Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitcore/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@
"name": "Svelte 5 Frontend",
"phase": 5,
"crate": "apps/desktop",
"passes": false,
"passes": true,
"tests": [],
"last_updated": null
"last_updated": "2025-05-22"
}
],
"agents": {
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/lib/components/ChatHistory.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import DOMPurify from 'dompurify';
import GenerativeCanvas from './GenerativeCanvas.svelte';
import { chatHistory } from '$lib/store.svelte';

let { } = $props();
</script>

<div class="space-y-6">
Expand Down
14 changes: 7 additions & 7 deletions apps/desktop/src/lib/components/ConnectPeer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import { invoke } from '@tauri-apps/api/core';
import { onMount } from 'svelte';

let address = '';
let status = '';
let isConnecting = false;
let recentAddresses: string[] = [];
let address = $state('');
let status = $state('');
let isConnecting = $state(false);
let recentAddresses: string[] = $state([]);

onMount(() => {
const storedAddresses = localStorage.getItem('recentPeerAddresses');
Expand Down Expand Up @@ -50,10 +50,10 @@
placeholder="/ip4/192.168.1.100/tcp/4001"
bind:value={address}
class="w-full bg-gray-900/80 border border-cyan-900/40 p-2 rounded text-cyan-300 placeholder-cyan-700/50 focus:outline-none focus:border-cyan-500/50 pr-24"
on:keydown={(e) => e.key === 'Enter' && connectToPeer()}
onkeydown={(e) => e.key === 'Enter' && connectToPeer()}
/>
<button
on:click={connectToPeer}
onclick={connectToPeer}
disabled={isConnecting}
class="absolute right-1 top-1 bottom-1 px-4 text-sm bg-cyan-500/20 text-cyan-300 rounded border border-cyan-500/50 hover:bg-cyan-500/40 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
>
Expand Down Expand Up @@ -81,7 +81,7 @@
{#each recentAddresses as addr}
<li>
<button
on:click={() => address = addr}
onclick={() => address = addr}
class="text-xs bg-gray-800/50 px-2 py-1 rounded border border-gray-700 hover:bg-gray-700/70"
>
{addr}
Expand Down
25 changes: 12 additions & 13 deletions apps/desktop/src/lib/components/Dojo.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
<script lang="ts">
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
import { createEventDispatcher } from 'svelte';
import NodeInfoPanel from './NodeInfoPanel.svelte';

const dispatch = createEventDispatcher();
let { onUpdateTokens }: { onUpdateTokens?: (amount: number) => void } = $props();

// Mock data for the current validation task
let question = "How do I fix a memory leak?";
let answerA = "Check for unclosed references and ensure proper resource disposal in your code.";
let answerB = "Restart your computer every hour and hope for the best.";
let question = $state("How do I fix a memory leak?");
let answerA = $state("Check for unclosed references and ensure proper resource disposal in your code.");
let answerB = $state("Restart your computer every hour and hope for the best.");

// Reactive state
let streak = 5;
let streak = $state(5);
let earnedTokens = tweened(0, {
duration: 400,
easing: cubicOut,
});
let selected: 'A' | 'B' | null = null;
let feedbackMessage = '';
let isAnimating = false;
let lastAnswerResult: 'correct' | 'incorrect' | null = null;
let selected: 'A' | 'B' | null = $state(null);
let feedbackMessage = $state('');
let isAnimating = $state(false);
let lastAnswerResult: 'correct' | 'incorrect' | null = $state(null);

async function handleSelection(choice: 'A' | 'B') {
if (isAnimating) return;
Expand All @@ -40,7 +39,7 @@
const reward = 10 + Math.floor(streak / 5); // Bonus for longer streaks
feedbackMessage = `Correct!`;
earnedTokens.set(reward);
dispatch('updateTokens', { amount: reward });
onUpdateTokens?.(reward);
} else {
lastAnswerResult = 'incorrect';
streak = 0;
Expand Down Expand Up @@ -85,7 +84,7 @@
<span class="answer-label">A)</span>
<p>{answerA}</p>
</div>
<button class="select-button" on:click={() => handleSelection('A')} disabled={isAnimating}>
<button class="select-button" onclick={() => handleSelection('A')} disabled={isAnimating}>
[SELECT A]
</button>
</div>
Expand All @@ -99,7 +98,7 @@
<span class="answer-label">B)</span>
<p>{answerB}</p>
</div>
<button class="select-button" on:click={() => handleSelection('B')} disabled={isAnimating}>
<button class="select-button" onclick={() => handleSelection('B')} disabled={isAnimating}>
[SELECT B]
</button>
</div>
Expand Down
12 changes: 6 additions & 6 deletions apps/desktop/src/lib/components/DojoPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
reward: number;
}

let currentTask: DojoTask | null = null;
let loading = false;
let rewardVisible = false;
let rewardAmount = 0;
let currentTask: DojoTask | null = $state(null);
let loading = $state(false);
let rewardVisible = $state(false);
let rewardAmount = $state(0);

async function loadTask() {
try {
Expand Down Expand Up @@ -94,7 +94,7 @@
<!-- Options -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<button
on:click={() => submit(currentTask?.option_a || "")}
onclick={() => submit(currentTask?.option_a || "")}
class="group relative h-48 bg-gradient-to-br from-zinc-900 to-zinc-900 border border-zinc-700 rounded-xl p-6 transition-all duration-300 hover:scale-[1.02] hover:border-emerald-500/50 hover:from-emerald-900/10 text-left">
<div class="absolute top-4 left-4 text-zinc-600 text-5xl font-black opacity-20 group-hover:text-emerald-500/20 transition-colors">A</div>
<div class="relative z-10 h-full flex items-center justify-center text-center">
Expand All @@ -105,7 +105,7 @@
</button>

<button
on:click={() => submit(currentTask?.option_b || "")}
onclick={() => submit(currentTask?.option_b || "")}
class="group relative h-48 bg-gradient-to-br from-zinc-900 to-zinc-900 border border-zinc-700 rounded-xl p-6 transition-all duration-300 hover:scale-[1.02] hover:border-blue-500/50 hover:from-blue-900/10 text-left">
<div class="absolute top-4 left-4 text-zinc-600 text-5xl font-black opacity-20 group-hover:text-blue-500/20 transition-colors">B</div>
<div class="relative z-10 h-full flex items-center justify-center text-center">
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/lib/components/GenerativeCanvas.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
export let blueprint: any = null;
let { blueprint = null }: { blueprint: any } = $props();

// Simple renderer for "Diffusion UI"
// In a real system, this would dynamically compile Svelte or use a component map
Expand Down
55 changes: 26 additions & 29 deletions apps/desktop/src/lib/components/ModelManager.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
// import { invoke } from '@tauri-apps/api/core'; // Uncomment when ready
import { invoke } from '@tauri-apps/api/core';

interface Model {
id: string;
Expand All @@ -13,7 +13,7 @@
recommended?: boolean; // If the system recommends this model for evolution
}

let models: Model[] = [
let models: Model[] = $state([
{
id: 'phi-3-mini-4k-instruct',
name: 'Phi-3 Mini',
Expand Down Expand Up @@ -47,38 +47,35 @@
status: 'ready',
tags: ['vision', 'core']
}
];
]);

let autoEvolutionEnabled = false;
let autoEvolutionEnabled = $state(false);

async function downloadModel(id: string) {
// Mock download logic
// Start local progress tracking
models = models.map(m => m.id === id ? { ...m, status: 'downloading', progress: 0 } : m);

// Simulate download
const interval = setInterval(() => {
models = models.map(m => {
if (m.id === id && m.status === 'downloading') {
const newProgress = (m.progress || 0) + 10;
if (newProgress >= 100) {
clearInterval(interval);
return { ...m, status: 'ready', progress: 100 };
}
return { ...m, progress: newProgress };
}
return m;
});
}, 500);

// await invoke('download_model', { modelId: id });
try {
await invoke('download_model', { model_id: id });
// On success, set to ready
models = models.map(m => m.id === id ? { ...m, status: 'ready', progress: 100 } : m);
} catch (e) {
console.error("Failed to download model:", e);
// Reset status on error
models = models.map(m => m.id === id ? { ...m, status: 'available' } : m);
}
}

async function activateModel(id: string) {
models = models.map(m => ({
...m,
status: m.id === id ? 'active' : (m.status === 'active' ? 'ready' : m.status)
}));
// await invoke('load_model', { modelId: id });
try {
await invoke('load_model', { model_id: id });
models = models.map(m => ({
...m,
status: m.id === id ? 'active' : (m.status === 'active' ? 'ready' : m.status)
}));
} catch (e) {
console.error("Failed to load model:", e);
}
}

function toggleAutoEvolution() {
Expand All @@ -98,7 +95,7 @@
<button
class="flex items-center gap-3 px-4 py-2 rounded-full border transition-all duration-300
{autoEvolutionEnabled ? 'bg-neural-purple/10 border-neural-purple text-neural-purple shadow-neon-purple' : 'bg-void-gray border-void-gray text-gray-400 hover:border-gray-600'}"
on:click={toggleAutoEvolution}
onclick={toggleAutoEvolution}
>
<div class="flex flex-col items-end">
<span class="text-[10px] font-bold tracking-wider">AUTO-EVOLUTION</span>
Expand Down Expand Up @@ -159,7 +156,7 @@
{#if model.status === 'available'}
<button
class="w-full py-2 rounded bg-void-gray hover:bg-gray-800 text-white text-xs font-bold tracking-wider transition-all flex items-center justify-center gap-2 group/btn"
on:click={() => downloadModel(model.id)}
onclick={() => downloadModel(model.id)}
>
<svg class="w-3 h-3 text-gray-400 group-hover/btn:text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
DOWNLOAD
Expand All @@ -180,7 +177,7 @@
{model.status === 'active'
? 'bg-cyber-cyan/10 text-cyber-cyan border border-cyber-cyan/50 cursor-default'
: 'bg-white text-black hover:bg-gray-200 hover:shadow-lg'}"
on:click={() => model.status !== 'active' && activateModel(model.id)}
onclick={() => model.status !== 'active' && activateModel(model.id)}
disabled={model.status === 'active'}
>
{#if model.status === 'active'}
Expand Down
30 changes: 11 additions & 19 deletions apps/desktop/src/lib/components/NodeInfoPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,18 @@
import { onMount } from 'svelte';
import { invoke } from '@tauri-apps/api/core';

let nodeInfo: any = null;
let error = null;
let nodeInfo: any = $state(null);
let error = $state(null);

onMount(async () => {
// MOCK DATA FOR VISUAL VERIFICATION
nodeInfo = {
peer_id: '12D3KooWQ...mock_peer_id...xyz',
addresses: [
'/ip4/192.168.1.10/tcp/12345',
'/ip4/10.0.0.5/tcp/12345'
]
};
// try {
// const info = await invoke('get_node_info');
// // Filter out loopback addresses
// info.addresses = info.addresses.filter(addr => !addr.includes('127.0.0.1'));
// nodeInfo = info;
// } catch (e) {
// error = e;
// }
try {
const info: any = await invoke('get_node_info');
// Filter out loopback addresses
info.addresses = info.addresses.filter((addr: string) => !addr.includes('127.0.0.1'));
nodeInfo = info;
} catch (e: any) {
error = e;
}
});

function copyAddress(addr: string) {
Expand All @@ -38,7 +30,7 @@
{#each nodeInfo.addresses as addr}
<div class="address-row">
<code>{addr}</code>
<button on:click={() => copyAddress(addr)}>📋 Copy</button>
<button onclick={() => copyAddress(addr)}>📋 Copy</button>
</div>
{/each}
{:else}
Expand Down
8 changes: 4 additions & 4 deletions apps/desktop/src/lib/components/NodeQRCode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
addresses: string[];
}

let qrDataUrl = '';
let selectedAddress = '';
let addresses: string[] = [];
let qrDataUrl = $state('');
let selectedAddress = $state('');
let addresses: string[] = $state([]);

onMount(async () => {
const nodeInfo = await invoke<NodeInfo>('get_node_info');
Expand Down Expand Up @@ -37,7 +37,7 @@
<h4>📱 Scan to Connect</h4>

{#if addresses.length > 1}
<select bind:value={selectedAddress} on:change={() => generateQR(selectedAddress)}>
<select bind:value={selectedAddress} onchange={() => generateQR(selectedAddress)}>
{#each addresses as addr}
<option value={addr}>{addr}</option>
{/each}
Expand Down
23 changes: 12 additions & 11 deletions apps/desktop/src/lib/components/PermissionGuard.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
// import { invoke } from '@tauri-apps/api/core'; // Uncomment when ready
import { invoke } from '@tauri-apps/api/core';

interface Permission {
id: string;
Expand All @@ -11,7 +11,7 @@
critical: boolean;
}

let permissions: Permission[] = [
let permissions: Permission[] = $state([
{
id: 'camera',
name: 'Visual Cortex',
Expand Down Expand Up @@ -44,16 +44,17 @@
granted: true,
critical: true
}
];
]);

let allGranted = false;

$: allGranted = permissions.every(p => p.granted);
let allGranted = $derived(permissions.every(p => p.granted));

async function requestPermission(id: string) {
// Mock request
// await invoke('request_permission', { permission: id });
permissions = permissions.map(p => p.id === id ? { ...p, granted: true } : p);
try {
await invoke('request_permission', { permission: id });
permissions = permissions.map(p => p.id === id ? { ...p, granted: true } : p);
} catch (e) {
console.error("Permission request failed:", e);
}
}

async function requestAll() {
Expand Down Expand Up @@ -109,7 +110,7 @@
</div>
{:else}
<button
on:click={() => requestPermission(p.id)}
onclick={() => requestPermission(p.id)}
class="px-4 py-2 bg-gray-700 hover:bg-gray-600 text-white text-sm rounded transition-colors"
>
Connect
Expand All @@ -121,7 +122,7 @@

<div class="p-6 bg-gray-800/50 border-t border-gray-700 flex justify-end">
<button
on:click={requestAll}
onclick={requestAll}
class="px-6 py-3 bg-cyan-600 hover:bg-cyan-500 text-white font-bold rounded-lg shadow-lg shadow-cyan-900/20 transition-all flex items-center gap-2"
>
Initialize All Systems
Expand Down
Loading
Loading