Commit Graph

2 Commits

Author SHA1 Message Date
Diogo Soares Rodrigues c7c375f5e1 fix(cursor): settle todo cards whose completion outruns the streamed block
When Cursor packs toolCallStarted and toolCallCompleted into one HTTP/2
chunk, the bridge tool_execution_end (synchronous callback, fired
mid-parse) reaches the interactive controller before the streamed
toolcall_start (queued on AssistantMessageEventStream, delivered a
microtask later). The controller found no pendingTools entry, dropped
the completion, and the card created afterwards animated forever.

Two halves, each necessary:

- Hold an early todo completion in #orphanedToolCompletions and replay
  it when the streamed block creates its component.
- Guard card creation from cumulative message_update frames with the
  turn-scoped #toolTimelineComponents map. Without this, the update
  after the replay re-lists the same toolCall block, finds pendingTools
  empty again, and spawns a second, permanently pending card. This is
  also why emitting a synthetic tool_execution_start from the bridge
  (previous attempt, reverted) could not work.

Both maps are cleared together at the existing transcript-anchor reset
sites. The normal ordering (start first) is covered by a control test.
2026-07-26 09:29:13 -03:00
Diogo Soares Rodrigues cc210094ef fix(cursor): refuse todo dependency graphs and sanitize failure text
Two review findings on the native todo sync.

- TodoItem.dependencies is a graph the local model cannot store: rows
  are keyed by content, carry no id, and hold no edges. An imported
  dependent row files as plain pending and nextActionableTask then
  offers work the server considers blocked. Refuse snapshots with an
  edge pointing at an unfinished row; edges whose blockers already
  finished constrain nothing and still mirror.

- The todo failure warning interpolated the provider error verbatim.
  Collapse and truncate it at the render boundary.

Also documents two known, unfixed defects: an async cursorOnToolResult
transformer resolving after the buffer drain, and the todo card
lifecycle race. Emitting a synthetic tool_execution_start for the
latter was measured and rejected -- the completion deletes the entry it
creates, so the late streamed block adds a second card.
2026-07-26 09:29:13 -03:00