Commit graph

358 commits

Author SHA1 Message Date
liruifengv
c569bab55d
fix: decouple workspace trust from runtime initialization (#4348)
* fix(kap-server): decouple workspace trust from runtime initialization

* fix: preserve workspace trust errors

* fix: emit workspace trust recovery changes

* fix: complete workspace trust recovery

* fix(agent-core-v2): reclaim session locks from zombie processes (#4320)

(cherry picked from commit 0a90e2e8a2)

* feat: let users take over a session lock left by an exited process (#4328)

* feat: let users take over a session lock left by an exited process

Session locks judged alive by mistake (a different hostname, pid reuse, or a failed process-state probe) blocked the session with no way out. Add a takeover path: the lock service evicts another process's lock, the SDK exposes Session.takeOverLock(), kap-server adds POST /api/v1/sessions/{id}:takeover, and the TUI offers Take over once a retry is still occupied. KIMI_CODE_SESSION_LOCK=0 turns the lock off for a process.

* fix(agent-core-v2): evict the lock directly on takeover

Takeover went through the reclaim marker, so a stale marker left by a crashed reclaimer on another host made takeover a silent no-op while the API reported success. Unlink the lock file directly instead.

* fix(agent-core-v2): surface takeover failures when the lock cannot be removed

Takeover swallowed unlink errors, so a lock file another user owns in a shared sticky directory was reported as taken over while the next retry stayed occupied. Ignore only ENOENT and let other errors reach the caller. Also fix the run gate test bootstrap stub typing.

* fix(tui): simplify the session takeover copy

* fix(tui): tie the takeover warning to the takeover action

* fix(tui): drop the holder line from the takeover dialog

* refactor(tui): move the session occupancy dialogs into a controller

(cherry picked from commit e7f1a99fc5)

* chore: sync web dist from code-app

code-app: 76483646b7c46a61bff868f1473535e0a32b473d

---------

Co-authored-by: 7Sageer <sag77r@hotmail.com>
2026-10-23 12:52:22 +08:00
liruifengv
3f80896a79
chore: merge release/2026-10-20 into release/2026-10-21 (#4294)
Some checks are pending
CI / release-workflow-tests (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Release / Release (push) Blocked by required conditions
Release / version (push) Waiting to run
Release / candidate (push) Waiting to run
Release / vscode (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Release / deploy-docs (push) Blocked by required conditions
* feat(kap-server): add remote control device deletion (#4192) (#4195)

* feat(kap-server): add remote control device deletion

* fix(kap-server): coordinate with the local tunnel before deleting this machine's device

Co-authored-by: liruifengv <liruifeng1024@gmail.com>

* ci: enable recoverable publishing for the October release (#4218)

* ci: publish core releases from isolated release branches

* ci: simplify release recovery to the CLI package

* ci: publish VS Code from approved release commits

* test: await release test registration for type-aware lint

* test: avoid assuming order of independent tower events

* ci: limit release migration to existing publishing flow

* chore: sync web dist from code-app (#4221)

* chore: sync web dist from code-app

code-app: f828bac439ab5b9266ff8387c2afb96ecfcb59ae

* ci: retrigger (flaky rpc-events teardown ENOTEMPTY)

---------

Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>

* ci: release packages (#4220)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat(tui): queue /compact behind the running turn (#4276)

* feat(tui): queue /compact behind the running turn

* docs: note /compact queueing while the agent is busy

* fix(tui): harden queued /compact edge cases

- keep /compact blocked while a compaction holds the turn (busy reason normalized to compacting)
- treat the first queued /compact as a FIFO barrier for Ctrl-S manual steer
- gate the failed-fire retry timer on the session actually going idle

* fix(tui): cover remaining /compact queue review edges

- advertise Ctrl-S in the queue pane only for items ahead of the compact barrier
- queue /compact when the awaited lazy session creation lands on a running turn
- document the auto-compaction skip for queued /compact in docs and the changeset

* fix(tui): guard queued /compact against concurrent compactions

- requeue without firing when another compaction already started (the SDK's begin() swallows this as a silent no-op; declared residual window needs the contract to expose the result)
- restore the input when a duplicate /compact is refused after lazy session creation

* fix(tui): render requeued /compact and mark it always available in docs

- request a render after restoring a compact item to the queue so it does not appear vanished during backoff
- the reference table's availability column now matches the queueing behavior (/compact is accepted during streaming and runs in order)

* fix(tui): steer messages ahead of a queued /compact automatically

The automatic (tower/WaitFor) steer batch now slices at the first queued /compact just like the manual path, so pre-barrier prompts still end a WaitFor promptly instead of being blocked by an unrelated compact item. Batches containing bash or skill items ahead of the barrier keep their existing all-or-nothing semantics.

* test(tui): drive the tower steer barrier case through the WaitFor event path

* chore: downgrade the /compact queue changeset to patch (#4279)

* feat: add cloud-gated model switch confirmation (#4286)

* feat(cli): add cloud-gated model switch confirmation dialog

* feat(server): expose named client_configs endpoint for cloud-controlled clients

* fix(server): keep broadcasting compaction events to transcript subscribers

* Revert "fix(server): keep broadcasting compaction events to transcript subscribers"

This reverts commit e489915bd8bf753033f982ce1b0845cea64c0784.

* fix(cli): address review findings on the model switch confirmation

* test(cli): fix the auth-flow gate test typing

* fix: close the login-path holes in the model switch gate

- install the refreshed model catalog before matching the cloud rule,
  so an alias introduced by /login no longer bypasses the confirmation
- return 'gated' from refreshConfigAfterLogin and forward the picked
  effort to the dialog; setDefaultModel skips its follow-up activation
  while the gate owns the switch
- ignore Escape once a dialog action was chosen so the input lock
  survives the new-session creation

* fix: keep displaced panels alive when the new-session switch settles

The async finalizer of a settled dialog action now only restores the
editor while the model-switch dialog still owns the editor replacement,
so an approval or question panel mounted over it is never wiped out
with its reverse-RPC request still pending.

* feat: support id lists and always-fresh model switch confirmation configs (#4292)

* feat: accept id lists in model switch confirmation rules

* feat: fetch client configs fresh on every request

The /client_configs endpoint now proxies the cloud per request instead
of serving a copy cached at server startup, so config changes take
effect without a server restart. The startup warm-up and the in-memory
store are removed; region is resolved per request.

---------

Co-authored-by: qer <wbxl2000@outlook.com>
Co-authored-by: Kimi Agent <zhangkaiyi@moonshot.ai>
Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-20 19:35:17 +08:00
qer
83c7909be9
revert: remove default workspace session creation (#4295) 2026-10-20 19:13:48 +08:00
7Sageer
df0ff3c549 feat(agent-core-v2): add cross-process session occupancy lock (#4246)
* feat(agent-core-v2): add cross-process session occupancy lock

Multiple clients (TUI / kap-server / VS Code / ACP) running core in
separate processes could open the same session and corrupt each
other's wire.jsonl and metadata. Each session now holds a cross-process
occupancy lock ({homeDir}/locks/sessions/{id}.lock) taken only while
writing: runs acquire it on submit / compact / undo / cron / delete /
fork / cold-archive, the append log holds it before flushing, and a
stale check compares the main agent wire's on-disk length with the
length this process knows.

Collisions surface as session.occupied (holder in details); writes by
another client detected after acquire surface as session.stale and the
caller reloads before continuing. kap-server maps them to
SESSION_OCCUPIED (40903) / SESSION_STALE (40930), reloads the session
on stale, and re-attaches WS subscriptions; the TUI shows an occupancy
dialog (retry/cancel) or reloads and replays history keeping the input;
print exits with code 4 on occupied and reloads automatically on stale;
VS Code / ACP get minimal occupancy notices. Locks are released a few
seconds after the session goes idle, on close, and on process exit;
locking I/O failures degrade to unlocked operation with a warning.

* docs: document session occupancy error codes and lock directory

* fix: address codex review on session occupancy lock

- metadata: re-read state.json on the first write of each lock-hold
  epoch (holdToken), so pure-metadata changes made by another client
  (title, archive) are not clobbered by turn-end lastPrompt writes
- lifecycle: hold an explicit lease across live archive(), matching
  delete(), so the idle release timer cannot drop the lock mid-teardown
- tui: route the occupied dialog's Cancel selection through the same
  cleanup as Esc (restore input, release recalled media)
- acp: tell stale-session users to close and reopen the session
- append-log: warn when retirement drops records kept in memory because
  the session lock was unavailable

* fix: always run the staleness check in beginSessionRun

The prompt channels (AgentPromptChannel.submit/submitSteer, kap
/prompts, promptWithSkills) write prompt metadata before calling
loop.submit, and the metadata write acquires the session lock first.
beginSessionRun then short-circuited on 'already held' and skipped the
wire-length staleness check, so the main prompt path never detected
updates written by another client. Drop the already-held shortcut: the
check is a single stat and always passes while the lock is continuously
held, so every acquisition path now runs it regardless of order.

* fix(print): preserve occupied handling on the stale retry

If another client acquires the session between the reload and the
retry, the retried turn now goes through the same conflict handler:
session.occupied reports to stderr / stream-json and exits with code 4
instead of bubbling out as exit code 1.

* fix: do not mistake own in-flight writes for external modification

storage.append grows the file (writeFile) before fsync/close complete,
and knownLength only catches up afterwards; a beginSessionRun landing
in that window (steer, queued prompts, cron fires during a turn) was
misjudged as session.stale and deleted the lock file mid-turn. Track
in-flight bytes per log and compare disk against known + in-flight.
Cover the analogous rewrite window (post-rename syncDir) with an
expected-final-length marker.

* fix: bound the staleness comparison and check once per lock hold

The equality check disk !== known + inFlight moved the false-positive
window to before the append lands (mkdir/open) and into chunked
writes, so beginSessionRun during a turn (steer, cron, queued prompts)
could misjudge, delete the lock file mid-turn, and later append behind
another client. Compare known <= disk <= known + inFlight instead, and
evaluate the check only on a fresh hold (holdToken epoch): re-entrant
runs pass through without a stat, matching the RFC's 'already held
passes through' while every acquisition path still triggers the check
exactly once per hold.

Also unify the occupancy prompt copy across clients: the engine error
message is now the single user-facing text ('该会话正在被其他 Kimi
Code 进程使用;请停止其他进程中的会话或退出该进程后重试'), and the
TUI dialog, /compact /undo errors, print output, and the VS Code
fallback all display it instead of maintaining their own wordings.

* fix: address third-round codex review

- metadata: hold an explicit lease across each state.json write so the
  idle release timer cannot unlink the lock mid-write
- print: preflight the session lock before goal creation; make goal
  creation idempotent and emit the goal summary only for attempts that
  did not fail with session.stale, so a stale reload + retry neither
  duplicates the goal nor the summary
- tui: route every prompt-launch path (plain, goal steer, plugin
  command, inline skill, batch steer) through one conflict handler
  with the occupied dialog and stale reload + input restore
- tui: snapshot and restore the attachment store across stale reloads
  so pasted media placeholders still resolve after history replay

* fix: move session occupancy to a fresh error code, use English copy, release locks on exit

SESSION_OCCUPIED reused 40903, which belonged to PROMPT_ALREADY_COMPLETED until #3747 retired it, and web clients still allowlist 40903 for that old meaning; reusing it conflated the two semantics. Move session occupancy to the never-used 40931 and update the server API reference in both locales.

The occupied error message was hardcoded in Chinese while every other engine error is English, so the TUI, print mode, VS Code, and ACP clients all rendered mixed-language output; replace it with an English equivalent.

The lock release hook ran on 'beforeExit', which never fires when the process leaves through process.exit (SIGHUP in the TUI goes through emergencyTerminalExit), leaving stale lock files that could keep a session looking occupied forever after a hostname change or pid reuse. releaseAll is fully synchronous, so hook 'exit' instead.

* fix(agent-core-v2): decide prompt-derived titles after re-reading session metadata

applyPromptMetadataUpdate decided whether to derive a title from the
prompt from the in-memory metadata cache, which is only refreshed when
the session lock is re-acquired. If another client named the session in
the meantime, the stale cache still looked untitled, so the next prompt
from this client overwrote the other client's title — both on the stale
path, where the prompt is rejected afterwards, and on the fresh path,
where the other client only changed the title on disk.

Move the untitled check into SessionMetadata.applyPromptMetadata, which
runs after ensureWriteOwnership() has re-read state.json, so the
decision is based on the latest persisted metadata. The published
SessionMetaUpdated event now carries the derived title only when it was
actually written.

* fix: address fourth-round codex review

- vscode: classify session.occupied and session.stale as preflight errors so the webview toasts them instead of silently swallowing the send, and give session.occupied the same English copy the engine emits (the toast text comes from getUserMessage in the extension host).
- engine: beginSessionRun now takes the session context and agent lifecycle service, and on the first check of each lock hold it runs externallyModified over every loaded agent's wire (scope agents/<agentId>, key wire.jsonl) instead of only the main agent's, so a fork that only touched a subagent journal is detected as stale. All four call sites (loop submit, manual compaction begin, undo, print preflight) pass the extra dependency.
- tui: keep the request in flight across a stale reload instead of dropping to idle, so input submitted during the reload queues rather than racing the closing session; park the queue around switchToSession (resetSessionRuntime would clear it) and drain it into the reloaded session afterwards; when restoring the rejected text, prepend it before content the user typed during the reload instead of overwriting it.
- kap-server: clear the in-flight turn tracker and subagent roster in detachSession so a reattached session no longer reports stale in-flight turns or running subagents in REST snapshots and WS resyncs.

* fix: harden session conflict recovery

Detect external appends that race journal reads so a later run cannot miss session.stale. Keep deferred wire migrations pending and finish them before appending, while rejecting the append if migration still cannot complete. Restore the complete plugin command after an occupied cancellation, including commands without arguments.

* fix: scope session staleness cache to session context

Replace the process-global session-id map with a WeakMap keyed by ISessionContext so closed and reloaded sessions do not retain cache entries for the lifetime of the process.

* fix: document session conflicts for metadata routes

Declare SESSION_OCCUPIED and SESSION_STALE in the response schemas for profile updates, title generation, and child creation. Cover the OpenAPI declarations and the existing HTTP 200 conflict envelopes with regression tests.

* refactor: centralize session conflict handling

Move session error mapping and stale reloads into one shared route helper, reuse shared conflict response declarations, and cover skill activation conflicts. Remove the duplicate prompt, session, and skill error mappers while preserving their existing envelopes.

* fix(sdk): restate session conflict errors

* fix(tui): keep the reloaded session open and resend after a stale conflict

* fix(agent-core-v2): lazily rebuild registered agents after a session reload

* refactor: simplify session conflict handling

* refactor: hygiene fixes from session-lock review

- kap-server: move SESSION_STALE to 40932 (collided with
  DEFAULT_WORKSPACE_UNAVAILABLE at 40930) and pin ErrorCode value
  uniqueness with a test
- node-sdk: fold six catch-and-restate copies into a restate() helper
- acp-server: sync mapPromptLaunchError docstring with the
  occupied/stale branches
- replace hardcoded session.stale/session.occupied literals with
  ErrorCodes constants
- inline the single-use sessionStaleError
- restore the strict timer-leak assertion with a warmup baseline
  instead of a blanket +1 allowance
- narrow SessionState.detached to ?: true

* refactor: introduce session-level run gate

- replace the beginSessionRun free function with ISessionRunGate, a
  Session-scoped service; loop/compaction/undo now inject one
  dependency instead of four, and sessionLock.ts no longer imports
  session-layer modules
- tryHold() absorbs the duplicated try/catch hold copies in
  wireService and sessionMetadataService
- resolve IAgentLifecycleService lazily inside the gate to avoid a
  construction-time cycle with agentLifecycleService

* refactor: tighten session lock and conflict recovery structure

- Narrow ISessionLockService to hold/tryHold/release/lease/held and share
  the hold bookkeeping between the memory and node-fs backends; drop
  holdToken and the module-level exit hook state.
- Session metadata refreshes on a new hold via onDidHold and skips agent
  registration through tryHold instead of catching session.occupied.
- AppendLogStore reads sizes through IFileSystemStorageService.sizeSync and
  exposes a generic write guard instead of a session-lock binding.
- kap: reload stale sessions only at the call sites that can raise
  session.stale and log reload failures; error mapping stays side-effect free.
- TUI: recover from a stale conflict through the in-place session reload with
  history replay, removing the same-session switch special case, the media
  store snapshot, and the queue parking.
- print: bound stale reloads with a simple retry loop.

* refactor(agent-core-v2): merge session lock release into run gate

* test(agent-core-v2): reuse append log fixtures

* refactor(agent-core-v2): break run gate and agent lifecycle dependency cycle

* refactor: reload stale sessions in core instead of each host

Stale detection already lived in core, but every host re-implemented the
recovery: TUI, print, and kap each closed and resumed the session, and TUI
and web resent the rejected input themselves.

Core now exposes reloadOnStale: on session.stale it closes and resumes the
session, lets the caller refresh, then retries the call once (undo reloads
and still rejects, since its count depends on what the user saw).

- kap: prompt submit, skill activation, and compact retry in place instead
  of returning 40932; undo still returns 40932 after reloading
- print: retries through reloadOnStale on the same session id and keeps the
  original permission mode to restore
- SDK: run-starting calls reload and retry internally; Session gains
  setStaleReloadHandler so hosts refresh before the retry
- TUI: drops its own reload/resend/queue-merge path; the stale handler
  replays history and keeps in-flight messages

* docs(server-api): note that only undo returns 40932 after a stale reload

* refactor(agent-core-v2): ask each agent's wire whether it was modified externally

* refactor(agent-core-v2): clarify agent restoration helper name

* Delete .changeset/ensure-agent-lazy-rebuild.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* fix(tui): wrap session occupied notice

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-10-20 17:38:33 +08:00
grapedge
ce0834a8f3
feat: share session rating rules across CLI and server (#4272) 2026-10-20 14:20:55 +08:00
qer
e5e56bc5fe
feat(server): place the default workspace under the home folder (#4277)
Some checks are pending
CI / release-workflow-tests (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
The default workspace lived in <Documents>/KimiCode/Default. On macOS the
first chat there triggered a Documents privacy prompt, and a denial blocked
every later chat until the user found the setting. Documents is also synced
by iCloud and OneDrive, and covered by Windows Controlled Folder Access.

Use ~/KimiCode/Default on every platform instead. This drops the Windows
PowerShell lookup, the XDG user-dirs parsing, and the documents_unavailable
reason; the error path is now always present.
2026-10-19 16:13:43 +08:00
qer
47002256a0
feat: add a default workspace for chats without a project (#4224)
* feat(server): create sessions in a default workspace when none is chosen

POST /api/v1/sessions accepts default_workspace: true, exclusive with
workspace_id and metadata.cwd. The server resolves <Documents>/KimiCode/Default
on every request, creates it on first use, and reuses it afterwards. A path
blocked by a file fails with 40409 and a permission error with 40411; the
server never relocates silently.

Workspace payloads on REST and WebSocket events carry is_default.

* fix(server): fail instead of relocating when Windows Documents cannot be resolved

A failed registry lookup used to fall back to %USERPROFILE%\Documents, which
could silently create a second default workspace when Documents is redirected
(for example by OneDrive). The lookup now fails with 40409, the failure is not
cached so the next request retries, and is_default reports false meanwhile.

* fix(server): resolve Windows Documents through the shell folder API

Reading User Shell Folders with reg.exe misses the default when the value is
absent, cannot expand every variable, and is blocked where registry tools are
disabled by policy. Ask Windows for the Documents folder through PowerShell
instead, forcing UTF-8 output so non-ASCII paths survive. A reported folder
that does not exist is treated as unresolved, so garbled output can never
create a workspace in the wrong place.

* test(server): assert the existing error code for a missing Windows Documents folder

* fix(server): start Windows PowerShell by absolute path

The Documents lookup spawned the bare name powershell.exe, so Windows
resolved it through the current directory and PATH. In an untrusted
checkout that lets a repository-provided powershell.exe run before the
trust gate. Resolve it under SystemRoot (falling back to windir and
then C:\Windows) instead.

* feat(server): report an unusable default workspace with its path and reason

Creating a session in the default workspace used to surface folder problems
as generic codes: 40409 when a file blocked the path or the Windows
Documents folder could not be located, 40411 on permission errors, and a
plain internal error for anything else. Clients could not tell the default
workspace apart from an ordinary missing directory, nor explain what to fix.

DefaultWorkspaceService now throws DefaultWorkspaceUnavailableError
(default_workspace.unavailable) carrying the folder path and one of
blocked_by_file, permission_denied, missing_parent, no_space, read_only,
invalid_path, documents_unavailable or unknown. ensure() also verifies that
a file can be created and removed in the folder, so a read-only folder is
reported before a session is placed there. The server maps the error to
40930 with { path, reason } in data.

* feat(server): make the default workspace location configurable

The default workspace was fixed at <Documents>/KimiCode/Default. Users who
keep chats on another disk, or whose Documents folder is synced, had no way
to move it.

Add a default_workspace.path setting in config.toml. It accepts an absolute
path or ~/..., and on Windows only a drive path or a full UNC share; the
value is checked for writability before it is saved and is never moved
silently. An invalid value in the file is reported as invalid_path instead
of falling back to the system location.

The server exposes GET and PATCH /api/v1/default-workspace with the
effective path, the saved custom path, the system path and the folder's
health. The section is kept out of GET /api/v1/config and rejected by
POST /api/v1/config so it has a single writer. Whenever the location
changes, through PATCH or an edit to config.toml, every registered
workspace broadcasts event.workspace.updated with its current is_default.

* feat(cli): add --default-workspace and expose the default workspace in the SDK

Add kimi --default-workspace to work in the shared default workspace instead
of the current directory. Both the interactive shell and print mode resolve
the folder through the engine before the session starts and change into it,
keeping PWD in sync; when the folder cannot be used, startup fails with its
path and reason. Resume hints become kimi --default-workspace -r <id> for
such sessions.

The session picker labels sessions in the default workspace as "Default
workspace" and copies a resume command without a cd for them. kimi doctor
reports the location and whether it can be used. The stty lookup excludes
both the launch directory and the new working directory, so a binary
planted in either is never executed.

The SDK gains KimiHarness.ensureDefaultWorkspace(), getDefaultWorkspacePath()
and getDefaultWorkspaceStatus(), maps default_workspace.unavailable to a
KimiError, and exports workspaceRootKey and DEFAULT_WORKSPACE_PROBLEM_MESSAGES.

* fix(server): never remove a write probe the check did not create

createExclusive resolves to false when the probe name already exists. The
write check ignored that result and went on to remove the path, which is a
recursive delete of an entry it did not create. Report the folder as
unknown instead and leave the entry alone.

* fix(server): declare 40001 on PATCH /default-workspace and log failed broadcasts

The PATCH route returns 40001 when the body fails validation, but its
OpenAPI response union only listed success and 40930, so generated clients
could not model it.

When the default workspace location changed but the workspace catalog
could not be read, the publisher dropped the broadcast without a trace.
Log a warning so the missing event.workspace.updated can be diagnosed.

* fix(cli): point the resume hint at the session folder after the default moves

A session started with --default-workspace printed
kimi --default-workspace -r <id> on exit even if default_workspace.path
changed while it was open. Following that hint moved into the new default
folder and refused the session, which still lives in the old one.

Repeat the flag only while the session folder is still the default
workspace; otherwise print cd <folder> && kimi -r <id>.

* refactor: trim the default workspace to what clients use

Keep session creation in the default workspace, the configurable
location, the 40930 error with its reason, and `kimi --default-workspace`.

Remove what no client needs:
- write probes, ancestor walks, and dangling-link checks; saving a
  location now creates the folder, and use-time errors come from mkdir
- `system_path` and `problem` in the status response
- the workspace-update publisher; clients refetch workspaces after PATCH
- special handling of `default_workspace` in GET/POST /config
- the stray FS_PERMISSION_DENIED mapping on session routes
- the session picker label, the doctor check, the extra stty exclusion,
  the moved-default resume hint, and the SDK path/status methods

Fix three gaps found along the way:
- clearing the location left `path` in config.toml, so it came back on
  reload; drop the section instead
- treat an empty or relative XDG_CONFIG_HOME as unset
- honor HostProcessOptions.timeout so a stalled PowerShell lookup ends

* refactor: drop the --default-workspace CLI flag

No CLI user needs it yet. Desktop and web reach the default workspace
through the server, so the flag, its resume hint, and the SDK's
ensureDefaultWorkspace() go away along with their changesets.

* refactor: drop the default workspace settings endpoint

The location is now changed only by editing default_workspace.path in
config.toml, which the config watcher picks up without a restart. Remove
GET/PATCH /api/v1/default-workspace and the engine's status() and
setCustomPath(). Session creation keeps mapping the unavailable error to
40930 with { path, reason }, and the reason list moves to the
POST /sessions docs.

* fix: require a drive or UNC share for a Windows default workspace path

Rooted paths such as \Chats resolve against the server's current drive,
so the same setting could point at different folders. Treat them as
invalid_path instead.
2026-10-19 12:29:51 +08:00
liruifengv
18c6d64272
feat: notify the agent of external changes after /reload (#4019)
Some checks failed
CI / release-workflow-tests (push) Has been cancelled
CI / build (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test (5) (push) Has been cancelled
CI / test-pi-tui (push) Has been cancelled
CI / test-vscode-legacy (push) Has been cancelled
CI / test-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
Nix Build / Check flake.nix workspace sync (push) Has been cancelled
Nix Build / nix build .#kimi-code (push) Has been cancelled
* feat: notify the agent of external changes after /reload

* refactor: route watch-based AGENTS.md change alerts through the change notifier

* test: pin the missed detection of trailing AGENTS.md content deletions

* fix(agent-core-v2): anchor change-notifier comparisons to delivered beliefs

* fix(agent-core-v2): diff the full subagent model pool in change notifications

* fix(agent-core-v2): mute stale-session auto notifications during session reload

* chore(agent-core-v2): regenerate manifests and complete notifier stubs for the reload fixes

* chore: update the reload-change-reminders changeset

* test(agent-core-v2): cover the announced-then-deleted AGENTS.md sequence

* fix(vis): cover the changeNotifier.snapshot wire record

* fix(agent-core-v2): harden change-notifier beliefs for legacy wires and edge baselines

* fix(agent-core-v2): unmute the stale notifier when a session reload fails midway

* fix(agent-core-v2): seed change-notifier beliefs from the rendered snapshot

* fix(agent-core-v2): await the change-notifier snapshot dispatch

* fix(vis): harden the change-notifier snapshot renderer for legacy records

* test: isolate the reload e2e from the watch channel and tighten seed assertions

* chore(agent-core-v2): regenerate the wire manifest for optional belief fields

* chore: drop the changeset for reload change reminders

* fix(agent-core-v2): diff reload reminders against persisted beliefs first

* fix(agent-core-v2): recompute the bound subagent allowlist on catalog changes

* fix(agent-core-v2): roll back change-notifier beliefs on conversation undo

* feat(agent-core-v2): inline added profile metadata in subagent change reminders

* fix(agent-core-v2): detect legacy AGENTS.md truncation and gate skill reminders

* fix(agent-core-v2): reset change-notifier beliefs on context clear

* feat(kap-server): project the reload session action into the OpenAPI document

* fix(node-sdk): keep plugin-only reloads from refreshing workspace catalogs

* fix(agent-core-v2): gate and filter subagent change reminders

* fix(agent-core-v2): evaluate reminder gates against the persisted binding

* fix(kap-server): scope reload catalog refreshes to the target workspace

* fix(node-sdk): scope reload catalog refreshes to the target workspace

* fix(agent-core-v2): reset change-notifier beliefs on compaction

* fix(agent-core-v2): hash AGENTS.md files from one atomic snapshot

* fix(agent-core-v2): close first-watch and legacy gaps in change detection

* fix(kap-server): block reload during compaction and reconcile after failed reload

* fix(node-sdk): block reload during compaction and reconcile after failed reload
2026-10-16 15:15:57 +08:00
Haozhe
6e7cc909da
feat(agent-core-v2): let dangerous_command_guard=false disable all built-in guard ask policies (#4250)
* feat(agent-core-v2): let dangerous_command_guard=false disable all built-in guard ask policies

* docs(agent-core-v2): name git control-path read relaxation and scope the only-ask-rules claim
2026-10-16 13:23:18 +08:00
Rick
034117338c
fix(vscode): add back navigation when AskUserQuestion (#4186) 2026-10-15 16:27:13 +08:00
7Sageer
5bab748ddd
feat(tui): auto-generate session title after the first turn (#4200)
* feat(tui): auto-generate session title after the first turn

* Update tui-auto-session-title.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* feat(tui): gate auto session title behind a tui.toml auto_session_title toggle

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-10-15 15:31:02 +08:00
tpoisonooo
60adab4c32
docs(tower): add description (#4216)
* docs: add Tower user guide

* docs: clarify Tower benefits and dependency gates

* docs(tower): add guides

* fix(docs): accept review advices

* docs(tower): remove keep_alive_on_exit

---------

Co-authored-by: konghuanjun <konghuanjun@moonshot.ai>
2026-10-15 12:56:05 +08:00
Kimi Agent
d4b9dc4a2d
docs(changelog): sync 2.2.0 from apps/kimi-code/CHANGELOG.md (#4223)
Some checks are pending
CI / test-vscode-legacy (push) Waiting to run
CI / release-workflow-tests (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-windows (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
* docs(changelog): sync 2.2.0 from apps/kimi-code/CHANGELOG.md

* docs(changelog): restore notify_user feature entry and document fullscreen enablement

* docs(changelog): simplify notify_user enablement to /experiments panel

* docs(changelog): drop non-public KIMI_CODE_TRUST_WORKSPACE entry

* docs(changelog): drop one-line title from notify_user entry

---------

Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>
2026-10-15 00:15:53 +08:00
Haozhe
f28c51c01f
feat(agent-core-v2): add global default for deferred MCP tool disclosure (#4210)
* feat(agent-core-v2): add global default for deferred MCP tool disclosure

* feat(agent-core-v2): capture the deferred MCP default at server connect time
2026-10-14 17:19:29 +08:00
7Sageer
0327e8e9a8
feat: support model migration metadata (#4171)
* feat: support model migration metadata

* chore: revert web bundle sync

* feat: persist model upgrade metadata

* fix: resolve model upgrade targets

* fix: keep model upgrade metadata consistent

* fix: complete model upgrade metadata handling

* fix: handle aliased upgrade targets and RFC3339 variants

* fix: resolve bare model upgrade targets

* feat: prompt for model migration in the TUI

* fix(tui): defer model migration until the editor is idle

* fix(tui): preserve model migration prompts and preferences

* fix(tui): hold the model migration prompt while /new replaces the session

* fix(tui): keep the resume cache hint from replacing an open dialog

* fix(tui): keep the thinking effort across a model migration when supported

* fix(tui): strip terminal control sequences from migration notices

* fix(tui): warn about prompt cache loss before a mid-conversation migration

* docs: drop the effort persistence claim from the migration wording

* test: trim redundant migration test cases

* fix: switch to the declared replacement when a registry drops the default model

A registry retires a model by dropping it after declaring `upgrade`, but
the refresh deleted the alias together with its upgrade metadata and
cleared the default, leaving users without a model and with a misleading
login hint. Refresh and re-import now move a dropped default to the
upgrade target persisted by an earlier refresh, clearing it as before
when that target is gone too. The TUI warns about the switch and moves
the live session off the dropped model once no dialog is open.

* docs: fix the /reload-tui command spelling in config-files

* fix: resolve migration placeholders at import and keep acknowledgements out of tui.toml

Migration text placeholders were only filled in by the TUI, so the model
catalog served raw templates to every other client. The registry import
now stores the final text and the TUI renders it as is.

Migration acknowledgements are display state rather than preferences, so
they now live in model-migrations.json under the data directory instead of
tui.toml; preference saves and acknowledgements no longer rewrite each
other, and /reload has nothing to sync.

Also carry the dropped model's record in the refresh result instead of
snapshotting it in the TUI, give performModelSwitch explicit persistence
modes instead of a boolean-or-mode flag, fold the Markdown notice into the
picker's notice option, and rename waitForLazyCreation to
waitForSessionAssembly now that it also waits for /new.

* refactor(tui): move the shared model switch out of the /model command

performModelSwitch and its helpers became shared once the migration
prompt and the retired-default switch started calling them, yet they
stayed in the /model command module, leaving a controller depending on
command internals. Move them unchanged to tui/utils/model-switch.ts, which
the command module and the migration controller now both import.

* feat: surface retired default model redirects in refresh results and catalog events

A registry-side retirement only existed in the OAuth orchestrator's
in-process RefreshResult, so kap-server's scheduled refreshes redirected
the default model without any client-visible signal. The refresh response
now carries an optional retired_default { from, to, from_model }, mapped
through to the REST refresh endpoints and the global
event.model_catalog.changed broadcast, and mirrored in the klient
contract.

* refactor(tui): consume the engine's provider refresh instead of orchestrating its own

The TUI ran the OAuth refresh orchestrator in-process through its own
persistence host (including a dead v1 fallback), duplicating what the
engine's discovery service already does. KimiHarness now exposes
refreshProviderModels (via the klient facade over
IProviderDiscoveryService), so the TUI deletes its orchestration glue and
reads retired_default from the engine response. Also fix the klient
facade deriving RefreshProviderModelsResponse from the OAuth login
refresh, which hid retired_default from clients.

* feat: move model retirement follow-through into the engine

The discovery service now records retirements, emits onDidRetireModel,
and answers retiredModelReplacement; agent profiles follow a retirement
live and on restore, so the TUI only shows the notice and steers the
session-less selection. The wire retired_default drops from_model in
favor of an engine-resolved from_display_name. Removes the now-dead
supportsAtomicSectionReplace / replaceConfigSections /
removeProviderFromConfig SDK exports (no remaining consumers).

* Update model migration guidance in documentation

Prompt for migration when the TUI editor is idle and switch to the declared replacement when a registry drops the default model.

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* test(oauth): drop the duplicate dropped-default redirect case

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-10-14 14:24:01 +08:00
liruifengv
b510fa9aec
feat(kap-server): add remote control device deletion (#4192)
Some checks failed
CI / build (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test (5) (push) Has been cancelled
CI / test-pi-tui (push) Has been cancelled
CI / test-vscode-legacy (push) Has been cancelled
CI / test-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
Release / Release (push) Has been cancelled
Publish VS Code extension / Publish VSIX to marketplaces (push) Has been cancelled
CI / typecheck (push) Has been cancelled
Nix Build / Check flake.nix workspace sync (push) Has been cancelled
Release / Deploy docs (push) Has been cancelled
Release / Native release artifact (push) Has been cancelled
Nix Build / nix build .#kimi-code (push) Has been cancelled
Release / Publish native release assets (push) Has been cancelled
* feat(kap-server): add remote control device deletion

* fix(kap-server): coordinate with the local tunnel before deleting this machine's device
2026-10-13 19:58:01 +08:00
oocz
3f0857eb7d
feat(agent-core-v2): register plugin skills under qualified names and relax plugin name validation (#4188)
* feat(agent-core-v2): register plugin skills under qualified names and relax plugin name validation

* docs: document qualified plugin skill names and relaxed plugin name validation

* fix(tui): prefer plugin commands over same-named plugin skill shorthand

---------

Co-authored-by: yuchengzhen <yuchengzhen@moonshot.cn>
2026-10-13 19:41:48 +08:00
liruifengv
c69bd6c5a0
feat(kap-server): add remote control device management (#4169)
* feat(kap-server): add remote control device management

* feat(remote-control): tag share URLs with the caller's platform source

The share link's from query parameter was hardcoded to kimi_code_cli, so
links created by the desktop app were mislabeled as CLI traffic.

buildRemoteControlUrl now takes the source explicitly and
RemoteControlOptions carries it as urlSource; kap-server threads
hostIdentity.platform through, so desktop hosts produce
from=kimi_code_desktop while CLI hosts keep from=kimi_code_cli.

* fix(kap-server): stop the local tunnel when the current device is deactivated or deleted

The device management routes only called the cloud API. When the target
device is the machine itself, the local tunnel kept running: after the
relay drops it, the client reconnects and re-registers, so the device
came back online (or was recreated after a delete) and the local status
never returned to off.

After a successful cloud deactivate/delete of the current device, the
routes now also disable the local tunnel manager.

* feat(kap-server)!: drop the remote-control device delete route

Device removal is collapsed to a single deactivate verb: the desktop UI
deactivates devices instead of deleting them, so the DELETE
/remote-control/devices/{id} route and the device client's deleteDevice
go away before this API ever ships.

* feat(kap-server): carry the lock holder in the already-running error

The enable route now returns the RemoteControlAlreadyRunningError holder
(pid, local origin, device id, url, started_at) in the error envelope's
details, documented with a details schema, so desktop can render a
structured conflict state instead of the raw message.

* feat(kap-server): expose the lock conflict in the remote control status

The manager now surfaces the holder when its last enable error is an
already-running lock conflict, and GET /remote-control returns it as a
structured conflict field, so clients can present the conflict state
proactively instead of parsing the error message.

* feat(kap-server): resolve the remote control lock conflict live in status

GET /remote-control now re-inspects the machine lock whenever the
manager is off: a live holder is reported as the conflict even without
a prior enable attempt in this process, and a stored conflict plus its
error text are dropped once the holder's process is gone. Panel state
refreshes such as after device deactivation now reflect reality.

* feat(kap-server): wait for the lock holder to release on current-device deactivation

When the deactivated device is the machine's own and the lock is held
by another live process (e.g. a CLI instance whose tunnel the relay is
about to terminate with user_requested), the route now polls the lock
for up to two seconds before responding, so a client's immediately
following status read sees the settled conflict-free state.

* style(kap-server): silence promise-executor-return in lock release wait

* test(remote-control): pass urlSource in the close-reason cases

* feat(kap-server)!: register remote control devices with the host product name

* refactor(cli): source the remote control identity from app constants

* fix(remote-control): make starts cancellable and harden logout cleanup

* fix(remote-control): close the remaining cancellation and invalidation races

* fix(kap-server): sweep remote control cleanup once more after logout

* docs: note the lock-release failure of remote control deactivation

* fix(remote-control): key cloud sessions by credential and settle cancelled starts

* fix(kap-server): block remote control starts during logout and serialize tunnel toggles

* fix(kap-server): gate local starts during current-device deactivation

* fix(kap-server): match active tunnel ids on deactivation and re-clear sessions after logout

* fix(kap-server): serialize Kimi logouts, harden lock cleanup, and whitelist device fields

* fix(remote-control): abort pending handshakes on close and answer logout before tunnel teardown

* fix(remote-control): cancel enables that are still queued behind a pending disable

* fix(kap-server): recognize foreign logout gates and retry post-logout tunnel teardown

* fix(remote-control): verify the machine lock after disable and recheck deactivation

* feat(kap-server): export loadOrCreateServerToken for host token provisioning
2026-10-13 17:40:24 +08:00
grapedge
afd95f64a5
feat(tui): unify skill prompts and steering (#4165) 2026-10-13 12:17:14 +08:00
Kai
0a3a2fbafa
feat: add NotifyUser progress display to desktop and web (#4159)
* feat: show NotifyUser progress in desktop and web

Give NotifyUser a one-line title, report the latest update on the
session status, and forward subagent updates to the parent so GUI
clients can show them on subagent cards.

* feat: turn on NotifyUser progress updates by default

Flip the notify_user flag default to true; the flag stays as the opt-out
(`[experimental] notify_user = false` or KIMI_CODE_EXPERIMENTAL_NOTIFY_USER=0).
Register the new subagent.update wire record in the vis renderers and
record-type union so the manifest coverage test passes.

* refactor: trim NotifyUser surfaces to conversation progress rows

* feat: make NotifyUser title optional and enforce single-line titles

* feat: make NotifyUser opt-in via the settings lab

* docs: describe NotifyUser as off by default with the settings lab opt-in
2026-10-12 17:01:36 +08:00
Haozhe
c151d5a3d0
feat(agent-core-v2): add KIMI_CODE_LLM_HEADERS_TIMEOUT_MS for llm headers timeout (#4092)
* feat(agent-core-v2): add KIMI_CODE_LLM_HEADERS_TIMEOUT_MS for llm headers timeout

* fix(agent-core-v2): harden KIMI_CODE_LLM_HEADERS_TIMEOUT_MS proxy fallback and range
2026-10-12 13:51:39 +08:00
qer
242ac23000
feat(cli): launch desktop with kimi app (#4145)
* feat(cli): launch desktop with kimi app

* fix(cli): report desktop opener failures and complete command tests

* fix(cli): resolve system openers from filesystem roots
2026-10-09 15:08:24 +08:00
liruifengv
5b93669767
feat(kap-server): add allow_ignored_globs to fs:list for un-ignoring named paths (#4058)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* feat(kap-server): add allow_ignored_globs to fs:list for un-ignoring named paths

The list filter keeps gitignored entries hidden unless they match the
new allow_ignored_globs request field, letting callers surface
specific ignored paths (e.g. .tmp) while the rest of gitignore still
applies.

* docs: document allow_ignored_globs in the fs:list API reference

* fix: traverse ignored ancestor directories of allow_ignored_globs matches

A nested allow glob such as ignored-dir/keep.txt or ignored-dir/** used
to be unreachable in recursive listings because the ignored parent was
skipped before any child could match. Keep an ignored entry when it is a
literal-prefix ancestor of an allowed glob (directories only), and
document that dot-path allowances additionally require show_hidden.

* fix: match ignored ancestor directories across wildcard glob segments

The literal-prefix check still dropped ancestors when a directory
segment of an allow glob contained a wildcard, e.g. ignored-*/keep.txt
or ignored-dir/**/keep.txt. Decide reachability by consuming the
candidate path segment-wise against a prefix of the glob instead.

* fix: correct and harden workspace fs glob matching

Compile **/ to (?:[^/]+/)* so recursive wildcards preserve path
segment boundaries; a/**/b no longer matches a/xxb. This affects
include_globs, exclude_globs, and allow_ignored_globs across
fs:list / fs:search / fs:suggest / fs:grep.

Match glob prefixes iteratively in globCanMatchBelow so deeply
segmented globs cannot exhaust the call stack.

* chore: add changesets for allow_ignored_globs and the glob boundary fix

* fix: satisfy noUncheckedIndexedAccess in the glob prefix grid

* fix: restrict globstar segment expansion to whole path segments

foo**/keep.txt regressed when **/ gained segment-boundary semantics:
the stars sat mid-segment but were expanded as a whole-segment
globstar. Only expand **/ when the stars open a path segment, treat
mid-segment stars as an ordinary within-segment wildcard, and keep a
trailing ** matching across segments as before.

* fix: match workspace fs globs with picomatch and probe speculative ancestors

Replace the hand-rolled glob compiler with picomatch, the standard
engine already used elsewhere in the package, which settles segment
boundary, mid-segment globstar, and deep-pattern complexity edge
cases for good. An ignored directory kept only as a possible ancestor
of an allow glob is now probed (depth and entry capped, fail-open) and
withheld when no descendant actually matches.

* fix: cast readonly glob list for picomatch isMatch

* fix: parse globs whole in the ancestor check and share the probe budget

Splitting allow globs on '/' corrupts brace and extglob constructs
that contain slashes; take path segments from picomatch.scan instead
and fall back to a conservative answer for opaque single-token globs,
letting the descendant probe decide visibility with whole-pattern
matching.

Probe budgets are now shared across one fs:list request instead of
resetting per candidate directory, so a tree full of speculative
ancestors cannot multiply filesystem operations.

* fix: tolerate empty globs and slash-bearing alternatives

picomatch throws on empty patterns where the old compiler simply
never matched, turning previously valid requests into server errors;
filter them out up front. Brace and extglob alternatives that embed
a slash inside one scanned part now fall back to the conservative
ancestor answer as well, leaving visibility to the whole-pattern
descendant probe.

* fix: disable picomatch negation in workspace fs globs

A leading exclamation mark was a literal character in the old
matcher, so exclude_globs like !foo only matched a path literally
named !foo; as a picomatch negation the same request would exclude
everything except foo. Pin the prior semantics with nonegate.

* fix: scan allowance globs with nonegate and skip empty segments

The scan call still used default negation, stripping a literal
leading bang from allowance prefixes like !foo/keep.txt. Consecutive
separators produced empty scanned segments that made picomatch throw
during prefix compilation; empty segments now simply match nothing.

---------

Co-authored-by: qer <wbxl2000@outlook.com>
2026-10-08 18:21:54 +08:00
Luyu Cheng
20a2cea72f
feat: cap WaitFor at 90s and let new input end the wait (#4061) 2026-09-29 18:52:09 +08:00
7Sageer
1f6f0b1fa2
feat: trust workspace via KIMI_CODE_TRUST_WORKSPACE env var (#4059)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* feat: trust workspace via KIMI_CODE_TRUST_WORKSPACE env var

* fix: honor trust env override in MCP registry and untrust route

* test: add getEnv to mcpManagement bootstrap mock

* test: fold trust-env route case into existing workspaces suite

* fix(cli): mention KIMI_CODE_TRUST_WORKSPACE in the print-mode MCP trust warning

* docs: describe KIMI_CODE_TRUST_WORKSPACE by its semantics, not its MCP effect
2026-09-28 17:03:52 +08:00
liruifengv
be7d5f5fea
docs(changelog): sync 2.1.1 from apps/kimi-code/CHANGELOG.md (#4018)
Some checks failed
CI / build (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test (5) (push) Has been cancelled
CI / test-pi-tui (push) Has been cancelled
CI / test-vscode-legacy (push) Has been cancelled
CI / test-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
Nix Build / Check flake.nix workspace sync (push) Has been cancelled
Release / Release (push) Has been cancelled
Publish VS Code extension / Publish VSIX to marketplaces (push) Has been cancelled
Nix Build / nix build .#kimi-code (push) Has been cancelled
Release / Deploy docs (push) Has been cancelled
Release / Native release artifact (push) Has been cancelled
Release / Publish native release assets (push) Has been cancelled
2026-09-24 15:47:04 +08:00
Haozhe
c7dd84124a
feat: turn filesystem watch back on by default (#4015) 2026-09-24 14:50:10 +08:00
7Sageer
929403b6db
revert: roll back workspace trust-boundary hardening (#4013)
* revert: roll back workspace trust-boundary hardening

Roll back the hardening added in #3964 that guarded against malicious
content inside an already-trusted repository:

- background git invocations no longer override repo-local git config
  (fsmonitor, hooksPath, filters, drivers, gpg, editor)
- agent file tools no longer re-resolve paths through symlinks
- project-local local.toml applies without workspace-trust gating,
  additional_dir entries are no longer rejected for resolving to the
  home directory or filesystem root, and writing it is auto-approved
  again inside a git worktree

Kept, since they only affect the pre-trust window or the trust prompt
itself: the fail-closed trust prompt and lazy footer git detection.

* Update revert-trust-boundary-hardening.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-09-24 14:49:36 +08:00
liruifengv
a1e4c13d41
docs(changelog): sync 2.1.0 from apps/kimi-code/CHANGELOG.md (#4006)
Some checks are pending
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (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 / Native release artifact (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* docs(changelog): sync 2.1.0 from apps/kimi-code/CHANGELOG.md

* docs(changelog): shorten the fullscreen TUI entry to how to enable it

* docs(changelog): reword the fullscreen TUI entry
2026-09-23 21:08:50 +08:00
grapedge
e17ff67928
feat(kimi-code): add TUI mode setting for fullscreen layout (#4004) 2026-09-23 20:14:52 +08:00
Haozhe
b3212fd9ab
fix(remote-control): pick credential slot and relay from login region (#3969)
* fix(remote-control): pick credential slot and relay from login region

Global login stores tokens in kimi-code-env-*.json and should use
code-rc.kimi.ai; Remote Control always read kimi-code.json and
code-rc.kimi.com. Resolve both from the persisted oauth ref.

* fix(telemetry): skip the dead global collector and keep shutdown alive

The global collector host has no DNS. Drop it from the region profile and
skip the send instead of falling back to the mainland endpoint. Keep the
shutdown timeout timer referenced so a failed flush cannot exit before the
TUI hands the process to the foreground server.

* fix(remote-control): require explicit relay origin and drop hardcoded .com defaults
2026-09-23 18:10:47 +08:00
7Sageer
a54e6f6a9b
feat(agent-core-v2): add KIMI_CODE_REPEAT_BREAKER env switch (#3995)
* feat(agent-core-v2): add repeat_breaker config switch

Add a top-level repeat_breaker boolean (default true) to config.toml,
overridable with the KIMI_CODE_REPEAT_BREAKER env var. When disabled,
the agent skips repeat reminders and forced stops on consecutively
repeated identical tool calls; same-step dedupe is unaffected.

* Update repeat-breaker-config-switch.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* feat(agent-core-v2): add tool_dedupe config switch

* refactor(agent-core-v2): drop the tool_dedupe config switch

Same-step dedupe stays always on. repeat_breaker remains the only public switch.

* refactor(agent-core-v2): read the repeat breaker from the environment only

KIMI_CODE_REPEAT_BREAKER is the only switch. Unset keeps reminders and forced stops on.

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-09-23 18:00:59 +08:00
7Sageer
6451f1e056
fix: harden workspace trust boundaries across git, file tools, and the local web server (#3964)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* fix(kap-server): reject malformed and null Origins

isOriginAllowed conflated an unparseable Origin header with an absent
one and allowed both, so a sandboxed document (Origin: null) passed the
WebSocket upgrade check and had its Origin echoed by the CORS hook.
An absent Origin is still allowed for non-browser clients, but a
present Origin that fails to parse, is null, or uses a non-http(s)
scheme is now rejected: the WS upgrade responds 403 and the CORS hook
withholds Access-Control-Allow-Origin.

* fix(kimi-code): sync web bundle for kimi_origin query gating

* fix(agent-core-v2): gate workspace local.toml behind trust and tighten additional_dir

* fix(agent-core-v2): block symlink escapes in agent file tools

* fix: harden background git invocations against repo-local config

* fix(agent-core-v2): close trust-gate gaps in add-dir and additional_dir validation

* fix: neutralize repo-configured clean and process filters in hardened git calls

* fix(agent-core-v2): fail closed when a path is too deep to verify

* fix: probe worktree-scoped filter config in hardened git calls

* fix: fail closed when git filter discovery fails and cache probes for repo subdirectories

* fix(agent-core-v2): block symlink aliases of the project-local config in write tools

* fix: neutralize smudge, merge drivers, and repo-controlled commit signing in hardened git calls

* fix: expand included git configs when discovering repo-defined drivers

* Revert "fix(kimi-code): sync web bundle for kimi_origin query gating"

This reverts commit cd6af49cf1dfebe505f0e890453c3207a74d3e80.

* fix: keep git hardening fail-closed on includes and probe failures in scanners

* fix: fail closed on uncodable driver names and disable repo-controlled signature verification

* fix: neutralize repo-controlled editors and match include sections case-insensitively

* fix: probe config names only and reject dangling symlinks in file tools

* fix: fail closed when core.worktree escapes the repository

* fix(agent-core-v2): match project config paths across separators and case

* fix: arm footer git only after workspace trust persists

* fix(agent-core-v2): check resolved sensitive targets for absolute outside paths

* fix: only skip git config caching for actual include sections

* refactor: share git config hardening primitives between agent-core-v2 and the CLI

* fix(agent-core-v2): clear trusted additional dirs synchronously on trust revocation

* fix(agent-core-v2): compare resolved write targets with Windows path semantics

* fix: fail closed when the git directory disappears during hardening probes

* refactor: move shared git hardening primitives into @moonshot-ai/git-hardening

* fix: close symlinked-gitdir and submodule-recurse gaps in git hardening

* fix(agent-core-v2): reject home-directory ancestors as additional_dir roots

* fix: compare core.worktree with Windows path semantics

* fix: skip git config probes on renders after a negative repo detection

* fix: resolve gitfile pointers against the .git file directory and match includeIf sections

* test: drop duplicated symlink and plain-file cases covered elsewhere

* fix: only treat project-config writes as aliased when the lexical path misses the config pattern

* test: move the realpath guard matrix into a module test

* test: cover git-hardening primitives in the shared package

* refactor: inline git hardening helpers and drop the shared package

Keep the constants and parsers next to the async engine spawn path and
the sync CLI spawn path instead of a third workspace package.

* refactor: drop footer git trust gate and config probing

Workspace trust is a process-level decision, so the TUI never mounts
the footer until the user has trusted. Footer git status now uses
static hardening flags only.

* refactor: route git execution through IGitService.runGit

- Add runGit(cwd, args, options) to IGitService as the public door for
  running git with repo-local config hardening applied.
- GitService implements runGit using the existing hardenedGitConfigArgs
  helper; status/diff now delegate to it.
- collectGitContext drops its own spawn/probe logic and calls
  IGitService.runGit instead, receiving the service through the
  promptPrefix context.
- Tower keeps its own git() function (accepted gap).

* refactor: move git hardening helpers to app/git/hardening

* Revert "fix(kap-server): reject malformed and null Origins"

This reverts commit b799a21d0390ff0e4e66437f0d7b90c0b8171efe.
2026-09-22 21:30:34 +08:00
qer
7ad0c46682
feat(plugins): update kimi-webbridge plugin to the 2.0.11 skill (#3961)
* feat(plugins): update kimi-webbridge plugin to the 2.0.11 skill

Bring the official plugin in line with the Kimi Browser Extension 2.x
daemon: document the ok/data response envelope, self-serve daemon
recovery via start, the movable listen address (10086 is only the
default), file-body retries on macOS/Linux, and the rewritten
operations reference (CLI subcommands, disk layout, new status
fields). Sync the manifest and marketplace versions to 2.0.11 and
point the help links at the new product pages.

* fix(plugins): point the Browser Extension help links at the canonical product path

The site canonicalizes /products/kimi-webbridge to
/products/kimi-browser-extension; ship the final URL in the skill,
manifest, and docs instead of relying on the redirect.
2026-09-22 12:57:23 +08:00
liruifengv
6a52dd781b
feat(config): add auto_session_title config option (#3962)
* feat(config): add auto_session_title config option

* chore: drop changeset, changelog entry ships with kimi-code-app instead
2026-09-21 19:55:40 +08:00
liruifengv
99eaa993ba
docs(changelog): sync 2.0.2 from apps/kimi-code/CHANGELOG.md (#3936)
Some checks failed
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test (5) (push) Has been cancelled
CI / test-pi-tui (push) Has been cancelled
CI / test-vscode-legacy (push) Has been cancelled
CI / test-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / build (push) Has been cancelled
CI / test (1) (push) Has been cancelled
Nix Build / Check flake.nix workspace sync (push) Has been cancelled
Release / Release (push) Has been cancelled
Publish VS Code extension / Publish VSIX to marketplaces (push) Has been cancelled
Nix Build / nix build .#kimi-code (push) Has been cancelled
Release / Deploy docs (push) Has been cancelled
Release / Native release artifact (push) Has been cancelled
Release / Publish native release assets (push) Has been cancelled
* docs(skill): list all entries for versions with 10 or fewer upstream entries in sync-changelog

* docs(changelog): sync 2.0.2 from apps/kimi-code/CHANGELOG.md
2026-09-19 20:54:09 +08:00
Haozhe
f17a22ebf4
feat: turn off filesystem watch by default (#3931)
* feat: turn off filesystem watch by default

* test: enable filesystem watch explicitly in watch-dependent suites
2026-09-19 20:17:47 +08:00
liruifengv
2cedfaf125
fix(kap-server): deliver session-level interaction events past agent filters (#3901) 2026-09-19 12:05:34 +08:00
liruifengv
1815096590
docs(changelog): sync 2.0.1 from apps/kimi-code/CHANGELOG.md (#3912) 2026-09-18 21:41:35 +08:00
liruifengv
92c3c59b22
feat: expose resolved base_url on models.dev catalog provider items (#3909)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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 / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
2026-09-18 20:43:06 +08:00
Haozhe
a80fe31cff
fix(agent-core-v2): stop workspace watchers from listing a flooded project root (#3892)
* fix(agent-core-v2): avoid root watch inventory and add a kill switch

Watch concrete candidate paths so a flooded project root cannot fill the V8 heap. Allow disabling every watcher with [watch] enabled or KIMI_CODE_WATCH.

* fix(agent-core-v2): stop watching the whole .kimi-code directory

Watch missing config files on the file path itself so session writes do not reload.
2026-09-18 15:24:05 +08:00
7Sageer
c5ad17f06a
feat(agent-core-v2): support api_key_env for provider credentials (#3762)
* feat(agent-core-v2): support api_key_env for provider credentials

Providers can declare api_key_env = "VAR" in config.toml to read their
Bearer token from an environment variable instead of storing it inline.
The value is resolved per request (rotation-friendly); an unset or empty
variable fails with config.invalid naming the provider and variable.
apiKey+apiKeyEnv and apiKeyEnv+oauth are rejected as conflicts.

The /models refresh path resolves the same chain (inline apiKey ->
apiKeyEnv -> env sub-table); a provider whose variable is unset lands in
failed[] without affecting others, and open-platform providers keep the
env declaration instead of persisting the resolved secret.

Custom registries: applyCustomRegistryProvider consumes the api.json env
field — imported providers get apiKeyEnv, the legacy inline apiKey is
dropped, and a hand-edited apiKeyEnv survives refreshes (tracked via
source.envKey). kimi provider add --api-key and the TUI registry token
field are now optional so public registries import without a key.

* docs: document api_key_env provider credentials

* fix(oauth): preserve hand-edited apiKeyEnv on registry refresh and address review nits

* fix(oauth): validate apiKeyEnv conflicts during refresh and address review nits

* fix(oauth): mirror apiKeyEnv in the klient provider contract and harden refresh validation

* fix(oauth): stop auto-binding registry env names to provider credentials

* fix(oauth): preserve hand-edited apiKeyEnv across registry re-imports

* fix(oauth): scope apiKeyEnv preservation to the owning registry

* fix(agent-core-v2): preserve apiKeyEnv across models.dev catalog re-imports

* fix(kap-server): drop apiKeyEnv when the provider update route receives a replacement key

* fix(agent-core-v2): replace provider credential fields on TOML writeback

* fix(kap-server): normalize whitespace-only api_key in the provider update route

* refactor(oauth): unify provider credential rules into shared primitives

A new provider-credential module in the oauth package owns the credential
precedence chain, the mutual-exclusion conflicts, the user-facing messages,
and the write-side tri-state reconciliation; the refresh orchestrator,
agent-core-v2 (model-auth, catalog, auth readiness), and the kap-server
provider routes compose it instead of re-deriving the rules per layer.

applyOpenPlatformConfig now takes credential: {apiKey}|{apiKeyEnv} and
merges onto the existing record, so open-platform refreshes no longer drop
hand-written fields (customHeaders, the env sub-table) on the inline-key
path either, and the refresh's write-then-undo block is gone.

Registry imports converge on removeCustomRegistryEntries +
applyCustomRegistryEntries (prior-snapshot provenance): the exported
capture/restore helpers are gone, the CLI persists a re-import with a
single setConfig instead of per-id removeProvider RPCs, and
default_model/default_provider survive a re-import whenever they still
resolve. kap-server's importCustomRegistry keeps the purge-then-rewrite
two-phase replace the config service's raw-merging writeback requires.

kap-server create/replace routes accept api_key_env (tri-state, mutually
exclusive with api_key), and GET /config plus the provider catalog item
expose the binding. A declared-but-unset api_key_env now fails readiness
checks with config.invalid (was auth.token_missing), matching request-time
behavior. Registry 401/403 without a key prints an authentication hint.

* fix(cli): persist registry re-import removals on both harness generations

The v2 harness's setConfig deep-merges per domain (retaining omitted keys
and skipping undefined defaults), so a shrunk re-import left removed
providers and aliases in config.toml and kept a cleared default dangling.
The CLI and TUI registry flows now share persistRegistryImport: on v2 the
removal phase and the rebuilt records go out as two atomic
replaceConfigSections writes (the writeback merges alias fields from raw
TOML, so the purge must be persisted first); on v1 the removeProvider RPC
cascades the removals before one merge write. defaultModel/defaultProvider
snapshots are captured before any removal so the restore works on both
paths.

* fix(oauth): reject oauth before the legacy env fallback and persist cleared thinking on re-import

refreshProviderModels' env sub-table fallback now throws the same
apiKey+oauth conflict the chat path rejects, instead of authenticating
with the fallback key and rewriting the provider to drop oauth.

persistRegistryImport writes the cleared thinking section through the
replacement payload, and drops the v1 fallback branch — registry imports
always persist through replaceConfigSections, so the removal phase no
longer needs per-id removeProvider RPCs.

* chore: consolidate provider credential changesets into one entry

* chore: trim changeset to the api_key_env entry

* fix: harden provider credential status and registry imports

* fix(oauth): expose browser-safe provider credential rules

* fix(node-sdk): replace serialized provider credentials

* fix(oauth): reject credential conflicts during refresh

* fix: harden custom registry re-imports

Reject reserved provider collisions and credential endpoint drift before mutation. Replace registry-owned sections atomically with compare-and-set guards, and carry the replacement contract through klient and node-sdk.

* refactor(registry): centralize custom registry import ownership

Route CLI and TUI imports through the engine via the typed SDK and Klient operation. Keep registry replacement policy inside the engine and preserve credential edits made while fetching the registry.

Cover the shared entry point with real configuration storage and memory/IPC transport tests.

* test: trim redundant api_key_env and registry-import coverage

* fix(cli): reuse the stored registry key on keyless re-import

Both first-party clients encoded "no key given" as an empty string, but
the engine's fallback chain (options.apiKey ?? registryKeyFromExisting)
only reuses the key parked in the provider's source blob when the option
is undefined. A keyless re-import of a private registry therefore went
out without an Authorization header and failed with 401 from the CLI
and the TUI dialog, while the kap-server REST route (which passes
undefined) reused the stored key fine.

Pass undefined from the CLI handler and the TUI import dialog instead
of normalizing to ''. The dialog's result type now marks apiKey
optional, matching the engine contract.

* test: pin CAS rejection and credential-conflict behavior

The coverage trim went past redundancy in three places, leaving the
PR's headline guards untested. Restore the compare-and-set rejection
path (guarded value changed on disk -> retry error, no write) and the
absent-section guard normalization in config.test.ts, the
apiKey+apiKeyEnv / apiKeyEnv+oauth conflict rejections at runtime
resolution (modelAuth) and at the refresh orchestrator (discovery,
with per-provider failure isolation), and the open-platform refresh
through api_key_env proving the resolved secret never lands in the
provider record. Also add the first direct unit tests for the shared
declaredProviderCredential / reconcileProviderCredentialUpdate
primitives.

* refactor(oauth): share reserved provider id rules between import and refresh

* Delete .changeset/registry-import-concurrent-credentials.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* test: trim cross-layer duplicate registry and credential coverage

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-09-17 22:02:53 +08:00
qer
25dd4ce973
feat(cli): rename the install-app subcommand to install-desktop (#3864)
install-app stays registered as a hidden alias so existing usage keeps working.
2026-09-17 14:42:11 +08:00
liruifengv
00bd3c2268
docs(changelog): sync 2.0.0 from apps/kimi-code/CHANGELOG.md (#3861)
* docs(changelog): sync 2.0.0 from apps/kimi-code/CHANGELOG.md

* docs(changelog): trim /desktop entry in English page
2026-09-17 14:08:43 +08:00
qer
34ec5d2a17
feat(cli): add /desktop slash command and kimi install-app subcommand (#3849)
* feat(cli): add /desktop slash command and kimi install-app subcommand

Both entry points print the Kimi Code desktop app page
(https://www.kimi.com/code) and open it in the default browser:
the kimi install-app subcommand from the shell, and /desktop
(alias /install-desktop) from the TUI.

* fix(cli): derive the desktop app page from the active region

Replace the hardcoded .com URL with the existing region-aware
kimiCodeOfficialInstallUrl() resolved at invocation time, so
global-region users land on the .ai site and region changes are
respected.

* docs(cli): describe the desktop app page URL as region-dependent
2026-09-16 20:53:35 +08:00
7Sageer
5653c739b9
feat(agent-core-v2): upload images as file references for Kimi models (#3784)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* feat(agent-core-v2): upload images as file references for Kimi models

* fix(agent-core-v2): scope media upload cache by endpoint and recognize SDK auth error status

* fix(agent-core-v2): restore the stripped /v1 for kimi files uploads on the anthropic route

* feat(agent-core-v2): omit oldest media when accumulated inline media exceed the request budget

* fix(agent-core-v2): key the media upload cache by the stable JWT subject

* fix(agent-core-v2): harden media request recovery

* fix(agent-core-v2): correct image memo accounting

* feat(agent-core-v2): include saved paths in dropped media placeholders

* docs: drop the saved-path re-read guarantee from the media budget note

The guarantee does not hold for inline data-URL media (no persisted
path exists), and the runtime warning already conveys path availability
when it applies. Addresses the codex P2 review suggestion by removal.
2026-09-15 21:32:42 +08:00
HydrogenE7
7d174ac933
perf(agent-core-v2): evict completed subagent scopes behind an LRU cache (#3778)
* perf(tui): batch and cache agent swarm progress rendering

* perf(agent-core-v2): evict completed subagent scopes behind an LRU cache

* fix(agent-core-v2): stop the agent actor in the session machine when its scope is removed

* fix(agent-core-v2): emit a terminal event for the final rate-limited run and defer eviction while background tasks run

* fix(agent-core-v2): include in-flight retries when abandoning suspended agents

* fix(agent-core-v2): roll back the closing flag when scope removal fails and wait per the configured eviction timeout

* fix(agent-core-v2): terminalize subagents spawned after batch cancellation and report task timeouts as failures

* chore: restore upstream/main state of files mangled by lint-staged autofix in the merge commit

oxlint --fix rewrites (prefer-set-has, catch-error-name, prefer toSorted/.at(-1)/toReversed)
touched seven files the branch never modified; one of them (oauth managed-kimi-code.ts)
no longer typechecks. Restore all seven to their exact upstream/main state. Committed
with --no-verify so the same autofix does not re-mangle them.

* fix(agent-core-v2): retry deferred scope evictions without exhausting the attempt budget, dedupe terminal events for starting retries, and patch-level the changeset

* fix(agent-core-v2): finish scope teardown instead of reactivating a partially torn-down scope

* fix(agent-core-v2): terminalize subagent-start hook cancellations and re-acquire resume targets after metadata reads

* fix(tui): record cancelled background agents in the transcript

* fix(agent-core-v2): route mirror terminal events through the batch exactly-once guard

* fix(tui): guard terminal swarm members from re-cancellation and deliver terminal status to cancelled foreground subagent cards

* fix(agent-core-v2): classify eviction as removed when teardown already closed the scope

* Merge remote-tracking branch 'upstream/main' into perf/subagent-scope-eviction

Skip lint-staged for this merge: its oxlint --fix pass rewrites unrelated files
(prefer-set-has etc. mangled seven files in the previous merge commit), while the
merge content is upstream's lint-clean code plus conflict resolutions already
verified by oxlint.

* chore: restore upstream/main changes dropped by a stash roundtrip during the merge

A git stash/pop cycle used to isolate an unrelated flaky test reverted 82 files of the
merge result to the pre-merge branch state, so commit 375ff2a4a missed them. The
working tree already held the correct merged content; this commit restores it.

* fix(agent-core-v2): propagate the cancellation reason from turn abort to tool signals

Cancelling a turn aborted the turn's llm scope and every tool scope
without a reason, so tools and subagents only ever saw the default
AbortError and could not tell a user cancellation from a system abort.
With the swarm terminal-event classification this surfaced as
`subagent.failed` ("This operation was aborted") on Ctrl+C instead of
`subagent.cancelled`.

Carry the reason end to end: `MachineEngine.abort(reason)` sends it on
`input.abort`, the agent machine remembers it for the turn and forwards
it to `turn.abort` and to every tool scope it aborts, the turn machine
passes it to the llm scope, and the loop service hands its cancellation
(a `UserCancellationError` by default) to the engine.

* fix(agent-core-v2): stop rebuilding an evicted subagent after its caller aborts

`createAgentAwaitingClose` polled for the previous scope to finish
closing without ever looking at the caller's abort signal, so cancelling
an `Agent` or `AgentSwarm` resume during that wait still recreated the
scope afterwards. In the `Agent` path the run then rejected before any
terminal event was mirrored, leaving an idle scope that the scope cache
no longer tracked.

Thread the caller's signal into the helper and check it before every
attempt; the Agent tool passes its call controller and the swarm service
passes the attempt signal. Also trim the eviction changeset to the one
sentence the changeset rules ask for.

* fix(agent-core-v2): report task-manager aborts of a subagent as cancelled

When the task manager times out or stops a background subagent it aborts
the run with a plain reason ('Timed out', the TaskStop reason), and the
run rejects with that raw reason. The task manager therefore classifies
the task as timed_out or killed, but the mirror only recognised
`UserCancellationError` as a cancellation and emitted `subagent.failed`,
so the transcript recorded a failure before the authoritative
`background.task.terminated` event could land.

Classify a terminated run by the shape of its abort reason: a real
Error that is not an AbortError (the swarm's own per-item timeout) stays
a failure, everything else that aborted the run is a cancellation. The
swarm's start-failure path uses the same rule.

* fix(agent-core-v2): flush the wire before evicting a subagent scope and re-pick LRU candidates

Two gaps in the scope-cache eviction pass:

- `AgentLifecycleService.remove()` swallows a failed wire flush and still
  tears the scope down, so an eviction that hit a disk-full or transient
  I/O error would drop the in-memory scope and let a later resume rebuild
  from a stale wire. Flush the agent's wire explicitly before removing;
  if that fails, keep the scope resident and retry on a later pass. The
  idle and task checks are repeated after the flush so a resume that
  started meanwhile is not cancelled by the removal.
- The pass snapshotted its candidates up front and re-validated them by
  attempt count only, so a scope that was resumed and completed again
  while an earlier eviction was awaited kept matching with attempts 0 and
  was evicted despite now being the most recently used. Pick the oldest
  eligible entry from the live map on every step instead, skipping only
  the entries this pass already tried.

---------

Co-authored-by: Kaiyi <me@kaiyi.cool>
2026-09-15 20:33:24 +08:00
Kimi Agent
39a74556a6
fix(plugins): rename WebBridge display name to Kimi Browser Extension (#3803)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (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
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* fix(plugins): rename WebBridge display name to Kimi Browser Extension

The product has renamed WebBridge to Kimi Browser Extension in work and
Chrome. Update the user-facing display name across the built-in
capability entry, TUI plugins selector, managed plugin manifest,
marketplace catalog, skill docs, and user docs to match. Internal ids,
binary names, CDN paths, and daemon references are unchanged.

* fix(plugins): bump webbridge to 1.11.4 and keep legacy docs anchor

Address review: point the changeset at the scoped CLI package, bump the
renamed plugin's manifest/catalog/docs version so installed users are
offered the renamed package as an update, and preserve the published
#kimi-webbridge documentation anchor beside the renamed heading.

* docs(plugins): match only the known extension-update error messages

Broadening the version-mismatch trigger to the generic prefix 'Please
update the' would misclassify unrelated tool errors as an outdated
browser extension; match the two known full messages instead.

---------

Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>
2026-09-15 18:13:51 +08:00
liruifengv
3eaed4e7d5
docs(changelog): sync 0.43.1 from apps/kimi-code/CHANGELOG.md (#3805) 2026-09-15 17:28:15 +08:00
liruifengv
bb0c66a15b
feat(oauth): switch the managed usage payload to the quota model (#3787)
The platform /usages payload now serves per-window used ratios
(goods_version, a usages map of limit5h/limit7d/monthTotal/monthCode
entries with used_ratio/reset_time, and boosterWallet) instead of
absolute used/limit rows.

- oauth: parse and fetch the quota model; keep the platform helpers
- toolkit / agent-core-v2 / node-sdk: getManagedUsage returns the quota
- kap-server: /oauth/usage passes the camelCase quota shape through
  (the legacy snake_case wire is gone)
- TUI /usage: plan rows are presence-driven from the quota payload;
  the monthly row carries a kimi/code breakdown line
- docs: server-api reference updated for the new response shape
2026-09-15 13:33:20 +08:00