Reverts port changes made during the spike back to default (3001/5173).
Adds two new stories for multi-worktree support: dynamic port management
(story 32) and worktree diff inspection with editor integration (story 33).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Proves that spawning `claude -p` in a pseudo-terminal from Rust gets Max
subscription billing (apiKeySource: "none", rateLimitType: "five_hour")
instead of per-token API charges. Concurrent agents run in parallel PTY
sessions with session resumption via --resume for multi-turn conversations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add workflow engine with acceptance gates, test recording, and review
queue. Frontend displays gate status (blocked/ready), test summaries,
failing badges, and warnings. Proceed action is disabled when gates
are not met. Includes 13 unit tests (Vitest) and 9 E2E tests
(Playwright) covering all five acceptance criteria.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fixed silent API key save failure by switching from keyring to Tauri store
- Removed keyring dependency (didn't work in macOS dev mode for unsigned apps)
- Implemented reliable cross-platform storage using tauri-plugin-store
- Added pendingMessageRef to preserve user message during API key dialog flow
- Refactored sendMessage to accept optional message parameter for retry
- Removed all debug logging and test code
- Removed unused entitlements.plist and macOS config
- API key now persists correctly between sessions
- Auto-retry after saving key works properly
Story 12 complete and archived.
The useEffect was re-running every time model changed, causing
Claude model selection to reset back to Ollama models. Fixed by:
- Removing model from useEffect dependency array
- Only run model fetch on component mount
- Check if saved model exists before loading it
- Don't reset model if it's not in Ollama list (allows Claude)
- Add Claude models to dropdown with optgroup sections
- Update context window calculation for Claude (200k tokens)
- Add API key dialog modal for first-time Claude use
- Check for API key existence before sending Claude requests
- Auto-detect provider from model name (claude-*)
- Update sendMessage to handle Claude provider
- Store and retrieve API key via backend commands
- Add visual separation between Anthropic and Ollama models
- Add anthropic.rs module with streaming support
- Convert between internal and Anthropic tool/message formats
- Add keyring dependency for secure API key storage
- Add API key management commands (get_exists, set)
- Auto-detect provider from model name (claude-* prefix)
- Support SSE streaming from Anthropic API
- Handle tool calling with Anthropic's format
- Add cancellation support for Anthropic streams
Story Updates:
- Unified model dropdown with section headers (Anthropic, Ollama)
- Auto-detect provider from model name (claude-* prefix)
- API key prompt on first Claude model use
- Secure storage in OS keychain via keyring crate
- 200k token context window for Claude models
Spec Updates (AI_INTEGRATION.md):
- Document Anthropic provider implementation
- Anthropic API protocol (SSE streaming, tool format)
- Tool format conversion between internal and Anthropic formats
- API key storage in OS keychain
- Unified dropdown UI flow
Spec Updates (STACK.md):
- Add keyring crate for secure API key storage
- Add eventsource-stream for Anthropic SSE streaming
- Document automatic provider detection
- Update API key management approach
User Story:
As a user, I want the LLM model dropdown to be alphabetically sorted
so I can quickly find the model I'm looking for.
Implementation:
- Added alphabetical sorting with case-insensitive comparison
- Used localeCompare() for proper string comparison
- Sort happens immediately after fetching models from backend
- Currently selected model remains selected after sorting
Technical Details:
- Sort logic: models.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
- Frontend-only change, no backend modifications needed
- Sorting preserves model selection state
Acceptance Criteria Met:
✅ Models sorted alphabetically (case-insensitive)
✅ Selected model remains selected after sorting
✅ Works for all models from Ollama
✅ Updates correctly when models change
Files Changed:
- src/components/Chat.tsx: Added sorting logic to model fetch
- .living_spec/stories/23_alphabetize_llm_dropdown.md: Marked complete
User Story:
As a user, I want to be able to scroll up to review previous messages
while the AI is streaming or adding new content, without being
constantly dragged back to the bottom.
Implementation:
- Replaced position-based threshold detection with user-intent tracking
- Detects when user scrolls UP and disables auto-scroll completely
- Auto-scroll only re-enables when user manually returns to bottom (<5px)
- Uses refs to track scroll position and direction for smooth operation
- Works seamlessly during rapid token streaming and tool execution
Technical Details:
- lastScrollTopRef: Tracks previous scroll position to detect direction
- userScrolledUpRef: Flag set when upward scrolling is detected
- Direct scrollTop manipulation for instant, non-fighting scroll behavior
- Threshold of 5px from absolute bottom to re-enable auto-scroll
Spec Updates:
- Added comprehensive Smart Auto-Scroll section to UI_UX.md
- Documented the problem, solution, requirements, and implementation
- Includes code examples and edge case handling
Acceptance Criteria Met:
✅ Auto-scroll disabled when scrolling up
✅ Auto-scroll resumes when returning to bottom
✅ Works normally when already at bottom
✅ Smooth detection without flickering
✅ Works during streaming and tool execution
Files Changed:
- src/components/Chat.tsx: Implemented user-intent tracking
- .living_spec/specs/functional/UI_UX.md: Added Smart Auto-Scroll spec
- .living_spec/stories/22_smart_autoscroll.md: Marked complete