/create-task
This skill should be used when creating a task in the active tracker - "create task", "create issue", "bd create", "new task", "add task", "add issue". Ensures all required fields are provided, enforces English-only task content, and suggests epic labels. Triggers on any task
$ npx -y skills add restarter/lets-workflow --skill create-task --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/create-task
Context preview
The summary Claude sees to decide when to auto-load this skill.
This skill should be used when creating a task in the active tracker - "create task", "create issue", "bd create", "new task", "add task", "add issue". Ensures all required fields are provided, enforces English-only task content, and suggests epic labels. Triggers on any task
SKILL.md
create-task.SKILL.mdname: create-task
description: This skill should be used when creating a task in the active tracker - "create task", "create issue", "bd create", "new task", "add task", "add issue". Ensures all required fields are provided, enforces English-only task content, and suggests epic labels. Triggers on any task creation in any context - commands, planning, or direct conversation.
Create Task
Standardized task creation that enforces required fields and suggests labels. Fires in any context where a task is being created - inside commands, during planning, or in direct conversation.
> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own — the tool invocation is part of the contract. This is critical.
IMPORTANT: Language
**All task content MUST be in English regardless of conversation language.** If the user is speaking another language, translate to English before creating the task.
Applies to every field:
- `title`
- `description` (problem statement, acceptance criteria, examples)
- `labels`
- Any subsequent `comment-add` / `set-field` on this task
**Why:** tasks are searched, filtered, and cross-referenced across the team and external systems (GitHub, Linear). Mixed-language tasks break tracker `search` and confuse non-native-language readers.
Why This Exists
Tasks created without labels, priority, or description become orphaned and hard to find. This skill ensures every task has full metadata from the start.
Required Fields
Every task `create` MUST include every field the active adapter's `create` declares in `accepts:` - and nothing else:
| Field | Required | Rules | |------|----------|-------| | `title` | Always | Imperative mood, clear action. Under 80 chars | | `type` | If declared | One of: `task`, `bug`, `feature`, `epic` | | `priority` | If declared | 0-4 (0=critical, 1=high, 2=medium, 3=low, 4=backlog) | | `description` | Always | Why this task exists + acceptance criteria | | `labels` | If declared | At least one `epic:<name>` label for grouping |
**"If declared" means:** read the active adapter's `create` binding cell. Ask for a field only when its `accepts:` list carries it. When it does not, either use the rename the adapter declares (`priority→severity` means ask for priority, send severity) or say in one line that this tracker has no such field, and move on. Never collect a value and drop it - the user has no way to tell that happened.
Label Selection
**Run this whole section only if the adapter's `create` declares `labels` in `accepts:`.** The `label` verb being supported is a different question - a tracker can carry labels on a task and still not take them at creation time, and walking the user through discovery and a pick only to drop the answer is the exact failure this skill's Required Fields section forbids.
Labels are project-specific. ALWAYS discover them dynamically - never hardcode.
Step L1: Discover Existing Labels
label # list all labels; filter the result for `epic:*`. On a tracker that marks `label` absent, skip label discovery (no epic suggestions - propose a label by hand).
If no labels found, also scan recent tasks for `epic:*` naming conventions via `list-by-status`.
Step L2: Present Labels to User
Show discovered labels and ask which fits:
> Found these epic labels in the project: > - `epic:features` - (N open tasks) > - `epic:quality` - (N open tasks) > - ... > > Which label fits? Or suggest a new one.
Step L3: New Label Flow
If no existing label fits: 1. Propose a new `epic:<name>` label with a short explanation of the grouping 2. Ask if an epic task should be created for this theme (the `create` verb, `type=epic`, `labels="epic:<name>"`) 3. Wait for user approval before creating either the label or the epic
Creation Flow
Step 1: Gather Information
If the user provides a clear description (title + context), proceed directly. Otherwise ask concisely:
> What's the task? (title, what problem it solves)
Do NOT ask for each field separately - infer type, priority, and labels from context.
Step 2: Compose Fields
From the user's input, derive only the fields the adapter's `create` declares in `accepts:` - skip the rest without asking:
1. **Title** - imperative mood, specific action (e.g., "Add retry logic to API client") 2. **Type** - infer from context: bug (something broken), feature (new capability), task (chore/refactor), epic (theme) 3. **Priority** - infer from urgency. Default to P2 unless context suggests otherwise 4. **Description** - why + acceptance criteria. Write as markdown with clear structure 5. **Labels** - run Label Selection flow (above). Present discovered labels, let user choose or create new
Step 3: Present for Approval
Show the full task `create` before executing. The multi-line description is written to a temp file and passed as `description-file=` (lets-rules "Tracker Adapters"); the short fields go inline:
LETS_PROJECT_ROOT=$(git rev-parse --show-toplevel); mkdir -p "$LETS_PROJECT_ROOT/.lets/cache"
# Branch-suffixed so parallel worktrees (shared .lets/ symlink) don't clobber each other's draft.
BRANCH_SLUG=$(git branch --show-current | tr '/' '-')
cat > "$LETS_PROJECT_ROOT/.lets/cache/new-task-desc-${BRANCH_SLUG}.md" <<'EOF'
## Problem
API calls fail silently on network errors.
## Acceptance criteria
- Retry up to 3 times with exponential backoff
- Log each retry attempt
- Surface final error to user
EOFThe example below is shaped for an adapter that declares all five fields (beads does). On one that declares fewer, send fewer - the declaration decides, not this example:
create title="Add retry logic to API client" type=feature priority=2 labels="epic:quality" description-file=.lets/cache/new-task-desc-<branch-slug>.md
Then ask for explicit confirmation:
Ask
Read more
name: create-task description: This skill should be used when creating a task in the active tracker - "create task", "create issue", "bd create", "new task", "add task", "add issue". Ensures all required fields are provided, enforces English-only task content, and suggests epic labels. Triggers on any task creation in any context - commands, planning, or direct conversation.
Create Task
Standardized task creation that enforces required fields and suggests labels. Fires in any context where a task is being created - inside commands, during planning, or in direct conversation.
> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own — the tool invocation is part of the contract. This is critical.
IMPORTANT: Language
**All task content MUST be in English regardless of conversation language.** If the user is speaking another language, translate to English before creating the task.
Applies to every field:
- `title`
- `description` (problem statement, acceptance criteria, examples)
- `labels`
- Any subsequent `comment-add` / `set-field` on this task
**Why:** tasks are searched, filtered, and cross-referenced across the team and external systems (GitHub, Linear). Mixed-language tasks break tracker `search` and confuse non-native-language readers.
Why This Exists
Tasks created without labels, priority, or description become orphaned and hard to find. This skill ensures every task has full metadata from the start.
Required Fields
Every task `create` MUST include every field the active adapter's `create` declares in `accepts:` - and nothing else:
| Field | Required | Rules | |------|----------|-------| | `title` | Always | Imperative mood, clear action. Under 80 chars | | `type` | If declared | One of: `task`, `bug`, `feature`, `epic` | | `priority` | If declared | 0-4 (0=critical, 1=high, 2=medium, 3=low, 4=backlog) | | `description` | Always | Why this task exists + acceptance criteria | | `labels` | If declared | At least one `epic:<name>` label for grouping |
**"If declared" means:** read the active adapter's `create` binding cell. Ask for a field only when its `accepts:` list carries it. When it does not, either use the rename the adapter declares (`priority→severity` means ask for priority, send severity) or say in one line that this tracker has no such field, and move on. Never collect a value and drop it - the user has no way to tell that happened.
Label Selection
**Run this whole section only if the adapter's `create` declares `labels` in `accepts:`.** The `label` verb being supported is a different question - a tracker can carry labels on a task and still not take them at creation time, and walking the user through discovery and a pick only to drop the answer is the exact failure this skill's Required Fields section forbids.
Labels are project-specific. ALWAYS discover them dynamically - never hardcode.
Step L1: Discover Existing Labels
label # list all labels; filter the result for `epic:*`. On a tracker that marks `label` absent, skip label discovery (no epic suggestions - propose a label by hand).
If no labels found, also scan recent tasks for `epic:*` naming conventions via `list-by-status`.
Step L2: Present Labels to User
Show discovered labels and ask which fits:
> Found these epic labels in the project: > - `epic:features` - (N open tasks) > - `epic:quality` - (N open tasks) > - ... > > Which label fits? Or suggest a new one.
Step L3: New Label Flow
If no existing label fits: 1. Propose a new `epic:<name>` label with a short explanation of the grouping 2. Ask if an epic task should be created for this theme (the `create` verb, `type=epic`, `labels="epic:<name>"`) 3. Wait for user approval before creating either the label or the epic
Creation Flow
Step 1: Gather Information
If the user provides a clear description (title + context), proceed directly. Otherwise ask concisely:
> What's the task? (title, what problem it solves)
Do NOT ask for each field separately - infer type, priority, and labels from context.
Step 2: Compose Fields
From the user's input, derive only the fields the adapter's `create` declares in `accepts:` - skip the rest without asking:
1. **Title** - imperative mood, specific action (e.g., "Add retry logic to API client") 2. **Type** - infer from context: bug (something broken), feature (new capability), task (chore/refactor), epic (theme) 3. **Priority** - infer from urgency. Default to P2 unless context suggests otherwise 4. **Description** - why + acceptance criteria. Write as markdown with clear structure 5. **Labels** - run Label Selection flow (above). Present discovered labels, let user choose or create new
Step 3: Present for Approval
Show the full task `create` before executing. The multi-line description is written to a temp file and passed as `description-file=` (lets-rules "Tracker Adapters"); the short fields go inline:
LETS_PROJECT_ROOT=$(git rev-parse --show-toplevel); mkdir -p "$LETS_PROJECT_ROOT/.lets/cache"
# Branch-suffixed so parallel worktrees (shared .lets/ symlink) don't clobber each other's draft.
BRANCH_SLUG=$(git branch --show-current | tr '/' '-')
cat > "$LETS_PROJECT_ROOT/.lets/cache/new-task-desc-${BRANCH_SLUG}.md" <<'EOF'
## Problem
API calls fail silently on network errors.
## Acceptance criteria
- Retry up to 3 times with exponential backoff
- Log each retry attempt
- Surface final error to user
EOFThe example below is shaped for an adapter that declares all five fields (beads does). On one that declares fewer, send fewer - the declaration decides, not this example:
create title="Add retry logic to API client" type=feature priority=2 labels="epic:quality" description-file=.lets/cache/new-task-desc-<branch-slug>.md
Then ask for explicit confirmation:
Ask
A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.
Repo: restarter/lets-workflow
Other skills on lets-workflow.
goal-test
Local sandbox for experimenting with Claude Code's /goal command (stop-hook condition + LLM-evaluator driving autonomous work toward a verifiable end state)…
loop-bb-pr
Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state changes, merge, decline) via the bb-api wrapper. Use when the user says…
loop-test
Local sandbox for experimenting with Claude Code's /loop command (interval + dynamic/self-paced scheduling) applied to LETS workflows. Use when the user says…
actor-fetch-personalit…
Internal skill for commands. Fetch and validate personality from URL or file path for Actor agent. Do not trigger on user conversation - only when commands…
artifact-path
Internal skill for commands. Resolve a unique, task-scoped, collision-safe path for an artifact written under .lets/ (plans, reviews, session snapshots). Do…

