Skip to content

Commit a58b5b2

Browse files
authored
fix(skill): polish builtin skills KIMI_CODE_HOME resolution (#644)
- custom-theme.md, update-config.md, mcp-config.md now resolve KIMI_CODE_HOME first. - custom-theme.md requires clarifying intent before creating or editing themes. - custom-theme.md falls back to plain-text questions in auto mode.
1 parent 1b58aa8 commit a58b5b2

5 files changed

Lines changed: 84 additions & 23 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@moonshot-ai/agent-core": patch
3+
"@moonshot-ai/kimi-code": patch
4+
---
5+
6+
Polish builtin skills.

packages/agent-core/src/skill/builtin/custom-theme.md

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
11
---
22
name: custom-theme
3-
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.
3+
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.
44
---
55

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

88
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.
99

10+
## Rules of engagement
11+
12+
- **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.
13+
- **Never assume the data directory is `~/.kimi-code`.** Always resolve `$KIMI_CODE_HOME` first with the Bash command below.
14+
- **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.
15+
- **Never overwrite an existing theme without reading it first.** Read, back up, then overwrite only after the user confirms.
16+
17+
## Where a theme lives
18+
19+
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.
20+
21+
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:
22+
23+
```bash
24+
echo "$KIMI_CODE_HOME"
25+
echo "$HOME/.kimi-code"
26+
```
27+
28+
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.
29+
1030
## What a theme is
1131

12-
- 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.
32+
- A theme lives at `<KIMI_CODE_HOME>/themes/<name>.json`.
1333
- **The filename is the theme name**: `ember.json` shows up in the `/theme` picker as `Custom: ember`.
1434
- Shape:
1535

@@ -67,24 +87,33 @@ Only set tokens from this set — unknown keys are silently ignored at load. If
6787
- **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`).
6888
- **Any specific colors?** Whether they have exact hex values to anchor on (a brand color, a preferred `primary`, etc.).
6989

70-
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.
71-
2. **Pick a starting point.**
72-
- Tweaking an existing custom theme: **Read** `~/.kimi-code/themes/<name>.json` first — never overwrite a theme you haven't read.
73-
- 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.
74-
3. **Choose colors deliberately.**
90+
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.
91+
92+
2. **Resolve the actual theme directory and current theme(s).**
93+
- Resolve the data root by checking `echo "$KIMI_CODE_HOME"`; if empty, use `echo "$HOME/.kimi-code"`. Use `<root>/themes` for every subsequent step.
94+
- If tweaking an existing custom theme, **Read** `<KIMI_CODE_HOME>/themes/<name>.json` first — never overwrite a theme you haven't read.
95+
- 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.
96+
97+
3. **Pick a starting point and choose colors deliberately.**
7598
- Every value is a 6-digit hex `#RRGGBB` (not 3-digit, not a named color).
7699
- 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.
77100
- `primary` is the most-seen color (links, selection, focus) — make it readable and distinct from `text`.
78101
- `roleUser` is the one role color meant to stand on its own — give it a distinct hue.
79-
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).
80-
5. **Validate.** Confirm the file is valid JSON and every `colors` value matches `^#[0-9a-fA-F]{6}$`. A quick check with **Bash**:
81102

82-
```bash
83-
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")'
84-
```
103+
4. **Create a candidate file; never edit the live theme in place.**
104+
- 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`.
105+
- Use **Edit** on the candidate to change only the intended keys. Keep every existing entry, comment, and formatting intact.
106+
107+
5. **Validate the candidate before overwriting.**
108+
- 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).
109+
- Invalid hex values are silently skipped at load (they fall back to the base palette), but fix them so the theme renders as intended.
110+
111+
6. **Back up and overwrite.**
112+
- 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"`.
113+
- If the target didn't exist, skip the backup.
114+
- Overwrite with the candidate: `mv <name>.json.new <name>.json`.
85115

86-
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.
87-
6. **Tell the user how to apply it** (next section).
116+
7. **Tell the user how to apply it** (next section).
88117

89118
## Applying the theme
90119

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

95124
## Don'ts
96125

126+
- **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.
97127
- Don't invent token names — only use the documented set; unknown keys are silently ignored.
98128
- Don't write 3-digit hex or named colors — use full `#RRGGBB`.
99-
- 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.
129+
- Never edit the live theme file in place; work through a candidate and validate before `mv`.
130+
- Before overwriting an existing theme file, **read it and back it up** so the user can recover.
100131
- Don't tell the user to restart the app to apply a theme — `/theme` or `/reload-tui` is enough.

packages/agent-core/src/skill/builtin/mcp-config.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,25 @@ tools exist and the user didn't name one, ask which.
3838
## Config edit
3939

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

43-
- User-global: `~/.kimi-code/mcp.json` (or `$KIMI_CODE_HOME/mcp.json` if
44-
set). Use for servers you want everywhere.
43+
The kimi-code runtime resolves the user-global directory as `KIMI_CODE_HOME`
44+
first, falling back to `~/.kimi-code`. Before touching the user-global file,
45+
resolve the actual directory with Bash so you don't read or write the wrong
46+
one. Check whether `KIMI_CODE_HOME` is set and fall back to `~/.kimi-code`
47+
when it is empty:
48+
49+
```bash
50+
echo "$KIMI_CODE_HOME"
51+
echo "$HOME/.kimi-code"
52+
```
53+
54+
Use the first line when it is non-empty; otherwise use the second line. In the
55+
rest of this skill, `<KIMI_CODE_HOME>` means that resolved data root —
56+
**never assume `~/.kimi-code`**.
57+
58+
- User-global: `<KIMI_CODE_HOME>/mcp.json`. Use for servers you want
59+
everywhere.
4560
- Project-root: `<project root>/.mcp.json`, where project root is found
4661
by walking up from `<cwd>` to the nearest `.git`. Use for
4762
Claude-compatible, repo-shared, or cross-agent servers.

packages/agent-core/src/skill/builtin/update-config.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@ Help the user inspect, change, and validate kimi-code's configuration files. The
99

1010
## The two config files
1111

12-
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:
12+
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.
13+
14+
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:
15+
16+
```bash
17+
echo "$KIMI_CODE_HOME"
18+
echo "$HOME/.kimi-code"
19+
```
20+
21+
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`**.
1322

1423
- **`config.toml`** — agent / runtime settings: `default_model`, `providers`, `models`, `thinking`, `permission`, `hooks`, `loop_control`, etc.
1524
- **`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.
@@ -31,7 +40,7 @@ https://moonshotai.github.io/kimi-code/en/configuration/config-files.html
3140

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

34-
- 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.
43+
- Location: `<KIMI_CODE_HOME>/config.toml` or `<KIMI_CODE_HOME>/tui.toml`. For other scopes/files, defer to the official docs.
3544
- A missing or empty file is fine — you'll create a minimal skeleton later.
3645
- 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).
3746

@@ -53,7 +62,7 @@ Don't edit the target file in place, and **don't rewrite it from scratch** — i
5362
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.
5463
2. **Read the target file** (Prerequisite 2): Read it to understand the current state and confirm it parses.
5564
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.**
56-
- 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`).
65+
- 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`).
5766
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).
5867
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.**
5968
6. **Back up and overwrite** (only after validation fully passes):

packages/agent-core/test/skill/builtin-custom-theme.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ describe('builtin skill: custom-theme', () => {
1414
expect(CUSTOM_THEME_SKILL.metadata.disableModelInvocation).toBe(true);
1515
});
1616

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

0 commit comments

Comments
 (0)