---
name: Environment Templates
description: Full CRUD management for task templates in this environment, including create, update, delete, and view operations.
argument-hint: list | view <name> | create <name> | update <name> | delete <name>
---

# Environment Templates Skill

This skill provides full management for task templates in the current environment:
- Template-level operations: list, view, create, update, delete

Use this when users want direct control over task templates and their parameters.

## Scope And Guardrails

- This skill can only modify templates in the current task's environment.
- Template names must use lowercase letters, numbers, and hyphens only.
- Use explicit user intent for destructive operations (`delete`).
- If user intent is already clear and explicit, execute directly; do not add unnecessary confirmation loops.

## Available Commands

### 1. List Templates (`/environment-templates list`)

List all templates in the current environment.

### 2. View Template (`/environment-templates view <name>`)

Fetch a template's content and metadata.

### 3. Create Template (`/environment-templates create <name>`)

Create a new task template with required fields:
- `content` - Template body (markdown with instructions)

Expected for new templates:
- `metadata.title` - Display title shown in the template picker. Always set this explicitly.
- `metadata.description` - Brief description shown in the template picker
- `metadata.parameters` - Object defining template parameters, when the template accepts inputs

### 4. Update Template (`/environment-templates update <name>`)

Update an existing template's content and/or metadata.

### 5. Delete Template (`/environment-templates delete <name>`)

Remove a template and its metadata from the environment.

## How It Works

This skill uses the task-scoped environment management API.

### Environment Variables

- `CODERFLOW_SERVER_URL` - Base URL for CoderFlow server
- `TASK_ID` - Task identifier used for auth (`X-Task-Id`)

### API Endpoints

- `GET /api/environment-management/templates` - List all templates
- `GET /api/environment-management/templates/:name` - Get specific template
- `PUT /api/environment-management/templates/:name` - Create or update template
- `DELETE /api/environment-management/templates/:name` - Delete template

## Template Structure

Templates consist of two files:
1. **`<name>.md`** - The template content (markdown with instructions)
2. **`<name>.json`** (optional) - Template metadata (title, description, parameters)

### Metadata JSON Structure

The metadata JSON should include a `title` string, a `description` string, and an optional `parameters` object. **Parameters are keyed by name** (an object map, not an array).

Always set `title` explicitly when creating a template. The server can fall back to the first markdown heading if `title` is omitted, but agents should not rely on that fallback because the UI-facing Template Title may be weak or missing.

```json
{
  "title": "Feature Implementation",
  "description": "Brief description shown in template picker",
  "parameters": {
    "feature_name": {
      "required": true,
      "description": "Help text shown in the UI",
      "default": "optional default value"
    }
  }
}
```

#### Parameter Fields

Each parameter supports:
- `required` (boolean) - Whether the parameter must be filled in. Default: `false`
- `description` (string) - Help text shown in the UI
- `default` (string) - Default value if not provided
- `prompt` (object) - Interactive selection configuration (see below)

Parameters without a `prompt` are rendered as plain text inputs.

#### Prompt Configuration (Interactive Selection)

Add a `prompt` object to a parameter to render it as an interactive selector instead of a text input.

**Common prompt fields (all prompt types):**
- `type` (required) - One of: `"list"`, `"command"`, `"files"`
- `label` (string) - Label shown on the prompt button/dialog
- `multiSelect` (boolean) - Allow selecting multiple values. Default: `false`. Max 4 multi-select parameters per template. Selected values are joined as a comma-separated string.

#### Prompt Type: `list` (hard-coded options)

```json
{
  "parameters": {
    "output_format": {
      "required": true,
      "description": "Output format to generate",
      "prompt": {
        "type": "list",
        "label": "Select Format",
        "multiSelect": true,
        "options": [
          { "value": "json", "label": "JSON", "description": "Standard JSON output" },
          { "value": "csv", "label": "CSV", "description": "Comma-separated values" },
          { "value": "xml", "label": "XML" }
        ]
      }
    }
  }
}
```

- `options` (required) - Array of choices. Each requires `value` (string). Optional: `label` (display text, defaults to value), `description` (smaller helper text).

#### Prompt Type: `command` (dynamic options from shell command)

```json
{
  "parameters": {
    "branch": {
      "required": true,
      "description": "Git branch to work on",
      "prompt": {
        "type": "command",
        "label": "Select Branch",
        "command": "git branch -a",
        "parser": "git-branches"
      }
    }
  }
}
```

- `command` (required) - Shell command to run in the container to generate choices
- `parser` - How to parse output. One of: `"json"` (default, expects `[{value, label?, description?}, ...]`), `"lines"` (newline-separated values), `"git-branches"` (parses git branch output), `"files"` (parses file paths)
- `repos` (array of strings) - Optional repo names to scope the command to

#### Prompt Type: `files` (file/directory browser)

```json
{
  "parameters": {
    "source_file": {
      "required": true,
      "description": "Source file to process",
      "prompt": {
        "type": "files",
        "label": "Select File",
        "multiSelect": true,
        "path": "src/",
        "include": "files",
        "pattern": "*.{js,ts,tsx}"
      }
    }
  }
}
```

- `path` (required) - Directory path relative to `/workspace`
- `include` - What to show: `"files"` (default), `"directories"`, or `"both"`
- `pattern` (string) - Optional glob pattern filter (e.g., `"*.{rpg,rpgle,sqlrpgle}"`)
- `repos` (array of strings) - Optional repo names to scope to

#### Multi-Select and Batch Processing

When `multiSelect: true`, the UI renders checkboxes instead of radio buttons. If multiple parameters have `multiSelect` enabled, the system generates a cartesian product of all selected values, creating a separate task for each combination. Max 4 multi-select parameters per template, max 100 total combinations.

### Template Content Syntax

**CRITICAL**: Template parameters must use `${parameter_name}` syntax (dollar sign + curly braces), NOT `{{parameter_name}}`.

CoderFlow's template rendering engine works in two passes:
1. **First pass**: Replaces `${variable}` with parameter values
2. **Second pass**: Processes EJS syntax (e.g., `<%= variable %>`)

**Correct syntax:**
```markdown
# Task: ${task_name}

Create a ${component_type} component with the following features:
- ${feature_description}
```

**Wrong syntax (will NOT work):**
```markdown
# Task: {{task_name}}  ❌ WRONG - parameters won't be substituted

Create a {{component_type}} component  ❌ WRONG
```

**Alternative (EJS syntax, also works):**
```markdown
# Task: <%= task_name %>

Create a <%= component_type %> component
```

## Implementation

### List Templates
```bash
curl -s "${CODERFLOW_SERVER_URL}/api/environment-management/templates" \
  -H "X-Task-Id: ${TASK_ID}"
```

**Response:**
```json
{
  "templates": [
    {"name": "bug-fix", "filename": "bug-fix.md", "description": "Fix a bug", "hasMetadata": true}
  ],
  "environment": "my-environment"
}
```

### Get Template
```bash
curl -s "${CODERFLOW_SERVER_URL}/api/environment-management/templates/bug-fix" \
  -H "X-Task-Id: ${TASK_ID}"
```

**Response:**
```json
{
  "name": "bug-fix",
  "content": "# Bug Fix Template\n\n...",
  "metadata": {"title": "Bug Fix", "description": "Fix a bug", "parameters": {}},
  "environment": "my-environment"
}
```

### Create/Update Template

**IMPORTANT**: When creating templates with parameters, always use a temporary file to avoid JSON array mangling in bash. Never embed complex JSON with arrays directly in `-d '{...}'`.

```bash
# Create a temporary file with the complete JSON payload
cat > /tmp/template-payload.json <<'EOF'
{
  "content": "# API Endpoint Implementation\n\nCreate a ${http_method} endpoint at ${endpoint_path}.\n\n${description}",
  "metadata": {
    "title": "API Endpoint Implementation",
    "description": "Create a new API endpoint",
    "parameters": {
      "endpoint_path": {
        "required": true,
        "description": "URL path for the endpoint (e.g., /api/users)"
      },
      "http_method": {
        "required": true,
        "description": "HTTP method",
        "prompt": {
          "type": "list",
          "label": "Select HTTP Method",
          "options": [
            { "value": "GET" },
            { "value": "POST" },
            { "value": "PUT" },
            { "value": "DELETE" }
          ]
        }
      },
      "description": {
        "required": false,
        "description": "Additional context for the endpoint"
      }
    }
  }
}
EOF

# Use the temp file with curl
curl -s -X PUT "${CODERFLOW_SERVER_URL}/api/environment-management/templates/api-endpoint" \
  -H "Content-Type: application/json" \
  -H "X-Task-Id: ${TASK_ID}" \
  -d @/tmp/template-payload.json
```

**Alternative using heredoc directly:**
```bash
curl -s -X PUT "${CODERFLOW_SERVER_URL}/api/environment-management/templates/api-endpoint" \
  -H "Content-Type: application/json" \
  -H "X-Task-Id: ${TASK_ID}" \
  -d @- <<'EOF'
{
  "content": "# API Endpoint Implementation\n\nCreate a ${http_method} endpoint at ${endpoint_path}.",
  "metadata": {
    "title": "API Endpoint Implementation",
    "description": "Create a new API endpoint",
    "parameters": {
      "endpoint_path": {
        "required": true,
        "description": "URL path for the endpoint"
      },
      "http_method": {
        "required": true,
        "description": "HTTP method",
        "prompt": {
          "type": "list",
          "label": "Select HTTP Method",
          "options": [
            { "value": "GET" },
            { "value": "POST" },
            { "value": "PUT" },
            { "value": "DELETE" }
          ]
        }
      }
    }
  }
}
EOF
```

### Delete Template
```bash
curl -s -X DELETE "${CODERFLOW_SERVER_URL}/api/environment-management/templates/old-template" \
  -H "X-Task-Id: ${TASK_ID}"
```

## Important Notes

1. When updating, preserve existing content that is still relevant.
2. Always assign a clear `metadata.title` for the Template Title shown in the UI.
3. Clearly define what parameters a template accepts in the metadata.
4. Templates affect how future tasks are created; call out impact before execution.
5. When creating templates with parameters, ALWAYS use a temp file (`cat > /tmp/file.json` + `-d @/tmp/file.json`) or heredoc (`-d @- <<'EOF'`). Never use inline `-d '{...}'` with complex nested JSON containing arrays, as bash shell escaping will corrupt the array structure.
6. After creating or updating a template, verify with a follow-up view call and confirm the saved metadata includes the intended `title`.
