feat: add CLI version display in status bar

Displays the Claude Code CLI version in the status bar (to the left of the system clock) to help with debugging and understanding which features are available.

Changes:
- Add get_claude_version command to fetch CLI version from `claude --version`
- Create CliVersion.svelte component to display version
- Position component in InputBar status bar next to SystemClock
- Update on app start and CLI reconnection

Closes #131
This commit is contained in:
2026-02-07 14:37:45 -08:00
committed by Naomi Carrigan
parent 9b3c242333
commit 7fecb20ba9
4 changed files with 100 additions and 0 deletions
+29
View File
@@ -1228,6 +1228,35 @@ pub async fn list_memory_files() -> Result<MemoryFilesResponse, String> {
}) })
} }
#[tauri::command]
pub async fn get_claude_version() -> Result<String, String> {
tracing::debug!("Getting Claude CLI version");
let output = std::process::Command::new("claude")
.arg("--version")
.output();
match output {
Ok(output) => {
if output.status.success() {
let version = String::from_utf8_lossy(&output.stdout)
.trim()
.to_string();
tracing::info!("Claude CLI version: {}", version);
Ok(version)
} else {
let error = String::from_utf8_lossy(&output.stderr);
tracing::error!("Failed to get Claude version: {}", error);
Err(format!("Failed to get Claude version: {}", error))
}
}
Err(e) => {
tracing::error!("Failed to execute claude --version: {}", e);
Err(format!("Failed to execute claude --version: {}", e))
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+1
View File
@@ -194,6 +194,7 @@ pub fn run() {
stop_discord_rpc, stop_discord_rpc,
close_application, close_application,
list_memory_files, list_memory_files,
get_claude_version,
]) ])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
+68
View File
@@ -0,0 +1,68 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { onMount } from "svelte";
let version = $state("Loading...");
async function fetchVersion() {
try {
const result = await invoke<string>("get_claude_version");
version = result;
} catch (error) {
console.error("Failed to get Claude CLI version:", error);
version = "Unknown";
}
}
onMount(() => {
fetchVersion();
});
</script>
<div class="cli-version">
<svg
class="terminal-icon"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="4 17 10 11 4 5" />
<line x1="12" y1="19" x2="20" y2="19" />
</svg>
<span class="version-text">CLI {version}</span>
</div>
<style>
.cli-version {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 6px;
color: var(--text-secondary);
font-size: 0.85rem;
font-family: var(--font-mono, monospace);
transition: all 0.2s;
}
.cli-version:hover {
border-color: var(--accent-primary);
color: var(--accent-primary);
}
.terminal-icon {
flex-shrink: 0;
opacity: 0.7;
}
.version-text {
white-space: nowrap;
}
</style>
+2
View File
@@ -18,6 +18,7 @@
import MessageModeSelector from "$lib/components/MessageModeSelector.svelte"; import MessageModeSelector from "$lib/components/MessageModeSelector.svelte";
import SlashCommandMenu from "$lib/components/SlashCommandMenu.svelte"; import SlashCommandMenu from "$lib/components/SlashCommandMenu.svelte";
import SystemClock from "$lib/components/SystemClock.svelte"; import SystemClock from "$lib/components/SystemClock.svelte";
import CliVersion from "$lib/components/CliVersion.svelte";
import { getCurrentMode } from "$lib/stores/messageMode"; import { getCurrentMode } from "$lib/stores/messageMode";
import { formatMessageWithMode } from "$lib/types/messageMode"; import { formatMessageWithMode } from "$lib/types/messageMode";
import { import {
@@ -916,6 +917,7 @@ User: ${formattedMessage}`;
<span>Clipboard</span> <span>Clipboard</span>
</button> </button>
<CliVersion />
<SystemClock /> <SystemClock />
</div> </div>