generated from nhcarrigan/template
chore: linter
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import { claudeStore } from "$lib/stores/claude";
|
import { claudeStore } from "$lib/stores/claude";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import type { Conversation } from "$lib/stores/conversations";
|
import type { Conversation } from "$lib/stores/conversations";
|
||||||
|
import { SvelteMap } from "svelte/reactivity";
|
||||||
|
|
||||||
let conversations: Map<string, Conversation> = new Map();
|
let conversations: Map<string, Conversation> = new Map();
|
||||||
let activeConversationId: string | null = null;
|
let activeConversationId: string | null = null;
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
let connectedConversationId: string | null = null;
|
let connectedConversationId: string | null = null;
|
||||||
|
|
||||||
// Track last seen message count for each conversation
|
// Track last seen message count for each conversation
|
||||||
let lastSeenMessageCount: Map<string, number> = new Map();
|
let lastSeenMessageCount = new SvelteMap<string, number>();
|
||||||
|
|
||||||
claudeStore.conversations.subscribe((convs) => {
|
claudeStore.conversations.subscribe((convs) => {
|
||||||
conversations = convs;
|
conversations = convs;
|
||||||
@@ -75,6 +76,11 @@
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
editingTabId = id;
|
editingTabId = id;
|
||||||
editingName = name;
|
editingName = name;
|
||||||
|
// Focus input after DOM update
|
||||||
|
setTimeout(() => {
|
||||||
|
const input = document.querySelector('.tab-item input[type="text"]') as HTMLInputElement;
|
||||||
|
if (input) input.focus();
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveTabName() {
|
function saveTabName() {
|
||||||
@@ -113,6 +119,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleTabKeydown(id: string, event: KeyboardEvent) {
|
||||||
|
if (event.key === "Enter" || event.key === " ") {
|
||||||
|
event.preventDefault();
|
||||||
|
switchTab(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
function handleGlobalKeydown(event: KeyboardEvent) {
|
function handleGlobalKeydown(event: KeyboardEvent) {
|
||||||
@@ -165,6 +178,7 @@
|
|||||||
? 'bg-[var(--bg-terminal)] text-[var(--text-primary)] border-t border-l border-r border-[var(--border-color)]'
|
? 'bg-[var(--bg-terminal)] text-[var(--text-primary)] border-t border-l border-r border-[var(--border-color)]'
|
||||||
: 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] hover:bg-[var(--bg-terminal)]/50'}"
|
: 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] hover:bg-[var(--bg-terminal)]/50'}"
|
||||||
onclick={() => switchTab(id)}
|
onclick={() => switchTab(id)}
|
||||||
|
onkeydown={(e) => handleTabKeydown(id, e)}
|
||||||
role="tab"
|
role="tab"
|
||||||
tabindex={0}
|
tabindex={0}
|
||||||
aria-selected={id === activeConversationId}
|
aria-selected={id === activeConversationId}
|
||||||
@@ -177,22 +191,29 @@
|
|||||||
onkeydown={handleKeydown}
|
onkeydown={handleKeydown}
|
||||||
onclick={(e) => e.stopPropagation()}
|
onclick={(e) => e.stopPropagation()}
|
||||||
class="bg-transparent border-b border-[var(--border-color)] outline-none px-0 py-0 text-sm w-32"
|
class="bg-transparent border-b border-[var(--border-color)] outline-none px-0 py-0 text-sm w-32"
|
||||||
autofocus
|
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div
|
<div
|
||||||
class="w-2 h-2 rounded-full {getConnectionStatusColor(conversation.connectionStatus)}"
|
class="w-2 h-2 rounded-full {getConnectionStatusColor(conversation.connectionStatus)}"
|
||||||
title="Connection: {conversation.connectionStatus}{id !== connectedConversationId && connectedConversationId ? ' (Another tab is connected)' : ''}"
|
title="Connection: {conversation.connectionStatus}{id !== connectedConversationId &&
|
||||||
/>
|
connectedConversationId
|
||||||
|
? ' (Another tab is connected)'
|
||||||
|
: ''}"
|
||||||
|
></div>
|
||||||
<span
|
<span
|
||||||
class="text-sm pr-6 max-w-[150px] truncate"
|
class="text-sm pr-6 max-w-[150px] truncate"
|
||||||
ondblclick={(e) => startEditing(id, conversation.name, e)}
|
ondblclick={(e) => startEditing(id, conversation.name, e)}
|
||||||
|
role="button"
|
||||||
|
tabindex={-1}
|
||||||
>
|
>
|
||||||
{conversation.name}
|
{conversation.name}
|
||||||
</span>
|
</span>
|
||||||
{#if id !== activeConversationId && id === connectedConversationId}
|
{#if id !== activeConversationId && id === connectedConversationId}
|
||||||
<span class="text-xs text-[var(--text-tertiary)]" title="This tab has the Claude connection">
|
<span
|
||||||
|
class="text-xs text-[var(--text-tertiary)]"
|
||||||
|
title="This tab has the Claude connection"
|
||||||
|
>
|
||||||
(connected)
|
(connected)
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -200,7 +221,7 @@
|
|||||||
<div
|
<div
|
||||||
class="absolute -top-1 -right-1 w-2 h-2 rounded-full bg-blue-500 animate-pulse"
|
class="absolute -top-1 -right-1 w-2 h-2 rounded-full bg-blue-500 animate-pulse"
|
||||||
title="New messages"
|
title="New messages"
|
||||||
/>
|
></div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -242,12 +263,7 @@
|
|||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M12 4v16m8-8H4"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -260,4 +276,4 @@
|
|||||||
.tab-item {
|
.tab-item {
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
<div class="terminal-tabs" style="background: red; height: 36px; color: white;">
|
<div class="terminal-tabs" style="background: red; height: 36px; color: white;">
|
||||||
Debug: Tabs Component Loaded
|
Debug: Tabs Component Loaded
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ User: ${formattedMessage}`;
|
|||||||
}
|
}
|
||||||
await invoke("send_prompt", {
|
await invoke("send_prompt", {
|
||||||
conversationId,
|
conversationId,
|
||||||
message: messageToSend
|
message: messageToSend,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to send prompt:", error);
|
console.error("Failed to send prompt:", error);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ Please continue where we left off and retry that action now that you have permis
|
|||||||
|
|
||||||
await invoke("send_prompt", {
|
await invoke("send_prompt", {
|
||||||
conversationId,
|
conversationId,
|
||||||
message: contextMessage
|
message: contextMessage,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { derived } from "svelte/store";
|
import { derived } from "svelte/store";
|
||||||
import { conversationsStore } from "./conversations";
|
import { conversationsStore } from "./conversations";
|
||||||
import type { ConnectionStatus, PermissionRequest, TerminalLine } from "$lib/types/messages";
|
import type { TerminalLine } from "$lib/types/messages";
|
||||||
import { characterState } from "$lib/stores/character";
|
import { characterState } from "$lib/stores/character";
|
||||||
import {
|
import {
|
||||||
setShouldRestoreHistory,
|
setShouldRestoreHistory,
|
||||||
|
|||||||
@@ -76,14 +76,23 @@ function createConversationsStore() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Derived stores for compatibility with existing code
|
// Derived stores for compatibility with existing code
|
||||||
const connectionStatus = derived(activeConversation, ($conv) => $conv?.connectionStatus || "disconnected");
|
const connectionStatus = derived(
|
||||||
|
activeConversation,
|
||||||
|
($conv) => $conv?.connectionStatus || "disconnected"
|
||||||
|
);
|
||||||
const terminalLines = derived(activeConversation, ($conv) => {
|
const terminalLines = derived(activeConversation, ($conv) => {
|
||||||
return $conv?.terminalLines || [];
|
return $conv?.terminalLines || [];
|
||||||
});
|
});
|
||||||
const sessionId = derived(activeConversation, ($conv) => $conv?.sessionId || null);
|
const sessionId = derived(activeConversation, ($conv) => $conv?.sessionId || null);
|
||||||
const currentWorkingDirectory = derived(activeConversation, ($conv) => $conv?.workingDirectory || "");
|
const currentWorkingDirectory = derived(
|
||||||
|
activeConversation,
|
||||||
|
($conv) => $conv?.workingDirectory || ""
|
||||||
|
);
|
||||||
const isProcessing = derived(activeConversation, ($conv) => $conv?.isProcessing || false);
|
const isProcessing = derived(activeConversation, ($conv) => $conv?.isProcessing || false);
|
||||||
const grantedTools = derived(activeConversation, ($conv) => $conv?.grantedTools || new Set());
|
const grantedTools = derived(
|
||||||
|
activeConversation,
|
||||||
|
($conv) => $conv?.grantedTools || new Set<string>()
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Expose derived stores for compatibility
|
// Expose derived stores for compatibility
|
||||||
@@ -198,7 +207,6 @@ function createConversationsStore() {
|
|||||||
if (targetConv) {
|
if (targetConv) {
|
||||||
characterState.setState(targetConv.characterState);
|
characterState.setState(targetConv.characterState);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -304,7 +312,12 @@ function createConversationsStore() {
|
|||||||
return line.id;
|
return line.id;
|
||||||
},
|
},
|
||||||
|
|
||||||
addLineToConversation: (conversationId: string, type: TerminalLine["type"], content: string, toolName?: string) => {
|
addLineToConversation: (
|
||||||
|
conversationId: string,
|
||||||
|
type: TerminalLine["type"],
|
||||||
|
content: string,
|
||||||
|
toolName?: string
|
||||||
|
) => {
|
||||||
ensureInitialized();
|
ensureInitialized();
|
||||||
|
|
||||||
const line: TerminalLine = {
|
const line: TerminalLine = {
|
||||||
@@ -443,4 +456,4 @@ function createConversationsStore() {
|
|||||||
|
|
||||||
export const conversationsStore = createConversationsStore();
|
export const conversationsStore = createConversationsStore();
|
||||||
// Initialize immediately
|
// Initialize immediately
|
||||||
conversationsStore.initialize();
|
conversationsStore.initialize();
|
||||||
|
|||||||
+22
-7
@@ -21,7 +21,7 @@ interface StateChangePayload {
|
|||||||
conversation_id?: string;
|
conversation_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let connectedConversations = new Set<string>();
|
const connectedConversations = new Set<string>();
|
||||||
let unlisteners: Array<() => void> = [];
|
let unlisteners: Array<() => void> = [];
|
||||||
let skipNextGreeting = false;
|
let skipNextGreeting = false;
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ async function sendGreeting(conversationId: string) {
|
|||||||
try {
|
try {
|
||||||
await invoke("send_prompt", {
|
await invoke("send_prompt", {
|
||||||
conversationId,
|
conversationId,
|
||||||
message: greetingPrompt
|
message: greetingPrompt,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to send greeting:", error);
|
console.error("Failed to send greeting:", error);
|
||||||
@@ -140,7 +140,11 @@ export async function initializeTauriListeners() {
|
|||||||
|
|
||||||
if (targetConversationId) {
|
if (targetConversationId) {
|
||||||
// Add system message to the correct conversation
|
// Add system message to the correct conversation
|
||||||
claudeStore.addLineToConversation(targetConversationId, "system", "Connected to Claude Code");
|
claudeStore.addLineToConversation(
|
||||||
|
targetConversationId,
|
||||||
|
"system",
|
||||||
|
"Connected to Claude Code"
|
||||||
|
);
|
||||||
|
|
||||||
// Update character state for this conversation
|
// Update character state for this conversation
|
||||||
claudeStore.setCharacterStateForConversation(targetConversationId, "idle");
|
claudeStore.setCharacterStateForConversation(targetConversationId, "idle");
|
||||||
@@ -162,7 +166,11 @@ export async function initializeTauriListeners() {
|
|||||||
|
|
||||||
// Don't add system message if we're about to reconnect
|
// Don't add system message if we're about to reconnect
|
||||||
if (!skipNextGreeting && targetConversationId) {
|
if (!skipNextGreeting && targetConversationId) {
|
||||||
claudeStore.addLineToConversation(targetConversationId, "system", "Disconnected from Claude Code");
|
claudeStore.addLineToConversation(
|
||||||
|
targetConversationId,
|
||||||
|
"system",
|
||||||
|
"Disconnected from Claude Code"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update character state for this conversation
|
// Update character state for this conversation
|
||||||
@@ -225,7 +233,6 @@ export async function initializeTauriListeners() {
|
|||||||
const outputUnlisten = await listen<OutputPayload>("claude:output", (event) => {
|
const outputUnlisten = await listen<OutputPayload>("claude:output", (event) => {
|
||||||
const { line_type, content, tool_name, conversation_id } = event.payload;
|
const { line_type, content, tool_name, conversation_id } = event.payload;
|
||||||
|
|
||||||
|
|
||||||
// Always store the output to the correct conversation
|
// Always store the output to the correct conversation
|
||||||
if (conversation_id) {
|
if (conversation_id) {
|
||||||
claudeStore.addLineToConversation(
|
claudeStore.addLineToConversation(
|
||||||
@@ -256,7 +263,11 @@ export async function initializeTauriListeners() {
|
|||||||
// Store session ID for the correct conversation
|
// Store session ID for the correct conversation
|
||||||
if (conversation_id) {
|
if (conversation_id) {
|
||||||
claudeStore.setSessionIdForConversation(conversation_id, session_id);
|
claudeStore.setSessionIdForConversation(conversation_id, session_id);
|
||||||
claudeStore.addLineToConversation(conversation_id, "system", `Session: ${session_id.substring(0, 8)}...`);
|
claudeStore.addLineToConversation(
|
||||||
|
conversation_id,
|
||||||
|
"system",
|
||||||
|
`Session: ${session_id.substring(0, 8)}...`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Fallback to active conversation if no conversation_id
|
// Fallback to active conversation if no conversation_id
|
||||||
claudeStore.setSessionId(session_id);
|
claudeStore.setSessionId(session_id);
|
||||||
@@ -294,7 +305,11 @@ export async function initializeTauriListeners() {
|
|||||||
|
|
||||||
// Always store the permission message to the correct conversation
|
// Always store the permission message to the correct conversation
|
||||||
if (conversation_id) {
|
if (conversation_id) {
|
||||||
claudeStore.addLineToConversation(conversation_id, "system", `Permission requested for: ${tool_name}`);
|
claudeStore.addLineToConversation(
|
||||||
|
conversation_id,
|
||||||
|
"system",
|
||||||
|
`Permission requested for: ${tool_name}`
|
||||||
|
);
|
||||||
} else if (conversation_id === activeConversationId) {
|
} else if (conversation_id === activeConversationId) {
|
||||||
claudeStore.addLine("system", `Permission requested for: ${tool_name}`);
|
claudeStore.addLine("system", `Permission requested for: ${tool_name}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user