/** * Settings panel for /vault (no-arg path). * * Opens an interactive SettingsList overlay where the user can * change the active backend and managed-provider policy. */ import type { ExtensionCommandContext } from "@mariozechner/pi-coding-agent"; import { getSettingsListTheme } from "@mariozechner/pi-coding-agent"; import { Container, Text, SettingsList, type SettingItem } from "@mariozechner/pi-tui"; import type { VaultController } from "./controller.js"; import type { BackendType, VaultConfig } from "../types.js"; const BACKEND_VALUES: BackendType[] = ["age", "keychain", "passthrough"]; function createSettingsItems(config: VaultConfig): SettingItem[] { const managed = config.managedProviders === "all" ? "all" : config.managedProviders.join(", "); const excluded = (config.excludeProviders ?? []).join(", ") || "none"; return [ { id: "backend", label: "Backend", description: "Credential storage backend", currentValue: config.backend, values: BACKEND_VALUES, }, { id: "managedProviders", label: "Managed providers", description: "Which providers the vault manages (all or specific list)", currentValue: managed, values: ["all"], }, { id: "excludeProviders", label: "Excluded providers", description: "Providers excluded from vault management", currentValue: excluded, values: ["none"], }, ]; } function applyChange( config: VaultConfig, id: string, newValue: string, ): VaultConfig { if (id === "backend" && BACKEND_VALUES.includes(newValue as BackendType)) { return { ...config, backend: newValue as BackendType }; } if (id === "managedProviders" && newValue === "all") { return { ...config, managedProviders: "all" }; } return config; } export async function openVaultSettingsPanel( controller: VaultController, ctx: ExtensionCommandContext, ): Promise { let draft = controller.getConfig(); await ctx.ui.custom((_tui, theme, _kb, done) => { const container = new Container(); container.addChild( new Text(theme.fg("accent", theme.bold("Credential Vault")), 1, 0), ); container.addChild( new Text( theme.fg("dim", "Configure credential storage backend and provider scope."), 1, 0, ), ); const settingsList = new SettingsList( createSettingsItems(draft), 6, getSettingsListTheme(), (id: string, newValue: string) => { draft = applyChange(draft, id, newValue); settingsList.updateValue(id, newValue); container.invalidate(); }, () => done(undefined), { enableSearch: false }, ); container.addChild(settingsList); return { render: (width: number) => container.render(width), invalidate: () => container.invalidate(), handleInput: (data: string) => settingsList.handleInput(data), }; }); // Persist on close controller.setConfig(draft); }