skills + agents
This commit is contained in:
107
.kilo/skills/semantic-frontend/SKILL.md
Normal file
107
.kilo/skills/semantic-frontend/SKILL.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
name: semantics-frontend
|
||||
description: 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:
|
||||
|
||||
```html
|
||||
<!-- [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] -->
|
||||
Reference in New Issue
Block a user