feat: add snippet library for prompt templates

- Add Rust backend with persistent storage for snippets
- Include 8 default snippets across categories (Code Review, Debugging, Testing, etc.)
- Create SnippetLibraryPanel component with category filtering
- Support create/edit/delete operations for custom snippets
- Default snippets can be edited but not deleted
- Add snippet button to InputBar for quick access

Closes #22
This commit is contained in:
2026-01-25 15:15:52 -08:00
committed by Naomi Carrigan
parent 4a8a1d564a
commit 02987f1a17
5 changed files with 879 additions and 0 deletions
+42
View File
@@ -25,6 +25,7 @@
type SlashCommand,
} from "$lib/commands/slashCommands";
import AttachmentPreview from "$lib/components/AttachmentPreview.svelte";
import SnippetLibraryPanel from "$lib/components/SnippetLibraryPanel.svelte";
import type { Attachment } from "$lib/types/messages";
const INPUT_HISTORY_KEY = "hikari-input-history";
@@ -39,6 +40,7 @@
let selectedCommandIndex = $state(0);
let attachments = $state<Attachment[]>([]);
let isDragging = $state(false);
let showSnippetLibrary = $state(false);
// Input history state
let inputHistory = $state<string[]>([]);
@@ -617,6 +619,16 @@ User: ${formattedMessage}`;
}
}
function handleSnippetInsert(content: string): void {
// Insert snippet at cursor position or append to input
if (inputValue.trim()) {
inputValue = inputValue + "\n\n" + content;
} else {
inputValue = content;
}
userHasTyped = true;
}
function handleKeyDown(event: KeyboardEvent) {
// Handle command menu navigation
if (showCommandMenu && matchingCommands.length > 0) {
@@ -723,6 +735,29 @@ User: ${formattedMessage}`;
</div>
<div class="button-wrapper">
<button
type="button"
onclick={() => (showSnippetLibrary = true)}
class="attach-button"
title="Snippet Library"
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
<polyline points="14,2 14,8 20,8" />
<line x1="16" y1="13" x2="8" y2="13" />
<line x1="16" y1="17" x2="8" y2="17" />
<line x1="10" y1="9" x2="8" y2="9" />
</svg>
</button>
<button type="button" onclick={handleFilePicker} class="attach-button" title="Attach files">
<svg
width="20"
@@ -769,6 +804,13 @@ User: ${formattedMessage}`;
</div>
</form>
{#if showSnippetLibrary}
<SnippetLibraryPanel
onClose={() => (showSnippetLibrary = false)}
onInsert={handleSnippetInsert}
/>
{/if}
<style>
.input-bar {
display: flex;