# Droploft Tasks

> Background task runs — list, inspect, retry. Use this to debug async failures from doc +upload, publish, etc.

- Skill: `langgenius/droploft-tasks` (Agent Skill)
- Install (CLI): `npx skillmds@latest add langgenius/droploft-tasks`
- Raw SKILL.md: https://api.skillmd.com/api/skills/langgenius/droploft-tasks/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: langgenius (https://skillmd.com/u/langgenius)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/langgenius/droploft-tasks

---


# Droploft v2 CLI — Tasks Skill

Async work runs as **task runs**. The most common producer is publish/optimize, kicked off by `doc +upload` or `documents publish`. Each row tracks status, attempts, and `error_message`.

## Statuses

`pending` → `running` → `success` | `failed` | `cancelled`

(`success` is the canonical terminal state; v1 spec called it `succeeded` — v2 uses `success`. The CLI accepts both when polling.)

## Layer 2 verbs

```bash
droploft tasks list                          # most recent first
droploft tasks list --format table           # human-readable
droploft tasks get <task-id>                 # one row
droploft tasks retry <task-id>               # re-enqueue a failed task
```

## Patterns

### Fish out the most recent failure

```bash
droploft tasks list --format json --jq '.[] | select(.status=="failed")' | head
```

### Wait for a publish you fired off without `--no-wait`

`doc +upload` polls automatically. If you used `--no-wait`, follow up:

```bash
TASK_ID=$(droploft documents publish <doc-id> --format json --jq '.data.task_id')
while true; do
  STATUS=$(droploft tasks get "$TASK_ID" --format json --jq '.data.status')
  case "$STATUS" in success|failed|cancelled) break;; esac
  sleep 3
done
echo "final: $STATUS"
```

## Errors

- `not_found` (exit 4) — the task belongs to another user, or doesn't exist.
- `tasks retry` on a non-failed row returns 409 conflict.

