Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:52:38 +08:00
commit 19fda56570
14 changed files with 1024 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
{
"name": "api-schema-validator",
"description": "Validate API schemas with JSON Schema, Joi, Yup, or Zod",
"version": "1.0.0",
"author": {
"name": "Jeremy Longshore",
"email": "[email protected]"
},
"skills": [
"./skills"
],
"commands": [
"./commands"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# api-schema-validator
Validate API schemas with JSON Schema, Joi, Yup, or Zod

View File

@@ -0,0 +1,598 @@
---
description: Validate API schemas
shortcut: schema
---
# Validate API Schemas
Implement comprehensive schema validation using modern validation libraries like JSON Schema, Joi, Yup, or Zod to ensure type safety, data integrity, and contract compliance across your API.
## When to Use This Command
Use `/validate-schemas` when you need to:
- Enforce strict data types and formats in API requests and responses
- Create reusable validation schemas across multiple endpoints
- Generate TypeScript types from validation schemas
- Implement complex conditional validation logic
- Provide detailed validation error messages to clients
- Ensure data consistency before database operations
DON'T use this when:
- Working with unstructured or highly dynamic data (use runtime checks instead)
- Building quick prototypes without formal contracts (premature optimization)
- Validation logic is trivial (simple type checks may suffice)
## Design Decisions
This command implements **Zod** as the primary approach because:
- TypeScript-first with automatic type inference
- Composable schemas with chaining syntax
- Zero runtime dependencies
- Excellent error messages out of the box
- Schema transformation and parsing capabilities
- Works seamlessly with modern frameworks
**Alternative considered: Joi**
- More mature with extensive ecosystem
- Better for JavaScript-only projects
- More verbose API
- Recommended for legacy Node.js applications
**Alternative considered: JSON Schema**
- Language-agnostic standard
- Better for cross-platform validation
- More complex to write and maintain
- Recommended when sharing schemas across different languages
## Prerequisites
Before running this command:
1. Choose validation library based on your tech stack
2. Define validation requirements for each endpoint
3. Plan error response format
4. Consider performance impact for complex schemas
5. Determine validation strategy (fail-fast vs. collect-all-errors)
## Implementation Process
### Step 1: Define Base Schemas
Create reusable schema primitives for common data types and patterns.
### Step 2: Compose Endpoint Schemas
Build complex schemas by composing base schemas with business rules.
### Step 3: Integrate with Middleware
Set up validation middleware to automatically validate requests and responses.
### Step 4: Generate Types
Generate TypeScript types from schemas for compile-time safety.
### Step 5: Implement Error Handling
Create consistent error formatting and reporting mechanisms.
## Output Format
The command generates:
- `schemas/` - Schema definitions organized by domain
- `validators/` - Compiled validation functions
- `types/` - Generated TypeScript types from schemas
- `middleware/validation.ts` - Request/response validation middleware
- `tests/schema.test.ts` - Schema validation test suites
- `docs/validation-rules.md` - Documentation of all validation rules
## Code Examples
### Example 1: Zod Schema Validation (TypeScript)
```typescript
// schemas/user.schema.ts
import { z } from 'zod';
// Base schemas for reuse
const emailSchema = z.string().email().toLowerCase();
const passwordSchema = z.string()
.min(8, 'Password must be at least 8 characters')
.regex(/[A-Z]/, 'Password must contain uppercase letter')
.regex(/[a-z]/, 'Password must contain lowercase letter')
.regex(/[0-9]/, 'Password must contain number')
.regex(/[^A-Za-z0-9]/, 'Password must contain special character');
const phoneSchema = z.string().regex(
/^\+?[1-9]\d{1,14}$/,
'Invalid phone number format (E.164)'
);
const addressSchema = z.object({
street: z.string().min(1).max(100),
city: z.string().min(1).max(50),
state: z.string().length(2).toUpperCase(),
zipCode: z.string().regex(/^\d{5}(-\d{4})?$/),
country: z.string().length(2).toUpperCase().default('US')
});
// User schemas
export const createUserSchema = z.object({
body: z.object({
email: emailSchema,
password: passwordSchema,
firstName: z.string().min(1).max(50),
lastName: z.string().min(1).max(50),
dateOfBirth: z.string().datetime().refine(
(date) => {
const age = new Date().getFullYear() - new Date(date).getFullYear();
return age >= 18;
},
{ message: 'Must be at least 18 years old' }
),
phone: phoneSchema.optional(),
address: addressSchema.optional(),
preferences: z.object({
newsletter: z.boolean().default(false),
notifications: z.enum(['email', 'sms', 'push', 'none']).default('email'),
theme: z.enum(['light', 'dark', 'auto']).default('auto')
}).default({}),
metadata: z.record(z.string(), z.any()).optional()
})
});
export const updateUserSchema = z.object({
params: z.object({
id: z.string().uuid()
}),
body: createUserSchema.shape.body.partial().extend({
// Can't update email without verification
email: z.never().optional()
})
});
export const getUserSchema = z.object({
params: z.object({
id: z.string().uuid()
})
});
export const listUsersSchema = z.object({
query: z.object({
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
sort: z.enum(['createdAt', 'email', 'name']).default('createdAt'),
order: z.enum(['asc', 'desc']).default('desc'),
filter: z.object({
email: z.string().optional(),
status: z.enum(['active', 'inactive', 'suspended']).optional(),
createdAfter: z.string().datetime().optional(),
createdBefore: z.string().datetime().optional()
}).optional()
})
});
// Type inference
export type CreateUserInput = z.infer<typeof createUserSchema>;
export type UpdateUserInput = z.infer<typeof updateUserSchema>;
export type GetUserInput = z.infer<typeof getUserSchema>;
export type ListUsersInput = z.infer<typeof listUsersSchema>;
// Validation middleware
import { Request, Response, NextFunction } from 'express';
export function validate(schema: z.ZodSchema) {
return async (req: Request, res: Response, next: NextFunction) => {
try {
const validated = await schema.parseAsync({
body: req.body,
query: req.query,
params: req.params
});
// Replace request properties with validated/transformed data
req.body = validated.body || req.body;
req.query = validated.query || req.query;
req.params = validated.params || req.params;
next();
} catch (error) {
if (error instanceof z.ZodError) {
return res.status(400).json({
error: 'Validation failed',
details: error.errors.map(err => ({
path: err.path.join('.'),
message: err.message,
code: err.code
}))
});
}
next(error);
}
};
}
// Usage in routes
import express from 'express';
const router = express.Router();
router.post('/users',
validate(createUserSchema),
async (req, res) => {
// req.body is now typed and validated
const user = await createUser(req.body);
res.json(user);
}
);
router.put('/users/:id',
validate(updateUserSchema),
async (req, res) => {
const user = await updateUser(req.params.id, req.body);
res.json(user);
}
);
```
### Example 2: Joi Schema Validation (JavaScript)
```javascript
// schemas/product.schema.js
const Joi = require('joi');
// Custom validators
const customValidators = {
sku: Joi.string().pattern(/^[A-Z]{3}-\d{6}$/),
price: Joi.number().precision(2).positive().max(999999.99),
url: Joi.string().uri({ scheme: ['http', 'https'] })
};
// Product schemas
const productSchema = {
create: Joi.object({
sku: customValidators.sku.required(),
name: Joi.string().min(3).max(200).required(),
description: Joi.string().max(2000).required(),
price: customValidators.price.required(),
compareAtPrice: customValidators.price
.greater(Joi.ref('price'))
.optional(),
category: Joi.string().valid(
'electronics',
'clothing',
'food',
'books',
'other'
).required(),
tags: Joi.array()
.items(Joi.string().min(2).max(20))
.max(10)
.unique(),
inventory: Joi.object({
quantity: Joi.number().integer().min(0).required(),
trackInventory: Joi.boolean().default(true),
allowBackorder: Joi.boolean().default(false),
lowStockThreshold: Joi.number().integer().min(0).default(10)
}).required(),
images: Joi.array()
.items(Joi.object({
url: customValidators.url.required(),
alt: Joi.string().max(200),
isPrimary: Joi.boolean().default(false)
}))
.min(1)
.max(10)
.unique('url')
.required(),
shipping: Joi.object({
weight: Joi.number().positive().required(),
dimensions: Joi.object({
length: Joi.number().positive().required(),
width: Joi.number().positive().required(),
height: Joi.number().positive().required()
}).required(),
requiresShipping: Joi.boolean().default(true),
shippingClass: Joi.string().valid('standard', 'fragile', 'oversized')
}).when('category', {
is: 'electronics',
then: Joi.required(),
otherwise: Joi.optional()
}),
variants: Joi.array()
.items(Joi.object({
name: Joi.string().required(),
options: Joi.array()
.items(Joi.string())
.min(1)
.required()
}))
.optional(),
metadata: Joi.object().pattern(
Joi.string(),
Joi.alternatives().try(
Joi.string(),
Joi.number(),
Joi.boolean()
)
).optional()
}).custom((value, helpers) => {
// Custom validation: ensure at least one primary image
const primaryImages = value.images.filter(img => img.isPrimary);
if (primaryImages.length !== 1) {
return helpers.error('any.invalid', {
message: 'Exactly one image must be marked as primary'
});
}
return value;
}),
update: Joi.object({
name: Joi.string().min(3).max(200),
description: Joi.string().max(2000),
price: customValidators.price,
// ... partial schema
}).min(1), // At least one field required
list: Joi.object({
page: Joi.number().integer().positive().default(1),
limit: Joi.number().integer().min(1).max(100).default(20),
category: Joi.string(),
minPrice: Joi.number().positive(),
maxPrice: Joi.number().positive().greater(Joi.ref('minPrice')),
search: Joi.string().max(100),
inStock: Joi.boolean()
})
};
// Validation middleware
function validateRequest(schemaName) {
return async (req, res, next) => {
const schema = productSchema[schemaName];
if (!schema) {
return next(new Error(`Schema ${schemaName} not found`));
}
const dataToValidate = {
...req.body,
...req.query,
...req.params
};
try {
const validated = await schema.validateAsync(dataToValidate, {
abortEarly: false, // Return all errors
stripUnknown: true, // Remove unknown keys
convert: true // Type coercion
});
// Merge validated data back
Object.keys(validated).forEach(key => {
if (req.body.hasOwnProperty(key)) req.body[key] = validated[key];
if (req.query.hasOwnProperty(key)) req.query[key] = validated[key];
if (req.params.hasOwnProperty(key)) req.params[key] = validated[key];
});
next();
} catch (error) {
if (error.isJoi) {
return res.status(400).json({
error: 'Validation failed',
details: error.details.map(detail => ({
field: detail.path.join('.'),
message: detail.message,
type: detail.type
}))
});
}
next(error);
}
};
}
module.exports = {
productSchema,
validateRequest
};
```
### Example 3: Pydantic Schema Validation (Python)
```python
# schemas/order_schema.py
from pydantic import BaseModel, Field, validator, root_validator
from typing import List, Optional, Dict, Any
from datetime import datetime, date
from decimal import Decimal
from enum import Enum
import re
class OrderStatus(str, Enum):
PENDING = "pending"
PROCESSING = "processing"
SHIPPED = "shipped"
DELIVERED = "delivered"
CANCELLED = "cancelled"
class PaymentMethod(str, Enum):
CREDIT_CARD = "credit_card"
DEBIT_CARD = "debit_card"
PAYPAL = "paypal"
STRIPE = "stripe"
BANK_TRANSFER = "bank_transfer"
class Address(BaseModel):
street: str = Field(..., min_length=1, max_length=200)
city: str = Field(..., min_length=1, max_length=100)
state: str = Field(..., regex="^[A-Z]{2}$")
zip_code: str = Field(..., regex=r"^\d{5}(-\d{4})?$")
country: str = Field(default="US", regex="^[A-Z]{2}$")
@validator('state', 'country')
def uppercase_codes(cls, v):
return v.upper()
class OrderItem(BaseModel):
product_id: str = Field(..., regex="^[A-Z]{3}-\d{6}$")
quantity: int = Field(..., gt=0, le=100)
unit_price: Decimal = Field(..., decimal_places=2, ge=0)
discount: Optional[Decimal] = Field(None, decimal_places=2, ge=0, le=1)
@validator('discount')
def validate_discount(cls, v, values):
if v and v >= 1:
raise ValueError('Discount must be less than 100%')
return v
@property
def subtotal(self) -> Decimal:
discount_amount = self.discount or Decimal('0')
return self.quantity * self.unit_price * (1 - discount_amount)
class CreateOrderSchema(BaseModel):
customer_email: str = Field(..., regex=r"^[\w\.-]+@[\w\.-]+\.\w+$")
items: List[OrderItem] = Field(..., min_items=1, max_items=50)
shipping_address: Address
billing_address: Optional[Address] = None
payment_method: PaymentMethod
notes: Optional[str] = Field(None, max_length=500)
coupon_code: Optional[str] = Field(None, regex="^[A-Z0-9]{4,12}$")
@validator('customer_email')
def validate_email(cls, v):
# Additional email validation
if not re.match(r"^[\w\.-]+@[\w\.-]+\.\w+$", v.lower()):
raise ValueError('Invalid email format')
return v.lower()
@validator('billing_address', always=True)
def set_billing_address(cls, v, values):
# Use shipping address if billing not provided
return v or values.get('shipping_address')
@root_validator
def validate_order(cls, values):
items = values.get('items', [])
# Check for duplicate products
product_ids = [item.product_id for item in items]
if len(product_ids) != len(set(product_ids)):
raise ValueError('Duplicate products in order')
# Calculate total
total = sum(item.subtotal for item in items)
if total <= 0:
raise ValueError('Order total must be positive')
# Validate coupon if provided
coupon = values.get('coupon_code')
if coupon and not cls.validate_coupon(coupon):
raise ValueError('Invalid coupon code')
return values
@staticmethod
def validate_coupon(code: str) -> bool:
# Implement coupon validation logic
valid_coupons = ['SAVE10', 'FREESHIP', 'WELCOME20']
return code in valid_coupons
class UpdateOrderSchema(BaseModel):
status: Optional[OrderStatus] = None
shipping_address: Optional[Address] = None
notes: Optional[str] = Field(None, max_length=500)
tracking_number: Optional[str] = Field(None, regex=r"^[A-Z0-9]{10,30}$")
class Config:
use_enum_values = True
# FastAPI integration
from fastapi import FastAPI, HTTPException, Depends
from fastapi.encoders import jsonable_encoder
app = FastAPI()
@app.post("/orders", response_model=Dict[str, Any])
async def create_order(order: CreateOrderSchema):
# Validation happens automatically
order_dict = jsonable_encoder(order)
# Process order
return {"id": "ORD-123456", **order_dict}
@app.patch("/orders/{order_id}")
async def update_order(
order_id: str,
updates: UpdateOrderSchema
):
# Only provided fields will be updated
update_dict = updates.dict(exclude_unset=True)
# Update order
return {"id": order_id, **update_dict}
# Custom validation endpoint
@app.post("/validate/order")
async def validate_order(order: CreateOrderSchema):
# Just validate without processing
return {"valid": True, "data": order.dict()}
```
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| "Invalid type" | Wrong data type provided | Check schema definition and input data |
| "Required field missing" | Mandatory field not provided | Ensure all required fields are present |
| "Validation failed" | Business rule violation | Review custom validators and constraints |
| "Schema not found" | Referenced schema doesn't exist | Verify schema imports and definitions |
| "Circular dependency" | Schema references itself | Refactor to break circular references |
## Configuration Options
**Validation Strategies**
- `fail-fast`: Stop at first error (faster)
- `collect-all`: Gather all errors (better UX)
- `partial`: Allow partial validation for updates
**Type Coercion**
- `strict`: No type conversion
- `loose`: Attempt type conversion
- `smart`: Context-aware conversion
## Best Practices
DO:
- Create reusable base schemas for common patterns
- Use descriptive error messages for custom validators
- Generate TypeScript types from schemas
- Version schemas with your API
- Document all validation rules
- Test edge cases and boundary conditions
DON'T:
- Duplicate validation logic across layers
- Use overly complex nested schemas
- Ignore performance impact of complex validations
- Mix validation with business logic
- Trust client-side validation alone
## Performance Considerations
- Compile schemas once at startup
- Cache validated results for identical inputs
- Use async validation for external checks
- Limit regex complexity to prevent ReDoS attacks
- Consider schema complexity for large payloads
## Security Considerations
- Sanitize error messages to prevent information leakage
- Implement rate limiting on validation endpoints
- Use strict type checking to prevent injection attacks
- Validate file uploads separately with size limits
- Never expose internal schema structure to clients
## Related Commands
- `/api-response-validator` - Validate API responses
- `/api-contract-generator` - Generate schemas from code
- `/api-testing-framework` - Test with schema validation
- `/api-documentation-generator` - Document schemas
## Version History
- v1.0.0 (2024-10): Initial implementation with Zod, Joi, and Pydantic support
- Planned v1.1.0: Add support for Yup and JSON Schema generation

85
plugin.lock.json Normal file
View File

@@ -0,0 +1,85 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:jeremylongshore/claude-code-plugins-plus:plugins/api-development/api-schema-validator",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "6fe99a526667bc7dd391d56742a23288b3bd1d53",
"treeHash": "b459f932e847d68e0e05b35c5895225bc94d064291e4b9f5270a8ef65918b307",
"generatedAt": "2025-11-28T10:18:08.393637Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "api-schema-validator",
"description": "Validate API schemas with JSON Schema, Joi, Yup, or Zod",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "964deefdc89c0c6afb1af808195fbe152019a4c1bfffc8f3afc0d73245dcfc44"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "ee709d51ea913c41f0b22736ce467df18dc635d400156c703d512ee4c248c5f1"
},
{
"path": "commands/validate-schemas.md",
"sha256": "4b90ff709dc69abb52eacb253f61603dfe9d00ab397507a8729f789fde9293be"
},
{
"path": "skills/skill-adapter/references/examples.md",
"sha256": "922bbc3c4ebf38b76f515b5c1998ebde6bf902233e00e2c5a0e9176f975a7572"
},
{
"path": "skills/skill-adapter/references/best-practices.md",
"sha256": "c8f32b3566252f50daacd346d7045a1060c718ef5cfb07c55a0f2dec5f1fb39e"
},
{
"path": "skills/skill-adapter/references/README.md",
"sha256": "792835f31b3849b180d74f135ac6fe79cc3ed93b6c826b2ea62d6d6703724dab"
},
{
"path": "skills/skill-adapter/scripts/helper-template.sh",
"sha256": "0881d5660a8a7045550d09ae0acc15642c24b70de6f08808120f47f86ccdf077"
},
{
"path": "skills/skill-adapter/scripts/validation.sh",
"sha256": "92551a29a7f512d2036e4f1fb46c2a3dc6bff0f7dde4a9f699533e446db48502"
},
{
"path": "skills/skill-adapter/scripts/README.md",
"sha256": "f2f6a48cd8eb28031af2c6040a6bf96d1f8fa3a9780e8f4bf884ea16bfd3b89d"
},
{
"path": "skills/skill-adapter/assets/test-data.json",
"sha256": "ac17dca3d6e253a5f39f2a2f1b388e5146043756b05d9ce7ac53a0042eee139d"
},
{
"path": "skills/skill-adapter/assets/README.md",
"sha256": "784881a613b5da6273956467a368958c1c73d156a8122cbe93d85d62a6c83978"
},
{
"path": "skills/skill-adapter/assets/skill-schema.json",
"sha256": "f5639ba823a24c9ac4fb21444c0717b7aefde1a4993682897f5bf544f863c2cd"
},
{
"path": "skills/skill-adapter/assets/config-template.json",
"sha256": "0c2ba33d2d3c5ccb266c0848fc43caa68a2aa6a80ff315d4b378352711f83e1c"
}
],
"dirSha256": "b459f932e847d68e0e05b35c5895225bc94d064291e4b9f5270a8ef65918b307"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,7 @@
# Assets
Bundled resources for api-schema-validator skill
- [ ] example_schemas/: A directory containing example schemas in various formats (JSON Schema, Joi, Yup, Zod).
- [ ] test_data/: A directory containing example data files to validate against the schemas.
- [ ] schema_templates/: Templates for creating new schemas in different formats.

View File

@@ -0,0 +1,32 @@
{
"skill": {
"name": "skill-name",
"version": "1.0.0",
"enabled": true,
"settings": {
"verbose": false,
"autoActivate": true,
"toolRestrictions": true
}
},
"triggers": {
"keywords": [
"example-trigger-1",
"example-trigger-2"
],
"patterns": []
},
"tools": {
"allowed": [
"Read",
"Grep",
"Bash"
],
"restricted": []
},
"metadata": {
"author": "Plugin Author",
"category": "general",
"tags": []
}
}

View File

@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Claude Skill Configuration",
"type": "object",
"required": ["name", "description"],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9-]+$",
"maxLength": 64,
"description": "Skill identifier (lowercase, hyphens only)"
},
"description": {
"type": "string",
"maxLength": 1024,
"description": "What the skill does and when to use it"
},
"allowed-tools": {
"type": "string",
"description": "Comma-separated list of allowed tools"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"description": "Semantic version (x.y.z)"
}
}
}

View File

@@ -0,0 +1,27 @@
{
"testCases": [
{
"name": "Basic activation test",
"input": "trigger phrase example",
"expected": {
"activated": true,
"toolsUsed": ["Read", "Grep"],
"success": true
}
},
{
"name": "Complex workflow test",
"input": "multi-step trigger example",
"expected": {
"activated": true,
"steps": 3,
"toolsUsed": ["Read", "Write", "Bash"],
"success": true
}
}
],
"fixtures": {
"sampleInput": "example data",
"expectedOutput": "processed result"
}
}

View File

@@ -0,0 +1,9 @@
# References
Bundled resources for api-schema-validator skill
- [ ] json_schema_spec.md: A markdown file containing a summary of the JSON Schema specification.
- [ ] joi_documentation.md: A markdown file containing key excerpts from the Joi documentation.
- [ ] yup_documentation.md: A markdown file containing key excerpts from the Yup documentation.
- [ ] zod_documentation.md: A markdown file containing key excerpts from the Zod documentation.
- [ ] schema_best_practices.md: A guide to writing effective and maintainable schemas.

View File

@@ -0,0 +1,69 @@
# Skill Best Practices
Guidelines for optimal skill usage and development.
## For Users
### Activation Best Practices
1. **Use Clear Trigger Phrases**
- Match phrases from skill description
- Be specific about intent
- Provide necessary context
2. **Provide Sufficient Context**
- Include relevant file paths
- Specify scope of analysis
- Mention any constraints
3. **Understand Tool Permissions**
- Check allowed-tools in frontmatter
- Know what the skill can/cannot do
- Request appropriate actions
### Workflow Optimization
- Start with simple requests
- Build up to complex workflows
- Verify each step before proceeding
- Use skill consistently for related tasks
## For Developers
### Skill Development Guidelines
1. **Clear Descriptions**
- Include explicit trigger phrases
- Document all capabilities
- Specify limitations
2. **Proper Tool Permissions**
- Use minimal necessary tools
- Document security implications
- Test with restricted tools
3. **Comprehensive Documentation**
- Provide usage examples
- Document common pitfalls
- Include troubleshooting guide
### Maintenance
- Keep version updated
- Test after tool updates
- Monitor user feedback
- Iterate on descriptions
## Performance Tips
- Scope skills to specific domains
- Avoid overlapping trigger phrases
- Keep descriptions under 1024 chars
- Test activation reliability
## Security Considerations
- Never include secrets in skill files
- Validate all inputs
- Use read-only tools when possible
- Document security requirements

View File

@@ -0,0 +1,70 @@
# Skill Usage Examples
This document provides practical examples of how to use this skill effectively.
## Basic Usage
### Example 1: Simple Activation
**User Request:**
```
[Describe trigger phrase here]
```
**Skill Response:**
1. Analyzes the request
2. Performs the required action
3. Returns results
### Example 2: Complex Workflow
**User Request:**
```
[Describe complex scenario]
```
**Workflow:**
1. Step 1: Initial analysis
2. Step 2: Data processing
3. Step 3: Result generation
4. Step 4: Validation
## Advanced Patterns
### Pattern 1: Chaining Operations
Combine this skill with other tools:
```
Step 1: Use this skill for [purpose]
Step 2: Chain with [other tool]
Step 3: Finalize with [action]
```
### Pattern 2: Error Handling
If issues occur:
- Check trigger phrase matches
- Verify context is available
- Review allowed-tools permissions
## Tips & Best Practices
- ✅ Be specific with trigger phrases
- ✅ Provide necessary context
- ✅ Check tool permissions match needs
- ❌ Avoid vague requests
- ❌ Don't mix unrelated tasks
## Common Issues
**Issue:** Skill doesn't activate
**Solution:** Use exact trigger phrases from description
**Issue:** Unexpected results
**Solution:** Check input format and context
## See Also
- Main SKILL.md for full documentation
- scripts/ for automation helpers
- assets/ for configuration examples

View File

@@ -0,0 +1,7 @@
# Scripts
Bundled resources for api-schema-validator skill
- [ ] validate_schema.py: Script to validate a given schema against a data file or API endpoint.
- [ ] generate_schema.py: Script to generate a basic schema from a data file or API endpoint response.
- [ ] convert_schema.py: Script to convert between different schema formats (e.g., JSON Schema to Yup).

View File

@@ -0,0 +1,42 @@
#!/bin/bash
# Helper script template for skill automation
# Customize this for your skill's specific needs
set -e
function show_usage() {
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Enable verbose output"
echo ""
}
# Parse arguments
VERBOSE=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
*)
echo "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Your skill logic here
if [ "$VERBOSE" = true ]; then
echo "Running skill automation..."
fi
echo "✅ Complete"

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# Skill validation helper
# Validates skill activation and functionality
set -e
echo "🔍 Validating skill..."
# Check if SKILL.md exists
if [ ! -f "../SKILL.md" ]; then
echo "❌ Error: SKILL.md not found"
exit 1
fi
# Validate frontmatter
if ! grep -q "^---$" "../SKILL.md"; then
echo "❌ Error: No frontmatter found"
exit 1
fi
# Check required fields
if ! grep -q "^name:" "../SKILL.md"; then
echo "❌ Error: Missing 'name' field"
exit 1
fi
if ! grep -q "^description:" "../SKILL.md"; then
echo "❌ Error: Missing 'description' field"
exit 1
fi
echo "✅ Skill validation passed"