Code Kits
The full registry of Kits, their spec node types, output artifacts, and topological batch ordering.
Code Kits
Praetor's generation pipeline is made up of Kits — each one responsible for a single type of implementation node. The Kit Registry maps an implNodeType string to the Kit that handles it.
This page documents every registered Kit, ordered by the topological batch in which it runs.
Topological Batch Order
Kits and deterministic pipeline steps run in dependency order. Later batches can import types and contracts from earlier batches.
Batch 0: [DETERMINISTIC] ScaffoldStep
Batch 1: [DETERMINISTIC] SharedTypesStep + DesignSystemStep
Batch 2: [KIT] EntityKit, SchemaKit, GuardKit
Batch 3: [KIT] AuthKit
Batch 4: [DETERMINISTIC] MigrationStep
Batch 5: [KIT] ServiceKit
Batch 6: [KIT] OperationKit
Batch 7: [KIT] EndpointKit
Batch 8: [KIT] APIClientKit
Batch 9: [KIT] ComponentKit, UIStateKit
Batch 10: [KIT] PageKit
Batch 11: [KIT] LayoutKit, NavigationKit
Batch 12: [KIT] WorkflowKit, NotificationKit, AutomationKit
Batch 13: [DETERMINISTIC] TestInfraStep
Batch 14: [DETERMINISTIC] CICDStepDeterministic steps produce output from templates with no LLM. Kit batches may involve an LLM in their APPLY phase.
Core Application Kits
| Kit | implNodeType | Output artifacts | Verification strategy |
|---|---|---|---|
| EntityKit | impl_entity | src/db/schema/{tableName}.ts, drizzle.config.ts, drizzle/migrations/{ts}_create_{table}.sql | All required columns present in Drizzle schema; TypeScript types exported; primary key present |
| SchemaKit | impl_schema | src/schemas/{name}.ts (Zod) | Schema exports a named Zod object; all required fields present; .parse() call does not throw on valid input |
| GuardKit | impl_guard | src/guards/{name}.ts | Guard exports a Hono middleware function; auth check logic present; 401/403 responses covered |
| AuthKit | impl_auth | src/auth/service.ts, src/auth/jwt.ts, src/auth/password.ts, src/auth/middleware.ts, src/app/api/auth/[...nextauth]/route.ts | Session service exports login/register/logout; JWT sign and verify present; password hash function exported |
| ServiceKit | impl_service | src/services/{name}.ts | Service class exported; all operations from spec present as method stubs; constructor accepts repository or DB |
| OperationKit | impl_operation | src/operations/{name}.ts | Operation function exported; parameter types match spec; return type matches spec |
| EndpointKit | impl_endpoint | src/api/routes/{label-slug}.ts | Hono route handler exported; method and path match spec; request validation present; response shape matches spec |
| APIClientKit | impl_api_client | src/lib/api-client.ts or src/integrations/{name}/{name}-client.ts | Typed client class exported; one method per endpoint; parameter types match backend contract |
| RLSKit | impl_rls_policy | src/db/migrations/rls_{table}.sql, src/db/migrations/rls_setup.sql | RLS policies cover SELECT, INSERT, UPDATE, DELETE; tenant filter uses correct column; SET app.tenant_id helper present |
| WorkflowKit | impl_workflow | src/workflows/{name}.ts (Inngest function), src/api/inngest.ts | Inngest function exported; id and name fields present; at least one step.run call; event trigger name matches spec |
| NotificationKit | impl_notification | src/notifications/{name}.ts | Notification function exported; template renders to string; email/SMS sender type matches |
| AutomationKit | impl_ai_automation | src/integrations/quickbooks/quickbooks-client.ts (or similar) | Integration client exported; all declared methods present; error handling wraps external calls |
UI Kits
| Kit | implNodeType | Output artifacts | Verification strategy |
|---|---|---|---|
| ComponentKit | impl_ui_component | src/components/{name-kebab}.tsx | 'use client' directive present; component name exported as default; all entity type names imported; mutation hooks wired for triggered endpoints |
| PageKit | impl_ui_page | src/app/{route}/page.tsx | Page component exported as default; data-loading hooks present; auth guard applied if requiresAuth: true; route group matches auth requirement |
| LayoutKit | impl_ui_layout | src/app/{path}/layout.tsx, src/components/layout/sidebar.tsx, src/components/layout/top-nav.tsx, src/components/layout/breadcrumbs.tsx | Layout wraps {children}; sidebar imports navigation manifest; breadcrumbs follow route structure |
| NavigationKit | impl_ui_nav | src/lib/navigation.ts, src/lib/route-manifest.ts | Navigation manifest includes all registered pages; route paths match page spec; auth-required routes flagged |
| DataLayerKit (not currently registered) | impl_data_layer | src/lib/hooks/{entity}.hooks.ts (React Query hooks) | Query hooks exported for each declared endpoint; mutation hooks present for write endpoints; types match backend contract |
| UIStateKit | impl_ui_state | src/lib/stores/{name}.ts (Zustand store) | Store exported; all declared state slices present; action functions exported |
Mobile Kits
| Kit | implNodeType | Output artifacts | Verification strategy |
|---|---|---|---|
| MobileComponentKit | impl_mobile_component | React Native component .tsx | Component exported; StyleSheet used; platform-safe properties only |
| MobileScreenKit | impl_mobile_screen | React Native screen .tsx | Screen exported; navigation params typed; SafeAreaView present |
| MobileLayoutKit | impl_mobile_layout | React Native layout component .tsx | Layout exported; children prop typed; navigation container wired |
| MobileFormKit | impl_mobile_form | React Native form component .tsx | Form exported; all fields present; submit handler calls correct mutation |
Frappe / ERPNext Config Kits
These Kits handle ERPNext DocType configuration nodes. They produce JSON configuration files rather than TypeScript source. See Config Kits for full coverage.
| Kit | implNodeType | Output artifacts | Verification strategy |
|---|---|---|---|
| NamingSeriesKit | spec_naming_series | src/services/naming/{name}.naming.ts, src/db/migrations/create_naming_counters.sql | parsePattern exported; generateId handles all 4 pattern types (hash, prompt, field, prefix-year-counter) |
| ChildTableKit | spec_child_table | src/db/schema/{table}.ts, src/types/{name}.ts, src/api/routes/{name}-child.ts | Parent FK columns present (parentId, parentType, parentField, idx); Hono router exported; CRUD routes present |
| LinkFieldKit | spec_link_field | Link field helper and type resolver | Foreign key type resolves to correct entity; nullable unless required |
| SubmittableKit | spec_submittable | Submit/cancel/amend workflow helpers | Workflow states cover Draft → Submitted → Cancelled; status field present |
| DocLifecycleKit | spec_lifecycle | src/services/lifecycle/{name}-lifecycle.ts | All 9 hooks exported (beforeInsert, afterInsert, validate, beforeSave, afterSave, onSubmit, onCancel, onAmend, onTrash); lifecycle class implements typed interface |
| AmendmentKit | spec_amendment | Amendment workflow helpers and migration | amended_from field present; amendment chain traversal exported |
| DynamicLinkKit | spec_dynamic_link | Dynamic link resolver | Target doctype resolver handles polymorphic references |
| ReportKit | spec_report | Report query and renderer | Report function exported; query result typed; at least one column defined |
| PrintFormatKit | spec_print_format | Print format template | HTML/Jinja template present; entity fields referenced correctly |
| EmailTemplateKit | spec_email_template | Email template module | Template renders subject and body; variable substitution present |
| AttachmentKit | spec_attachment | Attachment handling utilities | Upload, retrieve, and delete functions exported; file size limit respected |
| ActivityKit | spec_activity | Activity log service | Log function exported; activity record includes user, timestamp, and action |
| TagKit | spec_tag | Tag service and migration | Tag CRUD helpers exported; tag-to-entity join table created |
| SharingKit | spec_sharing | Document sharing service | Share, revoke, and check-access functions exported |
| VersioningKit | spec_version | Version history service | Create-version and restore-version exported; diff computation present |
| WebFormKit | spec_web_form | Public web form route and renderer | Form route exports GET and POST handlers; CSRF protection present |
Kit Registry lookup
The pipeline uses a single call to dispatch to the correct Kit:
import { getKit, initializeKits } from './kits/kit-registry.js'
// At startup — loads all Kit modules and triggers self-registration
await initializeKits()
// At generation time — O(1) Map lookup
const kit = getKit(implNode.implNodeType)
if (!kit) {
log.warn({ implNodeType: implNode.implNodeType }, 'No Kit registered for this node type — skipping')
continue
}
const output = kit.generate(input)If no Kit is registered for an impl node type, that node is skipped and a warning is recorded in the generation run summary. It does not block other nodes.
Adding a new Kit
- Create
src/services/codegen/kits/{name}-kit.ts - Implement
CodegenKit(orMultiNodeCodegenKitif you need all nodes at once) - Call
registerKit(new MyKit())at the bottom of the file - Add
await import('./my-kit.js')insideinitializeKits()inkit-registry.ts
The Kit will be available immediately after the next initializeKits() call.