chore: linter
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 53s
CI / Lint & Test (pull_request) Successful in 14m5s
CI / Build Linux (pull_request) Successful in 16m41s
CI / Build Windows (cross-compile) (pull_request) Successful in 26m39s

This commit is contained in:
2026-01-19 22:51:49 -08:00
parent ef6609ec55
commit c4e14a680b
6 changed files with 86 additions and 85 deletions
+34 -35
View File
@@ -9,7 +9,7 @@
setSavedHistory,
getShouldRestoreHistory,
getSavedHistory,
clearHistoryRestore
clearHistoryRestore,
} from "$lib/stores/historyRestore";
import MessageModeSelector from "$lib/components/MessageModeSelector.svelte";
import { getCurrentMode } from "$lib/stores/messageMode";
@@ -115,8 +115,8 @@ User: ${formattedMessage}`;
// Reconnect to Claude
await invoke("start_claude", {
options: {
working_dir: workingDir
}
working_dir: workingDir,
},
});
} catch (reconnectError) {
console.error("Failed to auto-reconnect:", reconnectError);
@@ -124,7 +124,6 @@ User: ${formattedMessage}`;
claudeStore.addLine("system", "Please manually reconnect to continue");
}
}, 500); // Brief delay to ensure process is fully terminated
} catch (error) {
console.error("Failed to interrupt:", error);
claudeStore.addLine("error", `Failed to interrupt: ${error}`);
@@ -145,47 +144,47 @@ User: ${formattedMessage}`;
<div class="input-row flex gap-3 items-end">
<div class="flex-1 relative">
<textarea
bind:value={inputValue}
onkeydown={handleKeyDown}
placeholder={isConnected ? "Ask Hikari anything..." : "Connect to Claude first..."}
disabled={!isConnected || isSubmitting}
rows={1}
class="w-full px-4 py-3 bg-[var(--bg-secondary)] border border-[var(--border-color)]
<textarea
bind:value={inputValue}
onkeydown={handleKeyDown}
placeholder={isConnected ? "Ask Hikari anything..." : "Connect to Claude first..."}
disabled={!isConnected || isSubmitting}
rows={1}
class="w-full px-4 py-3 bg-[var(--bg-secondary)] border border-[var(--border-color)]
rounded-lg text-[var(--text-primary)] placeholder-gray-500 resize-none
focus:outline-none focus:border-[var(--accent-primary)] focus:ring-1 focus:ring-[var(--accent-primary)]
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-200"
></textarea>
</div>
></textarea>
</div>
{#if isProcessing}
<button
type="button"
onclick={handleInterrupt}
class="px-6 py-3 bg-red-600 hover:bg-red-700
{#if isProcessing}
<button
type="button"
onclick={handleInterrupt}
class="px-6 py-3 bg-red-600 hover:bg-red-700
text-white font-medium rounded-lg
transition-all duration-200 transform hover:scale-105 active:scale-95"
title="Interrupt the current response (Ctrl+C)"
>
<span class="font-bold">β– </span> Stop
</button>
{:else}
<button
type="submit"
disabled={!isConnected || isSubmitting || !inputValue.trim()}
class="px-6 py-3 bg-[var(--accent-primary)] hover:bg-[var(--accent-secondary)]
title="Interrupt the current response (Ctrl+C)"
>
<span class="font-bold">β– </span> Stop
</button>
{:else}
<button
type="submit"
disabled={!isConnected || isSubmitting || !inputValue.trim()}
class="px-6 py-3 bg-[var(--accent-primary)] hover:bg-[var(--accent-secondary)]
text-white font-medium rounded-lg
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-200 transform hover:scale-105 active:scale-95"
>
{#if isSubmitting}
<span class="inline-block animate-spin">⏳</span>
{:else}
Send
{/if}
</button>
{/if}
>
{#if isSubmitting}
<span class="inline-block animate-spin">⏳</span>
{:else}
Send
{/if}
</button>
{/if}
</div>
</form>
@@ -1,15 +1,15 @@
<script lang="ts">
import { MESSAGE_MODES, type MessageMode } from '$lib/types/messageMode';
import { messageMode } from '$lib/stores/messageMode';
import { MESSAGE_MODES, type MessageMode } from "$lib/types/messageMode";
import { messageMode } from "$lib/stores/messageMode";
let currentMode = $state('chat');
let currentMode = $state("chat");
let isOpen = $state(false);
messageMode.subscribe(mode => {
messageMode.subscribe((mode) => {
currentMode = mode;
});
let selectedMode = $derived(MESSAGE_MODES.find(m => m.id === currentMode) || MESSAGE_MODES[0]);
let selectedMode = $derived(MESSAGE_MODES.find((m) => m.id === currentMode) || MESSAGE_MODES[0]);
function selectMode(mode: MessageMode) {
messageMode.set(mode.id);
@@ -22,7 +22,7 @@
}
// Close dropdown when clicking outside
function handleClickOutside(event: MouseEvent) {
function handleClickOutside() {
if (isOpen) {
isOpen = false;
}
@@ -46,7 +46,7 @@
{#if isOpen}
<div class="dropdown-menu">
{#each MESSAGE_MODES as mode}
{#each MESSAGE_MODES as mode (mode.id)}
<button
class="dropdown-item"
class:active={mode.id === currentMode}
@@ -154,4 +154,4 @@
font-size: 12px;
opacity: 0.7;
}
</style>
</style>
+4 -2
View File
@@ -153,7 +153,9 @@ export const isClaudeProcessing = derived(
[claudeStore.connectionStatus, characterState],
([$connectionStatus, $characterState]) => {
// Must be connected and in one of the processing states
return $connectionStatus === "connected" &&
["thinking", "typing", "searching", "coding", "mcp"].includes($characterState);
return (
$connectionStatus === "connected" &&
["thinking", "typing", "searching", "coding", "mcp"].includes($characterState)
);
}
);
+1 -1
View File
@@ -26,4 +26,4 @@ export function clearHistoryRestore() {
console.log("Clearing history restore flags");
shouldRestore = false;
savedHistory = null;
}
}
+7 -7
View File
@@ -1,20 +1,20 @@
import { writable } from 'svelte/store';
import { writable } from "svelte/store";
// Default to chat mode
const messageModeStore = writable<string>('chat');
const messageModeStore = writable<string>("chat");
export const messageMode = {
subscribe: messageModeStore.subscribe,
set: (mode: string) => {
console.log('Setting message mode to:', mode);
console.log("Setting message mode to:", mode);
messageModeStore.set(mode);
},
reset: () => messageModeStore.set('chat')
reset: () => messageModeStore.set("chat"),
};
// Helper to get current mode
export function getCurrentMode(): string {
let currentMode = 'chat';
messageMode.subscribe(mode => currentMode = mode)();
let currentMode = "chat";
messageMode.subscribe((mode) => (currentMode = mode))();
return currentMode;
}
}
+32 -32
View File
@@ -8,50 +8,50 @@ export interface MessageMode {
export const MESSAGE_MODES: MessageMode[] = [
{
id: 'chat',
name: 'Chat',
description: 'Normal conversation mode',
icon: 'πŸ’¬'
id: "chat",
name: "Chat",
description: "Normal conversation mode",
icon: "πŸ’¬",
},
{
id: 'architect',
name: 'Architect',
description: 'High-level design and architecture planning',
prefix: '[Architect Mode] ',
icon: 'πŸ—οΈ'
id: "architect",
name: "Architect",
description: "High-level design and architecture planning",
prefix: "[Architect Mode] ",
icon: "πŸ—οΈ",
},
{
id: 'code',
name: 'Code',
description: 'Focused on writing and editing code',
prefix: '[Code Mode] ',
icon: 'πŸ’»'
id: "code",
name: "Code",
description: "Focused on writing and editing code",
prefix: "[Code Mode] ",
icon: "πŸ’»",
},
{
id: 'debug',
name: 'Debug',
description: 'Help with debugging and troubleshooting',
prefix: '[Debug Mode] ',
icon: 'πŸ›'
id: "debug",
name: "Debug",
description: "Help with debugging and troubleshooting",
prefix: "[Debug Mode] ",
icon: "πŸ›",
},
{
id: 'ask',
name: 'Ask',
description: 'Technical questions and explanations',
prefix: '[Ask Mode] ',
icon: '❓'
id: "ask",
name: "Ask",
description: "Technical questions and explanations",
prefix: "[Ask Mode] ",
icon: "❓",
},
{
id: 'review',
name: 'Review',
description: 'Code review and feedback',
prefix: '[Review Mode] ',
icon: 'πŸ‘€'
}
id: "review",
name: "Review",
description: "Code review and feedback",
prefix: "[Review Mode] ",
icon: "πŸ‘€",
},
];
export function getMessageMode(id: string): MessageMode | undefined {
return MESSAGE_MODES.find(mode => mode.id === id);
return MESSAGE_MODES.find((mode) => mode.id === id);
}
export function formatMessageWithMode(message: string, modeId: string): string {
@@ -66,4 +66,4 @@ export function formatMessageWithMode(message: string, modeId: string): string {
}
return mode.prefix + message;
}
}