§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:
@@ -105,7 +105,7 @@ impl ToolBridge {
|
||||
/// rather than by namespaced id.
|
||||
///
|
||||
/// Example: `tool_for_kind(ToolKind::BackgroundTaskAction)` returns
|
||||
/// `Some("get_task_output")` for the grok_build agent and `None` for
|
||||
/// `Some("get_task_output")` for the kigi agent and `None` for
|
||||
/// agents that do not register a tool of that kind.
|
||||
pub async fn tool_for_kind(&self, kind: ToolKind) -> Option<String> {
|
||||
self.registry
|
||||
@@ -547,9 +547,7 @@ impl ToolBridge {
|
||||
&self,
|
||||
task_id: &str,
|
||||
) -> Result<bool, kigi_tool_runtime::ToolError> {
|
||||
use crate::implementations::grok_build::scheduler::types::{
|
||||
SchedulerCommand, SchedulerHandle,
|
||||
};
|
||||
use crate::implementations::kigi::scheduler::types::{SchedulerCommand, SchedulerHandle};
|
||||
let sender = {
|
||||
let res = self.registry.resources.lock().await;
|
||||
res.get::<SchedulerHandle>()
|
||||
@@ -705,7 +703,7 @@ mod tests {
|
||||
let bridge = ToolBridge::for_test();
|
||||
let toolset = bridge.toolset();
|
||||
|
||||
// PascalCase + grok_build's snake_case in one registry
|
||||
// PascalCase + kigi's snake_case in one registry
|
||||
// to exercise the lookup on the literal name strings each
|
||||
// namespace ships.
|
||||
register_fixture(&toolset, "Write", ToolKind::Write, "fixture_write");
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
//! reachable only through the login shell is still found.
|
||||
//!
|
||||
//! Inject is **always** non-empty on Unix callers: either install a shadow
|
||||
//! function (which tags itself with a `__grok_shadow_{name}` marker) or a
|
||||
//! function (which tags itself with a `__kigi_shadow_{name}` marker) or a
|
||||
//! marker-gated `unalias`+`unset -f` that drops *only* a prior harness shadow —
|
||||
//! never a user-defined `find`/`grep` function replayed from the snapshot.
|
||||
|
||||
@@ -47,7 +47,7 @@ const UGREP_DEFAULT_ARGS: &[&str] = &[
|
||||
|
||||
// Binaries embedded by build.rs when `KIGI_TOOLS_BUNDLE_{BFS,UGREP}_PATH` is set
|
||||
// (release pipeline). Self-extracted to `~/.kigi/vendor` on first use, mirroring
|
||||
// the ripgrep bundling in `grok_build::grep::ripgrep`.
|
||||
// the ripgrep bundling in `kigi::grep::ripgrep`.
|
||||
#[cfg(bundle_bfs)]
|
||||
const BFS_BYTES: &[u8] = include_bytes!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
@@ -100,16 +100,16 @@ fn build_injection(find_on: bool, grep_on: bool, tools: &ResolvedTools) -> Strin
|
||||
}
|
||||
|
||||
/// Drop a *previously installed harness* shadow so command-word `{name}` uses the
|
||||
/// OS binary again. Gated on the `__grok_shadow_{name}` marker that
|
||||
/// OS binary again. Gated on the `__kigi_shadow_{name}` marker that
|
||||
/// [`shell_function`] sets, so a user-defined `{name}` function replayed from the
|
||||
/// shell snapshot is left intact — only the harness's own shadow is removed.
|
||||
/// `set -u`/`set -e` safe and idempotent (`unset -f` is bash + zsh).
|
||||
fn restore_command(name: &str) -> String {
|
||||
format!(
|
||||
"if [ -n \"${{__grok_shadow_{name}-}}\" ]; then \
|
||||
"if [ -n \"${{__kigi_shadow_{name}-}}\" ]; then \
|
||||
unalias {name} 2>/dev/null || true; \
|
||||
unset -f {name} 2>/dev/null || true; \
|
||||
unset __grok_shadow_{name} 2>/dev/null || true; \
|
||||
unset __kigi_shadow_{name} 2>/dev/null || true; \
|
||||
fi"
|
||||
)
|
||||
}
|
||||
@@ -265,7 +265,7 @@ fn bash_safe_quote(s: &str) -> String {
|
||||
/// keeps the probe `set -u`-safe (a bare `$ZSH_VERSION` aborts bash under
|
||||
/// nounset). `exec -a` gives the binary the `find`/`grep` argv0 (ps display +
|
||||
/// ugrep grep-personality) in both bash and zsh. The trailing
|
||||
/// `__grok_shadow_{name}=1` marks this as a harness shadow so `restore_command`
|
||||
/// `__kigi_shadow_{name}=1` marks this as a harness shadow so `restore_command`
|
||||
/// only ever removes our own function — never a user's.
|
||||
fn shell_function(
|
||||
name: &str,
|
||||
@@ -284,12 +284,12 @@ fn shell_function(
|
||||
format!("{} ", qargs.join(" "))
|
||||
}
|
||||
};
|
||||
// `local __grok_bin` is re-resolved every call. The host hint is trusted
|
||||
// `local __kigi_bin` is re-resolved every call. The host hint is trusted
|
||||
// only when it's *executable* (`[ -x ]`, not just `[ -f ]`): the resolver
|
||||
// accepts any regular file as a hint, but `exec` needs `+x`, so a non-exec
|
||||
// hint must fall through rather than hard-fail with no OS fallback. Then
|
||||
// `command -v` on the live shell PATH (returns an executable), else the OS
|
||||
// binary. `|| __grok_bin=''` keeps the lookup `set -e`-safe (a failed
|
||||
// binary. `|| __kigi_bin=''` keeps the lookup `set -e`-safe (a failed
|
||||
// `command -v` would otherwise abort the function under errexit). The OS
|
||||
// fallback uses `command {name}` to bypass this function. `{prepend}` is
|
||||
// empty for find, the ugrep default flags for grep (and is omitted from the
|
||||
@@ -297,16 +297,16 @@ fn shell_function(
|
||||
format!(
|
||||
"unalias {name} 2>/dev/null || true; \
|
||||
{name}() {{ \
|
||||
local __grok_bin={qpref}; \
|
||||
[ -x \"$__grok_bin\" ] || __grok_bin=$(command -v {bin_name} 2>/dev/null) || __grok_bin=''; \
|
||||
if [ -z \"$__grok_bin\" ]; then command {name} \"$@\"; return; fi; \
|
||||
local __kigi_bin={qpref}; \
|
||||
[ -x \"$__kigi_bin\" ] || __kigi_bin=$(command -v {bin_name} 2>/dev/null) || __kigi_bin=''; \
|
||||
if [ -z \"$__kigi_bin\" ]; then command {name} \"$@\"; return; fi; \
|
||||
if [[ -z ${{ZSH_VERSION-}} ]] && (( BASH_SUBSHELL > 0 )); then \
|
||||
exec -a {name} \"$__grok_bin\" {prepend}\"$@\"; \
|
||||
exec -a {name} \"$__kigi_bin\" {prepend}\"$@\"; \
|
||||
else \
|
||||
(exec -a {name} \"$__grok_bin\" {prepend}\"$@\"); \
|
||||
(exec -a {name} \"$__kigi_bin\" {prepend}\"$@\"); \
|
||||
fi; \
|
||||
}}; \
|
||||
__grok_shadow_{name}=1"
|
||||
__kigi_shadow_{name}=1"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -326,20 +326,20 @@ mod tests {
|
||||
fn shell_function_shape() {
|
||||
let fn_body = shell_function("find", "bfs", Some(Path::new("/tmp/bfs")), &[]);
|
||||
assert!(fn_body.contains("unalias find"));
|
||||
// Preferred path is the fast-path hint; the shadow execs `$__grok_bin`.
|
||||
assert!(fn_body.contains("local __grok_bin=/tmp/bfs"));
|
||||
assert!(fn_body.contains("exec -a find \"$__grok_bin\" \"$@\""));
|
||||
// Preferred path is the fast-path hint; the shadow execs `$__kigi_bin`.
|
||||
assert!(fn_body.contains("local __kigi_bin=/tmp/bfs"));
|
||||
assert!(fn_body.contains("exec -a find \"$__kigi_bin\" \"$@\""));
|
||||
// Hint is trusted only when executable (`[ -x ]`, not `[ -f ]`), so a
|
||||
// non-exec hint falls through instead of hard-failing exec.
|
||||
assert!(fn_body.contains("[ -x \"$__grok_bin\" ]"));
|
||||
assert!(!fn_body.contains("[ -f \"$__grok_bin\" ]"));
|
||||
assert!(fn_body.contains("[ -x \"$__kigi_bin\" ]"));
|
||||
assert!(!fn_body.contains("[ -f \"$__kigi_bin\" ]"));
|
||||
// Self-heal: live-PATH lookup + OS fallback.
|
||||
assert!(fn_body.contains("command -v bfs"));
|
||||
assert!(fn_body.contains("command find \"$@\""));
|
||||
assert!(fn_body.contains("BASH_SUBSHELL > 0"));
|
||||
assert!(fn_body.contains("(exec -a find"));
|
||||
// Marker so `restore_command` only removes our own shadow.
|
||||
assert!(fn_body.contains("__grok_shadow_find=1"));
|
||||
assert!(fn_body.contains("__kigi_shadow_find=1"));
|
||||
// set -u-safe zsh probe (a bare $ZSH_VERSION aborts bash under nounset).
|
||||
assert!(fn_body.contains("${ZSH_VERSION-}"));
|
||||
assert!(!fn_body.contains("[[ -n $ZSH_VERSION ]]"));
|
||||
@@ -349,7 +349,7 @@ mod tests {
|
||||
fn shell_function_unresolved_uses_empty_hint() {
|
||||
// No host-resolved path → empty hint, relies on live-PATH `command -v`.
|
||||
let fn_body = shell_function("find", "bfs", None, &[]);
|
||||
assert!(fn_body.contains("local __grok_bin=''"));
|
||||
assert!(fn_body.contains("local __kigi_bin=''"));
|
||||
assert!(fn_body.contains("command -v bfs"));
|
||||
assert!(fn_body.contains("command find \"$@\""));
|
||||
}
|
||||
@@ -362,8 +362,8 @@ mod tests {
|
||||
Some(Path::new("/tmp/ugrep")),
|
||||
UGREP_DEFAULT_ARGS,
|
||||
);
|
||||
assert!(fn_body.contains("local __grok_bin=/tmp/ugrep"));
|
||||
assert!(fn_body.contains("\"$__grok_bin\" -G --ignore-files --hidden -I"));
|
||||
assert!(fn_body.contains("local __kigi_bin=/tmp/ugrep"));
|
||||
assert!(fn_body.contains("\"$__kigi_bin\" -G --ignore-files --hidden -I"));
|
||||
assert!(fn_body.contains("--exclude-dir=.git"));
|
||||
assert!(fn_body.contains("command -v ugrep"));
|
||||
}
|
||||
@@ -373,7 +373,7 @@ mod tests {
|
||||
assert_eq!(bash_safe_quote("/usr/bin/bfs"), "/usr/bin/bfs");
|
||||
assert_eq!(bash_safe_quote("/tmp/my bfs"), "'/tmp/my bfs'");
|
||||
let body = shell_function("find", "bfs", Some(Path::new("/tmp/evil$(id)")), &[]);
|
||||
assert!(body.contains("local __grok_bin='/tmp/evil$(id)'"), "{body}");
|
||||
assert!(body.contains("local __kigi_bin='/tmp/evil$(id)'"), "{body}");
|
||||
assert!(!body.contains("=/tmp/evil$(id)"));
|
||||
}
|
||||
|
||||
@@ -381,10 +381,10 @@ mod tests {
|
||||
fn restore_command_is_marker_gated() {
|
||||
let r = restore_command("find");
|
||||
// Only removes the harness shadow when our marker is set.
|
||||
assert!(r.contains("if [ -n \"${__grok_shadow_find-}\" ]"));
|
||||
assert!(r.contains("if [ -n \"${__kigi_shadow_find-}\" ]"));
|
||||
assert!(r.contains("unalias find"));
|
||||
assert!(r.contains("unset -f find"));
|
||||
assert!(r.contains("unset __grok_shadow_find"));
|
||||
assert!(r.contains("unset __kigi_shadow_find"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -401,8 +401,8 @@ mod tests {
|
||||
// from a prior snapshot is dropped, but a user function is left intact.
|
||||
let inject = build_injection(false, false, &both_tools());
|
||||
assert!(inject.ends_with("; "));
|
||||
assert!(inject.contains("if [ -n \"${__grok_shadow_find-}\" ]"));
|
||||
assert!(inject.contains("if [ -n \"${__grok_shadow_grep-}\" ]"));
|
||||
assert!(inject.contains("if [ -n \"${__kigi_shadow_find-}\" ]"));
|
||||
assert!(inject.contains("if [ -n \"${__kigi_shadow_grep-}\" ]"));
|
||||
assert!(inject.contains("unset -f find"));
|
||||
assert!(inject.contains("unset -f grep"));
|
||||
assert!(!inject.contains("find()"));
|
||||
@@ -415,7 +415,7 @@ mod tests {
|
||||
assert!(inject.contains("find()"));
|
||||
assert!(inject.contains("grep()"));
|
||||
assert!(inject.contains("-G --ignore-files"));
|
||||
assert!(inject.contains("__grok_shadow_find=1"));
|
||||
assert!(inject.contains("__kigi_shadow_find=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -433,7 +433,7 @@ mod tests {
|
||||
assert!(inject.contains("command -v ugrep"));
|
||||
// OS fallback present; not a marker-gated restore.
|
||||
assert!(inject.contains("command find \"$@\""));
|
||||
assert!(!inject.contains("if [ -n \"${__grok_shadow_find-}\" ]"));
|
||||
assert!(!inject.contains("if [ -n \"${__kigi_shadow_find-}\" ]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -461,7 +461,7 @@ mod tests {
|
||||
#[test]
|
||||
fn env_override_accepts_regular_file_without_exec_bit() {
|
||||
let bin = std::env::temp_dir().join(format!(
|
||||
"grok-bfs-noexec-{}-{}",
|
||||
"kigi-bfs-noexec-{}-{}",
|
||||
std::process::id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
@@ -491,7 +491,7 @@ mod tests {
|
||||
#[test]
|
||||
fn resolve_tool_precedence() {
|
||||
// Real temp files so the is_file() checks pass.
|
||||
let dir = std::env::temp_dir().join(format!("grok-resolve-{}-{:?}", std::process::id(), {
|
||||
let dir = std::env::temp_dir().join(format!("kigi-resolve-{}-{:?}", std::process::id(), {
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@@ -687,7 +687,7 @@ mod tests {
|
||||
return;
|
||||
};
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"grok-selfheal-{}-{}",
|
||||
"kigi-selfheal-{}-{}",
|
||||
std::process::id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
@@ -731,7 +731,7 @@ mod tests {
|
||||
};
|
||||
let shadow = shell_function(
|
||||
"find",
|
||||
"grok_no_such_search_bin_xyz",
|
||||
"kigi_no_such_search_bin_xyz",
|
||||
Some(Path::new("/nonexistent/bfs")),
|
||||
&[],
|
||||
);
|
||||
@@ -759,7 +759,7 @@ mod tests {
|
||||
return;
|
||||
};
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"grok-noexec-{}-{}",
|
||||
"kigi-noexec-{}-{}",
|
||||
std::process::id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
@@ -779,7 +779,7 @@ mod tests {
|
||||
// Hint is the non-exec file; bin_name isn't on PATH → must reach OS find.
|
||||
let shadow = shell_function(
|
||||
"find",
|
||||
"grok_no_such_search_bin_xyz",
|
||||
"kigi_no_such_search_bin_xyz",
|
||||
Some(hint.as_path()),
|
||||
&[],
|
||||
);
|
||||
|
||||
@@ -23,14 +23,14 @@ use tokio::io::AsyncReadExt;
|
||||
// Marker constants
|
||||
// ============================================================================
|
||||
|
||||
const BASH_STATE_START_MARKER: &str = "__GROK_BASH_STATE_START__";
|
||||
const BASH_STATE_END_MARKER: &str = "__GROK_BASH_STATE_END__";
|
||||
const ZSH_STATE_START_MARKER: &str = "__GROK_ZSH_STATE_START__";
|
||||
const ZSH_STATE_END_MARKER: &str = "__GROK_ZSH_STATE_END__";
|
||||
const BASH_STATE_START_MARKER: &str = "__KIGI_BASH_STATE_START__";
|
||||
const BASH_STATE_END_MARKER: &str = "__KIGI_BASH_STATE_END__";
|
||||
const ZSH_STATE_START_MARKER: &str = "__KIGI_ZSH_STATE_START__";
|
||||
const ZSH_STATE_END_MARKER: &str = "__KIGI_ZSH_STATE_END__";
|
||||
|
||||
/// Marker emitted by the init path to separate login-shell noise (MOTD, etc.)
|
||||
/// from the actual state dump on stdout.
|
||||
const INIT_STATE_MARKER: &str = "__GROK_INIT_STATE_MARKER__";
|
||||
const INIT_STATE_MARKER: &str = "__KIGI_INIT_STATE_MARKER__";
|
||||
|
||||
/// Maximum time to wait for a shell state init (login shell + rc files).
|
||||
const INIT_TIMEOUT: Duration = Duration::from_secs(15);
|
||||
@@ -47,7 +47,7 @@ pub fn shell_env_overrides() -> HashMap<String, String> {
|
||||
("TERM".to_string(), "dumb".to_string()),
|
||||
("NO_COLOR".to_string(), "1".to_string()),
|
||||
("FORCE_COLOR".to_string(), "0".to_string()),
|
||||
// Re-applied last via [`crate::util::apply_grok_agent_marker`] so request
|
||||
// Re-applied last via [`crate::util::apply_kigi_agent_marker`] so request
|
||||
// env cannot clear it.
|
||||
(
|
||||
crate::util::KIGI_AGENT_ENV.to_string(),
|
||||
@@ -88,15 +88,15 @@ dump_bash_state() {
|
||||
local content="$1"
|
||||
local var_name="$2"
|
||||
if [[ -n "$content" ]]; then
|
||||
builtin printf 'grok_snap_%s=$(command base64 -d <<'"'"'KIGI_SNAP_EOF_%s'"'"'\n' "$var_name" "$var_name"
|
||||
builtin printf 'kigi_snap_%s=$(command base64 -d <<'"'"'KIGI_SNAP_EOF_%s'"'"'\n' "$var_name" "$var_name"
|
||||
command base64 <<<"$content" | command tr -d '\n'
|
||||
builtin printf '\nKIGI_SNAP_EOF_%s\n' "$var_name"
|
||||
builtin printf ')\n'
|
||||
builtin printf 'eval "$grok_snap_%s"\n' "$var_name"
|
||||
builtin printf 'eval "$kigi_snap_%s"\n' "$var_name"
|
||||
fi
|
||||
}
|
||||
|
||||
_emit "__GROK_BASH_STATE_START__"
|
||||
_emit "__KIGI_BASH_STATE_START__"
|
||||
|
||||
_emit "$PWD"
|
||||
|
||||
@@ -121,7 +121,7 @@ dump_bash_state() {
|
||||
_emit_encoded "$aliases" "ALIASES_B64"
|
||||
|
||||
_emit "# end of bash state dump"
|
||||
_emit "__GROK_BASH_STATE_END__"
|
||||
_emit "__KIGI_BASH_STATE_END__"
|
||||
}
|
||||
"##;
|
||||
|
||||
@@ -142,15 +142,15 @@ function dump_zsh_state() {
|
||||
local content="$1"
|
||||
local var_name="$2"
|
||||
if [[ -n "$content" ]]; then
|
||||
builtin printf 'grok_snap_%s=$(command base64 -d <<'"'"'KIGI_SNAP_EOF_%s'"'"'\n' "$var_name" "$var_name"
|
||||
builtin printf 'kigi_snap_%s=$(command base64 -d <<'"'"'KIGI_SNAP_EOF_%s'"'"'\n' "$var_name" "$var_name"
|
||||
command base64 <<<"$content" | command tr -d '\n'
|
||||
builtin printf '\nKIGI_SNAP_EOF_%s\n' "$var_name"
|
||||
builtin printf ')\n'
|
||||
builtin printf 'eval "$grok_snap_%s"\n' "$var_name"
|
||||
builtin printf 'eval "$kigi_snap_%s"\n' "$var_name"
|
||||
fi
|
||||
}
|
||||
|
||||
_emit "__GROK_ZSH_STATE_START__"
|
||||
_emit "__KIGI_ZSH_STATE_START__"
|
||||
|
||||
_emit "$PWD"
|
||||
|
||||
@@ -171,7 +171,7 @@ function dump_zsh_state() {
|
||||
_emit_encoded "$aliases" "ALIASES_B64"
|
||||
|
||||
_emit "# end of zsh state dump"
|
||||
_emit "__GROK_ZSH_STATE_END__"
|
||||
_emit "__KIGI_ZSH_STATE_END__"
|
||||
}
|
||||
"##;
|
||||
|
||||
@@ -688,11 +688,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_dump_valid_bash() {
|
||||
let raw = "__GROK_BASH_STATE_START__\n\
|
||||
let raw = "__KIGI_BASH_STATE_START__\n\
|
||||
/home/user/project\n\
|
||||
export FOO=bar\n\
|
||||
# end of bash state dump\n\
|
||||
__GROK_BASH_STATE_END__\n";
|
||||
__KIGI_BASH_STATE_END__\n";
|
||||
let (cwd, rest) = parse_dump(ShellKind::Bash, raw).unwrap();
|
||||
assert_eq!(cwd, PathBuf::from("/home/user/project"));
|
||||
assert!(rest.contains("export FOO=bar"));
|
||||
@@ -700,11 +700,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_dump_valid_zsh() {
|
||||
let raw = "__GROK_ZSH_STATE_START__\n\
|
||||
let raw = "__KIGI_ZSH_STATE_START__\n\
|
||||
/tmp\n\
|
||||
typeset -x FOO=bar\n\
|
||||
# end of zsh state dump\n\
|
||||
__GROK_ZSH_STATE_END__\n";
|
||||
__KIGI_ZSH_STATE_END__\n";
|
||||
let (cwd, rest) = parse_dump(ShellKind::Zsh, raw).unwrap();
|
||||
assert_eq!(cwd, PathBuf::from("/tmp"));
|
||||
assert!(rest.contains("typeset -x FOO=bar"));
|
||||
@@ -712,28 +712,28 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_dump_missing_start_marker() {
|
||||
let raw = "/home/user\nexport FOO=bar\n__GROK_BASH_STATE_END__\n";
|
||||
let raw = "/home/user\nexport FOO=bar\n__KIGI_BASH_STATE_END__\n";
|
||||
assert!(parse_dump(ShellKind::Bash, raw).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_dump_missing_end_marker() {
|
||||
let raw = "__GROK_BASH_STATE_START__\n/home/user\nexport FOO=bar\n";
|
||||
let raw = "__KIGI_BASH_STATE_START__\n/home/user\nexport FOO=bar\n";
|
||||
assert!(parse_dump(ShellKind::Bash, raw).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_dump_wrong_shell_markers() {
|
||||
let raw = "__GROK_ZSH_STATE_START__\n/tmp\nstuff\n__GROK_ZSH_STATE_END__\n";
|
||||
let raw = "__KIGI_ZSH_STATE_START__\n/tmp\nstuff\n__KIGI_ZSH_STATE_END__\n";
|
||||
assert!(parse_dump(ShellKind::Bash, raw).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_dump_empty_snapshot() {
|
||||
let raw = "__GROK_BASH_STATE_START__\n\
|
||||
let raw = "__KIGI_BASH_STATE_START__\n\
|
||||
/home/user\n\
|
||||
# end of bash state dump\n\
|
||||
__GROK_BASH_STATE_END__\n";
|
||||
__KIGI_BASH_STATE_END__\n";
|
||||
let (cwd, rest) = parse_dump(ShellKind::Bash, raw).unwrap();
|
||||
assert_eq!(cwd, PathBuf::from("/home/user"));
|
||||
assert!(rest.contains("# end of bash state dump"));
|
||||
@@ -741,15 +741,15 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_after_marker_found() {
|
||||
let output = "Welcome to Ubuntu\nMOTD line\n__GROK_INIT_STATE_MARKER__\nactual data\n";
|
||||
let result = parse_after_marker(output, "__GROK_INIT_STATE_MARKER__");
|
||||
let output = "Welcome to Ubuntu\nMOTD line\n__KIGI_INIT_STATE_MARKER__\nactual data\n";
|
||||
let result = parse_after_marker(output, "__KIGI_INIT_STATE_MARKER__");
|
||||
assert_eq!(result, "actual data\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_after_marker_not_found() {
|
||||
let output = "just some output\n";
|
||||
let result = parse_after_marker(output, "__GROK_INIT_STATE_MARKER__");
|
||||
let result = parse_after_marker(output, "__KIGI_INIT_STATE_MARKER__");
|
||||
assert_eq!(result, output);
|
||||
}
|
||||
|
||||
@@ -797,11 +797,11 @@ mod tests {
|
||||
shell: ShellKind::Bash,
|
||||
};
|
||||
|
||||
let dump = "__GROK_BASH_STATE_START__\n\
|
||||
let dump = "__KIGI_BASH_STATE_START__\n\
|
||||
/new/dir\n\
|
||||
export X=1\n\
|
||||
# end of bash state dump\n\
|
||||
__GROK_BASH_STATE_END__\n";
|
||||
__KIGI_BASH_STATE_END__\n";
|
||||
assert!(state.update_from_dump(dump));
|
||||
assert_eq!(state.cwd, PathBuf::from("/new/dir"));
|
||||
assert!(state.snapshot.contains("export X=1"));
|
||||
@@ -832,7 +832,7 @@ mod tests {
|
||||
assert!(state.cwd.is_absolute());
|
||||
// The snapshot should contain at least some env var exports
|
||||
assert!(
|
||||
state.snapshot.contains("grok_snap_") || state.snapshot.is_empty(),
|
||||
state.snapshot.contains("kigi_snap_") || state.snapshot.is_empty(),
|
||||
"snapshot should contain encoded blocks or be empty: {:?}",
|
||||
&state.snapshot[..state.snapshot.len().min(200)]
|
||||
);
|
||||
@@ -995,13 +995,13 @@ mod tests {
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
let mut state = ShellState::init(ShellKind::Bash, &cwd).await.unwrap();
|
||||
|
||||
let (code, _) = run_command(&mut state, "export GPG_TTY=/grok-sentinel-tty").await;
|
||||
let (code, _) = run_command(&mut state, "export GPG_TTY=/kigi-sentinel-tty").await;
|
||||
assert_eq!(code, 0);
|
||||
|
||||
let (code, stdout) = run_command(&mut state, "echo \"[$GPG_TTY]\"").await;
|
||||
assert_eq!(code, 0);
|
||||
assert!(
|
||||
!stdout.contains("/grok-sentinel-tty"),
|
||||
!stdout.contains("/kigi-sentinel-tty"),
|
||||
"GPG_TTY must not persist across commands via the snapshot, got: {stdout:?}"
|
||||
);
|
||||
}
|
||||
@@ -1015,13 +1015,13 @@ mod tests {
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
let mut state = ShellState::init(ShellKind::Zsh, &cwd).await.unwrap();
|
||||
|
||||
let (code, _) = run_command(&mut state, "export GPG_TTY=/grok-sentinel-tty").await;
|
||||
let (code, _) = run_command(&mut state, "export GPG_TTY=/kigi-sentinel-tty").await;
|
||||
assert_eq!(code, 0);
|
||||
|
||||
let (code, stdout) = run_command(&mut state, "echo \"[$GPG_TTY]\"").await;
|
||||
assert_eq!(code, 0);
|
||||
assert!(
|
||||
!stdout.contains("/grok-sentinel-tty"),
|
||||
!stdout.contains("/kigi-sentinel-tty"),
|
||||
"GPG_TTY must not persist across commands via the snapshot, got: {stdout:?}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -669,7 +669,7 @@ impl LocalTerminalActor {
|
||||
}
|
||||
|
||||
cmd.envs(crate::util::pager_env());
|
||||
crate::util::apply_grok_agent_marker(&mut cmd);
|
||||
crate::util::apply_kigi_agent_marker(&mut cmd);
|
||||
|
||||
cmd.fd_mappings(prep.fd_mappings)
|
||||
.map_err(|e| ComputerError::io(format!("fd mapping: {e}")))?;
|
||||
@@ -1950,7 +1950,7 @@ impl LocalTerminalActor {
|
||||
.map(|m| m.len())
|
||||
.unwrap_or(0);
|
||||
tokio::spawn(async move {
|
||||
crate::implementations::grok_build::monitor::tool::run_monitor_pipeline(
|
||||
crate::implementations::kigi::monitor::tool::run_monitor_pipeline(
|
||||
&pipeline_task_id,
|
||||
&pipeline_description,
|
||||
pipeline_terminal,
|
||||
@@ -2754,7 +2754,7 @@ fn spawn_shell_command(
|
||||
cmd.envs(login);
|
||||
}
|
||||
// Agent marker must win over request/login env.
|
||||
crate::util::apply_grok_agent_marker(&mut cmd);
|
||||
crate::util::apply_kigi_agent_marker(&mut cmd);
|
||||
|
||||
// Detach from the controlling terminal so subprocesses cannot open
|
||||
// /dev/tty and compete with the TUI for terminal input.
|
||||
@@ -2762,7 +2762,7 @@ fn spawn_shell_command(
|
||||
|
||||
// If the sandbox profile restricts network, install a seccomp BPF
|
||||
// filter on the child that blocks connect/bind/sendto/listen/accept.
|
||||
// The parent (grok) process retains network for the LLM API.
|
||||
// The parent (kigi) process retains network for the LLM API.
|
||||
// Filesystem restrictions are already inherited from the process-level
|
||||
// Landlock/Seatbelt sandbox — no action needed here for FS.
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -2795,7 +2795,7 @@ fn spawn_shell_command(
|
||||
}
|
||||
cmd.envs(crate::util::pager_env());
|
||||
// Agent marker must win over request env.
|
||||
crate::util::apply_grok_agent_marker(&mut cmd);
|
||||
crate::util::apply_kigi_agent_marker(&mut cmd);
|
||||
|
||||
// Set creation flags inline rather than via crate::util::detach_command
|
||||
// + new_process_group: tokio's creation_flags is a SET, not OR, so
|
||||
@@ -2806,7 +2806,7 @@ fn spawn_shell_command(
|
||||
// job so we can assign it to our own ProcessGroup. Per Microsoft
|
||||
// docs this *fails CreateProcess with ERROR_ACCESS_DENIED* (os
|
||||
// error 5) when the parent process is in a job that does not
|
||||
// have JOB_OBJECT_LIMIT_BREAKAWAY_OK set — common when grok-agent
|
||||
// have JOB_OBJECT_LIMIT_BREAKAWAY_OK set — common when kigi-agent
|
||||
// is launched under a Windows service, scheduled task, or some
|
||||
// ACP host wrappers. The caller below retries without this flag
|
||||
// on os error 5.
|
||||
@@ -4212,7 +4212,7 @@ mod tests {
|
||||
|
||||
let mut req = make_request("echo \"[$GPG_TTY]\"");
|
||||
req.env
|
||||
.insert("GPG_TTY".to_string(), "/grok-sentinel-tty".to_string());
|
||||
.insert("GPG_TTY".to_string(), "/kigi-sentinel-tty".to_string());
|
||||
|
||||
let result = backend.run(req).await.unwrap();
|
||||
assert_eq!(result.exit_code, Some(0));
|
||||
|
||||
@@ -237,7 +237,7 @@ impl TaskSnapshot {
|
||||
|
||||
/// Result of killing a terminal task.
|
||||
///
|
||||
/// Serialized over the wire in the `x.ai/task/kill` ext response
|
||||
/// Serialized over the wire in the `kigi/task/kill` ext response
|
||||
/// (`kigi-shell::extensions::task::KillTaskResponse`) and deserialized
|
||||
/// by clients (kigi-tui), so it derives both serde directions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! This is a faithful port of `codex-rs/core/src/tools/handlers/grep_files.rs`.
|
||||
//! It returns **file paths only** (`--files-with-matches`), sorted by
|
||||
//! modification time. See the plan document for the full diff vs the
|
||||
//! grok-build `GrepTool`.
|
||||
//! kigi `GrepTool`.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tokio::process::Command;
|
||||
use tokio::time::timeout;
|
||||
|
||||
use crate::implementations::grok_build::grep::ripgrep::rg_path;
|
||||
use crate::implementations::kigi::grep::ripgrep::rg_path;
|
||||
use crate::types::output::CodexGrepFilesOutput;
|
||||
use crate::types::requirements::Expr;
|
||||
#[allow(unused_imports)]
|
||||
@@ -59,8 +59,8 @@ pub struct CodexGrepFilesInput {
|
||||
|
||||
/// Codex-namespace grep_files tool — file-path-only regex search.
|
||||
///
|
||||
/// Shares `ToolKind::Search` with the grok-build `GrepTool`. These tools are
|
||||
/// namespace-exclusive — consumers enable either `GrokBuild` or `Codex` search,
|
||||
/// Shares `ToolKind::Search` with the kigi `GrepTool`. These tools are
|
||||
/// namespace-exclusive — consumers enable either `Kigi` or `Codex` search,
|
||||
/// never both simultaneously. This follows the same pattern as
|
||||
/// `CodexListDirTool`/`ListDirTool` (`ToolKind::ListDir`) and
|
||||
/// `CodexReadFileTool`/`ReadFileImpl` (`ToolKind::Read`).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! This is a faithful port of `codex-rs/core/src/tools/handlers/list_dir.rs`.
|
||||
//! It does NOT respect `.gitignore`, does NOT exclude hidden files, and requires
|
||||
//! absolute paths. See the plan document for the full diff vs the grok-build
|
||||
//! absolute paths. See the plan document for the full diff vs the kigi
|
||||
//! `ListDirTool`.
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
@@ -244,7 +244,7 @@ impl kigi_tool_runtime::Tool for CodexReadFileTool {
|
||||
let content = collected.join("\n");
|
||||
|
||||
// 5. Build raw_output — the unformatted file content for the read
|
||||
// range. This matches the grok-build ReadFileTool semantics where
|
||||
// range. This matches the kigi ReadFileTool semantics where
|
||||
// raw_output is the actual file text without line-number prefixes.
|
||||
let raw_output = String::from_utf8_lossy(&file_bytes).into_owned();
|
||||
|
||||
|
||||
@@ -440,8 +440,8 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::computer::local::LocalFs;
|
||||
use crate::implementations::grok_build::read_file::{
|
||||
ReadFileInput, ReadFileParams, ReadFileTool as GrokReadFileTool,
|
||||
use crate::implementations::kigi::read_file::{
|
||||
ReadFileInput, ReadFileParams, ReadFileTool as KigiReadFileTool,
|
||||
};
|
||||
use crate::notification::types::ToolNotificationHandle;
|
||||
use crate::types::output::ReadFileOutput;
|
||||
@@ -465,7 +465,7 @@ mod tests {
|
||||
resources.into_shared()
|
||||
}
|
||||
|
||||
fn resources_with_grok_rules_on_read(root: &Path) -> SharedResources {
|
||||
fn resources_with_kigi_rules_on_read(root: &Path) -> SharedResources {
|
||||
let mut resources = Resources::new();
|
||||
resources.insert(Cwd(root.to_path_buf()));
|
||||
resources.insert(FileSystem(Arc::new(LocalFs)));
|
||||
@@ -675,7 +675,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grok_read_file_output_includes_matching_rule_once() {
|
||||
async fn kigi_read_file_output_includes_matching_rule_once() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
let root = temp.path();
|
||||
std::fs::create_dir_all(root.join(".cursor/rules")).unwrap();
|
||||
@@ -686,7 +686,7 @@ mod tests {
|
||||
.unwrap();
|
||||
std::fs::write(root.join("main.rs"), "fn main() {}\n").unwrap();
|
||||
|
||||
let shared = resources_with_grok_rules_on_read(root);
|
||||
let shared = resources_with_kigi_rules_on_read(root);
|
||||
let input = ReadFileInput {
|
||||
path: "main.rs".to_owned(),
|
||||
offset: None,
|
||||
@@ -695,7 +695,7 @@ mod tests {
|
||||
format: None,
|
||||
};
|
||||
|
||||
let first = kigi_tool_runtime::Tool::run(&GrokReadFileTool, test_ctx(shared), input)
|
||||
let first = kigi_tool_runtime::Tool::run(&KigiReadFileTool, test_ctx(shared), input)
|
||||
.await
|
||||
.unwrap();
|
||||
let ReadFileOutput::FileContent(first) = first else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Shared editor infrastructure used by the default grok_build tools.
|
||||
//! Shared editor infrastructure used by the default kigi tools.
|
||||
pub mod file_operation_lock;
|
||||
pub use file_operation_lock::{FileOperationLockGuard, FileOperationLockManager};
|
||||
/// Default `block_until_ms` when the model omits the field on blocking shell
|
||||
|
||||
+3
-3
@@ -115,7 +115,7 @@ pub struct AskUserQuestionParams {
|
||||
pub timeout_secs: Option<u64>,
|
||||
}
|
||||
|
||||
crate::register_resource!("grok_build", "AskUserQuestion", AskUserQuestionParams);
|
||||
crate::register_resource!("kigi", "AskUserQuestion", AskUserQuestionParams);
|
||||
|
||||
impl AskUserQuestionParams {
|
||||
/// Effective wait budget: `Some(duration)` = bounded, `None` = wait forever.
|
||||
@@ -160,7 +160,7 @@ pub struct QuestionOption {
|
||||
)]
|
||||
pub preview: Option<String>,
|
||||
|
||||
/// Opaque id; hidden from the model. Grok callers leave it `None`.
|
||||
/// Opaque id; hidden from the model. Kigi callers leave it `None`.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[schemars(skip)]
|
||||
pub id: Option<String>,
|
||||
@@ -236,7 +236,7 @@ impl crate::types::tool_metadata::ToolMetadata for AskUserQuestionTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn emitted_notifications(&self) -> &'static [&'static str] {
|
||||
+1
-1
@@ -197,7 +197,7 @@ pub struct UserQuestionSender(
|
||||
#[educe(Debug(ignore))] pub mpsc::UnboundedSender<UserQuestionRequest>,
|
||||
);
|
||||
|
||||
register_resource!("grok_build", "UserQuestionSender", UserQuestionSender);
|
||||
register_resource!("kigi", "UserQuestionSender", UserQuestionSender);
|
||||
|
||||
// ── Conversion helper ────────────────────────────────────────────────────
|
||||
|
||||
+9
-9
@@ -138,7 +138,7 @@ pub struct BashParams {
|
||||
pub timeout_secs: Option<f64>,
|
||||
/// **Foreground-only** ceiling for model-provided `timeout` (seconds).
|
||||
/// None → built-in [`DEFAULT_MAX_TIMEOUT_MS`] (5 minutes); production
|
||||
/// grok-build opts up to 10h via kigi-shell's `BashToolConfig`.
|
||||
/// kigi opts up to 10h via kigi-shell's `BashToolConfig`.
|
||||
///
|
||||
/// When set:
|
||||
/// - Positive model `timeout` values are clamped to this ceiling (ms).
|
||||
@@ -221,7 +221,7 @@ impl Default for BashParams {
|
||||
}
|
||||
|
||||
impl crate::types::resources::ResourceType for BashParams {
|
||||
const ID: &'static str = "grok_build.Bash";
|
||||
const ID: &'static str = "kigi.Bash";
|
||||
|
||||
fn validate_params_value(
|
||||
value: &Self,
|
||||
@@ -449,7 +449,7 @@ pub(crate) fn format_default_prompt(bash: &BashOutput) -> String {
|
||||
// Default upper bound for model-provided *foreground* command timeouts when
|
||||
// `BashParams.max_timeout_secs` is unset: a transport-safe **5 minutes**.
|
||||
// Consumers that want longer opt in per session via `max_timeout_secs` — in
|
||||
// particular production grok-build sets it to 10h in kigi-shell's
|
||||
// particular production kigi sets it to 10h in kigi-shell's
|
||||
// `BashToolConfig`. `max_timeout_secs` only lowers/raises this *foreground*
|
||||
// ceiling; background tasks (`timeout: 0` / omitted in background mode) are
|
||||
// always unbounded regardless of this value — the model owns their lifetime via
|
||||
@@ -986,13 +986,13 @@ fn clamp_foreground_block(
|
||||
}
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────────────
|
||||
// Bare `echo "<msg>"` detection (for statistics + hints in grok_build bash)
|
||||
// Bare `echo "<msg>"` detection (for statistics + hints in kigi bash)
|
||||
// ───────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Tracks usage of bare `echo "<msg>"` (and close variants) inside the bash tool.
|
||||
///
|
||||
/// These are often used by the model as a substitute for direct output or
|
||||
/// communication. We want statistics on this pattern for the grok_build
|
||||
/// communication. We want statistics on this pattern for the kigi
|
||||
/// implementation and can surface educational hints on repeated use.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct BareEchoHintState {
|
||||
@@ -1514,7 +1514,7 @@ impl crate::types::tool_metadata::ToolMetadata for BashTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -2048,7 +2048,7 @@ impl kigi_tool_runtime::Tool for BashTool {
|
||||
// past that deadline rather than kill the process.
|
||||
// Backwards compatible because
|
||||
// `auto_background_on_timeout` defaults to `false`;
|
||||
// existing grok_build callers that never opted in are
|
||||
// existing kigi callers that never opted in are
|
||||
// unaffected.
|
||||
auto_background_on_timeout: Self::auto_background_on_timeout_enabled(¶ms),
|
||||
foreground_block_budget: Self::effective_foreground_block_budget(¶ms),
|
||||
@@ -2173,7 +2173,7 @@ impl kigi_tool_runtime::Tool for BashTool {
|
||||
bash.output_for_prompt = format_default_prompt(&bash);
|
||||
|
||||
// Bare `echo "<msg>"` usage (common model anti-pattern for "just output something").
|
||||
// We tag it for statistics (grok_build backend) and can surface an educational
|
||||
// We tag it for statistics (kigi backend) and can surface an educational
|
||||
// hint on repeated use.
|
||||
bash.was_bare_echo = is_bare_echo(&bash.command) || is_bare_printf(&bash.command);
|
||||
if bash.was_bare_echo {
|
||||
@@ -3900,7 +3900,7 @@ mod tests {
|
||||
#[test]
|
||||
fn foreground_positive_clamped_to_default_max() {
|
||||
// The built-in default foreground ceiling is 5 min; production
|
||||
// grok-shell opts up to 10h via max_timeout_secs. Background unaffected.
|
||||
// kigi-shell opts up to 10h via max_timeout_secs. Background unaffected.
|
||||
assert_eq!(DEFAULT_MAX_TIMEOUT_MS, 300_000);
|
||||
let above_max: u64 = 50 * 60 * 60 * 1_000;
|
||||
assert_eq!(
|
||||
+2
-2
@@ -48,7 +48,7 @@ impl crate::types::tool_metadata::ToolMetadata for EnterPlanModeTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn emitted_notifications(&self) -> &'static [&'static str] {
|
||||
@@ -62,7 +62,7 @@ impl crate::types::tool_metadata::ToolMetadata for EnterPlanModeTool {
|
||||
fn requires_expr(&self) -> Expr<ToolRequirement> {
|
||||
// EnterPlanMode can only exist if ExitPlanMode is also registered —
|
||||
// entering plan mode without the ability to exit would be a dead-end.
|
||||
use crate::implementations::grok_build::exit_plan_mode::ExitPlanModeTool;
|
||||
use crate::implementations::kigi::exit_plan_mode::ExitPlanModeTool;
|
||||
Expr::Value(ToolRequirement::Tool {
|
||||
namespace: crate::types::tool_metadata::ToolMetadata::tool_namespace(&ExitPlanModeTool)
|
||||
.to_string(),
|
||||
+2
-2
@@ -55,7 +55,7 @@ impl crate::types::tool_metadata::ToolMetadata for ExitPlanModeTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn emitted_notifications(&self) -> &'static [&'static str] {
|
||||
@@ -71,7 +71,7 @@ Use this after you have finished writing your plan to the plan file in plan mode
|
||||
fn requires_expr(&self) -> Expr<ToolRequirement> {
|
||||
// ExitPlanMode can only exist if EnterPlanMode is also registered —
|
||||
// exiting plan mode without the ability to enter would be nonsensical.
|
||||
use crate::implementations::grok_build::enter_plan_mode::EnterPlanModeTool;
|
||||
use crate::implementations::kigi::enter_plan_mode::EnterPlanModeTool;
|
||||
Expr::Value(ToolRequirement::Tool {
|
||||
namespace: crate::types::tool_metadata::ToolMetadata::tool_namespace(
|
||||
&EnterPlanModeTool,
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//! Wire types for the `x.ai/exit_plan_mode` ACP ext_method.
|
||||
//! Wire types for the `kigi/exit_plan_mode` ACP ext_method.
|
||||
//!
|
||||
//! Shared between the shell (serializer) and the pager/desktop/VS Code
|
||||
//! (deserializer) so both sides stay in sync.
|
||||
+8
-8
@@ -31,8 +31,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod ripgrep;
|
||||
|
||||
// Re-export the shared GrokIntegerSchema from types module
|
||||
pub use crate::types::GrokIntegerSchema;
|
||||
// Re-export the shared KigiIntegerSchema from types module
|
||||
pub use crate::types::KigiIntegerSchema;
|
||||
use ripgrep::rg_path;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema, PartialEq, Default)]
|
||||
@@ -68,7 +68,7 @@ pub struct GrepSearchInput {
|
||||
|
||||
#[schemars(
|
||||
rename = "-B",
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "Number of lines to show before each match (rg -B)."
|
||||
)]
|
||||
#[serde(rename = "-B")]
|
||||
@@ -77,7 +77,7 @@ pub struct GrepSearchInput {
|
||||
|
||||
#[schemars(
|
||||
rename = "-A",
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "Number of lines to show after each match (rg -A)."
|
||||
)]
|
||||
#[serde(rename = "-A")]
|
||||
@@ -86,7 +86,7 @@ pub struct GrepSearchInput {
|
||||
|
||||
#[schemars(
|
||||
rename = "-C",
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "Number of lines to show before and after each match (rg -C)."
|
||||
)]
|
||||
#[serde(rename = "-C")]
|
||||
@@ -110,7 +110,7 @@ pub struct GrepSearchInput {
|
||||
pub r#type: Option<String>,
|
||||
|
||||
#[schemars(
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "Limit output to first N lines/entries, equivalent to \"| head -N\". Defaults to 200 lines or 500 entries."
|
||||
)]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -143,7 +143,7 @@ pub struct GrepParams {
|
||||
pub max_chars_per_line: Option<usize>,
|
||||
}
|
||||
|
||||
crate::register_resource!("grok_build", "Grep", GrepParams);
|
||||
crate::register_resource!("kigi", "Grep", GrepParams);
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────────────
|
||||
// Constants
|
||||
@@ -242,7 +242,7 @@ impl crate::types::tool_metadata::ToolMetadata for GrepTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+9
-12
@@ -7,9 +7,9 @@ pub mod terminal_command;
|
||||
pub use terminal_command::KillTerminalCommandTool;
|
||||
|
||||
use crate::computer::types::KillOutcome;
|
||||
use crate::implementations::grok_build::task::TaskTool;
|
||||
use crate::implementations::grok_build::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::grok_build::task::types::SubagentCancelOutcome;
|
||||
use crate::implementations::kigi::task::TaskTool;
|
||||
use crate::implementations::kigi::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::kigi::task::types::SubagentCancelOutcome;
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
use crate::types::resources::Terminal;
|
||||
use crate::types::template_renderer::TemplateRenderer;
|
||||
@@ -72,13 +72,13 @@ impl crate::types::tool_metadata::ToolMetadata for KillTaskTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
// Canonical wording lives in the shared builder; `versioned_definition`
|
||||
// renders it context-aware from the finalized toolset. This static
|
||||
// fallback mirrors the default grok-build toolset on the current OS.
|
||||
// fallback mirrors the default kigi toolset on the current OS.
|
||||
static DESC: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
|
||||
kigi_tool_types::build_kill_task_description(&kigi_tool_types::KillTaskToolNaming {
|
||||
monitor_tool: Some("monitor"),
|
||||
@@ -120,8 +120,7 @@ impl crate::types::tool_metadata::ToolMetadata for KillTaskTool {
|
||||
id: kigi_tool_runtime::Tool::id(&TaskTool).to_string(),
|
||||
if_params: None,
|
||||
});
|
||||
let mut arms =
|
||||
crate::implementations::grok_build::task_output::background_bash_requires_exprs();
|
||||
let mut arms = crate::implementations::kigi::task_output::background_bash_requires_exprs();
|
||||
arms.push(task_tool);
|
||||
Expr::Or(arms)
|
||||
}
|
||||
@@ -258,10 +257,8 @@ mod tests {
|
||||
BackgroundHandle, KillOutcome as KO, TaskSnapshot, TerminalBackend, TerminalRunRequest,
|
||||
TerminalRunResult,
|
||||
};
|
||||
use crate::implementations::grok_build::task::backend::{
|
||||
ChannelBackend, SubagentBackendResource,
|
||||
};
|
||||
use crate::implementations::grok_build::task::types::{
|
||||
use crate::implementations::kigi::task::backend::{ChannelBackend, SubagentBackendResource};
|
||||
use crate::implementations::kigi::task::types::{
|
||||
SubagentCancelRequest, SubagentCancelTarget, SubagentEvent,
|
||||
};
|
||||
use crate::types::resources::{Resources, SharedResources};
|
||||
@@ -334,7 +331,7 @@ mod tests {
|
||||
fn tool_name_and_description() {
|
||||
let tool = KillTaskTool;
|
||||
assert_eq!(kigi_tool_runtime::Tool::id(&tool).as_str(), "kill_task");
|
||||
// The static fallback is the shared builder's default grok-build
|
||||
// The static fallback is the shared builder's default kigi
|
||||
// rendering (monitor + task + bash present) for the current OS.
|
||||
let desc = crate::types::tool_metadata::ToolMetadata::description_template(&tool);
|
||||
assert!(desc.contains("Terminate"));
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
//! Workspace-only, subagent-free variant of `kill_task` (delegates to [`KillTaskTool`]).
|
||||
|
||||
use super::KillTaskTool;
|
||||
use crate::implementations::grok_build::task_output::background_bash_requires_exprs;
|
||||
use crate::implementations::kigi::task_output::background_bash_requires_exprs;
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
use crate::types::tool::{ToolKind, ToolNamespace};
|
||||
use kigi_tool_types::{KillTaskOutput, KillTaskToolInput};
|
||||
@@ -19,7 +19,7 @@ impl crate::types::tool_metadata::ToolMetadata for KillTerminalCommandTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+2
-2
@@ -45,7 +45,7 @@ pub struct ListDirParams {
|
||||
/// Defaults to `DEFAULT_MAX_OUTPUT_CHARS` (10,000) to match the Python
|
||||
pub max_output_chars: Option<usize>,
|
||||
}
|
||||
crate::register_resource!("grok_build", "ListDir", ListDirParams);
|
||||
crate::register_resource!("kigi", "ListDir", ListDirParams);
|
||||
/// Exact historical invalid-directory message for `list_dir` in legacy-0.4.10.
|
||||
///
|
||||
/// Historical fixture captured from an earlier (0.4.10) revision of this tool.
|
||||
@@ -579,7 +579,7 @@ impl crate::types::tool_metadata::ToolMetadata for ListDirTool {
|
||||
ToolKind::List
|
||||
}
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
fn description_template(&self) -> &str {
|
||||
r#"Lists files and directories in a given path.
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
//! `lsp` tool - code intelligence via language servers.
|
||||
//!
|
||||
//! Implementation is in `implementations::lsp`. This module provides the
|
||||
//! `LspTool` (Tool trait impl) under the `GrokBuild` namespace.
|
||||
//! `LspTool` (Tool trait impl) under the `Kigi` namespace.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -29,7 +29,7 @@ impl crate::types::tool_metadata::ToolMetadata for LspTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
//! Each sub-module here contains a tool that implements `NewTool` instead
|
||||
//! of the old `Tool` trait. During migration, old implementations live in
|
||||
//! `implementations/<tool>/` and new implementations live in
|
||||
//! `implementations/grok_build/<tool>/`.
|
||||
//! `implementations/kigi/<tool>/`.
|
||||
//!
|
||||
//! The [`register_all()`] function is the single entry-point for wiring up
|
||||
//! the standard toolset. It inserts shared resources (`Terminal`,
|
||||
+2
-2
@@ -23,7 +23,7 @@ impl crate::types::tool_metadata::ToolMetadata for MonitorTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -313,7 +313,7 @@ pub(crate) async fn run_monitor_pipeline(
|
||||
// a terminal event as well produced a second NotificationDrain turn
|
||||
// with the same ended signal. Stdout lines above still stream as
|
||||
// events while the process is alive; the UI learns completion from
|
||||
// `x.ai/task_completed`.
|
||||
// `kigi/task_completed`.
|
||||
|
||||
break;
|
||||
}
|
||||
+7
-7
@@ -22,7 +22,7 @@ use crate::types::template_renderer::TemplateRenderer;
|
||||
use crate::types::tool::{ToolKind, ToolNamespace};
|
||||
use std::sync::LazyLock;
|
||||
mod versions;
|
||||
use crate::types::schema::GrokIntegerSchema;
|
||||
use crate::types::schema::KigiIntegerSchema;
|
||||
/// Configuration for the ReadFile tool, stored as `Params<ReadFileParams>` in Resources.
|
||||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
@@ -30,7 +30,7 @@ pub struct ReadFileParams {
|
||||
#[serde(default)]
|
||||
pub cursor_rules_on_read: bool,
|
||||
}
|
||||
crate::register_resource!("grok_build", "ReadFile", ReadFileParams);
|
||||
crate::register_resource!("kigi", "ReadFile", ReadFileParams);
|
||||
/// Internal version discriminant for read_file.
|
||||
///
|
||||
/// `read_file` has cross-cutting version divergence: gitignore enforcement
|
||||
@@ -121,13 +121,13 @@ pub struct ReadFileInput {
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
#[schemars(
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "The line number to start reading from. Only provide if the file is too large to read at once."
|
||||
)]
|
||||
pub offset: Option<i64>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[schemars(
|
||||
with = "GrokIntegerSchema",
|
||||
with = "KigiIntegerSchema",
|
||||
description = "The number of lines to read. Only provide if the file is too large to read at once."
|
||||
)]
|
||||
pub limit: Option<usize>,
|
||||
@@ -152,7 +152,7 @@ async fn cursor_rules_on_read_enabled(resources: &SharedResources) -> bool {
|
||||
/// Negatives use the reference `split('\n')` field count plus a phantom field when
|
||||
/// the file is non-empty and has no trailing `\n`. Extraction still uses
|
||||
/// `split_inclusive`, so a start that lands on the phantom-only field yields
|
||||
/// an empty window (harness-aligned; not a Grok-line clamp).
|
||||
/// an empty window (harness-aligned; not a Kigi-line clamp).
|
||||
fn resolve_read_start_line(file_content: &str, offset: Option<i64>) -> usize {
|
||||
let offset_raw = offset.unwrap_or(1);
|
||||
if offset_raw == 0 {
|
||||
@@ -552,7 +552,7 @@ impl crate::types::tool_metadata::ToolMetadata for ReadFileTool {
|
||||
ToolKind::Read
|
||||
}
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
fn description_template(&self) -> &str {
|
||||
DESCRIPTION_FULL
|
||||
@@ -2315,7 +2315,7 @@ pub fn verify(req: &HttpRequest) -> Result<Claims, Error> {
|
||||
assert_eq!(extracted.content_concise, "2→");
|
||||
}
|
||||
/// Harness parity: offset=-1 on a file with no trailing `\n` resolves to the
|
||||
/// phantom field only (start past any `split_inclusive` line), so Grok
|
||||
/// phantom field only (start past any `split_inclusive` line), so Kigi
|
||||
/// returns empty content/raw — same as the reference phantom-only window.
|
||||
#[test]
|
||||
fn extract_file_content_lines_negative_one_no_trailing_newline_stable() {
|
||||
+1
-1
@@ -270,7 +270,7 @@ impl SchedulerActor {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::implementations::grok_build::scheduler::types::{ScheduledTask, SchedulerHandle};
|
||||
use crate::implementations::kigi::scheduler::types::{ScheduledTask, SchedulerHandle};
|
||||
use crate::notification::ToolNotification;
|
||||
use crate::types::resources::Resources;
|
||||
use std::sync::Arc;
|
||||
+1
-1
@@ -75,7 +75,7 @@ impl crate::types::tool_metadata::ToolMetadata for SchedulerCreateTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -32,7 +32,7 @@ impl crate::types::tool_metadata::ToolMetadata for SchedulerDeleteTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -35,7 +35,7 @@ impl crate::types::tool_metadata::ToolMetadata for SchedulerListTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -85,7 +85,7 @@ pub struct SchedulerState {
|
||||
pub tasks: Vec<ScheduledTask>,
|
||||
}
|
||||
|
||||
crate::register_resource!("grok_build", "Scheduler", SchedulerState);
|
||||
crate::register_resource!("kigi", "Scheduler", SchedulerState);
|
||||
|
||||
/// Handle for tools to communicate with the SchedulerActor.
|
||||
/// Ephemeral -- not serialized, not persisted. Inserted via `resources.insert()`.
|
||||
+2
-2
@@ -116,7 +116,7 @@ pub struct SearchReplaceParams {
|
||||
#[serde(default = "default_true")]
|
||||
pub include_user_edit_hint: bool,
|
||||
}
|
||||
register_resource!("grok_build", "SearchReplace", SearchReplaceParams);
|
||||
register_resource!("kigi", "SearchReplace", SearchReplaceParams);
|
||||
/// SearchReplace tool — new architecture.
|
||||
///
|
||||
/// Replaces an exact string in a file.
|
||||
@@ -757,7 +757,7 @@ impl crate::types::tool_metadata::ToolMetadata for SearchReplaceTool {
|
||||
ToolKind::Edit
|
||||
}
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
fn description_template(&self) -> &str {
|
||||
DESCRIPTION_FULL
|
||||
+1
-5
@@ -99,11 +99,7 @@ impl std::fmt::Debug for SubagentBackendResource {
|
||||
}
|
||||
}
|
||||
|
||||
register_resource!(
|
||||
"grok_build",
|
||||
"SubagentBackendResource",
|
||||
SubagentBackendResource
|
||||
);
|
||||
register_resource!("kigi", "SubagentBackendResource", SubagentBackendResource);
|
||||
|
||||
/// In-process channel-based backend for the local host shell.
|
||||
///
|
||||
+3
-5
@@ -47,11 +47,11 @@ impl crate::types::tool_metadata::ToolMetadata for TaskTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
// The Task tool description for Grok Build is *never* taken from here.
|
||||
// The Task tool description for Kigi is *never* taken from here.
|
||||
// It is always supplied via `ToolConfig::with_description(...)` using
|
||||
// the dynamically built string from `build_task_description()` in
|
||||
// kigi-agent/src/builder.rs (HEADER + per-subagent blocks + FOOTER).
|
||||
@@ -429,9 +429,7 @@ impl kigi_tool_runtime::Tool for TaskTool {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::implementations::grok_build::task::backend::{
|
||||
ChannelBackend, SubagentBackendResource,
|
||||
};
|
||||
use crate::implementations::kigi::task::backend::{ChannelBackend, SubagentBackendResource};
|
||||
use crate::types::resources::Resources;
|
||||
use crate::types::tool_metadata::test_ctx;
|
||||
use kigi_tool_types::SubagentCapabilityMode;
|
||||
+31
-42
@@ -97,7 +97,7 @@ pub struct SubagentRuntimeOverrides {
|
||||
/// `None` means "use role/persona default" (which itself defaults to `None`/shared workspace).
|
||||
pub isolation: Option<SubagentIsolationMode>,
|
||||
/// `/goal`-only harness override: the `agent_type` (e.g. `"cursor"`,
|
||||
/// `"grok-build-plan"`) whose `AgentDefinition` decides the child's harness
|
||||
/// `"kigi-plan"`) whose `AgentDefinition` decides the child's harness
|
||||
/// flavor — system prompt + toolset — applied
|
||||
/// REGARDLESS of the parent agent (so a session can pin a
|
||||
/// compat-harness verifier and vice versa).
|
||||
@@ -175,7 +175,7 @@ pub fn prune_orphaned_background_task_tools(config: &mut crate::registry::types:
|
||||
|
||||
fn is_background_capable_bash_tool(tc: &crate::registry::types::ToolConfig) -> bool {
|
||||
match tc.id.as_str() {
|
||||
"GrokBuild:run_terminal_cmd" | "GrokBuildConcise:run_terminal_cmd" => tc
|
||||
"Kigi:run_terminal_cmd" | "KigiConcise:run_terminal_cmd" => tc
|
||||
.params
|
||||
.as_ref()
|
||||
.and_then(|params| params.get("enabled_background"))
|
||||
@@ -667,7 +667,7 @@ pub enum SubagentEvent {
|
||||
#[educe(Debug)]
|
||||
pub struct SubagentEventSender(#[educe(Debug(ignore))] pub mpsc::UnboundedSender<SubagentEvent>);
|
||||
|
||||
register_resource!("grok_build", "SubagentEventSender", SubagentEventSender);
|
||||
register_resource!("kigi", "SubagentEventSender", SubagentEventSender);
|
||||
|
||||
// Mid-turn monitor event buffer
|
||||
|
||||
@@ -680,7 +680,7 @@ pub struct MonitorEventNotification {
|
||||
///
|
||||
/// In leader mode every session shares one [`MonitorEventBuffer`], so the
|
||||
/// drain sites filter on this to avoid surfacing one session's monitor
|
||||
/// events inside another session's turn. `None` for legacy / non-grok-build
|
||||
/// events inside another session's turn. `None` for legacy / non-kigi
|
||||
/// backends, which any session drains for backwards compatibility.
|
||||
pub owner_session_id: Option<String>,
|
||||
}
|
||||
@@ -703,7 +703,7 @@ impl MonitorEventNotification {
|
||||
/// drains its session's events via [`drain_owned`].
|
||||
pub type MonitorEventBuffer = kigi_interjection_core::EventQueue<MonitorEventNotification>;
|
||||
|
||||
register_resource!("grok_build", "MonitorEventBuffer", MonitorEventBuffer);
|
||||
register_resource!("kigi", "MonitorEventBuffer", MonitorEventBuffer);
|
||||
|
||||
/// Drain only `my_owner`'s events (the buffer is shared across sessions in
|
||||
/// leader mode); owner-less legacy events drain anywhere.
|
||||
@@ -754,7 +754,7 @@ pub struct SubagentListActiveRequest {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubagentDepthCounter(pub u32);
|
||||
|
||||
register_resource!("grok_build", "SubagentDepthCounter", SubagentDepthCounter);
|
||||
register_resource!("kigi", "SubagentDepthCounter", SubagentDepthCounter);
|
||||
|
||||
/// Session-scoped validator for model-facing `Task.model` arguments.
|
||||
///
|
||||
@@ -782,14 +782,14 @@ impl std::fmt::Debug for TaskModelValidator {
|
||||
}
|
||||
}
|
||||
|
||||
register_resource!("grok_build", "TaskModelValidator", TaskModelValidator);
|
||||
register_resource!("kigi", "TaskModelValidator", TaskModelValidator);
|
||||
|
||||
/// Carries the current session ID so TaskTool can set `parent_session_id`
|
||||
/// on the `SubagentRequest`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SessionIdResource(pub String);
|
||||
|
||||
register_resource!("grok_build", "SessionIdResource", SessionIdResource);
|
||||
register_resource!("kigi", "SessionIdResource", SessionIdResource);
|
||||
|
||||
/// Carries the current parent prompt/turn ID for TaskTool subagent scoping.
|
||||
///
|
||||
@@ -799,11 +799,7 @@ register_resource!("grok_build", "SessionIdResource", SessionIdResource);
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CurrentPromptIdResource(pub String);
|
||||
|
||||
register_resource!(
|
||||
"grok_build",
|
||||
"CurrentPromptIdResource",
|
||||
CurrentPromptIdResource
|
||||
);
|
||||
register_resource!("kigi", "CurrentPromptIdResource", CurrentPromptIdResource);
|
||||
|
||||
/// True while a `/goal` loop is active. Set by kigi-shell at turn start.
|
||||
/// When true, `TaskCompletionReminder` suppresses bg-task completion
|
||||
@@ -813,7 +809,7 @@ register_resource!(
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct GoalLoopActive(pub bool);
|
||||
|
||||
register_resource!("grok_build", "GoalLoopActive", GoalLoopActive);
|
||||
register_resource!("kigi", "GoalLoopActive", GoalLoopActive);
|
||||
|
||||
/// Thread-local tracing capture for behavioral log-emission tests.
|
||||
#[cfg(test)]
|
||||
@@ -908,12 +904,12 @@ mod tests {
|
||||
fn read_only_filter_prunes_orphaned_background_task_tools() {
|
||||
let mut config = ToolServerConfig {
|
||||
tools: vec![
|
||||
tc("GrokBuild:run_terminal_cmd", ToolKind::Execute),
|
||||
tc("GrokBuild:read_file", ToolKind::Read),
|
||||
tc("GrokBuild:list_dir", ToolKind::List),
|
||||
tc("GrokBuild:grep", ToolKind::Search),
|
||||
tc("GrokBuild:kill_task", ToolKind::KillTaskAction),
|
||||
tc("GrokBuild:get_task_output", ToolKind::BackgroundTaskAction),
|
||||
tc("Kigi:run_terminal_cmd", ToolKind::Execute),
|
||||
tc("Kigi:read_file", ToolKind::Read),
|
||||
tc("Kigi:list_dir", ToolKind::List),
|
||||
tc("Kigi:grep", ToolKind::Search),
|
||||
tc("Kigi:kill_task", ToolKind::KillTaskAction),
|
||||
tc("Kigi:get_task_output", ToolKind::BackgroundTaskAction),
|
||||
],
|
||||
behavior_preset: None,
|
||||
};
|
||||
@@ -921,27 +917,20 @@ mod tests {
|
||||
SubagentCapabilityMode::ReadOnly.filter_tool_config(&mut config);
|
||||
|
||||
let ids: Vec<&str> = config.tools.iter().map(|tc| tc.id.as_str()).collect();
|
||||
assert_eq!(
|
||||
ids,
|
||||
vec![
|
||||
"GrokBuild:read_file",
|
||||
"GrokBuild:list_dir",
|
||||
"GrokBuild:grep",
|
||||
]
|
||||
);
|
||||
assert_eq!(ids, vec!["Kigi:read_file", "Kigi:list_dir", "Kigi:grep",]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_only_filter_keeps_background_task_tools_when_task_tool_remains() {
|
||||
let mut config = ToolServerConfig {
|
||||
tools: vec![
|
||||
tc("GrokBuild:run_terminal_cmd", ToolKind::Execute),
|
||||
tc("GrokBuild:read_file", ToolKind::Read),
|
||||
tc("GrokBuild:list_dir", ToolKind::List),
|
||||
tc("GrokBuild:grep", ToolKind::Search),
|
||||
tc("GrokBuild:kill_task", ToolKind::KillTaskAction),
|
||||
tc("GrokBuild:get_task_output", ToolKind::BackgroundTaskAction),
|
||||
tc("GrokBuild:task", ToolKind::Task),
|
||||
tc("Kigi:run_terminal_cmd", ToolKind::Execute),
|
||||
tc("Kigi:read_file", ToolKind::Read),
|
||||
tc("Kigi:list_dir", ToolKind::List),
|
||||
tc("Kigi:grep", ToolKind::Search),
|
||||
tc("Kigi:kill_task", ToolKind::KillTaskAction),
|
||||
tc("Kigi:get_task_output", ToolKind::BackgroundTaskAction),
|
||||
tc("Kigi:task", ToolKind::Task),
|
||||
],
|
||||
behavior_preset: None,
|
||||
};
|
||||
@@ -952,12 +941,12 @@ mod tests {
|
||||
assert_eq!(
|
||||
ids,
|
||||
vec![
|
||||
"GrokBuild:read_file",
|
||||
"GrokBuild:list_dir",
|
||||
"GrokBuild:grep",
|
||||
"GrokBuild:kill_task",
|
||||
"GrokBuild:get_task_output",
|
||||
"GrokBuild:task",
|
||||
"Kigi:read_file",
|
||||
"Kigi:list_dir",
|
||||
"Kigi:grep",
|
||||
"Kigi:kill_task",
|
||||
"Kigi:get_task_output",
|
||||
"Kigi:task",
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -981,7 +970,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn read_write_filter_keeps_background_capable_bash_when_explicitly_enabled() {
|
||||
let mut bash = tc("GrokBuild:run_terminal_cmd", ToolKind::Execute);
|
||||
let mut bash = tc("Kigi:run_terminal_cmd", ToolKind::Execute);
|
||||
bash.params = Some(
|
||||
serde_json::json!({ "enabled_background": true })
|
||||
.as_object()
|
||||
+16
-16
@@ -11,10 +11,10 @@ pub use wait_tasks::WaitTasksTool;
|
||||
|
||||
use crate::DEFAULT_TOOL_OUTPUT_BYTES;
|
||||
use crate::implementations::BashTool;
|
||||
use crate::implementations::grok_build::task::TaskTool;
|
||||
use crate::implementations::grok_build::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::grok_build::task::types::{SubagentSnapshot, SubagentSnapshotStatus};
|
||||
use crate::implementations::grok_build_concise::BashConciseTool;
|
||||
use crate::implementations::kigi::task::TaskTool;
|
||||
use crate::implementations::kigi::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::kigi::task::types::{SubagentSnapshot, SubagentSnapshotStatus};
|
||||
use crate::implementations::kigi_concise::BashConciseTool;
|
||||
use crate::implementations::opencode::OpenCodeBashTool;
|
||||
use crate::implementations::task_output::tool::snapshot_to_result;
|
||||
use crate::types::requirements::{Expr, ToolParamsRequirement, ToolRequirement};
|
||||
@@ -58,7 +58,7 @@ pub(crate) fn capped_wait_timeout(timeout_ms: Option<u64>) -> Duration {
|
||||
|
||||
pub(crate) fn background_bash_requires_exprs() -> Vec<Expr<ToolRequirement>> {
|
||||
use crate::types::tool_metadata::ToolMetadata;
|
||||
let grok_build_bash = Expr::Value(ToolRequirement::Tool {
|
||||
let kigi_bash = Expr::Value(ToolRequirement::Tool {
|
||||
namespace: ToolMetadata::tool_namespace(&BashTool).to_string(),
|
||||
id: kigi_tool_runtime::Tool::id(&BashTool).as_str().to_string(),
|
||||
if_params: Some(Expr::Value(ToolParamsRequirement {
|
||||
@@ -66,7 +66,7 @@ pub(crate) fn background_bash_requires_exprs() -> Vec<Expr<ToolRequirement>> {
|
||||
value: Expr::Value(serde_json::Value::Bool(true)),
|
||||
})),
|
||||
});
|
||||
let grok_build_concise_bash = Expr::Value(ToolRequirement::Tool {
|
||||
let kigi_concise_bash = Expr::Value(ToolRequirement::Tool {
|
||||
namespace: ToolMetadata::tool_namespace(&BashConciseTool).to_string(),
|
||||
id: kigi_tool_runtime::Tool::id(&BashConciseTool)
|
||||
.as_str()
|
||||
@@ -83,7 +83,7 @@ pub(crate) fn background_bash_requires_exprs() -> Vec<Expr<ToolRequirement>> {
|
||||
.to_string(),
|
||||
if_params: None,
|
||||
});
|
||||
vec![grok_build_bash, grok_build_concise_bash, opencode_bash]
|
||||
vec![kigi_bash, kigi_concise_bash, opencode_bash]
|
||||
}
|
||||
|
||||
/// Shared `requires_expr` for both `get_task_output` and `wait_tasks`.
|
||||
@@ -669,13 +669,13 @@ impl crate::types::tool_metadata::ToolMetadata for TaskOutputTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
// Canonical wording lives in the shared builder; `versioned_definition`
|
||||
// renders it context-aware from the finalized toolset. This static
|
||||
// fallback mirrors the default grok-build toolset.
|
||||
// fallback mirrors the default kigi toolset.
|
||||
static DESC: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
|
||||
kigi_tool_types::build_task_output_description(&kigi_tool_types::TaskOutputToolNaming {
|
||||
monitor_tool: Some("monitor"),
|
||||
@@ -959,7 +959,7 @@ mod tests {
|
||||
kigi_tool_runtime::Tool::id(&tool).as_str(),
|
||||
"get_task_output"
|
||||
);
|
||||
// The static fallback is the shared builder's default grok-build
|
||||
// The static fallback is the shared builder's default kigi
|
||||
// rendering (monitor + task + bash + read present): concrete names, no
|
||||
// leftover template markers.
|
||||
let desc = ToolMetadata::description_template(&tool);
|
||||
@@ -1797,13 +1797,13 @@ mod tests {
|
||||
fn resources_with_backend_query() -> (
|
||||
Resources,
|
||||
tokio::sync::mpsc::UnboundedReceiver<
|
||||
crate::implementations::grok_build::task::types::SubagentEvent,
|
||||
crate::implementations::kigi::task::types::SubagentEvent,
|
||||
>,
|
||||
) {
|
||||
use crate::implementations::grok_build::task::backend::{
|
||||
use crate::implementations::kigi::task::backend::{
|
||||
ChannelBackend, SubagentBackendResource,
|
||||
};
|
||||
use crate::implementations::grok_build::task::types::SubagentEvent;
|
||||
use crate::implementations::kigi::task::types::SubagentEvent;
|
||||
use std::sync::Arc as StdArc;
|
||||
|
||||
let mut resources = resources_with_terminal(None);
|
||||
@@ -1816,10 +1816,10 @@ mod tests {
|
||||
|
||||
/// Extract a `SubagentQueryRequest` from a `SubagentEvent`, panicking on wrong variant.
|
||||
fn unwrap_query(
|
||||
event: crate::implementations::grok_build::task::types::SubagentEvent,
|
||||
) -> crate::implementations::grok_build::task::types::SubagentQueryRequest {
|
||||
event: crate::implementations::kigi::task::types::SubagentEvent,
|
||||
) -> crate::implementations::kigi::task::types::SubagentQueryRequest {
|
||||
match event {
|
||||
crate::implementations::grok_build::task::types::SubagentEvent::Query(q) => q,
|
||||
crate::implementations::kigi::task::types::SubagentEvent::Query(q) => q,
|
||||
_ => panic!("Expected SubagentEvent::Query"),
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -18,7 +18,7 @@ impl crate::types::tool_metadata::ToolMetadata for GetTerminalCommandOutputTool
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -83,7 +83,7 @@ impl kigi_tool_runtime::Tool for GetTerminalCommandOutputTool {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::implementations::grok_build::task_output::test_helpers::{
|
||||
use crate::implementations::kigi::task_output::test_helpers::{
|
||||
make_snapshot, resources_with_terminal,
|
||||
};
|
||||
use crate::types::tool_metadata::ToolMetadata;
|
||||
+5
-5
@@ -8,8 +8,8 @@
|
||||
//! tool only supports wait-all for multi-id waits.
|
||||
|
||||
use crate::DEFAULT_TOOL_OUTPUT_BYTES;
|
||||
use crate::implementations::grok_build::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::grok_build::task_output::{
|
||||
use crate::implementations::kigi::task::backend::SubagentBackendResource;
|
||||
use crate::implementations::kigi::task_output::{
|
||||
MAX_MULTI_WAIT_IDS, TaskOutputTool, resolve_tasks, wait_any_event_driven,
|
||||
};
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
@@ -27,13 +27,13 @@ impl crate::types::tool_metadata::ToolMetadata for WaitTasksTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
// Canonical wording lives in the shared builder; `versioned_definition`
|
||||
// renders it context-aware from the finalized toolset. This static
|
||||
// fallback mirrors the default grok-build toolset.
|
||||
// fallback mirrors the default kigi toolset.
|
||||
static DESC: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
|
||||
kigi_tool_types::build_wait_tasks_description(&kigi_tool_types::WaitTasksToolNaming {
|
||||
background_retrieval_tool: "get_command_or_subagent_output",
|
||||
@@ -170,7 +170,7 @@ impl kigi_tool_runtime::Tool for WaitTasksTool {
|
||||
|
||||
// wait_any: keep legacy event-driven path (not exposed on get_task_output).
|
||||
let timeout =
|
||||
crate::implementations::grok_build::task_output::capped_wait_timeout(input.timeout_ms);
|
||||
crate::implementations::kigi::task_output::capped_wait_timeout(input.timeout_ms);
|
||||
|
||||
let (terminal, backend, read_file_name, max_output_bytes) = {
|
||||
let res = resources.lock().await;
|
||||
+4
-4
@@ -158,7 +158,7 @@ pub struct TodoState {
|
||||
todos: IndexMap<TodoId, TodoItem>,
|
||||
}
|
||||
|
||||
crate::register_resource!("grok_build", "Todo", TodoState);
|
||||
crate::register_resource!("kigi", "Todo", TodoState);
|
||||
|
||||
impl TodoState {
|
||||
pub fn push(&mut self, id: TodoId, todo: TodoItem) {
|
||||
@@ -265,7 +265,7 @@ impl crate::types::tool_metadata::ToolMetadata for TodoWriteTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -609,8 +609,8 @@ mod tests {
|
||||
let snapshot = res.serialize();
|
||||
let state_map = snapshot.get("state").unwrap();
|
||||
assert!(
|
||||
state_map.get("grok_build.Todo").is_some(),
|
||||
"TodoState should serialize under 'grok_build.Todo'"
|
||||
state_map.get("kigi.Todo").is_some(),
|
||||
"TodoState should serialize under 'kigi.Todo'"
|
||||
);
|
||||
|
||||
// Deserialize into fresh Resources
|
||||
+1
-1
@@ -203,7 +203,7 @@ impl crate::types::tool_metadata::ToolMetadata for UpdateGoalTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -13,7 +13,7 @@ use super::error::WebFetchError;
|
||||
use super::http::HttpClient;
|
||||
use super::overflow::{OverflowHandler, RecoveryTools, inline_budget};
|
||||
use super::ssrf;
|
||||
use crate::implementations::grok_build::storage::SessionFileWriter;
|
||||
use crate::implementations::kigi::storage::SessionFileWriter;
|
||||
use crate::types::output::{WebFetchContent, WebFetchOutput, WebFetchSourceArtifact};
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
+5
-6
@@ -49,7 +49,7 @@ pub struct WebFetchParams {
|
||||
pub service_url: Option<String>,
|
||||
}
|
||||
|
||||
register_resource!("grok_build", "WebFetch", WebFetchParams);
|
||||
register_resource!("kigi", "WebFetch", WebFetchParams);
|
||||
|
||||
// Keep defaults here so call-sites don't have to manage unwrapping.
|
||||
// Vars are still public following other conventions though.
|
||||
@@ -92,11 +92,10 @@ impl WebFetchParams {
|
||||
/// Default allowlist for web_fetch tool.
|
||||
/// Note: GET-only preapproved domains. Path-scoped entries (e.g. vercel.com/docs) are included as-is.
|
||||
pub static DEFAULT_ALLOWED_DOMAINS: &[&str] = &[
|
||||
// xAI
|
||||
"x.ai",
|
||||
"console.x.ai",
|
||||
"docs.x.ai",
|
||||
"api.x.ai",
|
||||
// Kimi / Moonshot
|
||||
"kimi.com",
|
||||
"platform.moonshot.ai",
|
||||
"platform.moonshot.cn",
|
||||
// Programming languages
|
||||
"docs.python.org",
|
||||
"en.cppreference.com",
|
||||
+1
-1
@@ -75,7 +75,7 @@ impl crate::types::tool_metadata::ToolMetadata for WebFetchTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -50,7 +50,7 @@ impl crate::types::tool_metadata::ToolMetadata for WebSearchTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+3
-6
@@ -2,9 +2,7 @@
|
||||
|
||||
use strip_ansi_escapes::strip_str;
|
||||
|
||||
use crate::implementations::grok_build::bash::{
|
||||
BashTool, BashToolInput, BashToolOutput, KillReason,
|
||||
};
|
||||
use crate::implementations::kigi::bash::{BashTool, BashToolInput, BashToolOutput, KillReason};
|
||||
use crate::types::output::BashOutput;
|
||||
use crate::types::requirements::{Expr, ToolParamsRequirement, ToolRequirement};
|
||||
use crate::types::tool::{ToolKind, ToolNamespace};
|
||||
@@ -89,7 +87,7 @@ impl crate::types::tool_metadata::ToolMetadata for BashConciseTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildConcise
|
||||
ToolNamespace::KigiConcise
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -265,8 +263,7 @@ mod tests {
|
||||
// to_prompt_format() is a passthrough — it must NOT add another header.
|
||||
let mut bash = make_bash(0, "hello world\n");
|
||||
// Pre-bake DEFAULT (what BashTool::run() does)
|
||||
bash.output_for_prompt =
|
||||
crate::implementations::grok_build::bash::format_default_prompt(&bash);
|
||||
bash.output_for_prompt = crate::implementations::kigi::bash::format_default_prompt(&bash);
|
||||
assert!(bash.output_for_prompt.starts_with("exit: 0"));
|
||||
|
||||
// Concise post-processing (what BashConciseTool::run() does)
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
//! `GrokBuildConcise` namespace — concise variants of core GrokBuild tools.
|
||||
//! `KigiConcise` namespace — concise variants of core Kigi tools.
|
||||
//!
|
||||
//! These tools share implementation with `grok_build` via `pub(crate)` helpers
|
||||
//! These tools share implementation with `kigi` via `pub(crate)` helpers
|
||||
//! but produce concise output (compact line numbers, shorter messages,
|
||||
//! concise bash formatting).
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
//! Concise variant of the `read_file` tool.
|
||||
|
||||
use crate::implementations::grok_build::read_file::{ReadFileInput, run_read_file};
|
||||
use crate::implementations::kigi::read_file::{ReadFileInput, run_read_file};
|
||||
|
||||
const DESCRIPTION_CONCISE: &str = r#"Reads a file from the computer's filesystem. You can access any file directly by using this tool.
|
||||
It is okay to read a file that does not exist; an error will be returned.
|
||||
@@ -26,7 +26,7 @@ impl crate::types::tool_metadata::ToolMetadata for ReadFileConciseTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildConcise
|
||||
ToolNamespace::KigiConcise
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -77,7 +77,7 @@ impl kigi_tool_runtime::Tool for ReadFileConciseTool {
|
||||
use crate::types::tool_metadata::shared_resources;
|
||||
let resources = shared_resources(&ctx)?;
|
||||
|
||||
// GrokBuildConcise is not version-managed — always pass None.
|
||||
// KigiConcise is not version-managed — always pass None.
|
||||
let cwd_override = ctx
|
||||
.extensions
|
||||
.get::<kigi_tool_runtime::Cwd>()
|
||||
@@ -104,7 +104,7 @@ mod tests {
|
||||
use crate::types::tool_metadata::test_ctx;
|
||||
|
||||
use crate::computer::local::LocalFs;
|
||||
use crate::implementations::grok_build::read_file::ReadFileTool;
|
||||
use crate::implementations::kigi::read_file::ReadFileTool;
|
||||
use crate::notification::types::ToolNotificationHandle;
|
||||
use crate::types::resources::{Cwd, FileSystem, NotificationHandle, Resources};
|
||||
use std::sync::Arc;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
//! Concise variant of the `search_replace` tool.
|
||||
|
||||
use crate::implementations::grok_build::search_replace::{SearchReplaceInput, run_search_replace};
|
||||
use crate::implementations::kigi::search_replace::{SearchReplaceInput, run_search_replace};
|
||||
|
||||
/// Concise description — no read-before-edit enforcement, simplified formatting guidance.
|
||||
const DESCRIPTION_CONCISE: &str = r#"Replace an exact string in a file.
|
||||
@@ -27,7 +27,7 @@ impl crate::types::tool_metadata::ToolMetadata for SearchReplaceConciseTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildConcise
|
||||
ToolNamespace::KigiConcise
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//! ## Usage
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
//! use kigi_tools::implementations::grok_build_hashline::benchmark::*;
|
||||
//! use kigi_tools::implementations::kigi_hashline::benchmark::*;
|
||||
//!
|
||||
//! let corpus = vec![
|
||||
//! ("small.rs", "fn main() {}\n"),
|
||||
+5
-5
@@ -8,9 +8,9 @@ use std::path::Path;
|
||||
|
||||
use super::range_policy;
|
||||
use super::types::*;
|
||||
use crate::implementations::grok_build_hashline::anchor::split_lines;
|
||||
use crate::implementations::grok_build_hashline::read_file::format_hashline_content;
|
||||
use crate::implementations::grok_build_hashline::scheme::{
|
||||
use crate::implementations::kigi_hashline::anchor::split_lines;
|
||||
use crate::implementations::kigi_hashline::read_file::format_hashline_content;
|
||||
use crate::implementations::kigi_hashline::scheme::{
|
||||
Anchor, AnchorScheme, DEFAULT_SEARCH_RADIUS, ParsedAnchor, ShiftResult, ValidationResult,
|
||||
};
|
||||
|
||||
@@ -772,8 +772,8 @@ mod tests {
|
||||
PathBuf::from("/tmp/test.rs")
|
||||
}
|
||||
|
||||
use crate::implementations::grok_build_hashline::config::HashlineSchemeParams;
|
||||
use crate::implementations::grok_build_hashline::scheme::{ChunkFingerprint, ContentOnly};
|
||||
use crate::implementations::kigi_hashline::config::HashlineSchemeParams;
|
||||
use crate::implementations::kigi_hashline::scheme::{ChunkFingerprint, ContentOnly};
|
||||
|
||||
const SAMPLE: &str =
|
||||
"fn main() {\n let x = 1;\n let y = 2;\n println!(\"{x} {y}\");\n}\n";
|
||||
+6
-6
@@ -216,7 +216,7 @@ impl crate::types::tool_metadata::ToolMetadata for HashlineEditTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildHashline
|
||||
ToolNamespace::KigiHashline
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -462,9 +462,9 @@ mod tests {
|
||||
}
|
||||
|
||||
fn anchors_for(content: &str) -> Vec<String> {
|
||||
use crate::implementations::grok_build_hashline::anchor::split_lines;
|
||||
use crate::implementations::grok_build_hashline::edit::apply::anchor_suffix;
|
||||
use crate::implementations::grok_build_hashline::scheme::{AnchorScheme, ChunkFingerprint};
|
||||
use crate::implementations::kigi_hashline::anchor::split_lines;
|
||||
use crate::implementations::kigi_hashline::edit::apply::anchor_suffix;
|
||||
use crate::implementations::kigi_hashline::scheme::{AnchorScheme, ChunkFingerprint};
|
||||
let scheme = ChunkFingerprint::with_params(3, 8);
|
||||
let lines = split_lines(content);
|
||||
scheme
|
||||
@@ -620,8 +620,8 @@ mod tests {
|
||||
|
||||
// -- Diff detail tests (multi-edit compactness) -------------------------
|
||||
|
||||
fn test_scheme() -> Box<dyn crate::implementations::grok_build_hashline::scheme::AnchorScheme> {
|
||||
crate::implementations::grok_build_hashline::config::HashlineSchemeParams::default()
|
||||
fn test_scheme() -> Box<dyn crate::implementations::kigi_hashline::scheme::AnchorScheme> {
|
||||
crate::implementations::kigi_hashline::config::HashlineSchemeParams::default()
|
||||
.build_scheme()
|
||||
.unwrap()
|
||||
}
|
||||
+3
-3
@@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::computer::types::AsyncFileSystem;
|
||||
use crate::implementations::grok_build::grep::{GrepSearchInput, GrepTool, OutputMode};
|
||||
use crate::implementations::kigi::grep::{GrepSearchInput, GrepTool, OutputMode};
|
||||
|
||||
use crate::types::output::GrepSearchOutput;
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
@@ -162,7 +162,7 @@ impl crate::types::tool_metadata::ToolMetadata for HashlineGrepTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildHashline
|
||||
ToolNamespace::KigiHashline
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -342,7 +342,7 @@ mod tests {
|
||||
assert!(kigi_tool_runtime::Tool::capabilities(&tool).is_read_only);
|
||||
assert!(matches!(
|
||||
ToolMetadata::tool_namespace(&tool),
|
||||
ToolNamespace::GrokBuildHashline
|
||||
ToolNamespace::KigiHashline
|
||||
));
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//! `GrokBuildHashline` namespace — hashline-anchored read/edit/search tools.
|
||||
//! `KigiHashline` namespace — hashline-anchored read/edit/search tools.
|
||||
//!
|
||||
//! This module provides the anchor engine used by the hashline toolset:
|
||||
//! - [`AnchorScheme`] trait and implementations (Candidates A, B, C)
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
//! `hashline_read` — anchor-annotated file reading.
|
||||
//!
|
||||
//! Reuses the core file-reading logic from [`grok_build::read_file::run_read_file`]
|
||||
//! Reuses the core file-reading logic from [`kigi::read_file::run_read_file`]
|
||||
//! and post-processes the result to replace standard line-number formatting with
|
||||
//! scheme-aware anchor annotations.
|
||||
//!
|
||||
//! Output format: `ANCHOR→CONTENT` (e.g. `22:abc:rst→ let x = 1;`).
|
||||
|
||||
use crate::implementations::grok_build::read_file::{ReadFileInput, run_read_file};
|
||||
use crate::implementations::kigi::read_file::{ReadFileInput, run_read_file};
|
||||
use crate::types::context::TruncationConfig;
|
||||
|
||||
use crate::types::output::ReadFileOutput;
|
||||
@@ -105,7 +105,7 @@ impl crate::types::tool_metadata::ToolMetadata for HashlineReadTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuildHashline
|
||||
ToolNamespace::KigiHashline
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -249,7 +249,7 @@ mod tests {
|
||||
use crate::types::tool_metadata::test_ctx;
|
||||
|
||||
use crate::computer::local::LocalFs;
|
||||
use crate::implementations::grok_build::read_file::{MAX_LINES_READ, ReadFileTool};
|
||||
use crate::implementations::kigi::read_file::{MAX_LINES_READ, ReadFileTool};
|
||||
use crate::notification::types::ToolNotificationHandle;
|
||||
use crate::types::resources::{Cwd, FileSystem, NotificationHandle, Resources};
|
||||
use std::sync::Arc;
|
||||
@@ -358,7 +358,7 @@ mod tests {
|
||||
assert!(kigi_tool_runtime::Tool::capabilities(&tool).is_read_only);
|
||||
assert!(matches!(
|
||||
ToolMetadata::tool_namespace(&tool),
|
||||
ToolNamespace::GrokBuildHashline
|
||||
ToolNamespace::KigiHashline
|
||||
));
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ mod tests {
|
||||
}
|
||||
|
||||
/// No per-line clip on the hashline read path either (it formats the
|
||||
/// file content independently of grok_build `read_file`).
|
||||
/// file content independently of kigi `read_file`).
|
||||
#[tokio::test]
|
||||
async fn read_long_line_unclipped_by_default() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
@@ -13,7 +13,7 @@ pub const REQUEST_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(
|
||||
/// return the [`ConfigSource`](crate::types::config_source::ConfigSource) of each.
|
||||
///
|
||||
/// Plugin configs fill gaps (new server names) but never override user/project config.
|
||||
/// This is the canonical merge function — both session startup and `grok inspect` call it.
|
||||
/// This is the canonical merge function — both session startup and `kigi inspect` call it.
|
||||
/// Accepts both file-based `.lsp.json` paths and inline `lspServers` JSON values
|
||||
/// from plugin manifests (`plugin.json`).
|
||||
pub fn load_servers_with_plugins_sourced(
|
||||
|
||||
@@ -39,7 +39,7 @@ impl crate::types::tool_metadata::ToolMetadata for MemoryGetImpl {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
|
||||
@@ -16,7 +16,7 @@ impl crate::types::tool_metadata::ToolMetadata for MemorySearchImpl {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
pub mod codex;
|
||||
pub mod cursor_rules_on_read;
|
||||
pub mod editor_infra;
|
||||
pub mod grok_build;
|
||||
pub mod grok_build_concise;
|
||||
pub mod grok_build_hashline;
|
||||
pub mod kigi;
|
||||
pub mod kigi_concise;
|
||||
pub mod kigi_hashline;
|
||||
pub mod lsp;
|
||||
pub mod memory;
|
||||
pub mod opencode;
|
||||
@@ -13,8 +13,8 @@ pub mod skills;
|
||||
pub mod task_output;
|
||||
pub mod use_tool;
|
||||
pub mod web_search;
|
||||
pub use grok_build::bash::{BashError, BashToolInput};
|
||||
pub use grok_build::{
|
||||
pub use kigi::bash::{BashError, BashToolInput};
|
||||
pub use kigi::{
|
||||
AskUserQuestionTool, BashTool, EnterPlanModeTool, ExitPlanModeTool, GrepTool, KillTaskTool,
|
||||
ListDirTool, ReadFileTool, SearchReplaceTool, TaskOutputTool, TaskTool, TodoWriteTool,
|
||||
WaitTasksTool, WebFetchTool, WebSearchTool,
|
||||
|
||||
@@ -1095,7 +1095,7 @@ mod tests {
|
||||
|
||||
// ─── Description template shell-awareness parity tests ───
|
||||
//
|
||||
// Same shape as grok_build/bash: the opencode tool inherits the same
|
||||
// Same shape as kigi/bash: the opencode tool inherits the same
|
||||
// Unix-utility guidance and must branch on PowerShell/cmd.
|
||||
|
||||
mod description_shell_branches {
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::computer::types::AsyncFileSystem;
|
||||
use crate::implementations::grok_build::search_replace::CONTEXT_LINES;
|
||||
use crate::implementations::grok_build::search_replace::helpers::{
|
||||
use crate::implementations::kigi::search_replace::CONTEXT_LINES;
|
||||
use crate::implementations::kigi::search_replace::helpers::{
|
||||
build_edit_details, render_snippet, replace_using_positions,
|
||||
};
|
||||
use crate::notification::types::FileWritten;
|
||||
@@ -467,8 +467,8 @@ async fn handle_replacement(
|
||||
}
|
||||
|
||||
// Note: `replace_at_positions`, `render_snippet`, and `build_edit_details`
|
||||
// are imported from `grok_build::search_replace::helpers` — shared across
|
||||
// both the grok_build and opencode edit tools.
|
||||
// are imported from `kigi::search_replace::helpers` — shared across
|
||||
// both the kigi and opencode edit tools.
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────────────
|
||||
// Tests
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::process::Stdio;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::implementations::grok_build::grep::ripgrep::rg_path;
|
||||
use crate::implementations::kigi::grep::ripgrep::rg_path;
|
||||
use crate::types::output::ToolOutput;
|
||||
#[allow(unused_imports)]
|
||||
use crate::types::resources::{
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::process::Stdio;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::implementations::grok_build::grep::ripgrep::rg_path;
|
||||
use crate::implementations::kigi::grep::ripgrep::rg_path;
|
||||
use crate::types::output::{GrepFileMatch, GrepLineMatch, GrepSearchOutput};
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
#[allow(unused_imports)]
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//! Most tools follow the opencode parameter
|
||||
//! naming conventions (e.g., `read`/`edit` use `filePath`, `oldString`,
|
||||
//! `newString`); `write` is the exception — its input was normalized to
|
||||
//! snake_case (`file_path`) for grok_build consistency.
|
||||
//! snake_case (`file_path`) for kigi consistency.
|
||||
|
||||
pub mod bash;
|
||||
pub mod edit;
|
||||
|
||||
@@ -215,8 +215,7 @@ impl kigi_tool_runtime::Tool for ReadTool {
|
||||
// Check for images via magic-byte detection. Route through
|
||||
// compression — raw bytes (truncated or non-endpoint formats)
|
||||
// must never reach the conversation.
|
||||
if let Ok(meta) =
|
||||
crate::implementations::grok_build::read_file::bytes_to_metadata(&file_bytes)
|
||||
if let Ok(meta) = crate::implementations::kigi::read_file::bytes_to_metadata(&file_bytes)
|
||||
&& meta.is_image()
|
||||
{
|
||||
return Ok(crate::implementations::read_file::image::image_read_output(
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
//! `priority` — no caller-supplied IDs.
|
||||
//!
|
||||
//! State is stored as `State<TodoState>` in Resources, shared with the
|
||||
//! grok_build todo infrastructure.
|
||||
//! kigi todo infrastructure.
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::implementations::grok_build::todo::{TodoItem, TodoPriority, TodoState, TodoStatus};
|
||||
use crate::implementations::kigi::todo::{TodoItem, TodoPriority, TodoState, TodoStatus};
|
||||
use crate::types::output::{TodoWriteOutput, TodoWriteSuccess};
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
#[allow(unused_imports)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Shared image/PDF/metadata helpers for read tools (grok_build, etc.).
|
||||
//! Shared image/PDF/metadata helpers for read tools (kigi, etc.).
|
||||
|
||||
pub mod image;
|
||||
pub mod metadata;
|
||||
|
||||
@@ -267,7 +267,7 @@ pub fn raw_text_to_file_content(text: String) -> ReadFileOutput {
|
||||
}
|
||||
|
||||
enum PageTextStyle {
|
||||
GrokBuild,
|
||||
Kigi,
|
||||
Cursor { total_pages: usize },
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ fn extract_page_texts(
|
||||
text.push('\n');
|
||||
}
|
||||
match style {
|
||||
PageTextStyle::GrokBuild => {
|
||||
PageTextStyle::Kigi => {
|
||||
writeln!(&mut text, "--- Page {} ---", page_idx + 1).ok();
|
||||
}
|
||||
PageTextStyle::Cursor { .. } => {}
|
||||
@@ -317,7 +317,7 @@ fn extract_pdf_plain_text(bytes: Vec<u8>, style: PageTextStyle) -> Result<String
|
||||
let (doc, page_count) = open_pdf_document(bytes)?;
|
||||
let page_indices: Vec<usize> = (0..page_count).collect();
|
||||
let style = match style {
|
||||
PageTextStyle::GrokBuild => PageTextStyle::GrokBuild,
|
||||
PageTextStyle::Kigi => PageTextStyle::Kigi,
|
||||
PageTextStyle::Cursor { .. } => PageTextStyle::Cursor {
|
||||
total_pages: page_count,
|
||||
},
|
||||
@@ -328,7 +328,7 @@ fn extract_pdf_plain_text(bytes: Vec<u8>, style: PageTextStyle) -> Result<String
|
||||
/// Extract plain text from all PDF pages (no auto-read page limit).
|
||||
#[cfg(test)]
|
||||
pub(crate) fn extract_pdf_plain_text_all(bytes: Vec<u8>) -> Result<String, String> {
|
||||
extract_pdf_plain_text(bytes, PageTextStyle::GrokBuild)
|
||||
extract_pdf_plain_text(bytes, PageTextStyle::Kigi)
|
||||
}
|
||||
|
||||
/// Plain text from all PDF pages in the `Read` format.
|
||||
@@ -341,7 +341,7 @@ pub(crate) fn extract_pdf_text(
|
||||
pages_spec: Option<&str>,
|
||||
) -> Result<ReadFileOutput, String> {
|
||||
let (doc, _page_count, page_indices) = open_pdf_and_resolve_pages(bytes, pages_spec)?;
|
||||
let text = extract_page_texts(&doc, &page_indices, PageTextStyle::GrokBuild)?;
|
||||
let text = extract_page_texts(&doc, &page_indices, PageTextStyle::Kigi)?;
|
||||
Ok(raw_text_to_file_content(text))
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ impl crate::types::tool_metadata::ToolMetadata for SearchTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -697,8 +697,8 @@ mod tests {
|
||||
#[test]
|
||||
fn hash_value_pinned_output() {
|
||||
// Pin a known input/output pair so accidental hasher changes are caught.
|
||||
let h = hash_value(&"grok-mcp-fingerprint-stability-test");
|
||||
assert_eq!(h, hash_value(&"grok-mcp-fingerprint-stability-test"));
|
||||
let h = hash_value(&"kigi-mcp-fingerprint-stability-test");
|
||||
assert_eq!(h, hash_value(&"kigi-mcp-fingerprint-stability-test"));
|
||||
// The value must not change across runs (FNV-1a is deterministic).
|
||||
// If this assertion fails, the hasher implementation was modified.
|
||||
assert_ne!(h, 0, "hash should be non-zero for non-empty input");
|
||||
|
||||
@@ -22,7 +22,7 @@ pub const MAX_SKILL_WALK_DEPTH: usize = 5;
|
||||
///
|
||||
/// `skills` is the standard layout (`.kigi/skills/`, `.claude/skills/`,
|
||||
/// `.cursor/skills/`). The product-specific `skills-cursor/` layout is no
|
||||
/// longer scanned — it pulled vendor default skills into Grok Build sessions.
|
||||
/// longer scanned — it pulled vendor default skills into Kigi sessions.
|
||||
const SKILL_SUBDIRS: &[&str] = &["skills"];
|
||||
|
||||
/// Cursor ships these default skills in `~/.cursor/skills-cursor/`
|
||||
@@ -815,7 +815,7 @@ pub fn parse_skill_files(skill_files: Vec<(PathBuf, SkillScope)>) -> Vec<SkillIn
|
||||
|
||||
// Drop vendor-shipped default skills (vendor builtins) found under
|
||||
// a `/.cursor/` or `/.claude/` path. Always applied, independent of the
|
||||
// per-vendor toggle, so vendor builtins never leak into Grok Build.
|
||||
// per-vendor toggle, so vendor builtins never leak into Kigi.
|
||||
skills.retain(|s| !is_vendor_default_skill(&s.path, &s.name));
|
||||
|
||||
skills
|
||||
@@ -1467,17 +1467,17 @@ model: test-model
|
||||
)
|
||||
.unwrap();
|
||||
// Same name under /.kigi/ → kept (user content).
|
||||
let grok_shell = tmp.path().join(".kigi").join("skills").join("shell");
|
||||
std::fs::create_dir_all(&grok_shell).unwrap();
|
||||
let kigi_shell = tmp.path().join(".kigi").join("skills").join("shell");
|
||||
std::fs::create_dir_all(&kigi_shell).unwrap();
|
||||
std::fs::write(
|
||||
grok_shell.join("SKILL.md"),
|
||||
kigi_shell.join("SKILL.md"),
|
||||
"---\nname: shell\ndescription: user content\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let skills = parse_skill_files(vec![
|
||||
(cursor_shell.join("SKILL.md"), SkillScope::User),
|
||||
(grok_shell.join("SKILL.md"), SkillScope::User),
|
||||
(kigi_shell.join("SKILL.md"), SkillScope::User),
|
||||
]);
|
||||
assert_eq!(skills.len(), 1, "cursor builtin must be dropped");
|
||||
assert!(skills[0].path.contains("/.kigi/"));
|
||||
@@ -1523,9 +1523,9 @@ model: test-model
|
||||
"---\nname: claude-dyn\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
let grok_skill = sub.join(".kigi").join("skills").join("grok-dyn");
|
||||
std::fs::create_dir_all(&grok_skill).unwrap();
|
||||
std::fs::write(grok_skill.join("SKILL.md"), "---\nname: grok-dyn\n---\n").unwrap();
|
||||
let kigi_skill = sub.join(".kigi").join("skills").join("kigi-dyn");
|
||||
std::fs::create_dir_all(&kigi_skill).unwrap();
|
||||
std::fs::write(kigi_skill.join("SKILL.md"), "---\nname: kigi-dyn\n---\n").unwrap();
|
||||
|
||||
let file = sub.join("file.rs");
|
||||
std::fs::write(&file, "fn main() {}").unwrap();
|
||||
@@ -1541,15 +1541,15 @@ model: test-model
|
||||
);
|
||||
let names_on: Vec<&str> = on.iter().map(|s| s.name.as_str()).collect();
|
||||
assert!(
|
||||
names_on.contains(&"grok-dyn"),
|
||||
"grok-dyn missing: {names_on:?}"
|
||||
names_on.contains(&"kigi-dyn"),
|
||||
"kigi-dyn missing: {names_on:?}"
|
||||
);
|
||||
assert!(
|
||||
names_on.contains(&"claude-dyn"),
|
||||
"claude-dyn should be found when claude.skills on: {names_on:?}"
|
||||
);
|
||||
|
||||
// claude.skills OFF → only grok-dyn discovered.
|
||||
// claude.skills OFF → only kigi-dyn discovered.
|
||||
let mut compat_off = CompatConfig::default();
|
||||
compat_off.claude.skills = false;
|
||||
let mut checked2 = HashSet::new();
|
||||
@@ -1562,8 +1562,8 @@ model: test-model
|
||||
);
|
||||
let names_off: Vec<&str> = off.iter().map(|s| s.name.as_str()).collect();
|
||||
assert!(
|
||||
names_off.contains(&"grok-dyn"),
|
||||
"grok-dyn missing: {names_off:?}"
|
||||
names_off.contains(&"kigi-dyn"),
|
||||
"kigi-dyn missing: {names_off:?}"
|
||||
);
|
||||
assert!(
|
||||
!names_off.contains(&"claude-dyn"),
|
||||
|
||||
@@ -34,7 +34,7 @@ pub struct SkillOutput {
|
||||
}
|
||||
|
||||
// Old `SkillToolImpl` + `impl Tool` deleted.
|
||||
// New implementation is in `grok_build/skill/`.
|
||||
// New implementation is in `kigi/skill/`.
|
||||
|
||||
/// Build the formatted skill message shown to the model.
|
||||
///
|
||||
@@ -238,7 +238,7 @@ pub struct SubstitutionContext<'a> {
|
||||
|
||||
/// Apply variable substitutions to skill content.
|
||||
///
|
||||
/// Supported variables (Grok-native names + compat aliases):
|
||||
/// Supported variables (Kigi-native names + compat aliases):
|
||||
///
|
||||
/// | Variable | Alias | Description |
|
||||
/// |----------|-------|-------------|
|
||||
@@ -478,7 +478,7 @@ pub fn extract_skill_body(content: &str) -> String {
|
||||
///
|
||||
/// Public entrypoint for the shell crate to load skill content at
|
||||
/// prompt-assembly time (the new zero-round-trip path). The private
|
||||
/// `load_skill_content` in `grok_build/skill/mod.rs` is a duplicate
|
||||
/// `load_skill_content` in `kigi/skill/mod.rs` is a duplicate
|
||||
/// of this.
|
||||
pub async fn load_skill_content(skill: &SkillInfo) -> Result<String, String> {
|
||||
let path = std::path::Path::new(&skill.path);
|
||||
@@ -910,7 +910,7 @@ Step 2: Check for bugs.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grok_plugin_aliases_substitution() {
|
||||
fn test_kigi_plugin_aliases_substitution() {
|
||||
let mut content = "Root ${KIGI_PLUGIN_ROOT}, data ${KIGI_PLUGIN_DATA}".to_string();
|
||||
apply_substitutions(
|
||||
&mut content,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Task output tool — old `impl Tool` deleted.
|
||||
//! Helper functions remain for use by `grok_build/task_output/`.
|
||||
//! Helper functions remain for use by `kigi/task_output/`.
|
||||
|
||||
use crate::computer::types::TaskSnapshot;
|
||||
use crate::types::process_manager::format_system_time_rfc3339;
|
||||
|
||||
@@ -58,7 +58,7 @@ impl Default for UseToolParams {
|
||||
}
|
||||
}
|
||||
|
||||
crate::register_resource!("grok_build", "UseTool", UseToolParams);
|
||||
crate::register_resource!("kigi", "UseTool", UseToolParams);
|
||||
|
||||
/// Meta tool that dispatches calls to MCP tools discovered via `search_tool`.
|
||||
///
|
||||
@@ -130,7 +130,7 @@ impl crate::types::tool_metadata::ToolMetadata for UseTool {
|
||||
}
|
||||
|
||||
fn tool_namespace(&self) -> ToolNamespace {
|
||||
ToolNamespace::GrokBuild
|
||||
ToolNamespace::Kigi
|
||||
}
|
||||
|
||||
fn description_template(&self) -> &str {
|
||||
@@ -790,7 +790,7 @@ mod tests {
|
||||
fn classify_python_repr_single_line_is_long_line_text() {
|
||||
// mcp-server-sqlite returns a Python repr of rows (single quotes) on one
|
||||
// long line — JSON-ish but invalid JSON; the long-line case still catches it.
|
||||
let row = "{'id': 0, 'name': 'user0', 'email': 'u0@x.ai', 'age': 20}";
|
||||
let row = "{'id': 0, 'name': 'user0', 'email': 'u0@example.com', 'age': 20}";
|
||||
let payload = format!("[{}]", vec![row; 60].join(", "));
|
||||
assert!(payload.len() > LONG_LINE_BYTES && !payload.contains('\n'));
|
||||
let kind = McpDumpKind::classify(&payload);
|
||||
@@ -819,7 +819,7 @@ mod tests {
|
||||
// CSV is line-addressable (grep/awk work) → Other, no steer.
|
||||
let mut csv = String::from("id,name,email,age\n");
|
||||
for i in 0..50 {
|
||||
csv.push_str(&format!("{i},user{i},u{i}@x.ai,{}\n", 20 + i));
|
||||
csv.push_str(&format!("{i},user{i},u{i}@example.com,{}\n", 20 + i));
|
||||
}
|
||||
let kind = McpDumpKind::classify(&csv);
|
||||
assert_eq!(kind, McpDumpKind::Other);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user