feat(web): hide ACP-created sessions and workspaces from the sidebar#1908
feat(web): hide ACP-created sessions and workspaces from the sidebar#1908zhiyuan1i wants to merge 4 commits into
Conversation
The ACP adapter now tags every session it creates with `source: 'acp'` (plus the client's `clientInfo.name` when advertised) in the persisted custom metadata, which kap-server already forwards onto the wire session. kimi-web reads that tag and, behind a new on-by-default setting, filters ACP sessions out of the sidebar lists and archived views; workspaces whose loaded sessions are all ACP-created are hidden as well, via a computed root set applied only at the mergeWorkspaces call site (never persisted, so WS broadcasts cannot resurrect them). The tag marks "created via ACP": forked sessions inherit it through the existing custom-metadata copy, and `session/resume` never tags.
With the ACP-hiding preference on, the most recent session is often a bot-driven ACP session that the sidebar does not render; fresh load still auto-selected it, leaving the user on an invisible session. useWorkspaceState now takes an optional isSessionHiddenFromList dep (the facade wires it to the hide-ACP preference) and both the workspace pick and the session auto-select skip hidden sessions. Explicit deep links and notification clicks are unaffected — only the passive landing changes.
Follow-up to the fresh-load fix: openWorkspace (clicking a mixed workspace), the popstate dead-link fallback, and the post-archive successor pick all used rawState.sessions[0] and could land on a session the sidebar hides. They now share the same isSessionHiddenFromList predicate; openWorkspace with only hidden sessions left falls back to the empty composer, matching the empty-workspace behavior.
Last rawState.sessions[0] pick-next path: when the daemon reports the active session as gone, the fallback could land on a sidebar-hidden (ACP-created) session. Now shares the same hide-ACP predicate as the other pick-next paths.
🦋 Changeset detectedLatest commit: 7d66cc0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7d66cc0afd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| (s) => | ||
| !s.parentSessionId && | ||
| visibleWorkspaceIds.has(workspaceIdForSession(s)) && | ||
| !(hideAcpSessions.value && isAcpSession(s)), |
There was a problem hiding this comment.
Apply ACP filtering to recent workspace ordering
When hideAcpSessions is enabled and a mixed workspace has a newer ACP session plus an older human session, this filter removes the ACP row, but workspacesView still builds its recent-sort lastEditedAt from all rawState.sessions above. The hidden ACP activity can move that workspace to the top of the sidebar, so the setting still leaks/sorts by sessions it claims to hide; apply the same hideAcpSessions && isAcpSession predicate before computing workspace recency.
Useful? React with 👍 / 👎.
| const filteredArchived = computed<AppSession[]>(() => { | ||
| const q = archiveQuery.value.trim().toLowerCase(); | ||
| let rows = archivedItems.value.filter((s) => s.archived === true); | ||
| if (client.hideAcpSessions.value) rows = rows.filter((s) => s.source !== 'acp'); |
There was a problem hiding this comment.
Expose the ACP-session toggle in mobile settings
On mobile, App.vue opens MobileSettingsSheet instead of the desktop SettingsDialog, and this newly added filter is controlled by client.hideAcpSessions, which defaults to true. Because the mobile sheet has no corresponding toggle/event, mobile users cannot turn the filter off to find or restore archived ACP sessions, or reveal hidden ACP workspaces, from the mobile UI; add the same setting row here or pass through the existing setter.
Useful? React with 👍 / 👎.
Motivation
When a bot/automation client drives kimi-code over ACP (e.g. a chat-ops bot spawning one session per workspace directory), the kimi-web sidebar fills up with machine-owned workspaces (
s_xxxx-style directories) and sessions whose titles are raw injected prompt prefixes. There is currently no way to tell these apart from interactive sessions, let alone hide them.Approach
Tag at the source. The ACP adapter now passes
metadata: { source: 'acp', acp_client: <clientInfo.name> }when handlingsession/new.metadatais a first-classCreateSessionOptionsfield, so it lands in the session's persistedcustommap (same extension channel asgoal/parent_session_id) and kap-server'sbuildWireMetadataalready forwards it onto the wire session — zero server-side changes.Filter in the web view layer. With a new on-by-default setting (Settings → General → "Hide ACP sessions", persisted in localStorage):
sessionsForView,workspaceGroups, and both archived lists (desktop Settings dialog + mobile sheet) dropsource === 'acp'sessions.mergeWorkspacescall site. It is deliberately not written into the user-ownedhiddenWorkspaceRoots(which persists to localStorage and gets auto-cleared by workspace WS broadcasts).openWorkspace, popstate dead-link fallback, post-archive successor,handleSessionNotFound) skip hidden sessions so the user never lands on a session the sidebar does not render. Explicit deep links and notification clicks still open ACP sessions directly.Semantics and trade-offs (intentional)
session/loadandsession/resumenever tag, and forks inheritcustom(minusgoal), so a fork of an ACP session stays hidden.Testing
acp-adapter:session/newpasses the metadata tag, with and withoutclientInfo(325 tests green).kimi-web: new unit tests foracpOnlyWorkspaceRoots(mixed/empty/no-cwd edge cases) and for the hidden-aware pick-next paths (654 tests green,vue-tscclean).