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:
@@ -0,0 +1,344 @@
|
||||
# Theming and Appearance Customization
|
||||
|
||||
Grok Build draws all TUI colors from a central theme. You can switch themes while Grok is running, follow your operating system's light or dark appearance, and adjust scrollback layout, animations, and block styling through configuration files.
|
||||
|
||||
---
|
||||
|
||||
## Available Themes
|
||||
|
||||
Grok includes five built-in themes, plus an `auto` option that follows your system appearance:
|
||||
|
||||
| Theme | Config Names | Description | Truecolor Required |
|
||||
|-------|-------------|-------------|--------------------|
|
||||
| **GrokNight** | `groknight`, `grok-night`, `dark` | Neutral dark base with a magenta accent. Default theme. Survives quantization cleanly on 256-color and 16-color terminals. | No |
|
||||
| **GrokDay** | `grokday`, `grok-day`, `light`, `day` | Light theme for bright terminal backgrounds. | No |
|
||||
| **TokyoNight** | `tokyonight`, `tokyo-night`, `tokyo` | Dark, blue-tinted backgrounds from the Tokyo Night palette. Loses its character when quantized. | Yes |
|
||||
| **RosePineMoon** | `rosepine`, `rose-pine`, `rosepine-moon`, `rose-pine-moon` | Muted dark palette with mauve accents, from the Rosé Pine family. | Yes |
|
||||
| **OscuraMidnight** | `oscura`, `oscura-midnight` | Deep dark base with purple accents. | Yes |
|
||||
|
||||
Theme names are case-insensitive. The `auto` option (alias `system`) is documented under [Auto Theme (System Appearance)](#auto-theme-system-appearance).
|
||||
|
||||
### Minimal Mode Has No Theming
|
||||
|
||||
**Minimal mode** (`--minimal`) always renders with a single fixed terminal-native palette and ignores the `theme` settings entirely (they still apply to the full TUI). Minimal draws directly on your terminal's own background, so it uses your terminal's default foreground/background plus its 16-color ANSI palette — the same colors `git` or `ls` use — which stays readable on any light or dark terminal profile without detection or configuration. `/theme` and the theme rows in `/settings` are unavailable in minimal mode.
|
||||
|
||||
---
|
||||
|
||||
## Switching Themes
|
||||
|
||||
### In the TUI
|
||||
|
||||
Run the `/theme` slash command (alias `/t`) to open the theme picker. As you move through the list with the arrow keys, Grok previews each theme in real time. Press Enter to apply and save your choice, or press Escape to revert.
|
||||
|
||||
To switch without the picker, pass a name directly:
|
||||
|
||||
```
|
||||
/theme tokyonight
|
||||
```
|
||||
|
||||
Submitting `/theme` on its own -- without choosing from the picker -- cycles to the next theme.
|
||||
|
||||
### Via Config File
|
||||
|
||||
Set the theme in `~/.kigi/config.toml`:
|
||||
|
||||
```toml
|
||||
[ui]
|
||||
theme = "tokyonight"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Auto Theme (System Appearance)
|
||||
|
||||
Set `theme = "auto"` to have Grok follow your operating system's light/dark appearance and switch themes automatically:
|
||||
|
||||
```toml
|
||||
[ui]
|
||||
theme = "auto"
|
||||
```
|
||||
|
||||
By default, dark mode maps to **GrokNight** and light mode maps to **GrokDay**. Override either mapping with `auto_dark_theme` and `auto_light_theme`:
|
||||
|
||||
```toml
|
||||
[ui]
|
||||
theme = "auto"
|
||||
auto_dark_theme = "tokyonight"
|
||||
auto_light_theme = "grokday"
|
||||
```
|
||||
|
||||
`theme = "system"` is an alias for `theme = "auto"`.
|
||||
|
||||
### How Detection Works
|
||||
|
||||
| Platform | Method |
|
||||
|----------|--------|
|
||||
| **macOS** | Reads `AppleInterfaceStyle` system preference |
|
||||
| **Linux** | Queries XDG Desktop Portal (`org.freedesktop.appearance.color-scheme`) |
|
||||
| **Windows** | Reads the system personalization registry |
|
||||
| **SSH / headless** | Falls back to an OSC 11 terminal background query at startup |
|
||||
|
||||
Once running, Grok polls for appearance changes every 5 seconds. Toggling your OS between light and dark mode takes effect within seconds without restarting.
|
||||
|
||||
### Via the Settings Pane
|
||||
|
||||
Run `/settings` (alias `/config`) and open the **Appearance** category to set the **Auto dark theme** and **Auto light theme** interactively. Selecting `auto` in the `/theme` picker enables auto mode using these mappings.
|
||||
|
||||
---
|
||||
|
||||
## Color Support Detection
|
||||
|
||||
On startup, Grok detects your terminal's color capability level:
|
||||
|
||||
| Level | Description | Detection |
|
||||
|-------|-------------|-----------|
|
||||
| **Truecolor** (24-bit) | Full RGB color. All themes render as designed. | `COLORTERM=truecolor` or equivalent terminal capability |
|
||||
| **256-color** | Indexed palette. RGB values are mapped to the nearest palette entry. | Standard xterm-256color |
|
||||
| **16-color** | ANSI names only. Colors are mapped to the closest ANSI color. | Basic terminal support |
|
||||
|
||||
When you set `NO_COLOR`, Grok emits no color and renders in monochrome.
|
||||
|
||||
Run `/terminal-setup` to see the detected level (`color` row) and which themes the picker offers on this terminal (`themes` row). When truecolor is missing, the issues section explains how to enable it (or that Terminal.app cannot).
|
||||
|
||||
### Automatic Quantization
|
||||
|
||||
Every theme is defined using full RGB values. At startup, Grok quantizes all colors to match the detected capability level. This means:
|
||||
|
||||
- On **truecolor** terminals, colors pass through unchanged.
|
||||
- On **256-color** terminals, each RGB value is mapped to the nearest indexed palette entry.
|
||||
- On **16-color** terminals, colors map to ANSI names.
|
||||
|
||||
GrokNight and GrokDay use neutral grays that quantize cleanly. TokyoNight, RosePineMoon, and OscuraMidnight use distinctive tinted backgrounds that lose their character when quantized, which is why the theme picker hides them on non-truecolor terminals.
|
||||
|
||||
### Runtime-Generated Colors
|
||||
|
||||
Colors generated at runtime (syntax highlighting, background blending) are also quantized through the same pipeline, ensuring consistent appearance across all terminal types.
|
||||
|
||||
---
|
||||
|
||||
## Cursor Color
|
||||
|
||||
Grok sets your terminal cursor to the current theme's `accent_user` color using the OSC 12 escape sequence, to indicate an active Grok session. The cursor color is:
|
||||
|
||||
- Applied on startup and on theme switch.
|
||||
- Reset to the terminal's default on exit via OSC 112.
|
||||
|
||||
This works in terminals that support OSC 12 (most modern terminals).
|
||||
|
||||
---
|
||||
|
||||
## Compact Mode
|
||||
|
||||
Toggle compact mode with the `/compact-mode` slash command. Compact mode:
|
||||
|
||||
- Removes outer vertical padding (top/bottom margins become 0).
|
||||
- Reduces horizontal padding to the minimum (1 column).
|
||||
- Reduces top padding in the prompt area and info blocks.
|
||||
|
||||
The setting is persisted in `~/.kigi/config.toml` under `[ui].compact_mode` and survives restarts.
|
||||
|
||||
Use compact mode on small screens to maximize content area.
|
||||
|
||||
---
|
||||
|
||||
## Syntax Highlighting
|
||||
|
||||
Grok bundles three `.tmTheme` files for code-block syntax highlighting and selects one based on the active theme:
|
||||
|
||||
- `grok-night.tmTheme` -- GrokNight, RosePineMoon, and OscuraMidnight
|
||||
- `grok-day.tmTheme` -- GrokDay
|
||||
- `tokyo-night.tmTheme` -- TokyoNight
|
||||
|
||||
Grok selects the matching file automatically when you switch themes. The `.tmTheme` files are built into the binary, so you cannot replace them with your own.
|
||||
|
||||
---
|
||||
|
||||
## Deep Customization with pager.toml
|
||||
|
||||
For fine-grained control over the TUI appearance, create `~/.kigi/pager.toml`. This file controls scrollback layout, block styling, animations, and more. All settings have defaults; specify only the values you override. (Dev builds generate this file as a template with every default commented out — uncomment a line to override it; commented values keep tracking future defaults.)
|
||||
|
||||
### Layout
|
||||
|
||||
Control viewport padding and block spacing:
|
||||
|
||||
```toml
|
||||
[scrollback.layout]
|
||||
outer_vpad = 1 # Vertical padding (top/bottom) for the viewport
|
||||
outer_hpad_left = 2 # Left margin (minimum: 1)
|
||||
outer_hpad_right = 2 # Right margin (minimum: 1)
|
||||
block_pad_left = 2 # Padding between accent line and content
|
||||
block_pad_right = 2 # Padding after content at right edge
|
||||
```
|
||||
|
||||
### Scrollbar
|
||||
|
||||
```toml
|
||||
[scrollback.scrollbar]
|
||||
enabled = true # Show/hide the scrollbar
|
||||
gap_left = 0 # Gap between content and scrollbar (0 = adjacent)
|
||||
gap_right = 0 # Gap between scrollbar and screen edge (0 = at edge)
|
||||
# scrollbar_bg = "none" # Override background color (or "none" for theme default)
|
||||
# scrollbar_fg = "none" # Override thumb color (or "none" for theme default)
|
||||
```
|
||||
|
||||
### Scroll Behavior
|
||||
|
||||
```toml
|
||||
[scrollback.scroll]
|
||||
margin = 0 # Context lines above/below selected entry (0 = edge)
|
||||
min_page_fraction = 0 # Minimum scroll as % of viewport (0-100)
|
||||
follow_indicator = "center" # "center" = show down-arrow, "none" = hidden
|
||||
follow_auto_select = true # Auto-select latest entry when following
|
||||
follow_by_overscroll = true # Scrolling past bottom engages follow mode
|
||||
anchor_on_fold = true # Keep block header at same screen position when folding
|
||||
```
|
||||
|
||||
### Display Options
|
||||
|
||||
```toml
|
||||
[scrollback.display]
|
||||
sticky_headers = true # Pin user prompts as headers when scrolled past
|
||||
tab_width = 4 # Spaces per tab character (0 = pass through)
|
||||
expandable_indicator = true # Show "›" on foldable collapsed entries
|
||||
expandable_indicator_char = "›" # Character to use (default: "›")
|
||||
collapsed_accent_char = "❙" # Accent for collapsed groupable blocks (falls back to "|" on the legacy Windows console)
|
||||
dim_accent = 0.5 # Blend factor for dimmed accents (0.0-1.0)
|
||||
line_under_last_entry = false # Horizontal line below last entry
|
||||
selection_buttons = false # Show copy/view buttons on selection box
|
||||
```
|
||||
|
||||
### Animation
|
||||
|
||||
```toml
|
||||
[animation]
|
||||
fps = 30 # Frame rate (1-60). Higher = smoother, more CPU
|
||||
wave_rows = 32 # Rows per wave cycle for accent animation
|
||||
```
|
||||
|
||||
### Block Styling: Edit Diffs
|
||||
|
||||
```toml
|
||||
[scrollback.blocks.edit]
|
||||
indent = true # Indent diff content
|
||||
vpad = false # Vertical padding around diffs
|
||||
# expanded_by_default = true # Unset: follows [ui] collapsed_edit_blocks in config.toml
|
||||
# (flag on = collapsed one-liner); uncomment to pin either shape
|
||||
hunk_separator = "…" # Separator between hunks ("…", "───", "⋯", or "" for none)
|
||||
dual_line_numbers = false # Two-column line numbers (old + new, like GitHub)
|
||||
# line_summary = false # Show +N/-M in the collapsed header; unset follows the same flag
|
||||
# bg = "none" # Block background ("none", "light", "dark")
|
||||
```
|
||||
|
||||
### Block Styling: Thinking/Reasoning
|
||||
|
||||
```toml
|
||||
[scrollback.blocks.thinking]
|
||||
accent_enabled = true # Show accent line for thinking blocks
|
||||
animate = true # Animate accent line while thinking
|
||||
truncated_lines = 3 # Lines to show in truncated mode
|
||||
bg_blend = 70 # Markdown-color blend with background (0-100)
|
||||
header = true # Show "Thinking..." header
|
||||
header_bright = false # Bright header style (vs dim/muted)
|
||||
```
|
||||
|
||||
### Block Styling: Tool Calls
|
||||
|
||||
```toml
|
||||
[scrollback.blocks.tool]
|
||||
muted_collapsed = true # Gray out collapsed tool calls
|
||||
dim_details = true # Dim parenthetical details (line counts, match counts)
|
||||
bullet = "diamond" # Bullet style before tool headers
|
||||
```
|
||||
|
||||
Available bullet styles:
|
||||
|
||||
| Config Value | Character | Description |
|
||||
|-------------|-----------|-------------|
|
||||
| `none` | (none) | No bullet |
|
||||
| `dot` | `·` | Middle dot (smallest) |
|
||||
| `small-circle` | `•` | Bullet |
|
||||
| `circle` | `●` | Filled circle |
|
||||
| `small-triangle` | `▸` | Right-pointing small triangle |
|
||||
| `triangle` | `▶` | Right-pointing triangle |
|
||||
| `diamond` | `◆` | Filled diamond (default) |
|
||||
|
||||
### Block Styling: Execute (Shell Commands)
|
||||
|
||||
```toml
|
||||
[scrollback.blocks.execute]
|
||||
first_lines = 2 # Output lines shown at start in truncated mode
|
||||
last_lines = 3 # Output lines shown at end in truncated mode
|
||||
accent_enabled = true # Show accent line (animated while running)
|
||||
header_style = "label" # "shell" ($ prefix) or "label" (Run prefix)
|
||||
muted_command_collapsed = true # Mute command text when collapsed
|
||||
```
|
||||
|
||||
### Block Styling: User Prompts (Scrollback)
|
||||
|
||||
```toml
|
||||
[scrollback.blocks.prompt]
|
||||
vpad = true # Vertical padding
|
||||
bg = "light" # Background ("none", "light", "dark")
|
||||
show_prefix = true # Show the prompt prefix character
|
||||
min_lines = 2 # Minimum content lines in truncated/sticky mode
|
||||
```
|
||||
|
||||
### Prompt Input Widget
|
||||
|
||||
```toml
|
||||
[prompt]
|
||||
collapse_unfocused = true # Collapse when scrollback is focused
|
||||
mouse_hover = true # Show hover highlight on mouse over
|
||||
show_prefix = true # Show the prompt prefix character
|
||||
```
|
||||
|
||||
### Todo Badges
|
||||
|
||||
```toml
|
||||
[todo]
|
||||
badge_format = "default" # "default" = 2/5 (done/total), "colon" = [▶:1 □:4 ✓:3 ✗:2], "comma" = [1 ▶, 4 □, 3 ✓, 2 ✗]
|
||||
```
|
||||
|
||||
### Terminal Behavior
|
||||
|
||||
```toml
|
||||
[terminal]
|
||||
alt_screen = "auto" # "auto", "always", or "never"
|
||||
```
|
||||
|
||||
Alt-screen policies:
|
||||
- `auto` -- fullscreen in plain terminals and normal tmux; inline in tmux control mode and Zellij.
|
||||
- `always` -- always enter fullscreen.
|
||||
- `never` -- never enter fullscreen; run inline in the main scrollback.
|
||||
|
||||
### Plugins UI
|
||||
|
||||
```toml
|
||||
disable_plugins = false # Set to true to hide /hooks, /plugins commands and annotations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Theme Color Slots
|
||||
|
||||
Each theme defines the following color slots that are used throughout the TUI:
|
||||
|
||||
**Backgrounds:** `bg_base`, `bg_light`, `bg_dark`, `bg_highlight`, `bg_hover`, `bg_terminal`, `bg_visual`
|
||||
|
||||
**Accents:** `accent_user`, `accent_assistant`, `accent_thinking`, `accent_tool`, `accent_system`, `accent_error`, `accent_success`, `accent_running`, `accent_skill`, `accent_plan`, `accent_verify`, `accent_feedback`, `accent_remember`, `accent_model`
|
||||
|
||||
**Text:** `text_primary`, `text_secondary`
|
||||
|
||||
**Grays:** `gray_dim`, `gray`, `gray_bright`
|
||||
|
||||
**Semantic:** `command`, `path`, `running`, `warning`, `fuzzy_accent`
|
||||
|
||||
**Borders and scrollbar:** `selection_border`, `hover_border`, `prompt_border`, `prompt_border_active`, `scrollbar_bg`, `scrollbar_fg`
|
||||
|
||||
**Paste:** `paste_bg`, `paste_fg`, `paste_dim`
|
||||
|
||||
**Diff:** `diff_delete_bg`, `diff_delete_fg`, `diff_insert_bg`, `diff_insert_fg`, `diff_equal_fg`, `diff_gutter_fg`
|
||||
|
||||
**Markdown:** heading colors (`md_heading_h1`-`md_heading_h6`), `md_code`, `md_code_bg`, `md_text`, `md_muted`, `md_task_checked`, `md_task_unchecked`, `link_fg`
|
||||
|
||||
The theme system manages these slots internally and quantizes them automatically for your terminal.
|
||||
Reference in New Issue
Block a user