diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..3f55b2f
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,25 @@
+name: Build
+
+on:
+ push:
+ branches:
+ - '**'
+ pull_request:
+
+jobs:
+ idf-build:
+ runs-on: ubuntu-latest
+ container:
+ image: espressif/idf:v5.5.2
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Build firmware (ESP32-S3)
+ shell: bash
+ run: |
+ . "$IDF_PATH/export.sh"
+ idf.py set-target esp32s3
+ idf.py fullclean
+ idf.py build
diff --git a/README.md b/README.md
index 18e81df..63a8776 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,65 @@ cd mimiclaw
idf.py set-target esp32s3
```
+
+Ubuntu Install
+
+Recommended baseline:
+
+- Ubuntu 22.04/24.04
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb-1.0-0`, `libffi-dev`, `libssl-dev`
+
+Install and build on Ubuntu:
+
+```bash
+sudo apt-get update
+sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \
+ cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
+
+./scripts/setup_idf_ubuntu.sh
+./scripts/build_ubuntu.sh
+```
+
+
+
+
+macOS Install
+
+Recommended baseline:
+
+- macOS 12/13/14
+- Xcode Command Line Tools
+- Homebrew
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb`, `libffi`, `openssl`
+
+Install and build on macOS:
+
+```bash
+xcode-select --install
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+./scripts/setup_idf_macos.sh
+./scripts/build_macos.sh
+```
+
+
+
### Configure
MimiClaw uses a **two-layer config** system: build-time defaults in `mimi_secrets.h`, with runtime overrides via the serial CLI. CLI values are stored in NVS flash and take priority over build-time values.
diff --git a/README_CN.md b/README_CN.md
index 8c2d1e5..fc1f19c 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -54,6 +54,65 @@ cd mimiclaw
idf.py set-target esp32s3
```
+
+Ubuntu 安装
+
+建议基线:
+
+- Ubuntu 22.04/24.04
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb-1.0-0`、`libffi-dev`、`libssl-dev`
+
+Ubuntu 安装与构建:
+
+```bash
+sudo apt-get update
+sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \
+ cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
+
+./scripts/setup_idf_ubuntu.sh
+./scripts/build_ubuntu.sh
+```
+
+
+
+
+macOS 安装
+
+建议基线:
+
+- macOS 12/13/14
+- Xcode Command Line Tools
+- Homebrew
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb`、`libffi`、`openssl`
+
+macOS 安装与构建:
+
+```bash
+xcode-select --install
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+./scripts/setup_idf_macos.sh
+./scripts/build_macos.sh
+```
+
+
+
### 配置
MimiClaw 使用**两层配置**:`mimi_secrets.h` 提供编译时默认值,串口 CLI 可在运行时覆盖。CLI 设置的值存在 NVS Flash 中,优先级高于编译时值。
diff --git a/README_JA.md b/README_JA.md
index 82c4bfb..2ca1ffc 100644
--- a/README_JA.md
+++ b/README_JA.md
@@ -54,6 +54,65 @@ cd mimiclaw
idf.py set-target esp32s3
```
+
+Ubuntu インストール
+
+推奨ベースライン:
+
+- Ubuntu 22.04/24.04
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb-1.0-0`, `libffi-dev`, `libssl-dev`
+
+Ubuntu でのインストールとビルド:
+
+```bash
+sudo apt-get update
+sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv \
+ cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
+
+./scripts/setup_idf_ubuntu.sh
+./scripts/build_ubuntu.sh
+```
+
+
+
+
+macOS インストール
+
+推奨ベースライン:
+
+- macOS 12/13/14
+- Xcode Command Line Tools
+- Homebrew
+- Python >= 3.10
+- CMake >= 3.16
+- Ninja >= 1.10
+- Git >= 2.34
+- flex >= 2.6
+- bison >= 3.8
+- gperf >= 3.1
+- dfu-util >= 0.11
+- `libusb`, `libffi`, `openssl`
+
+macOS でのインストールとビルド:
+
+```bash
+xcode-select --install
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+
+./scripts/setup_idf_macos.sh
+./scripts/build_macos.sh
+```
+
+
+
### 設定
MimiClawは**2層設定**を採用しています:`mimi_secrets.h`でビルド時のデフォルト値を設定し、シリアルCLIで実行時にオーバーライドできます。CLI設定値はNVS Flashに保存され、ビルド時の値より優先されます。
diff --git a/main/idf_component.yml b/main/idf_component.yml
index afbca8e..ee698f3 100644
--- a/main/idf_component.yml
+++ b/main/idf_component.yml
@@ -2,7 +2,7 @@
dependencies:
## Required IDF version
idf:
- version: '>=4.1.0'
+ version: '>=5.5.0,<5.6.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
diff --git a/main/ui/config_screen.c b/main/ui/config_screen.c
index 8facf7f..bcac5fc 100644
--- a/main/ui/config_screen.c
+++ b/main/ui/config_screen.c
@@ -7,7 +7,6 @@
#include "display/font5x7.h"
#include "wifi/wifi_manager.h"
#include "mimi_config.h"
-#include "mimi_secrets.h"
#include "nvs.h"
#include "esp_log.h"
diff --git a/scripts/build_macos.sh b/scripts/build_macos.sh
new file mode 100755
index 0000000..773d6c5
--- /dev/null
+++ b/scripts/build_macos.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+IDF_VERSION="${IDF_VERSION:-v5.5.2}"
+ESP_ROOT="${ESP_ROOT:-$HOME/.espressif}"
+DEFAULT_IDF_DIR="$ESP_ROOT/esp-idf-$IDF_VERSION"
+IDF_DIR="${IDF_DIR:-${IDF_PATH:-$DEFAULT_IDF_DIR}}"
+
+if [[ ! -f "$IDF_DIR/export.sh" ]]; then
+ echo "ESP-IDF not found at: $IDF_DIR" >&2
+ echo "Run scripts/setup_idf_macos.sh first, or set IDF_DIR/IDF_PATH." >&2
+ exit 1
+fi
+
+# shellcheck source=/dev/null
+. "$IDF_DIR/export.sh"
+
+cd "$PROJECT_ROOT"
+idf.py set-target esp32s3
+idf.py build
diff --git a/scripts/build_ubuntu.sh b/scripts/build_ubuntu.sh
new file mode 100755
index 0000000..6e38ce0
--- /dev/null
+++ b/scripts/build_ubuntu.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+IDF_VERSION="${IDF_VERSION:-v5.5.2}"
+ESP_ROOT="${ESP_ROOT:-$HOME/.espressif}"
+DEFAULT_IDF_DIR="$ESP_ROOT/esp-idf-$IDF_VERSION"
+IDF_DIR="${IDF_DIR:-${IDF_PATH:-$DEFAULT_IDF_DIR}}"
+
+if [[ ! -f "$IDF_DIR/export.sh" ]]; then
+ echo "ESP-IDF not found at: $IDF_DIR" >&2
+ echo "Run scripts/setup_idf_ubuntu.sh first, or set IDF_DIR/IDF_PATH." >&2
+ exit 1
+fi
+
+# shellcheck source=/dev/null
+. "$IDF_DIR/export.sh"
+
+cd "$PROJECT_ROOT"
+idf.py set-target esp32s3
+idf.py build
diff --git a/scripts/setup_idf_macos.sh b/scripts/setup_idf_macos.sh
new file mode 100755
index 0000000..616a0c6
--- /dev/null
+++ b/scripts/setup_idf_macos.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if [[ "${OSTYPE:-}" != "darwin"* ]]; then
+ echo "This setup script currently supports macOS only." >&2
+ exit 1
+fi
+
+IDF_VERSION="${IDF_VERSION:-v5.5.2}"
+ESP_ROOT="${ESP_ROOT:-$HOME/.espressif}"
+IDF_DIR="${IDF_DIR:-$ESP_ROOT/esp-idf-$IDF_VERSION}"
+
+if ! command -v brew >/dev/null 2>&1; then
+ echo "Homebrew not found. Install it first:" >&2
+ echo " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"" >&2
+ exit 1
+fi
+
+ensure_brew_pkg() {
+ local pkg="$1"
+ if brew list --formula --versions "$pkg" >/dev/null 2>&1; then
+ echo "brew: $pkg already installed, skipping"
+ else
+ if ! brew install "$pkg"; then
+ echo "warn: failed to install $pkg via brew; continuing" >&2
+ return 0
+ fi
+ fi
+}
+
+ensure_brew_pkg_if_missing_cmd() {
+ local pkg="$1"
+ local cmd="$2"
+ if command -v "$cmd" >/dev/null 2>&1; then
+ echo "cmd: $cmd already available, skipping brew $pkg"
+ else
+ ensure_brew_pkg "$pkg"
+ fi
+}
+
+ensure_brew_pkg_if_missing_cmd git git
+ensure_brew_pkg_if_missing_cmd wget wget
+ensure_brew_pkg_if_missing_cmd flex flex
+ensure_brew_pkg_if_missing_cmd bison bison
+ensure_brew_pkg_if_missing_cmd gperf gperf
+ensure_brew_pkg_if_missing_cmd python python3
+ensure_brew_pkg_if_missing_cmd cmake cmake
+ensure_brew_pkg_if_missing_cmd ninja ninja
+ensure_brew_pkg_if_missing_cmd ccache ccache
+ensure_brew_pkg_if_missing_cmd dfu-util dfu-util
+ensure_brew_pkg libusb
+ensure_brew_pkg libffi
+ensure_brew_pkg openssl@3
+
+mkdir -p "$ESP_ROOT"
+if [[ ! -d "$IDF_DIR/.git" ]]; then
+ git clone --depth 1 --branch "$IDF_VERSION" --recursive \
+ https://github.com/espressif/esp-idf.git "$IDF_DIR"
+else
+ git -C "$IDF_DIR" fetch --tags --depth 1 origin "$IDF_VERSION"
+ git -C "$IDF_DIR" checkout "$IDF_VERSION"
+ git -C "$IDF_DIR" submodule update --init --recursive
+fi
+
+"$IDF_DIR/install.sh" esp32s3
+
+echo
+echo "ESP-IDF installed. For current shell run:"
+echo " . \"$IDF_DIR/export.sh\""
+echo "Then run from project root:"
+echo " idf.py set-target esp32s3"
+echo " idf.py build"
diff --git a/scripts/setup_idf_ubuntu.sh b/scripts/setup_idf_ubuntu.sh
new file mode 100755
index 0000000..8a4142a
--- /dev/null
+++ b/scripts/setup_idf_ubuntu.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if [[ "${OSTYPE:-}" != "linux-gnu"* ]]; then
+ echo "This setup script currently supports Ubuntu/Debian only." >&2
+ exit 1
+fi
+
+IDF_VERSION="${IDF_VERSION:-v5.5.2}"
+ESP_ROOT="${ESP_ROOT:-$HOME/.espressif}"
+IDF_DIR="${IDF_DIR:-$ESP_ROOT/esp-idf-$IDF_VERSION}"
+
+if [[ -f /etc/os-release ]]; then
+ . /etc/os-release
+ if [[ "${ID:-}" != "ubuntu" && "${ID_LIKE:-}" != *"debian"* ]]; then
+ echo "Detected ${PRETTY_NAME:-unknown}. Continuing, but package installation assumes apt." >&2
+ fi
+fi
+
+sudo apt-get update
+sudo apt-get install -y \
+ git wget flex bison gperf python3 python3-pip python3-venv \
+ cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
+
+mkdir -p "$ESP_ROOT"
+if [[ ! -d "$IDF_DIR/.git" ]]; then
+ git clone --depth 1 --branch "$IDF_VERSION" --recursive \
+ https://github.com/espressif/esp-idf.git "$IDF_DIR"
+else
+ git -C "$IDF_DIR" fetch --tags --depth 1 origin "$IDF_VERSION"
+ git -C "$IDF_DIR" checkout "$IDF_VERSION"
+ git -C "$IDF_DIR" submodule update --init --recursive
+fi
+
+"$IDF_DIR/install.sh" esp32s3
+
+echo
+echo "ESP-IDF installed. For current shell run:"
+echo " . \"$IDF_DIR/export.sh\""
+echo "Then run from project root:"
+echo " idf.py set-target esp32s3"
+echo " idf.py build"