Plukker fra tasks/*.md, flytter til active/, done/ ved fullføring. Støtter --loop (kjør kontinuerlig), --dry (forhåndsvis), --status. Krasj-deteksjon: stale oppgaver i active/ >60 min frigjøres. 30 min timeout per oppgave. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
160 lines
4.1 KiB
Bash
Executable file
160 lines
4.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Plukk neste oppgave fra tasks/ og kjør med Claude Code.
|
|
# Bruk:
|
|
# ./scripts/run-next-task.sh # kjør én oppgave
|
|
# ./scripts/run-next-task.sh --loop # kjør oppgaver i loop
|
|
# ./scripts/run-next-task.sh --dry # vis neste uten å kjøre
|
|
# ./scripts/run-next-task.sh --status # vis status
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
TASKS="$ROOT/tasks"
|
|
ACTIVE="$TASKS/active"
|
|
DONE="$TASKS/done"
|
|
LOGS="$ROOT/logs"
|
|
LOCKFILE="/tmp/synops-task-runner.lock"
|
|
|
|
mkdir -p "$ACTIVE" "$DONE" "$LOGS"
|
|
|
|
# Lås — hindrer dobbeltstart
|
|
if [ -f "$LOCKFILE" ]; then
|
|
PID=$(cat "$LOCKFILE" 2>/dev/null || echo "")
|
|
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
|
|
echo "Allerede en task-runner aktiv (PID $PID)"
|
|
exit 0
|
|
fi
|
|
rm -f "$LOCKFILE"
|
|
fi
|
|
echo $$ > "$LOCKFILE"
|
|
trap 'rm -f "$LOCKFILE"' EXIT
|
|
|
|
# --- Krasj-deteksjon: frigjør stale oppgaver ---
|
|
unstale() {
|
|
for f in "$ACTIVE"/*.md; do
|
|
[ -f "$f" ] || continue
|
|
age_min=$(( ($(date +%s) - $(stat -c %Y "$f")) / 60 ))
|
|
if [ "$age_min" -gt 60 ]; then
|
|
echo "Frigjør stale oppgave: $(basename "$f") ($age_min min)"
|
|
mv "$f" "$TASKS/"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# --- Status ---
|
|
if [[ "${1:-}" == "--status" ]]; then
|
|
todo=$(ls "$TASKS"/*.md 2>/dev/null | grep -v README | wc -l)
|
|
active=$(ls "$ACTIVE"/*.md 2>/dev/null | wc -l)
|
|
done_count=$(ls "$DONE"/*.md 2>/dev/null | wc -l)
|
|
echo "=== Synops oppgavestatus ==="
|
|
echo "Gjenstår: $todo"
|
|
echo "Aktiv: $active"
|
|
echo "Fullført: $done_count"
|
|
if [ "$active" -gt 0 ]; then
|
|
echo ""
|
|
echo "--- Aktive ---"
|
|
ls "$ACTIVE"/*.md 2>/dev/null | xargs -I{} basename {}
|
|
fi
|
|
echo ""
|
|
echo "--- Neste 5 ---"
|
|
ls "$TASKS"/*.md 2>/dev/null | grep -v README | sort | head -5 | xargs -I{} basename {}
|
|
exit 0
|
|
fi
|
|
|
|
# --- Kjør én oppgave ---
|
|
run_one() {
|
|
unstale
|
|
|
|
TASK=$(ls "$TASKS"/*.md 2>/dev/null | grep -v README | sort | head -1)
|
|
if [ -z "$TASK" ]; then
|
|
echo "Ingen oppgaver å gjøre"
|
|
return 1
|
|
fi
|
|
|
|
TASKNAME=$(basename "$TASK")
|
|
echo "=== Plukker: $TASKNAME ==="
|
|
|
|
if [[ "${1:-}" == "--dry" ]]; then
|
|
cat "$TASK"
|
|
return 0
|
|
fi
|
|
|
|
# Flytt til active
|
|
mv "$TASK" "$ACTIVE/$TASKNAME"
|
|
|
|
TASK_CONTENT=$(cat "$ACTIVE/$TASKNAME")
|
|
|
|
cd "$ROOT"
|
|
git pull origin main 2>/dev/null || true
|
|
|
|
# Kjør Claude Code
|
|
LOGFILE="$LOGS/task-$(date +%Y%m%d-%H%M)-$TASKNAME.log"
|
|
|
|
timeout 1800 claude -p "
|
|
Du har fått denne oppgaven:
|
|
|
|
$TASK_CONTENT
|
|
|
|
Arbeidsmappe: $ROOT
|
|
|
|
Arbeidsflyt:
|
|
1. Les CLAUDE.md for prosjektkontekst
|
|
2. Les refererte docs/proposals
|
|
3. Implementer
|
|
4. Verifiser (cargo check, npm run build)
|
|
5. Commit og push
|
|
6. Rapporter hva du gjorde
|
|
|
|
Regler:
|
|
- Les relevante filer før du endrer dem
|
|
- Gjør minimale, fokuserte endringer
|
|
- Push jevnlig underveis
|
|
" --dangerously-skip-permissions 2>&1 | tee "$LOGFILE"
|
|
|
|
EXIT_CODE=${PIPESTATUS[0]}
|
|
|
|
if [ "$EXIT_CODE" -eq 0 ]; then
|
|
mv "$ACTIVE/$TASKNAME" "$DONE/$(date +%Y-%m-%d)-$TASKNAME"
|
|
echo "=== Fullført: $TASKNAME ==="
|
|
# Commit task-flytt
|
|
cd "$ROOT"
|
|
git add -A tasks/ && git commit -m "Task fullført: $TASKNAME" --no-verify 2>/dev/null || true
|
|
git push origin main 2>/dev/null || true
|
|
return 0
|
|
else
|
|
mv "$ACTIVE/$TASKNAME" "$TASKS/$TASKNAME"
|
|
echo "=== Feilet (exit $EXIT_CODE): $TASKNAME ==="
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# --- Dry run ---
|
|
if [[ "${1:-}" == "--dry" ]]; then
|
|
unstale
|
|
TASK=$(ls "$TASKS"/*.md 2>/dev/null | grep -v README | sort | head -1)
|
|
if [ -z "$TASK" ]; then
|
|
echo "Ingen oppgaver"
|
|
else
|
|
echo "Neste: $(basename "$TASK")"
|
|
echo "---"
|
|
cat "$TASK"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
# --- Loop-modus ---
|
|
if [[ "${1:-}" == "--loop" ]]; then
|
|
echo "=== Task runner loop startet ($(date)) ==="
|
|
while true; do
|
|
if ! run_one; then
|
|
echo "Ingen flere oppgaver eller feil. Venter 5 min..."
|
|
sleep 300
|
|
else
|
|
echo "Venter 30 sek før neste oppgave..."
|
|
sleep 30
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# --- Enkel kjøring ---
|
|
run_one
|