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.
2.6 KiB
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:haikumatchesclaude-haiku-4-5)key:*— field is non-emptykey>value/key<value— comparison for numeric and date fieldsAND/ORfor combining expressions- Multiple
--filterflags are ANDed together
Supported keys:
model— substring match on model nameproject— substring match on project pathid— substring match on session/agent IDagents— 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
Filtertype withFilter::parse(s: &str) -> Result<Filter>— hand-rolled recursive-descent parser, no new dependenciesSessionRowtrait with fields:model,project,id,agents,messages,tokens,dateimpl SessionRow for SessionListItem— wires to allSessionListItemfields;tokens()returnsNone(token count not yet tracked in that struct)Filter::matches(&self, row: &R) -> boolevaluates the parsed AST against anySessionRowpub use filter::Filterre-exported fromsrc/lib.rs
Parser details
- Tokenizer splits on whitespace; identifies
AND/ORkeywords 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 8601YYYY-MM-DD;:(equality),>,< - Unknown keys and malformed syntax produce
AppError::Parsewith user-readable messages
Not-yet-wired fields
tokens—SessionListItemdoes not carry a token count;tokens:/tokens>/tokens<always returnsfalseuntil 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.