generated from nhcarrigan/template
b745100bd5
## Summary This PR covers the full audit of Claude CLI changes from 2.1.50 to 2.1.53, plus a batch of bug fixes, new features, and maintenance work identified during that review. ### New Features - **Workspace trust gate** — detects hooks, MCP servers, and custom commands in a workspace before connecting; persists trust decisions so users aren't prompted repeatedly - **Custom background image** — users can set a background image with configurable opacity; character panel and compact mode go transparent when active - **Draggable tab reordering** — conversation tabs can be reordered via pointer-event drag-and-drop (HTML5 drag is intercepted by Tauri/WebView2, so pointer events are used instead) - **Org UUID in account info** — exposes the org UUID from Claude auth status ### Bug Fixes - **Unread dot false positives** — initialise unread counts on mount to prevent all tabs showing the blue dot after toggling the file editor (Closes #164) - **Watchdog for hung WSL bridge** — detects connections that never receive `system:init` and kills the stale process after 1 minute (Closes #166) - **Suppress terminal window flash on Windows** — applies `CREATE_NO_WINDOW` to all subprocesses via a `HideWindow` trait extension (Closes #165) - **HTML escaping in markdown renderer** — escape `<` and `>` in `codespan` and `html` renderer callbacks to prevent raw HTML injection (Closes #169) ### Maintenance - Verify stream-JSON handles tool results above the 50K threshold correctly (Closes #162) - Reviewed hook security fixes from CLI 2.1.51 — not applicable to our setup (Closes #163) - Expose org UUID from `claude auth status` (Closes #160) - Clean up Svelte and Vite build warnings (`a11y_click_events_have_key_events`, `state_referenced_locally`, `non_reactive_update`, `codeSplitting`, chunk size, CodeMirror dynamic import) - Update all npm dependencies to latest compatible versions with exact pinning (Closes #81, Closes #82, Closes #83, Closes #84, Closes #85, Closes #86, Closes #87, Closes #90, Closes #91, Closes #93, Closes #94, Closes #95, Closes #96, Closes #97, Closes #98, Closes #99, Closes #101, Closes #141, Closes #142, Closes #143, Closes #145, Closes #146, Closes #147) - Run `cargo update` to bring Cargo.lock up to date ### Closes Closes #160 Closes #162 Closes #163 Closes #164 Closes #165 Closes #166 Closes #167 Closes #168 Closes #169 Closes #81 Closes #82 Closes #83 Closes #84 Closes #85 Closes #86 Closes #87 Closes #90 Closes #91 Closes #93 Closes #94 Closes #95 Closes #96 Closes #97 Closes #98 Closes #99 Closes #101 Closes #141 Closes #142 Closes #143 Closes #145 Closes #146 Closes #147 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #171 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
161 lines
3.9 KiB
Svelte
161 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
import { onMount } from "svelte";
|
|
|
|
const SUPPORTED_CLI_VERSION = "2.1.53";
|
|
|
|
let installedVersion = $state("Loading...");
|
|
|
|
function compareVersions(a: string, b: string): number {
|
|
const aParts = a.split(".").map(Number);
|
|
const bParts = b.split(".").map(Number);
|
|
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
|
|
const aVal = aParts[i] ?? 0;
|
|
const bVal = bParts[i] ?? 0;
|
|
if (aVal > bVal) return 1;
|
|
if (aVal < bVal) return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
let displayVersion = $derived(installedVersion.split(" (")[0]);
|
|
|
|
let supportedBadgeState = $derived.by(() => {
|
|
if (installedVersion === "Loading..." || installedVersion === "Unknown") {
|
|
return "neutral";
|
|
}
|
|
const semverMatch = /(\d+\.\d+\.\d+)/.exec(installedVersion);
|
|
if (!semverMatch) return "neutral";
|
|
const cmp = compareVersions(semverMatch[1], SUPPORTED_CLI_VERSION);
|
|
if (cmp > 0) return "ahead";
|
|
if (cmp < 0) return "behind";
|
|
return "current";
|
|
});
|
|
|
|
async function fetchVersion() {
|
|
try {
|
|
const result = await invoke<string>("get_claude_version");
|
|
installedVersion = result;
|
|
} catch (error) {
|
|
console.error("Failed to get Claude CLI version:", error);
|
|
installedVersion = "Unknown";
|
|
}
|
|
}
|
|
|
|
onMount(() => {
|
|
fetchVersion();
|
|
});
|
|
</script>
|
|
|
|
<div class="cli-versions">
|
|
<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 {displayVersion}</span>
|
|
</div>
|
|
|
|
<div class="cli-version supported {supportedBadgeState}" title="Highest audited 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"
|
|
>
|
|
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
</svg>
|
|
<span class="version-text">Supported {SUPPORTED_CLI_VERSION}</span>
|
|
</div>
|
|
|
|
{#if supportedBadgeState === "ahead"}
|
|
<span class="version-warning ahead"
|
|
>Your version is newer, some features may not be supported</span
|
|
>
|
|
{:else if supportedBadgeState === "behind"}
|
|
<span class="version-warning behind"
|
|
>Your version is out of date, please update to ensure compatibility</span
|
|
>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.cli-versions {
|
|
display: flex;
|
|
gap: 6px;
|
|
align-items: center;
|
|
}
|
|
|
|
.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);
|
|
}
|
|
|
|
.cli-version.supported.current {
|
|
border-color: var(--success-color, #4caf50);
|
|
color: var(--success-color, #4caf50);
|
|
}
|
|
|
|
.cli-version.supported.ahead {
|
|
border-color: var(--warning-color, #ff9800);
|
|
color: var(--warning-color, #ff9800);
|
|
}
|
|
|
|
.cli-version.supported.behind {
|
|
border-color: var(--error-color, #f44336);
|
|
color: var(--error-color, #f44336);
|
|
}
|
|
|
|
.terminal-icon {
|
|
flex-shrink: 0;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.version-text {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.version-warning {
|
|
font-size: 0.75rem;
|
|
font-style: italic;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.version-warning.ahead {
|
|
color: var(--warning-color, #ff9800);
|
|
}
|
|
|
|
.version-warning.behind {
|
|
color: var(--error-color, #f44336);
|
|
}
|
|
</style>
|