Files
resolutionflow/docs/superpowers/specs/2026-03-26-tasklane-improvements-design.md
2026-03-26 19:53:23 +00:00

5.2 KiB
Raw Blame History

TaskLane Improvements Design

Date: 2026-03-26 Status: Approved Scope: frontend/src/components/assistant/TaskLane.tsx, frontend/src/pages/AssistantChatPage.tsx


Context

The TaskLane is a right-side panel in the AI Assistant chat that renders structured questions and diagnostic actions from the AI. It launched with a working parse → render → submit pipeline, but has four UX issues and a missing submission flow design.

Changes

1. Progressive Preview + Batch Submit

Problem: The "Send All Responses" button is disabled until every item is answered or skipped. Engineers often want to submit partial results — answer 2 of 3 questions, paste output from 1 of 4 commands, and let the AI work with what they have.

Design:

  • Submit enabled when ≥1 item is done or skipped. Remaining pending items are simply omitted from the message (not auto-skipped — they're just not addressed).
  • Dynamic submit label: Send 2 of 6 Responses when partial, Send All Responses when all handled.
  • Collapsible preview section above the submit button:
    • Toggle: ▶ Preview (2/6 done) — collapsed by default
    • Expands to show the formatted markdown message that will be sent to the AI
    • Updates in real-time as items are answered/skipped
    • Uses the same formatting logic as handleTaskSubmit (question answers in blockquotes, command output in code fences, skipped items noted)
    • Styled as a bg-code block with font-mono text-xs, max-height ~150px with overflow scroll
  • Done items are re-editable. Clicking anywhere on a completed (green) card reopens it in active state for editing. Cards get cursor-pointer and a subtle hover state (hover:border-success/40) to signal editability. This uses the existing updateTask(idx, { state: 'active' }) mechanism — no new logic needed, just making the done card itself a click target.
  • No change to the TaskLane header or pending/active card behavior. Changes affect the footer area and done card interactivity.

Submission logic changes in TaskLane.tsx:

  • allHandled check on submit button changes from "all done/skipped" to "at least 1 done/skipped"
  • handleSubmit sends only items that have state done or skipped
  • Items still in pending or active state are excluded from the submission payload

Submission logic in AssistantChatPage.tsx (handleTaskSubmit):

  • No changes needed — it already formats based on r.state === 'done' and r.state === 'skipped', ignoring pending items.

2. TaskLane Reset on New Chat

Problem: Starting a new chat via handleNewChat doesn't clear the TaskLane. The previous session's questions/actions persist visually.

Fix: Add three lines to handleNewChat in AssistantChatPage.tsx:

setShowTaskLane(false)
setActiveQuestions([])
setActiveActions([])

Same pattern already exists in handleTaskSubmit. Also add to selectChat for switching between chats.

3. Conditional Chat Input Border

Problem: The chat input area has border-t border-border which creates a double-border effect alongside the TaskLane footer's border-t border-default.

Fix: Conditionally remove the chat input's top border when the TaskLane is open:

<div className={cn("px-3 sm:px-6 py-3 shrink-0", !showTaskLane && "border-t border-border")}>

The TaskLane's own left border and footer border provide sufficient visual separation when the panel is open. When closed, the chat input border returns.

4. Resizable TaskLane with Grip Handle

Design:

  • Drag zone: 6px wide hit target on the left edge of the TaskLane, absolutely positioned.
  • Grip indicator: Centered vertically on the drag zone — a 2×3 grid of small dots (6 dots total, w-1 h-1 rounded-full bg-current). Subtle text-muted/40 by default, text-muted-foreground on hover.
  • Resize behavior:
    • onMouseDown on the grip starts tracking
    • mousemove on document updates the width
    • mouseUp on document stops tracking
    • Width clamped between 280px min and 50vw max
    • cursor: col-resize applied to the grip and to document.body during drag (prevents cursor flicker)
    • user-select: none on document.body during drag (prevents text selection)
  • Persistence: Width saved to localStorage key rf-tasklane-width. Read on mount, written on drag end. Default: 340px.
  • Implementation: All in TaskLane.tsx — no external libraries. Uses useRef for drag state (avoids re-renders during drag), useState for the width value.

CSS change: Replace w-[340px] with style={{ width: panelWidth }} on the outer div. Keep shrink-0 so the chat area flexes.


Files Modified

File Change
frontend/src/components/assistant/TaskLane.tsx Preview section, submit logic, resize handle, width persistence
frontend/src/pages/AssistantChatPage.tsx TaskLane reset in handleNewChat/selectChat, conditional border

Out of Scope

  • TaskLane rendering when loading historical sessions (markers are stripped from stored messages — no TaskLane on reload)
  • Mobile-specific TaskLane layout (current: hidden on mobile, which is acceptable for now)
  • Keyboard accessibility for resize handle (future enhancement)