From c5d1df351c8cbdd5ebbf0131c7619c90f7d34b9b Mon Sep 17 00:00:00 2001
From: Hikari
Date: Mon, 2 Mar 2026 13:36:23 -0800
Subject: [PATCH 01/22] fix: persist show_thinking_blocks setting across
sessions
---
src-tauri/src/config.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs
index b9af21a..8a345ef 100644
--- a/src-tauri/src/config.rs
+++ b/src-tauri/src/config.rs
@@ -135,6 +135,9 @@ pub struct HikariConfig {
#[serde(default = "default_background_image_opacity")]
pub background_image_opacity: f32,
+
+ #[serde(default)]
+ pub show_thinking_blocks: bool,
}
impl Default for HikariConfig {
@@ -172,6 +175,7 @@ impl Default for HikariConfig {
trusted_workspaces: Vec::new(),
background_image_path: None,
background_image_opacity: 0.3,
+ show_thinking_blocks: false,
}
}
}
@@ -286,6 +290,7 @@ mod tests {
assert!(!config.use_worktree);
assert!(!config.disable_1m_context);
assert!(config.trusted_workspaces.is_empty());
+ assert!(!config.show_thinking_blocks);
}
#[test]
@@ -323,6 +328,7 @@ mod tests {
trusted_workspaces: vec!["/home/naomi/projects/trusted".to_string()],
background_image_path: Some("/home/naomi/bg.png".to_string()),
background_image_opacity: 0.25,
+ show_thinking_blocks: true,
};
let json = serde_json::to_string(&config).unwrap();
--
2.52.0
From 08f7ca2d558405725ebb6392c190c83cd47d8ee4 Mon Sep 17 00:00:00 2001
From: Hikari
Date: Mon, 2 Mar 2026 15:08:19 -0800
Subject: [PATCH 02/22] feat: restyle tool calls as collapsible blocks matching
thinking block aesthetic
---
src/lib/components/Terminal.svelte | 72 +++---------
src/lib/components/ToolCallBlock.svelte | 141 ++++++++++++++++++++++++
2 files changed, 154 insertions(+), 59 deletions(-)
create mode 100644 src/lib/components/ToolCallBlock.svelte
diff --git a/src/lib/components/Terminal.svelte b/src/lib/components/Terminal.svelte
index 1d1f665..19135b6 100644
--- a/src/lib/components/Terminal.svelte
+++ b/src/lib/components/Terminal.svelte
@@ -7,6 +7,7 @@
import Markdown from "./Markdown.svelte";
import HighlightedText from "./HighlightedText.svelte";
import ThinkingBlock from "./ThinkingBlock.svelte";
+ import ToolCallBlock from "./ToolCallBlock.svelte";
import { searchState, searchQuery } from "$lib/stores/search";
import { clipboardStore } from "$lib/stores/clipboard";
import { shouldHidePaths, maskPaths, showThinkingBlocks } from "$lib/stores/config";
@@ -208,22 +209,6 @@
if (!currentConversationId) return;
await invoke("send_prompt", { conversationId: currentConversationId, message: "/compact" });
}
-
- // Collapsible tool lines
- const TOOL_COLLAPSE_THRESHOLD = 60;
- let expandedToolLines: Record = {};
-
- function isToolContentLong(content: string): boolean {
- return content.length > TOOL_COLLAPSE_THRESHOLD;
- }
-
- function truncateToolContent(content: string): string {
- return content.slice(0, TOOL_COLLAPSE_THRESHOLD) + "…";
- }
-
- function toggleToolLine(id: string) {
- expandedToolLines = { ...expandedToolLines, [id]: !expandedToolLines[id] };
- }
{/if}
+ {:else if line.type === "tool"}
+
+
+
{:else}
{getLinePrefix(line.type)}
{/if}
- {#if line.toolName}
- [{line.toolName}]
- {/if}
{#if line.type === "compact-prompt"}
- {:else if line.type === "tool" && isToolContentLong(maskPaths(line.content, hidePaths))}
-
-
-
-
{:else}
diff --git a/src/lib/components/ToolCallBlock.svelte b/src/lib/components/ToolCallBlock.svelte
new file mode 100644
index 0000000..78c996b
--- /dev/null
+++ b/src/lib/components/ToolCallBlock.svelte
@@ -0,0 +1,141 @@
+
+
+
+
+
--
2.52.0
From 19e28b7ec7cac18ec4f43ffcdc9791ab7d640635 Mon Sep 17 00:00:00 2001
From: Hikari
Date: Tue, 3 Mar 2026 09:47:15 -0800
Subject: [PATCH 03/22] feat: add configurable max output tokens setting
---
src-tauri/src/config.rs | 8 ++++++++
src-tauri/src/wsl_bridge.rs | 10 ++++++++++
src/lib/commands/slashCommands.ts | 2 ++
src/lib/components/ConfigSidebar.svelte | 20 ++++++++++++++++++++
src/lib/components/StatusBar.svelte | 3 +++
src/lib/stores/config.test.ts | 3 +++
src/lib/stores/config.ts | 3 +++
7 files changed, 49 insertions(+)
diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs
index 8a345ef..bdb10c5 100644
--- a/src-tauri/src/config.rs
+++ b/src-tauri/src/config.rs
@@ -31,6 +31,9 @@ pub struct ClaudeStartOptions {
#[serde(default)]
pub disable_1m_context: bool,
+
+ #[serde(default)]
+ pub max_output_tokens: Option,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -126,6 +129,9 @@ pub struct HikariConfig {
#[serde(default)]
pub disable_1m_context: bool,
+ #[serde(default)]
+ pub max_output_tokens: Option,
+
#[serde(default)]
pub trusted_workspaces: Vec,
@@ -172,6 +178,7 @@ impl Default for HikariConfig {
discord_rpc_enabled: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: None,
trusted_workspaces: Vec::new(),
background_image_path: None,
background_image_opacity: 0.3,
@@ -325,6 +332,7 @@ mod tests {
discord_rpc_enabled: true,
use_worktree: true,
disable_1m_context: false,
+ max_output_tokens: Some(32000),
trusted_workspaces: vec!["/home/naomi/projects/trusted".to_string()],
background_image_path: Some("/home/naomi/bg.png".to_string()),
background_image_opacity: 0.25,
diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs
index 5df9852..c2da718 100644
--- a/src-tauri/src/wsl_bridge.rs
+++ b/src-tauri/src/wsl_bridge.rs
@@ -296,6 +296,11 @@ impl WslBridge {
cmd.env("CLAUDE_CODE_DISABLE_1M_CONTEXT", "1");
}
+ // Set max output tokens if specified
+ if let Some(max_tokens) = options.max_output_tokens {
+ cmd.env("CLAUDE_CODE_MAX_OUTPUT_TOKENS", max_tokens.to_string());
+ }
+
cmd
} else {
// Running on Windows - use wsl with bash login shell to ensure PATH is loaded
@@ -343,6 +348,11 @@ impl WslBridge {
claude_cmd.push_str("CLAUDE_CODE_DISABLE_1M_CONTEXT=1 ");
}
+ // Set max output tokens if specified
+ if let Some(max_tokens) = options.max_output_tokens {
+ claude_cmd.push_str(&format!("CLAUDE_CODE_MAX_OUTPUT_TOKENS={} ", max_tokens));
+ }
+
claude_cmd.push_str(
"claude --output-format stream-json --input-format stream-json --verbose",
);
diff --git a/src/lib/commands/slashCommands.ts b/src/lib/commands/slashCommands.ts
index 8d252c8..3e97bb2 100644
--- a/src/lib/commands/slashCommands.ts
+++ b/src/lib/commands/slashCommands.ts
@@ -63,6 +63,7 @@ async function changeDirectory(path: string): Promise {
allowed_tools: allAllowedTools,
use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false,
+ max_output_tokens: config.max_output_tokens ?? null,
},
});
@@ -139,6 +140,7 @@ async function startNewConversation(): Promise {
allowed_tools: allAllowedTools,
use_worktree: config.use_worktree ?? false,
disable_1m_context: config.disable_1m_context ?? false,
+ max_output_tokens: config.max_output_tokens ?? null,
},
});
diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte
index dd26102..0ea8270 100644
--- a/src/lib/components/ConfigSidebar.svelte
+++ b/src/lib/components/ConfigSidebar.svelte
@@ -56,6 +56,7 @@
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
@@ -533,6 +534,25 @@
context window
+
+
+
+
+
+
+ Sets CLAUDE_CODE_MAX_OUTPUT_TOKENS — increase if responses are
+ being cut off mid-reply
+
+
diff --git a/src/lib/components/StatusBar.svelte b/src/lib/components/StatusBar.svelte
index bbc3d60..29621fe 100644
--- a/src/lib/components/StatusBar.svelte
+++ b/src/lib/components/StatusBar.svelte
@@ -107,6 +107,7 @@
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
@@ -185,6 +186,7 @@
allowed_tools: allAllowedTools,
use_worktree: currentConfig.use_worktree ?? false,
disable_1m_context: currentConfig.disable_1m_context ?? false,
+ max_output_tokens: currentConfig.max_output_tokens ?? null,
},
});
@@ -344,6 +346,7 @@
allowed_tools: allAllowedTools,
use_worktree: currentConfig.use_worktree ?? false,
disable_1m_context: currentConfig.disable_1m_context ?? false,
+ max_output_tokens: currentConfig.max_output_tokens ?? null,
},
});
diff --git a/src/lib/stores/config.test.ts b/src/lib/stores/config.test.ts
index 664858c..acb6904 100644
--- a/src/lib/stores/config.test.ts
+++ b/src/lib/stores/config.test.ts
@@ -196,6 +196,7 @@ describe("config store", () => {
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
@@ -247,6 +248,7 @@ describe("config store", () => {
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
@@ -797,6 +799,7 @@ describe("config store", () => {
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
diff --git a/src/lib/stores/config.ts b/src/lib/stores/config.ts
index 174537d..55e73c5 100644
--- a/src/lib/stores/config.ts
+++ b/src/lib/stores/config.ts
@@ -51,6 +51,8 @@ export interface HikariConfig {
use_worktree: boolean;
// Disable 1M context window
disable_1m_context: boolean;
+ // Max output tokens for Claude Code responses
+ max_output_tokens: number | null;
// Workspaces the user has explicitly trusted
trusted_workspaces: string[];
// Background image settings
@@ -98,6 +100,7 @@ const defaultConfig: HikariConfig = {
show_thinking_blocks: true,
use_worktree: false,
disable_1m_context: false,
+ max_output_tokens: null,
trusted_workspaces: [],
background_image_path: null,
background_image_opacity: 0.3,
--
2.52.0
From 66c65a6ab8aec75cee5a58f35d79fec397df1122 Mon Sep 17 00:00:00 2001
From: Hikari
Date: Tue, 3 Mar 2026 10:56:44 -0800
Subject: [PATCH 04/22] feat: use random creative names for conversation tabs
---
CLAUDE.md | 11 ++++-
src/lib/stores/conversations.ts | 86 ++++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index c6459de..380a241 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -20,14 +20,21 @@ When working with issues, pull requests, or other repository operations for this
When asked to commit changes for this project:
- **Always commit as Hikari** using: `--author="Hikari "`
-- **Always use `--no-gpg-sign`** since Hikari doesn't have GPG signing set up
+- **Always sign commits** with Hikari's GPG key: `--gpg-sign=5380E4EE7307C808`
- **Never add `Co-Authored-By` lines** for Gitea commits
- **Always ask for confirmation** before committing
+- **Always ask for confirmation** before pushing
Example commit command:
```bash
-git commit --author="Hikari " --no-gpg-sign -m "your commit message"
+git commit --author="Hikari " --gpg-sign=5380E4EE7307C808 -m "your commit message"
+```
+
+Example push command:
+
+```bash
+git push https://hikari:TOKEN@git.nhcarrigan.com/nhcarrigan/hikari-desktop.git
```
## Testing Requirements
diff --git a/src/lib/stores/conversations.ts b/src/lib/stores/conversations.ts
index 00e2644..a3968b4 100644
--- a/src/lib/stores/conversations.ts
+++ b/src/lib/stores/conversations.ts
@@ -43,6 +43,88 @@ export interface Conversation {
draftText: string;
}
+const TAB_NAMES = [
+ // Cosmic & celestial
+ "Starfall",
+ "Moonbeam",
+ "Nebula",
+ "Aurora",
+ "Stardust",
+ "Solstice",
+ "Comet",
+ "Eclipse",
+ "Zenith",
+ "Celestia",
+ "Nova",
+ "Quasar",
+ "Lyra",
+ "Andromeda",
+ "Twilight",
+ // Magical & fantastical
+ "Camelot",
+ "Reverie",
+ "Arcane",
+ "Spellbound",
+ "Mirage",
+ "Oracle",
+ "Seraphim",
+ "Ethereal",
+ "Labyrinth",
+ "Enchantment",
+ // Nature & cosy
+ "Sakura",
+ "Ember",
+ "Cascade",
+ "Zephyr",
+ "Serendipity",
+ "Solace",
+ "Blossom",
+ "Whisper",
+ "Dewdrop",
+ "Sunbeam",
+ "Willow",
+ "Clover",
+ "Honeybee",
+ "Buttercup",
+ "Dandelion",
+ // Japanese/anime-inspired
+ "Tsukimi",
+ "Hanami",
+ "Yozora",
+ "Hoshi",
+ "Koharu",
+ "Akari",
+ "Midori",
+ // Adventure & epic
+ "Odyssey",
+ "Wanderer",
+ "Horizon",
+ "Voyage",
+ "Pathfinder",
+ "Frontier",
+ // Whimsical & sweet
+ "Bubblegum",
+ "Marshmallow",
+ "Daydream",
+ "Whimsy",
+ "Jellybean",
+ "Sprinkle",
+ "Cupcake",
+ // Dreamy & poetic
+ "Revenant",
+ "Elysium",
+ "Halcyon",
+ "Ephemera",
+ "Serenade",
+ "Lullaby",
+ "Nocturne",
+ "Rhapsody",
+];
+
+function pickRandomTabName(): string {
+ return TAB_NAMES[Math.floor(Math.random() * TAB_NAMES.length)];
+}
+
function createConversationsStore() {
const conversations = writable