From 2f1b196aea4cd037f3ffd6546b8d478494f75a05 Mon Sep 17 00:00:00 2001 From: GennKann Date: Sat, 28 Mar 2026 21:46:09 +0800 Subject: [PATCH] feat: add LuCI web management interface for OpenWrt --- contrib/luci-app-picoclaw/LICENSE | 66 ++ contrib/luci-app-picoclaw/README.de.md | 161 ++++ contrib/luci-app-picoclaw/README.ja.md | 172 ++++ contrib/luci-app-picoclaw/README.md | 69 ++ contrib/luci-app-picoclaw/README.pt.md | 161 ++++ contrib/luci-app-picoclaw/README.zh.md | 199 +++++ .../luci-app-picoclaw/Screenshots/logo.svg | 35 + .../Screenshots/screenshot_config.png | Bin 0 -> 1255789 bytes .../Screenshots/screenshot_main.png | Bin 0 -> 66029 bytes .../Screenshots/screenshot_mobile.png | Bin 0 -> 113127 bytes contrib/luci-app-picoclaw/install.py | 194 +++++ .../luci/controller/picoclaw.lua | 333 +++++++ .../luci/view/picoclaw/main.htm | 810 ++++++++++++++++++ .../scripts/build-apk-25xx.sh | 195 +++++ .../luci-app-picoclaw/scripts/picoclaw.init | 19 + 15 files changed, 2414 insertions(+) create mode 100644 contrib/luci-app-picoclaw/LICENSE create mode 100644 contrib/luci-app-picoclaw/README.de.md create mode 100644 contrib/luci-app-picoclaw/README.ja.md create mode 100644 contrib/luci-app-picoclaw/README.md create mode 100644 contrib/luci-app-picoclaw/README.pt.md create mode 100644 contrib/luci-app-picoclaw/README.zh.md create mode 100644 contrib/luci-app-picoclaw/Screenshots/logo.svg create mode 100644 contrib/luci-app-picoclaw/Screenshots/screenshot_config.png create mode 100644 contrib/luci-app-picoclaw/Screenshots/screenshot_main.png create mode 100644 contrib/luci-app-picoclaw/Screenshots/screenshot_mobile.png create mode 100644 contrib/luci-app-picoclaw/install.py create mode 100644 contrib/luci-app-picoclaw/luci/controller/picoclaw.lua create mode 100644 contrib/luci-app-picoclaw/luci/view/picoclaw/main.htm create mode 100644 contrib/luci-app-picoclaw/scripts/build-apk-25xx.sh create mode 100644 contrib/luci-app-picoclaw/scripts/picoclaw.init diff --git a/contrib/luci-app-picoclaw/LICENSE b/contrib/luci-app-picoclaw/LICENSE new file mode 100644 index 000000000..050662185 --- /dev/null +++ b/contrib/luci-app-picoclaw/LICENSE @@ -0,0 +1,66 @@ +MIT License + +Copyright (c) 2026 GennKann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +## Disclaimer & Third-Party Notice + +### Relationship to PicoClaw + +This project (**luci-app-picoclaw**) is an **independently created** LuCI web +management interface designed for OpenWrt routers. It provides a convenient +graphical frontend to manage the [PicoClaw](https://github.com/sipeed/picoclaw) +service via the OpenWrt LuCI web interface. + +**This project is NOT a derivative work of PicoClaw.** All source code in this +repository (Lua controller, HTML template, installation scripts, init.d service +file) was originally written by the author and is licensed under the MIT License +above. No source code from PicoClaw is included, copied, or modified in this +repository. + +### What This Project Does + +- Provides a LuCI web UI (controller + view) for managing the PicoClaw service +- Includes installation scripts and init.d service configuration for OpenWrt +- Communicates with PicoClaw via its standard CLI/API interface only + +### PicoClaw License + +PicoClaw is developed by [Sipeed](https://www.sipeed.com/) and is licensed under +the MIT License. If you use this management interface, you must also comply with +the PicoClaw license terms when using PicoClaw itself. + +- PicoClaw repository: https://github.com/sipeed/picoclaw +- PicoClaw license: https://github.com/sipeed/picoclaw/blob/main/LICENSE + +### Trademark Notice + +"PicoClaw" and "Sipeed" are trademarks of their respective owners. +This project is **not affiliated with, endorsed by, or sponsored by** Sipeed +or the PicoClaw project. + +### No Warranty + +This management interface is provided as-is. The author makes no guarantees +about its compatibility with current or future versions of PicoClaw or OpenWrt. +Users are responsible for ensuring that their use of PicoClaw complies with +PicoClaw's own license terms. diff --git a/contrib/luci-app-picoclaw/README.de.md b/contrib/luci-app-picoclaw/README.de.md new file mode 100644 index 000000000..23c66a931 --- /dev/null +++ b/contrib/luci-app-picoclaw/README.de.md @@ -0,0 +1,161 @@ +

+ PicoClaw LuCI +

+ +

PicoClaw LuCI — OpenWrt Webverwaltung

+ +

+ Eine schöne LuCI-Weboberfläche zur Verwaltung von PicoClaw auf OpenWrt-Routern +

+ +

+ OpenWrt + LuCI + License + Architecture +

+ +

+ English · + 简体中文 · + 日本語 · + Deutsch · + Português +

+ +--- + +## 📸 Screenshots + +| Desktop | Mobil | +|:---:|:---:| +| ![Dashboard](Screenshots/screenshot_main.png) | ![Mobil](Screenshots/screenshot_mobile.png) | +| ![Konfiguration](Screenshots/screenshot_config.png) | — | + +## ✨ Funktionen + +- 🖥️ **Modernes Dashboard** — Echtzeit-Service-Status, PID, Speichernutzung und Port-Überwachung +- 🚀 **Service-Steuerung** — PicoClaw mit einem Klick starten / stoppen / neu starten +- ⚡ **Autostart-Umschalter** — Autostart direkt in der Weboberfläche aktivieren/deaktivieren +- 📡 **Kanalverwaltung** — Alle Kanäle anzeigen und verwalten (Feishu, Telegram, Discord, WeChat, WeCom, Slack, QQ, LINE, DingTalk, WhatsApp, MaixCam) +- 🔧 **Formular-Konfiguration** — Intuitive Formular-Benutzeroberfläche für AI-Modell, Anbieter, Systemeinstellungen und Tools +- 📝 **JSON-Editor** — Direkte JSON-Bearbeitung mit Formatierung und Validierung +- 🌍 **5 Sprachen** — Eingebauter i18n: English, 简体中文, 日本語, Português, Deutsch +- 🔄 **Online-Update** — Neue Versionen prüfen und direkt aktualisieren +- 🔑 **Multi-Anbieter** — API-Schlüssel für Zhipu, OpenAI, ChatGPT, Claude, DeepSeek, Anthropic, Ollama, Azure OpenAI + +## 📋 Voraussetzungen + +| Anforderung | Details | +|---|---| +| **OpenWrt** | 24.10 / 25.xx (mit LuCI) | +| **Architektur** | ARM64, AMD64, ARMv7 | +| **SSH** | Für das Installationsskript erforderlich | +| **Python** | 3.6+ (auf dem PC) | +| **PicoClaw** | [sipeed/picoclaw](https://github.com/sipeed/picoclaw) neueste Version | + +## 🚀 Installation + +### Methode 1: Python-Installer (Empfohlen) + +```bash +pip install paramiko +wget https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/install_picoclaw_luci.py +python install_picoclaw_luci.py +``` + +### Methode 2: Paket-Installation + +> **Hinweis:** OpenWrt 24.10 verwendet `.ipk` (opkg), OpenWrt 25.xx verwendet `.apk` (apk-tools). Dies sind **unterschiedliche** Paketformate. + +#### OpenWrt 24.10(opkg / .ipk) + +```bash +opkg install luci-compat +wget -O /tmp/luci-app-picoclaw.ipk https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/luci-app-picoclaw_24.10_all.ipk +opkg install /tmp/luci-app-picoclaw.ipk +``` + +#### OpenWrt 25.xx(apk / .apk) + +OpenWrt 25.x hat den Paketmanager von `opkg` auf `apk-tools` umgestellt. Das Format änderte sich von `.ipk` zu `.apk`. Bauen Sie das Paket direkt auf dem Router: + +```bash +# Build-Skript herunterladen +wget -O /tmp/build-apk-25xx.sh https://raw.githubusercontent.com/GennKann/luci-app-picoclaw/main/scripts/build-apk-25xx.sh +chmod +x /tmp/build-apk-25xx.sh + +# .apk-Paket bauen +/tmp/build-apk-25xx.sh + +# Generiertes Paket installieren +apk add --allow-untrusted /root/luci-app-picoclaw_1.0.0_all.apk +``` + +### Methode 3: Manuelle Installation + +```bash +# PicoClaw installieren +ARCH=$(uname -m) +if echo "$ARCH" | grep -q "x86"; then PLAT="linux_amd64"; +elif echo "$ARCH" | grep -q "armv7"; then PLAT="linux_armv7"; +else PLAT="linux_arm64"; fi +wget -O /tmp/picoclaw "https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw_${PLAT}" +chmod +x /tmp/picoclaw && mv /tmp/picoclaw /usr/bin/picoclaw + +# LuCI-Dateien und init.d Service einrichten +# (Dateien aus diesem Repository kopieren) +``` + +## 🎯 Zugriff + +``` +http:///cgi-bin/luci/admin/services/picoclaw +``` + +## ⚠️ Haftungsausschluss + +Dieses Projekt ist eine Community-getriebene LuCI-Verwaltungsoberfläche für PicoClaw und ist **kein** Teil des offiziellen PicoClaw-Projekts. + +- **PicoClaw** wird von [Sipeed](https://github.com/sipeed) unter der MIT-Lizenz entwickelt +- Diese LuCI-Oberfläche ist ein unabhängiges Open-Source-Tool +- „PicoClaw" und „Sipeed" sind Marken ihrer jeweiligen Eigentümer + +## 📄 Lizenz + +[MIT-Lizenz](LICENSE) + +## 🙏 Danksagungen + +- [PicoClaw](https://github.com/sipeed/picoclaw) by Sipeed — Der großartige KI-Assistent, den dieses Projekt verwaltet +- [OpenWrt](https://openwrt.org/) — Das Fundament, auf dem dies läuft +- [LuCI](https://github.com/openwrt/luci) — Das Web-Interface-Framework + +## 🤝 Mitmachen + +Beiträge sind willkommen! Bitte erstellen Sie einen Pull Request. + +1. Forken Sie das Repository +2. Erstellen Sie einen Feature-Branch (`git checkout -b feature/amazing-feature`) +3. Committen Sie Ihre Änderungen (`git commit -m 'Add amazing feature'`) +4. Pushen Sie den Branch (`git push origin feature/amazing-feature`) +5. Erstellen Sie einen Pull Request + +--- + +

+ Wenn Sie dieses Projekt nützlich finden, geben Sie ihm bitte einen ⭐! +

+ +

+ + Stars + + + Forks + +

+ +

+ Made with ❤️ by GennKann +

diff --git a/contrib/luci-app-picoclaw/README.ja.md b/contrib/luci-app-picoclaw/README.ja.md new file mode 100644 index 000000000..e9781dc47 --- /dev/null +++ b/contrib/luci-app-picoclaw/README.ja.md @@ -0,0 +1,172 @@ +

+ PicoClaw LuCI +

+ +

PicoClaw LuCI — OpenWrt Web管理インターフェース

+ +

+ PicoClaw 専用 OpenWrt LuCI 美しい管理パネル +

+ +

+ OpenWrt + LuCI + License + Architecture +

+ +

+ English · + 简体中文 · + 日本語 · + Deutsch · + Português +

+ +--- + +## 📸 スクリーンショット + +| デスクトップ | モバイル | +|:---:|:---:| +| ![ダッシュボード](Screenshots/screenshot_main.png) | ![モバイル](Screenshots/screenshot_mobile.png) | +| ![設定エディタ](Screenshots/screenshot_config.png) | — | + +## ✨ 機能 + +- 🖥️ **モダンダッシュボード** — サービス状態、PID、メモリ使用量、ポート監視をリアルタイム表示 +- 🚀 **サービス制御** — PicoClawの開始/停止/再起動をワンクリック +- ⚡ **自動起動切替** — Web UIから起動時自動開始の有効/無効を切り替え +- 📡 **チャンネル管理** — 全チャンネルの表示・管理(Feishu、Telegram、Discord、WeChat、WeCom、Slack、QQ、LINE、DingTalk、WhatsApp、MaixCam) +- 🔧 **フォーム設定エディタ** — 直感的なフォームUIでAIモデル、プロバイダー、システム設定、ツールを設定 +- 📝 **JSON設定エディタ** — JSON直接編集、フォーマット、バリデーション対応 +- 🌍 **5言語対応** — 組み込みi18n:English、简体中文、日本語、Português、Deutsch +- 🔄 **オンライン更新** — 新バージョンの確認とUIからの直接更新 +- 📊 **システムログ** — PicoClawシステムログをリアルタイム表示 +- 🔑 **マルチプロバイダー対応** — Zhipu、OpenAI、ChatGPT、Claude、DeepSeek、Anthropic、Ollama、Azure OpenAIのAPIキー設定 +- 🎨 **レスポンシブデザイン** — デスクトップとモバイルブラウザの両方に対応 + +## 📋 動作要件 + +| 要件 | 詳細 | +|---|---| +| **OpenWrt** | 24.10 / 25.xx(LuCI導入済み) | +| **アーキテクチャ** | ARM64、AMD64 (x86_64)、ARMv7 | +| **LuCI** | 標準LuCIインストール | +| **SSH** | インストーラースクリプトに必要 | +| **Python** | 3.6+(PC環境) | +| **PicoClaw** | [sipeed/picoclaw](https://github.com/sipeed/picoclaw) 最新版 | + +## 🚀 インストール + +### 方法1:ワンクリックPythonインストーラー(推奨) + +PC上で実行 — SSH経由でルーターに自動インストールします。 + +```bash +pip install paramiko +wget https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/install_picoclaw_luci.py +python install_picoclaw_luci.py +``` + +### 方法2:パッケージインストール + +> **注意:** OpenWrt 24.10は`.ipk`(opkg)、OpenWrt 25.xxは`.apk`(apk-tools)を使用します。**別の**パッケージ形式です。 + +#### OpenWrt 24.10(opkg / .ipk) + +```bash +opkg install luci-compat +wget -O /tmp/luci-app-picoclaw.ipk https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/luci-app-picoclaw_24.10_all.ipk +opkg install /tmp/luci-app-picoclaw.ipk +``` + +#### OpenWrt 25.xx(apk / .apk) + +OpenWrt 25.xではパッケージマネージャーが`opkg`から`apk-tools`に変更され、形式も`.ipk`から`.apk`になりました。ルーター上で直接ビルドします: + +```bash +# ビルドスクリプトをダウンロード +wget -O /tmp/build-apk-25xx.sh https://raw.githubusercontent.com/GennKann/luci-app-picoclaw/main/scripts/build-apk-25xx.sh +chmod +x /tmp/build-apk-25xx.sh + +# .apkパッケージをビルド +/tmp/build-apk-25xx.sh + +# 生成されたパッケージをインストール +apk add --allow-untrusted /root/luci-app-picoclaw_1.0.0_all.apk +``` + +### 方法3:手動インストール + +```bash +# PicoClawインストール +ARCH=$(uname -m) +if echo "$ARCH" | grep -q "x86"; then PLAT="linux_amd64"; +elif echo "$ARCH" | grep -q "armv7"; then PLAT="linux_armv7"; +else PLAT="linux_arm64"; fi +wget -O /tmp/picoclaw "https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw_${PLAT}" +chmod +x /tmp/picoclaw && mv /tmp/picoclaw /usr/bin/picoclaw + +# LuCIファイル配置 +# controller → /usr/lib/lua/luci/controller/picoclaw.lua +# template → /usr/lib/lua/luci/view/picoclaw/main.htm + +# init.dサービス設定 +cp scripts/picoclaw.init /etc/init.d/picoclaw +chmod +x /etc/init.d/picoclaw && /etc/init.d/picoclaw enable +rm -rf /tmp/luci-* && /etc/init.d/picoclaw start +``` + +## 🎯 アクセス + +``` +http://<ルーターIP>/cgi-bin/luci/admin/services/picoclaw +``` + +## ⚠️ 免責事項 + +このプロジェクトはコミュニティ駆動のPicoClaw管理インターフェースであり、PicoClaw公式プロジェクトの一部ではありません。 + +- **PicoClaw**は[Sipeed](https://github.com/sipeed)によってMITライセンスで開発されています +- 本LuCIインターフェースは独立したオープンソースツールです +- "PicoClaw"および"Sipeed"は各所有者の商標です + +## 📄 ライセンス + +[MIT License](LICENSE) + +## 🙏 クレジット + +- [PicoClaw](https://github.com/sipeed/picoclaw) by Sipeed — このプロジェクトが管理する素晴らしいAIアシスタント +- [OpenWrt](https://openwrt.org/) — 実行環境 +- [LuCI](https://github.com/openwrt/luci) — Webインターフェースフレームワーク + +## 🤝 コントリビューション + +コントリビューションをお待ちしています!お気軽にPull Requestをどうぞ。 + +1. リポジトリをフォーク +2. フィーチャーブランチを作成 (`git checkout -b feature/amazing-feature`) +3. 変更をコミット (`git commit -m 'Add amazing feature'`) +4. ブランチをプッシュ (`git push origin feature/amazing-feature`) +5. Pull Requestを作成 + +--- + +

+ このプロジェクトが役立つと思ったら、⭐ をお願いします! +

+ +

+ + Stars + + + Forks + +

+ +

+ Made with ❤️ by GennKann +

diff --git a/contrib/luci-app-picoclaw/README.md b/contrib/luci-app-picoclaw/README.md new file mode 100644 index 000000000..6080fee60 --- /dev/null +++ b/contrib/luci-app-picoclaw/README.md @@ -0,0 +1,69 @@ +# LuCI Management Interface for PicoClaw on OpenWrt + +A beautiful LuCI web interface to manage PicoClaw on OpenWrt routers. + +## Features + +- **Modern Dashboard** — Real-time service status, PID, memory usage, and port monitoring +- **Service Control** — Start / Stop / Restart PicoClaw with one click +- **Auto-Start Toggle** — Enable or disable boot-on-start from the web UI +- **Channel Management** — View and manage all connected channels +- **Form-based Config Editor** — Intuitive form UI for AI model, providers, system settings, and tools configuration +- **JSON Config Editor** — Direct JSON editing with format and validation +- **5 Languages** — Built-in i18n: English, 简体中文, 日本語, Português, Deutsch +- **Online Update** — Check for new versions and update directly from the UI +- **System Logs** — View PicoClaw system logs in real-time +- **Responsive Design** — Works on both desktop and mobile browsers + +## Installation + +### One-Click Python Installer (Recommended) + +```bash +pip install paramiko +python contrib/luci-app-picoclaw/install.py +``` + +### Manual Installation + +```bash +# Copy LuCI controller +cp contrib/luci-app-picoclaw/luci/controller/picoclaw.lua /usr/lib/lua/luci/controller/ + +# Copy LuCI template +mkdir -p /usr/lib/lua/luci/view/picoclaw +cp contrib/luci-app-picoclaw/luci/view/picoclaw/main.htm /usr/lib/lua/luci/view/picoclaw/ + +# Set up init.d service +cp contrib/luci-app-picoclaw/scripts/picoclaw.init /etc/init.d/picoclaw +chmod +x /etc/init.d/picoclaw +/etc/init.d/picoclaw enable +``` + +## Requirements + +- OpenWrt 24.10 / 25.xx with LuCI installed +- ARM64 / AMD64 / ARMv7 +- PicoClaw latest version + +## Screenshots + +| Desktop | Mobile | +|:---:|:---:| +| ![Dashboard](Screenshots/screenshot_main.png) | ![Mobile](Screenshots/screenshot_mobile.png) | +| ![Config](Screenshots/screenshot_config.png) | — | + +## Access + +``` +http:///cgi-bin/luci/admin/services/picoclaw +``` + +## License + +MIT License — This is an independently created LuCI management interface. +It communicates with PicoClaw via its standard CLI/API interface only. + +## Links + +- Standalone repo: [GennKann/luci-app-picoclaw](https://github.com/GennKann/luci-app-picoclaw) diff --git a/contrib/luci-app-picoclaw/README.pt.md b/contrib/luci-app-picoclaw/README.pt.md new file mode 100644 index 000000000..f42ddc78c --- /dev/null +++ b/contrib/luci-app-picoclaw/README.pt.md @@ -0,0 +1,161 @@ +

+ PicoClaw LuCI +

+ +

PicoClaw LuCI — Gerenciador Web OpenWrt

+ +

+ Uma interface web LuCI bonita para gerenciar o PicoClaw em roteadores OpenWrt +

+ +

+ OpenWrt + LuCI + License + Architecture +

+ +

+ English · + 简体中文 · + 日本語 · + Deutsch · + Português +

+ +--- + +## 📸 Capturas de Tela + +| Desktop | Mobile | +|:---:|:---:| +| ![Painel](Screenshots/screenshot_main.png) | ![Mobile](Screenshots/screenshot_mobile.png) | +| ![Configuração](Screenshots/screenshot_config.png) | — | + +## ✨ Funcionalidades + +- 🖥️ **Painel Moderno** — Status do serviço em tempo real, PID, uso de memória e monitoramento de porta +- 🚀 **Controle de Serviço** — Iniciar / Parar / Reiniciar o PicoClaw com um clique +- ⚡ **Alternar Auto-início** — Ativar/desativar inicialização automática pela interface web +- 📡 **Gerenciamento de Canais** — Visualizar e gerenciar todos os canais (Feishu, Telegram, Discord, WeChat, WeCom, Slack, QQ, LINE, DingTalk, WhatsApp, MaixCam) +- 🔧 **Editor de Configuração** — Interface de formulário intuitiva para modelo AI, provedores, configurações do sistema e ferramentas +- 📝 **Editor JSON** — Edição direta JSON com formatação e validação +- 🌍 **5 Idiomas** — i18n integrado: English, 简体中文, 日本語, Português, Deutsch +- 🔄 **Atualização Online** — Verificar novas versões e atualizar diretamente pela interface +- 🔑 **Multi-provedor** — Chaves API para Zhipu, OpenAI, ChatGPT, Claude, DeepSeek, Anthropic, Ollama, Azure OpenAI + +## 📋 Requisitos + +| Requisito | Detalhes | +|---|---| +| **OpenWrt** | 24.10 / 25.xx (com LuCI) | +| **Arquitetura** | ARM64, AMD64, ARMv7 | +| **SSH** | Necessário para o script de instalação | +| **Python** | 3.6+ (no PC) | +| **PicoClaw** | [sipeed/picoclaw](https://github.com/sipeed/picoclaw) versão mais recente | + +## 🚀 Instalação + +### Método 1: Instalador Python (Recomendado) + +```bash +pip install paramiko +wget https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/install_picoclaw_luci.py +python install_picoclaw_luci.py +``` + +### Método 2: Instalação por Pacote + +> **Nota:** OpenWrt 24.10 usa `.ipk` (opkg), OpenWrt 25.xx usa `.apk` (apk-tools). São **formatos diferentes** de pacotes. + +#### OpenWrt 24.10(opkg / .ipk) + +```bash +opkg install luci-compat +wget -O /tmp/luci-app-picoclaw.ipk https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/luci-app-picoclaw_24.10_all.ipk +opkg install /tmp/luci-app-picoclaw.ipk +``` + +#### OpenWrt 25.xx(apk / .apk) + +OpenWrt 25.x mudou o gerenciador de pacotes de `opkg` para `apk-tools`, e o formato de `.ipk` para `.apk`. Construa o pacote diretamente no roteador: + +```bash +# Baixar script de compilação +wget -O /tmp/build-apk-25xx.sh https://raw.githubusercontent.com/GennKann/luci-app-picoclaw/main/scripts/build-apk-25xx.sh +chmod +x /tmp/build-apk-25xx.sh + +# Compilar pacote .apk +/tmp/build-apk-25xx.sh + +# Instalar pacote gerado +apk add --allow-untrusted /root/luci-app-picoclaw_1.0.0_all.apk +``` + +### Método 3: Instalação Manual + +```bash +# Instalar PicoClaw +ARCH=$(uname -m) +if echo "$ARCH" | grep -q "x86"; then PLAT="linux_amd64"; +elif echo "$ARCH" | grep -q "armv7"; then PLAT="linux_armv7"; +else PLAT="linux_arm64"; fi +wget -O /tmp/picoclaw "https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw_${PLAT}" +chmod +x /tmp/picoclaw && mv /tmp/picoclaw /usr/bin/picoclaw + +# Configurar arquivos LuCI e serviço init.d +# (copiar arquivos deste repositório) +``` + +## 🎯 Acesso + +``` +http:///cgi-bin/luci/admin/services/picoclaw +``` + +## ⚠️ Aviso Legal + +Este projeto é uma interface LuCI de gerenciamento do PicoClaw desenvolvida pela comunidade e **NÃO** faz parte do projeto oficial PicoClaw. + +- **PicoClaw** é desenvolvido pela [Sipeed](https://github.com/sipeed) sob a licença MIT +- Esta interface LuCI é uma ferramenta open-source independente +- "PicoClaw" e "Sipeed" são marcas registradas de seus respectivos proprietários + +## 📄 Licença + +[Licença MIT](LICENSE) + +## 🙏 Créditos + +- [PicoClaw](https://github.com/sipeed/picoclaw) by Sipeed — O excelente assistente de IA que este projeto gerencia +- [OpenWrt](https://openwrt.org/) — A base sobre a qual isso é executado +- [LuCI](https://github.com/openwrt/luci) — O framework de interface web + +## 🤝 Contribuição + +Contribuições são bem-vindas! Sinta-se à vontade para enviar um Pull Request. + +1. Faça um Fork do repositório +2. Crie um branch de funcionalidade (`git checkout -b feature/amazing-feature`) +3. Faça commit das alterações (`git commit -m 'Add amazing feature'`) +4. Faça push do branch (`git push origin feature/amazing-feature`) +5. Abra um Pull Request + +--- + +

+ Se você achar este projeto útil, por favor, dê uma ⭐! +

+ +

+ + Stars + + + Forks + +

+ +

+ Made with ❤️ by GennKann +

diff --git a/contrib/luci-app-picoclaw/README.zh.md b/contrib/luci-app-picoclaw/README.zh.md new file mode 100644 index 000000000..0798f0b43 --- /dev/null +++ b/contrib/luci-app-picoclaw/README.zh.md @@ -0,0 +1,199 @@ +

+ PicoClaw LuCI +

+ +

PicoClaw LuCI — OpenWrt 网页管理界面

+ +

+ PicoClaw 量身打造的 OpenWrt LuCI 美化管理面板 +

+ +

+ OpenWrt + LuCI + License + Architecture +

+ +

+ English · + 简体中文 · + 日本語 · + Deutsch · + Português +

+ +--- + +## 📸 截图预览 + +| 桌面端 | 移动端 | +|:---:|:---:| +| ![主界面](Screenshots/screenshot_main.png) | ![手机端](Screenshots/screenshot_mobile.png) | +| ![配置编辑](Screenshots/screenshot_config.png) | — | + +## ✨ 功能特性 + +- 🖥️ **现代化仪表盘** — 实时显示服务状态、PID、内存占用、端口监听 +- 🚀 **服务控制** — 一键启动 / 停止 / 重启 PicoClaw +- ⚡ **开机自启开关** — 在网页上直接控制开机自动启动 +- 📡 **通道管理** — 查看和管理所有通道(飞书、Telegram、Discord、微信、企业微信、Slack、QQ、LINE、钉钉、WhatsApp、MaixCam) +- 🔧 **表单化配置编辑** — 直观的表单界面配置 AI 模型、API 密钥、系统设置和工具 +- 📝 **JSON 配置编辑** — 支持 JSON 直接编辑、格式化和验证 +- 🌍 **5 种语言** — 内置国际化:简体中文、English、日本語、Português、Deutsch +- 🔄 **在线更新** — 检查新版本并直接在界面上更新 +- 📊 **系统日志** — 实时查看 PicoClaw 系统日志 +- 💬 **微信接入引导** — 微信个人号接入步骤引导 +- 🔑 **多 AI 供应商支持** — 配置智谱、OpenAI、ChatGPT、Claude、DeepSeek、Anthropic、Ollama、Azure OpenAI +- 🎨 **响应式设计** — 完美适配桌面和手机浏览器 +- 📦 **一键安装** — Python 安装脚本,通过 SSH 自动部署到任意 OpenWrt 设备 + +## 📋 系统要求 + +| 要求 | 说明 | +|---|---| +| **OpenWrt** | 24.10 / 25.xx(需安装 LuCI) | +| **架构** | ARM64、AMD64 (x86_64)、ARMv7 | +| **LuCI** | 标准 LuCI 安装即可 | +| **SSH** | 安装脚本需要路由器开启 SSH | +| **Python** | 3.6+(在电脑上运行安装脚本) | +| **PicoClaw** | [sipeed/picoclaw](https://github.com/sipeed/picoclaw) 最新版 | + +## 🚀 安装方式 + +### 方式一:一键 Python 安装(推荐) + +在你的电脑上运行,脚本会通过 SSH 自动完成所有操作。 + +```bash +# 安装依赖 +pip install paramiko + +# 下载安装脚本 +wget https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/install_picoclaw_luci.py + +# 运行 — 按提示输入路由器信息 +python install_picoclaw_luci.py +``` + +安装脚本会自动完成: +1. ✅ 检测系统架构(ARM64 / AMD64 / ARMv7) +2. ✅ 下载并安装最新版 PicoClaw +3. ✅ 创建 procd init.d 开机自启服务 +4. ✅ 部署 LuCI 网页管理界面 +5. ✅ 初始化 PicoClaw 配置 +6. ✅ 启动服务并验证 + +### 方式二:手动安装 + +SSH 登录你的 OpenWrt 路由器: + +```bash +# 1. 下载并安装 PicoClaw +ARCH=$(uname -m) +if echo "$ARCH" | grep -q "x86"; then PLAT="linux_amd64"; +elif echo "$ARCH" | grep -q "armv7"; then PLAT="linux_armv7"; +else PLAT="linux_arm64"; fi + +wget -O /tmp/picoclaw "https://github.com/sipeed/picoclaw/releases/latest/download/picoclaw_${PLAT}" +chmod +x /tmp/picoclaw && mv /tmp/picoclaw /usr/bin/picoclaw + +# 2. 部署 LuCI 文件(从本仓库复制) +# controller → /usr/lib/lua/luci/controller/picoclaw.lua +# template → /usr/lib/lua/luci/view/picoclaw/main.htm + +# 3. 设置 init.d 服务 +cp scripts/picoclaw.init /etc/init.d/picoclaw +chmod +x /etc/init.d/picoclaw && /etc/init.d/picoclaw enable + +# 4. 清理缓存并启动 +rm -rf /tmp/luci-* && /etc/init.d/picoclaw start +``` + +### 方式三:包管理器安装 + +> **注意:** OpenWrt 24.10 使用 `.ipk`(opkg 包管理器),OpenWrt 25.xx 使用 `.apk`(apk-tools 包管理器),两者是**不同的**包格式。 + +#### OpenWrt 24.10(opkg / .ipk) + +```bash +opkg install luci-compat +wget -O /tmp/luci-app-picoclaw.ipk https://github.com/GennKann/luci-app-picoclaw/releases/latest/download/luci-app-picoclaw_24.10_all.ipk +opkg install /tmp/luci-app-picoclaw.ipk +``` + +#### OpenWrt 25.xx(apk / .apk) + +OpenWrt 25.x 已将包管理器从 `opkg` 切换为 `apk-tools`,包格式从 `.ipk` 变为 `.apk`。需要在路由器上直接构建: + +```bash +# 下载构建脚本 +wget -O /tmp/build-apk-25xx.sh https://raw.githubusercontent.com/GennKann/luci-app-picoclaw/main/scripts/build-apk-25xx.sh +chmod +x /tmp/build-apk-25xx.sh + +# 运行构建 .apk 包 +/tmp/build-apk-25xx.sh + +# 安装生成的包 +apk add --allow-untrusted /root/luci-app-picoclaw_1.0.0_all.apk +``` + +> **为什么需要在路由器上构建?** OpenWrt 25.xx 使用 APKv3(Alpine Package Keeper)格式,需要 `apk-tools` 来正确构建。在路由器上构建可确保完全兼容。 + +## 🎯 访问地址 + +安装完成后,通过以下地址访问管理界面: + +``` +http://<路由器IP>/cgi-bin/luci/admin/services/picoclaw +``` + +例如:`http://192.168.1.1/cgi-bin/luci/admin/services/picoclaw` + +## ⚠️ 免责声明 + +本项目是社区驱动的 PicoClaw LuCI 管理界面,**不是** PicoClaw 官方项目的一部分。 + +- **PicoClaw** 由 [Sipeed](https://github.com/sipeed) 使用 MIT 许可证开发 +- 本 LuCI 界面是独立的开源工具 +- 我们尊重原始项目的所有知识产权 +- "PicoClaw" 和 "Sipeed" 是其各自所有者的商标 + +## 📄 许可证 + +本项目使用 [MIT 许可证](LICENSE)。 + +## 🙏 鸣谢 + +- [PicoClaw](https://github.com/sipeed/picoclaw) by Sipeed — 本项目所管理的出色 AI 助手 +- [OpenWrt](https://openwrt.org/) — 运行基础 +- [LuCI](https://github.com/openwrt/luci) — Web 界面框架 + +## 🤝 参与贡献 + +欢迎贡献!请随时提交 Pull Request。 + +1. Fork 本仓库 +2. 创建功能分支 (`git checkout -b feature/amazing-feature`) +3. 提交更改 (`git commit -m 'Add amazing feature'`) +4. 推送分支 (`git push origin feature/amazing-feature`) +5. 发起 Pull Request + +--- + +

+ 如果这个项目对你有帮助,请给一个 ⭐ 支持一下! +

+ +

+ + Stars + + + Forks + +

+ +

+ ❤️ 由 GennKann 用心制作 +

diff --git a/contrib/luci-app-picoclaw/Screenshots/logo.svg b/contrib/luci-app-picoclaw/Screenshots/logo.svg new file mode 100644 index 000000000..b4230f004 --- /dev/null +++ b/contrib/luci-app-picoclaw/Screenshots/logo.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OpenWrt + diff --git a/contrib/luci-app-picoclaw/Screenshots/screenshot_config.png b/contrib/luci-app-picoclaw/Screenshots/screenshot_config.png new file mode 100644 index 0000000000000000000000000000000000000000..a729e76b4d0895165d9a5145c655efcb6db504c6 GIT binary patch literal 1255789 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