Skip to content

feat(memories): match desktop category filter to mobile + add Workflow category#7582

Merged
kodjima33 merged 9 commits into
mainfrom
fix/memory-categories-match-mobile
Jun 2, 2026
Merged

feat(memories): match desktop category filter to mobile + add Workflow category#7582
kodjima33 merged 9 commits into
mainfrom
fix/memory-categories-match-mobile

Conversation

@kodjima33
Copy link
Copy Markdown
Collaborator

Problem

The macOS desktop Memories filter showed a different, messier set of categories than mobile — Manual, System, Focus, Interesting, Focused, Distracted, Productivity — built from a mix of the real backend category field and ad-hoc tags (focus/focused/distracted/tips/productivity/…). Mobile only has the three real categories. The "Manual" filter also surfaced auto-extracted memories that the user never created.

Changes

Desktop now mirrors mobile — filtering is driven purely by the backend category field, no tag-derived pseudo-categories:

  • MemoryTag reduced to the real categories with mobile's exact labels: Manual, About You (system), Insights (interesting), and the new Workflow.
  • Removed Focus / Focused / Distracted / Tips / Productivity / Health / Communication / Learning / Other filters.
  • Counts and SQLite filtering now key off category only (matches mobile semantics — About You shows all system, etc.).

New Workflow category (for how the user/AI agents work — AI-agent instructions, etc.), wired end-to-end:

  • Backend: workflow added as a primary MemoryCategory (boosts + validator).
  • Desktop: MemoryCategory.workflow + filter.
  • Mobile: enum + parse + chip rendering + included in the default filter set.

Notes / follow-ups

  • This is the code half. The "Manual shows memories I didn't create" data is being cleaned separately per-account on the backend (prod already done; the dev/beta backend this desktop build uses is handled next).
  • Mobile gets the Workflow chip here; a dedicated mobile filter-sheet toggle is a fast-follow (needs an l10n key across 49 locales).

Verification

  • Desktop: xcrun swift build -c debug — clean.
  • Mobile: dart analyze on touched files — no errors.
  • Backend: syntax + black clean; CATEGORY_BOOSTS lookup guarded and updated.

🤖 Generated with Claude Code

kodjima33 and others added 7 commits June 1, 2026 15:53
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…labels

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…al/About You/Insights/Workflow)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 1, 2026

Greptile Summary

This PR aligns the desktop Memories filter with mobile by replacing the ad-hoc tag/category hybrid with pure backend category-field filtering, and introduces a new workflow category end-to-end across backend (Python), mobile (Dart/Flutter), and desktop (Swift).

  • Desktop simplification: MemoryTag is reduced to the four real backend categories (manual, system, interesting, workflow), removing Focus/Distracted/Productivity/etc. pseudo-categories; counts and SQLite queries now use category only.
  • New workflow category: wired through the backend enum, CATEGORY_BOOSTS, the validator allowlist, the Dart schema and parser, the Flutter chip widget, and the Swift API model — all with consistent display names and icons.
  • Mobile filter defaults: MemoryCategory.workflow is added to the default _selectedCategories set for first-run users, but existing users with a persisted filter list will silently miss new workflow memories.

Confidence Score: 3/5

Safe to merge on desktop and backend; mobile has a data-visibility gap for existing users whose filter was ever saved.

The category addition is mechanically clean and consistent across all three platforms. The concern is in _loadFilter(): any mobile user who previously customized their filter will have a persisted list that omits 'workflow', so new workflow memories are silently absent from their feed with no in-app signal. For fresh installs or users who never touched the filter this is a non-issue, but returning users could wonder why they aren't seeing AI-agent memories that were supposedly saved.

app/lib/providers/memories_provider.dart — the _loadFilter migration path for existing users.

Important Files Changed

Filename Overview
app/lib/providers/memories_provider.dart Adds workflow to the default filter set for new users, but existing users with a persisted filter list won't receive workflow automatically — silent exclusion of new memories.
app/lib/backend/schema/memory.dart Adds workflow to MemoryCategory enum and _parseMemoryCategory; null and unknown values still fall through to system as before.
app/lib/pages/memories/widgets/category_chip.dart Extends switch statements for workflow case (color, icon, display name); all four enum cases are exhaustively covered, but display names remain hardcoded strings.
backend/models/memories.py Adds workflow to MemoryCategory enum, CATEGORY_BOOSTS, and the validator allowlist; scoring and legacy mapping paths are unaffected and correct.
desktop/Desktop/Sources/APIClient.swift Adds workflow case to MemoryCategory with matching display name and SF Symbol; displayName and icon switch statements are now exhaustive.
desktop/Desktop/Sources/MainWindow/Pages/MemoriesPage.swift Replaces tag/category hybrid filtering with pure category-based filtering; selectedTags defaults to empty (all memories visible) so no migration issue on desktop side.
desktop/CHANGELOG.json Adds unreleased changelog entry describing the filter change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Backend: MemoryCategory enum\n+ workflow added\n+ CATEGORY_BOOSTS updated\n+ validator allowlist updated] --> B[API Response\ncategory: 'workflow']
    B --> C[Mobile: Dart _parseMemoryCategory\n'workflow' to MemoryCategory.workflow]
    B --> D[Desktop: Swift MemoryCategory\nCodable decodes 'workflow']
    C --> E[CategoryChip widget\nTeal color, account_tree icon\nWorkflow label hardcoded]
    C --> F[MemoriesProvider._loadFilter\nfresh install: all 4 categories\nexisting saved filter: workflow absent]
    D --> G[MemoryTag.workflow\nrawValue used for SQLite query]
    D --> H[MemoriesPage categoryIcon/Color\ndelegates to MemoryCategory.icon]
Loading

Comments Outside Diff (1)

  1. app/lib/providers/memories_provider.dart, line 161-164 (link)

    P1 Existing users silently miss workflow memories

    When filterList is not null (i.e. a user has previously saved a filter), the stored list was written before workflow existed and will never contain "workflow". _selectedCategories is therefore built without it, and any new workflow memories are silently filtered out for these users — with no visual indication that a category exists but is toggled off. The orElse: () => MemoryCategory.system fallback won't help because "workflow" simply isn't present in the stored list, not because it fails to parse.

    The simplest mitigation is to inject any new primary category that is absent from the stored list, preserving categories the user did explicitly turn off.

Reviews (1): Last reviewed commit: "feat(memories): note memories filter cat..." | Re-trigger Greptile

Comment on lines +63 to +65
case MemoryCategory.workflow:
displayName = "Workflow";
break;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Hardcoded user-facing strings without l10n

"Workflow" (and the other display names "About You", "Insights", "Manual") are hardcoded strings rather than localisation keys. The project's flutter-localization rule requires all user-facing strings to go through l10n. The PR description flags a dedicated mobile filter-sheet l10n key as a fast-follow, but the chip label itself also needs a key before these strings appear in the 49 non-English locales.

Context Used: Flutter localization - all user-facing strings mus... (source)

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!

kodjima33 and others added 2 commits June 2, 2026 12:03
Re-pulls all backend memories (fixing stale categories after the server-side
category cleanup) and soft-deletes local synced rows the backend no longer has,
so Manual reflects only what the user actually created. Runs once per user and
guards against pruning on a failed/empty pull. Adds MemoryStorage.softDeleteSyncedOrphans.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kodjima33 kodjima33 merged commit d739e13 into main Jun 2, 2026
1 check passed
@kodjima33 kodjima33 deleted the fix/memory-categories-match-mobile branch June 2, 2026 16:37
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.

1 participant