|
|
30d0ff5695
|
fix(local-tool): 推論 bbox 標註不顯示 — 前端 canvas 尺寸 + KL520 reset + 延長 timeout
症狀:Mac 版上傳單張圖推論,畫面完全沒有 bbox 標註。實測追根因後發現
兩層獨立問題疊加(前端 + 後端),擇一修復都無法解決。
## Layer 1: 前端 canvas 尺寸對不上 img 顯示尺寸
- camera-inference-view.tsx renderedSize 初始值硬寫 {w:640, h:480}
- ResizeObserver 理應在 <img> load 後 fire,但實測沒 fire 或時機不對
- 結果 overlay canvas 永遠用 640×480 畫,bbox 嚴重偏位或跑出 canvas
修法(camera-feed.tsx + camera-inference-view.tsx):
- <img> 加 onLoad handler,decode 完立刻用 getBoundingClientRect 回報
- ResizeObserver effect 進來先檢查 img.complete && naturalWidth > 0,
是就立刻 report(cover HMR / cached image)
- effect 依賴加 streamUrl / batchImageUrl,換圖會重觀察
- renderedSize 初始值改 null,overlay 改為拿到真實尺寸才 render
- setState callback 用 prev 比對,同尺寸不觸發 render
- camera-overlay.tsx 加 [bbox-debug] console.log 保留(debug 成本低,
對未來排查有幫助)
## Layer 2: KL520 推論炸 ApiKPException Error 15
- kp.inference.generic_image_inference_send 回 SEND_DATA_TOO_LARGE
- 試過 image 尺寸(516×640 / 640×794 / 640×640 host pad)、numpy vs
bytes、明確傳 width/height — 全部炸
- Python bridge 直接測試(/tmp/test_bridge.py)做完整
`connect → reset → reconnect → load_model → inference` 序列 → 11 個
detection 正常回傳
- Go driver 走 `connect → load_model → inference` 跳過 reset
根因:commit ddf0eb8(2026-04-16)「KL520 首次 connect 跳過 reset」當時
為解 Windows 60s HTTP timeout 的優化。但副作用:KL520 若 session 間
firmware 殘留(fw=KDP2 Comp/U),直接 load_model + inference 100% 炸
Error 15。必須走完整 reset → 退回 Loader → 重新載 firmware → Comp/U
流程才能得到能 inference 的 session。
修法(kl720_driver.go):
- 移除「KL520 跳過 reset」特例,讓 KL520 和 KL720 都走 needsReset → restartBridge
- 註解記錄 trade-off:KL520 connect 時間 ~2s → ~15-20s(macOS),
Windows 可能 60s+
## HTTP timeout 配套調整
- device_handler.go ConnectDevice timeout 60s → 120s
- Windows worst-case(~65s:Loader reconnect 16s + firmware load 31s +
reboot 8s + reconnect 5s)留 buffer,避免 504 CONNECT_TIMEOUT
## Bridge 清理
- kneron_bridge.py 清掉中途試驗遺留的 `_host_preproc` 死碼
(還原成原版 _correct_bbox_for_letterbox)
- 加了 debug log(Inference: sending / parse done / EXCEPTION with
traceback)保留,未來排查 inference 路徑很有用
## 驗證(function 層)
/tmp/test_bridge.py 三種尺寸全通過:
- 516×640 直式 → 11 detections (person×8, tie×3) latency 308ms
- 1920×1080 横式 → 0 detections(合成圖,正常)
- 512×512 正方 → 0 detections
## 待使用者驗證
- Mac UI 實測:上傳 ~/Downloads/000000000459.jpg 應見 11 個 bbox 精準框住
- Windows 實測 connect 耗時 + timeout 是否足夠
- Linux 實測
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-21 01:12:10 +08:00 |
|
|
|
372259b4b1
|
fix(local-tool): 載入模型 dialog 點灰色區域不再關閉
使用者回報點 dialog 周圍灰色 overlay 會誤關 popup。
修法:flash-dialog 的 DialogContent 加:
- onInteractOutside: 永遠 preventDefault(灰色區域點擊不關)
- onEscapeKeyDown: 載入中 preventDefault(載入完成後可 Esc 關)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-16 23:43:34 +08:00 |
|
|
|
db272cac5a
|
feat(local-tool): Linux udev rule 未安裝偵測 + 一鍵安裝 UX
使用者在 Ubuntu 上 scan 不到 Kneron 裝置。根因:Linux 預設 USB 裝置
權限是 root only,非 root 使用者的 kp.core.scan_devices 因 permission
denied 而 silently 回傳 0 裝置。需要安裝 udev rule。
修法三層:
1. Server:GET/POST /api/devices 在 Linux + 0 裝置 + udev rule 不存在
時帶 udevHint: true
2. 新增 POST /api/system/install-udev:用 pkexec 提權安裝 99-kneron.rules
+ reload udev(彈 Linux 圖形化密碼對話框)
3. 前端 devices page:udevHint=true 時顯示 amber 色 banner 提示 +
一鍵安裝按鈕,成功後自動 rescan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-16 23:20:28 +08:00 |
|
|
|
8cd5751ce3
|
feat(local-tool): M8 重構 — Wails 控制台 + 瀏覽器 Web UI(R5 決策)
依 R5 五輪決策把 visionA-local 從「Wails 內嵌 Next.js」重構為「Wails
本機伺服器控制台 + 瀏覽器 Web UI」模式(類比 Docker Desktop / Ollama)。
程式碼變動
- M8-1 砍 yt-dlp 全套(後端 resolver / URL handler / 前端 URL tab /
Makefile vendor / installer / bootstrap / CI workflow,-555 行)
- M8-2 砍 Mock 模式全套(driver/mock、mock_camera、Settings runtimeMode、
VISIONA_MOCK 環境變數,-528 行)
- M8-3 ffmpeg 從 GPL 切換到 LGPL 混合方案:Windows/Linux 用 BtbN 現成
LGPL binary,macOS 自 build minimal decoder-only 進 git
(vendor/ffmpeg/macos/ffmpeg 5.7MB + ffprobe 5.6MB,比 GPL 版省 85% 空間)
- M8-4 Wails Server Controller:state machine、log ring buffer 2000 行、
preferences.json atomic write、boot-id、Gin SkipPaths、shutdown 7+1 秒、
notify_*.go 三平台 OS 通知、watchServer 改 Error state 不 os.Exit
- M8-4b 啟動階段管線 R5-E:6 階段進度 event、20s soft / 60s hard timeout、
stage 5/6 skip 規則、sentinel file、RestartStartupSequence 5 步驟
- M8-5 Wails 控制台 vanilla HTML/JS/CSS(9 檔 ~2012 行)取代 M7-B splash:
state 視覺、log panel、startup progress panel、Stage 6 manual CTA
pulse、shutdown modal、Settings、Dark Mode、i18n 中英雙語
- M8-6 上傳影片副檔名擴充(mp4/avi/mov/mpeg/mpg)
- M8-7 Web UI Server Offline Overlay(role=alertdialog + focus trap +
wsEverConnected 容錯 + Page Visibility)
- M8-8 CORS middleware(127.0.0.1/localhost only + suffix attack 防護)+
ws/origin.go 獨立 WebSocket CheckOrigin 避 package cycle
- MAJ-4 server:shutdown-imminent WebSocket broadcast 機制
(/ws/system endpoint + notifyShutdownImminent helper)
- M8-9 Boot-ID + 瀏覽器 tab 自動重連(sessionStorage loop guard)
品質
- ~105+ 新 unit test + race detector (-count=2) 全綠
- 10 個 milestone 全部通過 Reviewer 審查
- 三方 v2 + v2.1 文件(PRD / Design Spec / TDD)+ 交叉互審紀錄
收錄在 .autoflow/
交付前待處理(M8-10)
- 重跑 make payload-macos 把舊 GPL 77MB binary 換成新 LGPL
- 三平台 end-to-end build 驗證
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-15 17:57:54 +08:00 |
|
|
|
a6b71ea908
|
fix(local-tool): URL 影片載入提示「正在解析,請耐心等待」
URL 送出後 yt-dlp 解析 + ffmpeg probe 可能花 10-30 秒,
使用者只看到按鈕 loading 會以為卡住。
加一行黃色 animate-pulse 提示:
「正在解析影片連結,YouTube 影片可能需要 10-30 秒,請耐心等待...」
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-13 00:57:03 +08:00 |
|
|
|
f13848cf0b
|
fix(local-tool): workspace 推論面板跑版 — 右側面板固定寬度
右側 InferencePanel 沒設寬度也沒 shrink-0,被左側 CameraInferenceView
擠壓到只剩幾十 px,文字垂直排列。
修法:
- InferencePanel 外層加 w-80 shrink-0(固定 320px 不縮小)
- CameraInferenceView 外層加 min-w-0(允許 flex item 收縮到 0)
- gap-6 改 gap-4(省一點空間)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 23:36:20 +08:00 |
|
|
|
c24a04cdb2
|
fix(local-tool): Review minor m1/m2/m4 修復
m1(i18n 混用不一致):
- flash-dialog.tsx 所有英文字串改繁中(載入模型 / 選擇模型 / 硬體不相容 / 開始載入 / 關閉 / 完成)
- flash-progress.tsx 同理(模型載入失敗 / 重試 / 正在準備載入 / 模型載入完成)
m2(Dialog 關閉防護不完整):
- 改用 isInProgress 判斷(isFlashing || progress 未到 100%)+ 沒 error
而非只看 isFlashing,涵蓋「API 回應了但 WS 進度還在跑」的情況
m4(WS 3 秒 timeout 應 reject):
- connectAndWait timeout 改 reject + Error message
- flash-dialog handleFlash 加 try/catch 捕捉 WS 連線失敗
→ 呼叫 setError 讓 UI 顯示錯誤而非靜默卡住
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 20:21:18 +08:00 |
|
|
|
3c6971febd
|
fix(local-tool): Review M1-M4 + m5 修復 — flash 生命週期 + store 隔離
Review 問題修復:
M1(寫已關閉 channel panic):
- flash service goroutine 改成先等 driver.Flash() 返回,再寫 error 訊息,最後 close
- driver.Flash 返回後保證不再寫 progressCh,消除 race condition
M2(FlashTask 永不清除 memory leak):
- service.go 新增 CleanupTask(taskID) 公開方法
- device_handler.go 的 goroutine 在 `for range progressCh` 結束後呼叫 CleanupTask
M3(同裝置重複 flash taskID 衝突):
- ProgressTracker.Create 改成:舊 task 未完成時返回 nil
- StartFlash 檢查 nil → 回傳 "flash already in progress" 錯誤
M4(前端 flash store 全域不區分 deviceId):
- flash-store.ts 新增 activeDeviceId 欄位
- updateProgress 改接 (deviceId, progress),比對 activeDeviceId 防止混裝
- use-flash-progress.ts 的 WebSocket callback 傳入 deviceId
m5(flash_ws.go 雙重 conn.Close):
- read pump goroutine 移除 defer conn.Close(),由外層 defer 統一關閉
額外修復(S4):
- modelPath 為空時直接回 error 而非傳無效路徑給 driver
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 20:16:24 +08:00 |
|
|
|
44711753ae
|
feat(local-tool): 推論功能完整搬入 — flash 模組 + workspace 推論介面
## 後端(Phase 1)
新增 flash 模組(從 edge-ai-platform 搬入):
- server/internal/flash/service.go:StartFlash + 模型相容性檢查 + 晶片 NEF 解析
- server/internal/flash/progress.go:Flash 進度追蹤器
- server/internal/api/ws/flash_ws.go:WebSocket 推送 flash 進度
- device_handler.go:新增 FlashDevice method + flashSvc 欄位
- router.go:新增 POST /api/devices/:id/flash + WS /ws/devices/:id/flash-progress
- main.go:初始化 flash.NewService 並傳入 router
推論/攝影機/MJPEG/inference WebSocket 之前 M1 已搬好,不需改動。
Python bridge (kneron_bridge.py) 與 edge-ai-platform 完全相同,不需改動。
## 前端 store + hooks(Phase 2)
- stores/flash-store.ts(新):Zustand store — startFlash / updateProgress / retryFlash / reset
- hooks/use-flash-progress.ts(新):WebSocket hook 接收 flash 進度
inference-store / camera-store / inference types / use-inference-stream / use-websocket
之前 M1 已搬好,不需改動。
## 前端 UI 元件(Phase 3)
- components/devices/flash-dialog.tsx(新):模型載入對話框 + 硬體相容性檢查
- components/devices/flash-progress.tsx(新):Flash 進度條 + 錯誤重試
camera-inference-view / camera-feed / camera-overlay / source-selector /
inference-panel / performance-metrics / classification-result / confidence-slider /
video-progress / batch-image-thumbnails 之前 M1 已搬好。
## 前端頁面整合(Phase 4)
- workspace/page.tsx:繁中硬編碼、顯示已載入模型名稱
- workspace/[deviceId]/workspace-client.tsx:加入 FlashDialog 按鈕 + 繁中硬編碼
- devices/[id]/device-detail-client.tsx:加入 FlashDialog + 「進入工作區」按鈕(模型已載入才顯示)
- device-card.tsx:已連線 + 模型已載入時顯示「工作區」快捷按鈕
## 使用者操作流程
裝置列表 → 連線 → 管理 → 載入模型 → 進入工作區 → 選攝影機/圖片/影片 → 開始推論 → 看 bounding box / FPS / latency
或:裝置列表 → 工作區(已有模型)→ 直接推論
## 不搬的東西
- cluster/* 全部不搬(已砍 cluster 功能)
- relay / tunnel 相關不搬
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 20:07:09 +08:00 |
|
|
|
ebe86663b1
|
fix(local-tool): i18n type error — 用 devices.status.connecting/disconnecting
devices.connecting / devices.disconnecting 不在 TranslationDict type 裡,
改用已存在的 devices.status.connecting + 新增 devices.status.disconnecting。
刪掉上一個 commit 多加的頂層 devices.connecting / disconnecting key。
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 19:11:36 +08:00 |
|
|
|
ae5dfe1739
|
fix(local-tool): 連線 loading + 資料目錄平台路徑 + 卡片排版
A. 連線 / 斷線按鈕加 loading state:
- device-store.ts 新增 connectingId / disconnectingId state
- connectDevice / disconnectDevice 用 try/finally 包裹確保 reset
- device-card.tsx 按鈕加 Loader2 spinner + disabled
當任一裝置正在連線/斷線時所有按鈕都 disabled,防止連按
- i18n 新增 connecting / disconnecting 字串
C. 設定 > 一般 > 資料目錄顯示平台正確路徑:
- 用 navigator.userAgent 偵測平台
- Windows: %APPDATA%\visiona-local
- Linux: ~/.local/share/visiona-local
- macOS: ~/Library/Application Support/visiona-local
- 修正 Python 版本顯示 3.11 → 3.12
D. 裝置卡片排版修正:
- 名稱和狀態 badge 之間加 gap-3
- 名稱區域 min-w-0 + truncate 防止 badge 被擠到換行
- 連線中時 badge 顯示 connecting 狀態
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 18:57:06 +08:00 |
|
|
|
9b0d946acd
|
feat(local-tool): splash 顯示實時啟動進度 + 拉長 timeout + 修正執行模式顯示
Splash 進度:
- app.go 新增 bootstrapStatus field + GetBootstrapStatus() binding
- 各 startup step 呼叫 setBootstrapStatus 更新文字:
"正在初始化 Python 環境..."
"正在解壓 Python runtime (~10 秒)..."
"正在建立 Python 虛擬環境 (~5 秒)..."
"正在安裝 N 個 Python 套件 (numpy / opencv / KneronPLUS ...) (~30-60 秒)..."
"正在安裝 Kneron USB 驅動程式 (請在 UAC 視窗點「是」)..."
"正在準備應用程式資料..."
"正在啟動伺服器..."
"等待伺服器就緒..."
"載入主介面..."
- visiona-local/frontend/app.js 每 400ms 呼叫 GetBootstrapStatus 更新畫面
- wailsjs/go/main/App.js 手動補上新 binding export(避免等 wails generate)
Timeout:
- splash MAX_WAIT_MS 60s → 240s(涵蓋 UAC 被拖延 + 慢速硬碟)
- healthCheckTimeout 15s → 30s(server 首次啟動內部解析 + embed fs 載入)
設定 > 硬體 > 執行模式:
- 顯示預設值從 mock 改為 real(跟 app.go 實際預設對齊 - Q8 決策)
- 下拉選單寬度 240 → 420px 避免文字被截斷
- i18n 說明文字改為「預設為真實硬體模式,強制 Mock 請設 VISIONA_MOCK=1」
- 仍標 disabled — 未來 M8+ 會連 backend GET /api/system/config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 08:42:59 +08:00 |
|
|
|
4902cb5531
|
feat(local-tool): Kneron WinUSB driver 透過 KneronPLUS SDK libwdi 安裝
根因:
KP_ERROR_CONNECT_FAILED (error code 28) — Kneron USB 裝置預設沒綁定
WinUSB driver,SDK 無法開 handle。原 .iss 的 pnputil /add-driver 做法
需要 .cat 簽章(Windows 10/11 driver signing enforcement),我們沒有。
參考 edge-ai-platform/installer/platform_windows.go 的 installKneronDriverViaSDK:
KneronPLUS SDK 內建 libwdi wrapper — kp.core.install_driver_for_windows(pid)
libwdi 會自動用臨時自簽憑證,不需要 .cat 檔,只需要 UAC 提權。
實作:
- server/internal/api/handlers/system_driver_windows.go(新):
組 Python script → kp.core.install_driver_for_windows 對 KL520/KL720/KL720_LEGACY →
PowerShell Start-Process -Verb RunAs 提權執行 → 結果寫 temp 檔讀回
- server/internal/api/handlers/system_driver_other.go(新):非 Windows stub
- system_handler.go: NewSystemHandler 新增 pythonBin 參數 + InstallDriver handler
先判斷 runtime.GOOS==windows 才執行
- router.go: 新增 POST /system/install-driver
- main.go: 解析 pythonBin(VISIONA_PYTHON env var → cfg.PythonBin)傳入
前端:
- frontend/src/app/devices/page.tsx:Windows only 多一個「安裝 USB Driver」按鈕
(用 navigator.userAgent 判斷平台)
- frontend/src/stores/device-store.ts:connect 失敗訊息偵測 winusb / error 28 /
KP_ERROR_CONNECT_FAILED 特徵字串,回一條明確的繁中提示引導使用者去點按鈕
Wails app 端:
- visiona-local/app.go: 新增 InstallKneronDriver() binding 作為備用入口(目前前端沒用到,
因為前端跑在 http://127.0.0.1 不是 wails://,但保留給未來 splash 階段觸發用)
- visiona-local/platform_{windows,darwin,linux}.go: installKneronWinUSBDriver 平台實作
/ 跨平台 stub
.iss:
- 移除 pnputil /add-driver 的 [Run] entry(它是 silent-fail 的 dead code,
因為沒 .cat 簽章)
- 新增註解說明:driver 安裝改由 app 端呼叫 libwdi 完成
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 05:25:32 +08:00 |
|
|
|
f8533a6b04
|
fix(local-tool): sidebar icon + Wails Windows icon.ico + 掃裝置路徑修復
sidebar E icon:
- frontend/src/components/layout/sidebar.tsx 左上角的 "E" 方塊換成 <img> 指向
/visiona-logo.png,從 frontend/public/visiona-logo.png serve
Wails 桌面/工作列 icon:
- 把 branding/icon.ico 複製到 visiona-local/build/windows/icon.ico
- Wails v2 Windows build 偵測到這個檔案就會直接用它當 exe embedded icon,
不再從 appicon.png 自動 resize(解析度更好)
掃裝置根因修復:
1. server main.go:新增 resolveBridgeScript() 智慧找 kneron_bridge.py
- 優先 <exe>/scripts/kneron_bridge.py
- fallback <exe>/../scripts/... 對應 Windows installer 的 {app}\bin\ + {app}\scripts\ 佈局
- fallback <exe>/../Resources/scripts/... 對應 macOS app bundle
2. server kneron/detector.go:ResolvePython 重寫
- 最高優先:VISIONA_PYTHON 環境變數(由 Wails 殼層注入)
- 加入 visiona-local 新路徑:%APPDATA%\visiona-local\runtime\venv、
~/Library/Application Support/visiona-local/runtime/venv、
~/.local/share/visiona-local/runtime/venv
- 保留 edge-ai-platform 舊路徑作為 legacy fallback
3. visiona-local/app.go:spawn server 時 export VISIONA_PYTHON=<pyBin>
讓 detector 直接用 Wails 殼層已經 resolve 好的 python interpreter,
不再自己獨立去找造成不一致。
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 04:59:23 +08:00 |
|
|
|
50a3f73acd
|
feat(local-tool): 品牌視覺設計 + 內建模型首次啟動 seed
#8 首次啟動 seed 內建模型:
- app.go 新增 seedUserDataDir() 在 server spawn 之前執行
- 若 user data-dir 缺 models.json,從 locateBundleDataDir() 複製
models.json + nef/ 預置模型過去
- 新增 locateBundleDataDir() / copyFile() / copyDirRecursive() helper
- user 第一次開 app 會看到 8 個 Kneron 預置 .nef 模型(kl520×5 + kl720×3)
#5 #6 #7 品牌視覺:
- 新增 branding/ 目錄存放設計資產與生成工具
- logo.svg(向量原始稿)
- icon-{16,...,1024}.png(10 種尺寸)
- icon.ico(Windows 多解析度 ICO,PNG-in-ICO 格式)
- icon.icns(macOS)
- tools/gen_icon.go + gen_ico.go(純 Go 生成工具,未來調整 logo 用)
- README.md + 色票表
- 部署:
- visiona-local/build/appicon.png → Wails build 會嵌入 exe
- visiona-local/frontend/icon.png → splash 使用
- frontend/src/app/favicon.ico + icon.png → Next.js App Router favicon
- splash page 升級:加 logo icon + 品牌名 visionA Local + tagline Edge AI Workspace
- Wails window title: "visionA Local — Edge AI Workspace"
- wails.json productName: "visionA Local"
- Next.js metadata title + icons
- i18n: en/zh-TW 把殘留的 "Edge AI 平台" 字串改為 visionA Local 品牌
- .iss: SetupIconFile 指向 branding/icon.ico + UninstallDisplayIcon +
ArchitecturesAllowed 改 x64compatible 修掉之前的 deprecation warning
品牌色票:
- 主色 #4F7EFF(電子藍)
- 輔色 #6EF3C5(mint 點綴)
- 深色背景漸層 #1A1F36 → #0E1222
- 警示 #FF6B6B
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-12 04:42:41 +08:00 |
|
|
|
c54f16fca0
|
Initial commit: visionA monorepo with local-tool subproject
local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
Wails IPC raise endpoint, stale process cleanup
.autoflow/: full PRD / Design Spec / Architecture / Testing docs
(4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-11 22:10:38 +08:00 |
|