* 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>
* feat: extend implement plan button with fresh-agent path and server-side plan mode
- Split-button: primary click = same-session, chevron = fresh agent with clean context window
- Forward draft attachments and context files on implement (adds getAttachments() to handle)
- Authoritatively clear plan_mode via new session.set_plan_mode WS endpoint, not a message flag
- Add on_exit:disable_plan_mode to plan-and-build.yml plan step (mirrors feature-dev.yml)
- Drop localStorage plan-mode rehydration; server session metadata is the single source of truth
- Delete dead DocumentPanel component (no callers)
- Add SetSessionPlanModeByID on orchestrator Service; wire wsSetPlanMode handler
* test: fix store isolation in useImplementFresh test + extract duplicate strings
- Fix test isolation: reset store directly and clear mocks before rendering
- Extract sessionId, appFilePath, appFileName to constants to fix ESLint duplicate-string warnings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* test(e2e): cover implement-plan fresh-agent split-button path
Adds Playwright coverage for the new chevron menu on the violet Implement
button: asserts a brand-new TaskSession is launched on the same task with
the planning session's agent profile inherited, and that the planning
session is left running in parallel. Second spec verifies the split-button
is gated behind plan mode.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: defer plan-mode exit and surface error toast on implement failures
Move handlePlanModeChange(false) into the message.add success callback in
useImplementPlan so a failed send leaves the plan layout intact for retry.
Add error toast to useImplementFresh catch so launchSession failures are
visible to the user instead of silently logged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: guard fresh-agent launch on planning session executor_id
TaskSession.executor_id is optional, so the fresh-agent path could call
launchSession with an undefined executor and silently inherit the
workspace default instead of the planning session's executor. Add the
field to the early-return guard so the hook no-ops when the planning
session is missing either an agent profile or an executor.
* feat: mark fresh-agent session as primary and focus it
When useImplementFresh launches a new implementation session, the fresh
session is now automatically:
1. Set as primary via session.set_primary WS endpoint
2. Focused/selected as the active session in the UI
This improves UX by switching the focus to the fresh implementation context
immediately rather than keeping the planning session active.
Addresses comment in PR #832 from carlosflorencio.
- Extract setupFreshSession helper to keep complexity under 15
- Add tests for primary session marking and UI focus
- Add test for graceful handling of set_primary failures
- Update JSDoc to document the new behavior
- Extract test constants to avoid duplicate string warnings
* fix(test): replace self-referential test constants
`const TASK_ID = TASK_ID;` (and SESS_PLAN, SESS_FRESH) caused a TDZ
ReferenceError at module load, so vitest reported `(0 test)` and none of
the new fresh-agent coverage actually ran. Replace with literal values
so the 13 tests in this file execute again.
* fix: drop strict executor_id guard and skip composer clear on missing session_id
Two related issues:
1. e2e regression — the planning session in the FE store does not always
carry executor_id (the field is omitempty on the backend DTO and isn't
populated for fresh task sessions in the WS push path). The earlier
guard required it before calling launchSession, so the fresh-agent
path silently no-op'd in real flows. Drop executor_id from the guard
and only forward it when set; backend resolves it from the agent
profile / workspace default when omitted.
2. PR review (Greptile P1) — when launchSession resolves without a
session_id, the previous flow still cleared the composer and draft
even though no fresh session was activated. Bail out before the
clear so the user keeps their typed text and can retry.
Tests updated:
- replace the no-op-on-missing-executor test with one that asserts the
hook still launches and omits the key from the payload
- add coverage for the no-session_id branch keeping the composer intact
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>