Skip to content

CLI grammar redesign: --sort, --state, --age for extensible list filtering #11

@djdarcy

Description

@djdarcy

CLI grammar redesign: --sort, --state, --age for extensible list filtering

Problem

csb list currently uses ad-hoc boolean flags (--deleted, --all) and hardcoded last_active_at DESC ordering. This has two limitations:

  1. No way to sort by expiration -- with default cleanupPeriodDays=30, sessions older than 30 days are silently purged by Claude Code. csb list should let users see sessions soonest to be purged so they can back up or resume them before they're gone.
  2. Ad-hoc flag vocabulary doesn't extend -- each new filtering dimension (state, age, size, etc.) would need its own boolean flag, leading to flag sprawl.

Proposed grammar

Structured choice flags replace ad-hoc booleans:

csb list [QUERY] [options]

  --sort KEY       last-used (default) | expiration | started | oldest | messages | size
  --state STATE    active (default)    | deleted    | all
  --age WINDOW     today               | week       | month   | stale | overdue
  --reverse        Reverse sort direction
  -n N             Number of results
  --json           Output as JSON

The three filter/sort flags are orthogonal:

  • --sort controls ordering only
  • --state controls deleted/active subset
  • --age controls time-window subset

The positional QUERY remains as keyword substring search (unchanged).

Rollout plan

Phase 1: --sort (this issue's immediate scope)

  • Add --sort flag with choices: last-used, expiration, started, oldest, messages, size
  • Add module-level SORT_SQL whitelist dict in index.py (SQL injection safe)
  • Update list_sessions() signature with sort_key="last-used" default
  • Wire args.sort in cmd_list()
  • Expiration sort handles zero-mtime sessions via NULLIF(jsonl_mtime, 0) ASC NULLS LAST
  • 4 new CLI parse tests
  • 7 new index sort tests

See: 2026-04-10__17-06-00__list-sort-by-expiration-and-grammar-redesign.md (analysis) and 2026-04-10__17-23-45__claude-plan__csb-list-sort-phase1.md (plan).

Phase 2: --state and --age (separate session)

  • Add --state {active,deleted,all} with default active
  • Add --age {today,week,month,stale,overdue} for time-window filtering
  • Keep --deleted and --all as deprecated aliases (still work, mention in help)
  • Tests for each state and age option

Phase 3: Polish (further out)

  • --reverse flag to invert sort direction
  • Additional sort keys (project, folder-count)
  • Additional state options (archived -- sessions in git but not on disk)
  • Documentation update in README

Non-goals

  • No schema changes -- all necessary columns (jsonl_mtime, started_at, message_count, jsonl_size) already exist
  • No changes to timeline.py rendering -- just the ordering changes
  • No changes to csb scan, csb show, csb search -- those stay as they are
  • No changes to positional keyword search (csb list vault still works)

Backward compatibility

  • Default --sort last-used preserves current behavior exactly
  • --deleted and --all continue to work through Phase 2 (become aliases for --state)
  • All existing tests continue to pass without modification
  • JSON output order reflects the chosen sort

Related

  • Design doc: 2026-04-10__17-06-00__list-sort-by-expiration-and-grammar-redesign.md
  • Phase 1 plan: 2026-04-10__17-23-45__claude-plan__csb-list-sort-phase1.md
  • Issue csb list shows stale data -- auto-refresh or staleness warning #5 (stale index warning) -- --sort expiration surfaces the staleness problem more acutely since it depends on jsonl_mtime being fresh

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions