diff --git a/.agents/skills/gen-changesets/SKILL.md b/.agents/skills/gen-changesets/SKILL.md
index 29578bf5a9..b5fb0fd50d 100644
--- a/.agents/skills/gen-changesets/SKILL.md
+++ b/.agents/skills/gen-changesets/SKILL.md
@@ -148,7 +148,7 @@ Clarify session status typing for internal SDK callers.
`@moonshot-ai/kimi-web` is ignored by changesets and must **never** appear in a changeset frontmatter. Because the web app is bundled into the CLI release artifact, any web change that ships must list `@moonshot-ai/kimi-code` instead and describe the actual web-facing change in the text.
- Prefix the changelog entry text with `web: ` (for example `web: Fix the chat not scrolling to the bottom after sending a message.`) so the synced docs changelog can mark web UI entries. Apply this whenever the change is to the web project (`@moonshot-ai/kimi-web`).
-- If a PR contains both web UI changes and server API changes, split them into separate changesets so each entry has a focused description.
+- If a PR ships a web UI feature backed by server API changes that exist solely to power that feature, prefer a single `web:` entry describing what the web user gets. Do not add a separate server-API changeset unless the API has independent user value (a public endpoint that SDK or server consumers call directly). The docs changelog sync also deduplicates this pattern, but catching it here avoids duplicate changesets.
- Do not enumerate every micro-tweak; keep it to one sentence that captures what the web user gets.
Web-only fix:
@@ -161,7 +161,7 @@ Web-only fix:
web: Fix the chat not scrolling to the bottom after sending a message.
```
-Web UI plus server APIs in the same PR (split into two changesets):
+Web UI plus backing server APIs in the same PR (prefer a single `web:` entry; the API is plumbing):
```markdown
---
@@ -171,13 +171,7 @@ Web UI plus server APIs in the same PR (split into two changesets):
web: Add the server-hosted web UI, including chat layout and session list behaviors.
```
-```markdown
----
-"@moonshot-ai/kimi-code": minor
----
-
-Add the server REST and WebSocket APIs that power the web UI.
-```
+Split into two changesets only when the API has independent user value on its own (for example, a public endpoint SDK consumers call directly). In that case add the web entry above plus a separate one such as `Add a public REST API to list archived sessions for SDK consumers.`
## `@moonshot-ai/pi-tui` changes
@@ -228,3 +222,4 @@ Fix the transcript jumping to the top when scrolling up through history during s
- The entry includes real internal identifiers instead of neutral placeholders.
- A change that only touches `@moonshot-ai/pi-tui` lists `@moonshot-ai/kimi-code` instead of `@moonshot-ai/pi-tui`, or mixes both packages in one frontmatter.
- A web app change entry is missing the `web: ` prefix.
+- A server/API changeset exists only to back a web feature that a `web:` changeset already describes (use one `web:` entry instead, unless the API has independent user value).
diff --git a/.agents/skills/pre-changelog/SKILL.md b/.agents/skills/pre-changelog/SKILL.md
index c79016a0dc..adde7c1b36 100644
--- a/.agents/skills/pre-changelog/SKILL.md
+++ b/.agents/skills/pre-changelog/SKILL.md
@@ -37,9 +37,10 @@ If the CLI changelog is not in the diff (for example an SDK-only release), stop
Process the version block exactly as `sync-changelog` does for the docs site, but only in memory:
-- **Strip** (`sync-changelog` step 3): drop the H1, the `### Patch Changes` / `### Minor Changes` / `### Major Changes` subheadings, PR links, and commit-hash links; keep only each entry's body text.
-- **Classify** (`sync-changelog` step 4): bucket into Features / Bug Fixes / Polish / Refactors / Other; order within each section by reader value.
-- **Translate** (`sync-changelog` step 6): translate entry bodies to Chinese; section headings become 新功能 / 修复 / 优化 / 重构 / 其他.
+- **Strip** (`sync-changelog` step 3): drop the H1, the `### Patch Changes` / `### Minor Changes` / `### Major Changes` subheadings, PR links, and commit-hash links; keep only each entry's body text. The `Thanks [@user](...)!` credit (including the multi-author form) must be removed every time. Within each entry, drop SDK-only and provider-internal sentences (SDK capability mapping / API exposure, provider wire-format mechanics, internal XML markers) and keep only the user-facing effect and required constraints.
+- **Merge and deduplicate** (`sync-changelog` step 4): merge micro-tweaks to the same surface into one higher-level entry; when three or more fixes target the same UI area or the same class of problem, merge them into one higher-level fix entry (do not merge broad or genuinely distinct fixes); and drop a server/API entry that only backs a web feature already listed.
+- **Classify** (`sync-changelog` step 4): bucket into Features / Bug Fixes / Polish / Refactors / Other; order within each section by reader value (in Polish, user-visible improvements before protocol/internal adjustments).
+- **Translate** (`sync-changelog` step 6): translate entry bodies to Chinese; keep one sentence per entry with a parallel rhythm within a section; section headings become 新功能 / 修复 / 优化 / 重构 / 其他.
If an upstream entry is not in English, flag it and stop (changeset entries must be English).
diff --git a/.agents/skills/sync-changelog/SKILL.md b/.agents/skills/sync-changelog/SKILL.md
index 6e752387da..25e542d4b9 100644
--- a/.agents/skills/sync-changelog/SKILL.md
+++ b/.agents/skills/sync-changelog/SKILL.md
@@ -93,13 +93,13 @@ Use upstream order: newest version first.
Upstream entries look like this:
```markdown
-- [#317](https://github.com/...) [`2f51db4`](https://github.com/...) - Clean up lint warnings ...
+- [#317](https://github.com/...) [`2f51db4`](https://github.com/...) Thanks [@user](https://github.com/...)! - Clean up lint warnings ...
```
-Keep:
+Changesets may add a `Thanks ...!` credit, but it must be removed every time. Keep:
- Version headings such as `## 0.2.0`.
-- Only the body text of each entry, after the PR/hash decoration.
+- Only the body text of each entry, after the PR/hash decoration and any `Thanks ...!` credit have been removed.
Remove:
@@ -107,12 +107,17 @@ Remove:
- Changesets subheadings such as `### Patch Changes`, `### Minor Changes`, and `### Major Changes`.
- PR links such as `[#317](...)`.
- Commit hash links such as ``[`2f51db4`](...)``.
+- The `Thanks [@user](...)!` credit, including the multi-author form `Thanks [@a](...), [@b](...)!`. Drop the whole `Thanks ...!` segment every time, regardless of whether the feature is enabled.
-After stripping, each entry should be only:
+After stripping, each entry is `-
`.
-```markdown
--
-```
+Drop SDK-only and provider-internal detail. This changelog serves `@moonshot-ai/kimi-code` CLI and web users. Within an entry, keep only what CLI/web users can perceive, and remove sentences that document internals instead of user-visible behavior. Apply this on both the English and Chinese pages:
+
+- Drop sentences about how the SDK maps a capability, builds model aliases, or exposes a flag through an API such as `getExperimentalFeatures()` — that belongs in the SDK changelog, not here.
+- Drop provider / wire-format implementation mechanics (XML markers like ``, protocol field explanations, "the wire protocol is unchanged", cache-hit mechanics) unless they are the behavior a user perceives.
+- Keep the user-facing effect and any constraints users must follow (for example "question texts must be unique").
+
+Do not change facts or drop a real user-facing behavior — only trim the internal-only scaffolding. For over-long, internal-heavy entries, this trim applies on the English page too, not only in translation.
Web UI prefix: if the entry is a web UI change, prefix the body text with `web: ` so readers can tell it affects the web UI:
@@ -126,15 +131,25 @@ Upstream language rule: `gen-changesets` requires changelog entries to be Englis
Public-text rule: do not copy real internal endpoints, key names, account names, or service names into docs changelogs. Replace examples with neutral placeholders such as `example.com`, `example.test`, or `YOUR_API_KEY` while preserving the user-visible meaning.
-### 4. Classify Entries
+### 4. Merge, Deduplicate, And Classify Entries
+
+Before classifying, merge related entries and drop redundant ones from the user-facing changelog:
+
+- **Merge micro-tweaks to the same surface.** Collapse several small tweaks to the same UI area or feature into one concise entry at the higher level. For example, "change the composer's default height" and "change the composer's default font" merge into "Polish the composer's default styling." Use the most specific common ancestor (composer, settings page, tool card, and so on). Classify the merged entry by its combined effect, and keep the `web:` prefix if the combined change is still web-facing.
+- **Merge same-surface or same-kind fixes when you have three or more.** The `Bug Fixes` section tends to accumulate many narrow UI/polish fixes that read as noise when listed one by one. When three or more fixes target the same area (for example several tool cards in the TUI, or the web session/conversation surface) or the same class of problem (for example several "jumping/flickering/collapsing during streaming" fixes), merge them into one higher-level entry. Examples:
+ - "Fix the Bash tool card collapsing...", "Fix the Edit tool card jumping in height...", "Fix the Edit tool card flickering while its result streams in" → "Fix several TUI tool cards jumping, flickering, or collapsing in height when results stream in or end with short output."
+ - "Fix the collapsed sidebar not hiding...", "Stop the chat history from replaying its entrance animation...", "Fix tool components jumping the conversation when expanded/collapsed" → "web: Fix several layout and display glitches when switching sessions, including the collapsed sidebar not hiding, the chat history replaying its entrance animation, and tool components jumping the conversation."
+ - Keep `web:` if the merged fixes are all web-facing. Classify as `Bug Fixes`.
+ - **Do not over-merge.** Leave a fix standalone when it is broad, high-value, or genuinely distinct (for example model/provider tool-calling bugs, session-list corruption, file-completion gaps). Merging is for low-reader-value, similar-shape fixes that read as a wall of similar bullets.
+- **Drop server/API plumbing covered by a web entry.** If one entry adds a web UI feature (for example, an Archived sessions page) and another entry only adds the server or REST/WebSocket endpoints that exist solely to power that web feature, keep the `web:` entry and drop the API entry. CLI and web users perceive the web page; the backing API is implementation detail with no independent user value on this changelog. Keep the API entry only when it has independent user value — a new public endpoint that SDK or server consumers call directly, or a capability usable outside the web feature. When unsure, keep both and let the reviewer decide.
The docs changelog uses five section types:
| English section | Chinese section | Meaning |
|---|---|---|
| `### Features` | `### 新功能` | New user-facing functionality, such as a new command, flag, mode, or capability that did not exist before |
-| `### Bug Fixes` | `### 修复` | Fixes for behavior that was broken |
| `### Polish` | `### 优化` | User-visible improvements to existing functionality, including UX adjustments, behavior tweaks, and performance improvements that are not fixes or new capabilities |
+| `### Bug Fixes` | `### 修复` | Fixes for behavior that was broken |
| `### Refactors` | `### 重构` | Internal changes with no user-visible behavior change, including build, CI, tests, dependency cleanup, and internal renames |
| `### Other` | `### 其他` | Anything that does not fit above, such as CDN/endpoint swaps and docs-related artifacts |
@@ -148,6 +163,8 @@ Classification process:
Features vs. Polish: ask whether the entry introduces something the user could not do before. If yes (new command, flag, mode, viewer, or capability), use `Features`. If it only improves an existing surface (a UI panel that already existed, an existing prompt, an existing tool card, an existing payload pipeline), use `Polish`. Verbs like `Add` do not automatically mean `Features` — a small visual addition to an existing UI is still polish.
+Default-behavior changes: changing the default value of an existing capability (for example flipping a feature on by default) is usually `Polish`, because the capability already existed. Use `Features` only when the new default materially changes the out-of-box experience for most users in a way they could not get before. When genuinely ambiguous, flag it and confirm with the reviewer rather than guessing.
+
Keyword hints:
- **Features**: `Add ... command/flag/option/mode/viewer`, `Introduce`, `Support`, `Allow`, `Enable`, `Implement`, `New ... command/flag/option`
@@ -159,14 +176,15 @@ Keyword hints:
Within each version, section order is:
```text
-Features → Bug Fixes → Polish → Refactors → Other
+Features → Polish → Bug Fixes → Refactors → Other
```
Omit empty sections. Within each section, order entries by reader value, not upstream order:
1. Put the most valuable, obvious, and larger changes first.
2. Prefer broad user-visible features, workflow-changing fixes, high-frequency bugs, and large cross-cutting improvements over small polish, narrow edge cases, and internal cleanup.
-3. If entries have similar value, preserve upstream order.
+3. Within `Polish`, put directly user-visible UX or performance improvements (something users can see or feel) before protocol or internal-behavior adjustments (something that makes the model or pipeline behave more reliably but is invisible to users).
+4. If entries have similar value, preserve upstream order.
Do not reword or exaggerate entries just to make them look more important; only reorder existing entries.
@@ -246,6 +264,7 @@ Structural fidelity does not mean literal translation. The Chinese entries shoul
Guidelines:
- **One entry, one sentence.** Avoid chaining multiple effects with commas or semicolons. If the English entry is long, split it into shorter sentences or keep only the most important effect.
+- **Drop SDK-only and provider-internal detail.** Apply the trim from step 3 while translating: keep the user-facing effect and required constraints, drop SDK-mapping sentences, provider / wire-format mechanics, and internal XML markers. A long internal entry should collapse to one short Chinese sentence about what the user gets.
- **Prefer common changelog verbs**: 新增、支持、修复、优化、改进、调整.
- **Avoid indirect "through... make..." structures**. Do not write "通过 X,使 Y"; prefer direct cause-effect or just state the result.
- Bad: `通过缓存已渲染消息行,使终端在长篇对话中保持响应。`
@@ -263,6 +282,7 @@ Guidelines:
- Bad: `传入 --allowed-host 以允许额外的 host。例如 ... (多句展开)`
- Better: `例如 kimi web --allowed-host example.com。`
- **Do not translate technical identifiers**: keep command names, flag names, file names, env vars, config keys, and the `web:` scope prefix as-is.
+- **Keep parallel rhythm within a section.** When several entries fix similar web surfaces (layout, animation, sizing), phrase them with a consistent structure (for example 修复 <问题>,现 <行为>) so the section reads as a tidy list rather than a mix of shapes.
Example — translating a feature entry:
@@ -300,6 +320,7 @@ Check:
- Each section has the same number of entries on both pages.
- Within each section, the most valuable, obvious, and larger entries appear before smaller or narrower entries.
- PR links and commit hashes were stripped.
+- No `Thanks ...!` credit remains (remove it every time).
- Real internal identifiers were replaced with neutral placeholders.
- There are no empty sections.
- Markdown indentation and blank lines are intact.
@@ -416,6 +437,10 @@ Return the PR URL to the user when done.
|---|---|
| Adding entries directly to the English docs page without reading upstream | Use `apps/kimi-code/CHANGELOG.md` as the source |
| Copying PR links or commit hashes into docs | Strip them; keep only body text |
+| Leaving the `Thanks ...!` credit in docs | Remove it every time, including the multi-author form |
+| Leaving near-duplicate micro-tweaks as separate bullets | Merge small tweaks to the same surface into one higher-level entry (e.g. composer height + font → composer's default styling) |
+| Listing many narrow fixes to the same surface as separate bullets | When three or more fixes target the same UI area or the same class of problem, merge them into one higher-level fix entry; keep genuinely distinct or high-value fixes standalone |
+| Listing a server/API entry that only backs a web feature already listed | Drop the API entry and keep the `web:` entry, unless the API has independent user value |
| Rewording upstream English entries | Upstream is frozen; copy the body text unless the user explicitly asks otherwise |
| Leaving English text untranslated in the Chinese page | The Chinese page must be fully Chinese except preserved technical terms |
| Editing upstream changelog text | Do not edit upstream |
diff --git a/.changeset/README.md b/.changeset/README.md
index dd568888bd..42457c1326 100644
--- a/.changeset/README.md
+++ b/.changeset/README.md
@@ -29,7 +29,6 @@ All other workspace packages are private internal packages, are not published to
- `@moonshot-ai/vis`
- `@moonshot-ai/vis-server`
- `@moonshot-ai/vis-web`
-- `kimi-migration-legacy`
Version impact from internal dependencies must be judged manually. The published artifacts for CLI and SDK bundle internal workspace packages into the artifact itself; runtime `dependencies` of published packages must not include any `@moonshot-ai/*` internal workspace packages.
diff --git a/.changeset/ask-user-dismiss-not-recommended.md b/.changeset/ask-user-dismiss-not-recommended.md
new file mode 100644
index 0000000000..734886d44c
--- /dev/null
+++ b/.changeset/ask-user-dismiss-not-recommended.md
@@ -0,0 +1,5 @@
+---
+"@moonshot-ai/kimi-code": patch
+---
+
+Treat a dismissed question prompt as the user choosing not to answer, instead of implicitly selecting the recommended option.
diff --git a/.changeset/config.json b/.changeset/config.json
index c430a5cee9..2320f45e31 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -1,5 +1,5 @@
{
- "changelog": ["@changesets/changelog-github", { "repo": "MoonshotAI/kimi-code", "disableThanks": true }],
+ "changelog": ["@changesets/changelog-github", { "repo": "MoonshotAI/kimi-code" }],
"commit": false,
"fixed": [],
"linked": [],
@@ -10,8 +10,7 @@
"@moonshot-ai/server-e2e",
"@moonshot-ai/vis",
"@moonshot-ai/vis-server",
- "@moonshot-ai/vis-web",
- "kimi-migration-legacy"
+ "@moonshot-ai/vis-web"
],
"snapshot": {
"useCalculatedVersion": true,
diff --git a/.changeset/dynamically-loaded-tools-capability.md b/.changeset/dynamically-loaded-tools-capability.md
new file mode 100644
index 0000000000..1ff8e84f24
--- /dev/null
+++ b/.changeset/dynamically-loaded-tools-capability.md
@@ -0,0 +1,7 @@
+---
+"@moonshot-ai/kosong": patch
+"@moonshot-ai/kimi-code": patch
+"@moonshot-ai/kimi-code-sdk": patch
+---
+
+Rename the dynamic tool loading model capability from `select_tools` to `dynamically_loaded_tools`.
diff --git a/.changeset/fix-gemini-tool-calling.md b/.changeset/fix-gemini-tool-calling.md
deleted file mode 100644
index f0d7bbe91d..0000000000
--- a/.changeset/fix-gemini-tool-calling.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-Fix tool calling with Google Gemini models, including Gemini 3 thinking-signature round-trips across turns.
diff --git a/.changeset/print-goal-cron-turns.md b/.changeset/print-goal-cron-turns.md
new file mode 100644
index 0000000000..4d6c7936b9
--- /dev/null
+++ b/.changeset/print-goal-cron-turns.md
@@ -0,0 +1,5 @@
+---
+"@moonshot-ai/kimi-code": minor
+---
+
+Keep `kimi -p` runs alive after a turn ends while a goal is still active or a cron task is pending, so goal continuations and cron fires run their turns instead of being cut off when the main turn finishes.
diff --git a/.changeset/rebuild-session-index-on-boot.md b/.changeset/rebuild-session-index-on-boot.md
deleted file mode 100644
index e9bd68cb3b..0000000000
--- a/.changeset/rebuild-session-index-on-boot.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-Fix sessions that exist on disk but were missing from the session list or returned 404 on direct access, by rebuilding the session index at server startup and keeping it consistent.
diff --git a/.changeset/refill-composer-attachments.md b/.changeset/refill-composer-attachments.md
deleted file mode 100644
index dfb5ae1b88..0000000000
--- a/.changeset/refill-composer-attachments.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-web: Fix queued media messages not loading back into the composer and keep attachments when undoing a message.
diff --git a/.changeset/web-ask-user-question-result.md b/.changeset/web-ask-user-question-result.md
deleted file mode 100644
index cd5146ccc4..0000000000
--- a/.changeset/web-ask-user-question-result.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-web: Render AskUserQuestion answers as a readable option list with the chosen option(s) highlighted, instead of raw JSON.
diff --git a/.changeset/web-markdown-diff-block.md b/.changeset/web-markdown-diff-block.md
deleted file mode 100644
index 3679acf5bd..0000000000
--- a/.changeset/web-markdown-diff-block.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-web: Align the markdown diff code block with the design system: code text keeps the normal ink colour while the sign and a soft row background carry the change, matching the ~/diff panel.
diff --git a/.changeset/web-pre-session-skills.md b/.changeset/web-pre-session-skills.md
deleted file mode 100644
index 45c26e4fda..0000000000
--- a/.changeset/web-pre-session-skills.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-web: Show available skills in the composer before a session is created.
diff --git a/.changeset/web-resume-media-tool.md b/.changeset/web-resume-media-tool.md
new file mode 100644
index 0000000000..a18aea7b5e
--- /dev/null
+++ b/.changeset/web-resume-media-tool.md
@@ -0,0 +1,5 @@
+---
+"@moonshot-ai/kimi-code": patch
+---
+
+web: Fix ReadMediaFile results rendering as plain tool cards instead of images after resuming or reloading a session.
diff --git a/.changeset/web-tool-row-body-padding.md b/.changeset/web-tool-row-body-padding.md
deleted file mode 100644
index ce4f4d8961..0000000000
--- a/.changeset/web-tool-row-body-padding.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@moonshot-ai/kimi-code": patch
----
-
-web: Drop the stray left indent in the tool-call card body so expanded content aligns with the header.
diff --git a/.changeset/webbridge-plugins-link.md b/.changeset/webbridge-plugins-link.md
new file mode 100644
index 0000000000..55ce6bb282
--- /dev/null
+++ b/.changeset/webbridge-plugins-link.md
@@ -0,0 +1,5 @@
+---
+"@moonshot-ai/kimi-code": patch
+---
+
+Update the WebBridge install page link opened from the /plugins panel.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 16b9c0f12a..e5c4c6d37b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,7 +37,7 @@ jobs:
registry-url: "https://registry.npmjs.org"
- name: Upgrade npm for Trusted Publishing
- run: npm install -g npm@latest
+ run: npm install -g npm@11
- name: Install dependencies
run: pnpm install --frozen-lockfile
diff --git a/.gitignore b/.gitignore
index 46dca949ef..203492e4e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,16 @@ docker-compose.yml
docs/superpowers/
reports/
.superpowers/
+/plan/
+
+# Agent scratch / throwaway files - do not commit
+.tmp/
+HANDOVER*.md
+HANDOFF*.md
+handoff.md
+handover.md
+*-designs.html
+*-design.html
+*-mockup.html
+*-demo.html
+*-demos.html
diff --git a/AGENTS.md b/AGENTS.md
index a9f77b457d..f8cdf7c107 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -77,3 +77,7 @@ This is a TypeScript monorepo built for agent-assisted development. Keep the roo
- After finishing a task and before submitting a PR, you must run the `gen-changesets` skill (see `.agents/skills/gen-changesets/SKILL.md`) and generate a changeset under `.changeset/` according to its rules.
- When generating a changeset, **never** decide on a `major` bump on your own. When you judge a change to meet the major criteria (breaking changes, incompatible user configuration, renamed or removed commands/arguments, changed behavior semantics, etc.), you must stop and explain it to the user and ask for confirmation. **Only write `major` after the user has explicitly agreed.** Otherwise default to `minor` (and fall back to `patch` if `minor` is unclear). See the "Hard rule: confirm with the user before writing `major`" section in `.agents/skills/gen-changesets/SKILL.md` for details.
- Prefer importing via `import ... from '#/...'`, which serves the same purpose as `import ... from '@/...'`.
+- Do not commit throwaway scratch or exploratory files. Never stage:
+ - Agent working notes or handoff/summary documents (e.g. `HANDOVER-*.md`, `HANDOFF-*.md`, `handoff.md`).
+ - Throwaway UI/UX prototypes or design mockups (e.g. `*-designs.html`, `*-mockup.html`, `*-demo(s).html`) at the repo root or under a `design/` folder. The only tracked `.html` files should be Vite `index.html` entrypoints.
+ Before committing or opening a PR, run `git status` and `git diff --staged --stat` and remove anything matching these patterns. Put scratch work under `.tmp/` (gitignored) instead of the repo root or the source tree.
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 120000
index 0000000000..47dc3e3d86
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
diff --git a/HANDOVER-kimi-web-table-width.md b/HANDOVER-kimi-web-table-width.md
deleted file mode 100644
index c3ac05613a..0000000000
--- a/HANDOVER-kimi-web-table-width.md
+++ /dev/null
@@ -1,149 +0,0 @@
-# 接手文档:kimi-web 聊天表格宽度
-
-> **当前状态(未提交,用户先用着)**:表格在阅读列(≈760px)内**单元格换行**显示——
-> 不横向滚动、不溢出、不裁切,但**没有比正文更宽**。这是目前效果最干净、可以先用的版本。
->
-> **仍未达成的目标**:让宽表格像 Manus 那样**突破到比正文更宽的列**再换行。两次突破尝试
-> (容器单位 `cqw`、固定 px `@container` 断点)都没做出满意效果,已回退/停用,见 §4、§6。
->
-> **只改了 1 个文件**:`apps/kimi-web/src/components/chat/Markdown.vue`(表格样式块)。
-> typecheck / check:style 通过。
-
-## 1. 背景与目标
-
-`apps/kimi-web` 聊天里 markstream 渲染的 markdown 表格,默认被钉在阅读列宽内
-(`width:100%` + `table-layout:fixed`),宽表格要么被挤成很窄的列、要么表格内横向滚动。
-
-用户想要的最终效果(参照 Manus 截图):
-
-1. 表格**比正文阅读列更宽**(横向铺开),但
-2. 单元格**换行**,所以表格**永不横向滚动**(表格自身和对话面板都不滚),且
-3. 正文 / 代码 / diff / 工具块 / thinking 等其它块仍限在 760px 阅读列内。
-
-> 第 1 点(撑得比正文宽)目前**没做到**——见 §6。当前上线的是"列内换行"的降级版。
-
-## 2. 当前实现(列内换行版,正在用)
-
-`Markdown.vue` `
-
-
-
-