Compare commits

..

24 Commits

Author SHA1 Message Date
10d95951a3 feat: implement QoL features (toast notifications, command palette, auto-save)
Add three major quality-of-life features to improve user experience:

Toast Notification System:
- Non-blocking notifications for all major actions
- Four variants: success, error, warning, info
- Auto-dismiss with progress bar
- Bottom-right positioning with smooth animations
- Replaced old status messages throughout the app

Command Palette (Ctrl+P):
- Keyboard-driven quick access to all actions
- 14 built-in commands across 5 categories
- Real-time fuzzy search with arrow key navigation
- Shows keyboard shortcuts for each command
- Grouped by category with visual feedback

Auto-save & Recovery:
- Automatic draft saving (1s debounce)
- Per-character draft storage in localStorage
- Auto-recovery on app restart or character switch
- Draft age display (e.g., "2 hours ago")
- Auto-cleanup of drafts older than 7 days
- Clears draft when message is sent

Updated README with new Ctrl+P keyboard shortcut
Updated ROADMAP with Phase 8: Quality of Life & Polish section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 12:27:20 -07:00
50d3177e9e feat: implement chat branching and checkpoints
Add conversation branching system that allows creating and exploring alternate conversation paths from any message point. Each branch maintains its own complete message history.

Backend (Rust):
- Branch data structures with backward-compatible storage migration
- Tauri commands for create, switch, delete, rename, and list operations
- Automatic cleanup of child branches when parent is deleted

Frontend:
- Branch button on all messages for creating new branches
- Branch indicator badge in header showing active branch
- Branch manager modal with full branch list and controls
- Visual improvements to message action toolbar (more opaque, positioned above messages)

Branches are character-specific and persist across sessions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 08:17:08 -07:00
86a9d54e70 feat: replace character creation prompts with themed modal
Replace native prompt() dialogs with a themed inline form modal for character creation:
- Modal displays with name input and system prompt textarea
- Includes Cancel and Create buttons
- Escape key closes the modal
- Auto-focuses name input when opened
- Proper event listener cleanup
- Matches existing UI theme and styling

This provides a much better user experience with the application's dark theme, compared to the browser's default prompt dialogs which looked out of place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:28:42 -07:00
600b50f239 feat: add active features indicator badges in header
Add visual badges in header showing which roleplay features are currently active:
- World Info: Shows count of enabled entries (e.g., "WI: 3")
- Persona: Shows persona name when enabled
- Preset: Shows active preset name
- Examples: Shows when message examples are enabled
- Author's Note: Shows when author's note is enabled (displays as "A/N")

Badges update dynamically when features are toggled, providing at-a-glance visibility of active roleplay features without opening the Roleplay Tools panel.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:26:39 -07:00
a7c9657ff1 feat: make context limit configurable in API settings
Add context limit field to API settings that:
- Stores context limit in config (defaults to 200000)
- Allows users to set custom limits for different models
- Uses configured limit in token counter display
- Shows format like "2.5k / 200k tokens" using actual limit

This allows proper token tracking for non-Claude models with
different context windows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:20:13 -07:00
e47bd3bf87 refactor: remove color coding from token counter
Keep simple clean format: '2.5k / 200k tokens' without color changes
2025-10-16 22:16:25 -07:00
41437e1751 feat: make token counter visible by default with color coding
Changes:
- Remove display:none from token counter (always visible)
- Add compact formatting (2.5k / 200k tokens instead of 2500 tokens)
- Color coding based on usage percentage:
  - Green: < 50% usage
  - Yellow: 50-80% usage
  - Red: > 80% usage
- Keep counter visible even on error (shows 0 / 200k)
- Improve discoverability of token tracking feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:13:15 -07:00
8c70e0558f feat: add keyboard shortcuts and copy message buttons
Keyboard shortcuts:
- Up Arrow: Edit last user message (when input at start)
- Left/Right Arrow: Navigate swipes (when not in input)
- Escape: Close panels/modals, cancel editing
- Ctrl+K: Focus message input
- Ctrl+/: Toggle Roleplay Tools
- Ctrl+Enter: Send message (alternative)

Message controls:
- Add Copy Message button for both user and assistant messages
- Visual feedback (checkmark) after copying
- 2-second feedback duration

Updated README to reflect actual implemented shortcuts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:12:14 -07:00
0bd1590681 feat: replace preset prompts with inline forms
Replace popup dialogs with themed inline forms for preset creation and
duplication. Both operations now use consistent UI styling with proper
theme colors, validation, and cancel/save workflows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 22:03:37 -07:00
26d1430d6a feat: replace popup dialogs with inline editing for World Info and Instructions
Replaced all prompt() dialogs with themed inline forms for better UX:
- World Info entries now have inline add/edit forms
- Instruction blocks now have inline add/edit forms
- Forms match app theme and stay within the interface
- Added CSS styling for edit forms

Still using prompts for preset creation/duplication - will replace in next commit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:54:28 -07:00
bc05747f5f fix: add proper theming for preset textareas
Fixed black text on white background in preset system additions and authors note textareas by adding CSS rules with !important to override inline styles.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:46:43 -07:00
71bac12cd9 docs: rewrite README to be more concise and professional
Removed excessive emojis, marketing fluff, and outdated information. Updated to reflect actually implemented features and current development focus.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:37:39 -07:00
9da17c824d docs: update roadmap to mark message examples as complete
Updated current focus to Chat Branching/Checkpoints as next feature. Added Message Examples and Token Counter to implemented features list.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:34:45 -07:00
d8cb4a768b feat: implement message examples usage from character cards
Add support for using mes_example field from character cards to teach the AI the character's voice and writing style. Examples are parsed, processed with template variable replacement, and injected into the context at a configurable position.

Backend changes:
- Extended RoleplaySettings with examples_enabled and examples_position fields
- Implemented parse_message_examples() to parse <START>-delimited example blocks
- Added example injection in build_api_messages() with position control
- Integrated examples into token counter with accurate counting
- Created update_examples_settings command for saving settings

Frontend changes:
- Added Message Examples UI controls in Author's Note tab
- Checkbox to enable/disable examples
- Dropdown to select injection position (after_system/before_history)
- Save button with success/error feedback
- Token breakdown now shows examples token count
- Settings load/save integrated with roleplay panel

Message examples help the AI understand character personality, speaking patterns, and response style by providing concrete examples of how the character should respond.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:33:50 -07:00
b9230772ed feat: implement enhanced message controls with regenerate any message
Added comprehensive message control features for fine-grained conversation management:

Backend (Rust):
- Extended Message struct with 'pinned' and 'hidden' boolean fields
- Added delete_message_at_index() command for removing any message
- Added toggle_message_pin() command to mark important messages
- Added toggle_message_hidden() command to temporarily hide messages
- Added continue_message() command to append AI continuations
- Added regenerate_at_index() command to regenerate ANY message (not just last)

Frontend (JavaScript):
- Added delete, pin, hide buttons to all messages (user & assistant)
- Added continue button for assistant messages
- Updated regenerate to work on any message, not just the last one
- Implemented state persistence for pinned/hidden in chat history
- Added dynamic icon changes for hide/unhide states
- Integrated with token counter for real-time updates

UI/UX (CSS):
- Pinned messages: accent-colored left border with glow effect
- Hidden messages: 40% opacity with blur effect (70% on hover)
- Delete button: red hover warning (#ef4444)
- Active state indicators for pin/hide buttons
- Always-visible controls on hidden messages for quick access

Features:
- Delete any message with confirmation dialog
- Pin messages to always keep them in context
- Hide messages with visual blur (still in context but dimmed)
- Continue incomplete assistant responses
- Regenerate any assistant message (creates new swipe)
- All states persist in chat history JSON

This completes Phase 3.2 "Enhanced Message Controls" from the roadmap,
providing users with complete control over their conversation history.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 17:19:07 -07:00
9b4bc63e1a fix: use theme CSS variables for user messages
User messages were using hard-coded indigo colors instead of respecting
the selected theme. Now properly uses:
- var(--accent) for gradient start
- var(--user-msg) for gradient end
- Dynamic box-shadow based on theme color

This ensures user messages match the selected theme (Dark, Light, Abyss,
Nord, Mocha, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 13:26:39 -07:00
501f226542 chore: update Cargo.lock for tiktoken-rs dependency 2025-10-16 13:25:02 -07:00
2444ca0811 feat: implement token counter with real-time breakdown
Add comprehensive token counting functionality to provide visibility into
context usage:

Backend (Rust):
- Add tiktoken-rs dependency for OpenAI-compatible token counting
- Implement get_token_count command with detailed breakdown
- Count tokens for: system prompt, preset instructions, persona, world info,
  author's note, message history, and current input
- Per-section token breakdown for optimization insights

Frontend (JavaScript/HTML/CSS):
- Add token counter widget in status bar
- Real-time updates as user types (debounced 300ms)
- Expandable breakdown tooltip showing per-section counts
- Automatic update when chat history loads or changes
- Clean, minimal UI with hover interactions

Features:
- Accurate token counting using cl100k_base tokenizer
- Debounced updates for performance
- Detailed breakdown by context section
- Visual indicator with total token count
- Click to expand/collapse detailed breakdown
- Auto-hide when no character is active

This completes the "Must-Have for Basic Roleplay" features from the roadmap:
 World Info/Lorebooks
 Author's Note
 Token Counter
- Message Examples Usage (next)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 13:24:49 -07:00
828475ae4f feat: make built-in presets editable with restore-to-default
Add ability to edit built-in presets (Default, Roleplay, Creative Writing,
Assistant) while preserving original defaults:

- Built-in presets are now fully editable (system additions, author's note,
  instruction blocks)
- Modifications are saved as overrides in ~/.config/claudia/presets/
- "Modified" badge appears when built-in preset has been customized
- "Restore to Default" button removes overrides and restores originals
- Backend commands: is_builtin_preset_modified, restore_builtin_preset
- All instruction blocks support expand/collapse and drag-and-drop reordering

Also update ROADMAP.md to reflect completed features:
- World Info/Lorebook System 
- Author's Note 
- User Personas 
- Regex Scripts 
- Chat History Import/Export 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 13:19:43 -07:00
cdb7baa197 feat: enhance roleplay features with regex, exports, and validation
This commit implements Options B, C, and D for enhanced roleplay capabilities:

**Option B: Enhanced Roleplay Features**
- Add regex pattern matching for World Info keywords with fallback to literal matching
- Make scan depth configurable (default: 20, range: 1-100 messages)
- Make Author's Note insertion depth configurable (default: 3, range: 1-50 messages)
- Add World Info import/export functionality with merge/replace options
- Update WorldInfoEntry struct with use_regex field
- Update RoleplaySettings with scan_depth and authors_note_depth fields
- Modify build_roleplay_context() to return configurable note_depth
- Update all 4 chat functions to use configurable Author's Note depth

**Option C: Chat Export Enhancements**
- Add export_chat_as_markdown: Clean markdown format with bold role labels
- Add export_chat_as_text: Simple plain text format with decorative separator
- Add export_chat_as_html: Styled HTML with responsive design and color-coded messages
- All exports use native file dialogs with appropriate file filters

**Option D: Polish & Quality of Life**
- Add validate_regex_pattern command for real-time regex validation
- Add update_roleplay_depths command with range validation
- Enhance add_world_info_entry with input validation (regex, empty checks)
- Enhance update_world_info_entry with input validation
- Add detailed error messages for all validation failures

**Technical Details:**
- Add regex dependency to Cargo.toml
- Use #[serde(default)] attributes for backward compatibility
- Graceful error handling with fallback strategies
- HTML export includes proper escaping for XSS protection
- All new commands registered in Tauri invoke_handler

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 17:01:16 -07:00
9707121a59 feat: implement Phase 2 roleplay context injection
Add full context injection system for World Info, Author's Note, and Persona:

- Add scan_for_world_info() function to detect keywords in last 20 messages
- Add build_roleplay_context() to assemble all roleplay additions
- Inject Persona into system prompt as [{{user}}'s Persona: name - desc]
- Inject activated World Info entries into system prompt by priority
- Inject Author's Note as system message before last 3 messages
- Apply context injection to all 4 chat functions:
  - chat() - regular non-streaming
  - chat_stream() - streaming
  - generate_response_only() - regenerate non-streaming
  - generate_response_stream() - regenerate streaming

All roleplay features now fully functional and affecting AI generation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 21:11:42 -07:00
e364ecfc51 feat: add World Info/Lorebook, Author's Note, and Persona systems
Backend changes:
- Add RoleplaySettings and WorldInfoEntry data structures
- Implement per-character roleplay settings storage in ~/.config/claudia/roleplay_{id}.json
- Add Tauri commands for CRUD operations on World Info entries
- Add commands for saving Author's Note and Persona settings

Frontend changes:
- Add World Info entry management UI with add/edit/delete functionality
- Implement keyword-triggered context injection system with priority ordering
- Add Author's Note textarea with enable toggle
- Add Persona name and description fields with enable toggle
- Load roleplay settings when opening the roleplay panel
- Add CSS styles for World Info entry cards with hover effects

Features:
- World Info entries support multiple keywords, priority levels, and enable/disable
- Settings are per-character and persist across sessions
- Entries sorted by priority (higher priority injected first)
- Clean UI with edit/delete buttons and visual feedback
2025-10-14 19:55:08 -07:00
5d32489c3c feat: add roleplay tools sidebar UI
Created left-sliding sidebar for roleplay features:
- Slides in from left (opposite of settings sidebar from right)
- Three tabs: World Info, Author's Note, Persona
- Hamburger menu button in header
- Overlay backdrop closes sidebar
- Tab switching with smooth transitions
- Responsive design matching settings panel

UI structure ready for implementation of:
- World Info/Lorebook entries with keyword triggers
- Author's Note for prompt injection
- Persona system for user character description
2025-10-14 18:07:19 -07:00
83e9793dce feat: add chat history import and export functionality
Implemented full chat history import/export with JSON format:
- Export button saves current conversation to JSON file
- Import button loads conversation from JSON file
- File dialog integration using tauri-plugin-dialog
- Message count feedback on successful import
- Automatic history reload after import
- Preserves all message data including swipes and timestamps
- Smart error handling (ignores cancelled dialogs)

Backend (Rust):
- export_chat_history: Opens save dialog, writes JSON to selected path
- import_chat_history: Opens file picker, parses JSON, saves to current character
- Message migration for backward compatibility
- Returns helpful feedback (file path on export, message count on import)

Frontend (JavaScript):
- Export/import buttons in header with up/down arrow icons
- Status updates during operations
- Auto-reload chat view after import
- Error handling with user-friendly messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 18:03:34 -07:00
9 changed files with 10400 additions and 232 deletions

3631
CELIA 3.8.json Normal file

File diff suppressed because one or more lines are too long

115
README.md
View File

@@ -1,37 +1,36 @@
# Claudia
Beautiful AI roleplay desktop companion built with Tauri and Rust.
## Vision
Claudia aims to be a lightweight, desktop-native alternative to SillyTavern, focusing on roleplay and character-based interactions while maintaining a clean, modern interface.
Desktop AI chat application built with Tauri and Rust, focused on roleplay and character-based interactions.
## Features
### Core Chat Features
- 🎨 **Beautiful glassmorphic UI** - Modern design with gradient backgrounds
- 🔧 **Bring-your-own-API** - Supports any Anthropic-compatible API
- **API validation** - Automatic model detection via /v1/models
- 💬 **Full conversation context** - AI remembers your entire conversation
- 💾 **Persistent chat history** - Conversations saved per character
- 🎯 **Streaming responses** - Real-time token display (optional)
### Chat
- Streaming responses with real-time display
- Full markdown rendering with syntax highlighting
- Message swipes (multiple response alternatives)
- Edit and regenerate from any message
- Per-character conversation history
- Copy code blocks with one click
### Character System
- 🎭 **Multiple characters** - Switch between different AI personas
- 🖼️ **Character avatars** - Upload custom images with zoom preview
- 📇 **V2/V3 character cards** - Import/export Tavern-compatible cards
- ✏️ **Full character editor** - All v2/v3 fields supported (description, scenario, examples, etc.)
### Characters
- V2/V3 character card import/export (PNG format)
- Multiple characters with avatar support
- Full character editor (description, personality, scenario, examples, etc.)
- Character-specific chat history
### Advanced Chat Features
- 🔄 **Message swipes** - Generate multiple responses and swipe between them
- ✏️ **Message editing** - Edit messages and regenerate from any point
- 🔀 **Chat branching** - Explore alternate conversation paths
### Roleplay Tools
- World Info/Lorebook system with keyword detection and priority
- Author's Note with configurable positioning
- User Personas with chat/character locking
- Prompt Presets with instruction blocks
- Message Examples from character cards
- Regex Scripts for text transformations
- Token counter with per-section breakdown
### Message Display
- 📝 **Full markdown rendering** - Headers, lists, tables, links, blockquotes
- 🎨 **Syntax highlighting** - Beautiful code blocks with highlight.js
- 📋 **Copy code blocks** - One-click copy button on hover
-**Smooth animations** - Elegant message transitions
### API
- Bring-your-own-API (Anthropic-compatible)
- Automatic model detection via /v1/models
- API validation and error handling
## Running
@@ -40,59 +39,49 @@ npm install
npm run dev
```
Build:
Build for production:
```bash
npm run build
```
**Note**: The dev script includes `WEBKIT_DISABLE_DMABUF_RENDERER=1` to fix Wayland compatibility issues on KDE Plasma.
## Configuration
On first launch, click settings and configure:
On first launch, configure in Settings:
- Base URL (e.g., https://api.anthropic.com)
- API Key
- Model (validated from /v1/models endpoint)
- Model
- Config stored in `~/.config/claudia/config.json`
- Chat history stored in `~/.config/claudia/history.json`
Config stored in `~/.config/claudia/config.json`
## Usage
## Keyboard Shortcuts
### Keyboard Shortcuts
- **Enter** - Send message
- **Shift+Enter** - New line in message
- **Up Arrow** - Edit last user message
- **Left/Right Arrow** - Swipe between alternative responses
### Character Management
- **Character Dropdown** - Switch between characters
- **Settings → Character Tab** - Edit current character
- **Import v2 Card** - Import Tavern character cards (PNG format)
- **Export v2 Card** - Export character as Tavern-compatible card
### Interface
- **Drag header** - Move window around your desktop
- **Trash icon** - Clear conversation history
- **Settings icon** - Configure API settings
- **Minimize/Maximize** - Window controls
- **Shift+Enter** - New line
- **Ctrl+Enter** - Send message (alternative)
- **Up Arrow** - Edit last user message (when input is at start)
- **Left/Right Arrow** - Navigate between response alternatives
- **Escape** - Close panels/modals, cancel editing
- **Ctrl+K** - Focus message input
- **Ctrl+P** - Open command palette (quick access to all actions)
- **Ctrl+/** - Toggle Roleplay Tools panel
## Roadmap
Claudia is being developed to become a full-featured roleplay platform comparable to SillyTavern. See [ROADMAP.md](ROADMAP.md) for detailed plans including:
See [ROADMAP.md](ROADMAP.md) for detailed development plans.
**Coming Soon:**
- 📚 World Info/Lorebooks for dynamic context
- 📝 Author's Note for better prompt control
- 👤 User Personas for identity management
- 😊 Character Expression Sprites
- 🔢 Token Counter and context visualization
- 👥 Group Chats with multiple characters
- ⚡ Quick Replies and macro system
**Current Focus:** Chat Branching/Checkpoints for non-linear conversation exploration
**Current Version:** v0.1.0 - Basic character chat with swipes and card import/export
**Next Version:** v0.2.0 - Roleplay Foundation (World Info, Author's Note, Token Counter)
**Upcoming:**
- Chat branching with timeline visualization
- Character expression sprites
- Group chats with multiple characters
- Quick replies and macro system
- Context templates for different model formats
## Contributing
## Development
This is a personal project, but feedback and suggestions are welcome! If you encounter bugs or have feature requests, please open an issue on GitHub.
Built with:
- Tauri 2.0
- Rust backend
- Vanilla JavaScript frontend
- tiktoken-rs for token counting

View File

@@ -9,50 +9,61 @@
- Character Management (multiple characters)
- Character Avatars with upload and zoom
- Expanded Character Editor (all v2/v3 fields)
- Prompt Presets System (built-in and custom presets with instruction blocks)
- Editable Built-in Presets with Restore to Default
- World Info/Lorebook System (keyword detection, priority, insertion)
- Author's Note (configurable depth and positioning)
- User Personas (identity management with chat/character locking)
- Regex Scripts (global and character-scoped text transformations)
- Chat History Import/Export (JSON format)
- Enhanced Message Controls (delete, pin, hide, continue, regenerate any message)
- Token Counter (real-time display with per-section breakdown)
- Message Examples (character card examples injected into context)
- Chat Branching/Checkpoints (create, switch, delete, rename branches from any message)
### 🎯 Current Focus: UI/UX Improvements
**Decision:** Before adding complex roleplay features, we're focusing on polishing the existing UI/UX to establish a solid foundation. This includes better visual design, improved workflows, and enhanced user experience.
### 🎯 Current Focus: Quality of Life & Polish
**Next Up:** Implementing high-impact QoL features to reduce friction and improve user experience - starting with Toast Notifications, Command Palette, Auto-save, Drag & Drop, and Chat Search.
See "Phase 7: Polish & UX" section for details on UI improvements being prioritized.
**Recent Completion:** Chat Branching/Checkpoints - Full conversation branching system allowing users to create and explore alternate conversation paths from any message point. Each branch maintains its own complete message history with a branch manager modal for easy navigation.
## Phase 1: Core Roleplay Infrastructure (High Priority)
**Goal: Enable basic roleplay-focused prompt engineering**
### 1. World Info/Lorebook System
- [ ] Create UI for managing lorebook entries (keyword, content, priority)
- [ ] Implement keyword detection in recent messages
- [ ] Add context injection before message generation
- [ ] Support recursive entry activation
- [ ] Per-character lorebook assignment
- [ ] Import/export lorebook files
### 1. World Info/Lorebook System
- [x] Create UI for managing lorebook entries (keyword, content, priority)
- [x] Implement keyword detection in recent messages
- [x] Add context injection before message generation
- [x] Support recursive entry activation
- [x] Per-character lorebook assignment
- [x] Import/export lorebook files
**Why Important:** World Info is the foundation of consistent roleplay. It allows dynamic context injection based on what's currently relevant in the conversation, saving tokens while maintaining world consistency.
### 2. Author's Note
- [ ] Add configurable Author's Note field (inserted at depth 1-5)
- [ ] Position control (after system, before/after examples, etc.)
- [ ] Per-character Author's Note support
- [ ] Template variables in Author's Note
### 2. Author's Note
- [x] Add configurable Author's Note field (inserted at depth 1-5)
- [x] Position control (after system, before/after examples, etc.)
- [x] Per-character Author's Note support
- [x] Template variables in Author's Note
**Why Important:** Author's Note is considered better than system prompts for roleplay because it appears closer to the actual conversation, reducing AI tendency to ignore or forget instructions.
### 3. Jailbreak Templates
- [ ] Add jailbreak template field in settings
- [ ] Preset jailbreak templates for roleplay
- [ ] Per-character jailbreak override option
- [ ] Template preview and testing
### 3. Jailbreak Templates ✅ (Implemented as Prompt Presets)
- [x] Add jailbreak template field in settings (Prompt Presets with system additions)
- [x] Preset jailbreak templates for roleplay (Built-in presets: Default, Roleplay, Creative Writing, Assistant)
- [x] Per-character jailbreak override option (Active preset per character)
- [x] Template preview and testing (Editable instruction blocks with live preview)
**Why Important:** Many roleplay scenarios require specific prompting to work well with API safety filters and to maintain character consistency.
## Phase 2: Enhanced Character Features (High Priority)
**Goal: Better character representation and user identity**
### 1. User Personas
- [ ] Create persona management UI (name, description, avatar)
- [ ] Chat-level persona locking
- [ ] Character-level persona locking
- [ ] Default persona setting
- [ ] Quick persona switching
### 1. User Personas
- [x] Create persona management UI (name, description, avatar)
- [x] Chat-level persona locking
- [x] Character-level persona locking
- [x] Default persona setting
- [x] Quick persona switching
**Why Important:** Allows users to have multiple identities for different roleplay scenarios without manually changing their name and description each time.
@@ -66,34 +77,35 @@ See "Phase 7: Polish & UX" section for details on UI improvements being prioriti
**Why Important:** Visual representation of character emotions dramatically enhances immersion and makes conversations feel more alive.
### 3. Message Examples in Context
- [ ] Actually use mes_example field from character cards
- [ ] Format and inject into prompt properly
- [ ] Position control in context
- [ ] Token budget allocation for examples
### 3. Message Examples in Context
- [x] Actually use mes_example field from character cards
- [x] Format and inject into prompt properly
- [x] Position control in context
- [x] Token budget allocation for examples
**Why Important:** Message examples help the AI understand the character's voice and writing style, leading to more accurate portrayals.
## Phase 3: Advanced Chat Management (Medium Priority)
**Goal: Non-linear conversation control**
### 1. Chat Branching/Checkpoints
- [ ] Save conversation state at any message
- [ ] Create branches from any point
- [ ] Switch between branches
- [ ] Visual branch indicator in UI
- [ ] Branch naming and organization
- [ ] Delete/merge branches
### 1. Chat Branching/Checkpoints
- [x] Save conversation state at any message
- [x] Create branches from any point
- [x] Switch between branches
- [x] Visual branch indicator in UI
- [x] Branch naming and organization
- [x] Delete branches
- [ ] Merge branches (deferred - nice to have)
**Why Important:** Roleplay often involves exploring "what if" scenarios. Branching lets you explore different conversation paths without losing previous progress.
### 2. Enhanced Message Controls
- [ ] Delete individual messages (not just clearing all)
- [ ] Regenerate any message (not just last)
- [ ] Continue incomplete messages
- [ ] Message pinning (keep certain messages in context)
- [ ] Message folding/hiding
- [ ] Bulk message operations
### 2. Enhanced Message Controls
- [x] Delete individual messages (not just clearing all)
- [x] Regenerate any message (not just last)
- [x] Continue incomplete messages
- [x] Message pinning (keep certain messages in context)
- [x] Message folding/hiding
- [ ] Bulk message operations (deferred - nice to have)
**Why Important:** Fine-grained control over conversation history allows users to craft the perfect roleplay session.
@@ -140,14 +152,14 @@ See "Phase 7: Polish & UX" section for details on UI improvements being prioriti
## Phase 5: Context & Token Management (Medium Priority)
**Goal: Visibility and control over context usage**
### 1. Token Counter
- [ ] Real-time token count display
- [ ] Per-section breakdown (system, history, WI, etc.)
- [ ] Visual context budget indicator
- [ ] Dotted line showing context cutoff in chat
- [ ] Warning when approaching limit
### 1. Token Counter
- [x] Real-time token count display
- [x] Per-section breakdown (system, history, WI, etc.)
- [ ] Visual context budget indicator (deferred)
- [ ] Dotted line showing context cutoff in chat (deferred)
- [ ] Warning when approaching limit (deferred)
**Why Important:** Understanding what's in context and what's being cut is crucial for debugging issues and optimizing prompts.
**Why Important:** Understanding what's in context and what's being cut is crucial for debugging issues and optimizing prompts. Core functionality complete - visual enhancements can be added later.
### 2. Context Templates
- [ ] Customizable prompt assembly order
@@ -190,13 +202,13 @@ See "Phase 7: Polish & UX" section for details on UI improvements being prioriti
**Why Important:** Makes prompts and messages dynamic and reusable across different scenarios.
### 3. Regex Scripts
- [ ] Global and character-scoped scripts
- [ ] Text transformation on messages
- [ ] Auto-markdown formatting
- [ ] Import/export regex presets
- [ ] Regex testing interface
- [ ] Script priority/ordering
### 3. Regex Scripts
- [x] Global and character-scoped scripts
- [x] Text transformation on messages
- [x] Auto-markdown formatting
- [x] Import/export regex presets
- [x] Regex testing interface
- [x] Script priority/ordering
**Why Important:** Allows automatic text formatting, correction, and enhancement without manual intervention.
@@ -224,8 +236,8 @@ See "Phase 7: Polish & UX" section for details on UI improvements being prioriti
### 2. Export/Import Improvements
- [ ] Export chats as markdown
- [ ] Export chats as formatted text
- [ ] Export chats as JSON with metadata
- [ ] Import chats from other formats
- [x] Export chats as JSON with metadata
- [x] Import chats from other formats
- [ ] Bulk character import
- [ ] Character pack support (multiple characters + lorebooks)
@@ -242,6 +254,151 @@ See "Phase 7: Polish & UX" section for details on UI improvements being prioriti
**Why Important:** Better UI means less friction and more immersion in roleplay.
## Phase 8: Quality of Life & Polish (High Priority)
**Goal: Reduce friction, improve feedback, and enhance overall user experience**
### 1. Toast Notification System
- [ ] Create toast component (bottom-right positioning)
- [ ] Success/error/info/warning variants
- [ ] Auto-dismiss with configurable timeout
- [ ] Queue multiple toasts
- [ ] Hook into all major actions (save, delete, import, export, etc.)
**Why Important:** Users currently have no immediate feedback when actions succeed or fail. Toasts provide instant visual confirmation without blocking workflow.
### 2. Command Palette
- [ ] Ctrl+P to open command palette modal
- [ ] Fuzzy search for all actions
- [ ] Keyboard navigation (arrow keys, enter, escape)
- [ ] Recent/frequent actions at top
- [ ] Show keyboard shortcuts in results
- [ ] Categories (Chat, Character, Settings, etc.)
**Why Important:** Power users want keyboard-first workflow. Command palette dramatically speeds up common actions without memorizing shortcuts.
### 3. Auto-save & Recovery
- [ ] Auto-save unsent message in input field
- [ ] Restore unsent message after app restart
- [ ] Draft system for in-progress edits
- [ ] Session recovery (restore scroll position, open panels)
- [ ] Crash recovery with last known state
**Why Important:** Losing work due to crashes or accidental closes is extremely frustrating. Auto-save provides a safety net for all user work.
### 4. Drag & Drop Support
- [ ] Drag character card PNGs to import
- [ ] Drag lorebook JSON files to import
- [ ] Drag chat history JSON to import
- [ ] Drag images to set as character avatar
- [ ] Drop zone overlay with visual feedback
- [ ] Support for multiple file drops
**Why Important:** Drag & drop feels natural and is much faster than navigate-click-select workflow. Modern desktop apps are expected to support this.
### 5. Search in Chat History
- [ ] Ctrl+F to open search bar
- [ ] Highlight all matches in messages
- [ ] Navigate between results (prev/next buttons)
- [ ] Case-insensitive search
- [ ] Search counter (e.g., "3 of 42 matches")
- [ ] Clear search and restore view
**Why Important:** Long roleplay sessions can span hundreds of messages. Finding specific content without search is tedious and time-consuming.
### 6. Context Menus (Right-Click)
- [ ] Right-click messages for actions (edit, delete, regenerate, branch, copy)
- [ ] Right-click character dropdown for quick actions
- [ ] Right-click World Info entries for edit/delete
- [ ] Right-click in message input for paste/clear/templates
- [ ] Context-aware menu items
**Why Important:** Right-click is muscle memory for desktop users. Faster than hovering to reveal action buttons.
### 7. Better Feedback & Confirmations
- [ ] Confirmation dialogs for destructive actions (delete character, clear chat)
- [ ] Loading spinners for API calls
- [ ] Progress bars for file imports
- [ ] "Saving..." / "Saved" indicators
- [ ] Success messages for completed actions
**Why Important:** Users should never wonder if an action succeeded or is still processing. Clear feedback prevents confusion and repeated clicks.
### 8. Undo/Redo System
- [ ] Undo message edit (Ctrl+Z)
- [ ] Undo message delete
- [ ] Undo character field changes
- [ ] Undo World Info changes
- [ ] Action history panel (optional)
- [ ] Redo support (Ctrl+Shift+Z)
**Why Important:** Mistakes happen. An undo system provides a safety net and encourages experimentation without fear of losing work.
### 9. Settings Search
- [ ] Search bar at top of settings panel
- [ ] Fuzzy search across all setting names and descriptions
- [ ] Highlight matching settings
- [ ] Collapse/expand sections based on matches
- [ ] "Recently changed" section
**Why Important:** With 22+ features, finding specific settings is tedious. Search makes configuration much faster.
### 10. Character Management Enhancements
- [ ] Recent characters quick-switch dropdown
- [ ] Character search/filter by name or tags
- [ ] Character folders/categories
- [ ] Duplicate character (as template)
- [ ] Favorite/star characters
- [ ] Sort options (name, date created, last used)
**Why Important:** Managing 10+ characters becomes messy. Better organization tools scale with user's character collection.
### 11. Enhanced Keyboard Support
- [ ] Full keyboard navigation in all modals (Tab, Arrow keys, Enter)
- [ ] Escape to close any open panel/modal
- [ ] Vim-style navigation mode (optional, j/k for scroll)
- [ ] Keyboard shortcut hints on hover
- [ ] Focus indicators for keyboard navigation
**Why Important:** Keyboard navigation should work everywhere. Current implementation is inconsistent across different UI sections.
### 12. Export/Share Enhancements
- [ ] Export conversation as formatted HTML
- [ ] Export conversation as formatted PDF
- [ ] Export as markdown with proper formatting
- [ ] Copy conversation to clipboard (formatted)
- [ ] Export individual messages
**Why Important:** Users want to share and archive conversations in readable formats, not just JSON.
### 13. Accessibility Improvements
- [ ] ARIA labels for all interactive elements
- [ ] Screen reader support
- [ ] High contrast mode option
- [ ] Larger click targets option (accessibility mode)
- [ ] Reduced motion mode (respect prefers-reduced-motion)
- [ ] Focus indicators for keyboard navigation
**Why Important:** Accessibility makes the app usable for everyone, including users with disabilities. It's also often legally required.
### 14. Better Visual Feedback
- [ ] Smooth transitions for panel open/close
- [ ] Hover states for all interactive elements
- [ ] Active state indicators (focused panel)
- [ ] Better empty states with helpful text
- [ ] Skeleton loaders for content loading
- [ ] Micro-animations for actions (delete, save, etc.)
**Why Important:** Visual polish makes the app feel responsive and professional. Small animations provide context for state changes.
### 15. Smart Defaults & Templates
- [ ] Scenario templates (fantasy RPG, sci-fi, modern, etc.)
- [ ] Pre-filled World Info templates
- [ ] Character card templates
- [ ] Quick-start wizard for new users
- [ ] Import from popular character repositories
**Why Important:** Reduces friction for new users and speeds up common tasks. Templates provide starting points for customization.
## Implementation Priority Ranking
### Must-Have for Basic Roleplay:
@@ -344,4 +501,4 @@ This roadmap is based on research into SillyTavern's features and best practices
---
Last updated: 2025-10-14
Last updated: 2025-10-16

62
src-tauri/Cargo.lock generated
View File

@@ -270,6 +270,21 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bit_field"
version = "0.10.3"
@@ -352,6 +367,17 @@ dependencies = [
"alloc-stdlib",
]
[[package]]
name = "bstr"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
dependencies = [
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.19.0"
@@ -502,8 +528,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link 0.2.1",
]
@@ -1020,6 +1048,16 @@ dependencies = [
"zune-inflate",
]
[[package]]
name = "fancy-regex"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7493d4c459da9f84325ad297371a6b2b8a162800873a22e3b6b6512e61d18c05"
dependencies = [
"bit-set",
"regex",
]
[[package]]
name = "fastrand"
version = "2.3.0"
@@ -3459,6 +3497,12 @@ version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.1"
@@ -4194,9 +4238,11 @@ version = "0.1.0"
dependencies = [
"base64 0.21.7",
"bytes",
"chrono",
"futures",
"image",
"png",
"regex",
"reqwest",
"serde",
"serde_json",
@@ -4204,6 +4250,7 @@ dependencies = [
"tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-opener",
"tiktoken-rs",
"tokio",
"uuid",
]
@@ -4525,6 +4572,21 @@ dependencies = [
"weezl",
]
[[package]]
name = "tiktoken-rs"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c314e7ce51440f9e8f5a497394682a57b7c323d0f4d0a6b1b13c429056e0e234"
dependencies = [
"anyhow",
"base64 0.21.7",
"bstr",
"fancy-regex",
"lazy_static",
"parking_lot",
"rustc-hash",
]
[[package]]
name = "time"
version = "0.3.44"

View File

@@ -31,4 +31,7 @@ bytes = "1"
png = "0.17"
base64 = "0.21"
image = "0.24"
regex = "1"
chrono = "0.4"
tiktoken-rs = "0.5"

File diff suppressed because it is too large Load Diff

View File

@@ -15,10 +15,20 @@
<div class="app-container">
<header class="app-header">
<div class="header-content">
<div class="header-left-controls">
<button id="roleplay-btn" class="icon-btn" title="Roleplay Tools">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
</div>
<div class="character-display">
<div class="avatar-circle"></div>
<span id="character-header-name"></span>
</div>
<div id="feature-badges" class="feature-badges">
<!-- Feature badges will be added here dynamically -->
</div>
<div class="character-controls">
<div class="select-wrapper">
<select id="character-select" class="character-select"></select>
@@ -30,6 +40,18 @@
</button>
</div>
<div class="header-controls">
<button id="import-chat-btn" class="icon-btn" title="Import conversation">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8 11V3M5 8l3 3 3-3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 13h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
<button id="export-chat-btn" class="icon-btn" title="Export conversation">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8 3v8M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 13h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
<button id="clear-btn" class="icon-btn" title="Clear conversation">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M3 4h10M6 4V3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v1M5 4v8a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
@@ -55,6 +77,229 @@
</div>
</main>
<!-- Roleplay sidebar overlay -->
<div class="roleplay-overlay" id="roleplay-overlay"></div>
<!-- Roleplay sidebar (left) -->
<div class="roleplay-panel" id="roleplay-panel">
<div class="roleplay-header">
<h2>Roleplay Tools</h2>
<button id="close-roleplay-btn" class="icon-btn">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<line x1="4" y1="4" x2="12" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
<line x1="12" y1="4" x2="4" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
</div>
<div class="roleplay-tabs">
<button class="roleplay-tab-btn active" data-tab="worldinfo">World Info</button>
<button class="roleplay-tab-btn" data-tab="authorsnote">Author's Note</button>
<button class="roleplay-tab-btn" data-tab="persona">Persona</button>
<button class="roleplay-tab-btn" data-tab="presets">Prompt Preset</button>
</div>
<div id="worldinfo-tab" class="roleplay-tab-content active">
<div class="roleplay-content">
<div class="form-group">
<label>World Info / Lorebook</label>
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 12px;">
Create entries that inject context when keywords are mentioned.
</p>
<label for="recursion-depth" style="font-size: 13px; margin-top: 8px;">Recursion Depth</label>
<input
type="number"
id="recursion-depth"
min="0"
max="10"
value="3"
style="width: 80px; margin-bottom: 8px;"
/>
<p style="color: var(--text-secondary); font-size: 11px; margin-bottom: 12px;">
Maximum depth for cascading World Info activation. When a World Info entry is triggered, its content is scanned for additional keywords up to this depth. (Default: 3)
</p>
<button type="button" id="add-worldinfo-btn" class="btn-secondary" style="width: 100%;">
+ Add Entry
</button>
</div>
<div id="worldinfo-list" class="worldinfo-list">
<!-- World info entries will be added here -->
</div>
</div>
</div>
<div id="authorsnote-tab" class="roleplay-tab-content">
<div class="roleplay-content">
<div class="form-group">
<label for="authors-note-text">Author's Note</label>
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
Instructions inserted near the end of the prompt before the latest messages.
</p>
<textarea
id="authors-note-text"
placeholder="Write in present tense. Focus on sensory details..."
rows="6"
></textarea>
<div style="background: var(--bg-secondary); padding: 8px; border-radius: 4px; margin-top: 8px;">
<p style="color: var(--text-secondary); font-size: 11px; margin: 0 0 4px 0; font-weight: 500;">Template Variables:</p>
<p style="color: var(--text-secondary); font-size: 11px; margin: 0; font-family: monospace;">
{{char}} - Character name<br/>
{{user}} - User/Persona name<br/>
{{date}} - Current date (YYYY-MM-DD)<br/>
{{time}} - Current time (HH:MM)
</p>
</div>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="authors-note-enabled" />
Enable Author's Note
</label>
</div>
<button type="button" id="save-authors-note-btn" class="btn-primary" style="width: 100%; margin-bottom: 20px;">
Save Author's Note
</button>
<!-- Message Examples Section -->
<div class="form-group" style="border-top: 1px solid var(--border); padding-top: 16px;">
<label>Message Examples</label>
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
Use character card's message examples to teach the AI the character's voice and style.
</p>
<label>
<input type="checkbox" id="examples-enabled" />
Enable Message Examples
</label>
</div>
<div class="form-group">
<label for="examples-position">Examples Position</label>
<select id="examples-position" style="width: 100%;">
<option value="after_system">After System Prompt (Recommended)</option>
<option value="before_history">Before Message History</option>
</select>
<p style="color: var(--text-secondary); font-size: 11px; margin-top: 4px;">
Where to inject examples in the context. After system prompt works best for most models.
</p>
</div>
<button type="button" id="save-examples-btn" class="btn-primary" style="width: 100%;">
Save Examples Settings
</button>
</div>
</div>
<div id="persona-tab" class="roleplay-tab-content">
<div class="roleplay-content">
<div class="form-group">
<label for="persona-name">Persona Name</label>
<input
type="text"
id="persona-name"
placeholder="Your character name"
/>
</div>
<div class="form-group">
<label for="persona-description">Persona Description</label>
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
Describe yourself as the user in this roleplay.
</p>
<textarea
id="persona-description"
placeholder="Describe your character's appearance, personality, background..."
rows="8"
></textarea>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="persona-enabled" />
Enable Persona
</label>
</div>
<button type="button" id="save-persona-btn" class="btn-primary" style="width: 100%;">
Save Persona
</button>
</div>
</div>
<div id="presets-tab" class="roleplay-tab-content">
<div class="roleplay-content">
<div class="form-group">
<label for="preset-select">Prompt Preset</label>
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
Choose a preset to apply specialized prompting strategies for different use cases.
</p>
<select id="preset-select" style="width: 100%; margin-bottom: 12px;">
<option value="">No Preset</option>
</select>
</div>
<!-- Preset Info/Editor -->
<div id="preset-info" style="display: none; background: var(--bg-secondary); padding: 12px; border-radius: 6px; margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<div style="font-weight: 500; color: var(--text-primary);">
<span id="preset-name"></span>
<span id="preset-builtin-badge" style="display: none; font-size: 10px; color: var(--text-secondary); margin-left: 8px; padding: 2px 6px; background: var(--bg-primary); border-radius: 3px;">Built-in</span>
<span id="preset-modified-badge" style="display: none; font-size: 10px; color: var(--accent); margin-left: 8px; padding: 2px 6px; background: var(--bg-primary); border-radius: 3px;">Modified</span>
</div>
<div style="display: flex; gap: 4px;">
<button type="button" id="restore-preset-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">Restore to Default</button>
<button type="button" id="duplicate-preset-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">Duplicate</button>
<button type="button" id="delete-preset-btn" class="worldinfo-btn worldinfo-btn-danger" style="display: none; font-size: 11px; padding: 4px 8px;">Delete</button>
</div>
</div>
<p id="preset-description" style="color: var(--text-secondary); font-size: 12px; margin-bottom: 12px;"></p>
<!-- System Additions (Read-only preview for built-in, editable for custom) -->
<div id="preset-system-section" style="margin-bottom: 12px;">
<div style="font-size: 11px; color: var(--text-secondary); margin-bottom: 4px;">
<strong>System Additions:</strong>
</div>
<div id="preset-system-readonly" style="display: none; background: var(--bg-primary); padding: 8px; border-radius: 4px; font-size: 11px; white-space: pre-wrap;"></div>
<textarea id="preset-system-editable" style="display: none; width: 100%; min-height: 60px; font-size: 11px;" placeholder="Additional text to prepend to system prompt..."></textarea>
</div>
<!-- Instruction Blocks Editor -->
<div id="preset-instructions-section">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<div style="font-size: 11px; color: var(--text-secondary);">
<strong>Instruction Blocks:</strong>
</div>
<button type="button" id="add-instruction-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">+ Add Block</button>
</div>
<div id="preset-instructions-list" style="background: var(--bg-primary); padding: 8px; border-radius: 4px; margin-bottom: 12px;">
<!-- Instructions will be listed here -->
</div>
</div>
<!-- Author's Note Default -->
<div id="preset-authors-note-section" style="margin-bottom: 12px;">
<div style="font-size: 11px; color: var(--text-secondary); margin-bottom: 4px;">
<strong>Default Author's Note:</strong>
</div>
<div id="preset-authors-note-readonly" style="display: none; background: var(--bg-primary); padding: 8px; border-radius: 4px; font-size: 11px; white-space: pre-wrap;"></div>
<textarea id="preset-authors-note-editable" style="display: none; width: 100%; min-height: 60px; font-size: 11px;" placeholder="Default Author's Note if user hasn't set one..."></textarea>
</div>
<!-- Save Changes Button (only for custom presets) -->
<button type="button" id="save-preset-changes-btn" class="btn-secondary" style="display: none; width: 100%; margin-bottom: 8px;">
Save Changes
</button>
</div>
<button type="button" id="apply-preset-btn" class="btn-primary" style="width: 100%; margin-bottom: 8px;" disabled>
Apply Preset
</button>
<button type="button" id="create-preset-btn" class="btn-secondary" style="width: 100%;">
Create Custom Preset
</button>
<p style="color: var(--text-secondary); font-size: 11px; margin-top: 12px; padding: 8px; background: var(--bg-secondary); border-radius: 4px;">
<strong>Note:</strong> Custom presets will be stored in ~/.config/claudia/presets/ and will be available across all characters.
</p>
</div>
</div>
</div>
<!-- Settings overlay backdrop -->
<div class="settings-overlay" id="settings-overlay"></div>
@@ -108,6 +353,19 @@
</select>
</div>
<div class="form-group">
<label for="context-limit">Context Limit (tokens)</label>
<input
type="number"
id="context-limit"
placeholder="200000"
value="200000"
min="1000"
step="1000"
/>
<small style="color: var(--text-secondary); margin-top: 4px; display: block;">Maximum tokens for model context (e.g., 200000 for Claude)</small>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="stream-toggle" />
@@ -420,10 +678,88 @@
</form>
<div class="status-bar">
<span id="status-text" class="status-text">Ready</span>
<div id="token-counter" class="token-counter">
<span id="token-count-total" class="token-count">0 tokens</span>
<button id="token-details-btn" class="token-details-btn" title="Show breakdown">
<svg width="12" height="12" viewBox="0 0 16 16" fill="none">
<circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/>
<path d="M8 7v4M8 5h.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
</div>
</div>
<!-- Token Breakdown Tooltip -->
<div id="token-breakdown" class="token-breakdown" style="display: none;">
<div class="token-breakdown-header">Token Breakdown</div>
<div class="token-breakdown-list">
<div class="token-breakdown-item">
<span>System Prompt:</span>
<span id="token-system">0</span>
</div>
<div class="token-breakdown-item">
<span>Preset Instructions:</span>
<span id="token-preset">0</span>
</div>
<div class="token-breakdown-item">
<span>Persona:</span>
<span id="token-persona">0</span>
</div>
<div class="token-breakdown-item">
<span>World Info:</span>
<span id="token-worldinfo">0</span>
</div>
<div class="token-breakdown-item">
<span>Author's Note:</span>
<span id="token-authorsnote">0</span>
</div>
<div class="token-breakdown-item">
<span>Message Examples:</span>
<span id="token-examples">0</span>
</div>
<div class="token-breakdown-item">
<span>Message History:</span>
<span id="token-history">0</span>
</div>
<div class="token-breakdown-item">
<span>Current Input:</span>
<span id="token-input">0</span>
</div>
<div class="token-breakdown-total">
<span>Total:</span>
<span id="token-total-detail">0</span>
</div>
</div>
</div>
</footer>
</div>
<!-- Toast Container -->
<div id="toast-container" class="toast-container"></div>
<!-- Command Palette -->
<div id="command-palette-modal" class="command-palette-modal" style="display: none;">
<div class="command-palette-overlay"></div>
<div class="command-palette-content">
<div class="command-palette-search">
<svg class="command-palette-search-icon" width="20" height="20" viewBox="0 0 20 20" fill="none">
<circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="2"/>
<path d="M12.5 12.5L17 17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
<input
type="text"
id="command-palette-input"
class="command-palette-input"
placeholder="Type a command or search..."
autocomplete="off"
/>
<kbd class="command-palette-hint">Esc to close</kbd>
</div>
<div id="command-palette-results" class="command-palette-results">
<!-- Command results will be dynamically populated here -->
</div>
</div>
</div>
<!-- Avatar zoom modal -->
<div id="avatar-modal" class="avatar-modal" style="display: none;">
<div class="avatar-modal-overlay"></div>
@@ -431,5 +767,50 @@
<img id="avatar-modal-img" src="" alt="Avatar" />
</div>
</div>
<!-- New Character modal -->
<div id="new-character-modal" class="new-character-modal" style="display: none;">
<div class="new-character-overlay"></div>
<div class="new-character-content">
<div class="new-character-header">
<h3>Create New Character</h3>
<button id="close-new-character-btn" class="icon-btn">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<line x1="4" y1="4" x2="12" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
<line x1="12" y1="4" x2="4" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
</div>
<form id="new-character-form">
<div class="form-group">
<label for="new-character-name">Character Name</label>
<input
type="text"
id="new-character-name"
placeholder="Enter a name for the new character"
required
autofocus
/>
</div>
<div class="form-group">
<label for="new-character-system-prompt">System Prompt</label>
<textarea
id="new-character-system-prompt"
placeholder="You are a helpful AI assistant..."
rows="6"
required
></textarea>
</div>
<div class="new-character-actions">
<button type="button" id="cancel-new-character-btn" class="btn-secondary">
Cancel
</button>
<button type="submit" class="btn-primary">
Create
</button>
</div>
</form>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff