Common Argument Library — Saved Collections

  • Route: /research/cards/argument-library
  • Package: debate-search-evidence

What it shows

ArgumentLibraryPanel's tag-chip filter bar now has a Saved collections section beneath it, shown whenever the library has at least one tag collection:

  • Every saved collection renders as a button (its name plus tag count) — clicking it replaces the current tag-chip selection with that collection's saved tags, next to "Rename", "Update" (shown once at least one tag is active — replaces the collection's tags with the current selection), and a small "✕" remove button.
  • "Rename" swaps the button for a text field; renaming onto another saved collection's name is refused (case-insensitively) rather than merging.
  • A "Save current selection as" field + "Save collection" button saves the currently active tag chips under a new name. Disabled until at least one tag is selected and a name is typed.

Data flow

lib/argument-library-collections.ts (pure validation/(de)serialization)
  → lib/argument-library-collections-client.ts (GET/PUT /api/settings)
  → hooks/useSavedArgumentCollections.ts (localStorage: saved-argument-collections)
  → panels/ArgumentLibraryPanel.tsx

Local-first (works fully signed out) and best-effort account-synced through the same /api/settings row every other picker-style setting uses. Up to 50 collections, each name unique case-insensitively, each holding 1-30 tags.

Known gaps

None open. A saved collection can be renamed ("Rename" next to its button) and have its tag list replaced with the current selection ("Update", shown once at least one tag is active) — both close the two gaps this page previously tracked. The lost-update race this page used to track — a rename/update/add/remove from two signed-in devices at once silently dropping whichever PUT landed second, since the whole savedArgumentCollections list was a single account-settings field — is also fixed: every code path that changes a collection (addCollection/removeCollection/renameCollection/updateCollection in useSavedArgumentCollections.ts) now sends a single addSavedArgumentCollection/removeSavedArgumentCollection/ renameSavedArgumentCollection/updateSavedArgumentCollectionTags op instead, resolved by /api/settings against the account's row as it stands at write time rather than a client-computed whole-list replace — mirroring User Settings's favoriteTools fix. A plain whole-list savedArgumentCollections replace is still accepted by the route for a caller that genuinely needs one, but nothing in the app sends one anymore.