一键导入
sea-handler-gen
Generate SEA handlers from specifications. Creates type-safe, validated handlers with proper error handling and governance compliance.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Generate SEA handlers from specifications. Creates type-safe, validated handlers with proper error handling and governance compliance.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends AI agent capabilities with specialized knowledge, workflows, or tool integrations.
Use when creating, scaffolding, or updating the repository AI harness in VS Code. Trigger on requests to bootstrap or refresh instructions, prompts, agents, hooks, skills, or memory layers while preserving useful existing structure and avoiding monolithic always-on context.
Canonical SEA-Forge release workflow for release preparation, validation, branch promotion, tagging, rollback, and release-gate evidence. Use when preparing a release, promoting dev to stage or stage to main, cutting a version tag, validating release readiness, handling hotfix forward-merges, planning rollback, or executing a full end-to-end release. Prefer existing just recipes and evidence-producing gates over ad hoc deployment steps.
Use when SEA work touches specs, generators, manifests, semantic fixtures, regeneration, `src/gen`, or behavior projected from ADR/PRD/SDS/SEA authority.
Use when a SEA context has valid specs and generated contracts but lacks handwritten logic, runtime wiring, persistence, integration, tests, or executable proof.
Create concise, copy-paste-ready bridge prompts between a repo-aware coding agent and an external strategic reasoning agent such as S1 ArchDevAgent. Use when the user wants to offload architecture, research, large refactor planning, migration design, plan critique, implementation-spec drafting, test-strategy design, whole-repo analysis, or diff review to an external agent while keeping repo inspection and implementation in the coding agent. Also use when the user says "use S1", "ask S1", "make a prompt for S1", "bridge this to my external agent", "prepare a context packet", or "validate this S1 response".
| name | sea-handler-gen |
| description | Generate SEA handlers from specifications. Creates type-safe, validated handlers with proper error handling and governance compliance. |
Generate type-safe, validated handlers from SEA specifications. Handlers include proper error handling, validation, logging, and governance compliance.
Invoke when:
User invokes with:
Claude invokes automatically:
# Find spec for context
SPEC_FILE="apps/$CONTEXT/spec/context.yaml"
# Validate spec exists
if [ ! -f "$SPEC_FILE" ]; then
echo "❌ Spec not found: $SPEC_FILE"
exit 1
fi
# Validate YAML syntax
yq eval '.' "$SPEC_FILE" > /dev/null || exit 1
# Validate against CALM schema if applicable
calm validate "$SPEC_FILE" 2>/dev/null || true
echo "✅ Spec validated: $SPEC_FILE"
# Extract API surface from spec
API_SURFACE=$(yq eval '.api_surface' "$SPEC_FILE")
# Extract endpoints
ENDPOINTS=$(echo "$API_SURFACE" | yq eval '.endpoints[]')
# Extract schemas
SCHEMAS=$(echo "$API_SURFACE" | yq eval '.schemas[]')
# Extract events
EVENTS=$(echo "$API_SURFACE" | yq eval '.events[]')
For each endpoint, generate a handler:
// src/gen/handlers/{endpoint-name}.ts
// ⚠️ GENERATED CODE - DO NOT EDIT ⚠️
// Generated from: spec/context.yaml
// Regenerate with: just pipeline {context}
import { z } from 'zod';
import { Context } from '@sprime01/sea';
import type { Request, Response } from 'express';
// Request schema (from spec)
const RequestSchema = z.object({
// Schema from spec.api_surface.schemas
});
// Response schema
const ResponseSchema = z.object({
// Response schema from spec
});
// Handler interface
export interface {EndpointName}Handler {
handle(request: Request): Promise<Response>;
}
// Handler implementation
export class {EndpointName}Handler implements {EndpointName}Handler {
constructor(
private readonly context: Context,
private readonly logger: Logger
) {}
async handle(request: Request): Promise<Response> {
try {
// Validate request
const validated = RequestSchema.parse(request.body);
// Business logic call
const result = await this.execute(validated);
// Validate response
const response = ResponseSchema.parse(result);
return {
status: 200,
body: response
};
} catch (error) {
this.logger.error('Handler error', { error, context: request.body });
if (error instanceof z.ZodError) {
return {
status: 400,
body: {
error: 'Validation error',
details: error.errors
}
};
}
return {
status: 500,
body: {
error: 'Internal server error'
}
};
}
}
private async execute(input: z.infer<typeof RequestSchema>) {
// TODO: Implement business logic
// This calls into the domain layer
throw new Error('Not implemented');
}
}
// src/gen/types/{context}.ts
// ⚠️ GENERATED CODE - DO NOT EDIT ⚠️
import { z } from 'zod';
// Request schemas
export const CreateUserRequestSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
preferences: z.record(z.unknown()).optional()
});
// Response schemas
export const UserResponseSchema = z.object({
id: z.string().uuid(),
name: z.string(),
email: z.string(),
createdAt: z.string().datetime()
});
// Domain types
export interface User {
id: string;
name: string;
email: string;
preferences: Record<string, unknown>;
createdAt: string;
}
// src/gen/router/{context}.ts
// ⚠️ GENERATED CODE - DO NOT EDIT ⚠️
import { Router } from 'express';
import { {EndpointName}Handler } from './handlers/{endpoint-name}';
import { Context } from '@sprime01/sea';
export function create{Context}Router(context: Context): Router {
const router = Router();
const handler = new {EndpointName}Handler(context, context.logger);
// Generated from spec.api_surface.endpoints
router.post('/api/{endpoint}', async (req, res) => {
const response = await handler.handle(req);
res.status(response.status).json(response.body);
});
return router;
}
// tests/handlers/{endpoint-name}.test.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { {EndpointName}Handler } from '../../src/gen/handlers/{endpoint-name}';
describe('{EndpointName}Handler', () => {
let handler: {EndpointName}Handler;
beforeEach(() => {
handler = new {EndpointName}Handler(
mockContext,
mockLogger
);
});
describe('handle', () => {
it('should validate request schema', async () => {
const request = {
body: { /* valid request */ }
};
const response = await handler.handle(request);
expect(response.status).toBe(200);
});
it('should reject invalid request', async () => {
const request = {
body: { /* invalid request */ }
};
const response = await handler.handle(request);
expect(response.status).toBe(400);
});
it('should handle domain errors', async () => {
// Test error scenarios
});
});
});
Add .SEA-PROTECTED marker to all generated files:
/**
* ⚠️ GENERATED CODE - DO NOT EDIT ⚠️
*
* This file is automatically generated from:
* apps/{context}/spec/context.yaml
*
* To modify this handler:
* 1. Edit the spec file
* 2. Run: just pipeline {context}
* 3. Handlers will be regenerated
*
* Manual edits will be overwritten.
*
* Generated at: {timestamp}
* Spec version: {version}
*/
// Create
export class Create{Entity}Handler {
async handle(request: Create{Entity}Request): Promise<{Entity}Response> {
const entity = await this.domain.create(request.body);
return this.serializer.serialize(entity);
}
}
// Read
export class Read{Entity}Handler {
async handle(request: Read{Entity}Request): Promise<{Entity}Response> {
const entity = await this.domain.findById(request.params.id);
if (!entity) {
throw new NotFoundError('Entity not found');
}
return this.serializer.serialize(entity);
}
}
// Update
export class Update{Entity}Handler {
async handle(request: Update{Entity}Request): Promise<{Entity}Response> {
const entity = await this.domain.update(request.params.id, request.body);
return this.serializer.serialize(entity);
}
}
// Delete
export class Delete{Entity}Handler {
async handle(request: Delete{Entity}Request): Promise<void> {
await this.domain.delete(request.params.id);
}
}
export class {EventName}Handler {
async handle(event: {EventName}Event): Promise<void> {
// Validate event schema
const validated = {EventName}Schema.parse(event);
// Process event
await this.domain.processEvent(validated);
// Emit downstream events if applicable
await this.eventBus.publish({
type: '{EventName}Processed',
payload: validated
});
}
}
After generation, validate:
# TypeScript compilation
tsc --noEmit
# Linting
eslint src/gen/
# Schema validation
# (validate generated schemas match spec)
# Test compilation
vitest --run tests/
sea-generator-first for pipeline executionspec-guardian for generated zone protectiongovernance-validation for CALM compliancezod for runtime validationAfter generation:
## Handlers Generated
**Context**: {context}
**Spec**: spec/context.yaml
**Version**: {version}
### Generated Files
- Handlers: {count}
- Types: {count}
- Router: 1
- Tests: {count}
### Handlers
- {endpoint1}: Create{Entity}Handler
- {endpoint2}: Read{Entity}Handler
- {endpoint3}: Update{Entity}Handler
- {endpoint4}: Delete{Entity}Handler
### Validation
✅ TypeScript compilation passed
✅ All schemas validated
✅ Tests templates generated
### Next Steps
1. Implement business logic in domain layer
2. Run tests: pnpm test
3. Test API surface: pnpm test:e2e