Clean up goose2 settings headers (#8951)

Signed-off-by: Clay Delk <clay.delk@gmail.com>
This commit is contained in:
Clay Delk
2026-05-01 14:47:56 -04:00
committed by GitHub
parent 43ad9e6adb
commit 936e019f0e
12 changed files with 137 additions and 72 deletions
@@ -143,7 +143,6 @@ export function ExtensionsSettings() {
return (
<SettingsPage
title={t("extensions.title")}
description={t("extensions.description")}
actions={
<Button
type="button"
@@ -1,13 +1,97 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { SettingsPage } from "@/shared/ui/SettingsPage";
export function AboutSettings() {
const { t } = useTranslation("settings");
interface AboutAppInfo {
name: string;
version: string;
tauriVersion: string;
identifier: string;
}
function AboutInfoRow({ label, value }: { label: string; value: string }) {
return (
<SettingsPage
title={t("about.title")}
description={t("about.description")}
/>
<div className="flex items-center justify-between gap-4 py-2">
<span className="text-sm text-muted-foreground">{label}</span>
<span className="min-w-0 truncate text-right text-sm font-medium">
{value}
</span>
</div>
);
}
export function AboutSettings() {
const { t } = useTranslation("settings");
const [appInfo, setAppInfo] = useState<AboutAppInfo | null>(null);
useEffect(() => {
let cancelled = false;
async function loadAppInfo() {
if (!window.__TAURI_INTERNALS__) {
return;
}
try {
const { getIdentifier, getName, getTauriVersion, getVersion } =
await import("@tauri-apps/api/app");
const [name, version, tauriVersion, identifier] = await Promise.all([
getName(),
getVersion(),
getTauriVersion(),
getIdentifier(),
]);
if (!cancelled) {
setAppInfo({ name, version, tauriVersion, identifier });
}
} catch {
if (!cancelled) {
setAppInfo(null);
}
}
}
void loadAppInfo();
return () => {
cancelled = true;
};
}, []);
const fallback = t("about.unavailable");
return (
<SettingsPage title={t("about.title")}>
<div className="space-y-1">
<div className="divide-y divide-border">
<AboutInfoRow
label={t("about.fields.name")}
value={appInfo?.name ?? "Goose"}
/>
<AboutInfoRow
label={t("about.fields.version")}
value={appInfo?.version ?? fallback}
/>
<AboutInfoRow
label={t("about.fields.buildMode")}
value={
import.meta.env.DEV
? t("about.buildModes.development")
: t("about.buildModes.production")
}
/>
<AboutInfoRow
label={t("about.fields.tauriVersion")}
value={appInfo?.tauriVersion ?? fallback}
/>
<AboutInfoRow
label={t("about.fields.identifier")}
value={appInfo?.identifier ?? fallback}
/>
<AboutInfoRow label={t("about.fields.license")} value="Apache-2.0" />
</div>
</div>
</SettingsPage>
);
}
@@ -24,7 +24,7 @@ export function ChatsSettings() {
}
return (
<SettingsPage title={t("chats.title")} description={t("chats.description")}>
<SettingsPage title={t("chats.title")}>
<div className="space-y-3">
<h4 className="text-sm font-semibold">{t("chats.sectionTitle")}</h4>
{!loadingArchivedChats && archivedChats.length === 0 ? (
@@ -9,10 +9,7 @@ export function CompactionSettings() {
const icon = getProviderIcon("goose", "size-6");
return (
<SettingsPage
title={t("compaction.title")}
description={t("compaction.description")}
>
<SettingsPage title={t("compaction.title")}>
<div className="rounded-lg border bg-background p-4">
<div className="flex items-start justify-between gap-4">
<div className="min-w-0 flex-1">
@@ -103,7 +103,6 @@ export function DoctorSettings() {
variant="outline"
size="xxs"
onClick={copyDebugInfo}
className="text-muted-foreground hover:text-foreground"
>
{copied ? (
<Check className="size-3.5" />
@@ -120,7 +119,6 @@ export function DoctorSettings() {
variant="outline"
size="xxs"
onClick={runChecksAndRefresh}
className="text-muted-foreground hover:text-foreground"
>
<RefreshCw className="size-3.5" />
{t("doctor.rerun")}
@@ -36,10 +36,7 @@ export function GeneralSettings() {
const { preference, setLocalePreference, systemLocaleLabel } = useLocale();
return (
<SettingsPage
title={t("general.title")}
description={t("general.description")}
>
<SettingsPage title={t("general.title")}>
<SettingRow
label={t("general.language.label")}
description={t("general.language.description")}
@@ -78,30 +78,19 @@ export function GooseAutoCompactSettings() {
return (
<div className="space-y-3">
<div className="min-w-0">
<p className="text-sm font-medium">
<div className="flex items-center justify-between gap-2">
<p className="min-w-0 text-sm font-medium">
{t(`${translationKeyPrefix}.label`)}
</p>
<p className="mt-0.5 text-xs text-muted-foreground">
{t(`${translationKeyPrefix}.description`)}
</p>
<div className="flex items-center gap-1.5 text-xs text-foreground">
{isSavingThreshold ? (
<Loader2 className="size-3 animate-spin text-muted-foreground" />
) : null}
<span className="shrink-0 font-medium">{autoCompactValueLabel}</span>
</div>
</div>
<div className="w-full space-y-2">
<div className="flex items-center justify-between gap-2">
<span className="text-xs text-muted-foreground">
{t(`${translationKeyPrefix}.current`)}
</span>
<div className="flex items-center gap-1.5 text-xs text-foreground">
{isSavingThreshold ? (
<Loader2 className="size-3 animate-spin text-muted-foreground" />
) : null}
<span className="shrink-0 font-medium">
{autoCompactValueLabel}
</span>
</div>
</div>
<Slider
value={[draftThresholdPercent]}
min={1}
@@ -57,10 +57,7 @@ export function ProjectsSettings() {
return (
<>
<SettingsPage
title={t("projects.title")}
description={t("projects.description")}
>
<SettingsPage title={t("projects.title")}>
<div className="space-y-3">
<h4 className="text-sm font-semibold">
{t("projects.sectionTitle")}
@@ -222,10 +222,7 @@ export function VoiceInputSettings() {
if (loading) {
return (
<SettingsPage
title={t("general.voiceInput.label")}
description={t("general.voiceInput.description")}
>
<SettingsPage title={t("general.voiceInput.label")}>
<p className="text-xs text-muted-foreground">
{t("common:labels.loading")}
</p>
@@ -236,7 +233,6 @@ export function VoiceInputSettings() {
return (
<SettingsPage
title={t("general.voiceInput.label")}
description={t("general.voiceInput.description")}
contentClassName="space-y-4"
>
<div className="space-y-2 rounded-lg border border-border px-3 py-3">
@@ -41,7 +41,7 @@ describe("GooseAutoCompactSettings", () => {
render(<GooseAutoCompactSettings />);
const slider = screen.getByRole("slider", {
name: /auto-compact context/i,
name: /auto-compact threshold/i,
});
slider.focus();
await user.keyboard("{ArrowRight}");
@@ -62,7 +62,7 @@ describe("GooseAutoCompactSettings", () => {
render(<GooseAutoCompactSettings />);
const slider = screen.getByRole("slider", {
name: /auto-compact context/i,
name: /auto-compact threshold/i,
});
expect(screen.getByText("Off")).toBeInTheDocument();
@@ -1,6 +1,18 @@
{
"about": {
"description": "View app version, build info, and licenses.",
"buildModes": {
"development": "Development",
"production": "Production"
},
"fields": {
"buildMode": "Build mode",
"identifier": "App identifier",
"license": "License",
"name": "App name",
"tauriVersion": "Tauri version",
"version": "App version"
},
"unavailable": "Not available",
"title": "About"
},
"appearance": {
@@ -39,7 +51,6 @@
"title": "Appearance"
},
"chats": {
"description": "View and restore your archived chats.",
"empty": "No archived chats.",
"messageCount_one": "{{displayCount}} message",
"messageCount_other": "{{displayCount}} messages",
@@ -51,19 +62,16 @@
}
},
"compaction": {
"description": "Manage how Goose trims older context in long-running chats.",
"goose": {
"autoCompact": {
"current": "Threshold",
"description": "Choose when Goose should compact older context before replying. This applies to all Goose chats.",
"helper": "Set to 100% to turn auto-compaction off.",
"label": "Auto-compact context",
"label": "Auto-compact threshold",
"loading": "Loading...",
"off": "Off",
"saveError": "Failed to save auto-compaction setting."
},
"builtIn": "Built in",
"description": "Goose-specific context controls for long-running chats.",
"description": "Choose when the Goose agent compacts older context during sessions. This applies to all goose chats.",
"label": "Goose (Agent)"
},
"title": "Compaction"
@@ -74,7 +82,6 @@
},
"extensions": {
"title": "Extensions",
"description": "Manage MCP extensions that add tools and capabilities to Goose.",
"search": "Search extensions...",
"enabled": "Enabled",
"enabledCount": "Enabled ({{count}})",
@@ -82,7 +89,7 @@
"availableCount": "Available ({{count}})",
"empty": "No extensions configured.",
"noResults": "No extensions match your search.",
"addExtension": "Add Extension",
"addExtension": "Add extension",
"editExtension": "Edit Extension",
"deleteExtension": "Delete Extension",
"toggle": "Toggle {{name}}",
@@ -133,7 +140,6 @@
"tools": "Tools"
},
"general": {
"description": "Manage language and other app preferences.",
"language": {
"description": "Choose how Goose formats and displays the interface.",
"english": "English",
@@ -143,8 +149,7 @@
},
"title": "General",
"voiceInput": {
"label": "Voice Input",
"description": "Configure voice dictation for hands-free input.",
"label": "Voice input",
"providerLabel": "Transcription Provider",
"disabled": "Disabled",
"notConfiguredSuffix": "(not configured)",
@@ -198,7 +203,6 @@
"voice": "Voice"
},
"projects": {
"description": "Manage your projects.",
"empty": "No archived projects.",
"sectionTitle": "Archived projects",
"title": "Projects"
@@ -1,6 +1,18 @@
{
"about": {
"description": "La información de Goose aparecerá aquí.",
"buildModes": {
"development": "Desarrollo",
"production": "Producción"
},
"fields": {
"buildMode": "Modo de compilación",
"identifier": "Identificador de la app",
"license": "Licencia",
"name": "Nombre de la app",
"tauriVersion": "Versión de Tauri",
"version": "Versión de la app"
},
"unavailable": "No disponible",
"title": "Acerca de"
},
"appearance": {
@@ -39,7 +51,6 @@
"title": "Apariencia"
},
"chats": {
"description": "Restaura chats archivados.",
"empty": "No hay chats archivados.",
"messageCount_one": "{{displayCount}} mensaje",
"messageCount_other": "{{displayCount}} mensajes",
@@ -51,19 +62,16 @@
}
},
"compaction": {
"description": "Administra cómo Goose compacta el contexto anterior en chats largos.",
"goose": {
"autoCompact": {
"current": "Umbral",
"description": "Elige cuándo Goose debe compactar el contexto anterior antes de responder. Esto se aplica a todos los chats de Goose.",
"helper": "Ajústalo al 100% para desactivar la compactación automática.",
"label": "Compactación automática del contexto",
"label": "Umbral de compactación automática",
"loading": "Cargando...",
"off": "Desactivado",
"saveError": "No se pudo guardar la configuración de compactación automática."
},
"builtIn": "Integrado",
"description": "Controles de contexto específicos de Goose para chats largos.",
"description": "Elige cuándo el agente Goose compacta el contexto anterior durante las sesiones. Esto se aplica a todos los chats de Goose.",
"label": "Goose (Agente)"
},
"title": "Compactación"
@@ -74,7 +82,6 @@
},
"extensions": {
"title": "Extensiones",
"description": "Administra las extensiones MCP que agregan herramientas y capacidades a Goose.",
"search": "Buscar extensiones...",
"enabled": "Habilitadas",
"enabledCount": "Habilitadas ({{count}})",
@@ -133,7 +140,6 @@
"tools": "Herramientas"
},
"general": {
"description": "Administra el idioma y otras preferencias de la app.",
"language": {
"description": "Elige cómo Goose formatea y muestra la interfaz.",
"english": "Inglés",
@@ -144,7 +150,6 @@
"title": "General",
"voiceInput": {
"label": "Entrada de voz",
"description": "Configura el dictado por voz para entrada manos libres.",
"providerLabel": "Proveedor de transcripción",
"disabled": "Desactivado",
"notConfiguredSuffix": "(no configurado)",
@@ -198,7 +203,6 @@
"voice": "Voz"
},
"projects": {
"description": "Administra tus proyectos.",
"empty": "No hay proyectos archivados.",
"sectionTitle": "Proyectos archivados",
"title": "Proyectos"