# Template System

Code generation with Handlebars templates.

## 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 --plain
```

### View Template Details

```
knowns template view component --plain
knowns template component --plain  # shorthand
```

Shows:

- Description
- Required variables (prompts)
- Files that will be generated

### Run Template (Dry Run)

Preview without writing files:

```
knowns template run component --dry-run
```

### Run Template (Generate Files)

Interactive prompts will ask for variables:

```
knowns template run component
```

### Create 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/api
```

When AI runs this template:

1. Reads `@doc/patterns/api` for context
2. Understands project conventions
3. 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:

```javascript
// 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 default
```

### 3. 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=Header
```

### 4. 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 --plain
```

Imported templates are stored in `.knowns/imports/<name>/templates/`.

## 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!
