feat: add deploy skill with build/flash guide and helper scripts
- SKILL.md: full deployment guide covering prerequisites, config, build, flash, verification, OTA, and troubleshooting - deploy.sh: one-command build+flash script with auto port detection - validate.sh: pre-deploy checklist (ESP-IDF, secrets, hardware) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
89
skills/deploy/scripts/deploy.sh
Executable file
89
skills/deploy/scripts/deploy.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
# MimiClaw Quick Deploy Script
|
||||
# Usage: ./skills/deploy/scripts/deploy.sh [port]
|
||||
#
|
||||
# This script handles the full build-flash cycle:
|
||||
# 1. Checks prerequisites
|
||||
# 2. Ensures mimi_secrets.h exists
|
||||
# 3. Builds the firmware
|
||||
# 4. Auto-detects or uses specified serial port
|
||||
# 5. Flashes and opens monitor
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${GREEN}[+]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||
error() { echo -e "${RED}[x]${NC} $*"; exit 1; }
|
||||
|
||||
# Find project root (where this script lives: skills/deploy/scripts/)
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
info "MimiClaw Deploy — project: $PROJECT_ROOT"
|
||||
|
||||
# Check ESP-IDF
|
||||
if ! command -v idf.py &>/dev/null; then
|
||||
error "ESP-IDF not found. Source export.sh first:\n source \$IDF_PATH/export.sh"
|
||||
fi
|
||||
|
||||
IDF_VER=$(idf.py --version 2>&1 | head -1)
|
||||
info "ESP-IDF: $IDF_VER"
|
||||
|
||||
# Check secrets
|
||||
if [ ! -f main/mimi_secrets.h ]; then
|
||||
warn "main/mimi_secrets.h not found — creating from example"
|
||||
cp main/mimi_secrets.h.example main/mimi_secrets.h
|
||||
warn "Edit main/mimi_secrets.h with your credentials, then re-run this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if secrets are configured (WiFi SSID not empty)
|
||||
if grep -q 'MIMI_SECRET_WIFI_SSID.*""' main/mimi_secrets.h; then
|
||||
error "WiFi SSID is empty in main/mimi_secrets.h — edit it first"
|
||||
fi
|
||||
|
||||
# Build
|
||||
info "Building firmware (fullclean)..."
|
||||
idf.py fullclean >/dev/null 2>&1 || true
|
||||
idf.py build 2>&1 | tail -5
|
||||
|
||||
if [ ! -f build/mimiclaw.bin ]; then
|
||||
error "Build failed — check errors above"
|
||||
fi
|
||||
|
||||
BIN_SIZE=$(stat -f%z build/mimiclaw.bin 2>/dev/null || stat -c%s build/mimiclaw.bin 2>/dev/null)
|
||||
info "Firmware built: build/mimiclaw.bin ($(( BIN_SIZE / 1024 )) KB)"
|
||||
|
||||
# Detect serial port
|
||||
PORT="${1:-}"
|
||||
if [ -z "$PORT" ]; then
|
||||
# Auto-detect
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
PORT=$(ls /dev/cu.usbmodem* 2>/dev/null | head -1)
|
||||
else
|
||||
PORT=$(ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null | head -1)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$PORT" ]; then
|
||||
error "No serial port found. Plug in your ESP32-S3 or specify port:\n $0 /dev/cu.usbmodem1101"
|
||||
fi
|
||||
|
||||
info "Serial port: $PORT"
|
||||
|
||||
# Flash
|
||||
info "Flashing..."
|
||||
idf.py -p "$PORT" flash 2>&1 | tail -10
|
||||
|
||||
info "Flash complete!"
|
||||
echo ""
|
||||
info "Opening serial monitor (Ctrl+] to exit)..."
|
||||
echo ""
|
||||
|
||||
idf.py -p "$PORT" monitor
|
||||
106
skills/deploy/scripts/validate.sh
Executable file
106
skills/deploy/scripts/validate.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
# MimiClaw Deployment Validator
|
||||
# Usage: ./skills/deploy/scripts/validate.sh
|
||||
#
|
||||
# Checks that all prerequisites are met before building.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
pass() { echo -e " ${GREEN}✓${NC} $*"; }
|
||||
fail() { echo -e " ${RED}✗${NC} $*"; ERRORS=$((ERRORS + 1)); }
|
||||
warn() { echo -e " ${YELLOW}!${NC} $*"; }
|
||||
|
||||
ERRORS=0
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
echo "MimiClaw Deployment Validator"
|
||||
echo "============================="
|
||||
echo ""
|
||||
|
||||
# 1. ESP-IDF
|
||||
echo "ESP-IDF:"
|
||||
if command -v idf.py &>/dev/null; then
|
||||
VER=$(idf.py --version 2>&1 | head -1)
|
||||
pass "idf.py found: $VER"
|
||||
else
|
||||
fail "idf.py not found — source \$IDF_PATH/export.sh"
|
||||
fi
|
||||
|
||||
# 2. Project files
|
||||
echo "Project:"
|
||||
if [ -f main/mimi_config.h ]; then
|
||||
pass "main/mimi_config.h exists"
|
||||
else
|
||||
fail "main/mimi_config.h missing — wrong directory?"
|
||||
fi
|
||||
|
||||
if [ -f partitions.csv ]; then
|
||||
pass "partitions.csv exists"
|
||||
else
|
||||
fail "partitions.csv missing"
|
||||
fi
|
||||
|
||||
# 3. Secrets
|
||||
echo "Secrets:"
|
||||
if [ -f main/mimi_secrets.h ]; then
|
||||
pass "main/mimi_secrets.h exists"
|
||||
|
||||
# Check individual fields
|
||||
if grep -q 'MIMI_SECRET_WIFI_SSID.*""' main/mimi_secrets.h; then
|
||||
fail "WiFi SSID is empty"
|
||||
else
|
||||
pass "WiFi SSID configured"
|
||||
fi
|
||||
|
||||
if grep -q 'MIMI_SECRET_TG_TOKEN.*""' main/mimi_secrets.h; then
|
||||
fail "Telegram token is empty"
|
||||
else
|
||||
pass "Telegram token configured"
|
||||
fi
|
||||
|
||||
if grep -q 'MIMI_SECRET_API_KEY.*""' main/mimi_secrets.h; then
|
||||
fail "Anthropic API key is empty"
|
||||
else
|
||||
pass "Anthropic API key configured"
|
||||
fi
|
||||
|
||||
if grep -q 'MIMI_SECRET_SEARCH_KEY.*""' main/mimi_secrets.h; then
|
||||
warn "Brave Search key not set (web_search will be unavailable)"
|
||||
else
|
||||
pass "Brave Search key configured"
|
||||
fi
|
||||
else
|
||||
fail "main/mimi_secrets.h missing — run: cp main/mimi_secrets.h.example main/mimi_secrets.h"
|
||||
fi
|
||||
|
||||
# 4. Serial port
|
||||
echo "Hardware:"
|
||||
PORTS=""
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
PORTS=$(ls /dev/cu.usbmodem* 2>/dev/null || true)
|
||||
else
|
||||
PORTS=$(ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
if [ -n "$PORTS" ]; then
|
||||
pass "Serial port found: $(echo "$PORTS" | head -1)"
|
||||
else
|
||||
warn "No ESP32 serial port detected (plug in the board to flash)"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
if [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${GREEN}All checks passed!${NC} Ready to build and flash."
|
||||
echo " Run: ./skills/deploy/scripts/deploy.sh"
|
||||
else
|
||||
echo -e "${RED}$ERRORS issue(s) found.${NC} Fix them before deploying."
|
||||
fi
|
||||
Reference in New Issue
Block a user