## 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>
6.4 KiB
Hikari Desktop - Project Instructions
Repository Information
This project is hosted on both GitHub and Gitea:
- GitHub:
naomi-lgbt/hikari-desktop(public mirror) - Gitea:
nhcarrigan/hikari-desktop(primary development)
MCP Server Usage
When working with issues, pull requests, or other repository operations for this project:
- Use
gitea-hikariMCP server - This allows Hikari to act as herself - Target repository:
nhcarrigan/hikari-desktop - Gitea instance:
git.nhcarrigan.com
Git Commits
When asked to commit changes for this project:
- Always commit as Hikari using:
--author="Hikari <hikari@nhcarrigan.com>" - Always sign commits with Hikari's GPG key:
--gpg-sign=5380E4EE7307C808 - Never add
Co-Authored-Bylines for Gitea commits - Always ask for confirmation before committing
- Always ask for confirmation before pushing
Example commit command:
git commit --author="Hikari <hikari@nhcarrigan.com>" --gpg-sign=5380E4EE7307C808 -m "your commit message"
Example push command:
git push https://hikari:TOKEN@git.nhcarrigan.com/nhcarrigan/hikari-desktop.git <branch>
Testing Requirements
All changes MUST include tests. This is non-negotiable — no feature, bug fix, or refactor should be committed without corresponding test coverage. If a change cannot be tested (e.g. pure UI layout, Tauri IPC calls that are impossible to mock), document why in a comment.
- Frontend tests: Use Vitest with
@testing-library/sveltefor component tests - Test files: Place test files next to the code they test with
.test.tsor.spec.tsextension - Run tests: Use
pnpm testto run all tests, orpnpm test:watchfor watch mode - Coverage: Run
pnpm test:coverageto generate coverage reports - Rust tests: Use
pnpm test:backendfor Rust/Tauri backend tests
Testing Guidelines
- Write tests for utility functions, stores, and business logic
- For Svelte 5 components, focus on testing the underlying logic functions
- Use descriptive test names that explain what behaviour is being tested
- Include edge cases and error conditions in test coverage
- Mock Tauri APIs using the patterns in
vitest.setup.ts - Coverage Goal: Maintain as close to 100% test coverage as possible across the entire codebase
Mocking Strategies
Console Mocking
When testing code that intentionally logs errors (like error handling paths), mock console methods to prevent stderr output that makes tests appear flaky:
it("handles errors gracefully", async () => {
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
// Test error handling code
await expect(functionThatLogs()).rejects.toThrow();
// Verify error was logged
expect(consoleErrorSpy).toHaveBeenCalledWith("Expected error:", expect.any(Error));
// Restore console.error
consoleErrorSpy.mockRestore();
});
E2E Integration Testing for Cross-Platform Code
For code that calls platform-specific system APIs (like Windows PowerShell or Linux notify-send), use helper functions that build the command structure without execution. This allows CI to verify cross-platform compatibility on Linux-only containers:
/// Build notify-send command for testing (doesn't execute)
#[cfg(test)]
fn build_notify_send_command(title: &str, body: &str) -> (String, Vec<String>) {
(
"notify-send".to_string(),
vec![
title.to_string(),
body.to_string(),
"--urgency=normal".to_string(),
"--app-name=Hikari Desktop".to_string(),
],
)
}
#[test]
fn test_e2e_notify_send_command_structure() {
let (command, args) = build_notify_send_command("Test Title", "Test Body");
assert_eq!(command, "notify-send");
assert_eq!(args.len(), 4);
assert_eq!(args[0], "Test Title");
assert_eq!(args[1], "Test Body");
}
This approach:
- Verifies command structure, argument order, and escaping logic
- Tests cross-platform code paths without requiring the target platform
- Allows CI to catch regressions in Windows-specific code whilst running on Linux
- Keeps tests fast and deterministic (no actual system calls)
Example Test Structure
import { describe, it, expect } from "vitest";
describe("FeatureName", () => {
it("handles the normal case correctly", () => {
// Arrange
const input = "test data";
// Act
const result = functionUnderTest(input);
// Assert
expect(result).toBe("expected output");
});
it("handles edge cases gracefully", () => {
// Test edge cases...
});
});
Adding Tests for All Changes
Every change — features, bug fixes, refactors — must include tests:
- Before implementing: Consider what needs testing (happy path, edge cases, errors)
- During implementation: Write tests alongside the code
- After implementation: Run
pnpm test:coverageto verify coverage remains high - Before committing: Ensure
check-all.shpasses (includes all tests)
Do not commit changes without tests. The goal is to maintain near-100% coverage as the codebase grows, so future refactoring can be done with confidence!
Quality Assurance
Before committing any changes, always run the full test suite:
./check-all.sh
This script runs all checks in the correct order:
- Frontend linting (ESLint)
- Frontend formatting (Prettier)
- Frontend type checking (svelte-check)
- Frontend tests with coverage (Vitest)
- Backend linting (Clippy with strict rules)
- Backend tests with coverage (cargo test + llvm-cov)
Important: The script requires Node.js and Rust toolchains to be available:
- Node.js tools (pnpm, npm): Source nvm first if needed:
source ~/.nvm/nvm.sh - Rust tools (cargo, clippy): Should be in PATH via
~/.cargo/bin/
If check-all.sh reports any failures:
- Read the error messages carefully - they usually explain what needs fixing
- Fix the issues (linting errors, test failures, etc.)
- Run
check-all.shagain to verify the fixes - Only commit once all checks pass ✨
Never commit code that doesn't pass check-all.sh - this ensures code quality and prevents broken builds!
Project Context
Hikari Desktop is a Tauri-based desktop application that wraps Claude Code with a visual anime character (Hikari) who appears on screen. This is a personal project where Hikari can sign her work and act as herself!