You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
claudbg/.beans/claudbg-4bms--filter-query-...

2.6 KiB

title status type priority created_at updated_at parent
Filter query parser completed task normal 2026-03-31T00:33:08Z 2026-03-31T05:04:41Z claudbg-2vwx

Implement the filter query language:

Syntax:

  • key:value — substring match (e.g. model:haiku matches claude-haiku-4-5)
  • key:* — field is non-empty
  • key>value / key<value — comparison for numeric and date fields
  • AND / OR for combining expressions
  • Multiple --filter flags are ANDed together

Supported keys:

  • model — substring match on model name
  • project — substring match on project path
  • id — substring match on session/agent ID
  • agents — count of sub-agent runs (numeric)
  • messages — total message count (numeric, all roles)
  • tokens — total token count (numeric)
  • date — session start date (ISO 8601, e.g. 2026-03-20)

Errors: malformed syntax or unknown key → fail with a user-readable error message.

Summary of Changes

Implemented the filter query language as a standalone module in src/filter.rs.

What was built

  • Filter type with Filter::parse(s: &str) -> Result<Filter> — hand-rolled recursive-descent parser, no new dependencies
  • SessionRow trait with fields: model, project, id, agents, messages, tokens, date
  • impl SessionRow for SessionListItem — wires to all SessionListItem fields; tokens() returns None (token count not yet tracked in that struct)
  • Filter::matches(&self, row: &R) -> bool evaluates the parsed AST against any SessionRow
  • pub use filter::Filter re-exported from src/lib.rs

Parser details

  • Tokenizer splits on whitespace; identifies AND/OR keywords and key-op-value atoms
  • Recursive descent: or_expr → and_expr ( OR and_expr )*, and_expr → primary ( AND primary )*
  • AND binds tighter than OR (standard precedence)
  • String keys (model, project, id): : only; case-insensitive substring match; * matches any non-empty
  • Numeric keys (agents, messages, tokens): : (equality), >, <
  • Date key (date): ISO 8601 YYYY-MM-DD; : (equality), >, <
  • Unknown keys and malformed syntax produce AppError::Parse with user-readable messages

Not-yet-wired fields

  • tokensSessionListItem does not carry a token count; tokens:/tokens>/tokens< always returns false until the field is added

Tests

39 new unit tests in filter::tests covering: tokenizer, atom parser, Filter::parse (valid + error cases), and Filter::matches for all key types and logical operators. All 234 project tests pass.