/take-task
This skill should be used when claiming a task to work on - "take task", "візьми таск", "працюю над", "work on task X", "pick task X", "switch to task X", "claim task". Sets task to in_progress, creates/switches branch, saves the per-branch task-state file.
Claude Code
$ npx -y skills add restarter/lets-workflow --skill take-task --agent claude-code
Codex
$ npx skills add restarter/lets-workflow --skill take-task -a codex -y
Cursor
$ npx skills add restarter/lets-workflow --skill take-task -a cursor -y
Gemini CLI
$ npx skills add restarter/lets-workflow --skill take-task -a gemini-cli -y
GitHub Copilot
$ npx skills add restarter/lets-workflow --skill take-task -a github-copilot -y
OpenCode
$ npx skills add restarter/lets-workflow --skill take-task -a opencode -y
Windsurf
$ npx skills add restarter/lets-workflow --skill take-task -a windsurf -y
SKILL.md
take-task.SKILL.mdname: take-task
description: This skill should be used when claiming a task to work on - "take task", "візьми таск", "працюю над", "work on task X", "pick task X", "switch to task X", "claim task". Sets task to in_progress, creates/switches branch, saves the per-branch task-state file.
Take Task
Claim a tracker task and prepare the working environment.
> **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.
Why This Exists
Multiple flows need "claim task + prepare branch": /lets:start, mid-session task switch, direct "візьми таск X". Centralizing ensures consistent branch naming, worktree handling, and session ref saving.
Flow
Step 1: Resolve Task
**Tracker protocol:** `Skill(skill: "lets:protocol-tracker")` before this and any later `lets-tracker` block here, unless its text is in your current context.
show task=<task-id>
Verify task exists. Then claim it (set-status is a state change - HARD-FAIL loud if the binding can't run; do NOT proceed to branch setup on a failed claim):
set-status task=<task-id> status=in_progress
Step 2: Check Uncommitted Changes
**Team worktree** - `lets worktree info --json` reports a top-level `team`: this worktree belongs to a standing team and moves between tasks through `lets worktree switch`. Skip the generic question below and go to **Step 2T**. No `team` -> continue here.
Before switching branches, check for uncommitted changes:
git status --short
If changes exist and branch switch is needed, ask user:
AskUserQuestion(
questions=[{
question: "Uncommitted changes on current branch. What to do?",
header: "Uncommitted",
options: [
{ label: "Stash", description: "git stash, switch branch, remind to pop later" },
{ label: "Commit first", description: "Commit changes, then switch branch" },
{ label: "Stay", description: "Skip branch switch - work on current branch" }
],
multiSelect: false
}]
)Handle response:
- **Stash** -> `git stash`, proceed with branch switch, remind to `git stash pop` later
- **Commit first** -> delegate to commit skill, then proceed with branch switch
- **Stay** -> skip branch switch, warn about mixed work, then continue to Step 5 (the task was already claimed in Step 1 - save its `.task` state file for the current branch; do NOT stop before it, or detect-task/`/lets:done` are left with a claim but no boundary file).
If staying on current branch (worktree, already correct) or no changes - skip this step.
Step 2T: Team worktree - park, then switch
**Busy writer first.** Before anything else, run `ListAgents`. A busy agent of THIS session that writes in this tree stops the switch: a group agent of `.lets/cache/delegated-run-*.json` with `isolation: null` listed `running`, or a `Member:` id of this lead session in the team file that `ListAgents` lists `running` and whose spawn brief `.lets/cache/member-<team>-<name>.md` ("You are <name> (lets:<role>) of team <c>") names `lets:implementer` - every team agent is classified by its spawn brief, never by the roster (`/lets:team spawn` may run any role under any name); a brief that is missing, unreadable or names no role counts as a writer, never as read-only -> stop: "`{name}` is still working in this tree - wait for its report, or stop it (`/lets:team dismiss <name>`, or the run's Stop), then `/lets:start` again"; nothing is switched. A brief naming any other role is read-only. The same agent idle -> one line "`{name}` is idle and keeps `{branch}`'s context - dismiss it before its next brief", continue. Isolated implementers and read-only roles never block.
Read `${CLAUDE_PLUGIN_ROOT}/protocol/worktrees.md` before this step unless its text is in your current context (standing-team worktree, park never stash).
A team worktree never stashes. `git status --short`; changes present -> list them, and list separately every NEW path a park would need to name - untracked (`git ls-files --others --exclude-standard`) and staged additions (`git diff --cached --diff-filter=ACR --name-only HEAD`). Ignored files are never parked; they stay on disk. Then:
AskUserQuestion(
questions=[{
question: "Uncommitted changes on {branch} before switching to {task-id}. What to do?",
header: "Uncommitted",
options: [
{ label: "Commit first", description: "Commit them with /lets:commit, then switch" },
{ label: "Park", description: "Commit them as wip(<id>): park on this branch; unparked when you come back" },
{ label: "Stay", description: "Skip the switch - keep working on {branch}" }
],
multiSelect: false
}]
)- **Commit first** -> delegate to the commit skill, then the switch below.
- **Park** -> ask which of the listed new paths go into the park commit. `--include` names only the paths the user confirmed; an unconfirmed new path makes the switch refuse (`untracked_present`, nothing touched) - say so, and let the user confirm it or remove it.
- **Stay** -> no switch; warn about mixed work, then Step 5 as in Step 2's Stay.
No changes -> the switch below directly. The switch, from the team worktree:
lets worktree switch --task '<task-id>' --title-file .lets/cache/title-<session6>.txt --plugin-root "${CLAUDE_PLUGIN_ROOT}" --json
# Park: add --park and one --include '<path>' per confirmed new path(The title file is written as in Step 4, with the Write tool.) Render the result:
- `ok=true` -> "Switched to `{branch}`" (`created` -> "cut from `{base}`", with the staleness warning when `base_stale`); `park` -> name the park commit; `unpark` -> `unparked` (the parked changes are staged again), `parked_pushed` / `parked_unverified` / `parked_kept` (the park stays a commit - say why).
- Every `warn` step in `step
Read more
name: take-task description: This skill should be used when claiming a task to work on - "take task", "візьми таск", "працюю над", "work on task X", "pick task X", "switch to task X", "claim task". Sets task to in_progress, creates/switches branch, saves the per-branch task-state file.
Take Task
Claim a tracker task and prepare the working environment.
> **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.
Why This Exists
Multiple flows need "claim task + prepare branch": /lets:start, mid-session task switch, direct "візьми таск X". Centralizing ensures consistent branch naming, worktree handling, and session ref saving.
Flow
Step 1: Resolve Task
**Tracker protocol:** `Skill(skill: "lets:protocol-tracker")` before this and any later `lets-tracker` block here, unless its text is in your current context.
show task=<task-id>
Verify task exists. Then claim it (set-status is a state change - HARD-FAIL loud if the binding can't run; do NOT proceed to branch setup on a failed claim):
set-status task=<task-id> status=in_progress
Step 2: Check Uncommitted Changes
**Team worktree** - `lets worktree info --json` reports a top-level `team`: this worktree belongs to a standing team and moves between tasks through `lets worktree switch`. Skip the generic question below and go to **Step 2T**. No `team` -> continue here.
Before switching branches, check for uncommitted changes:
git status --short
If changes exist and branch switch is needed, ask user:
AskUserQuestion(
questions=[{
question: "Uncommitted changes on current branch. What to do?",
header: "Uncommitted",
options: [
{ label: "Stash", description: "git stash, switch branch, remind to pop later" },
{ label: "Commit first", description: "Commit changes, then switch branch" },
{ label: "Stay", description: "Skip branch switch - work on current branch" }
],
multiSelect: false
}]
)Handle response:
- **Stash** -> `git stash`, proceed with branch switch, remind to `git stash pop` later
- **Commit first** -> delegate to commit skill, then proceed with branch switch
- **Stay** -> skip branch switch, warn about mixed work, then continue to Step 5 (the task was already claimed in Step 1 - save its `.task` state file for the current branch; do NOT stop before it, or detect-task/`/lets:done` are left with a claim but no boundary file).
If staying on current branch (worktree, already correct) or no changes - skip this step.
Step 2T: Team worktree - park, then switch
**Busy writer first.** Before anything else, run `ListAgents`. A busy agent of THIS session that writes in this tree stops the switch: a group agent of `.lets/cache/delegated-run-*.json` with `isolation: null` listed `running`, or a `Member:` id of this lead session in the team file that `ListAgents` lists `running` and whose spawn brief `.lets/cache/member-<team>-<name>.md` ("You are <name> (lets:<role>) of team <c>") names `lets:implementer` - every team agent is classified by its spawn brief, never by the roster (`/lets:team spawn` may run any role under any name); a brief that is missing, unreadable or names no role counts as a writer, never as read-only -> stop: "`{name}` is still working in this tree - wait for its report, or stop it (`/lets:team dismiss <name>`, or the run's Stop), then `/lets:start` again"; nothing is switched. A brief naming any other role is read-only. The same agent idle -> one line "`{name}` is idle and keeps `{branch}`'s context - dismiss it before its next brief", continue. Isolated implementers and read-only roles never block.
Read `${CLAUDE_PLUGIN_ROOT}/protocol/worktrees.md` before this step unless its text is in your current context (standing-team worktree, park never stash).
A team worktree never stashes. `git status --short`; changes present -> list them, and list separately every NEW path a park would need to name - untracked (`git ls-files --others --exclude-standard`) and staged additions (`git diff --cached --diff-filter=ACR --name-only HEAD`). Ignored files are never parked; they stay on disk. Then:
AskUserQuestion(
questions=[{
question: "Uncommitted changes on {branch} before switching to {task-id}. What to do?",
header: "Uncommitted",
options: [
{ label: "Commit first", description: "Commit them with /lets:commit, then switch" },
{ label: "Park", description: "Commit them as wip(<id>): park on this branch; unparked when you come back" },
{ label: "Stay", description: "Skip the switch - keep working on {branch}" }
],
multiSelect: false
}]
)- **Commit first** -> delegate to the commit skill, then the switch below.
- **Park** -> ask which of the listed new paths go into the park commit. `--include` names only the paths the user confirmed; an unconfirmed new path makes the switch refuse (`untracked_present`, nothing touched) - say so, and let the user confirm it or remove it.
- **Stay** -> no switch; warn about mixed work, then Step 5 as in Step 2's Stay.
No changes -> the switch below directly. The switch, from the team worktree:
lets worktree switch --task '<task-id>' --title-file .lets/cache/title-<session6>.txt --plugin-root "${CLAUDE_PLUGIN_ROOT}" --json
# Park: add --park and one --include '<path>' per confirmed new path(The title file is written as in Step 4, with the Write tool.) Render the result:
- `ok=true` -> "Switched to `{branch}`" (`created` -> "cut from `{base}`", with the staleness warning when `base_stale`); `park` -> name the park commit; `unpark` -> `unparked` (the parked changes are staged again), `parked_pushed` / `parked_unverified` / `parked_kept` (the park stays a commit - say why).
- Every `warn` step in `step
A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.
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…
loop-bb-pr
Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state changes, merge, decline) via the bb-api…
loop-gh-pr
Compose a /loop that watches all open GitHub PRs for activity (new PRs, new commits, new comments) and auto-prepares a READ-ONLY…
loop-test
Local sandbox for experimenting with Claude Code's /loop command (interval + dynamic/self-paced scheduling) applied to LETS…
actor-fetch-personalit…
Internal skill for commands. Fetch and validate personality from URL or file path for Actor agent. Do not trigger on user…
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about take-task.
- Which coding agents can use take-task?
- take-task installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

