Skip to content

Generalize value-conditional drawer annotation beyond permissions.defaultMode #7

@samkeen

Description

@samkeen

Status

  • 2026-05-22: effortLevel annotation shipped (Option 1 against model-config.md — see Update log below). The pattern is now proven for two keys (permissions.defaultMode, effortLevel); the rest is per-key judgement, not a single follow-up.

This issue stays open as the umbrella. Spawn smaller issues only if a specific key earns one.

Background

The drawer surfaces a value-conditional annotation under the EFFECTIVE block when it can join the row's effective value to richer per-value prose:

permissions.defaultMode
string · scalar (last-wins)
Default permission mode.

EFFECTIVE
  "auto"                    USER · WINS
  → Auto-approves tool calls with background safety
    checks that verify actions align with your request.
    Currently a research preview

Originally wired up in 218171a (on top of faa33ec). Header prose stays generic (the description of the knob); the annotation describes the current value.

Survey — where we are

Key Values Per-value source Status
permissions.defaultMode 7 catalog/permissions.json ✅ shipped
effortLevel 5 (low/medium/high/xhigh/max) catalog/model-config.json ✅ shipped 2026-05-22
teammateMode 3 (auto/vertical/horizontal) ❌ none open — see decision matrix
viewMode 3 ❌ none open — see decision matrix
env.CLAUDE_CODE_DEBUG_LOG_LEVEL 5 ❌ none open — see decision matrix
tui 2 (fullscreen/classic) ❌ none likely "don't do it"
defaultShell 2 (bash/powershell) ❌ none likely "don't do it"
forceLoginMethod 2 ❌ none likely "don't do it"
~70 enable/disable toggles 2 n/a — name carries meaning out of scope

Per-key decision matrix

The remaining keys each need a small judgement call against the solution space (below). Rough sort:

  • 2-value toggles (tui, defaultShell, forceLoginMethod): probably Option 4 — don't do it. The value names are self-describing and the existing single-paragraph description usually covers both clearly. Pick up only if the description is genuinely thin for one of them.
  • 3-value enums (teammateMode, viewMode): each needs a quick check of its upstream docs page. If a clean per-value table exists, Option 1; if not, weigh Option 2 vs Option 4 by how painful the current description is.
  • env.CLAUDE_CODE_DEBUG_LOG_LEVEL: 5 values, env-var (lower visibility than a settings-key knob). Likely Option 2 territory if it earns the slot at all.

Solution space (reference)

  1. Sync upstream prose where it's structured. Add sync-<page>.js + catalog/<page>.json + extend resolveValueAnnotation in KeyDrawer.tsx. Same recipe as permissions / model-config.

    • Pro: Self-documenting, drift-detectable via the existing catalog-drift workflow.
    • Con: Each new domain costs one sync script + catalog file + tests. Worth it only when the upstream page actually has a structured table.
  2. Hand-curated overlay catalog. Single catalog/value-prose-overlay.json of shape { "<keyPath>": { "<value>": "<prose>" } }, edited by hand.

    • Pro: Flexible — covers keys whose upstream docs lack a structured table. Cheap to add a row.
    • Con: Rots silently without a watchdog; duplicates prose Claude Code's docs already write elsewhere.
  3. Description-prose parser. Extract per-value semantics from the existing description field on settings catalog entries that have an enum.

    • Pro: No new sync work.
    • Con: Fragile and noisy. Effectively dead — neither shipped slice needed it; treat as not-a-real-option.
  4. Don't do it. For 2-value enums, the existing single-paragraph description usually covers both values clearly.

    • Pro: Zero work.
    • Con: Loses an annotation where it would have helped (rare for 2-value enums).

Out of scope

  • Anything that changes the drawer layout. The annotation slot under EFFECTIVE is the contract; generalising it doesn't relayout.
  • Annotating enable/disable boolean toggles — the value name already carries the meaning.

Update log

2026-05-22 — first slice shipped (effortLevel).

  • New scripts/sync-model-config.js + tests, parses model-config.md's #### Choose an effort level table into catalog/model-config.json (5 records: low / medium / high / xhigh / max).
  • Wired through read_catalog as model_config (snake-case on the wire, like env_vars / sub_agents / cli_reference).
  • resolveValueAnnotation in KeyDrawer.tsx now hoists the typeof value === "string" guard and branches on both permissions.defaultMode and effortLevel. New findEffortLevel(name) lookup in src/lib/catalog.ts.
  • Catalog-drift workflow + landing-page stats + roadmap updated.
  • max is documented even though it's session-only and not accepted in the settings field (per upstream); the annotation still fires when a user lands at max via /effort max or the CLAUDE_CODE_EFFORT_LEVEL env var.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions