Resolves#195. Before sending an interrupt signal, check whether
the user has text selected. If so, let the browser handle Ctrl+C
as a native copy rather than interrupting Claude.
- Move isRestoringScroll = true before await tick() so scroll events
fired during the DOM transition cannot incorrectly set shouldAutoScroll
to false, breaking autoscroll for all tabs except the first
- Guard the windowStart reactive block with isSwitchingConversation so
stale lines from the previous conversation cannot override the correct
windowStart after a tab switch
- Fix lazy load threshold to trigger relative to the visible window top
(windowStart * AVG_LINE_HEIGHT + 300) rather than the absolute scroll
container top, so older messages load without scrolling through the spacer
Implements issue #179. Adds a Task Loop panel that imports hikari-tasks.json
files and automatically runs Claude Code through each task in sequence, one
per conversation tab. Includes Start/Pause/Stop/Resume controls, real-time
status indicators per task, and a StatusBar badge. WSL UNC paths from the
file picker are normalised to Unix paths at import time.
Adds a Changelog panel accessible from the nav menu. Fetches all
releases from the Gitea API on open and renders each entry with
version badge, date, pre-release tag, and markdown release notes.
Highlights the currently installed version with a pink "current" badge.
Consolidates 21 toolbar buttons into a single Menu trigger that
opens a scrollable dropdown with icon + label per item. Clicking
any item auto-closes the menu; backdrop click also closes it.
All panel state migrated to NavMenu; StatusBar trimmed ~480 lines.
- Terminal: virtual windowing renders max 150 lines, loads 50 older on
scroll-up with scroll position compensation; auto-advances window
forward during auto-scroll so old DOM nodes are unloaded continuously
- Markdown: two-stage derived rendering separates expensive parse step
(marked + hljs + spoilers, runs on content change) from cheap search
highlight step (runs on query change only)
- Achievements: fix double Object.keys() call in derived store
- Terminal: 150ms debounce on search query to reduce redundant updates
- Tests: add Markdown.test.ts for processSpoilers and highlightSearchMatches;
extend Terminal.test.ts with virtual windowing helper coverage
Adds a PRD Creator panel accessible from the status bar that lets Naomi
describe a goal and have Claude break it down into actionable tasks
written to hikari-tasks.json. Tasks can be reviewed, edited, reordered,
and executed directly from the panel. Uses the Lucide ScrollText icon to
distinguish it visually from the Todo List clipboard icon.
Also adds CODEBASE.md to the repo and gitignores hikari-tasks.json as a
user-generated data file.
- Add scan_project Rust command that walks the directory tree and detects project type
- Add CODEBASE as a managed ProjectFile type alongside PROJECT/REQUIREMENTS/ROADMAP/STATE
- Add mapCodebase() store function that scans and sends an analysis prompt to Claude
- Add CODEBASE tab to ProjectContextPanel with Map/Remap buttons and auto-reload on idle
- Update PROJECT_CONTEXT_SYSTEM_ADDENDUM to include CODEBASE.md reference
- Add projectContext store with load/save via existing Tauri file commands
- Add ProjectContextPanel modal with tabbed editor, file-exists badges, and templates
- Add injectTextStore signal so StatusBar can inject content directly into InputBar
- Add PROJECT_CONTEXT_SYSTEM_ADDENDUM auto-appended to custom_instructions on connect
- Add open-book button to StatusBar to open the panel
- Add PROJECT.md example file for the hikari-desktop project itself
- 34 tests covering all store methods, exports, and signal behaviour
## Summary
- **Fix git window "Not a git repository" error** — The working directory received from Claude Code is a WSL Linux path (e.g. `/home/naomi/...`), but git commands were being run as native Windows processes with `.current_dir()`. Windows can't resolve WSL paths, causing `git rev-parse --git-dir` to fail. Fixed by routing git commands through `wsl -- git -C <path>` when the working directory starts with `/`.
- **Add syntax highlighting and line numbers to diff view** — Replaced the raw `<pre>` block with a proper `DiffViewer` component featuring:
- Old/new line number columns with correct tracking across hunks
- Colour-coded gutter (`+`/`-`) with green/red row backgrounds
- Syntax highlighting via `highlight.js` using the detected file language, respecting all app themes via `--hljs-*` CSS variables
- Styled hunk headers and file headers
## New files
- `src/lib/utils/diffParser.ts` — pure diff parsing logic
- `src/lib/utils/diffParser.test.ts` — 30 tests covering all line types, line number tracking, and language detection
- `src/lib/components/DiffViewer.svelte` — the pretty diff viewer component
✨ This pull request was created with help from Hikari~ 🌸
Reviewed-on: #178
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- **fix**: `show_thinking_blocks` setting now persists across sessions — it was defined on the TypeScript side but missing from the Rust `HikariConfig` struct, so serde silently dropped it on every save/load
- **feat**: Tool calls are now rendered as collapsible blocks matching the Extended Thinking block aesthetic, replacing the old inline dropdown approach
- **feat**: Add configurable max output tokens setting
- **feat**: Use random creative names for conversation tabs
- **test**: Significantly expanded frontend unit test coverage
- **docs**: Require tests for all changes in CLAUDE.md
- **feat**: Allow users to specify a custom terminal font (Closes#176)
- **feat**: Display friendly names for memory files derived from the first heading (Closes#177)
- **feat**: Add custom UI font support for the app chrome (buttons, labels, tabs)
- **fix**: Apply custom UI font to the full app interface — `.app-container` was hardcoded, blocking inheritance from `body`; also renamed "Custom Font" to "Custom Terminal Font" for clarity
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #175
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- **Saved Drafts feature**: Users can now save input content as drafts for later use, and manage them from a new panel
- **Sound spam fix**: The "Working on it!" sound no longer plays repeatedly when Claude makes multiple tool calls in a row
## Details
### Drafts feature
- Rust backend (`drafts.rs`) with `list_drafts`, `save_draft`, `delete_draft`, and `delete_all_drafts` commands, persisted to `hikari-drafts.json` via the Tauri Store plugin
- `draftsStore` wrapping all four commands with timestamp formatting
- `DraftPanel` overlay with insert, per-item two-step delete confirmation, delete-all with confirmation, empty state, and slide-in animation
- **Drafts** button in the top control row (pencil icon)
- **Save as Draft** floppy-disk icon button in the button wrapper (disabled when input is empty)
### Sound spam fix
- Root cause: `resetSoundState` was called on **every** `thinking` state transition, including mid-task transitions (`coding → thinking → coding`)
- Fix: only reset sound state when entering `thinking` from a clean-slate state (`idle`, `success`, or `error`) — states that genuinely mark the end of one task and the start of a new one
## Test plan
- [ ] Save a draft and verify it persists across app restarts
- [ ] Insert a draft and verify it populates the input
- [ ] Delete individual drafts and verify delete-all works
- [ ] Verify "Working on it!" plays once per user message regardless of how many tools are called
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #174
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- **Markdown lists**: Explicitly set `list-style-type: disc` / `decimal` in the Markdown renderer — Tauri's WebView strips browser defaults, leaving bullets and numbers invisible.
- **Notification sounds**: Moved all per-task sounds (success, error, permission, task-start) from a global `characterState` subscription into the per-conversation `claude:state` event handler, so background tabs receive their sounds correctly and tab-switching never replays a sound that already fired. Closes#172
- **Draft text**: Persists `inputValue` per conversation tab so a half-typed prompt survives switching to another tab and back.
- **Interrupt messages**: Replaced vague "Process interrupted" / "Disconnected" strings with source-specific descriptions (keyboard shortcut, stop button, unexpected crash) so it's clear what actually happened.
- **Silent prompt loss**: When Claude Code exits whilst a prompt is in-flight, emits a visible error line telling the user their last prompt was not processed and to reconnect and retry.
- **Double disconnect**: Added an `intentional_stop` flag to `WslBridge` so that `stop()` / `interrupt()` — which kill the process themselves — suppress the duplicate "Disconnected unexpectedly" message that `handle_stdout`'s EOF path was also emitting.
- **Permission modal**: Fixed two cooperating reactivity bugs — `pendingPermissions` was mutated in-place (`.push()`), causing Svelte's derived-store chain to receive the same array reference and skip re-rendering; `PermissionModal.svelte` also used `$state()` (runes mode) where plain `let` is required for correct store-subscription reactivity.
## Test plan
- [ ] Unordered and ordered lists render with visible bullets and numbers in the chat terminal
- [ ] Completion sound plays once when a background tab finishes; switching back to that tab does not replay it
- [ ] Sounds for error, permission request, and task-start also play for background tabs and do not replay on tab switch
- [ ] Typing a prompt, switching tabs, and switching back restores the draft text
- [ ] Pressing Ctrl+C shows "keyboard shortcut (Ctrl+C)"; clicking the stop button shows "via stop button"
- [ ] If Claude exits mid-request, an error message appears prompting the user to resend
- [ ] Clicking stop or pressing Ctrl+C produces exactly one disconnect message (not two)
- [ ] When a tool requires permission, the permission modal appears and the user can approve or dismiss it
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #173
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
This PR covers the full audit of Claude CLI changes from 2.1.50 to 2.1.53, plus a batch of bug fixes, new features, and maintenance work identified during that review.
### New Features
- **Workspace trust gate** — detects hooks, MCP servers, and custom commands in a workspace before connecting; persists trust decisions so users aren't prompted repeatedly
- **Custom background image** — users can set a background image with configurable opacity; character panel and compact mode go transparent when active
- **Draggable tab reordering** — conversation tabs can be reordered via pointer-event drag-and-drop (HTML5 drag is intercepted by Tauri/WebView2, so pointer events are used instead)
- **Org UUID in account info** — exposes the org UUID from Claude auth status
### Bug Fixes
- **Unread dot false positives** — initialise unread counts on mount to prevent all tabs showing the blue dot after toggling the file editor (Closes#164)
- **Watchdog for hung WSL bridge** — detects connections that never receive `system:init` and kills the stale process after 1 minute (Closes#166)
- **Suppress terminal window flash on Windows** — applies `CREATE_NO_WINDOW` to all subprocesses via a `HideWindow` trait extension (Closes#165)
- **HTML escaping in markdown renderer** — escape `<` and `>` in `codespan` and `html` renderer callbacks to prevent raw HTML injection (Closes#169)
### Maintenance
- Verify stream-JSON handles tool results above the 50K threshold correctly (Closes#162)
- Reviewed hook security fixes from CLI 2.1.51 — not applicable to our setup (Closes#163)
- Expose org UUID from `claude auth status` (Closes#160)
- Clean up Svelte and Vite build warnings (`a11y_click_events_have_key_events`, `state_referenced_locally`, `non_reactive_update`, `codeSplitting`, chunk size, CodeMirror dynamic import)
- Update all npm dependencies to latest compatible versions with exact pinning (Closes#81, Closes#82, Closes#83, Closes#84, Closes#85, Closes#86, Closes#87, Closes#90, Closes#91, Closes#93, Closes#94, Closes#95, Closes#96, Closes#97, Closes#98, Closes#99, Closes#101, Closes#141, Closes#142, Closes#143, Closes#145, Closes#146, Closes#147)
- Run `cargo update` to bring Cargo.lock up to date
### Closes
Closes#160Closes#162Closes#163Closes#164Closes#165Closes#166Closes#167Closes#168Closes#169Closes#81Closes#82Closes#83Closes#84Closes#85Closes#86Closes#87Closes#90Closes#91Closes#93Closes#94Closes#95Closes#96Closes#97Closes#98Closes#99Closes#101Closes#141Closes#142Closes#143Closes#145Closes#146Closes#147✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #171
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
This PR bundles a collection of new features and quality-of-life improvements identified during a Claude CLI 2.1.50 audit.
- **Tab status indicator** — Tab stays yellow until the greeting is responded to, then turns green. Fixed disconnect not resetting to grey. Closes#157
- **Auth status display** — New "Account" section in settings sidebar showing login status, email, org, API key source, and Hikari override indicator. Includes login/logout buttons. Closes#153
- **CLI version badge** — New "Supported" badge showing the highest audited CLI version, colour-coded green/amber/red based on installed vs supported version. Closes#154 (bump to 2.1.50)
- **Rate limit events** — `rate_limit_event` messages from the stream are now parsed and shown as amber `[rate-limit]` lines in the terminal instead of being silently dropped. Closes#155
- **"Prompt is too long" handling** — Detects this error in assistant messages and shows a ⚡ Compact Conversation button to send `/compact` directly. Closes#158
- **`last_assistant_message` in Agent Monitor** — Extracts the agent's final output from the `ToolResult` content block in the JSON stream and displays it as a snippet on completed agent cards. Closes#156
- **`--worktree` flag** — New "Worktree isolation" toggle in session settings passes `--worktree` to Claude Code. Hook events (`WorktreeCreate`/`WorktreeRemove`) are displayed as green `[worktree]` lines. Closes#152, Closes#150
- **ConfigChange hook events** — `[ConfigChange Hook]` stderr events are now displayed as cyan `[config]` lines instead of errors. Closes#151
- **`CLAUDE_CODE_DISABLE_1M_CONTEXT` toggle** — New "Disable 1M context" setting in session configuration injects this env var into the Claude process. Closes#154
## Test plan
- [ ] Tab status indicator: start a new session and verify the tab stays yellow until Claude responds to the greeting, then turns green
- [ ] Auth status: open settings and verify the Account section shows correct login info
- [ ] CLI version badge: verify the "Supported 2.1.50" badge shows green when CLI matches
- [ ] Rate limit events: unit tests cover parsing; amber `[rate-limit]` lines display correctly
- [ ] Compact button: unit tests cover detection; button renders correctly in terminal
- [ ] Agent Monitor: use the Task tool and verify completed agent cards show a message snippet
- [ ] Worktree: enable toggle, start session, verify `--worktree` flag appears in process args
- [ ] ConfigChange: hook events display as `[config]` lines rather than errors
- [ ] Disable 1M context: enable toggle, start session, verify `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` in `/proc/<pid>/environ`
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #159
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
### New Features
- **Claude Sonnet 4.6 support** — added `claude-sonnet-4-6` as a selectable model in the config sidebar
- **Anime girl characters for subagents** — each subagent in the agent monitor is automatically assigned one of six characters (Amari, Keiko, Minori, Reina, Tatsumi, Yumiko) with a unique name, CDN avatar, title, and lore-flavoured description; assignment avoids duplicates when possible
- **"Meet the Team" cast panel** — a new modal accessible from the status bar introduces the full cast: Naomi (Chief hEx-ecutive Officer), Hikari (Chief Operating Officer), and the six subagent girls with their C-suite titles and character bios
### Bug Fixes
- **"Already running" error on invalid working directory** — if a spawned Claude process exits unexpectedly (e.g. because the working directory doesn't exist), `try_wait()` now detects the stale handle and clears it before allowing a restart
- **Working directory pre-validation** — on Windows, the app now runs `wsl -e test -d <dir>` before launching Claude; invalid directories surface a clear error immediately
- **WSL binary detection** — on Windows, `wsl -e bash -lc "which claude"` is used to probe for the Claude binary inside WSL; on Linux/WSLg, `bash -lc "which claude"` is used as a login-shell fallback so GUI apps find the binary even without shell PATH
- **WSL detection fix for production builds** — `detect_wsl()` now short-circuits at compile time on Windows targets, preventing inherited `WSL_DISTRO_NAME` env vars from misrouting native Windows binaries through the Linux code path
✨ This PR was crafted with love by Hikari~ 🌸
Reviewed-on: #149
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Fixes the memory files tab showing as empty on Windows production builds and the "forbidden path" error when trying to read memory files.
## Changes
### 1. List memory files from WSL home directory (commit 1)
- Split `list_memory_files()` into platform-specific implementations
- **Windows**: Use WSL command with `bash -l` to find memory files in WSL home (`~/.claude/projects/.../memory/`)
- **Linux/Mac**: Continue using native filesystem access
- Previously used `dirs::home_dir()` which returns Windows home (`C:\Users\...`), but Claude Code stores files in WSL home
### 2. Use backend command for reading files (commit 2)
- Changed frontend from Tauri's `readTextFile` plugin to `read_file_content` backend command
- Tauri plugin enforces scope restrictions and can't access WSL paths on Windows
- Our backend command already handles WSL paths correctly via `read_file_via_wsl()`
- Matches the pattern used throughout the app for other file operations
## Testing
- ✅ All 426 backend tests pass
- ✅ All frontend tests pass
- ✅ Lint, format, and type checks pass
- ✅ Follows existing WSL file operation patterns in codebase
## Related Issues
Fixes the memory files tab functionality on Windows whilst maintaining full compatibility with Linux/Mac.
✨ This PR was created by Hikari~ 🌸
Reviewed-on: #140
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
Resolves#137
## Summary
Claude CLI commands (plugin list, MCP list, version check, etc.) were being executed directly in Windows context where the `claude` binary doesn't exist, causing "program not found" errors across the UI.
This PR adds a helper function that automatically prefixes commands with `wsl` on Windows builds, ensuring all Claude CLI commands execute in the correct context.
## Changes
- **Added `create_claude_command()` helper function** that:
- On Windows: Creates command with `wsl claude` prefix
- On Linux/Mac: Creates command with `claude` directly
- **Updated 8 command functions** to use the helper:
- `get_claude_version`
- `list_plugins`
- `install_plugin`
- `uninstall_plugin`
- `list_mcp_servers`
- `remove_mcp_server`
- `add_mcp_server`
- `get_mcp_server_details`
- **Added comprehensive tests** for both Windows and Linux contexts
## What This Fixes
✅ Memory pane will now display files correctly
✅ CLI version will be detected properly
✅ Plugin pane will work correctly
✅ MCP servers pane will function properly
✅ All Claude CLI commands will execute in the correct context on Windows
## Testing
- ✅ All 427 backend tests pass (added 1 new test)
- ✅ All 387 frontend tests pass
- ✅ All linting and formatting checks pass
- ✅ `check-all.sh` reports: "✨ All checks passed!"
✨ This fix was created by Hikari~ 🌸
Reviewed-on: #139
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Add validation to check that the Claude CLI is installed before attempting to start a connection. If the `claude` binary is not found, users receive a helpful error message with installation instructions.
## Changes
- ✅ Add Claude binary check using `which` command in `WslBridge::start()`
- ✅ Return clear error message with installation command if not found
- ✅ Add test coverage for the binary check logic (`test_claude_binary_check_command_structure`)
- ✅ Update `CLAUDE.md` with Quality Assurance section documenting `check-all.sh`
## Error Message
If Claude Code is not installed, users will see:
```
Claude Code is not installed. Please install it using:
curl -fsSL https://claude.ai/install.sh | bash
```
## Testing
- All 427 backend tests pass ✅
- All 387 frontend tests pass ✅
- `check-all.sh` passes with no errors ✅
- New test validates the `which claude` command structure
## Documentation Updates
Added comprehensive Quality Assurance section to `CLAUDE.md` explaining:
- How to run `check-all.sh` before committing
- What checks are included and their order
- How to source necessary binaries (nvm for Node.js)
- Troubleshooting steps for failures
✨ This pull request was created by Hikari~ 🌸
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #138
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
This PR includes major feature additions, bug fixes, comprehensive testing improvements, and responsive design enhancements!
## New Features ✨
### Plugin & MCP Management (#133, #134)
- **Plugin Management Panel**: Install, uninstall, enable/disable, and update plugins
- **MCP Server Management Panel**: Add/remove MCP servers, view detailed configuration
- **Marketplace Management**: Add/remove plugin marketplaces from GitHub
- Backend commands for full CLI integration (`list_plugins`, `install_plugin`, `add_mcp_server`, etc.)
- Beautiful UI with proper loading states, error handling, and theme support
### Visual Todo List Panel (#132)
- Real-time todo list display when Hikari uses the `TodoWrite` tool
- Shows pending/in-progress/completed status with visual indicators
- Progress bar and completion count
- Automatically clears on disconnect
- Theme-aware styling
### Clear Session History Button (#130)
- "Clear All Sessions" button in Session History panel
- Confirmation dialog with session count
- Keyboard support and accessibility features
- Gives users control over disk usage
### CLI Version Display (#131)
- Displays Claude CLI version in status bar
- Auto-polls every 30 seconds for updates
- Useful for debugging and feature compatibility
## Bug Fixes 🐛
### Stats Panel Scrolling (#136)
- **Fixed stats panel overflow**: Added scrollable container with `max-height` constraint
- Stats panel now scrolls when content (Tools Used, Historical Costs, Budget sections) gets too long
- Prevents content from overflowing off screen
### Agent Monitor Fixes (#122)
- **Fixed agents stuck in "running" state**: Added `SubagentStop` hook parsing
- **Fixed agents persisting after disconnect**: Call `clearConversation()` on disconnect
- **Fixed "Kill All" button**: Now properly marks all agents as errored
- **Fixed badge persisting after tab close**: Cleanup agents when conversation is deleted
- Comprehensive tests for agent lifecycle management
### Discord RPC Cleanup (#129)
- Removed file-based logging for Discord RPC
- Replaced with proper `tracing` framework usage
- Reduces disk usage and eliminates maintenance burden
### Close Modal Bug Fix (#128)
- Fixed close confirmation modal not triggering after Discord RPC refactor
- Removed frontend calls to deleted `log_discord_rpc` command
- Modal now works correctly after all operations
### Responsive Design Fixes (#118)
- Fixed top navigation icons getting cut off at small screen widths
- Fixed Connect button disappearing on narrow screens
- Fixed bottom status info (clock, CLI version) getting cut off
- Added flex-wrap and mobile-optimised layouts
- Icons-only mode on screens < 640px
- Vertical stacking on screens < 768px
## Testing Improvements 🧪
### Comprehensive Test Coverage (#114)
- **417 backend tests** (up from 408)
- **387 frontend tests** (up from 363)
- **61%+ backend code coverage**
- Added E2E integration tests for cross-platform notification commands
- New test files: `agents.test.ts`, comprehensive CLI parsing tests
- Tests for `debug_logger.rs`, `bridge_manager.rs`, `notifications.rs`
- Console mocking for cleaner test output
- Fixed flaky frontend tests
### Testing Documentation
- Updated CLAUDE.md with comprehensive testing guidelines
- Documented mocking approaches (console mocking, E2E command structure testing)
- Added step-by-step guide for adding tests to new features
- Goal to maintain ~100% test coverage documented
## Closes
Closes#114Closes#118Closes#122Closes#128Closes#129Closes#130Closes#131Closes#132Closes#133Closes#134Closes#136
## Technical Details
- All new backend commands properly registered in `lib.rs`
- CLI output parsing with comprehensive test coverage
- Cross-platform compatibility verified through E2E tests (Linux CI can test Windows commands)
- Theme-aware UI components using CSS variables throughout
- Proper TypeScript types for all new stores and components
- ESLint and Prettier compliant
- All Clippy warnings addressed
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #135
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
This PR resolves several critical bugs that were blocking the permission modal and causing config loss:
- **Permission modal not appearing** - Fixed z-index issues and runtime errors
- **Config store race condition** - Resolved critical race condition causing settings to be lost
- **Excessive logging** - Removed redundant fmt layer that was writing to hidden stdout
- **System tool prompts** - Prevented unnecessary permission prompts for built-in tools
- **Permission batching** - Added support for parallel permission requests
- **ExitPlanMode tool** - Fixed ExitPlanMode tool not functioning correctly
## Changes Made
### Permission Modal Fixes
- Updated z-index to proper value (9999) to ensure modal appears above all other UI elements
- Fixed runtime errors that were preventing modal from rendering
- Resolved issues with permission grants not being properly applied
### Config Store Race Condition
- Fixed critical race condition where multiple rapid config updates would result in lost settings
- Ensured config writes are properly sequenced to prevent data loss
- Added proper synchronisation for config store operations
### Logging Cleanup
- Removed redundant fmt formatting layer that was outputting to hidden stdout
- Cleaned up excessive debug logging added during troubleshooting
- Removed temporary debugging documentation files
### UX Improvements
- Added close confirmation modal with minimise to tray option
- Implemented batching for parallel permission requests
- Added debug console for viewing frontend and backend logs
### ExitPlanMode Fix
- Fixed ExitPlanMode tool not functioning correctly, ensuring proper transitions out of plan mode
## Issues Resolved
Closes#112 - Permission flow now properly handles multiple tool requests
Closes#113 - ExitPlanMode tool now functions correctly
Closes#126 - Debug console feature added (partial - basic implementation complete)
## Test Plan
- [x] Permission modal appears and functions correctly
- [x] Config settings persist across app restarts
- [x] No excessive logging in production builds
- [x] System tools don't trigger permission prompts
- [x] Parallel permission requests are properly batched
- [x] Debug console displays frontend and backend logs
- [x] ExitPlanMode properly exits plan mode
---
✨ This PR was created with help from Hikari~ 🌸
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Reviewed-on: #127
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
Also includes a fix to persist configuration across reconnects.
Reviewed-on: #125
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #111
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
Also includes cached tokens in cost calculations to provide more accurate billing estimates.
Reviewed-on: #110
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #106
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #105
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
Closes#102
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #103
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #80
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
## Summary
- Add CodeMirror 6 editor with syntax highlighting for 40+ languages
- Add file browser sidebar with collapsible directory tree navigation
- Add multi-tab support with dirty state indicators and close buttons
- Add keyboard shortcuts (Ctrl+E toggle, Ctrl+B file browser, Ctrl+S save, Ctrl+W close tab)
- Add editor toggle button to status bar (disabled when not connected)
- Editor automatically uses current session's working directory
- Add Tauri backend commands for file operations (list_directory, read_file_content, write_file_content)
## Test Plan
- [ ] Connect to a session and verify the editor toggle button becomes enabled
- [ ] Press Ctrl+E to open the editor and verify file tree shows the session's CWD
- [ ] Navigate directories and open files to verify syntax highlighting works
- [ ] Edit a file and verify the dirty indicator (*) appears
- [ ] Save with Ctrl+S and verify the dirty indicator disappears
- [ ] Open multiple files and verify tab switching works
- [ ] Close tabs with Ctrl+W or the X button
- [ ] Disconnect and verify the editor automatically closes
- [ ] Verify keyboard shortcuts are documented in the shortcuts modal
Closes#72✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #79
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #77
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
### Explanation
_No response_
### Issue
_No response_
### Attestations
- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).
### Dependencies
- [ ] I have pinned the dependencies to a specific patch version.
### Style
- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.
### Tests
- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.
### Documentation
_No response_
### Versioning
_No response_
Reviewed-on: #76
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>