Files
ss-tools/.kilo/skills/semantic-frontend/SKILL.md
2026-04-19 20:05:45 +03:00

5.2 KiB

name, description
name description
semantics-frontend Core protocol for Svelte 5 (Runes) Components, UX State Machines, and Visual-Interactive Validation.

[DEF:Std:Semantics:Frontend]

@COMPLEXITY: 5

@PURPOSE: Canonical GRACE-Poly protocol for Svelte 5 (Runes) Components, UX State Machines, and Project UI Architecture.

@RELATION: DEPENDS_ON ->[Std:Semantics:Core]

@INVARIANT: Frontend components MUST be verifiable by an automated GUI Judge Agent (e.g., Playwright).

@INVARIANT: Use Tailwind CSS exclusively. Native fetch is forbidden.

0. SVELTE 5 PARADIGM & UX PHILOSOPHY

  • STRICT RUNES ONLY: You MUST use Svelte 5 Runes for reactivity: $state(), $derived(), $effect(), $props(), $bindable().
  • FORBIDDEN SYNTAX: Do NOT use export let, on:event (use onclick), or the legacy $: reactivity.
  • UX AS A STATE MACHINE: Every component is a Finite State Machine (FSM). You MUST declare its visual states in the contract BEFORE writing implementation.
  • RESOURCE-CENTRIC: Navigation and actions revolve around Resources. Every action MUST be traceable.

I. PROJECT ARCHITECTURAL INVARIANTS

You are bound by strict repository-level design rules. Violating these causes instant PR rejection.

  1. Styling: Tailwind CSS utility classes are MANDATORY. Minimize scoped <style>. If custom CSS is absolutely necessary, use @apply directives.
  2. Localization: All user-facing text MUST use the $t store from src/lib/i18n. No hardcoded UI strings.
  3. API Layer: You MUST use the internal requestApi / fetchApi wrappers. Using native fetch() is a fatal violation.

II. UX CONTRACTS (STRICT UI BEHAVIOR)

Every component MUST define its behavioral contract in the header.

  • @UX_STATE: Maps FSM state names to visual behavior. Example: @UX_STATE: Loading -> Spinner visible, btn disabled, aria-busy=true.
  • @UX_FEEDBACK: Defines external system reactions (Toast, Shake, RedBorder).
  • @UX_RECOVERY: Defines the user's recovery path from errors (e.g., Retry button, Clear Input).
  • @UX_REACTIVITY: Explicitly declares the state source. Example: @UX_REACTIVITY: Props -> $props(), LocalState -> $state(...).
  • @UX_TEST: Defines the interaction scenario for the automated Judge Agent. Example: @UX_TEST: Idle -> {click: submit, expected: Loading}.

III. STATE MANAGEMENT & STORE TOPOLOGY

  • Subscription: Use the $ prefix for reactive store access (e.g., $sidebarStore).
  • Graph Linkage: Whenever a component reads or writes to a global store, you MUST declare it in the [DEF] header metadata using: @RELATION: BINDS_TO -> [Store_ID]

IV. IMPLEMENTATION & ACCESSIBILITY (A11Y)

  1. Event Handling: Use native attributes (e.g., onclick={handler}).
  2. Transitions: Use Svelte's built-in transitions for UI state changes to ensure smooth UX.
  3. Async Logic: Any async task (API calls) MUST be handled within a try/catch block that explicitly triggers an @UX_STATE transition to Error on failure and provides @UX_FEEDBACK (e.g., Toast).
  4. A11Y: Ensure proper ARIA roles (aria-busy, aria-invalid) and keyboard navigation. Use semantic HTML (<nav>, <main>).

V. LOGGING (MOLECULAR TOPOLOGY FOR UI)

Frontend logging bridges the gap between your logic and the Judge Agent's vision system.

  • [EXPLORE]: Log branching user paths or caught UI errors.
  • [REASON]: Log the intent before an API invocation.
  • [REFLECT]: Log visual state updates (e.g., "Toast displayed", "Drawer opened").
  • Syntax: console.info("[ComponentID][MARKER] Message", {extra_data}) — Prefix MUST be manually applied.

VI. CANONICAL SVELTE 5 COMPONENT TEMPLATE

You MUST strictly adhere to this AST boundary format:

<!-- [DEF:ComponentName:Component] -->
<script>
  /**
   * @COMPLEXITY: [1-5]
   * @PURPOSE: Brief description of the component purpose.
   * @LAYER: UI
   * @SEMANTICS: list, of, keywords
   * @RELATION: DEPENDS_ON -> [OtherComponent]
   * @RELATION: BINDS_TO -> [GlobalStore]
   * 
   * @UX_STATE: Idle -> Default view.
   * @UX_STATE: Loading -> Button disabled, spinner active.
   * @UX_FEEDBACK: Toast notification on success/error.
   * @UX_REACTIVITY: Props -> $props(), State -> $state().
   * @UX_TEST: Idle -> {click: action, expected: Loading}
   */
  import { fetchApi } from "$lib/api";
  import { t } from "$lib/i18n";
  import { taskDrawerStore } from "$lib/stores";
  
  let { resourceId } = $props();
  let isLoading = $state(false);

  async function handleAction() {
    isLoading = true;
    console.info("[ComponentName][REASON] Opening task drawer for resource", { resourceId });
    try {
      taskDrawerStore.open(resourceId);
      await fetchApi(`/api/resource/${resourceId}/process`);
      console.info("[ComponentName][REFLECT] Process completed successfully");
    } catch (e) {
      console.error("[ComponentName][EXPLORE] Action failed", { error: e });
    } finally {
      isLoading = false;
    }
  }
</script>

<div class="flex flex-col p-4 bg-white rounded-lg shadow-md">
  <button 
    class="btn-primary" 
    onclick={handleAction} 
    disabled={isLoading}
    aria-busy={isLoading}
  >
    {#if isLoading} <span class="spinner"></span> {/if}
    {$t('actions.start')}
  </button>
</div>
<!--[/DEF:ComponentName:Component] -->