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

96 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`:
```typescript
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:
```tsx
<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)