MoonshotAI / MoonshotAI/kimi-code

Web UI shows the wrong permission mode — /status permission never synced (yolo/auto displays as manual)

Open Beginner friendly
#1,386 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

What version of Kimi Code is running?

0.22.3 (web SPA / kimi server run surface). The affected code path is unchanged on current main.

Which open platform/subscription were you using?

Not applicable — this is a client-side display bug in the web SPA, independent of the /login plan.

Which model were you using?

Not applicable — provider/model-independent (purely client-side UI state).

What platform is your computer?

Any (browser-based web SPA); reproduced on Linux.

What issue are you seeing?

The web UI's permission-mode indicator does not reflect the session's actual permission. It is seeded from browser localStorage (default manual) and is never updated from the session's real permission, even though the SPA already fetches GET /sessions/{id}/status, whose response includes the authoritative permission field. A session running in yolo (or auto) is displayed as manual, misleading the operator about whether tool actions are being auto-approved.

Root cause — two facts in the web client:

  1. Displayed permission is driven by localStorage, not the session. In apps/kimi-web/src/composables/useKimiWebClient.ts: state is seeded permission: loadPermissionFromStorage() (:363; loadPermissionFromStorage defaults to 'manual' at :130) and displayed via computed(() => rawState.permission) (:1732). The only write to rawState.permission is the user's explicit optimistic setPermission (apps/kimi-web/src/composables/client/useWorkspaceState.ts:1560-1561). Nothing syncs it from the session.
  2. The /status fold ignores permission. refreshSessionStatus (useKimiWebClient.ts:583) folds only model, context tokens, swarmMode, and planMode. st.permission is present (client.ts:399 maps the wire permission field into AppSessionRuntimeStatus.permission, types.ts:98) but is never applied to rawState.permission. So the fetched status corrects model/context/plan/swarm, but leaves permission at the stale localStorage/manual default.

Impact: safety-relevant, not cosmetic — the operator sees manual and may assume every tool action will be confirmed, while the agent is actually auto-approving everything (yolo). Also affects auto shown as manual. The daemon side is correct; /status already returns an accurate permission. This is purely a client-side sync gap.

What steps can reproduce the bug?
  1. Set default_permission_mode = "yolo" at the root of config.toml.
  2. Start kimi server run (the web SPA), open the web UI, create/open a session.
  3. Observe the permission indicator shows manual even after a full reload.
  4. Confirm the server disagrees: GET /api/v1/sessions/<id>/status"permission": "yolo" (both the SPA's own session and a fresh POST /api/v1/sessions one).

Behavioral confirmation the session is really yolo: the agent read a file via a tool without surfacing a tool-approval prompt (a manual session would prompt first) → tools were auto-approved. Only the label is wrong.

What is the expected behavior?

The permission indicator should reflect the session's server-side permission (yolo/auto/manual), synced from GET /sessions/{id}/status, rather than a stale localStorage default.

Additional information

Suggested fix: fold /status permission into reactive state exactly like swarmMode/planMode. In refreshSessionStatus (useKimiWebClient.ts:583, where rawState is already in scope):

rawState.permission = st.permission;

Permission is currently a single global rawState.permission (unlike the per-session planModeBySession/swarmModeBySession); if the indicator should be per-session, key it by sessionId (permissionBySession[sessionId] = st.permission) and drive the computed getter from the active session. Also worth reconsidering whether seeding from localStorage should win over an attached session's server-side permission at all.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/kimi-web/src/composables/useKimiWebClient.ts, especially refreshSessionStatus and the rawState.permission initialization. Compare the status mapping in apps/kimi-web/src/client.ts and the permission type in types.ts, then trace the displayed permission computed state. Done means the indicator reflects the attached session's server-reported manual, auto, or yolo permission after loading and refreshing, with the chosen session-scope behavior verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.