Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/refine-builtin-skills-home-resolution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@moonshot-ai/agent-core": patch
"@moonshot-ai/kimi-code": patch
---

Polish builtin skills.
61 changes: 46 additions & 15 deletions packages/agent-core/src/skill/builtin/custom-theme.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
---
name: custom-theme
description: Create or edit a kimi-code custom color theme — a JSON file under ~/.kimi-code/themes/ that recolors the TUI. Use when the user wants their own theme, asks for a specific palette or mood, or wants to tweak an existing custom theme's colors.
description: Create or edit a kimi-code custom color theme — a JSON file under the resolved KIMI_CODE_HOME data directory that recolors the TUI. Use when the user wants their own theme, asks for a specific palette or mood, or wants to tweak an existing custom theme's colors.
---

# Create a kimi-code custom theme (custom-theme)

Help the user design, write, and apply a custom color theme for the kimi-code TUI. A theme is a single JSON file; the TUI ships with `dark`, `light`, and `auto`, and any file the user adds becomes selectable alongside them.

## Rules of engagement

- **Never write a theme until the user has explicitly clarified what they want.** This skill may only run after the user has confirmed light vs dark, the style or mood, any specific colors they care about, and the intended filename. If any of these are missing, ask before creating files.
- **Never assume the data directory is `~/.kimi-code`.** Always resolve `$KIMI_CODE_HOME` first with the Bash command below.
- **Never edit a live theme file in place.** Always create a `.json.new` candidate, validate it, back up the old file, and then `mv` it into place.
- **Never overwrite an existing theme without reading it first.** Read, back up, then overwrite only after the user confirms.

## Where a theme lives

The kimi-code runtime resolves the data directory as `KIMI_CODE_HOME` first, falling back to `~/.kimi-code`. Theme files live inside the `themes/` subdirectory of that data directory.

Before doing anything, resolve the actual data root with Bash so you don't write to the wrong place. Check whether `KIMI_CODE_HOME` is set and fall back to `~/.kimi-code` when it is empty:

```bash
echo "$KIMI_CODE_HOME"
echo "$HOME/.kimi-code"
```

Use the first line when it is non-empty; otherwise use the second line. In the rest of this skill, `<KIMI_CODE_HOME>` means that resolved data root — **never assume `~/.kimi-code`**. Theme files live at `<KIMI_CODE_HOME>/themes/<name>.json`. Create the `themes/` directory if it doesn't exist.

## What a theme is

- A theme lives at `~/.kimi-code/themes/<name>.json` (or `$KIMI_CODE_HOME/themes/<name>.json` when that variable is set). Create the `themes/` directory if it doesn't exist.
- A theme lives at `<KIMI_CODE_HOME>/themes/<name>.json`.
- **The filename is the theme name**: `ember.json` shows up in the `/theme` picker as `Custom: ember`.
- Shape:

Expand Down Expand Up @@ -67,24 +87,33 @@ Only set tokens from this set — unknown keys are silently ignored at load. If
- **What style / mood?** e.g. warm vs cool, vivid vs muted, high vs low contrast, a named vibe ("nord", "solarized", "sunset"), or a base to start from (an existing theme, or `dark` / `light`).
- **Any specific colors?** Whether they have exact hex values to anchor on (a brand color, a preferred `primary`, etc.).

Use **AskUserQuestion** for the discrete choices (light vs dark, a few style options); use a plain question for free-form input like specific hex values. Don't start picking colors until you at least know light-vs-dark and the rough style.
2. **Pick a starting point.**
- Tweaking an existing custom theme: **Read** `~/.kimi-code/themes/<name>.json` first — never overwrite a theme you haven't read.
- Starting fresh: build a `colors` object from the token table. You can `ls ~/.kimi-code/themes/` and Read one of the user's existing themes as a reference for the format.
3. **Choose colors deliberately.**
For the discrete choices (light vs dark, a few style options), prefer **AskUserQuestion** if it is available. If you are running in **auto mode** and `AskUserQuestion` is unavailable, ask the same question as a plain-text message with clear numbered or bulleted options, and wait for the user's reply. Don't start picking colors until you at least know light-vs-dark and the rough style.

2. **Resolve the actual theme directory and current theme(s).**
- Resolve the data root by checking `echo "$KIMI_CODE_HOME"`; if empty, use `echo "$HOME/.kimi-code"`. Use `<root>/themes` for every subsequent step.
- If tweaking an existing custom theme, **Read** `<KIMI_CODE_HOME>/themes/<name>.json` first — never overwrite a theme you haven't read.
- Starting fresh: build a `colors` object from the token table. You can `ls <KIMI_CODE_HOME>/themes/` and Read one of the user's existing themes as a reference for the format.

3. **Pick a starting point and choose colors deliberately.**
- Every value is a 6-digit hex `#RRGGBB` (not 3-digit, not a named color).
- Keep contrast usable against the user's terminal background: don't let `text` / `textDim` sit too close to the background, and keep `success` / `warning` / `error` clearly distinguishable from each other.
- `primary` is the most-seen color (links, selection, focus) — make it readable and distinct from `text`.
- `roleUser` is the one role color meant to stand on its own — give it a distinct hue.
4. **Write the file** to `~/.kimi-code/themes/<name>.json` with **Write** for a new theme (pick a short kebab-case filename). When editing an existing theme, prefer **Edit** on just the color(s) that change so the rest stays intact — and back it up first (see Don'ts).
5. **Validate.** Confirm the file is valid JSON and every `colors` value matches `^#[0-9a-fA-F]{6}$`. A quick check with **Bash**:

```bash
node -e 'const p=require("os").homedir()+"/.kimi-code/themes/<name>.json";const c=(require(p).colors)||{};const bad=Object.entries(c).filter(([,v])=>!/^#[0-9a-fA-F]{6}$/.test(v));console.log(bad.length?["invalid:",...bad]:"all hex valid")'
```
4. **Create a candidate file; never edit the live theme in place.**
- Use Bash to create a candidate. If the target theme already exists, copy it verbatim: `cp <name>.json <name>.json.new` (inside `<KIMI_CODE_HOME>/themes/`). If it doesn't exist, use **Write** to create a minimal skeleton named `<name>.json.new`.
- Use **Edit** on the candidate to change only the intended keys. Keep every existing entry, comment, and formatting intact.

5. **Validate the candidate before overwriting.**
- Read the candidate with **Read** to visually confirm it is well-formed JSON and that every `colors` value is a full 6-digit hex `#RRGGBB` (not 3-digit, not a named color).
- Invalid hex values are silently skipped at load (they fall back to the base palette), but fix them so the theme renders as intended.

6. **Back up and overwrite.**
- Back up the old file first — **always** create a new timestamped backup and never overwrite an existing backup: `cp <name>.json "<name>.json.$(date +%Y%m%d-%H%M%S).bak"`.
- If the target didn't exist, skip the backup.
- Overwrite with the candidate: `mv <name>.json.new <name>.json`.

Invalid values are silently skipped at load (they fall back to the base palette; not fatal), but fix them so the theme renders as intended.
6. **Tell the user how to apply it** (next section).
7. **Tell the user how to apply it** (next section).

## Applying the theme

Expand All @@ -94,7 +123,9 @@ Only set tokens from this set — unknown keys are silently ignored at load. If

## Don'ts

- **Don't start creating or editing a theme until the user has clarified light/dark, style/mood, any specific colors, and the filename.** If anything is unclear, ask — don't guess.
- Don't invent token names — only use the documented set; unknown keys are silently ignored.
- Don't write 3-digit hex or named colors — use full `#RRGGBB`.
- Before overwriting an existing theme file, **read it and back it up** (e.g. `cp <name>.json "<name>.json.$(date +%Y%m%d-%H%M%S).bak"`) so the user can recover.
- Never edit the live theme file in place; work through a candidate and validate before `mv`.
- Before overwriting an existing theme file, **read it and back it up** so the user can recover.
- Don't tell the user to restart the app to apply a theme — `/theme` or `/reload-tui` is enough.
21 changes: 18 additions & 3 deletions packages/agent-core/src/skill/builtin/mcp-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,25 @@ tools exist and the user didn't name one, ask which.
## Config edit

Config lives in three files; on key collision, later entries in this
precedence order override earlier ones:
precedence order override earlier ones.

- User-global: `~/.kimi-code/mcp.json` (or `$KIMI_CODE_HOME/mcp.json` if
set). Use for servers you want everywhere.
The kimi-code runtime resolves the user-global directory as `KIMI_CODE_HOME`
first, falling back to `~/.kimi-code`. Before touching the user-global file,
resolve the actual directory with Bash so you don't read or write the wrong
one. Check whether `KIMI_CODE_HOME` is set and fall back to `~/.kimi-code`
when it is empty:

```bash
echo "$KIMI_CODE_HOME"
echo "$HOME/.kimi-code"
```

Use the first line when it is non-empty; otherwise use the second line. In the
rest of this skill, `<KIMI_CODE_HOME>` means that resolved data root —
**never assume `~/.kimi-code`**.

- User-global: `<KIMI_CODE_HOME>/mcp.json`. Use for servers you want
everywhere.
- Project-root: `<project root>/.mcp.json`, where project root is found
by walking up from `<cwd>` to the nearest `.git`. Use for
Claude-compatible, repo-shared, or cross-agent servers.
Expand Down
15 changes: 12 additions & 3 deletions packages/agent-core/src/skill/builtin/update-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ Help the user inspect, change, and validate kimi-code's configuration files. The

## The two config files

kimi-code has two TOML config files, both under `~/.kimi-code/` (or under `KIMI_CODE_HOME` when set), both snake_case, but with different ownership — decide which one the user means before doing anything:
kimi-code has two TOML config files, both under `<KIMI_CODE_HOME>/`, both snake_case, but with different ownership — decide which one the user means before doing anything.

The runtime resolves the data directory as `KIMI_CODE_HOME` first, falling back to `~/.kimi-code`. Before doing anything, resolve the actual directory with Bash so you don't write to the wrong place. Check whether `KIMI_CODE_HOME` is set and fall back to `~/.kimi-code` when it is empty:

```bash
echo "$KIMI_CODE_HOME"
echo "$HOME/.kimi-code"
```

Use the first line when it is non-empty; otherwise use the second line. In the rest of this skill, `<KIMI_CODE_HOME>` means that resolved root — **never assume `~/.kimi-code`**.

- **`config.toml`** — agent / runtime settings: `default_model`, `providers`, `models`, `thinking`, `permission`, `hooks`, `loop_control`, etc.
- **`tui.toml`** — terminal-UI / client preferences: `theme`, `[editor].command`, `[notifications]`, `[upgrade].auto_install` (auto-update). These can usually also be changed with the interactive commands `/config`, `/theme`, `/editor`, which is easier — prefer pointing the user at those.
Expand All @@ -31,7 +40,7 @@ https://moonshotai.github.io/kimi-code/en/configuration/config-files.html

Before any modification, use **Read** on the target config file (decide whether it's `config.toml` or `tui.toml` per the above):

- Location: `~/.kimi-code/config.toml` or `~/.kimi-code/tui.toml` (under `$KIMI_CODE_HOME/` when set). For other scopes/files, defer to the official docs.
- Location: `<KIMI_CODE_HOME>/config.toml` or `<KIMI_CODE_HOME>/tui.toml`. For other scopes/files, defer to the official docs.
- A missing or empty file is fine — you'll create a minimal skeleton later.
- If the file exists but **fails to parse as TOML**, report the error verbatim and **stop** — never overwrite a broken file in place (it could destroy the user's existing config).

Expand All @@ -53,7 +62,7 @@ Don't edit the target file in place, and **don't rewrite it from scratch** — i
1. **Clarify intent**: which key, what value, and which file (`config.toml` or `tui.toml`). Ask in one line if ambiguous; for discrete choices (e.g. scope) AskUserQuestion is fine, but use plain questions for free-form input.
2. **Read the target file** (Prerequisite 2): Read it to understand the current state and confirm it parses.
3. **Copy out a candidate (do not create from scratch)**: use **Bash** to copy the target verbatim — `cp config.toml config-new.toml` (same directory, `-new` suffix; for tui.toml, `cp tui.toml tui-new.toml`). **Leave the original untouched for now.**
- Only when the target doesn't exist (nothing to copy) should you use **Write** to create a minimal skeleton candidate (e.g. just the comment line `# ~/.kimi-code/config.toml`).
- Only when the target doesn't exist (nothing to copy) should you use **Write** to create a minimal skeleton candidate (e.g. just the comment line `# <KIMI_CODE_HOME>/config.toml`).
4. **Edit the candidate**: use the **Edit** tool on the candidate to **change/add only the target key** — never rewrite the whole file. That way every existing section, entry, comment, and bit of formatting stays exactly as-is; only what should change changes. The candidate is identical to the original, so use the content you read in step 2 to locate the Edit anchor. Check the change against the official docs (key / section / value type / allowed values, snake_case).
5. **Validate the candidate** (see Capability 3, via `kimi doctor`). **If anything fails, keep Editing the candidate and re-validate, looping until it all passes.**
6. **Back up and overwrite** (only after validation fully passes):
Expand Down
4 changes: 2 additions & 2 deletions packages/agent-core/test/skill/builtin-custom-theme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ describe('builtin skill: custom-theme', () => {
expect(CUSTOM_THEME_SKILL.metadata.disableModelInvocation).toBe(true);
});

it('pins the docs token reference and points users at ~/.kimi-code/themes and /theme', () => {
it('pins the docs token reference and points users at KIMI_CODE_HOME/themes and /theme', () => {
const content = CUSTOM_THEME_SKILL.content;
expect(content).toContain('customization/themes.html');
expect(content).toContain('FetchURL');
expect(content).toContain('~/.kimi-code/themes');
expect(content).toContain('<KIMI_CODE_HOME>/themes');
expect(content).toContain('/theme');
// every documented token should be named so the model knows the full set
for (const token of [
Expand Down
Loading