Rust SSH service: russh async client, DashMap session registry, TOFU host key verification, CWD tracking via separate exec channel (never touches terminal stream), base64 event emission for terminal I/O. 52/52 tests passing. Vue 3 frontend: ported from Wails v3 to Tauri v2 — useTerminal composable with streaming TextDecoder + rAF batching, session store with multi-connection support, connection store/tree, sidebar, tab bar, status bar, keyboard shortcuts. All Wails imports replaced with Tauri API equivalents. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
35 lines
891 B
Vue
35 lines
891 B
Vue
<template>
|
|
<div class="flex border-b border-[var(--wraith-border)]">
|
|
<button
|
|
v-for="tab in tabs"
|
|
:key="tab.id"
|
|
class="flex-1 py-2 text-xs font-medium text-center transition-colors cursor-pointer"
|
|
:class="
|
|
modelValue === tab.id
|
|
? 'text-[var(--wraith-accent-blue)] border-b-2 border-[var(--wraith-accent-blue)]'
|
|
: 'text-[var(--wraith-text-muted)] hover:text-[var(--wraith-text-secondary)]'
|
|
"
|
|
@click="emit('update:modelValue', tab.id)"
|
|
>
|
|
{{ tab.label }}
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
export type SidebarTab = "connections" | "sftp";
|
|
|
|
const tabs = [
|
|
{ id: "connections" as const, label: "Connections" },
|
|
{ id: "sftp" as const, label: "SFTP" },
|
|
];
|
|
|
|
defineProps<{
|
|
modelValue: SidebarTab;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
"update:modelValue": [tab: SidebarTab];
|
|
}>();
|
|
</script>
|