### [2026-08-08] FIX: verify_bundle.py vẫn false-positive trên Windows — TOC là Python literal nên backslash bị DOUBLE-escape ('app\\\\static') - **Tóm tắt thay đổi:** Fix LAN 2 normalize `replace('\\','/')` 1 lần KHÔNG đủ: TOC file là Python literal (repr) → path Windows ghi thành `app\\\\static` (2 backslash trên disk) → replace 1 lần ra `app//static` → regex `app/static(?=[/'"])` không match → vẫn báo "Bundle thieu" DÙ bundle đủ. Fix: normalize 2 bước — `replace("\\\\","/")` (bắt double-escape) rồi `replace("\\","/")` (backslash đơn). Verify bằng TOC giả lập Windows repr: cả 2 entry match True. - **Các file ảnh hưởng:** `tools/verify_bundle.py` (dòng normalize) - **Ghi chú/Test (nếu có):** Test TOC Windows repr `'app\\\\static\\\\js\\\\app.js'` → normalize ra `app/static/js/app.js` → regex match. User: pull code mới rồi chạy lại build_windows.ps1 (bước 3.5 sẽ hết báo thiếu nếu bundle thực sự đủ). --- ### [2026-08-08] FIX (LAN 3 - GOC ROOT): 'app\\static does not exist' — sys.path thieu CWD khi chay 'pyinstaller' (entry point) - **Tóm tắt thay đổi:** Lỗi 'app\static does not exist' vẫn tái diễn dù đã 2 lần sửa datas (absolute path roi collect_data_files). Lần này tìm ra GOC ROOT THẬT SỰ: lệnh `pyinstaller engine.spec` (entry-point script cua PyInstaller) KHONG them CWD vao sys.path — chi `python -m PyInstaller` moi them. `collect_data_files('app')` import package 'app' qua sys.path -> khong thay -> tra ve [] AM THAM -> bundle thieu static/templates (dung canh: tren may dev chay `python -m PyInstaller` nen CWD co trong sys.path -> tuong da dung; may Windows chay `pyinstaller` -> CWD khong co -> collect rong -> TOC khong co app/static — dung voi loi verify cua user). Fix trong `engine.spec`: 1. `sys.path.insert(0, _SPEC_ROOT)` TRUOC khi goi collect_data_files — import 'app' luon hoạt dong bat ke CWD. 2. Fallback cuoi: neu collect_data_files van tra ve rong -> datas TINH absolute (app/templates, app/static, app/models) + in WARN de debug. - **Cac file anh huong:** `engine.spec` (sys.path insert + fallback datas tinh) - **Ghi chu/Test (neu co):** VERIFY DUNG DIEU KIEN THAT BAI: build tu /tmp (CWD khac project root — giong `pyinstaller` entry point khong co CWD trong sys.path) -> TOC co app/static (124) + app/templates (12), khong co WARN "tra ve rong"; tools/verify_bundle.py -> OK exit 0; chay binary frozen -> /health OK, index 200, static js 200. pytest 86 passed. User: pull engine.spec moi roi chay lai build_windows.ps1. --- ### [2026-08-08] FIX (lan 2): ERR_MODULE_NOT_FOUND '@babel/standalone' vẫn xảy ra — build_windows.ps1 TỰ cài dep nếu thiếu - **Tóm tắt thay đổi:** User vẫn gặp ERR_MODULE_NOT_FOUND '@babel/standalone' dù đã thêm vào package.json — máy Windows chưa pull package.json mới hoặc npm install chưa cài. Fix: `build_windows.ps1` bước [2/6] — sau `npm install`, TỰ KIỂM TRA `node_modules\@babel\standalone`; thiếu → `npm install @babel/standalone --no-audit --no-fund`; vẫn thiếu → ERROR + exit 1. Không còn phụ thuộc package.json mới trên máy user. - **Các file ảnh hưởng:** `build_windows.ps1` (bước 2 tự cài @babel/standalone) - **Ghi chú/Test (nếu có):** File ASCII-only + UTF-8 BOM (không lặp lỗi PS5.1), brace depth 0. User: pull build_windows.ps1 mới (hoặc toàn bộ) rồi chạy lại. --- ### [2026-08-08] FIX: build.mjs ERR_MODULE_NOT_FOUND '@babel/standalone' trên Windows — package.json thiếu dependency - **Tóm tắt thay đổi:** User chạy build_windows.ps1 (bước 2/6 node build.mjs) nhận `Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@babel/standalone' imported from build.mjs`. Root cause: `build.mjs` import `@babel/standalone` nhưng **package.json KHÔNG khai báo** dependency này (máy dev có sẵn trong node_modules từ trước nên không lộ; máy Windows `npm install` chỉ cài theo package.json → thiếu). Fix: thêm `"@babel/standalone": "^7.29.8"` vào dependencies + chạy `npm install` cập nhật `package-lock.json`. - **Các file ảnh hưởng:** `package.json` (+@babel/standalone), `package-lock.json` (npm install) - **Ghi chú/Test (nếu có):** npm install OK (up to date), package-lock có node_modules/@babel/standalone, `node build.mjs` BUILD OK 1123403 bytes + node --check OK. User: pull code mới rồi chạy lại build_windows.ps1. --- ### [2026-08-08] FIX: verify bundle [3.5/6] false-positive 'app/static thieu' + check spec version — tools/verify_bundle.py - **Tóm tắt thay đổi:** User chạy build_windows.ps1 — bước verify [3.5/6] mới báo "ERROR: Bundle thieu: app/static, app/templates" nhưng thực tế bundle ĐỦ (collect_data_files('app') đã hoạt động — verify bằng build Linux). Root cause: script verify cũ dùng regex `-notmatch "app/static"` trên raw TOC — trên Windows TOC chứa `app\static` (BACKSLASH) → regex forward-slash không match → FALSE POSITIVE báo thiếu. Fix: 1. **tools/verify_bundle.py** (mới): verify TOC bằng Python — đọc text, `replace('\\','/')` normalize backslash→forward, regex theo prefix `app/static(?=[/'"]|$)`; exit 0 OK / 1 thiếu; không có TOC → WARN + exit 0 (không chặn build). Test 4 case: backslash OK, forward OK, thiếu static → ERROR, không TOC → WARN. 2. **build_windows.ps1 [3.5/6]**: trước tiên check `engine.spec` có chứa `collect_data_files('app')` — nếu spec CŨ (chưa pull code mới) → báo rõ "engine.spec CU... Pull code moi" + exit 1 (tránh nhầm lẫn nguyên nhân). Sau đó chạy `python tools\verify_bundle.py` + check `$LASTEXITCODE`. - **Các file ảnh hưởng:** `tools/verify_bundle.py` (mới), `build_windows.ps1` (bước 3.5 gọi script + check spec) - **Ghi chú/Test (nếu có):** verify_bundle.py test 4 case đều đúng; chạy với TOC THẬT (build Linux PyInstaller 6.21) → "Thiếu: KHÔNG — OK". Binary frozen: /health OK, index 200, static js 200. pytest 86 passed. User: pull code mới (có tools/verify_bundle.py) rồi chạy lại build_windows.ps1. --- ### [2026-08-08] FIX: build_windows.ps1 lỗi parse PowerShell — "String is missing terminator" (file chứa ký tự Unicode, PS 5.1 đọc theo ANSI) - **Tóm tắt thay đổi:** User chạy build_windows.ps1 trên Windows nhận ParserError "String is missing terminator" ở dòng 57 + "Missing closing '}'" ở dòng 34. Root cause: bản mình thêm bước verify [3.5/6] có chứa ký tự Unicode (em-dash `—` trong comment + chuỗi tiếng Việt có dấu "thiếu/Dừng/kiểm tra"). PowerShell 5.1 đọc file .ps1 KHÔNG có BOM theo ANSI/Windows-1252 → byte UTF-8 của `—` (E2 80 94) giải mã thành `â€"` — dấu ngoặc kép giả chui vào giữa chuỗi → chuỗi "mất terminator" + block `{}` lệch. Fix: 1. Viết lại toàn bộ build_windows.ps1 **chỉ ASCII** (bỏ dấu tiếng Việt, bỏ em-dash, dùng `->`). 2. Thêm **UTF-8 BOM** (EF BB BF) vào đầu file — PowerShell đọc đúng encoding bất kể. 3. Giữ nguyên bước verify [3.5/6] (TOC check app/static + app/templates). - **Các file ảnh hưởng:** `build_windows.ps1` (ASCII-only + BOM) - **Ghi chú/Test (nếu có):** File giờ 0 ký tự non-ASCII, có BOM; brace depth = 0 (cân bằng), không có dòng Write-Host quote lẻ. Lưu ý chung: MỌI .ps1/.bat trong dự án phải ASCII-only + BOM (PS 5.1 ANSI bug) — tránh tiếng Việt có dấu/em-dash trong file script Windows. --- ### [2026-08-08] FIX (LẦN 2): Windows exe vẫn crash 'app\static does not exist' + stuck 'Đang khởi động Engine' — bundle qua collect_data_files + fallback + verify build - **Tóm tắt thay đổi:** User build bản Windows vẫn gặp RuntimeError `Directory '..._MEIxxxx\app\static' does not exist` (lần 2 — fix trước dùng datas ABSOLUTE theo SPECPATH nhưng trên máy user vẫn thiếu static trong bundle) + UI stuck "Đang khởi động SonicForge Engine". 3 lớp phòng thủ: 1. **engine.spec — bundle qua IMPORT SYSTEM**: bỏ datas đường dẫn tĩnh, thay bằng `collect_data_files('app', excludes=['**/storage/**','**/__pycache__/**','**/*.pyc'])` — PyInstaller tự tìm assets (static/templates/models) qua package import, KHÔNG phụ thuộc CWD/SPECPATH lúc chạy lệnh (nguyên nhân gốc: chạy pyinstaller từ thư mục khác → relative path không resolve → bỏ qua âm thầm). Loại luôn `app/storage` (57MB soundfonts — vô ích trong onefile, config.py đã redirect %APPDATA%). Giữ `md/` (ngoài package) + librosa .pyi. 2. **app/main.py — fallback an toàn**: nếu STATIC_DIR không tồn tại → thử `sys._MEIPASS/app/static` và `dirname(__file__)/static`; vẫn thiếu → **tự os.makedirs** → StaticFiles không còn crash lúc import (engine không chết, app hiện lỗi rõ thay vì 6 hộp thoại + stuck loader). 3. **build_windows.ps1 — verify post-build [3.5/6]**: sau pyinstaller, đọc Analysis-00.toc kiểm tra `app/static` + `app/templates` có trong bundle — thiếu → in ERROR đỏ + `exit 1` (bắt lỗi NGAY lúc build, không đợi chạy app mới vỡ). - **Các file ảnh hưởng:** `engine.spec` (collect_data_files('app') + bỏ storage), `app/main.py` (fallback static dir), `build_windows.ps1` (verify TOC post-build) - **Ghi chú/Test (nếu có):** VERIFY THẬT trên Linux (PyInstaller 6.21, cùng spec): Analysis-00.toc chứa app/static (124), app/templates (12), app/models (5); exe 155MB (giảm 57MB); chạy binary frozen → /health OK, index 200, static js 200, favicon 200, không crash. pytest 86 passed. User cần chạy lại `build_windows.ps1` (bước 3.5 sẽ tự kiểm tra bundle). --- ### [2026-08-08] IMPROVE: About modal — logo dùng favicon của app (app/templates/favicon.svg, serve /favicon.svg) - **Tóm tắt thay đổi:** User yêu cầu logo trong About modal phải là logo của web/app — favicon lưu trong hệ thống. Trước đây AboutModal dùng div gradient chữ "SF". Fix: thay bằng `` (route đã có sẵn trong app/main.py — serve từ TEMPLATES_DIR; file app/templates/favicon.svg, SVG 1254x1254). Hiển thị 48x48 object-contain, nền tối + border cho nổi trên modal. - **Các file ảnh hưởng:** `app/static/js/app.jsx` (AboutModal img), `app/static/js/app.precompiled.js` (rebuild), `app/templates/index.html` (bump v=202608081600) - **Ghi chú/Test (nếu có):** BUILD OK 1123403 bytes, node --check OK, pytest 86 passed. Verify: /favicon.svg 200 image/svg+xml, bundle chứa "favicon.svg". --- ### [2026-08-08] FEAT: Menu Help (About + Hướng dẫn sử dụng) + Tools → Preferences (Theme/Language/Button font size) - **Tóm tắt thay đổi:** User yêu cầu 2 nhóm tính năng: 1. **Menu Help**: - `About SonicForge Studio...` → **AboutModal** mới: dev **Lộc Phạm**, email **tranloclqd@gmail.com**, version `1.0.0` (khớp tauri.conf.json), build Standalone (Tauri v2 + PyInstaller). - `Hướng dẫn sử dụng...` → **HelpModal** mới: 8 mục hướng dẫn song ngữ (vi/en theo language preference): Bắt đầu nhanh, MIDI & ARM, Piano Roll, FX & Master, SoundFont & VST, AI, Lưu & Xuất, Phím tắt. 2. **Tools → Preferences...** → **PreferencesModal** mới quản lý: - **Theme** (5 preset): dark (mặc định), midnight, forest, violet, graphite — áp qua `data-theme` trên `` + CSS variables `--sf-bg/--sf-panel/--sf-header/--sf-border/--sf-accent` (thêm trong index.html `