Skip to content

feat(categories): support field-scoped regex rules on master - #952

Open
TimeToBuildBob wants to merge 3 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/select-keys-category-rules
Open

feat(categories): support field-scoped regex rules on master#952
TimeToBuildBob wants to merge 3 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/select-keys-category-rules

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Problem

Category regex rules on the default branch match the whole bucket-specific event string, so users cannot distinguish fields such as app and title.

Both query engines already honor select_keys:

This PR is the webui half — serialize the field and expose it in the editor.

Change

  • Add optional select_keys to category regex rules and preserve it in categorize() query JSON.
  • Let the category editor select app and title; a blank selection keeps the legacy unrestricted behavior.
  • Make client-side classification, timeline filtering/coloring, and rule labels honor explicit field selections.
  • Normalize empty/duplicate lists so the Rust parser never receives invalid select_keys: [] (Python treats [] as falsy and would fall back to all fields).
  • Preserve legacy bucket-specific and cross-field regex behavior when select_keys is absent.

This ports the feature previously merged into the non-default vue3 branch in #840 to the current master implementation.

Tests

  • npm test -- --runInBand — 33 suites, 249 tests, 3 snapshots passed
  • touched-file npm run lint -- --no-fix ... — clean
  • tsc --noEmit -p tsconfig.json — clean
  • pre-commit hooks — clean

Out of scope

Browser URL and editor project/workspace targeting remain separate because those fields do not currently flow through the server-backed canonical categorized event stream.

Refs #823

Category regex rules can now target explicit event fields (app, title,
url) instead of matching every string. The editor exposes field
checkboxes; omitted select_keys keeps the legacy all-string-fields
behavior. Query serialization, client-side matching, and timeline
coloring honor the same field list.

Rust query-engine parity already landed in aw-server-rust#605.
Does not open a PR while this fork already has three open aw-webui PRs.

Refs: ActivityWatch#823
Git-Session-Id: 9e7d
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.79592% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.30%. Comparing base (13a9428) to head (0029ecd).

Files with missing lines Patch % Lines
src/util/color.ts 0.00% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #952      +/-   ##
==========================================
+ Coverage   49.55%   50.30%   +0.75%     
==========================================
  Files          45       45              
  Lines        2779     2817      +38     
  Branches      596      640      +44     
==========================================
+ Hits         1377     1417      +40     
+ Misses       1381     1320      -61     
- Partials       21       80      +59     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps

greptile-apps Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds field-scoped category regex rules while retaining unrestricted matching when no fields are selected.

  • Adds app and title field selection to the category editor.
  • Preserves and normalizes select_keys through presets, persistence, query serialization, client-side classification, timeline filtering, coloring, and labels.
  • Adds focused coverage for normalization, preset parsing, queries, editor behavior, and category matching.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported preset parsing path now preserves normalized field selections through downstream categorization flows.

Important Files Changed

Filename Overview
src/util/presetCategories.ts Preset parsing now retains valid, normalized field selections, completing the previously missing propagation step.
src/util/classes.ts Extends category rule types and matching helpers to normalize and honor explicit event-field selections.
src/components/CategoryEditModal.vue Adds field-selection controls and safely maps blank selections back to legacy unrestricted rules.
src/queries.ts Extends the serialized category-rule shape to include case and field-selection metadata.
src/util/color.ts Supplies complete event data when matching category colors so field scope is respected.
src/views/Timeline.vue Supplies complete event data to category filtering so explicit field selections affect timeline results.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  E[Category editor or preset] --> N[Normalize select_keys]
  N --> S[Stored active category rules]
  S --> Q[Categorize query JSON]
  S --> C[Client-side matching]
  Q --> A[Server-categorized events]
  C --> T[Timeline filtering and coloring]
Loading

Reviews (2): Last reviewed commit: "fix(categories): preserve select_keys in..." | Re-trigger Greptile

Comment thread src/util/classes.ts
Preset regex rules dropped field scope, so embedder-supplied
select_keys silently matched every string field.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@ErikBjare

Copy link
Copy Markdown
Member

@TimeToBuildBob What about support for it in aw-server-python?

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Already there — Python was the original; rust #605 was the parity catch-up.

aw-server (python) uses aw-core:

  • aw_transform/classify.py Rule has read select_keys since 2019 (d2c95e9, your commit)
  • q2_categorize / q2_tag pass the rule dict through unchanged

This PR puts select_keys on the categorize() query JSON, so both servers honor field-scoped rules. No Python backend PR needed.

One semantic difference, already guarded here:

  • rust: select_keys: [] is a parse error
  • python: empty list is falsy → matches every string field
  • normalizeSelectKeys omits empty/duplicate lists, so we never send []

Verified against current aw-core: title-only "test" matches {app: terminal, title: just a test}; app-only does not. Python still has no dedicated select_keys tests — not a blocker for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants