Skip to content

Context-action @-mentions are lost on a cold start (the staged note survives, the mention doesn't) #36

Description

@DaveTseng2019

What

On a cold start (no claude session running), a context action's staged .txt note survives — the attachment tray re-sends it when the CLI connects — but the at_mentioned it pushes alongside is dropped and never re-sent. The note arrives in the composer talking about code that was never mentioned.

Observed while verifying something else on #26, in the experimental hive on 18.9.12105.275 with main@1.18.1 (CLI 2.1.229). Feed from two Explains fired with nothing running:

[info] Explain: no Claude session - launching one. Staged items deliver when it connects.
[info] attach: staged 'explain-Program.cs.txt' (~29 tok) - will @-mention it when Claude connects.
[warn] Explain: Claude isn't connected.                     <- the whole-file mention, gone
[info] Launched Claude Code in VS's native Terminal window (...)
...
[info] client connected from 127.0.0.1:11208 (authorized)
[info] attach: @-mentioned '.claude/attachments/explain-Program.cs.txt' in the Claude composer.

So the composer ends up holding "Explain the file RefMaze/Program.cs (mentioned alongside this note)…" with no @Program.cs next to it.

Every action that mentions a range is affected the same way: Explain (whole file), Fix Errors (file, or the selection's line range), Generate Documentation / Add Comments (the function's span), Fix This Test (the test method's span).

Add to Chat / Alt+K is the sharpest case: it's the one action that doesn't call EnsureSessionLaunching, so with no session it neither launches nor stages anything — the click is a no-op plus a warning line. (That part is from reading ContextActions.AddToChatAsync, not something I ran.)

Why

1.18.0 made actions launch a session when none is running precisely so a click isn't wasted — but the launch takes a few seconds, and the mention is pushed immediately after it, into a socket that has no client yet. The staged note has a flush path (AttachmentService.FlushUnsentAsync on ConnectionChanged); the mention has none, so the half that carries the ground truth is the half that's lost.

Implementation notes

  • The tray already solves this shape, and Add to Chat in Solution Explorer: @-mention selected files and folders #35 leans on it: stage → chip → send, with unsent items flushed on connect and re-sendable by clicking the chip. Routing the actions' mentions through the same queue would close the gap and get click-to-re-mention for free.
  • The one thing that doesn't fit today is the line range: AttachmentItem has no lineStart/lineEnd, and SendAsync always emits a whole-file at_mentioned. Either add optional line fields to the item (and pass them through in SendAsync), or keep a small pending-mention queue next to SelectionService.MentionAsync and flush it from the same ConnectionChanged event. The first keeps one queue and one chip vocabulary; the second leaves the tray untouched.
  • Ordering matters: the note says "mentioned alongside this note", so the mention should flush after the staged .txt — the existing flush walks the tray in insertion order, which gives that for free if the mention lives in the same queue.
  • Worth deciding at the same time whether Add to Chat should launch a session like its siblings do. Once mentions survive a cold start, EnsureSessionLaunching in AddToChatAsync becomes a one-line change with the same behaviour as the rest of the flyout.

Happy to take this one if you'd like — it's adjacent to #35, and I have the cold-start repro set up.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions