13 KiB
status, system, created, owners
| status | system | created | owners | |
|---|---|---|---|---|
| active | agents | 2026-08-11 |
|
Hide Disabled Agent Profiles from Left Panel Navigation Requirements
Overview
An agent profile can be disabled via the /settings/agents profile list
(docs/specs/agents/requirements/profile-disable.md) — the enabled toggle takes it out
of task/session creation while keeping it configured and editable. A disabled
profile still appears in the Settings left panel's Agents tree (under
Settings → Agents) with a "Disabled" badge. Users who disable several
profiles (retired models, temporarily broken agent CLIs) get a cluttered
navigation tree with no way to suppress those entries, exactly the problem
the integrations feature solved for disabled integrations
(docs/specs/integrations/requirements/enable-disable-toggle.md, setting "Hide disabled
integrations from left panel navigation"). This feature adds the analogous
setting for agent profiles.
Requirements
REQ-AGENTS-HIDE-DISABLED-PROFILES-NAV-001: Hide Disabled Agent Profiles from Left Panel Navigation
Intent: An agent profile can be disabled via the /settings/agents profile list
(docs/specs/agents/requirements/profile-disable.md) — the enabled toggle takes it out of task/session
creation while keeping it configured and editable. A disabled profile still appears in the Settings
left panel's Agents tree (under Settings → Agents) with a "Disabled" badge. Users who disable
several profiles (retired models, temporarily broken agent CLIs) get a cluttered navigation tree
with no way to suppress those entries, exactly the problem the integrations feature solved for
disabled integrations (docs/specs/integrations/requirements/enable-disable-toggle.md, setting "Hide disabled
integrations from left panel navigation"). This feature adds the analogous setting for agent
profiles.
Acceptance criteria
- AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.1: The agents settings page (
/settings/agents) SHALL gain one new setting, "Hide disabled agent profiles from left panel navigation", off by default. It is a single, install-wide preference — not per profile. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.2: When that setting is off (default), a disabled profile MUST still appear in the Settings left panel's Agents tree exactly as it does today, with its "Disabled" badge — only the profile's own
enabledstate and reachability gate selection surfaces, not nav visibility. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.3: When that setting is on, a profile whose
enabledisfalseMUST be hidden from the Settings left panel's Agents tree. An enabled profile, and a legacy profile whoseenabledfield is absent (treated as enabled), are unaffected and stay listed. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.4: The setting SHALL NOT change any other behavior gated on a profile's
enabledstate (task/session/session-handoff/quick-chat pickers, the "no compatible agent" empty states, pre-selection defaults). Those keep gating onenabled !== falseexactly as they do today. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.5: The setting SHALL NOT hide anything from a settings page itself: the
/settings/agentspage keeps listing every profile, and the profile editor page (which owns the enable/disable toggle after the PageShell restructure) stays directly reachable by URL even while its left-panel nav entry is hidden. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.6: Toggling the setting SHALL take effect immediately (no reload, no save bar) and SHALL sync across browser tabs.
- AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.7: GIVEN a profile with
enabled: falseand the "hide disabled" setting off (default), WHEN the user opens the Settings left panel's Agents tree, THEN the profile is listed with its "Disabled" badge. - AC-AGENTS-HIDE-DISABLED-PROFILES-NAV-001.8: GIVEN a profile with
enabled: false, WHEN the user turns on "Hide disabled agent profiles from left panel navigation" on/settings/agents, THEN the profile's entry disappears from the Settings left panel's Agents tree immediately (no reload required), while enabled profiles and legacy profiles without the flag stay listed.
Migrated source detail
Why
An agent profile can be disabled via the /settings/agents profile list
(docs/specs/agents/requirements/profile-disable.md) — the enabled toggle takes it out
of task/session creation while keeping it configured and editable. A disabled
profile still appears in the Settings left panel's Agents tree (under
Settings → Agents) with a "Disabled" badge. Users who disable several
profiles (retired models, temporarily broken agent CLIs) get a cluttered
navigation tree with no way to suppress those entries, exactly the problem
the integrations feature solved for disabled integrations
(docs/specs/integrations/requirements/enable-disable-toggle.md, setting "Hide disabled
integrations from left panel navigation"). This feature adds the analogous
setting for agent profiles.
What
- The agents settings page (
/settings/agents) SHALL gain one new setting, "Hide disabled agent profiles from left panel navigation", off by default. It is a single, install-wide preference — not per profile. - When that setting is off (default), a disabled profile MUST still
appear in the Settings left panel's Agents tree exactly as it does today,
with its "Disabled" badge — only the profile's own
enabledstate and reachability gate selection surfaces, not nav visibility. - When that setting is on, a profile whose
enabledisfalseMUST be hidden from the Settings left panel's Agents tree. An enabled profile, and a legacy profile whoseenabledfield is absent (treated as enabled), are unaffected and stay listed. - The setting SHALL NOT change any other behavior gated on a profile's
enabledstate (task/session/session-handoff/quick-chat pickers, the "no compatible agent" empty states, pre-selection defaults). Those keep gating onenabled !== falseexactly as they do today. - The setting SHALL NOT hide anything from a settings page itself: the
/settings/agentspage keeps listing every profile, and the profile editor page (which owns the enable/disable toggle after the PageShell restructure) stays directly reachable by URL even while its left-panel nav entry is hidden. - Toggling the setting SHALL take effect immediately (no reload, no save bar) and SHALL sync across browser tabs.
Data model
No new persistent (backend/database) state. The setting lives in the
browser's localStorage, matching
hooks/domains/integrations/use-hide-disabled-integrations-in-nav.ts:
| Key | Type | Default | Notes |
|---|---|---|---|
kandev:agents:hideDisabledInNav:v1 |
boolean | false |
Not per-profile; one flag for the whole nav-filtering behavior. |
The per-profile enabled state is the existing
agent_profiles.enabled column (SQLite), exposed on every profile in the
GET /api/v1/agents / GET /api/v1/agent-profiles/:id responses and
normalized to enabled?: boolean on the canonical frontend AgentProfile
(apps/web/lib/types/agent-profile.ts). Absent on legacy payloads — treat
as enabled.
API surface
No backend/HTTP/WS changes. This is entirely a frontend feature.
Frontend primitives (new):
hooks/use-local-storage-boolean.ts— the shareduseLocalStorageBoolean(storageKey, syncEvent, defaultValue = false)primitive: install-wide,localStorage-backed boolean with theuseSyncExternalStore+storage-event + custom-event-broadcast shape both nav-visibility toggles use. Absent keys (and read failures) resolve todefaultValueon both the client snapshot and the server snapshot, so SSR and first client paint agree; a failed write throws.hooks/domains/settings/use-hide-disabled-agent-profiles-in-nav.ts— exportsuseHideDisabledAgentProfilesInNav()returning{ hideDisabled: boolean; setHideDisabled: (next: boolean) => void }, backed bylocalStoragekeykandev:agents:hideDisabledInNav:v1(defaultfalse), delegating to the shared primitive with custom event namekandev:agents:hide-disabled-in-nav-changed, so the settings tree re-renders immediately in the same tab and other tabs update via the browserstorageevent. The integrations sibling (useHideDisabledIntegrationsInNav) delegates to the same primitive with its own key/event, so the two features cannot drift in mechanism.app/settings/agents/hide-disabled-agent-profiles-setting.tsx— the settings-page row (label + description +<Switch id="hide-disabled-agent-profiles-in-nav">), rendered on the agents settings page directly below the header separator and above the "Installed Agents" list (the restructured page's profile list lives inside the installed-agent cards), so the setting appears before the first agent profile on the page. The switch saves immediately on toggle (the agents page has no settings-floating-save bar; its profile enabled toggles are immediate-save, and this setting follows that page convention).
Modified:
components/app-sidebar/sections/settings/settings-menu-branches.ts— the Settings left panel's Agents branch (buildAgentsBranch) filters its profile children: whenhideDisabledis on, a profile withenabled === falseis omitted. Profiles withenabledabsent/trueare always listed. The existing "disabled" badge convention is unchanged (it still renders on any disabled profile that is listed, i.e. when the setting is off).components/app-sidebar/sections/settings/use-settings-menu-branches.ts— the live branch builder readsuseHideDisabledAgentProfilesInNav()and threads the flag intobuildAgentsBranch, mirroring howuseVisibleIntegrationSlugsgates the integrations branch (both skip filtering entirely on the default path).
Permissions
No change. The setting is a per-browser-profile, install-wide UI preference with no authorization dimension (same as the integrations nav-hiding setting).
Failure modes
localStorageunavailable or throwing (private browsing, quota) — the hook degrades tohideDisabled: false(its documented default), so a storage failure never hides a profile the user cannot otherwise see or control.setHideDisabledthrows on a failed write instead of reporting a successful save, mirroring the integrations hook.- A profile with
enabledabsent (legacy payload) is never hidden — absence means enabled, consistent withlib/state/slices/settings/types.ts'sisSelectableAgentProfileand the normalizer default inlib/api/domains/agent-profile-normalize.ts.
Persistence guarantees
State lives only in localStorage; it is not part of any backend restart or
task-execution durability guarantee, matching the existing integrations
nav-setting convention. It survives a browser restart but not a
localStorage clear, and is not synced across devices/browsers.
Scenarios
- GIVEN a profile with
enabled: falseand the "hide disabled" setting off (default), WHEN the user opens the Settings left panel's Agents tree, THEN the profile is listed with its "Disabled" badge. - GIVEN a profile with
enabled: false, WHEN the user turns on "Hide disabled agent profiles from left panel navigation" on/settings/agents, THEN the profile's entry disappears from the Settings left panel's Agents tree immediately (no reload required), while enabled profiles and legacy profiles without the flag stay listed. - GIVEN the "hide disabled" setting is on and a profile is hidden,
WHEN the user re-enables the profile via the profile editor header
toggle (
/settings/agents/<agent>/profiles/<id>), THEN the profile's nav entry reappears immediately. - GIVEN the "hide disabled" setting is on, WHEN the user opens
/settings/agents(the page itself), THEN every profile — disabled or not — is still listed, and the profile editor (which owns the enable/disable toggle) remains reachable by URL. - GIVEN the "hide disabled" setting is on and a profile is disabled, WHEN the user opens the new task / new session / handoff / quick-chat selectors, THEN the disabled profile stays excluded exactly as it is today — the setting does not change selection gating.
- GIVEN the "hide disabled" setting is on, WHEN the user toggles it
off again on
/settings/agents, THEN disabled profiles reappear in the Settings left panel's Agents tree immediately.
Out of scope
- The main (office) sidebar's Agents section
(
components/app-sidebar/sections/agents-section.tsx). Office agents are workspace-scoped rows with their ownstatus/pause semantics and no user-facing enable/disable toggle; theenabledflag is a/settings/agentsprofile-flavor concept (seedocs/specs/agents/requirements/profile-disable.md's Out of scope). This setting does not touch office rows. - The mobile menu — it has no agent-profile surface today.
- No change to profile selection gating, pickers, empty states, or pre-selection defaults (unchanged by this setting).
- No change to the
DisabledBadgeconvention itself; it keeps rendering on any disabled profile that is listed. - No new command-palette entries or keyboard shortcuts.
Open questions
(none)