HandlerScaffoldGen
Scaffold a TypeScript handler for concept $ARGUMENTS with typed actions, storage patterns, and a conformance test.
When to use: Use when implementing a concept handler in TypeScript. Generates a .handler.ts handler with register(), typed action methods, input extraction, storage patterns, and a conformance test file.
Design Principles
-
One Handler per Action: Each action in the concept spec maps to exactly one async method in the handler.
-
Variant Completeness: Every return variant declared in the spec must have a corresponding code path — no missing branches.
-
Storage Sovereignty: Each concept owns its storage exclusively — no shared databases, no cross-concept state access.
-
Input Extraction: Extract inputs with as casts at the top of each method. Validate required fields before processing.
Step-by-Step Process
Step 1: Register Generator
Self-register with PluginRegistry so KindSystem can track HandlerConfig → HandlerImpl transformations. Registration is also handled automatically by register-generator-kinds.sync.
Examples: Register the handler scaffold generator
const result = await handlerScaffoldGenHandler.register({}, storage);
Step 2: Preview Changes
Dry-run the generation using Emitter content-addressing to classify each output file as new, changed, or unchanged. No files are written.
Arguments: $0 conceptName (string), $1 actions (actiondef[])
Step 3: Generate Handler Implementation
Generate a handler implementation with register ( ) , typed action methods , input extraction , storage patterns , and an optional conformance test .
Arguments: $0 conceptName (string), $1 actions (actiondef[])
Checklist:
-
Handler export name follows convention (camelCase + 'Handler')?
-
register() returns correct name, inputKind, outputKind?
-
Each action extracts input parameters with correct types?
-
Each action returns all declared variants?
-
Storage operations use correct relation names?
-
Error handling catches and wraps exceptions?
-
Conformance test covers register() and each action?
-
All files written through Emitter (not directly to disk)?
-
Source provenance attached to each file?
-
Generation step recorded in GenerationPlan?
Examples: Generate a handler
clef scaffold handler --concept User --actions create,update,delete
Generate with test only
clef scaffold handler --concept Article
Step 4: Edit the Handler Implementation
Refine the generated handler: implement each action method with domain logic, extract inputs from the request with proper type casts, interact with storage using the correct relation names, and return the correct variant with all fields declared in the concept spec.
References
- Handler implementation patterns
Supporting Materials
- Handler implementation scaffolding walkthrough
Quick Reference
Input Type Purpose
conceptName String PascalCase concept name
actions list ActionDef Action signatures with params and variants
inputKind String KindSystem input kind
outputKind String KindSystem output kind
capabilities list String Generator capabilities
Anti-Patterns
Missing error variant
Handler doesn't return error variant on failure — caller gets an unstructured exception.
Bad:
async create(input, storage) { const id = crypto.randomUUID(); await storage.put('items', id, { name: input.name }); return { variant: 'ok', item: id }; // Exception propagates raw if storage.put fails! }
Good:
async create(input, storage) { try { const id = crypto.randomUUID(); await storage.put('items', id, { name: input.name }); return { variant: 'ok', item: id }; } catch (err) { return { variant: 'error', message: String(err) }; } }
Validation
Generate a handler scaffold:
npx tsx cli/src/index.ts scaffold handler --concept User --actions create,update,delete
Run generated conformance test:
npx vitest run tests/user.conformance.test.ts
Run scaffold generator tests:
npx vitest run tests/scaffold-generators.test.ts
Related Skills
Skill When to Use
/create-concept
Generate concept specs before implementing handlers
/implementation-builder
Use SchemaGen for more advanced handler generation
/concept-validator
Validate concept specs before generating handlers