M0: compilable skeleton — Kigi 0.1.0 fork surgery

Hard fork of xai-org/grok-build (Apache-2.0) re-targeted as Kigi, an
unofficial Kimi Code CLI community build.

Rename & identity
- 72 xai-*/xai-grok-* crates -> kigi-* (explicit: xai-grok-pager-bin ->
  kigi-bin [binary `kigi`], xai-grok-pager -> kigi-tui; rest mechanical);
  ptyctl, ptyctl-cli, third_party/ unchanged; proto package
  xai.grok.tools.v1 -> kigi.tools.v1
- Config home ~/.kigi (KIGI_SHARE_DIR override), env prefix GROK_* ->
  KIGI_*, `kigi --version` carries the unofficial-community-build notice
- clap identity, help text, startup banner, prompt templates rebranded
  (templates re-encrypted)

Deletions (PRD removal list #5/#6/#7/#9/#10)
- voice input (xai-grok-voice) and all TUI wiring
- telemetry: Mixpanel client, external OTel stream, Sentry, OTLP layers,
  trace/GCS/S3 upload queues (kigi-file-utils halved), workspace upload
  module & dc_log, heap-profile uploader, auth-diagnostics uploader,
  session-analytics halves of feedback; local zero-egress observability
  preserved in new kigi-log crate (unified log, --debug firehose,
  subsystem file logs, opt-in instrumentation)
- announcements (crate, remote-settings fields, TUI surfaces)
- plugin marketplace (crate, sources/browse/CTA/extensions-modal tab);
  direct plugin install/uninstall/update via kigi-agent git_install kept
- relay/gateway/assets endpoints and features (agent relay, headless
  relay transport, gateway bridge, LeaderEnvUrls); leader IPC socket now
  ~/.kigi/leader.sock + KIGI_LEADER_SOCKET, no ws-url derivation
- functional types rehomed instead of deleted: PermissionMode ->
  kigi-config-types, McpInitStrategy -> kigi-mcp, PrCreationSource ->
  session signals, TerminalDiagnostics -> kigi-pager-render, agent_id ->
  shell util

Endpoints
- kigi-env rewritten: single production KigiEndpoints {coding_api_base_url
  https://api.kimi.com/coding/v1 (KIGI_CODE_BASE_URL), oauth_host
  https://auth.kimi.com (KIGI_OAUTH_HOST), update_base_url (GitHub
  Releases API), upgrade_page_url}; GrokBuildEnvironment enum deleted

Toolchain & workspace hygiene
- Rust 1.97.0 pinned; edition 2024; full cargo update; git2 hoisted to
  workspace at 0.21 (Option->Result API migration), quick-xml 0.41
- Root Cargo.toml hand-maintained (PRD §8.1): version 0.1.0 inherited by
  all members, members sorted, unused deps pruned
- cargo-deny advisories gate (deny.toml with documented transitive
  exceptions); CI workflow (check/clippy/fmt/deny/test, macOS+Linux)
- cross-crate test seams re-gated behind `test-support` cargo feature;
  insta snapshot baselines renamed to the kigi_tui prefix
- clippy --workspace --all-targets: zero warnings; fmt clean

Fixes surfaced by the port
- updater probe/installer divergence (bin/kigi vs bin/grok symlink set)
- idle model-metadata refresh dead under KIGI_CODE_BASE_URL override
  (new is_effective_coding_endpoint_url, loopback+override aware)
- macOS symlinked-TMPDIR fixture canonicalization (foreign_sessions,
  fast-worktree); RSS measurement tests serialized via serial_test

Docs & legal (Apache §4)
- NOTICE added (upstream attribution + change statement); THIRD-PARTY
  notices sustained; kigi-tools ported-code notices extended; README,
  CONTRIBUTING, SECURITY, AGENTS.md rewritten

Out of scope for M0 (tracked): Kimi auth/inference (M1), search/fetch,
command parity, config import (M2), Computer Hub excision & final
brand-token sweep (M2), distribution & self-update rewrite (M3).
This commit is contained in:
ZacharyZhang-NY committed 2026-07-17 05:31:01 -04:00
commit d6c20fc13f
2612 files changed
+1353757

No files matched your search

+137
View File
@@ -0,0 +1,137 @@
use crate::layout::rank::util::slack;
use crate::{GraphConfig, GraphEdge, GraphNode};
use graphlib_rust::{Edge, Graph, GraphOption};
/*
* Constructs a spanning tree with tight edges and adjusted the input node's
* ranks to achieve this. A tight edge is one that is has a length that matches
* its "minlen" attribute.
*
* The basic structure for this function is derived from Gansner, et al., "A
* Technique for Drawing Directed Graphs."
*
* Pre-conditions:
*
* 1. Graph must be a DAG.
* 2. Graph must be connected.
* 3. Graph must have at least one node.
* 5. Graph nodes must have been previously assigned a "rank" property that
* respects the "minlen" property of incident edges.
* 6. Graph edges must have a "minlen" property.
*
* Post-conditions:
*
* - Graph nodes will have their rank adjusted to ensure that all edges are
* tight.
*
* Returns a tree (undirected graph) that is constructed using only "tight"
* edges.
*/
pub fn feasible_tree(
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
) -> Graph<GraphConfig, GraphNode, GraphEdge> {
let mut t: Graph<GraphConfig, GraphNode, GraphEdge> = Graph::new(Some(GraphOption {
directed: Some(false),
multigraph: Some(false),
compound: Some(false),
}));
// Choose arbitrary node from which to start our tree
let start = g.nodes().first().cloned().unwrap_or("".to_string());
let size = g.node_count();
t.set_node(start, Some(GraphNode::default()));
while tight_tree(&mut t, g) < size {
if let Some(edge) = find_min_stack_edge(&t, g) {
let delta = if t.has_node(&edge.v) {
slack(g, &edge)
} else {
-1 * slack(g, &edge)
};
shift_ranks(&t, g, delta);
}
}
t
}
/*
* Finds a maximal tree of tight edges and returns the number of nodes in the
* tree.
*/
fn tight_tree(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &Graph<GraphConfig, GraphNode, GraphEdge>,
) -> usize {
fn dfs(
v: &String,
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &Graph<GraphConfig, GraphNode, GraphEdge>,
) {
let node_edges = g.node_edges(v, None).unwrap_or(vec![]);
for node_edge in node_edges {
let edge_v = node_edge.v.clone();
let mut _w: Option<&String> = None;
if v == &edge_v {
_w = Some(&node_edge.w);
} else {
_w = Some(&edge_v);
}
let w = _w.unwrap().clone();
if !t.has_node(&w) && slack(g, &node_edge) == 0 {
t.set_node(w.clone(), Some(GraphNode::default()));
let _ = t.set_edge(&v, &w, Some(GraphEdge::default()), None);
dfs(&w, t, g);
}
}
}
let nodes = t.nodes();
for node_id in nodes.into_iter() {
dfs(&node_id, t, g);
}
return t.node_count();
}
/*
* Finds the edge with the smallest slack that is incident on tree and returns
* it.
*/
fn find_min_stack_edge(
t: &Graph<GraphConfig, GraphNode, GraphEdge>,
g: &Graph<GraphConfig, GraphNode, GraphEdge>,
) -> Option<Edge> {
let edges = g.edges();
let result = edges
.iter()
.map(|e| {
let mut e_: Option<i32> = None;
if t.has_node(&e.v) != t.has_node(&e.w) {
e_ = Some(slack(g, e));
}
(e, e_)
})
.filter(|(_, e_)| e_.is_some())
.min_by(|(_, e1_), (_, e2_)| e1_.unwrap().cmp(&e2_.unwrap()));
if result.is_some() {
Some(result.unwrap().0.clone())
} else {
None
}
}
fn shift_ranks(
t: &Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
delta: i32,
) {
let nodes = t.nodes();
for node_id in nodes.into_iter() {
let node_ = g.node_mut(&node_id);
if let Some(node) = node_ {
node.rank = Some(node.rank.unwrap_or(0) + delta);
}
}
}
+53
View File
@@ -0,0 +1,53 @@
pub mod feasible_tree;
pub mod network_simplex;
pub mod util;
use crate::layout::rank::feasible_tree::feasible_tree;
use crate::layout::rank::network_simplex::network_simplex;
use crate::layout::rank::util::longest_path;
use crate::{GraphConfig, GraphEdge, GraphNode};
use graphlib_rust::Graph;
/*
* Assigns a rank to each node in the input graph that respects the "minlen"
* constraint specified on edges between nodes.
*
* This basic structure is derived from Gansner, et al., "A Technique for
* Drawing Directed Graphs."
*
* Pre-conditions:
*
* 1. Graph must be a connected DAG
* 2. Graph nodes must be objects
* 3. Graph edges must have "weight" and "minlen" attributes
*
* Post-conditions:
*
* 1. Graph nodes will have a "rank" attribute based on the results of the
* algorithm. Ranks can start at any index (including negative), we'll
* fix them up later.
*/
pub fn rank(g: &mut Graph<GraphConfig, GraphNode, GraphEdge>) {
let _ranker = g.graph().ranker.clone();
match _ranker {
Some(ranker) => {
let ranker_str = &*ranker;
if ranker_str == "network-simplex" {
network_simplex(g);
} else if ranker_str == "tight-tree" {
tight_tree_ranker(g);
} else if ranker_str == "longest-path" {
longest_path(g);
}
}
_ => {
network_simplex(g);
}
}
}
fn tight_tree_ranker(g: &mut Graph<GraphConfig, GraphNode, GraphEdge>) {
longest_path(g);
feasible_tree(g);
}
@@ -0,0 +1,365 @@
use std::collections::HashMap;
use crate::layout::rank::feasible_tree::feasible_tree;
use crate::layout::rank::util::{longest_path, slack};
use crate::layout::util;
use crate::{GraphConfig, GraphEdge, GraphNode};
use graphlib_rust::algo::postorder::postorder;
use graphlib_rust::{Edge, Graph};
use ordered_hashmap::OrderedHashMap;
/*
* The network simplex algorithm assigns ranks to each node in the input graph
* and iteratively improves the ranking to reduce the length of edges.
*
* Preconditions:
*
* 1. The input graph must be a DAG.
* 2. All nodes in the graph must have an object value.
* 3. All edges in the graph must have "minlen" and "weight" attributes.
*
* Postconditions:
*
* 1. All nodes in the graph will have an assigned "rank" attribute that has
* been optimized by the network simplex algorithm. Ranks start at 0.
*
*
* A rough sketch of the algorithm is as follows:
*
* 1. Assign initial ranks to each node. We use the longest path algorithm,
* which assigns ranks to the lowest position possible. In general this
* leads to very wide bottom ranks and unnecessarily long edges.
* 2. Construct a feasible tight tree. A tight tree is one such that all
* edges in the tree have no slack (difference between length of edge
* and minlen for the edge). This by itself greatly improves the assigned
* rankings by shorting edges.
* 3. Iteratively find edges that have negative cut values. Generally a
* negative cut value indicates that the edge could be removed and a new
* tree edge could be added to produce a more compact graph.
*
* Much of the algorithms here are derived from Gansner, et al., "A Technique
* for Drawing Directed Graphs." The structure of the file roughly follows the
* structure of the overall algorithm.
*/
pub fn network_simplex(g: &mut Graph<GraphConfig, GraphNode, GraphEdge>) {
let mut simplified = util::simplify(g);
longest_path(&mut simplified);
let mut t: Graph<GraphConfig, GraphNode, GraphEdge> = feasible_tree(&mut simplified);
init_low_lim_values(&mut t, None);
init_cut_values(&mut t, &mut simplified);
while let Some(e) = leave_edge(&t) {
let Some(f) = enter_edge(&t, &simplified, &e) else {
break;
};
exchange_edges(&mut t, &mut simplified, &e, f);
}
for v in g.nodes() {
let Some(node) = g.node_mut(&v) else {
continue;
};
let Some(simple_node) = simplified.node(&v) else {
continue;
};
node.rank = simple_node.rank;
}
}
/*
* Initializes cut values for all edges in the tree.
*/
fn init_cut_values(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
) {
let node_ids = t.nodes();
let mut vs = postorder(t, &node_ids);
vs.pop();
for node_id in vs {
assign_cut_value(t, g, &node_id);
}
}
/*
* Given the tight tree, its graph, and a child in the graph calculate and
* return the cut value for the edge between the child and its parent.
*/
fn assign_cut_value(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
child: &String,
) {
let cutvalue = calc_cut_value(t, g, child);
let child_lab_ = t.node_mut(child);
if let Some(child_lab) = child_lab_ {
let parent = child_lab.parent.clone().unwrap_or("".to_string());
let edge_label_ = t.edge_mut(&child, &parent, None);
if let Some(edge_label) = edge_label_ {
edge_label.cutvalue = Some(cutvalue);
}
}
}
/*
* Given the tight tree, its graph, and a child in the graph calculate and
* return the cut value for the edge between the child and its parent.
*/
fn calc_cut_value(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
child: &String,
) -> f32 {
// The accumulated cut value for the edge between this node and its parent
let mut cut_value = 0.0;
let child_lab_ = t.node_mut(child);
if let Some(child_lab) = child_lab_ {
let parent = child_lab.parent.clone().unwrap_or("".to_string());
// True if the child is on the tail end of the edge in the directed graph
let mut child_is_tail = true;
// The graph's view of the tree edge we're inspecting
let mut graph_edge = g.edge_mut(child, &parent, None);
if graph_edge.is_none() {
child_is_tail = false;
graph_edge = g.edge_mut(&parent, &child, None);
}
cut_value = graph_edge
.cloned()
.unwrap_or(GraphEdge::default())
.weight
.unwrap_or(0.0);
let edge_objs_ = g.node_edges(child, None);
if let Some(edge_objs) = edge_objs_ {
for e in edge_objs {
let is_out_edge = &e.v == child;
let other = if is_out_edge {
e.w.clone()
} else {
e.v.clone()
};
if other != parent {
let points_to_head = is_out_edge == child_is_tail;
let other_weight = g
.edge_with_obj(&e)
.unwrap_or(&GraphEdge::default())
.weight
.unwrap_or(0.0);
cut_value += if points_to_head {
other_weight
} else {
-other_weight
};
if is_tree_edge(t, child, &other) {
let out_cut_value = t
.edge(&child, &other, None)
.unwrap_or(&GraphEdge::default())
.cutvalue
.unwrap_or(0.0);
cut_value += if points_to_head {
-out_cut_value
} else {
out_cut_value
}
}
}
}
}
}
cut_value
}
fn init_low_lim_values(tree: &mut Graph<GraphConfig, GraphNode, GraphEdge>, root_: Option<String>) {
let mut root = tree.nodes().first().cloned().unwrap_or("".to_string());
if root_.is_some() {
root = root_.unwrap();
}
let mut visited: OrderedHashMap<String, bool> = OrderedHashMap::new();
dfs_assign_low_lim(tree, &mut visited, 1, &root, None);
}
fn dfs_assign_low_lim(
tree: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
visited: &mut OrderedHashMap<String, bool>,
next_lim_: usize,
v: &String,
parent: Option<&String>,
) -> usize {
let low = next_lim_.clone();
let mut next_lim = next_lim_.clone();
visited.entry(v.clone()).or_insert(true);
let neighbors_ = tree.neighbors(v);
if let Some(neighbors) = neighbors_ {
for w in neighbors.into_iter() {
if !visited.contains_key(&w) {
next_lim = dfs_assign_low_lim(tree, visited, next_lim.clone(), &w, Some(v));
}
}
}
let label_ = tree.node_mut(v);
if let Some(label) = label_ {
label.low = Some(low);
label.lim = Some(next_lim.clone());
next_lim += 1;
if parent.is_some() {
label.parent = Some(parent.cloned().unwrap());
} else {
// TODO should be able to remove this when we incrementally update low lim
label.parent = None;
}
}
next_lim
}
fn leave_edge(tree: &Graph<GraphConfig, GraphNode, GraphEdge>) -> Option<Edge> {
let edge_objs = tree.edges();
edge_objs
.iter()
.find(|edge_obj| {
tree.edge_with_obj(edge_obj)
.unwrap_or(&GraphEdge::default())
.cutvalue
.unwrap_or(0.0)
< 0.0
})
.cloned()
}
fn enter_edge(
t: &Graph<GraphConfig, GraphNode, GraphEdge>,
g: &Graph<GraphConfig, GraphNode, GraphEdge>,
edge: &Edge,
) -> Option<Edge> {
let mut v = edge.v.clone();
let mut w = edge.w.clone();
// For the rest of this function we assume that v is the tail and w is the
// head, so if we don't have this edge in the graph we should flip it to
// match the correct orientation.
if !g.has_edge(&v, &w, None) {
v = edge.w.clone();
w = edge.v.clone();
}
let v_label = t.node(&v).cloned().unwrap_or(GraphNode::default());
let w_label = t.node(&w).cloned().unwrap_or(GraphNode::default());
let mut tail_label = &v_label;
let mut flip = false;
// If the root is in the tail of the edge then we need to flip the logic that
// checks for the head and tail nodes in the candidates function below.
if v_label.lim.clone().unwrap_or(0) > w_label.lim.clone().unwrap_or(0) {
tail_label = &w_label;
flip = true;
}
let edge_objs = g.edges();
let candidates = edge_objs.iter().filter(|edge_obj| {
let v_node = t.node(&edge_obj.v).cloned().unwrap_or(GraphNode::default());
let w_node = t.node(&edge_obj.w).cloned().unwrap_or(GraphNode::default());
flip == is_descendant(&v_node, tail_label) && flip != is_descendant(&w_node, tail_label)
});
candidates
.min_by(|e1, e2| slack(g, e1).cmp(&slack(g, e2)))
.cloned()
}
fn exchange_edges(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
e: &Edge,
f: Edge,
) {
let v = e.v.clone();
let w = e.w.clone();
t.remove_edge(&v, &w, None);
let _ = t.set_edge(&f.v, &f.w, Some(GraphEdge::default()), None);
init_low_lim_values(t, None);
init_cut_values(t, g);
update_ranks(t, g);
}
fn update_ranks(
t: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
) {
let Some(root) = t.nodes().first().cloned() else {
return;
};
let mut children: HashMap<String, Vec<String>> = HashMap::new();
for v in t.nodes() {
let parent = t.node(&v).unwrap_or(&GraphNode::default()).parent.clone();
let Some(parent) = parent else {
continue;
};
children.entry(parent).or_default().push(v);
}
let mut stack: Vec<String> = vec![root.clone()];
while let Some(parent) = stack.pop() {
let Some(vs) = children.get(&parent).cloned() else {
continue;
};
for v in vs {
let mut edge = g.edge(&v, &parent, None);
let mut flipped = false;
if edge.is_none() {
edge = g.edge(&parent, &v, None);
flipped = true;
}
let minlen = edge.unwrap_or(&GraphEdge::default()).minlen.unwrap_or(0.0);
let parent_rank = g
.node(&parent)
.unwrap_or(&GraphNode::default())
.rank
.unwrap_or(0);
if let Some(v_node) = g.node_mut(&v) {
v_node.rank = Some(
parent_rank
+ if flipped {
minlen as i32
} else {
-(minlen as i32)
},
);
}
stack.push(v);
}
}
}
/*
* Returns true if the edge is in the tree.
*/
fn is_tree_edge(tree: &Graph<GraphConfig, GraphNode, GraphEdge>, u: &String, v: &String) -> bool {
tree.has_edge(&u, &v, None)
}
/*
* Returns true if the specified node is descendant of the root node per the
* assigned low and lim attributes in the tree.
*/
fn is_descendant(v_label: &GraphNode, root_label: &GraphNode) -> bool {
let low = root_label.low.clone().unwrap_or(0);
let v_lim = v_label.lim.clone().unwrap_or(0);
let root_lim = root_label.lim.clone().unwrap_or(0);
low <= v_lim && v_lim <= root_lim
}
+99
View File
@@ -0,0 +1,99 @@
use crate::{GraphConfig, GraphEdge, GraphNode};
use graphlib_rust::{Edge, Graph};
use ordered_hashmap::OrderedHashMap;
/*
* Initializes ranks for the input graph using the longest path algorithm. This
* algorithm scales well and is fast in practice, it yields rather poor
* solutions. Nodes are pushed to the lowest layer possible, leaving the bottom
* ranks wide and leaving edges longer than necessary. However, due to its
* speed, this algorithm is good for getting an initial ranking that can be fed
* into other algorithms.
*
* This algorithm does not normalize layers because it will be used by other
* algorithms in most cases. If using this algorithm directly, be sure to
* run normalize at the end.
*
* Pre-conditions:
*
* 1. Input graph is a DAG.
* 2. Input graph node labels can be assigned properties.
*
* Post-conditions:
*
* 1. Each node will be assign an (unnormalized) "rank" property.
*/
pub fn longest_path(g: &mut Graph<GraphConfig, GraphNode, GraphEdge>) {
let mut visited: OrderedHashMap<String, bool> = OrderedHashMap::new();
fn dfs(
v: &String,
g: &mut Graph<GraphConfig, GraphNode, GraphEdge>,
visited: &mut OrderedHashMap<String, bool>,
) -> i32 {
let node_label = g.node(v);
if visited.contains_key(v) {
return node_label
.cloned()
.unwrap_or(GraphNode::default())
.rank
.unwrap_or(0);
}
visited.insert(v.clone(), true);
let ranks: Vec<i32> = g
.out_edges(v, None)
.unwrap_or(vec![])
.iter()
.map(|e| {
dfs(&e.w, g, visited)
- (g.edge_with_obj(&e)
.cloned()
.unwrap_or(GraphEdge::default())
.minlen
.unwrap_or(0.0)
.round() as i32)
})
.collect();
let rank: i32 = ranks.iter().min().cloned().unwrap_or(0) as i32;
{
let _node_label = g.node_mut(v);
if let Some(node_label) = _node_label {
node_label.rank = Some(rank.clone());
}
}
return rank;
}
for node_id in g.sources().into_iter() {
dfs(&node_id, g, &mut visited);
}
}
/*
* Returns the amount of slack for the given edge. The slack is defined as the
* difference between the length of the edge and its minimum length.
*/
pub fn slack(g: &Graph<GraphConfig, GraphNode, GraphEdge>, e: &Edge) -> i32 {
let w_rank = g
.node(&e.w)
.cloned()
.unwrap_or(GraphNode::default())
.rank
.unwrap_or(0);
let v_rank = g
.node(&e.v)
.cloned()
.unwrap_or(GraphNode::default())
.rank
.unwrap_or(0);
let minlen = g
.edge_with_obj(e)
.cloned()
.unwrap_or(GraphEdge::default())
.minlen
.unwrap_or(10.0)
.round() as i32;
return w_rank - v_rank - minlen;
}