From task-workflow
Executes eligible tasks from session task list, syncs against codebase/PR state to surface stales, and generates handovers. Use /task-run [--all] [--sync [--dry-run]] [--handover [query]].
npx claudepluginhub jongwony/claudepanel.spoon --plugin task-workflowThis skill uses the workspace's default tool permissions.
Execute, sync, or hand over tasks from the current task list.
Manages tasks using Claude Code's native Task tools (TaskCreate, TaskList) for TODO tracking, progress checkpointing via git commits, and resuming work across sessions. Auto-activates on 'add to todos' or 'resume tasks'.
Resumes unfinished human-in-the-loop work like handovers, incomplete grills, and mid-draft tasks from GitHub issues using /pickup command.
Executes pending Claude Code Tasks in dependency order with wave-based concurrent execution, adaptive verification, retries, task group filtering, and configurable parallelism.
Share bugs, ideas, or general feedback.
Execute, sync, or hand over tasks from the current task list.
Unified task lifecycle management:
$ARGUMENTS: Mode selector and optional context.
--all: Batch mode with pre-flight sync. Execute all eligible tasks sequentially.--sync: Sync-only mode. Reconcile task list, no execution. Accepts --dry-run sub-flag.--handover [query]: Handover mode. Collect state and compose entry prompt. Optional query filters scope./task-run --all static verification).Parse $ARGUMENTS:
--handover is present → handover mode. Text after --handover is the optional query.--sync is present → sync-only mode. Check for --dry-run sub-flag.--all is present → batch mode with pre-flight sync.A task is eligible (Ready) when ALL conditions are met:
status is pendingblockedBy is empty (no unresolved dependencies)owner is empty or matches the current agentA task is skipped when ANY condition is true:
status is not pending (already in_progress or completed)blockedBy is non-empty (blocked by other tasks)owner is set to a different agent**Source Session**: pattern (handoff task — must be executed in target project)## Handover pattern (handover task — informational context for next session, not executable)Note: In --all mode, the pre-flight sync may auto-complete handover/pr-linked tasks before the eligibility check runs, reducing the skip list.
Used by both --all pre-flight and --sync modes. Classify each pending task by source type using a two-pass approach.
Note: This skill uses the TaskGet API which does not expose metadata fields. Classification relies on description patterns and subject heuristics.
Pass 1 — Subject-based pre-classification:
Handover: → handover typePR # or pr: → likely pr-linked typeunknown (needs TaskGet)Note: Handoff tasks cannot be reliably classified from subject alone (task-save generates imperative verb phrase subjects). Handoff classification happens exclusively in Pass 2.
Pass 2 — Description-based confirmation (only for unknown tasks from Pass 1):
Call TaskGet for each unknown task and classify by description patterns:
## Handover → handover**Source Session**: → handoff (skip — must be in target project)pr: AND checkbox_text: → pr-linkedgeneralTaskGet fails for a task (deleted, transient error): classify as uncertain and include the error in the sync reportThis deferred N+1 approach minimizes TaskGet calls for well-named tasks.
TaskList to get all tasks.AskUserQuestion:
[ID] subject as label, description snippet as description/task-run --all)Before batch execution, run a lightweight sync to clear stale tasks:
TaskList. Filter to status=pending tasks.gh pr list --state all --json number,state --limit 100. Match pr-linked tasks against PR state. Mark merged/closed as likely-completed. If gh is not installed or fails, skip gracefully (mark as uncertain).## Pre-flight Sync
### PR-linked (N)
**Likely completed** (merged/closed):
- [ID] subject — PR #X MERGED
**Still relevant** (open):
- [ID] subject — PR #X OPEN
### Handover (N)
- [ID] subject — [status note]
### General (N)
- [ID] subject
### Handoff (N) — skipped (uses CLAUDE_CODE_TASK_LIST_ID path)
- [ID] subject
Omit empty sections. Do NOT surface handoff tasks for action — they use the CLAUDE_CODE_TASK_LIST_ID path in their target project.
TaskUpdate(taskId, status="completed"). Independent TaskUpdate calls can be made in parallel.TaskList to refresh state (earlier tasks may unblock later ones).For each task to execute (used by both interactive and batch modes):
TaskUpdate(taskId, status="in_progress") with activeForm from TaskGet.TaskGet(taskId) to get full description and requirements.TaskUpdate(taskId, status="completed") when work is done./task-run --sync)Reconcile the current task list against codebase state. No task execution.
Call TaskList to get all tasks. Collect task summaries (id, subject, status, blockedBy).
Guard: If total tasks exceed 50, warn the user and ask whether to proceed or filter by status.
Filter to status=pending tasks only. If none exist, report "No pending tasks to sync" and stop.
Apply the Source Classification procedure (see above).
For each source type, apply the appropriate comparison method:
gh pr list --state all --json number,state --limit 100
Same command as Pre-flight Sync step 3 — classification rules are shared.
MERGED or CLOSED.OPEN.gh is not installed or fails: skip PR comparison, mark all as uncertain with note.Parse the task description for checklist items (- [ ] / - [x] patterns).
For each unchecked item, search for evidence:
git log --oneline -20 --grep="<keyword>"
And/or use Grep to search for relevant code changes.
Infer target directory from the task description context or subject. Note: target_cwd is stored in task metadata which is not accessible via TaskGet. The **Source Session**: endnote contains the source session UUID, not the target path. If the target cannot be inferred, ask the user or mark as uncertain.
If target_cwd is accessible:
git -C <target_cwd> log --oneline -5
Search for evidence using the task subject keywords:
git log --oneline -20 --grep="<keyword>"
And use Grep to search for related code changes.
Identify stale dependencies — where a blocking task is already completed:
blockedBy:
completed → mark dependency as staleNote: Report only — the TaskUpdate API only supports addBlockedBy (no remove). TaskList auto-filters completed blockers at runtime, so stale dependencies are cosmetic.
Present results grouped by source type, then by relevance:
## Task Sync Report
### PR-linked (N)
**Likely completed** (merged/closed):
- [ID] subject — PR #X MERGED
**Still relevant** (open):
- [ID] subject — PR #X OPEN
### Handover (N)
**Likely completed**:
- [ID] subject — all checklist items addressed
**Still relevant**:
- [ID] subject — 2/5 items remaining
### Handoff (N)
**Likely completed**:
- [ID] subject → /path/to/target — related commits found
**Uncertain**:
- [ID] subject → /path/to/target — target not accessible
### General (N)
**Likely completed**:
- [ID] subject — matching commits found
**Still relevant**:
- [ID] subject — no evidence found
### Stale Dependencies (N)
- [ID] subject — stale blockedBy: [ID_completed] (blocking task completed)
- [ID] subject — fully unblocked (all blockers completed)
Omit empty sections. Show task count per group.
--dry-run)likely-completed task: TaskUpdate(taskId, status="completed"). Independent calls can be made in parallel.uncertain tasks: keep as pending. Display with "(flagged by sync)" annotation in the report only — do not modify the task description.still-relevant tasks: no action.## Sync Summary
- Completed: N tasks
- Flagged (uncertain): N tasks
- Unchanged (still relevant): N tasks
- Stale dependencies: N (auto-filtered by TaskList)
--sync --dry-run)/task-run --handover [query])Prepare a structured handover for the next Claude Code session by collecting current work state, letting the user select what to transfer, and saving as a TaskCreate entry.
Issue initial calls in parallel: TaskList, git/PR state (Bash). Session context analysis requires no tool call.
TaskList to get task summaries. Count non-completed tasks and note their subjects. Do NOT call TaskGet yet — defer to Step 3.BRANCH=$(git branch --show-current) && git status -sb && gh pr list --state open --head "$BRANCH" --json number,title,url,body
Extract: branch name, working tree status, open PR info (number, title, unchecked - [ ] items).If $ARGUMENTS query is provided after --handover, filter tasks by subject keyword match from TaskList summaries before counting. Scope session context analysis to the specified topic.
Call AskUserQuestion with multiSelect: true to present the collected data.
Present only options where data was actually collected (skip empty sources):
Which information should be included in the handover?
Options (select all that apply):
1. Incomplete Tasks (N items) — [top 3 task subjects]
2. Session Context — [1-line summary of decisions/discoveries]
3. PR State — PR #N: [title], [M unchecked items]
4. Git State — branch: [name], [clean/dirty]
Option rules:
Fetch details for selected components: If "Incomplete Tasks" was selected, now call TaskGet for each non-completed task to retrieve descriptions (Current Status / Next Steps). This defers the N+1 cost to only when needed.
Compose the handover entry prompt from selected components. Use this template:
## Handover
### Incomplete Tasks
- [ ] [task subject]
- Current Status: [status from task description]
- Next Steps: [steps from task description]
- PR: #[number] (if linked)
### Session Context
- Decisions: [key decisions]
- Discoveries: [findings]
- Blocked: [blockers or open questions]
### Git State
- Branch: [current branch]
- Working tree: [clean/uncommitted changes summary]
### PR State
- PR: #[number] [title] ([M unchecked items])
### Priority
1. [highest priority item]
2. [next priority item]
Composition rules:
- [ ]) for actionable itemsAppend a source session endnote to the composed description:
---
**Handover Source**: `<source_session_id>`
To retrieve context from the originating session: `find ~/.claude/projects/ -name "<source_session_id>.jsonl"`
Obtaining source_session_id: Run ls -t ~/.claude/projects/*/*.jsonl | head -1 and extract the UUID filename (without .jsonl extension). Run immediately before TaskCreate.
Create a single TaskCreate with:
| Field | Format |
|---|---|
| subject | Handover: [1-line summary of primary work] |
| description | Entry prompt composed in Step 3 + source session endnote |
| activeForm | Handover ready for next session |
| metadata | {"source": "handover", "topic": "...", "source_session_id": "..."} |
{
"source": "handover",
"topic": "[primary topic or query value]",
"source_session_id": "[current session UUID]"
}
After TaskCreate, output resume instructions:
echo "${CLAUDE_CODE_TASK_LIST_ID:-}" to check for a named list.source_session_id from Step 4 as the task list ID:
CLAUDE_CODE_TASK_LIST_ID=<source_session_id> claude
Note: UUID-based task directories are cleaned up at session end.Track consecutiveFailures counter (starts at 0):
in_progress.AskUserQuestion whether to continue, skip, or stop.A task "fails" when:
Display a summary when --all mode completes or when 2+ tasks were executed:
## Task Run Summary
- Completed: N
- Failed (in_progress): N
- Skipped: N
- Remaining pending: N
pr: and checkbox_text:), update the PR checkbox after completion per PR-Task Sync rules.gh gracefully if not installed (mark PR-related items as uncertain).TaskUpdate with addBlockedBy to manage dependencies.--sync --dry-run mode, perform all comparisons but make zero mutations.