feat: add /laputa-next-task and /laputa-done slash commands, clean CLAUDE.md

This commit is contained in:
lucaronin
2026-03-30 17:28:21 +02:00
parent e7a5ee1cad
commit bb5fa2880f
3 changed files with 73 additions and 64 deletions

View File

@@ -0,0 +1,28 @@
# /laputa-done <task_id>
Mark a Laputa task as done: move to In Review, notify Brian, then self-dispatch the next task.
Run this after Phase 1 (Playwright) and Phase 2 (native app QA) both pass.
## Steps
**1. Move task to In Review**
```bash
curl -s -X POST "https://api.todoist.com/api/v1/tasks/$ARGUMENTS/move" \
-H "Authorization: Bearer $TODOIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{"section_id": "6g3XjX33FF4Vj86M"}'
```
**2. Notify Brian**
```bash
openclaw system event --text "laputa-task-done:$ARGUMENTS" --mode now
```
**3. Pick the next task**
Run `/laputa-next-task` to get the next task and start working on it immediately.
If `/laputa-next-task` returns `NO_TASKS` → exit cleanly. The hourly watchdog will restart you when new tasks arrive.

View File

@@ -0,0 +1,34 @@
# /laputa-next-task
Pick the next Laputa task from Todoist and move it to In Progress.
Priority order: **To Rework** first, then **Open** (sorted by Todoist priority p1→p4).
## Steps
1. Fetch tasks from To Rework (`6g6QqvR9rRpvJWvv`), then Open (`6g3XjWR832hVHhCM`)
2. Sort each section by priority (p1 highest)
3. Take the first available task
4. Move it to In Progress (`6g3XjWjfmJFcGgHM`) via Todoist API:
```bash
curl -s -X POST "https://api.todoist.com/api/v1/tasks/<task_id>/move" \
-H "Authorization: Bearer $TODOIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{"section_id": "6g3XjWjfmJFcGgHM"}'
```
5. Fetch the full task details (description, comments) from Todoist:
```bash
curl -s "https://api.todoist.com/api/v1/tasks/<task_id>" \
-H "Authorization: Bearer $TODOIST_API_KEY"
curl -s "https://api.todoist.com/api/v1/comments?task_id=<task_id>" \
-H "Authorization: Bearer $TODOIST_API_KEY"
```
6. For To Rework tasks: read the ❌ QA failed comment — it tells you exactly what to fix
7. Output: task ID, title, and full description so you can start working immediately
If no tasks are available in either section → output `NO_TASKS` and exit cleanly.

View File

@@ -10,13 +10,11 @@ This is how you pick up and complete a task. Follow this order every time.
### 1a. Pick up a task
Tasks come from Todoist (project `6g3XjQFwv9V8Pxfv`). Priority order:
1. **To Rework** (`6g6QqvR9rRpvJWvv`) — fix failed tasks before starting new ones
2. **Open** (`6g3XjWR832hVHhCM`) — sorted by Todoist priority (p1 → p4)
Run `/laputa-next-task` — it fetches the next task from Todoist (To Rework first, then Open), moves it to In Progress, and returns the full description.
When starting a task:
- Read the task description fully
- For To Rework: read the ❌ QA failed comment — it tells you exactly what to fix
- Read the task description and comments fully
- For To Rework: the ❌ QA failed comment tells you exactly what to fix
- Check `docs/adr/` for relevant architecture decisions before making structural choices
### 1b. Implement
@@ -28,68 +26,17 @@ When starting a task:
### 1c. When done — three mandatory steps
**Step 1: Move task to In Review**
```bash
curl -s -X POST "https://api.todoist.com/api/v1/tasks/<task_id>/move" \
-H "Authorization: Bearer $TODOIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{"section_id": "6g3XjX33FF4Vj86M"}'
**Step 1: Move task to In### 1c. When done
After Phase 1 (Playwright) and Phase 2 (native QA) both pass, run:
```
/laputa-done <task_id>
```
**Step 2: Notify Brian**
```bash
openclaw system event --text "laputa-task-done:<task_id>" --mode now
```
This moves the task to In Review, notifies Brian, and self-dispatches the next task automatically.
**Step 3: Self-dispatch — pick the next task**
Check Todoist for the next task (To Rework first, then Open, sorted by priority). Skip To Rework tasks whose last comment is ❌ with no follow-up human feedback. If a task is available, move it to In Progress (`6g3XjWjfmJFcGgHM`) and start immediately. If nothing is available, exit — the watchdog will restart you.
```python
# Todoist section IDs:
# To Rework: 6g6QqvR9rRpvJWvv | Open: 6g3XjWR832hVHhCM | In Progress: 6g3XjWjfmJFcGgHM
import os, json, urllib.request, sys
token = os.environ["TODOIST_API_KEY"]
def get_tasks(section_id):
req = urllib.request.Request(
f"https://api.todoist.com/api/v1/tasks?project_id=6g3XjQFwv9V8Pxfv&section_id={section_id}",
headers={"Authorization": f"Bearer {token}"}
)
with urllib.request.urlopen(req) as r:
data = json.load(r)
return data if isinstance(data, list) else data.get("results", [])
def get_comments(task_id):
req = urllib.request.Request(
f"https://api.todoist.com/api/v1/comments?task_id={task_id}",
headers={"Authorization": f"Bearer {token}"}
)
with urllib.request.urlopen(req) as r:
data = json.load(r)
return data if isinstance(data, list) else data.get("results", [])
for section_id in ["6g6QqvR9rRpvJWvv", "6g3XjWR832hVHhCM"]:
tasks = sorted(get_tasks(section_id), key=lambda t: t.get("priority", 4), reverse=True)
for task in tasks:
req = urllib.request.Request(
f"https://api.todoist.com/api/v1/tasks/{task['id']}/move",
data=json.dumps({"section_id": "6g3XjWjfmJFcGgHM"}).encode(),
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
method="POST"
)
with urllib.request.urlopen(req) as r:
t = json.load(r)
print(f"Next task: {t['content']} ({t['id']})")
sys.exit(0)
print("NO_TASKS — exiting")
```
### 1d. QA phases
Both phases run **before** you fire the done signal (steps 13 above).
nal (steps 13 above).
**Phase 1 — Playwright (you):**