Skip to content

Commit e0545f1

Browse files
committed
CI: lint
1 parent f2aa34b commit e0545f1

19 files changed

+1122
-679
lines changed

src/lib/components/Layout.svelte

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,7 @@
108108
</div>
109109

110110
<!-- Main Layout -->
111-
<div
112-
class="main-layout flex h-full gap-2 p-2 relative z-10"
113-
style="height: calc(100vh - 2rem);"
114-
>
111+
<div class="main-layout flex h-full gap-2 p-2 relative z-10" style="height: calc(100vh - 2rem);">
115112
<!-- Left Column: Stacked Panels -->
116113
<div class="left-column flex flex-col gap-2 flex-1">
117114
<!-- Guardian Panel -->

src/lib/components/panels/GuardianPanel.svelte

Lines changed: 159 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<script lang="ts">
22
import { onMount, tick } from 'svelte';
3-
import { ChevronLeft, ChevronRight, User, Key, Settings, CheckCircle, AlertCircle, Terminal } from 'lucide-svelte';
4-
import { guardianHelpers } from '$lib/stores/guardian.js';
5-
import { aiAnalysisHelpers } from '$lib/stores/ai-analysis.js';
6-
import { loadThemePreset, themePresets } from '$lib/stores/theme.js';
3+
import { Terminal, ChevronRight } from 'lucide-svelte';
4+
import { guardianHelpers } from '$lib/stores/guardian';
5+
import { aiAnalysisHelpers } from '$lib/stores/ai-analysis';
6+
import { loadThemePreset, themePresets } from '$lib/stores/theme';
77
import { uiHelpers } from '$lib/stores/ui';
8-
import { fetchOpenRouterModels } from '$lib/utils/ai-analysis.js';
8+
import { fetchOpenRouterModels } from '$lib/utils/ai-analysis';
99
1010
let apiKeyInput = '';
1111
let prevApiKey = '';
@@ -17,15 +17,15 @@
1717
};
1818
1919
let apiKeyStatus = 'unchecked'; // unchecked, checking, valid, invalid
20-
20+
2121
// CLI-style editing states
2222
let editingField: string | null = null;
2323
const themeKeys = Object.keys(themePresets) as Array<keyof typeof themePresets>;
2424
let currentThemeKey: keyof typeof themePresets = 'everforest';
2525
let themeIndex = 0;
2626
2727
const displayKey = (k: keyof typeof themePresets) => (k === 'tokyoNight' ? 'tokyo-night' : k);
28-
28+
2929
// OpenRouter model selection (dynamic; fallback list shown until fetched)
3030
let modelList: string[] = [
3131
'openai/gpt-oss-20b:free',
@@ -59,7 +59,9 @@
5959
if (dir === 'next') {
6060
currentModelIndex = modelList.length ? (currentModelIndex + 1) % modelList.length : 0;
6161
} else {
62-
currentModelIndex = modelList.length ? (currentModelIndex - 1 + modelList.length) % modelList.length : 0;
62+
currentModelIndex = modelList.length
63+
? (currentModelIndex - 1 + modelList.length) % modelList.length
64+
: 0;
6365
}
6466
persistModel();
6567
}
@@ -87,24 +89,25 @@
8789
}
8890
}
8991
90-
onMount(() => {
92+
onMount(() => {
9193
// Load saved guardian data
9294
const saved = guardianHelpers.load();
9395
if (saved) {
9496
guardianName = saved.name || '';
9597
apiKeyInput = saved.apiKey || '';
9698
preferences = { ...preferences, ...saved.preferences };
9799
}
98-
99-
// Get current theme from localStorage
100-
const savedTheme = (localStorage.getItem('petalytics-theme') as keyof typeof themePresets) || 'everforest';
100+
101+
// Get current theme from localStorage
102+
const savedTheme =
103+
(localStorage.getItem('petalytics-theme') as keyof typeof themePresets) || 'everforest';
101104
currentThemeKey = themeKeys.includes(savedTheme) ? savedTheme : 'everforest';
102105
themeIndex = themeKeys.indexOf(currentThemeKey);
103106
104-
// Get model selection from guardian storage
105-
loadModelFromStorage();
106-
// Fetch model list from OpenRouter if API key is present
107-
loadModels();
107+
// Get model selection from guardian storage
108+
loadModelFromStorage();
109+
// Fetch model list from OpenRouter if API key is present
110+
loadModels();
108111
});
109112
110113
function toggleTheme(direction: 'prev' | 'next') {
@@ -152,7 +155,7 @@
152155
}
153156
}
154157
155-
function handleKeydown(event: KeyboardEvent, field: string) {
158+
function handleKeydown(event: KeyboardEvent, _field: string) {
156159
if (event.key === 'Enter') {
157160
stopEdit();
158161
} else if (event.key === 'Escape') {
@@ -223,17 +226,28 @@
223226

224227
<div class="guardian-panel h-full" style="background: var(--petalytics-bg);">
225228
<!-- CLI-style header -->
226-
<div class="cli-header p-3 border-b font-mono text-sm" style="border-color: var(--petalytics-border); background: var(--petalytics-surface);">
229+
<div
230+
class="cli-header p-3 border-b font-mono text-sm"
231+
style="border-color: var(--petalytics-border); background: var(--petalytics-surface);"
232+
>
227233
<div class="flex items-center space-x-2" style="color: var(--petalytics-pine);">
228234
<Terminal size={14} />
229235
<span>guardian@petalytics:~$</span>
230236
</div>
231237
</div>
232238

233-
<div class="cli-content p-3 font-mono text-sm overflow-y-auto" style="color: var(--petalytics-text);">
234-
239+
<div
240+
class="cli-content p-3 font-mono text-sm overflow-y-auto"
241+
style="color: var(--petalytics-text);"
242+
>
235243
<!-- Guardian name row -->
236-
<div class="cli-row px-2 py-1" role="button" tabindex="0" onclick={() => startEdit('guardian')} onkeydown={(e) => handleActivate(e, () => startEdit('guardian'))}>
244+
<div
245+
class="cli-row px-2 py-1"
246+
role="button"
247+
tabindex="0"
248+
onclick={() => startEdit('guardian')}
249+
onkeydown={(e) => handleActivate(e, () => startEdit('guardian'))}
250+
>
237251
<span class="label" style="color: var(--petalytics-foam);">guardian</span>
238252
<span class="value" style="color: var(--petalytics-text);">
239253
{#if editingField === 'guardian'}
@@ -252,7 +266,13 @@
252266
</div>
253267

254268
<!-- API Key row -->
255-
<div class="cli-row px-2 py-1" role="button" tabindex="0" onclick={() => startEdit('apiKey')} onkeydown={(e) => handleActivate(e, () => startEdit('apiKey'))}>
269+
<div
270+
class="cli-row px-2 py-1"
271+
role="button"
272+
tabindex="0"
273+
onclick={() => startEdit('apiKey')}
274+
onkeydown={(e) => handleActivate(e, () => startEdit('apiKey'))}
275+
>
256276
<span class="label" style="color: var(--petalytics-foam);">api_key</span>
257277
<span class="value" style="color: var(--petalytics-text);">
258278
{#if editingField === 'apiKey'}
@@ -290,29 +310,69 @@
290310
<!-- Model selection (OpenRouter) -->
291311
<div class="cli-row px-2 py-1">
292312
<span class="label" style="color: var(--petalytics-foam);">model</span>
293-
<span class="value" style="color: var(--petalytics-text);">{displayModel()} {#if modelsLoading}(loading...){/if}</span>
313+
<span class="value" style="color: var(--petalytics-text);"
314+
>{displayModel()}
315+
{#if modelsLoading}(loading...){/if}</span
316+
>
294317
<div class="ml-2 flex items-center space-x-1">
295-
<button type="button" class="arrow-btn" onclick={() => cycleModel('prev')} aria-label="Previous model">&lt;</button>
296-
<button type="button" class="arrow-btn" onclick={() => cycleModel('next')} aria-label="Next model">&gt;</button>
297-
<button type="button" class="arrow-btn" onclick={loadModels} aria-label="Refresh models">↻</button>
318+
<button
319+
type="button"
320+
class="arrow-btn"
321+
onclick={() => cycleModel('prev')}
322+
aria-label="Previous model">&lt;</button
323+
>
324+
<button
325+
type="button"
326+
class="arrow-btn"
327+
onclick={() => cycleModel('next')}
328+
aria-label="Next model">&gt;</button
329+
>
330+
<button type="button" class="arrow-btn" onclick={loadModels} aria-label="Refresh models"
331+
>↻</button
332+
>
298333
</div>
299334
</div>
300335

301336
<!-- Theme row -->
302337
<div class="cli-row px-2 py-1">
303338
<span class="label" style="color: var(--petalytics-foam);">theme</span>
304-
<span class="value" style="color: var(--petalytics-text);">{displayKey(currentThemeKey)}</span>
339+
<span class="value" style="color: var(--petalytics-text);">{displayKey(currentThemeKey)}</span
340+
>
305341
<div class="ml-2 flex items-center space-x-1">
306-
<button type="button" class="arrow-btn" onclick={() => toggleTheme('prev')} aria-label="Previous theme">&lt;</button>
307-
<button type="button" class="arrow-btn" onclick={() => toggleTheme('next')} aria-label="Next theme">&gt;</button>
342+
<button
343+
type="button"
344+
class="arrow-btn"
345+
onclick={() => toggleTheme('prev')}
346+
aria-label="Previous theme">&lt;</button
347+
>
348+
<button
349+
type="button"
350+
class="arrow-btn"
351+
onclick={() => toggleTheme('next')}
352+
aria-label="Next theme">&gt;</button
353+
>
308354
</div>
309355
</div>
310356

311357
<!-- Preferences: only ai_insights -->
312-
<div class="cli-row px-2 py-1" role="button" tabindex="0" aria-pressed={preferences.aiInsights} onclick={() => togglePreference('aiInsights')} onkeydown={(e) => handleActivate(e, () => togglePreference('aiInsights'))}>
358+
<div
359+
class="cli-row px-2 py-1"
360+
role="button"
361+
tabindex="0"
362+
aria-pressed={preferences.aiInsights}
363+
onclick={() => togglePreference('aiInsights')}
364+
onkeydown={(e) => handleActivate(e, () => togglePreference('aiInsights'))}
365+
>
313366
<span class="label" style="color: var(--petalytics-foam);">ai_insights</span>
314-
<span class="value" style="color: var(--petalytics-text);">{preferences.aiInsights ? 'enabled' : 'disabled'}</span>
315-
<span class="ml-2" style="color: {preferences.aiInsights ? 'var(--petalytics-pine)' : 'var(--petalytics-subtle)'};">{preferences.aiInsights ? '' : ''}</span>
367+
<span class="value" style="color: var(--petalytics-text);"
368+
>{preferences.aiInsights ? 'enabled' : 'disabled'}</span
369+
>
370+
<span
371+
class="ml-2"
372+
style="color: {preferences.aiInsights
373+
? 'var(--petalytics-pine)'
374+
: 'var(--petalytics-subtle)'};">{preferences.aiInsights ? '' : ''}</span
375+
>
316376
</div>
317377

318378
<!-- Separator line -->
@@ -321,7 +381,13 @@
321381
</div>
322382

323383
<!-- Data Manager launcher (opens in right panel) -->
324-
<div class="cli-row px-2 py-1" role="button" tabindex="0" onclick={() => uiHelpers.setView('dataManager')} onkeydown={(e) => handleActivate(e, () => uiHelpers.setView('dataManager'))}>
384+
<div
385+
class="cli-row px-2 py-1"
386+
role="button"
387+
tabindex="0"
388+
onclick={() => uiHelpers.setView('dataManager')}
389+
onkeydown={(e) => handleActivate(e, () => uiHelpers.setView('dataManager'))}
390+
>
325391
<span class="label" style="color: var(--petalytics-foam);">data_manager</span>
326392
<span class="value" style="color: var(--petalytics-text);">open</span>
327393
<ChevronRight size={14} style="color: var(--petalytics-subtle);" class="ml-2" />
@@ -330,61 +396,64 @@
330396
</div>
331397

332398
<style>
333-
/* Alacritty-inspired interactive rows */
334-
.cli-row {
335-
display: flex;
336-
align-items: center;
337-
border: 1px solid transparent;
338-
border-radius: 6px;
339-
transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
340-
}
341-
.cli-row[role="button"] {
342-
cursor: pointer;
343-
}
344-
.cli-row:hover {
345-
background: var(--petalytics-highlight-low);
346-
border-color: var(--petalytics-border);
347-
}
348-
.cli-row:focus-within,
349-
.cli-row[role="button"]:focus-visible {
350-
outline: none;
351-
background: var(--petalytics-highlight-med);
352-
border-color: var(--petalytics-accent);
353-
box-shadow: 0 0 0 2px color-mix(in oklab, var(--petalytics-accent) 40%, transparent);
354-
}
355-
.cli-row[aria-pressed="true"] {
356-
background: var(--petalytics-highlight-high);
357-
border-color: var(--petalytics-accent);
358-
}
359-
.label {
360-
color: var(--petalytics-foam);
361-
}
362-
.value {
363-
margin-left: auto;
364-
text-align: right;
365-
flex: 1 1 auto;
366-
}
367-
.input-inline {
368-
padding: 0;
369-
}
370-
.arrow-btn {
371-
font-family: 'JetBrains Mono', monospace;
372-
font-size: 0.85rem;
373-
line-height: 1rem;
374-
background: transparent;
375-
border: 1px solid var(--petalytics-border);
376-
color: var(--petalytics-subtle);
377-
padding: 0.15rem 0.4rem;
378-
border-radius: 4px;
379-
cursor: pointer;
380-
}
381-
.arrow-btn:hover {
382-
background: var(--petalytics-highlight-low);
383-
color: var(--petalytics-text);
384-
}
385-
.arrow-btn:focus-visible {
386-
outline: none;
387-
border-color: var(--petalytics-accent);
388-
box-shadow: 0 0 0 2px color-mix(in oklab, var(--petalytics-accent) 35%, transparent);
389-
}
399+
/* Alacritty-inspired interactive rows */
400+
.cli-row {
401+
display: flex;
402+
align-items: center;
403+
border: 1px solid transparent;
404+
border-radius: 6px;
405+
transition:
406+
background 140ms ease,
407+
border-color 140ms ease,
408+
box-shadow 140ms ease;
409+
}
410+
.cli-row[role='button'] {
411+
cursor: pointer;
412+
}
413+
.cli-row:hover {
414+
background: var(--petalytics-highlight-low);
415+
border-color: var(--petalytics-border);
416+
}
417+
.cli-row:focus-within,
418+
.cli-row[role='button']:focus-visible {
419+
outline: none;
420+
background: var(--petalytics-highlight-med);
421+
border-color: var(--petalytics-accent);
422+
box-shadow: 0 0 0 2px color-mix(in oklab, var(--petalytics-accent) 40%, transparent);
423+
}
424+
.cli-row[aria-pressed='true'] {
425+
background: var(--petalytics-highlight-high);
426+
border-color: var(--petalytics-accent);
427+
}
428+
.label {
429+
color: var(--petalytics-foam);
430+
}
431+
.value {
432+
margin-left: auto;
433+
text-align: right;
434+
flex: 1 1 auto;
435+
}
436+
.input-inline {
437+
padding: 0;
438+
}
439+
.arrow-btn {
440+
font-family: 'JetBrains Mono', monospace;
441+
font-size: 0.85rem;
442+
line-height: 1rem;
443+
background: transparent;
444+
border: 1px solid var(--petalytics-border);
445+
color: var(--petalytics-subtle);
446+
padding: 0.15rem 0.4rem;
447+
border-radius: 4px;
448+
cursor: pointer;
449+
}
450+
.arrow-btn:hover {
451+
background: var(--petalytics-highlight-low);
452+
color: var(--petalytics-text);
453+
}
454+
.arrow-btn:focus-visible {
455+
outline: none;
456+
border-color: var(--petalytics-accent);
457+
box-shadow: 0 0 0 2px color-mix(in oklab, var(--petalytics-accent) 35%, transparent);
458+
}
390459
</style>

0 commit comments

Comments
 (0)