Template System
Code generation with Handlebars templates
Template System
Generate code using Handlebars (.hbs) templates linked to documentation.
Overview
The Template System allows you to:
- Create reusable code templates with Handlebars syntax
- Link templates to documentation for context-aware generation
- Run templates via CLI or MCP for AI-assisted code generation
- Preview output with dry-run before writing files
Template Structure
Templates live in .knowns/templates/:
.knowns/templates/
└── component/
├── _template.yaml # Configuration file
└── {{name}}.tsx.hbs # Template file(s)
Configuration File (_template.yaml)
description: "React component generator"
doc: "patterns/component" # Linked documentation
prompts:
- variable: name
message: "Component name?"
default: "MyComponent"
- variable: type
message: "Component type?"
options: ["page", "component", "layout"]
files:
- template: "{{name}}.tsx.hbs"
output: "src/components/{{name}}.tsx"
- template: "{{name}}.test.tsx.hbs"
output: "src/components/{{name}}.test.tsx"
condition: "{{includeTests}}"Template File (.hbs)
import React from 'react';
interface {{pascalCase name}}Props {
children?: React.ReactNode;
}
export function {{pascalCase name}}({ children }: {{pascalCase name}}Props) {
return (
<div className="{{kebabCase name}}">
{children}
</div>
);
}CLI Commands
List Templates
knowns template list --plainView Template Details
knowns template view component --plain
knowns template component --plain # shorthandShows:
- Description
- Required variables (prompts)
- Files that will be generated
Run Template (Dry Run)
Preview without writing files:
knowns template run component --dry-runRun Template (Generate Files)
Interactive prompts will ask for variables:
knowns template run componentCreate Template
knowns template create api-endpoint -d "REST API endpoint generator"Handlebars Helpers
Case Transformations
| Helper | Input | Output |
|---|---|---|
{{pascalCase name}} | my-button | MyButton |
{{camelCase name}} | my-button | myButton |
{{kebabCase name}} | MyButton | my-button |
{{snakeCase name}} | MyButton | my_button |
{{upperCase name}} | myButton | MYBUTTON |
{{lowerCase name}} | MyButton | mybutton |
Conditionals
{{#if includeTests}}
import { render } from '@testing-library/react';
{{/if}}
{{#unless minimal}}
// Full implementation
{{/unless}}Loops
{{#each fields}}
{{this.name}}: {{this.type}};
{{/each}}Comparisons
{{#eq type "page"}}
export default function {{name}}Page() {
{{/eq}}
{{#eq type "component"}}
export function {{name}}() {
{{/eq}}Linking Documentation
Templates can reference documentation for AI context:
# _template.yaml
description: "API endpoint following our patterns"
doc: "patterns/api" # @doc/patterns/apiWhen AI runs this template:
- Reads
@doc/patterns/apifor context - Understands project conventions
- Generates code following patterns
Example: Full Template
_template.yaml
description: "Next.js API route handler"
doc: "patterns/api-routes"
prompts:
- variable: name
message: "Endpoint name (e.g., users, posts)?"
- variable: methods
message: "HTTP methods?"
options: ["GET", "POST", "GET,POST", "GET,POST,PUT,DELETE"]
default: "GET,POST"
files:
- template: "route.ts.hbs"
output: "src/app/api/{{kebabCase name}}/route.ts"route.ts.hbs
import { NextRequest, NextResponse } from 'next/server';
{{#contains methods "GET"}}
export async function GET(request: NextRequest) {
try {
// TODO: Implement GET /api/{{kebabCase name}}
return NextResponse.json({ message: 'Success' });
} catch (error) {
return NextResponse.json({ error: 'Failed' }, { status: 500 });
}
}
{{/contains}}
{{#contains methods "POST"}}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// TODO: Implement POST /api/{{kebabCase name}}
return NextResponse.json({ message: 'Created' }, { status: 201 });
} catch (error) {
return NextResponse.json({ error: 'Failed' }, { status: 500 });
}
}
{{/contains}}MCP Integration
Templates are available via MCP for AI assistants:
// List templates
mcp__knowns__list_templates({})
// Get template details
mcp__knowns__get_template({ "name": "component" })
// Run template (dry run)
mcp__knowns__run_template({
"name": "component",
"variables": { "name": "Button" },
"dryRun": true
})
// Run template (generate files)
mcp__knowns__run_template({
"name": "component",
"variables": { "name": "Button" },
"dryRun": false
})Best Practices
1. Link Documentation
Always link templates to relevant documentation:
doc: "patterns/component"This helps AI understand context when generating code.
2. Use Meaningful Defaults
prompts:
- variable: name
message: "Component name?"
default: "MyComponent" # Sensible default3. Include Dry Run in Workflow
Always preview before generating:
# Preview first
knowns template run component --var name=Header --dry-run
# Then generate
knowns template run component --var name=Header4. Organize Templates by Domain
.knowns/templates/
├── components/
│ └── react-component/
├── api/
│ └── rest-endpoint/
└── tests/
└── unit-test/
Importing Templates
Share templates across projects using the import system:
# Import from GitHub
knowns import github:myorg/templates --name my-templates
# Import from npm
knowns import npm:@myorg/templates --ref ^1.0.0
# Sync to get latest changes
knowns import sync my-templates
# List imported templates
knowns template list --plainImported templates are stored in .knowns/imports/<name>/templates/.
See Import System for full documentation on importing and syncing.
Supported AI Platforms
Templates can be used via CLI or MCP across multiple AI platforms:
| Platform | Skills | MCP |
|---|---|---|
| Claude Code | .claude/skills/ | Full |
| Antigravity | .agent/skills/ | Full |
| Gemini CLI | ~/.gemini/commands/ | Full |
| Cursor | .cursor/rules/ | Full |
| Windsurf | .windsurfrules | Limited |
| Cline | .clinerules/ | Full |
Note: Claude Code and Antigravity use the same SKILL.md format - templates and skills are portable!