C
CULTIVA IA Panel de Control Agentes
Svelte 5 + SvelteKit 2 Referencia Completa
Métricas de servicios — $state + $derived
Clientes activos
38
▲ +4 este mes
Tareas IA en curso
127
▲ +12 hoy
Créditos consumidos
8.4K
▼ 68% del límite
Tasa de entrega
99.1%
▲ SLA cumplido
Runes de Svelte 5 — Referencia rápida v5.0
Rune Propósito Svelte 4 equivalente
$state() Estado reactivo profundo let x = 0
$state.raw() Estado shallow (reasignación) let arr = []
$derived() Valor computado reactivo $: doubled = x * 2
$derived.by() Computed con lógica compleja $: { ... }
$effect() Side-effect + cleanup $: sideEffect()
$props() Props del componente export let prop
$bindable() Binding bidireccional bind:value
$inspect() Debug reactivo (dev only) console.log()
Tareas de agentes activos $state + $derived
Generar contenido SEO para TiendaOrgánica
Completado · hace 12 min
agente-seo
Análisis competidores SaaS B2B — NutriPaw
En curso · estimado 8 min
agente-research
Emails onboarding secuencia × 5 — FitStudio
En cola · prioridad alta
agente-copy
Liquid section hero Shopify — LaFlorería
Completado · hace 45 min
agente-shopify
Dashboard analytics Svelte — CULTIVA IA
En curso · este componente
agente-web
Componente Svelte 5 — CULTIVA Dashboard
DashboardMetrics.svelte Svelte 5
<script lang="ts">
  // $state — estado reactivo profundo
  let metrics = $state({
    clients: 38,
    tasks:   127,
    credits: 8400,
    sla:     99.1,
  });

  // $derived — computed automático
  let creditPct = $derived(
    (metrics.credits / 12000 * 100).toFixed(1)
  );

  // $derived.by — lógica compleja
  let summary = $derived.by(() => ({
    status: metrics.sla >= 99 ? 'OK' : 'WARN',
    load: metrics.tasks > 100 ? 'high' : 'normal',
  }));

  // $effect — sincronizar con backend
  $effect(() => {
    const id = setInterval(async () => {
      const res = await fetch('/api/metrics');
      const data = await res.json();
      // mutación directa — reactivo
      metrics.tasks = data.tasks;
    }, 30_000);
    return () => clearInterval(id); // cleanup
  });

  // $props — interfaz del componente
  let { workspace = $bindable('cultiva-ia') } = $props();
</script>

<section class="dashboard">
  <MetricCard
    label="Créditos"
    value={metrics.credits}
    pct={creditPct}
    status={summary.status}
  />
</section>
state/agentes.svelte.ts Store Svelte 5
// Store global con runes en .svelte.ts
let tasks = $state<Task[]>([]);
let done  = $derived(tasks.filter(t => t.done));
let pending = $derived(tasks.filter(t => !t.done));

export function useAgentStore() {
  return {
    get tasks()   { return tasks; },
    get done()    { return done; },
    get pending() { return pending; },
    addTask(t: Task) { tasks.push(t); },
    toggle(id: string) {
      const t = tasks.find(x => x.id === id);
      if (t) t.done = !t.done;
    },
  };
}
Sistema de notificaciones Store writable
Skill SEO completada — TiendaOrgánica +340 keywords
hace 2 min
Nuevo cliente onboarding: NutriPaw SaaS
hace 15 min
Créditos API al 68% — revisar límite mensual
hace 1h
Agente-research desplegado (v2.1.0)
hace 3h
Workspace activo $bindable
CULTIVA IA — Interno
cultiva-ia.com
ACTIVO
NutriPaw SaaS
nutripaw.io
EN CURSO
FitStudio Pro
fitstudio.es
PAUSADO
LaFlorería E-commerce
lafloria.com
EN CURSO
SvelteKit 2 — Estructura de rutas y convenciones
src/routes/+page.svelte
Componente de página. Recibe data via $props() desde load function.
src/routes/+page.ts
Load function. Ejecuta en servidor (SSR) y cliente. Retorna objeto data.
src/routes/+layout.svelte
Layout compartido. Usa {@render children()} en Svelte 5 (reemplaza slot).
src/routes/api/+server.ts
Endpoint API. Exporta handlers GET, POST, PATCH.
src/lib/state/*.svelte.ts
Stores globales con runes. Importar con alias $lib desde cualquier componente.
svelte.config.js
Adaptadores: node, vercel, static, cloudflare. Bundle mínimo ~6KB.
Tabla de migración — Svelte 4 a Svelte 5
Svelte 4 Svelte 5 Notas
let count = 0 let count = $state(0) Estado reactivo explícito
$: doubled = count * 2 let doubled = $derived(count * 2) Más claro, type-safe
$: { sideEffect() } $effect(() => { sideEffect() }) Con cleanup vía return
export let prop = "default" let { prop = "default" } = $props() Destructuring estándar JS
<slot /> {@render children()} Snippets tipados
<slot name="header" /> {@render header?.()} Named snippets opcionales
import { writable } from 'svelte/store' $state en .svelte.ts Sin boilerplate de stores
Snippets — sustituto de slots tipados
AgentList.svelte Snippets
<script>
  let { agents, row, footer } = $props();
</script>

<ul class="agent-list">
  {#each agents as agent}
    <li>{@render row(agent)}</li>
  {/each}
</ul>
{@render footer?.()}

<!-- Uso en padre -->
<AgentList {agents}>
  {#snippet row(agent)}
    <strong>{agent.name}</strong>
    <span>{agent.status}</span>
  {/snippet}
  {#snippet footer()}
    <p>Total: {agents.length} agentes</p>
  {/snippet}
</AgentList>
Transiciones y animaciones nativas
TaskQueue.svelte Transitions
<script>
  import { fade, fly, slide }
    from 'svelte/transition';
  import { flip } from 'svelte/animate';

  let tasks = $state([
    { id: 1, name: 'SEO audit' },
    { id: 2, name: 'Copy email' },
  ]);

  function remove(id) {
    tasks = tasks.filter(t => t.id !== id);
  }
</script>

{#each tasks as task (task.id)}
  <div
    animate:flip={{ duration: 300 }}
    transition:fly={{ y: -20, duration: 200 }}
    onclick={() => remove(task.id)}
  >
    {task.name}
  </div>
{/each}