feat(categories): support force_active preset flag to override stored set selection - #973
feat(categories): support force_active preset flag to override stored set selection#973TimeToBuildBob wants to merge 2 commits into
Conversation
… set selection Builds that ship AW_PRESET_CATEGORY_SETS can now mark a preset as force_active: true to ensure the preset is activated even when the user has existing stored category sets (e.g. the built-in 'default' set from a prior AW install). Without this, a managed or research build that injects a preset taxonomy via AW_PRESET_CATEGORY_SETS would only activate the preset on a fresh install (the !hasStoredCategories branch in loadCategories). Any participant who had ActivityWatch before the build was deployed would see the research-study set appear in the set-picker but remain inactive — their stored 'default' selection taking precedence silently. Changes: - Add force_active?: boolean to CategorySet interface (classes.ts) - In loadCategories(), check for a force_active preset before deciding which sets to activate in the stored-sets branch (classes.ts) - parseSet() in presetCategories.ts now propagates force_active: true - The getPresetCategorySets() deep-copy now includes force_active so the flag survives the cache copy step - Unit tests cover: parser propagation, fresh-install activation, existing-install override, and non-force_active unchanged behaviour Git-Session-Id: 1e9e
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #973 +/- ##
==========================================
+ Coverage 52.25% 52.43% +0.17%
==========================================
Files 48 48
Lines 2943 2954 +11
Branches 692 698 +6
==========================================
+ Hits 1538 1549 +11
Misses 1385 1385
Partials 20 20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| // not just fresh ones. We only honour force_active on presets delivered | ||
| // via AW_PRESET_CATEGORY_SETS (getPresetCategorySets()), never on stored sets | ||
| // — user edits stored under the same id still win over the preset definition. | ||
| const forceActivePreset = presets.find(p => p.force_active); |
There was a problem hiding this comment.
Forced preset skipped initially
When a fresh install receives multiple presets and the force_active preset is not first, the forced-preset lookup is only honored in the stored-sets branch. The fresh-install branch still activates presets[0], so the managed taxonomy remains inactive despite being marked force_active.
There was a problem hiding this comment.
Fixed in 076a95a: the fresh-install branch now checks forceActivePreset first and only falls back to presets[0] when none is present. Added regression test force_active preset wins on fresh install even when it is not presets[0].
| } | ||
| return { id: raw.id, categories }; | ||
| const set: CategorySet = { id: raw.id, categories }; | ||
| if (raw.force_active === true) set.force_active = true; |
There was a problem hiding this comment.
Multiple forced presets ambiguous
If a configuration marks multiple presets as force_active, the parser accepts all of them while activation silently chooses the first match. This makes the selected taxonomy depend on array order and can unexpectedly override the user's stored selection without any validation or warning; the configuration should be rejected or clearly diagnosed.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Fixed in 076a95a: loadCategories() now collects all force_active presets with .filter(), emits a console.warn listing their ids when there are more than one, then takes the first. Ambiguous configs are diagnosable without silent override.
|
CI-green and mergeable — 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. |
…ultiple force_active presets P1 (Greptile): when a fresh install receives multiple presets and the force_active preset is not first in the array, loadCategories() was activating presets[0] unconditionally — force_active was only honoured in the stored-sets branch. Now both branches prefer forceActivePreset when present. P2 (Greptile): multiple force_active presets were silently accepted and the first match was used without any diagnostic. Now emits a console.warn listing the conflicting ids so misconfigured managed builds surface the error immediately. Tests: 2 new — force_active wins on fresh install even when not presets[0]; warn + first-wins on multiple force_active presets. All 46 pass.
|
@greptileai review |
|
@TimeToBuildBob I merged #974, what to do here? |
|
#974 and #973 solve different sub-problems:
After #974, users with no real edits get the preset automatically. Users with real edits still won't see it — Recommendation: if the Research Edition only needs to activate the taxonomy for users whose stored data was install-defaults (fixed by #974), close this PR as superseded. If you foresee needing the explicit override for managed/controlled deployments, I can rebase this onto master (the conflict is small — both PRs touch Which way do you want to go? |
|
@TimeToBuildBob i closed this, idk if it was right |
|
Closing was right for now. #974 already handles the practical case: it distinguishes "auto-saved install defaults" from genuine user edits, so presets activate correctly for research participants who happened to save settings before the build deployed. #973's |
Problem
When a build ships a preset category set via
AW_PRESET_CATEGORY_SETS, the preset is only activated on a fresh install — users who had ActivityWatch before the build was deployed never see the preset activated.loadCategories()takes thestoredSets && storedSets.length > 0branch, which preserves whateveractive_set_idswere stored (['default']), and skips the preset-activation path entirely.This matters for research builds and managed deployments where a specific taxonomy must be active regardless of prior install state.
Solution
Add an optional
force_active?: booleanfield toCategorySet. When a preset hasforce_active: true,loadCategories()activates it even when the user has stored sets.[{ "id": "research-study", "force_active": true, "categories": [...] }]Invariants preserved
getPresetCategorySets()(build-time env var) can useforce_active. A stored set cannot force-activate itself.force_activepreset is activated (same as the first-run path), sosyncToPrimarySet()can write user edits back correctly.force_activepreset exists, behaviour is identical to before.getPresetCategorySets()'s deep-copy — it previously strippedforce_activefrom the returned objects because the copy only included{ id, categories }.Changes
src/util/classes.ts: Addforce_active?: booleantoCategorySetinterface; check for force-active preset before restoring storedactive_set_idssrc/util/presetCategories.ts: Parse and propagateforce_active: trueinparseSet(); preserve the flag in thegetPresetCategorySets()copytest/unit/presetCategories.test.node.ts: 6 new tests covering parser propagation, fresh-install activation, existing-install override, and non-force-active unchanged behaviour