Skill: lightconsen/fullrun (version 1.0.2)

--- name: fullrun description: Automatically execute tasks from checklist.md with state management and scheduled checking trigger: When user says "start execution", "run tasks", "execute checklist" or similar commands --- # Fullrun Skill ## Overview This skill implements a task execution system with the following features: 1. **State Management**: Uses `.claude-status.txt` file to track execution state - `0` = Idle, ready to execute (or file doesn't exist) - `1` = Claude is currently executing tasks - `2` = All tasks completed, monitoring should exit 2. **Task List**: Reads pending tasks from `checklist.md` 3. **Scripts**: Executable scripts in the `scripts/` directory ## Requirements - **jq** - Required for install/uninstall scripts - macOS: `brew install jq` - Linux: `apt install jq` or `yum install jq` ## File Structure ``` project/ ├── SKILL.md # This skill definition file ├── checklist.md # Task list file (create in your project) ├── .claude-status.txt # Execution state file (auto-generated) ├── .fullrun.log # Execution log (auto-generated) ├── .monitor.pid # Monitor process PID (auto-generated) ├── .claude/ │ └── fullrun/ │ └── scripts/ # Installed scripts (auto-generated) │ ├── main.sh # Main entry point │ ├── fullrun.sh # Task execution script │ └── cron-manager.sh # Cron job management script └── scripts/ ├── main.sh # Main entry point (source) ├── fullrun.sh # Task execution script (source) ├── cron-manager.sh # Cron job management script (source) ├── install.sh # Installation script └── uninstall.sh # Uninstallation script ``` ## Usage ### Installation (run once per project) The installer creates project-local configuration in `./.claude/` - no global settings are modified. ```bash # In your project directory, run: ./scripts/install.sh ``` **What the installer does:** 1. Creates `.claude/` directory in your project 2. Copies scripts to `.claude/fullrun/scripts/` 3. Creates or updates `.claude/settings.local.json` with: - Permission rule for project scripts - SessionStart hook for auto-monitoring **Scope:** Configuration is project-local only. Other projects are not affected. ### Uninstall ```bash ./scripts/uninstall.sh ``` This removes: - The `.claude/fullrun/` directory - Fullrun permission rule from `.claude/settings.local.json` - Fullrun hook from SessionStart (preserves other hooks) - `.claude/settings.local.json` if it becomes empty ### Start scheduled monitoring (recommended) ```bash ./.claude/fullrun/scripts/main.sh start ``` ### Manually execute tasks ```bash ./.claude/fullrun/scripts/main.sh run ``` ### Check status ```bash ./.claude/fullrun/scripts/main.sh status ``` ### Stop monitoring ```bash ./.claude/fullrun/scripts/main.sh stop ``` ## Execution Rules 1. If `.claude-status.txt` does not exist or contains `0`, start executing unfinished tasks from `checklist.md` 2. When executing tasks, set `.claude-status.txt` to `1` 3. When all tasks are completed, set `.claude-status.txt` to `2` 4. Scheduled task checks every 1 minute: - If status = `0` or file doesn't exist + pending tasks = start execution - If status = `1` = Claude is running, continue waiting - If status = `2` = All tasks completed, exit monitoring 5. Monitoring automatically exits when all tasks are completed (status=2) ## Task Marking Format In `checklist.md`, tasks use the following format: - `[ ]` indicates incomplete - `[x]` indicates completed Example: ```markdown # Checklist - [ ] Task 1: Complete a feature - [ ] Task 2: Write tests - [x] Task 3: Completed task ``` ## Notes - Scheduled monitoring is session-level, stops when the current terminal session ends - For persistent monitoring, use system cron or launchd - The SessionStart hook checks for `checklist.md` in the current working directory at runtime - Configuration is project-local via `.claude/settings.local.json` ## Security Notes **What this skill accesses:** - Reads `checklist.md` in your current project directory - Creates/reads `.claude-status.txt` in your current project directory - Writes execution log to `.fullrun.log` - Does NOT access the internet - Does NOT request or transmit credentials **What the installer modifies:** - `.claude/settings.local.json` - Project-local settings (gitignored) - `.claude/fullrun/scripts/` - Project-local scripts **Persistence:** - The SessionStart hook runs at the start of each Claude Code session in this project - It only starts monitoring if `checklist.md` exists and no execution is in progress - Uninstall removes all modifications in the project ## How Task Execution Works 1. The shell scripts (`fullrun.sh`, `cron-manager.sh`) handle: - State management (`.claude-status.txt`) - Task queue management (reading `checklist.md`) - Logging (`.fullrun.log`) - Marking tasks as complete 2. **Task execution is delegated to Claude Code**: - When a task is started, it outputs the task description - Claude Code reads the task and executes the appropriate commands - This design allows for complex, multi-step tasks that require AI reasoning ## Cross-Platform Compatibility - **macOS**: Fully supported - **Linux**: Fully supported - **Windows**: Requires WSL or Git Bash The scripts use `awk` for text processing to ensure consistent behavior across all platforms.

path: README.md
content: # Fullrun - Task Executor

A script system that automatically executes task checklists with state management and scheduled checking.

## Requirements

- **jq** - Required for install/uninstall scripts
  - macOS: `brew install jq`
  - Linux: `apt install jq` or `yum install jq`

## Quick Start

```bash
# Install in project (run once per project)
./scripts/install.sh

# Start scheduled monitoring (recommended)
./.claude/fullrun/scripts/main.sh start

# Check status
./.claude/fullrun/scripts/main.sh status

# Manually execute tasks
./.claude/fullrun/scripts/main.sh run

# Stop monitoring
./.claude/fullrun/scripts/main.sh stop

# Uninstall
./scripts/uninstall.sh
```

## How It Works

1. System reads tasks from `checklist.md`
2. Checks `.claude-status.txt` to determine if execution is in progress
3. If there are pending tasks and currently idle, starts execution
4. Automatically checks every minute for resume capability
5. Task execution is delegated to Claude Code for intelligent task handling

## Task File Format

Edit `checklist.md` to add your tasks:

```markdown
# Checklist

- [ ] Task 1: Description
- [ ] Task 2: Description
```

The system automatically marks completed tasks as `[x]`.

## Files

| File | Description |
|------|-------------|
| `checklist.md` | Task list |
| `.claude-status.txt` | Execution state (0=idle, 1=running, 2=completed) |
| `.fullrun.log` | Execution log |
| `.claude/settings.local.json` | Project-local Claude configuration |
| `.claude/fullrun/scripts/` | Installed scripts |
| `scripts/main.sh` | Main entry script |

## Use Cases

- Automated build/test task execution
- Resume-capable batch processing
- Scheduled tasks with state recovery
- CI/CD pipeline task management

## Cross-Platform Support

- macOS: Fully supported
- Linux: Fully supported
- Windows: Requires WSL or Git Bash


path: checklist.md
content: # Checklist

- [ ] Task 1: Example task
- [ ] Task 2: Example task
- [ ] Task 3: Example task


path: CLAUDE.md
content: # Fullrun - Task Executor

## Usage

Run the following command to execute tasks:

```bash
# Check status and run tasks if idle
./scripts/main.sh run

# Or start the background monitor (checks every minute)
./scripts/main.sh start
```

## Files

- `checklist.md` - Task list (edit to add tasks)
- `.claude-status.txt` - Execution state (1=running, 0=idle)
- `scripts/main.sh` - Main entry point

## Commands

| Command | Description |
|---------|-------------|
| `./scripts/main.sh start` | Start background monitor |
| `./scripts/main.sh stop` | Stop background monitor |
| `./scripts/main.sh run` | Run tasks once |
| `./scripts/main.sh status` | Show current status |


path: scripts/uninstall.sh
content: #!/bin/bash

# Fullrun - Uninstall Script
# Removes fullrun skill configuration from the current project

set -e

PROJECT_CLAUDE_DIR="$(pwd)/.claude"
PROJECT_SETTINGS="$PROJECT_CLAUDE_DIR/settings.local.json"

echo "=== Fullrun Skill - Project Uninstall ==="
echo ""

# Check if settings file exists
if [ ! -f "$PROJECT_SETTINGS" ]; then
    echo "No project settings file found: $PROJECT_SETTINGS"
    echo "Nothing to uninstall"
    exit 0
fi

# Check if jq is available
if ! command -v jq &> /dev/null; then
    echo "Error: jq is required but not installed."
    echo "Install with: brew install jq"
    exit 1
fi

# Step 1: Remove fullrun permissions
echo "[1/3] Removing permissions..."
project_script_pattern="Bash($(pwd)/.claude/fullrun/scripts/*.sh)"
before_count=$(jq '.permissions.allow // [] | length' "$PROJECT_SETTINGS" 2>/dev/null || echo "0")
jq --arg pattern "$project_script_pattern" '.permissions.allow = (.permissions.allow // [] | map(select(. != $pattern)))' "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"
after_count=$(jq '.permissions.allow // [] | length' "$PROJECT_SETTINGS" 2>/dev/null || echo "0")
removed=$((before_count - after_count))
if [ "$removed" -gt 0 ]; then
    echo "      Removed $removed permission rule(s)"
else
    echo "      No permissions to remove"
fi

# Step 2: Remove fullrun hook from SessionStart
echo "[2/3] Removing SessionStart hook..."
has_session_start=$(jq 'has("hooks") and (.hooks | has("SessionStart"))' "$PROJECT_SETTINGS" 2>/dev/null || echo "false")

if [ "$has_session_start" = "true" ]; then
    # Filter out only the fullrun hook by name, preserve others
    jq '.hooks.SessionStart = (.hooks.SessionStart // [] | map(select(.name != "fullrun-auto-monitor")))' "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
    mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"

    # Check if SessionStart is now empty, if so remove the key entirely
    remaining_count=$(jq '.hooks.SessionStart | length' "$PROJECT_SETTINGS" 2>/dev/null || echo "0")
    if [ "$remaining_count" = "0" ]; then
        jq 'del(.hooks.SessionStart)' "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
        mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"
        echo "      Removed empty SessionStart section"
    else
        echo "      Removed fullrun hook, $remaining_count other hook(s) preserved"
    fi
else
    echo "      No SessionStart hooks found, skipping"
fi

# Validate JSON
if ! jq empty "$PROJECT_SETTINGS" 2>/dev/null; then
    echo "Error: Invalid JSON in $PROJECT_SETTINGS"
    exit 1
fi
echo "      JSON validation passed"

# Step 3: Remove installed files
echo "[3/3] Removing installed files..."

if [ -d "$PROJECT_CLAUDE_DIR/fullrun" ]; then
    rm -rf "$PROJECT_CLAUDE_DIR/fullrun"
    echo "      Removed: $PROJECT_CLAUDE_DIR/fullrun"
else
    echo "      Skipped: $PROJECT_CLAUDE_DIR/fullrun (not found)"
fi

# Clean up settings.local.json if it's empty or has only empty sections
# Check if permissions.allow is empty and hooks is empty or missing
is_empty=$(jq '((.permissions.allow // []) | length) == 0 and ((.hooks.SessionStart // []) | length) == 0' "$PROJECT_SETTINGS" 2>/dev/null || echo "false")
if [ "$is_empty" = "true" ]; then
    rm "$PROJECT_SETTINGS"
    echo "      Removed empty settings file: $PROJECT_SETTINGS"
fi

echo ""
echo "=== Uninstall Complete ==="
echo ""
echo "Project directory: $(pwd)"
echo "Settings file: $PROJECT_SETTINGS"
echo ""
echo "To reinstall, run: ./scripts/install.sh"
echo ""


path: scripts/main.sh
content: #!/bin/bash

# Fullrun - Main Entry Point

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

case "${1:-help}" in
    start)
        "$SCRIPT_DIR/cron-manager.sh" start
        ;;
    stop)
        "$SCRIPT_DIR/cron-manager.sh" stop
        ;;
    run)
        "$SCRIPT_DIR/fullrun.sh" run
        ;;
    status)
        echo "=== Task Execution Status ==="
        "$SCRIPT_DIR/fullrun.sh" check
        echo ""
        echo "=== Monitor Status ==="
        "$SCRIPT_DIR/cron-manager.sh" status
        ;;
    help|*)
        echo "Fullrun - Task Executor"
        echo ""
        echo "Usage: $0 {start|stop|run|status}"
        echo ""
        echo "Commands:"
        echo "  start  - Start scheduled monitoring (checks every minute)"
        echo "  stop   - Stop scheduled monitoring"
        echo "  run    - Execute tasks once"
        echo "  status - Check current status"
        ;;
esac


path: scripts/install.sh
content: #!/bin/bash

# Fullrun - Install Script
# Sets up fullrun skill in the current project directory

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FULLRUN_DIR="$(dirname "$SCRIPT_DIR")"
PROJECT_CLAUDE_DIR="$(pwd)/.claude"
PROJECT_SETTINGS="$PROJECT_CLAUDE_DIR/settings.local.json"

echo "=== Fullrun Skill - Project Setup ==="
echo ""

# Check if jq is available
if ! command -v jq &> /dev/null; then
    echo "Error: jq is required but not installed."
    echo "Install with: brew install jq"
    exit 1
fi

# Create .claude directory in project
echo "[1/4] Creating .claude directory in project..."
mkdir -p "$PROJECT_CLAUDE_DIR"

# Create symlink to scripts or copy them
echo "[2/4] Setting up scripts..."
if [ -d "$PROJECT_CLAUDE_DIR/fullrun" ]; then
    echo "      Project scripts already exist, skipping"
else
    mkdir -p "$PROJECT_CLAUDE_DIR/fullrun/scripts"
    cp "$FULLRUN_DIR/scripts/main.sh" "$PROJECT_CLAUDE_DIR/fullrun/scripts/"
    cp "$FULLRUN_DIR/scripts/fullrun.sh" "$PROJECT_CLAUDE_DIR/fullrun/scripts/"
    cp "$FULLRUN_DIR/scripts/cron-manager.sh" "$PROJECT_CLAUDE_DIR/fullrun/scripts/"
    chmod +x "$PROJECT_CLAUDE_DIR/fullrun/scripts"/*.sh
    echo "      Copied scripts to: $PROJECT_CLAUDE_DIR/fullrun/scripts/"
fi

# Create or update project settings.local.json
echo "[3/4] Configuring project settings..."

# Create settings.local.json if it doesn't exist
if [ ! -f "$PROJECT_SETTINGS" ]; then
    echo '{}' > "$PROJECT_SETTINGS"
    echo "      Created: $PROJECT_SETTINGS"
else
    echo "      Found existing: $PROJECT_SETTINGS"
fi

# Add permissions for project scripts
current_allow=$(jq -r '.permissions.allow // [] | .[]' "$PROJECT_SETTINGS" 2>/dev/null || echo "")
project_script_pattern="Bash($PROJECT_CLAUDE_DIR/fullrun/scripts/*.sh)"

if ! echo "$current_allow" | grep -qF "$project_script_pattern"; then
    jq --arg pattern "$project_script_pattern" '.permissions.allow += [$pattern]' "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
    mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"
    echo "      Added permission: $project_script_pattern"
else
    echo "      Permission already exists, skipping"
fi

# Add SessionStart hook for auto-monitoring
# The hook checks for checklist.md and .claude-status.txt in current directory at runtime
# Build hook JSON using jq to ensure proper escaping
HOOK_NAME="fullrun-auto-monitor"
HOOK_COMMAND="if [ -f \"\$(pwd)/checklist.md\" ] && [ ! -f \"\$(pwd)/.claude-status.txt\" ]; then echo \"Starting fullrun monitoring...\" && $PROJECT_CLAUDE_DIR/fullrun/scripts/main.sh start 2>/dev/null || true; fi"

has_session_start=$(jq 'has("hooks") and (.hooks | has("SessionStart"))' "$PROJECT_SETTINGS" 2>/dev/null || echo "false")
has_fullrun_hook=$(jq --arg name "$HOOK_NAME" '.hooks.SessionStart // [] | map(.name // "") | index($name) != null' "$PROJECT_SETTINGS" 2>/dev/null || echo "false")

if [ "$has_fullrun_hook" = "true" ]; then
    echo "      Fullrun hook already exists, skipping"
elif [ "$has_session_start" = "true" ] && [ "$(jq '.hooks.SessionStart | length' "$PROJECT_SETTINGS" 2>/dev/null)" -gt 0 ]; then
    # Append to existing SessionStart
    jq --arg name "$HOOK_NAME" --arg cmd "$HOOK_COMMAND" \
       '.hooks.SessionStart += [{"name": $name, "hooks": [{"type": "command", "command": $cmd, "timeout": 10, "statusMessage": "Initializing fullrun task executor"}]}]' \
       "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
    mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"
    echo "      Appended hook to existing SessionStart"
else
    # Create new SessionStart array
    jq --arg name "$HOOK_NAME" --arg cmd "$HOOK_COMMAND" \
       '.hooks.SessionStart = [{"name": $name, "hooks": [{"type": "command", "command": $cmd, "timeout": 10, "statusMessage": "Initializing fullrun task executor"}]}]' \
       "$PROJECT_SETTINGS" > "$PROJECT_SETTINGS.tmp" && \
    mv "$PROJECT_SETTINGS.tmp" "$PROJECT_SETTINGS"
    echo "      Created SessionStart with hook"
fi

# Validate JSON
echo "[4/4] Validating settings..."
if ! jq empty "$PROJECT_SETTINGS" 2>/dev/null; then
    echo "Error: Invalid JSON in $PROJECT_SETTINGS"
    exit 1
fi
echo "      JSON validation passed"

echo ""
echo "=== Project Setup Complete ==="
echo ""
echo "Project directory: $(pwd)"
echo "Settings file: $PROJECT_SETTINGS"
echo "Scripts directory: $PROJECT_CLAUDE_DIR/fullrun/scripts/"
echo ""
echo "Usage in this project:"
echo "  /fullrun - Start task execution"
echo "  ./.claude/fullrun/scripts/main.sh start - Start background monitoring"
echo "  ./.claude/fullrun/scripts/main.sh status - Check status"
echo ""
echo "To uninstall from this project, run: ./scripts/uninstall.sh"
echo ""


path: scripts/cron-manager.sh
content: #!/bin/bash

# Cron Job Manager for Fullrun
# Manages scheduled task checking

# Use current working directory as project root
WORKDIR="$(pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

STATUS_FILE="$WORKDIR/.claude-status.txt"
CHECKLIST_FILE="$WORKDIR/checklist.md"
LOG_FILE="$WORKDIR/.fullrun.log"
PID_FILE="$WORKDIR/.monitor.pid"

# Status values:
# 0 = idle, ready to execute
# 1 = claude is running/executing tasks
# 2 = all tasks completed, monitoring should exit

has_pending_tasks() {
    if [ ! -f "$CHECKLIST_FILE" ]; then
        echo "false"
        return
    fi
    if grep -q '\[ \]' "$CHECKLIST_FILE"; then
        echo "true"
    else
        echo "false"
    fi
}

get_status() {
    if [ ! -f "$STATUS_FILE" ]; then
        echo "0"
    else
        cat "$STATUS_FILE"
    fi
}

start_monitor() {
    echo "Starting scheduled monitoring..."
    (
        while true; do
            sleep 60

            status=$(get_status)
            pending=$(has_pending_tasks)

            echo "[$(date)] Check: status=$status, pending=$pending" >> "$LOG_FILE"

            # Status 2 = all tasks completed, exit monitoring
            if [ "$status" = "2" ]; then
                echo "[$(date)] All tasks completed (status=2), stopping monitoring" >> "$LOG_FILE"
                break
            fi

            # No pending tasks, mark as completed and exit
            if [ "$pending" = "false" ]; then
                echo "2" > "$STATUS_FILE"
                echo "[$(date)] No pending tasks, marking status=2 and stopping" >> "$LOG_FILE"
                break
            fi

            # Status 0 = idle and has pending tasks, start execution
            if [ "$status" = "0" ] && [ "$pending" = "true" ]; then
                echo "[$(date)] Idle state detected (status=0), starting task execution..." >> "$LOG_FILE"
                echo "1" > "$STATUS_FILE"
                "$SCRIPT_DIR/fullrun.sh" run >> "$LOG_FILE" 2>&1
                current_status=$(get_status)
                if [ "$current_status" = "1" ]; then
                    echo "0" > "$STATUS_FILE"
                fi
            fi

        done

        echo "[$(date)] Monitor exited" >> "$LOG_FILE"
    ) &

    echo $! > "$PID_FILE"
    echo "Monitoring started, PID: $(cat $PID_FILE)"
}

stop_monitor() {
    if [ -f "$PID_FILE" ]; then
        pid=$(cat "$PID_FILE")
        if ps -p $pid > /dev/null 2>&1; then
            kill $pid
            echo "Monitoring stopped (PID: $pid)"
        else
            echo "Monitor process does not exist"
        fi
        rm "$PID_FILE"
    else
        echo "No running monitor found"
    fi
}

monitor_status() {
    if [ -f "$PID_FILE" ]; then
        pid=$(cat "$PID_FILE")
        if ps -p $pid > /dev/null 2>&1; then
            status=$(get_status)
            pending=$(has_pending_tasks)
            echo "Monitoring running (PID: $pid)"
            echo "Status: $status (0=idle, 1=running, 2=completed)"
            echo "Pending tasks: $pending"
            return
        fi
    fi
    echo "Monitoring not running"
}

case "${1:-status}" in
    start)
        start_monitor
        ;;
    stop)
        stop_monitor
        ;;
    status)
        monitor_status
        ;;
    restart)
        stop_monitor
        sleep 1
        start_monitor
        ;;
    *)
        echo "Usage: $0 {start|stop|status|restart}"
        exit 1
        ;;
esac


path: scripts/fullrun.sh
content: #!/bin/bash

# Fullrun Script
# Automatically execute tasks from checklist.md with state management and scheduled checking

set -e

# Use current working directory as project root
WORKDIR="$(pwd)"
STATUS_FILE="$WORKDIR/.claude-status.txt"
CHECKLIST_FILE="$WORKDIR/checklist.md"
LOG_FILE="$WORKDIR/.fullrun.log"

# Status values:
# 0 = idle, ready to execute
# 1 = claude is running/executing tasks
# 2 = all tasks completed, monitoring should exit

# Logging function
log() {
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $*" >> "$LOG_FILE"
    echo "$*"
}

# Set status state
# Only allows values 0, 1, or 2
set_status() {
    local new_status="$1"

    # Validate status value - only allow 0, 1, or 2
    if [[ "$new_status" != "0" && "$new_status" != "1" && "$new_status" != "2" ]]; then
        log "ERROR: Invalid status value '$new_status'. Only 0, 1, or 2 are allowed."
        return 1
    fi

    echo "$new_status" > "$STATUS_FILE"
    log "Status set to: $new_status"
}

# Get current status
get_status() {
    if [ ! -f "$STATUS_FILE" ]; then
        echo "0"
    else
        cat "$STATUS_FILE"
    fi
}

# Check if there are pending tasks
has_pending_tasks() {
    if [ ! -f "$CHECKLIST_FILE" ]; then
        echo "false"
        return
    fi
    if grep -q '\[ \]' "$CHECKLIST_FILE"; then
        echo "true"
    else
        echo "false"
    fi
}

# Get the first pending task
get_next_task() {
    if [ ! -f "$CHECKLIST_FILE" ]; then
        echo ""
        return
    fi
    grep '\[ \]' "$CHECKLIST_FILE" | head -1 | sed 's/.*\[ \] //'
}

# Mark task as done
# Uses awk to replace the first [ ] with [x]
mark_task_done() {
    local task_line="$1"

    # Use awk for cross-platform compatibility
    # This replaces only the first occurrence of [ ] with [x]
    awk '{if(!done && /\[ \]/){sub(/\[ \]/,"[x]");done=1} print}' "$CHECKLIST_FILE" > "$CHECKLIST_FILE.new" && mv "$CHECKLIST_FILE.new" "$CHECKLIST_FILE"

    log "Marked task as done"
}

# Execute task
# This function logs the task and delegates to Claude for execution.
# The actual command execution is handled by Claude Code based on the task description.
execute_task() {
    local task="$1"
    log "=========================================="
    log "STARTING TASK: $task"
    log "=========================================="

    # Output the task for Claude to execute
    # Claude Code will read this and execute the appropriate commands
    echo ""
    echo ">>> TASK: $task"
    echo ""

    # Note: Task execution is delegated to Claude Code.
    # The task description from checklist.md should describe what needs to be done.
    # Claude will interpret and execute the necessary commands.
}

# Main execution loop
run_tasks() {
    set_status "1"
    log "Starting task execution loop"

    while true; do
        pending=$(has_pending_tasks)
        if [ "$pending" = "false" ]; then
            log "All tasks completed"
            set_status "2"
            break
        fi

        task=$(get_next_task)
        if [ -z "$task" ]; then
            log "No task found, setting status to idle"
            set_status "0"
            break
        fi

        execute_task "$task"
        mark_task_done "$task"
    done

    log "Task execution loop finished"
}

# Command handling
case "${1:-}" in
    status)
        get_status
        ;;
    check)
        status=$(get_status)
        pending=$(has_pending_tasks)
        echo "Status: $status (0=idle, 1=running, 2=completed), Pending tasks: $pending"
        ;;
    run)
        run_tasks
        ;;
    start)
        status=$(get_status)
        pending=$(has_pending_tasks)
        if [ "$status" = "0" ] && [ "$pending" = "true" ]; then
            log "Starting task execution..."
            run_tasks
        elif [ "$status" = "1" ]; then
            echo "Already executing (status=1)"
        elif [ "$status" = "2" ]; then
            echo "All tasks completed (status=2)"
        else
            echo "No pending tasks or unknown status"
        fi
        ;;
    *)
        echo "Usage: $0 {status|check|run|start}"
        exit 1
        ;;
esac


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)