* feat(web): chat history nav with ArrowUp/Down and Ctrl+R fuzzy search
ArrowUp/ArrowDown cycle the user's previous messages in the chat composer
(bash-style), Ctrl+R opens a fuzzy reverse-search overlay anchored to the
input. Opening the overlay drains the paginated message history in the
background so search covers the whole session, not only the pages already
loaded in the chat list.
* fix(web): address PR review on chat history nav (#1246)
- Always clear isDraining on cancel, error, and normal completion (cleanup
setter + try/catch/finally in the drain loop).
- Ctrl+R no longer dead-keys when the loaded history is empty: the overlay
opens unconditionally and renders "No matches" until drained pages arrive.
- Dedupe adjacent user prompts in the original message stream, not in the
extracted output, so repeated prompts separated by agent/tool turns stay
reachable from ArrowUp and Ctrl+R.
- Stabilize handleReverseSearchSelect by depending on the destructured
closeReverseSearch instead of the spread overlay object.
- HitRow key={hit.index} so React reuses rows across re-rankings.
- Reorder SSR/isOpen guards before computeStyle so window.* isn't touched
during a server render.
- Add use-drain-older-messages.test.ts covering normal drain, batch cap,
cancellation on active->false, and rejection clearing isDraining.
* fix(web): address PR feedback on chat history nav (#1246)
- writeHistoryContent wraps editor mutations in try/finally so
state.isApplying clears even if a chain or onChange handler throws.
- Dismiss the Ctrl+R overlay on window resize and capture-phase scroll so
the fixed-position portal can't drift away from the editor anchor.
- Drop the unused historyRef from useChatHistory's return value.
- Extract HitRow into message-history-search-row.tsx so the search file
stays under the 200-line cap.
* fix(web): keep Ctrl+R overlay open during keyboard navigation (#1246)
- Drop capture:true on the window scroll listener so scrollIntoView inside
the overlay's own result list (triggered by keyboard navigation past the
visible window) no longer dismisses the overlay.
- Remove the always-true isOpen prop and the unreachable guard from
MessageHistorySearch; visibility is controlled solely by the parent's
conditional render.
---------
Co-authored-by: Kandev Agent <agent@kandev.dev>
* feat(web): @-mention tasks in the chat composer
Lets users type @<taskname> in the chat input to reference other tasks.
The picked task is inserted as a chip and its metadata (id, workflow_id,
step, state) is appended to the prompt as a <kandev-system> block so the
agent can act on it via the kandev MCP tools.
Extends the existing TipTap mention extension with a new "task" kind;
task data comes from the kanban store (current workflow + visited
kanbanMulti snapshots), so no backend changes are needed.
* fix(web): harden task @-mentions from review feedback (#963)
- Sanitize interpolated task strings (title, id, workflow_id, step,
state) before they land in the <kandev-system> block so a hostile
task title (e.g. from Jira/Linear sync) can't terminate the block
early via embedded newlines or angle brackets.
- Expand the task-mentions context block on the onSend code path too
(used by preview-session-tabs), which was silently dropping the
agent-facing task context when chips were present in the editor.
- Deduplicate task mentions by taskId in getTaskMentions so mentioning
the same task twice no longer produces redundant lines.
- Skip stale state.kanban.tasks entries whose workflowStepId isn't in
the current workflow's steps to prevent tagging them with the wrong
workflow_id.
* fix(web): skip task mentions missing workflowId or workflowStepId (#963)
CodeRabbit flagged that getTaskMentions was filling missing
workflowId / workflowStepId with empty strings, propagating malformed
metadata into the prompt block. Skip such nodes during extraction.
---------
Co-authored-by: Kandev Agent <agent@kandev.dev>