Skip to content

fix(extension): stop fragmenting Included Memories that contain commas or newlines#1339

Open
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/extension-included-memories-comma-split
Open

fix(extension): stop fragmenting Included Memories that contain commas or newlines#1339
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/extension-included-memories-comma-split

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

Follow-up to #1261, rebuilt to stay within the current architecture. That PR was closed because it changed the shared GET_RELATED_MEMORIES response format and regressed auto-recall. This version does not touch that contract at all. It fixes only the one data-handling bug from #1257 that survived the memory-suggestion.ts refactor, and it does so entirely inside the popup's own display data.

The bug

The Included Memories popup stores the memory list on a data-* attribute by joining it into one string, then reads it back by splitting on [,\n]:

  • store: iconElement.dataset.memoriesData = String(response.data) (chatgpt.ts, claude.ts, gemini.ts) and = response.data (t3.ts)
  • read: memories.split(/[,\n]/) in showMarkerPopover (memory-suggestion.ts) and in T3's popup list and delete handler

Memory text is free-form and regularly contains commas and newlines, so one memory gets shredded into several rows. For example "Lives in Austin, Texas" shows as two entries. In T3 it is worse than cosmetic: the per-item delete indexes into that split list, so removing an entry splices the wrong item and then rewrites the injected prompt from the mangled result.

The fix

Store the list as JSON on the attribute and parse it back, so a memory with a comma or newline round-trips as a single item:

  • serializeMemoriesForDataset(memories) — JSON, returns "" for an empty list so the existing "are there memories" truthiness checks on the attribute keep working unchanged.
  • parseMemoriesFromDataset(raw) — parses the JSON, and falls back to the legacy [,\n] split for any value written by older code, so nothing breaks on upgrade.

Applied consistently across all four consumers (ChatGPT, Claude, Gemini, T3).

Why this preserves the contract

The change is confined to dataset.memoriesData, which only feeds the popup UI. The GET_RELATED_MEMORIES message is untouched (still an array of raw strings), and the injected dataset.supermemories prompt text is byte-for-byte the same as before (T3's initial injection still uses ${response.data}, and its delete-path re-injection still uses the same joined form). So what the model sees, and therefore recall behaviour, does not change.

Tests

memory-suggestion.test.ts (bun:test, following search-request.test.ts) covers the round-trip: comma-bearing and newline-bearing memories stay single items, trimming/empty handling, empty-list serializes to "", and the legacy-split fallback. 7 tests pass. Extension tsc is clean for these files (the remaining new_logo.png getURL overload errors are pre-existing on main). cc @ishaanxgupta

…ines

The Included Memories popup stores the memory list on a data-* attribute by
joining it into a single string (String(response.data) / response.data), then
reads it back by splitting on [,\n] in showMarkerPopover and in the T3 popup.
Memory text is free-form and frequently contains commas and newlines, so a
single memory was fragmented into several rows. In T3 that also desynced the
per-item delete: the clicked index no longer mapped to a real memory, so
removal spliced the wrong entry and rewrote the injected prompt from the
mangled list.

Store the list as JSON on the attribute and parse it back, so a memory with a
comma or newline survives as one item. serializeMemoriesForDataset returns an
empty string for an empty list so existing "memories present" truthiness checks
on the attribute are unchanged, and parseMemoriesFromDataset falls back to the
old delimiter split for any legacy value. This is confined to the popup's own
display data: the GET_RELATED_MEMORIES response and the injected
dataset.supermemories prompt text are left exactly as they were, so recall
behaviour does not change. Applied consistently across ChatGPT, Claude, Gemini
and T3, with unit tests for the round-trip.
Copilot AI review requested due to automatic review settings July 22, 2026 15:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

extension related to Supermemory Chrome Extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants