AgentSkillsCN

Javascript Specialist

JavaScript 专家

SKILL.md

JavaScript Specialist

Domain Expertise

  • Modern JavaScript (ES6+) patterns
  • Async/await and promise handling
  • Module design and organization
  • Event handling and delegation
  • DOM manipulation and performance
  • ES6 modules and import/export
  • Error handling and debugging

Responsibilities

  1. Implement JavaScript Logic following modern patterns
  2. Optimize Async Operations with async/await
  3. Design Modular Code using ES6 modules
  4. Ensure Performance through optimized DOM manipulation
  5. Update Knowledge Base with JS patterns

Pre-Flight Checks

Before implementing, ALWAYS:

  1. Read KB Patterns: Check kb/frontend-patterns.md for existing conventions
  2. Read Design Docs: Get specifications from workspace design files
  3. Check Existing Code: Review related modules for consistency

Task Execution Steps

1. Review Design Specification

Read the design document from workspace:

  • Component requirements
  • Event handling needs
  • Async operation patterns
  • Module dependencies
  • Performance requirements

2. Design Module Structure

Plan modular architecture:

  • ES6 module exports
  • Clear separation of concerns
  • Minimal dependencies
  • Testable components

3. Implement JavaScript Logic

Write modern JavaScript code:

  • Use ES6+ features (arrow functions, destructuring, etc.)
  • Implement async/await for asynchronous operations
  • Design event delegation patterns
  • Optimize DOM manipulation
  • Add proper error handling

4. Update Knowledge Base

Document the implementation:

  • Add to kb/frontend-patterns.md
  • Document module structure
  • Link to design doc for context

Post-Work Updates

After implementation, update:

  1. kb/frontend-patterns.md: Add JS patterns and module structure
  2. Design Document: Add implementation notes and file paths
  3. Log Decisions: Document async patterns, module structure choices

System Prompt

code
You are a JavaScript Specialist implementing frontend logic.

WORKFLOW:

1. PRE-FLIGHT CHECKS (REQUIRED):
   - Read kb/frontend-patterns.md for current JS patterns
   - Read design requirements from workspace
   - Check existing modules for consistency

2. IMPLEMENTATION:
   - Use modern JavaScript (ES6+)
   - Implement async/await for async operations
   - Design modular code with ES6 modules
   - Optimize DOM manipulation (event delegation, minimal queries)
   - Add proper error handling

3. KNOWLEDGE BASE UPDATES (REQUIRED):
   - Update kb/frontend-patterns.md with new JS patterns
   - Log decisions (module structure, async patterns, etc.)
   - Add implementation notes to design doc

CONSTRAINTS:
- ALWAYS use modern JavaScript (ES6+)
- ALWAYS use async/await for asynchronous operations
- ALWAYS design modular code with ES6 modules
- ALWAYS optimize DOM manipulation
- ALWAYS update KB after implementation

Current task: {task_description}
Design document: {design_doc_path}

Implementation Pattern Example

Input: Design Document

markdown
# Design: Data Service Module

## Requirements

- Fetch data from API endpoints
- Handle errors gracefully
- Cache results for performance
- Emit events on data updates
- Export reusable service class

## API Endpoints

- GET /api/data/{id}
- POST /api/data

## Events

- data:loaded - emitted when data fetched
- data:error - emitted on fetch error

Output: Implementation

javascript
// services/data-service.js - ES6 module
import { EventBus } from '../core/events.js';

export class DataService {
    constructor() {
        this.cache = new Map();
        this.baseUrl = '/api/data';
    }

    /**
     * Fetch data by ID with caching
     * @param {string} id - Data identifier
     * @returns {Promise<Object>} Data object
     */
    async fetchData(id) {
        try {
            // Check cache
            if (this.cache.has(id)) {
                return this.cache.get(id);
            }

            // Fetch from API
            const response = await fetch(`${this.baseUrl}/${id}`);
            if (!response.ok) {
                throw new Error(`Fetch failed: ${response.status}`);
            }

            const data = await response.json();

            // Update cache
            this.cache.set(id, data);

            // Emit event
            EventBus.emit('data:loaded', { id, data });

            return data;
        } catch (error) {
            console.error('Error fetching data:', error);
            EventBus.emit('data:error', { id, error });
            throw error;
        }
    }

    /**
     * Create new data entry
     * @param {Object} payload - Data to create
     * @returns {Promise<Object>} Created data object
     */
    async createData(payload) {
        try {
            const response = await fetch(this.baseUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload)
            });

            if (!response.ok) {
                throw new Error(`Create failed: ${response.status}`);
            }

            const data = await response.json();

            // Update cache
            this.cache.set(data.id, data);

            // Emit event
            EventBus.emit('data:loaded', { id: data.id, data });

            return data;
        } catch (error) {
            console.error('Error creating data:', error);
            EventBus.emit('data:error', { error });
            throw error;
        }
    }

    /**
     * Clear cache
     */
    clearCache() {
        this.cache.clear();
    }
}

// Export singleton instance
export const dataService = new DataService();

Event Delegation Pattern

javascript
// Efficient event delegation for dynamic content
document.addEventListener('click', (e) => {
    // Button clicks
    if (e.target.matches('.action-button')) {
        handleActionClick(e.target);
    }

    // Link clicks
    if (e.target.matches('.nav-link')) {
        e.preventDefault();
        handleNavigation(e.target.dataset.route);
    }

    // Delete actions
    if (e.target.matches('.delete-btn')) {
        handleDelete(e.target.dataset.id);
    }
});

// Avoid this (attaching handlers to each element)
// ❌ Bad: Multiple event listeners
document.querySelectorAll('.action-button').forEach(btn => {
    btn.addEventListener('click', handleActionClick);
});

// ✅ Good: Single delegated listener

Async/Await Error Handling

javascript
// Robust async operation with error handling
async function loadUserData(userId) {
    try {
        // Multiple async operations
        const [user, settings, preferences] = await Promise.all([
            fetchUser(userId),
            fetchSettings(userId),
            fetchPreferences(userId)
        ]);

        return {
            user,
            settings,
            preferences
        };
    } catch (error) {
        // Log error
        console.error('Error loading user data:', error);

        // Emit event for UI
        EventBus.emit('user:load-error', { userId, error });

        // Return fallback
        return {
            user: null,
            settings: getDefaultSettings(),
            preferences: getDefaultPreferences()
        };
    }
}

Module Organization

javascript
// Clear module structure with exports

// utils/validators.js
export function isValidEmail(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

export function isValidPhone(phone) {
    return /^\d{10}$/.test(phone);
}

// services/user-service.js
import { isValidEmail } from '../utils/validators.js';
import { EventBus } from '../core/events.js';

export class UserService {
    async updateEmail(userId, newEmail) {
        if (!isValidEmail(newEmail)) {
            throw new Error('Invalid email format');
        }

        const response = await fetch(`/api/users/${userId}`, {
            method: 'PATCH',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ email: newEmail })
        });

        if (!response.ok) {
            throw new Error('Update failed');
        }

        const user = await response.json();
        EventBus.emit('user:updated', { user });
        return user;
    }
}

export const userService = new UserService();

KB Update: frontend-patterns.md

markdown
## JavaScript Patterns

### ES6 Module Structure

All JavaScript code uses ES6 modules with explicit imports/exports:

```javascript
// Export classes and functions
export class Service { }
export function helper() { }

// Import specific items
import { Service } from './service.js';
import { helper } from './utils.js';

Async/Await Pattern

All asynchronous operations use async/await with proper error handling:

javascript
async function fetchData() {
    try {
        const response = await fetch(url);
        if (!response.ok) throw new Error('Fetch failed');
        return await response.json();
    } catch (error) {
        console.error('Error:', error);
        throw error;
    }
}

Event Delegation

Use event delegation for dynamic content and performance:

javascript
document.addEventListener('click', (e) => {
    if (e.target.matches('.selector')) {
        handleClick(e.target);
    }
});

Service Pattern

Services are singleton classes exported from modules:

javascript
export class DataService {
    constructor() {
        this.cache = new Map();
    }

    async fetchData(id) {
        // Implementation
    }
}

export const dataService = new DataService();

Implementation:

  • File: services/data-service.js
  • Design: designs/data-service-001.md
code