Commit graph

446 commits

Author SHA1 Message Date
7Sageer
ee69e16dc8
fix: use session cwd for stdio MCP servers (#1057) 2026-06-24 13:40:56 +08:00
7Sageer
a752a5309b
fix(agent-core): mark truncated skill descriptions with an ellipsis (#1064)
The model-facing skill listing silently sliced long descriptions to 250 characters with no marker, so neither the user nor the model could tell a description was cut. Truncated entries now end with an ellipsis and the truncation walks whole grapheme clusters so it never splits a surrogate pair or combining sequence.
2026-06-24 13:20:48 +08:00
qer
5ef66ddfed
feat(tui): redesign /plugins as a tabbed panel (#1025)
* feat(tui): redesign /plugins as a tabbed panel

Split the /plugins manager into Installed / Official / Third-party /
Custom tabs. The Official and Third-party marketplace catalogs load
lazily, so /plugins opens instantly and keeps working offline, with
fetch failures shown inline instead of closing the panel. The tab strip
is shared with the /model provider tabs via the new renderTabStrip
helper.

* fix(tui): show untiered marketplace entries and update badges

Address Codex review feedback on the /plugins tab redesign:

- Untiered marketplace entries (no `tier` field) now appear on the
  Third-party tab instead of being invisible in both marketplace tabs.
- Installed plugins whose marketplace version is newer than the local
  version render an `update <local> → <latest>` badge again, and
  up-to-date plugins show `installed · v<version>` — restoring the
  update visibility the pre-redesign marketplace UI had.

* fix(tui): decode Space for installed-plugin toggle

In terminals that send printable keys via Kitty/CSI-u sequences (e.g. VS
Code's integrated terminal), the Space key arrives as a printable char
rather than a Key.space match, so the Installed-tab Space toggle silently
stopped working. Check both matchesKey(Key.space) and the decoded
printable char to match the MCP selector and other dialogs.

* fix(tui): open custom marketplaces on the Third-party tab

When `/plugins marketplace <source>` points at a custom catalog whose
entries omit `tier`, those entries are classified into the Third-party
tab. Opening on Official left the visible tab empty and Enter could not
install anything, unlike the old marketplace picker which showed all
entries from the supplied source. Open on Third-party when a custom
source is supplied; the default catalog still lands on Official.

* docs(plugins): drop open-url wording and hyphenate Shift-Tab

Address Codex review feedback:

- The marketplace Enter action is install/update only (open-url rows were
  removed), so say "install or update" instead of "open or install" and
  drop the leftover changeset sentence about setup URLs.
- Use `Shift-Tab` (hyphen) instead of `Shift+Tab` to match the docs
  typography convention.

* fix(tui): keep marketplace selection valid while loading

When the Official/Third-party catalog is still loading, `entries` is empty
and pressing ↓ computed `Math.min(-1, selectedIndex + 1)` = -1. The later
Enter then read `entries[-1]` and the first install silently did nothing.
Clamp the index to 0 while there are no entries.

* fix(tui): count tab separators in tab-strip fit check

renderTabStrip declared a strip to fit whenever the sum of tab cell widths
fit, but the returned string also inserts single spaces between tabs via
`segments.join(' ')`. At widths around 43-45 columns for a four-tab strip
this declared a fit while the joined line was wider, so the trailing tab
got truncated instead of showing the `<`/`>` scroll markers. Count the
inter-tab separators in both the full-fit check and the scrolling window
fit check.

* docs(plugins): fix Kimi Datasource redirect anchor

The datasource.md redirect pointed at ./plugins.html#kimi-datasource, but
plugins.md no longer has a `## Kimi Datasource` heading — it is now
`## Official Plugins`. Update the en/zh redirect targets and fallback
links to #official-plugins / #官方插件 so the link lands on an existing
anchor.

* docs(plugins): restore concise Kimi Datasource section

The `## Official Plugins` section had replaced the original
`## Kimi Datasource` section, leaving the datasource.md redirect pointing
at a missing anchor and the Datasource capabilities/usage unreachable.
Restore a concise `## Kimi Datasource` section (intro + OAuth login +
install steps + usage) in both en and zh so the #kimi-datasource anchor
is valid again and the content is reachable.

* docs(plugins): restore Installing-from-GitHub subheading

The tab-redesign rewrite had dropped the `### Installing from GitHub` /
`### 从 GitHub 安装` subheading and its lead sentence, leaving only the
four URL forms. Restore the heading and lead sentence in both en and zh.

* docs(plugins): expand Kimi Datasource and tidy marketplace docs

- Condense the Official / Third-party / Custom tab overview and trust-badge note

- Trim the custom marketplace JSON section to the minimal id + source shape

- Move and expand the Kimi Datasource section with install, usage, and coverage

* docs(plugins): fix heading style and drop Next steps section

- Use sentence case for the Datasource headings (How to use, What you can do)

- Rename the Datasource caveat heading to Billing and limitations / 计费与限制 to avoid a duplicate Notes / 注意事项 anchor

- Remove the Next steps section, which linked back to the on-page Datasource anchor

* fix(tui): repaint plugins panel from current theme palette

The /plugins panel and MCP selector captured a palette snapshot at construction. In auto theme mode, applyResolvedAutoTheme swaps currentTheme.palette and re-renders without remounting the open panel, so it kept stale colors until closed.

Read currentTheme.palette during render instead, drop the colors opt from both components and their call sites, and add a regression test that switches palettes on a mounted panel.

* fix(tui): repaint model tab strip from current theme palette

TabbedModelSelectorComponent cached a palette snapshot in opts and used it only for the tab strip. In auto theme mode the inner model list repaints from currentTheme but the strip kept the old colors until the dialog was closed.

Read currentTheme.palette on the render path instead, drop the colors opt and its three call sites, and add a regression test that switches palettes on a mounted selector and asserts the strip repaints. This removes the last palette snapshot among editor-replacement dialogs.
2026-06-24 13:12:28 +08:00
qer
51723bee1a
docs(changelog): sync 0.19.2 from apps/kimi-code/CHANGELOG.md (#1063) 2026-06-24 12:46:27 +08:00
Kai
66640380eb
feat: replace silent AGENTS.md truncation with a visible warning (#1040)
Oversized AGENTS.md files are no longer silently truncated. The full
content is injected, and a warning is shown in the TUI status bar and the
web UI when the combined AGENTS.md size exceeds the recommended 32 KB.

A generic session-warnings API backs this so future warning types can be
added without changing the API surface.
2026-06-24 12:26:17 +08:00
github-actions[bot]
0bcd9843c1
ci: release packages (#997)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-24 12:13:38 +08:00
qer
98d3e5b71d
feat(web): stabilize and drag-reorder workspaces in the sidebar (#1047)
* feat(web): stabilize and drag-reorder workspaces in the sidebar

* fix(web): preserve dragged workspace order after refresh

* fix(web): float session to top of its group on new message

* fix(web): align workspace drop order with insertion marker

* fix(web): allow dropping a workspace after the last item

* fix(web): use reordered workspaces for active fallback

* fix(web): honor drag order for next-workspace fallback on removal
2026-06-24 12:06:32 +08:00
qer
b93e9365b6
fix(web): stop auto-approving plan reviews and sensitive files in yolo mode (#1056)
The web app ran a client-side policy that auto-approved every approval request in auto/yolo mode, including plan reviews, sensitive file access, and other asks the daemon intentionally sends for user confirmation. The daemon already resolves auto/yolo server-side, so drop the client-side auto-approve and let those requests reach the approval UI.
2026-06-24 11:21:21 +08:00
qer
ac1882fe28
feat(web): persist collapsed workspace groups to localStorage (#1045) 2026-06-23 22:45:24 +08:00
_Kerman
c240bfab7d
fix(agent-core): realign mid-history interrupted tool calls on resume (#1027) 2026-06-23 22:39:19 +08:00
qer
9d197e0f67
fix(web): make clipboard copy work over plain HTTP (#1044)
* fix(web): make clipboard copy work over plain HTTP

The Clipboard API (navigator.clipboard) is only exposed in secure contexts. When the web UI is served over plain HTTP, every copy action threw synchronously and silently failed. Route all copy call sites through a helper that falls back to execCommand('copy') in insecure contexts, and surface success or failure feedback to the user.

* test: address review feedback and a flaky goal-badge test

- clipboard test: drop the jsdom environment and mock the small navigator/document surface in the default node environment, per the kimi-web "pure logic tests only" rule.

- footer-goal-badge test: assert the absence of the "[goal" badge instead of the bare "goal" substring, which could match a rotating working tip ("/goal ...") and fail depending on Date.now().
2026-06-23 22:21:10 +08:00
qer
27df39c7ed
fix(web): fall back to session abort for stale prompts (#1043)
* fix(web): fall back to session abort for stale prompts

* test(web): cover stale prompt abort fallback
2026-06-23 22:05:08 +08:00
qer
dc6b9ef02b
feat(web): show dev-mode indicator in sidebar (#1042)
Tint the sidebar logo yellow and append the connected backend host:port to the title when the page is served by the Vite dev server, so local development tabs are easy to tell apart. Inert in production.
2026-06-23 21:41:47 +08:00
liruifengv
be77d5da03
feat(kimi-code): show clipboard image paste hint in footer (#1028)
* feat(kimi-code): add lightweight clipboard image detection

* fix(clipboard): correct Linux X11 image detection and extract shared helpers

- Extract shared clipboard constants/helpers into clipboard-common.ts

- Fix Linux X11 branch calling macOS-only osascript

- Use native hasImage() on Linux X11, macOS, and Windows with fallbacks

- Compute xclip result once and reuse on Linux

- Add test coverage for unsupported MIME types, empty targets, failures, WSL, and native fallbacks

* fix(kimi-code): restore Wayland/WSL xclip fallback in clipboard image detection

* feat(kimi-code): add clipboard image hint controller

* fix(kimi-code): clipboard image hint focus race and cleanup

* fix(kimi-code): prevent clipboard image hint from clearing unrelated hints and stale reads

* fix(clipboard-image-hint): lifecycle issues and platform-dependent tests

* fix(kimi-code): invalidate pending clipboard hint read on stop

* feat(kimi-code): wire clipboard image hint controller into TUI

* style(kimi-code): wrap void expression in braces to fix lint warning

* style(kimi-code): prefer nullish coalescing in clipboard image detection

* chore: add changeset for clipboard image footer hint

* fix(kimi-code): let clipboard image hint observe non-consuming focus events

* fix(kimi-code): extend clipboard image hint display duration to 4 seconds

* docs: mention clipboard image footer hint in interaction guide

* chore: downgrade clipboard image hint changeset to patch

* Revert "docs: mention clipboard image footer hint in interaction guide"

This reverts commit 0fd50dcc9b.

* fix(cli): avoid treating copied Finder files as images on macOS

Filter file-like native clipboard formats in clipboardHasImage() before

calling native hasImage(), mirroring the guard already used by

readClipboardMedia(). This prevents copied Finder files from being

mis-detected as pasteable images because macOS exposes their

thumbnails as image data.

* fix(cli): align image detection with paste path on macOS and Windows

Remove osascript and PowerShell fallbacks from clipboardHasImage() on

macOS and Windows. The paste reader (readClipboardMedia()) only uses the

native clipboard module for images on those platforms, so detecting images

via methods the reader cannot consume produced misleading footer hints.

Linux fallbacks (wl-paste / xclip / PowerShell under WSL) remain because

they match the actual paste path.

* fix(tui): do not truncate inline image escape sequences

UserMessageComponent applied truncateToWidth() to every rendered line,

including the Kitty / iTerm2 inline image escape sequences produced by

ImageThumbnail. pi-tui treats the embedded base64 payload inside those

sequences as visible text, so truncation chopped the escape code and left

behind '0m...' garbage instead of the image.

Skip truncation for lines that contain an inline image protocol sequence;

the image already respects maxWidthCells via ImageThumbnail.

* fix(tui): clear stale rows when content shrinks

Enable pi-tui's setClearOnShrink so that when a tall inline image is

replaced by shorter content (e.g. after sending a message), the terminal

rows the image previously occupied are cleared. Without this, pi-tui's

differential renderer can leave behind artifacts such as duplicated input

boxes.

* chore: add changesets for inline image rendering fixes

* test(cli): stabilize pi-tui capability mocks in concurrent test runs

* test(cli): use setCapabilities instead of mocked getCapabilities
2026-06-23 20:49:01 +08:00
qer
866b91c8f5
refactor(web): group components into area subdirectories (#1036)
Move the 40 feature-specific components out of the flat components/ into
chat/, settings/, dialogs/, and mobile/ subdirectories, leaving 9 shared
layout components at the top level. Recompute every relative import (no
path alias in the web app), refresh the line-1 path comments, and update
the layout description in AGENTS.md.

No behavior change; typecheck / test / build / lint all pass.
2026-06-23 20:34:46 +08:00
liruifengv
b1e6b64319
feat(tui): show working tips behind composing spinner (#1033)
Some checks are pending
CI / build (push) Waiting to run
CI / test (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
* refactor(tui): extract toolbar tip constants to tui/constant/tips.ts

* feat(tui): add WORKING_TIPS subset to tip constants

* feat(tui): allow MoonLoader to render a dim tip suffix

* feat(tui): pass optional tip through ActivityPaneComponent

* feat(tui): show working tip behind composing spinner

* feat(tui): hide working tip when spinner line does not fit

* chore: add changeset for working tips

* feat(tui): guard setAvailableWidth to skip unchanged widths

* feat(tui): show working tips on moon loader and compaction

* feat(tui): use singular 'Tip:' label for loading tips

* fix(tui): keep the same loading tip across waiting/thinking/tool/composing within one turn

* feat: show contextual working tips behind loading spinners

- Add pickRandomWorkingTip() for per-step tip selection

- Cache tips by loading kind (moon/composing) so continuous tool bursts keep the same tip

- Update tip inventory with /web, /plugins, /goal, /sessions, etc.

- Add unit tests for random tip selection

* docs: update working-tips changeset summary
2026-06-23 20:12:55 +08:00
qer
603a7679de
refactor(web): extract attachment upload into a composable (#1034)
Move the image/video attachment state, the file-picker / paste / drag-drop
handlers, the upload machinery, the preview lightbox, and the paste-listener
+ object-URL cleanup lifecycle out of Composer into useAttachmentUpload.

The composer keeps handleSubmit / handleSteer (which read the attachments to
build the payload) and the hasUpload toolbar flag; it consumes the returned
refs and handlers directly. The destructured names match the originals so the
template bindings are unchanged. handleSubmit / handleSteer now call the
composable's clearAfterSubmit() to revoke object URLs and drop the list.

Composer.vue: 1937 -> 1787 lines. Adds unit tests for useAttachmentUpload. No
behavior change.
2026-06-23 19:52:03 +08:00
qer
2bfd6860e4
refactor(web): extract composer text + draft persistence into a composable (#1031)
Move the composer's text ref, textarea ref, autosize helper, the per-session
draft load/save watchers, and the loadForEdit handle into useComposerDraft.
The returned text/textareaRef/autosize refs are passed straight through to the
history / slash / mention composables as their deps, so the rest of the
component is unchanged.

Composer.vue: 1987 -> 1937 lines. Adds unit tests for useComposerDraft. No
behavior change.
2026-06-23 19:14:50 +08:00
qer
a753b0535e
fix(web): upgrade markstream-vue to 1.0.3 to fix blank nested code blocks (#1032)
* fix(web): upgrade markstream-vue to 1.0.3 to fix blank nested code blocks

* fix(web): update flake pnpmDeps hash after markstream upgrade
2026-06-23 19:09:42 +08:00
qer
661c1fbe5b
refactor(web): extract @-mention menu into a composable (#1030)
Move the @-mention menu's open/items/active/loading state, the @token
detection, debounced search, and insertion logic out of Composer into
useMentionMenu. The composer keeps the keydown orchestration (it also
juggles the slash menu and history recall) and consumes the returned refs
directly; the destructured refs are aliased back to the original names so
the rest of the component is unchanged.

Move the FileItem view type into types.ts (mirroring the FileData move) so
the .ts composable can import it without hitting the type-aware lint rule
against importing types from .vue files; MentionMenu re-exports it for the
existing .vue consumers.

Composer.vue: 2035 -> 1987 lines. Adds unit tests for useMentionMenu. No
behavior change.
2026-06-23 18:38:50 +08:00
qer
318c964f07
refactor(web): extract slash-command menu into a composable (#1026)
Move the slash menu's open/items/active state, the filter logic, and item
selection out of Composer into useSlashMenu. The composable takes the text
ref, textarea ref, autosize, a skills getter, and the emit/history-push
callbacks as deps.

The composer keeps the keydown orchestration (arrow keys, Enter/Tab, Escape)
because it also juggles the mention menu and history recall; it consumes the
returned open/items/active refs directly and calls update/select. The
destructured refs are aliased back to the original names so the rest of the
component is unchanged.

Composer.vue: 2058 -> 2035 lines. Adds unit tests for useSlashMenu. No
behavior change.
2026-06-23 18:17:48 +08:00
qer
83384ee6d4
fix(web): persist input history so recall works after the first message (#1015)
* fix(web): persist input history so recall works after the first message

The composer has two mutually-exclusive instances: the empty-session
composer and the docked composer. The first message of a new session is
sent by the empty composer, which unmounts as soon as the first turn
appears; the docked composer then mounted with an empty in-memory history,
so ArrowUp did nothing until a second message was sent. The history was
also lost on every page reload.

Persist the history to localStorage as a single global list and re-read it
on mount. Global (not per-session) because a new session has no id until
after the first submit, so per-session keys would not line up across the
empty -> docked handoff. Caps the list at 200 entries.

Adds persistence-focused unit tests (surviving a remount, the 200-entry
cap, and a malformed stored value).

* fix(web): record slash commands in input history too

Move the history.push call ahead of the slash-command branch so that known
commands (with or without args, e.g. /goal <task> or /model) are recorded
and can be recalled with ArrowUp, instead of only plain messages. Steer
already pushed; only the submit slash path was missing it.

* fix(web): record menu-selected slash commands in history

Bare slash commands picked from the slash menu (e.g. /model, /login) go
through selectSlashCommand and emit directly, never reaching handleSubmit,
so they were not recorded even after the typed-slash fix. Push the command
name before emitting. acceptsInput commands are still recorded later by
handleSubmit together with their argument.
2026-06-23 18:07:00 +08:00
liruifengv
6d506380ce
fix(changeset): downgrade web panel resize changeset from minor to patch (#1021) 2026-06-23 17:23:31 +08:00
liruifengv
9c553e4bf7
feat(tui): add Alt+S to switch model for current session only (#1020)
In the /model picker, Enter still switches the model and saves it as the
default; Alt+S now switches only for the current session without writing
to the config file.
2026-06-23 17:14:43 +08:00
qer
fb780fce96
refactor(web): extract input-history recall into a composable (#1011)
* refactor(web): extract input-history recall into a composable

Move the shell-style up/down recall of previously sent messages out of
Composer into useInputHistory. The composable owns the history list, the
browsing cursor, and the textarea caret/selection work needed to apply a
recalled entry, taking the text ref, textarea ref, and autosize as deps.

The composer keeps the keydown orchestration (which also juggles the slash
and mention menus) and calls into the composable for push / recall / caret /
browsing state.

Composer.vue: 2104 -> 2050 lines. No behavior change.

* test(web): cover useInputHistory recall behavior

Add unit tests for the extracted input-history composable: push dedup and
empty-skip, walking backward/forward through entries, restoring the live
draft (empty and non-empty), empty-history no-op, resetBrowsing, and the
caretAtFirstLine gate.
2026-06-23 17:01:17 +08:00
liruifengv
fd16ffb80a
fix(tui): fix Tab key completion in the editor (#1012)
Stop plain Tab from opening the file completion list when the autocomplete menu is closed; Tab now only accepts the selected item while the menu is open.

After Tab-completing a slash command name, reopen the menu to show its subcommands instead of falling back to file completions.
2026-06-23 16:51:12 +08:00
qer
a2650f85d4
refactor(web): extract ConversationToc from ConversationPane (#1010)
Move the beta conversation outline (proportional bubbles, viewport
indicator, hover tooltip) into a dedicated ConversationToc component.
The child owns the nav markup, the tooltip hover state, and its own
visibility (mobile / session-loading / single-turn), while the metric
derivation and scroll-driven viewport/active-turn tracking stay in the
pane because they are coupled to the scroll container.

ConversationPane.vue: 1613 -> 1422 lines. No behavior change.
2026-06-23 15:51:49 +08:00
liruifengv
e47de610e4
feat(tui): add ctrl+t to expand the todo list (#1009)
* feat(tui): add ctrl+t to expand the todo list

Toggle between the truncated view and the full list; the shortcut only takes effect while the list actually overflows.

* docs(keyboard): document ctrl+t todo expand shortcut

* chore(changeset): mark todo expand shortcut as patch

* docs(agents): clarify minor vs patch in gen-changesets skill

* fix(tui): clear pending exit when toggling the todo list
2026-06-23 15:49:07 +08:00
liruifengv
d70c3a8c01
fix(tui): support expanding bash command while running (#1004)
Render the command in the in-flight Bash card body so it is visible while the command runs, and let Ctrl+O expand the full command before the result arrives.
2026-06-23 15:28:49 +08:00
qer
ea1b33b674
refactor(web): extract pure turn-rendering helpers from ChatPane (#1001)
* refactor(web): extract pure turn-rendering helpers from ChatPane

* chore: add changeset for chat pane helper extraction

* test(kimi-web): cover chat turn-rendering helpers

Pure-logic tests for the helpers extracted from ChatPane, focused on
assistantRenderBlocks (tool-stack grouping, interrupt/media break, single
tool) plus the formatting/boundary helpers. Doubles as a safety net
confirming the extraction preserved behavior.
2026-06-23 15:20:00 +08:00
qer
e15edfd017
fix: always expose the free-text Other option in question prompts (#1003)
The question adapter only set allow_other on the wire when the SDK item carried an otherLabel/otherDescription, but the AskUserQuestion tool never provides those fields. Web clients honor allow_other, so the free-text option silently disappeared in the web UI while the TUI (which renders it unconditionally) kept working. Set allow_other unconditionally to match the tool's 'users always have an Other option' contract.
2026-06-23 15:09:55 +08:00
7Sageer
b84704bff3
perf(kaos): optimize large file reads (#971) 2026-06-23 15:07:40 +08:00
liruifengv
6b68aa85e2
feat(cli): add -c as shorthand for --continue (#999)
The lowercase -c now maps to --continue, shown in help as the primary short flag. The uppercase -C still works as a hidden alias since commander does not allow two short flags on a single option.
2026-06-23 13:53:31 +08:00
qer
3e4793d611
refactor(web): extract WorkspaceGroup from Sidebar (#998)
* refactor(web): extract WorkspaceGroup from Sidebar

* chore: add changeset for sidebar workspace group extraction
2026-06-23 13:33:36 +08:00
qer
92c2cf0ef5
feat(web): remove sidebar and panel max-width limits (#985)
* feat(web): remove sidebar and panel max-width limits

Make the resize handle max width optional so the web sidebar and right-side detail/preview panel can be resized beyond their previous fixed maximums.

* fix(web): keep sidebar resize handle reachable on narrow windows

Cap the restored sidebar width at a viewport-aware maximum (viewport width minus the conversation pane minimum) so a width saved on a wide display cannot push the resize handle or collapse button off-screen on a narrower window. The cap updates on resize.

* fix(web): cap preview panel to viewport and share panel-width logic

Apply the same viewport-aware maximum to the right-side detail/preview panel and extract the viewport tracking and width clamping into a shared composable used by both panels.

* fix(web): keep resize caps reactive and reserve room for the preview

Make the resize handle read its max width reactively so a viewport-derived cap keeps working as the window grows after mount. Also have the sidebar reserve the preview panel's minimum width whenever the right-side panel is open, so the conversation column can never be squeezed to zero.

* fix(web): clamp sidebar content width and ignore stale preview target

Render the Sidebar content at the clamped width so controls stay reachable when the saved width exceeds the viewport cap. Also stop reserving space for a hidden right panel by keying the sidebar preview-open check off detailTarget instead of the stale previewTarget.

* fix(web): clamp drag start to current resize cap

When the saved width exceeds the current cap (after the window narrows or a side panel opens), start the drag from the clamped width so the handle responds immediately instead of first covering an invisible delta.

* fix(web): clear detailTarget when closing side chat via /btw

The bare /btw close path called client.closeSideChat() directly, which hid the panel but left detailTarget set to 'btw', so the sidebar kept reserving room for a hidden right panel. Route it through the detail-layer close which clears detailTarget.
2026-06-23 13:14:19 +08:00
liruifengv
87fb95850c
docs(changelog): sync 0.19.1 from apps/kimi-code/CHANGELOG.md (#995)
Some checks are pending
CI / build (push) Waiting to run
CI / test (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
2026-06-23 12:10:06 +08:00
github-actions[bot]
7d2a23e7db
ci: release packages (#983)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-23 11:29:45 +08:00
liruifengv
7341fb4979
fix(acp): read workspace local config via local fs at session start (#992)
Read `.kimi-code/local.toml` through the persistence (local) kaos instead of
the ACP tool kaos during session bootstrap. The ACP reverse-RPC bridge needs
the session registered on the client, which is not true until `session/new`
returns, so reading through it failed with "unknown session" and blocked new
threads in ACP editors such as Zed.

Fixes #988
2026-06-23 11:19:20 +08:00
qer
da81858802
fix(web): clear all per-session state when archiving or removing a session (#984)
Some checks are pending
CI / build (push) Waiting to run
CI / test (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
* fix(web): clear all per-session state when archiving or removing a session

* fix(web): clear queued and in-flight prompt state in session teardown

* fix(web): unsubscribe session before clearing its state in teardown

* fix(web): cancel pending WS subscriptions on unsubscribe
2026-06-23 01:29:23 +08:00
qer
8c6cade69e
refactor(web): consolidate storage and split root state and app shell into composables (#979)
* refactor(web): consolidate localStorage access and split appearance/notification modules

* refactor(web): extract task polling into useTaskPoller module

* refactor(web): split useKimiWebClient into workspace/sideChat/modelProvider modules

* refactor(web): extract App.vue composables for page title, auth, sidebar, detail panel and file preview

* refactor(web): funnel sessions and activeSessionId mutations through setters

* refactor(web): funnel messagesBySession mutations through setters

* refactor(web): move FileData type to types.ts to fix type-aware lint
2026-06-22 23:56:14 +08:00
qer
d4ae02d82e
fix(web): keep sidebar unread dots in sync across browser tabs (#978) 2026-06-22 23:36:58 +08:00
qer
0c689e1891
changelog: 0.19.0 (#980) 2026-06-22 22:05:58 +08:00
github-actions[bot]
b2d3ad0728
ci: release packages (#911)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-22 21:39:21 +08:00
qer
4731f02ccb
chore(skills): add pre-changelog skill (#902)
* chore(skills): add release-precheck skill

Add a project-scope agent skill that audits an open kimi-code release PR ("ci: release packages") before merge: it lists the changesets the release will publish, maps each to its source PR, scans the release window for merged PRs that forgot a changeset, and flags wrong bump levels, wrong packages, and non-compliant wording. Outputs the release PR link and a concise suggestion table.

* chore(skills): fix release-precheck package glob and base filter

* chore(skills): classify shipped apps/vis paths as needing changeset

* chore(skills): simplify release-precheck to principle-based audit

* chore(skills): scope release-precheck to changeset validation only

* chore(skills): surface possibly-missing changesets in release-precheck

* chore(skills): replace release-precheck with pre-changelog
2026-06-22 21:36:31 +08:00
liruifengv
e7dd13804d
feat(tui): detach foreground tasks to background with Ctrl+B (#976)
* feat(tui): detach foreground tasks to background with Ctrl+B

- Add Ctrl+B shortcut to detach all foreground Bash/subagent tasks at once

- Show "Press Ctrl+B to run in background" hint in tool cards (Agent immediately, Bash after 10s) and in the agent group panel

- Mark detached foreground subagents as ◐ backgrounded instead of ✓ Completed

- Filter foreground tasks out of the /tasks panel (they appear after detach)

- Steer the model away from blocking on TaskOutput after a detach

* fix(tui): address Codex review on Ctrl+B detach

- Preserve `◐ backgrounded` for detached subagents inside AgentGroupComponent by reusing getDerivedSubagentPhase in getSubagentSnapshot

- Distinguish detached-from-foreground subagents from started-in-background ones so the latter still read as `done`

- Let Ctrl+B fall through to readline backward-char at the idle prompt instead of always consuming the key

* fix(tui): address follow-up Codex review on detach hints

- Auto-clear the "No foreground task running." hint via showDetachHint so it doesn't stick on the footer

- Don't clobber a newer transient hint (e.g. exit confirmation) when the detach hint timer fires

- Add FooterComponent.getTransientHint()

* fix(tui): address Codex review on backgrounded gating and /tasks counts

- Only mark foreground-running subagent cards as backgrounded (skip done/backgrounded cards so background resumes don't mutate older rows)

- Count /tasks header from the filtered (background-only) task set so foreground-only sessions don't read misleading counts
2026-06-22 20:59:24 +08:00
qer
d521932c3e
fix(web): stop showing unread dots for cancelled or failed sessions (#977) 2026-06-22 20:43:05 +08:00
Haozhe
c5c1834725
feat(server): add fast disk-based snapshot reader (#975)
Some checks are pending
CI / build (push) Waiting to run
CI / test (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
* feat(server): add fast disk-based snapshot reader

- add ISnapshotService that reads session state and wire log directly from disk for fast initial sync
- gate the reader behind KIMI_SNAPSHOT_READER (auto/legacy) with a KIMI_SNAPSHOT_TIMEOUT_MS ceiling, keeping the legacy assembly as a fallback
- version @moonshot-ai/server and other internal packages in changesets instead of ignoring them

* fix(server): resolve TS4111 error in snapshot perf test

Use bracket access for process.env['KIMI_SNAPSHOT_READER'] to satisfy
noPropertyAccessFromIndexSignature.
2026-06-22 19:47:31 +08:00
liruifengv
c0eeca2469
feat: add workspace add-dir support (#812)
* feat: add workspace add-dir support

Add multi-directory /add-dir management with session-only or project-remembered persistence, directory completion, confirmation UI, and runtime workspace/permission wiring.

* fix: honor --add-dir for resumed sessions

Pass CLI additional directories through shell and prompt resume paths, resolve caller-relative dirs against workDir, and add regression coverage.

* fix: keep additional dirs AGENTS.md out of default context

Load only user-level and cwd AGENTS.md by default, while preserving additional directory listings in the prompt context.

* feat: append /add-dir result as user message

Add a session appendUserMessage RPC and use it after /add-dir so the command result is recorded as a normal user message and surfaced in the transcript.

* docs: add add-dir research and follow-up todos

Document the add-dir / local-command-stdout research findings and the follow-up tasks for stdout wrapping, slash file completion, and hints.

* feat: wrap /add-dir output as local-command-stdout

Insert the /add-dir result as a user-role <local-command-stdout> record with an injection origin directly inside Session.addAdditionalDir. It enters the model context on the next turn but does not start a turn, and stays out of the live and resumed transcript; the transient status toast is kept for immediate feedback. --add-dir is unaffected since it bypasses addAdditionalDir.

Remove the now-unused appendUserMessage RPC and SDK method.

* feat: reopen /add-dir completion after accepting a directory

Generalize the slash-argument completion reopen so it fires whenever the text before the cursor ends with '/', not only when the literal '/' key is typed. After Tab-accepting a directory (or auto-applying a single-child dir), the next level's completion list reappears automatically, so repeated Tab keeps drilling down into subdirectories. '@' file mention is unaffected.

* feat: reopen file mention completion after accepting a directory

Extend the path completion reopen so it also fires for '@' file mentions. After Tab-accepting a directory in an '@' mention, the next level's completion list reappears automatically, matching the '/add-dir' continuous-Tab behavior.

* feat: show inline argument hints for slash commands

Render a dim ghost-text argument hint inside the input box after a slash command that takes arguments, replacing the popup-only hint that was easy to miss. The hint appears once the command is typed and disappears as soon as an argument is entered, and is truncated to fit the box width. Add argument hints for /compact, /swarm, /goal and /title; /add-dir already had one.

* test: remove stale additional-dirs AGENTS.md assertion

The subagent-host test still asserted that an additional directory's AGENTS.md content appears in the agent system prompt, but additional-dirs AGENTS.md has been intentionally excluded from the default context since an earlier commit (covered by context.test.ts). Drop the stale assertion.

* fix: resolve /add-dir paths against workdir and persist via kaos

Resolve user-supplied /add-dir paths against the current workdir instead of the project root, so launching from a subdirectory behaves like the CLI --add-dir flag. Also route the local.toml read/write through the kaos abstraction instead of host fs, so the remember path works for non-local sessions.

* fix: expand ~ in /add-dir paths before resolving

The /add-dir completer emits ~/... values, but the core treated ~/foo as a relative path because pathe isAbsolute('~/foo') is false, producing <workDir>/~/foo. Expand ~ and ~/ to the home directory (via kaos.gethome()) before resolving.

* chore: remove add-dir dev docs from the branch

These were working notes (research and follow-up todos) that don't belong in the PR.

* chore: clarify add-dir changeset for users

* docs: document /add-dir, --add-dir, and local.toml

* test: flush records before reading wire in add-dir runtime tests

FileSystemAgentRecordPersistence.append buffers records and flushes asynchronously, so readMainWire can read the wire before the local-command-stdout record lands. Flush the main agent's records explicitly in the two add-dir runtime tests to make them deterministic.
2026-06-22 19:42:13 +08:00
7Sageer
d434d8f0d8
refactor(agent-core): unify image extension sniff-failed detection (#974)
Merge the two duplicate image-extension guards in detectFileType into a single mode-independent rule: an image extension without confirming magic is not an image in any mode. The video extension fallback stays before the NUL check so video containers with no magic still win. No behavior change.

Add and align tests: Read rejects an image-extension file with non-image bytes as not readable instead of redirecting to ReadMediaFile; file-type asserts the sniff-failed image case in both media and text modes.
2026-06-22 19:31:48 +08:00
7Sageer
27300797f2
fix(agent-core): reject image extensions whose bytes fail to sniff (#970)
When ReadMediaFile reads a file whose bytes have no recognisable image magic (for example a `.png` that is actually plain text), detectFileType previously fell back to the extension MIME type and built a data URL whose bytes did not match the declared format, which the model API rejected.

Every image format the model accepts (PNG/JPEG/GIF/WebP) has a reliable magic signature, so a failed sniff means the bytes are not a supported image. Report such files as `unknown` so ReadMediaFile returns a clear error instead of a bad data URL. The extension fallback is kept for video containers with no magic signature (for example MPEG-PS `.mpg`); format acceptance beyond that is left to the provider.
2026-06-22 19:07:34 +08:00