agentleFS
bbvch-aibbvch-ai/aihub-core/.claude/skills/scaffold-event-display/SKILL.md

scaffold-event-display

Skill16 starsChanged 3 days agoApache-2.0View on GitHub

Create a new event display component for the agent event timeline. Generates the Vue component with EventDisplayBase wrapper and registers it in the event component resolver (useEventComponent.ts). Use when user says 'create event display', 'scaffold event component', 'add event to timeline', 'new agent event UI', 'display a new event type', or 'register event display component'. Do NOT use for general Vue components (use scaffold-frontend-component), backend event class definitions (use nats-events reference), or full page scaffolding (use scaffold-frontend-page). Takes an event name as argument.

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 1 is distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Create a display component for a new agent event type.

    line 9
  2. Very specific:

    Read the frontend scope guide: packages/web/CLAUDE.md

    line 13
  3. Very specific:

    Check the event component resolver: packages/web/composables/event/useEventComponent.ts

    line 22
  4. Very specific:

    Check the backend event definition in packages/core/swiss_ai_hub/core/events/agent/ to understand:

    line 26
  5. Very specific:

    Protocol events are control and display: Every event of the capability calls (Conversation, Memory, AttachedFiles, Knowledge request and …

    line 34
  6. Very specific:

    Add the import to the #components import block:

    line 87
  7. Very specific:

    Add the mapping entry inside resolveComponentForEvent:

    line 96
  8. Very specific:

    Verify the component wraps content in EventDisplayBase with event, thread, and icon props

    line 119
  9. Very specific:

    Verify props use the intersection type pattern: ContextualizedAgentEvent & { event: {EventType} }

    line 120
  10. Very specific:

    Verify SDK types exist for the event — if not, warn user to run /generate-sdk

    line 121
  11. Very specific:

    Props typing: Always use ContextualizedAgentEvent & { event: {SpecificType} } for type narrowing (see ThoughtEvent.vue for example)

    line 144
  12. Distinctive:

    Tailwind only: No custom CSS (exception: Base.vue has scoped styles for PrimeVue overrides)

    line 146
  13. Very specific:

    PrimeVue components: Use InputText, Button, DataTable, Tag etc.

    line 147

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Scaffold a New Event Display Component

Create a display component for a new agent event type. The event name should be provided via $ARGUMENTS.

Before You Start

Read the frontend scope guide: packages/web/CLAUDE.md

Study existing event display components:

  • Simple: packages/web/components/Event/Display/ThoughtEvent.vue
  • With data fields: packages/web/components/Event/Display/ToolEvent.vue
  • Complex: packages/web/components/Event/Display/LLMEvent.vue
  • Base wrapper: packages/web/components/Event/Display/Base.vue

Check the event component resolver: packages/web/composables/event/useEventComponent.ts

Step 1: Identify the Event Type

Check the backend event definition in packages/core/swiss_ai_hub/core/events/agent/ to understand:

  • Event class name (e.g., MyNewEvent)
  • Fields available on the event
  • Parent event class (for inheritance-based resolution)

Also check the SDK types in packages/web/sdk/client/ for the TypeScript type.

Protocol events are control and display. Every event of the capability calls (Conversation, Memory, AttachedFiles, Knowledge request and result events) and of the tool loop (ToolLoop*, ToolCall*, ToolResult) is a ControlAndDisplayEvent, appears in the event history, and gets its own component here. The exceptions are ToolLoopStatusEvent and ToolLoopCondensedEvent, which are plain DisplayEvents. An event that renders as "Unknown" (UnknownEvent.vue) is missing its component and mapping. The event's _display_description also doubles as the chat's progress status, so write it as a short status sentence.

Step 2: Create the Component

Create packages/web/components/Event/Display/{EventName}Event.vue:

<template>
  <EventDisplayBase
    :event="event"
    :thread="thread"
    icon="<iconify-icon-name>"
  >
    <!-- Event-specific content rendered inside the collapsible panel -->
    <p class="text-2xl font-bold">
      {{ event.event.field_name }}
    </p>
  </EventDisplayBase>
</template>

<script setup lang="ts">
import type { ThreadDto, <EventName>Event, ContextualizedAgentEvent } from '@core/sdk/client'

defineProps<{
  event: ContextualizedAgentEvent & { event: <EventName>Event }
  thread: ThreadDto
}>()
</script>

EventDisplayBase Props

The Base.vue wrapper provides the card layout, raw data toggle, and agent badge. Your component fills the <slot>:

PropTypeDescription
eventContextualizedAgentEventRequired. The event object
threadThreadDtoRequired. Parent thread
iconstringRequired. Iconify icon name (e.g., mynaui:tool, hugeicons:brain)
isExternalbooleanOptional. Striped background for external agents
isEmptybooleanOptional. Hides slot content area
isWarningbooleanOptional. Yellow warning border
isErrorbooleanOptional. Red error border

Step 3: Register in Event Resolver

Edit packages/web/composables/event/useEventComponent.ts:

  1. Add the import to the #components import block:
import {
  // ... existing imports
  EventDisplay<EventName>Event,
} from '#components'
  1. Add the mapping entry inside resolveComponentForEvent:
const mapping = {
  // ... existing mappings
  <EventName>Event: EventDisplay<EventName>Event,
}

Step 4: Choose an Icon

Browse icons at https://icon-sets.iconify.design/. The project uses these icon sets:

  • mynaui:* (clean line icons)
  • hugeicons:* (detailed icons)
  • prime:* (PrimeVue icons)

Match the icon to the event's semantic meaning (e.g., mynaui:tool for tools, hugeicons:brain for LLM).

Step 5: Verify

  1. Confirm the component file exists at packages/web/components/Event/Display/{EventName}Event.vue
  2. Confirm useEventComponent.ts has both the #components import and the mapping entry for the new event
  3. Verify the component wraps content in EventDisplayBase with event, thread, and icon props
  4. Verify props use the intersection type pattern: ContextualizedAgentEvent & { event: {EventType} }
  5. Verify SDK types exist for the event — if not, warn user to run /generate-sdk

Examples

Typical invocation: /scaffold-event-display ToolCall

Result: Creates:

  • components/Event/Display/ToolCallEvent.vue — display component with EventDisplayBase wrapper
  • Updated useEventComponent.ts — import and mapping entry added

Troubleshooting

ProblemSolution
Event not rendered in timelineCheck mapping in useEventComponent.ts — event type name must match exactly
Type errors on event propsVerify SDK types are generated — run /generate-sdk if missing
Icon not showingVerify icon name at https://icon-sets.iconify.design/
Component renders but emptyCheck that isEmpty prop is not set and slot content accesses correct fields
Inheritance fallback not workingVerify _parent_event_names includes the parent event type

Key Conventions

  • Props typing: Always use ContextualizedAgentEvent & { event: {SpecificType} } for type narrowing (see ThoughtEvent.vue for example)
  • Tailwind only: No custom CSS (exception: Base.vue has scoped styles for PrimeVue overrides)
  • PrimeVue components: Use InputText, Button, DataTable, Tag etc. for data display
  • No i18n needed: Event display names come from the backend event_display_name field
  • Inheritance resolution: The resolver tries exact match first, then checks _parent_event_names

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.