chore(local-tool): rename local_tool → local-tool, add linux/windows bootstrap scripts

- 統一目錄名為 local-tool(連字號),修正所有文件中殘留的底線版本
- 新增 scripts/bootstrap-linux.sh 與 scripts/bootstrap-windows.ps1
  一鍵安裝依賴(Go/Node/pnpm/Wails/MSYS2)並執行 payload + installer build

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jim800121chen 2026-04-11 23:23:29 +08:00
parent 4e370bb730
commit 5a8d2797c2
9 changed files with 179 additions and 13 deletions

View File

@ -95,7 +95,7 @@
## 2.5 被移除元件回收清單 ## 2.5 被移除元件回收清單
以下程式碼可以從原專案直接刪除(不需要轉移到 local_tool 以下程式碼可以從原專案直接刪除(不需要轉移到 local-tool
``` ```
components/cluster/**/* components/cluster/**/*

View File

@ -14,7 +14,7 @@
## 2. 目錄層級策略 ## 2. 目錄層級策略
| Fromedge-ai-platform | Tolocal_tool | 策略 | 備註 | | Fromedge-ai-platform | Tolocal-tool | 策略 | 備註 |
|------------------------|----------------|------|------| |------------------------|----------------|------|------|
| `server/main.go` | `server/main.go` | **改寫** | 移除 cluster / tunnel / relay / hwid / gitea 邏輯 | | `server/main.go` | `server/main.go` | **改寫** | 移除 cluster / tunnel / relay / hwid / gitea 邏輯 |
| `server/go.mod` | `server/go.mod` | **改寫** | 移除不再需要的 importsmodule name 可改為 `visiona-local` | | `server/go.mod` | `server/go.mod` | **改寫** | 移除不再需要的 importsmodule name 可改為 `visiona-local` |
@ -249,13 +249,13 @@ dmg-config.py ← macOS dmgbuild 設定
## 5. 搬家步驟(建議執行順序) ## 5. 搬家步驟(建議執行順序)
1. **建立骨架**`mkdir -p local_tool/{server,frontend,visiona-local,vendor,scripts,dist}` 1. **建立骨架**`mkdir -p local-tool/{server,frontend,visiona-local,vendor,scripts,dist}`
2. **複製 server core**`cp -r edge-ai-platform/server/{internal/{api,camera,config,deps,device,driver,inference,model},pkg/logger,scripts,data,web} local_tool/server/` 2. **複製 server core**`cp -r edge-ai-platform/server/{internal/{api,camera,config,deps,device,driver,inference,model},pkg/logger,scripts,data,web} local-tool/server/`
3. **跳過要刪的 package**:不要複製 `cluster``tunnel``flash``update``pkg/hwid``cmd/relay-server``tray`(使用者決策 Q-A砍 tray 3. **跳過要刪的 package**:不要複製 `cluster``tunnel``flash``update``pkg/hwid``cmd/relay-server``tray`(使用者決策 Q-A砍 tray
4. **改寫 `main.go` + `config.go` + `router.go`**(見上方 §3 4. **改寫 `main.go` + `config.go` + `router.go`**(見上方 §3
5. **改寫 go.mod**`go mod init visiona-local/server``go mod tidy`(會自動清掉 unused imports 5. **改寫 go.mod**`go mod init visiona-local/server``go mod tidy`(會自動清掉 unused imports
6. **驗證 `go build ./...` 通過** 6. **驗證 `go build ./...` 通過**
7. **複製 frontend**`cp -r edge-ai-platform/frontend local_tool/frontend` 7. **複製 frontend**`cp -r edge-ai-platform/frontend local-tool/frontend`
8. **清理前端 cluster / relay / tunnel UI**(使用者決策 Q-C=C2M1 就要清乾淨,不留到 M2刪除 `src/app/clusters/``src/app/workspace/cluster/``src/components/cluster/``src/components/relay-token-sync.tsx``src/lib/api/clusters.ts``src/lib/api/tunnel.ts`(若有)、`src/lib/api/update.ts`(若有),修改 `sidebar.tsx` 移除 Clusters 導航項、`page.tsx` 移除 cluster stat、`settings/page.tsx` 移除 relay / cluster 區塊。最後驗證 `pnpm build` 通過且 UI 乾淨。 8. **清理前端 cluster / relay / tunnel UI**(使用者決策 Q-C=C2M1 就要清乾淨,不留到 M2刪除 `src/app/clusters/``src/app/workspace/cluster/``src/components/cluster/``src/components/relay-token-sync.tsx``src/lib/api/clusters.ts``src/lib/api/tunnel.ts`(若有)、`src/lib/api/update.ts`(若有),修改 `sidebar.tsx` 移除 Clusters 導航項、`page.tsx` 移除 cluster stat、`settings/page.tsx` 移除 relay / cluster 區塊。最後驗證 `pnpm build` 通過且 UI 乾淨。
9. **複製 installer**`cp -r edge-ai-platform/installer local_tool/visiona-local`,改 `main.go` 的 app 名稱與 bundle ID 9. **複製 installer**`cp -r edge-ai-platform/installer local-tool/visiona-local`,改 `main.go` 的 app 名稱與 bundle ID
10. **先跑 M1-12**:全新機器上 installer 能裝起來並跑通 Mock 模式 10. **先跑 M1-12**:全新機器上 installer 能裝起來並跑通 Mock 模式

View File

@ -85,7 +85,7 @@ visionA-local 是 `edge-ai-platform` 的**單機桌面版**,把原本需要 EC
## 4. 程式碼來源策略(摘要) ## 4. 程式碼來源策略(摘要)
新專案 `local_tool/` 從零建立,但可以自由從 `edge-ai-platform/` 取用程式碼: 新專案 `local-tool/` 從零建立,但可以自由從 `edge-ai-platform/` 取用程式碼:
- **直接複製(~60% 程式碼)**`installer/``server/internal/{api,camera,config,deps,device,driver,inference,model}``server/scripts/kneron_bridge.py``server/data/``server/pkg/logger` - **直接複製(~60% 程式碼)**`installer/``server/internal/{api,camera,config,deps,device,driver,inference,model}``server/scripts/kneron_bridge.py``server/data/``server/pkg/logger`
- **改寫(~20%**`server/main.go`(移除 cluster / tunnel / relay`server/internal/api/router.go`(刪 cluster routes`server/internal/config/config.go`(刪 relay / gitea flags`installer/app.go`(改名 + 加入 Python runtime 雙策略)、`frontend/`(刪 cluster / relay UI - **改寫(~20%**`server/main.go`(移除 cluster / tunnel / relay`server/internal/api/router.go`(刪 cluster routes`server/internal/config/config.go`(刪 relay / gitea flags`installer/app.go`(改名 + 加入 Python runtime 雙策略)、`frontend/`(刪 cluster / relay UI
@ -102,12 +102,12 @@ visionA-local 是 `edge-ai-platform` 的**單機桌面版**,把原本需要 EC
| # | 任務 | 說明 | 預估大小 | | # | 任務 | 說明 | 預估大小 |
|---|------|------|---------| |---|------|------|---------|
| M1-1 | 建立 repo 骨架 | `local_tool/` 目錄結構 + go.mod + Makefile 骨架 | S | | M1-1 | 建立 repo 骨架 | `local-tool/` 目錄結構 + go.mod + Makefile 骨架 | S |
| M1-2 | 複製 server core | 從 edge-ai-platform 複製 `server/internal/{api,camera,config,deps,device,model,inference}` + `pkg/logger` | S | | M1-2 | 複製 server core | 從 edge-ai-platform 複製 `server/internal/{api,camera,config,deps,device,model,inference}` + `pkg/logger` | S |
| M1-3 | 清理 main.go | 改寫 `server/main.go`:移除 cluster / tunnel / relay / hwid / GiteaURL | M | | M1-3 | 清理 main.go | 改寫 `server/main.go`:移除 cluster / tunnel / relay / hwid / GiteaURL | M |
| M1-4 | 清理 config.go | 砍 relay / tunnel / gitea / GUIMode 相關 flags | S | | M1-4 | 清理 config.go | 砍 relay / tunnel / gitea / GUIMode 相關 flags | S |
| M1-5 | 清理 router.go | 刪除 `/api/clusters/*``/ws/clusters/*``/auth/token` | S | | M1-5 | 清理 router.go | 刪除 `/api/clusters/*``/ws/clusters/*``/auth/token` | S |
| M1-6 | 複製 frontend | 複製 `frontend/` 進 local_tool | S | | M1-6 | 複製 frontend | 複製 `frontend/` 進 local-tool | S |
| M1-7 | **清理前端 UI**Q-C=C2 | **M1 必做**:刪除 `src/app/clusters/``src/app/workspace/cluster/``src/components/cluster/``relay-token-sync.tsx``lib/api/{clusters,tunnel,update}.ts`;修改 sidebar移除 Clusters 導航項、Dashboard移除 cluster 卡片、Settings移除 relay / cluster 區塊);最終 `pnpm build` 通過且 UI 乾淨、沒有殘留的 cluster / relay / tunnel 入口 | M | | M1-7 | **清理前端 UI**Q-C=C2 | **M1 必做**:刪除 `src/app/clusters/``src/app/workspace/cluster/``src/components/cluster/``relay-token-sync.tsx``lib/api/{clusters,tunnel,update}.ts`;修改 sidebar移除 Clusters 導航項、Dashboard移除 cluster 卡片、Settings移除 relay / cluster 區塊);最終 `pnpm build` 通過且 UI 乾淨、沒有殘留的 cluster / relay / tunnel 入口 | M |
| M1-8 | Go server 本地 build | `make build` 產出 `visiona-local-server`(含 embedded Next.js可直接 `./visiona-local-server` 跑起來 | S | | M1-8 | Go server 本地 build | `make build` 產出 `visiona-local-server`(含 embedded Next.js可直接 `./visiona-local-server` 跑起來 | S |
| M1-9 | 複製 installer shell | 從 `installer/` 複製 `app.go` + `main.go` + `embed.go` + platform_*.go改名為 `visiona-local` | M | | M1-9 | 複製 installer shell | 從 `installer/` 複製 `app.go` + `main.go` + `embed.go` + platform_*.go改名為 `visiona-local` | M |

View File

@ -1,6 +1,6 @@
# Removed Code — visionA-local # Removed Code — visionA-local
> 要從 edge-ai-platform 砍掉、不搬進 local_tool 的目錄 / 檔案 / import 清單。 > 要從 edge-ai-platform 砍掉、不搬進 local-tool 的目錄 / 檔案 / import 清單。
--- ---

View File

@ -141,7 +141,7 @@ visionA-local 是 `/Users/jimchen/Innovedus/edge-ai-platform` 的 local 版本
### 來源與策略 ### 來源與策略
- **參考原專案**`/Users/jimchen/Innovedus/edge-ai-platform` - **參考原專案**`/Users/jimchen/Innovedus/edge-ai-platform`
- **程式碼策略**:重新建立 local_tool可從 edge-ai-platform 自由取用任何程式碼(不做 fork、不做 submodule - **程式碼策略**:重新建立 local-tool可從 edge-ai-platform 自由取用任何程式碼(不做 fork、不做 submodule
- **產品名稱**visionA-local - **產品名稱**visionA-local
- **Bundle ID**(暫定):`com.innovedus.visiona-local` - **Bundle ID**(暫定):`com.innovedus.visiona-local`

View File

@ -96,7 +96,7 @@ visionA-local 是 `edge-ai-platform`(原本要部署到 EC2 + Docker 的 Knero
### 專案結構 ### 專案結構
``` ```
local_tool/ local-tool/
├── .autoflow/ PRD / 設計 / 架構 / 進度文件 ├── .autoflow/ PRD / 設計 / 架構 / 進度文件
├── server/ Go 1.26 後端Gin + go:embed ├── server/ Go 1.26 後端Gin + go:embed
├── frontend/ Next.js 16 + React 19 + shadcn ├── frontend/ Next.js 16 + React 19 + shadcn

View File

@ -11,7 +11,7 @@
; 4. make exe — 執行 iscc 編譯本檔 ; 4. make exe — 執行 iscc 編譯本檔
; ;
; 所有路徑相對於本 .iss 所在目錄 (installer/windows/) ; 所有路徑相對於本 .iss 所在目錄 (installer/windows/)
; 因此 ..\.. 會指回專案根目錄 (local_tool/) ; 因此 ..\.. 會指回專案根目錄 (local-tool/)
#define MyAppName "visionA-local" #define MyAppName "visionA-local"
#define MyAppVersion "0.1.0" #define MyAppVersion "0.1.0"

View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
# visionA-local — Ubuntu 22.04/24.04 x86_64 一鍵 build
#
# 使用方式:
# git clone https://github.com/jim800121/visionA.git
# cd visionA/local-tool
# bash scripts/bootstrap-linux.sh
#
# 環境變數:
# VISIONA_TARGET 預設 appimage可設 wails-linux / payload-linux
set -euo pipefail
TARGET="${VISIONA_TARGET:-appimage}"
GO_VERSION="1.22.5"
log() { printf '\033[1;36m==> %s\033[0m\n' "$*"; }
err() { printf '\033[1;31m!!! %s\033[0m\n' "$*" >&2; exit 1; }
[[ "$(uname -s)" == "Linux" ]] || err "此腳本只支援 Linux"
[[ "$(uname -m)" == "x86_64" ]] || err "此腳本只支援 x86_64"
[[ -f Makefile && -d visiona-local ]] || err "請先 cd 到 local-tool/ 目錄再執行此腳本"
log "[1/5] 安裝系統套件(需要 sudo"
sudo apt update
sudo apt install -y \
git curl ca-certificates build-essential pkg-config \
libgtk-3-dev libwebkit2gtk-4.1-dev \
python3 python3-pip python3-venv \
file desktop-file-utils fuse libfuse2
log "[2/5] 安裝 Go $GO_VERSION"
if ! command -v go >/dev/null || [[ "$(go version 2>/dev/null)" != *"go$GO_VERSION"* ]]; then
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o /tmp/go.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf /tmp/go.tar.gz
rm /tmp/go.tar.gz
fi
export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"
if ! grep -q '/usr/local/go/bin' "$HOME/.bashrc" 2>/dev/null; then
echo 'export PATH=/usr/local/go/bin:$HOME/go/bin:$PATH' >> "$HOME/.bashrc"
fi
log "[3/5] 安裝 Node 20 + pnpm"
if ! command -v node >/dev/null || [[ "$(node -v)" != v20.* ]]; then
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
fi
command -v pnpm >/dev/null || sudo npm i -g pnpm
log "[4/5] 安裝 Wails CLI"
if ! command -v wails >/dev/null; then
go install github.com/wailsapp/wails/v2/cmd/wails@latest
fi
wails doctor || log "wails doctor 有警告,繼續"
log "[5/5] 開始 buildtarget=$TARGET"
log "⚠️ ffmpeg 使用 GPL build需設定 VISIONA_ALLOW_GPL_FFMPEG=1"
export VISIONA_ALLOW_GPL_FFMPEG=1
make vendor-python-linux vendor-wheels-linux vendor-ffmpeg-linux vendor-ytdlp-linux
make payload-linux
case "$TARGET" in
payload-linux) ;;
wails-linux) make wails-linux ;;
appimage|*) make wails-linux && make appimage ;;
esac
log "完成 ✅"
log "產出位置:$(pwd)/dist/"
ls -lh dist/ 2>/dev/null || true

View File

@ -0,0 +1,95 @@
# visionA-local — Windows 10/11 x86_64 一鍵 build
#
# 使用方式PowerShell 以「系統管理員」開啟):
# git clone https://github.com/jim800121/visionA.git
# cd visionA\local-tool
# powershell -ExecutionPolicy Bypass -File scripts\bootstrap-windows.ps1
#
# 環境變數:
# $env:VISIONA_TARGET 預設 exe可設 wails-windows / payload-windows
$ErrorActionPreference = 'Stop'
$Target = if ($env:VISIONA_TARGET) { $env:VISIONA_TARGET } else { 'exe' }
function Log($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Fail($msg) { Write-Host "!!! $msg" -ForegroundColor Red; exit 1 }
# 必須以系統管理員身份執行winget 需要)
$isAdmin = ([Security.Principal.WindowsPrincipal] `
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole] 'Administrator')
if (-not $isAdmin) { Fail '請以系統管理員身份執行 PowerShell 再跑此腳本' }
if (-not (Test-Path 'Makefile') -or -not (Test-Path 'visiona-local')) {
Fail '請先 cd 到 local-tool\ 目錄再執行此腳本'
}
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
Fail 'winget 未安裝。請先從 Microsoft Store 安裝「App Installer」'
}
function Ensure-Winget($id) {
$installed = winget list --id $id -e 2>$null | Select-String $id
if (-not $installed) {
Log "安裝 $id"
winget install -e --id $id --accept-source-agreements --accept-package-agreements
} else {
Log "$id 已安裝,跳過"
}
}
Log '[1/4] 安裝系統套件'
Ensure-Winget 'Git.Git'
Ensure-Winget 'GoLang.Go'
Ensure-Winget 'OpenJS.NodeJS.LTS'
Ensure-Winget 'Python.Python.3.12'
Ensure-Winget 'JRSoftware.InnoSetup'
Ensure-Winget 'MSYS2.MSYS2'
# 重新載入 PATHwinget 裝完目前 session 拿不到)
$env:Path = [System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + `
[System.Environment]::GetEnvironmentVariable('Path','User')
$env:Path += ";$HOME\go\bin;C:\msys64\usr\bin;C:\msys64\mingw64\bin"
Log '[2/4] 安裝 pnpm'
if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) {
npm i -g pnpm
}
Log '[3/4] 安裝 Wails CLI + 確認 MSYS2 make'
if (-not (Get-Command wails -ErrorAction SilentlyContinue)) {
go install github.com/wailsapp/wails/v2/cmd/wails@latest
}
wails doctor
if (-not (Test-Path 'C:\msys64\usr\bin\make.exe')) {
Log '安裝 MSYS2 make'
& 'C:\msys64\usr\bin\bash.exe' -lc 'pacman -Sy --noconfirm make'
}
Log "[4/4] 開始 buildtarget=$Target"
Log '⚠️ ffmpeg 使用 GPL build需設定 VISIONA_ALLOW_GPL_FFMPEG=1'
# Makefile 需要 bash + make透過 MSYS2 MinGW64 shell 執行
# 將 Windows 路徑 C:\foo\bar 轉成 MSYS2 路徑 /c/foo/bar
$projectPath = (Get-Location).Path
$msysPath = '/' + $projectPath.Substring(0,1).ToLower() + '/' + `
($projectPath.Substring(3) -replace '\\','/')
$bashCmd = "cd '$msysPath' && " +
"export VISIONA_ALLOW_GPL_FFMPEG=1 && " +
"make vendor-python-windows vendor-wheels-windows vendor-ffmpeg-windows vendor-ytdlp-windows && " +
"make payload-windows"
switch ($Target) {
'payload-windows' { }
'wails-windows' { $bashCmd += ' && make wails-windows' }
default { $bashCmd += ' && make wails-windows && make exe' }
}
& 'C:\msys64\usr\bin\bash.exe' -lc $bashCmd
if ($LASTEXITCODE -ne 0) { Fail "build 失敗exit code=$LASTEXITCODE" }
Log '完成 ✅'
Log "產出位置:$(Join-Path (Get-Location) 'dist')"
Get-ChildItem dist -ErrorAction SilentlyContinue | Format-Table Name, Length