Skip to content

feat(staged): surface chat updates after linked notes#681

Merged
matt2e merged 9 commits into
mainfrom
chat-includes-messages-after-note
May 18, 2026
Merged

feat(staged): surface chat updates after linked notes#681
matt2e merged 9 commits into
mainfrom
chat-includes-messages-after-note

Conversation

@matt2e
Copy link
Copy Markdown
Contributor

@matt2e matt2e commented May 4, 2026

🤖 Summary:

  • Detect whether a session has chat messages sent after a linked note was updated.
  • Surface note freshness indicators and follow-up actions across session, branch, project, note, and timeline views.
  • Add backend message counting support and focused tests for note freshness behavior.

Tests:

  • Push hooks passed: crates-fmt, crates-test, crates-lint, differ-ci, staged-ci

@matt2e matt2e requested review from baxen and wesbillman as code owners May 4, 2026 06:08
@matt2e matt2e force-pushed the chat-includes-messages-after-note branch 2 times, most recently from 3cfaae9 to 5ea1342 Compare May 11, 2026 07:04
matt2e added 5 commits May 18, 2026 11:05
Signed-off-by: Test <test@example.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
…pdatedAt missing

Resolve code review comments on 2f3ef35:

- Replace client-side fetch of all session messages in NoteModal with a
  new count_assistant_messages_after Tauri command that performs a SQL
  COUNT(role='assistant' AND created_at > timestamp) query, avoiding
  transferring the full message payload just to count.

- Change BranchTimeline noteUpdatedAt fallback from `?? 0` to
  `undefined`, so notes without a populated updatedAt field skip the
  freshness feature entirely rather than showing a misleading count.

- Update onNoteClick type signature and BranchCard handler to accept
  number | undefined for noteUpdatedAt.

Signed-off-by: Test <test@example.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
- Extract singular/plural chat button label logic from NoteModal into
  formatChatButtonLabel() in noteFreshness.ts, co-locating all
  note-freshness display logic.

- Fix recurring CTA loop: after the user clicks the note-followup
  button, the CTA would reappear because the new assistant response
  has a createdAt after the updated note's updatedAt. Now
  shouldAskForNoteUpdate checks hasNoteFollowupBeenSent() which
  detects the marker text in any prior user message, suppressing the
  CTA once a followup has already been sent.

- Refactor onNoteClick callback from 5 positional parameters to a
  single NoteClickInfo object parameter for readability and safer
  future additions.

- Add tests for formatChatButtonLabel and hasNoteFollowupBeenSent.

Signed-off-by: Test <test@example.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
…ote update

hasNoteFollowupBeenSent previously scanned all user messages in the
session, so a single earlier note-followup would suppress the CTA
forever — even after the note was successfully updated and new
assistant messages arrived.

Now the function accepts a noteUpdatedAt parameter and only considers
marker messages with createdAt > noteUpdatedAt. This allows the CTA
to reappear when the note is updated (advancing updatedAt) and
subsequent assistant turns make it stale again.

Add test covering the case where a followup sent before the note
update does not suppress the CTA.

Signed-off-by: Test <test@example.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Rebase the branch onto origin/main (now at 317e721). No new migrations
were added on main since the previous rebase — both sides still end at
0014-add-pipeline, so no renumbering was needed.

Conflict resolution:
- NoteModal.svelte / SessionModal.svelte: merge new viewport import
  (from #730 keyboard-shortcut-hints change) alongside the branch's
  noteFreshness imports.

Follow-up fixes:
- Add workingDir to the test session fixture for the field introduced on
  main during the rebase window.
- Use invokeCommand (not raw invoke) for count_assistant_messages_after
  to match the rest of the file's wrapper convention.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
@matt2e matt2e force-pushed the chat-includes-messages-after-note branch from 5ea1342 to ee8569a Compare May 18, 2026 01:16
matt2e added 4 commits May 18, 2026 14:49
The session runner re-runs note extraction at the end of every turn for
sessions with a linked note, even when the assistant didn't rewrite the
note. update_note_title_and_content (and the project-note twin) then
unconditionally wrote `updated_at = now()`, so the note's freshness
marker advanced past any new assistant messages in the same turn.

Net effect: the note-followup CTA could never trigger for follow-up
turns in the session that created the note — every chat turn invalidated
its own marker by bumping updated_at past its own message timestamps.

Fix both update_*_title_and_content methods to short-circuit when the
title, content, and suggested next steps all match the existing row.
Add a regression test for each store method covering both the no-op
path and a subsequent real change to confirm updated_at still advances
when something genuinely differs.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
@matt2e matt2e merged commit fa6c52e into main May 18, 2026
5 checks passed
@matt2e matt2e deleted the chat-includes-messages-after-note branch May 18, 2026 09:04
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