From 4bd1cef1cf49f04c0bdf45f8ebd30819c3c98a8e Mon Sep 17 00:00:00 2001 From: shahondin1624 Date: Thu, 12 Mar 2026 12:07:50 +0100 Subject: [PATCH] feat: add preset configurations with built-in and custom presets Add preset store with three built-in presets (Strict mode, Research only, Full access) and localStorage persistence for custom presets. Integrate preset selector into ConfigSidebar with load, save, and delete actions. Built-in presets cannot be deleted. Closes #14 Co-Authored-By: Claude Opus 4.6 --- implementation-plans/_index.md | 1 + implementation-plans/issue-014.md | 35 +++++++ src/lib/components/ConfigSidebar.svelte | 101 +++++++++++++++++++++ src/lib/stores/presets.svelte.ts | 116 ++++++++++++++++++++++++ 4 files changed, 253 insertions(+) create mode 100644 implementation-plans/issue-014.md create mode 100644 src/lib/stores/presets.svelte.ts diff --git a/implementation-plans/_index.md b/implementation-plans/_index.md index 37620ba..b1ddd70 100644 --- a/implementation-plans/_index.md +++ b/implementation-plans/_index.md @@ -15,3 +15,4 @@ | #11 | Session creation and ID management | COMPLETED | [issue-011.md](issue-011.md) | | #12 | Session history sidebar | COMPLETED | [issue-012.md](issue-012.md) | | #13 | Session config sidebar component | COMPLETED | [issue-013.md](issue-013.md) | +| #14 | Preset configurations | COMPLETED | [issue-014.md](issue-014.md) | diff --git a/implementation-plans/issue-014.md b/implementation-plans/issue-014.md new file mode 100644 index 0000000..7819cae --- /dev/null +++ b/implementation-plans/issue-014.md @@ -0,0 +1,35 @@ +--- +--- + +# Issue #14: Preset configurations + +**Status:** COMPLETED +**Issue:** https://git.shahondin1624.de/llm-multiverse/llm-multiverse-ui/issues/14 +**Branch:** `feature/issue-14-preset-configs` + +## Acceptance Criteria + +- [x] Save current config as a named preset +- [x] Load preset from a list +- [x] Delete custom presets +- [x] 2-3 built-in default presets shipped: + - "Strict mode" — no overrides, restricted tools (FS Write, Run Shell, Run Code, Package Install disabled) + - "Research only" — limited tool set for read-only operations (Memory Write, FS Write, Run Code, Run Shell, Package Install disabled) + - "Full access" — all overrides relaxed (OverrideLevel.ALL), no tools disabled +- [x] Presets persisted in localStorage +- [x] Built-in presets cannot be deleted + +## Implementation + +### New Files +- `src/lib/stores/presets.svelte.ts` — preset store with built-in presets and localStorage persistence for custom presets + +### Modified Files +- `src/lib/components/ConfigSidebar.svelte` — added preset selector section at the top with load, save, and delete functionality + +### Key Decisions +- Built-in presets are hardcoded constants, not stored in localStorage +- Custom presets stored under `llm-multiverse-presets` localStorage key +- Overwriting a custom preset with the same name is allowed; overwriting built-in presets is not +- Preset config uses a plain interface (`PresetConfig`) rather than protobuf types for clean serialization +- Preset section placed at the top of the sidebar before Override Level, matching the issue instructions diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte index 09080fa..5978def 100644 --- a/src/lib/components/ConfigSidebar.svelte +++ b/src/lib/components/ConfigSidebar.svelte @@ -3,6 +3,7 @@ import type { SessionConfig } from '$lib/proto/llm_multiverse/v1/orchestrator_pb'; import { SessionConfigSchema } from '$lib/proto/llm_multiverse/v1/orchestrator_pb'; import { create } from '@bufbuild/protobuf'; + import { presetStore } from '$lib/stores/presets.svelte'; let { config, @@ -10,6 +11,9 @@ }: { config: SessionConfig; onConfigChange: (config: SessionConfig) => void } = $props(); let newPermission = $state(''); + let newPresetName = $state(''); + let showSavePreset = $state(false); + let saveError = $state(''); const toolTypes = [ { value: ToolType.MEMORY_READ, label: 'Memory Read' }, @@ -79,6 +83,36 @@ function resetConfig() { onConfigChange(create(SessionConfigSchema, { overrideLevel: OverrideLevel.NONE })); } + + function handleLoadPreset(name: string) { + const presetConfig = presetStore.loadPreset(name); + if (!presetConfig) return; + const updated = create(SessionConfigSchema, { + overrideLevel: presetConfig.overrideLevel, + disabledTools: [...presetConfig.disabledTools], + grantedPermissions: [...presetConfig.grantedPermissions] + }); + onConfigChange(updated); + } + + function handleSavePreset() { + saveError = ''; + try { + presetStore.savePreset(newPresetName, { + overrideLevel: config.overrideLevel, + disabledTools: [...config.disabledTools], + grantedPermissions: [...config.grantedPermissions] + }); + newPresetName = ''; + showSavePreset = false; + } catch (err) { + saveError = err instanceof Error ? err.message : 'Failed to save preset'; + } + } + + function handleDeletePreset(name: string) { + presetStore.deletePreset(name); + }