From b6db4f172046714dde4b9a1bbef5c9ae2456759f Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 01:10:48 +0800 Subject: [PATCH 001/133] chore(task): add fmp-rewrite parent task and audit child task --- .trellis/tasks/09-26-audit/check.jsonl | 0 .trellis/tasks/09-26-audit/implement.jsonl | 0 .trellis/tasks/09-26-audit/prd.md | 40 ++++ .trellis/tasks/09-26-audit/task.json | 26 +++ .trellis/tasks/09-26-fmp-rewrite/check.jsonl | 0 .../tasks/09-26-fmp-rewrite/implement.jsonl | 0 .trellis/tasks/09-26-fmp-rewrite/prd.md | 216 ++++++++++++++++++ .trellis/tasks/09-26-fmp-rewrite/task.json | 28 +++ 8 files changed, 310 insertions(+) create mode 100644 .trellis/tasks/09-26-audit/check.jsonl create mode 100644 .trellis/tasks/09-26-audit/implement.jsonl create mode 100644 .trellis/tasks/09-26-audit/prd.md create mode 100644 .trellis/tasks/09-26-audit/task.json create mode 100644 .trellis/tasks/09-26-fmp-rewrite/check.jsonl create mode 100644 .trellis/tasks/09-26-fmp-rewrite/implement.jsonl create mode 100644 .trellis/tasks/09-26-fmp-rewrite/prd.md create mode 100644 .trellis/tasks/09-26-fmp-rewrite/task.json diff --git a/.trellis/tasks/09-26-audit/check.jsonl b/.trellis/tasks/09-26-audit/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-26-audit/implement.jsonl b/.trellis/tasks/09-26-audit/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-26-audit/prd.md b/.trellis/tasks/09-26-audit/prd.md new file mode 100644 index 000000000..923b13234 --- /dev/null +++ b/.trellis/tasks/09-26-audit/prd.md @@ -0,0 +1,40 @@ +# 階段一:現況審計(唯讀) + +## 目標 + +讓使用者重新掌握 FMP 現況:產出 `docs/audit/` 下 12 份審計文件,作為階段二目標設計的事實基礎。 +完整需求見 parent task `09-26-fmp-rewrite/prd.md` §「階段一」與 §「信任規則」,本檔不重述。 + +## 範圍與約束 + +- 只新增 `docs/audit/` 與 `.trellis/tasks/` 下的檔案;分支 `docs/audit`。 +- 全部繁體中文,圖用 Mermaid;每份檔案開頭註明「現況描述,未經確認,不代表目標」。 +- 證據優先序:實際執行的 App 行為 > 程式碼 > 測試 > 文檔/註釋;每個結論附 `檔案:行號`、log 或截圖。 +- repo 內既有文檔、ADR、CONTEXT.md、spec、static-rule 測試都只是線索,需用代碼驗證; + 不一致兩邊都列並標「不一致」;推測標「推測」;查不到寫查不到。 +- 套件平台支援以 pub.dev/官方文檔為準。 +- 跑測試一律 `--exclude-tags live`,不為審計打真實 API。 + +## 交付物 + +`docs/audit/` 下:`features.md`、`architecture.md`、`playback.md`、`sources.md`、`errors.md`、 +`data.md`、`downloads.md`(補充)、`accounts-network.md`、`platforms.md`、`ui.md`、`devtools.md`、`engineering.md`、 +`questions.md`,另加 `README.md` 作為索引與一頁摘要。 + +## 補充需求(2026-09-26) + +見 parent PRD 階段一 6a、7、12 的「補充」段: +- 新增 `downloads.md`(下載序列圖、音質/檔名/metadata/分 P、路徑設定與失效、已下載檔案的播放與清理、各平台權限); +- `accounts-network.md` 補帳號系統全貌序列圖、「請求類型 × 音源」憑證矩陣、登入/未登入能力差異; +- `questions.md` 補下載、權限、帳號、「用登入狀態播放」相關決策。 +- 已寫在其他審計檔案的內容只引用,不重寫。 + +## 驗收標準 + +- [ ] 13 份文件(含補充的 `downloads.md`)齊全,各自覆蓋 parent PRD 對應條目列出的每一小項(做不到的明寫原因)。 +- [ ] 每份文件開頭有「現況描述,未經確認,不代表目標」。 +- [ ] 結論皆附證據;文檔/代碼不一致處標「不一致」;推測標「推測」。 +- [ ] `questions.md` 含 parent PRD 列出的必備項(每份 ADR、每個 CONTEXT.md 術語、平台綁定功能、 + 測試類別、資料層、i18n 語言、發佈管道),按影響大小排序。 +- [ ] `git diff main --stat` 只含 `docs/audit/` 與 `.trellis/tasks/`。 +- [ ] 結束時給使用者一頁摘要與最需先決定的 10 件事,然後停下等回覆。 diff --git a/.trellis/tasks/09-26-audit/task.json b/.trellis/tasks/09-26-audit/task.json new file mode 100644 index 000000000..2c9ffbd1e --- /dev/null +++ b/.trellis/tasks/09-26-audit/task.json @@ -0,0 +1,26 @@ +{ + "id": "audit", + "name": "audit", + "title": "Phase 1 audit", + "description": "Read-only audit of current FMP state into docs/audit/", + "status": "in_progress", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-26", + "completedAt": null, + "branch": "docs/audit", + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file diff --git a/.trellis/tasks/09-26-fmp-rewrite/check.jsonl b/.trellis/tasks/09-26-fmp-rewrite/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-26-fmp-rewrite/implement.jsonl b/.trellis/tasks/09-26-fmp-rewrite/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-26-fmp-rewrite/prd.md b/.trellis/tasks/09-26-fmp-rewrite/prd.md new file mode 100644 index 000000000..3f052b109 --- /dev/null +++ b/.trellis/tasks/09-26-fmp-rewrite/prd.md @@ -0,0 +1,216 @@ +# 背景 +FMP 是 Flutter 音樂播放器(目前支援 Android + Windows),音源為 Bilibili / YouTube / 網易雲。 +過去經過多輪 AI Agent 自主修改(約 1,900 個 commit、約 10 萬行 Dart),大部分我沒有 review 過, +我已不清楚程式實際在做什麼。 + +目標分三步:先讓我重新掌握現況 → 確認目標架構 → 按成熟做法重構/重寫, +讓代碼盡量簡單、邏輯統一、容易擴充。 + +長期目標是全平台:Android、Windows、Linux、macOS、iOS。 +目前我沒有 Mac 和 iPhone(近期可能會有),Linux 可以用虛擬機測試。 + +# 信任規則(最重要) +- repo 中所有既有內容 —— AGENTS.md、CLAUDE.md、CONTEXT.md、docs/、docs/adr/、.trellis/spec/、 + 代碼註釋、測試、static-rule 測試 —— 都是「未經我確認的主張」,不是準則。 +- 證據優先序:實際執行的 App 行為 > 程式碼 > 測試 > 文檔/註釋。 +- 每個結論附證據(`檔案:行號`、log、截圖)。文檔與代碼不一致時兩邊都列出,標「不一致」。 +- 推測要標「推測」;查不到就寫查不到,不要補完。 +- `docs/adr/` 的 ADR 和 `CONTEXT.md` 的術語可以當作「代碼為什麼長這樣」的線索, + 但每一條都要用代碼驗證,不能直接引用為結論。 +- 套件的平台支援、API、版本差異,一律查官方文檔或 pub.dev,不憑記憶。 +- 審計期間跑測試一律加 `--exclude-tags live`,不要為了審計去打真實 API。 + +# 階段一:現況審計(唯讀) +只新增 `docs/audit/` 與 `.trellis/tasks/` 下的檔案,不改其他任何檔案;在分支 `docs/audit` 上工作。 +全部繁體中文,圖一律用 Mermaid。每份審計檔案開頭註明「現況描述,未經確認,不代表目標」。 + +1. `features.md` 功能清單 —— 從兩個方向盤點: + (a) 使用者入口:路由、頁面、設定項、選單、快捷鍵、托盤、通知; + (b) 背景行為:定時器、自動刷新、自動更新、啟動任務。 + 表格欄位:功能|入口|平台|涉及音源|狀態(完整/半成品/死代碼/無 UI 入口/僅開發者模式)|證據。 + 另外獨立列出「我很可能不知道的功能」,特別標出: + - 會對外寫入的(修改遠端歌單、收藏等) + - 會把資料送到第三方的(AI API 等) + - 會自己下載或執行東西的(自動更新等) +2. `architecture.md` —— 分層、目錄地圖、模組依賴圖、Riverpod provider 圖、路由、 + 啟動流程(main 到首頁的初始化順序)。 +3. `playback.md` —— 從「點一首歌」到「出聲」的完整序列圖;播放器狀態機圖; + 佇列與播放模式、串流解析、URL 過期重取、音質降級、預載、錯誤恢復、音訊焦點/中斷、 + 系統媒體控制(Android 通知、Windows SMTC)、播放歷史、臨時播放、Mix、電台/直播。 +4. `sources.md` —— 每個音源的能力矩陣(含只能匯入的 Spotify/QQ、歌詞源 lrclib/網易/QQ); + 「今天新增一個音源要改哪些檔案」的實際清單; + 音源特定分支(`switch`/`if source ==` 等)散落在 UI/service 的位置。 +5. `errors.md` —— 所有例外型別與層級;每個音源的錯誤如何產生、轉換、重試、呈現; + 限流、退避、cookie 失效、風控驗證、地區/版權限制怎麼處理;使用者最終看到什麼(Toast/對話框/靜默)。 +6. `data.md` —— Isar schema 與 migration、secure storage 存了什麼、各種快取、 + 下載檔案結構、備份格式、全部設定項總表。 +6a. `downloads.md`(補充)—— + - 從「按下載」到「檔案寫入」的完整序列圖:佇列、並行數、進度、暫停/續傳/重試、取消、失敗處理; + - 音質選擇、檔名與目錄規則、metadata/封面寫入、分 P 的處理; + - 下載路徑的設定、變更、搬移,以及路徑失效(不存在、權限被撤銷)時的行為; + - 已下載檔案如何被播放、如何與資料庫對應、刪除與清理; + - 各平台的權限:每個權限(Android 儲存、通知、電池最佳化等;Windows 相關項) + 在哪裡請求、何時請求、被拒時怎麼處理。 + 已經寫在其他審計檔案裡的內容不要重寫,引用過去即可。 +7. `accounts-network.md` —— 各音源的登入方式、憑證存放與刷新、HTTP client 與攔截器、 + 每個音源的 headers/簽名/請求策略; + 目前 log、錯誤訊息、Debug 頁、備份中是否可能露出 cookie、token、簽名 URL、API key, + 現有的遮蔽做法在哪裡、涵蓋哪些出口。 + 補充: + - 帳號系統全貌:登入、登出、狀態顯示、失效偵測與通知、重新登入流程的序列圖; + - 一張矩陣:各類請求(播放、下載、詳情、排行、搜尋、匯入、刷新、收藏同步、遠端歌單編輯) + × 各音源,標出是否帶憑證、由哪個開關控制、預設值為何; + - 登入與未登入時各音源能力的差異(音質、可播放範圍等)。 +8. `platforms.md` —— 平台適配現況: + - 每一處平台判斷(`Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 等)的位置與用途, + 按功能分組,不按檔案; + - 從未在真機跑過的 iOS/macOS/Linux 分支,標為「未驗證」; + - 平台綁定的功能:自動更新、儲存權限與下載路徑、登入 WebView、托盤、全域快捷鍵、開機自啟、 + 桌面歌詞視窗、系統媒體控制、音訊後端; + - 每個依賴套件的平台支援表(Android/Windows/Linux/macOS/iOS),以 pub.dev 為準; + - 原生目錄(`android/`、`windows/`)中的自訂原生代碼與 MethodChannel; + - 列出若要支援 Linux/macOS/iOS 會卡住的地方(套件不支援、平台政策限制、功能本身不成立)。 +9. `ui.md` —— 頁面地圖、響應式斷點、手機與桌面的差異、主題與設計 token 現況、 + i18n(有哪些語言、字串怎麼管理)、無障礙與桌面鍵盤操作的現況。 + 在 Android emulator 和 Windows 實際執行並截圖,列出版面、間距、一致性問題(桌面播放器頁優先)。 +10. `devtools.md` —— 開發者模式現有功能、Toast/log/錯誤呈現的現況。 +11. `engineering.md` —— 工程現況: + - CI/發版 workflow 的每個 job 做什麼、何時觸發;自動更新如何把新版推給使用者; + - 測試盤點:按目錄統計數量,分出「不聯網/聯網(live)/手動探針/benchmark/測 CI 設定本身」幾類, + 每類舉例說明哪些有價值、哪些只斷言實作細節或原始碼字串; + - 列出所有會打真實 API 的地方(live 測試、tool/demo、手動探針、實機驗證流程), + 以及本機直接跑 `flutter test`(不加任何參數)會不會聯網; + - 效能基準:用現有 benchmark 或實測記錄啟動時間、記憶體、長列表捲動,作為重寫後的比較基準; + - static-rule 測試、依賴健康度(過時/棄用/社群 fork)、codegen、tool/ 腳本、死代碼、重複邏輯; + - AI 指令檔(AGENTS.md、.claude/、.agents/、.trellis/、docs/agents/)的內容與彼此重複處; + - mattpocock skills 留下的所有殘留(docs/agents/、CONTEXT.md、AGENTS.md「Agent skills」段等) + 以及引用它們的位置; + - 逐份比對 `docs/adr/` 每份 ADR 與現在的代碼是否一致,逐條比對 `CONTEXT.md` 的術語是否仍對應到代碼。 +12. `questions.md` —— 給我勾選的決策清單,每項選「保留/刪除/修改/不確定」,按影響大小排序。 + 其中必須包含: + - `docs/adr/` 每一份 ADR:列出它決定了什麼、代碼現況、選項「確認/推翻/不再適用」; + - `CONTEXT.md` 每一個術語:選項「保留/併入 spec 或 docs 術語表/刪除」; + - 每個平台綁定功能在其他平台上的去留:「全平台提供/僅部分平台/刪除」; + - 每一類測試的去留; + - 資料層是否更換(Isar 社群 fork vs 其他方案),及它對資料相容、全平台、重寫順序的影響; + - i18n 保留哪些語言; + - 發佈管道(GitHub Release/商店/sideload)各平台打算怎麼走。 + - (補充)下載、權限、帳號、「用登入狀態播放」相關的去留與行為決策。 + +階段一結束後停下,給我一頁摘要 + 最需要我先決定的 10 件事,等我回覆再繼續。 + +# 階段二:目標設計(我確認階段一後才開始) +先研究再設計,每個決定說明採用了誰的慣例: +- 架構:Flutter 官方 App Architecture 指南、Riverpod 官方建議 +- 其他播放器:Spotube(音源插件、全平台)、MusicFree(插件系統)、LX Music(自訂源)、 + Listen1(多音源)、Harmony Music、Namida、Finamp +- 文檔:人類文檔按 Diátaxis 分類;AI 文檔按 AGENTS.md 慣例,只寫「打開程式碼查不到的東西」 + +每項給出方案、取捨、需要我決定的點: +1. 音源插件化 —— 單一註冊點宣告能力:搜尋、串流解析、歌單匯入、登入、收藏同步、遠端歌單編輯、 + 排行/探索、電台直播、推薦/Mix、歌詞、下載。 + 新增音源 = 新增一個目錄 + 註冊一行;UI 依能力自動出現入口,不支援就不顯示; + UI 與 service 不得出現針對特定音源的分支。 + 區分「可播放音源」「僅元資料/匯入音源(需匹配到可播放音源)」「歌詞源」,並統一匹配流程。 +2. 統一錯誤模型 —— 一個 sealed 分類:網路、限流、需登入/憑證過期、風控驗證、地區/版權限制、 + 找不到、解析失敗、不支援。 + 回答:音源特有錯誤是否在音源自己的檔案中轉成統一型別? + 重試/退避/限流由誰負責(例如音源宣告策略、網路層統一執行)? + 哪些自動恢復、哪些提示使用者、哪些只記錄? +3. 統一 Toast —— 單一入口。開發者模式下錯誤 Toast 旁有「詳細」按鈕, + 可看錯誤類型、音源、請求摘要、stack trace,並可複製;所有錯誤同時進入可檢索的錯誤歷史。 + 所有會展示或匯出請求內容的地方(Toast 詳細、Debug 頁、診斷包、log) + 經過同一個遮蔽函式,cookie、token、簽名 URL、API key 一律遮蔽。 +4. Debug 頁 —— 做成正式工具而不是半成品:log 檢視與篩選、網路請求檢視、播放器/佇列即時狀態、 + 資料庫檢視、音源健康檢查、快取管理、診斷包匯出。UI 使用與 App 其他部分相同的設計系統。 +5. UI/UX —— 設計系統(間距、字級、色彩 token)、手機/平板/桌面的響應式規則、 + i18n 字串管理、無障礙與桌面鍵盤操作;桌面播放器頁給 2–3 個版面方案讓我選。 +6. 資料相容 —— 現有資料庫、登入憑證、下載檔、備份檔要不要保留,以及 migration 策略; + 資料層是否更換,依我在 `questions.md` 的決定展開。 +7. 重寫策略 —— 全新重寫 vs 逐步替換,給建議與理由; + 拆成可獨立驗證的里程碑,每個里程碑結束時 App 都能正常運作。 + 說明分支與發版策略:重寫期間舊版的修正在哪裡做、使用者跳版升級時資料與憑證如何遷移。 +8. 測試與閘門 —— 現有測試與 static-rule 哪些保留、哪些刪除;新架構需要哪些閘門。 + 聯網策略分三層,給具體方案: + - 預設測試零聯網,音源用錄製的真實回應(fixture);本機直接 `flutter test` 也不得聯網; + - 聯網冒煙測試每個音源每種能力最多一條,預設排除、需明確指定才跑,不擋 PR; + 評估是否用 CI 排程跑(注意機房 IP 可能被上游封鎖),失敗時如何通知; + - 一個錄製 fixture 的工具,自動遮蔽 cookie、token、簽名 URL; + - 音源插件化的共用契約測試:每個音源自動套用同一套測試,只需提供自己的 fixture; + - 開發時減少真實請求的方法(例如開發者模式的假音源或回應快取), + 以及與 Debug 頁「音源健康檢查」共用檢查代碼的可能性。 +9. 文檔結構 —— 給人看的(README、docs/)與給 AI 看的(AGENTS.md、Trellis spec)各放什麼,互不重複。 + 保留 ADR 機制,三者分工如下: + - `.trellis/spec/` 寫「這一層的程式碼怎麼寫」,不寫歷史; + - Trellis task 的 `design.md` 寫「這次任務怎麼做」,隨任務歸檔; + - `docs/adr/` 寫「跨模組決定的理由與被否決的方案」,長期保留。 + 新架構的每個重大決定(音源插件、錯誤模型、平台策略、測試策略、資料層、重寫策略、資料相容等) + 各寫一份新 ADR。 +10. 平台策略 —— 目標是全平台,但不要替還無法驗證的平台寫空實作: + - 平台差異收進單一平台層,由平台宣告能力(托盤、全域快捷鍵、自動更新方式、桌面歌詞視窗、 + 系統媒體控制實作、下載儲存方式、登入方式等),UI 與 service 依能力運作, + 平台層以外不得出現 `Platform.isXxx`;做法與音源插件化一致; + - 選套件時,同等條件下優先選支援全平台的;列出目前依賴中需要替換的套件與替代方案; + - 平台政策差異要明寫:例如 iOS 不能自行安裝更新、各平台的背景播放與儲存沙盒限制; + 以及各平台的發佈管道(非官方 API 與下載功能大概無法上架商店); + - 建議平台上線順序與驗證方式:Linux 可用虛擬機,建議儘早加入作為第三個平台驗證抽象; + macOS/iOS 在沒有 Mac 時,用 GitHub Actions 的 macOS runner 做編譯檢查(不簽名) + 與 iOS 模擬器測試,取得 Mac/iPhone 後再做真機驗證與簽名; + - 每個平台一個 child task,註明它需要的硬體或環境。 +11. 下載與權限(補充)—— 下載作為音源能力之一如何納入插件化;佇列與續傳; + 下載路徑與儲存抽象如何配合平台層(各平台沙盒與權限差異); + 權限管理統一入口:由平台宣告需要哪些權限,請求、被拒、引導使用者到系統設定的流程一致。 +12. 帳號與認證(補充)—— 帳號作為音源能力之一;憑證存放、刷新、失效的統一流程; + 「哪些請求帶憑證」由一處宣告,不散落在各 service;登入狀態對能力的影響如何反映在 UI; + 登出與重設資料時的憑證清理,以及 migration 不得擅自改變使用者自己設定的值。 +13. 播放核心(補充)—— 佇列、播放模式、播放狀態機、兩個音訊後端的抽象、串流解析與 URL 過期、 + 錯誤恢復、系統媒體控制;電台/直播目前繞過 AudioController 的例外是否保留。 +14. 音樂庫與同步(補充)—— 本地歌單與遠端歌單的關係與同步方向(誰覆蓋誰、衝突怎麼辦); + 遠端歌單編輯寫回第三方平台前的確認機制;自動刷新規則; + 僅元資料音源(Spotify、QQ)匯入時的匹配流程與匹配失敗的處理。 +15. 歌詞(補充)—— 歌詞源作為插件類別、自動匹配、AI 匹配(送往第三方的資料與開關)、 + 桌面歌詞視窗在各平台的去留。 +16. 背景任務(補充)—— 自動刷新、更新檢查、電台刷新、清理任務等統一由誰排程、如何取消、 + App 在背景或離線時的行為。 +17. 快取與離線(補充)—— 圖片、串流 URL、歌詞、排行等快取的統一策略;沒有網路時 App 能做什麼。 +18. 設定與日誌基礎設施(補充)—— 設定項的分組與存放;log 的分級、輸出位置、檔案輪替與保留, + 與 Debug 頁、診斷包、遮蔽函式的關係。 + +階段二的進行方式(補充):階段二開始時先給出所有設計項目的依賴關係與建議順序(例如資料層 → 網路與帳號 → +音源插件與錯誤模型 → 播放核心 → 音樂庫與下載 → UI),我確認後再逐項用 trellis-brainstorm 展開, +不要一次展開所有項目。 + +# 階段三:Trellis 流程 +- 檢查 `.trellis/`、`.claude/agents/`、`.claude/commands/`、`.claude/skills/`、`.agents/skills/`、hooks、`orca.yaml` + 與 AGENTS.md、docs/ 是否重疊或衝突,列出需要修改的地方。 +- 移除 mattpocock skills 的殘留:刪除 `docs/agents/`,並刪除或改寫 AGENTS.md「Agent skills」段、 + `docs/README.md` 中對它們的引用;若「issue 用繁體中文撰寫」等慣例仍需要,搬一句到 AGENTS.md。 +- 依我在 `questions.md` 的勾選處理 ADR 與術語: + - 「推翻/不再適用」的 ADR 刪除;「確認」的保留,必要時按新架構重寫; + - `CONTEXT.md` 的術語按勾選併入對應 spec 或 docs 術語表,全部處理完後刪除 `CONTEXT.md`; + - 同步修改所有引用:`.trellis/spec/`(data、services、guides)、`.github/workflows/release.yml` 註解、 + AGENTS.md、docs/README.md;`.trellis/tasks/archive/` 是歷史紀錄,不改。 + - 修改後用 `git grep` 確認沒有指向已刪檔案或已刪 ADR 編號的引用。 +- verify-on-device skill 與 AGENTS.md 的驗證表目前只涵蓋 Android emulator 與 Windows, + 規劃新平台加入時要如何擴充(Linux 虛擬機、macOS runner、iOS 模擬器), + 以及實機驗證時如何減少打真實 API(對應階段二第 8 項)。 + +# 重構過程的約束 +- 可 review 性優先:每個 child task 產出一個 PR,大小控制在我能 review 的範圍,太大就拆; + 每個 PR 附 review 指南(改了什麼、為什麼、我該看哪幾個檔案、怎麼實際驗證); + 沒有經我確認的 ADR 的設計,不進代碼。 +- 功能凍結:重寫期間不加新功能,想到的記進 parent task 的待辦,不實作。 +- 完成定義:`features.md` 中我勾「保留」的功能全部在新架構上跑通, + 且效能不低於階段一記錄的基準。 +- 重寫期間不發布正式版本;舊版的緊急修正怎麼處理,在階段二的重寫策略中提出方案。 +- 參考其他開源專案時只參考設計;要複製代碼,先確認授權相容並告訴我。 + +# Trellis 任務管理 +- 建立 parent task `fmp-rewrite`,把這整份 prompt 原文存成它的 `prd.md`。 +- 階段一建成它的第一個 child task `audit`(只寫 PRD,屬於輕量任務),然後開始執行。 +- 之後每個里程碑、每個新平台各是 `fmp-rewrite` 下的一個 child task, + 規劃時用 `trellis-brainstorm` 與我逐項確認,各自有 prd/design/implement。 + +# 輸出要求 +- 全程繁體中文,圖優先(架構圖、依賴圖、序列圖、狀態機圖)。 +- 大量閱讀可以分派子代理並行處理,但結論由你彙整,並逐條附上證據。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json new file mode 100644 index 000000000..219c679cd --- /dev/null +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -0,0 +1,28 @@ +{ + "id": "fmp-rewrite", + "name": "fmp-rewrite", + "title": "FMP rewrite", + "description": "Audit, redesign and rewrite FMP into a plugin-based, all-platform architecture", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-26", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [ + "09-26-audit" + ], + "parent": null, + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 4893f2cc72e836a050f18bcdcd653763d9eb8022 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 01:10:49 +0800 Subject: [PATCH 002/133] docs(audit): add phase-one audit of the current codebase Read-only snapshot of what the app actually does, with file:line evidence, as the factual base for the rewrite design. Each document was cross-checked by a second pass; corrections are marked inline. --- docs/audit/README.md | 62 ++ docs/audit/accounts-network.md | 517 ++++++++++++++ docs/audit/architecture.md | 659 ++++++++++++++++++ docs/audit/data.md | 362 ++++++++++ docs/audit/devtools.md | 219 ++++++ docs/audit/downloads.md | 395 +++++++++++ docs/audit/engineering.md | 627 +++++++++++++++++ docs/audit/errors.md | 400 +++++++++++ docs/audit/features.md | 446 ++++++++++++ docs/audit/perf-baseline.md | 217 ++++++ docs/audit/platforms.md | 413 +++++++++++ docs/audit/playback.md | 461 ++++++++++++ docs/audit/questions.md | 388 +++++++++++ docs/audit/screenshots/android-explore.png | Bin 0 -> 663631 bytes docs/audit/screenshots/android-history.png | Bin 0 -> 431951 bytes .../screenshots/android-home-scrolled.png | Bin 0 -> 519014 bytes docs/audit/screenshots/android-home.png | Bin 0 -> 551458 bytes docs/audit/screenshots/android-library.png | Bin 0 -> 234121 bytes docs/audit/screenshots/android-queue.png | Bin 0 -> 82450 bytes docs/audit/screenshots/android-radio.png | Bin 0 -> 81344 bytes docs/audit/screenshots/android-search.png | Bin 0 -> 74475 bytes .../screenshots/android-settings-scrolled.png | Bin 0 -> 211679 bytes docs/audit/screenshots/android-settings.png | Bin 0 -> 193348 bytes .../screenshots/windows-compact-home.png | Bin 0 -> 155431 bytes .../screenshots/windows-compact-player.png | Bin 0 -> 205708 bytes docs/audit/screenshots/windows-focus-rail.png | Bin 0 -> 90099 bytes docs/audit/screenshots/windows-focus-row.png | Bin 0 -> 127551 bytes docs/audit/screenshots/windows-home.png | Bin 0 -> 388732 bytes docs/audit/screenshots/windows-library.png | Bin 0 -> 232966 bytes .../audit/screenshots/windows-player-menu.png | Bin 0 -> 87670 bytes docs/audit/screenshots/windows-player.png | Bin 0 -> 377449 bytes docs/audit/screenshots/windows-queue.png | Bin 0 -> 385531 bytes docs/audit/screenshots/windows-search.png | Bin 0 -> 220197 bytes docs/audit/screenshots/windows-settings.png | Bin 0 -> 234413 bytes docs/audit/sources.md | 517 ++++++++++++++ docs/audit/ui.md | 354 ++++++++++ 36 files changed, 6037 insertions(+) create mode 100644 docs/audit/README.md create mode 100644 docs/audit/accounts-network.md create mode 100644 docs/audit/architecture.md create mode 100644 docs/audit/data.md create mode 100644 docs/audit/devtools.md create mode 100644 docs/audit/downloads.md create mode 100644 docs/audit/engineering.md create mode 100644 docs/audit/errors.md create mode 100644 docs/audit/features.md create mode 100644 docs/audit/perf-baseline.md create mode 100644 docs/audit/platforms.md create mode 100644 docs/audit/playback.md create mode 100644 docs/audit/questions.md create mode 100644 docs/audit/screenshots/android-explore.png create mode 100644 docs/audit/screenshots/android-history.png create mode 100644 docs/audit/screenshots/android-home-scrolled.png create mode 100644 docs/audit/screenshots/android-home.png create mode 100644 docs/audit/screenshots/android-library.png create mode 100644 docs/audit/screenshots/android-queue.png create mode 100644 docs/audit/screenshots/android-radio.png create mode 100644 docs/audit/screenshots/android-search.png create mode 100644 docs/audit/screenshots/android-settings-scrolled.png create mode 100644 docs/audit/screenshots/android-settings.png create mode 100644 docs/audit/screenshots/windows-compact-home.png create mode 100644 docs/audit/screenshots/windows-compact-player.png create mode 100644 docs/audit/screenshots/windows-focus-rail.png create mode 100644 docs/audit/screenshots/windows-focus-row.png create mode 100644 docs/audit/screenshots/windows-home.png create mode 100644 docs/audit/screenshots/windows-library.png create mode 100644 docs/audit/screenshots/windows-player-menu.png create mode 100644 docs/audit/screenshots/windows-player.png create mode 100644 docs/audit/screenshots/windows-queue.png create mode 100644 docs/audit/screenshots/windows-search.png create mode 100644 docs/audit/screenshots/windows-settings.png create mode 100644 docs/audit/sources.md create mode 100644 docs/audit/ui.md diff --git a/docs/audit/README.md b/docs/audit/README.md new file mode 100644 index 000000000..452b7b097 --- /dev/null +++ b/docs/audit/README.md @@ -0,0 +1,62 @@ +# FMP 現況審計 + +> 現況描述,未經確認,不代表目標。 + +審計日期 2026-09-26~27,分支 `docs/audit`,基準 commit `6d78fe23`。 +這是 `fmp-rewrite` 的階段一產出(Trellis task `.trellis/tasks/09-26-audit/`)。 + +## 怎麼讀 + +1. 先看下面的「一頁摘要」。 +2. 再打開 [`questions.md`](questions.md) 勾選決策;每一項都附了指向細節文件的證據。 +3. 需要細節時查對應文件。 + +| 文件 | 內容 | +|---|---| +| [`features.md`](features.md) | 功能清單(入口、背景行為)、死代碼、「你很可能不知道的功能」 | +| [`architecture.md`](architecture.md) | 分層、目錄地圖、模組依賴圖、Riverpod provider 圖、路由、啟動流程 | +| [`playback.md`](playback.md) | 點歌到出聲的序列圖、播放器狀態機、佇列、串流解析、錯誤恢復、系統媒體控制、Mix、電台 | +| [`sources.md`](sources.md) | 音源能力矩陣、音源抽象、新增音源要改的檔案、音源特定分支位置、匯入與歌詞匹配 | +| [`errors.md`](errors.md) | 例外型別、各音源錯誤流、限流/cookie 失效/風控、使用者看到什麼 | +| [`data.md`](data.md) | Isar schema 與 migration、secure storage、快取、下載檔結構、備份格式、設定總表 | +| [`downloads.md`](downloads.md) | 下載序列圖與狀態機、續傳、路徑設定與失效、已下載檔案、各平台權限 | +| [`accounts-network.md`](accounts-network.md) | 登入、HTTP client、各音源請求策略、敏感資訊外洩面、帳號全貌、請求 × 音源憑證矩陣 | +| [`platforms.md`](platforms.md) | 平台判斷位置、未驗證分支、平台綁定功能、依賴套件平台支援表、原生碼、其他平台的阻礙 | +| [`ui.md`](ui.md) | 頁面地圖、斷點、token、i18n、無障礙與鍵盤、實機截圖與問題 | +| [`perf-baseline.md`](perf-baseline.md) | 啟動時間、記憶體、長列表捲動的實機基準(重寫後的比較對象) | +| [`devtools.md`](devtools.md) | 開發者模式、Toast/log/錯誤呈現 | +| [`engineering.md`](engineering.md) | CI/發版、測試盤點、聯網點、static-rule、依賴健康度、死代碼、AI 指令檔、ADR 與 CONTEXT.md 比對 | +| [`questions.md`](questions.md) | 給你勾選的決策清單 | + +## 方法與可信度 + +- 證據優先序:實際執行 > 程式碼 > 測試 > 文檔。每個結論附 `檔案:行號`、命令輸出或截圖;文檔與程式碼不符標「**不一致**」,未實測的標「**推測**」。 +- 每份文件由一個子代理撰寫,再由另一個子代理做對抗式核查(重點核「死代碼/無呼叫端」、安全相關主張、推測)。首輪正確率約 93–98%,約 57 處被更正,文中以「核查更正」標記;沒有任何主要發現被推翻。 +- 只跑了離線測試(`--exclude-tags live`)。App 只在 `ui.md`/`perf-baseline.md` 實機執行:Android emulator 用的是空的測試資料;**Windows 的 debug/profile build 會讀寫你真實的 `Documents\FMP`**,審計時誤觸了一次播放(佇列當前曲目開始串流後立即暫停),可能改了播放位置、多了一筆播放紀錄。 +- 截圖中的個人資料(歌單、佇列、播放紀錄、當前曲目)已模糊處理。 + +## 一頁摘要 + +**規模。** `lib/` 手寫 Dart 343 檔 99,063 行(另有生成碼 46,089 行)、測試 261 檔 63,927 行、1,877 個 commit。離線測試 1,849 個全過,`flutter analyze` 無問題;但 main 的 CI 目前是紅的(一個用固定 200 ms 等待的時序測試,`engineering.md` §12)。 + +**架構。** 分層大致存在,AGENTS.md 宣稱的邊界逐條 grep 都成立,但實際依賴不是單向:有一個 19 個目錄的大循環(起因是 `main.dart` 的全域可變狀態被反向 import),`services → providers` 反向 11 次,UI 直接 import `services/` 66 次、`data/` 77 次。`AudioController` 單檔 2,953 行、約 125 個方法;播放器狀態至少有 5 份來源。162 個手寫 provider,放置慣例三種以上(`architecture.md`)。 + +**播放。** UI 上「點一首歌」幾乎全走「臨時播放」(播完回原佇列);歌單頁「全部」按鈕其實只加入佇列。網路錯誤的重試訊號只有一個沒人用的入口接得住,臨時播放、Mix、上下首因此會出現錯誤路徑。預取在重啟後形同失效;隨機模式下拖曳與「下一首播放」的語意不對(`playback.md`)。 + +**音源。** 有能力介面(`SourceCapability`),但新增一個能搜能播的音源最少要改 15 個檔,做到網易雲同等約 54 個;音源特定分支 50 處散在 28 個檔,守它的 static-rule 預算只有 9 處。Spotify/QQ 只能匯入,匹配到可播放音源(`sources.md`)。 + +**錯誤。** 自訂例外到畫面一律變成「發生錯誤」(`userMessageFor` 不認得它們),同時 adapter 又會把 `e.toString()` 原文丟上畫面;多源搜尋只要一源成功就隱藏其他失敗;網易雲任何非 200 碼(含限流)都會清憑證;播放用的連線偵測不到登入失效(`errors.md`)。 + +**資料與下載。** Isar 走社群 fork `isar_community` 3.3.2,11 個 collection 之間沒有任何 link,關係靠手動維護的 id。含簽名的串流 URL 明文存進資料庫;Windows 上資料庫與 log 在「文件」資料夾。**已由程式碼確認的資料遺失路徑**:每次啟動的下載同步用「清理過特殊字元的資料夾名」比對歌單原名,對不上就丟關聯;約 10 秒後的孤兒清理只看這份關聯、不看歌單本身的曲目清單,於是曲目被刪、從歌單消失(未實機重現,`downloads.md` §4.4)。Android 下載路徑選一次就改不了;續傳不驗證檔案一致性(`data.md`、`downloads.md`)。 + +**帳號與隱私。** UI 的登入狀態讀 Isar,實際送請求只看 secure storage;「重設所有資料」不清憑證,重設後 UI 顯示未登入但請求仍帶舊 cookie(已由程式碼確認)。log 遮蔽不涵蓋 CDN 簽名參數與 stackTrace。v3→v4 migration 把使用者自己關掉的 B 站「用登入狀態播放」強制打開。YouTube/網易的首頁排行永遠不帶登入(`accounts-network.md`)。 + +**你很可能不知道的。** 在本機刪「匯入的平台歌單」裡的曲目,會同步在 B 站/YouTube/網易雲上刪;每次啟動可能自動換 B 站 cookie;網易雲寫入請求帶偽造的 `X-Real-IP`;AI 歌詞匹配(預設關)會把影片描述與歌詞預覽連同 API key 送到自訂端點、不強制 https;Windows 更新會靜默執行下載的安裝程式或用隱藏的 bat 覆蓋程式目錄,SHA-256 只在 release 附了 checksum 檔時才驗;每 15 秒解析三個公共 DNS 名稱(`features.md` §15)。 + +**平台。** 88 處平台判斷、三種寫法並存。macOS/Linux 會出現半套桌面 UI、沒有標題列、推測無法播放;iOS 程式碼最接近能跑但缺背景播放與 ATS 設定。Linux 缺 just_audio/audio_service/flutter_inappwebview 實作;`media_kit_libs_windows_audio` 在 pub.dev 已 unlisted(`platforms.md`)。 + +**UI。** i18n 三語言完全對齊(各 1,176 key),但間距與字級沒有 token、App 內沒有任何鍵盤快捷鍵、播放頁大播放鍵沒有無障礙名稱(`ui.md`)。 + +**效能基準(profile,3 次中位數)。** 冷啟動到首幀 Android 1,239 ms/Windows 1,731 ms;首頁記憶體 Android PSS ≈179 MB/Windows Working Set ≈300 MB;長列表 UI thread 每幀中位數 1.00 ms/0.45 ms(`perf-baseline.md`)。 + +**工程與文檔。** 不加參數的 `flutter test` 會打三個音源的正式 API(`dart_test.yaml` 沒有預設 skip)。7 份 ADR 中 5 份與程式碼一致,0001、0007 部分不一致;CONTEXT.md 5 個術語都對得到程式碼,Media Handoff 的 redirect 檢查只在下載路徑。AI 指令檔分散在 AGENTS.md、`.trellis/`、`.claude/`、`docs/agents/`、`CONTEXT.md`、`orca.yaml`,有數處互相矛盾;`docs/agents/` 仍是 mattpocock 模板內容(`engineering.md` §8–§11)。 diff --git a/docs/audit/accounts-network.md b/docs/audit/accounts-network.md new file mode 100644 index 000000000..72e371017 --- /dev/null +++ b/docs/audit/accounts-network.md @@ -0,0 +1,517 @@ +# 帳號與網路層現況審計 + +> 現況描述,未經確認,不代表目標。 + +審計基準:分支 `docs/audit`(HEAD `6d78fe23`),2026-09-26。只讀原始碼,沒有打真實 API,也沒有執行 app。 +行號都是實際看過的位置。「**推測**」代表依程式碼推論、未實測;「**不一致**」代表文件(含註釋)和程式碼對不上。 +本文件不寫出任何 cookie、token、key 的值。硬編碼的金鑰只列位置與用途,值一律寫成 `***`。 + +--- + +## 1. 各音源登入方式 + +### 1.1 總覽 + +| | Bilibili | YouTube | 網易雲 | +|---|---|---|---| +| 登入方式 | WebView(兩平台)+ QR 碼(兩平台) | 只有 WebView | Android:WebView + QR;Windows:只有 QR | +| UI | `lib/ui/pages/settings/bilibili_login_page.dart:51-63` | `youtube_login_page.dart:322-340` | `netease_login_page.dart:51-78` | +| 取得的憑證 | SESSDATA、bili_jct、DedeUserID、DedeUserID__ckMd5、refresh_token | SID、HSID、SSID、APISID、SAPISID、`__Secure-1PSID`/`3PSID`/`1PAPISID`/`3PAPISID`、LOGIN_INFO、DATASYNC_ID(選用) | MUSIC_U、`__csrf`、userId | +| 必要欄位 | SESSDATA、bili_jct、DedeUserID(`bilibili_account_service.dart:99-103`) | SAPISID、`__Secure-1PSID`、`__Secure-3PSID`(`youtube_account_service.dart:34-38,57-67`) | MUSIC_U(`netease_credentials.dart:16-21`) | +| 憑證存放 | secure storage `account_bilibili_credentials`(`bilibili_account_service.dart:73`) | `account_youtube_credentials`(`youtube_account_service.dart:27`) | `account_netease_credentials`(`netease_account_service.dart:30`) | +| Isar | `Account` 列只存非敏感狀態:platform、userId、userName、avatarUrl、isLoggedIn、isVip、sessionExpired、loginAt、lastRefreshed(`lib/data/models/account.dart:9-48`) | 同左 | 同左 | +| 刷新 | 有:cookie refresh 流程(§1.5) | 沒有(`refreshCredentials` 直接回 true,`youtube_account_service.dart:166-172`) | 沒有(`netease_account_service.dart:299-305`) | +| 帶憑證的方式 | `Cookie` 標頭 | `Cookie` + `Authorization: SAPISIDHASH _`(`youtube_credentials.dart:97-102`) | `Cookie`(加上 `os=pc; deviceId=fmp`)+ Origin、Referer、桌面版 UA(`netease_credentials.dart:41-52`;`netease_account_service.dart:592-599`) | + +### 1.2 Bilibili + +```mermaid +sequenceDiagram + participant U as 使用者 + participant P as BilibiliLoginPage + participant S as BilibiliAccountService + participant B as passport.bilibili.com + participant SS as SecureStorage + participant DB as Isar Account + alt WebView 分頁 + P->>B: 載入 passport.bilibili.com/login(行動版 UA) + U->>B: 在 WebView 內登入 + B-->>P: 導回 *.bilibili.com(onLoadStop) + P->>P: CookieManager.getCookies(www.bilibili.com) + P->>P: 執行 JS localStorage.getItem('ac_time_value'),取得 refresh_token + P->>S: loginWithCookies(...) + else QR 分頁 + P->>S: generateQrCode() + S->>B: GET /x/passport-login/web/qrcode/generate + loop 每 2 秒,最多 90 次 + S->>B: GET .../qrcode/poll?qrcode_key=... + B-->>S: code 86101/86090/86038/0 + end + S->>S: code 0 時從 Set-Cookie 取出 cookie,從 body 取出 refresh_token + S->>S: loginWithCookies(...) + end + S->>SS: write account_bilibili_credentials (JSON) + S->>DB: upsert(isLoggedIn=true, userId, sessionExpired=false) + P->>S: fetchAndUpdateUserInfo(),打 /x/web-interface/nav + P->>P: 清掉 WebView 的 cookie、快取、WebStorage +``` + +證據:WebView 取 cookie 在 `bilibili_login_page.dart:126-190`;清理在 `:105-124`;QR 在 `bilibili_account_service.dart:133-253`;寫入在 `:92-130`。 + +**QR 流程的缺口:** 輪詢回 code 0,但 Set-Cookie 解析不出 cookie 時(`cookies == null`),程式不會呼叫 `loginWithCookies`,卻照樣送出 `success`(`bilibili_account_service.dart:184-200`)。UI 收到後會顯示登入成功並關閉頁面(`bilibili_login_page.dart:294-297`)。**已由程式碼確認(核查):** UI 在 `success` 後先呼叫 `fetchAndUpdateUserInfo()`,它把例外全吞掉(`bilibili_account_service.dart:511-517`);而沒有憑證時 `checkAccountStatus()` 直接回 `invalid`、不丟例外(`:469-473`),所以一定會走到 `widget.onLoginSuccess()`。結果是頁面顯示登入成功,secure storage 與 Account 列都沒有被寫入。尚未實測的只剩「伺服器是否真的會回 code 0 卻不帶 Set-Cookie」。(核查更正:原寫「**推測:** 使用者會看到『登入成功』,實際上沒有任何憑證被存下來」)另一個分支:Set-Cookie 有值但缺 SESSDATA 等必要欄位時,`loginWithCookies` 丟 `ArgumentError`,被輪詢迴圈的 `catch` 當成網路錯誤處理,畫面回到「等待掃碼」,而且例外字串會進 stream 的 `message`(`:220-236`)。 + +### 1.3 YouTube + +```mermaid +sequenceDiagram + participant P as YouTubeLoginPage + participant G as accounts.google.com + participant Y as www.youtube.com + participant S as YouTubeAccountService + participant SS as SecureStorage + P->>G: ServiceLogin?service=youtube&continue=youtube.com(桌面 Chrome UA,Android 去掉 #59;wv) + G-->>Y: 登入後導向 + Y-->>P: onLoadStop,host 是 youtube.com + P->>P: getCookies(www.youtube.com),JS 讀 ytcfg DATASYNC_ID + P->>S: loginWithCookies(cookieMap) + S->>S: 檢查三個必要 cookie + S->>SS: write account_youtube_credentials + P->>Y: JS fetch /youtubei/v1/account/accounts_list?key=...(在 WebView 內) + P->>S: updateUserInfo(name, avatar, channelId) +``` + +證據:`youtube_login_page.dart:71-120,214-299,327-339`;`youtube_account_service.dart:56-96,236-249`。帳號狀態檢查打 InnerTube `browse SPaccount_overview`,失敗再試頻道頁,最後試 guide(`youtube_account_service.dart:178-233,257-332`)。 + +### 1.4 網易雲 + +```mermaid +sequenceDiagram + participant P as NeteaseLoginPage + participant S as NeteaseAccountService + participant N as music.163.com + participant SS as SecureStorage + alt Android WebView + P->>N: 載入 music.163.com/#/login + P->>P: 每次 onLoadStop 都檢查 MUSIC_U cookie + P->>S: loginWithCookiesAndValidate(musicU, csrf) + else QR(兩平台) + S->>N: POST /weapi/login/qrcode/unikey(weapi 加密,匿名 cookie) + loop 每 3 秒,最多 60 次 + S->>N: POST /weapi/login/qrcode/client/login(每次重新加密) + end + N-->>S: 803,Set-Cookie 或 body.cookie + S->>S: loginWithCookiesAndValidate(...) + end + S->>S: 先拍快照(舊憑證與 Account 列) + S->>SS: write account_netease_credentials + S->>N: GET /api/nuser/account/get(失敗改 POST /api/w/nuser/account/get) + alt 驗證失敗 + S->>SS: 還原快照 + end +``` + +證據:`netease_account_service.dart:78-105,108-231,311-367,478-545`;`netease_login_page.dart:122-160,254-268`。 + +### 1.5 刷新與失效 + +- **啟動時**:`accountStatusCheckProvider` 先等 `accountCookieRefreshProvider`。後者只處理 Bilibili:已登入就呼叫 `refreshCredentials()`。接著 `verifyAllAccountStatuses` 對每個已登入的平台呼叫 `checkAccountStatus()`;回 invalid 就 `markSessionExpired()` 並跳一次提示(`lib/providers/account/account_provider.dart:131-178,216-252`)。`lib/app.dart:125` watch `accountStatusCheckProvider`,`accountCookieRefreshProvider` 是在前者內部被 watch(`account_provider.dart:167`);`app.dart:128` watch 的是 `accountSessionExpiryWatcherProvider`。(核查更正:原寫「這兩個 provider 都在 `lib/app.dart:125,128` 被 watch」) +- **Bilibili cookie refresh**(`bilibili_account_service.dart:351-454`): + 1. `GET passport/x/passport-login/web/cookie/info`,`refresh != true` 就直接回 true。 + 2. 用寫死的 RSA 公鑰做 RSA-OAEP(SHA-256),加密 `refresh_{timestamp}` 得到 correspondPath(`lib/services/account/bilibili_crypto.dart:14-25`)。 + 3. `GET www.bilibili.com/correspond/1/`,從 HTML 抓出 refresh_csrf(`:456-463`)。 + 4. `POST .../cookie/refresh`,拿到新的 Set-Cookie 和新的 refresh_token,寫回 secure storage。 + 5. `POST .../confirm/refresh`,帶新 cookie 和舊 refresh_token。 +- **請求期偵測**:只有 `BilibiliFavoritesService`、`NeteasePlaylistService`、`YouTubePlaylistService` 的 Dio 掛了攔截器(§2)。音源 adapter(搜尋、串流解析、詳情)都沒掛,它們收到 -101 或 301 不會把帳號標成失效。 + - Bilibili:-101/-111 時共用同一個 Completer 做刷新;刷新失敗或重試後仍是 -101,就 `markSessionExpired`(`lib/services/account/bilibili_auth_interceptor.dart:38-123`)。 + - 網易:已登入卻收到 code 301,就 `markSessionExpired`(`netease_auth_interceptor.dart:37-59`)。 + - YouTube:只記 warning,不做任何事(`youtube_auth_interceptor.dart:30-60`)。 +- **Bilibili 刷新後重試帶的是舊 cookie(送出舊 cookie 這點已由程式碼確認;伺服器的回應未實測)**:`onRequest` 把舊 cookie 直接寫進 `options.headers['Cookie']`(`bilibili_auth_interceptor.dart:28-33`)。刷新後的重試是 `_accountService.dio.fetch(requestOptions)`(`:77`),用的是同一份 `RequestOptions`,而帳號服務那個 Dio 沒有掛攔截器(`bilibili_account_service.dart:83,619`;整個 lib 的 `interceptors.add` 只有三處,見 §2)。`refreshCredentials()` 只更新 secure storage 與 `_cachedCredentials`(`:425-429`),不會回頭改那份 `RequestOptions`。所以重試送出去的一定是刷新**前**的 cookie;收藏夾寫入請求 body 裡的 `csrf`(舊 `bili_jct`)也不會更新。**推測**:刷新真的換了 cookie 時,重試很可能再收到 -101,接著被標成失效。(核查更正:原寫「(推測,未實測)」涵蓋整段)現有測試只覆蓋「刷新救不回來」這條路(`test/services/account/account_session_expiry_test.dart:125`)。 +- **登出**(`logout`):刪 secure storage 的 key、清記憶體快取、刪整筆 Account 列、清 WebView 裡對應網域的 cookie(Bilibili `:295-319`;網易 `:268-287`;YouTube `:136-155`)。 +- **失效**(`markSessionExpired`):刪憑證,但 Account 列保留並設 `sessionExpired=true`(Bilibili `:321-328`;網易 `:289-297`;YouTube `:157-164`)。 +- **secure storage 讀不出來**:降級成「未登入」,只記一行固定訊息(例如 `bilibili_account_service.dart:553-564`)。Bilibili 沒有 `_credentialsLoaded` 旗標,只用 `_cachedCredentials != null` 判斷,所以**沒有憑證(或讀取失敗)時**每次呼叫都會重讀一次 storage;有憑證時走記憶體快取(`bilibili_account_service.dart:551-552`)。(核查更正:原寫「所以每次呼叫都會重讀一次 storage」)網易有這個旗標(`netease_account_service.dart:28,403`)。 +- **「重設所有資料」不會清憑證**:只清 Isar(`lib/data/repositories/data_integrity_repository.dart:55-56`;`developer_options_page.dart:551`),`getAuthHeaders()` 又只看 secure storage 與記憶體快取(`bilibili_account_service.dart:264-267`)。重設後 `runDatabaseMigration` 重建的 Settings 預設 Bilibili、網易 `useAuthForPlay=true`,所以 `authForPlay` 仍會取出舊 cookie(核查:呼叫鏈已由程式碼確認)。見 data.md §3.1。 + +--- + +## 2. HTTP client 與攔截器 + +- 用的是 **dio 5.11.1**(`pubspec.lock`)。`package:http` 只是 dev_dependency,給 `tool/demo` 用(`pubspec.yaml:100-105`)。 +- **沒有** `LogInterceptor`、重試攔截器、快取攔截器,也沒有 `CookieJar`。整個 lib 只有三處 `interceptors.add`,全部是認證攔截器(`bilibili_favorites_service.dart:48`、`netease_playlist_service.dart:64`、`youtube_playlist_service.dart:55`)。cookie 一律手動組成 `Cookie` 標頭。 +- 共用工廠 `HttpClientFactory.create`:預設 UA 是 Chrome 122 桌面版,connect 逾時 10 秒、receive 逾時 30 秒(`lib/core/utils/http_client_factory.dart:12-41`;`app_constants.dart:115,118`)。音源專用的 `SourceHttpPolicy.createApiDio`/`createBilibiliLiveDio` 包在它外面,會套上各音源的標頭(`lib/data/sources/source_http_policy.dart:161-181`)。 + +| # | 實例 | 建立處 | 標頭/攔截器 | +|---|---|---|---| +| 1 | BilibiliSource `_dio` | `lib/data/sources/bilibili_source.dart:96-102` | createApiDio(bilibili),另加一組**隨機 buvid 指紋 cookie**(`:91-94,121-147`);帳號 cookie 由 `_withAuth` 在每次請求合併進去(`:167-174`) | +| 2 | BilibiliSource `_liveDio`/BilibiliLiveClient | `bilibili_source.dart:108`;`bilibili_live_client.dart:127-128` | live Referer + media UA | +| 3 | YouTubeSource `_dio` + `YoutubeExplode()` 內建 client | `youtube_source.dart:57,60` | createApiDio(youtube);youtube_explode 用它自己的 HTTP client 和 client 身分 | +| 4 | NeteaseSource `_dio` | `netease_source.dart:46` | createApiDio(netease);帳號 cookie 透過 `_withAuth` 每次附上(`:779-783`) | +| 5 | BilibiliAccountService `_dio` | `bilibili_account_service.dart:83` | createApiDio,**無攔截器**;攔截器的重試也走這個 Dio | +| 6 | BilibiliFavoritesService | `bilibili_favorites_service.dart:46-50` | createApiDio + **BilibiliAuthInterceptor** | +| 7 | NeteaseAccountService `_dio` | `netease_account_service.dart:46-50` | createApiDio + 固定的匿名 cookie(`:37-39`) + form-urlencoded | +| 8 | NeteasePlaylistService | `netease_playlist_service.dart:59-65` | createApiDio(Linux UA) + **NeteaseAuthInterceptor** | +| 9 | YouTubeAccountService `_dio` | `youtube_account_service.dart:45-48` | createApiDio(json) | +| 10 | YouTubePlaylistService | `youtube_playlist_service.dart:50-55` | createApiDio + **YouTubeAuthInterceptor** | +| 11 | DownloadService `_dio`(抓封面、頭像) | `download_service.dart:192-197` | receive 逾時 30 分鐘,media UA | +| 12 | 下載 isolate 的 `HttpClient`(抓音檔) | `download_service.dart:1819` 附近 | 每一跳重算 `MediaHandoff` 標頭;拒絕非 http(s) 或私有位址的重導向(`:1827-1846`);最多 5 跳 | +| 13 | UpdateService | `update_service.dart:218,756` | 打 GitHub API(`:397`),不帶憑證 | +| 14 | 歌詞:lrclib/網易歌詞/QQ 音樂 | `lrclib_source.dart:31`;`lib/services/lyrics/netease_source.dart:141`;`qqmusic_source.dart:108` | 各自的 UA 和 Referer;不帶帳號 | +| 15 | AI:`AiLyricsSelector`、`AiTitleParser` | `ai_lyrics_selector.dart:72`;`ai_title_parser.dart:21` | 裸 `Dio()`;請求時加 `Authorization: Bearer <使用者 key>`(`openai_chat_client.dart:48-67`) | +| 16 | 歌單匯入:QQ 音樂、Spotify | `qq_music_playlist_source.dart:14`;`spotify_playlist_source.dart:16` | HttpClientFactory 預設 | +| 17 | 圖片快取 | `network_image_cache_service.dart:442`(flutter_cache_manager 的 `HttpFileService`) | 由 ImageLoadingService 依 host 附上 `imageHeadersForUrl`(`source_http_policy.dart:104-119`) | +| 18 | 播放器 | just_audio `AudioSource.uri(headers:)`(`just_audio_service.dart:564`);media_kit/libmpv | 只帶 `mediaHeaders`(不含憑證) | +| 19 | WebView | 三個登入頁 | 自帶 cookie store | + +```mermaid +flowchart LR + subgraph Factory["HttpClientFactory.create
UA Chrome122, 10s/30s"] + end + Policy["SourceHttpPolicy
apiHeaders / mediaHeaders / imageHeaders"] --> Factory + Factory --> BS["BilibiliSource dio
+buvid cookie"] + Factory --> BL["Bilibili live dio"] + Factory --> YS["YouTubeSource dio"] + Factory --> NS["NeteaseSource dio"] + Factory --> BA["BilibiliAccountService dio
(無攔截器)"] + Factory --> BF["BilibiliFavoritesService dio"] + Factory --> NA["NeteaseAccountService dio
+匿名 cookie"] + Factory --> NP["NeteasePlaylistService dio"] + Factory --> YA["YouTubeAccountService dio"] + Factory --> YP["YouTubePlaylistService dio"] + Factory --> LY["歌詞/匯入 dio"] + BF -.-> BI["BilibiliAuthInterceptor
注入 Cookie / -101 刷新重試"] + NP -.-> NI["NeteaseAuthInterceptor
注入 Cookie+UA / 301 標失效"] + YP -.-> YI["YouTubeAuthInterceptor
Cookie+SAPISIDHASH"] + BI -- "重試走" --> BA + YT["YoutubeExplode 內建 client"]:::ext + DL["DownloadService dio + isolate HttpClient"]:::ext + AI["AI Dio()
Bearer key"]:::ext + UP["UpdateService dio"]:::ext + IMG["flutter_cache_manager HttpFileService"]:::ext + PL["just_audio / libmpv"]:::ext + Auth["SourceAuthContext.authForPlay
(Auth For Play)"] --> BS & YS & NS & DL + Policy --> PL & IMG & DL + classDef ext fill:#eee,stroke:#999 +``` + +帳號標頭是怎麼傳到音源 adapter 的:`SourceAuthContext.authForPlay(sourceType)` 先看 `Settings.useAuthForPlay(sourceType)`,開著才呼叫 `AccountServiceAuthLoader.load` → `service.getAuthHeaders()`(`lib/services/account/source_auth_context.dart:22-36,133-137`)。結果放進 `AudioStreamRequest.authHeaders`(`stream_resolution_service.dart:400-417`),由 adapter 自己合併進請求標頭。 + +--- + +## 3. 各音源的標頭、簽名與請求策略 + +### 3.1 Bilibili + +| 項目 | 現況 | 證據 | +|---|---|---| +| API UA | Chrome 122 Windows(`webUserAgent`) | `source_http_policy.dart:12,52` | +| API Referer/Origin/Accept | `https://www.bilibili.com/`、`https://www.bilibili.com`、JSON | `:44-53` | +| 媒體與圖片 | 只有 `Referer: https://www.bilibili.com`(刻意不帶尾斜線)+ media UA(Chrome 120) | `:9-11,46,82-84` | +| 搜尋 | Referer/Origin 改成 search.bilibili.com,加 `Accept-Language`,cookie 只有 buvid 指紋 | `:138-152`;`bilibili_source.dart:103-107` | +| 直播 | Referer `live.bilibili.com` + media UA | `source_http_policy.dart:154-159` | +| buvid | 每次程序啟動隨機產生 buvid3、buvid4、b_nut、_uuid、buvid_fp,本機亂數,不向 `finger/spi` 申請 | `bilibili_source.dart:121-147` | +| WBI 簽名 | **沒有實作**。view 改打 `wbi/view` 但不簽名,註釋說「目前不驗簽」 | `bilibili_source.dart:77-84` | +| 風控 | -352 等風控碼 → `rateLimited`,不換指紋重試,由上層退避 | `bilibili_source.dart:920-948`;`bilibili_exception.dart:15` | +| csrf | 收藏夾寫入時把 `bili_jct` 當成 `csrf` 參數送出 | `bilibili_favorites_service.dart:122-136` | +| Cookie refresh 加密 | RSA-OAEP(SHA-256),公鑰寫死在程式裡 | `bilibili_crypto.dart:14-33` | + +### 3.2 YouTube + +| 項目 | 現況 | 證據 | +|---|---|---| +| 匿名取流 | youtube_explode 3.1.0:audio-only 用 `androidVr`;muxed 用 `ios`、`safari`、`android`;HLS 依序試 `safari`、`ios`、兩者一起 | `youtube_source.dart:445-460,484-500,533-545` | +| 登入取流 | 每種 streamType 先匿名試,失敗才用 InnerTube **WEB** client 打 `/youtubei/v1/player?key=…`,帶 Cookie + SAPISIDHASH | `:340-376,406-423,121-139` | +| InnerTube 身分 | `clientName=WEB`、`clientVersion=2.20260128.05.00`、`hl=en`、`gl=US` | `lib/core/utils/innertube_utils.dart:5-20`;`youtube_source.dart:128-133` | +| API UA/Origin/Referer | media UA(Chrome 120);`https://www.youtube.com` | `source_http_policy.dart:55-60` | +| Mix 播放清單 | InnerTube `next`;HTTP 429 → rate_limited | `youtube_source.dart:1072-1100` | +| 帳號標頭 | `Cookie` + `Authorization: SAPISIDHASH`(SHA1(`ts SAPISID https://www.youtube.com`)) | `youtube_credentials.dart:97-102`;`youtube_account_service.dart:108-115` | + +### 3.3 網易雲 + +| 項目 | 現況 | 證據 | +|---|---|---| +| UA | `NeteaseMusicDesktop/3.0.18` 桌面版 UA;歌單管理用 Linux Chrome 60 UA | `source_http_policy.dart:13-19,68` | +| 取流 | **eapi**(AES-128-ECB + MD5),打 `interface3.music.163.com/eapi/song/enhance/player/url/v1`,帶帳號 cookie(`os=pc; deviceId=fmp`) | `netease_source.dart:88-121`;`lib/core/utils/netease_crypto.dart:78-88`;`netease_credentials.dart:41-52` | +| QR 登入 | **weapi**(兩層 AES-128-CBC + 無 padding 的 RSA),加上固定的匿名 cookie(偽裝 Windows 客戶端) | `netease_crypto.dart:56-68,115-121`;`netease_account_service.dart:37-39,109-113,152-156` | +| 搜尋與詳情 | 明文 `/api/*` form | `netease_source.dart:22-23,194,536` | +| 歌單管理 | `/api/linux/forward`,payload 以 AES-ECB 加密成 `eparams`;cookie 前面改成 `os=linux`;**固定送 `X-Real-IP: 118.88.88.88`** | `netease_playlist_service.dart:221-275` | +| URL 有效期 | 採用 API 回的 `expi`,沒有時退回 16 分鐘 | `netease_source.dart:40,164-169` | + +### 3.4 請求節流 + +整個 app **沒有全域的 rate limiter 或 semaphore**(grep 不到)。有的是這些分散的延遲與退避: + +- 匯入比對:多源間隔 1000 ms、單源 800 ms(`lib/core/constants/app_constants.dart:81-88`)。 +- 串流解析重試:一般 1 秒,被限流時 3 秒(`:134-146`)。 +- 播放失敗的漸進重試:1、2、4、8、16 秒(`:225-247`)。電台重連:1、3、10 秒(`:249-261`)。 +- 排行榜:失敗後依 `defaultFailureRetryDelays` 退避(`ranking_cache_service.dart:17`)。 +- 電台輪詢:App 進背景時暫停(`main.dart` `_RadioRefreshLifecycleObserver`)。 +- QR 輪詢:Bilibili 每 2 秒、最多 90 次;網易每 3 秒、最多 60 次;連續 5 次錯誤就停。 + +### 3.5 CONTEXT.md 術語對照 + +| 術語 | 程式碼對應 | 結論 | +|---|---|---| +| Source Auth Context | `SourceAuthContext`/`DefaultSourceAuthContext`(`source_auth_context.dart:76-194`) | 對得上 | +| Auth For Play | `Settings.useAuthForPlay(sourceId)`(`settings.dart:724`);閘門在 `authForPlay()`(`source_auth_context.dart:133-137`);消費點有串流解析(`stream_resolution_service.dart:406`)、下載(`download_service.dart:979`)、詳情(`track_detail_provider.dart:185`)、**首頁排行榜**(`ranking_cache_service.dart:270-274`) | 大致對得上。**不一致(輕微)**:CONTEXT.md 列的範圍沒提到排行榜。匯入與刷新走的是另外兩個函式 `playlistImportAuth`/`playlistRefreshAuth`(`import_service.dart:194,441`),搜尋不帶登入,這兩點和 CONTEXT 一致 | +| Stream Resolution Auth | `MediaHandoffRequest.streamResolutionAuth`(`lib/services/media/media_handoff.dart:16-21`) | 對得上 | +| Media Request Credentials(應為空) | `SourceHttpPolicy.mediaHeaders(sourceType)` 只接受 id,回傳 Origin/Referer/UA(`source_http_policy.dart:82-84`);`DefaultMediaHandoff` 只加 Range(`media_handoff.dart:54-62`) | 對得上。**不一致(註釋過時)**:`netease_account_service.dart:241-242` 的註釋說「供音頻播放器直接使用(CDN 需要 Cookie)」,但播放器實際上拿不到它 | +| Media Handoff | `MediaHandoff.preparePlayback`/`prepareDownloadHop`;下載 isolate 每一跳重算標頭(`download_service.dart:1847-1856` 附近) | 對得上 | + +--- + +## 4. 敏感資訊外洩面 + +### 4.1 現有的遮蔽函式 + +| 函式 | 位置 | 規則 | 誰會呼叫 | +|---|---|---|---| +| `AppLogger.redactSensitive` | `lib/core/logger.dart:177-200` | ① `Authorization` 標頭的值;② `SAPISIDHASH …`;③ `Bearer …`;④ `Cookie:`/`Cookie=` 後面整段;⑤ 26 個鍵名的 `key[:=]value` 形式,大小寫不分、**沒有字邊界**:MUSIC_U、musicU、`__csrf`、csrf、eparams、SESSDATA、bili_jct、DedeUserID、DedeUserID__ckMd5、refresh_token、access_token、apiKey、SAPISID、APISID、SID、HSID、SSID、`__Secure-*PSID`/`*PAPISID`、LOGIN_INFO、storePassword、keyPassword、password、token(`:81-134`) | **只有 `AppLogger._log` 會呼叫**(`:235-238`),處理 message 和 `error.toString()`。stackTrace **不處理**。lib 裡沒有其他呼叫者。測試:`test/core/logger/redaction_test.dart`、`test/services/account/account_credentials_redaction_test.dart` | +| `redactStreamUrl` | `lib/services/audio/playback_media.dart:12-19` | 只留 `scheme://host/…/最後一段路徑`,query 和中間路徑全部去掉 | `just_audio_service.dart:541,589`、`media_kit_audio_service.dart:743,819`、`PreparedPlaybackMedia.logLabel`(`playback_media.dart:68`),後者被 `playback_request_session.dart:544`、`audio_provider.dart:1733`、兩個後端的 next-medium log 使用 | +| `userMessageFor` | `lib/core/errors/user_message.dart:72-87` | 把例外轉成翻譯過的句子,不顯示原文 | `ToastService.failure`(`toast_service.dart:188-198`)、`failureMessage`(`user_message.dart:97-105`) | +| `SecureStorageUnavailable` | `secure_key_value_store.dart:13-27` | 只帶平台錯誤碼 | 三個帳號服務和 AI key 服務 | +| `_truncate(…, 60)` | `database_catalog.dart:164-165` | DB 檢視器裡的 URL 只顯示前 60 字 | 除錯頁 | + +`redactSensitive` 的**缺口**:它沒有處理 CDN 簽名參數(例如 `sig`、`signature`、`lsig`、`expire`、`upsig`、`deadline`,以及網易放在路徑段裡的簽章),也沒處理 InnerTube 的 `key=`。這些都要靠呼叫端自己先過 `redactStreamUrl`。 + +### 4.2 逐一出口 + +| 出口 | 可能外洩什麼 | 是否經過遮蔽 | 證據 | +|---|---|---|---| +| AppLogger 記憶體緩衝(500 筆)+ logStream | log 訊息與錯誤原文 | 是(redactSensitive) | `logger.dart:72,235-267` | +| Log 檔 `Documents/FMP/logs/fmp.log`(2 MB × 3) | 同上。Windows 上放在「文件」資料夾,**推測**可能被 OneDrive 之類的同步工具帶走 | message/error 是;**stackTrace 原樣寫入**(`LogEntry.toFileLine`,`logger.dart:52-63`)(核查更正:原寫「是」) | `log_file_sink.dart:24-28`;`logger.dart:269-270` | +| `debugPrint`(**release 版也會印**) | 同上。Android release 會進 logcat | 是(印的是 `fullMessage`/`safeError`);**stackTrace 原樣輸出** | `logger.dart:283-290` | +| `developer.log`(只在 debug) | 同上 | 是 | `logger.dart:273-281` | +| Log 檢視頁:複製到剪貼簿、匯出 log 檔 | 同上 | 複製用 `LogEntry.toString()`,不含 error/stackTrace;匯出是整份 log 檔(`sink.readAll()`),所以帶著未遮蔽的 stackTrace(核查更正:原寫「是(內容已經遮蔽過)」) | `log_viewer_page.dart:93,102-139,293,402` | +| media_kit 錯誤串流 | mpv 錯誤字串。**推測**:`file`/`stream` 類錯誤可能帶完整 URL(含簽名) | **否**,原樣寫入 `logError('media_kit error: $error')` | `media_kit_audio_service.dart:378-379` | +| just_audio `PlayerException` | 平台錯誤訊息。**推測**:ExoPlayer 部分錯誤可能帶 URI | **否**(只有 redactSensitive) | `just_audio_service.dart:301-304` | +| `Failed to play URL` 的 `e` | 例外原文 | 只有 redactSensitive | `just_audio_service.dart:578`;`media_kit_audio_service.dart:805,843` | +| youtube_explode 例外(`Stream type … failed: $e`) | 例外訊息。**推測**:可能含請求 URL | 只有 redactSensitive | `youtube_source.dart:398,402` | +| Dio 例外 `$e` | dio 5.11.1 的 `toString()` 只含 type、message、內層 error,**不含 URL 和標頭**(依套件原始碼 `dio_exception.dart:321-331`);內層的 `HttpException` 可能帶 uri(推測) | 只有 redactSensitive | 例如 `bilibili_account_service.dart:222,451` | +| Set-Cookie 解析失敗時印出整段 cookie | 整段 Set-Cookie | 是,但只遮得到清單裡的鍵名 | `bilibili_account_service.dart:613`;`netease_account_service.dart:552` | +| 使用者識別資訊 | Bilibili DedeUserID、網易 userId、YouTube 帳號或頻道名稱會以明文寫進 info log(`userId: …` 不符合 `DedeUserID=` 的模式) | 否 | `bilibili_account_service.dart:129`;`netease_account_service.dart:97-99`;`youtube_account_service.dart:276-277,306,324` | +| 下載錯誤 | isolate 只回傳 `e.message`/`e.path`,不回傳 URL;`errorMessage` 會存進 DownloadTask | 形式上沒問題 | `download_service.dart:1965-2020` | +| Toast | `ToastService.failure` 只顯示翻譯句。但 `SourceErrorKind.unknown`/`rateLimited` 會直接顯示 adapter 的原始 message;有幾頁用 `ToastService.error(context, e.message)` 顯示遠端例外訊息 | 部分 | `user_message.dart:56-58`;`playlist_detail_page.dart:625-633`;`add_to_bilibili_playlist_dialog.dart:81,243` | +| QR 輪詢錯誤訊息 | `e.toString()` 放進 stream。Bilibili 只在 expired 時顯示,而那時內容是固定的 'Network error';網易完全不顯示 | 無遮蔽,但不上畫面 | `bilibili_account_service.dart:233-238`;`bilibili_login_page.dart:289-291`;`netease_account_service.dart:217` | +| 啟動失敗畫面 | `error.toString()` 原文和 log 路徑 | 否 | `lib/app.dart:87`;`main.dart:68-81` | +| 除錯頁:DB 檢視器 | Track.audioUrl 前 60 字(host 加部分路徑)、Account 的 userId/userName、Settings 的 lyricsAiEndpoint 全文;**不顯示 secure storage** | 部分截斷 | `database_catalog.dart:132-139,164-166,485` | +| Isar 檔案(落盤) | `Track.audioUrl` 是**完整的簽名 URL**,到期時間照各來源回的 expiry 記;來源沒給時記 1 小時(`stream_resolution_service.dart:427-430`)。(核查更正:原寫「(1 至 2 小時有效)」,程式碼裡查不到 2 小時這個依據)Windows 上放在「文件\FMP」 | 否 | `stream_resolution_service.dart:427-471`;`database_provider.dart:50-53` | +| 備份匯出 JSON | **不含**憑證、API key、audioUrl。含 lyricsAiEndpoint、播放與搜尋歷史、歌單來源 URL、ownerUserId。明文,沒有加密 | 不需要 | `backup_service.dart:91-310`;`backup_data.dart:345-372` | +| 下載 metadata.json | 不含 URL 和憑證;含熱門留言者的名稱與頭像 | — | `download_service.dart:1499-1564` | +| 網路:媒體與 CDN | 刻意不帶憑證 | 由設計保證 | `source_http_policy.dart:73-84`;`media_handoff.dart:54-62` | +| 網路:重導向 | 下載 isolate 每跳重算標頭,拒絕私有位址 | 是 | `download_service.dart:1827-1856` | +| 網路:AI 端點 | 使用者的 API key(Bearer)和歌曲標題會送到使用者自訂的 URL;**沒有檢查 https**,填 http 就會明文送出 | 否 | `openai_chat_client.dart:41-67`;`openai_chat_endpoint.dart:1-6` | +| 網路:網易 `X-Real-IP` | 送出偽造的固定 IP(不算外洩,屬於請求偽裝) | — | `netease_playlist_service.dart:250` | +| Crash 回報、分享、診斷上傳 | **查不到**:pubspec 沒有 sentry、firebase、crashlytics、share_plus | — | `pubspec.yaml` | + +--- + +## 5. 硬編碼的 key、secret、appkey + +值一律寫成 `***`。以下沒有任何一項是 FMP 自己申請的私密憑證,都是逆向自各平台前端,或是公開金鑰。但它們在 repo 裡是明文。 + +| 位置 | 類型 | 用途 | +|---|---|---| +| `lib/core/utils/innertube_utils.dart:14` | YouTube InnerTube WEB API key(`***`) | `/youtubei/v1/*` 的 `?key=`。註釋說這是 youtube.com 前端公開的 key(`:8-13`)。另外在 `youtube_login_page.dart` 的 JS fetch 裡也會拼進 URL | +| `lib/core/utils/netease_crypto.dart:23` | 網易 weapi AES 預設金鑰(`***`) | QR 登入的 weapi 加密 | +| `netease_crypto.dart:26` | 網易 AES IV(`***`) | 同上 | +| `netease_crypto.dart:29` | 網易 eapi AES 金鑰(`***`) | 取流的 eapi 加密 | +| `netease_crypto.dart:36-40,48` | 網易 RSA 公鑰模數(公鑰)、eapi 分隔符 | weapi 的金鑰封裝 | +| `lib/services/account/netease_playlist_service.dart:49` | 網易 linux forward API 的 AES 金鑰(`***`) | 歌單管理 `eparams` 加密 | +| `lib/services/account/bilibili_crypto.dart:29-33` | Bilibili RSA 公鑰(base64 DER,公鑰) | cookie refresh 的 correspondPath | +| `lib/data/sources/playlist_import/qq_music_sign.dart:12,18,21` | QQ 音樂簽名用的 XOR key 和索引表(`***`) | QQ 音樂歌單匯入的簽名 | +| `netease_account_service.dart:37-39` | 網易匿名 cookie(偽裝 Windows 客戶端的 os/osver/appver) | QR 登入 | +| `netease_playlist_service.dart:250` | 固定的 `X-Real-IP` | 歌單管理請求 | +| `lrclib_source.dart:24` | lrclib UA,裡面有佔位網址 `github.com/user/fmp` | lrclib 的禮貌 UA | + +**沒有找到**:Bilibili appkey/appsec、WBI mixin key(WBI 沒有實作)、Spotify client secret(Spotify 匯入走 embed 頁,`spotify_playlist_source.dart:57`)、GitHub token(更新檢查走匿名 API)。也沒有 `String.fromEnvironment`/dotenv 這類注入。 + +--- + +## 6. 帳號系統全貌 + +本節只補 §1 與其他審計檔沒寫到的部分。登入流程細節見 §1.2–1.4;刷新與失效的機制見 §1.5;各平台失效判定見 `errors.md` §3.3;secure storage 的 key 與「重設所有資料不清憑證」見 `data.md` §3.1;功能入口見 `features.md` §8。 + +### 6.1 兩份登入狀態:Isar `Account` 與 secure storage + +「是否登入」在程式裡有兩個來源,而且彼此不會自動同步: + +| 讀的人 | 讀哪一份 | 證據 | +|---|---|---| +| 帳號管理頁的三張卡片(頭像、名稱、VIP 圖示、失效紅字、按鈕組) | Isar `Account`(`AccountNotifier` 監聽 `watchByPlatform`) | `account_management_page.dart:34-36,60-123`;`lib/providers/account/account_provider.dart:257-274` | +| `isLoggedInProvider(sourceId)`:匯入對話框的「使用登入狀態匯入」開關、「加入遠端歌單」的登入閘門、遠端編輯 planner | Isar `Account.isLoggedIn` | `account_provider.dart:96-100`;`import_playlist_dialog.dart:274-291`;`track_action_handler.dart:283-287,306-310`;`search_page.dart:1373-1379`;`remote_playlist_sync_provider.dart:75` | +| 各服務的 `isLoggedIn()`:啟動時要不要做 B 站 cookie refresh、要不要做狀態檢查、網易攔截器要不要把 301 當失效 | Isar `Account.isLoggedIn` | `bilibili_account_service.dart:284-287`;`youtube_account_service.dart:126-129`;`netease_account_service.dart:258-261`;`account_provider.dart:133,225`;`netease_auth_interceptor.dart:54` | +| **實際送出去的請求**:`getAuthHeaders()`/`getAuthCookieString()`(Auth For Play、匯入、刷新、三個攔截器、狀態檢查、勳章牆) | **只看 secure storage**(加記憶體快取),不看 `Account` | `bilibili_account_service.dart:258-267,551-575`;`youtube_account_service.dart:108-121`;`netease_account_service.dart:236-247` | + +兩份不一致時會發生的事: + +- **Isar 說未登入、storage 還有憑證**:「重設所有資料」之後就是這樣。UI 全部顯示未登入,播放、下載、詳情、排行仍帶舊 cookie。已記在 §1.5 最後一條與 `data.md` §3.1,這裡不重寫。 +- **Isar 說已登入、storage 讀不到**(`SecureStorageUnavailable`):`_loadCredentials` 降級回 null(`bilibili_account_service.dart:553-564`),請求全部變匿名,帳號卡仍顯示已登入。音訊設定頁的「讀不到憑證儲存」提示是看歌詞 AI key 那一次讀取決定的(`audio_settings_provider.dart:139-146`),帳號頁沒有對應提示。啟動時的狀態檢查接著會怎麼走(已由程式碼確認):`verifyAllAccountStatuses` 依 Isar 判定已登入 → `checkAccountStatus()` 拿不到 cookie,直接回 `invalid`(B `bilibili_account_service.dart:470-473`;Y `youtube_account_service.dart:179-182`;N `netease_account_service.dart:312-315`)→ `markSessionExpired()` 刪 storage、跳「登錄已失效」提示(`account_provider.dart:233-236`)。**推測**:如果讀取失敗只是暫時的,而刪除那一步成功,一組仍然有效的憑證會被刪掉。「讀不到」與「沒有」在這裡被當成同一件事。 +- **B 站 QR 假成功**:頁面顯示成功,兩份狀態都沒寫入。見 §1.2。 + +### 6.2 狀態機(三源共用) + +三個服務實作同一個 `AccountService` 介面(`lib/services/account/account_service.dart:15-48`),狀態轉換的形狀一樣,差別只在觸發點。 + +```mermaid +stateDiagram-v2 + [*] --> 未登入 + 未登入: 未登入(沒有 Account 列、storage 空) + 已登入: 已登入(isLoggedIn=true、storage 有憑證) + 失效: 失效(列保留 sessionExpired=true、storage 已刪) + 未登入 --> 已登入: T1 登入成功 + 已登入 --> 已登入: T2 啟動時 cookie refresh(僅 B 站) + 已登入 --> 已登入: T3 狀態檢查 valid(更新名稱、頭像、VIP) + 已登入 --> 失效: T4 狀態檢查 invalid + 已登入 --> 失效: T5 攔截器判定失效 + 已登入 --> 未登入: T6 使用者登出 + 失效 --> 已登入: T7 重新登錄 + 失效 --> 未登入: T8 失效態按登出 + 已登入 --> 未登入: T9 storage 內 JSON 壞掉 +``` + +| 轉換 | Bilibili | YouTube | 網易雲 | +|---|---|---|---| +| T1 登入成功(寫 storage,列設 `isLoggedIn=true`、`sessionExpired=false`) | `bilibili_account_service.dart:92-130`(`sessionExpired: false` 在 `:126`) | `youtube_account_service.dart:56-96`(`:93`) | `netease_account_service.dart:464-476`(`:474`);失敗時還原快照 `:478-545` | +| T2 cookie refresh | `account_provider.dart:131-152` → `bilibili_account_service.dart:351-454` | 無(`:166-168` 回 true) | 無(`:299-301` 回 true) | +| T3/T4 狀態檢查(啟動、帳號頁右上角按鈕) | `bilibili_account_service.dart:469-508`:-101/-111 才算 invalid | `youtube_account_service.dart:178-233`:401/403 或回應裡沒有使用者資料 | `netease_account_service.dart:311-367`:任何非 200 都算 invalid(風險見 `errors.md` §3.3) | +| T5 攔截器 | `bilibili_auth_interceptor.dart:38-123`(只掛在收藏夾服務) | **沒有**,只記 log(`youtube_auth_interceptor.dart:30-60`) | `netease_auth_interceptor.dart:37-59`(只掛在歌單服務) | +| T6 登出(刪列、清 WebView cookie) | `bilibili_account_service.dart:295-319` | `youtube_account_service.dart:136-155` | `netease_account_service.dart:268-287` | +| T4/T5 的落點 `markSessionExpired` | `bilibili_account_service.dart:321-328` | `youtube_account_service.dart:157-164` | `netease_account_service.dart:289-297` | +| T7 重新登錄 | 失效卡的主按鈕走同一個 `onLogin`(`account_management_page.dart:336-342,75`),也就是 T1 | 同左(`:98`) | 同左(`:119`) | +| T9 JSON 壞掉 | `_discardMalformedCredentials` 刪 storage、`isLoggedIn=false`,不設 `sessionExpired`(`bilibili_account_service.dart:578-584`) | 同類處理(`data.md` §3.1) | 同類處理 | + +以下偵測點**不會**觸發任何轉換: + +- 音源 adapter(播放解析、詳情、排行、匯入、刷新)收到 B 站 -101、網易 301、YouTube `login_required`,只會分類成 `SourceErrorKind.loginRequired`(`bilibili_exception.dart:46`;`netease_exception.dart:34`;`youtube_exception.dart:29`)。`SourceApiException.requiresLogin` 在 `lib/` 裡沒有任何呼叫者(`source_exception.dart:58`)。 +- 勳章牆(帳號頁「電台」)收到非 0 碼只丟例外,UI 顯示 `unknown(LOAD)`(`bilibili_live_client.dart:338-350`;`account_radio_import_sheet.dart:88-93`)。 + +### 6.3 使用者看到什麼 + +| 情境 | 畫面 | 證據 | +|---|---|---| +| 已登入 | 卡片顯示名稱,VIP 時多一個圖示(B `verified`、Y `workspace_premium`、N 預設圖示);按鈕是「歌單」、(僅 B 站)「電台」、「登出」 | `account_management_page.dart:254-256,302-311,321-334` | +| 失效 | 保留頭像,文字是「名稱 · 已失效」並用 error 色;按鈕是「重新登錄」、「登出」 | `:246-262,295-297,335-347` | +| 未登入 | 「未登入」+「登錄」 | `:260-262,348-352` | +| 剛轉成失效 | 一次 warning toast「$platform 登錄已失效,請重新登錄」。啟動檢查直接呼叫;攔截器寫 Isar 後由 watcher 補 | `session_expiry_notifier.dart:14-23`;`account_provider.dart:190-199,236`;`lib/app.dart:128` | +| VIP 從有變沒有 | info toast「$platform VIP 已過期」(只在狀態檢查時比較) | `account_provider.dart:237-240` | +| 播放時收到 loginRequired | 錯誤 toast「需要登入後播放」,不會導向登入頁,帳號狀態也不變 | `lib/core/errors/user_message.dart:49`;`audio.i18n.json:13` | +| 手動驗證 | 「正在檢查」→「已驗證」,或「部分平台檢查失敗:…」 | `account_management_page.dart:129-158` | + +**新發現:失效提示的去重一個 session 只有一次,重新登入也不會重置。** `_notifiedPlatforms` 只有 `add`,沒有移除的地方(`session_expiry_notifier.dart:15,22-23`)。所以同一次 app 執行裡「失效 → 重新登錄 → 再失效」時,第二次失效不會跳提示,只有帳號頁的紅字。 + +**新發現:登入或登出之後,首頁排行不會立刻重抓。** `lib/services/cache` 與排行相關的 provider 都沒有監聽任何帳號 provider(grep `AccountProvider|isLoggedInProvider|accountServicesProvider` 在 `lib/services/cache` 查不到),要等下一次定時刷新才會用新的登入狀態。串流解析快取的鍵裡有 auth header(`playback.md` §3.2),所以不受影響。 + +### 6.4 重新登錄的細節 + +- 重新登錄走的是完整登入流程,沒有「沿用舊帳號」的捷徑。成功後 T1 會把 `sessionExpired` 設回 false。 +- `markSessionExpired` 不清 WebView cookie,只有 `logout` 會清(對照 T6 與 T4/T5 那兩列)。不過三個登入頁在 dispose 時都會清自己網域的 cookie、快取與 WebStorage(`bilibili_login_page.dart:100-124`;`youtube_login_page.dart:29-57`;`netease_login_page.dart:100-119`)。**推測**:WebView 裡通常不會殘留舊 session,重新登錄不至於自動套回舊的失效 cookie;Windows WebView2 的 user data 目錄行為沒有實測。 + +--- + +## 7. 請求類型 × 音源的憑證矩陣 + +### 7.1 讀法與三道閘門 + +- 「帶」=一定附帳號標頭(前提是 secure storage 裡有憑證);「不帶」=程式碼路徑上沒有帳號標頭;「視開關」=要看下面三個開關之一。三道閘門**都不看** Isar `Account.isLoggedIn`,只要 storage 有憑證就會送出(§6.1)。 +- 三個開關: + 1. **Auth For Play**:`Settings.useAuthForPlay(sourceId)`,閘門在 `SourceAuthContext.authForPlay`(`source_auth_context.dart:132-137`)。預設 B 站 true、網易 true、YouTube false(`lib/data/models/settings.dart:76-79,91-92`)。UI 在音訊設定頁,每個音源一個開關(`audio_settings_page.dart:140-163`)。 + 2. **匯入時的 `useAuth`**:`playlistImportAuth`(`source_auth_context.dart:175-181`)。匯入對話框預設 false,未登入時不能打開(`import_playlist_dialog.dart:95,270-293`);帳號頁的「歌單」sheet 固定傳 true(`account_playlists_sheet.dart:275-278`)。 + 3. **`Playlist.useAuthForRefresh`**:`playlistRefreshAuth`(`source_auth_context.dart:184-190`)。欄位預設 false(`lib/data/models/playlist.dart:45`);匯入時直接寫成那次匯入的 `useAuth`(`import_service.dart:250,267`),所以**重新匯入同一個 URL 會覆寫使用者之前改過的值**;歌單編輯對話框可以改,Mix 歌單不顯示這個開關(`create_playlist_dialog.dart:120-140`)。 +- B 站的帳號 cookie 會和 buvid 指紋 cookie 合併送出(`bilibili_source.dart:167-173`);網易的 adapter 只取 `Cookie`(`netease_source.dart:779-783`);YouTube 送 `Cookie` 加 `Authorization: SAPISIDHASH`(`youtube_account_service.dart:108-115`)。 + +### 7.2 矩陣 + +| 請求類型 | Bilibili | YouTube | 網易雲 | +|---|---|---|---| +| **播放(串流解析)** | 視開關|Auth For Play|預設 true|`stream_resolution_service.dart:406-416` → `bilibili_source.dart:213-228`(cid `:456-460`、DASH `:334-343`、durl `:390-399`) | 視開關|Auth For Play|預設 **false**|每種 streamType 先匿名,失敗才帶登入打 InnerTube WEB `/player`(`youtube_source.dart:332-366,121-144`) | 視開關|Auth For Play|預設 true|每次都帶(`netease_source.dart:93-119`) | +| **播放的媒體位元組** | 不帶|無開關|—|`media_handoff.dart:54-62`;`source_http_policy.dart:73-84`。`playbackNetworkRequest` 仍會呼叫 `authForPlay` 把憑證讀出來,放進 `streamResolutionAuth`,再被 `DefaultMediaHandoff` 丟掉(`source_auth_context.dart:140-156`) | 同左 | 同左 | +| **下載(解析與詳情)** | 視開關|Auth For Play|預設 true|解析走同一個 `resolvePrimary(purpose: download)`(`download_service.dart:1043-1050`);詳情 `_fetchVideoDetail`(`:976-985`) | 視開關|同左|預設 false|同上;詳情先匿名(見「曲目詳情」) | 視開關|同左|預設 true|同上 | +| **下載的媒體位元組** | 不帶|無開關|—|憑證會被複製進 isolate 參數(`download_service.dart:802,824,1758`),但 `prepareDownloadHop` 不讀它(`:1851-1855`;`media_handoff.dart:54-62`) | 同左 | 同左 | +| **曲目詳情** | 視開關|Auth For Play|預設 true|`track_detail_provider.dart:185-186` → `bilibili_source.dart:744-753` | 視開關|同左|預設 false|youtube_explode **一律先匿名**;只有它失敗時才帶登入改打 InnerTube(`youtube_source.dart:214-276`) | 視開關|同左|預設 true|`netease_source.dart:381,531-545` | +| **首頁排行** | 視開關|Auth For Play|預設 true|`ranking_cache_service.dart:269-275` → `bilibili_source.dart:865-874,904-908` | **不帶**(開關開著也一樣)|—|—|快取層會呼叫 `authForPlay` 讀出憑證,但 `getRankingTracks` 不看 `request.authHeaders`(`youtube_source.dart:1635-1638`) | **不帶**(同左)|—|—|`getHotRankingTracks` 呼叫時沒有傳 auth(`netease_source.dart:334-338,355-357`) | +| **搜尋** | 不帶|無開關|—|`_searchOptions` 只有 buvid(`bilibili_source.dart:476-493,103-107`);直播間搜尋也不帶(`:1025-1045`) | 不帶|—|—|youtube_explode(`youtube_source.dart:865-874`) | 不帶|—|—|`netease_source.dart:195-205` 沒有 headers | +| **歌單匯入** | 視開關|`useAuth`|對話框 false、帳號 sheet true|`import_service.dart:194-201`;分 P 展開沿用同一份(`:223,590`);`bilibili_source.dart:535-551` | 視開關|同左|同左|帶登入時只走 InnerTube(`youtube_source.dart:1402-1409`)。**Mix 匯入不帶**(`import_service.dart:344`;`youtube_source.dart:1396-1398`) | 視開關|同左|同左|`netease_source.dart:255-280,303-306` | +| **歌單刷新**(手動、自動、遠端編輯後) | 視開關|`Playlist.useAuthForRefresh`|false(匯入時被覆寫成 `useAuth`)|`import_service.dart:441-448`;觸發點 `refresh_provider.dart:124,186`、`auto_refresh_service.dart:102`、`remote_playlist_sync_provider.dart:20-24` | 同左 | 同左 | +| **收藏同步/讀取遠端歌單**(帳號頁「歌單」sheet) | 帶|無開關|—|攔截器注入(`bilibili_favorites_service.dart:48,55`;`bilibili_auth_interceptor.dart:28-33`);入口只在已登入時出現(`account_management_page.dart:321-326`) | 帶|無開關|—|`youtube_playlist_service.dart:55,63`;`youtube_auth_interceptor.dart:21-23` | 帶|無開關|—|`netease_playlist_service.dart:64,68`;`netease_auth_interceptor.dart:22-27` | +| **遠端歌單編輯**(加入/移出、新建) | 帶|無開關(UI 用 `isLoggedInProvider` 擋)|—|`remote_playlist_sync_provider.dart:39-76`;寫入時送 `csrf=bili_jct`(`bilibili_favorites_service.dart:122-136`) | 帶|同左|—|`youtube_playlist_service.dart:88-111,218-223` | 帶|同左|—|`_postLinuxApi` 自己組 `Cookie: os=linux; …`(`netease_playlist_service.dart:221-250`) | +| **歌詞** | 不帶(歌詞與曲目來自哪個音源無關,一律查網易、QQ、lrclib)|—|—|`lib/services/lyrics/` 內 grep `Cookie`、`authHeaders`、`AccountService` 都查不到;歌詞用的網易 client 是另一個類別(`lib/services/lyrics/netease_source.dart:141`) | 同左 | 同左 | +| **電台/直播** | 串流**不帶**(`radio_source.dart:71,128-136`;`bilibili_source.dart:1055-1057`);帳號頁「電台」讀勳章牆**帶** cookie,無開關(`bilibili_account_service.dart:522-532`;`bilibili_live_client.dart:338-346`) | 無此功能(`radio_source.dart:59`,貼 YouTube 連結會被擋,`:140-143`) | 無此功能 | +| **Mix** | 無此功能 | **不帶**|無開關|—|InnerTube `next` 的 context 裡沒有帳號標頭(`youtube_source.dart:1072-1090`);介面本身就沒有 auth 參數(`source_capabilities.dart:49-55`) | 無此功能 | + +### 7.3 值得注意的不一致 + +- **排行:開關打開時 YouTube 與網易的排行仍然是匿名的。** 快取層對三個音源一律讀 `authForPlay`(`ranking_cache_service.dart:269-275`),只有 B 站真的用上。§3.5 說 Auth For Play「控制首頁排行榜」,實際上只對 B 站成立。 +- **YouTube 的「帶登入」只是備援。** 播放和詳情都是匿名先試,只有匿名失敗才帶登入(`youtube_source.dart:346-366,247-273`)。也就是說,登入的 YouTube 使用者就算打開 Auth For Play,平常的請求仍然是匿名的。 +- **i18n 說明比實際範圍窄**:播放認證的副標只寫「播放與歌曲詳情的請求」(`lib/i18n/zh-TW/audioSettings.i18n.json:34`),實際還包括下載解析、下載詳情與 B 站排行。只有 B 站的說明提到排行(`:35`)。 +- **Auth For Play 是否帶,只看 storage 裡有沒有憑證**,不看帳號頁顯示的登入狀態(§6.1)。 +- **歌單刷新的開關會被重新匯入覆寫**(`import_service.dart:250`)。 + +### 7.4 預設值與 migration 對使用者設定值的改寫 + +**預設值的三個來源(目前一致)**: + +| 來源 | B | Y | N | 證據 | +|---|---|---|---|---| +| 現行業務預設 `kDefaultUseAuthForPlayBySource` | true | false(查表不到時回 false) | true | `settings.dart:76-79,91-92` | +| 設定頁載入前的暫定值 | 同上 | 同上 | 同上 | `audio_settings_provider.dart:63-64` | +| 備份匯入時缺鍵的補值 | 同上 | 同上 | 同上 | `backup_data.dart:548-550,586-587` | +| 已淘汰的舊欄位(v1→v2 從這裡搬) | **false** | false | true | `settings.dart:412-429` | + +舊欄位的 B 站預設是 false,現行預設是 true,兩者之間的差距就是 v3→v4 要處理的東西。 + +**所有改寫使用者設定值的地方**(`lib/data/database/database_migration.dart`): + +| # | 步驟 | 改了什麼 | 會不會蓋掉使用者自己的選擇 | 證據 | +|---|---|---|---|---| +| 1 | v0→v1 | 5 個欄位同時等於型別預設時,改寫 `rememberPlaybackPosition=true`、`tempPlayRewindSeconds=10`、`disabledLyricsSources='lrclib'` | 會,前提是使用者剛好把設定調成那個形狀。註釋承認形狀猜測有這個問題,現在只跑一次(`:114-117,167-170`) | `:171-176,240-246` | +| 2 | v0→v1 | `neteaseStreamPriority` 為空時,設 `useNeteaseAuthForPlay=true`、`neteaseStreamPriority='audioOnly'` | **推測**不會:空字串代表這一列從沒寫過網易欄位 | `:181-184` | +| 3 | v0→v1 | **無條件**設 `railExpanded=false`、`detailPanelExpanded=true`、`detailPanelWidth=380` | 會:v0 列上已有的版面值一律被覆蓋(註釋的理由是這些欄位在 v0 不可能被寫過) | `:189-193` | +| 4 | v1→v2 | 把 6 個具名欄位搬進 `sourceSettings`,值照搬 | 不會改值;但搬過去的 B 站舊預設 false 會留到 v4 | `:207-222` | +| 5 | v2→v3 | 現在是空函式。步驟名稱記載它以前會把自動檢查更新打開(欄位已刪) | 現在不會 | `:145-149,229` | +| 6 | **v3→v4** | **B 站 `useAuthForPlay` 無條件設為 true** | **會**:自己關掉的人也會被打開,註釋承認分不出來(`:233-235`) | `:236-238` | +| 7 | 每次啟動的 `repairSettingsInvariants`(不算 migration) | 只修非法值:越界值多數重設為預設值(只有 `detailPanelWidth` 夾到邊界)、空字串補預設(核查更正:原寫「夾取值域」)、`lyricsAiTitleParsingModeIndex==1` 改成 0、首頁排行字串正規化。某個音源的 `SourceSettingsEntry` 不見時會重建,`useAuthForPlay` 回到預設(B/N 為 true) | 只動非法值或缺漏項,不動合法值 | `:252-375`(entry 重建在 `:307-318`,預設值來自 `settings.dart:682-693`) | +| 8 | 備份匯入(不算 migration) | 照備份的值寫回 `useAuthForPlay`,並蓋上 `schemaVersion=4` | 不會改寫。副作用是 v3→v4 之前匯出、B 站為 false 的備份,匯入後仍然是 false,v3→v4 不會再套用 | `backup_service.dart:675-681,748-750` | +| 9 | 「重設所有資料」 | 清空 Isar 後重跑 migration,Settings 回到預設(B/N 為 true) | 會,這是這個功能的本意;但 storage 的憑證仍在,見 §1.5 | `data.md` §2.1、§3.1 | + +--- + +## 8. 登入與未登入時各音源的能力差異 + +判準:只列程式碼裡**真的有分支**的差異。「平台伺服器對登入請求回什麼」不屬於程式碼,一律標「查不到(伺服器端行為)」或「推測」。 + +**總結:整個 `lib/` 沒有任何一處依登入狀態或 VIP 狀態選音質。** grep `isVip` 的結果只有三種用途:帳號頁的 VIP 圖示、「VIP 已過期」提示(`account_provider.dart:227-240`),以及曲目上的 VIP 徽章(`Track.isVip`,由網易的 `fee` 欄位推出,`netease_source.dart:694-709`)。登入與否的唯一差別是「請求有沒有附憑證」,其他交給伺服器決定。 + +### 8.1 Bilibili + +| 項目 | 未登入(或開關關閉) | 已登入且 Auth For Play 開(預設開) | 證據 | +|---|---|---|---| +| 請求參數 | `fnval=16`、`qn=0`、`fourk=1`(DASH);durl 用 `qn=120`。與登入無關 | 參數相同,只多 cookie | `bilibili_source.dart:23-38,334-343,390-399` | +| 音質選擇 | 只讀 `dash.audio`,依位元率排序後照音質等級挑 | 相同 | `:345-363` | +| Hi-Res 無損/杜比全景聲 | 不讀 `dash.flac`、`dash.dolby`,`fnval` 也沒有請求對應的旗標。**登入也拿不到**(程式碼層面) | 同左 | `:349-353`;`playback.md` §3.4 | +| 大會員才有的高位元率 AAC 軌 | 查不到(伺服器端行為) | **推測**:伺服器如果對大會員在 `dash.audio` 多回一條更高位元率的軌,`high` 等級會自動選到它 | `:356-363` | +| 會員專屬/付費影片 | -403、62012 → permissionDenied;-101 → loginRequired | 帶 cookie 後伺服器是否放行:查不到(伺服器端行為) | `bilibili_exception.dart:43-48` | +| 匿名節流 | 註釋記錄 2026-09-22 的實測:匿名打 `ranking/v2` 有 23/40 回 -352,帶 SESSDATA 0/40 | 這是 v3→v4 強制打開的理由 | `settings.dart:71-75`;`database_migration.dart:231-235`(本審計未重現) | +| 需要登入的功能 | 收藏夾讀寫、帳號「歌單」sheet、勳章牆電台匯入、帶登入匯入私人收藏夾都不能用(UI 按鈕只在已登入時出現,或開關被停用) | 可用 | `account_management_page.dart:321-334`;`import_playlist_dialog.dart:288-291` | + +### 8.2 YouTube + +| 項目 | 未登入(或開關關閉,**預設關**) | 已登入且開關開 | 證據 | +|---|---|---|---| +| 取流 | youtube_explode 匿名:audio-only 用 `androidVr`,muxed/HLS 用其他 client | **仍然先匿名**;匿名失敗才帶 cookie 與 SAPISIDHASH 打 InnerTube WEB `/player`,並選同一種 streamType | `youtube_source.dart:332-366,445-583` | +| Premium 高音質 | 沒有任何分支。Premium 只用在帳號頁圖示(topbar logo 的 `iconType` 含 PREMIUM 就算) | 同左 | `youtube_account_service.dart:199-207,502-507` | +| 年齡限制/需要登入 | playability 原因含 age 或 sign in → loginRequired → 「需要登入後播放」 | 匿名失敗後會帶登入再試一次;InnerTube WEB 對年齡限制或會員影片回什麼:查不到(伺服器端行為) | `youtube_source.dart:99-117`;`youtube_exception.dart:29` | +| 頻道會員影片 | 沒有專屬分支,會落在 `login_required`、`private_or_inaccessible` 或 `unplayable` 其中之一,要看伺服器給的字串 | 同上 | `youtube_source.dart:99-117` | +| 詳情 | youtube_explode 匿名 | 匿名失敗才走 InnerTube 帶登入 | `:214-276` | +| 搜尋、Mix、排行 | 匿名 | **同樣匿名**(§7.2) | `:865-874,1072-1090,1635-1638` | +| 需要登入的功能 | 讀取與編輯自己的播放清單、帶登入匯入私人清單 | 可用 | `youtube_playlist_service.dart:63-223` | + +### 8.3 網易雲 + +| 項目 | 未登入(或開關關閉) | 已登入且開關開(預設開) | 證據 | +|---|---|---|---| +| 請求的音質 | `level` 只照設定對應:high → lossless、medium → exhigh、low → standard;`encodeType=flac` | 參數相同,只多 cookie。不看帳號的 `vipType` | `netease_source.dart:101-119,785-794` | +| 實際拿到的音質 | 由伺服器依帳號決定。`media_handoff.dart:18-19` 的註釋也這樣寫;程式碼裡沒有依據,**推測** | 同左 | — | +| 試聽片段 | 回應帶 `freeTrialInfo` 時只寫 log,照完整歌曲回傳,沒有任何提示(已記在 `playback.md` §3.2) | 同左(VIP 歌曲而帳號不是 VIP 時也可能遇到,**推測**) | `netease_source.dart:139-150` | +| 「需要登入」與「需要 VIP」的判定 | `code==301` → 301 loginRequired(排在 VIP 判定之前,#87);`code==404 && fee==0` 也改判 301,但這條在 VIP 判定之後(`:884-891`),只有訊息不含 VIP/付費字樣時才走得到(核查更正:原寫兩條都「排在 VIP 判定之前」);`fee` 為 1/4 或訊息含 VIP、付費等字樣 → -10 vipRequired | 相同 | `netease_source.dart:850-866,884-891,937-958` | +| vipRequired 之後 | 先降一級音質重試(high → medium → low),最後在佇列模式下跳過這首 | 相同 | `audio_stream_quality_fallback.dart:42-67`;`source_exception.dart:18-25` | +| 曲目的 VIP 徽章 | 看歌曲的 `fee`/`privilege.fee`,與使用者是不是 VIP 無關;未登入也會顯示 | 同左 | `netease_source.dart:694-709` | +| 需要登入的功能 | 讀取與編輯自己的歌單、帶登入匯入私人歌單 | 可用 | `netease_playlist_service.dart:68-188` | diff --git a/docs/audit/architecture.md b/docs/audit/architecture.md new file mode 100644 index 000000000..d9cb49b77 --- /dev/null +++ b/docs/audit/architecture.md @@ -0,0 +1,659 @@ +# 架構現況審計 + +> 現況描述,未經確認,不代表目標。 + +審計基準:分支 `docs/audit`,HEAD `6d78fe23`,2026-09-26。統計排除 `*.g.dart`(Isar/slang codegen 產物,可能過期)。 +數字全部由 scratchpad 內的一次性 Python 腳本掃 `lib/` 產出:import 依賴解析 `import`/`export` 指令(`package:fmp/…` 與相對路徑都算),provider 盤點用正規表示式比對頂層 `final xxx = …Provider(`,provider 依賴用括號配對取出宣告本體(NotifierProvider 會再追到 `Xxx.new` 那個類別的本體)裡的 `ref.watch/read/listen/invalidate`。腳本沒解析 Dart AST,所以把 provider 或 `ref` 往外傳給別的類別之後才讀的依賴抓不到(例如 `AutoRefreshService` 拿著 `Ref`,`lib/services/library/auto_refresh_service.dart:17`)。 + +--- + +## 1. 分層 + +### 1.1 實際存在的層 + +| 目錄 | 檔案數 | 行數 | 實際職責(依程式碼觀察) | +|---|---:|---:|---| +| `lib/main.dart`、`lib/app.dart` | 2 | 613 | 行程啟動、平台初始化、全域可變狀態(`audioHandler`、`windowsSmtcHandler`、預讀主題,`lib/main.dart:29-44`);`FMPApp` 在資料庫就緒前後切換兩棵 `MaterialApp`,並錨住啟動期副作用 provider(`lib/app.dart:34-131`) | +| `lib/core/` | 24 | 3,755 | 常量、logger、斷點、共用 UI 服務(toast、圖片載入)、格式化工具;也放了音源專屬工具(`core/utils/netease_crypto.dart`、`core/utils/innertube_utils.dart`) | +| `lib/data/` | 57 | 15,054 | Isar models、repositories、資料庫開啟與遷移、外部音源 adapter(`data/sources/`)、**以及 Riverpod provider**(`data/database/repository_providers.dart`、`data/sources/source_provider.dart`) | +| `lib/services/` | 97 | 33,042 | 業務邏輯;其中不少本身就是 Riverpod `Notifier`(`RadioController`、`RankingCacheService`、`ConnectivityService`、`QueueStateNotifier`、`AudioController`) | +| `lib/providers/` | 39 | 7,640 | Riverpod provider 與 Notifier;也夾帶非 provider 的邏輯(`providers/download/download_scanner.dart` 414 行的檔案掃描、`providers/download/file_exists_cache.dart` 的快取) | +| `lib/ui/` | 124 | 38,959 | go_router、AppShell、頁面、widget、Windows 歌詞子視窗 | +| `lib/i18n/` | 0 個手寫 `.dart` | — | 3 語系 × 38 個 `*.i18n.json`,base locale 為 `zh-CN`(`slang.yaml`),產出 4 個 `strings*.g.dart` | +| **合計** | **343** | **99,063** | | + +**不一致**:`docs/development.md:29-31` 寫 `core/` 放「常量、主題、共享服務、工具」,但主題在 `lib/ui/theme/app_theme.dart`,`lib/core/` 內沒有主題檔;同段寫 `providers/` 是「Riverpod provider 定義」,實際上 162 個 provider 中有 32 個宣告在 `providers/` 之外(見 §4)(核查更正:原寫「161 個」);寫 `app.dart` 負責「路由接線」,實際路由表在 `lib/ui/router.dart:124`,`app.dart` 只引用 `appRouter`(`lib/app.dart:154`)。 + +**不一致**:`docs/development.md:16-24` 畫的是單向 `UI -> providers -> services -> repositories/sources`。實際的層間 import 次數(import 指令數,不含 i18n): + +| 從 \ 到 | core | data | services | providers | ui | main.dart | +|---|---:|---:|---:|---:|---:|---:| +| core | — | 6 | 0 | **1** | 0 | 0 | +| data | 29 | — | 0 | 0 | 0 | 0 | +| services | 103 | 187 | — | **11** | 0 | **1** | +| providers | 28 | 104 | 60 | — | 0 | **1** | +| ui | 197 | 77 | 66 | 139 | — | 0 | + +UI 直接 import `services/` 66 次、`data/` 77 次;`services/` 往回 import `providers/` 11 次;`services/` 與 `providers/` 各有一個檔案 import `main.dart`。 + +### 1.2 AGENTS.md 宣稱的邊界逐條驗證 + +| # | 宣稱 | 結果 | 證據 | +|---|---|---|---| +| 1 | UI 播放控制只呼叫 `AudioController`,不碰 `FmpAudioService`;電台是唯一例外 | **成立** | `lib/ui/` grep `FmpAudioService\|audioServiceProvider\|JustAudioService\|MediaKitAudioService` 無結果;`lib/` 內 `audioServiceProvider` 的消費者只有 `AudioController`(`lib/services/audio/audio_provider.dart:182`)與 `RadioController`(`lib/services/radio/radio_controller.dart:286`) | +| 2 | Isar 只由 `openFmpDatabase()` 開啟 | **成立** | `Isar.open(` 只出現在 `lib/data/database/database_provider.dart:92`;但 `openFmpDatabase()` 被呼叫兩次:`lib/main.dart:374`(預讀主題)與 `lib/data/database/database_provider.dart:111`,第二次靠 `Isar.getInstance`(`:86`)拿回同一實例 | +| 3 | 搜尋頁的音源 chip 是唯一來源選擇器,沒有設定在背後過濾 | **未發現反例(粗查)** | `lib/providers/settings/` 與 `lib/data/models/settings.dart` grep `searchSource\|enabledSearch` 無結果;沒有逐條追搜尋流程 | +| 4 | `audio_provider.dart` 不宣告 provider | **成立** | provider 盤點中 `lib/services/audio/audio_provider.dart` 0 筆;檔內以註解說明它與 `lib/providers/audio/audio_controller_provider.dart` 刻意互相 import(`lib/services/audio/audio_provider.dart:13-17`) | +| 5 | `audioControllerProvider` 與 backend/queue/stream provider 在 `lib/providers/audio/` | **成立** | `lib/providers/audio/audio_controller_provider.dart:26,33,45,56,91`;`lib/providers/audio/stream_resolution_provider.dart:9` | +| 6 | `nowPlayingPublisherProvider`、`playbackSideEffectsProvider`、`queueStateProvider` 宣告在 `lib/services/audio/` 的類別旁 | **成立** | `lib/services/audio/now_playing_publisher.dart:317`、`lib/services/audio/playback_side_effects.dart:237`、`lib/services/audio/queue_state.dart:77` | +| 7 | `neteaseSourceProvider` 是歌詞層的 `NeteaseSource`;同名資料音源只經 `SourceManager` 取得 | **成立** | `lib/providers/lyrics/lyrics_provider.dart:18,36` import `services/lyrics/netease_source.dart`;兩個同名類別:`lib/services/lyrics/netease_source.dart:130`、`lib/data/sources/netease_source.dart:25`。三個具體音源 adapter(bilibili/youtube/netease)在 `lib/data/sources/` 之外沒有任何 import | +| 8 | 規則 A:`lib/core/`、`lib/data/` 不 import `services/`、`providers/` | **成立(含 1 個具名例外)** | 例外:`lib/core/extensions/track_extensions.dart:7` import `providers/download/file_exists_cache.dart`,登錄在 `test/support/layer_boundary_static_rule_test.dart:29`。`data/` 零反向 import。規則沒管 `core → data`(6 次)與 `core ↔ data` 循環(§3.2) | +| 9 | 規則 B:feature 間的邊有快照 | **成立** | 腳本以同一定義(`services/` 與 `providers/` 視為同一 feature)算出 33 條邊,與 `test/support/layer_boundary_static_rule_test.dart:42` 的快照完全相同。**不一致**(小):同檔 `:39` 註解說「31 筆」,快照實為 33 筆。快照內含 feature 互相依賴:`audio ↔ download`、`audio ↔ library`、`audio ↔ lyrics`、`download ↔ library` | +| 10 | `isar.` 只出現在 `lib/data/repositories/`(ADR 0002) | **字面成立,但範圍窄** | 符合測試的 regex 只在 repositories 與測試白名單的 `lib/data/database/database_catalog.dart`、`database_migration.dart`(`test/data/static_rules/isar_boundary_static_rule_test.dart:20-25`)。然而 `Isar` 實例本身傳遍各層:UI 直接 `ref.watch(databaseProvider)` 並自己 new repository、甚至直接跑遷移(`lib/ui/pages/settings/developer_options_page.dart:135-136,548-554`);services 建構子收 `Isar`(`lib/services/account/bilibili_favorites_service.dart:35,237`、`lib/services/backup/backup_service.dart:43`、`lib/services/import/import_service.dart:144`、`lib/services/library/playlist_service.dart:66`) | +| 11 | UI 圖片只經 `lib/ui/widgets/images/` | **成立** | `lib/ui` 在 `widgets/images/` 之外 grep 載圖 API,唯一命中是 `ImageLoadingService.clearNetworkCache()`(`lib/ui/pages/settings/widgets/settings_cache.dart:105`),不是 loader,測試也明列它合法 | +| 12 | 只用 `ScopedSlider`,不直接用 Material `Slider` | **成立** | `Slider(` 在 `lib/` 只出現於 `lib/ui/widgets/controls/scoped_slider.dart:45` | +| 13 | 測試等待慣例、static-rule 測試命名位置 | **未查** | 屬測試面,不在本份範圍 | + +--- + +## 2. 目錄地圖 + +### 2.1 一級與二級目錄 + +| 目錄 | 檔案 | 行數 | 用途(依檔名與內容) | +|---|---:|---:|---| +| `lib/`(根) | 2 | 613 | `main.dart`、`app.dart` | +| `core/`(根) | 4 | 556 | `logger.dart`、`log_file_sink.dart`、`secure_key_value_store.dart`、`third_party_licenses.dart` | +| `core/constants` | 5 | 656 | app 常量、`breakpoints.dart`(`WindowClass`)、版面尺寸、UI 常量、下載檔名 | +| `core/errors` | 1 | 128 | `user_message.dart`(例外 → 使用者文案;import `data/sources/source_exception.dart`) | +| `core/extensions` | 1 | 89 | `track_extensions.dart`(唯一反向 import `providers/` 的檔案) | +| `core/services` | 3 | 1,483 | `image_loading_service.dart`(766 行)、`network_image_cache_service.dart`、`toast_service.dart`(含 2 個 provider) | +| `core/utils` | 10 | 843 | 格式化、`http_client_factory`、`platform_utils`,以及音源專屬的 `netease_crypto`、`innertube_utils`、`thumbnail_url_utils` | +| `data/database` | 4 | 1,353 | `openFmpDatabase()`、`databaseProvider`、遷移、collection 目錄、8 個 repository provider | +| `data/models` | 17 | 2,696 | 11 個 Isar collection(有 `.g.dart`)+ DTO/value object,`models.dart` 是 barrel | +| `data/repositories` | 16 | 3,873 | Isar 存取;`repositories.dart` 是 barrel | +| `data/sources` | 20 | 7,132 | Bilibili/YouTube/NetEase adapter、`SourceManager` 與 4 個 provider、HTTP policy、`playlist_import/`(QQ 音樂、Spotify 歌單解析,4 檔 683 行) | +| `providers/account` | 2 | 291 | 三平台帳號服務與狀態、啟動期 cookie 刷新/狀態檢查、`sourceAuthContextProvider` | +| `providers/audio` | 5 | 806 | `audioControllerProvider` 與協作者 provider、player selectors、音訊/播放設定 | +| `providers/download` | 8 | 1,194 | 下載 provider、`download_scanner.dart`(非 provider 的掃描邏輯)、`file_exists_cache.dart`、兩個近乎同名的 barrel(`download_provider.dart` 9 行、`download_providers.dart`) | +| `providers/library` | 8 | 2,489 | 歌單清單/詳情、播放歷史、刷新管理、兩條歌單匯入(見 §7.4)、`LibraryInvalidationCoordinator` | +| `providers/lyrics` | 2 | 585 | 歌詞來源、自動匹配、目前歌詞解析、歌詞視窗樣式 | +| `providers/search` | 2 | 813 | 搜尋 Notifier(785 行)、排行榜預覽 | +| `providers/settings` | 8 | 920 | 各設定 Notifier(主題、語系、版面、桌面、快捷鍵、刷新間隔、首頁排行、開發者選項) | +| `providers/system` | 3 | 298 | 備份、更新、`windowsDesktopServiceProvider` | +| `providers/ui` | 1 | 244 | 多選模式 | +| `services/account` | 17 | 4,125 | 三平台登入、憑證、auth interceptor、遠端歌單服務 | +| `services/audio` | 35 | 11,930 | 播放控制器、兩個後端、佇列、串流解析、系統媒體控制、各種 coordinator(見 §7.2) | +| `services/backup` | 2 | 1,754 | 備份匯出匯入 | +| `services/cache` | 1 | 342 | 只有 `ranking_cache_service.dart`(一個 `Notifier`) | +| `services/download` | 5 | 3,426 | 下載服務(2,030 行)、下載路徑管理/同步/維護 | +| `services/import` | 3 | 1,937 | `ImportService`(URL 匯入)、`PlaylistImportService`(外部平台歌單比對)、YouTube Mix 簡寫 | +| `services/library` | 8 | 1,346 | `PlaylistService`、自動刷新、遠端歌單編輯與同步 | +| `services/lyrics` | 15 | 4,242 | 歌詞來源(lrclib/網易雲/QQ)、自動匹配、AI 標題解析、歌詞視窗服務 | +| `services/media` | 1 | 63 | `media_handoff.dart` | +| `services/network` | 1 | 130 | `connectivity_service.dart`(一個 `Notifier`) | +| `services/platform` | 3 | 957 | Windows 托盤/快捷鍵/視窗、儲存權限、url_launcher | +| `services/radio` | 3 | 1,604 | `RadioController`(含 6 個 provider)、電台刷新單例、`RadioSource` | +| `services/search` | 2 | 282 | 搜尋服務、多音源 fan-out | +| `services/update` | 1 | 904 | 應用內更新 | +| `ui/`(根) | 3 | 472 | `router.dart`、`app_shell.dart`、`startup_failure_app.dart` | +| `ui/handlers` | 3 | 682 | 曲目動作(選單、協調器) | +| `ui/layouts` | 1 | 624 | `responsive_scaffold.dart`(三種導航殼) | +| `ui/pages` | 39 | 21,791 | 頁面;`settings/` 22 檔 8,612 行、`library/` 8 檔 5,877 行 | +| `ui/theme` | 2 | 268 | Material 主題 | +| `ui/widgets` | 70 | 13,457 | 14 個子目錄(dialogs 11 檔、player 10 檔、layout 9 檔…) | +| `ui/windows` | 6 | 1,665 | Windows 桌面歌詞子視窗(獨立 Flutter engine) | + +### 2.2 最大的 20 個檔案 + +| # | 行數 | 檔案 | +|---:|---:|---| +| 1 | 2,953 | `lib/services/audio/audio_provider.dart` | +| 2 | 2,431 | `lib/data/sources/youtube_source.dart` | +| 3 | 2,030 | `lib/services/download/download_service.dart` | +| 4 | 1,699 | `lib/ui/pages/library/playlist_detail_page.dart` | +| 5 | 1,681 | `lib/ui/pages/search/search_page.dart` | +| 6 | 1,347 | `lib/ui/widgets/panels/track_detail_panel.dart` | +| 7 | 1,220 | `lib/ui/pages/player/player_page.dart` | +| 8 | 1,206 | `lib/services/import/playlist_import_service.dart` | +| 9 | 1,103 | `lib/services/radio/radio_controller.dart` | +| 10 | 1,097 | `lib/ui/pages/library/import_preview_page.dart` | +| 11 | 1,077 | `lib/ui/pages/home/home_page.dart` | +| 12 | 1,069 | `lib/data/sources/bilibili_source.dart` | +| 13 | 1,059 | `lib/ui/pages/history/play_history_page.dart` | +| 14 | 1,017 | `lib/services/audio/media_kit_audio_service.dart` | +| 15 | 1,008 | `lib/data/sources/netease_source.dart` | +| 16 | 945 | `lib/services/backup/backup_data.dart` | +| 17 | 945 | `lib/services/lyrics/lyrics_auto_match_service.dart` | +| 18 | 909 | `lib/ui/windows/lyrics_window.dart` | +| 19 | 904 | `lib/services/update/update_service.dart` | +| 20 | 894 | `lib/data/repositories/playlist_mutation_repository.dart` | + +--- + +## 3. 模組依賴圖 + +節點是二級目錄;`(root)` 代表直接放在一級目錄下的檔案。邊上的數字是 import/export 指令數。i18n 被幾乎所有層 import,圖中省略。 + +### 3.1 層級總覽 + +```mermaid +flowchart TD + main["main.dart"] --> app["app.dart"] + app --> main + main -->|4| services + main -->|3| data + main -->|4| core + main -->|2| ui + app -->|9| providers + app -->|4| ui + ui -->|139| providers + ui -->|66| services + ui -->|77| data + ui -->|197| core + providers -->|60| services + providers -->|104| data + providers -->|28| core + services -->|187| data + services -->|103| core + data -->|29| core + core -->|6| data + services -. "11 反向" .-> providers + core -. "1 反向(具名例外)" .-> providers + services -. "1:全域 late 單例" .-> main + providers -. "1:預讀主題" .-> main +``` + +虛線是與 `docs/development.md` 分層方向相反的邊。 + +### 3.2 services/providers 細節(不含 core/data) + +```mermaid +flowchart LR + subgraph P[providers] + pAcc[account]; pAud[audio]; pDl[download]; pLib[library]; pLyr[lyrics] + pSea[search]; pSet[settings]; pSys[system] + end + subgraph S[services] + sAcc[account]; sAud[audio]; sBak[backup]; sCache[cache]; sDl[download] + sImp[import]; sLib[library]; sLyr[lyrics]; sMed[media]; sNet[network] + sPlat[platform]; sRad[radio]; sSea[search]; sUpd[update] + end + MAIN[main.dart] + + pAcc -->|9| sAcc + pAud -->|12| sAud + pAud --> pAcc + pAud --> pLyr + pAud --> sLyr + pDl -->|8| sDl + pDl --> pAcc + pDl --> pAud + pDl -->|3| pLib + pDl --> pLyr + pDl --> sLyr + pLib --> pAcc + pLib --> pAud + pLib -->|3| pDl + pLib --> sAcc + pLib -->|3| sImp + pLib -->|4| sLib + pLyr -->|3| pAud + pLyr -->|12| sLyr + pSea --> sCache + pSea --> sSea + pSet --> pSys + pSet --> sCache + pSet --> sPlat + pSet --> sRad + pSet --> MAIN + pSys --> pAud + pSys --> sBak + pSys --> sPlat + pSys --> sUpd + sAcc --> sMed + sAud --> sAcc + sAud --> sLyr + sAud --> sNet + sAud --> MAIN + sAud -. 反向 .-> pAud + sAud -. 反向 .-> pDl + sAud -. 反向 .-> pLib + sAud -. 反向 .-> pLyr + sCache -. 反向 .-> pAcc + sCache --> sNet + sDl -. 反向 .-> pDl + sDl --> sAcc + sDl --> sAud + sDl --> sMed + sDl --> sPlat + sImp --> sAcc + sImp --> sSea + sLib -. 反向 .-> pLib + sLib --> sDl + sPlat --> sLyr + sRad -. 反向 .-> pAcc + sRad -. 反向 .-> pAud + sRad -->|6| sAud +``` + +### 3.3 core/data 細節 + +```mermaid +flowchart LR + cRoot["core/(root)"]; cConst[core/constants]; cErr[core/errors]; cExt[core/extensions]; cSvc[core/services]; cUtil[core/utils] + dDb[data/database]; dMod[data/models]; dRepo[data/repositories]; dSrc[data/sources] + pDl[providers/download] + cErr --> dMod + cErr --> dSrc + cExt --> dMod + cExt -. 具名例外 .-> pDl + cSvc --> dSrc + cUtil -->|2| dMod + dMod -->|3| cUtil + dDb -->|7| dMod + dDb -->|2| dRepo + dRepo -->|32| dMod + dSrc -->|25| dMod + dSrc -->|7| cUtil + dRepo -->|4| cRoot + dSrc -->|5| cRoot +``` + +### 3.4 UI 層的依賴面 + +UI 幾乎依賴所有東西,畫成圖沒有資訊量,改列表(`ui/pages` + `ui/widgets` 合計):`core/constants` 75、`core/services` 47、`core/utils` 34、`data/models` 57、`data/sources` 9、`data/database` 6、`data/repositories` 2、`providers/audio` 38、`providers/library` 33、`providers/download` 20、`services/radio` 10、`services/lyrics` 7、`services/audio` 8、`services/library` 8、`services/account` 8。 +UI 直接 import `data/database` 或 `data/repositories` 的檔案:`lib/ui/pages/history/play_history_page.dart:11`、`lib/ui/pages/settings/database_viewer_page.dart:9-10`、`lib/ui/pages/settings/developer_options_page.dart:14,23-24`、`lib/ui/pages/settings/widgets/account_playlists_sheet.dart:14`、`lib/ui/widgets/dialogs/add_to_playlist_dialog.dart:12`。 + +### 3.5 循環依賴 + +以二級目錄為節點求強連通分量(Tarjan),扣除 i18n: + +1. **一個 19 節點的大環**:`main.dart`、`app.dart`、`core/extensions`、`providers/{audio,download,library,lyrics,settings,system}`、`services/{audio,download,library,radio}`、`ui/{(root),handlers,layouts,pages,widgets,windows}`。把它串起來的關鍵邊: + - `services/audio → main.dart`:`lib/services/audio/now_playing_publisher.dart:7` 從 `main.dart` 取全域 `audioHandler`、`windowsSmtcHandler`。 + - `providers/settings → main.dart`:`lib/providers/settings/theme_provider.dart:5` 取預讀主題。 + - `main.dart → ui/(root)`:`lib/main.dart:23` import `startup_failure_app.dart`;`main.dart → ui/windows`:`lib/main.dart:24`。 + - `core/extensions → providers/download`:`lib/core/extensions/track_extensions.dart:7`。 + - 一條實際路徑:`core/extensions → providers/download → providers/audio → services/audio → main.dart → ui/(root) → ui/pages → core/extensions`。 +2. **`core/utils ↔ data/models`**:`core/utils/icon_helpers.dart`、`core/utils/source_presentation.dart` import `data/models/track.dart`;`data/models` 反向 import `core/utils` 3 次。 +3. 兩兩互相 import 的目錄對:`providers/audio ↔ services/audio`(12/2,含刻意的 `audio_provider.dart ↔ audio_controller_provider.dart`)、`providers/audio ↔ providers/lyrics`(1/3)、`providers/download ↔ services/download`(8/2)、`providers/download ↔ providers/library`(3/3)、`providers/library ↔ services/library`(4/1)、`main.dart ↔ services/audio`、`main.dart ↔ app.dart`、`ui/pages ↔ ui/widgets`(117/2)、`ui/handlers ↔ ui/pages`、`ui/handlers ↔ ui/widgets`、`ui/(root) ↔ ui/pages`(router 與頁面互引)。 + +### 3.6 反向依賴清單(services → providers、core → providers、→ main.dart) + +| 來源 | 目標 | +|---|---| +| `lib/services/audio/audio_provider.dart` | `providers/audio/audio_controller_provider.dart`、`providers/download/file_exists_cache.dart`、`providers/library/library_invalidation_coordinator.dart`、`providers/lyrics/lyrics_provider.dart` | +| `lib/services/audio/playback_side_effects.dart` | `providers/audio/audio_controller_provider.dart` | +| `lib/services/audio/now_playing_publisher.dart:7` | `main.dart`(`audioHandler`、`windowsSmtcHandler`) | +| `lib/services/cache/ranking_cache_service.dart` | `providers/account/source_auth_context_provider.dart` | +| `lib/services/download/download_path_maintenance_service.dart`、`download_path_sync_service.dart` | `providers/download/download_scanner.dart`(邏輯放在 providers 目錄,服務層只好反向 import) | +| `lib/services/library/auto_refresh_service.dart` | `providers/library/refresh_provider.dart` | +| `lib/services/radio/radio_controller.dart` | `providers/account/account_provider.dart`、`providers/audio/audio_controller_provider.dart` | +| `lib/core/extensions/track_extensions.dart:7` | `providers/download/file_exists_cache.dart` | +| `lib/providers/settings/theme_provider.dart:5` | `main.dart`(預讀主題) | + +--- + +## 4. Riverpod provider 圖 + +### 4.1 版本與風格 + +- `flutter_riverpod: ^3.4.3`(`pubspec.yaml:15`),lock 為 3.4.3(`pubspec.lock:470-478`)。 +- **全部手寫**:沒有 `riverpod_annotation`/`riverpod_generator`/`@riverpod`,也沒有 `flutter_riverpod/legacy.dart`、`StateNotifier`、`StateProvider`、`ChangeNotifierProvider`、`AsyncNotifier`(grep 無結果)。與 `docs/development.md` 說的「沒有 `StateNotifier`」一致。 +- `ProviderScope` 關掉 Riverpod 3 的自動重試(`lib/main.dart:268`)。 + +### 4.2 盤點 + +共 **162** 個頂層 provider。(核查更正:原寫「161」。原腳本漏掉宣告跨行的 `lyricsMatchForTrackProvider = FutureProvider.autoDispose` 換行 `.family`,`lib/providers/lyrics/lyrics_provider.dart:536-537`) + +| 類型 | 數量 | +|---|---:| +| `Provider`(含 `.autoDispose` 7、`.family` 6) | 100 | +| `NotifierProvider`(含 `.autoDispose` 5、`.family` 2) | 41 | +| `FutureProvider`(含 `.autoDispose` 4、`.family` 4) | 16(核查更正:原寫「`.autoDispose` 3、`.family` 3」「15」) | +| `StreamProvider`(含 `.autoDispose` 3) | 5 | + +| 宣告位置 | 數量 | +|---|---:| +| `providers/library` 24、`providers/audio` 20、`providers/lyrics` 21、`providers/account` 19、`providers/download` 19、`providers/settings` 16、`providers/search` 5、`providers/system` 3、`providers/ui` 3 | 130(核查更正:原寫「`providers/lyrics` 20」「129」) | +| `services/audio` 7、`services/radio` 6、`services/cache` 1、`services/library` 1、`services/network` 1 | 16 | +| `data/database` 9、`data/sources` 4 | 13 | +| `core/services` 2 | 2 | +| `ui/widgets`(`networkBannerVisibleProvider`,`lib/ui/widgets/feedback/network_status_banner.dart:24`) | 1 | + +provider 散在 5 個層、至少 3 種放置慣例:放 `providers//`(多數)、放在類別旁(`services/audio`、`services/radio`、`services/cache`、`services/network`、`core/services/toast_service.dart:262`)、放在 data 層(`data/database/repository_providers.dart`、`data/sources/source_provider.dart:102`)。repository provider 也不統一:8 個在 `data/database/repository_providers.dart`,`downloadRepositoryProvider` 在 `lib/providers/download/download_providers.dart:34`,`radioRepositoryProvider` 在 `lib/services/radio/radio_controller.dart:1079`,`QueueRepository` 沒有 provider。 + +### 4.3 核心 provider 依賴圖 + +實線 = `ref.watch`,虛線 = `ref.read`(含 `ref.listen` 標註)。 + +**播放、音源、帳號** + +```mermaid +flowchart TD + db[(databaseProvider
FutureProvider)] + srcMgr[sourceManagerProvider] + accSvcs[accountServicesProvider] + biliSvc[bilibiliAccountServiceProvider] + ytSvc[youtubeAccountServiceProvider] + neSvc[neteaseAccountServiceProvider] + auth[sourceAuthContextProvider] + platform[audioRuntimePlatformProvider] + backend[audioServiceProvider
JustAudio / MediaKit] + qpm[queuePersistenceManagerProvider] + qm[queueManagerProvider] + srs[streamResolutionServiceProvider] + asm[audioStreamManagerProvider] + mix[mixTracksFetcherProvider] + handler["fmpAudioHandlerProvider
取自 main.dart 全域"] + smtc["windowsSmtcHandlerProvider
取自 main.dart 全域"] + pub[nowPlayingPublisherProvider] + lamc[lyricsAutoMatchCoordinatorProvider] + side[playbackSideEffectsProvider] + qs[queueStateProvider] + conn[connectivityProvider] + toast[toastServiceProvider] + lim[libraryInvalidationCoordinatorProvider] + fec[fileExistsCacheProvider] + lam[lyricsAutoMatchingProvider] + ctrl{{audioControllerProvider
AudioController}} + radio{{radioControllerProvider
RadioController}} + radioRepo[radioRepositoryProvider] + radioSrc[radioSourceProvider] + cur[currentTrackProvider 等 selectors] + win[windowsDesktopServiceProvider] + + biliSvc --> db + ytSvc --> db + neSvc --> db + accSvcs --> biliSvc & ytSvc & neSvc + auth --> db + auth -.-> accSvcs + backend --> platform + qpm --> db + qm --> db & qpm + srs --> db & srcMgr & auth + asm --> srs & auth + mix --> srcMgr + pub --> handler & smtc & platform + side --> pub & lamc + ctrl -.-> backend & qm & asm & toast & pub & side & lamc & mix & conn & lam & qs & lim & fec + cur --> ctrl + cur --> qs + radio --> radioRepo & radioSrc & backend + radio -.-> pub & ctrl & biliSvc & qs + radioRepo --> db + win -. listen/read .-> ctrl +``` + +**下載、歌單、設定** + +```mermaid +flowchart TD + db[(databaseProvider)] + settingsRepo[settingsRepositoryProvider] + trackRepo[trackRepositoryProvider] + plRepo[playlistRepositoryProvider] + dlRepo[downloadRepositoryProvider] + srcMgr[sourceManagerProvider] + srs[streamResolutionServiceProvider] + auth[sourceAuthContextProvider] + dlSvc[downloadServiceProvider] + dlProg[downloadProgressStateProvider] + fec[fileExistsCacheProvider] + lim[libraryInvalidationCoordinatorProvider] + toast[toastServiceProvider] + dpm[downloadPathManagerProvider] + dps[downloadPathSyncServiceProvider] + sds[startupDownloadSyncProvider] + plSvc[playlistServiceProvider] + plList[playlistListProvider] + plDetail[playlistDetailProvider.family] + allPl[allPlaylistsProvider] + refresh[refreshManagerProvider] + autoR[autoRefreshServiceProvider] + dlSet[downloadSettingsProvider] + lcs[lyricsCacheServiceProvider] + settingsN["theme / locale / layout / audioSettings / playbackSettings /
minimizeToTray / globalHotkeys / launchAtStartup / hotkeyConfig /
homeRankingSettingsStore / lyricsDisplayMode / lyricsWindowStyle / refreshSettings"] + rank[rankingCacheServiceProvider] + win[windowsDesktopServiceProvider] + + settingsRepo & trackRepo & plRepo & dlRepo --> db + dlSvc --> dlRepo & trackRepo & db & srcMgr & srs & auth + dlSvc -.-> dlProg & fec & lim & toast + dpm --> settingsRepo + dps --> trackRepo & dpm + sds -.-> dps & lim & allPl + plSvc --> plRepo & trackRepo & settingsRepo & db + plList --> plSvc + plList -.-> plRepo & lim & fec + plDetail --> plSvc + plDetail -.-> srcMgr & lim + allPl --> plSvc + lim -. invalidate .-> allPl & plDetail + lim -.-> fec + refresh -.-> srcMgr & plRepo & trackRepo & auth & db & lim & toast + autoR --> plRepo + dlSet --> settingsRepo & lcs + lcs --> settingsRepo + settingsN --> settingsRepo + settingsN -. "refreshSettings 讀" .-> rank + settingsN -. "globalHotkeys / hotkeyConfig watch" .-> win + rank --> srcMgr + rank -.-> auth +``` + +觀察(附證據): + +- `AudioController` 取協作者全用 `ref.read`(類別內 13 個)與 `readOptional`(2 個),檔內沒有任何 `ref.watch`,註解說明原因是 rebuild 時 `onDispose` 會拆掉後端(`lib/services/audio/audio_provider.dart:175-206`);`RadioController.build()` 對同一個 `audioServiceProvider` 卻用 `ref.watch`(`lib/services/radio/radio_controller.dart:286`)。兩個 Notifier 共用同一個後端實例。 +- 至少 19 個 provider 各自 `watch`/`read` `settingsRepositoryProvider`,讀的是同一列 `Settings`(`lib/data/repositories/settings_repository.dart:14,18` 都是 `get(0)`);部分 Notifier 另外持有一份 `Settings` 複本並就地改(例:`lib/providers/settings/refresh_settings_provider.dart:36,46,91`)。 +- repository 有 provider,但仍大量繞過直接 `XxxRepository(db)`:`lib/providers/audio/audio_controller_provider.dart:40-42,61-62`、`lib/providers/audio/stream_resolution_provider.dart`、`lib/providers/account/source_auth_context_provider.dart:9-12`、`lib/services/account/bilibili_favorites_service.dart:237`、`lib/ui/pages/settings/developer_options_page.dart:135-136,551` 等 20 處以上。 +- 取資料庫有兩種姿勢:`ref.watch(databaseProvider).requireValue`(多數)與 `.value` + null 檢查拋 `StateError`(`lib/data/database/repository_providers.dart:8-11`)或回傳 null(`lib/services/radio/radio_controller.dart:1080-1081`)。 + +### 4.4 AGENTS.md「Providers」段 + +§1.2 第 4–7 條逐句驗過,**全部成立**。但該段只描述了音訊與歌詞兩處的放置規則;整體上 provider 放置沒有單一規則(§4.2),AGENTS.md 與 `docs/development.md:29` 都沒提到 data/core/ui 層也宣告 provider。 + +--- + +## 5. 路由 + +### 5.1 方案 + +`go_router: ^18.0.1`(`pubspec.yaml`),單一全域 `appRouter`(`lib/ui/router.dart:124`),`MaterialApp.router` 接上(`lib/app.dart:154`)。一個 `ShellRoute`(非 `StatefulShellRoute`,註解說是為了切頁時銷毀非活動頁,`lib/ui/router.dart:123,129`)加兩個掛在 root navigator 的全螢幕路由。有 `RoutePaths` 與 `RouteNames` 兩組常量(`lib/ui/router.dart:34-94`);呼叫端混用 `context.push(RoutePaths.x)`、`context.pushNamed(RouteNames.x)`、`context.go(...)`(例:`lib/ui/pages/settings/settings_page.dart:76` 用 path,`lib/ui/pages/settings/widgets/settings_storage.dart:12` 用 name)。`downloadedCategory` 只有 name,沒有 `RoutePaths` 常量,參數靠 `state.extra as DownloadedCategory` 傳(`lib/ui/router.dart:184`),深連結或還原時 extra 會不存在(**推測**:會拋型別錯誤,未實測)。 + +除 go_router 外,沒有找到 `Navigator.push`/`MaterialPageRoute`;對話框、bottom sheet 走 Flutter 原生 API。 + +### 5.2 路由樹 + +```mermaid +flowchart TD + root["GoRouter
navigatorKey: rootNavigatorKey
initialLocation: /"] + shell["ShellRoute → AppShell
navigatorKey: shellNavigatorKey"] + root --> shell + root --> player["/player → PlayerPage
(root navigator, 下滑轉場)"] + root --> radioPlayer["/radio-player → RadioPlayerPage
(root navigator)"] + shell --> home["/ → HomePage (NoTransition)"] + shell --> search["/search → SearchPage (NoTransition)"] + shell --> explore["/explore → ExplorePage"] + shell --> queue["/queue → QueuePage (NoTransition)"] + shell --> history["/history → PlayHistoryPage"] + shell --> library["/library → LibraryPage (NoTransition)"] + library --> downloaded["downloaded → DownloadedPage"] + downloaded --> dlCat[":folderName → DownloadedCategoryPage
(extra: DownloadedCategory)"] + library --> plDetail[":id → PlaylistDetailPage"] + shell --> radio["/radio → RadioPage (NoTransition)"] + shell --> settings["/settings → SettingsPage (NoTransition)"] + settings --> dm["download-manager"] + settings --> audio["audio"] + settings --> lyr["lyrics-source"] + settings --> hr["home-ranking"] + settings --> guide["user-guide"] + settings --> dev["developer"] + dev --> dbv["database"] + dev --> logs["logs"] + settings --> acc["account"] + acc --> bl["bilibili-login"] + acc --> yl["youtube-login"] + acc --> nl["netease-login"] +``` + +共 25 個 `GoRoute`(`lib/ui/router.dart:134-306`)。導航列 6 個目的地:home、search、queue、library、radio、settings(`lib/ui/layouts/responsive_scaffold.dart:47-83`);`/explore`、`/history` 不在導航列,高亮落回首頁(`lib/ui/layouts/responsive_scaffold.dart:85-101`)。 + +### 5.3 手機與桌面的導航殼差異 + +導航殼按**視窗寬度**選,不按平台(`lib/ui/layouts/responsive_scaffold.dart:124-144`,斷點在 `lib/core/constants/breakpoints.dart:15-41`);平台差異只在 `AppContentWrapper`(`lib/app.dart:172-219`)。 + +```mermaid +flowchart TD + W{"WindowClass.of(width)"} + W -->|"compact:寬度未滿 600"| C["_CompactLayout
底部 NavigationBar + MiniPlayer/RadioMiniPlayer"] + W -->|"medium:600–839"| M["_MediumLayout
收合 NavigationRail(不可展開)+ 底部 MiniPlayer"] + W -->|"expanded / large / extraLarge:840 以上"| E["_ExpandedLayout
可展開 NavigationRail + 內容 + 右側 TrackDetailPanel(有曲目時)+ 底部 MiniPlayer
展開狀態與面板寬度存在 Settings"] + P{Platform} + P -->|Windows| PW["AppContentWrapper: CustomTitleBar + NetworkStatusBanner + 路由"] + P -->|其他| PA["AppContentWrapper: SafeArea + 依 banner 著色的狀態列 + NetworkStatusBanner + 路由"] +``` + +另有 Windows 桌面歌詞子視窗:由 `desktop_multi_window` 以 `multi_window` 參數重新進入 `main()`(`lib/main.dart:96-98`),走 `lyricsWindowMain` 獨立 `runApp`(`lib/ui/windows/lyrics_window.dart:28-31`),不經 go_router、不經 slang,文案是寫死的中文預設值由主視窗同步(`lib/ui/windows/lyrics_window.dart:33-53`)。 + +--- + +## 6. 啟動流程 + +### 6.1 順序(主視窗) + +| # | 步驟 | 位置 | 阻塞首畫面? | +|---:|---|---|---| +| 1 | 子視窗參數判斷 `multi_window` → 走歌詞視窗入口 | `lib/main.dart:96-98` | — | +| 2 | 掛 `FlutterError.onError`、`PlatformDispatcher.onError` | `lib/main.dart:102-123` | 同步 | +| 3 | `runZonedGuarded` → `WidgetsFlutterBinding.ensureInitialized()` | `lib/main.dart:125-129` | 同步 | +| 4 | log 落盤 `AppLogger.attachFileSink(await LogFileSink.inAppDocuments())` | `lib/main.dart:135` | **await** | +| 5 | `--minimized` 旗標 | `lib/main.dart:140` | 同步 | +| 6 | `LocaleSettings.useDeviceLocaleSync()` | `lib/main.dart:147` | 同步 | +| 7 | `_preloadSettings()`:`openFmpDatabase()` 開 Isar、讀 `Settings`、存入 `main.dart` 全域主題變數(此時遷移未跑) | `lib/main.dart:150,372-392` | **await** | +| 8 | 圖片快取上限(行動 100 張/50MB,桌面 200 張/80MB) | `lib/main.dart:156-164` | 同步 | +| 9a | Android:`AudioService.init(FmpAudioHandler)`,失敗退回未接通知的 handler | `lib/main.dart:167-195` | **await** | +| 9b | 桌面:`audioHandler = FmpAudioHandler()` dummy | `lib/main.dart:196-199` | 同步 | +| 10 | 桌面:`MediaKit.ensureInitialized()` | `lib/main.dart:202-216` | 同步 | +| 11a | Windows:`Future.wait([SMTC, WindowManager])`,各自被 `_guardStartupStep` 包住;WindowManager 設最小尺寸、隱藏標題列、`setPreventClose(true)`,非 `--minimized` 時 show+focus | `lib/main.dart:219-229,284-343` | **await** | +| 11b | Windows:`UpdateService.cleanupOldWindowsUpdateFiles()` | `lib/main.dart:231` | **fire-and-forget**(未 await) | +| 11c | 非 Windows:`windowsSmtcHandler = WindowsSmtcHandler()` 空殼 | `lib/main.dart:232-239` | 同步 | +| 12 | `registerThirdPartyLicenses()` | `lib/main.dart:243` | 同步 | +| 13 | 註冊 post-frame callback:建立 `RadioRefreshService.instance` 單例 + App 生命週期 observer | `lib/main.dart:247-259` | 首幀後 | +| 14 | `runApp(ProviderScope(retry: null, TranslationProvider(FMPApp)))`,`_appStarted = true` | `lib/main.dart:261-274` | — | +| 15 | `FMPApp.build` watch `databaseProvider` → loading 畫面(用預讀主題) | `lib/app.dart:34-63` | 首幀=loading | +| 16 | `databaseProvider`:`openFmpDatabase()`(reuse 同一實例)→ `runDatabaseMigration` | `lib/data/database/database_provider.dart:109-117` | **阻塞首頁**(loading 直到完成) | +| 17 | data 分支:Windows 先 watch `windowsDesktopServiceProvider`、`minimizeToTray`、`globalHotkeysEnabled`、`launchAtStartup`、`hotkeyConfig` | `lib/app.dart:95-104` | provider 建構同步;內部 I/O fire-and-forget | +| 18 | watch `themeProvider`、`localeProvider`、`playbackSettingsProvider`、`refreshSettingsProvider`、`autoRefreshServiceProvider`、`accountStatusCheckProvider`、`accountSessionExpiryWatcherProvider`、`startupDownloadSyncProvider` | `lib/app.dart:107-131` | 建構同步;各自的 async 工作 fire-and-forget | +| 19 | `MaterialApp.router(appRouter)` → `ShellRoute` → `AppShell` → `HomePage` | `lib/app.dart:133-158`、`lib/ui/router.dart:129-139` | 首頁 | + +eager provider 各自在背景做的事: + +- `windowsDesktopServiceProvider`:`ref.listen(audioControllerProvider)` 並 `ref.read(...notifier)` 綁托盤回呼 → **Windows 上 `AudioController` 在啟動時就被建出來**;`service.initialize(enableHotkeys: false)` 沒 await(托盤圖示、選單)(`lib/providers/system/windows_desktop_provider.dart:18-42`)。 +- `AudioController.build()` 以 `Future.microtask(initialize)` 啟動後端初始化、佇列還原、音量還原、預備目前曲目(不自動播放)(`lib/services/audio/audio_provider.dart:208,337-455`)。Android 上沒有 eager 錨點,第一次被建出來是 AppShell 的 `MiniPlayer` watch `currentTrackProvider`(`lib/ui/widgets/player/mini_player.dart:24`、`lib/providers/audio/audio_player_selectors.dart:169`)。 +- `refreshSettingsProvider`:非同步讀設定後 `ref.read(rankingCacheServiceProvider.notifier)` → `RankingCacheService.build()` 以 microtask 啟動排行榜載入與網路監聽(`lib/providers/settings/refresh_settings_provider.dart:38-62`、`lib/services/cache/ranking_cache_service.dart:146-151`)。 +- `autoRefreshServiceProvider`:`service.start()` 立即檢查一次並每 30 分鐘一次(`lib/services/library/auto_refresh_service.dart:32-45,143-157`)。 +- `accountStatusCheckProvider`:先等 `accountCookieRefreshProvider`(Bilibili cookie 刷新),再依序檢查三平台帳號(`lib/providers/account/account_provider.dart:131-175`)。 +- `startupDownloadSyncProvider`:掃描本地下載檔同步資料庫(`lib/providers/download/startup_download_sync_provider.dart:9-40`)。 +- 應用更新:**沒有**啟動時自動檢查;只在設定頁「關於」手動觸發(`lib/ui/pages/settings/widgets/settings_about.dart:70`),`database_migration.dart:224` 註記自動檢查已刪除。 + +### 6.2 時序圖 + +```mermaid +sequenceDiagram + autonumber + participant OS + participant Main as main() + participant Isar + participant AS as AudioService / SMTC / WindowManager + participant RP as ProviderScope + participant App as FMPApp + participant BG as 背景 provider + + OS->>Main: 啟動(args) + alt args[0] == multi_window + Main->>OS: lyricsWindowMain() 獨立 runApp + end + Main->>Main: 錯誤處理器、runZonedGuarded、ensureInitialized + Main->>Main: await attachFileSink + Main->>Main: useDeviceLocaleSync + Main->>Isar: await openFmpDatabase() + 讀 Settings(未遷移) + alt Android + Main->>AS: await AudioService.init(FmpAudioHandler) + else Windows + Main->>AS: MediaKit.ensureInitialized() + par + Main->>AS: await SMTC 初始化 + and + Main->>AS: await WindowManager(show/focus, preventClose) + end + Main--)AS: cleanupOldWindowsUpdateFiles(fire-and-forget) + end + Main->>Main: registerThirdPartyLicenses;登記 post-frame callback + Main->>RP: runApp(ProviderScope(FMPApp)) + RP->>App: build → watch databaseProvider + App-->>OS: 首幀:loading 畫面(預讀主題) + Main--)Main: post-frame:RadioRefreshService.instance + lifecycle observer + RP->>Isar: databaseProvider:openFmpDatabase(reuse)→ runDatabaseMigration + Isar-->>App: data + opt Windows + App->>BG: windowsDesktopServiceProvider(建出 AudioController,托盤 init 未 await) + App->>BG: minimizeToTray / globalHotkeys / launchAtStartup / hotkeyConfig + end + App->>BG: theme / locale / playbackSettings / refreshSettings + App--)BG: autoRefreshService.start()、accountStatusCheck、sessionExpiryWatcher、startupDownloadSync + BG--)BG: refreshSettings → RankingCacheService(microtask 初始化) + App->>App: MaterialApp.router → AppShell → HomePage + App--)BG: MiniPlayer 首次 watch → AudioController(Android 在此才建)→ microtask initialize +``` + +### 6.3 隱性順序契約 + +- `RadioRefreshService.instance` 是 `static late final`(`lib/services/radio/radio_refresh_service.dart:29`),在首幀後才賦值(`lib/main.dart:251`),而 `RadioController.build()`(`lib/services/radio/radio_controller.dart:279,306`)與 `RefreshSettingsNotifier.setRadioRefreshInterval`(`lib/providers/settings/refresh_settings_provider.dart:94`)直接讀它。目前能成立是因為這兩者要等資料庫就緒、首頁顯示後才會被建立;沒有程式碼保證這個先後(**推測**:資料庫開得比首幀快時不會出事,因為 `databaseProvider` 是非同步的,首幀必然是 loading)。 +- `audioHandler`、`windowsSmtcHandler` 是 `main.dart` 的全域 `late`(`lib/main.dart:29,32`),經 `fmpAudioHandlerProvider`/`windowsSmtcHandlerProvider` 包成 provider(`lib/services/audio/now_playing_publisher.dart:310-315`);在 `runApp` 前任何路徑都有賦值(`lib/main.dart:172-198,226-238`)。 +- 遷移在 `_preloadSettings` 讀完 `Settings` **之後**才跑(`lib/main.dart:371` 註解、`lib/data/database/database_provider.dart:114`),所以預讀主題讀的是遷移前的列。 + +--- + +## 7. 架構觀察 + +### 7.1 上帝類別 + +| 類別 | 規模 | 證據 | +|---|---|---| +| `AudioController`(`Notifier`) | 檔案 2,953 行;約 125 個方法、39 個公開方法、約 41 個欄位;以 `ref.read` 取 13 個、`readOptional` 取 2 個 provider | `lib/services/audio/audio_provider.dart:59,71,175-206`。已拆出 34 個協作檔(§7.2),控制器本身仍是全 repo 最大檔 | +| `YouTubeSource` | 2,431 行、約 63 個方法 | `lib/data/sources/youtube_source.dart:27` | +| `DownloadService` | 2,030 行、檔內 8 個類別、約 57 個方法 | `lib/services/download/download_service.dart` | +| `RadioController` | 1,103 行,同檔另宣告 6 個 provider;直接持有後端 `FmpAudioService` | `lib/services/radio/radio_controller.dart:229,239,286,1072-1104` | +| 頁面 | `PlaylistDetailPage` 1,699、`SearchPage` 1,681、`TrackDetailPanel` 1,347、`PlayerPage` 1,220 行 | §2.2 | + +### 7.2 過深的間接層(音訊) + +`lib/services/audio/` 35 檔 11,930 行,一次播放請求會經過:`AudioController` → `QueueCommands`/`QueueManager`/`QueuePersistenceManager`/`QueueStateNotifier` → `PlaybackRequestSession`(882 行、9 個型別)→ `AudioStreamManager` → `StreamResolutionService`(`lib/providers/audio/stream_resolution_provider.dart:9`)→ `SourceManager` capability → adapter;結果回來再經 `PlaybackEventRouter`(546 行、27 個型別)、`PlaybackHandoffGate`、`PlaybackRecoveryCoordinator`、`PlaybackSideEffects` → `NowPlayingPublisher` → `FmpAudioHandler`/`WindowsSmtcHandler`。另有 1 行的 `audio_playback_types.dart`(只有 `enum PlayMode`)與 10 行的 `mix_playlist_types.dart`(一個 typedef + 轉 export)。本份只描述層數,沒有逐條判斷哪一層是否必要。 + +### 7.3 重複的抽象 + +- **兩個 `NeteaseSource`**:`lib/data/sources/netease_source.dart:25`(播放音源)與 `lib/services/lyrics/netease_source.dart:130`(歌詞),各自 new 實例(`lib/data/sources/source_provider.dart:14`、`lib/providers/lyrics/lyrics_provider.dart:37`)。電台另有自己的 `RadioSource`/`BilibiliLiveClient`(`lib/services/radio/radio_source.dart:60,70`),`RadioRefreshService` 在沒注入時還會自己 new 一個 `RadioSource`(`lib/services/radio/radio_refresh_service.dart:75`)。 +- **repository 有 provider 又被直接 new**:§4.3。 +- **設定分散在十多個 Notifier**:每個都讀寫同一列 `Settings`(§4.3)。 +- **資料庫就緒檢查三種寫法**:`.requireValue`、`.value` 拋 `StateError`、`.value` 回 null(§4.3)。 + +### 7.4 命名與位置不一致 + +- `lib/services/audio/audio_provider.dart` 名為 `_provider` 卻不宣告 provider,內容是 `AudioController`;`RadioController` 則把類別與 provider 放同一檔且放在 `services/`(`lib/services/radio/radio_controller.dart:1086`)。同類東西兩種放法。 +- `lib/services/audio/audio_service.dart`(`FmpAudioService` 介面)與第三方套件 `audio_service` 同名;`audio_handler.dart` 才是接 `audio_service` 套件的那個。 +- `lib/providers/download/download_provider.dart`(9 行 barrel)與 `download_providers.dart` 只差一個 s;後者再轉 export `download_scanner.dart`、`services/download/download_service.dart`、`data/database/repository_providers.dart`,`lib/ui/router.dart:30` 為了 `DownloadedCategory` 引入整條 barrel 鏈。 +- 兩條「歌單匯入」:`import_playlist_provider.dart`(`ImportService`,URL 匯入)與 `playlist_import_provider.dart`(`PlaylistImportService`,外部平台比對),名稱互為倒裝(`lib/providers/library/import_playlist_provider.dart:54`、`lib/providers/library/playlist_import_provider.dart:111`);同一個對話框兩個都用(`lib/ui/pages/library/widgets/import_playlist_dialog.dart:115,173`)。 +- 放錯層的邏輯:`download_scanner.dart`(檔案掃描、`Isolate.run`)與 `file_exists_cache.dart` 在 `providers/`,因而造成 `services → providers` 與 `core → providers` 的反向依賴(§3.6);`core/services/` 與 `services/` 兩個「服務」目錄並存;`core/utils/` 內有網易雲加密與 YouTube innertube 工具;`services/cache/` 只有一個排行榜 Notifier。 +- `lib/core/errors/user_message.dart`、`lib/core/services/image_loading_service.dart` import `data/sources/`,讓 `core` 依賴 `data`,而 `data` 又依賴 `core`(§3.5)。 +- 平台分支殘留:產品只出 Android/Windows(`pubspec.yaml` 註解「FMP 不出 Linux/macOS」),但 `lib/main.dart:156,167,202,232`、`lib/services/audio/audio_runtime_platform.dart` 仍處理 iOS/Linux/macOS。 + +### 7.5 以 widget 為錨的系統副作用 + +- 桌面歌詞子視窗的開啟與所有同步(位置、歌詞、播放狀態、主題、語系、樣式)只寫在 `TrackDetailPanel` 的 `ref.listen` 裡(`lib/ui/widgets/panels/track_detail_panel.dart:112-193,273-317,557`);該 panel 只在 `_ExpandedLayout`(寬 ≥ 840)且有曲目時掛載(`lib/ui/layouts/responsive_scaffold.dart:325-327,364,514`)。**推測**:視窗縮到 840 以下、或 panel 被卸載時,已開啟的歌詞視窗停止更新;未實機驗證。 +- 相對地,帳號失效提示這類副作用刻意錨在 `FMPApp` 上,註解與 static-rule 說明原因是 Riverpod 3 會暫停被不透明路由蓋住的頁面上的 watch(`lib/providers/account/account_provider.dart:183-189`)。兩處採用不同策略。 + +### 7.6 全域可變狀態 + +`lib/main.dart:29-44`(`audioHandler`、`windowsSmtcHandler`、`launchMinimized`、三個預讀主題變數)、`RadioRefreshService.instance`(`lib/services/radio/radio_refresh_service.dart:29`)、`LyricsWindowService.instance`(`lib/services/lyrics/lyrics_window_service.dart:99`)、`UrlLauncherService.instance`(`lib/services/platform/url_launcher_service.dart:55`)、`rootNavigatorKey`/`shellNavigatorKey`/`appRouter`(`lib/ui/router.dart:97,101,124`)。前兩類是 §3.5 大環的成因。 diff --git a/docs/audit/data.md b/docs/audit/data.md new file mode 100644 index 000000000..6b1364f4d --- /dev/null +++ b/docs/audit/data.md @@ -0,0 +1,362 @@ +# 資料層現況審計(Isar/KV/快取/下載/備份/設定) + +> 現況描述,未經確認,不代表目標。 + +審計基準:分支 `docs/audit`(HEAD `6d78fe23`),2026-09-26。只讀原始碼,未執行 app。 +行號都是實際看過的位置。`*.g.dart` 只用來確認「Isar 實際持久化了哪些 getter」,它是 codegen 產物,可能過期,以原始碼為準。 +標「**推測**」的是依程式碼推論、未實測;標「**不一致**」的是文件(含註釋)和程式碼對不上。 + +--- + +## 1. Isar schema + +### 1.1 版本與來源 + +| 項目 | 事實 | 證據 | +|---|---|---| +| 套件 | `isar_community` 3.3.2(社群 fork),`isar_community_flutter_libs` 3.3.2,generator `isar_community_generator` 3.3.2 | `pubspec.yaml:18-19,95`;`pubspec.lock:688-711`(`source: hosted`,`url: https://pub.dev`) | +| 為何是 fork | 上游 `isar` 3.1.0+1 已停更,它的 generator 把 analyzer 鎖在 `<6.0.0`,Riverpod 3 裝不起來;v4 沒有 v3→v4 遷移工具。換 fork 的 commit 是 `3b1c7244`(2026-09-02) | `docs/adr/0007-isar-stays-on-v3.md`;`git show 3b1c7244` | +| fork 現況 | pub.dev 上最新版是 3.3.2,發佈者 isar-community.dev(已驗證),自述「主要做 v3 的 bug 修正與小更新」。頁面只寫了相對日期(約 6 個月前),查詢日 2026-09-26 | pub.dev/packages/isar_community | +| 目標平台 | 只出 Android 與 Windows(「FMP 不出 Linux/macOS」) | `pubspec.yaml:24-25` | +| Windows DLL | 檔名從 `isar.dll` 改成 `libisar.dll` | ADR 0007 §後果(未驗證建置產物) | +| 開啟參數 | `maxSizeMiB: 2048`;`compactOnLaunch`:檔案 ≥ 8 MiB 且 ratio ≥ 2.0 時壓縮 | `lib/data/database/database_provider.dart:92-106` | +| DB 名稱/位置 | `fmp_database.isar`(加 `.lock`),放在 `getApplicationDocumentsDirectory()/FMP/`。Windows 上這是使用者的「文件」資料夾,Android 上是 app 私有目錄。舊版放在 documents 根目錄的檔案,啟動時會搬過來 | `database_provider.dart:14-17,23-25,50-83` | +| 開啟入口 | `openFmpDatabase()` 在 `runApp` 前被 `_preloadSettings()` 先呼叫一次(這時遷移**還沒跑**),之後 `databaseProvider` 靠 `Isar.getInstance` 重用同一個實例 | `lib/main.dart:372-392`;`database_provider.dart:85-90,109-117` | +| 資料量 | ADR 0007 提到一份真實 DB 副本有 1,534 列;commit `25726c46` 的說明提到 332 筆 PlayHistory。**使用者目前 DB 的實際大小查不到**(沒有執行 app) | ADR 0007 §決策;`git show 25726c46` | +| 內建上限 | 播放歷史預設保留 10,000 筆、佇列上限 10,000、搜尋歷史 100 筆 | `lib/data/models/settings.dart:209`;`lib/core/constants/app_constants.dart:32,35` | + +### 1.2 Collections(共 11 個)與 embedded(2 個) + +schema 清單是 `fmpDatabaseCollections` 產生的 `fmpDatabaseSchemas`,除錯頁的資料庫檢視器也吃同一份清單(`lib/data/database/database_catalog.dart:50-144`)。 + +**注意:Isar 會持久化所有沒標 `@ignore` 的 public getter。** 從 `track.g.dart` 看得到 `formattedDuration`、`groupKey`、`hasValidAudioUrl`、`isPartOfMultiPage`、`sourcePageKey`、`uniqueKey` 都在 PropertySchema 裡(`lib/data/models/track.g.dart:54-140`)。`PlayQueue` 的 `length`/`hasNext`/`currentTrackId`、`Playlist` 的 `needsRefresh`/`trackCount`/`isImported`、`RadioStation.uniqueKey` 也一樣會被存下來(見各自的 `.g.dart`)。這些值只在 `put` 的當下計算,其中 `needsRefresh`、`hasValidAudioUrl` 這類跟時間有關的欄位,存在磁碟上的值會過時。 + +| Collection | 檔案 | 主鍵 | 欄位(型別) | 索引 | +|---|---|---|---|---| +| `Track` | `lib/data/models/track.dart:37-348` | autoIncrement | sourceId(String)、sourceType(String)、title、artist?、ownerId(int?)、channelId?、durationMs?、thumbnailUrl?、**audioUrl?**、**audioUrlExpiry?**、isAvailable、isVip、unavailableReason?、playlistInfo(List\)、pageCount?(**沒標 @ignore,會被存**)、cid?、pageNum?、parentTitle?、bilibiliAid?、originalSongId?、originalSource?、createdAt、updatedAt?;`viewCount` 標了 `@ignore` | `sourceId`(:42)、`sourceType`(:46)、`cid`(:248)、`updatedAt`(:273)、複合索引 `sourcePageKey`+`cid`(:277-278) | +| `PlaylistDownloadInfo`(embedded) | `track.dart:10-34` | — | playlistId(int)、playlistName(String)、downloadPath(String,空字串代表沒下載) | — | +| `Playlist` | `lib/data/models/playlist.dart:6-88` | autoIncrement | name、description?、coverUrl?、hasCustomCover、sourceUrl?、importSourceType?、refreshIntervalHours?、lastRefreshed?、notifyOnUpdate、ownerName?、ownerUserId?、useAuthForRefresh、isMix、mixPlaylistId?、mixSeedVideoId?、trackIds(List\)、createdAt、updatedAt?、sortOrder | `name` **unique**(沒設 replace)(:11)、`sortOrder`(:66) | +| `PlayQueue` | `lib/data/models/play_queue.dart:18-85` | autoIncrement | trackIds(List\)、currentIndex、lastPositionMs、isShuffleEnabled、loopMode(enum 以 name 存)、originalOrder?、lastVolume、lastUpdated?、isMixMode、mixPlaylistId?、mixSeedVideoId?、mixTitle? | 無 | +| `PlayHistory` | `lib/data/models/play_history.dart:10-77` | autoIncrement | sourceId、sourceType、cid?、title、artist?、durationMs?、thumbnailUrl?、playedAt、trackKey(getter) | `sourceId`(:15)、`sourceType`(:19)、`playedAt`(:38)、`trackKey`(:46-47) | +| `Settings` | `lib/data/models/settings.dart:212-734` | **固定 `id = 0`**(單例) | 見 §7;另有 6 個 `@Deprecated` 的舊欄位 | 無 | +| `SourceSettingsEntry`(embedded) | `settings.dart:127-149` | — | sourceId、streamPriority(逗號字串)、useAuthForPlay(bool) | — | +| `SearchHistory` | `lib/data/models/search_history.dart:6-20` | autoIncrement | query、timestamp | `query`(:11)、`timestamp`(:15) | +| `DownloadTask` | `lib/data/models/download_task.dart:24-107` | autoIncrement | trackId、playlistId?、playlistName?、savePath?、status(enum 以 name 存)、progress、downloadedBytes、totalBytes?、errorMessage?、tempFilePath?、priority、createdAt、completedAt? | `trackId`(:29)、`savePath`(:39)、`status`(:43)、`priority`(:63) | +| `RadioStation` | `lib/data/models/radio_station.dart:7-58` | autoIncrement | url、title、thumbnailUrl?、hostName?、hostAvatarUrl?、hostUid?、sourceType、sourceId、sortOrder、createdAt、lastPlayedAt?、isFavorite | `url` **unique**(:12)、`sourceType`(:31)、`sourceId`(:35)、`sortOrder`(:39)、`isFavorite`(:49) | +| `LyricsMatch` | `lib/data/models/lyrics_match.dart:9-28` | autoIncrement | trackUniqueKey、lyricsSource、externalId、offsetMs、matchedAt | `trackUniqueKey` unique + replace(:14) | +| `LyricsTitleParseCache` | `lib/data/models/lyrics_title_parse_cache.dart:5-20` | autoIncrement | trackUniqueKey、sourceType、parsedTrackName、parsedArtistName?、confidence、provider、model、createdAt、updatedAt | `trackUniqueKey` unique + replace(:9) | +| `Account` | `lib/data/models/account.dart:9-48` | autoIncrement | platform、userId?、userName?、avatarUrl?、isLoggedIn、lastRefreshed?、loginAt?、isVip、sessionExpired | 無(`platform` 沒有索引) | + +**Isar link:沒有任何 `IsarLink`/`IsarLinks`/`@Backlink`。** 整個 lib 都 grep 不到。collection 之間的關係全部是手動維護的整數 id 或字串鍵: + +- `Playlist.trackIds`、`PlayQueue.trackIds`、`DownloadTask.trackId` 指向 `Track.id`。 +- `Track.playlistInfo[].playlistId` 和 `DownloadTask.playlistId` 指向 `Playlist.id`。 +- `PlayHistory.trackKey`、`LyricsMatch.trackUniqueKey`、`LyricsTitleParseCache.trackUniqueKey` 用的是 `TrackKey.format()` 產生的字串,格式是 `sourceType:sourceId[:cid]`(`lib/data/models/track_key.dart:19-20`)。 + +參照完整性沒有 DB 層保證。`DataIntegrityRepository.scan/repair` 能修,但在 lib 裡唯一的呼叫點是開發者選項的「重設所有資料」`clearEverything()`(`lib/ui/pages/settings/developer_options_page.dart:551`)。**scan/repair 在 lib 裡有沒有其他呼叫點:查不到。** + +```mermaid +erDiagram + Track { + int id PK + string sourceId "index" + string sourceType "index" + int cid "index, nullable" + string sourcePageKey "composite index with cid" + string audioUrl "signed URL, nullable" + datetime audioUrlExpiry + string title + datetime updatedAt "index" + } + PlaylistDownloadInfo { + int playlistId + string playlistName + string downloadPath + } + Playlist { + int id PK + string name "unique" + int sortOrder "index" + string sourceUrl + bool useAuthForRefresh + int_list trackIds + } + PlayQueue { + int id PK + int_list trackIds + int currentIndex + int lastPositionMs + } + PlayHistory { + int id PK + string trackKey "index, getter" + datetime playedAt "index" + } + DownloadTask { + int id PK + int trackId "index" + int playlistId + string savePath "index" + string status "index" + int priority "index" + } + LyricsMatch { + int id PK + string trackUniqueKey "unique replace" + string lyricsSource + string externalId + } + LyricsTitleParseCache { + int id PK + string trackUniqueKey "unique replace" + } + RadioStation { + int id PK + string url "unique" + string sourceType "index" + string sourceId "index" + } + SearchHistory { + int id PK + string query "index" + datetime timestamp "index" + } + Settings { + int id PK "always 0" + int schemaVersion + } + SourceSettingsEntry { + string sourceId + string streamPriority + bool useAuthForPlay + } + Account { + int id PK + string platform + bool isLoggedIn + bool sessionExpired + } + Track ||--o{ PlaylistDownloadInfo : "embedded" + Settings ||--o{ SourceSettingsEntry : "embedded" + Playlist }o--o{ Track : "trackIds (int list, no link)" + PlayQueue }o--o{ Track : "trackIds (int list, no link)" + DownloadTask }o--|| Track : "trackId (int)" + DownloadTask }o--o| Playlist : "playlistId (int)" + PlaylistDownloadInfo }o--|| Playlist : "playlistId (int)" + PlayHistory }o--o| Track : "trackKey string" + LyricsMatch |o--o| Track : "trackUniqueKey string" + LyricsTitleParseCache |o--o| Track : "trackUniqueKey string" +``` + +**不一致:** `play_history.dart:43-45` 的註釋說:「這個索引加上去之前就存在的列不會有索引項,所以 v0 → v1 的遷移必須把所有既有列重寫一次。」可是 `_migrateV0ToV1` 只動 Settings(`database_migration.dart:171-194`),沒有重寫 PlayHistory。同一個 commit(`25726c46`)的 commit message 反而寫「Isar rebuilds the index for existing rows … No backfill step is needed」。所以三方說法不同:註釋說要重寫,commit 說不用,程式碼也沒寫。 + +--- + +## 2. Migration + +### 2.1 機制 + +- 版本號存在 `Settings.schemaVersion`(`settings.dart:221`),目前的常數是 `kFmpSchemaVersion = 4`(`lib/data/database/database_migration.dart:33`)。 +- 舊列讀出來的 `schemaVersion` 會是 `Isar.minLong`,負數一律當成 v0(`database_migration.dart:164-165`)。 +- 唯一入口是 `runDatabaseMigration`(`:38-68`),整段包在**一個** `isar.writeTxn` 裡: + 1. 沒有 Settings 列(全新安裝)時,寫入 `createBootstrapSettings()` 並直接蓋上目前版本(`:42-46`)。Android 的圖片快取上限預設 16 MB(`:106-112`)。 + 2. 否則依序套用 `fmpMigrationSteps` 裡 `to` 大於目前版本的步驟(`:48-57`),每一步都寫 info log。 + 3. 已有 Settings 列時,每次啟動都會跑 `repairSettingsInvariants`(`:252-375`;全新安裝那條分支不跑,`:42-58`)(核查更正:原寫「每次啟動都會跑」):夾取值域、空字串補預設、確保每個內建音源都有 `SourceSettingsEntry`。它不屬於遷移,所以不掛版本號。 + 4. 每次啟動都會跑 `_ensureHealthyPlayQueue`(`:70-82`):沒有佇列就建一個;整列都是型別預設值時把 `lastVolume` 設回 1.0。 + 5. 每次啟動都會跑 `_relinkLyricsMatchesToCidKeys`(`:89-103`):把 Bilibili 還用兩段式鍵的歌詞匹配改成三段式鍵。 + 6. 每次啟動都清空 `LyricsTitleParseCache`(`:66`)。這張表等於只活一個 session 的快取。 +- 觸發點:`databaseProvider` 開 DB 後馬上呼叫(`database_provider.dart:109-117`);`FMPApp.build` 會 watch 它(`lib/app.dart:34`)。開發者選項的「重設所有資料」清空 DB 後也會再跑一次(`developer_options_page.dart:551-554`)。 +- 備份匯入重建 Settings 時,會直接蓋上 `schemaVersion = kFmpSchemaVersion`(`lib/services/backup/backup_service.dart:748-750`)。 + +### 2.2 每一版 + +| 步驟 | 名稱 | 做了什麼 | 位置 | +|---|---|---|---| +| 0→1 | infer pre-versioning defaults | 舊列同時符合「5 個欄位都是型別預設」的形狀時,補回 `rememberPlaybackPosition=true`、`tempPlayRewindSeconds=10`、`disabledLyricsSources='lrclib'`;`neteaseStreamPriority` 為空時補網易的預設;版面欄位一律改成 `railExpanded=false`、`detailPanelExpanded=true`、`detailPanelWidth=380` | `database_migration.dart:171-194,240-246` | +| 1→2 | fold per-source settings into one list | 把 6 個具名欄位(`*StreamPriority`、`use*AuthForPlay`)折成 `sourceSettings` 清單。**只搬不刪**,舊欄位保留原值,方便降級 | `:207-222`;舊欄位 `settings.dart:321-336,414-429` | +| 2→3 | retired | 空函式。原本是把 `autoCheckUpdates` 打開,該欄位已刪;步驟保留只是為了佔住版本號 | `:229` | +| 3→4 | use the Bilibili login state for playback requests | 所有既有安裝的 Bilibili `useAuthForPlay` 一律改成 true。使用者自己關掉的也會被打開,註釋承認這一點 | `:236-238` | + +### 2.3 失敗時的行為 + +- 整段在同一個寫入交易裡,任何一步丟例外,整個交易都會回滾(`database_migration.dart:37-39`)。 +- 例外會讓 `databaseProvider` 進入 error 狀態,畫面顯示 `t.general.initFailed` 加上 `error.toString()` 原文(`lib/app.dart:64-90`,原文在 `:87`)。沒有重試:Riverpod 的自動重試已經被全域關掉(`lib/main.dart:268`)。 +- 這個錯誤畫面沒有匯出或修復的入口。**推測:** 使用者只能看到錯誤字串,資料不會被動到。 +- `_preloadSettings()` 開 DB 失敗時只記 log,然後用預設主題繼續(`main.dart:382-391`)。 + +--- + +## 3. 安全儲存與其他 KV + +**`shared_preferences`、Hive、GetStorage、sqflite 都不在依賴裡**(`pubspec.yaml` 全文)。持久化 KV 只有兩類:Isar 的 `Settings` 單例(§7)和 `flutter_secure_storage`。 + +### 3.1 flutter_secure_storage(10.3.1) + +封裝在 `SecureKeyValueStore`/`FlutterSecureKeyValueStore`(`lib/core/secure_key_value_store.dart:33-69`)。平台例外一律轉成 `SecureStorageUnavailable`,只帶錯誤碼、不帶訊息(`:13-27,60-68`)。註釋說後端是 Android Keystore 和 Windows DPAPI(`:7-9`),**未驗證**。`pubspec.yaml:67-73` 說明了刻意不升 11.x 的原因(11.x 拿掉了 9.x cipher 的遷移來源)。 + +| Key | 值(型別) | 寫入者 | 讀取者 | 刪除時機 | +|---|---|---|---|---| +| `account_bilibili_credentials` | JSON 字串:`sessdata`、`biliJct`、`dedeUserId`、`dedeUserIdCkMd5`、`refreshToken`、`savedAt`(`lib/services/account/bilibili_credentials.dart:32-39`) | `BilibiliAccountService.loginWithCookies`(`bilibili_account_service.dart:115-118`)、`refreshCredentials`(`:425-428`) | `_loadCredentials`(`:551-576`),有記憶體快取 | `logout`(`:297`)、`markSessionExpired`(`:324`)、JSON 壞掉時(`:578-584`) | +| `account_youtube_credentials` | JSON:`sid`、`hsid`、`ssid`、`apisid`、`sapisid`、`secure1Psid`、`secure3Psid`、`secure1Papisid`、`secure3Papisid`、`loginInfo`、`datasyncId`、`savedAt`(`youtube_credentials.dart:57-70`) | `YouTubeAccountService.loginWithCookies`(`youtube_account_service.dart:84-87`) | `_loadCredentials`(`:537` 起) | `logout`(`:139`)、`markSessionExpired`(`:161`)、JSON 壞掉時 | +| `account_netease_credentials` | JSON:`musicU`、`csrf`、`userId`、`savedAt`(`netease_credentials.dart:32-37`) | `_persistCredentials`(`netease_account_service.dart:464-476`)、`_restoreLoginSnapshot`(`:530-545`) | `_loadCredentials`(`:402-431`)、`_captureLoginSnapshot`(`:478-528`) | `logout`(`:270`)、`markSessionExpired`(`:292`)、快照還原時 | +| `lyrics_ai_api_key` | 純字串(OpenAI 相容 API key) | `LyricsAiConfigService.saveApiKey`(`lib/services/lyrics/lyrics_ai_config_service.dart:74-82`),UI 在 `lyrics_source_settings_page.dart:159,164` | `readApiKey`(`:70-72`)、`loadConfig`(`:40-63`) | 存空字串時刪除(`:76-78`) | + +**已知落差:「重設所有資料」不會清憑證。** `clearEverything()` 只清 Isar(`lib/data/repositories/data_integrity_repository.dart:55-56`),secure storage 裡的三組憑證都還在。三個 `getAuthHeaders()` 只看 secure storage,不看 `Account.isLoggedIn`(例如 `bilibili_account_service.dart:264-267`)。**已由程式碼確認(核查):** 重設之後 Account 列被清掉,UI 顯示「未登入」,但播放解析、下載時的詳情請求、曲目詳情、排行榜仍然會帶著舊 cookie 出去:重設後 `runDatabaseMigration` 重建的 Settings 沒有 `sourceSettings`,`useAuthForPlay` 落回 `kDefaultUseAuthForPlayBySource`(Bilibili、網易為 true,`settings.dart:76-79,685-693`),接著 `authForPlay` → `AccountServiceAuthLoader` → `getAuthHeaders()`(`lib/services/account/source_auth_context.dart:34-35,133-137`)。Bilibili 的 `_cachedCredentials` 在記憶體裡也沒被清,連 storage 都不用讀。未實測的只剩伺服器端是否接受。(核查更正:原寫「**推測:**」) + +### 3.2 其他非 Isar 的持久狀態 + +| 位置 | 內容 | 證據 | +|---|---|---| +| WebView cookie store(flutter_inappwebview 6.1.5;Windows 用 WebView2) | 登入頁的 cookie 和 localStorage。登入成功或頁面 dispose 時會刪 Bilibili 的 cookie、清快取、清 WebStorage(`bilibili_login_page.dart:105-124`);登出時刪各平台網域的 cookie(`bilibili_account_service.dart:303-316`、`netease_account_service.dart:276-284`、`youtube_account_service.dart:143-152`)。**WebView2 user data 目錄的實際位置:查不到設定,走套件預設** | 同左 | +| 歌詞快取的存取時間 | `_metadata.json` | `lib/services/lyrics/lyrics_cache_service.dart:276,327` | +| 開發者選項 | 開關、點擊次數、log 等級**只存在記憶體,不持久化** | `lib/providers/settings/developer_options_provider.dart:10-15` | +| Windows 開機自啟 | 由 `launch_at_startup` 套件寫系統設定。**寫入位置沒有追查(推測是登錄檔 Run 鍵)** | `lib/providers/settings/desktop_settings_provider.dart:128` 附近 | + +--- + +## 4. 各種快取 + +| 快取 | 位置 | 上限 | TTL | 清除方式 | 證據 | +|---|---|---|---|---|---| +| 網路圖片磁碟快取 | `getTemporaryDirectory()/fmp_network_image_cache`;metadata 用 `JsonCacheInfoRepository`(同名) | `Settings.maxCacheSizeMB`(桌面預設 32 MB,Android 新安裝 16 MB);物件數上限 = `maxCacheSizeMB*1024/100`,夾在 100–3000 之間;每載入 30 張檢查一次,超過 90% 就預防性清理 | `stalePeriod` 7 天 | 設定頁清除快取 → `clearCache()` 先 `emptyCache()` 再清檔案 | `lib/core/services/network_image_cache_service.dart:124-160,262-289,431-445`;上限同步在 `download_settings_provider.dart:70` | +| 記憶體內串流解析快取 | 行程記憶體 `_resolvedStreams`,鍵是 `uniqueKey|pageNum` | 32 筆(LRU) | 取決於 `AudioStreamResult.expiry` 和 `Track.audioUrlRefreshMargin` 5 分鐘(`track.dart:285-293`) | 開流失敗時丟掉該筆(`:330`);重啟後就沒了 | `lib/services/audio/stream_resolution_service.dart:102-112,340-341,370-385` | +| **持久化的串流 URL** | `Track.audioUrl`/`audioUrlExpiry` 寫進 Isar(含簽名的 CDN URL) | 每首一筆 | 各來源的 expiry:網易用 API 回的 `expi`,退路 16 分鐘(`netease_source.dart:40,164-169`);解析結果沒給 expiry 時預設 1 小時(`stream_resolution_service.dart:429`) | 下一次解析時覆寫 | `stream_resolution_service.dart:427-471`;`download_service.dart:1073-1075` | +| 歌詞內容快取 | `getApplicationCacheDirectory()/lyrics/*.json` | 檔案數 `Settings.maxLyricsCacheFiles`(預設 50),總量 5 MB;依存取時間淘汰 | 無 TTL | 設定頁「清除歌詞快取」(`settings_cache.dart:213-218`)→ `clear()` | `lyrics_cache_service.dart:18-19,51-74,141-157,203-244` | +| 歌詞匹配 | Isar `LyricsMatch`,只存 externalId,不存歌詞內容 | 無 | 無 | 使用者重新匹配時 | `lyrics_match.dart:5-8` | +| AI 標題解析快取 | Isar `LyricsTitleParseCache` | 無 | 每次啟動清空 | `database_migration.dart:66` | 同左 | +| 排行榜快取 | 只在記憶體(Riverpod state),不落盤 | 每個來源一份 | 每 `rankingRefreshIntervalMinutes` 分鐘(預設 60)刷新;失敗時退避重試 | 重啟就沒了 | `lib/services/cache/ranking_cache_service.dart:12-23,259-290` | +| 搜尋快取 | **查不到**。沒有搜尋結果快取;Isar `SearchHistory` 只存關鍵字 | — | — | — | `lib/services/search/`、`lib/providers/search/` grep 不到 cache | +| HTTP 快取 | **沒有**。Dio 都沒掛快取攔截器(整個 lib 沒有任何 `interceptors.add` 是快取類) | — | — | — | 見 accounts-network.md §2 | +| 音訊快取(Windows) | libmpv 的記憶體 demuxer cache:`cache=yes`、`cache-secs`/`demuxer-readahead-secs` = 桌面緩衝秒數、`demuxer-max-bytes`、`demuxer-max-back-bytes`;**不落盤** | 見左 | 無 | — | `lib/services/audio/media_kit_audio_service.dart:188-240` | +| 音訊快取(Android) | just_audio 直接用 `AudioSource.uri`,沒用 `LockCachingAudioSource`,**沒有磁碟快取** | — | — | — | `lib/services/audio/just_audio_service.dart:562-564,595,670` | +| 檔案存在快取 | 記憶體 `FileExistsCache`(Set\) | — | — | 依事件失效 | `lib/providers/download/file_exists_cache.dart:15` | +| 更新 APK | `getTemporaryDirectory()/`,重用前先做 SHA-256 與大小驗證 | 1 份 | — | 驗證失敗就刪 | `lib/services/update/update_service.dart:226-240` | +| Log 檔 | `getApplicationDocumentsDirectory()/FMP/logs/fmp.log`,輪替成 `fmp.1.log`… | 單檔 2 MB × 3 檔 | 無 | 輪替 | `lib/core/log_file_sink.dart:15-28,89-105` | + +--- + +## 5. 下載檔案結構 + +### 5.1 根目錄怎麼決定 + +優先序寫在 `DownloadPathUtils.getDefaultBaseDir`(`lib/services/download/download_path_utils.dart:187-216`): + +1. `Settings.customDownloadDir`(使用者選的目錄)。 +2. Android:`getExternalStorageDirectory()` 往上四層再接 `Music/FMP`,實際就是 `/storage/emulated/0/Music/FMP`;拿不到時退回 app documents 底下的 `FMP`。 +3. Windows:`getApplicationDocumentsDirectory()/FMP`,也就是「文件\FMP」,**和 DB、log 同一個資料夾**。 + +新下載一定要先選目錄。每個下載入口都會檢查 `hasConfiguredPath()`,沒選過就跳選擇對話框(`lib/services/download/download_path_manager.dart:20-29`;`download_path_utils.dart:184-186`)。2、3 只是為了讓舊檔案能被掃到。選目錄時 Android 要先要「所有檔案存取權」(`download_path_manager.dart:34-56`,ADR 0004),接著寫一個 `.fmp_test` 驗證能不能寫(`:59-68`)。 + +### 5.2 檔名與子目錄 + +``` +{baseDir}/ + {歌單名,沒有歌單時是 "未分类"}/ ← sanitizeFileName + {sourceId}_{parentTitle 或 title}/ ← sanitize,名稱上限 200 字 + audio.m4a (單 P) + P01.m4a / P02.m4a (多 P,依 pageNum 補零) + metadata.json (單 P)或 metadata_P{N}.json(多 P) + cover.jpg (downloadImageOption ≥ coverOnly) + avatar.jpg (coverAndAvatar) + *.downloading (暫存檔,續傳用) +``` + +- 路徑怎麼算:`computeDownloadPath`(`download_path_utils.dart:23-57`),有 `isPathInsideBase` 防止路徑跳出根目錄(`:49-55,117-122`)。 +- 非法字元改成全形;Windows 保留名稱(CON、NUL 等)前面加 `_`(`:81-156`)。 +- **副檔名一律是 `.m4a`,不管實際容器是什麼**(`:40-46`)。YouTube opus/webm、網易 flac/mp3 下載後也都叫 `.m4a`。**推測:** 播放器靠內容探測格式,所以播得動,但副檔名和內容可能對不上。HLS 串流直接拒絕下載(`download_service.dart:1060-1071`)。 +- 檔名常數:`lib/core/constants/download_filenames.dart:14-33`。 +- `DownloadPathUtils.getAvatarPath`/`ensureAvatarDirExists`(格式 `avatars/{platform}/{id}.jpg`,`:218-244`)**在 lib 裡沒有任何呼叫者**。實際的頭像存在影片資料夾裡的 `avatar.jpg`(`download_service.dart` `_saveMetadata` 內)。 + +### 5.3 metadata sidecar + +`_saveMetadata`(`lib/services/download/download_service.dart:1499-1590`)寫的 JSON 欄位有:sourceId、sourceType、title、artist、durationMs、cid、pageNum、pageCount、parentTitle、thumbnailUrl、downloadedAt。有 VideoDetail 時再加上 description、各種計數、publishDate、owner*、channelId,以及 hotComments(內容、留言者名稱、留言者頭像、讚數)。**不含 audioUrl,也不含任何憑證。** metadata 寫失敗只記 warning,下載照樣算完成(`:1560-1564`)。封面和頭像用 `_dio.download` 加 `imageHeaders`(`:1600-1620`)。 + +### 5.4 與 DB 的對應、重複檢測 + +- 下載完成後,路徑寫進 `Track.playlistInfo[].downloadPath`(embedded,按 playlistId 或 playlistName 對應,`track.dart:89-147`)。任務本身是 `DownloadTask`,`savePath` 有索引。 +- 去重有三層: + 1. 以歌單為單位:`isDownloadedForPlaylist` 先比名稱、再比 id(`track.dart:172-188`;`download_service.dart:507-517`)。 + 2. 以計畫路徑為單位:`getTasksBySavePaths` 查既有任務,同一批次內也會去重(`download_service.dart:541-569`)。 + 3. 目的地已經有檔案時:有配對 metadata 就算衝突;沒有 metadata 就當殘骸刪掉重下(`download_service.dart:1093-1101`)。 +- 啟動時會清掉已完成和失敗的任務、把 downloading 狀態改回 paused、刪掉孤兒 `.downloading` 檔(`download_service.dart:200-271`)。 +- 啟動時也會做一次「磁碟 → DB」同步:`startupDownloadSyncProvider` 呼叫 `syncLocalFiles()`,採 **REPLACE 模式**,把本地檔案當成權威來源,替換 DB 裡所有下載路徑;沒有有效 metadata 的檔案會跳過(核查更正:不會跳過。掃描器對沒有或讀不出 metadata 的 `.m4a` 會以資料夾前綴當 sourceId、`sourceType` 固定填 Bilibili 造出 DTO(`lib/providers/download/download_scanner.dart:385-391`),`sourceId` 幾乎不會是空字串,`download_path_sync_service.dart:286-290` 的跳過條件形同虛設,見 downloads.md §4.4);純本地檔案記成 `playlistId=0`(`lib/providers/download/startup_download_sync_provider.dart:1-40`;`lib/services/download/download_path_sync_service.dart:19-26`)。已下載頁也有手動同步按鈕(`lib/ui/pages/library/downloaded_page.dart:38,88`)。 +- 歌單改名時會連資料夾一起改(`lib/services/library/playlist_service.dart:170-174`,細節未展開)(核查更正:不改資料夾。`updatePlaylist` 只清掉該歌單所有曲目的下載路徑、回傳新舊資料夾路徑,由對話框提示使用者自己搬(`playlist_service.dart:166-189`;`lib/ui/pages/library/widgets/create_playlist_dialog.dart:480-485`);`lib/` 內沒有任何對下載資料夾的 `rename`,`playlistInfo[].playlistName` 也不跟著改,見 downloads.md §3.2、§4.4)。 + +--- + +## 6. 備份格式 + +- 格式:單一 JSON 檔 `fmp_backup_.json`,沒有壓縮、**沒有加密**。存到哪裡由使用者決定:Android 選目錄,其他平台用 saveFile 對話框(`lib/services/backup/backup_service.dart:51-89`)。 +- 版本:`kBackupVersion = 5`(`backup_service.dart:23-35`,v3/v4/v5 的變更記錄在同一段註釋)。匯入時只擋比目前版本**新**的備份(`:314-321`);缺少的鍵一律用預設值;v3 以前的六個每源鍵由 `_readSourceSettings` 折疊(`backup_data.dart:565-590`)。 +- 頂層鍵:`version`、`exportedAt`、`appVersion`、`playlists`、`tracks`、`playHistory`、`searchHistory`、`radioStations`、`settings`、`lyricsMatches`(`lib/services/backup/backup_data.dart:106-120`)。 + +| 內容 | 包含? | 備註/證據 | +|---|---|---| +| Playlist | 是(歌曲以 `uniqueKey` 字串引用) | `backup_service.dart:112-140`(`PlaylistBackup(` 在 :119) | +| Track | 是,但**不含** `audioUrl`/`audioUrlExpiry`/`playlistInfo`(下載路徑) | `backup_data.dart:345-372`(toJson) | +| PlayHistory、SearchHistory、RadioStation、LyricsMatch | 是 | `backup_data.dart:106-120` | +| Settings | 大部分欄位(清單見 `backup_data.dart:592-642`),**包含 `lyricsAiEndpoint`、`lyricsAiModel`** | 匯入時 `customDownloadDir`、`preferredAudioDevice*` 保留目前值(`backup_service.dart:751-755`);`hotkeyConfig` 只在 Windows 匯入(`:707-709`) | +| Account(Isar 列) | **否** | `_collectBackupData` 沒讀 Account(`backup_service.dart:91-310`) | +| secure storage 憑證、AI API key | **否** | 同上;API key 只存在 secure storage | +| DownloadTask、PlayQueue、LyricsTitleParseCache | 否 | 同上 | +| 下載的音檔 | 否 | — | + +匯入流程:先把所有資料解析成待寫物件,資料庫完全不動;最後由 `BackupRepository.writeImport` 用**單一** `writeTxn` 一次寫入(`backup_service.dart:371-400`;`lib/data/repositories/backup_repository.dart:110-111`)。歌曲依 `uniqueKey` 略過重複,歌單依 name 略過同名。使用者可以勾選要匯入哪幾類(`importData` 的參數,`:371-379`)。錯誤訊息是寫死的簡體中文字串,拼上 `$e`(例如 `:454`)。 + +--- + +## 7. 全部設定項總表 + +除特別註明外,存放位置都是 Isar `Settings`(id=0)。預設值寫的是 Dart 欄位初值;舊列缺欄位時讀到的是 Isar 型別預設(int → `minLong`、double → NaN),由 §2 的 repair 修正。「UI 入口」寫的是觸發 setter 的 widget 位置。 + +| 名稱 | 存放 | 型別 | 預設 | UI 入口 | 影響 | 證據(欄位/寫入) | +|---|---|---|---|---|---|---| +| schemaVersion | Settings | int | 0(新安裝時直接寫成 4) | 無 | 遷移版本 | `settings.dart:221`;`database_migration.dart:45` | +| themeModeIndex | Settings | int 0/1/2 | 0(跟隨系統) | 外觀 `settings_appearance.dart:45` | 主題;啟動前預讀 | `settings.dart:224`;`theme_provider.dart:73` | +| primaryColor | Settings | int? ARGB | null | 外觀 `settings_appearance.dart:170,225` | 主色 | `settings.dart:227`;`theme_provider.dart:82` | +| fontFamily | Settings | String? | null | 外觀 `settings_appearance.dart:331` | 字型 | `settings.dart:301`;`theme_provider.dart:94` | +| locale | Settings | String? | null(跟隨系統) | 外觀 `settings_appearance.dart:425` | 語言 | `settings.dart:304`;`locale_provider.dart:35` | +| railExpanded | Settings | bool | false | 桌面版面,側欄按鈕 `responsive_scaffold.dart:391` | 側欄展開 | `settings.dart:231`;`layout_settings_provider.dart:62` | +| detailPanelExpanded | Settings | bool | false | `responsive_scaffold.dart:486` | 詳情面板 | `settings.dart:240`;`layout_settings_provider.dart:67` | +| detailPanelWidth | Settings | double | `AppLayout.detailPanelDefault` | 拖拉面板(`responsive_scaffold.dart`) | 面板寬度,repair 會夾取範圍 | `settings.dart:244`;`layout_settings_provider.dart:77`;`database_migration.dart:359-372` | +| maxCacheSizeMB | Settings | int | 32(Android 新安裝 16) | 快取 `settings_cache.dart:81` | 圖片磁碟快取上限 | `settings.dart:247`;`download_settings_provider.dart:104` | +| customDownloadDir | Settings | String? | null | 下載路徑對話框 `change_download_path_dialog.dart:194`、`download_path_setup_dialog.dart:63` | 下載根目錄 | `settings.dart:250`;`download_path_manager.dart:73,93` | +| hotkeyConfig | Settings | String?(JSON) | null → `HotkeyConfig.defaults()` | 桌面 `settings_desktop.dart:191,284,365`(Windows) | 全域快捷鍵綁定 | `settings.dart:253`;`hotkey_config_provider.dart:68` | +| autoScrollToCurrentTrack | Settings | bool | false | 播放 `settings_playback.dart:17` | 切歌時捲到佇列裡的目前歌曲 | `settings.dart:256`;`playback_settings_provider.dart:74` | +| rememberPlaybackPosition | Settings | bool | true | `settings_playback.dart:55,69` | 重啟後恢復位置 | `settings.dart:259`;`playback_settings_provider.dart:83` | +| restartRewindSeconds | Settings | int | 0 | `settings_playback.dart:237` | 重啟恢復時倒退秒數 | `settings.dart:262`;`playback_settings_provider.dart:92` | +| tempPlayRewindSeconds | Settings | int | 10 | `settings_playback.dart:247` | 臨時播放恢復時倒退秒數 | `settings.dart:265`;`playback_settings_provider.dart:101` | +| playHistoryLimit | Settings | int | 10000 | `settings_playback.dart:122` | 播放歷史保留筆數,由 `PlayHistoryRecorder` 裁切 | `settings.dart:276`;`playback_settings_provider.dart:114` | +| maxConcurrentDownloads | Settings | int 1–5 | 3 | 儲存 `settings_storage.dart:176` | 同時下載數 | `settings.dart:281`;`download_settings_provider.dart:85` | +| downloadImageOptionIndex | Settings | int 0/1/2 | 1(coverOnly) | `settings_storage.dart:239` | 下載時附帶封面/頭像 | `settings.dart:284`;`download_settings_provider.dart:94` | +| minimizeToTrayOnClose | Settings | bool | false | 桌面 `settings_desktop.dart:119` | 關閉視窗時縮到系統匣 | `settings.dart:289`;`desktop_settings_provider.dart:37` | +| enableGlobalHotkeys | Settings | bool | false | `settings_desktop.dart:145` | 全域快捷鍵 | `settings.dart:292`;`desktop_settings_provider.dart:68` | +| launchAtStartup | Settings(另寫系統自啟設定) | bool | false | `settings_desktop.dart:64,70` | 開機自啟 | `settings.dart:295`;`desktop_settings_provider.dart:128` | +| launchMinimized | Settings | bool | false | `settings_desktop.dart:84` | 自啟時最小化;`main.dart` 啟動視窗時讀取 | `settings.dart:298`;`desktop_settings_provider.dart:134` | +| audioQualityLevelIndex | Settings | int 0/1/2 | 0(high) | 音訊 `audio_settings_page.dart:38` | 串流音質 | `settings.dart:309`;`audio_settings_provider.dart:179` | +| audioFormatPriority | Settings | String | `opus,aac` | `audio_settings_page.dart:46` | 格式偏好 | `settings.dart:313`;`audio_settings_provider.dart:193` | +| sourceSettings[].streamPriority | Settings(embedded) | String | B `audioOnly,muxed`/Y `audioOnly,muxed,hls`/N `audioOnly` | `audio_settings_page.dart:63` | 各音源的串流類型順序 | `settings.dart:59-63,318,716-721`;`audio_settings_provider.dart:213` | +| sourceSettings[].useAuthForPlay(**Auth For Play**) | Settings(embedded) | bool | B true、N true、Y false | `audio_settings_page.dart:74` | 播放解析、下載、詳情、排行榜是否帶登入 | `settings.dart:76-79,724-729`;`audio_settings_provider.dart:314` | +| preferredAudioDeviceId/Name | Settings | String? | null | 播放器輸出裝置選單 `fmp_audio_device_selector.dart:62,78` | 輸出裝置(media_kit) | `settings.dart:339-342`;`audio_provider.dart:1252-1268` | +| autoMatchLyrics | Settings | bool | false | `settings_playback.dart:183,194` | 播放時自動匹配歌詞 | `settings.dart:347`;`audio_settings_provider.dart:225` | +| maxLyricsCacheFiles | Settings | int | 50 | `settings_cache.dart:191` | 歌詞快取檔數 | `settings.dart:350`;`download_settings_provider.dart:120` | +| lyricsDisplayModeIndex | Settings | int 0/1/2 | 0 | 詳情面板 `track_detail_panel.dart:240`、`track_action_handler.dart:351` | 原文/翻譯/羅馬音 | `settings.dart:353`;`lyrics_provider.dart:214` | +| lyricsSourcePriority | Settings | String | `netease,qqmusic,lrclib` | 歌詞來源頁 `lyrics_source_settings_page.dart:90` | 匹配順序 | `settings.dart:357`;`audio_settings_provider.dart:234` | +| disabledLyricsSources | Settings | String | `lrclib` | `lyrics_source_settings_page.dart:101` | 停用的歌詞源 | `settings.dart:361`;`audio_settings_provider.dart:334` | +| lyricsAiTitleParsingModeIndex | Settings | int 0/2/3 | 0(off) | `lyrics_source_settings_page.dart:238` | AI 標題解析模式(1 是非法值) | `settings.dart:364`;`audio_settings_provider.dart:245` | +| allowPlainLyricsAutoMatch | Settings | bool | false | `lyrics_source_settings_page.dart:284` | 允許自動匹配沒有時間軸的歌詞 | `settings.dart:367`;`audio_settings_provider.dart:255` | +| lyricsAiEndpoint | Settings | String | '' | `lyrics_source_settings_page.dart:135` | OpenAI 相容端點(**歌曲標題會送到這裡**) | `settings.dart:370`;`audio_settings_provider.dart:266` | +| lyricsAiModel | Settings | String | '' | `lyrics_source_settings_page.dart:143` | 模型名 | `settings.dart:373`;`audio_settings_provider.dart:276` | +| lyricsAiTimeoutSeconds | Settings | int | 20 | `lyrics_source_settings_page.dart:151` | AI 請求逾時 | `settings.dart:376`;`audio_settings_provider.dart:289` | +| lyrics AI API key | **secure storage** `lyrics_ai_api_key` | String | 無 | `lyrics_source_settings_page.dart:159,164` | Bearer token | `lyrics_ai_config_service.dart:32,74-82` | +| lyricsWindow*(共 11 欄:TextColor、SecondaryTextColor、InactiveTextOpacity、OutlineEnabled/Color/Width、ShadowEnabled/Color/BlurRadius/OffsetX/OffsetY) | Settings | int?/double?/bool? | 全部 null = 預設樣式 | 詳情面板 `track_detail_panel.dart:243,246` | 桌面歌詞視窗樣式 | `settings.dart:379-409`;`lyrics_window_style.dart:279-307` | +| rankingRefreshIntervalMinutes | Settings | int | 60 | `settings_cache.dart:281` | 排行榜刷新間隔 | `settings.dart:434`;`refresh_settings_provider.dart:72` | +| homeRankingSourcePriority | Settings | String | `bilibili,youtube,netease` | 首頁排行設定 `home_ranking_settings_page.dart:23` | 首頁排行順序 | `settings.dart:437`;`home_ranking_settings_provider.dart:94` | +| disabledHomeRankingSources | Settings | String | '' | `home_ranking_settings_page.dart:81` | 停用的首頁排行(不能全部停用) | `settings.dart:440`;`home_ranking_settings_provider.dart:158` | +| radioRefreshIntervalMinutes | Settings | int | 5(0 = 關閉) | `settings_cache.dart:345` | 電台直播狀態輪詢 | `settings.dart:443`;`refresh_settings_provider.dart:88` | +| youtube/bilibili/neteaseStreamPriority、useBilibili/Youtube/NeteaseAuthForPlay(6 欄,`@Deprecated`) | Settings | String/bool | 見欄位 | **無 UI** | 給 v1→v2 遷移讀;v0→v1 也會讀、並寫入網易那兩欄(`database_migration.dart:181-183,241-242`);v2 之後不再有人寫(核查更正:原寫「只給 v1→v2 遷移讀」) | `settings.dart:321-336,414-429`;`database_migration.dart:1-4` | +| Playlist.refreshIntervalHours/notifyOnUpdate/useAuthForRefresh | 每張歌單(Isar Playlist) | int?/bool/bool | null/true/false | 匯入、歌單設定(未逐一定位) | 自動刷新、通知、刷新時是否帶登入 | `playlist.dart:30,36,45` | +| Track 旁的 LyricsMatch.offsetMs | Isar LyricsMatch | int | 0 | 詳情面板 `track_detail_panel.dart:223` | 歌詞偏移 | `lyrics_match.dart:24` | +| 開發者選項開關、log 等級 | **只在記憶體** | bool/LogLevel | 關閉/debug(debug 版) info(release 版) | 點版本號 7 次;`developer_options_page.dart:615` | log 過濾 | `developer_options_provider.dart:10-15,43-46`;`lib/core/logger.dart:68` | + +沒有 UI 入口的持久化設定:`schemaVersion` 和六個 `@Deprecated` 欄位。其餘 Settings 欄位都找得到寫入它的 UI(`preferredAudioDevice*` 的 UI 在播放器元件,`lyricsWindow*` 在詳情面板,不在設定頁)。 diff --git a/docs/audit/devtools.md b/docs/audit/devtools.md new file mode 100644 index 000000000..706ee67cf --- /dev/null +++ b/docs/audit/devtools.md @@ -0,0 +1,219 @@ +# 開發者模式、提示與日誌現況 + +> 現況描述,未經確認,不代表目標。 + +審計日期:2026-09-26,分支 `docs/audit`。全部結論以原始碼為準;文件/註釋的說法只當「主張」,與程式碼不符處標 **不一致**,沒有實際執行驗證的推論標 **推測**。本檔沒有跑 app,也沒有跑測試。 + +--- + +## 1. 開發者模式 + +### 1.1 如何開啟 + +| 項目 | 現況 | 證據 | +|---|---|---| +| 入口 | 設定頁「版本」列(`_VersionListTile`)連點 7 次 | `lib/ui/pages/settings/widgets/settings_about.dart:4-39`;次數常數 `requiredTaps = 7`:`lib/providers/settings/developer_options_provider.dart:49` | +| 提示 | 剩 4~1 次時 toast「再點 n 次」,達成時 success toast | `settings_about.dart:23-32` | +| 解鎖後 | 設定頁出現「開發者選項」區塊,點進 `/settings/developer` | `settings_about.dart:91-117`,掛在設定頁 `lib/ui/pages/settings/settings_page.dart:194` | +| 持久化 | **不持久化**。`isEnabled` / `tapCount` / `logLevel` 都是 `Notifier` 的記憶體狀態,重啟 app 即恢復關閉 | `developer_options_provider.dart:6-34`、`:10-15`(註釋明說「不落 `Settings`」) | +| 關閉方式 | 沒有 UI。`DeveloperOptionsNotifier.reset()` 在 `lib/` 與 `test/` 都查不到呼叫點(grep `developerOptionsProvider.notifier).reset`、`\.reset()`) | `developer_options_provider.dart:70` | +| build 條件 | 與 `kDebugMode` / `kReleaseMode` 無關,release 版也能解鎖 | grep `kDebugMode\|kReleaseMode\|kProfileMode` 只命中 `lib/core/logger.dart:68,273` 與 `lib/main.dart:110` | +| 路由保護 | 路由 `/settings/developer`、`/settings/developer/database`、`/settings/developer/logs` **無條件註冊**,只是 UI 上沒有別的入口 | `lib/ui/router.dart:246-263` | + +### 1.2 開發者選項頁(`lib/ui/pages/settings/developer_options_page.dart`)逐區塊 + +| 區塊 / 項目 | 做什麼 | 完整度 | 證據 | +|---|---|---|---| +| **除錯工具**:記憶體使用(`_MemoryInfoTile`) | 顯示進程 RSS(Android/Windows/Linux)、Flutter 圖片記憶體快取數量/大小、RSS 減圖片快取的「Native 估算」、磁碟圖片快取 MB、佇列曲數、首頁排行快取筆數(B 站/YouTube/網易雲)、歌詞快取檔數;有「清除圖片記憶體快取」按鈕 | 可用。摘要行有寫死的簡中字串 `'Flutter 图片: '` 沒走 i18n;「Native 記憶體」只是 `RSS − 圖片快取` 的粗估;歌詞快取讀取失敗被 `catch (_) {}` 吞掉 | `:167-474`,寫死字串 `:307`,粗估 `:353-367`,吞例外 `:223-227` | +| **除錯工具**:即時日誌 | 進入 `LogViewerPage`(見 §3.4) | 可用 | `:41-47` | +| **除錯工具**:日誌級別(`_LogLevelTile`) | 下拉選 DEBUG/INFO/WARNING/ERROR,呼叫 `AppLogger.setMinLevel`;**只影響之後的記錄**(含落盤),重啟即回預設 | 可用,不持久化 | `:596-627`;`developer_options_provider.dart:43-46` | +| **除錯工具**:資料庫檢視器 | 進入 `DatabaseViewerPage`:頂部 chip 選 collection(Track、Playlist、PlayQueue、PlayHistory、Settings、SearchHistory、DownloadTask、RadioStation、LyricsMatch、LyricsTitleParseCache、Account),每個 collection **一次 `findAll()` 全讀**,以卡片列出欄位;唯讀,無搜尋、無分頁、無編輯 | 可用;大資料量時一次全載入(**推測**會卡頓,未實測) | 頁面 `lib/ui/pages/settings/database_viewer_page.dart:115-157`;清單 `lib/data/database/database_catalog.dart:49` 起,各 `findAll()` 如 `:53`(`isar.tracks.where().findAll()`) | +| **資料管理**:資料庫資訊 | 顯示 DB 目錄、檔案大小、Track 數、Playlist 數 | 可用 | `:86-151` | +| **資料管理**:重設所有資料 | 確認對話框後 `DataIntegrityRepository(isar).clearEverything()`(= `isar.clear()` 清空**所有** collection),再跑 `runDatabaseMigration` 重建預設資料 | 可用,但範圍有限:只清 Isar;**不清** `flutter_secure_storage` 裡的帳號憑證與 AI API key、不清下載檔案、不清歌詞/圖片磁碟快取、不重建記憶體中的 provider 狀態(佇列、播放器)。**推測**:重設後畫面仍顯示舊的記憶體狀態,直到重啟 | `:510-567`;`lib/data/repositories/data_integrity_repository.dart:55-57` | +| **資訊**:除錯模式 | 永遠顯示「已啟用」+ 勾勾圖示,沒有任何開關或條件判斷 | 純裝飾,內容恆真 | `:66-79` | + +**相關但沒有 UI 入口的開發者向程式碼**:`DataIntegrityRepository.scan()` / `repair()`(重複 Track key、重複下載路徑、重複帳號平台、多筆 PlayQueue 的掃描與修復)在 `lib/` 查不到任何呼叫點,只有 `test/data/repositories/data_integrity_repository_test.dart` 使用。grep:`DataIntegrityRepository\|\.scan()\|\.repair()`。證據 `lib/data/repositories/data_integrity_repository.dart:59-85`。 + +--- + +## 2. Toast / SnackBar / 對話框 + +### 2.1 呈現入口一覽 + +全 app 只有一個自製的 `ToastService`(`lib/core/services/toast_service.dart`),**沒有**第三方 toast 套件(pubspec 與 `lib/` grep `fluttertoast|bot_toast|oktoast|overlay_support` 無結果)。底層一律是 `ScaffoldMessenger.of(context).showSnackBar`(`toast_service.dart:238-243`),不是 overlay。它有兩套入口: + +| 入口 | API | 呼叫次數(grep,不含定義檔) | 怎麼到畫面 | +|---|---|---|---| +| 靜態(需 `BuildContext`) | `ToastService.show` | 25 | 直接 `showSnackBarNow` | +| | `ToastService.success` | 59 | 同上 | +| | `ToastService.error` | 40 | 同上(傳入已組好的字串) | +| | `ToastService.warning` | 14 | 同上 | +| | `ToastService.failure(context, e, …)` | 13 | 先 `AppLogger.error` 記原文,畫面顯示 `userMessageFor(e)`(`:188-198`) | +| | `ToastService.showWithAction` | 6 | 帶 `SnackBarAction` | +| 實例(Stream,給背景服務) | `showInfo` / `showSuccess` / `showWarning` / `showError` | 6 / 2 / 5 / 12 | 推進 broadcast stream(`:55-80`)→ `toastStreamProvider`(`:269`)→ **只有** `AppShell` 在 `ref.listen`(`lib/ui/app_shell.dart:44-49`)→ `_showSnackBar`(`:20-29`) | + +- 使用 `ToastService` 的檔案共 45 個。 +- 實例入口的使用者:`AudioController`(`lib/services/audio/audio_provider.dart:185` 取得,`:639-651,761,1604,1911,1957,1982,1988,1993,2100,2685` 發送)、帳號狀態檢查(`lib/providers/account/account_provider.dart:162,239`)、下載、歌單刷新(`lib/providers/library/refresh_provider.dart`)、帳號管理頁。 +- 繞過 `ToastService` 自己 `showSnackBar` 的地方:0 處。`lib/ui/widgets/dialogs/change_download_path_dialog.dart:220` 只是先抓 `ScaffoldMessenger` 再交給 `ToastService.showSnackBarWithMessenger`。 +- 外觀統一由 `ToastService.buildSnackBar`(`:93`)決定:floating、依類型著色;時長 error/warning/帶 action 用 3000ms,其餘 1500ms(`lib/core/constants/ui_constants.dart:166,169`)。 +- 每次顯示都會 `clearSnackBars()` + `removeCurrentSnackBar()`(`toast_service.dart:240-242`),也就是**新 toast 直接蓋掉舊的、不排隊**。 + +### 2.2 對話框 + +- `showDialog` 44 處/27 檔(含 `showDialog(` 泛型寫法 17 處);`showModalBottomSheet` 15 處/13 檔(含泛型);`AlertDialog(` 38 處/23 檔。(核查更正:原寫「`showDialog(` 31 處/14 檔;`showModalBottomSheet(` 9 處/7 檔」,只數到不帶型別參數的寫法) +- 共用 helper:`showConfirmDestructiveDialog`(`lib/ui/widgets/dialogs/confirm_destructive_dialog.dart:7-37`)17 個呼叫點;另有 5 個「加入(遠端)歌單」helper。其餘約 35 處 `AlertDialog` 是各頁面手刻。 +- `.trellis/spec/ui/widgets.md:40-42` 明說兩種 dialog 入口風格(頂層 `showXxxDialog` 與 class 上的 `static show`)「都接受」。 + +### 2.3 不一致與重複(呈現面) + +1. **例外轉 toast 有三種寫法並存**: + - `ToastService.failure(context, e)` — 記 log + 翻譯(13 處)。 + - `ToastService.error(context, t.xxx(error: userMessageFor(e)))`,log 由呼叫端自己另記,例如 `lib/ui/pages/settings/log_viewer_page.dart:140-146`、`lib/ui/pages/settings/developer_options_page.dart:559-564`、`lib/ui/pages/settings/widgets/settings_backup.dart:34,90,351`。 + - 背景服務:`_toastService.showError(_errorPresenter.playbackFailed(e))`(`audio_provider.dart:1990-1993`)。 + `.trellis/spec/ui/widgets.md:25` 承認前兩種都可以。 +2. **原文外洩到 toast(與規則不一致)**:`lib/core/errors/user_message.dart:62-71` 說回傳值裡不會有例外原文,但 `AudioController` 在限流分支直接 `showWarning(e.message)`,並把 `e.message` 寫進 `state.error`(`audio_provider.dart:1984-1988`)。`SourceApiException.message` 是 adapter 組出的診斷字串,不一定翻譯過。守門的 `test/ui/static_rules/error_presentation_static_rule_test.dart:176` 只掃 `lib/ui`,掃不到 `lib/services`。**不一致**。 +3. **DB 初始化失敗畫面直接顯示 `error.toString()`**:`lib/app.dart:87`。`StartupFailureApp` 同樣顯示原文(`lib/ui/startup_failure_app.dart:74`),但那是它的註釋明說的例外;`app.dart` 這一處沒有說明。 +4. **背景錯誤有兩種送達機制**:音樂播放錯誤走 Stream(任何頁面都會顯示,前提見第 5 點);電台錯誤走「頁面級 `ref.listen`」,而且在 `HomePage`(`lib/ui/pages/home/home_page.dart:125-130`)與 `RadioPage`(`lib/ui/pages/radio/radio_page.dart:32`)各寫一份。使用者停在音樂庫、搜尋、設定等頁時,電台錯誤不會出現 toast。程式碼佐證(核查補證):導覽列以 `context.go` 切頁(`lib/ui/app_shell.dart:34-38`),而 shell 是普通 `ShellRoute`,非活動頁會被銷毀(`lib/ui/router.dart:123-129`),所以兩個 `ref.listen` 只在 HomePage/RadioPage 仍掛載時存在;除這兩處外 `lib/` 沒有其他監聽 `radioControllerProvider` 錯誤的地方。仍屬**推測**的是執行期表現(例如從首頁 push 子頁時 HomePage 仍在堆疊下方,其 listen 是否被 Riverpod 3 暫停),未實測。 +5. **全螢幕播放頁上可能看不到背景 toast(推測)**:Stream toast 只在 `AppShell` 監聽,`AppShell` 位於 `ShellRoute` 內;全螢幕播放頁 `/player`、`/radio-player` 掛在 root navigator、蓋在 shell 之上(`lib/ui/router.dart:293-307`)。repo 自己的規則說「Riverpod 3 會暫停被不透明路由蓋住的 consumer 的訂閱」(`test/providers/static_rules/riverpod3_static_rule_test.dart:31-35`)。若此說法成立,使用者在播放頁時發生的播放錯誤 toast 會被暫停或畫在被蓋住的 shell Scaffold 上。需要實機驗證。 +6. **toast 互相覆蓋**:`showSnackBarNow` 每次先清空佇列(`toast_service.dart:240-242`),連續錯誤只會看到最後一則。 +7. **文件範例與 API 不符**:`toast_service.dart:36-39` 的註解範例寫 `toastService.showMessage('消息内容')`,類別裡沒有 `showMessage`(實際是 `showInfo` 等,`:55-80`)。**不一致**。 + +### 2.4 錯誤呈現的其他 UI 元件 + +| 元件 | 用途 | 證據 | +|---|---|---| +| `ErrorDisplay`(含 `.network/.server/.notFound/.permission/.empty`、`compact`) | 頁面或區塊的錯誤/空狀態,附重試 | `lib/ui/widgets/feedback/error_display.dart:29` 起;33 處使用,例:`lib/ui/pages/search/search_page.dart:425,615` | +| `NetworkStatusBanner` | 全域橫幅:無網路,或播放網路錯誤(附「重試」呼叫 `retryManually()`) | `lib/ui/widgets/feedback/network_status_banner.dart:11-20,145-156`;掛在 `lib/app.dart:186,206` | +| `userMessageFor` / `failureMessage` | 例外 → 一句翻譯文字;`failureMessage` 順便 `AppLogger.error` | `lib/core/errors/user_message.dart:72-87,97-105` | +| `PlaybackErrorPresenter` | 決定播放失敗要跳過、重試或提示,措辭交回 `user_message.dart` | `lib/services/audio/playback_error_presenter.dart:28-80` | +| `StartupFailureApp` | `runApp()` 前失敗時的頂替畫面:中英文寫死、顯示原文、log 檔路徑、issue 網址 | `lib/ui/startup_failure_app.dart:22,57-82`;觸發 `lib/main.dart:68-92` | +| `app.dart` DB 載入失敗分支 | 紅色圖示 + `initFailed` + 原文 | `lib/app.dart:64-92` | + +代表性路徑: + +- **搜尋失敗**:`search_provider` catch → `failureMessage(e, stack, 'search failed', tag: 'Search')` 寫 log 並回傳翻譯句(`lib/providers/search/search_provider.dart:304`)→ 存進 state → `SearchPage` 以 `ErrorDisplay` 顯示(`search_page.dart:425`)。 +- **播放失敗**:`AudioController._handleSourceError`(`audio_provider.dart:1945-1995`)→ `PlaybackErrorPresenter` 決定跳過或提示 → `_toastService.showWarning/showError` → Stream → `AppShell` → SnackBar;網路類錯誤另外點亮 `NetworkStatusBanner`。 +- **匯出日誌失敗**:`log_viewer_page.dart:140-146` 自己 `AppLogger.error`,再 `ToastService.error(t.logViewer.exportFailed(error: userMessageFor(e)))`。 + +--- + +## 3. 日誌系統 + +### 3.1 實作 + +- 自製靜態類別 `AppLogger`(`lib/core/logger.dart:66` 起),不是第三方 logger 套件。 +- 層級 `LogLevel { debug, info, warning, error }`(`:9`)。預設最低級別:debug build 為 `debug`,release/profile 為 `info`(`:68`)。執行期可由開發者選項調整(§1.2),不持久化。 +- `Logging` mixin(`:295-303`)以 `runtimeType` 作 tag,提供 `logDebug/logInfo/logWarning/logError`。59 個類別使用;`log*` 呼叫約 792 處。直接呼叫 `AppLogger.info/warning/error` 的約 22/10/37 處(`AppLogger.debug` 除 mixin 轉發外無直接呼叫)。 +- `lib/` 內沒有散落的 `print(` / `debugPrint(` / `developer.log(`,全部收在 `AppLogger._log` 裡(`:273-289`)。 + +### 3.2 輸出去向 + +每一筆(通過級別門檻後,先 `redactSensitive`,`:234-238`)同時送往: + +1. 記憶體環形緩衝,最多 500 筆(`:70-72`,超過 `removeFirst`,`:261-264`)。 +2. broadcast stream,給即時日誌頁(`:75`、`:267`)。 +3. 落盤 `LogFileSink`(`:270`)。 +4. debug build 另外 `developer.log`(`:273-281`)。 +5. **不分 build 一律** `debugPrint`(`:283-290`)。註解 `:272` 寫「release 模式下使用 debugPrint」,實際是兩種模式都印。**不一致**(輕微)。 + +### 3.3 寫檔、位置、輪替 + +| 項目 | 現況 | 證據 | +|---|---|---| +| 啟用時機 | `main()` 在 `WidgetsFlutterBinding.ensureInitialized()` 之後 `attachFileSink`;binding 之前的 log 先進記憶體,掛上時整批倒進檔案 | `lib/main.dart:131-138`;`lib/core/logger.dart:163-170` | +| 位置 | `getApplicationDocumentsDirectory()/FMP/logs/fmp.log`。Windows 上是使用者的「文件」資料夾;DB 也在 `Documents/FMP/` 下 | `lib/core/log_file_sink.dart:24-28`;DB:`lib/data/database/database_provider.dart:50-53` | +| 輪替 | 單檔上限 2 MB、保留 3 個檔(`fmp.log`、`fmp.1.log`、`fmp.2.log`),超過刪最舊 | `log_file_sink.dart:17-19`、`:82-105` | +| 失敗處理 | 寫入非同步排隊,I/O 失敗全部吞掉;掛載失敗只記一筆 warning | `log_file_sink.dart:6-13`;`main.dart:136-138` | +| 遮蔽 | 訊息與 error 字串遮蔽 `Authorization`、`Bearer`、`SAPISIDHASH`、`Cookie` header,以及 `SESSDATA`、`bili_jct`、`MUSIC_U`、`refresh_token`、`apiKey`、`password`、`token` 等 key | `logger.dart:81-134`、`:177-200` | +| 遮蔽不涵蓋 | `stackTrace` 不遮蔽(`:256`、`:285-289`)。歌曲標題、上傳者、影片描述不算敏感:AI 歌詞比對在 debug 級別會把整個請求 payload(含影片描述與歌詞預覽)寫進 log(`lib/services/lyrics/ai_title_parser.dart:57`、`lib/services/lyrics/ai_lyrics_selector.dart:116`) | 同左 | + +### 3.4 即時日誌頁(`lib/ui/pages/settings/log_viewer_page.dart`) + +- 資料來源:開頁時複製 `AppLogger.logs`(最多 500 筆),再訂閱 stream 追加,畫面上限 1000 筆(`:32-46`)。 +- 篩選:級別(Debug+/Info+/Warning+/只看 Error,`:199-219`)+ 文字搜尋 message/tag(`:68-80`)。這個「顯示篩選」與開發者選項的「記錄門檻」是兩個不同的級別設定,後者調高後前者選 Debug 也看不到 debug。 +- 輸出:複製全部(`:91-95`)、長按單筆複製、詳情對話框(error + stack,`:345-415`)、匯出落盤檔(讀全部輪替檔、Android 選目錄/桌面另存新檔,`:102-148`)。沒有系統分享。 +- 清空:清畫面與記憶體緩衝,不動落盤檔(`:150-155`)。 +- 注意:「Info+」「Warning+」兩個選項是寫死英文(`:208-212`),另兩個走 i18n。 + +--- + +## 4. Log/錯誤從產生到呈現的流向 + +```mermaid +flowchart TD + subgraph Sources[錯誤與事件來源] + A1[services / providers
Logging mixin: logDebug..logError] + A2[UI catch 區塊] + A3[FlutterError.onError
PlatformDispatcher.onError
runZonedGuarded] + A4[AudioController
帳號檢查 / 下載 / 歌單刷新] + A5[RadioController.state.error] + end + + subgraph Mapping[翻譯層] + M1[userMessageFor e] + M2[failureMessage e] + M3[PlaybackErrorPresenter] + end + + subgraph Logger[AppLogger._log] + L0{level >= minLevel?
release 預設 info} + L1[redactSensitive] + L2[(記憶體緩衝 500 筆)] + L3[logStream] + L4[(Documents/FMP/logs/fmp.log
2MB x 3 輪替)] + L5[debugPrint / developer.log] + end + + subgraph UI[呈現] + U1[ToastService 靜態方法
show/success/error/warning/failure] + U2[ToastService 實例 Stream
showInfo/showError...] + U3[AppShell ref.listen
toastStreamProvider] + U4[SnackBar
新的蓋掉舊的] + U5[ErrorDisplay] + U6[NetworkStatusBanner] + U7[StartupFailureApp
顯示原文與 log 路徑] + U8[LogViewerPage
開發者選項內] + U9[HomePage / RadioPage
頁面級 ref.listen] + end + + A1 --> L0 + A2 --> M2 + A2 --> U1 + M2 --> L0 + M2 --> U5 + A3 --> L0 + A3 -- runApp 之前 --> U7 + A4 --> M3 --> M1 + M1 --> U2 + A4 -. "限流分支直接 e.message" .-> U2 + U1 -- failure 會記 log --> L0 + U2 --> U3 --> U4 + U1 --> U4 + A5 --> U9 --> U1 + A4 -- 網路錯誤 --> U6 + L0 -- 是 --> L1 --> L2 & L3 & L4 & L5 + L2 --> U8 + L3 --> U8 + L4 -- 匯出 --> U8 +``` + +--- + +## 5. 小結:不一致或重複清單 + +| # | 項目 | 證據 | +|---|---|---| +| 1 | 開發者模式不持久化、沒有關閉入口;`reset()` 無呼叫者 | `developer_options_provider.dart:6-34,70` | +| 2 | 「除錯模式:已啟用」是恆真的裝飾列 | `developer_options_page.dart:69-77` | +| 3 | 「重設所有資料」只清 Isar,憑證、AI key、下載檔、磁碟快取、記憶體狀態都不動 | `developer_options_page.dart:543-566`;`data_integrity_repository.dart:55-57` | +| 4 | `DataIntegrityRepository.scan/repair` 無 UI 入口,只被測試使用 | `data_integrity_repository.dart:59-85` | +| 5 | 例外轉 toast 三種寫法並存 | §2.3 第 1 點 | +| 6 | `AudioController` 限流分支把 `e.message` 直接顯示,靜態規則只掃 `lib/ui` 所以沒被攔 | `audio_provider.dart:1984-1988`;`error_presentation_static_rule_test.dart:176` | +| 7 | `app.dart` DB 失敗畫面顯示原文 | `lib/app.dart:87` | +| 8 | 背景錯誤兩種送達機制(Stream 與頁面級 listen),電台錯誤只在兩個頁面可見 | `app_shell.dart:44`;`home_page.dart:126`;`radio_page.dart:32` | +| 9 | 全螢幕播放頁上的背景 toast 可能被暫停或畫在被蓋住的 shell 上(**推測**,需實機驗證) | `router.dart:293-307`;`riverpod3_static_rule_test.dart:31-35` | +| 10 | toast 不排隊,新的蓋掉舊的 | `toast_service.dart:240-242` | +| 11 | `toast_service.dart` 註解範例呼叫不存在的 `showMessage` | `toast_service.dart:36-39` | +| 12 | `logger.dart` 註解說 release 才用 `debugPrint`,實際一律 `debugPrint` | `logger.dart:272,283` | +| 13 | 寫死字串未走 i18n:記憶體摘要 `'Flutter 图片: '`、日誌篩選 `'Info+'` / `'Warning+'` | `developer_options_page.dart:307`;`log_viewer_page.dart:208-212` | +| 14 | 約 35 個手刻 `AlertDialog`,只有破壞性確認有共用 helper | §2.2 | diff --git a/docs/audit/downloads.md b/docs/audit/downloads.md new file mode 100644 index 000000000..811ae992e --- /dev/null +++ b/docs/audit/downloads.md @@ -0,0 +1,395 @@ +# 下載與權限現況審計 + +> 現況描述,未經確認,不代表目標。 + +- 審計基準:分支 `docs/audit`(HEAD `6d78fe23`),2026-09-27。只讀原始碼與 pub cache 裡的套件 manifest,**沒有執行 app、沒有打真實 API、沒有跑測試**。 +- 行號都是實際看過的位置。標「**推測**」的是從程式碼推論、未實測;標「**不一致**」的是文件(含註釋、其他審計檔)和程式碼對不上;查不到的寫「查不到」。 +- 已經寫在其他審計檔的內容不重寫,各節開頭列出引用: + - `data.md` §5(根目錄優先序、檔名與子目錄、sidecar 欄位、去重三層、啟動清理)、§7(`customDownloadDir`、`maxConcurrentDownloads`、`downloadImageOptionIndex`) + - `features.md` §5(下載功能列表)、§13.1–13.4(啟動、定時器、清理、背景下載) + - `platforms.md` §1.5、§3、§3.8、§5.1、§5.2(平台分支、MethodChannel、Manifest、Windows runner) + - `accounts-network.md` §2 #11–12、§3、§4.2(下載用的 Dio/HttpClient、標頭、錯誤訊息外洩面) + - `errors.md` §1.2、§4.1(`UnsupportedDownloadStreamException`、下載錯誤呈現) + - `playback.md` §3.13(已下載檔的本地播放) + - `engineering.md` §0004、§0005(ADR 逐條核對) + +--- + +## 1. 從「按下載」到「檔案寫入」 + +引用:入口列表見 `features.md` §5;Dio/HttpClient 設定與 redirect 檢查見 `accounts-network.md` §2 #11–12;去重三層見 `data.md` §5.4。本節補完整呼叫鏈與行號。 + +### 1.1 UI 入口(全部在歌單詳情頁) + +`addTrackDownload`/`addTracksDownload`/`addPlaylistDownload` 在 `lib/` 只有歌單詳情頁呼叫(grep 結果)。`fromPlaylist` 是必填參數(`lib/services/download/download_service.dart:467-471`),所以**不在任何歌單裡的曲目不能下載**:搜尋頁、佇列、正在播放、排行榜、已下載頁都沒有下載入口。四個入口在 Mix 歌單都隱藏。 + +| 入口 | 顯示條件 | 呼叫鏈 | 證據 | +|---|---|---|---| +| 標題列「全部下載」按鈕 | 歌單有歌、非 Mix | 確認對話框 → 路徑檢查 → `addPlaylistDownload` | `lib/ui/pages/library/playlist_detail_page.dart:824-830,935-967` | +| 多選「下載」 | 非 Mix | `_downloadSelectedTracks` → `_addTracksToDownloadQueue`(`skipSchedule: true`,有新任務才 `triggerSchedule`) | `playlist_detail_page.dart:211,531-532,291-307,1031-1052` | +| 多 P 分組選單「下載全部分 P」 | 非 Mix | 同上 | `playlist_detail_page.dart:1268-1275,1317-1330` | +| 單曲選單「下載」 | 非 Mix | `addTrackDownload`(會自己觸發調度) | `playlist_detail_page.dart:1493-1498,1526-1535` | + +四個入口都先檢查 `hasConfiguredPath()`,沒選過目錄就跳 `DownloadPathSetupDialog`(`playlist_detail_page.dart:959-964,1020-1028`)。結果用 toast 回報,分成新增、已下載、已在佇列、部分已存在幾種(`:1054-1118`)。「已下載」只看 DB 裡的 `downloadPath` 字串,不檢查檔案在不在(`download_service.dart:507-519`;`lib/data/models/track.dart:172-188`)。 + +### 1.2 序列圖 + +```mermaid +sequenceDiagram + autonumber + participant UI as 歌單詳情頁 + participant PM as DownloadPathManager + participant P as downloadServiceProvider + participant DS as DownloadService(主 isolate) + participant DB as Isar(DownloadRepository) + participant SR as StreamResolutionService + participant ISO as 下載 isolate(HttpClient) + participant FS as 檔案系統 + participant EH as DownloadEventHandler + + UI->>PM: hasConfiguredPath()(download_path_manager.dart:25-29) + alt 沒選過目錄 + UI->>PM: DownloadPathSetupDialog → selectDirectory()(:34-56) + PM->>FS: 寫刪 .fmp_test(:59-68) + end + UI->>P: ref.read(第一次讀取時建立服務,initialize() 不 await,download_providers.dart:42-59) + UI->>DS: addTracksDownload / addPlaylistDownload(download_service.dart:491-605 / :615-636) + DS->>DB: 已下載過濾(DB 路徑字串)→ 算 savePath → getTasksBySavePaths 去重 + DS->>DB: saveTasks(status=pending,priority 遞增,:576-590) + DS-->>DS: _triggerSchedule()(事件)+每 5 秒定時器(:392-406) + DS->>DB: _scheduleDownloads:讀 maxConcurrentDownloads、取 pending(依 priority)(:420-456) + DS->>DB: 狀態改 downloading(:441-444) + DS-)DS: _startDownload(task)(不 await,:449) + DS->>SR: resolvePrimary(purpose=download, persist=true)(:1043-1050) + Note over SR: 下載不走本機檔、不重用快取的 URL(stream_resolution_service.dart:128,148-152)
音質設定與播放共用;任何錯誤重試 1 次(1 秒),限流 3 秒(:207-241) + SR-->>DS: RemoteStreamResolution(HLS 直接丟 UnsupportedDownloadStreamException,:1065-1070) + DS->>FS: 目的地已有檔:有配對 metadata→衝突失敗;沒有→刪掉(:1093-1102) + DS->>FS: 建目錄(recursive)、決定續傳位置(:1104-1122) + DS->>DB: 存 tempFilePath、status(:1126-1129) + DS->>ISO: Isolate.spawn(onError/onExit 都接到 receivePort,:818-833) + ISO-->>DS: ready(附取消用 SendPort) + loop 最多 6 跳 + ISO->>ISO: 檢查 scheme、禁止公網跳內網(:1831-1845) + ISO->>ISO: prepareDownloadHop:mediaHeaders+Range(media_handoff.dart:50-62) + end + ISO->>FS: open(append 或 write),逐塊 writeFrom(:1913-1957) + ISO-->>DS: progress(每 5%)→ 記憶體緩衝,每 1 秒 flush 給 UI(:348-389) + ISO-->>DS: completed / error(JSON 字串) / 'cancelled' + DS->>FS: 佔位 exclusive create → rename .downloading→音檔(:1460-1496) + DS->>SR: 取 VideoDetail(帶 authForPlay,:975-991) + DS->>FS: 寫 metadata JSON、封面、頭像(:1499-1599) + DS->>DB: completeTaskWithDownloadPath:同一交易寫 Track.playlistInfo 與任務 completed(download_repository.dart:189-219) + DS->>EH: DownloadCompletionEvent(:884-891) + EH->>EH: markFileExisting、移除記憶體進度、防抖後失效 library(download_event_handler.dart:28-57) + DS-->>DS: finally:釋放槽位、再觸發調度(:899-913) +``` + +### 1.3 各步補充 + +- **並行數**:`Settings.maxConcurrentDownloads`,預設 3(`lib/data/models/settings.dart:281`),設定頁是 1–5 的單選對話框(`lib/providers/download/download_settings_provider.dart:81-88`;UI `lib/ui/pages/settings/widgets/settings_storage.dart:172-185`)(核查更正:原寫「滑桿」,實為 `RadioGroup`)。調度器每次都重讀設定(`download_service.dart:425-426`)。調低時不會中斷正在跑的任務,只是暫時不補新任務。 +- **一任務一 isolate**:每個任務各開一個 isolate,註解說是為了避開 Windows 上的 "Failed to post message to main thread"(`:813-814`)。isolate 在 `_startDownload` 內 spawn,沒有 isolate 池。 +- **串流解析寫回 DB**:`persist: true` 會把新的 `audioUrl`/`audioUrlExpiry` 寫進 Track(`stream_resolution_service.dart:459-480`),`_resolveDownloadStream` 之後又把同樣的值寫到記憶體裡的 track 副本上(`download_service.dart:1072-1075`)。後者沒有存檔,是重複動作。 +- **位元組請求不帶登入**:`MediaHandoffRequest.streamResolutionAuth` 不會進請求標頭,只帶 `SourceHttpPolicy.mediaHeaders` 和 Range(`lib/services/media/media_handoff.dart:15-21,54-62`)。登入只影響解析階段選到的 URL。 +- **兩層逾時**:連線 30 秒(`lib/core/constants/app_constants.dart:124`;`download_service.dart:1820`),兩個 chunk 之間 30 秒(`app_constants.dart:118`;`download_service.dart:1928-1930`)。整體沒有上限。 + +--- + +## 2. 任務生命週期 + +引用:啟動清理的條列見 `data.md` §5.4、`features.md` §13.3–13.4;錯誤字串與翻譯見 `errors.md` §1.2、§4.1。 + +### 2.1 狀態機 + +`DownloadStatus` 有五個值(`lib/data/models/download_task.dart:6-21`)。「刪除」不是狀態,是整列從 Isar 移除。 + +```mermaid +stateDiagram-v2 + [*] --> pending: addTracksDownload(download_service.dart:576-590) + pending --> downloading: _scheduleDownloads 有空槽(:441-444) + downloading --> completed: completeTaskWithDownloadPath(download_repository.dart:211) + downloading --> failed: _handleDownloadFailure(download_service.dart:1388-1407) + downloading --> paused: pauseTask / pauseAll(:639-649, :695-711) + pending --> paused: pauseTask / pauseAll + paused --> pending: resumeTask / resumeAll(:652-656, :714-718) + failed --> pending: retryTask(歸零重下,:679-692) + downloading --> paused: 服務初始化 resetDownloadingToPaused(download_repository.dart:259-273) + pending --> paused: 服務初始化(同上) + completed --> [*]: 服務初始化刪除/clearCompleted(download_repository.dart:66-96, :318-326) + failed --> [*]: 服務初始化刪除 + pending --> [*]: cancelTask / clearQueue(刪暫存檔與半成品) + paused --> [*]: cancelTask / clearQueue + downloading --> [*]: cancelTask / clearQueue + failed --> [*]: cancelTask / clearQueue +``` + +- **不一致(註釋)**:`resetDownloadingToPaused` 的名字只講 downloading,實作把 pending 也改成 paused(`download_repository.dart:258-273`)。上一輪排在佇列裡還沒開始的任務,重啟後也要手動按繼續。 +- 「服務初始化」**不是 app 啟動**。`downloadServiceProvider` 是一般 `Provider`,第一次被讀取時才建立並呼叫 `initialize()`。讀取點只有歌單詳情頁的四個入口和下載管理頁(`lib/ui/pages/settings/download_manager_page.dart:20,331`)。沒開過這兩處的 session 不會清舊任務,也不會掃孤兒暫存檔。 + +### 2.2 進度回報 + +| 層 | 機制 | 頻率 | 證據 | +|---|---|---|---| +| isolate → 主 isolate | `SendPort`,進度每多 5% 送一次,到 100% 必送 | 依下載速度 | `download_service.dart:1941-1955`;門檻 `app_constants.dart:110` | +| 主 isolate 緩衝 | `_pendingProgressUpdates` Map,同一任務只留最新一筆;上限 256 筆,超過丟最舊的 | — | `:133-136,362-389` | +| 緩衝 → UI | 1 秒 `Timer.periodic` flush 到 `progressStream`,**不寫 DB** | 1 秒 | `:316-358` | +| UI | `downloadProgressStateProvider`(記憶體 Map)優先,沒有才用 DB 的值 | — | `download_providers.dart:86-94,132-170`;`download_manager_page.dart:334-342` | +| DB | 只在暫停、失敗、中止時由 `_saveResumeProgress` 寫入(以暫存檔實際長度為準) | 事件 | `:1219-1253` | + +- 回應沒有 `Content-Length` 時 `totalBytes = -1`,isolate 一次進度都不送(`:1918-1919,1941`)。UI 會停在 0% 直到完成(**推測**:YouTube/網易的 CDN 是否都會給長度,未實測)。 +- 進度條只在 downloading/pending 時顯示(`download_manager_page.dart:369`),paused 的任務看不到進度。記憶體進度只在完成時移除(`download_event_handler.dart:30`),暫停或重試後 UI 仍可能顯示舊值,直到下一筆進度進來。 + +### 2.3 暫停與續傳 + +- **斷點資訊存哪**:Isar 的 `DownloadTask.tempFilePath` 加 `downloadedBytes`(`download_task.dart:51,60`),實際續傳位置取 `{savePath}.downloading` 的檔案長度(`download_service.dart:1092,1114-1118`)。 +- **續傳條件**:`canResume`(有 `tempFilePath` 且 `downloadedBytes > 0`,`download_task.dart:96-98`),**而且**重新算出的 `tempPath` 要與存下的一致,暫存檔也還在(`download_service.dart:1114-1116`)。`savePath` 每次開始時都依目前的根目錄、任務建立時存下的 `task.playlistName`、目前的曲目標題重算(`:1412-1421`)。所以暫停期間改了根目錄或標題(`parentTitle`/`title`),就會刪掉舊暫存檔從頭下(`:1119-1122`)(核查更正:原寫「根目錄、歌單名或標題」;歌單名取自任務建立時的快照 `task.playlistName`(`:579`),暫停期間改歌單名不影響 `savePath`)。 +- **Range**:`Range: bytes=N-`(`media_handoff.dart:57-59`)。伺服器回 200 就改成從 0 覆寫(`download_service.dart:1904-1906`)。沒有檢查 `Content-Range`、`ETag` 或 `If-Range`。 +- **推測**:每次繼續都重新解析 URL(下載不重用,`stream_resolution_service.dart:148-152`)。音質降級(`lib/data/sources/audio_stream_quality_fallback.dart:42-66`)或串流優先序(audioOnly/muxed)讓第二次拿到不同的檔案時,只要伺服器回 206,新檔的位元組就會接在舊檔後面,產生內容損壞但標記為完成的檔案。沒有任何大小或雜湊驗證能擋下。 +- 暫停是**協作式**的:isolate 只在收到下一個 chunk 時檢查取消旗標(`:1931-1937`)。主 isolate 最多等 2 秒,之後直接 kill isolate(`:1197-1203`)。 + +### 2.4 重試 + +- **下載本身不自動重試**。isolate 回報任何錯誤,任務就直接 failed(`:874-876,892-898`)。 +- 自動重試只發生在串流解析:任何例外重試 1 次(等 1 秒)、限流重試 1 次(等 3 秒)(`stream_resolution_service.dart:207-241`;`app_constants.dart:138,143-145`),加上音質由高往低降級。 +- 手動重試(`retryTask`)會把 `downloadedBytes` 歸零(`download_service.dart:685-688`),於是 `canResume` 為 false,暫存檔被刪掉從頭下(`:1119-1122`)。失敗前 `_handleDownloadFailure` 才剛存好的續傳進度(`:1393`)因此用不到。 + +### 2.5 取消(刪除任務) + +- `cancelTask`:標記 discard guard → 送 `cancel` → 刪 DB 任務 → 未完成的任務刪 `tempFilePath` 與 `savePath`,並刪根目錄內的空資料夾(`:659-676,1263-1293`)。刪除有 10 次 × 50ms 的重試,用來應付 Windows 檔案占用(`:1299-1319`)。只刪根目錄內的路徑(`:1273-1277`)。 +- finalization 已經開始才取消時,每一步後都會檢查,並清掉 DB 路徑和落盤產物(`:996-1001,1007-1038`)。 +- 下載管理頁的「清空佇列」會刪所有未完成任務和它們的檔案,接著再清已完成(`download_manager_page.dart:40-50`;`download_service.dart:721-748`)。 + +### 2.6 失敗處理 + +| 面向 | 現況 | 證據 | +|---|---|---| +| 使用者看到什麼 | toast「下載失敗: {標題}」+下載管理頁該列紅字錯誤原因與重試鈕 | `download_providers.dart:72-76`;`download_manager_page.dart:383-416` | +| 原因字串 | 存翻譯後的句子,語言固定在失敗當下 | `download_service.dart:1375-1385` | +| HTTP 4xx/5xx、redirect 無 Location、超過 5 跳 | isolate 送的是**純字串**(`'HTTP 403'` 等),不是 JSON,還原成通用 `Exception`,使用者只看到通用訊息,看不出是 403 還是 404 | `:1870-1901,1348-1358` | +| isolate 非正常死亡 | `onError`/`onExit` 轉成錯誤,不再卡住槽位 | `:828-832,960-968` | +| 是否持久化 | 是,`failed` 列留在 Isar | `download_repository.dart:168-186` | +| 何時消失 | 下次**服務初始化**時連同 completed 一起刪(見 §2.1) | `download_service.dart:206-212` | + +### 2.7 App 重啟後未完成任務 + +- 服務初始化時 downloading/pending 都改成 paused,**不自動續傳**(`download_service.dart:214-215`)。已存的暫存檔保留,使用者按繼續才會續傳。 +- 孤兒 `.downloading` 掃描用 **basename** 比對(`:238-273`)。檔名固定是 `audio.m4a.downloading` 或 `P01.m4a.downloading` 這幾種(`download_path_utils.dart:39-46`),只要有一個暫停中的單 P 任務,整個根目錄下所有 `audio.m4a.downloading` 孤兒都不會被刪。註釋承認「同名時寧可留著」(`:234-235`),但實際上等於幾乎永遠同名。 +- 掃描只看**目前**根目錄(`:240-244`)。改過下載路徑後,舊目錄的暫存檔永遠不會被清。 + +--- + +## 3. 音質、檔名、metadata、分 P + +引用:路徑格式、全形替換、Windows 保留名、`.m4a` 一律副檔名、sidecar 欄位、HLS 拒絕,都見 `data.md` §5.2–5.3。本節只補缺的。 + +### 3.1 音質 + +- **下載與播放共用同一組設定**,沒有下載專用的音質:`AudioStreamConfig.fromSettings` 取 `audioQualityLevel`、`audioFormatPriorityList`、`streamPriorityFor(sourceType)`(`lib/data/sources/base_source.dart:44-50`;`stream_resolution_service.dart:404-406`)。失敗時由高往低降級(`audio_stream_quality_fallback.dart:23-66`)。 +- 串流優先序預設:Bilibili `audioOnly,muxed`、YouTube `audioOnly,muxed,hls`、網易 `audioOnly`(`settings.dart:59-63`)。 + - **推測**:audio-only 拿不到而落到 muxed 時,下載的是含影像的容器,檔名仍是 `.m4a`。 + - 解析結果是 HLS 時直接失敗(`download_service.dart:1065-1070`),不會改用優先序裡的下一種類型。 +- 網易試聽片段下載端擋不到:見 `sources.md` 下載列。 + +### 3.2 檔名與目錄(補 data.md 未寫的) + +- **控制字元不處理**:`sanitizeFileName` 只換 9 個符號、去頭尾空白、去結尾的點(`download_path_utils.dart:81-115`)。**推測**:標題含換行或 Tab(0x00–0x1F)時,Windows 建目錄會失敗,任務 failed。 +- **順序問題**:先 `trim` 再去結尾的點,所以「abc .」會變成「abc 」(結尾空白),Windows 不允許這種名稱(**推測**:失敗或被系統靜默去掉,未實測)。 +- **200 字截斷**以 UTF-16 code unit 計(`:109-112`)。**推測**:可能把 emoji 的代理對切半。整條路徑長度沒有控制:根目錄 + 200 字歌單名 + sourceId + 200 字標題,可能超過 Windows 的 260 字元限制(Dart 是否自動加 `\\?\`,未查證)。 +- **重名**:歌單名只在原字串層級唯一(`lib/services/library/playlist_service.dart:160-162`)。「a:b」與「a:b」換成全形後是同一個資料夾,兩個歌單的同一首歌算出同一個 `savePath`,後下載的那個會被判「已在佇列」或「目的地已有檔案」失敗(`download_service.dart:544-571,1093-1096`)。 +- **分 P**:`isPartOfMultiPage` 是 `pageCount > 1`(`track.dart:328`),檔名 `P{NN}.m4a` 補到兩位(`download_path_utils.dart:40-43`)。同一支影片的所有分 P 共用 `{sourceId}_{parentTitle}` 資料夾,各自有 `metadata_P{N}.json`。掃描時分 P 號以檔名為準,覆蓋 metadata 裡的值(`lib/providers/download/download_scanner.dart:352-366`)。 +- **不一致**:`data.md` §5.4 最後一條說「歌單改名時會連資料夾一起改」。程式碼**不改資料夾**:它清掉該歌單所有曲目的下載路徑,回傳新舊資料夾路徑,請使用者自己搬(`playlist_service.dart:136-141,166-189`;UI `lib/ui/pages/library/widgets/create_playlist_dialog.dart:483-484`)。而且 `Track.playlistInfo[].playlistName` 不會跟著改名(改名流程沒有更新它),這點在 §4.4 會用到。 + +### 3.3 metadata 與圖片(補 data.md 未寫的) + +- VideoDetail 在 finalization 時抓,抓失敗只記 debug,metadata 就少掉擴充欄位(`download_service.dart:975-991`)。`_fetchVideoDetail` 用 `authForPlay`(`:979-981`)。 +- 封面:`ThumbnailUrlUtils.getOptimizedUrlCandidates` 的 `ImageTargetSizes.high` 候選,依序試(`:1567-1581,1601-1622`)。頭像用 `low`,只有 `coverAndAvatar` 模式而且有 VideoDetail 時才抓(`:1583-1598`)。兩者失敗都只記 debug。`downloadImageOptionIndex` 預設 1=只抓封面(`settings.dart:284`;UI `settings_storage.dart:241`)。 +- **不寫內嵌 tag**:pubspec 沒有任何 ID3/MP4 tag 或 ffmpeg 套件(grep `tag|id3|ffmpeg|metadata` 只命中授權註解),音檔是 CDN 原始位元組。檔案離開 FMP 後,播放器看到的標題就是 `audio.m4a`。 + +--- + +## 4. 下載路徑 + +引用:根目錄優先序與 Android/Windows 預設見 `data.md` §5.1;平台分支見 `platforms.md` §1.5;ADR 0004 逐條核對見 `engineering.md` §0004。 + +### 4.1 首次設定 + +`DownloadPathSetupDialog._selectPath`(`lib/ui/widgets/dialogs/download_path_setup_dialog.dart:62-97`)→ `selectDirectory`(`download_path_manager.dart:34-56`): + +1. Android 先要權限(§6)。沒拿到就回 null,對話框回到可再按的狀態(`download_path_setup_dialog.dart:78-81`)。 +2. `FilePicker.getDirectoryPath()`。 +3. 寫再刪 `.fmp_test`(`download_path_manager.dart:59-68`)。失敗就跳「權限不足」對話框並回 null(`:48-53,98-119`)。 +4. 存進 `Settings.customDownloadDir`(`:71-75`)。 + +**推測**:Android 選到 SD 卡目錄時,`MANAGE_EXTERNAL_STORAGE` 對可移除儲存空間不一定有寫入權。`.fmp_test` 會失敗並擋下這次選擇,未實測。 + +### 4.2 設定頁變更 + +| 平台 | 能不能改 | 流程 | 證據 | +|---|---|---|---| +| Android | **不能**。選單只有「路徑資訊」 | 第一次選定之後,App 內沒有任何入口能重選(`hasConfiguredPath` 永遠 true,也不會再跳設定對話框) | `settings_storage.dart:60-76` | +| Windows | 能 | 確認(警告「會重設下載記錄」「檔案不會被刪」)→ 選目錄 → `changeBasePathAndResetDownloads` | `lib/ui/widgets/dialogs/change_download_path_dialog.dart:185-247` | + +`changeBasePathAndResetDownloads`(`lib/services/download/download_path_maintenance_service.dart:59-80`)做三件事:清空**所有** Track 的下載路徑、刪除已完成和失敗的任務、存新路徑。它**不搬移舊檔**,也**不掃描新目錄**。對話框只失效 `downloadPathProvider` 和 library(`change_download_path_dialog.dart:211-217`),要等重啟或手動同步才會認出新目錄裡原有的下載。其他副作用: + +- paused/pending 任務沒被處理。之後會下到新根目錄,因為 `tempPath` 不同而從頭下(§2.3)。 +- **推測(競態)**:變更時正在跑的任務已經算好了舊的 `savePath`,完成後會把舊路徑寫回 DB(`download_repository.dart:189-219`),下次啟動同步掃不到新根目錄以外的東西,又會把它清掉。 +- `downloadBaseDirProvider`(曲目詳情面板用來找頭像)沒被失效,直到重啟前都拿著舊根目錄(`download_providers.dart:173-176`;`lib/ui/widgets/panels/track_detail_panel.dart:781`;grep 不到 invalidate)。 + +### 4.3 路徑失效時的行為 + +| 情境 | 下載時 | 啟動時 | 播放已下載檔時 | +|---|---|---|---| +| 資料夾被刪 | `dir.create(recursive: true)` 重建,照常下載(`download_service.dart:1104-1108`) | 根目錄不存在:同步回 `(0,0)`,不清 DB(`download_path_sync_service.dart:32-35`);孤兒掃描略過(`download_service.dart:243-244`)。只刪歌單子目錄時,該目錄裡的曲目在同步時被清掉路徑(§4.4 第 4 步;曲目若還在別的資料夾配對到,則是第 3 步丟掉該條目)(核查更正:原寫「第 3 步」) | `File.existsSync` 不在就**永久**清掉該路徑,改播線上(`stream_resolution_service.dart:128-136,483-496`;見 `playback.md` §3.13) | +| SD 卡拔出/磁碟機不在 | 建目錄丟 `FileSystemException` → failed | 同上(根目錄不存在就不動 DB) | 同上。**推測**:暫時拔出期間播一次,該曲的下載關聯就沒了,要等重新插入後重啟(或手動同步)才找回 | +| Android 權限被撤銷 | 開檔丟 `PathAccessException` → failed,訊息「沒有權限存取」(ADR 0004;`download_service.dart:1995-2010`;`lib/core/errors/user_message.dart:85`)。**不會重新要求權限**,也沒有導去設定的入口 | **推測**:撤銷後系統會殺掉行程。重啟時,若 `Directory.exists()` 為真但列不到 metadata 檔(scoped storage 過濾),同步第 4 步會把所有下載路徑清掉(核查更正:原寫「第 3 步」;沒配對到的曲目是在第 4 步 `:214-224` 被清);若 `list()` 拋例外,整次同步被 catch 吞掉(`startup_download_sync_provider.dart:32-39`)(核查更正行號)。需實機驗證 | 同「資料夾被刪」 | +| Windows 無寫入權 | 選目錄時 `.fmp_test` 擋下;事後才失去權限時,`PathAccessException` → failed | 列目錄失敗:被 catch | 讀得到就照播 | +| Windows 路徑不存在 | 同「資料夾被刪」;上層磁碟不在時失敗 | 同上 | 同上 | + +App 啟動時沒有任何「下載目錄是否可用」的檢查或提示。`StoragePermissionService.hasStoragePermission()` 在 `lib/` 沒有呼叫者(`storage_permission_service.dart:69-77`;grep)。 + +### 4.4 `DownloadPathSyncService` 做什麼 + +`syncLocalFiles`(`download_path_sync_service.dart:26-232`)在啟動時由 `startupDownloadSyncProvider` 呼叫(`lib/app.dart:131`;`lib/providers/download/startup_download_sync_provider.dart:9-40`),已下載頁也有手動按鈕(`lib/ui/pages/library/downloaded_page.dart:38-75`)。步驟如下: + +1. 列出根目錄下每個一級子資料夾(歌單資料夾),用 `DownloadScanner.scanFolderForTracks` 掃二級資料夾裡的 `.m4a`(`:48-67`;`download_scanner.dart:297-407`)。 +2. 配對:先用 `TrackSourceIdentity` 直接命中;沒有 cid 時,退回 `formatGroup` 分組再比 `pageNum`(`:69-98,234-272`,與 ADR 0005 描述一致)。 +3. 對每個配對到的 Track **重建整個 `playlistInfo`**:只保留 `playlistName` 等於**資料夾名**的舊條目,把路徑換成本地的;本地沒有對應資料夾的舊條目**整條丟掉**(`:158-181`);多出來的資料夾加成 `playlistId=0`(`:183-197`)。 +4. DB 裡有下載路徑、但這次沒配對到的 Track,清空所有下載路徑(保留歌單關聯,`:214-224`)。 + +**資料遺失路徑(呼叫鏈已由程式碼逐段確認;未實機重現)**(核查更正:原寫「由程式碼推導的資料遺失路徑(未實測)」,每一段都查得到程式碼,只剩「未實機跑過」這一點)。`playlistInfo` 同時是「曲目屬於哪些歌單」的紀錄:`belongsToPlaylist` 讀它(`track.dart:156-158`),孤兒清理也以「沒有 `playlistId > 0` 的條目」判定孤兒(`lib/data/repositories/track_repository.dart:635-661`)。證據鏈: + +1. **寫入端存原始名**:下載任務的 `playlistName` 是 `fromPlaylist.name` 原字串(`download_service.dart:499,579`),完成時 `setDownloadPath(..., playlistName: task.playlistName)` 寫進 `playlistInfo`(`download_repository.dart:206-210`);加入歌單時也存原始 `name`(`playlist_mutation_repository.dart:765-797`)。 +2. **磁碟端是清理過的名**:資料夾名是 `sanitizeFileName(playlistName)`(`download_path_utils.dart:29-31`)。 +3. **比對**:同步的 `folderName` 取磁碟資料夾名(`download_path_sync_service.dart:283`),與 `info.playlistName` 做 `==` 字串比對(`:123-131,165-169`)。 +4. **丟條件**:對每個**配對到本地檔**的 Track,`playlistInfo` 被整個重建:舊條目只有名字等於某個本地資料夾名才保留,其餘(不論有沒有下載路徑)一律丟掉(`:162-181`,註解「本地没有匹配的文件夹 → 不保留」);沒對上的資料夾加成 `playlistId=0`(`:186-197`),整批 `saveAll`(`:199,226-228`)。 +5. **觸發時機**:每次 app 啟動,`app.dart:131` watch `startupDownloadSyncProvider` → `syncLocalFiles()`(`startup_download_sync_provider.dart:16`);已下載頁的手動同步按鈕也跑同一個函式。 +6. **刪除**:`AudioController` 初始化時 `QueueManager.initialize` 排一個 10 秒 `Timer`(`queue_manager.dart:219-229`)→ `_cleanupOrphanTracks`(`:830-843`)→ `deleteOrphanTracks`。唯一的豁免是目前佇列裡的 id(`track_repository.dart:648`);判定只看 `playlistInfo` 有沒有 `playlistId > 0`(`:653-658`)。**不**檢查 `Playlist.trackIds`、`DownloadTask.trackId` 或下載路徑是否存在(`PlayHistory` 存的是快照、不引用 Track id,本來就不影響)。Track 列直接 `deleteAll`(`:669`)。 +7. **兩者的先後不影響結論**:同步若在 10 秒內寫完,同一次啟動就刪;若同步較慢,被改寫的 `playlistInfo` 已落盤,下一次啟動的清理照樣刪。 + +會觸發的情況: + +- 歌單名含 `/ \ : * ? " < > |`、頭尾空白、結尾的點、超過 200 字、Windows 保留名時,兩者不相等(核查補:手動建立的歌單名會先 `trim`(`create_playlist_dialog.dart:436`),頭尾空白主要來自匯入時直接用遠端標題(`import_service.dart:237`))。 +- 使用者照 §3.2 改名流程的提示把資料夾搬成新名稱時,也不相等(`playlistName` 仍是舊名)。反過來,改名後**不搬**資料夾,同步會用舊名對回舊資料夾,把改名時清掉的下載路徑又接回去。 + +不相等時,該歌單的條目被丟掉,只剩 `playlistId=0`。若這首歌不屬於其他有條目的歌單、而且不在佇列裡,孤兒清理會刪掉這個 Track 列;`Playlist.trackIds` 仍指向已刪除的 id,`getByIds` 讀取時靜默濾掉(`track_repository.dart:72-84`),曲目就從歌單消失。本地歌單沒有任何回填機制;遠端匯入的歌單下次刷新時 `replaceTracksFromRemoteRefresh` 會重建關聯(`playlist_mutation_repository.dart:427,469`),但被刪的 Track 會以新 id 重建。 + +即使名稱對得上,重建(上面步驟清單第 3 步、證據鏈第 4 步)對「同時屬於另一個**沒下載**的歌單」的曲目也會丟掉那個歌單的條目(那個歌單沒有本地資料夾可對)。曲目因為還有已下載歌單的條目而不被刪,但之後只要從已下載的歌單移除,就會在下次啟動被當成孤兒刪掉,儘管它仍在另一個歌單的 `trackIds` 裡。 + +測試:`test/providers/startup_download_sync_provider_test.dart` 透過 provider 呼叫真實的 `syncLocalFiles`,但沒有任何案例設定 `playlistInfo` 的歌單名或多歌單歸屬;`test/services/download/download_system_requirements_test.dart:189-222` 只模擬配對(核查更正:原寫「現有測試沒有真的呼叫 `syncLocalFiles`」)。 + +- **不一致**:註釋「C1: 跳过没有有效 metadata 的文件」(`download_path_sync_service.dart:22,286-290`)以及 `data.md` §5.4「沒有有效 metadata 的檔案會跳過」,都和程式碼不符。掃描器對沒有 metadata 的 `.m4a` 會用資料夾前綴當 sourceId、`sourceType` 固定填 Bilibili,產生 DTO(`download_scanner.dart:385-391`),`sourceId` 因此幾乎不會是空字串,跳過條件形同虛設。**推測**:promote 中途被殺、留下無 metadata 的空佔位 `audio.m4a` 時,若該 bvid 在 DB 裡有對應曲目,同步會把它記成已下載,播放時本地優先,播到空檔。 +- `cleanupInvalidPaths()` 是死代碼(見 `features.md` §5)。 + +--- + +## 5. 已下載檔案 + +引用:播放時本地優先的判斷位置與後端見 `playback.md` §3.13;DB 對應欄位見 `data.md` §5.4;刪除的擁有權判定邏輯本節補。 + +### 5.1 播放與對應 + +- 判斷位置:`StreamResolutionService.resolvePrimary` 對非下載用途先跑 `_inspectLocalFiles`,第一個存在的 `allDownloadPaths` 就用(`stream_resolution_service.dart:128-145,483-496`)。它不管目前是從哪個歌單播的,任何歌單的下載都算。 +- 已下載頁與分類頁的曲目**不是 DB 列**,是從 metadata 即時造出的 `Track`(`playlistId=0`,`download_scanner.dart:86-105`),再交給 `playTemporary`/`addAllToQueue`(`lib/ui/pages/library/downloaded_category_page.dart:290,368-382`)。 + +### 5.2 掃描、同步、快取 + +| 機制 | 何時跑 | 在哪個 isolate | 證據 | +|---|---|---|---| +| 分類列表 `downloadedCategoriesProvider` | 已下載頁顯示、同步後失效 | `Isolate.run` | `download_providers.dart:195-208`;失效 `library_invalidation_coordinator.dart:159` | +| 分類內曲目 `downloadedCategoryTracksProvider` | 進分類頁 | `Isolate.run` | `download_providers.dart:213-219` | +| 啟動同步 `syncLocalFiles` | 每次啟動+手動 | **主 isolate**(逐資料夾 await 檔案 IO) | `download_path_sync_service.dart:61-67` | +| `FileExistsCache` | UI 查「有沒有下載」與本地封面時 | 主 isolate,非同步 `File.exists`;正向與負向各上限 5000 | `lib/providers/download/file_exists_cache.dart:36-50,188-203`;完成時 `markAsExisting`(`download_event_handler.dart:29`) | + +- 分類列表只數 `.m4a`,而且用 `recursive: true` 數(`download_scanner.dart:223-233`);曲目列表只看二級資料夾(`:305-313`)。兩者的深度定義不同。 +- 負向快取沒有 TTL,只靠 `downloadStateChanged` 事件整批失效(`lib/providers/library/library_invalidation_coordinator.dart:86-97`)。 + +### 5.3 刪除(刪檔 vs 刪記錄) + +| 動作 | 刪檔 | 刪/清 DB | 入口 | +|---|---|---|---| +| 刪整個分類(歌單資料夾) | 只刪「能證明是 FMP 寫的」檔(固定檔名或有配對 metadata 的 `.m4a`),不遞迴刪、不跟隨符號連結;`.downloading` 不動 | 刪前先掃描,刪後比對,把消失的路徑從 Track 清掉 | `downloaded_page.dart:450-510`;`download_path_maintenance_service.dart:82-116,376-448` | +| 刪單曲/刪整組分 P | 同上規則;資料夾裡沒剩音檔才清封面、頭像、metadata 和空資料夾 | 同上 | `downloaded_category_page.dart:528-556,697-727`;`download_path_maintenance_service.dart:118-137,451-523` | +| 從歌單移除曲目/刪歌單 | **不刪檔** | 只動 `playlistInfo` | `playlist_mutation_repository.dart:118-140`(無任何 `File(`/`Directory(`,grep) | +| 取消下載任務 | 刪暫存檔與未完成的目的地 | 刪任務列 | §2.5 | + +- 歌單詳情頁沒有「刪除已下載檔案」的入口。刪檔只能從「音樂庫 → 已下載」進去做。 +- 刪除時根目錄解析失敗,containment guard 就停用,照樣刪(`download_path_maintenance_service.dart:139-156,628-632`)。 + +### 5.4 清理 + +- 孤兒 `.downloading`:服務初始化時掃一次(§2.7 的限制)。 +- 孤兒音檔(磁碟上有、DB 沒對到):不清。同步只會把能配對的記成 `playlistId=0`,配不到的留在磁碟上,已下載頁照樣顯示。 +- DB 裡的失效路徑:啟動同步第 4 步,加上播放時的 `existsSync` 順手清。 + +--- + +## 6. 各平台權限總表 + +引用:Manifest 權限清單與 MethodChannel 方法見 `platforms.md` §3.8、§5.1;Windows 開機自啟、托盤、熱鍵、單一實例見 `platforms.md` §3、§5.2。本表補「誰在什麼時候請求、被拒怎麼辦」。外掛合併進來的權限是查 pub cache 裡 lock 版本的 manifest 得到的(`open_filex-4.7.0/android/src/main/AndroidManifest.xml`)。其他外掛(audio_service 0.18.18、just_audio 0.10.6、file_picker 11.0.3、flutter_inappwebview_android 1.1.3 等)的 manifest 沒有宣告 `uses-permission`。 + +### 6.1 Android + +| 權限 | 宣告位置 | 在哪裡請求 | 何時請求 | 被拒時 | UI 說明 | +|---|---|---|---|---|---| +| `MANAGE_EXTERNAL_STORAGE`(API 30+) | `AndroidManifest.xml:22-23` | `storage_permission_service.dart:86-101` → `MainActivity.kt:75-103`(`ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION`,失敗退到全域設定頁) | 第一次下載時的選目錄流程(`download_path_manager.dart:36-41`) | `selectDirectory` 回 null,設定對話框留在原地,可以再按;不會下載。事後撤銷:下載 failed,**沒有重新請求的入口**(§4.3) | 有:先顯示說明對話框(`storage_permission_service.dart:180-241`) | +| `READ_EXTERNAL_STORAGE`(maxSdk 32)、`WRITE_EXTERNAL_STORAGE`(maxSdk 29) | `AndroidManifest.xml:17-20`(open_filex 另宣告 READ maxSdk 32) | `storage_permission_service.dart:114-116` → `MainActivity.kt:105-136` 系統權限框 | 同上,只在 API 23–29 | 回 false,選目錄中止,**沒有說明也沒有導去設定**。**推測**:使用者勾「不再詢問」後每次都靜默被拒。API 30–32 宣告了 READ 但從不請求(`MainActivity.kt:125-130` 對 ≥R 回空陣列) | 無 | +| `permanentlyDenied` 分支/`openAppSettings` | — | `storage_permission_service.dart:103-109,174-177,244-269`;`MainActivity.kt:138-148` | **生產路徑到不了**:`_manageExternalStorageStatus` 只回 granted/denied(`:145-151`),只有測試覆寫能走到 | — | 有對話框但到不了 | +| `REQUEST_INSTALL_PACKAGES` | `AndroidManifest.xml:14` | 檢查 `lib/providers/system/update_provider.dart:183-186` → `update_service.dart:295-301`;開設定 `update_service.dart:303-306` → `MainActivity.kt:155-169` | 使用者在更新對話框按更新、APK 下載完成要安裝時 | 狀態停在 `installPermissionRequired`,對話框顯示按鈕讓使用者去設定(`lib/ui/widgets/dialogs/update_dialog.dart:121,290,342-346`) | 有 | +| `INTERNET` | `AndroidManifest.xml:10`(debug/profile manifest 也有) | 一般權限,不需請求 | — | — | — | +| `ACCESS_NETWORK_STATE` | `AndroidManifest.xml:11` | 一般權限。Dart 端查不到使用者:pubspec 沒有 connectivity_plus,連通性偵測是 DNS 解析(`features.md` §13.2) | — | — | — | +| `WAKE_LOCK`、`FOREGROUND_SERVICE`、`FOREGROUND_SERVICE_MEDIA_PLAYBACK` | `AndroidManifest.xml:5-7`;service `:64-72` | 一般權限;前景服務由 audio_service 在播放時啟動 | 播放時 | — | 媒體通知 | +| `READ_MEDIA_IMAGES`/`READ_MEDIA_VIDEO`/`READ_MEDIA_AUDIO` | open_filex 4.7.0 的 manifest 合併進來 | **從不請求**(grep 不到) | — | — | — | +| `POST_NOTIFICATIONS` | **沒有宣告**(主 manifest 與外掛 manifest 都沒有;核查補:本機既有的 `build/app/intermediates/merged_manifests/{debug,profile,release}` 合併結果也沒有,另有 androidx 加入的 `com.personal.fmp.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION`,非執行期權限) | 無 | — | **推測**:媒體通知依 Android 13 規則屬於 media session 豁免,未實機驗證 | — | +| 電池最佳化豁免(`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`) | 沒有宣告 | 無(grep 不到) | — | — | — | +| 下載用的前景服務/通知 | 無 | 下載只在 app 行程內用 isolate 跑,沒有自己的前景服務或 WorkManager | — | **推測**:背景時隨 app 被系統回收而中斷,重啟後變成 paused(§2.7) | 無下載通知 | + +### 6.2 Windows + +| 項目 | 宣告/位置 | 何時 | 被拒或失敗時 | UI 說明 | +|---|---|---|---|---| +| 檔案系統寫入(下載目錄) | 預設 `Documents\FMP`;自選目錄用 file_picker | 選目錄時寫 `.fmp_test` 驗證 | 跳「權限不足」對話框(`download_path_manager.dart:48-53`);下載時失敗 → failed | 有 | +| 登錄檔 `HKCU\...\Run`(開機自啟) | launch_at_startup(`lib/providers/settings/desktop_settings_provider.dart:117-157`) | 使用者開啟設定時 | 見 `platforms.md` §3 | 設定頁開關 | +| 全域熱鍵、具名 mutex、AppUserModelID、托盤 | 見 `platforms.md` §3、§5.2 | 啟動時 | 同左 | — | +| 防火牆 | 查不到任何 `HttpServer`/`ServerSocket`(grep `lib/`),不會觸發防火牆提示 | — | — | — | +| UAC | 安裝版更新以 `/SILENT` 執行安裝程式(`features.md` §15.3) | 使用者按更新 | 見 `features.md` §15.3 | 更新對話框 | + +--- + +## 7. 觀察 + +### 7.1 競態 + +1. **首次讀取服務時的初始化競態(推測)**:`initialize()` 不 await(`download_providers.dart:59`),UI 取到服務後馬上呼叫 `addPlaylistDownload`(`playlist_detail_page.dart:966-967`)。可能的交錯有兩種: + - `saveTasks` 的交易(`download_service.dart:590`)比 `resetDownloadingToPaused` 先提交時,剛建立的 pending 任務會被改成 paused(`download_repository.dart:259-273`),使用者看到「已加入佇列」卻不動。 + - `_triggerSchedule` 在調度訂閱建立之前送出(`download_service.dart:222-223` 要等整個根目錄遞迴掃描完),broadcast 事件會丟失,要等 5 秒定時器才補上。 +2. **改路徑與進行中下載**:見 §4.2。 +3. **掃描與寫入**:啟動同步在主 isolate 列目錄時,同一時間有下載正在 promote/寫 metadata。**推測**:同步可能讀到還沒寫 metadata 的音檔,走無 metadata 的退路配對(§4.4)。 +4. **暫存檔大小與 DB 值**:`pauseTask` 先 `_saveResumeProgress` 再停 isolate(`download_service.dart:642-647`),第一次存的長度比實際少。之後 isolate 收尾時會再存一次(`:866-871`),所以最終值正確,但中間有一段 DB 與檔案不一致。 + +### 7.2 重複邏輯 + +- 「根目錄是誰」有三個入口:`DownloadPathUtils.getDefaultBaseDir`(`download_path_utils.dart:187-216`)、`DownloadPathManager.getEffectiveBaseDir`(`download_path_manager.dart:87-88`,只是轉呼叫)、`downloadBaseDirProvider`(`download_providers.dart:173-176`)。`downloadServiceProvider` 與 `downloadedCategoriesProvider` 各自 new 一個 `SettingsRepository`(`:45-47,199-201`),沒有用 `settingsRepositoryProvider`。 +- 「曲目 ↔ 本地檔配對」有三份規則:同步的 `_matchScannedDownload`(`download_path_sync_service.dart:234-272`)、維護服務的 `_findMatchingPersistedTrack`(`download_path_maintenance_service.dart:272-299`,掃到的曲目沒有 cid 也沒有 pageNum、候選又只有一個時直接回那一個)(核查更正:原寫「候選只有一個時連 pageNum 都不比」;掃到的曲目有 pageNum 時仍會比,見 `:284-288`),以及 `playlistInfo` 的名稱/id 雙軌比對(`track.dart:89-106,172-188`)。 +- 已完成/失敗任務清理有兩個呼叫點:服務初始化(`download_service.dart:207`)與改路徑(`download_path_maintenance_service.dart:72`),另有 `DownloadService.clearCompletedAndErrorTasks` 公開方法(`download_service.dart:757-770`)。grep 不到它的呼叫者,維護服務直接用 repository 版本(`lib/providers/download/download_path_provider.dart:22-33`)。 +- `DownloadPathUtils.getAvatarPath`/`ensureAvatarDirExists` 沒有呼叫者(見 `data.md` §5.2);`StoragePermissionService.hasStoragePermission` 沒有呼叫者(§4.3);`DownloadRepository` 的多個查詢無引用(見 `engineering.md` 無引用清單 #13–20)。 +- `download_provider.dart` 與 `download_providers.dart` 兩個 barrel(見 `architecture.md`)。 + +### 7.3 與 ADR 0004 的一致性(補 `engineering.md` §0004 未涵蓋的) + +| ADR 0004 主張 | 現況 | 判定 | +|---|---|---| +| `_manageExternalStorageStatus` 只回 granted/denied,沒有 `permanentlyDenied` 這條路 | 符合(`storage_permission_service.dart:145-151`);但 `permanentlyDenied` 分支、`_showGoToSettingsDialog`、`openAppSettings` 仍留在程式碼裡,只有測試覆寫會走到 | 一致;有殘留死路徑 | +| 回來仍未授權 → `selectDirectory` 回 null,設定對話框留在原地,下載不會加進佇列 | 符合(`download_path_manager.dart:37-41`;`download_path_setup_dialog.dart:78-81`;入口 `playlist_detail_page.dart:962-963`) | 一致 | +| 寫檔被拒時下載會失敗、不會卡住 | 符合(`download_service.dart:1908-1916,1995-2010`),另有 `onError`/`onExit` 兜底(`:828-832`) | 一致 | +| 平台預設目錄留著,是為了讓舊版檔案仍能被掃描與同步 | 只在「從沒選過目錄」時成立。一旦選了自訂目錄,掃描、同步、刪除都只看自訂目錄(`download_path_utils.dart:193-196`),而啟動同步是 REPLACE 模式,會把舊預設目錄裡的路徑清掉(`download_path_sync_service.dart:214-224`)。新下載又一定要先選目錄,所以舊檔在第一次新下載後就從 App 消失(檔案仍在磁碟上) | **不一致**(與 ADR 的意圖不一致;**推測**:ADR 的描述沒有考慮到同步的 REPLACE 行為) | +| 後果:沒有權限就沒有下載目錄 | 第一次成立;事後撤銷權限時,目錄設定仍在,App 也沒有重新請求或改路徑的入口(Android 設定頁不給改) | ADR 沒寫到這個情境 | + +### 7.4 與 ADR 0005 的一致性(補 `engineering.md` §0005 未涵蓋的) + +- 同步配對「先 `TrackSourceIdentity`,沒有 cid 再退回 `formatGroup` 加 `pageNum`」與 ADR 描述一致(`download_path_sync_service.dart:69-98,234-272`)。 +- 維護服務在候選只有一個、掃到的曲目又沒有 cid 和 pageNum 時,直接回那一個(`download_path_maintenance_service.dart:292-294`)。ADR 只寫到「有 cid 比 cid、沒有才比 pageNum」,沒提這條退路。這不算矛盾,是 ADR 沒寫到的細節。 +- 下載的 `savePath` 不含 cid,分 P 靠 `pageNum` 決定檔名(`download_path_utils.dart:40-43`)。掃描端再以檔名覆寫 pageNum(`download_scanner.dart:352-366`)。檔案層的分 P 身分是 pageNum,DB 層是 cid,兩者靠 metadata 裡的 cid 接起來。metadata 缺 cid(例如下載當下 cid 還沒回填)時,走 ADR 所說的 `formatGroup` 加 `pageNum` 退路。 + +### 7.5 其他 + +- `downloadServiceProvider` 依賴的 provider(`streamResolutionServiceProvider`、`sourceAuthContextProvider`、`sourceManagerProvider`)目前只直接或間接 watch `databaseProvider`,`sourceManagerProvider` 則不 watch 任何東西(核查更正:原寫「都只 watch `databaseProvider`」)(`lib/providers/audio/stream_resolution_provider.dart:10-23`;`lib/providers/account/source_auth_context_provider.dart:8-16`;`lib/data/sources/source_provider.dart:102-106`),服務在 session 中不會被重建。**推測**:日後任何一個改成 watch 會變動的狀態(例如帳號),服務重建時會殺掉所有 isolate,並重跑初始化:清掉失敗任務,把 pending 改成 paused。 +- 一次下載會觸發兩次同步的 `File.existsSync`/非同步檢查以外,還有一次完整的 VideoDetail API 請求(`download_service.dart:1017`)。批次下載 N 首就是 N 次詳情請求,沒有節流(**推測**:B 站匿名下可能撞 -352,見 `errors.md` §3.1;失敗只影響 metadata 擴充欄位)。 diff --git a/docs/audit/engineering.md b/docs/audit/engineering.md new file mode 100644 index 000000000..4608064a0 --- /dev/null +++ b/docs/audit/engineering.md @@ -0,0 +1,627 @@ +# FMP 工程面現況審計 + +> 現況描述,未經確認,不代表目標。 + +- 審計時間:2026-09-26;分支 `docs/audit`,HEAD `6d78fe23`(`git log -1`)。 +- 本機環境:Windows 11、Flutter 3.47.1 stable(與 CI 釘的版本相同,`.github/workflows/ci.yml:28`)。 +- 規模:`lib/` 手寫 Dart 343 檔 99,063 行(另有生成碼 `*.g.dart` 46,089 行);`test/` 261 檔 63,927 行;`tool/` 7 檔 2,373 行。`lib/` 各層:`ui` 38,959、`services` 33,042、`data` 15,054、`providers` 7,640、`core` 3,755 行。最大單檔 `lib/services/audio/audio_provider.dart` 2,953 行。 +- commit 總數 1,877(`git rev-list --count HEAD`)。 +- 證據標示:`檔案:行號`、命令輸出。「**不一致**」=兩處說法(或文件與程式碼)對不上;「**推測**」=沒有直接證據;「查不到」=找過,沒找到。 + +--- + +## 1. CI/發版 + +### 1.1 `ci.yml` + +| 項目 | 內容 | 證據 | +|---|---|---| +| 觸發 | PR 到 `main`、push 到 `main`、手動 `workflow_dispatch`。沒有路徑過濾(註解說明是刻意的:純文字 commit 也要跑 `validate`)。 | `ci.yml:3-15` | +| 權限 | `contents: read` | `ci.yml:17-18` | +| 併發 | PR 以 ref 分組(新 push 取消舊 run),`main` 與手動以 SHA 分組 | `ci.yml:23-25` | +| Action 版本 | 全部以 commit SHA 釘住(checkout、flutter-action、setup-java、upload-artifact) | `ci.yml:40,48,98` | +| secrets | 無 | 全檔 | + +| job | runner | 做什麼 | 產物 | +|---|---|---|---| +| `validate`(Analyze and Test,15 分鐘上限) | ubuntu-latest | `fetch-depth: 0`(`pubspec_version_test` 要讀 tag)→ `flutter pub get` → `dart format --set-exit-if-changed lib test tool`(在 codegen 之前)→ `build_runner build` → `slang` → `flutter analyze` → `flutter test --coverage --exclude-tags live` | `coverage-lcov`(`coverage/lcov.info`,保留 14 天) | +| `build-android`(needs validate) | ubuntu-latest | Java 17 → codegen → `flutter build apk --release --target-platform android-arm64` | 無上傳(只是建置冒煙);沒有 `key.properties` 時 gradle 退回 debug 簽名(`android/app/build.gradle.kts:47-50`) | +| `build-windows`(needs validate) | windows-2022 | codegen → `flutter build windows --release` | 無上傳 | + +`ci.yml:61-77`、`ci.yml:87-155`。 + +```mermaid +flowchart LR + T[PR / push main / 手動] --> V[validate
format → build_runner → slang
→ analyze → test --exclude-tags live] + V --> A[build-android
arm64 release APK 冒煙] + V --> W[build-windows
windows-2022 release 冒煙] + V -.-> C[(coverage-lcov
14 天)] +``` + +**CI 近況**(`gh run list`):HEAD `6d78fe23`(PR #172 的 merge commit)在 `main` 上的 CI **失敗**:`test/data/repositories/account_repository_test.dart` 的 `watchByPlatform emits the current row and then every change` 期望 `null` 拿到 `'first'`(run 36239727409,`1847 tests passed, 1 failed, 1 skipped`)。同一個 PR 分支的 CI 是綠的,本機全量也通過(見 §2.3),屬時序相依的 flaky 測試,見 §12。 + +### 1.2 `release.yml` + +| 項目 | 內容 | 證據 | +|---|---|---| +| 觸發 | push `v*` tag;或手動輸入一個已存在的 `vX.Y.Z` tag | `release.yml:3-12` | +| 權限 | workflow 預設 `contents: read`;只有 `release` job 拿 `contents: write` | `release.yml:14-15,425-426` | +| 併發 | 同 ref 排隊、不取消 | `release.yml:17-19` | +| secrets | `KEYSTORE_BASE64`、`KEYSTORE_PASSWORD`、`KEY_PASSWORD`、`KEY_ALIAS`(`build-android` 解出 `android/release.keystore` 與 `android/key.properties`,缺任一個就 `exit 1`);`GITHUB_TOKEN`(`release` job 建 Release) | `release.yml:117-141,520` | + +| job | needs | 做什麼 | 產物 | +|---|---|---|---| +| `prepare` | — | 檢查 tag 格式 `^v\d+\.\d+\.\d+$` 且存在;算 `version_code = major*1000000 + minor*1000 + patch` | outputs:tag、version、version_code、version_with_code | +| `validate` | prepare | checkout tag → codegen → `flutter analyze` → `flutter test --exclude-tags live`。**沒有** `dart format` 檢查,也沒有 `--coverage`(與 ci.yml 不同) | 無 | +| `build-android`(matrix 4 格) | prepare, validate | 用 sed 把 `pubspec.yaml` 的 `version:` 改成 tag 版本 → 解 keystore → codegen → `flutter build apk --release [--target-platform]` → 改名 `fmp--android-.apk`;arm64-v8a 與 universal 另複製 `fmp-latest-android-.apk` | `android-apk-`(30 天) | +| `build-windows` | prepare, validate | pwsh 改寫版本 → codegen → `flutter build windows --release` → 把 `LICENSE`、`THIRD_PARTY_LICENSES.md`、`licenses/` 放到 exe 旁 → 壓 `fmp--windows.zip` 與 `fmp-latest-windows.zip` → choco 裝 Inno Setup → `inno_bundle:build` 產 ISS → regex 改寫 ISS(刪 icelandic、加 `DefaultGroupName`、`AppUserModelID`、移除 `skipifsilent`)→ 驗證改寫生效(F8 gate)→ ISCC 編譯 → `fmp--windows-installer.exe` + `fmp-latest-windows-installer.exe` | `windows-exe`、`windows-installer`(30 天) | +| `verify` | prepare, build-android, build-windows | checkout **workflow 的 ref**(刻意不 checkout tag,註解 `release.yml:368`)→ 下載全部 artifact 合併 → 產生 `fmp--checksums.sha256`(只含版本化檔)→ `AAPT2=… dart run tool/release/verify_release_assets.dart` | `release-assets`(30 天) | +| `release` | prepare, verify | 下載 `release-assets` → 找前一個 tag → 從 commit 範圍依 Conventional Commits 前綴(feat/fix/perf/deps)產 release body → `softprops/action-gh-release` 以 `draft: false` 直接發布 | GitHub Release(11 個 asset) | + +`release.yml:27-520`。 + +```mermaid +flowchart TD + TAG[push tag v*
或手動指定 tag] --> P[prepare
tag 格式 / 存在
算 version_code] + P --> V[validate
analyze + test --exclude-tags live] + P --> BA + P --> BW + V --> BA[build-android ×4
arm64-v8a / armeabi-v7a / x86_64 / universal
secrets: KEYSTORE_*、KEY_*] + V --> BW[build-windows
ZIP + Inno Setup 安裝檔
ISS patch + F8 驗證] + BA --> VR[verify
產生 checksums.sha256
verify_release_assets.dart] + BW --> VR + VR --> R[release
自動產 body
draft: false 直接發布
GITHUB_TOKEN] + R --> GH[(GitHub Release
11 個 asset)] +``` + +Release 最近五次(`gh run list --workflow release.yml`):v1.11.0 成功、v1.10.2 一次失敗後重跑成功、v1.10.1、v1.10.0 成功。 + +### 1.3 `tool/release/verify_release_assets.dart` + +唯一的 release 工具(211 行)。`verify` job 呼叫它(`release.yml:401-409`)。檢查: + +1. 檔案集合必須**剛好**等於 `expectedAssets(tag)`:6 個版本化檔(4 APK、zip、installer)+ 4 個 `fmp-latest-*` 別名 + checksums,共 11 個;缺一個或多一個都報錯(`verify_release_assets.dart:18-41,56-65`)。 +2. checksums manifest 每行格式、涵蓋全部 6 個版本化檔、不含別名、hash 相符(`:75-104`)。 +3. 每個 `fmp-latest-*` 與同後綴版本化檔逐位元相同(`:109-119`;理由是 App 內更新可能下載別名、卻用版本化檔名查 hash)。 +4. 以 `aapt2 dump badging` 讀每個 APK 的 versionName/versionCode 對 tag(`:122-141,168-176,195-199`)。 +5. Windows 安裝檔的 `MZ` + `PE\0\0` 簽章(`:143-165`;截斷的檔案擋不下,註解自承)。 + +由 `test/workflows/release_assets_verification_test.dart` 以假產物測每一項會紅(該檔 13 個 `test(` 呼叫點,其中一個在迴圈裡展開成 3 個,執行時 15 個)(核查更正:原寫「該檔 12 個 test」)。 + +### 1.4 自動更新:新版怎麼到使用者手上 + +**入口只有手動**:設定 → 關於 → 檢查更新(`lib/ui/pages/settings/widgets/settings_about.dart:70`)。App 啟動時不檢查,只在 Windows 上清理上一次更新的殘留檔(`lib/main.dart:231` → `UpdateService.cleanupOldWindowsUpdateFiles`,`update_service.dart:259-292`)。`docs/build-and-release.md:327-329` 的說法與程式碼一致。 + +```mermaid +sequenceDiagram + autonumber + participant U as 使用者 + participant UI as settings_about / UpdateDialog + participant N as UpdateNotifier
(update_provider.dart) + participant S as UpdateService
(update_service.dart) + participant GH as api.github.com / Release CDN + participant OS as 系統安裝器 / updater 腳本 + + U->>UI: 點「檢查更新」 + UI->>N: checkForUpdate() + N->>S: checkForUpdate() + S->>GH: GET /repos/1morr/FMP/releases/latest + GH-->>S: tag_name、body、assets + S->>S: _isNewerVersion(PackageInfo.version, tag)
依檔名分類 APK(ABI)/zip/installer/checksums + S->>GH: 下載 fmp--checksums.sha256 + S-->>N: UpdateInfo(releaseNotes = body) + N-->>UI: updateAvailable → UpdateDialog + U->>UI: 立即更新 + UI->>N: downloadAndInstall() + N->>S: getExistingDownloadPath(僅 Android,重驗 hash) + N->>S: downloadAndInstall(info) + S->>GH: 下載到 <檔名>.part + S->>S: 驗 size + SHA-256 → rename + alt Android + N->>S: canRequestPackageInstalls()?否 → 引導開設定 + N->>S: installApk → OpenFilex 開系統安裝器 + S->>OS: APK 安裝(系統驗簽) + else Windows 安裝版(有 unins000.exe) + S->>OS: installer /SILENT /DIR= /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS + S->>S: exit(0) + else Windows 免安裝版 + S->>S: isolate 串流解壓到 temp/fmp_update + S->>OS: wscript 啟動 .vbs → .bat:等 PID 結束 → robocopy 備份 → 覆蓋 → 失敗回滾 → 重啟 + S->>S: exit(0) + end +``` + +證據: + +- 查詢:`update_service.dart:389-420`(`releases/latest`、版本比較 `:689-708` 只比三段數字);release body 成為對話框內容 `:472,483`。 +- 資產分類:`abiPattern = fmp-.+-android-(.+)\.apk$`,別名與版本化檔落在同一格,誰排在 assets 清單後面誰贏(`:432-465`)。安裝版判定=exe 旁有 `unins000.exe`(`:54-57`)。Android ABI 由 `getprop ro.product.cpu.abi` 取得,找不到對應 ABI 退回 `universal`(`:64-68,155-171`)。 +- 完整性:有 manifest 時缺 hash 直接拋 `UpdateIntegrityException`;沒有 manifest(舊 release)只驗 size(`:777-782`)。下載先寫 `.part`,驗完才 rename(`:714-753`);驗證 `:800-828`。 +- Android 安裝權限:`update_provider.dart:183-193`;`installApk` `update_service.dart:248-254`。 +- Windows:installer 參數 `:613-618`;portable 的 `.bat` 內容 `:830-878`(`robocopy /MIR` 備份、`if errorlevel 8 goto rollback`);解壓走 isolate 串流 `:656,880`。 +- 信任鏈觀察:SHA-256 manifest 與產物來自同一個 GitHub Release,擋得住傳輸損毀,擋不住 Release 本身被替換;Windows 產物沒有 code signing(`release.yml` 無 `signtool`,grep 無結果);Android 由系統以同一把 keystore 驗簽。Release 發布前沒有人工閘門(ADR 0006)。 + +--- + +## 2. 測試盤點 + +### 2.1 按目錄統計 + +腳本:以正則 `(?` | 無 | 是(XML 屬性值) | 翻轉、刪除、註解、順序 | +| `support/audio_provider_size_…` | `audio_provider.dart` 程式碼行 ≤ 2,184(slack 50) | 無 | 否(行數) | 超過/縮太多、註解不計 | +| `support/call_site_ownership_…` | 直播 API、UI 用 source manager、UI 直接叫 source、自訂標題列、歌單失效,各自只准指定檔案 | 擁有權表 5 列 | 否(集合相等) | 越界、斷行、註解 | +| `support/layer_boundary_…` | `lib/core`、`lib/data` 不 import 上層;feature 間新 import 邊要登記 | 下層例外 1、已知 feature 邊 33 | 否(import 圖) | 違規、引號、同 feature | +| `support/live_source_tag_…` | 以預設建構子建真音源的測試檔要標 `live` | 守的類別 9、例外檔 6 | 部分(檔案層級,見 §3) | 每個類別合成違規、注入不算 | +| `support/outbound_hosts_…` | `lib/` 寫死的主機都要登記用途;DNS lookup 目標登記 | 主機 23、DNS 1 | 否(集合相等) | 新主機、改名重排 | +| `support/periodic_timer_…` | 每個 `Timer.periodic`/`Stream.periodic` 登記需求來源與可否關閉 | 9 檔 | 否(每檔計次) | 未登記、改名重排 | +| `support/source_branch_points_…` | `lib/data/sources/` 外依音源 id 分支的預算(只准減少) | 5 檔 | 否(計次等號) | 比較、switch、查表不算 | +| `support/source_http_policy_…` | 音源客戶端都走 `SourceHttpPolicy`;header 字面值只准指定檔 | 工廠檔 2、header 擁有者 10 | 否 | 合成違規、錯音源、斷行 | +| `support/static_rule_placement_…` | 讀 `lib/` 原始碼的測試必須叫 `*_static_rule_test.dart` 並放在 `test/support/` 或 `test/<層>/static_rules/` | 宣稱無例外 | 否 | 合成違規、temp 路徑、i18n JSON 不算 | +| `support/wait_convention_…` | 只有 3 個檔可直接呼叫 `pumpEventQueue` | 3 | 是(識別符出現) | 空格、tear-off、註解 | +| `ui/static_rules/error_presentation_…` | async error 分支不渲染空白;i18n 錯誤模板不填 raw exception;raw exception 不進使用者 widget | 無 | 否(樣式集合) | 合成違規、註解 | +| `ui/static_rules/slider_overlay_…` | Slider 只經 `ScopedSlider` | 1(ScopedSlider 本身) | 否(集合) | 各種寫法、相似名 | +| `ui/static_rules/ui_consistency_…` | 低階圖片 API 只在 `lib/ui/widgets/images/` 的 5 個語意 widget;ListTile leading 不直接用 Row | 5 | 否 | 合成違規、註解 | +| `ui/static_rules/watch_scope_…` | 5 個寬 provider 禁止整包 `ref.watch` | 5(被守對象) | 否(集合) | 格式、select/notifier 不算 | +| `workflows/dependabot_group_…` | 0.x 直接依賴都被排除在 minor-and-patch 群組外;`flutter_secure_storage` major 被 ignore | 無(讀 `pubspec.yaml`、`.github/dependabot.yml`) | 否(自寫 YAML 解析) | 解析器邊界 | + +觀察: + +- 每一檔都有合成違規的 test,多數也有「無關改寫不紅」的 test(對應使用者全域規則的雙向變異驗證)。`core_source`、`ui_consistency`、`error_presentation` 只測了「註解不算」,沒有測改名/斷行。 +- `wait_convention` 只擋直接呼叫 `pumpEventQueue`;`Future.delayed` 固定等待不在範圍(`.trellis/spec/testing/index.md` 自承),CI 失敗的 `account_repository_test` 正是 `Future.delayed(200ms)`。 + +--- + +## 6. 依賴健康度 + +### 6.1 `dart pub outdated`(2026-09-26) + +- 直接依賴 40 個(另 `flutter`、`flutter_localizations` SDK),dev 依賴 8 個(另 `flutter_test`)。 +- **沒有** `dependency_overrides`、**沒有** git 依賴、**沒有** path 依賴(`pubspec.yaml` 全檔)。`intl: any`(`pubspec.yaml:83`,註解說交給 `flutter_localizations` 決定)。 +- 摘要:61 個依賴被 lock 在較舊版本(可 `pub upgrade`);3 個被 pubspec 約束擋住更新到可解析版本。 + +| 直接依賴落後 | 現用 | 可升(相容) | 可解析 | 最新 | 備註 | +|---|---|---|---|---|---| +| archive | 4.2.0 | 4.3.0 | 4.3.0 | 4.3.0 | | +| audio_service | 0.18.18 | 0.18.19 | 同 | 同 | | +| cached_network_image | 4.0.0 | 4.0.2 | 同 | 同 | | +| equatable | 2.1.0 | — | 3.0.0 | 3.0.0 | major | +| file_picker | 11.0.3 | — | — | 13.1.0 | 解析不到 | +| flutter_cache_manager | 3.4.2 | 3.4.5 | 同 | 同 | | +| flutter_secure_storage | 10.3.1 | 10.3.4 | 10.3.4 | 11.2.0 | 刻意停在 10.x(`pubspec.yaml:68-73`、dependabot ignore) | +| package_info_plus | 9.0.1 | — | — | 10.2.1 | 解析不到 | +| pointycastle | 3.9.1 | — | — | 4.0.0 | 解析不到 | +| tray_manager | 0.5.3 | — | 0.7.0 | 0.7.0 | 0.x 約束擋住 | +| window_manager | 0.4.3 | — | 0.5.2 | 0.5.2 | 0.x 約束擋住 | +| build_runner(dev) | 2.15.1 | — | — | 2.16.1 | 解析不到 | + +### 6.2 棄用、fork、長期未發版 + +- **discontinued**:只有遞移依賴 `js 0.6.7`(被 `isar_community`、`audio_service`、`pointycastle` 依賴,`dart pub deps`)。直接依賴沒有 discontinued(pub.dev API 逐一查 `isDiscontinued`)。 +- **社群 fork**:`isar_community` 3.3.2/`isar_community_flutter_libs` 3.3.2/`isar_community_generator` 3.3.2(fork 最近發版 2026-03-23)。上游 `isar` 在 pub.dev 最後發版是 4.0.0-dev.14(2023-08-21),穩定版 3.1.0+1(2023-04-25);上游 `isar_generator` 3.1.0+1 要求 `analyzer >=4.6.0 <6.0.0`。 +- **pub.dev 最新版發布已超過兩年**(以 2026-09 計):`encrypt`(2023-09-18)、`scrollable_positioned_list`(2023-05-08)、`qr_flutter`(2023-05-14)、`reorderable_grid_view`(2023-11-20)、`media_kit_libs_windows_audio`(2023-09-27)。一年以上:`hotkey_manager`(2024-05)、`rxdart`(2024-06)、`flutter_inappwebview`(2024-10)。`media_kit` 1.2.6 為 2025-12-13。 +- `THIRD_PARTY_LICENSES.md` 與 ADR 0003 記錄 Windows `libmpv-2.dll` 是 2023-09-24 的凍結快照(未獨立驗證 DLL 內容)。 +- `docs/build-and-release.md:317` 記錄 `flutter_inappwebview_windows 0.6.0` 在 VS 2026 無法建置,所以 Windows runner 釘 `windows-2022`(`ci.yml:127`、`release.yml:219`)。 + +### 6.3 codegen + +| 工具 | 產物 | 何時跑 | +|---|---|---| +| `build_runner` 2.15.1 + `isar_community_generator` 3.3.2 | 11 個 model 的 `part '*.g.dart'`(`lib/data/models/`,`@collection` 11 個) | CI 每個 job、`orca.yaml` setup、AGENTS.md 要求 pull/切分支後手動跑 | +| `slang` 4.19.2(獨立 CLI,設定在 `slang.yaml`,`lazy: false`) | `lib/i18n/strings*.g.dart` | 同上 | + +沒有 `build.yaml`;沒有 riverpod_generator、freezed、json_serializable(`pubspec.yaml`、`git grep "@riverpod"` 皆無;`.trellis/spec/ui/index.md` 寫明「written by hand (no codegen, no freezed, no hooks)」)。`*.g.dart` 被 gitignore(`.gitignore:29`)。本機 build_runner + slang 共 2 分 28 秒。生成碼 46,089 行。 + +--- + +## 7. tool/、死代碼、重複邏輯 + +### 7.1 `tool/` 腳本 + +| 檔案 | 用途 | 狀態 | +|---|---|---| +| `tool/release/verify_release_assets.dart` | Release 產物檢查(§1.3) | CI 執行、有測試 | +| `tool/demo/bilibili_info_demo.dart` | 打 Bilibili 影片資訊 API | 手動;2026-09-10 建立後未改 | +| `tool/demo/bilibili_live_api_demo.dart` | 比較不同直播 API 取觀眾數 | 同上 | +| `tool/demo/bilibili_live_api_lookup_demo.dart` | 直播間 API 查詢(用 `package:http`,`pubspec.yaml:103-105`) | 同上 | +| `tool/demo/lyrics_matching_demo.dart` | 標題解析+lrclib 匹配可行性 | 同上;**自帶一份 `RegexTitleParser`**(`:31`),不 import `lib/services/lyrics/title_parser.dart:43` | +| `tool/demo/netease_lyrics_demo.dart` | 網易歌詞 API | 同上 | +| `tool/demo/qq_music_lyrics_demo.dart` | QQ 音樂歌詞 API | 同上 | + +6 支 demo 都不 import `package:fmp`,自己重寫 API 呼叫。 + +### 7.2 死代碼 + +方法(scratchpad `dead.py`、`dead2.py`): + +1. 檔案層級:從 `lib/main.dart` 沿 `import`/`export`/`part` 做可達性。**343 個手寫檔全部可達**,沒有孤兒檔案。 +2. 成員層級:抓頂層 class/函式/變數、2 空白縮排的 public 方法與 getter(排除 `@override`、`build` 等),計算名稱在整個 `lib/`(去註解)出現次數;只出現 1 次(宣告本身)即列為候選,再數在 `test/`、`tool/` 的出現次數。同名成員會互相遮蔽(漏報),extension 會誤報(已人工剔除)。 + +結果:136 個候選;其中 84 個在 `test/`、`tool/` 也沒有引用,52 個只被測試引用(多數是刻意的 `*ForTesting` 掛鉤)。前 30 個(**候選,需人工確認**;已用 `git grep -nw` 抽驗前 13 個,確實只有宣告一處): + +| # | 位置 | 名稱 | +|---:|---|---| +| 1 | `lib/services/audio/audio_provider.dart:859` | `playPlaylist` | +| 2 | `lib/services/audio/audio_provider.dart:863` | `restoreMediaControlOwnership`(`git grep -nw` 另命中 `now_playing_publisher.dart:82` 的註解,描述電台過去的呼叫方式,不是呼叫點)(核查補註) | +| 3 | `lib/services/search/search_service.dart:165` | `searchMixed` | +| 4 | `lib/services/search/search_service.dart:214` | `getSearchSuggestions` | +| 5 | `lib/services/import/import_service.dart:544` | `autoRefreshAll` | +| 6 | `lib/services/library/auto_refresh_service.dart:130` | `checkNow` | +| 7 | `lib/data/repositories/queue_repository.dart:78` | `insertTrack` | +| 8 | `lib/data/repositories/queue_repository.dart:131` | `moveTrack` | +| 9 | `lib/data/repositories/queue_repository.dart:170` | `updateCurrentIndex` | +| 10 | `lib/data/repositories/queue_repository.dart:187` | `updateShuffleEnabled` | +| 11 | `lib/data/repositories/queue_repository.dart:194` | `updateLoopMode` | +| 12 | `lib/data/repositories/queue_repository.dart:229` | `unshuffle` | +| 13 | `lib/data/repositories/download_repository.dart:25` | `getTaskByTrackId` | +| 14 | `lib/data/repositories/download_repository.dart:30` | `getTaskByTrackIdAndPlaylist` | +| 15 | `lib/data/repositories/download_repository.dart:43` | `getTaskBySavePath` | +| 16 | `lib/data/repositories/download_repository.dart:108` | `getPendingTasks` | +| 17 | `lib/data/repositories/download_repository.dart:119` | `getDownloadingTasks` | +| 18 | `lib/data/repositories/download_repository.dart:152` | `deleteTasks` | +| 19 | `lib/data/repositories/download_repository.dart:157` | `deleteCompletedTasks` | +| 20 | `lib/data/repositories/download_repository.dart:222` | `updateTasksStatus` | +| 21 | `lib/data/repositories/play_history_repository.dart:92` | `getRecentHistory` | +| 22 | `lib/data/repositories/play_history_repository.dart:175` | `getHistoryByDateRange` | +| 23 | `lib/data/repositories/play_history_repository.dart:193` | `getHistoryBySource` | +| 24 | `lib/data/repositories/play_history_repository.dart:408` | `getHistoryGroupedByDate` | +| 25 | `lib/data/repositories/track_repository.dart:212` | `getDownloaded` | +| 26 | `lib/data/repositories/track_repository.dart:221` | `watchDownloaded` | +| 27 | `lib/data/repositories/track_repository.dart:325` | `markUnavailable` | +| 28 | `lib/data/repositories/track_repository.dart:335` | `updateAudioUrl` | +| 29 | `lib/providers/account/account_provider.dart:43,68,116` | `isBilibiliLoggedInProvider`/`isYouTubeLoggedInProvider`/`isNeteaseLoggedInProvider` | +| 30 | `lib/services/lyrics/netease_source.dart:247` | `searchAndGetLyrics` | + +其餘無引用候選還包括:`radio_refresh_service.dart:260,276,282`(`refreshStation`/`addStationStatus`/`removeStation`)、`radio_controller.dart:780` `updateStation`、`windows_desktop_service.dart:365` `unregisterHotkeys`、`bilibili_favorites_service.dart:187` `batchRemoveFromFolder`、`queue_manager.dart:84,641` `setShuffleState`/`restoreOrder`、`download_path_sync_service.dart:313` `cleanupInvalidPaths`、`lrclib_source.dart:101` `getExact`、`theme_provider.dart:103` `toggleThemeMode`、`search_provider.dart:565` `setLiveRoomFilter`、`video_detail.dart:246-255` 三個 `formatted*Count` getter、`lyrics_cache_service.dart:365-380` 三個 getter(`fileUsagePercent`、`sizeUsagePercent` 兩個使用率,加上 `formattedMaxSize`)(核查更正:原寫「三個使用率 getter」)。 + +只被測試引用的例子:`play_history_repository.dart:55,244`(`getPlayCount`、`getPlayCountByKey`,各 7 處測試引用)、`bilibili_source.dart:1048` `getLiveRoomInfo`、`source_provider.dart:40,45`(`trackInfoSource`、`playlistParsingSource`)。 + +`flutter analyze` 無任何 issue(§2.3):analyzer 不回報未使用的 public 成員,所以上面這些不會出現在 CI。 + +### 7.3 重複邏輯(最明顯的幾組) + +1. **位元組格式化 6 份,輸出各不相同** + - `lib/data/database/database_catalog.dart:751`(B/KB/MB/GB,GB 兩位小數) + - `lib/ui/pages/settings/developer_options_page.dart:146` `_formatSize`(到 MB)與同檔 `:257` `_formatBytes`(到 GB)——同一檔兩份 + - `lib/ui/pages/settings/download_manager_page.dart:463`(到 MB) + - `lib/ui/widgets/dialogs/update_dialog.dart:373`(KB 取整數) + - `lib/ui/pages/settings/widgets/settings_cache.dart:54`(輸入是 `double mb`) +2. **InnerTube 文字抽取兩份,行為不同**:`lib/core/utils/innertube_utils.dart:23` `InnerTubeUtils.extractText`(`simpleText` 為空字串也回傳、runs 不 trim);`lib/data/sources/youtube_source.dart:1229` 私有 `_extractText`(空 `simpleText` 跳過、runs 會 trim、空結果回 null)。`youtube_account_service.dart:497`、`youtube_playlist_service.dart:558` 轉呼叫前者。同一份 YouTube 回應在搜尋與帳號頁可能抽出不同字串(**推測**,未實測)。 +3. **三個登入頁的 `_cleanupWebView`**:`bilibili_login_page.dart:106`、`netease_login_page.dart:106`、`youtube_login_page.dart:35`,結構相同只差網域。 +4. **短網址解析三份**:`netease_source.dart:755`、`qq_music_playlist_source.dart:112`、`spotify_playlist_source.dart:83` 的 `_resolveShortUrl`,都包 `SourceUrlPolicy.resolveRedirects`,差在 host 清單與 HEAD 重試。 +5. **`_formatDateTime` 三份**:`database_catalog.dart:760`、`create_playlist_dialog.dart:350`、`settings_backup.dart:295`。 +6. **Release 資產命名在三處各寫一次**:`release.yml:160-171,275-280,344-350`、`tool/release/verify_release_assets.dart:18-41`、`lib/services/update/update_service.dart:93-103,432-465`。verify job 會擋 workflow 與工具的漂移;App 端的解析沒有被任何測試對著工具的清單比對(查不到)。 +7. **`tool/demo/lyrics_matching_demo.dart:31` 的 `RegexTitleParser`** 是 `lib/services/lyrics/title_parser.dart:43` 的平行副本。 + +--- + +## 8. AI 指令檔 + +### 8.1 內容摘要 + +| 檔案/目錄 | git 追蹤 | 內容 | +|---|---|---| +| `AGENTS.md`(134 行) | 是 | 專案簡介;Agent skills(指向 `docs/agents/`);Verification 表(6 列);codegen 提醒;on-device 強制;註解用繁中;問先再改的範圍;Boundaries(無測試守的 4 條、有 static-rule 守的 6 條);Trellis 段;最後是 Trellis 自動管理區塊 | +| `CONTEXT.md`(53 行) | 是 | 5 個認證/媒體交接術語(§11) | +| `docs/agents/`(3 檔) | 是 | mattpocock skills 的設定產物(§9) | +| `.claude/settings.json` | 是 | 3 組 hook:SessionStart(startup/clear/compact)跑 `session-start.py`;PreToolUse `Task`/`Agent` 跑 `inject-subagent-context.py`;UserPromptSubmit 跑 `inject-workflow-state.py` | +| `.claude/hooks/`(3 支 Python,949+1,216+488 行) | 是 | Trellis 生成:注入 session context、子代理 context(jsonl)、每輪 workflow-state breadcrumb | +| `.claude/agents/`(trellis-check/implement/research) | 是 | Trellis 子代理;check 與 implement 已客製成跑 AGENTS.md § Verification(`trellis-check.md:86`、`trellis-implement.md:82`) | +| `.claude/commands/trellis/`(continue、finish-work) | 是 | Trellis 指令 | +| `.claude/skills/`(9 個 trellis-* + `verify-on-device`)(核查更正:原寫「10 個 trellis-*」;`git ls-files .claude/skills` 共 10 個目錄,含 verify-on-device) | 是 | Trellis 內建 skill;`verify-on-device`(149 行+3 份 reference+3 支 script)是唯一專案自有 skill | +| `.agents/skills/verify-on-device/` | **否**(`.gitignore:95` `/.agents/`) | 本機殘留的舊版 `SKILL.md`(399 行,2026-09-10),與追蹤中的 `.claude` 版(149 行)內容不同;`smtc_probe.ps1` 相同、`ax_flatten.py` 在工作區逐位元相同(`cmp` 無差異;兩份都是 CRLF,與 git blob 的 LF 差別來自 autocrlf)(核查更正:原寫「`ax_flatten.py` 只差行尾」) | +| `.trellis/workflow.md`(721 行) | 是 | Trellis 三階段流程(Plan/Execute/Finish)、task/spec/workspace 系統、commit 流程 | +| `.trellis/spec/`(6 層 20 檔 1,424 行) | 是 | data、services、ui、shared、testing、guides 各有 `index.md`(Guidelines 表、Pre-Development Checklist、Quality Check);規則回指 AGENTS.md | +| `.trellis/agents/`(check.md、implement.md) | 是 | Trellis 通用版子代理定義(未客製) | +| `.trellis/config.yaml` | 是 | `session_auto_commit: false`、`max_journal_lines: 2000`、channel worker 上限 6 | +| `orca.yaml` | 是 | Orca worktree:共用 `.trellis/workspace`;`setupAgentStartupPolicy: wait-for-setup`;setup 跑 `pub get`、`build_runner`、`slang` | + +### 8.2 重複與衝突 + +| 主題 | 出現位置 | 是否一致 | +|---|---|---| +| 驗證要跑哪些測試 | AGENTS.md § Verification;`.claude/agents/trellis-check.md:86`、`trellis-implement.md:82`;各 `.trellis/spec/*/index.md` Quality Check | 一致(後者都回指 AGENTS.md) | +| codegen 先跑 | AGENTS.md;`verify-on-device/SKILL.md` §2;`orca.yaml` setup;`.trellis/spec/data/index.md` | 一致 | +| on-device 驗證強制 | AGENTS.md;`verify-on-device/SKILL.md`;`spec/ui/index.md`、`spec/services/index.md`;`trellis-check.md:90`(子代理不能跑、須回報) | 一致 | +| 等待慣例的閘門範圍 | AGENTS.md「Test waits … a fixed pump count is flaky in both directions — `wait_convention_static_rule_test.dart`」 vs `.trellis/spec/testing/index.md`「Only a direct `pumpEventQueue` is gated; fixed runs of `Future.delayed(Duration.zero)` still appear」 | **不一致**:AGENTS.md 讀起來像整條慣例都有閘門,實際只擋 `pumpEventQueue`(§5) | +| live 測試排除 | `dart_test.yaml`、`ci.yml:73-77`、`release.yml:212-214`、AGENTS.md、`test/live` 檔頭、`spec/testing/test-conventions.md:24-29` | 一致;但都沒說不加參數的本機 `flutter test` 會連網(§3) | +| check 子代理定義 | `.claude/agents/trellis-check.md`(客製)、`.trellis/agents/check.md`(通用)、`.claude/skills/trellis-check/SKILL.md` | 重複 3 份,內容不同步 | +| commit/journal 流程 | `.trellis/workflow.md:604,647`(work → archive → **journal commit** 三段)、`.claude/commands/trellis/finish-work.md:64-66`(「This produces a `chore: record journal` commit」) vs `.trellis/config.yaml` `session_auto_commit: false`、AGENTS.md Trellis 段「Journals stay local」、`.gitignore` `/.trellis/workspace/` | **不一致**:`add_session.py:1089-1091` 在關閉時跳過 commit(核查更正行號:原寫 `:279`,那是 worktree 警告函式的同一判斷);`git log --grep "record journal"` 0 筆 | +| push | `.trellis/workflow.md` 3.4「Never push to remote in this step」、「ask for one-shot confirmation」 vs 使用者全域 `~/.claude/CLAUDE.md`「我自己的 repo 直接做,不用問:push…」 | **不一致**(repo 層 vs 使用者層;repo 內無衝突) | +| 可重用 skill 的位置 | AGENTS.md Trellis 區塊「`.agents/skills/` — reusable Trellis skills;`.codex/agents/`」 vs 實際:`.agents/` 被 gitignore、只有一份過期的 verify-on-device;`.codex/` 不存在;Trellis skill 在 `.claude/skills/` | **不一致** | +| verify-on-device | `.claude/skills/verify-on-device/SKILL.md`(追蹤)vs `.agents/skills/verify-on-device/SKILL.md`(本機、較舊、較長) | **不一致**(兩份內容不同) | +| 文件語言 | `docs/README.md:21`(AGENTS.md、`docs/agents/`、`.trellis/spec/` 英文);`docs/agents/domain.md:48-50`(ADR 繁中);`issue-tracker.md` Language 段(issue 繁中) | 一致;與使用者全域「文檔偏好繁中,專案全英文時跟著走」相容 | +| 註解語言 | AGENTS.md Conventions;`spec/shared/index.md` | 一致 | +| Boundaries 無測試守的 4 條 | AGENTS.md | 程式碼現況符合:`audio_provider.dart` 宣告 provider 數 0;`Isar.open` 只在 `lib/data/database/database_provider.dart:92`;`lib/ui` 沒有引用 `FmpAudioService`/`audioServiceProvider`;`lib/services/search`、`lib/providers/search` 無 auth/設定過濾 | +| `.claude/` 追蹤範圍 | `docs/README.md:22` vs `.gitignore:82-90` | 一致(skills、agents、commands、hooks、settings.json 追蹤) | + +--- + +## 9. mattpocock skills 殘留 + +殘留檔案: + +- `docs/agents/domain.md`、`docs/agents/issue-tracker.md`、`docs/agents/triage-labels.md`:`docs/README.md:23` 說明是 `/setup-matt-pocock-skills` 的產出再加 FMP 修改。 +- `AGENTS.md:7-14`「Agent skills」段:指向上面三檔。 +- `CONTEXT.md`:domain-modeling skill 的慣例檔名(`docs/agents/domain.md:5-13`)。 + +內容上的模板殘留: + +- `domain.md:13` 提到 `/domain-modeling`「reached via `/grill-with-docs` and `/improve-codebase-architecture`」;本 session 可用的 mattpocock skills 清單中沒有這兩個名字(有 `grilling`、`codebase-design`、`domain-modeling`)。 +- `domain.md:47`(核查更正行號)的範例「_Contradicts ADR-0007 (event-sourced orders)_」;本 repo 的 ADR-0007 是「Isar 停在 v3」。 +- `issue-tracker.md:25`(`/triage` 讀的旗標)、`:52-60`(`/wayfinder` 的 `wayfinder:map` 標籤與 sub-issue 流程):`gh label list` 沒有任何 `wayfinder:*` 標籤。 +- `triage-labels.md`:5 個角色標籤在 repo 中都存在(`gh label list`);實際使用次數:`ready-for-agent` 10、`ready-for-human` 3、`needs-triage` 3、`needs-info` 0、`wontfix` 0(`gh issue list --state all`)。 + +`git grep` 引用位置(樣式:`docs/agents|CONTEXT\.md|mattpocock|/triage|wayfinder|grill-with-docs|domain-modeling|improve-codebase-architecture|ready-for-agent|ready-for-human|needs-triage|Agent skills`): + +| 位置 | 引用 | +|---|---| +| `AGENTS.md:7,10,12,13,14` | Agent skills 段 | +| `docs/README.md:21,23` | 語言分工、`docs/agents/` 來源 | +| `docs/agents/domain.md:5,9,13,19,30,39,41,52` | 自身 | +| `docs/agents/issue-tracker.md:25,52,54,55` | `/triage`、`/wayfinder` | +| `docs/agents/triage-labels.md:5,7,9,10` | 標籤表 | +| `.trellis/spec/data/index.md:9` | 指向 `CONTEXT.md` | +| `.trellis/spec/data/sources.md:81` | 同上 | +| `.trellis/spec/guides/cross-layer-thinking-guide.md:51` | 同上 | +| `.trellis/spec/services/download-and-auth.md:3,38` | 同上 | +| `.trellis/spec/services/index.md:8,24` | 同上 | + +非 archive 共 30 行/10 檔,與上表逐列相符(核查更正:原寫「33 行/10 檔」;33 是加 `-i` 不分大小寫的結果,會多出 `.gitignore:83` 與兩份 `trellis-meta` skill 檔,共 13 檔)。`.trellis/tasks/archive/` 另計:8 行/3 檔(`00-bootstrap-guidelines/research/core-data.md`、`…/services.md`、`09-26-align-specs-with-code/research/spec-audit.md`)。未追蹤的 `.trellis/tasks/09-26-audit/prd.md`、`09-26-fmp-rewrite/prd.md` 也有命中(本審計任務本身,不計入)。 + +--- + +## 10. ADR 逐份比對 + +### 0001 每源設定收成清單、音源改用字串 id — **部分不一致** + +決定:刪 `enum SourceType` 改 `SourceIds` 字串常數;六個每源欄位收成 `List`,舊欄位保留供 v1→v2 遷移讀。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| `enum SourceType` 已刪 | 符合 | `git grep "enum SourceType" -- lib` 無結果 | +| `SourceIds` 為 `static const String` + `values` + `displayNameFor` | 符合 | `lib/data/models/source_ids.dart:16-18,24,30` | +| `sourceSettings` 清單與 `streamPriorityFor`/`useAuthForPlay`;`_putEntry` 重建整份 list | 符合 | `lib/data/models/settings.dart:318,700-709,724` | +| 六個舊欄位保留並標 `@Deprecated` | 符合(6 處) | `settings.dart:321,327,333,414,420,426` | +| `deprecated_member_use_from_same_package` 已開 | 符合 | `analysis_options.yaml:42` | +| `_fetchPlaylists` 對未知 id 拋錯 | 符合 | `account_playlists_sheet.dart:174-177` | +| `setUseAuthForPlay` 對未知 id 拋錯 | **不一致**:`Settings.setUseAuthForPlay` 呼叫 `_entryFor`,未知 id 會建一筆預設 entry 寫入,不拋錯;`AudioSettingsNotifier.setAuthForPlay` 也不拋。拋錯的版本在 `8ffa7d4f`(2026-09-03)被移除 | `settings.dart:685-694,727-728`;`audio_settings_provider.dart:303-320`;`git show 8ffa7d4f` 中 `- throw ArgumentError.value(` | +| 19 個 switch 的未知 id 行為表 | 未逐列驗證 | — | + +### 0002 Isar 只出現在 repository 層 — **一致** + +決定:`isar.`/`_isar.` 只准在 `lib/data/repositories/`,豁免 `database_migration.dart`、`database_catalog.dart`,以 static rule 守。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| 規則與 allowlist | 符合 | `isar_boundary_static_rule_test.dart:20-22`;全量測試通過 | +| 豁免檔的呼叫點數(ADR 寫 11/8) | 現況約 12/10(粗略 grep,去 `//` 註解) | 數字漂移,不影響規則 | +| `BackupRepository.writeImport` 單筆交易 | 存在 | `lib/data/repositories/backup_repository.dart:110` | +| `InTxn` 後綴方法 | 存在 | `playlist_mutation_repository.dart:301,630,661`;`lyrics_repository.dart:72` | +| 不加 `abstract Repository` 介面 | 符合 | `git grep "abstract.*class.*Repository" -- lib` 無結果 | + +### 0003 保留兩個音訊後端 — **一致** + +決定:Android `JustAudioService`、Windows `MediaKitAudioService`,共同判斷抽成純規則並由 static rule 釘住轉呼叫。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| 依 `AudioRuntimePlatform` 選後端(android/ios → just_audio) | 符合 | `lib/providers/audio/audio_controller_provider.dart:26-31`;`lib/services/audio/audio_runtime_platform.dart:7-19` | +| 共用規則檔與契約測試 | 存在 | `playback_end_reason_rules.dart`、`live_edge_seek_policy.dart`、`next_media_plan.dart`;`test/services/audio/backend_contract_test.dart` | +| `classifyExoPlayerFailure`/`classifyMpvMessage` | 存在並被兩後端使用 | `playback_end_reason_rules.dart:41,84`;`just_audio_service.dart:334`;`media_kit_audio_service.dart:380` | +| Android 音訊焦點靠 `audio_session` | 符合 | `just_audio_service.dart:4,20,165` | +| `MediaKitAudioService` 可注入 `PlatformPlayer` | 符合 | `media_kit_audio_service.dart:39-43` | +| Linux/macOS 殘留分支 | 符合(`main.dart` 仍對它們呼叫 `MediaKit.ensureInitialized`;repo 無 `linux/`、`macos/`) | `lib/main.dart:202-204` | +| 小差異 | `audio_controller_provider.dart:25` 註解寫「Windows/Linux」 | — | + +### 0004 Android 下載用所有檔案存取權與裸路徑 — **一致** + +決定:知情接受 `MANAGE_EXTERNAL_STORAGE` + `dart:io` 路徑,不用 MediaStore/SAF(不上架商店)。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| manifest 權限與 `maxSdkVersion` 32/29、`tools:ignore="ScopedStorage"` | 符合 | `AndroidManifest.xml:16-23` | +| `targetSdk = flutter.targetSdkVersion` | 符合 | `android/app/build.gradle.kts:31` | +| 自有 MethodChannel,不用 permission_handler | 符合 | `storage_permission_service.dart:22-26`;`MainActivity.kt:64,86`;pubspec 無 permission_handler | +| `selectDirectory` 用 `FilePicker.getDirectoryPath`、寫 `.fmp_test`、`hasConfiguredPath` | 符合 | `download_path_manager.dart:25,34,44,61` | +| `getDefaultBaseDir` Android 回 `Music/FMP` | 符合 | `download_path_utils.dart:181-187` | +| `PathAccessException` → `t.error.noPermission` | 符合 | `lib/core/errors/user_message.dart:85` | + +### 0005 曲目識別鍵包含 cid — **一致** + +決定:`uniqueKey` 有 cid 時為三段式,鍵字串是持久化格式;cid 回填時同交易改掛歌詞匹配。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| `TrackKey.format`/`formatGroup` | 符合 | `lib/data/models/track_key.dart:19-23` | +| `sourcePageKey` 複合索引、`uniqueKey`、`groupKey` | 符合 | `track.dart:277-278,331,334` | +| 外鍵 unique index | 符合 | `lyrics_match.dart:14-15`;`lyrics_title_parse_cache.dart:9-10`;`play_history.dart:46-47` | +| `backfillCid` 同交易 relink;啟動時補救 | 符合 | `track_repository.dart:160-166`;`database_migration.dart:86-97`;`lyrics_repository.dart:72` | +| 解析時 `track.cid ??= streamResult.cid` 與 `_resolutionKey` | 符合 | `stream_resolution_service.dart:340,449,465` | +| `track_key_test.dart` 釘字面輸出 | 存在 | `test/data/models/track_key_test.dart` | + +### 0006 Release 驗過產物就直接發布 — **一致** + +決定:拿掉草稿,改由 `verify` job 檢查 4 項後 `draft: false` 發布。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| `verify` job 與 `release` needs verify、`draft: false` | 符合 | `release.yml:361-363,419-421,514` | +| 11 個 asset(ADR「決策」段仍寫 10 個,「實作」段更正為 11) | 工具清單 6+4+1=11 | `verify_release_assets.dart:18-41`;ADR 內部前後數字不同,由 ADR 自己的實作段說明 | +| 別名逐位元相同的額外檢查 | 符合 | `verify_release_assets.dart:109-119` | +| `release_workflow_test` 以 YAML 解析釘 job 關係 | 符合(另有字串比對段落,§2.2) | `release_workflow_test.dart:135-170` | +| `docs/build-and-release.md` 不再描述草稿 | 符合 | `docs/build-and-release.md:156` | +| README 的 arm64 連結指向 `fmp-latest-android-arm64-v8a.apk` | 符合 | `README.md:23`、`README.zh-Hant.md:21` | + +### 0007 Isar 停在 v3,改用 isar_community — **部分不一致** + +決定:保留 v3 磁碟格式,依賴換成 `isar_community`,不升 v4。 + +| 主張 | 現況 | 證據 | +|---|---|---| +| 依賴為 `isar_community` 3.x | 符合(3.3.2) | `pubspec.yaml:18-19,95`;`pubspec.lock` | +| analyzer 10.x、build 4.x、Riverpod 3 | 符合(analyzer 10.2.0、build 4.0.7、flutter_riverpod 3.4.3) | `dart pub outdated` | +| 11 個 collection | 符合 | `git grep "^@collection" -- lib/data/models` 共 11 | +| Windows 子視窗 plugin 標頭改到 `isar_community_flutter_libs` | 符合 | `windows/runner/flutter_window.cpp:8`;`windows/flutter/generated_plugins.cmake:10` | +| 上游 generator 限制 `analyzer <6.0.0` | 符合 | pub.dev `isar_generator` 3.1.0+1:`>=4.6.0 <6.0.0` | +| 「上游 `isar/isar` 自 2025-07 沒有再發版」 | **不一致**:pub.dev 上 `isar` 最後一次發版是 4.0.0-dev.14(2023-08-21),穩定版 3.1.0+1(2023-04-25)。ADR 可能指 GitHub repo 活動(**推測**) | pub.dev API `/api/packages/isar` | +| fork 的 Android library 16 KB 對齊 | 未驗證(查不到本審計可離線驗證的方式) | — | +| `test/manual/real_db_probe.dart` 存在 | 符合 | 檔案存在 | + +--- + +## 11. CONTEXT.md 逐條術語比對 + +| 術語 | 對應程式碼 | 結論 | +|---|---|---| +| **Source Auth Context** | `abstract interface class SourceAuthContext`(`lib/services/account/source_auth_context.dart:76`),由 `SourcePlaybackAuthContext`、`PlaybackMediaRequestContext`、`DownloadSourceAuthContext`、`PlaylistAuthContext` 等窄介面組成(`:39-70`);實作 `DefaultSourceAuthContext`;provider `lib/providers/account/source_auth_context_provider.dart:8` | 有對應 | +| **Media Handoff** | `MediaHandoff`/`DefaultMediaHandoff`(`lib/services/media/media_handoff.dart:33-62`),`preparePlayback` 與 `prepareDownloadHop`;下載 isolate 每一跳呼叫 `prepareDownloadHop` 並自己做 redirect scheme/私有 IP 檢查(`download_service.dart:1831-1885`) | 部分對應:CONTEXT 說 Media Handoff「包含 redirect checks」,實際 redirect 檢查寫在下載 isolate 迴圈,不在 `MediaHandoff` 裡;播放路徑的 `preparePlayback` 只回 headers,不做 redirect 檢查 | +| **Stream Resolution Auth** | 概念上是 `SourceAuthContext.authForPlay()` 回傳、交給音源 adapter 解析串流的 headers(`stream_resolution_service.dart:406`、`download_service.dart:979`);型別上只有 `MediaHandoffRequest.streamResolutionAuth` 欄位(`media_handoff.dart:9,21`) | 有對應;`streamResolutionAuth` 欄位在 `DefaultMediaHandoff._prepareHeaders`(`:54-61`)完全沒被讀,註解說保留是為了讓呼叫端共用請求物件(`:16-20`)。唯一讀它的是 `_PlaybackUrlResolverMediaHandoff.preparePlayback`(`source_auth_context.dart:215`,轉交給注入的 `PlaybackUrlResolver`),但只有建構時傳入 `playbackUrlResolver` 才會用到這個 adapter;生產路徑(`source_auth_context_provider.dart:10`、`download_service.dart:165`)都不傳,只有測試會傳,所以**生產路徑上**從未被讀取(核查更正:原寫「欄位存在但沒有被讀取」的意涵過寬,`git grep` 在 `lib/` 有一處讀取) | +| **Auth For Play** | `Settings.useAuthForPlay(sourceId)`(`settings.dart:724`);`SourceAuthContext.authForPlay` 在設定關閉時回 null(`source_auth_context.dart:133-136`);呼叫點:串流解析、曲目詳情(`track_detail_provider.dart:185`)、下載詳情(`download_service.dart:979`)、**首頁排行榜**(`ranking_cache_service.dart:269-272`)。歌單匯入/刷新走 `PlaylistAuthContext` 的 `useAuth`/`useAuthForRefresh`;`lib/services/search`、`lib/providers/search` 無任何 auth | 有對應;CONTEXT 沒有明列排行榜(只寫「auth-aware metadata/detail service paths」) | +| **Media Request Credentials** | 沒有型別;落在 `SourceHttpPolicy.mediaHeaders(String sourceType)`(`lib/data/sources/source_http_policy.dart:82`)只回 CDN 的 Origin/Referer 與 User-Agent;`DefaultMediaHandoff` 與 `_PlaybackUrlResolverMediaHandoff.preparePlayback` 都用它(`media_handoff.dart:55`、`source_auth_context.dart:219`)(核查更正:原寫「`SourceAuthContext.preparePlayback`」,`SourceAuthContext` 沒有這個成員) | 有對應(以「空集合」的形式存在),與 CONTEXT 所述一致 | + +--- + +## 12. 工程觀察 + +只描述現況。 + +1. **`main` 目前是紅的。** HEAD `6d78fe23` 的 CI 失敗在 `account_repository_test.dart:105-118`:先 `listen` 再立刻 `upsert` 兩次、以固定 `Future.delayed(200ms)` 等待,斷言第一個事件是空值。同一測試在 PR 分支與本機通過。`wait_convention` 閘門只擋 `pumpEventQueue`,擋不到這種寫法。 +2. **不加參數的 `flutter test` 會連三個音源的正式 API。** `dart_test.yaml` 只宣告 `live` tag,沒有預設 skip;4 個 live test 會跑。CI 與文件都以 `--exclude-tags live` 為準,沒有一處提醒本機裸跑的行為。 +3. **更新推送鏈沒有人工閘門,也沒有簽章。** tag push 之後依序 validate → build → verify → 直接發布,release body 自動產生並原樣成為 App 內更新對話框內容。App 端只在使用者手動檢查時拉 `releases/latest`;完整性檢查用的 SHA-256 manifest 與產物同在一個 Release;Windows 安裝檔與 zip 未做 code signing;Android 依系統驗簽。Release 的 `validate` 比 CI 少一步 `dart format`。 +4. **測試數量多、以行為測試為主,另有一層原始碼文字規則。** 1,849 個離線 test 本機全過(2 分 48 秒),`flutter analyze` 無 issue。25 支 static-rule(144 個 test)全以正則比對原始碼,多數比集合或計次、各自帶合成違規測試;其中 `audio_provider_size` 以行數設上限、`live_source_tag` 以檔案為判斷單位。部分行為測試大量依賴 `debug*ForTesting` 掛鉤(下載服務 44 處;連同其他 `debug*` 成員 75 處)(核查更正:原寫「45 處」),`release_workflow_test` 有一段是比對 shell 片段字串。 +5. **死代碼與重複集中在 repository 與 UI 小工具。** 343 個 lib 檔全部可從 `main.dart` 到達,但有 84 個 public 成員在 lib/test/tool 都找不到引用(queue、download、play history、track repository 的整批 CRUD,`playPlaylist`、`searchMixed`、三個 `is*LoggedInProvider` 等,候選需人工確認)。位元組格式化有 6 份且輸出不一,InnerTube 文字抽取有兩份且行為不同,`tool/demo` 6 支腳本都不引用 `lib/`、其中一支帶了 `RegexTitleParser` 的平行副本。 +6. **依賴面:無 git 依賴、無 override,但有一個社群 fork 與數個多年未發版的套件。** Isar 走 `isar_community`(上游 pub.dev 自 2023-08 無發版);`encrypt`、`scrollable_positioned_list`、`qr_flutter`、`reorderable_grid_view`、`media_kit_libs_windows_audio` 最新版都在 2023 年;遞移依賴 `js` 已 discontinued;`flutter_secure_storage` 刻意停在 10.x;`tray_manager`、`window_manager` 被 0.x 約束擋在舊版。 +7. **AI 指令檔層數多,有幾處彼此對不上。** 規則分散在 AGENTS.md、`.trellis/spec/`(20 檔)、`.trellis/workflow.md`(721 行)、`.claude/` 的 hooks/agents/skills、`docs/agents/`、`CONTEXT.md`、`orca.yaml`。不一致處:Trellis 文件描述 journal commit 但設定已關閉;AGENTS.md 指向不存在的 `.codex/` 與被 gitignore 的 `.agents/`(內含過期的 verify-on-device 副本);check 子代理定義三份;AGENTS.md 對等待慣例的閘門範圍說得比實際寬;`docs/agents/` 留有 mattpocock 模板內容(`/wayfinder` 標籤不存在、範例引用不相干的「ADR-0007 event-sourced orders」)。 +8. **文件與程式碼大致同步,但有少數陳舊敘述。** 7 份 ADR 中 5 份與程式碼一致;0001 的「`setUseAuthForPlay` 對未知 id 拋錯」已在 `8ffa7d4f` 被移除;0007 的上游發版時間與 pub.dev 紀錄不符。CONTEXT.md 5 個術語都能對到程式碼,其中 Media Handoff 的「redirect checks」實際寫在下載 isolate,`streamResolutionAuth` 欄位存在但生產路徑沒有讀取(只有測試注入 `playbackUrlResolver` 時的相容 adapter 會讀,`source_auth_context.dart:215`)(核查更正:原寫「欄位存在但沒有被讀取」)。 diff --git a/docs/audit/errors.md b/docs/audit/errors.md new file mode 100644 index 000000000..6bc5204dc --- /dev/null +++ b/docs/audit/errors.md @@ -0,0 +1,400 @@ +# 錯誤處理現況審計 + +> 現況描述,未經確認,不代表目標。 + +審計日期:2026-09-26,分支 `docs/audit`。方法:只讀原始碼與 grep,另以一支一次性 Python 腳本分類 catch 區塊(腳本不在 repo 內)。未執行 App、未跑測試、未打真實 API。 +標記:**不一致** = 文檔/註釋與程式碼對不上;**推測** = 由程式碼路徑推論、未實跑驗證;**查不到** = 找不到對應實作。 + +--- + +## 1. 例外型別與層級 + +### 1.1 類別圖 + +```mermaid +classDiagram + class Exception { + <> + } + class SourceApiException { + <> + +String code + +String message + +String sourceType + +SourceErrorKind kind + } + class SourceErrorKind { + <> + network + timeout + rateLimited + unavailable + permissionDenied + loginRequired + geoRestricted + vipRequired + unknown + +isRetryable() + +shouldSkipTrack() + +canFallbackToLowerAudioQuality() + } + Exception <|.. SourceApiException + SourceApiException --> SourceErrorKind + SourceApiException <|-- BilibiliApiException + SourceApiException <|-- NeteaseApiException + SourceApiException <|-- YouTubeApiException + class BilibiliApiException { + +int numericCode + } + class NeteaseApiException { + +int numericCode + } + class YouTubeApiException { + +String code + } + + Exception <|.. BilibiliFavoritesException + Exception <|.. YouTubePlaylistException + Exception <|.. NeteasePlaylistException + Exception <|.. NeteaseException_lyrics + Exception <|.. QQMusicException + Exception <|.. LrclibException + Exception <|.. ImportException + Exception <|.. ImportCancelledException + Exception <|.. SearchException + Exception <|.. PlaylistNameExistsException + Exception <|.. PlaylistNotFoundException + Exception <|.. PlaybackTimeoutException + Exception <|.. StreamOpenFailedException + Exception <|.. RetryScheduledException_private + Exception <|.. UnsupportedDownloadStreamException + Exception <|.. SecureStorageUnavailable + Exception <|.. UpdateAssetUnavailableException + Exception <|.. UpdateIntegrityException + + class PlaybackEndReason { + <> + } + PlaybackEndReason <|-- EndedNaturally + PlaybackEndReason <|-- EndedPrematurely + PlaybackEndReason <|-- TransportFailed + PlaybackEndReason <|-- OutputDeviceFailed + PlaybackEndReason <|-- MediaUnopenable + PlaybackEndReason <|-- DecoderFailed + PlaybackEndReason <|-- UnclassifiedFailure + note for PlaybackEndReason "不是例外,是後端播放器事件的型別化結果" +``` + +`NeteaseException_lyrics` 指 `lib/services/lyrics/netease_source.dart:110` 的 `NeteaseException`,與資料層的 `NeteaseApiException` 無關。`RetryScheduledException_private` 指 `lib/services/audio/audio_provider.dart:53` 的 `_RetryScheduledException`。 + +只有三個音源 adapter 的例外繼承共同基底 `SourceApiException`(`lib/data/sources/source_exception.dart:32`)。其他 18 個型別都直接 `implements Exception`,彼此沒有層級。另外有 **33 處** `throw Exception(...)`(未分型),**50 處** `throw StateError/ArgumentError/UnsupportedError/UnimplementedError/FormatException/TimeoutException`(grep `lib/`,不含 `*.g.dart`)(核查更正:原寫「46 處」;重算含 `const` 與 `ArgumentError.value`:StateError 26、FormatException 14、ArgumentError 8(其中 `.value` 4)、UnsupportedError 2,UnimplementedError/TimeoutException 0)。 + +### 1.2 每個型別在哪裡丟、在哪裡接 + +「丟」= 建構點數(含 `throw` 與 `return` 給上層丟);「接」= `on T catch`、`is T`、switch pattern。其餘沒列出的地方由泛型 `catch (e)` 接住。 + +| 型別 | 定義 | 丟(數/代表位置) | 型別化接住(數/位置) | +|---|---|---|---| +| `SourceApiException`(抽象) | `source_exception.dart:32` | 0(抽象) | 9:`audio_stream_quality_fallback.dart:56, 90`;`audio_provider.dart:633, 738, 1880`;`stream_resolution_service.dart:207`;`radio_refresh_service.dart:216`;`playback_error_presenter.dart:68`;`user_message.dart:73` | +| `BilibiliApiException` | `bilibili_exception.dart:5` | 19:`bilibili_source.dart` 13(`_checkResponse:933-949`、`_handleDioError:952-989`)、`bilibili_live_client.dart` 6(`:195, 567-600`) | 只在 adapter 內 rethrow(`bilibili_source.dart:230, 641, 676, 697, 807, 897, 1041`) | +| `NeteaseApiException` | `netease_exception.dart:5` | 23:`netease_source.dart`(`_checkResponse:827-839`、`_classifyStreamUnavailable:841-910`、`_handleDioError:977-1007`) | 只在 adapter 內 rethrow(`netease_source.dart:167, 249, 321, 348, 460`) | +| `YouTubeApiException` | `youtube_exception.dart:5` | 33:`youtube_source.dart`(`_checkPlayability:87-97`、`_classifySourceError:2325-2360`、`_handleDioError:2395-2404`) | adapter 內(`youtube_source.dart:260, 1065, 1426, 1767, 2247, 2300, 2326, 2370`) | +| `BilibiliFavoritesException` | `bilibili_favorites_service.dart:282` | 5(`:58, 124, 161, 193, 253`) | 6:`playlist_detail_page.dart:623, 1623`;`add_to_bilibili_playlist_dialog.dart:79, 117, 241` 等 | +| `YouTubePlaylistException` | `youtube_playlist_service.dart:734` | 3(`:234, 720, 725`) | 5:`playlist_detail_page.dart:627, 1627`;`add_to_youtube_playlist_dialog.dart:81, 220, 274` | +| `NeteasePlaylistException` | `netease_playlist_service.dart:34` | 6(`:114, 203, 227, 289, 304, 319`) | 5:`playlist_detail_page.dart:631, 1631`;`add_to_netease_playlist_dialog.dart:71, 163, 217` | +| `NeteaseException`(歌詞) | `lib/services/lyrics/netease_source.dart:110` | 4 | 0(泛型 catch) | +| `QQMusicException` | `qqmusic_source.dart:84` | 2 | 0 | +| `LrclibException` | `lrclib_source.dart:8` | 1 | 0 | +| `ImportException` | `import_service.dart:701` | 6(`:176, 410, 414, 438, 664, 673`) | 1:`import_playlist_provider.dart:150` | +| `ImportCancelledException` | `playlist_import_service.dart:115` | 2(`:167, 230`) | 1:`playlist_import_provider.dart:180` | +| `SearchException` | `search_service.dart:237` | 1(`:139`) | 0 | +| `PlaylistNameExistsException` | `playlist_exceptions.dart:3` | 3(`playlist_service.dart:117, 162, 386`) | 0 | +| `PlaylistNotFoundException` | `playlist_exceptions.dart:11` | 5(`playlist_service.dart:152, 381`;`playlist_mutation_repository.dart:265, 308, 437`) | 0 | +| `PlaybackTimeoutException` | `audio_types.dart:151` | 2(`playback_request_session.dart:735, 743`) | 4:`audio_provider.dart:758, 1912`;`playback_error_presenter.dart:67`;`playback_request_session.dart:802` | +| `StreamOpenFailedException` | `audio_types.dart:167` | 1(`media_kit_audio_service.dart:685`) | 1:`radio_controller.dart:514` | +| `_RetryScheduledException` | `audio_provider.dart:53` | 1(`:1941`) | 1(`:596`) | +| `UnsupportedDownloadStreamException` | `download_service.dart:1721` | 1(`:1066`) | 1:`download_service.dart:1381` | +| `SecureStorageUnavailable` | `secure_key_value_store.dart:13` | 2(`:64, 66`) | 6:三個帳號服務(`bilibili_account_service.dart:556`、`netease_account_service.dart:407, 482`、`youtube_account_service.dart:542`)、`audio_settings_provider.dart:143`、`lyrics_ai_config_service.dart:48` | +| `UpdateAssetUnavailableException` | `update_service.dart:129` | 2 | 1(`:123`) | +| `UpdateIntegrityException` | `update_service.dart:200` | 6 | 1(`:238`) | + +`SourceApiException` 上的語意 getter `isUnavailable / isGeoRestricted / requiresLogin / isNetworkError / isTimeout / isPermissionDenied / isVipRequired`(`source_exception.dart:48-72`),以及三個遠端歌單例外的 `requiresLogin`(`bilibili_favorites_service.dart:289`、`youtube_playlist_service.dart:740-741`、`netease_playlist_service.dart:40`)、`YouTubeApiException.isPrivateOrInaccessible`(`youtube_exception.dart:44`):grep 全 `lib/` 查不到任何呼叫端。實際被讀的只有 `kind` 本身、`isRateLimited` 與 `kind` 上的三個 getter。(核查補充:`lib/` 內 `isNetworkError` 的命中全是 `PlayerState.isNetworkError`,不是這個 getter;`YouTubeApiException` 覆寫了 `isPermissionDenied`(`youtube_exception.dart:37-41`),仍無呼叫端;`*.g.dart` 與 `part` 檔也無引用。但這些 getter 在 `test/` 有消費者:`test/data/sources/source_exception_test.dart` 全部都測,`netease_source_test.dart` 用 `isGeoRestricted`/`isVipRequired`,`bilibili_source_test.dart` 用 `isUnavailable`——刪除時要連測試一起處理。) + +### 1.3 `SourceErrorKind` 決定的後果 + +| kind | 播放重試(`isRetryable`) | 跳過這首(`shouldSkipTrack`) | 降音質重試 | 使用者訊息(`user_message.dart:45-59`) | +|---|---|---|---|---| +| network / timeout | 是,退避 5 次 | 否 | 否 | adapter 診斷,否則「網路錯誤」/「逾時」(核查更正:原寫「「網路錯誤」/「逾時」」;Dio 路徑的診斷是 `classifyDioError` 的通用翻譯句 `t.error.networkError`/`connectionTimeout`,不是 `t.audio.sourceError*`) | +| rateLimited | 否(解析層另有一次 3 秒重試) | 否 | 否 | **直接用 adapter 的 message** | +| unavailable | 否 | 是 | 是 | adapter 診斷,否則「不可用」 | +| geoRestricted | 否 | 是 | 否 | 同上,「地區限制」 | +| vipRequired | 否 | 是 | 是 | 同上,「需要 VIP」 | +| loginRequired | 否 | 否 | 否 | 同上,「需要登入」 | +| permissionDenied | 否 | 否 | 否 | adapter 診斷,否則 Bilibili 有專屬一句,其他通用(核查更正:原寫「Bilibili 有專屬一句,其他通用」) | +| unknown | 否 | 否 | 否 | adapter message,空的才「發生錯誤」 | + +getter 定義:`source_exception.dart:15-25`。 + +核查補充:`_reasonFor` 對**所有** kind 都先取 adapter 的 message 當診斷(`user_message.dart:42-43`),只有空字串、純數字、等於 code、或落在 `_syntheticDiagnostics` 九句英文清單(`:13-23`)時才退回 kind 翻譯。所以「adapter 給什麼就顯示什麼」不限於 unknown:Bilibili -101 的伺服器原文、YouTube `'Video is unplayable: $e'`(unavailable)、兩個 adapter 的 `'No audio stream available'`(unavailable,不在清單內,清單只有 `'No stream URL available'`)都會原樣上畫面。 + +--- + +## 2. 每個音源的錯誤流 + +### 2.1 Bilibili + +**產生與轉換** + +| 來源訊號 | 轉成 | kind | 證據 | +|---|---|---|---| +| JSON `code` ∈ {-352, -412, -509, -799} | `BilibiliApiException(code, t.error.bilibiliRateLimited)` | rateLimited | `bilibili_exception.dart:20-22, 40-42`;`bilibili_source.dart:938-943` | +| JSON `code` = -101 | 同型別,message 為伺服器原文 | loginRequired | `bilibili_exception.dart:46`;`bilibili_source.dart:945-947` | +| JSON `code` = -403 / 62012 | 同上 | permissionDenied | `bilibili_exception.dart:47-49` | +| JSON `code` = -404 / -503 / 62002 | 同上 | unavailable | `bilibili_exception.dart:43-45` | +| JSON `code` = -10403 | 同上 | geoRestricted | `bilibili_exception.dart:50` | +| 其他非 0 `code` | 同上 | unknown | `bilibili_source.dart:947` | +| HTTP 412 / 429 | 合成碼 -429 | rateLimited | `bilibili_source.dart:966-972`;`bilibili_exception.dart:25` | +| 其他 HTTP 狀態 | `-(statusCode)`;HTTP 403/404/503 因此碰巧落在 -403/-404/-503 | 依上表 | `bilibili_source.dart:973-976` | +| Dio 逾時/連線錯誤/其他 | -1 / -2 / -3 | timeout / network / unknown | `bilibili_source.dart:980-988` | +| 非預期例外(解析錯誤等) | -999,**message = `e.toString()`** | unknown | `bilibili_source.dart:643, 678, 809, 899, 1043` | + +串流解析內部依 `streamPriority` 逐型別嘗試(DASH→durl),只有 `unavailable`/`vipRequired` 會往下一型別降級,其他立刻丟出(`bilibili_source.dart:244-294`)。評論失敗一律回空清單(`bilibili_source.dart:852-858`)。 + +**直播 client**:`getRoomInfo` 風控碼往上拋 rateLimited,其他非 0 碼與 Dio 錯誤回 null(`bilibili_live_client.dart:189-208`);`getRadioStream` 失敗丟未分型的 `Exception`(`bilibili_live_client.dart:285-295`);`resolveRealRoomId` 失敗吞掉、退回原 id(`bilibili_live_client.dart:172-176`)。 + +**重試**:見 §3.2。**UI**:見 §4.1。 + +### 2.2 網易雲 + +| 來源訊號 | 轉成 | kind | 證據 | +|---|---|---|---| +| JSON `code` ∉ {200, 0} | `NeteaseApiException(code, 伺服器 message/msg)` | 依碼 | `netease_source.dart:827-839` | +| `code` = -460 / -462 | 同上 | rateLimited | `netease_exception.dart:27-29` | +| `code` = 301 | 同上 | loginRequired | `netease_exception.dart:34` | +| `code` = 403 / -403 | 同上 | permissionDenied | `netease_exception.dart:35-37` | +| 404 / -404 / -503 / -200 | 同上 | unavailable | `netease_exception.dart:30-33` | +| 串流 `url` 為空,逐項判斷 | 301 → 登入;`fee` 1/4 或訊息含 vip/付費 → -10;-110 或 `flag & 256` 或訊息含版權/地區 → -110;403;404 且 `fee==0` → 301;其他 → -200 | loginRequired / vipRequired / geoRestricted / permissionDenied / unavailable | `netease_source.dart:841-910, 937-975` | +| 串流 `data` 陣列空 | `numericCode: -1`,message 英文 `'No stream data returned'` | **unknown**(-1 在網易雲沒有映射) | `netease_source.dart:127-132`;`netease_exception.dart:24-40` | +| HTTP 429 / 460 / 462 | -460 | rateLimited | `netease_source.dart:986-991` | +| 其他 HTTP | `-(statusCode)` | 依表 | `netease_source.dart:992-995` | +| 逾時/網路/其他 | -997 / -998 / -999 | timeout / network / unknown | `netease_source.dart:998-1006` | +| 非預期例外 | -999,**message = `e.toString()`** | unknown | `netease_source.dart:169, 251, 323, 350, 462` | + +`getAlternativeAudioStream` 永遠回 null(`netease_source.dart:173-178`),所以 CDN 403 之類的開流失敗沒有替代 URL,只剩音質降級那一段(`audio_stream_quality_fallback.dart:69-96`)。試聽 URL 被當成正常結果回傳(`netease_source.dart:145-163`)。 + +### 2.3 YouTube + +YouTube 大部分請求走 `youtube_explode_dart`,不是 Dio,所以 `classifyDioError` 覆蓋不到,改用字串比對(`youtube_source.dart:2320-2324` 註解自述)。 + +| 來源訊號 | 轉成 | kind | 證據 | +|---|---|---|---| +| InnerTube `playabilityStatus.status != OK` | code 由 status+reason **子字串**推:含 country/region/geo/location → geo;含 age → age_restricted;含 sign in/login/log in → login_required;含 private → private_or_inaccessible;`unplayable`;其他用 status 小寫 | geoRestricted / loginRequired / permissionDenied / unavailable / unknown | `youtube_source.dart:87-118`;`youtube_exception.dart:20-34` | +| 任何例外字串含 `429` / `rate` / `quota` / `too many` | `rate_limited` | rateLimited | `youtube_source.dart:2312-2318` | +| 字串含 timeout / socket / connection / network / 404 | timeout / network_error / not_found | 對應 | `youtube_source.dart:2338-2359` | +| Dio 403 | **不分類**(回 null,視為可以換下一種取法) | — | `youtube_source.dart:2327-2328` | +| 其他 Dio | 走 `classifyDioError` | 依狀態碼 | `youtube_source.dart:2395-2404`;`source_exception.dart:78-145` | +| `youtube_explode` 的 `VideoUnplayableException`(詳情) | 有 auth 改走 InnerTube;否則 `unplayable` | unavailable | `youtube_source.dart:247-258` | +| 其他非預期例外 | `'error'`,**message 內嵌 `$e`** | unknown | `youtube_source.dart:276-279, 1067, 1435-1438, 1769, 2251-2254, 2302-2305` | +| 所有 streamType 都拿不到 | `no_stream` | unavailable(→ 跳過這首) | `youtube_source.dart:373-377` | + +「Sign in to confirm you're not a bot」這類匿名擋下:匿名路徑的例外只要不是限流就回 null(`youtube_source.dart:381-405, 473-479`),沒有帶 auth 時最後落到 `no_stream` → unavailable → 播放層跳過,toast 的原因是英文原文「No audio stream available」(核查更正:原寫「顯示「不可用」」;`youtube_source.dart:376` 的 message 不在 `_syntheticDiagnostics`,`cannotPlay` 經 `sourceErrorReason` 會直接用它,見 §1.3 核查補充)。**推測**:實際例外字串未實跑確認;若字串剛好含 `rate` 子字串(如 generate、separate),會被誤判為限流並中止 fallback。帶 auth 時 InnerTube 回 `LOGIN_REQUIRED` 會變成 loginRequired 並中止(`youtube_source.dart:421-423`)。 + +搜尋的例外有特別處理,不把 `$e` 放進 message(`youtube_source.dart:962-969`);註解說實機曾整條印出 `ClientException ... uri=https://...`。其他路徑沒有同樣處理。 + +### 2.4 帳號與遠端歌單服務(三源) + +- **Bilibili 收藏夾**:`_checkResponse` 把 -101/-111/-403/-607/11010/11201 映射成翻譯字串,其他為「未知錯誤(code)」(`bilibili_favorites_service.dart:248-278`)。Dio 錯誤**不包裝**,原樣往上。 +- **YouTube 歌單**:`error.message` 用伺服器原文(`youtube_playlist_service.dart:716-721`);Dio 錯誤不包裝。 +- **網易雲歌單**:`data['message']` 用伺服器原文,沒有才翻譯(`netease_playlist_service.dart:297-308`);Dio 錯誤不包裝。 +- UI:三種例外都 `ToastService.error(context, e.message)`,其他走 `ToastService.failure`(`playlist_detail_page.dart:623-639`)。 + +### 2.5 外部匯入(Spotify/QQ)與歌詞源 + +- Spotify/QQ 的解析類失敗都是 `throw Exception(t.importSource.xxx)`,**翻譯好的訊息**(核查更正:原寫「所有失敗」;HTTP 請求 `spotify_playlist_source.dart:59`、`qq_music_playlist_source.dart:154` 外面沒有 catch,Dio 錯誤以 `DioException` 原樣往上)(`spotify_playlist_source.dart:53, 76, 139, 149, 186`;`qq_music_playlist_source.dart:64, 69, 171, 176, 181, 243`)。 +- 歌詞三源各自把 Dio 錯誤轉成自己的例外(`lrclib_source.dart:79-93`、`qqmusic_source.dart:166-209`、`lib/services/lyrics/netease_source.dart:201-239`),但自動匹配全部 `catch (e)` 後 log 並回 null(`lyrics_auto_match_service.dart:121-126, 197-199, 668-671, 711-714, 754-757, 806-809`)。 + +--- + +## 3. 橫切主題 + +### 3.1 限流 + +| 項目 | 現況 | 證據 | +|---|---|---| +| 偵測 | Bilibili 風控碼 + HTTP 412/429;網易雲 -460/-462 + HTTP 429/460/462;YouTube HTTP 429/412 + 字串子字串 | §2 各表 | +| 全域限速器/token bucket | **查不到**(grep `RateLimiter|Throttle|TokenBucket|Semaphore` 無結果) | — | +| 主動節流 | 外部匯入每首之間 1000/800ms(`playlist_import_service.dart:276-285`;`app_constants.dart:83-88`);Bilibili 收藏夾翻頁 200ms(`bilibili_source.dart:624-625`);網易雲 400 首一批、批間 200ms(`netease_source.dart:514-525`);直播真實房號快取以減少風控計數(`bilibili_live_client.dart:146-177`) | — | +| 播放遇限流 | 串流解析重試 1 次、等 3 秒(`stream_resolution_service.dart:207-224`;`app_constants.dart:144-146`);仍失敗 → 播放層 warning toast 顯示 `e.message`,**不退避、不跳過**(`audio_provider.dart:1984-1988`) | — | +| 網易雲限流訊息 | rateLimited 的使用者訊息直接取 `message`(`user_message.dart:56`;播放層更直接,`audio_provider.dart:1986-1987` 不經 `user_message.dart`,把 `e.message` 原樣寫進 state 與 warning toast)(核查補充),網易雲的 message 是伺服器原文(`netease_source.dart:832-837`),所以 toast 是平台原文(**推測**:原文內容未實測) | — | + +### 3.2 退避與重試(全部) + +| 位置 | 觸發條件 | 次數/間隔 | 證據 | +|---|---|---|---| +| 播放恢復階梯 | `SourceErrorKind.network/timeout`,或 `SocketException/HttpException/TlsException/TimeoutException`(非 `PlaybackTimeoutException`) | 5 次:1、2、4、8、16 秒;網路恢復時自動重播 | `playback_error_presenter.dart:63-80`;`app_constants.dart:226-246`;`playback_recovery_coordinator.dart:170-188`;`audio_provider.dart:2134-2142` | +| 串流解析(限流) | rateLimited | 1 次,3 秒 | `stream_resolution_service.dart:210-223` | +| 串流解析(非 `SourceApiException`) | 任何其他例外 | 1 次,1 秒 | `stream_resolution_service.dart:230-244`;`app_constants.dart:138` | +| 音質降級 | unavailable / vipRequired | high→medium→low | `audio_stream_quality_fallback.dart:42-67` | +| 串流型別降級 | adapter 內,可降級的錯誤 | audioOnly→muxed→hls | `bilibili_source.dart:253-278`;`youtube_source.dart:348-371` | +| 開流失敗換 URL | 後端開流失敗 | 1 次 `resolveFallback` | `audio_stream_manager.dart:105-127` | +| 播放逾時預算 | `PlaybackTimeoutException` | **不重試**,toast | `playback_error_presenter.dart:63-66`;`audio_provider.dart:1909-1918` | +| 排行榜 | 任何刷新失敗(不只限流) | 4 次:5 秒、30 秒、2 分、10 分;之後等每小時定時刷新 | `ranking_cache_service.dart:124-129, 288-310` | +| 電台直播狀態輪詢 | rateLimited | 間隔 × 2^n,上限 30 分;其餘錯誤直接標「未開播」 | `radio_refresh_service.dart:32, 216-226, 239-249` | +| 電台斷線重連 | 直播流斷開 | 3 次:1、3、10 秒 | `app_constants.dart:249-262`;`radio_controller.dart:263-264, 900-906` | +| YouTube 排行 | 暫時性錯誤(5xx、逾時、連線) | 1 次,200ms | `youtube_source.dart:1617-1631, 2369-2392` | +| Bilibili 收藏夾 -101/-111 | 認證失敗 | 刷新 cookie 後重打 1 次 | `bilibili_auth_interceptor.dart:40-88` | + +### 3.3 Cookie 失效 + +| 平台 | 啟動時 | 請求期(帳號服務的 Dio) | 請求期(播放/搜尋的 adapter Dio) | 自動刷新 | +|---|---|---|---|---| +| Bilibili | 先 `refreshCredentials()`(`account_provider.dart:131-152`),再 `checkAccountStatus`:-101/-111 → invalid → `markSessionExpired()` + toast(`bilibili_account_service.dart:500-501`;`account_provider.dart:233-236`) | 攔截器看到 -101/-111 → 刷新 → 重打一次;還是失敗就 `markSessionExpired()`,由 watcher 補 toast(`bilibili_auth_interceptor.dart:40-88`;`account_provider.dart:190-199`);只掛在收藏夾服務的 Dio(`bilibili_favorites_service.dart:47-48`) | **無攔截器**(`bilibili_source.dart:96-101`)。-101 → loginRequired → 「播放失敗:需要登入」,不標失效、不刷新 | 有(RSA correspondPath,`bilibili_account_service.dart:351-450`) | +| 網易雲 | `checkAccountStatus`:`code != 200` **一律**當 invalid(`netease_account_service.dart:360-362`)→ 清憑證、標失效(`:290-297`) | 攔截器:`code == 301` 且目前登入 → `markSessionExpired()`(`netease_auth_interceptor.dart:52-56`);只掛在歌單服務(`netease_playlist_service.dart:64`) | 無攔截器(`netease_source.dart:46`);301 → loginRequired | 無(`refreshCredentials` 直接回 true,`netease_account_service.dart:301`) | +| YouTube | `checkAccountStatus`:HTTP 401/403 或回應裡沒有使用者資料 → invalid(`youtube_account_service.dart:224-229`) | 攔截器只 **log** `UNAUTHENTICATED`,不標失效(`youtube_auth_interceptor.dart:30-60`) | 無攔截器 | 無(`youtube_account_service.dart:168`) | + +提示去重:同一 app session 每個平台最多一次(`session_expiry_notifier.dart:11-23`)。狀態檢查本身失敗(網路錯)只寫 log(`account_provider.dart:242-248`)。 + +風險:網易雲狀態檢查把 `-460`(限流)等任何非 200 碼都當成失效,憑證會被清掉(`netease_account_service.dart:360-362` + `:290-297`)。(核查確認呼叫鏈為事實:`verifyAllAccountStatuses` 收到 invalid 即 `markSessionExpired()`(`account_provider.dart:233-236`),後者刪 secure storage 並標失效;code 200 但缺 `profile` 也回 invalid(`:339-342`)。對照 Bilibili 只把 -101/-111 當 invalid、其他碼回 error(`bilibili_account_service.dart:500-503`)。前提是伺服器以 HTTP 200 回 JSON 非 200 碼;HTTP 層錯誤走 `DioException` → error,不清憑證。)**推測**:實際多常發生未量測。 + +### 3.4 風控驗證(captcha/412/wbi) + +- **captcha/極驗/gaia `v_voucher`**:grep `captcha|geetest|gaia|v_voucher|verify` 在 `lib/` **查不到**任何處理。遇到只會被分類成限流或未知。 +- **HTTP 412**:一律當限流(`source_exception.dart:105-111`;`bilibili_source.dart:966-972`)。 +- **WBI 簽名**:`/x/web-interface/wbi/view` 目前**不簽**,註解說 Bilibili 對它不驗簽(`bilibili_source.dart:77-84`)。哪天開始驗簽,匿名播放第一步(查 cid)就會失敗。 +- **buvid 指紋**:啟動時本地隨機生成 buvid3/buvid4 放進 Cookie(`bilibili_source.dart:91-102, 121-147`);遇風控不換指紋(`bilibili_source.dart:921-932` 註解自述已移除換指紋路徑)。 +- **網易雲 -462**(需要驗證):當成限流(`netease_exception.dart:27-29`),沒有驗證流程。 + +### 3.5 地區/版權限制 + +| 源 | 偵測 | 後果 | +|---|---|---| +| Bilibili | `-10403` → geo;`62002` → unavailable;`62012` → permissionDenied(`bilibili_exception.dart:43-50`) | geo/unavailable 在佇列模式跳過並 warning toast;permissionDenied 只 toast 不跳過(`audio_provider.dart:1951-1994`) | +| 網易雲 | `-110`、`flag & 256`、訊息關鍵字(`netease_source.dart:865-876, 957-975`);VIP 另走 -10 | geo/VIP 跳過;VIP 先降音質(`source_exception.dart:18-25`) | +| YouTube | playability 字串含 country/region/geo/location(`youtube_source.dart:103-108`) | 跳過 | + +跳過只在「佇列模式且還有下一首」時發生;否則停止播放並顯示錯誤(`audio_provider.dart:1952-1983`)。 + +--- + +## 4. 使用者最終看到什麼 + +### 4.1 依功能 + +| 功能 | 失敗時使用者看到 | 證據 | +|---|---|---| +| 佇列播放 | 可跳過:warning toast「無法播放〈歌名〉:〈原因〉,已跳過」並 300ms 後下一首;限流:warning toast 原因;網路/逾時:頂部網路橫幅+自動重試;其他:error toast | `audio_provider.dart:1880-1995`;`network_status_banner.dart:27, 74-102` | +| 臨時播放(搜尋頁點歌) | toast,然後還原原佇列 | `audio_provider.dart:633-658` | +| `PlayerState.error` | 7 處寫入 `e.toString()`(`audio_provider.dart:492, 530, 600, 854, 970, 1007, 1905`)。grep `lib/ui` **查不到**任何讀取 `PlayerState.error` 文字的地方,只有 `playback_event_router.dart:73` 的 `hasError` 旗標(核查補充:另有 `audio_provider.dart:438`(`'Initialization failed: $e'`)、`:1166`、`:2097` 也寫原文;整個 `lib/` 對它的讀取只有 `audio_provider.dart:518` 的非 null 判斷與 `:2770` 轉成 `hasError`,文字本身無人讀) | — | +| 搜尋 | 只有**所有**線上結果都空時才顯示 `ErrorDisplay`;部分源失敗時靜默(錯誤字串存在 state 但不畫)。字串前綴是原始 id(`bilibili: ...`),不是顯示名稱 | `search_page.dart:424-430`;`search_service.dart:105-116` | +| 排行榜 | 有舊快取時靜默保留;空的才顯示通用「載入失敗」 | `ranking_cache_service.dart:288-294`;`explore_page.dart:135-141` | +| 詳情面板 | `ErrorDisplay`(`failureMessage` 翻譯) | `track_detail_provider.dart:122, 207`;`track_detail_panel.dart:378` | +| 內部歌單匯入 | 對話框錯誤文字;`ImportException` 會變成「發生錯誤」(見 4.3 #1) | `import_playlist_provider.dart:150-180` | +| 外部歌單匯入 | 對話框錯誤文字,**一律**「發生錯誤」(見 4.3 #1) | `import_playlist_dialog.dart:557-576` | +| 遠端歌單讀寫 | error toast,內容為 `e.message` | `playlist_detail_page.dart:623-639`;`add_to_*_playlist_dialog.dart` | +| 電台播放 | error toast「播放失敗:〈原因〉」;原因是 `userMessageFor(e)`,而 `getRadioStream` 丟的是未分型 `Exception`(`bilibili_live_client.dart:285-295`),`getLiveInfo` 也是(`radio_source.dart:102`),所以通常是「播放失敗:發生錯誤」(核查補充) | `radio_controller.dart:510-525`;`home_page.dart:126-130`;`radio_page.dart:33` | +| 電台直播狀態 | 靜默;非限流錯誤直接顯示為「未開播」 | `radio_refresh_service.dart:221-226, 252-257` | +| 歌詞自動匹配 | 靜默,看不到歌詞 | `lyrics_auto_match_service.dart:197-199`;`lyrics_auto_match_coordinator.dart:74-78` | +| 歌詞手動搜尋 | `ErrorDisplay` | `lyrics_provider.dart:490`;`lyrics_search_sheet.dart:392` | +| 帳號 | 失效:warning toast(每平台每 session 一次);VIP 到期:info toast;檢查失敗:只 log | `account_provider.dart:224-248`;`session_expiry_notifier.dart:18-22` | +| 下載 | 下載管理頁顯示存下的翻譯句 | `download_service.dart:1380-1385, 892-898` | + +提示元件用量(grep):`ToastService.success` 60、`.error` 42、`.show` 26、`.warning` 14、`.failure` 13、`.showWithAction` 6;實例方法 `showError` 12、`showInfo` 6、`showWarning` 5、`showSuccess` 2;`showDialog` 呼叫 44 處(核查更正:原寫「49 處」,那是子字串計數,含 4 處 `_showDialog` 與 1 個同名區域變數);直接建構 `SnackBar(` 1 處(核查更正:原寫「15 處」,那是子字串計數,含 `buildSnackBar(` 8、`showSnackBar(` 4、`removeCurrentSnackBar(` 2)。`ToastService.failure` 是註解宣稱的「UI 顯示例外的唯一入口」(`toast_service.dart:180-198`),實際 13 處。 + +### 4.2 catch 統計 + +腳本以大括號配對抽出每個 catch 區塊再依內容分類(`lib/`,不含 `*.g.dart`)。分類是啟發式,數字是約數。(核查重算:另寫一支先遮蔽字串與註解、再配對括號的腳本,得總數 507(`catch (` 478 + 只有 `on X {` 29)、泛型 407、`catch (_` 115、完全空 36、只有註解 34、單行 `catch (_) {}` 36;與下表差距 < 1%,不更正。其餘分類未重算。) + +| 類別 | 數量 | +|---|---| +| catch 區塊總數(`catch (` 479 + 只有 `on X {` 的 32) | **511** | +| 沒有 `on` 型別的泛型 catch | 411 | +| `catch (_` | **115** | +| 空 catch(完全空) | **37** | +| 空 catch(只有註解) | **34** | +| 單行 `catch (_) {}` | 36 | +| 單行 `catch (e) {}` | 0(多行、只有註解的 `catch (e)` 有:`import_service.dart:552`、`add_to_playlist_dialog.dart:547, 558`、`radio_controller.dart:391`) | +| 只 log | **80** | +| 回傳預設值(含先 log 的 40) | 77 | +| rethrow/轉型再丟 | 73 | +| 只 `continue`/`break` | 4 | +| 其他(有實際處理) | 206 | +| `.catchError(` | 14 | + +空 catch 集中處:`lib/ui/windows/lyrics_window.dart` 9、三個登入頁共 12(其中 9 處清 WebView 狀態,另 3 處在 `youtube_login_page.dart:101, 210, 295` 解析頻道資訊與 DATASYNC_ID)(核查更正:原寫「三個登入頁共 10(清 WebView 狀態)」)、`radio_controller.dart` 4(`:294, 391, 1053, 1062`;核查補充)、`network_image_cache_service.dart` 7、`download_path_maintenance_service.dart` 6(`on FileSystemException`)、`download_scanner.dart` 4、`update_service.dart` 3。 + +### 4.3 最危險的幾處 + +1. **翻譯好的錯誤被壓成「發生錯誤」**。`userMessageFor` 只認 `SourceApiException`、`DioException`、`dart:io` 例外、`TimeoutException`、`FormatException`、`PathAccessException`,其他一律 `t.error.unknownError`(`lib/core/errors/user_message.dart:72-87`)。受影響: + - `ImportException`(訊息已翻譯,`import_service.dart:701-707`)→ `failureMessage`(`import_playlist_provider.dart:150-163`)→「發生錯誤」。 + - Spotify/QQ 的 `throw Exception(t.importSource.xxx)`(§2.5)→ `failureMessage`(`playlist_import_provider.dart:186-197`)→「發生錯誤」;對話框再包一層 `Exception` 丟給 `userMessageFor`(`import_playlist_dialog.dart:557-576`),還是「發生錯誤」。 + - `PlaylistNameExistsException`(`toString()` 是翻譯句,`playlist_exceptions.dart:3-9`)沒有任何型別化 catch → `failureMessage`(`playlist_provider.dart:121-129`)→ 建立歌單對話框 toast「發生錯誤」(`create_playlist_dialog.dart:509-513`)。(核查確認為程式碼事實,原標「**推測**」:`PlaylistService.createPlaylist` 先查 `nameExists` 就丟(`playlist_service.dart:115-117`),對話框的 validator 只擋空字串(`create_playlist_dialog.dart:103-105`),provider catch 後回 null,對話框讀 `playlistListProvider.error` 顯示。改名(`:162`)與複製(`:386`)走同樣的 provider catch。) + - `SearchException`(`search_service.dart:139`)同理。(核查補充:只在要求的音源沒註冊時丟,搜尋 chip 由已註冊音源推導,實務上很難觸發。) + - (核查補充)電台:新增電台對話框的 YouTube 網址、已存在、網址無法解析都是 `throw Exception(t.radio.xxx)`(`radio_source.dart:142, 147`;`radio_controller.dart:642, 752`),對話框 `userMessageFor(e)`(`lib/ui/widgets/radio/add_radio_dialog.dart:55-58`)→「發生錯誤」;電台播放失敗同理(§4.1)。 + - (核查補充)外部匯入連網路錯誤也不例外:provider 已把 `DioException` 翻成網路錯誤句,但對話框在 `phase == error` 時再 `throw Exception(state.errorMessage)`(`import_playlist_dialog.dart:556-559`),所以不論原因,外部匯入一律「發生錯誤」。 +2. **例外原文仍會上畫面,與註解主張不一致**。`user_message.dart:64-67` 說回傳值不會有 Dart 例外原文;但 adapter 把非預期例外包成 `message: e.toString()`(`bilibili_source.dart:643, 678, 809, 899, 1043`;`netease_source.dart:169, 251, 323, 350, 462`)或內嵌 `$e`(`youtube_source.dart:278, 1437, 2253, 2304`),而 unknown kind 的使用者訊息就是 message(`user_message.dart:57-58`)。**不一致**。(核查補充:YouTube 另有 `:1067`、`:1769` 直接 `message: e.toString()`,`:257` 的 `'Video is unplayable: $e'` 是 unavailable kind 也照樣顯示——因為 `_reasonFor` 對所有 kind 先取 message,見 §1.3 核查補充。呼叫鏈已追到 UI:詳情 `track_detail_provider.dart:122, 207`、搜尋 `search_service.dart:108-115`、內部匯入 `import_playlist_provider.dart:156, 172` 都經 `failureMessage` → `sourceErrorReason`。) +3. **網易雲狀態檢查把任何非 200 碼當成登入失效並清掉憑證**(`netease_account_service.dart:360-362, 290-297`;呼叫端 `account_provider.dart:233-236`)。 +4. **播放期的登入失效偵測不到**:攔截器只掛在帳號服務自己的 Dio,adapter 的 Dio 沒有(§3.3)。(核查補充:更精確地說,三個攔截器都只掛在**歌單服務**的 Dio(`bilibili_favorites_service.dart:48`、`youtube_playlist_service.dart:55`、`netease_playlist_service.dart:64`),帳號服務自己的 Dio 也沒有;`lib/data/sources/` grep `interceptors` 無結果;`lib/` 全域 `markSessionExpired()` 的呼叫端只有 `account_provider.dart:235` 與 Bilibili/網易雲兩個攔截器。)YouTube 攔截器即使看到 `UNAUTHENTICATED` 也只寫 log(`youtube_auth_interceptor.dart:30-37`)。 +5. **電台輪詢把網路錯誤顯示成「未開播」**:`getRoomInfo` 對 Dio 錯誤回 null(`bilibili_live_client.dart:205-208`)→ `RadioSource` 丟 `Exception('Failed to get room info')`(`radio_source.dart:102`)→ `_markOffline`(`radio_refresh_service.dart:223-226, 252-257`)。(核查補充:單站刷新 `refreshStation` 連限流也不分,任何例外都寫 `false`(`radio_refresh_service.dart:260-272`)。) +6. **搜尋部分失敗靜默**(`search_page.dart:424`)。 +7. **`ImportService.autoRefreshAll` 的空 catch**(`import_service.dart:548-554`)連 log 都沒有;但 grep 查不到任何呼叫端,是死碼。(核查確認:`lib/` 與 `test/` 只有定義處一筆,無 tear-off、無 codegen 引用。) +8. **加入本地歌單的逐歌單失敗不記 log**(`add_to_playlist_dialog.dart:547, 558`),使用者只看到「部分完成 N/M」(`:598-604`)。 +9. **YouTube 限流判斷用子字串 `rate`**(`youtube_source.dart:2312-2318`),任何含 generate/separate/accurate 的錯誤字串都會被當成限流並中止 fallback(`youtube_source.dart:389-395, 2362-2367`)。**推測**:未找到實際觸發案例。 + +--- + +## 5. 錯誤從音源到 UI + +```mermaid +flowchart TD + A[HTTP 回應或 youtube_explode 例外] --> B{adapter 分類} + B -->|Dio 錯誤| C[SourceApiException.classifyDioError] + B -->|JSON code 非成功| D[_checkResponse 依平台碼映射] + B -->|YouTube 非 Dio| E[_classifySourceError 字串比對] + B -->|其他非預期| F[包成 -999 或 error, message 帶原文] + C --> G[BilibiliApiException / NeteaseApiException / YouTubeApiException] + D --> G + E --> G + F --> G + G --> H{kind} + + H -->|unavailable 或 vipRequired| Q[音質降級與串流型別降級] + Q -->|仍失敗| R + H -->|其他| R[StreamResolutionService] + R -->|rateLimited 且首次| R1[等 3 秒重試 1 次] + R1 --> R + R -->|非 SourceApiException 且首次| R2[等 1 秒重試 1 次] + R2 --> R + R -->|rethrow| S[AudioController._executePlayRequest] + + S -->|network 或 timeout| T[退避階梯 1 2 4 8 16 秒] + T --> U1[網路狀態橫幅] + S -->|unavailable geo vip 且佇列有下一首| U2[warning toast 並跳下一首] + S -->|unavailable geo vip 且無下一首| U3[停止並 error toast] + S -->|rateLimited| U4[warning toast 顯示 adapter message] + S -->|loginRequired permissionDenied unknown| U5[error toast 播放失敗加原因] + + G --> V[搜尋 匯入 詳情 provider] + V --> W[failureMessage 或 userMessageFor] + W -->|SourceApiException| X[sourceErrorReason: adapter 診斷優先, 否則 kind 翻譯] + W -->|Dio 或 dart io| Y[通用網路或逾時句] + W -->|其他型別 含 ImportException 與 Exception 翻譯句| Z[一律 發生錯誤] + X --> UI[ErrorDisplay 或 toast] + Y --> UI + Z --> UI + + G --> RF[電台輪詢或排行刷新] + RF -->|rateLimited| BK[退避: 電台最多 30 分, 排行 5s 30s 2m 10m] + RF -->|其他| SL[靜默: 電台標未開播, 排行保留舊快取] +``` + +--- + +## 附:本檔發現的文檔與程式碼不一致 + +| 主張 | 位置 | 程式碼現況 | +|---|---|---| +| 回傳給 UI 的字串不會有 Dart 例外原文 | `lib/core/errors/user_message.dart:64-67` | adapter 的 -999/error 包裝把 `e.toString()` 放進 message,unknown kind 直接顯示它(§4.3 #2) | +| `ToastService.failure` 是 UI 顯示例外的唯一入口 | `lib/core/services/toast_service.dart:182-185` | 遠端歌單路徑直接 `ToastService.error(context, e.message)`(`playlist_detail_page.dart:623-634`);`home_page.dart:128` 直接顯示 `RadioState.error` | +| 三個 adapter 共 22 處 `on DioException catch` | `playback_error_presenter.dart:60` | 實數 19(Bilibili 9、YouTube 5、網易雲 5),加直播 client 2 為 21 | +| `isPermissionDenied` 表示「需要登入重試」 | `source_exception.dart:66-69` | 查不到任何依此重試的呼叫端 | +| Bilibili 風控「由上層退避:串流解析隔幾秒重試一次,排行榜與電台輪詢各有退避階梯」 | `bilibili_source.dart:921-925` | 串流解析只重試 1 次(`stream_resolution_service.dart:210`);之後播放層不退避(`audio_provider.dart:1984-1988`)。排行與電台的描述屬實 | diff --git a/docs/audit/features.md b/docs/audit/features.md new file mode 100644 index 000000000..24ac74e3e --- /dev/null +++ b/docs/audit/features.md @@ -0,0 +1,446 @@ +# 功能清單 + +> 現況描述,未經確認,不代表目標。 + +審計日期:2026-09-26,分支 `docs/audit`。所有結論以原始碼為準(`*.g.dart` 不採信);沒有執行 app、沒有打真實 API。與文件/註釋衝突處標 **不一致**;依程式結構推得、未實測的結論標 **推測**。 + +狀態欄的用語: + +- **完整**:有 UI 入口,端到端程式路徑存在。 +- **半成品**:有入口但功能明顯不全,或行為與介面宣稱不符。 +- **死代碼**:`lib/` 裡沒有呼叫點(列出 grep)。 +- **無 UI 入口**:程式會被呼叫,或資料欄位存在,但使用者沒有辦法觸發或修改。 +- **僅開發者模式**:要在「版本」連點 7 次後才看得到(見 `devtools.md`)。 + +平台欄:A = Android,W = Windows。程式裡還有 Linux/macOS 分支(例如 `lib/main.dart:232-235`),但 `pubspec.yaml` 的註解寫「FMP 不出 Linux/macOS」,本清單不列。 + +--- + +## 0. 入口總覽 + +### 0.1 路由(`lib/ui/router.dart`) + +所有頁面都掛在一個 `GoRouter`(`router.dart:124-309`)。`ShellRoute` 內的頁面共用 `AppShell`(導覽列 + 迷你播放器);全螢幕播放頁與電台播放頁掛在 root navigator,蓋在 shell 之上(`:293-307`)。 + +| 路徑 | 頁面 | 使用者怎麼到 | 證據 | +|---|---|---|---| +| `/` | `HomePage` | 導覽列「首頁」 | `router.dart:134-139`;導覽 `lib/ui/layouts/responsive_scaffold.dart:52` | +| `/search` | `SearchPage` | 導覽列 | `router.dart:141-146`;`responsive_scaffold.dart:58` | +| `/explore` | `ExplorePage`(排行完整列表,依音源分 Tab) | 首頁排行區塊的按鈕 | `router.dart:148-152`;`lib/ui/pages/home/home_page.dart:203` | +| `/queue` | `QueuePage` | 導覽列 | `router.dart:154-159`;`responsive_scaffold.dart:64` | +| `/history` | `PlayHistoryPage` | 首頁「最近播放」、設定頁「播放歷史」 | `router.dart:161-165`;`home_page.dart:672`;`lib/ui/pages/settings/settings_page.dart:108` | +| `/library` | `LibraryPage` | 導覽列 | `router.dart:167-171`;`responsive_scaffold.dart:70` | +| `/library/downloaded` | `DownloadedPage` | 音樂庫右上「已下載」 | `router.dart:174-177`;`lib/ui/pages/library/library_page.dart:64` | +| `/library/downloaded/:folderName` | `DownloadedCategoryPage` | 已下載頁點分類卡 | `router.dart:180-186`;`lib/ui/pages/library/downloaded_page.dart:296` | +| `/library/:id` | `PlaylistDetailPage` | 點歌單卡 | `router.dart:191-197`;`lib/ui/widgets/layout/playlist_grid_card.dart:57` | +| `/radio` | `RadioPage` | 導覽列 | `router.dart:202-207`;`responsive_scaffold.dart:76` | +| `/settings` | `SettingsPage` | 導覽列 | `router.dart:209-213`;`responsive_scaffold.dart:82` | +| `/settings/download-manager` | `DownloadManagerPage` | 設定「儲存」、已下載頁、歌單詳情頁 | `router.dart:216-220`;`lib/ui/pages/settings/widgets/settings_storage.dart:12`;`downloaded_page.dart:94` | +| `/settings/audio` | `AudioSettingsPage` | 設定「音質」 | `router.dart:222-226`;`settings_page.dart:101` | +| `/settings/lyrics-source` | `LyricsSourceSettingsPage` | 設定「播放」區的歌詞自動匹配列 | `router.dart:228-232`;`lib/ui/pages/settings/widgets/settings_playback.dart:155` | +| `/settings/home-ranking` | `HomeRankingSettingsPage` | 設定「快取」區 | `router.dart:234-238`;`settings_page.dart:128` | +| `/settings/user-guide` | `UserGuidePage`(靜態說明文字) | 設定「關於」 | `router.dart:240-244`;`settings_page.dart:172` | +| `/settings/developer` | `DeveloperOptionsPage` | **僅開發者模式** | `router.dart:246-249`;`lib/ui/pages/settings/widgets/settings_about.dart:111` | +| `/settings/developer/database` | `DatabaseViewerPage` | **僅開發者模式** | `router.dart:252-256` | +| `/settings/developer/logs` | `LogViewerPage` | **僅開發者模式** | `router.dart:258-262` | +| `/settings/account` | `AccountManagementPage` | 設定第一列 | `router.dart:266-269`;`settings_page.dart:76` | +| `/settings/account/{bilibili,youtube,netease}-login` | 三個登入頁 | 帳號管理頁「登入」 | `router.dart:271-285`;`lib/ui/pages/settings/account_management_page.dart:75,98,119` | +| `/player` | `PlayerPage`(全螢幕) | 點迷你播放器 | `router.dart:293-299`;`lib/ui/widgets/player/mini_player.dart:58,348` | +| `/radio-player` | `RadioPlayerPage`(全螢幕) | 點電台迷你播放器 | `router.dart:301-307`;`lib/ui/widgets/radio/radio_mini_player.dart:44` | + +每條路由都找得到 UI 入口,沒有孤兒路由。開發者頁的三條路由是無條件註冊的,只是 UI 入口藏起來。 + +不在路由表、以對話框或 bottom sheet 開啟的「頁面」:歌單匯入(`ImportPlaylistDialog`,`library_page.dart:258`)、匯入預覽(檔名是 `import_preview_page.dart`,實際是 `ImportPreviewDialog`,`lib/ui/pages/library/import_preview_page.dart:21-33`)、建立/編輯歌單(`library_page.dart:251`)、歌詞搜尋(`lib/ui/pages/lyrics/lyrics_search_sheet.dart:21-30`)、帳號歌單匯入(`account_management_page.dart:193`)、帳號電台匯入(`account_management_page.dart:202`)、新增電台(`lib/ui/pages/radio/radio_page.dart:77,94`)、更新對話框(`lib/ui/widgets/dialogs/update_dialog.dart:100-110`)。 + +### 0.2 其他入口類型(細節在各功能節) + +| 類型 | 摘要 | 證據 | +|---|---|---| +| 曲目選單(右鍵、「⋮」、長按三者同源) | 播放/下一首播放/加入佇列/加入歌單/匹配歌詞/**加入遠端歌單** | `lib/ui/handlers/track_action_menu.dart`、`track_action_handler.dart`、`track_action_coordinator.dart`;右鍵元件 `lib/ui/widgets/menus/context_menu_region.dart` | +| 多選模式 | 歌單詳情、搜尋、探索、歷史四頁;動作依頁面不同,含**加入/移除遠端歌單** | `lib/ui/widgets/app_bars/selection_mode_app_bar.dart`;`lib/ui/widgets/menus/selection_menu_items.dart:22-75` | +| 歌單卡選單 | Mix 播放/全部加入佇列/隨機加入/編輯/刷新/刪除 | `lib/ui/widgets/menus/playlist_card_actions.dart:26-71` | +| 鍵盤快捷鍵 | **沒有 app 內快捷鍵**(grep `Shortcuts(\|CallbackShortcuts\|SingleActivator\|KeyboardListener\|HardwareKeyboard\|onKeyEvent` 在 `lib/` 無結果,`LogicalKeyboardKey` 只出現在熱鍵設定 UI)。只有 Windows 全域熱鍵(§10) | `lib/data/models/hotkey_config.dart:9-17,212-257` | +| 托盤選單(W) | 目前曲目(不可點)/播放暫停/上一首/下一首/顯示視窗/結束 | `lib/services/platform/windows_desktop_service.dart:144-175` | +| 通知(A) | `audio_service` 媒體通知:上一首/播放暫停/下一首、seek、重複、隨機;按鈕依可用能力增減。沒有其他通知(沒有 `flutter_local_notifications`) | `lib/services/audio/audio_handler.dart:51-70,196-244` | +| SMTC(W) | 播放/暫停/停止/上下首/隨機/重複;快轉倒轉恆關;不支援從 SMTC 拖進度 | `lib/services/audio/windows_smtc_handler.dart:62-73,139-161,195-204,352-378` | +| 桌面歌詞視窗(W) | 獨立子視窗,控制列見 §6 | `lib/ui/windows/lyrics_window.dart`;開關 `lib/ui/widgets/panels/track_detail_panel.dart:557` | + +### 0.3 各頁選單位置 + +「右鍵」一律是 `ContextMenuRegion`(`onSecondaryTapUp` → `showMenu`),內容與同一列的「⋮」按鈕、長按選單相同。 + +| 頁面/元件 | 入口位置 | 內容 | 含遠端寫入 | +|---|---|---|---| +| 首頁排行、探索頁曲目列 `RankingTrackTile` | `lib/ui/widgets/track_tiles/ranking_track_tile.dart:59-61`(右鍵)、`:190-209`(⋮) | 完整曲目選單;長按進多選 | 是(加入遠端) | +| 搜尋頁:影片列、分 P 列、本機比對列 | `lib/ui/pages/search/search_page.dart:930,1046`、`:1106,1131`、`:1206,1283`、`:1421,1458` | 完整曲目選單;長按進多選 | 是 | +| 搜尋頁:直播間列 | `search_page.dart:1553,1646` | 播放、加為電台 | 否 | +| 搜尋頁:排序 | `search_page.dart:289` | `SearchOrder` | 否 | +| 歌單詳情:曲目列、分 P 群組、AppBar | `lib/ui/pages/library/playlist_detail_page.dart:1175`、`:485`;長按 `:340,390,416` | 曲目選單;匯入歌單的「移除」改為**從遠端移除** | 是 | +| 歌單卡(首頁、音樂庫) | `lib/ui/widgets/layout/playlist_grid_card.dart:42,61`;項目 `playlist_card_actions.dart:26-71` | Mix 播放、全部加入、隨機加入、編輯、刷新、刪除 | 否(刷新是讀取) | +| 播放頁「加入歌單」 | `lib/ui/pages/player/player_page.dart:243-265` | 本機/遠端 | 是(遠端) | +| 播放頁「更多」 | `player_page.dart:298-356` | 速度、歌詞搜尋、歌詞偏移、顯示模式 | 否 | +| 桌面側欄面板 | `lib/ui/widgets/panels/track_detail_panel.dart:482`(歌詞更多)、`:557`(開關歌詞視窗)、`:582`(加入歌單) | 同播放頁 | 是(遠端) | +| 首頁電台區塊、電台頁 | `home_page.dart:521,541`;`lib/ui/pages/radio/radio_page.dart:152,166` | 刪除 | 否 | +| 首頁最近播放 | `home_page.dart:715,727` | 曲目選單(不含遠端)+刪除 | 否 | +| 歷史頁:列、多選、AppBar、排序 | `lib/ui/pages/history/play_history_page.dart:606,636,753`、`:129`、`:206`(清空)、`:380` | 曲目選單(不含遠端)+刪除 | 否 | +| 已下載分類卡、分類頁 | `downloaded_page.dart:282,303`;`downloaded_category_page.dart:418,469,595,650` | 加入佇列、隨機加入、刪除檔案 | 否 | +| 佇列頁 | 沒有選單,只有拖曳(`queue_page.dart:627`)與圖示按鈕 | — | — | +| 下載管理 | `lib/ui/pages/settings/download_manager_page.dart:27` | 批次管理 | 否 | +| 封面/歌詞切換手勢 | `player_page.dart:500,511`(長按) | 非選單 | — | + +--- + +## 1. 播放 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 播放/暫停/上下首/進度條/隨機/循環模式 | 全螢幕播放頁、迷你播放器、通知、SMTC、托盤、全域熱鍵 | A/W | 全部 | 完整 | `lib/ui/pages/player/player_page.dart:682-722`;`audio_handler.dart:196-244` | +| 播放速度 | 播放頁「更多」→速度(`showMenu`) | A/W | 全部 | 完整 | `player_page.dart:326-327,744-750`;速度表 `lib/core/constants/app_constants.dart:43` | +| 音量/輸出裝置選擇 | 迷你播放器桌面控制、`FmpAudioDeviceSelector` | W(裝置選擇靠 media_kit) | — | 完整 | `lib/ui/widgets/player/fmp_audio_device_selector.dart`;還原偏好裝置 `lib/services/audio/audio_provider.dart:1276-1278` | +| 播放佇列:拖曳排序、移除、隨機打亂、清空 | 佇列頁 | A/W | 全部 | 完整 | `lib/ui/pages/queue/queue_page.dart:319-329,589-593,627` | +| 下一首播放/加入佇列 | 曲目選單 | A/W | 全部 | 完整 | `track_action_menu.dart` | +| 啟動時還原佇列與播放位置(不自動播放) | 自動 | A/W | 全部 | 完整 | `audio_provider.dart:424`(`autoPlay: false`)、`:778-802`;設定欄位 `rememberPlaybackPosition` 預設 true:`lib/data/models/settings.dart:259` | +| YouTube Mix/電台式無限播放 | 歌單卡「播放 Mix」、匯入 Mix 簡寫 | A/W | YouTube | 完整 | `playlist_card_actions.dart:26-71`;`lib/services/audio/mix_session_coordinator.dart` | +| 多 P 影片分 P 播放 | 搜尋結果展開、歌單分 P 群組 | A/W | Bilibili | 完整 | `lib/ui/pages/search/search_page.dart:1082`(`_PageTile`) | +| 播放失敗自動重試/跳過、網路恢復後重試 | 自動 | A/W | 全部 | 完整 | `lib/services/audio/playback_recovery_coordinator.dart`;網路恢復訂閱 `audio_provider.dart:272` | +| 播放時帶登入狀態(`useAuthForPlay`) | 音質設定頁(每個音源一個開關,見 §9) | A/W | 全部 | 完整 | `settings.dart:128-148`(`SourceSettingsEntry`) | +| 播放歷史(本機記錄、排序、刪除、清空、上限) | 歷史頁、設定「播放歷史上限」 | A/W | 全部 | 完整 | `lib/ui/pages/history/play_history_page.dart`;`lib/services/audio/play_history_recorder.dart` | +| 音樂與電台互斥(開電台暫停音樂、關電台可回到音樂) | 自動 | A/W | Bilibili 直播 | 完整 | `lib/services/radio/radio_controller.dart:380,562,840` | + +## 2. 搜尋 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 多音源搜尋(頁面上的音源 chip 是唯一的來源選擇器)、排序、篩選、分頁載入 | 搜尋頁 | A/W | B/Y/N | 完整 | `lib/providers/search/search_provider.dart:238,323,416,522,538,591` | +| 本機曲庫比對結果 | 搜尋頁 | A/W | — | 完整 | `search_page.dart:1152,1394` | +| 直播間搜尋(播放、加為電台) | 搜尋頁 | A/W | Bilibili 直播 | 完整 | `search_provider.dart:565,625,675,744`;`search_page.dart:1537` | +| 搜尋歷史(本機,刪除單筆、清空) | 搜尋頁 | A/W | — | 完整 | `search_provider.dart:765-775` | +| 首頁熱門排行(前 10)+探索頁完整排行 | 首頁、探索頁 | A/W | B/Y/N | 完整 | `home_page.dart:164`;`lib/ui/pages/explore/explore_page.dart:67-108`;背景刷新見 §13 | +| 首頁排行「停用某音源」 | 首頁排行設定頁的開關 | A/W | B/Y/N | 完整,但只作用在顯示層(`enabledHomeRankingSourceOrderProvider`):背景刷新仍抓**所有**已註冊音源的榜單 | `lib/providers/settings/home_ranking_settings_provider.dart:193-195`;抓取不過濾 `lib/services/cache/ranking_cache_service.dart:158-163,233-245` | + +## 3. 音樂庫/歌單 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 建立/編輯本機歌單(名稱、封面、自動刷新間隔) | 音樂庫「新增」、歌單卡「編輯」 | A/W | — | 完整 | `library_page.dart:97-104,251`;`lib/ui/pages/library/widgets/create_playlist_dialog.dart:39-61,291` | +| 歌單排序(拖曳) | 音樂庫排序模式 | A/W | — | 完整 | `library_page.dart:279` | +| 歌單詳情:播放、多選、下載、刪除曲目 | 歌單詳情頁 | A/W | 全部 | 完整 | `lib/ui/pages/library/playlist_detail_page.dart` | +| 加入本機歌單 | 曲目選單、播放頁「加入歌單→本機」 | A/W | 全部 | 完整 | `lib/ui/widgets/dialogs/add_to_playlist_dialog.dart:19` | +| **加入遠端歌單/收藏夾(寫入平台)** | 曲目選單「加入遠端」、播放頁「加入歌單→遠端」、多選 | A/W | B/Y/N(需登入) | 完整 | `add_to_bilibili_playlist_dialog.dart`、`add_to_youtube_playlist_dialog.dart`、`add_to_netease_playlist_dialog.dart`;未登入的來源被過濾:`track_action_handler.dart:220,306` | +| **在遠端建立歌單/收藏夾** | 上述對話框裡的「新建」 | A/W | B/Y/N | 完整 | `add_to_bilibili_playlist_dialog.dart:61-75`;`add_to_youtube_playlist_dialog.dart:204-205`;`add_to_netease_playlist_dialog.dart:147-148` | +| **從匯入歌單移除曲目=同時從遠端移除** | 匯入歌單的詳情頁:單曲「移除」與多選「從遠端移除」(有確認框) | A/W | B/Y/N | 完整 | `playlist_detail_page.dart:565-610`(批次)、`:1575-1610`(單曲);控制器 `lib/providers/library/remote_playlist_sync_provider.dart:39-77` | +| 匯入歌單的手動刷新 | 歌單卡「刷新」 | A/W | B/Y/N | 完整 | `playlist_card_actions.dart:253-255` | +| 匯入歌單的自動刷新 | 背景,見 §13 | A/W | B/Y/N | 完整 | `lib/services/library/auto_refresh_service.dart` | +| 遠端寫入後自動刷新對應的本機匯入歌單 | 自動 | A/W | B/Y/N | 完整 | `remote_playlist_sync_provider.dart:61-69`;`lib/services/library/remote_playlist_sync_service.dart:13-28` | +| 每次啟動刪除「不屬於任何歌單也不在佇列」的 Track 列 | 自動(啟動 10 秒後) | A/W | 全部 | 完整 | `lib/services/audio/queue_manager.dart:219-229`;`lib/data/repositories/track_repository.dart:635-673` | + +## 4. 匯入 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 以 URL 匯入 B 站收藏夾/YouTube 歌單/網易雲歌單(直接匯入) | 音樂庫「匯入」 | A/W | B/Y/N | 完整 | `lib/ui/pages/library/widgets/import_playlist_dialog.dart:159-169` | +| YouTube Mix 簡寫匯入 | 同上 | A/W | Y | 完整 | `import_playlist_dialog.dart:149-151`;`lib/services/import/youtube_mix_shorthand.dart` | +| 以 URL 匯入 **QQ 音樂/Spotify** 歌單,再到 B 站/YouTube 搜尋比對(網易雲不在比對來源內) | 同上 → 匯入預覽對話框(可換候選、處理未匹配) | A/W | QQ、Spotify → B/Y | 完整 | `import_playlist_dialog.dart:171-176`;`lib/services/import/playlist_import_service.dart:1-21,137`;預覽 `import_preview_page.dart:21-33,268-282` | +| 帳號歌單匯入(列出登入帳號的歌單並匯入) | 帳號管理頁「管理歌單」 | A/W | B/Y/N | 完整 | `account_management_page.dart:193`;`lib/ui/pages/settings/widgets/account_playlists_sheet.dart:132-161` | +| 帳號電台匯入(B 站粉絲勳章牆的直播間) | 帳號管理頁(僅 B 站列有此按鈕) | A/W | Bilibili 直播 | 完整 | `account_management_page.dart:79,202`;`lib/services/account/bilibili_account_service.dart:529`;`lib/data/sources/bilibili_live_client.dart:339-344` | + +**不一致**:`import_playlist_dialog.dart:26-29,69-73` 的註解說網易雲是「外部來源、需要搜尋匹配」,但同檔 `:159-176` 的程式先交給 `SourceManager` 判斷,網易雲 URL 走內部直接匯入;外部只剩 QQ 音樂與 Spotify。 + +## 5. 下載 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 下載曲目/整個歌單(連同 metadata JSON、封面、UP 主頭像寫在音檔旁) | 歌單詳情、多選「下載」 | A/W | 全部 | 完整 | `playlist_detail_page.dart:966,1039,1527`;`lib/services/download/download_service.dart:1509-1590` | +| 下載管理(佇列、暫停、繼續、清除) | 下載管理頁 | A/W | 全部 | 完整 | `lib/ui/pages/settings/download_manager_page.dart:20-41` | +| 已下載瀏覽(分類、分 P 群組、加入佇列、刪除檔案) | 已下載頁、分類頁 | A/W | 全部 | 完整 | `downloaded_page.dart:238-395,451-509`;`lib/ui/pages/library/downloaded_category_page.dart:519,552,690,723` | +| 變更下載路徑(會重設下載記錄) | 設定「儲存」(Android 不顯示此按鈕,`settings_storage.dart:60`) | W | — | 完整 | `lib/ui/widgets/dialogs/change_download_path_dialog.dart:187-230`;`lib/services/download/download_path_maintenance_service.dart:59` | +| 啟動時同步本機下載檔狀態 | 自動 | A/W | 全部 | 完整 | `lib/app.dart:131`;`lib/providers/download/startup_download_sync_provider.dart:9-40` | +| 下載服務啟動時:**清掉已完成與失敗的任務記錄**、下載中改暫停(不自動續傳)、刪孤兒 `.downloading` 暫存檔 | 自動(第一次讀取 `downloadServiceProvider` 時) | A/W | — | 完整 | `download_service.dart:201-228`;`lib/providers/download/download_providers.dart:42-59` | +| `DownloadPathSyncService.cleanupInvalidPaths()` | — | — | — | **死代碼**(grep `cleanupInvalidPaths` 在 `lib/`、`test/` 只有定義) | `lib/services/download/download_path_sync_service.dart:313` | + +## 6. 歌詞 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 歌詞顯示(原文/優先翻譯/優先羅馬拼音) | 播放頁、桌面側欄面板 | A/W | 網易雲、QQ 音樂、lrclib 歌詞 | 完整 | `track_action_handler.dart:318-354`(顯示模式選單) | +| 手動搜尋並指定歌詞 | 曲目選單「匹配歌詞」、播放頁「更多」 | A/W | 同上 | 完整 | `lyrics_search_sheet.dart:21-30`;`track_action_coordinator.dart:57`;`player_page.dart:134,338` | +| 歌詞偏移校正(逐首持久化) | 播放頁「更多」、桌面歌詞視窗 | A/W | — | 完整 | `player_page.dart:344-345`;`lyrics_window.dart:431-467` | +| **自動匹配歌詞**(每首開始播放時背景搜尋) | 設定開關,**預設關** | A/W | 網易雲、QQ 音樂、lrclib(lrclib 預設停用) | 完整 | `lib/services/audio/lyrics_auto_match_coordinator.dart:36-60`;預設 `settings.dart:347,357,361` | +| **AI 標題解析/AI 候選選擇**(呼叫使用者設定的 OpenAI 相容端點) | 歌詞來源設定頁,模式 off/alwaysAi/advancedAiSelect,**預設 off** | A/W | 使用者自訂端點 | 完整 | `settings.dart:163,364,658-679`;`lib/services/lyrics/lyrics_auto_match_service.dart:156,174`;見 §15 | +| 桌面歌詞視窗:上下首、播放暫停、顯示模式、樣式(顏色、外框、陰影)、單行/整頁、透明、置頂、偏移列、點行跳轉、右鍵某行校正偏移 | 桌面側欄面板的按鈕 | W | — | 完整 | `track_detail_panel.dart:557`;`lyrics_window.dart:719-743,775-776,876-907` | +| 歌詞快取(檔案數上限可調,大小上限 5 MB) | 設定「快取」 | A/W | — | 完整 | `lib/services/lyrics/lyrics_cache_service.dart:19-29` | + +主視窗推給桌面歌詞視窗的同步(位置、歌詞、播放狀態、主題)全部寫在 `TrackDetailPanel` 這個 UI widget 的 `ref.listen` 裡(`track_detail_panel.dart:113-197,273-325`;`LyricsWindowService.instance.sync*` 在 `lib/` 別處沒有呼叫者,已 grep 確認)。該面板只在 expanded 以上的寬版版面、且有曲目時掛載(`lib/ui/layouts/responsive_scaffold.dart:124-141,363-365,514`);**面板收起時仍掛載**,只是以 `OverflowBox` + 裁切藏起來(`responsive_scaffold.dart:498-520`),所以收起不會中斷同步。**推測**:視窗縮到 compact/medium 版面(面板卸載)或全螢幕播放頁蓋住 shell 時,歌詞視窗可能停止更新。未實測。(核查更正:原寫「面板收起或視窗變窄時,歌詞視窗可能停止更新」,收起那一半與程式碼不符) + +## 7. 電台/直播 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| 以 URL 新增 B 站直播間為「電台」 | 電台頁 `+`、搜尋頁直播結果「加為電台」 | A/W | Bilibili 直播 | 完整 | `radio_page.dart:77,94`;`radio_controller.dart:638` | +| 收聽直播(音訊)、停止、回到音樂 | 電台頁、電台播放頁 | A/W | Bilibili 直播 | 完整 | `radio_controller.dart:415,531,562` | +| 電台排序、刪除 | 電台頁 | A/W | — | 完整 | `radio_controller.dart:771,785`;刪除 `radio_page.dart:319` | +| 直播狀態背景輪詢 | 自動,見 §13 | A/W | Bilibili 直播 | 完整 | `lib/services/radio/radio_refresh_service.dart` | +| 播放中每分鐘刷新「高能用戶數」 | 自動 | A/W | Bilibili 直播 | 完整 | `radio_controller.dart:977-981`;`bilibili_live_client.dart:237-254` | +| 電台「收藏」 | — | — | — | **無 UI 入口**:`RadioStation.isFavorite` 欄位存在、會進備份,但 `RadioController.toggleFavorite` 在 `lib/`、`test/` 都沒有呼叫者(grep `toggleFavorite`);讀取端 `RadioRepository.getFavorites()` 同樣零呼叫(核查補證) | `lib/data/models/radio_station.dart:50`;`radio_controller.dart:795-797`;`lib/data/repositories/radio_repository.dart:74,103`;`lib/services/backup/backup_data.dart:456` | +| `RadioRefreshService.refreshStation` | — | — | — | **死代碼**(grep `refreshStation` 只有定義與一行註解) | `radio_refresh_service.dart:26,260` | + +## 8. 帳號 + +| 功能 | 入口 | 平台 | 涉及音源 | 狀態 | 證據 | +|---|---|---|---|---|---| +| B 站登入:WebView 與 QR code 兩個 Tab | 帳號管理 → 登入 | A/W | Bilibili | 完整 | `lib/ui/pages/settings/bilibili_login_page.dart:51-63` | +| 網易雲登入:Android 有 WebView + QR,桌面只有 QR | 同上 | A/W | NetEase | 完整 | `lib/ui/pages/settings/netease_login_page.dart:16-17` | +| YouTube 登入:WebView 登入 Google,登入頁內注入 JS 讀帳號名稱 | 同上 | A/W | YouTube | 完整 | `lib/ui/pages/settings/youtube_login_page.dart:43-48,230-260` | +| 登出(刪 secure storage、清 WebView cookie) | 帳號管理頁 | A/W | B/Y/N | 完整 | `account_management_page.dart:165-183`;`bilibili_account_service.dart:297-324` | +| 手動驗證所有帳號 | 帳號管理頁右上 | A/W | B/Y/N | 完整 | `account_management_page.dart:51,129-138` | +| 啟動時 B 站 Cookie 刷新+所有帳號狀態檢查(VIP 過期會 toast、失效標記) | 自動,見 §13 | A/W | B/Y/N | 完整 | `lib/providers/account/account_provider.dart:131-174,216-248` | +| 請求中偵測到登入失效時提示一次 | 自動 | A/W | B/Y/N | 完整 | `account_provider.dart:190-199`;`lib/services/account/session_expiry_notifier.dart` | + +## 9. 設定 + +設定主頁的區塊與順序(`lib/ui/pages/settings/settings_page.dart:64-196`):帳號管理 → 外觀(主題模式、主題色、字型、語言)→ 播放(音質子頁、播放歷史、歷史上限、自動捲到正在播放、記住播放位置、自動匹配歌詞)→ 快取(圖片快取大小、歌詞快取大小、首頁排行設定子頁、排行刷新間隔、電台刷新間隔)→ 儲存(下載管理、下載路徑、同時下載數、下載圖片選項)→ 備份(匯出、匯入)→ 桌面(**僅 Windows**:開機自啟、關閉時縮到托盤、全域熱鍵)→ 關於(使用說明、檢查更新、版本、開源授權)→ 開發者選項(隱藏)。桌面區塊的平台判斷在 `settings_page.dart:153-162`。 + +各設定項(路徑皆在 `lib/ui/pages/settings/` 下,除非另註;「消費點」是設定值被讀取的地方): + +| 設定項 | 位置 | 寫入 | 平台 | 消費點 | +|---|---|---|---|---| +| 主題模式 | `widgets/settings_appearance.dart:14-24,52-81` | `Settings.themeModeIndex` | A/W | `lib/app.dart:107-108,151` | +| 主題色(預設色票/自訂色) | `settings_appearance.dart:104-125,170-174,219-229` | `Settings.primaryColor` | A/W | `lib/app.dart:109,143-149` | +| 字型 | `settings_appearance.dart:308-366` | `Settings.fontFamily` | A/W | `lib/app.dart:110` | +| 語言(zh-CN/zh-TW/en) | `settings_appearance.dart:388-461` | `Settings.locale` | A/W | `lib/providers/settings/locale_provider.dart` | +| 自動捲到正在播放 | `widgets/settings_playback.dart:9-21` | `autoScrollToCurrentTrack` | A/W | `lib/ui/pages/queue/queue_page.dart:244` | +| 記住播放位置 | `settings_playback.dart:34-61` | `rememberPlaybackPosition` | A/W | `lib/services/audio/queue_persistence_manager.dart:62` | +| 重播/暫時播放後倒帶秒數(0/3/5/10/15/30) | `settings_playback.dart:232-250` | `restartRewindSeconds`、`tempPlayRewindSeconds` | A/W | `lib/services/audio/audio_provider.dart:789,2304` | +| 播放歷史上限(1000~50000,預設 10000) | `settings_playback.dart:87-136` | `playHistoryLimit` | A/W | `lib/services/audio/play_history_recorder.dart:43`;預設 `settings.dart:209` | +| 自動匹配歌詞(預設關)+齒輪進歌詞來源設定 | `settings_playback.dart:155,165-189` | `autoMatchLyrics` | A/W | `lyrics_auto_match_coordinator.dart:57` | +| 圖片快取上限(16/32/48/64 MB)+清除 | `widgets/settings_cache.dart:36-114` | `maxCacheSizeMB` | A/W | `lib/providers/download/download_settings_provider.dart:70-112` | +| 歌詞快取檔數(10~200)+清除 | `settings_cache.dart:157-227` | `maxLyricsCacheFiles` | A/W | `download_settings_provider.dart:73`;`lib/providers/lyrics/lyrics_provider.dart:76` | +| 排行刷新間隔(30/60/120/240 分) | `settings_cache.dart:259-294` | `rankingRefreshIntervalMinutes` | A/W | `refresh_settings_provider.dart:50-80` | +| 電台刷新間隔(關/1/3/5/10 分) | `settings_cache.dart:323-358` | `radioRefreshIntervalMinutes` | A/W | `main.dart:251-255` | +| 下載路徑(**Android 不能改**,按鈕只在非 Android 顯示) | `widgets/settings_storage.dart:41-85` | `customDownloadDir` | 改路徑僅 W | `lib/services/download/download_path_manager.dart:73,93`;`download_path_utils.dart:193-195` | +| 同時下載數(1~5) | `settings_storage.dart:158-190` | `maxConcurrentDownloads` | A/W | `download_service.dart:426` | +| 下載圖片(無/只封面/封面+頭像) | `settings_storage.dart:217-264` | `downloadImageOptionIndex` | A/W | `download_service.dart:1568,1584` | +| 匯出/匯入備份(匯入可勾選要還原的類別,「設定」會整批覆寫) | `widgets/settings_backup.dart:7-57,128-232,300-355` | 多數 Settings 欄位 | A/W | `backup_service.dart` | +| 開機自啟、最小化啟動 | `widgets/settings_desktop.dart:30-99` | `launchAtStartup`、`launchMinimized` | W | `desktop_settings_provider.dart:108-145` | +| 關閉時縮到托盤(預設關) | `settings_desktop.dart:114-120` | `minimizeToTrayOnClose` | W | `desktop_settings_provider.dart:30-39` | +| 全域熱鍵開關(預設關)+逐項錄製/清除/全部重設 | `settings_desktop.dart:130-365` | `enableGlobalHotkeys`、`hotkeyConfig` | W | `windows_desktop_service.dart:267,294` | +| 音質(高/中/低) | `audio_settings_page.dart:207-221` | `audioQualityLevelIndex` | A/W | `lib/data/sources/base_source.dart:46` | +| 音訊格式優先序(拖曳) | `audio_settings_page.dart:282-305` | `audioFormatPriority` | A/W | 選流邏輯(未逐一追) | +| 各音源串流類型優先序(拖曳) | `audio_settings_page.dart:372-395` | `sourceSettings[].streamPriority` | A/W | 選流邏輯(未逐一追) | +| 各音源「播放時使用登入憑證」 | `audio_settings_page.dart:150-161` | `sourceSettings[].useAuthForPlay`(預設依音源:Bilibili、網易雲 true,YouTube false;`settings.dart:76-79,686-693`)(核查更正:原寫「預設 false」,那只是 `SourceSettingsEntry` 欄位初值,實際預設取自 `kDefaultUseAuthForPlayBySource`) | A/W | `lib/services/account/source_auth_context.dart:135` | +| 允許純文字歌詞自動匹配 | `lyrics_source_settings_page.dart:272-287` | `allowPlainLyricsAutoMatch` | A/W | `lyrics_auto_match_service.dart` | +| 歌詞來源優先序、個別啟用 | `lyrics_source_settings_page.dart:85-104,292-326,422` | `lyricsSourcePriority`、`disabledLyricsSources` | A/W | `lyrics_provider.dart:367,396,424` | +| AI 模式/端點/模型/逾時 | `lyrics_source_settings_page.dart:133-155,495-620` | `lyricsAiTitleParsingModeIndex`、`lyricsAiEndpoint`、`lyricsAiModel`、`lyricsAiTimeoutSeconds` | A/W | `lyrics_ai_config_service.dart:40-62` | +| AI API key(存 secure storage,不在 Settings) | `lyrics_source_settings_page.dart:157-166,552-574` | secure storage `lyrics_ai_api_key` | A/W | `lyrics_ai_config_service.dart:32,70-80` | +| 首頁排行來源順序、啟用(至少留一個) | `home_ranking_settings_page.dart:14-24,47-136` | `homeRankingSourcePriority`、`disabledHomeRankingSources` | A/W | 只影響顯示,見 §2 | +| 桌面歌詞樣式(文字色、次要色、非當前行透明度、外框、陰影、重設) | `lib/ui/widgets/lyrics/lyrics_style_dialog.dart:205-329` | `lyricsWindow*` 系列欄位 | W | `lib/services/lyrics/lyrics_window_style.dart` | +| 歌詞顯示模式 | `lib/ui/handlers/track_action_handler.dart:318-354` | `lyricsDisplayModeIndex` | A/W | `lyrics_provider.dart` | +| 輸出裝置 | `lib/ui/widgets/player/fmp_audio_device_selector.dart:38-93` | `preferredAudioDeviceId/Name` | W | `audio_provider.dart:1252-1289` | +| 導覽列、詳情面板展開與寬度(拖曳即存) | `lib/ui/layouts/responsive_scaffold.dart:391,486,516,577,605` | `railExpanded`、`detailPanelExpanded`、`detailPanelWidth` | 寬版版面 | `lib/providers/settings/layout_settings_provider.dart` | + +開發者模式與日誌級別**不是** `Settings` 欄位,重啟就消失(見 `devtools.md` §1)。帳號管理頁與下載管理頁不寫任何 `Settings` 欄位。 + +## 10. 桌面專屬(Windows) + +| 功能 | 入口 | 狀態 | 證據 | +|---|---|---|---| +| 自訂標題列(無系統標題列) | 自動 | 完整 | `lib/main.dart:317-330`(`TitleBarStyle.hidden`);`lib/app.dart:182-189` | +| 系統托盤與托盤選單 | 自動 | 完整 | `windows_desktop_service.dart:144-175,219-253` | +| 關閉視窗:啟用托盤時只隱藏,並在每次關閉時用 `tasklist` 掃描是否有名稱含 fmp + installer/setup 的程序,有就強制結束 app;未啟用托盤時直接結束 | 自動 | 完整 | `windows_desktop_service.dart:401-428,467-493` | +| 啟動時一律 `setPreventClose(true)`,再由托盤設定改寫 | 自動 | 完整 | `main.dart:340-342`;`lib/providers/settings/desktop_settings_provider.dart:32,39` | +| 開機自啟(可選是否帶 `--minimized` 直接進托盤) | 設定「桌面」 | 完整 | `main.dart:140,332-336`;`desktop_settings_provider.dart:132-145` | +| 全域熱鍵(8 個動作,預設 Ctrl+Alt+Space/→/←/S/↑/↓/M/W,可自訂) | 設定「桌面」,預設關(`enableGlobalHotkeys = false`) | 完整 | `hotkey_config.dart:9-17,212-257`;`windows_desktop_service.dart:282-362`;預設 `settings.dart:292` | +| SMTC 媒體控制 | 自動 | 完整 | `windows_smtc_handler.dart` | +| 桌面歌詞視窗 | 見 §6 | 完整 | `lyrics_window_service.dart:161-264` | +| 輸出裝置切換 | 迷你播放器 | 完整 | `fmp_audio_device_selector.dart` | + +## 11. 更新 + +| 功能 | 入口 | 平台 | 狀態 | 證據 | +|---|---|---|---|---| +| 檢查更新(查 GitHub `1morr/FMP` 最新 release) | 設定「關於→檢查更新」,**只有手動**,沒有啟動或定時檢查(grep `checkForUpdate` 只有 `settings_about.dart:70` 一個 UI 呼叫點) | A/W | 完整 | `lib/services/update/update_service.dart:18-19,389-400`;`lib/providers/system/update_provider.dart:80` | +| 下載並安裝(Android:下載 APK → 系統安裝器;Windows 安裝版:靜默執行安裝程式並結束 app;Windows 免安裝版:解壓後用隱藏的 bat 覆蓋程式目錄並重啟) | 更新對話框按鈕 | A/W | 完整 | `update_service.dart:515-684`;細節見 §15.3 | +| 在瀏覽器開 release 頁 | 更新對話框 | A/W | 完整 | `update_dialog.dart:216` | +| 啟動時清理 Temp 裡的舊更新檔 | 自動 | W | 完整 | `main.dart:231`;`update_service.dart:257-290` | + +註釋說自動檢查更新(`autoCheckUpdates`)在 2026-09 被移除(`lib/services/backup/backup_service.dart:29-30`、`lib/data/database/database_migration.dart:224`),與程式現況一致:grep `autoCheckUpdate` 只剩這兩行註釋。 + +## 12. 備份 + +| 功能 | 入口 | 平台 | 狀態 | 證據 | +|---|---|---|---|---| +| 匯出 JSON 備份:歌單、曲目、播放歷史、搜尋歷史、電台、設定(含 AI 端點與模型名)、歌詞匹配 | 設定「備份→匯出」 | A/W | 完整 | `lib/services/backup/backup_service.dart:51-91`;`backup_data.dart:13,164,267,373,425,444,592,858` | +| 備份**不含**:帳號與 Cookie、AI API key(它們在 secure storage) | — | — | — | `backup_data.dart` 無 Account 類別;key 存 `lib/services/lyrics/lyrics_ai_config_service.dart:32,70-80` | +| 匯入備份(選檔、驗證、合併) | 設定「備份→匯入」 | A/W | 完整 | `backup_service.dart:339-371` | + +--- + +## 13. 背景行為 + +### 13.1 啟動時做的事 + +`main()`(`lib/main.dart:94-281`)依序: + +1. 子視窗入口判斷:參數是 `multi_window` 就改跑桌面歌詞視窗(`:96-99`)。 +2. 掛全域錯誤處理器(`:102-123`),進 `runZonedGuarded`。 +3. 啟用 log 落盤(`:134-138`)。 +4. 讀 `--minimized`(`:140`)、初始化 i18n(`:147`)。 +5. **打開 Isar 並預讀主題設定**(`:150`、`:372-393`)。 +6. 設定圖片記憶體快取上限(`:156-164`)。 +7. Android:`AudioService.init` 建媒體通知頻道(`:167-195`)。 +8. Windows:`MediaKit.ensureInitialized`(`:202-216`)、並行初始化 SMTC 與視窗管理器(`:219-229`)、**清理舊更新檔**(`:231`)。 +9. 登記第三方授權(`:243`)。 +10. 第一幀之後:建立 `RadioRefreshService`(間隔取自預讀設定),掛 app 生命週期觀察者,背景時暫停輪詢(`:247-259`、`:347-364`)。 +11. `runApp`(`:261-274`);Riverpod 自動重試被關掉(`:268`)。 + +`FMPApp.build`(`lib/app.dart:93-131`)在 DB 開好後 watch 下列 provider,等於啟動就跑: + +| Provider | 做什麼 | 證據 | +|---|---|---| +| `windowsDesktopServiceProvider`、`minimizeToTrayProvider`、`globalHotkeysEnabledProvider`、`launchAtStartupProvider`、`hotkeyConfigProvider` | Windows 托盤、關閉行為、熱鍵、開機自啟 | `app.dart:95-104` | +| `themeProvider`、`localeProvider`、`playbackSettingsProvider` | 設定載入 | `app.dart:107-116` | +| `refreshSettingsProvider` | 把排行刷新間隔推給 `RankingCacheService`,**間接啟動排行抓取** | `app.dart:119`;`lib/providers/settings/refresh_settings_provider.dart:50-64` | +| `autoRefreshServiceProvider` | 啟動歌單自動刷新,**立刻檢查一次** | `app.dart:122`;`auto_refresh_service.dart:37-38,143-158` | +| `accountStatusCheckProvider` | B 站 Cookie 刷新,接著依序檢查三平台帳號 | `app.dart:125`;`account_provider.dart:131-174` | +| `accountSessionExpiryWatcherProvider` | 監看帳號列轉成失效時提示 | `app.dart:128` | +| `startupDownloadSyncProvider` | 掃描下載目錄同步檔案狀態 | `app.dart:131` | + +這份清單由 `test/providers/static_rules/riverpod3_static_rule_test.dart:11-26` 用集合比對守著。 + +```mermaid +flowchart LR + M[main] --> DB[(開 Isar 預讀設定)] + M --> AS[Android: AudioService 通知] + M --> WIN[Windows: SMTC / 視窗 / 清舊更新檔] + M --> RA[runApp] + RA -. 第一幀後 .-> RR[RadioRefreshService
等 RadioController 啟動輪詢] + RA --> APP[FMPApp.build
DB 開好後] + APP --> T1[排行快取
每 60 分] + APP --> T2[歌單自動刷新
每 30 分檢查] + APP --> T3[B 站 Cookie 刷新
+ 三平台帳號檢查] + APP --> T4[下載目錄同步] + APP --> T5[Windows 托盤/熱鍵/開機自啟] + T1 --> NET[連通性偵測
每 15 秒 DNS] + HOME[首頁電台區塊] --> RC[RadioController] --> RR + QM[佇列初始化] --> Q1[每 10 秒存位置] + QM --> Q2[10 秒後刪孤兒 Track] +``` + +### 13.2 定時器與輪詢 + +| 行為 | 週期 | 何時跑 | 對外請求 | 證據 | +|---|---|---|---|---| +| 匯入歌單自動刷新 | 每 30 分鐘檢查;個別歌單依自己的 `refreshIntervalHours`(新建預設 24 小時),一次只刷一個,間隔 5 秒 | app 開著就跑(不看前景背景) | B/Y/N 歌單 API | `auto_refresh_service.dart:41-44,97-107`;`lib/core/constants/app_constants.dart:151`;`lib/data/models/playlist.dart:76-83`;`create_playlist_dialog.dart:61` | +| 首頁排行快取刷新 | 預設 60 分鐘;單一榜單失敗依退避重試;網路恢復時重抓 | 啟動就跑 | B/Y/N 排行 API | `lib/services/cache/ranking_cache_service.dart:12-23,149,208-215,306`;預設 `refresh_settings_provider.dart:14` | +| 電台直播狀態輪詢 | 預設 5 分鐘,可設關閉;被風控時退避(上限 30 分鐘);app 進背景時暫停 | `RadioController` 呼叫 `setRepository` 後開始(首頁的電台區塊就會觸發) | Bilibili 直播 API | `lib/services/radio/radio_refresh_service.dart:12-26,34,92-130`;生命週期 `main.dart:347-364` | +| 電台播放中:每秒更新時長、每分鐘刷新高能用戶數 | 1 秒/1 分鐘 | 播電台時 | Bilibili 直播 API | `radio_controller.dart:968-983` | +| 網路連通性偵測 | 每 15 秒解析 `dns.google`、`one.one.one.one`、`dns.alidns.com`(任一成功即算有網路) | 啟動後一直跑 | 系統 DNS 查詢 | `lib/services/network/connectivity_service.dart:52-56,73-76,102-116`;`app_constants.dart:154` | +| 下載調度 | 每 5 秒(加事件觸發);進度每 1 秒彙整 | 下載服務建立後一直跑 | 下載 CDN | `download_service.dart:348-358,391-406` | +| 播放位置存檔 | 每 10 秒 | 佇列初始化後 | 無 | `queue_manager.dart:819-823`;`app_constants.dart:54` | +| 播放位置檢查(判斷播完) | 每 1 秒 | 播放中 | 無 | `audio_provider.dart:1304-1311` | +| 圖片磁碟快取修剪 | 載入圖片累積到門檻後防抖觸發 | 圖片載入時 | 無 | `lib/core/services/network_image_cache_service.dart:221-250` | +| 歌詞快取寫入防抖、超量淘汰 | 事件觸發 | — | 無 | `lyrics_cache_service.dart:19-29,315` | +| 評論輪播 | 每 10 秒 | 評論區可見時 | 無(資料已抓) | `lib/ui/widgets/panels/comment_pager.dart:98` | + +**不一致**:`auto_refresh_service.dart:13` 的類別註解說「每小时检查一次」,同檔 `:40` 註解與 `app_constants.dart:151` 的實際值是 30 分鐘。 + +### 13.3 清理任務 + +| 行為 | 證據 | +|---|---| +| 啟動 10 秒後刪除孤兒 Track(不在任何歌單、不在佇列;播放歷史與歌詞匹配記錄保留) | `queue_manager.dart:219-229`;`track_repository.dart:630-673` | +| 下載服務啟動時清掉已完成/失敗的任務、刪孤兒 `.downloading` 檔 | `download_service.dart:206-220,230-240` | +| Windows 啟動時刪 Temp 裡的 `fmp-*.exe`、`fmp-*.zip`、`fmp_updater.*`、`fmp_update/` | `update_service.dart:257-290` | +| Android 下載新 APK 前刪舊 APK | `update_service.dart:550,567-585` | +| 圖片與歌詞快取依上限淘汰 | 見上表 | + +### 13.4 背景下載 + +只有使用者觸發的曲目下載會在背景跑(調度器每 5 秒檢查)。**不會**自動下載更新、**不會**自動續傳上次中斷的下載(啟動時全部轉成暫停,`download_service.dart:214-215`)。 + +### 13.5 自動更新 + +沒有。更新只能從設定頁手動檢查(§11)。 + +--- + +## 14. 死代碼與無 UI 入口彙整 + +| 項目 | 判定 | grep 與證據 | +|---|---|---| +| `AutoRefreshService.checkNow()` | 死代碼 | `checkNow` 在 `lib/`、`test/` 只有定義 `auto_refresh_service.dart:130` | +| `DeveloperOptionsNotifier.reset()` | 死代碼 | `developerOptionsProvider.notifier).reset` 無結果;定義 `lib/providers/settings/developer_options_provider.dart:70` | +| `DataIntegrityRepository.scan()` / `repair()` | 無 UI 入口(只有測試用) | `DataIntegrityRepository\|\.repair()` 在 `lib/` 只命中定義與 `developer_options_page.dart:551` 的 `clearEverything`;測試 `test/data/repositories/data_integrity_repository_test.dart` | +| `DownloadPathSyncService.cleanupInvalidPaths()` | 死代碼 | `download_path_sync_service.dart:313` | +| `RadioRefreshService.refreshStation()` | 死代碼 | `radio_refresh_service.dart:260` | +| `RadioController.toggleFavorite()` 與 `RadioStation.isFavorite`(連同 `RadioRepository.getFavorites()`) | 無 UI 入口 | `radio_controller.dart:795`;`radio_station.dart:50`;`radio_repository.dart:103` | +| `BilibiliFavoritesService.batchRemoveFromFolder()` | 死代碼(遠端批次刪除走 `updateVideoFavorites`) | grep `batchRemoveFromFolder` 在 `lib/`、`test/` 只有定義 `lib/services/account/bilibili_favorites_service.dart:187` | +| 開發者選項頁「除錯模式:已啟用」 | 半成品(恆真的裝飾列) | `lib/ui/pages/settings/developer_options_page.dart:69-77` | + +`Settings` 裡沒有 UI 入口的欄位(grep 欄位名於 `lib/ui` 無結果,只出現在遷移、備份、DB 檢視器): + +| 欄位 | 判定 | 證據 | +|---|---|---| +| `schemaVersion` | 內部欄位,合理 | `lib/data/models/settings.dart:221` | +| `youtubeStreamPriority`、`bilibiliStreamPriority`、`neteaseStreamPriority` | `@Deprecated`,只為遷移與舊備份相容保留;已由 `sourceSettings` 取代 | `settings.dart:324,330,336` | +| `useBilibiliAuthForPlay`、`useYoutubeAuthForPlay`、`useNeteaseAuthForPlay` | 同上 | `settings.dart:417,423,429` | + +--- + +## 15. 你很可能不知道的功能 + +### 15.1 會對外寫入的 + +| 行為 | 什麼時候發生 | 端點 | 證據 | +|---|---|---|---| +| B 站:建立收藏夾 | 「加入遠端」對話框裡按新建 | `POST /x/v3/fav/folder/add` | `bilibili_favorites_service.dart:117-131`;UI `add_to_bilibili_playlist_dialog.dart:61-75` | +| B 站:影片加入/移出收藏夾 | 「加入遠端」勾選變更;**從匯入的 B 站收藏夾歌單刪曲目** | `POST /x/v3/fav/resource/deal` | `bilibili_favorites_service.dart:154-168`;`remote_playlist_sync_provider.dart:47-50` | +| YouTube:加入/移出播放清單 | 同上(YouTube 歌單) | `POST /youtubei/v1/browse/edit_playlist` | `lib/services/account/youtube_playlist_service.dart:88-111` | +| YouTube:建立播放清單 | 對話框新建 | `POST /youtubei/v1/playlist/create` | `youtube_playlist_service.dart:218-223` | +| 網易雲:建立歌單、加入/移出曲目 | 同上(網易雲歌單) | `playlist/create`、`playlist/manipulate/tracks`,經 linux API 加密轉送,並附偽造的 `X-Real-IP: 118.88.88.88` | `lib/services/account/netease_playlist_service.dart:101-106,146-188,240-253` | +| **B 站 Cookie 自動刷新** | 每次啟動(已登入時);伺服器回報需要刷新才真的換 | `GET cookie/info` → `GET /correspond/1/...` → `POST cookie/refresh` → `POST confirm/refresh`(舊 refresh_token 作廢) | `account_provider.dart:131-152`;`bilibili_account_service.dart:350-444` | +| 播放紀錄上報、心跳、按讚、投幣、點擊統計 | **查不到**。grep `heartbeat\|history/report\|scrobble\|click-interface\|/like\|thumbup\|coin` 在 `lib/data/sources`、`lib/services/account`、`lib/services/library` 只命中讀取用的 `coin` 統計欄位(`lib/data/sources/bilibili_source.dart:792`) | — | — | + +移除匯入歌單的曲目時會先跳確認框(`t.remote.confirmRemove`,`playlist_detail_page.dart:565-573`),但「在本機歌單刪曲目=在平台刪曲目」這件事只在確認框文案裡說。 + +### 15.2 會把資料送到第三方的(非三個主音源) + +| 對象 | 何時 | 送了什麼 | 證據 | +|---|---|---|---| +| **使用者設定的 OpenAI 相容端點** | 開啟 AI 模式(預設關)且自動匹配歌詞開啟時,每首新歌 | `Authorization: Bearer `;標題解析:影片標題、上傳者;候選選擇:標題、上傳者、**影片描述**、時長、音源優先序、每個候選的曲名/歌手/專輯/時長/**歌詞預覽** | `lib/services/lyrics/openai_chat_client.dart:41-67`;`ai_title_parser.dart:41-60`;`ai_lyrics_selector.dart:42-55,106-137` | +| QQ 音樂(`u.y.qq.com`) | 歌詞搜尋(自動或手動) | 曲名、歌手查詢字串 | `lib/services/lyrics/qqmusic_source.dart:145,187` | +| QQ 音樂(`u6.y.qq.com`) | 匯入 QQ 音樂歌單 | 歌單 id(帶簽章) | `lib/data/sources/playlist_import/qq_music_playlist_source.dart:144-162` | +| Spotify(`open.spotify.com/embed`) | 匯入 Spotify 歌單 | 歌單 id | `lib/data/sources/playlist_import/spotify_playlist_source.dart:57-59` | +| lrclib.net | 歌詞搜尋;**預設停用**(`disabledLyricsSources = 'lrclib'`) | 曲名、歌手;User-Agent 寫 `FMP/1.0.0 (https://github.com/user/fmp)`(佔位網址,**不一致**) | `lib/services/lyrics/lrclib_source.dart:24`;`settings.dart:361` | +| GitHub API(`api.github.com/repos/1morr/FMP/releases/latest`)與 release 資產 | 手動檢查更新、下載更新 | 無使用者資料(一般 HTTP 請求) | `update_service.dart:389-400,755-775` | +| 公共 DNS 名稱(`dns.google`、`one.one.one.one`、`dns.alidns.com`) | 每 15 秒 | 經系統解析器查這三個名稱(不是直接連 DNS 伺服器) | `connectivity_service.dart:52-56,102-116` | +| 外部瀏覽器 | 點影片、頻道、直播間、UP 主空間、release 頁 | 對應 URL | `lib/services/platform/url_launcher_service.dart`;呼叫處如 `player_page.dart:900,978` | + +沒有分析、統計或崩潰回報套件:`pubspec.yaml` 的 dependencies 裡沒有 firebase/sentry/crashlytics/analytics/telemetry,`lib/` 也查不到。 + +附帶一提(與第三方無關,但使用者多半不知道):B 站匿名請求會自己產生 `buvid3`/`buvid4`/`b_nut` 等瀏覽器指紋 cookie(`bilibili_source.dart:92-146`);YouTube 登入頁會注入 JS 呼叫 `accounts_list` 取帳號名稱(`youtube_login_page.dart:238-260`)。 + +### 15.3 會自己下載或執行東西的 + +| 行為 | 觸發 | 細節 | 證據 | +|---|---|---|---| +| Windows 安裝版更新 | 更新對話框按「更新」 | 下載 `fmp--windows-installer.exe` 到 Temp,以 `/SILENT /DIR=<目前程式目錄> /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS` 啟動,接著 `exit(0)` | `update_service.dart:587-619` | +| Windows 免安裝版更新 | 同上 | 下載 zip、在 isolate 解壓到 Temp,寫出 `fmp_updater.bat` 與 `.vbs`,用 `wscript` **隱藏視窗**執行;bat 等原程序結束後 `robocopy` 備份程式目錄、覆蓋、重啟,失敗就還原 | `update_service.dart:624-684,830-876` | +| Android 更新 | 同上 | 下載 APK 到 cache,用 `OpenFilex` 開系統安裝器;需要時導去「安裝未知來源」權限頁 | `update_service.dart:540-565,247-254,295-306` | +| 更新檔完整性 | — | 只有 release 附 `*-checksums.sha256` 時才驗 SHA-256;沒附就只比對大小(GitHub 有回報時) | `update_service.dart:462-470,776-783,800-826` | +| 執行外部指令 | Android 檢查更新時 | `Process.run('getprop', ['ro.product.cpu.abi'])` | `update_service.dart:64-68` | +| 執行外部指令 | Windows 每次關閉視窗(托盤模式) | `Process.run('tasklist', ...)` 找安裝程式 | `windows_desktop_service.dart:470-493` | +| 伴隨下載的圖片 | 每次下載曲目 | 在音檔旁寫 metadata JSON、下載封面與 UP 主頭像 | `download_service.dart:1509-1590` | + +libmpv/FFmpeg 的 Windows 二進位是建置時下載,執行期不會下載(`main.dart:241-243` 的註解)。 + +--- + +## 16. 其他不一致 + +| 項目 | 證據 | +|---|---| +| `import_playlist_dialog.dart` 註解說網易雲是外部來源,程式把它當內部來源 | `:26-29,69-73` vs `:159-176` | +| `auto_refresh_service.dart` 註解說每小時,實際 30 分鐘 | `:13` vs `:40`、`app_constants.dart:151` | +| lrclib User-Agent 是佔位網址 `github.com/user/fmp` | `lrclib_source.dart:24` | +| `LyricsAiTitleParsingMode` 只有 3 個值,存的 index 卻是 0/2/3(1 被跳過:git 歷史確認 index 1 原是 `fallbackAfterRules`,見 `95ca53c6` 的原始 enum,後由 `d9b81d8a`「remove stale fallback AI mode references」移除;讀到 1 時當 off) | `settings.dart:163,658-679`(核查更正:原標「**推測**是移除過的模式」,已由 git 歷史確認) | diff --git a/docs/audit/perf-baseline.md b/docs/audit/perf-baseline.md new file mode 100644 index 000000000..82a594359 --- /dev/null +++ b/docs/audit/perf-baseline.md @@ -0,0 +1,217 @@ +# 效能基準(重寫前) + +> 現況描述,未經確認,不代表目標。 + +量測日期:2026-09-26,分支 `docs/audit`(HEAD `6d78fe23`)。這份文件是重寫後的比較基準:每個數字都附量測命令與原始輸出摘錄,重寫後用同一組命令重量即可對照。 + +## 量測環境 + +| 項目 | 值 | +|------|----| +| 主機 | Intel Core i9-13900HX(24C/32T)、31.8 GB RAM、NVIDIA RTX 4080 Laptop GPU | +| 主機 OS | Windows 11 專業工作站版 build 26200;主螢幕 2560×1440、縮放 150%(FMP 視窗 DPI 144) | +| Flutter | 3.47.1 stable(framework `6655482ec0`、engine `11d79658c4`)、Dart 3.13.1 | +| Build mode | **profile**(Android `app-profile.apk` 47.5 MB;Windows `build\windows\x64\runner\Profile\fmp.exe`) | +| Android emulator | AVD `Medium_Phone`:API 37(`android-37.2-beta3` google_apis_playstore ps16k x86_64)、4 vCPU、2048 MB RAM、1080×2400 @ 420 dpi、`hw.gpu.mode=auto`(GPU 由主機模擬) | +| Android App 資料 | emulator 內既有測試資料:2 個歌單(154 首 + 1 首)、15 筆播放歷史、佇列空 | +| Windows App 資料 | **使用者真實資料**:profile build 走 `getApplicationDocumentsDirectory()` = `C:\Users\\Documents\FMP\`(`lib/data/database/database_provider.dart:49-52`),1 個 1195 首的歌單、佇列 1195 首、有目前曲目 | +| 網路 | 兩平台首頁都會自動載入三個音源的排行榜(Bilibili / YouTube / 網易雲)與封面;Windows 右側 Detail Panel 另載入目前曲目的資訊與評論。這些請求無法避免,數字包含它們 | + +注意事項: + +- emulator 的 CPU、GPU 都是虛擬的,**Android 數字只能跟同一台主機、同一個 AVD 比**,不代表實機。 +- 兩個平台的資料量不同(Windows 有 1195 首佇列與目前曲目、Android 佇列空),所以兩平台之間的數字不能直接比較。 +- 同一時段另有其他 agent 在同一個 checkout 跑 `build_runner` / `flutter test`(codegen 開始時曾出現 `Waiting for already-running build_runner.`),主機不是完全閒置。 + +## 摘要 + +| 指標 | Android(Medium_Phone) | Windows | +|------|------------------------|---------| +| 冷啟動到首幀 `timeToFirstFrameMicros`(`--trace-startup`,3 次中位數) | **1239 ms** | **1731 ms** | +| 首幀完成光柵化 `timeToFirstFrameRasterizedMicros`(中位數) | 1292 ms | 1752 ms | +| `am start -W` TotalTime(3 次中位數) | 1482 ms | — | +| 首頁穩定後記憶體(3 次中位數) | PSS **183,367 KB**(≈179 MB)/RSS 310,752 KB | Working Set **299.9 MB**/Private **440.6 MB** | +| 長列表捲動,UI thread 每幀 `Animator::BeginFrame` 中位數/p99 | 1.00 ms/4.18 ms(歌單 154 首) | 0.45 ms/5.45 ms(佇列 1195 首) | +| 長列表捲動,raster 每幀 `GPURasterizer::Draw` 中位數/p99 | 4.27 ms/21.62 ms | 1.96 ms/2.72 ms | +| 捲動中超過 16.7 ms 的 raster 幀 | 43/302(第 1 輪)、17/306(第 2 輪) | 0/312、0/316 | + +## 1. 啟動時間 + +### 方法 A:`flutter run --profile --trace-startup`(兩平台) + +量的是 engine 進入點到 Dart 首幀(`timeToFirstFrameMicros`)與首幀光柵化完成(`timeToFirstFrameRasterizedMicros`)。每次跑完 App 會自行結束,`build/start_up_info.json` 被覆寫,所以每次跑完立刻複製一份。Android 每次之間先 `adb shell am force-stop com.personal.fmp`;Windows 每次之間程序已結束。 + +```bash +# Android +adb shell am force-stop com.personal.fmp +flutter run --profile --trace-startup -d emulator-5554 +cp build/start_up_info.json /android_startup.json +# Windows +flutter run --profile --trace-startup -d windows +cp build/start_up_info.json /win_startup.json +``` + +原始輸出(µs): + +| 次 | 平台 | timeToFrameworkInit | timeToFirstFrame | timeToFirstFrameRasterized | timeAfterFrameworkInit | +|----|------|--------------------:|-----------------:|---------------------------:|-----------------------:| +| 1 | Android | 380,399 | 1,245,787 | 1,354,611 | 865,388 | +| 2 | Android | 371,942 | 1,238,945 | 1,292,482 | 867,003 | +| 3 | Android | 252,215 | 875,541 | 936,132 | 623,326 | +| 1 | Windows | 1,286,636 | 2,322,241 | 2,346,683 | 1,035,605 | +| 2 | Windows | 1,350,721 | 1,730,724 | 1,751,879 | 380,003 | +| 3 | Windows | 1,332,404 | 1,676,262 | 1,717,516 | 343,858 | + +終端摘錄:`Time to first frame: 1245ms.` / `1238ms.` / `875ms.`(Android);`Time to first frame: 2322ms.` / `1730ms.` / `1676ms.`(Windows)。 + +觀察: + +- Windows 第 1 次是剛建完 profile build 後的第一次啟動,`timeAfterFrameworkInit` 比後兩次多約 0.65 s。**推測**是檔案系統與 DLL 冷快取;後兩次較能代表常態。 +- Windows 的 `timeToFrameworkInit` 穩定在 1.29–1.35 s,佔首幀時間的 77–80%;Android 只有 0.25–0.38 s。`WidgetsFlutterBinding.ensureInitialized()` 在 `main()` 很前面就呼叫(`lib/main.dart:129`),所以這段時間主要花在 Dart 之前。**推測**是 Windows runner 的原生 plugin 註冊(webview、media_kit、SMTC 等)與 engine 啟動,本次沒有拆解。 +- Android 第 3 次明顯較快(875 ms),三次差距大。emulator 的變異性高,重寫後比較時建議量 5 次以上。 + +### 方法 B:`adb shell am start -W`(僅 Android) + +量的是 Activity 冷啟動到第一個視窗繪製(`TotalTime`)。Flutter 的 Activity 視窗可能在 Dart 首幀之前就算「已繪製」,所以它跟方法 A 不是同一個終點。 + +```bash +adb shell am force-stop com.personal.fmp; adb shell sleep 3 +adb shell am start -W -n com.personal.fmp/.MainActivity +``` + +| 次 | LaunchState | TotalTime | WaitTime | +|----|-------------|----------:|---------:| +| 1 | COLD | 1482 | 1489 | +| 2 | COLD | 1331 | 1334 | +| 3 | COLD | 1677 | 1680 | +| 4(量記憶體時順帶) | COLD | 1458 | — | +| 5(量記憶體時順帶) | COLD | 1415 | — | + +前 3 次中位數 1482 ms;5 次中位數 1458 ms。 + +## 2. 記憶體 + +### Android:`dumpsys meminfo` + +冷啟動後停在首頁,等 20–28 秒(排行榜與封面載入完)才取樣。 + +```bash +adb shell am force-stop com.personal.fmp; adb shell am start -W -n com.personal.fmp/.MainActivity +adb shell sleep 28 +adb shell dumpsys meminfo com.personal.fmp +``` + +| 取樣 | TOTAL PSS (KB) | TOTAL RSS (KB) | +|------|---------------:|---------------:| +| 1(啟動後約 20 s) | 183,367 | 310,752 | +| 2(啟動後約 28 s) | 185,178 | 312,024 | +| 3(啟動後約 28 s) | 180,843 | 307,716 | + +取樣 2 的 App Summary 摘錄: + +``` + Java Heap: 10936 36076 + Native Heap: 41556 45984 + Code: 53028 158028 + Stack: 1248 1256 + Graphics: 0 0 + Private Other: 62372 + System: 16038 + TOTAL PSS: 185178 TOTAL RSS: 312024 TOTAL SWAP (KB): 0 +``` + +`Graphics: 0` 是 emulator 的 GPU 由主機模擬所致,實機會有數十 MB,不能拿來當實機的圖形記憶體基準。 + +### Windows:`Get-Process` + +Working Set 是實體記憶體駐留量,Private 是 commit 的私有位元組(含未駐留部分)。 + +```powershell +Get-Process fmp | Select-Object Id, WorkingSet64, PrivateMemorySize64, PeakWorkingSet64 +``` + +| 取樣 | Working Set | Private | 備註 | +|------|------------:|--------:|------| +| 1 | 281.0 MB | 416.5 MB | 啟動後約 1 分鐘;Peak WS 297.2 MB | +| 2 | 299.9 MB | 440.6 MB | 首幀後 30 s | +| 3 | 307.1 MB | 446.6 MB | 首幀後 30 s | + +中位數:Working Set 299.9 MB,Private 440.6 MB。Windows 載入了 1195 首的佇列與 Detail Panel 的封面、評論,這些都算在裡面。 + +## 3. 長列表捲動 + +### 3.1 `test/performance/` 下的兩支 benchmark + +兩支都**不叫 `*_test.dart`**,檔頭註解說明它們量的是絕對時間,只在閒置機器上手動跑(`test/performance/startup_benchmark.dart:6-15`)。它們跑在 `flutter test` 的主機 VM 上(debug JIT、無真正的 GPU),**量不到 App 的實際 UI**: + +- `list_scrolling_benchmark.dart`:用產生的 `Track` 建 **Material 內建的 `ListTile`** 或手寫的仿列(`:150` 起),不是 FMP 的 `TrackTile`;只 import `track.dart`。 +- `startup_benchmark.dart`:量 `Track` 建構、字串處理、`Directory.exists` 等微操作,不涉及 App 啟動流程。名稱中的「startup」與內容不一致。 +- 兩支都沒有網路存取,可離線跑。 + +```bash +flutter test test/performance/list_scrolling_benchmark.dart test/performance/startup_benchmark.dart -r expanded +# 00:03 +13: All tests passed! +``` + +輸出摘錄: + +``` +Created 1000 Track models in 4ms +Extracted display names 50000 times in 6ms +Performed 300000 date operations in 37ms +Performed 2000000 string operations in 433ms +Initial render of 100 items: 506ms +Initial render of 500 items: 76ms +10 scroll operations with 1000 items: 392ms (Average: 39.2ms per scroll) +Complex list item render (100 items): 213ms +Checked 10000 directory existence in 1482ms +Performed 200000 path operations in 122ms +100 widget rebuilds: 1155ms (Average: 11.55ms per rebuild) +Filtered and sorted 10000 tracks in 14ms +500 searches on 5000 tracks: 602ms +``` + +「100 items 506 ms、500 items 76 ms」這種倒掛說明第一個 `testWidgets` 吃到了 JIT 暖機,這些數字對重寫的參考價值低。 + +### 3.2 App 內實測:VM Service timeline + +`adb shell dumpsys gfxinfo com.personal.fmp` 對 Flutter 無效:捲動後 `Total frames rendered: 0`。Flutter 畫在 `SurfaceView` 上,不經過 HWUI 的統計。所以改用 VM Service 錄 timeline:`flutter run --profile` 起 App,對 `setVMTimelineFlags`(`["Dart","Embedder","GC"]`)→ `clearVMTimeline` → 操作 → `getVMTimeline`,再統計每幀的 `Animator::BeginFrame`(UI thread:build + layout + paint)與 `GPURasterizer::Draw`(raster thread)耗時。統計腳本放在 scratchpad(`timeline.py`),邏輯是對同名事件配對 `B`/`E` 或讀 `X` 的 `dur`。 + +**Android**:歌單詳情頁(154 首),每輪 8 次向下、8 次向上 `adb shell input swipe 540 2000 540 500 150`,間隔 0.8 s。 + +``` +== pass 1 +Animator::BeginFrame: n=303 median=1.00ms p90=1.92ms p99=4.18ms max=6.32ms >16.7ms=0 +GPURasterizer::Draw: n=302 median=4.27ms p90=17.16ms p99=21.62ms max=25.76ms >16.7ms=43 +== pass 2 +Animator::BeginFrame: n=308 median=0.81ms p90=1.66ms p99=4.01ms max=5.39ms >16.7ms=0 +GPURasterizer::Draw: n=306 median=3.67ms p90=12.68ms p99=20.99ms max=35.56ms >16.7ms=17 +``` + +**Windows**:佇列頁(1195 首),1904×1191 視窗,滑鼠滾輪向下 40 格、再向上 40 格(每格 `WHEEL_DELTA`×3,間隔 60 ms)。 + +``` +== pass 1 +Animator::BeginFrame: n=313 median=0.45ms p90=1.06ms p99=5.45ms max=8.03ms >16.7ms=0 +GPURasterizer::Draw: n=312 median=1.96ms p90=2.26ms p99=2.72ms max=10.00ms >16.7ms=0 +== pass 2 +Animator::BeginFrame: n=315 median=0.41ms p90=1.07ms p99=5.01ms max=10.41ms >16.7ms=0 +GPURasterizer::Draw: n=316 median=1.89ms p90=2.11ms p99=2.37ms max=2.58ms >16.7ms=0 +``` + +觀察: + +- 兩平台的 UI thread 都遠低於 16.7 ms 預算,捲動卡頓(若有)不在 Dart 端。 +- Android 的 raster 尾端(p90 12–17 ms、最高 35 ms)落在 emulator 的軟體/轉譯 GPU 上,**推測**不代表實機;但 timeline 裡 `Canvas::saveLayer` 在約 303 幀內出現 2040 次(約每幀 6.7 次),同一頁在 Windows 沒有進入前 25 名。saveLayer 在實機上同樣昂貴,來源(`Opacity`、帶抗鋸齒的 clip、`ShaderMask` 之類)本次沒有追查,值得在重寫時用實機 DevTools 確認。 +- Windows timeline 每幀有約 4 個 `Semantics.*` 事件(313 幀 1252 次):Windows 上無障礙樹一直處於啟用狀態,每幀都在更新語意節點。 + +## 4. 沒做到的項目 + +| 項目 | 原因 | +|------|------| +| 實機(非 emulator)Android 數字 | 本機沒有接實機 | +| Android 的 `Graphics` 記憶體、raster 時間的實機意義 | emulator 的 GPU 由主機模擬,`Graphics: 0` | +| `gfxinfo` 幀統計 | Flutter 走 `SurfaceView`,`Total frames rendered: 0`,改用 VM Service timeline | +| DevTools 圖形介面的 frame chart | 用 VM Service HTTP 端點取同一份 timeline 取代,沒有開 DevTools 網頁 | +| 播放中的 CPU/記憶體 | 任務要求不主動播放;Android 佇列空 | +| Windows 乾淨資料的基準 | profile build 讀使用者真實的 `Documents\FMP`,沒有獨立資料目錄的開關(見 `docs/audit/ui.md` § 6.0) | diff --git a/docs/audit/platforms.md b/docs/audit/platforms.md new file mode 100644 index 000000000..0f46cb375 --- /dev/null +++ b/docs/audit/platforms.md @@ -0,0 +1,413 @@ +# 平台現況審計 + +> 現況描述,未經確認,不代表目標。 + +- 審計基準:分支 `docs/audit`,HEAD `6d78fe23`,2026-09-26。 +- 範圍:`lib/`(排除 `*.g.dart`)、`android/`、`windows/`、`pubspec.yaml` / `pubspec.lock`、`.github/workflows/`。 +- 證據優先序:實際執行行為 > 程式碼 > 測試 > 文檔/註釋。本次**沒有實際執行**任何平台建置,所有「落到 iOS / macOS / Linux 會怎樣」都是讀程式碼推導的,標**推測**。 +- 套件平台支援:一律取自 pub.dev(`/api/packages//score` 的 `platform:*` 標籤、`/api/packages//versions/` 的 `flutter.plugin.platforms`),以及本機 pub cache 中 lock 版本的原始碼/README。取資料日 2026-09-26。 + +## 0. 摘要 + +- repo 只有 `android/` 與 `windows/` 兩個原生目錄,沒有 `linux/`、`macos/`、`ios/`(`ls` 結果;`docs/adr/0003-two-audio-backends.md:32` 也這樣寫)。CI 與 release 只建 APK 與 Windows(`.github/workflows/ci.yml:122,155`、`release.yml:155,256`)。README 徽章寫 `Android | Windows`(`README.md:9`)。 +- 平台判斷共 **88 處決策點**(grep 原始命中 103 行,扣掉註解、helper 定義與測試覆寫管線):81 處直接用 `Platform.isX` 或 `isDesktopPlatform`,7 處經 `AudioRuntimePlatform` 間接判斷。另有 2 處 Android SDK 版本判斷。全 repo 沒有 `kIsWeb`、`defaultTargetPlatform`、`TargetPlatform.` 的使用。 +- 判斷寫法有三種並存:`Platform.isWindows` 直接判斷(最多)、`isDesktopPlatform`(`lib/core/utils/platform_utils.dart:7`,Windows/macOS/Linux 都算),以及 `AudioRuntimePlatform`(`lib/services/audio/audio_runtime_platform.dart:7-19`,mobile / desktop 二分,未知 OS 落 desktop)。同一個功能常同時用到其中兩種。例如桌面 UI 控制元件用 `isDesktopPlatform`,但托盤、快捷鍵、SMTC、歌詞視窗用 `Platform.isWindows`。所以在 macOS / Linux 上,前者會出現、後者整組消失。 + +```mermaid +flowchart TD + subgraph 判斷方式 + A["Platform.isWindows / isAndroid
(直接判斷,約 70 處)"] + B["isDesktopPlatform
platform_utils.dart:7
Windows+macOS+Linux"] + C["AudioRuntimePlatform
audio_runtime_platform.dart:7
android/ios→mobile,其他→desktop"] + end + A --> W["托盤、快捷鍵、開機自啟、SMTC、
歌詞視窗、自訂標題列、更新、字型"] + B --> D["音訊裝置選擇器、緊湊音量、
水平捲動 hover 箭頭"] + C --> E["音訊後端選擇、
NowPlayingPublisher 分派"] +``` + +## 1. 平台判斷位置(按功能分組) + +「分支」欄寫出該判斷在 iOS / macOS / Linux 會走哪條路。這三個平台的路徑全部**未驗證**(repo 無原生目錄,無法建置)。 + +### 1.1 音訊後端與系統媒體控制(13 處) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/services/audio/audio_runtime_platform.dart:22`(switch 在 `:8-18`) | 以 `Platform.operatingSystem` 決定 mobile / desktop | iOS→mobile;macOS、Linux→desktop;未知 OS 落到 `default`,也是 desktop(`:16-17`) | +| `lib/providers/audio/audio_controller_provider.dart:28` | mobile→`JustAudioService`,其他→`MediaKitAudioService` | iOS 用 just_audio;macOS、Linux 用 media_kit | +| `lib/services/audio/now_playing_publisher.dart:154,165,187,215,232,263`(6 個 switch) | 正在播放資訊、狀態、能力送往 `FmpAudioHandler`(mobile)或 `WindowsSmtcHandler`(desktop) | macOS / Linux 送進沒初始化的 SMTC handler,每個方法因 `_smtc == null` 直接早退。結果是**沒有任何系統媒體控制**(檔頭註解 `:54-59` 也這樣寫,可信度靠 `windows_smtc_handler.dart:104` 的守衛) | +| `lib/main.dart:167` | Android / iOS 呼叫 `AudioService.init` | iOS 會跑,但沒有 `Info.plist` 背景模式設定(**推測**:沒有背景播放,也可能 init 失敗,失敗時退回 dummy handler,見 `:186-194`);macOS / Linux 只建 dummy handler(`:196-198`) | +| `lib/main.dart:202` | Windows / Linux / macOS 呼叫 `MediaKit.ensureInitialized()` | Linux:media_kit 預設用系統安裝的 libmpv(事實,media_kit README)。沒裝就在 init 或播放時失敗(**推測**),失敗會被 catch 並記 log(`:205-215`)。macOS:pubspec 沒有 macOS libmpv 套件(**推測**:播放失敗) | +| `lib/main.dart:219` | Windows 平行初始化 SMTC 與 window_manager,並清理舊更新檔 | 其他平台不進這條路 | +| `lib/services/audio/windows_smtc_handler.dart:104` | 非 Windows 不建立 `SMTCWindows` | 三平台都早退 | +| `lib/core/third_party_licenses.dart:24` | 只有 Windows 登記 libmpv / FFmpeg 授權 | macOS / Linux 若真的帶了 libmpv,授權頁不會列出(**推測**:授權揭露缺口) | + +### 1.2 視窗、托盤、快捷鍵、開機自啟(16 處) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/main.dart:232` | Linux / macOS 只初始化 window_manager | 會跑 `_initializeWindowManager`,設定 `TitleBarStyle.hidden`(`lib/main.dart:329`) | +| `lib/main.dart:340` | 只有 Windows 設 `setPreventClose(true)`(關閉時縮到托盤) | macOS / Linux 關視窗就直接結束 | +| `lib/app.dart:95` | 只有 Windows watch 托盤、快捷鍵、開機自啟、快捷鍵設定的 provider | macOS / Linux 完全沒有這些功能,雖然對應套件支援它們(見 §4) | +| `lib/app.dart:182` | 只有 Windows 插入 `CustomTitleBar` | macOS / Linux 的系統標題列被 `TitleBarStyle.hidden` 藏起來,又沒有自訂標題列。**推測**:Linux 沒有拖曳區與視窗按鈕;macOS 的 window_manager 在 hidden 模式下通常保留紅綠燈,但沒有拖曳區 | +| `lib/ui/widgets/layout/immersive_player_scaffold.dart:82` | 只有 Windows 在沉浸式播放器頂部放 `DragToMoveArea` | macOS / Linux 無法拖曳這頁(**推測**) | +| `lib/providers/system/windows_desktop_provider.dart:13` | 非 Windows 時 provider 回傳 null | 三平台都是 null | +| `lib/services/platform/windows_desktop_service.dart:51,65,182,207,283,402,423`(7 處) | 托盤初始化、dispose、tooltip、托盤選單、快捷鍵同步、關閉意圖、縮到托盤 | 全部早退 | +| `lib/ui/pages/settings/settings_page.dart:153,162` | 只有 Windows 顯示「桌面設定」區塊(開機自啟、縮到托盤、全域快捷鍵) | 三平台都看不到 | +| `lib/ui/pages/settings/widgets/settings_backup.dart:334` | 匯入備份後,只有 Windows 重新整理桌面設定 provider | 不影響 | + +Windows 專屬的寫死路徑沒有另外的平台守衛,靠呼叫端守衛保護:`windows_desktop_service.dart:95-99`(反斜線路徑)、`:472`(`tasklist`)、`update_service.dart:57`(`unins000.exe`)。 + +### 1.3 桌面歌詞視窗(1 處) + +| 位置 | 用途 | 落點(**未驗證**) | +|---|---|---| +| `lib/services/lyrics/lyrics_window_service.dart:162`(實作在 `:54`) | `open()` 在非 Windows 直接 return | macOS / Linux:按鈕點了沒反應。按鈕本身(`lib/ui/widgets/panels/track_detail_panel.dart:534-560`)**沒有平台守衛**,只看是否顯示歌詞、是否電台;Detail Panel 是否出現由寬度決定(`lib/ui/layouts/responsive_scaffold.dart:124`),**推測**:Android 寬版面也會看到這顆沒作用的按鈕 | + +### 1.4 自動更新(18 處) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/services/update/update_service.dart:55` | 判斷是否為安裝版(`unins000.exe`) | false | +| `:66` | 用 `getprop` 讀 Android ABI | 回傳 `universal` | +| `:98`、`:110`、`:116` | 依平台決定資產檔名與 `selectedAsset` | `selectedAsset` 為 null(`:121`) | +| `:227`、`:296`、`:304` | APK 快取檢查、安裝權限 MethodChannel | 早退,或直接回傳 true | +| `:260` | 清理舊 Windows 更新檔 | 早退 | +| `:392` | Android 預取 ABI | 跳過 | +| `:454`、`:459` | 取得 Windows 資產大小 | 跳過 | +| `:524`、`:526` | 分派 Android 下載、Windows 安裝程式或 zip | 會先在 `:521` 丟 `No download URL for current platform`(因為 `downloadUrl` 為 null);`:535` 的 `UnsupportedError` 實際到不了 | +| `lib/providers/system/update_provider.dart:151`、`:183` | Android 下載完觸發安裝並檢查安裝權限 | — | +| `lib/ui/widgets/dialogs/update_dialog.dart:165`、`:263` | Android 顯示 ABI 標籤;Windows 顯示「安裝後重啟」文案 | **推測**:三平台都能檢查到新版、開出更新對話框,按下載後才報錯。檢查更新入口 `lib/ui/pages/settings/widgets/settings_about.dart:70` 沒有平台守衛 | + +### 1.5 下載、儲存權限、備份匯出(13 處,另含 2 處 SDK 版本判斷) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/services/download/download_path_manager.dart:36` | Android 選目錄前先要儲存權限 | 直接開 `FilePicker.getDirectoryPath()`,再用寫入測試檔驗證(`:59-68`) | +| `lib/services/download/download_path_utils.dart:199` | Android 預設下載根目錄是 `getExternalStorageDirectory()` 往上四層加 `Music/FMP`(`:200-206`) | 其他平台用 `getApplicationDocumentsDirectory()/FMP`(`:214-215`) | +| `lib/ui/pages/settings/widgets/settings_storage.dart:60` | 非 Android 才顯示「變更下載路徑」 | iOS 會顯示。**推測**:iOS 選到沙盒外的目錄時,`dart:io` 寫不進去,寫入測試會失敗並跳錯誤。Android 使用者只能在第一次下載時透過 `DownloadPathSetupDialog` 選一次(`lib/ui/pages/library/playlist_detail_page.dart:960-962`),之後不能在設定頁改 | +| `lib/services/platform/storage_permission_service.dart:70,83,175`(另有 `:72,86` 的 Android 11 判斷) | 經自有 MethodChannel 檢查、請求 `MANAGE_EXTERNAL_STORAGE` 或舊版儲存權限 | 非 Android 一律回傳 true | +| `lib/services/backup/backup_service.dart:58` | Android 用 `getDirectoryPath`,其他平台用 `saveFile` | iOS 會走 `saveFile`,而且**沒傳 `bytes`**。file_picker 11.0.3 的文檔說行動平台的 `saveFile` 會直接用傳入的 bytes 存檔(pub cache `file_picker-11.0.3/lib/src/file_picker.dart:172`)。**推測**:iOS 匯出失敗或得到空檔 | +| `lib/ui/pages/settings/log_viewer_page.dart:123` | 匯出 log,同上 | 同上(**推測**) | +| `lib/services/backup/backup_service.dart:693,697,701,704,707` | 匯入備份時,桌面專屬設定只在 Windows 還原 | macOS / Linux 保留目前值 | + +### 1.6 登入(5 處) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/ui/pages/settings/bilibili_login_page.dart:86,90` | 依平台設定 WebView 的偽裝 UA(Android、iOS、其他=Windows Chrome) | 登入頁在所有平台都有「WebView」與「QR」兩個分頁(`:48-63`)。Linux:flutter_inappwebview 6.1.5 沒有 Linux 實作(事實,§4),**推測** WebView 分頁無法使用,QR 分頁可用 | +| `lib/ui/pages/settings/netease_login_page.dart:32,52` | Android 有 WebView 與 QR;其他平台只有 QR(`:74-78`) | 三平台只有 QR | +| `lib/ui/pages/settings/youtube_login_page.dart:61` | Android UA 去掉 `;wv`;其他平台用 Windows Chrome UA | YouTube **只有 WebView 登入**(`:322-326`,沒有 QR)。**推測**:Linux 完全無法登入 YouTube;iOS / macOS 送出 Windows UA 的 WKWebView 能不能通過 Google 登入,無法判斷 | + +登出時的 cookie 清除(`lib/services/account/bilibili_account_service.dart:306`、`netease_account_service.dart:279`、`youtube_account_service.dart:145`)沒有平台判斷,但都包在 try/catch 裡,失敗只記 warning。 + +### 1.7 外部連結(3 處) + +| 位置 | 用途 | 落點(**未驗證**) | +|---|---|---| +| `lib/services/platform/url_launcher_service.dart:105,120,133` | Android / iOS 先試 `bilibili://` 等 App scheme,失敗再開網頁 | iOS 會試 App scheme;macOS / Linux 直接開網頁 | + +### 1.8 UI 版面、主題、字型(14 處) + +| 位置 | 用途 | iOS / macOS / Linux 落點(**未驗證**) | +|---|---|---| +| `lib/ui/pages/player/player_page.dart:276,283` | 桌面顯示音訊裝置選擇器與緊湊音量 | macOS / Linux 會顯示,裝置清單來自 media_kit | +| `lib/ui/pages/radio/radio_player_page.dart:64,71` | 同上(電台) | 同上 | +| `lib/ui/widgets/player/mini_player.dart:96`、`lib/ui/widgets/radio/radio_mini_player.dart:96` | 桌面在迷你播放器插入 `MiniPlayerDesktopControls` | 同上 | +| `lib/ui/widgets/layout/horizontal_scroll_section.dart:149,152,176,234,246`(`_isDesktop` 定義在 `:51`) | 桌面有 hover 左右箭頭與不同的 scroll physics | macOS / Linux 同 Windows | +| `lib/ui/theme/app_theme.dart:71` | Windows 有中日文字型清單 | 其他平台的清單內容在 `:71` 之後(本次未展開) | +| `lib/ui/theme/app_theme.dart:97` | Windows 的 CJK fallback 是微軟雅黑;其他平台是 `Noto Sans SC` | pubspec 的 assets 只有 `assets/icon/` 與 `licenses/`,**沒有內建 Noto Sans SC**。**推測**:iOS / macOS / Linux 退回系統字型,Linux 沒裝 CJK 字型時會出現方框 | +| `lib/ui/pages/settings/widgets/settings_appearance.dart:322` | 「系統預設」字型名稱標示:Windows 顯示 Segoe UI,其他顯示 Roboto | iOS / macOS 的標示不正確(**推測**) | + +### 1.9 快取與記憶體預設值、開發者工具(5 處) + +| 位置 | 用途 | 落點 | +|---|---|---| +| `lib/main.dart:156` | 圖片記憶體快取:行動 100 張 / 50 MB,桌面 200 張 / 80 MB | iOS 用行動設定,macOS / Linux 用桌面設定 | +| `lib/core/services/network_image_cache_service.dart:140` | 磁碟圖片快取預設:行動 16 MB,桌面 32 MB | 同上 | +| `lib/data/database/database_migration.dart:108` | 全新安裝時 `maxCacheSizeMB` 的初值 | 同上 | +| `lib/services/backup/backup_data.dart:510`(使用在 `:512`) | 備份還原時的快取預設 | 同上 | +| `lib/ui/pages/settings/developer_options_page.dart:202` | 只有 Android、Windows、Linux 讀取 `ProcessInfo.currentRss` | iOS / macOS 顯示不到 RSS | + +### 1.10 其他 + +- `lib/main.dart:96`:`args.firstOrNull == 'multi_window'` 會轉進歌詞子視窗入口。這是命令列參數判斷,不是平台判斷,但只在 desktop_multi_window 建立子引擎時才會發生(見 §3.7)。 +- 測試:`test/services/audio/audio_runtime_platform_test.dart:11-29` 測了 `selectAudioRuntimePlatform` 的字串對應(包含 linux 與 ios)。CI 在 `ubuntu-latest` 跑測試(`.github/workflows/ci.yml:34-35`),所以單元測試執行時 `Platform.isLinux == true`。**推測**:凡是直接讀 `Platform.isX`、又沒有 override 的程式碼,測試跑的其實是 Linux 分支。`storage_permission_service.dart:51` 與 `update_provider.dart:60` 為此留了 override。 + +### 1.11 計數 + +| 分組 | 決策點 | +|---|---| +| 音訊後端與媒體控制 | 13(含 7 處 `AudioRuntimePlatform`) | +| 視窗、托盤、快捷鍵、開機自啟 | 16 | +| 桌面歌詞視窗 | 1 | +| 自動更新 | 18 | +| 下載、儲存、備份匯出 | 13(另加 2 處 Android SDK 判斷) | +| 登入 | 5 | +| 外部連結 | 3 | +| UI 版面、主題、字型 | 14 | +| 快取預設、開發者工具 | 5 | +| **合計** | **88**(+2 SDK 判斷) | + +> `lib/main.dart:219` 同時屬於音訊與視窗,只在音訊組計一次;1.10 的 `multi_window` 不計入。原始 grep 命中 103 行,差額是註解(`platform_utils.dart:6`、`audio_service.dart:43`、`now_playing_publisher.dart:50,51,57`、`mini_player_desktop_controls.dart:16`)、helper 或抽象定義(`platform_utils.dart:7-8`、`update_provider.dart:60,62,65,71`、`storage_permission_service.dart:120`、`lyrics_window_service.dart:38,54`、`horizontal_scroll_section.dart:51`),以及只是檔名比對、不是平台判斷的 `update_service.dart:268,282`。 + +## 2. iOS / macOS / Linux 分支總覽(全部**未驗證**) + +repo 沒有這三個平台的原生目錄,所以下表是「如果補上 runner、能建置起來,程式碼會走的路」。 + +| 平台 | 明寫的分支 | 經 `else` 或 desktop 預設落入的路徑 | 預期結果(**推測**) | +|---|---|---|---| +| iOS | `main.dart:156,167`、`network_image_cache_service.dart:140`、`database_migration.dart:108`、`backup_data.dart:510`、`url_launcher_service.dart:105,120,133`、`bilibili_login_page.dart:90`、`audio_runtime_platform.dart:10` | 桌面判斷以外的所有 `else`:更新(丟錯)、下載路徑(Documents/FMP)、備份與 log 匯出(`saveFile` 沒有 bytes)、網易雲只有 QR、YouTube 用 Windows UA 的 WebView、字型 fallback `Noto Sans SC` | 播放走 just_audio 加 audio_service,在程式碼裡是三平台中最完整的一條路;但缺背景模式與 ATS 設定(§6),匯出流程可能壞掉,更新入口會出現卻不能用 | +| macOS | `main.dart:202,232`、`platform_utils.dart:8`、`audio_runtime_platform.dart:14` | 桌面 UI 控制元件會出現;托盤、快捷鍵、開機自啟、SMTC、歌詞視窗、自訂標題列、關閉縮托盤全部沒有;更新丟錯 | media_kit 沒有 macOS libmpv 套件,無法播放;沒有系統媒體控制;標題列藏起來卻沒有替代 | +| Linux | `main.dart:202,232`、`platform_utils.dart:8`、`developer_options_page.dart:202`、`audio_runtime_platform.dart:13` | 同 macOS,另外 WebView 登入不可用 | 系統有裝 libmpv 才能播放;YouTube 無法登入;沒有 MPRIS | + +其他注意事項: + +- `audio_service` 本身支援 macOS(pub.dev 標籤),但 `main.dart:167` 只在 Android / iOS 啟用,所以 macOS 的媒體控制是**刻意不接,還是漏掉**,程式碼看不出來,查不到。 +- ADR 0003 說 Linux / macOS 的殘留分支「建置不出來」、「不是支援平台」(`docs/adr/0003-two-audio-backends.md:32-37`),和程式碼行為**一致**。但 `isDesktopPlatform` 的註解(`platform_utils.dart:3`)與 `audio_controller_provider.dart:23-25` 的註解寫「Windows/Linux」,讀起來像有支援。`pubspec.yaml:24` 寫「FMP 不出 Linux/macOS」。這些註解之間**不一致**(對「是否支援」的立場不同)。 + +## 3. 平台綁定功能 + +| 功能 | Android | Windows | 使用的套件或原生碼 | 其他平台 | +|---|---|---|---|---| +| 音訊後端 | ✅ just_audio 0.10.6(ExoPlayer)+audio_session | ✅ media_kit 1.2.6(libmpv)+media_kit_libs_windows_audio 1.0.9 | `audio_controller_provider.dart:26-32`;`just_audio_service.dart:166-167`;`media_kit_audio_service.dart:166-259` | iOS 走 just_audio(**未驗證**);macOS / Linux 走 media_kit,但缺平台 libs | +| 系統媒體控制 | ✅ audio_service 0.18.18(通知列、耳機鍵) | ✅ smtc_windows 1.1.0(SMTC),**不支援 seek**(`now_playing_publisher.dart:283-284` 的註解) | Android:`MainActivity : AudioServiceActivity`(`MainActivity.kt:14`)、Manifest 的 service 與 receiver(`AndroidManifest.xml:64-82`)。Windows:`main.cpp:43` 設定 AppUserModelID、`windows_smtc_handler.dart` | 無 | +| 自動更新 | ✅ GitHub release APK(依 ABI),`open_filex` 安裝,MethodChannel 檢查安裝權限 | ✅ 安裝版:下載 Inno 安裝程式,帶 `/SILENT /DIR= /CLOSEAPPLICATIONS` 啟動後 `exit(0)`(`update_service.dart:613-620`)。免安裝版:下載 zip,寫 `.bat`+`.vbs` 交給 `wscript` 覆蓋後 `exit(0)`(`:624-685`、批次腳本約 `:840-866`) | Manifest 的 `REQUEST_INSTALL_PACKAGES`(`AndroidManifest.xml:14`)與 ``(`:96-99`);pubspec 的 `inno_bundle` 設定 | 三平台會檢查、會提示新版,但下載時丟錯(§1.4) | +| 儲存權限與下載路徑 | ✅ `MANAGE_EXTERNAL_STORAGE`(Android 11 以上)或舊版讀寫權限,全部走自有 MethodChannel(刻意不用 permission_handler,見 `storage_permission_service.dart:22-24`)。預設路徑 `/…/Music/FMP` | ✅ 預設 `Documents\FMP`,可用 file_picker 改 | `MainActivity.kt:20-35,62-136`;`AndroidManifest.xml:17-23` | iOS:Documents/FMP(沙盒內)。macOS / Linux:Documents/FMP | +| 登入 WebView | ✅ flutter_inappwebview(Android WebView),B 站、網易雲、YouTube | ✅ flutter_inappwebview(WebView2),B 站、YouTube;網易雲只有 QR | Windows:`windows/CMakeLists.txt:60-73` 補了建置 workaround(上游 PR #2869)。Android:`gradle.properties:9-12` 補了 proguard workaround(上游 #2852)(核查更正行號,原寫 `:147-150`;該檔只有 12 行) | Linux 沒有實作 | +| 托盤 | ❌ | ✅ tray_manager 0.5.3(圖示、選單、tooltip 顯示當前歌曲) | `windows_desktop_service.dart:85-178`;圖示由 `windows/CMakeLists.txt:125-128` 安裝到 exe 旁 | 套件支援 macOS / Linux,程式碼只開 Windows | +| 全域快捷鍵 | ❌ | ✅ hotkey_manager 0.2.3,可自訂組合(`HotkeyConfig`) | `windows_desktop_service.dart:275-320` | 套件支援 macOS / Linux,程式碼只開 Windows | +| 開機自啟 | ❌ | ✅ launch_at_startup 0.5.1(寫登錄檔,依賴 win32_registry),可帶 `--minimized` | `desktop_settings_provider.dart:117-157`;`flutter_window.cpp:73-91` 讀 `--minimized` 決定要不要顯示視窗(核查更正行號,原寫 `:169-187`;該檔只有 130 行);`main.dart:140` | macOS 需要額外的原生程式碼(套件 README) | +| 關閉時縮到托盤、單一實例 | ❌ | ✅ `setPreventClose(true)`(`main.dart:340-342`)+`handleCloseIntent`。單一實例用具名 mutex `Local\FMP_MainInstance`,再用 `FindWindowW` 喚醒既有視窗(`main.cpp:13-36,57-68`)。偵測到安裝程式在跑時自行退出(`windows_desktop_service.dart:415-418,470-490`,`tasklist`) | runner C++ | 無 | +| 桌面歌詞視窗 | ❌ | ✅ desktop_multi_window 0.3.1,獨立 Flutter engine,`WindowMethodChannel('lyrics_sync')` 雙向溝通 | 見 §3.7 | 套件支援 macOS / Linux,程式碼只開 Windows | +| 自訂標題列 | ❌(Android 改畫 status bar 色塊,`app.dart:193-199`) | ✅ `CustomTitleBar`+window_manager `TitleBarStyle.hidden` | `lib/ui/widgets/app_bars/custom_title_bar.dart` | macOS / Linux 標題列被藏起來,卻沒有替代(§1.2) | + +### 3.7 歌詞多視窗機制 + +```mermaid +sequenceDiagram + participant UI as TrackDetailPanel
(主視窗 engine) + participant S as LyricsWindowService + participant P as desktop_multi_window
(Windows 原生) + participant R as runner
flutter_window.cpp + participant L as lyricsWindowMain
(子 engine) + UI->>S: open()(非 Windows 直接 return) + S->>P: WindowController.create(arguments={"window_type":"lyrics"}) + P->>R: 建立新 FlutterViewController
entrypoint args = ["multi_window", id, args] + R->>R: RegisterPluginsForSubWindow
(不註冊 tray_manager / hotkey_manager) + Note over R: main.cpp:58 看到 multi_window 就跳過單一實例 mutex + R->>L: main(args) → args[0]=="multi_window" → lyricsWindowMain + S->>L: ping / updateLyrics / updatePosition / updateTheme / updatePlaybackState / updateLyricsDisplayMode / close + L->>S: playPause / next / previous / seekTo / adjustOffset / resetOffset / changeLyricsDisplayMode / changeLyricsWindowStyle / resetLyricsWindowStyle / requestHide +``` + +- 入口參數 `"multi_window"` 是套件原生端寫死的。Windows 在 pub cache `desktop_multi_window-0.3.1/windows/flutter_window.cc:24`,macOS 在 `…/macos/…/FlutterMultiWindowPlugin.swift:108`。 +- 子視窗只註冊 6 個插件(`flutter_window.cpp:14-37`)。(核查更正行號)註解寫的原因:tray_manager 與 hotkey_manager 用全域 static channel,註冊到子 engine 會蓋掉主視窗的;window_manager 也有同樣問題,改用 `handleCloseIntent` 繞過。這一點沒有在執行中驗證,屬於註解主張。 +- 關閉子視窗時用隱藏而不銷毀(`lyrics_window_service.dart:112` 的註解說明原因是 window_manager channel 會被清掉)。 +- 套件 README 建議搭配 window_manager 時使用 `boyan01/window_manager` 的 fork;FMP 用的是 pub.dev 上的 window_manager 0.4.3,不是 fork(`pubspec.lock`)。實際影響查不到。 +- 要移植到 macOS / Linux,需要在 `MainFlutterWindow.swift` 或 `my_application.cc` 加上子視窗插件註冊(套件 README)。`lyrics_window_service.dart:162` 的 `isWindows` 守衛也要放寬。 + +### 3.8 MethodChannel 配對 + +| Channel | Dart 端 | 原生端 | 方法 | +|---|---|---|---| +| `com.personal.fmp/platform` | `lib/services/platform/storage_permission_service.dart:26`(`:125-176`) | `android/app/src/main/kotlin/com/personal/fmp/MainActivity.kt:20-35` | `getAndroidSdkInt`、`isManageExternalStorageGranted`、`isStorageGranted`、`requestManageExternalStorage`、`requestStorage`、`openAppSettings` | +| `com.personal.fmp/platform`(同一個 channel) | `lib/services/update/update_service.dart:211`(`:297,305`) | 同上 | `canRequestPackageInstalls`、`openInstallPermissionSettings` | +| `lyrics_sync`(`WindowMethodChannel`,雙向) | 主視窗 `lib/services/lyrics/lyrics_window_service.dart:119`;子視窗 `lib/ui/windows/lyrics_window.dart:231` | desktop_multi_window 插件內部轉送 | 見上方序列圖;兩端名稱一一對上(主→子:`lyrics_window_service.dart:240,271,307,335,394,415,430` 對 `lyrics_window.dart:272-289`;子→主:`lyrics_window.dart:392-506` 對 `lyrics_window_service.dart:472-515`) | + +- repo 沒有 EventChannel 或 BasicMessageChannel。Windows runner 沒有自訂 channel。 +- 兩個 Dart 類別各自宣告同名的 channel 常數,原生端只有一個 handler。沒有測試守住兩邊的方法名,**推測**:拼錯時只會在執行期拿到 `notImplemented`。 + +## 4. 依賴套件平台支援 + +來源:pub.dev score API 的 `platform:*` 標籤(**反映的是最新版**)。lock 版本和最新版不同的插件,改用 `/api/packages//versions/` 的 `flutter.plugin.platforms` 核對過,結果列在備註。所有直接依賴都來自 pub.dev(hosted),**沒有 git 或 path fork**,也沒有 `dependency_overrides`。 + +✅ 支援、❌ 不支援;「套件」指 Dart-only 套件,由 pub.dev 分析推得的平台。 + +### 4.1 dependencies + +| 套件 | pubspec 約束 | lock 版本 | 來源 | Android | Windows | Linux | macOS | iOS | 用途 | 備註(最新版與發佈日) | +|---|---|---|---|---|---|---|---|---|---|---| +| flutter_riverpod | ^3.4.3 | 3.4.3 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 狀態管理 | 最新 3.4.3(2026-09-03) | +| isar_community | ^3.3.2 | 3.3.2 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 資料庫 | 3.3.2(2026-03-23)。Isar 社群 fork,已發佈在 pub.dev | +| isar_community_flutter_libs | ^3.3.2 | 3.3.2 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | Isar 原生庫 | lock 版本 pubspec 列了 5 個平台 | +| path_provider | ^2.1.6 | 2.1.6 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | 路徑 | 無 web 標籤 | +| path | ^1.9.0 | 1.9.1 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 路徑運算 | 2024-10-17 | +| just_audio | ^0.10.6 | 0.10.6 | pub(插件) | ✅ | ❌ | ❌ | ✅ | ✅ | Android 音訊後端 | Windows / Linux 要另加實作套件(README)。iOS / macOS 帶 headers 時走本機 proxy,需要 ATS 設定(README) | +| media_kit | ^1.1.11 | 1.2.6 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | Windows 音訊後端 | Dart 層支援全平台,但**每個平台要另加原生庫**,FMP 只有 Windows 的。1.2.6 是最新(2025-12-13);約束寫 ^1.1.11,和 lock 差很多 | +| media_kit_libs_windows_audio | ^1.0.9 | 1.0.9 | pub(插件) | ❌ | ✅ | ❌ | ❌ | ❌ | Windows 的 libmpv | pub.dev 標記 **`is:unlisted`**;最後發佈 2023-09-27。官方 README 現在建議用 `media_kit_libs_audio` 1.0.7(全平台,2025-10-05;但它在 pub.dev 同樣標 `is:unlisted`,核查補充) | +| rxdart | ^0.28.0 | 0.28.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | Stream 組合 | 2024-06-14 | +| audio_service | ^0.18.15 | 0.18.18 | pub(插件) | ✅ | ❌ | ❌ | ✅ | ✅ | Android 媒體通知 | lock 版本的平台是 android、ios、macos、web。Linux 要另加 `audio_service_mpris`(README)。最新 0.18.19(2026-06-29) | +| audio_session | ^0.2.4 | 0.2.4 | pub(插件) | ✅ | ❌ | ❌ | ✅ | ✅ | 音訊焦點與中斷 | 沒有 Windows / Linux 實作;`just_audio_service.dart:166` 只在 Android 路徑使用 | +| smtc_windows | ^1.1.0 | 1.1.0 | pub(ffiPlugin,flutter_rust_bridge) | ❌ | ✅ | ❌ | ❌ | ❌ | Windows SMTC | 2025-08-18 | +| dio | ^5.11.1 | 5.11.1 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | HTTP | 2026-09-04 | +| crypto | ^3.0.3 | 3.0.7 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 雜湊 | — | +| encrypt | ^5.0.3 | 5.0.3 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 加解密 | 最後發佈 **2023-09-18** | +| youtube_explode_dart | ^3.1.0 | 3.1.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | YouTube 解析 | 2026-05-09 | +| go_router | ^18.0.1 | 18.0.1 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 路由 | Flutter Favorite | +| url_launcher | ^6.3.1 | 6.3.2 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | 開外部連結 | 2025-07-10 | +| scrollable_positioned_list | ^0.3.8 | 0.3.8 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 跳到指定索引 | 最後發佈 **2023-05-08** | +| cached_network_image | ^4.0.0 | 4.0.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 圖片快取 | 最新 4.0.2(2026-09-23) | +| flutter_cache_manager | ^3.4.2 | 3.4.2 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 快取管理 | 最新 3.4.5 | +| tray_manager | ^0.5.3 | 0.5.3 | pub(插件) | ❌ | ✅ | ✅ | ✅ | ❌ | 系統托盤 | lock 版本支援 linux、macos、windows。最新 0.7.0(2026-09-19)。0.5.3 在 Linux 需要 `libayatana-appindicator3`(pub cache README `:97-108`);0.7.0 改用 StatusNotifierItem,但 Linux 仍收不到點擊事件(0.7.0 README) | +| window_manager | ^0.4.3 | 0.4.3 | pub(插件) | ❌ | ✅ | ✅ | ✅ | ❌ | 視窗控制 | lock 版本發佈於 2024-10-27;最新 0.5.2(2026-07-04) | +| hotkey_manager | ^0.2.3 | 0.2.3 | pub(插件) | ❌ | ✅ | ✅ | ✅ | ❌ | 全域快捷鍵 | 最後發佈 **2024-05-18**。Linux 需要 `keybinder-3.0`(README) | +| package_info_plus | ^9.0.1 | 9.0.1 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | 版本資訊 | 最新 10.2.1。`gradle.properties:3-6` 說它是 `builtInKotlin=false` 的原因(核查更正行號) | +| open_filex | ^4.5.0 | 4.7.0 | pub(插件) | ✅ | ❌ | ❌ | ❌ | ✅ | 開啟 APK 安裝 | 只支援 android、ios;2025-03-06 | +| archive | ^4.2.0 | 4.2.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 解壓 Windows zip 更新 | 最新 4.3.0 | +| flutter_inappwebview | ^6.1.5 | 6.1.5 | pub(federated 插件) | ✅ | ✅ | ❌ | ✅ | ✅ | 登入 WebView | **沒有 Linux**。最後發佈 **2024-10-08**。本地建置要靠兩處 workaround(§3) | +| qr_flutter | ^4.1.0 | 4.1.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | QR 登入 | 最後發佈 **2023-05-14** | +| flutter_secure_storage | ^10.3.1 | 10.3.1 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | 憑證儲存 | 最新 11.2.0;大版本被刻意釘住(`pubspec.yaml:69-74`)。Linux 需要 libsecret 與 keyring 服務;macOS / iOS 需要 keychain entitlement(README) | +| pointycastle | ^3.9.1 | 3.9.1 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | RSA | 最新 4.0.0 | +| file_picker | ^11.0.3 | 11.0.3 | pub(插件) | ✅ | ✅ | ✅ | ✅ | ✅ | 選目錄、存檔 | 最新 13.1.0。macOS 需要 User Selected File entitlement(原始碼文檔)。`android/build.gradle.kts:18-26` 有它的 KGP workaround(核查更正行號,原寫 `:82-90`;該檔只有 48 行) | +| collection | ^1.19.1 | 1.19.1 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 工具 | — | +| equatable | ^2.1.0 | 2.1.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 值相等 | 最新 3.0.0 | +| slang_flutter | ^4.19.0 | 4.19.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | i18n | 來源在 codeberg | +| intl | any | 0.20.3 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 日期與數字格式 | 刻意不釘版本(`pubspec.yaml:81-82`) | +| flutter_localizations | sdk | — | SDK | ✅ | ✅ | ✅ | ✅ | ✅ | 本地化 | — | +| simple_icons | ^16.23.0 | 16.23.0 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 品牌圖示 | — | +| reorderable_grid_view | ^2.2.8 | 2.2.8 | pub | ✅ | ✅ | ✅ | ✅ | ✅ | 可拖曳網格 | 最後發佈 **2023-11-20** | +| launch_at_startup | ^0.5.1 | 0.5.1 | pub | ❌ | ✅ | ✅ | ✅ | ❌ | 開機自啟 | 2025-04-01。macOS 要自己加原生程式碼(README `:100-171`) | +| desktop_multi_window | ^0.3.1 | 0.3.1 | pub(插件) | ❌ | ✅ | ✅ | ✅ | ❌ | 歌詞子視窗 | 2026-08-26 | + +**不支援 Linux 的直接依賴**:just_audio、audio_service、audio_session、media_kit_libs_windows_audio、smtc_windows、open_filex、flutter_inappwebview。 + +**不支援 macOS**:media_kit_libs_windows_audio、smtc_windows、open_filex。 + +**不支援 iOS**:media_kit_libs_windows_audio、smtc_windows、tray_manager、window_manager、hotkey_manager、launch_at_startup、desktop_multi_window。 + +上面三份都是指「套件沒有實作」。就算套件支援,程式碼守衛也可能沒開,見 §2。 + +可替代的現成套件(pub.dev 標籤,2026-09-26):`media_kit_libs_audio`(全平台,`is:unlisted`)、`media_kit_libs_linux`(linux)、`media_kit_libs_ios_audio`(ios)、`media_kit_libs_macos_audio`(pub.dev score 沒有平台標籤,查不到)、`audio_service_mpris`(linux)、`just_audio_media_kit`(全平台)、`desktop_webview_window`(windows、linux、macos)。 + +### 4.2 dev_dependencies + +| 套件 | 約束 | lock | 平台 | 用途 | +|---|---|---|---|---| +| flutter_test | sdk | — | — | 測試 | +| build_runner | ^2.4.13 | 2.15.1 | linux、macos、windows(開發機) | Isar codegen | +| isar_community_generator | ^3.3.2 | 3.3.2 | 全平台 | Isar codegen | +| flutter_lints | ^6.0.0 | 6.0.0 | 全平台 | lint | +| slang | ^4.19.2 | 4.19.2 | 全平台 | i18n CLI | +| flutter_launcher_icons | ^0.14.1 | 0.14.4 | 全平台 | 圖示;設定只產 android 與 windows(`pubspec.yaml:128-138`) | +| inno_bundle | ^0.12.0 | 0.12.0 | windows | Windows 安裝程式 | +| http | ^1.6.0 | 1.6.0 | 全平台 | `tool/demo` | +| yaml | ^3.1.4 | 3.1.4 | 全平台 | workflow 測試 | + +## 5. 原生目錄 + +### 5.1 `android/` + +版控中的檔案:Gradle 設定、三份 Manifest(main / debug / profile)、`MainActivity.kt`、資源檔。`GeneratedPluginRegistrant.java` 與 `local.properties` 在 `.gitignore` 內(`android/.gitignore:6-7`)。 + +- **`MainActivity.kt`**(175 行,唯一的自訂 Kotlin) + - 繼承 `com.ryanheise.audioservice.AudioServiceActivity`(`:14`),這是 audio_service 的要求。 + - `com.personal.fmp/platform` channel 有 8 個方法(`:20-35`)。 + - `MANAGE_EXTERNAL_STORAGE` 透過 `startActivityForResult` 跳設定頁,並有 fallback intent(`:75-103`);Android 6–10 用 runtime permission(`:105-136`)。 + - 未知來源安裝權限:`canRequestPackageInstalls` 與 `ACTION_MANAGE_UNKNOWN_APP_SOURCES`(`:150-169`)。 +- **`AndroidManifest.xml`** + - 權限:`WAKE_LOCK`、`FOREGROUND_SERVICE`、`FOREGROUND_SERVICE_MEDIA_PLAYBACK`、`INTERNET`、`ACCESS_NETWORK_STATE`、`REQUEST_INSTALL_PACKAGES`、`READ_EXTERNAL_STORAGE`(maxSdk 32)、`WRITE_EXTERNAL_STORAGE`(maxSdk 29)、`MANAGE_EXTERNAL_STORAGE`(`:5-23`)。 + - `usesCleartextTraffic="true"`:註解說網易雲的串流 URL 是 http(`:33-34,40`)。just_audio README 也要求帶 headers 時開 cleartext(本機 proxy)。 + - `allowBackup="false"`:註解說是 flutter_secure_storage 的 keystore 問題,issue #35(`:25-31,41`)。 + - audio_service 的 `AudioService`(`foregroundServiceType="mediaPlayback"`)與 `MediaButtonReceiver`(`:64-82`)。 + - ``:`PROCESS_TEXT`、APK 的 VIEW intent(`:90-100`)。**沒有**宣告 `bilibili://` 等 scheme。**推測**:`launchUrl` 本身不需要,但如果之後改用 `canLaunchUrl`,Android 11 以上的 package visibility 會回 false。 +- **Gradle 的特殊處理** + - AGP 9.1.0、KGP 2.4.0、Gradle 9.3.1(`settings.gradle.kts:22-23`、`gradle-wrapper.properties:5`)。 + - `android.builtInKotlin=false`,原因是 package_info_plus(`gradle.properties:3-6`)。(核查更正行號) + - `android.r8.proguardAndroidTxt.disallowed=false`,原因是 flutter_inappwebview_android(`:9-12`)。(核查更正行號) + - 手動替 `file_picker` 子專案套用 KGP(`build.gradle.kts:18-26`)。(核查更正行號) + - 所有 library 子專案**強制 `compileSdk = 36`**,缺 namespace 的自動補(`:28-40`)。(核查更正行號) + - release 簽章:`key.properties` 不存在時退回 debug 簽章(`app/build.gradle.kts:45-52`)。**推測**:本地 release 建置會產出 debug 簽章的 APK,而且沒有任何警告。 + - `minSdk` / `targetSdk` 直接用 Flutter 預設(`app/build.gradle.kts:30-31`)。 +- `android/.kotlin/errors/errors-1788852048674.log` 存在於工作目錄,但沒有進版控。這是建置殘留。 + +### 5.2 `windows/` + +版控中的檔案:CMake(根、`flutter/`、`runner/`)與 runner 原始碼。和 Flutter 範本比對,只有 `main.cpp`、`flutter_window.cpp`、`Runner.rc`、`app_icon.ico` 有改(`git diff --stat` 從該目錄的首個 commit 起算:120 行新增、8 行刪除)。 + +- **`main.cpp`** + - `SetCurrentProcessExplicitAppUserModelID(L"com.personal.fmp")`,給 SMTC 辨識用(`:43`)。 + - 單一實例:具名 mutex,重複啟動時用 `FindWindowW`(class+title)找到既有視窗,還原並拉到前景(`:13-36,57-68`)。 + - `multi_window` 啟動時跳過 mutex,讓歌詞子視窗能起來(`:15-17,58`)。 + - **推測**:`ActivateExistingInstance` 靠視窗標題 `FMP - Flutter Music Player` 比對。如果 Dart 端改了標題,就找不到既有視窗,第二個實例會靜默退出。 +- **`flutter_window.cpp`** + - 子視窗選擇性註冊插件(`:14-37`,註冊回呼在 `:63-69`,§3.7)。(核查更正行號) + - 啟動時讀 `--minimized` 參數,決定首幀後要不要 `Show()`(`:73-91`)。(核查更正行號) +- **`runner.exe.manifest`**:PerMonitorV2 DPI,supportedOS 只列 Windows 10/11(`:1-14`)。 +- **根 `CMakeLists.txt`** + - 替 `flutter_inappwebview_windows_plugin` 加 `_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS` 與 `/FS`,目的是在 VS 2026 下能建置(`:60-73`)。 + - 把 `app_icon.ico` 安裝到 exe 旁,給托盤用(`:125-128`)。 +- `runner/CMakeLists.txt` 連結 `dwmapi.lib`(`:36`)。這是 Flutter 範本本來就有的,不是自訂。 +- Windows runner **沒有自訂 MethodChannel**。 + +## 6. 若要支援 Linux / macOS / iOS 會卡住的地方 + +標記說明:**事實**附來源;**推測**是依程式碼或常識推論,尚未查證。 + +### 6.1 Linux + +| 類別 | 項目 | 標記 | +|---|---|---| +| 缺原生專案 | 沒有 `linux/`,要用 `flutter create --platforms=linux` 產生,並在 `my_application.cc` 加子視窗插件註冊(desktop_multi_window README) | 事實 | +| 套件不支援 | flutter_inappwebview 沒有 Linux → WebView 登入不能用;YouTube 只有 WebView 登入,**等於不能登入 YouTube** | 事實(pub.dev 版本 pubspec)+推測(對 YouTube 的影響) | +| 套件不支援 | smtc_windows 只有 Windows;audio_service 沒有 Linux → 要另加 `audio_service_mpris`(audio_service README)或自己做 MPRIS,並接進 `NowPlayingPublisher` 的 desktop 分支 | 事實 | +| 套件不支援 | open_filex 沒有 Linux;更新流程在 Linux 沒有對應實作(`update_service.dart:521`) | 事實 | +| 系統依賴 | media_kit 預設用系統的 libmpv(`libmpv-dev`、`mpv`),或改用 Snap / Flatpak 打包(media_kit README);pubspec 沒有 `media_kit_libs_linux` | 事實 | +| 系統依賴 | flutter_secure_storage 需要 libsecret 與 keyring 服務(gnome-keyring / kwallet)(README)。沒有 keyring 時,`SecureKeyValueStore` 捕捉 `PlatformException`(`secure_key_value_store.dart:63`)並降級,**推測**:每次啟動都要重新登入 | 事實+推測 | +| 系統依賴 | tray_manager 0.5.3 需要 ayatana-appindicator;GNOME 還要裝 AppIndicator 擴充(README) | 事實 | +| 系統依賴 | hotkey_manager 需要 `keybinder-3.0`(README);**推測**:keybinder 走 X11,Wayland 下全域快捷鍵不可用 | 事實+推測 | +| 功能差異 | tray_manager 在 Linux 收不到托盤點擊事件,面板會自己開選單(0.7.0 README);`WindowsDesktopService` 的點擊處理不會生效 | 事實(0.7.0);0.5.3 的行為查不到 | +| 程式碼守衛 | 托盤、快捷鍵、開機自啟、歌詞視窗、關閉縮托盤、自訂標題列、SMTC 都寫死 `Platform.isWindows`(§1.2、§1.3),而且檔名與類別名就叫 `Windows*` | 事實(程式碼) | +| 程式碼守衛 | `TitleBarStyle.hidden` 套在所有桌面平台,但自訂標題列只有 Windows(`main.dart:329`、`app.dart:182`) | 事實(程式碼);推測(使用者看到的樣子) | +| 字型 | CJK fallback 用 `Noto Sans SC`,但沒有內建(`app_theme.dart:97-106`) | 推測 | +| 授權揭露 | libmpv 的授權只在 Windows 登記(`third_party_licenses.dart:24`) | 事實(程式碼) | + +### 6.2 macOS + +| 類別 | 項目 | 標記 | +|---|---|---| +| 缺原生專案 | 沒有 `macos/`;子視窗註冊要寫在 `MainFlutterWindow.swift`(desktop_multi_window README);launch_at_startup 要加原生 channel 程式碼與 Xcode 設定(README `:100-171`) | 事實 | +| 套件不支援 | smtc_windows → 要改接 audio_service(它支援 macOS,只是 `main.dart:167` 沒開) | 事實 | +| 套件不支援 | media_kit_libs_windows_audio 只有 Windows → 需要 `media_kit_libs_audio` 或 `media_kit_libs_macos_audio` | 事實 | +| 套件不支援 | open_filex 沒有 macOS;更新流程沒有 macOS 實作 | 事實 | +| Entitlements | 網路:media_kit 與 just_audio 都要求 `com.apple.security.network.client`(README)。檔案:file_picker 要 User Selected File Read/Write(原始碼文檔)。media_kit 建議關掉 sandbox 才能存取檔案(README)。flutter_secure_storage 要 `keychain-access-groups`,還要 provisioning profile,否則只能在建置它的那台 Mac 上跑;或改用 `usesDataProtectionKeychain: false`(README) | 事實 | +| ATS | 網易雲的 http 串流需要 `NSAppTransportSecurity`(just_audio 與 media_kit README 都提到非 HTTPS 要設定) | 事實(README)+推測(網易雲 URL 的形式在 macOS 上是否一樣) | +| 平台政策 | 在 Mac App Store 上架時,更新只能經 App Store,不能下載或安裝額外程式碼(App Review Guidelines 2.4.5(iv)(vii))→ 自有更新器與 GitHub 下載流程不成立 | 事實 | +| 平台政策 | 5.2.3 禁止在未經授權下,從第三方來源(例子就包含 YouTube)下載或儲存媒體;5.2.2 要求第三方服務的使用授權 → 下載功能、以及整個 App 本身,在 App Store 上架都有風險 | 事實(guideline)+推測(審核實際結果) | +| 平台政策 | 不經 App Store 散佈時,需要 Developer ID 簽章與 notarization,否則 Gatekeeper 會擋 | 推測(未查官方來源) | +| 沙盒儲存 | 預設路徑 `getApplicationDocumentsDirectory()/FMP` 在沙盒下會落在 container 內;自選下載目錄要跨次啟動保存,需要 security-scoped bookmark,但程式碼只存字串路徑(`download_path_manager.dart:71-75`) | 推測 | +| 程式碼守衛 | 與 Linux 相同的 `Platform.isWindows` 守衛(§1.2、§1.3);標題列藏起來卻沒有替代 | 事實(程式碼) | +| 開發者工具 | `ProcessInfo.currentRss` 沒有對 macOS 開(`developer_options_page.dart:202`) | 事實(程式碼) | + +### 6.3 iOS + +| 類別 | 項目 | 標記 | +|---|---|---| +| 缺原生專案 | 沒有 `ios/` | 事實 | +| 背景播放 | `Info.plist` 要有 `UIBackgroundModes` → `audio`;系統可能在沒有播放音訊時殺掉閒置的程序,README 建議曲間播放靜音(audio_service README)。FMP 在換曲時才解析串流 URL(**推測**),曲間的網路等待有被殺的風險 | 事實+推測 | +| ATS | just_audio 用本機 proxy 實作 headers(B 站需要 Referer 等 headers),加上網易雲是 http → 需要 `NSAllowsArbitraryLoads`(just_audio README);也可以改 `useProxyForRequestHeaders: false`,但那依賴未公開的 `AVURLAssetHTTPHeaderFieldsKey` | 事實 | +| 平台政策:更新 | App 不能下載、安裝或執行會改變功能的程式碼(2.5.2);iOS 沒有讓 App 自己安裝 IPA 的公開途徑 → 整個 `UpdateService` 不成立,檢查更新入口應該移除,因為目前會出現「有新版」卻下載失敗(§1.4) | 事實(2.5.2)+推測(公開途徑) | +| 平台政策:內容 | 5.2.3(未授權從第三方來源下載或儲存媒體,例子明列 YouTube)與 5.2.2(第三方服務授權)→ 下載功能與非官方 API 串流在 App Store 上架風險很高;側載或 AltStore 類散佈不受這條限制,但有簽章期限等問題 | 事實(guideline)+推測(散佈管道) | +| 平台政策:登入 | YouTube 登入是在 WebView 開 Google 帳號頁,並偽裝 Windows Chrome UA(`youtube_login_page.dart:60-69`);Google 會不會在 WKWebView 擋登入,查不到 | 推測 | +| 功能不成立 | 托盤、全域快捷鍵、開機自啟、桌面歌詞視窗、自訂標題列、視窗管理:套件都不支援 iOS(§4);程式碼已經用守衛擋住 | 事實 | +| 沙盒儲存 | `MANAGE_EXTERNAL_STORAGE` 路線不適用;下載只能在沙盒內。設定頁在 iOS 會顯示「變更下載路徑」(`settings_storage.dart:60`),選到沙盒外的目錄時 **推測**會寫入失敗;使用者要從「檔案」App 看到下載的檔案,需要 `UIFileSharingEnabled` 或 `LSSupportsOpeningDocumentsInPlace`(**推測**,未查官方來源) | 事實(程式碼)+推測 | +| 匯出流程 | 備份與 log 匯出在 iOS 呼叫 `saveFile` 時沒帶 bytes(`backup_service.dart:58-70`、`log_viewer_page.dart:123-133`) | 推測(會失敗) | +| Keychain | flutter_secure_storage 需要 `keychain-access-groups` entitlement;預設 accessibility 是 `unlocked`(README)。**推測**:背景刷新 cookie 時如果裝置鎖定,會讀不到憑證 | 事實+推測 | +| 外部 App scheme | `bilibili://` 會先嘗試開啟(`url_launcher_service.dart:105`);**推測**:`launchUrl` 在沒裝 App 時回 false,再退回網頁,可以運作 | 推測 | +| 字型、UI | 「系統預設字型」標示成 Roboto(`settings_appearance.dart:322`);CJK fallback 用沒內建的 Noto Sans SC | 推測 | + +## 7. 建議放進決策清單:每個平台綁定功能在其他平台上的去留 + +下列只列出需要做決定的題目,不預設答案: + +1. **支援平台的正式定義**:ADR 0003、`pubspec.yaml:24` 與 `platform_utils.dart`、`audio_controller_provider.dart:23-25` 的註解立場不一致。要先定下 Linux / macOS / iOS 各自是「目標」「不支援」還是「程式碼裡不留分支」。如果不支援,要不要刪掉 `main.dart:202,232` 等殘留分支。 +2. **音訊後端**:各平台用 just_audio 還是 media_kit;macOS / Linux / iOS 的原生庫要用 `media_kit_libs_audio` 還是依賴系統的 libmpv;已 unlisted 的 `media_kit_libs_windows_audio` 要不要換掉。 +3. **系統媒體控制**:macOS 要不要接 audio_service(現在是關的);Linux 要不要接 MPRIS;`NowPlayingPublisher` 的 desktop 分支要不要從「SMTC 或什麼都沒有」改成依平台分派。 +4. **自動更新**:iOS 移除;macOS 看散佈管道決定(Mac App Store 禁止);Linux 看打包格式(AppImage / Flatpak / deb)。另外,目前在不支援的平台上會出現更新提示卻不能下載,這件事本身要不要先修掉。 +5. **下載功能**:iOS / Mac App Store 版本要不要保留(5.2.3);Android 的 `MANAGE_EXTERNAL_STORAGE` 路線要不要改成 SAF 或 app 專屬目錄;Android 在設定頁不能改下載路徑,這是刻意設計還是遺漏。 +6. **登入方式**:Linux 沒有 WebView 時,各音源改用 QR 或其他方式,還是換 WebView 套件(例如 `desktop_webview_window`);YouTube 沒有 QR 登入時怎麼辦。 +7. **托盤、全域快捷鍵、開機自啟、關閉縮托盤**:macOS / Linux 要不要開(套件都支援,程式碼寫死 Windows);Linux Wayland 下的全域快捷鍵要不要支援。 +8. **桌面歌詞視窗**:macOS / Linux 要不要開(需要 runner 註冊子視窗插件,並放寬守衛);Android 寬版面出現沒作用的按鈕,要隱藏還是實作懸浮歌詞。 +9. **視窗外觀**:`TitleBarStyle.hidden` 加自訂標題列要不要擴展到 macOS / Linux,還是非 Windows 平台保留系統標題列。 +10. **字型策略**:要不要內建 CJK 字型,還是依平台寫 fallback 清單。 +11. **平台判斷的寫法**:`Platform.isWindows`、`isDesktopPlatform`、`AudioRuntimePlatform` 三種並存,要不要收斂成「能力旗標」(例如 `supportsTray`、`supportsSelfUpdate`);另外,CI 的單元測試其實跑在 Linux 分支(§1.10)。 diff --git a/docs/audit/playback.md b/docs/audit/playback.md new file mode 100644 index 000000000..001d6c6aa --- /dev/null +++ b/docs/audit/playback.md @@ -0,0 +1,461 @@ +# 播放管線審計(playback) + +> 現況描述,未經確認,不代表目標。 + +- 範圍:`lib/services/audio/`、`lib/providers/audio/`、`lib/data/sources/` 的串流解析、`lib/services/radio/radio_controller.dart` 與後端共用的部分。 +- 方法:只讀原始碼(分支 `docs/audit`)。沒有跑 App、沒有跑測試、沒有打真實 API。所以本文件每一條都屬於「程式碼層級」證據;標「**推測**」的是從程式碼推導出、但沒有實際重現過的行為。 +- 註釋、dartdoc、`docs/`、`.trellis/spec/` 都當作未經確認的主張。與程式碼不一致之處標「**不一致**」。 + +--- + +## 0. 一頁摘要 + +| 項目 | 實際做法(程式碼) | +|---|---| +| UI 入口 | 幾乎所有「點一首歌」都走 `AudioController.playTemporary`(搜尋、歌單詳情、首頁、排行、歷史、已下載、匯入預覽)。佇列頁走 `playAt`。`playSingle` / `playAll` / `playPlaylist` **沒有任何 UI 呼叫端**;`shuffleQueue` 只有佇列頁的打亂按鈕呼叫(`lib/ui/pages/queue/queue_page.dart:323`,非 Mix 模式才顯示)。 | +| 單一播放管線 | `AudioController._executePlayRequest` → `PlaybackRequestSession.start` → `AudioStreamManager.selectPlayback` → `DefaultStreamResolutionService.resolvePrimary` → 音源 adapter `getAudioStream` → `FmpAudioService.playMedia` | +| 後端 | Android:`JustAudioService`(just_audio 0.10 → ExoPlayer)。Windows:`MediaKitAudioService`(media_kit → libmpv)。由 `audioServiceProvider` 依平台選擇(`lib/providers/audio/audio_controller_provider.dart:26-32`) | +| 系統媒體控制 | Android:`audio_service` 的 `FmpAudioHandler`。Windows:`smtc_windows` 的 `WindowsSmtcHandler`。唯一出口是 `NowPlayingPublisher`,由它在音樂與電台之間仲裁 | +| 串流 | Bilibili:自己打 `/x/player/playurl`(DASH m4a,退 durl/flv)。YouTube:`youtube_explode_dart`(androidVr 拿 audio-only,退 ios/safari/android muxed,再退 HLS),有登入時補打 InnerTube WEB `/player`。網易雲:eapi `song/enhance/player/url/v1` | +| 預載 | 兩層:(1) 下一首 URL 預解析;(2) gapless「arm」:把下一首交給後端播放清單,由後端自己接上去 | +| 錯誤恢復 | 開流失敗會換一次 fallback 串流;網路類錯誤走 1/2/4/8/16 秒退避、最多 5 次;音源「不可用」在佇列模式下自動跳下一首;緩衝超過 15 秒會救一次 | +| 狀態來源 | 至少 5 份:後端快取欄位、`PlayerState`、`QueueState`、`QueueManager` 內部索引、系統媒體控制狀態(另外電台還有 `RadioState`) | + +--- + +## 1. 從「點一首歌」到「出聲」 + +### 1.1 典型入口:搜尋結果點擊 + +`lib/ui/pages/search/search_page.dart:481-486`:`onPlayTrack` 呼叫 `controller.playTemporary(track)`(B 站多 P 影片走 `_playVideo`,`search_page.dart:796-814`,也是 `playTemporary`)。 + +```mermaid +sequenceDiagram + autonumber + participant UI as SearchPage + participant AC as AudioController + participant TPH as TemporaryPlayHandler + participant PRS as PlaybackRequestSession + participant RC as RadioController + participant BE as FmpAudioService + participant ASM as AudioStreamManager + participant SRS as StreamResolutionService + participant SRC as 音源 adapter + participant AUTH as SourceAuthContext + participant SE as PlaybackSideEffects + + UI->>AC: playTemporary(track) + Note right of UI: search_page.dart:485 + AC->>AC: _ensureInitialized / _resetRetryState / _cancelActivePlaybackRequest + Note over AC: audio_provider.dart:609-613, 571-574 + AC->>TPH: enterTemporary(存佇列 index/position/wasPlaying) + Note over AC,TPH: audio_provider.dart:617-624, temporary_play_handler.dart:47-67 + AC->>AC: _executePlayRequest(mode temporary, persist false, prefetchNext false) + Note over AC: audio_provider.dart:627-633, 1804-1818 + AC->>SE: _updatePlayingTrack(track) countsAsNewPlay false + Note over AC,SE: audio_provider.dart:1384-1408 先把歌名推到通知列/SMTC + AC->>PRS: start(PlaybackSessionCommand) + Note over PRS: playback_request_session.dart:211 + PRS->>PRS: _enterLoading 產生 requestId + PRS-->>AC: onLoadingStarted -> _startSessionLoadingState isLoading true + Note over PRS,AC: playback_request_session.dart:466-473, audio_provider.dart:1429-1446 + PRS->>RC: onPlaybackStarting 若電台在播就 stop + Note over PRS,RC: radio_controller.dart:384-388 + PRS->>BE: stop() + Note over PRS,BE: playback_request_session.dart:508-511 + PRS->>ASM: selectPlayback(track, persist) 預算 T1 25s + Note over PRS,ASM: playback_request_session.dart:524-529 + ASM->>SRS: resolvePrimary(purpose playback) + Note over ASM,SRS: audio_stream_manager.dart:47-65 + SRS->>SRS: 本機下載檔存在就直接回 LocalStreamResolution + Note over SRS: stream_resolution_service.dart:128-145 + SRS->>AUTH: authForPlay(sourceType) 依 useAuthForPlay 設定 + Note over SRS,AUTH: stream_resolution_service.dart:400-418, source_auth_context.dart:133-137 + SRS->>SRS: _reusableResolution 行程內快取命中就重用 + Note over SRS: stream_resolution_service.dart:348-368 + SRS->>SRC: fetchAudioStreamWithQualityFallback 依音質逐級下降 + Note over SRS,SRC: audio_stream_quality_fallback.dart:42-67 + SRC-->>SRS: AudioStreamResult(url, bitrate, codec, expiry, cid) + SRS->>SRS: _applyStreamResult 就地寫 url/expiry/cid, 記快取, 視 persist 寫 Isar + Note over SRS: stream_resolution_service.dart:420-481 + ASM->>AUTH: playbackNetworkRequest -> MediaHandoff 加 CDN headers + Note over ASM,AUTH: audio_stream_manager.dart:141-154, media_handoff.dart:54-62, source_http_policy.dart:82-84 + ASM-->>PRS: PlaybackSelection(RemotePlaybackMedia 或 LocalPlaybackMedia) + PRS->>BE: playMedia(media) 預算 T2 8s + Note over PRS,BE: playback_request_session.dart:693-716 + alt Android JustAudioService + BE->>BE: stop, 等 idle, session.setActive(true), setAudioSources([uri+headers]), 不 await play() + Note over BE: just_audio_service.dart:536-581 + else Windows MediaKitAudioService + BE->>BE: stop, 等 idle, open(Media(url, httpHeaders), play false), 輪詢時長, _ensurePlayback 最多 5s 後 play() + Note over BE: media_kit_audio_service.dart:738-808, 661-702 + end + opt playMedia 拋錯 + PRS->>ASM: selectFallbackPlayback(failedUrl) 只試一次 + Note over PRS,ASM: playback_request_session.dart:538-589 + end + PRS-->>AC: PlaybackSessionResult.completed + AC->>AC: _exitLoadingState isLoading false, 碼率/格式, _mode = temporary + Note over AC: audio_provider.dart:1490-1531 + AC->>SE: _updatePlayingTrack(trackWithUrl) countsAsNewPlay true + Note over AC,SE: 播放歷史 + 歌詞自動比對 + 通知列/SMTC + BE-->>AC: playerStateStream(playing, ready) + AC->>AC: PlaybackEventRouter.routePlayerState -> ProjectPlayerState + Note over AC: audio_provider.dart:2363-2405, playback_event_router.dart:351-388 + AC->>SE: onPlaybackStateChanged -> 通知列/SMTC 顯示播放中 +``` + +補充: +- `_exitLoadingState` 在離開載入時會用後端「當下」的狀態補投影一次(`audio_provider.dart:1524-1530`),因為 Windows 上零位元組串流在開流時就進了 buffering、之後不再發事件(註釋所述,**未驗證**)。 +- Android 的 `playMedia` 在來源設好後就返回,`play()` 沒有被 await(`just_audio_service.dart:569-573`)。所以 `completed` 結果**不代表已出聲**,只代表 ExoPlayer 接受了來源。Windows 則會等到 ready 才 `play()`(最多 5 秒,0.5 秒後仍 idle 就丟 `StreamOpenFailedException`,`media_kit_audio_service.dart:672-686`)。 +- 臨時播放 `prefetchNext: false`(`audio_provider.dart:632`),所以不會預解析下一首。 + +### 1.2 其他入口是否走同一條路 + +| 入口 | 呼叫 | 走到哪裡 | 差異 | +|---|---|---|---| +| 搜尋、歌單詳情、首頁、排行、歷史、已下載、匯入預覽、TrackAction 選單「播放」 | `playTemporary` | `_executePlayRequest` | `search_page.dart:485,806-812`、`playlist_detail_page.dart:932`、`home_page.dart:725`、`ranking_track_tile.dart:66`、`play_history_page.dart:633`、`downloaded_category_page.dart:381`、`import_preview_page.dart:1081`、`track_action_handler.dart:97,263` | +| 佇列頁點歌、首頁佇列區 | `playAt` | `_playTrack` → `_executePlayRequest(mode queue/mix, persist true, prefetchNext true)` | `queue_page.dart:459`、`home_page.dart:1066`、`audio_provider.dart:994-1010, 2269-2279` | +| 下一首 / 上一首(UI、通知列、SMTC) | `next` / `previous` | 同上;脫離佇列時改走 `_returnToQueue` | `audio_provider.dart:1012-1085` | +| 歌單詳情「Mix 播放」 | `playMixPlaylist` | `_queueManager.playAll` 後 `_executePlayRequest(mode mix)` | `playlist_detail_page.dart:921`、`audio_provider.dart:912-972` | +| 歌單卡片選單「Mix」 | `startMixFromPlaylist` | 先抓 Mix 曲目,再呼叫 `playMixPlaylist` | `playlist_card_actions.dart:164`、`audio_provider.dart:865-897` | +| App 啟動恢復上次歌曲 | `_prepareCurrentTrack` | `PlaybackRequestSession.restore`(`setMedia`,不播) | `audio_provider.dart:422-428, 2282-2361` | +| 臨時播放結束 / 從電台返回 | `_restoreQueuePlayback` | `PlaybackRequestSession.restore`(`setMedia` + seek + 視情況 `play`) | `audio_provider.dart:662-775`、`playback_request_session.dart:279-339, 607-691` | +| 網路重試 / 緩衝飢餓救援 | `retryPlayback` | `PlaybackRequestSession.start(persist false)` | `audio_provider.dart:2003-2066` | +| 歌單詳情「全部」按鈕 | `addAllToQueue` | **不播放**,只加到佇列尾 | `playlist_detail_page.dart:850-852, 884-890`(方法名叫 `_playAll`,實際行為是加入佇列) | + +結論:所有「開始播一首」最後都收斂到 `PlaybackRequestSession` 的 `start` 或 `restore`。例外是 gapless 交界,由後端自己接下一首,控制器只跟帳(見 §3.5)。電台完全不走這條路(見 §3.12)。 + +--- + +## 2. 播放器狀態機 + +### 2.1 實際存在的狀態欄位 + +| 欄位 | 所在 | 誰寫 | +|---|---|---| +| `isLoading` / `isPlaying` / `isBuffering` / `processingState` | `PlayerState`(`player_state.dart:12-80`) | `_startSessionLoadingState`、`_exitLoadingState`、`_projectPlayerState`、`_resetLoadingState`、`_handleTerminalMediaOpen`、`_onBackendAdvanced`、`_onTransportFailure`、`_recoverFromPrematureCompletion`、`_handleSourceError`、`playAll` / `playSingle` / `playMixPlaylist` 直接寫、session 的 `onLoadingFinished` 閉包(`audio_provider.dart:239-252`) | +| `error` | `PlayerState` | 同上加 `play()` / `togglePlayPause()` 的 catch、`_applyQueueMutation`、`_applyRecoveryEvent` | +| `isNetworkError` / `isRetrying` / `retryAttempt` / `nextRetryAt` | `PlayerState` | 只經 `_applyRecoveryState`(`audio_provider.dart:2109-2121`),外加 `retryPlayback` 成功時直接清(`2034-2041`) | +| `_mode`(queue / temporary / detached / mix) | `AudioController` 私有欄位(`audio_playback_types.dart:1`) | `playTemporary`、`_exitLoadingState`、`clearQueue`、`_exitMixMode`、`_playFirstInQueue`、初始化恢復 Mix | +| 交接中的 requestId | `PlaybackHandoffGate`(閂存)與 `PlaybackRequestSession._requestId` | session 產生,gate 複製 | +| 後端狀態 | `JustAudioService` / `MediaKitAudioService` 的 `BehaviorSubject` 與快取欄位 | 後端自己,並在 `stop()` / `playUrl()` 時手動合成 `idle` / `loading`(`just_audio_service.dart:388-397, 551-557`;`media_kit_audio_service.dart:520-529, 760-766`) | +| Windows 的 `processingState` | **合成值**:completed > buffering > playing→ready > 有時長→ready > idle | `media_kit_audio_service.dart:449-466` | + +`processingState` 列舉:`idle / loading / buffering / ready / completed`(`audio_types.dart:2-17`)。控制器投影時套用一條規則:自己在載入中而後端說 `idle`,就改報 `loading`、位置報 0(`effective_playback_state.dart:23-47`)。 + +### 2.2 狀態圖(由程式碼推導的使用者可見狀態) + +```mermaid +stateDiagram-v2 + [*] --> Idle + state "Idle 無歌或已停止" as Idle + state "Loading isLoading=true" as Loading + state "Playing isPlaying=true ready" as Playing + state "Paused isPlaying=false" as Paused + state "Buffering isBuffering=true" as Buffering + state "RetryScheduled isNetworkError+isRetrying" as RetryScheduled + state "RetryExhausted isNetworkError, !isRetrying" as RetryExhausted + state "SourceError error!=null 停止" as SourceError + state "TerminalMediaOpenError error!=null idle" as TerminalErr + state "DroppedWhilePaused 記號, UI 仍是 Paused" as Dropped + + Idle --> Loading: playTemporary / playAt / next / previous + Loading --> Playing: session completed, 後端 playing + Loading --> Paused: restore(shouldResume=false) 啟動恢復 + Loading --> Loading: 新請求取代舊請求 superseded + Loading --> RetryScheduled: 網路/逾時類 SourceApiException 或 Socket/Http/Tls/Timeout + Loading --> SourceError: unavailable/geo/vip 且非 queue 模式, 或其他音源錯誤, 或 PlaybackTimeoutException + Loading --> Loading: unavailable 且 queue 模式有下一首, 300ms 後 next() + Loading --> TerminalErr: 開流錯誤 2 秒內沒自癒 + Playing --> Paused: pause / 耳機拔出 / 中斷 (Android) + Paused --> Playing: play / togglePlayPause + Paused --> Loading: play 時 URL 過期或暫停中斷線 + Playing --> Buffering: 後端 buffering + Buffering --> Playing: 緩衝恢復 + Buffering --> Loading: 連續 15 秒, 第一次救援 invalidate + retryPlayback + Buffering --> TerminalErr: 同一首第二次飢餓 + Playing --> RetryScheduled: TransportFailed 播放中 / EndedPrematurely + Paused --> Dropped: TransportFailed 暫停中 + Dropped --> Loading: 使用者按播放 + RetryScheduled --> Loading: 計時到 1,2,4,8,16s + RetryScheduled --> RetryExhausted: 第 5 次仍失敗 + RetryExhausted --> Loading: retryManually / 網路恢復 / togglePlayPause + SourceError --> Loading: togglePlayPause 重播當前曲 + TerminalErr --> Loading: togglePlayPause 重播當前曲 + Playing --> Loading: 自然播完 -> 單曲循環重播 / 推進佇列 / 回佇列 + Playing --> Playing: gapless 交界, 後端自己接上下一首 + Playing --> Paused: 佇列播完 PauseAtQueueEnd + Playing --> Idle: stop() +``` + +證據對照: +- 載入 / 完成:`playback_request_session.dart:211-277`、`audio_provider.dart:1429-1531`。 +- 退避階梯:`playback_recovery_coordinator.dart:157-215`,次數與延遲在 `app_constants.dart:226-235`(`maxRetries = 5`,1/2/4/8/16 秒)。 +- 開流錯誤自癒窗 2 秒:`playback_request_session.dart:162-163, 341-406`。 +- 緩衝飢餓:`buffer_starvation_watchdog.dart`(15 秒,`app_constants.dart:199`)、`playback_event_router.dart:507-522`、`audio_provider.dart:2448-2496`。 +- 完成路由:`playback_event_router.dart:458-470`。 +- 暫停中斷線:`playback_event_router.dart:429-440`、`audio_provider.dart:2513-2517, 2226-2267`。 + +### 2.3 幾份狀態來源、會不會不同步 + +```mermaid +flowchart LR + ENG[ExoPlayer / libmpv] --> BE[後端 BehaviorSubject 與快取欄位] + BE -->|playerStateStream 等 9 條流| AC[AudioController] + AC --> PS[PlayerState] + AC --> QS[QueueState 經 queueStateProvider] + QM[QueueManager 內部 _tracks/_currentIndex/_shuffleOrder] -->|stateStream| AC + AC -->|PlaybackSideEffect| NPP[NowPlayingPublisher] + NPP --> AH[FmpAudioHandler.playbackState Android] + NPP --> SMTC[WindowsSmtcHandler Windows] + RADIO[RadioController / RadioState] -->|直接呼叫| BE + RADIO --> NPP + BE -->|playerStateStream| RADIO +``` + +已確認(程式碼層級)的不同步點: +1. **正在播的歌 vs 佇列的當前歌**:`PlayerState.playingTrack` 與 `QueueManager.currentTrack` 刻意可以不同(臨時播放、清空佇列後的 detached)。判斷「脫離佇列」靠 `_isPlayingOutOfQueue`(`audio_provider.dart:2181-2192`),以 `Track.id` 比較。 +2. **通知列 / SMTC 位置**:有 500ms 節流(`audio_provider.dart:2421-2427`)。Android 通知的總時長取自 `track.durationMs` 元資料,不是後端回報的實際時長(`audio_handler.dart:83-85`);`publishPlaybackState` 在 Android 分支也沒傳 duration(`now_playing_publisher.dart:187-194`)。 +3. **音量**:Android 音訊焦點 duck 直接改後端音量(`just_audio_service.dart:174-177`),`PlayerState.volume` 不知道。 +4. **Android 中斷恢復**:中斷結束時 `JustAudioService` 自己呼叫 `play()`(`just_audio_service.dart:194-199`),繞過 `AudioController.play()` 的 URL 過期檢查(`audio_provider.dart:485-494`)。 +5. **電台期間**:控制器對位置、時長、緩衝事件直接 return(`audio_provider.dart:2410, 2589, 2599`),`PlayerState` 停在電台開始前的值。 +6. **Android `isPlaying` getter**:讀 `_player.playing`(`just_audio_service.dart:108`),`processingState` getter 卻讀自己的 BehaviorSubject(`120-121`),而 `stop()` / `playUrl()` 會往 subject 手動塞合成值。兩個 getter 在短時間內可能描述不同的瞬間(**推測**)。 +7. **Windows `isPlaying`** 來自 `stream.playing`,`processingState` 是合成的;`bufferedPosition` 的量級與 Android 不同(`audio_service.dart:35-38` 的 dartdoc,**未驗證**)。 + +--- + +## 3. 各主題 + +### 3.1 佇列與播放模式 + +**做法** +- 佇列本體在 `QueueManager`:`_tracks`、`_currentIndex`、`_shuffleOrder`、`_shuffleIndex`(`queue_manager.dart:21-34`)。`AudioController` 自己不存佇列,只投影成 `QueueState`(`audio_provider.dart:2878-2952`)。 +- 循環:`LoopMode.none / all / one`,`cycleLoopMode` 依 none → all → one 輪轉(`queue_manager.dart:732-740`)。 +- 單曲循環**不在 `getNextIndex` 裡**,而是在完成路由裡優先判斷,重播用 `_playTrack` 重開一次流(`playback_event_router.dart:465`、`audio_provider.dart:2820-2823`)。所以單曲循環每一圈都要重新走一次解析與開流(通常命中行程內快取),而且每一圈都 `countsAsNewPlay: true`,也就是每圈記一筆播放歷史(`audio_provider.dart:2276`)。 +- 隨機(非破壞性):開啟時產生一份索引排列,當前曲放第一位(`queue_manager.dart:753-767`);`getNextIndex` / `getPreviousIndex` 沿著排列走(`324-375`)。 +- 破壞性打亂 `shuffle()` 與 `restoreOrder()` 存在(`queue_manager.dart:616-664`),`shuffleQueue` 由佇列頁打亂按鈕呼叫(`lib/ui/pages/queue/queue_page.dart:323`,主審查更正:子代理初稿誤記為無呼叫端),但 **`restoreOrder` 沒有任何呼叫端**。 +- 加入:`add` 檢查 `maxQueueSize = 10000`(`queue_manager.dart:472`、`app_constants.dart:35`);Mix 模式下 `add/addAll/addNext/shuffle` 被 `QueueCommands` 擋下(`queue_commands.dart:52-123`)。 +- 持久化:`PlayQueue` 存 `trackIds`、`currentIndex`、`lastPositionMs`、`lastVolume`、`isShuffleEnabled`、`loopMode`、`originalOrder`、Mix 身分(`queue_persistence_manager.dart:78-128`、`queue_manager.dart:686-730`)。位置每 10 秒存一次(`queue_manager.dart:819-824`、`app_constants.dart:54`),seek 後立即存(`audio_provider.dart:576-582`)。**隨機排列本身不持久化**,重啟時重新產生(`queue_manager.dart:210-212`)。 +- 啟動 10 秒後刪除「不屬於任何歌單、也不在佇列裡」的 Track 列(`queue_manager.dart:224-227, 830-843`)。 + +**邊界與觀察到的問題** +- `addAll` 與 `insert` 不檢查 `maxQueueSize`(`queue_manager.dart:500-556`),只有 `add` 檢查。 +- **隨機模式下「下一首播放」不會是下一首**:`addNext` → `insert` → `_addToShuffleOrder`,後者把新索引插在當前位置之後的**隨機**位置(`queue_manager.dart:541-547, 775-786`)。**推測**這不是使用者預期。 +- **`move()` 不更新 `_shuffleOrder`**(`queue_manager.dart:594-613`):排列裡存的是 `_tracks` 的索引,拖動重排後同一個索引指到別首歌。隨機模式下拖動佇列後,接下來播放的歌會和畫面上的「接下來」不一致(**推測**,程式碼路徑明確,未實跑)。 +- `next()` / `previous()` 的 `_navRequestId` 防競態檢查是**死碼**:遞增與比較之間沒有任何 `await`(`audio_provider.dart:1017-1032, 1050-1070`),不可能不相等。實際防競態靠的是 session requestId。**不一致**:`.trellis/spec/services/audio.md` 的 Races 段把它列為獨立防線。 +- `previous()` 超過 3 秒時直接呼叫 `_audioService.seekTo(Duration.zero)`(`audio_provider.dart:1063-1065`),繞過 `seekTo()` 的延後 seek 與立即存位置。 + +### 3.2 串流解析 + +共通:`DefaultStreamResolutionService.resolvePrimary`(`stream_resolution_service.dart:123-168`) + +1. 非下載用途先查本機下載檔(`File.existsSync`,同步 I/O),不存在的路徑從 DB 清掉並發 `downloadPathsChanged` 事件(`128-145, 483-526`)。 +2. 讀設定組 `AudioStreamConfig`(音質、格式優先序、該音源的串流類型優先序)與 `authForPlay`(`400-418`)。 +3. 行程內 LRU 快取(上限 32,`113`)重用條件:track 的 URL 未過期、快取 URL 相同、設定相同、auth header 相同(`348-368`)。 +4. 未命中就呼叫 adapter;限流錯誤等 3 秒重試一次,其他錯誤等 1 秒重試一次(`207-246`、`app_constants.dart:138-146`)。 +5. `_applyStreamResult` 就地把 URL、到期時間、cid 寫進傳入的 track,視 `persist` 寫回 Isar(`420-481`)。沒有 `expiry` 時預設 1 小時(`428-430`)。 + +Media 請求 header:一律只有 CDN 的 Origin/Referer 加 UA,**不帶帳號憑證**(`source_http_policy.dart:73-84`、`media_handoff.dart:54-62`)。 + +| 音源 | 取法 | 格式 | 到期時間 | +|---|---|---|---| +| Bilibili | 無 cid 先打 `/x/web-interface/wbi/view` 拿 cid(`bilibili_source.dart:456-473`),再依 `streamPriority` 打 `/x/player/playurl`:`fnval=16` DASH(`327-382`)或 `fnval=0` durl(`385-425`);HLS 回 null | DASH:`container 'm4a'`、`codec 'aac'` 寫死(`374-376`);durl:`flv` muxed | 從 URL 的 `deadline` 參數算,缺就 2 小時(`432-445`) | +| YouTube | `youtube_explode_dart`:audio-only 用 `androidVr`,muxed 用 `ios/safari/android`,HLS 試 safari、ios、兩者(`youtube_source.dart:444-583`)。每種類型先匿名,失敗且有 auth 時用 InnerTube WEB `/player` 同類型再試(`332-378`) | audio-only 依 `formatPriority`(opus/aac)挑;muxed 依位元率 | **寫死 1 小時**(`youtube_source.dart:52-54`、`app_constants.dart:29`),不讀 URL 的 `expire` | +| 網易雲 | eapi `/eapi/song/enhance/player/url/v1`,`level` 由音質對應 lossless / exhigh / standard(`netease_source.dart:93-171, 785-794`) | 依回傳 `type`(mp3/flac/m4a…) | 用 API 的 `expi`(缺值時用防守值),註釋說實測 1200 秒(`netease_source.dart:40, 160-162`) | + +預設串流優先序:B 站 `audioOnly,muxed`、YouTube `audioOnly,muxed,hls`、網易 `audioOnly`(`settings.dart:59-63`)。預設帶登入解析:B 站、網易(`settings.dart:76-79`)。 + +**觀察** +- 網易雲的試聽片段(`freeTrialInfo != null`)只寫進 log,照常當完整歌曲回傳(`netease_source.dart:139-150`)。**推測**:使用者只會聽到片段然後跳下一首,沒有任何提示。 +- Bilibili `_getCid` 只取影片第一個 cid(`bilibili_source.dart:465`),`request.pageNum` 在 `getAudioStream` 裡沒被使用(`213-241`)。如果某個分 P track 帶 `pageNum` 卻沒有 `cid`,會解析到 P1 的音訊(**推測**:需要確認這種 track 是否真的存在)。 +- Bilibili 與 YouTube 的 `getAudioStream` / `getAlternativeAudioStream` 是兩套幾乎重複的實作(`bilibili_source.dart:213-321` vs `683-736`;`youtube_source.dart:444-583` vs `712-850`)。 +- 網易雲 `getAlternativeAudioStream` 一律回 null(`netease_source.dart:174-178`),fallback 只能靠降音質。 + +### 3.3 URL 過期重取 + +- 判斷:`Track.hasValidAudioUrl` 在到期前 5 分鐘就視為無效;**`audioUrlExpiry == null` 時永遠有效**(`track.dart:283-293`)。 +- 重取時機: + 1. 每次播放請求都經 `resolvePrimary`,過期或快取不中就重打(`stream_resolution_service.dart:147-167`)。 + 2. 暫停後按播放:`_resumeWithFreshUrlIfNeeded` 發現 URL 過期(或暫停中斷線)就重新 `_playTrack`,成功後延遲 500ms 再 seek 回原位置(`audio_provider.dart:2226-2267`)。已下載檔案排除。 + 3. 播放失敗(傳輸失敗、提前結束、媒體開啟失敗、緩衝飢餓)時先 `invalidateResolvedStream` 丟掉快取(`audio_provider.dart:2512, 2575, 2731, 2455`)。 +- 播放中**不檢查**過期:`seekTo` 沒有過期判斷(`audio_provider.dart:544-555`)。Windows 的 mpv 設了 `cache-secs=7200` 會一次抓完(`media_kit_audio_service.dart:216-237`),Android 只緩衝 10~20 秒(`just_audio_service.dart:153-160`),所以長曲目在 Android 上播到 URL 過期之後才讀的片段會失敗,進傳輸失敗重試路徑(**推測**)。 + +**觀察:Isar 裡的 URL 讓預取失效**(**推測**,程式碼路徑明確) +- `prefetchTrack` 在 `track.hasValidAudioUrl` 為真時直接 return(`stream_resolution_service.dart:299-304`)。 +- 但實際播放時的重用還要求行程內快取有這一筆(`355-356`)。 +- 重啟後,從 Isar 載入、帶著未過期 URL 的 track 會跳過預取,輪到它播放時快取又是空的,只好現場重新解析。`_armNextMedia` 的註釋說命中預取就不打網路(`audio_provider.dart:1669-1671`),在這個情況下不成立。 + +### 3.4 音質降級 + +- 設定:`AudioQualityLevel.high / medium / low`、`formatPriority`、每個音源的 `streamPriority`(`audio_settings_provider.dart:176-220`、`base_source.dart:43-50`)。 +- 等級選取:清單依位元率由高到低排好,high 取第一、medium 取中間、low 取最後(`audio_stream_quality_fallback.dart:9-20`)。 +- 主解析降級:只有 `unavailable` / `vipRequired` 會往下一級重試(`audio_stream_quality_fallback.dart:42-67`、`source_exception.dart:23-25`)。網路錯誤不降級。 +- 開流失敗的 fallback:`resolveFallback` 從**低一級**開始,每級先問 adapter 的 alternative,再試主解析但排除失敗的 URL,最後用原等級問一次 alternative(`audio_stream_quality_fallback.dart:69-96`)。一次請求只 fallback 一次(`playback_request_session.dart:538-589`),而且 fallback 結果 `persist: false`(`stream_resolution_service.dart:254`)。 +- 整次請求上限 T1+T2 = 33 秒,fallback 只能用剩下的時間(`playback_request_session.dart:524, 748-754`、`app_constants.dart:222`)。 + +**觀察**:B 站 DASH 不論實際 codec 一律標 `aac`/`m4a`(`bilibili_source.dart:374-376`),播放頁顯示的格式可能不準(**推測**)。B 站 DASH 回應裡的 `flac` / `dolby` 軌完全沒讀。 + +### 3.5 預載 + +兩層,都掛在成功開流之後: + +1. **URL 預解析**:`_prefetchNextIfRequested` 取 `getNextIndex()` 那一首(佇列裡的實例,不是 copy),fire-and-forget 呼叫 `prefetchTrack`(`playback_request_session.dart:809-829`)。`prefetch` 不落盤(`stream_resolution_service.dart:307-316`)。臨時播放不預取(`audio_provider.dart:632`);啟動恢復會預取(`playback_request_session.dart:683-684`),而 `_prepareCurrentTrack` 又自己預取一次(`audio_provider.dart:2349-2353`),靠 `_prefetchingTrackIds` 與 `hasValidAudioUrl` 去重。 +2. **Gapless arm**:預取完成後 session 回呼 `_armNextMedia`,再 `selectPlayback(persist:false)` 一次,交給 `setNextMedia`(`audio_provider.dart:1664-1699`)。 + - 條件:不脫離佇列、非單曲循環、電台沒占用、Mix 沒在補歌(`1651-1662`)。 + - Android:往 just_audio 播放清單 append,`useLazyPreparation: false` 讓第二項立刻準備(`just_audio_service.dart:148-152, 676-703`)。 + - Windows:mpv 播放清單 append,加上 `prefetch-playlist=yes`(`media_kit_audio_service.dart:250, 961-986`)。 + - 後端索引前進時發 `advancedToNext`,控制器在 `_onBackendAdvanced` 跟帳:`moveToNext`、更新 playingTrack、記歷史、接著預取並 arm 再下一首(`audio_provider.dart:1721-1782`)。 + - 保險:arm 期間位置檢查連續 3 秒停在結尾,就收回推進權、自己合成一次「播完」(`playback_event_router.dart:487-498`)。 + - 佇列任何變動都會重算,下一首不是 arm 的那首就 disarm(`audio_provider.dart:2879-2886`)。 + +**觀察**:arm 的 URL 在交界時才真正被讀,如果下一首 arm 之後使用者暫停很久,arm 的 URL 可能過期;交界時由後端自己開流,控制器沒有機會重解析(**推測**)。 + +### 3.6 錯誤恢復 + +| 失敗來源 | 分類位置 | 處理 | 上限 | 使用者看到 | +|---|---|---|---|---| +| 解析階段 `SourceApiException` network / timeout | `source_exception.dart:15-16` | 退避重試 | 5 次 | NetworkStatusBanner(`network_status_banner.dart:26-147`),耗盡後停在網路錯誤、可手動重試 | +| 解析階段 unavailable / geo / vip | `source_exception.dart:18-21` | queue 模式且有下一首:300ms 後 `next()`;否則 stop 並設 error | — | 警告 toast「已跳過」或錯誤 toast(`audio_provider.dart:1945-1983`) | +| 解析階段 rateLimited | — | 設 error,不重試(解析層已等 3 秒重試過一次) | — | 警告 toast | +| `PlaybackTimeoutException`(T1/T2 預算耗盡) | `playback_error_presenter.dart:67` | 不進退避 | — | 錯誤 toast「連線逾時」(`audio_provider.dart:1908-1915`) | +| Dart `Socket/Http/Tls/TimeoutException` | `playback_error_presenter.dart:64-80` | 退避重試 | 5 次 | 同上 | +| 後端 `TransportFailed`(播放中) | 後端翻譯 | stop 後進退避 | 5 次 | banner | +| 後端 `TransportFailed`(暫停中) | router | 只記號,按播放時重開 | — | 無 | +| 後端 `EndedPrematurely` | `playback_end_reason_rules.dart:23-34` | 從當前位置退避重試 | 5 次 | banner | +| 後端 `MediaUnopenable` / `DecoderFailed` | 後端翻譯 | 等 2 秒,後端自己往前走 0.5 秒以上算自癒,否則 stop | 1 次 | 錯誤 toast「播放失敗」(`playback_request_session.dart:341-406`) | +| 後端 `OutputDeviceFailed` | mpv `ao` log 或錯誤字串 | 只 toast,收回已排的提前結束重試,5 秒內任何 playing 都立刻 pause | — | toast「音訊輸出失敗」(`audio_provider.dart:2672-2692`、`playback_event_router.dart:369-373, 528-543`) | +| 緩衝飢餓 15 秒 | watchdog | 第一次:invalidate 後 `retryPlayback`;第二次:當作開不起來 | 同一首 1 次 | 錯誤 toast「逾時」 | +| `UnclassifiedFailure` | 後端 | 只記 log、丟棄 | — | 無 | + +網路恢復時 `connectivityProvider` 發事件,自動重試並把次數歸零(`audio_provider.dart:2134-2164`、`playback_recovery_coordinator.dart:259-286`)。 + +**觀察:`_RetryScheduledException` 只有一個 catch 點,而那個入口沒人用**(證據明確,後果部分屬**推測**) +- `_scheduleSessionRetry` 一定拋 `_RetryScheduledException`(`audio_provider.dart:1933-1943`),在 `_executePlayRequest` 的 catch 區塊裡被呼叫(`1883-1886, 1899-1901`),所以會拋出 `_executePlayRequest`。 +- 唯一以 `on _RetryScheduledException` 明確攔它的是 `playSingle`(`audio_provider.dart:596`),但 `playSingle` 沒有 UI 呼叫端。其餘經 `_playTrack` 的入口是被通用 `catch` 接住:`playAt`(`1005-1008`)、`togglePlayPause`(`528-531`)、`play()`(經 `_resumeWithFreshUrlIfNeeded`,`490-493`)都會把這個內部例外的 `toString()` 寫進 `state.error`。(核查補充:原句「唯一攔它的是 playSingle」易誤讀為其他入口讓它逃出) +- `playTemporary`(主要入口)會落進通用 catch(`649-659`):顯示「播放失敗」toast,並**立刻恢復原佇列**,而退避計時器仍然會在 1 秒後重播那首臨時曲目。使用者可能先看到錯誤、佇列歌開始載入、再被重試搶回去。 +- `playMixPlaylist` 的 catch 會 `_exitMixMode()` 並把 `error` 設成例外字串(`968-970`):網路抖一下就退出 Mix 模式。 +- `playAt` 把 `error` 設成例外字串(`1005-1008`)。`next()` / `previous()` 沒有 try,例外往呼叫端(按鈕、通知列、`_handleSourceError` 的 `Future.delayed`)拋,成為未處理的非同步錯誤。 +- `playTemporary` 的 `on SourceApiException` 分支(`633-645`)實際上不可達:`_executePlayRequest` 自己吞掉所有 `SourceApiException`,只會往外拋 `_RetryScheduledException`。 + +**其他觀察** +- Mix 模式遇到 unavailable 不會跳過:跳過條件寫死 `mode == PlayMode.queue`(`audio_provider.dart:1955`),Mix 的 mode 是 `PlayMode.mix`,所以直接停下並報錯(**推測**不是刻意設計)。 +- **不一致**:`playback_error_presenter.dart:56-63` 說 `MediaHandoff` 直接用 `dart:io` 的 `HttpClient` 所以會拋 Socket 等例外;實際的 `DefaultMediaHandoff` 只組 header、不發任何請求(`media_handoff.dart:39-62`)。`CONTEXT.md` 的 Media Handoff 詞條提到 "redirect checks":`MediaHandoff` 類別本身沒有,但**下載管線**有——下載 isolate 關掉自動轉址、逐跳呼叫 `prepareDownloadHop` 重算 header、拒絕轉到本機/私網主機、最多 5 跳(`lib/services/download/download_service.dart:1837-1889`)。播放路徑沒有 redirect 檢查,轉址交給後端播放器自己跟。(核查更正:原寫「程式碼裡查不到 redirect 檢查」) + +### 3.7 音訊焦點與中斷 + +- **Android**(`JustAudioService.initialize`,`just_audio_service.dart:165-213`):`AudioSessionConfiguration.music()`;duck 時音量減半、結束還原;pause / unknown 類中斷時暫停,pause 類結束時若之前在播就自動恢復(unknown 類結束不恢復);`becomingNoisy`(耳機拔出)暫停。 +- 每次開流 `setActive(true)`(`560, 592, 622, 642`),**每次 `stop()` 都 `setActive(false)`**(`385`),而每次播放請求都以 `stop()` 開場(`playback_request_session.dart:508-511`)。所以切歌會放掉再搶回音訊焦點(**推測**:其他 App 可能在切歌瞬間短暫恢復播放)。 +- **Windows**:`MediaKitAudioService` 沒有任何焦點或中斷處理。`audio_service.dart:9-13` 的 dartdoc 說 `audio_session` 在 Windows 上沒有 plugin,查不到反證。耳機拔出或裝置消失時只可能透過 mpv 的 `ao` 錯誤進 `OutputDeviceFailed` 路徑(`media_kit_audio_service.dart:393-398`)。輸出裝置可選,偏好裝置存在 Settings,啟動後裝置清單第一次就緒時套用一次(`audio_provider.dart:1252-1302`)。 + +### 3.8 系統媒體控制 + +- 唯一出口 `NowPlayingPublisher`(`now_playing_publisher.dart:65-304`),owner 為 `music` 或 `radio`。非 owner 的推送會被忽略;電台 `release` 時自動還給音樂(`131-148`)。按鈕依 `PlaybackCapabilities` 決定(`_apply`,`257-303`)。 +- **Android**:`audio_service ^0.18.15`,`AudioService.init` 在 `main.dart:172-183`(`androidStopForegroundOnPause: true`、快轉/倒轉 10 秒);失敗時退回一個沒接系統的 `FmpAudioHandler`(`main.dart:186-195`)。`MediaItem` 的 `artUri` 直接用 `track.thumbnailUrl` 網址,`duration` 用 `track.durationMs`(`audio_handler.dart:75-89`)。 +- **Windows**:`smtc_windows ^1.1.0`,`WindowsSmtcHandler`。metadata 有去重(`windows_smtc_handler.dart:12-49, 238-246`),封面經 `ThumbnailUrlUtils.getOsMediaArtwork` 轉成乾淨網址(`227-232`)。SMTC 不支援 seek(`now_playing_publisher.dart:283-284`)。 +- 推送時機:每次請求開始時先推一次 track(未解析),成功後再推一次(`audio_provider.dart:1816, 1515`);狀態由 `_projectPlayerState` 與節流後的位置更新推(`2398-2402, 2415-2432`)。 +- 觀察:`now_playing_publisher.dart:7` 從 `main.dart` import 全域 `late` 變數 `audioHandler` / `windowsSmtcHandler`,也就是服務層反向依賴 `main.dart`。 + +### 3.9 播放歷史 + +- 何時:`PlaybackSideEffectRegistry` 的 `onTrackStarted(countsAsNewPlay: true)` 時(`playback_side_effects.dart:166-175`)。實際觸發點是「開流成功」(`_exitLoadingState`)與「gapless 跟隨」(`_onBackendAdvanced`),**不是聽了幾秒**(`audio_provider.dart:1397-1402` 的註釋也這樣說)。 +- 不算的:重試(`2033-2038`)、啟動恢復、臨時播放結束後恢復佇列(`_restoreQueuePlayback` 沒傳 `countsAsNewPlay`,預設 false,`730-735`)。 +- 算的:單曲循環每一圈(見 §3.1)。 +- 存哪:Isar `PlayHistory` collection,`PlayHistory.fromTrack(track)` 快照;每寫一筆就依 `playHistoryLimit` 裁掉最舊的(`play_history_repository.dart:21-52`)。寫入 fire-and-forget(`play_history_recorder.dart:34-53`)。 + +### 3.10 臨時播放 + +實際語意(`audio_provider.dart:609-660`、`temporary_play_handler.dart`): +- 不改佇列內容。進入時記下佇列當前 index、後端位置、是否正在播(已在臨時模式時不覆寫,`temporary_play_handler.dart:54-56`)。 +- `persist: false`:解析結果不寫進 Track 列(但若 DB 已有該曲,會補寫 cid,`stream_resolution_service.dart:455-468`)。 +- 臨時曲播完(或按下一首/上一首)走 `_returnToQueue` → `_restoreSavedState`:依「記住播放位置」設定,把佇列曲載回原位置並倒退 `tempPlayRewindSeconds`;**原本在播才自動播,原本暫停就只載入不播**(`audio_provider.dart:778-806`、`temporary_play_handler.dart:76-93`)。 +- 沒有保存狀態時(佇列原本是空的),`_returnToQueue` 播佇列第一首(`2205-2224`)。 +- UI 上「點歌」幾乎都是臨時播放(§1.2),所以這才是 App 的主流程,佇列只由「加入佇列」「下一首播放」與 Mix 建立。 + +**觀察:臨時播放 + 單曲循環會丟掉恢復點**(**推測**,程式碼路徑明確) +- 單曲循環重播走 `_playTrack`,它把 mode 設成 queue 或 mix(`audio_provider.dart:2269-2279`),`_exitLoadingState` 接著把 `_mode` 改成 queue(`1512`)。 +- 之後按下一首:`_isPlayingOutOfQueue` 仍為真,但 `_isTemporaryMode` 已為假,所以 `_returnToQueue` 走 `_playFirstInQueue`,播佇列第一首並清掉保存的位置(`2196-2224`),而不是回到進入臨時播放前的那首。 +- 路由註釋說「臨時播放中按下單曲迴圈仍然迴圈同一首」(`playback_event_router.dart:456-457`),只講了循環本身,沒講循環之後的模式。 + +### 3.11 Mix + +- 語意:YouTube 自動產生的播放清單(RD 開頭)。以 `mixPlaylistId` + `mixSeedVideoId` 儲存在歌單上,播放時替換整個佇列並進入 `PlayMode.mix`(`audio_provider.dart:912-972`)。 +- 限制:禁止隨機(`1190, 941-944`)、禁止加入/插入/打亂(`queue_commands.dart:52-123`),清空佇列就退出 Mix(`audio_provider.dart:1145-1147`)。 +- 無限續播:每首開始時若剩餘 ≤ 1 首就在背景補歌(`mix_session_coordinator.dart:145-169`、`app_constants.dart:96`)。補歌最多試 10 次,每次間隔 1 秒,前 3 次用最後一首當種子,之後往前換種子,湊到 10 首新歌才停,依 `seenVideoIds` 去重(`192-330`、`app_constants.dart:93-105`)。佇列到底時若補歌還在飛,完成路由會等它(`audio_provider.dart:2632-2640`)。 +- 持久化:`PlayQueue.isMixMode` 等欄位,重啟時恢復 Mix 模式(`audio_provider.dart:390-410`、`mix_session_coordinator.dart:118-135`)。 +- 觀察:Mix 佇列只增不減,走的是 `addAll`,沒有 `maxQueueSize` 檢查(`mix_session_coordinator.dart:315`、`queue_manager.dart:500`)。`seenVideoIds` 也只增不減。長時間播放 Mix 時,佇列與記憶體會一直長(**推測**:實際成長速度未量)。 + +### 3.12 電台/直播 + +- 只支援 Bilibili 直播間(`radio_source.dart:138-156`)。取流:`/room/v1/Room/playUrl` 取 `durl` 第一個 URL,`qn=80`(`bilibili_live_client.dart:272-301`),沒有到期時間。 +- **驗證 AGENTS.md 的「Radio 是 FmpAudioService 例外」**:成立。`RadioController` 用 `ref.watch(audioServiceProvider)` 拿到同一個後端(`radio_controller.dart:286`),直接 `playUrl` / `stop` / `seekToLive`(`471, 534, 587, 617, 927, 946`)。整個 `lib/` 裡除了 audio 自己之外,只有它碰 `FmpAudioService`。 +- 共存機制: + - 音樂開始前:session 呼叫 `onPlaybackStarting`,電台有站就 `stop()`(`radio_controller.dart:384-388`、`playback_request_session.dart:215`)。**`restore()` 路徑不呼叫 `onPlaybackStarting`**(`playback_request_session.dart:279-339`)。 + - 電台開始前:只呼叫 `audioController.pause()`(`radio_controller.dart:840-847`),並記下佇列 index / 位置 / 是否在播,返回時用 `returnFromRadio` 還原(`1001-1012, 564-579`)。 + - 電台占用期間 `isRadioPlaying` 讓控制器忽略後端事件與結束原因(輸出裝置失敗除外)(`playback_event_router.dart:359, 402-412`)。 +- 電台的「暫停」實際是 `stop()`(`radio_controller.dart:583-587`,暫停時保留串流資訊以便恢復)。 +- 重連:只在後端回報 `completed` 時觸發,先查是否還在直播,是就依 `RadioReconnectConfig` 重連,否則停下等待刷新服務偵測重新開播(`850-958`)。電台不訂閱 `endReasons`,所以傳輸層錯誤在電台期間只會被控制器以 IgnoreEvent 丟掉(`playback_event_router.dart:407-411`);只有 Windows 上開流時的 `StreamOpenFailedException` 會觸發一次換 URL 重試(`radio_controller.dart:514-518`)。 + +**觀察:音樂載入中開電台的競態**(**推測**) +- `radio.play()` 只 `pause()` 音樂,沒有取消進行中的 `PlaybackRequestSession`(`radio_controller.dart:843`、`audio_provider.dart:497-503`)。 +- 若音樂正在解析串流,解析完成後 `_playSelection` 仍會 `playMedia`,把電台的流換掉。此時 `isRadioPlaying` 為真,控制器忽略後端事件,電台 UI 則認為自己在播。 + +### 3.13 已下載檔案的本地播放 + +- `resolvePrimary` 在非下載用途時先看 `track.allDownloadPaths`(各歌單的 `downloadPath`),第一個存在的就回 `LocalStreamResolution`(`stream_resolution_service.dart:128-145, 483-496`)。 +- `AudioStreamManager` 包成 `LocalPlaybackMedia`(`audio_stream_manager.dart:82-84`)。後端:Android `AudioSource.file`(`just_audio_service.dart:607-635`),Windows `Media(path)`(`media_kit_audio_service.dart:851-902`)。 +- 不存在的路徑會從 DB 清掉,並透過 `downloadPathsChangedStream` 讓控制器通知 library 失效與 `fileExistsCache`(`audio_provider.dart:283-304`)。 +- 本機檔不需要 URL 過期處理(`audio_provider.dart:2235-2236`)。 +- 觀察:檔案存在檢查是同步的 `File.existsSync`,在 UI isolate 上跑(`stream_resolution_service.dart:488`、`audio_provider.dart:2236`)。 + +### 3.14 睡眠定時器、速度、音量、均衡器 + +| 功能 | 現況 | +|---|---| +| 睡眠定時器 | **查不到**。`lib/` 裡沒有相關程式碼 | +| 均衡器 | **查不到**。只有 `user_guide_page.dart:190` 用了 `Icons.equalizer` 圖示 | +| 播放速度 | 選項 0.5~2.0(`app_constants.dart:43-51`),播放頁可選(`player_page.dart:747-766`),兩個後端都 clamp 到 0.5~2.0。**不持久化**:`setSpeed` 只打後端(`audio_provider.dart:1174-1182`),重啟回到 1.0 | +| 音量 | 0~1,存在 `PlayQueue.lastVolume`,啟動時恢復(`audio_provider.dart:412-418`、`queue_persistence_manager.dart:104-112`);靜音記住靜音前的值(只在記憶體) | +| 輸出裝置 | 只有 Windows(§3.7) | + +--- + +## 4. 觀察彙總 + +### 4.1 重複邏輯 +- 四條「開一首歌」的控制器路徑各自做 `_updatePlayingTrack` → session → `_replaceQueueTrackIfCurrent` → `_exitLoadingState` → `_updateQueueState`,細節略有不同:`_executePlayRequest`(`audio_provider.dart:1804-1926`)、`retryPlayback`(`2003-2066`)、`_restoreQueuePlayback`(`662-775`)、`_prepareCurrentTrack`(`2282-2361`)。`countsAsNewPlay`、`mode`、prefetch 的差異散落在四處。 +- `MediaKitAudioService` 的 `playUrl` / `setUrl` / `playFile` / `setFile` 四個方法各自有一份相同的時長輪詢迴圈(`media_kit_audio_service.dart:738-935`);`JustAudioService` 也有類似的四份(`535-652`)。 +- 音源 adapter 的主解析與 alternative 兩套(§3.2)。 +- 啟動恢復時預取兩次(§3.5)。 + +### 4.2 競態風險 +- **被取代的請求不會取消網路工作**:`isSuperseded` 只決定結果要不要採用;`selectPlayback` 仍然跑完,`_withBudget` 的 `timeout` 也不會取消底層 future(`playback_request_session.dart:524-536, 737-745`)。快速連點下一首 N 次會同時有 N 份解析在跑(各自還可能再重試一次),完成後照樣寫 Isar 與快取(`stream_resolution_service.dart:420-481`)。 +- 音樂載入中開電台(§3.12)。 +- `MediaKitAudioService._playbackCancelled` 是單一布林,由每次 `playUrl` 在開頭重設為 false(`media_kit_audio_service.dart:653, 750, 856`)。前一次還在 `_ensurePlayback` 迴圈裡時,新的開流會把旗標重設,舊迴圈可能替新媒體呼叫 `play()`(**推測**)。 +- `_requestDeadline` 是 session 上的單一欄位(`playback_request_session.dart:177, 524, 620`)。新請求進來會改寫它,被取代的舊請求在 fallback 時讀到的是新期限(**推測**,影響小)。 +- `_onTransportFailure` 用 unawaited 閉包做 stop 與排重試,靠 `_isAudioErrorRetryContextCurrent` 在 await 之後重新確認(`audio_provider.dart:2531-2556`)。 + +### 4.3 超大檔案 +- `lib/services/audio/audio_provider.dart` 2953 行,單一類別 `AudioController`。依 spec 有行數雙向 ratchet 測試(`.trellis/spec/services/audio.md` 第 5 點,本次未驗證該測試)。 +- `lib/data/sources/youtube_source.dart` 2431 行。 +- `lib/services/radio/radio_controller.dart` 1103 行、`bilibili_source.dart` 1069 行、`media_kit_audio_service.dart` 1017 行、`netease_source.dart` 1008 行。 + +### 4.4 多份狀態 +見 §2.3。另外 `PlayerState.error` 同時承載「音源錯誤訊息」「例外 `toString()`」與「開流失敗文案」三種內容。`togglePlayPause` 只要看到 `error != null` 就重播當前曲(`audio_provider.dart:517-523`),而 `error` 可能是 `_RetryScheduledException` 的字串(§3.6)。 + +### 4.5 死碼與未用入口 +- `playSingle` / `playTrack` / `playAll` / `playPlaylist`:沒有 UI 呼叫端(以 `grep` 查 `lib/`)。`shuffleQueue` 有呼叫端:`lib/ui/pages/queue/queue_page.dart:323`。 +- `QueueManager.restoreOrder`、`QueueManager.restoreQueue`、`QueueManager.setShuffleState`:`queue_manager.dart` 以外沒有呼叫端(以 `grep` 查 `lib/`)。 +- `AudioStreamManager.ensureAudioStream` / `ensureAudioUrl` 的 `retryCount` 參數沒被使用(`audio_stream_manager.dart:47-65, 128-139`;`ensureAudioStream` 收了不轉給 `resolvePrimary`)。另外 `AudioStreamManager.ensureAudioUrl` 與 `AudioStreamManager.getAlternativeAudioStream`(`:93`)在 `lib/` 都沒有呼叫端,只有 `test/services/audio/audio_stream_manager_test.dart` 使用。(核查更正:原寫「`ensureAudioUrl` / `getAlternativeAudioStream` 的 `retryCount` 參數沒被使用」;`getAlternativeAudioStream` 根本沒有 `retryCount` 參數) +- `_navRequestId` 檢查(§3.1)。 +- `playTemporary` 的 `on SourceApiException` 分支(§3.6)。 + +### 4.6 文檔與代碼不一致 +| 主張 | 位置 | 程式碼實況 | +|---|---|---| +| Navigation 有自己的防競態計數器 | `.trellis/spec/services/audio.md` Races 段 | 檢查點之間沒有 await,檢查永遠通過(`audio_provider.dart:1017-1032`) | +| MediaHandoff 用 `HttpClient`、會拋 Socket 類例外 | `playback_error_presenter.dart:56-63` | `DefaultMediaHandoff` 不發請求(`media_handoff.dart:39-62`) | +| Media Handoff 含 redirect checks | `CONTEXT.md` Media Handoff 詞條 | 只有下載管線逐跳檢查(`download_service.dart:1837-1889`),播放路徑沒有;`DefaultMediaHandoff` 本身只組 header(核查更正:原寫「查不到 redirect 檢查」) | +| `QueueManager.add` 回 false 代表「队列已满」 | `queue_manager.dart:466-467` | 只有 `add` 檢查,`addAll` / `insert` 不檢查 | +| `_armNextMedia` 命中預取時不打網路 | `audio_provider.dart:1668-1671` | 重啟後 Isar 帶 URL 的 track 不會被預取,arm 時會打網路(§3.3) | +| `PlayHistoryRecorder` 註釋說 null 來自「`audio_provider.dart` 的 provider 工廠」 | `play_history_recorder.dart:13-15` | 現在由 `playbackSideEffectsProvider` 以 `readOptional` 提供(`playback_side_effects.dart:237-248`),`audio_provider.dart` 已不宣告 provider | diff --git a/docs/audit/questions.md b/docs/audit/questions.md new file mode 100644 index 000000000..3b646c01b --- /dev/null +++ b/docs/audit/questions.md @@ -0,0 +1,388 @@ +# 決策清單 + +> 現況描述,未經確認,不代表目標。 + +這份清單給你勾選。每項列出**現況**(附證據,細節在對應的審計文件)、**影響**,以及選項。 +在你要的選項前把 `[ ]` 改成 `[x]`;想補充就寫在「備註」後面。 + +排序原則:越前面越會決定重寫的形狀(平台、資料層、資料相容),越後面越是局部去留。 +同一節內也按影響大小排。沒有預設答案;我在最後的對話摘要裡另給建議,這份文件不放建議,避免帶偏。 + +通用選項的意思: + +- **保留**:新架構照現在的行為做。 +- **刪除**:新架構不做,舊碼刪掉。 +- **修改**:保留功能但改行為,在備註寫你要的樣子(或留給階段二提方案)。 +- **不確定**:階段二先研究再問你。 + +--- + +## 1. 策略級(A 項,先決定,會改變整個重寫計畫) + +### A1. 目標平台與上線順序 + +- 現況:只有 Android、Windows 能跑。程式裡另有 iOS/macOS/Linux 分支,全部未驗證,而且三種判斷寫法並存(`Platform.isWindows`、`isDesktopPlatform`、`AudioRuntimePlatform`),macOS/Linux 會出現半套桌面 UI、沒有標題列、推測無法播放。見 `platforms.md` §0、§2。 +- ADR 0003 與 `pubspec.yaml:24` 說「不出 Linux/macOS」,`platform_utils.dart`、`audio_controller_provider.dart:23-25` 的註解讀起來像有支援:**不一致**。 +- 影響:平台層抽象要不要一開始就按 5 平台設計;要不要刪掉現在的殘留分支。 + +| 平台 | 目標(重寫第一版就要) | 目標(之後加入) | 不支援 | 不確定 | +|---|---|---|---|---| +| Android | [ ] | [ ] | [ ] | [ ] | +| Windows | [ ] | [ ] | [ ] | [ ] | +| Linux | [ ] | [ ] | [ ] | [ ] | +| macOS | [ ] | [ ] | [ ] | [ ] | +| iOS | [ ] | [ ] | [ ] | [ ] | + +備註: + +### A2. 資料層是否更換 + +- 現況:`isar_community` 3.3.2(社群 fork,pub.dev 已驗證發佈者,自述只做 v3 bug 修正),`data.md` §1。上游 `isar` 在 pub.dev 最後發版 2023-08(4.0.0-dev.14),最後穩定版 3.1.0+1;ADR 0007 寫「自 2025-07 沒有再發版」:**不一致**(`engineering.md` §10)。 +- fork 在 pub.dev 標 5 平台都支援(`platforms.md` §4.1)。 +- 11 個 collection,**沒有任何 IsarLink**,關係全靠手動維護的 int id/字串鍵(`data.md` §1);Isar 會把沒標 `@ignore` 的 getter 也存進去,其中 `needsRefresh`、`hasValidAudioUrl` 這類時間相關值在磁碟上會過時(`data.md` §1)。 +- 資料量:ADR 0007 提到一份真實資料庫 1,534 列;你目前實際大小查不到。 +- 影響: + - **資料相容**:換庫=要寫一次性匯出/匯入(或以現有備份格式為橋),不換=可以原地打開舊 DB。 + - **全平台**:fork 宣稱 5 平台都支援,但長期維護依賴一個社群 fork。 + - **重寫順序**:換庫的話,資料層要在最前面的里程碑;不換的話可以延後或只清理邊界。 + +- [ ] 保留 isar_community(v3 格式) +- [ ] 更換(階段二比較 drift/sqlite 系列、ObjectBox 等,並給遷移方案) +- [ ] 不確定 + +備註: + +### A3. 資料相容:重寫版本要不要讀得懂舊資料 + +| 資料 | 現況位置 | 保留並自動遷移 | 只支援經備份檔匯入 | 不保留 | 不確定 | +|---|---|---|---|---|---| +| 資料庫(歌單、曲目、歷史、設定、佇列) | Windows:`文件\FMP\fmp_database.isar`;Android:app 私有目錄(`data.md` §1) | [ ] | [ ] | [ ] | [ ] | +| 登入憑證(secure storage) | `flutter_secure_storage`(`data.md` §3、`accounts-network.md` §1) | [ ] | — | [ ] | [ ] | +| 已下載的音檔與 sidecar | Android `Music/FMP`、Windows `文件\FMP`(`data.md` §5) | [ ] | — | [ ] | [ ] | +| 備份檔(JSON 格式) | `data.md` §6 | [ ] 新版能匯入舊備份 | — | [ ] | [ ] | + +備註: + +### A4. 資料與 log 放在 Windows「文件」資料夾 + +- 現況:資料庫與 log 在 `Documents\FMP`(`database_provider.dart:50-53`、`log_file_sink.dart:24-28`),可能被 OneDrive 同步;資料庫內有含簽名的串流 URL(見 B6)。 +- [ ] 保留 - [ ] 修改:移到 AppData(需遷移) - [ ] 不確定 + +備註: + +### A5. 音訊後端:兩套(ADR 0003) + +- 現況:Android(與 iOS)用 just_audio→ExoPlayer,其他用 media_kit→libmpv;`media_kit_libs_windows_audio` 在 pub.dev 已 unlisted、最後發佈 2023-09(`platforms.md` §4)。兩個後端共用一批純規則,並有契約測試(`engineering.md` §10 ADR 0003:一致)。 +- 影響:全平台時 macOS/Linux 要 libmpv 來源,iOS/macOS 帶 headers 需要 ATS 設定。 +- [ ] 維持兩套 - [ ] 研究統一成一套 - [ ] 不確定 + +備註: + +### A6. 發佈管道 + +- 現況:只有 GitHub Release;tag push 後自動驗證、建置、直接發布,沒有人工閘門,Windows 產物沒有 code signing,SHA-256 檔與產物放在同一個 Release(`engineering.md` §1、ADR 0006)。ADR 0004 寫「擁有者決定永遠不上架任何商店」。 +- 平台政策(`platforms.md` §6):App Store 5.2.3 禁止未授權從 YouTube 等來源下載媒體;2.5.2 禁止 iOS app 自行下載可執行碼;Mac App Store 2.4.5 禁止自有更新機制。 + +| 平台 | GitHub Release | 商店 | sideload/自簽(AltStore、TestFlight 等) | 套件庫(Flathub、AUR、winget 等) | 不發佈 | 不確定 | +|---|---|---|---|---|---|---| +| Android | [ ] | [ ] | — | [ ] F-Droid 類 | [ ] | [ ] | +| Windows | [ ] | [ ] | — | [ ] | [ ] | [ ] | +| Linux | [ ] | — | — | [ ] | [ ] | [ ] | +| macOS | [ ] | [ ] | [ ] 未公證 dmg | [ ] Homebrew | [ ] | [ ] | +| iOS | — | [ ] | [ ] | — | [ ] | [ ] | + +另外:Release 要不要回到「草稿 → 你手動發布」(推翻 ADR 0006)? [ ] 維持自動發布 [ ] 改回人工發布 [ ] 不確定 + +備註: + +--- + +## 2. 會對外寫入、送資料給第三方、自己下載或執行東西的功能(B 項) + +細節與證據在 `features.md` §15、`accounts-network.md` §4。 + +| # | 功能 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---|---| +| B1 | 在本機刪「匯入的平台歌單」裡的曲目=在 B 站/YouTube/網易雲上刪 | 只靠確認框文案說明 | `playlist_detail_page.dart:565-610,1575-1610`;`remote_playlist_sync_provider.dart:47-50` | [ ] | [ ] | [ ] | [ ] | +| B2 | 「加入遠端」:在三個平台建歌單、加曲目 | 對話框操作 | `bilibili_favorites_service.dart:117-168`;`youtube_playlist_service.dart:88-111,218-223`;`netease_playlist_service.dart:101-188` | [ ] | [ ] | [ ] | [ ] | +| B3 | 網易雲寫入請求附偽造 `X-Real-IP: 118.88.88.88` | 固定送出 | `netease_playlist_service.dart:240-253` | [ ] | [ ] | [ ] | [ ] | +| B4 | 啟動時自動換 B 站 Cookie(伺服器要求時,舊 refresh_token 作廢) | 每次啟動檢查 | `account_provider.dart:131-152`;`bilibili_account_service.dart:350-444` | [ ] | [ ] | [ ] 改手動 | [ ] | +| B5 | AI 歌詞匹配:把標題、上傳者、**影片描述**、**歌詞預覽**連同 API key 送到自訂端點;端點不強制 https;debug 級別時整份 payload 寫進 log | 預設關閉 | `openai_chat_client.dart:41-67`;`ai_lyrics_selector.dart:106-137`;`openai_chat_endpoint.dart:1-6` | [ ] | [ ] | [ ] | [ ] | +| B6 | 含簽名的 CDN 串流 URL 明文存進資料庫(`Track.audioUrl`) | 每首一筆 | `stream_resolution_service.dart:427-471` | [ ] | [ ] 只放記憶體 | [ ] | [ ] | +| B7 | Windows 自動更新:安裝版以 `/SILENT` 靜默跑下載的安裝程式;免安裝版寫 bat+vbs 用 `wscript` 隱藏執行、`robocopy` 覆蓋程式目錄 | 使用者按「更新」後 | `update_service.dart:587-684,830-876` | [ ] | [ ] | [ ] | [ ] | +| B8 | 更新檔 SHA-256:只有 release 附 checksum 檔才驗,否則只比大小 | — | `update_service.dart:462-470,776-783` | [ ] | — | [ ] 強制驗 | [ ] | +| B9 | Android 自動更新:下載 APK 開系統安裝器 | 使用者按「更新」後 | `update_service.dart:540-565` | [ ] | [ ] | [ ] | [ ] | +| B10 | 每 15 秒解析 `dns.google`、`one.one.one.one`、`dns.alidns.com` 偵測連線 | 常駐 | `connectivity_service.dart:52-56,102-116` | [ ] | [ ] | [ ] | [ ] | +| B11 | B 站匿名請求自產 `buvid3`/`buvid4`/`b_nut` 瀏覽器指紋 cookie | 常駐 | `bilibili_source.dart:92-146` | [ ] | [ ] | [ ] | [ ] | +| B12 | 首頁排行:停用某音源只影響顯示,背景仍每小時抓所有音源 | 常駐 | `ranking_cache_service.dart:233-245`;`home_ranking_settings_provider.dart:193-195` | [ ] | [ ] | [ ] 停用即不抓 | [ ] | +| B13 | 下載時附帶寫 metadata JSON、下載封面與 UP 主頭像 | 每次下載 | `download_service.dart:1509-1590` | [ ] | [ ] | [ ] | [ ] | +| B14 | YouTube 登入頁注入 JS 呼叫 `accounts_list` 取帳號名 | 登入時 | `youtube_login_page.dart:238-260` | [ ] | [ ] | [ ] | [ ] | + +備註: + +--- + +## 3. 安全與隱私缺陷(C 項;這些是「現況的錯」,不是功能去留) + +| # | 問題 | 證據 | 重寫時修正 | 維持現狀 | 不確定 | +|---|---|---|---|---|---| +| C1 | 「重設所有資料」只清 Isar,不清 secure storage;重設後 UI 顯示未登入,但播放、詳情、排行榜仍帶舊 cookie(已由程式碼確認) | `data_integrity_repository.dart:55-56`;`data.md` §3 | [ ] | [ ] | [ ] | +| C2 | log 遮蔽不涵蓋 CDN 簽名參數:`media_kit` 與 just_audio 的錯誤原文未過 `redactStreamUrl`;stackTrace 不遮就寫進檔案與匯出;release 版 `debugPrint` 仍輸出到 logcat | `logger.dart:52-63,81-200,283-290`;`media_kit_audio_service.dart:379`;`just_audio_service.dart:301-304` | [ ] | [ ] | [ ] | +| C3 | B 站 QR 登入可能「假成功」:Set-Cookie 解析不到時沒存憑證仍走 `onLoginSuccess`(已由程式碼確認) | `bilibili_account_service.dart:184-200,469-473,511-517` | [ ] | [ ] | [ ] | +| C4 | B 站 cookie 刷新後的重試帶的是舊 cookie(程式碼確認;伺服器回應未實測) | `bilibili_auth_interceptor.dart:28-33,77` | [ ] | [ ] | [ ] | +| C5 | 網易雲啟動帳號檢查:任何非 200 碼(含限流 -460)都當登入失效並清憑證 | `netease_account_service.dart:290-297,360-362` | [ ] | [ ] | [ ] | +| C6 | 播放/搜尋用的連線偵測不到登入失效;YouTube 偵測到也只寫 log | `bilibili_source.dart:96-101`;`youtube_auth_interceptor.dart:30-37` | [ ] | [ ] | [ ] | +| C7 | 公開 repo 內有逆向取得的前端金鑰(InnerTube key、網易 weapi/eapi 金鑰、QQ 簽名表) | `accounts-network.md` §5(只列位置) | [ ] 集中管理 | [ ] 維持 | [ ] | + +備註: + +--- + +## 4. 帳號與「用登入狀態播放」(M 項) + +細節在 `accounts-network.md` §6(帳號全貌)、§7(請求 × 音源憑證矩陣)、§8(登入與未登入的能力差異)。 + +| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---|---| +| M1 | 「是否登入」有兩份來源:UI 讀 Isar `Account`,實際送請求只看 secure storage | 兩者可能不一致(見 §3 C1) | `accounts-network.md` §6.1 | [ ] | — | [ ] 統一以一份為準 | [ ] | +| M2 | 「用登入狀態播放」(Auth For Play)開關,每個音源一個 | 預設:B 站、網易開,YouTube 關;控制播放、詳情、下載、B 站排行 | `settings.dart:76-79,686-693`;`accounts-network.md` §7 | [ ] | [ ] 一律帶 | [ ] | [ ] | +| M3 | v3→v4 migration 把 B 站「用登入狀態播放」**無條件改成開**,使用者自己關掉的也被打開 | 已執行過的遷移 | `database_migration.dart:236-238` | [ ] | — | [ ] 改成詢問/不動使用者值 | [ ] | +| M4 | 其他改寫使用者設定值的 migration(v0→v1 無條件改寫三個版面欄位等) | — | `database_migration.dart:171-193`;`accounts-network.md` §7 | [ ] | — | [ ] | [ ] | +| M5 | YouTube 的「用登入狀態播放」只是備援:先匿名,失敗才帶登入 | — | `youtube_source.dart:247-273,346-366` | [ ] | — | [ ] 登入後先帶登入 | [ ] | +| M6 | YouTube、網易的首頁排行永遠不帶登入(開關開了也一樣);只有 B 站排行受開關影響 | — | `youtube_source.dart:1635-1638`;`netease_source.dart:355-357`;`ranking_cache_service.dart:269-275` | [ ] | — | [ ] | [ ] | +| M7 | 設定頁說明寫「播放與歌曲詳情」,實際還包括下載與 B 站排行 | **不一致** | `audioSettings.i18n.json:34` | — | — | [ ] 修文案 | [ ] | +| M8 | secure storage 暫時讀不到時,啟動檢查會當成失效並刪憑證、跳「登錄已失效」 | 推測可能刪掉仍有效的憑證 | `bilibili_account_service.dart:470-473`;`account_provider.dart:233-236` | [ ] | — | [ ] | [ ] | +| M9 | 登入失效提示每次 App 執行每個平台只跳一次,重新登入後再失效不再提示 | — | `session_expiry_notifier.dart:15,22-23` | [ ] | — | [ ] | [ ] | +| M10 | 播放時遇到「需要登入」的錯誤判斷存在但沒人使用,不會標記失效或引導登入 | — | `source_exception.dart:58` | [ ] | [ ] | [ ] 接上 | [ ] | +| M11 | 依登入/會員狀態選音質:B 站高解析與杜比音軌完全不讀;網易試聽片段不提示(見 D4) | — | `bilibili_source.dart:349-353`;`netease_source.dart:139-150` | [ ] | — | [ ] | [ ] | +| M12 | 歌單「使用登入狀態重新整理」會被重新匯入覆寫;帳號頁匯入的歌單一律帶登入 | — | `import_service.dart:250`;`account_playlists_sheet.dart:277` | [ ] | — | [ ] | [ ] | +| M13 | 各音源登入方式:B 站 WebView+QR;YouTube 只有 WebView;網易 Android WebView+QR、Windows 只有 QR | — | `platforms.md` §3;`accounts-network.md` §1 | [ ] | [ ] | [ ] | [ ] | + +備註: + +--- + +## 5. 下載與權限(N 項) + +細節在 `downloads.md`。 + +**N1 要不要在舊版先修?** 它在目前發行的版本上就可能正在刪你的曲目,而重寫期間不發正式版。 +- [ ] 審計後立刻在舊版 hotfix(需要例外發一版) - [ ] 先不修,重寫時處理 - [ ] 先備份資料庫再決定 - [ ] 不確定 + +| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---|---| +| N1 | **已確認的資料遺失路徑**:每次啟動的下載同步重建曲目的 `playlistInfo`,只保留「DB 歌單原名 == 磁碟資料夾名」的關聯;資料夾名是 `sanitizeFileName` 過的,歌單名含 `: ? / \|` 等字元、或你照改名提示搬過資料夾時就對不上而被丟掉。約 10 秒後的孤兒清理只看 `playlistInfo` 有無 `playlistId > 0`、不看 `Playlist.trackIds`,於是曲目被從資料庫刪除並從歌單消失。另外,已下載曲目若同時在另一個未下載的歌單,那個關聯每次啟動都會被丟 | 呼叫鏈完整、未實機重現(`downloads.md` §4.4) | `download_path_sync_service.dart:162-197`;`track_repository.dart:635-669`;`queue_manager.dart:226`;`app.dart:131` | [ ] | — | [ ] 以 id 比對、清理改看 `Playlist.trackIds` | [ ] | +| N2 | Android 下載路徑只在第一次下載時選,設定頁不能改;權限被撤銷後每次下載都失敗,不重新請求、不導去系統設定 | — | `settings_storage.dart:60`;`storage_permission_service.dart:69` | [ ] | — | [ ] | [ ] | +| N3 | 改下載路徑時的行為(搬檔/掃新目錄/只重設);歌單改名不會改資料夾,要使用者自己搬 | — | `download_path_maintenance_service.dart:59-80`;`playlist_service.dart:136-141,166-189` | [ ] | — | [ ] | [ ] | +| N4 | 續傳:每次繼續重新解析 URL,沒有 ETag/If-Range/大小驗證(推測可能接出損壞檔);手動重試從頭下;下載本身不自動重試 | — | `download_service.dart:685-688,1904-1906` | [ ] | [ ] 取消續傳 | [ ] 加驗證 | [ ] | +| N5 | 下載音質跟播放共用設定,沒有下載專用音質;可能拿到 muxed 串流 | — | `base_source.dart:44-50`;`settings.dart:59-63` | [ ] | — | [ ] | [ ] | +| N6 | 副檔名一律 `.m4a`(opus、flac 也一樣);metadata 只寫 sidecar JSON,不寫進音檔內嵌 tag | — | `download_path_utils.dart:40-46` | [ ] | — | [ ] | [ ] | +| N7 | 失敗任務在下次開啟下載功能時被清掉 | — | `download_repository.dart:66-96`;`download_service.dart:206-212` | [ ] | — | [ ] | [ ] | +| N8 | 下載只在 App 行程內的 isolate 跑,沒有前景服務或系統排程 | — | `downloads.md` §2 | [ ] | — | [ ] | [ ] | +| N9 | 播放時找不到本地檔就永久清掉下載路徑,不區分「儲存裝置暫時拔出」 | — | `stream_resolution_service.dart:128-136` | [ ] | — | [ ] | [ ] | +| N10 | 權限:沒宣告 `POST_NOTIFICATIONS`、沒有電池最佳化豁免;open_filex 合併進三個從不請求的 `READ_MEDIA_*`;Android 10 以下被拒時沒說明、不導去設定 | — | `downloads.md` §6;`AndroidManifest.xml` | [ ] | — | [ ] | [ ] | +| N11 | 權限請求統一入口(目前儲存權限走自有 MethodChannel,刻意不用 permission_handler) | — | `storage_permission_service.dart:22-24` | [ ] | — | [ ] 改用成熟套件 | [ ] | + +備註: + +--- + +## 6. 播放行為語意(D 項,目前行為可能不是你要的) + +細節在 `playback.md`。 + +| # | 行為 | 現況 | 證據 | 保留 | 修改 | 不確定 | +|---|---|---|---|---|---|---| +| D1 | 點一首歌=「臨時播放」(播完回原佇列),不是加入佇列 | 搜尋、歌單、首頁、排行、歷史、已下載都走 `playTemporary` | `playback.md` §0、§1;`search_page.dart:485` | [ ] | [ ] | [ ] | +| D2 | 歌單頁「全部」按鈕只加入佇列、不播放 | 方法名叫 `_playAll` | `playlist_detail_page.dart:884-890` | [ ] | [ ] | [ ] | +| D3 | Mix 模式(YouTube 無限佇列):無法播放的歌不自動跳過、佇列無上限 | — | `audio_provider.dart:1955`;`mix_session_coordinator.dart:315` | [ ] | [ ] | [ ] | +| D4 | 網易雲試聽片段照常當完整歌曲播放,不提示;下載端也擋不到 | — | `netease_source.dart:139-150` | [ ] | [ ] 提示/跳過 | [ ] | +| D5 | 播放遇限流:只在解析層重試一次、等 3 秒,之後提示,不退避不跳過 | — | `stream_resolution_service.dart:210`;`audio_provider.dart:1984-1988` | [ ] | [ ] | [ ] | +| D6 | 播放歷史在「開流成功」時記一筆;單曲循環每圈都記 | — | `playback_side_effects.dart:166-175` | [ ] | [ ] | [ ] | +| D7 | 隨機模式下拖曳排序不更新隨機順序;「下一首播放」插到隨機位置 | — | `queue_manager.dart:541-547,594-613` | [ ] | [ ] | [ ] | +| D8 | 開電台時只暫停音樂、不取消正在載入的音樂(推測會被音樂串流蓋掉) | — | `radio_controller.dart:840-847` | [ ] | [ ] | [ ] | +| D9 | YouTube URL 有效期寫死 1 小時,不讀網址裡的 `expire` | — | `youtube_source.dart:52-54` | [ ] | [ ] | [ ] | +| D10 | 電台/直播 | 輪詢開播狀態;網路錯誤顯示成「未開播」 | `bilibili_live_client.dart:205-208`;`radio_refresh_service.dart:252-257` | [ ] | [ ] | [ ] | + +電台/直播、Mix 整個功能要不要保留,另見 §7。 + +備註: + +--- + +## 7. 功能去留(E 項,主要功能域) + +完整清單在 `features.md`;這裡只列需要你表態的功能域。狀態欄沿用 `features.md` 的判定。 + +| # | 功能 | 狀態 | 平台 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---|---| +| E1 | 三個音源的搜尋與播放(B 站、YouTube、網易雲) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E2 | B 站分 P(多 cid 各自成曲,ADR 0005) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E3 | 音樂庫:本機歌單、排序、多選 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E4 | 匯入平台歌單(B 站收藏夾、YouTube 播放清單、網易雲歌單)並定時刷新 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E5 | 只能匯入的外部歌單(Spotify、QQ 音樂),自動匹配到可播放音源 | 完整;失敗時一律顯示「發生錯誤」(`errors.md` §1) | A W | [ ] | [ ] | [ ] | [ ] | +| E6 | 帳號登入(三個音源;WebView/QR) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E7 | 遠端歌單編輯(B1、B2) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E8 | 下載(含分類頁、路徑設定) | 完整;Android 在設定頁不能改下載路徑 | A W | [ ] | [ ] | [ ] | [ ] | +| E9 | 歌詞:多源搜尋(網易、QQ、lrclib)、自動匹配、手動選擇 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E10 | AI 歌詞匹配/標題解析(B5) | 完整,預設關 | A W | [ ] | [ ] | [ ] | [ ] | +| E11 | 桌面歌詞視窗(獨立視窗) | 完整,僅 Windows | W | [ ] | [ ] | [ ] | [ ] | +| E12 | 電台/直播(B 站直播間) | 完整;「收藏電台」無 UI 入口 | A W | [ ] | [ ] | [ ] | [ ] | +| E13 | Mix(YouTube 無限佇列) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E14 | 首頁排行/探索 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E15 | 播放歷史頁 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E16 | 備份與還原 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | +| E17 | 應用內更新(B7–B9) | 完整,只有手動檢查一個入口 | A W | [ ] | [ ] | [ ] | [ ] | +| E18 | 托盤、全域快捷鍵、開機自啟、關閉縮到托盤、單一實例 | 完整,僅 Windows | W | [ ] | [ ] | [ ] | [ ] | +| E19 | 播放速度(0.5–2.0,不持久化)、音量、桌面輸出裝置選擇;**沒有**睡眠定時器與均衡器 | 完整(`playback.md` §3.14) | A W | [ ] | [ ] | [ ] | [ ] | +| E20 | 使用者指南頁(設定頁進入,`lib/ui/pages/settings/user_guide_page.dart`) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | + +備註: + +--- + +## 8. 平台綁定功能在其他平台上的去留 + +現況在 `platforms.md` §3、§6。每格選:**全**=全平台提供;**部分**=只在部分平台(備註寫哪些);**刪**=刪除;**?**=不確定。 + +| 功能 | 現況 | 其他平台會卡在哪 | 全 | 部分 | 刪 | ? | +|---|---|---|---|---|---|---| +| 自動更新(應用內下載安裝) | A W | iOS 政策禁止;Mac App Store 禁止;Linux 依打包格式 | [ ] | [ ] | [ ] | [ ] | +| 下載音檔 | A W | App Store 5.2.3;iOS 沙盒 | [ ] | [ ] | [ ] | [ ] | +| Android 用「所有檔案存取權」裸路徑(ADR 0004) | A | 上架 Play 會被擋;可改 SAF/app 專屬目錄 | — | [ ] 維持 | [ ] 改 SAF | [ ] | +| 登入 WebView | A W | flutter_inappwebview 無 Linux 實作;YouTube 沒有 QR 登入 | [ ] | [ ] | [ ] | [ ] | +| 托盤 | W | 套件支援 macOS/Linux,程式寫死 Windows | [ ] | [ ] | [ ] | [ ] | +| 全域快捷鍵 | W | 同上;Linux Wayland 限制 | [ ] | [ ] | [ ] | [ ] | +| 開機自啟 | W | macOS 需額外原生碼 | [ ] | [ ] | [ ] | [ ] | +| 關閉縮到托盤、單一實例 | W | runner C++ 自訂 | [ ] | [ ] | [ ] | [ ] | +| 桌面歌詞視窗 | W | 需 runner 註冊子視窗插件;Android 寬版面有無作用的按鈕 | [ ] | [ ] | [ ] | [ ] | +| 自訂標題列 | W | macOS/Linux 現在是藏起來沒替代 | [ ] | [ ] | [ ] | [ ] | +| 系統媒體控制 | A(audio_service)、W(SMTC,不支援 seek) | macOS 可接 audio_service;Linux 需 MPRIS | [ ] | [ ] | [ ] | [ ] | +| 內建 CJK 字型 | 無(fallback `Noto Sans SC` 未內建) | 各平台字型不一 | [ ] 內建 | [ ] 依平台 fallback | — | [ ] | + +備註: + +--- + +## 9. 架構與程式碼層面的現況問題(G 項) + +多數會在階段二自然解決;列出來是讓你知道現在的樣子。 + +| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | +|---|---|---|---|---|---| +| G1 | `AudioController` 2,953 行、約 125 個方法;一次播放經十幾層協作物件;播放器狀態至少 5 份 | `architecture.md` §7;`playback.md` §2 | [ ] | [ ] | [ ] | +| G2 | 19 個目錄的大循環依賴(起因:`main.dart` 全域可變狀態被反向 import) | `architecture.md` §3;`lib/main.dart:29-44` | [ ] | [ ] | [ ] | +| G3 | 新增一個音源最少改 15 檔、同網易雲程度約 54 檔;音源特定分支 50 處散在 28 檔 | `sources.md` §3、§4 | [ ] | [ ] | [ ] | +| G4 | 錯誤呈現:自訂例外到畫面一律「發生錯誤」;adapter 把 `e.toString()` 原文丟上畫面;多源搜尋只要一源成功就隱藏其他失敗;507 個 catch 中約 70 個空的 | `errors.md` §1、§4 | [ ] | [ ] | [ ] | +| G5 | 播放網路錯誤的重試訊號只有沒人用的入口接得住,臨時播放/Mix/上下首會出錯 | `playback.md` §3.6;`audio_provider.dart:596,1933-1943` | [ ] | [ ] | [ ] | +| G6 | 161–162 個手寫 provider,放置慣例三種以上;repository 被繞過直接 `XxxRepository(db)` 20 處以上;約 19 個 Notifier 各自讀寫同一列 `Settings` | `architecture.md` §4 | [ ] | [ ] | [ ] | +| G7 | 死代碼:84 個 public 成員零引用(候選);`checkNow`、`reset`、`cleanupInvalidPaths`、`refreshStation`、`batchRemoveFromFolder`、`autoRefreshAll`、`playSingle`/`playAll`/`playPlaylist` 等已確認零呼叫 | `engineering.md` §7.2;`features.md` §14;`playback.md` §4.5 | [ ] | [ ] | [ ] | +| G8 | 重複邏輯:位元組格式化 6 份、InnerTube 文字抽取 2 份(行為不同)、兩個同名 `NeteaseSource`、兩條名稱倒裝的歌單匯入流程 | `engineering.md` §7.3;`architecture.md` §7 | [ ] | [ ] | [ ] | +| G9 | Toast/錯誤呈現三種寫法;背景錯誤只有 `AppShell` 在聽,全螢幕播放頁可能看不到(推測) | `devtools.md` §2 | [ ] | [ ] | [ ] | + +備註: + +--- + +## 10. 測試類別的去留 + +現況在 `engineering.md` §2、§3、§5。本機全量 `--exclude-tags live`:1,849 通過、0 失敗、2 分 48 秒。 + +| 類別 | 數量 | 現況評語 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---| +| 離線行為測試(services/data/providers/ui) | 約 1,700 個 | 以行為為主;部分大量依賴 `debug*ForTesting` 掛鉤(下載服務 44 處) | [ ] | [ ] | [ ] | [ ] | +| live 測試(打真實 API) | 4 個 | **不加參數的 `flutter test` 會跑它們**(`dart_test.yaml` 無預設 skip) | [ ] | [ ] | [ ] 預設排除 | [ ] | +| static-rule(正則比對原始碼) | 25 檔 144 個 | 都有合成違規測試;有些是計次預算(例如 `audio_provider.dart` 行數 ≤ 2,184、音源分支預算 9 處但實際 50 處沒守住) | [ ] | [ ] | [ ] | [ ] | +| 測 CI 設定本身(`test/workflows/`) | 4 檔 31 個 | 一半解析 YAML,一半比對 shell 片段字串 | [ ] | [ ] | [ ] | [ ] | +| benchmark(`test/performance/`) | 2 檔 13 個 | 可離線跑;斷言寬鬆的絕對上限 | [ ] | [ ] | [ ] | [ ] | +| 手動探針(`test/manual/`) | 2 檔 | 本機 HTTP 病態伺服器、真實 DB 探針 | [ ] | [ ] | [ ] | [ ] | +| `tool/demo/`(手跑、打真實 API) | 6 支 | 不引用 `lib/`,其中一支帶一份 `RegexTitleParser` 副本 | [ ] | [ ] | [ ] | [ ] | + +另:main 分支 CI 目前是紅的(`account_repository_test.dart:105-118` 用固定 200ms 等待,時序不穩;run 36239727409)。 +- [ ] 審計結束後先在舊版修掉 - [ ] 不管,重寫時處理 - [ ] 不確定 + +備註: + +--- + +## 11. i18n 語言 + +- 現況:`en`、`zh-CN`、`zh-TW` 三種,每種 38 個 JSON 檔,用 slang 管理(`lib/i18n/`)。缺漏 key 與硬編碼字串統計見 `ui.md` §4。 + +| 語言 | 保留 | 刪除 | 不確定 | +|---|---|---|---| +| English(`en`) | [ ] | [ ] | [ ] | +| 簡體中文(`zh-CN`) | [ ] | [ ] | [ ] | +| 繁體中文(`zh-TW`) | [ ] | [ ] | [ ] | + +其他想加的語言: + +- base locale(缺字時的後備語言)目前是 `zh-CN`:[ ] 維持 [ ] 改 `zh-TW` [ ] 改 `en` [ ] 不確定 +- 三語言目前完全對齊(各 1,176 個 key),但桌面浮動歌詞視窗有 33 個簡體字串寫死在程式碼(`lyrics_window.dart:33-66`),UI 裡另有硬編碼字串(`ui.md` §4):[ ] 重寫時全部納入 i18n [ ] 不確定 + +--- + +## 12. UI/UX 現況問題(U 項) + +現況在 `ui.md` §7、截圖在 `docs/audit/screenshots/`。階段二會出設計系統與桌面播放器版面方案;這裡先確認問題清單與範圍。 + +| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | +|---|---|---|---|---|---| +| U1 | 間距與字級沒有 token:`EdgeInsets` 約 250 處、`SizedBox` 約 500 處字面數字,29 處 `fontSize:` 繞過主題 | `ui.md` §3.2 | [ ] | [ ] | [ ] | +| U2 | 桌面鍵盤操作:App 內沒有任何快捷鍵(`Shortcuts`/`Actions` 0 處),Esc 離不開播放頁;焦點指示在深色主題幾乎看不見,Tab 要穿過整個清單才到導航軌 | `ui.md` §5.3;`windows-focus-row.png` | [ ] | [ ] | [ ] | +| U3 | 無障礙:播放頁大播放鍵沒有名稱;迷你播放器是「按鈕包按鈕」 | `player_play_pause_button.dart:46-48`;`mini_player.dart:54-58` | [ ] | [ ] | [ ] | +| U4 | 窄桌面視窗的迷你播放器保留 7 顆鈕,標題只剩 2 個字 | `windows-compact-home.png` | [ ] | [ ] | [ ] | +| U5 | 搜尋頁來源篩選列被排序鈕蓋住、沒有可捲動提示 | `windows-search.png`、`android-search.png` | [ ] | [ ] | [ ] | +| U6 | 數字與複數格式:「4600.0萬」「46.0M」「1 tracks」 | `number_format_utils.dart:28-37` | [ ] | [ ] | [ ] | +| U7 | 右側「正在播放」面板在所有頁面常駐(寬度 ≥ 840) | `ui.md` §1.2 | [ ] 保留常駐 | [ ] 只在播放相關頁 | [ ] | +| U8 | `large`/`extraLarge` 斷點註解承諾的版面沒有實作 | `responsive_scaffold.dart:116-145` | [ ] 實作 | [ ] 刪註解 | [ ] | +| U9 | Windows debug/profile build 讀寫使用者真實資料(`Documents\FMP`),沒有隔離;本次審計因此誤觸播放你佇列中的曲目 | `database_provider.dart:49-52` | [ ] 開發版用獨立資料目錄 | [ ] | [ ] | + +--- + +## 13. 開發者模式與 log(J 項) + +現況在 `devtools.md`。 + +| # | 項目 | 現況 | 保留 | 刪除 | 修改 | 不確定 | +|---|---|---|---|---|---|---| +| J1 | 開發者模式開啟方式(「版本」連點 7 次)、不持久化、沒有關閉入口 | `developer_options_page.dart:69-77` | [ ] | [ ] | [ ] | [ ] | +| J2 | Debug 頁現有區塊(log 檢視、資料庫檢視器、重設資料等) | `devtools.md` §1 | [ ] | [ ] | [ ] 階段二重做 | [ ] | +| J3 | log 寫檔(位置、輪替見 `devtools.md` §3) | — | [ ] | [ ] | [ ] | [ ] | +| J4 | `DataIntegrityRepository.scan/repair`(只有測試用) | `data_integrity_repository.dart:59-85` | [ ] 接到 Debug 頁 | [ ] | — | [ ] | + +備註: + +--- + +## 14. ADR 逐份 + +比對細節在 `engineering.md` §10。選項:**確認**=新架構沿用這個決定;**推翻**=改走別的路;**不再適用**=新架構下這題不存在。 + +| ADR | 它決定了什麼 | 代碼現況 | 確認 | 推翻 | 不再適用 | +|---|---|---|---|---|---| +| 0001 每源設定收成清單、音源改用字串 id | 刪 `enum SourceType`,改 `SourceIds` 字串常數;每源設定改成 `@embedded List` | **部分不一致**:ADR 說 `setUseAuthForPlay` 對未知 id 拋錯,`8ffa7d4f` 已改成建一筆預設(ADR 寫成時就已過時) | [ ] | [ ] | [ ] | +| 0002 Isar 只出現在 repository 層 | `isar.` 只准在 `lib/data/repositories/`,兩個明文豁免;由 static-rule 守 | 一致;但 `Isar` 實例本身傳遍各層,UI 甚至會自己跑遷移(`developer_options_page.dart:548-554`) | [ ] | [ ] | [ ] | +| 0003 保留兩個音訊後端 | Android/iOS just_audio,其他 media_kit;共用純規則 | 一致 | [ ] | [ ] | [ ] | +| 0004 Android 下載用所有檔案存取權與裸路徑 | 知情接受 `MANAGE_EXTERNAL_STORAGE`,理由是永不上架商店 | 一致 | [ ] | [ ] | [ ] | +| 0005 曲目識別鍵包含 cid | 分 P 以 cid 區分,鍵字串是持久化格式 | 一致 | [ ] | [ ] | [ ] | +| 0006 Release 驗過產物就直接發布 | 不留草稿,驗證 job 取代人工按發布 | 一致(release validate 比 CI 少 `dart format`) | [ ] | [ ] | [ ] | +| 0007 Isar 停在 v3,改用 isar_community | 留 v3 磁碟格式,依賴換成社群 fork | **部分不一致**:上游最後發版日期寫錯(實為 2023-08) | [ ] | [ ] | [ ] | + +備註: + +--- + +## 15. `CONTEXT.md` 逐個術語 + +比對細節在 `engineering.md` §11。選項:**保留**=留在(新的)術語表;**併入**=併進對應 spec 或 docs 術語表;**刪除**=新架構不需要這個詞。 + +| 術語 | 意思(一句話) | 代碼現況 | 保留 | 併入 spec/docs 術語表 | 刪除 | +|---|---|---|---|---|---| +| Source Auth Context | 決定某次音源操作可以用哪些憑證的政策 | 有對應:`SourceAuthContext`(`source_auth_context.dart:76`) | [ ] | [ ] | [ ] | +| Media Handoff | 從解析出的串流 URL 交給播放/下載後端的那一步(headers、redirect 檢查) | 部分對應:redirect 檢查只在下載 isolate(`download_service.dart:1831-1885`),播放路徑沒有 | [ ] | [ ] | [ ] | +| Stream Resolution Auth | 向音源要串流 URL 時用的憑證 | 有對應;`streamResolutionAuth` 欄位在生產路徑上沒被讀取 | [ ] | [ ] | [ ] | +| Auth For Play | 使用者設定,控制播放/下載/詳情是否帶憑證 | 有對應(`settings.dart:724`);實際也控制首頁排行榜,CONTEXT 沒寫 | [ ] | [ ] | [ ] | +| Media Request Credentials | 允許出現在音訊位元組請求上的憑證(目前為空) | 有對應(`source_http_policy.dart:82`) | [ ] | [ ] | [ ] | + +備註: diff --git a/docs/audit/screenshots/android-explore.png b/docs/audit/screenshots/android-explore.png new file mode 100644 index 0000000000000000000000000000000000000000..38868fc69545dc0313f645ce01adbd62aa49908e GIT binary patch literal 663631 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�C`PHK1aSh&0;k1(8^|AiKs=K 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

9!H&9$tP(#=B5 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�HTHNC+DDdTF zI)2pNTSs!wL>D$hu}oeVjS*T1t^x1R9uQL0L|2(8oiAlCkCL22z{Fqah|QB>pc2PR zcb(+6+2okWWB^*+clDgjQ0WKE2Ed{C58{bn4B+4!Mc@V!N=e63nA}6($9ye~HjOOJ*=E7|N+M}vha%Z@Z3t*}sR{T|nFcad%W0G;osb=BI zx^toDe5;eQnY~f$0MJIU8ewZN4-=Eu6Q_2@hZlVWdNw?r7$7edbpFPNsqy~?Mxm41c{uE+rS0Jt1A=@HOs3%FQ8@;w1=7<=Y6c7G2P5Sxh*H?d=QUA*4 z31&;bqFvu8sw9jypox#z8zr59N=0il9D3~Um$0CT5YxSXAZ$eJMv zwm=#IOAXR<+mV0zmJ&RA0Z-LW3H&hI63?WR!o@HDvIi+DFAt}JK^qwV3s7+l&{eGG z(R;Y~-XB9Qapa;gU7DQ=7=@6ASaE-$-SQMngN-MYWl=`m&}IbA;J0ko5o>RT%l&7( z0zvMICiZg5>dfGdSIx?yQA4lMw08gsuQ*gK#gAtFJf*UjdGs9snRbSqa=f2i$#Ls% zUF&+aesLpVztcuQn{BRQwsW_p$dzEF1JoYRA36YHvrq=?ig+@h*CKMkkE>DD8c|$) z5GN~{OrA9{je*CsJ0EkjT_Gk(_hEhvhqzKD9L|GoOxK}jS=JuU^ic0BkpzZVbG9N! zZ!)Yk*(`vv5j7@Ka`(41o-sRxso(h{^9srkYE9_0wvnu_qTvlu&5S5*c1NFeyjTMxG5O9KrUyw}kCl!v#YnS+{1o?f1$H3)( zE&6Y2)_*$^b_3BvBya)W$##aP*E(nsPK=}`SiE8I=?Y~R-FQCa+Yf8#b2eQPCc=qd zBf`|xYsi6H%#1~vT4cxp`|_uuJ?gX;Q0wyWWKcDv$fzwGcNx@7d}4}*2voIy0l7pv z;=#eioWUjR!H$AutJKJFIwi_?@UW>VDY&UJ;Wk9l%}2RTlETO`hQ*02YsC(OxZmpA z_^=Wal@@d5WNm)La*>BCqg9lY`u}~L7BX)0vflAz|gomdU)Ln9Z-X2u&X(Z(!x5>sHRe^LM*ibV2V{9izRA`0WN7|u1I^)jcuh<7p1Jj#MMo6 ziK=cfssGn4cFX;j&qEimXzH;#R0Lzww-m;qufUT)z1I$^xkhDdHT;gP_mh7?Isz$k zi*F(UiF5rIHRrmcZ-Tdc*Jj=rS!3dI#5KB6Ma41NyEZ=h%$9&U=c!DR5wfuC9}e@tH?vC6T)|0W#LRLPd<75?<-z-h zDpK_v3CSDR7u37xqUOZL=cZFU4kfxkEu5l9F``{Ghi|yr=i4+TXQfbN;!x8wO@k00 zW6I);ZSgUxMyzsb3(4a@6j>y&+X#5th3l4w@cQQWU=P#lLWePqa!K4QDxIGmTMQUOt19ubVp$E zEJ!kS#5k4+N@cY1Cyo|&iMdKS0KyLWw9p*9_YE|Wgjg#|@dTD0iF&vYTJ3oqcpGh9 zGm8rnzD+W^*7`dCdW493H2|yLVbM zumYM^1a;1YLP;DCA))_jT!x84o;^?qYAi?OcFpBc-|R4PB=$EwVGb+rK;bcqnHfio zt!J=@I%O@);=Kp@f1J2$kQ28!Kr%aByr8BO4^c6Hatc>K&mk>27f3IILrD0;tyoCC zBnQHohXD%P%&fMYE*He+TG@NU1R3Rkz__*cu0%O5~JCn&fa8P(-+!GBj;{xLMt^H zhPruLmW{ra)xwz-*I_9xV3@8T&01vs;!h9PdVdC|% z`Cj@;SwLxKHO@B<&awVCBRjcoSlUkg5|1orGLE>t$4(HiZkrTtHM=Qt|aO)B4J za=ILVDYMv%7&!}94{oYBn%$sfTb~k3MH4BWF^p6H_yiUX55Lx7P7EJz+nNze=Gq@x zs2qutRqQk)cIYsm!Zgt4e;|!cj6oC$BMatVq+g*FYERjKx*&>Pz;4wLVfDkpgvESP z)^Pz7`x}S$;qV*9!~t5!VbZayx&vR(P3FNGnG)ts4vQJpP;yGDUlnuBaEP)x^UT(HVWIzxG!35qWWqmPQsXKrFOG*Op-7t_OrJQ)Al4A$fFjf7ZqDV`$ExgeNO%oYhRZxbz8BBcLnjo=8x zZ8&WMc=>MpT^_d;h;yuqY$YTwG5f0>^dTA0zGP-}4TzgVM`42#E1K&`fYK^YNl!IA zT|TTfUFAlIUZ@TwJJq>?_{lUj@Sg;RJOk*M;+f8d{){II#07|HB63b+6)+5n;}}cM z#Y?OA03zX#4y7N?H;4R|xf2s#om&H-leEO*s8Az4B5P`lYUvL^1VYW*-#2rTfYMdh z7Ukap6{}}$olLx;OqIpO%S0XhIimXU#H}zVS6V|$LP=*Sgd&l?aW8f&ZoTM*5n*&7 z@h`?JNw+PSO|1hh7$%Jygy|3g^^rI!cxKLSsf)7^bnqe9rqS7${F6rrkq)clkUHNb zN*Ev`@~<59w8cWayB;=%8HI((t`jw1`1jwYAM94gKz!6tkMd7V@;+A zWxY>%sF2Tcv2=8;mYuhlYn&kSxXLtUHML1VtY1QPC9)-J>_gL??@zrB4r9-M-X($y z#hJZ-&(o%BlVmGCp&b2cgCt0!l4!ZBmEqbwJ6Amw$;R|LWG)zj5d#$X z|0hM`XazC|@@=5N#1GGT1B}n2y97Zm`AZ<^+X<{At_|wEF zC;@BF-JcblP)sxJPk~Eqd9agT-fj5VMo09(K2irndzfNRE(0izX%8dCFN{T0xqCH) zi=Ag>;qRR<{2Jk3yGbsGcyA?ag{kfyq3+CA{{khY%PZ2wN>i5I@im87K`PrRa~}Div(OyY86K?`SKB0&I+u0jh-910BC?5T z^f+$npm78BaROUdy1erAYWg2j_K2H&n8$B*uN;#+ZZIMoW;F6R$BenE+4hEo_}vUf z;r!XSwCH%QL`F{B3f~|foCz}ErwS~x!hb;p3-!$cYBjAbTvq~7rY-y*>%ZIPa+#gZ zv*|S1{P@uIC=kwQX*ya33fV!^?t?U z2!?QX!iCbgak&tUOPDxCpr-wekCx*Kjj7^_?=0k0ycRQ28U=+^g7gZBoK-whVyc%m;n0qQh}1SDoLRiYK2vDGbAX+nHZp2XKqlb=@UR+N-7#y8Nl>tf}nC^t9@ywYm|(k1Ge4ygt0!kqE> zcu{T=bQlOBXqdbbYFpVL|CwJYM#T|aXU{E3#GzOSTQh*>Y0vjuN zxpqIE;4}1WF6)_%A9C_g(F$}Jy{nW<^es_Vw&T&3rVG0)^W@S<@2*kJ|= zo8M@|H%V-y1v}GqZ8bVF>SjdXokF4Ij;6>#btm*kOUpQ+>&92X4(;9cTcS7ZvD@@C zyB1uWH+|rVRC6c)r$*LcMc1|UP{;eiR7a|{fWw3_e^v8PB&SzWnSsN-qrK07Y0_;? zw0C;V%!~>bEor|;tglG=FDqNxFmcQ9#YDs0o_UNq?GDtUen)A70aaSeSc;(R9>4=3 z@9@k%N5<^dIkQrslA}~QRIbT%9k~=5oJMW!Y(9XnAVe@?5i@OwVQN2|(#^`sT zbh#ATz?DN}N{S^0^Y`yEv6_WuR3++ks9%*_{7viboG?)w$1ON%YEtE-45|6+j7me*<-wYa@QqDBctV_l6Td99585qk z8y4)*m?CJ`ghLo37D_G00g*ytDO>B8y)r+a#8Q&0aWp97%d&&5j_SdUfW}gMc>u z7BBymwihNGehVUi((CKdRe$OB-x^~WpR15dC_^)|;LrPlt~~uJfkNY7JcLLDT-}{s zugzXd=b(xZM9=q6Z$e`>pO+eitBA5pZ`R9XpG%I7MQlwx~@j4)hPR( zp188!o~WDeVr7N?x8)A*(((_lSq`oX@i>6xLWer9X@lrI25KFV!L}BTV?K97(uZC=R-%%vrZ{y1F7A6b}X;rp2@p5s8Sv!!rvs zQZco(Oex3aMAa%*`**U+ac{2>#BF`lk31z(b$4kBam!wLBMRjK>U1y)k>4XaPR)`+3pkV-u#{mmOVA4{sA) zFNM2soTIfSmhLG*L3tpC>u&-AQ)fL|zcw9Vnl^sIb8dQ!iCny%EOn*|yv`~7+{e_& zjGx;60C~akBaYyB4bU8|msP31+9p6$mosr5nco^SdlWjZihO$xo#@w+)00g+JYMoM zPd6f1;tT$*A+WBSvd@I6w|(>Eloa>*q1NZbwC7&zF0gKfrj60tOyGSS?HbtA7O@`r z_8`sGewAm6cNIuY5D3y?83_@%LA86DM5OkT6%i5fyxGm-Iv(O%*T30Ga&WVYdi2@q z3BbI5s&+A>Tk_rt06`)u9u)&oijpA-cIv-T;iAh3G-)pq`me@?%$YA zkCfQ`W;|oay}^sn>#Lk96-r!y2$+0iMT$MB+r@3M+2l65icQ>orQHuQv=fZ?@=`-I zR`0M2vnF05O0++1C2t`0@K$iNl|+9S2kY3z>dt)o>fRw#p*~PZGpgNd^%;TE4TROt zOCa4kzHfE*;Df`~v^ylov^Ux%s%fCFbk>@bVbzE=ap^_hBVq{bzI?j?Hs4mZfj!L} zz5%9QM-D5zJRL1#1U|#Nwx+j5?q0p{?xE}I>dsc1l2%>M3C5SaF+eqX!kHkz%1yis zV}X)A?^)yJXZP##<7t(^g>hDw7pU%i!WF_{K&^<13;Zdq>jN!G*K@>6|MbwS@_iac z;l#bt`(nWwd}tl`P~P!Rd4;e-;T)qx`z=YpL%7aWQ*#q~Ey5R3rM0SQcq&nr;{hdxv3NWs!s#)KrGGX3km!jrirVJ$ zEZjZT88dPzAjJl-`^95erLho=g#90I<3v;fHl1#tk)$m{WQ^h`jvOlWjF z#U@sB6zF-z7#&1)uMcxJjmLKc9c!r6s10Fc>~gy1OfZjUyNh~2Elq9F8S~m4+$w-L z9rs}tr$|982>9e$Xa6f^pi+DlLC3P%lEPS%fyMh3Vveq^Ubd%)cQDw$g+5O$5g~-A z$1RmV#{i*J=fGC<;^&DN5;&GDlzHLsj^n6DWI~X;*$PZ?QaFJk>iHiBbzso7XN+kD zw`RCx>6mV)Jpz~-4 zQ*rFcAfRo3>`+ij(e;lQy8q3|fp+9c&YiVkoVk2Bdi=>#LA1V>T~8MJWo4)zt27~y z3nYNeJEHKm7mX~B2gU{oTmL+&@tME}V^0!FjuAC1O!+Mx_<)6XAMp-+WbrXU#iXxP z-D@d|RV^uSi6Y88e8||`N&Nm$T|JwJfV$c^>G1sc2^PoRr=`OQ!j9D)?Nc_b*Mzhb zV1?5`g>eivSv2#nhIOlMr`X&VJAaW#H_{X-V1vAr{4oUw^<74R0BW>$OHylEopKNo zq{c=8oi#Y0`@8kAzXCJ2JroHFHB4M-)`3oQlj=z@ugbDsz4)3ZSyx!D!~-&)#yIc?v1X5wnd8V=yv_`s-8e^t7CHS}4=w?eq~`M5qE z;%t6h76AGtb-bB^={i1RdR~1AC=H>IT5NotbhXz7dVYwo5%4Z^*sqLVw!gZ%-7|GU z`&tX!31z;6K;f0*!4(NuU9Yd7w&%}r*Aq`Vn{SISvZiR%Q`Y+TsW5A9UFU@M2Eezx zsb?kct=Fzk@K@W7`V{2$%V?t7ssWbQhx6SKpEK_6?3=SH{#OlZqj~(X@o|K%w?Tu0 z$IaK*Q@;4Plf_lL-K32tXppb3(Y5vbcAoT+n8KiQwQ(Ee+8GC8hpaXpLOO_^ybWIJ zGU^C<1&c$EYd=Y-(!Df-C6y<4=LChjD_2~m+gC{4KV$;Fi{<*G##V4zci8QH(RwPMjvTL_QyrLnmD6|6 zc~167ne0!`p6_V*v%P1LVHZcu!Qxkv+Qd%`k)Tl;_iHm`AKFP+}fe^uO>JcG0 zdcr$=>?BNl+C?@CC`p775GtX7yzW@KqkJO0ITJOU+@Y&kGLFlw$RC;#Hn(A@O9Oue z{SSH3XSi1KXHK`A4M(llw#8!Y!q*O(i-p8Vgt3ci@FG=y{f@=XLL5hFIZal7j@j<@x3i=!$wwpc5Ojf z*{(yQ$LG+`J9ORG4{M_9!t)JqA<8j%w}?xRq3`aiRqumd`oKAz&2fSETLJK^L!XDw zpFL36R^y>$}fS7Un943&RSill`z&18(`o; zwQR=<6+wQNK9{e>3)a-0lRypp1?&4)5cva@!0S!cJ}4xeUtt>@$^+@%m$jd`R6%bo zRC%&@JvTN9>@}Kd-9))|7&8z6AL_C?8cUZpKh`&ImJD934HbKCj0J9ti`@384;bt{ zzU7h6s;d5`MhB(FEU`6$e+L8`D$xpCf6>mt&@2EYg1J~sN=$DH9jzAdq%A#Ro!j)% z=|I4YL+N&8oJ$r#8_WbYvQP%olseZ<{*V2%&D;gLqkX^b>`=>N9_Kc2;*)@P1e2JZ z@f4ci6PHwYczOapVH0+x_-t5b9m4TF*n6uCD`ir3Xj^HsMmsZ)v6cvg=-5N%c^q>O z4-i@n#9(9OT_aY8J=`IL8AUF0Tb~LuQ|DU!d}ZXhoM-*Tby1p1S9TE&!=k)tKHi9R z^6!cb8gBA5Y6Gh&1=DdtCRcq1cQ-oTmTr^D+f(1OYW<(RiEn!R+s2=ZC4tHYuizKMUqrO6T(~DZ~ zpMCtx>F425BEyYGq&#)*9K+W_7&}Y7s+OUhhm5A%)}^i}P?!eheSul^FSsj}ShM%A zdTIV3TR&Y#|KLsBHw(cNL3RUG#RCtT6=dakOKF%Mv4yu(Kt;N zx6bunujkIK88GjEA9-(qPdiDS!ytb^|LG0;>Kvb_lWA1o^H$(CN8sbqddlGH4cpaHJea|FZ;DBUrvtNmp|Wto){slZ^eXO~AsUYWkDH z*n^EUk^wSWc)OjN>8G^Dj_%hDAuvn~JP8{NEoD-^86w?0D%c4GC-|GjI%z87+~=71{HKo(bB4vy@t9#f$$yK;~vi(`O=B z_GUls=wq9E@8;F5B6%dR54fEz1S-^{=om)xA=7rgV2Ic4z$fY@=>x7wQT)lt{_JW= z{a68{zNbTZ#4jS^xqFCgvz7|Qv@sTxp*lk)6y7!DsW?kXi!ISSSR4(ariHhF z6sNMP9|T63ZD0~qswWHP>CiQ29~HUqjG&wcF}}XM&Xn|>Ae^>7UBGcjn>-XK`0 zRhYz0)#jVV!2#0kXqL~O@&U5$EqLc!0+YZQ2aK7y`>v1I9p^>Yedeb3aJ1L%>84vR z`v~x!&R_skjkg2@$+$0dJ~Y6{K7y#61qR0SZ)RQW8{G!>H3&4W+?Fzdv| zC8^8T?dqDFpMI~Nw`izr<97kcLACQf)8|M;Jk1Yoj~DC6E$i#w^ zKj!}f1L)d=x*IlGedyr~qgC!3`QGyEs`>u`HOJ%aG*&12_gHV2{U@K?qXe%Dy z>i0!am?S<_kepx!wU?Y=@wZxX{|{1aomcb*VG3G26f$An#O%&atnVhZp7$Qw+G!3> z;NFHit9Yq}yB2V!X;0V8wXDHO>@2z=v@kzX$rJ>wdF8DQQJNV$DJ{NX$Yl<${z9nA zB~}_57{j%xxCp7ImBeD(=?po=oc0pax3Gznn4vwLPEGv^$BpMAx&l;i1H=*GAtc{k*=?i`8+koba{;z zb!ikYnc_7Bb!bqnv0Fx4)_iyYe6TosP<-9EIcm%01Uu;9&I$_0dT8yp)w4Y(dYutu z8Q2d~&{eYXc}TSeQq+Qq{PLYWpN!VO3mSahSH;Q~xw?A+X$iW=wd}7_ru65|)4M*; zGukj+%qP=F%)6$&>UAX&nG7aDRg(=8Uci-034tfnCGUe&qAH;!m&)dyU6_vU82O^_ zxWri=qftIpxc1`!Lj2$!)YqQzmL?G2gu~AkT9p)5V#!emiIn$f+86fZ;E`mIe2C{B z2^PI>-$7*BbuELaSSIavLqV5hqj$P$2Kd0>{>?_GN|aoj`)u$+ec5j;Y(cgMg$7wwQV1W*Zr$ zPz69QUFYN>^&tiQ7VWbL7NUsH&-r9dT~!I};|LvPPEbQt-Kuq;GXpV}M%klS;7NZI z18bwU9V6`f<-iE^a&mHj_!l z>cEzhsvR+5ixZ^Y+rpMZLQ;UcN1vt%fXg4I5#lk~7N?Cl#~=Q3o+w3%<|hj#OJGX1FUA^oMA6><1K7teT4`J-n3f;q#soQYW!5w&61x`5#HBL?fjucoR5A z0Dj5OCuhP*pX}RX5Dx&S*;MZ>pSRO#)%W!Xg)IIKj9lOmX~@+S^>+!lwfDm|kThln zao~oWlZ?#qQ(RVS*onzwOE2>KJE?dy-uhfq%~E~Qiu+Rx;W15;e(j}*x6e&pmcu?K z@ul;{N7wokGN?^7RpU5EmFab{tPDK)Hia5_&QE*L`T9AUbv<)c!y`& zpsie;Z9m1_gTVnOxJKgx5ck1d;=BgZ_gps5SkH5uGg!YS^0?8vS=6zwF*{GSd$ldf z+p3|1z`S$o42Z0o;)U;H_F$MMl5Btdbd?agI(Nl#<>}%)PPoL>(7(Q(4Hg9zJ@RYD zLq)N^5{}hR2WB@`2BVUT*BH$~gH+=q;UH6qw{~_;`BST5gXrnUL`AYKd43HKPT%J$ zl5|f)@sM~S%c%tRQVECnr}f;{^&4YhVsa=Si{&X9#VmkisbFgZMW98X)mXC)pupYL z%XJ1<=@O?CCrQ5`iqwUQi)j8z*459|Q7U&xcVL^$E)}BJt4l3yr4Uw7Nhzn&&WRam ztaDfSW+y~G?cyo71;y{D)BQlYC(OlMt%uk*H*D?iF-1~NVhn$ygugjoJbm+*JIf3t z1&y^G#-n;KXd@#bldp)Gz?DjtW;?La8nsd=-m4$Qfoez_DQ$oPhk*;8X@vf0YgLOx zc6A+*t7c_d=!^A~Pqq~(%VrdS3bjrJ%L~!vJKAKpiqz2X)me@-UcARq>hR})1)f?& zk&<*DbC{a#Ph4#3qCf87vqHaB4SdcXVD*-suaSL3>G4jTzZ`NQb%C@C3m&iqJ_i`> z^LfIs`3k6wJG*adP0aGw+cU9RiaDxO=eRb8@e4gxM2!uwlCZsHoq&!{ZmOiLC@MtYTAJ4 zCXePHzc*;H>*6~rn5Fr+S?Y>k$?7;*AxglSJiO)o6ux#f9o`~EAm(o$s?q|HCb=JG zHqAW;!DF+!ZmcQ4&SkwgC+%hdFSt24?JjOsE?`6Y+SrV|A6*YBMRzhEz6|f*0@W@W z3JZhlCb`O1RU5yg$WqOftSfEVTUs#^UWT?@e1Hi0T`S>K3uRM~p-uhr#=WVD!j1ou z1|t(jpu{eesiR9~bz>(hLx8t3R@=sj(g&NS0tA;ptWM0qmf84ttvRH;imZZ548o0K z6jphs;8AI$7-(z=l4yVcK|Fvg3Uq}ZS=vY*4FCHJB`$A%;wWv}MC7Svn-RNQg`9~K zR_gDZujmB`vzB5U#ELp9LcE#%wYeA$me!l16r^8Gl1KBU0Qob2<8xam#d5N*zzafi z!ALL@%?!zzZ}@Zk$xf_AtEUTsX!!Dpw_X^v*2OJ(T5lYUc@P7yR=l*A8VqspgrD=@ ze!W=*q#qc*(g>HR%N~=nflL+!JW}H2bSVu2VyP2jgH{L|cq_9M20`pHgm7!VOGY{z z$}xeq5L#IBlO!)wI1K?U9r^r%Y90oFh6aNm-M@~3eE^aaMVloOmhz82SXA@@4FY|> z_tyEvU3{f73rIyu2&cIIuOz?5a&J{I)&&wT<3#wYeY$U7iOOpzi1Kv0S3}5U}IwImFru>;;L~ z{#1k~U_Bx*nwu$KzI3p4rJD2-b737x7C}1iGzOWojU)m$*Aml>N7cmzkSuL2Z5QZ}?u+HnWS36REis6H(0GF6NNf{`YU z8SET_Qe64|-@ItbD?SKH#iP|(UC0Wd;KNL>P!lnRh7qe1>(?*Pr;8l5rpCd-9HNYp zxh9n2D1*HeS+xL@pPKhZJETDsGTM4^B-JQTV!A<+D{2;_W-=&81j3eKp2X!rVgrj({U7VYm4whW-%}c5FSkU>L^tRBUpGD}>08Oof5P$o_PK z%IzJP1TJqVZqxxZ^%+owcP`K}x6n}V^FuUODL-FxVo+-LiQkVI#6wm@L!j0T>r6id za`H6rddI=}TmQNirh85FioriGGubgVbh+#{wU)PDKYzaPZob+*wq5Qj;2M;^T<_d6 z5jl`HxPCrg$e*9@NXuBm+fQaq{WD_NV=JM{P6yQ%*Q;OztR8F<#4gUqEB4-x_*nFw z;U^}waoyXkjPO|FFoyHRNZZj$HK z_fw6*|so7^`?7AsWkWDW74e^CU+4}`D;f#skAf!Ujb)|Pe*TTjrLg}bOIir5L?+ zn1zDSAd8Pg<3SS>@(>lF;@*$D{z5?dN4&aXbmCQHYdHVgTi2y`QM`uNbrAMrv!|s7 zq>v&SCo~d{L-+b02Cde76Mjn)n}o{JAaN|hf`@>sF~iq6cwIb{+l!AxxKOju^6>xCIV~RZ~-?E~_>*6srC&79avqGcl+##KBX_ z2}s12v<#0`A+sQT->sNcN=Hb#~foecsT=w@WEkIc~C7Rx4z_K+t|81L)VrXW;O78CJ9Qm2{r zm#Wn_noD9(WU^W~Q&t+~*nDBiAJ&PjXPkD4TYy!!!qQ|x+h+ElkPokzX8588TA zONeB3wYqj3O;>mCAu{>4FQEvEmJ!F#^bCLG4_RH@w8#IK(z_ZK(8C}PH z%=fUpZuBVPC5;fu)gjPT)Lz%ECn$n|yH>*3d?H2f1!?T?mJOuxvibp{)Lp#| z^6m~5B_rTJs8%-7N_iieCSAuDNTN|Wc$fJfd*p82^F4oM<%%z>J4td%WIHE5q@P;R zUy$}DN@6#W3PHpV7NxiQ7J^_%ET`Hwt+AdW$!Xe|cmm5pXJvVQ9tk!c<)}4E(HD-{ z*)Qi5!3sxKP7WepNaYmku3SilR*dR$w+tnj6a+yKm4%R)NuAg>S(%peI}Ks^owrP7 zB!e0a`$H+30^)FGUY%>^w?PEanMRZGSh3NX#QoIK zN{&E(svd!xTVY0_wU%6Qd||(nP+u;FgWrddT6|}_Q%>uEq<-muk^2=`+PaK%tWD2L^6=J{&2tM*gkoXFNuR4(`N<#S+ zl5WDF53%KrK2f8>jvZ(Izvw?l}`KqqF0{v&%mnsm?g z2qr~Jdj1xmw+6+Jh%y8FD78B&j0BKMY9*Wl|3yY4f`C8b1F`QbZ`OkKBANwsD{cY% zx;Xzdsyb|6HA*m2u$*QzY8fmbAEPy~zjn7-K2^36HRmUR(_Rh&(cfrUApGuNl+kmo zDFQx!`m;R)$?8UMOiaD41yzz2d4g0o5l1uRg! z#h|!XsT_|aX@fQ5LIZIB?hy>L6-icTi4^)!E;p*P)@ZlCC>6W$`C$%V!g(e!oNH~k zIngwt8Xlq1=;<;U%BWz$_!U@N%ntn|6c)~#y|4Zvh&lEkz203XoWI|rhjg`kn7MB* zaOpkdrLiEV?{%-XvaF=lW&MuXAmX4E5Q9w%pvFM$>zkj$K>A zLYaosbN|?{let-Kwjbq3B$CgaQ@2wB$QWY@7ol8V9PZUL9xcuon$}lJ-p}#77XByU zaCy<5x9SZ;4q~IftPCEjKvT$95y-49Z}7i8pEtW9syDca>6tN zl-LHnp+i~Id5+&Ul1EfNJ>d#4&>2&@uZQl>T%AA)V6q-oXu@;JZpVRN8kMzDSYhD* zH#p3i^1VY*_M=zdhxNo}ixx!3;LT{%^;HHxKc*+u$%ZEmlHXt`5gOidA=hg-%KCsDekpxK%vrV&0{Xd${GODWgdHYC6cSv`4cZYO$cb9a7NP`@@ zrAt~G>5@Z8cXxL;JlpU8`Mo%6!5ckmGxzM7Yp#1fmQu-V5kzrBb-GPvbR+ZC<_j0- z4vtDmo?L>K1qAqTvGJ@EMZsm#aJDH6ddN7~4P0CaZu4roWx)DiWk-+1OE6L2jkXbW z*3hp&0H+QVs42iI{GhWe-YS^6Dnohx_0PhC+lW!n3ho8Ik&=ucI4N1mBqSppX-CE} z2*%Hpc6=5qyd~`qxR-Xlll+WAa*BEC9DnnKROQK2XpTiy z623|zrO2YYAcspHyTEFiz@je+4(*k5j;3g`<^_Kd?jFS5`0R3mkZg&ufkPpC1>;(! zdvOi7TaX;F|4h4@N3JTyo>Ro0N{L=gS*c6eYg$xh{zS%ks6K(L_jR@`q+Wrs8`yyQ zI1m(6FCAbB8!R#JB}ugM-o5U-Qxdc~U%kHD=tW@BnPtOSH!a}?jyRfD7Rbf~u{?$K z7qEFs<*RH6@B}n#;CKQ!$d`*}k)3u#fwXX>FmYhlxPHq?^oVYAAW_Y@cXsaUmQ~=L z$h$tm>bfyu;KJt1W3`{oZ@XP3$e8ozqG{W&N_4E5B`)KJUL59o3QzaP&ET4VN6WPP zp9&{W$OLkhX3lSi;}1JD!i%Tr3jEid*u1?7gTfj6heOJ4z)<+cPC?NF85zp2v#;&o zRO)ZGNX<;=PH&9Y5l{ndmz9;}1D}>^I^`}JNN|=j(?-}QBihEA#~W);g3Xx(>zs_b z>EGk;^ZQ=>_g4(>ra;6Sj|f~`&2{0D~@igw`Du+nyp z|BEb0*!5nRr+)wM-f)Gms-4J9T*SkEk}_L0Y>+lUXPf5wFZRJM>~Mz^knn0aUL9Ph z`SOsf-Kx~=Xe~KKnrXP1l9(Sbpz;wp)oGI4E-m0J!y_db;6qWw)igOEMv%5S_q!tt zmQCH&`)08Fq>)Oit4R>ks;vfAngLz6zdVUicQvvGX~H2nzmPMG8YXjJd?LJhDN={8 z=-50R1l9a^3-M3l@^1MrVg$gyd_)dgFw25QG?Qx zzOdzYZS78<%d}VL2pJ%{dFBWN23eQd#AX59zw(MC!@H`QihTg?Y(zi#upxo!x{z<) z@>E{o^^9NB@rHjb5V~+5zRRGM3_5>be!Zz!R~_)$iA?w&sBH=IDvf*SH2!`v#W_I4 zR_%|uC>`482jCVHMq{&nTl7+O;9pn0cP1Qn`WwbQivVj!i_Mpt_-+B&>+f7|~$+&S^5%#EGn>Li<@lS&`ynDFrlajd|3DQ(({mMS>VD;nH^PxC6)L z>0q*T&Y{*ux}c@?hs#Cl+gk3zGbiEtCEo+qgHB!Oh9X|2$@A`UWco7gU<@GWD z5zdgzouDkF;&4YOtQtFr6FHe02sx}eU4LVfOfp6akX6Km27q6rN&T5uRfcU01IH0+ zh3`F8NKXvF-SslFxLM7|^c`%+U9T2gTG&ZbM##cItO}vkWSn8dw4n;y&;-A}bALvf zFDqj$`>u^1qgSclme}ar)mt%bY(6}#To1_adiu*3uMolE8W@USCteGN=pf0s++i}O zRAdbDRmAh35d`BnQ8FB&Essq$hb`M*o)p4S2*2fcMrvrX+x43)Wg+>0(o?sctI`SQ zmfJ+GF0JDS5h0^DIvl~a^2VMvRO-v;N%TzW)RrK-=>)gXM1}U!x+|Eahs!Pvsva=>xAT)-STNI@{zq6sWw?#qmGSYYI}oU)wrV zSichoBk}IH$KAT_`i(W%PCvZ9pR(d~Y})gD*}9~eXeo9{GY1LW@djS?@5>XD<eB8{yR;73?=a5|(y5CXQBWdbEgQCKmPK@9x{z*Grc7eKS0$uIfHo5+iY%%*!QF6$r2@eB2(y-o7iJtCS zy9V6+%s$f}1IE47pQ3w0KDzZhequc=lkGQCJ^OupmR$g~rU)+o)E2#g%V$Q}w8{}| z9<;WjkSm;h?EGL?7VuIFzAR?(ua!2h={%xeOMm^CRH`s=AK>(I7b|!*(MMU)3VK<{ zC}@G_`rL# z8m7H!dC*q0`9Hb_x{R=RJ^B(UX55E6c;0^;wp=4Xc!aEds8(n50)xl+tZ6vbavqGc z?`y9gjst>LZL80C?}0@MoM%6XzcZ+p{H+GEo8_Ir@O^w|NFoZfFh-apIae@Qk7yqj zKO}N()!&~b$9YJE^U`Q!7Sgqf1bw01y>X6Td15^}1UwtmOuP5%IOy!gwB$=ONg@4xKy z_5#z;+#Irxqpp;P`S`$- zAp-6q{|=p25^{{2U!Fv@81C{6z1QmB7Pwt)Ff}i|dx3Fw9l&d=A)F-mx552pkkzg2 z0~OXt|5%Pd=`tHpg=hOZ?FmKjwp;Ei;d&aS+|kMr(Nnh`xwuIG_$`^)f1+t~`T zQhqnk;d}CTZB)S&Z>Jgi{2md82dXtkMjoF7P%j>eXeKygN2rbF9QEV@ zG0{``zm#_wfO_ah`dYB~Q%yz@f*)A(im~j^2d#!ZO-*i<{%xByREZaZ8b2l&gSHG! z94#u;*4~~X_a3bz3|O-lt~92so?Tf&zZmxz^JyYy#QY#JKjdS*?=1h)QoVO@Zxa?j zb82EJ)(o{cQh7}wIkALHPj530hsTiyxAU68il#OxD}?ULB97V558`yuLwW(;W`nS9{%o&8SlR8|xmI0(1< z%-t^|$)r#WJjbb9F$7niw7pc%DLz=^@QajQWJrYI-cOL)bdb=8m3^u0A#qBaI26S2 z=0~vOeSy;9D0su_$}dUieG&IRgYs4WxhWPcbLqwv4qXC&A+0^bfo!KsE>mg@wJ~@c zmiLr{9?WYYZ-AlVa&z1t7WbbiT!Q1fHI@KTO5=asH>-6g4(B)}&1^0dGnRxrmpCC`@WkhNpm? z%6fT7SS$usLlM{cy&j?6OPbsREGieEJNFa3`v(VZ-sJg z7?pZ%F9lKaGro#WBm3i-MD!vNvqO)g+Bn(vxfs})u>mWkdl09Msq`;In88`r8vSMvfX`$h^w~*J_`#dNWNv5ngk*#6G(`)XVJ zDlQ@>|EBBrcJmK_JB#~y{k1HE%igo}?u4)YA0)o9arY`VVCaae;@KB|mHqZ{j7k$T z3SsZ0H^^Fh<*s7+v3I}otEH}AJ4k`QuOsMp^GxT(H$*%(Gs!rxvvRY*VgDr(Fs_Z8 zpPYYr^YZfa30#U{amPUNnsr`%y3Ot{HN1s-SkHP-Q_SKy-<0$EWiwgOkyEH}uG?k$ zDjfBL9(c|5$o>})3BfV(!uTJ|+VDy-Y#iP{B#RF@9^z+)*HDs8=dlxm?*$FUX)d6| z^Wid`5?NYEITa*GIX{SR@DqpF9oyL8hVJj!+S-cI;R<`hH4f3^^Eiq{7HEGSWdHd~ zD0~*o`x;scDBxjf#(^0C--E+>O|Wk9WGw&A>{-H;ZAu(IzTAekJT!cQv&fc=lc;ZE z5(&|eX9AiQZ^Mr{`1tF7L9(P=fwl(26C_t5prrKVPGpiRozPo^!#}nnMB04th=QYdo}Ey^qxc3n zFR{Q6DK-W#vrDMAbluRfFS8%uZ<(l#?-y{&M2~ZqI`f;gug|x~s&Y_Yk9`2{x_@qE6$6TZI}%Ue^}v+kJ5kpo zk#){*FM*o%hbQEh=k@o!2{!YV)3oL@t(9~RXXg2!+t#TNNnS!`Enal|Os(&|OMx$c zcj($Uy;iWp#DfoOI_jn$0io{;z^lJIi}l!0exHAyxXTK>=rBr)3J|G35qdE=NBl;* zk$|#S(Cs8d;0Xp;&25$KQ|fPAyN602^ZyCJM&mA{r6PST6axt?CyQQ}%0Vw8ZHgJK z&uf0(0RzXPwaF)_UH5%X`zMNY&y1WDsGN5iz)P0Et&}o6TQDRE|}_Jd0N4dmdmX>a0$Uw@k2e zB%fUir`|ZA08cgeU_Lq^9P%xElyu~Ee}J&t!dJ}FnwrTp1?GZ(Gr17KE^=F+rJL;y zv7PUV@(%LJ6eb*#(FeZM{5%$kFV75oklTQXwrT%n!x&Bt-3oEo#`~M|Q2`U!y)iL0 zBS|(3az&)o6`hCd=Z19(TDFgI6o@aTTsKuGv%fF-`;Ps9bMsG4Q=-wAyeC0C63!9KJnl)2=}S$bWB@PSVm ztjS-EwIi5YnM(r)iS?oLoLuv(#)oj`iSK6gpmUsyfKs5CLK(wKSxX!}8*B!hif?$^ zF3ESW;}HqB?h7<_0Pya#&I>8m-;7YONGlZ)Z>RrwD)S`o{R@3yPkjW9k7A{UQ>%E& zp1YjuM2Mf57?-B)*8&Hsx6l)nNo?C173-92a+(<-3~M9b`xoJ3_QArJET72ftw^+l!9djsV(r*!$oaj z5FQy%_3;;5%)eQI%nE<$*_oW$v5(tq+IBk0Tfp)r7 z(fT+XnbCgn+ZPUv8Pt;A_?>{k&B-q2o}WFlloB6X^}FK{*6&4aEDVR9njotdAs->G zrl=#7jeJ_5z1j27THuNS^8n-QFX+uLSR>rgdu5RB(Z^g01btWN;cdAhmH`s26426| z_@{j-CpmW-0*CJ5;lWTJ9tP&SYL!Ruh?`+iO)#0WyML3M8en+sRq}Yc)}JH42cG?& zy4=NN>0?C(FbXgwf*fJz0rw>VTTp6N;|p~ji1KMn$8!?JHGqI4cc1M$SX4@VneF`A zC3FRyez(=2q-p^8Q}HTSu=h=${Tk$q9(%Spy%W)65`=MLB4XEZ##`B(e z>@{hJ3YK?7K=mKJ|B5wzvV>TnkimZL{9jg3`Wqf!h6%j4B`G9(xx=fspM=XAB&g35 zuAv0iC2&nKCV87o6PD`Gd9ol`Oa{NQ!R=x~V?Y5E0|{Dps!5AUf`U4FSt-iU3&S4< z2sQDh{bUlg4q0fV=9bB!0B!s6=C}nj_wuVQJ}{KJ+m-T@pPmF-By|1=LL< z5KiwkG@M18k@Lu;2CB-ulc*I1;d9^R^*@_QK~>6N52++t1VOQ=>>#3OQGU10unGT| z3E4+&(J$No%;7sT8Oc#!Y5Y6#)7vYwecBie8cL=SQbr(;9G&2}`Rwql!rOfP!>~nv zr0R{bR$btkpjK5t1Q|Xhmn`7%Cs0#TyX2c(>|ruSm*DzKJzPUP8u?Q`!)BWi7R(2Hd7w zN^2y3t;oR{VAWV&}nj@gDCtQYqc<83fupxo{{~3oq8j-YJq9euy=B~WU>z9 zcV^OaESuP!#g$~T^<)Vc{6-HbnSKVHW*1B&eat2lb5y?MpH)d?dy}D{d^-1O@oB8^ z#K>+MiwNAMiCnSQBie?>L_5a;w8W=O`ju{)6sMjkgO3`YZH(%1xmu!YBS2fh&*#=} zz1UKHYFMq+6vdMB9?5C~ffKBK9)!Lxbl-7>QoqoO_2nhtYDErIDKhH4pqw6R{qQFM z=z%4TLZfr3T8u@LQ);oeo+nhd# z4=Q~_RN?m|inEm0GU+$6nrU%?+ugti>_pbHbubn@)nnXs4(+qxzg-ebE&1O+^RU_9 zRXRPNfIo z*da7mWEr$LC)pHYmVza4x!%Y>6Z5B<_DQpu9nfAt%dhK7PM0+9=<}c>hS@CErH-mX z^&zQd!>OiJlH;Ik?r>na+G=c2aAHzn!4YxbQxHax6~{S7@V#9W4rQR@D0N17;rt~_ zlclg!VJBG)Bq$5*M#YNx#JpAQceZzhIKI1}K2U#jt6Sv8^f&jFUsu_D?0Xuo*@-Ef zE~Cg1Vn_pv%{>?UR36u9!q^inRV^~f>bED0(f5$4P0XOrK4FL1CPfGmF{Drn#RW*!aAy=AR$`d4*@MV%~WCxTb61Uq4vdc3xm= z0=1tTBn;R_-qdmt$GY-RwY@i39ha_)rEXQv?MiM@L5s>lkJjs{S`N835saX2&ZH6h#h+;AXY?0+sM3(o&v& zp`|RLq=|7e8dtA9bHEsVTyhsXR5gW5GXh zKO>jvr%&>iM}RE*(ZOyD6O)9(R>@Umd&%j+U+QvRta|WQj8k(BjoYAQSb0%gqqjiT5m4oB931TK8Ul8Tn8@M zo}+yz`Z8q~P^hCA8ZuG}bav#?r+T3CM~ix0440m-_}S&zaJ58ZH*$f=_mSH z)cO#y9Lqdcx(m5d2H4#V=E-u$H~pB&o?mlevy@5!6QB?T;OME9zwWOIy0s7OOCTPl zvjn!QtS%LHIu=$1!mdicf0&T4KV}TAupWhX z8hwre`~sIia!p;@&-HsFPQ!Xz;3HvxCxlSX@hJgAf(x2IU9JE|Y>Vo*o!J=;?ej@~ z&p+8gE%hVrfd4biV^KskVWUak*}8WZb8!FqWdkg-11qwo%CuV-mB!{hu@TTZ5Q0ue z6(@LSb5AtVURtT&1)8^RA3H3~UISjYZfMub0zuQoEw$O$45`=8B5OllT>;a92AUaX zwEs!trMZES9=Ed^^IGT?k@*Dp(9xOYl$zMsp-3UoGNBF|(@l-&h;c_c>82saxZDlI z%P8i!IGMDdY3MvGv5ie{7=@97@;ZcN9JozW&4|c9M`AM=2#ZDfS%W3&-*MT#g@=DM z3OMB|5xho$3K!Jk)RH7=VR~kGZrV;ZB*U7nY*?|XPcN=rdHH4b*S#OzBlMy9g+Cz0 zsADx??Cj}X5PZrNVh*~|zvFTylOaQSpAB`@o6eebOTdR={JClshsnb_Z1ObndBmn? zpy#tY(NS}>)zed-3H`{rchSe^aI#ta{wcGBtXPsxlX0Ys;43K{B+wg=q_F^vo;Vri z`n|2K;~x)1UL}GIhY!VJU!bxbdMMNfLq5taStR$m5hf#`v5OuAU}|-UEY?{{7d88rH69%UKTe5a>L=zSa-wS$+4KcZwwl^0{UK1o)sP?c=At=C>?B z{lt!QexUvbNWQldehpB|ILPrk-vr_%4awPWWI8E#?;GMBqg@_*g2_RAe)gCU&+Tue zQ$$a7xds6c-;+%^D!~9CheLSp)JnI!G0dY!xwCu`zNkK^7@;xh1RpODbufkT?@dTN z_7QdM%g+b+l){BMul;fkj6n4)QOX(y`qH*@ojsv_U>-d*w5`mnwFt~&(s)6A=F09Y zTEb5c6e|z0&MAtHsHDSPm%w~RI_TgFk_7CBoc*aB`glc4-7a6KvOC7kPbPN!r}|l{ z)$)v1YS<|1>V`cF6rb6=O`uw<^T|ZdSl@31kt{6J(&CLBa8&8VvAAvpH62kPo}iRSEKgrnx0-vqi^#Lay>6MHGF&zcX;p+QoLwy9~#^yd?KN3}O`< z029H0n;Vo3aP-oqZfcgM2FK@*Od1oE={dz}^uGpNBOT++=5{lU+lc46AC}&qpp&+x zzbeJTg!LY9GLwPK2f*OPfOjV?WTg00dexfwjA~|f9uY8rJVc8-7=+BuqsSU%=jDxb z6i`r7`bT5}cB@xZAdVc(%%o>#l7k=#@e2N?v)WFem_=f^W1-PW;o?)eh-3A`<$pmI z%L}?ROR$a^8X8I&k+3#-?slv89+T^4<7MquWC?Ip|K ztueg8^teT=-urevwr~Aj%{+=4^Z@15@)ka=Mq^>;n;G^e4BYPM^tPE|ylrkyL&ziY zesSB^*GEGL%PPe2ia1(7X>*Z}8g%ff)%mFG-r4J&fG6nK>fgV>A(S$sYh&TQQ*?Sv zqE<1BE5tn*1BQBF-}d9TVqeL^ zDzqsn#Hek{Nj()qy^_??4L<4+r~vP3@XHIin_En%sbqy#p9(y389F2y{)h{$HobSw zcyI`8#*ZH+fQ!jtxhXcwxie$6%}c#v7Bs(j5dU=wl8H&7RAKz-8gI!H?={4pZU)Y>TXaCq8$8>~U|%(|1f~vM7TRD_fV_NE zZIZ*a>W9t@+ZKMALb0?z;XCQ-nfdx8Jl~&~I{3dl*dasp9rz7V3DE$t1QX-o znF6biEZFhpYK$XHWpF-y(lIdT=Y*Ehp3-ETuz}%~X9K=h-YR)CW-r>7Od%#Ka;&Kg z`(C}s>{`9^`S31ao)kIldjB_@5$W7YY2TSQ?k!F;@|`;s2s}RT2s7rBjfnKWyS#4> zyyD2!)1^`!{N#O4((%mJmubWz#IkylTpAS{$EEzU&NQ zNymXyox>O#$?;7UI`F5J3^H+Tz|^uBX6k5JK2}!xFUy908T{OTHbld!)!^r^(g}0T z=Feb%@+|d>h1zH7H1+?YOf{dHUzcar?&s!;Kmn=HVwKI>{r&s*%SQKyy}do+Sx0dQ zHFpFryUqA>UGPLI(M`?bFd!^Xs>U2m31W`ab1rrKW%(odcY4`U<&4M#IDn&+Vo&&{ z)C;Mf@jvPzLXxS#eV4iJuC)yZ)96lTmriNs$FtdTrr9(TEVv-4cCRG#?GVUY%;ie3 z8Gp`HIXc?Xe81Feu)p?yWyrO*4g3glu9^hL#Fb0dwm0bM zI}w@UVn74B?ey&IpQ$N~3Ed%dF#N5rwL`5AW!gw#vXzw;P8FB#I)(AyT90L|^4pJo z_op=YjuQ@&4IbZ=p!MWM<8K3e<%L(n)Rz-oxZ7@<^tG9t*BTx}x2uC5Z+Dbx!yMfG zH7Cn>-`lVGfRD1z3&*Hsn$ZA^ve_F?(6!auOGr?s>&yE3ec&82a`u;(m})++V4!Jm*L%cxCE~@37%i6`5wm?0cn$cNq@)2rW7z(p-pFsw2b!vj5Vn&bXA^MsQ3Ur7->=u z?axO!S)}RS+PYAgEg9296-Q{Ksu6OTUz*>V923L%KUYM3x8wX&s#=)&_TnkG%Y0H9 z)qvQ(!}A6efg;$QE%Nxm6b+Lkj;CQR`&7iVAIk6UYU2&o=Q76lFHh$sGULeBH$>)c zPQ~(BdSG^>R@VRa`iw4ag8NYw3lsW-nw;xz!p`%;=fSW!)wV+0*+KoM?Wa`?^IcDxHGwNmDB-3TpGY3ujBay{{%lf6 z^KyHBpKm|o`nP-1|Fa|PgQd&9p~yCnt;o9`a|5r7wwVRrAwei4e23}AGq7v#*8Ur> z%GGnj=8wallsh&oiVdvBtA&&w2?JH7r9oF6=Rt8b{Rmt9Zb2e@w_VTrG(^`CK^LG>TkbOT z+Y{kqZ-jJkx-^6PC^Hs80+5);gU4b zI&?);@R)-*2)wDiO^V+KN$HzaN902h!7_UC2TSCqkGkveKtgul^eXB9O0j<1~x-r;cGha$31MDmw`tEbpF!$DtS7LP_oUbyx>4QJc z_bk$#^Ec<2M3~HH6Vcdv3iYI>{V?SrLmg2fiIT6_a?zS$-b498@lHbcsy6Nyu!RcA zHg8fvs9;XkOBvN`?Y3Szj9}i-kLdiZP(-*msbnq3=;R0}IyPg-M zA1Y8^cemGgZfBmS@85ZV^fI`cW*AsfdR0jkssnFgc)!DNEDY@Zx;%S7783D#l{dap zTe}_e5-Nup2}dS)=zf0xz8-k$e3^Y77*P{=T0uyJr~CVLVSx=4u!|eF;=k=fZ2UT< zz0m0>5Vw!q_4;uQ=*0xjT1tnlMeY~XnJ=!ywElYLrK}<-Ls}%=IV1nRfj@_Y!rox_b@5OZ2WQ_lRME~f ztDTW-G}84?UWFfA_JVhg$*4-y(Hp&7R*MUfG_Ao%Z#|OW@&LPncvVy)bUtD1%lIHzF37e zo)R7miX~>5C~+~2TU#@tPrAQLgG{##yJ&@e5M&%b_!x1tLEQu{%z@O z0ot0!ptqy8%LeO(AhGzTz)Xc^dSIqn66HC+hh+ytl76#_!-7kv%_+ zqm12yK{)4t<@0MVpp8nFFKseoO@Z|8bACq=@I2W8Vu{^r#YX_H2UyeD^RIjRloPa> zkz;hk_Ae4wT=vI_v7LZTk>lIZ49v!h(FKiG{$}5TfEAE_Dw#|H*!zan@8V4<-ljVK(tgZ2~ct5g#mK)vdi{SmTK`L9Iy+=jt zGUSPn{2Wf}aXYy>t=Q4@H@~lM;Zd;BDoF+osA;Jj4Mr%BEp6tq($&~neB-0a_-q7_ z_=QKUFimlJtL4YsE*xW65u%Wjbl?zjq?yepY-k!NY+%XQ5IE9`8M-pf)~t&>(=z~D z?FIDWg!$yKinF|3f#f)!{*dq&)XfJ$Il9n;7pCm4zb1iBQA3yTP1$YPfRuf5!l))! zKx?)=5KCJexs5wg2iWJ-lU4Q<{p_kQt|B`|eU-Ed?fdS@372I{Ok4$ zU>C0T4|$P3_oe}qrGa&yZ59oztGev8tD(4{#GIV7>89B)*L+#p^pE%Vx7n%dmkz8P z0)6&I_xNvb>bbxT@b#HP(`D}S*X{dX9@kpcL5sHluk0=P++L45?QCVJSitM5gr_rV z_lO;6j=zIIt~&?lC8gFam*E7;PaIcaf-J&oCCyzy8?vuV$}@Zb6zD3a*<&OX6ZHHf z5|}OW(AUt^x3~ooIN$Jkk6Yh0CwbJtcP+|^k6~_!1U^6Ok$=$K=`!Em$U}iJBMTx0 z&RWcOAAH6;qV206Q>0_j#edm-iP!FUO8EyJw{ohUEQj zf_!Y)a0V?U7oh-BX7#+G#pEC0z~Z#$<%7bO*;?qo;lM44HKjEG|4IJnl8zR}Cd-&$ z_0hH!uCKodrW|`xoj%dSKYTw;x0>sK=)km$zc1kaykHjLupOFHoYFnB8m{5jm%3G~ z)`&sPr!Q_kcSQW69N$@!3-lbn+D_Ij>qHfW#uQ2Y#EwB8Dt~kGW%m(eC~(LkbYjSy z>US56P8D1Gj!rMRh{9ybs&hm4guXqUX*E*hfX8`)uMQv|oqknQr`u7_V8rS>s*zN& zSDC7cRT?zqG^adnlAZk^qJqQ555vhzp`854AHICv5<`@BwgZ%yCT3>e9v^*x2{dRM z4V*1nINha>DTUrWe43P$q@b(}tZ<98)YTX^v|!gwwf8_FCNg&|Q)0rQY>GRzLT`!@ z$CP4n*XUF62tCj4v0hO>zF)tZ1GfkEJ>B~6Vde(@CEaoaQVq*ZTPWJgq`=xE;_7`_ zGH|(#p@lj zbzFidN6mU}Vkw{Ib?KXucA-3T=MKEb@S@8Qil>3Al~(`RN^MehsmjVN6-(fd9Gn~d zR8m3dn$PlhK<_zA_P9XV3}#wq_&6|Aae<79iP5NNOxY%)S@cZ2zazQp zIg}_dB2iG&lxE~)irFe+(9jaGatV!`h{yiXLmXi;$$&3u08+z8jCD6Q#VB)mgLyGH zF~WgKtMP@jGS1`?3Fd0nURUQYiDJ zN;{4&GqLfbSQ%gBSi;VP=~n|t6|JnS5Akq|j4Ci-K7efVzkQ{hgHDBpnTkYb>e;F+ zun};#7IdIGptJd=fU_Jqbbuq(*E_T{!({`%SP+Zxt=KbLWhk}HvUgkcDq(>;^ zo9x*JTp{YIWBf)cY9DKxX@hKvOCHK=bfXI3A|lS8Z|?4Rj zW|Ci$VLPYdnQ(W)9@2qwN)<*B(NJo2xa5brxxwGCIn{vt)QY9=t1!3cY5|$+rfuAB z@{TqQ@aGG!Bi!*Dsd1;Qe0?)>*WT29ef@y0FOxb<{KH7yPpt~t;$Mu2bTBT2+q@`$ z%z}%HrIOVQJQs^8qqff4&PxpF3OuqT`d~A1YbKotD5DhPMG5C+EwU)1CdDurY~zPy z71VQn(-_d-${%E{w>&B+lcmTBK^eM@a+OwLs?r0$U;^)Wc;4zZS3WrLL`uHH=K3KD zy-%ql`r0NVq=S6r0T85_Cvd1WoQAkNpLCq!9e)5(0w z4Yf1d(xLVlDOhekxHBZQ-Pn(D7tr1EjAVBs#I06!l;#wVosL}iH4JuS5bO}u8iByui2obJL8ZWUj>F8J)yxWg5T(F9r_4Vai8B8WrZ03xhPRHstPw z2VM#L`J68=`F*IRoA%1=%s`Qj8IGRuU0GY3C)JXJuT7LyUy4qaAyH--nkgY%mU~<6 zV0Z&xGt?=;1G?J0kgH$yI~mpE_ZVveTz<)euMPu+YIJ1Kk}i@JtDiBw5PlHhi5)Bb zB%8=SC4`LsNSmb48G3GgaC%r0f6cdIr%s<5wH<0zA7;7$N9WQ=ivDeZU8d-B-bHa9 z_`Ws?LIQswFxae2l-hc$mD`hB84G?ORf1fk#B$*;k!}h1Clhx*&Jc)vv%2t}qe?Mu z^U32I_AXzD?E^TyfVeX?NtXk1oW>C~%{s4wKLNAU4=~-IkChfm8pUnIu)=7o7MkBb za67K`_V+`p$sOJDo8qd~%&W?o;(ioE!vM4WF-rid{GA=jfPervGWc(35XCU}tM3rz z)7Ok#oTC%@=x~r^GBS}-6ZE|}__i_%BmL|_d`&-#{{I8dF-%QOd$^1X>hFAgp3tig zIQGnWZ~vs?{R8{0jDrH1SE<{>Fvo4y?P2Yn|8(;0-V0c&{xV)Oa39#&`!-1-{rmN9 zSsOIXT}wj~N}4tT7@*K3BWC;UH>c4`tHbR{ zNP(=FuT$dpi-d(D0n%*R^8A1eXPNDfW{64KUj?qA0USPqrJTH-MWhs@${%5aHyjv( z-Ge^MbWE?`qk^8btwPY5%dyfKocAZ#{%rn<%xt)nTg`^dHMRCjnZQ?}P00(h0;-0b z9AYb=9498;%kewQpR{4+=KhQ&1(Xam4RNDZ^@Mz`>0x0obCtRw$=^uffZVkbaPD+R z#5-WXm5(k!nHp!y3nuAj>Cqhzs)~Zs3i%UhW|Sh)*%Attx5MULv4J%Hohl!%-0P*F^9A2GzSU+N=$lY#x_ufn!1z)TYoyB_d1fNEr#oj_rwM2 z14V(#`j&>5pO0`LXVppkqTn>9iRD!(ud-0*=NoqqQ(odmPtmf9G#LU$W^LOU0?LwD zcSVQ3ysefSOL-j^OggM3tYkUn61@1KJ)k_q$^3RmYE?ZaIa^NK5o(8rWsnp+Y-fP3 zhE8pXOb-W7m}W`Gx6+l+1vZdp~oi7Hr8>!HqzS*DTW5j0MG%EUQ4fk?l`-ZQnuiiV}xB}^foU8jA7O&wY$-$ zirmXmO~*me>y$cCUmxsbE2h)Uy}k{G#)@P=a)IZ!{Lr~Bv#IJb}|G4&MbM_ zksdFBlo0|TH=s>da>3~%GnV~Kc1<4f!5}Y?0XnRv-CqIETI`)t1sEF-I4Jx*$$3f6 zq{u4@scY2;#g(X^t#_poDQE1EankHL&BZ#f&C*dk2YMKG%e;vzkO}Y|mrS!2{z&;^ zEIUl-4`HfWJJ`WzkmOn0aLx9aQ_98!=dgQDT7vCzGs9D>4sh7aoY3*I`aef$ZDCLf zF(zwoqf`#yk!%m%cgC6Cxy7lQ`sXWk>QO~;22v{*3Oz?k>(|_zI5k80`uaiu@Sh$R zLPBuQKRpfHRw}c_YwGhmdM;Bu|Ld_YLoiz?i{MnI&cyGu$W zhVJeTX&ibe>24UhI|QUf9lE<4h7f6K=|(Am@94ev_x(N3JTT`y@7{auz4lss(Wd(`9VallHPym?G22 zO3mxF*x5N;#$JmTWqB=hdSJXY4P*r4xL&VbJD;u7W@Oka&>HZ7`X$WX;PqVfGn8%6 zS(RJM<3!j>ZEk&WtS54Rq+BbbL!hm3hy;F5+D8wSDLdSQ;2pd4^BR}59ej*vt1uI2AV8-D?~*@9wfkYuXV#dPZxVNMUu|Bb>eBPbHOwOh>1I&WJ39 z&VXkQmGEr*p`eIopOKMa+hBOp3D@%&*iu%7}9vzuP7xv zqeIR$GagD1uG#O}F>$0NK|ht&cA4fo=I)iLu!J@@0*J}56khl=I{i?f<5fZzd4r+Q ze_qM*l0Pc_BV%Q%}n%l&2l%_WoA_^J5nwnu|l$(m&h(`hV0GZyaho)l^K~LFP7Y04>1%XQFVU|GS zz>Jo}lv8j_63`N`)-=stNDIdf$1|Soud`n$iaBgWo!-X=MvFj|-pW^M9?}^SsIqMC zV3`KpVQjPvaMh{{>=O!Qpw;3U*dk0UrQNu(OCV$&bW@>F-db2+APNiX=ojieW52jX zRCa{&VfphgRPd4tHYc`MFmGQjRK|0IB#pOTd9CzzzK5^Bb!}fi7;8D}y&NWV9f!Ym zv-SQ^BOQ5WLai;M6GoQX2$RR>X={!m#PGe4#fHDBTd+b=>Z)d z5b(Z{Phu|el)z(|$|Ix5QB#PVk_ZJ$ynRcom;%7PF%z%V0bpTh*pmB$-$@H5Ha54A z&}6{%u|;5DK8=Ixq#(I7MR^_iU_%W%(rjZgT`X9Lq*uyLvFN$t*D0k!-B1l&B1d-N zL09C;L(yY+-G3vN&H*vkl(_S##r^%vWv5LFFd7Vr9#IUuDyBwyN0Rck{i19L6KKzF z`@sD;zy#;T)DKyn!s~!>jE(8j-I}4n?*iX?*z#o0rSYhVET%S&+%qsi5j2ETv?LFy zDT)uX{#8<=WXGb6b|2sK%0rsx;hHkSsGO?NR?AnOZ}(14tZVdk&h}7A;j-i@EzsvD zo%d9(1Bi>pL}MTvDGL%57rZ(xYaImE9yiRG=dmYF_=Tz>O}R7)kii(&x5OK+xj0jv zxg+P`CCSv2A5`teq{|+*f-!B^$3H{bsQdSg#u8rVGVA)DwNpruT2dr7Aa!8sur@dL z*Wx8iOiVj`TfFQJ`$kM$gZN@zgF=9B%pImy#K;|!O-$9XDt%K*!DwLdW9DX&LW`xB z86KC^-&!{(gAuIOL{i_|CrWM|_vN{JZxT=zUtNKe$6^W41%Ux!hGPl? z`Yb3pq8o(eARGqvv+bjuM$tr^1{&y$Xc2Z6_R&@-z%2iq+h(&Oj79=X)m?UKCG6bTz3{H4W>l0ZxoU(JpL5%wl6&?=QuZnR~SWixmO_C#^?MfS}9?3oqM;B~S(ka+Sy3b<0^ z9!_@Pm46$$N-66q9I-+!TD&Sez}!Wyqfk^c`g)Hz_k7&`Um=U)k!AI%JTGG$8LpnM;+J1g?#+m<5G z?<64wW>M{dt5aJE*8v4sRk< z5`YgV=8wavoKgY584V7LJ0EiuI!7EiG?x;fi7en$T!dNF5$7mNGc%|1f609aNFuj; zYk?pBArnuBE6paDL0!hn_9wVO7YD54MkV#{CGr2mKq9bn_pHUibH}xA&VO|G%HjOM zs8ij{j2dW)D^}>!pqlqeB-cwH>7~|^YBpxnY@wL@L=Sq$4%b(Y$;Pzk3M53&pdE7} zvoNQlJFIZZ5P%kf)*jeZR8!v&xE!n5Ye764ixg=8a#~18g~JI_CchJ)Nfl}4eWw;G zYXl|Eq;PU6q{%U&YY%O6i>;=k$Ns`8{K(doPux)-EBXSPN7HOOU-YGx7TT`(sjLp) z*H=V>c-hjdVT1nND;KmfcsMUSep8dt9}0gpnpN+~+>RAg+M&Cr{$OrhIXG@i>Bw&0 zBIwRM6(P6G$AkyT3D-+5%Vcy_)-Qu*qq^(M_a9FJMv~V+dk^%3*N+we zA8IoboCOr@??c$fdK&@zn{dr2NY3_!!Nn~_%LjFeNFDpJt6#Umf<_k;axdeHST5QnZB5R+rJ5iz2`|=GGi%^9flp9u8XzDv)olSVE|xl zWi?Ugqe&nHnglR|@;=}Ce&XBaNeq`}%#u(*27<1YW%AH0|)6t3_GcY-m%cHl?TE}(@3Qg~q33@eKhgt05mHBTz8S`y6n|<@ zO?cm6NI@o6@47OlD+s$3&RuMbw_4UOTNRXaiqwZOqW`kkYcV*2l8)a|?D0k07gMT! z-;-Tn%C`q+;gu3fw#Dz>r?FYdVN;tw{SXBa1HEA9QrW@AX{G7KIK&2DELvpy@0Eb8 zP0j?_l)(;yduxzwR?dfa4(1_JiITG81dbF zrHQfY$iP?AhJ)~}pu5@Ss3KH^p_-t|Jck4DVUuHdThq(2>*(UBPlPm~Or9F@^>)q2 zM1p;TV;Q&uB1QHH<$k>J#tH4a8(G+z6!?*}LTK4JBvzhwp{2LaYZa6hDP+aNwuEe_ zA!e+&{hGb54H3Cq2Ew5J-pvQ*QVl~G!482f*@P_i=@V%#-`BFPs!W+zY}@B*0@~)l>kl+g#|dih|hjmpyC7 zF<}z8=EYE~2)fh;mr@2NhAgeED1^nR=qwu-pNvm7Nxw2b^pzEgk+qHO|Nb(Sw>fjR{ zfu@d)EBsnu6RJ<%wBhk9g&-CbfOLT;k7|sJWYA+P+#i(_#TXWmTb$-1V6$rInoZ%h zHI((`RsT|dwF>64ESv22OO}inCktJ>x%jY{^89wm=oMkd5MI71` z)X(_ec&HW|mKUqbdcRYJO^?W0M+7Og@x^|R*~U$5paqqo!Gn4(UFyVQFL`b%S&U#Ul&+VPOSGU+H8%;>;dOHruCq!m2_lFLLaJXGCWVjkY!4Y< zasfTch&Eug!#$l12#NIW<+Vm90B9EtO$di#3)alX6_* zutL#irmsx`?f0m=U(J+TJ`6QIzfDQ>dB|B1Ux1XfSTpEGC}XmsN1uHXq*A2z3HmDiQCj2d`6FhX(3%=EJQg z7UOyAUpdc0Kgtrky888&IU^?AB~D4`mv}gijApnNS_UIC!G)!NL0{xc9)AABT^|NT zSAUNgnm+oidVJ1OrVKPCw9QYl1bmuc{JzK^<_Wr@Cc#oM?y*Y$cMAV*215)KvC41N z{$}mzE&!Ngi6P{`hyb>LIRE!rc2nRy}AZ2}IAbQ`XEP5d7}V}+X)re#{zabd*rhJH+d zkSsLPq`K^J_}!3(N%IU&P=a4h?fzUkUvniRg?<|Wg% zkt1^!NdU}?#@@H*vsJZ!*w_F(;p1wXn-z*p%Z)j-E7KO6!ARu%PBaB@pwP=FJdh-} zB0-&%fTFdMT0jwbQfy(0D&1UYDj0d^d&`Z{9?MOs=k1e9NQD4jQ$}fgk=7{>w54L=ADyq%*U61^KzQ2DI7CS$Kn-zpS=U_t> zs0_sk{gF@Q>*rf}tr18^qDL}|P9K18@H?7_Ku!A{Bsw}I2_>J%TZ^WTsHTx!j~lzQ zw=s7cLl#9of|QbiPMj-Rvj)OLZ)w35mjxxR<&-AUQWAmpRnFD;7u1tVu?)i}oc|11 z9CdmS52;fX>*NnLh-%O@$l2jgef#2(kodBurY=$8ZPurm5`3-2=&lK22 z0!mVgq2H7u4_7=OGVEmi59b)f)2N^4(6wUpxb#4sr>QCo`-U^nQ#Ludq2bKWGWd|M z&T+o8a`vc^?7n_&!}*j}jhiV^P}HGW{b>@O+1WUg=HcO6(t~uAX#EdaY|f7NLMxE} ze=?Wf9?JvSSG=Qlef~_IKD+>ib7Mb@t~oA-5#Qn=Q-sK7o*eh9$kd1?`gTOGx@&gI zp@+~iN-3pj&`7dDFZ@M@3QbwLxP(T});aMlwm`9jbX1n(s2weQwdVx98=8#-8yX}m z$d$+II&2C>E?^QW3mW%ej#V3yd4xOVfT!zzDkf+v_~9^f^ItB zLRLU_rD@oZRx4lmy4$sOZg>Sj9wxI&z{&CUg&qhn}46|u^ zuPXJWTZ>cmK`O)JNsjhNY+;|5NS0pobtjX775tl2a=&Vlh(!rpk;uKLhHAWMB(|{Z z?B)@_d8I}rC^1)2r2DC%|K|)fB47w*xfSu+{q_FVw-I2`uU`w-dN)=eU!E!b9YmdY z+LmM~m+28B&@0R?K;~;iwU)g;;yS|O=x;KmE%;}y(M@;B0 zTCQ%-EYV4`dBdIEHT>16H;Ia+@VvfPn@THd{kD0IY^MSuGH>C22HK63{{;V;>=F41 zHXLD5&xpB6rm|x}f+$TwqE!@7VBI0tp)bcrsq!|puD3roX0eAhAwA|uza!#2{fmI< zXSy_H1q@_#d2|Xi590(=lA>#sSI4>UX)AmCtw_>B4i&z0>@%fsq~zz)X^N<^F8BRh zem{r}ZQ*RqPM(%zVzSA~`+}p)w12o?R#z9R4+^zX>fK;gr7Sjt;bW64C~rZCrM*ky zP|W|xT2tK%eHoMe>D3-)?DZyD&HHijLF9h;nt4*KI5}%{NV;ihl@*X62Cpu~J1n-R zBE7)Y{&HhWhyvcYOPXw~vHs=CU4i^dF3+$u!b14!>Pq9w;s+5yi3+V(>H9Qz%3E!G z=}P!RzoWw$OI_nzZs~6QlQHU44<1Q$<+;QJWefEO&;9*jEW8A`eGCji{t=4*2~-j^ zXPzK{%DBG1IKOhbJwlufho{<)z3%;l_?8}305SGt!A4wNAqRw+x?z}33NI8+8K74w zH7q^wasTbP#d`q40MZl>D6L38PrjL|@U!Z7{t-MnEibM==yMVAqa`kzn*Qt`tW(W9 z6#$U0$8PS6K6b7szs0UxLPA1mWxzD{+4zO<-CGT6QFR|{YUbABn$FtHfVBDvh#WeKAYVYJX;etI%u?Kn6lkp z`2PH%>k;GUP=p2|rX#N0M&UFWrgVx@>0*rq@!`DV&lhWJ>Mch}D!Zt%=Gz$0(Ic&! zy*DT_o<$HWc;s5LE3zhA+j__G*i05#hRZBTfY;d+J2i^**;5q<1pGX+YHHBRtnJ5j z{XbXA&VBzTLj5+EnWaW0gb^#eic<#1`G0r933I^wJm)tSVnS0Q%{nT3YyW&#Bvg(R z#bcj~7z^L13C*0#&L-lFjqvJZ)w1p0Sv155vdQ|Q?+WccDYirbtU*FyZMR7`bA8T8 zk|9ZtS4dS8bppqMC~H;CWl@vMXB?Dpx!^(k=Va7O)~{|zkiZzAuje9UQgl#>q9_RT z?0G`cw}!G!exJZS=6c3OmrITrMaeULBcZ%XX;}u_e2T%*#!KA+s{e!9PG1ZtIl!>x1*8sWeTU?%}OR~VuRify5K$*2tINmY4QAfTd z$M|gx?e{99p4xou@ZZ(sSZWl0$zhS$T*AVMVA7jTx@n)5aVSl&O^v;RMOn1?gwRnXoY^cC0T4CnL zv@)uyD65NX_y?7B1grxc4(wD)O1g66l5hPu&7Fg~G`e4?WAHvQ(tslLvdDUuHkn`$ z^!PWR2oz;|hL82#_=vA8&7Yy5xJdz~=@$;LZvF&uRWYK?$K$5tx+2ssgJ~(>j6=fu z;*Pa)3Wl!yv4NVq*vW9{C*Vx$?vA6H%OFjg;{nyajwVa-W|z|@(K$v0f04`)nT+oH z@UYxP@8g8999r>vhal5Yy5o!>QRL!vg#6&y8E&W4&H9vt#Yez0g4>|Om(cI}q^OQ< z=&T>aFw4H?D?B#u_|brhL36a)XA7mV(nxg}XQ5KM?&NH9zb;NCZgz26(#A_%bZkCl z+;gj0%#A0N;4>pOWl*wp-RRzc!RLhNYzO&4VNItf{iRoFXSRF?%}$gs2mkVjEuAD} zUV;B+1VsJ_XMu6)(8tnH4GTl7c=Hh}M10|9 zmWg(?J*b-Xm`r5P^K->UmVT%$#R()khnvDb_9=1E=WgddU$Q4`q}k(9O*`XC>JLy= zus59JGjg;!=bbX7D}1ga9h&qC?Ut<2sEWl99MujQ%$c%fL5O96a8&?y!4nFF-A#cv zNODXz3!OfK9TnJj!f(ynh+fFcF+&3=-oRrL_~H!XG2o(59>LzhT(6lnr`OZoQMI(p z-h5bXG0V0zeS$*aG@`=t=eMu2guR1D&jj7;^S1Afby5rx3IuziXWwx13x}MxVVv58 zOwk1R`uW`q%Tt*{*0@at?&#*M!wAXwYJKkYl+w`$ZherGqK0s_K0Y&J8BJ$ZUGCvd z5zr$NpOKU{;=lPh281k()gx|9Vo`QYw?Aj3NE_{qZg$(;TfF!Q=kvU+o5PIv#{kefA8p6k5M6~NJhQ4&spx_N1injTe64K)jqNdVRnwo>pHU{Ry?=?olE_G-cF z^4R^g$wbPhfs{qX&wVyrB0b(BlI_Lu4x|0~6uYjf%PWD*PmM}%)!-~3Orf)8xNkS#p9t?C zoD^*cfJ_n-@=bl;ezmOBVW5Zy8=y=pWC6LHmQl+#Z5KdsxLPTr9JH$)C_Hnjg^-jt z=`8}hiH`i!l_e(((TuYt+8i0M3O^(P2s8|bPlvq#R-m;;z)5ieXatLO>fn`J6W2oZ`M%(kOAs%&a~Fxrwq4a5pY8Y3QV zLsePMvu9l%F3(!XNZzO(OyQZ4*uGBAmtlQoSnT2wUP2PXWrrpwI;?Dq8vl)~uc@Ly zd`O(=r;qCu1G!UY-bB+8-SiK&{cX*n6OqSptg@NB(#K=F*pj*s}34$s`$8g(znf>{ptf#fh2{F zm{xD@0*FxCaVrl~-Vo@|Ec$dr;{7{_bs+#u3{XFmi~oEp{>vT{J0DP>1U9k_8e9pr zM(4#O-%UUN8|zt+(vk?0zm?LYsA@Y1=_n`lNunoKSKG2i#%dGWc6o+2pTG60=sC_bQfRrF3DB+XE5%l6d=g<0L-=DdywViKQsPQu* zhVzg* z7X~ECh)97bq!iF>b39XhizQi8OWzy3F$oYQ(Mwb6EB=0!mBZo+Hb-A}N;)={VqJ|* zL0|q|V?w>$IKn8c!V3fv5k;8=RJ5fe1(4LejPzi-Q*?Lkc51;L;m=DSr>ZT2TItP<+2eo_XD@Zr(|-9apgSE6$yxE(&1*k2IWf^_fz6GTs zpi({e7ge9V!i|vB%UZ~g9MM8OPHGgrI}mFt9l?VX1-zjBNTzn)EIM>uVlJ`?&H~pa zC^rA3>1A>fQCXeO>XhJhU{y`b;p@g{?(0K?5Fi%g%6cbd#FPj|>V5*&YbcakTcb;s zTXs$&7yO+{wfh<- zCmMdNUf6)8)L>nv5DmiQUc_u#bs<0Xy>5e~iR1_VMCb(V9T<)-HIQp`S_j&Z!9RTz z$u(?{vS~zOfk4^uSQ~^I&hP+WC3rf#x~Jjj21r^BQ0L1S$vT(J7q> zL8>&SzPe@*_^ZBo{Xz>}1?8A`Jr9U0|jCIh~)zyuUPjZYl0X!_whR%CLm8*fgPjGWywv$meNNj9+5&mYC)*XQDid~>y$v^;c~K@Q`l1+c3mGaJu}gyGxYW%} z#9>rCF!QfaDcm8KXr(YIa6<19^5v}v)HOSL#6W8iyU}S4i914zDcuf<-l-_91R^XD zk3vgPuWb$46>1f#?JuIOr#17WY}OPW=ycxW47!89VZZYbza8ruZ(Dn)l^JuWNX zk3Re68N%cmv`V#LTCABYnM#1P4iJ?q56BY5&yl^>JYFp~y$@3UA^qRp*|O}v3#$Pu zqeeuvj}Hh8?Z0AhgmNc9QZER_cgP*s27D^@ZT5N@9)F@Zc1lHa=6|(_MLCyCK8|OC ztjQ}BG`~tR1Y^WIB1)warig*cb`i)JLAVD;Njd2X2f9cVgtTk2Z1Gh&%~+KyNAJ!8u9BFZ$UDoqDGkZdVJ^hoeebwF4_BH{+P$H#` z`Q|3C+4Vxr76L%LH~a0)!nnF>GVgyf23Zidqos(J`B8t_xx)YWcv>-U`e5%VxI6jq z$^7nB;0E#SaHP2V+)z&00NnqI{%ynQUW?nG!S|2L_GHWHRgTr|L4s^=VU`AF)B(zw zwO_jmem60HMEeiq^%h3^+wtK^>&2%Mm2!Kvo;hZjRPU1{hbKSF#(vNGT+W-1B~opOX2AqFzeE^XeFMp+gTqp1zBgzF-6gF|pP5rsRFyBau&w+>ec7Ue>z{ruxuJ;tlZooUS)wJ^fExu& zZF4!~LoX)_xQQQWURSWmRg{c~-f!5uLsemeR%=3&RZ7fwY;HjwX}Wy+I#6U9VdGkR zGG%U4UEgn(Ic1SwXo7T>A=2_B}{g1W^5Y~VA zot74NJm_BgT}{j10^zvj)&0sJk*5Rg0^bRH(~+Ho(?g@tf`|Qr&O)~?;}#v$h3|K; z{l>bd$a~_9o_14UnL5a8?!Ix?^)03I&EwqbSED|liJUkx+dAfm31u15N)*pR7Q1hDM?rdO%!Z+Dg{I zKV#_T;+m42j5}FS@XpgS0~k#XiJx;S`}w``TiNHaxfy-i*?4x7AK>LSZ{lTo`HL+b zJ?JI~P~GSvl)e6abvB~@c+t?6{15O~*8Qj2mQ<3>oVsF-cM$TP>DCFYo>4%nygH8; z@&IcolIYmS=&(yI%vq8n4qdt&F=_7LYjc!caHT_u$Ykv^qSy%XE0TjV@FY=T3}uZK z%2B>zTCB);j6FP{jB>8}LE@O|m-)Y0jED|>GwUG7Os%tyn3eh?Jv>7!6KRSvbS2BK z?!R7d0kR6zM*NOUR9Ij#^m!Lj0nz?hb!uRdIw9cxH?Yqg`yGAW6X^NxOuwQE!*N*g zjwuLSFJEkS5|vV@?#6^RA5OOUTvU{6dZuC7>(y9UiL>#4wQ=^0kseCatTPe1=d1SJ z@wDU3wGN0%|8gI#PlQWK>(B~Pnhj5~eHF*zsC6z7L5qu6f5AfZ^K6BwCQ1>W;wiMW zoJ2;k%$TbZvg>xyk2XWe=+t`5QTB7!`*9&w#BH5s!Z1DUYCp#Q`>(Gw>1s6NIED%o z^8+qNdN?$Un)HDk?>pv8=Nx~g!?9i_p0&Uqo-KPh>^=e>8grxRRo)Lfx(!$?xEBp! z`Q-&Z*5Lb2ztaGVu+9)b6So*+*}|gghs|TW;mjNq(%JIVHfz{)68{!ATCVC&#B)oY zM_=sh@%mExdL;~!tzQ-m&Iy;MrAr>hA~ZC{fNe|JhV zBHdW1!T%r@;Hz0_z)W;|;?;FsW_)@Z_F}Qk3(gxUTdtOGipu{F8#gEag93^mFk>}B zh#b1Af)5PwLkiT2LUl)j2)(Gfs4XvDGgd*{LJ@!2$-I?{tNV-)PjMjWn_Xg07sn7`p)|A7HoED|&aJ#+*5&;gSq@DMxLnI^u%JP0M5_UPpbDTvp zT}xF0`PA$5iurVVzp^Y*Pfj(|6Nh*IGWNaCnC|i?jVN5~@WBr(9i7T1&aV8%vRLgo z_WJ9ZJ6k6k^H24e^s!`BE6q`PJH=A1t?g{unPcT@I?Y~MS?=uaBosq7ilH(M_AQ?r zxnjjxPn`M#C`klEsv2&*Ox9~cVCS#=TD(uEaQJo~&F&Y*cBw+U>FbBAzl7>u@vr_J zuC@MkFm~d1+Hno+1pIg#a9nCYeB46ubnX?nn=^ENVL)#7r%v2&F5t&ehOJ`@-)K5I z!Y{ckRncqZKtP7{XQJr!=13}V$~otkySKm09smu?)`LsI#=iFtzu(sZV%>ZW`tTp3 zex_c*S{1s)jn^lueYI8rRfi({t+A=8f99WdyJ~FUFaUuFN4+*LG%6+7+S(QLIRI3{ zs7e=&+Z(?FD+>O{_CdioZ?w|>kDG}h-sx;5m!ln&;qm@3ir9UP7RZsuWUbvQhNkT4)F; z^EW+vWpKO&bV|D$*=zSHBI>iUvih4G$s7$D-><0n*%0rTCj-joqSq_ZLV0rb@uz-& z&bnv)AIR4%&yG+l5C5u12#`r)Xh<}e(wi}BRLxcFeDU^3q<=$UGZ$lXyMNvBf{m{2#j}tG88VOV0k$pZM;{;=2DOtxZMXZ`VhqakTp;N-_3Tv(=|IhIWc#2je#vU&MYsx4P3V8I4(E39xb>m zxwXuD{5d?o@Y^b_q>csqJNSbu-~fSnvFY^Wi`ehI8jBB<6x&DZGyvpj-%6M_4RsfE zyS&6$&b;sJT=D9!Q*lwyzl+jg_9m)Y!mHnE+L`O z@$pUf81%nY(>jdk@0fCz3~`o6qqmz2S&S+HR1NJXqViyI)(r>0ks2TfrwlV)elcsQ zcB7(Ru)E!&?cktOQ!jY41y_&QenC}s<(i8?2l{c-o@@XmzQQ1!lUZ+coB)HJ=lN_M>?Nt!ipz_K zhcP2%9@(P%|7 ztrN@mEdJpj0UrL|>B;xA2K@hV0VI8LqA%STie1>@L)isov?&zAK4dVUwGwKnQ|hC-Dtj=5Bca>rgqfv%J(J1%vk z1W+`y>xkG2J#8`^K(DAFS0#%`go(H=^0C+bGIEArG83Q!Wa#?ufXCclSX&h0tEr|qd# zKu`b*_RfpBs@mP}M$vol#Pgt0A8k|w!?#%XTV<|Kp3mFwIAaa6}^lY{MU`_ z{zdTb1wsv>N7mNjq~eCKs+t&lBLFqX_uzaBAE{4&N0&j9yib!H<^Z>n`JT!)l^U84pxB7?c1<}fAm_5sKnr_{|WA?EB-rw zvCPpqdnu{# zeZ;yBCiINVc&OC4VqE|`Sz-GX)4Bi;XEz{B#b4!p^2O|)Jn&~Rb&JFBdA9n~o&96P zS}l7x&R5fx169&pe032;qsHT$M8AsIQF9i8SnnT+F%H-t1OY?nSgrSTREg)E*PW41 zk2_uFfV?WbJfQh?`sK}oPYaNhj)LwW2#xR8Cd=ZOQe1o@(%CxFb=QV7()!Qb_vV|_ zMyrVl)Z#9>&*TgBw{Onz5rDNjwV%7YVZro&nJoPE|4L-WcY3V(cvSFgqE6faTUM#c z$nJOC6trtUltpXPT)CCKA+PAm`u6q&ClfGJoWHo=U@OA7>Jb^x6<4QZU?ilDDH=Ih zrxvy$T6k-rSyp(E<}5^WZ02JN=0t3GDV*40n#tvu20A!IlUNoiV~al@8Txj}wVOl9 zU)y|8dnI7k#NETAFbxrTD6wGutgzU-k}lWrm34MM9qyfPMoQF>ggwPF_->Oyt+?lo z_lrTTD+|4a#Wz+Thc>wy&XU?OP|-XY5>EMhg79c;v)n^{_V3aW*<$qN{R|o z)uHIMwJj*;&uu{vZmYts=&i=QZce--$ysg5Q?FGLMzdtOvBs<@r)xO%Nz-N@73(EIaEpddc$4sd^Ma8YKqWq4@ZPMTnhj=#LLv`}Ml zpX)klTp1rv&gXn^1;OrcjuKvT8M1FQ4Ll!6#aIU9D^2tRiU0P|yW{^BF|lg4%%~F( zW!JLuR26?T6XLQxwh4SfaG6Tj-Dj(BsrEI!f}bNMQi&t7a&u`*2t<>al~I%DU}RLC zAQ#?mSQ>>m`M#=rO;>@h+i=&=AbyXu!|~Z z;54#_M<`YFZ$r`2j*}bduCkf>h+k!ii38fN>$+?o{p*QPD{#v~2s28wAr6{D)%Na2 zVqo3!lev+I*{^#Owe?LHArcs$c*!vnK9uTI%*@p#*fNB6m(pkUarT$yyyE2Hk38J} z{>`6W2DV|oOeIt(`2{LfT%%9mIIuTzg$u7wwu?I-zl z3>nGdfjuFoo8Z1i$HyD>$MC`pFoM|QdE{*cpeFEodGPe%@zf2_k_C47y8*S%1+Qz9 zD%$|x4*zXlJD>I(dkFN-T7cj8WGJ5;D2VEVEqsE+m4$?}^RvMhn+*B8CN=tdM=KO- zcfXsSEws430#49RdcGjHpj__@l5tJ7142Y(7uh*EGU$rCDU1#))%h@^MjUjrRli>%1-b8+Mk;2@A)ws9;QjY; zW|zDud~5v@wplcmc|E&48+O?I{tp()Up(bZ`43K^J|P`3IY2IC)742!D@9p7S-)WK=lQ%@VafoC5(Ldw#t!^NSC8>i&KbOsbYpE_0Zam zDUkq0h^o+LM=50yLjIpgq&q$-d?nR!1Q zry!pahMkXZSOjh46Z?pNoU=Jlu&Kp*A0N~&V+(F>zdXWzrKgSV%(I`}rQBvhiQn3v@Fvty?#5IVi1Acc zcew9Ai7)qcQq9+u9_7-SF|#{7IX?v=+-1JDSZ;)sq$qxFAd7rS4gT}T=Wi=vt|}nj z?2fqWCTC35f9|tco!>l1=jCdU_217`RHmBT_rIJ3?I|2~b;*cKwl>&@=&k=740p$~ z|4nF<(i)kFU$iU_&lH{9c$JMV330UQ4AGrN-+J5aG1yHIZPsv(&E_2)o>&1!bA6J}7v-nf_(uVvhFz*n6wCIMyv{ zGy#IUOXE&(cY?bUf(3%R6SQ%6cXxM9a1ZWIa0%{iUuCVc_qWeKI2VTt=<0{3tLv>< zKKjlTz`ctH}Al698ukpZjw4Vz4n44XFZfOW@VR+IuDm~ zmPkMO%$h$lxtwA~Q7gI3ueR%4Wg3}X^gtCneF@k>)n8Ju3)M;=ag_1F*572L`9YKz z;mqkkpP($7t)7HO6+$!bMBgvCqJiMWrVip6R%MlMuz$3h5`f{XcLfQRTRvQi>*>TE z&-SmEvU*w?B9rT#5$mrmoq&Y=W34Ar@3*_tug7cc;lSiJ!1|;buL{%?m8#Tel7|y@SaHqIR>5XYa!O;>64G zcWdR0kzK~8w6iDvm(dx7==dS1-AhX*>$I#a-9^U45sfbzDpwXgo96^JqL0oODzZz_ z-p~5WD@<>VUab#rUfE}@XSy~kt@~KwYR%Rw!$Mw1D*%;G!odL^a>qFYaN;Mdi6gzV z$_Dc*s*bx~b#4eP5Xqfm|S2np zQh#k7RnZlwH8k2%j<2!roCEe4|Vg z+u<)f2){>?*D0tm3XozCRp>+gE#P#^D2_0xqEwZXnw8mibqMg)$6Fjx5zSlaHu@PS zCl%jkO?0KIA|htxZmF@f@v4}cRB+m?fnkhVOBcTzSf9|4#+X3~Ud3a$O5tCiI`#nd z^f*rP4Pi+a>hgt3s-&oV4w?_DY>tQ-0>NkLV&s|zQ;1ht!je_3bHX1!XerZ=&Qz!m zQN=mAIQbYWWmcwROssSfU=W%RZe~V zRVC5sNB)~xRS@_2F$b|rV?E&-BDJ3Ss@=%mm=z#Svw3kfK@3)fh`Q_87qGnt*(MU7 zu1`E%;b0R9J%?s@?m2?D_PsaLq94}1cE7lu`#x1av^3`fo%?GKRWPKtQHIdC;WXmpk(@a35KTE#U@hH9z9lP?&VaPNGReAV+V zlVYn{hst%UFEsF^QkxU9GJ9sM=p|@P`=4Uyg7!b9&{8Z<^yLES;-gpxYed34S~+N> z=s|EWPA?TNod!|#`9@Nt)!E_JlVs;uAIAE(_}j%JU?MLV#q0!4bR#is2VPv=LO7Z^ z#3B$o4k%4v5=xaNlG)_@@CZfKQ7Y3%m|z_|(v+4EAZHbaj?J0v$Re6??`e+$lD1Lo zOHqYRPDPs2Q;HNslJ8|;41htki183C7V7xoP~a3wJF1w@tSzG*ULqQy`5^YG3$);2T~ zpf!D>P4K(gFUI8)3dNG~siDCtllz)c^i(|GNY|G4E*q$7o8&7LRmNNK`yvLO%c!y+ zA_br#Y>Lrfl4UAvE{aNFCME1x8sp#a)@nr5kpk^qeRWzw3Q#^aFUFd`7S{E*+<`pd z`iM)%)mOp$NzvzHNg;Q6St=?<-5sH48%wvLw}+L^_CN1~_a9u>wgRyhWIn!x8S?>| zU5bVI0YLn_4}l4^^`t1!-wSw2)FwsU<(lrP#*n@XCTUbpx4*|Kn~!zPraZ~r+%m&k z*X$qM*`~}ADz%$0M|~kNWhqTe_x~LJ1mobXzfB$25b|jOXL8HnbxQ*@NEq7o7Lfrb z=Uo>tT#voH-SK??PmRh(O}Gn9!-*=)25H%zB~b!G-kjAe<+D#rf%MNSfWA+mDfLzvL&*Gy|58? zFAXC2!dw+9o59U!Z?L^+->;a}N4OhhwbXQR%75pOw6Z> z7mrTeC-;+fzWt1)xx|Kj4^uCphPen=v=gmbMPaRjqPiV=-p8lfA>6P1w63~7s_+SU zi4?Q=9BE^84?4bGb3C>WL)Q}-VNsBBNp<$y5}Xy9k>$~71xOG_=YH?3!hf%D%~+e- zUD6`_Ii<@`(AgTN_)XrKn6uxLAu#N$A*9k*YSl8=50Y9kGyJvEGu^ zy(zr>s6Y}X+7&~!eeKjJaPNuV#mdVcQ6Hp|`-yZIZO1VpkfpL9P$ZYSgX6iYczO+* zs<(iFJ!pI!*?ok^YMW%v*BT%IMTZiU@$FT>9Cv~@rPq2ZV>sEF=K4-Y4DhaNGTUBS zVf=V*tnN(-W-5CC$dGz-C)VHA?)Z;eB;AwmH5O~kw{xS|ulC3IW`%b$>L>Q9T2D=k zi~{t4?M;#I?b*=l#J9V9@I<1jxcsR`wEai@{ySz*cOgfU3DWWY`>eNbBKPN2ov+>~ zo?aK?IA{Tq&i+D$ccDltQH>Z1+`guQ+vx7@Kcnx|qC#bMW3^|UU0ets!A?%sv5-;0 zR^I6>p1dzJMYWc9HtMTxI3r1!USoFEWE6CZECXuaz$VK@Ahq|r^=XntE^D#Rhtm)yIm-YPimW^j#2-+7|bP=b`P~irhoQNl=X0*8qnr3*h3Tw*|j&%FJSFdi5_7&g@ zP3OpCryM7N^(+d2)Bnyz`DN?+!LuP4z7E?}@Q8SEs7oV!Jg09j(h`riCX@C7)E^sB zb;^i6mMQ8{&)RLENcvrnJs@YFXU%7Z_~3klgfYboEL z4w%a8+E1+bZqeRICfzGan;*MLy}YNn{nSF|-6+%FakaJInT%!iKdoJzclYMI6(q&H zGtF{?{;0kx?V-&F$kaU=c8pK`yqVWq$ZFZy3P<_w#(g!)Hni)&j*rxFQ)zoey`Om( zVy#Ua4(K$I1HtKQO4ikvj*G@>BIj<|Laeu|Fye=Wi)(-vr)(_&JEdD8J$)JH@vm{S3BulW&C3$*HVQ1)3A zczL?js#YK0!LOr~B&_`UAgDP_R=d60X-rsoA*^HQbMW=UWgu)JC{=o~&5cd(WtgkQ z`$XbrYpdH_x$e;AuIbjreHFZG8>RVW$yYX_@l7HwK&5`r>2;_;z1(qI9%DtdhuP>s za|Fe+a&>LIaKejoz3o=3$?Es;SC{pE&5;RST~*Ij!f*u^Z$t%w8%)NZ=LZeV&BSM= zAdHifPGoTT_ME7;m{;}=X{Kw>`L8A`2CcRj0I0Ql zui#pFV*sj12zA;&@Bk{{4(f@q<~0zn?-uYanwsie4IJUIKX@3;azUSCrc#Z{z+vey zMU2N!6CYE`7dBI6k5VHbLts%t=w`#F2Ze|Z*JkrtfpV7G5``r1#3c)TY2jg>4N4Vam^YWRM~%&czQmUzCp-;TQL;Unx8 z=Gl5{w~*;FEt6icS_A(TcYl;JJmk)w7W+WJnDoafCo4#I&;I;dWa6C_2`t?xpE*nD z7mDlR*vMuYEZGEj@f!SM(3nL0#Rc!5cTB@9%Ti{K-v`p+WC|O!7#ygAd$!!dZky1R zF{ewS&;W^`lau}i@dgP@)uM*n1n&}N^N;4SCbYt+N~KPdx;ELagEuHfH;!)&=52S% z>YA%SSzPDk>ut;sTn#;j&u&)eVe~+17O$_lNPl$0a1# zorhUbC8Dk5*w1hrH{`|MC?Z~WDsesffWseoY5TiD*J&yce6?)({(io>qc_zwm$v@5!0zdp$c*!;2x}QbM!LO)to;AIg zUAKgMDI6a2y-~lL&lbKq(j^X~eWk|P*KmGhwP`=$RIk<@3&ha{5%3VzPlUiXOue3SM;%^$_0rsIr%j}%{BF;!eIfnE(m^2NxOPp=# zNTr2Y8ezjRUpDwAkrnFEic{Y)4JpwXsuizpv#N^`k?%r;-h{OIXwc#t8tw#3YHSUT z&L%l0=OpCidU7r%ATb)Fitf=OyM8~N`w)a+EoXaVyxidC)C^+;iP!6l=>LBEld#Jd zoC&w_E8OZRw))O&nlNEnx$g-#E|o@Chm9!~{%vdlxn$RnYK$h^uP-&Zk*1yJ6RDol zv<07hdW+zipRY}zk&pGwDx}NM$8}l5X;pc-Ys~rT75V*}cxKGa!dbDa^%t9V-yNN; zi)%{?%{*dnB>rU44D>{?%3oZP#og&Lw~Ml99M@=+$WM&r6`#>aP^A%~FfUZI{5+iK zY=>Nl83^{(!JI1joZ68Cndnk57Xuk7Oh<^7NAnIOLtEBp4~Qz%&a2QR{_1DZQtZG7 zp->}=7Abh{Bw~y9iUtd2PYJy!4+eK{cE)=@ow(SYd|x2Ey$`<1jRs${5H76EzotM& z#ZD=Ayx!P?+`&_UIIrU=9i^&2{`4UHxF|~30J@e}!B>hc=RL(jMMna0y$_E3pda8< z+)-%fv$fvOwjKn4V(5OGOtZ%x_Jsm< zP8XlS*>XiUH&ZJsy{|7Y8ut5{^nBY+@DDv_5tf|k6}t8KK5J`4Krk3}uT`Ak&f2`j zSxb4G>{79D+DhG2Os`oN(4=xe)A83^*&33DK(+_DBJzxVm5$egCQbc9HJ}8-?E=Jm zEDzO!eukAaNM%49Ws#OUZ6ygsekW+!wDONoh9`g0;ARilXO{sw@r!pkmK1v071%Tm z@;s(ki{$uxv(|_tf|2d+CcH)7e$iZAhH-x|=19Fd?c z{U7*|fk3|KbBv)a;lV|MTn;lfSvbm=wlJ8t{gybaG~q#1x-KD-l{Qw>ufUuAs&-kN zC7ioNf%jYC$aLLQ+AzaBG9gJ8E|bbG=m470PEZ?#b1}JMx9j!2#3SE13^b41x?oml zZng0ggQ!RsW95CJd<#PFxI^Hk4)X7*i6LseuF+T35*~Shs8UmGA;_Dt<^OnY~TJ~<`uc;>TggkZrv8N z4~o=^Y)qeb>{aw0C~AkHNyO4+l+@OaElE@k5g0Cnt;CwAjq6h)Ecd?*k+sGgG0xM8 zP&q|0`57y6Y>FjmG13y@_AylSEN?uIG{M? zwsz%m_Ud1WbAF|5!_zRf+jcd+eOyoE@jKR35TGqtYE1?h1o@u-3=kX~9Bcw&8B?`s zhuZ^J>^M4h?@hBC!75E&FNv1bPsH=p>+iZOb*~n#71M7$1~Z+eL#>t@QWMM7?caWW zM?^+)7^pJ_r1l2NKdV>i^xqO7|f zhW7F*tC;@&EtKmx$ZS6%T8g-?cu^OM94h1MT!*Suan&e=J9Yxjv=GExemJrJQtUI&~VOj}C15DNSi~ZG>TQ6QF{zUO& zCc~TM?;vhwnOdbhRN7ms&gj_90QE+RFUpQq$RPjOj|qSy-D@bRQv1i#Y3q;8AY!|N!U;hWM=gLv-P?ZYW7H#mzG1%P z_vfnLtq<4U&oIojFZ)b-H^cd5TtI6N&>G7F@b>8g4&1{TlXvRcTGn9U?rAOSUBD0i zBfMn(lG9MA|ibEMITYx{_NL-`U}WxpbIJdOp!Je~)W7BOt&I=3*NXT)Gh16*m~xce{|Z$RQl+`rA!V1n@~s7DpGucrzM z5viABR=!kz`*OyQojHZ@Il81!xOuyu@=(|RzK;zTmuO?J(sC)5Gv&;U-kJ1-4l+}p zS*%Fho2`(#)`%MdrZ#Z2o*gT~Jqf9jDxFm}5*47GJV+6KOI6H2+j0DJoG!EH!F~kS zo~c^nobdUh*YNFFIn9Un&1+slz~;_nn#~#ARnL8*&)Tcu8Di^s)w+6n#fP`vjI*xw z)7_o>s$w_e2bkxj-bD5Elr+N8>?GGJs2Yn?RWG7zLZ#Ctc;wapNz?P??Q(|i)aWgxa82o6xNGAzGhxMnK5ItNbj2zuvmxZxfS?6R zQ8S}H;)^BwOhk^7*e*P~GW#^95F0c1s7uG2Xxa@l%JHH&$7sIC-qZ|N_H9*a#qWi0 zZ;Mn#$@KSV4Sat%9(6XD)wcCe=Jg``HFd6h!ERT(dJ8F8Z+yB?HtIkpPQ9nobIZc{WDTjS z=L5q1jH%vZ$>6R7OSRkB`uVL(8-@>)&XqVXFCX{*aeegCY7}P%w^pP?e0lZjPHtX# zvfitfdvv$F7b;ZS=H-an)3{5W>6xye{mmTEVPk(OO-*?7Bf3$haP%YNQ@C_v{eSG9c%0Qs^;DK=0Q`H^Dl>DdJd8M1|U|4jMR85I~w zOPH4SM0BuHGo&D!{~G_=x>WO>W9S#Gxpl%fC#KpmL(ks#+caA#MGWFc`4I!E*u>$^ z&`k9OSpybY6%pTe)b8j{VT;0ziGf$)B$b-+3U1bxEw4&~?kd|ID zkHpxCTdlcQzOdH!`gKLaearlwcOpt4UDJLaMe|{#6?bKU#Ejz{BD$#wJv^CybEken z7>2at_I#2Cff329@vuV26J`DNwi&>6L9I%Dq(sxvL^EhNx=K>)`7(NokIJKEeF9i? zfyn&v_Qk`se76Uu>3+@}4uKJ}OoGur>i6QV91|`BLw$tJ*@Gygaq;nsj0wG}KF#Wy ztOiCjYPqV{cAjd~>a*42dbKV)+GdSzQ@&m;bJqaU5TCj zJX`$d$sKLeU-mMQ_h&l)K8Op*#biIM?n}i%t>3x695H$?l4Y7Q2!*4(Zo}Ls zN56c8K_S`^IP)N80(T?00>yhLxiD1|%>kSar?K3gAnQVOTlZ}OlvaVm&~Tiq9-KBG zTU{4IO_Tc#A@2~EwiCK>zO&fYX;4+U(8Wc*;2^>J_1>UU21^jowClLqX+!wV+x?($ zki8Ayn$>xj|LD5Uw=N$?0X{Z-84_u;X zrNd@|e%>w>vTJAdp8YAZJe3>vG^P`yn9E$f+O1~$zQFkyA0aZIH*KM$fFXi%>6;%{ zL<461AmMNNi6#YZT6)Sa#Q+?zgomf-M<8+WG>aS6bO;Rhj z2aYJlVorbj4p9ARMr5UQlp$SZ$jdtwfn=L6*pb*|(3dcdKI}#Vv+;=*lUY#Lc%lQc zAtEmoe~U!SgQt$YaI;@+rHExd*Ir*rXLJglA75I8vnJWjDZ`IAULUvO)I`5n5mSN& zGt1ARa8x{5r-!GJ*9&)MWiC)1K7s21$6ieN`j0B&T_0gqmEUXV`b^v!D0@0(%q`0he7YTesOt+Rl?gCQmp%=d-P3 zmuK{pKd%mnjr=#X(ct=9GXQ{oWh~W4AA*>t4sQW8bLboN+%4DJE+T%z^@+!3+5?0h zoo5{%tP%Fc_UF8BlAi}n1xLCzNWOSqu0K4vbRJ0)(g7PLst5?_@0K}UAC?4NPFO1& zTG7A3_Gh;xI{|5V`%_1_JcF!W66!u!C%H(Cc=I||SwUVEoW^ZElnWOT?Et^7nK4|m zCdQ?s-~~eS9$<6z%dl z$1BJPB;+Z9Mif&d(cWJE8aIUIYK`7utmaym3H7wn+{4Bhnjm&o(Q$&}O2Of}JuihQ z?H2WT1LiRIJqo`1@2Y=C{jR~3m@4U$sQksoME!=E9`vA=M&{H zo0*qXpjN7EJ#Us4Q7|d%WdgHYFgwG0Qz1M;$-O{kK0A~VT+D7gL{oU+Db^8OhuuIG zK~{7tpKit!E@J-O%J0=hdY3Ia zvVSdP%QfCdl>Z`Qp#GbZ2E7acD^|?}&*^*=%ral;mm;^Carr%06#>fyn=b0rX8?+%ANo$h2 zH0+YPMoRGfFAXB>j|FQI=h9D2Z#+MiMA16Esy%P1OoIb+K&Y-PqH~aajrde!@znWa zwlU4$os#@mp)_G5@jW;Nx}t8<&od`(Gqp8aojHJJE2F1*hWlRs(V8UAZ9_T2c2;_JRuX@_cpdz^BeK~#}eG9yTT27S^|n$<7(0HkwoEfK^p#z*s?*Fpy7r; z7EEX`uYKrv`&2fZjS`!aEy1(cnL1p#lEXZ~EJ5@m%mc3yIEjR<&eP47_*860oaC}> zb@cfFkvExr3dD?_%Vi@J?>DgMpq~Ie{g>E~vkD}M1YQ>K`UEP<% zPWRQYd?L$no{rZ@+sk#mS61d)xiRJ}2nAQ6vf`^D3$ z)e@;#3!w1jMR+dP4s#s8PeB+l5 zou>8H72Q?lp(-4Os?((UH(b)UDsW{ucV;y4<1$LE&$aHC*&^b9RQ# z*CT6|u8wZVRkx$x&pW2gD%O;8)lT1@(M89o#wZ|-L&1Tztaa{$b8?fR!j@g;5iG9i z@&S~ZNXhdDR!pdYMBL#H__O{WIY1>a&HeoMb}ElM#e)4Eo=-LN2CSlKMFpBNX+;#$ zGSf0<>;x3jmo@wM6K{8V&--sr)xAI0!mwN}*Y4V*xjGLbuWxQ%#up-4R)H4T=X+|Q zhfHg<{Y($WYHlQjdftHUcuuUIwrKPT?b?;M1w#U#cxsq6Q{B+qcva=n7XLRgeSS{T zes{k#;r)+hRk+?W8Kdj+hhQwkm*Jl`M-RZjHt(Su;m|E+Atq2h&Ib_69|q-eyt(rw z#6QTQ@{wSl4@8&<@BQMfI~FYXjP_WhVC>|yGlhZY+LGuD4ntx~3CWbN1ba|32JWb_Zi1F^(8?3+ zbTf~5M9U*dNOwxavgXwp@?Y*8OE^vaIGwNt%|?(M*URSaZvs?|%&#m0IP+t|m82y` zWbLzhzujj-^ac3pW|D+t@&DZMG(@{DN1;vFQFSfCI&9uY==gvE4R6 zWdiX~IF)64W*E^6byM;KzqR>1w3G#s&d2nYD(MSvEU$o^8SL7T5RvRYUSwn>j56T_ z6^(xX?nDtjBzFVCVEd@jOvx{XTduf-cmfRu8ya-UBMps-G}vJ~mu@}GJGU#gFdMJm zk6I3`&o+iXu3hr=!^f-lZ~*|twdXXw)zAO-FtH!O7WMULP)Bf3R`;1~Twov6;r((0 zcd} zt?9LI&$XSsfE-K3dd>TZt4Ry8Zy*r<7BC(T`R#C)R&tj2dew1!GxN-qPd1reAdf`q z@5X1q8tWqp!r{6P%NqTbV32*ODc$!I{NYP#c=l00o1lqZih%Th?r($D2>YH-J-XGu zT&%Onf~QH=3Qtk~&|W`TlO+mpgk7CSSg5M%@!5Tb|LDkm6QGh~#qh+{?DgUwanMh^Lg zEXWZTkXrH6Jm)Zvc%H|-{Ae9Z-L2Ux$>?4Clta3e%8_TR)LA&iEd!@fb3z3o&-j#R zmt}`wSjKsQxoQPY8y!UjV>44~bt@Vajwy0z%kGlUXqV32vh9~TJ_F$P0=+R}`ck05 zK6^P#ag+zx(4G)xc(~peX4ufY7!vULh5tn0RNqxDF?v9EFErZUoh<+DvN|Fv@-hp+ zvrg}YRt>NDOHsXvT}Qx!YPQ==v^73$!*CrhOm+aGf1y2*oM@BBYcHTLpn7vc?;Pv} zm>T%5b$$CUN~yYgcwgk#Y(OhB>LH_Hp8rX6!T>k*W5xLG@nOGyC&G9XH%)kD7T&Un=a%{d^gwxul5&ZwlXEb8 z(47jw;>ajiDrQz`eiP<>qZVOeAq{)&cc{|t=CH{t*amW?pf>v*P{YS)!4p+F7o`l2 z;HRcDef~c=>gOR?KsDzDDHw;#E-RY2{|_^i&?j@4;k<_6Tk;4MqXCiHbi!7b8tWNO zvg9~7x92R)fK0b%@TV9i(OSO?@*ZXqc+tr)El<#drU>C?-a81pfsK!ng6ET*xy|Lt zB7bJ^iF^wNx?^8v%Q(R4`ZEdOT&WBuGvy&{4yTEtS zFmu0;@`^$H_$xS-%>!9B>Di`rXgmtJ>a}ms+|tscXKxPBrv)I$AnVF>;-UTQHCX>w z`P(5A&~cLSecoYjBK@vq!utWJ+iwtB&S>mRfV|8y*ZwD?%Bb`Lhf=^~)=aw_99LI#(>o zb`Zf3Vs~3JayTuZOhNk??a@u;Ga1sdxwsqtCsTA*mnnld+_cK~%eeYB1brrmCwzO^ zPGoGw^4)ise9#s;-bcC}FEezIl?MgOEY|Klr3i@mE;_wGS8Tp%jia+mo>%l=L4bF2 z>oM008Z0Gu*xwWRB6s0AEUQchOwqXs?2g=C{ZlD=!HB4)lbD5#=4G^ufOu9!8Q9(0T_=a{U zukqdm<%F+FKyA6A)=W{A9y9vRi71u@Iz^+Ab?ImSzkx4`cSh%C*!C%PXG@l9^4nP7 zSQCzZud^Jkp-A}tM{xRd`a=$X0~{=Qb`4)o8TP=8kypg!RRC{S{bU{TiLfc{ zUf+_cCb$OWCg2% z&8(F>diQdYhzr|IXpjPTp2_CM6~g*sVz7mg@vB15M4WK9v1Cwp?Suo=p({D;K`Ot* zHFov$LYTvc%*B_jSQ~6{ZZO@Ki?@<_%?_}+BRMyoNV$XSX*n(9W}UR7yy7l3`2Fm$GFKV@MNW0HuHcd?`gv7^Z#ELp2 zZu~66*@+MY{CxOXe4@`}hlOPJim82Sc+H>rO<}FY5t5s`|jk_IlGP(<(^F`%ylm^hyH(~JeRT9R3 zeMrOmnn|B36kVl5lvoIrEBXVuj^6O?)nCK%;P@a{OSbC@_DVd%IU*vm_9@57>Mx`K z3(Eic&w8#AtoKIXcoRutpvaf7XZd%rDED^XO?HsMa|q*NJZuCCdS&>3%5@5;b_k#& z>B<{orcJmaGG+MMx0*_L&zP@rt;ye-nL8yImPz@Xg=u@n-C%*~KzcO4J~(0Xs@HV3 zglzBI>JrUtI6njAH}R>A*gwXNNcQ;-RuIX5;r`VvKmhmaJb^6AfWJ!vX?*Ys^9MKC znI_o>xXB)a#Nd6tjQRq`{36win{#NxTean-rG=r_9FgTE`EroMp`RP*`GG-gz_Os0 za=3XDYuGiARRX4jo_ta%Oki3A?PIV#ys3XI`X|jY z8Tf8hY>TW`YmsIwe2RZOHZt*!SF`_JQJ{oL3<>1H>>Ia_yvL-OUg)(b@9D_rl|n8t z!_mBs(RM{0l;w7w?!A1FNUqq>EtwetOFzmPnCqW=ic98pwV4yj9i8-DF|iz^5#6z)v9(r9U%gTV+Lj%MllPBL2` z(~5qrRdm_8P%E1X{m>zJXnLpUe-U2b8yv=}mK(vCbb&xwN782;#eH3ZN&c+jgN#`E z88;tJC-yW4M_b^NwUf^S0?stXZmp3k4cQ5rt6+ySMQCBFiP6A2Xg%$)T*WW6k_wty zjraTOB(2CqMibqn5@j6c{3h2Sni0)++ZYO^I%)HhM~y;a#=#g59=1sNzt5W`nYJx zB9|wmiOe~1^%RxZsUyC1EvT3M`~qLUVm^oXavW*A{3clBa*gqiWQl7F{&GmkMmf9* zD!R>(Nl2G0ZAZWwnAL*Y4O7h3px#GfZo3m~8xVZ%>RsT0_&~*RuN&eVCWYrfBsQQ- z)(5EtUvY*}gsOF(_@1dhAk3bLWdG@!R=%Ahip;PK4)*q>XiTv*iJ`DYN{McJU-l2P z#KZfI5Xk7LCjJKpxj)q0Onr;*h$E}|7BBo)-R|h>4pFTGL6r@G&Kr1v$!-C;l1Z9% z?(tgn;%OYABBC9YQn<9k48GwBt01;0T*oqE-2B-*AY_R7Eomj!b>eXt2ov zpqu!x;kJ{Y_?4&P_Tu}eaXc_-xVffos)5xdVWx{aSNmD+JM*`zL$1HQy9rO z22Sg_AF|V*$&T*ai#F6sfe2Z%CQt|G&bH6u7w+9D<uk$T=b(~ z72TYmaeVfuTLUT5(V18T^ASl*$mlNrQ4Nd8fZAHbbSRo~yi%?yX$j0h`V_uobJcXU zqwj#e!u`&h+rR~w7Vh80dzF$-*ZB7(@WjixKe{S@`qxH*H@D1y6xBaK0Q?G(R)j$Q z?~$B4y4`>O&tMuzhW_^`J_`!;FC+tRrCbB3{GX$~0_yj{|2?7-faCtphXeh@|Np7} zv$+4?U%-b!4+xQG!3FTKOhnT=n!=j-yo6{K=t4qxlzo0B481Qh@)7-mT6W``Pl8!E zF;vjStPtyxrKpk6g`Yk~KVNg#jv`0Jjwr`YK_7``S83TGqMOIXtW5>pl9k`I=9W|l#k961IO6-pXdh2y50BFD zyW2@HkS<;``&KE53vD)$o6*k`-ka0taqj+ZtuI(rV;W|H}EIfmtBG$3X>Y@M;35t=d0q&838}uNnZ}=QY(>Q-bEj)tJ+5X&$lNND?uguAQ^BH7HU{6 zY#B&OgV;?H&`|DHU*ilKWL*5PL0%xTkq4K6MGGIrN>U&uQ*MNcXI2@jLIw&=3gU_3 zR`1sLI*h?YQ|BR*Vz_%pKN6#J4g;{LqmwAvB+&2)BS0husK8fZNWAxh4^7Ph7`b5e zWz--(z{uoU4*><`+(b#G+dQlk^t6IuF=;&hCd|_m#`g5u%bABKOe23pTSgM#hWHTjKpRU&!d*bSTr-i&Fo>qW zENzuQA<|I#B9+?oIm3rR9xZ8-rB8U{LcdMYkFz@mKT$mm{h8e#;3(7jdkm2aSsk|{ zSm`Gi7lwvLr;m7ojw%Ns>IKzA91sxY*?#;M!WsFm(fn&Y*5oR7Vv9B@%tgg+F)ChU zVl^QHbbJA{rSA&tBBy;QLUUx};G3Sw7GZ+EC=CzZVF8TaKxmtkkWz;ZBTv;+#vOpD zhERke$qQ>)mP*0ME<=rl>D+a`>Nky=nYU3x9WJ4{ts=@ulPFcj+%Ry5*)eSfPB=?F z%HcOW$1CAIt`)IVCG-=~>_jR=93r7?a_Wn!?!KGx{vGK@{zLJoD~Fw%&^VE@pj07Z z9T;*7JE8tu8h3rJq_e=JV*j59;P18QuaJ>(lUd=&;m-JXVX`0O#%6s|L63?kL<7B( zvDEe>6D1QX<|j_5N?}E{eql8F^Bs8Re&LE3kp!@iVD&V=5=iR-Llbd=P1S7;JjIVH zK1~H73Vhi{aKVO1%8-sq#&Vw$MQG1G1J4F8UIJK%ZeC*Ey+8MNz%8`qkX9m!i!1Z9 zjTG|tgxD?CTZw}TCZ&Mb4Wd-GDpj~_gfN~ESfW?5DM;E%F@!YOd-PHr0e>a`-|wGG zg_>9*wkQZYA{VzKA$>IZ%@;(2E~8@4t0oGCU}-)=tAa_CRshkL=Hs3vNsle7Y6uHw zV|H6=4Idt#cgZ{)r&iZ9RRMH51ePGdZv zJ|CUGvqaz>QKLX*O(apH|192vo&?`Uzc`IOQw;%baGsXNx1>)4$*!p2YKw@*9m7@& z2M$F2uh|5Yk^fz6Neu^4Z4?-N8I`yZed(GFMp;v%XJ$WiR8eFS6^u`aa@Ta`;ZDX# zyz)jB{@X1rRpHwyt{Q-5w^OV_+y*mr0WAeY>0Y|Cf(ovK-*vFALgCNDVTd6%m{AEzK6ktboPJg z}K41xPFyU(^6=Rn`5qKHew&YM`YydCI546O$=myi{f7C-o< zsDYH`t1tR{*8jOfVj(s1sAwQG3qq8&xfOm`3<;??Xzc(_C|?BzeKhA-TTIBb0w#$Z zl1W~?Bz#nasBICahLjXo zypP1zZz=nFC);pqO;BD3i!SA7gl((_sM*9R2D7#2T!XhTqVio2Rj7g@Jaqp$1u!Eb8vP*#^9f%x?UTNL>KX-#nY;hn2 zHVU>8SyU>4Mw)gLXj73z^hGsFp#oUtIe(CeKzpI`eogd=zwSbXC#A4S3Xeb7FlvFN z#zx1NIZ_JFY3!lj#gZ}}(Tj_%^5qpae=mbKO^c0w@w>V-DS74X$bZ90)zyjmy@h>mqBQf|1+# zx=^KgcYiJ)RT$T?_s8*xlqgvn???{kt(8&3%8Df1G`@?OU+zt?g>5~DR$7+K38fCZf4KwrMCi!)*kBG?s1C%; z3%1kh;$q$br-$Ap5LKPH5=rz^-}p#e`OF>|9Fx=n7geu|x9mVFW2r>cakfo~jyV`k zOBWR%G8j4-UTM&CD5atz3lSK!$v(;fw<TM;xXY?H@==CO2uJE(oIirus@1vpbwS^gN35b2ai`Q2Oo+(BD&hml z#!-xV@dZtLmC#M;>sT4}ppio0_ORURg#H(qmFn%FQGmMmi9jf8{lwn55w^;*%CWNf#-p4H0)cHX_I%&?l;lX1`%1vk;RXT|QZ_ zj9<-Xisg{a&hZ939QSM8 zZ!Ce4g-Ur67&g3nXEmc~f>F8MB)IH0VrFJ$5#!cVx#Bx}duLy=ur2pD1n*qK_7wr~DbfhS3k!6Orbe+{4A9UL5rbsEn&h%~Imx`}-9 z?YH|eZ2sEMNL04IxT{xc3wMLf*UH_*C?x+}P>Sbo{HZ30*43mnl@9-Ij})Mf6s<}~ zrpF`uwQrfYyro)zz>qsonuqzc;Bv8=xmMfCQy~XGLV1HnK!itXfC?-BrU6AHwP_)~ zuY{qj_q|nWYOI_QAMa1KU^O+WK(#V+&kk&Zhg;3St9oifcx5%2-e@uaxUx>nBL3z# zASyur9jv5{Z7OFfD?Y3rZl$wl9Pusik^mU) zykBBa<-NoV-k;d+PqT&2?)gA~&2D5;F~QoYAovW-JmSZ(=>YF7pVaT`FIx+!^*u%H zIZhQ|IX+zuIBs?@Z0y8+t4v^Ao$Fd@c5H4wr+3X9Xx`5liHqVFUN&BuKfLFyv}?h4qZ^<1LZmkxL27 z{e4{2A!oH9)M|^<_M|^@iG#tM?|iCw80O^*>^XS4Jn5aQ$zu=j%|c&1->o~EE{sFr zKP~vX+V_W9oC>~PA*Qlh_uJ50M&3_qgIB;4m&>*t@0e~Ynd>a)N=2-8`mMjAZnp=RE$v0r2kM`7sIqL7A+H-Pb4|q_dwJep2FHQ z5KQQ9LlSQ>rAHp}T&45$B zGJ4~)mFDZF2H4E~Ku9Xv+HF`stn1-!lIzwGC6s2X4S^5uNp;=6k3mhkmHS<3&E--9 ze}gj20I7^2#d|aHz^_9%eDU4M6F(py$*H0Z4k|x>p)-N(%S| z?<1FS_^%l72Z%`%b-!Q@g!K#nRTLQM=dh4G1)PFVi@2iNfisWU!6)@{U7T1vr~yKc zpMlE^n)jkoHYaNiF1O1r9k?mzLc+rDIPcm6+uHa*Iv4y4`s-=x71~qaBf@m&J*@(` zfQU2>7RSBOX{Cb_vt{3_nt*pMhgm}dt@Y+z|9)h&_cgx&))-x%9_OEH=@Zes!5712 zf3exVqrg7bTV`EC8g0fd2Z$zso9N+bgfaPb>PeeYNY<#Q|1%Kp=3NokzGkJ73s8d< zq|=pp6@Cu|PPv&LVVv3oxKrSedYsp5G@t5wo2uX6`}ycqi=v1Dm~K(vKL~`pX_zZc zE|Ml*Q+t_9qG|=D{m%iR=%)zrZ=_s>4*_96t%ghF+h~_wa^ey{PG)1gUr zH(2A;1))W>)JeN~{Q8mcaNwi70&e}_Wh}kLoLS}&F+a|Axmbi?B5$#Z(F!_O_^2P5 zUKA@YcMq>iHjX7og>q@boa^4`HpuP9=JjXSwpMM-kk6IvAkMzNJ_`ursVfdTrQD8f zFroUlk<|YxnB%%m_o?vvj}AMilJmoh7~;Z)?>>BZ_?=?gSk}U_*#*yL)#5em*6^|5 z3ovEL?;PP;bw10v?d;g76p*P&SY2Awu@)OGJyf?#|nrkZ$h4<)55{#syF)7~g^ z7J=aNHF^e*i_y`J#mV2hwYki@+$?VdqAd5Lk_4LdhbQnv&%j${!KEiHQ7J<5vT2HW zdzKAkc|#{VcH~S%@I5Z(t+JL{{}21E@d#1+x-!Tc80KL z?Y8((S)Py7`%mE4riVfS-PIe*70ulaeFG<9*uC)##LhSc!TMGB$h&nP!BfZMD_O>} z1p7PN)l^9$_W)+&fs2PE1E`BppUlm^B!m2k2u}NdqjO3EIHKC79g8duy^d#c8#Vh8l@*Qa3RuBHHg20-gM@RU+!d zgrt$WlRa>w5UC?-iqFgPYlUS4=D#{?@>ZzgWPZ)LB0l+-u3@QaHJm)eE74!4LK|`A zsrb$?d-9%YmsGa5`D1{j1DQ+-eI3$Z#Ex!k9h~XYCl7>W*zJO>qQV{VSp->gm|@iJ zT2j`nSADq?tEzSheSJbGpnBNiD}8jUxflp6*K0)jok*`UZP}69x~!$;`7|U+2YJ}H zgB;{VGSnYbS~OMa9wZgde#U=2CtfF>PZcRP%e!nVqA~+ugRgZ0Pv9FaXB1~A5yWXIj&SY`b$y6ZOaN4 zOr3}d^WIrL2W@XF2$+qfvg=qUrKOEr4iHR)P}Xf1=S9k>d@EoGQ1KxG1~`r8!^bt1 zLexAj=aT5OTHg8@NNngu3X{FmM2#?lUFZ7%Q$l5$xKSDi|iFruJUv$J`C4HP?8HSy^-z zZ0;x6pr=P#iBAN=+cNj5P<6Z@0&Z^Se{I}ZNk7`Js9_)6$VbTG8>usRec0$yZ1P zUzk^z*5-<-tEXs(ZbjhGSC1$MZh=G-FqV+MEBbc2DZeVlC%6VoRloC%L7Pjvoz8c4 zhl^QyO(ZTzn@*|~g(2t9Wy7h9%WG;%4kmP?S~;7&3}u0EHu`lxt}`dECoxvp zrD-va<<5a13C9!BDYb&@r5ey|7SjRJ=#*2Zr8b^75zHj*wK_jCU9atLSBxi0Ghi;p zTZ8iL^pemct6bd{Y&%|o1QZCpf&aSNI#0ksFKK2et6%!`+g9_dz`&nYi6E1!o+yFt z63VP$`vC%t($#|)7qthMgHxAvp#12sJo=K`0Tuab{YRGZ^&&Ih?Y%M7XeNJ}8m&4| zltWC+Oyb@38UxJa(`wxQDnZGo31o~gmL*%}+WcCT!Evzp-0|{ATh)H4-L%^5xUc;R z!3gWSUwC-k%8&bI^!5vHu2rDu?q59k1hvi@-5dpGh*Ak{CQ?{~+i%N2)9}N$eLy$Y z9U1k%({^i}gr#h(3q~aifXk0B+!6f%BN=K0BU2)VvN#*N z^YS%RU1op-YcuI37IEoo3As5D3UcbKxL>e(Lk7b50Q`PIJo2q)!Ze%(gi49=r?QIj z9VNef_j@Sf^!O`u-xP~(hX3OQn9p?k216E1lCV=&I13cOcZsQX6+sx~EKualA5zVc*6*3n+R4Qvg^Cvz7)~`-RuhB1ML_GG9f6 z=<|figqXeA6BL(`(Vp=`9e3U9m4NfMnK|9c%#5Pv9KXNgr*!l-*NPj2V0Ngq=Q?;S z>FUM*&G~LWqS^1U|=8=zSoY@3cov@^O36HjiC<7SMJKDT66$* zv#v90cB*N(7(dn>F4yal)6#~4U)%(?iSUu%+B)u&>Yl}po0pT;34xR5{Y<$O4t8BC z-wQVE!KZw=_ogusW5 zl~>+IWv@1?q0hf(6nHcAaM`MTSVw}D5eDo_uU)>9lKRUsfCA7X1$}vg)`svL*Rmap z#!Uf~2l&zT6J$i8<|}n{$o<}D>)Y_3VeI8 zm>yl1VDQ`yf74)b?aZc$P{GufroMaYp|~oZE!gK>OsDLUg2J(R($OP%Gj(iQ6M&Do zpd{O@{fY$$cdgif!~Sm-J66;VJc2@}FAXOYhMmeYyQD9-Dr&Hx^5r3smc#bzR78`= z+2Gpa9*FrxM`VDr8*o|D8UH(*o*0$O|7fzT+tbkTXLIPBjFc}PtAoct%|wB#y%crL z2acgy9H`Bp-akTL3nW6n(;2gb!h+6KG<7@skGx$c@2k%<=D$xvC`|E2*gpl9?SpKEr;7gAZKQIU8^C7)ZGK2UL`I z&yOSo+nZeQ zr70RHzD?7{jQX`r)7Hb?`W|O}v(hR}Z7PyLvp(d42-**!%-ZNbwk?l&DGNnpZ2FD9 zTyH$VfBV+i7hs+xkbgI-aWV})hZLy7jiquJKRs_B+S$XZm$NNw?SUGZ4!c5h5;~v)as)UmJJZoRA#mia?kngzne3oKFfItWq=v@Vl{@@X^!9$EH} zIQUMJU3Dwgjdlh=>!KnPEyQjim!6QIX6z;Y2PNnBeEJcN6X{U4hMI(tJww;GtJ?(Yp88W1)ne8TP$5 zBbd~`78q%&Bw&_gW*Vmd{0>W_;>CSZmi^Nx0`5shrkJO$kgQ9|;j$pUc8HUjEL4$W zu0R!>fvX_!tV*S1J6DRap8=U*iAv+=JrwA8jGE(n?FP@`-W6z=)$E_OIxY!*+ny9f zHck52s#?6NW840Q``?=xKHr`+%6MI_r8lN@5GFdk`aCBrSgD@r60|WnenkG}$+U9j zV2Z_~Yq$9;UCH7J$i0N)vxWjQqghuL00b1?ZspX>eyuFi^6P9kCm4U2-pkf-Xu9C% zN?i<|EhvQ3Y+|ovZDGpn^_iAG2?(9pK{7F%|zJ=oQ4n!Ru5MSMrOzPMhs?{@=&}cFEeYXeFFh=Oy&+-6i z_YaoFjVHqt`F&T>x6tfD(0s9Bz8kRray> zQ-%)_(n->2^4cHrqo}3|dudgsT~y(89OBP}W78*IgN6=D=gLIfcsf6~S22P|R1FP@ zU%g(M>%5*n-d5e-gZH|C=Sa^svY>jU9505|e5L8&Byabrjb6*Cq6z!KHU?2yx&1faPGw9dH8BDEB}M zDgxdIHC`7$)J)@C-v$Bfn~qqH&K&r>15gw|Jznjl*+dS$Sp}c~y55jChpkH~G?l8p zB0j>iz$8WHswv-Jq85=poY-6_$XuyA8r@V4qs!aMoQ53-2T3c18C)*ot^u?1`^t-N zLNsL&GcF+aDLNglUrjsh7Pl^ojEZlaGAERJc!JWl$NdTnj*b+fiqQ?oM`7938`)u} z@*+@?Mkbw>$`qZp6%{JRoJzc=_IamDgTyJXTzk_uGY(h5?h=7Rkh=QrDeqZunD2IO zL7!gZQ4f95aiRk6lVt@ChY@zi%PsBqVG|xb`#z2|6?x;!tv+3k)q2C)UVx4sNLI>| zUA<&LW^4!2cW3y}oxprJ>8i|ju59_65t~lkW#DcYm_+UAzJ_5!Ok0Ls8wY3_gOV3q z_Me0N#%FuU9Yj5YN~EHqlSP@{p>MD844#?8P+FRN{HB&=wYIAxxKz!VEnyY-HvGnLzPo2y`fIg=ud^&u@cz~ z9_Q}b!nQVfU-WW8gO@_Ji6(_#(_m?~sSnLnZCh_Z`mk<*t1WfA|&RxN>vSH*Vr7x_9gF|iF0_=c-X&P^;5 zbfiJsO@)lqDATw}2$LXbn<*I_M-^TSf@t`LUt-GvSnGF}Xz=m-F&BIYh+t|O8m15i z>ij@}GcWm(#J3(>3QvF=SxC+5R|Eef;Rl23J5N!oK`O#JuR2Yo>XENM6U$s_`ToFI-cwNcWO;P%`RifEkaWo*WJ>r+^@^8JfY1iQeLM#DHJlgm(SbujvnTG zp1KZd@^JVYER}&hO`OWi&zpyGKCV1~B9Wzge~!p?G?+ImA2v8PRlT;DsSunnuvkkp_vcKZybj-5L~{ZKCsZxV-v-Oh zLmpGX*C)h@V3<*9%1l*iai9mNV^4w=Ij?RhM;|s8xW~&~>;ZSFX^n-M7w)R}52 zGawA7B4RX)Y-UJ+Z9_w3bt_$54cE@?Gz|;5vYhziZ>4&@5U%j^)qBJESy)(xMhCki zOtS-PjbUC0H_A-J${tE$oxi_Xx`ad`1$~Z^&MYG~%tzUC4+~H# zj#ll&HXVGGuoxazqs8Idxvle(Ph+D8F9O41gToT`#!^}LZ@5i|n}M)mvV@(k!xZ^$ zp&y+=4K!VseQ%89Pj-aM*7FYI$&Ief+lT#(iNjYeuP|%n7;Q{t48GSDuo?wd;&WR# z!zvFL%(yoWC{`5cXIYAdH{#yj0zkINDs|fIAey(#ROZNy@Z9G@Ag)mETiDA7E?O*d&=Ta`(vsQSSb({`d+KpNhI7azdGH_yk>kol9@J4Cr&OmSpeReJh`YB5qE&*bdg{x1fc_cxv z7|^6}W0ckE*8ox~AS#JoTf4$d0`M3?-eAX1qJwNUlEaD^RqK2nJ1ZdyjenZX;y4&+ zL4wtp`0tpF5@3QzC(U#zsimcEwWIFTQX7p;E=O_ zCW3gy|4mkPyvQt+wbq!FJQy9eFd&EH8I;6EwVt^c{2umQ9WN2bEho(bi6cSK-4vbkk%C))NV%TtW>TK_eo}l(AJka)BoMd* zScJBxBieL`&%XMRZsxc83U9MgEqH|Ojx7$&Zfa^;aUGZ| z(})9*5244&P~}+KIf{#l)+Yf=#e#Wx9rpVutJ9~%F-M)9fuj9=jNHTE1p-i_E0W=lxtKQ8z zczELhE3;^#g7dG>@x1QLHtsjbfCWb8{{OFJcAqZ8A~C2~Bp?vOaIV^+%O=vB-k$t> zs-C=NzVwCX?L8Nl-^u_8re|bPaAJOPmCwZoX(q8IoV?z8Xr~F4t6H%5A zW~y8>R+KpZvpD-6?mJ|^+MPd&**{w>_|BA6Rl~QNT!A#?qgC>CeD(E*nYH-hWJlER z(<=BD7?=pVc)7h`G+^3ZNOw00pyJ!+87A2BGq9;s=X?!!{5&kD9QVyhIWXso$VVLZ zY_;s)U1B>QPwSLi0?7U#S$>Zv7Z9V)iV(t30X$;*!O>FFLznrV_G)fi`XWOQkrk@! z@VDORHqKil?`QWLE4t~6Bm-}FqQ-wBp2u6{vIh=o3wBcnEeyuzxT3&vAsY6z09e9& zt-pI}X>`>F7&|jTD+j5V8oXy`9wTa`@qro!9tjr6@`#PEzYYwq+ne2Y#%<`eCo5M& zh`V9{cAA~v-9afhY0_o8!43qs3DREUQoVaSGVxYC=%Yw#SX)31i5JSV7DK%LpUh`u!F^Z1l8L zS9b!bX9_2amGbBbRVd4lG@Mp0Rd_7XvwR*ts1(Y>H+tM1=^e8C9((8~?Q+&L+AXH_ zhCI7ux*mntK>+%D7kHUg@!#cZOz5Y3&Hv*KciTB1Neb>C1BA7~`h`2Q*ZGRWxxZMz z@b!Mos);KM+5_j+dg2FQIxIocb*$_N-~62y0wMx66-{<__U|V@=oh!~W<#C@;D#I- zoFZ-Z+BoI?;HHO4r`HgkW&;YTKc2t5{;M$cTzaPKK2%VE)??H5BJqvq(BvaBVJ{#p z3=Wlyq}E%_0F#=&!WInahzf~u+Fb9e4!r5Xe*Y1X)#Riw0=O)S`Y@*Cri`Iun@ec; z64cR013Be)f%DJ<($ZQnOLPqtexloHSJ*hc1)++~sPR28{b|~WZ2=1U`tSbzb2gv+ zj+M$`{SAPVF*r7cl!&3uF6<<(EpvhOn2I@(&$T z331&n(dwv^P4CsPZUUHGzV*Gwiv7T)H@EU05hjBiSpQ(E-J{-N{d&U`XkxEb*>vGugS)waC{(7=;foMp@>+fMeg4jqrjub^k(|Gb_!c*E~| zX|{`audBh# zb}BtufwtAHjVYSl(L$AL{;#+4$M@#b)DE8S2li>C1-4A~D*%2alCO-Tm)|jWhixda zwzXyR;lc$>@7t7lOiyhfjRjwp7Nkn1V19Zl3T>iHqWfldHLiWR+~RURo;L-S)fe>H zcx?2ueBIlE5LV)eqP>3y$`V@Y)v93gR-`o|#}u)6a)q8yfWozCX9$3aS2IMRl2O%u z_(M$hDI~X!V}ap!?M~N%W?ZEUY_;Hm$a4Iexq&5`(bH@YZ`| z4xGBI5Hfs4HlGO^VXSB-3pvN~M8^I*Mo(Ux?z8s5X0;T4*6u#px={bL&i$%k?6|0& z{4gzNbLe4Zo(s!lwD?CRApyYT_TUQ6A{?hkT<%(J3C|LM$%IGdYg#>zM@qXk3gqe@;GzVd#gv6zw40^#Chkc9T4BH(Ryf=|I z5#iN+C&x!vr6?V=?`AkG?*H*~gX_;8J>2PLl^?)!*>_>xH3L45G6+Nl5RbXQf{eFc zMo)3X2ialOVOOR{28izpJMJmeV4^P48N$8O#`V23`@4(PyY+Ydqd=_|+#4qr6`dv) z6wJz7PJHG~D~&9n`G`c=`ObQ2@{zHkY;^&V^~c36ukBygOQROue>h*;nw3}*1s?dj zM68gwcP1^#)iUh5;oGjJ=?J~AQTqkCG69R5`fE+<+l_I;?bzgXvBAbJX^As*G$-ws zXFuZv{Rkk%O<-NkP7ku636LX9OlydJa>QYInw75ona)J(Xu7o13~;uzy@3BKoKiJReu;nw>q&UG)!W) z5V7#}{biAA{J+IDqz4qPKZNMLj&r@?h|-?KYV6lyDus2p6nCC4Av5(l>w=< z$PTcgfe*H$SO8TT_?!R{T2NkG<6p=7=H}*;`P>f?X>2*044?l2RPbz-M%Lrau?k}& zVe^eciB1til7Ypn#9PfYzxYb%u~TC?aDjx+_mwQ)rtP6nrjdx%(y2bL3D`~Be4DDD z?s)s}6A?3sTxtq%>jMu{89?by_{X63tWn#R|7!jG_AGCLoNt#BYOp%oOEI)miZS{UNCs3U^ugmT17wkoinCU6jPM{0_x_wO+D07>ZnV z;ymHp2${aSDeV|3vOkoe)C}WARGFPBOYXT+>6&A`jdPelqYlg%{u3&UQVs=yuT`ht)ue7E$Y>2N^I$oFzQwmeubC19LTO&pe#kP8@7NL&?)0 z&Lb)e*S&5_E;LOyb4M7=*4xX9ybu2Ur37p@cFhwC83ObXD{o36a->i8bO|A#*vW!Ov6e7s=_zUQ2uA4BJdJkl|4Z5|MeJ2WV4w~4*HCz z+@bH~aJ)duNtxu{+`O~1qq=CdGxLyTciX&Q?Jy@J@VH~F@Aa%U&R^tE*u%?myX447 zi2n*T!3X)|f8LbA|7$&iaJ4nb;|UnH+dUvJ6R#md-3+?BnJv?Z;tl>>VA}!O+1rVy z@uj1Yk-(LF%Qx_H0w_qNLi890H^SdOn@uLX(@r&4Ji8YzSC{xO#4t|=^?-@2uNY45 z@lQQ`eVH>cj0ioRwFixrDU-- zxZMG2y3oI_Lq>@&PrO!~m6U{0+aA!nt%ePu$2=x|`1xfeap-xwm1A}&WN3Z&ASEss z)Oz6*|7LYzw=mlY)~{U9GgDCAiA`i7_;Gbx1=tBojx)aSCErLrMf^ywZ!gMadc(;B z#HhjUZrYn3gqKayzA?(%9sy~Ua$zjJ!ue=*rGZmZDVT`+P${^9{YgfnX%{fB- zKY$2*T#F6YeD->980T6pMvdgzlFIZv8A6aQhW(5)Y8)l_F`3Z{@Q_%0bs5x|E2aMX zp;pZ<=>LtN>icFC;u~-HM!Wzn#qR|nDOy#dMx(37J*T2bJjsA9Xvxf_v*XoJIMC{* zF-WyLkHvh}?ij>Sre3ubB*6JeU2OFKcmdR0D>+wOy(0RS69e<2_(FeVx|^llbo|ZJ z`fFyf4Ez9%xE)miHvg|r=b$?VWWh(cyr8IjQ5=_?ksd&B-G6;)-i@uVXor34z1@GE z5BZ}LnE?FDHPK>LNnByP6`{6jyn|$$%^YSp{jb#ofI(W{#89=qUC#n^S3h8xP?8J> z@T9SyQ`d+W1Dt0#lU0K6VUdl#zrIU%oabg=dX0yVqjg#dCK@YKDo~@*UD%zLWhekD zxOv6MO`QxG+LQT63X=Iu;iwgTKsLbeELI!7zY}E21o*8{Us%FHK&QnZRMFJL78oxP z{$K_`P)nl!>Le<*i6!}DccHU+-uR>lNpu5fhKkp38g(7EPD)l9{)sgnEk~)SQ^8%r zypsk#0ELTMBE@&O=jankHzzR(3DYUt(Z`Z6-OK}Du&{tqH8?y>R;14WSpCYi!HDZG z7o;N^&%*kK0-&M`{*ZIocy%u2EiP#4(Vu^h&0dC2mec%&ks}~d>hS7v@3;0!_zo6iYkk+{|{E3vujR{p8G9+<$W~$Y&n22TE zAZH5+P%s2c{e+Sa2!~Bg(~@v@_(|pEqtUZ=_#wyrb}JcC8^FaG^15{n#B&D0ni~&wA#0J4jF!uUA;(Jm3?VC>3-v^{UJTCZ89+H^ z;~(MUxOrC3h;1jxSb#_;aVZ+sN6i) zn8~{uo1eEg%EcNi9PhIg!52mIpb+!VcetMeNh4}XYBnYt!pW&RP~c4Y1p}g@ zS;AE@ro}S0eD}#O+MvC)ZfUipS&mJ>+qr#o`d6%gUY5s1SVV;?>9*m9yS@OoS!hz1 z4AyHjL=SxUaI*9h3wORsRz2u)0*WBsYpS0N#h&??GVlF(HVPz%sf$<5a+UA+Z`{|JKty>=$VL(>Xs?dHWC*uO* zBcn9~6oQOzQ4a!_HB=kqBf(;sLm~1!R#}oigDYsYfB!Zc4-%w%RX*^wSdE$kBg%Uo zAWD)+JPp-M51FB4uM~%eqmJV+;qR=^^%n~H1)c7zFIbH>T?F%~r!b!`-ec)Gph9W< zYKiT7|B<+$+}^?X2S7c>4a3wX;~2dHtk+^ct?C&VfGxh|Q#9j4wcRi2(h- zVpL=Am@YTaXRj-?C8hF_q=1@IX=&hY%bYx%GH6!adXp@I;oUBT>NL0jBZq`kGhas# zfu2p~_qLR$XI+C!qCXiLeT?RSvRrA12x)$A%ycLL*^+-ZNt9o1{nOJ3QTcLpWwExf=I@|poc?VQe`N{!O*a7$<;61$C~`aR zv&C;AbGrf-lTY1E2Z+8^Um{Tevs{j+wG?T=1wWC2TOob68a^?8yv#<4nCoe0{$Hws za%l^{EmvmoKtg!r{4c#mZxPEFWwa5yp;0G$f{<<3rb;U><$UR2R30|#RjsqmIWn{m zn7=N%=NOib_F?IzOL(h(DXJH=E`#T`ZNI_Hs5+|cGlqI`-!Nzf zT+`u%ydQtRynnpx_A$uT4{2Td@Im^6q>Y%}|Dt%>BEX-Do#`N^7%9w2<)b_%rgOx! zw0H|jQt**^!W5HK`H?tFU5#crOH>Hmb;wq#mT;eSDsz5X$Zjwae~=RW*&CJ+5jDny z@Ik1hAzhSwa>?B(`?B6v6}emZp-{mfZBcb$h$-a;k24jd=9k+P)mc-Dh??kSzW(Byksj+z|?7 z{OH~CQF(&4O`=m$gy~5AKP`~&A?Qky=mA+=_xrDZRzAzze+p(4*BuJGyZ-+n`Lx3PyY;MB3xJ3nr!c(r~r(uFa$xOylYD!i{?2Q2tNfRe<4$MF*mKJxt%KFZnaLEb}-;552|0P32x%}Nt9r@o75iq{+mz%~Q|1ONT2 zKo6;XvWZMDzL(d>X_$oL*A<8}{ZdMs9|r!e!fBqN&3hF^FAi=x3?NkX?z zCIs1fnQ#PPw`Vo8e9X)%nvEAToK9B~00ytqIfIQc7vOaZ2nn8q44&~yfpiRu{DUz%qd|e5k4xHq!~n!_)bfUIWC37+Zh(jVQFb;>CWbeCbO}C`%;#}H=-l+ zy&$)5PGA2Qca)m&TKV^llt6>q{L+sn)7zy#wwt7!d~A!>KOT`CQ^dCOjMt{S0@oORrRwCNGwCP<9^7scQ?nj51ygSdino2ZBk zQm~Z==1fd@Oy-8ZvXV-uo9XFN2HBk~t6Jb&$O#ny5nnhy3K(S`E@c!){QToBE~HBN zD-@Ah;>;gvNYl7cmUT@125E?hQ`#G`L;dn;L$rgET0Kg{ET3{nzA$5jZozN$!2?Fp zh;EH(cVA2Vch0rCNBbstiP>RaxMap0T1MPJsl{tCw)@2nHVYE`TP)5FrHqBNg$&RwG;YK=Lc;y+zOn2Gq zc^VKGi12hL<|bq7POvi919zE;iAkO(QT|uby=a_~&X~yN#7N^|!#WnT0^yb_4zl>| zro9_9ByEV4#gp7ixEh9=n;YM&2usU#e4H%pCmKK2Z-T63T$$c`7VdW~ztWP;TPkH| zDCFM(L1`1f#W%;IQDN}~1H*pAy76kf^*jK=qc;^Izo?X2v&0qFDKj@?> zve25r3U#5|ZcDv+Mxri%LURuP2P4qCWn-B+pyXDFxp%o>`!0wLWsuV+D z0#QejCqP5@pvWn=7$P7=i-F=^xu zz`hpWwgHeF1D9SM69D$6Kynj9;6+eDFzwfmHj0|-{Q^TCN%@@e7o^waO?Dm$Yf{WG zX3yC_Z0{Fhi&cugX*)g94)Ge9%NS(7!1XH|6(arVK+KBWly>XoGHXY{PzZ*#L z;FMi5Q!xkcC15%3XQp`A{9E-906%*R^o_=uFsagD*t9>Zcfw!to;J<=hSUS2qE}dd zTTLCCpLalQKm-=_y*?Lt?)tbManu{Xu*$Se4Ql6LYyqfzHLE&f6yv z*^3<-_0~rTGPtG+^@-p87SZ+%p*LhFJLe=OzL}fUw8A?jW=Ndx>FeQ%Yk9O%#v;#;cg+m$ z+kj_`a8019fcJPjNLdz-Mx+Wyx^Q%BOAp?sJ(_9;?LVd;Zv{p}Q+uwIUcuihueIC;+yT&;zp;Gh7d|ac}vK;51xWtf95eBr<~*#CDi)&*-}D^jWOZ+y}eeE_xw*gO}IYZX>V-{1kj1XMWZ^ zQ2zVg^Est$yv6f8^qf>86$vtw!##@_WBpX zsQixIWBljiqb}{N1fFf(;9bOR!>`Krqu}&kdxvj}A@E(g?N{!>cvw0)O&8}ibT^dS z?V46@UXRCZPqk%hIzKX;Q=0aAqgGv3kP(3cU9)sKy{JgMLb9kbk7J-Mo}-vuP$EYE zNeK~iQlpZXkBFLo-)hqX#y5EX!F8JQ0t_Q8WMEJwOJ9T7Se_sDsCp8u%p)pCUOZnK zU?^3u-lgeZ1ii&Y{HaG(S8;H5Q1#CXS$vCBwE269+<@$Cm{anssh(8q`FWAQj21L9 zenLhb#sPCBM5V;hLA{pYlonPDlWXym7mjt#Y|M?zt3@WOf4dp3U(?ZPl!*(~L*P8c zH{5{9^J-c$@@{^ew)cseWVM8Sv@pY9#Sja!7O3R9P*LfybHw=HOdN{vG1HFpg1)`T zUwqGr^PLf8nJ+YgnRzh$((fdnnUBxAU@wQaOSfKN&wd=$SwP8YTU8J@7R~;GUh@XF{2=h^ z$h#(RC9m7foJR8%MDY9R|Hsr*xJ7@p~7ri9!XCk-lcH6HQO(SIDsOz?LwXoLL zLTTFGgX<{j&kq4nJ!)Oq=w^a$n((+?Pf$ODqY}?@j65O$Q@+=cN~$lsVmXB~szCH#M~S-T5MX;r_7hnC`km46XxnSCm`+ z{rk58z)4YfuVVn?NN~?rn4jKsv|nDysuX|XesHDCqe(s;|9F-0$KWh8y!js28E5YK zkLUFc{F6u9_cz{M9`+K}y`HkyAGBXH*yJ@?cj z+JH-S^<(Y&i=#;9hk~pNRpw@Qp7<188@hpg$>Q1pL3<4)XxN_Qr2EL65$Tc>MjZXwrYt!jVzn@K7#|kAT z*kVtJ>5c82jJuNI%_|%n+@|Bqq)cg&tEw4^mth8NOqfJ8Kyd_!by56S-i1WU5@Fr6 z(|l}qw$zRaAU9Spj_ zZs2}x7;oCc|Fq2(Q_>NvxN~-DsSeCup#E^3-+#CfE#?(i)%q@tFBIp^T+EJqE@|uzgF(ZV?Sh5)Zi@g|HuiGI51K+cfjjY-st9s}_%~h{=DW_y7st&KPU3!)2l_ zE}s5ggb_@1z-xC-j(A{t*5LQ3&CM=m+m2_OXNK#{?9E2@)7+f%D&h-=HCIx;yZhu| z0C_tuH}BX_JZE5c0$v}ZZ#!C2xhXt<#q2ckye*tSnEa9065Do}Tj`^IzLAegap=8&x_43xzkIWt@@I}pDSYTR@Mr%xF6KE-0yjYP(iLbPMHf7y zSE;8EA_T~_Nft`4FJ3>Mc2Hl+6eo721CK}c)4{J6d2H&gne2JDSn%slSKj?I6dl_H zqtjDb>!rufKGH8G07=RK7mLp=@145*}Vb3@OH;uDpXNGRyR;M|!kl z;Az3})rsQSlQOV^t3eoYe*9=Kg8CWcQUim)FhX{N-m+ddAuAo)`nNkV!md;7;DBh2 zN=jK8DFqaa(5TpnqHauRK3O6K#7h(Ar^9=a7oVIjfp! zLU~G8B8mIHQS_de7tdETxDpR1F{If54BkqZd`D?);QH^7?#d>Yk4-Q9!znMQ9@sk` zmuwN6HfxpVY|^dk68r;0@CNgyt8Lt1!)GMCzKZTAuduG~WrE4IVO=rM;kjfcH4}pNqCX^l@|Y_UkR2ECG`( z%Ec^CiS4CLj#^!TaNRgD@`7jUgmu{S*I)H~-93t<=HsmXD_WqpX)df**T}P>=5bV> z8bCYt%3?b)@a!w8Tzw>eHK!4uc*lqDkK+BudccyiX z)`Dk0^t>4ng@?j;btI^Nb&$NGw#2+`eLYUpT^M8Wwt#cKN#a3?H6iTh7Uqp16{AN% zRdv6Q(=>vTt3t`xybqYg7hV%X_f|YN_RPfokaY$^6r{zb9l*oYKjq&geNsSE+R`-Z5kr6FX58)Fsnw*)Jsf?j-?0@BI6@#wgCi@QEmmlpmi~Wm|QpAiFoFB6f5C*+0FEZfL zM0fZmSy)p+P=QLOmM0d$LN^ElLCj2)mE`-b(H%6NdLX|D+Lx@-rKwJC7@^X|$SPiWI1gHkD-DN+3e5egP z8G#nZONZ}1D%s%7XXi6T9Po?P8=z6>*W@V0*?Pa8aNmSF?1(*y5CL8oV zKivc+&Xk^+FrypJ{ynB};7`uDxjjuTOGo9Z>X>&weaL>v63$#){2t0+-{ zZTK_#&SwtK5dfyZB_FVD=u0{PMi{cYhp`7bH2*40HkxUA+~W2MANgfDceam%nD!QddS^i}j)l$}Hhm`?y4NG`_K8D~-C@=;s zpf7K{pD|lu1)0GC7 zf&|y~ho}E&0YLF?=Ag_l{>HUj+C&I5# zsPOd~FJ57m&JmRwK6#1RM=)a%_7>GcLP1|GLAh$Y(ViovUb9bNUTd+tw*i?}i_GzU zoK&#o2Pu!qgUdgLr*Xy0UHk_DJ>@KLxcaYJD_t+HuDHgx+H}h7_Yc4G+Z>fqYl@g16JGghEKMq>4=0?;eY zEZD;4s^5(WK9-d^QQ3A(8*zEfzbbyyIGZLI%ijKsEU@GfKP{Y{_!}^;=(!~|(tL}ImjKG6+u8!V0gsW~XSzFu_3P4?QUEsRPP_q?O| z)bZK;*I!!zna$`8I~{DOijDwSq1paEA^zR_5<_P8c%x+xO?uv@l9FDqythfs28n>u zvQ>D6&K?CYHf@jEuxGAjBV%?#-lyZ~unI@Y;{3OO(dSlp9E0fT4PlwP)hlXx^IsX@ zZ#v`409a@T$1B3$>fzK4fw2E4;i_qrs}P{x-C_l%il-qkiq#*yDUv~NMQH6LkfjBz z@3T4^WYH5;P%#*O7t&4Cv6%S=vZHZ8T1sD5@T-F~O9G6Mbz^A(+=x@bs8R9-zY?EU ztWmwogtSx*0dLcvqBI9xG*BCjo?~840j?&gg|!>+3EkI&tTQlyNfMbb1nJduQB5jx zzUxS1ors2xqs8Cp&rSU$g4g7=r;-JbUAqMWnVeo>Nl8dUP-P{T)h$wHslNf21t|Y& zpoQxo)I<}J+4_AfQtCA;Dq=UNz;<#z{LX&FsK+%E8ZkzbVZ2_L7t!G4s71;Sujng~ ztDrV(e43hh01*C8DZFyq2l*wmL>sXu7g|SG!IF2;0d|Y011uVJJ-`6dh&xjmzY;#EOdHX`sr^lkO6YO1QPP;vzrFJNcU%lW4e3iKW3y{KmKY2;ZnEjZP&2z^xN$$ zIXiR(l42`Z1H49C(?OiFrKQbU_<%<)t=+>}k&(j`zC73ZF3+d09kix9Azf`$vz!S> z^`)*yw@(hwI5R88V*|44y^P6*6HRS9RPMDv_^g;}uHYydO&Lkly)Kr^e0Y9m^6Rgx zcl56mA%6fb)%72WNt~x93P-!aHFJ3cHCGvHPW#hM;{rymZ+C|Eh9loBO*MIL5_p(f zHN;e9+B2y>+$(0eUcGwvJY*^D^^3i#rPk!-^770`A89jYQXylAna71CoV=BE_$=Z# z^zwf&>cBP8bU~O3#BVzmeQQFvpc*9$h5aOvfs}}46Zwllk=hAHLQaWRK}mvhB4xj6 zK`xbiSR$0&pbz143fEVPa6dq)LM}l@VQcxtT8fw9(G+%{8(jJg zM>%oMXada4-4lKYjgc8laj}IkWLEp`-?8Ym~V`N}{FtRR4F!a=uyTS_0z|^JZUqeRA z0BQM})xz{KQW6%cvFbkL>WR+m04>Yt)FhP-=!-Khmr}e2y^}m8;}n~Lme)ehyISuW zYb|YTwhwH})5L#GzWZ>M{07eX=6O#yav@vducI<`2U3Ofv+H(h|5XTnrMB^q$s^K0 zNA}$tZ|}dy2d$GM%9+Qc9S?>5rblfYC11Q*u=oEOKag#_0-G{S8m0|hygJ%jeLy{L z-kzs+7{4WbdAnG*>>6Bo`(c=>iK6w5o0C)BsT}!vrZU&YrsfCXUw>AFgDV;r!|XSb zmN(jYo3>{3N&YymduI-o6hDl<=*Io{P4xWWwSntz?M3hBN93z)yT#Ltr^HF}QS0cX zYvTz$IRCmjcgv>f)Ab!WT0KVF)!lyNApl9rgZ|)BRXFuf5Ew6QS!6c@?@azAg;4x7 zTH-ID{&?A8sWXEw>&>mHB#0JZkm$mozu0esKQaLGWHvGn6%0^;MkF zpnLPP?+Y@d0e)S>M_=M;UL9`wplIWXf`)(eNs_RQKaRl1IU2TIULESxPB40TgNnDO z@T8$z>c3(!5SRQ6qN1W+&gjA43P8O*gDO7y7f16-y?j7WAuxFxai+{AAn-N(u=83? z$+*DmV(?{mBa@!~0-gYEHa7wioTibBvKKPnP6tM-2earKC6Gse6UzAS*og5+WRSWq zN66x75~J}d_h=O3o~&MM>72_=o?P-kWymhc&=t7`VWyEu#sR9PAF$*Jn2i}j16e{t zt-u<$32EtSKw3{ws;**0F-e%jI!jQmW5H*lMIQxYCPC1E);Ap0OtN9Y4YmRs(eiUO zD%P&A)=EeUjtO@I910;NP`jTjGun0Nh&oNya2(#q1Y!-Ei7Ofu7RJ*ANz6p5;>AXu zkf{`{p$mh&j=WxU4Qe8UeLg_V>FHr=`eN91k{Q@p{WPm=dkAm`GVR zElnwsd*St`k&hDvTihic_Ip}X4-5X03zysn@w1t~yzY+%J~;niX~=$B|8!8l@lM$w z2c0&>VQx*CNH9r`D;f51a~eU#p9T!h3v&JnU|T79cM-}%%KFBJiTS;!2EOkc6X#yj z{JQ6l)E?A!mN=R(MLcQ@U-+Ayb4mzp!X&;Od_VRQy`Ac4-iQ)uy2%UI32y>>_J0}q zVP~w|KP}M|_IR~~>+{c(r#RcoEp?~)aQ4w!PvUkZdu(#@^mXFoW>> zk46*&8SYQtZ>Kps$f~{lFK2i3S45L5zTZvxJOa7(>vlJ^XQy><-I1ytt{DNY~P387t zmaAJ3O<>mZ=NR-Jc55?H$0y7&63F5^Kd;#&PvjFR#+{t8a|3Ncyp<}?XWLJ;%dn`s zZaO3E!i4gU<-5qffgN126zj%6L04B_JywjilU3o^jyu2Mg1?Xt+GdxLP3fWqJ(Q$Z z|J8+D_9Rs6Zkdx>JAqb(4`_?ac8@q9k*^f_a?yE?&|*RkVPOlnbzwtAx04LM*rbGOn7B$N*8ip($PoOh0ojN=0z1PtA73lZ1*jNfO$fTvrTSkS!f zb-44VQMtk=*_jrXW7PAV^XTB`agZ)sGiufG{XuKbJ7kn7O;w@9jdqU%0(u>Zy8BQ6 zys`c3ZsIqW$T9D?(SuK4pa12!3-Ne>jMUAMYq@O z!#EOcxix@m?+CR+!&_y|j-83@<6FX8k1T-9A}xMrt>qp`#&4ytW2m0>a2@|E1)M)# zr1!jp$BY4luFdfQYIp=Eak#SB>^ZmS%FQoi_6E))(l^V48O@Fs*4DXN8~~*`Z56rT z?Ww=v__ zORDqA;jxpojg9HlxA9*4-izJJ-uLhxvFkBsk{r*p9qaM z)6OKYtH7FB1GC)T^uh6*0a!{M>_PSlSh=)t4Dx7977JjsAFS93(> z*SXkz+Z%AUKE!BGI{N$3o$F0YH8K-udAP@s1GM+&UWG5$@1nx;BFI*bYAxSG-yb1fBgMxQ~uCS!l;^5*-4O zUkV$iZU9i<9Oe#CVLJ!58GUWnOT*tgE)UIgurO$wfI4F;7=|`lr2F^T<2d{Fyv>`6 z$EIrZp!q@77?qU>^PkMy17P~}_nQ7O>d(&Wp~{q#oh_%{o+niZ8LoG)lrNs&6G+^S zN1yuV7J@R|m%o!2B@O4bRb-A*x~S3f@0C}1dd9Bk>l)l5d!2Pi03SYZO>j@Tv`lH4 zcHdxxx7l_FV3hOQ(^a)S2?I4!8$E?zXmdcW6FhZS%gfV`&4Xk}0Mty%!8W^DYX7qM ze~i(&}p6d{d~UF4J1Y!j_`zXNWExYfnGFOI!Y+tQNJ|40vZ}0MeWFr1=nhmu)NIq3 zSZ;19v&AKUe0ufPp@fY1^D^)16~5@@nkd!-Q##^%L%}6Cv=jB99U)Umvb!PefXEOm zE>^jHlze{ssqkWkW{-A!-2GCZ`5?dOd75Y!u3lwR($P*w>>Fb_9Hnp^Yk42`8J*mT zERlaZ-3&+)`7hK>ON1zF+(16QvvdYGW zBO|DLJ9{nyu&fVOwQ0Qdc~oNc@?5A&E~DG(M1DzeCaM!KN_ipVbvm5wc(Q}L{f$+g zQ^Qmo`i~b+)a9^>YoUAC06YzxsiUrIuMO`xv{wZ;SEWHhrkgRN+yVc1L)bR?YoWub zDvr2CWINyys6H%ie02uH{z|0`ny4Uq>>toMd_rcl+f#>w~ z-|T<&V=s@T%M7pWS2(JEfq#H}cFt;;k=X&oD+;(IC=fRKD;KZwehVx`0L9GotRt$H zZRgm6#9#noRW#0r9e!WRl71uFByqkE9Cl8_?58_ZcGx?i-H+S9GJBpMx1R;~_dnSmB)7NzI_Kg{ z<3~sGdYa5WuQPhcD9&~ZTdsv`?pnZiG_&uBjHr5Vb&1n$8--v45o-X0WVj9*Jr{gl z*x`On^}V4mv98^VD!;#`Uro ziskSxvusnP+ASC-fql3fJ?Z)&p*&{4z}hApdrl}UMbWkTMHu-(JmK9Dk3 zwyG=xsr&u~_ErHl{ZgYEdf}qrgboeu-ShF+qDci!YlavdTRu~#NpI@J80Z#jl=z+n zf`gPzbJWu3^WV3NQrSJ%qG5dmJwZ-9mJGQ5iP}HR0(>;61-N#Zq2F2ptLHz^5J*SM`_I!XU@X_)Ip(vif33k$8_MT|80=zSXzCMuWc zG15!nRmsLB^Mzd1&$Rtj;4H_{+nJasN-;NVKsAEfnIoo;7OoKnbKg4>ui#udhWn zHk6q@dkEsSv|wf&i6a3#tO$8tA5c&0F?8n=nkmz$u=~wFJF&1&bV*-CF#>1;T5DUP z$-Xb1SQ})NbwT6hn#f8`*4=*i%D}suR?0b}V0qty@CYh670W|60t#rOn%Y&Zu}vr@ zCp7_$#u7xik3l%E_(yX4GCI9>3)DH>9xj;^(=CmO8$hRmQX{~EDmBt`E>>P`ED0jr z(kr27`0qRLX+o&4%a{B1zfLRHxQc$lz=*TVdj+QrKwun2d`Kpur$wIO+UB(q6xwE(6owJ#&4 z^h0NHLqo$FDlOySl$MrK?9=&)sKjHQRmO3MPawTHd3T`GPgbRyl2Z$|v;r#H%WJgN z!Hr<^`Q+IDTVPPFg@2!M#9Cppq1B?H_hVslIWd-O<6K?`Q3Dl!VvS3E=m)2O1}HlM z?iT8%pD0o&7zqZdj!C)Ce<74$B>7ErkfJ7tClq~yZA*`Oscq@kv7w|jt?he8~G%kVA3V+q)ab(E|WyMF-9lKfy!iHOFiX| zIhtk125mkR|CYhrgl+qyK8v z?iFD9-ab|H3hm?kOTS*am>HVFe$Mg_+6YW?%p>X2tbt&v{@y7usy+2er|(A$@4n5@ z4JEP(D^Aphfnb~sdPpNViLe` zlw2+H$03^2CnJ91qOapwFkXq&#+#pQCP4ImKeQW~x4uqx-o6G`8RU~O_J$JDt}{qs zgva@Ho=dt!egUy!e|y3V6L#|LiM=y}8vIb&i&n>?cN;R(OG{gX+n@k6F%3EkN%*b{ z86ANoZ&;3vsFej@N&zw1^iMi zj2hXU?;#_nfMBdxqXfI8>VCub+{Mn4a%7VbWvGe$d8Ajf#l66ypy)y#LiT-52PqvI zCle2nZXg-g=OPTkAED6n3*-r{nd!muh#*neofoYaph1~u%j-3bIByGaTGvntc&G11 z+|70k)hX^qGB(?bU-P%8rJH8i{LS_DGbdJeNMn(x?~X~miI**I-4D0aS<(r8tWZu1 zI7Sa%g>(V}tJv8sQo9C<*GNN#0uKX=lpZCbQj6of)>}MCkxmJj>d%YY=AD@ZUE1u? z{Dj_QDs`gC*@a+cMyXYp^^&qQ-Q-6yR&0$Bt$Kt|83k_7l?>8>ZohEJV)Mes^`Y*o zs`te5|2Z}N!Lg`ISU2}8&;3}MMxA=YLHo9YQ6dL2@cp4nwPC2xzpXo2rniu>R}s%P z+5<5E5aGa3<`oLC z(UG!QLQDGnzHeWSf55TiM6GP-NAKpzqhJCYdm?F)u`08C1iJ6iONCDBTzAukq54PRmGJOXsJvmd+l;OCo@qi1LE$yZ`FNEm()%~0tgivG$UM?(Vow!eW^?w^}ZZ%n;( zQ`dUrYcFT?c^xj$v6Fa8@R{*V64WZEpktHDvwlep3g2BK|o+~H)&Ro zpn$58cELXZ%D49vcAy2bM5YpB6<2=jumUV7{&$Is8hHGX4JUrH2NbX!{y1}ghrypw>dp>(Dn@-@mdDz*Ny>!RnAg}w^`h{*^H!ndZKpb*$wqJEiBDY$Y*7&{3L z#Q1I7UT0z4O_n@uc76#oPit_49dX9=%R0&BjBK$f>f5((%fCO}T{vBzTx>+wJZ(C? zcZ{rQ71`$mE(pQZy6pe4EURcpSGIXFD{cLs)4V!To}^aXb<4t8>ziP{p7$C!V5(C!*9_J2l-sqon8_ zxUzor_ze!YOi`J>B_X??f7cxKs()_Sb^F}3EECj_j3>ijPiLA?;NPk7oFX|S7#5bJc`1X(T z4~BpkXnt4PRB2a(2narTg%@~6l!T`e!4s5`z(P|?Vr{@L$1iZ91sT%ze}`aFgG9j4 z@1{@|Bd1Z;yoU|voQK90P^p$>;Fqw{e8&G~Y7dcglp6a(Ha4>;1A;GSzBvCOz22L* zU%}RG{JHxCAGZ6~!mP{B#?4*Y&~?jISXg-Q#qVF4Z?fg7ZkaPPGwT}~PKW9(fm!w< zM@_Ij?OY4^eojS2q-XG3JDr?1=bu!++>Ppp(9yfJKJI+O*BM%my@(I4cN?~A7)WGjX zC$(og^r^>%Vb8FTu~IwHYvLoK<@2{QzgiyuH4l%-sVE6m;%7Kvgk14-$ZJNL5?CWh zIXb=ufXgSKGY*?vAcCJcYG+Hg2yFh#qMM}v$ibXu-UrXj=ydbQDE+|`+4BN`0X_<% zVqA4U860mD$^2J}6j30{R>HU$gw(B+o+-?7vmPX!0g6Z(SwKOZ$V)(h z^N@*dU6~-5kneK;cY9w^f9a2)dJS0k%10UozWxa{tR+b-xO#jFF*+R4 z5Rr{&pluQ+@G#;n$`8coSpZGym>S5}EgXF|m(h=nt5WN3k`=`p0CTsVAT=9wlEEX) zdT?exO{#uYXXTGn+@ zTE$RP%0W;?_t^3U%QTR+iHVh*TCPugEI5}9?Is(tm`@L@Z$RNo^k6`X?@eKl14R-w z;(uZflvUb@P<-wCAHYk$Aq`Ph#>!sy3O0*ca7tccNmME`k$dIOShfm9+n9y=1H(R& zNDWbaOUu{}#w;mE~;U83oT3K=}9a$@=CPkgRzWKDTXlS=GOrn0cxD zYQhN9WP&foZA-yNHV)TAuJQZpB2SQzDt-`#MJT@?lSDADpU{$-m5xB1v7yJQtW^VB zqEf0=1JE3}(hu~=1Ip;!s;X!jbU-3{bVOwcl%nf^LW|N*AXy%mtAV8oJF#s!qd45q!PiLNFm_#M?>5dRfI?lD`viyXpfF|2gs>7AAk2wo;&Vx!ZllD@fe zQQF|ThZ@ireLC+aM@DAukIwGwBQ@yOBb;^1Hczf$;Pr(uo_2?8k}nW4SKfNP-H`Te zK%*r_3Ivmpi{wiGoC=rrd$&IILyDjue|p)OMd2+$FtiMRh;u|a(C4Zspwpk{G-N$M z={JFuKT!~k8gz{f(?BoGemnib-9e3;i-!b8kmf*D@tdkJj^@OX!33hku7>Ur$76m` z{k0Vm+MeoI!U!fYNDQ&pNz)jTLyGu%R9x90LtY-DDS<=!BkgYpk4hPDc^`u!Svorz zF*&4ZN5hsM+;5BzMYjKp?nn2VG24`Ae0K6TxornlXZ4l2o}Lm);w^|4xN2ql`MVVe zH&JIS0>+OX@hnlw%eHc=sz|-PNFfYFVWmBgGLOI444S-ISLOp5bpL>rnWXsWK8{z%<=>(z2b z(7vMad{FXNKqDo1ln-JNwKSmhC%!>XJEu~Q@4n_&&-)f&{22*@g%uF}$mJ;1OXV1N zd^T{}Ak$|Ic;rGo`lfAxrKCVpkx^5y^M++>jWt>@YTRsxKi`KY zSz5`T;OO>t2w+Q2_|z*Px7qkN@>pR;_tU;|9RjS%{&zvO>%TWRjv;1m zoDJBQkz6u|>W<&+r4*tq$aye`6@8@e&;^`|p zx{J*FNahiSS0`nB!l(OML53u`j-jaeE;pTFNI9edXbU7@&oNgUnwZFtR?23XlF997 zBB1pUU3rzUCqoDarZ7XX*lO#O!Zsg8F{xQIzG<*+v*_~q`i;ymmDcq4V=&EtR10po z2+C2|B{4}S{Lu7C#fiGnEXzXSku^Gk`gjPmV|v9*--^^x*JD8bWdb#oancx4M2r`g zI>uTeUO6Wo)NtA`dK9%vZJruN>P;!>O0}G+3BLreFmL3!h;P2cG@2w^pcW<^dtQ&o z(mfVznNjtctHRyorX5!&E(csg%d4Fiw*NkX_dfMMy9RuPHvHQs9>D(MsP)`t+2#B# z!aoo0esb#z@zFhhRfBydOt_4R3KT0e4iwJ-g`Kt{VD$EzM$%&QE5@xNLb|)nUuMM- zorwpDYABjksEISk(V6)%G9}kRGx1VmAmZ}kgD}}#^{(9b0H{9DE~m&R@bafSB4Em| zU~JHg(!SGt%PQ3lEvU{}R8R+_sm#y&+LzGJ%=2k!8wVo9yLql^UXOPwM8t5R2@t=m z|BAsa+2b!wlTm5%xrad;8ZH^ri}3-AM6J?keJ2dPOkG3c*VfM$RC?|gTrBxK3f8A* zVL56A%{ku^-SL^eYP0ldU=?LP zf;zW`BN~3lu8jD<70nLN3>h*ey+0hy&%3d>&j#tEa~kxU8yf5FR(mJyaBR1W z5E4Z84(Npvkre1(DVtQ!6Ue^%!lDcCp2T6kg{&trrCdm$0D?_NAvJ=ntx*1(8pcre zBMJdpMaURppQ*0_7p@N7DHv4FZ$TJu5wd{-0&;S2GC4MYBl{x`NSD*gPj~<_$ z9cZnrd>&nPANXmXxcju?_|EAli-K=RNMtCk4jU~4ha<%p7N69FWkB-veN*Ss2j1as z#?+7JJ)jq#kxBg#^O^kv==`NZI8ax-cPn$qK za%}gUf*xFY59TTSIW80|Sbs8em}|3Hy9>u(*F~z%{&HH?j>( zB4mhFX+?Q0B7iS^k~M~8%{Or~HAEeOuQjAS#7I4Q?H7gpL+wh8dJBrIF<~ZK1v*cR&Tl3L5CxsqN(`=wzS}K6Y#6Sm${vJUOoPc#7zpfZ zQ#sxO^}PtoPu(}CDp|a#A9-&zMvqc@EU5D<6llN}9{PvI2n<;}8~2jNrmXb{CZyvH zvJF~sE~1Kb@zTOzv~%JXx4XHTGICZJ-_)CcaH|qN4HkAgg}`9{!rBnjpjRjm=A`2Q`eiPuAy=xrmnxcbM4AB-;OpnRY z;aTK&`tbSgvPiLGHZ&3O$Ptvj>cOY0M!7r`qy@3K9W4HNt7#5Mps^VWH0%o!u(59v zhRo6v=&Ywh9Ed_cVi(qG4H37v-?I?03HZGsk-pE${87&-I&V>bY*LS6$ukd?R_7dR zmn+R}B<8u|LoX<21>^sB4WQwQU#uFg%i)XyXHd6e5U_C(+NggWb@q$yr3{0e429EY zl+s3GoH-q=fVZUh8gz-Bvs8W{jkzx`XUo=M--fpo7+>GCn>agD`}eU`7OU3?{`|-m z5z|0LaODC_wv1p+)Syw58dl=Wn}%{@duZ6pI!S8UDJLkodf@mM@}@fMxL+kIfT}~$_{XYlk zKv)d=KnL!Zf(ORD${ItV{c}tM05>>P<5Rf3it22WVOOqJT z`2wQ%9qYtD@S2Aj3q3m?LZ=;(65r{B`r`*0D+&7zZ~xV@l-mn_Yff;>mDXG zj+JyVt#b`M0Jjo1$4@Do_FO9h5Nq_yhv*6U117%2t0ob_;F{PZimy94du9bLK41`{ zl45Nt-`i%v<^suA(uHb8X$p9wOsA!0XIaVu>4p61OvK@JW}k59o&6J1a?W~D5<%T# zV`{+6Oy6S+5T}LBzVTi}Ny0f0F%R5mt-igE-o)A zC*~AZU2gF(DDdSe^}E#1GpnDld5Ng7qvBXfPCX)LW^y#{)mSXh(8>TNDoTs(RS2@IC2T+GW>i@Zap8w(Q@$jr)G&&X}hwnH^yl1>6eHP zZHz7V!`M2WnC5t#sNHk*MDC`@zN}VnE%AMOHONgLUkCjXEKC69@(5dKN=f30h!o6# z#-xOm?R=xO1T|un7%YC7Tm0&?R6w67LFu*t1Y;U5z3cX+{c2pqK&WJxxa6Cj&VB3K zrDQTU+D8*eOXVEWN2F1jYek+vS8Imles?E$I2Awmkr4aBNplESjZ52_@ukl=s3KN_ z)=yzYPh^ZeQ=>$M&FLWJCGPf%pJt9gkp542H~gxSCK#&4CR?H?wd|@(jCrMEdkCY%Hx|gO9@e57MH=b!ZblHZz8n`p}{*3iz331t4n9?eM?B8S?f)|G5;ny#dcl+o#~+m%>M!wqEQt&;yoV zET;7`#1#14IDV2JV-#rdqiAEp;zwq{JW$i>x!?qQ9`Ptb`ebE-=z&gj9wZn8WbPxu z|D)+DfTHf+E+P$*f^;`XBi&tsbT`u7EFs<9EdnCl-7O#>(p@5w3nE?L#rOX)vop*r zJM7H8zbDRfo^$lRW2&QUgdj7J2csYzguW}s#8O3E*D!`<#QH%VIt13A1fz->ccK)E zRg3rA@vVO|;L&RtM0Fu*cVkw%s}Pt{so932^fTev#9!`!F3|~1a$yOJws-CVEV5Ge z-Ys&90{coM<$!>|kV2~}1TNP_>O5r$&ce#HHZ-Ebuvk|6fYHq@Lkj$OD@$l&ks;`rRS9{xIem@~=I3=eYD zpm5Z+zaW|K{2GS69qbrWWl*6$OTEu|{Yv-GXUE--fhX5c13zv+Xi#A7r1o_f98Imz zIU^S7e(+hlm}@?Cuh4Voj6ItaiC4p8-uOHH79w`$17x6dT5WKFPcmipIJ?=+-_D_* zsNP-oM^KeYO>gk7_gVHD*OvRd`(kH%H1O%|`q=vaftGmet~%a72a(JtVPazZ*4J+| zrPTLlKbg>IeH1T#Vh@({43?@X91^uWKX06bnd|e#HXo0peG6ryXH<5B5*(?b@`!!`VOSEmBodFvcPv3(vskDOFT8r$xn|3hTW#ny(DE$n0pIe5nO{t!qewPn|mkg$5id9Io<$%3zAneYC~uo}3e%xXO*C}kf$etA4k&Nn{J z;oCeon5*91FAwOcGHAcrdez<2P^xBhlJoyzD^7}VpQz<@m*+IKIv`VI^?Deq+Q4md z(D!0Gzp$(8fhNmf;2{DoE}}3Vrt~F(SXEVAt=aIqs+7eVf2MLx$B){jZ1zJhW2$t| zlugXcia&U*AaBWXt1_@rMo>4xBBEXH^xPOkn3yHV5};zMAEu`Wi(41f!OA!8zjMc} z!ox2R_3~QkXVOyP2%}Qp*b~dZrVLSfQ;JOd#&=GWU6xN!!~84rOQZ{Sqyh=5sjL^n zPFS?*<4H=x)?XAj9OuARwA{_5Te1@GK(VA3;pT@zVzemv!SC%QqNTbN$#0WoTV6)7 zFfg#IZfJ=TrDu3JVWaFJh!y4ySs;z=}k?m zE0OE2lG%@t(}p*(C6HZ*wlJJ*{xabBzV{pa0R@B!YxDPV;E24Xl3 z?UlsibG}y;kY_+ZK)n8u-rbkpbrSj|iR!;2+JdIBADLZUJo<*m`(71-nnh3?2@KRm z8cL@V{-iDk`7z@>rRH2OL1{{YlG4UpJ2Qdo=EG0*u1wdyiBW-yxdyziQ13BOu;;?X z%d%QF$wLhy^f=#r{AKe_;Wz<>fdmtQ!XRWu77KNV=%5`--IzX85qPJ@5)H?33ttzWB!=N$ubP9|)2iM>P5i4M3ds-)MhV&V_|Wi&d_eBuXP*Xb^VwdGO)!Ytb@!KeMb_ zduKvZh9ve-7wRs!=KZ9E1Q%1;m(oZLHJ_qmTT(q9bg4o`NAM8pWi)ioS0moDtGc* zvu$m7O-anApnl_WvZ9wJM6%;}{Z=oc3igrFbeFGmu!<`1;dF^o)Ke5RKw|1@>LO9W z;q%2LMT&KAg<-Jcs>FoDD(}70jZyeL%zn2YnwxK*f^0~3Lpl>^+|bm^K*%uy=k89h z#r>ShBti9)DSEL@sQ4gFx;%wakgrL?>V2>s^tc#OBR@sYp;{2z>&ld&7$(UmM@d=| zr7%nP#TS{;!0tVZih^Gv((|q<6T1r4H|J9FxGT>?Wf=(x_kSN86qhtdleBxB-JNA; zia6pWmrN81zW)||?!jNC?=}^BHytkQCVPt(Pvc+v`*5WX8W4a8LznCJ!*GqLyYv2{ zM(Nk5XqKO&p8B;$Mk!#tEPS@7e6~307dJ8S+V|+-aXjE|cz5J|9qX~wVX#f(Xnb{R zSg|rQa3TryJ-LShw+gazZ^@1hK)#42dQ;~!PS^&@meo}yj?ALk(#XB(67bO4Wo2i_ zEnLU20~pBseBW|!Wo0B!2%-}Asj@QHdipa!IIg+4xQI{iJy-oOFoga(wcH(wfIeJ)q5Y=8o7QQ{;v=7D*jh7=X!ArX1V7AzVkb0?o7onb=p96 z^gKPzgBfttD7X!tGk8&R`VF+^vL@y9VT%0WGCc@J*dcJmL2uG(_9eD>qn2Q3NKitb z$rp1hX+x2itl(e~8@Dku%&p7{BVrQKA}Qd`u*CAlPCSyAT*ZjS*d(SXl+kf$CvNhT z-(-I(sLk{06GIAqBi!}9#Y)~G)ur|W`-XRtP$+C}d;8w&m(HOQpM@153PP1i1cY@2 z*tKwPSHuQsI$Kw;C*|0F!$eC4~|STPrH-|NqQk{P{ z@TFWM?j@6E1yZv0aod3dUT&QeYkYDZxQr2VJnlGfAPu;S>@*}I{#FkR7}J=&6L`8dUwq3K zahw_UbGe=lr*UF7dYGYr;{1EKPvvREw)Y(vaT%ZpN% zdBSTK@iK?6-4qka8r~PhD#;w<{M@YYKIS_P*mwr>ellzD&fE3bLW?twNb3cmW`#CE zoI#@vF4^7paG=c4BtA>;{d+T#M)60>o+rP};sJ>X?6xm|HRn{!6!cafHmEg)uLc{5 z5bs^$h`c;QAeidMoBqF$9Yyo+Sg%zx-Ds6)lc}(xL-TOOkxWP77^(?F>?1LMG}*#j z8NS|cq*a-bgzr_Uu(9tYW$r1igzM!Ev<$~pY(W1ebF@UfZiNsH&p2DBWQWx_llIXd zSXU%Ui9}3*yiz6@v!BXPqveFoDz?-FQ^F^by|MK9lBTScz-PQ-Q?57G(u1(w7{P3W zG}I&NNpZE?R$m;+Mc8CZe_~fp{`fv8PMJ!rm0rY>PEHbCNQ}5QP{~#Jq6@l=L-gVk zUb!uiWf5AH)Upj0RZvrA&;3jk8OH)T9D3;yUlH8Pp(|?Dgb`Z$)Uub+J5(1Bd~*vm z);PwmBxDFD&srW{@q{dEb!|tToC4cdnFt~n&~yoGoN{DxfmH&oH{4SyM#?Pd+s)1E z=nHTeAh(guqC|P0{W|Rm@MSI66dCJib>)4ydey`m%lpS}y*4=iAwXmsc!zCk>@w5l zz9nmP1uiK<1uf3bKvbvW+-9xA`&$-!Fp)zW!3W53YdW9ndoqtfIZsa>47krd+e2|X zWu9HZiu^cT!obkv{dnHUq`wDAS9R-U-mTaA?V7-T#v$lNYOfCKrG@grZ=}8||N4!A zb%K8#1%ZeOO4Wf`jJ-(j*Y7iRO)cor)ImsEAw9o!&qF0q4jwc~~iZ0j!C6MwY7WI-4{+VHm2_@?Ow6d@Yd! zz4{C$x7k#|pBH+&SOZIxXhX6@!O^$`DFBF|d?y>z_?0cM6XO&=PECe3TM7cmJ9ZYK zFX?5rd9i6U=)WLgfuVv}N+mFnjz(wXwxbD`R*3yB{9ZfcwXAIt<4f+@(z&*+TYqwd z#r()5pzszapD0hzPx1798V=<6^?15QswzvF~G7|1SFRXW`byM!{;^!M}EDGsM zGeyp3!*%wz7ZM#=|ACxZwEs?8j<#MDx!DFsx`J*{1rn}K$=2oe9oQGkZZ4FeAPu5b zDyaxjOf3<{E?sFwVp6W4qvD2$Aync6RWnr++b~sh4GaWCpvZ{c!LP`MVO>tF_z`ZV zjKv0*k~{wej9PR#Za<@NSmSue8c|~rwtXlO-_PlHIHKk%e2I#Kvb5Wp85Ec=eFY5Z z5skFPdK0nDX4oV&*0aJ8a4E#mIyG%C3FK7df`yu>o!)VCSZyOq6WE)Xhf6Kmtdke@ zTG^&BhSrR54nCFiw{!S?v9=fI&k;C%)jb z#Z}34%Njwn63P^U-~m}ZBp5yZW@7aX-s_*q3w7>He)snkdfj<^^_FD5EVlC;Y-~t9 zLGW}kurmL3{-Xa-R0PC|2$i$hFH#-4`7v4PVaST&v6XorX?+BKxvwY^=aR3BMGLX#;z+>BfJgsJDw9Qun{4p~ z9%b1qqsYyv@)yl=#GJ7dhUEU?s)IlGpb7U2c;E!AC=QLgn{ej~VUdANX% zm*dM}nd?n!hMrVa@4oy-`0r)_N^^k!>LmKo{xm3pfCbt_RBHJ`hc^ybJ^%q=dTI(Z zLOEaiq)@FLZ3Q;i`30I!lzS(=6(IuihG#esWqtwgpNTTp2h+;+?zbMq#TmTT*d@%` zJ>?TRiUtO&Vo_(_VIw$tbctDMVtqVZr9 zZiQZZ+Svqzgf8FrM-56lmCQG1;4uOZ)6hhEwM*a{#z<+$IA5^sO{&*q_sqDjC=!ut z#opc?natDOlkD#TXo~5Q->T8$dH)&NDa7VY6KW-{`8C+j)cjv({ICY*Wf6sOyO3T= zZMfGAO`xF3Bc%O8%{C;RXbPu0pCtYFyQw~7#Yl;iyv1X}efD5O(p&9TlgA14GV~x6 z3=-;goAr%0;WttqUv{KEV$x?vQMzv&J(K=TUWSJ`5y2m;`{(PrKciz>WG&ET4M4UK4e z2RPW0%UQa1l|rA9)ai)K$|clP8Eh}7KB}W7SQ+V&VVMX?!Evxrll-CJOKbf@qUE&a zT`lmNcm4AE`n(%ZtS~-!8oKZJztT*mRW_a7pIz~r6nc758QxwE3pZ)~EMyPMH@I{K z1sMCjce=bq)k80am+=TT3`^_JEx#zdbbS~0Qnx6m-{b8Q7$JP0`8eMFuuO;1>Qbo9 zc)BaHJ{ezqjT|cOJYXv%BvheYoAd+&UUpt~<^()=hr1o#Z?>_3mdta-YdRJ}@C6S= z>gnQKZ7ZMD=Rf9n8o1-88~TiVS)#u|L;$X(*#X|D%_}|!hSi>ze`|cNU5;C}(Vx1v zc+Av`Q1-A}XuyX9{|8r}%R_=wU4Mx@P~n~QB+&qU^gnr?-O+=V`F`K|x`-K4$5tNN z*XvzoZCF}11cw@$$)>iI^M!Nwre&II$PC?Q=RCa5K)rg^b?;emN}kHFr=F$F9Cpz5 z_wQfQzYB5OHBM9Fq+Z6zlR}q*?Vg@fb8~I$rvjeGrboJZN_9?~ef@a$|J^3TNaE{w z4N6M%pvt0}5eB4K^$P{#K~$WE;svSZ+DdZOa3j?~b+lLvyz96^OpXYhRO}tzFDCgb zi=U%)B@e#W8xJC^&tC~65woHH#t-8Cc(`P=^af4mmULixX%rr!A1sX|BCA2*pOqym z%GRxW9#Mx?KZJtm@ujw&3!A|d-#%#WWvCl*N)%OSrF`v{0$>)r)T~#ZBZCV?PO`2@ z*j^S**;tD42x=n2d0>v23M{3+Xe$zDP?6W8dS{{cp{Osb28Cn=Clswir3ibD4la;A zu%P@j?li5|=yHUVi@wbIZ@yhCM$Ld{&$9w4YJ&7kwf-E)f z<%$-WldzwkpYL_K(Tl-YaQSE){im}p1Rl6|^TyJ<|I+AYWiPhb6Foja^EW|M;@jYR zNP`AEBKjUIuYXpd2Tg0K+Gns){THiJzF0L9K+f*?&u_)S&4Bt|LY{C;3FkskQ&wi03UG-*ljOpNt7?n;4?!|D^Vn1cesrs@jZL=k5;vQ z3~L+0cW61K?K(eljK}18ipF~-xkKN8t;cR#TiX@X@eZTAV`omn!N`ZN7W8)he+$X# zfA)40H*EbL>~S|pV}W3Q0Ld%h`bG=J2toOMcf-_F0KoO=8JXoObH!$zi@Luh0%e zz_~K~5F3ZvXKZeKMWC*veL6(uVWdv}8O~IN&9S&BSD_`N%-a(`grg~FkiIA-u;2@F z^@x=T6$JjNg~XrQbYGrJ>&D3Q{Ui5qGAshi<~czu{I>vu*y--ddHbq+{f72h+<#z8 zTVBq9g~#;p&yKP)uq%JjEOL_=@ZQ)s0f_HC_>n>eqf(!=GR%h25428tFT3->c;V;A zc~Fw-cU?4A{~34mkG7nz*eo}?^Va@C(b;h#=vv{CY zDq>;${RZ*wD$ADl_-Y$}dCK|w_HleWw2SVg6S2%`0fv8qtI@g5R==r5JH)5uSC*|r z?Jv+bKHVlj3%>q18~|e9kcZpJv1ey8JStv@xROzTNcYWbb$?MNuxdXWz)^OZ;ETTW z%RwZ?e+TcP@7f>B!{NW8J;87LcaM;j$JfXe+Id-f zLlcqW2NY>QLWbS=RzJaexQ$kgLO2fnfc8M9=Dr#nckY)zH;4D@Ti$rR?OcuB9>;|6 znIiT`XJ_>24#!xUjz}VCo`9gc;v~ft?0W{*f2+&?~Mj3X7?N_l4v%Vz2Mha8a2#eDb@HlFbM;EtbkEe>zSo1;ur~=0X_LLst2GHlvc1r?Eytqj`pZ`PiS~O; zho_CUMmTbrw$0YNO0S)Td$=1FzU>&!t2;}Pu|><=!Cm1?9hb$GUeCU)pr)pV5TkJ= zB}g$t44DYaOVl-&MT?Go;MeTU3{0{?r+)Pfd@PPcz?pck+y4(vLCfi37WazFfxR7o z7rJMknJq0}i#+bSGHVDNS_JOeoFu(V$uYrwTa zj`I)!RhbIm{(<*o`#Se0@t-3lX;9b4hd_V-yJXw`qX4gMqU+s&n-e7G=f-w2i1}CP z@vh+hgiqd|$cP}r7no)079Em3y3q}qo^A+qh|X0R40m3xA@=B4=C&G<n&#%go3Jt80 zBh*7zR!2IIXl71Dk~G*UQBr_u;V&VSRPc4KUiqp1|VkX!1 z2eT(n9DvY&EG!Iu=<>h0y^(Q0)D;*#)TzH9!daY~8^YDnpWvJn?8i;-_RBYGn7g~= zc>sZvYZNCWk>qfLGfOgNu3PGIcTTg}vWpDw$C?O2x{QHpAZ&8cY`YjfWakbP;N zbjD!0M!gm%tr3;TDwIKAn^5@?DuX#x8Q)(D+AuL>#mhjsnM>p zT&<}eE+;5i{U#vQt$1W}f6L_p+CXdZ_*X6;HA%phvU*ll7T8I#*sHT3_FTEcf?}B| zW*`8Decw!JlhSB3D2M<3B>W@$P)}RKAyB!gSc~G9+Hidk<$G()C7-cSK#VJ$JXgk* z;-nHMi4e(z5S)NQLDRKs_Q6Z>Q%dj!_o-Ko7o}XOHg%rjf^vFs9};5vOADhPv#Y~- z53ny{V;h>Ax2{=Iyezw_djD;~!w1styvnhth!-e9d7MD@ z8|*EoHeJ-3hN1jb^N9aUs|v{2tX@q!Pk z=#gH;#c(6$uz@|7FTj?JOYzB%&doSBqq|Wp^s5`kfHT|CRF{lC=P!U(e|it~bIjjk zfT{KyZ_NQtt+%*hMJf8%aZFzRM?msT7es@A954Y7t6q0I8@F3qLGBR=xavn#dXOzn z0+Vn*wE4>nZZm{x$f_-d&x_k~W`c>W!DxxVLUqPk=V{tsli85(_YY}aloJP_MEf$# z!-G*=^Ea*!2HSY;?)hYSqx)CPy7F>c$w7@+MBtBia!T{csAE0fF;@T0F#Ie19)J%a z^%#-*?;sIBA!(nYS$(GlV!`r~L)Tt9VB_iPW_ge4t#xQgO%_mIB#p|*RGy!RUWuXR zZ}T$ix}kWkdGi1>u=n5!#t;eoZEv@~^?2jCw7#nL>P2R>G@w=d`;m}@l^J+vdGk%D zh(iu&lT;l{eg7^ima=QLPYqDDuFHkWaiXkvjKl-ecYqbu( z=F2Ag^$9R8=es?ue?qr|@1K9m;=^H^nYGY%iCqQ_(PqO(dQ~O zS8WuZl61OFSLdPm%vdb8Bd3e<5y;~Ia40YS6ezcCFpRz zPm-kp&xGA_TdEuXU%OLfw2%DUx3a0rNAc;R z?X<*jKUd;?n`6hKTvZh**_5X)fiu#E5K)5pK^1o^lGnbnasV4S#!)4XGFvIQb_99o z8)f>Ks*#bh0gD7nb|H|b8nn!fj2cu?Ww#jR`ccYn_!!2MFhMO_Y^s>U`)u;^s|9BP z-Ox`tH5f54h#>W}vbUxrRa4CPE>>Kccw>hULV>5Im@P;!>?~U{?dIkNtjqQk(P?n` zP4GpW8J8|cW@p*GM_>NA7Cb+H5knx7X4)EOXZAc&5~a`t*7;9xFg53SgS#SmCP`6M zajYA^Ql0+ieF;HQs?^HDuHx8+gCBEq(u}Ev36nVS77>Hn_*)GPu{61Fr)Op)6%>fT zV+&-Fk|&DjQ=-+~(TYtQni@8IWJH8E2RF{EyHl8|Ted!!5f4+mp4LCxCObQ!!Z-^T zd5F9|+jSmXW?hF0>oq%Uc6VLTz`QkR_#N@h{YO!vbeytaZOT)R*mD1bD1aC7U*1K< zG*93a^yQlzMk+%;T-<{n^$;;5=t>1^%#ok;P7iqOyn2TP>>fT-9XJ+>3-Axc?6a8- z$8i}R9j&^4Lm{3nQQqxCoe(j;+e4)>`g%5&?O0G=9__|BD6r-{Xh=#Iu3(p8tidNs z7{eZ>x_DzworL&`H|*AJW`5rFhaBCX88zj4fL$26PniDL;~F$gq|0xxR{>xaN9#)M zweWwb)~og(2=(?hqjq4MU??V2R;^H(GO^eF1yXqJ_AsY3g#5*Lr9BKzYTf^H0g5>I zR7YN(YA3bnqvI-r;E3=WUm(r{?X*RLBhmc0V_QYsB;>xRva~h!W{5V$Y+K!O(z+p! zB<|-G&f6MN+#%xz+T@XhwtB4=o3%{8>O5KC$rFjKb-)yRe@oj^$&~KLg!p$4;zS=?NF+C^uZd^ zfW8MR3ygH26r5EZuuT-+=-8Ejp|Bax)q0rlY!8(?*Z1d?OzX`)*$)vm{>kJ*xms-$ zGCFMJq(be#utjQA>#Q>U8E3M|Z;L@AaK?K&fYS$8@hVugb>MaL%23nMvK%c=$Mz_b zw7N)#N?j&etu{c~7de@?JdJ*$!uzgkYH)FLlm2P7ft4v%wE%PhJ^*M|7~V5GBz$!N z3)#ds@c#kece($K|K~ny`o4~wr8yE`!;d+QWRO#nAVI(|<62ZtbEAw-Lhq_(A5s54 zX@{x0fW1qeIe-){$sA{}gqrPSgN80f(2#&c#f}u?d@4_qlOfUiGf|eBf^Fv|Qi}SQ zjB#(=A5Gc|_dy|g?+%9Ee0%{*f*)rS!^X=V3)M>GV0)b5UdMz`+m~rtVR;C{22+Jg zO~4wod%P=6c_zW1`>CLmfI$PWY?9^OFbiyhe(E0Rd}3e9@@1q@;l0AmS8YW?imCco z^9dcHsFsx2ii}2-{`*k>rLQ@8*#Z|XCO>bpqiB{B%hD{8AR7R%kP5#0J8k~JP}DWb zf&Vj>tM*o>ry`RRsNe5ipXEb$lN4CiY!$l_c6qvM8OT8eWosoOp3gh)1?uwarTIsJ z6@MsXZF~`6e?5NkgQ~wNe*9SZR&IDsNx&6H>EO!6tam|ebiF^{cZ8!Xma%rA85ijxiyGr%eqo(y5>*@EV zwfI{44<58{dA+h{3doCrHnv=aUUMA41~%J{{g>_9JUv6>F?KJ#e+)#%9Q`&1#n96~ z2iz1>D;9p|J~-MKvH-7F|C=9s{x|Fp#QEEan$2SRY7cfD?)3A(R2SlvYysPlj6CMR zbIu=(_++u%y#q*W*uEnwF%|Kcb6!eF)~}YqT1Cq&3RAv!n3rH2W)Q&9e|%qfSyZRZ z-e)Y@hE$408`jfHe$q&Wf+TIzaQb~IZ?-b+o&2WOGqk*N8R}fwQnt@gV%xTnr@`7< zI(-t@@pPvKCw@u=T%!JLj^o?roCM9J#fP1B_j4DzF{k!1m26kih@G2n-p*SQIhWs~ z7(a^2#K%;f`^Bn~7p(#Wvubw>{fxP0gt1rGOXufHicx0goXGb$z+d3 z{Cf)&GfIm~o&l_vjr(3R8SMZ$-k#DD7D5wQWGAR!0D3w46Kjgf!=aMfbLABAsb{Ck zGXgx)bVHYsXF`}&ofjpW+s&Ov_Jw7-e8hjQeStmEvOa&NW$D=P1!{n;>qQw+d2BJ50by}htBA=e2d&L zIo=KrSkt3LN(R{!M_qKXam+{2G(|}uaVpX$Wqd>##K*)g!oJE=5KQbj6Qo9&ckds} z$86evZg%1qui7fxs!#e}mo6xT5G$tIpc@@p4ZZ%7K^CDz7!zKjs*X>0D_^Wa|6_Gp zY5thS<7jCR;4v8-?kLrKmn%-+K82!YvitD^a=P9yP@cPD<1^UYqzzDBfMu`26LtMB^m6Gud&T=Urpfb>8<=0rcx1~OBCG6wSc z(R{Pn@e1FH`{n9Y*RMRtabaPhS#|zMoBM(HRwOWJ2K#Ck7yad5vjiN`!Ib?K=yGWk zNa4s+6*(Xm75)5%|05cp{u@6t;Gxdo4Xf(*Qs5~h$kSGSr#ReN86^-iiogo2DL8UH zbes}A^e%*9f>Xg^{*FXpZD)rD|Ju#baFEh-C-}CT$z_er`F_IqcFumm0k1tC3Xv^!T4lVy_Y-Rj#{D%Gs(JB=k_8`sK?P$IOvZV)7FY_gZ18mtQprND?$0P=pi- zepeRE6K!V^myg+{D3)Y=c6GH>vY%F}$#m64Hl#1lfQijiq*A{29e?{dHrRAST8WY- zO2AHO5aC&$4}?ZEQI4|97waOEtpg;drE09nep#p6L`VP(m2L09sik2pgXj=&yL=7! ztOF7lLXxg(IMCbS%PmcVrvVjE1}RcySUbz}B&+3H_rHaTJDUN%vhSbd{EwZLu{On{ z82*2${Lc@JlE*B(r$z4iBb0;F!Q2t*|9Jc19CCdE*n`@py?H{2JZMMz$M08f&NnXx zl`}7@`e^>pe~V)X8#hV*2!(3TmBMr}nhEA70qb2_p6&id^{* z#S=Bp`vV)Tj$`-g9l-AeM!wl(_b0GyPJIe3ym0)FCwK+z{qzJKY)Z+L8CC2aK-d!kweZd}NIIMn9%y?gI z4(qrrS+Dq>v1ST*vTP5{#XC7IK={&+Nk^0^%s#XPR-nhEX>@h{EIbiR{E zsAg!Bf@j}MfT(Ys*Xd$G&*`whqlF2?(yI#EXG$6#f z^4&M688!T#_j^Z==k<4LxbLX@;XIQ~`rKIGWlAc?XGujjkv(iY`%U;V#0PT8;Pj!g zfiZQIS?3S=plT%KxYMzkJyJ4fZ0+yods4H89H+ihD!91qc#&gx64rl1&Mjyl$YWk| zH6G|qx#GsJ7-ns78F1wX6UD`hPjo7M(9rRmRyl^OI5L?5cXRR#aG|b+^9~Z_Eo4j7 z!16WlIgG;@b``=d<&`JUpX{%+K|n+VZvpx;0s=zBFm7e#coC;{k-AuVbb|&}<02uv z_{Z4zXMim&#hkbG6FwS5DXJ1?eOUv8xFdn4`ol;IfC$!lZ%a?`9%u}hvXlD#WyL?@ zv{*7HBy?3Tqe-EP945IzK;S)Y0nPvA>Q4oY&u__;IdW+dN7=lW+>Wo${93xu$Cb?D z%$5xVU&#!roWk8b9hk2 z%~#W?bO=do(}RcZdPi09yY~r~yp3M!_Lr#nHsSVVUe`^)VCe{5>K%s=ri-bTjA@Pb;!@eT>XI6^Wf_0wtYszSh7Q- z&#$UTR%^E@x`4QTxR3`_XgTz5gozoBR&I0Bv%; z*(-T{J+H%1oWhUCwV^Vs|K+{vHzQ1CE;y~qx#WeLjpt&5orV(=x$T)b#Fn#VsfSDF z^b~M}vHaeoh_Sl1i-6VyBt86c3=%B}ZZF6_F50~-C*WUwGgMTe-m}z5BJWlgV2BziH^Nk$Bny^T#*bD*Y)R@XWfsN zBIx2dT_e!K)L$bU{QRTY>sQjkSBL>f1M(j|O8S+%f6`QFclkPX-Xo$rt-8;jEyB+d zIr^Vv=eZm)n3)xJ{L&DCsB3lmvr1G__@D6zpA@aG!@tUz1g}RwqsNdJM0qNqL#TNH zxU60e8u5_M`R?P!cu1}iUEWnu7oI#r@r>%{XW{%8H`{FJoA-AgCLd15Fo|Q|=O%8N zGC@Wc8Qmp9W96BNbYux9wrsX-=4*0 zJ8qUdOe^4%670k+I~FgGWoG6Tq@g>X@in;^>^0uaImVsV+MhHY5r%@k%Y$C~<%LGuc{3IaRD?z0DWw-`(`t9e z(0iVz3nNFDE16~?cy}UkxYP)lItL|WbB)aoMwcmFxy8TB(CmNf`D~#(;Bn(@YU&*= zT|BX=;LY#C*`@-s`qZsIW2~0DRjc}*eieq-GbO^~CBo;{6T%0~LqkIu_+&;6fzLNA z4X;sHyiuA;%oh`vZBtaiiN?Kp!8@ZC6oE;k`fI+-R8V!?`S-1H5uLPJ(?Jx%ScExUpuN~XktPw=wyN4k+;TvH9z~H7+d!jiAFtJ^CmE)F|CeShpR`!_x##S z`C$uY4nGW^=rA(V&MygCsw{wW(fy}_ebHu9wI^hvZhZYm3MKGWYaisy5nh3*T zd8plgXZ7wIlToj-{w+>}u8bwFRr~6%IX%Z6*ZjvjW47&rAv)TtRL|~k@PMb=8vQk$ z2w0l#+Rcfe@;)y&lqxjbt$w_4|Xcbx%QDYcF&kwW&1e_}d!kE~&cPTWh4)I)a+sqh5^OL&S37@&sUK5#F zwa8WTC>XwECIW~4MM{T%UkBAJ$%{Os3=nr}&?x@yy2u7aP>k>AG+5(oBVJD1%;Af) zq&xcFm(SG4pyqp^zY?@(ns~MHrxN1i9qu~87duX8|1(VwN)BzZZql8pOBo>iF~G*j z-5a%2h$-*TeT27EKfU5{YY!$T-Z8I<-g~u#a^vaLAT)Qwe||I#+dw?xcSa8@eN*|t zlhh23?864)rbIwhxDs}|Z}6A-xVgkH(fQtDrK>^e_Ly>bD;ax+cO(PDQ(21FE*a?MK9 zZDbVh|sMW+M;oB67XIY&$G>8WDbL{5@&QX8N^`FjhL5S_xTr zBUUCxitT47ESaEAn(9jnjX^9-Wa>90-wrYRDJqGKm2$>RwpCF6)Rp;@8_pw&Q3o0$ zQ6P?-&Q?Tj^j??wQOzZbA}K13pNuabe=<}caF~@->rKtuD%1{F$9M%>#G3JVV>FldS~WVO6JUVW+*Y-SmA zn82KEJSHyY-55s_byZm9kpGYfVnB5NMr*iDVbucsGl@oc1UQ`L8O>~SSSdr5pF#uS zy$IPbSC}{PKf0swQ3#&KTc_ZgfM?$pfke=_qIQGnI zcJcwO+Ut5O-fI;C?T!a>ez`=B9f^n-I$GZ2+^j!SSp)bA3!|6y!OD-}!*Kosg8-hL zGYqf&7+&6G$F9pbs?n8DJTxD~>xcF3D^!?=O*68cIDzAz2S(kAj(!JoQi0OzL$P!x zpKPl(`6j*Jj7g`xzA;=I188v95Z%K(9fpAMdB@qrPEP&gCXL8>K50GscKpMY^40ug z0O^N$P=aDq^EdnzS1j&gfR`tw&d)Oa^fX79WW4%< zX1_p9!`kN7=1TpBO3rkz+ZEo_R2h;~^wL|dIeYpGbhmv)A(+<00;FbwJkJn%-v zG>LE#)JQ@!)R`_|U*YFpoZR>MwkGo*j* zSIo5XE{5=xm_x@Nt?+52GFZXzfB~cFq3q_nVZH#Ql>;o4u9C<3?DgI|65p=S~ z9v)c+@rULAp81T@8TQ_0c#Fm#Vo+z@ay7M|IAVNh{_ed{M{TpBlH9 znJMP3Kt6z%^pa3#$lEe^WLC>?bdFQGaLP_|Qm83VUEnQ(Jtel?`OXB$wud zmtqIY83j`B@HpLlK_RMUud2ZTn}{lAa71h>ORv`CB>5b6+!W?;A%z_F+O^Tzv!0t_ zYa;JooO!*2uZ%+Q`(5*{6(>Xjc^$)}C;B~sB)g5NP-0Td< zW;LGc!g-KE+{c33{|;eadkPQN{o9fEZ`zpJU_Q*Df%8x7qF)f+hlwJg_hNTMa?+GR zAx0W%Auzn+PFE^Jy&r{pA-%VCHX^6QyfyI#@q$6DBv&7R;N|^(c*~=ETdwOe$>rHm zJDGW#kV5s>@>pzDKlNHU?t1YU@<<9^FMO3-mfC)x{8^4QMQOn9EB6ht2;tK>LgcE^^KUN{!I8| zsahVHV&i#B*%sW*v#Gl{C^;-Ck=j?qDj2;e+2C+WP zjx=A=Oq`d~!k9Tp(dBVP7r5Pf;6%>5YD7zFj8IT)h;t)Ss%HxXZTQOV`FLp!*#woD z4TgV^)i2e32~g+diHmU0%^+h%l(kKRm3?ejFKAgppYg!J8u~6$!T+)MmQ8hSO|)?E zjeBtS;O-vWU4u(-2=1=IA-KD{1$Tlw1b2tvZg=H8=e+g)g};T_g%~zQZ)Bh**YF8~CGQ5E{P<4t{$?gY2VmYock_V6Re3fbFzD@xw8Vgy|d)BM@ELxCA8cIeskF8Napr$CIvc9vZ;^ew?H6)J2VK>)PS&m>%M zERri&n%5eI+W$cS;Vu`Wsy|e78kO3ihm2A-=wB)EWpDLGfWek=W_zv)3)y0lOj0?Ap|O@FHT7ib^+RVt;c4E==w(O^~ ztUg4pf!x<&_+*42ZUhCc#ygNhFi5V(8#08QlA2{``7KGWy5AT!$P#49uBlQsmDeT0 zAx?N5qZUm2TH}r0`kxjc;hF2x=d#fqwZhhHA1*Wz_E;5bS#Vh)*>G11w;pL}Q1pDc zIx{P~SaUMENX|-TesXj9$Bf4z#!;W==po7`ICrCYnRoW@nS!s%=*gh>^wtFcBJv5L0-Uv6aRgGe{;Nt)2|X9 z+qc7JAHwwh5d~r96b{9D16Hv6 zL8e;UfmAZAl;*sv9*YpCZf=avL&d39&6hm`E-}*hn%ZbyYM9`D1Ha=Rr+OJ$e7X>W zp!_B9JuJz?9R);0Ko0PcDfrA)(!vPgwPUhT*YVjNsKwR-an)-#&VM>xVfvy-^y~-f zxt}A)LD#fao*iCO+Ox>C+dBgz@FMs=unayp+csk0MhNTvj)doh%b*ib;`|$C+0JqE zt6yyY3Z6d-wQg~l@{vZ#So1M)FJsp^nZnIk-v4e~c_TsHzGSE9f-qn}6P}?z4H|+J zDIF3H%jknqSrh7k)NBLKaP)~v<|t~Ma1LrfOgdkg4avknY2LOq`--R}c@HL(mbz#_ zO~v%47FNc<0)6pSwSH?H4AGy>z@8hTc5O%`WjSdt@ z6o|QHWrrG?VN{S3)=IFDBiJAR@=hdKLNzpN^2xWfgDt12SfV7m9RcEIu$}!H^fa&Z zG$apPl4{^a_=7>eLzQj(FMHI$l)W-{Y{GKoP=X-IvWS^~Gl^7Of$DNZDD=$84JwJ} z$KvWNQ&CS1ge<%YS98+D|Jk)bHBSiu35V;dd*2|zw+>FFM6vlKLw_#1*-)W)a%|># zzDOT6iLNUl$@rlDqQE6w5=hg9-LdQ%&4$~KzJW^Zp9j^t7zX+T2lyTBIcEf;TJX{fbb`SuHyS+P{vUMfnNl6K5>%pxnF~8`Plb zc`VXuj{2i?-POLodfwL?4Y16xRf6Mlx(Q7DaLdWIr!R z<1{kr#<-4s+yBv0Sfmd&Lp5W!RQgFwq&vlADhVwBL9bqDGxPm^1AqQL?td9uy2q=s zLwRU`@%1=cgX%CKOhPt{YN}@d><3HNkG^H{5JI)K@TqF*FcLArhr>y)i**$YC^04F zT?(;3)Nm5Tv*Glg)HG){{5&o;g$IX*cHp$bSy>9SRq#aKKX(bvB?3cfepeXngogX# zCa79z_B?Z42O0p!Ma;zEc-lt9v(*@vooP`@-kAsPjZcjRP6ZRgRF&pV1(*kZszdro z6sB6r7~CCtp?v3v0wZ<(YLjYZ5eVl5>%19`Eyvdns5+XTpN7b>!*$FJdCHdJIPX-Y`s2s4%Pv&p{I_BWMRio?RC-r@ZzsVXu8})1<17=x?;Q*ZQ+iH8 zDf;)g10Nvb%3h6p)Po$6jOj?FG8hf%Cosccv5kSU?=xScwg`xcSwOg2XETr@h-Ezn zIB$8yEP1v0q^zdY{{+23B#HZErGzsEc0^Qfuyf7Q2`BL6FH<5C#gz;JhHi8ii^cC{ z|6owdAq+l`ve2T(0nCjMsnOhi(jg;W5X$k8+h%1VO(a3dDDOpyk<@1Q1VFrA806?i#z&=`EN*8mZo=K&igM+ zNtaS6Kp_49euZoQ@82XUTMp0qiT=B%6P0DMpz;6BRfUP#SHLp(@6%j-F<9t-%cC%f z50UHN7${BCxC<~o|9$#@|LXsy2gu014wEyt^|I^8khgMDYc~H$yAhfaG61CPZ2*~0 z9tHw9afwL7+5LnPo$sUY%Z@hf$Xo}P0>q?T2Q(2G>iqdP6n(~{IJi3EI6{#?O&LKU zhZaA#830gxR5JkSE@+RkL2KWUv2+Qms}w&^H@Z;O%bE7TX2@k_)Cx7(_42JITETmt zXxQ8w2Nx$$JF}P4Eqxn|Rz&$V+#dxTQaBRKSQvpc!~hb6eU6F>c*0tN?d!vLV*~w9 z_Q^xYf$Xq@DLoSJo}qd!E$2E`wF~OWOFes}A|U@_eUBq%-|T-^x@tBw{xQuCB4c|* zX{rU1tUMDRpR5tRsS@!mWe*HEn1TJ(pAIT1G|NU@R>ykC^UFcSmUvqwgQ$T5*wWep zix9`G;c(awGi*^*XM>xf?^(uEn}I`=G-p4N&Ro)g6R1kP{I${AA~?c!7=#J#NcNx) zByL5;#VM(ohOe+zC5y*S#pa+MV}$-bBtPPqYwerto!n%Cqbo9RpO%;*$3tfzKoja` zlM(b0=)XU0J|FO(XvI8p{k#8eO=dn~-X>mz5Ou+c5KGYwVgpegTeLbEf<#>-<-ukA zIs;IWQc_VJIq?9+bcW-N2S18rUE;z8O6Ar^QL;XSCb_YC!_;D zk|0fCr2(WWCk*#!MuHDf;(>IdAA~Cg%xHum`4S8J!oY|?pfE!(uYf#iY%Pum5Z8fG zl|PEeiwu=NSqOfpx=~n)*j9h8@Ida?KwLo7`TcWDN3`MA^qqcnFj46G9q-1=KJtyg zzfq)=DDf{|IzG_1#}s}lo&>W(kL>p&lS1=wk8x>}BTdSqvtQR(L~z?4cFCXa)|M$= zDP*7PHKS={8~A}#(L;j5N1VboaLW^h3f%qAcmw*B$BIepK-Hy<(=h}+pd1L%m8quLoY_JS*Cdf%&2=S zqc0R&6`Kqgn+ou+FJC!I7f-Os{vx%)U3X!vq`)bW$Wr;$oto^fX z$PbaKm7m6lbOilU>{7$Qgh8EYkErD`AJygXmk+;v1=SsP5*2^hn_8i7s3F+1k2&ZN z-0j;E^|I-DuGB$#hyMRwMjWugTOO8VvPGL$3TG`ehzLA72q(DvK>!f!o&`o5%$*?C zY16CQsp@==ZNVA97VXfZ3i6{h9t{iYN2JKLB!sOEAeGzM|4~PGIiZ9xU>r^Vp$94w zWU3T@z#V0lpxuFlM*BHl8`nI5E0k7-IE2z736LK2JWt6=Eh}44!9D@jDve78g_!jCzz_I+HSIRW9_C5sCd1*-5gg%GhXuk%Y;kL0h zo_X1-<4R@BbIO04{`22*@jI}wfir6W8YP+{kjIl3>Q&ELHloA{cgGdsNI3^|9R@x& z#f#_rhi!hr(UJA)RvaG=Gv7f07e}y21Fqa(NGlQ2_bZtgpAsjUojwM4A6Xx;QH0l$YrP`pC@-0fxWzGB=^nUtx5Nr87aexpkzP0V zV{@}YtwfJD-hL%tr<~Av?8BE!h+tcXlF%V=zYzaAY<}wA7OupfL2~@M_a9#1Uvh#D ziC4VVXPwwh|8fo__^KQPlV)v}PSYw-N81E{KYcygo5 z_34e?fEZT6I*-6qm-Mt+NH8psA2(8Jno2gjsDby<^2IVqMJ8I(@#KkO{*6s#RVeY6 zeKHr94l~+OnY^ywo^W)qakRwaDHGSpNH*IgBEP&CsrCfk5D5z9FB$cPpkIiC1Y%wH zQ!-PFs3XMWXs(3^UKT@Hecjou6Nf_Z;Jc1PsjqXzDuiIs0`oTcb1g@;yzrS7nU%-Y zF5kk+P5(!7D<2OR0Eg8K+M;r3crd}rnJ9QxsAMT0qAKL|FeFjn4roM(F>$QrQNhv1 z4Aet0A;4NqV`4w78>3c01op^?5E9>0%o?RgDx1Me@H<3eWaVljT3OFaqm_6{z!exd zWFm!Mv(4ga#VhY3&G0Zt*_+DC@Fh}o7##7CSVY&HcN0d)hc4THuTUCtbz}htlb}I~ zq#*uHj4f5dnFbluez8l4JGxN+ZI;{VOHMKtodSWn2Vbiro(jyJ@DT|%0yL_=jSjaL z?MN?4Sy47CB=Y)LwKKD-8kX7=DtMj!p(RKSgl>ltK-PkN*sq=lY1}Q@E&0JqR~MZx z%zf-a^pV-zD5DuJZz0n7}Z>3g*cF-0^qY|VB$rwDnhuZ`hJ-54ReIp zR)@kPSs6J)^(z)+9>_Ykjyds;Jq4f%UuDdBj<5}|X(P}C$9PPTMEqi8&=bt;tfEK!CkeOYw~@JVhBLW51FLj;`0i~( z4>uUVIT~fT=_TX_OzgvNF+CvALMtY6i;Bv94q9s?G96EIX48?Qyd&!O3?)~4K-qqW zB>FYlZQT~iiPIN_TfSIHMxZxgJ*gDG)gLzxu>cpfk3zdxVeC;Ch)9z^Dlu#s5+43K zCO?k!i8C7G6J5rJ!^1gLU4?juUh&GAvO0w7b6FY+U#&Ko>iypHJZa!_skUwJ=J2Qg zt%W(ILQ(N~=4Pfb1A9^icxZKzq{2Yqd=enezK)Z@PbPOKt#-ajhdDqK3>FghK{K006U(z@zV6@P4RC!> zp*;H^GpR$%DoHr_5UK$FTN^m5>QB*>nj%ui0Y}>oNw94m9UDUcfESw#4csr@F9qxY zWK1im#vA=yKWp9i#4ZZ@-3d5q-G~%M%$IG7%*?eq%n&W|BSG;(Fgm`aoUOOHBj6JnFCa#P2`Yj`qV5RoHO@4U6IQP_ zbd)f{mHp!#HV0R(z=v5uQ4pfnHlDS_F{|>7^M#`~1kvi^r}4^N=u(FjjF^DTCurE( zj($(y6zQnoYR~t&0pYO5B=Pd_@wyi2#n3VeimDyudcl4Vg?35q{V?@Bxk`{1oRpnGL z|7nSI5*FOlUUqz3xdn~cVJDP03|UewXexVStL*u{XLj7NsHnJ>!*pOoZ4TFY`HUk| zJ``vr97Q8Guz{m&8ju8$Lqkd^?XsoQ@AKH)ovw}Qwjq)}pis+500@DfSE71$01jb3 z_lE~Z1>yD_x_XWKEy~(uXzIE*a^pIfIw$^UD4vs9acUYqm6VEy`*3uqE3<%rR6IF= ziz2zbZU=LC0v{KCC{o~ue)Qlv;Hq(DiSF)QrB0nz?_N(80SrmrmO2CT%ayFFX6m9qcWE`=7Q}PRxRUL7tMeGRSeFSaXqD z;qIQQ;I!a4CfCZDFRQ(+pl8FAi}y%)-BGb#xnz1K%o2-0WRpl{of!l9;8cwr1tX1$ zi)(gxA<%L=*6&1~3wF=V&BZO&jci{Sck&qPX(a*Ds}BgDIJT28c=dZwg#v~k(P27p z`;IY3f4;xLfO-;^c}m%VQpKY~k8Wx@_Fp2xIq@F}3E!l}0$!kV^;9-utpNv2tSTnX zt6v|l1WKT!NF0_EFF^o28?JL2AlcE3C&y9soU_!bAm!phRoE|=kcoM81#5l64x6^~gl=1isd3-wY9p3z z=)@RgJV=XF7N5^ANUOpGBfK!qU3a?Av$^E;z@B6%m!7tBgaCTQxO}mb$oj^P^{Z=X zQw{b3Dv{B1IP>XBV`yN^pTc>|I7q|R3j;Lkc!S8p6s5oMl%M2%?@QO%y7zPRy&)iB zw0zsV7j$Yz7Nv29#I-Lmt}0m;$?+BW5{zdggiyqj>LO6(bCz9kf0f~(-se6!wu)bW z#saO!jOfw$>A zcPv*;hC5aPIGXTh#xXWF4qPCxI@`t)pnGAP*urjzp#up#Wiza{%v4t~_y4HrbaFfY zRToJ*nabxD>yZ@TI)$7ko1tb@8I>FRx3-x>KJ0-Z+?=r6aBfEqbet48a3cy(KK7i# z0m9EoYdl&Ev%v_VoW7B_d`>@fjI;k7Y-%%kkDsF^tW!h)ixl>G;}SpXu)kh9H*AZx zIE_en?C&5&o-5nXF`>0yMgFM!@3ARCqddno+i zQw%_+-I5{;mecsSW@l;aY?iPb7?EsNbadb3TCBuI7|PlbLo5V@_csn{3;J(6T&KyB4nV$lQbgGWU!$D%u5# zSNAj80Xm?~(QNjh2oJ|3>HtC}nsuf85`9S{Zo|QHqG>waI5weH2yCp@sAB%$pS3nr z@xQFhG651HA2u!h(>2SX>yMkz?+jV)Gj@n@J$`NoXtZBty$Foiqr%HQ0*7#c;cxi} zF>Dr-vOA&`yM97SySrlHzabf+H`q-Yc?Piqz9y9cPpy<{=>4T0+3{|nK4xjhd+WRY z?xOF`BJeX!p^yFF4a*>h78%;wh@CuJN0VCHVChUgnquin9Yuo8q!p0v5Jn4Yn#0fg z9jae6U){KZ{j+#RzTxL??D+nflUo$j<6E9eb#x@zEr5SYs=LW>+}EO34uO--d>g=%xP{+=!mZekG;rkE7H1>i_Jx935@6$4Rc_h0EDxnO7)f(C$tJ zB$EmYETFNk@&LvF&{bTuOLV9cS%;U-TXG$g=NLQWOuwURqS&i0!qyTDL{w^j4f0df z`ASC`LO!b5VaT7kL}Pi&vvx=4--5PK1SW}MRjVcL{WT?zdiWYYp{Eockb%OU{ zIQwaMs6#Kl|9)x&la?DWVCBA!tmHdbn%qxRk>`e%c$`~2xox?w;{Dt6)^fe#T6aI) z0f<}s$io2?%%0(K{4vXA-JNe|C~J5DaJM-gy5{tKZjN~#Jr21&0fs9;oGerx^cD+d zerIS+nFW;LL7|pMo@XceLx7ZS16qIMrV$Tl0XS3gT|G**uzlMfe|cVf%Yiq!_`ggqqGdj!^C1f3vlo?y!9mwBuP|E13p+$}SXIPhU^K8+RV(5#N>Hlg`*`<+G+G_qdblM_eVt1^8FRQQO_z#5YHQ}l zR=DaQy)F`~ zh-J`|7>OtvLw^25@^txAwDzagj2-`wa2Mc#m8<8!F5saAec`>2rNkLGOGrJUXv zZ1W(8o$a$xkRD^PlY@OJBrv}CuZyBf+xYI>SgnUA0jH@}oz=aq%h~!kf$JJ~%L~9Z zj(e`ZqWMCO{-*^Xpyg!usLT>gJ>;GcxI6Kq*Hca8M{U}N-h4qf>)X-NB zT#56d{t(gIB@r__|82@S5k67qiro$?rx&yzZFPIRYv)d8hWj9n#BEDb+QwtY#@^DT z#~m|&5C3wfv>c?+d>ft%Jcrz^!3R(vC5!?dCbSx4>+w=N(9uDAz$ZMJTh%Dt#A6^ zSg}E^Zm}m@;lJ{nYvv1UDF&cw{I&Ck>o93GJ8bFK@(ch0S^>3`tnS`-RupL_STy`W z&CfxBFvu+Y1c6aAkNHnY9-p314+KWXo4pdcoiew_5pn)H3U_S$?U+H|gVKU3muDm1h7h}d}R z*w~tU+g0%W8ZgLv-kxyZdEOCNE%9vM`!~(|Mb#(bk)w4(ATOC7S^=C+&Yi{V154A))8LX4LI>5;F)j9H1 zRLcdU0Yw=VH0B!_wDx-Ww5{Z15+ zG1#NOexU$u8128@ozC@e$3J%14!^yktDQ(q^zT9f6!Kcz9kY)C_<1Pvwx-WEEQZ*` z+%DVta|@~%WZb}sA=bpQrrTq$qVY6iC@ELC)t7qh!HD^Ctqvc4ph4IG@t*(ULw$X{ z379fODQsc~Vb$2B018SZ=99ut>Im%Cm)I9@IQz5j)q9Ph+|!`-*(|I2_ii8C&OI}M z%Ps+K>?#j?uZ-r-GkULmm25+&rNdf*-5sNEmhsJi^VnZg)$a^~uMM*;cLR&xfHomk zj;4(E6=Sb&8FuSltnW9az9ud%NMS#S&b>E0YX>jtk~>dJh|X#CFQoyEwP43#oo!p+ z?i~63nlI7&)lc6oKq5%sbzYzSOxNaezU}*RnGL8Bz@wl4bj4)9 z2XkHk>Eh!TpM_MNpT}hf^|oi)mbbV&J3FgBLj{oNZMpof^8>{2NjVOX=!nSM2#b0wKXm~46nr!{ z04i{jgwjBz$ZU~{yU`P!uzx!D7#O^_;9IVSs`p0qpW)U@A$|+t`&l5gaLtnnRg4+< z(8pe9ExF)@v9g4Ogr=m}?s(@U3QeB?6Nr%HHQTaA89O3PlXZLf0p$?c3ZcPHh;s_v z&bpm%vUiLCoB)a}@qR1*IUNO3q-0+&tS1QIpG~Bq=;)b@U{>sn zPb9mwzc(h$@S5$Lx$kaukT>-}07={M)g#O0ZD}suS=I=fP+R<)h{(}0TN({846A@z z=I)&L*QqSb0eI*~OS+8aTBbwEcoU@-R1s{iGZA7*11G0QxpdC@Z{xTCKR$a@=Xt;o z0PolH9RJf6>ku)l42l?;s5;%l}z_*K|qeVBqOXQ2007g1mQzvR2NHQ+8+Z-D_hYJ8?BueIm$QxS?eC0cdvs0USPEruC=01Jl}!Zt9&rgW{SvhNhMEJ`J$^e01m>SSPeQq5LzE^2FSn@~A_ zZg=YtKE2p(Ar1i-|Bo`E7Xh4b9F9#tfsVdY+(PXbjq^6{#HjXMyH=CM} z7&T41g7x}zw^zk`zF(jsFKz4jeD?nBQp|V7Or&gO`f^X9FpVJ1+I5bI zn3Z0)SgKwv{v+3nwNH?c<)_w~aARXFo|&53JO}Gp@kTb?rU2AMt*2S#x~DseDf;XV z@kq#7azR==etZh$4L=%(PhKUTM8FDyKS9|hi>=B6ib1!))CVs;i5n(a$WI}rJJ)X1 zU+UB9u2>-BQwWVi!Mwxg7i&$nM2?S-Q6yDKfY&j;=O*)+Oz8zo(BF?pXJqgYmFg2& z?$GeB2?u2j`#cFgTjVB48eyY+nlfVq+$bZhkN#sH9-$r|+LunJ%wewJjat?SRprE{ zF%&TZgc(^5^NlizX2XnE(5e@s%BUf|ePq{2vm}Wz3YB&>i5jP!rm2GL8TRq2!7`O= zJ0OaB@h6}^3oL;JK?1$a1p6jjI>+U_@Upqmu|DMAjv=9Ge#u;s{XZa#yL z*2RkCO;Ou6>_F7f*PqmU!RE79yo!F$qxfE0S#INMSWkcPxxQ`U1NxBMq2lUS5haW_ z_cKJVyQN~Oz)37UFMk<^R=4j=7-JJ7`)|W4Tzd^FkGG5ZU~YT!8V@I>zGqBzRO3lQ z(BLp%XzeRBe+E!xd5|tmOir4Q?9ybuA#nkTQLE8|9hvXu!zSIKzWc3ORqOT$L*~JP zcmfkL)9rXE{%tZD_i0Vv+pbpOV?B1u^~5TRk5QX9@ajhlB?ytahp94G4d2-;W~@63 zprYB*2`r=#U`c2$;ledgTY_PlH@+K&)-Ws5;lfn#><^A0g-k0mz%ANA4@e*-#Q+66iy$(81Gs>d4m?cL`L8p?jC}_wiQqFy zAWQ^`h&-AU+XPLv5C*zcVL^tN5SzmmjBtO*74QLOu0m$9&m7{}PAP6ct@VL`DD1kK0&;h^zgA?F5o$d6GtTxfKC zlIjMvg=8Vr$9L}Lav3<8J>KSiDxYm!%&&G5nn>#_1q4NF3)kYTK^s=-sBD*Za1p z;4ngF;*`yi*}qZ`GJdSyjnz*!(Aqb6o#}hLiHV=`2Gm`BE0Xg~VC;MdFda=+QdI2D zbX^^=Z9855gP%7|&DxpObD;0l19;qMX=zIf8-lILwAN3qdpdT%!B~I8Obbzj$o782 zsW+Q6>v?%h)KJZ#hU53V%kg~&!>@UNJLNPIWMO6DZS0B>cnj-#_4c-07&`au_XC5N za?Y&odP|$^e8~WY1S++bVI&t#7uyMnpVlJ};d@(`&xa<_>ra?x`;KVn`^s4yNtcyd zQGYrf-0Ts><~9<1`}Tke8R#!RK3-U;2Mt?j)m6Tp!oyzpI(cII`_L((3+R_q+3*Uy zih%o&<-5hrfX^RdAYL>7Myp=6nInoU-&EasWm(n!5`h#mTjz9j!&%%+BP-wO3-_M- zl5O%l#C`p1WX!0i7fLqsj#BXD0-{`_x=6pvhwrvOAyYtuXY_Y@_0}KHbEzh(br<-y z^V(-K)R_Ef>W#^#tjW%Y$n2z-{*f7FRkd7=>U9KMuCPF4zOb#n(49-S<+aHj1%a$9 zg2i~1HxFs)XaC`Q$5ZAZ7cRk-rbnMUy3Us?8MDbOz&)Jy(v9!ta5^woG{k=M4W{m1 z&(m&Ga298TcI0v6{cY&J-u!ZuQBXx)Prli9?QpsSMid%(YcmkpEIGGts^R8}R4$Fp zm+;6g2iV+la2UA;WK5_jA_Fzu2j6zCJZkCT&T(Ds4VeVk>F9C6I_51tQm#^w@(t=ZB#h@q| z6%<(bm4@y*)TmOjh_dYkHfykH$;kQgMa3E3n2G?tGAoga^0J(g5}1f019-fFlibeS zq~p48;5cBUTTDr&n<)?)kI>+4GD$(R5xBJ4rU0#a^Xn^G#@T!cWZS2MD17H#rOahl$Gl5y z!LdjG@Mc+)w_YgVt9nX3W2yR%8}F~_4xI1brw?MpLBix{TRovf+qn{i%LcOEqWpsI zSMYZ7o(Wm}l+5lkCN3M!%}57%4Pl#K$BE2TfS`z_@4>t@F*3GH{vJ6NDJ%bcVj&A` zyv+r%gMN?WPzq~OtW z(P=g|F^8wrkGbroDQfd2l$w+vz^$)`iM&ab35`;mPq-l0zib4~vW#|Gck`+x>@z8L zQTXHu#pdmnx~lbT@7diz4UA@XIAe-_iFn>R5ATGE~>WvsHS(0o;qrX$aA!q6`x+K&tTUJ}x5Mz#erLhyMbj3`+@Ru#hs2hSY z(+X1)_NY=MQFa&3phV>jIT>wHpNxEB+J;rlMT3_JAKDJ;Lq!V-kBY)*+UX}DSN5Z@ zRutky-*u(Ud6$R4VRO>(xI2;{Cc|6#sH(B3tfT~(h0TA)BSo2I7BTE?bS5WNqU*Ca zK@>B9KT?gcxLNp$#z4-Z^=&~ad`Wok^0o2mZoqQSVSgsDbtmD zpPN4~I{#@su(c(8uSR6x<272EDb%&!f~t(bqj$eLqDnBlI%7T`a;G^%eUAQJ!p+X? zwn?n#x!1VcML(XQ2C5ZyPA2kwsh!<1f4_hLmYYLF%k*a*0Tg9vLhl!5hKH3D#QvxS zx4lLU9CkA{OeH|?p6?z?MUHW&(dLEC3NY70s%QqGo&VQEv zUct}3CLQ<7LM#gqyZzFS0 zfx|^lXhFk)P5;j(Znv#MEKU^8G{sh~PtX~Y8;Fbg3VMH@!lDkce50#%Kowtt6XS>P z6%5A)uw0Hk-KV$3GI*c(2tBtiIiP&x9ODu)6J8c^$FnsW?*^KyJD(zEC%8J)9P%kP zeD3MZGrTG5aiNy)fW@TiF#ba}jipqji<#BjXZ(^XyBpc@!09(9kP|H4Kr^WL79702 z4T^MBYQ0Q0*15T~0nip`ifdthSZknMYTPtZ5IdWqin_eZ{W>)vGPwT=9x)+2x`HNo zB(-oeyqFTT&MWI>of_l~7vb#Sobll_*HVuxcn^ZEvvW&9forwE&3PAD5`8HhqXZmO z@(@Ill*nQ&Mk<0ZN|dPz{U~5*N*YJ}F(%gnwi4Cs-4x;ar0cL5Wj4(c-` zjRS=T2~%VA)@6Xu$q1>G^cDDUp~ywzqBlYU&=G)S&`Fl31ZjzIWLtqU8{{aQ{E>Uz z`<-9CS})T&+k1bBKwL=H+ws%=+jFPM%FZRQRI$GO>VZ*FRgFXma8^43M)E1RKTJzZ zITQGC7IpS)3J2nNzm>>Op11nyWqWz`I#Ai~qDla%3N*^5)#=4u-TnmUm=60wg2i!vEb-_4=~Dgd_0lpnpPQug^Yc-Pt)IOF7;qg)o?}+C+uOZFwopcs81_=lv!xU2 zF^2E@l+{m#<)NV~YjA@1k1P{wpd@uaP{6vq1s|x8x=^n2#BmlY7|ZVjSp1I71x(ROghx>)bo=&fwx{%-c*Oc74 z#(U?h%JN1Nb=QkItHnsc?oJlJN8O5T8!7^HX=SCD%6p2;_;#L=ZRe#~Rp(vWZqsG6 zyutE`or}9#J`m2?C@5eyBWL9gO2}gJ3R)mXn`m_ELz>s$80|V<)$1mK!w3JNv#pnF z4z>n-;LRkSpCs#h2fw?{zRNTfcM3GlW|u$0@3Zc2!zUaF0*0O$BMw9OGWYR+4#fkm z*iG97ZV?4u9z?st+go;tk}v+OoHto%d%g!E14D9%s8-fwq+1SqyJ~?ej!TV`V#75A zCMNJ*uh!F9@*No0Vkhgl(AdePXI0rJP|Br^%WH2+)-NepQVLQFCsmr-O7ch77dD*7U$1Wvj7)|LaO@`86$xZuS@%GFC`; zQS0rR#pB0KUQ5oe@VTkJluJk)Ev*L#AC^_0yolkl4QY!K`1~BBbdFZroD*o+zHc*% z7*J|zAQLlXRb3GuAFw6vpDo@#EOjh#$|&=>Rjnbdt=h7ELa1=R(MW7ae*|$ zWA*-m_h)1P8z_w2ZFwRcJnTf9pWZHBtv{brH2XeG!@TUo`!=*zD{_7I7WJ;a4%S4^TvW_R-Um?gHja zvH)NNC@h%v_`IJ|i#eAKZcpnc_6PCai2Q}hQdoiCW_VnczMP$7Q9&WjvL(bY;yR)( zMs>IZULWT`AaA!A$Ls(Vp=?%Qw$~LbFd85qC~s^g^7ppeXrZEk`JqJ(&rPf`(I99D z1Uwct8r|_!&PC>~^?-Jyr~C8Cp!A{o^Uh}%i!uez4Eq<@_V*qbubZxz4?~hy02bU2 zIjK4~FgZwNwPSEyb9AlC{E-UqRss#ePRkR#XZ<9h_`Sdu8ZFe&OM203xsBFYa-8Jn zSVAu*6UjwcT(kdj<(5`-IrWNc8{5kUHBUKU$QlEMWFCnUouX!Mt`>Yw!gX z?HLk;p5#mG?!}pIe^L*q>8NGb?sIyE&ohtgxGhA1^bUlrISyaOR@^=&YFazqAD7J= zJ~9GtTcJdnTCH{CotvPqUoM|-*DB6a-xiz-5;NR-!%yoM*E4bN&+a!a7koEFq=$#8 zvc~lKLS6YlR6OQSIZ0!4MPrS$Bv6zqYTz=JYeTg^naxnU1KV1xU@Jf&o0DC_Xha zSWRD|grPTpXg|SM2uXRd^iz3vgSG4mWfs%nS}`N7#*aF$N4OwG*auc-IVo~9(XX~F z*H^G+rtz8SfkP)GRGi5Hy|xct0tmCvVm%)}`+C1FZ)rdo{T30C z?%jr4-{;YEWFTSk!1(H2&Mb7Dx1sI)yz`Yoj2PQ{jNDR&6;4#KeY! zt+m`A#iM+WFR7MXv%Pue@3$m~PjSqp+U;5F0aeAHJ;Z>POz3Q|R<#oNr86-l|{aAtTa+rHs`%Kv7`K~;INXl6xo3?6u zyk;0mFzD^NF}kP0Jy-?6hNHJ(zPAhGE>D3<=GV%jmzPn-;XC>rs-}}kmgDy8R9;tG zmYLl>4ZZy`+A3@I86(^8Yze-)S1|xcrUdr~7)*uD^6D<>qIDa2f8(>|Mtrwl!kNcy zbxx+C-h!_WDo=Mu*KPZ3=Igrhg4Z`D&p$Nu4UettoZM{Rm=0h73(LqvhuI?elPNEc zJLG!qom19?vt)hu)OUH$?}nLdunGxgIwbV=1xu$Ok{Wu58bu6$49bXDc^Wlhu-|B( zj(xHJ(*hunFsX8)=AtaDzFeJDJ2C!|S7(Bufdu5~%YZpmkWf7$sk7SeS`;`Rx|Lp} zlCJ_kg8n4ZkB|K_Fp%fa`a>s#^8ILccP}pU#{kk=TfR0AW+81!d8Nfo$_MKV7UC#F z_#%tEGFxB`&rC=-mbR?g8pUBZQBJ8MvZ9JM(py^ul;yUt6%=t9!NP^uo*{_>;ImB?eSp62 zSRvxT$VlR}vfQuHmlodCvZB;M(_9CdbmClS&IK?Q`9n_IaZI&}AQc5a(_Cr;*r7gA zH4KSj6gg6fe9dW1v?lk*rKBTjISc-&M)(kV|7@SP)C2{aS9v!pgbhap+qOLpmt}`y zq~|0j#;u8!#bRQ7uPI@IXq?(f0V#h7gWEKAJPLa!Cym-kB;JBmZd*okUfl0R4G@_X zCbjGd+4`{DCT;nSYHDgo+z(R)-C&AJO4C)bQyDukyq$f#`F$Y> zg}(1^G(Ip`(S);x{k=Y9;zbR~jQZ=gzKvRt5)x{R97)T|s*LDeUDt7HmD6=-Qe5r8 z{GLTUR+swkcyc#?=F@%kTp>84+PHt(^wOid-xg|IJim5XZCqn9{GDAheD@cq`NQD< z-U5;xchZqv7eK3efp-rP`HlgHDcEfGo9Af?GEQF(rl}U-sRCh;wyTTZ8v7g$vVDD| zKaFeXdk@f1W!DLJB^}s1I5@ODkB^LP|IUxu3PjFiOZmzsP4{u7q@>p-{C>mNH_+z1 zc6vguY+^H6>8y6Htr(v53X|{#X+Fsoh~5&={9}-KQvus zP#w|IOb8Yv*u~u?xVyUqhv328-GjSZ@Zj!nad&rj_W;5D+r0NZsyy zUGj=H1k-_XeX^IMBj|}YC()EFKP`TJhkK}Fv48fyIa|jS`?+~IaDGe78nr{Peg)}Y z%r5|j>In|i|2;_3x5J&I5GY9|-NUHB#!*UAZH-1uF3$T+#G1~7%-cSXz8vC1Oc)VA~aFwCwUbP5PQFZk#k1icHui2$|2$Si4e%frm zVa>OgOhy~wqNm%FbslOvKp_`MxXRGAA~B$y=+&Rm4QWRW?CVfl&bRMjR&L%NSj?M$ zh7ayS>fqx_MH8^K%nm->wc0AL4B{_xWyiGNt$ZzbJ*}#M$D>1}?eNRs{(gZtA{%SHUR+`Ght>IGl^VAb)0(_V5sCVjF}9ea z$2zW^OVYQw-R!r;S@-umqvwch9L|)!F@gk zY>&(FMwV9Xt?%_l_TiJW=DvLG%7@F<#3I8ZW76W-blPpjs(z$ZVq}Xu{W9F3Day$7 zspHM$N-|^wyK&XU`o|X}N1v?-hE7TF>M4BeG88|31@_oV?e1yL!qbw=;QWy$--e6V zYm&(``F}#Kq*ymI9c6>iuO(rjI3n8P;?Jm7P%2eO+CD1%0gLC|lKdn>jmm*7 z7Ew?GCufO4LHcW$r3IVgM16IKsz!mZ8Woie)5i%URpj-f)z$>%z*=b;z(Z-7Eh!-n zjrF-S4}YZ<0a;&vK{jca4{$-t+~HNde> z8N>HRmGH)Qj6{vS#4K!LNN=(tBVzVVrk9^D$JR+|Wg&EM7teL)D)YqiMp5D#NL=6k z7}`*uF_&Mv&ZXftK6&v&BjL@J*aNko(#oioRN0D(Xhd;E6xT)D#)O!((VnO;pD3YW1SiaO{XFoi}CS!Cu#5zI5Hi^8Jf1T3R8K*%VQSIcu5D z3@uI>m*<}v)9}eDo%;R?xMCDmi=0Mo$$4F?}gl z8jF*z?5Go$UBxz|G8ENzyIcn2g!{ox)pX^e5WS3&eTIE``nfrb9=ySc?7}s;L9hyd%_MQq zPUyF&Q*<$!A3`%;`P6a+_S&O6RB|1-a>fSu35vMp+^VK$*0O6&m;Uh0j|1tN-V?R7 zIKqgDm74wkjw{j_K7aExmBl&6r(AfqlNw5{t)HK`z02*W#(?B@wCz!#*6fNztx7{~ ze`N&G;kgmCrg=g_nM3)OpK8T_<8}hEGCSP=JfM>NeXe}YjuyjkPzb+>r$Jm|8bMB_ zyyC~fSSqb{eQ3W7hO(mK#L9@Y0WJ#ujYKu|u}%D4r!UC3y=&XS*&0$prly}Ua|qHJ=p?Rm9R$H3_Plui}i1EdEl`kFFntg9sd&S#Us z0xGH=6nGWY-dZ}^jG-_6E=odHAY_ZYq=LR8n(x7gGZ0^ebZ#}*2+*r!h*?-d8IZ~H zigEeB{HFaXS?+~@wc??mElF(#%N7entXK@CG=wGl56;erP-#^2{cddYGXZzQq! z^odk3mFCk_aXt<@D91`JHSzi6PGb?oz>G3qdGLuM;L0-w_{SRrBjC%*S)=!ylYC{s z#7FNxhsxRc`!qB;+*c$ioC9t599!yta;1P@Dv`$C9_~5g+7(@1QUR3`%y88EmCOZ8 zyU>pUD!h=yI+RkDR$reY7pvtP>zZJ3M;3tL5=7Jx0a?9oM8;W$%RSncAouNkO!v!en1lg$txw&Nb90d`Pb~uG6zMSszJ`j8 zxtp26Q>e47%F=~z1j5^QlLhmZ3zt)*NLMqX49>$>VCXanJFBss29~{gNx}%xTF=9 z>0{|U;VbIs%#uHAs5e)RA5QQcYOAR3gL!P_!>xec?g3Ev0aqq}@BLarz!%<7kuUs- zewmWwtMOReZm@&+o_O*C*Q|}}_B@5=_QRX>e`;SZS|>X)@3br?LQ$TX0K5g4&!+SB z&am^9-A5Z(Q>g!0QxZ7bJ+(CmXrr}^K(|#j)1eI9CEkrn6HYhXW|MD>dT9yU2=g^( z7lS+Q$$74syg6w7vKg{r-V$YRdt}HYB&T(Ec{*QT2b~~0b z9bIQj3+z9us;2zo_r9HNa9U=KJT;5J47JY&p7rUR*Rd z;!Z2fabH6?T22Sjo`~`@S%{Ae0F2vk6h|Jmxj`U2oohK@DP%Mf%Zxlmf2m{ z6!A1C6Bx_v-F&}t1z1vrRt&UMMweUN0N7oC1;zi~bFIT(C6I7{f~S+2J2Ug)=3ZR4 zLM#1g1MDi>}6jX#AJ}rHz|Jgfy-$@5rZu%TSqh~ zT>AC+)|7!;|B$(#uSi=-i@N&-DSEkJ`gt#>g|p?cG`@7tcW=Vyi%tP`9s7Cll<2oQ z1yE4BO;em1*$7Z|kLcX5iG6cnFKWEz$po-ry7c<4IFq_OXcgo3&}Mmw@N^-PX6NU6N+#xI2U4^ZurKS2tDG* zBvBg8WlB|HVIf3HE;1rpwTClx^YXG;+HcPo1229C50jrSYY09XwZBGAXk74Ee`YeX zJY0ov^$F{P#QJxyiGk_&0y~t?L2=1Zh0RBeyC3ebIyium_&YePkQ$T>LP2CxP+t9z z+*jZsIE^fv+oBDd0-qvde3&T{ss$b79E5d+C6>zd&~DR4MfTy?9_6y7W`}8Hp*+{> z(P0OXIF|{39r6lM0z@3Q3b$gMui(R#+j!)V|vF=|#)J;e8HmOT-XJ&9?T-BrB-vNw}!Fz>qe6^U;c< znLxm4J8pin&Vgks;By*MAh2$+Zi%Z;no&^Go!F%B2t7%=bqyGdB^~&7sq;hE$i8ob-Y2(opDy;fBlnD98ejj?l3PD|oKk|M^3Nglp z31E@oRZ5VZ94&Nm@U>tn>*^;=;YzBA7t?A*k*i9(EPeJRN@zmqU+^LWrJtl(@X|a$ zq!zO!NzRfHa9nw;-)!VyrY>_C86O&?VqCc;rj0lQeMMuy8@{$YV`t}&)5Us<^S zTyB#JYa{Ob`9~-fkctem+n`@xFJj==vJ!1YY5UH%JvY8Ux&Sv;gyi9sk%n^3cAR;z z5DmaG2|p3-g2mOxbz==Wi~NwI$>Geo<6p{6P42QA6r6~<3Rb4)jW5tCkX_yYZBNfh z5LM%nvZlT8(mHx`ha>k~{rRo&_MGhNeH}8L=Xnomd;*WHb)g8Pm45iSdw(@~YP)2C z!3^*{xi5)y-L8W6z}Y@eVcvHehw>Togo6M>M0v&2TGV}G0u}b*>d|YMDznEXNQZ#> z?-E)}K`8FMd>R0nyHqNTE<~5IUvC}lOlrt`+(+GBCYYuek6mt_X%!>`xAENM#$tLDe#k8IK$jh!ctyQEXhw#OLg`a1YTR4 zD-~MS(CBPswUKaZ*ZoHl1A6RRBcoMBAh;{QG>7^1ywT0@1b5iy{&lmHdWd1kf`qtD zm*E~5!=}vkVCF%>YZB5p_{WUkv%*&&HwRPa?_+7KB>U-;**&&>2Map73)-V`ptp7N z*20H}k~>A(A^!O-Euw?C(a}CMK0&f|ub}Wa`}{MJRgf8HB*T%gD%2;JlMrk8z*2n~#Hvj>8ygBS@<)}5G6QFKa>QGG2lxm^ z1Y9}i?Y|GyCmRX5S?yus!lI?>ii&CzUp~3y7J@NmS*M*dPf7u}no5l%+9KVJ4Y6Ov z?)lU2=9=m&&)09Dkosv5qP`3xotLgag9moR!8kxv`T2wKCpA<{C8-r|*bJ2t=LWX0 zCM~agwK4RQI)p(EVuYF9)xHo z%SvZnpduRw&ZN~l_?5f^%Cax~RhxaDj)QG}-&<@GS=bRoOinjM+s>P9Cb z+;}JI&1d7!MUeQMT2VNWKqMpuz zMD!0>S*Y>BGKXI&os)BI#Hi1c3JTKKKLIN)AdXam*GTFB z_zCCP*aC5ce+B!Y%wAE`TlMFcI?!2uEsO0D`R2p4?s_Cc!~#<_7$f7DNA$uOHwrkoVu&0nqrC&aQ4tap5#>N-U3Kn#Z9uaeR(3X*A7mp7 zuc#0duA*Y4Qq&>^Uz1bvH_UpqI6Qdu+#!5$30zm9cwTL7THf_JA_*L|E=v{{MQ$8q zcJ?)`px9~<6QW2aKK0>As=YJNf3*$CcA6 z`ztZbSs;F?H?qYh_KTKs#U_8_H^wgL0rj z>k4G~w#A2oP}e-?bWEP#N@HgDJh3vor$E$)Aw;7|G!(NIM?>!UvxL55?QmmnY)o zF~6et<9;>uojgq<4BZOOzHv(VVg-~1^3$m|ZSaxUGuD_txWt=TAeEqlRiHJZ(y3X7%2U0SQ_BOvhn|XYqHfY4M8%_mkA3 zgbwx(rrFMS(9nhB=H_>;Z9(d?TC6c`D{B7+JC9b2h&N%Zt~2uQ`uBGON920`Tm!2w?=dVu$j{7a{Ub!C zJ$UjrDbRqpO-O(shA?JO#7Btua}Me(T3`=~#i^y@4$6Y6y1oX5pI{eL?;LABIg_lP zz%Q{z{`Qg*cxAOW_?#7IQ4wcay}ED>mX2IoANJ+6K1MpLQ3{Mo)9x67c)hvI@-tq5 zXecas^F7fy2|Y2nG9R2vp#SyZ)dvn94&Yx^O-9g><(NVG$*H+~`8-O32bc4qOj^D6 ztSGyfx=gUDOazJTcPR#e?T7L6-insustRN0V;b3hideL+Z1msVq56_&tE@~`0WX5c zdQ&k@$8*Q}2syu7Slc>2aHVpATrc|5X6BbZdwZvaI<>KD+aLnukm+jc>H@nq0jtpx z4-#3Bn2-=9va+FnLR zby$|^_x>4X+;VJ4((nDF_j=r)j01e{W2Xl%o%Li50~hOkP5Sm1X0_x>SsR|~NS0;q z#r3yp!#@Dw9pKdbxKl~?}m%A_o7N{?cVdB0l2ISdh)PQa`a(u zR=(+P?blVh)D|ZAzVl3ckBcrbLwbNGl6m2Gl7>^+^cRl6{Q~+_5x>SOzd38M?Kc4@ia}+Z^<|oQ4^```0nv@(WnO-@Psn-#DV{8(aWb6#pKA zR5;QoFh}=~;0rL2f&b)Lqps=U0@LwA=iY8fKg9ad>q56(`6ZA4;ZlVDdC(Xi$j~Zj z=P=^PJOS788G&T z*4SeB&2FMx)jvezl#rg(1y_|rFNDKDdGBMjFk+WoAZyj8^IsG%+Z zuL}QLIt&{gEhbojkDl2PerS}g>+pITvMkn)e=sJAiGCX*3V5b z<3~WiNkgWbUo@EHY6bc?(Iqh}qKvbC34fv>Mx`Ld#*d$EFLB}>VDVi03-oPAa((m?y5~ocw+p&y3uB*De-)H z+1G{~W0vvp$d}OmIkT~@u$;Ep8=z1%9S7sSPdTpbJJ|1|t2iyL{w<^5Ocby#+xkb78e^GQBV+mw+dZ$Yon-Llb&Q^JeHnn%a7=fz zpQ7gg=m(IkrWM-n8>>6Hl>@kE;@t}rJl1qraST9@H(04Rmm=N)wol)_!_|ERgSn&q z8$chk?~QsV1HsvElVe_8enJA;CMBJ6x>YHTlUy9B1`V}N+-$-&O)4av zfsg=_5z&}kuytT*ZZW;=>OdJRsz*ix`u^O2?2eN27(KdQ{ckXFpM>7zHW6Kl?rV6g zeT1kttSfCGBk55Nte@MbW+6i7TY{S=KN6_Y!XH=|9wdGiWTC-%ZvJrF3ZVrui^yTp zZKcx5lVbWlU&Mm?Aszl^up+DuKnGR}aVx^jIQ&7T63!_tj20x4*H`v7e| zSby8zGk%|Bot`7Da0e@dGYdprmy$g z2r?=qgow1&>T+iVEHZnz?1IGd?-4kNKn1~}eArsL0!muVwovzLU#nX#(zxH1;OIyA zLzeT3V`}~V53Xw-JnL|+4b2zI-?#zOVox&nkgK{$f!&9MZ(DN-@&y1g0ZR-_b{zsE z28MqCo#6GsWYkByt&cDcqYq(`=}jGpNA<_E4_m!RoF_whOTL|PAPmqB{KNFFJuv(D zy~PTf5ZDzC#7lis#3Id4;bm`Aj}tEkxZx2p@z&Jj9=!kNNC0@2<)ZDG9hhB`#jXR2 zJZ9q=kUw^Ja_gx>H0KNK0Dv?B-Q~}m5euDqPe}j1`o?<&`E)jgS+yu4XH6$Sr_tlc zz&j`}@ScI^J0%1&Z5o2lzEp+m&x9E%1&6mq8{6?{Lh%pe7V8)5Gqm^7y27>nmJROa zS{E(u$gzCi8t=Pi;GOKG;55*@k4G)+;CKGCJFqFki1lNp^SxIrMLUr<1cO1N2beVL z2fEgeqk3<`09pqirDPF^p7xugq~hS(e5wylw_m%5N!`L5#<_n z!3p1Z<92dU$>K*EEFWza?%Uo5PLEnPoP94bhL*}Ix34D!^4bh`NmcKbypbw#J?Q|x zHGh}XDJMWE0%T@bxc)LoD9k*x*A!YIUU*;fSGB)sjy$Blxs!^7IGx>3b^2Nasw(eI z0B3(-9OIGNT$Fx=+r>W`N$a1c1c2=yvj+yywyR~+Y=;4CQ)Z_jWM&o?b2GEw_4SFs z6j~HR#|z1_YZ1Py(M7w~JxueD8#Dgbvjn3XzVAHsqMwQbv7X z#Z8gv9hoR>;}&JrCkZkn2!|Z4pGGFTf$Tu=lTpQHc7yFqQj5ojRY*)1Qk#m&HUAzQ zrUGCp_O0t?rQsx?+&I`AJ1jBf;o*tG@^ZZFMR_WfFq&{7>F|i~NB8N;B~%1+;`|_k z)CZ8C0y+pXPBO8UZ66j&J1zV`X?SczcoxKKBSc%OtfM2Mug?#(?5CU!Y9LW~g2VGG z!5dd-aqLS`BoH%Uq2@I2CsrSi+rT|w#Si^8v{1xx!arof$mz7{F-v7g;}}DOg^#W{ z=~vw=rN&~FxNWmY;>nHE`w&-?$!vwCV|#2s+9%bpy(b_( zkDIOcKd-JMK_@5kWvQ&jO6i95oj1&Xd@ucsTAOo@v&Y>5hcTe}8`*9{yIpPQgcZ^M zCg6FGZ+z^%=>GN!FW*#Spswz$)@UG;Oukx6i>=l35!a;KVP|ZDev64BmFp92z$bP_ z3d0{*6MwSmTCsTX9AQlugY_8^0`T@iW37g34PczVCE57&Fq{!iRw$*^+Le(v`!e8X zc5FA_^Q)HH96ui6KJ@AN_{+cSQ)VrAwr$_qZmIhmr)1v}+Y&zK#az`0JT1-gzsYUB zQurKW`d+nFqIz9Sw!vKR`CjV1{dleEd=Ke7ym;Tf$lg<(CmPp#?AP<@x%&;6vfknb zGeN99HdNUxeXs{N%Q?0kdv4TkxO}ub>$@7{yL$5okCV;|MsQUfngezh?MO zkONu~gsjW@^J>u>#v=Fog%K?2d_ii&V=`y^iDtr=zZf> zEvmJ{hr`wT^$+Fi*eHE_V$4e?p?i-@$#IGK+vMhJr`sUUW_Mhk#0R&BDPsPc(awja z!R+(Q3pdKfw&T?IR%X~NhA;U1H}#q;fWmZ044%p4AHKuwa{nSyNW5-$N@r0#F=VM0 zjgTH3+AqX{((+_o*q;_iQOuII+Vl;szqnkqr=ginO!3*nG96W07s{2Xs&QlOiE#4Ys@U)ETYF3<}5E^FQX!t%*8sy``S)0 zfc5msuMvkPhO%rY>dTnBU{>q(guLM%-j>gZpK+atQLeUy(DS_wxzAo!A98}bW&I;w z$wH8c*uaZ_5#O}9v=sXYr^6oA*U{1PN*6#gENAuHa5Ub4b8D(Q00Aa|#_jUUo?CKo z*+Lt?iDOs=djTxuNK63ivHj0HO}Fa|_j6&5xxwg~4ndy-PV>bE#) zl*6^B!wTO65AwlA-L5NHo#!3Phbt7J?aT)?49E(^*{IcWB+4k}^Oy>79@NNss@jUe6WK zgV~1Jd<^hfboE)hwm9D})4iqfd6C#0zh&rrYkRjEv>%)F-U`t69A|r(0F-`VzVJU@ z4u#!83Ou3-4Bx-nzCR~af*a$GV5YY_2 zkE6K3qa6xk3}d#%SRPL4UCs5@tL*%5MTCdDzHjzEhpz9}318f_9k1m$u2}?L37Z@) zk|rOnH*O~g`?y9!d`~&DZ<+w-?CWd72d+Tmwo?h;BW&LZ_*Tznd zfvO~>zX|Vel+6|wsxMEruh4*9wdc$(L+gzau!isd-CrPY@^Nd@=O>^qW7`{<&1U&t z=}ltmey!DHc5mZz-RK*^z#l~?A#nM+IVu0zC(rZH~x{nP3g#B)%n zaLk&|=2a0Sr&PNwmBBL4*7=h)S`mwcP7zEr3D@Rq#18oDf-l-a6C`2`LUgpvhpr(g z5dw6x4JBd#BZ;BWcrv-Lgh0&-alFB$ncvP3#?f`r-M?d`E%v~DdDX&75ItJeKk!7A zeq{D?27t0`Tm==AXK<|t;OM@bu#KiQVT1=>Mc6&<%$^K|t zWT{qk>k^e0;*@WKhxd1)rY$@d&yULu(sl{S1rd0pzJ|o0f0pp>UlI;!lc2W+;bPb@ z7zQn!g1TZ>zwsLM7NWb6jTO^Kf3Ldyt|j70{3|WPVDRpIY?8qa@Z|(XDD;Mt)X%(U zB1Q+V&pCW~e4jadM~eim&EKvTw7BfHJ^+nDV}1QBKp-r9vHh;0?ciXs{9fJn2$R2W z+Hi0|uXE*?*B0W-Pda$`mmV13EW*be!h^e2+rtPz#tKQ`g%P;H{!Qv^y(S%ajG_88 zH)6@NU$?UL4|k>a72BkFbsX8}Rj`fm^$P^>YriF>BQm9Jui&iXs96UdXeYP6r(7Jc zZNA}j+!QceJu-Ovd3IhQM&t1bC+}M=*9MK!w?^XX*?+2XAGgd}Ad>ljZw{iC-1_4wq;VS)L`z3=Az^?}yL*m>jT#9@aW?(^Nn?ok}6 z6St0w)#gNUg_ir{XyqQ+L+hE|%XMMH!McEE1JmpH=9?=ZDalX=_%@fbS*^B2 z$pGO!UH8_)rsbGorGh>CdF^oGO8xnTByg+!!kr=ey~ldetl(%__r7J(z88_>GO5Zd zXwv7cZq4<=8;@T}mHlj~BNOn5cbF}+-9caM^w+Goi`?{G1zW%LXTL-FKAHOVR5Wgk zh&8|p0pcOzu3!xA>098r))jtQf+k?fW`a^Wm)Rpt7X}C z;)BgMo}KTWxWWrWoQntS<29y}{b!r+dwvHS?dr@de2!TYG;Z91_&P-D1o9$rm}flI z*{vNe9IIg4UDeIIJ>^=$nER{{B>u60=R5noOB6LVb;bgH2Z#87j+Mv#n01Fce3K9U zhg!pct2=2F6@_Yaf@$;=Ha!d1JVlgczGA@eFc${`(>6O8{F8_)| zrHKsg{$mlC%g0dGZzUWQ3Yv!H{ol28hTy9!;gEO8a&)UmgG?Uhh`$IpQ7R`m7jiI6 zrD<$+!+deL+0s{n3UeYNr7*?(wbqt2CJ6^GZ0?jFY8VwwEQJOz5fn71PhHGePbA5u z5)y&^gU3}J6YzXrSKB6;YAT5rrzEMU+Wdj2^nH}9V2$yE(cVMCDQZ<`!NihRDTz2}jq%h_q=^_(IQ$kH-?GeX^RMmZ zt@cY3ln^qc&?ViLr_Ezl(frJSl%k+#n|1_+CUrUM-1vGu94imCpED7AUx(9hV z@S->Y80P&(zOl}6@QY3JzGv2L*5AXgT38thL}U&514PP_)RHs5B&A(!HwSL!@D|{c zL%0@%N^(r#SEOVeEpTEe!_ne7$-|UJ+Vb%be_3&8EHO`}CJ~U7Zhz2oBcY2e=t)f0 z?+h^$MUW5?*AQ1scJkyiirYmCQTkkQ2dSJeD{3Ej{pGMM`HLYUtPrT5%se4AEU^2p zeoI-=uPiM=Y9Ii5W7o~5YjC^!J23u8L^leeoTMWOpV}SyY)ZEwWrwl>S08CV@FS{h zz>;(HC7LVH_3U|IQG?gfLnL&&y^Ew8A|IKm^byzeUGL&nC{Jmptye`^q^#3R^?;d& zMTAri+ZZZ>@*DHX?bU!mpopY~wGiNz*1la9+Zz^DP;07g=5~Riidt*GWe&U(WXNu= zYRAEeq6|xC`U>lW&-An$?I#o)*RvPoRr*H25 zxfW$cX2vL}UYD|BeqdEXkVdt_NHv}+Jai|pe#4}e!i+r)kMD-aSfjeWY3xQjQ!c&n zcTnLO;_=-RGUfL}>bi1^N95m0J)Ue?Eu~m@At14DilFl3GTCo()r_5~t({M7Pot)> zg@RN;@$sC|VYA%2L-tzXg3JE3Lp2LFW^!>#BpD*Ge%)%>l%+pKIHmYUj$J)7_#66; zcPVScK2Gcg>Q!xA{?y6w(_bgXgmI%cJirr{3F0iXf~_(;M{08~9>Bt*pwu zQl7yL4^z9#{$$Sl?XaTJ;obW_d-lHl96VVSf~yF+0#21aAVQYklX_k(1776WFME2k z$1WP@P7iaNZ}{&An=hx19s~@KEC~s7yMZ3Gak<~*B#hjpG&sAeYis@UqZ1GVZE~GO z(vTX?7J>wP9zMuywKFqXFS97GnWHrCrA)h3S=IhOB5|*v5=4iZRn783#n{k zmA2tW?f9qj9XHXKJnVe1&ZFVl54lhf*>|33p2)7J7PEBo_Y|(1YkOb_-hlsAc z{Jt=I^Z^fyZ7!E1#?1XMqcUYT>gp&9(b;I6mSw+%f8L{NkQ1n|;lu=DsEQ2@&>(L2 zyXnvpZ^8N#!TN8dJDkf@8b3$le_%biy?$C&R#tu~yLeLnFg6kF4v(2;spmzv*zvG( z`@VqquJioj(hY?NH1{`0u|r{rSElD#j~c^U8Je_1^Jji3x1I{>1QNq5I2(l2V}uO-3U3#3>%9 z$OGe$l|;>`qfab8u4c}HslnwFHg^4J*lGM@1!kO0TH%Hb)3Vv`U=i-Yn0UD1!c3lJ zaCPc1f(O(b1x0a#5_r7+SGw$y?>+t*k9}h9nE4)GO9&we;T|KN{~Rpw6;?S5kukar zXGje}0XhoASA6kADuLhG@Hk-*am;7;Qn+m5-rd8>_!;tHBodyvVdKF!&!40XyWs;9 z%?gH8zO~z2aSQ#nSBur`T@%fGT;_INe>9HHeIRpTLoC4r9^XVQx9T{~a`m6vxD$kY zQCM|ET(PZ;B?WQ^@NG`v#BPlwIZBQQ`F~!SZBK~Lo584w6)EaP2E+4{7A`vgS z={IdbM6;!6JA4LamC#dk9X{XM!@V%9zrS^TLaLOH-vp{`b=}9l(>0erOWmsKIt>K* zyboOgz{cCIAeSax8HcX1s%>!#W_kSx8x~FyS?Bg~fJecLDPsC+JA|B;T^Wu<( z3ev+v1!5Jbhr#5V?W1?LH3n z^kBTjWIuf_ESy-cd3D+^~f#5<>lk9va3timc4S_UbNJp#!Mq zPdpn8GaBc12U8^0>QfoNgv^KS7>UAAg9G>jgb1m3ErtSNN)aFqX^EzlNCxhM5+zGY z^#;)q3L55HRu!QMETsJN#1my5O-g=n;;1AM>u$A+zy(E<0DgIB=NMA?$M-GYPfHfl zX|2-qo$cd%pGGjLgQ1Ojh6?wLr7~b0c=CrFF$x=%EF0`{qs9E4jCxTj)Y5gUj9hG3 zcw8^Gy8`Z&mJnj+)4rcx_Ec55&ui{_v;79f2;6SUC+CpgYFJqDYPo%0_`Z8GEHw=q zpW7Rbxj!Al{fj^ULXfaC5K~xKW)ENZkO;Zkd_1q$4vKhvX4eXDS0!TbaVPadCm-GU z^u+7~QT=Hdh9o{o!@~+?A==m5!9G30n&#NWk1r#1L^2sqTp3EFYUvcR^NdrC4rNMM zi0Q&TEr$yC-$(=}49YwFy&+kjj-4(ZR4HxtSp0&6#sW)B{Wr3f7CATV>$VkF<@fKc zmzZuJl~k`O?RKL`CKSh4ZrrHD@_Ujoh*`z-sYc^Dr8Le>5yT@v#(s`p3icjep%g*W zW~^qcX|TjtH_wrO{p*)WqR2YNny#~LiyBw@5gQrz4_Ayc4VU_Kk;q-k_~fQlzW4(E zw=TWAr&Z|wypz7d7H`&J3 z*5A+=QsmSl@gxkFh57Xa#aw?1{KVO{X(oMsR6!v1$BXl zMNlk68*ZaH>`RjlG;ue#0vuB%0*cbs2XZnciwx&I4IxeSIaIN%6xHur-I@^#D4G)W ztJXMC6dx9FtQ3g?f0VBO(6>o@-E0b&-xm`!jLc*F!hqNy%BZR?xtb@{<7AL?reqR~ zDwYFZtC&5XBqpARQaEI9E}J)fkbm`?tU>fsRvXmn6R#elEVE!`2Nm$t-lhzl?=kOg~oGp9%KDoHgC3 znOsg;{FOk1qfk6jY=&?j@2!Z(-Mzj0MXXiQ(%C3cp^A;u(IYiLBHHn3j~UFU-D1k2 zuIC7a#)3$aGn}kOCDzcviu=WE?qv6z#D6St3sNzWC|^_0_N2WxX0enTsfVkrT$2kg zT2f4s_(PC0BMySOJokxIPdIK=88%$v44Kr(+#IN(KJC$7Z4>vP$)%qrT3VFcam+ z(~pwa84#%Q5%C<>gc`_ORUpu5z8b2k)s#Pd30};6)%`Hhd^-}2Z1?|bk%3jO`Sq*U zB_@AYFB0L}<%1aJ`GLC6m3s4^f<-T;9z<+*k zOqnIcp5SDDi?K2Nc@uA~)p!-2qBGv-^hqaysvtBIFbon)D+Dcnu#}e7$W1C$E7lY_ zh5|UcwNDkqmk(EGh~$HHH02dEg3^A;EBcwqFtRq-oog$=u+5mYwM%W-nu~F4@S2!N0`A$@15Ojqs0lG!}mRZ z%A37e#(<)|H4fkHgF)Qy^q`{T$?COpMj9DuV#c2saOXsX(O52?Sjs?}19)_d1|uY= zH2H24V|YTn<^bx_Po}_Oipg33j_mF$$u&gPf^G8M-yT>dg*r0RoPVt(t6Kd-$rp9s znE^$1#(^KQ=*(sXp`=j@9_@0yngOo!Cg@n|q?`f&%8bxFEPS!=heHwZ(^P|4gLaJh zRB%?QXcFOfqUqv!Lh)o|QcCTe4T)l5uBr_q2SM%!jkL&%Bu0>)Rc#Oj==*LP65Cz< zpIfF$tjDXL=YL#)UYNLv zYGWUkTTMicx3tAzpDZ2ynuWqzcB?thmx_iIuSD*R&sme|XSkC`H zjWFZ&UZeEf*X#^|xV+2ZbGkUWiwz|&QM?5^(JI5x3L<8GeT$to6OA){*oJK@!iqLy zTb)Ak2V;i>_YaMWAX!vJ1RCW-uG=JbM3aFDq-#%>ghEl8mrtaIvY}BJx?Fci0=Cj4TJ?=x zUY1J6NNIMvx2ae1+C6n84eGBz#H5q?m;X|QLkJM$KOH3}-6DQ9Z76e7tnft_CJGXi zwp-X<)V-iDpQ8V7p7gLVeeUuI==onK4!%zMzQ6?c65o2fE(?@wnScH$VYflOy~Mjb zz?#nM^q~JVGi_G?oA!!b;s9HU49hK`QVhXcNF_bEJi?AZi^{@0fvR#lunW7Ju?{vf zp$TuBHzG4bXro9~Mlv3UxoTF=FXXxGY^@_j(#Ma)F)<3F;G^;7!fqR6!61uRnH(vc zU+g?oXZ+7krXN|AsA!=-^vmuxaX%(?W6FAsP>**8P>a6g|G&Bg#Sv*F9e}U^}H0CQ#2S_ zSU}_;Xn}1ZoS}U0UEhZ~@&=pEYReQtqKR82N=u4_eX6f&vk3 zJJZ}`bB(#wu(=}*6J%1$CltRBD(eT4p#~b*4J=BY!`j1!7<&3NSBM>W56f#FKb2;d zXB2rw@U@G^PMRpNzZKQ1;W&?#OZs!dFiQhqv&Qq|M%FIEt&m% zr;RffFc$=Z|NIE79tF8enZxB5t5u>>%N|ozkf zX%-!E3iYFqByW)!o7+ooR|uk_NH|9h4?7}FFycfGNtDf!rsY#@Q%i@< zpeT)4d<$ZNEr@F=T@aKEOe7*#;uIu$UD!5K zvHI*r4z*%w3$aXRZDvS$-LW$s(v~P2iU|a!aFJ|o7je=xPA8x!%_ty!bS)4`MQ2Ty z`|FeacA!DO(vaZ6r_YM@Lt3Uzjq=o)Dj3jrCcNOa6e!q;Y3vxGS-+f5`IHMsR+<)R z@g~`T??TsC41sh}nw&_9z!@mYsorq^znl_Yv~~RefSoODo?i~LZkiT54xCwWqOP6P zx@Yb6bu$ZLJ^C&t0Y9)wGVI!0#74-N)ml&wviBQx`)`GXAh^2+cemgW z+}+(RcyPDi?nCeZ!5snw2=4w)zI*RGRl_f)YU*rRYj^kVzR+9*FnFWf5M+0-(RlANX?J5n$Aiie#}y82IHeNWTkG%^=6Id+lND-8RVEB#|<)AcR8; zqMftIiq&tG>n1u)&%36m9yu$Cmn+yUm#x@Rj^d&@<8X9&M<|t#X3bkIclyJRl6FV- zG9)|8eHP;4lt##Ha?{S>HIZ-qvJx>Dvw6%oBprIB*hEgVi0EOzCeEUj<}D@+!cZ8P zi{7J#lAhLHz=6Uz;n2X`OM*VX6yIJtaPX>Xkce`=qX1XRS~vv#F^58d0wOnAmPr4?xkcUSezRdYXW`}pR z%(Wgi+mduL^``@fUp;m;A@4+rm$K!k(v12Wn6kK`eu{Iy1Ny1plcKJZzr zhlq?7{{QrvMf7IZ2YgC-{HUV!^WiMYn@tNxZcC0#G&XJeGsk?wTl97qvSIFjWGSek znNW0MaYC3UE;fssX=jk!aAv>o=$_VNF+{uP&*|r~TqtP{@m2=3Y?5o>%Jc3)Oq8wg zwX#fJ1KK^6J27&nUL>wKF6+`td0fs~Eo2JLX##28h*8r#2{0mnS$ww%2u@c@6Aq^z1uVZdvx?hG}N{f4ZE`hABwc7rwT#`-Re}`*4f#a&ur$qc%*|@^_FGyMLgEizjJ@) z{9m-g$oh-lNIbxp`G+V69%!9Cf`tG)?|8hr{jto^%GTw$L%8R^BNFj4u$TMvJHHGg ze(2l1q7!=iHKu;j*5#6k#eNU;D<952_Fgw3|L#d3HHY#K~S_!#4 z_CcF{sSvvu)#9-H_wV1wcOnxguRov%)Q*m4%_FE6g-Ijz>va=q>%|GEg~9*QMWqhd zBcE*?6une%Z3$D`?`1MsF$*EJ&-Qe)~&R%gouoDN(uW>3FQ7OKRON6`Wv% z8JGH@43?agt|O^m*i$?H_jATaCJu6nb^y%jye@iNVmrg2$kkWGOu%ycLn|XIJBNyc zMm0snv2D4@mq)+tFZB!w6Vs^9U$-ONZ}W1i>P_}ro#{R${l6bR4xx0RXiqob=#C4T zFP|2v$~rEssfH0bo?^yHAT*kq%j4=iT+*)Ca?36FQ&#H|)*-Qz_DJ6~N=R4V-_NPP zrXq{|?=cAjW~T1niv)mBb~&unL)h3@h4srBPnTCFqqp`^;hUer|2VkYXTWl8<&l5t zFdn$xg2$B`^+PjkAmtEtJ4uPMcK9=&&p1^{xxgQ_YsFk_wq64xI}XfgDk=cCPs2e# zS3^n*%Npa(JY9)ra;>R}2+AlcVZ&4Zy-l)7IL=I^hB>XtWZ82AvZ9ZZki>`%Yo3)v zkkb8~)?2b@`}1o})4DNjC5`=x@XY#w?s21;rAJ7Qw()eYFWGj#L}avEymW267FSKU zQk${i8B=&mN*yLjjf51YRA1Unww0 zBy)TQO=9;q&VKBaK=7x9*l#hj(NlWzT!|l5Qt)(D4h(g+YL(JSQI}+T8%8 z0ENX`#Ws`xA1lnitkb5ovO}zt0A2AvGZpx2rHa5i9qiLH&1C#2|E1@49>VYV{2h$~ zmeqT#)YMq^#z?XgItI{z7_ zFai>L*t%>8&rvDWsBdX+#}MretgK;%7KD>yF2UyVL)K}U)ehm{v9#{lB5S4H-Ke4; z3{APU`ko(!1eD8pO!yU5RpZ^{f96jdc|6BS!>aLzC2<~OfBJQJ#FA&SC2^k`|B+HO z0X~Fr-+Av2i{&$}wU<-xY7}KyO$e%Ti_nN~2?jz{zjduV^bS~GL-4GogE+Br^MZ77 z>-sV>1@3>F0*qWcifvvQBkw&_VqUK#fZdO4NqE2GdC${#eB~7I_$!Jq5S>b=3p^qL z9v&G>J#Q^DI|L%0t&bsvtvAh7mv~2%VK~Fi;v9-PXEi^M(CNRU)KW!Q$OW=}=2skD znm`MamWts`_$j|rc_3w78 zl7D0eXerdBbXc8?b`8b)0QqHV7I79B2NXdyB-Q1?E+UdR$M*LSWdgFZv~ha&OIw!l z^5olsa4Ewj4ZxUmxBZ%kR zs^ZL_-;Z5G9rh!`Cx5E#A6hLuf zS-*&bPp;cCw)06&o0nX6zG(OddhMvPV3$lLL`KXJ-4%ryheoFu)_m!S&;hGcow z->@G)M7xEwz&X-r$$XyMZ5W<2O&>*yOd~HX&j)`Vi2|lrVLCO@oimv2?|pPQWdasX zibr+yuMoea9fdIy-jWsTWLnH|gqjx6p^l;M&ch}4r{IeV7s0%ZF*l1P?^Tbd2;;@n*E?;3PtFwrK*w=Fsy%DcU z6*aANqRqWL8G0!ovVO(3xEWA7suCuUiA?|f%dFq_Wp8^Rw0&+{a)Fzoq>K|UIWuZG zML-!xhWr~RELh)uRT5c@L(W=xO2tQlmF(w?YcBieP)I3ZC@Y30%oXy8A6PQ%v@;E5 z{m{kTdIC9%W@#57E6m01ZunYWr)|@^j$;?w7Ca^es~_K?&WVe6k|OL9BSU?f)&9s9 z7Sk?jRqI*QuqV^Wo7eg8Gc61DWeN0M(4eh*ibT%=STID~^~otcT4ZL5ZO|XyXkMly zFSj4gcm90=7rGRqdJ5y6{~xsPc6xo25gDw1Kd5)`vVVW`_j~DkBRGG~y1$0rx=%Pf z7!IKWGMc{5(PZnw2%^D_6c&%9(ML zrMr46myxN2Ef?&LM^O#iw3rZzMJ$f!XLAAG?k-gE_sd{s$DL2${3vg|NSTezZd1Z= zRYRziZS}SLn+8?fgzRpZSet~EceL!%SS&HgsAOZ^w01}eR8HpCxu2(ZylxMm@LO^& z067z!VD}DgL^}b3)WfRaf^BJLp)N?N1YslQ^z@u3?_%$hP$P&}12L>nrEH>_!M>4m znBwxehB;F^qt9j|dIa#KNr{!~UetehPcWy^_!g^$s_?aV7U6RKcQYM89zGO)?-&gu zvWsJXxvGD~0@?rup59&XwV&lcYKPMVLdfCdz&?!z zgH#NPxa1lVJVL#kDrqX9b^3CGkzXylJO1b{2M?;PQ!|bJYg%y(W04Z$%;wAII}=zr zhc{YUI{e--*pX4ZicGtJgv|keHP~ghx zNt}Sfh-Y{!8O?IwsTqg1=fmLygs(9B@z$mj%uCn=cg95{BNCq$n+|5+OsEn zJKf?%x55&{22=vmT@ms+?66FPF|ywvg-Dfba$(UM7nkQ$GGNuTaETWt;~AHo_ExaK zgt@g}6c|7jeAU$?K*H>lR##_IW=cSyXds)3hX=NNu(QXyB88ajRS`9-0&&9J!PoEo zy2#U}pX36UhaOT)g-bGT>HWp>6O#s0tq3-z8HbD#^>8R^it%Lr_Pqz3b?jB&WNQDZ zuOoLVX@Q{=!b6w;hOJnfkpgDdRZSv_RKXNy{4NNOE~T2ZPZKJp6qv*gI?&XQ*N`oR za9YIlj`j#K``XmmKKT}T$Nm@HX_3l86IZ=90ynKxjDF;05GvC!fDh2w(aFtU+M{W| z`g>Gd@`{aSwI-~KR3I88&8NLn3`~+`)hAMln^Yl8SD@-UH?f^0{ zrsfKmL&NG!=VdfrE|U3p1;R22hH7Lp^F}W-l16?)Qw52hjc+mqJM=@o!EwY!N4G6y zYH~I1H8pi}B%i&ib_!ixU1e)k)hJ4-S&_=DER*C-KSkpc9*R{WWLkmDqvoQRXBgZi zk7%TIV!CG>+5)p?P5Kp#{J7Lz=l#sz{kW z&l`z^roBQMYxIv!@P!v-OLIg@%Jet}1+KzG^)~FS-sBNSEGL%YZx)5v*dIrHtCBy8 zs1?oAVj!Z)wB2Q?k>psS3D8_Jlv!P#hUGq)Vrc9nsX!eHifauFP2O+F72hDkZad!uFcLE$j*Ub5f7oWm{sCdtB z#-oC7nA5UHCikaBm}`Pwtr9nJ@~u{uZP~*|tH!3u<6tyjeRaUfTbeOC0joO+XR)}ViY6&U zR?5Wm=P5AlWF6gc9Z`)KYnnjX{skpB!!3mRo`x{uX1NmdirHld{rr8sD5cpQjf+N< zGlbmyZ<-qOT%<%MUKfcd1paQaSpN&k&1egF{w>j}W+#jX5IG>4J>gVfdR`ZxC;$%Q zdU~ADrZ8#(&!S6-cywE#grJZNE;#{*1}>XIq|p2P6XQpuC#Ld_=QCe=!L-uSt~s&l zFrS_XY2XyH6QvQC$c6bWCI!(DgG1a}xsaw@nZ(?}8yTB}gBMyF8LKi1=O4eGAj<`j zm=;1wl#KdB4+$5m)wyb8Cg1(*)65J9dz&auIWtS%fR{pT#tq zs0bX-{K|xCb{@?Oa@UiNEXgs}&zDZV_Drt~@!x-`v+|$5e|`jvXRP}vOQ_|rG*Y%< zjE=P_SWFQ8&}Tdm{R+e@``a(~{>43c&kSThao?U&(&JtjCNACqHmMM$IH^j)S=IHu z*=J|Mi;kPpDZ|w1NUJ*F1d><=-1+-GQGGk)Tc1xoSbK8#wbj(lvL6n2P{aebAnXbP zgQL|sPpPDXV3l=B&XXj9_I7``jdzIW=LZK=IfpTk#3kvB4!P$>*x2<~u$%wbccGTY zejsg;N0pH$9);Z%f{F+i%3^>srxrgmY;5#Z=>BYvse|&d>1pi8|316}52=Z742gnw z2su2CtLG=FbjmwaK=i_%V0D~CG9od-XkN=;5i#WIuC)X`OQ8xv9=Tb#3Y_+HGeM>v z3vIMnh=K6!s;owngSaf+Z4~*GIOd>9^8jVVBG-mc7d=i0=d8rw*T!PR6HPczP4zzX zZym&$P{jaXWPqH%m&A(GfBRFs?2Wh-t5LqShJGsAb&Dqr3MplV-Peuo6w3k;|ZEwk#8ZSP?YT{C&ER=lHv<#?^9RJ;lv71PA|sNr>B1 z;xiW2$;`m;vxqhfO(tygHFaPqBTY>WkBDki{VBtUBYyoh^GX)pfjp``O3W|`RF?+$C7FnB~rc&FlG?K{hyR~|%)Gz4v1wi}v`0La*@)stthTJ5T zXky5vYZYtI*>tx407t`1%|Xi{x|6_K6uG%rOQ@LNJAPcf_#L$IU3G}4l)~ln|9^62<48C%Sp9b<{C=a0jIXxXVTiN2 zA9E_@xiG3(8gKUyj{WyO*|$O*VX11Uqa}`SqdFbg=62gZsL5)yBsd8g*bIQKN+}sN zG~g%N^Aj6wo}*^*99UMZOOlSr2pRf8yA4Xpp7_|{c$zA$S;oSi+EAPMa#uhwtICWw zhVSCVM<(ON3#>RAG#l8+lS6uUkC5}G>Na#Hmc7x$QrC5mc;3$q%`&bU^|&=Yn_nPq zhqai!r|x!F_!05s3cSmg>=uo23*s3nu9+wTjsO%Y0fB7Hs{C_xTZXwco*<0vb~Hx0 z3a#-tkPzMsrp7o$UFy)xzEc7}dJdR!P^+qjU z#|utY`~S26?LoIEi%q~`baid5;N0pyZLO*T);63|Yh55yRu2PbBv2@Bc*(hl2*#x!9C^8qF zkS(K~v~&}sR+L)ej2Em$7$zwXZ^yh!3$kZ~KnRZJdhPNkJmG3y)PR5fbG|88sbluH zz47;zcgdkiyfk^CDnns6OuY((wpzUw=x=;fZDDDx>{^sZh#HzXiYegbREggR6vlGJ zk;WjZ==4%7X_T9rMu!s*tkNVk%GyFLh9-|GMkfPsoDkxuJ3~veDt$Ua@mGT+b4g!# z(;4nT+dP+da&M8*51NJLp7>&QLHH#M%=yq?lC0e9m(YA!5Sa3_EwydoY>3&tBp4|e z7s?z(P1eJ+Ad2FkSb~W+;ze0n8jRRqHkI?Zi~k;eOT_*6_NDXogdvmZS*Xl_;ku>X zKW~&Y(69cmdV$cetJA2pBOk$jvpXw4pA=${%_rO{HTmCjxk`)8`!PY_izk@_A4sS! zT!kpN6Ap2sC8;W!4P*dskgA0&*~0G(Qf0)s@K2;KUKW?V>Xq4kmX+C- zkM#TS?JIJ{lI>Tv&)SPQsky{t{0`DCVqO4obtp!9m7y5t?HOGDHtX4ZI2S z^UEaP>(k>YP)CDZh1_t=Ic14ccuVx^R0&mwSHpA&c5TH?VqhKx>-I_;JL(jyi4Bgh zf3MQxLD#6JRlA3!#gTDjs8z=IU(4AKZ}*d{b|iAmu#^WLqSegtCWPYHRHMy>lpU2O zYuWsLeB}y9mwn}mgBc)&gi&)Gty~Gu$aiW{OdY1yRabTs7z)KjVeLEEP)a_V4;^-6~9QP$OO@7Zyi#4+&MG!MA(6ga@+*hdmHU#@(J z{Qjam>XtyjdM>0>sr67E_-4iJu)6N|0Rc)Wn=M$921jA!b^5S%?R;5g{VVU~XM@qw zo?8FaF$#fC*US+QH4tq2C3L#MU5sWM~|ov)g; z&>H^;-oqThbWZts{H(*I5-r9MN@ZBnr~|!-u*)V*6zewNY3LHJwN9Rhi{?eDC2PN( ziU5yG@bomEHer#5RH-?EV4hs6MQr}(BicDytKw6sZ>jfP!`CgFGX zbI#)y)!D`_adX+3!U1xR`;rFzKS?&-@qP}s<@T%HS!6HUk<2>nP6bPhCrmZ^efhA+ zcn}vEJbhW7z1Jje2_Wb0a_`B9H}rsh-Ro(ytKaHIJ6R}Xr8thh&jQ(dtO1t=S#N}l z4E`PG1CgYDUaZc0iNY_Yb?v(@E*P30G`v+(`TS<-Fk;4 z;wekGY1;^ZH-5azj1cOhvKWcMeL2>?hrFmZ-WcsToILElp7vj<&-tGbb@uzO&?OY4 zy3xcqtX2O=iL~>pYAmszQ&Hs%3m#thnSlToPw_oQlCC{Cbi{-ilnU-bGQBX6+kS>I zqWYkzLrkZ56}1afiVL=ez?wUTk)p`ka$tP8ERTOZzL2)?4`vWXVDF#Pia{|E!J zstYB#EH~%^Dx+@eN7D)Sc56BYtG(Ioa5p;{Jf53z*E@;)8o( z7+BOo4m+qB%}ktSa;*h#e_;tfKh9uF4KcC5j~D`I?WLLUW3+Ov3epbywH(eO7J!F3NJyeEMJ{ zhEv1~*=oE=SXgTp5khKwpubgD$1YSC9KKx7_%3KR-`w9{zZ`Qh`yUW&zTIt^-uzJ= zy?I&G@$qJgR}c5qez@Je)blaq&RDb;D*Vk1*V_8X;(CoNiwn$Db~bG6i$A`OA>YpG$@sH zh=cAIeq_lY#(ks(Ti9CMN*xMya}~Q}Fu9~{#piI*22b3GB&?N-T~UMv+6C^gpbZCx zBW#`I7@9j6eBONT0|Mb&;LvIV5v`7i)ZXm~Tw_N1aI1B^0MBnY8v&5@sIh8#!#p54zs8wgSI7yH-YXxn$ z^Je@WahR_UxY2bdt1D&Q#7xtnNG#SG&wRIF(rK|>nDEHcs|9b|zr+AV=JeLDMXR{2 zEz|vE@iJ#iupc+mczOiinA1M_ZEPgA<6;mQO`losalNXn{l8to+3how4A{B+0RHds zQL!zI9+85VJEy!@ih4T~^H=C4OwJ_1j<~%Mvp`c5fVKpZ z52uViC*L3zc}gT}tgc2Dxlom7|G6~-zCA&-qX2`#WGH2KMF@5%(xune&}7Kn4IZcho@d{BTyga1bSN6;6qwkPhNUsI z&6{VboyBv1fo9pElx^UAe2+H2hc~E6S%+d`g@NVaO<|!zTYLq%!jcrx6E>uaz+Ycw z%n2~&Op=!=27gc#TN#hs+}>U;1U~Dz3OetOz3h*QOpnp!H7^B}nnmk!SbelR`1HYN zL(1=fqrkMmpscU2Ah7TD#P8Vg?I5f+GEH;Pg75BLRK%gtTVi*jF>MxwRG5 zHQ;sX6uPAp#bRza`emiyZLDG1za~lTsaW=GF{P+!9yjCubCIiZXd>9KUHdIuSU9~piu)RGYRuw5uiY`XJBW^Z3 zApuP~kzgolT1mbX@5La=#|tD;gd?BR96sne;64{9guaK6hJi360ViC@^~)VbYlkkz zgXL?IUE#(hJuD;(3ypL<$uwA z&IfE6OqOuUIl|)>Bvl<5ek^2qb7zA@pRf5m(I?jF7!ed;YXgyflg7nuSvJN2>%7)5 zkOJ0dn5itWGPaXUH?CQY7*VS9GGXXq7i@OKy>yiy zr&Pj5FR=s}n6ot=(tO@7w;yUW&+{!L&(H=*vQcNdUifiL;=|3%SFY5=_xE>W*KYe2 zmwf97%G@YP)nOjTE|S_?CZY5#`Gh4Q>y>As-#YSVZVx%)lvh~D`jQ_zlhN#JM%Ix^pyivvpi{aBJbs%wM5V`#lO!QUcow!UXXZ(mm z>2OYgbtgk#SXM>`9s*tPf&8{X`0q7qfbE#+loeobucSR@;t03LM{7~l1mTeCvC~_$#kanm7 zKS+sX-8?V4BzwE$05Vt*f`GD$>=g-`;8WY3B)=SDt6jb>7Qw;Cg8gkYnz$ z<$v!w#pOs0?h^59{jvexrBQBlJL34e+?XfdF%GN_-rHvNtiZdK$t(`|rH%J@i`NG_ zksY8N90)Lez7~1!n>q!G#Bd)#gTm*HnsiKt(BWPDN};h|ZH~5W0k=DwXYso;Ue5^U zbX*^t_4(L{XjI|ieb5=6vzTcJc=hq|^(El4#W4pb?ALU-W(7|3#gPgg{`KAufHuY z=mVx2LxB%6Q;Tn4NkL^T7u8SIou8BY8QctXp@O ztQ{P7#wS=uopb%~Y#ilGefkYDY^f{D+_;5@(`6>I-6r?|$9 zfn_)6fi!yk!<#fe*r!&h!mL|z&dApM>d$4I&B<^o=>l8P7it#S?tZJ6Fhs!m!;$hr z=u6kF)}UTGuNH5-r&atwjE2`wog!*lh~`=Qt=9OwHBS{r50zRJEE&vITQgv92e;V3 zeCZ)o8=O;PG&@0@bN_*h97iY=vDq5{T*#N~t%T+Zi zYBrZafULFZ)*HW-Ov42tc|tYf;MN*cSs4V)8?c>5$Fv|&4N-iX@WZ_U*0g&AIfjfeUAkNZ#boQbr=L7Vv~jAg?0BO)+|1A zIG!y(Y#`NA$Z{zF0H~knJ^fDBZfvTO70LMpOmXreq179CTpS!u) zc>BjStK084joE>A;O!ytEh-vYS@_tFR&H=6Ab?KfWfuLugAM>ya(McF6iF#xot_6| z64mwPw{`DN)gw~vX97OoNJctc89ad7Sg!kGw<)r389C9`@CUiB)0QWBYY;lUej^Pq3B7Lt8LY;T{eVrLl(Moi zt<3weU(1X9n*s2ZDOO;dEphC6MA^yU`nkl3;;7<#eEO%~{S7*kV z8^#e4m5;_rp+~8VbdPI67#+D5eDOnbU;zXs1A6g(y`l!G$1JsPp-_*#-dGju&k8S|DX1i)9kb z2HP89I*1!%Ks6cc+_gS`j*j+M_9qzd^eUGmn&sKJZ;zu|!1LRkq^2NKw@-yh5(?-? z?K%`usbBqsMI#aY4FxWCk?Jr|DHAKe0F7ZF3ua8&3q6ZsPH6BB3_^g>>Osc4O-Y69LK4**B~0vS8I6H^iq|6@*m z0f8Lk0|2e;p^Tk?C-q8lKUq4zesRKMKJR+#VfKEq@$vDgSUOn`7$tdGpc8ifgeS0I z8z1;M*Z19eHg)Ro>QS&f&x0`BESLqD;)}IMA*TCPnt-vK@ED!QoAWgPb4|~*>(kBA z`okL$MATjw+1nqPsio*)RErrhsYV9OyPl>A?2=0or30f2Tjy3#=? zWH9fX3%}aDy`8_E1>r&@3g3YW-pd0wPdc(VEPpO;PKySLFcBR@17;2JYhQ{DDlhW4 z0`CK6Ze6xQAN}ecn@&zn4y{Dqy{}syuMb_pH9|&E#Su~bOWl|8VWtQTOEaj}`RLof z7}U}1dL^QZzp?^lMeyoRvBW{nVe`CFsSf>jiwV3|`wgUiS0?SN%f1%{;ro>t()1sN zX}c4~kBsO-FHYATiy3%8La$<>&bO|v$nt^!LhI%)8vz1vzCYzFu(NzXSJwc@)ihK4 zJKoU`+I%#Q?_lWLweaCy`?A;jSZq@&IQAPuZgTm)pXq#-68Hn2*f`0*`&!U<(Ar`Yf{G%L*im;-19`uYJ3Ko!9jr7@CsO9TwN1zGQ@X4h5HFku?{_K zmo)uUt45n}Y<&tKo*jPhS|u!0R5Bh|_zG!lrP8GdZfeQqo`Tg}xP~xG_&_^K$N5{hq z^vy{tk$Z25d_Na2!btl8f`@Z+r?zeF!2E15NJYJ`Pyt8E?+y8V62I>P7Jw@Yz4KR^ta#Mf)6{$siFr2NsOHN_yPN$0H(g(rxxn|0 zzESt3p70Dc1%7mM-Bv#W3AX z)6g?$Wo5#+*!m_8zYP{pI|f`|z|A?YwUXuCDV~UVa2CX%jGy zG#KIOdsJL>TYcs~4YBq|GIG$1B$ew{SIx-9Jg@c1?Z z_KaUcNdRbMb+*n2zhd0@F!syfCQY4|-SovPg_rLs+6vg?Uou?H7UQjQmn%SIVrXJU zoz45mpFqinX?H>0NXe?Qv(8Q>Aj&g3H!4PiF)G5DHbJ=a%Lb zTMWuHn9tZxaFQxuYEk8iDm2D{lXhcuSL9}|u+KBRie7Q^pzYMZ;~=j$qqG-2u^EeO zoTx6m1&P^7l8%@eE+S#LxVcJ~qErjmHh#9#hOM(p$ilOFLgiXzo{e@x=*zV4y))h} zFKvQ3@li?RcRJ9bUh9{&MPf3W`qy@fQ(}LAct=EUKJVxA7qs^W^n!z{i4W#azid8b z33@MA(gQITkN~D;=A7RLI+;t-*b+j%1VWFxE@|<7raPbcfgbRS@&tO zD-?J~3`p}m18w=^53=`JVdO3LVwr0?vS)g$d~b06wGbeTKlG{H2#p+CtX;dqsuI3S zPW*=vv@m=T^$7$PC~e?1PvBIAs*S+F6Dm;xZ}Ont#QWQe)zl@tV{aCZk^il*84zl% zBz!lU$X!j4Hpgtxa1mAKObZV-`ubGgt@Tsy->Ed;J_^0wcO!i2`9x(@ zkv6m@{|EmquY{&H>RT#M{&{6=8bMt=?lGXF{DatRnpK5zv zSkVe*NGK^o3{Rg(aoJoog4Ll5FcBZ}V_B(HHRxg_43yOv@sffx3GGnyDmiZ@Y>L<< z8RAd8b(sDfomyBeDYc$2%fFkTJL^zIQ|(eqo2fTSd3`JN)n<)uL@;gSz8(BitMTXf zF?%}jxk?Az%eaLS5nQmS=XHwT{ z%HnL@ySXhvbd*rL^PvMmq(G|}z=%E|G)Na~gvetZ-}-dcVimDb*J)Ou-!z!N!exB$ zOUYa7{25JCH~NcF6Reayc(dXqm|>BIFzk z9SSWYR8O_&X4yhj|m4+D7a(*Ve_(#F4ItT>%!Wv!l{%lFnw!U&6LyQenf`%P1fN+L3F;xhgm8O|TGlZE!MXb6g?Y8# z!Lpu7jrqz(4{`N}D}}g5`b>ohe-w`;`6=a&y%PFqkb@%HufvFyfh zW2mJu7a28}UO}40Ew!Pot!T~8PKIPTAQeJ%_`c;Br0S>&^t@kkZuw_#M!zHCVZ<<( zt}nZrOD%4jX4q|i$?Eaz5!7g_4zjr(yBP)U(0s~q!eR*s`b25#obEzAx5}5&(KJ(J zck-c#T8v1slv`GzFx{*YcE(x7IZhR+*i3~T2Fo0$#V4;qkM^iug{;E#nuS-*tR+^F z85%k?ihQPBF7*%5AB#2cEkgBt875N$7!tS=5W;4YYcJu}kVIIBG|L93=(*wm>MVyX z4Nj|UfVRnrZKbbOv7Ld2?mbas#&Z^gcbEz|3)AM2`+g6vc#fd(9olimx#gIt4aBPg zHRg2m_wVn69N~VThOt5jz71plYw-+xj%XrzU5uZepLN-&zu&|=c0VPJPV&CG0qo%? ztr}U>#|&og?8L|1*yS6AHKea**0_kjQf^ zYiHE;v=DmG>SvTVyfpYfgc2%#BIuD{JLtv40du+MReYb9>s=~38-ydfDQSBi=^xR<8b?;v7jMDH3 z3Rvc`#~N>VlIaoUdt0sqFztJs9$Vg4EkI0)cm_1d)5i@`c_aTfpCta%(@g(LEe~oO z-WQ|KWN4MQPa2X%cMz=DTK3z0}XZA7b zV$VCtN$iP>YiP-StD2JJ(Tf|F^XrUyLb*I*NfW_f9d#mzLJ!_Lg@q!SoAC@sA%%v% z#t|AqAW8>8`uINScHR(7_gz3Cbzmi2eC2ka<*>{R#-_2hYm^-~9qt!pb%zBcS-7JW z)L`t80k#r@YBt*&9pWu2Ris*+!4M{DZY^0mISp|f8Q%QZ^rSza&k$Hx#XqA<+u9;? z&p%q;Sa-HLP}HP5hsmN!6OGa0Q{@jJ@FU>TV1b!JC z7-Ix;W5Y&jX$W0p@a}ZY`$WIKxTSO-!>TZ=eID3B*E?KwzyG$$5Ab0C+OQ*|LAswW z0&r|yvsIS0G$>U6A*l%o|H)3=;An_PrC?w`8&I5s%#tzWf}IqGn~TI1rkPYHfgH>Y zuMf*?kPiJiFXa8`P=oYh`cb=4vX$U#zTE!O79F#1Y6E5$#AG?tyrMF8$WpA4Zh}}F zI(IyC5-@m2{9Xx(31**a`jP5 zC$e&jZO&XhIz6>qsM6GcA15D}dj7_#O1y&))w}?*h#KTq?MYZfltqBb)S;ozBPXfP zY7S8XAY2L^nm_6{3cgD26{kLjI}NYV+={M%aqsn5d>v`_5|_g?1*Z3Ab% z!vfE_CMWCxn7QbA}Up6_2yktG)x!^KILLY8C&FRvj@i79Kz6R6y<_PAlt zcjVGON~%g$eg&A6Qrv`-BKC(4V!5I@UL6KiIVy$`(C6aYVLj9zoV~4$2tW0Bs(7ip zmSAm8^KL1lQQoz)m?1Dlk_b&|amlTV=p|?hz4T&2M3Cl1=e2W0J9*o$} z8_|kL87+Q;`h}deT9!!sOYa(|T=TXIA`Tx;9{+9W-j{`Xs3WMiL4fS4hy*JDBF(AO z*2Pv+GHvElcJf*creRgTVH*O7mZ#Y^J4w~aBpb+!1D?LJZ=;kgfr9bTFf^5Xq<;(KuN{HFSvkQhdX$GmN4{QQKtr|lxhciKGP zeh{zC;d4`{$fK;`(qV9YzS48QIeLI^{JSHaDT~MPOe}HUHc^!Q@^>nq%^(bbc#NmU z7VHAZ+n2Y%^XwM83XN)rTn_51)z9e(|EkJp*ngYFL(9i#c51bqA7Q!07ir=kg$)L^ z0V?tD)qP~DB-B;6+wgcO8gLWMt<5U*Y2Rk+LXsYW6BjEf%I1(XYbgy9GZwk8I-s=l zUpx{M?zBqW8nsH`vc=8pi@y&f>mVZhfc1{THtRnQJyMcdwwY0r;rz^k4|g4@yq ztQ;e7(8}}pgo1tD-$0Wv4ND7b#gD5@Ppci6NaqW-S!a z;&Jk9gJqSpi~z(JBOX@(D0*lJm)sj<`$w-0Q>aayoG^GCnjx9N-1~@ZHZUv~SjMQK z>=NDFVWC_R)R3c%vNkyjq~ZuLl?c=&q4@1ME>NS+cRnN$emVk>z!@k|8XKHw^%~Kf zS9F4)F5&Tad3OB_H0%87;7;CkKV7@QWHvu7*m2WC0N^L>vy(_;v}5<}Q~u`ZTs&3R z@&9!tmd)k8Uw;G!HWQ$`n;t65b(*a)H&8j$OF0uoE@A$CfUo|RAnOcgNToY>P54Vn z9gpa!kw=1_?_-Nt0NCGT@BKT7fvdOr(-_qMSf7*Q!$e7kED7DOPb~Gm-R^y?*UlCf zo&mU=VBjB#=jF4sIb07W4>oP!Z0Qa0?`1f!s2i`&wjN%dQ5%p z9bDjNiwN=m*n7*SxVkM`7y<+h8WJG5JHcIoySuwSxCafcjk~+MOK^AhV2!)G+?{it zQ*XUL;Z|L$_J^jcc6YBm=UP+790MrTFzwD!3CTtOXLmsQFJkw%6-lEJi;WawCWT!B zd6i-PuP`LLg8t@@8p!Y{R(FC`}GSF zon&a=F&;NqkUm%-PX!6o1qUx^SRww2olYOAavyyMfwX~3wO<@kG7t&*W`=;}_UO_4B-#Rvo35`5t}zL+ zOLbGyt<@rv!Ha}AsRS;2-`DUTd67WFLK(}z0lo((LeZiPBtE(zRZ&5S$-epnJwe~4 zs5{@CIsdStaoO@}2BpM9Q(4hKP;#k4K|L)DS8>FP&mUg+I$aQs^pKPGkb@4y$;jW5 zVZVnx-oLxj5S+DQP+_71*76Wn;sC(_i8lX@ECY$6q)o>mxoWvv;?Li*a&jmeuj}`Z zKt4<+Bz$46y6&M9quOkk$j1{Bi8cjlco870h8!TomKa% z;lan-*ZXSkKb8@o@6_ZGM}5@Y_S!uTfeE8YH8$hdeG0%$itNiobH4Xc57c~#p$w3; zi}*#_eFSaA(qIXbKpHPuz*0N;q0s=L^poasy-L2qR_*h&r?>d$a%}WZ&ojXb0AaJ} zF^g&ArFfb2Oz^x#TeNDcyZ4`vQeHFw@q|A+41@TUNu8cx;qrK)%4|Q{_7BDRzShsp zW-o3pTA(8W)DP{196jHwe8zze3-a+&&LPGmf2ZkE!7@Wfb3qI5E*9;amZZlw*t3;+ zFJIm$d@3>undH9_VvpX-qkUNj0JiLYfBt%Ad;7tuF9hwS+rvA{wf)sq7i0UQfU7G?*5lazwl01#Lc`DX)7mzNCGipa-eHTx)WJf>iD4Zb^T{5vyS~#1>vM*xpRuqM`whbUFz9HH zgO55BLkPWsQ!lg1SY9n0nyXk5gXMqxtUmYyacU_Djgk-=1dg5Dz0g4!w2#Sz1qpwX zK_8qe!xW9g?JhqoVxF2E^@E9WoUA%C)Xz==Bnsk7l!{Qrh-$)?=Ql=;!twXbT;CX? zc&;GYS{q3MyOXi}d$44%0K|=bfUxCKy8(t4o2`wqU4E`_4{8Zk{STaQ85Yh(F$#Ez z&qfJ?6!7y7FpJK^z?6x^jI{H2mtwb?DszMTYwf3M5BP5km|S<5{KzkNZt@*+a@!=wvZ|JZ{j-Lo-32J&}Wu|;Z-4V{-c{H(N z{PYq$h&O#}I>}kr^4okXj#eYKu?RTJY}JQp|MU2R|F-LJT|azvASbFa3hNMl;0xU+ z$}bQJjtG0g`gUeme`Ho)K2_*J8OVK5otlezU@53ASN4@>(Jx{eMC1UiDGrT1potzA zy@W-B38Jw3%|g^iSVPRZ^?8A?d;lXceSgzKcBOSooM%$V(m%w|33qmWR>rnPI;SGT zn%iZ%;dhe8?EXdL@%r%2a1pUiFl7lNM|HUKBm?+RB&zx?aKBg$7EQez&75qCI?}3v z>m#1Q6e$;Z=<$uyDPg5rjb`2_Qc=`zF`}qA{*uHza{4k6VS?o|a8UNVqzGkBPW44F zxPtlT(}h&zSf4bFB71NWKovb~Z~fH&fb|S8d&u=Mz8`j~4yt1m8Rg+%5_#aa1p+f{9){ZZ)=kL*{tFC~y6ED!ebN6=H<bdT7TJtx~ptz zI=!sKddm6f(>}+(ozUm3W7G0z>d9}7xx75zKY9N0NECH^aIo2aJ!u6xf4{9laUTOB zIgM5)py<1xAx7Xu6R?@Ps56KAzFpZ?yoh4Gv%ImOzg#69B+HVL&S|=^=^1D|CbBViQfr@xZXDsmZMBb4ik6 zg;&2;zb-O)1i|DuyN|C`Wy{Yh)f|jK$}sh|yFjR?`5lLr!lVHJao`4Ml-|=g06-03 z!tZU*ZEuW3Di?>{g|;X&aX_E{?g2cGwe&YqnST5)!(}QBlRZP)TbzV`&zZY)TB|XPzVuB=}xb%t5yvVkbXE_yL4230~H6 z5v~tgaOG2ktOKOx8QJv~4@z*=ALRts?}yy!Rf{l*TMY&eiK7Q{!O5EHX4iM8HwiT9 zoM!loI`{PS9Ovi}F-Sn0K#U0L^>?{eUF?3Aj%14&EL&(78#Qscu+>y(KPf_-usR-z z_K#eQ2#I2qk-l3TRjcwEN)mZCOb*&F1sKAbX@Z~UXYVUM+2bnFC0%+Y0XT6<^az;> zh8b1NKd7uT!PX()1}GzB2~=syWffzfBF#^NB?3_*dQ$U=V%zHlh1fIe4sRoVunHsp zLFJTHUjO+=3kyg%qP-7ZgC}1|0Ob+x14iIT*>}u(_H^X=FP`rhx%nNiewHQzj~Dx= zr>DENtcJv_*O!Ucjyp;Ft6>WJ-sehNPy){S`4hmzUeW^ed+q_f(R;B5O)!YNV;(ol zc|k)ujmx?7xwW!QjY+CPk@tW{_x*`?AQ!-|>;?0`Z2jn*$HT?l0X~<<=N%=>bg@#$ z<2Re-jySn2PYdVUc$JUil$EWyo0UK+`K*Jlty9z>?}H^cR*K%jhC#bNgd)>z+xJcw^ z3yK{3Uhdyt;?KR_VLfj*-hQX(-zfgApmB-iTRWie-F)A8JG=iIEiF`Pj2@|!xj$@) zHQyd@?DW%FNUfP9>GnL>i>Y=)+MRKlowM>i=Eo(wT@Ax7asQ_W`!5g%t3L0_dM=_s z8&4P=?18hP1}z&R7TC2w8ItU&SX7`}n70x|W7zITTEjR(%`=&Ux--npDaj;;hGGG& zn*VxMY4_lB^2fc|L`~!T`J8(o*|D;rZDk(d@lqoCBq1P-S`canRh(TP*7N&AkIGLV z+VA;+TEj{ClYuSi_%=J2FL)|+2<_4>o*Z%_fj$Qwm5@sCiLb=Q)vAJX5bONaXzaI@ zn&K}~d6ng@SDs04%PQ{$-EjHqrj5d@%uQbKbaFxhrYD^A&%(b z$3-o#(r_L|IdatZ+TTld>t;dymWyR(cbQ`Tl)a#FxuGdG4?WWd7 z12;FHt2}pUI!*<~f_YC2tW;3*rbC+Emb37#w0^4W9+g#XS^GRDwS)Z-L4A7HZC6SF z3LeF4==U*&&qJ?IbP?Yzl~vOFWK({dd`a_puJ}(rWcaB+r!a{vq;%LVm>-r0<&rsX?Yo-u>o6p8?0zr2l z`zP$8>k+l~^uhNf_YIeWz1NIVhf`L-nb%#}PaPcV>e?^9>Q$?1*pJUIUgY?^ooinJ ztA2L>hDXqLL5xfr-@+j0J%e$6y>Bs}VwO3)w$^=drNDpHi&ET3U=-2PSwly?SFDBq z&wzUY0tP9)Z@I51uB2UWb|1y4On!ySF9?x6OXHCdIjRPMJ{}AR6dtV3XVpg@}v?I z(a5f8YDsWHj+$6oe>pg271hZ-M8^*S`MoMqfaHTth0E-r%k z(>GpEH?~pUtD3&!L}EpXzAURmX{+<4U(c?ad!t_ig)h8hEBc#F`!B17jOsb(aVx#+RG~d)+=)D&8?lEY zwbAdLa-LUlo`CA22>@F@`O_5Ts&fHqTYFELbo&cNLwvv6LV>!tjPmh|@_E7Fc_^>r z*y_Vj*TA;FRZ**e`3SL};fl|HUpLt@>d1TeLgDa;sdi!eu9|uLO7H;j*U⁢{-VU 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

%5<6q!FOfP9dkl`= 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 k}^s^b=3eo_gWw9f(>;GZ)XXNPodu28lBPSpyo; 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/android-home.png b/docs/audit/screenshots/android-home.png new file mode 100644 index 0000000000000000000000000000000000000000..53cbb2161e8b9cea9f9f5a0812c7300a9c354df2 GIT binary patch literal 551458 zcmeFYcT`hf*Di`kRVmUtf)oKMDouJ3A%GyggHi)XlM-40mGYA=Rq4G2La&joARwIt zsiF4}L3%wqzTfwrd+#52oH5RK?zn$^8H16nV`uNR=9+8HXFl^;A75&zlHFpug@=bn z22y*bi-$)biHAq}ii8OG9~Y(wB=AMxsRYs|0X~5ww*LVCzTv5>s)Pq0V%fyQyN3sQ zrl{|mu`>tpN;0_W-5V}AR-n3<*$03bE!?=FX?u5z|0r^<{`L2H z6%|6-PxBn{FO^8RIN}vO<7JRZtPPM$mX{rnJ7P>DE?4+QR~yf6fju z#e2&<;4QmU0S>uNBzL`Y%JeN55~=d{MPD##=v<_;VQEf|LT+v@(^Kmt&H$B`f|Qz? z#}()%OJ)hzk)EU&bG`R^y?YApZoIoiLh{nuI+%=AM&G74qp0LZiMU_5P3!3q zbIWegwez20m)oCOIS+@@J;nT2z(%QKyLGUTZl`*u%bvrti>Tp)9y8B6dAD{S*SXb$ zl{z?F%k8U}Duqm7dyQw!HY;Rx)o8QRgrd|TE{ohMcx5lb`?&Sm)kAhh9Q*Q(=9{Q> zoRhdOt$jUhAx~zh*{0ZJ$YUIbyVeiSB{yqW4W8=`qzLQz_@t1t$mHB4rYLD@YWnU; zOiV2BP*l@G3NqU9?t|B&AN^Kcb@9N=%nWI=M7eAPbNg))l9BhP@{YgaU&Dn8Egb0` z+*fu7kP_&jaWm}KQd*c{-IfEelHfJgM)2-AR$S_+m11q{oPBK@HoWe*^7~VTVPa*a z8*Gpa7+_A2ot+(dHyKFE>xW0MhTXdD_T2IOD204b<sdQm#&zzdW_s`e8Je5t_5Vde!7WAg)Ztl za5)fyV5DGxA(5 z5cNB`xE&y>p)A1Uw7t_9TK7!Hr82H^X_@(e!A76v0Uha3Fq<~C15f((Pt8t!HHVz0WErK7GG_vd$LzE zntyTv`@nCCc-nS*xU{2AKvI1m){<y;EiX=*UnLi+W11j%jwA36jV3 zZyts-CwQ$fI&4-#E?#KM{wd(vOrEqvwPRb%TwPrS%U*Bp7dE)t08Ydty;eszhzolQ zC246)(1X5+{(<4zL!5hz=JzzMd<_MbPWE`I_H1Q5u0CklA2~6RF>-zrAD@Pnk=u&h z>h$as2r=4ia&2Xj=DGX(Zw-=CVN32|K6blK`-d=ZZ*O(<7r3lRK+>0Hja1F6{44)n zblM+ZBEXI&QR^b(b0AmY-oh+VIgM<3C@XxXriVGvhhV^d}0_Jr8O z0xdzHk8-CwHf8}m22Yrv!`~BmX7FQYq0Lgp?k_XDr0PpzQ!Rr=kIrZ8=jWF?2!MHY z=rD`Bh=ek?n>7TMQl0ZOoF10CwOxj11uRYx2}?+(WM^k5P$f<@y2&4EZB+cQ{B&!R zfs;a8+wbaXpj!_qhAe~2?Zb*%ObNpXr-40h*63mY#4nfWuOM1lTCyNR1A}BkxMgWZ z>(i~-(%K@6r>!c(Ew+7bg8uC$f+h{$DBUMesQ$URxiH!=yffL2X!jvi>^zhy6MItoC^9O_jK;m-jn=4YcHje0WMuSM*!p$u zlqW7GRi!otw|57@kY!&lWQx%vzdlc{eVs0F&v(miW0G}>#`#f;52om!-z46fvnrjP zoiDD+fgOXHY1ckKTE*=lLDR2l8mWRh)2KQkbZTZ|g+o?A%l8|-K%O!^2&x6v%@rI# z=v(4hJk;WU2E^A+RSW&(r(eVu+Y2~k=;Pao-O|pc*(A{gMr_U&eWUsKtF1a~XIh~WLbyX$I(78rn~$re+uSX8UXI?(X`#qm+e8`ZF|{-6hSgJO)N$wL#Kh-eW7E)Qpjg z^u~f;LGo`;)WX6;#Sv|QYaUEz7;%H%y?d7?6((y6j8Gu}(s@e16_%RSxE=Q~c64Gu zXfo7;TGV%hvKVd83G%4+h>VIE-_WrU4cu_Q{JP-){XKdPc*lV24&am0mwz}~&*!BH zSa?H1mV?8|8H=6_OKRK>HqFs`o#_SSoO-YvuyPV;zj0L7eCQKtrhOn!y)mB;PG@1FLa2>*`9&fto5G$HJ)BqV=lFSSx{G}UuaiY zR#FmQSy_pHag&CU@?O;Uv4wyS@863C%@Q19vkO)VYz0po-_czk!5%{#_<`Kyped;* zVF^im!bacgxHTmp`5qYQ#l^(|CKb&m&1;s+kt?XB(0=NZ)pohd3{o9hYT6m&8_e2% z)v2iL6mWRpY^u+UTg)=az>_L_S>J5AvlV4p8anXK=kbG!apAgC6Q)6AqqfzY_qx2; z>sbOI^9abunBOG6qwA&b^#MCDm7XtXCNALM7JGz27vCf%FDd`33GAt|^75p{#>PM> zbQOpMRaGKk5K^N?_*_zki~=r6NjeyVKVM0n>XNaDs8J86mCVkX6A}|U|5(V~${az6 zv0W#vZ*FdGQE7&SEHkjNv1y%t5E78qXuMoCG&|o@&3YNJKt7m-y`-4ed##hpwYkq{ z^y}ywZdZYSCBcNofh=5G-=2P5fr4A)AHpP1=PFmW)a>+?Cru~MdvO^Q(;{Zt_&T$p zz*WcpjC^%da9aXyq~6ctGGEi&7ZGGyVMt3yTUJ%_QhE#m1_J#S z4GMI5#?4BYcsQnR#Pf~e1daSWqa4`U%dFc8dqfAS&vtorqMxOjQNVNz1k#%M45=vTLP!yfpZ z;-6oF?^#6!U8>;zMs-G~lWIVokJ&Q(!tTz4PtJRa6%gLMim;!W#+^K$R ziaxu(-VL$pb9!=82i5`}k|X>L~%jn;&KAUwRtl9iP;n}Dx(ZvmWZ6?|?m4sY&9 z1-TymX|di)7R-VGYj<{^4!Bjz{yt3d)r88H*_WHWB$8=3n_4_xwVpZDXdM2k zeBHL~TKqG!=BWw}qE^V-Oe3|v;I@%SEt=v$etz~CEo*m^9E6ME(Bq$D^Run{dwV)y zHE``3ZghU@S(Sf=WUYvAlb5x$m;y0pG4Ce*)>M8mOhbegKi2-o!0>pXp71FAr$s_6 z0cD)*MbqqThNt~D%+s>^GH5z^oR*$>J;@K}#ZP7cpx1qM>342mV#4RpoYs@?3JIoRi#{9ftleI7XhHhAN!&C%wsW*|AA!5$cRX$caI5fc`{n|^SPI- zm)^*$$t8d5`NlMz%$pdj&XtqD zMr~Nze5w|5EPXfq%+68rbNxXQxK|76T3W*Cug~Ax%bzDLj`ZVd86BNZSJ271eR)^f zcLLFjPmYrANcKcCEpJgxli|l+12FYTU9D#grsoZ4&KfLy;n+zUJfuQzsgHHW2LH~w z6?Kc7wR!k#_Tzfy?+e^Z+{-bWGng*2%^zf}wb@X09DF6BVA;vricOQ*q>{Z}@&pY0 zf{=h@~6sGDr^!0xH}rzbi+x^P?}2jIjtV zoNKtp8o&%u0drt)?|LBBjQ7w!^_l)WF1oklX>Rd6y#G&I&e zfd&NyogEEelK{9j68|#dSSI*tkACREC`WK`FlM#|hFrs;d3PtNz!Ucml}0RZaK1Xz zaR-!QD}ucp;?3xiXN3-Gxt=Em-hk-36>H<`>-(U_sG!>&2RcHWxp}#zcd*FX)b8x} z$GdaI^UVooyia$qBh@yoSW?pJc8_n}-O7sZ6v=xd!orc#MrKmS8GmTzxn~!h7cIK9 z%PRIh5R;>}g@--787qVUH>_;mCvp&yV*D4oqSu7oH6cI8ww}vHT;5C|+MpmG>ewD@ zj)G?e#dIHY9c!n=HO5&4YwAZ!g?Ya{$+~+u8z>0?uZT+*K_PK1T#b~+nZL5W&I^G+ zPESwyfWf zoS&I7tFEr*7ZNh`GikoKyhOGKC-6k4-;(seW`^*`Du6)3VSMeJS_%gAW8CEg|?XDGQn)c!J{<_HV~ zWTVvOzZ8v}|1~v`Vwzf#eEI-pOLp(30B#0&;G6%8#8TF)e6fF1R?Bz(_js-UGJ@>C zAM|$>@%}$yBmdjj|35aiLX^zOZ{^77n8z2Uh@ec^01iIkWmx~4Z}w|y388*;nZ{^( zF|%a&1)+M(cIKk9{WIo1P{?hS7CSf}ZXqKhV^NqVZpeQY@0(lD;hvDgDq_%a<4;*> z=_m#=3ygwuTpvJ+k27Q-_=H`sR+uZkm)k;!J-Xe2jdjmbt|bf%>hl@xLZ$3<^=`XSf`t9DzkhS zY?RT;wUq{7lnKH(wvQWOK<8K4^}djH`)veHey3&-Sk z+=x6$A4C28{iQMn0J?m9jYiO9Kiv>+TDY_Gkd}_FRP}f_GCFeXvrfL4&(2@E-_*$V zO;RotgPh!whoJ9+`iF-nwc9Vst%6Qf7{4%1H@aoFJbwmW=unihnI(u}mVnPQv6hyV zjg8r994>bePN$_5{hUM4-n|P43J?G&en}GvdJm-0beU|f7gx)+0LY&oNv#P=1ZodV zPs3_03W;$m0b9Dgt$mE#r5-167XbWuAVtXR*4xUD!=) zkWc{F^)T8s@cTt6m-ipn*Z#$eOu*@(Py*~0tY~?yFGu76+5W3 ztSy>9-ud}sL{D435W5!aaBK>23F0nVqmzHyQUJ{Cn(haKfANS33=B*&AJ0utt}(4R zJ4uW?+*pn)ttuJ$eb$gb<^ruE0fZ2J&Vyco$(LU}5;;gI+#O_y( z^^7N@rNcP-Q*x}-v+9gn)oGwd(+r(PJL7#-aQCfet?1d+3+CtZG zTV&*|xq$0d)0)6O(n;J-5$&zIOBx|eC|x9|&KQlE&~ULF6TWnwBLc90z@*t<~-fMLI-+$$e)wD?f6%!Qc)XlY<1j)F_qBZFpD4Wxh(oOt04aUZtA1w_#Wq zAs@fE(#O6}k=Su%@}MhNVU+mxoJ8yuG-&7Ks%1az2}@8SjT>69B&1;APx2B)7! zx}?W&$(~Gz-P)#^U3en;y~kUc3^P8giR!#iHWdl3;M#OoN!FFHbNcZQfvQ_X6s5bU za@?*g4K?+B3T+Aux)Dw3o|KZbg@s(s3C%J*3Ji5^KNROa(!kMl`xGoA!}8Y!0QcHO zN%a%z1|O0=XNh5xZRtDw*3+}qVCIU9=Kz>NhJu7KWz$;w7&hpI&g#ybGsF2FFZ<+q z;dP7zT7PYK&gXI*o>o+v`a%aNJPZJ0$^zlDc}XEZ;*cGTT4BokZZdqfsLJkW)6avr z0_t;Zpha``quq*v0yCEmW2e6;0Sdw;Qes2E!U~>*L}$49RLIz;f5Z9x(Wx>k5lOqo zRFWeYvcZt^YktnuT-(txtnI|NG(~9o&9SM@>(VjE4)Xn}Gcx#9U6B^E10=@DwtVkr zXNB3(52xgAhp86sfsvtKS+D}dQJ>|bRXV1w7}q&vS|-%Kdp^8DYamFBO=wz}Pgf{$e?hX3(mf;OkxkFWQ2Tso!M7{&#zM6*peqcY5M8#c*jw(|ZWsP)D`}N) zHVIGjL5d!3j;jV|ye)lwF-tM;{I=tf{ZEG0liAz1$feHY-ztQ(3w>Qs0@A)laMKBA z_sOb2%J$1X4njhv>kd9XzR?Vc^tK1ikRuBRu53 zvv%9j8jF6TKm2V4ylgaWb>DDg4b{LoO5N|hes^$ybhnB$F$03O>BFEam~d;} z$`uG`eI+L+`@0Nnhs#k=P|O7k2XD#Bc>P%5XgS()CWHQI&#r`?r~8mi*igvZpL7M6 z7hHj)Ty`9NE=^2Ke4rXBLe(>_kKcY%yF`mkPRCr%kxkBx6#R9*7VGb~06@Te=FiKu zQ5k#% z5*uBV1K2EWFCx;Tmyj~xamCfOntPgAS~@}k)X`V1 zZ`$R9xckOb(#h5fI_d$|4{S^w^uFCO@$w6Kv9z&)`&SZTt67M>BroaCNN3P@WtFhY z)T_g7O#1-^qiDhCDX*1GvtL;Kdmj1ia55igcevOUw$XDvoWct?tqhlrcw=R0Xs_ie zM!1F#F_==yZ;RnjBess2nU)$JCB$gAA>Ec`Il35r zG{oBTYnDM=rE{OAVgO`s7WapOgJ?;x`e&-WqtX3(3 zJhOi)G8@~~HfP?NUNpOtm>zjB6bePQnjIU$aGWt1zVX@J zdv~mJWF4HYZr>9G^y+%uNT2E;p8Tl`w#u!*fTNx(XE*wF3n7uLm*>95#jmJj`MdvfQ~=6yBt6Q;VsHC(*%fyXiDj3t}~_Qba!n&Nt97 z3RZrj*PWwSF}i_I9~6R(%*={gpAx%ZqA{vQUS8NKkVDp!5!8H2TH#XOV>4+Wd@a`6 zESUyfJqNa2A!{RRv9`4~!s8?8Q}|INcPYPMMHO>ILvN!LFF(Hzs_b@Y1AGr^uBfOO z6YCgRw#AQ-vqFatGdnsD`5USlwGy4w2lC-sU?Zky6#t-%vW05v$HlQaii#hVl<)y6 z5#=@LF{AiAx-7U*MUVA|ye+sGh>I`Av!CWZ|&I$DRQiAP!8i7h{-n@0S=(x3QFm}g(20FL7oW=j8yO1~ ztYuotMO)UtSvmV#*8ZXMNmob@AeV63tV}0^ehBZ8VsWlk>wbRJK**9%2NaO_v59y$ zBB;Z{r_rjH#msJo=FH)=gNp#)=jP_ty%pXXfT6f>q?nzXqrJ=K`l~3RRzg)wOze#w zFpUmSpY^Bb(YrPzlBmi#$J>&zt*g%xh{&RhUcMYKvNbZAtn(#jg>YHEjL!y)&wm*_ zqcbLs{eU+UP>y^ zSVP^LRa;gs$)I7^Wik=zhSdiF!#BLKQzuWu!Lot*o_X-QcYUCnjGMgB4jk1FRCg89 zYdpyrtpVOufS!wkjGfbeA>`8g1utU0^_&4ec5Li1pqBw!Mr=amxIJ59wG{GT6O)gL zafWP-zr-HV}8z zC@gNZQQzT zvsQcWeC$AfzmwM;+(uvm@_e$4WY0*WteD1>32{=o=RwU)0Ei#%Is}W@d$I&$wiY9u z2nkO!M}#S~AqYR4rD%DE`E+juzU|m~wJGdpTE=;~EOogxpA=TJ+WLUWAhVg?Nex+l zFQ-w@loUfS(xb6hw0F!(LfQd&J1r)p`y&xKOGyacGCMv{D7ApBvbZ-fka?ZhsD|)6 zj56Qg*j5TO#CLEDTUNG1!7FxC_4QD?TRU>&kId8aQWQTaFmCX~$YPIxh6EgK*L0|y z@H`eH;Kr_99B8Ru=VAA(zvm7ueJb)v%clRq)1@5a%JQRK9fObo84FWDYmiUNM3wiU z*WCMjAkXSxcNQWBo%TZP)z{bi?}n|<)I2L@6u12h^wN^5w>K=N`O@_ccK!@+0zf5d zc6P_J{d*LBquobfx*?fupilezM=uRlKN;Y|Qr(a}-aVCGH^U|67;2y9E#C*o^@{!d z`woW&2B?h)H`GRrfOh4vEKq<9Ui&A9$81$-Wqx3d-8=kah%QhoESIlwvYFdrZJ4Aw zJA4^I-owt+%jH#jDF;RD5qFV7&DsV7r89QYHaNW4wp6kAvnp&?uyVQ+UBdgJ&=sQ4pUs}}i{QS?+Hn47^b&TVp=U=80 z0NI!5ocnl;R_ogaK7d2;?mm>5KD>57wYFg2nW#@?Oqq_+Rw#ie64L3YE|Rrji6W4l`xd zBk_YvHXk+J;-SvSSnqiX^~+1B*U@QD^1S?Ym8Dg1gE`XR$m|h0EB_<_^1$=!1BXj` zR?~2ZcY(HS=d=9~FrqC!Ug0|{^;;H!$1Qg2ZnoH`uZ-_ z2wJVaUwcg$kr);h=6IB-y}1vAzkD$`dcCQkF>nAd2U`FG;o=n=ba}@2K%_)$z-t4r z+k}x-a4AqrT-7$t2WhyqUK*xPj;9G_c~t|7IcGtWnr|cW*mS?N<3SmEgTLI!o8R%q zf);gCi_Z6ZkHp?wx`%r>@HmgR+_Bq{@&7OYv8tG8F_;kp8)qmff6zBD$j{ihX<8o$ z6Lgr8#t=#f9~Q33*y?&Q4v2FkbnSky=9nhqHT%vDu@LCUsd9=gpM7M6KJ+LEf>YJQBC z9#|Crh+4y9E9tX?L30S{E9F(+PQ}ia{YU|`<}%dc;$p5tR-h^9H**jiGUssqp4gmctE4nIE23uDNaJPRa97n_PeyQq!Pw5ijTY z2$a(F+KhngaxNegXcGE%s~Z>J^WNS)k=FnEVIlvz<3V%%y^&Hlym}_B}i+T4?@Wf!}TM=1bF6-EW7C8L;{OaF& zA4Ww+PXu6pBAdp0#U$ZY*=_#o7>L)^)AfcIuPg37e5mR6^(tKGOCadOvXZjW!Nrr| z&0)wza|}O@sb%?dus`z8BPix9--dIdLUr3*XBr@PT-%*%dNPw|3-$oGqb7k4dWRp2 zus<@+%3|A+zt=w^0S0Hx&ORjXg<#o=MnsnRk5Bv?Dnx;Z^oEuNvifGMqsUGBbS@{i z$5Z<;1T&fS^YSqIxwCbYy1>?GegqqIx6Xw_;@muAaW zrm-$`wj^*a;2}Gkp0)e842hSKG?fpu`C966vN2yHIYgAfd9TAruQ+D1=?U=zLA%C= zB0D}etK3_+)oE!~iiZ|iY0wBn0&#DNhHo#=AS1dMVJI}?IuUtUm|d%#Js=q zvHVF$F1B#pY61`stp5jp-fk0hYvdUqtf<|-9S5G-4#W}Xc(Hfg7m^GtEGn*lwitbn zh-79>2c&D2ZCCvx>ljQ$6T|x4lfQjBupB;lMhzf64xjfsW}Wlt#q`gmnqiv&)rvFf z<}s|MW^5!Fpq^+L7=BIL;cSAJ7V<>WU46RBF`wr}maQ{ncfzD`HZY1On!WO$e@Og% zeM<@oo;goeAcL*0Dgo7^okZ`2+Zs$8JMUs5j(b238v%fi_+JI}I&LGktgUv_~#2IHt3El3zf8`HsY2))R5mg5t+ zHn`2e0cm5H*G|dCX9n(LZB)tK`=W0)-2Ht0n_A3qPY=2IZ+*Vxhri7Xy#G28|9`j5 za3;q4?;hoU!C?@E8N|xifWC=|qqDrowj3FYWR;1h#qWryJD6TJ=(EeSBNrX$i%(yg z&7Qa+21kysW+AjRG!t9de>aijDWJWo4xWR?iMvcsEPTeh#`E5wEEif_1SG-w?QPKH z&z~PyS!Mqf@#agQ{WYW;urGCW6X4BjPJqZ&6gE^-^S1TLu|weDRD#8w*2;enhG z+{81pfSYIIKfj!vu3OpGn{GqV!B#;g z0!DCM#n-uXmuIl~fa^>9$=`Dq*aJ)>db6YRgE|N_Y6Eop($doGhasHP1D=1KXqx;+ z1PFkY&PPv%!Mg$2r-5@o)5*aObAD-05tUmqwJC`Uy zej$`Jhaw0B3U33X=zu(wkDFTski&|8JsR!JE(x~IBf7)zYNOHkq12zBPYwXoICb_s zh7GyX5`KrRfSvwfReeMp1AIYT5}ns7^Y?^Lj>}#5Cgb*?OHt^w0l5_nXp-hx1tXsf z%Q; z-<|;qu>U#Ph>&iAGhQAhe4u9F6Vxezl;mQk*0UzxhuwC;2vjyHrD|u6l@FUY{pOYZ zGdr4m|0DE#YZPF_#{w!0VWC0yzyG5d)J+&nzuO_58set)w{ zh##f<=a7g9ghh67aq(?_M{`F|DOca3HzG)P)U+k)0uDCd9UThv2IE!4Z2l#qkJ=xa7VJm9y<8rW26QgS4d1`($E4ih zkuZ~xRyHhmJv(v?90rovr0CcDCvFnZ%L4uYa6spE;89M1vz@WDYJQtcCv*W?&xF8l z!*JazygGUU79pQNUk(r;#P1)L&p9~oT3ugfwq$<#wqQtV`)31xrHO0nDqW^G>dRYC z&)UPwy#$SeUp8^h+YK%aZO8H#FC8)-DbCN&!yi!No;VT)acF<1Q&Gc^13b-OP&}Z@S zetLL|g2L_h;kTg6JD5yH#tM_a%d$Y@@m82vlF!qm`o_(!6d zjz@JaD~j)@O7h=_OjF~NCrSo=fBs4#CyL+k*A?`fIZ#$mY;Yv@W321o+rKvzli-t6 z|N8PNmyB7Q;f(WsKyyi2c&nU)R%@l*`U-fn#xA@~jZ)FTB0HPJdGx;`Ap)(5EufbLg3hib{jO%i!UXhOpyeR~VCwZ#+IeesXqpr4^l^ zE+8&^J)3M~&LQk3OmFbl++b}$u!)aty$(w3C1(;<1J2aB2pEn(UbJWdqpvQf8=!~= z7qlg|X*B=2V^`>&i!n~h0IZTtR3ymP&(E>vVDoHU{%XP9@^;84t0jnTipy0oh{Hn$M^I|fz&yc$=;Q2YxuN%~c* z;OauW|He=M7R%jV_-hcn|C0wr|KBjC3~+e$m7(w)6i9npD{Df{2t?n&xU%K^{QjX= zVs>Tf?A)xrg#ouVgaW|GIq~u2z_|$kVtnc67f3cT&ilD@vtPLUrNN6#Cm8?gvQ9C1 z+wRtUVg8mA*L99a1-eaD`j~E8!LNdRQoSB!YEmIqR*x!a8L}{hahcfZWL`i6X&4rS zDIif!Wn~5iCPMO!rrso5Ib~@~2FPaEw380VB>9#`zrNYJkQ=-3sh^p?o$7}6T=G;b~BmfmcZWfYYyP=5L96OdUM65z8^hPmV*cDk_rHd$b2RIKp++H zNoY%$%+0N^Qa;pfr$qYsBz=eFe+}$fS!U${0;b8V40lw7({_1HlL=R&6w(A1D-(y* z1CG`KhZ7g&1GYa!G*lbM71YzgRBB9JDkqU9+$M2%URD%H^;sLF{__oW{@2++%slE(Q zHvmjj8LTwX%pz0fq2Z~2OW(}6a@GyGTV(qQ*{T&vQfIIh(_1?X59F{7U*w8Fb1mdb5Z0hLTtjfzs{4I?4~E1o*iGYG5L&?l>yVdy)hq z;=4U>KefVY#^41OE~C5iQmYwgc1V3fH8;%UvAx`|&GyjjmnRO`Cu6mL=8wO+aS~|7 ztD1atQ~@V1A%r}vN2p}T3PmDdw?0dD74ex$gL_q_*wi$v@92`KXBBOPs8c7Y?X`xq z?aH+b*uBmAMqyre{}F!Zo!_lgu5I)gREFVdf(pi=cu}3EQDXS-R7hmogSFk2N%lHI zdaygx0hhrNw;5hjcD=6;n6DRUz>pJ+AT}oM2L;Iq)&Z>bxz4Cfj@96_(@{q#$^O(;|GdG@Im4EfxVzSJT#$(W{#izYBG<9>Xp z0w*bpqDxEc$2-aIRXNz>1&B_XDV;6GND91v&*48O2l{*|#?3b4&<(iwJ8f$2A1jSZ#qs>ZVNN#W+qv{eJ&ItdqMej?xg&(%$ z9lYox-X{2mV!~Mb-q8mYFV*wv@MlPwNN$wYlkj~qT|Sk2&5%&Q7h@mA^+KBBH(gTL zh>m`wU)kJTQ*2nB*4TUV5)sp!I>o0stnVTf?|0s+qT(Q+a%WLlI4yA0q)`z~dolK{ z)7v6+;v0&po-@rON;LLS59h-Z_y;WUfj49{IhBB%U^?&3vwM1>YVSxK74v_y5OZ@E ze$6x8=UatMIFs2sm_EbMaO;|ug{`aU=l^-y=CcAehB?)uCQKV|6 zT6N9-|6-YEILokg$+s?FFEx>8!AQ-ChjqXeRjBwh+r>_Q$RJ4t4V}AeoVifk7&%}V zADY*9)i~DJmk66ha*B)9n{_!Ox4yZ2r1tgAQV#7@*H}PEn&u~|ttARTDt7L@>qy2_92)C)~(2-W*FTQ z8;P`j!?cKyvsmQ}V@Zl6m$e{F%hfGu#A9PXFG4?V)x9I2 z?CLZP%NJ7%Cfa&%K@9JLDe{ zsLB6#twa)wPW^jc&OU$y@)|(E?0ogl}@E(t~ z+Pig1{3>$vx|?NGsxGD&@zQ#=!g!@u(JIYC$s(!{Hwjaa<~07Wvc|_FrMi!b0imzi zCNn!f-l>i^<|5JHCj=$Ds_5h*b){T5mqQsROvGD*^lmG0c=OJ5n-V(SLdBbcRqukR zsKxHf5az-*VTKzRY~kmDQK#M=24)*qA94(M|5WB(DkTwH8Vv?}@&5=Xnmm8b17nlDp}mlLK8)e*D21m?0)ky$PUa8z?umgP zp=nLcs`yY!){5#Xq4%_`%aeZA>8`9i9Arq+{RYku(Kh~h-+}^jzH-a1Jbq&9iEofv z{@uk04n=tA@~T<|&m$%l`qj1HU7Y;_*2!`4Oois5?jjAfN#AZg$+jLf(c%mQ^!v2d$g^7t|C|%5ecNS67CgA&INei3%5|5I=r!4)Pv#FUf}k72gHM__ zP0Iv^rPU!u{|dT*v7RQ>;HmP|vS+RP;1iJ48IqLZk?P(HRpF$3E0?J7^uZ)|>hXhA z4d1L@fJN3x;0#p&5wAYzc<=N3Ylu?edoS5&@T+81r-!6e)B?}ml+>p^tN!k-Y%cKy zn>Xf2eH)*9Rf+CHb!HfwI)6O=6ZR*+%R7K|R3P~%MwjR_FN%7V#7V{Un&ws?yof`c z`KMT-R!`*HAE}WfXzTh9NTDZ(Nd*=*@RS9oh^mdeq~|3pI!o5pVVW{^>8eldWZG{p z8mg7!>k=@%Q;O80|2%j2n39Mx^Cz_wBP$}cl);AXJqsuSFK0cf)YPWB=b`Oel1J?{ z;Gj))Cb228r_XI%>EU(1>SCx;3}=f_PC7q~eyk%rGDEgT+Xw$M9Dn(FH=a=P@s~@T zmOpr|(uV@GrwXc(Tp%(O6AOn2Ym9+V>4At=ta#d&Qj2F5QlDv7!3Da;93K;to?Cm= zDVse=;L1%_N>Y%<=ip{i)Yo84&#)_^yPp)X4W`n4!(tPy_+vqtsE7n^5nW{(m_LJ8@=ckci%$p zDRWY)@p-TihdhX+REjSkt+2n%L6EFYi2hK5%yMf_zZceV3=N!AWQwU5OgrRDDjkJm zI;1EYnP2ItThJEyym*Yv;&Rfyuky~W_b7JY-(e`?0WOoDe_B{R4X$Bx`s z4kh93DB`Q|$(&Hj$azn4tL{=J#wT(5C(XAPZ{hdc17EV~@PB++mt1hyEa6MZxc9RN zuAcmPkzXZY>jG0p^vK}wrX|8zZ$etecM zKji`!BPDXZK7AKJiBtu0Glz?dw7h05b$@XD&}OrYx|+vs8wz>U24xlqFd9SHa{F@V z%-Z_D`8-Mn(RCKPE2Z!;q{_IkQYvJWV|<+Y4Z7{FNX#3kQq?#!BDJ%lxbiI@Q>!e_DX&Or7N8{vqB8%cpvDgHJC+ zUOByeKRtWrCM@OA(hMpU1I2V2Y{afpOps{LFSPl;Q>S0aR0g2%RMeM-XB#o;#7$xmd-eeGlIl{KOV$d8bhvH1)WxQNKeaJp?U|-^eBL;`;I0H^4fVwD zHR*qVH5e-#@S9!ER$vItWMV))783()AI+F}j`e*TWMbYmi`)Nm=b_mkX>kU~r9m-p zAXDEz&SupEHZrY90?MDa1uy$dKe}fg>Lt?f0*2%yffAjiE=aPy`jU}hJCIVr1$tJf z%W+3JJUkp+Z>kS7Xel!&DlRTXu5Dm2gapdU$`AN9F`Gq|?b(L4oh{yw_yVG;d(@gN z9HHDGT^^ny@PyejOp@-?-i-~(iU-^uxzdRnbt+fmkeHNzqd)RQ85A{u{z|6}@6A&3 z{;(;}nTk}4{zev=R0ai0JmaU3u)=43RZr1RSf~h|&FR{w9_kRh^U5o%&5m~z8O$=) zcRyLXdUjynfR|JM$BO<VY3Nq&Al%`L)E%4a&yS}ln?ye$Yuz@i;W zl;ICeTB6@JcfqGjbZs7?#@^I}>p9JbvxQ00tu>?dN1W<6wzrFsk$1aZpEqRc_giE@ zk8GyuJ>R?BpXrM*3Az8b@&Z7>DKyy*7qefngbfilz0*i)a7?G`3JWY$Fmj_;BGnc6 z{q~0IP%oKmfq-KjGna=Z#~spJD*dfD)i^dxz7o_~!%dVyF<9rwRnG5DVHSr^N2qx3 zcyz_T)usr7N554*qZiIc6vusXnPFgNS0!77Jq>Z=2D@FR8WlRgMz(h8|MpEQ6ja626`zyT0}+MiJBl%ZH}A1VG&eJi z>ml4(BCOlK?fevqcBh1Qkw%iNJ~DF#Hqh(b5ZV;e{O2@{zp6c@F-`A$ZvPLOt|}~! zwprrt9^5TRfW?9(xI=K)5Zv7*IKd$yxD#w~5AN>H;_mKpCg1;@i`k34fZ5%ix2vnV ztFcEsKu$GI**!CD8JLqcl=Y zsyeFi-~Vo@358B_v#49jaMo*>rs{J;DQ2d#tkX%7#iw^u5FC6KpCwMeLhXAd*JPwiVGd+b z?Y|uo-Y7ZH@FeqV!*i@@o>RD4!Fx?=PhN2<07#~%@7Hpl&$zc67>w19+G0lOB~8R_ z2~QwcQpGDZlZEJ8%ok~~OhcB#l2T8W>$$kOBk%}9BxK~2lz6S@!DbhmK+%V8_jdBJ zug}eCsko@x=Rl=oc1#6x{>p+UZN*_L+GeRXkk88Ltkqp~rEhi}Kroap+*`|%O&7fL z&O?^w$^-aKFZH^MwZ^deLbHl}VNOIuS_mpw+rvnt->lK~=KF8(oujo+o1Mu7+-&kR z(&%Dn1l_S^bt;+Y6)NYbLyX+)Vp!7}I5{~**?!Svjc<7hgSS55_V+l-3uj4LN6V<@ zGEyVK69Y`xPf+5 z9xN1`J9SrIH8vR$)*)v;ghE0>Qoa~a6fX<-KVo8F92ULTKn zu$288)PpE;4w;vi*TKnY&Z14FnFsEd(wLtFbZB6=Vl|X&%xkP|A0Bl3ja2K`wBNtA zVb+Yl__O=1Z|uR48YTi9gj@d-EB!t0ZAYSO0y23RA$&a zrlb-irgw`Uf2eQ+XOiTCot1O6srR%{ z*9y=}w&Ku@4#i^F_QU+;pyt-|c(h@4sQ>L^3rg>GWB86_{r-X7Z;b9&8$m#k(21qb z!Ihz4P>t{hk++Ap5B%Kl9lCG3tWqzJEfBwc`=--oL)i1N_LpT-o>|J@5-shebpnL$y7W+h3+?w(c6Y z+x@Ev|BJK7$DhX0ol8lynO!|WKFWn!`#G~98%TA=rVPX8K53ikr(q~-kYi~GEbS;# zVo;Ho;97z3v{C;623|t?uWs5ndaMT3DRHa@bYo?s$=u{^C;VXLGK0F*z(DBT-Q9&M zTapyKh|lrV^75@bVt94oxda0Bv79_@uu=juB-~41P)%{4C%RDu#Zw(#;gvRjaFKW0 z``w_@H`t07CYX$g4Z{V~R;6lK4K!i2*#An;XvB4dDdZ zPLqf&B2(7PJ*omdB#*|-FclOyB)Ws6qodm23h2pTHuAS%24&`C>AY~;@89JWMk`&i zqr6&UOj(D2vhHNwe3u^|tK8)%l{W3ZY5yC~ciN>M6?0>I7w&ZSc!T;mYEO8t=?UH8 zYfOyyT*aPY+ckTb&nx2E9kf%^3RQ*xKX-5PTCewkWx^^X8ECKKMPujy3=NZYiNg$9y8wl$3O%uP#aP<+|GbXRRw< z%jGLR!=tDoTdS*gop+9X2j-Plvn8eB6cgjYy0>SNO9YLWDOjdS zi|QIi9!ADyAcXD93JlEvJpa%GO5m^V{GXDoff1}SNy^1)$lpn0Fkw1Vxf#|&sPbrZ zQ!;*cO~VxE2ixZ5XB$-DG9dR6EsGNN>-NH1BsnBCAq zLZ!BMW!1alc0^Xzenjq7Ds=xbwpO@{d1~eZH}~kwHAr7y2j_FtfQA8A#M;45gf3@buTo9*%oyG$`n$$m$dap1Ovw&9sB4G{22OTNsu|Occ zXe`=2hbzpFh$XeUu0tWvp80~-||cC)MNmUe9PNe3lK89ZBDsq;Fb=0pO4~_^O8nbZ+0)?1 zU-Pe#rE;qTer_PZbXS6!|Y^d2AQIk*I1JAM~sb&B{s<09f+%Ot=R%y2vj z)S4X;gz{o?)fyuO8@ae7b>@6NZQQ~rbXO4Be$cTV^WO9nJotN6IY%DyjzS-3Kqb-i zb5?>nb$|&BJL=jK!X)q8k!)wr^xwF87%>;=URfb^c6RpJ8nXX)6kb(jYS1ToCJp~r z<=Rjz%Cr5-Q)Zm9USNxvr`TcH)^?0+D2euH|922nM zphX#z+>nAufplCz`t6%_e&1#zxn%;7UIOugUfcZ2>a-G#6huiG7HA75BU5a+Iff`D z5;d$-tz0>(IBBVKv1cPxM#uD>f7sbqmeLRGj8wIqU_{mZRPueyN=eP!X0`W14e81Z z7+qhdJo6fF@i@|59a=Qc@I^ECytiw6_{QejeH63captinfZ_ck`p(uv4KDVUE&{jh zF}i})ru}~W?YXiaPxQRO-XF1H#fgiA$8NjiOs`k_9|kfw@9HLh>U`cmq!3zfYr45z z_PBMHV>`_uc^3)L*R_4kG^%CrTpx0Zb)1VOO`%XpCiSBI_C3F`q)4 zyK1w+Txl6Jm$0Q-vH5%42cbYT0#}1Vs)nQgegT772*Rjmm6-Uvch@$2zyHCvAg*_o ztr?a4i!(tOUNMVv3%%ud?H@M7sHq^n807DQt+O~ydNCR`gE#Yr4%SGw0>@%7yuO~F?$uT)x@b6*Nm7P0SQBcr32wMD|{Yj>6nG@-n<-x!-Q z>F7o^(oXWauXpifwQ5za?=UM}pZK7br6iGsM%P=@v>WV_tX#Q;Ag%r9F#n^$xqKkI(Vv zwH5%T5EzJ@uJk)kMKB1j6BU3&o>wsg6#F_y+nWxu!EeW?S=|Ez1D`XlTEGu$)|3>}N?Sd3*0BTkP?o8e?1qnoz^Nuh ze*FUJjDo$`dVA!sOt^d)_dCVLo|w{co?61y_ILd)_(|z>orHP48uk z;wqQWz(syH0l?@V{)e69Q*-MOOfBn{gL|oaWs|*VM6D_2(K$47YvpnlLbe`*n*@~v z&jz(vWTs3!JmSh}zO(4)6;xED^~(LK@i>s};N%kMEM(PtpzP> zZB@fHGA3XBHG3#wm3k*Ptd>KdukYRJtcjCJ`X5Mci_T7LrjPKPXsVr5OR=scY_iJI%bPj8QIZXbkwCUgKan9zSG)>~JT2`6 zi3n03edoXbg1S83e*Tc5L)TICdZ3Dijt-r1GjE>xuwcsBPqR~2Gq$O#>33Aw*SNna z)NW)5;CD>#h@n?R*g+l9(vwxD{-`oBZw=|_Ok!+~H z+w6wTSmA;=W5P!^ue%EV-6B4l6c!E3dbe$Nmp2uDWb>|=-p8!E4d;RFPn050i{qya zB1kY^-WV*|P3}@6-_B$XCr;DN2=d#D#*L12n@0{RC2LZitT?+ofrYciTS@Im^TZ&@cUqQZnbhh9*nmMd#EPxTE z*IFWa|Djkyw)4_#SgZOghpg-mZh6JyuQoOUy(XC&Eiwjs0C4|E%Y$Z z*e8DxAl5{V9{|lps^NdJwJy5Ooa=_ml%oeWnF>}QIW+}%nh$9FFV|fA2L}ZzZ0i=$ zl>}u*d-oWA7a}6YZdN45jEikM29jQnS~d03=~g_p#G8QILkB(UPc)VyHM9;|+7lkt zY24$5rVQM<%y1W&dYk6hj>M!(=uFd(a-y3=)+RPMT+L=FYpYH)9u)8<|KAIspKLdz z50O_;a5z$!uX4S@nzafMRW!Anv^&k$A#ib*xn%C+CNO28uInKVCXg;r&isDVl0Szf zg$xsThR9ehlc&g#_yKKj$H}7H5=4wdbuLKABru5%4I*~kY>cjhj-w9lO-XVS=yTTp z$zl+khflANQab9YW2PfFV^`zYjWAcH{r#x4dGiUqHUji z?P5krc!4h9?|IzAKUvJO+bQVK#kUqT#9OrY=G&WNMs*pqoTr#Zj+@g=#;Ps8h#Z|R z4U9$b$P#M*^|;_@-NR6~1@|?yy_|%c5DLD*2OBex?DW6Y73s9irHXhRPRBexliSVd z&@(V#9;Ua#qHf^|U^4G-HI98Qr+Pb8e_})Nx-fk06-`?p0Y8n>fV(>YT%Gk?B(z9k z-*|naHk3@`N49q7dDpT!ifTAh+h)jrtTL z^6K&WDn_we)}QIxv8CsIQulY)wL*Wv@6qgmj-rN2D`SH}fElTqln5Lhw z0gzjs`oAuP+Z_Gn!Dd}B?8(O7dlvor^b=j)>eD&v-yB`ne*TOo|RwDFOAGSUgb-)f+F%=%+a zp0^o909A@hKwvn5PHv&m5f%_TfXFqGA99`7N1W*WJWB1yDN zeqFvLvw;YTmcEN89v;is`Vkvj<#vL6-`3B{yV~*Catdek^=mL+q*k33_m|Q^d+-xC z7gq}a;By-qFvp!2n_W?BxVS6|81XLgqTp*QL3?i4b+plvLpGx-#cXCSy3v2QyNemv z%)sA>NGfpq$%S_8Pzo|ledfth1bKb*sXq%sUhA%%+ojqTTw;OIuN=12t> zTz3_Zx1Kiv;5_R&OJsu!_tIClNOI1(c;ATBIS1!(Q0$FdWdi(LRrD=AFgKG1jc{$ z;X=l4c2bZGPY$ZWtoJ`{>f>s-eH%cD6L&lhV9HZ8=D`+gNqMn z*b#1eF@~+F`0q76aQe;o0#5EB^Fj963Hl>s5)j(hT{4L}XjH z$oco(+7*%>=DefyCeK`u#I((Khe#G}H)@qo&{3kx9f2k2i0?Dz`&f~{*H<&RrgcF5 z4Ews(7k#%3cxn1oiuGmo{mjXTeNfj74t zx>L`+jD802{k^D$+U}&Km)Crk^}K)=bc`Dw>t8>Nph22q-y9%y4aIs!V%~gubKY}7%k)!1p_{O@NQZshO2}t8t4tf#^Jpr9Mg9G)Br!7xx zqz&S4xwz*+I5)pJ`rI)90Vn9TnMkWP^0cj&^c!oR={GmKTfgNdy&^xER)hAnSCflQ zUGdjxbK%i{Ec#Px-<|)xZ`)h<8O4Op>O-dc#n|27qkx!~UUvUZM}{)5i97JqtSb=0 zeA$j}M<)k6-fJ(bV&v|piDUX6FXivsd#ekEZ@r)2UeCrc@6EkH;kn^=e(S!d@6e#w zUxt5?PHByPGu@~=I(>saRkq6E19xX!$)RSe_HUzCc+&uAOtkC6c1_kB3q{jr9@O*r z_*+;*`;F~$Z?FGFfc-(*D81%$cmMrmyRWD5+7`u~hwx2=61m&%bZ&1HKNtTM^pkz- z$=s7|mS^8f>;c8V&mvOvJ|ch$W4ECg%}p<#%Un`wTA_I#emmLje?BILx%-c__~pCK znT@OWJoM}B#5h$QVA+oi|Ca(=R66d^ZD|%g*7R*49EyhAUmrdN%F@NoVVr1$SB26l zVvD*pg8@@6RKcBfrjY9FD=I*c{#{4}4R*WG4>=3OAz*jGhQJRM2qF{Eu*5rF=w+Ey zNpoZs%~?#8NoC}to$ZEnae`sHXp*Vo2l85RqMC;pr~77uq^*Ld7>kvMs1&EhcrR2;$|a;jstBw< zYsHDKGlm>BGBRNYbgD4oACPGMkYUZPoJ%MS1t}=204+tWtq{B@&nZx^Bk40`$0Tuo zd~g#~BE3cV;GSr3-1UvimSu=aL*~LyziIrU?>`^5lUf2J+h03KE#{Zk447}JTn#_8X2>6Qyfvggashc ze);Y>Y;;mW`k6cVJ~k2+wn|WRycUjihgR7XV}Y{hCURh1cAT`ea$k0Gha+4rqs#;? zW0~7Th#8<5PxPVdxliAqVL-vWj)IxD`O<3DWosNe`MF#e4^x# z{jRJ<#R2oNKmy)-4i_~aD;)ARiR{H#>KGV;kDbw6hC~IxCP2AOAec|CbPz@|zVJny zS2tq837pG-lA)s5@@-2oB7=odPgznYBIuUa#0drtQE z9Vp8}be?qwdv&NJggG54G)$;_p0j~k$^jizQ zt$0=qkPIikwULqIV%XV?x}edood4_RzWvNJF_dd2%fF|5!ZbatPKyLmaU*XQz$9^M z6S86$2uvozHC6p2n?HwC{E0CbOY2i1f=Zx-N!cgLxTVi1(WS6mV7p!FFpB4Wk*1xW zY46AuMQ7}crtz5M8I&pE!HJs|(MR_lF;dywH|cUT%C#tL_1cBQ^C8DY>EO{_v zrz~a$L)cz~^phf~MjzSei`+Lt=`_+EP+*7Q?Q#gy1&dui%zZY&k`A6QQr|Pj&!7y( zYvF>2J2%3FBZx9micJ=(3LX>4fC_UXO-isZvjE+GrFS_LTXz;eIlNryp&Vg5++&&)K@z1D+&5ti*K*Ll-#-mDe1f!Ao8-cZmR&-6yovO(TVBR zL}8fVTZO?TCtKUT1m?mUkQE}veREXT&quh%wo$WQo`w4xHz|bs8s74z2X~??{9)N& zuL#es7ARi#MLgdS*DyN(_TXWxUF06tzQE~R8&`FD`tM`Hyx_K@xBC~*Ip-{Zq=xv% zPhDJ8ea}Sg*lRm)g7q_cIDK1oZ@>?jZ+pa1K2M!D=<sAyf|DAlakh5gl< z<(%bkDlF;w^?vhLyUWCI1Nq2w)~gG`Bc^}4R5c*}F+}FQkk{BQ@4wU|o{@b0=H^Br zbrw&H%)92p#ZYDtz4s*e>KH4spS`eR(5v8|b<*0y@DHy1Hf8z`wS1jeQek>bLZvEj z%Iug%)kag1&0oM>&_Z&UU>ajIV}PP8fZ@-A1O`ANV5VS#)TGgHzIT-b=xMU&;ZFOU zd22dD>e~B&)=@1zx-YWXaEvUXTENsqOrI-W3|vTOA#$IVO5UG_rIcd+Z)tfyY_h&V zAYwmkNTe*oWHsXh+w8nrhC%MOre01A#^6sgiXVy#{0nIRAP`Yi4h4dGbpr9(em(>Q zKvfBtin;h@LZE+qrwZQBcUe%Z?8bx%PMWcYSuFBYRh$koabn%fkKY*y0zgOF%VVh zZimI`9-9%djT+@Gu(4rBwbM%eGl+bvH<|82*>i(po;!3EAM>rz%P9o^K!w%)%<1e5 zIT`nR%xYSHM#VT-f--EsB=Nbw#DvWl6UlnKXP|Hx>8?|A^zu>)$kT!N_x*zjg6aRu z1G4XYm>lGwWf@78D0h75gMhYOf#29ym@^qH7!h?a#c0`aDn@%;WWh<^cJPskq2`{aZ>^6GcLdX_=dvR7muP&h zOb06Bf+ifkpYbsS7n)+N+b-tbU?Ac0Z_0fvU z)MTG`0TI-aE2l6*+BUex-&@h@ZHLg%%Dt@ctnn6a-nHokEO5X69aAMX!*_S_dfB#t z2R;UM{EcicYraZi{lGkZY@VyI=r+smndx@T{|#f@)?3_7Lrv}cHH_kX-u!i_ivU$N zpfwbI>+#6WXn&mw$_I2pWB1&xP`sxka09YyI=~c>^;Qlo@3-BMpxur&j3-2a7oq@z z7L>IIA1`l;Um$Kr4GNY*{XYa!y-!;Zm+OB6+}q8~jfl>rG+;GjCBU%fKU~8o7K$dq z$_XPCigrSoFNzDpB>0BLl&tAWRoBq2{J8sPKb#1-3oRD9 zuOLi&@5u#~V`<+(d>m!Q`3pf2VoY^W%DBusDe9&OZS&A9#6nA_m8$*%*O3hOwcl2% z{3l7O?kP=Ml|o^*w-3$I&Yq9wt+(GQjMMCs7gP9a+O2CI3+Y&+S(dlf&R){Y-!5#d z{MUT%OuLdbFXoo*>-Y_LU9K_wLbPh!Y)fArPQu_K!|FM=I?0|ZrAi|*2hn*%_!&tvZ?ya&^=Tg&emyX4KI^amwyj!+d zqorMsV^mt=qfuuOUBwcWU<=w~VPV<+Lle7MH*eToZ!4VgNX3xlF~yTnL(>SB1Ds8* z{BL<{rg5TmIi2TN9?#}5HJh#vAPgt%qptBEGrf&*oOj2J*8`x_y)KK%WIsoWQ_Fk( z_omr;Kw!GtkY%u_?yX6LIJMy2v-3y>Z|rASM8_qjqSrs@BV6JD%k$q{^5c zMY>Z}i&g}t-QM>P%gLV^H==e?`(hnJA{wO!{130DPfF7uJ?>2Z-Qz-GbD)%|ZoCoJMc z3#woLzL;bl$*AFXVCP!<^X>ChxHvV`v5*b>Y15Nk83hMtEnTvDa+!9^Pw1D&t!BIT zhDm^rel28;u0tf#n~ly&-)HjdjbTcgv_(7HPW!~=rRS*LVC_8?@0ewyEcR zXV^!V(GXNZPOp&)=z*~@8S`eSGJ{zb2efw}j~2D}(bjl;P_Gv&HKbgp7CypjJX!9} zNt#Kjs>?QhSFEwGJMp7_ zgkNMiHd0GfS0(?w55(7o66T9zRKLFKO|V+jR+@e5;9t)xkNrTzHwKkq&ad~y3D|s` zUo8;JCq?oOD5A^h71}Trq8!gp4Fb&NHgY$Z?W^nrFi;R-(G_qRCmG?8(CMIaXeQ1d zzR&cVjyztX9$NEYO@wGBQ|X~8Y;w8E>*vY^S|SBI#7)UzbAZsZjExRHHp3|p2G@wf z)pVB`XpZILmuhR&hX%j@G%xcJgAYTraewN4DL$CeZkaa8NJ4^4z0UdJw&h{_9$x=a z^!o6NXv1pMfsg|xiriD)14`!v7Rc{H(;!4#6ioHF%q`5@wYKc^qNu%6gw2Ok^gZZl9x3Sbg^S6gGg&dW6*BF6Yz8Ilh z-s7hJ%(Q!2pT`4W%3$tZBX(BOs_CLIZGrUtum-2~EsLVijv8C*Jx(M_RQA_I;EkHSFWNoRSZDCVrP1KUZZv&#n2+mTl0&l-Ohx znQ?J((NZ7R=phon_~iBFse!-G_VW6W^6AGy7&)Y+#^%9kcQk8Uj=jC-e!AcOp~E)Y zX10VCa|y+13Y2P4XQeK?VzCKqv@Iwr`!O|jTk4_lvs^xcMB(qlT$=pfZ=2srt$^0g zstEt-B;LXg7faSmr)ueQD_ma(DqjYkF@OI%nQ}ank-MVA3aVa2>;9~qPl^2P^_AV8 zaM9C@m!=PAz-eT=PZsB5sTdMP3Qo#|51W|Cj~L%Gf4HR3s@j{Q76P|%aKb6y$Bo1cnKDvpZ}CZuBXB+Y9kaHCYne5qLjx8nOL6d>xpcjfMj zw)6VaZM!kM;oY&>lU7BueE>w3Js+%1#UjEDR3 znT%}w06g9mCMB7AQQ6x%6dG3k4mz)~YjxbA61Z5fC1z&zgi-hnJe{@8=Q!Qd^QdX$ z*Gs(~1}J1^iTDdoGz-D&G#Gt7uhji3d4LjLs!^e6TcpZ?WosdAYY)yX6#6!n`FrUU zVmv}Q2qHVz~216G_Y_})PV$Cm!anWWMK+qKL}sCPQUC^jd=Fd;dTO=cwO zmeHjAI7}behCn$LY3{s)iZN-zOw zU6na(S&wkynj-Bwfj_kbCK!uPChYMM;V_Sb9YtfBMZXNSK6|;ueBG{=4ioWv-eAHaX1ZoLecb4-(3lyz_(vU$3Vo^k=2V;Z(6u4D zZ%2(?`A%Z^icYkl<4SOM6^k|;(P*W0q^?36}etF zCdahf)E}H>p-@9&qCPPe9l%?csaa-}Os)P3oO>lk30!_AaUf&qrYx~sh=G-*iqDLd zIdoyIS52ldNc)mk3yreU_eVRVtKOD4_lp$`ww0CDA24_@Dd`ohNc))UQbJ^#UZ zS6=w(StKnQ3nL`xxOIMYL55`6Qopl`2Ho5r+_PCV<2F2(7gL!nf%8RXFXqW;rs4j@ z%&dsPVPaLnTCtYW-FLp9MX^|NC7$=?5#0*>71_Si z(83g0LBr>Aol{=IEE!AQDuMaat^h&=xX_li(}le}R%#p=osjWb&HT~W9Wjk1lH1#q zzmW_@6G;3Y3_@ZeHkA|loHsb$DYtzt$QWFW4L+aoDh`C|kHL+SEG~^wRVS3Nq}L*V z<_)C!{0k)q4~0Tj3+Wv-`S-}`SvYRQZai8%iy_@~xtxL$ab-5qMkM5B=;o=3{7<~x zWt9=*=JE3M;Sz^m6cfN1k^99sJxQI9NHgM}c|J8#rnTO_8zQV}-+3~7AKr_e05{3~ zD}V~=fy#)n8jY}>KBCu#0Q|?Kw?tMp@;wuaUWk56j3Vr9UnPoTnO*`o;xp%tZ6H== zQ^~I%%Z%DCEaDoGl7V88Y6Vevlu70mhYyw((bQ7YXZ`T=a=P)LI#f?vuH33FNuho#x= z0^X=l>o3@MCVuR!h3yb_BQIqPN$1| zoUhl@lQ%J=2glCivg#f#CrimSV}doKj*}KiXS*ZDeIp0*FZ(p#M$#uw`J)8zoqIN< z96AQ#fm~TRGoBz#t77Wp?8IeaLsE-J@jWMo{Rd4vlA+Iqr&YV|ogJBQJve8P)3<2Hl=DB3H^kA(*1c+9-hpwJ2M+4sz^?%p1p9llFKa3Q)CteHY zyQPw7iFsFW<1>ol$D6NEudl~7KLidfZi$+`b)1hGr-khZtbk>4m9u-rrKQ$&6exuZ z4oFmuXPMsb?vFq1j{NQhmZ|WYKHsy}-%B$!y=6Y#Kh=zLnvanppc4^pHeS3Z~IYu5e zUghPu?2?Z`b`Jw6<~a!%3*h;apeP&+B*H*y^4Kq`>Ji1(M5*G9qg6F9$V0j_a#WM~ zqSJ6HNFb_X#i*NA2rdeF)-uTai;GAtfhnBvr6rDYvvEkeNiJ-(28Lo{ z`JtiGWc9Yj(&z9jUD|%4ez@&S7Y7NKLpmDe`ckAMs$tJ{j?J#%B16&sA!b?u_Q3c( zBaqzT{5swhX6nJqsKp)#GBa-JihgdEam^ zgAfHQi+s(!byM2cpOV7!k3QyMyzA{mq!^hgR@H7Z;ph4`W|W2fWOL;TZnNt8iO5}T z_wte4_xMYu=j~Z>e|1fD(+;Np`hH%_>A7d2uVA_Q)6lG@qJ?{)fPd#*y2B;1uHYW* z-RgL}X{?Rv^n zp>Z@OEIxy$U>rVKBLNIBD&yH$;1=IZ56CJnXy}l!F5W8$CH*T7DPl1m9||F28ZD1w z@F`vDej}VbE|p$BT(LDJF^y$1LorhE1ZcuFuvkXE82kF^{5L{O24%c-kkcSW7;;$6 zz~ERXL!#D(p3P5HUDc>e5=!2D;Fm!WTMYI=7|ic*(_?{^ALZKo(QCVjjxnT&V;Qbe zE?+GsOpVTgr5^nJ9{Ha2<1aPk{6mf(l+@;$`Nkj=)J(prg4Ae*QRxEBj7eH$M&)Sw z3c!}d(SbDN$gBLbN&wi>BK2CwBh`StfcU-8rzQh8)O&JR4o~N|xN`CM=@6|p%U+%nL^0ku#Vy~p6wEpp)UMKYjSi1$Gd*xF9NdlFy zuzpyh!UXc@TI{ROJ1{A{ zKO^E|gz;M)$IEAY#18;`fvsDRNXc>lbf{_I9fC;VRjIzzy+G6F1nl#gaz!oJXZl=5f_vnG9W9d!BC*LtXekgA_tBc=-_xzYUbcsLgc~#D<`jqE4>u2Lc ziDmSUUjeQyV2k{A4ZE=Ep#>l><&&6?jai`GEoan{n(ID8$Lz?ck< zI`ZgCNA|UIaG;E5JpP)n^d~mhT3K6PN)Vd?>pW*8H)ldm>5p_X z2D(fbEesv&v&tr~tKKj!UqVdOl$q(y=dE9?^Y9yh;freoSjGhooJLD-|7jjxg)k*F z)bjrPfyG5XAuBB!^ztIBc?8Ry2ilM{nUt=+P;*z>tRpt$$|tc1R5BT5mg&i3aie-8dUM519rHoqGwLep z`q5Ecm)iG!xvNMbysy{4M6Qb3pFP9UyZlarZ=5!l(=5{l0 z#W47Tizxg{AQv@lzcZFr^>q8l8dg_#w}iZJ<-KD_rm?JzrmhlGuAgav_5cH*s%*3s zHun~%#-(Ao7IzX@(u!@3}Lp*|_gcI9YIY+nTqMP!B4kZ4_!YEd#ml0wC_)TLGDJE7@jJ2SJIKM64w z=Ky=^lhbK?0E3JWC5-QQKFo2U0@L&&f$p#HgX_N=zws+80q0ANf4kaRZS`_I zgWO%VM6toGAHAFY?a}Qj=&=U7yh1+LBk*QNpd(4fX;oUnmini-MA4Seee7QAE09Ky z29QXB5ERo_i+90eL}apY+1PC8FhAfU>Pd)f{)4{HIA1zenaGm@og0r7ABunm>7Akb z38c$qtz^pZUi^5igy7OokI2E_wSER#ze6IGhX>CnHxh+vW~?{MB*h`+OytiyQB6Y4 zx3m>*)u6fP_k(<-H-5W5vLvE&tKYMJw*2LDS=03uUaZj#Cku>SODil#?Lr2r{xluV zfV&VAHRDoUQ^R<&gfG?%Qv0Qf6-+u@0E~p~_DPE$RVF&>?MN)jP+_Ht7t^O{jQ8d* z*4EkPP44pGSCGLAnyPQ?93<506BC=v@Pgu`X&p!r3k0W?he4Gj!`>k~qo1jiMWv)a zvtZ|e*<=ODi@@L*qYu&`Vzb%QI`J)JA7Kh%f2_sM)hD!fQ^s2hQ@{eN22XdVdjoIh zp~0f#O3#@&(3R?$}-O=5a8nLXrmJE%czf4!-g zzRg(pBCdl(N~hoK(ui+8nJeM*JlJ3SLM0ZO?+QUrCQ(@?dy!|=sSWSX@)4{P0kCFO zeXdufdxe3XYj1M8`)SkP=b>T2$AvsSV6ZXmFGWA;$I$m|EkS^ZD%AO=QWQ#5<7sNd z@=A5R%|o?DGGqJ4^K9FXhP|P?%tf{ldSh`^-ETbqOR9e&QE-q6cNUQF`^}m2L6hh* zqR7-760YC7>JyPPgG}?N_NSUs&UV>*>Jx#)2i+cO<`oYHJ4w^x-+YmRPV77!Xv zeG}i>jd|BLznbnfR9yUWe0)pj#X7tI{R%W;A17TN)g7glLS3RK1ke)0tf$P0#yjxGXQ9roudiA=9enM{jVBUg>UZ{7^+SX2#zf# zLwp+aEGzmUkM%&#Zt<~&f-6Zcaja82H6v(et)Vb)5dIjl7ZX66Qfnwj^-3z>_S`3~>pJJmPjbH1 zuZvHQp+F_Zht$Bupy+=l5^n0`q<qnDY3Nb<+XX+fk2L?B{ zYyRu`;xx~(zGL@)m*YIKA3C2B01!lK-fbXLuixOR zZPQBCLH3FfF0qIwk9=siYYq3#C?}tC%UXIq)zE-ybsv4{glUtFDU?fb+(P@rZgLm) zvr6-Q>2~vOj@)sM-=BT6;OWTWm9$ygxq^mBK6AL37x*L{rG7~BWn4l4cIL!ZjGFn1B@CF8EMPMjVRl4+T#Gf5*H%EZKmArUXzMWsRzf3j6coBhB~3y zb2<;|5wXGQWs4UbRFC_quczlKmU{>r6lqOlwi{H#oR$6uQC6B5|49U8ux5%=MvOz2 zgGd4yNkwd(FmK?P`m-r}cpNN)@aCI@TIqx^RfX71y-~N>J5-rd{Rb1cT0~3y^@$;= zkEm7c1ydw5k&P?JYST`u{*EzQ3CYP~A|iCo&dy-ex4{a){>-7VvF+9`orNuB2&$hZ ziO`JER>a`>cQ*C}rPgcO9iYM=E6YOpZ2f3<5RlWX}|@oWu@zfSbWf|ZgxH*f49DKGQ7 zX|`0YvbCO9xsg+?j_5b3VAlQd2Uz&!(=rBR3HM?sYuV5L9-Mm4_a9&EShP2ovwb!h zSX(dH1s{(-zS$Yi8I&o`9!;7rw!>0wr6KjYiq{xu9whc1<(hB;S`sVid4N;ZtcxfK!|FF~i46m@fS&9j+#m zq(V>J1rLmI6q^PHPJ+^RgN+FgQYLy%Z}V*tpygppT<7A%nmp19x%;#m6~sQ>#0REG zn+?MAXg)APAr#UJ$_Wmz)(3a6eg#Q)LBe&eN#({%yei+0o2+DwWCIivwTfas@X5<4 zlLj}#h;Fy`hE5j~-zqCC4U=`Kzcg#rKx?D0%MFD!3CXbP(I*BjAasUWe>z zL#z?>Taw6wLgExk*@;>x7+8)6LL!iXt;GWM@rWw2NzOGsf*dQMTP;Doiv%5S4o60` z8#^+e0!4ud)-j475#fE{p6~*UCgqf6PWC)BLXL-kwY!T->do5$@2A)$w(BNd#A4CI zbQNabTN{?QnIsO9K5vN~b)Nd&`9A-gn6EMvDr(zE4q0^EpH|J7Zk%-KYDzg5l<+F~-YN?K&iex4rg z%CbMK(C8UX3+!0J1I`?+sT3+%_rKd!MHwO%(9(Cpj}}D@QZdBM`q*r|!>qo4K09bv zpM{bM_%*TYjN5(|U2IY*X7SUydwVP3=x_59xR#xB<6YI()+|t1QXQs5-}GaOoHIHz zlNbQttC=JD96Ia9e(k*$`6nyhM{$hhflof9FC(T;Yxa#rfBHz8*@%hu7e39+BUMu6m{Mc?9;{@sH+UE9Z^}i<0crj6x1ThOVoo(iS~XvAuT1O z$lKt(imcu?L^@E-swG-6mEIKxt5i3w+pfZh^{bLeFgEu&eTrgW*oHJ3aiSG}jDt2D zN5Blu#-ZQ3ZPv6`O@2xICpWVe%l9G{Hnq_U;P6i`vRq&Lvg$xh33vr|?OU?D}GSFQ3p5 z-F>5NWPa!5xu2Zsb+J#^xKBK9;BoApuCVk}y%#!j^X>U<8UU)i5)|o&RomHor;DTU z_AVDPbmtdLA8I^@iVRU3`=Gv$&KEL#1HWAV3{HCj`^Qus@eQxMzcv8s28JJw+v*Gf zrVmks{AZKjUlB+?GlvW@#BP8or7HXz0sz}Cqd&GLjCzu>5fMIhhOJ=wJZaYC~!uMsj!K|ode}90_&2itB5EFa*Y3(9(#t+DOG!0f8;(nk5OdkXa6|7$? zl#^V)qq#iGA+u3kwlV=mQ$20h2z@+1IP~k&Hoq&3`=1&BgF>2iOU-^kSU~|T%b7(F z9*Pyzv$z)`QNY#nbhr5Mgab3)XM)oc)B^o-S77;Pib^t%`CPPi4x4qfIsxm+6idGOa z!@+^nLVjZ<>OhtUzG)ye{j9~eAN5hECqmJ& zdLgZaT-UuvA`hIoOfO1IO#D8vn_uSq7U~Qv9Fv@PO9+Si&BiAGoyTPdga}7}qBa`n z<>I7Qh4za>9w?;Kirf9*G^TIZr8kpu&Y{A7T5fG0Z>|(Fx5Tj zsKRbF^Mdx&|4b0Y?=AqSRRL|uaZIWTpf5@SG9|XJS9>H0xwVcPqO6^@Uh&iU-X7!J z|Dwi7KU%GmkMmwKKi`b5y{Qr~YXoQ(i|Kw>1}3JhEdS1F#<_;@_R!=0S!}4qLUym; z3=gNWx_&=h4#(q{BcKa}&z!U+?{e}jhVu!}ZneWP?|6Hct=yEGZ*iC)i*}6({JAIb znLHogm!gaA2K$q?N2r>267+D{vo~57_eV=XaM!|ALmD7>xx9${Fx7fnR5ZX@&shm6 z#%Iy#gGfZ)>2CQ|WeeP2?};sX^a-M_`0jDt>myPSc=u@mWFS}NmPrl4{EDM*dBl%H zI)hGqomIRK2AKf2Tt3hB2&i-Sv0mY+`qW156JUGHX4wdxU8D3C>IUey;Kvc`J_s645d0z!UiY^cYc6$tX)ZMh zX>OPbB|*{Y(yHiclSTHYlo;GIY-DZv4KZ$5{I@IYAS}gYs|Z8f)rP~CrkEZ#5eEE1 zVtG}mR9HStIvqnXO2SJHc=!~|o&>)n6qP>5EJPXaw*rr@g{m^7hr{L7$Mlj0aga@{ zrvT9Gdq(+}{I6(L+IpBhUBV2FQBObogc0|nRNd?lR< zzVX>QMOw&bbvI7gW`dOP8Mmiykcv%(UUSsvW?im~Cqrty$QlRVCEvTH_Y7vC(YLJJ zFRzCg;q@RA!}dc6Ar4hMMD2G7wSyV?B^Jb_IT;1lo2e&&3W6&bl$|Hbg6^aFc{!k%dPyY8kauqr8a}=Kf?qd#EMl%slWO2(&4@Qw%S`(9Yy-VsMbCYx@RgAs z%@88{7Cvt%<>w$sB^9&W6Tc+s>nkvADZg7kR8^cnqw~ADDGf>U^Lj~*)bY$sq{o`? zCw1%U5!P0_P0I^Y${?f3E)i5>wz$ARSRnYm;@u5$>fH@zITJ#P_NP2{iW~~IKr~%i z_M0bR5JBTloM7pH+c+4dJyt1ZkA!zTRh;EcHuAG+7wUbtv-IWeY2?G*-$X?n3E~gh zElGpfo>9O-)t@JHJEKQ`o~~$jl5jEXuD8ykYkXHect&&oO6@Qc0+B6J9q$^ke2NQFcENImd5OSp>%t4|s4^+Qc zaX+yapx^Uxq)Et(uY_59Q1kk?q{| zR&*%q>!lgMuGm2#A3#Q9E%oC0H6+*W4~v&Kd|w)!U)JJZ3AEVa&xex>Pi_3app<6dOrNEQd;~*|d7_NH(YKcCCV=rpgUhG8U_i;*b~(;BnkDps zbFRVu6%%+pZvY9z*hVPH_^*FA#koe87R9<^%y_1oX!G^#%PYRWlulZX$B!?vqXxHL z1zDBjSsSTxpFa=2G!%UV@FH5jhqY`#B5F;4kdFq`Jh`?+Ei;bEeY+F18(kN;<%_xho}$P zM^Kpu{l*qbve+cI4x^n+MB<<>!WBP=_%>NOrRVbuC`Mh2np7#^n~k08-s0e!8Pl0G z4H1MGgN7N&LBq8BBR#0QMkpxrxb%6#o8em%Ru&>ea?#G{M13FOkL}hUksY8!t`w0~v34?a==uX}n?c zoXnlMDN)Y%H2#h9^qjD!s-cnc_30oy`<;ZJ0qJ)Hw4#E7pwALnK&f47Mx#H!^zW%; zpc9j&Fd|_2n0NFE5@~7|77?+Wepf#n0RCkHEjT4;Zi3 z{P&`~4G({*p?SS$&1viU6WjC8b6xdpJph?ZD3sH_>%|y-@e?%kxrYaGjJ%cePToDu z%&)&0h#k9Nmd5seQc+`_?_@>$6@O{JbeC1SeEg@I)lw%=W1j)=eW0@_V7>iV4WFAJ zAR~*55P%1Ku)^un#DfJFu#8K$Jniqt!JKZi`ISj%Sd+;%G7zB<;R1t1MVLoKFM(mE zQ0PuTD49HxS$|f2eU390wijQ`P$MgpTnkX~Qjss9}ekjgrh*PM2~ z2)>?m8vK7dd!`E>Ilhg&5iK-pPq(@b08w9QunY6=-PuBZtUW$hf}#KN1OEg-W~#=b zt$E*Z<$UT@OojANe!V^E-R#fkG@k5yd2?}j;a>n`ur%?Q+EqOMXD7AVOj1jawy8m%t1@tdC_j?Dhs^^nl?{w|iqaJJ$l`0lvApIj~1~N5TiU;QryI=WSiSE2*d$*hR5x@ZjtH5ZWS5 z!dYKm>f3v?0L!ai1vBX6xzP{ciQW!>x7b|IK(w6~ydOHQC=~^-ae&;gbQe$?vLA0* zTkC%yG4M7=9TdgT;b_h35=tI4kyz*1z>4mQIn+`va}Wo5Pgkl`RL0JI!8o^MEz zIUSBQ{#=ALqO-^Qpf7*_;QUG%0qPwFUG;${uS=bkV~1Ekuno2tB|zsr)4W=$G$ln| z>H(yuN~-#aSS5hsa*6So6J&)qR%Tn)yt~?}`e>Oc*wJgR%LmARyDL4G2k;I3U_5DS z`C5m~52VP78u;+>8*M(7LQ8k121)JBeNc4qK6PP(V|Xp}LU-5z9;q=hu9_zZbak?l zvD)taI#8&l!$%;;=K`rp;m2~>7}|RDr?uCU3(Wb=bQ|~qpv}t~NSJ`UpVa%p>G|nb zj;=t5?OF%_{aqr-&5Gwy_@LMIwdT;o2pu0&hNA{S&O|5_5Dx;nxV4YI15q<~RD+~4 z*4Ea4F2~L;O*Uueolfp8zqpSEF+rc>EfP0UC4u@4US&;b0s{q)9azq-)!@1~o;^O1 zQedyD`WhnoPcQQiX`h7&q^zm!CD!~}A=bRtZf+Gi&9LEz62OQPYKYU36;`LUNg7^E zIrgvN0c1F>HfJ=nbL#f5*R&wy?~ZXT;U92B_muSpMQEshJ1I9Pu_6cAfy-N6^J5-JL}^R@xl;GNgc3e$z7al3nmN! zG*W^zeZfiZnVjAr0vyyL_sv+$hNSJ}D0wbbl3fLd6DFiot$u&pNi`(mw#xj;_K{xa z(cW|Ea%bX|A?e#fqKwzEv9&ENDaoy{quFpw3wb~&V`MtN_qqEg=&CO^@7CgaEbCwZ z#s7d(QB~5_V2|2MPJp^WAFMQ4SP*2yHe+`mA8=kAYx$&cr~9Pl>3ebLb2p{tsvu>P zttd9sjui%=)B&u{p1mkH_uHD`o%d&+dmO>%zrb9+ z2d1LWS?LivE0{-uX7t`b1ymke6+PoT?qykLw*Py^bT`ut9lNT-J>!Y-Rnl#@w6XKj z%5%N&n!QO_*)-D&3OAHNPXbiq3#NizP3jb5qAa?6Rz?87-FL(QBB$VwW} zvqbfwv3d635gw%kdJb2$oT)d?zcor`8gZ&=IqMXPWR1gJ?82;QO5e%4wyT6xs0IG}o7+ zRw{Z%=FKM4*e&3^lJh>?*J6NJE?Gle7Vsp?UmxwIDR>S?>wb3(*d`h-i7&radk(<% z?4R-y{w|~7Ww!}^X0r{vK|Bw}Rn~B3Lca%M?h9dP#|6jHqrCt2cQ!kj*xY(eM>+wQr`9kR@<1-7EpS3WN&Vc|Ha1(DB55Qjw9-+ z2E~K}TOo7#c%f?K@Z^{r8fNqXP{O^CfPAE+Nl<#sqtx=jLIiNxhm`{Mv~6ThK5qAy$~a}tR93$qR>Qr$OJxu`;AJ@ zfwI(}k?-6Ni$j`aZ^sKssi{;!U8k2@x9{G_C>MVQG(lVg3l?{U zY<3gIr46AscmE{tkE>IHf>AQ?-ve5t9t(VRuV$~;7Lpi34~_==I$)>l@Fz8;nvP5W zU#&O{8{OV}x zdpVtfn7SKotiXe3>nv^y)Md4K*Xi6m_2<3ME2_WbVF+w|?SZx)ORlZ9f{;TSykc}m z{2q_zceY-IZ5!{%Z2m2*_WpP}IMlm)MB&-3Z~^d?CsX+v1=8nfGB04)l!^?^Rt)i= zzQ=O-+FA`)B}p(Su$a_8A@uoIPto1 zjT1u$`mP>$fyiE3T1i0~n}5hlqc00=x2LBH!Po^1d1)UBquu)&0>}X}UFH@?GdUw) zwOFYJen@93x}OF2|5oyz0=V8ZDB5{mz#~2*aYW(MYTuMpwA`bMftprdoXB^e8|9^e zj}`~n`K$_kqgIYJU+R`rmvaqONNAjIw-NPy1OA833oIaegGcNZ?7iK%+xiSN8Af5q zg;df}IX=PO0gXp#&(~KoE7_<^q2e5$3u+O}nK*j;@P~Ueu#$3ftFhB(9Q9Mv4`dH) zsBl6!OwPH{hG}uwCOOHHXO->Zsas3lDBRW}I~9TeY&on({l2`cr>AM0PMa0Mm%qMDJ*ar zg~}9%cJ`*)-(jrYzL6s1i~(Mf{l(L(ecdjdI?O`u0n6F~j@)taXt_VcDt%zp`?&x0 z(BSKjMt=C0=o=EdP&D@!;Fj?V^62E09sc6Gw{t*1xSRn_a6FeV_P zimG|TG)&478&5_#)bXGTJ~&1tI}WC{M!#P|Isk_j7ENLL{gxHHERrH^Zu%mDq_>HH}aJ9&Bl3X$RvE+e?6_l7& zZ#7LGA`mT-$?M-h_r;{KlRjxuT{mad3nB&Msdm#G~y1y7x`9N;%a=F(&;^2BRReaBy@2p*C!5RCs zuV`i-yx+J4of+J`T6NQOUo%yNOOP%|VgC3i+kcvcU6@Vfp7sKO1#n}6dVORKcXqyc9mc?o10=% zlipx4;E3`VjD%rJ0lvUGdcMXwOj3l0ASLH7usd^CB*kFYcdc`RXLse~_n{qu5dwi7 zoXGDadgTHu<;ZR6n8GqGNal;4azX?RjY>ttmS;SptoBsOLO5=+>}N(`1XsA-P>MXA zdM%y}xF1VGSx*?2To`q(+is=q$~pDccjDr2?CrP`2M<;^h``iQkY4Rm%a=9pmfhp* z4k7-?+mhJacpUz0={;`~m4p2x3wsjXdFr47bd&IO&M20124}~~0ByEERv|pZpFZU- zmkbfiwU;fY6`y~xD0^s5Ei0cm9LSt9o~@`!c}ME=jfqdwYANP>?^~!|d(XxOjBjTb zL1C#}SrKeVS=8bDt<|*`sn_55Sy^pk4-fpc+e~h!%zK~l4HFr4jq;6R*|qw(w=qXd z%%SfW4;P~qNVQYUwQs%xzvJuj@SX1*EcHIQSEUQItjerQ+43OS?bBbfb5P*nZW_?1 zJGC&iecZuL={Q_iZ2tA&+BdgDbU2MUE<&voJ1GANH9BkZI=sHp{)ETv1AvhRlreHU z`}oc_=k>BpLHln60LWSzt}Adsy?hAdXw+r(@Z^QbzB~Z}70e!?1Q%FY)iel4Q+-vO zXSGh1lT`Tr#j=ke^Z*oXbtN9qUrR$NPis4~#h^yz!``%z+bxo|IUIzBxg~J9?lh&^ z0&9jyqZN$6ctO{L7Uxg34$^4U^+l!+YhIl1iB|fn5X&#xy65$DKG^L3k9Wj;#FIUb zk!4&|8!t&hMm8Lf@LV2UesFrpSR0^<!|}gx&M8=-29pdJAGq$(t7Gnwh`lc1U2>9YV<+jOPz43_783py8Fz< z6hJ7@=X3Lo z&b|>*4`2O$%BBL^lLi-3D=qgh%mxi09?$yC1+|dmCRrWwtiJ(c%fwZX`rToxO zymn0x(4r*j5f%?DEI=fpN~avqdYCkgB-$nJ_!8=pL<41}h?%qkF*C~Mlai(O5lGjN zov3Qm1Pza6Zc3U_7*668`$NJ^lO6XMsk>3%s&Im{J~zMQy=!Xo4*tGKY>Jj#o)%?$ z@CRIGJ6EI%+89n|V*cakQdtb`$yu};5Gej!Q&-o!x=QMi!#n26E|HjEV&?w^G*&(@*ZYsaDXE@j}>iB z1V;?t8F(~n2$Y~TwD&eDo9pBl2V?&|BbKA%)AMeOXWML_0~xjC#D}w!cx0ION&mXL|2T2z&mGmjaImpeqims`#8XJ3gDMTtsCAo|hE3 zA{{dOE@971O7-f~eRi2IeRPDb-{WU*4WCG4dbx5keB~_c5uH*COCn$hzv4!1_^D-! zS>Kzh3@%R(p+F3W3CooUWnnIFl?TU}^bpB~2{15hIekA(6-T?Wm%Ac$f`?Xvbaoye zXT}iw*L^2E`6d4a`gtMFZ4h8zfv)i^WleDUbP}km*BK)pvISjnwh0Pgbxk8+YtSoD zFGYXbs2@e=K|bvgAMRp-qK#Z}{Rq_7A67ZtJv^FEN8h&XD}14Rh@s2A<8age_(Ohi zSu4Mk2+yJ0WQrY{KJkdcUL>xr?z8hT2gbhtkvXa>EZy4Dq_!FvHfUi(z;4Z(5+smKy(pusk{_$>ATswCE`|i`o#5C(|DbuZ& zt#UtMgiLhlKpbO2kg-6e3xO#nXZbf%M7ZBJcSSaorR1pU#1JIRenR1(4&6;X5zaEL z(Hj}?q#Fs?Gw_z1PD@h>htoDOBnc;qJ%@zNBW21=78S;n1w5{dN*nM87K?hT3$2nV z(n~HXyo^Xy2SpOBp+Uui<7#D#`SIuWavC9J`8TmI8qV}-+-gHsl(gUbx~6k{)9bI@ z8e&NcS>;H--WeP4-cqI~6Sk0_RhdTjFKpQI@bR~yY5wQ&7T*uLOb89${wsb#y1aivS-pKa@a=pUIen?s;J4I9 z=dL}%Gx)kM(a_Mq12D&D)Qf+NIfA}nem@mRWi=>ZCK>ovBz#8Fj`!1^+IlGeix=Nk zy+TxtUW-pQzTwxHB;E@Bu?el{We&;ed}N4}YIxzGJ8y+HXUc}ITgf*ivtJ0HD1rn9 zE973(=yl~&r0%U&Jf(;pFyC_TEy+kftZmTxzp~+8a$h-1oeGxF$7ph*CZ7!&+I(Q+ zX`dGDd)+8WwAIF|DeOe71RB}?oAbm4tA(}B&*`2AMcono)QVUE1QbX}kxFZsgco$T zS^li+(w~;>RoJP6C%t2cd3y9caxB=MJ(lfEF4W z`ZOwZXYIGK`+RQeS$6a}{%s6%YcPbl>2%ar&5ct{m)e0VlmJEllc~opKMf|67^mpk z^=P2Ee|*zz-Y1v8eKK~&0eyui_)X6D?1PP;LK+Z*Hip{t?fJCHyT6|*XJLL7nK71+ zt)WSq%~fu$QP-dd3=)?`ibh(4_n9|EYpOMN_x$DDAh*WC!=IV>WYZhLr~%hnrYCIz z`luFJP(omfl(l>CM1;_VI8tcIL7F&|Un9Yxq>eVkb?2VgD?#oqP%1;P#nvFM5WE@3 z@$(10>`Xt~dv)eQYz<| zD>9yRz`u5Vi_m%Q1_KBY62(+~PyOf8Pp6xG|1gY)v2e|Ka?UU0KGZH7Dv|L8;J(#L zB2|DNlInRPawnYXpz9O!v6LP%vKLv5s)oX<=9(x4CBZ?kycOlocXB6d8Ec?=_Nok4 zshT_sOP21F39tlC+`3BKk@aGQLGy1UYb;6_!3Y(l+BYtNWIAep+`GF)Vi{P}lCx{*|uFh994W6!N zNZe0yzTW*#@BMB*t+8&&t@*#4X62k!uk9?t;c@*fMn^>P(1|$D`mb8uyOp))H@@@A zO|S_U^@f+9JD%H5`w7lEc88PoTUN1E71mJnzl2p5!#^+Uu60}e3<(p%X2xd$cke%r zJ3e$gmS$jvp(hiRtplT-QTZ+>y&oKf$rT(S+g)mnn;V8Ba)khf!Q-AoCZ|X zIn%_f!uKGoIn$=oQrUKef=AtP?+fdFDtx3aJ+yf8eZ6+@;c3zdnO!xPX6Cz#?ST+ zS@(wPE%^a5?MpMRw_WpQHE4^H%sa&LekU+7SdN3`b?Ci1G*{#82pAQ_M%!@hukOoc z<9YPyKgol#TtdakJUkfNpn}N>{Iu`rTfHF3ps-j>Tc$w!8U|xzi~(c405CdQ_+oby z0ad=T*iq`0Q%PX;oXHzgTG<}G+njy#a76Ne+N>B6lPV(^}( zQWVWZ*i zX$#9_2NJ>R>R_U1Hg~K0a0d1ak_6G0KZaKSdB!gwTU*<<+xH#uYcG@UUS^hj4-M}k z0U~*RPi--a`hPcij5l-KBpsW+S9kUVO=@+DNjAH0;#jf_AY~w3!DUE`J9bFg?Z4g4^X3#$> zgmmB}1z}1bgx3rXQj8)Q2Oub-ikkms%T;GdEXre*C-~TqhL1A zBkWdXqFNzkOon3H_P|*fg@7{526W)32elM z<7wQ#c3&lc!-m=;fhj4QAmshhJw|pS`Y~1qm=xkWm)mTK5VkOwsQz&MdT(lzupkhK zuqOcr+iwwU>piS2CX3EQGbbqvzRI%XH!!{Yg%nj8Vnh?NacG5V6ylBxCu2c?!h#*yn{gQF?aak>Gq4b&ukf7@| zc?Jxb^#GlugOMKuq!580g6dOR%B<6;Y|L4RNsnBrJ$wo9GX8Ul?KY%7>mtwR6E7d0 z_G14b0%hTq*D0UxgMr`0pnt^U#Ik?J=hXJq|B`byS#`vL6gvk8HvJ5UuxvOGoo=9p zgIW~vVG#KSF0YHDI(aVqwqx5hu`n1*)N%`CkcgTx;ar|%aD)Bg+M?++-~i)+9fu%Q zaV&9#f<0wa-}&iBv54A%WZYFcyvvmSHmXALR=fR&Y=Tg_C-u@W@Xrp*W`4N#aWj5% zb|TZvUTw$VejO!d29YRCj!I<8BoHixI0r+W*GSu8X*7*ZpLV~N6d^yu4FSs5K9Qt| zD&+tkTW?#Onaqx4moeA`wBd5hP#U_fY3uCG!5~RhhNO_2PQZz#u8x)$glNB1)7bb) zt%5r=Y+Z~zsH^^PKHS7}I{!;Pvs?>QOx!9R0n?a+6z#SiSs$v`+_Ujasu1r_ZSgSE;Vix z`k`qwZUS-yO~@~kDToXKC$P_)9Kn{wgcyv@!Z@&}{JSCE6kSk-!wf_Iivc}HA?qbD%+t=sT&};2jP}cq3(EloIV|d#n$WJ>vsOmg! z*}AWhhes;Zw#LG$PRm{H=EK+`zjKiHX(z@mvtzy}g_G$xZFx6DCg}Sj#qNi;(VYRA zVdd}Ka#+>lpf)TOQFRS_D%n$kNb^wHcLSK%KUseIQU_5iE140TF|6l{Mp5Ic1m@vO zgn=NU2IBD3 z(ooYx5ybtf#_}lnQ*9%R3L%&I7F3kyEUpGFr|)CSEM{a9XQqqEF)}s9wk4(~CMI_N z_uy7hzo6bVFVlaxAQtJ`4=j�|$k9O(Z_4oAbYIfN@^OaJy zZyV73&np7o4H^EI(Xg3d*38U?MMqQh+Jz^b`HsvorOE(E!ZZ&x4LmUIVY zWWd5pEIi9=y`gVR!n({_KC5f!wK-zWIPQ!(RT$(s>$(=b!MvQ>OD%h#!>oaYr)9+VMb$qe}*;3S6}?5lKC` zLwm)1ggEBmaKAE>Dw(no;1u42kh$ePR!>HsUR3Jnl2G1-&HvSG#0mU|q=#^fxU-0+u0uA$$S^+qeB2=~+OUsw* z-<5E}Xrlr?T8>xOdH-mEdambvs_AGB2L_8**R_sp%cU}ir>V^zH!u8OcFp|w!t%e6 zYr-5+NLUH};XtW1DZR$J(At2)ur43|5pTx$Fy!5-e^L=)q6uZZ=aXve`8%=)(B(E( zU+(7J<=UCS=T+Z?l`N8z=3VOG!%26^1KTbLBefefB^Wu9tNJP%ly~^{7*go!u3ouO z!X%{}^@bwI*vfkC9hO*O2*y7)-M2JFh!!P((msD`dOY#A;`)^99>+gYuG##%!Ajmr zHYjb6$`$h=O(U5&LXt*Ht|0f2Dy8db*ozk}tq9>Qn2~|oZjoHa)a>pl0gQ+QZ&v?L zTs_{n^q9?emcE4WKwl$ou!Qitmh`ZX;BL=-s&)g4BwYiTGH4xa-aF(yp%g>gH!Bc< z2@EmFnX-x^=shq5b&AScQ&Grufif2bxev{vS@sj@^($)Syq$@B!PupZBN-LuR zZ5G5hY5|1kQ`0`9{>=)pMANNb;LkZ7sb!2J*Z?SL8Y?hROzItFKA)hrups!Fat5RH zhQw|S#$Y}W{=U}h?09#{6OwJdhArUQZdr5mgGIo1G7qDMLa-H%PV{yP@eR5VXWWn|se`F>m$Xb5Iy(j*=I|@GiAzCTzj^0L-zk*)h(|h;LeqwzTgU8OvS!Ag958{PVY}ThnH3#8kT%& zkFH-)2X_?8^$GxUj6S!5E9*;JSXwe|)-sCfChFD^Q;+3#*+HG&4+~xF+&*_O<==t^~W63va z9$Z*~OlylB_0b9$Zq51MAN7Zh!nh!pK=AM%*Pc>UkF89J>B;Bw#bTk}jSWH39wI4y z+=4v-Q9|@saU-@w1Du~@X)G}*>sctvIOA`oLK#=V$(wj6nT|wK-huI=*KpxrVISn! zS~pf&So4?^ECE3`7E$XDt^OL@WpmTlZTDHF&=FlEj3NP&kbq@E2_s0OhV7=Vl8kPN zny5TxwyZSEnZKVjMzzFo_+GEo8CNbcIfz<<22)ItlDv$X&rW%YKxPj0m~)(BAn==& zxTYb{0XRGfp=1z7wnEiwubnWB^$kSXolxc#(^pqh4|j`6oiJSgVL4u_$J*?80)KN0 zt!;NBCeiqnTTv#);Z)r@SWM;}m1^jdJ&bfXjg&uyDE}Ov_P;dd#^zx?RPYWS0KzEX zo|keSoJha!8NVipZ3A>8Cvf+T_sp&E-Kwc6L#{!x)bNFe7J98;2~SgJ>en-sxO=CL z-D2#%#F=2wYkE`xW8oF!MPqXTNR?^XcVZ>8`9-j-jNCI8ur+TJX=2jR@W_}RLX}ju zpJ5B?B;VuI!mT-zuob5onymKQ>1d@H$k|bk3;-icOvm@ zStw=Y!;|0?*ei;YDR4?MLdGiH(#zf`XpMk8IXK-^P4xrZ;Gy)@sFn0Ju?0BizM5UD9{f{2975Ky8MbeEuahmh=8bBDMSCx;dMdcJ1zd5RV4HqE)?&O6mw)5|YI z9)_6szr+EtC41XBfHS1uZU8&SFUrGjC8yY6Y<7~vE{TVq`!6=x3w_Sr9oZC%CGlEz zb#udKZH=%oA*{OpMIi%)M&wV=1urLL�#_mM<5a+zRf+L!D!mi!20*Zzj4|akKdz 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 z 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≪$crR~E0%YxXFIx+|#YiOx>K@$ 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 Jryts{{lG)}EcH6;~ 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ś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%0A-mDB*;wFu-DOxwU6Va^FFYiKP28DvR*#@haZbFs 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/android-library.png b/docs/audit/screenshots/android-library.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dfba9c83ea51a17599bdb39aabc116bd7ab314 GIT binary patch literal 234121 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 Xy?!9q`<0-T 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%0D^n`g5gjrb@>t277SlQYZLs;wqk{$bH1& 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
DTjp9G{32BysIQ1!o_EcApcR21XO$UST5SDN z)&D#FSTo7{EwUs~@p88cs4&;wQ~o zkku4cHu4%?v>5~QX*uEeqWg*%pPv?t;4d%Ef+4+pAGe>y;PR%k<;CnX##x2--;$qS z?;CvsUr|)pnc2TkYHI+K-l!L@s4=x6-bc4a>$4~h;Jw6Vm1oZGb15t?x|K<`+TW zloArjNR9d^i%YDFT1lC+to<@Vsu1i?MNPe5(r?}?*I^#;+?s0^#C7ueMK<@Jz)Oui zCRK5fKE%knoSKaeRJzjcgAqBc#Y4&zkDq>ZvyNO#uuAy=Z{#UPKc0fTsEXa7o z$me1)ZK}UVxPRPhl7c(i?dmN>@V)mFjOG8c+{3zG6oon1>wKyc}8sdC~wiDG{emlUh( z37EOm4ea2>3(#}XvFZGz3jZ5`cW8l3Pot?3MJ^@yyPj|cgO^%uiYK|X$kB-DJHN8G zW-+)hGVJj0>u+XUl9>Dq96wBT^3j7$SG-$aEw)fzA|*Wc`lU0!>|tn4e#Y#^|H@P6 z>k=KV)z8Qng@ko(hH`3qiJo zo<%3yoom!SG8pT3OVi1!NXsnN*3V(Meo*X~++#r%eewCZT=~~rrf%0Vw^5VO_>K)i zA!g%Px)af`6_ktAXcgl`$rE%=+?&p=@#HLTe3$mADYt~i#*;QI4K2&6Qhq;>x2&`( zvXqkTA2#*e$ntV;Nh3!ujPbb%88Re_BzhYX>+S_Ap)^IMv8_lIMKsIi#Mk$!N2O2I z*>jowiw@HUEV58A4su>x3MZE zp-JZ#{yE`C_bOf!;ec2P=a-It6|GP4K1@*A($NPs-cR+gk$@rCnhi zJ^U&pcsI66l1-k+c!jL|mlT9(#LVuD@}MEejC7DieU;CQ6Z81Zkf zge*N_tX%5$I3oT)I%og9^kzEwLp@p6sU(zW{lBPR_PI_IkG+77!-V)3$ z+Yn}WC%qOkiNa_eExzw>QkA~)?18b%y6NLIdx;)hpV0T1(tzL}mjnx~M1)T0>t9qQ zZ<)ifPk$zB{$N$}XiZ*^V@daEezR$|FT$+wr{0TrnpM#~u4%X2jyG4e}m3-uY zd!?ryQo3@QBWc)SlPucDn?&fFhs8uByXPbq?e=# z$?^G?sjn<;;)sQ`N8{FCmZV(?;}=p}kujU-+VuR_34!^p#i-KdC5&E4cdIm zl=t}({0+Xp=oEYLR!)Jot$on%qsnu^EV-TlVvW!2ubz6O;|5&+G0a23OBZRgfKLZ` zz%p}hm~XJ2%fAr&Ha(DS$vAWAr+JUQn5+Eb)l(j<%g{oQYG^f8C%w_G%nBxVeiZQK zY^yjA*A6(@wR-UB=WFDKr|?x+PNcUAePH&paeUzGrP6z}Ax1ra+o#WP=kpTXTC3F#?Lne-#C3R^@ZN!buU@`#g(n)HfzMSkLbCy z=jOPz++5OUk|a@=5EN076Mt#WZsJ8ln;1B>1ec4j5z{bbfqGUU;ujPe%{ z*yMsIqkhhO@^`#rSX3&8&#NxGjbY%@m&m9>av(H680GIz^42wGVj8p+;^IhYR8lc? zkx?m>4#r{@xt3o-PtAj*Eux(jJ=(;46xMIQgnnLFv&#R5BCLd69HX>S^S+=C+sF5t zTgAA#+IMVa-_*n}Jof_ypB}#iH^pN^NT@P}e(!LbrG_MF^g2VJ?AK%%a&}>YD9;D= zwflFLU%VUWMT1E-{|d(2Kdh0&o_RRo+cs&v;k|fxF@nhRCJu$>KO2Cesp%W!8KU2_Ap-R(1dholo|ee*a6dnCW#>Mm?K@ZgPGy`k6#dM`^uuk^q9oBvI$vY1dE!% z!gocE5dIIV0-dizI=&9nDSiCu`96<*`?uRb;~IC`$%5^0Lp2+3U&Tt7RT7&*{=kH{ z0-8=s&XEh&b)a7Usira8MFb})S}}x+?`Nl`(+fkc+pi{yW3yBUOy{p%&-@9m^?K!T z!)!ejrOUA1ybLVo43ub$o+kJp`b|3VjVmMoDZ4WLW=zOe4W(Ur@5LaLo_>V9%Tf@V z$hI>Y+cr1)O98GO$HgcCa8oZ&Q;!;YMUoLwET=Ih{un*M>6osJfpSabYd-PcoYS-Y z`pd1XRAh7kCat?c*W?s!t4>G+k&YcF>2||j!t~;A-*V!JbfOe8N6|@(n)Vysb1Y+Y z;E{l*X1!cH3l?C#mI`r>v!eL%ez0)`R!;3UisD2r0b^a;AfocG zgG>o!P7yJ9A;Czbl$~U87{`w3PYX?dG8D0B{n0j4&-b(ptBD&}lHW`c;~yujEzJ&Y z!@=kMsmK07T(yA#)3CQV$m%2eLYuC$`~=Hke>d<*hc_xu1@fETTUd~S+gwO#O=--T zl$CQFi`c7KEeF?ddE<@kr~|eaf3(}kCi9gWq&S(Orz?eU7O0ARstL^VBQv0zdELyb zAH!$)dGS|>V2opP$!@kn5VM$Wq}^L*QscVl?eJ$8Lz~RO?R8pT*~ZIVOYy$-ni>$l zqaXexgE5#_n~>F0Z5-|x%N1|AVtR-ABENiIyXkMNIEXq-k)ylhm6{%?6cy@YD?7Eu z*Hn(KIn^VyT#vOws6`eHk>yEicf6U-EBNG(WoE=ut2EDfMPAiWKJ=W-0sRfm=#fG9 zNV#;^>>#zm>9)^@Y(s2II^$sU1Ve+urwhrPoKK!?k|(_=!;r=`PeP+Rd2vHGl&qrq zVT8Vfnb2j%sH#(!BH*j3^h53sVG*o_VQDf$8UjMx=l+r*rY~7dx5-b3YQ;N$a#8t#q2U-jiZf?^C;8{J4HBy>%AVa5 z2~?=1oTzy#vXb5oHw!m1nUsu113_K8o z>+_TlSKIzes(b>Iexe12URwyw!+ej>!uowAa*C7?Q}C2jRh7x86svp2;z%O7iY%>({Lu}+ z$}IQ` z{E>-SQt#l*loShfmz>m)4f_*i8!PXhzT1&qh3HyupZM&bwFK~0+kPH~3%mOTy#27* z;dO5Vd}yq*4gTcMOC?6Gtav6zpTgzJAhM}5%sb$upK7FbNLdK3q`B;;D3X5T@jK-s ziP4wdGu=MD9_l^0%@6utCa?>O6||`XlPA?(O%xf{8#;>eqSeI(IvZb?G5_!wRd?53 zDjn)Iot{7^wXh6HWBC{Z*$`${Ih8bi{^4b0DFNmMWy^r;JO_)ml%T7KYprE^L-#?H z40}lHG4s0Q;2pmz-@xu#Y!9jqONJ<~Im#bKVw;$aTCQOmRK-=Rv>w6V?~i!6`!_$m zeyG|be~zTlnSwOu=E8NgLXCL7|H-c@_NjiEvSi#7+;8S5z2y4QX2d(c>L&HrK5Aq9 z#O7*R5%eXnAiqp;m?Y{ca~4*ZErf&6vpe3C^15xa1jSL++m8&GbxSxr@fmp0>b({7 z7yl-^=&@i8_bQsb2A18gSK({ss53KkE#tWsw5@-qHaIuOqlylJ6C32S=F|vMB zM4Kv4u103mX{lmQQs8Tsq_a_gZJLavDEx8W(Sj6ryvWc?Sc5yEDAfuHPhj+Ci$rm| zzFzfeW_t9kS&wG-)@>&T<11M`g%FgPQ67TKXKrLdr@pGJ=Lu1)Us;FH+m6frx0h=oYefE`NMhgT zqFcx+t7Ug{r%rtZUg>ve(1bF{w9<}uf|Pwe4 z*_%9{Y{XgU)-toHCGM*+?jwCU#a~n6Y&=dnM|`sdl@YRf^4L8m+L;=45NRw@CO4h# z8a3&`g#~kHIM!;BfrbQ=rau~&XsWfsD^|fcZW=^ZK#!fp(>yF9N5}5Q!Tf!f)}d&b z)L%nn)AUsDhvzk)0QbDpDz5o`lU3;bRP!^ypw)noPX-gyD0v}sOYr3n-n_qp3xYxk z#?Sc-6P6qK(w};!Sx(gc|-X9Aah#zClm?5BDhKMvLC6V3v|f zMHZEY%id}j8W+DgePEaGz_d~dROdXA7QFiDccbjn%Q1~xsBjb|C-WYgw`Y|GO)8VR zOhNSr(lXL1R)fFWMEPy1WwMbqnO1@xsr(Q}mr^BaxUQ-PNpVXb-XZhn`yrL^^uJmw5IHMxU}PkzzV7&An8J%3c^d|4OT;f9@g64SC8I`$TdRE9+MI;v(#HA8C(Q zliJrYvq`GDt{3R9PS{>I7ArTzeQwaNT@MPh zfkURY+3OwWaA1Ew3)T|@uuz1%^sI&dfr5rb@IrKniHv3Q#?3uvCbW2euZz(^$(e^ z8?k;SYGBm;&ghQnC98k7_9nPygtVVTbw>)H{3-SqG@G4c)3noZSFe=eTx>k0=Y}~( z##i|Kcq25mZK^nmWkYKzhHe(aV|qOYO*qQcbAe@}{DnnyM7v3DL#l?aZGrYTa`a&St~hLgLqrHf)yfZ0hJ%4!~%5ia+_9+h=Kdifmh~ z?#E^uokg1x-d>E`tF+y%|FR% zN%$tr{*mGg*7u{svCXLGk5XtYC%y(T3KOZJh@ye=-(Lyw3U!!wKTyTmg`BU>kQg|* zOPOe|X3B+yBxMANx(ZD(64)RWF9}8iu~Y0ay?7!nC# zlad+`7_ugnq-;e>`tyZyQ?b|7<~sPhHw&36X2^(jMQ^>Y{if9CoA%?3R6}j%fJR!5 zC&RRgUURdaON%6YC0yo{9~CwiuZs|6u=mUMZ52Z?K9SZ!EXrb%B1#1_1^XqraD%NZ zDA`tM5VM_#M)@%B{(h`#9S?c7Xv2$m9);YY9y=vJs28y)lVfS3cxNa_HbLl?_-pa< zm>ai1MO*N9_BT?0pUA25u!=^EDd!o5S=;SpB^ig@dy4#2`CP=*(MZnQmH&2Y#8>m_ z-PT%JW}#*`R8N!M!s?YGH^KSYb)6g5nr#cu!H zk7F;eQ=W~8|LJ&WH(Nw0e3<;sMJX58ca)85Yb&X*;(aEW?X*p`8Sgqr6f6l_5H5a1He$>x zKZ-%|6FB*kjOO3f#hN?wZh&M|2D5-Y?wyKm9VPOM4PO*?+0+^CNUpvocdw%{$`pGd z&Z4rB2eJHeXs%5Zy_!~jY{Bhy(l$t4h|LJUV!*PT15aOR_rBV?tjI9+imbof&|mBR z{pN~4i%4cURv#M73&Lgmk?(u=S?8v{$18$*lDKM61MPSHdIIY zzJJ?eC1LtgbJePqB3h4}M12q`?t+$C(1JF;ZY`AXM8W_7b0Mns`n`CAK+m8GF|f8c2XS6KzTqs#b=i#2KByfR5eqd z;*C*9&Y@3OK3C>`pD{pOL|<&PSWj<+RWVX97XB+pX0Qod@wHm&q{VV;`YQLkJy3UZbPuWcQ>e~MI; zI);r+U$Z$@XGd*);6ZI*dAVQZnkX-4+4C%J$^~2M6n1tW5&5wohZ|pu=^&miDNk9T zS6nShdUoX4N|cDu^l6{mZ`n}Ya-2>Lk+0p|kwGf4@ltIpqVDOlL)zZ*hFjr%8@1rb zQP+BkVOSIQbMy2&f8_hHCzhM0sK7n{zv!DZ-r9cpi2efo`ZwL@!QH_(j%y=4${EQU zx9_mT$s3p{39EC^_GP6|@KxW>Ogvjx(w}_VE=WMoig~8v!}d<=nK5&lYx3=$U?rk_Z~+%HipYWOr48x+6xik2#&lzDzkRr801bk4WEN-Q$31h$6l33=;A zpE$QkvMM~|XCk{uQ^=mmdUhc9KCIAom8N~hzoO^ZI%J;dku(k-9{2`E{58|C^_S3* zymf;qb&m2YS-q__-JROkZ-uA zwM>|8=Ka6En*TG1|Exi!-T#@1|F6%4DcI(C&O*g(dx&^>m-ex9#v6i%1dkVH6=ihj zL!C!M*ud)%&?7v=2C%0Y6jp*rYQIzk+S!47+_iv(pkDmH?dKLZ;;}_XW!5@kPa>E@B)`A7(H-P{3zPmKN!+-wqKmGmx0Ga-OQ^A&LO>sLTtzw{u(RMay znmX`=1s0hs>17jJU!#3(NPDixsm6 zUU#Xma|n1JMx6RS(iH(mMyw`*>W<^&hm0$xbv@6i5aU|m-(&?W>WpVr1in*?rLwZdjFCa z0fN}xfnduEPN(m-v-p?Y_75S~*5Lb9IB%%n2&>0&xc$eI_0Aow~&PiVi8 z3(c;$sOa(N`w!Mo;mGaZN!IX_01&s^_=EK^LJhH}7q?ylIV_0Nb=y6|K7Ql{XSy#Y z{r`w#H*nM)Gf&%f5Vhvv2zwbZ^iVNtF`QZhheB+-L2#2AU2v)StJWt^qL`&VeN@g) zb6Bo%M(`p6sD#Vc>+IZGJ53NvYM^>p1GEZJl$!?L$_StYACz_H5V`IbeUITxIjXx$ z9V9?>vO!?&RPekchDY+V`h#7%Nz~MYI7Hm(-2+=u{cAO%G56EC}av3249_yw1Hbk|2xw4LX%-r2=F@IGiuYGzZV@=Lyb23mN zH{0TgOCfO4hRG&$wqqbj>2Xr@a2Lne;C#GfXVbYES3?UM5-{)aDjLBQbcTD_|A#S` z-dB=VFZ|>6aFQmvpMAx=SMVD&+@*(TiR;7jr@My_Xov^IS+rL<8ZO1{6!cDmzxgK0 z-U`-+J?*j52J;AN06kocBTlstQt~DBdw*-Lk0EFIxxb$>QZ=6X#A$n+T8KHUw0Ke7 zuMCC79{yVgDocMB=YReC=JPQ){p?`8bgUD24vzGC{iCnG~6x{Q)ubW;2AX*<}r#Zoy?e z4D_IZs`H=1&J8Qu{HJ9cI(Bq$ly%)5hoLaY!?)>ut)EIUV7uvXd^x@=Og+j7JvN6e z4U-3A2wZ-M&*05yg8TKv?=+7wDKdJIq(SiA{4)IUw1dWJ4+kc^3ir97JD5CiXKXWU z5Xy|Ecjp7DJvi&{JFOTNxklVwBfvaKo-i4x^R7|c()IowmFL0ev>xO^jCbj#S00QP za=g@Zmk~hay0vSf>v|dM1KdgmzTG9(br~g8(*`fOiuK!52srHY=B9$zg1ViLJZz_n zb#hbP_V~AxJvRx}bnSLKyDhZzQ+$^1x4e!Q!FLusg2#>aQ21m?ip}e~dkQ|AmDBDt zm$hCx=c9$X>p@<5;ls-76we_eHEk!DQJkd~UYrwv(6MG*7PF(xO?U812x8fw?@ffz z83erXYu3UEXmEHY=`6>Z?4+v5z75z5;R!1;b(6#}AjDY(j{8j`v z`;#}rLU#uRC5`2tcUR-Xd=G0t0qg}c$${2Gcb)%f#-IyUG{zdlVF_Wj#~#|v z1ovGB)_bKDSmEF&ZP#=FpsBnCy1G%y%^d*`paO4LBaV)_H%C4i1X&-3By(c zv^MKuyxQ)UllwWbX$X(*a0-CYoS`?J=gSBblp2IRfUIy&sHCL1CV*zfiEXK z8FP1c1V!8}BR(p=6uDo;P4m2(1s0O6>3$5r@qS_VrF+=oH86sF#i7Ibnqv@nzeEoV z%LWb!w34ptrV3rEOB=A%l;E9TbZKs9K;z!eL+|cNAP)uY_+g#z9**Hh#{g3@KWbz6zRPr%bo--w_C)MbJ>0|sB1a5Z*D?tw zu&vXK8GwxYxMyvch}9B!CT;WO852;~eV*6LkcZ3ZWv6`>mP6QPoF1%KeyXWj#B=;h zZkp|F*DD)2LNX}s2GNI@iynE zu{GcPVPb7K04{y`X#RRi*m>Fh!Eu_x9;?po;r^%rQyMmq3k)v;{K;$fy_(*`dD`;B zIKUaO?KH>F7QQ3cG3*3kV0nZ$LK>C7&P>5>)Pm=`l%G^}FlPbB-_2 ztwi&q8#ped%ZeB91`j}Dl++nhR6J_o=&@?cc?=m3cSx17w!>&=yR6;a)uA4&X}RHG zOlCoLyb0P|lO8i~RkzuNyO_7Drfu7qk2t}F)@~D*G+oVQMhI^WyeWZRxh2pDoDXn8 z;g==(Wu}Xf;LAzGDhS@qyX3MCxPZouv5*K*u~`DhWoLzA83ESFg!z++*o^0j?9Mrz zthA=V9fUhhW4_A4qCxP?Xrtoov&R}f>qk655x9?4usaNP+Kg3mkeCH{*pj9xN%+|L zxEL%kUt=wJURcC&Q9!tvonk$J18TbZ(WwdegL^dV+SQyStJ@Ab5pXLiaZCpqrAxXg z;uj7;h}$~OK%JcY!DMS(^^uq$hs+n%bOa_6>v^26v^vU6NQm6hIA30H4b{Ty9qaD8 zigg;C6ibd~E4HVv;ch%hI(Db;0+oX8PEI2bLvASE-rvS!gO#NJHsA#@ycH#;2TsF4cpTj(V( z0&o;iui%r`%euUR;`+TQEvuk!2G^;=4Nk|bc~Xkf8P{pfx~+00KwB2`PSH*O^Hl{q zix!If4yBAG=a%P|^S?C|Yrk}pf87saqOj(FR1OBv^D>iE@YW5!9Pq3hkmp#C3RF)^ z%l-be8+x8{d<3~We1yC`^WypwZ%m!pyW<7~fVqI;s@AfqgGmlqrvN;j@AtT(h!S`w zWR}r!&rGHEXt4none!1JeFAU>jVo{$Y&;3}=Bq6m0Mxi@tlMsBMZQ~_Q)32&>q6GU z5Es*suSD{9XK~=;HcX~2dj|lkfBWz{HLd1|$_qYRK;Xmh-L^E#puC4irS@YqR!#R; z4k8+IAE7BOCsKEYSZqK?2iWFN{YhxWkidBxW)rn~ji#Q}OuoC23W{cO&>1b))JpW2ajKS4Ka^+}hKw*H`8Cf7t)>qQQ^z^7d3 zgXMdNWP7LP{7nha*{=w2hoBM@K>W>u5Swi>>q0HF<{Q6ZJzMc&azKyB0BvLfg1Q4T z5kq zMmTu>%@!AQ5>oc459i;CXG1IAJdJ175Ly?skEzMBBaHk8C~? zZZkd!_&i(yWZbVBVIAx8tYq%}*t;kvNoU1@x_OyRrC3pL0ki?GOkAx+B_{Cw!{ep}?) zhwA>@_0i%oY{qXO7^JATnEvmdR)z#KZva{6!Y{H8+?gI1*LXOkb#*v@{YbZ^>#b-`LN0p@x!QKS?}&9= zRsrB%CKf*cf|2ikuIUwK8@7w=O5N2q&m`}z62HydZNa(DXYZZks{!^~^&=L(7!k7u zdgQpsbC2Yz1sPWaHW3Xl$dps^gP^GU)j{3*9Y`UA&u>XY!RKp)pcSwqo#O4%VGY6r zav#u5wd^2MyXudd41vS07a@pn3c)3}{h~)X1~jM6^J6a1?JrzC=f$dg!B786fJXRc zCAw~nRV5g5IKST zInpV$Bn|TB(=Ia5?PvtiGp`UpfjDWHD(#L+OkY!L>6IUxc8AP)&h6$>B|M;90pbqy zaJk%gvv$k+jtbTj@aPo*?tiFV4`=dEe*~d$!DcEMiiW1iK6x4nQ$*SvPHN0V*`-(cyOj6>v4XP3d`12Bb-sSAs__j}UjU zne+8O6O>B1P_{0(tW&d-YCpsepkhRd`%)cUn!^}JH#t|@@S}Hzz@YGD{g){pTrr&# zG=k*>PCMqU8ZLoxL7kVIsTN$fUAI#NSJ*uOV$g;hI!^1kFOoGlJzRAX1J>-c4DeZp zRcg)$Gp9Z6xClV2|7m#gXmiJZkL>+e4Tu%F4PtV>H}-74&rC~KNySL9Kgy@N+aSEY zzW}t+S+M=mb@(CX)vb96m5{?uyg_ve*sXbNbN+S0gq_{;1C#;$beK6$r9#ff6KVKtJnO?{ zbIP0pR;3&%E)!65%pOX>1NSWFs}F+#b_Ik^nL5^a5iz8JHTJ*kF8o7LBfeDP!<=n5 zv_0hVT8GMTQ2#avg^EM&BNj{;^EO(9A6zn*7x<=cT#F_8y||G z@cqk6^y22de!bhMf(@Xr1y8f0ub^7RhNJu>vOJM5Ovzdx z4QQe&5CXOcINveA#g#NzFaRC3Ow>Kc<^eyq^}H%5E)UzVzTL=mYA!wZOA&-z7Pzz3 zu6Q%KCUkUDx!(hxI$_Wla+M2lTXF^SGU~iiO#7$Hs(qI-iDEOoi)-)CIO8DODIjL^ z1I9zw^TCEA?d4z>KnOZNI7*~*bW`XFBLNK21J*U^y={ZuPBsO62tHnhA_73#xPKWo zfX4%-d7Opu7F!SB1FUwxr*{4Nv!<3-!!i7hO3QZ(a*#W`gc;oBmmdnje>Q;L0o}RhCj6%|!=JLCl zZ)U8)=Pd>0lhzpkr8Udu6u$BDS+W2>R87Yw#2q76h89DzgJZ7_mUMWEK&QU=tW+VC z{8zOGpljH0?BAo>hwy2Q9qrfAM!>WVFU`r9!2t~pbUKCOs>A|%!9QC6GQW(;6D@`| zg+r;0do|;ca<^QZc+pEob@hH-UIez0WZet{6bBp-G~n|ji0gWQmB%vwagucs^z4l3 z8h$%1PQ7^3id)UYv7jj+GbM5dxSdA#;Z#67905j2&e>IdcdnoWw#f#rLmbvT#te@E z2vA|dSMi5H5OF!uj(a$3P&|3Jd}hAraS!;N3$9@R=VhD$DGa#%gIG0f*EK1+BfzZw zlAvP241BCssupznkeE1J3p?xCwBAkT0N7z&zx#CX2-b1jM$eU5KrR7UCwG$1Yoj}umQ^$C zk$3=?35CT$V6C`Iwaup!9`nF~J&sGJ%#(oJ@NU79PMW*_$z$9Cc!B=M^altGj%wHM z^zQbkOiSUY#L1726?D=9JgDPzgBJ?32Az2A4+9nr<^c!1j35vSv<;=~NABM42dL%! zi?)p(Ll!yVqO(mvk2hVck!`0yQMrVNg;jjs4S6Dd#q-{_pcR8Eopy>Fz_kFImD3TA zg#nrDATQ+VIky2%Qq!^Lwze&7GeQ`C1CZLH<1{XiQviD1ITtzhF0n`EA3^_xuA441X4SqyL=X#=far5Pt7A>o; z$HHkhMS)IPWdV1;7xGC}gr7Z7x77b(H+}PAVT#uxc87k$EZX_p2BRztys~ z5}^FY_FX%`S`0x?2Jlu(t?&^?o{(F4kqS%u&#}3wH-~J;;6ide+rgK1C;(LOYTNa` zix9d$83&TgJ|;FQ0hgW1aruUodrV+z&j36`^i*bik_DeSLv4mizz;wcc(7D;2fPNf zn^kY$|EYdsO$L4nfu|kMl&uE=q0`}{8Zf|_>of%X(MXoduzBtm)ref2xsjXvxD?oo z`PzJXSt1PEhz825V<-i>*yKKKmYd?VRJX0`I2lW<8*kmU@aGyR2;SxUS%4MM+?|f= z04ED16doGw?yLazLN0P4X8;vCyIxLCI~}{N0|t}t`hT(a-cL=YZTu+etFHPAtDvZ~ zwIBilt4J@gth#{oULznNy$MJO(Y2sbvUKU9(o5()pduh$dJR!J1VRlV{d?v8&Y3xX z!I?QT?l0?@2+8x@&vjqdr`@Qv`rYYp*!kZyMrp$)e`krY)ytki&^{oU%ch*C5>Vm{ zG|R_sdek1n613&Q$MqK=`4x%}EPd4w083hQlZhH=Kds#{&KJ8yRs6e|awwo!xI!&-6bOm9F?mvnoZelWtN8}w2Fh*Ap3 z;BGniw!6^Vvs(p#GFjg_4e$?Z{{qsRdMy4f^twT7-x)uqBEQ}dxiVhsYpC@qgpMV# zHq!k38Oc0WyGfQ<1bxM@${l&8xS^I_Bqoff;ynrVo`j&cGqB8HG-g(o_t>-u5jotK z^Ao!Z+kLlF_zuI5hE;p%_~A9j@D4x_s7Dl3%VwyA#u{P1-S3|1sE4Hi9rH_CNan-4 z;{SW||JWF1A@!g{EDfM`F~$tqpGcP(?O1OlFqu5)&GHcs+ZX?@xB3Nn)`p%Kul8iC zAp*Ba8LG5?PiI_9*5X_DiQ@W=_q~%o_}huY*1vH+89YEIsy8wH>88WXms(nU?%N~d&P-9GZ}YlwKG-QCtTUQ7L5g(oCg z>ujH~vMfo{BE90teBR&o^67tWiVaQF+jB_?dANmfD&A;mY00?2B-etB={DZa#pM)oZ}5?ox@75i?9?tW8xa_-})koPB_vG+guWBDcfuSj9ei-#^4adAEIdUHMZ zD?w`i@5oZ>Whr^~d9D|^9{RhNrS@j-<>HFFb`yT;Z#fU2YetVM?f>263Y|~Nk*&g& zVvawzDQ~dQTp{nOkrwWn}Cf{qOS0wBFuxyqsUqt{(?4lSQuo-m)88eu|CV z<96;gF}D2Di^E)8dN=t>^~5bs{H9m)hUw&3$`<+0rS^=Z+n0^rOrJY&iBEKPpzJxr zb8p-y-Ol&?61N}S*ypAry6ju_7qfS7TxxIoxziH21HAXS9S~jTE&C5kW*;A2_uKn3 z61Rgg_qi#H?v$5)WnuR5jr6vj6O_1(>f7h`NR(k%`kcMCkFQ*}<-L$Z%a5a6qh=w( z7Qb<|ENPuZQTrz=>}-b%GY->5x%i^&*4-=ms0Lh`g>@}+TAAP0^u#EPseW}0TAYuq*WO#rr+0ym?)mPI5OJ>CH}Nr)EWP8mIG4V7 zw~Ge<=M(tfjkuf3#l`jWH@L%p2y*Vv^Yj0^htJ`H{vM^bhl}gWG0v4&{PpHvSL4^( z`1PdxDh0m^%hDWYnrQjD<0O;4RuHaW! z@T(O3Dh0nv!7oUe1GoPg5Pl5^zq*27?9#7N@c$DsF;;(6hKo!7pE238%WVYX`cNgU zLzg7_6J@%kRz|qE&~L9&w;mn&JxOoRyGwmyDgW5**$dP--_hd^hOv^@FWub#Wbs1B z`~}k|f50fCiWQ`_=*U#uR-Gb6Q2-TYIK8l10y8$4OfUeNa2dr+xYbb1&DW%r_oc_mY$Y zr@y`)aJq-AavRGIPRKVdfJ6Oi=BlKsN8g87sFpiDaE?cuS5OFGJQtyd3{#ph>K1j6 zoR_r?v+prUU~{UT`q|s4@wMtfdrUPUFkq^8YuGy@S8stdC8s%G;Ks3{ zIAmF9-~v8iivA<5dndwDerhw0SJ!>GFwjEP!lC)HdD(0ywlRp!_oY<8F#?`@Qt5wF@YUmG4}ooXg;L6rW%0MP1SemOx)amw5HPuf*s0uZ|xSdVGCB zCrx2Z>%;H&l2rpyBzcF9!HO8o+`^dHSdMP)V^&rg_*74yKB;x6%x$d9d!~&?MBQ#1 zgl*dcg4Q z%*yUG8km?2?_&qA$Lb=qwX`ft?*FV^NVP7us{In`Iy!q&+G>{+yw=2K(YHcbO1;`j zN}Xcb$*Ru%v*4+^DkW7E$_xq<4EYvHCs{T!PEMV=loTJ6kgzlJeB%XqusMte*=QHI zWN-{qJS;){6Ghu*?K{v&VbOgTdaNfcP*)@mZ;g#~>%yY)5JNz4-d8IS6ZCtnl3&vhmuShKNXV`J@> zPV8$r2C|t3U*M4hHJ^w0`tMn5jciuFYcZ8FmpH*=*>&&jpBq&Zo*8waA8sDm)?b^F zb?m8`oep;$$*#H(xc3f!7h)j-X3 z74%kjE;yaY;2)AoqT6OZAn8!Iq!lS&S|h8iCW>UUb(j&Nx9ULk-y&LIoEF;{K0M`NsKz;0eBxLeF{rvg3Q^ zEl(UXN_D}sn}l~J&RtoLh4OFL%#_9@%2$fD9hZlq4k zf2m*eWazP&`f~x>Z$;FZE9D>qzUKEzM_2{KseAA{Yu}4euhndkhX!*z3H-<)aWGV_ z2243m6`EHwDTJaK4>{MtzbBOgrWz8#bpnRa-Yv_c%OkqXQV)Dx9)kOnqSvQSPr*lf zqs?#41{Xv&=8+2^y}R*@z+Qj$;KB$NiN+RN54?$vIVF)nUh*BmQ)X++3|cf3*~AQI zXXon4Ao_GyOFJVBkDPJ)zF~Ty*wAI;sb%M~aP0kyx*W zuC6D(j;yVK--WF}jj{M4PXWqx)9vu0DAnoT)(nry1^1-hc16U0&M><8;ogj#0!BMc z-d)I5RwMGvwadk_v8{x(vdb#L^ST8X$-i}FhH`(N@jOQ~x#^#O*`nd$`n$7h==INU zOYKLzt4~_G`~BE+&<)o;EE$m4Z9&|S5Xjbymw@ZyHDCRNQ~bKhdqvR!bYou1 z$UuKTIQqu8g~s`FehQ098u|G82IHupOGQL4(CYk_typX5%7=}{78c`?3fAZW?dq;{ zT+omEIz5}9c@1X$vp-D8=M~S3bIbKmig#mm4X}A;rC&g9-4_%lG`ujPl_-q@W5_kP z(I45C9@^F;AwOFZ>sD%WH2B}-V$^AiFZfM8w#WG_D%}FxR;#mYwwex#2wt(9U1Lq( zf@iV$osTjJ@21m25p2O$g)~I^4B(v5?A!*4p#W?+S=PB$xXabYs zS;udP^}v6KQg(rQP-%~dQwYK(HQn;@NkB8&#R7+KZRT2HZI&@|uEpc~V%wlvde%`B zD%HNNjFktIgNR>wqjV*uHNRgj=uDL1Bv5RbYHm4pd(`}-{gqWX`Jeuff)tO2%)oNT zK++DVXw{h8vM*HTjtE=~xb49r_i0JfCW1^f4eI?@r4`pE2VE1St;dPo)eSOSEjIrC zJ9xEVFmVkK4aHMFcbS)y&_ABm2k&%QM_Z0!Ul?E1PG@u!U|E?h`lWU+&SMlAQ|Xjh zrO>=?9d{7qSKZ=Ps$pPxPhy))k->f)gVVkj=`m$@MO7r}Xdbme`V3~vicsfA>|||F zT!!+qY{uS&GKs~w`5l!t#(au?-bfR83y++XR;72zh7&(UOuGzL6GEBfGqJ}+CUErP z`qjEUJeA;mV*csB0-oKJhWSVv9Jku`@3K#B=!;M)$1a=K&EhGh=$99yteOUt_nSuC zMWdif-*|Q)YyUvCXOq85H9mL^cbNX7#Ambz^xO5UBk$qyyDNg4Wzknnvozxw)!B)f zoX{Bs81bq8fX48sL zYnXFHMzQJUi^EiORuFmFltq8To(v#->P6_{SRbZv{Ff~rx8LSBE;RGzZE}%M&TM{} z#WI8X)Xc5&=$Xjs;)f{OY^<(fbuLPFQviAVQ&5L_!WQe`{^y6I=Ze3fKA2)F{+$Y< zyAy643n34gJ`4M=1}=NXquyOVG`v@x7|ZT~t3(7Fi%qpo8UZybVVwU6G5=PlK7h8i zk0)fSTOrV+NFPVrbMR4$tP|-jE?5jJ_@~zoR`U)BY27XQOc`OJ-Oz=-6!7Rkildbl z-)YIz)_l^`$c4uz3$jjrJUuvD8~W|XS%pcjnaRK{`EH`ac}uA8PxkCHz$z_&JD+b< z-0+#ltiZAR7LSr5Iavk_54sK4x!$KJuouh`%(#>NH5)UAVtd}}J#cVPqizr6jTjZ0 z{p^y}Y1*C+&v?uz9nfVr&31h`eLAaGeX9$NWMRp9aUY?%vkK@QYV%)9Z^#C}GZf9T zFp;43U12qlwm(;ul!qPXk^k_TF5x)x3gN?5zwwF`&stG-;Ga=zeKR%o_56zEe)(k% zo$0>A=0o`=-M-J8bJrT{X`tT+1I>Y>f?H?sAKPP{dXnRVx_jJND-Q-%$18)E=1gM{ z+`?BMx5tPQU)k6xR|Qk-qtt_V)pplNzD+;tTw$To86%0}h8K%QuaFA<5>NQhlu)R& zobA}1j8Wab{}Y#5VW>+deu>jK!rz57OT8E*@kV`jy;)VPUuo$%uPa;G*A%u=ZUopW zS(}M{2*&zQB64-gnNnm~@i)#1_FNwO)`(MArrSis7~8HqBSn_g=H-s=<0}=b@)H-t zv@Tgzt$>-M1XW;S-x|4E5u7vlTGZ7D8ybQU=22&OZ6=F|-P_F#SbN69(y};antIEj zYqV5>5Ym|%;wzI1nMMbNzq_l6d^E~45EDd)kX?pE9(zS%K5E2XWYgbBVr!-efvoXY z^9ynmIN<`>q!C-0?&YrLj(>j}ygD(KB~ZwEGZ4sJKBd#AUr_hF)z7{+Ru<*|?3_4r zq_Xu($eyJZ^k4UmU3DT&E+8MDB_~Hj^apakkg~4Z-r=~e{3qt9cq|wVY8Q~Fn9V$S zrYuF z*zYQsF<#T2fM%_iU3KVit96(ebUk_5YFA8zm+N@8PKx}smO9e z-Yk2IH>uOLce6a3LMhuTNef2{EV7p864|a{t6NnoLE|V29$R2Fmtg6sjUP)+s-1=U z(*#W>WfJy3X8za(m`pQh_C;sp6grxVCo||wO1lVuj|}$!nd|q@CALU#`kZeUp-cs1 zwOBjVH&M3>JN+j-O=0scZ_+M}2!8%3O`Q)=o>JjYY-7 zzA>k?B(#>RhX=_igIvo-vpYLFRLbp`G_pmdi}4_#cDm}WsDc8eyLzf_rl)?>Nb?zu z>{++*63)7LK3o(~1E$&Kp`w%^2iTAyPh)Gfn$X@Y7ajO_ier$vrvlf%iqv_CTl9Jo@-*^7|kVEL~hCs?w+ zZ_uusC{UB&Y=t|u3tJg3IWSl$OnITwA~!tbJcn1n1yM8oMsll*wE=xd7xGUw6pGY8 zbtu+tkj;yBW!!w+H`!>_u(bZY-u>Gr}%VRju$=cd{IoL7D4qTDN0Wepd)0 zC;#a^U1^GpSN+pxCsiph`!}sZTT&AtR6A5{b>{0K-eBmG(xdHl)wZ^a>q!RX^Z8HD zb|y&GlU@qkjS@^^w?Lmv_ipo-5jHI6%g}4@=?Gnq4nxo$lCSk^kckSTm*Qje;GPDN ziE|m*>sg6NbC^ZJUP9s;)5|xpo>A3|71Qppj!v;z)?IZp2XtXp-1QzwKQCs<w zyspKBG8KSKzhx3Ch*0;twG+J7nCK+(?HHu+FudF1u_enFwu=HrZ6P=zltks93LzHF zqOQs&Hc(gx#nK+%oNkNgKRwfi>D)RaVO;pA?>7IVN%!iC>GyA+YdSj4tEsJZ`=+OL zLzP0n9P^VP-B4n8TXyJ?io{ z1C8!o}2odk1ABau|! z#@@Bx?8xp;7Uhv?2NJ=h3ix+iZL==IKw4t^%y}SNjK8e}8^&zcJFWaEa^t4Zc(ty_{ymyyYRYTo_p|i6 zy3$mt>E3Gc69eSc5iC@Vl+~r(*s94gZ;1Udyp;v(zP&Rx=U%(4*eW~C-{q;(jwIAn zq^^>joRMQsvK)9~E@~$io|!Sk+PFY$Xhmzg@td%7=s%g;O9R-(`Q$(1W7fMBJ`~sP z)WM|9w{yfcYujKcO~p^g8v3~@*Uw*$W_)zrSsBZ#w}ajs_MD)9eBWJAS^3e-@m{=; z>HSu`JY?e8kd9be7)(jNHdbbX8#*0(7uw`AgV?63+Iy~rfl+bDQ1fJy6~5K~J+>kW zp$ywF!Q=&+xM5CXU%`lSsQ0HQd$bY?*Cxy}Z&G{GM$87fXTF_}dN^2On=aWFDZnXV zdwG+(3sH1`h%EBiYy+%edzm~eE|yVYi`nUL#b$+a#YDR7o#>}y5JKlxHgi)T>9SMUaneeNh(0A_5R#6 zr_P_0Jn+Up7f`#pPrPp<1eJX7nVa*Lo&Z{G2dQg8i#Q@AA*5X4iEHL2QXjg7N>$^l z?AxN?c5B*fLAUIIw=2L05SSQsqqQlKCdw2&Z$yxh_{?R*V&>0NZ{FYr`o8n*3-%X@Z^ zM+fKF8j;lAsSOJpo^xNrs2uckdyX`nPS`>}Dl{vd1`D7jF54qbIWMfUH&sctH$+EB zg_OX)|NNYGuAV{aW5yvs7~x@hxE#-;x_h7fbYB#rxQ%rJi=) zA!tY-fTgh|Dclg7s%U%D!^6Yw<#a?u1WdUoa^*-&HTS7M-`U{npi#8}gs)vPQJOjT zf**OR!g2l4>bPj2dIIdaykgq-aDLE&u^9^voB$5k1Y%6Aev6N=Kc6v|{gJ8Y(>hsHv-!qHcdD$RY@;odLq?k_4xHSV*-(|6S=aG>mHfI5|0aJDgvp zy=(G)2-U^7z+;_P|G6rA+BcCogFMlJCG*S>e>NZBK2sBj*l5EQc;r@~c?g15d6O_$7+4O#ni%^OxAOWEfTYFz?9yQ>bpQJ57=5h?J&>&p z1HG7b>h{mOB9Q`3t$pI~c3mO&^m5glz^x*1Nu~_aFI!bCzD)60_MR-oW0YExmclWl zyCOKENBu=K16-G$jpQomZQPCzG*|gal>qN_Lp!XRneg{p}VJt zgt&j5jqG)us#@)V?<8_Uve^5v;06vl44H=A{sU~9F`E^zyl^KU*(<`BazfGWrK^g1 zYljzA(Ucr?G~N`58;U_orv-Pk^mgrDc^kmAsbl=<;t?Y)^CcnFO-vA)(XS;V+8d(} za}PjL)oYFPkLmHLcFv@RKnj!6ghW-g=0-kmhIutER!38N7)+C?kNRH&)?l`bZ;cXA z@VA+9d zn9XE;%Krv~C%yB=!MWNpt6CqYbZ^>iek(oyZjDwG?kmjc&Q1vE$`}rP8>(-Mxge@T z-L$mwA_dm3mJz|&o)I)XN*Jnejy2R(&w?EQid1BkTWU~p-(Llz*e{95&_MiA1q*J` z$yxDO&)S*!R(KgoI#o&n*2`oxA*##D&GJrZd`b%an?2@4jhxyQ`&mQd0voTXz!aum zX;KJfH9*#BF73hx@0mNWnl-}bEl=!90xY1+L95=7VGRc%^IQq<>Z&RsL_mfR$3-i}$|y7KWRMTWBWsj zA`p=OgJ9M@IXB;o2?Be#I&0f7)4*y77At%bRoduGyDLnKJOavvmeowdHF@vpk54mr zR=#I8%UgP;al$VBVY1z3Qa*%XPN}onM4Xs)PT2smTFQA&WoxIHNLkJ&VQeRNH(;xs za!BN!s2ElD6Y2c-^DP5OAO=?9*9;b#%ND)jl_=Rfe^LK3vFS1Z6Csd)r*oc@~vlRIgTQW_7&ST`AOtTE|H`jRR2z7TUCnG)hCv{Lo!E?B9g5~C(k)qG4%rD7G+S}(-&pUz6(ZN2EJfKS zzi&N>zaGwCo`4$` zIA4ecnlU|?MIF@C;FK#Z>Dp}o^fpt^Tm|%+AIEAH;AgH*!>b+b=CDr92e?T2S{ zw0vuAst9_sl({**hwwML>OY^8o7i7&hYJTYUISM{+z?AYrQ%_={CxfptnCm0SbG&` zRv_}o=jZ#|L~04ZQM&3IU+v1J?&W^U$TBulnw-Pj+mjTnU+16Z*L}c{!I$#$`b6a< zDOs|3tX6v>qTA08UAH(iVnfGUO9u*~2Kyof_{aYk ziY)#sB0lw+b3eeh**3B$S_GL*UK((krIN+P4{AM~G5%XitH89H1pN=5tDY5Lj|p@6e{`7Uq+T5;<=Y^R%!s?Pk47ipIsqzS&+%qnihb^RjH(+ zhLd2KjyA}=`QrWcXBdh$=0xpXpQzMI#8Jj2eKqE9@gT0kI%71w4a)x>FBYAuzn<(8 zxjY0p1`&rX;@zPbFn;P%`{0Ff`jQc&RXaS2> zTaD3Tv+6rDVWUtB5;Wb*Z(6GKQ9aXb%m)_2>jSs zw)wz9s-FpvwujfUO3h(S%zfn5T?|}9A4hlqtn+o!s@*rg!ewX~a(j0#5#ok@=esnR z-s9U#R1wA#n5VZDrH|p?j$svAJfS`wQf4Zo8vL9-kssg}-Ef6~5?MAV`r+@f*w_J|VX@u=f(i>x5 zv=s1zU%tN1s~)Dg&zfl%s#0=^ouKGN=Rh= zXWW*)O2RFqAL11Qd``;O+cB#n{tRdg3N;3{4Wiy~;|#L~lh0oR{3t9$>2bMQ@KA@b zWtCgJ$+Z)7ym*!tw$zrAh%BS+bOsA<&Bx&`2Mfty&Sjc(%Z=N^Xd|-2%7xwz+6*n| zcAc;rCr9$FWsCmOL^fVqtLXl8rxer+H!^s}p^&X;JvFkuB`W4LMn$V2RO-EKY;vN~ zSZfuClE}+(b|Mmh>_8F>Z&}$n){+UJ-L+2Xr3F>r+Pk~eHa;2x(zp(Jfac}%hPtZh zCg(J~Mk}7h8z1J2j~|bSxC(or)hPD;;vxD=kG~u`;>P?Et^03|J0w~gY3j$Nr%#0x z%tMDX-#tR~Xo=C=^Taqxapl$FIY~3Y*#MZAj0#VYJU?j8b%?Q|%QJa3Kinb8wFG{6 zDH?F`QRd!H^C$fULh$2$G7UebY2*<_uju!?CLWJ~*=(Za7u-zSs@I5>f;77hVBR?3 zz&`h}+#jzSHXmC3<5Uq40h*cfE1xB_5*~yq(CEMkU$)w&H@7Jy!0^9XKGNuXTeBVD z`>w98W9RQM6m6#&`}e0>g_P&n6j_vKYX^+yX@5#nEo|!Q5`~_Az99n*CuF%8VZC>4 z!%TAZZW115?!BIQXhMQfeB4a@lcVDzM`_dHacnMfpZvc6CsyIoy{c}0rKzj;x4hsJ zomI3ERe!zLO=l;U>-T@+fBa~;@yYQb$b`P+dznq0xxWRnpa0msQ2fL5u-+xX4|}iw z#clrj`uqQ@89G@LZ z(U-16;Kq~pcT3$a)Bf|DRxX#`bMb_uA9SDWf|97^&7*eR1g_iB{|kEX1~JnA7dpK^ zQX!gLIAqcGHM|Z^p2;6jEieqUUMCPKL#;V=0N8i|Hyu_r@fag(i$bclDO~1 zcVClY-_>u%{xh(cKTeJb!&F>?lVC z1$VnA1JMKm9!?|-z#yv=m7bF|(bZ2so{%)*5Kc%Qkt;O%8i!L!NiYFK#Jy_F5!5yQ zJ)2US(m}lEB5GQwfaX({bb^h>tIcv^eXgd__`3PRR2FoSN)cs@u*#MU#;_xJbr1LaGH%s)uPk@0hW;HZ-fO%h}?Qb!>RG-&axT9itaPgciC ze&7by7ws_^L8YsH`hek4Ce|8*fx%m?o*-2W=(yLeR-NPv3;`$!GzQTL3G(i=?fRf8 z^5Qd$*H@2Ht$jq?M&tLOq1ksWzDk{dxoe*?}uc@{7 z3yLdhdv#(Bz>!qh0FUK(Xy1j%tJNYQ>$V?W9))bJ2vGL~+DmnT3~7@l;Caug5%NH* z2p;te3WvQwhR(%*oinuw5=V>UfWA0?r;uR~ypfg25wO&o6!mN7e<9rD3hYW(qvsc3 zdkn<`8_2^GKm!^&I%a2?enBzGBZ&|#9w;F?R82rp)+CD=ASLOh*InAHnP|g2`c}Wg zQDxZW>#Jx;6=Z_2<#531c%88V!~8g*79xZvBkO01Ib=e9-axjsUw0*nwxb<>;luW_ z?ni??JM$;biF7~TT0f7`NxCZMUF$~_ic;VF=GdK*NO;faM<%coS#2XzkC`c+ce1jw zP%w2v(%07){He%MY~oGXz|A;F59DB0uSHZKV-qA4mQ6R9+uPgbvQD8i^NdEO$-D>j z<*Nac-oW{L;@`gr2><9_J+{+I^mvRL5g;!Q)o)L0NhKX8m7!T5R(sre6MY9v9ym%T z{rR)a)FyB>?2050AE%?S*H!h#%bD^|OS%EF1^^iobb_!_IWg>qH{$tDd_eF1%*)Bp zv66-z2{RLghhh%muITgxb>PR&-g*hZL?_6S;AvD_!&SE@Xdg!9m>WOMVS?Rvbx$4}$MtoF}B@*-zu!wX)3kLLG zGmnZ}r<4HyvR1YiNEuN-&}=P}jwLo_1h9!~O8-_vj}C#2_)ypiyxUxA3lfr+k_~Io@^6NKqzX@S$HakF?Czh=Q(}Mv( zJ%_!$g&uu>dQj-mJBq6sYB)!CbMrR8&3EWiViB+vmbNEY%7YH7PQZkFfYa)e=xb?c zQtgcdcU+wxdn3S7*F<8TFxCY5s6Wo$0yeqeb?il$P2upIaj7bgQdc_n>Ug!J7itcc zFJ~zOM7=zMrF^@^15`FvH$xqHR7e@rgc1E&)ev_IUDu<<@9L#jw`ZOo0)d^7lFw{c zQhB~fK^ZhrYeQMCFt8QQkh`F;A=!JH)PKayDJj8jNXXMp=}A*ox~A$pTxj0j8N60$ z%6gjO&>62bU2=;z6J&hyjw^5X-g4M?(htb9x8C+mr#4%1^$9vD>ZrNT{(eN#_d36} zsCxIIhCm1{1!YzzTHss=8@*OwRl8~FiBp>mKYN7#GDKBx!65~Ssyym;UtfI&d0g|N z2%w?Hl@>#HjtT(BFI~S{#EUn zlN;!ifn3kKk+hwOuXBJ=sxeBMHz&^matyOKI#ux}0MuHHXF#l(rBmiseBm3qTfl#y z#$@@8A+}V%z|f)MHabE~pRk|)s<96tqGB zvuZ%)R|c!Jr#D|LAidfN(&lYxoQ!l@isyetSY!ruD@DPxv3H6t=)HT)k2u(k?v2$| z$wIQ@>o=o_p({lSgmFl^Td)aX!LuyyI?NbKv}xbk8w7F4=uc1d387m9D`T7+;+W!2 zS?;f#VBujE*6hKAfVP!MdCI;>VlW1JNsYldsu-`upJ7pgWNr9La~<&q$@B(;IRbS( z)2`((h)#c?S@kY?K$1wJb1%cAxVwG~c~pSL3?Q(#2Ua?aC5Etscc_V~`hanqNp~{Q z>?HwqH7683N?0xEGvh_1fZU{CwKWF=@|#4%b!FaOo6nrl;~_AHeOPeP+{X958uoCeG3 z9s3h(iehYABJ9NQh_j|UW!f+zfD`=#0+Xuo;vrJKUsri!B8_yxdI#Id%MVHZQ9!La z0@iA36(5i@d8JJ_rRF=4JQ7oo-9FR@yM|LnXg(0R?Q~8ga5Ax2*D7@Lbz6aP5smup zMh03PP-SneL{|St=U6<%Bxc|!Iz=Sa&{Hbex*3gxDB4a=hT{l~l-eos^p)~}nLCkD zt9|EXeKqXXrU8v!pcVn749dyS^&e+J7_r)wBr9o@tC!<}mseS>fu(!Rx$F=Trx@13 z*(X2;tjm4Qg6ee5b_2tEF$4rVK=#-DU~G+)_JGi}0s5IKKZ@FG@o&dz~+q_ zgk}5R#SAecRs`q=_#rqjE724iBn?tsKo*fGxoxO(wX@SrmCofZqBWP)h4Qpm!xNq; zfRQv~$Y63<*q}N()fRqJI3Ecf|C@f!%%+uS%vLe5KS7OcKR-LG3faP*OXXr^xsK_&1+P`|)Ts2PX#vvr85?6(mXSfUX8}>dGd_Kp>n~_^x2+H1?!|LiU)SrY=pN(im;)g zuiz*)fC>2j>^UXxzB~xpG0EC)X^;=kVrkn;zN>Pk3xp>eR2T%&9O5954V@C4mC>td zr1=yGbk!%yqF#^km zH%!3_P{6$E`RKGXRJY$qPVv%38~{3KWT1mf*2f@Vv<|24GGIM`{8hzJeZQ^yixu4yG+#%*M$7)pwgb-kfa7$JByKPObtW&`Gi zMn0No_J4~$&rzpT#7Ka}VA1pzZ=%2;me62cUWqSuUAuY4P`d}z`vt|d7tO`V%fs%VNsql~c`?)q9@{9DH9@lbo`o+#Am#)d z*qIh_8r!%t{t_pyq@)yp_tkaDy3j;F?kcCNN*(0YRgX7`xzN-GbO&;6NK&EtiOCWi z6y_6oPB#n2)Gu&ARlJ3Go=8JRC~XXuH-ZXb{SF)ecn`jAE|BpxK3<}5GT6KpRD%@G zzntzkI%kcWXh$x~|o6$*41-XoH&4_P!;Ymlg(`Vo^N|%;0n&2dufk=fy`z~4*Kf4Gda!}z?6+EYixF8&JCm$2f;m4x& zY1o|f;Y!!U_-YnoO8{PjKK?c2T?>?~4!a6cuR*JHkVUya?E_af-LLgD2oyDSbu&QE zavr0ayc-b=a@C1|he*&ER>Z)IF2K)S+~DEx9vm{0qaMrYsb`aRa}njabc)EoZx4FS z>5P8BkV3nzymr4}n5}~&S51H>p<$EoQwzHS`MSi=)7JHm##{>KAtI9;YWWjT%iz^W zg&3qg6ac8m!Un*siE1TqPUPa~*-T7Kz*qpg?DR`wvGqil5zrMF;uH?>KWLjdRdR|> z(keuQj;J0!U)=+4F7RsHxN2uvAPq*r;S3$gtTF3MdIzwK&;;*fQyK~bla-ru5g zx6{$1^bcQO(8$YvizT$6VOyYo^Cqg2Ju6%P`~l6dAIbCdRxg@?^Ucu#7OSJXTS(q* zRJ(dIIV~*>stwFscw4&M9s0dg#U)S>=~xvTmG+N0Wk70ty;O($6)=W?E#m{FO~i9l zWfS&OZiYL;H;h|I2as^7YPSZvmNz1;5g^ZMGKCi0_*ryZ0>L>J0 zEBVomR22A8*n9RJPplX5y$5rd6cDi;X@0)*a5jSV>j49fvJaYqwQRH3k@a^SKs?X} zD&cXK3J@v78}%sqcFGm|p@jS+JqRrH*OE}0)6;Fr??lc-t)>eOQ&$5BFpRjl^Z2j= z7f2vyhVLK_0}1F%*=rR824Qc~{92R3goD22Te=R>hi^m z-)vu=z{_?S*fyc>2W)fFYe3t+HA>qm@cWH}!^Os~WR%J5#l&?ujuG#RQ9J%2AG(%_ zN>@taGj7evYcPaDav+06#u9u47ln^Sa=k0Wa;--}hlZ$4B&U}5&^nRa`6iVvfT|D&^Lzo_ANI~q zIE2tKQ~OSXnK(Yitf75u0hmS%UGAmUcj0)%%#5xHs!<^qiD0h-MXEjvq~CE#<$dZR zHC5V2K)>#~jDcSao*a9hic#U%E@ zJ{f(~W{}_7>+_2RZ1TKfuW;4NNRyEzP__^6BnOOo)bG_5-|f!Tf9+*a>+D28Z8prq z-mBXM3QW?6rTsb)kGJ*jiX!-qSGiUO&C;e{?2pj7d?>Wt0#{ECpoqJdwk+eQ?dD%t z5l|*I1bH(QRWJ4)84X;Jhweo?mvs9`(sHz7x&_M#)FfPwLx%&-v4(*g{ zt7T4!f5kRXhf~n?>+iohjsF|hmjkmJCP1la)?|I}Y6)`(wBoIq{YzQ>$j2T-cNQ6* zhRatd2+#%vRb2OJx(kZlfH8+ixql6^G&%Tf0WzHPedGy*D!qQpbHfswKqq;B1dBP1;Iz zY^|Kj=%2mG4`AukuQs8l?;QfBo&4p+kt43kvEZXX^b)4zEwSk@&>P8Za8SmChzq8@bc3<{#aU);37=93*`>y2$LKsbmEv6`!5 zJEP}&HK(w?{l*Uo#VEU5-@apCN+TN^K7Bq;rIz+f?}~!xB??`ds7r$^IMMv@kz5z+GbC2 z?4KT!%Nsh9o&Zh-9w2QFq#R>TWb=Np;ZFZvqPR~5{Yb;m)aH9J>`G%?oGF!@n3 zqwTWdX=#Q=S#BNRJcgDP52G)IiJ%#!-_(SNA5e7TyM&9w!NdO5do9nYsi~2}oj-rs z55kTvtFi}yJsroaMA%j5=N704tXZj@yFK-A$n0|f3003tK%aJ+jIVb0pA`3Ax0xO; zs-6mJ6FR*6_<>NA(sJ$xjJh&=Ry0qb3K+J~WVK)pw7T!-aoJtbkHTjZfCmP|cSFUog`ske}ndZ#f9@ zKDwB|iiU&berRtkV145*l-zo_#<+h0df$Oi76?KvdcZ+(nf7fF^(>mJp%^zSHarN-$|2A^ zGwBp$+gEN{Q$Oh#!Dvd2J~T(P4X%v5c$973C1e7F6Ew&^7&&x#0T7Pa0F1hYrP-1 zV{g6uFZH8t#@T14YvmSUx5G_@xBk_G(U%c0TH>oF$`daR^LAzaez(zLeS5NRwkd4|u-YAeX%tj2bIR~R?8I6H3TwCzKWU+gFn!g)9C~O!| zSE<*TW%{kpjchtimh;8g5$FJ^1zn4>S)M|&N1^!ZH%a4_F017rx&;6rPTY{NI7Iv~ zCCOuFS>p8>4~1kzDB!}~FK+Aad#t1BD_gx{7>`LV*OYbdr5NLVk@+LLX)~90Zy6}K zvq&yLT1sL*-pkbsJ%4Yp;qk_@F2k==R^KoBvGQ=+NlQ2VTA#VE4`8<4Y#*rV?s27) zOYPgzQBz~>M^n**%EHu;;AYJab^$<=(VfgmaT^3E-Z(!&vm6Vri&ZQKL zmW(#{SK3@+mROpP%k<_G*1o7UZ>y)Wc@G>Nr|{(q|DHt_vdbUj+}j`L#9fN8_ny!9 zn*&!JpJHriR-Cn$Rw&(0;%P^mcsbL5!o3M*3E=_M_kTa@s*|_DMu<*JoyP&A;kbq~ z6`HP$YEON$m~3g%A^0R-lKGSOl92ymrlq_G1Aq`wv4hFioHxP#gM{M^LB#@i<{>c8 zja*EoDt~zF>7p(5tA6 z$U-jgek;!hv{{=TE1urbD3T`VYFaQ{*VB~Hw(GqgdpFxd&4P0JU$D8I+F9C_g_GbC zXT{|@On2?cDM?9zeWLuL5?KaWZ}^dqHl~7C4eK3?zJ3ocD8>OxVA|bP{+Z?Tf z(<=Te6hwrM@Et-Xie7|HS$?M4fvs?1W&$4wUde{9SDu5LpZWn4Bog@b7&UQ}10EE{ z!L;!hx{G4V938vObU0`W4<>c+{<(E5J-Vtem9YCDtSgypNP08LD2kz4wiiy?7=9-) zW3t_9%dB@MeW7cYuG@|ItCbS8)s5R(PTqae{kKxq1h!e6$8se5DPptIz^o(dzh}+a zk;puM0Hr|D4%$>Iy^kY|Q-Tiit4|8heZ6dk6DTO0Qdwx{lKUBJmZI+=KsPj6zmgTMay;uPFFI&^Jex{$!S2S0`>d^gP%PQ$) zT(O6U3d?JR{7=DfW~fx)Z#U|9+_wZPs-j{aU!1Dki^Zn<%+5vM71oz^xYx4Qu+mL` z>#W9mm`+R|gZ z3(KE0Q&?CCAAc61%;;sboYV)Bk(o=$r~0whusK=We7Y{*-+k6mA-z@X8v{7{vRO@u z#ZZ2rzrP`>C3)SVmi^PETV%GHFBVs~YJhMC36OJ#e{i?76JmV19 z^8He?t4`_YHhhNZDuLk(M$7v>*f6ndi@NPZ+h&t)&B@GLbZs?@YK;!tJ4lBAtNr_7 z&+S^ta1`q)PzJNSs*|Lom(#a02PL$RzKm7HpGx~}!?;(sj5L@3{&KX$xZ@)o!6bUxBIv)S{Cd>@=IT`-6e`~qesi4jkKrF!OWwNiJ&!wTFVS{s~JOIKe{b8rlwDAUHA z6jjw2Ip{kPZT6hT3s3ae*7YM+?(KOFN}`Q~O^_+!OBqrFSm~idkn)0ykPXL4h%CSd_sE;qQq5>Wnu|aT!k+tB60jqKnMGJ^@sn(ipYE zz(Boh5Oux^w)G3YhDOiQ{-v4elN=Bf(G7icHa#>Ye!@N6{wr3glH7ze0D@{7S5n~C zGvj&MozfxVAwxnJ--G**$4ox;gYC@emS0>1Sq(Mxy!NY056%N>1*r%?vG}pgY1)@T z7k0!gN+I1|Q8Jr#+K{)#fL@#m3`3t;`&5SS+!OOFk$mpiJC5^~XK5AfFZ`+Qcfi+b zKyM`h_=S;?%+Si4e|OFn)6Ge9Zvf{pDCvq9i0B6Ye&+(s{@Td4cw87iU&}AlYy}>cw)egsepcUnNS9uz6@6Y zLx$Ix?5qtRS#a-)e+*G9AiC$Emvw-a@mn_2-(?t%1rbor z%Mb6>2WRi5dd4@;k2b7PBM!%A=H}W8K*bxsFqC9ia%=dyy$D2qt_9dis7+OtolRRu zf%gF%A%RMTZE??$b=EE;dL7au?(PntG0!~Q?;!eo!IFb!gPz?Q9L!%BB@lDd2-tC* zprGK6kJ&zFEM_!bwd*@6+mHy8w;p;i14iJBK|%C@S7*VAPHdX3ueOf?rwbU^LnlOK z*ra+spFm!m=xlF&48-0(FbV-8umFEc10PTDBsql1ON^dwF+TI8E_S;Gr)6lWKna>C z>=aXZf!5$uX_VH7WFAh`Ng5oFpFFDY0~xui2-*TU=3=HNN(K#*;0?7ER}eJE+!oCY zCfPV~8mJSbcf9lt%{@-BT7Y=38!^&gV4M!JU^aA| zfgTBbpmebAfg~w6yjg#!1*{s)cQnyy#Q;y+r}>Df)&OO88ZRR&NTWGGSAp&qK0CNM znw@RAE+CQ*Skv2AsZV2VER-j@8}TR%OlHda$G4x%;2(x8JG~clqF`c~0V}kUzJX3r zoSnkW$jjTlzQUc8q|E2ZtFxl_E}c5zgqO@P;>IgP=_;&RNRKILceGN`bxWjm+Zd5v|Zp_m;ui{k{rNI79Dxn#Uqn3V;rKBZA>%iBs z6aaGGo2{R9dYWEZO7Je~2vn?4x-B`GgR%R^kRc88$`B&~DY|KYD4UU1Qrc>>^ZrBfF#IC8Ya@B z^Z}T?VX~bB2@ZW}@tjc0VOn-Ba&@KM787sZv6F8EMIiP%tQXM-9=*)PN|-tmxZ9=g zh5X?<2BCs%0rH^s)&X^$4}0PxrNFK0ekk{uFa;Q?7+g&bv}_|u$TqHSclE_?lV=?d zw&`+;C=7a;oj3Q!O^tB!r=ABQC!IgXRw=!piU9K7)OA1xfBjo&arf^6xU;$Dq3>1~ zC6!U;P0-ZO5i{J=d1Wn zqeJ{YED7X|=Y9IwDALFSOJD5piGp2ZF7FXLJON0i;?a7XjAx=Q6JQmk9*N=uulx4j zSA*o4t0Q8Fk_hRbW)|^k*rQ48@&uWMTG>IRnsgFxq|r!M`;`x~E?NmUJ4|wab-!ks zZG@bCu3>y6T$*DRSDq3zPYk62k8z&VNwo1+%zX>CbV;3*WAh*#BMMu*2IB7%BUyvZzcZ zedNOh|4lGta=5${MdZ~Vtp7rP+6||1C8dnznUS5Ht>c{YmC0~(m4zzA(R8D>XTU>& z#8--%oXU#2rmqvj%}{mQF#wq-m=)Q_^$9rG!_AARtuK4rfn-!#3+#DZhMT>9`7hM> z@2!M+QO0uiAJmL(sy47an7&b`I;|&XcO?RXGeHu8mdJ~mM%lj3q&?>R zQ*kHGtE`S0$Sx-x)!gGk8+jJ5E&m&Uw`VQnWVi+>S1l`v04zEZQV}$Dy`FyzGT=9f*!=INVKtJnQx#|6xO@H#mUe+sY6dq{;dliO*6fgA}?Rf9AM zROk#4*aLGAyMOZ_7R*5mK}FrAJ`#u{m!)u@QaYW0%o;)-6b!t&6ck0YW`zkB*-C7zoM_$SKP^5GDoI zmOp@F!}RZG8$Ad?IjXbz>@If-775Jn8@e5#Q_pYoPXdz}pp|PWoPvmfU}4h&*!YV0 z1BQ#oD##&(@*1@GB@(8Qa;*f6`K7KW@EV_nPufw_X0c_BrjEsm0CJYd?IU16s_(}R z-pxQCqWw0aIXp%&9FOHRU6^O)>QDN{3uZ`~ka)(u{cP>#-7Cu?%zAh|jkVB0AwfDT ze+!nX=^D0z6cyJU@J6s;0*p(*$q*E^%NweU(sKaEBk@Qo6`E-oImr1OQ1jVtvbOy57pReea!xzvkJhY!2BxJ)5W zcKDRXUdxOlE2)-g@`B9F%$~F~{UGC^#=5x6moE#MoGxs@(BR+`=V~FFgyKJ;NNSa*lI8Nh5(hqRwx?Y36$&Yf^<`_elaGALEmCf~ZnIJMTSwQ5JX%eJ1{ zD4BF+kNWM2(z``^wF)_I8TV#r`u+RaHY5H1(Pnv??e8+%cjwS5yY#-uTar*_VEpWtv#+1J3X8s)IT`)HF@>g8~@$ud2rQ{K7CQscf0fs96$Km zhTR8OSyhNv{>NiExjCL;xN8-w@BW706PUI3_=YZzRcmi0r+-cVY4LmQ|I|EO_|IDU iKhYF=^^iGPCFR{y@u@xhdZ;y3Ir@j&A>!|6Z~P0XxCdtd literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/android-queue.png b/docs/audit/screenshots/android-queue.png new file mode 100644 index 0000000000000000000000000000000000000000..512a66b69b46b1f75839876ae6f974c6f261d7b7 GIT binary patch literal 82450 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/android-settings-scrolled.png b/docs/audit/screenshots/android-settings-scrolled.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b145955e980651ab8e36fc87358eaf720507f4 GIT binary patch literal 211679 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

;hhT19Ukbs0b6skgyz~L9@OV0uZUszr$ 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 uN_i(^(-R&1CJ%9y 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Ⓢ6Fy1fc}1@y4+($%nCpmV<-^#>pQorK)Z#B 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

5>x6e2U{W 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 z z5-tDJA(pC_jVn>}h-xh@wbr)YTi0)~;cao2Q^z)uFgS+1znY|28*$@f(s&NY3j-9^ zS(G$=NvJDR=qK@KBJ*$S*#9Ei#H{U#C@2rCL6rBDe}DvZr|RC|RRY3+Kp( z#kN5eV(I#{S*;MLy45n-zeq?L*O5?aOkmUtFbZj~gtRF4(&|JSJ4@M~FhVsUM0;zk z*4o-z9%+O~sq-0Z6J6*kp>Bz6oM3&EB_b5H@nZr7O^6gyJ+zdn;Hi}vGzNMV?)HMS&iMT{|{8r~v* zA{(FkMB_V>t@@y-Ln4Rr_J{7*lDwWqC z(rxfS6QAzHGYD-l2zc73g0y(Bpm936M+qQb%t}zLqpeTBzI}R)9XqbIt@i$Vo0taK z3KcYII#v_&CwbI>bQQT|^I%cd-p|Ca&-~z~dekpp*rog~gm##A%pp3aQ z#~CWyhtPJY5e#y0E=>k8UoKU~Ul=4rEq&Z1+DWUh)2KFh=YIV=T7?k3+B*jH@91c6 z?`?{0D)MAS-7>Mh-uy_K-(V8(AY^vH4f zu@A}X+OwssdC5d*3lkQoHD5+tqzUHG5OJbLsmd!3)pj1(mjtbT>+N1`eftAwZ*S|{ z-lu>6)(^LQv~}A@Ua`%Px@qCfDry%9XXaVIPT#u9a- iyZWs)>o;s968|4!-$yZ~lxzF|0000j7!@9 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-focus-rail.png b/docs/audit/screenshots/windows-focus-rail.png new file mode 100644 index 0000000000000000000000000000000000000000..c858442226994cb34f6c74e807ab3e9a7ae83ff1 GIT binary patch literal 90099 zcmd42WmH>V^eq~sP}~a?Xpt6ocZw7*6e$|q-Q9|NaJLpIrC2HM#VMBJ?xZ1v;I1$H z?!8~$c<=wdKE^m>u#+6w`>efW&beYgswv=Mzr+Rr0C-A@a+&}DN+|$<+WQ<8`N=B> z?iK(F0H7o%t?j$C-|3fc^~vw>Uff|}I!C=Ax80x9`XxFM5iuG6Rs=C^s}K*chfQ~D zfWI@%`}plUxsrP}tyS)v3QRiauVtNdmeBehYmDaKA_45Be8! zvO=EIon150V3FJXdaz^w;uLOU0PaoM%rF(~W{P(Ow{KC8)Q^t|9I}KWMPV03} z-p+Hz*zp4f-kIgUXLXJ4lZqaDC;gnc+K-AA=3IOiBgqk`vxZ&g1<27)23wT8FF&bq znF?IDo7RRIl~B%^V%~e@S)TEk4>e2g1clN=j}6?N;?|JO|GBif+av zeXcGz)?1HDgqD{3%m)q@Hn)rJ`f*HL4;tq?toov&Ujw@zOw)^18a4f1W-dMSTUE#% znALIwjlNR$=MKEhJY)~LIlS#hK1uUmo%>I?%LE5+73&)Ze1TRFB3+Xynb zOz;6>-ut`35%;0`NQ*7ZCs=d6*X=rka0OjI`uV$bLkmqfmuyw=cmOS1zed}?t@Q7p zQv-V~eQkXwf1!Pr>N-mz?~5c!BZgbiLxA#8^syz3yKxUDMrzxl(c9b}jAk1Qnkgq)c+sebq4;8=jf!d`$Rl_}PP+}qn zqo%(~S?jgmPad&&viA3{u4d5)?)Ff`0AQ@PTtjx!^_wggqcfY@$KU5BS3_LvgCy~h z=B=6&W2o|9256RPhhbU1{QK5a- zCd9=fcx@W}9=VPOZ3jF3a+RxV>pYjB#U5!Ji}=W`+qKiRcoR1_()X{sju|rSA(<{g zP#3A=<|p%ZzWROsy6qtZ8KcT^9&~kPG@_tt8 zMaKY$O91*wo7L;0oBeWvkNZtNW6nu5_{oVuFco9}V>ZrU-@d*>-+8gojFVB$4qH#p zhGee0vk9>|sk6W9LI3JkclHg}ZZg3Swcs6`$fvv7NIfnV2ekXo?i~zqNIbmaX)k-S z#LG%SYnwWbLdW>>zCLrr@Y;$yoTJfz3=kYV1irY4?+zOEaem0k%VLEgclXhFUiX8I zZr3JOo#8XUxj){;>-yWEI;!>CPgM2wdZPzd=ANFO1g|e>{id>4L(!b1I!{5fl{!9n zH4<@g?Q|VAuOK*)?FU_z-L>6@PV-*T?Xw)KTQ>i#^Bun3a&i3%F&Q8!j^lTH}h)8P%k zFRXceS$R$%nRqFQywC;->ZooN;PdH3fJXCo;WRa=E;|dxf`d#>pL)X8N2$BvC^pXa zyDeQHuv$CQnu+~|!=gTZKilK3IpFFV91`qHkT(i3tEFF)_&3;f-`3m-`yqs&1H~sD zwm&{N)cUEAzDIhd@~nf?$dJ3kZg_na~>OJo&|NrwS@@ zco1+{_aWygtf+@N%T{6&!^aR(Nj@ghz-c`dJzv?(~BKfH$vbwhI9%T|K!nv1TMYpls|29ko#EM`a2d}0hb z?a#$(0s^Jc401t60GdO8Ch=7whje&Q9KbK<_$AGKnePO>}8-uaFQH z6wKrzMNZ9L>>Dy{X9h8^B8~ZPK_1!rN#ujyt_SW6J|1^n?oalTWU7AG^O>W(Z76(N z3a+3{6~Iwub5~h=-@Nn9(t6N?M-4m}hGWvUKQ+qfH||iveA6rSu;x!bAXB%z)2Ug_ zp6f-PA0pkTslUYd5NaZk%tgxCe#Yxttf1mEs%ZzmS)DgN%{2e&%RFBScX(|n%Njq> zR(C|LU%5ZS9Jh8d*DT%=eBXpHl)CMf^gud&Pe|=D>8TQoBf~i4`nAvf$bc+jb4~KG zs(wB2JP$a3zxTleF|zxLWG3^b>G3p*fI|S@w&DgYKt4tfoU_%Er~bGC9C(9_aK1=? zYcSLAj5Fm?7&4&`4p`H2w{Bm|IEYw3*jZJFcl8s-sw_{AMOeZDY0qUJ zWXsFThr;S4bRJug#y%0$gVS}6aOp|y-6mMSN-5J{twB8~_#UMBD%i4bcX!vEE#gmX zta{MJbdw$!)q7R1-MMPO9OcQo{O^qG|Gyd73AMt4itE^EFL}pN6hW}sl+6<|=U>c>B+Yr2XQ0>er@~$-|Z|{@q1w;Q45C@S_gk>J}UvjL2>A5~8tskv#t%wz&QA^>rS>dcb4n>X1|$ zVklk#zPJ70>7+4`S@@Xbe0!|vbvx-K)x_Xj=UfGWx!w{u2h6^$y&GN+yow3D`Nx4w zDF3jLH!eJ7kr0-j-s4LW>|bmaX_xwL0uTVP*h0DW@y-bXTbS-c*NqweSe`9 zaYcC>?rA~r`_;+WKOv)21)+$X(409+USgv-i%{?xgG&I^>uDlcT?d*Al@SO(8_B~@ zSsm^n@4cfZYGRF^76dGI>bKrqELL0p$^Ge~8{CC>v0k9A(IFQ4m$crGWk>qnM3?+ZCU{4?^oA1YSB z0>29@uKYT0?16Yje%DiEa&4osx}aj>1It_Y9Pde=SwxR~$|Wev;n9*6*^(ZfZ{0%{ zPArf$1I|7VCLG|rUtHGIJmeqaIo^!cUbiaJajQaY_~h_!t=%;3%M2Emd6yWd0su)~ zE{$RL{rj0W83E`s&i4=1@w{zd$9)uWodtEOFbPTX3LOLFc^kgY=&sDK;IHf(6~^!{ zro(qk{mZBmhT1M!5Jbq`gmn7=z{UK!or~`A@9V$iL+>7cO9oAKNG`Zk@^4+Iufch~EIOzO6QxOi3ma})df^@Snhv-65W zD4*FLuHw=UL!fhq;$p8Q_*;I=F)v?}DNH)CLPo&`P3E-qRYIemic_{`F9#Pwyex8>&nO}D&}OHw4*TsBp`k1qhBc{FtlasPBx5tR zK{@pe4LZv@(HGt>)%L1vJT(ck^W05UQHbo{?VYUH6+(iWzkdLt?-F=Gswnp8asXQM z7&*%Zvlu|KsV%cLR>=Omg>qiV)t=O<&$_=@t^#)9=syDY`L)6xoAIgu$UtrIwh3@R z#AJn6)V~*5pB{D|7TOHu2*@`tC5Eqb*EVAgm3EO7&>OJ=rkrFSmcZMcMWN6*>AEZ>^45(o z1~f~I6jPsNEC4#MC9c^eODKJ!9DZ83L?>FOL~Sr6K9cL8J0zTDy2N0gVw+7t&ELD& ztG456R`>3hEWqXP5FRpj#+flPkyRc$9JiVRiGWDdcANUqL99{d-AXr9UDI)=Lg%%H zisJhn`e%#B=%9nD3NU9V4lG@v2hvB(Ml9daqonU1v4fv zr#3fkK~Puxw&V*P-18a(NkT=%UPkvm@vPFyNQa2ZWD<*Eq7(q$HfjnQy=>GlArSy2 znMV!%`DZy&wr{wpGBZdwY)Ln8-|gQIVyAAzigRo`+Gk!BTfe9YVl~Q|RyVx-lXPF} z$au?6;j`%3v-VmcKdY#np6qJM3(!hOYuW3j1p`*hfFtJ*-T-|QMgw`IxP>W7>kEtA z^0hZ?G>u2HoR{3tbltIl?wg9Fs4b+%zayARlg40j$NP6HfmWd^DWlLZRn|N(vJ&}C za7TM|myYYc0(RpXU;T^~n?Q#eO2-Y5dpAt6O-)IR#G&Xd61>WiKHK$qsw%BUKz{O& z3ysd-4LBfvzM9QkHGRY$Ixc)xCU)Q8g}KJ`ToWAfaEh!8x^^iG|Bi^%&i$*l@Ua8nJQPEz>YU6y6t1al@|sUzW#5cJ}*SDl-Za2UmJ~wP);{ z*F@VL>?c56)R9=&69arS)uYzG4uj_dGV!>?vI|rsI)xsck3a1k8N}1<^d}-e zXi+P5%eIZNaI-8a?F-jXmD(r1hzr|*MJkKM>IoVpC`Oik?=u`GNyA>|07y;)wn?#r z%33sam4>`B;8$HmpRoA%5WuG7aqHOcI+beb>V(`cN`KwUwyI(z+M#_M^JL<*#wjeC z1P&%wHXCWZWkTFIf1_c9*jKOaMVMK>Ypt;yj!|S%q8^YKC?=%e_e9^m@1&Hb;ho*2 zv$6J1Rhfqdmr44KV3h?p6>se}>}yJYONIx@XB>ow1l_-T-00~Z@LKf%i}*}0e2YBk zBiOr))O^5#~rA?#Q zF^`SMMALKXj-vGOY0iN8{Zt&x}tVUBGPxIilukJ^`jqYH}Z4%HR3$- zA-30la(aLA78X(NnlyR)UN6z66%`in8Jv@zlotfv#B=%Dnb^7dnqId}7m~NwkugCc zBMtmsHDXieTm(fu$H+yr&}gK)axE8)5O@(Y$#j3109H@qHk!%UrTr;2nqL$b6cmui zQ7$9$C5Hbbc^msmzwXz3UT9VOhu&Vs)Hnp^_Z6t1T@>M6 z(JWOkp{hEbkmO<%wDm_5L-Q)AQ+7aR&EuXKHum9=l<@L}3RLp3!!!9760)*9-|c8? zDh%4rsi+7DxsD$SIdvfM;!R~5-viaHizeLP2vG$n-v)qe#@7c*`&JlfX?6SE zHHUdH=I~$gDY)Q8cB4yHWZ0U?{w zf@5Q2yo{O^+I8jGqu->5?j>5u(8@mNeAjT&Wy@Hk{Nrlr>$?go7t>@dYh~#Codq%t z17z@;r8i7bUN%gt1DmQ|e=dGwmOw-V&G#_ggH!2ub$n#6G43?LZeEP}k@4+ysaAz* zG4eLOGdtqYEefiNEF<4Z2DlLLF%({OYR*)4t4ccEc^K01_&38@<8bY|$%p15Es(LR z1+q~wzvou}wqa!F_T@}YXT3;4HX4{;rN%9ndcc8xBf<;>))egclKUp zHN49ShCEuPs#exb`jtCVp_Zj-u24|5R$3Y^H>8X*t!CT0Uc}-#fa=`Z>T8@T_h2~f zz^A;(dNZ3$>hb9sTur1|m(;U7e$OaBxIp6N?BhCZNXYv&XNEWu=?ZqgO?rYDI!*S1 zOTur+F^;*pxB{-rvby&&YDGGR#E}u@FmSoO%YXW@Mrbb@o;|$Z)~1je9o*PuTw{jX z8pxS9Zaob%s2g-gzUs)gh~pYI?ghHI)G#d@ zIx$zz{P@Hc6@~F5@!vm$7@z)OO?xnpL>;2^Ybw7+Z>-9JKS=ud6s6@|&p90HIDJ}8 zuvC0rUywh)pN1ue;cW`2uSKI4${Xoji71~cVahj6U+eJWlNA)<;Smt=nmYxr2}*W3 z!3Ax{IJtU%|4QXmYNZx1IG&l2aWTtgEJU=W!KGa9$+CXTw zw*jlHCprLg!3>G_Q{OF0&W7K?$U;Q<#RJjj5+%6TThGPfNsJyxsn)Kxqyqm;OU@vR zJE6dgp8gkZ(K zGK0`7osLmi;@QU~3svlYUj92GSm!O z51f`l`<2(tZpsy%c_kqow2AzGAPm)XmXNVAtRLAL2I)H=63|73Ffasmz6i z`L2Zjyg{q$*)D?11=hdJ&zA=8WZ?c1=cJ0c+!nJloY!v#IueK zY#GYbE;XOv$~jKUO`Pe_%Ep(JTD70pGTcK<*83+43@VTSF`i|3sifDX#HFBUJuE%# z1AOt%;L*m2w{Ld55Leq#uYDPBmsf`#bD`g04ie<8j1FRVzS~X2^p4{aehiC#z395J zdSTPTA%OKCV2%9h3G)o-K1PD@Hb_XiXejW1;e{^iCk04OLeV_yO$r=iXfugJY5#|X zLTWnL8zl8I^M-BqPnBxw;Mv@wlX4~PbN34E3hlUUUo-zo)41D$ffg zN#2>f6Ay!7RaPL+zVsA3cnl8@AHz=HWlk6O9DfJ6-jMx=f^J#33>B9pG zN*kHLX^!WD-9T>KfVqiD_aUYRDHxn(hycAt4@V1+8v_-H1%Z)J-^=s1cR-Q0AI6me zRCx15QKmIh35fwCc3e|R!a{~db^Zf;pP25<`)c|EzE1c(h&&M`0N;DK2>}3U6Z3pR z%$P?um(an3O-U|+6(p|`_!Y@XAqgUKlb|2v+U%rU{|CDa-u$?_z>QxNRCn8(^|0A< z-fhqZaWHu(x4EY76>f<0Kv%-lW8Laq$qbyMdG%@w2uP;e%J;GPf}OK>sN^wII2y|a zv-0yWI1w{;sl(gHem2u!HoPlm(i52s0ypuD6< z@(I7FXdAPAz|b%w6Qkt$qB_^A`(8zP7ZSx^MPix%ab(TiNJPBRhZ^A^6y!AN3ODe3 z^oG)4S`Z&3h4aAi4fcC=IJLx)o65|V={>bl>0cNv9iD8^B9OLho7Up<^UtxGaOlNf36Ck1)y2JV;0E@qmTula)X#kE!`;SzML5W zXwmXTy4Z+Pi10w{aH>7BFqGt?19DYV=-p52Yvg{B`H#3*J2!j1c679*VmR2$F7O38 zdjrG;$#ikp*Uil`#@Q)^1}S2p&LX5}!M^!2XE!^yaLwWt$+axm+%W2Q+I#8N9=1ZW zFuBDQ6ch-Q_m>L(9ba3BId@-apvtBx#XAZX9UJw;@`d9PQqs|re2zhuOmd}(7#j)k zkp_@&wLuos+lIWsf?3BB2g=bc z0)m(qgIOeHvifHU9?f9oS=M|f*+p7KAozB@edhDcjEz($v-}fp4G!Gn3&_)6MIZ^# zmVNchJOU&8ONlba{ml;#-q$9tA9tq8Z^s-HKp=Sy&yVKwBF1?6pvHaB&xPaPJ~1Aa zQEn)!oXU#mmV|&%j|pL+C54kR!UDPVV;8A_{knBaO}pRt(4A|FD^Bv7p>&+3EH&Z* ztu!qhNSm~cc}>L!V!mnR{=uQ4Ql36pS!Bqt48TZ6;W2Bm{8G0(M@aM>g$U*OFa_TC zMjhaD@MVK?!&Ho-TsxTPUD}i?36E?(0L3%EztNgO=Z}X!5Pu*M5eGxjc1Mz6mGuFJ zSphZ{Po!u-Df`9TZar8O{_Qa+4c>p@CA+2QA=u)rHe%U(uTVaB+*~$N|*`iES$#q+$(A{s4K_QvpzJtlVi?DZ5vhgRk zR1$N8*|40bi7ov5liKsq3Nnp2{iw<7g;SC2VXOb7NSn{0EkeD=};MDW6+<+ zC;|p4W|Xlx%h2i3X_u=1$dyWy*zSb!zr<5!LK1oQ_Pvx*?g|q*Eci-t)%^w*}l%^4%phsC&@e$8tx2))M}dc zLaqhBE9T*5K$?9V;5v(t1=lBlW&P>7_sX|)T#b2c@h*qdxcD@E?LYlk8&?<8X+elfUB*nZhmpkF9uskc5+gSq}{(>Mh^UsK2G5U z>JK3{9cK{x2qCJCJdx*oozmYgabM?Rzd@-obcT*K2gE793dplN?|GMP0KWcZMoHmA z(27uNqNrN|EjMiPwfuFch^dCWC)oLO&V2TB%~+MoJG6QFG!JSbBO{gl%!feUPHO`{ zg@q$3Ak6iE7)A8ew$Ylj5ej!xEDc-$`WJqdGJrIeO_x|KSFhdCtJ(5Zszd`y%v+08MT=jF@Wg_Gv7KbL++> zTmI!7Re5*?bj$ULNWUomaLdMe;2hm2T6Q_o-Ex8?PFIjoC5sI*fQ!2?r7OlSes>fV zjbyiqdOhnRM^sJh7LQF=i2ll04cdzj%<5LY(@J-dC z7Toe}djCEeD5UsI5>1AaMuGPuF$oJL_5ru*b>U%aC_~KT9+_;V?(Oz6ll6-qU*Sxu z{Yvrt8F7&*z>g<8A9=vVI>5Y340?VHN;(@wKvYcTE{%mE2xaZy4Mdp(x5T?0f&DeE z6(|b1Rx4JmUQkr9-~42>AczeI7rh!;Sr|ZIazkDub!UHBU}^vy?1FcNeB^7R{4# z0_0W}6)(U7ViA)Vc^c*X`4+j8`@OrCY3_{=t4S(O+qAP!@eel7`j>)quO`@4 z$~|PzRlk*P(5oL%SZ@ciFa_)blv*B9};g zg#-UG+WkG7PR&}A#SL?7?`>th7|_GwazV1o%faV%cd0R;lPeus&|vk@N6b#oF2$bKFwFU$4$W&Gp^gSY!(LsNo)YscVB7ZRfoI z&{Q5q3LwQ97!V-{F!bmwo0_6&yDdUWkIIU%Fg3z1pY$$;#`9@L)7wlnlBarJ*0Hwp zXDy#{O3*EfjU6UF+26k{YF*Sx;5(i5W^$YxVZw#{V$r4Av!$3gYglrtHptS%2!*TA z(QLLcQ}3kOeUQQCjHE&j7R5=RLrTo-#wmelFXeK z`M$id>&thZ#iA!Byzjz^n;8ctClh}Jd`|x5Vrm*Vy3i{lGHE@mp20>o??t(-DcTBD zb6B+%Oo{@mNX9E(G}GYIQQ_SFIC=K@vJ={Qi_?~f`~!g=?m$I|`Vp5v_*Ksi2${n$ zF)_X<|0ZEor?O?cJTaupA$6U7=jF6~?MuA;=TQMC>We`&zgRV0`L1uPdn?SZ0v20< z-``0&wEcH4B6|;0NQlqm#UN>%->VlvIfSU#_|z6tfQYcKq`7rXg852Ar$JKV_mHn z4{sB`!dr0?bE$3-Kgo`?=|0(d<@Rn)r9td-+`PqYEWna*b^ub*fRw4+U40AUBE0(7 z3_R_+?C=@i69{k&xk|yqEJSpR?Rd@3t`c{22QG(1%ff8t9cR7O9A8ly2PE7#Apdi2 zvez*O(bw^5S993LQA;V}l7k53)e#H77!R#!P-m60wU{|7qez*4bk_Myp7&B=LoJl24h_JmR!bv=)OWUaN#~4G08qml zv{zoN>iKRxS`O20&Ww$P6G%2VTJG$mspT4Ge?lsE5aKUza~?v2t39iYRmwCqs3Gq9 zbp1S;i9xqsE@D?N)QzrhZ-lxZqND=)p426zh`tWtY*jc)`T@;+CkiY_U<`$(#bXn~hUaFcBUZI7f zNk|MFa~KvgvuF5=&m${hsf6){BH~-z!Jf49{gtBN`<;u|h?EiG;f|jF^hQXwUaAFt z(B5?x$>nA9Iq1Zq=&JkiB7~r9-+`_2|meKF*#fh_uGCj_TQN_;kx)}*J!xjjc5u_`GL$}9c+Dl zeO8>A8$_qfC4+-~Bbwyy}zJX1Gdc2OlXm}dc#WgnHy;PjZZb)%xM5 zea^XR103o;1|my)DRF-BHg6{(jR4cGkY%Uam4{Yv$U*J;?R>~>Z1<`S+1l4Z{8Ztk zw(aJD!1cese?T*1739*U4V^OnXs(_7bHK#F5G`=s{+6f^zJ^7oF6lMn^*zMZFZtvj zv=X6XasAh{u35b~4@(FHFV$RISy83q!<935D;kRe93(<_AEdO2NqruROGreKmP}s~ zS}A8&jTg#T-JnLCp=^U{!W{}CCpyJZ~>HQwA-3LGuU*; zz~fRk!wgEr5ez3es^!x;xw$VX^$}&%6RmV<-}^5+)XHh1hFr83kQmJ}f%9WlZAeg3 zVs!BUQsy!E-sBeW>`ye)M}wM)xtEYanMV)vxMxJ;6Nd)h#}-D+7CbauFQpD11|%-; zPC8DFJ+)&Bwn0?}X`}vSYbcCz)oow4etx7dm6026g`VT$YA>I|U^!{?pf7ajGW75I z-lAdIqBBI%D)Q|KexUoH41a?GDB-uOZUm(XYvg_`)sl?-z(8uD$sJn*&}6lDx5)NH zAxb9U32$E(N1;7ASZq*TqgOX~d4HXg zv%Qigoc^sp+Ea{1FiEy@@jCYU#8c3Sc_$!AZK!GS$EP12=hg!g0jo?Qm)G55KPHfC zf}vMYyY9Bi9LEOHFNnzTR3_454v3Nu3w%hyd`*zCnO`E!bre(1Y`#mcgf=MM7eoA_ zL|R_ifsCp;g*&$7P24aA?O!nTCp$|Y#lM0>FMb!`!lX`tP9DaIl>Ky!yiVMzhE)4pfP9C$5xCFis z^DQ=c*C=UH4ffy+3M0N=^=aD=d_V)Zs&1&w(eZ?A(X_y*Gl& zZ_O6=8^p$Sh~?k)i(pRRNf&!HcD$n%mwLPUj>Ok^!#~u#qQkT2^fNK{n5S4Yy{rs9 zJ&F62oc1u3n(M=FmChiyg+HZyH9L_q(kxz=t3K*#YMdrr9m%6^{q~Jx2>Y#+{DHBBIV4OP#L2!bbJ@ruK%NrK2}b{Yc8f_yYv>7%B-Y zjFDqaE+oar#P1J{N#IeRDX^6%f}#I$3o61vQT-OCT0Z-tH-%baKCd9Jpr8N`wY#=f zC<{zkJ#y*++VFNwqCsl^@e7RFz1JQ(4b`Qb5GNUxRO32+UHK7{D~{LwUTgsvI$sr` z@kepG9mVCf1cbObKUbeat+z4{zO!DwCluB!6=*O_)T@ZVb(1T>MT50fyaDxP6K0^$ z%RaY#{;5he{Y|VlTHM_i;p7w;wGZ_MH3coP&2I`ilw^#wcf^cJ-`~v|x+O=_8qvP9 z!X*-!vTGEplLuecvu1(GHKqSLH~u(9$|Vz+>Y`SM5)so9QGQT*E~@FK!0?HU==e9D zy9Tv`Q^MCbpbud=GA5)0Ah_ie3(LS=Z(#fM32+|22HCj*@uAHIvJOM*6HX)DTNiCD z-wN(k`&T=~Fk#S4Bu++X*UrxNip!^{nSWgBuT%OyT@g(Y{X>IONVI@EHiM@>dnOm) zw^5EN^|q`pn^*a5U2KUS+cZ8y;xM%kE=hGF{N^P$$bu1&{Fht)_h&^W`S+&u7*T}O z3d$_$Q#cS_`spPKn#;3ucLm}ULh-Co_X+ZU&`;E2noIw!9($|U+f!7gJaCEHldP)D@|<*L-jO(fG4ZLrF+a@4K)W(=&VqUD!8eTDpW(d1@j4w`LUY-EcogP`uU1 zw;e3?q)ungzz1Tc3iB@Y$10nb0dO_azYE8HAcg(>`i|BD!1?vv;PV`mzoi29v~P`K z$Jnm)xiV^J^JXJY-nmE*6aYDm*v~1_ks-ZsC~kn*R)DV&O;Ks6tq!UD%6#jJ-%GL> zXsl3hbCj`I9s@P?^Ka9v9%PJ7h)YDZG+@i0s|4dyDa5` zI<8SWxTRoipkhheP0?-RQ$8y-OdS08fr==U z=Z%H;2h}Ri`ob(K>X%#j+Ea^7Ud#LYcR$D&>`&8afXJSs(bV>|I#ohn&50}}C2; zL|^I7@Lz!JK+J#=6MkOz_4(CBwMFQmZy_I&nxTve{vphpx(T$c_D1CT+TQo&+|)E$4td==Ao^Um$3W=>IIo4r(FFSJ$X)HL79W3q|1Y)ae=L8sRy{3qW=WXXLB}>o_JG}c*R`}DPiXvL#h@bn z)66h=oKpF9NJyYz`fjB1r_V5se-4oA!@H1mRbr13SGA_)ah>nfYSbC>R&8H}67x|| zh_L8rU{|5b_D#zOL6ms&Y5@v*^uboZD|Z%@KLG9_I)J9zj9uh-+f)>#EGvd3#%B+@ zNZDcBHkv`kCUpS^j{)FIRqaBq+Zu*D)7vHvzO?!pHu4cZoKwCW)gR?dhnU9Y({-2G zNH1npVO74=7->(+npTR&1v%BJ_K@d}XP!%4wtfUd#OH>n+ ziz?7z+mnj`pvx!^xf$)eq=xXu&X|mdftKy&Xubu+QF5gj>e+IQsl9hYFOAbj_IfZu zL~uN&N!q;^dL%&o2lYh{`$*~^*>-a*(X{S!83Zj1siC1z(cRC+GD4BeQVjzwv+gPK z%YV_7AKEq497^3@ zH#*EA#lCqyANKu`Jx|EVl-0JMb=@A^E_OdU!UlfmRB{C!t7JK&e-63d?EZIpUG5oJ znLPx^C(;ZnJ6Dlmyx|dvGwLH^f|S(MRTpI zPbBxWy+8@GId$OBTRC284FDZ|e1>zQY>z&Ycsp%WO=dhJZPB1W$$2vuMU0+M95d`& zr~snlmsT#D5(yV~Ea8@xOdEj)az>&_EB|@}YUz_O0eq~S^lniu$3Ml5`#&OO=>uSe z&coe^l;KSY+YU~=y31paQ}g4|1y{&18>Zy2#O12Twt|#cMwqT*0uApy@nvFGSFx-};h(!^0W)ak|MVfD`*VPPg0qkYNS+l93|!xlSk9Q66o7 z)O@=VEIuJ!#!bOZL6KeJCSGv`Q4>+}?j-QYwyoNE ziGGFqN^g)@Fw)C*+;XAB z6Wz*^M=1VeGfjt{33IE_Cx`Bgv<%1cV3+*$`Ps}=pymhehul0V+t+RngEWx^0c_D? z8!2&LznFj{1#octmH#aukFWJ^UVjK*?z)0-NzQ65m1p=QFL@rZODw-Pz6v8>JL)0e z`1I+R-LTbR{%&o__B!yPtNqZh4Pv-{C8bjI&_~{V#AVX$hg9J|U?QgGjoO9=gGS0A zt*{|hg}v;CDTC<)0Ykn}aE@AW1j<#YO#(=p_&M0)PYQd+Y3?{aK$aHJC;Uwu#=Y0T z&_kJ`ycMDPM%b-Kg6loAv^iUq&WLwFYxhsq1*qi88RWF&7OB?d9c+yIPSKbFl>AeXRplr2HY zuVgNE`^BD^LmsMnLwj+q6C~brh#FSaqoKntjcjHCH&c-)uUP%Z z8vYXI*lmiQ1W-+GVWFCzv80J7Fl4!j2B8yBDzv^14ebfEJO7qwnA@mE>@b*9bfH^I z8OyTN;6^1o=lovg_ur4T=`9~?6p0`wej7bkAQp=l4=^6Kge+TqD?O^~1ZlWEx?35I zUE#>tMa>aaL4;ehhrQgn`3MIdgb_MArb1*P?-2VtvXYd6k~vdzm%cAQ`uti6E9x)D z*~P3uomtXrJ_}FyrAz1eZL=f^PrC&-RltoMJlOA$3qi2_OXxcA0;yrj~7wkIy0Z=@usE5gq?ItZd{E+^&r>XXmNSjW9m;y z3VuKw+G+jyc-|0Yi8)V_sz{Aq{Y@$D@P~<+Cg-9ZO@Pl-&fOA;`X92}C4?X$Vb1r} z1(D8r${v<`w#bv>7CIWPJS=ZVB#@N{hrwMO)(QOodfDUPVS0^t0ak$DNFA7_8my*W z)b$0bh|_laaqc{8Z01+IISW&2n1lk4WHBl0!^tNWqI9AZXRaaAYUTcE**%X<$ zz_l6Ez-0l-Z!PFK%TU^Gv$|K>g5*=uCI~1P3uwoIkCQ_~q8dAG4<+3XUepSxupJV4 z%;kSw(L$0o3l=nAIejU*w(P~lY8kU@2P~WKf^>3_z zM~5DXJ$7lOfZ8~_D_zo$>{X->${L((ldd@^3<-u5aU?E!70iWSsu%Hl{8BeF8bQ%~ zt3LZdk~ede>+l{T_PAGolpVPs>Yex96f2s`7j%IopDJb+>nt!o2j4X(;p1fv3f?yv zlF<3XRYz4ktLR?20}douok6 zq6`oQ^@|S(i|$qNE;1f6bQZaPErn;OX!Mf{QVql+Do4klIAK%VUrU-0`R|i%;T_VL zf2##vb_Y9-{*5EK?I;`yme8plgZ*6l!I|&A1kS>{_=xgvlvYTOpLTna)+Qke2Qp*qSGf`I7_&>{J&p ziDS|rwT#qZ30<_%=i!xF!Wv8}`G>#DeDy&reYy|oEHChPCoE0qX>{%&MPS*pjGKf4R-JnRoj4KUn{rjaB@}Y)zKGBJYzw2Hc*ZPb|p`c2KYy@k*#9W zWx%1q>RloFjCoX)Dfi*wi8^9g<8tQ)?QPuR3rz3cR_B6^l3+Kzfpm}^no0Zqph#S0 zpvVGLk=u;{a%x?lc5YSP_3q{EEk;AAds*gjKI{*r)H+;P^0!9k%C6?9!}0M{wvmu< zi(ah{LSVk@LLdu>Og9L&MLLe2aqUYABO0cQ_<4N+d1oCSV8c6XWaBe+C-=nj&oNuf zf=dm#)j2R2QfuPu%~=2nxn0QQc2uI%s`#Q=u-@vS`!$>A<*T5x<^mAx^{$~W1RsnICBVsPL4!@hxF2QI$9cmK-W3QFKY zR`*>JV1v!%{-lRg6b;x+HS*gA(ZELp^Ta5xNZ5OasB(0)~AiYY&Oq*#7X?2EO-W-Y|jZRebwK{qE zHjFm^44n3`;tIS;72MhvZD$>-4XlFwbvgB%A_zexi3bq~FPr?exb$>hXL9}Wm+v_? z{baT*y6?Rj7xh}rTWGwsNi%P5@`&h324rexOtAG%@@_{pj|yeFmL>-RgGVzFM`KLP zZFP?l+8d_Cq+tBcvNbe4duTzx+Eaps3`#+#c{QyUxei7067^md9N@P=WDVOrvpkxZ zHR}Aw%6(B)FiojUv*P;t**wu3x%S!I{Osqvy{AER`EQ~Ezm~6M7v$)F7hr=HHaol9 zUv#w}v~Cb^%566pa-jTQl$~W*l;QWF2N-(98A66qh7PHrOS(G*MNm4VyGt7BZfT@J z8YGnN?vzGKKtOt5e*gXNwYy*T+7ELPU*LJ?o%cECIp@BQYNcjLUCBO1rZPR&gd_wi zkU2NXE`voBl%+q^^+}V?PR9UMxg>FyVzNepnwoj0Vp{$N?`WYBB{iO9JJRpUqZ?Pf z3mt2(ip%xW)%?|yXq%V3i@tv_ceeFXQqxF(vsruHp2#!%tl+Z#JBfaHl2vWU>-JlN z6pvO61yr!IQZTa)@Ni1A=1<7QMOd!@f$Qk29dt_- zK6fvxTYpTS*Do(>^GbF+fOQ^pjIDj65Zs}V$zpH*2($v4y6g-jGAjrdwD{OR)E^28 zeR%nSW3AbTP&)LbT*8DjSs{LT;xkMENyACnG=%GW-uP1QiQbOf-6rnBEXI|1CJ8@omUePrYz#Ha-3cfhL1 zS8XZ7`O)*O$aMNDPmQbym95(gAz5;g(&^u?JTc#78F2{G=_qlxkFjc}M-g`g2YwlN=JB2KJbm?68dN#@8cysd zF5ga2547!ad^2<|_N}UH_x127xt%LaEY;5cRuHx~Andxl7^W#;CoHmso~p%}_NDYG z-e2Z|PCmI>O|`DZ&_n>*N&%9H`!;;|WU+RMO-p<-DCV>e2z!Te>YwQus^}kfEXEcLufglZD&CGMLGg{aX%;y}T3^ z3QizTvo8P``$@d5%6)KqwrxAkTc8}%HrBc3g(t6M)8)NqOKP~f?Qzaud3T$}YTJJR zjg+so*zR?=ZIgQeB(Z0+(XR{>*Wsd$#}yx5eYc#Y*_jhzXXma{typm#A7s;UUN4p| zrcv~9JVq02urfg&V)?r45B*gvP=zr5=ooc>f3~SHTmH7i<7}?J#kVO(y;u%$8q_vz zsghJ7$Sugzp!&AjL8%4Cs1!C~jNj}0^XuXD9)+N5?PB>j5cTD`7}*T$x=pWP?T!px z3|r1tSie+MfAd7BeJ>fp4h_!sFmrQM{&>uPRW@W*f1@(Q>|*0aO*5U zd6{CYC|~e3@A(OoRGj6|Ff>Q~rWZL6D_wCr|Iv`T@FlESidnfTd(+^8|yQas|(a6Vugljg&H)%B$)u9f&tZrZzQM<4d%eTk4}525MTb{)#TJT;N4n&o^Jq zPMf+9!00kv>LYAPSHIE54~HBM%v49d>+R{(3XFKYv;EAp=-EJxGEcjs*W^$aUc~PR z{9b#thSHiAr-|S^H;nFAoJ5{Ok$Nw`d9I|6mTEG$(77!C8;^Ff?jK}pS!Wzh)yq(K zS?kBYT=6|FWp&?rgq8uw+x{}}sjdO0=k)xqzCZFec>?Y)H}K(!O{dRa7axjhC?xX!;Wfl&&jXD zS%~sk51n*!Bl9w$s~5tn*IszkwP}ng)?6B?IdI+T9bl=Sy}jL;_VAwGWtxqT zw)N1pixcPhJ$|bjUn45uzada3&99u+omD1Yq-*1mVjL(YugW)}Fq*`?5kLGvs0uqP zQK&P%x%zXteAfHbX4|FP;g+N8=mJ~!iM@)?j{%d&Nwvze)1aa$4Slt>tlz~t)is8$ ze;t0F4yi_=K&$8U!TK~i70l>nJs`AThFsa8Fl1Frn)rm!Z1UaU@Vmb zG)$HgPo7!HuM2`8Q4PdFx04ab+Q9gE;?4F)FS^!1lu>*8YnBV;7q*M15S9;39;P<+ zx}_I*f44rn_r|Nu%^`VsIQ2@W*BK;@QYONJ0~s82S@|yE3fM8(kUcE7bmMp9?aMVL zgEMq@X>wMwl+71YkBASW9dDxU%Awg;C zJb$kjc_Dz75?OnHSqOoyt<-9{T0p7=Vu z9o@IIzf(x^cETs#R@aa(8)_dzh|zjTsIu40q1d5~rV*gLK!I3{9#y+FN`I^lj%+R| z``oZ~Nf~TL@qRcZ6Ph#`s%kJKhhv%hgIWLz4UH;ziJ<^LQ4)_B-#rliIiG0Xw2Ukh z?)2?r_o<=Eh(SbLqZ%V81#!(4!E8nN!l82Ma}97`{F@t}k5yche45OTho-}4|N6d} z3}SkO;}n&)ue4dN;2qUG9W^<-U?QjTZoRA1shhT$S3n8z^>}$n&W=Uu2Z<4*q%i~| zIbKeDmFtqkKmo!1sT-Nmk-(p$=*g6{P>R4EaZjKbfTLxjK(aZ8K$C%_p;%Zb(3bsE z5R5TVvU)~9Oco?yuU@XTKb@u=cQv1S`crq#CSWGRp5~AD>}A2RkEI_0lRhqdBEg;wtd9I z%LVai=qN;yc2L4Vc3@C}b6J9VFsN>30@gQXjw%WQ8+X9r7$AUFm9|t0w$O~YnUK<# zgFDheY5jA)S__mDwYCO{kHhA^Y7d?{E(Y~&p8}A<9hz`pc+Ny~ro5oKv8kD5jYi@X zSU~n|Z=gZb!q;K#(rBd;%;zKxogV=Pe;zZwCR2KGZ{MH~ZkUTjkjD`f*98aXOUA&k zQHoL|WU15`Vsl_Uf8Zz`#*G)c&!p$Vxe)ZIqT*oGNRXs1NnV{n1_!tkk_v`BfwNa1 zKuIWEbppDlis_@vcCmG*xY+sLS=i2Vi!?a8%>KQ#`{1+H*Wp!nF*i5m#Dc9vi&Ga) zfI6m6)om(9gKN6Koc=m)4&||)c#tg3X~UIl!zbz|g8KE)(({mV#gnq9Ud#7n&D-T= zRwn}HiT(d+Vf%k7-2jKf|LHCGzkfz`ajq`v`!n_jJC7cq-3o910?G1s`^g@UR-4{_ z!)kJBL)VeB(X05udndK+=I_7PwNX0mo-RF{+pY+4@Egbs8deK6bRV@I`#b=5;E((F z-aq)+-nd>jKb$?>wFBp|Jc9bYd)7=Q$6>@R-LK&gYL^BC2$cgw;}q)5m%byHr1@p2 zRx3kGa37ueZhksZulgm?(qzbU5A)w64=G=P7RJpS47MHS6`q&I5K(swu{<#@@pvOu z8GFHqWvit8035zw>#3Af2sl_AIB`@Z8SZ1B$biHcM4;J8^cC!P<&>`Tkf^ODL4UEe z+tdpi%bdynaGbx56%KgnyW6vqdG)=!Xjkortll7g*<#cV7?Op|W*{t(Uxa8p5d9b{LP-o|18Z-b-+2A$dccM~p)&f4 zoy&kPPGtlVl~g?anwP2-EC-_T+jZA=>!ER7wUT)jRcdv>KPqB2?wOgEcD+xw(hxF% z(s3yA{ZRPW*R@XT@YP+Vb~}Ii@Z*2I%l|7HzG(f9BN)OjF`|kjgrFM%2k2vo44#;+ zH6tI!MKW%Nufs5Xt2IvbH}hYU(J{BXSt0VReok=U48tf?p%$`mBq)pq26sAau5iGI zQ6=MpVmQ_!z|=n!FQfAeu$IrnBqe`;WY2|)(}#_xIZ6Xn=j-Pl--v=myFmV-(2bgk zs!orku;nkh7e${d_CKutX}dGgqo<>Pb+xDB^ujaiazOk00^Xv%c*O%v*87?B7ciJV z3cDm;M|P0Zq`V7kdfT z1!url1^ocSwPm)Yyt-=2#TnA<^c zq$tVdAlP5`eUS-RsD3C&{qL6aaVTKp3dbS6tTkAQ zvom3PbU~>g12?Q->6@PIscmGJI!?G31?MEyZ`mJwcHponB0(BctYMqMiuCQEim#_O zauk$~el1;rD1~9d2-{kb_H;*96GE9+-9eo%jEI}qO3lNAy$uqDrw*AoEPdGlMG;5B@Yz@H#$RO=Yf zZWtH3>MZSjCZqgjV^%l;J4SODE-Hn9>jcQQAN zzledr-QV-*1E7AZe(AFDj<=Hldxk(oXix6a_vFR*{2NM0XC&E+25~#DTaAdH?8W~6 z6NH>SaE>34olGzP;1JGXX`{2kJsPL{UvCRTFu%7EU_Q65?cFBfl+xzx*^pHqniOJy z_bR|OA|fa|f3VYtVo)lU`8&UX`s?efe{$RlflG?xJY%!u#Smmkrs`2;KoE#gQlW%1 zhfs-ds8ds$sxl<>$cA{r$<)(C^XS5mViT{Tn~+SW1Y0r~Us&oqjqidVC8pjszQA{8 zzrgQZ`)Sn(z1JjOEbWv&LSuj{66isEu_}PqYo~UC*6snU$)@hl{s+%JdLEyHjvJt6 zk?iuq>iMeG>ovEqc@z+*Y#@YuPgPu!R16b^jGO_n{_kIusRTzaf#_cC+ct*|r6S+E zKW>UrqN3sfijGtcF$k3X=0Y&YxcR(8)=#uc73eL-2gON>iTlLtN@{G(9{ph(f3G@xsJN$qMp4{Sd+D1cY=P=&frrIwgWrQWPU%Tb~b&Jsb`~ z(%|>l5y?a{xvS@^A_)56v~5WAAp5vLywB*Q;2f+cbbU}UGz-*#K(IccJSJa{+)F)_ zP-Df0gD8%QIyx#z44GCk&;RnPvMnR|*dGZoP3A=3ma`~f7oV#jVnFrM`t(%9_Ma-D zRKwlc#n}h96~G2Fw>|9n^=x<7{4(IZ&o3!Y@{3gSTYH-BqeVbH`!iX0j{E3-f7({L zX!0iG_d{Xn%F?tX$n9^n%w?8|0lz7WU~m@+3bi;T9T*lUmgXq86?7`zRGiq!o(-QQ z(b5^oeBX3Zty~n35*=aAObc%|_ang1-FuE1%Lzsf!9(Nu@WwB>;HD8qwV?tAr9VuR zOC@m(G2)at3*Opx3Br?Udmv$B+#OFor>^%RPM)n|F}H0URQoPT(KIb*~__O5bPf#fnUxr)t8&Y|fcv2E;MP;>pT{S%kc zx21Ktc=pdIn^0UmzbPBIn+lAR(MxpTQ-PjxbEbh~^n3g`jQgM#62Vz1i&OWr*Skp@|a=%ViE~7!#$|`T;B{*J{$FRiE_j}BTX?NZN%Ubow}nAz%owQm!E|} zLi=J6ps@k=o;n_ROY5O=HkT0DYSr6084*BFV80<_OTH>_AMbl7*QWZfWz@^XK19Xm zfIy7e1rP@e=;i5`CPqFijcD2{m%c05_Tb1hKO((V&=5TDYu7^>5)PoyuJ}F#7yQ#Tvo;)e~6o2}evv|trt*iE$xsx!9UlofiK7u637|u?W6Oo4``^flIF1NXY@bip1pP=Eto#%9iA%>N3Ob;Bf}!N10t^09c1^{5;Ey4Z?jTkC~^%TeE5`1j6pFB=o;9cfp&28U~%;| zX$f!i)7!{*rXQtA*AzL8al{-&Kf11KaW8AA%LWdyOM}h*ppghlDv2gNFwLR7?pceO{r(ZVxRg zLMQp!-w%kW2c@6Aw)OHF+(_rS-~8Y^6{)rI&~dlS%BXc5MF6G_lZN4w80$w^)a8Ed ztb1mRDj6oL*p=$UCj=kLX|KzuO$AeMcJkXB%i|YUp+_RwHu*XO6}vI0Wh!}08sdGt!cy2CTMR& zB4XZIss3@JtSDhUjoM%F@jITVV|Xf@b4&gvz;L6d_vy>`U;a(?KJz4f*DCmY?P~`Y z`WY4+_xOfUGL%p+NNq-fq7$P~11GN(x8iA~U z!m@t{?kNV7$>*jt-5=o?qf*92Nsz{zbTYWeaEjdaM+d){?@jRMoXxCG30Yor6MFw_ z$z8o{<;Tfu%?yxp3^Wx}6cX!C6E}7zfu7x@8iaZ&RHo%7gNZ$@tNh7J;uFKVz=&HE za}5gx=U)<3ry6WfFbD!dkQ(N5goPJt_Bh6OVPP0^AuOmmo8pz6b(kz9Euiyb;4EqJ z$xJOvKTs&ZvH2f2+ZQCsB1kltP>^8#&`=1eA(lO%z0szc@7ALc_rUQ6aG(Crrgl{t z@$Ml3ShY(tq30K&n}$MaLOVVn;J$fL%ONeW4`VdcmOAouk!<9D0HOVk%{ z`k5__-ht&0MS)Nu7=ooid_OgGXV%#{`hE~;e%6FDZ}&U(ti`aIF64*egN^!VCDAyJ z>p`j!36zF%Dfn_shfF>Em#057ZDj`3tP|4s{Q8J+GUdxxtiUk?u0x=IFanLAT@lm> z1S}SjY|FymY1ZNlvhr{&)mrKkEBQ(jWcJnUcR{xEYB?k{_RqEVD`#wCa*nhOy zKJI$}URM_F^UqfK)!t_M!`8M`iLa52;JaNYB8Ewb`p z!;IHUj=?VW3=LcIfc4dhB=KLH5PahZgsVU}Z~CFlEd*Mpo=t_w5EW(JN|r#ErjFrA zixBIe*Wt=RQO`z028gkC=TBfGt{J}bSy@=qsK^qK^j;!^ybAb-6%G9qj3&ZHWK>;J zq>q@^FrbtOKd0 zbGGuKhI#eT*X_fuG5P*9gbl;*%k91jsfyEG6-SH2bW3q@F`38(j2Y7V956Q^ETmE4 z`}IcRqWTbQID!giMAhREYaiDn6pap^Es2#H6@-l@N1~EX5yJb#oHiu@1Ixu#-w-P; zBKK?d>#-=H?65DV0ju2)cZNJg?zR{#rKV&tZGTHOtaw}Q`Wr?Zl^3rY7$KSdnMXz@ zFK>*JfiX?`vzHdz)TgLz-O>aEC7SG1=H<+jU&5Y-mkGI63Y})hK06J+9j0&%>Es6a8w0tvh$e!hI>3&PHD(k5?{c z8XhLwmz>xSMOa4pL!qMVJ>x>-7!;rwXTectTmj&WLYW?EVB+5!Y@`oLM8T8ab-_;> zoXl(tnsCy-nlL7$+TSLO0f`2Lxf6y-=0#5=S8QzY%S@KI3dD3uPd)!qF*M>{po=Hx z>O`(e#We_Rk{?y5(33Pw8Sy2n#nw}1bQU27gR>)wWcE=`ngS@!95w)Nd0tN6a-Ur;CA zbbY>{H~d$Amhx2qOGsNB{rq9*Xsg?xK6AzVU{&lyZAiqvJ-w1+4<&cXzg1z2SM zi8i;$8a3?q*H|x8kUxesy;D=kAKYM|GT&VU-)n!_{^*o8uy5t_i1&3Ts;C`cEv;tZA z`d6LeDNE;^$lg?t;qo5DxOqPeM$#*aKtycx2l2-V9b)1)!Ln)p?l?**35>Hy#iAm~ zL&?^Vi33mn#?tEu{1r>aUtWw-80K44&Q}lCp#IoE%Ka>uWJGQM>$0KVY&r<5c4jop z@&TArBHpI@h|eZnn0zW)eDn8l1cSuvY84RTiQLsZIDtA3qu<}lfK)4I%S_DpN0#2; z1siU5b9Ru6{kaTf z9`p$eHD;!H`C~yI-=KFyynIXQfH5C|G#NAwzBTb9JGr8s84-)xqxxw)Fa}PmA?B0a z&}^w5l@qG9+&AlOHswDyIm zrT775XgY3d`H8tSHXM>;cq&4eg*%0L7fW_3tjv;}2BD!{us||yrS}PEWZ=;r)@l@JD%uL^~7KYE9Rei2l~%{Pvw1v6zln;sbCa<$ugXh zj=#rc`MUEf!4=~+)^xF;Y!uLVgcG;=E`Ntztyt?>ONtOJPzs;#%-$D>10IfU(Jtwj zmG-_T!Mqs&T)n*6v)R@4%A{gY;;BgO-&!+Mvo_Ct*DpD=jKCwq#qs|0i0_q@FVH&C zQ_YeN(!csf^q8UE-JywGpFEA8VzeJ2AFw2W(R~HKij8&qnY`7JV)!zOP)vqw*2o8z zZas%T;G%AFRF{QeN@421Xtkz`3RpwV>+{3C z@E8dFCz_eWZ^Zv9lq1ytLCVN(fcz`OWIXsox$mD^4duH&8C$OfDLX*44-9cQVm|jd zFRVOLi$=Y9<7RnVRmqJaV|_Ma|frFwhYCkJqos=x*>KBq&TU8e(2mHPukgC(J zTD>(LOlzCqr$4tXapIZIIV9e>iw&M!om{GCT45C^7gv45|4rRahQ3g%*l%V&fh|=_ zO;GKZxTO!^Mr53&IAG*gbW`pKl$lUT379A^@+JtbaxO~CKx3DEb#g|O_N_h=)eE0hGbok=WtYXS*+Fm9wvL9EaUQOXj8m`n-B8v1a}Pjv!$WS6q!Ijxha{eM(>& z?(8-?Fw`Q7sbu;$tWA(sr9h8b%vpQYUHqVVP>ld)q{tY`T`X%bV4q5@o8&?o7OpFe zirBibSyM`Ob*{JNGWdxTu=M23Dycq8u57M`Ec*17PU-l-Rn{gvUzdod-j>XBP5ZLT zUT`%YP#4R=l~hz*byxyPQ{|SL`|USRiI_)(_T43Nix}rwLx%tU(}`c)wrOQeIh_>C zaIQV(7I;F(SJjoz<WL?}8m*D?tB=oxZb+}w*M`PJzu^dKnf!H>oqwmQN*hwcxv9VK)=A(s)0V4MF{4yoQN|8Y$n!7DIhGp5nrd`P zw7T?yYg&081wu>l#E@Df=NYciA|0iO+watUz=Ha-W2SmI8!6V0HI*-5khfGZY`c8j z$h@u}*uU-&`xM{FvW@MwL&aX>Sar(y^*|Gx?04-VR)oS2gbi;=^ZWQiEkj$jM>Z?4 z<5ES$dHLdSFYW9D z)3jN8qwU`=)ydlfFY0m&hWIWDrC2lrf!U2h_2JY*vghvkO(yF@j;uo%W;;fea!pC; zHbrWD6Or%ACjCq|IZ<>)xW2RUy7WQBUI%R;`s66;{@>>Y2r~S`pH8S!lKwG?ECtgKQ;YiXET?S z)BOPN#|%<@4s*8D3Qyp*E72fFOv|N3MnFy%^7D_)JSOl0Bg2)~t?1DD7I2(mj^8@U z?{05XTX6|oWvR0urEvh|D3+L%{(Q(*2w_igH9^ zQw^VUjIp9v?}WBLKlk_KMTilL;2_KtFpwlaoO}Uww0muQiOznD3CcLr45tl;Z!CkY zF5A25l(5Vr3^rj#r0U{9ti_V2KUT!K1S{5KLLKIBNs7L32=mXLR;#5e{4N*DzmdvH ztI({Zz0Tt4SpMxo&hcB|pTg+f%!_!!4RDjcKXz|Obw-~!zk z+`Mb?8dHHt_DRHVQTla*#j|fPK8jyCQ$t;lz)<`twK7ubQtdBZzpgggZ|{Tkp3Vyn z1H*ZufiQk-c|w?ESoIj=L|OPdJ+fDtug zV%N*xU7YX8bg!;f+RC(xgY6}YowR6{x?lud9vCwb6)a^soGUr9uZ{AYepoi8?NJh# z5J0HM4g2)A^CKZ~=FZiZ83ZZ{JgW^qRz3nerA&;7&$7w>O!-ZN;QjG(`}Z4jz8AfK zniYl)_b~h|vhO0ar{eo_A@*?Z5Pv~hw3)fG15a4~1Y88%}fx+H}p9^7hj#=l>vidmge{d8p`brJMg>V1Z+38M5Hn8FeU z?nQs4n23^bhPJX)%D5}3h**w4xNM)k)^)=Tt01U@2-v)rBta80X#O=z(4(Ga(%Hy+ z;AhofLZcAnf;F~c^LTlq97kT6J!&$dCs6#1V_e3dAiGaCMR65xXNd&40_CaMbGzWb zS=q+*cKrD^<`uO7Is8EjIfaUR_4i8l+237hDRxcaUOx)@;t&)1FsS#mBvr9fc3n}t zpT9W8=0uQgFm7P?YsSav8>6qTymGWkKR5w3i*~2pnij2&O&{O@*VoQU>EI``AiVU zCk|rK0I_oHruhAHtqe`uD2X{7OTgTq`Xn={U}CJqkGPJJKCPrKO6;hqI20Su62^+c z?YK<@GhdpE#qLzy`?qBrlOZvHSPW0BJBlg{SYUs_BVssoFVaRvY!hr4x zCF4F&bWo{Y(gqzpwjL@}*?V1z55hTl)W(#SCZg5YkxQ#dZi z(f%;8dRs4v0}`0S2J~C`uO1KLLHyxy2Foiy$MoV!!~9_8G~xhiJ4Mcog5&}(z>Odz z0r{yh!!+aJ9^a&*HT1e6TqyWRP}g!Mm+MU;R)^mh6!vFX;RXvI%bd@jCZ7hSJO+2u zD@SJ@UcU{GZq?j%qhO`N2<#GbED%aG&SfYyH0qN()0}ZemzTz|@4psHGCNrvF?*nH zw?E?*x!D^%YQ1AyvD@-?T{R2oIu$Hm%nad{ooanc0-|0EB`1;Sf%5O)!zAXGuK_Cq z8mJsUo+dW9sh;V46Sr8iU;E#gc$USs1XL5~B0G@C$y_b~dlZoBAi<$$$d% zSz64ZEGwHXWE$?==Kp-l8~Fy*FYYa0wR^TLl&`iEfmSZFF7>XP6^I+WZsT7Zzq$wJ zkKN=Fx9#djHT~5~+PM(vmTnT5GKScTkL%eanqT6FgY?cS7Gdaf1PW0kR0VZf13)_h zP;0VK6A8x6EG(hTmo=2#4H`0{;bWwnXlztAY6xR@k?@B=V__ClQczeRB?DK#c!9vX z!$9nJ=3k?LG{!PO5evJkR-V@WRg^~_1DQ+(?pfVc$6>k3orm&dXUHPw z2gI49Qa0G5EjJw5hEqBr8v`Kf-meMjSA2|8_BymMn)5~_|1nfGcGTTqlITd3>r&UY zo8090e`DLP{s6<1JpGm*K`qdq$Kg*MmCxsjAQYk_`jtm#j}w{{Oq`-A9!FXMo&GPb zQkHWm8eE3cZjRcHlP~XA2I2_fRgh24)*=N5tNr)?B#bT|f+IlpT_x2m1XZHT5zPLG zG0C2Tdkvj#`Cgn_)9hhgW{BF%LS_|g8;OQTAngdk>%axm3if>P&9`m)Oc{v-0fRVP<1Tzb2P_PjPU@&@@UWeEcMvROU9F}PR%%o@BUDpo&BC$6p3@vZu zX;81TDs<_MlidJ8C{MDzYnS;n?=>j{jJI{^DJG%PA>{ z?`~?c^7?m0=2$Do5&qzjzBqxbxRkwvxQdR8y}45S3}6FQvkV2%?D4VXB!m-QrC}Nq zAp51J%DBcs8gdTkY50@jiW-by3JxriJ&LUX(T-3Mw-JLge86-JBBTQ2)nKtun5#EP z|CHnBF$K9xL%fWR?QJp?-(?^Rwtio}h#QVb34fg$bvlE{JY3c)G*9WMMO~x$_e0(N zG_th)9(cVv-w1dr%txzU<7xVE)9!tEi#xh#^5zN1g?_layc}@J?lfdLZ_j&Lh-U#` z%rf0C629Pqsxez%G*!R&z9tTOJQ~u<_-<%6-~8*EjF?3?#p~gNkzvRaHubKUv*L(7 z;~#puHZss1y~K%+Ato|9z3N}NLY9k*mm#J3$2l7G zcQR{@Qj^O4_vVy*p4i>m_Y&iF11c}v4{fIkoMr8A!d&QGy2b5XeRj_rt}Sdcz7ZIC zlRqbU^+#R>uoX-G{1Le$GcE1cXCQO!4@i<_Eh%P`W7Kt+3S=#%^v3XSZ zVYSw39!6izXW=q>us5M{y+w=^F0nT-pEJT&_nYxvj}n>f z^|_M9+gNWpm!dBo*FcN_(jSP7oYy<=A4yuid%E&ae(ZHq#CvPJlL_3RX)o^nT}!^i zbNb1UWkT;JG|D>iy~nvbEp%N+puov$X3vcW1Y!pV(?F^HRHc88DGzA*TkcGlpA{DU z&F|m<=vSxai}je8m~AKJwy$mu()6C2xuUe__3YWSTs5>n z7P}33UtJh>9d*9AmOXe_aXGWCyt%LY{ERi+d#*Tok=O9Dnc&0h_=@{|(2i0i>}n02 z*k^rW(C~$eYmy%MxaY&wi{1T2R8VW{8OmC?Z`*oB%dyA%CPltKq6TjmmE!Z}T+3<# zPCg29SHl0Ee zDt44?7#zW_v=;-%45+H;EUz2Tim@q#+7II0=|YK6MTncUG|RO^h=NnS_S5cJUV}L` z^jtPSY0f+gj!A>^!@Aned}J*x_uFqL+l4Ov0RqdG?Kz{U$jo7*X#QuQd*Dg|^T&Yf z&wh)z@^-BIMak<@!FF$tjw7kb<>e=!N$=6tohpf^kHdJMx4*9k4t(5h!*=NMUse6~ z*M4_kNZb7IP_J?YKcm36Mb##wl3r0b$mSh^hCXj$S-Inl^mv9Qoc$QD@4;@WMx5R@4hBg=YcCzi&56orc zPVtD0Ay^59#_X&#Q_PWOG8heC$5^(h30@MJQcWLvT8t8Xi>(i}>XhkyT~buKA3Bp% zW^_Tg@Wp3$@0ax!bu{N^YrQ0skDvmsMYa%Epc7Hiy{_(~^IgyRU^2@?|EP~ZUFVmh zrkgU((GgQ*Z4_{^C<-~Nxc>dR{igG{uwJpi z+|~5s&Ev-OIP7|QwnBbsE})qES)B(fP_^8j%I7v0KG)F@0#cN$zYZuUa8#MK&_G?} zJM8)8ma5Vi#|euG>AEE=o=#1sczF{zu^^JLnoO~d~Ky&kE#jW5KANx0NFRFp9 z?3zei#LsN0{n|>&IxCCzQf^!(xFruNQgC}nZmR~*O|P6J=y#5cmdI(xY(W1ezNrF-T4n()(m+@-Sg>E9-D=~xtx%e_--&C$WjH) zNTnV~s!G6EkU&=;%B&hs1TgiXgp%rV#dQ-p{#xvB!^P!c=;rF#)^a5D=n(}IdoI+6 z?o5C47$D>L4*GW8U=Q z+)2&`;_uQANe1zfi)H98Z4#f^^ZQ2LK*vsGT7T`;sZ_e(7IR0xS~u3vVjX-U6KNHQ z=C;)|b#_z};UTxY}ac#@quJMM}EYco}JfMlR{-VEI zY*+;x9@Mt>hDpsp)1`84%oEwUGC;Z&CJM8}BBWCnqVLA>EPggZ7J2pNf}G&}I6Q|YU2FEH)~XPyxX*0OG^_g-@4t2i-XN$R(O-0sVpg)zM$K@9r@5D-Dy7C?=88%@a>wA6a~J;Kk3ORmmm1*hj3hEz8W@*oU17 z6EaEbQ{s9FLLZWL|M-*Ap zXC~8pXkCxzEB#Z*+q!ol_<$u?Vx7$P?mpaSSHa$B1H7HwcG@i*4f!`!B;wwA&imeL zoE8|$&;r?9w!4cgP`CKfRIQPD`*41@Ux;4@c=zl^1bYe! zJ0{qvzH!N?L$lQxXmo=oViYjAXeUm{%L68b!-S}Zm?=Vw^3e52^|*;Ncuqf`qX~^} z1B)3k`7a)C7PKcAAWA6Zwt5n`D-Sk!gt`NYLmpTxlmj3b9M3+MJ97z4eRxi0{)M|? zPCx;kG!t*#qGPbOUlBFW$XxnE^<@O#XBwm^o}wM6N#P06STn6cQjc(v#u6~S{SNI8 z*lSJg?11vumbUl#YQx1j@R*2K5pX}BEd5~78bB;~@a+x5`^!7aOFEc65L+w*kq2NW zdT6eB;&vjHEClSZBnXicrX4E%VP7Q+H1p4(ZJ)cza&ldzW( zRodCYE=&>J-5V-G&lNgWy)Ta09=f(3gHB+X0RdcPH^HW%%@inKaOe`pY zP*Q(22|q(9ySgN5ZIJ$(;Jr;9zCcnwdQ|WTDA7>8fL|R>0s%um7MNhY)L#(Sgn(*o z-$k^RDKNgW-4`#{$vheM{gZ=f_V?GZS7737#Zr^DZ;wsO(oT2xf$8NCYodJnzpYW% zVkd>9m&*ln=THCo0^zjRS^6rn70nems}y8j_JP$X$j-Hz6iM(mWd%;u8u18nOaa+J z_K!7SlnRZX6o`D>cnIIrcvqH*L=HWCOrJ&-m!^WyOp$|26I>u)UfNpJI<_^fAliY2 zl1jB6fr4Z~Q6rJ=C$zDAC1~bSxxHt`^ECM*@Fp2X@R@gm;84tA5~!3YY$FY3XH17b z2?Yh^b1^9eMsNnaF2!_by^!iUxW>FLQmI>X4=I+O&8+ij9&Ks)n24z*?C0p=5zjWQ zU_3vu^{(L@$V=&x*G<~0WWKn~Kit>P*gu^!UbPh3lVqN-H^D(cX!xaxGL~;@4pT_Q zCaE(LF_8p!p$$t6C(zMJJfDfoj_dg|w(_>d?A+>*%wj4{R*?WfFvO(>U;2h@(&QoD zLcZMRlmC(Ae>wxJBzY@OqUfK)ZFZ7D)b9_6%3XJf#B{CEJ$#b14#GE+z&4WzWjyql zx?p-}#9S%GW|6;3G3KOD&c?WVm?D=#g4)&hV|cSjg3&*Jj!+-zG2V9^q=eEkMoW)* z*m->Tgd{s^q0#yo9a%yF0Y3~@hLgNo=5Iq0LK2*hvaG80ShG<9jfYD_fPm;(G?S*j z_V?ZUc}lqI;ngb0rVRnaJht+ga3^2#1G!piIF?2&MlytM2x_CWl*>*y(4iG(7cD=~ z&ji^pZ$*<6M=XPYX$UFf(Tr=1l97KR;z5})lE_2+f8*#RD54_Lh`&P2F-~h%#Dizc zF%BprjO5mqr#6E|eT}}8ti%CH2x2Y-KvFjQ2mgw3x4N_2t8#rhe>!#gy!m6hiPkhV zt_J<-ZzQ?n=iM`nH5anI0=LzC-9uRh;e($drLdwcN1Z9Oh6G7acQ`a&D=$ei(Xg6| zg-2ez7_+i*_AOL3uQ&=B)moYc1^~$H5Q~VMX**;c>?WFLGYg1{@TL3Qi%5p#YEU}L zoW65YAdIFv6)j4^P~~sz^tvv}7NeyAHe4s%^lf}hHMXg5Ec16Vn z2Jpmy(Z@;&44n2LV7wUie|h2m{D%L2#sB^d-~_2UJlqoDl902B+{Yt1x-9QY92r}= zJTQ;)Qw%6b`i(!j@nGC!aOny0$L&}T6kRY62evUeo071qUSZN*Z^o$;;V1sq%<%cQ zG)EZ|Ury>%pO4ol#0dxepDO>!C;CIzpY;(ig>Ro%JI-X9h0i*+b6%{+4#;xw|8o-kD8K+GE;g^LxTlWh52l0w72fPo1jF*dpii8F z`9R~tsSJo36%HIcr$p2;w|YC)#bEfPRMP!Smz~KTNBDdP@Q?0AzyIedCbt@{RpP(l z-zwts^hmep!iXxIYRX2VGO}|Zq}|GslPAK#Wv`@R)FkE!j0@DRDdQn-o~v@irJoYn ze7eegN6W`o3(U8iKy=d-wHjThH3H2PE&I=4i#LNPz{$Dz{k9C_b_P)pv44wXdC@Mb zF{vsVynB++9x7nzqX7);*$->YmHccLRxIY?c3)@S#9yW|AM!BMY)75Z16}m@=fuOI zid-nskdZeX@yECx@f1^w3RUJk;H+pRZx(hD!=)CJo9%vuNYeC{!M;da_%DHx9x`95a8;kD<#emwp73;A}j>+$~FLgwMf&-W~l{0WrcSsN6@kTkpS zS)uB!-OeO)-XL`EThH?C1tGFza9$kfRWC}gW=RCbTTCfgS-9?Vf1Y#%vUFmxLMjx9 zK_9I+9tTJh0Vr0%+MnTx8^tSecsQer)NGQ7;|3`WCX;53ZQ1diF{2Pte`u~B`F_gSSrV`+ zJczPj7GNHO;jw6(y=F<_{)T}X#4G(NC6Zt+3`PipVCwD`0ws6|4%k)_V7>xr0~jbC z29bpaQJGa|?feT^J-;w|+8p`dd;7jU6MdJB9zRkH@^D^a)M;%ac-xm~*kIz_ZDods zWokbl;;vI_676;w&N-;cL{sT+2d7j9lAyC<)nBw2)Bz!2_@h&x*nU+b)+|D$!KHge zQ0z>Bj!Fm*t@M{wzy!m~wO?4E%5uWN4{mn*a|a-yfZ!0qN9Pi+jJ~^lGY#ttBgCPw zmW&R9q4eRv!g?sCbi2eqFrx$jN|M5-j)2y2BlF?=&P*WHOAGqGpYfbxIJUAl36j+DDJcius!xI|&i-3`dumLz7nnzfIsmKnns=cRb}>7{p739+UVXqv}09 z&495D1;SrhHyZdMsA&d1=TI~x9ceP}_GHVmNIOVU7RfpgC7z!Xs|-R-(T^Gqf_O<@ z5CZ%!Dg=PeH(C2Y=^~Cm(F^@)RQ~r@lf%*#ZOPS0?vv@+X20N)(y8$E$JKW4v(1@U z;nw!G6M=&3tLE>Rpr^f(=Z`MW4I?7H=@vTIt6rzafF|nZw-*<4Wn^n{dbV_^g`=+X zW@!1lr@MEJkQJ7NUYbUbX8hhF%LXJNRu`TMY%QgmuQz91p-AUi-m*Dm(W!tB#*z35 zhDtyo+A*9YffP#JUR(XP#_x%wd{^cu&8*>2DG;HxT#+pLFT4(`4anr4S}H2V`o1pejmA#_ z^%FwqAZ3Bur0kiij=fGRFHYf|ucCjuAMZVQJ*7|n-E75(USwOb>9t{iKCh`Xtml;) zUWeTG+}Tb*06D_;vVtC{aM+|(jHq4hm(e$$M)BdtA+IQKtSiIA+yYqy%AMzHQ8EGt zctzDeU8UC<6A>{WWkKPtTaU-|7Tx|@gjqS%*9QC~SwOS{ov3|U%x$#v*zkI6@pmi&V7;Cib3y4KV zS$NF?NxsQoa$nXAv!(FYB$uNGS%Oy$n}0-Q%p|HHSn$cp`M;}-<3ma)wL6XZ5s~1) z{caKP2w{mh+~PBkEs3&bMS4>95hQjzp)n73#&D05gg%&p&XyAb1fFy@n<#s-lEQ$>$QQ1w-cUia4Nd` zabVS47Yn0yWXF}=xL6)e?fWzw@^Js$bQslGJ6PR+C&|(TZ~h5$%K#y?iYoz z?1D|db8UPvI4mwLx;_P8d6aqAoWmi&5|*Le$1)?p6!@B&+xptUAWEZcM!(H;{2L+; zU1oefRX=`(GD7BTw0ATrjWjVK92}=ORV6A6DuWi6_3ijpJ_HAjVvdqq(6UreBOQL9 z_4AWku9tdw@|^D}5Fgym-`q^w<=lpIIGl?w%jUi1hz}d~`H9;qCP?%?*XSsp#=_ayI5qdF zIrlpWNXziPLx$W3!w~)0l$11ki0_#vOgs+B>A>bpHc}|jvO5^T7}P|o3_=Tn8-Q9A zAj6;-5HQdULkhr#^PF6c`@(?cwvRuy@#2`nk6yA$A zrQq&ArMZi@ADY)b4s=|v+z*(Y$7%m6_2lSIj4X%JRgMb{7T{+$s^US$yz93SM2x5#~OqT~n<*5b1;&I2M zH7hjXnuiBDj;XeYTL;n_&@4+d+?lP@=h%NDFaLV7wHS5aUC~9YOCNV%w7zR>a{Sc+ zyGR=0Cxv);&V4yu6tBHG@Ox+{TB^Q{wOf7o$yN2R`N0#b;COU^_4W;@<(9Ac$T9S~ z<6ao_cRKgkJ+rU;b~0y6FD6`ErSwlQ&>##SB??}^_p3lr9Wj_MUWKa*m4%K(mLcKH=GmQC!G72OkO30 z+-)1IW%Z$A#`nDbnNRr5n~TX_?6(s0M(9XnV6|n>=d1!s3K6TlUpb`%l*+np)0a+c zB_ouue19A&KG{0Ug-GIz!roR2iyKUkBvUqrLkN`F@GQy(5}$3cqE$7YKy>mA%RU$7 zGrecz)q)LIG59TPaf0pE@AF=U2GFJ!=*_ZXV0>~VczUyP>UZ7L+<7e8={81o$y$Zr zyE#P1>$LEFgp~C$Qvtl*<@fn9XTr+s)#nMlPp(i;RUkt))=Mp+;o%A7{JNgEP664d zT}d=7+w{nG1&`%%DQHVC-^_GKB!%sA;%8@y&cb-Ry?i=i)nngFR8D+Z3~sL#dS{8> zgu(IKb?Q|P`Wg{%E5CkC36~ZYGno+%s=_fsa4~-q)-tmQwQ29m@f@xfMVlfc7qU`P z6+GU4_1o?x7uea>05;R79dsYtn&(l`FP<9#!KGQBhk?J4IRxrflOg-puIISaTKex? z#h0;);p1xDvenZ;eNCp~nPE!K=i6a6a#>P*Y|(RP(}51!SFw~fJ)}$rieK@66_G1| zU_KetxIWc_RPNlb2B!rh&aWPBi6M3#)trW?5`>v$%RUpr)YQG5bccUU(uVShbQI!%l(LA8xGxMP^Ml$y zkZUHp-U3JlyWh4l z!YITop?UD^RAW7|GFkiuh%{GL#pnU+Te)|AtN4vdNpvDl%P4#8n!BbX5hRYhz_@N@JDi;XF266 zYD*g^NS{%mbVG2|DA*^f(GC4+YUk2yShL4R_VM9t z$=655=`^cQW%9k3kR}-(hAOUCqiKTqx}4XNZ10;);p&RQdU!FAGZh7uBunGyE6xlW zFfI|47Q7}J8ERI1KW{<)(&w4g4Nfq%iCJ`aFxKFz_SE2_qcBG3&xfv?+^$a(?Ovq` zE`p1#ds#mHRw6#bL!}@n1flt1moF~LLPeHBu2=8Rgb?r13~?lZ*B&|%QMJ^Mu(V

Cn zT>gB{;fUkloMJ4O#V^a>12@G>r$DcOKyZ6Eil@S z*WPexpeG5Xe!t{(1Dj~whgi&;#zo1F+78PrnbEDRi9ZLvD?@Zwm+n-yurS#l<}Bo{ zeiGGnS-8YPxKp6(1KTEx^IC zGW+tYWSPJDl}u#!-AH`qG(J~Pyayxkc%gD&LmWbZ`tr1;*?u}?1&wP#GXah+l`-w% z7dmkTx%OVlO4aga!9u0oRn~I;0GsU^2~UP+#~=HTye(f89h4Tzw?2I1w;wVoVF1zi zOG72a*$IK>7^=AO06Yl74m7(aT>W?=uvf*u5rn6rtw#TP%kBQfA$Qn4yM4vj0sM2z zBcP;9@zF=X_anB4XN}pgp+fCjz(R7C9ux2WVU~_%b4|F|gS4A{S0u2j7kh*1K7b{Y z?f9k<3poln1qyvkBCOs^B7t0TW+$0LlLr&C_JE$y^iOtmeKh0KRNABule1dNv~vNJ zbW?rIn=zXk+J#_>lHF2xDvHQ8MA$z|c7Cl_SfYRWB(MbSo8l?CH75$PqFf#Xc1Lr*9H}vp(6NZQjfbIxc?)p|6Uy6A*i5R+3=(pD-kJ6NNE8{d@s>M%1#oy) z|1K3BJ_0`G>2j~#>w^)l!s^Six}_5#Qdk9Awzbb!F@G5LA*^jq?VI>}P@0_+X3#?e zRFaeHPTrACnz<&KlXFGS(8HeV8c2> z7$Q{NeADgh>A*A;f{l(u)l~o10$fCQEYm~Uv~HeXhXj>GAZGjVCG#7%fJ}$)Q~U@4 z(pZg-oi^>b)6VgX`#Q0L_EN;({ghdKJw0@e<#@UcltCC1ZXOXGK7zbP??qHp@X;$B zmp#BxX@6dO`(_@#{RTnui7)6l{ei43a#l2>BHH*TKlIAAKip{ba^&UWFY}t2d-}pi zeB+vJyEe-Lq=6J&2aG}#$h`mhkBGY59;*2Eir@>HGbi M7&>#&TGuje3$G24!$i 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Œ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

kX_8DbR1OkXtFT#&D7}jPsJ|Uj64r^$jBVjTz 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 IM6N<$g4nZuD*ylh literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-focus-row.png b/docs/audit/screenshots/windows-focus-row.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c2d8e370b20f9715c9adc4cae8684e6e8a7b36 GIT binary patch literal 127551 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-home.png b/docs/audit/screenshots/windows-home.png new file mode 100644 index 0000000000000000000000000000000000000000..83f163b8e2e20019c10d1396182896ffe6fce68f GIT binary patch literal 388732 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%0DC)#2hRn8e%57>=H&Gtl=U>QJl`5_qwRFSHDsB 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%0DE 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⪻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�wH9Uk9XY|N4rHfiGmQ{|e0 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 Ij?=^c1A=|x;{X5v literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-player-menu.png b/docs/audit/screenshots/windows-player-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..a323c7083c724deb026ce92bd1b7fb3a21782abc GIT binary patch literal 87670 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

Z1}@h{iCE_8RhM_{P7tfvjQyJ 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 Uv80AzasU7T07*qoM6N<$g1)U72mk;8 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-player.png b/docs/audit/screenshots/windows-player.png new file mode 100644 index 0000000000000000000000000000000000000000..e2e6c1dc479bf25518bea95e9d9571e2af743213 GIT binary patch literal 377449 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�@JGXNtjvdPGCzL6yE4CYBrog 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-queue.png b/docs/audit/screenshots/windows-queue.png new file mode 100644 index 0000000000000000000000000000000000000000..8888d141be825137e09ab1a6a8fb5f5e8418c09a GIT binary patch literal 385531 zcmd?QcU03|*Db0dpwjF}S5ZI#kq!buL`0=3(xgcTX;MQAL6D*di1Zo|1?kcWEec9W z=q*6#5PD630BPr!=Y8LAe9v?K{m!}fjypzBM}YkHUTf{S=A3K$URPV4j zr2h$HsO@7p6WOzihbnp3Z24$s`X>dz0*Lr?ZibonOfv6zuMRad_Y$fIjf7^cL8;t+ z=#dW9k?aD7cf0t!u6vYg7a9I1{OYNeyC+o6p8V@owf?$)@obe+0nb_eKjghKw+VkT z3w4W1Rt6s!bUSE%1dqG7D@+6#vJ=Bg(9>RnTC$VA_-@(h1L8C}C{I7)>Zy?b{<>@k z-G)(TMrx-V+cRC8=3^8#D=0O!@NR8|t;RtysP|;F?Br0)qm8V9El-S@Yvo!vMn=mM zuO;i&e6%_}vAvd9D*3Oa{nwvWE#rqW3T}-kGvEVD((~Z1s6F)b_L>ijkvkArT&ZK4 z1!;W=ZQA7b&FR#CcJ}XI7yaZzZH)#u;xpTr50k0oUJ;m30o8x+{y&eXDTVvv#e(+n zd5)WJh#1l8jnP4R=lE-X-`iC^;1P$5>8`FAy8_3wZe?--57Xav4@4r(4zE+@nr63h zB#Ndkq7f>g_y6%Qc{1>Ja}a7zLv}h)Pv*>j7V)1S^R5S;k>px`?movqK76%bOLpoc zlkGp2^}Xl8Apt>zsA>M=8x9R4TTlY=TVg5QKORzb?_@UfKO&`n`hR<1;rU>RfBfc) zo5%jQ=RZA${LkY5{h7Ln#}fV#z3khQg?Bjr{%L)MLrR1Re0i+j1gpY&9~XW?47x%p z3-UI;UHy{&A1my8IZ_!DG}5CmnJ2Ia1Ccop2YUNngcL$!`hdBQ!#spL=hb zGM8^?K|T}<3|ds96Z(6ytCFw|IOU)NRok_B!$#7jhOHVR&z5idA4X*F>e)l#SP1sL zVCMH!oF}#2a|^Fd7^5C%BrU5Oc9Tq#xP+9Cp2dP@jx$F7bTcP)>rheo^Ev6R%`4q* zkV2^Xhxih-n=ur_5(^o!<|BVs@2%YYM>>QHP-S&p-k{ z)yh7iqC`zf75198#M$KU1a@4DAT7XxG+PN%PFtp~Fd}KGnHtI`w@lh@n|9in@t63t4v=38z5Ac423u?PLjedCPHMfS@O|bQ4WG#Zsvx$oUk9qyU z25k8CJ{ZUMDpTJQ`F>DpxHkQh8{~ffy(Ifij)SMkufLf2VX<)U*=(#0Qm}b5`p%nD zDZg`XaZvNxp11R~P%Ocq%}k01*`aB9hrev6#ptkkjzNTmX;BU7zZIc_=o*4=uQ<)2 zNqABP^)ta@n}qObu#l$;dw%PTI+ftofO6>}HtYxl*IgRn=cQQ8?KcxQ@hedBkf}?X zA%oEL4lDQ`MZdj$^1{@c6G}&9KGIBHx?4SpZwk9#i)bwi+Cu?PZK5T6nmh$Y`At#w z!M^Lce0av%qfiSHZb|v@79R1BP+e`>(V7Z7QPtt^Y8195yadH&hq8X4BrLTj01u^7 zsFWa7(%PAGKqj~Nwu9;Ro2X>On;v!o#*Lci*h40WEnQdM>(q(D$W8_hwu2};#%T6` zl&Xqj1wNe=?PmTMy_|kQ&zvK>(H7;M-%L;nJH;MIUSm|831(D$MJPijB;3Y~IUsW4{jF#KUOSD!;L%Lu`?^IH?8nwEwnNhk)Ep?U-A%O;3qq zF%x!6cHLq~cJHw~6s`W?=%&p*B9%zg5Nq=KRz&wV80@<}V$FvijiBtnE?%FQWd%DJ zB!b!QWg^42tX93CMctL2GJOzw3QZAcYXkI!6u z`#EzQv*o`eZ_Dzx{hd8oa#M8qOW@zi_M}SRm;ck?fBYXfd{RaKgzn$-b}FRs|ADUb zKe@1h5?9C?&#Kh}HpHg z9Ax}|;i;=#Y|vuaard%&o02e6@}Leepi1FCJgBem!oMh1i92NNiw45G|66<0Y8^ZY zx82IOU!0p&jW!S1yIeI5B5pRj&rfdo*PebVfAl?fdap+>2DG~Dp#{QsLgimk$$}kx z|5azV*9?@}bHWS*-KaAWAYZJ$VX2ol0Fv4Id35{J(AFassfA`j)7G7ai4m7+yQNIR zgtbmB1l=&TC#Zbb84sgel!Wy{cbH&@>-I6e3+G}3x~!REznaOe*8>ZZ*1}hpS=?1| zf$e|IUkBDj-t?Si%h-QAvC_EL?dFoUIHacyS;&p4b47V~<7g3ZE^FE!uX5BY&7m!0 zLrct;V)2Jjc=*=VJ=;T=9u1GAnvNwHHf0^zP@9j2%d*)1;(x=-3$o2Ck?OqSDkhVA zrC?ERrIiI)o_)cH5|i3ZH|=}!5qfOI_|}OwdJF1N-vFVmowvbl!YI6dx^ekSY}R3U zKIrh)+DHizQ`@}JkxMa=?~UN2+-1yWJl%K&2v}i%DVGnqZ^gbYB6(z<7e8v91@4j+ zt3MTe8bHoO?-@EaKs@*~%=2swNp-sg;nRi7>PZ!R=02?~vQok~{zZq!H+Mt%%=6yj z^0d;qCCqDGCr3n0K!iVHzg1-?-jKlv;^dTb8OCF>VLD*dLYYb*CdZ~g+Rk&VaUJtm zG`43g*$4X0m0I`JfN8zR{d(EP%}UqII;S=PRw;>XpN# zHrX{cxQ_1a2{vx_sj?17nD2gOhh!=CFP6-kdz)4rtPIzCuW1vf^ZU;R{&)uj{yS^n z%-aZRXDb0t1u3lmP|fwiCK?7FHi|)UgD{6Avwt!9s>zl0%3jJqax?IOO$Wec_xHig zssYXiSfD8bi_^Yh1X-BpTMMh?liQ#}yETCrqrj6t*50xyzOjO`QxQ~&@ENr8)C4gq z!?0;_I6uo{RS>k-Id#UuYv+%ce`nOg>`LQiJN%+7VnfufP}HPWZfQtsFmSgkw!el} z#&%zTO^-uzNI+(GC9rEXriA2P=v2d$--ph>q=mzcGf;tX@9~x zR*CO0l7H%O6Kv`;#+Fp>^Y0CjSL#L4B^C$@5GSSGPpX7w^c3`vv@}dICBS>-7lG}@ zlvi8UkV`A3Y8%|7s!QCNvl`3Yl-?%$ty6Ns*{Z@>)m5K<4IQzK53# z1BnXL_f{6-SL3C$Jh!hgw*Lh95ig+*GdZ~rFu^-q;OQpEG$q2QbvqBZnY`f&?tw2w zcJck#3epK0(4(c1x|d4zMkVdA?|vs_9!=#r-huCaW+M+Oe*lO`w?V)bWNY5yFwG%x zT_g^=k9QIywS{R7I!{36fs;tgregyw{{$HGm`m-Xw&H9w-{Gh_h|~{t9%&52RmS-5 z=f?OBF-tb$kizCiACkN7s?s>t%Wo3o6YBM=LD~TTs8BW(rYY!N=&zgz?xRw07H)Mu zR?=dKZ4^qCZQS1j&Y>?#w3Zv+Xq{)OuzlT`xAdmS zrJaQU-_cDA+^9xp`Hi&q$P=QZS{9vT+<jhA%f97Fj4w?m>7f|<;MspZ`{%${t*khvy9L9H-e$5m`eN8jO6&zK${*2Zy?iB~P1>mhnQxzSUyM)+ZeB1+e!W&g z-X8-4VQv9?4&f;{zfGP;Yi;SSX*t#(1eJF>OS7Sr-wzP>4}kOt7TO~d1Y(;usLO?y z-l6u^aL;HNpcB$5ZU-H?L){mi0ZQbkCAl&CXTs#xS6WLNJAnlniD}TEON%*}=}n(C zbQu^?akMgQ7?qn|2G2vM9SngJN3J&m9G$Y>VV@E)MM{c~Rm35902yVz-GZn;7|;Ou z9!1b95^)qum0OzdG^dWE%K)?i%%Y>AeC3tv4Y^W>M|*45C9I%@nFt=r-C8n$?+=G+ zUfHv#L}dqTK+5u!$OY2kz?$rZSraTsEy?%NNSRxZrO7R&Fjj|#^$OG!VLX78(y+++ zG&NJd!Wu~>FWZ;7XOk#{Qv~3v_W3uO1nJ{U+GkSC;w7)!-`TD+k>U`c_yWmDl=2k}3KHh?4%D7o?iEdX~Ebp#Z-iZy!!1w|%=%mx9OCT*#W825iCvKi@Np?XaHoD!!B(Z+Wa~fiu&nB1A2Y~gG870|d zbxWH)5F1iSIV>hLZYdGq1jtB<31PpsX}%+uYNF^rs>&AdyOmG8DpDB`YQ8>uVOKjw zfd0{USOz#IBZTIy7vc#(SejxXE5hk{@&uHHfBP-B{0JIIHTFU_JptHvi{SA&C|YW| z&z%|ZD(5dv+!t8A7H$S3W?0W{W^Vcl@+_5tn~HL$Lc8MaiWBHK04{_b-gl&e*cNS4>kQwEQ78rYPp*BC^UslLYoJ!+zi#e9Fm=}52yM{_W;fo8QmN7lCNn!A~|zc zRxn1r(SrJtZ!)lZk%mK|tcngm3CL}~Wi&sCW=i)vbNMeTvdYXUHeh|H6ik}j|wlE+P|MmZ;8}f{R1V>EqflmL&J1aS2H|&23cBKB=46rx5dG>x?O4Cw=>FI zv*epO;DGrrN@l@bC-0GYDcw4vYr(F`v=GPYr zm^&1?8>U&xe7Nk0jH6OQAmF6|`k)C`Zz!`j8%r6C>)mxa+Gs*I zO|+R&w%LG{cIrSCwQgQJ^`+k0$Z?T<wA zRQ%nw`W-|@+hGr(Ibiu(#MBmu5PdBGAoi28uImTVk`yIC{F)sAV&cgKT#v38 z%`98&q^Y2vjJ(Ut-z+H%K(m@Vp%uRBjn|sLv~byiZ4`{CMQrf&H=wD3zwoR9%a($f zzMo^B(9wTx9?VpXuAdQRr!fH5n+g_Pf|-E>j5^d$7^T@g!HoSWw)Gm~W~}c4Kkv@A zx*Q*}Dw5`$6XOp!S4lW8#Vau`VXe996jww1E*j-N?fknTFY!Pc^~U01OSr&36-H%Z%2G<$h@yY9d%rB3(n8-J zmy9AnI^hR9Is2VD<$hCR_Av6q5;vX?ag+$Zoox~)W{3oGF#RtoJ_Q{o0`hb#&3*25 z5UuD-0ZU=5*VJz~5ik&MAr8CU98eG4u2>x5;7x+G`C7MrcBif}z(}GbbvA=agEqKy zf?BVq2sV@*C^sFw=Je1%Fu&t~^G%ZI8~cNq!qr45b_^cN&vb=2)t>VcSL;<*T3VjB zfHZ30bodT`bZh|89C;!LyQn0gkl&@_yFQ=ZuIyerNmI>RJD(yBDnR5i>b>t-XHO0X zcV~k4LCA>L^PAS58F`KrYZO$<>5`BI0RKxHeEub?$fD8-pgkahC`=E1Po4yrr(&NC z&2umY1RT|oN|ZWx02d3IrOSuR&{QrUFxTtmV``_|+X1Qf4zFuk29R~~PAkPGtv(a7 zKel;ppO!JD65f9JtLB9PjdvV4ZLb*bu;t z8wR|a6Bpdz0O6e5q@6*t45u>qVq3b~<;VU@nLb|}d#U4x{mh5&W1&`--pzP~Pmq`2 zPB26RWttffbH+L^4>EynHzU1UGYvnuENwT1TzZLS@x;LB!>3}L^s38 zq?fhsFy;C!8*Ru|HF}Cyh`MUnok5?>Ui5r3%s>(w!bck^Iw%YQuErEO3yc8Fo#<<5 z7x-pmJLt6lC^C0$%lfs~WYQW2A$_U!N%=BV$NxcPVDBo_dB(fseVTVgvm{R+1j1ZEtIWjM*nVY zGh_usm?k_^S48ULx_a0cPL`~y9sa%@_<(w-Ott3(ZAl;90kkxNyx|5OwTyslB6@A) zxxHq7O}YJ|Uy}748E9k*Ui?b)!w``C-JdLJG-4{hHVKqf)ACI*f52*aUeilnPUXYc zQz0u*pvQXLc=-+rm>-Flk()#Hv*BxMk8RqiYX@jWJV&pWqv1lWG|heh?>0K>Re^#4 zaZLD<+}I)N5cHcr_RTq(oYtH2M&i(C0g=AC=d}Y^huG~Afcyk4?@Dq%^zkR3F2hid zv)$)%Wqa8qHMY_P1+7I3W(oyb4XwdIxLIWoDOTFS=ib4mP&UxQEBmcLz^14(K%LGt5 zbu1e#2Y@DN0cvi4+^LM*A|^Zy)Sj$xj+?nxKVYlTt`)Qh?=B$@!lHP+e@AF5w{nO9 z1CX|ep5V7!0G3)EX;Dy1%3_b+XpX79dCRA~HedG!6KWu><(jt0*K-Bx3SHHMfsAn# zYwwwwJya%|m$Cu|%nBLlF>Tx_G3H`z;Z*7lpDK@%YTtD+Bp9vS$T&&v9G(wY9e0BI zY`-Wn+!+kkMpucEw&y?uI;T$B$tjg9&T&}wx7`l^6d~{*nK-N?Uu!1Zjse(hk!nN zWkM=K4)<7?UGwLeq_*$JchLbouH?rZ%o7H0ULWIQFlr@Edj!OkG&O` z4IWcB12jzXd8@oqpp(|kjexflRI-;)H=HRUP4PmXKv0&HYX z7U)TAvStQ(om5;Z)G-Y(5f8haHPAAMdpGPko&8~Qe|bi8Pwb4ZlV~1DX%cwK(O&X> z)XZO@P_w1+UJou{lLxi7Tr$peYi0w^8>eF-q$u-)xw_jkrL_$J=&bS5SQ5Fvl5+G- ztYskZtdwdK)&+{+1UK6Qs$&#z8!d=wXxe)hx})9dX2Y2f?m61H-F(Ul;2lZTLfROq zmVThZ<3eThznss|{Igp$>sn3rT;dbJ$aSbMT?dY6^IB%UNCH}*wmBXXL+fv?ubiW)b7gMPDK{1a;MG+^6AUhJRKS1)EfqZRo zfn)u9`iUEru=(+Zjb`Es-vJTbxGya)#&Px}%P=4l-n6_gQ=%l6jaf$U&{Et4NO)yn zoGKwt8}DY=^UXWQ1GKNB9rRrCe5vbS_Cl>egvVd@pXd>QS^)t3sH^snw%ch36hO7p zVqL)0LT)hW5HJr+2c-ZZ`lN@!IC$~#zcSgldP&T0HVQmlw*xc?2wFkMZ*QkvGz4Y^ z%qm%W{4C_f>|21l4Fx z6u{R3uK)Bodym;FM{4>34hA1_z!0d+YJeiy(jFk_oGZZe@dxh63tp1wRJRj22;W+UeEG2CRh$6QeB+3y>iX+xDdMTsrXt&Wf0Ij8gviV+`VOg>KkL*q+TUme-RGF;+0%A}}V$~6MB27?v z<-JZ?Cx*Lf=7YAN-M1*QCL7%>WlCqP7;xpq4Z384pzN{m9pyudcM7kqCjg>517HG_ z(`Cw*sLQ<-&>a+v=C!+4|5R5#>Nhm?!#)udbmOvz;$ToxJRf4=j~Edq_S5F{%h2;q zyP}9Y4eN}(5DL{7aMV|eW5F1gS{jA`UqX^NUeFT4lu_OJFx+3))uIjQWuS zOmzM=zmhT`cRvwSxJPo5UUi=uySb;Dg<~F0q9CFuV}677_KF` zx#R6TjSIZXS6orehs~1Aviy++G-E`^4}DA6D*O?|T~jlD3%HNfTW=1K0Zi@$3N@Iu zo4}dY2sk_z(3Z8!5ds#Kew6_WEQJGV>=uf>PgR^aG}DjyJ9}xKeIsTYBfP#+oCWFf zyv-DL)xiMht6b*z@%euYK|*8jG@p$NP;e7a>hs;oM(2Nxrn5H;2St$J-Dm1RIhX^} zi8(#k`bdcH(YaW~2fq(Zm$pLcQKMCkG(pU&Mn~gC9O@vv+w@Tlz=hlZ1kr)u^k|Bb z(#w&rgXh`pP*(QP4OF=}OgU@8XnQL29Tujb_$jDV`^=RGrH!jd?(|Y>H!ji8>~JBU&0Kya z8PHwFkhD1g%~z}FqcOwi2De7wRtVtrq%)8wfSUr89qDx0Y2QID@dbd{9NH>3t^*6A zQ#Sd}B?*U;!X{K(Lzx$kK@))6kRad`ljo8VM*q4S@(JCq&cm}2h5$@IwRKudfh9B7 z@0CRF<|37{a;_Owb9Q>Qg#x!2A5{B2ozl(53zh6-xt>q#bs6s za0Pz5qoS}iUe;eE{jz2a-cfrUI8Z@#uNjp&9T;4AR7=}_7F`h5DZ=TnMA*r^ToD}V zMl{Jo-OsR>bf=7*V&XhMquQlteO3N8zMy2`dreuV#RYbag3eOe*wYeakDte{eX`)( zwGsDoztm~>$?s5b?vTIoUfIqQ&20=bz8&`{esogv+hv)MixL1_l6Gf zdtpjxXx)o)&^Hr^(O?p^%9ZN%Fz?j4gIFDs`Nws-M>ev&8x(fvk~Z7n!9#Xa3 zLx+W3)6>@{!R677GY*%Z%@-Md?W{Lh%zk4Muj-2SS3}+Ge4HT7V_{d;w&Aq^Z$6`r@+zxgScpDt z!lCE!I#kSQHPi9?dZyx)p$la-aXoFyIp>2W+!?JtJchKNtIrhAb${q0#mXJs78k1i z_1@Glb|BTUFfF!nt?+!dm!WIz;0Lnqt>g!1Z44!oq=RwH`bv_8@%?*}V}|!0WtF|0 zAKY-beE3I2(#};arWRA!{~IJOaAKKXI4aHAf8Lg@v|_D1Ta3Tx$EEz|v!0z2PCF(+ z4lL|nHOj&@WL|cg*{BrJtMs)vTz@Bh6|xBFm}ya+%3y#zH499~_7__l7+o*>(5^al zH`QfX_0RUMM5=YWv^+XF>%E?TZ;GXxON1%zrSH8TK^xp}-Hzw7c6Y^0qnsGAkBF}* z?-+f)t-hmYTHw}@wo18cd{-!R>JgVs(Bqff>J?p*;=vxHuLzYh{a-|aB;*Sw} zj!ZdQnXzKFW%ShH{qML2>fz+(az{I7=t9gb;wN$2{f5opH7!?leW4_t(-LF6xihDB zE?8|IBh-Bn|Ln%fXJCbN!JH5hlhP~YbYp*0e`9laYWlNLr z>Kl$l<={Qp5r?_lqOAwTO_D}>E!Y$bt~)dQHfjwI6OaFVdP?^ANtH?-O#yC7E6VOn ze~oS>82YS7hFwVyacRWCL&)?gDE^&rq2gW1!mN247m%o`W?aOAMsIFi;r86KF}(fo z6U^A}s?C)gc(tTWb=Y~k50IkoUbh}7fA+GFWx(cK{|d@bZL%X}U6%j{FMs{G*|wHy z-+d=7yOmRpX-Grw*_`tunWxVT2c~)~HtJn(2E(h`*X~yqY5cUD7gfIFog#O4;avHP z&ES~UE|4~(>jZ*#)@J0-^Hq=iJufMF63?KGRgNZel4yuXpxNC)+hbUITO^$8Dwkv2 zaF5+RezSW?p}4XnfFIgP_Gmt| zDgIcu>Um?|Y@^YHH ziI^wE-RyVO3C;qCMi$4{-$9CVV1<8m14m6T;REmSg=y}6*(EVv0abqhH=@atRk&lpZ zdFmcKM-rjhn^A+#O+;{8epa*sd72y>5!DVKZ<*!D+I2|kRF}-}45Jg?{Sh~V^v#(S z@GxlcPvFjcIrL_M^OYGw(?U&*U#5tT_;o|n+h|3QG zN*(dncJq)UMlVGAp2jm{)b{tWB3?B~C#vq2ziJleY5jeIBi;SrOWEM0>*>4@t&2`XmsDZj3?SU?+dee;lIWf+tW-u-Hu z*EH^p6Zj~u-|~gyp-fbwOti^DmMoqRu(A05j0uoD3$N@H6%w zb!N?LqjtZ^paz6TPmY=h@+Gv8UU%kC=H4^lHhDeVZxgy;v?#t14 zOI-Ir#0w@#?1NNPE^g{7fzgF&#r?XqiYCP1-KUX-KcIK7)<(AdEz1`*UBwG#dXxyH zg!}T3PuRL$%OIJ)Qvf$|_<6Q_4!gzz(s*U5!2TRGj`dAB@a_cbA9H!|s#TGSE68Kr@0!oQNq2n^mU8-*_Sk8g zbzJ1z6E~T-?A_NqYOfUdqZkv?y;R39BiH%BH-dDTHTL9Rq>s9ybUiC{eKci%V(-WC zqdUtAv1ketv;5JEyqLuI-zwNHavMw78VU94_@`MUpakht77%RU~tgfJ)Jz$bp5fiKTogDKVdTc${_}*>*zc#|Ga~eQvfkKqrt3$ zQnhEXONt)ezqvxa^qn^ZGh2PjR#uVXaR2cuR{BA#=8tIE*Q>I8#*Munb-#Azg6=$g z)9_B);5@r>`vCI3-`VFS>lUG#zbGAQVD2V)+YZ%UKSSLQzoPrKhqiCN%ajzA>`GxY zU268KOsIE6|udpvC%8GinftfPd=FXro>L&7z;HoQk_PaMBs!yUtr-DS1-Fa>bRxg0PZZ%0I&N3hjkZue zUmuVAD)-QRK`w6f*hliSSvvlz+G$se&x7nhbi+iGanupuD@v`2#OnuaIq34n9fcHG z;-w@QJL^|IJic{ptIJ;U!*vsJ%?y#yGktY0T0*W+wezuZbn;ICb@uYoDp%dzAAsCK zO8s00TM=KK013P~?QoOBG_lhqUC?)>AkuAc!O~W9|F^MJT33);K`lM0`;8^tO)gFN zsXWx%G0C(9{xW7K?f%C!9XR8J;NIQ+h_+ zz9{ER+}X?l8(xjJ>|@DsrpKe+=QFk5kUwr4@=-pe=0SyX+SG>lXGK95AFUdOiMHGW z^|0GfHh&VNbuarM-``gFz}bd^^XS7;ha7%4252 z!oPQGLkjJ+u}0FN_=;P>!#)S3cT-KCZ&4GWY7{*i_l^2F@)h>F40ztPfu3X{vjp;X zy0!PS{bRtqqv{i<#7ohwj&S#jA=x3}2>#ua-Ni38o^vBEW~reoySjr5rx{G}mvU}@ zOc~QQ@PaMw?pvW6-)(#Z28X%)*DrD`eZi`D>Z~|oDjW=gk&n$;GmeEBERL|}RE%%D zy5W-IZ0q3|VLj~;9_Dc-?26xqm;wo58FN0NTAkPa+0Nc-=>kO0?BkELS2XG91f*@x z-O$^lu&8ie4yd%kzE1sR`#Cm_t~+%^^j$mtvJJe%3H~9#`>U+&C%T$zKOc48dGxSz zGUv*9>H$?DK_l}OVEw%d==7}dtPv^FGL?@A(w;DXhv@NuN8FlzZ7Jf1t{V-Eh`wm~ zq@%0V>3*&GlkXX!U7_*CLk;e1>~|!wE%9~&f|5@_c&9)8+t#fiKwrOn{|ay!`Xy6g zORG|3?OpoPo>rvSDwy3|JmMmwJ#uD4#615biwx^tIJPxn;m0Soy4PtUx)t3afv)er zBs`NieM6?U9^`Wqg(-e^DRu4Htq_U4&F&(B#ZT#fzGh%EHk8tnVpa>2RjU15KeLE@ z#!hsm^(n@~UtR-%8Oc8OT6c!54f@6|##Qd{2TR7}QtvR~Dw z_m7<_>|TQCCpyg-lvirn9?N?&RqHc&@Oww52@YNzR7@qu@-K>u5g-kni7!%uq;;PK~I`V$-lm0t32WHW?hs||g% z9xQIJTEVrRVp7q?UOCrYGc@yT&)oXPV;{t&pLIktR|`wkU-(xjYlXcE0a06nAHF$v ztzRr~hcwCxf1Ay&c^H4X*ZSc5yU&v0U1!F}6KC!9CcgcA>GS9HjDnDMl~l22&$^bd zljQ|Vh3}aOzIe+5`>-Zv1dnNvk3-dS+^f4rnhqnM`e!vYRl<$}zP)Ras8-9+lk>jc zmF*JQnNo4Gf%Pg^pnM98dbaaH^JA%0Nr#ve@1BYiUvTv|SH~rC6DK*@yw&i^H#28%~WMGRQToGvBTzVj{RSgK?f!up7l3ZmM8Ld3kVo7o>Ymt zhRJ*NWp~g?3Oxao-w^|!%zV~F=)2zH0QR1oYjIsB513mf6n5@mqcC(8+kgmPW50|nT9ZQMxy?=D^@nP!cG~V$&hB@ zZFa=QiK0O-XZUaSu#187eww~FE`83SwGru5n*KEZwok?oy+gp|v@eZPu;Jv+>we7K zg9=wKXK}weWq8H8Uy<=WWHEv1!ulG^hiVoNr}`H?oVOTXl+0Dm-uJZG3`q@NN`L*c z3i8`rtRtAK_NG=|O$RT#LRD9Hd;uovWIUv!Mx4U(LOy4q#&P02g!gz0x z$K|vDC|nLgkVT((E1%uA3JS*c-@LcQg_uJ3g6#UZ$a(V$(@Z5cx?5^ zBOzNb!WKf=rUyIB3KU&>k=#06j@HG0I%6o%nVPZ3a4qps25*<+y9EWC%bJy3Rl$x? z*!>8Teh)N~r$|WU(dQ=;#gZ0`!X8kmk+m0^q4<6FwAfU(9X>RJSLz%7KJoH=f^CnK z`-~>*?YrZA?KebRmfyF?7$4SczjtQBmNKs#wEQrrS(eOi8yb*juq#gNeDb|nwYQw` z0Gs8@&vE5i#n(>CrxomV+`_ibxZQnu`Iga|1v4Q92Stilil`Vp-xVeMv)mTGdEBO! zyApun;V7KbYv$eEHL~$>m8=YOgj>pUU60uhEED;?S}-6rcsbkvSv;1es8MnTP~ZGjGF3A#RlG3NP8PtVwSCxrQ{MW6 zTh50@P2GpXCh*)~_z|-h7`qru@1LGotK$eVtwP>ChyT#OAn`>y)$PRZi8?v8nwDEU zHF^b_XQXerrC+<8wt>hTHx*kPmekun|GxPPQ@f|Mp=ERRM)7El&u5a8uWR#(3_NFI zLD%ho0+$+Lt>NL+`5_awBf)Irf?hZqHq}X{^0Gu6a)0@DnxebeNAaPQY%kuc;hI`=DKfJ7 zALh?RuE*MK@O%NgBg!9zk{uUT+qgq_$1T$F9i|5rm7nXm?S|b)Zdmrn^qe?bEIl?O zJUoDTVqLm{$ogIY)wNcR%}!FUTpiiEsLlUowXN<^2p0b}KN z>v*-uk*S{zdSe9GZ@IKxP&2Vl>AK#&aV;C}k^64vs6W@%-??DIkqNAudhw#8in49r ztLv3+*wWTPlrzZw`TT>GM3K9E-Q*sGuCZTcKzc|rs{PlOUllhN`R5?lO&A+Ao=3F% zXfk~CtMWBIDUo+SX`S;?yQ9g0US1yZ_pTf&(%#a<0o!d9sjU{ zrLl>lH<+J*EPfAtDc0Ul|I0c$+meH|O6JbZf{%CK7UEtA(;1*`UWO}R8AB3h?!cWI z>Z>|V8h@t<_ZIdcW$rTnS~GDRyJ2rbQ(F&4d=1J!Wo1Sme}}ntYyH66DD_}Ib0ar7<7uCC{b=YQGP2_|1OhG5;BRMX%*E{IT`6CtzhuvhL~Ms>Nkl< zNv54$dEV%y4ussdyj7RR2algisR~@n#f6*uiXCc>_;h|0mUQb}HyS+D<3)ePXEhFq z$Olhcp{Ab6Dx6~rch2Kp7n;RcEmlnMErE%D&f8>u8n(e`%fY{wNJOKZ98q%HKRIH4 zJ@Mj|HRw*=#7p-S`YE_+cO%(rRc++N zmxVvyf&X$5RdkDwujl87#UWTuz_85NGm9ruYW>0WOD-1q4)%&&F$@=$6kjf$gtxtW z)$uw&n2;fa=(ydoCi94c%ZA73?dP$aho8Eg)mZ$Lq%XrxiZg!5RCvDnEeun}Z6NoW z?+j1ghDxW5x~PIcPrvyeBioD@pIhc`I5jMvurfGZ?38jRS`NNWZy4RTx;70)y8O9y z%HZ}>JL8?XQ?{&(gXjH_GGqMKX?G>8*njQE7O(u+hdg_1^=GG6Ry-s|RQGyIv$SIMdH9QLO=<_izsGcTTB@)AObn9EazI`RdKi zei2A#Oe;83bT&yN_0ZI-Y9Jxr;ME-XW1@3>Sj*!J(V=ijBMPcq*F`@5>7B>P<{HV) z*AzM*7@Pqt^XD4sAAH77>sPR>fG3`cz>MzOzBll`X|bs+ZhVyS;>Xv%va^1L6Uk$* z1D>V?3b+`NhV~3Q<5fPeLJ68DjgEbW&lEX7;MkK4j#_4Q9b~ zA!9B<&%E^*T{d>!^OCCAwk@Xl#d1WHi-v~Q0t!6#LF-3glG02k|0k#CFez{wMmH#BSkoY;HwThzf;y0*j~5# zq|jHZrtbchzLoIG{@x{Rv5UsynrqV!qvq*8q~Ab3=v%P4sHvb5{_@;&k-Oqg&a*^U zU-Ep|DK31@^%Is^;j(`B`TR{zJx;l6x;??eQ-L-I-vxq7@5T!da%||r7f*!s&M6Ay zeXPo`EOq@lU0$g#pPtBWs9>^mDj5r=Z^$a%8Pn%+jy4SLYhQWzeAv31&3YMQ@FZ*!CEcdB74<-b(+6f1JXG4_HD(_uQd~$*0U!` zUtdW%jtsEF&l|8^SmMW&*G8@mqT1+q-e!jlNYySlTOjRCTc79@i}7$t+Lv6@Im?^} zT*HvKpD&x(8CM!NfY^MDv5fnz&e7pd>^iZ2q0{bO{MHm5g3Q8GKAe%U`PzEvC?x5y z|Jfre<6z7V({VquX-n?ZD*~vF<6CxTJtd>7E20Sln?j627*6!U!2PJbdG2G&YB?j< za&}P&(2Ktod;Tt{dr?1Zk+nKc@~KWX#hdxho?uHX5|o;*3fw)G^tF*=Q3Az{L!cp_#Th&{7VES00- z=au>SazX67&rC-0O15+iYsV_MqMO8+UCWuX75SA4MW*OvcN@FprQJiIEit3AI`Pp17v%xC^bcIg~xnj#-FFW9(dbBlb&^w&gw zrZe!lYy5e^u1boPuc0w=Q!MFwb%h-=K|0L+j^A@$0wP8j+;e9JXQlQcjlMIVB{eQ? zYC<{owxYyq+cwxo7hGj(JL%>cx~0H$fuv}dkiGA4`>bOAy?kfkrG}>4YNo$ZolBPs zri2Z&bM?(J`s3@uqd28SlTWX|zkgYKQRc#%yY0UL-a*I65xYD7F#dX=o}@X2+|!RMoA+Lqf==%Is`^aj8H&HLBhN5eeN&!FLrQg(~ znH8!GSS>u}Ap_SuZ?YT8JBcMdOhul4n9;(G|H>b}mSX9i%A5QqX7iZEF)J?xarSO= zagKlzX&*(;mnNg{Z`!eqvOn7?zxg=u1hnqR%s#f_{H{r2DWhgT5Eg$%CKuU4uNa#a4Gemd}<*Z9VU&!^^F}pxl3#b=NXr8&xF2acpH-$np{ldWaEH@yJxpcZaH^OA$c+B>Mz5 z&hvwUF^xMVf=httA{IC|t}v!NY%HEeW6~Qa6(tO5bp`RIfoK$ZIt=i5B9njEpLM+A zx_;FH7KEff=lSD2;U8_Vtu|Kan`o9`WbtXH;dg->M=4UciOkZUNNfzQ;Js2iO?&3i zbA7S%ZCXv4AiM%gW`Bzpo~c(>e-UeHUO#tDXf*gr?W|sOb`8<^ATh)FZH2o-xySQ5 zvv&+FW z(NshhK>~bzRIAnr*WM#(QY$+`O8(`jiB|XHgC!!Rd^1G-$kN?VYx(x5Rw=T8J^2V0 z+jH7pJ7RIJb_m3;cGM?;{JO`XL^YWpx3ZJuFo7DIrf*#?bb`y_PD9N+_n8`=P!RLx z1>I;wbic8fntcbwvsQZcsS(JK6D7FY%Poz&{_P$-dSORRex*oRILNeS)57!V%YWmK zg)7k5R_7DU1Y0@-lO7r3n_t)JKRwQ0IDIDg>h4@J%T|}P$hN+lO+UGyR=F#d%vH;a$sLKZDne)gKM zn82ld!f3_Ec=;M~1k7GfTdG2TeI-`)BmuM?ji8wG*mW>8c!Kt{^!-n)3y+g(Ba}UM zn#}qL&BQvr4bORp-w8)+f@?f@{T+sjoH8}FU!zZ=x@FcAPuyL2yE)QRzVEVJcRgpG zc>zBJI--`}no*19Dx>hjqy39B$EsQq0Bs&ksV!VgK(n}HAqYa=%39HrYK2Xgn73nP zUz#KNon^v1s|3#^+fwPMvF)|Tuw2_JdS`@>A1S@{^AW1c{@lkr0p58SM4NupSbX4U z!Q%rxNh)1c`mT08r(+X=xyqw_ujXMp9?fsgcGj6=ud-#FtKd*6Qn><{XtINR;y{E; z6}p^O9k)8q!#Ll;_|M2|XS?IiM`e8`KVFRY3gLb+s#l+|^~whfDD}!=F~o4dAI`p^ z@fPZmgZNKOTL0|1Ud`VU%obKnswx}_D=U1FCjOV^9L+DKMf}8(xpKFIJj2 zxgGQIwHupuB873Q99fJGo%K97oVd;`XPg&?3=eq>5E$YkfiYpgC`k9b8vVhu#T;D3&qKF=j^_imkww9Q?HR9(xSU6u=aE=f?z<@qG?uci2d1WiW zx8H|4KSI%S#u*d+SXv%Na3|2aWI>b-_Ke>G)1;=gJGecVhut)DE0l)IxpUsW1)Ram z7OFlvmx!8t`v%1~ZpBnvBPx(V4+Vz7{&vEAesF=m+?`#_c;@!A!}YP2n!~wW8Sh=@ zIu?KZR<=;D;LWMXS<|}n%146R`F}FUo?|Qtz#5Thi0J3`71mVs`Whjn2CD5QPU2-02vwWd7xIAv82 zoSe2@7SFMsM}ClE&}#W?J`65z@fjO_oo`yl)2GUQf8VZ$na50JVD0IL0X3%8b}5mkacv z*1Io~C~qmR-p62L*@NCZhLC;ThqulQdS zleXY!YrVtzBW0Y4lOM_44NtKzLE&8kI993OjaV7KHI?r=As4 z>hqE>U84+OrVgMfX@fd7;lOveS8CQVAr+iimCv1rl_#)6fJaVqd>p1R1>9rL5LY(A z3+LW=5XEZxG>XH1@R6qbmKUWyBz?zcCy+NAwrzhPX{J2Iz##p*em?#6+)~oYi$lj5 zyO-AAhZc%FQY$UZ+xil+>@|&vF2&7Qf(R*=g>*Qr(xib4hTkeq^Lw9zJeS=lE3Q1D z^R}fW^ZhK;QC7k{oH-i^k*A-?S_gu3Prw?Ku+d5*wU4*{GFo|!q!U%tc7sB_gZ#$E z`H4j?q3U7w%{cv~C)GIY^ohGaU{BJU@Zc#sFy5|2@WXt+)bV_-YNz$TOQz+?>6pp< zNQ9QdbF(`PC5m2XuI&2rHbJP^)}dNFWl*{<-AUuk_Ps8q^fJ9Ona0me(+uD%4dF4-~H>aNw*?B4x%ed%?_0dIy>_TgG_X>b3_ z#hOoD6xX-^?24p4D=U*3X9prT?Y1__-V3J(x-8wTaCZDV>*;S{Q#-NXkjmy>C;WCR z;j$6r_bo}>A!*hJ(0{0lPBL}0Xq@*^6Bf~Yx`stNyhU>^z8alLJKWhUzq9489A}3f(lNJV@J!!9T>%*4BE3 z^P(EQ^AeNgqGY^gO zGcKAZ{H@Yy+13DAw}beb6k+bn01~^QF-8Xdx~X)qThY#_Bhk~N&wR{7N%R`5kS9s8 zx$z$oGSG+yGwogh7zVn~hFJYw%Q9IwodTzW4i3cFL02awyLFG#M}F=n{_~dzbZ!=L zK-t5(=aa-owD~3LhdjEPR2T<#hX2w0Yn#{xo5*<9(!&vsNBNb|IsXNeeafNje@l&w zZNi<^V;%kXtg*Z1iJ80=?DGDUvi=q5&t||Rmp@TC2l6&gM zTBu0;Io3R7kvr)xO{?Up`(ukQ91a;%ikZ5uRhD$2@bT1WV#HIeA<1KGgytYWd?o6?v0OomLrqn3xcNrZUP`OBN#wG6MtzYxI3n0;7&vJy@yP zr3w$-(`5{aDN)B?+*4V}at=i5v^&#{pN2a`A-S6M2Ec1`Mj2A0=eGdizn!nmyW>v zqu9<_Q&INMn}^inIM1jc>wKV%fa9TKYUy;E`%?QSU3|yXc;P`Rk3@fyw9-zJNHM_d zKIl47uN#hP=)HW}D%709UA8Bk877kjSfA4>BZ%m9{2|ABR)EijS2F}AGr1@qcr96QUo?ab{{nFtlE{CyKwk9Oeh8yBqWUim!q=U zER$BRG5Y9@qwTAHX)|gro!m_h*k)9Qxjq4AN%jvYVo;{ z0`ikAOO{P?6AHjP()fp}HlIg++dhBfAzNSXoY*@P0rP?C{xtV2MlZB4r_-=ebz7g4 zn|bPsv*t+K$@8QkSLY`=s)uBqo!q&5jK>=+1hN1x_xJwHxGwZJJdmHxdrIj#Zz3Gr zqiCYE8_Qp*MKMtY7YKUW$F-S~;2<@b`9(mVtTn`!hKHud3=VCQ@c+u)OE0K{pLDR! zhyU#&IwrtAAN6=5oJzom4zPC!V|U}>o6EYV<<#q0k0t7;cJ^?PYRw=uJLT5`NKj}n zN#x>MO-(*V7(>Hl=O(zADwh^i6m|!@h)9rw8~65>diM@Oq^Sp%#8T=T8q1-7mZJ38V=N$U;JGf zyWDKXr5tO}GZM>;_4e?5wK-OYmqZk&EcUpfnX_Sp_EuL;%No@&X?r;uE7c`AhoG(= zE6`~Enno=SRgW})@H8qs3#oE9OL3pk46KoLQ6wJ>JD!zuw=vh&C>d%TSMta0(=?mh z{)9g3#9}^(6iHqUNM~)s5_4l3AeQh?XD`}Wga>i3+@HlCZ~VlJx$yp&Aawl@{S=ko0;OMl{gQa#+vl*zQXSu|J$;^_$r4G!~ghk zEzv};aQ*6A;4coX*#^hq=~aj280vLqyejh0ZTjE7f{tAZ>A1c6@XlZwMtyZv3e~Sp z<;jDyx+_wCZA+dcQj=MWxcRO;qT*(JpT^V42Ji*vTUmDrP8zetv=|K>woYHq?ljI6 zv|1Y1337h+k>z=F5Wab0wJU_S+^B8PQuUAploX$H%4^(GQazm}-^ol&Qo3MpV9D4V zO+2d!7Xt1X*8ctCwAlS6zE0d**oEjH-Z0V9Cj%36#kxXpgC@{Kslld3gU%!)g^~}I zF%xmYJ2g!xl9=@F))sw8T;B5IjV3b7fL*Ns##`Y|#y*m9jw6x82}d{}q*`T(Vd$H_ z=U$+~ogE)ghe?twtZa-xj$d~Gyd??pW52-}KF*VUsicHB{N4yD(zL{?fv+b`%+vLe~Sx;dkrA#^^q)We#-Pcz}WE)rhkR2->?+!+5- zLN6hQy>#DY9)TogvI{<)aj+EtBDXzIy=gZo$$@9TYRM1jHZtRO@)Bq1wntW&&=xtTXi>#XBn!|o-(@Qtt#o~ z?fCs67PqF1^R!B!H;nWh|1{o=eUym4gIS;o5?m%r5+g%Sd^tL(r0mtM>6SjA{7fYC zfBYIOwJuDmo)9s6qE;e_){!&;gwC$Dlq zT_#oJJ;k|!1zEsp;Y=xVRokp?QU#&!Fy=xbJ7);@RNO(4ldGM*{6EqrW=B1u z;?};^&ny!2#`^tvlNamyNuej52Cm&LVq+{^zWxsVt&YT$^Gye=%Z;GCK(;$>X}&Pm z|D*-MC-=Q9_*?V-p=Ua#N138*V&OA3t-(nN7OGUlYGi>M`fa-=7`GzDB|PYyqee7( zvb6jkv6_1AkP|WQ6mxrLGC-rPpbX|iRpD`O$)ygk75}h3{9r^Y3LxyF=?q1I!5t>X zPas!7nMl*bQ5fg-HU}Mb5soay%HW;2j3Fw{nAQBS%ITR%+t3R;ZJZqbpB zE81t1c{Ad5S5!5}-+1atbJ5>Xq0-8LV;GqhajyLo^57+IYRNX31eX5};hM64n(h0` zG~+xPyFrAuG|q=%>RxLcz2yi3JJbn;aP>)}bLW%ghRdd;js?Sn3Adv_|BzdKLEw;?m0y|Gj5?-3#sKCX zJRc!XsXAH^tA$Ymoli!!#k6nJ1-H^bSS7xClocvbAdgAj3dvfL|RIab!@ zn+kuSpCjiCRW^j&b3>&SgdK6b2B!591`Cy{B1U8@o`|iXb50pn;n-y@r_?8i=b?dH zbq%7IVZ1oP*2d*1WQ!70zt;P^p3@&8;RdelSf1|okC4YS!dWPKcAmmR64Aa0P%9*i z*RcyccOf7&O}70#VT_;?xUmEbY@Pt=Fs=ZSYyTTGkN z>u4*Z@`Ze{#g@Y@Y{)?G_LzjPj#3tPSMEXlX)T+HvSm39{0Ri>{o=@I%|(y zhm&!vv6d1RsASOjs0T_;;DYLSq=r+ZKmSavW+W>g(pHP=GTo}lU>#}V@(}rWeGiqD z{5z4ZrC}H84bR=qR(#w1eKfmx2VCoRM9Ya~4rp|b+yggI8FVM-e(m2M61K;MJg%iY zH<{jfhSEg5C^VMbEOg>iia!@C9o=ElKUu}Q=98?9@zz?d_}mEOY5iQ6tcF)}I7G29 z$V_G|#FIp-Kf1u1^-Fn_QO4G5kvI0AvLn@u2{a+4YJ#a=Ob2lC=%}m^1n20&i)H$g z%bgxR>j55_?0eE?u$v?xq3a)mCV9TP5xIm%B@Ys{o3O$1&YlIYs)G1OM~rvl@A)OE zsMg`o6=f_&Nku&f0BwSA+DIxJ9>Yokp@RC1S+hbA&;0H|ICR-x8Z-mmyJ3ON`*~t< zv*3&`{TwcN@opRiw&8;>63daF^Ut~mf}2f$2W+8(+J4j4n&(L8Y&cIYEC&`_IP$sH zz4PE}7Go$dsbA>N$S#Rn^f$7>p1GJRR}cMSppRH@)ZR-)@R}HYrOWeTf=!6`v+E7q zLly4;i%tL<;+#sy5>;0QyN5mcI+8l}${hsc#J};#Up<}AHP$cT1c7=}7zHImsc6~L zQvhRG45ho1Pw=q9i?kZ&k@m{fhBYIE`T;g|Ju*(->FYjRA2IkQW!_ z!s=Iyv!2XQs>bYHszurV_ykCTLM1}?T9-O{V}_CIfv4I0BXioBm}i$t5$+iW2^k~3 zBH@wHW`j&c5Diy!mB?T^)H1xG$r4M+9J*`FrXF7@QmWxEc=ajPKyu59Nz374HSVR> zJVq=SQ$FO+UNfy$C3R*%zTs8a@vOEd?X^HXHHS(Qb+B?eAg?(FqeUb??O!;)_@{{E z#c+D{-h+Ghu30Ok(N>Nd!evG$Z5f-1C# z)8!prw~4sRLHxBwtUi8bqda3!D;N`YJd%vErg=K?hI`Iof}lml1)t|ngcGVJO%Rv- z96V6xsd0dPlG`UW33UZko6CQ!>{!;<+nlh57g0Q$0xdS>_~}PY4uj0%4mZ4JXIH9F z7kNuI105=jpiS8~4dac_2FNa>U|JuPZ4dS-TEi}sfKw2Yy7BuJNO#Spa22F;EP;sb zE^&w279aA)Ni4;@0!hr{?II^1DyyWApgE*4W#H_?g`IdOw3L3*zpKoc(PQI@H?F^W ze)Zhs2gvQM3W%-b;{cPU0Bg?US3bEy2hvpFC*qvt zq4HU~T{vouD*j*Bi&ZR*g74F4w>!>Au!Hg4RGIu!iI2UeQ?t#ELxVJpft<@BBqc~5 zw*pQ7F%x8Q=US-UlR$?8db^X+XFJBo!DwKUrI-`&EJ#S1E1c^f9XK_=K3zU2#RR|m*v{> zMe?4@noXko_A?g|VX+$Q{tVG7Dc*!Clq{h~i!2YeyhJ|^HS+Kexe$q?n5E_2H_gIU zX)1xwh&XI$aLB}mto|dqvf-9EC*{UQW4^ETlO8Ij)5sFnfb2^TKOpD`vb9>>iTUr7 zRR8&VFym>{a20CyaOS=O6@wkC=<_+6DA@vxfZ9pB$U*t0rq|`e$oERULc+Vo$Ox|B zft?STWLk_H=5>W{7x_hW*Molrzx;<<{LlOgo9}hTA$J$+&_#Blw-3f_yTMEsv`_jiulK@Sb3S>DBCxNmv ze68}Ce4})InX<6&FDnx^MOX>qhi1sr9*)o}kKs{ffMq_{%I1VkBB?>QjUb@>_`~I# z0)A;jK8X*Xef;J5QmwchAkvrXxe!!;BJfX#n;_=<4GRWIZ^QW#6}262>Katn-IG{1 z6Z0_X0YoKv?d8_b@P>88bSa;m6Mxf$DPc_A@tWL;w(WTiIYriAvR54zX;bx=d(+;I zRfjSz&%3}sh?JIk!$ z=h+(V`+I>xIc}6>(A+s+&l^ETex&H3lj_)b+00*`nxX-P!z7Lb;a~KHk?vDUcVC~# zlYO3KC&BL6=CkHEyVjXb>%Am}ufOkxht*b9UI+>8dM}l zW`5oFPCHcv+O+aG6zMT8ZT@mDgx6==&~C2eiIBeWBtNi@4-CNJsmN)5YG9l>N=)fW z0CCBvc^)Kv;p=T!LER`Ncc;lF*^|Y z>>!8Bj({DB>$wYL8-}+$e8Z*KO9Jd+g?GMGoGZkvE#+Z%6QekVQba;nL%gkj)8ItFl zVPW3b>ayz(BVQrOYyXu39&hF?UoW(Jo`M**&kQIRh)I#RG!3=1m{qeKxs?Z`>lgsM zEaqJog+%(lIu1GweG;KGx#%KinR^xMyDf$sVH$%0d=wmTvffFoiB4VO?I#krLcQiM7)S>}zE_i#N5c<2{w$2uq{RlrchfhMU15eh(q$r+(Gv>hWv=YL(HIw60zu_dxh6fDxbv`|!daCZAQX6sKtQf$$w3t4# zUlAT|{~E3^7V!)kyc3b80PdtC``d}t3y$*q`CthRw7YJPp;1@PYtnM)s+^p+f)egn zXFLi@@^kEB1cLsGvpB?uaaf5%f z2?iX6^xf>~W%sLF!RxQ#g*%VaWDGBdk%uo5{+*q?Fi4_ASsARl*g2mr{A??@%@oH5 zIFRI&2Vzb}82`j=W5Y$J%ANhOMsH*~63!=ZApG0BrWaxLP64?uy|wMz?&Wd+pCU(Q zS|4K_)ylI}s+%6wOq$o5Z9>QEi7JAlntA*JXV|g&`Eoia$7a8f+kWsU)9TnJlV-2f|xN2~Y87 zRit=()$6?;WJ3b}&O`dyAHs{$@grDA@HR0(iWTF|>QF>K-6N<=>>(1vlX&tkbLmBB0+&<(Z4z6> zKgl@yTh5gQWMzgF2@0tlxWflq1Mxl6U58{@u>i4dq}ZY<8@-C6^LTr}WBtPW3>!Rf z*(&};W@~pyPkd7djsQ{p@QY71VKx?e^w%=YPe?3U_0zM^@kw`}unlonvAM@hr203L zH_TN8^3yfb{duysl!zfFoMmFH^E}bN0eHRXZ5g>$u+(QR58xQ&Z>DI4ib>`9`gX~a zw{)iKxHS%y9ZpIAlywz~8j@4o;0k#xF3GxmSQortEvy_))m2ZX4t0g}U@zP^1+C#~Qlw|hrB z@Ttyu&}QmsduM*j=~ZYQ10@dUFT@!COl4#_QqME!jE>d7I&|e? z!V&v3(G!hbtlP<&2unuWsANPv`Hw?;PZV1v!7+F4T2UX^<5e+jIsjM(1Xlh4k5k&R zuu?FjdgLSmf@>4z7a*d+aQD?uRpgN6n~YqfKhsA?KZo|wX>(H)!OXZfC zVGvJFZ4aoCUP?sNDEzVswg;bY>W9pld*3T_J&1*i*$*#6&ESkLb&wdjH+8%>+OBv#CBHabCy+z3jisCwmbi^cQbTm%I z8gl(DQ8m)P#v9mFwZD@ieaT@>$2~;jouKBP$W>L&$TzF^I?fEx$7Z&cbzsRUdil*8 z_qqs1BtMn8NML;8#jw=yZMYY?PP}^a;osN-#>c6a70K{$UCiO@N{;teiDV&t#>7Ne zEayBkBmAQh@Q*L)L|WG8Na&s-=u!HdOGqqWWNZryh+76qd-?ehvbkcyPKVdTd$%C< zaU$10sowWA9IofC-wwBfH?YaKUbj3pXKlYieqvJu8qD5CCi}yfhTRuWYL1NGzF&MF zkuBwA{RYK3hz~}~Fm(1jpZF7FJ5Xoy^Nyka_4(tdsOjw=N9Lp&J&vCTr+{ZO%Qfnx zE7Irit)nkx0dD}GB<6HS)RyT1{EEbzbvE2dM>o~GD>Wv1k=KlJJCAC9k2`B|hgSUN zVN~{&MW^`{-k=%DR+JnJ421kU4`F^|0l8KsYTN)izD1s)9=WVtV+z$L4P#U+*blf6}@QZt7u2|zhj&(vMNu<)VQJ#wZ%GU#%MVYs!jiRw!cDBl`yuO zzer;tkMegdrC2#6&FVs$?Kj*Df6&Ehr6=S&&<1IsS0m!jSO><1#G`Wi4)S|ApgN?| zv%q)LW71#M%c?5W{J`E|p_eo`YvsRx4|qpm-h@7j2)JEw9T~ToaAwBv9{dVS%nU-*F5M}q8wH-cBTx; zE~d9woH0eQ#5zc%(P+v7L|)#@h~t=eyQo6E(AOw|DpBJ0gXJLubwy2HNGPWV3@bZNWAhNnQc>hHg@jX{TTQ>+tl7luS3cDJ`9M$sFBq z1oj4gJE+DKR_Dt&wH39$yPaTqn)`OUGdiC@9GCy@D$y)W&^wy4uI`r2mSul^!ocTH2 zbA*vZh_F(#rsuxSk)^Hb7j^-qqbW21o*K>NsE|e7S0H;mzIfV3ezJ{8c3uCK@n}Rq z;3gb;YHug~yVE4T49g;S%3d{N=IH`E6m|2ZVIoq|#ATxgkDh$l-{P6!03|WA~WRAIWz|CsgespFz82c`=iSzC&h2A$OdXEow6maD;%E~ zYYN;gsGY{zhr8d8NczC^-q*iXh+-C)hGe{x&SCu$w~_N(oS9la!cSAEnkrf~B=BsNMuS+C@@Sm>!%nQ zh7Of9WAX_;-v%TTD=?nh)L%(*Fl^JW&J3z#(Cx%gj))7o+~Atas|>QzP7fvH@3Q%j zBE)(7wnQ|E_Dh+dGW+!*%5b84-I(bmKCaw%&VrPdLMb@6-OeCwbGzJX_qj7uY^z zxnI;sr^zI+%rNpZWXnMltyfpdkcWOFHB+-b> z%jU|6O*qqp&qw4zJaTuq+We}0I7V~0(yd5__Yd}eJtLUkJiRX>5$$N4L_& zc3^on8%_mzbyD>avK*Pn?ULLT=_2F(Zw7^q4 z!`l{&b$}>UxcgD;|CEd)h*th(KXT3DlQ_;gZhVyTNZHg=*hmQ;uZW9H$`TfXkWB7r z&VN{>8@c*i4y;6q2DF_+JO;lXMHJWtt#^=b}R8Q7y9LtC_^GN3w*Xjo0;i zO$q-1=c*E}2>%Ic1}aPI_R%x}4t4%*4l2r`$b;BYp9HGDPpYoMm?d{t_$lW_y~pAm z{!7>F$kQb^^hYdZrZM2dVb%g29aFGNx4Sg2U#PSfEs3W6_@UrwHl0+A^d$RTn~0dw zala%1#+?|@rTfRxx%=EkJMli0l^3>M72=`S>(OjRQ+WG-HvP@$-9Rjk(R0gQ{}yY$ zKU00pSNMfM&iZ;1J6`iKhN||=yH|Zt5fLol)Z==RKMZJ@lGW%ZI@ytdzkO)Eyv`_ z;&xr7CCz0Yhh>bOmF=a1m_>_PuYm5mOJ?~SWhsg#qdn8c(i-!eO2;XJ`;nn* zDP$fbr>sm+PJRKq0c%<59JkljUT1&zB!E&aw{UE97hekR26SP2I!2!OCzm?ch6t#Y zQ5O>-?H{V;GeV9jtH;0dZSz!YBO^E96VtDAK6vHqr1>}NI4=8*l#(#152<+W@EF$$ zY(Xc_DP!D)!|7)i=p8!6hY=x9Li*GGK3zRSFm(fH%#UUYz7f@zoI;PXlhoxrZ2)$)+<|8@S*%{KpU#$opFzM_&EnH zs@A|Io7oR+AH_ys*Z$jrR-O2F`jGXcxkipfBb6ERIT|jk zmYYbUOQ1Jk+}m+RV8fAO5Py6~88`wcQTaXuo<-g6&PXAQY@jWDo%JFA%%N28gFtcA zAiGDG{;TW%A_ho8&tI-xV$)aseXUaoVmtpYd=;iZY2+PixLDmS5U-t&HVo2?VCFej z5hp}&sF@OF5PwKq(q^yNYZn#;2&}GCqlIK4*@sdIBZ>DJxwZ2n*YJxBs~(T04+UBK zSEsdZB^b*&asBgA`KN?Nuh(_W;@;UNO;%<@pjyg7<=_3;%38QxOL^aH`Np`H5sG*a z3z3yO;98kzm~g|7QnQO}b1G7^>Js0@nU$&bZXEE~MW?I=KCW*1%#%@FVzjrUQS)oMRxY!XKS7R)^*~-Bc3`L*=hO$6FvI)7#p!m92y0eLKN&sCII^>PW zh9OVQYDs}LH!`?WoP09#_9h`VA(us9VWoh{)c}&OxDe((h<=LCe5>y{=%HOv1imEy zIQKO0I##&2faus7J()><{HR2UAaZHvQr}sLR79{q+aP|=Y(6&6s zWw<}z-vJ8xY_&<+sGWW0l_H1p+h{FYN8T5f54zvuoR&1pl|{X&v=mU|`_V~q_wFr@ zJ-6f2c&$9%x=c+<93QIS6nN##`mB@~T<3}}RaKF5XwL%iyEpz<@?N7y0GHZWnX69w z`xtfEqEP}k4;$}SGnb8rGVO9zXkTT@cQgBa&YnUgSH0g~#Ow(n?#xS3zcE`YFbbH= z!TEJl@rqMCQ1XSwyx!{Nfd9h^q_FSv#;Hir%(QzmJN3wx$ z9Lrm&v&!QGNlD`r*ZMn+uzJFe|Dwd#8Pj)gv?c-PO>BuZ<6nI1l=_i|JUPiowq2h0 z2rZsjus&yC*UrvY_rc=C05-pQgzhl`n3R`_#(yVm3PRh2?6bk4yo>ztH)Cv_vyFs5 zULEn%^WhukL+&;%((=qvE(gwVsI{F)t|V*hD>zj8iOVM4DDWcpkViqyyFs2ZzGmuGx`2~9p~AoQ{Z~`u)BI)%<)ZWJYuZiuYPCx%7<+G zXyWap6`xDy|1>wH5AqZ+KT6!n1$+M#^wM5^4A3<#d|G_Vd0q zhB|?Om323Ck6J~Mgaqvt#2KV}s6jmaO>gnL3n)Y-*0U#q$-n?&!rzBN-bG&YOTP%+ z9((skAi3h28j{s`X(#0{a(rrc-9C`Tl>DhS5_oOa4axUx~ zq0cb1@uwI0PnycWcj9-PVXX!6+%!V=H%|$PDz9do|JDZb59R&L6}lDv`In-UKiezU zt-C9hk)_UF=>0{ib8gS-Zr|5J(@&>m<0HsDy=8muUf0}D7F(qK@oV*NtNxuCd3Fz0 z{B>4WEhJ?eB)k3xsX$i0@So?+6VV4o6Y_yoOA#OlS|ievq+t>hevxH=w&Hh?)=v#{ zFF zR%R}eIY+jrGVydl?9qeE3p&8Wi|mY)>6_7txxA=UbZ1d;g0Wi7lc@o+{{&!KB6mH- zUrpf(BaJ6c^uZAxHNKxp3K(Cnlc$U1`@%a#aWC2-g7YS!u(FF2J5_GhL#KeL5%>{* z+mTcxggUnL&EW?P|C|emoV0|83ydJ@09i?P%!p{G?LTPvRbvAdy*z2tUCe+&BqkP? z!iLc>J7foPd)V<%M+ynU2#3WnrZ}A{Q{}SJth?r!1F8y5Ik4^7<(8e~u$h0kbHtp8 zt90X~#iY8X4Y{w7aXHf6&FR0tYxRp#pPBNs5)GS)QFAaJ z(~qotgNV6<587Q zIE6lAWEUZ~+Y63k{48;ft}qxErfFjYg=Kk$6dAkxNaVEc9Q8^;U@<*JlgG{;OjVhM zGVzWOqiH%!>nW_Bc}&(^jdm)L8Yh8cZIA3bw)?&Rh<5T2#|M@=N$4i=jtb4CZxP;Yfb9YeLpFn4g>>OISzaA2ImdRrq zWKWlE#}))12Z-!1ghtBo#K~s}*QOpNyM4I4SP8k;*))6yrtG`7yW7)Oz<9S4;>?%w zi}Cp#kxEN91_6=GrCIdi5MIHfwQ@KVJ!JT2kDGH5tejrblOu|No0I*PoHEk#MU=(} z;q$bBx8p-J7Mq@}tUZ{^K zzeh2Wdj$*S@dA8pvn{%-U~t%bxLE2OCU^Utw~LM>FO7|vLyGZ&d~dEWf}_ za22XPq_i_QI{20{6AY)wR+|u~Ffl0Kys~I>nZ#;kdKwS5BB{Pu=wJGv}B0;rKf|4=#TM(nH-j9$h9(*6N$c8r<(7Ti!KU$ja@R?;xs62i%Xc{ z%i+Inefefmg6zC1>rxU&_D2JpbK%5Ph5n_l>v6Ix-`$Bf7arM66>X`Kof=I|N{{n1 zF;Np)xm10K*^ZwzF*YL<6Y@CH@kMI;5V`x;^0}PL)-=cC2}M4%Cah>$2TqD9lXV3M zGV8*!xH+|tpvf_UFNfMAM+|6^WksC*MmYUsr5bHhwLx*lFxhPrPA$+m^Neg*G}G1# zN1Z)#0JjET?v6^A7cncB)*Xr;Fv708as0Wv5c-#N;ADNqzHOvCYec$X$XGaS^;suB z03F2JHV)qwvGUm0Mfcb7;BlDy9YiodUJ@ILALk8|wTlaP%H%_Whsm+yrcV~J7x*8s zhpQeLU>6Rcyo^e{ESTH7J0&pXXj>KiT_kT9>7u6FEnI84v?&=L$y6nD_kb^BA9shD zCuO$lZGs&{rbfu_U7kAX@;6VkA!cv=2D%aRC>KcGRYt-|wrP0Em1daR7S9dC{RO-2 zc{qu!CdKT@&k7J#v?qORY$8EqMZ^#m0+a=D0+ku&XhaqhSyq@&D>Eb`XR1O7y#q>?$O?b2(lvfLtW`5kyQxdmOo#MfFs#oe1vp-m8MmOP~TXnW$ph zN&7`_!cp$NaeI<4$FC?X#E)Qp5Dfm3!$$YOa(7(X;3a41^F(j&%prz-lD!`(AP9mM zTlo=8E}yD5d$I~IBq?PkZSlLDez=sU0ke?$fH-)Z?`l3QRq12s$}5M4Mf1mP7MU-* z7cmZ{Ivg=~Kh~bi44Kz9!8Tqix)II9=;@HG=(LDVwpuHWoI~+c^&2`vUoT#II{{** zC#ugb7c)nkGttUNqwFM=S&0)=yX*uRCT4*tDYIn_J&06=QsZtvStZjAl9lj%ED~l2 zGNZI*Ps*`Y(F;PXv*qt1Wv*Rb_KYqvyw4O<8kDOdR>TTF{NOn7K+D zv2RV`p>7Fc5_B&?voJ&FR>tm31>!WJywOJWGhOTDL4?Q%X`lRBE3?fyK-{$Z3=1Wh z)w$%0y+SON=&!ly%0lsfE2eIE`k0&FI|Y5(mbM&76ZN0+&OX_=#noB@=F$il0)ufzSm={ z%tV7DEf76VzuKEG`$Y~?4uBvCnz8!F@qr_~9{=KyU6~ad`mE38L!Uk5*DIn*GG|$+ zZ9|c-?Vw>h&Dttb84rksdqnhJ7df4e4|p~kPUuJ{&k@x@gfJr=y`JL z;vp!)N{S-=yA@ex5H2s4O>{sO;~sIH9DlIlk+Hw$8BLBKh1kv25SK*a!4xzy!7=;W zIkAW^di?DpLTAEklYa&O(w-LUv*uXJStR>}J=wz?mW9_6hL!;?8ipw zvYE#zB4%TP8(UZ|VWr!wbfM^p$ejHV+JH2gdP0OfVkbb~6BWLj$b3o7Us@hOvH zO8*wpT#^>5!)N<~5iU%wF~U?OlddZJ;qQjo!ZP)gZDMsqQ5EG*oWvwwWajibXOB3! zk;v@EM#E;Ib3Yg^n=@OHYvPx$3q1!paD`#Y^}nzk@02+EA*9&-^o&2idO@-gp1b6f z9qTj(VX^X9I6MGB&{|jjup?H%vmYdN1!V@>d~Vj{hdMeMUWLqleAMJqxKEXttSZaz zC(_wetK<1lxF+%KC(Sy?1<|rXzfOk&rR2MW z5fds+nuyWu6q(;!Zt~udh6szP!wPMloEkZn;+dL2%=8A0;V#tjeG#f5zo3X-Bzr{T zJ2fLQW?Xw5BzLR7D?1zIkp+>Yr13q(2fNT5M5PGVJ(V1SrmMTr z_4SxnWy+V6PhDfJz4WRs=0LG>G$Qdn>PiZaOZWb-JSkH%10E zneA=Od;~I8k6SDoUlo@5;wB6h5J^O5MG!AJ|ICQaW1y1qan>FX8` z$gew7sMI2Pz}cJWfSYJ0DwH?suVjw$bq$b)xar%wEetzmOY;PzTGps#jDGnGSpA+p zh%{Rzsm#3i(<9a?emZllAC{0!{+ZH)gbe7^D!H2*r3aT_%Jfl~7k}vWVql9fm-itE zf)-VUC!T)#=#(Nhnf+Ut<&wweK`B8oxF>U~!ovpZ(F6w#;#^ze;ygxlgA3YQj!z>S z(xjNI(PyG(y`B7N$p4t3W=KMfIekd1cFc`VzVyjzG|3~^Y_M0rIQb%RL=idGtmDw+ zW}YRooXvz`_Oj7&uLUtXK^{|_Y||GQGG~h^u`3+mi)vM|t(r7=l;D?)5@envg5%Kp zSmZ=(DS%eoS#AefC_yu!uGAzs+Oev7@?AouX`VD@TcXLNU(vEeNXVb?Vh)|V&d+Ib zh}I1b6d8wIf4RL|3Qm*V=b5yf7Ly$RWoFAxdT{bzco=I*AdRfq7w_8WnxMnVV|8ZN z>DuH;GU36I7$=Y%@4Lj2Q$OPt%JHJbvm&>HTM3b#(fFllfq?S%pm3Gc%6r6Ja=Lrz z-I^}E+x0!v7)3P)h*ntKP|EL9f64}Qb}RI`be>;&4;$%CJLW2FC1bpdjTfycWx+L! zIC{5`HSQCOX{9kpipj?!%+?R48p$Mtjz}|Be~QX^XBcv{ch}CioWYOK(F8&6APWs+ z%r~sFr&s4A7nUZGp0fK_F5_7aY(~-ZWvJRqVy541VIqU16shkY{i7A(4ikEE^sA?2L5olP2vJIZb zBpxGoO?0?EU`5R(H|kXG8>Prfr5EQo>(QUi(hb#(c#$d#f-Ki2CCf{sUGuRe)&?lm zSn_9)&W6*~x8&jg0tkZEswy6{)ph`Kx>GKQXDi+iO5b}kRZ=;W^U0sgghOvBS^i7q z#N+%7jR$6~GC_`kG>*nL_5b-K%-b@Fpc!<9ZE`P7rn|26_!_3)L8=jRVPgBXtZnS__;&02+^pieMAGwcx=uskTLb$K`%Ff%gM4Zlql_#4UQZOrC2_i zrpDfyaje`}7RuCTt|}$@*t5xm%X*+o-Ca+h z7)=ecJKvq%E?JaMEZDK@tz_%~j<6cj$cC6s2kWLA6fUpb2< z48~uf%p|w6G3AAm7m=QB3MDfgJA(X2_JoNl>mLwY0^qZ&9aa(xW|ckxYt{hz$#oQW zxomXy1SS_$*2k>>0JQ^=Xz}XFtY>zwQ5j%fqsuO0xzpx*H5meVu@&bd8_V2LRi(#C ztCK0cSgGQE-^t4Xv}{Dk1|A1g&M&3_I-va|sbqeCn3T!lYiM(o*w(HY@HwpSqKoO2vFD3a$Gz zz3>kV6BCPV5i;2vkP_j$Faicz6m{7KrV5zJjC#E;m0)auL|r z9i-?|l4FTe>_a)kS)R6Qdkk>WwxT^3l2D+-Z8A=ykoOT1zYqy_5(6j`)DTU z4+nTnz=*DVz z{)UCovsyqetSHC&P{KaA3vqS~xf$W@>Z;Pvzt_8m$ z)RvHyZMA}@KpqS-I!rMTu?RLdBvVe#G!j!LzI16SpGmT1lpvU!B(t39DU&t{+Y!(t z!{oT|BfHy@k+K`bss9Q>kV&8!5+b{bQMVYbUeNMH1cB z9uoZ9dB`Iy*2k^70)1nicvGgb;|jdZ39=mh(+#eho;_;yV}i&sAF z2`Zm1QS1_CxR_*yVM&4#BSb`_qoanERwjOwwIb6)79%o4i^{aCIaMHMW7=rSpBeGv z{*n|fr1AN|tRvmmUk*qkq%KCVzR^hHcFFVsac|pkDtc;36^V^TDz@r$6`DeA`TaB9 zb^QKdNA29|dU!icB;AEGjV$g2gE*VRr#ZN6SJY8PGjZVi+9&)A4Y`H^PXH zPBE5uVILk?f-EzS$vK6Gqa7|ovN@4^l094@2!hs{#2hF+s79rS06$2d#{5ZPzC!4f z*>Yx~YL46!vHmfTf4Hoor-_(B3yMJruS#cj9s8qxjwTDT90IeS-!)BE)#eIng*r~&yHhq($pbCYVw$%rf0zf zM!R(E(}MWYkO>L<0s96o##~A2vRxHAsLfcF^#7Q7w6uuSt zij#VH1IOTfIrd8b+7a!Q{eYdgufxdE>qT^65v`ZmMM;;Fy2Xevne5Pm;jj2260d!X zl?Ds3ig^@(@^Y!=Uth?Rh<)!NpEiwgCK6;5D5vdsGa2+a^#t)ZrqHQLNSY5O%P&HP z-C=H08*VAHRfKa5{sD)D%ldWyFu(aMU%x?qmq60dd4hz+d^ZCljle>?3l<*FTs2L~ zfEGbrUl6jK64N0qkHyc125| zavqj_aTtKq>IAC98OdlLZBJ~?d;6@C!(Ll?Jxo79I`eX@LH83u2xN?mHx0qc!H{3v zFL7SSFDbjn#vj|I4<`~qe2x=W*WklakXMUI>RqMe(@#I#~zmz}7H zAlf*#C%MA1=Jo`d`ZO4FlM_&F(F9h9(HuFJdZ#HgXEV9JpYa#EbEREala0wG;9 za}#4?woD*+x`NDXIo%NCdT}0|+4ZMOK&`h#PW{)v?*%`|5dNEUmH5=d%3CJ8w-M*>!fl2TCjHM}d*<^v z8HP(>oL=0>HwE(7cR2k{nK~i;PGAW@c^SnYIt(KF=UTckwVMkDlnG@PUk}*e=KhJ0 z*PLoa_ZLkbYBlxJv#Hlcwzj{>>3Xa zk!j9eRfO18;!UcNU@!yE1!``h1J#;S1Yvr=7y&Yx(ItVTE={!i4B_%Oo?Zw|M+f`9 zppBl7qwfO#8Gz1PWJJm1`sf*X#uzhtb$0QV_coF&l-wAa&hvg?VPQ@-=g*A|Wu|u7 zKr(h!<=Y>aJ31-{+sSI$P~R~8hzT0&mF<7l3)1k+j7h`zMLL+{P%BFMmZo_zr^%FZi5L5{ zTi8xWC)6vyk>d5)Ad9kM(sHU28YXqnhZ0&MM^pLcb~RHbkc&s7_2(W2a{Wc_&Tv!^ z%J{T>C!}c$*#ECB^Hx{EUVpsm4cUv zj;7ML7Q%}ohIRS4o0tG%!kQCwX1$@|PjIH}J4keD!f&zo6@t7T zMu1JeU$C1pc?{?rUjQgCljwLt$6zrO9Ln;bW59C9^8&_0e1HtBFYL zEb7y|x7Qa>Xn#LYU$7y5x@|%QBc3%W~Tgg=R zb(cx25ActY)<%wliE0#FRpi};@Cf=7gcX73J>5G;JFvUwnz4RrHv|Lg0}4Eaxq2UjJVP)u%TsfmZ{9-5qeK1>FpS3ugr z&6ts7QxOXzcF;f8YyOKR1fxd=VdE>YVOh#w#>zCAVu z&)m$dmnplK;8cC9hHWkfW828eh}mnQtZ1@hcCcrs0f z^I-krO=IG^;gTe$t`behQ_K5(cO6N`iAJZ97N+}!UTM-PqqVcR(a1#$RSn}}+X5&r ztI|bL&XJ9K%wME}M4*mFcR8$L|J4`G zU$E^Ajlgbdq1iN#-N0&P-B}He$0xRMZ5pPl}!LTy#2-V2tR&EC*#Snv*B%t337C*OnOW*Qx0XTp(#1H zj@^KKZwt3zytfls4h))ne;^g5!&PQPZFB4*tjh7L*-yQBpn%c@Ke`ShT#L#dZTkVT z>J&6A&i?X$0;XL5P_Lj?VvZE9t+?F1rpm)-CuTirjCjar7K7cFY}|VwK6h?1;Twm# z4SS;29;6qjSvJwDYpjx1mxbk4d`{}^@MdRiD?Yar;u{I`wWz#Xaxsc+7;e+#9A112 z^AC&s*vPy*^+V*zE^AFc;-h5+8dyv`071}ptASq)>TBW9=0Is~&prl6U|@z*CsqrE$Nz##bW_j%U=B32Q8Tq)jwsn#4^xjB%(Ns@lvdgSy3@)05!Mf-)#)4LXc^74s( zfN3mzOb5ht|LWEG$hRotlc70284e-n%6#N^M6H~L8Dad%;y_fun!21Q! z@5`yu+?Yq}iEV(JtilSZ6G%>&tZc-mg$c^hNh(ZU!!xn8QcI!L4Ww^7qES{|8C%&vQEYW0Qw!rCM78#59nGKOPkwR69NYZP|OluuOiqRM*wp=RH zmN1f}QnuFi;LDJGUZb7208%6(sSTb$m~YfP5c3uy^g z4B4=*Y1=O|s7O(ATCj~+G!uUd9BJyCNdzW(l_+q^-!&ewkLHAkaN)*wh(RKB09TS_ z!_x(Y#px&o&EfqdnkN$i-VkHU*v8?}=8TfNg}=wnk>lxyO$Xqj_lRhr%q;+g59N6B zVweg|LTr=cQFcuDJ?ZI{;dq;U9|BNbCb`cWuID6wH2i9%&pt7n4wunjnS2YP=E>#= z91?TmIq}&n?>bozwP{!RJP!U|)1qO_PFa~nJHvmHcXH|+oX3#D()}ri&sMq3 z?~@c9hbZzK)7z12;xWL6`n4tO7t4w z5~DXOGOZYva+3J`(QjYOL2f{@ogtf*m9V!htkK4p|yPO7rQ z5ZRJd{N~UhoLMHt_aNTs;$+_ z0w4(5jwL396X%j1u02_~*Y62u9>yofmDhA5|C)Su(Cb3&t>Pq18y$<}lUOLLjfC0Q zf32<<#Wo~Q`hIDe61Uln^eSrnxHgkS=U-!$TtdU-xAF2_IYmnrR*XdC*)iLWag`Az zdo7Q4XpRZQ(MlxVlO|Pc`~8N7S?LGA6P#)Cl42$+Y8qjA{I&8d$q{Kup&;wF*QSGcNl${r*(0g{)3OVnolJR0ba_Paz4I#F4O30DCcI#1edTB zs=(~sPwq>;{DWIrR&-*>E zw-qL6^FbFXbJH!4!jM_Qk9!V|jYs(q3*}s=h9O;03Jr)j>$xKd$WPS=ABBxv}1Glz^Bh%!mYR1K3xH(;74q=J$!ITqI zWtbfNTevmW+@B6D_Bg&^N;$A%j1{3+lW4@C?3W2XRt|Cr8kP__B1VfEb05md6GdFJ zEmeqI5x&g>nN@N+tAx_iQ5G$RL@pc=KJ#}G+F1S<2(>m<)=5Y-kB>#TxNPy))1%bn zBl8_4ltnx(r#A!lE*cl^bFsqDFH&>!0g8U`qWi6N?-e?x>}{!kkb8^`omv3O%PQky zup5$(D9qVKT5-{&$$G?QLr~W{o%0Fd#F&4R^JB4zh-{w}%2$Q2fHlXV(1l0IaAbDK z9;Su4F@0R-Kfti(6KyR@nOO_yEtctIPc53NTkOGYW#LHLl4f_zEv_HaBvYO(SFXyd zY7SgkDS7$rCNDqB)zN8Y8&hkDBa2exYE5zphh*N{nrU1a((tqSm1;!;PVcOqBy(q2}x?mDq@>M9##-Yy5L#_4DBjO_oNb zK85C;VuQTR%9l}+m53nT|8*SGy1DHMVLz@{kvWnU(Kv`=3AvSI`fJ(5sf)v|p$_a9 zH7X?m@u$%YUb?t^Y0tRJ2B^phBf8YT1gESc#ILJ7YX%N^Vy9!hO`t{Iby8OdSIsv+ zH%tzZlDVQM&#}a~SYN6}DxK!d&Qud;637?3Yek4d$!UeXbfMA`d@)PmH(9{qOnBT) zE}PAD`KUAHHoOt=Q}qXf1B>ype6iDz2>Mco?;_nMu~H&e&o?z0{UqL?-GO%`bq9ys ziE-;NjVlVEyi8(GoOr8;3&Dm{dLNSeO&Bbv8#s|=@zv75Wz(Q^#EqP+&xfe&^;L7{ zxSf_YA}G0w9Idm2oie#iT;=?IW(@Eon$eo#-$E4j6v)p@Im_piS?;C~dMB3ZliGlN zwW4iD2S9ldatNjSm*W(l0r^Nf^?cI03NxFe4$6o-rm7tC*cX$*nuB?=$bUF6n#fee z`cN~OX2N#|W-?pPhqLOvv$|^2*P)$zyR{Q#J7Bgv6;sYep0(o<4w3V*G&wGQLF>IW zS34DeAPAaJy$_tpo-yq*`&%~Na(YSeRCDizdu+6W1JjF5E<=4(*(t~OKyAXD%%38u ziLcRZ-;|~!%k&*vzSUbmhy8?{p&etRt%;y=6UfOIC=Nxt;1W{~%t{}k#DQ>)bkdgD zGS7qn3(lQcWVw-Eb4hA(filW`+;7cU8tHb-#|0@yxV&&Zg4MvVJ{DEdt}2YbJT*5= z<}iXm!uxk{{p|_X3l$NopLdl8K6F^L@iQ}Crom#N} z65*#dnrPGrjTG8-;0TAS54R~X%I@trqi^64T(jK4jPK*u&_>3b;I{fTuE zF6N=5QLjJh_cUUTIJ^$98(H*#|c2%qM(O@%NUjVW=nx zqd(V(zx*KnlVb+llSa5#{B3L)DaZOGBkFKl724DIorsK*9;0gXGM+^A@x&cogya2p zn_X32aQ3{yW)-W#2mz)oD!-0m-aTg6A2 zRe?&yub`Fr@Rt)i8RNT%Y{rqdjcA?QMBd&!90^x%GjmYd6 zZDtid5o}r_t8DzcCpS!HZ+htsl)i(RasbFroNq7_#Q{Dp zSoRD($PgCCiX1FjHNprl&cgLUq7|u-Y*Uf9XzzyO-5Av5uS;a3|o zJuG{hWfEvvp|=s$h|WcNgD1tYbp8V4aa}OB6#vl?z&BaCE7-*pBM-aCtow0QKA26; z1faZ(vVOe6u1_8!Gfx+Eo6uzW6;KrJh9~!BC;hCWJElLX@x9jiU5I~tler}My$9)L zksT*nXMZ>N4>#m14F9~7N+VB_?DIng=Wh!eC(De)F#(s^Gfib<=F1F{#rT;a#i2pS zfI;n#N3(IPKy$b2J?ok8Xkb3QSZbiBi-nfm4%*~#vV3NeTl#F&)3SQzWNuDU2eGfr z0BTHu1{YnlW~9o-wdn6b`I(nK zYMU1ajvNu6&pOTz0}J+V(++u1w&Jmi-}XO3?ieZcjG<=Up@kT_jI|LB&&`%iJ7pK* z?Uac#LS7ZJ4ax zD+fG1{%{d}7aK>@cG`%2Xhcp$+8%Qs%A5r8uN1;TK#Z2Yl=;g-fS6cjjoU4%vCi15 zc>J0JSva|HYy_aZ?2_La;)v}GmetR6*v|+2h>&hzA0mHilD3n=H#YwfE&g?#l_H`z z+NI5IH+(bGAew%DiG7QY){I(m5bc5)n&zK~Q#BNzQaxPUGR6~GZAo_*IxB@($gg>- zC925IFFj%0KKZG3w<72$%an^;d6?;OUDU$bQW@V3H5PZn=ek4elGEhDM=AXTsr#Gf zZ9^}6{>%z(Ro9F>@~E~kr$tu00Sa(3TYQ^q+u?T=PdrtRGV&`1mC64c#TzR9Oe78= zq78c+w(njtE^Ecb3aK(t%Q*~dToe7OcLlv&b+PKcB9I%g+;>u4`%7O81OP!0G(S!C z=wDl!@w{dAJVAzCee!Cf-kBMF&ZRCB%JEA!LpFU#nx^G%k>V9pkeS|%jNNg1^Nq+b zzV?&)a3Vl3E{QyZCaXjFQc^V;JLZdokvOdVtafFjO#LV#z1gW$Oqo|JlCkeXiE&WB zoSm_>19~1M2P=$doa$%fk%b7`WNy_O+#dv(>Jf8ixJ$Tbw1=k677RsH`|)VOPla|h zp?BjYiV&IgcS4-wu0Kq$O8j8qjhLw+v$&4>5*y*(20OHoM8m>bxfdeG3rpQ7^FX@G zII?ES%COuke7#{mUQ`y%%;G(!j6Y0|G}&hoyMt;;;(JHm1LS_H9c44aBQ2LWyzonQ zwJj`^mr3$E()(XuWBzjiA40!Fq%U{rA)#(X4&QYx}fn9q|Xkyz>vdSrY+se zwplah-27x%4mFyf#mj?@l{gMtr5mgGQLSA1X!5$Q9yS0$&~~ILpU9m?bIEmPs;>;j z>AL33wkUzQy{&G(JnLVar`VjfX!yoymayY4hacl90HAtmcm73aV3i({)*~eRrO}j&a(wmB4OVD zMp}-H)ju|!c(uqrdiX0?x-KeC&yXb(L<3cS_5jMuC;3uuj+N;KX3q}evB^JJiIJRj z7m0V1RX_X8RwP#XZi&p3ZO}NHg7Q0$THzWll~Xx=688S;1~8Dl9?#g%1WdA=cGy$B zs)A`tem+u;*KK(0zX4@(AAkuZJQ)m^?bKo~SBE?_$pIYttQA{RF=c7kNz2pEFm;_L ze{0ClWF4;%QMY}rVKY5r*fM}BOQVr=IpiTGS~^z1x-)fc+vR#=tDuws#j|^ zZRol5H(oJ_f3wc}w9b{rFIfg+_gnpw)lI63uc={SyenLgQR!ZZ2htxiS2e|xfH{?> zavBE>7I|x`8#uZw>1Bwuc5SP z>wS>sFJ3Lfq7(5br^z%=cOoMHB0J7)1QSq3?*zBwF;j$8TOLwaqtC$2MxHsE+y#?2 zW#cGo_|k^%AR2R&cO@4lIk4^I4B5}nn57#rf{VY}rr$vXT=sy2IILh~nf!9R3v@1{ zyJ`~qxh4l+BYQ@Zb7Wc9p;oL}Qh+?s!VIz3 z(?wJfFBTraoP}6+vU%94c#8lmx=OVGJbv{RhZ8CzkeI}jQPMLeC9<*%@v`=pqK*S5 z^(9!$f_3BN@R`ZjD%oaD%~=EZ*3pkn7DZ0>G*)IM+gBscG6!qO1)3nW(UWKLo@boC z!F)-#H+yzBGg4$aWz0&+;(qH=#76>`b(N>Qh6d|3;cz~BCQ>%UHAL>ZmebZB>Q(P> z0YMP7GEx?y(?6^A!$yyMlaw-f&FDOxLZ~^(crD29ta|CoQhDBWsE%?5O>Uuni7i*?)afg=dXi56pZs@!_)QpoHLDVy9S7?zj&l;NV;iq zT_Sp{=rXDdl65>FuWWIUCT}r(!@ty%29h2vQiRZ)ITL1KkQqxMOgU}Pjx*wID;OH- z4TV=0=i`)q${7ErSH5*2Bpf z)>^rQ{C1Q;Zd^+7>{V)7(nMGGVI zHoMb3WmS=r-hEY=-ENt}HL!bhDYO38Cu6Hb@1#r9{Mzi*Fp{K}4pSFy>TILzR0ny0 z&Uvi6QJqA!@>e7KZHC=Zs-o#ObD8K-kB)Ns+S1&6u6W_L>-U`jlng=8>QZ4;n`X+q zeQHW{ytw3f$m^c8FOI<-+|#VFvYV0jzBDzmUIul3KEB{@^bpThzNp5)w87b&5h2c> zLmncI6*KpOANe$3s-_VL7>4&U?d1Sk-jw;+vdW zBGXGj*XW~lXO1t}_Yv+Txy@O()8Ejit|B^#z7csNrpxFzY|9soi8Ch5Y1a%9xoM`% z{*Jl}r7NzI>tTz$kHperTz{sXI2);BA!>LLHyW!Bzait8HtACuKzX@D?^x^R&qR;A zJdSa5vfd(kP0B?Li9U>f6m;USmu!$dvl&l6yCYWmgf~>Tq%fOdBG!plN|`Fk<39+5Xs)@AK(-5T`iw`NPkL8EBBB1)HH> zWkwjXqwkK~M=u&Lv~nIQ>ohEPnY?_8J@@2vcO?Wt(AtsxbIw(us$rZWkC|nOypM|8u>tA>kwO$ijl~%l0v-fcJo~~Zb74Ff-oH`W)LjeGb$(MF~ zA$(%cstOAYkyBq_f7{$BMoCvpZpIPee3uPVW_))g;tMm0&&P^62tawcM7k}xw$wbIja4+M zzT?<qYx*TQh=V^Kw1#H0-BoX?odsc zWBs~EHqVWje1^fC&KjDEheWpN%{|>vndy)f!gI}}$dq0ygBga4A?8!O`BHO9)=1h` zsdVQR>p$^*)YC>rQ}z-<7O}r#qJyOgEpIOxpTzN=QW0@Jhl6;udamBghD{GF3g>VRhAZWIl*K713P4Y9$ zwJrWiHX44pGG<2sCJV->U$S*Ul)R{;i7&^vg4DRTK>({jRKFd;uomQ&yfiuA@SDnb zkYY6wQ@WO*he(L@u)!m@J!Z=_2Fuh)Ro7OXy0IaQ-Sq31I>h==3M4ORWco!XyHy?v z=qo$kuZ=#Ww@z5QC}i31h#nO(Ov1WftR&bq`F|?bV$X1C`-Fxpjmk ztoW!RdlJ3p2v#Qd1B;(y&5d6ERHv%*dZ9i-+bvZ%UU*uG@knj+W))xCR3WjZbR=|- zi?9_QKjf6O(~AKHmf5j{QWFI~4ER!jGBgj)Swtm_GDXn>?bMv1Y4vCs7>7~bg@hjn zrQ=TFX25*R z_ry62Xqnrur=sNMU;`qXU=C`M>`Hvb)!;WmxIJ@Nne6jDbEH%CGL!e8+3-7Y`g<0F zAZX^QdzIls(5Slk&U-o!zYFc$(tCLXmYH3YQH>9PQDL9a#~Ynt!!?TU*@d|T3?`e z&*oOfI)s4|>LJwaMl3=skr}OFbfa6qk*%E+UOJ;c(D*BI?cl-{6QFZ?hwU=#%mb;D z<F#3ZBg{kq%FC;4 zA16K|^0C`|7O}UaA5+j{?x)Wtabh`01e1nCpQG>WIa6HIvk*NkeN-k1k#g8NC$n8M z%)V>_PJ*n_P{x)cqMaKV`}1eQMwQ&7F>3`-%fTs@(4yXpS1eJERD`Lhu53>UD*wa7M_zB;A&1w=he z_LNQzUSz_=x@~AxdO35$TTErNa%mo7Jvj%QywT7$N-RLc(%um9CQLiAS;)r`HoYQt z_wI@mc);R@yd{|q2m1cmp?XMrdoxW@qp8}o=I#VQwPN`MnjDNdhgN8 z%D4IbV_#8g)a^OB!af8+(3(*{>CMh4hL<#D4$z9L`tnuV99bqzF$=PrYn4I z+hjV;QQ^hF0W>-KprtuP{zoh9GNy-gWSX0mJV%oW9cG?%eKlE+xMDo zzgmhY>`;nBe=p3zMw$?Jc-B$FV3Hb~r?4t@Vf-iFIX|5N19+=smtjE3&Zc-I;j-^2 zW2Q{0v7bVFry0bLV=`3^UNUHx>CeH*e(;TSNWMbyd?gP@Z99fQQS;k#? zfmv^{E~#kNe4K(YGW|KfWwxB4kzR$5T(fj&n1%AFiz(h|$$P~pzaiqpTnl%?GQUtP zH7lgIz2$AkzU){Xe!*8RXx64ue=rzcHZtAQ@69w)U>qDat+Wa!!zHUH8CNUv%(e4C=?=k;7&O^?c~7HL7f1KRE?ksA zGYI^J=4V#J6<}04m8gEzA;S2;>Go-*e^+^JTiej%ZVLo2NE)ThO6_INqG*qO@HweH|jBd7m} zWLu_M8O^S44SS5D6giG)D(jekZeQVG`?G@@l`_d82!f#Pa)iuI4=0SjIvTI7e*+_X z*4tc9q0wvV>n`U)m|_7wNW^Cezai8Vx znmG+mljk^P<$u%BxErU8uIO%~3-LAaXX>ZcG*0A*;Y7yfA}K;hMcX9BbbkdS<{P9V zrW>o@RGEBSFzy4B-OxLOhm}%gf_e`Y2F28zqG#lj(@r*uftfN=Zz3_ff;!`3Zpk8w zOGOkTs1kkK<<8o$qh6&J%0K`4&!71CCth&D1?QZ5P7M6u=^xshB}g_Qr4(OE&JCFx9Oqp=rA<9*{N%J%&u;6WEvzYJ%Ll8vM0@5pnD zC1jW86K<4;_(+yxi$Sl8>5CC6Xs>;2Mt5c3SjV>m4$|8Slkyb(Sr=-d1%tW!H1*g$hRc-iwRNnZCV*yy9Fn-d178s$z>%G%c4+mlwSM^oviW za+j!!6{C_4$<2`IE=?>AkjYa0BHCK3r3Ap#Tcz;r%-$7+rwc*I0w_%(F_@QPS_(@Kiy7nI0x9Mp zwik=WN-k3M*d~)%Aw$n8iELed()NqIno4FaW)~sMTEmY^*(^@xUu#5m%XqV2<)oxdK44&Dq^F$H-?8I-gBQNBn%A`xAE|S= z;42rL_0MOWbn;2fs!??F&AXEi=1^G$2Jq$X)Xcrm>&8_=-hPBwmDHCp8>BThT z#6A;sUh2tOJ|<=^dr07f!VWin-z{Ntf+hJlg>6C9OsZ1gn^qn)PG2Ws%^eD%)Ka=f z_E?Sjx^O=ba#&34rzLa!ZRRuf3@zeg?vz>8QC%u|nv=V{urG&9ZrEZP|4#d?k(m(k zNXM}FFFhYMd*FT;#L$=6fgECGy?`{)YJdNJlfAqLqk%CoCnRh zJ|FInShTp5sVekZFnpYMc`-$khVt_0umn3A) z3X@KCc|tx9vS_l;Q71`dveKm$v(G7ISR%zVU*Y(emFta5b2OQpNQxY@Ovo?>G9bwP z>6+mwkRStb0_w8czXXes$z(0gKEp(fO#adYkK`7ICptzYQWzFgi)%o|_0`B~QPI&Z z?R2625?S^{*w5p;rTGM*_RI7UrtIl(W8&ku*gRc@k2G`iyXhD1V~h2<>Lu^V$sq>4 zdZLR7ep_9D$f`M2_G&Te7SC0Gw)`SpzO_ThpLWgci-cS>Dbxt@tRU?-2525gbi3?*OAzb2EhO;mnLkK1Vls3CGOrSHT zAP^iJ*+ zzoSG?-?Wp4kB+_r+t$j&qB&$@QD&DNt%`L~q-*9-0>7;M`7-?KSq&@h6xHp+5I5>^ zc|qn`>6d4G`0D)W$g+JRqiSZaDs_#XezQUkLI{E&XrKm+*TvtEO{7)xuxP7&BJ)IH zB9zU|Q?<$rH2a~`83wY$vTM{fnNGn1RO1=*-|O*EVVfLbnI^d`trgSAoFAe%kYt;4 zshl`9t3wq{R?G3xlnO7Z^OM_Ltzu>T z1lOA^q%g|-PT#MPKyNc1Xc#Y#pSwPigKz$U9G}#rpHiPgoStPzWEQGh-MqfiPxOT7 zS}fK~eDPHOu2+a@yTzc}Vd@d4 zqnc=0IeBgxCO_OJ+JIQvz*)LW=2VqpJVCEGtc@8mk}HTXi^O7bWSlCZ4*3v~Do>L+ zH6|JJaLF%4AUzw#DTU_<(b`e`)iSv&40AJ0A;>FQTm{d_P39c8!}OY)m<9vE=%*r{ z7X5v>dz%!!EWT_eF6^=ji}eMUsNK;VU-l-+9rTI#IACR8^}u--pw`!bmw6 zPSa|!SCBgSUToC8`~)4J(~7ygh`Rs%_BsD+=QnF#kswE=LI$10Tf)yJJjZfNc*bPm zRXIFM#_zY$e-6XT>;;~`$cwI(OtS3b>c;TVYkO#Vq-XLPFvqAav7JXk{R8m&#GL0+ z<{;UGWVsZ-$$w}}BbWt>TvX{Yy@)I*ARo-K2u8DG%~sU4PrRx$rSSWK4wHvZq{ay) z`(FkTmlrOA`@-ulYdqsHrz8w6+@5B&3!fab=SKI`b&-MD2)*oBR=7;UYNR`an%Aa^ z1&3fPor;|Dvit?xEz|pa%h$Z>SgD~%qZ=_Y_wp1<7@iE}Deu_HW6u`UKDIUO{VI-+ z#a%DS5rADbZ(>2h>FLhWLOIja<=e#FAbM~!;IcazV-Vxqnci)3=$3ZM)n9UYX>!F; z2!fzhAo3hr4hiA_t*9oy4C*DZE-T8`N|n)Y$qb1Yl~jg06)-0^l9`%#S7jxup>#; zhdSmIs+7(o#P=2EHRm)n??ah>dN8b&>9rEQh$3my07hWfXeY6pc+%M8y zjUir=6=_r)mAn}`k8j5`LozS-yc1XCqZ&0|<(_(moHk zxzGEb&wXCAN)>F2lP~4aQ`|t~$1``$g%PqxVPRZ|X3OM95bhThY=j7Js_BBKpN5!t zsp{31MCpyV$gjc1@9t@fS7+kC3>31>bEnKfPDUgWA-sd{<<^VRNh}aq3NKmkQC3(W z%Qj=tT~r-Rtcu<=@ry1W5(QtTR>{%jMRE&39AG5wW?Crwk=TChlx_ww3mRmhtfQID zn7fGm*=DbYQd`{e!;iR3@^XYfqx>>&C4AY=XK+y$z`7!IFH>x>C)X9tC3-vAi5)do zDSB?n z!OJ?(?+v)ZnIXaQo&iA+wAMAv4+j^&xCPRxeW-BgsZJx!O2{-sB+vbV)+&p$Cd-nM zQ)zGG>}^me`%GYp5L0fj%+Jr@W;725)&yjwOtzjT(>RIDsZ=6zDyuEiD_vsxSVMI6W%pTeQRwB67 z@!2E~JL$&nEX9a-oj6#wS@0MBO?{BoR+=sQPHOX%X{Ij2ebksohz)l|n(}UG63Pyx zCynXqU#08|q8Nnyld{aBVOr{_#z>hTQ`@{O!LzI+0+VRNWQltQ7;n;gtFPGHEMK_1 z=z2x>C%S+M#>muSnWT!DbdP@bXI>V{Jq=&wW1Z=A_9;gaK2um{V@%#e0{a%<-WmM^3|3nI0g4;bWb3>&DR7NYvH5 zc_y=WvJF8H1VQv!w3yPrr!P$gN<=t19I*2#*d~i?*z}X-qYa!{2?Re&6GzFqBs~?z z$O(IiXq0+!v*L7UI87eoV51;rRvPdg%O_?|B18Zfo7`f}@|x%dP;gPb3dEf_!4$!c zmr%lClVvtzB!!3lI86<&k^TjbE#DU``1~B(qhC7VC39Ujt@bubt}-6`lC0cfco7P7 zK%DHPy0!Q`G3uOMBxlOe!A0_??5~;W=7M5n3m=o&JdMw;t(wqlJA30kWPMUx?zY$| zbo1JAc%G~pRYOnB@wO^_WJS~vif%Xprx)cjm+2GP_J+`7;wYyYLtoQY2q-C%obc{QBw%D{p+f(7J?&9Y-eMKh2P7hrZwrVw6mkR6s?u> zM>%RS0tYS1m#=y*a^<>bW|Ml0SMvBXjEns@mvjTAI3%1d%2#QjEGId<)@)Xqp-Jh8 zy1sV%=xDkD=|!v$nSs*jWNnSp>?-|EdSgu3m;k z`NAAORfDgmM`yIj6-JDf5U_2bOvWT(p{%bIyS{1mP3Gg_fcUa$#VMb^2vRplX4oM^ zAQ_|hr_tya*>rg!ZZ+ydna%Bt$X3lD2!bGJ8MKg3p0JRZ5v;@V?vgE2<#MrOo6ZQz zSRzi+*wTDPG?j#HYrsY~*pxQ?z*6|W=%>k61W`@q2&(MZf#SR{5CxNNi# zt#UYt^5u*()AT+T-ekkX%mI?H%_nUBEhS72$@GmB!LGXSBbu6oOq2bBc=26GnkT1I zkL3jR!}@XXi4eV8bY7B^Z;kOb`4PIeP@@yHtLq+4z%w zZ_4aFXHeHT3HpdHY@r+SPkG(HY6!0Ah(p_A!o>705`AC()Se#~zc`>zisV2yreKg? zB7g4Al+~>6uGVNu@H7DrLmQ%YVLYWb>9y-*2t5`P_zYy6#(S~M|syH*JpKMMgD$A}~x-{{C zSWS^aOpYa0wpQED-9mZTqI{zXa~Ryz$<#PBFKgQK3D}&d-N0HGbMA%xrWeky#buX%{c7{;o6ljA7IaLC_kJF@2si zpZ-kvTz)ZR&iAZn_!i08o$5A`_|RFpjAs9~p1)X79|v7XT5mYS_av1AHpWL4028n( zl}O2}={lK2OUao@v^_83hjC*^&6X&p81MSY}{FYaN*`1 z!*3^I5X0*mNXXx^4tky7rgP zXLcKqhbntetDCKO7S*SyEh0ro` zfwXvUv(Ia3UMxMj^-jzREn&B&?$T`7vwl}0EtF%_%*e@aut82OfPx_if>v1DmoMdM zCmt)LJT2w$O2l`p&Tr7UWp^-3aeNBFl<4#)PFMsaBMB*OVgO9QH<8w&${6Ei zDyAORWt@vcYi0n3!w_MQ?V zq|YnV=H5(VWFo4>-(J`_VTqe5+S@cT{j2$#=%BjS(hZ$<83dOX%cS7rH=37`am0Vw z3bfP>hvCOO#7R#yMeb6j!7BVxB8(I1XUplE7h_nGMpBm-;a%G&i3ZE!_rR%KmbU_7 zGL6|b@iS%o?xt@e{X-OOgiLLXiQgkqjJkrjkc?)HipXPCc zmlqpVa52%s148c+egwxKVJF{^iNcW~bF=#O&oYqkwY86M0-6=)A%J-4D1ZprO zV;mo01x-%lu=In$hH*AP%Z)<4jl*T@W&mjjf}klBhHh@SxuWWS_?eUERW9L8Yk2CK zSl0VvPd1utak!K#IWbqog+;~^(8VyGN_0@S8)tPs1H#67X|gOT1DaWeG+38z&}6}* zDNXj^lcPX#R5ZKX%{4qXHFNKIZnhd`Odf-TNnH2W0hNSATwvIU6VgD4S%K=cJ~4~* z%_5Ol|D*F@U7tRAxHnE8P8Q;eX2of0F1%j2Gl(uMLebrFd|`g?jg-?pVEDd>myWI1 z=U=ADF0)*wbd_>y*2lvolXn2=TFJ;iSjh|49Nl81OF%wISho;2OeV>B_m$CzRladl z+^>8%kpGa4k-C9dcXSs&T7yP}5V~Fuo34SyxkKT_#m>{*oj`DTv0Um5W!*3l-`Yd} z@k2s@2jSNXZiI--i1`77ICk|veDEL2{IC4uG=ywN@?gL}Z>|-1GG{0uSqOLFnSVW@ z9bKm6yM+k6sZ>a!#Uf((97wWFH+L97xv?@~!_rNL$&`6DIzw}Q zmd23Tz_D1Lb*>%AsTSLIAiIw}V_=QNW@;Vd(vSn`?jY?<(u*5FW=?i8b(%t|#fyY5 z{#z`ZT-W+a<~o?=pIS9CZ(*8%Iss4S{Nx8LE~XFk-JV`Gc3s3gpTX`--w-94F^4JF zylRZ98u|>l%p;}<>OEu#@D<;6Aqaw?i8aujMfZk8RDQDxyf8=k@ zTQkeZ{1_tR&J;2~NmVw#EV3{+ju|Ty7h@!*MW)vT<}t3O3Q;i$j-!VtkK+jwAodYV znjEqudD5(WshR5W(^nyV6d@4RFpneGGMOg_y3&ylpEl;GTw$al$ds0^^N|p%n?^_U z5S>n>^{>0M!IIf^!GOAxgNx|J!lfZ5$;m37dAdk8Y;MPCD_V zW+CPMy2e#N$s&5);ph>ExUTTeIB&2_Tv@~`>xZ-OoD3dfmCFmsaw8xnW2)cl{x|+N zm@Sjyf95kCr`a~OweW`S{jt|ig ziR`lNqJ^>#5Il}jw!$N$_u?B7Mm>j0jXX4Pc$?QNw7LB(O`}~rmbFkea?mlUDj(ZC zx0SX~p0En6CD`i$xyfiaziYxAn3!S2sLCYSXsBeTOfIKUC6Yi^+Pv07+F(@Q_`M&= ziW}i>iK8hQR#}-O#IjRX_QmREEp!=k7A@S3} z&Qj9k5Y3;iRT+}5+mi2BYST9C3R6mNeN5+^%KWnn^fV<++z2D!(c>PgPsrZaJiPWK z1kvrtix6EE`?sa|BSGiBG`yL1ucBg6K5q~lqB(k-e$?%EgF_7eyWHp>L;Ai5_H}Ut zB;CQ+(A9)oD8tpVD>&`)^Q9r_<|B6?_eb9SM?bqLTVwHQhTI~lH%TjF)$3_l@t(<8 zH~ZTlN3lt5co%J_eJ7=BqU$*2$3kwEbM}fhXRRie7Y845@CQ%-kXw}RnSc6ck9_na zT{wlv2On~9vzYS6$Mo0rjxW0r(Qm|IBm75popoq3NADjlRK1 zSz0I)OJuUFr2E%LByZH}tv_;VUbtCF`O0qGMS=qJu|63hGjAA)*r%C6XcIs95|0l2`nZ^|+ozLnC$Uh@dTx;}l1q`9-(>3o z(F7t+=A2S3dt}`(nK@U+JlPx%(^zSIY}0_)*hr3ugjJWg>wtJ#UzaOaULnoMxJ_E-VVY|Aj#A#dbIGq1%lUz z@&DNj%%gx{%N)+0y@S)b8160tx()S?25sJ*h5H-k)9HugZk|4dyuR`g@-lWDTvad! z%JCJ}Ukc~5BIW9gl+zTPeDvr_^si!}4swI{-*A#8gJo*D&MzWG$@=S!k)yi;st)Pq z(Isjk%#&-67NWvNeZpM@wFF;ja_Z>w&G|gH6eAY=PGc#ldkzE{@?bfYZBW_+0dC1j$k!lP-D$GZzVL@1dr+=H{_q#*&equdamLETNZI%C&UiU=VwrbHLw0GIqD2&Hi~or6M?z%s zC;hI3J3aPG@ujWqf#b}VSv=c^a`Z{UC~-KSv;Z)LI+BZJPTXd)5@^ta(Tbc?yP}0M zd45X#kzp%&%ipJlU_i;Su`I{>{#t4j%+U3M;V-Dr))3EM{6j) zSoDZ;C*#np1H+-2P%7Q`&1)nEnsk^&=*dLfDmm3mL?=A+!j)PsJ7v*~x+O&iCS#HR zLmM_9-V>P>9qZ;djgimj5Tat!PHp-+e{NR~m6aR%bKS%ptC$L|lOYI#pzTZ=D3xP} zU*(3Gi}j_tn3d_pLi5g)v#6s2qB=wI<9V5@xvOX|tr$UTglw^52yEkrLbf3wMUJqH z{8nht|`N18=LJnVt>N~E}`1ML_${1`RB-!5Au6&9%3xh*Ii?h z8@no@7M>o^`FEnf2^MrH!BHGf72U7R31p1Uk;9aodBBL)$}RVJ+O=_D*}*-kcbDNN z@L_>I=OQDSIdgXGnksn4kXV^Tv;N9m1(y>_4z~q$o!r=l!yy&#MdH3;M)Ou=Vt6kr z;8}de2s*CdC(p%rk72cwp@mVd0eG?NT~!K3-%))d%LXT`mh{ahc3&ieC-sOpKDO zC-+p3M%C_pw{l&ynOi95TXG5uW#i7uFTNM2(&DbqRG1f;i_B9oRW(=kj!^!8a)Yex z4#-GCIB$$kg1AZY9s$m19P%w3LrQSSjKXTq>3!P^;z0f}%814$G5G9SfGo)Oy;W!^Bpa(qv|H&Fq)i zDYC#oCg{1?JkB?>42~1sV072*yA3}D^Owl8JK|MYJHB9R_jPen-{M_^HDTf~p#_OY z3+CV=;aUe6x-*U3Az<9DShwIFHAzmTIF6i_k{-&6pwKz~N4r1IB#8R+ z?*16#MUB`XR~YWZyE0$ktT%p16U1Brp!{b?KBG5|V8?^Zjcf8>2?aJ82(lYlk|nIS z^>PdJxe?HRfePawT^KY@INV4jE`9M0p1t=HF6jVr@PFYsGWDSx%#+g(d}ASkRMV0} zdLOH61cR)2;vUn)bM%3%5u&%E5Ec!V$xlg=2Ml7b?DL_XF2VwbMVA-cZ-T#McBModPHUf*@!yq`xB0wX|u+|JC&C7Wo75%2Wo^EhnetkfqbCtWp>Q)-fZ%Rfh<^3n3}vfCMRhPSB15RkjuziB4N9 zno%eBkkVRNG>^t_Lf(Ry{btmA6OHVccoI!-&x$PjX>#;7n$E2E4svy1yn-xkM`?15 z8J%FnUH7UMEv4@K2EA|g{KRD3Jkoe zk12GQ8k-A8$yCv$a*D}&CiQC}NO6jvZXllbX|sa3UY|D(k7mr$#f7^pzQF^pB+L25F9NPA+AO?yQ)_lsfszaKnC0g5uoj7gHjJK2;cLO4D#OZd)kn332UpFJs9Ou?QJA=0l@8(vt7 zU?0+TW7fyMks?$h=gdf3YrDCK8?iNIm3$kMvo#=NI_hUia`u@fQPCe^=o0=7-dSog zPSDK`lUHTRPWVf7lI~;_se3jMe+5k}l*t8jmGThB?IrUz(q`P6IG7~+Mo5q}IcoGs zG`dcXR>^5mz5tq2izez#X>wrJ^!5-~oY~vUPRd(Hb{zS-!2cszu%-E|B3N9W#IQjo z=s9}25I4X0IwWeP5Hkngi_?x5kzoIaj=KCOj8Ibqfb##Jy?+6^ zugmNDz;mAF@QUPqdBsE3QVCbnS8_Yo2G-xWZW@w6Ag>G6Jq?@*pmrI{Bwb$?V{ax0+ zoZEAr=UKn^|DI=G)?Rz%xeAVI~x0zvQkg9@TX9fPPnn zA*+pYvok`b9P%|axiEVmj=akf=~4M~uJ168_^QCl2}^0@x{xyM;njF$o-D88 z$R|wS1S@gBgSglxisUjYl(7gw!mRn1Le6wQh$URyihimYjJhyuyFwX~UF0g_>I5nV z8=>7@q~lD}%w$y;zuG&Oj~RSfr@R;}gw3l!e5h)x=Xex^hOI+AzFgKV?h^NkrN0Z@ zB67~0U*uxDCLaa<3WbZ>WvZH7r}gKHGO;BLQwB{QF=E8aj^eKSyxhv0!xs|I^qMlu zWQ>N{UCTn^dKD3B%Hy}s1eb;-^eNT!!U4JEHHVadrR)X`wVh#=DD$kTUME2kT9yN- zGvLYX57y9rktU;_J3&J$WT@b3hr9b+!~rO=1HjVqu}5JYg}JIAr(0$bU&(O*)0f(UAFQKcV2ZRM%M28>Ly01-9$;8 znxSi7g&(m$Ks!g66&ijEAB>VOYYB4#JmPE-Xrg|@;i}>#();wij-MSb#g8u29%p8#*|w^uaN+H{virw z8Wx&t$wYW8bE7;Na3;NTl2g`bP%M~8@4bEy@#F8 zsu$I@dt1RztP?zUo)fryzR&1yQ-1%Ej{?XeA!fWW#seW$dqJ6JZnpgn$>+N=ie>Ro z*{zH65D3lQj|R)*;xyQy#-SQ#j=SPH|9S`Eh!G=3Je?rX$BCEjnQXfc&VwSZH}EarQy(r8 z94)X^s-g``VTJ(#BZu2{-7RpdF`>%}fMu={R}DICzjU9hk_Pjmq^EcD!N|g7vB4By zOhzyIqgKl47_Hl#eY)IqXSnACN{Gf70IpV7R0=Eq)f;)$!=mun+%5EupJB0k1<|_c z1ED#*y^97Hyd73T*aQz%{R$j)^#@AnQ_Q1)dV}k+whe8?GhDl9PM(Z=vYZ6S(nxbL zLJq++8O5#2y4nB%002ouK~%`tR#n%$w{}fCQHHDDLbpdPQl3A3;@tRXxIMS|7(n?( z!SBTMuZWTPtT4@xb0PQ3hZkEnASXN?#xEL_soHvD!--G;1+NM##V8q6$)a55p#Y8* zbi$~nF&Yhp@Q?G51(dgQB)C+ZkN8^1H3Td#SdMJ+Wcxx6`sXvLvUbF$mZEf4fcp-C z%kCVzQlT7}&LUP$?AUgb%Orr~P9|L%f}B567{5{LIr1!RIn(kYtO0MOD%`w*H7}|) z%Mxxr3omYXeRp#ndS1Wwe#9Hr?i#G#dV6qw6Ws#Ux|V6>nSnTQZQ}DFb@!CFN}+6( zrl&`l56j|BanZbef}-)CV0qD9yj(U!F=tD&&lA`9Rz!Z>pHofGqc2-)He$qx5i#OT z*LhFdDq=kvK2n$h`4un=5GyIVXiWr6~Y1dF;uwF7d&OD#{}*-tpVPsHWytcl3JOw z1tx1EV)VNZR4N!+r-%cF)VJxBZPfsgwM|iV`h6vS7q(HDAj+Jv#f1TA4A7;w`0t!0uJTh;%o_9bRAt zP`*{PQy9O>lFmovBuEDevrce(&=aQ{IJAcSAnq7Ey?@hF&p`pIp=5!@N{xXp8(G%r z2%32oOPHnj2{FKL%L7iE6;u%%;8e+NI(R4>1+FYFtOisPK_IzR_d=(9@;1>Ra;tIe zK`~WzcmHQ_>^2h03iK9>{y?bXkIc@M66h71Qxj{c&(nPr>a9`y1euvpGYzuaF-z|+pM1BAwwlmE!y-MYivD9G+D^(FZi&bAN zwS`(^(=1zhgP2ZASXo{KVKQ?M_0vG;49#Wk7alUyF2Y(!*YyJ0h*4dsmgt6I%-FJx z2M6vJpJx&&^UjL@LaI8LznW#EliQDIBZ@>azI<84@24cQ+ zl%$d(><(C@M4$a9jbe=_&AbS;yvBl6U?c3TExsnHisRGx-0GGe4winU_V(H(51IMs z9W2G!Y*t9TmMqV`it9c6FA{<0hzv%I7%}46xma8_dNUDXr`frFWqqt z!m%k_&v7A-Jc2+rWtgB;cxv%lW1qK2cd!chjYTZLTjFq75>EuJ3e4=nfHR^v;iUe? zGtp#QVW^C_x^mBv;Lb(`1<*a;5j~U*4f7~J3X05(vtz-sBIWj=Z(oJaNIw-wm`{mv zVc2A?T0#h|ZPKrOmCm(@nAmz{QnDN^FL;)#!ouAnSOo_a_H(Xsa6=S0wO2x2?$3zqll%_0k0 zN03~e<0+@SB3=KbTm3A4wHQG8Mu8o|P2)7I{qnUW^&1QBJG6X7ZgAB^xX@%~Kh*-v z$oX??XJU*rS#U9$Ua%5b`|J~}?2xgo&HZ8;S-Zds2O&_btuGMyv~J(D>?2<``+Bxa z(kq5_$_H{}Cd!DJO`)t}WW4@wR46Bi9AQi37(kFwE9~fTp-?v43Lw)FD=&5}<@d|( z6u7)*?jNa#f1X$yTNnbOe2JIA0(=8BIHK3lUtEh)s*6H(<5v1UfX(SvzoS+MV~)$r8CtA ze4Njbxuh%3go7rJ7%}202J}&K7ojqdD?dJ;7i(_AUK&bX3s_d}*9@{E!YbGfO=tc$ zd$)pMX<-UZ2l$rpo4`sVTLn#?o#JP~eVwgn-!CWVHtm>3ds;NZKnbW)JzkYjKx29O zTg#K<{z*4l@}MQKz#h5~9|IL=W6gJ1k2OjrpETReq6vd{bCI;;x<#PdwGClOuHv)^WYbmET(j= z0^Vp?N}q#U3yYA8Z229EPoGuHc+mI?I^ygmhJfLp~?XTptJ$&(2{@vG7xrbO)XDUN|nG z2=>$2Da9VKyxiS(xSsSjq`r5;6U}vZO?4{E=jZt;3(m+10}n1dV#J7-7T0FVa8`C= z$+`6WoWAyUqRa-nW3fDn3*eT^*$r>Zo^U`nRx@`Qsk5tnSGMeLMqHkuc>t6GA(59h zyA>vUBpA%C+9Aj|QARBXU#Q%I^>!}{oYO2=9nwc$$P6o75ha-oTV}8Z+hRw^RZnUX z<3O2R)#hyrI|-}HLlNn7PtFtk=-yBPgMl^%{J74PN*fl$)@1)|MOKZN zttYdXlViIu3ztgv7p7ds=~QfMkZ!NqcDVuAOt(3EtaErLWg=xUYvl}%AQ=S#^MztD zw~Jqa22j3TD8nSD-`1R_6AB1cPWNU>@8n6+yRDCqB$a8Kv+>TFwFz%5%pd0#PR8vncoxtuaDOkVADv0UombTMMYh$kM} zMak9IBXmXY!sk-ME&b`M-!eV6kVHMMd_;%!O6C&OG@!~rFJ>h=v= zQCPu5dk_w-VN)T|%K}RriJhBLR0Jd_KyyIM25!RuZlaV#a2pDpt->IWpjpOWtX+o= zJDcN~x*j5wSGc~-<(+7MlZ1`cukA!4$Sk(>_d;Nn%9 z_A-L0vAQqVrxy_=OLMZes?b3ld0<`kDvsyXC&>a-I+3!%U-q;Rk@Bo+!Bq5Enw2N( zaA>YSWv?X2>#KUx9$6??EE-(E*W}P4r0Z+dm1O(OM@7cxM;9FLSF4y)RrgSS7AehOrj2JOu#PbUOt@*t~x&p4@8+Q=T{Mxau_TBUD zhOB|o^j8E3PUM1R0@Xpsr3#u;uO`0a#wrjGDlTL23ZF92iCfCWfU6XCw{x_fR@4la153XnX z_1;)(?X@wuz8`lnopM^5>$TE)E)`vNZU)H6@|fGSvX9tdo)E}jukZD5e?2)1_);P{=Rp%uq4792kd=F`g4n~Cv@<#)cNu^hoZ~21r3~~a zf*L_DWdYQp<+7$>8XR!|HMY79E|;%~02l_?N?+nAu%XT{i;kgqa)LaiMwC{K&J`` ziQ;v&H{AFdk(%^HE~^QGKAGmYBr=-~^6gp`1TQj?`ry*m367cs(#7BBo?_Gjo5J-m^dt^;Dti?`d2iR`>4O~EHD z_D~Iijpw0~6%h8p#ZlEHmbpW2hN@kHrBJ}1zoxx0=4fL0jBs>SmV^KT>T|`Z=Kya3 zp1QWbL55&^T0uSf{^@5i6gEKq!dz-D=lRcb#d3nRTiZtfQ+^#xI%Yp;H*&RDW;7#o z+Alc9&!Pw6jL`8<2v9A$8c2TdO+~}p{USqC1i2Yub2hrSWwgi?aG)mLDS}ECO(dzV zywx1yyT4OVyEKVR;6PYx4{@%cx*jQ0~p!YwI<^r4oDoNy>Q zkoX7xTz$2TZFjn@aD&)TU4i%`<&hj^2* zs`m3?Gj?sRKBK<&I!AR%RZ0s}D{1(>7G-|m+>vub(LgL=e#UCTfGJHvuZ~F=iF)Yc z^NI&TPEQqLQ8&JtGDzF=9kYQvG}&vUe#p`xqbo|@^=H!*n&?FsoJ}LWQeMh}Rb^PQ z{k?ePos}yL?&N8Q?BlxeG+z|G%j+S)iVARm1gP1BF<&(upfS7lo%kHGUFGy$w6zLG zY_l8obewp`vtCV>bvVP(oO{Nv9jAascZnd{@fm*#AOn6jxlJT!gZD+l!R{bTlFY*)e`335(s5$nYTN9&Cr?w5cCOh@RiNlFY&j%lHH=m5c#j`C{=f zU{)h(yOXvJhDwFrES`dB{4+B`J8#y?szseu+1)@&;`3y)OO10moQCC}>pNxGneM{I zEdu&#UCbD2m2mcXqYG*kyI65d(}bBh+edqOo3tjQcNEEb)- zto&sAK(#S|3a+{d+l{5buj^0zRo69RUX~!sTAg0EO{x8@_f}_Mt-bm$#Y{XF^4}4Z z{`BPaZI)qo8=;wYf&0H$s=aH(Dh>$DjX-+;9jnk&;`5Pk6QElXy_;uh@+a*=-IHi8vurdP!p_K=Fk!>4ri+ZiZq@Y23;ws;4HdYy zR)4U-^GAHb%!uJK+M;YRj;dmC&y6mY`NC2sBVBjmE0V|kr|LZ2rYT2isv=xG@)JnG zkm2`AHazP^#3YMQNmZudnODT`V&8FRA`7N&<7O`p%-BhHD~OizP)uy2AsfaQLVq>} z2Ky$~Q2xxVN8n!(YYgk*#=#Gs&1-A}a|5v`B%LdccL6(IW7?sp{`9E)IMYpOxKf2T z7RW7DxR=2;&CXQ_erx+i^HAs+q~gZHjIio5`%@wQsNt7BpN=!`IrjYS(cp#u&n%U) z#>goU6K2_)ndJbT8iK{-n2V1)OU=q7b-ZndCSvk5lJm)PzRA94{d)n2fY&JG>l)wj ze@R&sQUpJ``f+J`ngO`AenHKFA-@CfK*h-1DKQbof}zWT{V9^fG2o;dNzyS0)rn5;^g4lcu`0;_L))$z3!+SC->6_h}Yqg`|i z@qXcPpYIdb!aCMt(|vq8)v!m(-QNaqI|Z+dUBTqrk}^#V6V{U`?UZy!H=swLi=4(qj#<61BP= zt{he*MAG~l)U^@W)HV(=>2g?7^Mq{zP-O(rJ=15NUZs_Rw)snsm+=^5#5?Ra{GMtr zw(afX=(EQL%^I2dFIsJ&2|NVHPXxD?*8Us$HjUW>V|(k0ESbue>9V;9o2g+MO=aXC z?my)9X`)!3@NMj_ww=O8^`&1Xi(ADbu>Cz@u=s%~w8l99TBZX6_q=vlA1{|Rtqqd) zq>ie?yhMa^4iV{0OGv9yqS($bYFia7?s=+ARgr>HBER?N-J^I9+v|EjIJ0ocu@#e& zIXWU1v>tYe9ez}QNVA(1bxxIXj=coy9w&#=rpKK0>0%AWlEys&hU?c(Ub!K9UVn6r zC0LN1Q5JC&6-b=Gwag6po2gt|gy+)8?%k*+_u>5H*56&=bbW2L`Io$7myjoc0^A&P z;rcyWWhJR0tgS#1G3O6BIC1rz%+xY1RW4XB;%dWv5!}s;?-{mWUlO7y9X0&E~*NA-UfIQVe>Y zP%dyF`GZxJ>K>J-Tdk9k^~6jZ2SG#e@+}3YJf6gyYAjwpyi91faBi7=b4@YR{*EJ& zrTpyp6VB3wGH;}|YIf4YPE`&u zl~$&222-z+(zfa98r!78tS3j*%)%w&k{Pysr^luY_lke0dxUxued}_h@Bgxdbrt^UhG!1xaAz}=4 z<+XdJsq+ z$o#QPKhR<5>dRB13}}v9)pcD!8eSyuSX(IwCm}ft8!}PLEl)f()rY<>r?Uh?4XqLU zPOtHrHw+9JMZjfA@GAUsGY@NN73}gnHl5$Kb$&nG*Z;6~UatNly#rQvYzoTZe1rk+o&3hlIIElj z#T01=&)W_^d9!FdbgCna7XsbxV=_0m%wA-utqCLis7C4cKa4{E4oW1s_|f9HutU*O zF5$BH|6GzS*Ty40EY}ReIbqHCTb@ViR;2hqvYpVDkR5j=ow12-cxr!5zQYLX)s34NlV)J9`AmEClg<7c^>F`V%nY6jNJ5@#6omfL^ZI%;J32{dvKaxlwVqUI7C(iOQCW(gzo!eT3RF zUL;faP{X=Kz&yFA8d{Mnt>!+Y1A>aC!lEF!vXo0S7LJn&y0{zYOL6$frI5?Uq)aMy zC6JOD(+NX%z+(g;AHd1~ph?-JMcFZ{n4RLGV(&IO@Zw~_rwIvGS>7oTKYjgkuE)f- z`}Z^_=teo1s`Ur`1-B8P*dpz3+NKd~UYoDbLoNUJOm>~qXu9GxB(sxRVK#>=K^H3q zM$N?ugZPI!Qb zj!maFrsT0~YRyv!`|~qLnZNBcZ6WTNih(krS)p<}{6?}-xkF=34jmtT1Vae9+%1gX z1@_wCo=Zzt8?!_w)XxN}SvLzi+?L+DRY)5J*N}#X;Z^pSkNFS_XKw}7;X zhBScovBL(qp+0SW>tD6C* zh!CMf)7;HmcbhnP|3c}JyNND99wBW__kVaL zdT54vz{7j{^)=b0ix)1ct_}x0s)kzd&MTfQNivMNZx+r{q|ZA3v27+^v|pQLG5X47 zLqkoN5E&*{tM3*D#b24i61+URYw2EdYioMh3NF}oB7O#2_VyV@lS&5XmyBPRQKy35 zots#a+KsYnTBD2j=6jRO#W`XasOf5R6y~w(sCh7&o+Gu;#dqp2ntoQFeu&^|%Z@=c zXBiTtu)1K1@^J*FeajU6N9DBG)5gp)4!6XI5ojdd$~_A2XfKS#s{mC$_RE#ihFGTgbvd___^ zMW?|#47wBnG0ivD49W6^&F~R$?iMH>@S)J)kPIf}mR!Cz_W3g)KU7?TPmjrqr16#O z+8Xax_p7a<^qvdiGd$AHAtN6I8gK@iv^}ZZatl~>&dSG9XULwQFg}6sIKs&#ZO6c2 zZ%)U)MkBYHvz3cMtf=50YvJpdit0|;htWLQ$&;^-f!()m(`6cElVv%hrb>-R6{>3q z6Hwy^mX#|(FU5_~?7SY?&PlBS4mhNe7Eyt{Y*DGKRWpfK4eO1wD})uC{plUydp1zG?Z80$ zot7c*_WKDH$Z=gUCitu5A;AS_G{*EO`C)=k!76WpS(in;sxRgO7N@}k?$FS*2pBp1W%1$7hqsI6dd=R7p44xxh(v;P4h+`=NB?7)@J& z7Zuj*FvKrgOI1YrJBHqnSO4A;u8XI|`;bOT<=3B9id5^Yh~bg{SjUm*hqYH zc&z!B1z{ckAx*;U8!Ry1GpvP?OK_JL`pL#GE)zURX3%4>XE{%x?S8_Ee2LhzJ>YVC z4`GwNap(1~{RGAi)!z?;-F$uHgaz>mB%c6*#`j_!FMiBuv-XSjp3<_}hs?o&;s-Q> zzh9*ODbZj#@pO;ZinFvCUYPH~27+Xd@#)mI@P62;m@t)bee0X_gic6IVpFeGL@@u3 zaxU5mwS*}`0ioA|f9(cJe9ZPBq}R)pkM5(ffzsPnuvdp2tJ+REJc#Ivhh-Scn-1UJ zmqcI%TryoO3trW^2&fivnbjtB%~|MGx=NotG<=|ZcTk{lpyRwi&;c6)w!VR4d07EQzOhF<5RD28!LJU#=8lks9|x{l@09n6p%- zTvZ>%;$Toax3(4@=b z%=N5iEAT~K4#s*o4Bgpar%A9l)v3c)=eZ$jAO^5TBf3-ykyS zjE}`H=4I2#zLD*-H^Fi~o8CNU=qskqZQt#%t?0<@RkevF;LA)Cf#8!#_w}|v6^_Wh zGQQ5z^1}C97_~dlIzedC(wAO0P3i8~gY)&6l4D;mm7O8Pw0^RsSNa0w4xOMxjC1pS z_%^rn>wu1(yz23e6l;>Dc!+9{HQ0AT2XW7324IQ8Kp1qHj>~;XNs=sIW%mdIlw0Ds z=>A`t6!B#X%Pd^JcdM6_QyVmb1 z9S{jnU1{aEx^m~9@%fpcDI@)Exr%a1w*`{X^~byv;sGp8{Ez^B!p8D?2ACPa8sG%a znY9WU1^eIo?bl%e3XLX>+x>BlA--;s!4MW4`dYG*B5!^I&m;%b)puFrlg!2NFmI{@ z_;&Y3>qxd@2ZA0x0qcd_^`B;G?>~ z1ayC{CUJ70?lOvk?n1)K^TZ7fgsTwhWalGbM&e6c_koI332%Md?|QxMn`38&U5|W0 zpzQkLeS=`y1>=_XB5M-2>61qcc%{Fv>pU5$Y)HRNLrrnqX?1;67kJ?3#Xa?%?@bOW z+%f|8EHQZl|Ld%3jvPG{L92XUAmcp7-dN5dbvTuH2vUP9C8&G~a+w&ry)hAn0t5>+ z=@634>^F0`(Mg+9SU^MmH)LWbuok9T!l=2ntY9d$S$aGAeryXK&s0wa6Lh#%p=^-% z5apI`kg2c{yRh6Xgo|kB5PVdqW?%!65v@qkJRF#cW#4i@AR_^5NP8@s5o0vM8|pY5 zvAP}w6}mGhS;m~|^RVtrvo~*shhsY69@)W3wY(ujCWa)__Z-_0-ST!?b&j_LF6kyH zgqjD)!RNpJEfSLv>X@D=?qs#qsm;L!->u#BpAK@_P5D+ku2H~V{2-5 z--IRSKYJ#>BNXVfn3>OIWs?dz!if?|c>KdO+|>1qwHsLa;cal2Cd0x!5|-rdE`w** zh0Nzt$K$4B+=A?Bbn2a(rpk{JCX+dBjlO&?O5fy-i)yHz``MV>nTx>2|yh*`*uqDqV?O)r_8cr;q)s&uzE1lVBXJ z%o9UWV!r~5OT1HBN#y<>w8t{^~)o!oWR(=E?t)SiYUbC!PMP4|2(Zxr+Th;!=P{Bgp zB~GL*x(*Y)kGjOX2VIOn)Giq31{TADh{HJ#{|%I}JFHY`RD@`;2c_mUD1%byCSBIUx1t63o6&;11SH2j<_6E?_HA~a0t;Xv>URx^BVG)`Y`$BYt-=^=!U zfH%&Ns9zXot$CDfjDsWNF}gU(!K9spjj^+0Sw7J6+pI^l6!vaf*vHcmLx1rPHelg0 z7Ox9{x;Qj|KQws)#clv!4B9Wnn+}a``@(Mcgg5-+{!NJ6@A(YY6oY|1_93_AWwx$KU*hxmAFVe#VtxbV|7UC@Te-VSFo9bzYM@j z#rqp0XBA2oqNs4goe6S{D7*(iy#$(l7DW@$;^Lcwps9M+ryoKytX0pfmdl((1`9My z$Jm;cBzzCPZ1Jg}g9a(Tc!O9SAiXV}%N-0^K2p0x?Q)a~2>J+g80#XPdUZudb%;V%<~u7dwkWt=4Yc3<@mJ!L>H!s{PNwHbll}&O z3RM?jO1}s`nHsY{Q4Qew5UW#>$Sc%-1dj%ipSCo%ojFgN@wA#oS?3Z= zGmdj44rFQSFk?>J#y`L~l9T4c4an4akZ4Ry8+Beg_#e&^pCrF$e%@he=F|l9i1P}6 zK`x;Z*tq0`u;1OYLjanGBeq9ng9(eg-W~|!d6b9DD^bDWtou^1B|p7G9U4Lt z2mx^UaB7xz4xS2D_^x?5FCS5g1$$p zb|NjX>aM_+S9BOa84LLv*@36FXW74{rEhqlmBSdkw0t*MU+QL-Ayl41I|3shO#gs; zTe3gil^;K3?!SPNk>`9Fh#N~_N2mJ0U$2l}liyJ& z52ey2p7gAETn?<-qD43Z{apfC%z6Q_zF?6o|ruQw+ zHZ?xrXQ~psuP=Bdin@YOog46EnGLQHUDm?DXbCfh!h^*)%hc=Kjfe#{-c1$-)G1hO z>G8E#VriB9@O>ukOb&6-h+{$&=Cm)28@r>EBZwK*h(Vs+2p5sw9|n-5+Rr3gz+RwI zfi6yCq~$_L&?qmib*XmRet}To@zn*SEmvpqZhzbgHsbRd{T{~f>d$aG{?^0r*yHo$ z^UUxu{;_TInrZX0(pro&1#jMX;m#>1^UZ{H9Bc`6C$dn~SWyqIvO8*{gXKT!m}w%-m{$n!|^9A)U6No zyMj^Ls2XDBA`WbGDfX4!55?-?cwwd$wDw1@;J6SgeM$oq9@(t1&FE`=5sEITu0pS| z3ZB%_0~c}I!zu6-1XzF%7~u}C??CHi868yLXaoH$c|6B=`8ja{)sUC&pk z^h)=3atjItuq93gvw3~ikw~QZUZ<>X|CwV-~5%MHuQ(o)Tv0k4#SrVEFa6AEzu1Q zP-n5EJK2Eg>nsO8!$>c_?cx5e!GGZ7)!`M0pDq2jovJ-DMsfbu65{65q_xw*Jmx0u z`<-PIiI-gJScr1xv+-DLHrb=|P@m>KBDcTC>wIq_!lwFKeT^(TFn5 zHz*Gx3iJ;UM-G+8@hVzD*mjyq`rlsUz=YI9cRCc%aFCI&jS^XsKYFxB#pk7=cti71 zQCj!CBgKEO?51k=h*+DuwDB658NI`9*b?c;r1^G{K<){=i+=>p>^^jUylp(*f4r`3 zyjaUz+Pu#D+_-r6f237ktG`xtY(o+}hPikjY^?BY!7?BwGUGfuX0`-}S&5m~SvOjU z7upZ}Ri%YuN1P*{ZJzrYdz&H^!xdxf&DZyZAVw#HldcRc_my4h;Dz2nB-gRy4O!PJITEgLnVN%Nuog3RbplWn8TDEx=<*(RnV?C(IbKT?C&20`p@<4l;No~wDv6Q@n`@mT6UA-TzG(i=>zc+FQToZDg^8UFm9 zUmG)CN?u#3$5Iuu^yJnJ<@vLgUwr=y(3Z`&E9nVSyZ~~WaNT&y*fIll4=E@xgbG@h zqD1C&uk92x@+ulj2H8Yb*kqPf+4bf<37ZHRvpKqAtRFA9v$Uh7no`f_4v1-419%ep zF7nf*-Ey;;uxnsx_^EIpN7a4;Pw5VSz-L~L!J(|_g98F@(zL2c|Ah&v8?5NavlaluyX3NUbG2@d+6!hB`h!r!I8;W zs_cyNJGli}Xhr0`G2(;NPI_|mywqt}kR?W<)|Tbrjcx`$ERoS;yc_~ZzZZ5k5c!@s z+TeyOD%QeSu#4J={NDdmCnf(Wl~N!~)u`Fwm#r+1XF!o1YdxCbxc=L06^d~J62ne* zurlw|38@Dc~SN;6MX8F?x;7@@2V~&N-%VY!I?I~e?oWu%dM&jNuAHdgi{L`z3r$%DmDH(}W z%}vw|g!7vRoE(Pxf|EfB-kn}$bGnFk2#pwtw~lr8B0(?O3|~{;<=+=W@3T$XW13F- zoW1Mfg|6_d6%}sGbP5V>kA+Q8uD_W<8Z_KtGh7HHU|pTExwZC$5A_>Y?9*wK9N#0R^^@dWhpfHDkMF56c9or7)q1NNV1H0 znKgrx1*6r1O|kB`$J#4fHODeM{$n%y93l=OA9f+D5+==ikoPkWOe9sy2q=aO z&2e!?oxa+76gu2;VUokjy>0%uoW(&pZ5^vzUSHBt;-_N(i3?O`6AfKcF>M;k%zHm5 zdeJ+wfkg(3#Zb|#WC~X38SHc-Wn4N2^^e3x_>3i6{f#%y4kJ7r%0#6nQTC=xWtNqf zX|||ZO<3pZ4u4ZGE|Jrah+h*)Mb#ny<`Rb30-5Z>vbp%iGQ5tPlJ$nQSVLs<`#Ao2 zohD&?iy-kOWS2H77(El^Rz6a^w(Swid;H+&(&fEzqbBA3!fWs&{gsLTY?j~ZfwZ?B z(B~5QOs=Rr3{Bn^f(W;%T9Bz)hOlTq8{S{Hz*L9(FuoK8lQjd=*PIbN%b-!B%rxHK z&0}awESq~0!}RE&+mvit_#0FZ?_@^dttL>mU>H!(+QN@=g6&RqB^nv`Fnb_~b6vB> zY0y{rlfm*VrxS4VBX0MuTkdnL!Uq@0Bpdnu6Qw5uV{5+4g1CQ#7MX|_%9w6OfMWu{Zx37_M%fu z%|56EogBr;)K6nbUXhqIllc4uH%BJLH(K_BdFwLnQT=-yre`7ju!%pB@od(^)C+{e zX2NEoUzy=0bWqsY9jwPU+!&rO>eU`+#TrA!8uVWWpGh5?U0HL=um5WREO=vUYC9Mn z>w#aN&pjagitn%ca$&LgmLrrUTPjo97@T;I=QXe-w!f!0;6IuSdpbg%n$D_8(~pEv z#c#-Nj&398e<8cySs2SnHLj(YDNJRyb{JKu0cGxLmmZ%fH!0oV-lgf*p5x2XgF7Zm zWfOS9dHVque>Zi;yi{4_um2B-`46+tlKZRhSYT<{G{hLE^;Wuws^F!RJt`mrU0HkK zKb_Lni6Qv$a|YngtK79zZ@_nVFD$=uobY)8mOHGQknW=ag(j3{?YhQ_o&FIe`&f$WFl-GX6-Key&I`;E$vV(_T$^gyD;w z)`KS6K1}gsR>Q|W}7WYMl!;%>b;aitZDVwNVECMAa`tb2WZGE)Z_Wf zn}QSd<$P9OtHc_FZVyC7f2$@Kwp-m@I;^QotsM)#nQ90eCG%v>d5w+s420o-n-wsW zeO~B%zvF)0^0}XMmZxV1WA8#7YT|+Xh$v6}kUt<78F?ZrvJvx#SQ&=n=lE)SI`IXN zwfeVj*54is+RgqZ88*`uU$wTJ0-J288$JL2t`Jss6IO}Q3k;74X5crL>p^qE| zYG4z*gpGw7b5)W*1!jUrf_9qx#FC0d1F={V6~)a;4ECuE98j^ZI(CN|szAznFcQMIwbDdSkEe`U?0dhj49kwvh(5vy@OOeqP-;ErONc{UT7X(Z>FmvUH^ zACC&<24Zuz)&?hP#E8KdUQ^e%5na*!I0(6saU+J~%EFC?N$`0T_l|+l{hSRaU)m;p zJ`1l8|6B6=Gef?gI?&6B=?V`fL$-@WT)@Q-EvfBJYUuk{hv&PW##I2_km0y`SysjQ z9Zet}R}qdJn*A=v2qISEK#`e22>_D?36CiPIB}E!J3mPiN5g^A_yuSFa3JY(`G7nd zeRQrEtBgfmM=FI#>-px;Wj30`q(*w;7-KN4C&Hs#tlg%|X^pY;plN5RHQgqPe#&Hm zGwlB!5y?64s_1)%(df>3J~4?tyywZRDIN*$yGjr^ zVTCubdFopAQNoTj^T?@5v$@P7S?-p-P*GQd-yFz~{2~T#M^HGsjmVOe4mXvB8V)3L z)y8>}#)HdMW+zJ!x;sR1Qun1S>=+{uHJ_F#DGV{nB07TIcJTtA*WDRym?i)-B*P_< zghdUv;}(7j+mhFEbXWTzttEP*J1pdN`^eP#=zRAr9&F^|ech$=`M9jA?Rvzz@x|(6 zKVHM0_)YX_q%%;7rXt1nun;5s_$?1#W`Q6kKgJkJwF0$*DX#)Vtu(=vntD4WR&Y_ zS@oQ>V$4?`{=XVd7I+KmB>o^4Kn>)2w8P;yr?bw-avCpNm>ni!*={!87L=(477d6# z%ast<@N%5a8gT@{Kw+wcVxQSg?{=B)H;}bk=xJylCFHX&Ic(9ZAw#|(E1Y|%je!ht zoue?#2LGs}0?5LX=a^EzvY;^j07c!Ee`{LdGqueP9@YN7KcS9)gc%&{wL{52E*_(s`Na&-R|y3q_KcP5k65b}mv<-X zZEW)>eh(Dp2+!JQz{;%0I0)m4sb;?ka$V%peQm#Z^kBUV0$v7nUP=4R%8dA2JiNbi zbZq@*eFgfgY^?M3r|5nSljX)<@1p#W^C9TD@cyU{0H$rv@($VHcx@`C&ydd?JJZ=c ziia7;hO8xMfHIRjC>Nlg2J^0q&g`TKTzk!0kfp7f7y`y#g~j=34q_)fG}Ft3&*$bH z$3kr2k_@>~mjtl=v9#Pxx)W{y*M$vVhMG=#M&SdS$$Hcou*P2#5Ka9xB~?`{gqKT? z3oj0-3<9Cgi)3@F=H;Sp9R6GH`rjb`!g+u>A<10I#fRSdt!Av?D!Ta!3+rNBr?wJ$ zNX4|V`KJfS(3`R0%jT_mw&fZ256gc6m#%XiBD6#f|NJvF@Wp-Y=S%Y<9Aqm%lXha;+p1hjwa-O_R zs((8xGkCr@njF^7&(KoX9|U>#6dJlbE$Y75oB1?mUcV)OOm^O-cbsy>N<2NhwRV0u zRe7v!l;~Y`K6vF|746yRvfG@&AX&mAD3qe>1>c+n{|01=sDx;xq~~dYS01e9=^gS!zmr zxO#sUKb@TquNKnYG__oLzxd&ZNw*-KS0^)Jj;S}Hw*JcBlKgTT2I+f>RJ4O&Dh7=U zd73MrlsOIE0z+N-6c6ltbe+)(foAh2j6JecdV+Y+`73Sv{YjxVoX4)PN4TWIsmidj z#-s1=UCkm*x=Jd~gR+~wQQx2Rb$~1rv~-*i`^l81e?FA0!xr>*y2p2o&>+V$ z5WtDr?GuLCLh*T=d~X)GDSqG0_AcyK_nEtRL;8r=xOC}!yYSu+cwYbfqqoZE?WFT| z!Dq?l<+`zy-K}xuZR2D1!{|Z8(0wb2k?V~DNZ=X~fiHLNci;||CTxzeEjDS2@@6mE z#_;EXm&b=Yd|ml(o@n z!S}WppcL4MPQ$W=rB>YGjO{)04@3L6FR&7LkIq88)Kfhhy4zbg*v6 zQhpoH+)W$P2rPnZovn)s^84M(x=@2p`pdU5BJnEqOIY60%uj>i?Cc}Oxbi(U|I_zj z>d&iE0TG=2B>P!@AaLW9??&od!`}%I^%Y`kdYgt46BBZ}MQvLYR4OV&!*{t)(6$j7 zAYo@EvQkld*D)px`wb8fIzxL)_B{>8LX~*r9e~)MRyp(2TDqK5r)JkzQ|z!?Aa}Bh z41r+bF%&QLz0F*ia<_vB^dGE0cNZy$=!I8l)Pm|0-!<$AFD41cioKTKQUpIk(tg0V z@!|6l{ZaK1BJk=%nt7eRe!DMl+xgaOEXAz-E)D!h272Ai3A`M%yErL$2-~aaz@p(?S4)95M6Dwl9A}{M3JBoO? z^HZD6L}~1zS z$<@lO)Qv0G)|jq!r9s2nmo!MQlxS?1M`g9~(&To8OvezZug$!Mi-XCu0~1oR-hnU8 zY>;0@_4oAvu_=5C^)_}>xw6JG+=`djdOz0cqyJpa^S?0x9-Ubn)B(vN!~Z`a?*@(2w++=9LLHXmvC zRYS$P5ee{?nI4c6T7bo-G+G+Y2VyHPv_CoFTde}olbuQ>3{}xCwPuac7Aixvdw-)f z)cT$#YHu$f{=~U>v-5TsR1C!g6)Jf2}0}_`uGzwTwhY(>(4iM#KDal5NpSqYdm}D|vfeI#BZ0 zWeVe)oQa0zy^S|DHn#5S2xUJoX3Y%(r%4BB3D3bbbCVt{amn#&x zZbWxpeB4sJAN~tf=bq0~(&Y2l^ietd?vBH zyRoR1y*0UwZLD&kNK@4~M?D7F6AEokB=;r;M-z$+pxziz&O1N--+H!O3tVS! zykEE7C@dJJ>ewfDLu~uw+MuH2cZ_?%a@5!_5T0h1Rt|{C7&AeH6Gdv3?|yqh$FaZ3 zU$RaFb7^~$Q(#0!PT9JVd{L3-D-M0GZUPFN!H?{&751s3eyb=Mn?SzSHz9`h$n+20 z>h&G(CrJq~CW|&bvO_C;Lziz*I3ch@P1aa+1mj`ur-{~YhflT7`}-FZtbR9SnL~>< zT}u2&^~sixM$CNamCX{B!R~uT>E?!)U6{kRP zhvHD6c%fKvmmtO6wYW=gcemi~mf-FlDDDpJ<-FfH_YWj%WoP!Dna2u?!?WRc!}=L-Ov0J0xR zz5cnUgmai=>SDIpd0mfTovC^ReZzFT19fH1ZS&uQ+94X26v-rUaC6uZ0n{Ll@3x4{ zI{)gpb9M4NEBKZZ>=me0EanHPoqHL7Vg&15GC7dIM2wWm(}7imybSo#(LKZo*aq?H&|d)KZ{rMJ-IGb^%P`UCVCo zr9^#@vKcXz$OkZR@GB7|Cu`ppAEn7~%sBUQQFs`?nCZKz-p}*=+Q=!a`JnFF>WiKT zl4t1g^xiK#R@Y@WU0$5$S3z=$bkqc4-k6TYyRBogFAX+Q_pv`C0jr))8rd1u&U$N` zWzfOm2eiN2Ie-5tsKlGDIIJ0;Qb162IZMccc4>(O3GFZnckUE}fbt*VQoq4pm<>jM z&yAkUwS-H*g+MJuKCrAdxUzP954u_nNmLGb7BZM>5w#!qo!^!0)SL-jrKtYlhM`vY zv*4b@8%4*f=Hsh$rDto<-Mfs4y}$EyAHR<9JaVp0F2?t=?ZiX44IZ`S9#c}1wQe1K z2{(X#DnPNwYpkK_Nul!n866W!!UID5+S}l2nDYo?D0an-(`6ef?q!_{p=wOHMLRD zr@fu96m3H1!I8;Cq@ot1?T;9Z6@Sl1fzC0EZHMa8W@v(X*&b(9*Ilc8+X6$4Mg)MM zjY&kaal=~2lPvXG?ACKDE49SDr)t&)i=gw79_ij|$zz=nG)4Z}3@&88N+}C22xgPI zoMbCnAn4tNt7M5W{kiSU?&{-&u0Zrx>zB}j_ZaNgl{%(!%G({o3dRE=wW|fbOXlYR z|EpO5ST17SuD|MtZA>${)B&dPXIbR{59j8PN7~Ex?y=wuF2@X6v?hdX!Efn{eD5*f zSq_@4b<0B6VeR3irGTVqj_+81`ICfZ)rTf51TysJys?%3GRj+X-ZTz@;`j86=kx|1 z1BHNOZKp80rD>5O@x9kcPkm&*Nl9~3zZuaAD%U4gD^|RgTgZgD_Z38q4KP3)noQfhe+o*1 zWw>gom86Y?ApvmgjqPVu9CHIn)hGYnIpB?ej^dLh37!Cy6Q#xk8UV60c4)yP^ShWe zd-irZrU_bl`IDtgAQ2V3mAVSEWM6){;P3`}9XI2zLqUHC73^8O+yvdWiNV2|dSR37 z%G#&t)bM9$(|eqsV+a=wwR(@FT@Uz^P=s_cOr)Kt%CrZ^(ReK3P-xtI^^FoMdLNl_ zcGZRb$n6l9Ei25;ZR*V*OE@SU7zlr#cB1Kye$ydTO27QnPOZx{v&DlpR6HutxgZgGedTPs`Jce|O_C!a#Af73H0g&n86H?&tqQH4 z9X4n-NRBz9Y`{m zlgpSK>4{lh>+?th9<|E}FxIT>$8x;!<-I73O(*LL>(mpb;Fqta-d={?pZt+hE6zWF z$lpHkVX^j{M%dMJFZ_}Cm+M^1Z{T?tZaj6UPyybP#lypt<6%Tu|CiF}O1U@r6W@md z$Hyb$eS6mEk_0*wAeZVNAA{FtS2yyBiN3<&%58j(D^}zZE zO}>Ps2ke#U?nGwztM-I{Uj3<*x(?*7kNyJiG6PAy>M{jy+={yt_tn2NsQa&KP)-6YXN6=5p43d zt0o;i7NsPz|4RBe|KY7SF^dTMM9-6Z?$5DE&fB<9rQr2%C*V*qMUuL@ktA%qWb=Bx zxkaBQoD!FIeB$Qm#+pa#HmmCs-eMyh1iTyWTyM+u#Eg9C$W$cdF{*~jbZ_NIcVe3vY zOH);M-F~s$hCo)Gt~LY{Z&b3V0uUX_#)J0}5fHE@CBmB;id?3mzO)iw>Il0YK$c8$ zqsVLm!r?=9rohI@S(=xtTqE(Ry$cCuc%=E;zeW4Nu2~JezcMoF*h1^09aC#|Gy< z>=_z&l|K4|ji$ivE@y*m;L=Amx9^CtS8fBoxlFt*xDrHi;3Co z7-`+S$W9(bsr|{-^M!mnG2NFmhUYVRnub?wDOdFc2zF<*#=Z`tk_6sB+l8l`)GA#e z7F{#w`N#hA23 zFx$^(gNxTuIhJ#VR&hJSXN)lZHJ=pTqtd{mNQxcGm+Idtb_!kBC_X`5+dD!s;@my7 z3>3NK3&o)hzf)?WXU1G7Cwwj~3uvz>JFiEtg;bT&jNkQC$^>UKiM=CRv+z(vprSwJ0r!t$Z{D~@?)yY zpa4z|=-+jUmrcKZgXhUF|4>-Z1Tz!AlJY89vu$;zPx-*bB#3nTzZ|HWBKGVIz#TE@ zm4PrXyrjE?;DuHuJ~?pO~zQk{nSQR8=Q|kLYrX6ei%lj#lQr zpkRh$2%k_(rnVOCA;oF(?SM~a@deZhjZ2NyS~$;kEKju%09$-pY_&_GvA0+k!kL1F zYHr)eGs+a8{;OGC48BXbMl4z3$ikDU5eoZHR*31+!9LEYJ?X@IXhcNr!>yGHY3 z6?HV0TPB)IIwopf3PZ_sr*h;2ef`g(7WC>eu}Gelu@3icOeX4v1vNAQxiGD|1ULh2 zb!0_d4XJq#Eh~ar)|xS>2GKw~3E#fD_u6Oqj@|IRkh+W+?pC*qQg69gdED@urX%&3 zDAUJUL6xU)N?hq=aX8faFY`UNB{$JPNY#laM>Lf@5t7A3Dm-B%Q++2ZcG=zELd z3Bt^GN<>oYxjt2=L6gisk|Ft70LSGE3DF*@a7@)zskleoNrSWoH^GbP@X{1m3dPcU zO6fj$wB(ZD3qWk=`F5i$&gCnvUND?0f$&EzfG@`iraS+^bYx{vQoG=xal4>tX^Cs~ z?rm@#nm-$9jutEGBGttS%+zheJvx}#?>2_=6$PbY&@MW5603z5O7afP%Z0)6@z2k1 z8-%5$k4ZNxWAavq-t5Y6uX1dr<19&QZ^pmXNk;@v#kPp~dr9B%WHG|>hCxZXd3(2t z7rf{fq^Z1Q6Z~6N>~z*B`DI6=rYZN;k<+;UNoU%$4;hXq3|IRPv(@gwU%A%^9TfWn z5$(I@RXPxcy~UD~Y2(5V2pT0XE&ss}6=_l3mclD!!O3`G30AX9i6zcih6*`SWkFTz z;vOoMeX7G6aRP6Fx zAS?VSHnsa29|)YFmMZj`p+C=VV^)IpgZ>(v%k3$Vh#@c7JYti$h8p%7j7QG}P-eI; z8a<;T)$=WUt{u6Yd2XzVnEP`a0Ibi3uoa%3aGcrHrix%_YtVQ}M;`kjK+ybr^f1iL zTQB;aUStZ#w)@N5G43i;k(i_-!G9%+juA!n*$9q47rj7DImvte>--h@K4=Li7_8xj zJsG)SHZA}?6!z)xt;TnUG3<`AN-J|((rA0?UyhQ)pn$YJ>~r zBkVyXLhW*$Z55aCH5t+51C`Cw6d{%-DL6+le~b*<^+j>kqy$Z%>W~3Pkc-##tFoO; zj^p)4eF?S2r-{#dCIa6hbJAw*>W_1*Nu)S}#M4GJ9B25Dvx@_oPv>

?_?kFkzLl*;}^&Y;^Ncp*aNE$-f_>$C_nXWKl|abR?A|0S#4BZ zv3l$MSg84R>sZoTA=@!g!*QE)>(g##uA2i`woX?N!n+PRf8UmxYG;(d-fB`QWS6B| z>1_!8cUbtd^G7#H201$B&ouW zkM{#N1cc7IWi;H?wo#}`K%qF$TZYC+`uXdDl7>TlRe~_)_c&fdz`4WrhB&al=!p-! zY?KtE{;XxY>G=w3{2@nG6@N3BNQ4MyK)_5fx+`uT@H*J#*p|8w#E|j5HJ(q;wI;1O zK%IaJVhazqDQS%7&7xUoEu(0_QQ zqv^ROXgB=v&Bah9j$F%DRWsIlgV5R!){Ky~`0IQ{(%`wVz@Mcqq|N&lae7uGZ#|1o-W(aG9;-IOOsp>>C;i`g&dr;i0hQT>U_B9{Vvb2_y z&BS|1IGr{uvq|{R47D-HESU#sgGsyI!VgE^py&R!Lv`%7?}W`;!|S5X+p*35j*usE zdTGPr%0cDRwYK)QLP=)K$Jg88jBU(cpB%?p542rIwhRiy5#^8sqmKvwaYF`D_4k;r zl6~aVWIR}cRf?h4e)|2b^Y8NG1gqJfD{+I63(9GV>#ivV<6P$c(GziR19XaC&_V8p zxH`vDx(-bHcQwu{oW*OT96ir)UI)AN)m;;FRoW&V4!x_|LVCNSI;gcs(c}2cC*%5K zlvnu(T|2x$cBLjiep6YGHTVEqH*t*=rzpYU7eIy78bUnYe}Ye zWX2U4s8$yhP0EiyOtApVnze&dB0{q}FXfj14G{*HO9^|g)M4zILDp+Ix|QXNg^04# zvM26-M=Oec=G*68<^&sYcK4RBX6`h{X0>IAv--iscSIaI`WO9TkRTjj9HK%1G*`N4iG!1_WUlB@YiF4>C8En8561cFPGjEi^TVS5Nmu@8`2~U0 zi8EM*)?7!7#Ksa&-W+|rn()yYZ*e9kJ9up59^;b+-_l|3_zR84+kqW!LjyLytjrkS zG_*+=;4#%-5&pQr4S-ukO(3tB1l+#+8HPhi=10DLo*4`Y4z*bcehWM8{ zSJ@`w77qFKD9m~#Eom1W(*S2lhjJ#J$<(!NEBiq{YVCdF^e+v%UwnU!9KYDjVxGp~dkeib z`f?w(K-L(^t>r18l`E%NHJ@g9Jq)3KZ*DTnIBc7LjF-IPos-liCj$vM6HD}d$5xQz zd9n?87wn}FwjU44VV=JaU4$>G#+Pnu?fI0egP+xmW-f)X==Fifwm>BzIDs&kut?8w z@@uPOPfPB1@3`OpUX+K!#1-AEL&0BudKK4+9Vo}uFjnkvSQpruNrDF7Rabp@dU+Rv zvFtvQ6e{LcT)NOO3=URQpzfnciUxec+(eRmU(YO5MQ+P9O%X^aV ziz@#q9o;{WwmtXR;G$g=r0aBaG#FCB#M7drc(&C*Wzb&0=&{p{i%2_a1T#P-Y@4u0 zCZNZCSV!MUcMfyl=76^uwO>E&JQbL*EUb0PCQ*~-&D0~G=5=z7%`Y?4Bk8Yd%BQQ;hn#b86|NvR`X`45LHdub^Q;wzof3qk{f$Vnn*UZ2jj^;3Z@(#h~*`uFro-rJbqE= z&Hp`nmP25>VRDAPVTV6vz5{74k$ya^gU^HK;meiZtxTTryN|D0+>uRhne15`jjBbG zu~QLYX#>q%d*TePK!)fedemj_(**JoL*4ngHQ9$q6w!M`IaFme6?%aV-vVbeFa%q6 zyV`sk>qYv8eQSDmBZX}_+LV~k6%#QYs3h)U1AGbc_sF&O6AfOt+g6AN#{z+p6*3>*c+f-{Xjt)NN|@h*=X1NU*7_xOe%T4$Y)Ji0)QBR**eoY+mA$3o;3PIA zrBi>&B?n_glPO|9ZrfuQcdQCeIlpH+)<878rUp1I!p4(d&yR2cj`7uX+4fE;$+#{v z)9$9z+WDd$2_qAXABP+iIA$tfVSG~BXT!`dxmobbIR8e|#3uqqmLRht_7No_ZWO7- z`Uq5ZaO3OD{x3PzN&#=g2||tb-b$;M7%iKt6C;fdy^D5!clv7*&SweMR-+|_gG=rl zz-x?&run~oFE?@>pRqHl8?!$RXSXN5``qh;vuIfBJgi!nY&61_EYGt}y7F2=4>nfX@J}dneXs4twKo5GCm|8S)3%RGlatnWH|!V{fX3P7EU0bbzW}p@~_?#<6n4w z0@JtNZ-MI8TI7octgw3r?Yjj55ws?39wD&+G>l3*Zp`j@b+2Reli(T`ey9L^5X+@U zU}W%_RheH}q$J$OhD|9O{x0QhE2I&GDlX^q*}6mjhpRIr>#+d-(=XH}%$ ztFtLN%h}a7SqSM#5fYlk6`ccBSD7Mc5#UW*U$1g z-5xcp%=&tFf_?fV-32=08Y-LaF-%}mY^NO`D;75I&u4bGTMn|Z-ANfRc9h9IuP4A$ zWew>GkF%C(tkH7NyMin*>f_oU@HgJ5uCy!r=6_-GY_qlI_m52dCIdl2oa%IHv;{i$vd?wh@CFYEc?9YuC?nHU!j z2u_lbg%&_9X02}G30-u4KY2h_8G=+0AuB#P$?#UG{O!ty-rvPjqH5vjM4N0PW*>W} zUABhkz7$Tzp-dn;>N%MH4R@lP<1^I%IKMV=96BdPG360ED2&%sB5vi*%*!lOrj>VP z76z51V1lO%v3(-m={uCqX+4^jCBg&mguG>V6>EDnbfk7IN_V4hxVw^SZP#k+%XFK< zrKlYrl5#%ON_YXr>fWWjS~vu*IrINBOT^dJoO{*qQ@<;IxrlS%ga=3`QNU#rr0gFK z8-k|mEHZaD!ZhFfnF!5tt;sIQ8sfQhY&WswHwfk)H)!OtX}^b3Rm73#ijb3I_5tgd zR1{ZBEjY#XE-z~pV2YUy>Sr^+)yKh=A3KbIYPMY`&x0m!zwWn1KOql-v`NE@8_ovJ zK~ikyW(s{zmq;?TQL@6Y@>4AcnpHeuJHI~72#=Q}3H{7CbJ7M{wf`VaclG$T3LtwN z;Jf?+E?kN&f+9|Y#^UWIHp_*0zkXQzw{30NQoDsq6XHsbdLN>C?lhF5rgPN(mr~8= zob9@rB+_b0J?Ko8Me{wgIV^wp9Cw_u(eO@M84}nyIFCDxj3wysvjjc27C91-?Rq%; z=>&5tE%o!E7tw@dIeWUG+NZ`JEUpSV)*>>nPer~wp0m>gRJ2wbsy^AEKN0i(gxv|w#5aqud?s+PzAJ1Zf1)sx{X#I&K)-f8Sg z9GZikfP-OZoUtUvblYh5d~5!{ck_)sc`i@m-2q>?7P9geE3@Ec`hXj3U2xI?EMl*= z&cnaTz&h~EYZ?_RlQ$zQlosJ}xwSE=pMWlNmk z$qfz(Z*wZsF3cM;_&Dy(fRGU$L>pAEWv?Cm$W( ze|pm$RTDaq-N4H609Zx!sfHj=^tdeORT#Vg8N^XbYRhSEx2is5!QR4L?9>$CV@ai9@%T;^xPd z$=Nz%qxvwjSNUwf^lGi)wf!ndInto$+^`1`t@lwRTB0|L;O$04OMQT&Z>66(DVRbp zV*_b>@3%ftYiMSTqDBO^6oW1@cS)>xKo?dlCrNA*e*N12t#m3_b5mL(+xVniiv+06 z+ZBRzg3RHa><9u%s)9xysh=Dd)ERwnf;zht)*s9|{pS(8)YFFx7*O1pXzkP9;f?hj z4CG6wr&rcX2uR#7_W8TFFt$R(v+Ad(nbc=E|2#^ zR6oUEA|H`njK_j&Qq^}#EauXZ!Ran#pW?zIg9(kX&#Xpq_=xMXlA0UptUkMhOR7%an z1Dk~zS>C|rD5pKq;PN%_Vn}Ef8GM1wF;(no{=G&<5iWz$SPni1=@65#337ketleEHI$wKwU z@e4irje)#$3wK@^>)O379CR<|nkv$4;r|AZbovq$Y9}48wb+W&a0IDNE>4v0cLEar|Q836*QICe9MgG?B|bT5rm*& zGeG*36nXfsOorC#F!=org5MnM?nIXl!%9BZNZjeZ1uRl37pIjPnaN;S8RlB^X>n-# zSUNnJ{u;e=MR?w$t`s6;NwB4YB#z_&M-ol0ZmwbEmpj;gfAfFsBJ;a*{FchAmfB^~ z;AZDNA^o+e`WTU&Njo4r>_o+7{Pi?M$hZkr!z4y9I%0e0HADiBmQ6>$XYrdyv;~dE zp1oz*$@{U5l==Fa8zdMa;WsCs{gmtWjn#+^MreKMnoP3GaJ{z&!F%(>h)8c(&+~UD z|I%cP+m*H=0(f&TZZCIKAhd>Tv}V8&!qM5#`tM8W2Wqo9Bxvrf7v;B9I#pQx&O^XK zJayB){iwJ8#Z!uI?pOe-I`fGpo_yCu#=rFEH&GjiHuqq4`HEzPY4ex(w<`ht&C{2C z)tdYSML&-D!jhpSKznFjRH5-yjFo?Lf=yh%z5_Yc9itrc$BG9ndgr`sic!a6Ld_p+Mzh%~B%E;lQ22l3iOQ$<~iKy+GLfY|(RH zkVRV^66h!{hJKHU+@AXOuj{jhBiAN5U_bDfu|qu z?*XC^M~Z8ic8z~XJv)>9RJ^55fm|*P?=geF&p3k@8q%wo_93q*k0Jd70OAiBXZt81 zDsjZ*n<14P?UBBs#f1Oy3jHYfl*dNzHg2z{Mf?Q6W%-UR?vW~buZJXUO4+Z+yLz2! z>0(Vq3>Sl*KM~qO3^RU(+23sGu9ly*5$yXYV>Quv6t5H9qFL(#sx?VqaXR-tjeIsS z8Ey}W8kbKK>9ixcwZC~wy~Ch^2gJ|TZz47;ej55dJ?fr@4>r!QMl~nu^?V=i;GT%` zu*}PtN=i3A3l3l8=P!_^HZoI5 zS3r~xNhD}>8CVQ+#HFIZ3=K82bx4)rF_fR&B}Sjw0~-kHW1agXzG)0Q-XU~Cal|U6~(v?91n?6u+x&#V1ZSUn0CFUoX=-} zxt~f*bQ*yCQMtHI=paqO+M87yF7HX1h>9nKbtn#!J?Pic? zNd1NZwD9YCc+;Mz>_s(ULr|;!hw6F=u3c>=DVy831AY49C)R~uuNZ4qTgPEe%xrSq zXkAZtb&e0a3+FY-$66kA(0umRRN?v==l!mJJzcwt{bByua@8NYeBCZG%>u9Of2y4Z z2ccvCpG^!GPqDeO6Ql_=&P=>U>m+eZNQx9%8*eO=F**2s(pF3Q{_+<7pc>V`Y(ce= zJj9Mt6G^soM|D2`G7-kDw?qY6s6?Q;Q#=lQe*seOImxqrTdXpqUE`2pZ-Lzvioip_ zSAQo4By&M0pPs%;Z1!(*^!ntcTJnZkBitI~d`4lxbb(6VwF`d`@=n21nKpd4aJJa~-z5NsknwkY89XX4LDz^L*)mF|bT3=_6&*ltAe}*d>z-zO`~Vw@BAF zObTm-XmKe4QedurkQ%X&lDwZeIC{~_RQ?B=p-Cq_jqMzlEFR@FM3L+}!5fbh^| zCJ`pkWE_a4V0-^+|a+y2vf5(zji+307D9Da}iZvKe8BV!oFqHQu+wnI0t?yEuOFMB8txJ@WAo(9c8O__^+y)zATtyL`v7U(cPHcev06{BsDhlg{=fB0^v+LH5S z?&I~gvCM}&5Nezrg?U2rn@P4+9W{<#Iy`9foaG7k2zURV`i1LA@&dt`2K9+2iiNyP z1wh~m^$2}XfmT?6$)r=3pz;$8#&@}IiU(6rXKDvCd3sQeE*mDJZ1$fsSFF&{)g7ZR zANP1H(PLHrX=}eQ28pc__6;Q09lR?rD&WVokr0KebiQ>ajh`ELwVg{|rFRPdmq@NzpXFW)c6=UH81}=gjLhtikc;q=LfH zTU|$sdVs<$UzR%2(}G4UQsk3ILc^&Qzg!{qBE*#tNyTOGEDK=asbZJ292?I^g~&Hq zp3^~T#u3ssu)xnXH#i+DrXxuLIsUu0iKu;CMKvu#zPb#2r>2hG7HGV~NuY!9j=uB0 zqVAoh9I3=v74t7nn$O>~#xI^CE2sVnJ6r~9>N!rqu~?Z8_%V07PvQ2}HP6Wz#k4^G zJIAxH*Ut@bJnA_-3*Adn^)1WQw3@E(F9cOf`Y&z1JcCfG7Pz^J(roNI zJt7YAcGlhO@f!IITDX1Hz+pxc2DFN|)Yq?u9MN@R2+xBc#xyC9dgb~tCZ}Xz5M1LS z$@g7Y_;E0JNx2_)FM-*d4?LXlf%~|tcL(miNqlscl}qulocJXktpK?$TpS*6#(A*2q?qV!xU|u_cJ5mMsR)? zj{*LA019gbBfkj%X?V{quhL_3i12OE`JmTO{iwZxwM~Yc(Q8=ZjlSlOz$8l0VBKd5 z?{cJK^#^Vz9A{~cBO1;8Oi%G@E`1UG4HZbG9;qf2i6gFW42}uJ3Tf5vfn(4aY816@ zWbbnJgr^qOddp3wZ{~35pbQi$%85z0WN=lom4EAnX$$3zO&!~pD3)$_maw@}6g=lt za^-6t_UxOT7|4#CAM;caY;X+nkXf$71OHqQazD||F@)*}2l>pcx@EOyk-+qn-A!1# z+)O#`FEd^1_;4xH91;rY@kb(b)LdDXWG-nzh;0MfQ~0${vZ4njoT7YT zOims2JYhQim`*!53@f(z$zOfIYM6}NpM6a=>oTO`GFV(gq=rMpe1v&{h#Z%x6IuO3 z<@9)jTP1u$Yi-*RJJeX1pAtlS%W<;;6u2PAfTE`g~-bmKS{rvSCz7TN!yw8I^k|zym?jfH80Ok$@VqjI| z&eC)8*h@_}G;}C)5MtCf&NBj$cJtJJ9>+10BM6ARW$#cKZt%C9&@uv~D#xV26S9xn zj-px{q*O{GKc&5`-8gP_mvz}BvW3L<;QdWh7$`FAJ(|Ce(jD&|E~W255-UK!XobWw zrs>0}16!5LIY|w=tA=JsGB{z7k0>*79wtW-s|xOB#`#ro4MVp+8D`R565PnI-xgHA z{M>abV4rC>H-3s*V{Q{zW0UqF&2myxi?vG|cdDKU=E{muGdxg{lVTQQ&j0!U7jcDR=X_+Pn|xPo^A+`g|KK{`qw5*yK0vtK3+a?4 zep`Jt>e1Bd$7m%qu(t*I8^0SS6~utt_?AZTM?fh*EE)(`7Q`?Vbc-}M7>83*77Snz zmRgANZEk?swYsC;N($!{LjlfG=Kyu?;yV4XV-W!zPg_h^JO}v9cj!IwDC~5<(W}8| zzTo|%TxLz0F}<$09{1zw=-Gh{CkbN>oMcc)1u${;=y6}GgJ4G-sWxfIu}OK zNR=g_FL)aJD>7$`0pBiKR-hyF9fg1xl5wE#jjEhhu1r2~zqO--NVLCajrM$vO%2D% zzV1wk`%~vbnTga(!CSw{S&1(!<{XGw^225CCO`qaF?5o`+1l-26}O1{QX`|Tu*h;7 zt|}+1Pbf;*uFE3J)vn|^kLtaz_=n?wYP#w&iK>Y3p6K-d+M`Qv3r<&(F4oKIRu50s z)l2JqyyEQSep!f~zssVh_?IFRA8j*4aVmDjs(q&+#uN?#fE8eBP?P_LG6eK(3KSsC zoIWg|=ubuaz&kGRfUxqYn%P6$0elf8U9-<1(E$DtvmCS)jYg5MNWUpEQ#GWY3J{ro z+}4E{Y|*H*^H{j5*V6hoY$&ApCKw>oOjLd5rrm@qZ&kzX=NuSNlCc0R?ThAHZ7%KN zSv`oYL%blLIhO6};OojyE&PlZ>XzcuQKFkRvoLo-r<>dm-k}Asc7IZ9{?@>boCju- za0uCtBRwYRS{_`3*$V-)L%am@*3Qe{s8BcWRl$viA>NsbX7A(X6W8|U*ShA;TgYa) zYS$f`FAIj>>!Qyq;omkk{X{xe7sb4rS(*Ik+a5don=LtB^8m?u0$6Fnu$|p53QT ziPS+*xl(eKvKKTal=CIwWN9=`j7=}~+r!!U+lVK^`;~4u?F8~P;Ki4EgTIbUcf0SP^bRj{-U@*#3mW&v5)@zkW2{n+q@gzXj(n}-~S-G zYj<@cV6^~jrhxn>vq(*aflk}6@*Fk^a>8XFn(t{`;^JMI&3 z&D(f{Ibey&aRl>+;^7C9`WYa=-xr$ioO0$7|FYK z^@ts#X5MZ4rm|mpFZ5m^=AL%q(<9ibx?#H>ZO-YWzvj=Gp#D1ogTEvH#A*Cf@@qs2 z8z;^W(17@kR<9sd-@uNxv=a%(rq;i(yP zbxR0=pumLauP9J4BCC6F-g8KYX<3sQ8tWi%n;`Y1!frWHL8~e!GS(S4G8_d?h=`n| zEp3+Gul_a-e74VQ^LgK`bC2=` zxryFoa7d6>75rE9;Bj#LJS;UAz;v9edf3wVd|e{G#Z~@nZ!2Y(VR^2PZ0X@A0^@oz zzP&ZFm~eNaN5Hb=F+I8hORdlHbJ$lB3!7nGwkS3xIoe8eB(S3|Z#SBgIFH^JxuUET z&flev*mZ*vu^8_X!}hPCva!8mQLm5;zR8%8RXD&rwclCB=1cXt=c3!+U*|)u=g*fE zIR@UHGLM-3*qq={*`~}AYMc<|1FF2252oN{U2zuRAZI=$z>`Y?)yPYgGwbH|cDO&! z=ZV8IK8==la_^93tlt?=m>UbgO7uvJre)R&ve{DpGX->=*$a0@vMCut3ch7o!dt5; z%ce)CIj;CL`-y7`foDEh38+a%?vAlUJa|go(e0d))9{;2thVLSyDD*HXjncd#V%Jb znV=TpaiIyq}vJG-tWgmm-rAPYUYAg1(>MpSYZ6nDU9J_YFH9@JVFsXb|CHR{cqlRtJ4=fOw?sU4FAlxwJM|X%U;YCU(r|C z;ML7qtamKjuM-u-_s&V>??U^k@WFPERdye-pja<^ig7y+WSe&}&AyL1qq{q7f9JbF ztEaxZDSw7)UY#0^28rXZ))|2~4CPK0{ewP5oDcdv6nPM{KpaUhcNFb_{c(~l0@S`3 z)^hbto1%K})xO&g&j1Xj{X$x->U0b^#|DgWyHYAeeJ5;c^*%E^H!=cSd-R?Q&r@x@ zeQzuBcz@U9+*RNt%G1iEYU$CD?*u+YaN03FSILFoE~_0$eAKZeA#b$e>`VSUEjh1! z50Q8a4A#9G72iho+}EM1(XwzW!nt6Bp6vND9gj&d=euri&7N}in}dr+BKqD)rI31Z z0N$cJVS{Vr#06ZHO^)?!u|Rb+IpJFyw9;0(ji@G=?#&%&jWO=IX9Dzw zi5WX1>oVvv!^9R!$Rb`Q@~7(s&9d*tA4awO`mx;07)REhd`_?v!_4M;ui-my+w67V z)^#1(wHL`r{Ab_p={V>+mZp+x`yyM;ta&UIQ=3~NT3*>`4&?1wX<6!{-o=k>@K*Zq??J3|4 znUy}h+Nf*eH(FW4^&ymc>MwvKf=Eb38>3E$6td;qXl@y^p=eJwzO<-k;`>(E9WoN! zlW1BrKG%(A43)4SX;X;30J!n1x7?XvNp6VVmrpPe#TaHb%rizf6dDVoF$+7sD&MIi z>85lAXy2JYr$hsZJO7I0|6mGTRxT96Rg>}{RxehE?Yf>CGB?|#Rb23}xmIvvHk4I* zA2k6B$l7TfZGXq%Rtywaf7HWgc#eg`n zsaNYNgg;#2`HN>ImY6<0hA{S+D_ZPKa5OQ(8p*LP$gJL^qFS1d7a=%5VdG|vqJbPSYZ!7sSzA7j`mBpWDMDZlw9r&cr}Bz{{!eaa+IOVa32@U*^4M zxcPcSibgFnuSl%^We zRCK{)GpZ*$C1 z1xtJ#4bB5y0C-fJM4o_LXm1&Zps1$;A|i#ss+Tos1n@szTf2ll(}fc15VQz4pT&0Y zjaJ^v`robgzXg9E*j}sb{$%i98vLp7gVuDuX1LztQH}xjrM#E-Mz3;k@d8SkxSp;o8m(TWBUq$rJ4^ZVz<_rb5hPO_L`TE!c50N=aICF97t$^U?RLiA%UsQwP>OG?gxe)>nL*Z3C| zP{rEGgt>qL9M&W$b2ia$%FZOK(XtnRk!UatY2omqi60$IJSQo#sTLksG_L3{Aws^j zo(U#mw6K61_2{SK)CGBnY&kP>Tp>8l?EewZRYF>BrfU(ZeodP(F*P2bJVA;FK zVq!lfbv-V6Uln^@7r+0fNg@iYgxFA*A2wXL6eEQpJjclcyCTIU(ZNEd)rt$O^y#6vCkq-B*FVA)3vK*y=yo5F z8tLCdP|J7fU!rPMX{UTTh;YNo@qO3wz(V13*`)^ig=@{=E`#}&=%O_k(1yp2E@IS4 z`-Ux|FY4I`W?dndzG)sFXx$9qx5_*1d}jhH?gR+j-uYCa)XO1 z&FNn9G#N~wyikyO30iX3`v@nmahMGTG5z#oKrZvDA3vS)L<-;#Nft%%ils zYhu?k*G!RVWfT62eqj(z+z0!WM!^LanK1(uZ<_`1r!)yjLR|$g&_edXA&Ib*2TTA0 zNQ;?q^hf#R!fWyr94yphtj=*!m1*~W(jp(%O-gyHlxJ0sA%o~X zN9`+e3P8(iP-vNHN}rVvo4M}To4n~~k#@+S29@%8%|vtE9HpI1 z-@ZY31L%`oMdN21U}FvS=oZj%EgZ0pK7?h*%{WtO!`|N-+Wf2{;>P?1u)DEZy#FfC zc(Vfd{XbA_wjcZYyZivTvX-Bjf09ejfQC|K2zX{kfvAU8GinyPw5T;<7!q7fhqfbx z&#``*;S8TQ7_p)ndcQAVW9Y_HiIZHrD^*}M2w=mEVl=_kjSla1)9fL-uPlC5NRbaq zH?ioASq+GWL41P?>KP8PE9&0oNPOAf4J{BCDrf{E4E|pYGqv(0O&L)6fn<&PK3AH(|}?KQZAVdV$$Z7^~K|F#;4!5 z??qh#e<&Ad1Rq5O3pz)>%Pz3}a=ha8S-e;~bKyF%5#<6$jYy5KfKf`gsHXsGP&(v}WLxDm!z*gO{fu8YJklFz;Wk%LVkE>gap-U&{yPj-h@2pALTi$5 z%N`t+Yv?Cq3OPAHgWZS{SbKbfI%~2 zjGfzAMEs>KV2VdwKJ8P_BdBJx`%!AdL?x!R$@sJ!@FSI+XDpM zmwdcs%cN`tM}dg9Pd@rblq+VWUJ2gMTs$#cRni;ZfQ-6c>xCd4t?4$^h zPeqJt_pApUf6Jtl))N1HN8dg2TGL!CX2oc>>{SllmUk*Li44y1E|;U(D(Dza+4ug- zjUJUe87<2SunE|zygFxqVQ`qdHw@5zMLrfZUd^?x{O`NK$jMM;_ z-bXj9=CXTUZtk#ECBm5g=cT-mq`JGr!Y|FSxW`0@ZFyH|7uDW2e{EE3vyqpnad;-4 zl}=eFpYFIL|5QTEY6_Xz%=s85X%Uh>NLQw@%z>%nZz77|Rkkx?ruNR-31;JK9->MW zf#~Wda{ZhC>_sl#A=NWBx1INs-e+j2ZfBwei z1#vgu1ki$GU?j0AQM_-kWN}&iT$ixUbe%I{w0AbM)qrP*DZg=JyZh|~Z-RgmmJOQd zubCu>uIf4d?=0RP)qL79O1SnVT63`0 z@wK;@kG1FYH+1_w?=_5bMT6_7Y4@Ab3*!{QnbYp+6+McIYn_Jf1L(tudu?CZ$ zEs*?eb$WN3VDv~wuS0$h1;at(Uj4?C<-Y{N!fvrug^LBx(OT3s!h>;`0k- zxsXPuJn2RigP`Cbeb{J8*}$@KypgF<8m*%e+bg-yEzc+oxRFN|$TA2yc&G~s2q;n> zMs(ec``&a2-Wy-MPPlfSv~Aqwqj`UZ8!Zs<*~Q;%PMg&3dabm5yKdT`QeRk9<)M^S zeYA%IbQlM1X%c=DM)P@SewfRFslU(&p2aCQ`f_$SwHDtsb~Atv8Wi-)%L zw{b8;U1U6JW7BURjsyhZc)aTMd;a?6XU=gFBh0#y+h~LrmXe@E9(Iet&)6{?zU(-Jtn-$LhlHmq zJ1ZWfIN2~$ljxuwa^0PC@eQdwK%q7SIgV_i4rM6mr+KCC-Kv@MGE~H_E;)Fu`SGkE z3Z=|VNr?lhu+ux5mHNWiQVbe=;l;=cS(Wn?2h09DPxousRZ3&m1~ z5q2Io$AV}J?LybzCN{c~?|Fuqh}wtC*GmuWuh~9jk?hyRao=~1DKuEpbZbgdgrJ^V zU~mgOOdA(XnMTN!jtZnVnrxmm8Ovm~c$Rkwdml9m7DeZh#w9+51CrCD+{R)UUKn^ z{L#CqH>3!oe@I4qchqP?{8aN(ph45wJv*o@T$1!>leqe)e(X)~IEoH`lVaP5*aSi6 zF$z(Pss()R)Wou7r>#4*Env>>C5j3<5?mlldB(sbZcP6SYoiwcqPvdifpcz zKWnzL1Z|g*X{Kqu>I5eGmweFF4pGFXm4E!1&6rvUp3^*LH?Qm~I$7pX3(x(_p{9|Z z>f8`g$7s{#l26^ZiG}x0niTu*+5LiXI(*M-MrGHev{Y-5vA{vbfU4AKV+||SEerufIue0qnymdW2bn zj^(taL5cd;o!J~iStxA&xA{d0%JvLjd12jkBH!V6grg?5Ry#eJKE$U^Of*lLz8df3M~R{RM(UKYvsDiX9>PHTk*V@ z@05=vipyE7e%~yOPKGAu#w4p(@l)@~LcKk`1XGimCU*XPcwJ81USlIKoK+-72Rr_- z%Fpt*tv6YrlipA9CgoUA5L8!v`w)NHuV2`RT^s z6i{(hqW5GS3jFhrW>fHpW~pP8i{XsG_oAs(yxdEE4B8g@rr`Q)3}|amP!CvAWA*e} z(*JK2GYZJ|UeE3J5~>SULP_l%dpb7$H6-D*>DjUZMWq=Zy-nDA{FsvUyWCbUH>IR}WdHECV1#AD{FuV=N*Bs?T0@P0)%c zD)7%t6Mt9_h8MmowP%6FY4@^NPS3`NRIu+tKct<7OxzvZ!rI1a1UCfk4hq%!s>R4l zs^A3G@opLQx*0CttzsOwreL z67U%nwl1IQMSZ;+-HY^5Rd(&DKG0Lw$4L<-W@3q;+DV9^gYld%MewU;Lg0^R6q(aE z!em@pPfTMPaUGP^E?0&fFR}9ASRY9e8EzF+6^X^T2p;xijJlGQPAB_j4n|%LZo?{9 zg~78K+Jt04OlpItg_?vH3$MXu@U2geOc1FLC@#=SbkmE zH*u%oTUEk{?INcSgeyMJo^8Ht&mBnN3uPVrze{HO(D*LkX`u%y+f$*~;p}r35>;9?E9s8SCX~vCUKL-9!xc? z*$SSemYJG4p+;o`g@~U2&2@Nj1rpV)PsZ|=be9RD3 zfWdTPQYu~U3st?jQ=eeeL-rkLwL_BwJ11RXjzearqZg=|Ifc91&pcG!n&}>wqL^h$ zeGA5Hc1%il7CrqY9$=(VeE>7rB+mU3loO}LbQ}=Vys_--^nJL}Esbdtf^VQU#(Ez{ z0|&SHP6>{$n~Xj1>%pPdqY>}+MTxVSgFL1Aijzq(ETBO^r?U z++W+-XPv*gWj7c-+9>*U*t=RG9MR!II#DT_S}7AL;kyQDyK~UtVrXL7zXbljJFiqb zN&Ge9vnpctTDu3^S~)B)CDkT!W8UZ;KWdgG-VlWY&nekhwgq|U>7qWQ!1jE2;vj_ zvS5a5mJ#*xi8$Rd{Oz?r*qCNwm|={CmSHKMwKtJhuJFyQzBONk5NnD88+Qgz8>?K0 zv$11}ZiL}UII`CEtlYcF_7jlp_QURi2Qi7R+@A&b1Aqu(QIYonTw;bfI6X3%AfGmK zh4QpnNX~XqqU3oMlO7J`r~(p$(LIO$nl__C-6)NON|q|3nllvWY{V66!;K+^FglW} zCDrNQI+|;{&1+3oJ>G}NWz%dPH#DewW!cV7MA_+O6h}BlVcB5VJGA}STdc6W8+PHC zmw&SPWMW3UxVZfM)?GLR$I&hO2V&OU8zTD5Bu4ir zxSKplMy{M4e4lhkNAC|33i<{F8?Jx#(grcexuC#rvk2bZe6W8OFl#CZ$biMCi(F4C zr%SsqHMCz%*!%4me-`ixBvREaB5CWfSw>eVQhM4HjGQj(lqBXik=>-v;wTxOlW zt*3j>+QxCs=6*z;W4obW5n5l5z*S>MB-mfAA!*JIPIk!b%vu!lt;>ixaTX~#x8|i9 z!-XP)GOMF&EK(yGNGg}F560MeETzP!M$^lvU)R!Vk+?ZMxF>46enAk$!V{E$CJgSr zMK5}yEp~S+V)z_QcfYFMznQy(WCBpyUKzCX>h#T8=$l9m_)D+(q&wT=oOq!b%?=BbzJPonK%5}rzohbsdU3Oh+p`^X4-DW4p(y!1_vv7+jSK6_3#(P zcV1LbixO5cZQ}1wQ$OKoYkn-L)M^v3*totle#uH!c`?ZueuvrX<(}r1*N+1cVb9TK zfNoT5G&Ol^jf6`PQ+~L(<~!S<9^*#bQBF5Gz;}yO)K2?n)sCP zg&3L@(eW7hL3xAQcR6spn4GqR&ar2N68O^3l8gVUk*)Dq%OdWFBx8}K4gyRQk^A(T z2>4Q#uX~MCAG3vsQa)sODe=4(^ zv(rv=#doRV;wiDJJeO*-rwPF(0+P|YJUau+CJ--5Y)#apcEWgUqsE6|K`8Mdg*Cy+ z%lE}jLr<(~V_$?WZQ>%YmLK!~;v_V{8uAtI=!Q|9;k_X$!L_X;9(1i@6SXu9K61(Y zo(?zKnmdQsM{;dqN9qGu2+V!fg^Epif3DB3{Q-nv&K)ZKkd3#iD4sZHo}gwqrBh^b z`16S_YcA3oZ%FZ^9oI_n|@d{n42b1z!GurNgVb{lcb$fAwE4T@2j)U)P>=i`7246Ma)>jX5;uY;7_h zqSijAUu>anWzi`JhEf&e>`G+V196<&MrMGkgS&2bXNxFn{lXN;hZRn!|JRS&>)p_= z_mBp!e!KQUU*PJ~V)iD&+$t^@|2i^1fiy8~X|T&YECu zMHUV;@7=G_v85^k0fS`Pjn9ZEP}FrXj_MIvS^AFa8K-xM^d?)aHcLNwFG`ZUrM)|2 zP#Fw0SU8YcmTkY$!EFCDk$qdY=U#dbSjUgrgFtZ^d|SXBxU`3lw?9$QMs{eOA}INe zBG&|cmaU-4bT{Fux*Hizqq68FoGaT2AYx#ZIq1FK+zZd=0mV`A=5q)ovJ`Q{Qg71j z$$YBvurog-;>V&ZhXTr;^p)fev_!C?W;;DLleD?>x;#0NnU(#Hx|e~S*)G#Wc!Z_w zH4#J|9faHCDl`m=&KIIBs!-T$BMzgv2N;!`?b-dZ8uo%q;HCOm;pVxWj08i#t|!^( zyp@7fv!kA%Wl}0}FSOQM$eXx|{U8O97F01!a}uG`0se(E)gz^|b~cBn&8c@t0iZL- znzjGGn$iyOEjU`6z=HZ#dQ>Z77hYZ%KJ@hZRy+W;C(=ue8L0`F){RSr_Y8XGtm2f4 zw~x#9>{VxJI}yM_Fu}$cu+Ywtu%{VVs#_|R~-2RJ@ZLEORX{KEP7F^ z-tK@-PnlO;tKIH)=y_NKN`p08HwLKWDxHR%Y}^oYI%0pGu}VDIb&4I294FkrU! zr;ccAOQisROh(eh`pf~8Q2Fg!^JWnuuNx#2=^a;1KA0LX_>Afe4liAElo|&B2y#4$ z*+0~WW@}hyjZC7rk23lbcY*Yn=8(hDA9j}x0P`e@{X)8x|ezp|?c&jWO9;<#d{CFia7 zK4-|FeLc4{7}LA(Kii&@vYXX-AstfHOHE6}jfRU;_p*=5IKb_T{@ga+hWovO@GC91 zdIj!vB$uxAJk78geiH+J&h*?%fEN>FATC^#qp=N_43oXeizy3@(hhD%!^?Cd^ghPn%+3LLS6x_XvyU4lVBkeytKWMN~_O_-ql`5_UMCH16O^u697I5 zU+21J9;b)f^bZMR6Y8D3QL7AN;bVIbV|r9ogugVpHTGLQd7z%ch;5Bx3T!Z==+VEw z+7Sd)*WzN>^G&!j@4R1^^K~ubnD`CEfq~j#8o+`f0M!@GiJ3t%v@Bm|v)us5bts)S zfUo6KxkHA;$bN-v;vZcHGn5gvmQif8(j7XpiKx{EG6B@TfO5Kr3*&vwFNg4|dT1n>16zuVX!K(XS!~Jtdz#ZH{G0=*@ZtKWebIf zE76MY$}{;cjUGi2ChjCpyyoq3kxMrlsL73mA^55hHNm3Zqg`*99$BWw7N@RwW=a9tltN(laqgZ zS$|jom?YIZn3{+Nd&I-%f5KTYBo(YU)pn2+$&xSNJ*o;7ljTeeI}GTGc}8u*xm7YF z?gz7ah6SBz9Q?9z6HCu`{qDP@1bm;<* zOVLDhwK9{%RlOP|7iCcQ?8uf#2-<@FW>pe>WVyZ2$Tf;*gM?1U%5HpsZ@|=ZM&Io) ziR^|m#Ypg8#|&fcQ+N3|I^rjUNWmxr=SI%JA0Lat25^i+Mo{cF07FQ_?Mx$i7%>$q z;0o$EjK7cPxp;Su%b)3k9kLPy{PN?c(SwQjNZF!EMg`$5y{29XY5gxD>y!n=A4!EQ zd3owS_{h4?_W${&+8vIVBHI1{F*4ii*1zm0dNAcOO|y(#S!C%e#n;<=_81;tSp6t>Y9@zgRJsTr7xBW)$DihE~Yha{f6mMLunlCbYIK4k< z)u^S{J#S5UgDjmYBbYl+W8Sb-N$bF!nNe*Y%+O`XTbNKqsz5~WKRbHnoksKmNek0$ zokb~W6U@X3Zx5W?-)xlJVwFl{)ke-08Pi8(%x27r) z`hSxn_AUqfiUO?XyjE_^c9ZZGR@z3}M@TbS+^qc8BLBSMIX>vFb95d%FrTe9d2MSn zCCg1$(yO=hQsnn(+Wr${MI~2`&aUn_7@7gLZU>e*t(nN*@p~TKW3TE+S$NUf%2U8n zPO=>ymlztzq2t2@Crm(}qhcrt1q-4h#MI^NMZXLYUpI^VKx$Y*Ge>`C9=3^Ld z^<$jXck`)hvc6DSS|*^9g)82?;AwjDrOv`lU`@rqSx8aFA-K2Ord=NN$7~1~EvPN4 z#zt>jeMVW)*4=sw?qs>nOeoH>BvZ8OZh7S!)=PD8gswu@ws7#50r1oIZb;VsB`_Ch z0q~|Jcfn5a8Mu^6Y}mMOmmR=BCp!dscTlR^5N$kGjx|yF>w|)oC}>y3(GaQ!`X9i= z|HW~sxUb!gMFQs;O%kc?YRw6bi;0LH6SNPmCTvoJnl(RtPN|RT%&L?S+JjWHuK~i< zFG#w$AYY@==ng{DGb?t$MY9rR-60O+{g^yqcHtcn7gkH4Ei(pa>bL{GQ$IABaFj`s z3Lk!S(NiG@kr+=$7!x^KbZ;Om^WjZNFe{DyOdTP9{65L_i4g19_YLAlk}%(TYFDp% zAe|sfU^LO7>T)vgIXz>c#X2OfweZlpNVINkJJPr;4vq~{82g$+lfEk+FtJwMDoY?1 z=}zZMs006{u3iK*%WGCm&;qMz7}O%!+wQ?5(lrgD>2xKk`tE`o_9V zFC$EGY!3`N)SMNX$l%Cn4I+1AMP-=hP?y2c1TdBbPUkargOZ<7~&U|O+n+OA-YgbTU6Rk{S z*#T~HYIT=pl2z82mu6X3dE0gdB;K5blm=KF;n%IzcY!9bgs($|gQ4686jWBlm6m`& z2TyPfxzWA5BEJlZ!guNno>XHZTPJG>)9c;=qm>2)ZDxV1qQ(qJlsNX!6&%1&e5l~? zYil0LU3nN?ThB6`DogyY6*jes9x8CDTpNFdwE~Z0zVMrAj?loMz7A0D|1;Ki|67qV6Nz$EHWtmuOE?KANeIQa=Um_MtK45}F;CvqOTe)m z;h>He^#kic70jTz#Zlk*zKRr}48MG;>#{plOS|6Y+BU{ZJdm<9Dt6K4&!#d}fL9gx zId}gTM(s8jFsRIRZ~4z@xNPuAgDb;Ieut%EZ#klp_KQZkRi2^70$VZ8K%&DFd;=!c zI-cHyi!x0m~& z6QpyR{5s`osv)m5r_$h-j|bhP*GDXIT=rL?8Hs5-tTth{8LRJc8Y_P?i~fJr_n)kgnii(lZizyo*9~sjq(dg{*r{ zQTjb`QKol~k06@yR9~ISlMz`8ehrABWWPntx|^zL6f`yc^AAb9-gyOjXTB7BB7Ccq z`WnsrtokNWj>l|s%sG7_T5&oa!|qxD>Y>SdJG)9r;frY+ZMA*m9&1hW+7$b-ic-@B zRY@SPJB#LOS<@l!CLU6OwziheBk8Zaz5k0Lcdl#C&)$`ZC^K8W06QPtTsY}RzhQ;k z)B%~95QLIFvB>tj=e{bZY8lf31T1+=2mm7xBaJUU2Ec;TP=9gkBIX0cjxhv#QVprA zr@Y-_f}t9%JIwP50YuzGe+sY_ZcTjc;q1^`%;$(a6Oz%rmMM8o!hp5y(RAtEZw5nb zh?$6Knna=_o!kg>P)*#{cqxfexD8TVt_Rd+4+(oUjIX?5YcYv(c~}iLcIL7X{7L#)I2_-o>{q)mkJ9E_k_LP z{*;LZ>3pzSW6l!*%^Z)fOlOJg+VT90O7)c>CwdVxl;G=e5m#*2k!3mt)#VA^G(3tk zM^VU@J*hp{IgwD2>`PjW!%Z6(pDd)m0Wbi&a4Bh>1*5=DOHD;=FWr1(fXnjdO_HIqb-42 zJeTi+Gx{HV%))iD_X#KA+7#AfI|SS`=C5fD5Y5vW15w+BF$|h(VH=i}j}x6W%NUg# zub3h%b6uMxp)}(S4czSKA!D%US-4XY)D`>{CpN2&X^t+{2^p9=!VdC=h2n`69jxjT z)tFYQ--}k>vfcD+_JhIklt(eoJCsk_mR{4?zJA#pz&MN$E0ZVT4Sm@>@v|TIL#6nF z7EOcMeFs5@T;4Om$Dg9L-K7$&PScbv%k4jSHDF_;GVRYCyMF1`b1|^zH!^a6tRIZu z-Ffcyi$7QyA3*8NTmA6kj)h|j!&)wVFFVM+GG^PFr zvS#)(`S&9zOQ&}<9{8oxCVtCMd<3jzxkf3JQhzIv0yf&UpUNKzz8WYZOrsj7cqrFv z2$}!6P5dBzqpT#fBp~gADSEeaRAJge>mr}m;>z1;m)R-*%^05{eY`wjS334V%(N}i zhQaZf(!!8}N?p_(%aZ2iZ~y-w$YE^qnQ&fQpiU+z^ktcL?^TBk=111j<^n2nfo{zA zddU!enPWQ|?A|Y>uzaE;OU((*oMB1ifC-)>M9k{^F?+-m3Ja-@m!C~BG6|kqNmktF zTNUo=JK=W3h?wx$GG8{kQ7ed@Jh8rkP*X~NmMk(5EPQAPqe};aJT)oy$C}53V z3>7GofjiJA9k*(h248M)+)VkqI*zRIxH30tm_lu{URZVo`RImn`Z1=fa-&KoU0+DH z8!b-(ws74^l0pJ^2AwG+3_g4kjtUfH{oyBF9E`IL`3K)j_$$UtnN$3aXuel@T$7!P zP9$BP!uc#moA{fv>&qM`fBOl0+WR8ZC9iR6j;r_EY z;0=0!T?7t&p>}t4&sjIi|KEds`uvc%xHoz{ac6`Zi=Wo=cVdiXI#w&0?nd{*OD)65 z7UqqO3*i(8;OwSJ<Eq8p zB_|@ELdVV`)gZ#Kyp5uor0I<_V22`X5@ks*D0m>8@edVv4yl^*%7_MW-YLtu-w-R_ zQwsd9EZ6iC=a}V*f;!8bg_WWqSrG|H-Y9O1)^G(kWy0KJAOTIEgTIhLU&$2pfHQJ7 zyT`H8dO#i^Yq!kGGnCOWN%xDwf$i=f4a*1Kh<9GCi$L=}+(GqwghOUM- z79S~+5SV)T`tA$rMu4;P`^E;0{JmphGihhewe&f(ASS7G=h{QvlR8&~PC={(eZ?jk z#m$|=qNv{)+uNmGIrfw_+~azJ>@I0Sr)8{gZ@zMzk7aO|Q><3D)9odzDwxB#^BNem zPVEA5AJq&EY>QQ3jdV4QrmFpKZ#@q@eXsf(p1(PQr0U+knm>{F6!~=ii%7dwZ|&{& zovgRb3w-OfJ>@7=2ATI**{k7709myH3&uJqumoU67JpY|Fi6V=faC}|$GPH_Lg8Pg=PTost4f{MIbkn2#(9cACpB z3B{8v5LsE%Qe!ZWmXL(kZMiZiVECgSpg;lrhm#Kg5-)bZO7l0y#IlZVR@UY?qqJo> zTik-uS7tsr8!gvCeRU4zWL=3(YEFEW4$4bT1_!zd)c}%ay+8kF2v#iFrk^W3qaL!Z z#?R=ADN7h30mh$ympZ_Wro)u@aAGbRnQb}VzU=nhy1Wa8jd zZ?&RO5u+m57Ohd6e@h#D`kxK#uX`Jo%V4jvN1#B;0lX)aoPy38mwzvi>38DCQNH=feWU33_@ zDzyniSgg-Q5rXKn9|qm&aE>iTN;>^|U!Jb%>`Z_QyB_N6;83t?X$QRG1=3=)-aHcV zyJdK(0xd+if?ji@NsvRAwITpR{*lU7ZK}nduyAuLiZnBPwOnDZ3}h1^ZfRy3PIkNc zeWXM#BxM&B#Z^%VOXW$YDXwBKWlgqHwjUy0#+HtGI;!_*F3f#YjOA|&URHnHmW+NY zdDe|%N;ey+E*_CMR*21&nBEdOO?G#L9P^ZT~{=MIs}tHGG3qyN?ff_0m?q^((lo(^j|NC&zm38w=j=KA@pBorW2f z74>Zce6J4m--0zhg2~PPJxzM=9qPR;$NJo++Nk@flJM6p6?mg0Srp5!pVtzkLtn?x zF`%N|nkCS40{tGaw!KfHOPhITARy4`8a(luJ*NoF9|$=L*`=l0d!JoJqf7CUfXq_s1-pu;ldYReV;$5t=;py1Z(Ib~@W4n}zVTYhzf6 z%g+m{{yJcL$;PWuA{CswGxKRDim2yvJeGU$pCW_cG!?an zdoj$? zKlb%>((6)G@M$~N>(cJ=D0(yzn8qfMUHW793yz>{`{U6mqh?||dCpoEg9}N7Ew9Qt zhOi?ML6dlA{8CeY+W^$dw*zMY&(MVqryOt_=Y~#7VqYqswoDC=nxMr6N8Zf0Ny8nz zdpEpn{|UmBcI6bU6c8;*i0Gay^F>G8jzrAeOeS}1VK9W z*;3$Bq8(6gw9%S*GX%OyiQ*76ar9?*m>51oVe zqQ)~0{u@J^gbdkN{-#A)bP@Z9Z~4(#d_yOnqBk0f|K|2m$SIzq!%KA2r*@)E6X-&$ z<}g8ZCOjhI5+OQ{lI!_5G4 zYb^Xee8X=TJt!Q(0hGj6^>*D%;|^bG0@GRMx8mVOsnt??k<14vPgG;mkd?p8z+GBz zrM+y<>OJDLrdPv#zbli2-limKpt7b-?z2|?ERk$nh6J;}*nVK_GeG72xA+w@sdFxP zd$r?S?cH~x_Y$&u{^+0Ubs_k+rLd-4L(mN06`FBMH!K}GLGesHl8A+?z(|2Q&h{i6 zx_oTJne9jkynf$idgG{zT$n$4w==L{S=OD(iPtw@*AeMpR>`qa#O2u%T|}Cpj9i7& z42=9(K+`@5)pf8!CyiH27NmP3;V}HbFQ8Mp3Me(vD7h+Onj5Bgf`0D)(fUePzM z=J1v&nzEg9pE>gPw$uO1Q?iPHnj~Vpyn4N28%>Q!wQ#AWOiOGuOu;{iV*1KdVxG8s zEFy7y;-O#zlKYv%pjZI3h=ygaB6R?lecoC!+&N9oQXA2$J3VEb(oTJ0?xXT=o>oH7 z@_+wQ$;MAv4IytgFsS$pq3zFprZl+cOcJ&uc@ot0B$-uIJ#%P<-2IkHc1K8*aUdU- z3rAjA7wv}d?LX#ODv8B-ro7*?b4-}Ror3cf7g$R9Y3dwlE$01v0A)5Y8-UW>5e^g& zo_?@a@U-;p)2#DC@gJ0FmX2aQjMyATOm%n(V14UHlom-szKKMlT7nl8mg5{9`G*ua zaz)l%;zC$Bhi;MDyNguB)NhzacPwK78+I5hWP(M`iVX{Yc*ck$yIWJnl$>2k51ray z1Ezo-0sH2p_NPKax?ZDmuaCR_I-cWF7@xYnD7@`WJ|`)>j}iO+i+#Nf6|l=phBqL+ z6XaGSu+AGv*w^ny{W-}WJT*{Af3Ygpy3XJs+5 zlyg!2UTc5ZLmul z&icdt>S%pYi{3rZa_WEkoH?W;758_~IZgLs4=<^yWq#IgBEWxp#gSXyv_ImFiwv(O zjDbf1V~!(m;dWnXU=f|xueh^@=4SjD>5O8q>pDl`S<2~cXx!C1qwc?nz>3^`*q>MP z&+s=mtNHeh{9bczjjgx(yF_y8V|{Qe7jRRYQZ%hZy{c^G=uZStc2lF~+`mrR?5Uu) zBDC)Q)TdHnmEMShpYpO_e|asm(Pi$Kv|t>91?E|-O`$B_jno(EW?E{WIwX}JM$-gF z|G86(JIw;cgUyC|BXQTkSnypy$=*GewZ$?M=~LB_9Fh;q@oXGfrrwJQ^AGJn-dk`^ z)jSWdSs-`Xq_xI4iT*{66Bg9iLLHQ;G+MzYcSy72hzQz19K2xJ%H$Sc3`Lr15qdHf zJl_?((damyMq!W-d$ak6n|oix+5WE4{*e26$@tzosqg9Bibmj`{w`~@cT6zH^N`g) zgogQp!`I|sKtFLmxjhP`EVB*lJSVN~9ld$>IE6|o{fuyQq zLFk#515hDbMD&zKS!ce?Yd|e)GpYvm!rW{N2j*BIgnK#1B@f%B!Uf^}B1AaRsJVGz zX`jemKDIo+=UDry=TAQ|qb8cW9*RrNtrT2~82L9U${|FH;}_5B=X zkDkOi4jJd{aFxjQR9;HoR(uzV zzJWT0E(WO|1aIK=h~s9mRfS10B#nt`>p(m{CMeV3;XHoB>jkjBM>$_~*(^|vsV%nH@LJk9VxIlOpD$#Y)x!Pm5EuMgB-~i;?o`CtUeHL zNaiwb2Kfl{rc)LljU=BjDdP*kCg}F% zZ(;zq+R&gYr9u57NDs8=5lf%R1XRIOi>mJp;`AA68ncxy$$q}kYeO)d-kgFLPU{Xz!iA1now>40s>s<$@{?ha6bGT?mftDH2pM6 z!zoc6fCewH&0UOCEcLS>^QA42;F~5!fH8f+O`Fh4+l9*z!1E9@qagcYz--3-1!;jj zvXq-|o9m6`d0T7aHrm^CMRB}EwEa^?+sn!TqQ0bD$y3m_kSZuL$`-M!UKjcvaCFYsk1TcgeCn({|rbTRp*VJMuY zBIAqiL3#-(X^oh2Lc;l0)k?3UNY?lZhJZS6W+5BjwfNJPHqjA>Z&zw=Cb{t(6>*YOZuVaSyf=h6M zyF1;uyK8WV#yz-8qrn{-cZcBa!EJLt-}{e!R);l4jaqBYOY#3Im*xL;As50Up>p<} z$$@{Yy@ft(OkSePrD!r@{#$9{Dmvxx8*TREJq%baR9mRW#)po6JjT?#C+FVc=eBu2 z)oq>$AAsKnNWC{v{SNztT{{{Zh^GuR}otx8? z*ikw4uVdwsMt-#VYIVa1jIji-d?m@$5BGOkG&$u_1mQzfEG>xuXKBG`%Z`9%xq*bQ zRDB}dXG`y5A@!X+UpPO)zZVmP+u&L+vlmAWA4T`HyczJ(9L?=Qe4A^{@Xkh4f-Bos zC@ZG7^w5p|bY%I`vkW`U=ES(XpEuu>>#naxRN!vb*8G2Y7~H7v{knDadVdxfEg}?8 zQK!=Kl5&NT3A>ma%{PsxB%@_EA3=_G5z!0_HkQ|7?{_B~g58`n zt+$p+P}Tera7{Y;j@YlF#WiUqh_NZS#v>89+{X1%7u7c%KhtbtM=EJR8`zGj2`sZd zl6^nDV)yEDzC<;{Qs*Fqp*8l_rlQE?%I8-`lMMVV)!2uZL0C`TZ7vv5YP`vSJ0j8J$$ zv*4sO>Nx`Du%U(ri8)IE>lSJFg@L=H4@2pOMhcfFB26TM(&>T*Udb1QjujaSOZGJsEewaR+s*yj9mOfJr@NKKMNGT^ZG&N|K@jsMy3s=KN+xt3aQq|r4#IOo! zm3avE_hWuOr2W(~8b8PHcO5bpjHZLT`?gr``t5rqZezwqMU&_lyUd4BpF#?CFFZ5u zB$_4skS$G|#)1hg{9TQU|5w7pWrt2p^c?yX(5zUYJUVaI zREgwPB8>&5Ic2QC*%=$Z9+Qzfbagi%tJ0WA=&W%9e22pPtl!HobFZYVwoH94rW7(_ zCq>@?YDPQt3M^HfX04IM1<6!cr{$zV^I5lEC!EE3oVO|wl`kXoJ+M0iX3nmmFwJk; zSgC5XRPY`p!n4qC0LTI0;_16be{yrTCtx*>eiSr)TpS#lsRSl$GbTbKiz%dv;0Ip> zmhSGzU$1;>JTeh3C-@9Ng4PbF(ZHv~eC<89AA4L5h)RCz)|;1O7VHD&zJmvEGgAIn zG8?$QOO9x&Pct;qWofDF&<<27hl_q8lfU!5a#dpgR%Yry^A&%iDXVsA zW(;YaFbB4i5?HO|G*LJ>^tiwqk)il2G_{j%GF-dQct1+u-KF+LH6kk2gOHen@&Bt9 z`;d8E)+Bg#^PBIv^tDyX9>U}(SE5rgsE(%Kl34OsN5wPFx!oz{jQ z#c#@^8=*hnPVVx*1pbxyHQZ>{Iur|*=H2hh#Ii;IrKB{MDwDhaCtsJ4b9Ykbc z5Ptj=Q1QF4fpyVpdNJn{A2=|y(eum08YE74?`{_NfEC-S&^OvHDtx-mM9kXHE+B#e zUDJ6zemsuF*vD3kI776v5$o?^5Zj}>)ktBmCO#*tq6^CO5i}LUd`h2a8>#U$;mX!zD{P1#s_DZ7oQ`i*~vN%R0QCRx?nAO!FWj4A6y)Qu!GM%G1)=3+44 zyJ@g7sXUCAHp@D(xG=QkV-4MG6(jUNegmHyJPNe5d%C6~HIIC^JKsQ!F%OTr7;-Mh z@;>>$Ed}F$RA#2Ujhc6ev#JJgS(Wj7}MxrMsK@ne`8};?Wtdm8Y#(Hgz-j#2P_E+XkDFjmFn?Qf8JapKp>U~Zp zu+q9BXl_irlS(}q(wZWR{{8u46*O%HB24asaKd@86#(YwykqrR4Ekdqj$x;84fB<# zIZx4UuwqnI_q^*F-Kc2c%&nr$aG5YqQsdgLF~4&r*5y!eJW%hjJE_b?^rnyRd{WC^ zx|_ZbMJjM!eK5;=N$)zASNwz9`M7j(m-|?;@sIL-=lx=v*ZTndELD*YA^T~UpVK=# zY(I025kzx!-T5p`roSDhl?g^hm&?;gi*cNUFo^^ho=FH(bLl!uK_g3TKEG# zA4`Pe_YT+dprt9+OVb}-%_vn0<(DPA{2;F#NAFp&>LOoaPS$d&>0QTzWT^ysHR{(x zBtHGf(bXpFT^~o~r#aBeu$en)FF8!yN6&uZ^F__MPaB|-IJ0p7zux349`g0z>}yaN z_q)4X3irCjnjXDl!La*N$!XOO=C}xgu+|R$jZ=yh)o-zts(SeJXSM9(dGT;iVR7l^fjpsP1r#C1vxct z{?4O%sl(GqY^%-Yq(n+q);T^+H=815e}G_8qg$W=fieG-&IyRcHkiW5v_}JLLfN+) zh%_Kim}j4NXQR?{s_jExs3;6#x*-rRuS^7>Q#*^~iwWbf$bM;$`M9Z%9`m`hrTSxInqxa-(OrngT6T`e2{)K_*9NOamC!pHL#7OK@ql?5Y57?XUF+@9!=@K1ESDmm?q5{o#L=U4Rqfn;xsOMsBm~J3-7eR_`)iq42%+A>$&mY=H)AHWR;k%x z8b_`Av!0QoJab+U|0mckS$HS1Se5&;Zrj<)*B_7HYaY`S-_>)$-q2S^xp%z6HWdfET2A4`)#O!=@<_Yx*(ox!e6=TeDITxkPkty!;@Ab-D zc<%BW+5;%3kn62u@YBYX2YcM0?4}K5ul`U|WmH*X`M2(XWQ)M)7xNhwTM@km0>4C5 zCOn|*Jvm}H&k+u})Davmrced!MI}v&=%!3R*>PkO zDr=>dMu&6bVq2LTkd3<_PpP_hwkKzOR~w29yM}FZ3{S&$!cls&6`lMg7U=%&w4?` zsF$&-1%N35FN4!SGH28*SqvMX-k%gQzH@B@3&>^E7mqzi+&B^xmt>|@3XQI8_M0sf zq-#4#=oUXy-{=FzGranl`xKb#wMoU1{l`?Uv4kD?xX8C{U6_8xT)Z`yP=(a#>)eti z%^@GriPMmz(&cj(=>8|+_otb-;mh$`Q5zO&Unf*r26i`Td>b}CqE-T?I27fB(J;7T zr9t?!b4rd|frD$Vus)n?ro%(ez2#0l^O(`_rm(Yx>8+hFoUJ;uS1U$r<~Oit&JnjC ztmV%eV?*_9EKST8p>(P54d~vj(C*Fuht4FSx|{k=N3AZqH@P3TR`!nhMdD}ZQB7zq zD@O1EOWLe8KEV#wwh17hLoY-7xo!y)ef7gtph42b>9JGH$vQ3$nCSeboESZN2Xr=QcF} z7wuTb=k!ZD_B7w8^Gq0x1ZTxN^>VXKKKwD}ym=a`S4Q0foqHAFjh?aGaeiv0L1N%l z$fLfvC%f3LhCxH?RAA>a9O(lzXH@wj`A!h!GhK+ZCruwpN6^%g`k%v8`D_%-uhw+Q z8ko?vU{+;n9F}gN3vu`twepDMK|p%rs6%aE=h{w%yg4Gt^_oPEl|a)@EB!PjGa!9uNy!-oGD}B( z4agr>EvBmpV!PrVzj5~2m|6+q=+Tsf`% zVNFwfiQ?uLSoO!6Uq8~l_*~};0CJ0+>+o=m26uAF_ze_;F@L zv-LHTvrug4LKzd+BC7|o+4VQ{#tLt>yTXX>(xT5*j$%6?(J~($UMdi)2~aU4rh(RO zzz=;Ij>703US{nCx>SYHu){SSyaFbi(od#W#h(I+P1U;Q4<*g9@HA7e1Op&hah$8{ zijuV-Uh)#TprH^2uqKOEo0YkUB^KIhHPz;>g%3H=vQL3}`Pu>o7Npx5n`$ysf4E11 zq<=pmT2|emRV+!f#o*N97h4-HU4eJRSkc^?U4Uc6dD>DIk3LapcTP!uy!Pm~_%VWl z3d|)Fo1RabL_`hBvduWOT_2R5i?-+W#UrHVZD#WlsGI6_@x1X|@;25b41O?tRD8R> zf9<;v?DBYCf4i-DE=2WxC~?C@Tog1>eZ4T-g(OuBoCgXf)A$Lv_Aah54}UF)0J+O0 zW%dlXME-UJ|AAU&r%gIg3YP-M(&^U3OMi0WMYkf^husJ0bO0py(yQK-1g*5)7!V%5p5z+$J68jO4Y0@;5Sg>6BR#~BB^ z)D8EyQisq1KjppQrk4#30r7ifIJPdd4a7T|6vpK6vA5%wG|kg0chw`0#_%go*bR7$ zfLSCqRF}6<8So5^5*eo)Zm^jVmov+sr)n3-g%%i2n=l|Gby61jD>_4-G@7qGcf;xULT#?Gh=gxcJl1jf0nPVr0^Fd{c%2TotPk2*j1oZP zcXJ1U7ZU~;4`vq%(*szmEJn;dHE6Iyw|3=RWKL)~^7>r!@dxvC zJ0MyH$PV)K|3}_$6ZD9VfG<-2QC~gA?>Q@7%gtjhqITg!B=XlD9y&$Gs@}Ry#L65? z{f1J5jc=U#dLof#D;jRkMfhWUi>7d-G_tFUakSV4bK%OaVVz?bIqYy+7~>aPwOahg z{L$Hvj<3Ng!Uj;OA&eh16l04sAMo2~dou;lq{MQ=g>1Av^{c)1TYAEy^3FhHBtK}` zGU!?WpxOzWNUr|8LZibsb-PMEe>SU4CkOFsXr?nPM951H|BF+D(s|D=Y-(e|4V~7z zb1d$%;POu3P|GGg)M-d$AkEu%nZ3{XlgyGoBVpW`*&4d;egC-kJPFP-Y4SZA{2hSx zG5T)O57Ys@v{Lc~)=2$_W^Nx10Ye5EglO7FKi?0tuo2<^ilDkUKHHJ^0#yC$2Hhu1 zyq2hJ|ItKn|Ep_Hi@U4`~w4x^wz{0)9Es2;nZ~Ctcee9R_J9>wa7j01^Blu8u-x-XN%{+CaNa&g+D=if8ff|R zW&JE0>Mp}?87~q)3?(Q2cg4jsiu7a5rg-h!pAEs~Ra%Z2!3NPX58gKQ7BDn)m1Wtt zhk2q;8g~uY4&bfR0=z`n1SeR?-E~i=&n5UDST;58AN9WX>WLc!p@A3Upg~Jnf>zNj znrQ~0Z-K4!_Dj>Ct2bg{t*CBgc`!A zic`3T#}RB+I6^OVhXOfQJ&&Z@Ax7c$chCzoJL;}4=*4Cia#>4RKV+0|x|+#PM9Lf-0&!!@?%B#;C<#M0B*N{OGr6>I}z>H*qBHile!S#BM zCKZRXOGV`ibJK8=ZscVHVHRG8VQ^r5xeHLlxdW;%(wALn zLIyzd(+trjPdhovTY;<^7b*jol0?HF7L$!hhk$02Y_5w{4I`PdCoS3pmqI{x(_j5~ zo$@=WzC3xpt+%X5mFj3YL6a5@#qG02CY1*Cp5n`|#WMqd&o)i_xz!I(?VaHq$Q(_s zOaI~+Tj@dPuf$|p-4Y)Pr4(Hz!L?EL8B}&1%Z?RgfDgXY=QmswoJHDJ*@P{JlBP9h zMP_V>%498*#-k%g+dYy%h+=^?7M8;i&k_8Uz#AjY+M4cJ1W;=!e&;7`E0V~k4k00E z2cPF5Y_)6Y8wIADkO=&vLbpxgsVpMxh{U0Ds$Ng`{;w3$&*#@;|MT|5^`~CMF`mrM z%f{jR=sB_O4i|^aAP9yIKYNCszJ0fmn3T&hkmiJ%>c2c~8v8TeE8kO6xBM|QcOX8{ zX=|9|9isM>=E8ZNuZwqw25KWn+{hFY@vsy7Y1!+fYt`|cs#I%8Yk$LyI%H@!@`OHt zWUVOAPBrJENJ~YOxs8?Kb0d-cW7H1C2?dS`tk~05c7mH-!sI%yo^gA@dCoKQ2F&>{Yq1`DD0Lah1aai*hSNm-1j zk?(M4>Ihi=3Xks;82|cB>7W3EVE1)P*faiak-eG8q1$d<|Jr;$2=}K8LE>PQp<&AU zQH6G@zY!7Db-13FSp3bL`o+Z8&<@-YvrPV#pkK7T-9~wFJiCyRkYk9N^?H(;-w?a5dFw<`Ymrn z1^v{0t6^k`IM>Vsz#9dcf9_o)?4G80)+sHbmottes7lG^kW8f}-GfU$B&EdKCy+T? z6YL@Y?$e8|0A&;rLh8QpQMy79a$ov>L=+Yg{0NWEfzz;&0xd%C#d!nWj~)aKALk99 z2s=-!k(sO8w;C3m{Tm|_jccE{Z%5qKD3PDJwHdfk|3Pj{&}qZiR|J*dK;R#qFnSAg zaJr#l1T^X1PWvMUnMCKL)}v8U5#DWGr&z|-HoC2o8HEy&G09@wP7HZpHm{7!e@lg+ z6I%I6bkH5kUwAT;oE?c>gjP4_q{_xzlwcqPZ>V(WH3u{P_u=*=-z4jv)NX!Nv|_rf zz1+REW-n2K;A)HQu=z&qJqI$Tp($I8!_7bJyR|V;RZ3*+?7%psD1;;A*!c`?-W(Aj zl3NAb4Ra&O2%1K6e7Ws_Z#f=JvF3#wnojv5H#93kJ<0Zj@_-q{0gJRGrMNxVI6QWL{^kb{W zh(HdzLH11iFs4RCTL04_zn61~K{)RA2c9+`rk|D^>^b31gqbdoA+8wJI-~T#BdnfI zT%Qrl``sm$O&>b_MIXUDf#6jB#NC-wihO`w{#v1Wh2byEcS&)(&C>pkR3f*QTDHa~)nQinxWr zH~W{ArywwPZXTWy@|OvgAe@fMrsbCX9Qy!raHn;ORP z3i@<)rJzg8rm%tjKzdn9%xD{QFwCFy%gq9SF7JrKCiWAQ{QO}Z-s=u%ouJ8y=aUq zq+w`3w&4vIRZgZxlmopR;4;#AIXlv;!RRiDKT%mtB2s(SC(4Kypl zt|s#$3Ev%Cr@~`re%c_CNx8211bOy-+1?51f7>!4RA3Q`L(-R}lW}v*E0ar1XF%dF z_CIzoejD+sG3y$-{gEDKH59d?&{_xq`<`QmK@&0js9l`e{gGl^U_#aAYa~^xKH5uM z-L|pkqu4RYkjigB{n`rDB_2}6gb0q%$vs+b>U5RT2L5%;iPaD+%efXkk_@~rFushX zXdm{jEZv~(pOPI!LJ_2e|6g)jL72}HztH`%lD?vV*(v#_3e}i>wxT0^?QVxfQn5}s zTt^atxqLiNd38)V#+Wd3afpB{^N{fqk*ZsCi*)b<%L&MlVvUPUT*DjqYu%ujAf5e! zND3=^S}e2xpNg{b(>bz(d_Lg}_g0S`XTiANoE-0lh?y~akGpV4v@C#uHBK!aql3UJ zFgeY4_?O7tSqQ>(o|((({8`e8gopgJWz3~P(BiBc=Lv?Vbv%~XXdMCA{YwOo`PlCe z8P4?0Nr%Y6S^(1C{MQJovY!F3As#YNN@fnH0rh>5A)|~nzx3}HiK6((p!K#={Kcs3 zFaGGTvVEWBf9L#W#P`128A^>6#b?Ujd(HUton+h$Pp||@e578aD3HB9%NnL4;QIUa ze?#cz!=3$7NB46;5T$dX2fbKPJsn7-ZA^+Ho8+6$MFu)mUlO3J4RMzbot9=5iG{AX z^U-XYohAU(hBUp4L6u6{s_trltXbBl{qE%W`rJ2bNu0Z6<>p5MTlv&&o0=JKd+%^% zIl(*`j=MavbW2xdyW)$n#Q{@8&j6#)z%6KU#O|Sh;_BE@3K3*B+GM!Lp8TUZ`mx># z6ir#b?R-g*TBF|YZ2QIU*}Az;!$LB zo~vM9+0b;Krty^iG>9$!l4-@Brq|ye7ncezCxd(B;#1>@c+Gd5qfSBv=Y8ko>xVBr zYy8|;CmByj_(=@YQm|5^$+cPh4I8?VC_WFj7XX=eMUj@JLxLBOudt{XT&c4ai~E}X zn^xP9)dP%lP#BGdkMNnQf_)JSLLumeGRlKAZ97HH|GOip7f(t96OTiDumkTecDpK@ z@uj17{;5dD_=>AM3mKadu_|pQ--pP+P$6V>woCoTqlduhea&)5I}Zs8?r3D=*_KUU zjoqEB3{W?89Z*XngdqavN=MMbSvN}>rPbFkt3JFt7Rk?dG~kXWJeNbtwLIrj*I}L6 zU1yY+OgwdT*d8?>TIQ`bX!&jFW~*q={m6Jx!;(sOfV{XG@WS^6Nkz{prg1h3|4#YX z!1a|ojJk}-u4L;>T!^l6?2gwtuVnv~Z}mxX?p8t!$#wtS@SN<9L-nc|kEg>`4~)^^ zd_m)w_aS`R_LTC#Ab|dUbJ{qPqaj(HUU$7M>=apL-U@v@H>Si+U>Gk`kFR)LY2&lC zWj__MVy4aqgy*Fn&~W~w_$&P;DFA>t{KW)>;Qw;SbNyBk{(T+s@@uik@gMXv}uCeQsIF-xrYxySn z67-nt|5h>5K==>>p86+E2UYU(F)AgiQ{;5dukC7b1*c1=x%mMv1QHs?*>+r6KwUg! z5HJMUoLJtD$x0)iC<`Q#$OyoP8?}`PBhhGzXhB4%cc)g@_}Ylv_XXjuf^z5!U*_@h z5B7X^@xh0hP{+RvMv-Pa^MiZhe{Dcaw4kqW<&xSaAA90};mc#(`-9?INBhHn&ry5x zf2%1PV*OER#xEw(NP|W3+1L{S_(rDQ#51EmaA`9)4B)elB#0awJR_(kjV;FFHM$Dr znJupAL6x_DnWcAjf~M-sSH;(bYZ{dYD?}w>%Fj8&+$nQEVOq&(8K+e8lrnGr^i6TA zq^dJ-LhJgtIM~=a2@PbyTZ|G$w}#tGRb!l~eAnFc81br3VA$GzaUYj$`wvBJ@wz-% zboYsJ?(^uZdD?ZJ4Eh~74o44)AT1lXpwAntlsaYU-}$sVB4AWmvZp|VPs|d+xcEa4 zZdhiZS4!67f=Y3xNlkPHF$mZ_799h}5Wr=Rs0?eK8Vzvk(J_-43*@mbn^sB3-6d&u zl!AjVZ(ovTSisxWgW2;e)}z?RG#RK5<#8l6hSMIW{xE(E2=%#WlEem2I15#_85?t? zL4g>9#F;v1cW<9>%an>MapcA>aG{7u3l?}X==z>vw7XQ9clth8&4h=LFlY&z?HcTan*ipY5% zm@et@EN-Rq1bwq0Th97X0W*(06 zWZ|M!5!$0G>eCi(-@)B&*h&GR-|d!%>wUm0!;tyvUui}6Gg0Oze${v#FJPa$Q&*db zqx#Ptp;yA2QdcM1{Zqbu67>ZCA*HjQ6fIe>n1y#va08k?fm#Do6iUm-AivEPw@8q! zpYFs*RDdDF|GxRyJUl>)L&jP1eACy93uox+IjYPq+YVRsKBJ>p24!fa+Yk0b6(_;B zUWs}H)mN%LRB~pX!TA#4OZ?M!5&oPvGyk)cw3O%D1oUrwYlGlKF-)BsLW&w@5LamK zhblT@fv>XQIf@NQhtDO)102g+!iTe2I;x9`1_dL-6^^_x;x!g=z@cn3)vapoPcQIK z$J9(FD7s35!+L?8OCOKJLMMI7oX3vHL-Q}O4sHx#HusXwEC7d&@<#n0a0F8PHZl~R z_K|#dU;_PHU#5(}7!_pO!JjTVW4Vr&U1S@}l(_fT0gOg#oddt4WUGqHR8-UX z1WtuS8qg4HTC&M@`DcoDYoYeL;mx=so+f-O#ShEz`c}jIVT%&Dq+Mp9E|?0(1-hvm zbZBo}WT{XFYhYL9!K_RY)np>|Gscq&uKLnY!Gu*8f}pR)RcOhCmjI|Hl9|uUX04;> zPP4|`=is&dcfUW4^Oj2IpA1cdFBb-1B!zReC~pRz%Q-aW^hf6nBm@*5m;{qPquTF% z{OW6pQ?Kht1CU8p3dZU}#>kC-+%n0~M3bLW++$fdR5g$jcSj`SOSH+q?(?i~gsI9__Wt?f*72pIGD;G9Rh|ERb9$2&R}vS2-KR7B=&?4^@TWnxY#Foj~f zz{}6g>&&7E5E=R^xS=-O$IYDC@x zzHr+ulXWqdgnMB}qr>1^il(VleNLl&bFLVct0(hATj4*CuQl!Bdai=5ZGR4$cJCI( z_JI1sUoAQYDmL-Q_Wcu;Y5Y380$XA`-!Phn#mWW#V?-iSe{1{gUx&Y_5mF$zvCB-r z@+zQ*S9Xg9ju?0OLoG&?B^ADYyZ#7|i=|e#TNs%yFo627bfMZP?|+hvcHnKJK`22A zbjQc!IF<-T(~p}7iD;_yu+U-?fg_Pz-?*&K7Rf)oqc6>YVHs@A5WT=pcVAH^%T=$K zTO=bsHMzH5X>E|UaxEo0XGbqZU<%;|@9R%a4cvijREGW)=;>P+HJa8}Z*&bRSrLgt z=$Walkt{Ur)L0#1`=!G|geX;Gg+}8UZDLx@TME`J*b4wl9V)Ja2_a;&pb&+}0J;Jr zPXZo5@ff|?)@Ty3vnkpLW`Vp~edYFEwy4IW(caj3X&n!mMN)4VjqQ4o=&}XtNCh$R zdGtPS`6eoO5<`6!8(9=7A-}3t=^v@bHd8{tLMa-n9s{67)jifl7_(6( znZ(=dXkvZ1k47$}mNdqVbcr-%&45&*)Iw@!69ARDZ&l}?u&Rzp1%7)i13mUg)14Xp z3b+k-gg7nph~K@PppE1CKiO%^MeVxM2P4jV?o_8q6G6)1o%ibADFl|ce+ zFb;#bMu@VxFFXBzHMVjeY=1PF3e)J`0cL+W8=1L7K|?|P6cju|1m0mKaer~+k`qd;~tqpzzCV{yUl91*vGFTRfX{}Y<%96;FK#zN@WrHm-LsJdVIql=weApL#C zB<`vb>7@Pcn7h56UwPjbA{$QMeA1k9BKgQ=v%`?$Jat)_|N5VdML=|zE`DT{BZA+< z-7ksOwF(%tBcOVRmM)zW33@culo(`}al@JY(FdVd_p_*OKs^i8&1NQWx8noS$Nhov zh#k|<^6V{_0RZbsm=6N++W_G9@bKli;$>(USBMNj))Za@2P8c|mI_nPc}0v-<&CAWHy9VlfsTl78If396H>NyKxaf7BFLP9a(8(B)get zaS(7;1uD>iQ%XS+qfEh%{Au&#Nv=wJt*dr3KVu}oFo@zkx_n*WXVxS z%L^!P21HhE0*tq?04)M9vtd7;;+|%5zM{OvbDsWp{i_0m!LK{%YcPM{*;bLyxb|D1 ziALA(%j!Fx&sG>@3EHhQm!YfL7T!+N_fn_@N@&t=V9tMOm~0yi`65lK;bN5Ppgbdi zry56d>h6Y682-JAWALRz)Dh1gC2)Jx1stO3tMU^Ss{>Y9v|y@HiT z;nWa-wj+7@UoP+tt78sb+fc;6tN>=x;?t&?aiv?IHe~o>(eE-0*xXj^yP;`xh9lCM zq^f4WhG$B#9x_~=GHsObTp$ZN1ST4XjNru75GFWXqXAZPl(@vI)0xOx^`%!DojZs{ z7#%+|k)-XCB5!y@Iy}m7te{B>_Eowr-JL=JyXaC%#(9_RX7h*_sXd_u5x&sueYnlS zgbB5P{z5xNHIj8CA`s~QMwU@r2?rs48%Ds_6O!~mU+N2r2U>-KQI1DyQ+=-$pWK=V%ti3fLg>cT|v)%wp=lu<#&I-d63GoZq_ z%XjE>L8h;xQG^_W=NrTJf#p7@ICih9DeM3APY_*uZ;sEhnV%|p4;sG1{po#lu|?9p zmCV0hH>k5oo)3NXTH!|LSU%AFt?4Ew^pyeiIqJVz&pFTPa$~2VVxFUL#8Z=Z?Xae0 z803yEPW@wttX{DI6Gp_1vsF+^m~&>wd-tSA=rjQ}=0gMxqU4_{Ravi8m28ZbPe4tS zC5m3sypHR{q596{ZB7KNj1*rj_>#A@?ZkLu<@}(az>VG1x3%&we$#m9u7w3=xM2JX z0G>7##!_uy*iUV_?%Pf_a07S4Xr(DynlGuZ{uRNBsQ6c_9Uc#Rp9$HAXG~pbY_nX7 ztzLklO}leduzNgfWmV51S=ugdhr7bu&K(rZcbw-XA^}F+BK|bW0$;h>;tPW3pej1Q zMP`GMy1U+$2yse|3#SG0nKF^Bo49RtHKoE}lY}|KG-jWOHw1ok(0q#Q*$;|gF{2o7 zBy#;O`uuN^4upgopPYg_n|^yajrua@Eqt3KY<-V+wdH@e^?uy-wy^nT|9Z#z>i;nG z{`#Lbrelym_%i82kVwdDno;8CDOUe=MF}Ux=)Bm8)gF6J10I#`L6*Q814RlK>ZOB+ za~(1W`^SMh>4WMNAc@BMkv-YVCZkg5WpeKvjXCQ{M7_?HLvFeLr}G((*q`XEs*dpB zJ)+F+4Fp}F)%fGw%qAT zUHl@ZH^Uw81SS~^cT7prWbg#3>*{;7%gD_k&BXr}eCfOm`~GaHypgA|D7o<*uYu*o z@WcR9EIO%{HM25(c7FYE>BrhtMOb{VT}mIh^O2+nuweUC{Wq%#E#4C*%3)_!&{_G# zuT?-t5T%J72NC>uv{y{(?jJO*ju+$q>c>OIQ6Ll@4+V>ar&7_ZX%B|zZ zmf6_2hhE5*1{81@U+HI!ZLw|Y(cL+eUp_r-LIxj_JG{y&RD!JcXO=@M=8wwOr6nT0 z{o+7B$f33|#Kba@Sv#QDC=aLST^e zPgQ}V*mL|Ns~T- z^qG?BDGjKq@$=mr{x8CT8?;)nX*?5&+}tSu?i(0$e|IB&6r{p#hBG=OLOtI?see>Z zZj$Tc_DLJgE)E>+l~qm&y6Aq36$9BJ(HZ7{&`-qEmp!g|m?FJ&(X!k!4S%AV^Jvn% zrh^_~iLczY+dZ*MLJY;!`fZeHC&RjQY-ktCm~pn$e;GO)xj4d?`mS~N*4Q7osOTFL zgXc$09_ap~!D3+=sT@|iDl$8CJ8=C~s&S1uhn4B=5XelK#O+iCM9hlUUO@ND*CrQ? zEDuE?WSj?BQLj3UXOtVvO2iD$Xy*Za`@@ zHihjb-=(&Gi;`RFs8-SiV4}k?+5vPM`{2Wi_7Dw=^=094W6@<*clTKom?k*;F#3YB zPHNSI1 z?fsXP;`fsKGHmX%lIa$QwRw-)buZ(!izfW`M%rrR?n5Aw%qZD#=HY;X=Y-ujA*!is z-2Yt?;T!QULYC%Vui8kU+Zys6l@dMa#Ez|xPKkC6CUT)S1gwBP0XmSZ-OkTfY=dmN z(Y7af7B@&gxERwoxk~UZpY@Na2!U3G&-JVbZ^AEa>yGa1dwCKX2VK(UZ<^7^(QM7$ zyPa+@)3W8es*K5`BNyAd^)0GXRNPbtt_f@0Lgjs5y!YpO>2}>u_`m2{T`>)3iyWNU z8!l+U+uqdU`9VG~K@S3Bn(xnd{{01^TI#U>v?MW&Jfmr%Zm_VZM=6~g6gM789s|h0 zwTRiwcx-)*wYBX52S+NI9{_3{w}8~BQJ*c@`lsz#Zw1trd1DLl?qt^VL(wJ$Nzrm7 zKKO|h^JaPD?!?EAA@6znz_Qg{78477GJzfYol)5l#FXsFn0aD2Z<{CRiGpirCVx9- z7Q%2JE34;W9Knc$6_V9ew4GrU*uTT4!Hg=vbPKiASI~5C+CO+BIT0G^z^)bI+^QJd z{G&C6uT)~wQx~GUBNjt)C#lt6XSvEa!mCg^6&FV!=8rHwe8-Q*fq!;J%^>AxdpS?> z1f&H<_zuo`0{fM@XBPr8T<%DdQMYjowia1Ao=5(@i|u-thpb?e1CQw`Clv-oqzU)g z63i@d?R0h#fa3g-BEtfFUi<2q-;)@rN8gG60Oj3;d+@{Xj`L`2R9?Tm#|V1KEqCFhssTGGHp_L@S0z zW(F(QW0(gGaC*hJv8yu>>e*49YSXyS6%71%V3G_`p#OgNz~j7|N0(z*PAM0gXs%h4 zrcSPIa9DtPPt(bM>7CrXa>$r?*zf5WsW2dgn4)RBJqjEdds{+`Qr*^Tw2aSi`aU9; zUe|F2gqn#q1q)~+l(L036%H@0>IDpiL?(c1Lfk5V8d%gd2Qj6mbjZw#aThY>^A71q z*cR-}RCf@*kdJW8tujbR4^ z`6#RFc;5{ZzL0;1IG-IHdkA#?7j&TRq`|SXWK7~8-rcu>Ax5&PHa14w4tZWa46GyI zE^$7P$wNltfdUG%d5}{An}Yi^3MSb9IPuTCQ0-$}1Ek!U=i_&<=e+C%AGe-y@aDLo zq1ZV1OoX;3l}tZWKhGg8k~QKeXcjO#T2L06{Mt;-`R1M((QQBxHyyRUky9Q_Jv-x} z%)dLwdlO}?tpcwPceJENDT(&k^FN!dBH*mr(TU8b1jJ&vsr=Rs>rOo>kP#$eyuORD z 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

cg+A}Ev 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 jLt*gJY3EqM&EwN>v(LfHGgb%#n-* literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-search.png b/docs/audit/screenshots/windows-search.png new file mode 100644 index 0000000000000000000000000000000000000000..6ba46405252bc51963e5b599b31c807b23374c3e GIT binary patch literal 220197 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

    +fLW&>JuHtx5 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

    LC^59zh<)a0#}8QX~kWUH&sNQQiIwXZc6 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%0A?_v9=6Wf7QCYq|@W4)(g09@Ed(>?g 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≈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%0Dbvf5zIn3VG| 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

    4oV>+eht!sy;C)c%B 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 HC@KE|nQY 現況描述,未經確認,不代表目標。 + +審計日期:2026-09-26,分支 `docs/audit`。方法:只讀原始碼與 grep,未執行 App、未跑測試、未打真實 API。行號為審計當下實際看到的位置。 +標記:**不一致** = 文檔/註釋與程式碼對不上;**推測** = 由程式碼路徑推論、未實跑驗證;**查不到** = 找不到對應實作。 + +--- + +## 1. 能力矩陣 + +### 1.1 播放音源(註冊在 `SourceManager`) + +`SourceManager` 預設只註冊三個 adapter:`[BilibiliSource(), YouTubeSource(), NeteaseSource()]`(`lib/data/sources/source_provider.dart:14`)。各 adapter 宣告實作的能力介面: + +- Bilibili:`DisposableSource, TrackInfoSource, AudioStreamSource, SearchSource, PlaylistParsingSource, TrackDetailSource, PagedVideoSource, RankingSource, LiveSource`(`lib/data/sources/bilibili_source.dart:41-52`) +- YouTube:`DisposableSource, TrackInfoSource, AudioStreamSource, SearchSource, PlaylistParsingSource, TrackDetailSource, DynamicPlaylistSource, RankingSource`(`lib/data/sources/youtube_source.dart:27-37`) +- 網易雲:`DisposableSource, TrackInfoSource, AudioStreamSource, SearchSource, PlaylistParsingSource, TrackDetailSource, RankingSource`(`lib/data/sources/netease_source.dart:25-34`) + +| 能力 | Bilibili | YouTube | 網易雲 | +|---|---|---|---| +| 搜尋 | ✅ `search()` 走 `/x/web-interface/search/type`(`bilibili_source.dart:476-532`) | ✅ `search()` 走 youtube_explode(`youtube_source.dart:865-970`) | 部分:`search()` 走 `/api/cloudsearch/pc`,**`order` 參數收了但沒用**(`netease_source.dart:183-253`) | +| 串流解析 | ✅ DASH(`fnval=16`)→ durl(muxed);HLS 直接回 null(`bilibili_source.dart:297-324, 327-426`) | ✅ 每個 streamType 先匿名(androidVr / ios+safari+android / safari+ios),失敗才用同一 streamType 帶 auth 打 InnerTube WEB `/player`(`youtube_source.dart:332-378, 407-426, 445-587`) | 部分:eapi `/song/enhance/player/url/v1`(`netease_source.dart:93-171`);`getAlternativeAudioStream` 永遠回 null,沒有替代 URL(`netease_source.dart:173-178`);試聽片段(`freeTrialInfo`)只寫進 log,不告知使用者(`netease_source.dart:145-150`) | +| 歌單匯入(貼網址) | ✅ 收藏夾 URL,先過主機白名單(`bilibili_source.dart:193-210, 535-645`) | ✅ 一般歌單(InnerTube→youtube_explode 退路)與 Mix(`youtube_source.dart:1377-1440`) | ✅ 歌單 URL 與 `163cn.tv` 短網址(`netease_source.dart:257-325, 714-723, 755-775`) | +| 登入 | ✅ WebView + QR 兩個分頁(`lib/ui/pages/settings/bilibili_login_page.dart:15, 54-63`) | ✅ 僅 WebView,UA 偽裝繞過 Google 的 WebView 封鎖(`lib/ui/pages/settings/youtube_login_page.dart:13-16, 60-70`) | ✅ Android:WebView + QR;其他平台只有 QR(`lib/ui/pages/settings/netease_login_page.dart:16, 32, 52-77`) | +| 收藏同步/遠端歌單讀取 | ✅ `getFavFolders`(`lib/services/account/bilibili_favorites_service.dart:55`);帳號頁列出後以 URL 走一般匯入(`lib/ui/pages/settings/widgets/account_playlists_sheet.dart:130-143`) | ✅ `getPlaylists`(`lib/services/account/youtube_playlist_service.dart:63`;`account_playlists_sheet.dart:145-158`) | ✅ `getPlaylists`(`lib/services/account/netease_playlist_service.dart:68`;`account_playlists_sheet.dart:160-172`) | +| 遠端歌單編輯(寫) | ✅ 建立/加入/批次移除(`bilibili_favorites_service.dart:117, 154, 187`;adapter `lib/services/library/remote_playlist_edit_controller.dart:225`) | ✅ 建立/加入/移除(`youtube_playlist_service.dart:88, 105, 218`;adapter `remote_playlist_edit_controller.dart:310`) | ✅ 建立/加入/移除(`netease_playlist_service.dart:101, 146, 159`;adapter `remote_playlist_edit_controller.dart:367`) | +| 排行/探索 | ✅ `ranking/v2`,預設 `rid=1003` 音樂區(`bilibili_source.dart:865-917`) | 部分:不是排行榜,是 YouTube Music 頻道「New This Week」歌單再依播放數排序(`youtube_source.dart:48-51, 1617-1652`) | ✅ 官方熱歌榜歌單 `3778678`(`netease_source.dart:42, 332-364`) | +| 電台直播 | ✅ 兩條路:搜尋頁的 `LiveSource`(`bilibili_source.dart:1025-1057`;`lib/providers/search/search_provider.dart:217`);電台頁的 `RadioSource` 直接用 `BilibiliLiveClient`,**不經 `SourceManager`**(`lib/services/radio/radio_source.dart:60-71`) | ❌ 明確拒絕(`radio_source.dart:140-143`) | ❌ 未實作 `LiveSource`(`netease_source.dart:25-34`) | +| 推薦/Mix | ❌ | ✅ Mix(`DynamicPlaylistSource`,`youtube_source.dart:977-1073`;呼叫端寫死 `SourceIds.youtube`:`lib/providers/audio/audio_controller_provider.dart:74`、`lib/providers/library/playlist_provider.dart:426`) | ❌ 查不到每日推薦/私人 FM 之類的實作 | +| 歌詞 | ❌(只當被匹配的一方) | ❌(同左) | ✅ 另一個同名類別 `lib/services/lyrics/netease_source.dart:130`;網易雲曲目直接用 `sourceId` 取歌詞(`lib/services/lyrics/lyrics_auto_match_service.dart:104-127`) | +| 下載 | ✅ 共用下載管線(`lib/services/download/download_service.dart:977, 1060-1070`) | 部分:HLS 串流拒絕下載(`download_service.dart:1060-1070, 1716-1735`) | ✅ 共用下載管線;試聽片段同樣不會被擋(核查確認為程式碼事實:`isTrial` 只用在 log,`AudioStreamResult` 沒有對應欄位,`lib/` 其他地方 grep `trial` 無結果,下載端無從判斷;原標「**推測**」。API 實際何時回試聽 URL 仍待實機) | +| 影片分P(cid) | ✅ `PagedVideoSource`(`bilibili_source.dart:649-680`);匯入時展開多 P(`lib/services/import/import_service.dart:205, 454, 588`) | ❌ | ❌ | +| 音質選擇 | 部分:只依 `qualityLevel` 在 DASH 音軌中挑(`bilibili_source.dart:356-363`),格式優先序不適用(固定 aac,`bilibili_source.dart:373-381`);查不到 Hi-Res/杜比(只讀 `dash['audio']`,`bilibili_source.dart:349-353`) | ✅ `qualityLevel` + `formatPriority`(opus/aac)(`youtube_source.dart:589-615`) | ✅ `qualityLevel` 映射為 `lossless`/`exhigh`/`standard`(`netease_source.dart:785-794`) | +| 詳情/評論(額外) | ✅ `TrackDetailSource`(`bilibili_source.dart:744-811`) | ✅(`youtube_source.dart:214-281`) | ✅(`netease_source.dart:376-464`) | + +共通:音質逐級降級(high→medium→low)只在 `unavailable` / `vipRequired` 時觸發(`lib/data/sources/audio_stream_quality_fallback.dart:42-67`,條件見 `lib/data/sources/source_exception.dart:23-25`)。串流優先序(audioOnly/muxed/hls)是每源設定(`lib/data/models/settings.dart:59-63`)。 + +### 1.2 非播放來源 + +| 來源 | 能力 | 證據 | +|---|---|---| +| Spotify | 僅歌單匯入(抓 `open.spotify.com/embed/playlist/` 頁面解析),再用播放音源搜尋匹配;無歌詞直取 | `lib/data/sources/playlist_import/spotify_playlist_source.dart:57-59`;`lyrics_auto_match_service.dart:658-659` | +| QQ 音樂(匯入) | 僅歌單匯入(`u6.y.qq.com/cgi-bin/musics.fcg` + 自簽 `sign`) | `lib/data/sources/playlist_import/qq_music_playlist_source.dart:151-162` | +| QQ 音樂(歌詞) | 歌詞搜尋與取得(`u.y.qq.com/cgi-bin/musicu.fcg`) | `lib/services/lyrics/qqmusic_source.dart:98, 146, 188, 253` | +| lrclib | 歌詞搜尋/依 id 取得/精確查 | `lib/services/lyrics/lrclib_source.dart:22-125`;UA 仍是佔位字串 `FMP/1.0.0 (https://github.com/user/fmp)`(`lrclib_source.dart:24`) | +| 網易雲(歌詞) | 歌詞搜尋與取得,自帶一個 Dio,不帶登入 | `lib/services/lyrics/netease_source.dart:130-150, 301` | +| Bilibili 直播 | 電台(直播轉音訊)、粉絲勳章牆匯入電台 | `lib/data/sources/bilibili_live_client.dart:104`;`lib/services/radio/radio_controller.dart:670-690` | +| OpenAI 相容端點 | 歌詞 AI 標題解析與候選挑選(使用者自填 endpoint/key) | `lib/services/lyrics/ai_title_parser.dart`、`lib/services/lyrics/ai_lyrics_selector.dart`;呼叫處 `lyrics_auto_match_service.dart:153-190, 388-400` | + +`PlaylistSource` enum 有 `netease` 成員(`lib/data/sources/playlist_import/playlist_import_source.dart:95-98`),但 `PlaylistImportService` 只註冊 QQ 與 Spotify(`lib/services/import/playlist_import_service.dart:137`),全 repo 查不到任何地方產生 `PlaylistSource.netease` 的 `ImportedTrack`。網易雲網址走內部 `SourceManager` 匯入(`lib/ui/pages/library/widgets/import_playlist_dialog.dart:159-168`)。`PlaylistSource.netease` 目前只剩 switch 分支,實際上是死值。 + +--- + +## 2. 音源抽象現況 + +### 2.1 有什麼 + +- **沒有**全能基底類別。`base_source.dart` 開頭註明刻意不設 `BaseSource`(`lib/data/sources/base_source.dart:4-5`),檔案裡只剩 DTO(`AudioStreamConfig`、`AudioStreamRequest`、`AudioStreamResult`、`SearchResult`、`PlaylistParseResult`)。 +- 能力是 9 個窄介面,全部繼承 `SourceCapability { String get sourceType; }`(`lib/data/sources/source_capabilities.dart:7-126`)(核查更正:原寫「10 個窄介面,全部繼承」;繼承者為 TrackInfo/AudioStream/TrackDetail/PagedVideo/DynamicPlaylist/Ranking/Live/Search/PlaylistParsing 共 9 個,連同下面的 `DisposableSource` 才是 10 個)。另有不繼承它的 `DisposableSource`(`source_capabilities.dart:15-17`)。 +- `SourceManager` 以 `_capability(type)` 依 id 與型別查能力(`source_provider.dart:28-35`),另有依 URL 找 adapter 的 `*ForUrl`(`source_provider.dart:57-85`)。UI 列音源用 `registeredSourceTypesProvider` / `searchSourceTypesProvider` / `rankingSourceTypesProvider`(`source_provider.dart:110-130`)。 +- 音源 id 是字串常數 `SourceIds`(`lib/data/models/source_ids.dart:15-43`),與 ADR 0001 一致。 + +### 2.2 抽象之外的平行體系(不經 `SourceManager`) + +| 體系 | 型別 | 證據 | +|---|---|---| +| 帳號 | `abstract class AccountService` + 三個實作 | `lib/services/account/account_service.dart:15-47`;`bilibili_account_service.dart:66`、`youtube_account_service.dart:21`、`netease_account_service.dart:23` | +| 遠端歌單讀取 | 三個互不相干的 service,無共同介面,UI 以 `switch` 分派 | `account_playlists_sheet.dart:130-172` | +| 遠端歌單寫入 | `abstract class RemotePlaylistEditAdapter` + 三個 adapter | `remote_playlist_edit_controller.dart:19, 225, 310, 367` | +| 歌詞 | 三個具體類別(`LrclibSource`、lyrics `NeteaseSource`、`QQMusicSource`),**無共同介面**,靠字串 `'netease'/'qqmusic'/'lrclib'` 分派 | `lrclib_source.dart:22`、`lib/services/lyrics/netease_source.dart:130`、`qqmusic_source.dart:98`;分派 `lyrics_auto_match_service.dart:278-300, 444-461` | +| 外部歌單匯入 | `abstract class PlaylistImportSource` + Spotify/QQ | `playlist_import_source.dart:113-125` | +| 電台 | 具體類別 `RadioSource`,直接持有 `BilibiliLiveClient` | `radio_source.dart:60-71` | + +### 2.3 繞過能力介面的地方 + +- **Mix**:`dynamicPlaylistSource(SourceIds.youtube)` 寫死 YouTube(`audio_controller_provider.dart:74`、`playlist_provider.dart:426`)。 +- **直播搜尋**:`liveSource(SourceIds.bilibili)` 寫死(`search_provider.dart:217`)。 +- **電台**:完全不經 `LiveSource`,`RadioSource` 直接呼叫 `BilibiliLiveClient`(`radio_source.dart:60-71`),勳章牆直接讀 `bilibiliAccountServiceProvider`(`radio_controller.dart:672`)。 +- **歌單匯入匹配**:搜尋音源寫死 `[SourceIds.youtube, SourceIds.bilibili]`(`playlist_import_service.dart:320`),不看 `searchSourceTypesProvider`。 +- **帳號 Cookie 自動刷新**:只刷 Bilibili(`lib/providers/account/account_provider.dart:131-152`)。 +- **播放認證**:`SourceAuthContext.authForPlay` 經 `AccountServiceAuthLoader` 以 `platform` 為鍵查帳號服務(`lib/services/account/source_auth_context.dart:22-36, 133-137`),這條路是查表,沒有具體型別。 + +### 2.4 類別圖 + +```mermaid +classDiagram + class SourceCapability { + <> + +String sourceType + } + class DisposableSource { + <> + +dispose() + } + class TrackInfoSource { + <> + +parseId(url) + +canHandle(url) + } + class AudioStreamSource { + <> + +getAudioStream(request) + +getAlternativeAudioStream(request) + } + class SearchSource { + <> + +search(query, page, pageSize, order) + } + class PlaylistParsingSource { + <> + +isPlaylistUrl(url) + +parsePlaylist(url, authHeaders) + } + class TrackDetailSource { + <> + +getVideoDetail(id, authHeaders) + } + class PagedVideoSource { + <> + +getVideoPages(id, authHeaders) + } + class DynamicPlaylistSource { + <> + +isDynamicPlaylistUrl(url) + +getMixPlaylistInfo(url) + +fetchMixTracks(playlistId, currentVideoId) + } + class RankingSource { + <> + +defaultRankingRequest + +getRankingTracks(request) + } + class LiveSource { + <> + +searchLiveRooms(query) + +getLiveStreamUrl(roomId) + } + SourceCapability <|-- TrackInfoSource + SourceCapability <|-- AudioStreamSource + SourceCapability <|-- SearchSource + SourceCapability <|-- PlaylistParsingSource + SourceCapability <|-- TrackDetailSource + SourceCapability <|-- PagedVideoSource + SourceCapability <|-- DynamicPlaylistSource + SourceCapability <|-- RankingSource + SourceCapability <|-- LiveSource + + class BilibiliSource + class YouTubeSource + class NeteaseSource_data + BilibiliSource ..|> DisposableSource + BilibiliSource ..|> TrackInfoSource + BilibiliSource ..|> AudioStreamSource + BilibiliSource ..|> SearchSource + BilibiliSource ..|> PlaylistParsingSource + BilibiliSource ..|> TrackDetailSource + BilibiliSource ..|> PagedVideoSource + BilibiliSource ..|> RankingSource + BilibiliSource ..|> LiveSource + YouTubeSource ..|> DisposableSource + YouTubeSource ..|> TrackInfoSource + YouTubeSource ..|> AudioStreamSource + YouTubeSource ..|> SearchSource + YouTubeSource ..|> PlaylistParsingSource + YouTubeSource ..|> TrackDetailSource + YouTubeSource ..|> DynamicPlaylistSource + YouTubeSource ..|> RankingSource + NeteaseSource_data ..|> DisposableSource + NeteaseSource_data ..|> TrackInfoSource + NeteaseSource_data ..|> AudioStreamSource + NeteaseSource_data ..|> SearchSource + NeteaseSource_data ..|> PlaylistParsingSource + NeteaseSource_data ..|> TrackDetailSource + NeteaseSource_data ..|> RankingSource + + class SourceManager { + -List~SourceCapability~ _sources + +audioStreamSource(type) + +searchSource(type) + +playlistParsingSourceForUrl(url) + +liveSource(type) + +dispose() + } + SourceManager o-- SourceCapability + + class BilibiliLiveClient + BilibiliSource --> BilibiliLiveClient + class RadioSource + RadioSource --> BilibiliLiveClient : 繞過 SourceManager + + class AccountService { + <> + +platform + +getAuthHeaders() + +checkAccountStatus() + +markSessionExpired() + } + AccountService <|-- BilibiliAccountService + AccountService <|-- YouTubeAccountService + AccountService <|-- NeteaseAccountService + + class RemotePlaylistEditAdapter { + <> + } + RemotePlaylistEditAdapter <|.. BilibiliRemotePlaylistEditAdapter + RemotePlaylistEditAdapter <|.. YouTubeRemotePlaylistEditAdapter + RemotePlaylistEditAdapter <|.. NeteaseRemotePlaylistEditAdapter + + class PlaylistImportSource { + <> + +canHandle(url) + +fetchPlaylist(url) + } + PlaylistImportSource <|-- SpotifyPlaylistSource + PlaylistImportSource <|-- QQMusicPlaylistSource + + class LrclibSource + class NeteaseSource_lyrics + class QQMusicSource + note for NeteaseSource_lyrics "歌詞三源無共同介面,以字串 id 分派" +``` + +圖中 `NeteaseSource_data` 指 `lib/data/sources/netease_source.dart:25`,`NeteaseSource_lyrics` 指 `lib/services/lyrics/netease_source.dart:130`。兩者同名。AGENTS.md 說 `neteaseSourceProvider` 是歌詞層那一個,這點與 `lib/providers/lyrics/lyrics_provider.dart:35-37` 一致。 + +--- + +## 3. 「今天新增一個音源要改哪些檔案」 + +樣本:網易雲。`lib/` 內提到 `netease`(不分大小寫)的 Dart 檔有 **49** 個(不含 `*.g.dart`),i18n JSON 有 **20** 個(en 8、zh-CN 6、zh-TW 6),`test/` 內有 **68** 個檔。下表依「要不要改」整理,`` 代表新音源。 + +### 3.1 最小可用(能搜尋、能播放) + +| # | 檔案 | 為什麼要改 | +|---|---|---| +| 1 | `lib/data/models/source_ids.dart:16-24` | 加常數並放進 `values`。`values` 會帶動設定預設、首頁排行白名單、音訊設定列表、搜尋 `allDirectSources`(`settings.dart:170`、`audio_settings_provider.dart:152, 168`、`search_provider.dart:35`、`database_migration.dart:307`) | +| 2 | `lib/data/sources/_source.dart`(新) | 實作需要的能力介面 | +| 3 | `lib/data/sources/_exception.dart`(新) | 繼承 `SourceApiException`,把平台錯誤碼映射成 `SourceErrorKind` | +| 4 | `lib/data/sources/source_provider.dart:14` | 註冊進預設清單 | +| 5 | `lib/data/sources/source_http_policy.dart:43-70` | 每源 CDN/API header、UA;未知 id 回空 map | +| 6 | `lib/data/sources/source_url_policy.dart:12-13` 一帶 | 主機白名單(`isPlaylistUrl` / `parseId` 會用) | +| 7 | `lib/core/utils/icon_helpers.dart:15-18` | 品牌圖示 switch | +| 8-10 | `lib/i18n/{en,zh-CN,zh-TW}/importPlatform.i18n.json` | `SourceIds.displayNameFor` 靠 flat map 查名字(`source_ids.dart:31-34`) | +| 11-13 | `lib/i18n/{en,zh-CN,zh-TW}/audioSettings.i18n.json` | 音訊設定頁以 `audioSettings.streamPriority.Title`、`authForPlay.Description` 查字串(`lib/ui/pages/settings/audio_settings_page.dart:57, 153-155`) | +| 14 | `lib/data/models/settings.dart:59-63, 76-79, 172` | 預設串流優先序、預設是否帶認證(有 fallback 可不改);`defaultHomeRankingSourcePriority` 是寫死的 `'bilibili,youtube,netease'` | +| 15 | `lib/services/platform/url_launcher_service.dart:19-45` | 「在 App/網頁開啟」連結表 | + +選配(不改不會壞,但呈現會退化): + +| # | 檔案 | 為什麼 | +|---|---|---| +| 16 | `lib/core/utils/thumbnail_url_utils.dart:130, 391-418` | 封面 CDN 尺寸最佳化 | +| 17 | `lib/core/utils/source_presentation.dart:8, 11` | 歌曲型還是影片型呈現(方形封面、收藏數) | +| 18 | `lib/data/models/video_detail.dart:198` | 目前每源一個 factory(`fromNetease`、`fromYouTube`) | +| 19 | `lib/ui/pages/settings/developer_options_page.dart:212-218` + 3 份 `settings.i18n.json` 的 `rankingCache` 字串 | 開發者頁把三源排行快取數寫死(`zh-TW/settings.i18n.json:182`) | + +### 3.2 有登入 + +| # | 檔案 | 為什麼 | +|---|---|---| +| 20-22 | `lib/services/account/_account_service.dart`、`_credentials.dart`、`_auth_interceptor.dart`(新) | 帳號、憑證、請求期失效偵測 | +| 23 | `lib/providers/account/account_provider.dart:78-92` 與每源 provider 宣告 | `accountProvidersBySource` 與 `accountServicesProvider` 都是手寫清單 | +| 24 | `lib/ui/pages/settings/_login_page.dart`(新) | 登入頁 | +| 25 | `lib/ui/router.dart:60, 93, 282-284` | 路由 | +| 26 | `lib/ui/pages/settings/account_management_page.dart:60-125` | 三張 `_PlatformCard` 手寫 | +| 27-29 | `lib/i18n/*/account.i18n.json` | 登入文案、VIP 文案 | + +### 3.3 有遠端歌單 + +| # | 檔案 | 為什麼 | +|---|---|---| +| 30 | `lib/services/account/_playlist_service.dart`(新) | 讀寫遠端歌單 | +| 31 | `lib/services/library/remote_playlist_edit_controller.dart:367` 一類 | 新 adapter 類別 | +| 32 | `lib/providers/library/remote_playlist_sync_provider.dart:43-58` | adapter map | +| 33 | `lib/ui/widgets/dialogs/add_to__playlist_dialog.dart`(新) | 每源一個對話框 | +| 34 | `lib/ui/widgets/dialogs/add_to_remote_playlist_dialog.dart:22-27` | 對話框 map | +| 35 | `lib/ui/pages/settings/widgets/account_playlists_sheet.dart:130-172` | `switch` 分派三個 service | +| 36 | `lib/ui/pages/library/playlist_detail_page.dart:623-634, 1623-1634` | 每源例外型別各一個 `on ... catch` | +| 37 | `lib/data/sources/remote_playlist_id_parser.dart:8-14` | 依源解析遠端歌單 id | +| 38-40 | `lib/i18n/*/remote.i18n.json` | `dialogTitle` | + +### 3.4 也是歌詞源 + +| # | 檔案 | 為什麼 | +|---|---|---| +| 41 | `lib/services/lyrics/_source.dart`(新) | 沒有共同介面可實作 | +| 42 | `lib/services/lyrics/lyrics_auto_match_service.dart:96, 104, 278-300, 444-461, 650-660` | 字串分派 5 處 | +| 43 | `lib/providers/lyrics/lyrics_provider.dart:36, 172-181, 391, 430-460` | 每源 provider、取內容、手動搜尋 | +| 44 | `lib/ui/pages/lyrics/lyrics_search_sheet.dart:83, 88, 101, 550` | 篩選、圖示、名稱 | +| 45 | `lib/ui/pages/settings/lyrics_source_settings_page.dart:60, 73` | 名稱、圖示 | +| 46 | 預設歌詞順序字串:`settings.dart:357, 601`、`lib/providers/audio/audio_settings_provider.dart:45`、`lib/services/backup/backup_data.dart:670, 749`、`lib/data/database/database_migration.dart:321` | 同一個 `'netease,qqmusic,lrclib'` 寫在 4 個檔 6 處 | +| 47-49 | `lib/i18n/*/lyrics.i18n.json`(及 `settings.i18n.json` 的 `sourceX`) | 名稱 | + +### 3.5 能力寫死給特定音源(新源要有該能力就得改) + +| 檔案 | 寫死的內容 | +|---|---| +| `lib/providers/audio/audio_controller_provider.dart:74`、`lib/providers/library/playlist_provider.dart:426` | Mix 只找 YouTube | +| `lib/providers/search/search_provider.dart:217`、`lib/ui/pages/search/search_page.dart:239, 253, 267` | 直播搜尋只找 Bilibili | +| `lib/services/radio/radio_source.dart:140-153`、`lib/services/radio/radio_controller.dart:672, 741, 755` | 電台只支援 Bilibili | +| `lib/services/import/playlist_import_service.dart:22-37, 277-283, 314-352, 1163-1198` | 外部歌單匹配只搜 YouTube/Bilibili。檔頭註解(`:15-21`)承認網易雲沒加進來,並說這是產品決定 | +| `lib/providers/download/download_scanner.dart:387` | 掃到認不得的下載資料夾一律當 Bilibili | +| `lib/services/library/remote_playlist_edit_controller.dart:206` | 查不到歌單來源時退回 YouTube | + +### 3.6 不必改 + +- `lib/services/backup/backup_data.dart:573-577`:只折疊 v3 以前的舊備份鍵。 +- `lib/data/database/database_migration.dart:179-242`:v1→v2 遷移專用。 +- 搜尋 chip、探索頁 tab、音訊設定清單、歷史篩選:都從 provider 推導(`search_page.dart:200`、`explore_page.dart:35`、`audio_settings_page.dart:17`、`play_history_page.dart:357`)。 + +### 3.7 統計 + +| 情境 | 檔案數 | +|---|---| +| 最小可用(3.1 必改 #1-15) | **15**:新增 2(adapter、例外)+ 修改 Dart 7 + i18n JSON 6 | +| 加上選配呈現(#16-19) | 19 + 3 份 `settings.i18n.json` = **22** | +| 與網易雲同等(登入 + 遠端歌單 + 歌詞) | 約 **54**:3.1 的 22 + 3.2 的 10 + 3.3 的 11 + 3.4 的 11(#46 另含 `audio_settings_provider.dart`、`backup_data.dart`、`database_migration.dart` 3 檔)。3.5 的寫死能力不含在內 | +| 對照:網易雲實際足跡 | lib Dart **49** 檔 + i18n JSON **20** 檔(en 8、zh-CN 6、zh-TW 6);測試 **68** 檔 | + +--- + +## 4. 音源特定分支散落位置 + +範圍:`lib/ui`、`lib/services`、`lib/providers`。「分支」採寬定義:依音源 id 做 `==`/`switch`/`case`、以音源 id 為鍵的手寫 map 或清單、把某能力寫死給某源、每源各一個 typed catch。音源自己檔案裡的自我識別(例如 `String get platform => SourceIds.bilibili`、建立 `Track` 時填 `sourceType`)不算。歌詞源字串(`'netease'/'qqmusic'/'lrclib'`)另列一類,因為它是另一套 id。 + +### 4.1 表 + +| # | 位置 | 分支內容 | 能力 | +|---|---|---|---| +| 1 | `lib/ui/pages/library/widgets/import_playlist_dialog.dart:51-55` | `switch (PlaylistSource)` → 圖示 | 匯入 | +| 2 | `import_playlist_dialog.dart:149-152` | Mix 縮寫網址 → `SourceIds.youtube` | Mix/匯入 | +| 3 | `lib/ui/pages/lyrics/lyrics_search_sheet.dart:83` | map `'netease'` → `LyricsSourceFilter` | 歌詞 | +| 4 | `lyrics_search_sheet.dart:88-90` | switch 歌詞源 → 圖示 | 歌詞 | +| 5 | `lyrics_search_sheet.dart:101-103` | switch 歌詞源 → 名稱 | 歌詞 | +| 6 | `lyrics_search_sheet.dart:550-551` | switch 結果來源 → 圖示 | 歌詞 | +| 7 | `lib/ui/pages/search/search_page.dart:239, 253, 267` | 直播篩選 chip 寫死 `sourceType: SourceIds.bilibili` | 直播 | +| 8 | `lib/ui/pages/settings/account_management_page.dart:60, 83, 105` | 三張平台卡片手寫 | 登入 | +| 9 | `lib/ui/pages/settings/developer_options_page.dart:212-218` | 逐源取排行快取數 | 排行(偵錯) | +| 10 | `lib/ui/pages/settings/lyrics_source_settings_page.dart:60-62` | switch 歌詞源 → 名稱 | 歌詞 | +| 11 | `lyrics_source_settings_page.dart:73-75` | switch 歌詞源 → 圖示 | 歌詞 | +| 12 | `lib/ui/pages/settings/widgets/account_playlists_sheet.dart:130-172` | `switch (platform)` 三個 `case` 分派 service | 遠端歌單讀取 | +| 13 | `lib/ui/widgets/dialogs/add_to_remote_playlist_dialog.dart:22-27` | map 源 → 對話框 | 遠端歌單寫入 | +| 14 | `lib/ui/pages/library/playlist_detail_page.dart:623-634` | 三個 per-source 例外 `on` | 遠端歌單寫入/錯誤 | +| 15 | `playlist_detail_page.dart:1623-1634` | 同上 | 遠端歌單寫入/錯誤 | +| 16 | `lib/ui/pages/player/player_page.dart:824, 842` | `isSongSource` / `showsFavoriteCount`(間接,表在 `source_presentation.dart:8, 11`) | 詳情呈現 | +| 17 | `lib/ui/widgets/panels/track_detail_panel.dart:830, 946, 975, 1061` | 同上,4 處 | 詳情呈現 | +| 18 | `lib/services/backup/backup_data.dart:573-577` | 舊備份鍵 map | 備份 | +| 19 | `lib/services/import/import_service.dart:374` | Mix 匯入寫 `importSourceType = youtube` | Mix | +| 20 | `lib/services/import/playlist_import_service.dart:22-37` | `SearchSourceConfig { all, bilibiliOnly, youtubeOnly }` | 匯入匹配 | +| 21 | `playlist_import_service.dart:99-110` | switch `PlaylistSource` → 歌詞源字串 | 匯入/歌詞 | +| 22 | `playlist_import_service.dart:277-283` | 依設定選節流延遲 | 匯入匹配 | +| 23 | `playlist_import_service.dart:314-352` | switch 設定;`:320` 寫死 `[youtube, bilibili]` | 匯入匹配 | +| 24 | `playlist_import_service.dart:1163-1198` | 手動搜尋 switch 設定 | 匯入匹配 | +| 25 | `lib/services/library/remote_playlist_edit_controller.dart:206` | 退回 `SourceIds.youtube` | 遠端歌單寫入 | +| 26 | `lib/services/lyrics/lyrics_auto_match_service.dart:96` | 預設 `['netease','qqmusic','lrclib']` | 歌詞 | +| 27 | `lyrics_auto_match_service.dart:104-105` | `track.sourceType == SourceIds.netease` 直取歌詞 | 歌詞 | +| 28 | `lyrics_auto_match_service.dart:278-300` | switch 歌詞源 | 歌詞 | +| 29 | `lyrics_auto_match_service.dart:444-461` | switch 歌詞源 | 歌詞 | +| 30 | `lyrics_auto_match_service.dart:650-660` | if/else 歌詞源直取 | 歌詞 | +| 31 | `lib/services/platform/url_launcher_service.dart:19-32` | 影片連結 map | 外部開啟 | +| 32 | `url_launcher_service.dart:36-45` | 頻道連結 map | 外部開啟 | +| 33 | `lib/services/radio/radio_controller.dart:672` | 直接讀 `bilibiliAccountServiceProvider` | 電台 | +| 34 | `radio_controller.dart:741` | `station.sourceType == SourceIds.bilibili` | 電台 | +| 35 | `radio_controller.dart:755` | `const sourceType = SourceIds.bilibili` | 電台 | +| 36 | `lib/services/radio/radio_source.dart:140-153` | 拒絕 YouTube、只收 Bilibili | 電台 | +| 37 | `lib/providers/account/account_provider.dart:78-81` | `accountProvidersBySource` map | 登入 | +| 38 | `account_provider.dart:85-92` | `accountServicesProvider` 手寫清單 | 登入 | +| 39 | `account_provider.dart:131-152` | 只刷 Bilibili cookie | 登入/Cookie | +| 40 | `lib/providers/audio/audio_controller_provider.dart:74` | `dynamicPlaylistSource(SourceIds.youtube)` | Mix | +| 41 | `lib/providers/audio/audio_settings_provider.dart:45` | 預設歌詞順序 | 歌詞 | +| 42 | `lib/providers/download/download_scanner.dart:387` | 未知資料夾 → `SourceIds.bilibili` | 下載 | +| 43 | `lib/providers/library/playlist_import_provider.dart:98-105` | switch `PlaylistSource` → 字串(與 #21 重複一份) | 匯入/歌詞 | +| 44 | `lib/providers/library/playlist_provider.dart:426` | `dynamicPlaylistSource(SourceIds.youtube)` | Mix | +| 45 | `lib/providers/library/remote_playlist_sync_provider.dart:43-58` | adapter map | 遠端歌單寫入 | +| 46 | `lib/providers/lyrics/lyrics_provider.dart:36` 一帶 | 每個歌詞源一個 provider | 歌詞 | +| 47 | `lyrics_provider.dart:172-181` | if/else 歌詞源取內容 | 歌詞 | +| 48 | `lyrics_provider.dart:391` | switch 篩選 → 歌詞源 | 歌詞 | +| 49 | `lyrics_provider.dart:430-460` | switch 歌詞源並行搜尋 | 歌詞 | +| 50 | `lib/providers/search/search_provider.dart:217` | `liveSource(SourceIds.bilibili)` | 直播 | + +另外還有整份檔案就是某一源的 UI/服務:3 個登入頁、3 個 `add_to__playlist_dialog.dart`、3 組帳號服務、3 個歌詞源類別。它們不在表內。 + +### 4.2 總數 + +- 寬定義:**50 個分支點**(上表),分布在 **28 個檔案**(ui 11、services 8、providers 9)。依能力:歌詞 16、匯入/匹配 7、遠端歌單 6、電台/直播 6、登入 4、Mix 4、詳情呈現 2、外部開啟 2、其他 3(排行偵錯、備份、下載)。 +- 窄定義(static rule `test/support/source_branch_points_static_rule_test.dart` 只數 `==`/`!=`/`case`/`=>` 且排除 map 與 lyrics 檔名的字面值):整個 `lib/`(排除 `lib/data/sources/`)預算 **9** 處(`source_branch_points_static_rule_test.dart:24-45`);落在 ui/services/providers 的是 `radio_controller.dart` 1、`lyrics_auto_match_service.dart` 1、`account_playlists_sheet.dart` 3,共 **5**。這個測試本審計**未執行**,數字取自它宣告的預算。 +- 兩個數字差很多,因為 static rule 刻意把 map 查表、`PlaylistSource` enum、歌詞源字串、寫死能力的 `xxxSource(SourceIds.y)` 呼叫都排除在外。它守得住「多一個 `==`」,守不住「多一張手寫 map」。 + +--- + +## 5. 匯入與匹配流程 + +### 5.1 外部歌單(Spotify/QQ)匹配到可播放音源 + +入口:匯入對話框先問 `SourceManager.sourceTypeForUrl`(內部源直接匯入),認不得才問 `PlaylistImportService.detectSource`(`import_playlist_dialog.dart:159-180`)。 + +演算法(`lib/services/import/playlist_import_service.dart`): + +1. 取歌單:第一個 `canHandle(url)` 的 `PlaylistImportSource.fetchPlaylist`(`:212-219`)。Spotify 解析 embed 頁(`spotify_playlist_source.dart:57-76`);QQ 打簽名 API(`qq_music_playlist_source.dart:151-181`)。 +2. 逐首搜尋,**序列執行**,每首之間固定延遲:`all` 1000ms、單源 800ms(`:276-285`;常數 `lib/core/constants/app_constants.dart:83-88`)。 +3. 查詢字串 `"$title ${artists.join(' ')}"`(`playlist_import_source.dart:28`)。每源取 `maxResults × 8` 筆,預設 `5 × 8 = 40`(`:153, 312`)。 +4. 候選來源: + - `all`:並行搜 **YouTube 與 Bilibili**,單源失敗只寫 log(`:314-331`)。網易雲不在內(`:15-21` 註解承認)。 + - `bilibiliOnly` / `youtubeOnly`:單源,失敗直接拋出,該首記為 `noResult`(`:333-351, 264-272`)。 +5. 打分 `_calculateRelevanceScore`(`:443-535`): + - 時長先過濾:差距評分 < -50 直接回 -100(`:454-463`)。時長分數表見 `:619-660`(差 ≤10 秒 +20;>200% 為 -100)。 + - 加權:標題相似度 ×0.35、藝人相似度 ×0.25、播放量 ×0.15、組合分 ×0.15(`:499-503`)。 + - 加分:精確匹配、頻道與藝人、官方頻道、標題關鍵字、時長、版本、括號內歌名 +15(`:506-532`)。 + - 相似度用 N-gram 與 Jaccard 取高者(`:1044-1075`)。 +6. 排序時另外加播放量相對分:佔最高播放量比例 ×8,差 100 倍再 +10、差 10 倍 +4(`:376-427`)。 +7. 過濾分數 < 0,取前 5,第一名自動選為 `selectedTrack`,狀態 `matched`(`:354-372, 250-258`)。 +8. 建立歌單時把原平台 id 寫進 `originalSongId` / `originalSource`(`'netease'|'qqmusic'|'spotify'`),給歌詞直取用(`:80-110`)。 + +手動重搜 `searchForTrack` 與自動匹配**不一致**:`all` 模式搜全部已註冊音源(含網易雲),而且只依播放量排序、不打分(`:1163-1179`)。 + +```mermaid +sequenceDiagram + actor U as 使用者 + participant D as ImportPlaylistDialog + participant P as PlaylistImportNotifier + participant S as PlaylistImportService + participant X as Spotify或QQ ImportSource + participant F as searchSourcesInParallel + participant YT as YouTubeSource + participant BL as BilibiliSource + U->>D: 貼上網址 + D->>D: sourceTypeForUrl 為 null + D->>P: detectSource(url) + U->>D: 開始匯入 + D->>P: importAndMatch(url) + P->>S: importAndMatch(url, searchSource) + S->>X: fetchPlaylist(url) + X-->>S: ImportedPlaylist + loop 每一首(序列) + S->>F: search title+artists, pageSize 40 + par YouTube + F->>YT: search() + and Bilibili + F->>BL: search() + end + F-->>S: 成功源的結果,失敗源只記 log + S->>S: _sortByRelevance 與過濾分數小於 0 + S->>S: 取前 5,第一名為 selectedTrack + S->>S: delay 1000ms 或 800ms + end + S-->>P: PlaylistImportResult + P-->>D: phase completed + D->>U: 開啟匯入預覽頁 +``` + +### 5.2 歌詞匹配 + +觸發:每首歌開始播放時 `LyricsAutoMatchCoordinator.onTrackStarted` fire-and-forget(`lib/services/audio/lyrics_auto_match_coordinator.dart:37-39`);設定 `autoMatchLyrics` 關閉就不跑(`:55-58`)。來源順序 = 設定的 `lyricsSourcePriority` 扣掉停用的(`:62-65`),預設 `netease,qqmusic,lrclib`(`settings.dart:357`)。 + +流程(`lib/services/lyrics/lyrics_auto_match_service.dart:72-203`): + +1. 同一首並發去重(`:80-86`)。已有 `LyricsMatch` 就跳過(`:89-94`)。 +2. 網易雲曲目且網易雲啟用:用 `sourceId` 直取,逾時 `networkReceiveTimeout`(`:104-127`)。 +3. 有 `originalSongId` 且其來源啟用:直取網易雲或 QQ,Spotify 不支援(`:130-151, 643-672`)。 +4. AI 設定可用時依模式:`alwaysAi` 用 AI 解析標題再查詢;`advancedAiSelect` 收集所有源候選交給 AI 挑;AI 失敗退回正則(`:153-190, 323-437`)。 +5. 預設:`TitleParser` 正則解析標題(`:231-252`),依來源順序逐源查,**第一個有結果的源就停**(`:268-309`)。 +6. 每源的篩選:時長差 ≤ 20 秒(`app_constants.dart:179`;網易雲與 QQ 的 `duration == 0` 直接放行,`:693, 736`);只剩一筆就用它,多筆就 `_selectBestMatch`(`:701-703, 744-746, 786-793`)。 +7. `_selectBestMatch` 打分:標題 Levenshtein ×0.4、藝人 ×0.3(無藝人給 0.5)、時長 ×0.2(≤3 秒 1.0、≤10 秒 0.8、≤20 秒 0.5)、有同步歌詞 ×0.1;最高分 ≥ 0.6 才採用(`:819-895`;門檻 `app_constants.dart:182`)。 +8. 預設只接受同步歌詞;開了 `allowPlainLyricsAutoMatch` 才接受純文字(`:223-229`)。 +9. 命中後寫快取與 `LyricsMatch`(`:624-638`)。 + +**不一致**:類別註解寫「只有一个结果符合时长条件时才自动匹配」(`lyrics_auto_match_service.dart:24-26`),程式碼在多筆時會用 `_selectBestMatch` 挑一筆(`:701-703`)。 + +快取:`LyricsCacheService` 是檔案型 LRU,預設最多 50 檔、總量 5MB,超過從最舊開始刪(`lib/services/lyrics/lyrics_cache_service.dart:13-19, 203-240`);metadata 寫入防抖 2 秒(`:39`)。顯示時先讀快取,沒有才依 `LyricsMatch.lyricsSource` 打對應 API 再寫回快取(`lib/providers/lyrics/lyrics_provider.dart:163-190`)。 + +```mermaid +sequenceDiagram + participant C as LyricsAutoMatchCoordinator + participant M as LyricsAutoMatchService + participant R as LyricsRepository + participant NE as 網易雲歌詞 + participant QQ as QQ音樂歌詞 + participant LR as lrclib + participant AI as OpenAI相容端點 + participant K as LyricsCacheService + C->>M: tryAutoMatch(track, enabledSources) + M->>R: getByTrackKey + alt 已有匹配 + M-->>C: false + end + opt 網易雲曲目 + M->>NE: getLyricsResult(sourceId) + end + opt 有 originalSongId + M->>NE: 或 QQ getLyricsResult(originalSongId) + end + alt AI 可用 + M->>AI: 解析標題或挑選候選 + else 正則 + M->>M: TitleParser.parse(title) + end + loop 依來源順序,命中即停 + M->>NE: searchLyrics + M->>QQ: searchLyrics + M->>LR: search + M->>M: 時長 20 秒內,多筆用分數 0.6 門檻 + end + M->>K: put(trackKey, result) + M->>R: save(LyricsMatch) + M-->>C: true +``` + +--- + +## 附:本檔發現的文檔與程式碼不一致 + +| 主張 | 位置 | 程式碼現況 | +|---|---|---| +| 歌詞自動匹配只在單一結果時匹配 | `lyrics_auto_match_service.dart:24-26` | 多筆時用分數挑(`:701-703`) | +| 三個 adapter 共 22 處 `on DioException catch` | `lib/services/audio/playback_error_presenter.dart:60` | 實數 Bilibili 9、YouTube 5、網易雲 5,共 19;加直播 client 2 處為 21 | +| `PlaylistSource.netease` 是匯入來源 | `playlist_import_source.dart:95-98` | 沒有對應的 `PlaylistImportSource`(`playlist_import_service.dart:137`) | +| lrclib UA 帶專案網址 | `lrclib_source.dart:24` | 網址是佔位字串 `github.com/user/fmp` | diff --git a/docs/audit/ui.md b/docs/audit/ui.md new file mode 100644 index 000000000..5c49ea6b3 --- /dev/null +++ b/docs/audit/ui.md @@ -0,0 +1,354 @@ +# UI 現況審計 + +> 現況描述,未經確認,不代表目標。 + +審計日期:2026-09-26,分支 `docs/audit`(HEAD `6d78fe23`)。證據優先序:實機行為 > 程式碼 > 測試 > 文檔。實機執行用 profile build(環境見 `docs/audit/perf-baseline.md`)。截圖在 `docs/audit/screenshots/`,含個人資料的區域已模糊或塗灰(見 § 6.0)。 + +## 1. 頁面地圖 + +### 1.1 路由與導航 + +路由表在 `lib/ui/router.dart`(go_router)。一個 `ShellRoute`(`router.dart:129`)包住所有有導航殼的頁面;兩個全螢幕播放頁掛在 `rootNavigatorKey` 上、跳出殼外(`router.dart:293-304`,`_fullscreenPlayerPage()` 上滑轉場)。 + +```mermaid +flowchart LR + subgraph Shell["ShellRoute(AppShell + ResponsiveScaffold)"] + home["/ 首頁 HomePage"] + search["/search SearchPage"] + queue["/queue QueuePage"] + library["/library LibraryPage"] + radio["/radio RadioPage"] + settings["/settings SettingsPage"] + explore["/explore ExplorePage"] + history["/history PlayHistoryPage"] + downloaded["/library/downloaded DownloadedPage"] + dlcat["/library/downloaded/:folderName DownloadedCategoryPage"] + detail["/library/:id PlaylistDetailPage"] + s_dm["/settings/download-manager"] + s_audio["/settings/audio"] + s_lyr["/settings/lyrics-source"] + s_rank["/settings/home-ranking"] + s_guide["/settings/user-guide"] + s_dev["/settings/developer"] + s_db["/settings/developer/database"] + s_log["/settings/developer/logs"] + s_acc["/settings/account"] + s_bl["…/bilibili-login"] + s_yt["…/youtube-login"] + s_ne["…/netease-login"] + end + player["/player PlayerPage(全螢幕)"] + rplayer["/radio-player RadioPlayerPage(全螢幕)"] + + home -- "查看全部(排行榜)" --> explore + home -- "查看全部(最近播放)" --> history + home -- go --> library + home -- go --> queue + queue -- "空狀態按鈕 go" --> search + settings --> history + settings --> s_acc + settings --> s_audio + settings --> s_lyr + settings --> s_rank + settings --> s_guide + settings --> s_dm + settings -- "開發者選項(連點版本號後才出現)" --> s_dev + s_dev --> s_db + s_dev --> s_log + s_acc --> s_bl + s_acc --> s_yt + s_acc --> s_ne + library --> downloaded --> dlcat + library -- "歌單卡片" --> detail + Shell -. "MiniPlayer(有目前曲目才顯示)" .-> player + Shell -. "RadioMiniPlayer(有目前電台才顯示)" .-> rplayer +``` + +證據:`home_page.dart:203`(explore)、`:672`(history)、`:353`/`:415`(library)、`:1029`(queue);`queue_page.dart:355`;`settings_page.dart:76,108,172`;`settings_about.dart:95-111`(開發者選項,`developerOptions.isEnabled` 為執行期狀態);`library_page.dart:64`;`downloaded_page.dart:297`;`playlist_grid_card.dart:57`;`mini_player.dart:58`;`radio_mini_player.dart:44`。 + +不經路由開啟的全螢幕/半屏介面:`showModalBottomSheet` 16 處、`showDialog` 分布在 13 個檔案,包括歌詞搜尋(`lib/ui/pages/lyrics/lyrics_search_sheet.dart`,`lib/ui/pages/lyrics/` 只有這一個檔)、匯入歌單預覽(`import_preview_page.dart:33` 定義的是 `ImportPreviewDialog`,**不一致**:檔名叫 page,實際是 dialog;`settings_backup.dart:113` 另有同名私有類別 `_ImportPreviewDialog`)、加入歌單、快捷鍵錄製。 + +**沒有歌詞頁路由。** 歌詞只以兩種形式出現:播放頁內的一欄(`resolvePlayerLayout` 的 `wideSplit`,`player_page.dart:76-86`),和桌面的獨立浮動視窗(`lib/ui/windows/lyrics_window.dart`,`desktop_multi_window` 開的另一個 engine,入口 `lyricsWindowMain`)。 + +**播放頁沒有路由層的防呆。** 進入點只有 MiniPlayer,而 MiniPlayer 在 `currentTrack == null` 時回傳 `SizedBox.shrink()`(`mini_player.dart:26-29`);`PlayerPage` 本身接受 `currentTrack` 為 null。直接 `context.push('/player')` 會進入一個空的播放頁(程式碼推論,未實測)。 + +### 1.2 導航殼:手機 vs 桌面 + +`AppShell`(`lib/ui/app_shell.dart`)包 `ResponsiveScaffold`(`lib/ui/layouts/responsive_scaffold.dart`,624 行),6 個固定分頁:首頁、搜尋、佇列、音樂庫、電台、設定(`responsive_scaffold.dart:47-84`)。 + +| 視窗級距 | 版面 | 程式碼 | +|----------|------|--------| +| compact(< 600dp) | `Scaffold` 底部 `NavigationBar`;MiniPlayer 疊在導航列上方 | `_CompactLayout`,`:149-189` | +| medium(600–839dp) | 左側收合 `NavigationRail`(`scrollable: true`、`labelType: all`)+ 內容;MiniPlayer 在 `bottomNavigationBar` | `_MediumLayout`,`:192-223`;`CollapsedNavRail` `:238-290` | +| expanded 以上(≥ 840dp) | 可展開的導航軌(72 ↔ 256dp)+ 內容 + 有目前曲目時右側 Detail Panel(預設 412dp、可拖寬,上限視窗 40%) | `_ExpandedLayout`,`:293-608`;尺寸在 `lib/core/constants/app_layout.dart` | + +三種版面的 MiniPlayer 都掛在 `Scaffold.bottomNavigationBar`(`:168`、`:220`、`:368`),所以在桌面上它橫跨整個視窗寬度,導航軌下方那一段也算在內(見 `windows-home.png` 左下角)。 + +`/explore`、`/history` 不是導航分頁,`navIndexForLocation()` 把它們一律對到 index 0 首頁(`:93-100`)。從設定頁進播放歷史時,導航列亮的是「首頁」而不是「設定」(程式碼推論;Android 實機上從首頁進入時亮首頁,見 `android-history.png`)。 + +Windows 另有自繪標題列 `CustomTitleBar`(`lib/ui/widgets/app_bars/custom_title_bar.dart`,36dp),只在 `Platform.isWindows` 分支掛上(`lib/app.dart:181-188`);非 Windows 走 `SafeArea`。 + +## 2. 響應式斷點 + +定義在 `lib/core/constants/breakpoints.dart:15` 的 `enum WindowClass`: + +| 級距 | 下界(dp) | 程式碼中的用途 | +|------|-----------:|----------------| +| compact | 0 | 底部導航;MiniPlayer 音量改成彈出直式滑桿(`mini_player_volume_control.dart:36-81`) | +| medium | 600 | 收合導航軌 | +| expanded | 840 | 可展開導航軌 + Detail Panel;播放頁開始可用兩欄 | +| large | 1200 | 註解寫「可收合導覽軌 + fixed pane」,但 `ResponsiveScaffold` 對 expanded 以上走同一個 `_ExpandedLayout`,**沒有看到 large 專屬的分支**(**不一致**:註解主張與程式碼) | +| extraLarge | 1600 | 同上,無專屬分支 | + +數值取自 Material 3 / `androidx.window` 的 `WindowSizeClass`(檔頭註解)。同檔另有 `columnsFor(containerWidth)`(`_idealColumnWidth = 400`、最多 3 欄),用來算容器內欄數,與視窗級距刻意分開。 + +播放頁版面另外看高度(`player_page.dart:76-86`):寬 ≥ 840dp 且高 ≥ 520dp(`AppLayout.playerWideMinHeight`)才走兩欄;有歌詞時 `wideSplit`、沒有時 `wideSingle`;高度不足且橫向時 `shortSplit`,其餘 `narrow`。 + +不走 `WindowClass` 的硬編碼寬度判斷 3 處:`account_management_page.dart:357`(`maxWidth < 520`)、`color_palette_button.dart:179-180`(320 / 360)、`lyrics_style_dialog.dart:166-167`(400 / 360)。都是對話框邊距或按鈕換行的局部判斷,數值與斷點不對齊。 + +### 手機與桌面的差異清單 + +| 面向 | Android(compact) | Windows(預設 1280×800 → expanded) | +|------|--------------------|------------------------------------| +| 導航 | 底部 `NavigationBar` | 左側導航軌(可展開到 256dp) | +| 目前曲目資訊 | 只有 MiniPlayer | MiniPlayer + 右側 Detail Panel(封面、統計、下一首、簡介、評論) | +| MiniPlayer 尾端控制 | 無 | 音訊輸出裝置選擇器 + 音量(`isDesktopPlatform`,`mini_player.dart:96`) | +| 標題列 | 系統狀態列 | 自繪 `CustomTitleBar` | +| 播放頁 | narrow | wideSingle / wideSplit;頂列多出輸出裝置與音量(`player_page.dart:276,283`) | +| 橫向捲動區 | 觸控拖曳 | 額外支援滑鼠拖曳與滾輪(`horizontal_scroll_section.dart:51`) | +| 歌詞 | 播放頁內 | 播放頁內 + 桌面浮動歌詞視窗 | +| 字型清單 | sans-serif 系列 | Microsoft YaHei UI、SimSun 等(`app_theme.dart:71,97`) | +| 全域快捷鍵 | 無 | `hotkey_manager` 系統級熱鍵(§ 5.3) | + +`isDesktopPlatform` 判斷 Windows、macOS、Linux 三者(`lib/core/utils/platform_utils.dart`),但專案只出 Android 與 Windows。 + +## 3. 主題與設計 token + +### 3.1 token 在哪裡 + +`lib/ui/theme/` 只有兩個檔: + +- `app_theme.dart`(223 行):`ThemeData` 組裝(`useMaterial3: true`,`:126`)、從種子色產生 `ColorScheme`、`cardTheme` 用 `AppRadius.borderRadiusLg`(`:143-145`)、`listTileTheme` 用 `borderRadiusMd`(`:150-151`)、`navigationBarTheme`、字型清單與 fallback(`textTheme` 只套 `fontFamilyFallback`,`:204`,**沒有自訂字級**)。 +- `theme_preset_colors.dart`(45 行):預設紫 `Color(0xFF6750A4)` 與 9 組預設主題色。 + +間距以外的 token 實際放在 `lib/core/constants/ui_constants.dart`(217 行): + +| token | 值 | +|-------|----| +| `AppRadius` | xs 2、sm 4、md 8、lg 12、xl 16、pill 28、sheet 20(另有預建 `borderRadiusXs…Pill`) | +| `AnimationDurations` | fastest 100、fast 150、medium 200、normal 300、slow 500、loop 1600 ms | +| `AppSizes` | playerMainButton 80、thumbnail 40 / 48 / 56、cardAspectRatio 0.8、maxBottomSheetHeight 800 | +| `ImageTargetSizes` | 32 / 56 / 120 / 200 / 460 / 480(圖片載入檔位,#107) | +| `ToastDurations` / `DebounceDurations` | 1500 / 3000 ms;300 / 500 ms | + +版面尺寸在 `lib/core/constants/app_layout.dart`(`railCollapsed 72`、`railExpanded 256`、`detailPanelMin 320`、`detailPanelDefault 412`、`paneSpacer 24`、`playerCoverMax 420`、`playerContentMaxWide 720` 等)。 + +**沒有間距 token**:`grep -rn AppSpacing lib` 零命中,也沒有其他間距常數類別。**沒有字級 token**:字級全靠 `Theme.of(context).textTheme` 的 M3 預設樣式或字面數字。 + +### 3.2 硬編碼統計(`lib/ui/`,排除 `lib/ui/theme/` 與 `*.g.dart`) + +數字由 Python 全文掃描(跨行建構子也算)取得;單行 `grep -rhoE` 抽查結果在括號內,差異來自跨行寫法。 + +| 模式 | 次數 | 最常見的值 | +|------|-----:|-----------| +| `EdgeInsets.all(數字)` | 68 | 16(23)、12(11)、8(9)、24(7)、32(6) | +| `EdgeInsets.symmetric(` / `.only(` / `.fromLTRB(` | 98 / 47 / 39 | — | +| `SizedBox(height: 數字)` | 263(單行 191) | 16(73)、8(46)、20(32)、12(32)、2(16) | +| `SizedBox(width: 數字)` | 251 | 8(83)、12(26)、16(24)、4(24)、20(11) | +| `fontSize:` 字面數字 | 29 | 12(8)、13(6)、14(4)、11(3)、10(3) | +| `Color(0x…)` | 10(含 theme 目錄 19) | 集中在 `color_palette_button.dart`(7)、`account_management_page.dart`(3) | +| `Colors.xxx` | 81 | transparent(23)、white(21)、black(12)、red(8)、white70(4) | +| `BorderRadius.circular(…)` | 6 | 3 處傳參數、2 處字面 8、1 處用 `AppRadius` | + +token 使用量: + +| token | `lib/ui/` 內引用 | +|-------|----------------:| +| `AppRadius.*` | 106–111(`borderRadiusLg` 33、`Md` 26、`Sm` 23、`Xs` 12) | +| `AnimationDurations.*` | 36(對比字面 `Duration(milliseconds: N)` 只剩 2 處) | +| `Theme.of(context).textTheme` | 142 | +| `Theme.of(context).colorScheme` | 205 | +| `AppSpacing.*` | 0(不存在) | + +結論:圓角、動畫時長、色彩已經收斂到 token 或主題;**間距與字級沒有 token**,間距完全是字面數字(`EdgeInsets` 250 餘處、`SizedBox` 500 餘處),值集中在 4 / 8 / 12 / 16 / 20 / 24 / 32,事實上是一套 4 的倍數系統但沒有被命名。`fontSize:` 的 29 處繞過了 `textTheme`,會跟使用者字級設定脫鉤(**推測**,未逐處確認是否另乘 `textScaler`)。 + +## 4. i18n + +- 語言:`lib/i18n/` 下 `zh-CN`、`zh-TW`、`en` 三個資料夾,各 38 個 namespace 檔(`*.i18n.json`)。產物 `strings*.g.dart` 已 gitignore。 +- slang 設定(`slang.yaml`):`base_locale: zh-CN`、`namespaces: true`、`input_file_pattern: .i18n.json`、`lazy: false`(註解說明 Android / Windows 不支援 deferred loading)。 +- key 數量(Python 遞迴數葉節點):三語言各 **1176** 個,彼此缺漏 0、多出 0。 +- 同值檢查:`en` 值含中文字元 0 個;`zh-TW` 與 `zh-CN` 字面完全相同且含中文的 153 個(例如 `account.logout`、`audioSettings.qualityLevel.high`)。**推測**大多是繁簡同形字(如「登出」「高」),不一定是漏翻;沒有逐條確認。 +- 語言選擇:設定 → 外觀 → 語言,四選一:跟隨系統(`null`,走 `useDeviceLocaleSync()`)、简体中文、繁體中文、English(`lib/providers/settings/locale_provider.dart`、`settings_appearance.dart:422-460`)。實機上 Android(系統 en-US)顯示英文、Windows(系統繁中)顯示繁中,兩者都是「跟隨系統」。 +- 複數:英文字串用 `"$n tracks"`(`lib/i18n/en/library.i18n.json:4`),沒有用 slang 的 plural,實機出現「**1 tracks**」(`android-library.png`、`android-home-scrolled.png`)。 +- 數字格式:中文萬/億一律 `toStringAsFixed(1)`(`lib/core/utils/number_format_utils.dart:28-37`),所以出現「**4600.0萬**」「1100.0萬」(`windows-home.png`);英文走 K / M / B,「46.0M」同樣帶多餘的 `.0`。 + +### UI 中的硬編碼字串 + +中文字面值(排除 `//`、`///` 註解行)38 處,扣掉 1 處 RegExp(`fmp_audio_device_selector.dart:105`)後 37 處使用者可見: + +- `lib/ui/windows/lyrics_window.dart:33-66`:33 處**簡體**預設字串(`'等待歌词...'`、`'暂无歌词'`、`'上一首'`…)。註解寫「從主視窗同步」,同步到之前或失敗時,英文與繁中使用者會看到簡體。 +- `lib/ui/pages/settings/developer_options_page.dart:307`:`'Flutter 图片: …'`,簡體、未走 i18n。 +- `lib/ui/startup_failure_app.dart:66,73,77,81`:啟動失敗畫面的中英雙語字串。註解說明這是刻意的(此時 i18n 與 Riverpod 可能正是故障源),屬合理例外。 + +英文字面值 5 處:`'FMP'`(`startup_failure_app.dart:35`)、`'URL'` ×2(`import_playlist_dialog.dart:220`、`add_radio_dialog.dart:94`)、`'Info+'` / `'Warning+'`(`log_viewer_page.dart:209,212`)。前三個是專有名詞,後兩個是漏走 i18n。 + +## 5. 無障礙與桌面鍵盤操作 + +### 5.1 語意與 tooltip(程式碼) + +| 項目 | 次數 | +|------|-----:| +| `Semantics(` | 12(6 檔) | +| `ExcludeSemantics(` | 2 | +| `MergeSemantics` / `semanticLabel` | 0 / 0 | +| `tooltip:` | 120(41 檔) | +| `Tooltip(` | 14 | +| `IconButton` 有 `tooltip:` | 97 / 98(例外 `lyrics_title_bar.dart:212` 以外層 `Semantics` 補上) | + +`lyrics_title_bar.dart` 的自訂參數叫 `semanticsLabel`(多一個 s,`:122-224` 共 12 處),不是框架的 `semanticLabel`。 + +### 5.2 實機觀察到的語意問題 + +- **播放頁的大播放鍵沒有無障礙名稱。** Windows MSAA 樹中它是 `[push button] '' @(1860,1480 120x120)`,旁邊的上一首、下一首都有名字。`PlayerPlayPauseButton` 把 `FilledButton` 包在 `Tooltip` 裡(`player_play_pause_button.dart:46-48`),按鈕本身沒有 label;Tooltip 的訊息沒有進到這個節點。 +- **MiniPlayer 是「按鈕裡包按鈕」。** MSAA 樹裡 `'開啟播放器'` 是整條 1904×97 的 push button,隨機播放、上一首、播放等按鈕是它的子節點(`mini_player.dart:54-58` 的 `Semantics(button: true)` 包 `GestureDetector`)。讀屏會先念整條再念子按鈕;以此節點中心點擊,在窄視窗時會點到播放鍵(本次審計因此誤觸發播放,見 § 6.0)。 +- Android 的曲目列在 uiautomator 裡角色是 `ImageView`,文字是整列合併(`'1\n“世事起伏多折…\n早睡起大王\n2.1M'`),名次、標題、作者、播放數擠成一個節點。 +- Windows MSAA 樹健康:首頁 133 個節點,run log 沒有 `Failed to update ui::AXTree`。 + +### 5.3 鍵盤 + +程式碼:Flutter 的快捷鍵框架**完全沒用**:`Shortcuts(`、`Actions(`(排除類別名尾碼的誤配後)、`CallbackShortcuts`、`LogicalKeySet`、`SingleActivator`、`FocusTraversalGroup`、`RawKeyboardListener`、`HardwareKeyboard` 都是 0。唯一的 `KeyboardListener` 在快捷鍵錄製對話框(`settings_desktop.dart:439`)。`autofocus` 7 處,全在對話框或搜尋框。App 內沒有任何快捷鍵(沒有空白鍵播放、沒有 Esc 返回、沒有 Ctrl+F 搜尋)。 + +全域熱鍵:`hotkey_manager`,`HotKeyScope.system`(`lib/data/models/hotkey_config.dart:78`),預設值(`:212` `HotkeyConfig.defaults()`): + +| 動作 | 預設 | +|------|------| +| 播放/暫停 | Ctrl+Alt+Space | +| 下一首/上一首 | Ctrl+Alt+→ / Ctrl+Alt+← | +| 停止 | Ctrl+Alt+S | +| 音量+/- | Ctrl+Alt+↑ / Ctrl+Alt+↓ | +| 靜音 | Ctrl+Alt+M | +| 顯示/隱藏視窗 | Ctrl+Alt+W | + +`Settings.enableGlobalHotkeys` 預設 `false`(`lib/data/models/settings.dart:292`);服務先以 `enableHotkeys: false` 初始化(`lib/providers/system/windows_desktop_provider.dart:42`),再依設定同步。 + +Windows 實測(1904×1191 視窗,繁中): + +| 操作 | 結果 | 證據 | +|------|------|------| +| Tab(第 1 次) | 焦點到「查看全部」,按鈕出現淡色底 | scratchpad `w_tab1.png` | +| Tab ×4 | 焦點到排行榜第 2 列,整列淡灰底;**第 1 列沒有看到被聚焦**(**推測**第 2、3 次 Tab 停在第 1 列本身與其選單鈕) | `windows-focus-row.png` | +| Tab ×14 | 仍在首頁排行榜(YouTube 第 2 列),焦點依文件順序逐列前進;要走到導航軌、Detail Panel、MiniPlayer 需要穿過整個清單 | scratchpad `w_tab14.png` | +| Shift+Tab 從頭倒退 | 依序到導航軌的「設定」「電台」「音樂庫」,每項是很淡的圓角底 | `windows-focus-rail.png` | +| 焦點在「音樂庫」按 Enter | 切到音樂庫頁 | `windows-library.png` | +| 播放頁 Esc | 第 1 次關掉右上角溢出選單;第 2 次**無作用**,停在播放頁 | scratchpad `w_escgrid.png` | +| Ctrl+Alt+W(`SendKeys`) | 視窗可見性沒變(`IsWindowVisible` 前後皆 true)。log 有 `Hotkeys registered`,但使用者可能改過綁定(`Settings.hotkeyConfig`,沒有讀取),也可能是合成按鍵沒被 `RegisterHotKey` 接到。**未能確認** | run log | + +焦點指示是 M3 預設的狀態層(淡色底),在深色主題下對比很低,沒有焦點框。空白鍵播放沒有實測:程式碼裡沒有對應的快捷鍵,而實測會觸發真實播放。 + +## 6. 實機截圖與問題清單 + +### 6.0 執行方式與資料 + +- Android:AVD `Medium_Phone`(1080×2400 @ 420dpi → 411×914dp,compact),`flutter run --profile -d emulator-5554`,系統語言 en-US,淺色主題。App 資料是 emulator 內既有的測試資料。 +- Windows:`flutter run --profile -d windows`,系統繁中,深色主題(跟隨系統),1904×1191 client px @ 150%(≈1269×794dp,expanded);另把視窗縮到 600px 寬(≈390dp,compact)看窄版。 +- **Windows 的 debug / profile build 讀使用者真實的 App 資料**:資料庫在 `getApplicationDocumentsDirectory()` 下的 `FMP/`(`lib/data/database/database_provider.dart:49-52`),Windows 上就是使用者的「文件」資料夾,log 在 `Documents\FMP\logs`(`lib/core/log_file_sink.dart:25-27`)。沒有開發用的資料目錄開關。因此 Windows 截圖的 Detail Panel、MiniPlayer、佇列、搜尋紀錄、歌單名稱、播放頁封面與標題都已模糊。 +- Android 的使用者歌單名稱與搜尋紀錄已塗灰,播放歷史列表已模糊;歌單詳情頁顯示了匯入歌單的擁有者名稱,所以沒有放進 repo。 +- **副作用**:在 Windows 窄視窗點 MiniPlayer 的「開啟播放器」節點中心時,點到的是播放鍵,使用者目前的佇列曲目開始播放(從真實音源串流),隨即按暫停。這會在真實資料庫留下播放位置,**可能**也寫入一筆播放歷史。 +- 播放頁(Android)無法進入:emulator 佇列是空的,MiniPlayer 不顯示。`references/runtime-state.md` 的離線做法要用 `ext.isar.editProperty` 改資料庫並放一個本地 WAV,`ext.isar` 只在 debug build 有,而且會改動資料,本次沒做。Windows 有使用者既有的目前曲目,可以不播放就打開播放頁。 +- 歌詞:沒有獨立頁面;Windows 播放頁的目前曲目沒有歌詞(走 `wideSingle`),浮動歌詞視窗沒有開。 + +### 6.1 Android(Medium_Phone,英文,淺色) + +| 首頁 | 首頁(下捲) | 探索 | +|---|---|---| +| ![](screenshots/android-home.png) | ![](screenshots/android-home-scrolled.png) | ![](screenshots/android-explore.png) | + +| 搜尋(空狀態) | 佇列(空) | 音樂庫 | +|---|---|---| +| ![](screenshots/android-search.png) | ![](screenshots/android-queue.png) | ![](screenshots/android-library.png) | + +| 電台(空) | 設定 | 設定(下捲) | 播放歷史 | +|---|---|---|---| +| ![](screenshots/android-radio.png) | ![](screenshots/android-settings.png) | ![](screenshots/android-settings-scrolled.png) | ![](screenshots/android-history.png) | + +觀察: + +1. **首頁沒有標題列,其他分頁都有。** 首頁從區塊標題「Trending」開始(靠左);搜尋頁以搜尋框當頂部;佇列、音樂庫、電台、設定各有置中的 AppBar 標題。一級分頁的頂部形式有三種(`android-home.png`、`android-search.png`、`android-settings.png`)。 +2. **同一個排行榜列在首頁與探索頁的右側留白不同。** 首頁的 ⋮ 在 x=933(1080 寬)、探索頁在 x=975(uiautomator 座標);首頁列右側多留約 40px,也跟區塊標題的「View All」不對齊。 +3. **「1 tracks」**:英文沒有處理複數(首頁「My Playlists」卡片、音樂庫卡片)。 +4. **搜尋頁來源篩選列被排序鈕蓋住。** 「All Sources / Bilibili / Yo…」橫向捲動,右端被固定的「Relevance」下拉鈕截斷,「NetEase Cloud Music」完全看不到,沒有漸層或箭頭提示還能捲(`android-search.png`;`search_page.dart:169-183` 的 `SingleChildScrollView` + 右側 `_buildSortButton`)。 +5. **設定列尾端的提示不一致。** 「Theme」「Language」有 `>`、「Theme Color」是色點、「Font」什麼都沒有;「Font」同樣是點了開選擇對話框(`settings_appearance.dart:308-313` 的 `onTap: _showFontDialog`),只是沒有 `>`(`android-settings.png`)。 +6. **設定是單一長清單。** Android 7 段(帳號、外觀、播放、快取、儲存、資料備份、關於;`settings_page.dart:68-164`),Windows 多一段「桌面」(`:153-162`),手機上要捲約 4 個畫面才到底;段落之間只有細分隔線與小標題(`android-settings-scrolled.png`)。 +7. 空狀態(佇列、電台)版式一致:大圖示 + 標題 + 說明 + 主要按鈕,品質良好。 +8. 播放歷史頁頂部有統計卡、篩選列、日期群組,資訊密度高;右上三個動作(日期、搜尋、更多)加置中標題,在 411dp 寬時標題與按鈕貼得很近(`android-history.png`)。 + +### 6.2 Windows(繁中,深色,1269×794dp) + +| 首頁 | 音樂庫 | +|---|---| +| ![](screenshots/windows-home.png) | ![](screenshots/windows-library.png) | + +| 設定 | 搜尋(空狀態) | +|---|---| +| ![](screenshots/windows-settings.png) | ![](screenshots/windows-search.png) | + +| 佇列 | 播放頁(wideSingle) | +|---|---| +| ![](screenshots/windows-queue.png) | ![](screenshots/windows-player.png) | + +| 播放頁溢出選單 | 焦點:排行榜列 | 焦點:導航軌 | +|---|---|---| +| ![](screenshots/windows-player-menu.png) | ![](screenshots/windows-focus-row.png) | ![](screenshots/windows-focus-rail.png) | + +窄視窗(600px ≈ 390dp,compact): + +| 首頁 | 播放頁(narrow) | +|---|---| +| ![](screenshots/windows-compact-home.png) | ![](screenshots/windows-compact-player.png) | + +觀察: + +1. **播放數格式「4600.0萬」「1100.0萬」**(`windows-home.png`),來自 `number_format_utils.dart:35` 固定一位小數。 +2. **桌面 MiniPlayer 在寬視窗中段大片空白。** 標題在左端約 360px 處結束,控制鈕從約 1350px 開始,中間約 1000px 沒有內容(`windows-home.png` 底部);進度條是頂端一條細線,沒有時間標示。 +3. **窄桌面視窗的 MiniPlayer 只剩 2 個字的標題。** compact 寬度下桌面仍放 7 顆控制鈕(隨機、上一首、播放、下一首、循環、輸出裝置、音量),標題被擠成「【早…」(`windows-compact-home.png`,模糊前為「【早...」)。手機版沒有後兩顆,所以這是桌面 compact 專屬問題(`mini_player.dart:96`、`mini_player_volume_control.dart:36-81` 只把音量改成彈出式,沒有收起按鈕)。 +4. **搜尋頁篩選列同樣被排序鈕截斷**:「全部音源 / 嗶哩嗶哩 / YouTube / 網易雲音樂 | 全部直播間 / 已開播 / 未開播」,「未開播」被「綜合」下拉鈕蓋住一半(`windows-search.png`)。在 1269dp 的視窗、內容區約 785dp 時仍放不下。 +5. **Detail Panel 常駐。** 有目前曲目時所有分頁右側都固定 412dp 的「正在播放」面板,設定、搜尋這類與播放無關的頁面內容區因此只剩約 60%(`windows-settings.png`、`windows-search.png`);面板可收起(`收起面板` 按鈕)。 +6. **設定頁在寬螢幕上仍是單欄長清單**(8 段),內容區約 785dp 寬,每列右端的 `>` 離文字很遠;尾端提示的不一致同 Android(「字體」沒有 `>`)。 +7. **播放頁頂列擠在右上角**:加入歌單、輸出裝置、靜音、音量滑桿、資訊、更多共 6 個元件排在右側,左側只有收起鈕(`windows-player.png`、`windows-compact-player.png`)。wideSingle 下封面與控制列置中,背景模糊色塊在右半部偏灰,左右不對稱(**推測**是封面取色的漸層,非錯誤)。 +8. **播放頁溢出選單把開關和指令混在同一欄圖示裡。** 「調整偏移」是開關,用 `check_box_outline_blank` / `check_box` 當前導圖示(`player_page.dart:344-353`),同一欄的其他項目(播放速度、搜尋歌詞、歌詞顯示)是一般圖示,視覺上像一個孤立的核取方塊(`windows-player-menu.png`)。 +9. 焦點指示對比低(§ 5.3);排行榜列聚焦時是淡灰底、導航軌是極淡的圓角底,在深色主題下幾乎看不出來(`windows-focus-row.png`、`windows-focus-rail.png`)。 +10. 首頁在寬視窗下排行榜列橫跨整個內容區(約 1208px),標題一行放完,但三個音源依序往下排,沒有利用寬度並排;`columnsFor()` 以內容區寬度算欄數,785dp / 400 → 1 欄(`breakpoints.dart` 的 `columnsFor`,程式碼推論)。 +11. Windows 內容區右側的捲軸常駐顯示在內容與 Detail Panel 的交界(`windows-home.png` x≈1383),位置在內容區中段,看起來像分隔線。 + +### 6.3 跨平台一致性 + +- 主題、元件(M3 `NavigationBar` / `NavigationRail`、`ChoiceChip`、`ListTile`)兩平台共用,圓角與色彩一致。 +- 手機底部導航的「Queue」是一級分頁,桌面也是;同時桌面 Detail Panel 又顯示「下一首」。佇列有兩個入口,資訊重複。 +- 語言是逐平台跟隨系統,所以兩平台實機看到的是不同語言;翻譯齊全,但簡繁混排的來源資料(標題、作者)不受 App 語言影響(例如 Windows 繁中介面下的「嗶哩嗶哩」區塊全是簡體標題)。這是資料本身,不是 i18n 缺漏。 + +## 7. 問題總表(依影響排序) + +| # | 問題 | 平台 | 證據 | +|---|------|------|------| +| 1 | 播放頁大播放鍵沒有無障礙名稱 | 兩者(Windows 實測) | MSAA `[push button] ''`;`player_play_pause_button.dart:46-48` | +| 2 | App 內沒有任何鍵盤快捷鍵;Esc 無法離開播放頁 | Windows | § 5.3;`Shortcuts`/`Actions` 使用數 0 | +| 3 | 窄桌面視窗的 MiniPlayer 標題被擠到 2 個字 | Windows compact | `windows-compact-home.png`;`mini_player.dart:96` | +| 4 | 搜尋篩選列被排序鈕截斷,且沒有可捲動提示 | 兩者 | `android-search.png`、`windows-search.png`;`search_page.dart:169-183` | +| 5 | 間距與字級沒有 token;`EdgeInsets` 250 餘處、`SizedBox` 500 餘處字面數字,29 處 `fontSize:` 繞過 `textTheme` | 程式碼 | § 3.2 | +| 6 | 「4600.0萬」「46.0M」數字格式、「1 tracks」複數 | 兩者 | `number_format_utils.dart:28-37`;`en/library.i18n.json:4` | +| 7 | MiniPlayer 語意是按鈕包按鈕;以它的中心點擊會誤觸播放 | Windows 實測 | MSAA `'開啟播放器'` 含子按鈕;`mini_player.dart:54-58` | +| 8 | 焦點指示在深色主題下幾乎看不見;Tab 要穿過整個清單才到導航軌 | Windows | `windows-focus-row.png`、`windows-focus-rail.png` | +| 9 | 桌面浮動歌詞視窗的 33 個預設字串是簡體硬編碼 | Windows | `lyrics_window.dart:33-66` | +| 10 | Windows 開發版讀寫使用者真實資料(`Documents\FMP`),沒有隔離開關 | Windows | `database_provider.dart:49-52` | +| 11 | 設定列尾端提示不一致;設定是 7–8 段單欄長清單 | 兩者 | `android-settings.png`、`windows-settings.png` | +| 12 | `WindowClass.large` / `extraLarge` 註解承諾的版面沒有實作 | 程式碼 | `breakpoints.dart`;`responsive_scaffold.dart:116-145` | + +## 8. 建議放進決策清單的項目 + +- **i18n 語言去留**:三語言 1176 key 完全對齊,維護成本是每次改字要動 3 份。`zh-CN` 是 base locale,但使用者(與 Windows 實機)用繁中。要決定:保留三語言、只留繁中 + 英文,或改 base locale 為 `zh-TW`。另需決定浮動歌詞視窗是否納入 slang。 +- **間距/字級 token**:重寫時是否引入間距與字級 token(現況的事實標準是 4 的倍數:4 / 8 / 12 / 16 / 20 / 24 / 32),以及是否用靜態規則擋掉新的字面數字。 +- **桌面鍵盤操作的範圍**:要不要做 App 內快捷鍵(空白鍵播放、Esc 返回、Ctrl+F 搜尋)與焦點順序(`FocusTraversalGroup` 把導航軌、內容、MiniPlayer 分組)。 +- **Detail Panel 的存在條件**:是否在所有頁面常駐,或只在與播放相關的頁面出現。 +- **桌面 compact 的 MiniPlayer**:窄視窗時要收哪些控制鈕。 +- **開發資料隔離**:Windows debug / profile build 是否改用獨立資料目錄,避免開發與審計動到使用者真實資料。 +- **大斷點**:`large` / `extraLarge` 要做專屬版面,還是把註解改成現況。 From 5bd916b583040d170ce2b4ca02846890518c96b9 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:26:08 +0800 Subject: [PATCH 003/133] docs(audit): correct the remote-removal wording for imported playlists --- docs/audit/README.md | 2 +- docs/audit/features.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/audit/README.md b/docs/audit/README.md index 452b7b097..c03dabfc3 100644 --- a/docs/audit/README.md +++ b/docs/audit/README.md @@ -51,7 +51,7 @@ **帳號與隱私。** UI 的登入狀態讀 Isar,實際送請求只看 secure storage;「重設所有資料」不清憑證,重設後 UI 顯示未登入但請求仍帶舊 cookie(已由程式碼確認)。log 遮蔽不涵蓋 CDN 簽名參數與 stackTrace。v3→v4 migration 把使用者自己關掉的 B 站「用登入狀態播放」強制打開。YouTube/網易的首頁排行永遠不帶登入(`accounts-network.md`)。 -**你很可能不知道的。** 在本機刪「匯入的平台歌單」裡的曲目,會同步在 B 站/YouTube/網易雲上刪;每次啟動可能自動換 B 站 cookie;網易雲寫入請求帶偽造的 `X-Real-IP`;AI 歌詞匹配(預設關)會把影片描述與歌詞預覽連同 API key 送到自訂端點、不強制 https;Windows 更新會靜默執行下載的安裝程式或用隱藏的 bat 覆蓋程式目錄,SHA-256 只在 release 附了 checksum 檔時才驗;每 15 秒解析三個公共 DNS 名稱(`features.md` §15)。 +**你很可能不知道的。** 匯入歌單的曲目選單有一個明確標示的「從遠程播放列表移除」,會真的刪平台上的曲目(本地沒有單純的刪除);「加入遠端」會在平台上建歌單、加曲目;每次啟動可能自動換 B 站 cookie;網易雲寫入請求帶偽造的 `X-Real-IP`;AI 歌詞匹配(預設關)會把影片描述與歌詞預覽連同 API key 送到自訂端點、不強制 https;Windows 更新會靜默執行下載的安裝程式或用隱藏的 bat 覆蓋程式目錄,SHA-256 只在 release 附了 checksum 檔時才驗;每 15 秒解析三個公共 DNS 名稱(`features.md` §15)。 **平台。** 88 處平台判斷、三種寫法並存。macOS/Linux 會出現半套桌面 UI、沒有標題列、推測無法播放;iOS 程式碼最接近能跑但缺背景播放與 ATS 設定。Linux 缺 just_audio/audio_service/flutter_inappwebview 實作;`media_kit_libs_windows_audio` 在 pub.dev 已 unlisted(`platforms.md`)。 diff --git a/docs/audit/features.md b/docs/audit/features.md index 24ac74e3e..a2b9b2628 100644 --- a/docs/audit/features.md +++ b/docs/audit/features.md @@ -394,14 +394,14 @@ flowchart LR | 行為 | 什麼時候發生 | 端點 | 證據 | |---|---|---|---| | B 站:建立收藏夾 | 「加入遠端」對話框裡按新建 | `POST /x/v3/fav/folder/add` | `bilibili_favorites_service.dart:117-131`;UI `add_to_bilibili_playlist_dialog.dart:61-75` | -| B 站:影片加入/移出收藏夾 | 「加入遠端」勾選變更;**從匯入的 B 站收藏夾歌單刪曲目** | `POST /x/v3/fav/resource/deal` | `bilibili_favorites_service.dart:154-168`;`remote_playlist_sync_provider.dart:47-50` | +| B 站:影片加入/移出收藏夾 | 「加入遠端」勾選變更;在匯入的 B 站收藏夾歌單裡,對曲目按紅色的「從遠程播放列表移除」(單曲選單或多選) | `POST /x/v3/fav/resource/deal` | `bilibili_favorites_service.dart:154-168`;`remote_playlist_sync_provider.dart:47-50` | | YouTube:加入/移出播放清單 | 同上(YouTube 歌單) | `POST /youtubei/v1/browse/edit_playlist` | `lib/services/account/youtube_playlist_service.dart:88-111` | | YouTube:建立播放清單 | 對話框新建 | `POST /youtubei/v1/playlist/create` | `youtube_playlist_service.dart:218-223` | | 網易雲:建立歌單、加入/移出曲目 | 同上(網易雲歌單) | `playlist/create`、`playlist/manipulate/tracks`,經 linux API 加密轉送,並附偽造的 `X-Real-IP: 118.88.88.88` | `lib/services/account/netease_playlist_service.dart:101-106,146-188,240-253` | | **B 站 Cookie 自動刷新** | 每次啟動(已登入時);伺服器回報需要刷新才真的換 | `GET cookie/info` → `GET /correspond/1/...` → `POST cookie/refresh` → `POST confirm/refresh`(舊 refresh_token 作廢) | `account_provider.dart:131-152`;`bilibili_account_service.dart:350-444` | | 播放紀錄上報、心跳、按讚、投幣、點擊統計 | **查不到**。grep `heartbeat\|history/report\|scrobble\|click-interface\|/like\|thumbup\|coin` 在 `lib/data/sources`、`lib/services/account`、`lib/services/library` 只命中讀取用的 `coin` 統計欄位(`lib/data/sources/bilibili_source.dart:792`) | — | — | -移除匯入歌單的曲目時會先跳確認框(`t.remote.confirmRemove`,`playlist_detail_page.dart:565-573`),但「在本機歌單刪曲目=在平台刪曲目」這件事只在確認框文案裡說。 +(核查更正:原寫「在本機歌單刪曲目=在平台刪曲目,只在確認框文案裡說」,措辭誤導。)實際行為:匯入歌單**沒有**本地「從歌單移除」,選單只提供明確標示的紅色「從遠程播放列表移除」(`playlist_detail_page.dart:210-212,1502-1515`);按下後確認框寫「確定要從遠程播放列表中移除嗎?同時會從本地歌單中移除」,先寫遠端、成功後才刪本地,再從遠端刷新(`remote_playlist_edit_controller.dart:61-135`)。匯入歌單也不會出現在「加入歌單」對話框(`add_to_playlist_dialog.dart:100,254`);本地只能改名稱、描述、封面與自動刷新設定(`create_playlist_dialog.dart:120-124,454-458`)。刷新以遠端為準、整批取代曲目(`import_service.dart:498-506`)。 ### 15.2 會把資料送到第三方的(非三個主音源) From ea8cb3483f67a05e7f4d9ff0706b1be3219dc241 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:31:33 +0800 Subject: [PATCH 004/133] docs(audit): record owner decisions and draft the phase-two order --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 209 ++++++++ docs/audit/questions.md | 450 ++++++++++-------- 2 files changed, 453 insertions(+), 206 deletions(-) create mode 100644 .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md new file mode 100644 index 000000000..8fac36c3e --- /dev/null +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -0,0 +1,209 @@ +# 階段二計畫:設計項目的依賴關係與順序 + +> 草案,等你確認順序後才開始逐項 brainstorm。每一項展開時都會先研究(官方文檔、其他播放器的做法), +> 本文的「初步傾向」只是起點,不是結論。 + +依據:parent `prd.md` 階段二第 1–18 項、`docs/audit/questions.md` 的勾選(2026-09-27)。 + +## 1. 設計項目 + +prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項(19、20)。 +第 8 項擴大為「測試、閘門與開發環境」,因為 U9(開發版資料隔離)與「單一實例妨礙實機測試」屬於同一件事。 + +| # | 項目 | 主要回答的 questions.md 項 | +|---|---|---| +| 1 | 音源插件化(含能力宣告、僅元資料/歌詞源分類、匹配流程) | G3、E5、B3、B11、B14 | +| 2 | 統一錯誤模型(含重試、退避、限流責任歸屬) | G4、G5、C5、C6、D5、D10 | +| 3 | 統一 Toast 與錯誤歷史 | G9 | +| 4 | Debug 頁 | J2、J3、J4 | +| 5 | UI/UX 設計系統與響應式、桌面播放器版面方案 | U1–U8、E20 | +| 6 | 資料層選型與資料相容(migration) | A2、A3、A4、B6、G6、M3、M4 | +| 7 | 重寫策略(全新 vs 逐步、里程碑、分支、舊版 hotfix) | N1 hotfix 已選「重寫時處理」 | +| 8 | 測試、閘門與開發環境 | §10 全部、U9、E18 的開發測試問題 | +| 9 | 文檔結構與 ADR/CONTEXT.md 去留 | §14、§15 | +| 10 | 平台策略與平台層 | A1、§8 全部、C7 | +| 11 | 下載與權限 | N1–N11、B13 | +| 12 | 網路層與帳號認證 | M1–M13、C1–C4、B4 | +| 13 | 播放核心 | A5、D1–D10、E13、E12、E19 | +| 14 | 音樂庫與同步 | B1、B2(已定)、B12、E4、E7 | +| 15 | 歌詞 | B5、E9–E11 | +| 16 | 背景任務 | B10、B12 | +| 17 | 快取與離線 | B6 | +| 18 | 設定與日誌基礎設施 | C2、J3 | +| 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡等新功能 | + +## 2. 依賴關係 + +箭頭 A → B 表示「B 的設計要用到 A 的結論」。 + +```mermaid +flowchart LR + D9[9 文檔結構/ADR]:::meta + D7[7 重寫策略(高層)]:::meta + D10[10 平台層] + D6[6 資料層與相容] + D18[18 設定與日誌] + D12[12 網路與帳號] + D2[2 錯誤模型] + D1[1 音源插件] + D8[8 測試與開發環境] + D17[17 快取與離線] + D16[16 背景任務] + D13[13 播放核心] + D14[14 音樂庫與同步] + D11[11 下載與權限] + D15[15 歌詞] + D3[3 Toast] + D5[5 UI/UX] + D4[4 Debug 頁] + D19[19 發版與更新] + D7F[7 重寫策略(里程碑定稿)]:::meta + + D9 --> D7 + D7 --> D10 + D10 --> D6 + D6 --> D18 + D10 --> D18 + D18 --> D12 + D12 --> D2 + D2 --> D1 + D12 --> D1 + D10 --> D1 + D1 --> D8 + D6 --> D17 + D1 --> D17 + D10 --> D16 + D18 --> D16 + D1 --> D13 + D2 --> D13 + D17 --> D13 + D10 --> D13 + D6 --> D14 + D1 --> D14 + D12 --> D14 + D16 --> D14 + D1 --> D11 + D10 --> D11 + D13 --> D11 + D1 --> D15 + D13 --> D15 + D2 --> D3 + D18 --> D3 + D3 --> D5 + D13 --> D5 + D18 --> D4 + D3 --> D4 + D8 --> D4 + D10 --> D19 + D16 --> D19 + D5 --> D7F + D4 --> D7F + D19 --> D7F + D11 --> D7F + D14 --> D7F + D15 --> D7F + classDef meta fill:#eee,stroke:#999 +``` + +## 3. 建議順序 + +| 順序 | 項目 | 為什麼排這裡 | +|---|---|---| +| 1 | 9 文檔結構/ADR 去留 | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | +| 2 | 7 重寫策略(高層) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | +| 3 | 10 平台層 | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | +| 4 | 6 資料層與相容 | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | +| 5 | 18 設定與日誌 | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | +| 6 | 12 網路與帳號 | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | +| 7 | 2 錯誤模型 | 音源插件介面的回傳與例外型別要先定。 | +| 8 | 1 音源插件 | 核心抽象;依賴 10、12、2。 | +| 9 | 8 測試與開發環境 | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | +| 10 | 17 快取與離線 | 串流 URL、圖片、排行快取的策略,播放核心要用。 | +| 11 | 16 背景任務 | 刷新、清理、更新檢查誰來排程。 | +| 12 | 13 播放核心 | 最大的一塊;依賴 1、2、10、17。 | +| 13 | 14 音樂庫與同步 | B1/B2 已定方向,細節依賴 6、1、12、16。 | +| 14 | 11 下載與權限 | 依賴播放核心的本地播放路徑。 | +| 15 | 15 歌詞 | 依賴 1、13。 | +| 16 | 19 發版與更新 | 依賴 10、16;你已給出流程要求。 | +| 17 | 3 Toast | 依賴 2、18。 | +| 18 | 5 UI/UX | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | +| 19 | 4 Debug 頁 | 把 18、3、8 的成果收成正式工具。 | +| 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | + +## 4. 你在 questions.md 直接問的問題 + +**Mix 模式「無法播放的歌不自動跳過」是什麼?** +一般佇列裡某首歌被下架或不可用時,程式會提示並自動跳下一首;但這個判斷寫死只在「普通佇列」模式生效 +(`lib/services/audio/audio_provider.dart:1955` 的 `mode == PlayMode.queue`),Mix 模式遇到同樣情況會停下並報錯。 +你沒遇到過,是因為要剛好在 Mix 裡碰到不可用的影片。傾向:新設計裡兩種模式同樣處理。 + +**iOS 能不能用 GitHub 發佈?** +可以放 IPA 檔在 GitHub Release,但 iOS 不能像 Android 那樣直接安裝:一定要簽名。常見途徑是 +AltStore/SideStore 這類側載工具(免費 Apple ID 簽的 App 需要定期重簽),或付費開發者帳號走 TestFlight/App Store +(後者有下載功能與非官方 API 的審核風險)。以上是一般做法,細節(期限、數量上限、歐盟替代商店)在第 10、19 項查官方來源確認。 +傾向:iOS 暫定「GitHub 放未簽名 IPA+側載」,等你有 iPhone 再決定。 + +**單一實例會不會妨礙開發時實機測試?** +會,現在開發版和正式版搶同一個 mutex 與同一份資料。傾向:開發版用不同的實例名稱與獨立資料目錄(U9 你已勾選), +兩者可以同時開,也不會再動到你的真實資料。放在第 8 項。 + +**均衡器、響度平衡做得到嗎?** +桌面(media_kit/libmpv)大致可以:media_kit 能在執行期設定 mpv 屬性(context7 查到 `Player.setProperty`), +mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio)的支援範圍這次文檔沒查清楚,放在第 13 項確認。 +不過這兩個是**新功能**,依「功能凍結」先記進第 20 項待辦,重寫完成後再做;第 13 項設計播放核心時會預留接口的可行性判斷。 + +**static-rule 是什麼、有沒有用?** +是一種「讀原始碼文字、用正則檢查」的測試,例如「`isar.` 只能出現在 repository 資料夾」「`audio_provider.dart` 不得超過 N 行」。 +它守的是程式碼寫法,不是 App 行為。優點是便宜;缺點是只比對字串,容易漏(例如音源分支預算寫 9 處,實際有 50 處)或誤報。 +傾向:重寫後大部分改用 Dart analyzer 的 lint 或 import 規則(更準),只保留少數無法用 lint 表達的,放在第 8 項。 + +**測試要不要打真實 API?** +傾向和你的想法一致:預設測試零聯網(用錄下來的真實回應當 fixture);真實 API 的檢查放在 Debug 頁的「音源健康檢查」 +與一組需明確指定才跑的冒煙測試,不進 CI(CI 機房 IP 容易被擋,而且很多功能要登入)。保留的測試只守「契約與行為」, +不守實作細節。放在第 8 項。 + +**應用內更新流程**(你已給出要求,第 19 項照此設計): +不在啟動或定時檢查,只有手動檢查;檢查到後由你點「下載」;下載完成後可選「安裝」或「刪除」;點安裝才安裝; +重啟後清除舊安裝包。Release 維持自動發布,發佈說明由 CHANGELOG(或 commit 訊息)自動產生,不手寫。 + +## 5. 各「不確定」項的初步傾向 + +展開到該項時會先研究再給正式方案;這裡讓你先看方向。 + +| 項 | 初步傾向 | 在哪一項定案 | +|---|---|---| +| A2 資料層 | 傾向換到 SQLite 系(例如 drift):資料本來就是關聯式、靠手動 id 維護;5 平台成熟;migration 可測。舊 Isar 只留在一次性遷移模組裡讀舊資料 | 6 | +| A3 資料相容 | 你選「全部自動遷移」:首次啟動讀舊 Isar、舊 secure storage、掃描舊下載目錄,轉進新格式;舊備份檔可匯入 | 6 | +| A4 資料位置 | 安裝版放系統的 App 資料目錄(Windows 是 AppData);免安裝(Portable)版放程式旁邊的資料夾——你說得對;第一版不提供自訂位置;舊 `Documents\FMP` 自動搬 | 6、10 | +| A5 音訊後端 | 維持「一個播放介面、每平台一個實作」的形狀;至於 Android 用 just_audio 還是全平台統一 media_kit,要看背景播放、均衡器、Linux 支援再比較 | 13 | +| A6 iOS | 見 §4 | 10、19 | +| B3 網易 `X-Real-IP` | 推測是為了繞過地區限制;先實測拿掉會不會壞,需要就保留但寫明在網易音源裡、附理由 | 1 | +| B4 B 站自動換 cookie | 保留(B 站要求定期刷新才能維持登入),但在帳號頁顯示最後刷新時間與結果 | 12 | +| B5 AI 歌詞 | 保留、預設關;強制 https;payload 不寫進 log;送出的欄位最小化並在設定頁列出 | 15 | +| B6 串流 URL 存 DB | 不存進資料庫,只放短期快取 | 17 | +| B7–B9 更新 | 依你的流程;安裝檔一律驗 SHA-256;免安裝版的自我覆蓋改成更穩的做法 | 19 | +| B10 每 15 秒 DNS 偵測 | 拿掉,改用系統的網路狀態 API 加「請求失敗才判定離線」 | 16 | +| B11 B 站 buvid | 保留(匿名請求需要,否則容易被風控),收在 B 站音源內 | 1 | +| B12 停用音源仍抓排行 | 停用就不抓 | 16 | +| B13 下載附帶檔案 | 保留,另外把資訊寫進音檔內嵌標籤(N6) | 11 | +| B14 YouTube 取帳號名 | 保留,收在 YouTube 音源的登入流程裡 | 1、12 | +| C1–C7 | 全部在重寫時修正(你已勾) | 12、18 | +| M 全部 | 依你的方向:登入由音源插件提供、介面自適應;「用登入狀態」開關對每個音源語意一致、涵蓋排行等所有讀取請求(可能改名);憑證只有一份來源;migration 不得改使用者設定值;讀不到憑證時不刪;依登入狀態選音質由音源決定 | 12、1 | +| N2–N11 | 改用成熟套件(權限、背景下載);Android 下載路徑可改並可重新授權;續傳驗證 If-Range/ETag;下載專用音質;副檔名照實際格式;失敗任務保留到使用者清除;權限統一入口 | 11 | +| D3 Mix 不跳過 | 與佇列一致,自動跳過 | 13 | +| D4 網易試聽片段 | 標示「試聽」並依設定跳過,不當完整歌曲播 | 1、13 | +| D5 限流 | 網路層統一做指數退避加隨機抖動、每音源限速;播放時多次失敗才跳過並提示 | 2 | +| D6 播放紀錄 | 維持(你說這是你要的) | 13 | +| D8 電台打斷音樂載入 | 開電台時取消正在載入的音樂 | 13 | +| D9 YouTube URL 期限 | 讀網址裡的 `expire`,不寫死 1 小時 | 1、17 | +| D10 電台錯誤顯示成未開播 | 區分「未開播」與「查詢失敗」 | 2、13 | +| E6 帳號登入 | 你沒勾,暫當「保留」,請確認 | — | +| E18 托盤/快捷鍵等 | 保留,擴到所有桌面平台 | 10 | +| E19 均衡器、響度 | 新功能,記進待辦 | 20 | +| E20 使用者指南頁 | 傾向刪除,改成 README/docs 裡的說明連結;你也可以選優化 | 5 | +| §8 平台功能 | 以「各平台體驗一致」為目標:托盤、快捷鍵、開機自啟、歌詞視窗、標題列、單一實例開到所有桌面平台;系統媒體控制全平台;應用內更新 iOS 除外;登入 WebView 不可用的平台改 QR 或貼 cookie;CJK 字型依平台 fallback,Linux 視情況內建 | 10 | +| §10 測試 | 見 §4 | 8 | +| J2–J4 | Debug 頁重做成正式工具;log 寫檔保留並加輪替與保留期限;資料檢查/修復收進 Debug 頁 | 4、18 | +| §14 ADR | 0001 字串音源 id:確認;每源設定清單:由新設計取代。0002、0007:看 A2,換庫就「不再適用」。0003、0004:在 13、11 重新決定。0005 分 P 以 cid 區分:確認(也是舊資料遷移要用的格式)。0006 自動發布:確認,並補上 CHANGELOG 產生說明 | 9 | +| §15 CONTEXT.md | 5 個術語的內容(憑證只在解析串流時用、媒體請求不帶憑證)是對的原則,併進第 12 項的網路規範;術語本身隨新設計改名,CONTEXT.md 在階段三刪除 | 9、12 | diff --git a/docs/audit/questions.md b/docs/audit/questions.md index 3b646c01b..d6a1157f8 100644 --- a/docs/audit/questions.md +++ b/docs/audit/questions.md @@ -25,13 +25,15 @@ - ADR 0003 與 `pubspec.yaml:24` 說「不出 Linux/macOS」,`platform_utils.dart`、`audio_controller_provider.dart:23-25` 的註解讀起來像有支援:**不一致**。 - 影響:平台層抽象要不要一開始就按 5 平台設計;要不要刪掉現在的殘留分支。 -| 平台 | 目標(重寫第一版就要) | 目標(之後加入) | 不支援 | 不確定 | -|---|---|---|---|---| -| Android | [ ] | [ ] | [ ] | [ ] | -| Windows | [ ] | [ ] | [ ] | [ ] | -| Linux | [ ] | [ ] | [ ] | [ ] | -| macOS | [ ] | [ ] | [ ] | [ ] | -| iOS | [ ] | [ ] | [ ] | [ ] | + +| 平台 | 目標(重寫第一版就要) | 目標(之後加入) | 不支援 | 不確定 | +| ------- | ----------- | -------- | ----- | ----- | +| Android | \[x\] | \[ \] | \[ \] | \[ \] | +| Windows | \[x\] | \[ \] | \[ \] | \[ \] | +| Linux | \[ \] | \[x\] | \[ \] | \[ \] | +| macOS | \[ \] | \[x\] | \[ \] | \[ \] | +| iOS | \[ \] | \[x\] | \[ \] | \[ \] | + 備註: @@ -46,54 +48,60 @@ - **全平台**:fork 宣稱 5 平台都支援,但長期維護依賴一個社群 fork。 - **重寫順序**:換庫的話,資料層要在最前面的里程碑;不換的話可以延後或只清理邊界。 -- [ ] 保留 isar_community(v3 格式) +- [ ] 保留 isar\_community(v3 格式) - [ ] 更換(階段二比較 drift/sqlite 系列、ObjectBox 等,並給遷移方案) -- [ ] 不確定 +- [x] 不確定 -備註: +備註:你建議怎樣做 ### A3. 資料相容:重寫版本要不要讀得懂舊資料 -| 資料 | 現況位置 | 保留並自動遷移 | 只支援經備份檔匯入 | 不保留 | 不確定 | -|---|---|---|---|---|---| -| 資料庫(歌單、曲目、歷史、設定、佇列) | Windows:`文件\FMP\fmp_database.isar`;Android:app 私有目錄(`data.md` §1) | [ ] | [ ] | [ ] | [ ] | -| 登入憑證(secure storage) | `flutter_secure_storage`(`data.md` §3、`accounts-network.md` §1) | [ ] | — | [ ] | [ ] | -| 已下載的音檔與 sidecar | Android `Music/FMP`、Windows `文件\FMP`(`data.md` §5) | [ ] | — | [ ] | [ ] | -| 備份檔(JSON 格式) | `data.md` §6 | [ ] 新版能匯入舊備份 | — | [ ] | [ ] | + +| 資料 | 現況位置 | 保留並自動遷移 | 只支援經備份檔匯入 | 不保留 | 不確定 | +| -------------------- | ----------------------------------------------------------------- | -------------- | --------- | ----- | ----- | +| 資料庫(歌單、曲目、歷史、設定、佇列) | Windows:`文件\FMP\fmp_database.isar`;Android:app 私有目錄(`data.md` §1) | \[x\] | \[ \] | \[ \] | \[ \] | +| 登入憑證(secure storage) | `flutter_secure_storage`(`data.md` §3、`accounts-network.md` §1) | \[x\] | — | \[ \] | \[ \] | +| 已下載的音檔與 sidecar | Android `Music/FMP`、Windows `文件\FMP`(`data.md` §5) | \[x\] | — | \[ \] | \[ \] | +| 備份檔(JSON 格式) | `data.md` §6 | \[x\] 新版能匯入舊備份 | — | \[ \] | \[ \] | + 備註: ### A4. 資料與 log 放在 Windows「文件」資料夾 - 現況:資料庫與 log 在 `Documents\FMP`(`database_provider.dart:50-53`、`log_file_sink.dart:24-28`),可能被 OneDrive 同步;資料庫內有含簽名的串流 URL(見 B6)。 -- [ ] 保留 - [ ] 修改:移到 AppData(需遷移) - [ ] 不確定 -備註: +- [ ] 保留 - \[ \] 修改:移到 AppData(需遷移) - \[x\] 不確定 + +備註:你建議怎樣做,我認為當前似乎也沒有什麼問題,不過用戶可能會想要手動更改?然後Portable版是不是應該將數據儲存到自己的文件夾中才對? ### A5. 音訊後端:兩套(ADR 0003) -- 現況:Android(與 iOS)用 just_audio→ExoPlayer,其他用 media_kit→libmpv;`media_kit_libs_windows_audio` 在 pub.dev 已 unlisted、最後發佈 2023-09(`platforms.md` §4)。兩個後端共用一批純規則,並有契約測試(`engineering.md` §10 ADR 0003:一致)。 +- 現況:Android(與 iOS)用 just\_audio→ExoPlayer,其他用 media\_kit→libmpv;`media_kit_libs_windows_audio` 在 pub.dev 已 unlisted、最後發佈 2023-09(`platforms.md` §4)。兩個後端共用一批純規則,並有契約測試(`engineering.md` §10 ADR 0003:一致)。 - 影響:全平台時 macOS/Linux 要 libmpv 來源,iOS/macOS 帶 headers 需要 ATS 設定。 -- [ ] 維持兩套 - [ ] 研究統一成一套 - [ ] 不確定 -備註: +- [ ] 維持兩套 - \[ \] 研究統一成一套 - \[x\] 不確定 + +備註:你認為怎樣做比較好? ### A6. 發佈管道 - 現況:只有 GitHub Release;tag push 後自動驗證、建置、直接發布,沒有人工閘門,Windows 產物沒有 code signing,SHA-256 檔與產物放在同一個 Release(`engineering.md` §1、ADR 0006)。ADR 0004 寫「擁有者決定永遠不上架任何商店」。 - 平台政策(`platforms.md` §6):App Store 5.2.3 禁止未授權從 YouTube 等來源下載媒體;2.5.2 禁止 iOS app 自行下載可執行碼;Mac App Store 2.4.5 禁止自有更新機制。 -| 平台 | GitHub Release | 商店 | sideload/自簽(AltStore、TestFlight 等) | 套件庫(Flathub、AUR、winget 等) | 不發佈 | 不確定 | -|---|---|---|---|---|---|---| -| Android | [ ] | [ ] | — | [ ] F-Droid 類 | [ ] | [ ] | -| Windows | [ ] | [ ] | — | [ ] | [ ] | [ ] | -| Linux | [ ] | — | — | [ ] | [ ] | [ ] | -| macOS | [ ] | [ ] | [ ] 未公證 dmg | [ ] Homebrew | [ ] | [ ] | -| iOS | — | [ ] | [ ] | — | [ ] | [ ] | -另外:Release 要不要回到「草稿 → 你手動發布」(推翻 ADR 0006)? [ ] 維持自動發布 [ ] 改回人工發布 [ ] 不確定 +| 平台 | GitHub Release | 商店 | sideload/自簽(AltStore、TestFlight 等) | 套件庫(Flathub、AUR、winget 等) | 不發佈 | 不確定 | +| ------- | -------------- | ----- | ---------------------------------- | ------------------------- | ----- | ----- | +| Android | \[x\] | \[ \] | — | \[ \] F-Droid 類 | \[ \] | \[ \] | +| Windows | \[x\] | \[ \] | — | \[ \] | \[ \] | \[ \] | +| Linux | \[x\] | — | — | \[ \] | \[ \] | \[ \] | +| macOS | \[x\] | \[ \] | \[ \] 未公證 dmg | \[ \] Homebrew | \[ \] | \[ \] | +| iOS | — | \[ \] | \[ \] | — | \[ \] | \[x\] | -備註: + +另外:Release 要不要回到「草稿 → 你手動發布」(推翻 ADR 0006)? [x] 維持自動發布 [ ] 改回人工發布 [ ] 不確定 + +備註:iOS不能夠GitHub發佈嗎,Release不太想要手動發佈,會可能想要根據commit信息或是維護一個CHANGELOG文檔,根據CHANGELOG文檔來生成信息,不要手動發佈或是手動設置文案。 --- @@ -101,40 +109,44 @@ 細節與證據在 `features.md` §15、`accounts-network.md` §4。 -| # | 功能 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---|---| -| B1 | 在本機刪「匯入的平台歌單」裡的曲目=在 B 站/YouTube/網易雲上刪 | 只靠確認框文案說明 | `playlist_detail_page.dart:565-610,1575-1610`;`remote_playlist_sync_provider.dart:47-50` | [ ] | [ ] | [ ] | [ ] | -| B2 | 「加入遠端」:在三個平台建歌單、加曲目 | 對話框操作 | `bilibili_favorites_service.dart:117-168`;`youtube_playlist_service.dart:88-111,218-223`;`netease_playlist_service.dart:101-188` | [ ] | [ ] | [ ] | [ ] | -| B3 | 網易雲寫入請求附偽造 `X-Real-IP: 118.88.88.88` | 固定送出 | `netease_playlist_service.dart:240-253` | [ ] | [ ] | [ ] | [ ] | -| B4 | 啟動時自動換 B 站 Cookie(伺服器要求時,舊 refresh_token 作廢) | 每次啟動檢查 | `account_provider.dart:131-152`;`bilibili_account_service.dart:350-444` | [ ] | [ ] | [ ] 改手動 | [ ] | -| B5 | AI 歌詞匹配:把標題、上傳者、**影片描述**、**歌詞預覽**連同 API key 送到自訂端點;端點不強制 https;debug 級別時整份 payload 寫進 log | 預設關閉 | `openai_chat_client.dart:41-67`;`ai_lyrics_selector.dart:106-137`;`openai_chat_endpoint.dart:1-6` | [ ] | [ ] | [ ] | [ ] | -| B6 | 含簽名的 CDN 串流 URL 明文存進資料庫(`Track.audioUrl`) | 每首一筆 | `stream_resolution_service.dart:427-471` | [ ] | [ ] 只放記憶體 | [ ] | [ ] | -| B7 | Windows 自動更新:安裝版以 `/SILENT` 靜默跑下載的安裝程式;免安裝版寫 bat+vbs 用 `wscript` 隱藏執行、`robocopy` 覆蓋程式目錄 | 使用者按「更新」後 | `update_service.dart:587-684,830-876` | [ ] | [ ] | [ ] | [ ] | -| B8 | 更新檔 SHA-256:只有 release 附 checksum 檔才驗,否則只比大小 | — | `update_service.dart:462-470,776-783` | [ ] | — | [ ] 強制驗 | [ ] | -| B9 | Android 自動更新:下載 APK 開系統安裝器 | 使用者按「更新」後 | `update_service.dart:540-565` | [ ] | [ ] | [ ] | [ ] | -| B10 | 每 15 秒解析 `dns.google`、`one.one.one.one`、`dns.alidns.com` 偵測連線 | 常駐 | `connectivity_service.dart:52-56,102-116` | [ ] | [ ] | [ ] | [ ] | -| B11 | B 站匿名請求自產 `buvid3`/`buvid4`/`b_nut` 瀏覽器指紋 cookie | 常駐 | `bilibili_source.dart:92-146` | [ ] | [ ] | [ ] | [ ] | -| B12 | 首頁排行:停用某音源只影響顯示,背景仍每小時抓所有音源 | 常駐 | `ranking_cache_service.dart:233-245`;`home_ranking_settings_provider.dart:193-195` | [ ] | [ ] | [ ] 停用即不抓 | [ ] | -| B13 | 下載時附帶寫 metadata JSON、下載封面與 UP 主頭像 | 每次下載 | `download_service.dart:1509-1590` | [ ] | [ ] | [ ] | [ ] | -| B14 | YouTube 登入頁注入 JS 呼叫 `accounts_list` 取帳號名 | 登入時 | `youtube_login_page.dart:238-260` | [ ] | [ ] | [ ] | [ ] | -備註: +| # | 功能 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +| --- | ----------------------------------------------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------- | ----- | ----------- | ----------- | ----- | +| B1 | 匯入歌單的曲目選單有紅色「從遠程播放列表移除」:先刪平台上的,成功後刪本地(核查更正:原寫「在本機刪=在平台刪」,措辭誤導,見 `features.md` §15.1) | 只靠確認框文案說明 | `playlist_detail_page.dart:565-610,1575-1610`;`remote_playlist_sync_provider.dart:47-50` | \[x\] | \[ \] | \[ \] | \[ \] | +| B2 | 「加入遠端」:在三個平台建歌單、加曲目 | 對話框操作 | `bilibili_favorites_service.dart:117-168`;`youtube_playlist_service.dart:88-111,218-223`;`netease_playlist_service.dart:101-188` | \[x\] | \[ \] | \[ \] | \[ \] | +| B3 | 網易雲寫入請求附偽造 `X-Real-IP: 118.88.88.88` | 固定送出 | `netease_playlist_service.dart:240-253` | \[ \] | \[ \] | \[ \] | \[x\] | +| B4 | 啟動時自動換 B 站 Cookie(伺服器要求時,舊 refresh\_token 作廢) | 每次啟動檢查 | `account_provider.dart:131-152`;`bilibili_account_service.dart:350-444` | \[ \] | \[ \] | \[ \] 改手動 | \[x\] | +| B5 | AI 歌詞匹配:把標題、上傳者、**影片描述**、**歌詞預覽**連同 API key 送到自訂端點;端點不強制 https;debug 級別時整份 payload 寫進 log | 預設關閉 | `openai_chat_client.dart:41-67`;`ai_lyrics_selector.dart:106-137`;`openai_chat_endpoint.dart:1-6` | \[ \] | \[ \] | \[ \] | \[x\] | +| B6 | 含簽名的 CDN 串流 URL 明文存進資料庫(`Track.audioUrl`) | 每首一筆 | `stream_resolution_service.dart:427-471` | \[ \] | \[ \] 只放記憶體 | \[ \] | \[x\] | +| B7 | Windows 自動更新:安裝版以 `/SILENT` 靜默跑下載的安裝程式;免安裝版寫 bat+vbs 用 `wscript` 隱藏執行、`robocopy` 覆蓋程式目錄 | 使用者按「更新」後 | `update_service.dart:587-684,830-876` | \[ \] | \[ \] | \[ \] | \[x\] | +| B8 | 更新檔 SHA-256:只有 release 附 checksum 檔才驗,否則只比大小 | — | `update_service.dart:462-470,776-783` | \[ \] | — | \[ \] 強制驗 | \[x\] | +| B9 | Android 自動更新:下載 APK 開系統安裝器 | 使用者按「更新」後 | `update_service.dart:540-565` | \[ \] | \[ \] | \[ \] | \[x\] | +| B10 | 每 15 秒解析 `dns.google`、`one.one.one.one`、`dns.alidns.com` 偵測連線 | 常駐 | `connectivity_service.dart:52-56,102-116` | \[ \] | \[ \] | \[ \] | \[x\] | +| B11 | B 站匿名請求自產 `buvid3`/`buvid4`/`b_nut` 瀏覽器指紋 cookie | 常駐 | `bilibili_source.dart:92-146` | \[ \] | \[ \] | \[ \] | \[x\] | +| B12 | 首頁排行:停用某音源只影響顯示,背景仍每小時抓所有音源 | 常駐 | `ranking_cache_service.dart:233-245`;`home_ranking_settings_provider.dart:193-195` | \[ \] | \[ \] | \[ \] 停用即不抓 | \[x\] | +| B13 | 下載時附帶寫 metadata JSON、下載封面與 UP 主頭像 | 每次下載 | `download_service.dart:1509-1590` | \[ \] | \[ \] | \[ \] | \[x\] | +| B14 | YouTube 登入頁注入 JS 呼叫 `accounts_list` 取帳號名 | 登入時 | `youtube_login_page.dart:238-260` | \[ \] | \[ \] | \[ \] | \[x\] | + + +備註:B1、B2(2026-09-27 對話確認):遠端歌單是權威,同步只從遠端往下;使用者不能在本地增刪匯入歌單的曲目。保留 App 內明確標示的遠端操作(「從遠程播放列表移除」「加入遠端歌單」)作為修改遠端的手動途徑,改完再同步下來。匯入歌單的名稱、描述、封面與自動刷新設定可以在本地改。我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。關於更新的話,我不會希望在啓動時或定時的更新檢查和提示,應該只讓用戶手動檢查更新,然後用戶檢查更新後可以點擊下載,下載完成後可以點擊安裝或是刪除,點擊安裝才進行安裝。重啓後的話可能也要清除舊的安裝包。 --- ## 3. 安全與隱私缺陷(C 項;這些是「現況的錯」,不是功能去留) -| # | 問題 | 證據 | 重寫時修正 | 維持現狀 | 不確定 | -|---|---|---|---|---|---| -| C1 | 「重設所有資料」只清 Isar,不清 secure storage;重設後 UI 顯示未登入,但播放、詳情、排行榜仍帶舊 cookie(已由程式碼確認) | `data_integrity_repository.dart:55-56`;`data.md` §3 | [ ] | [ ] | [ ] | -| C2 | log 遮蔽不涵蓋 CDN 簽名參數:`media_kit` 與 just_audio 的錯誤原文未過 `redactStreamUrl`;stackTrace 不遮就寫進檔案與匯出;release 版 `debugPrint` 仍輸出到 logcat | `logger.dart:52-63,81-200,283-290`;`media_kit_audio_service.dart:379`;`just_audio_service.dart:301-304` | [ ] | [ ] | [ ] | -| C3 | B 站 QR 登入可能「假成功」:Set-Cookie 解析不到時沒存憑證仍走 `onLoginSuccess`(已由程式碼確認) | `bilibili_account_service.dart:184-200,469-473,511-517` | [ ] | [ ] | [ ] | -| C4 | B 站 cookie 刷新後的重試帶的是舊 cookie(程式碼確認;伺服器回應未實測) | `bilibili_auth_interceptor.dart:28-33,77` | [ ] | [ ] | [ ] | -| C5 | 網易雲啟動帳號檢查:任何非 200 碼(含限流 -460)都當登入失效並清憑證 | `netease_account_service.dart:290-297,360-362` | [ ] | [ ] | [ ] | -| C6 | 播放/搜尋用的連線偵測不到登入失效;YouTube 偵測到也只寫 log | `bilibili_source.dart:96-101`;`youtube_auth_interceptor.dart:30-37` | [ ] | [ ] | [ ] | -| C7 | 公開 repo 內有逆向取得的前端金鑰(InnerTube key、網易 weapi/eapi 金鑰、QQ 簽名表) | `accounts-network.md` §5(只列位置) | [ ] 集中管理 | [ ] 維持 | [ ] | -備註: +| # | 問題 | 證據 | 重寫時修正 | 維持現狀 | 不確定 | +| --- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------- | -------- | ----- | +| C1 | 「重設所有資料」只清 Isar,不清 secure storage;重設後 UI 顯示未登入,但播放、詳情、排行榜仍帶舊 cookie(已由程式碼確認) | `data_integrity_repository.dart:55-56`;`data.md` §3 | \[x\] | \[ \] | \[ \] | +| C2 | log 遮蔽不涵蓋 CDN 簽名參數:`media_kit` 與 just\_audio 的錯誤原文未過 `redactStreamUrl`;stackTrace 不遮就寫進檔案與匯出;release 版 `debugPrint` 仍輸出到 logcat | `logger.dart:52-63,81-200,283-290`;`media_kit_audio_service.dart:379`;`just_audio_service.dart:301-304` | \[x\] | \[ \] | \[ \] | +| C3 | B 站 QR 登入可能「假成功」:Set-Cookie 解析不到時沒存憑證仍走 `onLoginSuccess`(已由程式碼確認) | `bilibili_account_service.dart:184-200,469-473,511-517` | \[x\] | \[ \] | \[ \] | +| C4 | B 站 cookie 刷新後的重試帶的是舊 cookie(程式碼確認;伺服器回應未實測) | `bilibili_auth_interceptor.dart:28-33,77` | \[x\] | \[ \] | \[ \] | +| C5 | 網易雲啟動帳號檢查:任何非 200 碼(含限流 -460)都當登入失效並清憑證 | `netease_account_service.dart:290-297,360-362` | \[x\] | \[ \] | \[ \] | +| C6 | 播放/搜尋用的連線偵測不到登入失效;YouTube 偵測到也只寫 log | `bilibili_source.dart:96-101`;`youtube_auth_interceptor.dart:30-37` | \[x\] | \[ \] | \[ \] | +| C7 | 公開 repo 內有逆向取得的前端金鑰(InnerTube key、網易 weapi/eapi 金鑰、QQ 簽名表) | `accounts-network.md` §5(只列位置) | \[x\] 集中管理 | \[ \] 維持 | \[ \] | + + +備註:我不太懂,按你建議的來,如果有錯的話最好就改了。 --- @@ -142,23 +154,25 @@ 細節在 `accounts-network.md` §6(帳號全貌)、§7(請求 × 音源憑證矩陣)、§8(登入與未登入的能力差異)。 -| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---|---| -| M1 | 「是否登入」有兩份來源:UI 讀 Isar `Account`,實際送請求只看 secure storage | 兩者可能不一致(見 §3 C1) | `accounts-network.md` §6.1 | [ ] | — | [ ] 統一以一份為準 | [ ] | -| M2 | 「用登入狀態播放」(Auth For Play)開關,每個音源一個 | 預設:B 站、網易開,YouTube 關;控制播放、詳情、下載、B 站排行 | `settings.dart:76-79,686-693`;`accounts-network.md` §7 | [ ] | [ ] 一律帶 | [ ] | [ ] | -| M3 | v3→v4 migration 把 B 站「用登入狀態播放」**無條件改成開**,使用者自己關掉的也被打開 | 已執行過的遷移 | `database_migration.dart:236-238` | [ ] | — | [ ] 改成詢問/不動使用者值 | [ ] | -| M4 | 其他改寫使用者設定值的 migration(v0→v1 無條件改寫三個版面欄位等) | — | `database_migration.dart:171-193`;`accounts-network.md` §7 | [ ] | — | [ ] | [ ] | -| M5 | YouTube 的「用登入狀態播放」只是備援:先匿名,失敗才帶登入 | — | `youtube_source.dart:247-273,346-366` | [ ] | — | [ ] 登入後先帶登入 | [ ] | -| M6 | YouTube、網易的首頁排行永遠不帶登入(開關開了也一樣);只有 B 站排行受開關影響 | — | `youtube_source.dart:1635-1638`;`netease_source.dart:355-357`;`ranking_cache_service.dart:269-275` | [ ] | — | [ ] | [ ] | -| M7 | 設定頁說明寫「播放與歌曲詳情」,實際還包括下載與 B 站排行 | **不一致** | `audioSettings.i18n.json:34` | — | — | [ ] 修文案 | [ ] | -| M8 | secure storage 暫時讀不到時,啟動檢查會當成失效並刪憑證、跳「登錄已失效」 | 推測可能刪掉仍有效的憑證 | `bilibili_account_service.dart:470-473`;`account_provider.dart:233-236` | [ ] | — | [ ] | [ ] | -| M9 | 登入失效提示每次 App 執行每個平台只跳一次,重新登入後再失效不再提示 | — | `session_expiry_notifier.dart:15,22-23` | [ ] | — | [ ] | [ ] | -| M10 | 播放時遇到「需要登入」的錯誤判斷存在但沒人使用,不會標記失效或引導登入 | — | `source_exception.dart:58` | [ ] | [ ] | [ ] 接上 | [ ] | -| M11 | 依登入/會員狀態選音質:B 站高解析與杜比音軌完全不讀;網易試聽片段不提示(見 D4) | — | `bilibili_source.dart:349-353`;`netease_source.dart:139-150` | [ ] | — | [ ] | [ ] | -| M12 | 歌單「使用登入狀態重新整理」會被重新匯入覆寫;帳號頁匯入的歌單一律帶登入 | — | `import_service.dart:250`;`account_playlists_sheet.dart:277` | [ ] | — | [ ] | [ ] | -| M13 | 各音源登入方式:B 站 WebView+QR;YouTube 只有 WebView;網易 Android WebView+QR、Windows 只有 QR | — | `platforms.md` §3;`accounts-network.md` §1 | [ ] | [ ] | [ ] | [ ] | -備註: +| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +| --- | ----------------------------------------------------------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------- | ----- | --------- | ----------------- | ----- | +| M1 | 「是否登入」有兩份來源:UI 讀 Isar `Account`,實際送請求只看 secure storage | 兩者可能不一致(見 §3 C1) | `accounts-network.md` §6.1 | \[ \] | — | \[ \] 統一以一份為準 | \[x\] | +| M2 | 「用登入狀態播放」(Auth For Play)開關,每個音源一個 | 預設:B 站、網易開,YouTube 關;控制播放、詳情、下載、B 站排行 | `settings.dart:76-79,686-693`;`accounts-network.md` §7 | \[ \] | \[ \] 一律帶 | \[ \] | \[x\] | +| M3 | v3→v4 migration 把 B 站「用登入狀態播放」**無條件改成開**,使用者自己關掉的也被打開 | 已執行過的遷移 | `database_migration.dart:236-238` | \[ \] | — | \[ \] 改成詢問/不動使用者值 | \[x\] | +| M4 | 其他改寫使用者設定值的 migration(v0→v1 無條件改寫三個版面欄位等) | — | `database_migration.dart:171-193`;`accounts-network.md` §7 | \[ \] | — | \[ \] | \[x\] | +| M5 | YouTube 的「用登入狀態播放」只是備援:先匿名,失敗才帶登入 | — | `youtube_source.dart:247-273,346-366` | \[ \] | — | \[ \] 登入後先帶登入 | \[x\] | +| M6 | YouTube、網易的首頁排行永遠不帶登入(開關開了也一樣);只有 B 站排行受開關影響 | — | `youtube_source.dart:1635-1638`;`netease_source.dart:355-357`;`ranking_cache_service.dart:269-275` | \[ \] | — | \[ \] | \[x\] | +| M7 | 設定頁說明寫「播放與歌曲詳情」,實際還包括下載與 B 站排行 | **不一致** | `audioSettings.i18n.json:34` | — | — | \[ \] 修文案 | \[x\] | +| M8 | secure storage 暫時讀不到時,啟動檢查會當成失效並刪憑證、跳「登錄已失效」 | 推測可能刪掉仍有效的憑證 | `bilibili_account_service.dart:470-473`;`account_provider.dart:233-236` | \[ \] | — | \[ \] | \[x\] | +| M9 | 登入失效提示每次 App 執行每個平台只跳一次,重新登入後再失效不再提示 | — | `session_expiry_notifier.dart:15,22-23` | \[ \] | — | \[ \] | \[x\] | +| M10 | 播放時遇到「需要登入」的錯誤判斷存在但沒人使用,不會標記失效或引導登入 | — | `source_exception.dart:58` | \[ \] | \[ \] | \[ \] 接上 | \[x\] | +| M11 | 依登入/會員狀態選音質:B 站高解析與杜比音軌完全不讀;網易試聽片段不提示(見 D4) | — | `bilibili_source.dart:349-353`;`netease_source.dart:139-150` | \[ \] | — | \[ \] | \[x\] | +| M12 | 歌單「使用登入狀態重新整理」會被重新匯入覆寫;帳號頁匯入的歌單一律帶登入 | — | `import_service.dart:250`;`account_playlists_sheet.dart:277` | \[ \] | — | \[ \] | \[x\] | +| M13 | 各音源登入方式:B 站 WebView+QR;YouTube 只有 WebView;網易 Android WebView+QR、Windows 只有 QR | — | `platforms.md` §3;`accounts-network.md` §1 | \[ \] | \[ \] | \[ \] | \[x\] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。我會希望各音源能夠邏輯統一,用登入狀態播放的開關對各個音源的作用都一樣,可能也包括了排行榜功能?不過這樣的話這個開關可能要改個名,或是改為新增的一個開關。登入功能的話,考慮到類似插件化,是否應該由音源提供,介面自適應? --- @@ -167,23 +181,26 @@ 細節在 `downloads.md`。 **N1 要不要在舊版先修?** 它在目前發行的版本上就可能正在刪你的曲目,而重寫期間不發正式版。 -- [ ] 審計後立刻在舊版 hotfix(需要例外發一版) - [ ] 先不修,重寫時處理 - [ ] 先備份資料庫再決定 - [ ] 不確定 - -| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---|---| -| N1 | **已確認的資料遺失路徑**:每次啟動的下載同步重建曲目的 `playlistInfo`,只保留「DB 歌單原名 == 磁碟資料夾名」的關聯;資料夾名是 `sanitizeFileName` 過的,歌單名含 `: ? / \|` 等字元、或你照改名提示搬過資料夾時就對不上而被丟掉。約 10 秒後的孤兒清理只看 `playlistInfo` 有無 `playlistId > 0`、不看 `Playlist.trackIds`,於是曲目被從資料庫刪除並從歌單消失。另外,已下載曲目若同時在另一個未下載的歌單,那個關聯每次啟動都會被丟 | 呼叫鏈完整、未實機重現(`downloads.md` §4.4) | `download_path_sync_service.dart:162-197`;`track_repository.dart:635-669`;`queue_manager.dart:226`;`app.dart:131` | [ ] | — | [ ] 以 id 比對、清理改看 `Playlist.trackIds` | [ ] | -| N2 | Android 下載路徑只在第一次下載時選,設定頁不能改;權限被撤銷後每次下載都失敗,不重新請求、不導去系統設定 | — | `settings_storage.dart:60`;`storage_permission_service.dart:69` | [ ] | — | [ ] | [ ] | -| N3 | 改下載路徑時的行為(搬檔/掃新目錄/只重設);歌單改名不會改資料夾,要使用者自己搬 | — | `download_path_maintenance_service.dart:59-80`;`playlist_service.dart:136-141,166-189` | [ ] | — | [ ] | [ ] | -| N4 | 續傳:每次繼續重新解析 URL,沒有 ETag/If-Range/大小驗證(推測可能接出損壞檔);手動重試從頭下;下載本身不自動重試 | — | `download_service.dart:685-688,1904-1906` | [ ] | [ ] 取消續傳 | [ ] 加驗證 | [ ] | -| N5 | 下載音質跟播放共用設定,沒有下載專用音質;可能拿到 muxed 串流 | — | `base_source.dart:44-50`;`settings.dart:59-63` | [ ] | — | [ ] | [ ] | -| N6 | 副檔名一律 `.m4a`(opus、flac 也一樣);metadata 只寫 sidecar JSON,不寫進音檔內嵌 tag | — | `download_path_utils.dart:40-46` | [ ] | — | [ ] | [ ] | -| N7 | 失敗任務在下次開啟下載功能時被清掉 | — | `download_repository.dart:66-96`;`download_service.dart:206-212` | [ ] | — | [ ] | [ ] | -| N8 | 下載只在 App 行程內的 isolate 跑,沒有前景服務或系統排程 | — | `downloads.md` §2 | [ ] | — | [ ] | [ ] | -| N9 | 播放時找不到本地檔就永久清掉下載路徑,不區分「儲存裝置暫時拔出」 | — | `stream_resolution_service.dart:128-136` | [ ] | — | [ ] | [ ] | -| N10 | 權限:沒宣告 `POST_NOTIFICATIONS`、沒有電池最佳化豁免;open_filex 合併進三個從不請求的 `READ_MEDIA_*`;Android 10 以下被拒時沒說明、不導去設定 | — | `downloads.md` §6;`AndroidManifest.xml` | [ ] | — | [ ] | [ ] | -| N11 | 權限請求統一入口(目前儲存權限走自有 MethodChannel,刻意不用 permission_handler) | — | `storage_permission_service.dart:22-24` | [ ] | — | [ ] 改用成熟套件 | [ ] | -備註: +- [ ] 審計後立刻在舊版 hotfix(需要例外發一版) - \[x\] 先不修,重寫時處理 - \[ \] 先備份資料庫再決定 - \[ \] 不確定 + + +| # | 項目 | 現況 | 證據 | 保留 | 刪除 | 修改 | 不確定 | +| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----- | ---------- | -------------------------------------- | ----- | +| N1 | **已確認的資料遺失路徑**:每次啟動的下載同步重建曲目的 `playlistInfo`,只保留「DB 歌單原名 == 磁碟資料夾名」的關聯;資料夾名是 `sanitizeFileName` 過的,歌單名含 `: ? / |` 等字元、或你照改名提示搬過資料夾時就對不上而被丟掉。約 10 秒後的孤兒清理只看 `playlistInfo` 有無 `playlistId > 0`、不看 `Playlist.trackIds`,於是曲目被從資料庫刪除並從歌單消失。另外,已下載曲目若同時在另一個未下載的歌單,那個關聯每次啟動都會被丟 | 呼叫鏈完整、未實機重現(`downloads.md` §4.4) | `download_path_sync_service.dart:162-197`;`track_repository.dart:635-669`;`queue_manager.dart:226`;`app.dart:131` | \[ \] | — | \[ \] 以 id 比對、清理改看 `Playlist.trackIds` | \[x\] | +| N2 | Android 下載路徑只在第一次下載時選,設定頁不能改;權限被撤銷後每次下載都失敗,不重新請求、不導去系統設定 | — | `settings_storage.dart:60`;`storage_permission_service.dart:69` | \[ \] | — | \[ \] | \[x\] | +| N3 | 改下載路徑時的行為(搬檔/掃新目錄/只重設);歌單改名不會改資料夾,要使用者自己搬 | — | `download_path_maintenance_service.dart:59-80`;`playlist_service.dart:136-141,166-189` | \[ \] | — | \[ \] | \[x\] | +| N4 | 續傳:每次繼續重新解析 URL,沒有 ETag/If-Range/大小驗證(推測可能接出損壞檔);手動重試從頭下;下載本身不自動重試 | — | `download_service.dart:685-688,1904-1906` | \[ \] | \[ \] 取消續傳 | \[ \] 加驗證 | \[x\] | +| N5 | 下載音質跟播放共用設定,沒有下載專用音質;可能拿到 muxed 串流 | — | `base_source.dart:44-50`;`settings.dart:59-63` | \[ \] | — | \[ \] | \[x\] | +| N6 | 副檔名一律 `.m4a`(opus、flac 也一樣);metadata 只寫 sidecar JSON,不寫進音檔內嵌 tag | — | `download_path_utils.dart:40-46` | \[ \] | — | \[ \] | \[x\] | +| N7 | 失敗任務在下次開啟下載功能時被清掉 | — | `download_repository.dart:66-96`;`download_service.dart:206-212` | \[ \] | — | \[ \] | \[x\] | +| N8 | 下載只在 App 行程內的 isolate 跑,沒有前景服務或系統排程 | — | `downloads.md` §2 | \[ \] | — | \[ \] | \[x\] | +| N9 | 播放時找不到本地檔就永久清掉下載路徑,不區分「儲存裝置暫時拔出」 | — | `stream_resolution_service.dart:128-136` | \[ \] | — | \[ \] | \[x\] | +| N10 | 權限:沒宣告 `POST_NOTIFICATIONS`、沒有電池最佳化豁免;open\_filex 合併進三個從不請求的 `READ_MEDIA_*`;Android 10 以下被拒時沒說明、不導去設定 | — | `downloads.md` §6;`AndroidManifest.xml` | \[ \] | — | \[ \] | \[x\] | +| N11 | 權限請求統一入口(目前儲存權限走自有 MethodChannel,刻意不用 permission\_handler) | — | `storage_permission_service.dart:22-24` | \[ \] | — | \[ \] 改用成熟套件 | \[x\] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。我可以接受改為使用成熟的套件以及大幅的修改,包括之前或是之後的B、C、M、N、D等等的項。 --- @@ -191,22 +208,24 @@ 細節在 `playback.md`。 -| # | 行為 | 現況 | 證據 | 保留 | 修改 | 不確定 | -|---|---|---|---|---|---|---| -| D1 | 點一首歌=「臨時播放」(播完回原佇列),不是加入佇列 | 搜尋、歌單、首頁、排行、歷史、已下載都走 `playTemporary` | `playback.md` §0、§1;`search_page.dart:485` | [ ] | [ ] | [ ] | -| D2 | 歌單頁「全部」按鈕只加入佇列、不播放 | 方法名叫 `_playAll` | `playlist_detail_page.dart:884-890` | [ ] | [ ] | [ ] | -| D3 | Mix 模式(YouTube 無限佇列):無法播放的歌不自動跳過、佇列無上限 | — | `audio_provider.dart:1955`;`mix_session_coordinator.dart:315` | [ ] | [ ] | [ ] | -| D4 | 網易雲試聽片段照常當完整歌曲播放,不提示;下載端也擋不到 | — | `netease_source.dart:139-150` | [ ] | [ ] 提示/跳過 | [ ] | -| D5 | 播放遇限流:只在解析層重試一次、等 3 秒,之後提示,不退避不跳過 | — | `stream_resolution_service.dart:210`;`audio_provider.dart:1984-1988` | [ ] | [ ] | [ ] | -| D6 | 播放歷史在「開流成功」時記一筆;單曲循環每圈都記 | — | `playback_side_effects.dart:166-175` | [ ] | [ ] | [ ] | -| D7 | 隨機模式下拖曳排序不更新隨機順序;「下一首播放」插到隨機位置 | — | `queue_manager.dart:541-547,594-613` | [ ] | [ ] | [ ] | -| D8 | 開電台時只暫停音樂、不取消正在載入的音樂(推測會被音樂串流蓋掉) | — | `radio_controller.dart:840-847` | [ ] | [ ] | [ ] | -| D9 | YouTube URL 有效期寫死 1 小時,不讀網址裡的 `expire` | — | `youtube_source.dart:52-54` | [ ] | [ ] | [ ] | -| D10 | 電台/直播 | 輪詢開播狀態;網路錯誤顯示成「未開播」 | `bilibili_live_client.dart:205-208`;`radio_refresh_service.dart:252-257` | [ ] | [ ] | [ ] | + +| # | 行為 | 現況 | 證據 | 保留 | 修改 | 不確定 | +| --- | -------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------ | ----- | ----------- | ----- | +| D1 | 點一首歌=「臨時播放」(播完回原佇列),不是加入佇列 | 搜尋、歌單、首頁、排行、歷史、已下載都走 `playTemporary` | `playback.md` §0、§1;`search_page.dart:485` | \[x\] | \[ \] | \[ \] | +| D2 | 歌單頁「全部」按鈕只加入佇列、不播放 | 方法名叫 `_playAll` | `playlist_detail_page.dart:884-890` | \[x\] | \[ \] | \[ \] | +| D3 | Mix 模式(YouTube 無限佇列):無法播放的歌不自動跳過、佇列無上限 | — | `audio_provider.dart:1955`;`mix_session_coordinator.dart:315` | \[ \] | \[ \] | \[x\] | +| D4 | 網易雲試聽片段照常當完整歌曲播放,不提示;下載端也擋不到 | — | `netease_source.dart:139-150` | \[ \] | \[ \] 提示/跳過 | \[x\] | +| D5 | 播放遇限流:只在解析層重試一次、等 3 秒,之後提示,不退避不跳過 | — | `stream_resolution_service.dart:210`;`audio_provider.dart:1984-1988` | \[ \] | \[ \] | \[x\] | +| D6 | 播放歷史在「開流成功」時記一筆;單曲循環每圈都記 | — | `playback_side_effects.dart:166-175` | \[ \] | \[ \] | \[x\] | +| D7 | 隨機模式下拖曳排序不更新隨機順序;「下一首播放」插到隨機位置 | — | `queue_manager.dart:541-547,594-613` | \[x\] | \[ \] | \[ \] | +| D8 | 開電台時只暫停音樂、不取消正在載入的音樂(推測會被音樂串流蓋掉) | — | `radio_controller.dart:840-847` | \[ \] | \[ \] | \[x\] | +| D9 | YouTube URL 有效期寫死 1 小時,不讀網址裡的 `expire` | — | `youtube_source.dart:52-54` | \[ \] | \[ \] | \[x\] | +| D10 | 電台/直播 | 輪詢開播狀態;網路錯誤顯示成「未開播」 | `bilibili_live_client.dart:205-208`;`radio_refresh_service.dart:252-257` | \[ \] | \[ \] | \[x\] | + 電台/直播、Mix 整個功能要不要保留,另見 §7。 -備註: +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。Mix模式下的"無法播放的歌不自動跳過"是什麼意思,我似乎沒有遇到過。網易雲我比較少用不太了解,你建議怎麼樣修改。限流和重試問題我也不太清楚,你有更好的方法嗎。"播放歷史在「開流成功」時記一筆;單曲循環每圈都記"這個應該是我想要的。電台、直播和有效期也不太清楚,如果有問題或是有更好的方案的話你可以修改。 --- @@ -214,30 +233,32 @@ 完整清單在 `features.md`;這裡只列需要你表態的功能域。狀態欄沿用 `features.md` 的判定。 -| # | 功能 | 狀態 | 平台 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---|---| -| E1 | 三個音源的搜尋與播放(B 站、YouTube、網易雲) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E2 | B 站分 P(多 cid 各自成曲,ADR 0005) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E3 | 音樂庫:本機歌單、排序、多選 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E4 | 匯入平台歌單(B 站收藏夾、YouTube 播放清單、網易雲歌單)並定時刷新 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E5 | 只能匯入的外部歌單(Spotify、QQ 音樂),自動匹配到可播放音源 | 完整;失敗時一律顯示「發生錯誤」(`errors.md` §1) | A W | [ ] | [ ] | [ ] | [ ] | -| E6 | 帳號登入(三個音源;WebView/QR) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E7 | 遠端歌單編輯(B1、B2) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E8 | 下載(含分類頁、路徑設定) | 完整;Android 在設定頁不能改下載路徑 | A W | [ ] | [ ] | [ ] | [ ] | -| E9 | 歌詞:多源搜尋(網易、QQ、lrclib)、自動匹配、手動選擇 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E10 | AI 歌詞匹配/標題解析(B5) | 完整,預設關 | A W | [ ] | [ ] | [ ] | [ ] | -| E11 | 桌面歌詞視窗(獨立視窗) | 完整,僅 Windows | W | [ ] | [ ] | [ ] | [ ] | -| E12 | 電台/直播(B 站直播間) | 完整;「收藏電台」無 UI 入口 | A W | [ ] | [ ] | [ ] | [ ] | -| E13 | Mix(YouTube 無限佇列) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E14 | 首頁排行/探索 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E15 | 播放歷史頁 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E16 | 備份與還原 | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -| E17 | 應用內更新(B7–B9) | 完整,只有手動檢查一個入口 | A W | [ ] | [ ] | [ ] | [ ] | -| E18 | 托盤、全域快捷鍵、開機自啟、關閉縮到托盤、單一實例 | 完整,僅 Windows | W | [ ] | [ ] | [ ] | [ ] | -| E19 | 播放速度(0.5–2.0,不持久化)、音量、桌面輸出裝置選擇;**沒有**睡眠定時器與均衡器 | 完整(`playback.md` §3.14) | A W | [ ] | [ ] | [ ] | [ ] | -| E20 | 使用者指南頁(設定頁進入,`lib/ui/pages/settings/user_guide_page.dart`) | 完整 | A W | [ ] | [ ] | [ ] | [ ] | -備註: +| # | 功能 | 狀態 | 平台 | 保留 | 刪除 | 修改 | 不確定 | +| --- | ---------------------------------------------------------- | -------------------------------- | --- | ----- | ----- | ----- | ----- | +| E1 | 三個音源的搜尋與播放(B 站、YouTube、網易雲) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E2 | B 站分 P(多 cid 各自成曲,ADR 0005) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E3 | 音樂庫:本機歌單、排序、多選 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E4 | 匯入平台歌單(B 站收藏夾、YouTube 播放清單、網易雲歌單)並定時刷新 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E5 | 只能匯入的外部歌單(Spotify、QQ 音樂),自動匹配到可播放音源 | 完整;失敗時一律顯示「發生錯誤」(`errors.md` §1) | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E6 | 帳號登入(三個音源;WebView/QR) | 完整 | A W | \[ x | \[ \] | \[ \] | \[ \] | +| E7 | 遠端歌單編輯(B1、B2) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E8 | 下載(含分類頁、路徑設定) | 完整;Android 在設定頁不能改下載路徑 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E9 | 歌詞:多源搜尋(網易、QQ、lrclib)、自動匹配、手動選擇 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E10 | AI 歌詞匹配/標題解析(B5) | 完整,預設關 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E11 | 桌面歌詞視窗(獨立視窗) | 完整,僅 Windows | W | \[x\] | \[ \] | \[ \] | \[ \] | +| E12 | 電台/直播(B 站直播間) | 完整;「收藏電台」無 UI 入口 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E13 | Mix(YouTube 無限佇列) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E14 | 首頁排行/探索 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E15 | 播放歷史頁 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E16 | 備份與還原 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E17 | 應用內更新(B7–B9) | 完整,只有手動檢查一個入口 | A W | \[x\] | \[ \] | \[ \] | \[ \] | +| E18 | 托盤、全域快捷鍵、開機自啟、關閉縮到托盤、單一實例 | 完整,僅 Windows | W | \[ \] | \[ \] | \[ \] | \[x\] | +| E19 | 播放速度(0.5–2.0,不持久化)、音量、桌面輸出裝置選擇;**沒有**睡眠定時器與均衡器 | 完整(`playback.md` §3.14) | A W | \[ \] | \[ \] | \[ \] | \[x\] | +| E20 | 使用者指南頁(設定頁進入,`lib/ui/pages/settings/user_guide_page.dart`) | 完整 | A W | \[ \] | \[ \] | \[ \] | \[x\] | + + +備註:單一實例的確是我想要的,畢竟用戶在正常使用時不會用到多個,但是這樣似乎導致了在開發時不太好實機測試?均衡器、響度平衡也都是我想要的,但是當前能夠做到嗎?使用者指南頁有需要保留嗎,應該移除、還是優化? --- @@ -245,22 +266,24 @@ 現況在 `platforms.md` §3、§6。每格選:**全**=全平台提供;**部分**=只在部分平台(備註寫哪些);**刪**=刪除;**?**=不確定。 -| 功能 | 現況 | 其他平台會卡在哪 | 全 | 部分 | 刪 | ? | -|---|---|---|---|---|---|---| -| 自動更新(應用內下載安裝) | A W | iOS 政策禁止;Mac App Store 禁止;Linux 依打包格式 | [ ] | [ ] | [ ] | [ ] | -| 下載音檔 | A W | App Store 5.2.3;iOS 沙盒 | [ ] | [ ] | [ ] | [ ] | -| Android 用「所有檔案存取權」裸路徑(ADR 0004) | A | 上架 Play 會被擋;可改 SAF/app 專屬目錄 | — | [ ] 維持 | [ ] 改 SAF | [ ] | -| 登入 WebView | A W | flutter_inappwebview 無 Linux 實作;YouTube 沒有 QR 登入 | [ ] | [ ] | [ ] | [ ] | -| 托盤 | W | 套件支援 macOS/Linux,程式寫死 Windows | [ ] | [ ] | [ ] | [ ] | -| 全域快捷鍵 | W | 同上;Linux Wayland 限制 | [ ] | [ ] | [ ] | [ ] | -| 開機自啟 | W | macOS 需額外原生碼 | [ ] | [ ] | [ ] | [ ] | -| 關閉縮到托盤、單一實例 | W | runner C++ 自訂 | [ ] | [ ] | [ ] | [ ] | -| 桌面歌詞視窗 | W | 需 runner 註冊子視窗插件;Android 寬版面有無作用的按鈕 | [ ] | [ ] | [ ] | [ ] | -| 自訂標題列 | W | macOS/Linux 現在是藏起來沒替代 | [ ] | [ ] | [ ] | [ ] | -| 系統媒體控制 | A(audio_service)、W(SMTC,不支援 seek) | macOS 可接 audio_service;Linux 需 MPRIS | [ ] | [ ] | [ ] | [ ] | -| 內建 CJK 字型 | 無(fallback `Noto Sans SC` 未內建) | 各平台字型不一 | [ ] 內建 | [ ] 依平台 fallback | — | [ ] | -備註: +| 功能 | 現況 | 其他平台會卡在哪 | 全 | 部分 | 刪 | ? | +| ------------------------------- | ---------------------------------- | ------------------------------------------------- | -------- | ------------------ | ----------- | ----- | +| 自動更新(應用內下載安裝) | A W | iOS 政策禁止;Mac App Store 禁止;Linux 依打包格式 | \[ \] | \[ \] | \[ \] | \[x\] | +| 下載音檔 | A W | App Store 5.2.3;iOS 沙盒 | \[ \] | \[ \] | \[ \] | \[x\] | +| Android 用「所有檔案存取權」裸路徑(ADR 0004) | A | 上架 Play 會被擋;可改 SAF/app 專屬目錄 | — | \[ \] 維持 | \[ \] 改 SAF | \[x\] | +| 登入 WebView | A W | flutter\_inappwebview 無 Linux 實作;YouTube 沒有 QR 登入 | \[ \] | \[ \] | \[ \] | \[x\] | +| 托盤 | W | 套件支援 macOS/Linux,程式寫死 Windows | \[ \] | \[ \] | \[ \] | \[x\] | +| 全域快捷鍵 | W | 同上;Linux Wayland 限制 | \[ \] | \[ \] | \[ \] | \[x\] | +| 開機自啟 | W | macOS 需額外原生碼 | \[ \] | \[ \] | \[ \] | \[x\] | +| 關閉縮到托盤、單一實例 | W | runner C++ 自訂 | \[ \] | \[ \] | \[ \] | \[x\] | +| 桌面歌詞視窗 | W | 需 runner 註冊子視窗插件;Android 寬版面有無作用的按鈕 | \[ \] | \[ \] | \[ \] | \[x\] | +| 自訂標題列 | W | macOS/Linux 現在是藏起來沒替代 | \[ \] | \[ \] | \[ \] | \[x\] | +| 系統媒體控制 | A(audio\_service)、W(SMTC,不支援 seek) | macOS 可接 audio\_service;Linux 需 MPRIS | \[ \] | \[ \] | \[ \] | \[x\] | +| 內建 CJK 字型 | 無(fallback `Noto Sans SC` 未內建) | 各平台字型不一 | \[ \] 內建 | \[ \] 依平台 fallback | — | \[x\] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。我會盡量希望用戶在不同平台上的功能和體驗都一樣,但是如果實在做不到的話也可以放棄。 --- @@ -268,19 +291,21 @@ 多數會在階段二自然解決;列出來是讓你知道現在的樣子。 -| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | -|---|---|---|---|---|---| -| G1 | `AudioController` 2,953 行、約 125 個方法;一次播放經十幾層協作物件;播放器狀態至少 5 份 | `architecture.md` §7;`playback.md` §2 | [ ] | [ ] | [ ] | -| G2 | 19 個目錄的大循環依賴(起因:`main.dart` 全域可變狀態被反向 import) | `architecture.md` §3;`lib/main.dart:29-44` | [ ] | [ ] | [ ] | -| G3 | 新增一個音源最少改 15 檔、同網易雲程度約 54 檔;音源特定分支 50 處散在 28 檔 | `sources.md` §3、§4 | [ ] | [ ] | [ ] | -| G4 | 錯誤呈現:自訂例外到畫面一律「發生錯誤」;adapter 把 `e.toString()` 原文丟上畫面;多源搜尋只要一源成功就隱藏其他失敗;507 個 catch 中約 70 個空的 | `errors.md` §1、§4 | [ ] | [ ] | [ ] | -| G5 | 播放網路錯誤的重試訊號只有沒人用的入口接得住,臨時播放/Mix/上下首會出錯 | `playback.md` §3.6;`audio_provider.dart:596,1933-1943` | [ ] | [ ] | [ ] | -| G6 | 161–162 個手寫 provider,放置慣例三種以上;repository 被繞過直接 `XxxRepository(db)` 20 處以上;約 19 個 Notifier 各自讀寫同一列 `Settings` | `architecture.md` §4 | [ ] | [ ] | [ ] | -| G7 | 死代碼:84 個 public 成員零引用(候選);`checkNow`、`reset`、`cleanupInvalidPaths`、`refreshStation`、`batchRemoveFromFolder`、`autoRefreshAll`、`playSingle`/`playAll`/`playPlaylist` 等已確認零呼叫 | `engineering.md` §7.2;`features.md` §14;`playback.md` §4.5 | [ ] | [ ] | [ ] | -| G8 | 重複邏輯:位元組格式化 6 份、InnerTube 文字抽取 2 份(行為不同)、兩個同名 `NeteaseSource`、兩條名稱倒裝的歌單匯入流程 | `engineering.md` §7.3;`architecture.md` §7 | [ ] | [ ] | [ ] | -| G9 | Toast/錯誤呈現三種寫法;背景錯誤只有 `AppShell` 在聽,全螢幕播放頁可能看不到(推測) | `devtools.md` §2 | [ ] | [ ] | [ ] | -備註: +| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | +| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ----- | ----- | ----- | +| G1 | `AudioController` 2,953 行、約 125 個方法;一次播放經十幾層協作物件;播放器狀態至少 5 份 | `architecture.md` §7;`playback.md` §2 | \[x\] | \[ \] | \[ \] | +| G2 | 19 個目錄的大循環依賴(起因:`main.dart` 全域可變狀態被反向 import) | `architecture.md` §3;`lib/main.dart:29-44` | \[x\] | \[ \] | \[ \] | +| G3 | 新增一個音源最少改 15 檔、同網易雲程度約 54 檔;音源特定分支 50 處散在 28 檔 | `sources.md` §3、§4 | \[x\] | \[ \] | \[ \] | +| G4 | 錯誤呈現:自訂例外到畫面一律「發生錯誤」;adapter 把 `e.toString()` 原文丟上畫面;多源搜尋只要一源成功就隱藏其他失敗;507 個 catch 中約 70 個空的 | `errors.md` §1、§4 | \[x\] | \[ \] | \[ \] | +| G5 | 播放網路錯誤的重試訊號只有沒人用的入口接得住,臨時播放/Mix/上下首會出錯 | `playback.md` §3.6;`audio_provider.dart:596,1933-1943` | \[x\] | \[ \] | \[ \] | +| G6 | 161–162 個手寫 provider,放置慣例三種以上;repository 被繞過直接 `XxxRepository(db)` 20 處以上;約 19 個 Notifier 各自讀寫同一列 `Settings` | `architecture.md` §4 | \[x\] | \[ \] | \[ \] | +| G7 | 死代碼:84 個 public 成員零引用(候選);`checkNow`、`reset`、`cleanupInvalidPaths`、`refreshStation`、`batchRemoveFromFolder`、`autoRefreshAll`、`playSingle`/`playAll`/`playPlaylist` 等已確認零呼叫 | `engineering.md` §7.2;`features.md` §14;`playback.md` §4.5 | \[x\] | \[ \] | \[ \] | +| G8 | 重複邏輯:位元組格式化 6 份、InnerTube 文字抽取 2 份(行為不同)、兩個同名 `NeteaseSource`、兩條名稱倒裝的歌單匯入流程 | `engineering.md` §7.3;`architecture.md` §7 | \[x\] | \[ \] | \[ \] | +| G9 | Toast/錯誤呈現三種寫法;背景錯誤只有 `AppShell` 在聽,全螢幕播放頁可能看不到(推測) | `devtools.md` §2 | \[x\] | \[ \] | \[ \] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,按你的推薦來做。 --- @@ -288,20 +313,23 @@ 現況在 `engineering.md` §2、§3、§5。本機全量 `--exclude-tags live`:1,849 通過、0 失敗、2 分 48 秒。 -| 類別 | 數量 | 現況評語 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---| -| 離線行為測試(services/data/providers/ui) | 約 1,700 個 | 以行為為主;部分大量依賴 `debug*ForTesting` 掛鉤(下載服務 44 處) | [ ] | [ ] | [ ] | [ ] | -| live 測試(打真實 API) | 4 個 | **不加參數的 `flutter test` 會跑它們**(`dart_test.yaml` 無預設 skip) | [ ] | [ ] | [ ] 預設排除 | [ ] | -| static-rule(正則比對原始碼) | 25 檔 144 個 | 都有合成違規測試;有些是計次預算(例如 `audio_provider.dart` 行數 ≤ 2,184、音源分支預算 9 處但實際 50 處沒守住) | [ ] | [ ] | [ ] | [ ] | -| 測 CI 設定本身(`test/workflows/`) | 4 檔 31 個 | 一半解析 YAML,一半比對 shell 片段字串 | [ ] | [ ] | [ ] | [ ] | -| benchmark(`test/performance/`) | 2 檔 13 個 | 可離線跑;斷言寬鬆的絕對上限 | [ ] | [ ] | [ ] | [ ] | -| 手動探針(`test/manual/`) | 2 檔 | 本機 HTTP 病態伺服器、真實 DB 探針 | [ ] | [ ] | [ ] | [ ] | -| `tool/demo/`(手跑、打真實 API) | 6 支 | 不引用 `lib/`,其中一支帶一份 `RegexTitleParser` 副本 | [ ] | [ ] | [ ] | [ ] | + +| 類別 | 數量 | 現況評語 | 保留 | 刪除 | 修改 | 不確定 | +| ---------------------------------- | ---------- | --------------------------------------------------------------------------- | ----- | ----- | ---------- | ----- | +| 離線行為測試(services/data/providers/ui) | 約 1,700 個 | 以行為為主;部分大量依賴 `debug*ForTesting` 掛鉤(下載服務 44 處) | \[ \] | \[ \] | \[ \] | \[x\] | +| live 測試(打真實 API) | 4 個 | **不加參數的 `flutter test` 會跑它們**(`dart_test.yaml` 無預設 skip) | \[ \] | \[ \] | \[ \] 預設排除 | \[x\] | +| static-rule(正則比對原始碼) | 25 檔 144 個 | 都有合成違規測試;有些是計次預算(例如 `audio_provider.dart` 行數 ≤ 2,184、音源分支預算 9 處但實際 50 處沒守住) | \[ \] | \[ \] | \[ \] | \[x\] | +| 測 CI 設定本身(`test/workflows/`) | 4 檔 31 個 | 一半解析 YAML,一半比對 shell 片段字串 | \[ \] | \[ \] | \[ \] | \[x\] | +| benchmark(`test/performance/`) | 2 檔 13 個 | 可離線跑;斷言寬鬆的絕對上限 | \[ \] | \[ \] | \[ \] | \[x\] | +| 手動探針(`test/manual/`) | 2 檔 | 本機 HTTP 病態伺服器、真實 DB 探針 | \[ \] | \[ \] | \[ \] | \[x\] | +| `tool/demo/`(手跑、打真實 API) | 6 支 | 不引用 `lib/`,其中一支帶一份 `RegexTitleParser` 副本 | \[ \] | \[ \] | \[ \] | \[x\] | + 另:main 分支 CI 目前是紅的(`account_repository_test.dart:105-118` 用固定 200ms 等待,時序不穩;run 36239727409)。 -- [ ] 審計結束後先在舊版修掉 - [ ] 不管,重寫時處理 - [ ] 不確定 -備註: +- [ ] 審計結束後先在舊版修掉 - \[x\] 不管,重寫時處理 - \[ \] 不確定 + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。我可能會希望測試不要打真實API,只有開發者在Debug頁面手動測試或是添加一個測試健康之類的測試,還是說你認為CI或是測試這類的要打實際的API來測試當前程序是否能夠正常使用比較好?但是當前匿名的話似乎很多東西都做不到或是被限流,需要登陸才行。然後static-rule的話其實我不太懂這個是什麼,他有用嗎。我會希望可能只保留一些必要的測試來在添加新功能後、修改代碼後能夠守護某些行為的一致。 --- @@ -309,16 +337,18 @@ - 現況:`en`、`zh-CN`、`zh-TW` 三種,每種 38 個 JSON 檔,用 slang 管理(`lib/i18n/`)。缺漏 key 與硬編碼字串統計見 `ui.md` §4。 -| 語言 | 保留 | 刪除 | 不確定 | -|---|---|---|---| -| English(`en`) | [ ] | [ ] | [ ] | -| 簡體中文(`zh-CN`) | [ ] | [ ] | [ ] | -| 繁體中文(`zh-TW`) | [ ] | [ ] | [ ] | + +| 語言 | 保留 | 刪除 | 不確定 | +| ------------- | ----- | ----- | ----- | +| English(`en`) | \[x\] | \[ \] | \[ \] | +| 簡體中文(`zh-CN`) | \[x\] | \[ \] | \[ \] | +| 繁體中文(`zh-TW`) | \[x\] | \[ \] | \[ \] | + 其他想加的語言: -- base locale(缺字時的後備語言)目前是 `zh-CN`:[ ] 維持 [ ] 改 `zh-TW` [ ] 改 `en` [ ] 不確定 -- 三語言目前完全對齊(各 1,176 個 key),但桌面浮動歌詞視窗有 33 個簡體字串寫死在程式碼(`lyrics_window.dart:33-66`),UI 裡另有硬編碼字串(`ui.md` §4):[ ] 重寫時全部納入 i18n [ ] 不確定 +- base locale(缺字時的後備語言)目前是 `zh-CN`:\[ \] 維持 \[ \] 改 `zh-TW` \[ \] 改 `en` \[ \] 不確定 +- 三語言目前完全對齊(各 1,176 個 key),但桌面浮動歌詞視窗有 33 個簡體字串寫死在程式碼(`lyrics_window.dart:33-66`),UI 裡另有硬編碼字串(`ui.md` §4):\[ \] 重寫時全部納入 i18n \[ \] 不確定 --- @@ -326,17 +356,19 @@ 現況在 `ui.md` §7、截圖在 `docs/audit/screenshots/`。階段二會出設計系統與桌面播放器版面方案;這裡先確認問題清單與範圍。 -| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | -|---|---|---|---|---|---| -| U1 | 間距與字級沒有 token:`EdgeInsets` 約 250 處、`SizedBox` 約 500 處字面數字,29 處 `fontSize:` 繞過主題 | `ui.md` §3.2 | [ ] | [ ] | [ ] | -| U2 | 桌面鍵盤操作:App 內沒有任何快捷鍵(`Shortcuts`/`Actions` 0 處),Esc 離不開播放頁;焦點指示在深色主題幾乎看不見,Tab 要穿過整個清單才到導航軌 | `ui.md` §5.3;`windows-focus-row.png` | [ ] | [ ] | [ ] | -| U3 | 無障礙:播放頁大播放鍵沒有名稱;迷你播放器是「按鈕包按鈕」 | `player_play_pause_button.dart:46-48`;`mini_player.dart:54-58` | [ ] | [ ] | [ ] | -| U4 | 窄桌面視窗的迷你播放器保留 7 顆鈕,標題只剩 2 個字 | `windows-compact-home.png` | [ ] | [ ] | [ ] | -| U5 | 搜尋頁來源篩選列被排序鈕蓋住、沒有可捲動提示 | `windows-search.png`、`android-search.png` | [ ] | [ ] | [ ] | -| U6 | 數字與複數格式:「4600.0萬」「46.0M」「1 tracks」 | `number_format_utils.dart:28-37` | [ ] | [ ] | [ ] | -| U7 | 右側「正在播放」面板在所有頁面常駐(寬度 ≥ 840) | `ui.md` §1.2 | [ ] 保留常駐 | [ ] 只在播放相關頁 | [ ] | -| U8 | `large`/`extraLarge` 斷點註解承諾的版面沒有實作 | `responsive_scaffold.dart:116-145` | [ ] 實作 | [ ] 刪註解 | [ ] | -| U9 | Windows debug/profile build 讀寫使用者真實資料(`Documents\FMP`),沒有隔離;本次審計因此誤觸播放你佇列中的曲目 | `database_provider.dart:49-52` | [ ] 開發版用獨立資料目錄 | [ ] | [ ] | + +| # | 問題 | 證據 | 重寫時處理 | 不處理 | 不確定 | +| --- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ---------------- | ------------- | ----- | +| U1 | 間距與字級沒有 token:`EdgeInsets` 約 250 處、`SizedBox` 約 500 處字面數字,29 處 `fontSize:` 繞過主題 | `ui.md` §3.2 | \[x\] | \[ \] | \[ \] | +| U2 | 桌面鍵盤操作:App 內沒有任何快捷鍵(`Shortcuts`/`Actions` 0 處),Esc 離不開播放頁;焦點指示在深色主題幾乎看不見,Tab 要穿過整個清單才到導航軌 | `ui.md` §5.3;`windows-focus-row.png` | \[x\] | \[ \] | \[ \] | +| U3 | 無障礙:播放頁大播放鍵沒有名稱;迷你播放器是「按鈕包按鈕」 | `player_play_pause_button.dart:46-48`;`mini_player.dart:54-58` | \[x\] | \[ \] | \[ \] | +| U4 | 窄桌面視窗的迷你播放器保留 7 顆鈕,標題只剩 2 個字 | `windows-compact-home.png` | \[x\] | \[ \] | \[ \] | +| U5 | 搜尋頁來源篩選列被排序鈕蓋住、沒有可捲動提示 | `windows-search.png`、`android-search.png` | \[x\] | \[ \] | \[ \] | +| U6 | 數字與複數格式:「4600.0萬」「46.0M」「1 tracks」 | `number_format_utils.dart:28-37` | \[x\] | \[ \] | \[ \] | +| U7 | 右側「正在播放」面板在所有頁面常駐(寬度 ≥ 840) | `ui.md` §1.2 | \[x\] 保留常駐 | \[ \] 只在播放相關頁 | \[ \] | +| U8 | `large`/`extraLarge` 斷點註解承諾的版面沒有實作 | `responsive_scaffold.dart:116-145` | \[x\] 實作 | \[ \] 刪註解 | \[ \] | +| U9 | Windows debug/profile build 讀寫使用者真實資料(`Documents\FMP`),沒有隔離;本次審計因此誤觸播放你佇列中的曲目 | `database_provider.dart:49-52` | \[x\] 開發版用獨立資料目錄 | \[ \] | \[ \] | + --- @@ -344,14 +376,16 @@ 現況在 `devtools.md`。 -| # | 項目 | 現況 | 保留 | 刪除 | 修改 | 不確定 | -|---|---|---|---|---|---|---| -| J1 | 開發者模式開啟方式(「版本」連點 7 次)、不持久化、沒有關閉入口 | `developer_options_page.dart:69-77` | [ ] | [ ] | [ ] | [ ] | -| J2 | Debug 頁現有區塊(log 檢視、資料庫檢視器、重設資料等) | `devtools.md` §1 | [ ] | [ ] | [ ] 階段二重做 | [ ] | -| J3 | log 寫檔(位置、輪替見 `devtools.md` §3) | — | [ ] | [ ] | [ ] | [ ] | -| J4 | `DataIntegrityRepository.scan/repair`(只有測試用) | `data_integrity_repository.dart:59-85` | [ ] 接到 Debug 頁 | [ ] | — | [ ] | -備註: +| # | 項目 | 現況 | 保留 | 刪除 | 修改 | 不確定 | +| --- | -------------------------------------------- | -------------------------------------- | ---------------- | ----- | ----------- | ----- | +| J1 | 開發者模式開啟方式(「版本」連點 7 次)、不持久化、沒有關閉入口 | `developer_options_page.dart:69-77` | \[x\] | \[ \] | \[ \] | \[ \] | +| J2 | Debug 頁現有區塊(log 檢視、資料庫檢視器、重設資料等) | `devtools.md` §1 | \[ \] | \[ \] | \[ \] 階段二重做 | \[x\] | +| J3 | log 寫檔(位置、輪替見 `devtools.md` §3) | — | \[ \] | \[ \] | \[ \] | \[x\] | +| J4 | `DataIntegrityRepository.scan/repair`(只有測試用) | `data_integrity_repository.dart:59-85` | \[ \] 接到 Debug 頁 | \[ \] | — | \[x\] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。如果有問題或是有更好的方案的話可以按你推薦的來改。 --- @@ -359,17 +393,19 @@ 比對細節在 `engineering.md` §10。選項:**確認**=新架構沿用這個決定;**推翻**=改走別的路;**不再適用**=新架構下這題不存在。 -| ADR | 它決定了什麼 | 代碼現況 | 確認 | 推翻 | 不再適用 | -|---|---|---|---|---|---| -| 0001 每源設定收成清單、音源改用字串 id | 刪 `enum SourceType`,改 `SourceIds` 字串常數;每源設定改成 `@embedded List` | **部分不一致**:ADR 說 `setUseAuthForPlay` 對未知 id 拋錯,`8ffa7d4f` 已改成建一筆預設(ADR 寫成時就已過時) | [ ] | [ ] | [ ] | -| 0002 Isar 只出現在 repository 層 | `isar.` 只准在 `lib/data/repositories/`,兩個明文豁免;由 static-rule 守 | 一致;但 `Isar` 實例本身傳遍各層,UI 甚至會自己跑遷移(`developer_options_page.dart:548-554`) | [ ] | [ ] | [ ] | -| 0003 保留兩個音訊後端 | Android/iOS just_audio,其他 media_kit;共用純規則 | 一致 | [ ] | [ ] | [ ] | -| 0004 Android 下載用所有檔案存取權與裸路徑 | 知情接受 `MANAGE_EXTERNAL_STORAGE`,理由是永不上架商店 | 一致 | [ ] | [ ] | [ ] | -| 0005 曲目識別鍵包含 cid | 分 P 以 cid 區分,鍵字串是持久化格式 | 一致 | [ ] | [ ] | [ ] | -| 0006 Release 驗過產物就直接發布 | 不留草稿,驗證 job 取代人工按發布 | 一致(release validate 比 CI 少 `dart format`) | [ ] | [ ] | [ ] | -| 0007 Isar 停在 v3,改用 isar_community | 留 v3 磁碟格式,依賴換成社群 fork | **部分不一致**:上游最後發版日期寫錯(實為 2023-08) | [ ] | [ ] | [ ] | -備註: +| ADR | 它決定了什麼 | 代碼現況 | 確認 | 推翻 | 不再適用 | +| ---------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ----- | ----- | ----- | +| 0001 每源設定收成清單、音源改用字串 id | 刪 `enum SourceType`,改 `SourceIds` 字串常數;每源設定改成 `@embedded List` | **部分不一致**:ADR 說 `setUseAuthForPlay` 對未知 id 拋錯,`8ffa7d4f` 已改成建一筆預設(ADR 寫成時就已過時) | \[ \] | \[ \] | \[ \] | +| 0002 Isar 只出現在 repository 層 | `isar.` 只准在 `lib/data/repositories/`,兩個明文豁免;由 static-rule 守 | 一致;但 `Isar` 實例本身傳遍各層,UI 甚至會自己跑遷移(`developer_options_page.dart:548-554`) | \[ \] | \[ \] | \[ \] | +| 0003 保留兩個音訊後端 | Android/iOS just\_audio,其他 media\_kit;共用純規則 | 一致 | \[ \] | \[ \] | \[ \] | +| 0004 Android 下載用所有檔案存取權與裸路徑 | 知情接受 `MANAGE_EXTERNAL_STORAGE`,理由是永不上架商店 | 一致 | \[ \] | \[ \] | \[ \] | +| 0005 曲目識別鍵包含 cid | 分 P 以 cid 區分,鍵字串是持久化格式 | 一致 | \[ \] | \[ \] | \[ \] | +| 0006 Release 驗過產物就直接發布 | 不留草稿,驗證 job 取代人工按發布 | 一致(release validate 比 CI 少 `dart format`) | \[ \] | \[ \] | \[ \] | +| 0007 Isar 停在 v3,改用 isar\_community | 留 v3 磁碟格式,依賴換成社群 fork | **部分不一致**:上游最後發版日期寫錯(實為 2023-08) | \[ \] | \[ \] | \[ \] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。要不要保留或是修改這些ADR? --- @@ -377,12 +413,14 @@ 比對細節在 `engineering.md` §11。選項:**保留**=留在(新的)術語表;**併入**=併進對應 spec 或 docs 術語表;**刪除**=新架構不需要這個詞。 -| 術語 | 意思(一句話) | 代碼現況 | 保留 | 併入 spec/docs 術語表 | 刪除 | -|---|---|---|---|---|---| -| Source Auth Context | 決定某次音源操作可以用哪些憑證的政策 | 有對應:`SourceAuthContext`(`source_auth_context.dart:76`) | [ ] | [ ] | [ ] | -| Media Handoff | 從解析出的串流 URL 交給播放/下載後端的那一步(headers、redirect 檢查) | 部分對應:redirect 檢查只在下載 isolate(`download_service.dart:1831-1885`),播放路徑沒有 | [ ] | [ ] | [ ] | -| Stream Resolution Auth | 向音源要串流 URL 時用的憑證 | 有對應;`streamResolutionAuth` 欄位在生產路徑上沒被讀取 | [ ] | [ ] | [ ] | -| Auth For Play | 使用者設定,控制播放/下載/詳情是否帶憑證 | 有對應(`settings.dart:724`);實際也控制首頁排行榜,CONTEXT 沒寫 | [ ] | [ ] | [ ] | -| Media Request Credentials | 允許出現在音訊位元組請求上的憑證(目前為空) | 有對應(`source_http_policy.dart:82`) | [ ] | [ ] | [ ] | -備註: +| 術語 | 意思(一句話) | 代碼現況 | 保留 | 併入 spec/docs 術語表 | 刪除 | +| ------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------- | ----- | ---------------- | ----- | +| Source Auth Context | 決定某次音源操作可以用哪些憑證的政策 | 有對應:`SourceAuthContext`(`source_auth_context.dart:76`) | \[ \] | \[ \] | \[ \] | +| Media Handoff | 從解析出的串流 URL 交給播放/下載後端的那一步(headers、redirect 檢查) | 部分對應:redirect 檢查只在下載 isolate(`download_service.dart:1831-1885`),播放路徑沒有 | \[ \] | \[ \] | \[ \] | +| Stream Resolution Auth | 向音源要串流 URL 時用的憑證 | 有對應;`streamResolutionAuth` 欄位在生產路徑上沒被讀取 | \[ \] | \[ \] | \[ \] | +| Auth For Play | 使用者設定,控制播放/下載/詳情是否帶憑證 | 有對應(`settings.dart:724`);實際也控制首頁排行榜,CONTEXT 沒寫 | \[ \] | \[ \] | \[ \] | +| Media Request Credentials | 允許出現在音訊位元組請求上的憑證(目前為空) | 有對應(`source_http_policy.dart:82`) | \[ \] | \[ \] | \[ \] | + + +備註:我不是專業的,因此有很多東西我都不清楚應該怎麼樣做比較好,你的建議是什麼。 \ No newline at end of file From 50a3fe41a07d2928692d4bc6aeb1ec9c8fd0c6ca Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:31:35 +0800 Subject: [PATCH 005/133] chore(task): archive audit --- .trellis/tasks/{ => archive/2026-09}/09-26-audit/check.jsonl | 0 .../tasks/{ => archive/2026-09}/09-26-audit/implement.jsonl | 0 .trellis/tasks/{ => archive/2026-09}/09-26-audit/prd.md | 0 .trellis/tasks/{ => archive/2026-09}/09-26-audit/task.json | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-26-audit/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-26-audit/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-26-audit/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-26-audit/task.json (90%) diff --git a/.trellis/tasks/09-26-audit/check.jsonl b/.trellis/tasks/archive/2026-09/09-26-audit/check.jsonl similarity index 100% rename from .trellis/tasks/09-26-audit/check.jsonl rename to .trellis/tasks/archive/2026-09/09-26-audit/check.jsonl diff --git a/.trellis/tasks/09-26-audit/implement.jsonl b/.trellis/tasks/archive/2026-09/09-26-audit/implement.jsonl similarity index 100% rename from .trellis/tasks/09-26-audit/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-26-audit/implement.jsonl diff --git a/.trellis/tasks/09-26-audit/prd.md b/.trellis/tasks/archive/2026-09/09-26-audit/prd.md similarity index 100% rename from .trellis/tasks/09-26-audit/prd.md rename to .trellis/tasks/archive/2026-09/09-26-audit/prd.md diff --git a/.trellis/tasks/09-26-audit/task.json b/.trellis/tasks/archive/2026-09/09-26-audit/task.json similarity index 90% rename from .trellis/tasks/09-26-audit/task.json rename to .trellis/tasks/archive/2026-09/09-26-audit/task.json index 2c9ffbd1e..64056f00f 100644 --- a/.trellis/tasks/09-26-audit/task.json +++ b/.trellis/tasks/archive/2026-09/09-26-audit/task.json @@ -3,7 +3,7 @@ "name": "audit", "title": "Phase 1 audit", "description": "Read-only audit of current FMP state into docs/audit/", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-26", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From 1764badc9a5ca9cb147031474deee9b242227204 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:38:55 +0800 Subject: [PATCH 006/133] docs(audit): fix the E6 tick and record the confirmed phase-two order --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 ++++++++++-- docs/audit/questions.md | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 8fac36c3e..454085ddc 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -1,6 +1,6 @@ # 階段二計畫:設計項目的依賴關係與順序 -> 草案,等你確認順序後才開始逐項 brainstorm。每一項展開時都會先研究(官方文檔、其他播放器的做法), +> 順序已於 2026-09-27 確認,逐項以 trellis-brainstorm 展開。每一項展開時都會先研究(官方文檔、其他播放器的做法), > 本文的「初步傾向」只是起點,不是結論。 依據:parent `prd.md` 階段二第 1–18 項、`docs/audit/questions.md` 的勾選(2026-09-27)。 @@ -198,7 +198,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio | D8 電台打斷音樂載入 | 開電台時取消正在載入的音樂 | 13 | | D9 YouTube URL 期限 | 讀網址裡的 `expire`,不寫死 1 小時 | 1、17 | | D10 電台錯誤顯示成未開播 | 區分「未開播」與「查詢失敗」 | 2、13 | -| E6 帳號登入 | 你沒勾,暫當「保留」,請確認 | — | +| E6 帳號登入 | 保留(已確認;原勾選的方括號沒閉合,已修正) | — | | E18 托盤/快捷鍵等 | 保留,擴到所有桌面平台 | 10 | | E19 均衡器、響度 | 新功能,記進待辦 | 20 | | E20 使用者指南頁 | 傾向刪除,改成 README/docs 裡的說明連結;你也可以選優化 | 5 | @@ -207,3 +207,11 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio | J2–J4 | Debug 頁重做成正式工具;log 寫檔保留並加輪替與保留期限;資料檢查/修復收進 Debug 頁 | 4、18 | | §14 ADR | 0001 字串音源 id:確認;每源設定清單:由新設計取代。0002、0007:看 A2,換庫就「不再適用」。0003、0004:在 13、11 重新決定。0005 分 P 以 cid 區分:確認(也是舊資料遷移要用的格式)。0006 自動發布:確認,並補上 CHANGELOG 產生說明 | 9 | | §15 CONTEXT.md | 5 個術語的內容(憑證只在解析串流時用、媒體請求不帶憑證)是對的原則,併進第 12 項的網路規範;術語本身隨新設計改名,CONTEXT.md 在階段三刪除 | 9、12 | + +## 6. 已確認(2026-09-27) + +- 順序照 §3。 +- 其餘「不確定」項以 §5 的初步傾向為方向,展開時研究後再定案。 +- D3:Mix 與普通佇列統一處理,不可播放就自動跳過。 +- iOS:GitHub Release 發佈 IPA,供側載。 +- static-rule:重寫後改用 Dart analyzer 的 lint 規則。 diff --git a/docs/audit/questions.md b/docs/audit/questions.md index d6a1157f8..474556a13 100644 --- a/docs/audit/questions.md +++ b/docs/audit/questions.md @@ -241,7 +241,7 @@ | E3 | 音樂庫:本機歌單、排序、多選 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | | E4 | 匯入平台歌單(B 站收藏夾、YouTube 播放清單、網易雲歌單)並定時刷新 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | | E5 | 只能匯入的外部歌單(Spotify、QQ 音樂),自動匹配到可播放音源 | 完整;失敗時一律顯示「發生錯誤」(`errors.md` §1) | A W | \[x\] | \[ \] | \[ \] | \[ \] | -| E6 | 帳號登入(三個音源;WebView/QR) | 完整 | A W | \[ x | \[ \] | \[ \] | \[ \] | +| E6 | 帳號登入(三個音源;WebView/QR) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | | E7 | 遠端歌單編輯(B1、B2) | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | | E8 | 下載(含分類頁、路徑設定) | 完整;Android 在設定頁不能改下載路徑 | A W | \[x\] | \[ \] | \[ \] | \[ \] | | E9 | 歌詞:多源搜尋(網易、QQ、lrclib)、自動匹配、手動選擇 | 完整 | A W | \[x\] | \[ \] | \[ \] | \[ \] | From 8f03a20cab85ba7f4f006c99b925f4fa9c8d2f2b Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:43:38 +0800 Subject: [PATCH 007/133] chore(task): plan phase-two item 9 (docs structure and ADR disposition) --- .trellis/tasks/09-27-design-docs/check.jsonl | 0 .trellis/tasks/09-27-design-docs/design.md | 79 +++++++++++++++++++ .../tasks/09-27-design-docs/implement.jsonl | 0 .trellis/tasks/09-27-design-docs/implement.md | 35 ++++++++ .trellis/tasks/09-27-design-docs/prd.md | 43 ++++++++++ .trellis/tasks/09-27-design-docs/task.json | 26 ++++++ 6 files changed, 183 insertions(+) create mode 100644 .trellis/tasks/09-27-design-docs/check.jsonl create mode 100644 .trellis/tasks/09-27-design-docs/design.md create mode 100644 .trellis/tasks/09-27-design-docs/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-docs/implement.md create mode 100644 .trellis/tasks/09-27-design-docs/prd.md create mode 100644 .trellis/tasks/09-27-design-docs/task.json diff --git a/.trellis/tasks/09-27-design-docs/check.jsonl b/.trellis/tasks/09-27-design-docs/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-docs/design.md b/.trellis/tasks/09-27-design-docs/design.md new file mode 100644 index 000000000..f5ac01ae4 --- /dev/null +++ b/.trellis/tasks/09-27-design-docs/design.md @@ -0,0 +1,79 @@ +# 設計:文檔結構與 ADR 機制 + +## 1. 目標文檔地圖 + +判準:一種資訊只有一個家;放哪裡由「誰讀、什麼時候讀」決定。 + +| 位置 | 讀者 | 放什麼 | 不放什麼 | 採用的慣例 | +|---|---|---|---|---| +| `README.md`(英)+`README.zh-Hant.md` | 使用者 | 產品介紹、截圖、下載、平台支援 | 開發細節 | 維持現況雙語(App 本身支援英文) | +| `docs/*.md` | 人類開發者 | 操作指南(建置、發版、除錯)、參考(設定、產物命名)、說明(架構為什麼這樣分) | 單一段程式碼的理由(寫在 dartdoc)、agent 規則 | Diátaxis;不預建四個空資料夾,`docs/README.md` 的地圖表加一欄標每份文件的類型 | +| `docs/adr/NNNN-*.md` | 人類與 agent | 跨模組決定、理由、被否決的方案、怎麼確認有被遵守 | 實作步驟、任務進度 | MADR(見 §3) | +| `AGENTS.md` | AI agent | 頂層目錄地圖(≤10 列)、驗證指令表、邊界規則(每條附閘門)、程式碼查不到的地雷 | 能從程式碼幾秒查到的東西、某一層的寫法細節 | agents.md;使用者全域規則 | +| `.trellis/spec//` | AI agent(實作該層時) | 這一層的程式碼怎麼寫、範例與反例 | 歷史、決策理由(連到 ADR)、有閘門的規則本文(連到 AGENTS.md) | 使用者在 prd 定的分工 | +| `.trellis/tasks/*/design.md` | 執行該任務的人與 agent | 這次任務怎麼做 | 長期規則 | 隨任務歸檔 | +| `.claude/skills//` | AI agent | 可被叫用的專案操作流程(例如 verify-on-device) | 規則 | Claude Code skill | +| `docs/audit/` | 使用者 | 重寫前的現況快照與驗收基準 | 新內容 | 凍結;最後一個里程碑刪除(§5) | + +語言:以上全部繁中;程式碼識別字、指令、檔名、log 字串、commit message 保留原文。README 例外,維持英/繁雙語。 + +## 2. 規則放哪裡 + +| 資訊 | 唯一位置 | 其他地方怎麼提 | +|---|---|---| +| 有閘門的邊界規則 | `AGENTS.md` | spec 只放連結 | +| 規則為什麼存在 | 對應的 ADR | AGENTS.md 一句話+ADR 編號 | +| 某層寫法慣例 | `.trellis/spec//` | — | +| 驗證要跑什麼 | `AGENTS.md` 驗證表 | Trellis 子代理定義回指 AGENTS.md,不複寫 | +| 建置/發版步驟 | `docs/` | AGENTS.md 只放指令 | +| 單一段程式碼的理由 | 旁邊的 dartdoc 或守它的測試 | — | + +AGENTS.md 裡每一條規則都要能回答「哪個 test 或 lint 守著它」;答不出來的,要嘛補閘門,要嘛刪掉(使用者全域規則)。 + +## 3. ADR 機制 + +- 位置維持 `docs/adr/`(MADR 預設是 `docs/decisions/`,但既有引用都指向 `adr/`,改名沒有好處)。 +- 檔名 `NNNN-用英文小寫連字號的標題.md`,從 **0008** 接續,編號不重用。 +- 範本 `docs/adr/template.md`,章節(依 MADR 精簡): + - 標題(問題+選擇) + - 狀態、日期 + - 背景與問題 + - 考慮過的選項(每個一段:做法、優點、缺點) + - 決定與理由(寫明採用了誰的慣例) + - 後果(好的、壞的、之後要注意的) + - 如何確認:守著這個決定的 test/lint/review 點(對應 MADR 的 Confirmation) +- 什麼時候寫:階段二每個設計項目定案時,重大決定各一份(預期至少:重寫策略、平台層、資料層與相容、網路與帳號、錯誤模型、音源插件、測試策略、播放核心、下載與權限、發版與更新)。一個項目可以有多份,也可以沒有(例如 Toast 可能只進 spec)。 +- 取代舊 ADR:新 ADR 推翻或讓舊 ADR 不再適用時,**同一個 commit**:刪除舊檔、改掉所有引用、`git grep` 確認沒有殘留(`.trellis/tasks/archive/` 是歷史,不改)。新 ADR 在「背景」裡寫明它取代了哪一份、原本決定了什麼。 + +> 與 MADR 的差異:MADR 以狀態「superseded by」保留舊紀錄;這裡依使用者要求直接刪除,歷史靠 git。 + +## 4. 舊 ADR 與 CONTEXT.md 的去留 + +| 舊 ADR | 處理 | 在哪一項定案 | +|---|---|---| +| 0001 字串音源 id + 每源設定清單 | 字串 id 的部分確認沿用;每源設定清單由第 6/18 項的新設計取代。第 1 項寫音源插件 ADR 時把字串 id 併進去,0001 同時刪除 | 1、6、18 | +| 0002 Isar 只在 repository 層 | 第 6 項決定資料層後:換庫則刪除;原則(資料庫只在資料層)寫進新的資料層 ADR | 6 | +| 0003 兩個音訊後端 | 第 13 項重新決定,新 ADR 取代 | 13 | +| 0004 Android 所有檔案存取權 | 第 11 項重新決定,新 ADR 取代 | 11 | +| 0005 曲目識別鍵包含 cid | 確認沿用(也是舊資料遷移要用的格式);第 6 項視需要改寫 | 6 | +| 0006 Release 自動發布 | 確認沿用;第 19 項補上「發佈說明由 CHANGELOG 產生」後改寫 | 19 | +| 0007 Isar 停在 v3 | 隨 0002 一起處理 | 6 | + +`CONTEXT.md`:5 個術語描述的原則(憑證只用在解析串流、媒體位元組請求不帶憑證、「用登入狀態」開關的範圍)併進第 12 項的 ADR 與 spec,術語依新設計命名;階段三刪除 `CONTEXT.md` 並改掉 `.trellis/spec/` 裡 7 處引用。 + +## 5. `docs/audit/` 的生命週期 + +重寫期間凍結(只允許核查更正),是完成定義的基準(`features.md` 勾「保留」的功能、`perf-baseline.md` 的效能)。最後一個里程碑的 PR 刪除整個目錄,並把 `docs/README.md`「審查記錄不進 `docs/`」恢復成沒有例外。 + +## 6. 階段三要處理的現況衝突 + +來自 `docs/audit/engineering.md` §8.2、§9: + +- mattpocock 殘留:`docs/agents/` 三檔、AGENTS.md「Agent skills」段、`docs/README.md:21,23`;「issue 用繁中撰寫」搬一句進 AGENTS.md。 +- AGENTS.md 的 Trellis 自動區塊提到不存在的 `.codex/`、被 gitignore 的 `.agents/`;本機 `.agents/skills/verify-on-device/` 是過期副本。 +- check 子代理有三份定義(`.claude/agents/trellis-check.md`、`.trellis/agents/check.md`、`.claude/skills/trellis-check/`)。 +- Trellis 文件描述 journal commit,但設定已關閉。 +- AGENTS.md 對「等待慣例」的閘門範圍說得比實際寬。 +- `.trellis/workflow.md` 3.4「不 push」與使用者全域「自己的 repo 直接 push」的層級差異:repo 內不衝突,保留 Trellis 原文,不在 repo 內處理。 + +`.trellis/`、`.claude/` 裡由 Trellis 產生的檔案,改動前先確認 `trellis update` 會不會覆蓋(AGENTS.md「Trellis」段已記錄要保留的客製)。 diff --git a/.trellis/tasks/09-27-design-docs/implement.jsonl b/.trellis/tasks/09-27-design-docs/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-docs/implement.md b/.trellis/tasks/09-27-design-docs/implement.md new file mode 100644 index 000000000..e6176625a --- /dev/null +++ b/.trellis/tasks/09-27-design-docs/implement.md @@ -0,0 +1,35 @@ +# 執行計畫 + +本任務(第 9 項)只產出設計;下列兩部分分別在不同時點執行。 + +## A. 本任務核准後立即做 + +- [ ] 在 `docs/adr/` 新增 `template.md`(design.md §3 的章節)。之後第 1 項起的 ADR 都從它複製。 +- [ ] `phase2-plan.md` 把第 9 項標為完成,並連到本任務。 +- [ ] 歸檔本任務。 + +不動 `AGENTS.md`、`docs/README.md`、`.trellis/spec/`:它們描述的是舊程式碼,在階段三與各里程碑改寫。 + +## B. 階段三 child task(階段二全部定案後) + +依 design.md §4、§6: + +1. 刪除 `docs/agents/`;刪除 AGENTS.md「Agent skills」段;把「issue 用繁中撰寫」寫進 AGENTS.md。 +2. 改寫 `docs/README.md`:地圖表加 Diátaxis 類型欄;刪 `:21` 中英分工規則與 `:23` `docs/agents/` 說明;`docs/audit/` 註明為凍結快照。 +3. 依使用者在 `questions.md` 的勾選與 design.md §4 處理舊 ADR(已被新 ADR 取代的,應已在寫新 ADR 時刪除;這裡只收尾)。 +4. `CONTEXT.md` 內容併入第 12 項產出的 spec 後刪除;改掉 `.trellis/spec/data/index.md:9`、`data/sources.md:81`、`guides/cross-layer-thinking-guide.md:51`、`services/download-and-auth.md:3,38`、`services/index.md:8,24`。 +5. 修正 design.md §6 其餘衝突(AGENTS.md Trellis 區塊、check 子代理重複、journal commit 敘述、等待慣例敘述);本機刪除 `.agents/`。 +6. AGENTS.md、`.trellis/spec/` 改寫為繁中(可隨各里程碑逐層改寫,不必一次翻完)。 + +驗證: + +```bash +git grep -n -E "docs/agents|CONTEXT\.md|Agent skills|wayfinder|grill-with-docs" -- . ':!.trellis/tasks/archive' ':!docs/audit' +git grep -n -E "adr/000[1-7]|ADR 000[1-7]" -- . ':!.trellis/tasks/archive' ':!docs/audit' # 只允許仍存在的 ADR +``` + +兩條都只能命中仍存在、刻意保留的檔案。 + +## C. 最後一個里程碑 + +- [ ] 刪除 `docs/audit/`;`docs/README.md` 恢復「審查記錄不進 `docs/`」無例外。 diff --git a/.trellis/tasks/09-27-design-docs/prd.md b/.trellis/tasks/09-27-design-docs/prd.md new file mode 100644 index 000000000..bb0386014 --- /dev/null +++ b/.trellis/tasks/09-27-design-docs/prd.md @@ -0,0 +1,43 @@ +# 設計第 9 項:文檔結構與 ADR/CONTEXT.md 去留 + +## 目標 + +定下重寫後「給人看的文檔」與「給 AI 看的指令」各放什麼、互不重複,ADR 機制怎麼運作, +以及舊 ADR(0001–0007)、`CONTEXT.md`、mattpocock 殘留、`docs/audit/` 的去留。 +之後每個設計項目產出的 ADR 都照這裡的規則寫。 + +需求來源:parent `prd.md` 階段二第 9 項、階段三;`phase2-plan.md` §5(使用者已確認「按推薦」)。 + +## 背景(證據) + +- 人類文檔:`README.md`(英)+`README.zh-Hant.md`、`docs/` 5 份繁中文件與 `docs/README.md` 文件地圖;`docs/adr/` 7 份繁中 ADR。 +- AI 指令:`AGENTS.md`(134 行,英文)、`.trellis/spec/` 6 層 20 檔(英文)、`.trellis/workflow.md`、`.claude/{agents,commands,hooks,skills}`、`orca.yaml`;沒有 `CLAUDE.md`,本 session 的 Claude Code 直接載入了 `AGENTS.md`。 +- `docs/README.md:21` 規定中英分工;`:24` 規定「審查記錄不進 `docs/`」,與 `docs/audit/` **不一致**。 +- 重複與衝突見 `docs/audit/engineering.md` §8.2;mattpocock 殘留與引用見 §9。 +- ADR/`CONTEXT.md` 的引用還出現在 `.github/workflows/release.yml`、`tool/release/verify_release_assets.dart`、`test/workflows/*`、`lib/data/repositories/lyrics_repository.dart`、`search_history_repository.dart`。 +- 採用的慣例:Diátaxis(反對預建空結構)、agents.md、MADR(design.md 詳述)。 + +## 需求 + +- R1 三者分工:`.trellis/spec/` 寫「這一層的程式碼怎麼寫」、不寫歷史;task `design.md` 寫「這次任務怎麼做」、隨任務歸檔;`docs/adr/` 寫「跨模組決定的理由與被否決的方案」、長期保留。 +- R2 新架構的每個重大決定各寫一份 ADR,從 0008 接續、不重用編號,用 `docs/adr/template.md`(含「如何確認」一節)。 +- R3 舊 ADR 被新 ADR 推翻或不再適用時,同一個 commit 刪除舊檔、改掉所有引用、以 `git grep` 確認;確認沿用的保留(必要時改寫)。各份處理見 design.md §4。 +- R4 `CONTEXT.md` 的原則併入第 12 項的 ADR 與 spec,術語隨新設計命名;階段三刪除 `CONTEXT.md` 並改掉引用。 +- R5 人類文檔依 Diátaxis 分類,不預建空資料夾;`docs/README.md` 地圖標出每份文件的類型。 +- R6 mattpocock 殘留在階段三移除(`docs/agents/`、AGENTS.md「Agent skills」段、`docs/README.md:21,23`);「issue 用繁中撰寫」搬一句進 AGENTS.md。 +- R7 語言(使用者 2026-09-27 決定):所有文檔繁中,包括 `AGENTS.md`、`.trellis/spec/`、ADR、`docs/`;程式碼識別字、指令、檔名、log 字串、commit message 保留原文;README 維持英/繁雙語。`docs/README.md:21` 的中英分工規則刪除。 +- R8 `docs/audit/`(使用者 2026-09-27 決定):重寫期間凍結保留、只允許核查更正,作為完成定義的基準;最後一個里程碑的 PR 刪除,並恢復「審查記錄不進 `docs/`」無例外。 +- R9 AGENTS.md 的每條規則都要附守著它的 test 或 lint,否則補閘門或刪除。 + +## 驗收標準 + +- [ ] `design.md` 給出目標文檔地圖、規則放置表、ADR 機制、舊 ADR 與 `CONTEXT.md` 的逐項處理、`docs/audit/` 生命週期、階段三衝突清單。 +- [ ] `docs/adr/template.md` 存在,章節與 design.md §3 一致。 +- [ ] `implement.md` 列出階段三的執行步驟與 `git grep` 驗證指令。 +- [ ] `phase2-plan.md` 標記第 9 項完成。 + +## 範圍外 + +- 各設計項目本身的 ADR 內容(在各自的項目裡寫)。 +- 階段三的實際執行(刪檔、改引用、翻譯)另開 child task。 +- 本任務不改 `AGENTS.md`、`docs/README.md`、`.trellis/spec/`。 diff --git a/.trellis/tasks/09-27-design-docs/task.json b/.trellis/tasks/09-27-design-docs/task.json new file mode 100644 index 000000000..90b9bed02 --- /dev/null +++ b/.trellis/tasks/09-27-design-docs/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-docs", + "name": "design-docs", + "title": "Design: docs structure and ADR disposition", + "description": "Phase-2 item 9: target doc structure for humans and agents, ADR mechanism, and disposition of old ADRs and CONTEXT.md", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 1783f4bfba64f9930ac7384a95ddc470ce090faa Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:45:01 +0800 Subject: [PATCH 008/133] docs(adr): add the ADR template for the rewrite decisions --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .trellis/tasks/09-27-design-docs/implement.md | 6 +-- .trellis/tasks/09-27-design-docs/prd.md | 8 ++-- .trellis/tasks/09-27-design-docs/task.json | 4 +- docs/adr/template.md | 39 +++++++++++++++++++ 6 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 docs/adr/template.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 454085ddc..680156652 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -110,7 +110,7 @@ flowchart LR | 順序 | 項目 | 為什麼排這裡 | |---|---|---| -| 1 | 9 文檔結構/ADR 去留 | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | +| 1 | 9 文檔結構/ADR 去留(✅ 完成,見 `archive/2026-09/09-27-design-docs`) | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | | 2 | 7 重寫策略(高層) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | | 3 | 10 平台層 | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | | 4 | 6 資料層與相容 | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 219c679cd..062a165f3 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -19,7 +19,8 @@ "pr_url": null, "subtasks": [], "children": [ - "09-26-audit" + "09-26-audit", + "09-27-design-docs" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-docs/implement.md b/.trellis/tasks/09-27-design-docs/implement.md index e6176625a..e0e1b6edc 100644 --- a/.trellis/tasks/09-27-design-docs/implement.md +++ b/.trellis/tasks/09-27-design-docs/implement.md @@ -4,9 +4,9 @@ ## A. 本任務核准後立即做 -- [ ] 在 `docs/adr/` 新增 `template.md`(design.md §3 的章節)。之後第 1 項起的 ADR 都從它複製。 -- [ ] `phase2-plan.md` 把第 9 項標為完成,並連到本任務。 -- [ ] 歸檔本任務。 +- [x] 在 `docs/adr/` 新增 `template.md`(design.md §3 的章節)。之後第 1 項起的 ADR 都從它複製。 +- [x] `phase2-plan.md` 把第 9 項標為完成,並連到本任務。 +- [x] 歸檔本任務。 不動 `AGENTS.md`、`docs/README.md`、`.trellis/spec/`:它們描述的是舊程式碼,在階段三與各里程碑改寫。 diff --git a/.trellis/tasks/09-27-design-docs/prd.md b/.trellis/tasks/09-27-design-docs/prd.md index bb0386014..84051a559 100644 --- a/.trellis/tasks/09-27-design-docs/prd.md +++ b/.trellis/tasks/09-27-design-docs/prd.md @@ -31,10 +31,10 @@ ## 驗收標準 -- [ ] `design.md` 給出目標文檔地圖、規則放置表、ADR 機制、舊 ADR 與 `CONTEXT.md` 的逐項處理、`docs/audit/` 生命週期、階段三衝突清單。 -- [ ] `docs/adr/template.md` 存在,章節與 design.md §3 一致。 -- [ ] `implement.md` 列出階段三的執行步驟與 `git grep` 驗證指令。 -- [ ] `phase2-plan.md` 標記第 9 項完成。 +- [x] `design.md` 給出目標文檔地圖、規則放置表、ADR 機制、舊 ADR 與 `CONTEXT.md` 的逐項處理、`docs/audit/` 生命週期、階段三衝突清單。 +- [x] `docs/adr/template.md` 存在,章節與 design.md §3 一致。 +- [x] `implement.md` 列出階段三的執行步驟與 `git grep` 驗證指令。 +- [x] `phase2-plan.md` 標記第 9 項完成。 ## 範圍外 diff --git a/.trellis/tasks/09-27-design-docs/task.json b/.trellis/tasks/09-27-design-docs/task.json index 90b9bed02..b8890e692 100644 --- a/.trellis/tasks/09-27-design-docs/task.json +++ b/.trellis/tasks/09-27-design-docs/task.json @@ -3,7 +3,7 @@ "name": "design-docs", "title": "Design: docs structure and ADR disposition", "description": "Phase-2 item 9: target doc structure for humans and agents, ADR mechanism, and disposition of old ADRs and CONTEXT.md", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/template.md b/docs/adr/template.md new file mode 100644 index 000000000..09a96e40e --- /dev/null +++ b/docs/adr/template.md @@ -0,0 +1,39 @@ +# NNNN — 問題與選擇(一句話) + + + +- 狀態:提議中/已採納 +- 日期:YYYY-MM-DD +- 影響範圍:受影響的目錄、資料格式或流程 + +## 背景 + +要解決什麼問題、為什麼現在要決定。取代舊 ADR 時,寫明舊的是哪一份、原本決定了什麼。 + +## 考慮過的選項 + +### 選項 A:名稱 + +做法、優點、缺點。 + +### 選項 B:名稱 + +做法、優點、缺點。 + +## 決定 + +選了哪一個、為什麼;寫明採用了誰的慣例(官方指南、其他專案)。 + +## 後果 + +- 好的: +- 壞的: +- 之後要注意: + +## 如何確認 + +守著這個決定的 test、lint 或 review 點。沒有閘門的決定,寫明為什麼不需要,或什麼時候補。 From 3d55335fdccb12bea989994c8bc1dd958bcffb9e Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:45:02 +0800 Subject: [PATCH 009/133] chore(task): archive design-docs --- .../tasks/{ => archive/2026-09}/09-27-design-docs/check.jsonl | 0 .../tasks/{ => archive/2026-09}/09-27-design-docs/design.md | 0 .../{ => archive/2026-09}/09-27-design-docs/implement.jsonl | 0 .../{ => archive/2026-09}/09-27-design-docs/implement.md | 0 .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/prd.md | 0 .../tasks/{ => archive/2026-09}/09-27-design-docs/task.json | 4 ++-- 6 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-docs/task.json (91%) diff --git a/.trellis/tasks/09-27-design-docs/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-docs/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-docs/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-docs/check.jsonl diff --git a/.trellis/tasks/09-27-design-docs/design.md b/.trellis/tasks/archive/2026-09/09-27-design-docs/design.md similarity index 100% rename from .trellis/tasks/09-27-design-docs/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-docs/design.md diff --git a/.trellis/tasks/09-27-design-docs/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-docs/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-docs/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-docs/implement.jsonl diff --git a/.trellis/tasks/09-27-design-docs/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-docs/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-docs/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-docs/implement.md diff --git a/.trellis/tasks/09-27-design-docs/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-docs/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-docs/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-docs/prd.md diff --git a/.trellis/tasks/09-27-design-docs/task.json b/.trellis/tasks/archive/2026-09/09-27-design-docs/task.json similarity index 91% rename from .trellis/tasks/09-27-design-docs/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-docs/task.json index b8890e692..6f81a18c4 100644 --- a/.trellis/tasks/09-27-design-docs/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-docs/task.json @@ -3,7 +3,7 @@ "name": "design-docs", "title": "Design: docs structure and ADR disposition", "description": "Phase-2 item 9: target doc structure for humans and agents, ADR mechanism, and disposition of old ADRs and CONTEXT.md", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From c605a7d5351eac14a6c927e37f6936ad34e26f0a Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:48:34 +0800 Subject: [PATCH 010/133] chore(task): plan phase-two item 7 (rewrite strategy, high level) --- .../09-27-design-rewrite-strategy/check.jsonl | 0 .../09-27-design-rewrite-strategy/design.md | 69 +++++++++++++++++++ .../implement.jsonl | 0 .../implement.md | 9 +++ .../09-27-design-rewrite-strategy/prd.md | 52 ++++++++++++++ .../09-27-design-rewrite-strategy/task.json | 26 +++++++ 6 files changed, 156 insertions(+) create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/check.jsonl create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/design.md create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/implement.md create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/prd.md create mode 100644 .trellis/tasks/09-27-design-rewrite-strategy/task.json diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/check.jsonl b/.trellis/tasks/09-27-design-rewrite-strategy/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/design.md b/.trellis/tasks/09-27-design-rewrite-strategy/design.md new file mode 100644 index 000000000..844a58321 --- /dev/null +++ b/.trellis/tasks/09-27-design-rewrite-strategy/design.md @@ -0,0 +1,69 @@ +# 設計:重寫策略(高層) + +## 1. 決定摘要 + +| # | 決定 | 來源 | +|---|---|---| +| D1 | 全新骨架+搬運葉節點邏輯,不走逐步替換 | 使用者 2026-09-27 | +| D2 | 同一 repo 的 `main`,新專案在子目錄 `app/`;不開長期分支、不開新 repo | 使用者 2026-09-27 | +| D3 | 新 App 沿用舊 App 的身分識別 | 由 A3(全部自動遷移)推出 | + +這三條會在本項核准後寫成一份 ADR(0008)。 + +## 2. 目錄形狀 + +```mermaid +flowchart TB + subgraph 重寫期間 + R[repo 根目錄
    舊專案 lib/ test/ android/ windows/ tool/ pubspec.yaml
    凍結,只收緊急修正] + A[app/
    新專案:新架構
    每個里程碑一個 PR 合進 main] + D[docs/ docs/adr/ docs/audit/] + end + subgraph 切換之後 + A2[app/ 成為唯一專案] + D2[docs/ docs/adr/(docs/audit/ 刪除)] + end + A --> A2 + R -.->|切換 PR| G[刪除] +``` + +- `app/` 是之後的永久位置,切換時只刪舊專案,不搬目錄。 +- 葉節點邏輯**複製**進 `app/`(連同測試)後依新介面調整,不從 `app/` import 根目錄的程式碼。新舊之間沒有共用程式碼,也就沒有過渡層。 +- `app/` 有自己的 `AGENTS.md`(agents.md 慣例:agent 讀最近的那一份),寫新架構的規則;根目錄 `AGENTS.md` 保留給舊專案的緊急修正,並加一句指向 `app/AGENTS.md`。Trellis spec 的分法在第 8 項定(可用 Trellis 的 package 範圍)。 + +## 3. App 身分識別 + +新 App 必須和舊 App 同一個身分,理由:Android 只有同一個 `applicationId`+簽名金鑰才能讀舊 App 私有目錄裡的資料庫與 Keystore 保護的憑證;使用者的舊版才能直接升級成新版。 + +| 項目 | 現值 | 位置 | +|---|---|---| +| Android `applicationId`/`namespace` | `com.personal.fmp` | `android/app/build.gradle.kts:19,29` | +| Android 簽名金鑰 | 由 release secrets 提供 | `docs/build-and-release.md` | +| Windows AppUserModelID | `com.personal.fmp` | `windows/runner/main.cpp:43` | +| Windows 安裝包 AppId(Inno Setup) | `BAF6CE8D-E1C8-4C29-AE0B-EDE98D5F8FAA`(註解:發布後不可改) | `pubspec.yaml:121-122` | + +開發版用不同的身分(U9,第 8 項定細節),與正式版可以同時存在、互不碰資料。 + +## 4. 舊版緊急修正與發版 + +- 重寫期間不發正式版。 +- 舊版需要緊急修正時:在 `main` 上改根目錄舊專案,走一般 PR,照舊用 `vX.Y.Z` tag 觸發 `release.yml` 發版(release workflow 只建根目錄專案,不受 `app/` 影響)。這是例外,每次都先問使用者。 +- 已決定不做的:N1 資料遺失不在舊版修(questions.md)。 +- 新 App 第一次正式發版=切換那一版:版本號接在舊版之後,舊版使用者透過應用內更新拿到它,首次啟動執行自動遷移(第 6 項設計)。 + +## 5. CI + +- 現況:`ci.yml` 刻意不設路徑過濾(`ci.yml:3-7`,理由是純文字 commit 也可能改到有測試守的規則),全跑約 23 分鐘。 +- 重寫期間要新增 `app/` 的 validate/build job。舊專案的 job 是否只在根目錄檔案變動時才跑、以及 main 上那個時序不穩的舊測試(`account_repository_test.dart:105-118`)會不會一直擋新 PR,在第 8 項決定。 + 若第 8 項之前就開始寫 `app/`,先讓舊專案 job 照跑,遇到那個不穩的測試就重跑。 + +## 6. 切換(cutover) + +條件(完成定義):`features.md` 勾「保留」的功能在 `app/` 全部跑通;效能不低於 `perf-baseline.md`;舊資料自動遷移在真實資料副本上驗證過。 + +切換 PR 做的事:刪除根目錄舊專案與 `docs/audit/`;`release.yml`、`ci.yml`、`orca.yaml`、`tool/release/` 改指向 `app/`;根目錄 `AGENTS.md` 併入 `app/AGENTS.md` 或改為指路;舊 ADR 依第 9 項規則收尾。 + +## 7. 延後到第 7 項定稿 + +- 里程碑拆分與每個 child task 的範圍,包括第一個 tracer bullet 用哪個音源、跨哪些層。 +- 各里程碑的驗收方式與效能量測時點。 diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/implement.jsonl b/.trellis/tasks/09-27-design-rewrite-strategy/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/implement.md b/.trellis/tasks/09-27-design-rewrite-strategy/implement.md new file mode 100644 index 000000000..3fa569044 --- /dev/null +++ b/.trellis/tasks/09-27-design-rewrite-strategy/implement.md @@ -0,0 +1,9 @@ +# 執行計畫 + +本任務只產出設計與 ADR;不建立 `app/`(第一個里程碑才建)。 + +- [ ] 依 `docs/adr/template.md` 寫 `docs/adr/0008-rewrite-as-new-app-in-same-repo.md`,內容取自 design.md §1–§6,含被否決的選項(逐步替換、長期分支、新 repo)與「如何確認」。 +- [ ] `phase2-plan.md` 把第 7 項(高層)標為完成,註明里程碑拆分留到定稿。 +- [ ] 歸檔本任務。 + +驗證:ADR 的 Mermaid 圖(若有)以 mermaid-cli 渲染一次;`git grep` 確認 ADR 內引用的檔案與行號存在。 diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/prd.md b/.trellis/tasks/09-27-design-rewrite-strategy/prd.md new file mode 100644 index 000000000..10fa1be9e --- /dev/null +++ b/.trellis/tasks/09-27-design-rewrite-strategy/prd.md @@ -0,0 +1,52 @@ +# 設計第 7 項(高層):重寫策略 + +## 目標 + +決定「全新重寫」還是「在現有程式碼上逐步替換」,以及對應的程式碼位置、分支、發版與舊版修正的路徑。 +這裡只定方向;里程碑拆分在階段二最後(第 7 項定稿)做。 + +需求來源:parent `prd.md` 階段二第 7 項、「重構過程的約束」;`phase2-plan.md`。 + +## 已確認的約束(使用者已定) + +- 每個 child task 一個 PR、大小可 review、附 review 指南;沒有經確認的 ADR 的設計不進程式碼。 +- 功能凍結:重寫期間不加新功能。 +- 完成定義:`features.md` 勾「保留」的功能全部在新架構跑通,效能不低於 `perf-baseline.md`。 +- 重寫期間不發正式版本;N1(現行版資料遺失)選「先不修,重寫時處理」。 +- 資料相容:資料庫、憑證、下載檔全部自動遷移,舊備份可匯入(questions.md A3)。 +- 第一版目標平台 Android+Windows,Linux/macOS/iOS 之後加入(A1)。 +- 使用者全域規則:tracer bullet,每一步結束 repo 都可運作;內部改動不留相容層。 + +## 現況(證據) + +- `lib/` 343 檔 99,063 行;最大的是 `audio_provider.dart` 2,953 行、`youtube_source.dart` 2,431 行、`download_service.dart` 2,030 行(`docs/audit/architecture.md` §2)。 +- 新架構預計改動的範圍幾乎涵蓋每一層:資料層可能換庫(A2)、provider 結構(G6)、音源插件(G3)、平台層(§8)、錯誤模型(G4)、播放核心(G1、G5)。 +- 可直接沿用價值高的「葉節點」邏輯:各音源的 API 呼叫、簽名與加密(`netease_crypto.dart`、WBI、InnerTube)、解析器、`TrackKey` 持久化格式(ADR 0005),以及 1,849 個離線測試中測這些行為的部分。 +- 離線測試本機全過;main 的 CI 目前因一個時序測試失敗(`docs/audit/engineering.md` §12)。 + +## 採用的慣例 + +- Martin Fowler〈Strangler Fig Application〉:逐步把行為從舊系統搬到新系統,用 seam 與過渡架構讓兩者並存;他觀察到一次性整體重寫多半失敗,理由包括使用者等不了新功能、舊行為難以釐清。 +- 本專案與 Fowler 前提的差異:功能凍結且不發版(使用者等新功能的壓力不存在);舊行為已在 `docs/audit/` 盤點並經使用者逐項勾選。 + +## 已決定 + +- D1(使用者 2026-09-27):**全新骨架+搬運葉節點邏輯**。同一 repo 另建新 Flutter 專案,依新架構搭骨架; + 已被測試證明的底層邏輯(音源 API 呼叫、簽名與加密、解析器、`TrackKey` 格式)連同其測試搬入,不重寫。 + 第一個里程碑是 tracer bullet:一個音源搜尋並播放,在 Android 與 Windows 跑通,之後逐層加能力。 + 舊 App 原封不動保留,新 App 功能齊全後切換。「每個里程碑 App 都能運作」指新 App 已有的功能完整可用; + 重寫期間使用者日常使用舊版。 + +- D2(使用者 2026-09-27):同一 repo 的 `main`,新專案放子目錄 `app/`(永久位置);不開長期分支、不開新 repo。舊版緊急修正在 `main` 上改根目錄舊專案,照舊以 tag 發版,每次先問使用者。 +- D3(由 A3 推出):新 App 沿用舊 App 身分識別(Android `applicationId` `com.personal.fmp` 與簽名金鑰、Windows AppUserModelID、Inno Setup AppId),否則讀不到舊資料、舊版也無法直接升級。開發版另用身分(U9)。 + +## 驗收標準 + +- [ ] `design.md` 涵蓋目錄形狀、App 身分識別、舊版修正與發版、CI、切換條件與步驟,以及延後到定稿的項目。 +- [ ] `docs/adr/0008-*.md` 依範本寫成,含被否決的選項與「如何確認」。 +- [ ] `phase2-plan.md` 標記第 7 項(高層)完成。 + +## 範圍外(延後到第 7 項定稿) + +- 里程碑拆分、第一個 tracer bullet 的音源與範圍、各里程碑驗收方式。 +- CI 對新舊兩個專案的觸發策略與不穩測試的處理(第 8 項)。 diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/task.json b/.trellis/tasks/09-27-design-rewrite-strategy/task.json new file mode 100644 index 000000000..cf21c9418 --- /dev/null +++ b/.trellis/tasks/09-27-design-rewrite-strategy/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-rewrite-strategy", + "name": "design-rewrite-strategy", + "title": "Design: rewrite strategy (high level)", + "description": "Phase-2 item 7 (high level): greenfield vs incremental replacement, branch and release strategy, legacy hotfix path", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From b63d1de477ba04183ae1074380eb5e74a569f9c4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:49:41 +0800 Subject: [PATCH 011/133] docs(adr): 0008 rewrite as a new app in the same repo --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../implement.md | 6 +- .../09-27-design-rewrite-strategy/prd.md | 6 +- .../09-27-design-rewrite-strategy/task.json | 4 +- .../0008-rewrite-as-new-app-in-same-repo.md | 72 +++++++++++++++++++ 6 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 docs/adr/0008-rewrite-as-new-app-in-same-repo.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 680156652..5f2127100 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -111,7 +111,7 @@ flowchart LR | 順序 | 項目 | 為什麼排這裡 | |---|---|---| | 1 | 9 文檔結構/ADR 去留(✅ 完成,見 `archive/2026-09/09-27-design-docs`) | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | -| 2 | 7 重寫策略(高層) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | +| 2 | 7 重寫策略(高層)(✅ 完成,ADR 0008;里程碑留到第 20 步定稿) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | | 3 | 10 平台層 | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | | 4 | 6 資料層與相容 | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | | 5 | 18 設定與日誌 | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 062a165f3..5ba1499ab 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -20,7 +20,8 @@ "subtasks": [], "children": [ "09-26-audit", - "09-27-design-docs" + "09-27-design-docs", + "09-27-design-rewrite-strategy" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/implement.md b/.trellis/tasks/09-27-design-rewrite-strategy/implement.md index 3fa569044..08b2f9d91 100644 --- a/.trellis/tasks/09-27-design-rewrite-strategy/implement.md +++ b/.trellis/tasks/09-27-design-rewrite-strategy/implement.md @@ -2,8 +2,8 @@ 本任務只產出設計與 ADR;不建立 `app/`(第一個里程碑才建)。 -- [ ] 依 `docs/adr/template.md` 寫 `docs/adr/0008-rewrite-as-new-app-in-same-repo.md`,內容取自 design.md §1–§6,含被否決的選項(逐步替換、長期分支、新 repo)與「如何確認」。 -- [ ] `phase2-plan.md` 把第 7 項(高層)標為完成,註明里程碑拆分留到定稿。 -- [ ] 歸檔本任務。 +- [x] 依 `docs/adr/template.md` 寫 `docs/adr/0008-rewrite-as-new-app-in-same-repo.md`,內容取自 design.md §1–§6,含被否決的選項(逐步替換、長期分支、新 repo)與「如何確認」。 +- [x] `phase2-plan.md` 把第 7 項(高層)標為完成,註明里程碑拆分留到定稿。 +- [x] 歸檔本任務。 驗證:ADR 的 Mermaid 圖(若有)以 mermaid-cli 渲染一次;`git grep` 確認 ADR 內引用的檔案與行號存在。 diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/prd.md b/.trellis/tasks/09-27-design-rewrite-strategy/prd.md index 10fa1be9e..151504c32 100644 --- a/.trellis/tasks/09-27-design-rewrite-strategy/prd.md +++ b/.trellis/tasks/09-27-design-rewrite-strategy/prd.md @@ -42,9 +42,9 @@ ## 驗收標準 -- [ ] `design.md` 涵蓋目錄形狀、App 身分識別、舊版修正與發版、CI、切換條件與步驟,以及延後到定稿的項目。 -- [ ] `docs/adr/0008-*.md` 依範本寫成,含被否決的選項與「如何確認」。 -- [ ] `phase2-plan.md` 標記第 7 項(高層)完成。 +- [x] `design.md` 涵蓋目錄形狀、App 身分識別、舊版修正與發版、CI、切換條件與步驟,以及延後到定稿的項目。 +- [x] `docs/adr/0008-*.md` 依範本寫成,含被否決的選項與「如何確認」。 +- [x] `phase2-plan.md` 標記第 7 項(高層)完成。 ## 範圍外(延後到第 7 項定稿) diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/task.json b/.trellis/tasks/09-27-design-rewrite-strategy/task.json index cf21c9418..63ed39725 100644 --- a/.trellis/tasks/09-27-design-rewrite-strategy/task.json +++ b/.trellis/tasks/09-27-design-rewrite-strategy/task.json @@ -3,7 +3,7 @@ "name": "design-rewrite-strategy", "title": "Design: rewrite strategy (high level)", "description": "Phase-2 item 7 (high level): greenfield vs incremental replacement, branch and release strategy, legacy hotfix path", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md new file mode 100644 index 000000000..33642e433 --- /dev/null +++ b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md @@ -0,0 +1,72 @@ +# 0008 — 重寫:在同一 repo 的 `app/` 另建新專案,搬運葉節點邏輯 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:repo 目錄結構、`.github/workflows/`、`orca.yaml`、`AGENTS.md`、App 身分識別、舊版發版流程 + +## 背景 + +FMP 經過多輪 AI agent 自主修改(`lib/` 343 檔 99,063 行),擁有者已不清楚程式實際在做什麼。 +2026-09 的現況審計(`docs/audit/`)顯示,新架構要改動的範圍幾乎涵蓋每一層: +資料層可能換庫、音源要插件化、平台差異要收進單一平台層、錯誤模型要統一、 +2,953 行的 `AudioController` 要拆(`docs/audit/architecture.md`、`docs/audit/questions.md`)。 + +限制條件(擁有者已定):重寫期間功能凍結、不發正式版;舊資料庫、憑證、下載檔全部自動遷移; +第一版目標平台 Android+Windows;每個任務一個可 review 的 PR。 + +## 考慮過的選項 + +### 選項 A:在現有程式碼上逐步替換(Strangler Fig) + +一塊一塊換成新架構,新舊並存,每次合併後現行 App 都完整可用。 +優點:沒有「新 App 功能不齊」的階段。 +缺點:幾乎每一層都要換,換資料層期間新舊兩套資料存取必須同步;過渡程式碼大量出現且最後要丟, +違反「內部改動不留相容層」;舊架構的循環依賴與上帝類別會拖住新設計;PR 較難 review。 + +### 選項 B:全新骨架+搬運葉節點邏輯(採用) + +同一 repo 另建新 Flutter 專案,依新架構搭骨架;已被測試證明的葉節點邏輯(音源 API 呼叫、 +簽名與加密、解析器、`TrackKey` 持久化格式)連同測試複製進來再依新介面調整。 +優點:沒有過渡層;新架構不受舊形狀牽制;避開整體重寫最大的風險——把能用的東西重寫一遍再寫壞。 +缺點:新 App 功能齊全前,擁有者日常仍用舊版;repo 裡暫時有兩個 Flutter 專案。 + +### 位置的子選項 + +- **長期 `rewrite` 分支**:`main` 乾淨,但分支越久最後合併越痛,舊版修正要同步兩邊。否決。 +- **另開新 repo**:完全隔離,但 issue、release、Actions secrets 與自動更新的 release 來源都要搬。否決。 +- **同一 repo 的 `main`、子目錄 `app/`**:採用。 + +## 決定 + +1. **全新骨架+搬運葉節點邏輯**(選項 B)。葉節點是**複製**,`app/` 不 import 根目錄舊專案的任何程式碼。 + 第一個里程碑是 tracer bullet:一個音源能搜尋並播放,在 Android 與 Windows 跑通,之後逐層加能力。 +2. **位置**:同一 repo 的 `main`,新專案在 `app/`,這也是它的永久位置;舊專案留在根目錄、凍結。 + `app/` 有自己的 `AGENTS.md`(agents.md 慣例:agent 讀離它最近的那一份)。 +3. **App 身分沿用**:新 App 使用與舊 App 相同的身分識別——Android `applicationId` `com.personal.fmp` + (`android/app/build.gradle.kts:29`)與同一把簽名金鑰、Windows AppUserModelID `com.personal.fmp` + (`windows/runner/main.cpp:43`)、Inno Setup AppId(`pubspec.yaml:121-122`)。 + 只有同一身分,Android 上才讀得到舊 App 私有目錄的資料庫與 Keystore 保護的憑證,舊版也才能直接升級。 + 開發版另用身分,與正式版分開。 +4. **舊版緊急修正**:在 `main` 上改根目錄舊專案、走一般 PR、照舊以 `vX.Y.Z` tag 發版;每次先經擁有者同意。 +5. **切換**:`docs/audit/features.md` 中勾「保留」的功能全部在 `app/` 跑通、效能不低於 + `docs/audit/perf-baseline.md`、舊資料自動遷移在真實資料副本上驗證過之後,以一個 PR 刪除根目錄舊專案與 + `docs/audit/`,並把 `release.yml`、`ci.yml`、`orca.yaml`、`tool/release/` 改指向 `app/`。 + 新 App 的第一個正式版本號接在舊版之後,經應用內更新送達,首次啟動執行自動遷移。 + +採用的慣例:以 Martin Fowler〈Strangler Fig Application〉為對照;他反對整體重寫的主要理由 +(使用者等不了新功能、舊行為難以釐清)在這裡不成立——功能凍結且不發版,舊行為已盤點並經擁有者逐項勾選。 +主幹開發(不開長期分支)與 agents.md 的巢狀 `AGENTS.md` 慣例。 + +## 後果 + +- 好的:每個里程碑是可 review 的小 PR,直接合進 `main`;沒有過渡程式碼;舊版隨時可以緊急修正並發版。 +- 壞的:重寫期間 CI 要跑兩個專案,時間變長;兩份 `AGENTS.md` 要各自寫清楚適用範圍; + 新 App 功能齊全前不能取代舊版。 +- 之後要注意:新 App 的身分識別一旦與舊版不同就無法自動遷移,任何改動 `applicationId`、簽名、AppId 的變更都必須另立 ADR。 + CI 如何同時處理兩個專案、舊專案不穩的測試是否擋 PR,由測試策略的 ADR 決定。 + +## 如何確認 + +- `app/` 不得 import 根目錄舊專案:由 `app/` 的 analyzer 設定與 import lint 守(測試策略 ADR 落實時加上);在那之前靠 PR review。 +- App 身分識別:切換前的里程碑加一項檢查,比對 `app/` 的 `applicationId`、AppUserModelID、Inno Setup AppId 與上列現值一致。 +- 切換條件:切換 PR 的 review 指南逐項列出 `features.md` 勾「保留」的功能與效能量測結果。 From 7d35d0de2d437f69dbc8520579385d14292f44fd Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 02:49:42 +0800 Subject: [PATCH 012/133] chore(task): archive design-rewrite-strategy --- .../2026-09}/09-27-design-rewrite-strategy/check.jsonl | 0 .../2026-09}/09-27-design-rewrite-strategy/design.md | 0 .../2026-09}/09-27-design-rewrite-strategy/implement.jsonl | 0 .../2026-09}/09-27-design-rewrite-strategy/implement.md | 0 .../2026-09}/09-27-design-rewrite-strategy/prd.md | 0 .../2026-09}/09-27-design-rewrite-strategy/task.json | 4 ++-- 6 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-rewrite-strategy/task.json (92%) diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-rewrite-strategy/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/check.jsonl diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/design.md b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/design.md similarity index 100% rename from .trellis/tasks/09-27-design-rewrite-strategy/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/design.md diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-rewrite-strategy/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/implement.jsonl diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-rewrite-strategy/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/implement.md diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-rewrite-strategy/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/prd.md diff --git a/.trellis/tasks/09-27-design-rewrite-strategy/task.json b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/task.json similarity index 92% rename from .trellis/tasks/09-27-design-rewrite-strategy/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/task.json index 63ed39725..3aff63485 100644 --- a/.trellis/tasks/09-27-design-rewrite-strategy/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-rewrite-strategy/task.json @@ -3,7 +3,7 @@ "name": "design-rewrite-strategy", "title": "Design: rewrite strategy (high level)", "description": "Phase-2 item 7 (high level): greenfield vs incremental replacement, branch and release strategy, legacy hotfix path", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From e4148beb406351189897b9dbe3dcaaeafe8f193c Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 03:29:04 +0800 Subject: [PATCH 013/133] chore(task): plan phase-two item 10 (platform layer) --- .../tasks/09-27-design-platform/check.jsonl | 0 .../tasks/09-27-design-platform/design.md | 113 +++++ .../09-27-design-platform/implement.jsonl | 0 .../tasks/09-27-design-platform/implement.md | 9 + .trellis/tasks/09-27-design-platform/prd.md | 62 +++ .../research/platform-packages.md | 422 ++++++++++++++++++ .../research/platform-policy-and-peers.md | 373 ++++++++++++++++ .../tasks/09-27-design-platform/task.json | 26 ++ 8 files changed, 1005 insertions(+) create mode 100644 .trellis/tasks/09-27-design-platform/check.jsonl create mode 100644 .trellis/tasks/09-27-design-platform/design.md create mode 100644 .trellis/tasks/09-27-design-platform/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-platform/implement.md create mode 100644 .trellis/tasks/09-27-design-platform/prd.md create mode 100644 .trellis/tasks/09-27-design-platform/research/platform-packages.md create mode 100644 .trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md create mode 100644 .trellis/tasks/09-27-design-platform/task.json diff --git a/.trellis/tasks/09-27-design-platform/check.jsonl b/.trellis/tasks/09-27-design-platform/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-platform/design.md b/.trellis/tasks/09-27-design-platform/design.md new file mode 100644 index 000000000..9c34e6812 --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/design.md @@ -0,0 +1,113 @@ +# 設計:平台層 + +採用的慣例:Namida 的 `lib/controller/platform/`(每個能力一個目錄:共用介面+各平台實作+工廠); +Flutter 官方 federated plugin 的「共用介面+各平台實作」切法;官方對平台分支的建議 +(純 Dart 分支用 `defaultTargetPlatform`,呼叫原生 API 才用 platform channel,新 channel 用 Pigeon)。 + +## 1. 形狀 + +```mermaid +flowchart TB + subgraph UI與service + U[頁面/service] + end + subgraph 平台層 app/lib/platform/ + C[PlatformCapabilities
    一個不可變的值:這個平台有什麼] + F[各能力的工廠
    依 defaultTargetPlatform 選實作] + subgraph 能力 + T[tray/] + H[hotkeys/] + M[media_controls/] + S[single_instance/] + W[lyrics_window/] + P[storage_paths/] + UPD[self_update/] + L[login_webview/] + PERM[permissions/] + end + end + U -->|讀| C + U -->|呼叫介面| F + F --> T & H & M & S & W & P & UPD & L & PERM +``` + +- 每個能力一個目錄:`<能力>.dart`(介面+工廠)、`<能力>_<平台>.dart`(實作)。第三方平台套件 + (`tray_manager`、`window_manager`、`hotkey_manager`、`smtc_windows`…)只在這些實作檔裡 import。 +- `PlatformCapabilities` 是每個平台一份的宣告:有沒有托盤、全域快捷鍵、開機自啟、單一實例、 + 桌面歌詞視窗、自訂標題列、系統媒體控制(哪一種)、應用內更新(哪一種)、登入 WebView(能不能讀 cookie)、 + 需要的執行期權限、資料與下載目錄的規則。UI 只看這份宣告決定顯示哪些入口;service 只呼叫介面。 +- 一個能力若要在執行期才知道(例如 Linux 在 Wayland 下沒有全域快捷鍵),由該平台實作在啟動時判斷後寫進宣告,外面看到的仍是一個布林值。 +- **平台層以外不得出現** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform`,也不得 import 上述平台套件。閘門:Dart analyzer lint(第 8 項選定工具後落實);在那之前靠 review。 +- 新增原生呼叫(MethodChannel)一律用 Pigeon 產生,不手寫字串 channel。 + +## 2. 不寫空實作 + +還沒驗證的平台,**宣告**全部能力為「沒有」,不寫任何實作檔;App 在該平台只有核心功能(依第 13 項的播放後端而定)。 +某個平台的 child task 開始時,才加入它的實作並把宣告改成真值。這讓 Linux/macOS/iOS 從第一個里程碑就能編譯, +又不會有沒人驗證過的程式碼。 + +## 3. 各能力的套件與平台 + +✅ 採用|⏳ 該平台 child task 時接上|✖ 不提供(原因) + +| 能力 | Android | Windows | Linux | macOS | iOS | 套件 | +|---|---|---|---|---|---|---| +| 系統媒體控制 | ✅ | ✅ | ⏳ | ⏳ | ⏳ | `audio_service`(Android/iOS/macOS);Windows `smtc_windows` 或 `audio_service_win`(第 13 項比較,重點是 seek);Linux `audio_service_mpris` | +| 托盤 | ✖ 無此概念 | ✅ | ⏳ | ⏳ | ✖ | `tray_manager` | +| 視窗管理、自訂標題列 | ✖ | ✅ | ⏳ | ⏳ 保留系統紅綠燈按鈕 | ✖ | `window_manager` | +| 全域快捷鍵 | ✖ | ✅ | ⏳ 僅 X11;Wayland 為協定限制 ✖ | ⏳ | ✖ | `hotkey_manager` | +| 開機自啟 | ✖ | ✅ | ⏳ | ⏳ 需 macOS 13+ | ✖ | 維持 `launch_at_startup`;Linux/macOS 接上時與 `auto_start_flutter` 比較 | +| 單一實例 | ✖ 系統本身單例 | ✅ | ⏳ | ⏳ | ✖ | Windows 先沿用 runner 的具名 mutex(搬進新 runner);Linux/macOS 接上時評估 `flutter_single_instance`(先讀原始碼) | +| 桌面歌詞視窗 | ✖ | ✅ | ⏳ | ⏳ | ✖ | `desktop_multi_window` | +| 登入 WebView | ✅ | ✅ | ⏳ 選型在第 12 項 | ⏳ | ⏳ | 行動端與 Windows 暫定 `flutter_inappwebview`;Linux 候選 `webview_cef`(能讀 cookie);沒有 WebView 時改用 QR 或其他方式(第 12 項) | +| 執行期權限 | ✅ | ✖ 無此概念 | ✖ | ✖ 用沙盒授權 | ✅ | 第 11 項定(`permission_handler` 不支援 macOS/Linux) | +| 應用內更新 | ✅ APK | ✅ installer/portable | ⏳ 視打包格式 | ⏳ Sparkle(`auto_updater`) | ✖ 政策禁止 | 第 19 項定 | +| 網路狀態 | ✅ | ✅ | ✅ | ✅ | ✅ | `connectivity_plus` | +| 檔案選取、目錄 | ✅ | ✅ | ✅ | ✅ | ✅ | `file_picker`、`path_provider` | + +同類播放器普遍把桌面音訊/SMTC 套件改成 fork 或本地 path。這裡不預先 fork;遇到非改不可的問題時, +用 git 依賴並鎖 commit,在 pubspec 註解寫明原因與對應的上游 issue/PR。 + +## 4. 資料與下載目錄(A4) + +| 情境 | 資料(資料庫、設定、log) | 預設下載目錄 | +|---|---|---| +| Android | App 私有目錄 | 第 11 項定 | +| Windows 安裝版 | `%APPDATA%` 下的 App 目錄(`path_provider` 的 application support) | 使用者的音樂資料夾下 `FMP` | +| Windows Portable | 程式旁的 `data/`(以程式旁的標記檔判斷是 Portable) | 程式旁的 `downloads/` | +| Linux | `~/.local/share` 下的 App 目錄 | `~/Music/FMP` | +| macOS/iOS | 沙盒內的 Application Support | 第 11 項定 | +| 開發版 | 與正式版分開的目錄與身分(第 8 項定細節) | 同左 | + +舊版 `Documents\FMP` 的資料在第一次啟動時搬到新位置(第 6 項的遷移流程)。第一版不提供自訂資料位置。 + +## 5. 平台政策(寫進 ADR,避免之後重新研究) + +- iOS:不能自行安裝更新;經 GitHub 發 IPA、以 AltStore/SideStore 側載,免費 Apple ID 需 7 天重簽、最多 3 個 App; + 上架 App Store 與「下載第三方媒體」衝突(Guideline 5.2.3),不走商店;背景播放需要 `UIBackgroundModes: audio`。 +- macOS:Sequoia 起未公證的 App 無法用 Control-click 繞過 Gatekeeper,要讓一般使用者順利安裝需付費開發者帳號做公證;取得 Mac 時再決定。 +- Android:不上 Google Play(Play 不允許音樂播放器使用 `MANAGE_EXTERNAL_STORAGE`,第 11 項會一併考慮)。 +- Linux:只有 AppImage 適合應用內自我更新;Flatpak 交給系統更新、deb 沒有機制(第 19 項)。 + +## 6. 其他平台差異 + +- 自訂標題列:Windows、Linux 用自訂標題列;macOS 保留系統紅綠燈按鈕、標題列透明延伸。 +- CJK 字型:不內建;依平台寫 fallback 清單。Linux 虛擬機驗證時若發現常見發行版缺字,再決定是否內建子集。 + +## 7. 平台上線順序與驗證 + +| 平台 | 從哪裡開始 | 驗證方式 | 需要的環境 | +|---|---|---|---| +| Android | 第一個里程碑 | emulator+實機;每個里程碑 | 現有 | +| Windows | 第一個里程碑 | 本機;每個里程碑 | 現有 | +| Linux | 第一個里程碑起 CI 編譯+單元測試;第一個里程碑完成後開 child task 在虛擬機實機跑;之後每個里程碑做一次冒煙測試 | 虛擬機 | Linux 虛擬機(建議同時有 X11 與 Wayland 工作階段) | +| macOS | 第一個里程碑起 CI(GitHub Actions macOS runner)不簽名編譯 | 取得 Mac 後開 child task 做實機驗證與簽名/公證 | Mac;公證需付費開發者帳號 | +| iOS | 第一個里程碑起 CI 不簽名編譯+iOS 模擬器測試 | 取得 iPhone 後開 child task 做實機與側載驗證 | iPhone;側載工具 | + +正式發佈:Android、Windows 在切換時;Linux、macOS、iOS 各自在其 child task 完成實機驗證後才發佈。 + +## 8. 預期的 child task(里程碑定稿時排入) + +- `platform-linux`:接上 Linux 各能力實作、虛擬機驗證、打包格式(配合第 19 項)。 +- `platform-macos`:需要 Mac;實作、簽名與公證。 +- `platform-ios`:需要 iPhone(簽名需要 Mac);實作、背景播放設定、側載驗證。 diff --git a/.trellis/tasks/09-27-design-platform/implement.jsonl b/.trellis/tasks/09-27-design-platform/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-platform/implement.md b/.trellis/tasks/09-27-design-platform/implement.md new file mode 100644 index 000000000..aefe3c579 --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/implement.md @@ -0,0 +1,9 @@ +# 執行計畫 + +本任務只產出設計與 ADR;平台層程式碼在第一個里程碑建立。 + +- [ ] 依 `docs/adr/template.md` 寫 `docs/adr/0009-platform-layer-with-declared-capabilities.md`:design.md §1–§7 的決定、被否決的選項(沿用 `Platform.isX` 散落、只按 Android/Windows 設計的二分抽象、為未驗證平台寫空實作)、「如何確認」(lint 閘門與第 8 項的關係)。 +- [ ] `phase2-plan.md` 標記第 10 項完成。 +- [ ] 歸檔本任務。 + +驗證:ADR 內的 Mermaid 以 mermaid-cli 渲染;引用的研究檔與審計檔路徑存在。 diff --git a/.trellis/tasks/09-27-design-platform/prd.md b/.trellis/tasks/09-27-design-platform/prd.md new file mode 100644 index 000000000..81ae4ad5b --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/prd.md @@ -0,0 +1,62 @@ +# 設計第 10 項:平台層 + +## 目標 + +把所有平台差異收進單一平台層:平台宣告自己有哪些能力,UI 與 service 依能力運作,平台層以外不出現 +`Platform.isX`/`defaultTargetPlatform`。選定各能力在五個平台上的套件,寫明平台政策限制與平台上線順序。 + +需求來源:parent `prd.md` 階段二第 10 項;`questions.md` A1、A4、§8(使用者:各平台體驗盡量一致,做不到可以放棄);ADR 0008。 + +## 已確認的前提 + +- 第一版 Android+Windows;Linux、macOS、iOS 之後加入(A1)。iOS 經 GitHub Release 發 IPA 供側載(phase2-plan §6)。 +- 不替還無法驗證的平台寫空實作(parent prd 第 10 項)。 +- 資料位置:安裝版用系統 App 資料目錄;Portable 版放程式旁;舊 `Documents\FMP` 自動搬(A4,按推薦)。 +- 單一實例保留;開發版用不同身分與資料目錄(E18、U9)。 + +## 現況(證據) + +- 88 處平台判斷、三種寫法並存;macOS/Linux 會出現半套桌面 UI(`docs/audit/platforms.md` §0–§2)。 +- 平台綁定功能與各平台阻礙:`platforms.md` §3、§6。 + +## 研究結論(`research/platform-packages.md`、`research/platform-policy-and-peers.md`) + +- **沒有一套套件能覆蓋五平台**:系統媒體控制、多視窗、登入 WebView 都要依平台拼接。 +- 系統媒體控制:`audio_service`(Android/iOS/macOS)+ Linux `audio_service_mpris`(Spotube、Finamp、Harmony 都用)+ Windows `smtc_windows`(現用,無 seek)或 `audio_service_win`(待評估)。 +- 托盤 `tray_manager`、視窗 `window_manager`、快捷鍵 `hotkey_manager`、多視窗 `desktop_multi_window`:三個桌面平台都支援,現在只接了 Windows。Linux Wayland 下全域快捷鍵是協定層限制,不是套件問題。 +- 開機自啟:`auto_start_flutter` 五平台都支援、機制透明(macOS 需 13+);`launch_at_startup` 現用。 +- 單一實例:`flutter_single_instance` 涵蓋三個桌面平台,機制未公開(推測 gRPC+檔案),需讀原始碼再決定。 +- 登入 WebView:`flutter_inappwebview` 無 Linux、2024-10 後未發版;桌面端能讀 cookie 的只有 `webview_cef`(較新、社群訊號小);`desktop_webview_window` 訊號好但沒有 cookie API。 +- 權限:`permission_handler` 不支援 macOS、Linux(這兩個平台本來就沒有 Android 式執行期權限)。 +- `path_provider`、`file_picker`、`connectivity_plus`:五平台可用。 +- 更新:Android APK、Windows installer/portable、macOS Sparkle(`auto_updater`)、Linux 只有 AppImage 適合自我更新、iOS 不可。 +- 政策:App Store 5.2.3 與下載第三方媒體衝突;iOS 側載免費帳號 7 天重簽、3 個 App 上限;macOS Sequoia 起未公證 App 無法用 Control-click 繞過 Gatekeeper;Google Play 不允許音樂播放器用 `MANAGE_EXTERNAL_STORAGE`。 +- 同類播放器:都把平台差異集中在一層;Namida 最徹底(`lib/controller/platform/` 每能力一目錄:`_base.dart`+各平台實作+工廠)。三家把桌面音訊/SMTC 套件改用 fork 或本地 path。 +- Flutter 官方:純 Dart 的平台分支用 `defaultTargetPlatform`;要呼叫原生 API 才用 platform channel,建議用 Pigeon 產生型別安全的介面;federated plugin 是官方認可的「共用介面+各平台實作」切法。 + +## 已決定 + +- D1(使用者 2026-09-27):Linux 從第一個里程碑起 CI 編譯並跑單元測試;第一個里程碑完成後開 Linux child task + 在虛擬機實機跑,之後每個里程碑做一次虛擬機冒煙測試;切換前不發 Linux 版。macOS、iOS 從第一個里程碑起在 CI + 做不簽名編譯(iOS 加模擬器測試),取得設備後各開 child task。 +- 其餘(平台層形狀、各能力套件、資料目錄、標題列、字型、政策)依研究結論與使用者「按推薦」寫入 design.md。 + +## 需求 + +- R1 平台差異只存在於平台層;平台層以外不出現 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform`,也不 import 平台套件;以 lint 守(第 8 項落實)。 +- R2 每個平台一份 `PlatformCapabilities` 宣告;UI 依宣告顯示入口,service 只呼叫介面。 +- R3 未驗證的平台只宣告「沒有」,不寫實作檔。 +- R4 新的原生呼叫用 Pigeon。 +- R5 平台政策限制寫進 ADR。 + +## 驗收標準 + +- [ ] design.md 涵蓋:平台層形狀、不寫空實作的做法、各能力×五平台的套件表、資料與下載目錄、平台政策、標題列與字型、上線順序與驗證、預期的平台 child task。 +- [ ] `docs/adr/0009-*.md` 依範本寫成,含被否決的選項與「如何確認」。 +- [ ] `phase2-plan.md` 標記第 10 項完成。 + +## 延後到其他項目 + +- 各音源的登入方式與 Linux 登入 WebView 選型 → 第 12 項。 +- Android 下載儲存(ADR 0004 去留)→ 第 11 項。 +- 音訊後端 → 第 13 項。Linux 打包格式與各平台更新機制 → 第 19 項。 diff --git a/.trellis/tasks/09-27-design-platform/research/platform-packages.md b/.trellis/tasks/09-27-design-platform/research/platform-packages.md new file mode 100644 index 000000000..301e21a3c --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/research/platform-packages.md @@ -0,0 +1,422 @@ +# 研究:平台能力套件盤點與 Flutter 官方寫法建議 + +> 對應 `.trellis/tasks/09-27-design-platform` 的研究第 1、4 點。 +> 目標平台:Android + Windows(第一波),Linux / macOS / iOS(後續)。 +> 查證方式:pub.dev packages API(版本/發布時間/是否 discontinued)與 score API +> (`platform:*` tag)、context7、官方 README。政策類問題見另一份文件 +> `platform-policy-and-peers.md`。查不到的一律寫「查不到」,未經一手來源證實的 +> 推論一律標「推測」。所有 pub.dev 資料查證於 2026-09-27。 + +## 目錄 + +1. 系統匣(tray) +2. 視窗管理 + 自訂標題列 +3. 全域快捷鍵 +4. 開機自動啟動 +5. 單一實例 +6. 多視窗(桌面歌詞視窗) +7. 系統媒體控制 +8. 登入用 WebView(含登入後讀 cookie) +9. 權限 +10. 檔案選取 / 應用程式目錄 +11. 應用內更新 +12. 網路狀態 +13. 音訊(僅列事實,不做引擎決策) +14. Flutter 官方對平台專屬程式碼的建議 + +--- + +## 1. 系統匣(System Tray) + +| 套件 | 最新版 | 發布日期 | Discontinued | Android | iOS | Windows | macOS | Linux | 備註 | +|---|---|---|---|---|---|---|---|---|---| +| `tray_manager` | 0.5.3 | 見 FMP 現有 audit §4(已用) | 否 | – | – | ✅ | ✅ | ✅ | FMP 現況只接了 Windows;README 未寫 Linux 是走 `libayatana-appindicator3` 還是 StatusNotifierItem,需查原始碼確認(查不到,未在 README 明載)。 | +| `system_tray` | 見 pub.dev | — | 否 | – | – | ✅ | ✅ | ✅ | Spotube 未採用(其 pubspec 只有 `tray_manager`,見下方引用);未再深挖,因 `tray_manager` 已是現有依賴且平台覆蓋相同,沒有理由多引入一個套件。 | + +**來源**:`https://pub.dev/api/packages/tray_manager/score`(platform tag 含 +android 以外的 windows/macos/linux);Spotube 依賴確認見 +`https://raw.githubusercontent.com/KRTirtho/spotube/master/pubspec.yaml` +(`tray_manager: ^0.5.0`)。 + +**結論**:`tray_manager` 已是 FMP 現有依賴且三桌面平台都聲明支援,維持使用, +只是目前只在 Windows 端接線;Linux 端要接時需先讀原始碼/範例 app 確認底層是 +`libayatana-appindicator3`(GTK 沿用)還是新的 StatusNotifierItem 實作。 + +--- + +## 2. 視窗管理 + 自訂標題列 + +| 套件 | 最新版 | Discontinued | Windows | macOS | Linux | 備註 | +|---|---|---|---|---|---|---| +| `window_manager` | 見 FMP 現有 audit §4(已用) | 否 | ✅ | ✅ | ✅ | FMP 現況只接 Windows。 | +| `window_manager_plus` | 1.0.5(2024-10-08) | 否 | ✅ | ✅ | ❌ | **明確不支援 Linux**:README 原文「Linux is not currently supported.」,pub.dev 平台 tag 只有 `windows`/`macos`。是 `window_manager` 的獨立 fork/改寫,內建多視窗管理,但與 `desktop_multi_window` README 建議的另一個 fork(`boyan01/window_manager` 特定 commit)是**不同的兩個東西**,不要混淆。 | + +**來源**:`https://pub.dev/api/packages/window_manager_plus/score`(tags 只有 +`platform:windows`、`platform:macos`);README 引用透過 WebFetch 讀取 +`https://pub.dev/packages/window_manager_plus`。 + +**結論**:自訂標題列/視窗控制維持用 `window_manager`(三桌面平台都支援,FMP +已用於 Windows)。`window_manager_plus` 只在需要「多視窗」且能接受放棄 Linux +支援時才考慮,見下方第 6 節的取捨。 + +--- + +## 3. 全域快捷鍵 + +| 套件 | 最新版 | Windows | macOS | Linux | 備註 | +|---|---|---|---|---|---| +| `hotkey_manager` | 0.2.3(FMP 已用) | ✅ | ✅ | ✅(X11 only,見下) | pub.dev 平台 tag 三者皆列,但 Linux 端底層是 `keybinder-3.0`,只支援 X11。 | + +**Linux Wayland 限制(事實,非推測)**:Wayland 的安全模型設計上不允許應用 +程式攔截「未取得焦點時」的全域按鍵,這是協定層面的限制,不是某個套件沒做好: + +- KDE 開發者討論:`https://discuss.kde.org/t/global-shortcuts-on-wayland/…` + (原文核心論點:全域快捷鍵在 Wayland 下必須透過 compositor 提供的 + portal,應用程式本身無法像 X11 時代直接抓鍵盤事件) +- GNOME Shell 的 + `org.gnome.desktop.portal.GlobalShortcuts` 是目前最接近的補救方案, + GNOME 46+/48 逐步落地,但需要 compositor 端支援且流程是「使用者互動綁定」 + 而非程式主動抓鍵,功能覆蓋面比 X11 版 `keybinder` 窄。 + 來源:GNOME 官方 portal 文件 + `https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html` +- Arch Wiki/Arch Linux Forums 對 `keybinder-3.0` 的說明同樣指出它是 + X11-only(依賴 `libX11`/`XGrabKey`)。 + +**結論**:`hotkey_manager` 維持用於 Windows/macOS/X11-Linux;Wayland-Linux +下全域快捷鍵在設計上要當作「已知不可行」而非之後修的 bug,若要支援只能走 +`GlobalShortcuts` portal 且功能會縮水(需 compositor 支援、無法在背景任意 +時刻攔截任意組合鍵)。 + +--- + +## 4. 開機自動啟動(Launch at Startup) + +| 套件 | 最新版 | 發布日期 | Android | iOS | Windows | macOS | Linux | 機制 | +|---|---|---|---|---|---|---|---|---| +| `launch_at_startup` | 0.5.1(FMP 已用) | 見 audit §4 | – | – | ✅ | ✅ | ✅ | README 未列出各平台底層機制細節(查不到)。 | +| `auto_start_flutter` | 1.4.0 | 2026-03-30 | ✅ | ✅ | ✅ | ✅ | ✅ | **五平台全支援**,且 README 明載各平台機制(見下)。 | + +**`auto_start_flutter` 各平台機制(來源: +`https://pub.dev/packages/auto_start_flutter` README 原文)**: + +- **Windows**:原生寫入 `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` + 登錄檔(帶 `--autostart` 參數),不需額外原生程式碼。 +- **macOS**:呼叫新版 `SMAppService.mainApp.register()` API 註冊為登入項目 + ——**需要 macOS 13+**(雖然套件宣稱最低支援 10.14,但這個 API 本身要 13+, + 對應 audit 文件裡「macOS 原生程式碼需求」的疑慮是真的:舊版 macOS 需要 + fallback 到 `SMLoginItemSetEnabled` 之類的舊 API,套件是否有 fallback + 未在 README 說明,查不到)。 +- **Linux**:在 `~/.config/autostart/` 產生標準 X-GNOME `.desktop` 檔案, + 不需原生程式碼。 +- **Android**:監聽 `BOOT_COMPLETED` broadcast 並啟動 headless + `FlutterEngine`;**需要手動在 `AndroidManifest.xml` 加 + ``** + (套件本身不再預設帶這個權限宣告)。callback 必須是 top-level/static + 函式並加 `@pragma('vm:entry-point')`。 + +**結論**:若要把「開機自動啟動」做成真正跨平台一致的能力, +`auto_start_flutter` 是目前唯一五平台都支援且機制透明的候選;但 macOS +13 以下的行為是設計上的缺口,需要在設計文件裡明確標注最低版本需求,不能 +當成「已解決」。若近期只做 Windows(現況),`launch_at_startup` 維持不動 +即可,機制差異不影響決策。 + +--- + +## 5. 單一實例(Single Instance) + +FMP 現況:Windows-only,C++ named mutex(audit §3/§3.8)。 + +| 套件 | 最新版 | 發布日期 | Android/iOS/Web | Windows/Linux/macOS | 機制 | +|---|---|---|---|---|---| +| `flutter_single_instance` | 1.7.0 | 2025-11-04 | ⚠️ 恆回傳「是第一個實例」(README 原文:「will always return `true` for `isFirstInstance` method」),行動端等於沒有這個能力 | ✅(README 標「Confirmed working」) | **README 未指名機制**(不是 named mutex/socket/lock file 的哪一種,查不到);從依賴列表(`path_provider` + `grpc` + `protobuf`)與 macOS 設定需求(要求關掉 App Sandbox、要能「當 server 監聽/當 client 送焦點請求」)推測底層是「本機 gRPC channel + 檔案系統狀態」,**此為推測,非 README 明載**。另外 debug build 下永遠回報是第一個實例,除非手動關閉 `debugMode`。 | + +**結論**:`flutter_single_instance` 可以覆蓋 Windows/macOS/Linux 三個桌面 +平台,比現有的 Windows-only C++ named mutex 更省維護(不用自己寫平台原生 +碼),但底層機制沒有在文件公開,若要採用建議先讀原始碼再決定是否信任其 +跨程序協定的安全性/穩定性(例如 gRPC channel 的埠號/socket 路徑是否有 +權限或多使用者衝突風險)。行動端本來就不需要這個能力(單一實例是桌面 +多開視窗情境的問題),所以「行動端恆為第一個實例」不是缺點。 + +--- + +## 6. 多視窗(桌面歌詞視窗) + +FMP 現況:`desktop_multi_window` 0.3.1,audit §3.7 已有完整的原生註冊 +時序圖與流程說明。 + +| 套件 | 最新版 | Windows | macOS | Linux | 備註 | +|---|---|---|---|---|---| +| `desktop_multi_window` | 0.3.1(FMP 已用) | ✅ | ✅ | ✅ | README 建議搭配一個 fork 過的 `window_manager`(`boyan01/window_manager`,鎖定特定 commit)以取得視窗控制能力,**這個 fork 跟 `window_manager_plus` 是兩個不同的東西**,不要混淆(見第 2 節)。 | +| `window_manager_plus` | 1.0.5 | ✅ | ✅ | ❌ | 自帶多視窗管理,但明確不支援 Linux;若採用等於歌詞視窗功能在 Linux 上要另找方案或直接不支援。 | + +**結論**:維持 `desktop_multi_window`(FMP 現有依賴且三桌面平台都支援), +不建議换成 `window_manager_plus`——後者雖然「自帶多視窗」比較省事,但 +直接放棄 Linux 支援,與「目標平台功能對等」的前提衝突。`desktop_multi_window` +的已知代價(audit §3.7 已載明)是每個新視窗是獨立 Flutter engine,原生 +plugin 要重新註冊一次,這件事在换任何套件的情況下都不會消失,除非放棄 +「歌詞獨立視窗」這個功能形態本身。 + +--- + +## 7. 系統媒體控制 + +FMP 現況:Android 用 `audio_service` 0.18.18;Windows 用 `smtc_windows` +1.1.0(無 seek 支援,audit §3 已載明);Linux/macOS/iOS 尚未串接。 + +**先回答任務指定的關鍵問題:目前沒有任何單一套件同時覆蓋 Android + iOS + +macOS + Windows + Linux 五個平台的系統媒體控制**,各平台仍需拼接不同套件: + +| 平台 | 候選套件 | 最新版 | 發布日期 | 備註 | +|---|---|---|---|---| +| Android / iOS / macOS | `audio_service` | 0.18.18(FMP 已用於 Android) | 見 audit | 官方文件與 README 宣稱涵蓋 Android/iOS/macOS 三者的通知列/控制中心整合(`MPNowPlayingInfoCenter`/`MPRemoteCommandCenter`),FMP 目前只接了 Android。 | +| Windows | `smtc_windows` | 1.1.0(FMP 已用) | 見 audit | 目前無 seek 支援(audit 已載明);`audio_service_win` 是另一個候選(見下)。 | +| Windows(替代) | `audio_service_win` | 見 pub.dev | — | 定位是 `audio_service` 的 Windows 平台實作(federated plugin 的 windows 端),與 `smtc_windows` 是不同的兩條路:一個是「讓 `audio_service` 這個 app-facing API 在 Windows 上也能用」,一個是「直接包 SMTC 原生 API」。是否比 `smtc_windows` 更完整(例如是否支援 seek)需要進一步讀原始碼比對,**查不到**(README 未明確列出 seek 支援與否)。 | +| Linux | `audio_service_mpris` | 0.2.0(Spotube 採用,見 +`https://raw.githubusercontent.com/KRTirtho/spotube/master/pubspec.yaml`) | — | 走 `audio_service` 的 federated 架構,把 MPRIS(D-Bus)接到同一套 app-facing API。 | +| Linux(替代) | `mpris_service` | 見 pub.dev | — | 獨立的 MPRIS 實作,不透過 `audio_service` 的 plugin 架構,直接自己起 D-Bus service。 | +| Linux(新發現,較冷門) | `anni_mpris_service` | 0.1.0(2022-09-06) | 已 3 年未更新,likeCount 僅 4,pub points 150/160 | 明顯是個人專案等級的小套件,維護活躍度低,不建議作為主要候選,僅供比較。來源:`https://pub.dev/api/packages/anni_mpris_service/score`。 | +| macOS(額外選項) | `flutter_media_session` | 見 pub.dev | — | 定位不明確是否涵蓋多平台或僅 macOS/iOS,README 需要進一步確認涵蓋範圍,**查不到完整平台清單**(初步查詢顯示它的訴求接近 `audio_service` 的替代品,但生態成熟度與採用度遠不如 `audio_service`,未深入比較)。 | + +**結論**:系統媒體控制的現實是「`audio_service` 家族(federated plugin) +是唯一有機會做到多平台一致 API 的路線」——Android/iOS/macOS 走 +`audio_service` 本體,Linux 走 `audio_service_mpris` 補上 federated +實作,Windows 則要在 `smtc_windows`(目前已用,但無 seek)與 +`audio_service_win`(federated 路線但成熟度未知)之間選:如果 Windows +也想收斂進 `audio_service` 的同一套 API 之下,`audio_service_win` 值得 +花時間評估;如果 SMTC 的 seek 缺口可以之後再補,`smtc_windows` 維持現況 +風險最小。 + +--- + +## 8. 登入用 WebView(含登入後讀 Cookie) + +FMP 現況:`flutter_inappwebview`(audit §4 已指出無 Linux 支援、 +最後發布 2024-10-08,久未更新)。 + +| 套件 | 最新版 | 發布日期 | Windows | macOS | Linux | Android/iOS | Cookie 讀取 | 備註 | +|---|---|---|---|---|---|---|---|---| +| `flutter_inappwebview` | 見 audit §4 | 2024-10-08(久未更新) | ✅ | ✅ | ❌ | ✅ | 內建 `CookieManager` | audit 已載明無 Linux 支援;一年多沒發新版,長期維護風險需列入設計考量。 | +| `webview_flutter` | 見 pub.dev | — | 官方федерated plugin,桌面支援仍在發展中 | 部分支援 | 官方本身不含 Linux 實作 | ✅ | 有官方 `WebViewCookieManager` | Google 官方維護,行動端最穩,桌面覆蓋不如專門的桌面 WebView 套件完整。 | +| `desktop_webview_window` | 0.3.0 | 4 個月前(相對 2026-09 約當 2026-05 前後) | ✅(WebView2 1.0.992.28,Win10 需另裝 Runtime,Win11 內建) | ✅(WKWebView) | ✅(WebKitGTK-4.1/4.0 + libsoup-3.0) | – | **README 未提供 cookie 讀取 API**(只有 `runWebViewTitleBarWidget`、`WebviewWindow.create()`、`launch(url)`、`isWebviewAvailable()`),查不到內建 cookie 方法。 | 桌面三平台齊全,由 verified publisher `mixin.dev` 維護,524k 下載、160 分,維護訊號良好;但登入後讀 cookie 這個 FMP 需要的能力,目前檯面上的 README 沒有給答案,需要進一步翻原始碼確認是否可用 `evaluateJavascript('document.cookie')` 繞過(缺點是讀不到 HttpOnly cookie)。 | +| `webview_cef` | 0.6.2 | 32 天前(很新) | ✅(Win10+ x64) | ✅(12.0+,arm64/x86_64/universal) | ✅(x64/arm64;另有 eLinux Wayland/DRM-GBM 變體不依賴 GTK/X11) | – | **有明確 cookie API**:`WebviewManager().visitAllCookies()`、 +`visitUrlCookies(url, bool)`、`setCookie`、`deleteCookie` | 基於 CEF/Chromium 149,桌面三平台 CI 都跑,更新頻繁(0.5.0 才剛做過含破壞性變更的大升級),但 publisher 是 unverified uploader、like/下載量遠低於 `desktop_webview_window`(88 like vs 222 like),屬於較新、還在快速迭代的套件。 | + +**結論**:這是本次研究裡最沒有「一個套件打天下」答案的能力項。 +`flutter_inappwebview` 的 Linux 缺口加上更新停滯,長期不是理想解; +桌面三平台 + 明確 cookie API 這個組合目前只有 `webview_cef` 符合, +代價是套件本身較新、社群訊號較小;`desktop_webview_window` 訊號更好但 +cookie 能力不明確需要再查原始碼。若行動端與桌面端要走不同套件(行動端 +留 `flutter_inappwebview` 或换官方 `webview_flutter`,桌面端另接 +`webview_cef`/`desktop_webview_window`),這件事本身就是「登入 WebView」 +這個能力天生無法用單一套件覆蓋五平台的證據。 + +--- + +## 9. 權限(Permissions) + +| 套件 | 最新版 | Android | iOS | Windows | macOS | Linux | Web | +|---|---|---|---|---|---|---|---| +| `permission_handler` | 見 pub.dev | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | + +**來源(一手 API 資料,非轉述)**: +`https://pub.dev/api/packages/permission_handler/score` 回傳的 `tags` +逐字為: +``` +['publisher:baseflow.com', 'sdk:flutter', 'platform:android', + 'platform:ios', 'platform:windows', 'platform:web', 'is:plugin', + 'is:null-safe', 'is:wasm-ready', 'is:swiftpm-plugin', + 'is:built-in-kotlin', 'is:dart3-compatible', 'license:mit', + 'license:fsf-libre', 'license:osi-approved'] +``` +**macOS 與 Linux 完全沒有 `platform:` tag**,不是我方擷取遺漏,是套件本身 +沒有宣告支援。 + +**結論**:FMP 目前沒有依賴 `permission_handler`(現況是自己寫 +MethodChannel 版的 storage 權限服務,對應 audit 文件脈絡下的 +`storage_permission_service.dart`)。這次查證的意義是:即使設計階段考慮 +「乾脆全平台都改用 `permission_handler`」,這條路本來就走不通——macOS 和 +Linux 需要另外的方案(例如 macOS 的檔案存取權限走 sandbox +entitlement/NSOpenPanel 使用者授權模式,Linux 桌面環境本身多半沒有 +Android 式的執行期權限系統,多半是檔案系統 DAC 或 portal +(`xdg-desktop-portal`)授權模型),這兩個平台的「權限」概念本來就和 +Android/iOS 不同,不是「换一個套件」能解決的問題。 + +--- + +## 10. 檔案選取 / 應用程式目錄 + +| 套件 | 涵蓋 | 備註 | +|---|---|---| +| `file_picker` | Android/iOS/Windows/macOS/Linux/Web 均支援檔案選取對話框 | 現有 FMP 依賴(假設;未在本次逐一重查版本,因非本輪 gap) | +| `path_provider` | 五平台皆支援,但語意不同:Android 有 app-specific 外部/內部儲存區分;iOS/macOS 走 sandbox 容器內的 `Documents`/`Application Support`;Windows/Linux 走 `%APPDATA%`/`~/.local/share` 類的使用者設定目錄 | 這是官方 first-party 套件(`flutter/packages` 倉庫下維護),屬最穩定、最沒有替代品必要的選項。 | + +**結論**:這兩個能力已經是生態系「事實標準」,沒有必要重新評估替代品; +真正需要設計決策的是「FMP 自己在這些目錄底下的檔案配置規則」(例如下載 +檔案要放 Documents 還是 Application Support,這牽涉使用者能否直接在 +系統檔案總管看到),這屬於設計文件(design.md)的範疇,不是套件選型 +問題。 + +--- + +## 11. 應用內更新(per-platform) + +| 平台 | 可行機制 | 備註 | +|---|---|---| +| Android | 下載 APK 後導向系統安裝流程(`REQUEST_INSTALL_PACKAGES` 權限) | 現況(audit 已載明),非 Play Store 上架前提下唯一路徑。 | +| Windows | Installer(如 Inno Setup/MSIX)或 portable 版本直接覆蓋執行檔 | 需要應用自己下載新版並觸發安裝程式,或提示使用者手動更新;沒有作業系統層級的強制簽章要求,但未簽章的 installer 會被 SmartScreen 攔一次性警告。 | +| Linux | AppImage 可用 `AppImageUpdate`/`zsync` 做差量自我更新;Flatpak/deb **不建議**做應用內自我更新 | 見 `platform-policy-and-peers.md` §Linux 打包格式自我更新可行性,附官方來源。 | +| macOS | `auto_updater`(Flutter 套件)包裝 Sparkle 框架 | 需要產生 EdDSA 金鑰、架設 `appcast.xml`,且應用本身仍建議走 Developer ID 簽章 + notarization(否則 Gatekeeper 會擋,見政策文件)。 | +| iOS | **不可能**:App Store 是唯一分發管道時完全走蘋果審核;側載(AltStore/SideStore)情境下更新機制受限於 7 天重簽或年費開發者帳號,細節見政策文件。 | | + +`auto_updater` 套件細節:來源 `https://pub.dev/packages/auto_updater`—— +包裝 macOS 的 Sparkle 與 Windows 的 WinSparkle(**因此 `auto_updater` +本身理論上是 Windows + macOS 雙平台**,但 FMP 現況 Windows 端更新機制 +未使用它,需要在設計階段決定是否統一到這個套件,或維持 Windows 自己的 +installer 流程、只在 macOS 端引入 `auto_updater`)。 + +**結論**:更新機制天生無法五平台統一,這不是套件選型能解決的限制,而是 +各平台分發模式本身的差異(有無審核商店、有無強制簽章)。`auto_updater` +是目前唯一同時覆蓋 macOS + Windows 兩個桌面平台的現成套件,值得在設計 +階段評估是否取代 Windows 現有的更新流程以換取程式碼共用。 + +--- + +## 12. 網路狀態 + +| 套件 | 涵蓋平台 | +|---|---| +| `connectivity_plus` | Android / iOS / Windows / macOS / Linux / Web 均支援(federated plugin,官方生態系常見選擇) | + +**結論**:五平台都支援,沒有必要比較替代品,直接可用。 + +--- + +## 13. 音訊(僅列事實,不做引擎決策) + +本節刻意不下「該選哪個音訊引擎」的結論,只列查證到的事實,決策留給 +design.md。 + +| 套件 | 涵蓋平台 | 關鍵事實 | +|---|---|---| +| `just_audio` | Android/iOS/macOS/Web;**不支援 Windows/Linux 原生**(FMP 現況只在 Android 用,audit 已載明) | 官方定位是行動端/Web 優先的播放引擎。 | +| `media_kit` | Android/iOS/macOS/Windows/Linux 全平台(基於 libmpv) | FMP 現況 Windows 端使用(`media_kit` 1.2.6 + `media_kit_libs_windows_audio` 1.0.9)。**`media_kit_libs_*` 系列全部都是 `is:unlisted`**(非只有 macOS 版如此):本次重新查證 `media_kit_libs_linux`、`media_kit_libs_windows_audio`、`media_kit_libs_macos_audio`、`media_kit_libs_ios_audio` 四個套件的 score API,`tags` 都包含 `is:unlisted`,且都由同一個 `publisher:media-kit.dev` 發布——這是 media-kit.dev 團隊刻意的作法(把「引擎殼」`media_kit` 上架、把「各平台原生函式庫包」故意標成 unlisted 避免使用者誤裝錯平台的包),**不是套件被棄用或有問題的訊號**,audit 文件原本對 macOS 版本的疑慮可以澄清為「四個平台包都是同樣的 unlisted 狀態,行為一致」。唯一例外是 `media_kit_libs_macos_audio` 的 score API 回傳資料明顯比其他三個少很多(只有 `is:unlisted` 與 `publisher` 兩個 tag,没有 `platform:macos`、沒有 grantedPoints),這看起來像是 pub.dev 分析流程對這個特定套件跑失敗,而非套件本身聲明的差異——**用 packages API(非 score API)重新確認**其 `pubspec.flutter.plugin.platforms` 內確實宣告了 `macos`,可視為 pub.dev 網站端資料展示的落差,不影響套件本身可用性判斷。來源:`https://pub.dev/api/packages/media_kit_libs_macos_audio`。 | +| `audioplayers` | Android/iOS/Windows/macOS/Linux/Web 全平台(latest 6.8.1,2026-06-27 發布,likeCount 3445,pub points 150/160,活躍度高) | **README 本身沒有寫背景播放機制**:官方 README 完全沒有提到 Android 前景服務、iOS 背景音訊 session、桌面背景播放行為或媒體通知,只泛泛帶過「並非所有功能都支援所有平台」並指向另一份 Feature Parity Table(該表未在 README 頁面內展開)。**背景播放機制查不到**,需要另外去 GitHub 的 Feature Parity Table 或原始碼確認,不能假設它像 `just_audio`+`audio_service` 那樣有現成的背景播放/通知整合。來源:`https://pub.dev/packages/audioplayers`。 | + +**結論(僅陳述事實,非決策)**:`media_kit` 是唯一單一套件涵蓋五平台的 +音訊引擎候選;`just_audio` 在 Windows/Linux 端沒有原生實作,必須另外 +搭配平台特定方案(FMP 現況正是如此:Android 走 `just_audio`,Windows +走 `media_kit`);`audioplayers` 雖然套件本身平台覆蓋最廣,但背景播放 +這個對音樂播放器至關重要的能力,官方文件沒有給出足夠資訊,需要在 +design.md 決策前先補這塊查證,不能只憑「平台 tag 齊全」就假設它能滿足 +背景播放需求。 + +--- + +## 14. Flutter 官方對平台專屬程式碼的建議 + +來源:context7 `/flutter/website`(Flutter 官方文件庫)。 + +### (1) `defaultTargetPlatform` vs `dart:io Platform` + +官方架構總覽文件(`architectural-overview.md`)示範的寫法是用 +`defaultTargetPlatform`(來自 `package:flutter/foundation.dart`)搭配 +`TargetPlatform` enum 做分支,而非 `dart:io` 的 `Platform.isX`: + +```dart +if (defaultTargetPlatform == TargetPlatform.android) { + return AndroidView(...); +} else if (defaultTargetPlatform == TargetPlatform.iOS) { + return UiKitView(...); +} +return Text('$defaultTargetPlatform is not yet supported by the maps plugin'); +``` + +`defaultTargetPlatform` 的優勢(推測性總結,基於此範例與其在 +`package:flutter/foundation.dart` 而非 `dart:io` 的定位):它在 Web +編譯下也能運作(`dart:io` 的 `Platform` 類別在 Web 上會丟例外,因為 +Web 平台沒有 `dart:io`),因此凡是「UI 層/Widget 層」要依平台分支的 +程式碼,官方範例都用 `defaultTargetPlatform`;`dart:io Platform.isX` +則保留給「本來就只會在原生平台跑」的邏輯(例如檔案系統操作、 +Isolate、Socket 這類 Web 上本來就不存在的能力)。FMP 現況三種判斷風格 +並存(`Platform.isWindows` 直接呼叫、`isDesktopPlatform` helper、 +`AudioRuntimePlatform` enum,見 audit §0),對照官方建議,UI 層的平台 +分支應該收斂到 `defaultTargetPlatform`/`TargetPlatform`,`dart:io` +的 `Platform` 保留給非 UI 層(例如平台通道初始化、原生檔案路徑組裝)。 + +### (2) 條件匯入(Conditional imports) + +官方 Web/Wasm FAQ 文件示範的模式: + +```dart +import 'fallback.dart' + if (dart.library.js) 'legacy_web_interop.dart' + if (dart.library.js_interop) 'wasm_web_interop.dart'; +``` + +這個機制原本是為 Web/Wasm 而設計(依 `dart.library.*` 是否存在切換 +匯入的檔案),但同樣的語法也可以用 `dart.library.io` 之類的條件在 +桌面/行動端之間切換實作檔案,是 Dart 語言層級的能力,不依賴任何套件。 +來源:`https://github.com/flutter/website/blob/main/sites/docs/src/content/platform-integration/web/faq.md`。 + +### (3) Platform Channels 與 Pigeon + +官方 Platform Channels 總覽文件明確建議:**如果只是要寫「平台專屬的 +Dart 程式碼」(不涉及呼叫原生語言 API),用 `defaultTargetPlatform` +即可,不需要 platform channel**;platform channel 機制是保留給 +「真的需要呼叫非 Dart 語言(Kotlin/Swift/C++ 等)撰寫的原生 API」的 +情境。原文(節錄): + +> "you can also write platform-specific Dart code in your Flutter +> app by inspecting the `defaultTargetPlatform` property." + +`Pigeon` 是官方推薦的 platform channel 型別安全替代方案:用 Dart +定義 `@HostApi()` 介面,自動生成雙端型別安全的 binding 程式碼,取代 +手寫 `MethodChannel` 字串命名容易出錯的問題。FMP 現況的 MethodChannel +對照表(audit §3.8)如果未來要擴充更多平台端呼叫,`Pigeon` 是官方建議 +的路線,比繼續手寫字串常量 channel 名稱更不容易出錯。 +來源: +`https://github.com/flutter/website/blob/main/sites/docs/src/content/platform-integration/platform-channels.md`、 +Pigeon 範例 +`https://github.com/flutter/website/blob/main/examples/platform_integration/pigeon/lib/pigeon_source.dart`。 + +### (4) Federated Plugins(聯邦式外掛架構) + +官方套件開發文件(`developing-packages.md`)說明 federated plugin +的宣告方式:一個「app-facing package」定義共用介面,各平台各自一個 +「platform package」透過 `implements` 宣告自己實作了哪個 app-facing +package: + +```yaml +flutter: + plugin: + implements: hello + platforms: + windows: + pluginClass: HelloPlugin +``` + +這正是 `audio_service`(app-facing)+ `audio_service_mpris`/ +`audio_service_win`(各平台 platform package)這類生態系套件採用的 +架構,也是 `path_provider`、`connectivity_plus`、`file_picker` 等 +Google 官方套件的標準做法。**設計啟示**:FMP 若要建立自己的「平台層」 +抽象(audit §7 問題 #11 提到的整合三種平台判斷風格),federated +plugin 的介面切分方式(一個共用抽象 + 各平台各自的實作套件/模組)是 +官方認可、且已被生態系驗證過的架構模式,不需要自己發明一套新的分層 +方式。 +來源: +`https://github.com/flutter/website/blob/main/sites/docs/src/content/packages-and-plugins/developing-packages.md`。 + +--- + +## 待補查項(誠實列出,非本次時間內完成) + +- `audioplayers` 的 Feature Parity Table(GitHub 上,非 pub.dev README) + 未實際打開比對背景播放逐平台細節——**查不到**(本次只查了 pub.dev + README 頁面本身)。 +- `desktop_webview_window` 是否能透過原始碼裡未在 README 曝光的 API + 讀取 cookie——**查不到**,需要另外開 repo 讀 `lib/` 原始碼確認。 +- `audio_service_win` 是否支援 seek(相對於 `smtc_windows` 目前的 + 已知缺口)——**查不到**,README 未明確比較。 +- `launch_at_startup` 套件本身在 Linux 端的底層機制(`.desktop` 檔案 + 還是其他方式)未在其 README 找到直接說明——**查不到**,只查了 + `auto_start_flutter` 的對應說明作為參照。 diff --git a/.trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md b/.trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md new file mode 100644 index 000000000..de32b9079 --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md @@ -0,0 +1,373 @@ +# 研究:平台商店政策限制與同類 Flutter 播放器的平台層架構 + +> 對應 `.trellis/tasks/09-27-design-platform` 的研究第 2、3 點。 +> 查證方式:tavily-search/WebFetch 對官方或權威來源;同類專案透過 +> `gh api`/raw GitHub 直接讀 `pubspec.yaml` 與原始碼目錄。查不到的一律 +> 寫「查不到」,推論一律標「推測」。查證時間 2026-09-27(政策類內容請注意 +> 官方頁面隨時可能更新,之後設計階段落地前建議重新核對一次日期)。 + +--- + +## 第 2 點:平台政策限制 + +### 2.1 iOS 側載(AltStore/SideStore) + +**免費 Apple ID 簽名的硬性限制(事實)**: + +- 憑證 **7 天**到期,須重新簽署; +- 免費帳號一次最多 **3 個** App 保持已簽署狀態(AltStore 本身也算一個 + 名額); +- 一週內最多能註冊 **10 個** App ID。 + +來源:SideStore 官方文件 FAQ +`https://docs.sidestore.io/docs/faq`(原文:「If using a free Apple +Account, SideStore can only install 3 apps (including itself) at a +time. Additionally, only 10 different apps may be installed in a +week.」;「Apple only allows 3 apps to be installed using a free Apple +Developer account.」)。 + +**付費 Apple Developer Program($99/年)的差異(事實)**:憑證效期延長為 +**365 天**,且解除 3-App 名額限制。同一份 SideStore FAQ 原文:「To +remove this restriction (and also get a 365 day expiry), you can pay +for a $99/year Apple Developer account.」 + +**繞過限制的手法(了解即可,不建議作為 FMP 的正式支援路徑)**: +LiveContainer 或針對特定舊版 iOS(18 db5/18.0.1 以下)的 SparseRestore +漏洞可繞過 3-App 限制,但**繞不過** 10 個 App ID/週的限制,且屬於利用 +系統漏洞,不是官方支援的機制,不建議寫進 FMP 的設計依據裡。來源同上 +SideStore FAQ。 + +**EU DMA 帶來的替代路徑(事實,隨時間演進中,需留意日期)**: + +- 歐盟《數位市場法》(DMA)自 2024 年起強制 Apple 在歐盟境內開放 + 第三方應用市集與網頁直接分發(Web Distribution)。 +- 截至 2026-01-01,Apple 已將歐盟合規條款統一為:原本每次安裝 + 0.5 歐元的 Core Technology Fee 取消,改為透過替代市集分發時收取 + **5% 固定抽成**。來源: + `https://www.buildmvpfast.com/blog/eu-dma-digital-markets-act-app-store-sideloading-mobile-2026` + (二手分析文章,非 Apple 官方一手來源,但內容與 Apple 官方公告方向 + 一致,列為輔助佐證)。 +- Apple 官方一手來源確認替代市集資格持續擴大:`https://developer.apple.com/support/apps-in-the-eu` + 原文:「Starting October 1, 2026, developers who meet at least one + of the following criteria will be eligible to operate an alternative + app marketplace」,並提到 2026 秋季會更新 EU 地區的 App 安裝體驗 + (安裝替代市集/App 時的系統確認流程)。 +- **AltStore 已支援「初次設定後不需電腦」的裝置端側載**(事實,來源 + `https://www.buildmvpfast.com/blog/eu-dma-digital-markets-act-app-store-sideloading-mobile-2026`: + 「AltStore recently shipped on-device sideloading that works without + a computer after the initial setup.」)——這代表在歐盟地區,側載的 + 操作門檻已經比「電腦上跑 AltServer、手機和電腦要同 Wi-Fi」的傳統模式 + 低很多,但**免費開發者帳號的 3-App/7-天限制本身沒有因為 DMA 而解除** + (同來源原文:「Apple restricts free developer accounts to 3 + sideloaded apps at a time」)。 +- 地區限制與跨區使用(事實):離開已授權地區後,已安裝的替代市集 + App 有最多 **30 天**的寬限期仍可開啟使用,但無法安裝新 App 或更新 + 既有側載 App,直到使用者返回受支援地區。來源: + `https://staging.advance-he.org/ios-alternative-app-store-1vab.html` + (二手整理文章,內容與 Apple 官方對地區偵測機制的描述方向一致,但 + 非一手來源,列為輔助佐證,正式落地前建議直接查 Apple 官方文件核實 + 30 天這個確切天數)。 +- 替代市集本身的存續风险(事實案例):MacPaw 的 Setapp Mobile 已於 + **2026-02-16** 在歐盟停止營運,官方說法是「業務條款仍在演變且複雜, + 不符合 Setapp 的商業模式」。來源: + `https://techcrunch.com/2026/02/22/move-over-apple-meet-the-alternative-app-stores-available-in-the-eu-and-elsewhere` + ——這說明依賴第三方替代市集作為 FMP iOS 分發管道本身帶有「市集可能 + 說關就關」的風險,不是一勞永逸的解法。 + +**結論**:FMP 若要在 iOS 提供側載版本,免費 Apple ID 路線對「持續使用」 +不友善(7 天要手動/背景重簽,且與其他側載 App 共用 3 個名額),付費 +開發者帳號(年費 $99)是唯一能拿掉這兩個限制的正式路徑;EU DMA +替代市集是另一條路,但只在歐盟地區有效、政策仍在 2026 年持續演進中 +(10 月 1 日還有新一輪資格開放),且已有替代市集中途關門的先例, +不宜當作長期穩定的唯一分發管道。 + +### 2.2 iOS 背景播放(Background Audio) + +**必要設定(事實)**:Xcode 的 Background Modes capability 需要勾選 +「Audio, AirPlay, and Picture in Picture」,對應在 `Info.plist` 寫入 +`UIBackgroundModes` 陣列並含 `audio` 值。來源:Apple 官方文件 +`https://developer.apple.com/documentation/xcode/configuring-background-execution-modes`。 + +**審核風險(事實,有多個開發者踩雷案例佐證)**:宣告了 `audio` 這個 +background mode,但**實際上沒有持續播放聲音的功能**,會被 Apple 審核 +以 **Guideline 2.5.4(Performance — Software Requirements)** 拒絕, +理由是「declares support for audio in the UIBackgroundModes key... but +did not include features that require persistent audio」。來源案例: +`https://devforum.zoom.us/t/ios-app-was-rejected-from-apple-appstore/37734`、 +`https://community.appinventor.mit.edu/t/audio-in-the-uibackgroundmodes-key-in-your-info-plis/113744`。 + +**結論**:FMP 是音樂播放器,背景持續播放本來就是核心功能,宣告 +`UIBackgroundModes: audio` 沒有 2.5.4 風險;但如果設計上出現「背景時 +播放器實際被系統暫停」的路徑(例如某些串流來源在背景會斷線),要注意 +這反而會製造審核風險,不是單純「加個 Info.plist key」就結束。 + +### 2.3 App Store 審核指引:下載第三方內容(YouTube 類)條款 + +**逐字核對現行 Apple 官方指引頁面**(來源: +`https://developer.apple.com/app-store/review/guidelines`,2026-09-27 +查證版本): + +- **5.2.3 Audio/Video Downloading**:「Apps should not facilitate + illegal file sharing or include the ability to save, convert, or + download media from third-party sources (e.g. Apple Music, YouTube, + SoundCloud, Vimeo, etc.) without explicit authorization from those + sources. Streaming of audio/video content may also violate Terms of + Use, so be sure to check before your app accesses those services. + Authorization must be provided upon request.」 +- **5.2.2 Third-Party Sites/Services**:「If your app uses, accesses, + monetizes access to, or displays content from a third-party service, + ensure that you are specifically permitted to do so under the + service's terms of use. Authorization must be provided upon + request.」 +- **2.5.2**:現行版本文字為「Apps should be self-contained in their + bundles, and may not read or write data outside the designated + container area, nor may they download, install, or execute code + which introduces or changes features or functionality of the app, + including other apps. Educational apps designed to teach, develop, + or allow students to test executable code may, in limited + circumstances, download code provided that such code is not used + for other purposes.」——這條規範的是「下載可執行程式碼」,跟 FMP + 下載媒體檔案(音訊)是不同的行為類別,不直接適用,但方向上共通點是 + 「Apple 對『App 執行期動態取得外部內容/程式碼』一律要求明確授權或 + 限縮用途」。 + +**FMP 的實際處境(推測,非官方逐字判定)**:FMP 播放/下載 Bilibili、 +YouTube、網易雲音樂的內容,若要上 App Store,5.2.3 與 5.2.2 +是最直接相關的兩條——**串流播放**本身已經處於「使用第三方服務內容」 +的灰色地帶(要看該服務 ToS 是否允許第三方 client 存取,這是各來源 +自己的服務條款問題,不是 Apple 一方能豁免的),**下載並保存到本機** +則幾乎確定會被視為 5.2.3 所指的「download media from third-party +sources... without explicit authorization」,這個問題不是「换個 +措辭」或「加個免責聲明」能解決,是 FMP 現有下載功能在 iOS App Store +分發模式下的結構性衝突(此為推測,實際判定以 Apple 審核當下為準, +但風險本身可從指引原文直接讀出,不是無中生有的推測)。 + +### 2.4 macOS 未公證(unnotarized)App 的安裝體驗與公證需求 + +**公證需要什麼(事實)**:需要 **Apple Developer Program 付費帳號** +(Developer ID 憑證),用 Developer ID 簽署後透過 `notarytool` +(`altool` 已於 2023-11-01 起停止接受上傳)送交 Apple 公證服務做 +自動安全掃描,通過後取得票證(ticket),讓 Gatekeeper 在使用者 +第一次執行/安裝時確認「已通過公證」。來源: +`https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution`、 +`https://developer.apple.com/developer-id`。 + +**未公證的使用者體驗(事實,且近年變嚴)**: + +- 傳統上使用者可以用「按住 Control 點兩下開啟」繞過 Gatekeeper 的 + 警告;但 **macOS Sequoia 起這條路徑被拿掉**,使用者必須改到 + 「系統設定 > 隱私權與安全性」裡手動允許該軟體執行。來源 Apple + 官方新聞稿:`https://developer.apple.com/news?id=saqachfa` + (原文:「In macOS Sequoia, users will no longer be able to + Control-click to override Gatekeeper... They'll need to visit + System Settings > Privacy & Security to review security + information for software before allowing it to run.」)。 +- 未公證但已簽署(或完全未簽署)的 App,Gatekeeper 會在啟動對話框中 + 顯示描述性警告資訊,幫助使用者判斷是否要繼續執行;公證本身對終端 + 使用者是「近乎無感」的背景流程,差別主要體現在這個警告訊息與 + Sequoia 之後那個多一步的系統設定操作。來源同上 + `notarizing-macos-software-before-distribution` 文件。 + +**結論**:FMP 若要在 macOS 上以「非 App Store」形式分發,公證不是 +必須(Gatekeeper 仍可被使用者手動放行),但 Sequoia 之後的手動放行 +流程比以前繁瑣(多一層系統設定),對一般使用者是明顯的安裝摩擦; +要做到「開箱能雙擊執行不嚇到使用者」,公證加 Developer ID 簽署 +(年費 $99 的 Apple Developer Program)是目前唯一官方認可的路徑。 + +### 2.5 Google Play 對 `MANAGE_EXTERNAL_STORAGE` 的限制 + +**官方允許用途(事實,逐字節錄自 Google 官方文件)**: + +> "For apps requesting access to the All files access permission, +> intended and permitted use includes file managers, backup and +> restore apps, anti-virus apps, and document management apps." + +來源:Play Console 官方說明 +`https://support.google.com/googleplay/android-developer/answer/10467955`; +Android 官方開發文件同樣列出這幾類:檔案管理、備份還原、防毒、文件 +管理,且需求必須「與 App 核心功能直接相關」。來源: +`https://developer.android.com/training/data-storage/manage-all-files`。 + +**明確不允許的用途(事實)**:官方文件明列「Media Files access」與 +「Any File selection activity where the user manually selects +individual files」是**無效用途**,這兩種情境應該改用 Storage Access +Framework 或 MediaStore API,而不是申請 `MANAGE_EXTERNAL_STORAGE`。 +來源同 `support.google.com` 上引文件。 + +**審核流程(事實)**:宣告此權限且目標 API 為 Android 11+ +的 App,Google Play 要求開發者完成 **Permissions Declaration Form** +並取得 Google 核准才能上架;Android Studio 本身也會對宣告此權限的 +App 顯示 lint 警告,提醒這項政策限制。來源: +`https://developer.android.com/training/data-storage/manage-all-files`。 + +**結論**:FMP 的下載/儲存功能如果只是「把音訊檔案存到 App 自己的 +下載目錄」,屬於 App-specific storage,根本不需要 +`MANAGE_EXTERNAL_STORAGE`;只有當設計要求「讓使用者自由選擇任意 +外部目錄存放下載檔案」時才會踩到這個權限,且即使申請也大機率不符合 +官方列出的允許用途(FMP 不是檔案管理員/防毒/備份還原/文件管理 +App),送審被拒的風險偏高。這對「檔案選取/應用程式目錄」的設計 +方向是明確訊號:優先走 Storage Access Framework(透過 `file_picker` +之類套件底層走 SAF)或 App 專屬目錄(`path_provider`),不要設計成 +需要 `MANAGE_EXTERNAL_STORAGE` 的形態。 + +### 2.6 Linux 打包格式的應用內自我更新可行性 + +| 格式 | 能否應用內自我更新 | 依據 | +|---|---|---| +| **AppImage** | **可以**,透過 `AppImageUpdate` 搭配 `zsync` 協定做差量更新,只下載檔案中真正變動的部分。更新資訊(update information)在打包時用 `appimagetool -u` 內嵌進 AppImage 本身。 | AppImage 官方打包指南 `https://docs.appimage.org/packaging-guide/optional/updates.html`;`appimage-builder` 官方文件 `https://appimage-builder.readthedocs.io/en/latest/advanced/updates.html`;`https://appimage.github.io/AppImageUpdate`(AppImageUpdate 官方頁面,甚至 AppImageUpdate 自己也是用同一套機制自我更新)。 | +| **Flatpak** | **官方立場是「App 不應該自己做更新」**,更新這件事是 Flatpak 執行環境本身的職責(`flatpak update`),由使用者的桌面環境(如 GNOME Software/KDE Discover)或排程任務(systemd timer)觸發。多個社群討論串證實 Flatpak **沒有內建的「App 自動更新」機制**,需要使用者手動或靠桌面環境的排程功能。 | `https://www.jwillikers.com/automate-flatpak-updates-with-systemd`(原文:「Flatpak doesn't provide an auto-update mechanism but instead leaves this up to software apps」——注意這裡的語境是指「Flatpak 平台不會主動幫你排程」,而不是「App 可以自己實作更新」;實務上 Flatpak sandbox 本身的權限模型也不鼓勵 App 繞過 Flatpak 機制自己下載並替換自身執行檔);Flathub 社群討論串進一步說明「an app bundles its dependencies... if one of these dependencies get updated you get a flatpak update」,更新的決策權在 manifest/repo 層級,不是 App 執行期自己觸發。來源:`https://discourse.flathub.org/t/flatpak-update-problem-again/10115`。 | +| **deb** | **不能**,`.deb` 格式本身沒有自我更新機制,更新完全依賴 `apt`/`dpkg` 或第三方封裝的倉庫管理工具(如 `deb-get`)去重新整理套件索引並安裝新版。 | Debian 官方文件 `https://www.debian.org/doc/manuals/debian-faq/pkgtools.en.html`(`apt update`/`apt upgrade` 的標準流程);`deb-get` 專案本身的存在(`https://github.com/wimpysworld/deb-get`)恰好反向證明:正因為原生 `.deb` 生態系沒有「App 自己更新自己」的機制,才需要這類第三方工具去統一管理「透過 GitHub 或直接下載發布的 `.deb` 套件」的更新流程。 | + +**結論**:三種 Linux 封裝格式裡,**只有 AppImage 適合做「應用內 +自我更新」**這個 FMP 設計問題(audit §7 開放問題 #4)的候選;Flatpak +理論上技術上可行但違反平台慣例(使用者與桌面環境預期「更新交給 +Flatpak 系統本身」,App 自己動手改變安裝內容甚至可能被 sandbox +權限擋下);deb 完全沒有這個能力,若要支援 `.deb` 分發,更新只能 +交給使用者手動下載新版或維護自己的 apt 倉庫(等於要自己維運一個 +套件源,複雜度遠高於單純做「應用內檢查更新」)。 + +--- + +## 第 3 點:同類 Flutter 音樂播放器的平台層架構 + +四個對照專案:Spotube(`KRTirtho/spotube`,近期已轉移組織至 +`team-spotube/spotube`)、Harmony Music(`anandnet/Harmony-Music`)、 +Finamp(已從 `jmshrv/finamp` 轉移到 `finamp-app/finamp`,預設分支是 +`redesign` 而非 `master`)、Namida(`namidaco/namida`,本身即針對 +Android **與桌面**,並非行動端專屬)。 + +### 3.1 依賴清單比較(逐字取自各自 `pubspec.yaml`) + +| 能力 | Spotube | Harmony Music | Finamp | Namida | +|---|---|---|---|---| +| 系統匣 | `tray_manager: ^0.5.0` | `tray_manager: ^0.2.3` | (未見於 pubspec,查不到是否有此功能) | `tray_manager`(**自己 fork**:`https://github.com/MSOB7YY/tray_manager`,非 pub.dev 版本) | +| 視窗管理 | `window_manager: ^0.4.3` | `window_manager: ^0.4.2` | `window_manager: ^0.5.1` | `window_manager: ^0.5.0` | +| 單一實例 | 查不到(pubspec 未見專門套件,可能走自訂或未實作) | 查不到 | 查不到 | **自己 fork**:`windows_single_instance`(`https://github.com/MSOB7YY/flutter_windows_single_instance`) | +| 系統媒體控制(Android/iOS/macOS) | `audio_service: ^0.18.13` | `audio_service: ^0.18.17` | `audio_service: ^0.18.18` + `audio_service_platform_interface: ^0.1.3` | `audio_service`(**自己 fork**:`https://github.com/MSOB7YY/audio_service`) | +| 系統媒體控制(Linux MPRIS) | `audio_service_mpris: ^0.2.0` | `audio_service_mpris: ^0.1.5` | `audio_service_mpris: ^0.2.0` | `anni_mpris_service: ^0.1.0`(pub.dev 官方版本,而非自己 fork——與其他能力大量自 fork 的風格不同,值得注意) | +| 系統媒體控制(Windows SMTC) | `smtc_windows: ^1.1.0` | `smtc_windows: ^0.1.2`(明顯落後版本) | `smtc_windows`(**用本地 path**:`packages/smtc_windows/`,pubspec 註解說明是因為對某些相依套件的版本鎖定需求) | `smtc_windows`(**用本地 path**:`packages/smtc_windows`) | +| 音訊引擎 | `media_kit`(**全部改用本地 path**:`media_kit`/`libs/android/`/`libs/ios/`/`libs/macos/`/`libs/windows/`/`libs/linux/`,等於自己 vendor 了一整份 media_kit 家族而非直接吃 pub.dev 版本) | `just_audio: ^0.9.46` + `just_audio_media_kit`(**自己 fork**:`https://github.com/anandnet/just_audio_media_kit.git`,用 just_audio 的介面包一層 media_kit 當桌面後端) | `just_audio`(**自己 fork**:`https://github.com/LennartEnns/just_audio_fork.git`,pubspec 註解明講原因:等官方 PR #1555 合併前的暫時替代)+ `just_audio_media_kit`(另一個 fork:`https://github.com/Komodo5197/just_audio_media_kit.git`)+ `media_kit_libs_linux`/`media_kit_libs_windows_audio` | `media_kit`(本地 path)+ `media_kit_video`/`media_kit_libs_linux`/`media_kit_libs_macos_video`/`media_kit_libs_windows_video`(官方 pub.dev 版本)+ `just_audio`(**自己 fork**:`https://github.com/MSOB7YY/just_audio`) | +| 登入 WebView | `flutter_inappwebview: ^6.1.5` + `desktop_webview_window`(**用本地 path**:`packages/desktop_webview_window`,等於也自己維護了一份 fork) | 查不到 | 查不到 | 查不到(Namida 本身不含帳號登入類來源,屬性質不同的播放器,此項目不適用,非查證疏漏) | +| 網路狀態 | 查不到(未見 `connectivity_plus`) | 查不到 | `connectivity_plus: ^7.0.0` | `connectivity_plus: ^7.0.0` | + +**觀察到的共通模式(事實,非推測)**:**四個專案沒有一個是「純吃 +pub.dev 發布版本」**——只要牽涉到桌面平台的音訊引擎(`media_kit`/ +`just_audio`)、Windows SMTC(`smtc_windows`)或更冷門的桌面能力, +四個專案裡有三個(Spotube、Finamp、Namida)都改用 **本地 path 依賴 +或自己 fork 的 git 依賴**,而不是直接引用 pub.dev 上的版本。這反映 +一個現實:pub.dev 生態系裡「桌面平台整合類」套件的發布節奏,追不上 +這些專案自己需要的修補速度或客製化需求,因此普遍策略是「先蹲點在 +一個能動的 fork/vendor 版本上,而不是被上游的發布週期綁住」。這對 +FMP 的設計啟示是:規劃桌面平台整合套件時,要預先假設「未來很可能 +需要 fork 或 vendor 某些套件」,不能假設 pub.dev 上的版本會一直 +剛好符合需求,設計上應該預留「套件來源可以是 git/path 而非純 +pub.dev version constraint」的彈性(這在 pubspec.yaml 語法上本來就 +支援,只是要在專案慣例/CI 裡承認並規範這種情況怎麽處理,例如要不要 +鎖 commit hash、要不要同時追蹤上游 PR 進度)。 + +### 3.2 平台差異程式碼的組織方式:集中 vs. 散落 + +**Spotube**:程式碼庫內找到明確的集中化檔案(來源: +`gh api repos/KRTirtho/spotube/git/trees/master?recursive=true` +逐一列出的路徑): + +- `lib/utils/platform.dart` —— 集中定義 `kIsDesktop`/`kIsMobile`/ + `kIsFlatpak` 之類的平台旗標常數,供全專案 import 使用(非 + 逐檔案重複寫 `Platform.isX`)。 +- `lib/services/wm_tools/wm_tools.dart` —— 把 `window_manager` 的 + 操作包一層自己的介面。 +- `lib/provider/tray_manager/tray_manager.dart` + + `lib/provider/tray_manager/tray_menu.dart` —— 系統匣邏輯獨立成 + 一個 provider 模組,不是散落在 UI 頁面裡直接呼叫 + `TrayManager.instance`。 +- `lib/services/audio_services/{audio_services.dart, + mobile_audio_service.dart, windows_audio_service.dart}` —— + 音訊服務依平台(行動端 vs. Windows)拆成不同檔案,但共用同一個 + 上層抽象檔案 `audio_services.dart` 做選擇分派。 + +**Namida**(四個對照專案裡集中化程度最徹底、最值得 FMP 直接參考的 +一個):整個 `lib/controller/platform/` 目錄本身就是一個「平台層」, +每個平台會有差異的能力各自一個子目錄,命名慣例統一為 +`.dart`(對外的統一介面/工廠)+ `_base.dart` +(共用抽象定義)+ `_.dart`(各平台實作),總共 +涵蓋:`app_single_instance`、`ffmpeg_executer`、`home_widgets`、 +`namida_channel`(原生 MethodChannel 封裝)、`namida_storage`、 +`permission_manager`、`shortcuts_manager`、`smtc_manager`、 +`tags_extractor`、`tray_manager`、`window_manager`、`zip_manager`, +共 12 個能力模組。來源: +`gh api repos/namidaco/namida/git/trees/main?recursive=true`。 + +實際機制(讀取 +`https://raw.githubusercontent.com/namidaco/namida/main/lib/controller/platform/base.dart` +與同目錄下 `tray_manager/tray_manager.dart`、 +`namida_channel/namida_channel.dart` 原始碼確認): + +- `base.dart` 定義一個泛型工廠 `NamidaPlatformBuilder`,核心方法 + `init({required android, required windows, linux, ios, macos})` + 內部用 `switch (defaultTargetPlatform) { TargetPlatform.android => + android(), ... }` 做分派,未支援的平台丟 + `UnimplementedError()`;另有 `initValue` 處理「值」而非 + 「建構函式」的情境,並用一個 sentinel object(`_unsupportedPlatform`) + 去區分「這個平台回傳 null」跟「這個平台根本不支援」兩種語意,避免 + 用 `null` 混用造成歧義。 +- 各能力模組的「對外介面檔」(如 `tray_manager.dart`、 + `namida_channel.dart`)本身**不是**用 Dart 語言層級的條件匯入 + (`if (dart.library.io)` 那種),而是用 **`part`/`part of`** + 把 `_base.dart`、`_android.dart`、`_linux.dart`、`_windows.dart` + 等檔案全部合併成同一個檔案的邏輯單元,執行期再靠 + `NamidaPlatformBuilder.init(...)` 動態決定要建構哪個實作類別。 + 這代表**所有平台的實作程式碼都會被一起編譯進最終產物**(不像 + 條件匯入那樣在編譯期就把不相關平台的程式碼排除掉),换來的好處是 + 程式碼閱讀動線更直覺(同一個能力的所有平台變體都在同一個邏輯檔案 + 群組裡,`part of` 語法上要求彼此可以互相直接引用型別而不用 + import),代價是理論上執行檔會包含用不到的其他平台程式碼(對 + Dart/Flutter 這種每個平台本來就是分開建置產物的情況,這個代價 + 在實務上通常可忽略——Windows 建置產物本來就不會真的執行到 + Android 分支的程式碼,只是原始碼/中介表示層次上都在)。 + +**Finamp**:只找到一個集中化訊號——`lib/utils/platform_helper.dart` +與 `lib/services/audio_service_smtc.dart`(來源: +`gh api repos/finamp-app/finamp/git/trees/redesign?recursive=true`), +規模遠不如 Namida,比較接近「有一個統一的平台判斷 helper,但沒有 +像 Namida 那樣每個能力都獨立成一個目錄」的中間型態。 + +**Harmony Music**:本次查證範圍內(僅 `pubspec.yaml` 逐項比對) +未進一步深入其 `lib/` 目錄結構,**查不到**其平台差異程式碼是集中 +還是散落——受限於研究時間,這個專案只完成依賴清單比對,架構層面 +留待需要時再補查。 + +### 3.3 結論:共通模式與對 FMP 的啟示 + +1. **沒有任何一個對照專案是「純用 `Platform.isX` 散落各處」**—— + 至少都有一個集中的平台旗標檔案(Spotube 的 + `lib/utils/platform.dart`、Finamp 的 `platform_helper.dart`), + 程度較深的(Namida)則是把每個「會隨平台變化的能力」都獨立成 + 一個目錄,用同一種「`_base.dart` + 各平台實作 + 一個工廠函式」 + 的樣板去組織,這與 Flutter 官方文件裡 federated plugin + 「共用抽象 + 各平台各自實作」的精神是一致的(見 + `platform-packages.md` 第 14 節),只是 Namida 是在應用層自己 + 重造了一套更輕量的版本,而不是真的發布成獨立 pub.dev 套件。 +2. **音訊/桌面整合類套件普遍要接受「fork 或 vendor」**,不是 + FMP 現況(audit 文件觀察到的三種平台判斷風格並存)特有的問題, + 而是這個生態系普遍的現實。 +3. 對 audit §7 開放問題 #11(是否該把三種平台判斷風格收斂成統一的 + capability 物件):Namida 的 `NamidaPlatformBuilder` 模式提供了 + 一個具體、已經在生產環境跑過的參考答案——**不是**做一個龐大的 + 「單一 capabilities 物件」把所有能力塞進同一個介面,而是「每個 + 能力各自一個小模組,共用同一套建構分派慣例(同名工廠函式/相同 + 目錄命名規則)」,讓新增一個平台差異點的成本是「照現有模式加一個 + 子目錄」,而不是「去改一個中央大物件的介面」。 + +--- + +## 待補查項(誠實列出) + +- Harmony Music 的 `lib/` 目錄結構(是否集中化平台判斷)——本次未 + 執行,查不到。 +- Spotube 是否有 `connectivity_plus` 或等價的網路狀態偵測——pubspec + 未見,查不到是否用其他方式判斷網路狀態(例如直接依賴 `dio` 的 + 請求失敗來間接判斷)。 +- EU DMA replacement marketplace 的 30 天跨區寬限期,來源為二手 + 整理文章而非 Apple 一手文件,正式寫入 design.md 前建議重新以 + `developer.apple.com/support/apps-in-the-eu` 或其連結的官方頁面 + 核對確切天數與生效條件。 diff --git a/.trellis/tasks/09-27-design-platform/task.json b/.trellis/tasks/09-27-design-platform/task.json new file mode 100644 index 000000000..bbf081066 --- /dev/null +++ b/.trellis/tasks/09-27-design-platform/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-platform", + "name": "design-platform", + "title": "Design: platform layer", + "description": "Phase-2 item 10: platform layer with declared capabilities, package choices for all five platforms, platform policy constraints, rollout order", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From d3d97d6671a09ec3ccfdc2fbae1e36929a70cfa4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 03:30:23 +0800 Subject: [PATCH 014/133] docs(adr): 0009 platform layer with declared capabilities --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../tasks/09-27-design-platform/implement.md | 6 +- .trellis/tasks/09-27-design-platform/prd.md | 6 +- .../tasks/09-27-design-platform/task.json | 4 +- ...atform-layer-with-declared-capabilities.md | 81 +++++++++++++++++++ 6 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 docs/adr/0009-platform-layer-with-declared-capabilities.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 5f2127100..526304c87 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -112,7 +112,7 @@ flowchart LR |---|---|---| | 1 | 9 文檔結構/ADR 去留(✅ 完成,見 `archive/2026-09/09-27-design-docs`) | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | | 2 | 7 重寫策略(高層)(✅ 完成,ADR 0008;里程碑留到第 20 步定稿) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | -| 3 | 10 平台層 | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | +| 3 | 10 平台層(✅ 完成,ADR 0009) | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | | 4 | 6 資料層與相容 | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | | 5 | 18 設定與日誌 | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | | 6 | 12 網路與帳號 | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 5ba1499ab..f57c76c76 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -21,7 +21,8 @@ "children": [ "09-26-audit", "09-27-design-docs", - "09-27-design-rewrite-strategy" + "09-27-design-rewrite-strategy", + "09-27-design-platform" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-platform/implement.md b/.trellis/tasks/09-27-design-platform/implement.md index aefe3c579..69235dcae 100644 --- a/.trellis/tasks/09-27-design-platform/implement.md +++ b/.trellis/tasks/09-27-design-platform/implement.md @@ -2,8 +2,8 @@ 本任務只產出設計與 ADR;平台層程式碼在第一個里程碑建立。 -- [ ] 依 `docs/adr/template.md` 寫 `docs/adr/0009-platform-layer-with-declared-capabilities.md`:design.md §1–§7 的決定、被否決的選項(沿用 `Platform.isX` 散落、只按 Android/Windows 設計的二分抽象、為未驗證平台寫空實作)、「如何確認」(lint 閘門與第 8 項的關係)。 -- [ ] `phase2-plan.md` 標記第 10 項完成。 -- [ ] 歸檔本任務。 +- [x] 依 `docs/adr/template.md` 寫 `docs/adr/0009-platform-layer-with-declared-capabilities.md`:design.md §1–§7 的決定、被否決的選項(沿用 `Platform.isX` 散落、只按 Android/Windows 設計的二分抽象、為未驗證平台寫空實作)、「如何確認」(lint 閘門與第 8 項的關係)。 +- [x] `phase2-plan.md` 標記第 10 項完成。 +- [x] 歸檔本任務。 驗證:ADR 內的 Mermaid 以 mermaid-cli 渲染;引用的研究檔與審計檔路徑存在。 diff --git a/.trellis/tasks/09-27-design-platform/prd.md b/.trellis/tasks/09-27-design-platform/prd.md index 81ae4ad5b..1399377a7 100644 --- a/.trellis/tasks/09-27-design-platform/prd.md +++ b/.trellis/tasks/09-27-design-platform/prd.md @@ -51,9 +51,9 @@ ## 驗收標準 -- [ ] design.md 涵蓋:平台層形狀、不寫空實作的做法、各能力×五平台的套件表、資料與下載目錄、平台政策、標題列與字型、上線順序與驗證、預期的平台 child task。 -- [ ] `docs/adr/0009-*.md` 依範本寫成,含被否決的選項與「如何確認」。 -- [ ] `phase2-plan.md` 標記第 10 項完成。 +- [x] design.md 涵蓋:平台層形狀、不寫空實作的做法、各能力×五平台的套件表、資料與下載目錄、平台政策、標題列與字型、上線順序與驗證、預期的平台 child task。 +- [x] `docs/adr/0009-*.md` 依範本寫成,含被否決的選項與「如何確認」。 +- [x] `phase2-plan.md` 標記第 10 項完成。 ## 延後到其他項目 diff --git a/.trellis/tasks/09-27-design-platform/task.json b/.trellis/tasks/09-27-design-platform/task.json index bbf081066..f30652232 100644 --- a/.trellis/tasks/09-27-design-platform/task.json +++ b/.trellis/tasks/09-27-design-platform/task.json @@ -3,7 +3,7 @@ "name": "design-platform", "title": "Design: platform layer", "description": "Phase-2 item 10: platform layer with declared capabilities, package choices for all five platforms, platform policy constraints, rollout order", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md new file mode 100644 index 000000000..52febc2b7 --- /dev/null +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -0,0 +1,81 @@ +# 0009 — 平台差異收進單一平台層,由平台宣告能力 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`app/lib/platform/`、所有依平台顯示或運作的 UI 與 service、平台相關依賴、CI 的平台矩陣 + +## 背景 + +舊專案有 88 處平台判斷、三種寫法並存(`Platform.isWindows`、`isDesktopPlatform`、`AudioRuntimePlatform`), +結果 macOS/Linux 會出現半套桌面 UI、沒有標題列、推測無法播放(`docs/audit/platforms.md` §0–§2)。 +重寫的長期目標是 Android、Windows、Linux、macOS、iOS 五平台;第一版只做 Android+Windows,其餘之後加入 +(`docs/audit/questions.md` A1)。擁有者希望各平台功能與體驗盡量一致,做不到才放棄。 + +研究(`.trellis/tasks/archive/2026-09/09-27-design-platform/research/`)確認:沒有一套套件能涵蓋五平台, +系統媒體控制、多視窗、登入 WebView 都要依平台拼接;同類 Flutter 播放器(Spotube、Finamp、Harmony Music、Namida) +都把平台差異集中在一層。 + +## 考慮過的選項 + +### 選項 A:沿用散落的平台判斷,只統一寫法 + +把三種寫法換成一種 helper。改動最小,但「哪些功能在哪個平台有」仍分散在各處,加一個平台就要全 repo 搜尋。 + +### 選項 B:只按 Android/Windows 設計抽象 + +以「行動/桌面」二分設計介面。第一版最快,但只有兩個平台時介面容易變成 if Windows/else Android 的包裝, +Linux、macOS 加入時要回頭改介面。 + +### 選項 C:單一平台層、每個平台宣告能力(採用) + +見下方決定。 + +### 附帶否決:為還沒驗證的平台先寫實作 + +先寫好 Linux/macOS/iOS 的實作「等之後驗證」。否決:沒人跑過的程式碼只會製造假的完成感。 + +## 決定 + +1. **平台層**:`app/lib/platform/`,每個能力一個目錄——`<能力>.dart`(介面與工廠)、`<能力>_<平台>.dart`(實作)。 + 能力包括托盤、視窗與標題列、全域快捷鍵、開機自啟、單一實例、桌面歌詞視窗、系統媒體控制、目錄規則、 + 應用內更新、登入 WebView、執行期權限。平台套件(`tray_manager`、`window_manager`、`hotkey_manager`、 + `smtc_windows`…)只在實作檔 import。 +2. **能力宣告**:每個平台一份不可變的 `PlatformCapabilities`。UI 依它決定是否顯示入口;service 只呼叫介面。 + 要在執行期才能判斷的(例如 Linux 在 Wayland 下沒有全域快捷鍵)由實作在啟動時寫進宣告。 +3. **平台層以外禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件的 import。 +4. **不寫空實作**:未驗證的平台宣告全部能力為「沒有」、沒有實作檔;該平台的 child task 開始時才加入實作。 +5. **原生呼叫**:新的 MethodChannel 一律用 Pigeon 產生型別安全介面。 +6. **套件**(各能力×平台的完整表在 design.md §3):系統媒體控制用 `audio_service`(Android/iOS/macOS)+ + Windows SMTC+Linux `audio_service_mpris`;托盤、視窗、快捷鍵、多視窗沿用現有套件並擴到其他桌面平台; + `connectivity_plus`、`file_picker`、`path_provider` 五平台共用。桌面套件需要修補時用 git 依賴鎖 commit,並註明上游 issue。 +7. **目錄**:Android 私有目錄;Windows 安裝版 application support(`%APPDATA%`)、Portable 版程式旁 `data/`; + Linux `~/.local/share`;macOS/iOS 沙盒 Application Support;開發版另用目錄與身分。舊 `Documents\FMP` 首次啟動時搬遷。 +8. **外觀**:Windows、Linux 用自訂標題列;macOS 保留系統紅綠燈按鈕。CJK 字型不內建,依平台 fallback。 +9. **上線順序**:Android、Windows 從第一個里程碑起全面驗證;Linux、macOS、iOS 從第一個里程碑起在 CI 編譯 + (iOS 加模擬器測試);Linux 在第一個里程碑後開 child task 於虛擬機實機驗證,之後每個里程碑冒煙測試; + macOS、iOS 取得設備後各開 child task。各平台在實機驗證完成後才發佈。 + +### 平台政策(決定的前提,免得重新研究) + +- iOS:不能自行安裝更新;App Store Guideline 5.2.3 與下載第三方媒體衝突,不上架;經 GitHub 發 IPA、以 + AltStore/SideStore 側載,免費 Apple ID 需 7 天重簽、最多 3 個 App;背景播放需 `UIBackgroundModes: audio`。 +- macOS:Sequoia 起未公證 App 無法以 Control-click 繞過 Gatekeeper,一般使用者順利安裝需付費開發者帳號公證。 +- Android:Google Play 不允許音樂播放器使用 `MANAGE_EXTERNAL_STORAGE`;FMP 不上 Play。 +- Linux:只有 AppImage 適合應用內自我更新;Flatpak 交給系統、deb 沒有機制。 +- 系統限制:Linux Wayland 不允許應用程式攔截全域按鍵(協定設計),只能經 portal 且功能縮水。 + +採用的慣例:Namida `lib/controller/platform/` 的每能力一目錄結構;Flutter 官方 federated plugin 的 +「共用介面+各平台實作」;Flutter 官方對平台分支的建議(`defaultTargetPlatform`、platform channel、Pigeon)。 + +## 後果 + +- 好的:加一個平台=加實作檔+改一份宣告;「哪個平台有什麼」一眼可查;未驗證平台不會有假裝能用的功能。 +- 壞的:每個能力多一層介面;Linux/macOS/iOS 在其 child task 完成前只有核心功能。 +- 之後要注意:登入 WebView 在 Linux 的選型、Android 下載儲存、音訊後端、Linux 打包與各平台更新機制分別在 + 網路與帳號、下載與權限、播放核心、發版與更新的 ADR 決定,並更新本 ADR 的套件表引用。 + +## 如何確認 + +- 平台層以外禁止平台判斷與平台套件 import:Dart analyzer lint(測試策略 ADR 選定工具後加上);在那之前由 PR review 檢查。 +- 能力宣告與 UI 一致:每個平台 child task 的驗收包含「宣告為沒有的能力,UI 不出現入口」。 +- CI:從第一個里程碑起建置矩陣含 Linux、macOS、iOS(不簽名)。 From 72a40544e7c5a82a3460a6089e9b612dabe6f0c0 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 03:30:24 +0800 Subject: [PATCH 015/133] chore(task): archive design-platform --- .../{ => archive/2026-09}/09-27-design-platform/check.jsonl | 0 .../{ => archive/2026-09}/09-27-design-platform/design.md | 0 .../2026-09}/09-27-design-platform/implement.jsonl | 0 .../{ => archive/2026-09}/09-27-design-platform/implement.md | 0 .../tasks/{ => archive/2026-09}/09-27-design-platform/prd.md | 0 .../09-27-design-platform/research/platform-packages.md | 0 .../research/platform-policy-and-peers.md | 0 .../{ => archive/2026-09}/09-27-design-platform/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/research/platform-packages.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/research/platform-policy-and-peers.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-platform/task.json (91%) diff --git a/.trellis/tasks/09-27-design-platform/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-platform/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-platform/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-platform/check.jsonl diff --git a/.trellis/tasks/09-27-design-platform/design.md b/.trellis/tasks/archive/2026-09/09-27-design-platform/design.md similarity index 100% rename from .trellis/tasks/09-27-design-platform/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-platform/design.md diff --git a/.trellis/tasks/09-27-design-platform/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-platform/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-platform/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-platform/implement.jsonl diff --git a/.trellis/tasks/09-27-design-platform/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-platform/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-platform/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-platform/implement.md diff --git a/.trellis/tasks/09-27-design-platform/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-platform/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-platform/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-platform/prd.md diff --git a/.trellis/tasks/09-27-design-platform/research/platform-packages.md b/.trellis/tasks/archive/2026-09/09-27-design-platform/research/platform-packages.md similarity index 100% rename from .trellis/tasks/09-27-design-platform/research/platform-packages.md rename to .trellis/tasks/archive/2026-09/09-27-design-platform/research/platform-packages.md diff --git a/.trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md b/.trellis/tasks/archive/2026-09/09-27-design-platform/research/platform-policy-and-peers.md similarity index 100% rename from .trellis/tasks/09-27-design-platform/research/platform-policy-and-peers.md rename to .trellis/tasks/archive/2026-09/09-27-design-platform/research/platform-policy-and-peers.md diff --git a/.trellis/tasks/09-27-design-platform/task.json b/.trellis/tasks/archive/2026-09/09-27-design-platform/task.json similarity index 91% rename from .trellis/tasks/09-27-design-platform/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-platform/task.json index f30652232..1365315cb 100644 --- a/.trellis/tasks/09-27-design-platform/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-platform/task.json @@ -3,7 +3,7 @@ "name": "design-platform", "title": "Design: platform layer", "description": "Phase-2 item 10: platform layer with declared capabilities, package choices for all five platforms, platform policy constraints, rollout order", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From 64ca621367691c80a5fdaa5245f2a2d6a27eedd4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 03:56:44 +0800 Subject: [PATCH 016/133] chore(task): plan phase-two item 6 (data layer and compatibility) --- .trellis/tasks/09-27-design-data/check.jsonl | 0 .trellis/tasks/09-27-design-data/design.md | 71 +++++ .../tasks/09-27-design-data/implement.jsonl | 0 .trellis/tasks/09-27-design-data/implement.md | 11 + .trellis/tasks/09-27-design-data/prd.md | 54 ++++ .../research/migration-feasibility.md | 241 ++++++++++++++ .../research/persistence-options.md | 300 ++++++++++++++++++ .trellis/tasks/09-27-design-data/task.json | 26 ++ 8 files changed, 703 insertions(+) create mode 100644 .trellis/tasks/09-27-design-data/check.jsonl create mode 100644 .trellis/tasks/09-27-design-data/design.md create mode 100644 .trellis/tasks/09-27-design-data/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-data/implement.md create mode 100644 .trellis/tasks/09-27-design-data/prd.md create mode 100644 .trellis/tasks/09-27-design-data/research/migration-feasibility.md create mode 100644 .trellis/tasks/09-27-design-data/research/persistence-options.md create mode 100644 .trellis/tasks/09-27-design-data/task.json diff --git a/.trellis/tasks/09-27-design-data/check.jsonl b/.trellis/tasks/09-27-design-data/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-data/design.md b/.trellis/tasks/09-27-design-data/design.md new file mode 100644 index 000000000..a0f29eab0 --- /dev/null +++ b/.trellis/tasks/09-27-design-data/design.md @@ -0,0 +1,71 @@ +# 設計:資料層與相容 + +採用的慣例:drift 官方的 schema 版本快照與 migration 測試(`drift_dev schema dump`/`SchemaVerifier`); +Spotube 的 drift+sqlite3 組合;一次性遷移模組「先寫到暫存、驗證後才換上」的保守做法(`research/migration-feasibility.md` §1.5)。 + +## 1. 選型 + +- `drift`+`sqlite3`(native assets 自動打包原生庫,不再用 `sqlite3_flutter_libs`)。 +- 資料庫檔放在 ADR 0009 §7 定義的資料目錄。 +- 只有資料層(repository)能碰資料庫;UI 與 service 透過 repository 介面。這延續舊 ADR 0002 的原則,閘門改成 import lint(第 8 項)。 + +## 2. Schema 原則 + +- **關係交給資料庫**:外鍵、`ON DELETE` 規則、唯一鍵;歌單與曲目用關聯表(含排序欄位),不再在曲目上存「屬於哪些歌單」的清單。 + 這直接消除舊版「啟動同步重建 `playlistInfo` → 孤兒清理刪曲目」那一類錯誤(`docs/audit/downloads.md` §4.4)。 +- **曲目身分**:`TrackKey` 字串格式沿用(ADR 0005,含 cid),作為曲目表的唯一鍵,也是遷移時對應舊資料的依據。 +- **只存事實,不存推導值**:不持久化 getter、格式化字串、`needsRefresh` 這類與時間有關的推導值。 +- **不存短期資料**:串流 URL 與其到期時間不進資料庫(B6,第 17 項)。 +- **下載紀錄獨立成表**:一首曲目的下載檔(路徑、格式、大小、來源歌單)存在下載表,不塞在曲目上(第 11 項細節)。 +- **設定也存在資料庫**:`shared_preferences` 的檔案位置由平台決定、不能跟著 Portable 版的 `data/` 走, + 所以設定放在同一個資料庫的設定表;分組與型別在第 18 項定。 +- 時間一律存 UTC epoch 毫秒;音源 id 用字串常數。 + +## 3. Schema 演進 + +- 每一版 schema 用 `drift_dev schema dump` 存快照進 repo;每個 migration 都有「從上一版升上來」的測試。 +- **migration 不得改寫使用者設定過的值**(M3、M4)。要改預設值時,只影響「沒設定過」的列;有對應測試。 +- migration 失敗時整個交易回滾,App 顯示錯誤頁,不在半升級的資料庫上啟動。 + +## 4. 舊資料自動遷移(legacy import) + +```mermaid +sequenceDiagram + participant App as 新 App 首次啟動 + participant LI as legacy_import 模組 + participant Old as 舊資料(Isar、secure storage 10.x、下載目錄) + participant Tmp as 暫存的新資料庫 + participant DB as 正式新資料庫 + App->>LI: 偵測到舊資料且尚未匯入 + LI->>Old: 唯讀開啟舊 Isar、讀舊憑證、讀舊下載紀錄 + LI->>Tmp: 轉換後在一個交易內寫入 + LI->>Tmp: 驗證:各表筆數、抽樣比對、外鍵完整 + alt 驗證通過 + LI->>DB: 把暫存資料庫換成正式資料庫,寫入匯入紀錄 + LI-->>App: 繼續啟動,舊資料原封不動 + else 失敗 + LI-->>App: 錯誤頁:重試/匯出診斷/先以空白資料啟動(舊資料保留,之後可再匯入) + end +``` + +- **模組**:`app/lib/legacy_import/`,唯一依賴 `isar_community` 與 `flutter_secure_storage` 10.x 的地方;其他程式不得 import 它。 +- **資料庫**:從舊位置(Android 私有目錄、Windows `Documents\FMP`、舊 Portable 目錄)唯讀開啟;轉換規則以舊 schema 的實際欄位為準(`docs/audit/data.md` §1)。 + 舊版被 migration 強制改過的設定(例如 v3→v4 的 B 站播放認證)無法還原原值,照現值匯入。 +- **憑證**:用與舊版相同的 `flutter_secure_storage` 10.x 讀出,寫進新的憑證存放處(第 12 項定);讀不到的音源標記為「需要重新登入」,不崩潰、不影響其他資料。 +- **已下載檔**:不搬動檔案;依舊資料庫的下載路徑與舊下載目錄掃描結果,登記進新的下載表;找不到的檔案不登記。 +- **舊備份檔**:備份匯入支援舊格式,與資料庫匯入共用同一套「舊 DTO → 新 schema」轉換。 +- **舊檔保留**:遷移永遠不刪舊檔。App 內提供「刪除舊版資料」的按鈕(匯入成功後才出現)。 +- **模組保留期限**:舊版允許跳版升級,所以 legacy import 模組與它的兩個舊依賴一直保留,直到擁有者另立 ADR 移除(移除前需公告最低升級路徑)。 + +## 5. 要在第一個里程碑實測的技術風險 + +- `isar_community` 與 `sqlite3` 兩套原生庫在同一個 App 共存(Android、Windows)。若衝突:legacy import 改成獨立的一次性小程式,由新 App 啟動它。 +- `sqlite3` 原生庫在 Android 的 16KB page size 對齊(用官方對齊檢查腳本)。 +- 在擁有者真實資料的**副本**上跑完整遷移(沿用舊 repo `test/manual/real_db_probe.dart` 的做法:以環境變數指向副本),切換前必須通過。 + +## 6. 舊 ADR + +- ADR 0002(Isar 只在 repository)與 0007(Isar 停在 v3)描述的是根目錄舊專案,舊專案在切換前仍需緊急修正時會用到。 + 因此**不在寫新 ADR 時刪除**,改為在切換 PR 連同舊專案一起刪除;新 ADR 註明它們只適用舊專案。 + (這是對第 9 項規則的細化:被取代的 ADR 若仍描述凍結中的舊專案,隨舊專案在切換時刪除。) +- ADR 0005 沿用;新 ADR 引用它。 diff --git a/.trellis/tasks/09-27-design-data/implement.jsonl b/.trellis/tasks/09-27-design-data/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-data/implement.md b/.trellis/tasks/09-27-design-data/implement.md new file mode 100644 index 000000000..e3780e935 --- /dev/null +++ b/.trellis/tasks/09-27-design-data/implement.md @@ -0,0 +1,11 @@ +# 執行計畫 + +本任務只產出設計與 ADR;資料層與 legacy import 在里程碑中實作。 + +- [ ] 寫 `docs/adr/0010-drift-data-layer-and-legacy-import.md`:design.md §1–§6,被否決的選項(留在 isar_community、ObjectBox、Hive CE、Realm、設定用 shared_preferences、遷移後自動刪舊檔、遷移成功一版後就移除 legacy 模組),「如何確認」(schema 快照+migration 測試、「不改使用者值」測試、真實資料副本遷移、import lint)。 +- [ ] 在 ADR 0002、0007 開頭加一行:「只適用根目錄舊專案;新專案見 ADR 0010;切換時隨舊專案刪除」。 +- [ ] 第 9 項規則的細化寫進 `docs/adr/template.md` 的註解(被取代但仍描述凍結舊專案的 ADR,切換時刪除)。 +- [ ] `phase2-plan.md` 標記第 6 項完成,並在「第一個里程碑的必要驗證」記下 design.md §5 三項。 +- [ ] 歸檔本任務。 + +驗證:Mermaid 以 mermaid-cli 渲染;`git grep -n "ADR 0002\|ADR 0007\|0002-repository\|0007-isar"` 的命中都仍指向存在的檔案。 diff --git a/.trellis/tasks/09-27-design-data/prd.md b/.trellis/tasks/09-27-design-data/prd.md new file mode 100644 index 000000000..71f738abe --- /dev/null +++ b/.trellis/tasks/09-27-design-data/prd.md @@ -0,0 +1,54 @@ +# 設計第 6 項:資料層與相容 + +## 目標 + +選定新 App 的持久化方案(五平台),定下 schema 原則,並設計舊資料(資料庫、登入憑證、已下載檔、備份檔) +在新 App 首次啟動時的自動遷移。 + +需求來源:parent `prd.md` 階段二第 6 項;`questions.md` A2(不確定,請推薦)、A3(全部自動遷移)、 +A4(資料位置,按推薦)、B6(串流 URL 不存資料庫)、M3/M4(migration 不得改使用者設定值);ADR 0008、0009。 + +## 已確認的前提 + +- 新 App 沿用舊 App 身分(ADR 0008),才讀得到 Android 私有目錄的舊資料與 Keystore 保護的憑證。 +- 資料目錄:安裝版用系統 App 資料目錄、Portable 版在程式旁 `data/`、舊 `Documents\FMP` 首次啟動搬遷(ADR 0009 §7)。 +- 串流 URL 只放短期快取,不進資料庫(B6,第 17 項細節)。 +- migration 不得改寫使用者自己設定過的值(M3、M4)。 +- `TrackKey` 字串格式(含 cid)確認沿用(ADR 0005)。 + +## 現況(證據) + +- 舊資料層:`isar_community` 3.3.2,11 個 collection、沒有 IsarLink,關係靠手動 id/字串鍵;沒標 `@ignore` 的 getter 也被持久化(`docs/audit/data.md` §1)。 +- 舊 migration:`kFmpSchemaVersion`,整段包在一個交易;v3→v4 無條件改寫使用者設定(`data.md` §2;`accounts-network.md` §7)。 +- 舊憑證:`flutter_secure_storage` 刻意固定在 10.x:v10 第一次讀取時重新加密 Android 憑證,11.x 移除了 9.x 的 cipher,沒跑過 10.x 的安裝升到 11.x 會讀不出憑證(`pubspec.yaml:68-73`、`.github/dependabot.yml:46-54`)。 + +## 研究結論(`research/persistence-options.md`、`research/migration-feasibility.md`) + +- **drift(SQLite)**:2.35.0(2026-09-09),五平台;`sqlite3` 3.x 以 native assets 自動打包原生庫,不再需要 `sqlite3_flutter_libs`; + 有官方 schema 版本快照與 migration 測試工具;反應式查詢、isolate、FTS5;資料檔可用任何 SQLite 工具檢視。Spotube 採用。 +- **isar_community**:可留在 v3 原地打開舊檔;但長期依賴社群 fork,migration 靠自建機制,Linux/macOS/iOS 未驗證。 +- **ObjectBox**:五平台,但 schema 遷移細節與 FTS 證據不足。**Realm**:一年以上未發版,不建議。**Hive CE**:輕量 KV,不適合當主資料層。 +- 同類播放器:Spotube drift+shared_preferences;Finamp isar fork+hive_ce(長期共存);Namida 加密 sqlite3+JSON 設定檔;Harmony 純 hive。 +- 換庫遷移:新 App 需暫時依賴 `isar_community` 讀舊檔;Finamp 證明 Isar 能與另一個資料庫長期共存,但 isar+sqlite3 兩套原生庫共存沒有直接先例(原理上風險低),需在第一個里程碑實測。 +- sqlite3 的 Android 16KB page size 問題上游已修,仍需用對齊腳本實測一次。 + +## 已決定 + +- D1(使用者 2026-09-27):換成 drift(SQLite)。 +- 其餘依研究與「按推薦」寫入 design.md:設定存資料庫(因 Portable 版目錄)、legacy import 模組、舊檔不自動刪、 + 模組保留到另立 ADR、ADR 0002/0007 隨舊專案在切換時刪除。 + +## 需求 + +- R1 資料庫只由資料層存取(import lint,第 8 項)。 +- R2 關係用外鍵與關聯表;不持久化推導值與串流 URL;`TrackKey` 為曲目唯一鍵。 +- R3 每版 schema 有快照,每個 migration 有升級測試;migration 不改使用者設定過的值,有對應測試。 +- R4 首次啟動自動匯入舊資料庫、憑證(讀不到則標記需重新登入)、已下載檔(不搬檔);舊備份可匯入;全部先寫暫存、驗證通過才換上,失敗不留半套資料。 +- R5 遷移不刪舊檔;匯入成功後提供手動刪除入口。 +- R6 第一個里程碑實測:isar+sqlite3 共存、16KB 對齊;切換前在真實資料副本上跑通遷移。 + +## 驗收標準 + +- [ ] design.md 涵蓋選型、schema 原則、schema 演進、legacy import 流程與失敗處理、實測風險、舊 ADR 處理。 +- [ ] `docs/adr/0010-*.md` 依範本寫成;ADR 0002、0007 加註只適用舊專案。 +- [ ] `phase2-plan.md` 標記第 6 項完成並記下第一個里程碑的必要驗證。 diff --git a/.trellis/tasks/09-27-design-data/research/migration-feasibility.md b/.trellis/tasks/09-27-design-data/research/migration-feasibility.md new file mode 100644 index 000000000..d6a100074 --- /dev/null +++ b/.trellis/tasks/09-27-design-data/research/migration-feasibility.md @@ -0,0 +1,241 @@ +# 遷移可行性研究:Isar 共存、原生函式庫、flutter_secure_storage 相容性 + +範圍:`.trellis/tasks/09-27-design-data` 研究項目 3、4。標記慣例同 +`persistence-options.md`:「查不到」=已查但沒有可信來源;「推測」=有間接 +證據但未直接證實。 + +擁有者硬性要求(`.trellis/tasks/09-27-design-data/prd.md`、對照 +`docs/adr/0008-rewrite-as-new-app-in-same-repo.md` 決定 3「App 身分沿用」): +舊資料庫、登入憑證(`flutter_secure_storage`)、下載檔案、舊備份檔全部 +**自動遷移**,不需要使用者手動操作。 + +## 1. 若換資料層:暫時依賴 isar_community 讀舊檔的可行性 + +### 1.1 是否可行 + +可行。`isar_community` 是可獨立引入的一般 Dart/Flutter 套件,不需要開啟成 +「主資料層」才能用——新 App 可以只用它的 `Isar.open()` + 對應的 schema class +把舊資料庫檔案打開、讀出所有 collection 的資料,轉換寫入新資料層(drift/ +ObjectBox/其他),跑完就不再需要它。這正是 FMP 現有 ADR 0007 已經驗證過的 +使用方式的子集——ADR 0007 證實「一份 3.1.0+1 寫出的真實資料庫(1,534 列)的 +副本能原地打開、反序列化、寫入後讀回」,代表 isar_community 讀取現行 FMP +資料庫格式沒有相容性障礙。 + +Schema class 定義需要與 FMP 現行 11 個 collection 的 schema id/property id +完全一致才能正確反序列化(`docs/audit/data.md` 已盤點這些定義),這部分是 +「複製 FMP 現有 model 定義」而非重新設計,风险集中在把這些 class 從舊 +`isar`/`isar_community` 依賴版本正確搬到新 App 的 `pubspec.yaml`。 + +### 1.2 isar_community 與 drift(sqlite3) 能否共存(原生函式庫衝突) + +**直接證據(同一組件並存於同一 App,長期生產環境)**:Finamp 目前的 +`pubspec.yaml` 同時依賴 `isar`(fork:`Komodo5197/isar-community.git`,透過 +override 指向社群 fork,與 FMP 使用的 fork 系出同源但非同一個 fork)與 +`hive_ce`,兩者長期並存於同一個 App 且都在生產環境使用,`main.dart` 同時 +`Isar.open(...)` 與 Hive 的初始化互不干擾: + +```dart +_mainLog.info("Setup hive and isar"); +... +final isar = await Isar.open( + [DownloadItemSchema, IsarTaskDataSchema, FinampUserSchema, DownloadedLyricsSchema], + directory: ..., + name: isarDatabaseName, +); +``` + +來源:https://github.com/finamp-app/finamp/blob/master/lib/main.dart + +**這個證據的侷限,必須明確標註**: +- Finamp 並存的是 Isar + Hive CE,**不是** Isar + drift/sqlite3。Hive 是純 + Dart 實作,沒有自己的原生函式庫;drift/sqlite3 則會透過 native assets + 機制打包一份原生 SQLite 動態函式庫。「Isar + Hive 共存沒問題」不能直接 + 證明「Isar + drift/sqlite3 共存沒問題」,因為後者牽涉兩套不同的原生函式庫 + 同時存在同一個 App 進程內。 +- **沒有查到**任何專案同時依賴 `isar`/`isar_community` 與 + `sqlite3`/`sqlite3_flutter_libs`/drift 的公開範例(查了 GitHub code + search 與 pub.dev 依賴關係,沒有命中)。 +- 從**技術原理**推測(標記「推測」,可信度中高):isar 的原生函式庫符號是 + `isar_*` 前綴(`libisar.dll`/`isar_community` 對應改名為 + `libisar.dll`,依 ADR 0007「Windows 的 library 名稱從 `isar.dll` 變成 + `libisar.dll`」),sqlite3 的原生函式庫符號是 `sqlite3_*` 前綴,兩者 + 函式庫命名空間不重疊,理論上不會有連結期符號衝突;分屬不同的動態函式庫檔案 + (`.so`/`.dll`),作業系統的動態載入器本身就是為多個獨立函式庫共存設計的, + 沒有已知的技術原因會讓兩者無法在同一個 App 裡同時載入。真正的風險點通常是 + Android 的 native library 打包(多個外掛都想放同名 `.so` 或使用同一個 + ABI 目錄)與建置工具鏈整合,而非執行期衝突。 +- **建議**:由於是「暫時共存」(遷移完成即可移除 isar_community 依賴,不是 + 永久架構),實際風險可以用一個小驗證(在 tracer bullet 階段內建置一個同時 + 引入兩個依賴的最小 App,跑一次 `flutter build apk`/`flutter build windows` + 確認建置與啟動皆正常)在成本很低的情況下排除,不需要在研究階段就下定論; + 若驗證失敗,退路是把遷移模組拆成獨立的 Dart 執行檔/腳本(不進 Flutter App + bundle),只在遷移那一次性流程中跑,執行完即丟棄,徹底避開打包期衝突。 + +### 1.3 打包體積影響 + +**沒有查到**具體的位元組數字(isar_community 原生函式庫加 sqlite3 原生 +函式庫同時打包會增加多少 APK/安裝檔大小),需要實測才能有確切數字。可以 +給出量級推測(標記「推測」):isar 原生函式庫按平台通常是數 MB 等級 +(ADR 0007 提到的目標 ABI 是 Android `arm64-v8a`/`armeabi-v7a`/`x86_64` +與 Windows `x86_64`),sqlite3 原生函式庫本身通常也是 1 MB 內的等級,兩者 +同時打包對現代 App 的總安裝檔大小(通常數十 MB 起跳)影響比例不大,但如果 +是**永久性**同時依賴(而非遷移用完即丟),仍建議實測後再下結論。由於本研究 +的情境是「臨時遷移用」,遷移模組完成後即可從 `pubspec.yaml` 移除 +`isar_community` 依賴,之後的正式版打包不受影響。 + +### 1.4 Android 16 KB page-size 對齊:sqlite3(Dart 套件)現況 + +ADR 0007 已確認 isar_community 的 Android library 是 16 KB 對齊 +(`docs/adr/0007-isar-stays-on-v3.md`)。查證 sqlite3(Dart 套件)本身: + +- `sqlite3.dart`(simolus3/sqlite3.dart)的 CHANGELOG 沒有直接提及 + 「16KB」「page size」「16384」等字樣(已查,無命中)——**這點單獨查證是 + 「查不到」**。 +- 但 GitHub Issues 上有多筆關於此套件與 16 KB page-size 的討論並且**都已 + 關閉**: + - #308「16KB page size not supported」——維護者 + (simolus3)在留言中說明:「I've added 16 KiB page size support somewhat + recently (last year I believe)」,指向的是 `sqlite3_flutter_libs` 這個 + 外掛套件本身的原生函式庫版本問題;回報者最後查明是**專案依賴了另一個 + 過舊的 `sqlite3-native-library` Android 版本**,不是 `sqlite3.dart`/ + `sqlite3_flutter_libs` 本身缺乏支援,更新依賴版本後解決並關閉此 issue。 + 來源:https://github.com/simolus3/sqlite3.dart/issues/308 + - #320「16KB Page Size Support Warning」、#321「Google Play's 16 KB page + size compatibility」、#257「Failed to load dynamic library ... 16KiB + page size」——皆為同一類問題(依賴版本過舊或 Google Play 檢查腳本誤判), + 均已關閉。 +- **結論(推測,可信度中高)**:`sqlite3`/`sqlite3_flutter_libs` 上游已在 + 約 2024–2025 年間修好 16 KB 對齊問題,只要依賴版本夠新(本研究建議的方案是 + 透過 native assets 自動打包的最新 `sqlite3` v3.x,而非舊版 + `sqlite3_flutter_libs`),16 KB 對齊應該沒有問題。但**沒有查到**官方對 + 「native-asset 打包管線(build hooks)產出的 binary 是否沿用同一套已修好 + 對齊問題的原生原始碼與建置腳本」的明確重申文件——這點技術上兩者本來就是 + 同一套上游 C 原始碼,只是打包/分發機制不同,可信度高但不是 100% 官方 + 明文保證,仍標記為「推測」。建議在設計文件定案前,用 + `developer.android.com` 官方提供的 ELF alignment 檢查腳本 + (https://developer.android.com/guide/practices/page-sizes#alignment-use-script) + 對 tracer bullet 階段產出的 APK 實測一次,取得確定結論而非依賴文件推測。 + +### 1.5 其他專案常見的「一次性遷移模組」模式 + +從 Finamp 案例(雖然遷移方向與 FMP 相反,但模式本身可直接借鑑)歸納出兩種 +模式,FMP 可依情境擇一: + +- **模式 A:搬移後保留旧資料,靠旗標防止重跑**(Finamp + `FinampUserHelper.migrateFromHive()`): + ```dart + Future migrateFromHive() async { + await Hive.openBox("FinampUsers"); + await Hive.openBox("CurrentUserId"); + var currentUserId = Hive.box("CurrentUserId").get("CurrentUserId"); + if (currentUserId != null) { + var currentUser = Hive.box("FinampUsers").get(currentUserId); + if (currentUser != null) { + _isar.writeTxnSync(() { + _isar.finampUsers.putSync(currentUser, saveLinks: false); + }); + } + } + } + ``` + 呼叫端由 `hasCompletedIsarUserMigration` 設定旗標防止重複執行,**不刪除** + 舊的 Hive box——舊資料留在磁碟上,只是不再被讀取。 +- **模式 B:搬移後清掉舊儲存**(Finamp 同一個 codebase 內的 + `_migrateThemeModeLocale`):複製完成後明確呼叫 + `oldThemeModeBox.deleteFromDisk()`/`oldLocaleBox.deleteFromDisk()`, + 再標記完成旗標。 + 來源(模式 A、B 皆出自): + https://github.com/finamp-app/finamp/blob/master/lib/services/finamp_user_helper.dart + 、`lib/main.dart` 同檔。 + +FMP 的情境(自動遷移整個舊資料庫、憑證、下載檔、備份檔,且擁有者要求 +「自動」而非使用者手動觸發)比較貼近**模式 A** 再加上「遷移驗證通過才刪除 +舊檔」的保守版本:先用旗標+完整性檢查確認新資料層內容與舊資料庫一致,才 +清理舊 Isar 檔案,避免遷移中途失敗導致資料兩邊都不完整。這與 +`docs/adr/0008-rewrite-as-new-app-in-same-repo.md` 決定 5「切換」條款一致 +(「舊資料自動遷移在真實資料副本上驗證過之後」才刪除舊專案)——但那條講的是 +「刪除舊 App 程式碼」的時機,遷移模組本身「何時刪除使用者裝置上的舊資料庫 +檔案」是另一個需要在 design.md 明訂的獨立決策點。 + +## 2. flutter_secure_storage + +### 2.1 五平台支援與各平台後端 + +| 平台 | 後端套件 | 實際儲存機制 | 來源 | +|---|---|---|---| +| Android | 內建於主套件 | Android Keystore + EncryptedSharedPreferences | https://pub.dev/packages/flutter_secure_storage | +| iOS | 內建於主套件 | Keychain | https://pub.dev/packages/flutter_secure_storage | +| macOS | 內建於主套件 | Keychain | https://pub.dev/packages/flutter_secure_storage | +| **Windows** | `flutter_secure_storage_windows` | **混合式**:每個 key 的值用 AES-GCM 加密後存成獨立 `.secure` 檔案,放在 App 的 support 目錄;AES-GCM 的加密金鑰本身存在 **Windows Credential Manager**(不是常見誤解的「純 DPAPI」) | https://pub.dev/documentation/flutter_secure_storage_windows/latest | +| **Linux** | `flutter_secure_storage_linux` | 透過 **libsecret**(`org.freedesktop.Secret`/`org.freedesktop.portal.Secret`),需要有執行中的 keyring 服務(`gnome-keyring`、`kwalletmanager`,或輕量的 `secret-service`);支援 Flatpak/沙盒環境(走 portal);新版 Freedesktop runtime(25.08+)/GNOME 49/KDE 6.10+ 已內建 libsecret,App 不必自行編譯進去 | https://pub.dev/packages/flutter_secure_storage | + +FMP 目標第一版平台是 Android+Windows,兩者後端都已查證:Android 走 +Keystore-backed EncryptedSharedPreferences,Windows 走上述混合式機制,皆為 +成熟、持續維護的官方後端,沒有查到相容性風險。Linux(未來平台)需要注意 +執行環境必須有 keyring 服務在跑,這是 Linux 桌面環境的外部依賴,不是套件 +本身的問題——若目標是 AppImage/Flatpak 散布,需要在該平台的 child task +額外驗證 keyring 服務的可用性假設是否成立。 + +### 2.2 新版能否讀舊版寫入的值(10.x → 最新版) + +**沒有查到**官方文件或 CHANGELOG 對「跨大版本讀取相容性」的明確保證聲明 +(例如「10.x 寫入的值保證能被最新版讀取」這類逐字聲明)。從技術層面推斷 +(標記「推測」,可信度中): + +- Android/iOS/macOS 三個平台的底層儲存機制(Keystore、Keychain)本身是 + 作業系統管理的服務,不是套件自己控制的檔案格式,只要金鑰/識別子命名規則 + 沒有跨版本改變,理論上舊版寫入的值可以被新版正常讀出——這类风险主要來自 + 套件本身是否在某次大版本更新中**改變了 key 的命名空間或加密參數**,而非 + 作業系統層面的問題。 +- Windows/Linux 後端因為是套件自己實作的邏輯(AES-GCM 檔案格式、libsecret + schema),版本間相容性完全取決於這兩個聯邦套件( + `flutter_secure_storage_windows`、`flutter_secure_storage_linux`)自己的 + CHANGELOG 有沒有做過破壞性格式變更——這點需要在真正決定升級版本號之前, + 針對目標新版本逐一讀過這兩個套件從 10.x 到最新版之間的 CHANGELOG 找 + 「BREAKING」「format change」「migration」等字樣,本研究**尚未逐版讀完 + 完整 CHANGELOG**,標記為此項研究的已知缺口,建議設計 migration 模組時 + 另外花時間做這個逐版 CHANGELOG 檢查,或更保守地採用「用舊版本讀出全部值→ + 用新版本重新寫入」的顯式遷移步驟,完全繞開「新版本能不能讀舊版本格式」 + 這個問題本身。 + +### 2.3 FMP 舊版為何刻意停在 10.x + +對舊專案根目錄 `pubspec.yaml` 執行 `grep -n -B3 -A3 flutter_secure_storage`, +找到明文理由(一手證據,非推測): + +``` +# 「10.x 發過一版」不等於「每個安裝都遷移過」—— 沒跑過 10.x 的安裝一升到 11.x +# 就讀不出憑證,只因 `SecureKeyValueStore` 的防護才降級成重新登入而不是崩潰。 +# `.github/dependabot.yml` 因此 ignore 它的大版本。 +flutter_secure_storage: ^10.3.1 # Cookie/Token 安全儲存 +``` + +來源:`C:\Users\Roxy\orca\FMP\pubspec.yaml:70-73`(現行舊專案根目錄)。 + +**這是本研究對「新版能否讀舊版寫入的值」最直接、最具體的一手證據**,比 +2.2 節的官方文件推測更可信,且結論是**否定**的一個具體案例:從 +`flutter_secure_storage` 10.x 升到 11.x 存在已知的讀取相容性斷層—— +**不是「每個裝置都會壞」,而是「沒有實際跑過 10.x 版本程式碼的安裝,一旦 +直接升級到 11.x 就讀不出用舊格式寫入的憑證」**。FMP 現行程式碼靠自製的 +`SecureKeyValueStore` 包裝層吸收了這個問題,讀取失敗時的行為降級成「要求 +使用者重新登入」而不是讓 App 崩潰,把資料遺失的後果限制在「使用者體感是 +被登出」而非資料損毀或當機。`.github/dependabot.yml` 也因此手動 ignore 這個 +套件的大版本升級 PR,是刻意的、有記錄的決定,不是疏漏。 + +**對新 App 的設計意涵**: +1. 這個案例直接證明「假設新版能讀舊版格式」是不安全的預設——即使同一個套件 + 的同一個大版本區間內(10.x→11.x)都可能出現讀取斷層,遑論新 App 若選用 + 更新的大版本。 +2. 新 App 若要讀取舊 App 用 `flutter_secure_storage` 10.x 寫入的憑證,最 + 穩妥的路徑是:新 App 的遷移模組**暫時也依賴 `flutter_secure_storage` + 10.x**(與舊 App 完全相同的版本)去讀出憑證明文,讀出後立刻用新 App + 正式採用的版本(可以是最新版)重新寫入,寫入格式由新版本自己決定, + 不依賴任何「跨版本讀舊格式」的隱含假設。這與舊 App 現行的 + `SecureKeyValueStore` 保護精神一致:讀取失敗要降級成「要求重新登入」而 + 非讓遷移流程整個中止或崩潰,若讀取失敗,新 App 應该允許使用者用登入 + 流程重新取得憑證,而不是把整個資料遷移判定為失敗。 +3. `docs/adr/0008-rewrite-as-new-app-in-same-repo.md` 決定 3「App 身分沿用」 + 確保新 App 與舊 App 共用 Android Keystore/Windows Credential Manager + 的存取範圍(同一個 `applicationId`/簽名金鑰),這是「新 App 能不能讀到 + 舊 App 憑證」的**前提**(身分不同,作業系統層面就不會授權存取),本節談 + 的是「身分符合的前提下,套件版本間的格式相容性」這個獨立的第二層風險。 diff --git a/.trellis/tasks/09-27-design-data/research/persistence-options.md b/.trellis/tasks/09-27-design-data/research/persistence-options.md new file mode 100644 index 000000000..a058c6f8d --- /dev/null +++ b/.trellis/tasks/09-27-design-data/research/persistence-options.md @@ -0,0 +1,300 @@ +# 資料持久化層研究:候選比較、同類播放器、設定存放 + +範圍:`.trellis/tasks/09-27-design-data` 研究項目 1、2、5。標記慣例:「查不到」=已查 +但沒有可信來源;「推測」=有間接證據但未直接證實。每個具體宣稱附來源 URL。 + +## 1. 候選資料層比較 + +候選:drift(SQLite)、sqflite/sqlite3 直接用、isar_community(留在 v3)、 +ObjectBox、Hive CE(`hive_ce`)、Realm。 + +### 1.0 版本與維護狀態(pub.dev API,2026-09-27 查) + +| 套件 | 最新版 | 發布日期 | 來源 | +|---|---|---|---| +| `drift` | 2.28.2(依查詢當下) | 持續 2026-09 內有發布 | https://pub.dev/api/packages/drift | +| `sqlite3` | 3.x 系列 | 持續 2026-09 內有發布 | https://pub.dev/api/packages/sqlite3 | +| `sqlite3_flutter_libs` | 0.6.0+eol | 2026-02-15,**明確標記 EOL** | https://pub.dev/packages/sqlite3_flutter_libs | +| `isar_community` | 3.x(社群 fork) | 2026-03-23 | https://pub.dev/api/packages/isar_community | +| `objectbox` / `objectbox_flutter_libs` | 最新穩定 | 2026-05-20 | https://pub.dev/api/packages/objectbox | +| `hive_ce` / `hive_ce_flutter` | 最新穩定 | 持續 2026-09 內有發布 | https://pub.dev/api/packages/hive_ce | +| `realm` | 20.2.0 | 2025-09-24,**其後無任何新版**(查詢時已隔一年未更新) | https://pub.dev/api/packages/realm | + +Realm/MongoDB Atlas Device SDK 結論:最新版距今逾一年沒有更新,維護狀態明顯停滯, +列為候選但不建議採用;本專案不需要雲端同步,Realm 的核心賣點(Device Sync)用不上。 + +### 1.1 五平台支援(含原生函式庫打包) + +- **drift + sqlite3**:官方文件確認 `sqlite3` 套件 v3.x 起改用 Dart build hooks + (native assets/`code_assets` 機制)**自動打包**原生 SQLite,Android/iOS/ + macOS/Windows/Linux 五平台都不再需要手動加 `sqlite3_flutter_libs` 或 + `sqlcipher_flutter_libs` 這類外掛套件(兩者官方文件都寫「no longer + necessary... can be removed」)。若要換成加密版 SQLite(SQLite3MultipleCiphers), + 在 `pubspec.yaml` 用 `hooks: user_defines: sqlite3: source: sqlite3mc` 即可換源, + Windows/Linux 端的 native_assets 目錄會被 Flutter 標準建置流程自動複製進 bundle。 + 來源:context7 `drift` 官方文件(native assets/build hooks 章節); + https://pub.dev/packages/sqlite3_flutter_libs;https://pub.dev/packages/sqlcipher_flutter_libs。 + Namida 本身也是用同一個 `hooks: user_defines: sqlite3: source: sqlite3mc` 機制換成加密 SQLite。 +- **isar_community**:五平台支援沿用上游 isar 的成熟度,FMP 現行版本已在 + Android+Windows 生產驗證(`docs/adr/0007-isar-stays-on-v3.md`);fork 的 Android + library 已確認 16 KB page-size 對齊(同 ADR)。Linux/macOS/iOS 未在 FMP 內驗證過, + 上游 isar 過去有五平台支援紀錄,但 fork 是否對每個平台都持續打包需要在 + child task 實測,本研究不下定論。 +- **ObjectBox**:官方套件 `objectbox_flutter_libs` 涵蓋 Android/iOS/macOS/ + Linux/Windows 五平台原生函式庫打包;非 Flutter 的 Dart-only 場景需另外跑 + `install.sh` 或走 fallback 搜尋路徑(Windows 找當前目錄與 + `%WINDIR%\system32`;macOS 找 `/usr/local/lib`;Linux 找 `/lib`、`/usr/lib`)。 + 來源:context7 `/objectbox/objectbox-dart` 官方文件/README。FMP 是 Flutter app, + 用 `objectbox_flutter_libs` 這條路徑,不受此限制影響。 +- **Hive CE**:純 Dart 實作,無原生函式庫依賴,理論上五平台都能跑;沒有找到 + Hive CE 在 Linux/macOS/iOS 的官方相容性聲明之外的額外限制,視為「查得到但 + 非重點候選」(純 key-value/物件儲存,見下方「不建議理由」)。 +- **Realm**:官方 SDK 過去主打 Android/iOS/macOS,Windows/Linux 桌面支援 + 歷史上一直較弱,且維護已停滯(見上表),不再深入查證平台細節。 + +### 1.2 Schema migration 機制與可測試性 + +這是候選之間差距最大的一項。 + +- **drift**:一套完整、官方維護的遷移+測試工具鏈: + - `dart run drift_dev make-migrations` —— 版本號一變動就自動產生 step + migration 骨架與對應的測試腳手架; + - `dart run drift_dev schema dump` —— 把每個 schema 版本匯出成 JSON,進版控; + - `dart run drift_dev schema generate` —— 依匯出的 schema JSON 產生遷移測試碼; + - `SchemaVerifier`(`schemaAt`/`migrateAndValidate`/`startAt`/ + `InitializedSchema`)—— 讓測試能「在舊版本 schema 塞資料 → 跑遷移 → 驗證新 + 版本資料正確」,是目前查到唯一有官方一條龍遷移測試工具的候選。 + 來源:context7 `drift` 官方文件(schema migration 章節)。 +- **isar_community**:沒有官方遷移測試工具;FMP 現行做法是手動維護 + `kFmpSchemaVersion` 並用 `test/manual/real_db_probe.dart` 對真實資料庫副本 + 跑前後驗證(`docs/adr/0007-isar-stays-on-v3.md`)——等於自己補上 drift 內建的 + 那一層。 +- **ObjectBox**:官方文件宣稱「automatic」schema migration——「simply change + your model, we handle the rest」,但查到的說明僅止於這句行銷語,沒有找到 + 對「刪欄位」「改型別」「破壞性變更」這類場景的具體行為文件或遷移測試 API。 + 這點標記「查不到」,若要採用 ObjectBox 需要在設計前再花時間查證破壞性 + schema 變更的實際行為,不能只憑這句話假設它總是安全。 +- **Hive CE**:沒有 schema 遷移機制,型別演進靠手寫 `TypeAdapter`(見 Finamp + 案例,第 2 節)——本質上是「舊 binary 版面手動 parse 進新 class」,沒有版本 + 化 schema 或自動化測試工具。 + +**結論**:schema migration 可測試性上 drift 明顯領先;這對「新資料層要長期維護、 +且要能安全演進」的目標權重很高。 + +### 1.3 Reactive queries(watch/stream) + +- **drift**:原生支援 `.watch()`/`.watchSingle()`/`.watchSingleOrNull()`, + 回傳 `Stream`,直接對接 Riverpod `StreamProvider`(官方文件範例即用這個組合)。 + 來源:context7 `drift` 官方文件。 +- **isar_community**:沿用上游 isar 的 `watchObjectLazy`/`watchLazy`/ + `.watch()` API(FMP 現行程式碼已在用,例如 Finamp 的 + `FinampUser.watchObjectLazy(0)` 模式,見第 3 節引用)。 +- **ObjectBox**:`Query.watch()` 走 `entityChanges` broadcast stream,官方測試 + 套件裡的 `isolates_test.dart` 證實可跨 isolate 生效。來源:context7 + `/objectbox/objectbox-dart` 文件與測試範例。 +- **Hive CE**:`Box.watch()` 存在,但事件粒度是「整個 box 的 key 變化」,不像 + drift/isar/ObjectBox 能對查詢結果做細粒度 reactive。 + +### 1.4 Isolate 使用 + +- **drift**:`NativeDatabase.createInBackground(file)` 一行設定即可把整個資料庫 + 操作丟到背景 isolate,不需要改查詢程式碼。來源:context7 `drift` 官方文件。 +- **isar_community**:上游 isar 本身設計成可跨 isolate 共用同一個 `Isar` + instance(`Isar.open` 於多個 isolate 可重複取得同一個開啟的實例),FMP 現行 + 已依賴此特性。 +- **ObjectBox**:`Store` 可跨 isolate 共用,`Query.watch()` 已驗證跨 isolate + 能收到事件(見上)。 +- **Hive CE**:官方文件與社群討論显示 Hive 系列历史上对多 isolate 并发写入较 + 敏感(同一 box 不建議多個 isolate 同時寫),這點沒有找到 hive_ce 有結構性改善 + 的正式聲明,標記「推測」——沿用原始 Hive 的限制,需要在設計時避開多 isolate + 寫入同一個 box。 + +### 1.5 Codegen/build_runner 依賴 + +- **drift**:需要 `drift_dev` + `build_runner`(`.drift` 檔或 Dart table 定義 + → 產生 `.g.dart`)。FMP 現行 isar 已經依賴 `build_runner`(Isar generator), + 對現有工作流沒有新增類別的負擔,只是換一套 generator。 +- **isar_community**:需要 `isar_generator` + `build_runner`(FMP 現行做法)。 +- **ObjectBox**:需要 `objectbox_generator` + `build_runner`。 +- **Hive CE**:需要 `hive_ce_generator` + `build_runner`(`TypeAdapter` 產生); + 也可以完全手寫 `TypeAdapter` 不跑 codegen,彈性略高但要自己維護 field 對應。 + +四個方案都要 `build_runner`,這項對比較結論影響不大——FMP 現有工具鏈已經有 +這個依賴,換誰都不會多引入新的建置步驟類別。 + +### 1.6 Riverpod 相容性 + +- **drift**:context7 官方文件直接給了 `StreamProvider` 接 `.watch()` 的範例, + 是四個候選裡唯一在官方文件層級示範 Riverpod 整合的。 +- 其餘三者(isar_community/ObjectBox/Hive CE)都是「stream/watch API 存在, + 自己包一層 Riverpod provider」,FMP 現行 isar 用法就是這個模式,技術上都可行, + 沒有相容性障礙,只是沒有官方文件示範。 + +### 1.7 全文檢索(FTS) + +- **drift**:支援 FTS5,build option 開 `sqlite_module: [fts5]`, + 搭配 `package:drift/extensions/fts5.dart` 的 `bm25`/`highlight`/`snippet` + 等輔助函式可直接寫進查詢;FTS5 虛擬資料表**只能在 `.drift` 檔宣告,不能用純 + Dart class 定義**。來源:context7 `drift` 官方文件。 +- **isar_community**:上游 isar 有自己的 index/filter 機制,但不是標準 + SQL FTS5,全文檢索能力有限(前綴比對、simple word index),FMP 現行程式碼 + 沒有依賴 isar 的全文檢索能力。 +- **ObjectBox**:多次查詢(context7 `/objectbox/objectbox-dart` 官方文件與 + README)都沒有出現 FTS/全文檢索相關 API 或說明,官方文件重點在向量搜尋 + (on-device ANN vector search)而非文字全文檢索。**標記「查不到」**——沒有 + 查到 ObjectBox 有 FTS 功能的證據,也沒有查到「明確不支援」的官方聲明,需視為 + 高機率不支援或功能非常有限。 +- **Hive CE**:沒有內建全文檢索,需要自己實作(例如把 tokenize 後的關鍵字另存 + 一份索引 box)。 + +FMP 若未來要做「搜尋歌單/曲目名稱」這類本地全文檢索需求,drift 是唯一有現成 +標準 SQL FTS5 支援的候選。 + +### 1.8 效能數據(萬列等級) + +- ObjectBox 官方發布的 Flutter 資料庫效能測試(廠商自測,需帶保留態度): + 在 Kirin 980 真機、每批 10,000 筆物件、50 次取平均,比較 sqflite/Hive/ + ObjectBox/Drift(Moor)/Floor;ObjectBox 在 create/update 上比 sqflite + 快至多 70 倍;Hive 讀取快是因為記憶體快取造成的比較基準不公平(該報告自己 + 也這樣註記)。來源:https://objectbox.io/flutter-databases-sqflite-hive-objectbox-and-moor + (此為 ObjectBox 官方部落格,屬利害關係人自測數據,非獨立第三方基準, + 結論要打折扣看待)。 +- **沒有查到** drift/sqlite3 或 isar_community 針對「數萬列」等級、非廠商 + 自測的獨立效能比較數據——這點標記「查不到」。FMP 現行 isar 資料庫本身 + 規模(依 `docs/audit/data.md` 所述約 1,534 列的真實資料庫副本)遠低於 + 「數萬列」門檻,效能差異在 FMP 實際資料量下大機率都不是決策關鍵因素, + 比 schema migration 可測試性、五平台原生打包簡易度優先度低。 + +### 1.9 一般工具可檢視資料檔案 + +- **drift/sqlite3**:資料檔案就是標準 SQLite 檔案,任何 SQLite 瀏覽工具 + (DB Browser for SQLite、DBeaver 等)都能直接開啟檢視,不需要專案自己寫 + 檢視器。這對「除錯時直接看資料庫內容」的日常開發體驗是明顯優勢。 +- **isar_community**:專屬二進位格式,FMP 現行靠自己寫的 + `lib/data/database/database_catalog.dart`(`ADR 0002` 允許例外的檢視器) + 才能查看,也可以用官方 Isar Inspector(若 fork 相容)。 +- **ObjectBox**:專屬二進位格式(FlatBuffers-based),沒有查到通用檢視工具, + 需要透過 ObjectBox 官方的 Admin 介面或自己寫程式讀取——標記「查不到」通用 + 工具,需要專案自建或依賴 ObjectBox 自己的管理介面。 +- **Hive CE**:專屬二進位格式,沒有查到成熟的通用圖形化檢視工具。 + +drift/sqlite3 在這項是唯一「不需要專案自己投資檢視工具、業界通用工具即可用」 +的候選,對照 FMP 現在得自己維護 `database_catalog.dart` 的現況,是一個實質的 +維運成本下降。 + +### 1.10 小結:候選比較結論 + +| 維度 | drift(sqlite3) | isar_community | ObjectBox | Hive CE | Realm | +|---|---|---|---|---|---| +| 五平台原生打包 | 自動(native assets) | 已驗證(Android+Win) | 有專用套件 | 純 Dart 無需打包 | 弱/停滯 | +| Schema 遷移工具 | 官方一條龍+測試 API | 手動+自建驗證腳本 | 宣稱自動,細節不明 | 手寫 TypeAdapter | 查不到 | +| Reactive watch | 有(Stream) | 有 | 有(含跨 isolate) | 有(box 粒度) | 查不到 | +| Isolate | 一行設定 | 已驗證 | 已驗證 | 推測有限制 | 查不到 | +| FTS | FTS5 完整支援 | 有限 | 查不到/推測無 | 無,需自建 | 查不到 | +| 通用工具可查看 | 是(任何 SQLite 工具) | 否(自建檢視器) | 否 | 否 | 否 | +| 維護狀態 | 活躍 | 活躍(社群 fork) | 中等活躍 | 活躍 | 停滯逾一年 | + +**首選:drift(建立在 sqlite3 之上)。** 理由:五平台原生打包已經隨 +`sqlite3` v3.x 的 native-asset 機制自動化、不必再手動管理平台外掛套件; +schema 遷移有官方測試工具鏈,直接補上 FMP 現行 isar 方案「自己手動維護版本號 ++ 自建驗證腳本」的缺口;FTS5 是唯一標準化的全文檢索支援;資料檔案可以用任何 +通用 SQLite 工具查看,比繼續維護專屬的 `database_catalog.dart` 更省力; +Riverpod 整合有官方範例。次要候選是 ObjectBox(若效能是關鍵瓶頸可再評估), +但其 schema 遷移細節與 FTS 支援目前查不到足夠證據,不適合在證據不足的情況下 +選為首選。Realm 因維護停滯不建議列入候選。Hive CE 定位是輕量 KV/物件儲存, +不適合作為 FMP 這種有查詢/關聯需求的主資料層(更適合settings這類簡單資料, +見第 3 節)。 + +## 2. 同類播放器用什麼 + +四款同類 Flutter 音樂播放器的持久化選型(皆以 `pubspec.yaml` 直接查證, +GitHub API 讀取,2026-09-27): + +| 專案 | 主資料庫 | 設定存放 | 來源 | +|---|---|---|---| +| **Spotube** | `drift` + `sqlite3` + `sqlite3_flutter_libs` | `shared_preferences`(與 DB 分開) | https://github.com/KRTirtho/spotube/blob/master/pubspec.yaml | +| **Finamp** | `isar`(fork:`Komodo5197/isar-community.git`) + `hive_ce`(雙資料庫並存,長期) | `shared_preferences`(另外還有 `hive_ce` 存部分設定,見下方細節) | https://github.com/finamp-app/finamp/blob/master/pubspec.yaml | +| **Namida** | 自訂 SQLite(`sqlite3` + `sqlite3mc` 加密源) | 純 JSON 檔案,手寫 `SettingsFileWriter`,不經任何 DB/`shared_preferences` | https://github.com/namidaco/namida/blob/master/pubspec.yaml、`lib/base/settings_file_writer.dart` | +| **Harmony Music** | `hive`(原版,非 CE) | 同一套 `hive` box,與其他資料**混放**、無獨立機制 | https://github.com/anandnet/Harmony-Music/blob/master/pubspec.yaml | + +四個樣本呈現四種不同組合,沒有一致的業界標準,但有兩個明顯的多數傾向: +(a)drift/SQLite 是新專案(Spotube)的選擇;(b)**設定與主資料庫分開存放** +是三分之三有明確劃分的專案(Spotube、Finamp、Namida)的共同做法,只有 +Harmony Music 把設定混進主資料庫。細節見第 3 節。 + +### 2.1 Finamp 的 Isar + Hive CE 共存細節(同時是候選比較與遷移可行性的關鍵佐證,詳細分析見 `migration-feasibility.md` 第 1 節) + +Finamp 目前生產環境**長期同時使用** Isar 與 Hive CE,不是「遷移後即將移除」的 +過渡狀態: + +- Isar 存放:`DownloadItem`、`IsarTaskDataSchema`(第三方套件 + `background_downloader` 的 `IsarPersistentStorage` 內部要求,非 Finamp 自己 + 的選擇)、`FinampUser`(登入使用者,用 `.watchObjectLazy(0)` 做 reactive + provider)、`DownloadedLyrics`。 +- Hive CE 存放:一般設定(`FinampSettingsHelper`)、播放佇列 + (`QueueService`)等。 +- `FinampUserHelper.migrateFromHive()` 是一次性遷移,把 `FinampUser` 資料 + 從舊的 Hive box 結構搬進 Isar(方向是 Hive→Isar,不是反過來),由 + `hasCompletedIsarUserMigration` 設定旗標控制只跑一次。 + +來源:https://github.com/finamp-app/finamp/blob/master/lib/main.dart、 +https://github.com/finamp-app/finamp/blob/master/lib/services/finamp_user_helper.dart + +## 3. 設定存放:與資料庫合放 vs. 分開 + +FMP 現行做法(依 `docs/audit/data.md`)是設定也在 Isar 的一個 collection 裡; +以下是四個同類專案的實際做法,供設計新架構時參考: + +- **Namida —— 純 JSON 檔案,完全不進 DB/`shared_preferences`**: + `SettingsFileWriter` mixin,每個設定群組(`SettingsController` 的多個 part + file,如 `settings.equalizer.dart`、`settings.player.dart`)各自序列化成 + JSON 直接寫入磁碟檔案,寫入用 2 秒 debounce 合併,避免頻繁磁碟 I/O: + ```dart + mixin SettingsFileWriter { + String get filePath; + Object get jsonToWrite; + Duration get delay => const Duration(seconds: 2); + Future writeToStorage() async { + if (_canWriteSettings) { + _canWriteSettings = false; + _writeToStorageRaw(); + } else { + _writeTimer ??= Timer(delay, () { + _writeToStorageRaw(); + _canWriteSettings = true; + _writeTimer = null; + }); + } + } + Future _writeToStorageRaw() async { + await File(filePath).writeAsJson(jsonToWrite); + } + } + ``` + 來源:https://github.com/namidaco/namida/blob/master/lib/base/settings_file_writer.dart + 優點:完全不依賴資料庫版本/schema,設定檔可以直接用文字編輯器查看或手動 + 修復;缺點:要自己處理併發寫入與 debounce,沒有交易保證。 + +- **Spotube —— `shared_preferences`,與 `drift` 資料庫完全分開**: + 設定是設定、播放資料是資料,兩條路徑互不干擾,遷移或重建資料庫不影響設定。 + 來源:`pubspec.yaml` 依賴清單(見上表)。 + +- **Finamp —— 以 `shared_preferences`/Hive CE 為主,與 Isar 分開**: + 一般設定不進 Isar;Isar 只保留「非設定」的功能性資料(下載項目、使用者、 + 歌詞快取)。 + +- **Harmony Music —— 混放**:`settings_screen_controller.dart` 與 + `theme_controller.dart` 都直接呼叫 `Hive.box`,與其他業務資料共用同一套 + 儲存機制,沒有獨立分層。來源:GitHub code search + `repo:anandnet/Harmony-Music Hive.box` 命中上述檔案;同一次搜尋 + `SharedPreferences` 沒有任何命中,確認 Harmony Music 不用 + `shared_preferences`。 + +**傾向結論**:四分之三的專案把設定與主資料庫分開(Namida 用純檔案、 +Spotube/Finamp 用 `shared_preferences`),只有 Harmony Music 混放。分開存放 +的共同理由(可從程式碼行為推斷,非官方明文說明,標記「推測」):設定的讀寫 +頻率與資料型態(少量、扁平、常整包序列化)跟主資料庫的查詢型負載模式不同, +分開後設定變更不需要打開資料庫交易,資料庫 schema 遷移也不會牽動設定格式。 +FMP 若採用 drift 作為主資料層,比照 Spotube/Finamp 的做法,用 +`shared_preferences`(或功能對等的簡單 KV 方案)單獨存放設定,與 drift 資料庫 +分離,是目前證據支持度最高、也最容易實作的路線。 diff --git a/.trellis/tasks/09-27-design-data/task.json b/.trellis/tasks/09-27-design-data/task.json new file mode 100644 index 000000000..6bf11aff6 --- /dev/null +++ b/.trellis/tasks/09-27-design-data/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-data", + "name": "design-data", + "title": "Design: data layer and compatibility", + "description": "Phase-2 item 6: persistence choice for all five platforms, schema principles, and automatic migration of the legacy database, credentials, downloads and backups", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 4aacca4a5cb484788ec0b2367d0eb9bb32480032 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 08:31:43 +0800 Subject: [PATCH 017/133] docs(adr): 0010 drift data layer and legacy import --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 8 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .trellis/tasks/09-27-design-data/implement.md | 10 +-- .trellis/tasks/09-27-design-data/prd.md | 6 +- .trellis/tasks/09-27-design-data/task.json | 4 +- docs/adr/0002-repository-boundary.md | 2 + docs/adr/0007-isar-stays-on-v3.md | 2 + ...0010-drift-data-layer-and-legacy-import.md | 80 +++++++++++++++++++ docs/adr/template.md | 1 + 9 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 docs/adr/0010-drift-data-layer-and-legacy-import.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 526304c87..f1ebdd0a4 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -113,7 +113,7 @@ flowchart LR | 1 | 9 文檔結構/ADR 去留(✅ 完成,見 `archive/2026-09/09-27-design-docs`) | 之後每一項都會產出 ADR;先定 ADR 放哪、舊 ADR 與 CONTEXT.md 怎麼處理。輕量,一次就能定。 | | 2 | 7 重寫策略(高層)(✅ 完成,ADR 0008;里程碑留到第 20 步定稿) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | | 3 | 10 平台層(✅ 完成,ADR 0009) | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | -| 4 | 6 資料層與相容 | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | +| 4 | 6 資料層與相容(✅ 完成,ADR 0010) | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | | 5 | 18 設定與日誌 | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | | 6 | 12 網路與帳號 | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | | 7 | 2 錯誤模型 | 音源插件介面的回傳與例外型別要先定。 | @@ -215,3 +215,9 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - D3:Mix 與普通佇列統一處理,不可播放就自動跳過。 - iOS:GitHub Release 發佈 IPA,供側載。 - static-rule:重寫後改用 Dart analyzer 的 lint 規則。 + +## 7. 第一個里程碑的必要驗證(各項設計累積) + +- ADR 0010:`isar_community`+`sqlite3` 原生庫在 Android、Windows 共存;`sqlite3` 的 Android 16KB page size 對齊。 +- ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 +- ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index f57c76c76..70318e335 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -22,7 +22,8 @@ "09-26-audit", "09-27-design-docs", "09-27-design-rewrite-strategy", - "09-27-design-platform" + "09-27-design-platform", + "09-27-design-data" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-data/implement.md b/.trellis/tasks/09-27-design-data/implement.md index e3780e935..f8cc2975b 100644 --- a/.trellis/tasks/09-27-design-data/implement.md +++ b/.trellis/tasks/09-27-design-data/implement.md @@ -2,10 +2,10 @@ 本任務只產出設計與 ADR;資料層與 legacy import 在里程碑中實作。 -- [ ] 寫 `docs/adr/0010-drift-data-layer-and-legacy-import.md`:design.md §1–§6,被否決的選項(留在 isar_community、ObjectBox、Hive CE、Realm、設定用 shared_preferences、遷移後自動刪舊檔、遷移成功一版後就移除 legacy 模組),「如何確認」(schema 快照+migration 測試、「不改使用者值」測試、真實資料副本遷移、import lint)。 -- [ ] 在 ADR 0002、0007 開頭加一行:「只適用根目錄舊專案;新專案見 ADR 0010;切換時隨舊專案刪除」。 -- [ ] 第 9 項規則的細化寫進 `docs/adr/template.md` 的註解(被取代但仍描述凍結舊專案的 ADR,切換時刪除)。 -- [ ] `phase2-plan.md` 標記第 6 項完成,並在「第一個里程碑的必要驗證」記下 design.md §5 三項。 -- [ ] 歸檔本任務。 +- [x] 寫 `docs/adr/0010-drift-data-layer-and-legacy-import.md`:design.md §1–§6,被否決的選項(留在 isar_community、ObjectBox、Hive CE、Realm、設定用 shared_preferences、遷移後自動刪舊檔、遷移成功一版後就移除 legacy 模組),「如何確認」(schema 快照+migration 測試、「不改使用者值」測試、真實資料副本遷移、import lint)。 +- [x] 在 ADR 0002、0007 開頭加一行:「只適用根目錄舊專案;新專案見 ADR 0010;切換時隨舊專案刪除」。 +- [x] 第 9 項規則的細化寫進 `docs/adr/template.md` 的註解(被取代但仍描述凍結舊專案的 ADR,切換時刪除)。 +- [x] `phase2-plan.md` 標記第 6 項完成,並在「第一個里程碑的必要驗證」記下 design.md §5 三項。 +- [x] 歸檔本任務。 驗證:Mermaid 以 mermaid-cli 渲染;`git grep -n "ADR 0002\|ADR 0007\|0002-repository\|0007-isar"` 的命中都仍指向存在的檔案。 diff --git a/.trellis/tasks/09-27-design-data/prd.md b/.trellis/tasks/09-27-design-data/prd.md index 71f738abe..c93c8638a 100644 --- a/.trellis/tasks/09-27-design-data/prd.md +++ b/.trellis/tasks/09-27-design-data/prd.md @@ -49,6 +49,6 @@ A4(資料位置,按推薦)、B6(串流 URL 不存資料庫)、M3/M4 ## 驗收標準 -- [ ] design.md 涵蓋選型、schema 原則、schema 演進、legacy import 流程與失敗處理、實測風險、舊 ADR 處理。 -- [ ] `docs/adr/0010-*.md` 依範本寫成;ADR 0002、0007 加註只適用舊專案。 -- [ ] `phase2-plan.md` 標記第 6 項完成並記下第一個里程碑的必要驗證。 +- [x] design.md 涵蓋選型、schema 原則、schema 演進、legacy import 流程與失敗處理、實測風險、舊 ADR 處理。 +- [x] `docs/adr/0010-*.md` 依範本寫成;ADR 0002、0007 加註只適用舊專案。 +- [x] `phase2-plan.md` 標記第 6 項完成並記下第一個里程碑的必要驗證。 diff --git a/.trellis/tasks/09-27-design-data/task.json b/.trellis/tasks/09-27-design-data/task.json index 6bf11aff6..c616412a8 100644 --- a/.trellis/tasks/09-27-design-data/task.json +++ b/.trellis/tasks/09-27-design-data/task.json @@ -3,7 +3,7 @@ "name": "design-data", "title": "Design: data layer and compatibility", "description": "Phase-2 item 6: persistence choice for all five platforms, schema principles, and automatic migration of the legacy database, credentials, downloads and backups", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0002-repository-boundary.md b/docs/adr/0002-repository-boundary.md index 5536b52fc..a8bd512a1 100644 --- a/docs/adr/0002-repository-boundary.md +++ b/docs/adr/0002-repository-boundary.md @@ -1,5 +1,7 @@ # 0002 — Isar 只出現在 repository 層 +> 只適用根目錄舊專案;新專案(`app/`)見 [ADR 0010](0010-drift-data-layer-and-legacy-import.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-04 - 影響範圍:`lib/data/repositories/`、所有曾經自己持有 `Isar` 的 service diff --git a/docs/adr/0007-isar-stays-on-v3.md b/docs/adr/0007-isar-stays-on-v3.md index c22f6e8a7..95f5d734e 100644 --- a/docs/adr/0007-isar-stays-on-v3.md +++ b/docs/adr/0007-isar-stays-on-v3.md @@ -1,5 +1,7 @@ # 0007 — Isar 停在 v3,改用 isar_community fork +> 只適用根目錄舊專案;新專案(`app/`)見 [ADR 0010](0010-drift-data-layer-and-legacy-import.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-25(補記;決策本身在 `35007eb0`(2026-07-05)與 `3b1c7244`(2026-09-02)) - 影響範圍:`pubspec.yaml` 的 Isar 依賴、`lib/data/models/` 的所有 collection、release 前的 native libs 檢查 diff --git a/docs/adr/0010-drift-data-layer-and-legacy-import.md b/docs/adr/0010-drift-data-layer-and-legacy-import.md new file mode 100644 index 000000000..d7c35928d --- /dev/null +++ b/docs/adr/0010-drift-data-layer-and-legacy-import.md @@ -0,0 +1,80 @@ +# 0010 — 新專案用 drift(SQLite),首次啟動自動匯入舊資料 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`app/` 的資料層與設定存放、`app/lib/legacy_import/`、備份格式、舊版使用者的升級路徑 + +## 背景 + +舊專案的資料全在 `isar_community` 3.3.2(Isar v3 的社群 fork):11 個 collection、沒有任何 IsarLink, +歌單與曲目的關係靠手動維護的 id 與字串鍵;沒標 `@ignore` 的 getter 也被持久化;migration 用自建的 +`kFmpSchemaVersion`,其中 v3→v4 無條件改寫了使用者的設定(`docs/audit/data.md` §1–§2、`docs/audit/accounts-network.md` §7)。 +手動維護關係的結構造成過資料遺失:啟動時的下載同步重建曲目的歌單關聯,對不上就丟,接著孤兒清理把曲目刪掉 +(`docs/audit/downloads.md` §4.4)。 + +擁有者要求舊資料庫、登入憑證、已下載檔、舊備份檔在新 App 全部自動遷移(`docs/audit/questions.md` A3), +而新 App 沿用舊 App 身分(ADR 0008)。本 ADR 對新專案取代 ADR 0002、0007;那兩份仍描述根目錄舊專案, +在切換 PR 隨舊專案刪除。 + +## 考慮過的選項 + +### 留在 isar_community(v3) + +能原地打開舊檔,遷移最簡單。但長期依賴一個自述「主要做 v3 bug 修正」的 fork(上游 Isar 2023 年起停更); +手動維護關係的結構會帶進新專案;Linux、macOS、iOS 從未驗證。 + +### drift(SQLite)(採用) + +見下方決定。 + +### 其他 + +- **ObjectBox**:五平台,但 schema 遷移細節與全文搜尋的證據不足。 +- **Hive CE**:輕量鍵值儲存,不適合當關聯資料的主資料層。 +- **Realm**:一年以上未發版,且核心賣點(雲端同步)用不上。 +- **設定用 `shared_preferences`**(Spotube、Finamp 的做法):檔案位置由平台決定,無法跟著 Portable 版放在程式旁的 `data/`。 +- **遷移後自動刪除舊檔**:失敗或有漏時無法回頭。 +- **遷移成功一版後就移除 legacy 模組**:舊版允許跳版升級,跳過那一版的使用者會拿不到舊資料。 + +## 決定 + +1. **選型**:`drift`+`sqlite3`(native assets 自動打包五平台原生庫)。資料庫檔在 ADR 0009 定義的資料目錄。 + 只有資料層(repository)能存取資料庫。 +2. **Schema 原則**: + - 關係交給資料庫:外鍵、`ON DELETE` 規則、唯一鍵;歌單與曲目用關聯表(含排序欄位)。 + - 曲目以 `TrackKey` 字串(含 cid,ADR 0005)為唯一鍵。 + - 只存事實:不持久化推導值、格式化字串、與時間有關的推導狀態;串流 URL 不進資料庫。 + - 下載紀錄獨立成表。 + - 設定存在同一個資料庫的設定表。 + - 時間存 UTC epoch 毫秒;音源 id 用字串。 +3. **Schema 演進**:每版以 `drift_dev schema dump` 存快照;每個 migration 有升級測試;migration 不得改寫使用者設定過的值, + 只能影響沒設定過的列;migration 失敗整個回滾,App 顯示錯誤頁而不在半升級的資料庫上啟動。 +4. **舊資料匯入(legacy import)**: + - 位於 `app/lib/legacy_import/`,是唯一依賴 `isar_community` 與 `flutter_secure_storage` 10.x 的地方。 + - 首次啟動偵測到舊資料時:唯讀開啟舊 Isar、用與舊版相同的 secure storage 版本讀憑證、登記舊下載檔(不搬檔), + 轉換後寫入**暫存**資料庫;驗證筆數、抽樣比對、外鍵完整後,才換成正式資料庫並寫入匯入紀錄。 + - 失敗時不留半套資料,顯示錯誤頁:重試、匯出診斷、或先以空白資料啟動(之後可再匯入)。 + - 讀不到的憑證只把該音源標為「需要重新登入」。 + - 舊版被 migration 強制改過的設定無法還原原值,照現值匯入。 + - 舊備份檔可匯入,與資料庫匯入共用同一套轉換。 + - 永遠不自動刪舊檔;匯入成功後,設定頁提供「刪除舊版資料」。 + - 模組與其舊依賴保留到另立 ADR 移除;移除前需公告最低升級路徑。 + +採用的慣例:drift 官方的 schema 快照與 migration 測試工具;Spotube 的 drift+sqlite3 組合; +一次性遷移「先寫暫存、驗證後才換上」的保守做法。 + +## 後果 + +- 好的:關係完整性由資料庫保證;schema 演進可測;資料檔可用通用 SQLite 工具檢視;舊版使用者升級不需手動操作。 +- 壞的:新 App 帶著 `isar_community` 與舊版 secure storage 兩個舊依賴,直到另立 ADR 移除;要重新設計 schema 與轉換規則。 +- 之後要注意: + - `isar_community` 與 `sqlite3` 兩套原生庫共存沒有直接先例,第一個里程碑在 Android、Windows 實測;若衝突,legacy import 改成由新 App 啟動的獨立一次性小程式。 + - `sqlite3` 原生庫的 Android 16KB page size 對齊,第一個里程碑用官方對齊檢查確認。 + - 新憑證存放處在網路與帳號的 ADR 決定;`flutter_secure_storage` 升到 11.x 的條件同樣在那裡處理。 + +## 如何確認 + +- Schema 快照與每個 migration 的升級測試在 CI 執行。 +- 「migration 不改使用者設定過的值」有專門測試:先寫入使用者值,跑 migration,斷言值不變。 +- 資料庫只由資料層存取、`legacy_import/` 不被其他模組 import:import lint(測試策略 ADR 落實)。 +- 切換前,在擁有者真實資料的副本上完整跑一次匯入,並把筆數比對結果附在切換 PR 的 review 指南。 diff --git a/docs/adr/template.md b/docs/adr/template.md index 09a96e40e..b8dadc280 100644 --- a/docs/adr/template.md +++ b/docs/adr/template.md @@ -4,6 +4,7 @@ 複製這個檔案成 `NNNN-英文小寫連字號標題.md`,編號接在現有最大號之後、不重用。 格式依 MADR 精簡,多一節「如何確認」。 推翻舊 ADR 時:同一個 commit 刪除舊檔、改掉所有引用、用 git grep 確認沒有殘留,並在「背景」寫明取代了哪一份。 +例外:被取代的舊 ADR 若仍描述凍結中的根目錄舊專案,改在舊檔開頭加註「只適用舊專案」,於切換 PR 隨舊專案刪除(ADR 0008)。 --> - 狀態:提議中/已採納 From de0dc806949348a41e90532071b2d5499611533f Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 08:31:45 +0800 Subject: [PATCH 018/133] chore(task): archive design-data --- .../tasks/{ => archive/2026-09}/09-27-design-data/check.jsonl | 0 .../tasks/{ => archive/2026-09}/09-27-design-data/design.md | 0 .../{ => archive/2026-09}/09-27-design-data/implement.jsonl | 0 .../{ => archive/2026-09}/09-27-design-data/implement.md | 0 .trellis/tasks/{ => archive/2026-09}/09-27-design-data/prd.md | 0 .../09-27-design-data/research/migration-feasibility.md | 0 .../09-27-design-data/research/persistence-options.md | 0 .../tasks/{ => archive/2026-09}/09-27-design-data/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/research/migration-feasibility.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/research/persistence-options.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-data/task.json (92%) diff --git a/.trellis/tasks/09-27-design-data/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-data/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-data/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-data/check.jsonl diff --git a/.trellis/tasks/09-27-design-data/design.md b/.trellis/tasks/archive/2026-09/09-27-design-data/design.md similarity index 100% rename from .trellis/tasks/09-27-design-data/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-data/design.md diff --git a/.trellis/tasks/09-27-design-data/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-data/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-data/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-data/implement.jsonl diff --git a/.trellis/tasks/09-27-design-data/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-data/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-data/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-data/implement.md diff --git a/.trellis/tasks/09-27-design-data/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-data/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-data/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-data/prd.md diff --git a/.trellis/tasks/09-27-design-data/research/migration-feasibility.md b/.trellis/tasks/archive/2026-09/09-27-design-data/research/migration-feasibility.md similarity index 100% rename from .trellis/tasks/09-27-design-data/research/migration-feasibility.md rename to .trellis/tasks/archive/2026-09/09-27-design-data/research/migration-feasibility.md diff --git a/.trellis/tasks/09-27-design-data/research/persistence-options.md b/.trellis/tasks/archive/2026-09/09-27-design-data/research/persistence-options.md similarity index 100% rename from .trellis/tasks/09-27-design-data/research/persistence-options.md rename to .trellis/tasks/archive/2026-09/09-27-design-data/research/persistence-options.md diff --git a/.trellis/tasks/09-27-design-data/task.json b/.trellis/tasks/archive/2026-09/09-27-design-data/task.json similarity index 92% rename from .trellis/tasks/09-27-design-data/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-data/task.json index c616412a8..3a8d243a7 100644 --- a/.trellis/tasks/09-27-design-data/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-data/task.json @@ -3,7 +3,7 @@ "name": "design-data", "title": "Design: data layer and compatibility", "description": "Phase-2 item 6: persistence choice for all five platforms, schema principles, and automatic migration of the legacy database, credentials, downloads and backups", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From 3e60fd3079f2e78b602dda8eeb3fac98eeb64c6d Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 09:03:48 +0800 Subject: [PATCH 019/133] chore(task): plan phase-two item 18 (settings and logging) --- .../09-27-design-settings-logging/check.jsonl | 0 .../09-27-design-settings-logging/design.md | 70 ++++++ .../implement.jsonl | 0 .../implement.md | 9 + .../09-27-design-settings-logging/prd.md | 35 +++ .../research/diagnostics-and-settings.md | 138 +++++++++++ .../research/logging-and-redaction.md | 216 ++++++++++++++++++ .../09-27-design-settings-logging/task.json | 26 +++ 8 files changed, 494 insertions(+) create mode 100644 .trellis/tasks/09-27-design-settings-logging/check.jsonl create mode 100644 .trellis/tasks/09-27-design-settings-logging/design.md create mode 100644 .trellis/tasks/09-27-design-settings-logging/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-settings-logging/implement.md create mode 100644 .trellis/tasks/09-27-design-settings-logging/prd.md create mode 100644 .trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md create mode 100644 .trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md create mode 100644 .trellis/tasks/09-27-design-settings-logging/task.json diff --git a/.trellis/tasks/09-27-design-settings-logging/check.jsonl b/.trellis/tasks/09-27-design-settings-logging/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-settings-logging/design.md b/.trellis/tasks/09-27-design-settings-logging/design.md new file mode 100644 index 000000000..e5cdd487c --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/design.md @@ -0,0 +1,70 @@ +# 設計:設定與日誌基礎設施 + +採用的慣例:talker 作記憶體歷史與分派;Finamp `censored_log.dart` 的已知值替換;NewPipe 錯誤報告的診斷包欄位; +Spotube 以 drift 單列多欄存設定、Riverpod `watchSingle()` 接上。 + +## 1. 日誌 + +```mermaid +flowchart LR + subgraph 產生 + A[各模組] -->|Log.info/warn/error| F[Log 門面] + N[dio 攔截器
    請求摘要] --> F + E[統一錯誤模型] --> F + end + F -->|redact| R[遮蔽函式] + R --> T[talker
    記憶體歷史] + T --> FS[檔案輸出
    資料目錄/logs/] + T --> DBG[Debug 頁
    自製 UI] + T --> DIAG[診斷包] + T -.只在 debug build.-> CON[console] +``` + +- **門面**:`app/lib/core/logging/`,提供 `debug/info/warning/error`,參數是訊息、tag(模組或音源 id)、error、stackTrace、結構化欄位。門面先呼叫遮蔽函式,再交給 `talker`。 +- **talker 只當資料核心**:用它的歷史與分派;**不用** `TalkerScreen`(Debug 頁要用 App 的設計系統,第 4 項自做 UI),**不用** `talker_dio_logger`(會繞過遮蔽)。 +- **輸出**: + - 記憶體歷史:最近 1,000 筆。 + - 檔案:ADR 0009 的資料目錄下 `logs/`,單檔 2MB、保留 3 個(沿用舊值),寫入失敗不影響 App。 + - console:只在 debug build;release 版完全不輸出到 logcat/stdout。 +- **層級**:release 預設 `info`;開發者模式可調到 `debug`(第 4 項定是否持久化)。 +- **閘門**:門面以外禁止 `print`、`debugPrint`、`developer.log` 與直接 import talker(lint,第 8 項)。 + +## 2. 遮蔽函式 + +`app/lib/core/redaction/`,一個入口,四種策略依序套用: + +| 策略 | 做什麼 | 名單來源 | +|---|---|---| +| header 名單 | `Cookie`、`Set-Cookie`、`Authorization`、`X-Goog-*` 類等整個值換成 `***` | 舊 `lib/core/logger.dart` 名單+研究檔補充 | +| key 名單 | query 參數、JSON/form body 中的 `SESSDATA`、`bili_jct`、`MUSIC_U`、`refresh_token`、`access_token`、`csrf`、`apiKey`、`password`、`token` 等 | 同上 | +| CDN URL | 已知媒體主機(Bilibili upos、googlevideo、網易 CDN)的 URL 只留主機與路徑,簽名類參數(`upsig`、`deadline`、`sig`、`signature`、`lsig`、`expire` 等)去掉 | 舊 `redactStreamUrl`+研究檔 | +| 已知值替換 | 帳號層把目前每個音源的實際憑證值登記進來;任何輸出中出現這些值就逐字換成 `***<來源>***` | Finamp 做法 | + +- 套用在訊息、error 字串、**stackTrace**、結構化欄位。 +- 名單集中在一個檔案;**每個音源插件可以追加自己的名單**(第 1 項介面的一部分)。 +- 測試:每個音源一組「長得像真的」假憑證與假簽名 URL,斷言經過任何出口(log 檔、歷史、診斷包、網路紀錄)後都不再出現。 + +## 3. 網路紀錄 + +自己的 dio 攔截器,每個請求記一筆摘要:方法、主機、路徑、遮過的 query、狀態碼、耗時、回應大小、音源 id、錯誤類型(對應第 2 項)。 +**不記 request/response body**。它透過門面寫入,所以和一般 log 一起出現在 Debug 頁、一起遮蔽、一起進診斷包。 + +## 4. 錯誤歷史 + +第 2 項的統一錯誤型別在被處理時,一律以 `warning` 或 `error` 經門面寫入,帶結構化欄位(錯誤類型、音源、對應的網路紀錄、使用者看到什麼)。 +Debug 頁從歷史中篩出錯誤即為「可檢索的錯誤歷史」;跨重啟的歷史由 log 檔提供。 + +## 5. 診斷包 + +參考 NewPipe:一組欄位產生一份純文字(方便貼到 issue)加一份 JSON。 +內容:App 版本與建置、平台與系統版本、語系、各音源是否啟用與登入狀態(只有是/否)、非敏感設定摘要、最近的 log 與錯誤歷史(已遮蔽)。 +不含硬體識別資訊、帳號名稱、歌單內容。產生時從已遮蔽的歷史組裝,匯出(另存、複製、分享)只用這份結果。UI 在第 4 項。 + +## 6. 設定 + +- 依功能分組,每組一張**單列表**,每個設定一個有型別的欄位:播放、外觀、音樂庫與同步、下載、歌詞、網路、桌面、開發者。 + 每組一個 Riverpod Notifier,監看自己那一列;寫入只更新改動的欄位。這消除舊版 19 個 Notifier 共寫同一列的問題。 +- **欄位可為空=使用者沒設定過**:讀取時空值套用程式裡的預設。改預設值只需改程式,不必寫 migration,使用者設定過的值不受影響(ADR 0010 的「migration 不改使用者值」由結構保證)。 +- 每個音源的設定(例如「用登入狀態」、音質偏好)另一張表,以音源 id 為主鍵,音源插件不必改 schema 就能有自己的設定列。 +- 分組內有哪些欄位,依 `docs/audit/data.md` §7 的設定總表在里程碑中逐組定案;使用者已勾「刪除」的功能,其設定不搬。 +- 設定包含在備份中;legacy import 把舊設定的現值寫入(ADR 0010)。 diff --git a/.trellis/tasks/09-27-design-settings-logging/implement.jsonl b/.trellis/tasks/09-27-design-settings-logging/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-settings-logging/implement.md b/.trellis/tasks/09-27-design-settings-logging/implement.md new file mode 100644 index 000000000..0407c087e --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/implement.md @@ -0,0 +1,9 @@ +# 執行計畫 + +本任務只產出設計與 ADR;程式在里程碑中實作(日誌門面與遮蔽函式屬於第一個里程碑的基礎)。 + +- [ ] 寫 `docs/adr/0011-settings-and-logging.md`:design.md §1–§6;被否決的選項(`logger`、`logging`、自寫全套、`TalkerScreen`、`talker_dio_logger`、`alice`、記錄 body、單一大設定表、key-value 表、`shared_preferences`);「如何確認」(lint、遮蔽測試、設定預設值測試)。 +- [ ] `phase2-plan.md` 標記第 18 項完成;「第一個里程碑的必要驗證」加上 log 門面與遮蔽函式。 +- [ ] 歸檔本任務。 + +驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-settings-logging/prd.md b/.trellis/tasks/09-27-design-settings-logging/prd.md new file mode 100644 index 000000000..c11e6bc9e --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/prd.md @@ -0,0 +1,35 @@ +# 設計第 18 項:設定與日誌基礎設施 + +## 目標 + +定下新 App 的設定怎麼分組、怎麼存;log 的層級、輸出、輪替與保留;以及所有會展示或匯出內容的出口 +(log 檔、Debug 頁、錯誤 Toast 的詳細、診斷包、網路紀錄)共用的**同一個遮蔽函式**。 + +需求來源:parent `prd.md` 階段二第 3、4、18 項;`questions.md` C2(重寫時修正)、J3(按推薦)、M3/M4;ADR 0009(目錄)、ADR 0010(設定存資料庫、migration 不改使用者值)。 + +## 現況(證據) + +- 自製 `AppLogger`:500 筆記憶體緩衝、落盤 `Documents/FMP/logs/fmp.log` 2MB×3 輪替、`redactSensitive` 只遮 header 與 key 名;release 版仍 `debugPrint` 到 logcat(`docs/audit/devtools.md` §3)。 +- 外洩面:stackTrace 不遮、CDN 簽名 URL 不遮、AI 請求 payload 在 debug 級別整份寫入(`docs/audit/accounts-network.md` §4、`devtools.md` §3.3)。 +- 設定約 45 項,約 19 個 Notifier 各自讀寫同一列 `Settings`(`docs/audit/data.md` §7、`architecture.md` §4)。 + +## 研究結論(`research/logging-and-redaction.md`、`research/diagnostics-and-settings.md`) + +- 日誌:`talker` 5.1.20(2026-07,五平台,160/160)是唯一同時有記憶體歷史、檢視 UI、dio 轉接的候選;`logger` 2.8.0 有輪替但沒有 UI 與 dio 整合。talker 的紀錄物件欄位不可變,**遮蔽必須在呼叫 log API 之前**做(在觀察者裡做不到)。 +- 遮蔽:三種策略互補——key/header 名單、CDN URL 形狀截斷、**已知值替換**(Finamp:把目前登入帳號的實際 token 值在訊息與 stackTrace 中逐字替換);stackTrace 也要遮。網易的簽名在 POST body 不在 URL。 +- 診斷包:NewPipe 的錯誤報告結構最適合參考(同一組欄位產生文字/JSON,刻意不含硬體識別資訊);Finamp 的教訓:在產生內容時遮一次,匯出只用已遮的結果。 +- 網路紀錄:`talker_dio_logger` 會繞過我們的遮蔽層;`alice` 是另一套平行 UI;`pretty_dio_logger` 不留歷史。 +- 設定建模:Spotube 用 drift 單列多欄(每個設定一個有型別的欄位),Riverpod 以 `watchSingle()` 串流接上;沒找到 key-value 表的先例。 + +## 需求 + +- R1 單一 log 入口(薄門面);門面先遮蔽再交給 `talker`;門面之外禁止 `print`、`debugPrint`、`developer.log` 與直接呼叫 talker(lint,第 8 項)。 +- R2 單一遮蔽函式,四種策略:header 名單、key 名單(query 與 body)、CDN URL 簽名參數、已知憑證值替換;套用在訊息、error 字串與 stackTrace。Toast 詳細、Debug 頁、診斷包、網路紀錄、log 檔都只用遮過的內容。 +- R3 網路紀錄用自己的 dio 攔截器,只記摘要(方法、主機、路徑、遮過的 query、狀態、耗時、大小、音源、錯誤類型),不記 body。 +- R4 錯誤歷史:統一錯誤模型(第 2 項)的每個錯誤都以結構化欄位寫入 log,Debug 頁可依類型、音源、時間篩選。 +- R5 設定依功能分組,每組一張單列表、每個設定一個有型別的欄位;欄位可為空=「使用者沒設定過,用程式預設」,讓預設值可以改而不動使用者值;每個音源的設定另一張表以音源 id 為鍵。 +- R6 release 版不輸出到 logcat/stdout。 + +## 待決定(見摘要) + +- release 版是否寫 log 檔,以及寫到哪個層級。 diff --git a/.trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md b/.trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md new file mode 100644 index 000000000..c8143c106 --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md @@ -0,0 +1,138 @@ +# 研究:診斷包內容、設定分組與儲存 + +範圍對應 task brief 項目 3、5。規則:版本 / 平台 / 維護狀態一律附 URL;查不到寫「查不到」;推測寫「推測」。全文繁體中文,程式識別碼保留原文。 + +--- + +## 3. 診斷包(diagnostic bundle)內容調查 + +調查對象:Spotube、Finamp、Jellyfin 系列 client、NewPipe。四者皆為開源 Flutter/Kotlin 媒體類 app,與 FMP 定位相近,適合作為「診斷包該裝什麼」的實例參照。 + +### 3.1 NewPipe(最完整、最適合當結構範本) + +Source: https://raw.githubusercontent.com/TeamNewPipe/NewPipe/dev/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.kt + +NewPipe 的錯誤回報畫面(`ErrorActivity`)用**同一組欄位**同時產出三種格式:畫面上顯示的面板、可分享的 Markdown、以及 JSON——三種格式共用一份資料模型,這件事本身就是一個值得抄的設計(避免「畫面顯示的」和「匯出檔案裡的」欄位兜不起來)。欄位清單: + +- `user_action`:使用者當下在做什麼操作觸發了這個錯誤(例如「正在播放串流」) +- `request`:觸發錯誤的請求描述 +- `content_language` / `content_country`:使用者設定的內容語言/地區 +- `app_language`:app UI 語言 +- `service`:來源服務名稱(對應 FMP 就是 bilibili/youtube/netease) +- `package`:app 的 package name +- `version`:app 版本號 +- `os`:作業系統字串 +- 時間戳:ISO-8601 格式 +- `exceptions`:例外陣列(可能不只一個) +- `user_comment`:使用者在送出回報前可自行填寫的說明文字 + +**明確排除**:裝置型號、硬體資訊——NewPipe 刻意不收集這些。 + +**與 FMP 遮罩需求的關聯**:`request` 欄位若是 FMP 場景,就是「觸發錯誤的那個 HTTP 請求」,必須經過第一份文件(`logging-and-redaction.md`)第 2 節的同一個遮罩函式再放進診斷包——這正是 owner 要求「Toast、Debug 頁、診斷包、logs 走同一個遮罩函式」的具體落地點之一:診斷包的 `request` 欄位如果繞過遮罩直接塞原始 `RequestOptions.toString()`,就是一個獨立於 log 檔案之外的第二個洩漏出口。 + +### 3.2 Finamp(提供遮罩-匯出的具體管線範例) + +Sources: +- https://raw.githubusercontent.com/finamp-app/finamp/legacy/lib/services/finamp_logs_helper.dart +- https://raw.githubusercontent.com/finamp-app/finamp/legacy/lib/services/censored_log.dart + +Finamp 沒有 NewPipe 那種多欄位結構化診斷包,做法更單純:一份「已遮罩的純文字 log」。管線是: + +1. 記憶體中維護 `List logs`,上限 1000 筆,超過就丟掉最舊的(`addLog` 方法內邏輯)。 +2. `getSanitisedLogs()` 逐筆取 `log.censoredMessage`(`censored_log.dart` 定義的 extension,內含本文件姊妹篇第 2.1 節描述的「已知值替換」遮罩),組成一個純文字 `StringBuffer`。**直接讀原始碼確認:這個函式本身不附加任何 metadata header(裝置資訊/版本號/時間戳)——只有逐行遮罩後的訊息**,本輪之前的一份基於間接 WebSearch 推論的筆記主張這裡有 metadata header,經直接讀原始碼後**予以撤回**:以本次直接讀取的原始碼為準,不採用先前間接來源的說法。 +3. `shareLogs()` 把上述字串寫進暫存檔 `finamp-logs.txt`,用 `Share.shareXFiles` 分享出去,分享完刪除暫存檔。 +4. `copyLogs()` 提供另一條路徑:直接複製到剪貼簿(`FlutterClipboard.copy`),不經過檔案。 + +這個管線印證的設計原則:**遮罩必須在「組字串」那一步完成,而不是在「分享/匯出」那一步**——`shareLogs()`/`copyLogs()` 兩個不同出口都呼叫同一個已經遮罩過的 `getSanitisedLogs()`,而不是各自兜一份字串再各自遮罩,避免兩個出口的遮罩邏輯漏同步。 + +### 3.3 Spotube + +Source: 前次研究已確認 Spotube 有「Logs 頁面」與 clipboard 複製(未附出處 URL,屬於前次研究成果,本輪未重新查證,若要在設計文件中引用需要重新取得原始碼路徑確認;本輪聚焦在其設定/資料庫遷移,見下方第 5 節)。屬於三者中最簡化的基準線:僅「看 log + 複製」,沒有結構化診斷包也沒有已知的遮罩管線說明。**此段落標記為推測/待補證據**,不建議直接引用其遮罩實作細節。 + +### 3.4 Jellyfin 系列 client + +本輪與前次研究皆未能取得 Jellyfin 官方 client 或其他第三方 Jellyfin client(非 Finamp)的診斷包原始碼與具體欄位清單。**查不到**具體證據,故本文件不對 Jellyfin 系列做超出「以 Finamp 為代表」以外的單獨陳述(Finamp 本身就是一個 Jellyfin client,已在 3.2 節詳細覆蓋)。 + +### 3.5 對 FMP 診斷包設計的建議結構 + +綜合 NewPipe(欄位結構)與 Finamp(遮罩管線): + +- 欄位面向抄 NewPipe:app 版本、平台(OS 字串)、UI 語言、觸發時的使用者操作、觸發時的請求(經遮罩)、例外與 stack trace(經遮罩,見姊妹篇 2.2 節 stackTrace 需要遮罩的結論)、時間戳;明確**不收集**裝置型號等硬體資訊(跟隨 NewPipe 的隱私取捨,且 owner brief 未要求裝置資訊)。 +- 遮罩時機抄 Finamp:診斷包產生函式呼叫同一個頂層遮罩函式組字串,Debug 頁的「匯出」按鈕只是把這個已經遮罩過的字串包成檔案分享,不在匯出那一步才做遮罩。 +- 三種輸出格式(畫面顯示 / 匯出檔案 / 未來若要 JSON 上傳)共用同一份資料模型,抄 NewPipe 的架構,避免 owner 要求的「單一遮罩函式」被繞過在某個格式專屬的字串拼接路徑上。 + +--- + +## 5. 設定分組與儲存 + +比較對象:Spotube(Hive → Drift 遷移後的現況)、Finamp(現況仍為 Hive),並對照 FMP 自身 ADR 0010(drift 資料層)與 Riverpod 配對方式。 + +### 5.1 Spotube:Drift 單列寬表(single-row-multi-column) + +證據取得方式:`gh api repos/KRTirtho/spotube/git/trees/master?recursive=true` 找到檔案路徑後,直接 fetch 兩支原始碼確認。 + +**Schema 設計**(`lib/models/database/tables/preferences.dart`):一張 `PreferencesTable`,`id` 是唯一的 `IntColumn`(`autoIncrement()`),實際運作時**永遠只有 `id = 0` 這一列**,其餘每個設定項各佔一個獨立型別的欄位(`BoolColumn`/`TextColumn`/`IntColumn`),共約 24 個設定欄位: + +| 欄位 | 型別 | 預設值/備註 | +|---|---|---| +| albumColorSync | Bool | true | +| amoledDarkTheme | Bool | false | +| checkUpdate | Bool | true | +| normalizeAudio | Bool | false | +| showSystemTrayIcon | Bool | false | +| systemTitleBar | Bool | false | +| skipNonMusic | Bool | false | +| closeBehavior | Text(`textEnum()`) | close | +| accentColorScheme | Text(`text()`,自訂 `SpotubeColorConverter` 轉換) | "Slate:0xff64748b" | +| layoutMode | Text(`textEnum()`) | adaptive | +| locale | Text(JSON,`LocaleConverter` 轉換) | 系統語言/地區 | +| market | Text(`textEnum()`) | US | +| searchMode | Text(`textEnum()`) | youtube | +| downloadLocation | Text | "" | +| localLibraryLocation | Text(`StringListConverter`) | "" | +| themeMode | Text(`textEnum()`) | system | +| audioSourceId | Text(nullable) | — | +| youtubeClientEngine | Text(`textEnum()`) | youtubeExplode(**注意**:程式碼裡另有 `defaults()` 靜態方法在非 iOS 平台改用 `newPipe`,與 SQL column default 不一致,屬於 Spotube 自己程式碼裡的一個小瑕疵,設計 FMP 時要避免「SQL 層預設值」與「Dart 層預設值」兩處各自維護造成分歧) | +| discordPresence | Bool | true | +| endlessPlayback | Bool | true | +| enableConnect | Bool | false | +| connectPort | Int | -1 | +| cacheMusic | Bool | true | + +**Riverpod 配對方式**(`lib/provider/user_preferences/user_preferences_provider.dart`): + +- `build()` 同步先回傳 `PreferencesTable.defaults()`(讓 UI 立刻有值可用,不必等資料庫回應),接著非同步查 `id = 0` 那一列;查無則 insert 一列預設值(含平台相關的下載路徑計算)。 +- 用 drift 的 `watchSingle()`(針對 `id = 0` 的 reactive stream)持續監聽,每次資料庫變動都會重新 emit,然後把 `state` 設成新值——**資料庫是唯一事實來源,provider 只是鏡射**。 +- 寫入一律走同一個 `setData(PreferencesTableCompanion(...))` 方法,內部是 `db.update(db.preferencesTable)..where((t) => t.id.equals(0))` 再 `.write(companion)`;因為 drift 的 companion 只帶「有指定的欄位」,未指定的欄位不會被覆寫,所以每個設定項的 setter 只需要包一個單欄位的 companion。 +- `reset()` 用 `query.replace(PreferencesTableCompanion.insert(id: const Value(0)))` 整列換成全新的 insert companion,所有欄位回到 table 預設值。 +- 錯誤處理:訂閱 `watchSingle()` 的錯誤導到 `AppLogger.reportError`(Spotube 自己的錯誤上報,非本研究重點)。 +- `ref.onDispose` 時取消 stream 訂閱。 + +### 5.2 Finamp:Hive 單一物件(現況仍非 drift/SQLite) + +Sources: +- https://raw.githubusercontent.com/finamp-app/finamp/legacy/lib/services/finamp_settings_helper.dart +- https://raw.githubusercontent.com/finamp-app/finamp/legacy/lib/models/finamp_models.dart + +**確認後的實際形狀**(先前一份基於記憶/未直接查證的筆記說法已由本輪直接讀取原始碼驗證,可視為確認而非推測): + +- `FinampSettings` 是一個 `@HiveType(typeId: 28)` 的**扁平物件**,`@HiveField(0)` 到 `@HiveField(26)`,共 27 個欄位,全部平鋪,沒有拆子物件分組(欄位清單含 `isOffline`/`shouldTranscode`/`transcodeBitrate`/`sleepTimerSeconds`/`bufferDurationSeconds` 等播放與同步相關設定,也有 3 個標記 deprecated 但仍保留欄位位置的舊設定,例如 `downloadLocations`→改用 `downloadLocationsMap`)。 +- 儲存位置:單一 Hive box,box 名稱與 box 內的 key 都寫死是字串 `"FinampSettings"`(`Hive.box("FinampSettings").get("FinampSettings")!`),也就是整個設定物件只有唯一一筆記錄,用一個固定 key 存取——形狀上等同 Spotube drift 表的「永遠只有一列」,只是儲存引擎不同(Hive 物件序列化 vs. SQL 列)。 +- 寫入模式是「整包讀出、改一個欄位、整包寫回」:`finampSettingsTemp = finampSettings; finampSettingsTemp.xxx = newValue; box.put("FinampSettings", finampSettingsTemp);`——與 drift 用 companion 只送「有變更的欄位」不同,Hive 這邊每次都要重新序列化整個物件。 +- 對 UI 的曝光是 `ValueListenable>`(Hive 原生機制),不是 Provider 或 Riverpod,UI 端要包 `ValueListenableBuilder`。 +- 原始碼裡有作者自己留的風險註解,坦承 box 在啟動時才建立、目前用 `!` 強制解包「以後可能會出問題」,以及 `resetTabs()` 方法疑似忘記呼叫 `put()` 導致變更未落盤——這兩點是 Hive 單物件模式在缺乏型別安全交易保護下容易犯的錯誤類型,供 FMP 設計 drift 版本時引以為戒(drift 的 `update().write(companion)` 本身是一個明確的資料庫操作,比「改記憶體物件後要記得手動 put」更不容易漏寫)。 + +### 5.3 對 FMP 的建議(呼應 ADR 0010 drift 決定) + +**單列多欄(single-row-multi-column)優於 key-value 表**,理由: + +1. **兩個實例佐證同一個方向**:Spotube 選 drift 單列寬表;Finamp 雖然是 Hive,但本質也是「單一物件、扁平欄位」——兩個獨立專案在不同儲存引擎下收斂到同一種資料形狀(一筆記錄、每個設定各自一個具名欄位),沒有一個看到的先例是用 key-value table(`key TEXT, value TEXT` 那種形狀)存應用設定。 +2. **型別安全**:drift 的具名欄位配合 `textEnum()` 或自訂 `TypeConverter`,讓每個設定在 Dart 端直接是強型別(enum/bool/int),比 key-value 表「value 欄位存字串、讀出來自己 parse」更不容易在遷移或多處讀寫時出現型別不一致。 +3. **Riverpod 配對模式現成可抄**:Spotube 的 `build()` 先給同步預設值、`watchSingle()` 做 reactive 更新、寫入統一走一個 `setData(companion)` 方法——這一整套模式可以直接對應到 FMP 的 `audioControllerProvider` 之類「資料庫是事實來源、provider 是鏡射」的既有慣例(`AGENTS.md` Boundaries 段落描述的 provider 分工原則),架構上一致。 +4. **key-value 表的已知缺點**(本節為基於一般資料庫設計常識的推論,非本輪直接找到反例佐證,標記**推測**):每加一個設定就要多一列,型別要另外編碼(例如塞 JSON 字串或加一個 type 欄位做 tagged union),migration 時「這個 key 的值格式要換」不像 drift 的 column migration 那樣有型別檢查與遷移工具鏈支援;查詢單一設定值也變成要 `WHERE key = ?` 而非直接讀欄位。 + +**建議的 FMP 分組方式**:跟隨 Spotube「一張 preferences 表 + 其他 per-domain 表分開」的思路(Spotube 除了 `preferences.dart` 外還有 `audio_player_state.dart`/`authentication.dart`/`history.dart` 等各自獨立的表),而不是把所有設定通通塞進一張表——這與 owner brief 提到的「settings grouping」直接對應:日誌/診斷相關設定(log level、輪替策略、是否啟用網路請求記錄)可以是 preferences 表裡的欄位,也可以視規模拆一張專屬的 `logging_settings` 表,這屬於設計階段(`design.md`)要決定的細節,本研究只確認「單列寬表」這個整體形狀的方向。 + +**待 owner 定案的開放問題**: +- preferences 表是否要為了未來擴充性拆成多張(例如 UI 設定 vs. 播放設定 vs. 日誌設定各一張表,皆單列),還是维持 Spotube 那種「一張大表」——drift 的 migration 機制對兩種形狀都支援,不構成技術障礙,純粹是模組化 vs. 簡單性的取捨,需要 owner 對照 ADR 0010 已定的方向決定。 +- FMP 是否需要 Spotube 那種「先同步回傳預設值、非同步才 seed 資料庫」的模式,或者可以接受啟動時等資料庫 ready 才顯示設定頁——取決於 FMP 現有啟動流程的 UX 要求,非本研究範圍。 diff --git a/.trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md b/.trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md new file mode 100644 index 000000000..86420a06b --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md @@ -0,0 +1,216 @@ +# 研究:日誌套件、遮罩策略、網路請求日誌 + +範圍對應 task brief 項目 1、2、4。規則:版本 / 平台 / 維護狀態一律附 URL;查不到寫「查不到」;推測寫「推測」。全文繁體中文,程式識別碼保留原文。 + +--- + +## 1. 日誌套件比較 + +候選:`logging`、`logger`、`talker`(+ `talker_flutter`、`talker_dio_logger`)、`loggy`、自寫薄層。 + +### 1.1 版本與維護狀態(pub.dev API,抓取於 2026-09-27) + +| 套件 | 最新版本 | 發布日期 | 發布者 | 來源 | +|---|---|---|---|---| +| `logging` | 1.3.0 | 2024-10-17 | Dart team(`dart-lang/core` monorepo,作者欄 `Dart Team `;pub.dev 是否為 verified publisher 查不到,僅能由 repository URL `github.com/dart-lang/core/tree/main/pkgs/logging` 佐證) | https://pub.dev/api/packages/logging | +| `logger` | 2.8.0 | 2026-09-05 | verified publisher `sourcehorizon.org` | https://pub.dev/api/packages/logger | +| `talker` / `talker_flutter` / `talker_dio_logger` | 全部 5.1.20(同步發版) | 2026-07-28 | `frezyx`(talker 作者) | https://pub.dev/api/packages/talker_dio_logger 、 https://pub.dev/api/packages/talker_flutter | +| `loggy` | 2.0.3 | 2022-11-07(近 4 年未更新) | verified publisher `infinum.com` | https://pub.dev/api/packages/loggy | + +`logging` 距今近兩年未發版但屬 Dart 官方套件,API 面極小(`Logger`/`LogRecord`/`hierarchicalLoggingEnabled`),停滯代表「穩定」而非「廢棄」。`loggy` 近 4 年零更新,且下方 1.2 節會說明其功能缺口,判斷為**不推薦**而非單純過時。 + +### 1.2 五平台支援(pub.dev 分數頁,抓取於 2026-09-27) + +| 套件 | Android/iOS/Windows/Linux/macOS/Web | Pub points | 備註 | +|---|---|---|---| +| `logger` | 6/6 皆支援 | 150/160 | Web 非 WASM 相容(`advanced_file_output_stub.dart` import `dart:io`),平台分只拿 10/20;不影響 Android/Windows/Linux 使用 | +| `talker_flutter` | 6/6 皆支援 | 160/160 | WASM-ready;`share_plus` 透傳的 `url_launcher_windows`/`url_launcher_linux` 平台警告不計分 | +| `loggy` | 6/6 皆支援,WASM-ready | 150/160(靜態分析扣 10) | — | +| `logging` | 純 Dart package,無平台限制(查不到 pub.dev 分數頁的逐平台列表,但作為 `dart:core` 層級套件不含平台相關程式碼,推測全平台可用) | 查不到 | — | + +FMP 目標平台為 Android + Windows(+ ADR 0009 提到的 Linux),四個套件在平台支援面都不構成排除理由。 + +Sources: https://pub.dev/packages/logger/score 、 https://pub.dev/packages/talker_flutter/score 、 https://pub.dev/packages/loggy/score + +### 1.3 功能矩陣 + +| 能力 | `logging` | `logger` | `talker`生態 | `loggy` | 自寫薄層 | +|---|---|---|---|---|---| +| Log level | 內建 `Level`,可階層式(`hierarchicalLoggingEnabled`) | 內建 `Level` | 內建 `LogLevel` + `TalkerLog` 型別 | 內建,含自訂 `LogOptions` | 自訂 enum,工作量最小 | +| 結構化欄位(非純字串) | `LogRecord` 有 `error`/`stackTrace`/`zone`,無自由欄位 map | 同左,`error`/`stackTrace` | `TalkerData` 有 `message`/`exception`/`error`/`stackTrace`,**皆為 `final`**(見下方 2.4 節的關鍵限制) | 僅 `message`/`error`/`stackTrace` | 完全自訂 | +| 記憶體內歷史(in-app 可查) | 無內建,需自接 `Logger.root.onRecord.listen` 手動存 list | `MemoryOutput`(`BufferOutput` 子類,可設 buffer size) | `Talker` 本身即維護 `history` list(`TalkerHistory` 介面),為套件核心設計 | 無內建,需自接 stream | 自訂 ring buffer | +| 落盤 + 輪替 | 無內建 | `AdvancedFileOutput`:支援依大小/時間輪替、`maxLogFiles` | 無內建輪替;需自接 `FileOutput`(社群方案)或自寫 | 無內建 | 自訂(FMP 現況即此路線) | +| 內建檢視 UI | 無 | 無(純 logging 套件,無 UI 套件) | **有**:`talker_flutter` 提供 `TalkerScreen`/`TalkerView`,含分級篩選、搜尋、複製、分享匯出 | 無 | 無(FMP 現況自寫 Debug 頁) | +| dio 整合 | 無官方橋接 | 無官方橋接(需自寫 `Interceptor` 呼叫 `Logger`) | **有**:`talker_dio_logger`(官方子套件,見下方第 4 節) | 需額外套件 `flutter_loggy_dio`(非官方維護,功能未知,查不到近期更新記錄) | 自訂 dio interceptor | +| Riverpod 整合 | 無官方橋接,慣例做法是把 logger 實例包成一個 `Provider` | 同左 | 無官方 Riverpod 套件;talker 本身是一個可注入的物件,包 `Provider()` 即可,方式與其他兩者相同 | 同左 | 自訂 | +| release build 自動抑制 | 需手動判斷 `kReleaseMode` 設定 `Logger.root.level = Level.OFF` | **內建**:預設 `Filter` 是 `DevelopmentFilter`,`kReleaseMode` 下自動只放行 `Level.warning` 以上(原始碼行為,見 pub.dev 文件) | 無自動行為,需自己在建構 `TalkerSettings` 時依 `kReleaseMode` 設 `enabled`/`useConsoleLogs` | 無自動行為,需自訂 `LogOptions` | 自訂,FMP 現況已自行處理 | +| 單一遮罩 hook 點 | 無(資料模型 `LogRecord` 欄位非 final 但套件本身不提供攔截點) | 無官方攔截點,但呼叫端可在呼叫 `logger.d(msg)` 前自行處理 | **不可在 `TalkerObserver` 做**——`TalkerData` 的 `message`/`exception`/`error`/`stackTrace` 皆為 `final`,物件建立後才進 observer,字串已經定型(原始碼確認,見下方 2.4) | 無官方攔截點 | 完全掌控,天然是唯一 hook 點 | + +Sources(套件文件): +- `logger` `MemoryOutput`/`AdvancedFileOutput`/`DevelopmentFilter`:https://pub.dev/documentation/logger/latest/logger/logger-library.html +- `talker` 核心與 `TalkerData`:https://pub.dev/packages/talker ,原始碼確認見任務前段(`packages/talker/lib/src/talker.dart` 等,上一輪已讀取) +- `talker_flutter` `TalkerScreen`:https://pub.dev/packages/talker_flutter +- `talker_dio_logger`:https://pub.dev/packages/talker_dio_logger +- `loggy`:https://pub.dev/packages/loggy (功能限制由 README 描述反推,未見獨立的 history/file-output API) + +### 1.4 結論與理由 + +**推薦:`talker` + `talker_flutter` + `talker_dio_logger`。** + +理由(對照 owner 的四個硬性要求): + +1. **單一遮罩函式**:無論選哪個套件,`TalkerData` 系列欄位都是 `final`——這不是 talker 特有的限制,而是確認了一個通用結論:**遮罩必須發生在呼叫進 logging 套件的 API 之前**,也就是 FMP 現有的 `AppLogger` 薄層角色不能省。talker 在這件事上不比其他套件差,因為反正大家都得靠呼叫端遮罩。 +2. **內建歷史 + 內建 UI**:talker 唯一內建「歷史紀錄」和「現成 Debug 頁 UI 元件」的套件,可以直接省掉 FMP 現有 Debug 頁裡「log 檢視/過濾」那塊的自製 UI 工作量,同時仍可用 `TalkerScreen` 的客製化參數(`TalkerScreenTheme`、自訂 `logsListBuilder` 等,查不到完整客製清單,需要實作時再查 API doc)保留現有外觀。 +3. **dio 整合官方支援**:`talker_dio_logger` 是同一作者維護、隨 talker 同步發版(見 1.1 版本同步的證據),比起自己接 `logger`/`loggy` 的 dio interceptor,維護面更集中。 +4. **release 抑制**:talker 沒有像 `logger` 的 `DevelopmentFilter` 那樣自動化,需要自己在初始化時判斷 `kReleaseMode`——這點 `logger` 略勝,但差距是一行 `if (kReleaseMode) ...` 的等級,不足以扭轉結論。 +5. **維護活躍度**:三個 talker 子套件在 2026-07-28 同步發到 5.1.20,屬於目前候選中最新鮮的(`logger` 2026-09-05 更新更近,但 `logger` 沒有內建 UI/歷史/dio 官方整合,三項關鍵能力都要自己補)。 + +**為何不選 `logger`**:功能面(`MemoryOutput` + `AdvancedFileOutput` + release 自動抑制)扎實,但沒有內建 UI 元件,Debug 頁的「log 檢視/過濾」仍要自己刻;dio 整合也要自己寫 interceptor。等於在「網路日誌」與「UI」這兩塊都要重新造 talker 生態已經提供的輪子。 + +**為何不選 `loggy`**:近 4 年未更新,且不論歷史或落盤都要自己補,dio 整合還得依賴一個看不到維護紀錄的第三方套件 `flutter_loggy_dio`,風險最高、能力最少。 + +**為何不選 `logging` 或自寫薄層當「後端」**:`logging` 是最小可用的分級 API,沒有歷史/UI/dio 整合,等同從零開始搭;自寫薄層工作量最大,且 FMP 現有 `AppLogger` 已經是這條路線,若要重寫,talker 能提供的 UI + 歷史管理是現成的淨增量,沒有理由再全部自己刻一次。 + +**待 owner 定案的開放問題**: +- talker 的 `TalkerScreen` UI 客製化程度是否足以取代 FMP Debug 頁現有外觀,還是要另外接自訂 UI 只用 talker 當後端資料源——需要在設計階段實際跑一次 `TalkerScreen` 才能判斷,本次研究未做 UI 實測(不在本任務範圍:純研究,不寫程式碼、不跑 app)。 +- release build 下是否要完全關閉本地檔案落盤(只保留記憶體歷史),或降級只寫 warning 以上——這是產品決策,非技術限制。 + +--- + +## 2. 遮罩(redaction)策略 + +### 2.1 三種可辨識的遮罩手法 + +| 手法 | 判斷依據 | 代表實作 | +|---|---|---| +| (a) 結構化 allowlist:依 **key 名稱** + regex | 掃過 map/JSON 的 key,命中黑名單 key 就整個值換成 `***` | FMP 現有 `AppLogger.redactSensitive`(26 個 key 名稱,不分大小寫比對,但**沒有 word boundary**,例如 key 名 `apikey_display_name_only` 也會誤命中——見 `docs/audit/accounts-network.md` §4.1 對此缺口的描述) | +| (b) 結構性截斷:依 **URL 形狀** | 不看內容是否敏感,一律只留 `scheme://host/…/最後一段`,中段路徑與整個 query 丟棄 | FMP 現有 `redactStreamUrl`(`lib/services/audio/playback_media.dart:12`),因為 YouTube HLS manifest 與 NetEase 的簽章可能落在**路徑中段**而非 query,只砍 query 不夠 | +| (c) 已知值替換:拿**目前登入帳號的實際敏感值**做全文字串比對替換 | 不靠 key 名稱也不靠 URL 形狀,而是遍歷「目前所有已登入帳號」的 `baseUrl`/`accessToken` 等真實值,在整段 log 字串(**含 stack trace**)中做不分大小寫的精確值比對並替換 | Finamp `censored_log.dart`(`legacy` 分支):對每個 `finampUserHelper.finampUsers` 的帳號,把其 `baseUrl`、`accessToken` 的字面值在 log 全文中取代;另外任何標記 `containsLogin` 的紀錄整則訊息直接換成字串 `"LOGIN BODY"` | + +Source(Finamp):https://raw.githubusercontent.com/finamp-app/finamp/legacy/lib/services/censored_log.dart + +**手法比較**:(a)(b) 屬「靜態規則」,不需要知道當下登入了誰,缺點是規則要窮舉 key 名稱/URL 形狀,容易漏;(c) 屬「動態比對」,優點是不管值出現在哪個欄位、哪種格式都能抓到(因為比對的是值本身,不是位置),缺點是只能遮罩「已知在系統裡的值」,對外部本來就未儲存成帳號物件的一次性 token(例如某次請求臨時簽出的 CDN 網址)無效,仍需要靠 (b) 的結構性規則補。**三者互補、不互斥**——FMP 應該三種都留:(a) 管一般 header/表單欄位、(b) 管 CDN 簽名網址、(c) 管「目前登入帳號」的長效憑證(cookie/token/baseUrl),三層疊加。 + +### 2.2 stackTrace 是否需要遮罩 + +需要。證據: +- Finamp 的已知值替換明確涵蓋 stack trace 全文(見上)。 +- FMP 自己的稽核發現「log 檔案裡 stackTrace 是原樣寫入,沒有經過任何遮罩」是一個現存缺口(`docs/audit/accounts-network.md` §4.2,log file 那一列:「stackTrace 原樣寫入」)。 +- 理由很直接:Dart 例外訊息常把觸發例外的請求物件(含 URL、header)字串化進 `toString()`,這段字串會被收進 stackTrace 或 exception message,等於繞過任何只檢查「log 呼叫參數」而不檢查「例外物件內容」的遮罩。 + +結論:遮罩函式的輸入必須包含 `error`/`exception` 物件的 `toString()` 結果與 `StackTrace` 的 `toString()`,不能只處理呼叫端傳入的純文字訊息。 + +### 2.3 CDN 簽名網址參數名稱清單 + +#### Bilibili(upos) + +證據來源:`SocialSisterYi/bilibili-API-collect` 原始倉庫已被 GitHub 封存且預設分支改名為 `deprecated`、內容清空(疑似下架事件,`gh api repos/SocialSisterYi/bilibili-API-collect` 確認 `archived:true`),改用其活躍 fork `pskdje/bilibili-API-collect` 的 `docs/video/videostream_url.md`(master 分支,內容完整,含真實擷取範例網址)。 + +Source: https://raw.githubusercontent.com/pskdje/bilibili-API-collect/master/docs/video/videostream_url.md + +會被 `upsig` 簽章覆蓋、必須視為敏感的參數(`uparams` 欄位本身會自我聲明涵蓋哪些 key,例如實測值 `uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform`): + +| 參數 | 意義 | 敏感等級 | +|---|---|---| +| `e` | 不透明長權杖 | 高(簽章覆蓋) | +| `uipk` | 未知用途,簽章覆蓋 | 中 | +| `nbs` | 未知用途,簽章覆蓋 | 中 | +| `deadline` | unix 秒數到期時間 | 中(本身非機密,但暴露「這條網址還能用多久」;**FMP 自己的 `playback_request_session.dart` 的 `_expiryFromUrl` 函式已在讀這個欄位算過期時間,等於一階證據確認此參數存在且被 FMP 使用**) | +| `gen` | 產生方式(playurl/playurlv2/playurlv3) | 低 | +| `os` | CDN 路由標籤(mcdn/cosbv/08cbv/bcache/upos) | 低 | +| `oi` | 數字 id | 低 | +| `trid` | 請求追蹤 id | 低 | +| `mid` | **使用者數字 id——敏感,可識別帳號** | 高 | +| `platform` | pc/html5 | 低 | +| `upsig` | 簽章雜湊本身 | 高 | + +非簽章覆蓋但仍屬路由/裝置指紋的參數:`bvc`、`nettype`、`orderid`、`agrr`、`bw`、`logo`、`og`、`mcdnid`、`cdnid`、`buvid`(裝置指紋)、`build`、`lrs`、`tag`、`dl`、`f`、`qn_dyeid`。 + +另外,*請求*端(非回傳網址)會帶一個 `session` 參數(buvid3 + 時間戳做 md5),用途是配額驗證,與回傳的 CDN 網址簽章是兩件事,同樣需要遮罩。 + +一階佐證:`lib/services/audio/playback_request_session.dart` 約第 434 行: + +```dart +Duration _expiryFromUrl(String url) { + final deadline = int.tryParse( + Uri.tryParse(url)?.queryParameters['deadline'] ?? '', + ); + ... +} +``` + +(FMP 自己的程式碼直接讀 `deadline` 這個 query 參數,證實其存在且被業務邏輯依賴。) + +#### YouTube(googlevideo) + +沿用上一輪研究成果(`docs/audit/accounts-network.md` 與外部 InnerTube 相關文件已於前次交叉確認,本輪未重新查證,逐字保留):`expire`、`ei`、`ip`、`id`、`itag`、`mime`、`sig`、`lsig`、`sparams` 等;`sparams` 本身也會像 Bilibili 的 `uparams` 一樣列出哪些參數被簽章涵蓋。InnerTube API 呼叫另有 `key=` 這個 API key query 參數,`docs/audit/accounts-network.md` §4.1 明確指出這是 FMP 現有 `redactSensitive` 完全沒處理到的缺口。 + +#### NetEase Cloud Music + +**結構性結論:NetEase 的串流網址本身不走「query string 簽章」這條路。** + +證據鏈: +1. GitHub 外部查證是死路——`Binaryify/NeteaseCloudMusicApi` 已被封存且倉庫清空至只剩 README(`size:1`),`gh api .../forks` 逐一檢查約 30 個 fork,全部一樣被清空(同樣疑似下架事件),無法從外部文件補上參數名稱清單。 +2. 改用 FMP 一階原始碼佐證:`lib/core/utils/netease_crypto.dart` 顯示 NetEase 兩套簽章機制—— + - `weapi()`:雙層 AES-128-CBC 加密 + RSA 包公鑰,回傳 `{'params': ..., 'encSecKey': ...}`,這兩個值放進 **POST body**,不是 URL query。 + - `eapi()`:AES-128-ECB + MD5 完整性摘要,回傳一段 hex 編碼的 `params` 字串,一樣放進 **POST body**。 +3. 串流網址的到期時間來自 API JSON 回應裡的 `expi` 欄位(缺省 fallback 16 分鐘),同樣不是 URL 參數。 + +**對遮罩設計的意涵**:對 NetEase 的音訊串流網址做「砍 query」幾乎是 no-op——網址本身結構上就沒有東西好砍。真正需要遮罩的是**請求時的 POST body**(`params`/`encSecKey` 或 hex `params`)與**隨請求附帶的 header/cookie**(`docs/audit/accounts-network.md` §3.3、§4.1 記錄的 `X-Real-IP: 118.88.88.88` 這個固定偽造值本身不敏感,但同一批請求帶的帳號 cookie 敏感)。換句話說,NetEase 這條路徑的遮罩重點從「URL 形狀」轉移到「POST body 內容」與「header/cookie」,跟 Bilibili/YouTube 的威脅模型不同,設計文件要分開處理,不能套用同一個「砍 query」function 就當作三個來源都覆蓋到了。 + +Sources: `lib/core/utils/netease_crypto.dart`(FMP 原始碼)、`docs/audit/accounts-network.md` §3.3 / §4.1(FMP 稽核文件)。 + +### 2.4 為何遮罩不能做在 logging 套件內部(架構結論) + +以 talker 為例驗證(原始碼於前次研究讀取確認):`TalkerData` 的 `message`、`exception`、`error`、`stackTrace` 全部宣告為 `final`,物件建構完成後才會傳進 `TalkerObserver.onLog()`。也就是說: + +- 想在 `TalkerObserver` 裡攔截並改寫內容——**做不到**,欄位是 `final`,观察者拿到的已經是定型後的物件,只能讀不能改。 +- talker 內建的匯出機制(`talker_flutter` 的 `download_logs_native.dart`)是**原樣**把歷史紀錄寫成純文字檔案再呼叫 `SharePlus` 分享,過程中不會做任何二次處理。 + +(Source:https://raw.githubusercontent.com/frezyx/talker/master/packages/talker_flutter/lib/src/utils/download_logs/download_logs_native.dart ,確認匯出用 `path_provider` 存到暫存檔 `talker_logs_.txt` 後 `SharePlus.instance.share(ShareParams(files:...))`。) + +**結論對三個套件都成立,不是 talker 特有的限制**:無論最終選 `logging`/`logger`/`talker`/`loggy` 哪一個當後端,遮罩都必須在「呼叫進 logging 套件 API 之前」完成,也就是 owner 要求的「單一遮罩函式」在架構上只能是一層**呼叫端的薄 facade**(FMP 現有 `AppLogger` 的角色),而不能實作成任何一個 logging 套件的 plugin/observer/formatter。這對「Toast 詳情、Debug 頁、診斷包、logs 都要走同一個遮罩函式」這個 owner 需求是決定性的架構前提:這四個出口理論上可能分別呼叫「logging 套件的 API」與「build 診斷包字串」與「顯示 Toast 文字」三種不同路徑,若遮罩函式只掛在 logging 套件裡,另外三個出口就會漏接——必須讓四個出口的原始資料在各自組字串前,共同先過同一個頂層函式。 + +--- + +## 3. 網路請求日誌(dio interceptor) + +比較對象:`talker_dio_logger`、`pretty_dio_logger`、`alice`(含 `alice_dio` adapter)/ `alice_lightweight`。 + +### 3.1 版本與維護狀態 + +| 套件 | 最新版本 | 發布日期 | 備註 | +|---|---|---|---| +| `talker_dio_logger` | 5.1.20 | 2026-07-28 | 與 talker 核心同步發版 | +| `pretty_dio_logger` | 1.4.0 | 2024-07-21 | Dart SDK 限制 `>=3.0.0 <4.0.0`;1.1.1 起不再宣告 Flutter SDK 依賴(純 Dart 相依 `dio: ^5.5.0`),近 2 年多未更新但 API 面小、無明顯棄用訊號 | +| `alice`(核心) | 1.10.0 | 2026-09-18 | verified,pub points 160/160,6/6 平台(含 Windows/Linux),WASM-ready | +| `alice_dio`(dio adapter) | 1.3.2 | 2026-09-18 | 依賴 `alice: ^1.10.0`、`dio: ^5.8.0+1`,與核心同步發版 | +| `alice_lightweight` | 3.10.0 | 2025-05-12 | 第三方 fork(`payfazz`),移除部分依賴的輕量版,維護活躍度低於官方 `alice`+`alice_dio` 組合 | + +Sources: https://pub.dev/api/packages/talker_dio_logger 、 https://pub.dev/api/packages/pretty_dio_logger 、 https://pub.dev/api/packages/alice 、 https://pub.dev/api/packages/alice_dio 、 https://pub.dev/api/packages/alice_lightweight 、 https://pub.dev/packages/alice/score + +**修正歷史**:舊版 `alice`(`jhomlala/alice`,對應本輪之前的既有印象)採單一套件內建全部 adapter 的設計,`getDioInterceptor()` 一類方法后來被移除;目前(1.10.0,2026-09-18)採**模組化設計**——核心 `alice` 套件 + 專用 adapter 套件(`alice_dio`/`alice_http`/`alice_chopper` 等),透過 `AliceDioAdapter().getInterceptor(alice)` 掛進 dio。`alice_lightweight` 是舊架構下「移除多餘依賴」的 fork,在新架構模組化之後已不是必要的替代方案,因為官方版現在本來就用得輕量。 + +### 3.2 各套件記錄的內容與用途 + +| 套件 | 記錄內容(可設定項) | 保留方式 | 內建遮罩 | +|---|---|---|---| +| `talker_dio_logger` | 走 talker 的 `TalkerDioLogger` interceptor,把 request/response/error 轉成 talker 的 log 條目,進而進入 talker 的 history/UI 同一套機制 | 併入 talker 歷史(受 talker 的記憶體上限與(若接了)落盤規則管) | **無**,且因 `TalkerData` 欄位 final(見 2.4 節),必須在呼叫 `talker.log(...)`/`GenerousDioLogInterceptor` 產生訊息**之前**完成遮罩——即需要客製 `TalkerDioLogger` 的 `requestPen`/`responsePen`/`errorPen` 或自寫等價 interceptor,在組字串當下呼叫遮罩函式 | +| `pretty_dio_logger` | 依建構參數各自開關:`requestHeader`(預設 false)、`requestBody`(預設 false)、`responseHeader`(預設 false)、`responseBody`(預設 **true**)、`error`(預設 true);另有 `filter` callback 可依 `RequestOptions`/資料型別排除特定請求 | **不保留歷史**——純粹即時印到 `logPrint`(預設 `print`),沒有記憶體 buffer 或檢視 UI,要保留歷史得自己接 `logPrint` 存起來 | **無**內建遮罩;但有 `filter` 掛鉤可用來跳過或改寫要印的內容(原始碼 `onRequest`/`onResponse`/`onError` 都是先跑 `filter` 判斷再印,理論上可以在 `filter` 或自訂 `logPrint` 裡插入遮罩,但這是繞過官方設計意圖的用法,官方 API 沒有正式的「內容改寫」鉤子,只有「是否印」的布林鉤子) | +| `alice` + `alice_dio` | 完整請求/回應(header、body、query parameter〔限 dio〕、狀態碼、耗時),另外附加圖片/影片預覽、curl 匯出、安全/不安全連線標示 | **有獨立的 Inspector UI**(`showInspector()`),有自己的儲存/瀏覽機制,功能面最重 | 查不到官方文件提及任何內建遮罩機制(README/pub.dev 敘述未提 redaction),推測需要在 adapter 層自行處理,等同前兩者的限制 | + +Sources: +- `pretty_dio_logger` 建構參數與 `onRequest`/`onResponse`/`onError` 原始碼:context7 `/websites/pub_dev_pretty_dio_logger`(來源 https://pub.dev/documentation/pretty_dio_logger/latest/ ) +- `alice`/`alice_dio` 功能描述:https://pub.dev/packages/alice 、 https://pub.dev/packages/alice_dio (WebSearch 摘要整理,功能清單部分來自同系列套件的歷史描述,未逐條在原始碼核對,標記為**推測**的部分已在上表註明) + +### 3.3 結論 + +延續第 1 節選定 talker 生態的前提下,**`talker_dio_logger` 是自然選擇**,理由: +- 統一進 talker 的 history/UI,不必再維護第二套「網路請求檢視」畫面,直接對應 owner 要求的「Debug 頁要有網路請求檢視」。 +- 遮罩鉤子的限制與第 2.4 節結論一致——不管選哪個 dio logger 套件,都得在 interceptor 組訊息字串的當下呼叫同一個頂層遮罩函式,`talker_dio_logger` 允許自訂 `requestPen`/`responsePen`(需在實作階段查 API 細節確認精確簽名,本研究未逐行核對這兩個 callback 的參數型別,標記**查不到**具體簽名,只確認 talker_dio_logger 支援客製化輸出這件事本身)。 +- `alice` 系列功能最完整(含 curl 匯出、圖片預覽),但代價是引入一整套獨立於 talker 的 UI/儲存系統,會與「單一遮罩函式」「統一 Debug 頁」的目標打架——等於要在兩個獨立系統裡各自插入遮罩鉤點,增加遺漏風險。除非 owner 認為 curl 匯出等進階功能是硬需求,否則不建議引入。 +- `pretty_dio_logger` 不保留歷史,不符合 owner「網路請求要能檢視」的需求(純粹即時印出,重啟或翻頁後就看不到之前的請求),排除。 + +**待 owner 定案的開放問題**: +- `talker_dio_logger` 的 `requestPen`/`responsePen`/`errorPen` 客製化 callback 確切簽名與是否能完全掌控輸出字串(含 body 的巢狀結構如何序列化)需要在設計/實作階段直接讀套件原始碼或寫小範例驗證,本次研究以「文件已確認可自訂輸出」為止,未深入到逐參數層級。 +- 是否需要記錄 request body:若 body 含帳號密碼(如 NetEase 登入的 `password` 欄位),這是遮罩函式必須覆蓋的欄位,需在設計階段把「NetEase 登入 body 裡的密碼欄位」加進允許清單式遮罩(2.1 節手法 (a))的 key 名單。 diff --git a/.trellis/tasks/09-27-design-settings-logging/task.json b/.trellis/tasks/09-27-design-settings-logging/task.json new file mode 100644 index 000000000..b604e7ab6 --- /dev/null +++ b/.trellis/tasks/09-27-design-settings-logging/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-settings-logging", + "name": "design-settings-logging", + "title": "Design: settings and logging infrastructure", + "description": "Phase-2 item 18: settings grouping and storage, log levels, outputs, rotation and retention, and the single redaction function shared by logs, Debug page, diagnostics and toasts", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 1b341f8d3d67aa32abca2c76e019c9685de015eb Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 11:09:56 +0800 Subject: [PATCH 020/133] docs(adr): 0011 settings and logging infrastructure --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 3 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../implement.md | 6 +- .../09-27-design-settings-logging/prd.md | 11 +++- .../09-27-design-settings-logging/task.json | 4 +- docs/adr/0011-settings-and-logging.md | 61 +++++++++++++++++++ 6 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 docs/adr/0011-settings-and-logging.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index f1ebdd0a4..0e0461cfc 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -114,7 +114,7 @@ flowchart LR | 2 | 7 重寫策略(高層)(✅ 完成,ADR 0008;里程碑留到第 20 步定稿) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 | | 3 | 10 平台層(✅ 完成,ADR 0009) | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | | 4 | 6 資料層與相容(✅ 完成,ADR 0010) | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | -| 5 | 18 設定與日誌 | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | +| 5 | 18 設定與日誌(✅ 完成,ADR 0011) | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | | 6 | 12 網路與帳號 | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | | 7 | 2 錯誤模型 | 音源插件介面的回傳與例外型別要先定。 | | 8 | 1 音源插件 | 核心抽象;依賴 10、12、2。 | @@ -221,3 +221,4 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0010:`isar_community`+`sqlite3` 原生庫在 Android、Windows 共存;`sqlite3` 的 Android 16KB page size 對齊。 - ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 +- ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 70318e335..1289eae1c 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -23,7 +23,8 @@ "09-27-design-docs", "09-27-design-rewrite-strategy", "09-27-design-platform", - "09-27-design-data" + "09-27-design-data", + "09-27-design-settings-logging" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-settings-logging/implement.md b/.trellis/tasks/09-27-design-settings-logging/implement.md index 0407c087e..6ac59bf9f 100644 --- a/.trellis/tasks/09-27-design-settings-logging/implement.md +++ b/.trellis/tasks/09-27-design-settings-logging/implement.md @@ -2,8 +2,8 @@ 本任務只產出設計與 ADR;程式在里程碑中實作(日誌門面與遮蔽函式屬於第一個里程碑的基礎)。 -- [ ] 寫 `docs/adr/0011-settings-and-logging.md`:design.md §1–§6;被否決的選項(`logger`、`logging`、自寫全套、`TalkerScreen`、`talker_dio_logger`、`alice`、記錄 body、單一大設定表、key-value 表、`shared_preferences`);「如何確認」(lint、遮蔽測試、設定預設值測試)。 -- [ ] `phase2-plan.md` 標記第 18 項完成;「第一個里程碑的必要驗證」加上 log 門面與遮蔽函式。 -- [ ] 歸檔本任務。 +- [x] 寫 `docs/adr/0011-settings-and-logging.md`:design.md §1–§6;被否決的選項(`logger`、`logging`、自寫全套、`TalkerScreen`、`talker_dio_logger`、`alice`、記錄 body、單一大設定表、key-value 表、`shared_preferences`);「如何確認」(lint、遮蔽測試、設定預設值測試)。 +- [x] `phase2-plan.md` 標記第 18 項完成;「第一個里程碑的必要驗證」加上 log 門面與遮蔽函式。 +- [x] 歸檔本任務。 驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-settings-logging/prd.md b/.trellis/tasks/09-27-design-settings-logging/prd.md index c11e6bc9e..be568fd4c 100644 --- a/.trellis/tasks/09-27-design-settings-logging/prd.md +++ b/.trellis/tasks/09-27-design-settings-logging/prd.md @@ -30,6 +30,13 @@ - R5 設定依功能分組,每組一張單列表、每個設定一個有型別的欄位;欄位可為空=「使用者沒設定過,用程式預設」,讓預設值可以改而不動使用者值;每個音源的設定另一張表以音源 id 為鍵。 - R6 release 版不輸出到 logcat/stdout。 -## 待決定(見摘要) +## 已決定 -- release 版是否寫 log 檔,以及寫到哪個層級。 +- D1(使用者 2026-09-27):release 版寫 log 檔,層級 `info` 以上,單檔 2MB、保留 3 個,只存本機、經遮蔽、不上傳。 +- 其餘依研究與使用者要求(Debug 頁用 App 設計系統)寫入 design.md:不用 `TalkerScreen`、不用 `talker_dio_logger`、不記 body、設定分組單列表。 + +## 驗收標準 + +- [x] design.md 涵蓋日誌門面與輸出、遮蔽函式、網路紀錄、錯誤歷史、診斷包、設定建模。 +- [x] `docs/adr/0011-*.md` 依範本寫成。 +- [x] `phase2-plan.md` 標記第 18 項完成。 diff --git a/.trellis/tasks/09-27-design-settings-logging/task.json b/.trellis/tasks/09-27-design-settings-logging/task.json index b604e7ab6..621894067 100644 --- a/.trellis/tasks/09-27-design-settings-logging/task.json +++ b/.trellis/tasks/09-27-design-settings-logging/task.json @@ -3,7 +3,7 @@ "name": "design-settings-logging", "title": "Design: settings and logging infrastructure", "description": "Phase-2 item 18: settings grouping and storage, log levels, outputs, rotation and retention, and the single redaction function shared by logs, Debug page, diagnostics and toasts", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0011-settings-and-logging.md b/docs/adr/0011-settings-and-logging.md new file mode 100644 index 000000000..f1929e40d --- /dev/null +++ b/docs/adr/0011-settings-and-logging.md @@ -0,0 +1,61 @@ +# 0011 — 單一日誌門面與單一遮蔽函式;設定依功能分組、空值代表未設定 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`app/lib/core/logging/`、`app/lib/core/redaction/`、dio 攔截器、Debug 頁、診斷包、設定的資料表與 Riverpod 狀態 + +## 背景 + +舊專案的自製 `AppLogger` 只遮 header 與 key 名:stackTrace 不遮、CDN 簽名 URL 不遮、release 版仍輸出到 logcat, +AI 請求在 debug 級別整份寫進 log(`docs/audit/devtools.md` §3、`docs/audit/accounts-network.md` §4)。 +設定約 45 項,約 19 個 Notifier 各自讀寫同一列 `Settings`,migration 還改寫過使用者設定(`docs/audit/data.md` §2、§7)。 + +擁有者要求:所有會展示或匯出請求內容的地方(Toast 詳細、Debug 頁、診斷包、log)經過同一個遮蔽函式, +cookie、token、簽名 URL、API key 一律遮蔽;錯誤進入可檢索的歷史;Debug 頁用 App 的設計系統。 +設定存在資料庫、migration 不得改使用者設定過的值(ADR 0010)。 + +## 考慮過的選項 + +- **日誌套件**:`logger`(有輪替與記憶體輸出,但沒有檢視 UI 與 dio 整合)、`logging`(官方但極簡)、`loggy`(四年未更新)、 + 自寫全套、`talker`(採用:記憶體歷史、分派、五平台、持續維護)。 +- **檢視 UI**:`TalkerScreen`(否決:不是 App 的設計系統)vs 自製(採用)。 +- **網路紀錄**:`talker_dio_logger`(否決:直接寫入 talker,繞過遮蔽層)、`alice`(否決:另一套平行 UI 與遮蔽面)、 + `pretty_dio_logger`(否決:不留歷史)、自己的攔截器經門面寫入(採用)。記錄 request/response body(否決:遮蔽代價高、易漏)。 +- **遮蔽時機**:在 talker 觀察者裡遮(否決:talker 的紀錄欄位不可變,做不到)、在門面寫入前遮(採用)。 +- **設定建模**:單一大表(Spotube;否決:舊版多 Notifier 共寫一列的問題會延續)、key-value 表(否決:失去型別、無先例)、 + `shared_preferences`(否決:位置無法跟 Portable 版走,ADR 0010)、每組一張單列表(採用)。 +- **release 版 log 檔**:不寫(否決:重開後錯誤歷史消失)、只寫 warning 以上(否決:缺前因後果)、寫 info 以上(擁有者 2026-09-27 選定)。 + +## 決定 + +1. **日誌門面**:全 App 只有一個 log 入口,參數含訊息、tag(模組或音源 id)、error、stackTrace、結構化欄位; + 門面先遮蔽,再交給 `talker`(只用它的歷史與分派)。門面以外禁止 `print`、`debugPrint`、`developer.log` 與直接使用 talker。 +2. **輸出**:記憶體歷史最近 1,000 筆;檔案在 ADR 0009 資料目錄的 `logs/`,單檔 2MB、保留 3 個,寫入失敗不影響 App; + console 只在 debug build,release 不輸出到 logcat/stdout。release 預設層級 `info`,開發者模式可調到 `debug`。 +3. **遮蔽函式**(唯一一個)依序套用:header 名單、key 名單(query 與 body)、已知媒體 CDN 的簽名參數去除、 + 已知憑證值逐字替換(帳號層登記目前各音源的實際憑證值,Finamp 的做法)。套用在訊息、error 字串、stackTrace、結構化欄位。 + 名單集中一處,音源插件可追加自己的名單。 +4. **網路紀錄**:自己的 dio 攔截器,每個請求一筆摘要(方法、主機、路徑、遮過的 query、狀態、耗時、大小、音源、錯誤類型), + 經門面寫入;不記 body。 +5. **錯誤歷史**:統一錯誤型別被處理時一律經門面以 `warning`/`error` 寫入,帶錯誤類型、音源、對應網路紀錄等欄位; + Debug 頁篩選即為錯誤歷史,跨重啟由 log 檔提供。 +6. **診斷包**:參考 NewPipe,一組欄位產生純文字與 JSON;內容為版本、平台、語系、各音源啟用與登入狀態(是/否)、 + 非敏感設定摘要、已遮蔽的 log 與錯誤歷史;不含硬體識別資訊、帳號名稱、歌單內容。產生時組裝一次,匯出只用這份結果。 +7. **設定**:依功能分組(播放、外觀、音樂庫與同步、下載、歌詞、網路、桌面、開發者),每組一張單列表、每個設定一個有型別的欄位, + 每組一個 Riverpod Notifier 監看自己那一列、只寫改動的欄位。**欄位為空=使用者沒設定過**,讀取時套用程式預設; + 改預設值不需 migration,也不會動到使用者設定過的值。每個音源的設定另一張表,以音源 id 為主鍵。設定包含在備份中。 + +採用的慣例:talker 作資料核心;Finamp `censored_log.dart` 的已知值替換;NewPipe 錯誤報告的欄位結構; +Spotube 以 drift 存設定並以 `watchSingle()` 接 Riverpod。 + +## 後果 + +- 好的:任何出口都不會漏出未遮蔽的內容;錯誤可依類型與音源追查;設定的預設值可以安全調整;新增音源不必改設定 schema。 +- 壞的:Debug 頁的 log 檢視要自己做;遮蔽名單要隨音源維護;release 版在本機留有 info 級別的使用紀錄(已遮蔽、不上傳)。 +- 之後要注意:統一錯誤型別的欄位由錯誤模型的 ADR 定;Debug 頁與開發者模式的持久化由 Debug 頁的設計定;各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案。 + +## 如何確認 + +- lint:門面以外禁止 `print`、`debugPrint`、`developer.log`、import talker(測試策略 ADR 落實)。 +- 遮蔽測試:每個音源一組假憑證與假簽名 URL,斷言經 log 檔、記憶體歷史、診斷包、網路紀錄後都不再出現原值,包括出現在 stackTrace 的情況。 +- 設定測試:寫入使用者值後改變程式預設,斷言讀到的仍是使用者值;未設定的欄位讀到新預設。 From 25f0952dc0929c886006dcfabdcef4e8cc36ebc9 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 11:09:57 +0800 Subject: [PATCH 021/133] chore(task): archive design-settings-logging --- .../2026-09}/09-27-design-settings-logging/check.jsonl | 0 .../2026-09}/09-27-design-settings-logging/design.md | 0 .../2026-09}/09-27-design-settings-logging/implement.jsonl | 0 .../2026-09}/09-27-design-settings-logging/implement.md | 0 .../2026-09}/09-27-design-settings-logging/prd.md | 0 .../research/diagnostics-and-settings.md | 0 .../research/logging-and-redaction.md | 0 .../2026-09}/09-27-design-settings-logging/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/research/diagnostics-and-settings.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/research/logging-and-redaction.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-settings-logging/task.json (92%) diff --git a/.trellis/tasks/09-27-design-settings-logging/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/check.jsonl diff --git a/.trellis/tasks/09-27-design-settings-logging/design.md b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/design.md similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/design.md diff --git a/.trellis/tasks/09-27-design-settings-logging/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/implement.jsonl diff --git a/.trellis/tasks/09-27-design-settings-logging/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/implement.md diff --git a/.trellis/tasks/09-27-design-settings-logging/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/prd.md diff --git a/.trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/research/diagnostics-and-settings.md similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/research/diagnostics-and-settings.md rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/research/diagnostics-and-settings.md diff --git a/.trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/research/logging-and-redaction.md similarity index 100% rename from .trellis/tasks/09-27-design-settings-logging/research/logging-and-redaction.md rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/research/logging-and-redaction.md diff --git a/.trellis/tasks/09-27-design-settings-logging/task.json b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/task.json similarity index 92% rename from .trellis/tasks/09-27-design-settings-logging/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-settings-logging/task.json index 621894067..b6b82c6f8 100644 --- a/.trellis/tasks/09-27-design-settings-logging/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-settings-logging/task.json @@ -3,7 +3,7 @@ "name": "design-settings-logging", "title": "Design: settings and logging infrastructure", "description": "Phase-2 item 18: settings grouping and storage, log levels, outputs, rotation and retention, and the single redaction function shared by logs, Debug page, diagnostics and toasts", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From 494dfe719b19424b177c0014e98e7ca4305378ed Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 11:56:08 +0800 Subject: [PATCH 022/133] chore(task): plan phase-two item 12 (network layer and accounts) --- .../09-27-design-network-accounts/check.jsonl | 0 .../09-27-design-network-accounts/design.md | 98 +++++ .../implement.jsonl | 0 .../implement.md | 9 + .../09-27-design-network-accounts/prd.md | 50 +++ .../research/credentials-and-http.md | 286 ++++++++++++++ .../research/login-methods.md | 370 ++++++++++++++++++ .../09-27-design-network-accounts/task.json | 26 ++ 8 files changed, 839 insertions(+) create mode 100644 .trellis/tasks/09-27-design-network-accounts/check.jsonl create mode 100644 .trellis/tasks/09-27-design-network-accounts/design.md create mode 100644 .trellis/tasks/09-27-design-network-accounts/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-network-accounts/implement.md create mode 100644 .trellis/tasks/09-27-design-network-accounts/prd.md create mode 100644 .trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md create mode 100644 .trellis/tasks/09-27-design-network-accounts/research/login-methods.md create mode 100644 .trellis/tasks/09-27-design-network-accounts/task.json diff --git a/.trellis/tasks/09-27-design-network-accounts/check.jsonl b/.trellis/tasks/09-27-design-network-accounts/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-network-accounts/design.md b/.trellis/tasks/09-27-design-network-accounts/design.md new file mode 100644 index 000000000..70551b1b5 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/design.md @@ -0,0 +1,98 @@ +# 設計:網路層與帳號 + +採用的慣例:dio 官方 `QueuedInterceptor` 做單飛刷新;`cookie_jar`+`dio_cookie_manager` 管 cookie; +PiliPlus 以 QR 為主的 B 站登入;ytmusicapi 的「瀏覽器登入後貼上 cookie」;Finamp 的已知值遮蔽(ADR 0011)。 + +## 1. HTTP 層 + +```mermaid +flowchart LR + subgraph 音源插件 + REQ[請求定義
    帶 AuthRequirement] + end + subgraph 每個音源一個 API client + I1[認證攔截器
    依 AuthRequirement 注入] + I2[cookie 管理] + I3[錯誤對應
    回應→統一錯誤型別] + I4[限流與退避
    依音源宣告的策略] + I5[網路紀錄
    ADR 0011] + end + subgraph 媒體 client + M[只加媒體 headers
    Referer / UA
    不掛任何認證] + end + REQ --> I1 --> I2 --> I3 --> I4 --> I5 --> NET[(音源 API)] + PLAY[播放/下載的位元組請求] --> M --> CDN[(CDN)] +``` + +- **每個音源一個 API client**(dio 實例),該音源所有 service 共用;另有一個**媒體 client** 專門抓音訊位元組,它沒有認證攔截器、沒有 cookie 管理,物理上帶不了憑證。 +- 攔截器順序:認證注入 → cookie 管理 → 錯誤對應(第 2 項)→ 限流與退避(策略由音源宣告,第 2 項定細節)→ 網路紀錄(ADR 0011)。 +- 匿名用的 cookie(例如 B 站 `buvid`)屬於非機密,存在資料庫;登入憑證只在憑證存放處(§3)。 + +## 2. 哪些請求帶憑證:單一宣告點 + +每個請求在音源插件定義處宣告 `AuthRequirement`(放在 dio `RequestOptions.extra`),認證攔截器只看這個標記: + +| 標記 | 意思 | 用在 | +|---|---|---| +| `required` | 一定帶;沒登入就不發請求,直接回「需要登入」 | 寫入遠端歌單、讀收藏夾與私人歌單 | +| `userPreference` | 已登入且該音源的「以登入身分瀏覽與播放」開啟時才帶 | 搜尋、排行、詳情、串流解析、下載詳情、歌單刷新、電台、Mix | +| `never`(預設) | 永遠不帶 | 公開頁面抓取(Spotify embed、QQ 公開歌單)、第三方歌詞源 | + +媒體位元組請求不經 API client,由 §1 的媒體 client 發出,所以不在這張表裡。 +網路紀錄記錄每個請求「有沒有帶憑證」(是/否),Debug 頁可查。 + +## 3. 憑證存放與帳號狀態 + +- **唯一來源**:`CredentialStore`(`flutter_secure_storage` 11.x),以音源 id 為鍵。登入狀態由它推導,不再另存一份。 + 帳號的非機密資訊(顯示名稱、頭像網址、最後刷新時間與結果)存在資料庫,只供顯示。 +- **讀不到不刪**:secure storage 暫時讀不到(例如 Keystore 未就緒)時,帳號狀態為「暫時無法讀取」,稍後重試,不刪除、不提示失效(M8)。 +- **遮蔽登記**:每次載入或更新憑證,把實際值登記到遮蔽函式(ADR 0011)。 +- **Linux**:需要 libsecret 與執行中的 keyring;沒有 keyring 時的行為在 Linux child task 實測後定。 +- 舊版憑證由 legacy import 以 10.x 讀出後寫入(ADR 0010)。 + +## 4. 登入是音源能力 + +音源插件宣告它支援的登入方式,UI 取「音源支援 ∩ 平台有能力(ADR 0009)」顯示入口: + +| 方式 | 說明 | B 站 | YouTube | 網易 | +|---|---|---|---|---| +| QR 掃碼 | App 顯示 QR,手機 App 掃碼確認 | ✅ 主要 | — | ✅ 主要 | +| App 內網頁登入 | WebView 開登入頁,完成後讀 cookie | ✅ | ✅ 主要(桌面 UA) | ✅(有 WebView 的平台) | +| 貼上 cookie | 在自己的瀏覽器登入後,把 cookie 貼進 App(附步驟說明) | ✅ | ✅ 備案 | ✅ | + +- **登入成功的定義**:拿到憑證後,先呼叫該音源的帳號資訊 API 驗證有效,**驗證通過才寫入** `CredentialStore`(修正 C3 的假成功)。 +- 沒有 WebView 的平台(例如 Linux):B 站與網易用 QR,YouTube 用貼上 cookie;是否引入 `webview_cef` 在 Linux child task 決定。 + +## 5. 刷新、失效與重新登入 + +```mermaid +stateDiagram-v2 + [*] --> 未登入 + 未登入 --> 已登入: 登入並驗證通過 + 已登入 --> 刷新中: 音源判定需要刷新(例如 B 站 cookie/info) + 刷新中 --> 已登入: 刷新成功,寫回憑證 + 刷新中 --> 已失效: 刷新失敗 + 已登入 --> 已失效: 帶憑證的請求被音源判定為憑證無效 + 已登入 --> 暫時無法讀取: secure storage 讀取失敗 + 暫時無法讀取 --> 已登入: 重試成功 + 已失效 --> 已登入: 重新登入 + 已登入 --> 未登入: 登出 + 已失效 --> 未登入: 登出 +``` + +- **刷新**:由音源宣告是否支援與時機(B 站:啟動時問伺服器是否需要刷新,B4 保留)。帳號頁顯示最後刷新時間與結果。 +- **請求中遇到憑證無效**:只有「帶了憑證」的請求才會觸發。`QueuedInterceptor` 單飛:若音源支援刷新,先刷新、**用新憑證重建請求**後重送一次(修正 C4);否則標記已失效。 +- **判定憑證無效由音源負責**:每個音源明確列出哪些回應代表憑證無效;網路錯誤、限流、風控碼一律不算(修正 C5)。偵測在所有帶憑證的請求上都有效,不限帳號頁(修正 C6)。 +- **已失效時**:保留憑證(可能只是暫時),停止帶它;提示一次 toast,帳號頁與相關入口顯示「需要重新登入」;重新登入後,下一次失效會再次提示(修正 M9)。 +- **登出**:清除該音源的憑證、該音源網域的 WebView cookie、記憶體中的 cookie、遮蔽登記。 +- **重設所有資料**:清資料庫、所有憑證、所有 WebView 資料(修正 C1)。 + +## 6. 「以登入身分瀏覽與播放」 + +- 每個音源一個開關(存在每音源設定表,ADR 0011),語意一致:控制該音源所有 `userPreference` 請求。 +- 預設值由音源宣告:B 站、網易、YouTube 皆為開。YouTube 的開關旁附說明:以登入身分大量請求,可能被 Google 視為自動化行為(推測,研究未證實)。 +- legacy import 以舊值作為使用者設定(舊版開關範圍較窄,新版範圍變廣;切換版本的發行說明寫明)。 + +## 7. 只能匯入的來源 + +Spotify(embed 頁)與 QQ(公開歌單)不需登入,`AuthRequirement.never`。抓頁面的做法可能隨對方改版失效,由第 1 項的音源健康檢查涵蓋。 diff --git a/.trellis/tasks/09-27-design-network-accounts/implement.jsonl b/.trellis/tasks/09-27-design-network-accounts/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-network-accounts/implement.md b/.trellis/tasks/09-27-design-network-accounts/implement.md new file mode 100644 index 000000000..a230e50b8 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/implement.md @@ -0,0 +1,9 @@ +# 執行計畫 + +本任務只產出設計與 ADR;程式在里程碑中實作。 + +- [ ] 寫 `docs/adr/0012-network-layer-and-accounts.md`:design.md §1–§7;被否決的選項(每個 service 各自一個 dio、手動拼 Cookie header、在各 service 決定帶不帶憑證、TV 裝置碼 OAuth、只用貼上 cookie、刷新後用舊 options 重送、非 200 即清憑證、UI 與請求各讀一份登入狀態);「如何確認」(媒體請求不帶 cookie 的契約測試、刷新後重送帶新憑證的測試、每音源「憑證無效」判定表的測試、登出與重設清憑證的測試)。併入 `CONTEXT.md` 的原則(媒體請求不帶憑證、解析串流才用憑證)。 +- [ ] `phase2-plan.md` 標記第 12 項完成;記下「YouTube WebView 登入是否可用」為加入 YouTube 登入的里程碑先實測項目。 +- [ ] 歸檔本任務。 + +驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-network-accounts/prd.md b/.trellis/tasks/09-27-design-network-accounts/prd.md new file mode 100644 index 000000000..af7ddb2d1 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/prd.md @@ -0,0 +1,50 @@ +# 設計第 12 項:網路層與帳號 + +## 目標 + +設計新 App 的 HTTP 層、憑證存放與刷新、「哪些請求帶憑證」的單一宣告點、「用登入狀態」開關的統一語意, +以及登入作為音源能力的形狀(UI 依音源宣告自適應)。 + +需求來源:parent `prd.md` 階段二第 2、12 項;`questions.md` M1–M13(使用者:各音源邏輯統一、開關語意一致且可能涵蓋排行、登入由音源提供、介面自適應)、C1、C3、C4、C5、C6(重寫時修正)、B4、B14;ADR 0009(登入 WebView 平台差異)、0010(legacy import)、0011(遮蔽與網路紀錄)。 + +## 現況(證據) + +- UI 顯示的登入狀態讀 Isar `Account`,實際送請求只看 secure storage(`docs/audit/accounts-network.md` §6.1)。 +- 請求 × 音源憑證矩陣:開關只影響部分請求;YouTube 的「用登入狀態」只是匿名失敗後的備援;YouTube/網易排行永遠不帶登入(`accounts-network.md` §7)。 +- 缺陷:重設資料不清憑證(C1)、B 站 QR 假成功(C3)、B 站刷新後重送帶舊 cookie(C4)、網易非 200 即清憑證(C5)、播放連線偵測不到失效(C6)、secure storage 暫時讀不到就刪憑證(M8)、失效提示每次執行只跳一次(M9)。 +- 登入方式:B 站 WebView+QR;YouTube 只有 WebView(桌面 Chrome UA 開 `accounts.google.com/ServiceLogin`,登入後讀 cookie,`lib/ui/pages/settings/youtube_login_page.dart:60,329-337`);網易 Android WebView+QR、Windows 只有 QR。 +- Spotify 匯入抓公開 embed 頁(`lib/data/sources/playlist_import/spotify_playlist_source.dart:55-58`),不需登入。 + +## 研究結論(`research/login-methods.md`、`research/credentials-and-http.md`) + +- B 站:成熟客戶端(PiliPlus)以 QR 為主;WBI 與 App 簽名兩套;cookie 刷新流程的社群文件已因存證信函下架,需以實作驗證。 +- 網易:QR 或手機驗證碼;社群 API 專案同樣已封存。 +- YouTube:Google 封鎖內嵌 WebView 做 **OAuth**(`disallowed_useragent`)。可行替代:系統瀏覽器登入後貼上 cookie/headers(ytmusicapi 官方方式之一,憑證約兩年有效);TV 裝置碼 OAuth 需自備 Google Cloud 憑證。 + **不一致**:研究以 OAuth 政策推論 WebView 不可用,但舊 App 走的是 `ServiceLogin` 網頁登入加桌面 UA,不是 OAuth;實際是否可用程式碼無法判斷。 +- Spotify:**不一致**:研究以 Web API 推論匯入需登入,舊 App 用的是 embed 頁,不受影響(但抓頁面本身可能隨時失效)。 +- 憑證:`flutter_secure_storage` 11.2.0,五平台;新 App 寫的是新資料,可直接用 11.x;legacy import 維持 10.x 唯讀(ADR 0010)。Linux 需要 libsecret 與執行中的 keyring,沒有 keyring 時的行為查不到。 +- HTTP:每個音源一個共用 dio 實例;`cookie_jar`+`dio_cookie_manager` 管 cookie;刷新後重送用 `QueuedInterceptor` 並以新憑證重建請求;`dio_smart_retry` 兩年未更新,只適合網路層重試,音源錯誤碼的退避自寫。 +- 宣告帶憑證:以請求層標記(`RequestOptions.extra` 帶 `AuthRequirement`:必須/可選/禁止,預設禁止);媒體位元組請求走另一個不掛認證攔截器的 dio。 + +## 已決定 + +- D1(使用者 2026-09-27):YouTube 登入以 App 內 WebView(桌面 UA 開網頁登入、讀 cookie)為主,另提供「從瀏覽器貼上 cookie」作為備案(被 Google 擋或平台沒有合適 WebView,例如 Linux)。不做 TV 裝置碼 OAuth。舊版 WebView 登入目前是否可用未知,列為第一個加入 YouTube 登入的里程碑先實測的項目。 + +- D2(使用者 2026-09-27):開關改為「以登入身分瀏覽與播放」,每音源一個、語意一致,涵蓋該音源所有讀取請求(搜尋、排行、詳情、串流解析、下載詳情、歌單刷新、電台、Mix);寫入與私人資料一律需登入;媒體位元組請求一律不帶。預設 B 站、網易、YouTube 皆開,YouTube 附帳號風險說明。 +- 其餘依研究與使用者方向寫入 design.md。 + +## 需求 + +- R1 每音源一個 API client;媒體位元組請求走獨立的媒體 client,不掛認證。 +- R2 每個請求在音源插件宣告 `AuthRequirement`(required/userPreference/never,預設 never),認證攔截器只依此注入。 +- R3 憑證只存一處(`CredentialStore`),登入狀態由它推導;讀不到不刪。 +- R4 登入方式由音源宣告,UI 取音源與平台能力交集;登入成功須先驗證憑證有效。 +- R5 憑證無效由音源明確判定,限流/網路/風控不算;刷新後以新憑證重建請求重送;失效時保留憑證、提示、可重新登入且下次失效會再提示。 +- R6 登出清該音源憑證與 WebView cookie;重設資料清全部。 +- 修正:C1、C3、C4、C5、C6、M1、M5、M6、M7、M8、M9、M12(M12:歌單刷新依開關,不再被重新匯入覆寫)。 + +## 驗收標準 + +- [ ] design.md 涵蓋 HTTP 層、帶憑證宣告、憑證存放與狀態、登入方式、刷新與失效、開關語意、只匯入的來源。 +- [ ] `docs/adr/0012-*.md` 依範本寫成。 +- [ ] `phase2-plan.md` 標記第 12 項完成並記下 YouTube WebView 實測項目。 diff --git a/.trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md b/.trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md new file mode 100644 index 000000000..a3c6a1136 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md @@ -0,0 +1,286 @@ +# 研究:憑證儲存與 HTTP 層 + +對應項目 2、3、4。查不到的地方寫「查不到」,超出已驗證證據的推論標「推測」。 + +## 1. 憑證儲存:`flutter_secure_storage` + +### 1.1 版本與五平台後端 + +pub.dev():最新版 **11.2.0**,發布於 +2026-09-16。score()滿分 160/160、4,490 個 +like、近 30 天下載 454.9 萬次——目前 Flutter 生態圈事實標準的安全儲存套件,沒有理由不選它。 + +自 10.x 起是聯邦式套件(federated plugin),核心套件 `flutter_secure_storage` 只定義介面,各平台後端各自 +一個套件,`pubspec.yaml` 的 `dependencies` 已列出對照關係: + +| 平台 | 後端套件 | 底層機制 | +|---|---|---| +| Android | 內建於核心套件(`com.it_nomads.fluttersecurestorage`) | Android Keystore 包一層自家 cipher,寫入 SharedPreferences | +| iOS / macOS | `flutter_secure_storage_darwin` ^0.4.0 | Keychain | +| Windows | `flutter_secure_storage_windows` ^4.2.2 | DPAPI(`CryptProtectData`,官方 README 用詞) | +| Linux | `flutter_secure_storage_linux` >=3.0.1 <5.0.0 | `libsecret`,需要一個執行中的 keyring service | +| Web | `flutter_secure_storage_web` ^2.1.1 | 瀏覽器儲存(非本專案關注範圍) | + +### 1.2 11.x 的破壞性改動(讀官方 CHANGELOG 逐條確認) + +CHANGELOG: +(官方倉庫現況:`repository` 欄位在 pubspec 寫的是 `mogol/flutter_secure_storage`,但目前實際维護者/組織是 +`juliansteenbakker`,兩個帳號指向同一個專案歷史,`CHANGELOG.md` 內容與 pub.dev 發布記錄一致,可信)。 + +**11.0.0**(2026-08-06)明確標「Breaking changes」,重點摘錄(原文英文,以下為理解整理): + +- 移除 v10 就已標記 deprecated 的項目:**若資料是用 v10 之前的舊版寫入、且從未升級過 v10,直接跳到 v11 + 會讀不出來**(CHANGELOG 原文:"If you used a version prior to v10, upgrade to v10 first so existing data + is migrated.")——這是唯一一條會導致資料真的遺失的規則。 +- Android:移除 `KeyCipherAlgorithm.RSA_ECB_PKCS1Padding`、`StorageCipherAlgorithm.AES_CBC_PKCS7Padding` + 這兩個舊版加密方案;移除 `AndroidOptions.encryptedSharedPreferences` 參數(Jetpack Security 後端整個不再 + 支援,資料在 v10 已自動搬到自家 cipher);移除 `AndroidOptions.sharedPreferencesName`(改用 + `storageNamespace`)。 +- Android `minSdk` 提高到 24、`compileSdk` 提高到 37;理由是 Flutter 3.35 本身已把最低 Android API 拉到 + 24,導致 API 23 的支援路徑事實上沒人能再驗證,連帶砍掉支援 API 21-22 的舊 AES-CBC cipher 路徑。 +- 11.1.0(2026-09-10)新增 `checkUpgradeStatus()`,可以在執行期主動查詢「這次啟動是不是直接從 v10 之前 + 跳過來、資料可能已經遺失」;11.2.0(2026-09-16)修掉一批 Android 端的 biometric/多執行緒相關 bug。 + +**對 FMP 的實際影響(結合 ADR 0010 已定案的架構)**: + +- ADR 0010 已經把 `flutter_secure_storage` 10.x 隔離在 `app/lib/legacy_import/`,只用來**唯讀**讀取舊 App + 寫入的憑證(舊 App 本身用的正是 10.x)。10.x 本身不受 11.x 這些破壞性改動影響,維持現狀即可。 +- 新 App(`app/` 主體)要寫入的是**全新的憑證資料**(重新登入或匯入後轉存),不存在「舊版 v10 之前資料 + 沒升級就跳 v11」的情境,因此**新 App 直接使用 11.2.0(目前最新穩定版)沒有升級路徑風險**,符合使用者 + 規則「依賴裝當前 stable」。这一點回答了 ADR 0010 §後果留下的「`flutter_secure_storage` 升到 11.x 的條件 + 在網路與帳號的 ADR 決定」:條件已經滿足(新 App 的資料本來就是全新寫入,沒有舊資料可言),可以直接採用 + 11.x,不需要额外的相容層。 + +### 1.3 Linux:libsecret/keyring 需求與無 keyring 時的行為 + +`flutter_secure_storage_linux` 官方 README +(, +已完整讀取): + +- 建置需要 `libsecret-1-dev`,執行需要 `libsecret-1-0`(多數 Linux 桌面環境預裝)。 +- **執行期還需要一個「正在運行的 keyring service」**:GNOME/Ubuntu 靠 `gnome-keyring`(GNOME session 預設 + 啟動)、KDE 靠 `kwallet`、其他輕量桌面環境靠 `secret-service`。 +- README 明確把「Headless / CI」列成需要額外處理的情境,提供的解法是手動啟動並解鎖一個 + `gnome-keyring-daemon`: + ```bash + eval $(dbus-launch --sh-syntax) + echo "" | gnome-keyring-daemon --unlock --daemonize --components=secrets + ``` + 這代表官方文件本身承認「沒有桌面 session、沒有人手動解鎖 keyring」的環境下這個套件**預期無法直接運作**, + 需要額外啟動步驟。README **沒有明說**一般桌面環境下 keyring 被鎖住或不存在時 API 呼叫會拋什麼例外、還是 + 靜默失敗——**這點查不到**,需要在 Linux child task 的 POC 階段實測(例如全新安裝、未曾設定過密碼鑰匙圈 + 的 Ubuntu minimal、或使用者手動殺掉 `gnome-keyring-daemon` 後)才能確認失敗模式。 +- 已知建置問題:透過 snap 安裝的 Flutter 在 Ubuntu 22.04+ 上,因為 snap 內建的 GLib 版本與系統 + `libsecret` 編譯時的 GLib 版本不一致,會出現連結器錯誦(`undefined reference to + 'g_task_set_static_name'` 等),官方建議改用官方 tar 版 Flutter 而非 snap 版。這點值得記進 Linux child + task 的建置文件,避免踩坑後才發現。 + +### 1.4 有沒有更好的替代方案 + +沒有找到明顯更好的替代——`flutter_secure_storage` 是 Flutter 生態圈裡分數、下載量、平台覆蓋度都最高的 +選項,且 ADR 0010 已經因為「新舊憑證都要能讀」而選定它作為新舊兩端共用的技術路線(差在版本號)。查證過程 +沒有刻意再找第二個候選方案,因為使用者規則「通用功能的順序:專案已有依賴→成熟且持續維護的套件→自己寫」 +——本專案已經在用這個套件,且它本身仍然活躍維護(近一個月內三次發版),沒有理由切換。 + +## 2. HTTP 層:`dio` 與周邊套件 + +### 2.1 版本與周邊套件現況 + +| 套件 | 最新版 | 發布日期 | 用途 | +|---|---|---|---| +| `dio` | 5.11.1 | 2026-09-04 | HTTP client 本體 | +| `cookie_jar` | 4.0.9 | 2026-02-27 | Cookie 儲存與比對邏輯(RFC 6265) | +| `dio_cookie_manager` | 3.5.0 | 2026-07-25 | 把 `cookie_jar` 接成 dio 的 Interceptor | +| `dio_smart_retry` | 7.0.1 | **2024-10-22** | 逾時/特定狀態碼自動重試 | + +(均來自 `curl https://pub.dev/api/packages/` 直接讀取的 `latest` 欄位。) + +**`dio_smart_retry` 已將近兩年沒有新版**(上次發版 2024-10-22,距今近 23 個月),score +()145/160、313 個 like,仍能通過 pub.dev 的相容性 +分析,但不算「持續維護中」的專案;若採用,建議把它定位成「單純的逾時/連線層退避重試」(它的訴求本來就是 +HTTP 層級的重試,不涉及認證邏輯),不要把認證刷新的邏輯也塞進去,降低對這個套件維護狀態的依賴程度。 +`cookie_jar`/`dio_cookie_manager` 都是 `cfug`(dio 官方 GitHub 組織)自己維護的子套件,跟 dio 本體版本 +同步發布,可信賴度高於 `dio_smart_retry`。 + +### 2.2 per-source client v.s. 共用 client + +`docs/audit/accounts-network.md` §2(已讀)記錄了舊專案的現狀:**沒有共用 Dio**,每個音源、甚至同一個音源 +內的不同 service(帳號 service、收藏夾 service、播放 adapter)都各自 new 一個 Dio 實例;全 `lib/` 只有 +三處 `interceptors.add`,且全部是認證攔截器,**沒有** `LogInterceptor`、重試攔截器、快取攔截器,也沒有 +`CookieJar`(accounts-network.md:139)。這造成的實際後果(accounts-network.md:249-253 表格):認證攔截器 +只掛在「歌單/收藏夾服務」的 Dio 上,播放/搜尋用的 adapter Dio 完全沒有攔截器,導致播放期偵測不到登入失效 +(errors.md:336)。 + +**建議**:**per-source 一個 Dio 實例**(Bilibili 一個、YouTube 一個、網易一個),而不是 per-service 或全域 +共用一個: + +- 三個音源的 base header、簽名邏輯、cookie 網域完全不同,共用一個全域 Dio 反而要在攔截器裡用 if-else 分流, + 違反「單一音源的邏輯別外洩到別的音源」的分層目標。 +- 但**同一個音源內部**的所有 service(帳號檢查、收藏夾、播放 adapter、下載)必須共用同一個 Dio 實例, + 這樣認證攔截器只要掛一次,就能涵蓋該音源的所有請求類型——直接修正 accounts-network.md 記錄的「攔截器 + 只掛在部分 service」這個根因(不是攔截器邏輯寫錯,是掛的位置從一開始就不夠廣)。 +- CDN/媒體位元組請求(見 §3.2)不套用該音源的認證攔截器,理由見下方。 + +### 2.3 Cookie 管理:`cookie_jar`/`dio_cookie_manager` v.s. 手動組 header + +舊專案是手動把 cookie 字串塞進 `options.headers['Cookie']`(`bilibili_auth_interceptor.dart:28-33`,見 +§2.4 完整分析)。`dio_cookie_manager` 官方定位(pub.dev description)是「結合 `cookie_jar` 與 dio 的攔截器」 +——好處是能自動處理 `Set-Cookie` 回應、cookie 的網域/路徑/過期比對都交給 `cookie_jar`(實作 RFC 6265) +處理,不必自己維護字串拼接邏輯。 + +**建議採用 `PersistCookieJar`(`cookie_jar` 提供,可持久化到磁碟)+ `CookieManager`(`dio_cookie_manager`) +掛在每個音源自己的 Dio 上**,取代手動字串拼接,原因: + +1. 手動拼接容易漏掉 cookie 屬性比對(過期時間、路徑),也是舊 bug 的根源之一(見 §2.4:`onRequest` 寫死 + 的 cookie 字串在刷新後不會自動更新,因為它根本不是從一個「活的」cookie store 讀出來的)。 +2. `PersistCookieJar` 本身處理持久化,可以取代「憑證存進 secure storage 之後,还要手動同步回 Dio」这一步 + ——改成「認證用的長效憑證(SESSDATA、MUSIC_U 等)存 secure storage 做單一事實來源;請求時的 cookie 由 + `CookieJar` 管理,登入/刷新成功後只需要呼叫 `cookieJar.saveFromResponse()` 或直接建構 `Cookie` 物件寫入, + 不需要自己在每個攔截器裡手動組字串」。 + +需要注意:`cookie_jar`/`dio_cookie_manager` 本身不做「認證」判斷(不知道什麼是登入失效),仍然需要一個 +自訂的認證攔截器疊在它上面做「偵測 -101/301/401 之類的業務碼、觸發刷新」——兩者是互補而非取代關係。 + +### 2.4 重試模式:官方 `QueuedInterceptor` 範例 v.s. FMP 舊 bug 的直接對比 + +**dio 官方文件對「認證刷新後重試」給出了明確的建議模式**,範例檔案: + +(透過 context7 `/cfug/dio` 確認此為官方 README 引用的範例;已直接讀取完整原始碼)。關鍵設計,逐條對照 +FMP 舊程式碼(`lib/services/account/bilibili_auth_interceptor.dart`,本次研究已完整讀取,行號依現況檔案): + +| 面向 | dio 官方範例的做法 | FMP 舊 `BilibiliAuthInterceptor` 的做法 | 問題 | +|---|---|---|---| +| 攔截器基底類別 | `QueuedInterceptorsWrapper`——dio 內建、專門解決「多個並發請求同時觸發刷新」的攔截器基底,會自動把並發請求排隊 | 普通 `Interceptor` + 自己手寫一個 `Completer` 去重(`_ensureRefreshed()`,第 92-114 行) | FMP 的手寫版本邏輯本身沒有明顯錯誤(`Completer` 去重是正確技巧),但重新造了 dio 已經內建的輪子,且只去重「刷新動作」,沒有去重「等待刷新完成前的請求排隊順序」,維護成本比直接用 `QueuedInterceptor` 高 | +| 刷新成功後怎麼重試 | **明確地在重試前重寫 `requestOptions.headers`**:`dio.fetch(error.requestOptions..headers = {'Authorization': 'Bearer ${tokenManager.accessToken}'})`——用**當下最新**的 token 覆寫 headers,再送出同一個 `RequestOptions` 物件 | `_accountService.dio.fetch(requestOptions)`(第 77 行)——**直接重送同一個 `RequestOptions` 物件,不重寫任何欄位** | **這就是 accounts-network.md:128 已記錄的真實 bug**:舊 cookie 是在 `onRequest`(第 28-34 行)處理**送出前**的階段被寫進 `options.headers['Cookie']` 的;重試呼叫的 `_accountService.dio`(帳號服務自己的 Dio)**沒有掛這個攔截器**(`bilibili_account_service.dart:83` 沒有 `interceptors.add`),所以重試**不會重新跑一次 `onRequest`**,那個 `RequestOptions` 物件裡凍結的還是**刷新前**的舊 Cookie 字串。`refreshCredentials()` 只更新了 secure storage 與記憶體快取(`:425-429`),**不會回頭修改已經建構好的 `RequestOptions`**。結果:換了新 cookie,但重試送出的還是舊的,大機率再收到一次 -101,被誤判成「刷新也救不回來」而標記帳號失效(`markSessionExpired()`)——使用者其實已經登入成功,卻被系統判定成需要重新登入 | +| 併發保護測到什麼程度 | 用「當時請求帶的 token」跟「目前 token」比對,只有兩者相同時才觸發刷新,避免同一批並發請求觸發多次刷新 | 同上,`Completer` 機制本身能達到類似效果 | 這部分 FMP 的手寫邏輯是對的,不是 bug 來源 | + +**結論與建議**: + +1. 新專案的認證攔截器一律繼承 `QueuedInterceptor`(或用 `QueuedInterceptorsWrapper`),不要再手寫 + `Completer` 去重——這是 dio 官方為同一個問題提供的內建解法,語意更清楚、更不容易在維護時漏掉邊界情況。 +2. **重試前必須用最新憑證重新建構請求**,不能直接 `dio.fetch(requestOptions)` 重送凍結的舊物件。具體做法: + 用 `requestOptions.copyWith(headers: {...最新 cookie...})` 或直接修改 `requestOptions.headers` 後再 + `fetch`,並且要用**掛了同一個攔截器鏈的 Dio 實例**去發這個重試請求(不要像 FMP 舊碼一樣切去另一個沒掛 + 攔截器的 Dio),否則同樣的「憑證沒跟著更新」問題還會用不同形式重現。 +3. 这也回頭印證 §2.2 的建議:認證攔截器必須掛在該音源**唯一**的共用 Dio 上,而不是像舊專案一樣只掛在部分 + service 的 Dio——如果重試要呼叫「同一個掛了攔截器的 Dio」,前提就是這個 Dio 真的涵蓋所有需要認證的 + 請求,不能分裂成多個實例。 + +### 2.5 速率限制/退避 + +舊專案的限流退避邏輯分散在多處、各自硬編碼重試次數與秒數(`docs/audit/errors.md` §3.2 已整理:串流解析 +1 次/3 秒、排行榜 4 次/5 秒-30 秒-2 分-10 分、播放漸進重試 1-2-4-8-16 秒、電台重連 1-3-10 秒),且播放層 +「不退避、不跳過」限流錯誤(`errors.md:227`)。 + +本次查證沒有找到 pub.dev 上專門做「HTTP 429/backoff」且比自己寫更有優勢的成熟套件(`dio_smart_retry` 本身 +支援按狀態碼、按次數退避,但如 §2.1 所述已近兩年未更新,且它的退避策略是通用 HTTP 語意,不理解「Bilibili +的 -352 風控碼」這種業務層限流)。**建議**:業務層的限流(各音源自訂的錯誤碼)用一個共用的、可設定重試 +次數/退避序列的小型 helper 自行實作(不依賴 `dio_smart_retry`),統一放在音源共用的錯誤處理層,取代舊 +專案「數字硬編碼在四五個不同檔案」的狀況;純 HTTP 層級的逾時重試(連線失敗、5xx)可以視情況疊加 +`dio_smart_retry`,但不要用它處理業務碼判斷。 + +## 3. 憑證宣告 Pattern:哪些請求該帶認證,CDN 位元組請求絕對不該帶 + +### 3.1 官方支援的欄位:`RequestOptions.extra` + +透過 context7 查證 dio 官方 README(`/cfug/dio`)確認 `RequestOptions`/`Options` 類別本身就有一個官方 +支援、專門給呼叫端附加自訂中繼資料的欄位: + +> `Map? extra` — "Custom field that you can retrieve it later in `Interceptor`, +> `Transformer` and the `Response.requestOptions` object." + +這代表「用一個型別化標記,宣告這個請求需不需要帶認證」不需要發明新機制,dio 本身就設計了這個切入點, +攔截器可以在 `onRequest` 裡讀 `options.extra` 來決定要不要注入認證資訊。 + +### 3.2 設計提案(本次研究基於上述官方欄位提出的建議,非既有套件或客戶端的既定作法,標記為「本任務原創 +設計提案」而非查證得到的既有慣例) + +```dart +/// 標記一個請求是否需要帶該音源的認證憑證。 +/// +/// 放進 [RequestOptions.extra],音源自己的認證攔截器讀這個值決定要不要注入 +/// Cookie/Authorization header;沒有這個標記的請求(含所有 CDN/媒體位元組 +/// 請求)一律視為 [AuthRequirement.never],避免把帳號憑證意外送到不該送的地方。 +enum AuthRequirement { + /// 一定要帶:例如收藏夾、帳號狀態查詢。認證攔截器缺憑證時直接失敗,不送出。 + required, + + /// 依使用者設定的「使用登入態」開關決定要不要帶:例如排行榜、串流解析、詳情。 + optional, + + /// 一定不能帶:所有 CDN/媒體位元組請求、不需要認證的公開 API。 + never, +} + +extension AuthRequirementExtra on RequestOptions { + AuthRequirement get authRequirement => + extra['authRequirement'] as AuthRequirement? ?? AuthRequirement.never; +} +``` + +呼叫端在建構請求時明確標註: + +```dart +dio.get( + '/x/v2/fav/video/favoured', + options: Options(extra: {'authRequirement': AuthRequirement.required}), +); +``` + +認證攔截器的 `onRequest` 邏輯變成: + +```dart +@override +void onRequest(RequestOptions options, RequestInterceptorHandler handler) { + switch (options.authRequirement) { + case AuthRequirement.never: + break; // 什麼都不做,確保絕不會不小心帶認證資訊 + case AuthRequirement.required: + // 缺憑證直接 reject,不送出 + case AuthRequirement.optional: + // 依 Settings.useAuthForPlay(sourceId) 決定要不要注入 + } + handler.next(options); +} +``` + +這個設計直接對應擁有者「使用登入態」開關必須語意一致、且可能要涵蓋所有讀取請求(含排行榜)的要求——因為 +**預設值是 `never`**(沒標註的請求視為不該帶認證),新增一個讀取端點時,工程師必須主動決定它是 +`required`/`optional`/`never` 三者之一才能編譯過(若把它做成一個必填的建構參數而非有預設值的具名參數) +,而不是像舊專案那樣「大部分請求根本沒有攔截器,帶不帶認證取決於這個 service 的 Dio 有沒有被加過攔截器」 +這種隱性、容易遺漏的狀態(accounts-network.md 記錄的排行榜、播放 adapter 沒有攔截器覆蓋正是這種遺漏)。 + +### 3.3 CDN/媒體位元組請求為什麼絕對不能帶認證 + +三個可播放音源的串流位元組本身都是從各自的 CDN 網域下載(Bilibili 的 `upos-*`/`cn-*` 系列 CDN 網域、 +YouTube 的 `*.googlevideo.com`、網易雲的 `music.126.net` 等——具體網域列表見 +`docs/audit/accounts-network.md` 已有的音源 API 網域整理,本次未重新枚舉),這些網域: + +1. **通常不需要認證**——串流 URL 本身已經帶簽名/過期時間(例如 Bilibili 的 `durl`/`dash` URL 帶 + `deadline`、`gorder` 等簽名參數,網易雲的 CDN URL 同樣帶簽名),認證是在**取得串流 URL 這一步**(API + 請求)做的,位元組下載這一步不需要、也不應該再帶帳號 cookie。 +2. **帶了反而是風險**:CDN 網域與 API 網域即使是同一間公司,也不代表用同一套 cookie 網域規則;把帳號 + cookie(SESSDATA 等長效憑證)打到 CDN 請求上,等於擴大這組憑證的曝光面(多一個會看到它的伺服器), + 且沒有任何已知功能需要這麼做。 +3. `AuthRequirement.never` 作為預設值,加上「音源的認證攔截器只掛在該音源的 API Dio 上、下載/播放的位元 + 組請求用**另一個完全沒掛認證攔截器的 Dio 實例**(甚至可以是同一個 dio 套件的裸實例,不套用任何音源 + 專屬設定)」——雙重保險:就算某個 CDN 請求不小心被標成需要認證,只要它是透過「位元組下載專用 Dio」 + 發出去的,攔截器根本不存在,物理上不可能被注入 cookie。 + +**建議**:位元組下載(串流播放的 range request、下載到本機檔案)統一走一個獨立的、跨音源共用的「媒體 +下載 Dio」,不繼承任何音源的認證攔截器;音源的 API Dio(帶認證攔截器)只負責「換取串流 URL」這一類 +metadata 請求,兩者職責與 Dio 實例層級都明確分開,不依賴「記得幫這個請求標 `never`」这種容易遺漏的人工 +規則作為唯一防線。 + +## 4. 需要 owner 決定的事項 + +1. **`AuthRequirement` 是本次研究提出的設計提案,不是抄某個現成套件或客戶端的既定做法**(dio 官方只提供 + `extra` 這個底層欄位,沒有定義任何「認證需求分級」的慣例)——需要 owner 確認這個三態設計( + `required`/`optional`/`never`)是否貼合「使用登入態」開關語意上要涵蓋哪些請求的實際需求,或者需要更細的 + 分級(例如是否要區分「登入態必須新鮮」與「登入態可以是快取的舊憑證」)。 +2. **`flutter_secure_storage` Linux 在無 keyring 環境下的實際失敗模式查不到**(§1.3),需要在 Linux child + task 的 POC 階段實測(例如全新未設定密碼鑰匙圈的系統、或 keyring 被鎖住時)才能決定要不要為此加一層 + 「secure storage 不可用」的降級處理(例如提示使用者需要啟用系統鑰匙圈,或退回明確標示為較不安全的 + 儲存方式)。 +3. **業務層限流退避沒有找到合適的成熟套件**(§2.5),確認是否接受「自行實作一個共用退避 helper、取代 + 舊專案分散在四五個檔案的硬編碼重試邏輯」這個方向,還是有其他既有內部工具可以複用。 diff --git a/.trellis/tasks/09-27-design-network-accounts/research/login-methods.md b/.trellis/tasks/09-27-design-network-accounts/research/login-methods.md new file mode 100644 index 000000000..4a7b006e3 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/research/login-methods.md @@ -0,0 +1,370 @@ +# 研究:各音源登入方式與 Linux 登入替代方案 + +對應項目 1、5。範圍:Bilibili、YouTube(YouTube Music)、網易雲音樂、Spotify、QQ 音樂的登入方式; +Linux 平台無成熟內嵌 WebView 套件時的替代方案。查不到的地方寫「查不到」,超出已驗證證據的推論標「推測」。 + +## 0. 一個貫穿全篇的重要發現:兩個最大的社群 API 文件/實作專案都被平台法律行動下架 + +在深入各音源之前先提出,因為這直接影響「該不該投入更多工程去對接非官方 API」的判斷: + +- **`SocialSisterYi/bilibili-API-collect`**(Bilibili 非官方 API 文件的事實標準,20,202 星)於 + 2026-01-28 收到 B 站委託律師事務所的存證信函,指控其「以技術手段系統性收集、整理 B 站非公開 API + 接口及其調用邏輯、參數結構、訪問控制及安全認證機制,並以文件、程式碼示例形式向公眾傳播」構成侵權。 + 該倉庫已**永久關停並刪除全部文件與範例程式碼**,預設分支被改名為 `deprecated`,只留一份說明: + (`gh api repos/SocialSisterYi/bilibili-API-collect` + 確認 `archived: true`、`default_branch: "deprecated"`;`deprecated` 分支的 README 為存證信函說明原文)。 + 這代表本檔案原本要引用的「cookie 刷新流程官方文件」已經**不存在可驗證的穩定連結**——下面 §1.4 + 的刷新流程步驟是延續本任務前一階段研究時讀過的內容整理,**現在已無法重新對照原文**,標記為「推測」 + (carried-over,非本次可重新驗證);改以 PiliPlus 原始碼作為主要、可即時驗證的證據來源。 +- **`Binaryify/NeteaseCloudMusicApi`**(網易雲音樂非官方 API 的事實標準,30,253 星):`archived: true`, + 預設分支 `master` 的整個 git tree 只剩一份 `README.MD`,內容為「保护版权,此仓库不再维护」,並連結兩篇 + 中文科技媒體報導(、 + )——同樣是版權/法律驅動的下架,不是單純棄坑。 + +兩個分屬 Bilibili、網易雲的頭號社群專案在同一年內都被平台方用法律手段下架,且都指名「系統性收集非公開 +API」為理由。這比「套件多久沒更新」嚴重得多,是需要 owner 明確知情、明確決策的風險(見 §7)。 + +## 1. Bilibili + +### 1.1 登入方式總覽(以 PiliPlus 為證據來源) + +參考客戶端:**PiliPlus**(`bggRGjQaUbCoE/PiliPlus`,18,720 星,GPL-3.0,目前活躍維護,`main` 分支)。 +選它是因為它是目前 star 數最高、仍在維護的 Flutter Bilibili 播放器,程式碼可直接對照。 + +PiliPlus 實際實作的登入方式(`gh api repos/bggRGjQaUbCoE/PiliPlus/contents/lib/http/login.dart` 確認存在, +內容已抓取): + +- **TV/APP 掃碼登入**(QR,非 Web QR): + - `LoginHttp.getHDcode()` → `POST` `Api.getTVCode` + (`https://passport.bilibili.com/x/passport-tv-login/qrcode/auth_code`,App-sign 簽名),取得 + `auth_code` 與 QR 內容。 + - `LoginHttp.codePoll()` → `POST` `Api.qrcodePoll` + (`.../x/passport-tv-login/qrcode/poll`,App-sign 簽名),輪詢掃碼狀態。 + - 確認端點常數見 + : + `qrcodeConfirm = '.../x/passport-tv-login/h5/qrcode/confirm'`、 + `getTVCode = '.../x/passport-tv-login/qrcode/auth_code'`、 + `qrcodePoll = '.../x/passport-tv-login/qrcode/poll'`。 + - 檔案: +- **帳密登入**:`getWebKey()`(取得 salt 與 RSA 公鑰)搭配密碼加密提交;細節未展開讀取,未來若要做需另行 + 細讀該函式後續呼叫。 +- **簡訊登入**:`sendSmsCode()` → `POST` `Api.appSmsCode`,帶 Geetest 驗證碼參數 + (`geeChallenge`/`geeSeccode`/`geeValidate`)或 `recaptchaToken`——代表 Bilibili 的簡訊登入介面本身就內建 + 人機驗證挑戰,純程式化提交會被擋。 + +PiliPlus **沒有**實作「Web 版」`x/passport-login/web/qrcode/*` 系列端點;它統一走 TV/APP 家族端點。這代表 +「哪一種 QR 登入」在 Bilibili 生態裡至少有兩種變體,選 TV/APP 家族有一個活躍客戶端可直接對照實作。 + +### 1.2 兩種簽名機制(重要,容易漏掉) + +PiliPlus 的原始碼證實 Bilibili API 至少有**兩種互不相通的簽名方案**,混用會直接導致簽名錯誤: + +1. **WBI 簽名**(Web API 家族):`img_key`/`sub_key` 混合出 mixin key,再對參數計算 `w_rid`/`wts`。 + 檔案: +2. **App-sign**(App/TV API 家族,登入相關端點都在這裡):參數依 key 字母排序、串接固定的 `appkey`+`appsec` + 後取 MD5。檔案: + (`AppSign.appSign()`,約 40 行,已讀取確認邏輯)。 + +新專案的 Bilibili adapter 若同時要呼叫 Web API(列表、詳情)與登入相關的 App/TV API,**必須分別實作兩套 +簽名**,不能假設一套簽名適用全站。 + +### 1.3 buvid/deviceId 自產生 + +PiliPlus 兩者都是**純本地產生**,不需要額外網路請求換取: + +- `generateBuvid()`:16 個隨機 byte → MD5 → `'XY${md5Str[2]}${md5Str[12]}${md5Str[22]}$md5Str'`。 +- `genDeviceId()`:BCD 編碼的時間戳 + 隨機 byte + checksum → MD5;程式內註解直接標明移植自 + `bilive_client`: + 。 + +兩者都在 (`LoginUtils` +class)。沒有獨立的 `buvid.dart` 檔案,邏輯內嵌在 `login_utils.dart`(確認過 `lib/utils/` 55 個檔案的完整 +清單,無此檔)。 + +### 1.4 Cookie 刷新(SESSDATA 過期前的主動刷新) + +官方流程(延續前一階段研究的記憶整理,來源倉庫已如 §0 所述被下架,**目前無法提供可重新驗證的原文連結**, +標記「推測」,但邏輯與 PiliPlus 程式碼裡出現的端點家族一致,可信度仍高): +`GET cookie/info`(檢查是否需要刷新)→ 用回傳的 RSA 公鑰加密一段 CorrespondPath → `GET correspond/1/{path}` +(帶著新舊 cookie 訪問這個網頁換取 refresh_csrf)→ `POST confirm/refresh`(提交新舊 csrf,換發新 +SESSDATA/bili_jct,並讓舊 cookie 失效)。 + +**負面發現,且有第二個獨立來源交叉印證**:PiliPlus 的 `login.dart` 裡**沒有** `refresh` 或 `correspond` +字串(`curl` 全文檢索確認),代表這個目前 star 數最高的維護中 Flutter 客戶端**沒有實作**主動 cookie 刷新; +另一個獨立專案 `seiuna/bilibili-api` 先前研究也確認同樣不完整。這說明 Bilibili 的刷新流程即使官方有文件, +真正落地實作的成熟客戶端也少——**FMP 重寫時若要做這段,預期工作量與踩坑成本會比看起來大**,且沒有現成、 +可直接抄的完整開源實作可以參照除錯,只能照官方描述的流程自行實作並自行測試邊界情況(例如 CorrespondPath +的有效期、多裝置同時刷新的競態)。 + +### 1.5 建議 + +- QR 登入走 TV/APP 家族端點(`passport-tv-login/*`),因為有 PiliPlus 這個活躍客戶端可直接對照實作與除錯。 +- buvid/deviceId 本地產生即可,不必額外請求。 +- 需要清楚拆開 WBI 與 App-sign 兩套簽名邏輯,各自獨立測試。 +- Cookie 刷新流程按官方描述實作,但**預留比預期更多的測試與除錯時間**,並接受「SESSDATA 過期後退回重新登入」 + 是一個合理、被業界驗證過的降級路徑(PiliPlus 這麼成熟的客戶端都沒做主動刷新)。 + +## 2. YouTube / YouTube Music + +### 2.1 Google 官方政策:內嵌 WebView 無法用於 Google 登入 + +Google 官方部落格明文禁止在內嵌 WebView(`android.webkit.WebView`、`WKWebView` 等)裡完成 OAuth 登入, +2021 年公告、2023 年擴大執行範圍,違反者會在 OAuth 授權端點看到 `disallowed_useragent` 錯誤: + +- + (原始公告,2021 年 9 月 30 日起全面封鎖內嵌 WebView) +- (2023 年擴大到企業/教育帳號的通知信原文, + 引用同一份政策) + +這代表 ADR 0009 選定的 `flutter_inappwebview`(本質上就是包裝 `WKWebView`/`android.webkit.WebView`)**原則上 +無法用來完成 Google 帳號登入**——不是「可能不穩定」,是 Google 明確會擋。此政策只針對 Google 自家 OAuth +端點,不影響其他音源。 + +### 2.2 開源客戶端實際怎麼取得登入態 + +`sigma67/ytmusicapi`(Python,YouTube Music 非官方 API 的事實標準,3,029 星,維護活躍,最後 push +2026-09-25)官方文件列出兩種認證方式: + +1. **Browser 認證**(官方文件: + ): + 使用者自己在**真實瀏覽器**(非嵌入 WebView)登入 `music.youtube.com`,用瀏覽器開發者工具複製一個已認證 + POST 請求(如 `/browse`)的完整 request headers(含 cookie),貼給 `ytmusicapi browser` 指令或 + `headers_raw` 參數。文件明確標註:「這組憑證的有效期跟你的瀏覽器 session 一樣長,大約兩年,除非你登出」 + (原文:"These credentials remain valid as long as your YTMusic browser session is valid (about 2 years + unless you log out).")。這是「登入用系統瀏覽器、貼上 cookie/headers」模式的官方先例,直接對應本任務 + 項目 5 問的「Linux 上用系統瀏覽器登入再貼 cookie」是否可行——**可行,且是 ytmusicapi 官方推薦的主要 + 方式之一**。 +2. **OAuth(TV/Limited Input device 類型)**(官方文件: + ): + 文件明確寫「自 2024 年 11 月起,YouTube Music 要求開發者自備 YouTube Data API 的 Client ID 與 Secret + 才能連上 API」,需要自己在 Google Cloud Console 申請專案,OAuth client type 選 + 「TVs and Limited Input devices」。官方連結: + - 申請憑證: + - 流程規格:(Google 官方的 TV device + OAuth flow) + 換言之,**這條路線仍然可用**(不是被完全砍掉),但代價是 FMP 專案要自己申請並內嵌一組 Google Cloud + OAuth 憑證,且要處理裝置碼輪詢流程;比「使用者手動貼 headers」複雜,但不需要使用者手動操作開發者工具。 +3. **yt-dlp 的 cookie 方式**(延續前一階段研究):yt-dlp 支援直接讀取瀏覽器的 cookie 檔(`--cookies-from-browser`) + 或匯入 Netscape 格式 cookie 檔案來取得串流權限,邏輯上與 ytmusicapi browser 認證同源(都是「借用真實 + 瀏覽器已登入的 cookie」),不是獨立的第三條路。 +4. **Harmony Music**(Flutter YouTube Music 播放器):前一階段研究已確認它完全沒有實作登入,最終退回 + 離線功能為主——負面案例,證實「在 Flutter 裡幫 YouTube 做內嵌登入」連同類產品都沒做成。 + +### 2.3 建議 + +- **沒有可靠的內嵌 WebView 登入方式**,這是 Google 官方政策造成的硬限制,不是實作能力問題。 +- 兩個現實可行的路線: + 1. 「系統瀏覽器登入 → 使用者手動複製 headers/cookie 貼回 App」——ytmusicapi 官方採用且文件化,成熟度高, + 但使用者體感複雜(需要開發者工具)。 + 2. TV device OAuth flow——使用者體驗較好(裝置碼+另開瀏覽器授權,不需要開發者工具),但 FMP 需要自己 + 申請並打包一組 Google Cloud OAuth 憑證,且要處理該憑證被 Google 停權/限流的風險。 +- 兩條路線都不涉及在 App 內嵌 WebView 跑 Google 登入頁,跟平台選型(flutter_inappwebview/webview_cef/ + desktop_webview_window)無關——**YouTube 登入的瓶頸不是 Linux 有沒有 WebView,而是 Google 政策本身**, + 這點在三個平台(Android/Windows/Linux)都一樣。 + +## 3. 網易雲音樂 + +### 3.1 QR 登入流程(以 `TianhaoC/NeteaseCloudMusicApi-enhanced` 為證據來源) + +原始的 `Binaryify/NeteaseCloudMusicApi`(30,253 星)已如 §0 所述被下架刪除原始碼。改用其分支 +`TianhaoC/NeteaseCloudMusicApi-enhanced`(`archived: false`,但 `stargazers_count: 0`、 +`pushed_at: 2026-01-19`,距今約 8 個月沒更新,儘管專案描述自稱「自 v4.28.0 後自行維護」)取得可驗證的原始碼: + +- `module/login_qr_key.js`:`POST /api/login/qrcode/unikey`,body `{type: 3}`,取得 QR 用的 `key`。 +- `module/login_qr_create.js`:組出 `https://music.163.com/login?codekey=${query.key}`(web 平台可加 + `chainId` 參數),用 npm 套件 `qrcode` 產生 QR 圖。 +- `module/login_qr_check.js`:`POST /api/login/qrcode/client/login`,body `{key, type: 3}`;輪詢回傳 + 狀態碼 **801=等待掃碼/802=已掃碼待確認/803=登入成功**;成功時 `result.cookie`(陣列)以 `.join(';')` + 組成完整 Cookie 字串回傳——**MUSIC_U 就在這個陣列裡**。 +- `module/login_refresh.js`:`POST /api/login/token/refresh`,成功(`code === 200`)時同樣回傳 + `result.cookie` 陣列並 join 成字串——確認網易雲有一個明確的 token 刷新端點,且刷新後同樣是整組換發 + cookie(不是單獨換一個 token 欄位)。 +- `module/login_cellphone.js`:`POST /api/w/login/cellphone`(`weapi` 加密),body 含 `phone`、 + `countrycode`(預設 `86`)、`captcha`(簡訊驗證碼)或 `password`/`md5_password`(MD5 雜湊過的密碼), + `remember: 'true'`;成功時同樣回傳 `result.cookie`。確認手機號登入同時支援「驗證碼」與「密碼」兩種方式, + 由呼叫端決定帶哪一個欄位。 + +以上四個檔案內容均已直接讀取確認(原始碼可信、非轉述)。 + +### 3.2 建議 + +- **QR 登入是風險最低、最值得優先做的方式**:流程單純(三個端點:拿 key、組 QR、輪詢狀態)、不需要處理 + 簡訊驗證碼的圖形驗證、也不涉及密碼加密細節,且 QR 登入天生不依賴 WebView(見 §6),三平台一致。 +- 手機號登入可作為 QR 之外的第二選項,但要處理 `weapi` 這層網易雲自家的請求體加密(本次研究未深入該加密 + 演算法本身,若要做需另行研究 `weapi`/`eapi` 加密機制)。 +- **token 刷新有明確端點**(`login/token/refresh`),比 Bilibili 的刷新流程單純,值得在新專案優先實作, + 作為一個「刷新流程能落地」的正面對照。 + +### 3.3 需要留意的風險 + +- `TianhaoC/NeteaseCloudMusicApi-enhanced` 本身接近一年沒更新、star 數為 0,**不算一個「持續維護」的專案**, + 只是目前少數還保有原始碼可查的分支,不建議把它當長期依賴,只當作端點行為的參考實作。 +- 原始版 `Binaryify/NeteaseCloudMusicApi` 的下架與 Bilibili 的 `bilibili-API-collect` 下架同屬 2026 年内 + 的平台法律行動,兩個 FMP 要做「可播放」的中文音源都各自出現過一次「頭號社群專案被平台方法律手段下架」 + 的先例,見 §0、§7。 + +## 4. Spotify、QQ 音樂(只需「匯入」,不需播放) + +### 4.1 Spotify:2026 年的 API 限縮,已讓「免登入匯入公開歌單」名存實亡 + +Spotify 官方 2026 年 2 月的開發者變更公告與遷移指南(均為官方一手來源): + +- : + `GET /playlists/{id}/tracks` 被 `GET /playlists/{id}/items` 取代。 +- : + 明確寫新端點「**只對使用者擁有或協作的歌單開放**」(原文:"Only available for playlists the user owns + or collaborates on.")——即使呼叫端已經是登入使用者,也不能讀別人的公開歌單內容。 +- : + 官方部落格說明 Development Mode(一般第三方 App 預設走的模式)自 2026-02-11 起限縮:需要 Spotify + Premium 帳號、每個開發者只能有一個 Development Mode Client ID、每組 Client ID 最多 5 個被授權使用者、 + 可呼叫的端點集合被縮小。 + +**結論**:Spotify 原本可以用 Client Credentials flow(不需要使用者登入)讀公開歌單 metadata 的路徑,在 +2024 年 11 月已針對 Spotify 官方歌單、瀏覽類端點先收緊過一輪;2026 年 2-3 月這輪更直接把「讀取歌單曲目 +內容」限縮到「該歌單的擁有者或協作者本人登入後才能讀」。**這代表擁有者原本設想的「Spotify 只需要匯入 +公開歌單,不需要處理登入」這個假設,在 2026 年的 Spotify API 現狀下已經不成立**——除非匯入對象剛好是 +使用者自己的歌單(此時使用者本來就需要登入 Spotify),否則匯入「別人分享的公開歌單連結」在 Development +Mode 下很可能直接被 API 拒絕。這點列入 §7 需要 owner 重新確認範圍。 + +### 4.2 QQ 音樂:公開歌單通常不需要登入 + +延續前一階段研究:QQ 音樂的公開歌單詳情(以 `disstid` 為 key 的端點)一般**不需要登入態**,但需要正確的 +`User-Agent`/`Referer` header 組合(瀏覽器直接呼叫會因為 `Referer` 檢查被擋,必須模擬 App 或桌面端的 +header)。登入態主要用在 VIP 歌曲串流 URL、私人/個人歌單這類需要身分的資源。官方也提供需要開發者註冊的 +OpenAPI,作為更穩定但需要走審核流程的替代方案(本次研究未深入 OpenAPI 的申請門檻與額度限制,若要採用 +需另行查證)。 + +對 FMP「只需匯入公開歌單」的需求而言,QQ 音樂目前技術上可行、風險遠低於 Spotify;主要工作是維持正確的 +偽裝 header,而非處理登入。 + +## 5. Linux 登入替代方案 + +### 5.1 起點:`flutter_inappwebview` 不支援 Linux + +直接查 pub.dev API 確認(,抓取當下 `latest.version` +為 `6.1.5`):其 `dependencies` 只列出 +`flutter_inappwebview_android`/`_ios`/`_macos`/`_web`/`_windows` 五個平台實作套件,**沒有 Linux**。 +這與 ADR 0009 §之後要注意「登入 WebView 在 Linux 的選型…在網路與帳號的 ADR 決定」的前提一致:Linux 從 +一開始就不在 `flutter_inappwebview` 的能力範圍內,必須另外選型。 + +### 5.2 `webview_cef`:cookie API 已直接讀原始碼確認,可讀 HttpOnly cookie + +pub.dev 資料():最新版 **0.6.2**,發布於 2026-08-25T08:37:54Z; +score()140/160、88 個 like、近 30 天下載 831 次;支援 +Windows、macOS、Linux(含 eLinux)。 + +**Cookie API 已確認、非推測**:官方 README +()「Cookies」一節列出: + +```dart +await WebviewManager().setCookie('example.com', 'key', 'value'); +await WebviewManager().deleteCookie('example.com', 'key'); +final all = await WebviewManager().visitAllCookies(); +final some = await WebviewManager().visitUrlCookies('example.com', false); +``` + +往下追原生實作,`visitAllCookies`/`visitUrlCookies` 是包在 `WebviewCookieVisitor` 這個 C++ 類別上, +它直接實作 CEF 原生介面 `CefCookieVisitor`(、 +,已讀取完整原始碼)。 +CEF 的 `CefCookieVisitor`/`CefCookieManager` 系列 API 是直接讀 Chromium 網路層底層的 cookie store(等同 +`chrome://settings/cookies` 看得到的那份資料),**不是**透過頁面 JS 的 `document.cookie`(後者本來就讀不到 +HttpOnly cookie)。因此可以有把握地說:**webview_cef 能讀到 HttpOnly cookie**,這是基於它使用的是 CEF +原生 C++ cookie 介面(而非 JS 橋接)這個結構性事實得出的推論,不是我們直接跑過驗證,但可信度高,标記 +「推測(基於原始碼結構的合理推論,未實機驗證)」。 + +**包裝大小**:README 明確寫 Windows 首次建置會下載「官方 CEF Standard Distribution(約 330 MB,來自 +)」,並從原始碼編譯 `libcef_dll_wrapper`——這是**建置時**下載的暫存 +依賴大小,不等於最終安裝包大小。README 沒有給出最終打包後的安裝包體積數字,**這點查不到**,需要在 +POC 階段實際打包一次 Windows/Linux 版本才能得到準確數字;可以合理預期比純 Flutter(無 CEF)的包大上 +一個量級(CEF 是完整 Chromium),與市面上其他內嵌 Chromium 的桌面框架(如 Electron)體積量級相近,這是 +基於「同樣內嵌完整 Chromium」的合理推論,標記「推測」。 + +Linux 建置需求(README「Linux」一節):`clang`、`cmake`、`ninja-build`、`libgtk-3-dev`、`pkg-config`; +CEF 在首次建置時自動下載(x64、arm64 皆支援),無最低發行版版本要求(表格中 Linux 一欄的「Minimum +version」是「—」,即未特別限制)。 + +### 5.3 `desktop_webview_window`:WebKitGTK 原生 cookie API(前一階段研究,本次確認套件現況) + +pub.dev 資料():最新版 **0.3.0**,發布於 +2026-05-27T04:26:21Z,支援 macOS、Windows、Linux。 + +前一階段研究已直接讀過其 Linux 端原始碼,確認它透過 WebKitGTK 原生 API +(`webkit_cookie_manager_get_cookies`、`soup_cookie_get_http_only()`)讀取 cookie,這組 API 同樣是直接讀 +WebKitGTK 的網路層 cookie store,可以讀到 HttpOnly cookie(此為前一階段已驗證的結論,非本次重新驗證, +但原始碼引用仍然有效,此處視為已確認、非推測)。 + +### 5.4 一個重要的真實案例對照:PiliPlus 在 Linux 上**沒有**用任何原生 WebView cookie API + +PiliPlus 為了支援 Linux,寫了一個自己的、基於 `MethodChannel` 的 Linux WebView plugin +(,channel 名稱 +`com.example.piliplus/linux_webview`),**沒有使用 `webview_cef` 或 `desktop_webview_window`**。它的 cookie +處理方式(, +`LinuxCookieManager`,已讀取完整原始碼)是: + +- **讀取**:直接從 App 自己的 Dio cookie jar(`Accounts.main.cookieJar`)拿 cookie,**不從 WebView 原生 + API 讀**。 +- **寫入**(要把已登入的 cookie 灌回 WebView,讓網頁顯示已登入狀態):組一段 JS + (`generateCookieInjectionJs()`),透過 `document.cookie = ...` 把 cookie 注入頁面——這個方向沒有 + HttpOnly 限制(寫入 cookie 本來就不受 HttpOnly 影響,HttpOnly 只擋「JS 讀取」)。 +- 登出/清除:呼叫 `LinuxWebviewPlugin.clearAllCookies()`。 +- 在非 Linux 平台,`LoginUtils.setWebCookie()` 則是把 cookie jar 同步進 `flutter_inappwebview` 的 + `CookieManager`()。 + +**這是一個已被驗證、上線運作的真實案例**,證明「Linux WebView 不需要有原生 cookie 讀取 API,只要能載入 +登入頁讓使用者操作,登入成功後的憑證從自己的 Dio cookie jar 或 App 端攔截網路請求取得即可」是可行的設計。 +換句話說,即使某個 Linux WebView 方案的 cookie API 有疑慮,只要能:(a) 顯示登入頁、(b) 讓應用層攔截或 +讀出登入成功後產生的 Set-Cookie(例如透過攔截該 WebView 的網路請求,或後續改用該音源自己的登入 API 而非 +單純泡在 WebView 裡等 cookie),仍然可以不依賴 WebView 的原生 cookie API 完成登入。 + +### 5.5 系統瀏覽器登入+貼上 cookie/headers,作為完全不需要嵌入式 WebView 的備案 + +見 §2.2:`ytmusicapi` 官方文件就是採用這個模式(使用者在真實瀏覽器登入、用開發者工具複製 headers 貼回 +App),且明確說「有效期約兩年」。這代表: + +- 這不是一個臨時的權宜之計,是至少一個成熟開源專案官方採用、且文件化的正式登入方式。 +- 缺點是使用者體感複雜(需要打開瀏覽器開發者工具),比較適合當 Linux 平台在其他方式都不可行時的 + **最後備援**,而不是主要體驗。 +- 對 Bilibili、網易雲這類支援 QR 登入的音源,QR 登入本身就完全不依賴 WebView(只需要能顯示一張 QR 圖 + 給使用者用手機掃,加上一個輪詢 API)——**QR 登入是三平台一致、不需要處理 WebView 選型的最穩健方案**, + 應該優先於任何形式的 WebView 內嵌登入。 + +### 5.6 建議(Linux 登入方式排序) + +1. **優先用 QR 登入**(Bilibili TV/APP QR、網易雲 QR)——完全不需要 WebView,三平台程式碼一致,是本研究 + 中風險最低的選項。 +2. 音源沒有 QR 登入、必須走 WebView(例如帳密登入頁)時,`webview_cef` 是目前唯一同時支援 Windows/macOS/ + Linux 三桌面平台、cookie API 有原始碼可驗證讀取邏輯的套件,代價是打包變大(確切數字待 POC 驗證)與 + 建置鏈變複雜(需要 C++20 工具鏈、CEF 下載)。 +3. 若 `webview_cef` 的建置成本或包大小在 POC 階段被判定不可接受,PiliPlus 的模式(自建輕量 WebView plugin + + 不依賴原生 cookie API,改用應用層自己的 cookie jar 或攔截登入成功後的網路回應)是一個有實機驗證先例 + 的備案,但需要為每個要用 WebView 登入的音源多做一層「登入成功偵測」邏輯(不能單純等 WebView 的 cookie + API 通知)。 +4. YouTube 登入完全不依賴以上選型(見 §2.3),系統瀏覽器貼 headers 或 TV OAuth device flow 是唯二選項, + 三平台一致。 + +## 6. 查不到/需要進一步驗證的項目清單 + +- Bilibili cookie 刷新流程的官方原文連結:來源倉庫已下架,查不到可重新驗證的穩定連結(見 §0、§1.4)。 +- `webview_cef` 最終打包後在 Windows/Linux 的安裝包體積:官方 README 只給建置時 CEF 下載量(約 330 MB), + 查不到最終打包體積的官方數字,需 POC 階段實測。 +- QQ 音樂官方 OpenAPI 的申請門檻與額度限制:本次未深入查證。 +- Bilibili 帳密登入(`getWebKey()` 之後的 RSA 加密細節)與網易雲 `weapi`/`eapi` 請求體加密演算法:本次 + 研究未展開,兩者都只在需要真的實作「帳密登入」時才必要(QR 登入不需要)。 + +## 7. 需要 owner 決定的事項 + +1. **Bilibili、網易雲兩個中文音源的頭號社群 API 專案都已被平台方以法律手段下架**(§0)。這代表持續對接 + 這兩個音源的非公開 API 存在真實的、已發生過的法律風險先例,不是假設性風險。是否要在文件(例如 + README 或 ADR)中明確記錄這個風險並取得 owner 知情同意,還是需要重新評估投入這兩個音源的工程優先序, + 需要 owner 決定。 +2. **Spotify 匯入公開歌單在 2026 年的 API 現狀下技術上可能不可行**(§4.1):新端點只對歌單擁有者/協作者 + 開放,Development Mode 額度也大幅限縮。這與「Spotify 只需要匯入,不需要處理登入」的原始假設衝突, + 需要 owner 確認:(a) 維持原假設但接受多數「匯入別人分享的公開歌單」案例會失敗;(b) 改為要求使用者 + 登入自己的 Spotify 帳號、只能匯入自己擁有或協作的歌單;(c) 放棄 Spotify 匯入功能。 +3. **YouTube 登入無法用內嵌 WebView**(§2.1,Google 官方政策),必須在「使用者手動複製瀏覽器 headers」 + 與「FMP 自行申請 Google Cloud OAuth 憑證走 TV device flow」之間選一個作為主要方式,兩者使用者體驗與 + 工程成本差異大,需要 owner 決定要哪一種、或兩種都提供讓使用者選。 +4. **Linux 登入 WebView 選型**:`webview_cef`(包大小/建置鏈成本較高,但 cookie API 有結構性把握) + v.s. 自建輕量 WebView + 不依賴原生 cookie API(PiliPlus 模式,開發工作量較高、但有實機驗證先例)—— + 兩個方案目前都缺少「在 FMP 的實際打包流程裡跑一次」的驗證數據,需要 owner 決定是否值得為此開一個 + POC child task 再做最終選型,或先接受某個選項並在後續里程碑修正。 diff --git a/.trellis/tasks/09-27-design-network-accounts/task.json b/.trellis/tasks/09-27-design-network-accounts/task.json new file mode 100644 index 000000000..c5904fc57 --- /dev/null +++ b/.trellis/tasks/09-27-design-network-accounts/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-network-accounts", + "name": "design-network-accounts", + "title": "Design: network layer and accounts", + "description": "Phase-2 item 12: HTTP layer, credential storage and refresh, single declaration of which requests carry credentials, unified auth toggle semantics, login as a source capability", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From a6c99ddcf5e180584e715af5ede538498689c0c2 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 11:58:22 +0800 Subject: [PATCH 023/133] docs(adr): 0012 network layer and accounts --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 7 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../implement.md | 6 +- .../09-27-design-network-accounts/prd.md | 6 +- .../09-27-design-network-accounts/task.json | 4 +- docs/adr/0012-network-layer-and-accounts.md | 74 +++++++++++++++++++ 6 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 docs/adr/0012-network-layer-and-accounts.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 0e0461cfc..935b542d0 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -115,7 +115,7 @@ flowchart LR | 3 | 10 平台層(✅ 完成,ADR 0009) | 資料目錄、音訊後端、登入方式、更新方式都要問「平台宣告了什麼能力」。 | | 4 | 6 資料層與相容(✅ 完成,ADR 0010) | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | | 5 | 18 設定與日誌(✅ 完成,ADR 0011) | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | -| 6 | 12 網路與帳號 | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | +| 6 | 12 網路與帳號(✅ 完成,ADR 0012) | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | | 7 | 2 錯誤模型 | 音源插件介面的回傳與例外型別要先定。 | | 8 | 1 音源插件 | 核心抽象;依賴 10、12、2。 | | 9 | 8 測試與開發環境 | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | @@ -222,3 +222,8 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 - ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。 + +## 8. 延後到特定里程碑的實測 + +- ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。 +- ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 1289eae1c..e0c61ac33 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -24,7 +24,8 @@ "09-27-design-rewrite-strategy", "09-27-design-platform", "09-27-design-data", - "09-27-design-settings-logging" + "09-27-design-settings-logging", + "09-27-design-network-accounts" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-network-accounts/implement.md b/.trellis/tasks/09-27-design-network-accounts/implement.md index a230e50b8..0b75fbb19 100644 --- a/.trellis/tasks/09-27-design-network-accounts/implement.md +++ b/.trellis/tasks/09-27-design-network-accounts/implement.md @@ -2,8 +2,8 @@ 本任務只產出設計與 ADR;程式在里程碑中實作。 -- [ ] 寫 `docs/adr/0012-network-layer-and-accounts.md`:design.md §1–§7;被否決的選項(每個 service 各自一個 dio、手動拼 Cookie header、在各 service 決定帶不帶憑證、TV 裝置碼 OAuth、只用貼上 cookie、刷新後用舊 options 重送、非 200 即清憑證、UI 與請求各讀一份登入狀態);「如何確認」(媒體請求不帶 cookie 的契約測試、刷新後重送帶新憑證的測試、每音源「憑證無效」判定表的測試、登出與重設清憑證的測試)。併入 `CONTEXT.md` 的原則(媒體請求不帶憑證、解析串流才用憑證)。 -- [ ] `phase2-plan.md` 標記第 12 項完成;記下「YouTube WebView 登入是否可用」為加入 YouTube 登入的里程碑先實測項目。 -- [ ] 歸檔本任務。 +- [x] 寫 `docs/adr/0012-network-layer-and-accounts.md`:design.md §1–§7;被否決的選項(每個 service 各自一個 dio、手動拼 Cookie header、在各 service 決定帶不帶憑證、TV 裝置碼 OAuth、只用貼上 cookie、刷新後用舊 options 重送、非 200 即清憑證、UI 與請求各讀一份登入狀態);「如何確認」(媒體請求不帶 cookie 的契約測試、刷新後重送帶新憑證的測試、每音源「憑證無效」判定表的測試、登出與重設清憑證的測試)。併入 `CONTEXT.md` 的原則(媒體請求不帶憑證、解析串流才用憑證)。 +- [x] `phase2-plan.md` 標記第 12 項完成;記下「YouTube WebView 登入是否可用」為加入 YouTube 登入的里程碑先實測項目。 +- [x] 歸檔本任務。 驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-network-accounts/prd.md b/.trellis/tasks/09-27-design-network-accounts/prd.md index af7ddb2d1..fc92d8d72 100644 --- a/.trellis/tasks/09-27-design-network-accounts/prd.md +++ b/.trellis/tasks/09-27-design-network-accounts/prd.md @@ -45,6 +45,6 @@ ## 驗收標準 -- [ ] design.md 涵蓋 HTTP 層、帶憑證宣告、憑證存放與狀態、登入方式、刷新與失效、開關語意、只匯入的來源。 -- [ ] `docs/adr/0012-*.md` 依範本寫成。 -- [ ] `phase2-plan.md` 標記第 12 項完成並記下 YouTube WebView 實測項目。 +- [x] design.md 涵蓋 HTTP 層、帶憑證宣告、憑證存放與狀態、登入方式、刷新與失效、開關語意、只匯入的來源。 +- [x] `docs/adr/0012-*.md` 依範本寫成。 +- [x] `phase2-plan.md` 標記第 12 項完成並記下 YouTube WebView 實測項目。 diff --git a/.trellis/tasks/09-27-design-network-accounts/task.json b/.trellis/tasks/09-27-design-network-accounts/task.json index c5904fc57..c3902314f 100644 --- a/.trellis/tasks/09-27-design-network-accounts/task.json +++ b/.trellis/tasks/09-27-design-network-accounts/task.json @@ -3,7 +3,7 @@ "name": "design-network-accounts", "title": "Design: network layer and accounts", "description": "Phase-2 item 12: HTTP layer, credential storage and refresh, single declaration of which requests carry credentials, unified auth toggle semantics, login as a source capability", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0012-network-layer-and-accounts.md b/docs/adr/0012-network-layer-and-accounts.md new file mode 100644 index 000000000..22bb2766d --- /dev/null +++ b/docs/adr/0012-network-layer-and-accounts.md @@ -0,0 +1,74 @@ +# 0012 — 網路層與帳號:請求宣告是否帶憑證、憑證只存一處、登入由音源宣告 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`app/` 的 HTTP client 與攔截器、憑證存放、帳號狀態、登入 UI、每音源設定表、音源插件的請求定義 + +## 背景 + +舊專案的帳號與網路(`docs/audit/accounts-network.md`、`docs/audit/errors.md`): + +- UI 顯示的登入狀態讀 Isar `Account`,實際送請求只看 secure storage,兩者可能不一致;「重設所有資料」不清憑證,重設後請求仍帶舊 cookie。 +- 「用登入狀態播放」只影響部分請求,三個音源語意不同(YouTube 只在匿名失敗後才帶;YouTube 與網易的排行永遠不帶)。 +- 帶不帶憑證散落在各 service 手動組 header;每個 service 各自一個 dio。 +- B 站 QR 登入可能假成功;B 站刷新憑證後用舊 options 重送;網易任何非 200 都當失效並清憑證;播放用的連線偵測不到失效;secure storage 暫時讀不到就刪憑證;失效提示每次執行只跳一次。 + +`CONTEXT.md` 記錄的原則經審計驗證仍成立,併入本 ADR:**憑證只用在向音源解析串流與 API 請求,實際抓取音訊位元組的請求一律不帶憑證**。 + +## 考慮過的選項 + +- **沿用各 service 自己決定帶不帶憑證**:否決。規則散落,無法一處檢查,是舊版範圍不一致的根源。 +- **每個 service 一個 dio**:否決。刷新、cookie、限流無法共用。 +- **手動拼 Cookie header**:否決。改用 `cookie_jar`+`dio_cookie_manager`。 +- **YouTube 只用「貼上 cookie」**:否決為唯一方式,保留為備案;App 內網頁登入體驗較好。 +- **YouTube TV 裝置碼 OAuth**:否決。需在公開 repo 放 Google Cloud 憑證,有被濫用與撤銷的風險,並受配額限制。 +- **採用:請求層宣告+每音源一個 API client+獨立媒體 client+單一憑證存放+登入方式由音源宣告**,見下。 + +## 決定 + +1. **HTTP 層**:每個音源一個 API client(dio),該音源所有 service 共用;攔截器順序為認證注入、cookie 管理、錯誤對應、 + 限流與退避(策略由音源宣告)、網路紀錄(ADR 0011)。另有一個**媒體 client** 專抓音訊位元組,只加媒體 headers(Referer、UA), + 不掛認證攔截器與 cookie 管理。匿名用的非機密 cookie(例如 B 站 `buvid`)存資料庫。 +2. **帶憑證的單一宣告點**:每個請求在音源插件的定義處宣告 `AuthRequirement`: + - `required`:寫入遠端歌單、讀收藏夾與私人歌單;未登入就不發請求,直接回「需要登入」。 + - `userPreference`:搜尋、排行、詳情、串流解析、下載詳情、歌單刷新、電台、Mix;已登入且開關開啟才帶。 + - `never`(預設):公開頁面抓取、第三方歌詞源。 + 認證攔截器只依此標記注入。網路紀錄記錄每個請求是否帶了憑證。 +3. **憑證存放**:唯一來源 `CredentialStore`(`flutter_secure_storage` 11.x,以音源 id 為鍵),登入狀態由它推導; + 帳號的非機密顯示資訊存資料庫。讀取失敗時狀態為「暫時無法讀取」並稍後重試,**不刪除**。憑證載入或更新時登記到遮蔽函式。 + 舊憑證由 legacy import 以 10.x 讀入(ADR 0010)。 +4. **登入是音源能力**:音源宣告支援的登入方式(QR、App 內網頁登入、貼上 cookie),UI 顯示「音源支援 ∩ 平台有能力(ADR 0009)」。 + B 站、網易以 QR 為主;YouTube 以 App 內網頁登入(桌面 UA)為主、貼上 cookie 為備案。 + **拿到憑證後先呼叫帳號資訊 API 驗證,通過才寫入**。 +5. **刷新與失效**: + - 刷新由音源宣告是否支援與時機(B 站啟動時詢問是否需要刷新);帳號頁顯示最後刷新時間與結果。 + - 只有帶了憑證的請求才可能觸發失效;每個音源明確列出哪些回應代表憑證無效,網路錯誤、限流、風控碼不算。 + - 遇到憑證無效:`QueuedInterceptor` 單飛,支援刷新就先刷新、**以新憑證重建請求**後重送一次;否則標記已失效。 + - 已失效:保留憑證、停止帶它、提示一次,帳號頁與相關入口顯示需要重新登入;重新登入後下一次失效會再提示。 + - 登出:清該音源憑證、該音源網域的 WebView cookie、記憶體 cookie、遮蔽登記。重設所有資料:清資料庫、全部憑證、全部 WebView 資料。 +6. **「以登入身分瀏覽與播放」**:每個音源一個開關(每音源設定表,ADR 0011),控制所有 `userPreference` 請求,三個音源語意一致。 + 預設由音源宣告,B 站、網易、YouTube 皆開;YouTube 旁附說明:以登入身分大量請求可能被視為自動化行為(推測)。 + legacy import 以舊開關值作為使用者設定;舊版開關範圍較窄,切換版本的發行說明寫明。 +7. **只能匯入的來源**:Spotify(embed 頁)、QQ(公開歌單)不需登入,標為 `never`;抓頁面可能隨改版失效,由音源健康檢查涵蓋。 +8. **沒有 WebView 的平台**(例如 Linux):B 站、網易用 QR,YouTube 用貼上 cookie;是否引入 `webview_cef` 在 Linux child task 決定。 + +採用的慣例:dio 官方 `QueuedInterceptor`;`cookie_jar`+`dio_cookie_manager`;PiliPlus 以 QR 為主的 B 站登入; +ytmusicapi 的瀏覽器 cookie 認證;Finamp 的已知值遮蔽(ADR 0011)。 + +## 後果 + +- 好的:一處就能看出每個請求帶不帶憑證;憑證不可能送到 CDN;登入狀態只有一個來源;三個音源行為一致;審計列出的 C1、C3、C4、C5、C6、M1、M5–M9、M12 由結構修正。 +- 壞的:每個請求定義多一個標記;每個音源要維護「憑證無效」判定表與遮蔽名單;YouTube 的 App 內網頁登入可能被 Google 擋,屆時只能靠貼上 cookie。 +- 之後要注意: + - B 站與網易的社群 API 文件已因法律行動下架,刷新流程等細節需以實作與測試驗證。 + - YouTube App 內網頁登入目前是否可用未知,第一個加入 YouTube 登入的里程碑先實測。 + - Linux 沒有 keyring 時 secure storage 的行為,在 Linux child task 實測。 + - 統一錯誤型別與限流退避策略的細節由錯誤模型的 ADR 定。 + +## 如何確認 + +- 契約測試:每個音源的媒體請求經媒體 client 發出後,請求上不含任何 Cookie/Authorization。 +- 測試:`AuthRequirement` 三種標記在「未登入/已登入且開關開/已登入且開關關」下的注入結果。 +- 測試:刷新後重送的請求帶的是新憑證。 +- 測試:每個音源的「憑證無效」判定表;限流與網路錯誤碼不會把帳號標為失效。 +- 測試:登出與重設所有資料後,`CredentialStore` 為空且請求不再帶憑證。 From cf65c0e33ee066b6f1c56b62a37d06eddb7b29c1 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 11:58:22 +0800 Subject: [PATCH 024/133] chore(task): archive design-network-accounts --- .../2026-09}/09-27-design-network-accounts/check.jsonl | 0 .../2026-09}/09-27-design-network-accounts/design.md | 0 .../2026-09}/09-27-design-network-accounts/implement.jsonl | 0 .../2026-09}/09-27-design-network-accounts/implement.md | 0 .../2026-09}/09-27-design-network-accounts/prd.md | 0 .../research/credentials-and-http.md | 0 .../09-27-design-network-accounts/research/login-methods.md | 0 .../2026-09}/09-27-design-network-accounts/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/research/credentials-and-http.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/research/login-methods.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-network-accounts/task.json (92%) diff --git a/.trellis/tasks/09-27-design-network-accounts/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/check.jsonl diff --git a/.trellis/tasks/09-27-design-network-accounts/design.md b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/design.md similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/design.md diff --git a/.trellis/tasks/09-27-design-network-accounts/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/implement.jsonl diff --git a/.trellis/tasks/09-27-design-network-accounts/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/implement.md diff --git a/.trellis/tasks/09-27-design-network-accounts/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/prd.md diff --git a/.trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/research/credentials-and-http.md similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/research/credentials-and-http.md rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/research/credentials-and-http.md diff --git a/.trellis/tasks/09-27-design-network-accounts/research/login-methods.md b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/research/login-methods.md similarity index 100% rename from .trellis/tasks/09-27-design-network-accounts/research/login-methods.md rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/research/login-methods.md diff --git a/.trellis/tasks/09-27-design-network-accounts/task.json b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/task.json similarity index 92% rename from .trellis/tasks/09-27-design-network-accounts/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-network-accounts/task.json index c3902314f..edca1a3a1 100644 --- a/.trellis/tasks/09-27-design-network-accounts/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-network-accounts/task.json @@ -3,7 +3,7 @@ "name": "design-network-accounts", "title": "Design: network layer and accounts", "description": "Phase-2 item 12: HTTP layer, credential storage and refresh, single declaration of which requests carry credentials, unified auth toggle semantics, login as a source capability", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From 88db67b67fe5f3049af5aa76b278e3e079cfe358 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 12:24:47 +0800 Subject: [PATCH 025/133] chore(task): plan phase-two item 2 (unified error model) --- .../tasks/09-27-design-errors/check.jsonl | 0 .trellis/tasks/09-27-design-errors/design.md | 78 ++++ .../tasks/09-27-design-errors/implement.jsonl | 0 .../tasks/09-27-design-errors/implement.md | 7 + .trellis/tasks/09-27-design-errors/prd.md | 34 ++ .../research/error-model-patterns.md | 362 +++++++++++++++++ .../research/retry-and-peers.md | 380 ++++++++++++++++++ .trellis/tasks/09-27-design-errors/task.json | 26 ++ 8 files changed, 887 insertions(+) create mode 100644 .trellis/tasks/09-27-design-errors/check.jsonl create mode 100644 .trellis/tasks/09-27-design-errors/design.md create mode 100644 .trellis/tasks/09-27-design-errors/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-errors/implement.md create mode 100644 .trellis/tasks/09-27-design-errors/prd.md create mode 100644 .trellis/tasks/09-27-design-errors/research/error-model-patterns.md create mode 100644 .trellis/tasks/09-27-design-errors/research/retry-and-peers.md create mode 100644 .trellis/tasks/09-27-design-errors/task.json diff --git a/.trellis/tasks/09-27-design-errors/check.jsonl b/.trellis/tasks/09-27-design-errors/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-errors/design.md b/.trellis/tasks/09-27-design-errors/design.md new file mode 100644 index 000000000..b7918adc8 --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/design.md @@ -0,0 +1,78 @@ +# 設計:統一錯誤模型 + +採用的慣例:Dart sealed class 做窮舉分類;NewPipe `ErrorInfo` 的欄位(可重試、是否可回報、給使用者的訊息)與 +「同一錯誤依情境升級呈現」;AWS〈Exponential Backoff And Jitter〉的全抖動退避;Riverpod 3 以 `AsyncValue` 承接錯誤。 + +## 1. 分類 + +一個 sealed 型別 `AppError`,擁有者指定的 8 類,加上 1 類給「預期外」: + +| 類別 | 什麼時候 | 例子 | +|---|---|---| +| `NetworkError` | 連線、逾時、DNS、TLS、離線 | dio 的連線錯誤 | +| `RateLimited` | 音源明確表示請求太頻繁 | HTTP 429、網易 -460(依音源判定表) | +| `AuthRequired` | 需要登入的請求但未登入 | `AuthRequirement.required`(ADR 0012) | +| `CredentialInvalid` | 帶了憑證但音源判定無效 | B 站 -101(依音源判定表) | +| `VerificationRequired` | 風控,需要人工驗證或換身分 | B 站 -352/-412、YouTube「確認你不是機器人」 | +| `Unavailable` | 內容存在但不能播,附原因:地區、版權、會員、年齡、只有試聽 | 網易 VIP 歌、YouTube 地區限制 | +| `NotFound` | 內容不存在或已刪除、私人 | 影片下架 | +| `ParseError` | 回應格式不符合預期(多半是音源改版) | JSON 欄位消失 | +| `Unsupported` | 音源或平台沒有這個能力 | 理論上 UI 會先依能力隱藏;出現即是 bug | +| `UnexpectedError` | 以上都不是(包住未知例外) | — | + +YouTube 的機器人驗證歸在 `VerificationRequired`,不歸 `CredentialInvalid`:它不代表帳號壞了,常見解法是登入或貼上 cookie、換網路(NewPipeExtractor 也把它獨立成專屬例外)。 + +**共同欄位**:音源 id(可空)、`retryable`、`retryAfter`(可空)、給使用者的 i18n 訊息 key 與參數、`expected`(預期內的錯誤不算 bug,不附「回報」)、原始 error 與 stackTrace(只進 log,經 ADR 0011 遮蔽)、對應的網路紀錄 id。 + +## 2. 在哪裡轉換 + +- **網路層**(ADR 0012 的錯誤對應攔截器):把 dio 的傳輸層錯誤轉成 `NetworkError`。 +- **每個音源在自己的目錄裡**有一份對應表:該音源的 HTTP 狀態與錯誤碼 → `AppError`,包含 ADR 0012 要求的「憑證無效」判定。 +- **音源邊界以上**(service、Riverpod、UI)看不到 `DioException` 與音源私有的錯誤碼,只看 `AppError`。 +- 未知例外在音源邊界包成 `UnexpectedError`,保留原始 error 與 stack。 +- 測試:每個音源用錄下來的錯誤回應 fixture,逐一斷言對應到的類別(契約測試,第 8 項)。 + +## 3. 錯誤怎麼傳 + +- 音源與 service 丟出 `AppError`;Riverpod provider 以 `AsyncValue.error` 承接,UI 用 exhaustive `switch` 呈現。 + (Flutter 官方指南用 `Result` 型別,但那是為 `ChangeNotifier` 架構設計;本專案用 Riverpod,`AsyncValue` 已扮演同樣角色,不再包一層。) +- 使用者動作(播放、加入歌單、登入…)由呼叫端捕捉 `AppError` 交給呈現層(第 3 項 Toast)。 +- 禁止空的 `catch` 與吞掉錯誤只回預設值;需要忽略時必須記 log 並註明原因(lint,第 8 項)。 +- 所有錯誤被處理時經 log 門面寫入(ADR 0011),成為錯誤歷史。 + +## 4. 重試、退避、限流:只有一層 + +- **Riverpod 3 的自動重試全域關閉**(`ProviderScope(retry: (_, _) => null)`),避免與網路層重試相乘。 +- **重試只在網路層做**,策略由音源宣告、網路層統一執行: + - 只重試冪等請求(GET);POST 等寫入不自動重試。 + - 只重試 `NetworkError`、`RateLimited`,以及音源標為可重試的其他錯誤。 + - 指數退避+全抖動;尊重 `Retry-After`;次數上限由音源宣告(預設 2 次)。 + - 每個音源一個併發上限與最小請求間隔(`pool` 套件做併發;最小間隔自寫),用來預防限流,而不只是事後重試。 +- **憑證刷新後重送**:ADR 0012 的單飛刷新,與上面的重試分開計算。 +- **播放層的恢復**(連續失敗幾首就停、何時換音質、何時跳過)在第 13 項定。 +- 使用者手動重試:UI 的「重試」按鈕 invalidate 對應 provider。 + +## 5. 使用者看到什麼 + +| 類別 | 自動處理 | 使用者看到 | log 層級 | +|---|---|---|---| +| `NetworkError` | 網路層重試 | 動作失敗時 toast「網路連線失敗」;持續離線時顯示離線狀態(第 16、17 項) | warning | +| `RateLimited` | 網路層退避重試 | 仍失敗才 toast「{音源} 請求太頻繁,請稍後再試」 | warning | +| `AuthRequired` | 不重試 | 提示並附「登入」按鈕 | info | +| `CredentialInvalid` | 刷新一次(ADR 0012) | 刷新失敗:提示一次需要重新登入 | warning | +| `VerificationRequired` | 不重試 | toast 附建議:登入(B 站、YouTube)、或貼上 cookie、或稍後再試 | warning | +| `Unavailable` | 不重試 | 在曲目上標示原因(地區/會員/年齡/只有試聽);播放時跳過並提示 | info | +| `NotFound` | 不重試 | 在曲目上標示「已失效」;播放時跳過並提示 | info | +| `ParseError` | 不重試 | toast「{音源} 的回應格式改變,可能需要更新 App」 | error(可回報) | +| `Unsupported` | — | 不應出現;出現時 toast 通用訊息 | error(bug) | +| `UnexpectedError` | 不重試 | toast 通用訊息 | error(可回報) | + +- **訊息一律來自 i18n key**,永遠不把 `e.toString()` 或伺服器原文顯示給使用者(修正 G4);原文只進 log。 +- **部分成功**:多音源搜尋、批次匯入等,成功的照常顯示,失敗的音源或項目單獨標示,不再被成功的結果蓋掉(修正 G4)。 +- **背景工作**(自動刷新、排行抓取)不跳 toast,只記錄並在對應畫面顯示狀態(第 16 項)。 +- **同一錯誤去重**:同一類別+同一音源在短時間內只提示一次(Finamp 的做法)。 +- 開發者模式下每個錯誤 toast 有「詳細」(第 3 項)。 + +## 6. 不做(功能凍結,記入第 20 項待辦) + +- B 站 -352 的 geetest 驗證碼互動(PiliPlus 有做):新功能;現階段以「登入」作為主要建議(舊版實測帶登入時 -352 為 0/40,`lib/data/models/settings.dart:70-75`)。 diff --git a/.trellis/tasks/09-27-design-errors/implement.jsonl b/.trellis/tasks/09-27-design-errors/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-errors/implement.md b/.trellis/tasks/09-27-design-errors/implement.md new file mode 100644 index 000000000..9574dea55 --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/implement.md @@ -0,0 +1,7 @@ +# 執行計畫 + +本任務只產出設計與 ADR。 + +- [ ] 寫 `docs/adr/0013-unified-error-model.md`:design.md §1–§6;被否決的選項(沿用多種例外型別、Flutter `Result` 包裝、Riverpod 與網路層雙重重試、在 UI 顯示伺服器原文、在 service 各自重試、做 geetest 驗證互動);「如何確認」(每音源錯誤回應 fixture 對應測試、Riverpod 重試關閉的測試、空 catch lint、i18n 訊息測試)。 +- [ ] `phase2-plan.md` 標記第 2 項完成;第 20 項待辦加入「B 站 geetest 驗證互動」。 +- [ ] 歸檔本任務。 diff --git a/.trellis/tasks/09-27-design-errors/prd.md b/.trellis/tasks/09-27-design-errors/prd.md new file mode 100644 index 000000000..a4e3a777a --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/prd.md @@ -0,0 +1,34 @@ +# 設計第 2 項:統一錯誤模型 + +## 目標 + +一個 sealed 錯誤分類貫穿全 App;回答擁有者的三個問題:音源特有錯誤在哪裡轉成統一型別、重試/退避/限流由誰負責、 +哪些自動恢復/提示使用者/只記錄。 + +需求來源:parent `prd.md` 階段二第 2 項;`questions.md` G4、G5、C5、C6、D5、D10(按推薦);ADR 0011、0012。 + +## 現況(證據) + +- 自訂例外到畫面一律「發生錯誤」;adapter 把 `e.toString()` 原文丟上畫面;多源搜尋隱藏失敗;507 個 catch 中約 70 個空的(`docs/audit/errors.md` §1、§4)。 +- 播放限流只重試一次、不退避;電台網路錯誤顯示成未開播;網易非 200 即清憑證(`errors.md` §2–§3)。 +- 重試訊號只有沒人用的入口接得住(`docs/audit/playback.md` §3.6)。 + +## 研究結論(`research/error-model-patterns.md`、`research/retry-and-peers.md`) + +- Flutter 官方指南:`sealed Result` 取代 throw,逼呼叫端處理;設計給 `ChangeNotifier`+Command。 +- Riverpod 3:失敗的 provider **預設自動重試 10 次**(200ms→6.4s),可在 `ProviderScope(retry:)` 全域關閉(已以官方文件核對:riverpod.dev/docs/concepts2/retry)。與網路層重試疊加會相乘。 +- NewPipe `ErrorInfo`:可重試、可回報、使用者訊息;同一錯誤依情境升級呈現。Finamp 以「類別+來源」去重。 +- 退避:指數退避+全抖動、尊重 `Retry-After`;只重試冪等請求;併發用 `pool`。 +- 風控:B 站 -352 走 geetest 驗證(PiliPlus);YouTube 機器人驗證在 NewPipeExtractor 是獨立例外;地區限制各自是專屬例外。 + +## 需求 + +- R1 單一 sealed `AppError`:擁有者的 8 類(網路、限流、需登入、憑證無效、風控驗證、無法取得〔地區/版權/會員/年齡/試聽〕、找不到、解析失敗)加上「不支援」與「預期外」;共同欄位見 design.md §1。 +- R2 音源特有錯誤在該音源目錄內的對應表轉換;音源邊界以上只看 `AppError`。 +- R3 Riverpod 自動重試全域關閉;重試只在網路層,策略由音源宣告;只重試冪等請求;退避加抖動、尊重 `Retry-After`;每音源併發上限與最小間隔。 +- R4 使用者看到的訊息一律來自 i18n;部分成功要標出失敗部分;背景工作不跳 toast;同類同源錯誤去重。 +- R5 禁止空 catch 與靜默吞錯(lint)。 + +## 待確認(見摘要) + +- design.md §5「使用者看到什麼」表。 diff --git a/.trellis/tasks/09-27-design-errors/research/error-model-patterns.md b/.trellis/tasks/09-27-design-errors/research/error-model-patterns.md new file mode 100644 index 000000000..1a6d293f4 --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/research/error-model-patterns.md @@ -0,0 +1,362 @@ +# 統一錯誤模型前置研究(一):官方架構建議與型別設計 + +本檔涵蓋研究項目 1–3:Flutter 官方 App Architecture 的錯誤處理建議、Riverpod(含 Riverpod 3 +自動重試)的錯誤處理慣例、Dart `sealed class` 慣例與錯誤欄位設計。查證方式:官方文件 +(docs.flutter.dev、dart.dev、riverpod.dev)與 context7 鏡像的官方原始碼/文件。查不到的地方 +標「查不到」,推論的地方標「推測」。 + +## 1. Flutter 官方 App Architecture:`Result` 與 `Command` + +來源:、 +(皆為官方文件,範例取自 +`flutter/samples` 的 Compass App)。 + +### 1.1 為什麼 repository/service 回傳 `Result` 而不丟例外 + +官方文件的論點(逐條對應原文): + +- **Dart 的例外是 unchecked**:「methods that throw exceptions don't need to declare them, and + calling methods aren't required to catch them either」——呼叫方沒有編譯期義務處理例外。 +- **例外會在跨層呼叫中被漏接**:在 service → repository → view model 的鏈路中,view model 不會 + 直接呼叫 service;忘記包 `try-catch` 的 view model「compiles and runs, but crashes」,直到真的 + 觸發網路/JSON/HTTP 錯誤才會爆炸。 +- **`Result` 把錯誤放進回傳型別**:「`Result` classes force the calling method to check for + errors, reducing the amount of bugs caused by uncaught exceptions.」 +- **控制流變簡單**:多層 fallback 不需要巢狀 `try-catch`,改用型別檢查(`if (apiResult is Ok) + return apiResult;`)依序嘗試。 + +### 1.2 完整程式碼(原文逐字,來自官方文件) + +```dart +/// Utility class that simplifies handling errors. +/// +/// Return a [Result] from a function to indicate success or failure. +/// +/// A [Result] is either an [Ok] with a value of type [T] +/// or an [Error] with an [Exception]. +sealed class Result { + const Result(); + + const factory Result.ok(T value) = Ok._; + const factory Result.error(Exception error) = Error._; +} + +final class Ok extends Result { + const Ok._(this.value); + final T value; +} + +final class Error extends Result { + const Error._(this.error); + final Exception error; +} +``` + +服務層產生 `Result`(把 `throw` 換成 `Result.error`,並把可能丟出的例外收進 `catch`): + +```dart +Future> getUserProfile() async { + try { + final response = await client.get(...); + if (response.statusCode == 200) { + return Result.ok(UserProfile.fromJson(jsonDecode(...))); + } else { + return const Result.error(HttpException('Invalid response')); + } + } on Exception catch (exception) { + return Result.error(exception); + } +} +``` + +呼叫方用窮舉 `switch` 拆解(`sealed` 保證編譯期檢查兩種分支都處理到): + +```dart +switch (result) { + case Ok(): + userProfile = result.value; + case Error(): + error = result.error; +} +``` + +官方文件也列出現成套件作為 `Result` 的替代實作:`result_dart`、`result_type`、 +`multiple_result`(三者均為 pub.dev 上的套件,文件未評比優劣)。 + +### 1.3 `Command` 如何把錯誤/loading 狀態暴露給 UI + +`Command`/`Command0`/`Command1` 包一個回傳 `Result` 的函式,繼承 `ChangeNotifier`: + +```dart +abstract class Command extends ChangeNotifier { + bool _running = false; + bool get running => _running; + + Result? _result; + bool get error => _result is Error; + bool get completed => _result is Ok; + Result? get result => _result; + + void clearResult() { _result = null; notifyListeners(); } + + Future _execute(CommandAction0 action) async { + if (_running) return; // 防止重複觸發(例如按鈕連點) + _running = true; _result = null; notifyListeners(); + try { + _result = await action(); + } finally { + _running = false; notifyListeners(); + } + } +} + +final class Command0 extends Command { + Command0(this._action); + final CommandAction0 _action; + Future execute() async => _execute(_action); +} +``` + +- 暴露的狀態:`running`(進行中)、`error`(最近一次是 `Error`)、`completed`(最近一次是 + `Ok`)、`result`(原始 `Result`)、`clearResult()`(UI 消費完一次性事件,例如彈完 SnackBar 後 + 呼叫,避免同一個錯誤重複觸發)。 +- `_execute` 不 `catch` action 丟出的例外:action 被要求「不丟例外,一律回傳 + `Result.error`」;若真的丟出未捕捉的例外,`finally` 仍會重置 `running`,但例外會繼續往上 + 傳——即 `Command` 本身**不是**全域例外守門員,錯誤分類與捕捉的責任還是在 service/repository + 層產生 `Result` 的地方。 +- UI 用 `ListenableBuilder` 監聽 `Command` 本身(而不是整個 view model)來畫 loading/錯誤狀態; + 一次性動作(SnackBar、導頁)則在 `initState`/`dispose` 手動 `addListener`,處理完呼叫 + `clearResult()`。 + +官方文件也提到 pub.dev 上的 `command_it` 套件作為現成實作可替代手寫版。 + +**觀察(推測)**:官方文件本身有兩處不一致,值得在 FMP 設計時避開同樣的坑: +1. `result` 的 dartdoc 註解寫「回傳 `null` 表示 action 正在跑或以錯誤完成」,但實際程式碼裡 + `Error` 完成時 `_result` 不是 `null`,只有「進行中」或「已被 `clearResult()` 清除」才是 + `null`——註解與行為對不上。 +2. Command 頁的 UI 範例混用了兩版 `Command`(簡化教學版 `error` 型別是 `Exception?`、重置方法叫 + `clear()`;完整版 `error` 是 `bool`、重置方法叫 `clearResult()`),照抄範例會編譯不過。 + +**對 FMP 的啟示**:`Result`/`Command` 這套官方模式本身**不含錯誤分類**——它解決的是「錯誤有沒有 +被強制處理」,而不是「這個錯誤屬於網路/限流/需登入的哪一種」。分類(第 3 節)要另外設計一個 +`sealed` 的錯誤型別,放進 `Result.error` 的位置或包成 `Exception` 傳遞。 + +## 2. Riverpod 錯誤處理與 Riverpod 3 自動重試 + +來源:、 +、、 +、 + +(經 context7 `/rrousselgit/riverpod`、`/websites/riverpod_dev` 取得,皆為官方倉庫/官方站台)。 + +### 2.1 `AsyncValue`、pattern matching、`ref.listen` + +- `AsyncValue` 三態不變:loading/data/error,`ref.watch` 拿到後可用 Dart 3 pattern matching + 窮舉處理: + + ```dart + switch (activity) { + AsyncValue(:final value?) => Text(value.activity), + AsyncValue(:final error?) => Text('Error: $error'), + _ => const CircularProgressIndicator(), + } + ``` + +- **一次性提示(SnackBar/導頁)用 `ref.listen`,不要把錯誤畫進 rebuild 出來的 UI**:官方範例 + 直接在 `build()` 內呼叫 `ref.listen`,於 callback 裡跳 SnackBar;這與 FMP 的 `Command` 模式 + 中「UI 監聽 `Command`、錯誤消費後 `clearResult()`」是同一個原則的兩種實作路徑(Riverpod 原生 + 用 `ref.listen`,Command 模式用 `ChangeNotifier` 監聽)。 +- `AsyncValue.guard` 用來把一段可能丟例外的非同步程式碼包成 `AsyncValue`(等同 `Result` 模式在 + Riverpod 世界的對應物);具體 API 簽名建議實作前另查 `AsyncValue.guard` 的最新 dartdoc(本次 + 未取得逐字原始碼,標**查不到逐字定義**,但其用途——取代手寫 `try { state = AsyncData(...) } + catch (e, s) { state = AsyncError(e, s) }`——在官方遷移指南與多篇範例中反覆出現,可視為確認的 + 用法慣例)。 +- **重試(使用者手動或程式觸發)用 `ref.invalidate` / `ref.refresh`**:兩者關係官方原文—— + `ref.refresh` 是 `invalidate` 後接 `read` 的語法糖;只想丟棄快取用 `invalidate`,需要立刻拿到 + 新值用 `refresh`。下拉重整範例:`onRefresh: () => ref.refresh(activityProvider.future)`。 + +### 2.2 Riverpod 3 自動重試機制(本次研究明確要求確認的部分) + +**確認的事實**(來自 + 與 +`whats_new.mdx`,非第三方轉述): + +- **是的,Riverpod 3.0 起,provider 初始化時丟出例外會自動重試,預設開啟、不需要額外設定。** +- **預設策略**:最多重試 **10 次**,退避時間呈指數成長,**從 200ms 到 6.4 秒**封頂 + (`whats_new.mdx` 原文:「starting with a 200ms delay that doubles with each retry, up to a + maximum of 6.4 seconds」;`retry.mdx` 原文:「a provider can be retried up to 10 times, with + an exponential backoff going from 200ms to 6.4 seconds」)。 +- **兩種例外類型永遠不重試**: + 1. Dart 的 `Error`(例如 `StateError`、`ArgumentError`、`TypeError`)——官方理由:這類代表 + **程式本身有 bug、不可恢復**,重試沒有意義,只會在 log 裡製造噪音。 + 2. `ProviderException`——當一個 provider 依賴的上游 provider 失敗時,這個 provider **自己不是 + 失敗的源頭**,收到的是包著上游錯誤的 `ProviderException`;重試這個下游 provider 沒有用, + 真正該重試的是上游那個 provider。**推論**:若上游被設成不重試(`retry: (_, __) => null`), + 所有依賴它的下游也不會重試,因為它們收到的都是同一個 `ProviderException`。 +- **自訂/關閉方式**(三個層級,任一層都用同一種函式簽名 `Duration? Function(int retryCount, + Object error)`,回傳 `null` 表示停止重試): + - **全域關閉/自訂**:`ProviderScope(retry: (retryCount, error) => null, ...)`(App 根部)或 + `ProviderContainer(retry: ...)`(測試/無 widget 情境)。 + - **單一 provider 自訂**:程式碼產生語法 `@Riverpod(retry: myRetry)`;手動語法 + `NotifierProvider(TodoList.new, retry: myRetry)`。 + - **自訂函式範例**(官方原文): + ```dart + Duration? myRetry(int retryCount, Object error) { + if (retryCount >= 5) return null; + if (error is ProviderException) return null; + return Duration(milliseconds: 200 * (1 << retryCount)); + } + ``` + +**對 FMP 的影響(分析,非官方原文,標為推測/設計建議)**: + +- 這個機制作用在「provider **初始化**(`build()`)丟例外」的層級,跟 ADR 0012 講的「dio + 攔截器裡的限流與退避」是**兩層不同的重試**:Riverpod 3 的重試是「provider 建立失敗後重新跑一次 + `build()`」,會重新觸發底下所有的網路呼叫;dio 攔截器的重試是「單一 HTTP 請求失敗後在同一次 + `build()` 內重送」。兩者疊加時要小心**重試次數相乘**(例如 dio 層重試 3 次都失敗、丟出例外, + Riverpod 又對這個 provider 重試 10 次,等於使用者體感一次操作背後打了 30 次請求)。 +- 由於 Riverpod 3 預設對「所有非 `Error`/`ProviderException` 的例外」都重試,若 FMP 的統一錯誤 + 型別(第 3 節)是一個 `sealed class`(例如 `SourceError`)而不是 Dart `Error`,它會被 Riverpod + 判定為「可重試」而自動重試 10 次——**除非** FMP 明確在該類 provider 上關閉或客製 `retry:`,依 + 統一錯誤型別裡的 `retryable` 欄位(見第 3 節)動態決定要不要讓 Riverpod 繼續重試,或乾脆全域 + 關閉 Riverpod 的自動重試、把「要不要重試」的決策權完全交給 ADR 0012 講的「音源宣告策略」那一層 + (dio 攔截器),避免兩層重試各自決策、互相打架。**這是需要擁有者決定的分工問題**,見本任務最終 + 回報。 +- `ref.invalidate` 觸發的「使用者按重試按鈕」跟 Riverpod 3 的自動重試是分開的兩件事:使用者手動 + 重試沒有次數上限、也不受 `retry:` 參數控制。 + +## 3. Dart `sealed class` 慣例與錯誤欄位設計 + +### 3.1 `sealed` 語意(來源:,官方文件) + +- `sealed` 建立一個「已知、可窮舉的子型別集合」;子型別必須跟 `sealed` 類別在**同一個 + library**。`sealed` 隱含 `abstract`(不能直接建構實例,但可以有 factory constructor、可以定義 + 給子類別用的建構子)。 +- **窮舉檢查的範圍是「直接子型別」**:編譯器只保證知道所有「直接」繼承/實作它的型別(因為都在 + 同一個檔案/library),`switch` 若沒有涵蓋某個直接子型別會是編譯期錯誤。 +- 子類別本身**不會**自動變成 `abstract` 或受限——除非額外標 `base`/`final`/`sealed`。官方文件 + 另外指出:任何繼承或實作 `base`/`final` 類別的型別,自己也必須標 `base`、`final` 或 + `sealed`,但這條規則是為了保護「不能在外部繼續擴充」的保證,不是直接針對 `switch` 窮舉本身 + (這點官方頁面沒有明講兩者的因果關係,屬於**推測**:混用時若某個直接子型別本身是普通 + `class`,它可以在別的 library 被繼續擴充,但因為 `switch` 是依「型別比對」而非「集合相等」, + 對它的 `case` 依然會吃到它所有的子型別,因此不影響最外層 `switch` 的窮舉性——只影響「該子型別 + 底下還能不能長出新分支、新分支會不會被外層 switch 的既有 case 隱性吃掉」)。 +- 若不需要窮舉、或希望之後能新增子型別而不算破壞性 API 變更,官方建議改用 `final` 而非 + `sealed`。 + +**對 FMP 的啟示**:統一錯誤型別的頂層(例如 `SourceError`)應整個宣告在單一檔案/library 內、標 +`sealed`,讓「網路、限流、需登入/憑證過期、風控驗證、地區/版權限制、找不到、解析失敗、不支援」 +這八個分類都是它的直接子型別,`switch` 才能真正窮舉這八種、逼所有消費端(UI、log、重試邏輯)在 +新增第九種分類時編譯期出錯而不是漏處理。 + +### 3.2 錯誤型別欄位設計的既有先例:NewPipe `ErrorInfo` + +來源: + +(直接讀取官方倉庫原始碼確認,非轉述)。NewPipe(Android/Kotlin)用一個 `ErrorInfo` +(`Parcelable` data class)統一封裝所有要回報/顯示的錯誤,欄位: + +| 欄位 | 型別 | 用途 | +|---|---|---| +| `stackTraces` | `Array` | 原始例外的 stack trace(純文字化,供回報/log) | +| `userAction` | `UserAction`(enum) | **使用者當時在做什麼**(見 3.3),不是錯誤種類本身 | +| `request` | `String` | 觸發錯誤的請求描述(例如 URL) | +| `serviceId` | `String` | 是哪個服務/來源(YouTube、SoundCloud……)——對應 FMP 的**音源 id** | +| `message` | `ErrorMessage`(string 資源 id +格式參數) | **使用者看到的訊息 key**,不是寫死字串,走 i18n | +| `isReportable` | `Boolean` | 是否該讓使用者回報成 bug(區分「已知的來源錯誤」與「未預期的例外」) | +| `isRetryable` | `Boolean` | **可否重試**——對應 FMP 要的 retryable flag | +| `recaptchaUrl` | `String?` | 若是風控驗證碼,附上驗證頁 URL | +| `openInBrowserUrl` | `String?` | 提供「用瀏覽器打開」作為降級手段的連結 | + +`ErrorInfo` 另有 `getMessage(context)` 方法把 `ErrorMessage`(string 資源 id + 格式參數)解析成 +在地化字串——即「訊息不是存字串本身,而是存 key + 參數」,這正是研究要求的「user-facing message +key」模式的直接先例。 + +### 3.3 `UserAction`:值得借鏡但不是「錯誤分類」 + +來源: + +(直接讀取確認,共 31 個列舉值,節錄): + +```kotlin +enum class UserAction(val message: String) { + USER_REPORT("user report"), + UI_ERROR("ui error"), + SEARCHED("searched"), + REQUESTED_STREAM("requested stream"), + REQUESTED_CHANNEL("requested channel"), + REQUESTED_PLAYLIST("requested playlist"), + REQUESTED_COMMENTS("requested comments"), + PLAY_STREAM("play stream"), + DOWNLOAD_FAILED("download failed"), + SUBSCRIPTION_UPDATE("subscription update"), + // ……共 31 項 +} +``` + +**重點澄清**:`UserAction` 記錄的是「使用者當下的操作情境」(搜尋、播放、訂閱更新……),**不是** +錯誤本身的分類(網路/限流/風控……)——那個分類在 NewPipe 裡是靠**例外的 Java/Kotlin 類別本身** +表達(見 3.4),`ErrorInfo` 只是把「操作情境」跟「例外物件」打包在一起,方便回報與 log 時同時看到 +「使用者在幹嘛」與「發生了什麼」。**對 FMP 的啟示**:FMP 的統一錯誤型別要處理的是後者(例外分類本 +身),至於「使用者當下在做什麼操作」這種情境資訊,可以是統一錯誤型別之外、由呼叫端(UI/ +Command)附加的另一組 metadata,不必塞進 `sealed class` 的分支設計裡,否則分類會爆炸成「網路 +×操作」的笛卡兒積。 + +### 3.4 NewPipe 用「例外類別階層」做分類,而非「一個大 enum」 + +來源: 的 +`extractor/src/main/java/org/schabi/newpipe/extractor/exceptions/`(直接列出並讀取確認): + +``` +ExtractionException (基底) +├─ ParsingException +│ ├─ ContentNotAvailableException +│ │ ├─ AgeRestrictedContentException (年齡限制) +│ │ ├─ GeographicRestrictionException (地區限制) +│ │ ├─ AccountTerminatedException (帳號被終止,另帶 Reason.UNKNOWN/VIOLATION) +│ │ ├─ PrivateContentException +│ │ ├─ PaidContentException +│ │ ├─ SoundCloudGoPlusContentException +│ │ └─ YoutubeMusicPremiumContentException (皆為「需要付費/VIP」的細分) +│ └─ SignInConfirmNotBotException (YouTube「確認你不是機器人」,見研究二) +├─ ContentNotSupportedException (不支援) +├─ UnsupportedTabException +└─ ReCaptchaException(帶 url 欄位) (風控驗證碼,見研究二) +``` + +這與 Dart 的 `sealed class` 階層設計精神一致:用**型別本身**表達分類與繼承關係(`is +GeographicRestrictionException` 同時滿足「是地區限制」也「是內容不可用」的雙重身分),而不是 +單一 enum 欄位——這點呼應擁有者要求的八分類其實有天然的包含關係(例如「地區限制」與「找不到」在 +NewPipe 裡就是「內容不可用」的兩個具體子分類)。**建議(推測/設計方向)**:FMP 的 `sealed class` +分類可以參考這個層次,讓「找不到」與「地區/版權限制」共享一個中介型別,而不是八個平行、互不相干 +的分支。 + +### 3.5 FMP 統一錯誤型別建議欄位(綜合本節先例,非官方規範) + +依 ADR 0011(結構化錯誤欄位、log 需要音源與網路紀錄關聯)、ADR 0012(每音源宣告限流退避策略、 +每音源列出「憑證無效」判定表)與本節先例,錯誤型別至少要能表達: + +| 欄位 | 對應先例 | 用途 | +|---|---|---| +| 分類(`sealed` 的哪個子型別) | NewPipeExtractor 例外階層 | 網路/限流/需登入/風控/地區/找不到/解析失敗/不支援 | +| 音源 id | `ErrorInfo.serviceId` | ADR 0011 要求 log 帶音源;哪個 dio client 出的錯 | +| `retryable` flag | `ErrorInfo.isRetryable` | 決定要不要進退避重試(見研究二) | +| retry-after 等待時間 | 本研究項目 4 要求 | 來自 HTTP `Retry-After` 或音源自訂節流回應 | +| 使用者訊息 key(非寫死字串) | `ErrorInfo.message`(string 資源 id + 參數) | i18n;FMP 用 slang,key 對應 arb/slang 條目 | +| 原始 error + stackTrace | `ErrorInfo.stackTraces`;Flutter `Result.error` 帶 `Exception` | ADR 0011 錯誤歷史/log 門面要求的欄位 | +| 是否可回報/是否為預期錯誤 | `ErrorInfo.isReportable`;yt-dlp 的 `expected=True/False`(見研究二) | 區分「已知的來源行為」與「真的是 bug,需要診斷包/回報」 | + +## 參考連結彙整 + +- Flutter:、 + +- Dart: +- Riverpod:、 + 、 + 、、 + +- NewPipe: + 、 + +- NewPipeExtractor: + diff --git a/.trellis/tasks/09-27-design-errors/research/retry-and-peers.md b/.trellis/tasks/09-27-design-errors/research/retry-and-peers.md new file mode 100644 index 000000000..0b1c9a881 --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/research/retry-and-peers.md @@ -0,0 +1,380 @@ +# 統一錯誤模型前置研究(二):重試/退避與同類專案比較 + +本檔涵蓋研究項目 4–6:指數退避與 jitter、Dart 重試套件與 dio 攔截器重試模式、`Retry-After` +標頭、並發上限與 token bucket、不該重試的情況;同類開源客戶端(Spotube、Finamp、NewPipe)如何 +分類「自動恢復/提示使用者/只記錄」;風控驗證(B 站 -352/-412、`v_voucher`、geetest)與地區 +限制(YouTube「確認你不是機器人」、年齡/地區限制)的常見處理方式,含 NewPipe 與 yt-dlp 的分類。 +查證方式與標記規則同研究一。 + +## 4. 重試與退避 + +### 4.1 指數退避與 jitter:AWS 官方部落格與可執行原始碼 + +來源:(官方部落格, +四種公式以圖片呈現、頁面文字無法直接擷取數學式,已改用其連結的參考實作確認); + +(`awslabs` 官方帳號下的模擬器倉庫,`src/backoff_simulator.py`,已直接讀取原始碼確認)。 + +確認的四種公式(逐字取自官方模擬器原始碼): + +```python +class Backoff: + def __init__(self, base, cap): + self.base = base + self.cap = cap + def expo(self, n): + return min(self.cap, pow(2, n) * self.base) + +class ExpoBackoff(Backoff): # 無 jitter:純指數 + def backoff(self, n): + return self.expo(n) + +class ExpoBackoffEqualJitter(Backoff): # Equal Jitter:一半固定 + 一半隨機 + def backoff(self, n): + v = self.expo(n) + return v / 2 + random.uniform(0, v / 2) + +class ExpoBackoffFullJitter(Backoff): # Full Jitter:整個區間隨機 + def backoff(self, n): + v = self.expo(n) + return random.uniform(0, v) + +class ExpoBackoffDecorr(Backoff): # Decorrelated Jitter:以上一次結果為基礎 + def __init__(self, base, cap): + Backoff.__init__(self, base, cap) + self.sleep = self.base + def backoff(self, n): + self.sleep = min(self.cap, random.uniform(self.base, self.sleep * 3)) + return self.sleep +``` + +AWS 部落格原文的結論(文字部分可讀取確認):**Full Jitter** 與 **Decorrelated Jitter** 的模擬 +結果最好(在高併發重試下完成總時間最短、對後端造成的請求尖峰最小),純指數退避(無 jitter) +在多個 client 同時重試時會造成「雷鳴群聚」(thundering herd),Equal Jitter 介於兩者之間。 +**建議(推測,供 FMP 設計參考)**:新設計優先選 Full Jitter(實作最簡單、`random.uniform(0, +v)`)或 Decorrelated Jitter(需要保留上一次的 sleep 值當狀態);純指數或無 jitter 不建議用於 +多裝置/多分頁可能同時對同一音源退避的情境。 + +### 4.2 Dart 重試套件現況 + +**`retry`(google/dart-neats)**——來源:(pub.dev API 確認最新版 +`3.1.2`,發布於 `2023-05-16T14:26:11Z`);原始碼 +(直接讀取確認)。 + +```dart +final class RetryOptions { + final Duration delayFactor; // 預設 200ms + final double randomizationFactor; // 預設 0.25(±25%) + final Duration maxDelay; // 預設 30s + final int maxAttempts; // 預設 8 + + const RetryOptions({ + this.delayFactor = const Duration(milliseconds: 200), + this.randomizationFactor = 0.25, + this.maxDelay = const Duration(seconds: 30), + this.maxAttempts = 8, + }); +} +``` + +延遲公式為 `pow(2, attempt) * delayFactor`,再乘上 `(1 ± randomizationFactor)` 的隨機係數;預設 +排程約為 400ms、800ms、1600ms、3200ms、6400ms、12800ms、25600ms(各自再 ±25%),共 8 次嘗試、 +7 次等待。**這個 jitter 風格是「在指數值附近 ±25% 隨機」,跟 AWS 四種公式都不完全相同**(不是 +Equal Jitter 的「一半固定一半隨機」,也不是 Full Jitter 的「整個區間隨機」)——是第三種變體, +選用時不要跟 AWS 的兩個名稱混用。**現況:距今 3 年多沒有新版,屬於停滯但功能單純、程式碼量小 +(單檔)的套件,停滯風險相對低**(推測:功能單純代表也不太需要維護)。 + +**`dio_smart_retry`**——來源:(pub.dev API 確認最新版 +`7.0.1`,發布於 `2024-10-22T03:40:02Z`);原始碼 +(`retry_interceptor.dart`、 +`http_status_codes.dart` 已直接讀取確認)。 + +確認的預設可重試狀態碼集合(逐字取自 `default_retry_evaluator.dart`/`http_status_codes.dart`): + +```dart +const defaultRetryableStatuses = { + status408RequestTimeout, status429TooManyRequests, + status500InternalServerError, status502BadGateway, + status503ServiceUnavailable, status504GatewayTimeout, + status440LoginTimeout, status499ClientClosedRequest, status460ClientClosedRequest, + status598NetworkReadTimeoutError, status599NetworkConnectTimeoutError, + status520WebServerReturnedUnknownError, status521WebServerIsDown, + status522ConnectionTimedOut, status523OriginIsUnreachable, + status524TimeoutOccurred, status525SSLHandshakeFailed, status527RailgunError, +}; +``` + +值得注意這組集合混入了非標準/CDN 專屬碼(IIS 440、nginx 499、AWS ELB 460、Cloudflare +520–527),但不含 501、505–511、526。**確認:`dio_smart_retry` 完全不支援解析 HTTP +`Retry-After` 標頭**——已直接讀原始碼確認package 內沒有任何處理該標頭的程式碼,另用 +`gh api "search/code?q=retry-after+repo:rodion-m/dio_smart_retry"` 搜尋整個倉庫也是零筆命中。 +**對 FMP 的啟示**:若音源(尤其 B 站限流)會回 `Retry-After`,不能直接依賴 +`dio_smart_retry`,需要自己在攔截器裡讀該標頭並覆寫等待時間,或整個重試邏輯自己寫(ADR 0012 +本來就要求「限流與退避策略由音源宣告」,代表本來就不是套用一個套件的預設值就能滿足)。 + +### 4.3 `Retry-After` 標頭處理(推測性設計建議) + +未找到 Dart 生態圈中「開箱即用、正確解析 `Retry-After`(可能是秒數或 HTTP-date 兩種格式)」的 +現成攔截器套件(標**查不到現成套件**)。標頭本身的格式定義屬於 HTTP 規範 +(RFC 9110 §10.2.3,非本次逐字查證重點,僅供 FMP 實作時對照):值可以是整數秒數,也可以是 +HTTP-date 字串。**建議(推測)**:FMP 若要支援它,需自行在音源的錯誤對應攔截器中讀取此標頭、 +解析兩種格式、把結果轉成「retry-after 等待時間」欄位放進統一錯誤型別(見研究一第 3.5 +節),而不是交給任何現成重試套件的預設行為。 + +### 4.4 並發上限與 token bucket + +**`pool`(dart-lang/tools,Dart 團隊官方套件)**——來源:(pub.dev +API 確認最新版 `1.5.3`,發布於 `2026-08-28T20:42:37Z`,非常新,代表持續在維護)。`pool` 提供 +`Pool(maxAllocatedResources)` 語意,可以直接當作「每音源/每主機並發上限」的號誌 +(semaphore):`final resource = await pool.request(); ... resource.release();` 或 +`pool.withResource(() => ...)`。**建議(推測)**:優先用這個現成、官方維護的套件實作「每 host +並發上限」,不需要自己寫號誌;token bucket(限制「單位時間內請求數」而非「同時並發數」)則 +`pool` 本身不直接提供,若音源需要的是速率限制(而非並發上限),需要另外實作簡單的 token +bucket 或改用固定視窗計數器(本次未找到官方/pub.dev 上維護中、對應此需求的現成 Dart 套件,標 +**查不到現成套件**,屬於自己寫的範圍,符合 CLAUDE.md「專案已有依賴 → 成熟套件 → 自己寫」的 +優先序最後一級)。 + +### 4.5 什麼情況不該重試 + +- **HTTP 方法冪等性**——來源: + (MDN,官方詞彙表)。確認冪等方法:GET、HEAD、OPTIONS、TRACE、PUT、DELETE;**非冪等**:POST、 + PATCH、CONNECT。定義原文:「the intended effect on the server of making a single request is + the same as the effect of making several identical requests」。MDN 特別註明這是「意圖」而非 + 伺服器強制保證,且冪等不代表回應內容每次相同(例如 DELETE 重送可能第二次回 404)。 + **對 FMP 的啟示**:非冪等請求(例如「寫入遠端歌單」這類 `AuthRequirement.required` 的 POST + 請求,見 ADR 0012)預設不自動重試,除非該端點本身具備冪等保證(例如帶了去重用的 + idempotency key);純讀取(串流解析、搜尋、詳情)是 GET,可以安全重試。 +- **4xx 語意**(綜合 `dio_smart_retry` 預設集合與一般 HTTP 慣例,推測歸納,非單一權威來源): + `dio_smart_retry` 的預設可重試集合裡幾乎不含標準 4xx(只有 408 Request Timeout、429 Too Many + Requests 兩個是 4xx,其餘都是 5xx 或 CDN 專屬碼)——即業界慣例是「4xx 代表請求本身有問題 + (認證、參數、權限),重送同一個請求不會有不同結果,除非狀態改變(例如 401 先刷新憑證再重 + 送,或 429/408 等等一下再送)」。**對 FMP 的啟示**:統一錯誤型別裡的「需登入/憑證過期」與 + 「找不到」(通常對應 401/403/404)預設不該進入通用重試迴圈,而是先分別導向「刷新憑證後重送 + 一次」(ADR 0012 已定義的 `QueuedInterceptor` 流程)或「直接回報使用者」;只有「限流」 + (429、Retry-After)與部分網路層錯誤(連線逾時、5xx)才進入退避重試。 +- **Riverpod 3 的 `Error`/`ProviderException` 不重試**——見研究一第 2.2 節,這是另一層(provider + 初始化層級)的「不重試」規則,跟 dio 攔截器層级的規則是互補而非重複。 + +## 5. 同類開源客戶端如何分類「自動恢復/提示使用者/只記錄」 + +### 5.1 NewPipe:三層升級式 UI 呈現 + 獨立分類欄位 + +來源: + +(直接讀取原始碼確認)。NewPipe 用同一個 `ErrorInfo`(研究一第 3.2 節)餵給三種呈現方式,依 +情境選擇: + +1. **`showSnackbar`**——非致命、當下有可見的 root view 時的預設做法(例如某個縮圖載入失敗)。 +2. **`createNotification`**——背景 service 執行中,或沒有 root view 可用時;因為系統通知本身是 + 靜默的,程式碼裡同時會補跳一個 `Toast`,確保使用者當下有機會看到。 +3. **`ErrorActivity`/`openActivity`**——只在「前景 activity 開著、且錯誤嚴重到必須中斷」時 + 才使用,是最後手段,會整頁顯示錯誤詳情並提供回報功能。 + +`isReportable` 欄位(見研究一)額外控制「要不要提供回報按鈕」——即使走同一層 UI 呈現, +「已知的、可預期的來源限制」(如地區限制、需要登入)通常 `isReportable = false`(不需要使用者 +回報成 bug),而未分類的例外預設 `isReportable = true`。**歸納(推測)**:NewPipe 的「自動恢復」 +並非由這個錯誤呈現系統處理,而是分散在各個呼叫點自行判斷(例如串流解析失敗時嘗試下一個可用 +的串流來源)——`ErrorInfo`/`ErrorUtil` 本身只負責「呈現」與「是否可回報」,不負責「重試」, +重試邏輯在更上層(各別的 fragment/presenter)依需要各自實作。 + +### 5.2 Finamp:型別比對 + 訊息關鍵字過濾 + 去重 + +來源: + +(注意:Finamp 預設分支是 `redesign` 不是 `main`,已用 `gh api repos/finamp-app/finamp --jq +.default_branch` 確認後直接讀取原始碼)。單一靜態入口 `GlobalSnackbar.error(dynamic event)`, +依「執行期型別+訊息內容」分流,**沒有** sealed 錯誤型別: + +- **只記錄、完全不顯示 UI**(呼叫 `_logger.info(...)` 後直接 `return`):訊息內容符合 + `"Failed host lookup"`、`"HTTP connection timed out"`、任何 `TimeoutException`、 + `"Could not fetch the response for GET"` 的網路類錯誤——這些被視為「暫時性、使用者不需要每次 + 都看到」的雜訊。 +- **顯示給使用者**:其餘所有情況——彈出通用的「發生錯誤」SnackBar,並附「更多」按鈕開啟 + `AlertDialog` 顯示完整錯誤文字;其中 HTTP `401` 會額外對應到專屬的在地化字串 + (`responseError401`),其餘狀態碼共用通用字串(`responseError`)。 +- **去重**:用 `"network:$statusCode:$底層例外執行期型別"`(或非 Response 例外的 + `"network:$執行期型別"`)當 key,記在 `_activeErrorKeys` 集合裡;只要對應的 SnackBar 還沒 + 關閉,同一個 key 的錯誤不會重複彈出,SnackBar 的 `closed` future resolve 後才從集合移除。 +- **沒有內建重試動作**:SnackBar 本身不附「重試」按鈕,恢復與否交給使用者手動操作 + (例如下拉重整)。 + +**對 FMP 的啟示**:Finamp 這種「用字串比對訊息內容來分流」的做法,正是統一錯誤型別要解決的 +問題本身——用 `sealed class` 取代字串比對,才能在編譯期保證涵蓋所有分類,也才能讓「網路類錯誤 +只記錄不顯示」這種規則寫成對 `NetworkError` 型別的一個 `case`,而不是一串脆弱的字串前綴比對。 +去重機制(用「分類+來源」當 key 抑制短時間內重複提示)是值得直接借鏡的模式。 + +### 5.3 Spotube + +本次僅有先前(compaction 前)從 GitHub issue 討論串取得的間接證據(例如錯誤訊息以 stack +trace 形式出現在使用者回報中),未能直接確認 Spotube 目前版本實際的錯誤呈現/Toast 機制原始碼 +位置與邏輯。**標記:查不到**(Spotube 使用 Riverpod + Riverpod 的 `AsyncValue` 錯誤模式,但 +「自動恢復/提示/只記錄」三分法在其程式碼庫的具體實作細節,本次未能在時間內定位到對應檔案並 +直接讀取確認,不列入具引用力的結論,僅供owner知悉此為未覆蓋的比較對象)。 + +### 5.4 三分法歸納(綜合本節,供 FMP 設計參考,推測) + +| 分類 | NewPipe 對應 | Finamp 對應 | FMP 建議方向(推測) | +|---|---|---|---| +| 自動恢復(不打擾使用者) | 呼叫點自行 fallback(換一個串流來源),不經統一呈現層 | 無明顯對應(無自動 fallback 機制) | 限流/暫時性網路錯誤且 `retryable=true`:由重試層處理,只在多次重試後仍失敗才升級成提示 | +| 提示使用者 | `showSnackbar`/`createNotification`/`ErrorActivity`(依情境三選一) | 通用 SnackBar + 詳情 Dialog,401 有專屬文案 | 需登入/風控驗證/地區限制/不支援:這些使用者能採取行動(重新登入、完成驗證、知道不支援)的分類應提示 | +| 只記錄 | `isReportable=false` 時不強調回報,但仍走同一套 UI 呈現(NewPipe 沒有「完全不顯示」這一級) | 特定網路錯誤訊息完全不顯示,只 log | 找不到(單一項目層級的 404,不影響整體操作)、解析失敗但有 fallback 可用時:只記錄,避免每次列表捲動都跳提示 | + +## 6. 風控驗證與地區限制 + +### 6.1 Bilibili:`-352`/`-412`/`v_voucher`/geetest + +**直接原始碼證據(PiliPlus,`bggRGjQaUbCoE/PiliPlus`)**: + +- `lib/http/error_msg.dart`(grep 確認):`const errorMsg = {-352: '风控校验失败,请检查登录 + 状态'};`——**沒有** `-412` 的對應項(間接印證下方「`-412` 回應是 HTML 不是 JSON code」的說法, + 因為若是 JSON code 就會列在這張表裡)。 +- `lib/http/validate.dart`(直接讀取完整原始碼確認)——實作了 `v_voucher` 的兩段式驗證流程: + + ```dart + abstract final class ValidateHttp { + static Future> gaiaVgateRegister(String vVoucher) async { + final res = await Request().post(Api.gaiaVgateRegister, + queryParameters: {if (Accounts.main.isLogin) 'csrf': Accounts.main.csrf}, + data: {'v_voucher': vVoucher}, + options: Options(contentType: Headers.formUrlEncodedContentType)); + if (res.data['code'] == 0) return Success(res.data['data']); + else return Error(res.data['message']); + } + + static Future> gaiaVgateValidate({ + required dynamic challenge, required dynamic seccode, + required dynamic token, required dynamic validate, + }) async { + final res = await Request().post(Api.gaiaVgateValidate, + queryParameters: {if (Accounts.main.isLogin) 'csrf': Accounts.main.csrf}, + data: {'challenge': challenge, 'seccode': seccode, 'token': token, 'validate': validate}); + if (res.data['code'] == 0) return Success(res.data['data']); + else return Error(res.data['message']); + } + } + ``` + + 即:先呼叫 `register` 帶 `v_voucher`拿到 `token`/`challenge`,交給使用者完成 geetest + (`lib/pages/login/geetest/geetest_webview_dialog.dart`,本次僅確認檔案存在、未逐行讀取細節, + 標**部分查不到**:geetest WebView 對話框的具體互動細節未展開),拿到 `validate`/`seccode` + 後呼叫 `validate` 完成驗證。 + +**間接證據(社群文件,非直接讀取確認,標為 推測/間接來源)**:`SocialSisterYi +/bilibili-API-collect` 倉庫的 `docs/misc/sign/v_voucher.md`(本次僅透過 WebSearch 綜合結果得知 +其存在與大致內容,**未直接開啟該檔案逐字確認**,故標記為間接來源)記載的完整流程:`-352` +回應會帶 `v_voucher`;呼叫 register 端點取得 `token`+`challenge`;使用者完成 geetest 驗證得到 +`validate`+`seccode`;呼叫 validate 端點換得 `grisk_id`;用 `grisk_id` 組出 `gaia_vtoken` +(URL 參數)與 `x-bili-gaia-vtoken`(cookie)後重送原始請求。此流程與 PiliPlus 的實際程式碼 +(上方直接確認)在「register → 使用者完成驗證 → validate」三段式上完全吻合,可視為有直接程式碼 +佐證的間接資料。另外社群普遍記載:wbi 簽名的 playurl 請求會多帶 `dm_img_list`/`dm_img_str`/ +`dm_cover_img_str`/`dm_img_inter`(模擬螢幕互動軌跡的參數)與 `gaia_source=pre-load`/ +`isGaiaAvoided=true` 來降低觸發 `-352` 的機率(本節同樣標記為間接來源,未直接讀取該社群文件 +原文確認逐字內容)。 + +`-412`(間接來源,WebSearch 綜合,**查不到直接讀取到的 PiliPlus 或官方文件原始碼佐證**):通常 +代表 IP/頻率觸發的封鎖,持續數分鐘到數小時;即使帶著有效 cookie 也可能被觸發;回應常是 HTML +錯誤頁而非 JSON,代表偵測邏輯必須先檢查 Content-Type/內容形狀,不能直接假設是 JSON 硬解析; +社群建議是不要對 `-352`/`-412`/`-799` 做激進的自動重試(`-799` 代表另一種頻率限制,本次同樣 +僅間接得知,查不到逐字定義來源)。 + +**對 FMP 的啟示(推測)**:「風控驗證」這個分類的錯誤型別,欄位至少要能承載「驗證用的 URL/ +token/challenge」(呼應 NewPipe `ReCaptchaException` 的 `url` 欄位,見研究一第 3.4 +節),且必須明確跟「限流」(`-412`、`-799`,只需要等待與退避)分開——ADR 0012 +已經要求「每個音源明確列出哪些回應代表憑證無效,網路錯誤、限流、風控碼不算」,這條原則同樣 +適用在「風控驗證」不等於「憑證無效」也不等於「限流」,三者是統一錯誤型別裡三個不同的分支。 + +### 6.2 YouTube:「確認你不是機器人」、年齡/地區限制 + +**直接原始碼證據(yt-dlp,`yt-dlp/yt-dlp`,`yt_dlp/extractor/youtube/`)**: + +- `_video.py`(約 4030–4080 行,直接讀取確認):當一支影片沒有可用格式時,依 `reason` + 字串內容分流訊息,並用**同一個** `ExtractorError`(透過 `raise_no_formats`)搭配不同訊息文字 + 呈現三種情境: + - 訊息含 `"sign in"` → 附加登入提示(見下方 `_youtube_login_hint`)。 + - 播放器回應帶 `playerCaptchaViewModel` → 附加「YouTube is requiring a captcha challenge + before playback」。 + - 訊息含 `"This content isn't available, try again later"` → 附加「已被限流最多一小時,建議 + 用 `-t sleep` 加延遲」的說明與 wiki 連結。 + - 若 `subreason` 顯示是地區限制(`"The uploader has not made this video available in your + country"`),則呼叫**獨立的** `raise_geo_restricted`,帶上允許的國家清單。 +- `_base.py`:`_youtube_login_hint` 屬性組出「附上如何匯出 cookie 的 wiki 連結」的完整提示文字; + `_check_login_required` 在音源要求登入但未認證時呼叫 `raise_login_required`。 +- `common.py`(yt-dlp 通用基底類別,直接讀取確認): + + ```python + def raise_login_required(self, msg='...', metadata_available=False, method=NO_DEFAULT): + if metadata_available and (self.get_param('ignore_no_formats_error') + or self.get_param('wait_for_video')): + self.report_warning(msg); return + msg += format_field(self._login_hint(method), None, '. %s') + raise ExtractorError(msg, expected=True) + + def raise_geo_restricted(self, msg='...', countries=None, metadata_available=False): + if metadata_available and (...): + self.report_warning(msg) + else: + raise GeoRestrictedError(msg, countries=countries) + + def raise_no_formats(self, msg, expected=False, video_id=None): + if expected and (...): + self.report_warning(msg, video_id) + elif isinstance(msg, ExtractorError): + raise msg + else: + raise ExtractorError(msg, expected=expected, video_id=video_id) + ``` + + 三個關鍵設計點: + 1. **地區限制有自己專屬的例外子類別**(`GeoRestrictedError`,攜帶 `countries` 清單),而 + 「需要登入」「機器人驗證」「無可用格式」全部共用通用的 `ExtractorError`,只靠訊息文字 + 與 `expected: bool` 旗標區分。 + 2. **`expected` 旗標**——標記「這是已知、會發生的情境」還是「未預期的 bug」,跟 NewPipe 的 + `isReportable`(相反語意:`isReportable=true` 代表未預期)是同一個概念的兩種表達方式。 + 3. **`metadata_available` + `ignore_no_formats_error`/`wait_for_video`**——當已經有部分中繼 + 資料可用時,這三種本來會整個中斷的錯誤(登入、地區限制、無格式)都可以「降級成警告」而不是 + 拋出例外,讓呼叫端可以選擇「有多少資料先顯示多少」。**這是「自動恢復」的一種具體實作模式**: + 不是重試,而是「接受部分結果、把錯誤降級為警告」。 + +**NewPipeExtractor 對應(研究一第 3.4 節已列出階層,此處補分類意義)**: + +- `SignInConfirmNotBotException extends ParsingException`——文件註解原文:「Content can't be + extracted because the service requires logging in to confirm the user is not a bot. Can + usually only be solvable by changing IP (e.g. in the case of YouTube).」——**明確指出這類錯誤 + 在客戶端側幾乎無法自動恢復**(換 IP 不是客戶端能做的事),對應到 FMP 分類應歸類為 + 「風控驗證」而非「需登入」,即使訊息文字看起來像登入提示。 + - **對 FMP 的重要啟示(推測)**:YouTube 的「Sign in to confirm you're not a bot」訊息, + yt-dlp 把它跟真正的「登入才能看」歸在同一個籠統的 `ExtractorError`(只靠訊息文字分流 + UI 提示),但 NewPipeExtractor 把它獨立成一個介於「風控」與「需登入」之間的類別 + (繼承 `ParsingException` 而非 `ContentNotAvailableException`)。這代表這個情境**不完全 + 等同**擁有者定義的「需登入/憑證過期」或「風控驗證」任一個既有分類,而是兩者的交集—— + FMP 設計統一錯誤型別時,這是一個需要擁有者決定「歸類到哪一類、還是兩者都不完全貼切」的 + 具體案例(見最終回報的待決問題)。 +- `GeographicRestrictionException`、`AgeRestrictedContentException`:均繼承 + `ContentNotAvailableException`,與 yt-dlp 把地區限制獨立出來(`GeoRestrictedError`)的做法 + 一致;年齡限制 NewPipeExtractor 有獨立子類別,yt-dlp 這邊本次未特別確認是否也有獨立處理 + (**標記查不到**:本次只確認了地區限制與登入/機器人驗證的 yt-dlp 程式碼路徑,未特別搜尋 + yt-dlp 對年齡限制的專屬處理邏輯)。 + +## 參考連結彙整 + +- AWS:、 + +- Dart 套件(pub.dev API + 原始碼):、 + 、 + 、 + 、 +- MDN: +- NewPipe: + +- NewPipeExtractor: + +- Finamp: + +- PiliPlus:(`lib/http/validate.dart`、 + `lib/http/error_msg.dart`) +- yt-dlp: + 、 + 、 + +- 間接來源(未直接讀取確認,供追蹤):`SocialSisterYi/bilibili-API-collect` 倉庫的 + `docs/misc/sign/v_voucher.md` diff --git a/.trellis/tasks/09-27-design-errors/task.json b/.trellis/tasks/09-27-design-errors/task.json new file mode 100644 index 000000000..aa2589377 --- /dev/null +++ b/.trellis/tasks/09-27-design-errors/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-errors", + "name": "design-errors", + "title": "Design: unified error model", + "description": "Phase-2 item 2: one sealed error taxonomy, where source-specific errors are mapped, who owns retry/backoff/rate limiting, and which errors auto-recover, notify or only log", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From bf4d151323e0fc368e9a067c5bb8e262f9cdaea4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 12:41:57 +0800 Subject: [PATCH 026/133] docs(adr): 0013 unified error model --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 4 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../tasks/09-27-design-errors/implement.md | 6 +- .trellis/tasks/09-27-design-errors/prd.md | 10 ++- .trellis/tasks/09-27-design-errors/task.json | 4 +- docs/adr/0013-unified-error-model.md | 76 +++++++++++++++++++ 6 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 docs/adr/0013-unified-error-model.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 935b542d0..c7442eac4 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡等新功能 | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013) | ## 2. 依賴關係 @@ -116,7 +116,7 @@ flowchart LR | 4 | 6 資料層與相容(✅ 完成,ADR 0010) | 選型(A2)與舊資料自動遷移(A3)是最早的里程碑。 | | 5 | 18 設定與日誌(✅ 完成,ADR 0011) | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | | 6 | 12 網路與帳號(✅ 完成,ADR 0012) | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | -| 7 | 2 錯誤模型 | 音源插件介面的回傳與例外型別要先定。 | +| 7 | 2 錯誤模型(✅ 完成,ADR 0013) | 音源插件介面的回傳與例外型別要先定。 | | 8 | 1 音源插件 | 核心抽象;依賴 10、12、2。 | | 9 | 8 測試與開發環境 | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | | 10 | 17 快取與離線 | 串流 URL、圖片、排行快取的策略,播放核心要用。 | diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index e0c61ac33..159292c55 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -25,7 +25,8 @@ "09-27-design-platform", "09-27-design-data", "09-27-design-settings-logging", - "09-27-design-network-accounts" + "09-27-design-network-accounts", + "09-27-design-errors" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-errors/implement.md b/.trellis/tasks/09-27-design-errors/implement.md index 9574dea55..5d61cfcad 100644 --- a/.trellis/tasks/09-27-design-errors/implement.md +++ b/.trellis/tasks/09-27-design-errors/implement.md @@ -2,6 +2,6 @@ 本任務只產出設計與 ADR。 -- [ ] 寫 `docs/adr/0013-unified-error-model.md`:design.md §1–§6;被否決的選項(沿用多種例外型別、Flutter `Result` 包裝、Riverpod 與網路層雙重重試、在 UI 顯示伺服器原文、在 service 各自重試、做 geetest 驗證互動);「如何確認」(每音源錯誤回應 fixture 對應測試、Riverpod 重試關閉的測試、空 catch lint、i18n 訊息測試)。 -- [ ] `phase2-plan.md` 標記第 2 項完成;第 20 項待辦加入「B 站 geetest 驗證互動」。 -- [ ] 歸檔本任務。 +- [x] 寫 `docs/adr/0013-unified-error-model.md`:design.md §1–§6;被否決的選項(沿用多種例外型別、Flutter `Result` 包裝、Riverpod 與網路層雙重重試、在 UI 顯示伺服器原文、在 service 各自重試、做 geetest 驗證互動);「如何確認」(每音源錯誤回應 fixture 對應測試、Riverpod 重試關閉的測試、空 catch lint、i18n 訊息測試)。 +- [x] `phase2-plan.md` 標記第 2 項完成;第 20 項待辦加入「B 站 geetest 驗證互動」。 +- [x] 歸檔本任務。 diff --git a/.trellis/tasks/09-27-design-errors/prd.md b/.trellis/tasks/09-27-design-errors/prd.md index a4e3a777a..573ca36c0 100644 --- a/.trellis/tasks/09-27-design-errors/prd.md +++ b/.trellis/tasks/09-27-design-errors/prd.md @@ -29,6 +29,12 @@ - R4 使用者看到的訊息一律來自 i18n;部分成功要標出失敗部分;背景工作不跳 toast;同類同源錯誤去重。 - R5 禁止空 catch 與靜默吞錯(lint)。 -## 待確認(見摘要) +## 已決定 -- design.md §5「使用者看到什麼」表。 +- 使用者 2026-09-27 核准 design.md 全文(含 §5「使用者看到什麼」表)。 + +## 驗收標準 + +- [x] design.md 涵蓋分類、轉換位置、傳遞方式、重試分工、呈現規則、不做的項目。 +- [x] `docs/adr/0013-*.md` 依範本寫成。 +- [x] `phase2-plan.md` 標記第 2 項完成並加入待辦。 diff --git a/.trellis/tasks/09-27-design-errors/task.json b/.trellis/tasks/09-27-design-errors/task.json index aa2589377..f9a635db5 100644 --- a/.trellis/tasks/09-27-design-errors/task.json +++ b/.trellis/tasks/09-27-design-errors/task.json @@ -3,7 +3,7 @@ "name": "design-errors", "title": "Design: unified error model", "description": "Phase-2 item 2: one sealed error taxonomy, where source-specific errors are mapped, who owns retry/backoff/rate limiting, and which errors auto-recover, notify or only log", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0013-unified-error-model.md b/docs/adr/0013-unified-error-model.md new file mode 100644 index 000000000..148040b5f --- /dev/null +++ b/docs/adr/0013-unified-error-model.md @@ -0,0 +1,76 @@ +# 0013 — 統一錯誤模型:一個 sealed 分類、音源內轉換、只在網路層重試 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:音源插件的錯誤對應、網路層攔截器、Riverpod 設定、所有錯誤呈現(Toast、曲目狀態、背景工作狀態) + +## 背景 + +舊專案(`docs/audit/errors.md`、`docs/audit/playback.md` §3.6): + +- 自訂例外到畫面一律變成「發生錯誤」,同時 adapter 又把 `e.toString()` 原文丟上畫面;多源搜尋只要一源成功就隱藏其他失敗; + 507 個 catch 中約 70 個是空的。 +- 播放遇限流只重試一次、不退避;電台的網路錯誤顯示成「未開播」;網易任何非 200 都當登入失效。 +- 播放網路錯誤的重試訊號只有一個沒人用的入口接得住。 + +擁有者要求的分類:網路、限流、需登入/憑證過期、風控驗證、地區/版權限制、找不到、解析失敗、不支援;並要回答 +音源特有錯誤在哪裡轉換、重試/退避/限流由誰負責、哪些自動恢復/提示/只記錄。 + +## 考慮過的選項 + +- **沿用多種各自定義的例外型別**:否決,這是舊版呈現混亂的來源。 +- **Flutter 官方指南的 `Result` 包裝**:否決。它為 `ChangeNotifier`+Command 架構設計;本專案用 Riverpod, + `AsyncValue` 已承擔同樣角色,再包一層只增加轉換。 +- **Riverpod 自動重試與網路層重試並存**:否決。Riverpod 3 預設失敗重試 10 次(200ms→6.4s,riverpod.dev/docs/concepts2/retry), + 疊加網路層重試會讓次數相乘。 +- **各 service 自己重試**:否決,策略分散且無法一致退避。 +- **把伺服器或例外原文顯示給使用者**:否決,原文只進 log。 +- **實作 B 站 geetest 驗證互動**:功能凍結期間不做,記入待辦。 + +## 決定 + +1. **分類**:一個 sealed `AppError`: + `NetworkError`、`RateLimited`、`AuthRequired`、`CredentialInvalid`、`VerificationRequired`、 + `Unavailable`(附原因:地區、版權、會員、年齡、只有試聽)、`NotFound`、`ParseError`、`Unsupported`、`UnexpectedError`。 + YouTube 的「確認你不是機器人」歸 `VerificationRequired`(NewPipeExtractor 同樣獨立處理)。 + 共同欄位:音源 id、`retryable`、`retryAfter`、給使用者的 i18n 訊息 key 與參數、`expected`(預期內的不當 bug)、 + 原始 error 與 stackTrace(只進 log、經遮蔽)、對應的網路紀錄 id。 +2. **轉換位置**:網路層把傳輸錯誤轉成 `NetworkError`;**每個音源在自己的目錄內**以對應表把狀態碼與錯誤碼轉成 `AppError` + (含 ADR 0012 的「憑證無效」判定);未知例外在音源邊界包成 `UnexpectedError`。音源邊界以上只看得到 `AppError`。 +3. **傳遞**:音源與 service 丟出 `AppError`;Riverpod provider 以 `AsyncValue.error` 承接,UI 以 exhaustive `switch` 呈現; + 使用者動作由呼叫端捕捉並交給呈現層。所有被處理的錯誤經 log 門面寫入(ADR 0011)。禁止空 catch 與靜默吞錯。 +4. **重試只有一層**:Riverpod 自動重試全域關閉。網路層依音源宣告的策略重試:只重試冪等請求;只重試 `NetworkError`、 + `RateLimited` 與音源標為可重試者;指數退避+全抖動、尊重 `Retry-After`、次數上限預設 2。每個音源有併發上限與最小請求間隔, + 事先避開限流。憑證刷新後重送(ADR 0012)另計。播放層的恢復策略由播放核心的 ADR 定。 +5. **呈現**: + + | 類別 | 自動處理 | 使用者看到 | + |---|---|---| + | 網路 | 網路層重試 | 動作失敗時提示;持續離線顯示離線狀態 | + | 限流 | 退避重試 | 仍失敗才提示「{音源} 請求太頻繁」 | + | 需登入 | — | 提示並附「登入」 | + | 憑證無效 | 刷新一次 | 刷新失敗才提示一次需重新登入 | + | 風控驗證 | — | 提示並建議登入、貼上 cookie 或稍後再試 | + | 無法取得 | — | 曲目上標示原因;播放時跳過並提示 | + | 找不到 | — | 曲目標示「已失效」;播放時跳過並提示 | + | 解析失敗 | — | 提示「{音源} 回應格式改變,可能需要更新」 | + | 不支援/預期外 | — | 通用訊息(視為 bug,可回報) | + + 訊息一律來自 i18n;部分成功要標出失敗的音源或項目;背景工作不跳 toast,只在對應畫面顯示狀態; + 同類別+同音源短時間內只提示一次;開發者模式下提示附「詳細」。 + +採用的慣例:Dart sealed class 窮舉;NewPipe `ErrorInfo`(可重試、可回報、使用者訊息);AWS〈Exponential Backoff And Jitter〉; +Finamp 以「類別+來源」去重;Riverpod 官方的全域 `retry` 設定。 + +## 後果 + +- 好的:使用者看到的訊息一致且可翻譯;每個音源的錯誤行為可用 fixture 測試;重試次數可預期;修正審計的 G4、G5、C5、C6、D5、D10。 +- 壞的:每個音源要維護錯誤對應表;新增錯誤原因時要改 sealed 型別與所有 exhaustive `switch`(這正是想要的強制)。 +- 之後要注意:Toast 的外觀與「詳細」內容由 Toast 的設計定;播放層跳過與停止的條件由播放核心的 ADR 定; + B 站 geetest 驗證互動列在功能凍結待辦。 + +## 如何確認 + +- 契約測試:每個音源以錄下的錯誤回應 fixture,斷言對應到的 `AppError` 類別。 +- 測試:`ProviderScope` 的 retry 為關閉;網路層只對冪等請求重試、尊重 `Retry-After`。 +- lint:禁止空 catch;禁止在 UI 顯示 `toString()` 之類的原文(以只接受 i18n key 的呈現 API 在型別上擋住)。 From 069ec48dccb200e73e5b782a84dd5496c6c1439c Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 12:41:58 +0800 Subject: [PATCH 027/133] chore(task): archive design-errors --- .../{ => archive/2026-09}/09-27-design-errors/check.jsonl | 0 .../tasks/{ => archive/2026-09}/09-27-design-errors/design.md | 0 .../{ => archive/2026-09}/09-27-design-errors/implement.jsonl | 0 .../{ => archive/2026-09}/09-27-design-errors/implement.md | 0 .../tasks/{ => archive/2026-09}/09-27-design-errors/prd.md | 0 .../09-27-design-errors/research/error-model-patterns.md | 0 .../2026-09}/09-27-design-errors/research/retry-and-peers.md | 0 .../tasks/{ => archive/2026-09}/09-27-design-errors/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/research/error-model-patterns.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/research/retry-and-peers.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-errors/task.json (92%) diff --git a/.trellis/tasks/09-27-design-errors/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-errors/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-errors/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-errors/check.jsonl diff --git a/.trellis/tasks/09-27-design-errors/design.md b/.trellis/tasks/archive/2026-09/09-27-design-errors/design.md similarity index 100% rename from .trellis/tasks/09-27-design-errors/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-errors/design.md diff --git a/.trellis/tasks/09-27-design-errors/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-errors/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-errors/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-errors/implement.jsonl diff --git a/.trellis/tasks/09-27-design-errors/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-errors/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-errors/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-errors/implement.md diff --git a/.trellis/tasks/09-27-design-errors/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-errors/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-errors/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-errors/prd.md diff --git a/.trellis/tasks/09-27-design-errors/research/error-model-patterns.md b/.trellis/tasks/archive/2026-09/09-27-design-errors/research/error-model-patterns.md similarity index 100% rename from .trellis/tasks/09-27-design-errors/research/error-model-patterns.md rename to .trellis/tasks/archive/2026-09/09-27-design-errors/research/error-model-patterns.md diff --git a/.trellis/tasks/09-27-design-errors/research/retry-and-peers.md b/.trellis/tasks/archive/2026-09/09-27-design-errors/research/retry-and-peers.md similarity index 100% rename from .trellis/tasks/09-27-design-errors/research/retry-and-peers.md rename to .trellis/tasks/archive/2026-09/09-27-design-errors/research/retry-and-peers.md diff --git a/.trellis/tasks/09-27-design-errors/task.json b/.trellis/tasks/archive/2026-09/09-27-design-errors/task.json similarity index 92% rename from .trellis/tasks/09-27-design-errors/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-errors/task.json index f9a635db5..0e5345594 100644 --- a/.trellis/tasks/09-27-design-errors/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-errors/task.json @@ -3,7 +3,7 @@ "name": "design-errors", "title": "Design: unified error model", "description": "Phase-2 item 2: one sealed error taxonomy, where source-specific errors are mapped, who owns retry/backoff/rate limiting, and which errors auto-recover, notify or only log", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From d83e83a191a704ba2e510280a9c4ac2289a3bb05 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 13:45:44 +0800 Subject: [PATCH 028/133] chore(task): plan phase-two item 1 (script source plugins) --- .../09-27-design-source-plugins/check.jsonl | 0 .../09-27-design-source-plugins/design.md | 103 +++++ .../implement.jsonl | 0 .../09-27-design-source-plugins/implement.md | 10 + .../tasks/09-27-design-source-plugins/prd.md | 46 ++ .../capability-modeling-and-matching.md | 368 +++++++++++++++ .../research/peer-plugin-interfaces.md | 432 ++++++++++++++++++ .../09-27-design-source-plugins/task.json | 26 ++ 8 files changed, 985 insertions(+) create mode 100644 .trellis/tasks/09-27-design-source-plugins/check.jsonl create mode 100644 .trellis/tasks/09-27-design-source-plugins/design.md create mode 100644 .trellis/tasks/09-27-design-source-plugins/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-source-plugins/implement.md create mode 100644 .trellis/tasks/09-27-design-source-plugins/prd.md create mode 100644 .trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md create mode 100644 .trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md create mode 100644 .trellis/tasks/09-27-design-source-plugins/task.json diff --git a/.trellis/tasks/09-27-design-source-plugins/check.jsonl b/.trellis/tasks/09-27-design-source-plugins/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-source-plugins/design.md b/.trellis/tasks/09-27-design-source-plugins/design.md new file mode 100644 index 000000000..2dfb1d624 --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/design.md @@ -0,0 +1,103 @@ +# 設計:音源插件化(腳本插件) + +採用的慣例:MusicFree、LX Music 的 JS 腳本插件(使用者可安裝的來源);Spotube 的 manifest 宣告能力與 API 版本、 +iOS 以側載發佈;Flutter federated plugin 的「一套介面、多種實作」;Spotube 的匹配結果快取與使用者改選。 +參考其他專案只看設計,不複製程式碼(MusicFree 為 AGPL-3.0)。 + +## 1. 形狀 + +```mermaid +flowchart TB + UI[UI 與 service
    只認 SourcePlugin 介面與能力宣告] --> REG[插件註冊表] + REG --> SP1[ScriptSource:bilibili.js] + REG --> SP2[ScriptSource:netease.js] + REG --> SP3[ScriptSource:youtube.js
    或暫時的 Dart 實作] + REG --> SP4[ScriptSource:使用者安裝的腳本] + subgraph 宿主(App) + RT[JS 執行環境 flutter_js
    QuickJS / JavaScriptCore] + HOST[宿主 API v1
    http、crypto、storage、log、login] + NET[網路層 ADR 0012/0013] + end + SP1 & SP2 & SP3 & SP4 --> RT --> HOST --> NET +``` + +- **一套介面 `SourcePlugin`**:App 其他部分只認它與能力宣告,分不出來源是哪個、是不是腳本。 +- **所有來源都是 JS 腳本**:可播放音源(B 站、網易、YouTube)、僅元資料來源(Spotify、QQ 匯入)、歌詞源(網易、QQ、lrclib)。 + 內建腳本隨 App 打包在 assets,標為「內建」,可停用不可刪除;使用者安裝的腳本不得使用內建腳本的 id。 +- **YouTube 例外的退路**:可行性驗證失敗時,YouTube 暫時以 Dart 實作同一個 `SourcePlugin` 介面;找到解法後換回腳本。 +- **腳本引擎**:`flutter_js`(Android/Windows/Linux 用 QuickJS,iOS/macOS 用 JavaScriptCore)。腳本以 ES2020 JS 撰寫;作者可用 TypeScript 再打包。 + +## 2. manifest(每個腳本一份) + +| 欄位 | 說明 | +|---|---| +| `id`、`name`、`version`、`author`、`homepage` | 識別與顯示;`id` 是音源 id(ADR 0001 的字串 id 沿用) | +| `apiVersion` | 宿主 API 版本;不相容時拒絕載入並顯示原因 | +| `capabilities` | 見 §3 | +| `domains` | 允許連線的網域清單;宿主 HTTP 只放行這些 | +| `login` | 支援的登入方式與所需資料(WebView 登入網址與要讀的 cookie 名、QR 流程、貼上 cookie 需要的欄位與說明) | +| `retryPolicy`、`rateLimit` | 重試次數、可重試的錯誤、併發上限、最小請求間隔(ADR 0013) | +| `redaction` | 追加的遮蔽名單:cookie/header/參數名、CDN 網域(ADR 0011) | +| `defaults` | 例如「以登入身分瀏覽與播放」的預設值(ADR 0012) | +| `icon` | 顯示用圖示 | + +## 3. 能力 + +| 能力 | 意思 | +|---|---| +| `search` | 搜尋曲目(可再宣告支援的搜尋類型與排序) | +| `resolveStream` | 由曲目取得可播放的串流(含 headers、到期時間、音質、格式、是否試聽) | +| `trackDetail` | 曲目詳情 | +| `multiPart` | 一個項目含多個分 P(B 站 cid,ADR 0005) | +| `importPlaylist` | 以網址匯入歌單(宣告可處理的網址樣式) | +| `libraryRead` | 讀取使用者的收藏夾與私人歌單(需登入) | +| `libraryWrite` | 建立歌單、加入/移除曲目(需登入) | +| `charts` | 排行/探索 | +| `live` | 直播/電台(開播狀態、直播串流) | +| `mix` | 推薦或無限播放佇列 | +| `lyrics` | 搜尋歌詞候選、取得歌詞(逐字/逐行時間軸、翻譯) | +| `login` | 由 manifest 的 `login` 欄位宣告方式 | + +- 可播放音源:有 `resolveStream`。僅元資料來源:有 `search` 或 `importPlaylist` 但沒有 `resolveStream`。歌詞源:只有 `lyrics`。不另立型別。 +- 下載不是插件能力:凡是 `resolveStream` 回傳可下載格式的,下載由宿主處理(第 11 項)。 +- UI 依能力顯示入口;同一個能力由多個來源提供時(例如搜尋、排行),UI 列出所有提供者,不寫死任何一個。 + +## 4. 宿主 API v1(腳本能用的全部) + +| API | 說明 | +|---|---| +| `http.request` | 經網路層發出(ADR 0012/0013):帶 `authRequirement`、只能連 manifest 的網域、統一重試與限流、網路紀錄與遮蔽;回傳狀態、headers、body | +| `crypto` | MD5、SHA、HMAC、AES(CBC/ECB)、RSA、Base64 等,涵蓋網易 weapi/eapi 與 B 站 WBI 所需 | +| `storage` | 每個插件自己的鍵值儲存(非機密,例如 WBI 金鑰快取、匿名 `buvid`) | +| `credentials` | 只能讀自己音源的憑證欄位(例如 B 站寫入需要的 `bili_jct`);不能讀其他音源 | +| `log` | 經 log 門面(ADR 0011),tag 為插件 id | +| `errors` | 腳本丟出 `{ category, code, message, retryAfter }`,宿主轉成 `AppError`(ADR 0013);分類對應表寫在腳本裡 | + +沒有檔案系統、沒有任意 socket、沒有其他插件的資料。資料交換一律是 JSON DTO(曲目、歌單、串流結果、歌詞候選…), +以 `apiVersion` 版本化;宿主提供 TypeScript 型別定義檔。 + +## 5. 安裝與信任 + +- 從檔案或網址安裝;安裝前顯示 manifest:名稱、作者、能力、**會連的網域**,並警告「此腳本會以你的登入身分存取這些網站」。 +- 更新:重新安裝新版本(自動檢查插件更新列入第 20 項待辦)。 +- 停用與移除:移除時一併清除該插件的 storage 與憑證。 +- Debug 頁提供「音源健康檢查」:對每個插件跑一組基本呼叫(第 4、8 項)。 + +## 6. 匹配流程(宿主統一) + +- **一份共用評分核心**:標題、歌手(正規化後的相似度)、時長(容差內加分)、歌詞時另加同步歌詞加分。歌單匯入與歌詞都用它,不再各有一套。 +- **跨來源比較**:對所有啟用的目標來源同時搜尋,取分數最高者,不在第一個命中時就停;分數相同依使用者排序的來源優先序。 +- **目標來源集合**:由使用者設定(啟用的可播放來源與順序);自動匹配與手動重搜用同一個集合。 +- **使用者可改選**:匹配結果持久化;使用者改選後標為手動,之後不再自動重算。 +- **匹配失敗**:保留該項目並標示「未匹配」,可手動搜尋;不靜默丟棄。 + +## 7. 對其他 ADR 的影響 + +- ADR 0008「搬運葉節點邏輯」:音源邏輯改為**以舊 Dart 程式碼為規格、用 JS 重寫**;非音源的葉節點(`TrackKey` 格式等)仍照搬。ADR 0008 加註。 +- 第 8 項:契約測試要能對腳本插件以錄下的 HTTP 回應重播執行;插件作者也能在本機跑。 + +## 8. 第一個里程碑與可行性驗證 + +- 第一個里程碑的 tracer bullet 用一個腳本音源(哪一個在里程碑規劃時定)完成搜尋與播放,同時建立 JS 執行環境、宿主 API 的最小集合、腳本契約測試的雛形。 +- **YouTube 可行性驗證(有時限)**:YouTube.js(MIT,官方只寫支援 Node.js、Deno、瀏覽器)在 `flutter_js` 裡能否搜尋並解出可播放串流;它需要宿主提供 `fetch` 與 eval。時限內失敗則 YouTube 暫以 Dart 實作。 +- `flutter_js` 在 Android 與 Windows 上的非同步(Promise)、記憶體與啟動成本實測。 diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.jsonl b/.trellis/tasks/09-27-design-source-plugins/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.md b/.trellis/tasks/09-27-design-source-plugins/implement.md new file mode 100644 index 000000000..d208f5dd3 --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/implement.md @@ -0,0 +1,10 @@ +# 執行計畫 + +本任務只產出設計與 ADR。 + +- [ ] 寫 `docs/adr/0014-script-source-plugins.md`:design.md §1–§8;被否決的選項(編譯期 Dart 插件、先 Dart 後轉腳本、hetu_script、允許腳本讀其他音源憑證或檔案系統、各功能各自的匹配評分);「如何確認」(能力宣告與介面一致的結構測試、腳本重播契約測試、網域清單強制的測試、UI 無音源分支的 lint)。 +- [ ] ADR 0008 加註:音源邏輯改以舊程式碼為規格、用 JS 重寫(見 ADR 0014)。 +- [ ] `phase2-plan.md` 標記第 1 項完成,第一個里程碑必要驗證加入 YouTube 可行性驗證與 flutter_js 實測,並記下腳本插件是解除功能凍結的例外。 +- [ ] 歸檔本任務。 + +驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-source-plugins/prd.md b/.trellis/tasks/09-27-design-source-plugins/prd.md new file mode 100644 index 000000000..d417ed1c3 --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/prd.md @@ -0,0 +1,46 @@ +# 設計第 1 項:音源插件化 + +## 目標 + +單一註冊點、音源宣告能力;新增音源=新增一個目錄+註冊一行;UI 依能力自動出現入口;UI 與 service 沒有針對特定音源的分支。 +區分可播放音源、僅元資料(匯入)音源、歌詞源,統一匹配流程。 + +需求來源:parent `prd.md` 階段二第 1 項;`questions.md` G3、E5、B3、B11、B14、D4、D9(按推薦);ADR 0009–0013 已定的音源插件義務: +遮蔽名單(0011)、API client 與 `AuthRequirement`、登入方式、憑證無效判定(0012)、錯誤對應表與重試策略(0013)。 + +## 現況(證據) + +- 舊版已有小介面(`SourceCapability` 系列),三個 adapter 各自 `implements` 一組(`docs/audit/sources.md` §1–§2)。 +- 問題不在介面形狀,而在繞過:新增一個音源最少改 15 檔、同網易程度約 54 檔;50 處音源分支散在 28 檔;電台、Mix、遠端歌單寫死特定音源(`sources.md` §3–§4)。 +- 匹配:歌單匯入與歌詞各有一套評分,自動匹配與手動重搜用不同的音源集合;歌詞「命中即停」不跨源比較(`sources.md` §5)。 + +## 研究結論(`research/peer-plugin-interfaces.md`、`research/capability-modeling-and-matching.md`) + +- 同類專案共通能力:搜尋、串流解析、登入、歌詞;多數加收藏/匯入。MusicFree(AGPL-3.0)、LX Music(Apache-2.0)用 JS 腳本插件;Spotube(BSD-4-Clause)有插件系統;Listen1 為 provider 物件。 +- 腳本插件的價值在於「使用者自行安裝來源、免發版修補」;代價是安全、除錯、測試、iOS Guideline 2.5.2(不得下載執行程式碼)風險。 +- Dart 能力宣告:能力列舉(給 UI)+每個能力一個小介面(給型別系統),並用結構測試檢查兩者一致。先例 AetherTune(0BSD;2026-07 建立、2 星,僅作參考)。 +- 匹配:Spotube 以快取+使用者可改選處理元資料→音訊的匹配;同類專案都沒有自動評分的歌詞匹配,FMP 舊版是唯一做評分的。 +- 契約測試:Dart 生態沒有現成框架;以共用 test helper+各音源 fixture 落地。 + +- 腳本引擎:`flutter_js` 0.8.7(2026-01,五平台:QuickJS/JavaScriptCore);`hetu_script` 0.6.4(Spotube 採用,Dart 風格小眾語言)。YouTube.js(MIT,2026-09 仍維護)官方只寫支援 Node.js、Deno、瀏覽器,解密需宿主提供 eval 與 fetch。 + +## 已決定 + +- D1(使用者 2026-09-27):採**執行期 JS 腳本插件**,並**納入這次重寫**(為此項明確解除功能凍結)。目的是讓使用者能以 AI Agent 生成並安裝自己的音源;不上架任何商店。 +- D2(使用者 2026-09-27):**內建音源現在就全部做成腳本**(B 站、網易、YouTube、Spotify/QQ 匯入、歌詞源);YouTube 先做有時限的可行性驗證,失敗則暫以 Dart 實作同一介面。 +- 其餘依研究寫入 design.md:JS(非 hetu)、宿主 API 範圍、manifest、安裝時顯示網域並警告、統一匹配流程。 + +## 需求 + +- R1 一套 `SourcePlugin` 介面;App 其他部分只認介面與能力宣告,沒有針對特定音源的分支。 +- R2 所有來源是 JS 腳本+manifest;內建腳本隨 App 打包。新增音源=新增一個腳本(使用者可自行安裝)。 +- R3 腳本只能經宿主 API 動作:網路請求一律經網路層並受網域清單限制;憑證只能讀自己音源的;沒有檔案系統。 +- R4 能力宣告驅動 UI;僅元資料來源與歌詞源以能力區分,不另立型別。 +- R5 匹配用一份共用評分核心、跨來源比較、使用者可改選且改選後不重算、失敗項目保留並標示。 +- R6 腳本插件可用錄下的 HTTP 回應跑契約測試。 + +## 驗收標準 + +- [ ] design.md 涵蓋介面形狀、manifest、能力、宿主 API、安裝與信任、匹配流程、對其他 ADR 的影響、第一個里程碑與 YouTube 驗證。 +- [ ] `docs/adr/0014-*.md` 依範本寫成;ADR 0008 加註音源邏輯改為 JS 重寫。 +- [ ] `phase2-plan.md` 標記第 1 項完成;記下 YouTube 可行性驗證與 flutter_js 實測;記下「腳本插件」為解除凍結的例外。 diff --git a/.trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md b/.trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md new file mode 100644 index 000000000..7c04e88b7 --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md @@ -0,0 +1,368 @@ +# 研究:Dart 能力宣告慣用法、可播放來源比對、歌詞來源抽象、契約測試 + +> 對應 `.trellis/tasks/09-27-design-source-plugins` 研究第 3–6 點。 +> 查證方式:官方文件(WebFetch)與 `curl`/`gh api` 直讀原始碼(一手 +> 來源)。查不到的一律寫「查不到」,推論一律標「推測」。查證時間 +> 2026-09-27。與 `peer-plugin-interfaces.md` 引用同一批專案,LICENSE +> 已在該文件列出,此處不重複。 + +--- + +## 第 3 點:Dart/Flutter 生態系宣告「可選能力」的慣用法 + +FMP 需要的能力清單包含:搜尋、串流解析、歌單匯入、登入、收藏同步、 +遠端歌單編輯、排行/探索、電台/直播、推薦/Mix、歌詞、下載——十種 +左右,且不是每個音源都全部支援。以下是三種真實存在的做法。 + +### 3.1 一個大介面 + 全部可選方法(MusicFree 風格,Dart 對照) + +Dart 沒有「全部方法可選」的介面語法(TS 的 `method?: Fn` 在 Dart 裡要 +嘛用 `Fn?` 型別欄位,要嘛全用 `mixin` 預設實作)。若照抄 MusicFree +的形狀,Dart 版大概是一個大 abstract class,非必要方法給 +`UnimplementedError` 的預設實作,能力靠 `is` 或執行期呼叫時 +`try/catch UnimplementedError` 判斷——**這個做法在 Dart 生態系找不到 +真實先例**(查不到任何知名 Flutter 套件採此形狀),推測是因為 Dart的 +靜態型別檢查讓「呼叫了不支援的方法才在執行期爆炸」的代價比 TS/JS +更不划算:TS 的可選方法呼叫端至少會被 `method?.()` 強制寫可選鏈, +Dart 沒有對應的介面層級強制。**不建議 FMP 採用**。 + +### 3.2 能力列舉 + 一個核心介面 + 可選擴充介面,用 `is` 檢查 +(AetherTune 風格,`peer-plugin-interfaces.md` 1.5 已詳列程式碼) + +- 核心介面只放「每個來源都一定要有」的最小方法集合 + (`id`、`name`、`capabilities`、`search()` 等)。 +- 每個可選能力對應**一個獨立的小介面**(`MusicSourceSearchPagingProvider` + 等),實作者需要該能力就額外 `implements` 那個介面。 +- 執行期用 `provider is XxxProvider` 判斷這個實例是否真的提供了某個 + 可選能力的方法簽章。 +- **關鍵優點**:`capabilities` 集合是宣告(給 UI/設定頁用的「這個 + 來源支援什麼」清單),`is` 檢查是型別系統保證(呼叫端在拿到 + `provider as XxxProvider` 後,編譯期就能保證方法存在,不會呼叫到不 + 存在的方法)——兩者是分開但可交叉驗證的兩層,AetherTune 的 + `validateMusicSourceProviderContract`(見第 6 點)正是拿這兩層互相 + 核對,抓「宣告了某能力但沒 implements 對應介面」這種不一致。 + +### 3.3 聯邦式 Flutter 外掛(`PlatformInterface`)——宣告的是「平台」不是「能力」 + +官方文件: + +(WebFetch 一手來源,Flutter 官方頁)。 + +三層角色:app-facing 套件(開發者直接 import 的 API)/platform +interface 套件(定義抽象 API 的 base class)/platform 實作套件 +(各平台各自實作)。核心機制: + +- `PlatformInterface` 基底類別的 `verifyToken()`:**強制實作方用 + `extends`,禁止 `implements`**(防止實作方繞過基底類別未來新增的 + 方法而不出現編譯錯誤——這其實是一種「向前相容」保護,跟本任務要 + 解決的「能力宣告」問題方向不同)。 +- 每個平台實作透過靜態 `instance` getter/setter 註冊自己;純 Dart + 實作用 `registerWith()` 靜態方法。 +- pubspec.yaml 的 `platforms` map 用 `implements`/`pluginClass`/ + `dartPluginClass`/`default_package` 宣告「這個套件替哪個平台提供 + 哪個介面的哪個實作」。 + +**這個模式解決的是「同一份 API,不同平台各自實作,且不見得每個 +API 呼叫都由套件強制檢查平台支援」的問題**,官方文件只講到「宣告 +支援的平台」層級,沒有更細的「這個平台支援哪些子能力」機制——換句 +話說,federated plugin 本身沒有比 3.2 更細的能力宣告顆粒度, +對「一個音源支援搜尋但不支援登入」這種同平台內的部分能力沒有直接 +幫助,但它示範的「一個抽象契約套件,被多個實作各自依附」結構, +與 FMP 想要的「音源目錄」結構是同一個精神:**平台實作套件對應到 FMP +的「一個音源一個目錄」,platform interface 套件對應到 FMP 要建的 +「音源契約」介面本身**。 + +### 3.4 動態、依當下狀態變化的能力宣告(`audio_service` 的 `MediaControl`) + +`audio_service/lib/audio_service.dart` + +(第 140 行 `class PlaybackState`): + +```dart +/// The list of currently enabled controls which should be shown in the media +/// notification. +final List controls; // 第 168 行 + +/// The set of system actions currently enabled. ... +final Set systemActions; // 第 196 行 +``` + +`MediaControl`(第 835 行)本身是一組**靜態常數實例** +(`MediaControl.stop`/`.pause`/`.play`/`.rewind`/`.skipToNext`/ +`.skipToPrevious`/`.fastForward`,各帶 `androidIcon`/`label`/ +`MediaAction action`),另有 `.custom()` 建構子接受 +`CustomMediaAction? customAction` 做自訂動作。 + +這與 AetherTune 的 `Set` 本質不同: +`PlaybackState.controls`/`systemActions` 是**每次播放狀態更新都可能 +變動**的「現在這一刻允許哪些操作」(例如正在緩衝時可能拿掉快轉), +是**動態、依情境變化**的能力宣告;AetherTune 的能力集合是**靜態、依 +音源本身**、跟播放狀態無關的能力宣告。 + +### 3.5 建議:FMP 採 3.2(AetherTune 風格)為主幹,3.4 的思路用在播放層 + +- **音源層**(本任務範圍):採 AetherTune 風格——一個 + `SourceCapability` enum(列出全部十種能力)+一個核心 + `MusicSourcePlugin`/`Source` 介面(放搜尋等每個音源都有的最小 + 集合)+每個可選能力一個獨立小介面,執行期用 `is` 檢查。這個形狀 + 同時滿足擁有者「UI 依宣告能力自動出現入口」(讀 `capabilities` + 集合)與「服務層無音源分支」(呼叫端用 `is` 拿到有型別保證的可選 + 介面,不用 `switch (sourceId)`)兩個要求。 +- **能力顆粒度**:不要學 Spotube 的 4 種粗顆粒(會逼著把「搜尋」跟 + 「串流解析」這種明顯該分開的能力擠在一起),也不要學 MusicFree + 的「有實作就算」(Dart 有更好的型別系統可用,沒必要退化成執行期 + 觀察);抓 AetherTune 的 19 種量級,依 FMP 需求清單(搜尋、串流 + 解析、匯入、登入、收藏同步、遠端歌單編輯、排行/探索、電台/ + 直播、推薦/Mix、歌詞、下載,共 11 類,部分再拆子項如「收藏讀取」 + vs「收藏寫入」)逐一列舉即可,不需要更抽象的通用機制。 +- **播放層(超出本任務範圍,供交接)**:`audio_service` 的 + `MediaControl`/`systemActions` 動態宣告模式是既有播放核心 + (`AudioController`,見 `AGENTS.md` 邊界章節)已經在用的機制 + (`audio_service` 已是 FMP 的既有依賴),不需要因為本任務而改動; + 音源層的靜態能力宣告與播放層的動態控制宣告是兩層不同的關注點, + 不應該合併成同一個模型。 + +--- + +## 第 4 點:metadata-only 來源比對可播放來源 + +### 4.1 Spotube 的演算法(`peer-plugin-interfaces.md` 1.1 已列出介面, +此處聚焦比對邏輯本身) + +檔案:`lib/services/sourced_track/sourced_track.dart` + + +流程: + +1. `SourcedTrack.fetchFromTrack()`:先查 drift 的 `sourceMatchTable` + 有沒有這首 Spotify 曲目對這個音源外掛的快取比對結果,有就直接用 + 快取結果去解析串流(`audioSource.streams(cachedMatch)`),**不重新 + 搜尋、不重新評分**。 +2. 沒快取才呼叫 `fetchSiblings()` → 外掛的 `matches(track)`(見 + `MetadataPluginAudioSourceEndpoint`)取得候選清單。 +3. 評分只在**非純英文標題**時才跑(`ServiceUtils.onlyContainsEnglish` + 判斷),純英文標題直接信任外掛回傳的搜尋排序,不額外評分——這是 + 一個實用但也可能引入偏差的捷徑(推測:可能是因為英文搜尋引擎/ + YouTube 搜尋排序本身對英文查詢已經夠準,不需要二次加權)。 +4. 評分公式 `rankResults()`——**純字串比對/正則,完全不看時長**: + - 候選標題含藝人名 +1、候選藝人清單含該藝人(小寫完全相等)+1 + (對每個 Spotify 藝人各算一次,可疊加); + - 候選標題含曲名 +3; + - 候選標題命中「官方MV/官方音檔/官方歌詞影片/視覺化」正則 + +1,且該正則命中同時標題又含曲名時再 **+2**(疊加獎勵「官方 + 頻道的正確曲目」這個最常見的正確答案形狀); + - 依分數由高到低排序,取第一名寫入快取。 +5. 使用者可以手動 `swapWithSibling()` 選其他候選,這個動作會**刪除 + 舊快取列、寫入新列(`InsertMode.replace`)**,下次直接沿用使用者 + 選的結果——即人工修正是「覆蓋快取」而非另開一張表,往後同一首歌 + 都不會再自動重新評分。 + +**關鍵設計取捨**:Spotube 完全不用時長作比對訊號,只信任「標題/ +藝人字串相似度 + 官方標記」;比對結果快取後即凍結,除非使用者手動 +換源。 + +### 4.2 FMP 舊版比對問題(`docs/audit/sources.md` §5,已讀取確認) + +FMP 舊版其實**有**時長比對,且複雜度遠高於 Spotube,但正是這個複雜度 +帶來了問題(`docs/audit/sources.md:391-467`): + +- **雙重實作、行為不一致**:歌單匯入的自動比對 + (`playlist_import_service.dart`)與歌詞匹配 + (`lyrics_auto_match_service.dart`)是兩套完全獨立的評分函式 + (`_calculateRelevanceScore` vs. `_selectBestMatch`),權重、門檻、 + 相似度演算法(N-gram/Jaccard vs. Levenshtein)都不同,同一個「這 + 是不是同一首歌」的問題在 FMP 裡有兩個不同答案的來源。 +- **自動比對與手動重搜不一致**:歌單匯入的自動比對只搜 YouTube+ + Bilibili(`docs/audit/sources.md:403` 註解承認網易雲被排除),但 + 使用者手動重搜 `searchForTrack` 卻搜「全部已註冊音源」且**只依 + 播放量排序、完全不打分**(`:414`, `:1163-1179`)——同一個 UI 動作 + 的「自動」與「手動」路徑用不同的音源集合、不同的排序邏輯,使用者 + 完全無法預期兩者為何給出不同結果。 +- **文件與程式碼不一致**:歌詞比對的類別註解宣稱「只有一個候選 + 結果符合時長條件時才自動匹配」,但實際程式碼在多筆候選時一樣會 + 跑 `_selectBestMatch` 選一筆(`:467`)——即文件描述的「保守」行為 + 與程式碼實際的「總是自動選一個」行為不符。 +- **來源優先序寫死在比對邏輯裡**:歌詞比對用「命中就停」 + (`:461`,依 `lyricsSourcePriority` 逐源查,第一個有結果的就用), + 沒有跨來源比較所有候選再挑最好的,等於「最先查到的來源」比 + 「品質最好的來源」優先權更高。 + +### 4.3 建議設計:統一比對流程 + 明確區分兩種音源角色 + +依擁有者要求,音源要分「可播放來源」「metadata-only/匯入專用來源 +(必須比對到可播放來源)」「歌詞來源」三種角色,且要有**統一**的 +比對流程。建議: + +1. **用能力宣告表達角色,不用另一套型別階層**:一個來源可能同時 + 宣告 `metadataSearch`(能查到「有這首歌」但不一定能播)與 + `streamResolution`(能解出播放網址)——**沒有 `streamResolution` + 能力的來源,就是 metadata-only/匯入專用來源**,不需要額外的 + `MetadataOnlySource` 標記型別;这直接對應 AetherTune 把 + `streamResolution` 與 `directPlayback` 分開列舉的做法(見 + `peer-plugin-interfaces.md` 1.6 的表格結論)。 +2. **比對邏輯只寫一份,供匯入與歌詞共用比對評分核心**:把 + 「候選清單 → 加權評分 → 門檻過濾 → 排序取前 N」抽成一個共用函式, + 参數化輸入(標題、藝人、時長、優先旗標如「官方」)與權重,匯入 + 流程和歌詞比對都呼叫同一份,避免舊版兩套邏輯各自演化、行為 + 分岔的問題重演。是否要完全比照 Spotube 拿掉時長訊號,還是保留 + 舊版的時長過濾但修掉「兩套不同門檻」的不一致,**是需要擁有者 + 決定的產品行為**(見文末待決策清單),本研究只指出「兩套邏輯」 + 本身是舊版問題根源,不是「有沒有用時長」。 +3. **自動比對與手動重搜必須走同一份邏輯與同一個來源集合**:舊版 + 「自動只搜兩源、手動搜全部且不評分」的不一致要在新設計裡消除—— + 手動重搜應該是同一個比對函式、允許使用者事後從候選清單挑其他 + 選項(近似 Spotube 的 `swapWithSibling`),而不是另一套排序規則。 +4. **比對結果需要可覆寫且覆寫後不再自動重算**:採 Spotube 的快取 + +手動覆蓋模式(覆蓋後寫回同一個持久化欄位,往後直接採用,不 + 重新評分)——這與 ADR 0010 的 drift/`TrackKey` 資料層可以自然 + 對應(比對結果表用 `TrackKey` 或原始平台 id 做鍵,覆蓋即 + upsert)。 + +--- + +## 第 5 點:歌詞來源作為插件類別 + +### 5.1 三個腳本插件專案的實際做法(`peer-plugin-interfaces.md` 已詳列 +程式碼位置,此處聚焦「歌詞是不是一等能力」與「有沒有評分」) + +| 專案 | 歌詞是否為插件系統的一部分 | 有無自動評分/比對 | +|---|---|---| +| Spotube | 否,完全獨立、寫死呼叫 `lrclib.net` | 無需比對(單一硬編碼來源,直接用當前曲目的 artist/track/album/duration 查) | +| MusicFree | 是,但只是 `search()` 的一種 `SupportMediaType` | 無,使用者手動建立「聯合 key」關聯 | +| LX Music | 是,`lyric` 是 3 個動作之一 | 無,文件未描述任何評分機制 | + +**誠實結論:本研究涵蓋的所有同類專案,沒有一個對歌詞做自動評分式 +比對**——這點在啟動研究前不確定,現在可以確定地寫下來。FMP 舊版 +(`docs/audit/sources.md` §5.2)反而是**唯一**做了自動評分歌詞比對的 +(Levenshtein 標題 ×0.4、藝人 ×0.3、時長 ×0.2、有同步歌詞 ×0.1, +門檻 0.6),但如第 4.2 節所述,這套邏輯本身有文件與程式碼不一致、 +「命中即停」而非「比較所有來源」的問題。 + +### 5.2 建議:歌詞來源用同一個能力框架宣告,但比對邏輯與音軌比對共用核心 + +1. **歌詞來源同樣是「能力宣告」的一種**:一個音源可能只提供 + `lyrics`(純文字)或同時提供 `lyrics` + `syncedLyrics`(含時間軸), + 對齊 AetherTune 把兩者分開列舉的作法;一個「歌詞專用」來源 + (不提供播放、不提供 metadataSearch)在能力集合上就是「只有 + `lyrics`/`syncedLyrics`,沒有 `streamResolution`/ + `metadataSearch`」的音源,不需要獨立型別階層。 +2. **比對核心複用第 4.3 點的共用評分函式**:歌詞來源的候選(多首 + 同名/ 同名異曲)用同一套「標題/藝人相似度 + 時長 + 加分項」框架 + 評分,而不是像舊版一樣另開一份 `_selectBestMatch`。是否要保留 + 舊版「有同步歌詞加分」這個訊號、要不要恢復「跨來源比較所有候選 + 而非命中即停」——這些是行為變更,需要擁有者確認(見待決策清單), + 本研究只指出「兩套獨立評分邏輯」是要避免的結構問題。 +3. **沒有同類產品的自動評分先例可抄,FMP 等於是在四個同類專案裡 + 做得最細的那個**——這是把舊版的評分邏輯**修對**(消除不一致), + 而不是抄一個更成熟的外部模型;因為外部真的沒有更成熟的模型可抄。 + +--- + +## 第 6 點:契約測試(Contract Testing) + +### 6.1 AetherTune 的結構化契約驗證器(最接近的真實先例) + +`apps/mobile/lib/src/domain/music_source_provider_sdk.dart` + + +```dart +final class MusicSourceProviderContractReport { + const MusicSourceProviderContractReport(this.issues); + final List issues; + bool get isCompliant => issues.isEmpty; +} + +MusicSourceProviderContractReport validateMusicSourceProviderContract( + MusicSourceProvider provider, +) { + // 檢查 id 格式(RegExp)、name/description/capabilities 非空、 + // 網域格式與去重、disclosure 與 capabilities 是否互相對應 + // (例如宣告了 authentication 能力卻沒有對應揭露),並交叉核對 + // 宣告的能力與實際 implements 的擴充介面是否一致: + if (provider.capabilities.contains(MusicSourceCapability.searchSuggestions) && + provider is! MusicSourceSearchSuggestionProvider) { /* 記一筆 issue */ } + ... +} +``` + +這是**結構化/宣告一致性**驗證:檢查的是「宣告的能力」與「實際 +implements 的介面」「隱私揭露欄位」彼此對不對得上,**不是**拿真實 +或錄製的 HTTP 回應去跑這個 provider、斷言它解析出正確結果——也就是 +說,即使一個音源的 `search()` 實作邏輯完全是錯的(例如永遠回傳空 +清單),只要它宣告的能力跟它 implements 的介面一致,這個驗證器一樣 +會回報「合規」。 + +### 6.2 `shared_preferences_platform_interface` 的結構化測試(次要先例) + +`packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart` +(`flutter/packages` monorepo):只驗證「用 `implements` 而非 +`extends` 去實作這個 platform interface 會噴錯」,同樣是**結構化** +(型別系統層級)而非行為層級的契約測試。 + +### 6.3 誠實陳述:Dart 生態系沒有強力的「行為式、fixture 驅動」契約 +測試先例 + +本研究透過 `gh search code`/repo 瀏覽,在 Spotube、MusicFree、 +LX Music、Listen1、AetherTune、以及 Flutter 官方 federated plugin +生態系裡,**找不到**任何「用同一組錄製好的 fixture/夾具,自動跑過 +每一個插件實作,斷言輸出符合某個共同斷言集」的 CI 測試套件。 +四個「必查」同類專案沒有一個做自動化的逐插件測試(插件多半是外部 +社群倉庫,主 repo 沒有義務或機制去跑它們);AetherTune 與 +`shared_preferences_platform_interface` 提供的都只是**結構化**驗證。 + +**這點不必視為壞消息**:FMP 的 ADR 0011–0013 已經明確要求(且用詞 +就是「契約測試」)三種行為式契約,且已經指定好每種契約要斷言什麼: + +- ADR 0011:「遮蔽測試:每個音源一組假憑證與假簽名 URL,斷言經 log + 檔、記憶體歷史、診斷包、網路紀錄後都不再出現原值」; +- ADR 0012:「契約測試:每個音源的媒體請求經媒體 client 發出後, + 請求上不含任何 Cookie/Authorization」; +- ADR 0013:「契約測試:每個音源以錄下的錯誤回應 fixture,斷言 + 對應到的 `AppError` 類別」。 + +這三條全部是「**同一組測試邏輯,套用在每個音源各自提供的 fixture +上**」的形狀——技術上就是「一個共用的 test helper 函式(或 +`group`/`test` 產生器),接受音源 id + fixture 路徑為參數,被每個 +音源的測試檔各自呼叫一次」,Dart `package:test` 原生就能表達這種 +「參數化測試套件」(用一個函式包住 `group()`/`test()`,在每個音源的 +測試檔裡呼叫該函式並傳入自己的 fixture),不需要额外框架。 + +### 6.4 建議:把 ADR 既有的三種契約測試模式,擴充成本任務的「音源能力 +契約」測試骨架,並補一層 AetherTune 風格的結構化檢查 + +1. **結構化層**(抄 AetherTune 的精神,不抄程式碼):一個 + `validateSourceContract(Source source)` 之類的函式,在測試環境 + (或啟動時 debug 模式)跑過所有已註冊音源,斷言「宣告的 + `capabilities` 與實際 `implements` 的擴充介面一致」——這一層可以 + 直接寫成一個 `test/support/*_static_rule_test.dart`(依 + `AGENTS.md` 既有的 static-rule 慣例),不需要新框架。 +2. **行為層**(延伸 ADR 0011–0013 已經定義的三種契約,外加本任務 + 新增的「搜尋/比對」契約):每個音源目錄下放自己的 fixture + (錄製的 API 回應/錯誤回應/假憑證),共用測試 helper 驗證: + - 錯誤對應表(ADR 0013); + - 憑證不外洩到媒體請求(ADR 0012); + - 已知敏感值經遮蔽(ADR 0011); + - (本任務新增)宣告了 `metadataSearch` 但沒有 + `streamResolution` 的來源,比對流程能正確把它標記為 + 「需要比對到可播放來源」而非直接嘗試播放。 +3. **不引入新的測試框架或第三方契約測試套件**——生態系裡沒有更成熟 + 的現成方案可用(見 6.3),FMP 自己已經在 ADR 裡定義好要斷言什麼, + 缺的只是「共用 test helper + 每個音源提供 fixture」這個組裝方式, + 這是本任務設計階段要生產的東西,不是能從外部抄來的。 + +--- + +## 待補查項(誠實列出) + +- LX Music `inited` 事件的能力宣告是否在執行期被「檢查」過(例如 + UI 是否會因為某個自訂源沒宣告 `lyric` 動作而隱藏歌詞按鈕),還是 + 純粹信任腳本自己不要呼叫不支援的動作:官方文件頁沒有說明到這個 + 細節,查不到。 +- AetherTune 的 `validateMusicSourceProviderContract` 完整方法體 + (本研究只讀到約前 200 行,含 `searchSuggestions`/ + `favoriteMutation` 等幾個 `is!` 檢查分支)是否涵蓋全部 19 種能力 + 各自的介面交叉檢查:未讀完全文,不確定是否有遺漏分支,需要在 + 設計階段若要參考此模式時重新完整核對一次原始碼。 +- FMP 新設計的比對評分是否要保留舊版的時長訊號、要不要恢復「跨 + 來源比較所有候選」而非「命中即停」:這是行為變更,本研究不代為 + 決定,列入下方最終報告的待決策清單。 diff --git a/.trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md b/.trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md new file mode 100644 index 000000000..7574116be --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md @@ -0,0 +1,432 @@ +# 研究:同類音樂播放器的音源/插件介面,與編譯期 vs. 執行期插件的取捨 + +> 對應 `.trellis/tasks/09-27-design-source-plugins` 研究第 1、2 點。 +> 查證方式:`gh api` / `gh search code` / `curl` 直接讀各 repo 的原始碼與 +> LICENSE 檔(一手來源);LX Music 的部分官方文件頁面用 WebFetch(標明 +> 為文件頁摘要,非原始碼)。查不到的一律寫「查不到」,推論一律標 +> 「推測」。查證時間 2026-09-27。 +> +> 依擁有者要求:只看設計、不抄程式碼;本文引用的程式碼片段僅為指出介面 +> 形狀與關鍵字,並非要移植進 FMP。 + +--- + +## 第 1 點:同類專案的音源/插件介面 + +### 1.1 Spotube — 執行期腳本插件(hetu_script) + +- Repo:`team-spotube/spotube`(`KRTirtho/spotube`已重新導向到此)。 + License:`LICENSE` 開頭為 BSD 系列四條款文字(**BSD-4-Clause**)。 + + +**插件本體是腳本,不是 Dart 類別。** Spotube 內嵌 `hetu_script`(一個 +Dart 風格的腳本語言直譯器),插件是打包成 `.hetu`/`.json` 的腳本+ +manifest,安裝後由直譯器在執行期載入、執行。Dart 側只有一層「端點」 +薄封裝,透過 `Hetu.fetch("metadataPlugin")` 取出腳本物件,再用 +`HTInstance.invoke("methodName", ...)` 以字串方法名反射呼叫腳本裡的 +函式。例如音源解析端點: + +`lib/services/metadata/endpoints/audio_source.dart` + + +```dart +class MetadataPluginAudioSourceEndpoint { + final Hetu hetu; + Future> matches(...) async { + final raw = await hetuMetadataAudioSource + .invoke("matches", positionalArgs: [track.toJson()]) as List; + ... + } +} +``` + +其餘端點(`album.dart`、`artist.dart`、`auth.dart`、`browse.dart`、 +`core.dart`、`playlist.dart`、`search.dart`、`track.dart`、`user.dart`, +均在 `lib/services/metadata/endpoints/`)同一種寫法:Dart 端只定義 +「這個能力長什麼型別」,實際邏輯永遠在腳本裡,Dart 側完全不檢查腳本 +是否真的實作了該方法(呼叫不存在的方法會在執行期才失敗)。 + +**能力宣告**:manifest(`PluginConfiguration`, +`lib/models/metadata/plugin.dart` +): + +```dart +enum PluginApis { webview, localstorage, timezone } + +enum PluginAbilities { + authentication, + scrobbling, + metadata, + @JsonValue('audio-source') + audioSource, +} + +factory PluginConfiguration({ + required String name, required String description, required String version, + required String author, required String entryPoint, required String pluginApiVersion, + @Default([]) List apis, + @Default([]) List abilities, + String? repository, +}) = _PluginConfiguration; +``` + +只有 4 種能力旗標(認證、Scrobble、metadata、音源),metadata 插件的 +`type` 固定是 `"metadata"`——即 Spotube 的插件系統設計目標窄:只解決 +「幫 Spotify 的曲目找到可播放來源」與「metadata 補充」,不是通用音源 +系統。**歌詞不是插件能力**:`lib/provider/lyrics/synced.dart` + +的 `SyncedLyricsNotifier.getLRCLibLyrics()` 直接用 Dio 打死 `lrclib.net` +的公開 API(`Uri(host: "lrclib.net", path: "/api/get", ...)`),完全在 +插件系統之外,是寫死的單一內建功能。 + +**iOS 分發**:官方 `README.md` + +的下載表格 iOS 欄位原文:「\*iPA file only. Requires sideloading with +AltStore or similar tools.」——即官方**未上架 App Store**,只提供側載 +IPA。是否直接因為 Guideline 2.5.2(見 2.7)而不上架,Spotube 維護者 +沒有公開這樣講,此因果關係標「推測」。 + +### 1.2 MusicFree — 執行期腳本插件(一個大介面 + 執行期 duck typing) + +- Repo:`maotoumao/MusicFree`。License:`LICENSE` + 開頭為 + 「GNU AFFERO GENERAL PUBLIC LICENSE Version 3」(**AGPL-3.0**)。 + +插件是 JS/TS 檔(打包成 `.js`),執行期用 `eval` 類機制載入成物件。 +介面定義在 +`src/types/plugin.d.ts` +: + +一個 `IPlugin.IPluginDefine`,14 個方法**全部可選**(`search?`、 +`getMediaSource?`、`getMusicInfo?`、`getLyric?`、`getAlbumInfo?`、 +`getMusicSheetInfo?`、`getArtistWorks?`、`importMusicSheet?`、 +`importMusicItem?`、`getTopLists?`、`getTopListDetail?`、 +`getRecommendSheetTags?`、`getRecommendSheetsByTag?`、 +`getMusicComments?`),外加 `platform`/`supportedSearchType` 等描述性 +欄位——**沒有獨立的「能力」列舉**,能力等於「這個方法有沒有被實作」。 + +執行期怎麼知道一個插件支援什麼:`src/core/pluginManager/plugin.ts` + +的 `class Plugin`: + +```ts +public supportedMethods: Set = new Set(); +... +this.supportedMethods = new Set(Object.keys(_instance).filter( + key => typeof (_instance[key]) === "function", +) as any); +``` + +即載入腳本物件後,**用 `typeof === "function"` 逐一檢查每個 key**, +把「真的是函式」的 key 收進一個 `Set` 當作這個插件的能力清單。這是 +典型的執行期 duck typing:介面本身不強制實作,能力清單是「觀察」出來 +的,不是插件「宣告」出來的(雖然實務上兩者通常一致)。 + +歌詞:`getLyric?` 只是 `IPluginDefine` 裡衆多可選方法之一,且歌詞在 +搜尋層被當成 `ICommon.SupportMediaType` 的一種(跟音樂、專輯、歌單同 +一個 `search()` 入口,`type` 參數切換),**沒有比對評分**——使用者手動 +把歌詞結果與曲目建立「聯合 key」關聯,是人工配對,不是自動匹配。 + +### 1.3 LX Music — 執行期腳本插件(極窄,3 種動作) + +-桌面版 repo:`lyswhut/lx-music-desktop`。License:`LICENSE` + + 為 **Apache-2.0**。行動版 `lyswhut/lx-music-mobile` 同樣 + Apache-2.0(`gh api repos/lyswhut/lx-music-mobile` 回報 + `license.spdx_id = "Apache-2.0"`)。 + +自訂源(custom source)是 JS 腳本,檔頭以註解宣告 +`@name`/`@description`/`@version`/`@author`/`@homepage`;執行期用 +一個 `inited` 事件把該腳本「登記」進主程式,payload 裡列出這個腳本 +(可能同時登記多個具名音源)各自支援哪些 `actions`。文件明確列出的 +動作只有 3 種:`musicUrl`(解析播放網址)、`lyric`(歌詞)、 +`pic`(封面圖);內建的一般音源甚至只保證 `musicUrl`。 +來源:LX Music 官方文件頁 +(此為文件頁摘要, +非原始碼一手引用;文件對應的原始碼倉庫 `lyswhut/lx-music-doc` 確切 +檔案路徑查不到,未進一步核實)。 + +即 LX Music 把「能力」壓到最窄的顆粒度(3 個動作),且歌詞是動作之一 +但**沒有評分機制**——文件沒有描述任何自動比對邏輯,行為上更接近「這個 +音源要嘛回得出歌詞要嘛回不出來」。 + +### 1.4 Listen1 — 沒有正式介面,命名慣例 + 極簡能力旗標 + +- Repo:`listen1/listen1_chrome_extension`。License:`LICENSE` + + 為 **MIT**。 + +每個音源是 `js/provider/*.js` 裡的一個物件,**沒有任何 TypeScript/ +JSDoc 介面宣告**,方法名純粹靠約定(`search`、`get_playlist`、 +`lyric`、`bootstrap_track`、`get_user`、`get_login_url`、`logout`、 +`get_playlist_filters` 等)。 + +但確實有一個**輕量中央註冊表**,`js/loweb.js`: + +```js +/* global netease xiami qq kugou kuwo bilibili migu taihe localmusic myplaylist */ +const PROVIDERS = [ + { name: 'netease', instance: netease, searchable: true, support_login: true, id: 'ne' }, + { name: 'xiami', instance: xiami, searchable: false, hidden: true, support_login: false, id: 'xm' }, + { name: 'kugou', instance: kugou, searchable: true, support_login: false, id: 'kg' }, + ... +]; +function getProviderByName(sourceName) { return (PROVIDERS.find(...) || {}).instance; } +function getAllSearchProviders() { return PROVIDERS.filter((i) => i.searchable).map((i) => i.instance); } +``` + +即每個條目除了 `name`/`instance` 外,還帶 3 個**布林能力旗標** +(`searchable`、`support_login`、`hidden`)。這些旗標**確實在分派時 +被用來過濾**:例如全源搜尋 `MediaService.search('allmusic', ...)` +呼叫 `getAllSearchProviders()`(只挑 `searchable: true` 的音源); +登入頁用等價的 `getLoginProviders()` 過濾 `support_login: true`。 +但除了這 3 個旗標涵蓋的「可搜尋」「可登入」「要不要在清單顯示」之外, +其餘能力(例如 `lyric`、`get_playlist_filters`)完全沒有旗標,呼叫端 +(`getLyric()`、`getPlaylistFilters()`)**假設每個註冊的 provider 都有 +該方法**,不做任何存在性檢查——找不到就是執行期噴錯。 + +**結論**:Listen1 是「命名慣例 + 極簡集中式能力旗標」的中間型態,比 +MusicFree 的全動態 duck typing 更死板(旗標要手動維護),但比起完整 +介面又更鬆散(大多數方法無旗標保護)。 + +### 1.5 AetherTune — 編譯期 Dart class 註冊(本研究找到的關鍵先例) + +- Repo:`Yunushan/aethertune`。License:`LICENSE` + , + 全文為 **BSD Zero Clause License (0BSD)**, + 版權標示「Copyright (C) 2026 AetherTune Contributors」。 + `pubspec.yaml` + + 確認是真實在維護的 Flutter App(`audio_service`、`just_audio`、 + `media_kit`、`flutter_secure_storage: ^11.2.0` 等依賴),描述為 + 「Free and open-source music app with local playback and provider + plugins.」,且每個音源都有對應 `test/*_test.dart`,不是玩具專案。 + +這是四個「必查」專案之外,額外找到的第五個案例,**直接對應本任務要找 +的「編譯期 Dart 類別註冊」模式**:音源不是腳本、不是動態載入的外部檔, +而是**編譯進 App 本體的 Dart class**,一個介面+一個能力列舉: + +`apps/mobile/lib/src/domain/music_source_provider.dart` + + +```dart +enum MusicSourceCapability { + metadataSearch, searchSuggestions, radioDirectory, streamResolution, + directPlayback, libraryBrowse, playlists, playlistMutation, + favoriteMutation, albumFavoriteMutation, artistFavoriteMutation, + artwork, lyrics, syncedLyrics, offlineCache, downloads, + subscriptions, recommendations, authentication, +} + +/// Implement this contract to add a legal source adapter. +abstract interface class MusicSourceProvider { + String get id; + String get name; + Set get capabilities; + ProviderPrivacyDisclosure get disclosure; + Future> search(String query); + Future resolveStream(Track track); +} +``` + +以及可選擴充能力用**獨立小介面**(不是塞進大介面的可選方法): + +```dart +abstract interface class MusicSourceSearchPagingProvider + implements MusicSourceProvider { + Future searchPage(String query, {String? cursor, int limit = 20}); +} +``` + +公開 SDK 入口是一個獨立的 library barrel 檔 +`apps/mobile/lib/aethertune_provider_sdk.dart` +, +匯出 `MusicSourceProvider`、能力列舉、`Track` 等契約型別,並帶版本號 +`aethertuneProviderSdkVersion`,也提供一個結構化契約驗證函式 +`validateMusicSourceProviderContract`(見本文件第 6 點)。 + +真實存在超過 15 個具體實作(`internet_archive_provider.dart`、 +`jellyfin_provider.dart`、`subsonic_provider.dart`、 +`radio_browser_provider.dart`、`lrclib_lyrics_provider.dart`、 +`spotify_metadata_provider.dart` 等,倉庫樹狀清單已核實存在對應 +`test/*_test.dart`),證明這不是設計草稿,而是可運作、有測試覆蓋的 +編譯期插件系統。 + +`dddevid/musly` 曾在 WebSearch 中出現為次要線索(Subsonic 家族多後端 +客戶端),本次研究**未驗證**,不納入結論。 + +### 1.6 五個專案的能力清單比較 + +| 專案 | 插件形態 | 能力宣告單位 | 顆粒度 | 歌詞是否為獨立能力 | +|---|---|---|---|---| +| Spotube | hetu_script 腳本 | manifest 的 `abilities: List` | 極粗(4 種:認證/Scrobble/metadata/音源) | 否,硬編碼 LRCLib,不經插件系統 | +| MusicFree | JS/TS 腳本 | 執行期觀察函式是否存在(`supportedMethods: Set`) | 細(14 個可選方法) | 是,但只是 `search()` 的一種媒體類型 | +| LX Music | JS 腳本 | `inited` 事件的 `actions` 陣列 | 極細但選項極少(3 種動作) | 是,`lyric` 是 3 動作之一 | +| Listen1 | 命名慣例物件 | 中央 `PROVIDERS` 表的少數布林旗標 | 部分能力有旗標,多數靠假設 | 有 `lyric` 方法但無旗標保護 | +| AetherTune | 編譯期 Dart class | `Set` enum + 可選介面 | 細(19 種能力,含 `lyrics`/`syncedLyrics`) | 是,明確列舉且與可播放能力分離 | + +**共通點**:五個專案都用「一個中心點知道有哪些音源/插件」+「每個 +音源/插件用某種方式宣告或暴露自己支援什麼」,沒有例外;差別只在 +「能力顆粒度」與「宣告是靜態聲明還是執行期觀察」。**沒有一個專案** +把「metadata-only 來源」「playable 來源」「歌詞來源」統一成同一種 +能力物件的三個子集——它們要嘛用完全獨立的系統(Spotube 的歌詞), +要嘛把歌詞併入既有的搜尋/動作機制(MusicFree、LX Music),要嘛用 +能力列舉的其中幾項區分(AetherTune 的 `lyrics`/`syncedLyrics` vs. +`streamResolution`/`directPlayback`)。AetherTune 是唯一同時涵蓋 +「metadata-only 標記」概念的:它的 `streamResolution` 能力與 +`directPlayback` 分開宣告,暗示「能查到資訊但不能直接播放」與 +「能直接播放」是兩種不同能力,這點值得 FMP 借鑑(見第二份文件第 4 點)。 + +--- + +## 第 2 點:編譯期插件 vs. 執行期腳本插件的取捨 + +FMP 的情境:Bilibili/YouTube/網易雲三源,音源清單由**擁有者**決定 +新增,不是讓一般使用者自己裝任意第三方插件市集。這點會讓天平明顯偏 +向編譯期。以下逐項比較,每項都盡量掛上實例證據。 + +### 2.1 安全性 + +- **腳本插件**(Spotube/MusicFree/LX Music):載入的是**外部、 + 執行期取得**的程式碼,即使解讀為「腳本」而非原生機器碼,仍然是 + 「App 執行期改變自己的行為」。MusicFree 用 AGPL-3.0、插件生態明確 + 鼓勵第三方社群貢獻與分享插件檔(`.js` 檔直接分享安裝),代表使用者 + 會安裝來路不明的第三方插件——這正是 App 供應鏈風險的來源:插件能 + 存取的 API(`fetch`、`localStorage` 等)等於它能做的事,惡意插件 + 可以外洩使用者資料或請求任意網域。 +- **編譯期插件**(AetherTune):音源程式碼與 App 一起走 code review、 + 一起發版,沒有「執行期安裝未經審查程式碼」這個攻擊面;代價是新增 + 音源需要重新發版,使用者不能自己裝插件。 +- FMP 現況(`docs/audit/sources.md`)音源就是三個固定、擁有者維護的 + 來源,不存在「讓使用者自由裝插件」的需求,編譯期插件的安全模型 + (沒有外部程式碼載入面)直接適用,不需要腳本插件解決的「多方不 + 信任程式碼共存」問題。 + +### 2.2 法律風險 + +- 三個腳本插件專案(Spotube/MusicFree/LX Music)都採用「App 本體 + 乾淨、插件另外分發」的切割:MusicFree 的插件倉庫與主 App 分開, + Spotube 的插件也是另外安裝的 `.hetu` 檔。這個切割的**動機之一** + (專案本身沒有明文承認,此處標「推測」)很可能是降低「App 本體 + 內建直接繞過版權保護的程式碼」的法律曝險——插件是使用者自行安裝的 + 第三方內容,App 本體看起來只是一個「通用播放器框架」。 +- 這個切割對 FMP **不適用**:FMP 的三個音源就是 App 的核心賣點, + 是擁有者自己維護、跟 App 一起發版的功能,沒有「甩鍋給使用者自行 + 安裝插件」的空間或意圖,法律責任本來就在 App 本體上,編譯期或 + 執行期都不改變這個事實。 +- 換句話說:法律風險考量在 Spotube/MusicFree 的情境裡是選擇腳本 + 插件的理由之一(推測),但**這個理由對 FMP 不成立**,因為 FMP + 沒有意圖把音源包裝成「使用者自選第三方插件」。 + +### 2.3 效能 + +- hetu_script/JS 引擎都是**直譯執行**,比原生 Dart AOT 編譯碼慢; + 對 FMP 這種音源呼叫頻率不高(搜尋、解析串流是網路 I/O bound,不是 + CPU bound)的場景,效能差異在實務上可忽略——**兩個方案都不會是 + 瓶頸**,但編譯期 Dart 沒有「載入腳本引擎」與「跨語言呼叫(Dart↔腳本 + 的 `invoke`/JSON 序列化)」這層開銷與複雜度。 + +### 2.4 除錯 + +- Spotube 的 `MetadataPluginAudioSourceEndpoint.matches()` 呼叫失敗時, + 例外從 hetu_script 直譯器丟出,Dart 側只看到一個泛用執行期錯誤, + 對照 ADR 0013 要求的「每個音源在自己目錄內把錯誤轉換成 sealed + `AppError`」——**腳本插件的錯誤天然缺乏型別**,要做到 ADR 0013 那樣 + 精確的錯誤分類,必須先在腳本裡手動序列化錯誤碼再讓 Dart 側解析, + 多一層轉換與失敗可能。 +- 編譯期 Dart 插件的例外就是普通 Dart 例外,IDE 斷點、stack trace、 + 型別檢查全部原生可用,直接對齊 ADR 0013 的分類需求。 + +### 2.5 測試 + +- 腳本插件的「契約測試」要嘛要跑一個腳本直譯器去執行插件(MusicFree/ + Spotube 都沒有看到自動化這樣做的證據——本研究未找到任一專案有 + 「用同一組 fixture 自動跑過所有插件」的 CI 流程),要嘔另外寫一層 + mock 直譯器。 +- 編譯期 Dart 插件可以直接用 `flutter test` 對每個音源類別跑同一組 + 抽象測試(AetherTune 的 `validateMusicSourceProviderContract` 就是 + 能在編譯期靜態拿到 class 去驗證的例子),與 ADR 0011–0013 已經 + 要求的「契約測試」/「遮蔽測試」風格完全對齊,不需要額外的腳本 + 執行環境。 + +### 2.6 打包/分發 + +- 腳本插件的賣點是「不用重新發版就能更新音源」——Spotube/MusicFree/ + LX Music 都有插件市集/插件倉庫,讓使用者或社群更新單一音源而不用 + 等 App 更新。這對「音源可能因網站改版而失效、需要頻繁修補」的場景 + 是真實優勢。 +- 但 FMP 是**擁有者自己維護三個音源**,發版頻率由擁有者控制,且 + ADR 0009/0010 已經確立「新專案在 `app/`、Isar→drift 遷移」等會伴隆 + 重新發版的既定路徑,音源程式碼的更新沒有跟 App 版本脫鉤的急迫需求。 + +### 2.7 iOS App Review:Guideline 2.5.2 + +Apple Developer 官方 App Review Guidelines 2.5.2 原文(已在既有姊妹 +研究 `platform-policy-and-peers.md` 中確認並沿用同一段引用): + +> 「Apps should be self-contained in their bundles, and may not read or +> write data outside the designated container area, nor may they +> download, install, or execute code which introduces or changes +> features or functionality of the app, including other apps. +> Educational apps designed to teach, develop, or allow students to +> test executable code may, in limited circumstances, download code +> provided that such code is not used for other purposes.」 + +這條規則字面上直接針對「執行期下載並執行會改變功能的程式碼」—— +**腳本插件系統如果讓使用者從網路上下載新插件檔並在 App 內執行,屬於 +這條規則的核心打擊範圍**。 + +實例佐證:Spotube 官方 `README.md` 的下載表格顯示 iOS 版**沒有上架 +App Store**,只提供側載 IPA(見 1.1)。Spotube 團隊沒有公開說明這是 +否直接因為 2.5.2(此因果關係標「推測」),但至少可以確認的事實是: +一個具備「執行期載入外部腳本插件」架構的音樂 App,**目前沒有出現在 +App Store 上**。MusicFree、LX Music 兩者也都不在官方文件或 README +中聲稱有上架 App Store(`MusicFree`/`LX Music` 官網與 GitHub README +均只提供 Android/桌面/側載下載連結,查不到 App Store 連結)。 + +編譯期插件(AetherTune)沒有這個問題:音源程式碼在編譯時就固定在 +App bundle 內,符合「self-contained」,不涉及執行期下載可執行程式碼。 + +### 2.8 結論與對 FMP 的建議 + +**建議 FMP 採編譯期 Dart class 註冊,不做執行期腳本插件系統**: + +1. FMP 的音源是擁有者自己維護的固定三源,不存在「讓一般使用者自由 + 安裝第三方插件」的產品需求,腳本插件解決的「多方不信任程式碼共存 + +不重新發版即可更新」兩個核心痛點對 FMP 都不成立或優先度低。 +2. 編譯期方案直接對齊 ADR 0011(統一日誌/遮蔽)、ADR 0012(請求層 + `AuthRequirement` 宣告)、ADR 0013(sealed `AppError`+契約測試) + 已經確立的「音源在自己目錄內做轉換、用型別系統窮舉」的既定方向—— + 這三份 ADR 的機制全部假設音源程式碼在編譯期可被型別系統看見,腳本 + 插件會讓這些機制多一層序列化橋接。 +3. 未來若 FMP 想上架 iOS App Store,編譯期方案不會撞上 Guideline + 2.5.2;若走側載,這個顧慮就不成立,但編譯期的其餘優點(除錯、 + 測試、與既有 ADR 對齊)仍然成立,所以建議不論 iOS 分發策略為何都 + 走編譯期。 +4. 唯一的取捨代價:新增或修補一個音源必須跟著 App 一起重新發版, + 不能做到「音源失效時不等 App 更新就先修好」。這點擁有者已經在 + ADR 0008(App 重寫、沿用舊身分)與既有專案的開發節奏中,用「擁有 + 者自己維護、快速發版」的模式運作,評估為可接受的代價,但**這是 + 一個需要擁有者確認的產品決策**(見兩份研究文件共用的「待決策」 + 清單)。 + +--- + +## 待補查項(誠實列出) + +- LX Music 自訂源 `inited` 事件與 `actions` 陣列的**確切原始碼位置** + (`lyswhut/lx-music-doc` 或桌面版/行動版 repo 內實際處理該事件的 + 檔案)查不到;本文引用僅到官方文件頁 `https://lxmusic.toside.cn/desktop/custom-source` + 的內容摘要,未能核對成一手程式碼引用。 +- Spotube/MusicFree/LX Music 的 iOS 未上架是否**明確因為** + Guideline 2.5.2(而非其他條款,例如 5.2.2 第三方內容或版權疑慮) + ,三個專案都沒有公開聲明因果關係,本文只呈現「有腳本插件系統的 + 音樂 App 目前都不在 App Store 上」這個相關性事實,因果推論已標 + 「推測」。 +- `dddevid/musly` 是否也是編譯期插件模式:本次研究未驗證,不納入 + 結論,僅記錄為未查證線索。 +- MusicFree/Spotube 是否有任何形式的自動化「插件契約測試」(CI 對 + 每個已知插件跑同一組驗證):透過 `gh search code` 與倉庫瀏覽**未 + 找到**任何此類 workflow 或測試檔,判定為「沒有」而非「查不到」, + 因為兩個 repo 的 CI 設定與測試目錄都是公開可查的,且插件本身是 + 外部倉庫,主 repo 沒有理由對其跑契約測試。 diff --git a/.trellis/tasks/09-27-design-source-plugins/task.json b/.trellis/tasks/09-27-design-source-plugins/task.json new file mode 100644 index 000000000..acaa56b1e --- /dev/null +++ b/.trellis/tasks/09-27-design-source-plugins/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-source-plugins", + "name": "design-source-plugins", + "title": "Design: source plugins", + "description": "Phase-2 item 1: single registration point with declared capabilities for playable, metadata-only and lyrics sources, unified matching flow, no source-specific branches in UI or services", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From ed27942f10d36c87eb92f200109786202caa9972 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 13:54:09 +0800 Subject: [PATCH 029/133] chore(task): move source plugins to a separate plugin repository --- .../09-27-design-source-plugins/design.md | 29 ++++++++++++++----- .../09-27-design-source-plugins/implement.md | 3 +- .../tasks/09-27-design-source-plugins/prd.md | 5 ++-- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/.trellis/tasks/09-27-design-source-plugins/design.md b/.trellis/tasks/09-27-design-source-plugins/design.md index 2dfb1d624..cc843bbce 100644 --- a/.trellis/tasks/09-27-design-source-plugins/design.md +++ b/.trellis/tasks/09-27-design-source-plugins/design.md @@ -12,7 +12,8 @@ flowchart TB REG --> SP1[ScriptSource:bilibili.js] REG --> SP2[ScriptSource:netease.js] REG --> SP3[ScriptSource:youtube.js
    或暫時的 Dart 實作] - REG --> SP4[ScriptSource:使用者安裝的腳本] + REG --> SP4[ScriptSource:其他來源的腳本] + IDX[插件庫 index.json
    官方 1morr/fmp-plugins 或自訂] -.安裝/更新.-> REG subgraph 宿主(App) RT[JS 執行環境 flutter_js
    QuickJS / JavaScriptCore] HOST[宿主 API v1
    http、crypto、storage、log、login] @@ -22,8 +23,8 @@ flowchart TB ``` - **一套介面 `SourcePlugin`**:App 其他部分只認它與能力宣告,分不出來源是哪個、是不是腳本。 -- **所有來源都是 JS 腳本**:可播放音源(B 站、網易、YouTube)、僅元資料來源(Spotify、QQ 匯入)、歌詞源(網易、QQ、lrclib)。 - 內建腳本隨 App 打包在 assets,標為「內建」,可停用不可刪除;使用者安裝的腳本不得使用內建腳本的 id。 +- **所有來源都是 JS 腳本,App 不內建任何來源**:可播放音源(B 站、網易、YouTube)、僅元資料來源(Spotify、QQ 匯入)、 + 歌詞源(網易、QQ、lrclib)都放在獨立的官方插件庫,由使用者在 App 內安裝(§5)。官方插件與使用者自己的插件走同一條安裝路徑。 - **YouTube 例外的退路**:可行性驗證失敗時,YouTube 暫時以 Dart 實作同一個 `SourcePlugin` 介面;找到解法後換回腳本。 - **腳本引擎**:`flutter_js`(Android/Windows/Linux 用 QuickJS,iOS/macOS 用 JavaScriptCore)。腳本以 ES2020 JS 撰寫;作者可用 TypeScript 再打包。 @@ -76,12 +77,23 @@ flowchart TB 沒有檔案系統、沒有任意 socket、沒有其他插件的資料。資料交換一律是 JSON DTO(曲目、歌單、串流結果、歌詞候選…), 以 `apiVersion` 版本化;宿主提供 TypeScript 型別定義檔。 -## 5. 安裝與信任 +## 5. 插件庫、安裝與信任 -- 從檔案或網址安裝;安裝前顯示 manifest:名稱、作者、能力、**會連的網域**,並警告「此腳本會以你的登入身分存取這些網站」。 -- 更新:重新安裝新版本(自動檢查插件更新列入第 20 項待辦)。 -- 停用與移除:移除時一併清除該插件的 storage 與憑證。 -- Debug 頁提供「音源健康檢查」:對每個插件跑一組基本呼叫(第 4、8 項)。 +採用的慣例:MusicFree 的「訂閱」插件來源、LX Music 的自訂源匯入(App 本體不附音源)。 + +- **官方插件庫是另一個 repo**(`1morr/fmp-plugins`):每個插件一個目錄(腳本+manifest+錄下的測試 fixture); + 它自己的 CI 跑每個插件的契約測試,並產生 `index.json`(id、名稱、版本、`apiVersion`、能力、網域、下載網址、SHA-256)。 + 主 repo 只放播放器本體,測試用假插件與錄下的回應。 +- **插件頁**:預設讀官方 index;可加入其他 index 網址;也可從檔案或單一網址安裝。 +- **安裝前顯示** manifest:名稱、作者、來自哪個插件庫、能力、**會連的網域**,並警告「此腳本會以你的登入身分存取這些網站」。 + 由 index 安裝時以 SHA-256 驗證檔案。 +- **更新**:不在背景定時檢查;打開插件頁或手動「檢查更新」時比對 index,可一鍵全部更新。音源壞掉時更新插件即可,不必發 App 新版。 +- **首次啟動**:沒有任何來源時顯示引導,列出官方插件,勾選後一鍵安裝。 +- **舊版升級**:legacy import 不依賴插件;匯入時偵測舊資料用到的音源(B 站、YouTube、網易),提示一鍵安裝對應的官方插件; + 未安裝前這些曲目標示「音源未安裝」。 +- **停用與移除**:移除時一併清除該插件的 storage 與憑證;已存在的曲目保留並標示「音源未安裝」。 +- Debug 頁提供「音源健康檢查」:對每個已安裝插件跑一組基本呼叫(第 4、8 項)。 +- 法律面:App 本體不含呼叫非官方 API 的程式碼,降低主 repo 的暴露面,但不消除風險(B 站社群 API 文件庫已於 2026-01 因存證信函關閉,`research/login-methods.md` §0)。 ## 6. 匹配流程(宿主統一) @@ -99,5 +111,6 @@ flowchart TB ## 8. 第一個里程碑與可行性驗證 - 第一個里程碑的 tracer bullet 用一個腳本音源(哪一個在里程碑規劃時定)完成搜尋與播放,同時建立 JS 執行環境、宿主 API 的最小集合、腳本契約測試的雛形。 + 插件庫 repo 與插件頁可在後續里程碑建立;第一個里程碑以「從檔案安裝」載入腳本即可。 - **YouTube 可行性驗證(有時限)**:YouTube.js(MIT,官方只寫支援 Node.js、Deno、瀏覽器)在 `flutter_js` 裡能否搜尋並解出可播放串流;它需要宿主提供 `fetch` 與 eval。時限內失敗則 YouTube 暫以 Dart 實作。 - `flutter_js` 在 Android 與 Windows 上的非同步(Promise)、記憶體與啟動成本實測。 diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.md b/.trellis/tasks/09-27-design-source-plugins/implement.md index d208f5dd3..e47e01713 100644 --- a/.trellis/tasks/09-27-design-source-plugins/implement.md +++ b/.trellis/tasks/09-27-design-source-plugins/implement.md @@ -2,9 +2,10 @@ 本任務只產出設計與 ADR。 -- [ ] 寫 `docs/adr/0014-script-source-plugins.md`:design.md §1–§8;被否決的選項(編譯期 Dart 插件、先 Dart 後轉腳本、hetu_script、允許腳本讀其他音源憑證或檔案系統、各功能各自的匹配評分);「如何確認」(能力宣告與介面一致的結構測試、腳本重播契約測試、網域清單強制的測試、UI 無音源分支的 lint)。 +- [ ] 寫 `docs/adr/0014-script-source-plugins.md`:design.md §1–§8;被否決的選項(編譯期 Dart 插件、內建腳本隨 App 打包、插件放在主 repo、背景自動檢查插件更新、先 Dart 後轉腳本、hetu_script、允許腳本讀其他音源憑證或檔案系統、各功能各自的匹配評分);「如何確認」(能力宣告與介面一致的結構測試、腳本重播契約測試、網域清單強制的測試、UI 無音源分支的 lint)。 - [ ] ADR 0008 加註:音源邏輯改以舊程式碼為規格、用 JS 重寫(見 ADR 0014)。 - [ ] `phase2-plan.md` 標記第 1 項完成,第一個里程碑必要驗證加入 YouTube 可行性驗證與 flutter_js 實測,並記下腳本插件是解除功能凍結的例外。 +- [ ] `phase2-plan.md` 記下:建立 `1morr/fmp-plugins` repo 與其 CI 排入里程碑規劃(不在本任務建立)。 - [ ] 歸檔本任務。 驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-source-plugins/prd.md b/.trellis/tasks/09-27-design-source-plugins/prd.md index d417ed1c3..ebd1dbdac 100644 --- a/.trellis/tasks/09-27-design-source-plugins/prd.md +++ b/.trellis/tasks/09-27-design-source-plugins/prd.md @@ -28,12 +28,13 @@ - D1(使用者 2026-09-27):採**執行期 JS 腳本插件**,並**納入這次重寫**(為此項明確解除功能凍結)。目的是讓使用者能以 AI Agent 生成並安裝自己的音源;不上架任何商店。 - D2(使用者 2026-09-27):**內建音源現在就全部做成腳本**(B 站、網易、YouTube、Spotify/QQ 匯入、歌詞源);YouTube 先做有時限的可行性驗證,失敗則暫以 Dart 實作同一介面。 +- D3(使用者 2026-09-27):**App 不內建任何來源**;官方插件放獨立 repo(`1morr/fmp-plugins`,自有 CI 與 `index.json`),使用者在 App 內從插件庫安裝;可加自訂插件庫、可從檔案/網址安裝;更新只在打開插件頁或手動時檢查;首次啟動引導安裝;舊版升級時提示安裝舊資料用到的音源插件。 - 其餘依研究寫入 design.md:JS(非 hetu)、宿主 API 範圍、manifest、安裝時顯示網域並警告、統一匹配流程。 ## 需求 - R1 一套 `SourcePlugin` 介面;App 其他部分只認介面與能力宣告,沒有針對特定音源的分支。 -- R2 所有來源是 JS 腳本+manifest;內建腳本隨 App 打包。新增音源=新增一個腳本(使用者可自行安裝)。 +- R2 所有來源是 JS 腳本+manifest;App 不內建來源,從插件庫(官方或自訂)、檔案或網址安裝,以 SHA-256 驗證。新增音源=在插件庫新增一個目錄(或使用者自行安裝腳本)。 - R3 腳本只能經宿主 API 動作:網路請求一律經網路層並受網域清單限制;憑證只能讀自己音源的;沒有檔案系統。 - R4 能力宣告驅動 UI;僅元資料來源與歌詞源以能力區分,不另立型別。 - R5 匹配用一份共用評分核心、跨來源比較、使用者可改選且改選後不重算、失敗項目保留並標示。 @@ -41,6 +42,6 @@ ## 驗收標準 -- [ ] design.md 涵蓋介面形狀、manifest、能力、宿主 API、安裝與信任、匹配流程、對其他 ADR 的影響、第一個里程碑與 YouTube 驗證。 +- [ ] design.md 涵蓋介面形狀、manifest、能力、宿主 API、插件庫與安裝與信任、匹配流程、對其他 ADR 的影響、第一個里程碑與 YouTube 驗證。 - [ ] `docs/adr/0014-*.md` 依範本寫成;ADR 0008 加註音源邏輯改為 JS 重寫。 - [ ] `phase2-plan.md` 標記第 1 項完成;記下 YouTube 可行性驗證與 flutter_js 實測;記下「腳本插件」為解除凍結的例外。 From c05f0241f19b9f9c221baf63caf97dd663514efd Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 13:55:06 +0800 Subject: [PATCH 030/133] chore(task): fix the source plugin design diagram --- .trellis/tasks/09-27-design-source-plugins/design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-27-design-source-plugins/design.md b/.trellis/tasks/09-27-design-source-plugins/design.md index cc843bbce..7570f947b 100644 --- a/.trellis/tasks/09-27-design-source-plugins/design.md +++ b/.trellis/tasks/09-27-design-source-plugins/design.md @@ -13,8 +13,8 @@ flowchart TB REG --> SP2[ScriptSource:netease.js] REG --> SP3[ScriptSource:youtube.js
    或暫時的 Dart 實作] REG --> SP4[ScriptSource:其他來源的腳本] - IDX[插件庫 index.json
    官方 1morr/fmp-plugins 或自訂] -.安裝/更新.-> REG - subgraph 宿主(App) + IDX[插件庫 index.json
    官方 1morr/fmp-plugins 或自訂] -. "安裝/更新" .-> REG + subgraph HOSTG["宿主(App)"] RT[JS 執行環境 flutter_js
    QuickJS / JavaScriptCore] HOST[宿主 API v1
    http、crypto、storage、log、login] NET[網路層 ADR 0012/0013] From da5d1a02a57a8b28238b3ae2a8bfa88914e09f63 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 13:56:49 +0800 Subject: [PATCH 031/133] docs(adr): 0014 script source plugins from a plugin repository --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 8 ++- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../09-27-design-source-plugins/implement.md | 10 +-- .../tasks/09-27-design-source-plugins/prd.md | 6 +- .../09-27-design-source-plugins/task.json | 4 +- .../0008-rewrite-as-new-app-in-same-repo.md | 2 + docs/adr/0014-script-source-plugins.md | 72 +++++++++++++++++++ 7 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 docs/adr/0014-script-source-plugins.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index c7442eac4..ec54d8fd3 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -117,7 +117,7 @@ flowchart LR | 5 | 18 設定與日誌(✅ 完成,ADR 0011) | 設定存放依賴資料層;日誌與遮蔽函式是網路層的前提。 | | 6 | 12 網路與帳號(✅ 完成,ADR 0012) | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | | 7 | 2 錯誤模型(✅ 完成,ADR 0013) | 音源插件介面的回傳與例外型別要先定。 | -| 8 | 1 音源插件 | 核心抽象;依賴 10、12、2。 | +| 8 | 1 音源插件(✅ 完成,ADR 0014) | 核心抽象;依賴 10、12、2。 | | 9 | 8 測試與開發環境 | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | | 10 | 17 快取與離線 | 串流 URL、圖片、排行快取的策略,播放核心要用。 | | 11 | 16 背景任務 | 刷新、清理、更新檢查誰來排程。 | @@ -222,8 +222,14 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 - ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。 +- ADR 0014:JS 執行環境(`flutter_js`)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;`flutter_js` 在 Android、Windows 的 Promise/記憶體/啟動成本實測;YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)。 ## 8. 延後到特定里程碑的實測 - ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。 - ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 + +## 9. 功能凍結的例外與里程碑規劃備忘 + +- 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27),是功能凍結的唯一例外。 +- 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 159292c55..d3dc3b6db 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -26,7 +26,8 @@ "09-27-design-data", "09-27-design-settings-logging", "09-27-design-network-accounts", - "09-27-design-errors" + "09-27-design-errors", + "09-27-design-source-plugins" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.md b/.trellis/tasks/09-27-design-source-plugins/implement.md index e47e01713..0558dcb50 100644 --- a/.trellis/tasks/09-27-design-source-plugins/implement.md +++ b/.trellis/tasks/09-27-design-source-plugins/implement.md @@ -2,10 +2,10 @@ 本任務只產出設計與 ADR。 -- [ ] 寫 `docs/adr/0014-script-source-plugins.md`:design.md §1–§8;被否決的選項(編譯期 Dart 插件、內建腳本隨 App 打包、插件放在主 repo、背景自動檢查插件更新、先 Dart 後轉腳本、hetu_script、允許腳本讀其他音源憑證或檔案系統、各功能各自的匹配評分);「如何確認」(能力宣告與介面一致的結構測試、腳本重播契約測試、網域清單強制的測試、UI 無音源分支的 lint)。 -- [ ] ADR 0008 加註:音源邏輯改以舊程式碼為規格、用 JS 重寫(見 ADR 0014)。 -- [ ] `phase2-plan.md` 標記第 1 項完成,第一個里程碑必要驗證加入 YouTube 可行性驗證與 flutter_js 實測,並記下腳本插件是解除功能凍結的例外。 -- [ ] `phase2-plan.md` 記下:建立 `1morr/fmp-plugins` repo 與其 CI 排入里程碑規劃(不在本任務建立)。 -- [ ] 歸檔本任務。 +- [x] 寫 `docs/adr/0014-script-source-plugins.md`:design.md §1–§8;被否決的選項(編譯期 Dart 插件、內建腳本隨 App 打包、插件放在主 repo、背景自動檢查插件更新、先 Dart 後轉腳本、hetu_script、允許腳本讀其他音源憑證或檔案系統、各功能各自的匹配評分);「如何確認」(能力宣告與介面一致的結構測試、腳本重播契約測試、網域清單強制的測試、UI 無音源分支的 lint)。 +- [x] ADR 0008 加註:音源邏輯改以舊程式碼為規格、用 JS 重寫(見 ADR 0014)。 +- [x] `phase2-plan.md` 標記第 1 項完成,第一個里程碑必要驗證加入 YouTube 可行性驗證與 flutter_js 實測,並記下腳本插件是解除功能凍結的例外。 +- [x] `phase2-plan.md` 記下:建立 `1morr/fmp-plugins` repo 與其 CI 排入里程碑規劃(不在本任務建立)。 +- [x] 歸檔本任務。 驗證:Mermaid 以 mermaid-cli 渲染。 diff --git a/.trellis/tasks/09-27-design-source-plugins/prd.md b/.trellis/tasks/09-27-design-source-plugins/prd.md index ebd1dbdac..0f97d0faf 100644 --- a/.trellis/tasks/09-27-design-source-plugins/prd.md +++ b/.trellis/tasks/09-27-design-source-plugins/prd.md @@ -42,6 +42,6 @@ ## 驗收標準 -- [ ] design.md 涵蓋介面形狀、manifest、能力、宿主 API、插件庫與安裝與信任、匹配流程、對其他 ADR 的影響、第一個里程碑與 YouTube 驗證。 -- [ ] `docs/adr/0014-*.md` 依範本寫成;ADR 0008 加註音源邏輯改為 JS 重寫。 -- [ ] `phase2-plan.md` 標記第 1 項完成;記下 YouTube 可行性驗證與 flutter_js 實測;記下「腳本插件」為解除凍結的例外。 +- [x] design.md 涵蓋介面形狀、manifest、能力、宿主 API、插件庫與安裝與信任、匹配流程、對其他 ADR 的影響、第一個里程碑與 YouTube 驗證。 +- [x] `docs/adr/0014-*.md` 依範本寫成;ADR 0008 加註音源邏輯改為 JS 重寫。 +- [x] `phase2-plan.md` 標記第 1 項完成;記下 YouTube 可行性驗證與 flutter_js 實測;記下「腳本插件」為解除凍結的例外。 diff --git a/.trellis/tasks/09-27-design-source-plugins/task.json b/.trellis/tasks/09-27-design-source-plugins/task.json index acaa56b1e..d4f8f4c8c 100644 --- a/.trellis/tasks/09-27-design-source-plugins/task.json +++ b/.trellis/tasks/09-27-design-source-plugins/task.json @@ -3,7 +3,7 @@ "name": "design-source-plugins", "title": "Design: source plugins", "description": "Phase-2 item 1: single registration point with declared capabilities for playable, metadata-only and lyrics sources, unified matching flow, no source-specific branches in UI or services", - "status": "planning", + "status": "in_progress", "dev_type": null, "scope": null, "package": null, @@ -12,7 +12,7 @@ "assignee": "1morr", "createdAt": "2026-09-27", "completedAt": null, - "branch": null, + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, diff --git a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md index 33642e433..22abcf83b 100644 --- a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md +++ b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md @@ -1,5 +1,7 @@ # 0008 — 重寫:在同一 repo 的 `app/` 另建新專案,搬運葉節點邏輯 +> 補充(2026-09-27):音源相關的邏輯不搬運 Dart 程式碼,改以舊程式碼為規格、用 JS 腳本重寫並放在獨立插件庫,見 [ADR 0014](0014-script-source-plugins.md)。其他葉節點(例如 `TrackKey` 格式)照本 ADR 搬運。 + - 狀態:已採納 - 日期:2026-09-27 - 影響範圍:repo 目錄結構、`.github/workflows/`、`orca.yaml`、`AGENTS.md`、App 身分識別、舊版發版流程 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md new file mode 100644 index 000000000..7db4e0ef8 --- /dev/null +++ b/docs/adr/0014-script-source-plugins.md @@ -0,0 +1,72 @@ +# 0014 — 音源是執行期 JS 腳本插件,App 不內建,從插件庫安裝 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`SourcePlugin` 介面與註冊表、JS 執行環境與宿主 API、插件頁與首次啟動引導、legacy import 的升級提示、 + 新 repo `1morr/fmp-plugins`、匹配流程 + +## 背景 + +舊專案已有小介面(`SourceCapability` 系列),但新增一個能搜能播的音源最少要改 15 個檔、同網易程度約 54 個; +50 處音源分支散在 28 個檔;電台、Mix、遠端歌單寫死特定音源;歌單匯入與歌詞各有一套匹配評分 +(`docs/audit/sources.md`)。 + +擁有者要求:單一註冊點宣告能力、UI 依能力出現入口、UI 與 service 沒有音源分支、統一匹配流程; +並希望使用者能以 AI Agent 生成自己的音源並安裝。FMP 不上架任何商店(ADR 0009)。 +為此,擁有者明確將腳本插件納入重寫範圍(功能凍結的例外)。 + +ADR 0009–0013 已定的音源義務(遮蔽名單、`AuthRequirement`、登入方式、憑證無效判定、錯誤對應表、重試策略)由插件的 +manifest 與腳本承擔。 + +## 考慮過的選項 + +- **編譯期 Dart 插件**:型別與測試最直接;但修音源要發 App 新版,使用者無法自行加音源。否決。 +- **先用 Dart 寫內建音源、之後再轉腳本**:前期穩,但三個音源邏輯要寫兩次,腳本 API 很晚才被真實使用驗證。否決。 +- **腳本語言用 `hetu_script`**(Spotube 採用):Dart 風格小眾語言,AI 生成能力差。否決,改用 JS。 +- **內建腳本隨 App 打包**:首次啟動即可用;但修音源仍要發 App、App 本體含非官方 API 呼叫。否決。 +- **插件放在 FMP 主 repo**:CI 與版本管理簡單,但失去 App 本體與插件的分離。否決。 +- **背景自動檢查插件更新**:與擁有者對 App 更新「只手動檢查」的要求不一致。否決。 +- **允許腳本讀其他音源憑證或檔案系統**:否決。 + +## 決定 + +1. **一套介面 `SourcePlugin`**:App 其他部分只認介面與能力宣告,分不出來源是誰、是否為腳本;UI 與 service 沒有針對特定音源的分支。 +2. **所有來源都是 JS 腳本+manifest,App 不內建任何來源**:可播放音源(B 站、網易、YouTube)、僅元資料來源(Spotify、QQ 匯入)、 + 歌詞源(網易、QQ、lrclib)。引擎為 `flutter_js`(Android/Windows/Linux 用 QuickJS,iOS/macOS 用 JavaScriptCore),ES2020。 + 音源邏輯以舊 Dart 程式碼為規格、用 JS 重寫(調整 ADR 0008 的「搬運葉節點」僅適用非音源部分)。 +3. **manifest**:`id`(字串音源 id)、名稱、版本、作者、`apiVersion`、能力、允許的網域、登入方式、重試與限流策略、遮蔽名單追加、預設值、圖示。 +4. **能力**:`search`、`resolveStream`、`trackDetail`、`multiPart`、`importPlaylist`、`libraryRead`、`libraryWrite`、`charts`、`live`、`mix`、`lyrics`、`login`。 + 可播放音源=有 `resolveStream`;僅元資料來源與歌詞源依能力區分,不另立型別。下載由宿主處理,不是插件能力。 + 同一能力有多個提供者時 UI 全部列出。 +5. **宿主 API v1**(腳本能用的全部):`http.request`(經 ADR 0012/0013 網路層、只能連 manifest 網域)、`crypto`、每插件 `storage`、 + 只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`)。沒有檔案系統、任意 socket、其他插件的資料。 + 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。 +6. **插件庫**:官方插件在獨立 repo `1morr/fmp-plugins`,每插件一目錄(腳本、manifest、錄下的測試 fixture),其 CI 跑契約測試並產生 + `index.json`(含 SHA-256)。App 插件頁預設讀官方 index,可加自訂 index 網址,也可從檔案或網址安裝;由 index 安裝時驗證 SHA-256。 + 安裝前顯示能力與會連的網域,並警告「此腳本會以你的登入身分存取這些網站」。 +7. **更新**:只在打開插件頁或手動檢查時比對 index,可一鍵全部更新;音源壞掉以更新插件修復,不必發 App 新版。 +8. **首次啟動與升級**:沒有來源時引導安裝官方插件;legacy import 偵測舊資料用到的音源並提示一鍵安裝,未安裝前曲目標示「音源未安裝」。 + 移除插件時清除其 storage 與憑證,曲目保留並標示。 +9. **匹配**:宿主一份共用評分核心(標題、歌手、時長容差,歌詞另加同步歌詞加分),歌單匯入與歌詞共用;對所有啟用的目標來源比較取最高分, + 同分依使用者排序;目標來源集合由使用者設定,自動與手動重搜一致;結果持久化,使用者改選後不再重算;匹配失敗保留並標示。 +10. **YouTube 退路**:可行性驗證(YouTube.js 在 `flutter_js` 能否搜尋並解出串流;它官方只寫支援 Node.js、Deno、瀏覽器,需宿主提供 fetch 與 eval) + 有時限;失敗則 YouTube 暫以 Dart 實作同一個 `SourcePlugin` 介面。 + +採用的慣例:MusicFree、LX Music 的 JS 腳本插件與插件訂閱(App 本體不附音源);Spotube 的 manifest(能力、API 版本)與 iOS 側載發佈; +Flutter federated plugin 的「一套介面、多種實作」;Spotube 的匹配結果快取與使用者改選。只參考設計,不複製程式碼(MusicFree 為 AGPL-3.0)。 + +## 後果 + +- 好的:新增音源=在插件庫新增一個目錄或自行安裝腳本;修音源不必發 App;ADR 0011–0013 的保護自動套用到所有腳本; + App 本體不含非官方 API 呼叫,降低主 repo 的暴露面(不消除風險;B 站社群 API 文件庫已於 2026-01 因存證信函關閉)。 +- 壞的:第一個里程碑變重(要先有 JS 執行環境與宿主 API);腳本除錯比 Dart 難;首次啟動多一步安裝;要維護第二個 repo 與其 CI; + 宿主 API 一經發佈就要維持相容(以 `apiVersion` 管理)。 +- 之後要注意:`flutter_js` 在 Android 與 Windows 的 Promise、記憶體與啟動成本需實測;YouTube 可行性驗證;插件庫 repo 與插件頁的建立時程在里程碑規劃定; + 自動檢查插件更新若日後需要,另立決定。 + +## 如何確認 + +- 結構測試:每個插件的 manifest 能力與它實際匯出的函式一致;`apiVersion` 不相容時拒絕載入。 +- 契約測試:以錄下的 HTTP 回應重播執行每個插件,涵蓋 ADR 0011(遮蔽)、0012(媒體請求不帶憑證、`AuthRequirement`)、0013(錯誤對應);插件 repo 的 CI 與插件作者本機都能跑。 +- 測試:宿主 HTTP 拒絕 manifest 網域以外的請求;腳本無法讀取其他插件的 storage 與憑證。 +- lint:UI 與 service 不得出現音源 id 字串常數或特定音源的型別(測試策略 ADR 落實)。 From edee2d0d85dbf82fca4121d2b0daec6480635f65 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 13:56:50 +0800 Subject: [PATCH 032/133] chore(task): archive design-source-plugins --- .../2026-09}/09-27-design-source-plugins/check.jsonl | 0 .../2026-09}/09-27-design-source-plugins/design.md | 0 .../2026-09}/09-27-design-source-plugins/implement.jsonl | 0 .../2026-09}/09-27-design-source-plugins/implement.md | 0 .../{ => archive/2026-09}/09-27-design-source-plugins/prd.md | 0 .../research/capability-modeling-and-matching.md | 0 .../research/peer-plugin-interfaces.md | 0 .../2026-09}/09-27-design-source-plugins/task.json | 4 ++-- 8 files changed, 2 insertions(+), 2 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/implement.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/research/capability-modeling-and-matching.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/research/peer-plugin-interfaces.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-source-plugins/task.json (92%) diff --git a/.trellis/tasks/09-27-design-source-plugins/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/check.jsonl diff --git a/.trellis/tasks/09-27-design-source-plugins/design.md b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/design.md similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/design.md diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/implement.jsonl diff --git a/.trellis/tasks/09-27-design-source-plugins/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/implement.md similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/implement.md rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/implement.md diff --git a/.trellis/tasks/09-27-design-source-plugins/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/prd.md diff --git a/.trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/research/capability-modeling-and-matching.md similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/research/capability-modeling-and-matching.md rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/research/capability-modeling-and-matching.md diff --git a/.trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/research/peer-plugin-interfaces.md similarity index 100% rename from .trellis/tasks/09-27-design-source-plugins/research/peer-plugin-interfaces.md rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/research/peer-plugin-interfaces.md diff --git a/.trellis/tasks/09-27-design-source-plugins/task.json b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/task.json similarity index 92% rename from .trellis/tasks/09-27-design-source-plugins/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-source-plugins/task.json index d4f8f4c8c..4ccf1a294 100644 --- a/.trellis/tasks/09-27-design-source-plugins/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-source-plugins/task.json @@ -3,7 +3,7 @@ "name": "design-source-plugins", "title": "Design: source plugins", "description": "Phase-2 item 1: single registration point with declared capabilities for playable, metadata-only and lyrics sources, unified matching flow, no source-specific branches in UI or services", - "status": "in_progress", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,7 +11,7 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, + "completedAt": "2026-09-27", "branch": "docs/audit", "base_branch": "main", "worktree_path": null, From f402e5f64710008c4ce36eb2e2a29f1688b890cd Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:03:26 +0800 Subject: [PATCH 033/133] chore(task): add a handoff note to the phase-two plan --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index ec54d8fd3..0dfe2ef71 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -233,3 +233,15 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27),是功能凍結的唯一例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 + +## 10. 目前進度與下一步(交接用,2026-09-27) + +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0014`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 +- **進行中:第 8 項「測試、閘門與開發環境」**,task `.trellis/tasks/09-27-design-testing/`(planning 狀態); + 研究代理的產出寫到該目錄 `research/`(`lint-and-gates.md`、`fixtures-and-network.md`、`dev-env-and-ci.md`)。 + 下一步:讀研究 → 寫 prd.md(現況、研究結論、待決定)→ 一次問使用者一個問題 → design.md/implement.md → 最終摘要等核准 → 寫 ADR 0015 → 歸檔。 +- 之後順序:17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 +- 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 From ab1e58a1d995e2642a5dc2fb61ed3522a6080f79 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:35:23 +0800 Subject: [PATCH 034/133] chore(task): add design-testing research and prd draft --- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../tasks/09-27-design-testing/check.jsonl | 0 .../09-27-design-testing/implement.jsonl | 0 .trellis/tasks/09-27-design-testing/prd.md | 69 +++ .../research/dev-env-and-ci.md | 275 ++++++++++++ .../research/fixtures-and-network.md | 333 ++++++++++++++ .../research/lint-and-gates.md | 425 ++++++++++++++++++ .trellis/tasks/09-27-design-testing/task.json | 26 ++ 8 files changed, 1130 insertions(+), 1 deletion(-) create mode 100644 .trellis/tasks/09-27-design-testing/check.jsonl create mode 100644 .trellis/tasks/09-27-design-testing/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-testing/prd.md create mode 100644 .trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md create mode 100644 .trellis/tasks/09-27-design-testing/research/fixtures-and-network.md create mode 100644 .trellis/tasks/09-27-design-testing/research/lint-and-gates.md create mode 100644 .trellis/tasks/09-27-design-testing/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index d3dc3b6db..29cfe2f10 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -27,7 +27,8 @@ "09-27-design-settings-logging", "09-27-design-network-accounts", "09-27-design-errors", - "09-27-design-source-plugins" + "09-27-design-source-plugins", + "09-27-design-testing" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-testing/check.jsonl b/.trellis/tasks/09-27-design-testing/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-testing/implement.jsonl b/.trellis/tasks/09-27-design-testing/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-testing/prd.md b/.trellis/tasks/09-27-design-testing/prd.md new file mode 100644 index 000000000..6f72eecaf --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/prd.md @@ -0,0 +1,69 @@ +# 設計:測試、閘門與開發環境(階段二第 8 項) + +## 目標 + +為 `app/` 定下:保留哪些舊測試與 static-rule、新架構的閘門(lint、測試、CI)、零聯網的預設測試與 fixture、 +腳本插件的共用契約測試、聯網冒煙測試、開發時少打真實 API 的方法,以及開發版與正式版分離(U9、單一實例)。 +產出 ADR 0015。 + +依據:parent `prd.md` 階段二第 8 項;`phase2-plan.md` §4(測試、static-rule、單一實例三段); +`docs/audit/questions.md` §10(四類測試你都勾「不確定」並附備註)與 U9;ADR 0008–0014 的「如何確認」段。 + +## 現況(審計,`docs/audit/engineering.md`) + +- 約 1,849 個離線測試本機全過(2 分 48 秒);25 支 static-rule(144 個 test)以正則比對原始碼,部分是計次預算 + (`audio_provider.dart` ≤ 2,184 行;音源分支預算 9 處但實際 50 處沒守住)。 +- `dart_test.yaml` 只宣告 `live` tag、沒有預設跳過:**裸 `flutter test` 會打真實 API**(4 個 live 測試);CI 靠 `--exclude-tags live`。 +- 部分行為測試依賴 `debug*ForTesting` 掛鉤(下載服務 44 處,全專案 `debug*` 成員 75 處)。 +- CI(`.github/workflows/ci.yml`):單一專案、不做路徑過濾(理由寫在檔頭),釘 Flutter 3.47.1;validate 7 分、Android 6 分、Windows 10 分。 +- 開發版與正式版共用同一個單一實例鎖與同一份資料(Windows `Documents\FMP`),開發時會動到真實資料。 + +## 你已表達的方向 + +- 測試不打真實 API;真實 API 只在 Debug 頁手動檢查或明確指定的冒煙測試(`questions.md` §10 備註)。 +- 冒煙測試不進 CI(`phase2-plan.md` §4 傾向,你在順序確認時「按推薦」)。 +- 只保留守「行為一致」的必要測試;static-rule 改用 Dart analyzer lint(`phase2-plan.md` §6)。 +- 開發版資料隔離(U9 勾選);單一實例保留給正式版。 + +## 研究結論(`research/` 三份,已抽查關鍵事實) + +1. **lint**:官方 `analysis_server_plugin`(Dart 3.10+)自寫規則;`custom_lint` 已封存且依賴的舊協定在 Dart 3.13.2 棄用。 + 規則測試用官方 `analyzer_testing` 的 `assertDiagnostics`/`assertNoDiagnostics`,正好是「雙向變異驗證」。 + 現成工具(DCM 付費、DCL)只能做 import/呼叫限制,ADR 0013 的嚴格空 catch 與 ADR 0014 的音源 id 規則都要自寫,所以全部自寫、不引入 DCM。 + **地雷**:`flutter analyze` 目前不顯示 plugin 診斷並回報 No issues(flutter/flutter#193203,3.47.5 可重現,修復未確認進 stable) + → CI 用 `dart analyze --fatal-infos` 並放一個必紅的哨兵檔驗證 plugin 有接上。 + 官方 `empty_catches` 放行 `catch (_) {}`,不符 ADR 0013。 +2. **fixture**:不用現成套件(`vcr` 系維護不明、`dartvcr` 是 `package:http` 不是 dio),自寫薄的 dio `HttpClientAdapter` + 在最底層錄製/重播;因為 adapter 層看到的請求已含憑證,寫檔前一律經 ADR 0011 的正式遮蔽函式,另有測試掃描所有 fixture 不得含未遮蔽憑證。 + JS 插件只經宿主 `http.request` 出網,契約測試只換掉宿主這一端,腳本不知道自己在測試。 +3. **零聯網**:`dart_test.yaml` 對 `live` tag 設 `skip`(`presets` 解除,已查 dart-lang/test 設定文件)+ + `flutter_test_config.dart` 用 `HttpOverrides.global` 讓建立真實 `HttpClient` 直接丟錯。 +4. **契約測試在哪裡跑**:`flutter_js` 的原生 QuickJS 在 `flutter test`(純 Dart VM)不會自動載入,需先建好動態庫再指定路徑 + (`quickjs_engine` 文件同樣說明);`integration_test` 在桌面跑真的 App 二進位則一定載得到。→ 第一個里程碑實測。 +5. **開發版**:Flutter 3.47 起 Windows/Linux 有官方 `--flavor`;`pubspec.yaml` 的 `flutter: default-flavor:` 讓不帶參數的 + `flutter run` 用指定 flavor(context7 查證)。官方 flavor 只管建置輸出、視窗標題、圖示; + Windows AppUserModelID、資料目錄、單一實例鎖名稱要自己依 `appFlavor` 接上(推測可行,未實測)。Android 用 `applicationIdSuffix`。 +6. **CI**:公開 repo 的 GitHub-hosted runner 免費不限分鐘;兩個 Flutter 專案用 `dorny/paths-filter` 依專案切 job, + 不依「是不是程式碼」切(舊檔頭理由仍成立);彙總 job 當唯一必要檢查。 +7. **測試比例**:Flutter 官方不給數字,只給「單元+widget 多、整合測試挑重要情境」。golden 用 `alchemist` 的 CI golden(Ahem 字型,跨平台一致), + `golden_toolkit` 已停更。 + +## 待決定 + +- [ ] 插件開發迴圈與 fixture 錄製在哪裡做(App 內開發工具 vs 只有命令列) +- [ ] 開發版資料:永遠從空白開始,或可從正式版複製一份快照 +- 其餘(lint 規則清單、空 catch 例外寫法、舊 static-rule 逐條去留、golden 範圍、CI 切分)屬技術選擇,放進 design.md 與最終摘要一併核准。 + +## 驗收條件 + +- [ ] ADR 0015 記錄:測試分層與保留原則、lint 閘門與 CI 指令、零聯網機制、fixture 格式與遮蔽、插件契約測試/冒煙測試/健康檢查的關係、開發版身分與資料隔離、CI 切分。 +- [ ] 舊 static-rule 25 支逐條給出去向(改 lint/改測試/刪除/屬舊專案不動),附理由。 +- [ ] ADR 0008(`app/` 不 import 舊專案)、0011(遮蔽測試)、0013(空 catch、原文不上畫面)、0014(契約測試、音源 id lint)的「如何確認」各自對到一個具體閘門。 +- [ ] 第一個里程碑的必要驗證(`phase2-plan.md` §7)補上本項的實測項。 +- [ ] `phase2-plan.md` §3 第 8 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 實作任何測試、lint 或 CI(屬各里程碑)。 +- Debug 頁的版面與其他功能(第 4 項);本項只定健康檢查與插件開發工具「要不要有、共用什麼」。 +- 舊專案(根目錄)的測試調整,除了 CI 切分。 diff --git a/.trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md b/.trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md new file mode 100644 index 000000000..4ef7d0a7e --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md @@ -0,0 +1,275 @@ +# 研究:開發版/正式版分離、CI 矩陣與測試比例 + +> 對應 `.trellis/tasks/09-27-design-testing` 研究第 4、5、6 點:Flutter +> flavor 機制(尤其 Windows/Linux 現況)、GitHub Actions 費用與 +> iOS/Linux 建置需求、單一 repo 兩個 Flutter 專案的 CI 路徑過濾、 +> 單元/widget/整合測試比例的官方指引、golden test 是否值得採用。 +> 查證方式:Flutter 官方文件(WebFetch)、GitHub 官方文件與第三方 +> 定價站交叉核對(WebSearch)、repo 內 `.github/workflows/ci.yml` +> 原始碼直讀。查不到的一律寫「查不到」,推論一律標「推測」。 +> 查證時間 2026-09-27。 + +--- + +## 第 4 點:開發版與正式版分離 + +### 重要前提修正:Windows/Linux 現在都有官方 flavor 支援 + +任務原始描述預設「Windows 過去沒有官方 flavor 支援」,這個前提 +**已經過時**。查證結果: + +- **Windows**:官方文件明講「Windows 的內建 flavor 支援需要 + **Flutter 3.47 或以後**」 + ()。 +- **Linux**:官方文件同樣要求 **Flutter 3.47 或以後** + ()。 +- FMP 的 `ci.yml` 目前釘的版本是 `FLUTTER_VERSION: '3.47.1'` + (`.github/workflows/ci.yml:28`)——**剛好在支援門檻之上**,`app/` + 可以直接用官方 `--flavor` 機制,不需要任何 `--dart-define` 式的 + 手刻繞路方案。 + +### 機制與 FMP 需要的四項隔離:App 身分、資料目錄、單一實例、視窗標題 + +Windows 與 Linux 的機制幾乎一致,都是把 flavor 名稱寫進 +`generated_config.cmake` 的 `FLUTTER_APP_FLAVOR`(在 +`add_subdirectory(${FLUTTER_MANAGED_DIR})` **之後**才可見,寫在 +之前的 `if(DEFINED FLUTTER_APP_FLAVOR)` 判斷會被靜默略過,兩個 +平台的官方文件都特別提醒這個順序陷阱)。建置輸出會落在各自的 +flavor 子目錄(例如 `build/windows//staging/runner/Release/`、 +`build/linux//staging/release/bundle/`),Dart 端可讀到 +`appFlavor` 常數。 + +逐項對照 FMP 的需求(沿用 ADR 0008 決定 3「開發版另用身分,與正式版 +分開」): + +| 需求 | Windows 做法 | Linux 做法 | +|---|---|---| +| App 身分(AppUserModelID/類似識別) | 官方文件本身**沒有涵蓋** AppUserModelID 這類識別碼的逐 flavor 設定,只示範視窗標題/圖示/`FileDescription`/`ProductName`(`windows/runner/CMakeLists.txt` 用 `configure_file` 產生 `main.cpp`/`Runner.rc` 的 `.in` 樣板,依 `FLUTTER_APP_FLAVOR` 切換字串)。FMP 現有 `windows/runner/main.cpp:43` 寫死 `com.personal.fmp` 這個 AppUserModelID,要讓開發版另用身分,需要**在同一份 `.in` 樣板機制內,額外把 AppUserModelID 字串也做成依 flavor 切換的變數**——這是文件沒有直接示範、但同一套「樣板 + CMake 變數替換」機制天然可以延伸支援的用法,屬於**推測**:官方沒有反例說「不能」,但也沒有把 AppUserModelID 列為官方支援項目之一,落地時要自己加、自己測。 | Linux 的圖示不內嵌在執行檔,來自 `.desktop` 檔與圖示主題,官方文件建議透過打包格式(Snap/Flatpak/Debian)分流,這代表 Linux 上的「App 身分」更多是打包層級的事,不是像 Windows 那樣有一個單一「AppUserModelID」欄位。 | +| 資料目錄 | 不是 flavor 機制直接管的範圍;FMP 現有資料目錄邏輯(通常經 `path_provider` 取得使用者資料夾)**需要自己依 `appFlavor` 值組出不同的子路徑**,例如正式版用 `com.personal.fmp`、開發版用 `com.personal.fmp.dev` 當作資料夾名稱的一部分。 | 同左,`appFlavor` 常數可讀到,路徑組合邏輯要自己寫。 | +| 單一實例(single-instance)互斥鎖 | FMP 若原本用具名 mutex/window class 判斷「是否已有一個實例在跑」,這個名稱字串同樣要依 `appFlavor` 加後綴,讓開發版與正式版的互斥鎖不互相干擾——**這部分官方文件完全沒有涵蓋**(不屬於 flavor 機制本身,是 FMP 自己的單例邏輯要接上 `appFlavor`),標記為需要 `implement.md` 階段自行設計。 | 同左。 | +| 視窗標題 | 官方文件直接示範:改 `windows/runner/CMakeLists.txt` 在 `if(FLUTTER_APP_FLAVOR STREQUAL "staging")` 分支設 `WINDOW_TITLE`,透過 `.in` 樣板注入 `main.cpp`。 | 官方文件示範用 `add_definitions(-DFLUTTER_APP_FLAVOR="...")` 把 flavor 字串傳進 C++ 端的 `my_application.cc`,用 `#ifdef`/`g_strcmp0` 判斷分支設標題。 | + +**結論**:Flutter 官方 flavor 機制解決的是「建置輸出隔離」與「視窗 +標題/圖示這類展示層」的部分,FMP 真正在意的「App 身分識別 +(AppUserModelID)、資料目錄、single-instance 互斥鎖」三項**都不是 +flavor 機制原生涵蓋的範圍,而是要在同一個 `appFlavor` 常數/ +`FLUTTER_APP_FLAVOR` CMake 變數的基礎上,自己把這三個字串/路徑做成 +依 flavor 切換**——**flavor 機制提供的是「一個可靠的、建置期就決定 +好的字串(`appFlavor`)」,FMP 自己的程式碼要負責「拿這個字串去組出 +App 身分、資料目錄、mutex 名稱」,這件事本身沒有官方文件可以照抄, +需要在 `design.md`/`implement.md` 階段設計。 + +### Android + +Android 的官方 flavor 機制(`productFlavors`、 +`applicationIdSuffix`)是最成熟、行之有年的方案,**本研究未重新查證 +細節**(沿用先前研究結論:Android 用 `applicationIdSuffix` 可以讓 +開發版與正式版是完全不同的 `applicationId`,天生就有獨立的資料目錄 +與獨立安裝,Android 系統層級保證兩者不會互相干擾單例——這點是 +Android 平台本身的沙盒機制決定的,不需要 FMP 自己實作單例互斥判斷)。 + +--- + +## 第 5 點:CI 矩陣與成本 + +### GitHub Actions 對公開 repo 免費、無實質分鐘數上限 + +- 官方文件確認:公開 repo 使用標準 GitHub-hosted runner(含 + Linux/Windows/macOS)完全免費,沒有分鐘數上限,只受一般的 + 合理使用政策約束(來源:GitHub 官方帳單文件 + , + 經 WebSearch 摘要交叉核對多個第三方定價站的說法一致)。 +- 分鐘數配額與 OS 倍率(Linux 1x/Windows 2x/macOS 10x)**只影響 + 私有 repo**,FMP(`1morr/FMP`)是公開 repo,這點對 FMP 不構成 + 限制。 +- 2026 年的計費調整(2026-01-01 生效的降價、`self-hosted` runner + 收費一度宣布又在 48 小時內撤回等變動)**都明確排除公開 repo**—— + 多個來源一致確認「公開 repo 的標準/self-hosted runner 使用維持 + 免費」。這部分屬於第三方站台的整理與 GitHub 官方文件的交叉比對, + 非單一權威來源逐字引用,但方向一致,可信度高。 + +**結論**:FMP 在 CI 矩陣設計上**不需要顧慮 runner 分鐘數費用**,可以 +放心加入 macOS(跑 iOS 建置)與額外的 Linux 建置 job,不必為了省 +分鐘數而犧牲涵蓋範圍。 + +### iOS 建置與 Linux 建置需求 + +- `flutter build ios --no-codesign` 需要在 `macos-latest` runner 上 + 跑(iOS 建置工具鏈只存在於 macOS,這是 Xcode 的限制,非 GitHub + Actions 特有)。可以額外用 `--config-only` 只產生 Xcode 專案而不 + 真正編譯,用於更輕量的「專案設定正確性」檢查;若要更完整驗證, + 搭配 iOS Simulator(`xcrun simctl` 或 `flutter test -d + `)跑 `integration_test`(見下方第 6 點的桌面/ + 模擬器支援現況)。 +- Linux 建置需要 GTK 開發套件(`libgtk-3-dev` 等,Flutter 官方 + `flutter build linux` 的前置需求),**本研究沿用先前已確認的 + 結論、本次未重新逐條查證套件清單**,落地時建議直接抄 Flutter + 官方 Linux 桌面設定文件當下列出的套件清單,而非憑記憶列舉, + 避免版本間套件名稱變動(例如 GTK3 與 GTK4 過渡期的套件名稱 + 差異)。 + +### CI 如何只跑「被改到的那個 Flutter 專案」——路徑過濾設計 + +**先重新檢視舊 `ci.yml` 的「不做路徑過濾」理由是否仍然成立**: + +`.github/workflows/ci.yml:3-7` 原文(逐字): + +> No path filter. Markdown carries rules that tests enforce -- the +> agent instruction files most of all -- so a prose-only commit is +> exactly the one that must not skip `validate`. `paths-ignore` is +> trigger-level and cannot skip only the build jobs; measured run +> time is 23 minutes total (validate 7, Android 6, Windows 10), +> which is not worth a changed-files job to avoid. + +這段推理成立的前提是「**單一 Flutter 專案**」:`validate`/ +Android/Windows 三個 job 全部針對同一份程式碼,唯一要回答的問題是 +「這次改動要不要跑 CI」,答案是「除非確定完全不影響任何被測試強制 +的規則,否則都要跑」——純文件改動(尤其是 agent 指令檔,它們本身 +承載被測試強制執行的規則)沒有這種確定性,所以不排除。**這個結論 +不變**,`app/` 加入後,「純 markdown 改動要不要跳過所有 CI」的答案 +仍然是不要。 + +但這個舊理由**沒有回答、也不需要回答**一個新問題:一旦 repo 裡有 +**兩個獨立的 Flutter 專案**(根目錄舊專案+`app/`),**改動只涉及 +其中一個專案時,另一個專案的 job 該不該跑?** 這是舊理由誕生時 +(單一專案)根本不存在的情境,不能用「23 分鐘不值得」這句話簡單 +帶過——因為現在的問題不是「省 CI 分鐘數」,而是「兩個專案的 CI +邏輯已經不同(不同的 `pubspec.yaml`、不同的 lint 設定、`app/` +之後會有 `analysis_server_plugin` 而舊專案不會),把它們**混在 +同一個 job 矩陣裡本身就會讓失敗原因難以歸因**(例如 `app/` 的 lint +regression 會被誤讀成整個 repo 出問題)。 + +**建議**:對「兩個專案之間」做路徑過濾(`app/` 變動只跑 `app/` 的 +job;根目錄變動只跑根目錄舊專案的 job;`.github/workflows/`/ +repo 層級設定檔變動兩者都跑),但**維持「不對 markdown/文件類 +變動做排除」的舊原則**——也就是說路徑過濾的切分軸是「這是哪個 +專案的程式碼」,不是「這是不是程式碼」。標準做法: + +- `dorny/paths-filter`(GitHub Marketplace 上維護活躍的路徑過濾 + action,本研究沿用先前查證、本次未重新確認其最新版本號,落地 + 時建議直接查 的 releases + 頁面取得當下最新版本並用 commit SHA pin,與 FMP 現有 `ci.yml` + 已經對 `actions/checkout` 採用 commit SHA pin 的慣例一致)在 + 一個獨立的 `changes` job 裡宣告兩組路徑過濾規則(`app/**` + 一組、根目錄舊專案的路徑一組,兩者互斥),下游的 `validate-app`/ + `validate-legacy` 等 job 用 `if: + needs.changes.outputs.app == 'true'` 之類的條件決定要不要跑; + 用一個 `always()` 的彙總 job 把所有條件 job 的結果收斂成單一 + 必要狀態檢查(branch protection 只認一個 job 名稱時常見的模式), + 避免「被跳過的 job」被 GitHub 誤判為「必要檢查未通過」。 +- 這個 `changes`/彙總 job 的寫法屬於社群廣泛使用的標準 + monorepo 模式,非 FMP 特有設計,落地時可直接抄 `dorny/paths-filter` + 官方 README 的範例。 + +--- + +## 第 6 點:測試比例與 golden test + +### 官方對單元/widget/整合測試比例沒有給數字 + +Flutter 官方測試總覽頁(, +2026-09-27 查證)明講不給比例,只給定性權衡: + +> "Generally speaking, a well-tested app has many unit and widget +> tests, tracked by code coverage, plus enough integration tests to +> cover all the important use cases." + +權衡表(原文逐項對照): + +| | 單元測試 | Widget 測試 | 整合測試 | +|---|---|---|---| +| 信心程度 | 低 | 較高 | 最高 | +| 維護成本 | 低 | 較高 | 最高 | +| 依賴數量 | 少 | 較多 | 最多 | +| 執行速度 | 快 | 快 | 慢 | + +**結論**:FMP 要採用的具體比例(例如「每個 service 至少 N 個單元 +測試」「每個關鍵使用者流程一個整合測試」)**是團隊/擁有者的選擇, +不是 Flutter 官方的硬性規定**——這點應該列入最終報告的待決策清單, +而不是本研究替擁有者下決定。可以參考的方向:官方的建議精神是 +「單元+widget 測試盡量多、用 code coverage 追蹤;整合測試只挑 +『重要使用情境』,不要求全覆蓋」。 + +### `integration_test` 套件桌面支援現況(2026-09 官方文件) + +- 官方 + (頁面更新時間 2026-07-31,對應 Flutter 3.47 世代文件)確認 + Windows/macOS/Linux 桌面平台都是**第一方支援**,用法是在 + 專案根目錄跑 `flutter test integration_test/app_test.dart`, + 若跳出裝置選擇提示就選桌面平台;也支援 `flutter test + integration_test -d ` 直接指定裝置,不需互動選擇。 +- **限制**:`integration_test` 無法自動化「原生系統 UI」——作業系統 + 層級的權限對話框、通知、原生元件——這點官方文件與套件測試文件 + ()都明確 + 說明。若 FMP 需要測到原生對話框層級的互動,**Patrol** 套件是 + 常見的擴充方案,但 Patrol **目前只支援 Android/iOS/macOS/ + web,不支援 Windows/Linux**——這代表 FMP 在 Windows/Linux 上 + 若真的需要原生 UI 層級互動測試,`integration_test` 是唯一選項, + 沒有現成的「加強版」可用;反過來說,FMP 目前已知的驗證需求 + (音源搜尋播放、UI 頁面渲染)多半不涉及原生系統對話框, + `integration_test` 本身應該足夠。 +- **建置限制**:桌面應用必須在對應的作業系統上建置(Windows 建置 + 要在 Windows 上跑、macOS 在 macOS、Linux 在 Linux),CI 上代表 + 每個平台各自需要一個 runner——這與第 5 點的 CI 矩陣設計直接相關, + 不是額外的新限制,只是重申。 + +### golden test 是否值得採用——建議採用,但用 `alchemist` 而非 +`golden_toolkit` + +- **`golden_toolkit`(eBay Motors)已停止維護**:最後版本 + 0.15.0,多個開源專案已經開 issue 要遷移離開(例如 + `wger-project/flutter#732`「目前用的 golden_toolkit 已被放棄, + 雖然只用在少數地方,也應該換成沒被放棄的東西」),第三方文章 + 指出它三年沒更新(來源:WebSearch 摘要,未逐一核對每篇文章的 + 發布時間,但多篇獨立來源結論一致)。 +- **`alchemist`(Betterment + Very Good Ventures)是目前主流遷移 + 目標**:pub.dev ,最低 + Flutter 版本需求 3.32.0(低於 FMP 的 3.47.1,相容),下載量與 + 分數(219 個 like、160 分、33 萬+ 下載,查證當下 libraries.io + 快照)顯示採用度高。核心設計正好解決「跨平台字型渲染差異」這個 + 任務原始描述關心的問題: + - **CI golden**:用 Ahem 字型(把所有文字渲染成方塊),文字內容 + 不影響像素輸出,**在任何作業系統上跑都應該得到位元完全相同的 + 圖片**,適合進版控、適合在 Linux CI 上跑而不用擔心字型渲染 + 差異導致跨平台假陽性失敗。 + - **Platform golden**:用真實字型渲染,只適合在同一台機器/同一 + 作業系統上比較(例如本機開發者自己驗證畫面),**建議 + gitignore、不進版控**,因為換一台機器(不同字型渲染引擎)比 + 對就會失準。 + - 兩種各自用 `AlchemistConfig` 設定,API 是 `goldenTest`/ + `GoldenTestGroup`/`GoldenTestScenario`,與舊 + `golden_toolkit` 的 `multiScreenGolden`/`screenMatchesGolden` + 不同,若日後任何舊程式碼(根目錄舊專案)已經用 + `golden_toolkit`,遷移到 `app/` 時需要重寫(但 ADR 0008 本來 + 就是複製葉節點邏輯、不 import 舊專案,golden test 屬於測試 + 程式碼、且是 UI 層,本來就不在「複製葉節點」的範圍內,等於 + 在 `app/` 從零開始寫)。 +- **建議**:FMP 的 UI 元件(尤其 ADR 提到的「圖片載入語意元件」、 + `ScopedSlider` 這類有明確規格、容易被意外破壞外觀的共用元件) + 適合用 alchemist 的 CI golden(Ahem 字型版本)進版控,作為 + 「這個元件的視覺結構沒有意外跑掉」的低成本回歸防護;不建議對 + 「每一個頁面的每一種狀態」都上 golden test,golden test 的 + 維護成本(UI 微調就要重新產生 golden 圖)與整合測試接近「較高」 + 的那一檔,過度使用會拖慢日常開發,這點與官方測試金字塔的精神 + (widget/整合測試維護成本較高、應該挑重要案例)一致。 + +--- + +## 待補查項(誠實列出) + +- Windows AppUserModelID 是否能透過 flavor 樣板機制(`.in` 檔 + 變數替換)乾淨地依 flavor 切換,本研究只確認「機制上看起來可以 + 延伸」,**標記為推測**,未在真實 FMP `windows/runner/main.cpp` + 上實際試做一次,落地前必須動手驗證一次「開發版與正式版是否真的 + 各自有獨立的 AppUserModelID、且互不觸發對方的單一實例判斷」。 +- Linux 建置所需的確切套件清單(GTK 版本、其他系統相依套件)本次 + 未重新查證,沿用先前研究結論,落地前應直接參照 Flutter 官方 + Linux 桌面文件當時列出的清單。 +- `dorny/paths-filter` 目前最新版本號與其官方 README 目前確切的 + monorepo 範例語法,本次未重新開啟該 repo 逐字核對,落地前需要 + 直接查最新 release 並抄它當時的範例,而非依賴本研究記憶中的 + 慣例寫法。 +- Android `productFlavors`/`applicationIdSuffix` 的細節本次未重新 + 查證(沿用先前研究),若擁有者對 Android 開發版身分有更細節的 + 要求(例如是否也要像 Windows 一樣處理視窗標題等價物、圖示), + 需要另外針對 Android 官方 flavor 文件查證。 diff --git a/.trellis/tasks/09-27-design-testing/research/fixtures-and-network.md b/.trellis/tasks/09-27-design-testing/research/fixtures-and-network.md new file mode 100644 index 000000000..024eecaa4 --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/research/fixtures-and-network.md @@ -0,0 +1,333 @@ +# 研究:HTTP 錄製重播與零網路測試 + +> 對應 `.trellis/tasks/09-27-design-testing` 研究第 2、3 點:dio 生態系的 +> HTTP fixture 錄製/重播工具、錄製時如何自動遮蔽憑證、fixture 檔案 +> 格式設計、JS 腳本插件如何透過宿主 HTTP 層重播 fixture;以及如何讓 +> `flutter test` 不帶參數時保證連不到網路、smoke test 如何標記與執行、 +> 是否該排程跑、失敗時如何通知。 +> 查證方式:pub.dev/GitHub 官方頁面、Dart 官方文件(WebFetch/ +> WebSearch)、flutter_js 官方 repo。查不到的一律寫「查不到」,推論 +> 一律標「推測」。查證時間 2026-09-27。 + +--- + +## 第 2 點:HTTP 錄製與重播 + +### 現有 dio 生態系工具盤點 + +| 工具 | 對接方式 | 錄製到磁碟 | 維護狀態 | 來源 | +|---|---|---|---|---| +| `http_mock_adapter` | `HttpClientAdapter` 或 `DioInterceptor`(Mockito 為底) | 不支援,要手寫每個回應 | 最後活躍約 2023-11,`dio` 版本鎖 `^5.3.2` | | +| `dio_mock_interceptor` | Interceptor,回傳寫死的回應 | 不支援 | 未深入查證版本歷史 | | +| `vcr` | 自訂 `HttpClientAdapter`(`VcrAdapter`),設在 `dio.httpClientAdapter` | **支援**,第一次找不到錄製檔就照常送出請求並存檔,之後重播 | 原作者 repo 更新時間**查不到**(WebSearch 未取得最後 commit 日期) | 、 | +| `vcr2` | 同上,宣稱是 `vcr` 的 null-safety 維護 fork,「可搭配 http 套件使用」 | 支援 | 比 `vcr` 新,但確切最後更新時間**查不到** | | +| `dartvcr`(EasyVCR 的 Dart port) | `package:http` 的 `BaseClient`,**不是** dio 的 `HttpClientAdapter** | 支援,且原生附「錄製過期」「Mode.auto/record/replay/bypass」「內建 censor(如 `Censors().censorQueryElementsByKeys(['api_key'])`)」 | 有維護(EasyPost 官方 port),但因為底層是 `package:http` 而非 dio,要接進 FMP 的 dio 生態必須額外寫一層 `HttpClientAdapter` 橋接,或改用 `dio_compatibility_layer`(讓 `package:http` 的 `Client` 包成 dio adapter,方向與 FMP 需要的相反,仍需自己驗證是否雙向可行) | | + +### 建議做法:不直接採用任何現成套件,自寫一個薄的 `HttpClientAdapter` 包裝層 + +理由: + +1. `vcr`/`vcr2` 維護狀態的最後更新時間查不到,且它們的錄製格式、 + 匹配邏輯(怎麼判斷「這是同一個請求」,是否含 body/query + 自訂比對規則)沒有在查證中看到足夠細節,無法確認能否滿足 FMP + 需要的「錄製時自動遮蔽」與「fixture 帶結構化 metadata(來源、 + 擷取時間)」需求。 +2. `dartvcr` 雖然功能最完整(含內建 censor、過期機制),但底層 HTTP + client 型別與 FMP 的 dio 架構(ADR 0012 講的「每來源一個 dio + client」)不同源,橋接層本身變成一個新的、沒人驗證過的依賴。 +3. 官方與社群共識的作法(來源:WebSearch 摘要多篇 Dio 測試指南)是 + 「Dio 5 的慣例做法是自寫一個包住真正 adapter 的 + `HttpClientAdapter`:record 模式下正常放行請求、把回應存成 JSON; + replay 模式下直接從存好的檔案組出 + `ResponseBody.fromString(...)`」——這與 FMP 既有的 + `test/support/` 慣例(自己寫測試基礎設施)一致,且**adapter + 層級正好位在所有 interceptor 之下**:dio 的請求方向是 + `interceptors → adapter`,回應方向是 `adapter → interceptors`, + 所以 adapter 錄到的請求是「所有 request interceptor(含 ADR 0012 + 注入的 `Authorization`/cookie)都已套用之後」的最終原始請求, + 錄到的回應是「response interceptor(含 ADR 0013 的錯誤對應、 + ADR 0011 的 log)都還沒碰過」的原始回應——**這代表 adapter 層級 + 錄到的資料一定含有真實憑證,遮蔽必須在寫入磁碟之前、由錄製層 + 自己動手,不能依賴任何 interceptor 幫忙擋掉**(見下方遮蔽小節)。 + +### fixture 檔案格式設計(本研究自行設計,非抄自既有工具) + +沿用 ADR 0014 決定 6「每插件一目錄(腳本、manifest、錄下的測試 +fixture)」的既有方向,建議目錄與檔案結構: + +``` +<音源目錄>/test/fixtures/ + search_keyword_basic.json + resolve_stream_track_123.json + error_401_credential_invalid.json +``` + +單一 fixture 檔案內容(JSON,逐一鍵值為建議欄位,非任何工具強制格式): + +```jsonc +{ + "meta": { + "recordedAt": "2026-09-27T00:00:00Z", // 擷取時間,UTC + "sourceId": "bilibili", // 對應音源,供人工排錯 + "capturedBy": "manual", // manual|ci-live-smoke,追蹤是誰錄的 + "redacted": true // 是否已跑過遮蔽,錄製流程強制為 true 才可寫檔 + }, + "request": { + "method": "GET", + "url": "https://api.bilibili.com/x/web-interface/search?keyword=xxx", + "headers": { "cookie": "[REDACTED]" } + }, + "response": { + "statusCode": 200, + "headers": { "set-cookie": "[REDACTED]" }, + "body": "{...}" + } +} +``` + +- 一個檔案對應「一次請求/回應」,而非整個測試案例的多次請求打包在 + 一起——理由是重播時每個請求各自比對/各自替換更直覺,也讓 + diff/code review 時容易看出單一 fixture 的變化。 + 一個測試案例若牽涉多次請求(例如先搜尋、再取得播放地址),對應 + 多個 fixture 檔,由測試程式按呼叫順序或按 URL 比對來取用——比對 + 規則本身(要精確比對 query string 還是只比對 path)留給 + `implement.md` 依實際音源 API 決定,本研究不預先下死規定。 +- `meta.redacted` 這個欄位本身**不能**單獨當作信任依據(它只是 + 記錄「錄製流程有沒有跑過」),真正的把關要靠遮蔽函式在寫檔前 + 強制執行、加上一條測試斷言:對每個現有 fixture 檔案掃描已知的 + 憑證特徵(`Set-Cookie`、`Authorization`、簽名 URL 的 `sign=`/ + `expires=` 等 query 參數樣式)不得出現非 `[REDACTED]` 的值——這條 + 測試本身即是「fixture 內容不含真憑證」的閘門,建議放在 + `test/support/` 底下、跑在一般 `flutter test`(不需要網路)。 + +### 錄製時自動遮蔽——沒有任何查到的工具原生支援「跟 FMP 一致的遮蔽規則」 + +- `dartvcr` 原生有 censor 機制(`Censors().censorQueryElementsByKeys(...)`), + 但它是通用工具,遮蔽規則要自己設定要遮哪些 key/header,且如前述 + 它底層是 `package:http` 而非 dio,FMP 若要用它就要接受這層橋接 + 成本。 +- `vcr`/`vcr2` 的文件**查不到**有內建遮蔽機制的描述。 +- ADR 0011(雖然本研究未直接讀取該 ADR 全文,但 ADR 0012/0013/0014 + 的「如何確認」段落都提到「遮蔽」是同一份規格)代表 FMP 已經有、 + 或即將有一個「production 用的遮蔽函式」(用來清 log/診斷包)。 + **建議:錄製 fixture 時直接呼叫同一個 production 遮蔽函式**,而不是 + 另外維護一套「只給測試用」的遮蔽規則——這樣遮蔽規則只有一份來源, + 且錄製流程「不小心洩漏正式環境沒設定要遮的東西」的風險與正式 + log 洩漏風險綁在一起,一次測試(同一份契約測試/redaction test) + 就能同時涵蓋兩種使用情境。這是本研究對 ADR 0011「遮蔽」與 + ADR 0014「契約測試涵蓋 0011」兩項要求的具體串接建議,需要 + `implement.md` 階段落實成「遮蔽函式簽章要能同時處理『dio + RequestOptions/Response 物件』與『log 字串』兩種輸入」。 + +### JS 腳本插件如何透過宿主 HTTP 層重播 fixture + +依 ADR 0014 決定 5,腳本能用的宿主 API 只有 `http.request`(經 +ADR 0012/0013 網路層),這正是唯一的 HTTP 出入口,也是天然的 +重播掛勾點。技術путь: + +- `flutter_js`(`abner/flutter_js`)的橋接機制是 + `evaluate()`/`onMessage(channel, handler)`/`sendMessage(channel, + payload)`:Dart 端註冊一個 channel(例如 `http.request`),JS + 腳本呼叫宿主提供的 `http.request(...)` 包裝函式時,實際上是把 + 參數用 `sendMessage` 送回 Dart,Dart 端在 `onMessage` 回呼裡真正 + 執行 HTTP 呼叫、再把結果回傳給 JS。 + (來源:`flutter_js` 官方 repo README, + ——README 有 `onMessage`/ + `sendMessage` 的範例,具體參數型別建議在 `implement.md` 落地前 + 直接讀原始碼核對,此處只確認機制存在與大致用法。) +- **這代表「host API 的 `http.request` 實作」是唯一需要替換的地方**: + 正式執行時,這個 Dart handler 呼叫真正的 dio client(含 ADR 0012 + 的 `AuthRequirement` 注入、ADR 0013 的錯誤對應);契約測試執行時, + 同一個 handler 改成呼叫上一節設計的「重播 adapter」,回傳 + fixture 內容——**JS 腳本本身完全不知道自己在測試環境,呼叫方式 + 一模一樣**,這正是題目要求的「用同一個宿主 API,測試替身換掉 + production 後端」。 +- 具體做法:`SourceHttpClient`(或等效的宿主 HTTP 抽象)改成建構子 + 注入一個 `HttpClientAdapter`,production 組裝走真正的 dio + `IOHttpClientAdapter`,契約測試組裝走「重播 adapter」(讀 + `test/fixtures/*.json`,依 URL/method 比對回傳對應的 fixture + 回應,找不到就丟出明確錯誤而非靜默通過,避免測試因為 fixture + 遺漏而誤判成功)。 + +--- + +## 第 3 點:零網路測試與 smoke test + +### 預設 `flutter test` 保證連不到網路——雙重機制 + +**機制一:`dart_test.yaml` 的 tag 預設跳過** + +Dart test 官方支援在設定檔用 `tags:` 區塊,對某個 tag 設定 +`skip: true`(或帶理由的字串),這個設定**對所有呼叫方式生效**, +包含裸 `flutter test`(不帶任何參數)——要跑被跳過的測試,必須用 +`-P`/`--tags`/設定檔的 `presets` 明確覆蓋。這是 Dart test 官方 +機制的一部分(`package:test` 的 `dart_test.yaml` 設定檔),FMP +可以: + +```yaml +# dart_test.yaml +tags: + live: + skip: "會打真實 API,只能手動或排程執行,見 docs/development.md" +``` + +被標 `@Tags(['live'])` 的測試檔,一般 `flutter test`(含 CI 的 +`flutter test --exclude-tags live`,這條指令其實在有了 `dart_test.yaml` +的 `skip` 設定後已經是多餘但無害的雙保險)都會顯示「跳過」而非 +「執行」。要真正執行,需要 `flutter test --tags live` 之類的明確 +呼叫並額外提供 preset 或環境變數解除 skip(Dart test 的 `skip` +選項可以接受一個字串,永遠跳過除非在設定檔用 +`presets: { live: { tags: { live: { skip: false } } } }` 這類結構 +明確解除——**具體語法組合建議落地時對照當時的 `package:test` 版本 +文件重新核對,本研究只確認「tag + 設定檔 skip + presets 解除」這個 +機制存在**,未逐字驗證最新語法)。 + +**機制二:`HttpOverrides.global` 攔截所有真實 socket 建立** + +- 在 `test/flutter_test_config.dart` 的 `testExecutable` 內,於所有 + 測試執行前安裝一個自訂 `HttpOverrides`: + + ```dart + Future testExecutable(FutureOr Function() testMain) async { + HttpOverrides.global = _ThrowingHttpOverrides(); + await testMain(); + } + + class _ThrowingHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + throw StateError( + '測試中偵測到真實 HttpClient 建立——一般測試不得連網路,' + '若這是刻意的 live/smoke 測試,請在該測試內用 ' + 'HttpOverrides.runZoned 明確允許。', + ); + } + } + ``` + +- 涵蓋範圍:`dart:io` 的 `HttpClient` 本身、`package:http` 的 + `IOClient`(底層用 `HttpClient`)、dio 預設的 + `IOHttpClientAdapter`(同樣底層用 `HttpClient`)都會在建立時 + 立刻丟例外,測試會直接失敗並顯示清楚訊息,而不是安靜地嘗試連線 + 然後在 CI 環境因為連不到而逾時或間歇性失敗。 +- **涵蓋不到的例外**:直接用 `dart:io` 的 `Socket.connect`(略過 + `HttpClient` 抽象)不受此攔截;某些平台專屬的 HTTP 引擎 + (`cupertino_http` 用 `NSURLSession`、`cronet_http` 用 Android + Cronet)繞過 `dart:io HttpClient`,`HttpOverrides` 對它們無效—— + FMP 若日後改用這些引擎作為 dio adapter,需要額外設計攔截機制 + (例如強制在測試環境注入假 adapter,而不倚賴 `HttpOverrides`)。 + 就 FMP 目前 dio-based 架構而言,這兩個機制合起來已能攔住幾乎所有 + 意外連網。 +- 需要刻意允許連網的 smoke test,可用 + `HttpOverrides.runZoned(testMain, createHttpClient: (context) => + HttpClient())` 在該測試的 zone 內暫時換回真正的 `HttpClient`, + 離開該 zone 後恢復全域攔截——保證「允許連網」是**逐一測試顯式 + 聲明**,不是整份測試檔案的預設狀態。 + +兩個機制疊加的理由:tag skip 解決「這個測試會不會被執行」, +`HttpOverrides` 解決「萬一有人忘記標 tag、或某個測試意外新增了會 +連網的程式碼路徑」的最後防線——這是縱深防禦(defense in depth), +不是其中一個就夠。 + +### smoke test 的標記與執行方式 + +- 用 `@Tags(['live'])` 標記在測試檔頂端(`package:test` 官方標籤 + 機制),與上方 `dart_test.yaml` 的 `live: skip:` 設定對應。 +- 執行方式建議兩種入口都留: + 1. **手動**:`flutter test --tags live`(開發者本機在需要驗證 + 「音源 API 是否仍然可用」時手動跑,例如插件作者要驗證自己的 + `1morr/fmp-plugins` 插件契約測試對應到真實 API 還有沒有壞)。 + 2. **App 內 Debug 頁健康檢查**:依擁有者方向「真實 API 呼叫只能經 + 由 Debug 頁健康檢查或明確呼叫的 smoke test」,這代表 App 本身 + 要有一個開發者可以手動觸發的頁面,對每個已安裝音源跑一次 + 「呼叫一個最輕量的 API、回報成功/失敗」,這是產品功能而非 + 測試框架的一部分,屬於 `implement.md` 的 UI 設計範疇,本研究 + 只確認它與「smoke test」共用同一份「真實呼叫」程式碼路徑是 + 合理設計(同一組 API 呼叫,一份給人在 App 內手動點、一份給 + CI 排程跑)。 + +### 是否該在 CI 排程執行 smoke test——不建議排程,只建議手動觸發 + +**證據**(沿用之前研究、本次未重新查證,僅整理結論與既有 URL): + +- Bilibili:沒有官方聲明會封鎖雲端/CI 網段,但多個社群專案(` + yt-dlp` 相關 issue、至少一個公開 GitHub Actions 專案的 README) + 顯示從自動化環境呼叫會遇到 HTTP 412「風控」回應,該專案的因應 + 方式是準備 `BILI_COOKIE` secret 並加上 cooldown(延遲)機制, + 顯示這不是憑空的疑慮而是有人實際踩過的問題。 +- YouTube:自 2024 年中起有廣泛紀錄的雲端/機房 IP 封鎖 + (「Sign in to confirm you're not a bot」、後續演變成 403 加 + proof-of-origin token),屬於公開、多方確認的現象;但**沒有直接 + 證據**顯示這具體會擋到 GitHub Actions 的 runner IP 段(GitHub + Actions 的出口 IP 屬於 Azure 的資料中心範圍,一篇部落格文章推測 + Azure IP 可能有「不同的信譽分數」,這點明確標記為**推測**,非 + 確認事實)。 + +**建議**:**不要**把 smoke test 排進 GitHub Actions 排程 +(`schedule:` cron)。理由: + +1. 排程一旦命中風控/封鎖,會產生持續失敗的雜訊——擁有者的目標是 + 「保護真實憑證帳號與 IP 信譽」,而不是「盡快發現音源掛掉」(音源 + 掛掉更適合由使用者實際使用時回報、或插件作者手動驗證來發現, + ADR 0014 決定 7 本來就是「使用者手動檢查更新」的哲學,排程 smoke + test 與這個哲學不一致)。 +2 若排程從共享的 GitHub-hosted runner IP 段持續打真實 API,一旦 + 帳號或 IP 被標記為異常,受影響的不只是 FMP 這個 repo,同一個 + IP 段是所有使用 GitHub Actions 的專案共用的,可能连累其他不相干 + 的自動化。 +3. 若擁有者仍然想要某種形式的「定期健康檢查」,比較安全的作法是 + **自架的、非 CI 網段的排程**(例如擁有者自己機器上的 cron,或 + Debug 頁本身在使用者打開 App 時順手跑一次而非固定排程),而不是 + 公開 CI 服務的共享網段——這點屬於需要擁有者確認方向的決策,列入 + 最終報告的待決策清單。 + +若擁有者仍決定要排程(不論排在哪裡),失敗通知機制的技術做法 +(來源:WebSearch 對 2026 年現況的綜合整理,非單一權威來源,此段 +标记为社群慣例整理而非官方規範): + +- GitHub 對排程失敗**沒有內建的「開 issue」機制**,預設只會寄信給 + 最後修改該 workflow 檔案的人(等於失敗紀錄躺在一個人的信箱裡)。 +- 三種常見做法: + 1. **Marketplace action**:如 + `JasonEtco/create-an-issue`(用 issue 範本檔案 + `if: failure()` + 步驟)或「Failed Build Issue」action,設定簡單但引入第三方 + action 的信任面。 + 2. **獨立 watcher workflow**:用 `workflow_run` 事件監看其他 + workflow 的完成狀態,好處是不用改每個既有 workflow + (`urcomputeringpal/workflow-failure-issues` 是一個現成的 + reusable workflow 範例)。 + 3. **直接用 `gh` CLI,不引入任何第三方 action**(多篇 2026 年的 + 專案採用,視為目前較常見的做法):在失敗的 job 後面加一個 + `if: failure() && github.event_name == 'schedule'` 的步驟, + 先 `gh issue list` 搜尋是否已有同標題的開放 issue,有就 + `gh issue comment` 累加、沒有才 `gh issue create`——避免同一個 + 問題连續多天各開一個新 issue。 +- **建議**:若日後真的要接失敗通知,直接用 `gh` CLI 的自建 step + (做法 3),不引入額外 action 依賴,且與 FMP 既有「issue tracker + 用 `gh` 操作」的 agent 慣例(`docs/agents/issue-tracker.md`) + 一致。**但前提是擁有者先決定「要不要排程執行 smoke test」——本研究 + 的建議是不要,這段技術做法只在擁有者選擇排程時才用得上**。 + +--- + +## 待補查項(誠實列出) + +- `vcr`/`vcr2` 兩個套件的實際最後維護時間、與目前 dio 主版本 + (`cfug/dio`,目前 5.x 系列)的相容性**查不到**——WebSearch + 摘要沒有給出明確的 commit/發布日期,若日後决定改採用其中之一 + 而非本研究建議的「自寫薄 adapter」,落地前必須直接開 + pub.dev 版本頁與 GitHub commit 紀錄核對。 +- `flutter_js` 的 `onMessage`/`sendMessage` 確切函式簽章(參數 + 型別、是否為 async、channel 命名限制)本研究只確認機制存在於 + README,未逐行核對原始碼;`implement.md` 階段需要直接讀 + `abner/flutter_js` 的原始碼確認。 +- Dart `package:test` 目前版本(配合 FMP 使用的 Dart 3.13.x) + `dart_test.yaml` 的 `presets`/`skip` 解除語法,本研究引用的是 + 機制概念而非逐字核對當前語法版本,落地前建議寫一個最小可執行的 + 範例(一個永遠失敗的 `live` 測試+一次 `flutter test` 確認跳過、 + 一次 `flutter test --tags live` 確認執行)驗證行為,而不是照抄 + 本文件的 YAML 片段。 +- GitHub Actions 排程失敗通知的三種做法,本研究只做了現況整理 + (WebSearch 綜合摘要),未實際驗證任何一種在 FMP repo 上的行為; + 且此段本身建立在「擁有者決定要排程」這個尚未拍板的前提上,暫時 + 不建議投入實作時間查證更深。 diff --git a/.trellis/tasks/09-27-design-testing/research/lint-and-gates.md b/.trellis/tasks/09-27-design-testing/research/lint-and-gates.md new file mode 100644 index 000000000..a54e0d025 --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/research/lint-and-gates.md @@ -0,0 +1,425 @@ +# 研究:Dart 自訂 lint 現況與 FMP 靜態規則落地方案 + +> 對應 `.trellis/tasks/09-27-design-testing` 研究第 1 點:Dart 自訂 lint 現況 +> (`analysis_server_plugin`/`custom_lint`/第三方工具)、能否表達 ADR +> 0009–0013 要求的四類規則、`flutter analyze` 是否會顯示這些診斷、以及 +> lint 規則本身的雙向變異測試怎麼做。 +> 查證方式:官方文件與原始碼(WebFetch/context7)、GitHub issue/PR +> 一手來源、pub.dev/dcm.dev 官方頁面(WebSearch+WebFetch)。查不到的 +> 一律寫「查不到」,推論一律標「推測」。查證時間 2026-09-27。 + +--- + +## 第 1 點之一:官方 `analysis_server_plugin` 現況 + +Dart SDK 3.10 起,官方提供新一代 analyzer plugin 系統 +`analysis_server_plugin`,取代舊的 legacy plugin 協定: + +- 套件: +- 撰寫規則指南: +- 撰寫插件指南: +- 使用插件指南: +- 測試規則指南: +- Dart 官方總覽頁: + +結構:一個 analyzer plugin 是一般 Dart 套件,入口在 `lib/main.dart` +匯出頂層 `plugin` 變數;每條規則拆成 `AnalysisRule`(規則本體)+ +`SimpleAstVisitor`(AST 走訪),用 `registerNodeProcessors` 註冊、 +`rule.reportAtNode(node)` 回報診斷。啟用方式是在消費專案的 +`analysis_options.yaml` 頂層 `plugins:` 區塊列出套件,**規則預設不開, +要逐條在設定檔打開**(來源:`writing_rules.md`/`using_plugins.md`)。 + +### `custom_lint`(社群方案)現況:已封存、已被 SDK 正式棄用其依賴的舊協定 + +- **Repo 已封存**:GitHub 顯示 `invertase/dart_custom_lint` 由 owner 於 + 2026-03-24 封存,唯讀狀態(來源:GitHub repo 頁面 metadata,透過 + WebSearch 查得該日期;第三方一份 README 寫封存日是 2026-05,以 + GitHub 官方封存通知的 2026-03-24 為準)。 +- **停在舊版 analyzer**:`custom_lint` 最新版 0.8.1(發布於 + 2025-09-09),鎖定 `analyzer ^8.0.0`;目前 `analyzer` 已到 14.x, + 沒有任何已發布的 `custom_lint_builder` 相容新版 analyzer + (來源:pub.dev 版本頁 + + WebSearch 綜合,pub.dev 頁面本身未寫「deprecated」字樣,此為 + 用版本號與封存狀態推論出的現況,非套件自我聲明)。 +- **在新 SDK 上會壞**:`dartway_lints` 專案回報在 Flutter + 3.47.2/Dart 3.13 pin 下,`custom_lint` 於 IDE analyzer 內丟出 + `Unknown request: analysis.setAnalysisRoots` 而崩潰 + (來源:GitHub issue,經 WebSearch 摘要取得,未逐字覆核 issue 全文, + 故此點標記部分推論)。 +- **SDK 官方棄用時間軸**: + - Dart SDK issue #62164〈Deprecating the legacy analyzer plugin + system〉,2025-12 開立,官方目標是棄用 `custom_lint` 所依賴的舊 + plugin 協定: + - **Dart 3.13.2**(2026-08-25 發布)的 changelog 正式將舊 plugin + 系統標記為 deprecated(來源:WebSearch 摘要 Dart changelog + 條目,未逐字複製全文措辭)。 + - Dart SDK issue #64188〈Remove legacy analyzer plugin system〉 + (2026-09-02 開立):「舊系統已於 3.13.2 棄用,未來某個穩定版將 + 開始移除(先停用執行舊插件)」: + + +**結論**:`custom_lint` 不建議在 FMP 新專案 `app/` 採用——它依賴的協定 +已被 SDK 正式列入棄用/移除時程表,套件本身已封存且技術上已在目前 +Dart 版本上出現崩潰。FMP 應直接以官方 `analysis_server_plugin` 為 +基礎(riverpod_lint 已完成遷移,見下)。 + +### 生態系遷移現況佐證 + +- `riverpod_lint` 已改用 `analysis_server_plugin` 實作 + (來源:WebSearch 摘要 riverpod GitHub issue 討論串內容,pub.dev + 頁面 /changelog + 可交叉核對版本 + 時間,此處僅摘要「已遷移」的事實陳述,未逐條核對每個版本號)。 +- `import_lint` 的 pub.dev 頁面(查閱日 2026-09-27 顯示的頁面更新 + 日期為 2026-04-18)已要求 Dart 3.10+ 並使用新版 `plugins:` 設定: + ;changelog: + (**查不到**具體是 + 從哪個版本號開始遷移——changelog 頁面查得的最新可讀條目是舊格式, + 版本號需要直接開 pub.dev 頁面核對,此處不虛構版本號)。 +- 遷移實戰文章(第二手來源,僅供交叉參考、不作為權威): + 、 + + +--- + +## 第 1 點之二:關鍵風險——`flutter analyze` 是否會顯示 plugin 診斷 + +這是 FMP 能否採用 `analysis_server_plugin` 的**前提性風險**,因為 +`AGENTS.md` 現有 CI 閘門明文是 `flutter analyze`(見 +`AGENTS.md`「Verification」表格與「`flutter analyze` and the +`dart format lib test tool` CI gate」一句)。 + +**現況(2026-09-27 查證):這是一個仍未修復、已知存在的 bug。** + +- `flutter/flutter#193203`〈`flutter analyze` hides analyzer plugin + diagnostics and reports "No issues found!"〉,2026-09-23 提出,已被 + 標記為 `#187999` 的重複單: + +- 回報環境與 FMP 目前用的版本非常接近:**Flutter 3.47.5(stable, + commit 6a19cca)、Dart 3.13.4**。回報內容:`flutter analyze`(即使 + 在套件根目錄執行)與 `dart analyze <目錄>` 都印出「No issues + found!」、完全不含 plugin 診斷;只有對**單一檔案**路徑執行 + `dart analyze` 才會顯示 plugin 診斷。核心 lint(非 plugin)不受影響, + 一樣正常顯示——也就是說用 `flutter analyze` 跑 CI 會「安靜地放行」 + 所有 plugin 規則的違規,`flutter analyze` 顯示通過不代表真的通過。 +- 官方文件的說法(`analysis_server_plugin` 相關頁面)宣稱 plugin + 診斷「在 IDE 與命令列執行 `dart analyze` 或 `flutter analyze` 時都 + 可取得」——目前與這個已知 bug 的實測結果矛盾。 +- 根因與修復進度:Dart SDK PR #63805〈Defer analysis-complete + notification until plugins finish〉指出問題在於 analysis server 會 + 在 plugin 分析**尚未完成**時就送出 `$/progress kind:end` + (及對應的 `analyzerStatus` 通知),導致 LSP client(`flutter + analyze` 的底層機制)誤判分析已結束、在 plugin 診斷真正發布前就 + 收工。該 PR 的討論串顯示「Gerrit CL 已核准,等待 reviewer merge」, + 但**查不到明確證據顯示此修復已經合併進 stable**(來源:WebSearch + 摘要該 PR 討論串內容,未直接開 Gerrit 頁面核對合併狀態,標記 + 「查不到」而非猜測已修復或未修復)。 +- **社群目前的因應方式**:改跑 `dart analyze --fatal-infos`(在套件 + 根目錄執行,而非 `flutter analyze` 或對子目錄跑 `dart analyze`), + 或是在 CI 中額外放一個「必定觸發某條 plugin 規則」的哨兵測試檔, + 只靠「No issues found!」不足以證明 plugin 規則真的有跑(第二個 + 作法來自另一個遷移專案的 CI 修復方式,WebSearch 摘要,未看到原始 + PR diff)。 + +### 對 FMP 的具體建議 + +1. **CI 的 lint 步驟不能只依賴 `flutter analyze`**:至少要加一個 + `dart analyze --fatal-infos`(在 `app/` 目錄下執行)或直接用 + `dart analyze` 對整個套件根目錄執行,兩者都要留著,因為 + `flutter analyze` 仍然要拿來檢查 Flutter 專屬的分析行為 + (例如它認得 `.dart_tool/package_config.json` 裡 Flutter SDK 的 + 部分,`dart analyze` 有時反而看不到某些 Flutter 特定診斷——這是 + **推測**,未實測驗證兩者診斷集合的確切差異,落地前必須在 + `app/` 建好骨架後親自跑一次兩個指令比對輸出)。 +2. **無論選哪個指令,落地前必須先建一個「哨兵規則違規」測試固定檔** + (例如一個刻意 `print()` 的假檔案),跑一次 CI 確認它真的被攔下、 + 而不是「沒有輸出=規則沒生效」被誤判為通過。這與下方「雙向變異 + 測試」的精神一致,只是層級提高到「整條 CI pipeline 有沒有接上 + plugin 診斷」而非「單一規則邏輯對不對」。 +3. 這個 bug 屬於 Dart/Flutter 工具鏈本身的暫時性缺陷,不影響「該不該 + 採用 `analysis_server_plugin`」的長期判斷(生態系已經全面遷移、 + `custom_lint` 已停滯),但**會影響 FMP 現在(2026-09)能不能只信任 + `flutter analyze` 這一個指令**——這點必須寫進 CI 設計,不能假設它 + 會在可預見時間內修好。 + +--- + +## 第 1 點之三:ADR 要求的四類規則,各工具能不能表達 + +FMP 需要用靜態規則表達的類型(依 ADR 0008–0014 逐條列出): + +| 類型 | 具體規則 | 來源 ADR | +|---|---|---| +| (a) 目錄 A 不得 import 目錄 B | `app/` 不得 import 根目錄舊專案;`lib/core/`/`lib/data/` 不得 import `lib/services/`/`lib/providers/`;`legacy_import` 模組不得被其他模組 import | 0008、既有 `AGENTS.md` Layers、0010 | +| (b) 符號 X 只能在目錄 Y 內使用 | `isar.` 只能出現在 repositories 層;`talker` 只能在 log 門面內直接 import | 既有 `AGENTS.md` Isar access、0011 | +| (c) 禁止空 catch/靜默吞錯 | 不只 `catch (_) {}`,含「catch 到但沒有任何後續動作」 | 0013 | +| (d) 禁止 `print`/`debugPrint`/`developer.log`/直接 `talker` 呼叫 | 只能經單一 log 門面 | 0011 | +| (e,0014 新增) UI/service 不得出現音源 id 字串常數或特定音源型別 | 見下方專節說明,這條**沒有任何工具能直接做到** | 0014 | + +### (a) 目錄間 import 限制 + +**可以做到**,且有兩條路: + +- **DCM `avoid-banned-imports`**:官方文件 + ,設定為 + `entries` 陣列,每筆有 `paths`(regex,適用哪些檔案)、`deny` + (禁止 import 什麼)、`message`、選填 `severity`,另有 `exclude-paths` + 可排除例外檔案。DCM 官方還有一篇專門的架構治理指南 + 〈Enforcing Architecture Boundaries with DCM〉 + , + 裡面的範例就是「禁止 `lib/` 內非 `core/` 的地方 import + `flutter_bloc`」「禁止 web 目標檔案 import `dart:io`」這種形狀,與 + FMP「`app/` 不得 import 根目錄舊專案」「`legacy_import` 不得被其他 + 模組 import」幾乎是同一種規則的不同參數。**注意**:文件特別提醒 + Windows 裝置上 `paths` 的 regex 要注意路徑分隔符號,這對在 Windows + 上開發的 FMP 有直接影響,落地時要驗證。 +- **官方 `analysis_server_plugin` 自寫規則**:FMP 現有 + `test/support/layer_boundary_static_rule_test.dart` 本來就是手刻 + AST/字串掃描邏輯,改寫成一條 `AnalysisRule` 是同等工作量的搬遷, + 差別只在於錯誤是「lint 診斷」而非「測試失敗」,可以在 IDE 即時顯示 + (若前一節的 `flutter analyze` bug 修好的話)。 + +### (b) 符號限制在目錄內 + +**可以做到,而且是「順便」做到**:Dart 語言規則是「要呼叫某個 +extension 方法或存取某個型別的成員,必須先 import 定義它的 +library」,所以只要用 (a) 的機制把 `package:isar_community/isar.dart` +這類 import **在允許目錄以外全面禁止**,呼叫端根本沒有辦法在沒有 +import 的情況下寫出 `isar.xxx`——**禁止 import 等於連帶禁止了符號 +使用**,不需要額外一條「禁止某符號」的規則。DCM 的 +`avoid-banned-imports` 或自寫 import-lint 規則两者皆可達成,不需要 +額外用到 `banned-usage`。 + +`talker` 直接呼叫的限制同理:只要 `talker` 套件的 import 被限制在 +log 門面檔案內,門面以外的程式碼物理上無法直接呼叫 +`talker.xxx()`。 + +### (c) 空 catch/靜默吞錯 + +**官方 `empty_catches` 有明確、經官方文件證實的漏洞**: + +- 官方文件: +- 規則文字:「AVOID empty catch blocks」,**但官方文件自己給出的 + 合規寫法之一就是 `catch (_) { }`**——文件原文:"the exception + identifier can be named with underscores (_) to indicate that we + intend to skip it",也就是說**用底線命名的空 catch 是被這條規則 + 視為「有意為之」而不會被標記**。 +- 這與 FMP 的 ADR 0013 意圖直接衝突——ADR 0013 明講「禁止空 catch + 與靜默吞錯」,而不是「允許用底線變數名稱表示的有意跳過」。舊專案 + 的 507 個 catch 中約 70 個是空的(`docs/audit/errors.md` + 背景數字),這類程式碼很可能一部分就是 `catch (_) {}` 形式,官方 + `empty_catches` 對這部分完全沒有防護力。 + +**FMP 需要更嚴格的規則,官方內建 lint 不夠,需要自訂**:一條自訂 +`AnalysisRule`,邏輯是「catch 子句的 body 沒有任何會被觀測到的 +副作用陳述式」(body 為空、或只有註解、或只有 `_ = e;` 這類假動作), +**不管 catch 變數叫什麼名字**。DCM 沒有現成對應規則名稱可以直接設定 +達成這麼精確的語意(`banned-usage`/`avoid-banned-imports` +都不是為此設計),這條建議走**自寫 `analysis_server_plugin` 規則** +路線,理由見下方「建議」小節。 + +### (d) 禁止 `print`/`debugPrint`/`developer.log`/直接 `talker` 呼叫 + +- 官方 `avoid_print`() + 只覆蓋 `print()`,且**只在 `flutter_lints` 套件的規則集裡,不在 + 核心 `lints` 套件**(來源:官方文件 all-rules 頁面分類)。不覆蓋 + `debugPrint`、`developer.log`。 +- DCM `banned-usage`() + 是專門為「禁止呼叫特定函式/方法/建構子/屬性」設計的規則, + 設定為 `entries`,每筆有 `name`(或 `name-pattern` 正規表達式)、 + `description`、`paths`、`exclude-paths`、`severity`。**這正是 FMP + 需要的形狀**:四條 entries 分別禁止 `print`、`debugPrint`、 + `developer.log`(或其 `name-pattern`)、`Talker`/`Talker.new` + 之類的建構子呼叫,並用 `exclude-paths` 排除 log 門面自己的檔案。 + 官方文件特別提醒:這條規則會連外部套件/核心函式庫的呼叫一併 + 抓到,所以要給精確的 `name`(例如用 `'DateTime.now'` 而非 + `'now'`)避免誤傷。 + - **版本沿革**:DCM 1.21.0(2024-08 發布)把原本一體適用「用法+ + 命名」兩種情境的 `banned-usage`(前身叫 `ban-name`)拆成兩條: + `banned-usage` 專管「用法」(方法呼叫、屬性存取), + `avoid-banned-names`() + 專管「宣告命名」。FMP 這條規則屬於「用法」,對應 + `banned-usage`,不是 `avoid-banned-types`(那條是禁止**型別參照**, + 例如禁止在某處寫出 `SomeType` 這個型別名稱,用途不同,容易混淆 + 但語意不對)。 +- **DCL(Bancolombia fork,`dart_code_linter`)也有對應機制**:舊名 + `ban-name`,DCM 1.21.0 已把它從 DCM 拿掉、但 DCL 是更早的 fork, + 規則索引頁 仍列出 + `ban-name`(「Configure some names that you want to ban」), + 規則詳細頁**查不到**(搜尋時該頁未被索引到,需要直接開 + 核對 + 欄位名稱,落地前必須重新查證,此處不假設它與 DCM 舊版格式完全 + 相同)。 + +### (e) 音源 id 字串常數/特定音源型別限制(ADR 0014)——**沒有工具能直接做到** + +這條規則跟前面四條本質不同:前四條都是「**import 或呼叫某個具名 +符號**」,可以用「先擋 import,符號自然用不了」的方式一次性解決; +但「音源 id 字串常數」通常只是普通 `String` 值(例如 +`if (sourceId == 'bilibili')`),**Dart 語言不要求你 import 什麼 +才能寫一個字串字面值**,任何 import-based 或 usage-based 規則都 +沒有掛勾點可以攔。 + +- DCM 的 `avoid-banned-types`() + 能禁止**型別參照**(例如禁止在 `lib/ui/` 出現某個具名型別),但 + 管不到「這個變數剛好裝了字串 `'bilibili'`」這種值層級的東西。 + `banned-usage` 的 `name`/`name-pattern` 比對的是**符號名稱** + (方法、屬性、建構子),同樣不比對字串字面值的內容。 +- **唯一能讓現有工具生效的做法是先做架構設計,把「音源 id」從 + 裸 `String` 改成一個獨立型別**(例如 `SourceId` 值物件,或直接 + 用 `SourcePlugin` 實例本身當作能力查詢的 key,UI/service 永遠不 + 在自己的程式碼裡寫出具名音源的比較邏輯,而是依 ADR 0014 決定 3 + 「UI 依能力出現入口」——UI 只問「這個能力有沒有提供者」,不問 + 「音源是不是 bilibili」)。一旦音源 id 有了自己的型別 + (而不是裸 `String`),"禁止在 `lib/ui/`/`lib/services/` 之外 + 參照這個型別的具體建構" 或 "禁止 import 定義具名音源模組的檔案" + 就變回 (a)(b) 類規則,可以用 `avoid-banned-imports`/ + `avoid-banned-types` 解決。 +- **這是本研究對 ADR 0014 落實方式的具體建議**:把「不得出現音源 id + 字串常數」翻譯成「音源 id 必須是一個不能在 `lib/ui/`、 + `lib/services/` 之外具現化字面值的型別」,讓可驗證的部分回到 + 現有工具能力範圍內;真正「裸字串比對」的殘餘風險(例如有人硬是把 + `SourceId` 型別的 `.value` 屬性拿出來跟字面值比較)**只能靠自寫 + `analysis_server_plugin` 規則掃描字串字面值**去補,或者接受這是 + design review 要盯的邊界情況,不強求 100% 工具化。這點需要擁有者 + 在架構設計階段確認方向,見最終報告的待決策清單。 + +--- + +## 第 1 點之四:候選工具總表與建議 + +| 工具 | 授權/費用 | 維護狀態(2026-09) | 能表達 (a)(b) | 能表達 (c) | 能表達 (d) | 能表達 (e) | +|---|---|---|---|---|---|---| +| 官方 `analysis_server_plugin`(自寫規則) | 免費、Dart SDK 內建 | 官方在維護,是未來方向;`flutter analyze` 目前有已知顯示 bug(見上) | 可以(需自己寫) | 可以(需自己寫,且能寫出比 `empty_catches` 更嚴格的語意) | 可以(需自己寫) | 部分可以(字串字面值掃描需自己寫,見上) | +| `custom_lint`(`invertase/dart_custom_lint`) | 免費、MIT | **已封存(2026-03-24)、SDK 已棄用其依賴協定、在 Dart 3.13 上會崩潰** | 不建議採用 | 不建議採用 | 不建議採用 | 不建議採用 | +| DCM(`dcm.dev`,前身 Dart Code Metrics) | Free(50k LOC)/Pro $16/mo(150k LOC)/Teams $80/mo 5 席(不限 LOC)/Enterprise,全部本機分析。來源: | 積極維護,商業產品,規則集完整、文件詳盡 | `avoid-banned-imports`,開箱即用 | 無精確對應規則,仍需自寫或接受 `empty_catches` 等級的鬆散度 | `banned-usage`,開箱即用 | 不行(同上,值層級規則) | +| DCL(`bancolombia/dart-code-linter`,DCM 的免費 fork) | 免費 | 有維護(見其 CHANGELOG),但規則文件不如 DCM 完整、`ban-name` 詳細頁查證時未能直接核對 | `avoid-banned-imports`,開箱即用 | 同上 | `ban-name`(舊式),欄位格式待落地時核對 | 不行 | +| `import_lint` | 免費 | 已遷移至 `analysis_server_plugin`(2.x 起,確切版本號查不到),仍在維護 | 只做 import 限制,比 DCM 陽春但夠用 | 不適用(非它的範圍) | 不適用 | 不行 | +| `layerlens` | 免費 | 前次研究確認為依賴圖視覺化+循環偵測工具,**不是強制執行工具**,只能畫圖、不能讓 CI fail | 不行(不是 enforcement 工具) | 不適用 | 不適用 | 不適用 | + +### 建議:**官方 `analysis_server_plugin` 自建規則套件為主力,不引入 DCM/DCL** + +理由: + +1. FMP 需要的規則有一半((c) 的嚴格版空 catch、(e) 音源 id 字串) + **任何現成工具都做不到**,無論選 DCM 與否都必須自己寫至少兩條 + `AnalysisRule`。既然無法迴避「自己寫規則」這件事,团队就要具備 + `analysis_server_plugin` 的撰寫與測試能力;一旦具備了,(a)(b)(d) + 用同一套工具寫也不增加額外的學習或維運成本,不需要再疊加一個 + 商業產品。 +2. DCM 是持續計費的商業產品(即使 Free tier 目前的 50k LOC 額度對 + 剛起步的 `app/` 專案夠用,長期維護的專案終究會超過,屆時要嘛 + 付費要嘛遷移,屬於「先幫套件裝上以後要拆的相容層」的反面 + ——不符合使用者全域偏好「不為想像中的未來需求加抽象層」,這裡 + 反過來說:不要為了眼前方便,引入一個未來勢必要遷移走的付費依賴)。 +3. 官方路線的唯一已知缺點是 `flutter analyze` 目前無法可靠顯示 + plugin 診斷(上一節),但這個風險**與選哪個 lint 引擎無關**—— + DCM/DCL 都是各自獨立的 CLI(`dcm analyze`/DCL 自己的執行檔), + 本來就不透過 `flutter analyze` 呈現結果,所以這個風險不構成「改用 + DCM 就能迴避」的理由,只是提醒 FMP 的 CI 設計必須顯式呼叫 + `dart analyze`(若走官方路線)或該工具自己的 CLI(若走 DCM/DCL + 路線),不能只信任 `flutter analyze` 的退出碼。 +4. 若日後(`app/` 規模變大、需要更細緻的架構規則、團隊擴編)發現 + 自寫規則的維護成本超過預期,DCM 的 `avoid-banned-imports`/ + `banned-usage` 是現成、文件完整、成熟維護的替代/補充方案,**保留 + 為之後可加購的選項**,不是現在就要下的決定。 + +### 需要自寫的規則清單(供 `implement.md` 規劃參考) + +1. `no_empty_catch_body`:catch 子句 body 沒有任何有效副作用陳述式, + 不因變數命名為 `_` 或加註解而免責(除非該註解緊鄰在唯一一行、且 + FMP 決定要保留「有意跳過需寫理由」的例外——**這點需要擁有者確認 + 要不要保留「有註解就放行」的例外,還是完全禁止空 body**,列入 + 待決策清單)。 +2. `no_direct_log_symbols`:禁止在 log 門面檔案以外的地方 import/ + 呼叫 `print`、`debugPrint`、`dart:developer` 的 `log`、`talker` + 套件的具名符號。 +3. `no_cross_project_import`:`app/` 不得 import 根目錄舊專案路徑 + (ADR 0008 決定 3 已指定由「測試策略 ADR」落實)。 +4. `no_isar_outside_repositories`:`isar` 相關 import 只能出現在 + `lib/data/repositories/`(沿用既有 `AGENTS.md` 規則,從 regex + 測試改寫成 lint)。 +5. `no_source_id_literal_outside_sources`(依賴上方「先做型別化」的 + 架構前提):音源 id 具名型別的建構式/字面值只能出現在 + `lib/data/sources/`。 + +--- + +## 第 1 點之五:lint 規則本身的「雙向變異測試」怎麼做 + +官方提供專用的單元測試框架 `analyzer_testing` +(), +機制如下: + +- 測試類別繼承 `AnalysisRuleTest`(基於 `test_reflective_loader`, + 用 class 而非 `group`/`test` 閉包組織測試);`setUp()` 裡指定 + `rule = MyRule()` 後呼叫 `super.setUp()`。 +- `assertDiagnostics(source, [lint(offset, length)])`:餵一段刻意 + 違規的原始碼,斷言在指定位置真的報出診斷——**這就是使用者全域 + 偏好要求的「造一個違規證明它會紅」**。 +- `assertNoDiagnostics(source)`:餵一段合規(或刻意做了無關的格式/ + 命名變化)的原始碼,斷言完全不報診斷——**這就是「改一次無關的 + 格式或命名證明它不會紅」**。 +- 範例(來源同上): + + ```dart + @reflectiveTest + class MyRuleTest extends AnalysisRuleTest { + @override + void setUp() { + rule = MyRule(); + super.setUp(); + } + + void test_has_await() async { + await assertDiagnostics(r''' + void f(Future p) async { + await p; + } + ''', [lint(33, 5)]); + } + + void test_no_await() async { + await assertNoDiagnostics(r''' + void f(Future p) async {} + '''); + } + } + ``` + +**落地建議**:FMP 每條自寫規則至少配一對測試方法—— +`test_violation_is_flagged`(違規版本,`assertDiagnostics`)與 +`test_unrelated_change_is_not_flagged`(同一段程式碼做無關的變數 +改名/換行/加註解,`assertNoDiagnostics`)——直接對應使用者全域 +偏好「新加的靜態規則要在測試檔內做雙向變異驗證」的字面要求,且這個 +框架是**官方一手提供**,不需要另外自己搭測試骨架。若 FMP 之後選擇 +DCM/DCL 補強某些規則,兩者都是外部 CLI 工具,**查不到**它們有提供 +對等的「規則單元測試」框架(DCM 文件裡看到的都是「規則設定」文件, +未見到「測試我自己寫的規則設定是否如預期觸發」的官方測試 API)—— +這點也是傾向官方路線的一個加分點:自寫規則有官方測試框架可用, +買來的規則设定沒有。 + +--- + +## 待補查項(誠實列出) + +- `flutter analyze` 是否顯示 plugin 診斷的 bug(`flutter/flutter#193203` + / `#187999`)**修復進度**:查詢當下(2026-09-27)看到的 PR + `dart-lang/sdk#63805` 討論串停在「已核准待 merge」與「有建置/測試 + 失敗待處理」的狀態,**沒有查到明確的「已合併進某個 stable 版本」 + 的證據**。落地 `app/` 的 CI 前,必須用當時的實際 Flutter/Dart + 版本重新驗證一次(建一個哨兵違規檔,比較 `flutter analyze` 與 + `dart analyze` 的輸出是否一致),不能沿用本文件查證當下的結論。 +- DCL(Bancolombia fork)`ban-name` 規則的精確設定欄位(`entries` + 的欄位名稱是否與 DCM 舊版一致)**查不到**,本文件只查到規則存在 + 於索引頁、其詳細頁未被搜尋索引到。若日後決定採用 DCL 作為 + DCM 的免費替代,需要直接開 + + 核對。 +- `import_lint` 遷移到 `analysis_server_plugin` 的確切版本號 + **查不到**(changelog 頁面查證時只讀到舊格式的條目,需要直接翻 + pub.dev 的 Versions 分頁逐版核對)。 +- (e) 音源 id 字串常數規則若最終還是需要「掃描字串字面值」的自寫 + 規則(架構型別化未能 100% 消除裸字串比較的情況),這條規則的 + 誤判率(例如日誌訊息、i18n key 裡剛好出現音源名稱字串)需要在 + 實作階段用真實程式碼樣本測過,本研究未做這個層級的驗證。 diff --git a/.trellis/tasks/09-27-design-testing/task.json b/.trellis/tasks/09-27-design-testing/task.json new file mode 100644 index 000000000..5e2b41297 --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-testing", + "name": "design-testing", + "title": "Design: tests, gates and dev environment", + "description": "Phase-2 item 8: which old tests and static rules to keep, lint-based gates, zero-network default tests with recorded fixtures, contract tests for script plugins, live smoke tests, dev instance isolation, CI matrix", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From a73d6f50c0ff94b8da0ae764ceffb7a69207b51f Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:41:04 +0800 Subject: [PATCH 035/133] chore(task): add design and plan for tests, gates and dev environment --- .trellis/tasks/09-27-design-testing/design.md | 193 ++++++++++++++++++ .../tasks/09-27-design-testing/implement.md | 11 + .trellis/tasks/09-27-design-testing/prd.md | 77 +++---- 3 files changed, 235 insertions(+), 46 deletions(-) create mode 100644 .trellis/tasks/09-27-design-testing/design.md create mode 100644 .trellis/tasks/09-27-design-testing/implement.md diff --git a/.trellis/tasks/09-27-design-testing/design.md b/.trellis/tasks/09-27-design-testing/design.md new file mode 100644 index 000000000..0e971b8b2 --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/design.md @@ -0,0 +1,193 @@ +# 設計:測試、閘門與開發環境 + +範圍是 `app/`。根目錄舊專案的測試與 static-rule 原樣留著守舊程式碼,切換 PR 時隨舊專案一起刪(ADR 0008); +舊專案唯一的改動是 CI 切分(§7)。 + +## 1. 測試分層與寫法 + +| 層 | 守什麼 | 怎麼跑 | +|---|---|---| +| 單元 | 純邏輯:匹配評分、遮蔽、重試與退避、設定預設值、`TrackKey` | `flutter test` | +| widget | 頁面與元件的行為,以 provider override 注入假資料 | `flutter test` | +| 插件契約 | 每個插件的檢查案例,重播 fixture(§3) | 契約執行器(§3.4) | +| 整合 | 只挑 tracer bullet 級流程:搜尋→播放、從檔案安裝插件、舊資料匯入 | `integration_test`,桌面 runner | +| golden | 只給設計系統的共用元件(清單在第 5 項定),`alchemist` 的 CI golden(Ahem 字型) | `flutter test` | + +- 原則:測試守契約與使用者看得到的行為,不守實作細節;行為變更同一個 PR 補測試;用能證明該行為的最低層。 +- 不設覆蓋率門檻(Flutter 官方也不給比例,`research/dev-env-and-ci.md` §6)。 +- 正式程式碼不留測試掛鉤:假實作一律經建構子或 provider 注入。舊專案 75 個 `debug*` 成員中下載服務就有 44 處,是這條的來源(lint L6)。 +- 從舊專案複製的葉節點連同它的測試一起複製(ADR 0008),包含 `pumpUntil`/`drainEventQueue` 等待助手。 + +## 2. lint 閘門 + +自寫規則放在 `app/packages/fmp_lints/`(官方 `analysis_server_plugin`),`app/analysis_options.yaml` 以 `plugins:` 啟用; +另開官方 `lints`/`flutter_lints` 與 `riverpod_lint`(落地時查證它已遷移到新插件系統)。 + +| 規則 | 內容 | 來源 | +|---|---|---| +| L1 `fmp_layer_imports` | 依賴方向表:`app/` 不 import 根目錄舊專案;`legacy_import` 不被其他模組 import,`isar_community` 只准在 `legacy_import` 內;`drift` 只准在資料層;平台套件只准在平台層;層與 feature 的方向在骨架建立時填表 | ADR 0008、0009、0010;舊 `layer_boundary`、`isar_boundary` | +| L2 `fmp_no_empty_catch` | catch 本體沒有任何陳述式(只有註解也算空)即違規;變數取名 `_` 不豁免(官方 `empty_catches` 會放行) | ADR 0013 | +| L3 `fmp_log_facade` | `print`、`debugPrint`、`dart:developer` 的 `log`、`talker` 套件只准在 log 門面內 | ADR 0011 | +| L4 `fmp_source_id_literal` | 官方插件 id 字串(清單寫在 lint 設定)只准出現在 `legacy_import`(舊 `SourceType` 對應插件 id)與測試 | ADR 0014;舊 `source_branch_points` | +| L5 `fmp_url_literal` | `http://`、`https://` 字面值只准在一個端點檔(App 自己的主機:更新檢查、官方插件 index) | 舊 `outbound_hosts`;插件的網域由 manifest+宿主測試守 | +| L6 `fmp_no_for_testing` | `lib/` 內不得宣告名稱以 `ForTesting` 結尾的成員 | §1 | +| L7 `fmp_http_client_owner` | `Dio(` 只准在網路模組內建構 | ADR 0012 | +| L8 `fmp_test_waits` | 測試內直接呼叫 `pumpEventQueue` 只准在等待助手內 | 舊 `wait_convention` | +| L9 `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | 全域偏好「停用規則要註解原因」 | +| L10 `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只准在平台層 | ADR 0009 | + +- 每條規則以 `analyzer_testing` 寫雙向變異測試:`assertDiagnostics` 造違規證明會紅,`assertNoDiagnostics` 改無關的命名或格式證明不紅。 +- **接線哨兵**:`flutter analyze` 目前不顯示插件診斷還回報 No issues(flutter/flutter#193203)。CI 跑 `dart analyze --fatal-infos`, + 另由 `app/tool/check_lint_wiring.dart` 暫時放一個違規檔進 `lib/`、斷言 `dart analyze` 失敗且輸出含規則名,再移除。 + 它證明的是「規則有接上 `app/`」,規則邏輯本身由上一條的規則測試證明。 +- `AGENTS.md` 列的每條靜態規則都要寫出對應的規則名;沒有規則守的就不寫進去。 + +## 3. 檢查案例、fixture 與契約測試 + +### 3.1 檢查案例(一份四用) + +```mermaid +flowchart LR + C["檢查案例
    每插件每能力最多一條"] + C --> R["契約測試
    重播 fixture,進 CI"] + C --> S["冒煙測試
    真實連線,手動"] + C --> H["Debug 頁健康檢查
    真實連線,App 內"] + C --> W["錄製
    真實連線,遮蔽後存成 fixture"] + W -->|寫入| F[("fixtures/")] + F --> R +``` + +插件目錄(`1morr/fmp-plugins` 每插件一目錄,ADR 0014): + +``` +/ + manifest.json + index.js + checks.json # 檢查案例:能力、輸入、期望(非空、欄位存在、錯誤類別) + fixtures//001.json, 002.json … # 一次請求/回應一個檔,依呼叫順序 +``` + +錯誤案例(401、412、B 站 -352 等)可以手改 fixture,`meta.capturedBy` 記為 `manual-edit`。 + +### 3.2 fixture 格式 + +每檔 `meta`(`recordedAt`、`pluginId`、`pluginVersion`、`capturedBy`)+`request`(method、url、headers、body)+`response`(status、headers、body)。 +重播比對:method+URL(query 排序後比)+順序;**被遮蔽的欄位不參與比對**(簽名、時間戳這類每次都變的參數本來就在遮蔽名單裡)。 +比對不到就讓測試失敗並印出請求,不回傳空值。fixture 不自動過期,上游改版由冒煙測試或健康檢查發現。 + +### 3.3 錄製與遮蔽 + +- 錄製與重播都在宿主網路層最底部的 dio `HttpClientAdapter`:重播 adapter 取代真實 adapter,腳本與攔截器照常運作。 +- 這一層看到的請求已含攔截器注入的憑證,所以寫檔前一律經 ADR 0011 的正式遮蔽函式(不另寫一份測試用規則),插件 manifest 的遮蔽追加同樣生效。 +- 閘門:一支測試掃描所有 fixture,已知憑證欄位(cookie、authorization、set-cookie、簽名 query、CDN 簽名 URL)不得有未遮蔽值。 + 插件庫 CI 與 `app/` 的測試 fixture 都跑。 + +### 3.4 契約執行器 + +- 一個通用套件,對每個檢查案例:載入插件 → 以重播 adapter 執行 → 斷言。斷言內容: + - manifest 宣告的能力與實際匯出的函式一致;輸出通過 DTO 驗證;符合案例期望。 + - 錯誤案例對到預期的 `AppError` 類別(ADR 0013)。 + - 媒體請求不帶憑證、`AuthRequirement` 生效(ADR 0012)。 + - 請求只連 manifest 網域;log 輸出經過遮蔽(ADR 0011)。 +- 執行環境:`flutter_js` 的原生 QuickJS 在 `flutter test`(純 Dart VM)不會自動載入,要先建好動態庫再指定路徑。 + 第一個里程碑實測;不可行就改在桌面 `integration_test`(Linux runner+xvfb)執行,它跑的是真的 App 二進位。 +- 插件庫 CI 以固定的 FMP commit/tag(對應 `apiVersion`)執行它。`app/` 的 CI 則對 `app/test/fixtures/plugins/` 內的小型測試插件執行, + 涵蓋每種能力與錯誤,不依賴官方插件庫。 + +### 3.5 App 內插件開發工具(已決定 A) + +開啟開發者模式後可用: +- 從資料夾載入插件、重新載入; +- 跑檢查案例(真實連線)並看該插件的 log; +- 錄製模式:以 App 內已登入的帳號執行案例,遮蔽後寫進該插件資料夾的 `fixtures/`; +- 每插件網路模式:真實/錄製/重播。重播讓開發時不必一直打真實 API。 + +「從資料夾載入」先只在桌面平台提供,由平台層宣告能力(ADR 0009);Android 仍可從檔案或網址安裝。 +健康檢查(真實連線跑已安裝插件的案例)所有平台都有。版面在第 4 項設計。 + +### 3.6 測試插件 + +`app/test/fixtures/plugins/` 放一個測試插件:資料是合成的,播放指向隨測試附帶的本機音檔。 +它同時用在 `app/` 的契約與整合測試,以及開發版的離線開發(不必安裝官方插件就能搜尋、播放)。 + +## 4. 零聯網 + +- `app/dart_test.yaml`:`tags: live: skip: "<理由>"`,另設 `presets: live` 解除;裸 `flutter test` 一律跳過(已查 dart-lang/test 設定文件)。 +- `app/test/flutter_test_config.dart`:`HttpOverrides.global` 讓建立真實 `HttpClient` 直接丟 `StateError` 並說明原因; + 真的要聯網的測試在自己的 zone 內用 `HttpOverrides.runZoned` 明確放行。 +- JS 腳本沒有 socket,只能經宿主 `http.request`(ADR 0014),所以也在這個範圍內。 +- 冒煙測試=檢查案例的真實連線模式:插件庫以 `--live` 手動執行,或在 App 的健康檢查執行。**不進任何 CI、不排程**: + B 站對機房 IP 回 412 風控、YouTube 自 2024 起擋機房 IP,排程只會固定觸發風控並暴露憑證。 + +## 5. 開發版 + +- 兩個 flavor:`dev`、`prod`;`pubspec.yaml` 設 `flutter: default-flavor: dev`(context7 查證),不帶參數的 `flutter run` 一定是開發版。 + `release.yml` 明確帶 `--flavor prod`。 +- 依 flavor 切換: + + | 項 | prod(ADR 0008 固定值) | dev | + |---|---|---| + | Android `applicationId` | `com.personal.fmp` | 加 `applicationIdSuffix ".dev"` | + | Windows AppUserModelID | `com.personal.fmp` | `com.personal.fmp.dev` | + | App 名稱、視窗標題、圖示 | FMP | FMP Dev,圖示加標記 | + | 資料目錄、單一實例鎖名稱、secure storage 命名空間 | 正式值 | 加 `-dev` 後綴 | + + Windows 的 AppUserModelID、鎖名稱與資料目錄不在官方 flavor 的範圍內,要自己依 `appFlavor`/`FLUTTER_APP_FLAVOR` 接上(推測可行,第一個里程碑實測)。 +- 開發版資料預設空白(已決定 A)。要真實資料時用一般功能帶進去: + - 舊版資料:在開發版執行舊資料匯入並選一個資料夾副本。開發版拒絕直接讀舊版的正式資料位置(Windows `Documents\FMP`),避免開啟時寫到真實資料。 + - 新版資料:用正式版的匯出備份(不含帳號與 Cookie)。 +- Android 開發版身分不同,讀不到舊版私有資料:Android 上的舊資料遷移驗證在模擬器上以 prod flavor 做,不在真機上做。 +- 閘門:測試斷言 prod 的身分值與 ADR 0008 一致、dev 的每一項都不同;開發版拒絕正式資料路徑也有測試。 + +## 6. 舊 static-rule 的去向 + +「不帶過去」= `app/` 不需要(舊專案的那支照舊守舊程式碼)。 + +| 舊規則 | 去向 | 理由 | +|---|---|---| +| `core_source`(授權註冊順序) | 不帶過去 | 綁舊 `main.dart` 的呼叫順序 | +| `isar_boundary` | L1 | Isar 只剩 `legacy_import` 在用(ADR 0010) | +| `source_ownership` | 不帶過去 | 沒有內建音源;改由 L4 與宿主邊界守 | +| `riverpod3` | 不帶過去 | 綁舊 provider 錨點;改用 `riverpod_lint`;retry 關閉另有測試(ADR 0013) | +| `audio_backend_shared_rules`、`audio_seam`、`playback_event_routing` | 第 13 項決定 | 依播放核心的新結構 | +| `lyrics_window_strings` | 第 15 項決定 | 若保留子視窗,改以型別化訊息,型別本身就能擋 | +| `settings_backup_coverage` | 改成測試 | 以 drift 表的欄位比對備份匯出與匯入(ADR 0011 的分域設定表) | +| `android_manifest`(`allowBackup="false"`) | 保留為設定測試 | 系統備份會帶走資料庫卻帶不走 Keystore 裡的憑證 | +| `audio_provider_size` | 刪 | 行數預算不守行為 | +| `call_site_ownership` | 拆掉 | UI 直接叫音源改由 L1 守;自訂標題列與直播改由平台層能力決定(ADR 0009) | +| `layer_boundary` | L1 | — | +| `live_source_tag` | 刪 | 由 §4 的兩道防線取代 | +| `outbound_hosts` | L5+manifest 網域 | — | +| `periodic_timer` | 第 16 項決定 | 背景任務若集中排程,再加 lint 禁止入口外的 `Timer.periodic` | +| `source_branch_points` | L4 | 計次預算改成直接禁止 | +| `source_http_policy` | L7+ADR 0012 網路層測試 | — | +| `static_rule_placement` | 刪 | 讀原始碼的測試由 lint 取代 | +| `wait_convention` | L8 | — | +| `error_presentation` | 用型別擋 | ADR 0013 的呈現 API 只收 i18n key;其餘細節由第 3 項定 | +| `slider_overlay` | 第 5 項決定 | 先在目前的 Flutter 版本重現 Windows 無障礙樹凍結,仍會重現才加 lint | +| `ui_consistency`(圖片) | 第 5 項決定 | 依新的設計系統元件 | +| `watch_scope` | 不帶過去 | 綁舊的寬 provider | +| `test/workflows/*`(含 `dependabot_group`) | 第 19 項決定 | 依新的發版與依賴更新流程 | + +## 7. CI + +- 一個 `changes` job 用 `dorny/paths-filter`(以 commit SHA 釘版本,與現有慣例一致): + - `app`:`app/**`、`.github/**`; + - `legacy`:`app/**` 以外的全部(含 `.github/**` 與文件)。 + - 依專案切分,不依「是不是程式碼」切分:舊檔頭「文件承載規則,純文件改動不能跳過」的理由照樣成立。 +- `app` 的 job: + - format、`dart analyze --fatal-infos`、接線哨兵、`flutter analyze`; + - `fmp_lints` 規則測試、`flutter test`(不加參數,零聯網有保證)、契約執行器; + - 建置矩陣:Android、Windows、Linux、macOS、iOS(`--no-codesign`),來自 ADR 0009; + - 整合測試:Linux(xvfb)與 Windows。 +- `legacy` 的 job 維持現狀,只在根目錄有變動時跑。所以 `app/` 的 PR 不會被舊專案的不穩測試擋住(回答 ADR 0008 留下的問題)。 +- 一個 `always()` 彙總 job 當唯一的必要檢查,跳過的 job 不算失敗。 +- 公開 repo 的 GitHub-hosted runner 免費不限分鐘,矩陣不為省時間縮減。 +- 冒煙測試不進 CI(§4)。 + +## 8. 第一個里程碑要實測的項目 + +- 在 `app/` 上用 `dart analyze` 看得到插件診斷,接線哨兵會紅;比對 `flutter analyze` 的輸出差異。 +- 契約執行器能否在 `flutter test` 內載入 QuickJS;不行就改用 `integration_test`。 +- dev 與 prod 同時開啟:AppUserModelID、單一實例鎖、資料目錄各自獨立。 +- 故意寫一個聯網測試:裸 `flutter test` 會跳過它;放行 tag 執行時,`HttpOverrides` 會擋下沒有明確放行的連線。 diff --git a/.trellis/tasks/09-27-design-testing/implement.md b/.trellis/tasks/09-27-design-testing/implement.md new file mode 100644 index 000000000..8ba410940 --- /dev/null +++ b/.trellis/tasks/09-27-design-testing/implement.md @@ -0,0 +1,11 @@ +# 執行計畫:第 8 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0015-testing-gates-and-dev-environment.md`(MADR-lite,依 `docs/adr/template.md`),內容取自 `design.md` §1–§7; + 舊 static-rule 去向表放 ADR 附錄或連回本任務歸檔的 `design.md`(ADR 只留原則與「第幾項決定」的指向)。 +2. ADR 0008 的「如何確認」與「之後要注意」補一句:`app/` 不 import 舊專案由 L1 守、CI 切分已在 ADR 0015 決定。 + ADR 0009、0010、0011、0014 的「如何確認」寫「測試策略 ADR 落實/選定工具後加上」的地方,改成指向 0015 的規則名。 +3. `phase2-plan.md`:§3 第 8 項標 ✅(ADR 0015);§7 加入 `design.md` §8 的四項實測;§10 交接段更新進度與下一項(17 快取與離線)。 +4. 驗證:Mermaid 以 mermaid-cli 渲染成功(設計圖已驗);`git grep -n "測試策略 ADR"` 確認沒有漏改的指向。 +5. `task.py finish`、`task.py archive design-testing --no-commit --skip-branch-validation`;Conventional Commits 分開提交 ADR 與任務歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-testing/prd.md b/.trellis/tasks/09-27-design-testing/prd.md index 6f72eecaf..bed9e20cc 100644 --- a/.trellis/tasks/09-27-design-testing/prd.md +++ b/.trellis/tasks/09-27-design-testing/prd.md @@ -4,7 +4,7 @@ 為 `app/` 定下:保留哪些舊測試與 static-rule、新架構的閘門(lint、測試、CI)、零聯網的預設測試與 fixture、 腳本插件的共用契約測試、聯網冒煙測試、開發時少打真實 API 的方法,以及開發版與正式版分離(U9、單一實例)。 -產出 ADR 0015。 +產出 ADR 0015。技術設計見 `design.md`,執行步驟見 `implement.md`,研究見 `research/`。 依據:parent `prd.md` 階段二第 8 項;`phase2-plan.md` §4(測試、static-rule、單一實例三段); `docs/audit/questions.md` §10(四類測試你都勾「不確定」並附備註)與 U9;ADR 0008–0014 的「如何確認」段。 @@ -12,58 +12,43 @@ ## 現況(審計,`docs/audit/engineering.md`) - 約 1,849 個離線測試本機全過(2 分 48 秒);25 支 static-rule(144 個 test)以正則比對原始碼,部分是計次預算 - (`audio_provider.dart` ≤ 2,184 行;音源分支預算 9 處但實際 50 處沒守住)。 + (`audio_provider.dart` ≤ 2,184 行;音源分支預算 9 處但實際 50 處沒守住)(§5)。 - `dart_test.yaml` 只宣告 `live` tag、沒有預設跳過:**裸 `flutter test` 會打真實 API**(4 個 live 測試);CI 靠 `--exclude-tags live`。 - 部分行為測試依賴 `debug*ForTesting` 掛鉤(下載服務 44 處,全專案 `debug*` 成員 75 處)。 -- CI(`.github/workflows/ci.yml`):單一專案、不做路徑過濾(理由寫在檔頭),釘 Flutter 3.47.1;validate 7 分、Android 6 分、Windows 10 分。 -- 開發版與正式版共用同一個單一實例鎖與同一份資料(Windows `Documents\FMP`),開發時會動到真實資料。 - -## 你已表達的方向 - -- 測試不打真實 API;真實 API 只在 Debug 頁手動檢查或明確指定的冒煙測試(`questions.md` §10 備註)。 -- 冒煙測試不進 CI(`phase2-plan.md` §4 傾向,你在順序確認時「按推薦」)。 -- 只保留守「行為一致」的必要測試;static-rule 改用 Dart analyzer lint(`phase2-plan.md` §6)。 -- 開發版資料隔離(U9 勾選);單一實例保留給正式版。 - -## 研究結論(`research/` 三份,已抽查關鍵事實) - -1. **lint**:官方 `analysis_server_plugin`(Dart 3.10+)自寫規則;`custom_lint` 已封存且依賴的舊協定在 Dart 3.13.2 棄用。 - 規則測試用官方 `analyzer_testing` 的 `assertDiagnostics`/`assertNoDiagnostics`,正好是「雙向變異驗證」。 - 現成工具(DCM 付費、DCL)只能做 import/呼叫限制,ADR 0013 的嚴格空 catch 與 ADR 0014 的音源 id 規則都要自寫,所以全部自寫、不引入 DCM。 - **地雷**:`flutter analyze` 目前不顯示 plugin 診斷並回報 No issues(flutter/flutter#193203,3.47.5 可重現,修復未確認進 stable) - → CI 用 `dart analyze --fatal-infos` 並放一個必紅的哨兵檔驗證 plugin 有接上。 - 官方 `empty_catches` 放行 `catch (_) {}`,不符 ADR 0013。 -2. **fixture**:不用現成套件(`vcr` 系維護不明、`dartvcr` 是 `package:http` 不是 dio),自寫薄的 dio `HttpClientAdapter` - 在最底層錄製/重播;因為 adapter 層看到的請求已含憑證,寫檔前一律經 ADR 0011 的正式遮蔽函式,另有測試掃描所有 fixture 不得含未遮蔽憑證。 - JS 插件只經宿主 `http.request` 出網,契約測試只換掉宿主這一端,腳本不知道自己在測試。 -3. **零聯網**:`dart_test.yaml` 對 `live` tag 設 `skip`(`presets` 解除,已查 dart-lang/test 設定文件)+ - `flutter_test_config.dart` 用 `HttpOverrides.global` 讓建立真實 `HttpClient` 直接丟錯。 -4. **契約測試在哪裡跑**:`flutter_js` 的原生 QuickJS 在 `flutter test`(純 Dart VM)不會自動載入,需先建好動態庫再指定路徑 - (`quickjs_engine` 文件同樣說明);`integration_test` 在桌面跑真的 App 二進位則一定載得到。→ 第一個里程碑實測。 -5. **開發版**:Flutter 3.47 起 Windows/Linux 有官方 `--flavor`;`pubspec.yaml` 的 `flutter: default-flavor:` 讓不帶參數的 - `flutter run` 用指定 flavor(context7 查證)。官方 flavor 只管建置輸出、視窗標題、圖示; - Windows AppUserModelID、資料目錄、單一實例鎖名稱要自己依 `appFlavor` 接上(推測可行,未實測)。Android 用 `applicationIdSuffix`。 -6. **CI**:公開 repo 的 GitHub-hosted runner 免費不限分鐘;兩個 Flutter 專案用 `dorny/paths-filter` 依專案切 job, - 不依「是不是程式碼」切(舊檔頭理由仍成立);彙總 job 當唯一必要檢查。 -7. **測試比例**:Flutter 官方不給數字,只給「單元+widget 多、整合測試挑重要情境」。golden 用 `alchemist` 的 CI golden(Ahem 字型,跨平台一致), - `golden_toolkit` 已停更。 - -## 待決定 - -- [ ] 插件開發迴圈與 fixture 錄製在哪裡做(App 內開發工具 vs 只有命令列) -- [ ] 開發版資料:永遠從空白開始,或可從正式版複製一份快照 -- 其餘(lint 規則清單、空 catch 例外寫法、舊 static-rule 逐條去留、golden 範圍、CI 切分)屬技術選擇,放進 design.md 與最終摘要一併核准。 +- CI(`.github/workflows/ci.yml`):單一專案、不做路徑過濾(理由寫在檔頭 `:3-7`),釘 Flutter 3.47.1(`:28`);validate 7 分、Android 6 分、Windows 10 分。 +- 開發版與正式版共用同一個單一實例鎖與同一份資料(Windows `Documents\FMP`,`database_provider.dart:49-52`),開發時會動到真實資料。 +- 備份匯出/匯入已存在且不含帳號與 Cookie(`docs/audit/features.md` §12)。 + +## 研究結論摘要(`research/` 三份,關鍵事實已抽查) + +- lint 用官方 `analysis_server_plugin` 自寫;`custom_lint` 已封存。`flutter analyze` 目前不顯示插件診斷(flutter/flutter#193203)。 +- fixture 錄製/重播自寫在 dio `HttpClientAdapter` 層;現成套件不合 dio 或維護不明。 +- 零聯網用 `dart_test.yaml` tag skip+`HttpOverrides`(dart-lang/test 設定文件查證)。 +- `flutter_js` 的 QuickJS 在 `flutter test` 不會自動載入(`quickjs_engine` 文件);桌面 `integration_test` 一定載得到。 +- Flutter 3.47 起 Windows/Linux 有官方 flavor;`default-flavor` 可設預設 flavor(context7 查證)。 +- 公開 repo 的 CI 免費不限分鐘;Flutter 官方不給測試比例;golden 用 `alchemist`(`golden_toolkit` 停更)。 + +## 決定 + +1. **檢查案例一份四用**:每插件每能力最多一條案例,用於契約測試(重播,進 CI)、冒煙測試(真實連線、手動)、 + Debug 頁健康檢查(真實連線、App 內)、錄製(遮蔽後存 fixture)。冒煙測試不進任何 CI、不排程(你先前按推薦確認)。 +2. **插件開發在 App 內**(2026-09-27 選 A):開發者模式下從資料夾載入、重新載入、跑案例看 log、用 App 內登入錄 fixture、每插件切換真實/錄製/重播; + 命令列只負責重播。從資料夾載入先只在桌面平台。 +3. **開發版資料預設空白**(2026-09-27 選 A):要真實資料時用舊資料匯入(選資料夾副本)或還原正式版備份,不另做快照功能; + 開發版拒絕直接讀舊版正式資料位置。Android 的舊資料遷移驗證在模擬器以 prod flavor 做。 +4. 技術選擇(`design.md`):測試分層與原則(§1)、lint L1–L10 與接線哨兵(§2)、fixture 格式/遮蔽/契約執行器/測試插件(§3)、 + 零聯網(§4)、flavor 與身分(§5)、舊 static-rule 逐條去向(§6)、CI 依專案切分(§7)、第一個里程碑實測(§8)。 ## 驗收條件 -- [ ] ADR 0015 記錄:測試分層與保留原則、lint 閘門與 CI 指令、零聯網機制、fixture 格式與遮蔽、插件契約測試/冒煙測試/健康檢查的關係、開發版身分與資料隔離、CI 切分。 -- [ ] 舊 static-rule 25 支逐條給出去向(改 lint/改測試/刪除/屬舊專案不動),附理由。 -- [ ] ADR 0008(`app/` 不 import 舊專案)、0011(遮蔽測試)、0013(空 catch、原文不上畫面)、0014(契約測試、音源 id lint)的「如何確認」各自對到一個具體閘門。 -- [ ] 第一個里程碑的必要驗證(`phase2-plan.md` §7)補上本項的實測項。 -- [ ] `phase2-plan.md` §3 第 8 項標 ✅ 與 ADR 編號。 +- [ ] ADR 0015 記錄決定 1–4 的原則與理由,含被否決的方案(DCM/`custom_lint`、現成 VCR 套件、排程冒煙測試、命令列限定的插件開發、開發版快照)。 +- [ ] 舊 static-rule 25 支+`test/workflows/` 逐條有去向與理由(`design.md` §6)。 +- [ ] ADR 0008、0009、0010、0011、0013、0014 的「如何確認」中待測試策略落實的閘門,各自對到一條規則名或測試。 +- [ ] `phase2-plan.md` §7 加入 `design.md` §8 的實測項;§3 第 8 項標 ✅ 與 ADR 編號;§10 交接段更新。 +- [ ] `git grep "測試策略 ADR" docs/adr` 無遺留指向。 ## 不在範圍 - 實作任何測試、lint 或 CI(屬各里程碑)。 -- Debug 頁的版面與其他功能(第 4 項);本項只定健康檢查與插件開發工具「要不要有、共用什麼」。 +- Debug 頁與插件開發工具的版面(第 4 項);播放核心、歌詞、背景任務、UI、發版相關規則的細節(第 13、15、16、5、19 項)。 - 舊專案(根目錄)的測試調整,除了 CI 切分。 From a5a2239224bad7635546bc8d0f55cf69521a1626 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:43:37 +0800 Subject: [PATCH 036/133] docs(adr): 0015 testing gates and dev environment --- .../0008-rewrite-as-new-app-in-same-repo.md | 6 +- ...atform-layer-with-declared-capabilities.md | 2 +- ...0010-drift-data-layer-and-legacy-import.md | 2 +- docs/adr/0011-settings-and-logging.md | 2 +- docs/adr/0013-unified-error-model.md | 2 +- docs/adr/0014-script-source-plugins.md | 4 +- .../0015-testing-gates-and-dev-environment.md | 94 +++++++++++++++++++ 7 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 docs/adr/0015-testing-gates-and-dev-environment.md diff --git a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md index 22abcf83b..b8d26532b 100644 --- a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md +++ b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md @@ -65,10 +65,10 @@ FMP 經過多輪 AI agent 自主修改(`lib/` 343 檔 99,063 行),擁有 - 壞的:重寫期間 CI 要跑兩個專案,時間變長;兩份 `AGENTS.md` 要各自寫清楚適用範圍; 新 App 功能齊全前不能取代舊版。 - 之後要注意:新 App 的身分識別一旦與舊版不同就無法自動遷移,任何改動 `applicationId`、簽名、AppId 的變更都必須另立 ADR。 - CI 如何同時處理兩個專案、舊專案不穩的測試是否擋 PR,由測試策略的 ADR 決定。 + CI 依專案切分,舊專案的測試只在根目錄變動時跑、不擋 `app/` 的 PR(ADR 0015)。 ## 如何確認 -- `app/` 不得 import 根目錄舊專案:由 `app/` 的 analyzer 設定與 import lint 守(測試策略 ADR 落實時加上);在那之前靠 PR review。 -- App 身分識別:切換前的里程碑加一項檢查,比對 `app/` 的 `applicationId`、AppUserModelID、Inno Setup AppId 與上列現值一致。 +- `app/` 不得 import 根目錄舊專案:lint `fmp_layer_imports`(ADR 0015)。 +- App 身分識別:測試斷言 prod flavor 的身分值與上列一致(ADR 0015);切換前的里程碑另加一項檢查,比對 `app/` 的 `applicationId`、AppUserModelID、Inno Setup AppId 與上列現值一致。 - 切換條件:切換 PR 的 review 指南逐項列出 `features.md` 勾「保留」的功能與效能量測結果。 diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 52febc2b7..5216b75af 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -76,6 +76,6 @@ Linux、macOS 加入時要回頭改介面。 ## 如何確認 -- 平台層以外禁止平台判斷與平台套件 import:Dart analyzer lint(測試策略 ADR 選定工具後加上);在那之前由 PR review 檢查。 +- 平台層以外禁止平台判斷與平台套件 import:lint `fmp_platform_checks` 與 `fmp_layer_imports`(ADR 0015)。 - 能力宣告與 UI 一致:每個平台 child task 的驗收包含「宣告為沒有的能力,UI 不出現入口」。 - CI:從第一個里程碑起建置矩陣含 Linux、macOS、iOS(不簽名)。 diff --git a/docs/adr/0010-drift-data-layer-and-legacy-import.md b/docs/adr/0010-drift-data-layer-and-legacy-import.md index d7c35928d..2b1d69df9 100644 --- a/docs/adr/0010-drift-data-layer-and-legacy-import.md +++ b/docs/adr/0010-drift-data-layer-and-legacy-import.md @@ -76,5 +76,5 @@ - Schema 快照與每個 migration 的升級測試在 CI 執行。 - 「migration 不改使用者設定過的值」有專門測試:先寫入使用者值,跑 migration,斷言值不變。 -- 資料庫只由資料層存取、`legacy_import/` 不被其他模組 import:import lint(測試策略 ADR 落實)。 +- 資料庫只由資料層存取、`legacy_import/` 不被其他模組 import:lint `fmp_layer_imports`(ADR 0015)。 - 切換前,在擁有者真實資料的副本上完整跑一次匯入,並把筆數比對結果附在切換 PR 的 review 指南。 diff --git a/docs/adr/0011-settings-and-logging.md b/docs/adr/0011-settings-and-logging.md index f1929e40d..0e95bd32f 100644 --- a/docs/adr/0011-settings-and-logging.md +++ b/docs/adr/0011-settings-and-logging.md @@ -56,6 +56,6 @@ Spotube 以 drift 存設定並以 `watchSingle()` 接 Riverpod。 ## 如何確認 -- lint:門面以外禁止 `print`、`debugPrint`、`developer.log`、import talker(測試策略 ADR 落實)。 +- lint:門面以外禁止 `print`、`debugPrint`、`developer.log`、import talker:lint `fmp_log_facade`(ADR 0015)。 - 遮蔽測試:每個音源一組假憑證與假簽名 URL,斷言經 log 檔、記憶體歷史、診斷包、網路紀錄後都不再出現原值,包括出現在 stackTrace 的情況。 - 設定測試:寫入使用者值後改變程式預設,斷言讀到的仍是使用者值;未設定的欄位讀到新預設。 diff --git a/docs/adr/0013-unified-error-model.md b/docs/adr/0013-unified-error-model.md index 148040b5f..94cdf023c 100644 --- a/docs/adr/0013-unified-error-model.md +++ b/docs/adr/0013-unified-error-model.md @@ -73,4 +73,4 @@ Finamp 以「類別+來源」去重;Riverpod 官方的全域 `retry` 設定 - 契約測試:每個音源以錄下的錯誤回應 fixture,斷言對應到的 `AppError` 類別。 - 測試:`ProviderScope` 的 retry 為關閉;網路層只對冪等請求重試、尊重 `Retry-After`。 -- lint:禁止空 catch;禁止在 UI 顯示 `toString()` 之類的原文(以只接受 i18n key 的呈現 API 在型別上擋住)。 +- lint:禁止空 catch(`fmp_no_empty_catch`,ADR 0015);禁止在 UI 顯示 `toString()` 之類的原文(以只接受 i18n key 的呈現 API 在型別上擋住)。 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index 7db4e0ef8..374c4b15b 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -67,6 +67,6 @@ Flutter federated plugin 的「一套介面、多種實作」;Spotube 的匹 ## 如何確認 - 結構測試:每個插件的 manifest 能力與它實際匯出的函式一致;`apiVersion` 不相容時拒絕載入。 -- 契約測試:以錄下的 HTTP 回應重播執行每個插件,涵蓋 ADR 0011(遮蔽)、0012(媒體請求不帶憑證、`AuthRequirement`)、0013(錯誤對應);插件 repo 的 CI 與插件作者本機都能跑。 +- 契約測試:以錄下的 HTTP 回應重播執行每個插件的檢查案例(執行器與 fixture 格式見 ADR 0015),涵蓋 ADR 0011(遮蔽)、0012(媒體請求不帶憑證、`AuthRequirement`)、0013(錯誤對應);插件 repo 的 CI 與插件作者本機都能跑。 - 測試:宿主 HTTP 拒絕 manifest 網域以外的請求;腳本無法讀取其他插件的 storage 與憑證。 -- lint:UI 與 service 不得出現音源 id 字串常數或特定音源的型別(測試策略 ADR 落實)。 +- lint:UI 與 service 不得出現音源 id 字串常數或特定音源的型別:lint `fmp_source_id_literal`(ADR 0015)。 diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md new file mode 100644 index 000000000..6fd5f46c5 --- /dev/null +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -0,0 +1,94 @@ +# 0015 — 測試與閘門:自寫 lint、預設零聯網、插件檢查案例一份四用、開發版獨立身分 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`app/` 的測試、`app/packages/fmp_lints/`、`app/analysis_options.yaml`、`app/dart_test.yaml`、 + `.github/workflows/`、`1morr/fmp-plugins` 的插件目錄格式與 CI、開發者模式的插件開發工具、App flavor + +## 背景 + +舊專案(`docs/audit/engineering.md` §3–§5):約 1,849 個離線測試;25 支 static-rule 以正則比對原始碼, +部分是計次預算且沒守住(音源分支預算 9 處、實際 50 處);`dart_test.yaml` 沒有預設跳過 `live`,裸 `flutter test` 會打真實 API; +行為測試依賴 75 個 `debug*` 測試掛鉤;開發版與正式版共用同一個單一實例鎖與同一份資料,開發時會碰到擁有者的真實資料(U9)。 + +ADR 0008–0014 各自留下「由測試策略 ADR 落實」的閘門:`app/` 不 import 舊專案、平台判斷只在平台層、Isar 只在舊資料匯入、 +log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、插件契約測試。 + +擁有者的方向:測試不打真實 API;真實 API 只在 Debug 頁手動檢查或明確指定的冒煙測試;只保留守行為一致的必要測試; +使用者能以 AI Agent 生成自己的音源(ADR 0014)。 + +## 考慮過的選項 + +- **沿用正則 static-rule 測試**:否決。只比對字串、容易漏也容易誤報,且規則不會在編輯器裡即時出現。 +- **`custom_lint`**:否決。repo 已於 2026-03 封存,依賴的舊 analyzer 插件協定在 Dart 3.13.2 棄用。 +- **DCM(付費)或 DCL**:否決。只能表達 import 與呼叫限制;嚴格空 catch 與音源 id 規則仍要自寫,不值得多一個付費依賴。 +- **現成 HTTP 錄製套件(`vcr`、`vcr2`、`dartvcr`)**:否決。`vcr` 系維護狀態查不到,`dartvcr` 基於 `package:http` 而非 dio,都沒有與正式遮蔽函式一致的遮蔽。 +- **冒煙測試排程上 CI**:否決。B 站對機房 IP 回 412 風控、YouTube 自 2024 起擋機房 IP;排程只會固定觸發風控並暴露憑證。 +- **插件只能以命令列開發與錄製**:否決。要裝 Flutter SDK 並手動貼 cookie,「使用者自己生成音源」實際上只剩會架開發環境的人做得到。 +- **開發版一鍵從正式版複製快照**:否決。多一個只給開發用的功能,且下載紀錄指向正式版檔案,開發版刪除時可能刪到真實檔案。 +- **CI 依「是不是程式碼」做路徑過濾**:否決。沿用舊 `ci.yml` 檔頭理由:文件承載規則,純文件改動不能跳過。 + +## 決定 + +1. **測試原則**:測試守契約與使用者看得到的行為,不守實作細節;行為變更同一個 PR 補測試,用能證明它的最低層。 + 分層:單元、widget(provider override 注入假資料)、插件契約、整合(只挑搜尋→播放、從檔案安裝插件、舊資料匯入)、 + golden(只給設計系統共用元件,`alchemist` 的 CI golden)。不設覆蓋率門檻。正式程式碼不留測試掛鉤,一律經建構子或 provider 注入。 +2. **lint 閘門**:以官方 `analysis_server_plugin` 自寫規則,放 `app/packages/fmp_lints/`: + + | 規則 | 內容 | + |---|---| + | `fmp_layer_imports` | 依賴方向表:`app/` 不 import 舊專案;`legacy_import` 不被 import、`isar_community` 只在其內;`drift` 只在資料層;平台套件只在平台層 | + | `fmp_no_empty_catch` | catch 本體沒有陳述式即違規,變數名 `_` 不豁免 | + | `fmp_log_facade` | `print`、`debugPrint`、`dart:developer` 的 `log`、`talker` 只在 log 門面 | + | `fmp_source_id_literal` | 官方插件 id 字串只在 `legacy_import` 與測試 | + | `fmp_url_literal` | `http(s)://` 字面值只在一個端點檔 | + | `fmp_no_for_testing` | `lib/` 不得宣告 `*ForTesting` 成員 | + | `fmp_http_client_owner` | `Dio(` 只在網路模組 | + | `fmp_test_waits` | 測試內直接呼叫 `pumpEventQueue` 只在等待助手 | + | `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | + | `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只在平台層 | + + 每條規則以官方 `analyzer_testing` 做雙向變異測試。`flutter analyze` 目前不顯示插件診斷並回報 No issues + (flutter/flutter#193203),所以 CI 跑 `dart analyze --fatal-infos`,並以接線哨兵(暫放違規檔、斷言分析失敗且含規則名)證明規則接上了 `app/`。 +3. **預設零聯網**:`app/dart_test.yaml` 對 `live` tag 設 `skip`、以 preset 解除;`app/test/flutter_test_config.dart` 以 + `HttpOverrides.global` 讓建立真實 `HttpClient` 直接失敗,要聯網的測試在自己的 zone 明確放行。JS 腳本只能經宿主 `http.request` 出網,同樣受限。 +4. **檢查案例一份四用**:每插件每能力最多一條檢查案例(`checks.json`),同一份用於契約測試(重播 fixture,進 CI)、 + 冒煙測試(真實連線,插件庫 `--live` 手動執行)、Debug 頁健康檢查(真實連線,App 內)、錄製(真實連線,遮蔽後存 fixture)。冒煙測試不進任何 CI、不排程。 +5. **fixture**:錄製與重播在宿主網路層最底部的 dio `HttpClientAdapter`;一次請求/回應一個 JSON 檔(`meta`+`request`+`response`)。 + 寫檔前一律經 ADR 0011 的正式遮蔽函式;重播比對 method+排序後的 URL+順序,被遮蔽的欄位不參與比對;比對不到就讓測試失敗。 + 錯誤案例可手改 fixture 並標記。 +6. **契約執行器**:一個通用套件以重播執行每個案例,斷言能力與匯出一致、DTO 驗證、案例期望、錯誤對到 `AppError` 類別(0013)、 + 媒體請求不帶憑證(0012)、只連 manifest 網域、log 經遮蔽(0011)。插件庫 CI 以固定的 FMP 版本執行;`app/` 的 CI 對 `app/test/fixtures/plugins/` + 內的測試插件執行(合成資料、播放本機音檔),不依賴官方插件庫;同一個測試插件也供開發版離線開發。 +7. **App 內插件開發工具**:開發者模式下從資料夾載入插件(先限桌面平台,由平台層宣告)、重新載入、跑案例看 log、 + 以 App 內登入錄 fixture、每插件切換真實/錄製/重播。命令列只負責重播。版面由 Debug 頁的設計定。 +8. **開發版**:flavor `dev`/`prod`,`pubspec.yaml` 設 `default-flavor: dev`,發版明確帶 `--flavor prod`。 + dev 的 Android `applicationIdSuffix ".dev"`、Windows AppUserModelID `com.personal.fmp.dev`、名稱「FMP Dev」與標記圖示、 + 資料目錄/單一實例鎖/secure storage 命名空間加 `-dev`;prod 維持 ADR 0008 的身分。開發版資料預設空白, + 真實資料以舊資料匯入(選資料夾副本)或還原正式版備份帶入;開發版拒絕直接讀舊版正式資料位置。 + Android 開發版讀不到舊版私有資料,Android 的舊資料遷移驗證在模擬器以 prod flavor 做。 +9. **CI**:`dorny/paths-filter` 依專案切分——`app/**` 與 `.github/**` 觸發 `app` 的 job,`app/` 以外的任何變動(含文件)觸發舊專案的 job; + 一個 `always()` 彙總 job 當唯一必要檢查。`app` 的 job:format、`dart analyze`、接線哨兵、`flutter analyze`、lint 規則測試、 + 不加參數的 `flutter test`、契約執行器、Android/Windows/Linux/macOS/iOS(不簽名)建置、Linux 與 Windows 的整合測試。 + 舊專案的 job 維持現狀,只在根目錄變動時跑,`app/` 的 PR 不被舊專案的不穩測試擋住。 +10. **舊 static-rule**:原樣留在舊專案守舊程式碼,切換 PR 時一併刪除。概念在 `app/` 的去向(改 lint、改測試、刪除、由後續設計項決定) + 逐條列在 `.trellis/tasks/archive/2026-09/09-27-design-testing/design.md` §6。 + +採用的慣例:Dart 官方 `analysis_server_plugin` 與 `analyzer_testing`;`package:test` 的 tag 與 preset;VCR 錄製重播模式(自寫、接在 dio adapter); +Flutter 官方 flavor 與 `default-flavor`;`dorny/paths-filter` 的 monorepo 切分;Flutter 官方測試總覽的權衡(單元與 widget 多、整合只挑重要情境)。 + +## 後果 + +- 好的:規則在編輯器裡即時出現且每條有雙向測試;裸 `flutter test` 保證不聯網;每個插件的錯誤、遮蔽、憑證邊界都用同一套案例驗證; + 使用者不裝開發環境也能在 App 內開發並錄製插件;開發時不再碰到真實資料;兩個專案的 CI 失敗不會互相誤導。 +- 壞的:要維護自寫的 lint 套件;fixture 會隨上游改版過時,要重錄;Debug 頁多一塊插件開發工具;flavor 的 Windows 身分、鎖與資料目錄要自己接。 +- 之後要注意:`flutter analyze` 的插件診斷 bug 修好後可以拿掉 `dart analyze` 的重複步驟,但接線哨兵保留; + 播放核心、歌詞、背景任務、UI、發版各自決定 `design.md` §6 標給它們的規則;`riverpod_lint` 是否已遷移到新插件系統在落地時查證。 + +## 如何確認 + +- `fmp_lints` 每條規則的 `analyzer_testing` 測試(違規會報、無關改動不報);CI 的接線哨兵。 +- 第一個里程碑實測:`dart analyze` 看得到插件診斷;契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`); + dev 與 prod 同時開啟時身分、鎖、資料目錄各自獨立;一個故意聯網的測試在裸 `flutter test` 被跳過、解除 tag 後被 `HttpOverrides` 擋下。 +- 測試:prod 的身分值與 ADR 0008 一致、dev 每一項都不同;開發版拒絕舊版正式資料路徑;掃描所有 fixture 不得有未遮蔽憑證。 +- `AGENTS.md`(`app/`)列出的每條靜態規則都寫出對應規則名;沒有規則守的不寫進去。 From 292e88d615dcbd81141d4d340b457d3c28e94b6a Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:43:38 +0800 Subject: [PATCH 037/133] chore(task): archive design-testing --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 13 ++++++------- .trellis/tasks/09-27-design-testing/implement.md | 11 ----------- .../2026-09}/09-27-design-testing/check.jsonl | 0 .../2026-09}/09-27-design-testing/design.md | 0 .../2026-09}/09-27-design-testing/implement.jsonl | 0 .../2026-09/09-27-design-testing/implement.md | 11 +++++++++++ .../2026-09}/09-27-design-testing/prd.md | 0 .../09-27-design-testing/research/dev-env-and-ci.md | 0 .../research/fixtures-and-network.md | 0 .../09-27-design-testing/research/lint-and-gates.md | 0 .../2026-09}/09-27-design-testing/task.json | 6 +++--- 11 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 .trellis/tasks/09-27-design-testing/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-27-design-testing/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/research/dev-env-and-ci.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/research/fixtures-and-network.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/research/lint-and-gates.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-testing/task.json (89%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 0dfe2ef71..fed0ee383 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -118,7 +118,7 @@ flowchart LR | 6 | 12 網路與帳號(✅ 完成,ADR 0012) | HTTP client、憑證、「哪些請求帶憑證」的單一宣告點。 | | 7 | 2 錯誤模型(✅ 完成,ADR 0013) | 音源插件介面的回傳與例外型別要先定。 | | 8 | 1 音源插件(✅ 完成,ADR 0014) | 核心抽象;依賴 10、12、2。 | -| 9 | 8 測試與開發環境 | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | +| 9 | 8 測試與開發環境(✅ 完成,ADR 0015) | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | | 10 | 17 快取與離線 | 串流 URL、圖片、排行快取的策略,播放核心要用。 | | 11 | 16 背景任務 | 刷新、清理、更新檢查誰來排程。 | | 12 | 13 播放核心 | 最大的一塊;依賴 1、2、10、17。 | @@ -223,6 +223,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 - ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。 - ADR 0014:JS 執行環境(`flutter_js`)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;`flutter_js` 在 Android、Windows 的 Promise/記憶體/啟動成本實測;YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)。 +- ADR 0015:`fmp_lints` 接上 `app/`,`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)。 ## 8. 延後到特定里程碑的實測 @@ -236,12 +237,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0014`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0015`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 8 項「測試、閘門與開發環境」**,task `.trellis/tasks/09-27-design-testing/`(planning 狀態); - 研究代理的產出寫到該目錄 `research/`(`lint-and-gates.md`、`fixtures-and-network.md`、`dev-env-and-ci.md`)。 - 下一步:讀研究 → 寫 prd.md(現況、研究結論、待決定)→ 一次問使用者一個問題 → design.md/implement.md → 最終摘要等核准 → 寫 ADR 0015 → 歸檔。 -- 之後順序:17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 17 項「快取與離線」(尚未建 task)。 +- 之後順序:16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-27-design-testing/implement.md b/.trellis/tasks/09-27-design-testing/implement.md deleted file mode 100644 index 8ba410940..000000000 --- a/.trellis/tasks/09-27-design-testing/implement.md +++ /dev/null @@ -1,11 +0,0 @@ -# 執行計畫:第 8 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0015-testing-gates-and-dev-environment.md`(MADR-lite,依 `docs/adr/template.md`),內容取自 `design.md` §1–§7; - 舊 static-rule 去向表放 ADR 附錄或連回本任務歸檔的 `design.md`(ADR 只留原則與「第幾項決定」的指向)。 -2. ADR 0008 的「如何確認」與「之後要注意」補一句:`app/` 不 import 舊專案由 L1 守、CI 切分已在 ADR 0015 決定。 - ADR 0009、0010、0011、0014 的「如何確認」寫「測試策略 ADR 落實/選定工具後加上」的地方,改成指向 0015 的規則名。 -3. `phase2-plan.md`:§3 第 8 項標 ✅(ADR 0015);§7 加入 `design.md` §8 的四項實測;§10 交接段更新進度與下一項(17 快取與離線)。 -4. 驗證:Mermaid 以 mermaid-cli 渲染成功(設計圖已驗);`git grep -n "測試策略 ADR"` 確認沒有漏改的指向。 -5. `task.py finish`、`task.py archive design-testing --no-commit --skip-branch-validation`;Conventional Commits 分開提交 ADR 與任務歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-testing/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-testing/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-testing/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-testing/check.jsonl diff --git a/.trellis/tasks/09-27-design-testing/design.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/design.md similarity index 100% rename from .trellis/tasks/09-27-design-testing/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-testing/design.md diff --git a/.trellis/tasks/09-27-design-testing/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-testing/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-testing/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-testing/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-27-design-testing/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/implement.md new file mode 100644 index 000000000..51e7482e4 --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-27-design-testing/implement.md @@ -0,0 +1,11 @@ +# 執行計畫:第 8 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0015-testing-gates-and-dev-environment.md`(MADR-lite,依 `docs/adr/template.md`),內容取自 `design.md` §1–§7; + 舊 static-rule 去向表放 ADR 附錄或連回本任務歸檔的 `design.md`(ADR 只留原則與「第幾項決定」的指向)。 +2. [x] ADR 0008 的「如何確認」與「之後要注意」補一句:`app/` 不 import 舊專案由 L1 守、CI 切分已在 ADR 0015 決定。 + ADR 0009、0010、0011、0014 的「如何確認」寫「測試策略 ADR 落實/選定工具後加上」的地方,改成指向 0015 的規則名。 +3. [x] `phase2-plan.md`:§3 第 8 項標 ✅(ADR 0015);§7 加入 `design.md` §8 的四項實測;§10 交接段更新進度與下一項(17 快取與離線)。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染成功(設計圖已驗);`git grep -n "測試策略 ADR"` 確認沒有漏改的指向。 +5. [x] `task.py finish`、`task.py archive design-testing --no-commit --skip-branch-validation`;Conventional Commits 分開提交 ADR 與任務歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-testing/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-testing/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-testing/prd.md diff --git a/.trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/research/dev-env-and-ci.md similarity index 100% rename from .trellis/tasks/09-27-design-testing/research/dev-env-and-ci.md rename to .trellis/tasks/archive/2026-09/09-27-design-testing/research/dev-env-and-ci.md diff --git a/.trellis/tasks/09-27-design-testing/research/fixtures-and-network.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/research/fixtures-and-network.md similarity index 100% rename from .trellis/tasks/09-27-design-testing/research/fixtures-and-network.md rename to .trellis/tasks/archive/2026-09/09-27-design-testing/research/fixtures-and-network.md diff --git a/.trellis/tasks/09-27-design-testing/research/lint-and-gates.md b/.trellis/tasks/archive/2026-09/09-27-design-testing/research/lint-and-gates.md similarity index 100% rename from .trellis/tasks/09-27-design-testing/research/lint-and-gates.md rename to .trellis/tasks/archive/2026-09/09-27-design-testing/research/lint-and-gates.md diff --git a/.trellis/tasks/09-27-design-testing/task.json b/.trellis/tasks/archive/2026-09/09-27-design-testing/task.json similarity index 89% rename from .trellis/tasks/09-27-design-testing/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-testing/task.json index 5e2b41297..e052788c6 100644 --- a/.trellis/tasks/09-27-design-testing/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-testing/task.json @@ -3,7 +3,7 @@ "name": "design-testing", "title": "Design: tests, gates and dev environment", "description": "Phase-2 item 8: which old tests and static rules to keep, lint-based gates, zero-network default tests with recorded fixtures, contract tests for script plugins, live smoke tests, dev instance isolation, CI matrix", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-27", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From e862b31591f15bc352d4540e7b6223e33839116c Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 14:44:55 +0800 Subject: [PATCH 038/133] chore(task): start design-cache-offline --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-27-design-cache-offline/check.jsonl | 0 .../implement.jsonl | 0 .../tasks/09-27-design-cache-offline/prd.md | 19 ++++++++++++++ .../09-27-design-cache-offline/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-27-design-cache-offline/check.jsonl create mode 100644 .trellis/tasks/09-27-design-cache-offline/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-cache-offline/prd.md create mode 100644 .trellis/tasks/09-27-design-cache-offline/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index fed0ee383..cfdb2cf7f 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -240,7 +240,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0015`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 17 項「快取與離線」(尚未建 task)。 +- **進行中:第 17 項「快取與離線」**,task `.trellis/tasks/09-27-design-cache-offline/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 29cfe2f10..47357c018 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -28,7 +28,8 @@ "09-27-design-network-accounts", "09-27-design-errors", "09-27-design-source-plugins", - "09-27-design-testing" + "09-27-design-testing", + "09-27-design-cache-offline" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-cache-offline/check.jsonl b/.trellis/tasks/09-27-design-cache-offline/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-cache-offline/implement.jsonl b/.trellis/tasks/09-27-design-cache-offline/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-cache-offline/prd.md b/.trellis/tasks/09-27-design-cache-offline/prd.md new file mode 100644 index 000000000..c2ee160a8 --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/prd.md @@ -0,0 +1,19 @@ +# Design: cache and offline + +## Goal + +Phase-2 item 17: unified cache strategy for images, stream URLs, lyrics, charts and plugin responses; what the app can do offline + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-27-design-cache-offline/task.json b/.trellis/tasks/09-27-design-cache-offline/task.json new file mode 100644 index 000000000..c1c492a1c --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-cache-offline", + "name": "design-cache-offline", + "title": "Design: cache and offline", + "description": "Phase-2 item 17: unified cache strategy for images, stream URLs, lyrics, charts and plugin responses; what the app can do offline", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From bef9c34b0270b14b3b40d09c9e00c2ca028e4cd3 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 15:30:05 +0800 Subject: [PATCH 039/133] chore(task): add design-cache-offline research and prd draft --- .../tasks/09-27-design-cache-offline/prd.md | 56 ++- .../research/current-state.md | 433 ++++++++++++++++++ .../research/packages-and-platform.md | 252 ++++++++++ .../research/prior-art.md | 365 +++++++++++++++ 4 files changed, 1095 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-27-design-cache-offline/research/current-state.md create mode 100644 .trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-27-design-cache-offline/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-cache-offline/prd.md b/.trellis/tasks/09-27-design-cache-offline/prd.md index c2ee160a8..56de766c9 100644 --- a/.trellis/tasks/09-27-design-cache-offline/prd.md +++ b/.trellis/tasks/09-27-design-cache-offline/prd.md @@ -1,19 +1,53 @@ -# Design: cache and offline +# 設計:快取與離線(階段二第 17 項) -## Goal +## 目標 -Phase-2 item 17: unified cache strategy for images, stream URLs, lyrics, charts and plugin responses; what the app can do offline +為 `app/` 定下圖片、串流網址、歌詞、排行與插件回應等快取的統一策略,以及沒有網路時 App 能做什麼。產出 ADR 0016。 -## Requirements +依據:parent `prd.md` 階段二第 17 項;`phase2-plan.md`(B6、D9,及相關的 B10、B12);ADR 0010–0015。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對) -## Acceptance Criteria +- **圖片**:三層互不統一——Flutter 記憶體 `ImageCache`(寫死 行動 100 張/50MB、桌面 200 張/80MB,`lib/main.dart:156-164`)、 + `flutter_cache_manager` 磁碟快取(7 天、上限由設定「圖片快取大小」16–64MB 推估檔案數,`network_image_cache_service.dart:127-140`)、 + 解碼縮放。使用者設定只管磁碟那一層;「清除圖片快取」不清記憶體層。同一張圖不同顯示尺寸各存一份(`image_loading_service.dart:315-383`)。 +- **串流網址**:存進 Isar `Track.audioUrl`/`audioUrlExpiry`(`track.dart:68-71`),另有行程內 32 筆快取(`stream_resolution_service.dart:109-113`)。 + 播放只看行程內快取、不用 Isar 那份,所以持久化實際沒用;**反而造成預取失效**:下一首在 Isar 有「未過期」網址時 `prefetchTrack` 直接返回 + (`:299-304`),切歌時退化成同步解析。過期來源:B 站讀 `deadline`、YouTube 寫死 1 小時(D9)、網易讀 `expi` 否則 16 分鐘。 +- **歌詞**:`getApplicationCacheDirectory()/lyrics/` 每首一個 JSON,LRU,檔數上限可調(10–200)、總量寫死 5MB(`lyrics_cache_service.dart:19-64`)。 +- **排行**:只在記憶體,重啟重抓;離線時保留舊資料;**停用首頁顯示的音源仍在背景抓**(`ranking_cache_service.dart:158-172`,B12)。 +- **電台**:沒有快取,只有記憶體中的直播狀態。搜尋歷史是使用者資料(Isar,上限 100),不是快取。 +- **音訊**:沒有邊聽邊存。Windows mpv 只是播放期記憶體緩衝;已下載的曲目優先播本機檔,離線可播。 +- **離線**:每 15 秒對三個公共 DNS 查詢判定(`connectivity_service.dart:51-116`,B10);只有一個全域 Banner,沒有任何頁面有離線狀態。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- MusicFree 讓音源插件自己宣告網址能否重用(`cacheControl`),App 不必懂各平台的 `expire`/`deadline`;NewPipe 用固定 TTL(YouTube 1 小時)。 +- Namida 是唯一分類可調上限+LRU 的;Spotube 一個開關;MusicFree 一個音樂快取容量+三個清除按鈕;Finamp 不做快取、只靠明確下載,並有自動+手動的離線模式。 +- `cached_network_image`/`flutter_cache_manager` 仍活躍(2026-09 發版)。`just_audio` 的 `LockCachingAudioSource` 仍是 experimental,Windows/Linux 不保證; + `media_kit` 沒有邊聽邊存,只能自建本機 proxy。 +- `getApplicationCacheDirectory()` 在 Android 會被系統在空間不足時清掉,官方要求 App 自行處理。 +- `connectivity_plus` 官方文件明說「有網路介面不代表能上網」,建議以請求本身的錯誤判斷——與 B10 的方向一致。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向(先前的勾選) + +- B6:串流網址不進資料庫,只放短期快取。D9:網址期限從網址本身讀,不寫死。B10:拿掉 DNS 輪詢,改系統網路狀態+請求失敗判定。B12:停用就不抓排行。 + +## 依功能凍結歸入待辦(第 20 項),本項不做 + +- 邊聽邊存(音訊快取):新功能,且 Windows 需自建 proxy。現有的「下載」照舊是唯一的離線保存方式。 +- 手動離線模式開關、已下載內容的容量管理(LRU+釘選):新功能。 + +## 待決定 + +- [ ] 快取的使用者設定形式(一個總上限 vs 分類上限) + +## 驗收條件 + +- [ ] ADR 0016 記錄:快取的定義與位置、每一類的鍵/期限/上限/清除、串流網址期限由插件回報、離線判定與離線時各功能的行為、使用者設定。 +- [ ] B6、D9、B10(離線判定部分)、B12 各自對到決定與閘門;舊預取失效問題在新設計下不再成立並有測試守。 +- [ ] `phase2-plan.md` §3 第 17 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 背景刷新的排程機制(第 16 項);播放佇列跳過的細節(第 13 項);下載(第 11 項);設定頁版面(第 5 項)。 diff --git a/.trellis/tasks/09-27-design-cache-offline/research/current-state.md b/.trellis/tasks/09-27-design-cache-offline/research/current-state.md new file mode 100644 index 000000000..cdab9415b --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/research/current-state.md @@ -0,0 +1,433 @@ +# Research: 快取與離線行為 —— 舊代碼庫(lib/)現況基線 + +- **驗證日期**:2026-09-27 +- **方法**:先讀 `docs/audit/{data,playback,sources,perf-baseline,features,platforms,questions}.md` 找線索, + 再逐一開對應的 `lib/` 原始碼重新核對;審計文件的結論一律視為「待驗證假設」, + 本文件只記錄本次親自讀過原始碼後確認的事實。凡未能在原始碼中核對到的項目, + 明確標註「查不到」並說明已嘗試的搜尋方式;純推論未見直接程式碼佐證的, + 標註「推測」。所有結論括號內為 `檔案路徑:行號`(相對 repo 根目錄)。 +- **範圍**:只描述 `lib/` 現況,不做設計建議或評論(含 B12 相關的排行榜背景刷新 + 行為,只如實記錄現況)。 + +--- + +## 1. 圖片快取 + +**套件與分層**:`cached_network_image: ^4.0.0` + `flutter_cache_manager: ^3.4.2` +(`pubspec.yaml:52-53`)。圖片快取實際上有三層,彼此獨立、由不同機制管理: + +1. **Flutter 內建記憶體快取**(`PaintingBinding.instance.imageCache`): + App 啟動時依平台寫死大小,Android/iOS 100 張 / 50MB,桌面 200 張 / 80MB + (`lib/main.dart:156-164`)。**不可由使用者調整**,也不受設定頁「圖片快取 + 大小」影響。 +2. **`flutter_cache_manager` 磁碟快取**(`NetworkImageCacheService` + /`_FmpImageCacheManager`,`lib/core/services/network_image_cache_service.dart`): + 快取目錄為 `getTemporaryDirectory()/fmp_network_image_cache` + (`network_image_cache_service.dart:282-284`);固定 `stalePeriod` 7 天 + (`_stalePeriodDays = 7`, `network_image_cache_service.dart:127`),**不可 + 由使用者調整**;`maxNrOfCacheObjects` 由目前大小上限除以 100KB 估算, + clamp 在 100–3000 個 (`network_image_cache_service.dart:131-132`)。 +3. **`ResizeImage` 解碼快取**:主顯示路徑用 `memCacheHeight` 限制解碼後圖片 + 佔用的記憶體,磁碟不做二次縮放(`image_loading_service.dart:614-624, + 646-660`,comment 明確說明是刻意避免 flutter_cache_manager 同時存原圖與 + 縮放副本造成雙倍磁碟佔用)。 + +**使用者可調的「圖片快取大小」設定**:`Settings.maxCacheSizeMB` +(`lib/data/models/settings.dart:247`,欄位預設 32),UI 在 +`settings_cache.dart:4-127`,選項為 16/32/48/64 MB +(`settings_cache.dart:62`),最小值 16MB (`download_settings_provider.dart:102`)。 +此設定**只影響第 2 層(flutter_cache_manager 磁碟快取的檔案數估算與手動 +trim 上限)**,不影響第 1 層記憶體快取、也不影響第 2 層的 7 天有效期: +- 設定變更會呼叫 `NetworkImageCacheService.setMaxCacheSizeMB(value)` + (重建 CacheManager)與 `trimCacheIfNeeded(value)`(依修改時間刪最舊檔案 + 至符合上限)(`download_settings_provider.dart:100-113`)。 +- App 啟動時也會同步一次並做初始 trim + 估算初始化 + (`download_settings_provider.dart:69-77`)。 +- 另外還有「載入 30 張圖後檢查一次」與「估算值達 90% 上限時立即清理」的 + 背景 trim 機制 (`network_image_cache_service.dart:142-158, 190-219`)。 + +**平台差異**: +- 磁碟快取預設上限:Android/iOS 16MB,桌面 32MB + (`network_image_cache_service.dart:135-140`)。 +- 全新安裝走 `createBootstrapSettings()`:行動裝置強制設 16MB,桌面沿用 + `Settings()` 預設 32MB (`lib/data/database/database_migration.dart:106-112`)。 +- 資料完整性修復邏輯 `fix(settings.maxCacheSizeMB < 1, () => ... = 32)` + **不分平台**、壞值一律修回 32MB (`database_migration.dart:265`)——與 + 行動裝置預設 16MB 不一致,是純資料修復用途,非平台感知。 +- 記憶體快取(第 1 層):行動 100 張/50MB、桌面 200 張/80MB + (`main.dart:156-164`)。 + +**誰清除、如何清除**: +- 使用者在設定頁「清除圖片快取」只清第 2 層(`ImageLoadingService + .clearNetworkCache()` → `NetworkImageCacheService.clearCache()`: + 呼叫 `cacheManager.emptyCache()` 後再手動刪目錄檔案、重建 CacheManager + (`network_image_cache_service.dart:262-279`) )(`settings_cache.dart:103-113`)。 + **不會清除第 1 層記憶體快取**。 +- 第 1 層記憶體快取只能在「開發者選項」頁用 + `PaintingBinding.instance.imageCache.clear()` + + `clearLiveImages()` 清除,一般使用者看不到這個入口 + (`lib/ui/pages/settings/developer_options_page.dart:266-274`)。 + +**Cache Key**:磁碟快取 key 為 `'fmp_s${cacheExtent}_$url'` +(`image_loading_service.dart:315-317, 378-383`),`cacheExtent` 依顯示尺寸 +與 DPR(量化到 0.5)計算,同一張圖不同顯示尺寸會產生不同快取條目 +(`image_loading_service.dart:340-341, 368-373`)。 + +**請求標頭**:圖片 CDN 請求預設**不帶 User-Agent**( +`SourceHttpPolicy.imageHeadersForUrl` 預設 `includeUserAgent: false`), +只帶對應音源的 Referer/Origin;下載管線與 `imageHeaders()` 預設才帶 +`mediaUserAgent` (`image_loading_service.dart:319-331`, +`source_http_policy.dart:96-119`)。 + +--- + +## 2. 串流 URL 快取 + +**Isar 持久化欄位**:`Track.audioUrl` (String?) 與 `Track.audioUrlExpiry` +(DateTime?) (`lib/data/models/track.dart:68,71`)。有效性判斷: +`hasValidAudioUrl` —— `audioUrl` 為 null 則無效;有 `audioUrlExpiry` 時要求 +`now` 早於 `expiry - 5 分鐘安全邊界`(`audioUrlRefreshMargin`) +(`track.dart:280-293`)。 + +**行程內(記憶體)解析快取**:`DefaultStreamResolutionService._resolvedStreams` +是一個 `Map`,key 為 +`'${track.uniqueKey}|${track.pageNum ?? ''}'` +(`lib/services/audio/stream_resolution_service.dart:109, 335-341`),上限 32 +筆、超過時以插入順序(近似 LRU)淘汰最舊者 +(`stream_resolution_service.dart:111-113, 382-384`)。**這個快取只存在於 +當前執行的 process,App 重啟後為空**(註解明確說明:`stream_resolution_ +service.dart:103-108`)。 + +**播放路徑會不會重用 Isar 上已持久化但仍有效的 `audioUrl`?** 不會直接重用。 +`resolvePrimary()`(播放用途)呼叫 `_reusableResolution()`,此函式**必須** +在 `_resolvedStreams`(行程內記憶體快取)命中才會回傳非 null +(`stream_resolution_service.dart:348-368`;第 355 行 `_resolvedStreams +.remove(key)` 為 null 就直接放棄,不會退回去看 `track.audioUrl` 是否仍 +`hasValidAudioUrl`)。也就是說:**App 重啟後第一次播放同一首歌,即使 Isar +裡的 `audioUrlExpiry` 還沒過期,仍會重新打網路解析**——`Track.audioUrl`/ +`audioUrlExpiry` 持久化的實際作用範圍**只在同一個 process 內的短路徑判斷** +(例如 UI 顯示、`hasValidAudioUrl` 供 `prefetchTrack` 判斷是否需要預取,見 +下方 bug)。 + +**已確認的行為/落差(非推測,有程式碼與呼叫鏈佐證)——預取(prefetch) +可能因為 Isar 殘留的「有效」`audioUrl` 而失效**: +1. `PlaybackRequestSession._prefetchNextIfRequested` 在每次成功開始播放後, + 對佇列下一首呼叫 `_audioStreamManager.prefetchTrack(nextTrack)` + (`lib/services/audio/playback_request_session.dart:813-826`)。 +2. `prefetchTrack()` 開頭檢查:若 `track.hasValidAudioUrl` 為 true 就直接 + return,不做任何解析 (`stream_resolution_service.dart:299-304`)。 +3. 若下一首曲目是從 Isar 讀出、帶著上一個 process 留下的、尚未過期的 + `audioUrl`/`audioUrlExpiry`(例如佇列裡排在後面、幾分鐘前才被 + `_applyStreamResult` 寫入資料庫的曲目 (`stream_resolution_service.dart: + 420-480`)),這次 `hasValidAudioUrl` 會是 true,於是 `prefetchTrack` + 直接跳過,**不會**把結果寫進 `_resolvedStreams`。 +4. 真正要切到這首歌時,`_armNextMedia` 呼叫 + `_audioStreamManager.selectPlayback(nextTrack, persist: false)` + (`lib/services/audio/audio_provider.dart:1663-1677`),其註解明確寫 + 「命中預取留下的行程內快取時不會再打網路」(`audio_provider.dart: + 1671-1673`)——但因為第 3 步 `prefetchTrack` 提早退出,`_resolvedStreams` + 裡根本沒有這個 key,`_reusableResolution` 會 cache miss,於是仍然要在 + `_armNextMedia` 當下同步打一次網路解析。 + **淨效果**:預取機制原本要提前把下一首解析好、讓切歌時零延遲,但只要 + 佇列裡的下一首曲目在 Isar 中殘留一個「還沒過期」的 `audioUrl`,這次 + prefetch 就會被跳過,切歌當下退化成同步網路解析(不是播放失敗,是 + 多了一次原本該提前做完的等待)。 + +**每個音源的過期時間來源與寫死值**: +- **Bilibili**:優先從 URL 的 `deadline`(unix 秒)query 參數反推實際過期時間 + (`lib/data/sources/bilibili_source.dart:428-438`,註解量到約 7178 秒 + ≈ 1.99 小時,非常接近寫死的 2 小時);已過期則回傳 `Duration.zero` + 強制立即視為需要重新解析;拿不到 `deadline` 才退回常數 + `AppConstants.bilibiliAudioUrlExpiryHours = 2` 小時 + (`lib/core/constants/app_constants.dart:26`, + `bilibili_source.dart:373-379, 417-423`)。 +- **YouTube**:**固定寫死** 1 小時 (`_audioUrlExpiry = Duration(hours: + AppConstants.youtubeAudioUrlExpiryHours)`,`youtubeAudioUrlExpiryHours = 1` + 於 `app_constants.dart:29`;套用處見 `lib/data/sources/youtube_source.dart: + 52-54` 及多處 `expiry: _audioUrlExpiry`,如行 470/518/567/738/784/831/ + 1970/2005/2020)。**不會**依實際簽名 URL 內容反推真實到期時間。 +- **NetEase**:優先用 API 回報的 `expi`(秒);`expi` 為 null 或 ≤0 時退回 + 常數 `_fallbackAudioUrlExpiry = Duration(minutes: 16)` + (`lib/data/sources/netease_source.dart:41, 152-163`)。 + +**清除/失效機制**:沒有「清除串流 URL 快取」的使用者入口;唯一的主動失效點 +是 `invalidateStream(track)`——從 `_resolvedStreams` 移除該 key,供播放失敗 +時呼叫,避免同一個壞 URL 被無限次重複交還 +(`stream_resolution_service.dart:328-333`)。`Track.audioUrl` 欄位本身不會被 +主動清空,只會在下一次成功解析時被新值覆蓋 +(`stream_resolution_service.dart:427-428, 462-474`)。 + +**下載請求刻意不重用快取**:`purpose == StreamResolutionPurpose.download` +時強制 `reusable = null`,一定重新打一次解析,理由是下載耗時可能超過 5 +分鐘安全邊界,寧可多付一次解析成本也不要让整個檔案因 URL 中途失效而報廢 +(`stream_resolution_service.dart:147-152`)。 + +--- + +## 3. 歌詞快取 + +**實作**:`LyricsCacheService` (`lib/services/lyrics/lyrics_cache_service.dart`)。 +- 儲存位置:`getApplicationCacheDirectory()/lyrics/` + (`lyrics_cache_service.dart:63-64`),每首歌一個 JSON 檔,檔名為 + `base64Url(trackUniqueKey) + '.json'` (`lyrics_cache_service.dart:268-271`)。 +- 另有 `_metadata.json` 記錄每個 key 的最後存取時間,用於 LRU 淘汰,寫入採 + 2 秒防抖 (`lyrics_cache_service.dart:33-39, 311-320`)。 +- 雙重上限:檔案數(使用者可調,見下)與**固定** 5MB 總大小上限 + (`maxCacheSizeBytes = 5 * 1024 * 1024`,`lyrics_cache_service.dart:19`, + 此值**不可由使用者調整**)。任何一項超過就以 LRU 逐一淘汰最舊檔案,直到 + 兩項都在限制內 (`lyrics_cache_service.dart:203-239`)。 + +**使用者可調的「歌詞快取」設定**:`Settings.maxLyricsCacheFiles` +(`lib/data/models/settings.dart:350`,預設 50 = +`LyricsCacheService.defaultMaxCacheFiles`),UI 選項 10/30/50/100/200 +(`settings_cache.dart:171`),最小值 10 +(`download_settings_provider.dart:118`)。變更會呼叫 +`LyricsCacheService.setMaxCacheFiles(value)`,若目前快取超過新上限會立即 +觸發清理 (`lyrics_cache_service.dart:25-31`, `download_settings_provider.dart: +115-126`)。此設定**只控制檔案數上限**,不影響固定的 5MB 大小上限,也 +不影響 LRU 的存取時間判斷邏輯本身。 + +**清除**:設定頁「清除歌詞快取」直接呼叫 `LyricsCacheService.clear()`—— +整個刪除 `lyrics/` 目錄再重建,`_accessTimes` 清空 +(`lyrics_cache_service.dart:141-158`, `settings_cache.dart:215-226`)。 + +**平台差異**:查不到——`LyricsCacheService` 沒有任何 `Platform.isX` 分支, +`getApplicationCacheDirectory()` 由 `path_provider` 依平台解析實際路徑, +但快取邏輯(上限、LRU、清除)本身對 Android/Windows 一致。 + +--- + +## 4. 排行/首頁快取(Ranking / Home) + +**實作**:`RankingCacheService` (`lib/services/cache/ranking_cache_service.dart`), +是純記憶體狀態(`Map>`),**不持久化到 Isar 或磁碟** +(`ranking_cache_service.dart:24-108`;App 重啟後榜單資料需要重新抓取, +本文件未找到任何寫入 Isar/檔案的程式碼路徑,搜尋方式:在 +`ranking_cache_service.dart` 全文與 `grep -r "RankingCacheService"` 均未見 +持久化呼叫)。 + +**刷新策略**: +- App 啟動時立即抓一次,有 5 秒初始逾時保護 + (`_defaultInitialLoadTimeout`, `ranking_cache_service.dart:117, 178-199`)。 +- 定時背景刷新,預設間隔 1 小時,可由使用者在設定頁調整為 + 30/60/120/240 分鐘 (`Settings.rankingRefreshIntervalMinutes` 預設 60, + `lib/data/models/settings.dart:434`;UI `settings_cache.dart:245-306`)。 +- 單一音源刷新失敗時走退避重試(5s/30s/2min/10min),非等到下一次整點刷新 + (`ranking_cache_service.dart:117-129, 297-311`)。 +- 監聽 `ConnectivityNotifier.onNetworkRecovered`,網路恢復時立即重新整個 + 刷新一輪 (`ranking_cache_service.dart:149, 217-230`)。 + +**是否會抓「已停用顯示」的音源(現況,對應 B12 的現況描述,不含任何設計 +評論)**:`RankingCacheService.bindSources()` 用 +`manager.registeredSourceTypes`(`SourceManager` 註冊過的所有音源)建立要 +刷新的榜單清單 (`ranking_cache_service.dart:158-172`),**與**首頁顯示用的 +`homeRankingSettingsProvider.disabledSources`(使用者在「首頁熱門來源」設定 +頁勾掉的音源,`lib/providers/settings/home_ranking_settings_provider.dart: +11-38, 107-170`)**完全是兩條互不相干的資料**:`registeredSourceTypes` +只反映音源是否被 `SourceManager` 註冊(見 `lib/data/sources/source_provider. +dart:20`),不受「首頁熱門來源」開關影響。因此目前程式碼行為是:使用者在 +首頁設定頁停用某音源的排行顯示後,`RankingCacheService` 仍會照 +`rankingRefreshIntervalMinutes` 的間隔在背景持續抓該音源的榜單資料,只是 +首頁 UI 不顯示(UI 端用 `enabledHomeRankingSourceOrderProvider` 過濾, +`home_ranking_settings_provider.dart:193-195`,本次未展開讀取 UI 消費端, +以 `docs/audit/features.md` 對此點的描述與本次核對的 `bindSources` 邏輯 +互相印證,判定一致)。 + +--- + +## 5. 電台快取 + +**沒有獨立的「電台快取」機制/檔案**。搜尋方式: +1. 全域搜尋 `RadioCacheService` 類別與 `radio.*cache`/`radio.*Cache` 樣式的 + 檔名或類別名,均無結果。 +2. 讀了唯一相關服務 `RadioRefreshService` + (`lib/services/radio/radio_refresh_service.dart`),其角色是**直播狀態 + 輪詢**,不是內容快取: + - `_liveStatus`(`Map`)只存在記憶體,記錄各電台目前是否在 + 直播 (`radio_refresh_service.dart:66, 79-80`),**不持久化**。 + - 電台的封面/標題/主播名若有變化,會回寫進 Isar 的 `RadioStation` 實體 + 本身(`repository.save(station)`,`radio_refresh_service.dart:195-215`), + 這是電台元資料的**目前值**,不是另一份「快取」副本。 + - 刷新間隔可調(0=關閉、1/3/5/10 分鐘,`RadioRefreshService.offMinutes` + 常數與 UI 選項,`settings_cache.dart:308-370`),預設 5 分鐘 + (`radio_refresh_service.dart:34`)。 + - 有風控退避(連續被限流時間隔倍增,上限 30 分鐘, + `radio_refresh_service.dart:239-250`)與 App 進背景暫停輪詢 + (`radio_refresh_service.dart:133-146`),這兩者是流量控制,非快取策略。 + - 電台音訊串流本身走一般播放路徑,沒有另外的電台專屬串流快取層——本次 + 搜尋 `lib/services/radio/` 目錄下與 `cache` 相關的字串未再找到其他 + 結果。 + +--- + +## 6. 搜尋歷史 + +**儲存**:Isar `SearchHistory` collection (`lib/data/models/search_history.dart`), +欄位為 `query`(`@Index()`)與 `timestamp`(`@Index()`)。透過 +`SearchHistoryRepository` 存取 (`lib/data/repositories/search_history_repository.dart`)。 + +**上限**:`AppConstants.maxSearchHistoryCount = 100` +(`lib/core/constants/app_constants.dart:32`),**不可由使用者調整**、沒有 +對應設定頁項目。 + +**去重與寫入規則**:`saveQuery()` 先刪除同字串(`queryEqualTo`,精確比對) +的舊紀錄,再寫入新紀錄,最後只保留依時間排序後最新的 100 筆,多的整批刪除 +(`search_history_repository.dart:38-69`)。**沒有基於時間的過期機制**, +純粹是「筆數上限 + 精確字串去重」。 + +**清除規則**:`clear()` 直接清空整個 collection +(`search_history_repository.dart:32-34`);`deleteById()` 支援單筆刪除 +(`search_history_repository.dart:27-29`)。UI 呼叫點未在本次範圍內展開讀取 +(不影響儲存層行為的判定)。 + +**前綴建議查詢**:`searchByPrefix()`——查詢字串為空回最近 5 筆;非空時做 +case-insensitive contains 比對,取最近 10 筆 (`search_history_repository.dart: +72-88`),屬讀取路徑,非快取。 + +--- + +## 7. 音訊本身(播放中的暫存/快取)與下載管線的邊界 + +**播放時的串流緩衝——兩個後端策略完全不同,且都不是「磁碟快取」**: + +- **Windows(media_kit / libmpv)**:`MediaKitAudioService._configureForAudioOnly()` + 明確設定 `cache=yes`、`cache-secs=7200`(2 小時)、`demuxer-max-bytes=24MB`、 + `demuxer-max-back-bytes=8MB`、`demuxer-readahead-secs=7200` + (`lib/services/audio/media_kit_audio_service.dart:26-28, 189-240`)。 + 註解說明目的是讓 libmpv 一次性連續下載整首歌曲,避免分段請求間 TCP + 連線閒置被 CDN(尤其 YouTube)以 `WSAECONNRESET` 切斷 + (`media_kit_audio_service.dart:195-196, 214-216`)。**這是 libmpv 內部的 + 串流層記憶體緩衝**(沒有出現 `cache-dir` 或任何指向磁碟路徑的 mpv + 屬性設定,本次搜尋 `media_kit_audio_service.dart` 全文未見磁碟快取路徑 + 設定),只服務「目前這首歌從頭到尾播放一次」,並非可被下一次播放或其他 + 曲目重用的持久快取,App 重啟、切歌都不會保留。 +- **Android(just_audio / ExoPlayer)**:`lib/services/audio/ + just_audio_service.dart` 全文搜尋 `cache`/`Cache` 字串**無結果**——沒有 + 設定任何 ExoPlayer `CacheDataSource` 或自訂快取層,代表 Android 端用的是 + ExoPlayer 預設的記憶體內播放緩衝(多大、策略為何屬於 ExoPlayer 內部預設 + 值,**推測**:FMP 未覆寫,故沿用套件預設,未在 FMP 程式碼中找到任何相關 + 設定值可引用)。 + +**與下載管線(`lib/services/download/`)的邊界**:本次檢查未發現任何共用 +儲存路徑或程式碼路徑上的模糊地帶: +- 下載檔案落地在使用者可設定的下載目錄(`DownloadPathUtils.getDefaultBaseDir()`, + `lib/services/download/download_service.dart:240-243`),與圖片磁碟快取 + (`getTemporaryDirectory()`)、歌詞快取 (`getApplicationCacheDirectory()`) + 用的是不同的系統目錄類別,彼此不共用檔案或索引。 +- 播放路徑對「已下載」與「串流」是硬性二選一、非快取關係: + `resolvePrimary()` 一開始就呼叫 `_inspectLocalFiles(track)` 檢查 + `track.allDownloadPaths` 是否有實體檔案存在,若有就直接回傳 + `LocalStreamResolution`,完全跳過網路解析與上面提到的串流 URL 快取邏輯 + (`stream_resolution_service.dart:123-145, 483-`);只有下載 + (`StreamResolutionPurpose.download`) 才會反向強制不重用任何解析快取 + (`stream_resolution_service.dart:147-152`,見第 2 節)。 +- 結論:**播放緩衝(mpv 的記憶體串流快取/ExoPlayer 預設緩衝)與下載檔案 + 是兩個完全獨立的機制**,找不到共用儲存、共用清理邏輯或行為交疊的證據。 + +--- + +## 8. 離線行為 + +**偵測機制**:`ConnectivityNotifier` +(`lib/services/network/connectivity_service.dart`): +- **不是**用系統網路介面狀態,而是每隔固定間隔對三個公共 DNS 主機做 + `InternetAddress.lookup`:`dns.google`(Google)、`one.one.one.one` + (Cloudflare)、`dns.alidns.com`(阿里,對中國大陸友善),任一成功即判定 + 有網路 (`connectivity_service.dart:51-56, 99-116`)。 +- 輪詢間隔:`AppConstants.connectivityPollingInterval = Duration(seconds: + 15)` (`lib/core/constants/app_constants.dart:154`),套用於 + `Timer.periodic` (`connectivity_service.dart:72-76`)。**確認任務描述中 + 「每 15 秒 DNS 探測」的說法屬實**。 +- 單次 DNS 查詢逾時:`AppConstants.dnsTimeout = Duration(seconds: 5)` + (`app_constants.dart:157`,套用於 `connectivity_service.dart:105-107`)。 +- 狀態變化(斷網→有網)會透過 `onNetworkRecovered` 廣播事件,目前有兩個 + 訂閱者:`RankingCacheService`(立即重新整輪刷新排行榜, + `ranking_cache_service.dart:149, 217-230`)與 `audio_provider.dart:272` + (播放側網路恢復重試邏輯,本次未展開細節)。 + +**各頁面離線行為**:全域搜尋 `connectivityProvider` 的消費點,全 repo 只有 +4 處 (`ranking_cache_service.dart:149`、`network_status_banner.dart:25,79`、 +`audio_provider.dart:272`),**沒有找到任何頁面層級(首頁/搜尋/下載/電台) +針對離線狀態的專屬分支邏輯**。實際離線體驗目前完全由一個全域元件負責: + +- **全域頂部 Banner**:`NetworkStatusBanner` + (`lib/ui/widgets/feedback/network_status_banner.dart`),掛在 + `AppContentWrapper`(`lib/app.dart:180-214`),對 Windows 與 + Android 都會在每一頁上方顯示,不分頁面。`resolveNetworkStatusBannerKind()` + 只有兩種非空狀態:`noNetwork`(`!isConnected`,文案 `t.networkStatus. + noNetwork`,`network_status_banner.dart:11-20, 99-104`)與 + `playbackNetworkError`(播放中偵測到網路錯誤,額外顯示手動重試按鈕, + `network_status_banner.dart:96-98, 143-157`)。 +- **首頁 / 排行榜**:離線時不主動顯示「離線」提示,行為是「維持顯示上一次 + 成功抓到的快取資料」——`RankingCacheService` 刷新失敗時 + `state.updateSource(sourceType, error: ...)` 但**不清空** `tracksBySource` + (`ranking_cache_service.dart:259-295`,錯誤只記在 `_errorsBySource`, + 舊的 `tracks` 欄位維持不變),配合頂部全域 Banner 提示無網路。首頁本身 + 是否讀取 `errorFor()` 顯示額外文案——查不到,本次未展開讀取首頁 UI + 組件(超出核心 8 類快取/離線範圍,且不影響上述 service 層行為的判定)。 +- **搜尋頁**:沒有本地搜尋結果快取(見第 6 節,`SearchHistory` 只存查詢字 + 串本身,不存結果),離線時搜尋請求會直接透過一般網路例外處理路徑失敗; + 未找到搜尋頁專屬的離線分支(`grep connectivityProvider` 未命中 + `search_page.dart` 或 `search_provider.dart`)。 +- **播放器**:`hasPlaybackNetworkError` 只在播放過程中偵測到網路類錯誤時 + 由 `audioControllerProvider` 曝光 (`network_status_banner.dart:26-28, + 73-75`),離線時若嘗試播放**串流**曲目會經一般的串流解析失敗路徑處理 + (非本文件範圍展開的錯誤呈現細節)。 +- **已下載內容離線播放**:**確認可行**。`resolvePrimary()` 對本地檔案的 + 檢查發生在建構網路請求之前、且不受 `purpose` 以外任何連線狀態檢查阻擋 + (`stream_resolution_service.dart:123-145`)——只要 `track.allDownloadPaths` + 裡有檔案通過 `File(path).existsSync()`,就直接回傳 `LocalStreamResolution` + 播放本地檔案,全程不觸碰 `ConnectivityNotifier` 或任何網路呼叫。 +- **下載頁**:離線時發起新下載會在下載請求本身的網路層失敗(一般 + Dio/HTTP 例外),未找到下載頁專屬的「離線」提示分支(`grep + connectivityProvider` 未命中 `lib/services/download/` 或下載相關 UI 頁)。 +- **電台頁**:`RadioRefreshService.tick()` 不檢查全域連線狀態,遇到請求失敗 + 時走 `_markOffline()` 把該電台標記為未直播,屬於「請求失敗」的一般錯誤 + 處理路徑,不是「偵測到離線後跳過請求」的專屬邏輯 + (`radio_refresh_service.dart:216-227, 252-257`)。 + +**小結(查不到的部分)**:除了上述 5 個消費點與全域 Banner,本次在 +`lib/ui/pages/{home,search,download,radio}` 目錄範圍內搜尋 +`connectivityProvider`/`ConnectivityNotifier`/`isConnected` 均無命中, +判定「離線時每頁的行為」目前**沒有專屬設計**,一律退化為各自原本的網路 +請求失敗處理(多半是通用錯誤 Toast/重試,不是「離線」語意的空狀態), +加上全域頂部 Banner 提示。若需要更細的「失敗時實際顯示什麼 UI 文案」, +需要另外逐頁讀取(未在本次範圍內完成,屬於離線行為的呈現細節而非快取/ +偵測機制本身)。 + +--- + +## 附錄:本次驗證涉及的檔案清單 + +- `lib/core/services/image_loading_service.dart` +- `lib/core/services/network_image_cache_service.dart` +- `lib/main.dart`(記憶體圖片快取設定) +- `lib/ui/widgets/images/{track_thumbnail,recent_play_cover_image, + radio_cover_image,avatar_image,playlist_cover_image}.dart` +- `lib/ui/pages/settings/widgets/settings_cache.dart` +- `lib/ui/pages/settings/developer_options_page.dart` +- `lib/providers/download/download_settings_provider.dart` +- `lib/data/models/settings.dart` +- `lib/data/database/database_migration.dart` +- `lib/data/models/track.dart` +- `lib/services/audio/stream_resolution_service.dart` +- `lib/services/audio/playback_request_session.dart` +- `lib/services/audio/audio_provider.dart`(局部) +- `lib/data/sources/{bilibili_source,youtube_source,netease_source, + source_http_policy}.dart` +- `lib/services/lyrics/lyrics_cache_service.dart` +- `lib/providers/lyrics/lyrics_provider.dart` +- `lib/services/cache/ranking_cache_service.dart` +- `lib/providers/settings/{refresh_settings_provider, + home_ranking_settings_provider}.dart` +- `lib/services/radio/radio_refresh_service.dart` +- `lib/data/repositories/search_history_repository.dart` +- `lib/data/models/search_history.dart` +- `lib/services/network/connectivity_service.dart` +- `lib/ui/widgets/feedback/network_status_banner.dart` +- `lib/app.dart`(局部) +- `lib/services/audio/{just_audio_service,media_kit_audio_service}.dart` +- `lib/services/download/download_service.dart`(局部) +- `lib/core/constants/app_constants.dart` +- `lib/i18n/zh-TW/settings.i18n.json`(局部) +- `pubspec.yaml` diff --git a/.trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md b/.trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md new file mode 100644 index 000000000..1bae7cac6 --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md @@ -0,0 +1,252 @@ +# Research: 快取與離線設計 — 套件與平台客觀事實 + +- **Query**: 為「快取與離線」設計蒐集套件版本、維護狀態、平台限制與 API 事實(圖片快取、HTTP 層快取、音訊快取、平台快取目錄、網路狀態偵測) +- **Scope**: external(pub.dev / GitHub / Android 官方文件 / mpv 手冊)+ 內部(FMP `pubspec.yaml` / `pubspec.lock` 現況比對) +- **Date**: 2026-09-27 +- **查證方式**:版本號與最後發佈日期一律讀 pub.dev(用 `https://pub.dev/api/packages/` 這個 pub.dev 官方 JSON 端點,內容與 pub.dev 套件頁一致;未特別註明則來源即此端點);維護狀態讀對應 GitHub repo 的 `pushed_at` 與 open issues(GitHub REST API);套件行為讀對應版本的原始碼(GitHub raw)與官方 README;Android 系統行為讀 `developer.android.com` 與 `support.google.com`;mpv 快取行為讀 `mpv.io` 官方手冊(master)。沒有用 context7(環境未提供 context7 / tavily 工具,全部改用可直接存取的 pub.dev API、GitHub API 與官方文件頁)。本文件不含任何未查證的版本號或 API 細節;查不到的欄位明確標註「查不到」。 + +FMP 現況對照(讀自 repo 內 `pubspec.yaml` / `pubspec.lock`,非外部查證): +- `dio: ^5.11.1`(lock 內實際解析為 `5.11.1`,即目前最新版) +- `cached_network_image: ^4.0.0`(lock 內實際解析為 `4.0.0`,非目前最新的 `4.0.2`) +- `flutter_cache_manager: ^3.4.2`(lock 內實際解析為 `3.4.2`,非目前最新的 `3.4.5`) +- 安裝的 Flutter 版本:`3.47.1`(Dart `3.13.1`),高於 cached_network_image 4.0.2 要求的 `Flutter >=3.44.0` / `Dart ^3.12.0`,故理論上可升到 4.0.2 + +--- + +## Findings + +### 1. 圖片快取套件 + +#### cached_network_image + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `4.0.2` | +| 最後發佈日期 | 2026-09-23 | +| 來源 | https://pub.dev/packages/cached_network_image (資料取自 `pub.dev/api/packages/cached_network_image`) | +| GitHub repo | https://github.com/Baseflow/flutter_cached_network_image | +| repo 最後 push | 2026-09-24(`pushed_at`,GitHub API),open issues 327 個 — 近期仍有活躍 commit | + +- 4.0.2 的 `environment` 要求 `sdk: ^3.12.0`、`flutter: >=3.44.0`;依賴 `flutter_cache_manager: ^3.4.1`、`octo_image: ^2.1.0`,以及新拆出的 `cached_network_image_platform_interface`、`cached_network_image_web`。 +- **自訂 HTTP client / dio 整合**:`CachedNetworkImage` widget 建構子有 `cacheManager`(型別 `BaseCacheManager?`)參數,可傳入自訂 `CacheManager`(原始碼:`cached_network_image/lib/src/cached_image_widget.dart` 第 47-61、222-242 行,GitHub `Baseflow/flutter_cached_network_image@main`)。實際抓取行為由底層 `flutter_cache_manager` 的 `FileService` 決定(見下一節),本套件本身不直接曝露 dio 整合點,是透過傳入客製化的 `CacheManager` 間接達成。 +- **Windows / Linux 支援狀況(已知限制)**:cached_network_image 本身是純 Dart 套件,不宣告平台限制;但底層 `flutter_cache_manager` 在 Windows / Linux 上使用不同的中繼資料儲存後端(見下一節),行為與 Android/iOS/macOS 不同。GitHub 上仍有數個與 Windows 相關、狀態為 open 的 issue: + - #1023「CachedNetworkImage logs errors / crashes on Windows when image URL returns 404」(open,最後更新 2026-03-30) + - #981「Deadlock Freezes on windows if image data is invalid」(open,最後更新 2024-10-22) + - #887「CacheManager attempts to create file named guid.* on Windows」(open,最後更新 2023-11-13,檔名相關) + - #707「please add windows support」(open,最後更新 2023-09-01,仍掛著但套件目前技術上可在 Windows 執行,此 issue 較像是要求官方正式承諾支援) + (來源:`https://api.github.com/search/issues?q=repo:Baseflow/flutter_cached_network_image+windows+...`) +- **快取上限與手動清除 API**:`CachedNetworkImage` 本身不直接提供清快取方法;清除要透過底層 `CacheManager`(見下一節的 `emptyCache()` / `removeFile()`)。`CachedNetworkImage.evictFromCache(url)` 靜態方法存在,用於清除單一 URL 的快取(原始碼第 47-53 行,內部呼叫 `cacheManager.removeFile`/預設 `CachedNetworkImageProvider.defaultCacheManager`)。 + +#### flutter_cache_manager(cached_network_image 的依賴) + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `3.4.5` | +| 最後發佈日期 | 2026-09-19 | +| 來源 | https://pub.dev/packages/flutter_cache_manager | +| GitHub repo | https://github.com/Baseflow/flutter_cache_manager | +| repo 最後 push | 2026-09-23(GitHub API `pushed_at`),open issues 133 個 | + +- **儲存後端**:檔案本體一律落地檔案系統(`FileSystem` / `IOFileSystem`,實際路徑見第 4 節 `path_provider`);中繼資料(cache key、過期時間等)依平台不同: + - Android/iOS/macOS:預設用 **sqflite**(`CacheObjectProvider`) + - 其他平台(**包含 Windows、Linux**):預設用 **`JsonCacheInfoRepository`**(不是 sqlite,是 JSON 檔) + - Web:`NonStoringObjectProvider`(不落地) + 原文(`flutter_cache_manager/lib/src/config/config.dart` dartdoc,GitHub `Baseflow/flutter_cache_manager@master`): + > "On Android, iOS and macOS this defaults to `CacheObjectProvider`, a sqflite implementation due to legacy... On the other platforms this defaults to `JsonCacheInfoRepository`." + 對應實作(`_config_io.dart`): + ```dart + static CacheInfoRepository _createRepo(String key) { + if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) { + return CacheObjectProvider(databaseName: key); + } + return JsonCacheInfoRepository(databaseName: key); + } + ``` +- **上限設定方式**:`Config` 建構子的 `stalePeriod`(預設 **30 天**)與 `maxNrOfCacheObjects`(預設 **200**),原始碼同上(`_config_io.dart`)。 +- **自訂 HTTP client / dio 整合**:`FileService` 是抽象介面(`abstract class FileService { Future get(...); }`),預設實作 `HttpFileService` 用 `package:http`;原始碼 dartdoc 明確寫: + > "One can easily adapt it to use dio or any other http client." + (`flutter_cache_manager/lib/src/web/file_service.dart`)。也就是說 dio 整合需自行實作一個 `FileService`,透過 `Config(fileService: ...)` 注入,套件本身不附帶現成的 dio 版 `FileService`。 +- **手動清除 API**:`CacheManager.emptyCache()`(清整個快取)、`CacheManager.removeFile(key)`(清單一檔案)、`CacheStore.getCacheSize()`(讀目前快取大小)。(`cache_manager.dart` / `cache_store.dart`,同 repo) + +#### extended_image(替代方案) + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `10.1.0` | +| 最後發佈日期 | 2026-07-12 | +| 來源 | https://pub.dev/packages/extended_image | +| GitHub repo | https://github.com/fluttercandies/extended_image | +| repo 最後 push | 2026-07-12(GitHub API),open issues 44 個 | +| 依賴 | `extended_image_library: ^5.0.0`(實際圖片快取邏輯在此子套件) | + +- `extended_image_library` 最新版 `5.0.1`(發佈 2025-05-30,來源 `pub.dev/api/packages/extended_image_library`)。 +- **是否支援自訂 cache 策略**:查到的原始碼(`extended_image_library/lib/src/_extended_network_image_utils_io.dart`,GitHub `fluttercandies/extended_image_library@main`)顯示快取是**扁平檔案快取**,固定寫入 `getTemporaryDirectory()/`,只提供: + - `clearDiskCachedImages({Duration? duration})` — 清全部或清超過某個存活時間的檔案 + - `clearDiskCachedImage(url, {cacheKey})` — 清單一檔案 + - `getCachedSizeBytes()` — 讀快取大小 + 沒有找到等同 `flutter_cache_manager` `Config`(`stalePeriod`/`maxNrOfCacheObjects`)或 `FileService` 那種可插拔的策略介面;`httpClient` 是靜態 getter,指向 `dart:io` 的 `HttpClient`,不是可替換的抽象介面,沒有找到官方文件說明如何整合 dio。extended_image 主 repo 的 README 全文未提及 "cache" 相關章節。 + +#### Flutter 內建 `ImageCache` + +- 來源:`https://api.flutter.dev/flutter/painting/ImageCache-class.html`(Flutter 官方 API 文件) +- 原文: + > "Class for caching images. Implements a least-recently-used cache of up to 1000 images, and up to 100 MB. The maximum size can be adjusted using `maximumSize` and `maximumSizeBytes`." +- **確認為純記憶體快取**:文件與命名皆未提及落地磁碟;`ImageCache` 是 `PaintingBinding` 持有的全域單例(`imageCache` 頂層屬性),生命週期跟著 App process,**App 重啟(process 結束)即清空**,且與磁碟快取(如 `flutter_cache_manager`)是兩層互相獨立的快取。 +- 限制:預設上限 1000 張圖或 100 MB(先到者為準),可透過 `maximumSize` / `maximumSizeBytes` 調整;不提供依 URL 手動落地磁碟的機制。 + +--- + +### 2. HTTP 層快取 + +#### dio_cache_interceptor + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `4.0.7` | +| 最後發佈日期 | 2026-06-26 | +| 來源 | https://pub.dev/packages/dio_cache_interceptor | +| GitHub repo(monorepo) | https://github.com/llfbandit/dart_http_cache | +| repo 最後 push | 2026-07-10(GitHub API),open issues 僅 1 個(相對非常少) | +| dio 相容性 | `pubspec.yaml` 宣告 `dio: ^5.2.0+1`,涵蓋 FMP 目前用的 `dio 5.11.1`,**相容** | + +- **儲存後端**:`dio_cache_interceptor` 本體只含 `MemCacheStore`(純記憶體,`http_cache_core/lib/src/store/mem_cache_store.dart`)。其餘後端是同 monorepo 下的**獨立 pub 套件**: + | 套件 | 最新版 | 最後發佈 | 底層儲存 | + |---|---|---|---| + | `http_cache_file_store` | 2.0.2 | 2026-07-09 | 純檔案系統 | + | `http_cache_hive_store` | 5.1.1 | 2026-07-09 | `hive_ce` | + | `http_cache_isar_store` | 3.1.0 | 2026-05-20 | `isar_community 3.3.2`(**與 FMP 現用的 `isar_community: ^3.3.2` 同一大版本**) | + | `http_cache_drift_store` | 7.0.1 | 2026-07-09 | `drift` | + | `http_cache_sembast_store` / `http_cache_mmkv_store` / `http_cache_objectbox_store` | 各自獨立版本 | 查頁面可得,未逐一列出 | sembast/MMKV/ObjectBox | + (來源:`pub.dev/api/packages/`,逐一查詢) +- **是否適合快取 JSON API 回應**:套件描述本身即「respecting HTTP directives (or not)」。`CachePolicy` enum(`http_cache_core/lib/src/model/cache/cache_policy.dart`)提供: + - `request`:有 cache 指令才快取,沿用標準 HTTP 語意 + - `forceCache` / `refreshForceCache`:**即使來源沒有回 cache 指令也強制快取**(dartdoc:「In short, you'll save every successful GET requests.」) + - `noCache` / `refresh`:不快取或略過快取直接打來源 + 也就是說即使排行榜/搜尋結果等 API 沒有回 `Cache-Control`,也能用 `forceCache` 之類的策略強制快取,這點是查到的客觀事實。 + +(此段沒有查到「dio_cache_interceptor 是否明確測試過 dio 5.11.1」這種逐版相容性資訊,只查到 pubspec 宣告的版本區間;`^5.2.0+1` 語法保證可解析到 `5.11.1`。) + +--- + +### 3. 音訊快取 + +#### just_audio 的 `LockCachingAudioSource` + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `0.10.6` | +| 最後發佈日期 | 2026-06-29 | +| 來源 | https://pub.dev/packages/just_audio | +| GitHub repo | https://github.com/ryanheise/just_audio | +| repo 最後 push | 2026-06-29(GitHub API),open issues 345 個 | + +- **是否仍是 experimental**:查了目前(`minor` 分支,即目前開發/最新發佈分支)原始碼 `just_audio/lib/just_audio.dart` 第 3368-3373 行,`LockCachingAudioSource` 類別上方仍標註 `@experimental`,dartdoc 原文: + > "This is an experimental audio source that caches the audio while it is being downloaded and played. It is not supported on platforms that do not provide access to the file system (e.g. web)." + **結論:截至 0.10.6,`LockCachingAudioSource` 仍是 experimental API,未被扶正。** +- **支援平台(含 Windows 確認)**:`just_audio` 套件本身在 `pubspec.yaml` 的 `flutter.plugin.platforms` 只宣告了 **android、ios、macos、web** 四個平台(來源:`pub.dev/api/packages/just_audio` 的 pubspec 內容),**沒有 windows、沒有 linux**。官方 README(`ryanheise/just_audio@minor` 分支 `README.md`)明確說明: + > Windows / Linux 支援需要額外加裝第三方聯邦式套件(`just_audio_media_kit`、`just_audio_windows`、`just_audio_libwinmedia` 三選一),並提醒「For issues with the Windows implementation, please open an issue on the respective implementation's GitHub issues page.」——換句話說 Windows/Linux 上跑的其實是另一個社群套件的實作,不是 just_audio 官方原生實作,`LockCachingAudioSource` 依賴的本機 HTTP proxy 機制(README 原文:「just_audio's proxy (used to implement features such as headers, caching and stream audio sources) runs on a `localhost` HTTP server」)在 Windows/Linux 上是否等效運作**沒有查到官方文件明確保證**。 + 這與 FMP 自己 `pubspec.yaml` 註解一致:FMP 目前的架構是 **Android 用 just_audio、Windows 用 media_kit**(並未使用 `just_audio_media_kit` 這個橋接套件),因此 `LockCachingAudioSource` 在 FMP 目前架構下只會在 Android 路徑上出現。 +- **已知問題(GitHub issues,依 `updated_at` 排序,皆與 `LockCachingAudioSource` 直接相關)**: + - #1213「An Unhandled Exception is thrown when loading LockCachingAudioSource fails.」— open,最後更新 2026-09-17(非常新) + - #594「`LockCachingAudioSource` does not recover from network errors」— open,最後更新 2026-02-11 + - #1425「Player returning 0 position and duration when using LockCachingAudioSource and accept-ranges missing from response headers」— open,最後更新 2025-03-18 + - #1469「LockCachingAudioSource throws unhandled exception with cache and part files on `_fetch`」— **closed**,最後更新 2025-05-28 + (來源:`https://api.github.com/search/issues?q=repo:ryanheise/just_audio+LockCachingAudioSource+...`) + +#### media_kit(libmpv 封裝) + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `1.2.6` | +| 最後發佈日期 | 2025-12-13(距查證日 2026-09-27 已約 9.5 個月未出新版) | +| 來源 | https://pub.dev/packages/media_kit | +| GitHub repo | https://github.com/media-kit/media-kit | +| repo 最後 push | 2026-08-30(GitHub API,**repo 本身仍有近期 commit**,但尚未對應新的 pub.dev 發版),open issues 353 個 | + +- **是否有 demuxer cache/邊放邊落地到磁碟的機制**:media_kit 的 `NativePlayer`(libmpv 後端)原始碼(`media_kit/lib/src/player/native/player/real.dart` 第 2470-2471 行,GitHub `media-kit/media-kit@main`)對所有平台(註解標示 `// ALL:`,非僅 Android)硬編碼設定: + ```dart + 'cache': 'yes', + 'cache-on-disk': 'yes', + ``` + 也就是 libmpv 的網路串流確實會落地到磁碟的暫存快取檔。**但**查了 mpv 官方手冊(`https://mpv.io/manual/master/`,`--cache-on-disk` 條目)原文: + > "Write packet data to a temporary file, instead of keeping them in memory... **The cache file is deleted when playback is closed.** ... A cache file is generally worthless after the media is closed, and it's hard to retrieve any media data from it (**it's not supported by design**)." + **結論(客觀事實,非建議):media_kit/libmpv 目前啟用的磁碟快取是播放期間的暫存緩衝,關閉播放即刪除,且設計上不支援事後取出重用,不等同「下載存檔」。** + mpv 手冊另外記載 `--stream-record=`(把 demuxer 收到的原始資料寫到指定檔案,可用於網路串流,但「Switching streams or seeking during recording might result in recording being stopped and/or broken files」)與 `dump-cache ` 指令(含 `=no` 的連續傾印模式)。media_kit 的 `NativePlayer` 有公開的 `setProperty()` / `command()` 方法(`real.dart` 第 1232、1432 行),理論上可讓應用層呼叫這些 mpv 原生指令;但**這是 mpv 底層能力,media_kit 官方文件(README、pub.dev 頁)本身沒有針對「邊聽邊存」寫任何說明或封裝 API**。 +- **GitHub issue 現況(截至查證日)**: + - #269「[Enhancement] Cache Media」— **open**,2023-07-17 開出,2025-01-17 仍有人追問進度。maintainer(`alexmercerind`)在 2023-08-09 明確回覆: + > "Network caching is not present as a feature & will be likely implemented sometime in future... It will be implemented from scratch, there's no existing dedicated API." + 後續討論中(2024-04)多位使用者提到唯一可行的變通方法是**自建本機 HTTP proxy server,邊轉發邊把 bytes 寫檔**(同 just_audio `LockCachingAudioSource` 的做法),因為要在 mpv/libmpv C 原始碼層面加真正的快取功能超出專案能力範圍(maintainer 原話:「we don't really have the required skillset & time to implement it directly in C source-code of mpv」)。 + - #633「Please add completed cache file save to local storage with encrypt」— open,2024-04-02 開出,同樣尚無官方實作。 + **結論:截至查證日,media_kit 沒有官方、文件化的「播放同時落地成可重用檔案」功能,此為社群長期待實作的 enhancement request。** + +#### 兩者在「邊聽邊存」的支援程度比較(僅陳述查到的事實) + +- `just_audio`:`LockCachingAudioSource` 是官方套件內建、有公開 Dart API(`cacheFile`、`downloadProgressStream`、`clearCache()`)的功能,但標記 experimental,且只在 Android/iOS/macOS 的原生實作路徑上有文件保證;Windows/Linux 需經第三方橋接套件,官方文件未保证該功能在該路徑上等效。 +- `media_kit`:不論哪個平台,都**沒有**官方封裝的「邊聽邊存為可重用檔案」API;libmpv 有的磁碟快取機制(`cache-on-disk`)依 mpv 官方手冊明確設計為播放期暫存、關閉即刪,不支援事後取出;若要邊聽邊存,需自行在應用層實作類似 just_audio 的本機 proxy 方案,或改用 mpv 的 `--stream-record` / `dump-cache` 原生指令(media_kit 有暴露 `command()`/`setProperty()` 可呼叫,但無官方文件與封裝)。 + +--- + +### 4. 平台快取目錄 + +#### path_provider — `getApplicationCacheDirectory()` + +| 項目 | 內容 | +|---|---| +| `path_provider` 最新版 | `2.1.6`(發佈 2026-06-15),來源 https://pub.dev/packages/path_provider | +| 平台實作套件版本 | `path_provider_android 2.3.1`(2026-04-08)/`path_provider_windows 2.3.0`(2024-07-09,**已一年多沒更新**)/`path_provider_linux 2.2.2`(2026-06-24)/`path_provider_foundation 2.6.0`(2026-01-15,iOS+macOS 共用) | + +各平台實際對應的系統路徑/概念(原始碼來源:`flutter/packages` monorepo,`main` 分支,逐一列出): + +- **Android**:`path_provider_android/lib/src/path_provider_android_real.dart` 第 44-49 行,直接回傳 `context.cacheDir`(Android `Context.getCacheDir()`,即內部儲存的 App 專屬快取目錄,實體路徑概念上是 `/data/data//cache`)。註:該套件目前用 `dart:jni`(jnigen)直接呼叫 Android API,已無獨立的 Kotlin/Java 外掛程式碼目錄。 +- **iOS / macOS**(`path_provider_foundation/lib/src/path_provider_foundation_real.dart` 第 62-71 行):對應 `NSSearchPathDirectory.NSCachesDirectory`。macOS 上會額外把 App 的 bundle identifier 接在路徑後面;**iOS 則不會**(原始碼註解:「This is not done for iOS, for compatibility with older versions of the plugin.」),因為 iOS App 本身已是逐 App 沙盒。 +- **Windows**(`path_provider_windows/lib/src/path_provider_windows_real.dart` 第 124-126、243-259 行):對應 `WindowsKnownFolder.LocalAppData`(即 `%LOCALAPPDATA%`)底下再接一層由執行檔 VERSIONINFO 資源讀出的 `\` 子目錄。**沒有額外的「Cache」字面子資料夾**——即 ApplicationCache 與 ApplicationSupport 用的是同一套 `\` 命名規則,差別只在於前者掛在 `LocalAppData`(不隨帳號漫遊)、後者掛在 `RoamingAppData`(`%APPDATA%`)。 +- **Linux**(`path_provider_linux/lib/src/path_provider_linux.dart` 第 70-88 行):對應 `xdg.cacheHome`(即 XDG Base Directory 規範的 `$XDG_CACHE_HOME`,未設定時預設 `~/.cache`)底下的 `` 子目錄;若該目錄不存在,會 fallback 嘗試以執行檔名稱為子目錄名(原始碼註解引用了一個相容性問題 `flutter/flutter#186834`)。 + +#### Android 系統對快取目錄的自動清除行為(官方文件) + +- 來源:`https://developer.android.com/training/data-storage/app-specific`(Android 官方開發者文件,「Create cache files」「Remove cache files」章節) +- 原文(節錄): + > "Caution: When the device is low on internal storage space, Android may delete these cache files to recover space. So check for the existence of your cache files before reading them." + > "Even though Android sometimes deletes cache files on its own, you shouldn't rely on the system to clean up these files for you. You should always maintain your app's cache files within internal storage." + **結論:Android 系統在裝置儲存空間不足時「可能」(而非保證、也無固定時機)自動清除 App 的快取目錄內容,官方明確建議 App 自己做存在性檢查與清理,不要依賴系統。** +- **使用者手動清除 App 快取**:來源 `https://support.google.com/android/answer/7431795`(Google 官方支援頁,Android 設定 App 管理頁面說明),原文: + > "Clear cache: Deletes temporary data. Some apps may be slow the next time you open them." + 即使用者可在系統設定的「應用程式資訊」頁面對單一 App 執行「清除快取」,此動作會清掉 `getCacheDir()`/`getExternalCacheDir()` 底下的內容(該頁面未逐一列出實作細節,此為官方對使用者的行為描述,非開發者 API 文件)。 + +#### Windows/Linux 的系統層級自動清快取機制 + +- **查不到** Windows 官方文件(`learn.microsoft.com`)中有任何作業系統層級「自動清除 `%LOCALAPPDATA%` 底下任意程式子目錄」的機制說明;本次查證只確認了 `path_provider_windows` 如何決定路徑(見上),沒有查到 Windows 系統本身會主動清除該路徑內容的官方陳述。 +- **查不到** Linux 發行版或 XDG 規範中有「系統自動清除 `$XDG_CACHE_HOME` 內容」的通用機制說明;XDG Base Directory 規範本身只定義路徑慣例,未查到規範文字承諾自動清除行為。 +- 因此本題目前的查證結果是:**沒有找到 Windows/Linux 官方文件證實存在系統層級自動清快取機制**(這不等於「確定不存在」,只是查證範圍內沒有找到相關官方陳述),與 Android 有明確官方文件記載的行為形成對比。 + +--- + +### 5. 網路狀態偵測 + +#### connectivity_plus + +| 項目 | 內容 | +|---|---| +| 最新穩定版 | `7.3.1` | +| 最後發佈日期 | 2026-07-23 | +| 來源 | https://pub.dev/packages/connectivity_plus | +| GitHub repo | https://github.com/fluttercommunity/plus_plugins(monorepo,`connectivity_plus` 只是其中一個子套件) | +| repo 最後 push | 2026-09-26(GitHub API,非常新),open issues 109 個(monorepo 全部子套件合計) | +| 支援平台 | README 平台表格列出 **Android、iOS、macOS、Web、Linux、Windows 全部打勾**(來源:`plus_plugins/packages/connectivity_plus/connectivity_plus/README.md`,`main` 分支) | + +- **官方明確警語**(README 開頭 Note 區塊,原文): + > "You should not rely on the current connectivity status to decide whether you can reliably make a network request. Always guard your app code against timeouts and errors that might come from the network layer. Connection type availability does not guarantee that there is an Internet access. For example, the plugin might return Wi-Fi connection type, but it might be a connection with no Internet access due to network requirements (like on hotel Wi-Fi networks where user often needs to go through a captive portal to authorize first)." + **結論:官方文件本身就明講「偵測到網路介面連上不代表真的能上網」,並直接建議用「請求本身要處理逾時與錯誤」而不是依賴連線狀態來判斷是否離線** —— 也就是查到了任務描述裡預期的那種警語與建議搭配用法,來源是套件自己的 README,不是第三方推論。 +- 其餘平台特定備註(同 README):Android 上「同時開行動網路和 Wi-Fi 時,系統只會回報 Wi-Fi」;iOS/macOS 上沒有獨立的 VPN 介面類型,VPN 連線會回報成 `other`。 +- 版本需求(README「Requirements」章節):Flutter >=3.19.0、Dart >=3.3.0 <4.0.0、iOS >=13.0、macOS >=10.15、Java 17、AGP >=8.12.1、Gradle wrapper >=8.13、Xcode >=26.1.1。 + +--- + +## Caveats / 查不到 + +- 沒有用到 context7 或 tavily:本次執行環境沒有掛載這兩個工具,改用 pub.dev 官方 JSON API、GitHub REST API 與各官方文件頁直接查證,資料來源與官方頁面內容一致(pub.dev API 就是 pub.dev 頁面的資料來源)。 +- **dio_cache_interceptor 與 dio 5.11.1 的逐版相容性**:只查到 pubspec 宣告的版本區間(`^5.2.0+1`,涵蓋 5.11.1),沒有查到官方是否針對 5.11.x 做過專門測試或已知問題列表。 +- **cached_network_image / extended_image 是否有「已知平台限制」的官方聲明文件**(例如 pub.dev 頁面的 Platform 支援表格細節):本次用 GitHub issue 搜尋佐證 Windows 上仍有已知 bug(見上),但沒有找到官方 README 或文件明確列出「不支援某平台」的正式聲明;cached_network_image/flutter_cache_manager 的 pub.dev pubspec 都沒有宣告 `flutter.plugin.platforms` 限制(純 Dart 套件,理論上全平台可跑),實際限制來自底層儲存後端行為(已於上文列出)。 +- **Windows/Linux 系統層級自動清快取機制**:查不到官方文件證實存在(見第 4 節說明),非「確認不存在」,只是本次查證範圍內沒有找到來源。 +- **media_kit `command()`/`setProperty()` 呼叫 `stream-record`/`dump-cache` 在 Flutter/Dart 層的官方封裝或範例**:查不到;只確認了這兩個方法存在且為 public API,以及 mpv 手冊對這兩個原生指令的行為說明,沒有查到 media_kit 官方或社群提供的 Dart 範例程式碼。 +- **`http_cache_sembast_store` / `http_cache_mmkv_store` / `http_cache_objectbox_store` 的確切版本號與發佈日期**:已確認存在於同一 monorepo,但本次沒有逐一查詢它們的 pub.dev 頁面(時間關係只深入查了 `file_store`/`hive_store`/`isar_store`/`drift_store` 四個較常見的後端)。 diff --git a/.trellis/tasks/09-27-design-cache-offline/research/prior-art.md b/.trellis/tasks/09-27-design-cache-offline/research/prior-art.md new file mode 100644 index 000000000..1981cdff7 --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/research/prior-art.md @@ -0,0 +1,365 @@ +# Research: 快取與離線策略 — 同類開源專案 Prior Art + +- **Query**: FMP(Flutter 音樂播放器,串流 Bilibili / YouTube / NetEase)重寫時的快取與離線策略設計,需要參考同類專案在:串流網址過期處理(YouTube `expire`/Bilibili `deadline` 類參數)、圖片快取上限與清理、漸進式音訊快取、離線模式(自動/手動、功能可用性、已下載曲目辨識)、可調整設定 六個面向的實作方式。 +- **Scope**: external(開源專案原始碼閱讀) +- **Date**: 2026-09-27 +- **驗證方法**: 本機以 `git clone --depth 1` 取得下列專案原始碼後直接閱讀原始碼與設定檔逐行驗證;未使用 web search 工具(環境中未提供),亦未憑訓練記憶臆測版本相關細節。每個結論均附帶以下對應 commit SHA 建立的 GitHub permalink: + + | 專案 | Repo | HEAD SHA(複製當下) | + |---|---|---| + | Spotube | `team-spotube/spotube` | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | + | Namida | `namidaco/namida` | `e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5` | + | Finamp | `jmshrv/finamp` | `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc` | + | NewPipe | `TeamNewPipe/NewPipe` | `7e5df38aad4b2c035332b3f71aee3064d4fdaae4` | + | NewPipeExtractor | `TeamNewPipe/NewPipeExtractor` | `4818304b90fc9b6a3497d7e40b43aedb9a3f7074` | + | MusicFree | `maotoumao/MusicFree` | `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee` | + + 找不到或無法確認的項目一律明確標註「查不到」並附上已嘗試的搜尋方式,不依記憶猜測。 + +--- + +## Findings + +### Spotube(`team-spotube/spotube`) + +架構:Flutter,播放走內建 `shelf` HTTP server 代理(見 `lib/provider/server/routes/playback.dart`),前端一律向本機 server 要串流。 + +- **快取分類與 TTL**: + - 音訊快取:以 track 為單位寫入磁碟檔案(見下)。目錄由 `getMusicCacheDir()` 依平台決定: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/user_preferences/user_preferences_provider.dart#L97-L113 + - 圖片快取:透過 `cached_network_image` + `flutter_cache_manager`(`pubspec.yaml` 依賴,未見任何自訂 `CacheManager`/`Config`): + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/pubspec.yaml#L24-L52 + 實際使用處為 `CachedNetworkImageProvider`,沒有覆寫 TTL 或容量: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/components/image/universal_image.dart#L33-L52 + - 未見獨立的「metadata TTL」快取層(除歌詞、`sourceMatchTable` 之外,見下)。 + - **查不到**:`flutter_cache_manager` 的預設 `stalePeriod`/`maxNrOfCacheObjects` 是否被 Spotube 用某個全域設定覆寫——已在整個 repo 搜尋 `CacheManager(` 建構呼叫,僅找到 `flutter_cache_manager` 套件本身;判定 Spotube 對圖片使用套件預設值。 + +- **串流網址過期處理**:**純被動重試(reactive)**。播放代理先對串流網址發 `HEAD` 請求探測,若失敗則呼叫 `refreshStreamingUrl()` 重新解析來源並重試: + ```dart + ).catchError((e, stack) async { + final sourcedTrack = await ref.read(sourcedTrackProvider(track.query).notifier).refreshStreamingUrl(); + url = sourcedTrack.url!; + return dio.head(url, options: options); + }); + ``` + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/server/routes/playback.dart#L177-L191 + 未見任何對 URL 內 `expire`/`deadline` 等參數的主動解析或預先判斷過期時間的邏輯——策略完全依賴「用了才知道」。 + +- **圖片快取上限與清理**:無自動清理/無容量上限程式碼;僅提供手動「Clear Cache」按鈕(顯示資料夾目前大小): + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/library/user_local_tracks/local_folder.dart#L150-L250 + +- **漸進式音訊快取**:**存在**,且與「明確下載」是分開機制。播放代理在串流的同時,若 `userPreferences.cacheMusic` 為真,會把位元組寫入 `.part`,完成後改名為正式快取檔;下次播放時若快取檔存在則直接讀本機檔案、完全略過網路: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/server/routes/playback.dart#L89-L92 + (讀取快取)與 + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/server/routes/playback.dart#L217-L265 + (寫入 `.part` 再 rename)。未見容量上限設定——快取會無限增長直到使用者手動清除。 + +- **離線模式**:**沒有明確的「離線模式」開關或狀態**,而是靠一個獨立的 `ConnectionCheckerService` 持續偵測連線(含 VPN 介面偵測、對 `google.com`/`www.baidu.com` 做 DNS 探測、斷線時每 30 秒輪詢): + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L24-L111 + 斷線時的行為僅止於暫停播放並跳 toast 通知,**未見任何功能因離線而被停用/隱藏**: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/root/use_global_subscriptions.dart#L30-L115 + 已下載/已快取曲目的辨識:`local_tracks_provider.dart` 把「明確下載目錄」「音訊快取目錄」「使用者本機音樂庫目錄」三者掃描結果合併為同一份「本機曲目」清單,未見對播放優先序做特殊標記: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/local_tracks/local_tracks_provider.dart#L1-L90 + +- **使用者可調整設定**:僅「Cache Music」開關(是否啟用漸進式音訊快取)+「開啟快取資料夾」連結: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/settings/sections/playback.dart#L130-L165 + 另有獨立的「明確下載」功能(`DownloadTask`/`DownloadManagerNotifier`),與上述漸進快取為兩套機制: + https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/download_manager_provider.dart#L1-L80 + +--- + +### Namida(`namidaco/namida`) + +架構:Flutter,內建 `MusicWebServer` 自架 HTTP 伺服器橋接 YouTube 串流與播放器;同時支援訂閱「伺服器」音樂來源。是五個專案中快取子系統最完整、參數最豐富的一個。 + +- **快取分類與 TTL(有精確容量上限,非 TTL 制)**:`SettingsController` 定義四個獨立容量上限(單位 MB),各自對應一種快取類別: + ```dart + final videosMaxCacheInMB = (8 * 1024).obs; // 8GB + final audiosMaxCacheInMB = (4 * 1024).obs; // 4GB + final serversMaxCacheInMB = (4 * 1024).obs; // 4GB + final imagesMaxCacheInMB = (8 * 32).obs; // 256 MB + ``` + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/settings_controller.dart#L183-L186 + 另提供「精簡」(影片/音訊/伺服器快取皆關閉,圖片 2GB)與「積極」(24GB/12GB/12GB/2GB)兩組預設組合: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/settings_controller.dart#L405-L461 + 圖片快取內部再依 90%/10% 比例切分「影片縮圖」與「頻道圖片」兩個子預算(見 `storage_cache_manager.dart` 的 `_ImageTrimmer`)。 + +- **串流網址過期處理**:**主動 TTL 檢查 + 被動重試併存**。播放前呼叫 `hasExpired()` 判斷快取的串流結果是否過期,過期則強制重新請求: + ```dart + final bool expired = mainStreams?.hasExpired() ?? true; + ``` + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L1197 + (另見 L1335、L1521、L1938 同一模式重複出現) + 過期或播放失敗時會呼叫 `fetchVideoStreams(videoId)` 重新取流: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L1284 + 字幕/CC 檔另有自己的過期防護,註解直接說明原因: + > "caption urls expire after a few hours, so the fetched file is kept around" + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/class/subtitle_track.dart#L150-L181 + **查不到**:`hasExpired()` 內部究竟是解析 YouTube 串流網址中的 `expire` 參數、還是純粹用固定 TTL 判斷——此邏輯實作於外部套件 `namidaco/youtipie`,但該 repo 無法存取(`git clone` 回傳 "Repository not found",`gh api repos/namidaco/youtipie` 回傳 404,`gh api "search/repositories?q=youtipie"` 亦回傳 0 筆結果),判定為私有或已下架,僅能確認 App 端「呼叫端會先查過期再決定要不要重打」這個介面行為,內部判斷方式查不到。 + +- **圖片快取上限與清理**:`imagesMaxCacheInMB` 控制總量,清理由共用的 `_Trimmer`/`_ImageTrimmer` 類別執行,依「存取時間(`stat.accessed`)由舊到新」的 LRU 順序刪除,並排除標記為 `isKept`(VIP/釘選)與正在下載中的檔案: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/storage_cache_manager.dart#L1-L990 + 觸發時機:App 啟動(`_secondaryAppInitialization`)、每 30 分鐘一次的 `Timer.periodic`(但受 24 小時的 `_timeAwareRecheckInterval` 節流)、以及 App 回到前景: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L320-L360 + +- **漸進式音訊快取**:**存在**,由 `ServerCacheController` 負責,最多 3 個並行下載工,每 100ms 更新一次進度: + ```dart + static const _kMaxParallelDownloads = 3; + static const _kProgressUpdateIntervalMs = 100; + ``` + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/music_web_server/server_cache_controller.dart#L8-L9 + 容量超過 `serversMaxCacheInMB`/`audiosMaxCacheInMB` 時由 `trimExcessCache()` 觸發同一套 LRU+VIP 排除邏輯清理: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/music_web_server/server_cache_controller.dart#L203 + +- **離線模式**:**無獨立「離線模式」開關**,而是逐檔在播放時判斷「本機是否已有可用快取/下載檔」。核心邏輯:若快取檔存在,且(該檔被標記為 `isKept()`,即使用者釘選保留 **或** 檔案大小與伺服器記錄相符),就直接用本機檔案播放,完全不連網;否則刪除失效快取後才回退連網: + ```dart + if (ServerCacheController.inst.isKept(tr) || await cacheFile.fileSize() == tr.size) { + onFetched(cacheFile); + return AudioVideoSource.file(cacheFile.path); + } else { + await cacheFile.tryDeleting(); + } + ``` + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L3050-L3057 + 另有獨立的 `isAvailableOffline(videoId)`,同時查「音訊快取表」與「本機曲庫索引」兩個來源: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/audio_cache_controller.dart#L1-L45 + 以及一個手動限定「只搜尋已快取/已下載內容」的 Offline Search 功能: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/pages/yt_local_search_results.dart#L1-L70 + 連線偵測(`connectivity.dart`)額外區分 `hasConnection`/`hasHighConnection` 兩級,後者用於驅動「省流量模式」: + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/connectivity.dart#L1-L130 + +- **使用者可調整設定**:四個容量上限皆有對應的滑桿 UI(影片/音訊/伺服器/圖片快取各自可調): + https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/ui/widgets/settings/advanced_settings.dart#L540-L568 + +--- + +### Finamp(`jmshrv/finamp`) + +架構:Flutter,對接 Jellyfin 伺服器(非簽章網址、無到期時間概念的認證模型)。1.0 版做過一次下載子系統大改(Hive→Isar、`flutter_downloader`→`background_downloader`),動機記錄於: +https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/DOWNLOADS_PLAN.md + +- **快取分類與 TTL**:Finamp 是五者中唯一**沒有隱式/漸進式音訊快取**的專案——已針對 `lib/services/` 全目錄以 `cache`/`Cache` 關鍵字搜尋,僅發現「明確下載」(`DownloadStub`/Isar 持久化)與圖片快取(`DefaultCacheManager()`,未覆寫任何設定)兩種: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/album_image_provider.dart#L72 + **查不到**:`DefaultCacheManager()` 的實際 disk 容量上限——Finamp 未覆寫 `flutter_cache_manager` 預設 `Config`,故沿用套件本身預設值(套件原始碼未在本次研究範圍內深入)。 + +- **串流網址過期處理**:**結構性不適用**。Jellyfin 的媒體串流網址走伺服器端 API Key 驗證,不含如 YouTube `expire`/Bilibili `deadline` 的簽章到期參數;`jellyfin_api_helper.dart` 中對 401 的處理僅用於「登出/重新登入」情境,並非串流網址到期重試: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/jellyfin_api_helper.dart#L1070-L1105 + +- **圖片快取上限與清理**:未見任何自動清理或容量上限程式碼(沿用 `flutter_cache_manager` 套件預設值,同上)。 + +- **漸進式音訊快取**:**不存在**。所有離線可播放內容都必須經過使用者明確觸發的「下載」流程,沒有「邊播邊存」機制。 + +- **離線模式**:**自動+手動並存,且有明確的四態自動化列舉**: + ```dart + enum AutoOfflineOption { + disabled, + network, + disconnected, + unreachable, + } + ``` + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L3125-L3131 + 四態的精確定義(取自英文語系檔):`network` = 沒連上 WiFi/有線網路時自動開啟離線模式;`disconnected` = 完全沒有任何網路連線時開啟;`unreachable` = 切換網路後 ping 不到伺服器時開啟: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/l10n/app_en.arb#L2208-L2218 + 使用者也可以手動切換離線模式開關,此舉會**暫停自動化直到重新啟用**("pauses the automation until you reenable it"): + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/l10n/app_en.arb#L2224 + 對應的手動開關 UI 元件: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/components/MusicScreen/offline_mode_switch_list_tile.dart#L12 + **功能可用性**:離線時多處明確停用需要伺服器運算的功能,例如首頁改顯示「未下載/離線模式下不可用」訊息而非嘗試連網: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/components/HomeScreen/home_screen_content.dart#L298-L343 + 「Instant Mix」(伺服器端生成的接續播放清單)離線時停用: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/components/MusicScreen/music_screen_tab_view.dart#L344 + 「Most Played」等需伺服器統計資料的篩選器離線時停用: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/components/curated_item_filter_row.dart#L20-L26 + 離線期間的播放記錄改寫入本機 Hive box + JSON-lines 檔案,供之後同步或手動分享匯出,而非即時上報伺服器: + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/offline_listen_helper.dart#L16-L94 + 已下載曲目的辨識:透過 Isar 持久化的 `DownloadStub` 記錄判斷,`queue_service.dart` 多處以 `isOffline` 旗標門控電台/Instant Mix 等需連網功能,未見「下載優先於串流」的排序邏輯(因為沒有漸進快取可比較,下載是唯一的本機來源)。 + +- **使用者可調整設定**:`downloads_settings_screen.dart` 提供一組完整的下載相關設定(皆為明確下載範疇,非漸進快取):`RequireWifiSwitch`(僅 WiFi 下載) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L107 + `SyncFavoritesSwitch`(收藏自動同步下載) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L120 + `SyncOnStartupSwitch` + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L154 + `ConcurentDownloadsSelector`(併發下載數,1-25 滑桿) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L181 + `DownloadWorkersSelector`(下載執行緒數,1-5 滑桿) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L223 + `DownloadSizeWarningCutoffTile`(超過此 MB 數時跳出下載體積警告,數值輸入框) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L284 + 以及前述的四態自動離線模式選單。 + +--- + +### NewPipe(`TeamNewPipe/NewPipe` + `TeamNewPipe/NewPipeExtractor`) + +架構:Android 原生(Java/Kotlin),抽取邏輯獨立於 `NewPipeExtractor` 函式庫,播放走 ExoPlayer,圖片走 Coil。是唯一非 Flutter 的參考對象。 + +- **快取分類與 TTL(固定 TTL 制,非解析網址參數)**:核心是一個記憶體內 `LruCache`(`InfoCache`),容量上限 60 筆、超量清到 30 筆: + ```java + private static final int MAX_ITEMS_ON_CACHE = 60; + private static final int TRIM_CACHE_TO = 30; + ``` + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/InfoCache.java#L38-L44 + 每筆項目的過期時間由 `ServiceHelper.getCacheExpirationMillis()` 依服務決定,是**寫死的固定時長**,非解析串流網址內任何到期參數: + ```kotlin + fun getCacheExpirationMillis(serviceId: Int): Long { + return if (serviceId == ServiceList.SoundCloud.serviceId) { + TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES) + } else { + TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS) + } + } + ``` + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/ServiceHelper.kt#L138-L144 + 即 YouTube 固定 1 小時、SoundCloud 固定 5 分鐘,與 YouTube 串流網址本身的 `expire` 參數無關。已在 `NewPipeExtractor/extractor/src/main` 全目錄搜尋關鍵字 "expire",**零筆命中**,可確認抽取器本身完全不解析網址內的到期參數。 + +- **串流網址過期處理**:**播放走固定 TTL、下載走被動重試(403 觸發)——兩套獨立機制**。 + 播放端:ExoPlayer 的媒體來源包裝物件持有與 `InfoCache` 相同語意的 `expireTimestamp`,過期後才允許被替換: + ```java + private boolean isExpired() { + return System.currentTimeMillis() >= expireTimestamp; + } + ``` + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java#L44-L58 + 下載端:偵測到 HTTP 403 時視為「網址已過期」,觸發 `doRecover()` 重新取流,三處下載執行緒(一般/回退路徑/初始化)皆用同一常數判斷: + ```java + if (e instanceof HttpError && ((HttpError) e).statusCode == ERROR_HTTP_FORBIDDEN) { + mMission.doRecover(ERROR_HTTP_FORBIDDEN); + ``` + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/DownloadRunnable.java#L133-L139 + 另見 + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/DownloadRunnableFallback.java#L116-L119 + 與 + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java#L178-L181 + +- **圖片快取上限與清理**:圖片走 Coil 的 `SingletonImageLoader`,**未見任何自訂容量設定**(沿用 Coil 預設值);使用者變更「圖片畫質」偏好時,程式會主動清空 Coil 的記憶體與磁碟快取: + ```java + loader.getMemoryCache().clear(); + loader.getDiskCache().clear(); + ``` + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java#L71-L83 + 另有手動「清除中繼資料快取」設定項,直接呼叫 `InfoCache.getInstance().clearCache()`: + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java#L61-L63 + +- **漸進式音訊快取**:**不存在**。NewPipe 僅有「明確下載」(`DownloadMission`/`us.shandian.giga.get`),沒有邊播邊存的隱式快取層。 + +- **離線模式**:**沒有應用層級的「離線模式」概念**,也沒有針對離線的功能停用/降級邏輯——NewPipe 定位為串流優先的用戶端,已下載的影片/音訊僅能透過各自的下載清單頁面存取,不會被優先匹配進正常瀏覽/搜尋流程。 + +- **使用者可調整設定**:圖片畫質偏好(連帶觸發快取清空)、手動清除中繼資料快取兩項,皆為前述已列出的 preference 項目;對應 UI 文案: + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/values/strings.xml#L105-L108 + +--- + +### MusicFree(`maotoumao/MusicFree`) + +架構:React Native,播放邏輯集中於 `RNTrackPlayer`,來源解析走「外掛(plugin)」模式——每個外掛實作 `getMediaSource(musicItem, quality)`,與 FMP 自身的 source-adapter 架構在概念上相近。 + +- **快取分類與 TTL**: + - Metadata 快取(`MediaCache`):MMKV 儲存,容量上限 800 筆,超量時做「刪掉一半」的清理(程式碼自己標註為臨時方案): + ```ts + // 最多缓存800条数据 + const maxCacheCount = 800; + ... + // TODO: 随机删一半 + for (let i = 0; i < maxCacheCount / 2; ++i) { ... } + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/mediaCache.ts#L10-L41 + - 音訊快取:委派給原生播放器本身(見下)。 + - 圖片:`react-native-fast-image`(`package.json` 依賴),未見自訂容量設定。 + - **查不到**:MMKV `MediaCache` 是否有依時間的 TTL 過期機制——已讀完整份 `mediaCache.ts`(84 行),僅有容量上限與「刪一半」清理,未見任何時間戳比對邏輯,判定沒有 TTL,僅有容量驅逐。 + +- **串流網址過期處理**:**結構性迴避——每次播放都重新呼叫外掛解析,並由外掛自行宣告快取策略**。核心是外掛可選擇性宣告的 `cacheControl` 欄位,對應列舉: + ```ts + export const CacheControl = { + Cache: "cache", + NoCache: "no-cache", + NoStore: "no-store", + }; + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/constants/commonConst.ts#L44-L48 + `getMediaSource()` 依此欄位決定是否重用上次解析出的網址:`Cache` = 一律重用已快取網址;`NoCache` = 僅離線時退回使用快取網址,其餘一律重新解析;未宣告時預設 `no-cache`: + ```ts + const pluginCacheControl = this.plugin.instance.cacheControl ?? "no-cache"; + if (mediaCache && mediaCache?.source?.[quality]?.url && + (pluginCacheControl === CacheControl.Cache || + (pluginCacheControl === CacheControl.NoCache && Network.isOffline))) { + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/pluginManager/plugin.ts#L225-L243 + 若外掛宣告 `NoStore`,新解析出的網址則完全不寫回快取: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/pluginManager/plugin.ts#L292 + 由於解析網址這件事本身被下放給各外掛,MusicFree 核心完全不需要知道任何特定平台的 `expire`/`deadline` 參數語意。 + +- **圖片快取上限與清理**:設定頁提供「清除圖片快取」按鈕(顯示目前佔用大小),屬手動觸發,未見自動清理: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/basicSetting.tsx#L498-L509 + 另有對應的「清除音樂快取」「清除歌詞快取」按鈕: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/basicSetting.tsx#L471-L490 + +- **漸進式音訊快取**:**存在,但完全委派給原生播放器**,應用層僅在啟動時傳入一個容量上限給 `RNTrackPlayer.setupPlayer()`,預設 512MB: + ```ts + await RNTrackPlayer.setupPlayer({ + maxCacheSize: Config.getConfig("basic.maxCacheSize") ?? 1024 * 1024 * 512, + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/entry/bootstrap/bootstrap.ts#L152-L154 + 此上限可在設定頁調整(100MB-8GB 區間,UI 顯示已格式化大小): + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/basicSetting.tsx#L118 + +- **離線模式**:**沒有獨立的「離線模式」開關,完全自動判斷**。`Network` 是一個基於 `@react-native-community/netinfo` 的單例,區分 `Offline`/`Wifi`/`Cellular` 三態,全自動更新,無手動覆寫入口: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/utils/network.ts#L1-L61 + 行動網路下的播放限制:若目前是行動網路、使用者未開啟「行動網路可播放」設定、且該曲目「不是本機音樂」且「沒有本機路徑」,則直接擋下播放: + ```ts + const localPath = getLocalPath(musicItem); + if (Network.isCellular && + !this.configService.getConfig("basic.useCelluarNetworkPlay") && + !LocalMusicSheet.isLocalMusic(musicItem) && + !localPath) { + await ReactNativeTrackPlayer.reset(); + throw new Error(PlayFailReason.FORBID_CELLUAR_NETWORK_PLAY); + } + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/trackPlayer/index.ts#L405-L418 + **已下載曲目的辨識與優先播放**:`getLocalPath()` 依序檢查(1)曲目網址本身是否為 `file://`/`content://` 開頭、(2)舊版序列化欄位中的 `localPath`、(3)附加資訊(media extra)中的 `localPath`: + ```ts + export function getLocalPath(mediaItem: ICommon.IMediaBase) { + if (mediaItem.url && (mediaItem.url.startsWith("file://") || mediaItem.url.startsWith("content://"))) { + return mediaItem.url; + } + const legacyLocalPath = mediaItem?.[internalSerializeKey]?.localPath; + if (legacyLocalPath && typeof legacyLocalPath === "string") { + return legacyLocalPath; + } + const localPathInMediaExtra = getMediaExtraProperty(mediaItem, "localPath"); + return localPathInMediaExtra ?? null; + } + ``` + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/utils/mediaUtils.ts#L89-L109 + 此檢查在 `getMediaSource()` 的**最開頭**(優先於 metadata 快取查詢、優先於呼叫任何外掛解析)就執行——只要找到本機路徑即直接回傳,完全跳過外掛解析流程: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/pluginManager/plugin.ts#L200-L217 + 即:本機/已下載曲目在架構上具有最高優先序,且此優先序判斷與快取策略(`cacheControl`)完全獨立。 + +- **使用者可調整設定**:「音樂快取上限」(100MB-8GB 滑桿/選項)、「清除音樂快取」「清除歌詞快取」「清除圖片快取」三個獨立按鈕、「行動網路下可播放」「行動網路下可下載」兩個獨立開關: + https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/setting/settingTypes/basicSetting.tsx#L400-L510 + +--- + +## 對照表(僅列事實,不含建議) + +| 面向 | Spotube | Namida | Finamp | NewPipe | MusicFree | +|---|---|---|---|---|---| +| 技術棧 | Flutter | Flutter | Flutter | Android 原生 (Java/Kotlin) | React Native | +| 圖片快取上限 | 套件預設(未覆寫) | 可調(預設 256MB,含 90/10 子分配) | 套件預設(未覆寫) | 套件預設(未覆寫),畫質變更時全清 | 未見容量上限,僅手動清除按鈕 | +| 串流網址過期策略 | 純被動:HEAD 探測失敗才重新解析 | 主動 `hasExpired()` 檢查 + 過期/失敗雙重觸發重新取流 | 不適用(Jellyfin 無簽章到期網址) | 播放走固定 TTL(YouTube 1hr/SoundCloud 5min);下載走被動 HTTP 403 觸發重試 | 每次播放重新呼叫外掛解析;外掛可用 `cacheControl`(`cache`/`no-cache`/`no-store`)宣告是否重用網址 | +| 是否解析網址內 `expire`/`deadline` 參數 | 查不到(未見相關程式碼) | 查不到(判斷邏輯在無法存取的外部套件 `youtipie` 內) | 不適用 | 否,確認為固定 TTL(已對 extractor 原始碼搜尋 "expire" 零命中) | 不適用(不持久判斷單一網址壽命,改用外掛宣告的策略) | +| 漸進式(隱式)音訊快取 | 有,無容量上限,需手動清除 | 有,`serversMaxCacheInMB`/`audiosMaxCacheInMB` 可調並自動 LRU 清理 | 無(僅明確下載) | 無(僅明確下載) | 有,容量委派給原生播放器(預設 512MB,可調) | +| 離線模式切換 | 無獨立模式,僅連線偵測+暫停播放 | 無獨立模式開關,逐曲目判斷本機檔案可用性 | 有:4 態自動化列舉(`disabled`/`network`/`disconnected`/`unreachable`)+ 手動開關(手動會暫停自動化) | 無離線模式概念 | 無獨立模式,全自動依 `Network` 單例狀態判斷 | +| 離線時功能停用 | 未見(僅暫停播放) | 未見整頁功能停用,僅提供「離線搜尋」限定範圍搜尋 | 有:首頁部分區塊、Instant Mix、Most Played 等伺服器運算功能明確停用 | 不適用(無離線模式) | 有:行動網路(非離線)下非本機曲目被擋下播放,需開關放行 | +| 已下載/本機曲目辨識機制 | 三個目錄(下載/快取/本機庫)合併掃描,無特殊優先標記 | 檢查快取檔存在 + (`isKept()` 或檔案大小相符) 才視為可離線播放本機檔 | Isar 持久化 `DownloadStub` 記錄 | 各自獨立的下載清單,不併入一般瀏覽/搜尋 | `getLocalPath()` 檢查 URL scheme/legacy 欄位/media extra,且在 `getMediaSource()` 最前面短路,優先於外掛解析與 metadata 快取 | +| 代表性使用者可調快取設定 | 「Cache Music」開關 + 開啟快取資料夾 | 4 組獨立容量滑桿(影片/音訊/伺服器/圖片)+ 精簡/積極預設組合 | 下載相關:僅 WiFi 下載、收藏自動同步、併發數(1-25)、執行緒數(1-5)、體積警告門檻、4 態自動離線模式 | 圖片畫質偏好(連動清快取)、手動清中繼資料快取 | 音樂快取容量(100MB-8GB)、三個獨立清快取按鈕、行動網路播放/下載開關 | + +## Caveats / Not Found + +- Namida:`hasExpired()` 的內部判斷方式(是否解析 YouTube 串流網址參數、或使用固定 TTL)——實作於外部套件 `namidaco/youtipie`,該 repo 目前無法存取(clone 404,`gh api repos/namidaco/youtipie` 404,`gh api search/repositories?q=youtipie` 0 筆),僅能從呼叫端行為推斷「有主動過期檢查」這一事實,內部機制查不到。 +- Spotube:`flutter_cache_manager` 圖片快取的實際 `stalePeriod`/`maxNrOfCacheObjects` 數值——Spotube 未覆寫套件設定,本次研究未深入套件本身原始碼確認其確切預設值。 +- Finamp:`DefaultCacheManager()` 的圖片快取實際容量上限——同上,未覆寫預設值,套件本身預設數值未在此次研究中查證。 +- MusicFree:`MediaCache`(MMKV metadata 快取)除容量上限外是否有任何以時間為準的過期機制——已讀完整份 84 行原始碼確認沒有時間戳判斷,僅容量驅逐(`TODO: 随机删一半`),此點為確定結論而非「查不到」。 +- 本次研究未涵蓋第五個可選專案 LX Music;改以 MusicFree 作為第五個對象,符合任務原始指示中「可選 MusicFree 或 LX Music 擇一」的要求。 From e0ce3fa36be12cb7c437344b78f71f7a4ff609b6 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:14:25 +0800 Subject: [PATCH 040/133] chore(task): add design and plan for cache and offline --- .../09-27-design-cache-offline/design.md | 89 +++++++++++++++++++ .../09-27-design-cache-offline/implement.md | 10 +++ .../tasks/09-27-design-cache-offline/prd.md | 16 ++-- 3 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 .trellis/tasks/09-27-design-cache-offline/design.md create mode 100644 .trellis/tasks/09-27-design-cache-offline/implement.md diff --git a/.trellis/tasks/09-27-design-cache-offline/design.md b/.trellis/tasks/09-27-design-cache-offline/design.md new file mode 100644 index 000000000..d09c7cb65 --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/design.md @@ -0,0 +1,89 @@ +# 設計:快取與離線 + +## 1. 什麼是快取 + +- **快取=可以隨時丟、丟了只會變慢的東西**:圖片、歌詞內容、排行、串流網址。 +- **不是快取**(放主資料庫或各自的位置,不受快取上限與「清除快取」影響):音樂庫與歌單、下載檔、播放與搜尋歷史、歌詞匹配結果(ADR 0014)、 + 插件 storage 與憑證、設定。 +- 磁碟快取一律放在平台層提供的快取目錄(`getApplicationCacheDirectory()` 之下的 `fmp/`;開發版依 ADR 0015 另有目錄),**不進主資料庫**(B6 的原則推廣到所有快取)。 +- Android 系統在空間不足時可能清掉快取目錄:索引指向的檔案不存在就當作未命中並刪掉索引,不當錯誤。 + +## 2. 統一快取庫(磁碟) + +- 一個快取模組擁有快取目錄:一個小的 drift 索引(`cache.db`,與主資料庫分開)加上檔案。 + 索引欄位:鍵、類別(image/lyrics/charts)、所屬插件 id、大小、最後存取時間、期限(可空)。 +- **一個總上限**(已決定 A):寫入後超過上限,就不分類別依最後存取時間淘汰;啟動時也檢查一次。 +- 移除插件時刪掉它的快取項目(與 ADR 0014 清除 storage 一致)。 +- 「清除快取」=清空索引與檔案,並清掉 Flutter 記憶體 `ImageCache`。 +- 快取目錄只由快取模組存取:`path_provider` 只在平台層(ADR 0009),平台層只把快取目錄交給快取模組,由 lint `fmp_layer_imports` 的依賴表守(ADR 0015)。 + +## 3. 各類快取 + +| 類別 | 鍵 | 期限 | 備註 | +|---|---|---|---| +| 圖片 | 實際請求的 URL | 無(只靠 LRU) | 經 ADR 0012 媒體 client(不帶憑證,套用插件宣告的媒體標頭)。插件 DTO 的封面是多尺寸清單 `artwork: [{url, width?}]`,宿主依顯示尺寸挑最接近且不小於的一張;同一 URL 只存一份,縮放在解碼時做(`cacheWidth`/`ResizeImage`) | +| 歌詞內容 | 歌詞插件 id+歌詞 id | 無(內容不變) | 匹配結果存主資料庫,所以快取被淘汰後直接用存下的 id 重抓,不重新匹配 | +| 排行 | 插件 id+榜單 id | 無(由刷新覆蓋) | 先顯示快取並標「更新於 …」,背景刷新後替換;只抓已啟用插件且在首頁啟用的榜單(B12),停用就刪掉它的快取。刷新排程由第 16 項定 | +| 串流網址 | 見 §4(只在記憶體) | 插件回報 | — | + +- 圖片接法:`cached_network_image` 接受自訂 `BaseCacheManager`;以 `flutter_cache_manager` 的 `Config`(自訂 `CacheInfoRepository`+`FileService`)接到統一快取庫與媒體 client。 + 落地時驗證;接不起來就讓圖片保留它自己的索引,由統一淘汰器依檔案大小一起淘汰(總上限的語意不變)。 +- Flutter 記憶體 `ImageCache` 的大小由平台層宣告(沿用舊值:行動 100 張/50MB、桌面 200 張/80MB),不給使用者調。 +- 不做通用 HTTP 回應快取(`dio_cache_interceptor` 之類)與搜尋結果快取:搜尋要新鮮;插件需要保存的東西用自己的 storage。 + +## 4. 串流網址 + +- `resolveStream` 的 DTO 帶 `expiresAt`(可空)。**網址期限由插件從網址本身讀**(YouTube 的 `expire`、B 站的 `deadline`、網易的 `expi`)——D9 移進插件,宿主不懂任何平台參數(MusicFree 的慣例)。 +- 宿主只在記憶體保存(B6):鍵=曲目鍵+分 P+音質偏好,上限 64 筆,淘汰最久沒用的。 + 有效期到 `expiresAt − 5 分鐘`;`expiresAt` 為空時從解析起 5 分鐘內有效,只夠「預取→播放」交接用。 +- 播放失敗時作廢該筆(重試與跳過由第 13 項定)。下載一律重新解析,不用快取(沿用舊版理由:下載可能比安全邊界還久)。 +- 預取與播放讀寫同一份快取,舊版「資料庫裡的舊網址讓預取被跳過」的失效情況不再存在。 + +## 5. 離線 + +### 5.1 判定 + +```mermaid +stateDiagram-v2 + [*] --> Online + Online --> NoInterface: 系統回報沒有網路介面 + Online --> Unreachable: 短時間內連續傳輸失敗且沒有任何成功 + NoInterface --> Online: 系統回報網路介面恢復 + Unreachable --> Online: 任何一個請求成功,或網路介面變化 + Unreachable --> NoInterface: 系統回報沒有網路介面 +``` + +- 系統網路狀態用 `connectivity_plus`,經平台層提供介面變化事件;它的官方文件就說「有介面不代表能上網」,所以另以請求結果判定。 +- 「連續傳輸失敗」只算 ADR 0013 的 `NetworkError`(限流、登入等不算),門檻預設「30 秒內 3 次、其間沒有成功」。 +- **不輪詢**(B10:拿掉每 15 秒的 DNS 查詢)。離線中不發背景請求;使用者主動操作照常發請求,成功就回到 Online。背景任務的暫停與補跑由第 16 項定。 +- 狀態由網路層擁有(ADR 0012),UI 與 service 經 provider 讀取。 + +### 5.2 離線時各功能 + +| 功能 | 離線時 | +|---|---| +| 音樂庫、歌單、下載管理、設定 | 完整可用 | +| 播放 | 已下載的曲目照常播放;未下載的在播放時自動跳過並提示一次(D3 的統一跳過);整個佇列都不能播就停止並提示 | +| 曲目列表 | 未下載的曲目淡化顯示(只在離線時) | +| 歌詞 | 快取中有就顯示;沒有就顯示離線狀態 | +| 首頁排行 | 顯示快取並標「更新於 …」;沒有快取就顯示離線空狀態 | +| 線上搜尋、電台/直播、插件安裝與更新、登入 | 顯示離線狀態,不送出請求 | + +- 呈現:保留一個全域離線提示,各頁用同一個「離線空狀態」元件;文字一律 i18n(ADR 0013)。 +- 離線期間背景產生的 `NetworkError` 不跳 toast(ADR 0013「背景工作不跳 toast」的延伸)。 + +## 6. 使用者設定(已決定 A) + +- 「快取上限」一項:128MB/256MB/512MB/1GB。預設值由平台層宣告:桌面 256MB、行動 128MB;未設定=跟著預設(ADR 0011)。 +- 設定頁顯示各類目前用量,加一個「清除快取」按鈕。 +- 舊版的「圖片快取大小」(16–64MB)與「歌詞快取檔數」不匯入:語意不同(各管一類、上限偏小),新欄位維持未設定、使用預設。 + 排行與電台的刷新間隔屬第 16 項。 + +## 7. 閘門 + +- 單元測試:串流網址快取(安全邊界、`expiresAt` 為空的 5 分鐘、作廢、下載不走快取);**預取後播放只解析一次**。 +- 單元測試:快取庫跨類別淘汰到上限以下;檔案被系統刪掉時視為未命中;清除後用量為 0;移除插件會刪掉它的項目。 +- 單元測試:網路狀態轉換(介面消失、連續失敗、成功恢復),且沒有計時器輪詢。 +- widget 測試:每個頁面在離線時顯示離線狀態(用假的網路狀態 provider)。 +- 插件契約(ADR 0015):各官方插件的 `resolveStream` 檢查案例斷言回傳 `expiresAt`,且與 fixture 網址內的期限參數一致。 +- 依賴方向:快取目錄只經快取模組(`fmp_layer_imports`)。 diff --git a/.trellis/tasks/09-27-design-cache-offline/implement.md b/.trellis/tasks/09-27-design-cache-offline/implement.md new file mode 100644 index 000000000..8c6e17346 --- /dev/null +++ b/.trellis/tasks/09-27-design-cache-offline/implement.md @@ -0,0 +1,10 @@ +# 執行計畫:第 17 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0016-cache-and-offline.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§7;被否決的方案: + 分類上限、串流網址持久化(B6)、宿主解析各平台期限參數、通用 HTTP 回應快取、DNS 輪詢(B10)、手動離線模式與邊聽邊存(功能凍結,列待辦)。 +2. ADR 0014 補一句:`resolveStream` DTO 帶 `expiresAt`、封面為多尺寸 `artwork` 清單(見 ADR 0016)。 +3. `phase2-plan.md`:§3 第 17 項標 ✅(ADR 0016);待辦(第 20 項)加入邊聽邊存、手動離線模式、已下載內容容量管理;§10 交接段更新,下一項 16 背景任務。 +4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用正確。 +5. `task.py finish`、`task.py archive design-cache-offline --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-cache-offline/prd.md b/.trellis/tasks/09-27-design-cache-offline/prd.md index 56de766c9..f07010fdd 100644 --- a/.trellis/tasks/09-27-design-cache-offline/prd.md +++ b/.trellis/tasks/09-27-design-cache-offline/prd.md @@ -2,7 +2,7 @@ ## 目標 -為 `app/` 定下圖片、串流網址、歌詞、排行與插件回應等快取的統一策略,以及沒有網路時 App 能做什麼。產出 ADR 0016。 +為 `app/` 定下圖片、串流網址、歌詞、排行與插件回應等快取的統一策略,以及沒有網路時 App 能做什麼。產出 ADR 0016。技術設計見 `design.md`,執行步驟見 `implement.md`。 依據:parent `prd.md` 階段二第 17 項;`phase2-plan.md`(B6、D9,及相關的 B10、B12);ADR 0010–0015。 @@ -38,15 +38,21 @@ - 邊聽邊存(音訊快取):新功能,且 Windows 需自建 proxy。現有的「下載」照舊是唯一的離線保存方式。 - 手動離線模式開關、已下載內容的容量管理(LRU+釘選):新功能。 -## 待決定 +## 決定 -- [ ] 快取的使用者設定形式(一個總上限 vs 分類上限) +1. **快取的定義**:可以隨時丟、丟了只會變慢;一律在平台快取目錄、不進主資料庫。歌單、下載、歷史、歌詞匹配結果、插件 storage 與憑證不是快取。 +2. **一個總上限**(2026-09-27 選 A):128MB/256MB/512MB/1GB,預設桌面 256MB、行動 128MB;跨類別依最後存取淘汰;顯示各類用量+一個「清除快取」。 + 舊版兩個快取設定不匯入(語意不同)。 +3. **串流網址**:只在記憶體(B6);期限由插件從網址讀並回報 `expiresAt`(D9),宿主不懂平台參數;預取與播放共用同一份,舊預取失效不再存在。 +4. **離線**:系統網路狀態+連續傳輸失敗判定,不輪詢(B10);離線時本機功能完整、已下載曲目可播、未下載曲目淡化並跳過、排行與歌詞顯示快取、其餘顯示離線狀態。 +5. **排行**只抓已啟用的榜單(B12);技術細節見 `design.md` §2–§7。 ## 驗收條件 -- [ ] ADR 0016 記錄:快取的定義與位置、每一類的鍵/期限/上限/清除、串流網址期限由插件回報、離線判定與離線時各功能的行為、使用者設定。 +- [ ] ADR 0016 記錄決定 1–5 與被否決的方案;內容涵蓋:快取的定義與位置、每一類的鍵/期限/上限/清除、串流網址期限由插件回報、離線判定與離線時各功能的行為、使用者設定。 - [ ] B6、D9、B10(離線判定部分)、B12 各自對到決定與閘門;舊預取失效問題在新設計下不再成立並有測試守。 -- [ ] `phase2-plan.md` §3 第 17 項標 ✅ 與 ADR 編號。 +- [ ] `phase2-plan.md` §3 第 17 項標 ✅ 與 ADR 編號;待辦(第 20 項)加入上列三項新功能。 +- [ ] ADR 0014 補上 `resolveStream` 的 `expiresAt` 與多尺寸 `artwork`。 ## 不在範圍 From 9c4e16a3241a8eb1e25978d358ee295e8ce57e1b Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:15:40 +0800 Subject: [PATCH 041/133] docs(adr): 0016 cache and offline --- docs/adr/0014-script-source-plugins.md | 3 +- docs/adr/0016-cache-and-offline.md | 67 ++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0016-cache-and-offline.md diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index 374c4b15b..aef4ec536 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -40,7 +40,8 @@ manifest 與腳本承擔。 同一能力有多個提供者時 UI 全部列出。 5. **宿主 API v1**(腳本能用的全部):`http.request`(經 ADR 0012/0013 網路層、只能連 manifest 網域)、`crypto`、每插件 `storage`、 只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`)。沒有檔案系統、任意 socket、其他插件的資料。 - 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。 + 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。`resolveStream` 回傳網址期限 `expiresAt`(插件從網址本身讀), + 封面為多尺寸清單 `artwork`(ADR 0016)。 6. **插件庫**:官方插件在獨立 repo `1morr/fmp-plugins`,每插件一目錄(腳本、manifest、錄下的測試 fixture),其 CI 跑契約測試並產生 `index.json`(含 SHA-256)。App 插件頁預設讀官方 index,可加自訂 index 網址,也可從檔案或網址安裝;由 index 安裝時驗證 SHA-256。 安裝前顯示能力與會連的網域,並警告「此腳本會以你的登入身分存取這些網站」。 diff --git a/docs/adr/0016-cache-and-offline.md b/docs/adr/0016-cache-and-offline.md new file mode 100644 index 000000000..47033a74c --- /dev/null +++ b/docs/adr/0016-cache-and-offline.md @@ -0,0 +1,67 @@ +# 0016 — 快取與離線:一個可丟的快取庫、網址期限由插件回報、以請求結果判定離線 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:快取模組與 `cache.db`、圖片載入、串流解析、`resolveStream` 與封面 DTO、網路層的網路狀態、各頁的離線狀態、快取設定 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/current-state.md`,已以程式碼核對): + +- 圖片快取分三層互不統一,設定「圖片快取大小」只管磁碟那層,「清除圖片快取」不清記憶體層(`lib/main.dart:156-164`、`network_image_cache_service.dart:127-140`)。 +- 串流網址存進 Isar(`track.dart:68-71`),但播放只看行程內快取;持久化的舊網址反而讓預取被跳過、切歌時退化成同步解析(`stream_resolution_service.dart:299-304`)。 + YouTube 期限寫死 1 小時(D9)。 +- 歌詞快取有檔數上限與寫死的 5MB;排行只在記憶體,停用首頁顯示的音源仍在背景抓(B12)。 +- 離線靠每 15 秒查三個公共 DNS(B10),只有一個全域 Banner,沒有頁面有離線狀態。 + +擁有者已勾選:B6 串流網址不進資料庫;D9 期限從網址讀;B10 改用系統網路狀態加請求失敗判定;B12 停用就不抓排行。 + +## 考慮過的選項 + +- **分類各自上限**(Namida、舊版):否決。設定項隨類別增加,使用者分不清差別;改一個總上限。 +- **串流網址持久化**:否決(B6);舊版證明它沒被播放使用、還造成預取失效。 +- **宿主解析各平台的期限參數**:否決。違反 ADR 0014「App 不懂特定音源」;改由插件回報(MusicFree 的 `cacheControl` 同樣把判斷交給插件)。 +- **通用 HTTP 回應快取(`dio_cache_interceptor`)與搜尋結果快取**:否決。搜尋要新鮮,插件需要保存的東西用自己的 storage。 +- **定時輪詢判斷離線**:否決(B10)。`connectivity_plus` 官方文件也說有介面不代表能上網,應以請求結果判斷。 +- **手動離線模式(Finamp)、邊聽邊存(Spotube、Namida、MusicFree)、已下載內容容量管理**:新功能,依功能凍結列入待辦。 + 邊聽邊存另有平台限制:`media_kit` 沒有此功能,需自建本機 proxy;`just_audio` 的 `LockCachingAudioSource` 仍是 experimental。 + +## 決定 + +1. **快取的定義**:可以隨時丟、丟了只會變慢的東西——圖片、歌詞內容、排行、串流網址。音樂庫與歌單、下載檔、播放與搜尋歷史、歌詞匹配結果、 + 插件 storage 與憑證、設定都不是快取,不受快取上限與清除影響。 +2. **統一快取庫**:一個快取模組擁有平台快取目錄(`getApplicationCacheDirectory()` 之下),以獨立的 drift 索引 `cache.db`(與主資料庫分開)加檔案保存; + 索引記鍵、類別、所屬插件、大小、最後存取、期限。檔案被系統清掉視為未命中。移除插件時刪除它的項目。 +3. **一個總上限**:使用者設定「快取上限」128MB/256MB/512MB/1GB,預設由平台層宣告(桌面 256MB、行動 128MB,未設定=跟著預設,ADR 0011); + 超過時不分類別依最後存取淘汰。設定頁顯示各類用量與一個「清除快取」(含 Flutter 記憶體 `ImageCache`)。舊版兩個快取設定語意不同,不匯入。 +4. **各類快取**: + - 圖片:鍵為實際請求的 URL,經 ADR 0012 媒體 client;插件的封面 DTO 為多尺寸清單 `artwork: [{url, width?}]`,宿主挑最接近且不小於顯示尺寸的一張,縮放在解碼時做。 + 以 `cached_network_image` 的自訂 cache manager 接到快取庫;接不起來就保留它自己的索引、由統一淘汰器依檔案大小一起淘汰。 + 記憶體 `ImageCache` 大小由平台層宣告,不開放設定。 + - 歌詞內容:鍵為歌詞插件+歌詞 id,只靠 LRU;匹配結果在主資料庫,淘汰後以存下的 id 重抓、不重新匹配。 + - 排行:鍵為插件+榜單 id;先顯示快取並標「更新於 …」再背景刷新;只抓已啟用插件且在首頁啟用的榜單(B12),停用就刪掉快取。 +5. **串流網址**:`resolveStream` DTO 帶可空的 `expiresAt`,由插件從網址本身讀(D9)。宿主只在記憶體保存(B6),鍵為曲目鍵+分 P+音質偏好、上限 64 筆, + 有效到 `expiresAt − 5 分鐘`;為空時 5 分鐘內有效。播放失敗作廢該筆;下載一律重新解析。預取與播放共用這一份。 +6. **離線判定**:網路層擁有網路狀態——系統回報沒有網路介面(`connectivity_plus`,經平台層)即 `NoInterface`;30 秒內 3 次 `NetworkError` 且其間沒有成功即 `Unreachable`; + 任何請求成功或介面變化回到 `Online`。不輪詢;離線中不發背景請求,使用者操作照常發請求。 +7. **離線時各功能**:音樂庫、歌單、下載管理、設定完整可用;已下載曲目照常播放,未下載的淡化顯示、播放時自動跳過並提示一次,整個佇列不能播就停止; + 歌詞與排行顯示快取,沒有就顯示離線狀態;線上搜尋、電台與直播、插件安裝與更新、登入顯示離線狀態、不送請求。 + 一個全域離線提示加共用的離線空狀態元件;離線期間背景產生的 `NetworkError` 不跳 toast。 + +採用的慣例:MusicFree 讓插件決定網址可否重用;Finamp 的離線時功能降級;`connectivity_plus` 官方建議的「以請求結果為準」; +NewPipe/Spotube 的圖片快取交給 `cached_network_image` 系列;Android 官方對快取目錄「可能被系統清除、App 自行處理」的要求。 + +## 後果 + +- 好的:快取只有一個位置、一個上限、一個清除;丟掉快取不會掉資料;預取失效不再發生;網址期限跟著插件修,不必發 App;離線時每頁有明確狀態;不再每 15 秒查 DNS。 +- 壞的:要自建快取索引與淘汰;圖片接到統一快取庫需要實作 cache manager 介面;每個播放類插件都要正確回報 `expiresAt`。 +- 之後要注意:背景刷新與離線時的暫停、補跑由背景任務的 ADR 定;播放失敗的重試與跳過細節由播放核心的 ADR 定;邊聽邊存、手動離線模式、已下載內容容量管理列在功能凍結待辦。 + +## 如何確認 + +- 單元測試:串流網址快取的安全邊界、`expiresAt` 為空、作廢、下載不走快取;**預取後播放只解析一次**。 +- 單元測試:快取庫跨類別淘汰到上限以下;檔案被刪視為未命中;清除後用量為 0;移除插件刪除其項目。 +- 單元測試:網路狀態的轉換,且沒有計時器輪詢。 +- widget 測試:各頁在離線時顯示離線狀態。 +- 插件契約(ADR 0015):播放類插件的 `resolveStream` 檢查案例斷言 `expiresAt` 與 fixture 網址內的期限參數一致。 +- lint `fmp_layer_imports`(ADR 0015):快取目錄只經快取模組取得。 From 70fab878d02d846f10b7146f922851849afa720a Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:15:41 +0800 Subject: [PATCH 042/133] chore(task): archive design-cache-offline --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 ++++++------ .../tasks/09-27-design-cache-offline/implement.md | 10 ---------- .../2026-09}/09-27-design-cache-offline/check.jsonl | 0 .../2026-09}/09-27-design-cache-offline/design.md | 0 .../09-27-design-cache-offline/implement.jsonl | 0 .../2026-09/09-27-design-cache-offline/implement.md | 10 ++++++++++ .../2026-09}/09-27-design-cache-offline/prd.md | 0 .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../09-27-design-cache-offline/research/prior-art.md | 0 .../2026-09}/09-27-design-cache-offline/task.json | 6 +++--- 11 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 .trellis/tasks/09-27-design-cache-offline/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-cache-offline/task.json (88%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index cfdb2cf7f..65f4802dd 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013) | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016) | ## 2. 依賴關係 @@ -119,7 +119,7 @@ flowchart LR | 7 | 2 錯誤模型(✅ 完成,ADR 0013) | 音源插件介面的回傳與例外型別要先定。 | | 8 | 1 音源插件(✅ 完成,ADR 0014) | 核心抽象;依賴 10、12、2。 | | 9 | 8 測試與開發環境(✅ 完成,ADR 0015) | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | -| 10 | 17 快取與離線 | 串流 URL、圖片、排行快取的策略,播放核心要用。 | +| 10 | 17 快取與離線(✅ 完成,ADR 0016) | 串流 URL、圖片、排行快取的策略,播放核心要用。 | | 11 | 16 背景任務 | 刷新、清理、更新檢查誰來排程。 | | 12 | 13 播放核心 | 最大的一塊;依賴 1、2、10、17。 | | 13 | 14 音樂庫與同步 | B1/B2 已定方向,細節依賴 6、1、12、16。 | @@ -237,10 +237,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0015`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0016`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 17 項「快取與離線」**,task `.trellis/tasks/09-27-design-cache-offline/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 -- 之後順序:16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 16 項「背景任務」(尚未建 task)。 +- 之後順序:13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-27-design-cache-offline/implement.md b/.trellis/tasks/09-27-design-cache-offline/implement.md deleted file mode 100644 index 8c6e17346..000000000 --- a/.trellis/tasks/09-27-design-cache-offline/implement.md +++ /dev/null @@ -1,10 +0,0 @@ -# 執行計畫:第 17 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0016-cache-and-offline.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§7;被否決的方案: - 分類上限、串流網址持久化(B6)、宿主解析各平台期限參數、通用 HTTP 回應快取、DNS 輪詢(B10)、手動離線模式與邊聽邊存(功能凍結,列待辦)。 -2. ADR 0014 補一句:`resolveStream` DTO 帶 `expiresAt`、封面為多尺寸 `artwork` 清單(見 ADR 0016)。 -3. `phase2-plan.md`:§3 第 17 項標 ✅(ADR 0016);待辦(第 20 項)加入邊聽邊存、手動離線模式、已下載內容容量管理;§10 交接段更新,下一項 16 背景任務。 -4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用正確。 -5. `task.py finish`、`task.py archive design-cache-offline --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-cache-offline/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/check.jsonl diff --git a/.trellis/tasks/09-27-design-cache-offline/design.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/design.md similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/design.md diff --git a/.trellis/tasks/09-27-design-cache-offline/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.md new file mode 100644 index 000000000..f8066f174 --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/implement.md @@ -0,0 +1,10 @@ +# 執行計畫:第 17 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0016-cache-and-offline.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§7;被否決的方案: + 分類上限、串流網址持久化(B6)、宿主解析各平台期限參數、通用 HTTP 回應快取、DNS 輪詢(B10)、手動離線模式與邊聽邊存(功能凍結,列待辦)。 +2. [x] ADR 0014 補一句:`resolveStream` DTO 帶 `expiresAt`、封面為多尺寸 `artwork` 清單(見 ADR 0016)。 +3. [x] `phase2-plan.md`:§3 第 17 項標 ✅(ADR 0016);待辦(第 20 項)加入邊聽邊存、手動離線模式、已下載內容容量管理;§10 交接段更新,下一項 16 背景任務。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用正確。 +5. [x] `task.py finish`、`task.py archive design-cache-offline --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-cache-offline/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/prd.md diff --git a/.trellis/tasks/09-27-design-cache-offline/research/current-state.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/current-state.md similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/current-state.md diff --git a/.trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/packages-and-platform.md diff --git a/.trellis/tasks/09-27-design-cache-offline/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-27-design-cache-offline/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-cache-offline/task.json b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/task.json similarity index 88% rename from .trellis/tasks/09-27-design-cache-offline/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-cache-offline/task.json index c1c492a1c..5a9838800 100644 --- a/.trellis/tasks/09-27-design-cache-offline/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-cache-offline/task.json @@ -3,7 +3,7 @@ "name": "design-cache-offline", "title": "Design: cache and offline", "description": "Phase-2 item 17: unified cache strategy for images, stream URLs, lyrics, charts and plugin responses; what the app can do offline", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-27", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 31484ac0ad6882a75cb6d4b94cdaaf471699f5dc Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:16:28 +0800 Subject: [PATCH 043/133] chore(task): start design-background-tasks --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-27-design-background-tasks/check.jsonl | 0 .../implement.jsonl | 0 .../09-27-design-background-tasks/prd.md | 19 ++++++++++++++ .../09-27-design-background-tasks/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-27-design-background-tasks/check.jsonl create mode 100644 .trellis/tasks/09-27-design-background-tasks/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-background-tasks/prd.md create mode 100644 .trellis/tasks/09-27-design-background-tasks/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 65f4802dd..de3b48adf 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -240,7 +240,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0016`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 16 項「背景任務」(尚未建 task)。 +- **進行中:第 16 項「背景任務」**,task `.trellis/tasks/09-27-design-background-tasks/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 47357c018..c33c960f0 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -29,7 +29,8 @@ "09-27-design-errors", "09-27-design-source-plugins", "09-27-design-testing", - "09-27-design-cache-offline" + "09-27-design-cache-offline", + "09-27-design-background-tasks" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-background-tasks/check.jsonl b/.trellis/tasks/09-27-design-background-tasks/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-background-tasks/implement.jsonl b/.trellis/tasks/09-27-design-background-tasks/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-background-tasks/prd.md b/.trellis/tasks/09-27-design-background-tasks/prd.md new file mode 100644 index 000000000..7f2f3b1af --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/prd.md @@ -0,0 +1,19 @@ +# Design: background tasks + +## Goal + +Phase-2 item 16: who schedules auto-refresh, radio polling, cleanup and other periodic work; cancellation; behaviour in background and offline + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-27-design-background-tasks/task.json b/.trellis/tasks/09-27-design-background-tasks/task.json new file mode 100644 index 000000000..c3cce92e9 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-background-tasks", + "name": "design-background-tasks", + "title": "Design: background tasks", + "description": "Phase-2 item 16: who schedules auto-refresh, radio polling, cleanup and other periodic work; cancellation; behaviour in background and offline", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From dc0c47fbd1cf5a4e727426cdd165116dc77ae85b Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:36:16 +0800 Subject: [PATCH 044/133] chore(task): add design-background-tasks research and prd draft --- .../09-27-design-background-tasks/prd.md | 51 +++- .../research/current-state.md | 251 ++++++++++++++++++ .../research/packages-and-platform.md | 178 +++++++++++++ .../research/prior-art.md | 169 ++++++++++++ 4 files changed, 638 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-27-design-background-tasks/research/current-state.md create mode 100644 .trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-27-design-background-tasks/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-background-tasks/prd.md b/.trellis/tasks/09-27-design-background-tasks/prd.md index 7f2f3b1af..9981bc987 100644 --- a/.trellis/tasks/09-27-design-background-tasks/prd.md +++ b/.trellis/tasks/09-27-design-background-tasks/prd.md @@ -1,19 +1,48 @@ -# Design: background tasks +# 設計:背景任務(階段二第 16 項) -## Goal +## 目標 -Phase-2 item 16: who schedules auto-refresh, radio polling, cleanup and other periodic work; cancellation; behaviour in background and offline +為 `app/` 定下自動刷新、電台輪詢、清理等週期或背景工作由誰排程、如何取消、App 在背景或離線時的行為。產出 ADR 0017。 -## Requirements +依據:parent `prd.md` 階段二第 16 項;`phase2-plan.md`(B10、B12);ADR 0016 留給本項的「背景刷新排程、離線暫停與恢復後補跑」。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對) -## Acceptance Criteria +- 11 個 `Timer.periodic`(登記在 `test/support/periodic_timer_static_rule_test.dart:34-104`),各自開、各自取消;只有 3 項可設定間隔: + 排行(30/60/120/240 分,預設 60,不能關)、電台直播狀態(關/1/3/5/10 分,預設 5)、每張匯入歌單的刷新間隔(1–168 小時或不啟用,新建預設 24)。 +- 會發網路請求的週期工作:DNS 偵測(15 秒)、排行、匯入歌單(每 30 分檢查一次,一次刷一張、間隔 5 秒)、電台直播狀態、收聽電台時每分鐘刷新直播間資訊。 +- **只有電台輪詢在看不見時暫停**(`main.dart:347-365`,#95 為減少對 B 站的常駐流量),回前景時距上次超過一個間隔才補一輪;其餘背景照跑。 +- **沒有任何工作在發請求前看網路狀態**;離線照發、靠失敗收拾(電台因此把網路錯誤標成未開播,D10)。退避五套各不相同。 +- 本機工作(播放位置每秒檢查、每 10 秒存檔、下載進度每秒彙整、下載排程每 5 秒備援、評論自動翻頁)不發請求。 +- 一次性啟動工作:孤兒曲目清理、下載狀態整理、Windows 更新殘留清理、帳號狀態檢查與 B 站 Cookie 刷新(B4)。 +- 更新檢查只有手動;沒有定期憑證刷新;快取清理與 log 輪替都是事件觸發。 +- `auto_refresh_service.dart:13` 註解寫「每小時檢查」,實際 30 分鐘(不一致)。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- Finamp、Namida、Spotube、Harmonoid 都**不用** workmanager 之類做內容刷新;主流是「前景才跑+回前景時到期才補」(threshold),可調間隔只給真有定期需求的功能, + 「開 App 時刷新」本身就是正式設定(Namida `refreshOnStartup`、Finamp `resyncOnStartup`)。Namida 以單一連線控制器「離線時登記、恢復後補跑一次」。 +- Android 沒有前景服務時背景 Timer 不可靠,Doze 會斷網;`workmanager` 0.10.10(2026-09-07,活躍)最小間隔 15 分鐘、iOS 由系統決定、**不支援 Windows**。 +- 桌面最小化/縮托盤是 `AppLifecycleState.hidden`,Timer 照跑(Windows 效率模式只會變慢);iOS 只有播放中的背景音訊模式可靠。 +- Riverpod 3 的做法:Timer 放在 Notifier `build()`、`ref.onDispose` 取消,由生命週期與網路狀態 provider 決定建立與銷毀,不需第三方排程套件。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已由其他項決定 + +- 更新檢查只手動(第 19 項);插件更新只在插件頁或手動檢查(ADR 0014)。 +- 離線狀態與「離線中不發背景請求」(ADR 0016);排行只抓啟用的榜單(B12);不輪詢 DNS(B10)。 +- B4(B 站 Cookie 刷新)屬第 12 項;D10(電台未開播與查詢失敗的區分)屬第 2、13 項;下載排程屬第 11 項;播放位置相關計時屬第 13 項。 + +## 待決定 + +- [ ] App 看不見時,網路型週期工作要不要繼續跑 + +## 驗收條件 + +- [ ] ADR 0017 記錄:排程由誰擁有、工作如何宣告、何時跑與暫停、離線與恢復後補跑、取消、使用者設定、退避。 +- [ ] 舊的每一項週期與一次性背景工作都有去向。 +- [ ] 舊 `periodic_timer` static-rule 的去向(ADR 0015 §6 標給本項)定案。 +- [ ] `phase2-plan.md` §3 第 16 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 播放本身的背景執行、音訊服務與系統媒體控制(第 13 項);下載的背景執行與排程(第 11 項);更新流程(第 19 項);設定頁版面(第 5 項)。 diff --git a/.trellis/tasks/09-27-design-background-tasks/research/current-state.md b/.trellis/tasks/09-27-design-background-tasks/research/current-state.md new file mode 100644 index 000000000..d96dceea6 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/research/current-state.md @@ -0,0 +1,251 @@ +# 現狀盤點:舊專案(lib/)週期性與背景工作 + +> 查證日期:2026-09-27。分支 `docs/audit`。 +> 查證方式:讀 `docs/audit/`(engineering.md、features.md、playback.md、data.md、downloads.md、platforms.md、questions.md)、逐一 Read `lib/` 原始碼核對、Grep 全庫(`Timer(`、`periodic`、`Future.delayed`、`Isolate.spawn`/`compute(`)。 +> 入口清單:`test/support/periodic_timer_static_rule_test.dart:34-104` 的 `_timers` 登記表(9 個檔案、12 個 `Timer.periodic`),已逐一核對原始碼。 +> 行號皆為本次實際 Read 到的內容;推測另標。 + +--- + +## 總覽表 + +| # | 工作 | 檔案 | 間隔 | 可設定 | 背景暫停 | 離線感知 | 使用者可關 | +|---|---|---|---|---|---|---|---| +| 1 | 網路連通性 DNS 偵測 | connectivity_service.dart | 15 秒(寫死) | 否 | 否 | (本身就是) | 否 | +| 2 | 首頁排行快取刷新 | ranking_cache_service.dart | 預設 60 分 | 是(30/60/120/240 分) | 否 | 部分(聽恢復事件) | 不能關,只能調間隔 | +| 3 | 匯入歌單自動刷新 | auto_refresh_service.dart | 30 分檢查(寫死) | 每歌單各自間隔 | 否 | 否 | timer 不能關;每歌單可不設間隔 | +| 4 | 電台直播狀態輪詢 | radio_refresh_service.dart | 預設 5 分 | 是(關/1/3/5/10 分) | **是**(#95) | 否(錯誤顯示成未開播) | **能**(間隔設「關閉」) | +| 5 | 電台收聽:每秒更新已播放時長 | radio_controller.dart | 1 秒(寫死) | 否 | 否 | 不適用(本機) | 停止收聽即停 | +| 6 | 電台收聽:刷新直播間資訊 | radio_controller.dart | 1 分(寫死) | 否 | 否 | 否 | 停止收聽即停 | +| 7 | 播放位置檢查(補切下一首) | audio_provider.dart | 1 秒(寫死) | 否 | 否(刻意,背景才需要它) | 不適用(本機) | 不適用 | +| 8 | 播放位置定期存檔 | queue_manager.dart | 10 秒(寫死) | 否 | 否 | 不適用(本機) | 不適用 | +| 9 | 下載進度彙整 flush | download_service.dart | 1 秒(寫死) | 否 | 否 | 不適用(本機) | 不適用 | +| 10 | 下載排程 | download_service.dart | 5 秒(寫死)+事件觸發 | 並行數可設(1–5,預設 3) | 否 | 否 | 不適用 | +| 11 | 評論區自動翻頁 | comment_pager.dart | 10 秒(寫死) | 否 | 否 | 不適用(本機) | 不適用(只在面板開著時) | + +--- + +## 1. 網路連通性偵測 + +- **檔案**:`lib/services/network/connectivity_service.dart` +- **做什麼**:每 15 秒對 `dns.google`、`one.one.one.one`、`dns.alidns.com` 做 DNS 解析(`InternetAddress.lookup`,任一成功即算有網路,單次逾時 5 秒);狀態翻轉時更新 `ConnectivityState`,斷→通時 broadcast `onNetworkRecovered`(`:52-56,73-97,102-116`)。 +- **誰啟動**:`ConnectivityNotifier.build()` → `_initialize()`(`:43-47,64-80`)。第一個讀它的是 `RankingCacheService.build()`(`ranking_cache_service.dart:149`)與 `AudioController._wireProviderCallbacks()`(`audio_provider.dart:271-273`),實際上 App 啟動後排行快取經 `refreshSettingsProvider`(`app.dart:119`)就會帶起它(推測:啟動早期即開始輪詢)。 +- **間隔**:`AppConstants.connectivityPollingInterval` = 15 秒、`dnsTimeout` = 5 秒,皆寫死(`lib/core/constants/app_constants.dart:154,157`)。 +- **背景/最小化**:無 AppLifecycleState 處理,背景照跑。 +- **離線行為**:它本身就是離線判斷者。 +- **失敗退避**:無;每輪固定間隔,三個目標逐一試完才算斷線。 +- **取消**:provider dispose → `_teardown()` 取消 timer 並關 controller(`:120-123`)。實務上常駐。 +- **使用者能否關閉**:不能(static rule 登記表自承「2026-09 決定不改行為」;questions.md B10 尚未決定)。 +- **下游消費者**:排行榜網路恢復重抓(`ranking_cache_service.dart:218-230`);播放網路恢復(`audio_provider.dart:2155-2163` → `_onNetworkRecovered()`)。 + +## 2. 首頁排行快取刷新 + +- **檔案**:`lib/services/cache/ranking_cache_service.dart` +- **做什麼**:對 `SourceManager` 註冊的每個 `RankingSource` 並行抓排行榜存進記憶體 state(不落盤);啟動時立即抓一次,之後定時整批重抓;網路恢復時也整批重抓(`:178-257`)。 +- **誰啟動**:`rankingCacheServiceProvider`(`NotifierProvider`)在 `build()` 裡 `Future.microtask(initialize)` 並接網路監聽(`:146-151`)。由 `refreshSettingsProvider._loadSettings()` 在啟動時 `updateRefreshInterval` 觸發建構(`refresh_settings_provider.dart:62-64`;該 provider 錨在 `FMPApp.build`,`app.dart:119`)。 +- **間隔**:`Settings.rankingRefreshIntervalMinutes`,預設 60 分;設定頁選項 30/60/120/240 分(`lib/ui/pages/settings/widgets/settings_cache.dart:245`;預設 `refresh_settings_provider.dart:14`;持久化 `lib/data/models/settings.dart:434`)。改設定即重啟 timer(`:202-215`)。**不能設成關閉**;首頁排行設定頁停用某音源只影響顯示,背景仍抓全部音源(`home_ranking_settings_provider.dart:193-195`;questions.md B12)。 +- **背景/最小化**:無生命週期處理,背景照跑照抓。 +- **離線行為**:不看 connectivity 狀態就發請求;失敗走退避。網路恢復事件觸發額外一整輪(`:222-227`)。 +- **失敗退避**:單一榜單失敗保留舊快取,按 `[5s, 30s, 2m, 10m]` 階梯退避(`Timer` 一次性重試),用完交還給定時刷新與網路恢復;每次整輪刷新重置階梯(`:124-129,297-311,236`)。 +- **取消**:provider dispose → `_teardown()` 取消 refresh timer、全部退避 timer、網路訂閱(`:325-335`)。 +- **使用者能否關閉**:不能關,只能調間隔。 + +## 3. 匯入歌單自動刷新 + +- **檔案**:`lib/services/library/auto_refresh_service.dart` +- **做什麼**:每 30 分鐘掃一次全部歌單,挑出 `needsRefresh` 的(匯入歌單且設了 `refreshIntervalHours`、且 `lastRefreshed + 間隔 < now`),按最久未刷新排序,**一次只刷一張**,每刷完一張等 5 秒再刷下一張(`:57-123`)。刷新本體走 `refreshManagerProvider.refreshPlaylist`(`:100-102`)。 +- **誰啟動**:`autoRefreshServiceProvider` 建構即 `service.start()`(`:143-158`),由 `FMPApp.build` watch(`app.dart:122`)。`start()` 立刻檢查一次再開 timer(`:32-45`)。 +- **間隔**:檢查節拍寫死 `AppConstants.autoRefreshCheckInterval` = 30 分(`:41-44`;`app_constants.dart:151`)。**不一致**:類別註解(`:13`)寫「每小时检查一次」。每張歌單的刷新間隔是 Isar `Playlist.refreshIntervalHours`(小時;`lib/data/models/playlist.dart:30,76-83`),歌單編輯對話框選項 1/6/12/24/48/72/168 小時或不啟用,新建預設 24 小時(`create_playlist_dialog.dart:57-61,293-320`;「不啟用」存 -1,`:455-457`)。 +- **背景/最小化**:無生命週期處理,背景照跑(`features.md` §13.2 亦註明「app 開著就跑(不看前景背景)」)。 +- **離線行為**:不看 connectivity;刷新失敗只記 log 繼續下一張(`:108-110`)。 +- **失敗退避**:無;單張失敗略過,等下一個 30 分鐘節拍。以 `_checkGeneration` 代際防止舊迴圈寫狀態(`:125-127`)。 +- **取消**:`stop()` 取消 timer;provider dispose → `dispose()`(`:48-54,136-139,153-155`)。 +- **使用者能否關閉**:timer 本身不能關;但預設不刷新——歌單沒設 `refreshIntervalHours` 就永不入列(`playlist.dart:77`)。`checkNow()` 手動入口是死代碼(`:130`;`features.md` §14)。 + +## 4. 電台直播狀態輪詢 + +- **檔案**:`lib/services/radio/radio_refresh_service.dart` +- **做什麼**:輪詢資料庫裡每個電台的 Bilibili 直播間資訊(開播狀態、封面、標題、主播名),更新記憶體快取並按需寫回資料庫,經 `stateChanges` 廣播(`:157-236`)。類別註解自承這是「App 裡唯一開著就永遠在打 Bilibili 的流量」(`:21-26`)。 +- **誰啟動**:`main.dart` 第一幀後建立全域單例 `RadioRefreshService.instance`(間隔取預讀設定;`main.dart:247-258`),但**不輪詢**;要等到 `RadioController._initialize()` 呼叫 `setRepository()` 才 `_startRefreshTimer()` 並立即刷一輪(`:92-99`;`radio_controller.dart:304-306`)。觸發點是首頁電台區塊建構 RadioController。 +- **間隔**:`Settings.radioRefreshIntervalMinutes`,預設 5 分;設定頁選項 關閉(0)/1/3/5/10 分(`settings_cache.dart:311`;`defaultRefreshInterval` `:34`;`offMinutes = 0` `:38`;`intervalFromMinutes` 把 0 轉成 null = 關閉、非法值回預設 `:42-46`)。改設定即 `updateRefreshInterval` 重啟 timer(`:111-119`;`refresh_settings_provider.dart:83-97`)。 +- **背景/最小化**:**有**。`main.dart:256-258,347-365` 的 `_RadioRefreshLifecycleObserver` 把 `paused/hidden/detached` → `pause()`、`resumed` → `resume()`;`inactive` 不算背景(桌面視窗失焦)。timer 不取消,`tick()` 直接不做事;回前景時距上次乾淨刷新超過一個間隔才補一輪(`:123-155`)。手動 `refreshAll` 不受暫停限制。 +- **離線行為**:不看 connectivity。非風控例外一律 `_markOffline` 把該台標成未開播(`:252-257`;questions.md D10 記「網路錯誤顯示成未開播」)。 +- **失敗退避**:被風控(`SourceApiException.isRateLimited`)的那輪立刻停,下一輪推遲 `interval × 2^n`(n 上限 10)、上限 30 分(`maxBackoff` `:32`;`_enterBackoff` `:239-250`);乾淨跑完一輪歸零(`:231-233`)。網路錯誤不退避,照常下一拍。 +- **取消**:間隔設「關閉」→ timer 不建;`dispose()` 取消 timer 關 controller(`:298-302`)。 +- **使用者能否關閉**:**能**,設定 > 電台刷新間隔 > 關閉;關閉時連啟動那一輪都不刷,只剩電台頁手動下拉(`:16-17,97-98`)。死代碼:`refreshStation`/`addStationStatus`/`removeStation`(`:260,276,282`;`features.md` §14)。 + +## 5. 電台收聽:每秒更新已播放時長 + +- **檔案**:`lib/services/radio/radio_controller.dart:972-975` +- **做什麼**:收聽電台期間每秒以 `DateTime.now() - _playStartTime` 更新 `state.playDuration`(`:993-998`)。純本機計時,無網路。 +- **誰啟動**:`play()` 成功開流後 `_startTimers()`(`:505,968-982`)。 +- **間隔**:1 秒,寫死。 +- **背景/最小化**:無生命週期處理;直播音訊本身在背景繼續播,timer 照跑。 +- **離線行為**:不適用(本機)。 +- **失敗退避**:不適用。 +- **取消**:`stop()`、直播結束 `_pauseAndWatchForResume()`、換台都 `_stopTimers()`(`:531-532,944-946,985-990,1045`)。 +- **使用者能否關閉**:不適用(只在收聽時跑)。 + +## 6. 電台收聽:每分鐘刷新直播間資訊 + +- **檔案**:`lib/services/radio/radio_controller.dart:978-981` +- **做什麼**:收聽期間每 1 分鐘呼叫 `refreshStationInfo()`(`:800`)重新拉直播間資訊(高能用戶數等)。打 Bilibili 直播 API。 +- **誰啟動**:同 #5,`play()` 成功後 `_startTimers()`。 +- **間隔**:1 分鐘,寫死。 +- **背景/最小化**:無生命週期處理,背景照打。 +- **離線行為**:不看 connectivity;失敗走 `refreshStationInfo` 自己的例外處理(未展開核對)。 +- **失敗退避**:無。 +- **取消**:同 #5,`_stopTimers()`。 +- **使用者能否關閉**:停止收聽即停,無獨立開關。 + +## 7. 播放位置檢查(補切下一首) + +- **檔案**:`lib/services/audio/audio_provider.dart:1304-1316` +- **做什麼**:每秒把播放上下文交給 `PlaybackEventRouter.routePositionCheck`:後端漏掉 completed 事件時(Android 背景播放),位置連續停在結尾(距時長 ≤ 500ms)就合成一次「播完」補切下一首;推進權已 arm 給後端時連續 3 秒不動則收回推進權(`playback_event_router.dart:472-498`;`playback.md` §3.6)。 +- **誰啟動**:`AudioController.initialize()`(`:380`),**無條件常駐**——timer 不是只在播放時才跑,是每秒都跑、內部在 `!backendIsPlaying` 時 no-op(`playback_event_router.dart:477`)。登記表上「只在播放時跑」指的是效果,不是 timer 本身。 +- **間隔**:`AppConstants.positionCheckInterval` = 1 秒、閾值 `positionCheckThreshold` = 500ms,寫死(`app_constants.dart:69-72`)。 +- **背景/最小化**:無生命週期處理;它的存在目的就是補背景播放(`:1302` 註解)。 +- **離線行為**:不適用(本機)。 +- **失敗退避**:不適用。 +- **取消**:`_teardown()` → `_stopPositionCheckTimer()`(`:460,1313-1316`)。 +- **使用者能否關閉**:不能,也無必要(本機)。 + +## 8. 播放位置定期存檔 + +- **檔案**:`lib/services/audio/queue_manager.dart:819-824` +- **做什麼**:每 10 秒把當前播放位置寫進佇列持久化(`PlayQueue.lastPositionMs`)。 +- **誰啟動**:`QueueManager.initialize()`(由 AudioController 初始化帶起)還原佇列後 `_startPositionSaver()`(`:218`)。 +- **間隔**:`AppConstants.positionSaveInterval` = 10 秒,寫死(`app_constants.dart:54`)。seek 後另有一次立即存檔(`audio_provider.dart:576-582`,事件觸發非 timer)。 +- **背景/最小化**:無生命週期處理,背景照寫。 +- **離線行為**:不適用(本機 Isar)。 +- **失敗退避**:無(`_savePosition` 內部未展開核對)。 +- **取消**:`QueueManager.dispose()`(`:239-245`)。 +- **使用者能否關閉**:不能。「記住播放位置」是另一個設定,只影響還原,不影響這個 timer。 + +## 9. 下載進度彙整 flush + +- **檔案**:`lib/services/download/download_service.dart:348-358` +- **做什麼**:每 1 秒把下載 isolate 回報累積在記憶體的進度一次 flush 到 `progressStream`(只進記憶體 state,**不寫 DB**,刻意避免 Isar watch 觸發重建;`:316-358`)。註解說明也為了避免 Windows PostMessage 佇列溢出(`:350-353`)。 +- **誰啟動**:`DownloadService.initialize()`(`:226`),由 `downloadServiceProvider` 建構時呼叫(`download_providers.dart:42,59`)。**該 provider 不在 `FMPApp.build` 的啟動清單**;首次被 watch 是下載管理頁(`download_manager_page.dart:20`)或歌單詳情頁的下載動作(`playlist_detail_page.dart:966,1039,1527`)。也就是兩個下載 timer 不是 App 啟動即跑,是第一次碰下載功能才跑(推測:之後常駐不關)。 +- **間隔**:1 秒,寫死(`:354-355`)。 +- **背景/最小化**:無生命週期處理。 +- **離線行為**:不適用(本機彙整)。 +- **失敗退避**:不適用。 +- **取消**:`dispose()`(`:284-285`)。 +- **使用者能否關閉**:不適用。 + +## 10. 下載排程 + +- **檔案**:`lib/services/download/download_service.dart:397-406` +- **做什麼**:排程下一個待下載任務:讀 `Settings.maxConcurrentDownloads`、算空槽、把 pending 任務轉 downloading 並 `_startDownload`(每個任務一個 `Isolate.spawn`,`:818`)(`:420-456`)。事件驅動(`_triggerSchedule` broadcast)為主,5 秒 `Timer.periodic` 是備援——啟動初期事件可能丟失,靠定時器補(`downloads.md` §2 記 `_triggerSchedule` 早於訂閱建立時事件會丟)。 +- **誰啟動**:`initialize()` → `_startScheduler()`(`:223`),時機同 #9。 +- **間隔**:5 秒,寫死(`:403`)。並行數 `Settings.maxConcurrentDownloads` 可設 1–5、預設 3(`downloads.md` §2;`settings.dart:281`)。 +- **背景/最小化**:無生命週期處理;下載只在 App 行程內 isolate 跑,無前景服務/WorkManager(questions.md N8)。 +- **離線行為**:不看 connectivity;下載失敗由任務自身狀態處理,不自動重試(`downloads.md` §2)。 +- **失敗退避**:排程器本身無退避;串流解析層另有一次重試(1 秒)與限流重試(3 秒)。 +- **取消**:`dispose()`(`:280-283`)。 +- **使用者能否關閉**:不適用;無新任務時每 5 秒空轉一次(讀設定+查 pending,皆本機)。 + +## 11. 評論區自動翻頁 + +- **檔案**:`lib/ui/widgets/panels/comment_pager.dart:96-105` +- **做什麼**:每 10 秒若評論區在螢幕可視範圍內(`_isVisible()` 算 RenderBox 與螢幕交集,`:74-94`)就自動翻到下一則(到底繞回)。 +- **誰啟動**:widget `initState` → `_startAutoScroll()`,僅 `autoScroll: true` 時;目前只有桌面 Detail Panel 傳 true(`track_detail_panel.dart:919-922`);全螢播放頁的 `CommentPager`(`player_page.dart:1081`)不傳,預設 false 不跑。 +- **間隔**:10 秒,寫死(`:98`)。 +- **背景/最小化**:無生命週期處理;但面板關掉 widget 就 dispose。 +- **離線行為**:不適用(資料已抓)。 +- **失敗退避**:不適用。 +- **取消**:`dispose()` 取消(`:68-71`);切歌或 `autoScroll` 變動時重啟(`:53-65,107-111`)。 +- **使用者能否關閉**:無設定開關;關面板即停。 + +--- + +## 登記表之外的發現 + +以下都不在 `_timers` 登記表(不是 `Timer.periodic`/`Stream.periodic`),但屬於背景/週期性質的工作。 + +### 啟動時一次性背景工作(非週期) + +| 工作 | 時機 | 證據 | +|---|---|---| +| 孤兒 Track 清理(不在任何歌單、不在佇列的 Track 刪除) | 佇列初始化後 10 秒一次性 `Timer`(刻意用 Timer 而非 Future.delayed,避免撞上已關閉的 Isar) | `queue_manager.dart:220-229,830-843`;`track_repository.dart:635-669` | +| 清已完成/失敗下載任務、`downloading` 全部轉 `paused`、刪孤兒 `.downloading` 暫存檔 | `DownloadService.initialize()`(首次碰下載功能時) | `download_service.dart:206-220,238-273` | +| Windows 清理上次更新殘留(Temp 裡 `fmp-*.exe/.zip`、`fmp_updater.*`、`fmp_update/`) | 每次啟動(僅 Windows) | `main.dart:231`;`update_service.dart:259-292` | +| 清空 `LyricsTitleParseCache` 表(只活一個 session 的快取) | 每次啟動開 DB 時 | `lib/data/database/database_migration.dart:66`(data.md §1) | +| 下載目錄掃描同步(`DownloadPathSyncService.syncLocalFiles`) | 啟動時 `startupDownloadSyncProvider`(`app.dart:131`) | `lib/providers/download/startup_download_sync_provider.dart:9-17` | +| B 站 Cookie 刷新+三平台帳號狀態檢查 | 啟動時一次(`accountStatusCheckProvider`,`app.dart:125`) | `account_provider.dart:131-174` | + +### 快取清理(全部事件觸發,無定期清理) + +- **網路圖片磁碟快取**:每載入 30 張或估計大小超過上限 90% 時觸發修剪(防抖 `DebounceDurations.long` = 500ms),LRU + 7 天 stale + `Settings.maxCacheSizeMB` 上限(桌面預設 32 MB);`compute()` 掃目錄。`lib/core/services/network_image_cache_service.dart:202-252,50-86`。設定頁可手動清除。 +- **歌詞內容快取**:LRU,檔數 `Settings.maxLyricsCacheFiles`(預設 50,設定選項 10/30/50/100/200,`settings_cache.dart:171`)+ 總量 5 MB 寫死;存取時間寫 `_metadata.json` 用 2 秒防抖 `Timer`。`lib/services/lyrics/lyrics_cache_service.dart:18-39,315`。 +- **記憶體串流解析快取**:32 筆 LRU,依 URL 有效期失效(data.md §4;`stream_resolution_service.dart:102-112`)。 +- **圖片記憶體快取**:啟動時設 `PaintingBinding` 上限(`main.dart:156-164`)。 + +### log 輪替 + +- 有輪替但非定時:`LogFileSink` 單檔 2 MB × 3 檔,寫入時超過上限才輪替(`fmp.log` → `fmp.1.log` …),位置 `Documents/FMP/logs/`。`lib/core/log_file_sink.dart:15-28,82-105`。無啟動時清理、無依日期刪除。 + +### 更新檢查 + +- **只有手動**:設定 > 關於 > 檢查更新(`settings_about.dart:70` → `update_provider.dart:80` → `update_service.dart:389`)。啟動時不檢查、無定時檢查(grep `checkForUpdate` 全庫只有這一條 UI 呼叫鏈)。與 questions.md B7–B9 備註一致(使用者明確要求不要啟動/定時檢查)。 + +### 播放歷史寫入 + +- 即時寫、非節流:開流成功且 `countsAsNewPlay` 時 `PlayHistorySideEffect.onTrackStarted` → `PlayHistoryRecorder.record`,fire-and-forget microtask 直接寫 Isar,並依 `Settings.playHistoryLimit`(預設 10,000)截斷。`playback_side_effects.dart:166-185`;`play_history_recorder.dart:34-53`。單曲循環每圈記一筆(playback.md §3.9;questions.md D6 使用者確認這是要的行為)。 + +### 帳號/憑證刷新 + +- **B 站 Cookie**:只有啟動時一次。`accountCookieRefreshProvider` 先 `needsRefresh()`(打 B 站 API 問伺服器要不要換)再 `refreshCredentials()`;伺服器要求時舊 refresh_token 作廢。`account_provider.dart:131-152`;`bilibili_account_service.dart:331-357`。**無定期刷新**。 +- **三平台帳號狀態**(session 有效性 + VIP):同樣啟動時一次(`accountStatusCheckProvider` → `verifyAllAccountStatuses`,`account_provider.dart:158-174,216-229`)。請求期由攔截器偵測失效寫 Isar,UI 經 `accountSessionExpiryWatcherProvider` 提示(`account_provider.dart:190-199`)。無定期檢查。 +- **YouTube/網易**:查不到任何定期憑證刷新。 + +### Windows 托盤與桌面歌詞 + +- `lib/services/platform/windows_desktop_service.dart`(托盤、全域熱鍵、關閉縮托盤、安裝程式偵測)**沒有任何 Timer/輪詢**,全事件驅動(tray_manager/hotkey_manager 回呼、provider watch)。 +- 桌面歌詞子視窗(`lib/services/lyrics/lyrics_window_service.dart`、`lib/ui/windows/lyrics_window.dart`)主行程側無週期工作,狀態推送走 desktop_multi_window method channel(事件驅動);子視窗內只有一次性防抖/延遲 Timer(滾動恢復 3 秒 `lyrics_window.dart:813`、樣式 flush `lyrics_window_style.dart:41`)。 + +### `Future.delayed` 自我排程迴圈(退避形狀,非持續迴圈) + +static rule 登記表註解(`periodic_timer_static_rule_test.dart:13-14`)說「目前沒有」`Future.delayed` 自排下一輪的迴圈;核對後確認全庫的 `Future.delayed` 都是**有限次退避重試或 debounce**,沒有無限自我排程: + +| 位置 | 形狀 | +|---|---| +| 電台斷流重連 `_handleStreamEnd` | 最多 3 次,1s/3s/10s(`RadioReconnectConfig`,`app_constants.dart:250-262`;`radio_controller.dart:894-941`) | +| 播放失敗復原 `PlaybackRecoveryCoordinator` | 最多 5 次,1s/2s/4s/8s/16s(`NetworkRetryConfig`,`app_constants.dart:226-246`;`playback_recovery_coordinator.dart:170`) | +| 排行榜失敗退避 | 4 階 5s/30s/2m/10m(一次性 `Timer`,見 §2) | +| Mix 補歌 | 最多 10 次、間隔 1 秒(`mix_session_coordinator.dart:293-299`;`app_constants.dart:99-105`) | +| 串流解析重試 | 一般 1 次(1 秒)、限流 1 次(3 秒)(`stream_resolution_service.dart:216,236`) | +| 匯入比對搜尋節流 | 多源 1 秒/單源 800ms(`app_constants.dart:83-88`) | +| 帳號 QR 登入輪詢等待 | `bilibili_account_service.dart:167`(2 秒)、`netease_account_service.dart:146`(3 秒)——登入流程內有限等待,非常駐 | +| media_kit 時長輪詢 | `playUrl/setUrl/playFile/setFile` 四份相同的「等後端回時長」迴圈,50ms 一拍、有逾時上限(`media_kit_audio_service.dart:782-949`;`app_constants.dart:60`) | + +### 其他 isolate + +- `download_service.dart:818` `Isolate.spawn`:每個下載任務一個長駐 isolate,靠 receivePort 回報進度、cancel port 取消。 +- 一次性 `compute()`/`Isolate.run()`:圖片快取目錄掃描與刪檔(`network_image_cache_service.dart:50,55,86`)、下載路徑維護(`download_path_maintenance_service.dart:91,124`)、下載目錄掃描(`download_providers.dart:205,215`、`download_scanner.dart`)、Windows 免安裝版更新解壓(`update_service.dart:656`)。全部一次性,完成即回收。 + +### 背景暫停覆盤 + +全庫只有 `RadioRefreshService` 接 `AppLifecycleState`(`main.dart:347-365`,#95)。其餘網路輪詢——DNS 偵測、排行刷新、歌單自動刷新、電台收聽中的資訊刷新——**背景照跑**(Android 上行程被系統限制時自然停,但程式碼層無主動暫停)。 + +### 離線感知覆盤 + +唯一對外發請求前會考慮連線狀態的機制是「網路恢復事件」:排行榜(`ranking_cache_service.dart:222-227`)與播放(`audio_provider.dart:2155-2163`)**監聽恢復**;但沒有任何工作在發請求**前**檢查 `connectivityProvider` 狀態——離線時照發,靠各自失敗路徑收拾(電台還會因此把狀態誤標成未開播,D10)。 + +--- + +## audit 文件提出的未決問題(與背景工作相關) + +出自 `docs/audit/questions.md` 與各 audit 文件,尚未勾選定案: + +1. **B10**:每 15 秒解析 `dns.google`、`one.one.one.one`、`dns.alidns.com` 偵測連線——常駐,去留未定(`connectivity_service.dart:52-56,102-116`)。 +2. **B12**:首頁排行「停用某音源」只影響顯示,背景仍每小時抓所有音源——有「修改:停用即不抓」選項未定(`ranking_cache_service.dart:233-245`;`home_ranking_settings_provider.dart:193-195`)。 +3. **B4**:啟動時自動換 B 站 Cookie(伺服器要求時舊 refresh_token 作廢)——每次啟動檢查,去留未定(`account_provider.dart:131-152`)。 +4. **D10**:電台輪詢開播狀態;網路錯誤顯示成「未開播」——未定(`bilibili_live_client.dart:205-208`;`radio_refresh_service.dart:252-257`)。 +5. **N8**:下載只在 App 行程內 isolate 跑,無前景服務或系統排程——背景時隨系統回收中斷、重啟變 paused,是否改未定(`downloads.md` §2、§6)。 +6. **文件不一致**:`auto_refresh_service.dart:13` 類別註解「每小时检查一次」vs 實際 30 分鐘(`app_constants.dart:151`;`features.md` §13.2 已記)。 +7. **E17**:應用內更新只有手動檢查一個入口;使用者在 B7–B9 備註已明確「不要啟動或定時檢查」,重寫應沿用此決定。 +8. **E18**:托盤、全域快捷鍵、開機自啟、關閉縮托盤、單一實例(皆 Windows-only、事件驅動)功能去留未定;使用者備註確認單一實例要保留。 +9. **M9**:登入失效提示每次 App 執行每平台只跳一次,重新登入後再失效不再提示(`session_expiry_notifier.dart:15,22-23`)——與啟動帳號檢查的觸發頻率相關,未定。 +10. **重寫時的機制問題**(非 questions.md 條目,本次盤點觀察):現行 11 個週期工作中,只有電台輪詢有背景暫停、只有排行刷新有離線恢復通道、失敗退避策略五套各不相同(排行 4 階、電台 2^n 上限 30 分、播放 5 階、電台重連 3 階、歌單刷新無退避);新專案若要統一背景任務排程,這三個維度是主要分歧點。 diff --git a/.trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md b/.trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md new file mode 100644 index 000000000..1e7245f29 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md @@ -0,0 +1,178 @@ +# 背景任務排程:平台與套件硬性事實 + +- 查證日期:2026-09-27 +- 查證方式:context7(Riverpod、flutter_workmanager 官方文檔)+ pub.dev API(版本與發佈日期)+ 官方文檔(developer.android.com、api.flutter.dev、developer.apple.com)+ tavily-search 補充 + GitHub API(workmanager 維護活動)。 +- 適用範圍:FMP 重寫的背景任務排程設計(排行榜背景刷新、匯入歌單自動刷新、電台輪詢、連線偵測、快取清理)。 + +--- + +## 1. Android 背景執行限制 + +### Dart `Timer` 在背景的行為 + +`Timer` 依附於 Dart isolate 的事件迴圈,**只要進程活著且 CPU 醒著就會繼續觸發**;Flutter 官方沒有「背景自動停止 Timer」的機制。官方對背景執行的指引是:要在 App 非前景時執行 Dart 程式碼,需另外建立 isolate(callback dispatcher 模式),或用 WorkManager 類的持久化排程(來源:[docs.flutter.dev — Background processes](https://docs.flutter.dev/packages-and-plugins/background-processes))。 + +硬性限制來自 Android 系統,不是 Flutter: + +- **無前景服務時**:App 退到背景後進程屬 cached 狀態,系統在記憶體壓力下可隨時終止它;進程一死,Timer 自然也沒了。此外 App Standby bucket 會按使用頻度限制 job/alarm/網路額度(如 working set 每小時最多 10 次鬧鐘、rare bucket 更嚴;來源:[developer.android.com — Power management resource limits](https://developer.android.com/topic/performance/power/power-details))。 +- **有前景服務時**(媒體播放用的 mediaPlayback foreground service):進程被歸類為前景,不會被 App Standby 判為 idle。官方原文:「The system makes this determination when the user doesn't touch the app for a certain period of time and none of the following conditions applies: … The app has a process currently in the foreground, either as an activity or foreground service」。但官方同時警告「Don't start a foreground service just to prevent the system from determining that your app is idle」(來源:[developer.android.com — Optimize for Doze and App Standby](https://developer.android.com/training/monitoring-device-state/doze-standby))。 + +### Doze 的影響(對 Timer 與網路同樣致命) + +Doze 期間(裝置未充電、靜置、關螢幕),系統對**所有** App 套用以下限制,前景服務也不例外(該頁只說前景服務可避開 App Standby 的 idle 判定,未給予 Doze 豁免): + +- **Suspends network access.** +- **Ignores wake locks.**(→ CPU 睡眠,Dart isolate 不跑,Timer 實質不觸發) +- 標準 `AlarmManager` 鬧鐘延遲到 maintenance window;`JobScheduler` 不跑,「WorkManager uses `JobScheduler` internally, so `WorkManager` tasks don't run」。 +- 系統定期進入短暫 maintenance window 放行積壓的 jobs/syncs/alarms 與網路;且「the system schedules maintenance windows less frequently」——放著越久,窗口越稀疏。 +- `setAndAllowWhileIdle()` / `setExactAndAllowWhileIdle()` 每 App 每 9 分鐘最多觸發一次。 + +(以上皆引自 [developer.android.com — Optimize for Doze and App Standby](https://developer.android.com/training/monitoring-device-state/doze-standby);AOSP 層級的 Doze / Lightweight Doze 差異見 [source.android.com — Platform power management with Doze](https://source.android.com/docs/core/power/platform_mgmt)。) + +部分豁免(使用者手動加入電池最佳化白名單)也只放開網路與 partial wake lock,jobs/syncs/鬧鐘照樣延遲。可查 `isIgnoringBatteryOptimizations()`。 + +### 對本專案的含意 + +Android 上「App 在背景、Timer 繼續跑」只在**裝置醒著且進程沒被殺**時成立,完全不可靠。即使播放中的前景服務保住進程,Doze 照樣斷網、忽略 wake lock。所以背景刷新在 Android 只能兩條路:前景(含播放中)跑 Timer,或交給 WorkManager 以 15 分鐘粒度、容忍 Doze 延遲;「恢復後補跑」是必要設計,不是加分項。 + +--- + +## 2. workmanager 套件與 Android 官方建議 + +### 套件現況(查證於 2026-09-27) + +- pub.dev:**0.10.10**,發佈於 **2026-09-07**(verified publisher fluttercommunity.dev)。[pub.dev/packages/workmanager](https://pub.dev/packages/workmanager) +- 平台:**Android、iOS、macOS、Web**;README 提到經由獨立的 `workmanager_linux` 提供實驗性 Linux 支援(未列在 pub.dev 平台 metadata)。**不支援 Windows**。 +- 維護狀態:活躍。GitHub `fluttercommunity/flutter_workmanager` 最近 push 2026-09-07,0.10.9(2026-08-20)→ 0.10.10(2026-09-07)連續發版,open issues 僅 8 個(gh api 查證)。 + +### 硬性限制 + +- **Android 週期任務最小間隔 15 分鐘**:「For Android, periodic tasks have a minimum frequency of 15 minutes」;periodic task 的 `initialDelay` 只是 best-effort hint,不保證首次準時(來源:[flutter_workmanager docs — customization.mdx](https://github.com/fluttercommunity/flutter_workmanager/blob/main/docs/customization.mdx),context7 查證)。 +- **iOS 不支援固定間隔**:`registerPeriodicTask` 的 `frequency` 被忽略,「the system determines if and when a task runs based on battery, device state, and usage patterns. The minimum gap between runs is 15 minutes, but tasks are frequently deferred or skipped entirely」(同上文檔)。iOS 需 `UIBackgroundModes: fetch` + `BGTaskSchedulerPermittedIdentifiers`([quickstart.mdx](https://github.com/fluttercommunity/flutter_workmanager/blob/main/docs/quickstart.mdx))。 +- **Doze 下不準時**:如第 1 節,Doze 期間 WorkManager(底層 JobScheduler)不執行,全部延遲到 maintenance window。 + +### Android 官方對週期性背景工作的建議 + +官方推薦的可延遲、需保證執行的背景工作一律走 WorkManager(Jetpack):它處理 Doze、App Standby bucket、裝置重開機後的持久化,並按約束(網路、充電等)排程。週期工作 `PeriodicWorkRequest` 的最小 repeat interval 即 15 分鐘。來源:[developer.android.com — WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)、[developer.android.com — Optimize for Doze and App Standby](https://developer.android.com/training/monitoring-device-state/doze-standby)。 + +### 對本專案的含意 + +workmanager 是目前仍活躍維護的唯一主流選項,且只做 Android/iOS(macOS/Web 不算本專案場景)——**Windows 不在內**,桌面端要另走「進程活著就跑 Timer」的路線。粒度上接受「至少 15 分鐘、Doze 下更久、iOS 完全由系統決定」:排行榜刷新、歌單刷新這類場景合用;電台輪詢若需要分鐘級以下精度,背景只能放棄,改在前景/播放中做。 + +--- + +## 3. Windows / Linux / macOS 桌面 + +### 最小化時 Dart `Timer` 是否繼續跑 + +**會。** 依 `AppLifecycleState` 官方 dartdoc: + +- `paused`「**This state is only entered on iOS and Android**」,且 paused 時引擎停止 `onBeginFrame`/`onDrawFrame`。 +- 桌面平台視窗最小化或不可見時進入的是 `hidden`(詳見第 5 節),引擎不停止,Dart isolate 與 `Timer` 照常執行。 + +(來源:[api.flutter.dev — AppLifecycleState](https://api.flutter.dev/flutter/dart-ui/AppLifecycleState.html)。桌面平台沒有 Android/iOS 那種「App 進背景即可能被系統暫停/殺掉」的模型,進程只要沒被使用者關掉就一直跑。) + +### OS 層的節流(Windows) + +- **Power Throttling(Win10+)與 Efficiency Mode(Win11, EcoQoS)**會對系統判定為背景的進程降 CPU 頻率/降 QoS 等級;有使用者回報 App 一最小化就被自動套 Efficiency Mode。效果是**變慢而非停止**:Timer 照樣觸發,但排程延遲與執行時間可能拉長,且新版 Windows(25H2)在桌機、插電狀態下也更積極(來源:[Tweaktown — Windows 11 is secretly throttling your apps](https://www.tweaktown.com/guides/11436/windows-11-is-secretly-throttling-your-apps-heres-how-to-catch-it/index.html)、[Microsoft Q&A — Automatically activates efficiency mode](https://learn.microsoft.com/en-us/answers/questions/4011547/automatically-activates-efficiency-mode))。 +- 這是 per-process 的系統策略,App 端無公開 API 保證豁免;媒體播放中的進程因持有 audio session,實務上較不會被判為純背景(推測,無官方來源)。 + +### Linux / macOS + +本次未查到官方文檔級來源。一般桌面模型同 Windows:最小化不暫停進程,Timer 照跑;macOS 的 App Nap 會對隱藏 App 做 timer coalescing(推測,未逐字查證 Apple 文檔,本專案現階段非目標平台)。 + +### 對本專案的含意 + +Windows(及日後 Linux/macOS)上「最小化/縮托盤後繼續跑 Timer」是成立且可靠的,背景刷新可以直接用 Dart `Timer` + Riverpod 實作,不需要任何平台排程器。唯一要注意的是 Efficiency Mode 造成的延遲是**效能問題不是正確性問題**,設計上容忍抖動即可。 + +--- + +## 4. iOS 背景執行 + +### BGTaskScheduler 的性質 + +- 系統決定何時執行,**不保證準時、不保證執行**:「The system decides timing, not the app」;任務會依電量、網路、使用習慣被延遲、節流或跳過(來源:[Apple — Configuring background execution modes](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)、[WWDC25 — Finish tasks in the background](https://developer.apple.com/videos/play/wwdc2025/227):「background execution isn't guaranteed. Instead, it's opportunistic, often discretionary」)。 +- `BGAppRefreshTask`(小刷新)與 `BGProcessingTaskRequest`(長一點、可要求接電源)兩類;實測回報差異極大:Background Fetch 一天可能只有 3–4 次,Processing 常在充電整夜時才被排入([r/iOSProgramming 實測討論](https://www.reddit.com/r/iOSProgramming/comments/1dt7njq/how_often_do_you_get_background_processing_with))。系統會學使用者開 App 的時段,排在使用者快開之前跑([uynguyen.github.io](https://uynguyen.github.io/2020/09/26/Best-practice-iOS-background-processing-Background-App-Refresh-Task))。 + +### Audio background mode + +宣告 `UIBackgroundModes: audio` 且在播放音訊時,App 退到背景**不會被 suspend**,可持續執行:「Typically, an app is in a suspended state when it's in the background. However, there are a limited number of background execution modes … such as playing audio … the system launches or resumes the app, in the background, and affords it time to process any related events」([Apple — Configuring background execution modes](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes))。Apple Developer Forums 上也有實測:正當使用 audio background mode 的 App 在背景持續收到並處理事件,而同時未宣告的 App 已被 suspend([developer.apple.com/forums — Background Tasks](https://developer.apple.com/forums/tags/backgroundtasks))。在此狀態下 Dart isolate 存活、`Timer` 可持續觸發(推論自上述官方行為;無 Flutter 官方文件逐字保證)。注意 Apple 審核會查「宣告 audio 但沒有持續音訊功能」的濫用(同論壇串有 Guideline 2.5.4 拒審案例)。 + +### 對本專案的含意 + +iOS 上唯一可靠的背景窗口是**播放中**(audio background mode):此時 Timer 可用,排行榜/電台/歌單刷新都能跑。非播放時只能交給 BGTaskScheduler(workmanager 的 iOS 端),接受「系統決定、可能一天幾次」的現實——所以「恢復前景/恢復播放時補跑」在 iOS 上是主要路徑而非備援。 + +--- + +## 5. Flutter `AppLifecycleState` 各平台觸發時機 + +狀態定義([api.flutter.dev — AppLifecycleState](https://api.flutter.dev/flutter/dart-ui/AppLifecycleState.html)、[docs.flutter.dev — add AppLifecycleState.hidden 遷移指南](https://docs.flutter.dev/release/breaking-changes/add-applifecyclestate-hidden)): + +| 狀態 | 含意 | 平台差異 | +|------|------|----------| +| `resumed` | 可見且可互動 | 全平台 | +| `inactive` | 可見但無焦點/過渡中(Android 對應 `Activity.onPause` 或 onResume 但無視窗焦點,如來電、分割畫面、PiP) | 全平台 | +| `hidden` | 所有 view 不可見 | Android/iOS:只是 `inactive`↔`paused` 之間的短暫過渡;**桌面(非 web):最小化或所在桌面不可見時的穩定狀態** | +| `paused` | 不可見、不接收輸入,引擎停止 `onBeginFrame`/`onDrawFrame` | **只有 iOS 和 Android 會進入** | +| `detached` | 引擎在跑但沒有 view(如 Android 通知回覆場景) | 各平台零星出現 | + +針對本專案關心的 Windows: + +- **最小化 → `hidden`**(dartdoc 原文:「minimized or placed on a desktop that is no longer visible (on non-web desktop)」)。引擎不停止,Timer 繼續跑。 +- **縮到托盤**(`window_manager` 的 `hide()` 隱藏視窗):視窗不可見,同理落到 `hidden`(推測——與最小化走同一 visibility 路徑;`window_manager` 另有 `WindowListener` 的 `onWindowMinimize` / `onWindowHide` 事件可明確區分兩者,若設計需要分辨「最小化」與「縮托盤」應用這組事件而非 lifecycle)。 +- `window_manager` 現況:**0.5.2**,發佈 2026-07-04,支援 Windows/Linux/macOS,verified publisher leanflutter.dev([pub.dev/packages/window_manager](https://pub.dev/packages/window_manager));托盤搭配 `tray_manager` **0.7.0**(2026-09-19,0.6.x 兩版已被 retract)。 + +### 對本專案的含意 + +跨平台判「要不要跑背景刷新」的單一訊號:`resumed`/`inactive` 一定跑;Android/iOS 的 `paused` 不跑(等 resume 補跑);桌面 `hidden` **繼續跑**。監聽 `AppLifecycleState` 就能涵蓋「離線/背景暫停、恢復補跑」的觸發,桌面目標下不需要額外的視窗事件;要區分最小化與托盤才需要 `window_manager`。 + +--- + +## 6. Riverpod 3 與排程/定時刷新 + +查證版本:riverpod **3.4.3**(2026-09-03,[pub.dev/api/packages/riverpod](https://pub.dev/api/packages/riverpod))。官方文檔([riverpod.dev](https://riverpod.dev),經 context7 查證)沒有獨立的「polling / periodic refresh」食譜頁,但有三個直接對口的官方模式: + +1. **Provider 內開 `Timer` + `ref.onDispose` 取消**([docs/concepts2/refs](https://riverpod.dev/docs/concepts2/refs) 的官方範例): + + ```dart + class Tick extends Notifier { + @override + int build() { + final timer = Timer.periodic(Duration(seconds: 1), (_) => state++); + ref.onDispose(timer.cancel); + return 0; + } + } + ``` + + 間隔本身也可以 `ref.watch(durationProvider)` 讓週期可設定、改變時自動重建 Timer([migration/from_state_notifier](https://riverpod.dev/docs/migration/from_state_notifier) 的範例即如此)。 + +2. **`keepAlive` + `Timer` 的 `cacheFor` 模式**([docs/concepts2/auto_dispose](https://riverpod.dev/docs/concepts2/auto_dispose) 的官方範例):auto-dispose provider 在無人監聽後再保留指定時長,適合「離開頁面後短時間內回來不用重抓」的快取語意: + + ```dart + extension CacheForExtension on Ref { + void cacheFor(Duration duration) { + final link = keepAlive(); + final timer = Timer(duration, link.close); + onDispose(timer.cancel); + } + } + ``` + +3. **`ref.invalidate` / `ref.invalidateSelf`**:強制丟棄狀態、下次讀取時重算,即「立即刷新」與「排程器到點後觸發重抓」的掛鉤點。 + +### 對本專案的含意 + +Riverpod 3 的排程做法就是把 `Timer` 放進 Notifier 的 `build()`、`onDispose` 取消,加上 lifecycle/連線狀態 provider 決定 Timer 的建立與銷毀——例如 watch 一個「是否可跑背景刷新」的 provider(前景/桌面 hidden/播放中/Online),false 時 Timer 根本不建,true 時建立;恢復時用 `invalidateSelf` 補跑一次。這正好疊在第 5 節的 lifecycle 訊號與已定案的 Online/NoInterface/Unreachable 網路狀態上,不需要第三方排程套件介入 Dart 層。 + +--- + +## 套件版本速覽(查證日 2026-09-27,pub.dev API) + +| 套件 | 最新版 | 最後發佈 | 平台 | 維護狀態 | +|------|--------|----------|------|----------| +| `workmanager` | 0.10.10 | 2026-09-07 | Android/iOS/macOS/Web(Linux 實驗性、**無 Windows**) | 活躍:連續發版(0.10.9 於 2026-08-20),open issues 僅 8 | +| `connectivity_plus` | 7.3.1 | 2026-07-23 | Android/iOS/Linux/macOS/Web/Windows | 活躍(plus_plugins 系列,fluttercommunity.dev) | +| `window_manager` | 0.5.2 | 2026-07-04 | Windows/Linux/macOS | 活躍(leanflutter.dev) | +| `tray_manager` | 0.7.0 | 2026-09-19 | Windows/Linux/macOS | 活躍;注意 0.6.0/0.6.1 已 retract | +| `disable_battery_optimization` | 1.1.2 | 2025-08-28 | 僅 Android | 低活動(一年未更新),只作引導使用者關閉電池最佳化的選配 | diff --git a/.trellis/tasks/09-27-design-background-tasks/research/prior-art.md b/.trellis/tasks/09-27-design-background-tasks/research/prior-art.md new file mode 100644 index 000000000..f6107c868 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/research/prior-art.md @@ -0,0 +1,169 @@ +# 背景任務排程 — 先行研究(prior art) + +- 查證日期:2026-09-27 +- 查證方式:WebFetch / gh api 讀 GitHub 原始碼(raw 檔與 code search),未 clone 任何 repo。 +- 涵蓋產品:Finamp、Namida、Spotube、Harmonoid(Flutter);MusicFree(React Native,對照);NewPipe(Android native,對照)。 +- 所有 permalink 均釘在調查當下各 repo 預設分支的最新 commit SHA。 + +--- + +## Finamp(Jellyfin 播放器,Flutter) + +- Repo:https://github.com/finamp-app/finamp(預設分支 `redesign`,SHA `0aae9d5`) +- 背景相關套件([pubspec.yaml](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml)): + - `background_downloader: ^9.2.3`([L29](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L29))— 原生層背景下載 + - `audio_service: ^0.18.18`([L63](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L63))— 背景播放 foreground service + - `connectivity_plus: ^7.0.0`([L143](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L143)) + - **沒有** workmanager / background_fetch / android_alarm_manager_plus / flutter_background_service。 + +**1. 集中排程器?** 沒有。timer 分散在各功能(Discord RPC 15 秒、播放歷史回報、下載總覽 UI 4 秒輪詢等,各開各的 `Timer.periodic`)。真正需要背景的下載整個外包給 `background_downloader` 的原生 service,Dart 側只收狀態更新([downloads_service.dart L190](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service.dart#L190) `FileDownloader().addTaskQueue(...)`)。 + +**2. 背景時刷新是否繼續?** Dart 側不做背景刷新;下載由原生 downloader 繼續。回前景時用 `AppLifecycleListener` 補跑([L290–303](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service.dart#L290):`"App returning from background, restarting downloads."`,且註解寫明「背景超過 5 小時視同重啟,重新 resync」)。啟動時若 `resyncOnStartup` 設定開啟則跑一次 sync([L367](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service.dart#L367))。 + +**3. 離線與網路恢復。** 單一 `network_manager.dart` 統一聽 `Connectivity().onConnectivityChanged`([L34](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/network_manager.dart#L34)),在 `_onConnectivityChange`([L84](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/network_manager.dart#L84))一次處理:auto-offline 模式切換(等 7 秒二次確認避免誤觸發)、local/public server URL 切換、PlayOn 重連、對暫停下載跳 snackbar。連線錯誤連續 10 次會主動暫停下載([downloads_service.dart L351](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service.dart#L351));解除離線模式後呼叫 `restartDownloads()` 補跑([L499](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service.dart#L499))。 + +**4. 使用者可調項目。** `autoOffline`(off / network / disconnected)、`requireWifiForDownloads`、`resyncOnStartup`([downloads_settings_screen.dart L161](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/screens/downloads_settings_screen.dart#L161))。**沒有任何「刷新間隔」設定** — library metadata 沒有定時刷新。 + +**5. 開 App 刷新 vs 定時刷新。** 完全走「開 App 時(可開關的 resync)+ 手動同步按鈕(SyncDownloadsButton)」,不定時。 + +--- + +## Namida(YouTube/本地播放器,Flutter) + +- Repo:https://github.com/namidaco/namida(預設分支 `main`,SHA `e8363db`) +- 背景相關套件([pubspec.yaml](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/pubspec.yaml)): + - `connectivity_plus: ^7.0.0`([L56](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/pubspec.yaml#L56)) + - `audio_service`(git fork,[L124](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/pubspec.yaml#L124)) + - **沒有** workmanager / background_fetch / flutter_background_service;下載也是前景實作(`rhttp`),無背景下載套件。 + +**1. 集中排程器?** 半集中。全 App 只有一個 app 級的定期 timer:`_timeAwareRecheckTimer`,30 分鐘 tick 一次、但距上次未滿 24 小時就直接 return([main.dart L587](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L587) `Duration(hours: 24)`、[L629–630](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L629) `Timer.periodic(const Duration(minutes: 30)...)`、[L645](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L645) due 判斷),tick 到期的話統一跑一批每日級雜務 `_recheckTimeAwareEssentials()`(account 支援資訊、auto-backup、cache trim、版本檢查、intent cache 清理,[L350](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L350))。其餘 timer 仍是分散的(SyncSender、party reconcile、各 UI 進度條等各自開)。 + +**2. 背景時刷新是否繼續?** 不繼續 — Flutter timer 在 isolate 被系統暫停後自然停,Namida 不抵抗這件事,改用回前景補跑:`NamidaChannel.inst.addOnResume(_recheckTimeAwareEssentialsIfDue)`([main.dart L633](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/main.dart#L633))。背景播放靠 audio_service。 + +**3. 離線與網路恢復。** 有單一 `ConnectivityController`([connectivity.dart](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/connectivity.dart)),全 App 共用 `hasConnection` / `hasHighConnection`(還分級成 data-saver 依據)。關鍵設計是 `executeOrRegister`([L93–104](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/connectivity.dart#L93)):有網路就立刻執行,沒網路就登記到 `_onConnectionRestored` 佇列,連線恢復時全部觸發一次後清空 — 例如 `VersionController` 用它延後版本檢查。Linux 上另有 D-Bus portal fallback。 + +**4. 使用者可調項目。** `settings.sync.autoSyncIntervalMinutes`([sync_sender.dart L169](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/sync_manager/sync_sender.dart#L169),`Timer.periodic(Duration(minutes: intervalMinutes))`;`<= 0` 即不建 timer,等於關閉),是少數真的開間隔給使用者的功能。另有 `settings.refreshOnStartup` 開關控制開 App 時是否重建媒體索引([indexer_controller.dart L228](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/indexer_controller.dart#L228))。 + +**5. 開 App 刷新 vs 定時刷新。** 媒體庫走「開 App 時刷新(可開關)+ 手動 refresh 按鈕」;定時只留給每日級維護雜務與使用者明確開啟的裝置同步。 + +--- + +## Spotube(Spotify/YouTube 播放器,Flutter) + +- Repo:https://github.com/team-spotube/spotube(預設分支 `master`,SHA `69a310c`) +- 背景相關套件([pubspec.yaml](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/pubspec.yaml)): + - `connectivity_plus: ^6.1.2`([L25](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/pubspec.yaml#L25)) + - `audio_service: ^0.18.13`([L18](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/pubspec.yaml#L18)) + - **沒有** workmanager / background_fetch / flutter_background_service / 背景下載套件。 + +**1. 集中排程器?** 沒有。全 repo 唯一的 `Timer.periodic` 在 [connectivity_adapter.dart L24](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L24):斷線後每 30 秒主動重探一次。 + +**2. 背景時刷新是否繼續?** 前景才跑。30 秒重探在 `AppLifecycleState.paused` 時直接跳過([L26](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L26));回前景時 `didChangeAppLifecycleState` 立刻重查([L46–47](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L46))。 + +**3. 離線與網路恢復。** 雙層偵測:被動聽 `Connectivity().onConnectivityChanged`([L40](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L40))+ 斷線期間主動輪詢。`_isConnected()` 用實際連線驗證(DNS lookup google.com / baidu.com + Dio HTTPS HEAD fallback + VPN 介面偵測,[L109](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L109)),不只信 OS 回報的介面狀態;結果以 broadcast stream 給消費端([L126](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/connectivity_adapter.dart#L126))。查不到連線恢復後有統一的補跑佇列(推測:由各消費端自行對 stream 反應)。 + +**4. 使用者可調項目。** 查不到任何間隔設定;30 秒是寫死的常數。 + +**5. 開 App 刷新 vs 定時刷新。** 內容刷新(首頁 feed、歌單)查不到任何定時機制 — 走進頁面時載入 / 手動刷新(推測,未找到定期內容刷新的程式碼)。 + +--- + +## Harmonoid(本地檔案播放器,Flutter) + +- Repo:https://github.com/harmonoid/harmonoid(預設分支 `master`,SHA `2b021f7`) +- 背景相關套件([pubspec.yaml](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/pubspec.yaml)): + - `audio_service: ^0.18.18`([L16](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/pubspec.yaml#L16)) + - `media_library`(自家索引套件,[L84](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/pubspec.yaml#L84)) + - **沒有** connectivity_plus、workmanager、任何背景執行套件。 + +**1. 集中排程器?** 沒有,也幾乎沒有 timer — 純本地播放器,沒有需要定期拉的遠端資源。 + +**2. 背景時刷新是否繼續?** 無背景工作可言。媒體庫在 `ensureInitialized` 裡只跑一次:先從 DB 快取載入([filesystem_media_library.dart L95](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/core/filesystem_media_library.dart#L95) `refresh(insert: false, delete: false)`),**只有 library 是空的(首次啟動)才做完整檔案系統掃描**([L99–104](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/core/filesystem_media_library.dart#L99))。 + +**3. 離線與網路恢復。** 不適用 — 沒有 connectivity 監聽,內容全是本地的。 + +**4. 使用者可調項目。** 無間隔設定。 + +**5. 開 App 刷新 vs 定時刷新。** 典型案例:開 App 從快取載入 + 手動刷新按鈕(`lib/features/media_library/media_library_refresh_button.dart`),完全沒有定時刷新。 + +--- + +## MusicFree(插件式播放器,React Native — 對照) + +- Repo:https://github.com/maotoumao/MusicFree(預設分支 `master`,SHA `d118b18`) +- 注意:不是 Flutter,是 React Native。背景相關套件([package.json](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/package.json)): + - `@react-native-community/netinfo`([L27](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/package.json#L27)) + - `react-native-background-timer`([L60](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/package.json#L60))— 但只用於 `delay` 工具與睡眠定時(scheduleClose),**不是**背景排程 + - `react-native-track-player`([L80](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/package.json#L80))背景播放 + +**1. 集中排程器?** 沒有。 + +**2. 背景時刷新是否繼續?** 不繼續;所有「更新」都發生在開 App 時。bootstrap 的 `extraMakeup()`([bootstrap.ts L206–212](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/entry/bootstrap/bootstrap.ts#L206)):若 `basic.autoUpdatePlugin` 開啟且距上次超過 86400000 ms(寫死 24 小時),逐一從來源 URL 靜默重裝啟用中的插件。App 自身更新檢查 `useCheckUpdate` 在 hook 掛載時跑一次([useCheckUpdate.ts L35–39](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/hooks/useCheckUpdate.ts#L35)),尊重使用者跳過的版本。 + +**3. 離線與網路恢復。** NetInfo 包成全域 `Network` 狀態(Offline / Wifi / Cellular,[src/utils/network.ts](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/utils/network.ts)),供各處查詢;查不到連線恢復後的補跑機制(推測:無,下次操作自然重試)。 + +**4. 使用者可調項目。** `basic.autoUpdatePlugin` 開關;間隔寫死 24 小時,不可調。 + +**5. 開 App 刷新 vs 定時刷新。** 完全走「開 App 時 + 距上次超過 threshold」模式,無任何定時。 + +--- + +## NewPipe(YouTube 客戶端,Android native — 對照) + +- Repo:https://github.com/TeamNewPipe/NewPipe(預設分支 `dev`,SHA `7e5df38`) +- 背景相關套件([gradle/libs.versions.toml](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/gradle/libs.versions.toml)): + - `androidx.work:work-runtime` / `work-rxjava3` 2.11.2([L79](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/gradle/libs.versions.toml#L79)、[L110–111](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/gradle/libs.versions.toml#L110)) + +**1. 集中排程器?** 有 — 用系統級 WorkManager。而且全 App 只有**一個**定期背景工作:`NotificationWorker`(訂閱頻道新影片檢查+發通知)。 + +**2. 背景時刷新是否繼續?** 會 — `PeriodicWorkRequest`([NotificationWorker.kt L131](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt#L131))App 關閉也照跑;執行期間掛 foreground notification(`FOREGROUND_SERVICE_TYPE_DATA_SYNC`)。用 `enqueueUniquePeriodicWork` 保證唯一([L140–145](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt#L140),設定變更時 `CANCEL_AND_REENQUEUE`,否則 `KEEP`)。注意:feed 列表本身仍是打開頁面/下拉才刷新,定期工作只用於「通知」這個真有背景需求的功能。 + +**3. 離線與網路恢復。** 不自己寫 — 把網路條件宣告為 WorkManager constraint([L123–127](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt#L123):`NetworkType.CONNECTED`,勾選後升級為 `UNMETERED`),離線時工作自動延後到約束滿足,由系統負責補跑。 + +**4. 使用者可調項目。** 間隔完全開給使用者(`streams_notifications_interval` 設定,[ScheduleOptions.kt L23–26](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/local/feed/notifications/ScheduleOptions.kt#L23)),外加「只在非計費網路執行」開關;設定頁變更後 force reschedule。另有 `runNow()` 單次立即執行([L158](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationWorker.kt#L158))。 + +**5. 開 App 刷新 vs 定時刷新。** 兩者並存但分工明確:內容瀏覽 = 開 App/手動;背景通知 = 系統排程、間隔與網路條件都可調。 + +--- + +## 橫向比較與對本專案的啟示 + +### 集中排程 vs 分散 timer + +- **Flutter 陣營沒有人做真正的集中排程器**。分散的 `Timer.periodic` 是常態(Finamp、Namida 都是十來個各開各的)。 +- 最接近集中式的是 **Namida 的「一個 30 分鐘 tick + 24 小時 due 判斷」**:一個 app 級 timer 統一派發每日級雜務(backup、cache trim、版本檢查),到期才做、沒到期就 return。成本極低、涵蓋面剛好是「不需要準時、但需要定期」的工作。 +- 唯一有系統級集中排程的是 native 的 NewPipe(WorkManager),而且只用在一個功能上。 + +### 背景繼續 vs 前景才跑 + +- **Flutter 播放器一致選「前景才跑」**,沒有任何人用 workmanager / background_fetch 在背景做內容刷新(Finamp、Namida、Spotube、Harmonoid 的 pubspec 都沒有這類套件)。原因顯而易見:Flutter timer 在 isolate 被暫停後本就停跑,與其對抗平台,不如: + 1. **回前景時補跑** — Finamp `AppLifecycleListener` → `restartDownloads()`(背景逾 5 小時視同重啟 resync);Namida `addOnResume` → `recheckIfDue`。 + 2. **記住 due 時間,醒來再判斷** — Namida 的 24h due-check、MusicFree 的 24h plugin 更新,都是「時間到了才做」而非「每 N 時間做一次」,天然容忍 App 被殺。 + 3. **原生層代跑** — 真有背景需求的工作(下載、播放)交給原生 service(background_downloader、audio_service),Dart 側只收事件。 + +### 離線與網路恢復 + +兩種成熟模式: +- **一次性補跑佇列**(Namida `executeOrRegister`):離線時把想做的事登記起來,連線恢復時全部觸發一次後清空。適合版本檢查這類「做過就好」的事。 +- **狀態驅動重啟**(Finamp / Spotube):連線恢復後重啟下載、重查狀態。適合持續性工作。 +- Spotube 額外教訓:OS 的 connectivity 事件不可靠時,斷線期間加一個 30 秒主動輪詢(真打 google.com / baidu.com 驗證)作為補充。 +- 共同點:**connectivity 都是單一 controller 統一管理**(Namida `ConnectivityController`、Finamp `network_manager.dart`、Spotube `ConnectionCheckerService`),沒有人讓各功能各自聽 `connectivity_plus`。 + +### 可調間隔的常見做法 + +- 間隔**只**在真正有定期需求的功能上開放(Namida 裝置同步的分鐘數、NewPipe 通知間隔),且都有「0 / 關閉 = 不排」的語義。 +- 其餘一律是 **threshold 模式**:「開 App / 回前景時,若距上次超過 X 才做」(Harmonoid 首次掃描、MusicFree 24h 插件更新、Namida 24h 雜務、Finamp 5 小時 resync),X 寫死或給個 on/off 開關,很少給自由間隔。 +- 「只在打開 App 時刷新」本身就是常見的正式設計(Namida `refreshOnStartup`、Finamp `resyncOnStartup` 都是使用者可開關的設定項),不是偷懶。 + +### 對本專案(FMP)五項工作的對應建議 + +| 工作 | 各家做法對應 | 建議方向 | +|------|-------------|---------| +| 連線偵測 | Namida / Finamp / Spotube 都是單一 controller | 一個 connectivity controller,提供 `hasConnection` + `executeOrRegister` 式的一次性補跑;不要各功能自聽 | +| 排行榜背景刷新 | 無人做背景刷新;threshold 模式為主流 | 開 App / 回前景時距上次超過 threshold 才刷新,間隔 per-feature 可調、0 = 只手動 | +| 匯入歌單自動刷新 | 同上;MusicFree 插件 24h 模式 | 同上,threshold 模式 | +| 電台直播狀態輪詢 | 播放中 UI timer(Finamp/Namida 慣例) | 前景 timer,功能存活期間才跑;回前景補一次 | +| 快取清理 | Namida 的每日級 due-check | 併入一個 app 級「每日雜務」timer(30 分 tick + 24h due),不單獨開排程 | +| (若未來要背景下載同步) | NewPipe WorkManager / Finamp background_downloader | Android 上才考慮原生排程,且只給真正有背景需求的功能 | + +核心結論:**不對抗 Flutter 背景限制、用「回前景 + due 時間判斷」取代定時背景刷新、connectivity 單一入口、間隔只開給真有定期需求的功能** — 這是五個成熟專案收斂出來的共同答案。 From 4792d63389fca45aab22e393ff189379c861996e Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 19:44:24 +0800 Subject: [PATCH 045/133] chore(task): add design and plan for background tasks --- .../09-27-design-background-tasks/design.md | 77 +++++++++++++++++++ .../implement.md | 10 +++ .../09-27-design-background-tasks/prd.md | 12 ++- 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 .trellis/tasks/09-27-design-background-tasks/design.md create mode 100644 .trellis/tasks/09-27-design-background-tasks/implement.md diff --git a/.trellis/tasks/09-27-design-background-tasks/design.md b/.trellis/tasks/09-27-design-background-tasks/design.md new file mode 100644 index 000000000..150d55cb8 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/design.md @@ -0,0 +1,77 @@ +# 設計:背景任務 + +## 1. 範圍:什麼算背景任務 + +**會發網路請求、按時間重複做的工作**才歸本設計的排程器管: + +| 工作 | 間隔來源 | +|---|---| +| 首頁排行刷新 | 使用者設定 | +| 匯入歌單自動刷新 | 每張歌單各自設定 | +| 電台直播狀態 | 使用者設定 | +| 收聽電台時的直播間資訊 | 固定 1 分鐘,只在收聽中 | + +其他工作不進排程器,各有歸屬: + +- 播放位置檢查與存檔:本機、播放需要,第 13 項。 +- 下載排程與進度:事件驅動,第 11 項(舊版每 5 秒的備援輪詢不帶過去)。 +- 快取淘汰:寫入時觸發(ADR 0016);log 輪替:寫入時觸發(ADR 0011)。 +- 更新檢查與插件更新:只手動(第 19 項、ADR 0014);B 站 Cookie 刷新:第 12 項(B4)。 +- DNS 偵測:刪除(B10、ADR 0016)。 +- 評論自動翻頁:純 UI 動畫,留在元件內。 + +一次性的啟動維護工作(例如舊更新檔清理、下載狀態整理)登記在同一個「啟動維護清單」,第一個畫面出來後依序跑一次,細節由各自的設計項定。 + +## 2. 排程器 + +- 一個 `BackgroundScheduler`,在 service 層,是週期工作的**唯一擁有者**。功能只登記工作,不自己開計時器。 +- 工作宣告:id、所屬插件(可空)、間隔(`Duration?`,空=關閉)、執行函式。所有登記的工作都需要網路。 +- 每個工作的「上次成功時間」存資料庫(重啟後照算,例如歌單的 24 小時不會因重開 App 而重新起算)。下次到期=上次成功+間隔。 +- 只用**一個計時器**,指向最早到期的工作;到期就跑、跑完重算。沒有工作時不留計時器。 + +## 3. 何時跑(已決定 A:看不見就暫停,全平台一致) + +```mermaid +flowchart TD + E["事件:App 變成可見、網路恢復、設定變更、工作登記或到期"] --> C{"App 可見
    且 Online?"} + C -- 否 --> P["不跑,取消計時器
    進行中的請求跑完但不再開新的"] + C -- 是 --> D["跑所有已到期的工作"] + D --> T["計時器指向下一個最早到期"] +``` + +- 「可見」=`AppLifecycleState.resumed` 或 `inactive`(桌面視窗失焦仍算可見)。`hidden`(桌面最小化、縮到托盤)與 `paused`(手機背景)都暫停。 +- 網路狀態取自 ADR 0016 的 `Online`/`NoInterface`/`Unreachable`,只有 `Online` 會跑。 +- App 啟動就是一次「變成可見」:先顯示快取(ADR 0016),再跑已到期的工作。不需要另設「開 App 時刷新」開關。 +- 不用 `workmanager`:手機背景的刷新不可靠且要另開 JS 執行環境,桌面不支援。 + +## 4. 並行、失敗與取消 + +- 全域同時最多 2 個工作;同一個插件的工作依序執行。網路層的每插件併發上限與最小請求間隔照常生效(ADR 0013)。 +- 匯入歌單一次刷一張(沿用舊版,避免對同一平台連發)。 +- 失敗:網路層已依策略重試(ADR 0013)。排程器對仍失敗的工作退避:1、2、4…分鐘,上限為該工作的間隔。`RateLimited` 帶 `retryAfter` 時以它為準。 + 連續傳輸失敗會讓網路狀態轉成 `Unreachable`,恢復時到期的工作補跑。一套退避,取代舊版五套。 +- 手動刷新(下拉、按鈕)立即跑該工作,不看間隔;離線時顯示離線狀態,不送出(ADR 0016)。 +- 取消:插件停用或移除、榜單在首頁停用(B12)、歌單改成不啟用、間隔設為關閉時,立即移除工作;以代際檢查丟掉已過期的結果,不寫回狀態。 + +## 5. 使用者設定 + +| 設定 | 選項 | 預設 | 變更 | +|---|---|---|---| +| 排行刷新間隔 | 30/60/120/240 分、關閉 | 60 分 | 新增「關閉」(只手動刷新);舊版不能關 | +| 電台狀態刷新間隔 | 關閉/1/3/5/10 分 | 5 分 | 不變 | +| 匯入歌單自動刷新(每張) | 1/6/12/24/48/72/168 小時、不啟用 | 新匯入 24 小時 | 不變 | + +舊設定的值由舊資料匯入原樣帶入(語意相同,ADR 0010「不改使用者設定過的值」)。 + +## 6. 閘門 + +- 單元測試(假時鐘、假生命週期、假網路狀態): + - 看不見時不跑,回到可見時到期的工作各跑一次; + - 離線時不跑,恢復後補跑; + - 只有一個計時器; + - 手動刷新不看間隔; + - 移除或停用後不再跑,且過期結果被丟掉; + - 退避序列與 `retryAfter`; + - 上次成功時間重啟後仍生效。 +- lint `fmp_periodic_timer_owner`:`Timer.periodic`、`Stream.periodic` 只准出現在排程器與播放核心模組(清單由第 13 項定),取代舊 `periodic_timer` static-rule 的登記表。 + 規則依 ADR 0015 的方式寫雙向變異測試,加入 `fmp_lints`。 diff --git a/.trellis/tasks/09-27-design-background-tasks/implement.md b/.trellis/tasks/09-27-design-background-tasks/implement.md new file mode 100644 index 000000000..7de7a11e4 --- /dev/null +++ b/.trellis/tasks/09-27-design-background-tasks/implement.md @@ -0,0 +1,10 @@ +# 執行計畫:第 16 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0017-background-task-scheduler.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: + 各功能自開計時器(舊版)、`workmanager` 系統排程、桌面縮小時繼續跑、每工作各自退避、DNS 輪詢。 +2. ADR 0015:在 lint 表後加一句「後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017)」;ADR 0016 的「之後要注意」把背景刷新的指向改成 ADR 0017。 +3. `phase2-plan.md`:§3 第 16 項標 ✅(ADR 0017);§10 交接段更新,下一項 13 播放核心。 +4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認引用。 +5. `task.py finish`、`task.py archive design-background-tasks --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-background-tasks/prd.md b/.trellis/tasks/09-27-design-background-tasks/prd.md index 9981bc987..b9a913c72 100644 --- a/.trellis/tasks/09-27-design-background-tasks/prd.md +++ b/.trellis/tasks/09-27-design-background-tasks/prd.md @@ -2,7 +2,7 @@ ## 目標 -為 `app/` 定下自動刷新、電台輪詢、清理等週期或背景工作由誰排程、如何取消、App 在背景或離線時的行為。產出 ADR 0017。 +為 `app/` 定下自動刷新、電台輪詢、清理等週期或背景工作由誰排程、如何取消、App 在背景或離線時的行為。產出 ADR 0017。技術設計見 `design.md`,執行步驟見 `implement.md`。 依據:parent `prd.md` 階段二第 16 項;`phase2-plan.md`(B10、B12);ADR 0016 留給本項的「背景刷新排程、離線暫停與恢復後補跑」。 @@ -32,13 +32,17 @@ - 離線狀態與「離線中不發背景請求」(ADR 0016);排行只抓啟用的榜單(B12);不輪詢 DNS(B10)。 - B4(B 站 Cookie 刷新)屬第 12 項;D10(電台未開播與查詢失敗的區分)屬第 2、13 項;下載排程屬第 11 項;播放位置相關計時屬第 13 項。 -## 待決定 +## 決定 -- [ ] App 看不見時,網路型週期工作要不要繼續跑 +1. **一個排程器**擁有所有會發網路請求的週期工作(排行、匯入歌單、電台狀態、收聽中的直播間資訊);其他工作各有歸屬(`design.md` §1)。 +2. **看不見就暫停,全平台一致**(2026-09-27 選 A):只有 App 可見且 `Online` 才跑;回到可見或網路恢復時,到期的工作補跑一次。不用 `workmanager`。 +3. 一個計時器、上次成功時間持久化、全域並行 2、同插件依序、一套退避;手動刷新不看間隔;停用即移除(B12)。 +4. 設定:排行間隔新增「關閉」,其餘沿用;舊值原樣匯入。 +5. lint `fmp_periodic_timer_owner` 取代舊 `periodic_timer` 登記表。 ## 驗收條件 -- [ ] ADR 0017 記錄:排程由誰擁有、工作如何宣告、何時跑與暫停、離線與恢復後補跑、取消、使用者設定、退避。 +- [ ] ADR 0017 記錄決定 1–5 與被否決的方案;內容涵蓋:排程由誰擁有、工作如何宣告、何時跑與暫停、離線與恢復後補跑、取消、使用者設定、退避。 - [ ] 舊的每一項週期與一次性背景工作都有去向。 - [ ] 舊 `periodic_timer` static-rule 的去向(ADR 0015 §6 標給本項)定案。 - [ ] `phase2-plan.md` §3 第 16 項標 ✅ 與 ADR 編號。 From 3a65efc3dfc0788da7489645bdd14d4024b5a0b7 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 22:04:56 +0800 Subject: [PATCH 046/133] docs(adr): 0017 background task scheduler --- .../0015-testing-gates-and-dev-environment.md | 2 + docs/adr/0016-cache-and-offline.md | 2 +- docs/adr/0017-background-task-scheduler.md | 66 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0017-background-task-scheduler.md diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index 6fd5f46c5..dc3c0fe14 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -48,6 +48,8 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 | `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | | `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只在平台層 | + 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017)。 + 每條規則以官方 `analyzer_testing` 做雙向變異測試。`flutter analyze` 目前不顯示插件診斷並回報 No issues (flutter/flutter#193203),所以 CI 跑 `dart analyze --fatal-infos`,並以接線哨兵(暫放違規檔、斷言分析失敗且含規則名)證明規則接上了 `app/`。 3. **預設零聯網**:`app/dart_test.yaml` 對 `live` tag 設 `skip`、以 preset 解除;`app/test/flutter_test_config.dart` 以 diff --git a/docs/adr/0016-cache-and-offline.md b/docs/adr/0016-cache-and-offline.md index 47033a74c..8f8fe5f4a 100644 --- a/docs/adr/0016-cache-and-offline.md +++ b/docs/adr/0016-cache-and-offline.md @@ -55,7 +55,7 @@ NewPipe/Spotube 的圖片快取交給 `cached_network_image` 系列;Android - 好的:快取只有一個位置、一個上限、一個清除;丟掉快取不會掉資料;預取失效不再發生;網址期限跟著插件修,不必發 App;離線時每頁有明確狀態;不再每 15 秒查 DNS。 - 壞的:要自建快取索引與淘汰;圖片接到統一快取庫需要實作 cache manager 介面;每個播放類插件都要正確回報 `expiresAt`。 -- 之後要注意:背景刷新與離線時的暫停、補跑由背景任務的 ADR 定;播放失敗的重試與跳過細節由播放核心的 ADR 定;邊聽邊存、手動離線模式、已下載內容容量管理列在功能凍結待辦。 +- 之後要注意:背景刷新與離線時的暫停、補跑見 ADR 0017;播放失敗的重試與跳過細節由播放核心的 ADR 定;邊聽邊存、手動離線模式、已下載內容容量管理列在功能凍結待辦。 ## 如何確認 diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md new file mode 100644 index 000000000..321f9f719 --- /dev/null +++ b/docs/adr/0017-background-task-scheduler.md @@ -0,0 +1,66 @@ +# 0017 — 背景任務:一個排程器、只在 App 可見且在線時跑、到期補跑 + +- 狀態:已採納 +- 日期:2026-09-27 +- 影響範圍:`BackgroundScheduler`、排行/匯入歌單/電台的刷新、App 生命週期處理、刷新間隔設定、`fmp_lints` + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/current-state.md`,已以程式碼核對)有 11 個 `Timer.periodic`, +各自開、各自取消(登記於 `test/support/periodic_timer_static_rule_test.dart:34-104`)。會發請求的有 DNS 偵測(15 秒)、排行、 +匯入歌單(每 30 分檢查)、電台直播狀態、收聽電台時的直播間資訊。只有電台輪詢在看不見時暫停(`main.dart:347-365`,#95 為減少對 B 站的常駐流量), +其餘背景照跑;沒有任何工作在發請求前看網路狀態;退避有五套各不相同。 + +ADR 0016 定了網路狀態與「離線中不發背景請求」,把排程、暫停與恢復後補跑留給本 ADR。 + +## 考慮過的選項 + +- **各功能自開計時器(舊版)**:否決。暫停、離線、退避、取消各寫一套,而且不一致。 +- **`workmanager` 系統排程讓手機背景也刷新**:否決。Android 最小 15 分鐘、Doze 會延後並斷網,iOS 由系統決定,不支援 Windows; + 還要在背景另開 JS 執行環境跑插件。Finamp、Namida、Spotube、Harmonoid 都沒有這樣做。 +- **桌面最小化或縮到托盤時繼續跑**:否決。與手機行為不一致,常駐請求變多、風控機會變大;回到畫面時補跑就足夠。 +- **每個工作各自退避**:否決,改一套。 +- **DNS 輪詢判斷連線**:否決(B10、ADR 0016)。 + +## 決定 + +1. **範圍**:一個 service 層的 `BackgroundScheduler` 是會發網路請求的週期工作的唯一擁有者:首頁排行、匯入歌單自動刷新、電台直播狀態、收聽中的直播間資訊(固定 1 分鐘)。 + 不歸它管的: + - 播放位置檢查與存檔:播放核心; + - 下載:事件驅動,下載的 ADR 定; + - 快取淘汰(ADR 0016)與 log 輪替(ADR 0011):寫入時觸發; + - 更新檢查與插件更新:只手動; + - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次。 +2. **工作宣告**:id、所屬插件(可空)、間隔(空=關閉)、執行函式。「上次成功時間」存資料庫,重啟後照算。 + 排程器只用一個計時器,指向最早到期的工作。 +3. **何時跑**:只有 App 可見(`AppLifecycleState.resumed` 或 `inactive`)且網路狀態為 `Online`(ADR 0016)時才跑。 + `hidden`(桌面最小化、縮到托盤)與 `paused`(手機背景)一律暫停:取消計時器,進行中的請求跑完,不再開新的。 + 變成可見或網路恢復時,所有已到期的工作各跑一次。App 啟動視同變成可見:先顯示快取,再跑到期的工作。 +4. **並行與失敗**:全域同時最多 2 個工作,同一插件依序;網路層的併發上限與最小請求間隔照常生效(ADR 0013);匯入歌單一次刷一張。 + 仍失敗的工作依 1、2、4… 分鐘退避,上限為該工作的間隔;`RateLimited` 帶 `retryAfter` 時以它為準。 +5. **手動與取消**:手動刷新不看間隔、立即執行(離線時顯示離線狀態)。插件停用或移除、榜單在首頁停用(B12)、歌單改為不啟用、間隔設為關閉時立即移除工作, + 以代際檢查丟掉過期結果。 +6. **設定**:排行刷新間隔 30/60/120/240 分或關閉(新增「關閉」,預設 60 分);電台狀態刷新間隔 關閉/1/3/5/10 分(預設 5 分); + 匯入歌單每張 1/6/12/24/48/72/168 小時或不啟用(新匯入預設 24 小時)。舊值原樣匯入(ADR 0010)。 + +採用的慣例:Finamp、Namida、MusicFree 的「前景才跑、回前景時到期才補」;Namida 的單一連線控制器與恢復後補跑; +Riverpod 3 在 Notifier 內建立計時器並以 `ref.onDispose` 取消、由生命週期與網路狀態 provider 驅動。 + +## 後果 + +- 好的:一套規則管暫停、離線、退避與取消;看不見時零常駐請求;重啟不會讓刷新間隔重算;新增週期工作只要登記。 +- 壞的:打開 App 的頭幾秒可能看到較舊的排行或歌單;桌面縮到托盤聽歌時,資料要等回到畫面才更新。 +- 之後要注意:播放核心若需要自己的計時器,把模組加進 `fmp_periodic_timer_owner` 的允許清單;下載的背景執行由下載的 ADR 定。 + +## 如何確認 + +- 單元測試(假時鐘、假生命週期、假網路狀態): + - 看不見與離線時不跑; + - 恢復後到期的工作各跑一次; + - 只有一個計時器; + - 手動刷新不看間隔; + - 移除或停用後不再跑,且丟掉過期結果; + - 退避與 `retryAfter`; + - 上次成功時間重啟後生效。 +- lint `fmp_periodic_timer_owner`(加入 ADR 0015 的 `fmp_lints`):`Timer.periodic`、`Stream.periodic` 只准在排程器與播放核心模組, + 取代舊 `periodic_timer` static-rule 的登記表;依 ADR 0015 寫雙向變異測試。 From fca2e7fff1a6ea0e072092aef567d12d95605397 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 22:04:57 +0800 Subject: [PATCH 047/133] chore(task): archive design-background-tasks --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 10 +++++----- .../tasks/09-27-design-background-tasks/implement.md | 10 ---------- .../2026-09}/09-27-design-background-tasks/check.jsonl | 0 .../2026-09}/09-27-design-background-tasks/design.md | 0 .../09-27-design-background-tasks/implement.jsonl | 0 .../2026-09/09-27-design-background-tasks/implement.md | 10 ++++++++++ .../2026-09}/09-27-design-background-tasks/prd.md | 0 .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../research/prior-art.md | 0 .../2026-09}/09-27-design-background-tasks/task.json | 6 +++--- 11 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 .trellis/tasks/09-27-design-background-tasks/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-background-tasks/task.json (88%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index de3b48adf..1f458d657 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -120,7 +120,7 @@ flowchart LR | 8 | 1 音源插件(✅ 完成,ADR 0014) | 核心抽象;依賴 10、12、2。 | | 9 | 8 測試與開發環境(✅ 完成,ADR 0015) | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | | 10 | 17 快取與離線(✅ 完成,ADR 0016) | 串流 URL、圖片、排行快取的策略,播放核心要用。 | -| 11 | 16 背景任務 | 刷新、清理、更新檢查誰來排程。 | +| 11 | 16 背景任務(✅ 完成,ADR 0017) | 刷新、清理、更新檢查誰來排程。 | | 12 | 13 播放核心 | 最大的一塊;依賴 1、2、10、17。 | | 13 | 14 音樂庫與同步 | B1/B2 已定方向,細節依賴 6、1、12、16。 | | 14 | 11 下載與權限 | 依賴播放核心的本地播放路徑。 | @@ -237,10 +237,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0016`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0017`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 16 項「背景任務」**,task `.trellis/tasks/09-27-design-background-tasks/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 -- 之後順序:13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 13 項「播放核心」(尚未建 task)。 +- 之後順序:14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-27-design-background-tasks/implement.md b/.trellis/tasks/09-27-design-background-tasks/implement.md deleted file mode 100644 index 7de7a11e4..000000000 --- a/.trellis/tasks/09-27-design-background-tasks/implement.md +++ /dev/null @@ -1,10 +0,0 @@ -# 執行計畫:第 16 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0017-background-task-scheduler.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: - 各功能自開計時器(舊版)、`workmanager` 系統排程、桌面縮小時繼續跑、每工作各自退避、DNS 輪詢。 -2. ADR 0015:在 lint 表後加一句「後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017)」;ADR 0016 的「之後要注意」把背景刷新的指向改成 ADR 0017。 -3. `phase2-plan.md`:§3 第 16 項標 ✅(ADR 0017);§10 交接段更新,下一項 13 播放核心。 -4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認引用。 -5. `task.py finish`、`task.py archive design-background-tasks --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-background-tasks/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/check.jsonl diff --git a/.trellis/tasks/09-27-design-background-tasks/design.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/design.md similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/design.md diff --git a/.trellis/tasks/09-27-design-background-tasks/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.md new file mode 100644 index 000000000..c1594e6fc --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/implement.md @@ -0,0 +1,10 @@ +# 執行計畫:第 16 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0017-background-task-scheduler.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: + 各功能自開計時器(舊版)、`workmanager` 系統排程、桌面縮小時繼續跑、每工作各自退避、DNS 輪詢。 +2. [x] ADR 0015:在 lint 表後加一句「後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017)」;ADR 0016 的「之後要注意」把背景刷新的指向改成 ADR 0017。 +3. [x] `phase2-plan.md`:§3 第 16 項標 ✅(ADR 0017);§10 交接段更新,下一項 13 播放核心。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認引用。 +5. [x] `task.py finish`、`task.py archive design-background-tasks --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-background-tasks/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/prd.md diff --git a/.trellis/tasks/09-27-design-background-tasks/research/current-state.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/current-state.md similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/current-state.md diff --git a/.trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/packages-and-platform.md diff --git a/.trellis/tasks/09-27-design-background-tasks/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-27-design-background-tasks/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-background-tasks/task.json b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/task.json similarity index 88% rename from .trellis/tasks/09-27-design-background-tasks/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-background-tasks/task.json index c3cce92e9..b309cbc63 100644 --- a/.trellis/tasks/09-27-design-background-tasks/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-background-tasks/task.json @@ -3,7 +3,7 @@ "name": "design-background-tasks", "title": "Design: background tasks", "description": "Phase-2 item 16: who schedules auto-refresh, radio polling, cleanup and other periodic work; cancellation; behaviour in background and offline", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-27", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From e5d224955503d71efc69129589028fd115170449 Mon Sep 17 00:00:00 2001 From: 1morr Date: Sun, 27 Sep 2026 22:07:50 +0800 Subject: [PATCH 048/133] chore(task): start design-playback-core --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-27-design-playback-core/check.jsonl | 0 .../implement.jsonl | 0 .../tasks/09-27-design-playback-core/prd.md | 19 ++++++++++++++ .../09-27-design-playback-core/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-27-design-playback-core/check.jsonl create mode 100644 .trellis/tasks/09-27-design-playback-core/implement.jsonl create mode 100644 .trellis/tasks/09-27-design-playback-core/prd.md create mode 100644 .trellis/tasks/09-27-design-playback-core/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 1f458d657..3d19d27d4 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -240,7 +240,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0017`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 13 項「播放核心」(尚未建 task)。 +- **進行中:第 13 項「播放核心」**,task `.trellis/tasks/09-27-design-playback-core/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index c33c960f0..c2d10b157 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -30,7 +30,8 @@ "09-27-design-source-plugins", "09-27-design-testing", "09-27-design-cache-offline", - "09-27-design-background-tasks" + "09-27-design-background-tasks", + "09-27-design-playback-core" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-27-design-playback-core/check.jsonl b/.trellis/tasks/09-27-design-playback-core/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-playback-core/implement.jsonl b/.trellis/tasks/09-27-design-playback-core/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/09-27-design-playback-core/prd.md new file mode 100644 index 000000000..55668f3d1 --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/prd.md @@ -0,0 +1,19 @@ +# Design: playback core + +## Goal + +Phase-2 item 13: queue, play modes, playback state machine, audio backend abstraction, stream resolution and expiry, error recovery, system media controls, radio/live exception + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-27-design-playback-core/task.json b/.trellis/tasks/09-27-design-playback-core/task.json new file mode 100644 index 000000000..0ba7100be --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-playback-core", + "name": "design-playback-core", + "title": "Design: playback core", + "description": "Phase-2 item 13: queue, play modes, playback state machine, audio backend abstraction, stream resolution and expiry, error recovery, system media controls, radio/live exception", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 89a9180d07399fe9f399e6d7da8dc15d0c383b92 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:28:26 +0800 Subject: [PATCH 049/133] chore(task): add design-playback-core research and prd draft --- .../tasks/09-27-design-playback-core/prd.md | 65 +++- .../research/current-state.md | 272 ++++++++++++++ .../research/packages-and-platform.md | 156 ++++++++ .../research/prior-art.md | 340 ++++++++++++++++++ 4 files changed, 822 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-27-design-playback-core/research/current-state.md create mode 100644 .trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-27-design-playback-core/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/09-27-design-playback-core/prd.md index 55668f3d1..48c01390c 100644 --- a/.trellis/tasks/09-27-design-playback-core/prd.md +++ b/.trellis/tasks/09-27-design-playback-core/prd.md @@ -1,19 +1,62 @@ -# Design: playback core +# 設計:播放核心(階段二第 13 項) -## Goal +## 目標 -Phase-2 item 13: queue, play modes, playback state machine, audio backend abstraction, stream resolution and expiry, error recovery, system media controls, radio/live exception +為 `app/` 定下佇列、播放模式、播放狀態機、音訊後端抽象、串流解析與網址過期、錯誤恢復、系統媒體控制, +以及電台/直播繞過播放控制器的例外是否保留。產出 ADR 0018。 -## Requirements +依據:parent `prd.md` 階段二第 13 項;`phase2-plan.md`(A5、D1–D10、E12、E13、E19);ADR 0013、0014、0016、0017 留給本項的部分 +(播放層的恢復與跳過、`fmp_periodic_timer_owner` 的播放模組清單);ADR 0015 §6 標給本項的舊 static-rule +(`audio_backend_shared_rules`、`audio_seam`、`playback_event_routing`)。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對,另見 `docs/audit/playback.md`) -## Acceptance Criteria +- `AudioController`(`audio_provider.dart` 2,953 行)已拆出 13 個協作者:`QueueManager`(佇列唯一寫入口)、`PlaybackRequestSession`(請求代際)、 + `PlaybackEventRouter`(純函數,後端事件→23 種動作,唯一判讀失敗的地方)、`PlaybackRecoveryCoordinator`(1/2/4/8/16 秒 ×5)、`PlaybackHandoffGate`、 + `NowPlayingPublisher`(系統媒體控制唯一出口)等。 +- 狀態至少 5 份並存;`PlayerState.error` 一欄承載三種內容(音源訊息、例外 `toString()`、開流失敗文案)。 +- 佇列:四種模式 `queue/temporary/detached/mix`;UI 幾乎所有點歌走臨時播放(D1);隨機為非破壞性索引排列(不持久化); + 「下一首播放」在隨機模式插到隨機位置(`queue_manager.dart:541-547,775-786`);Mix 只增不減、不檢查上限。 +- 兩個後端共用 `FmpAudioService` 介面,**不能收斂的差異寫在介面 dartdoc**(音訊焦點僅 Android、`processingState` 在 Windows 為合成值、`playMedia` 回傳時機不同等); + 可收斂的規則抽成 4 個純檔並有契約測試(`backend_contract_test.dart`)。gapless 以「當前+一個前瞻」清單實作(`next_media_plan.dart`)。 +- 錯誤恢復:只有 unavailable 且 **queue 模式**才 300ms 後跳下一首,**Mix 完全不跳**(`audio_provider.dart:1955`,D3);限流只設錯誤不重試(D5); + 重試次數成功後不歸零;被取代的請求不取消網路工作。 +- 系統媒體控制:Android `audio_service`、Windows `smtc_windows`;音訊焦點與拔耳機只有 Android;SMTC 不支援 seek;服務層反向 import `main.dart` 的全域 handler。 +- 電台是唯一繞過 `AudioController` 直接操作後端的播放者(`radio_controller.dart:286` 起),靠 `isRadioPlaying` 互斥; + 開電台只暫停音樂、不取消進行中的解析(D8 的競態),`restore()` 路徑也不停電台。 +- 其他缺陷:`_navRequestId` 是死碼且與 `.trellis/spec/services/audio.md:70-72` 不一致(不一致);B 站多 P 只取第一個 cid(`bilibili_source.dart:456-473`); + 播放中不檢查網址過期。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- Finamp、Spotube、Harmonoid、Namida 都沒有「臨時播放」模式;佇列真相多半放在原生播放清單、Dart 只投影;「一個介面、兩個後端」只有 Namida 做(Android ExoPlayer、桌面 mpv), + FMP 現有的介面+dartdoc 差異清單是其中最完整的形狀。插播在隨機模式下錯位是共通坑,各家有解法。錯誤跳過只有 Namida 產品化(7 秒倒數)。直播只有 Namida 有 `isLive` 分支。 +- 後端事實(pub.dev,2026-09-27):`just_audio` 0.10.6、`audio_service` 0.18.19、`audio_session` 0.2.4(均 2026-06,活躍;無 Windows/Linux); + `media_kit` 1.2.6(2025-12 最後發版,repo 2026-08 仍活躍),Windows/macOS/iOS 的 libs 停在 2023-09;`smtc_windows` 1.1.0;Linux 用 `audio_service_mpris`。 + media_kit **不內建任何系統整合**(通知、音訊焦點、SMTC、MPRIS、Now Playing 都要自接),Android APK 每個 ABI 約 +3MB。 + just_audio 在 Android 有 gapless、`AndroidEqualizer`/`AndroidLoudnessEnhancer`(對應待辦的均衡器與響度)、`HlsAudioSource`。 +- **研究更正**:研究稱 ExoPlayer 不支援 FLV;官方支援格式表列 FLV 為「YES,不可 seek」(developer.android.com/media/media3/exoplayer/supported-formats,2026-09-28 查證), + 與舊版 Android 能播 B 站直播一致。兩方案都能播 HLS 與 FLV 直播。 +- 桌面沒有 `audio_session`,音訊焦點與拔耳機在桌面兩方案都不支援,不構成差異。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向(先前的勾選) + +D1 點歌=臨時播放;D2 歌單「全部」只加入佇列;D3 Mix 與佇列統一「不可播放就自動跳過」;D4 網易試聽標示並依設定跳過; +D5 限流由網路層退避、播放多次失敗才跳過並提示;D6 開流成功記歷史、單曲循環每圈記;D7 隨機模式行為保留;D8 開電台時取消正在載入的音樂; +D10 區分「未開播」與「查詢失敗」;E12 電台、E13 Mix、E19 速度/音量/輸出裝置保留(均衡器、響度、睡眠定時器在待辦); +ADR 0013 的呈現表:無法取得/找不到「播放時跳過並提示」。 + +## 待決定 + +- [ ] A5:Android 用 just_audio+桌面 media_kit,還是全平台 media_kit +- [ ] 其餘待逐一確認 + +## 驗收條件 + +- [ ] ADR 0018 記錄:後端選擇與介面、佇列與播放模式、狀態模型、串流解析與過期、錯誤恢復與跳過、系統媒體控制、電台/直播、播放模組的計時器與 lint。 +- [ ] D1–D10、E12、E13、E19 各自對到決定;ADR 0015 §6 標給本項的三支舊 static-rule 有去向。 +- [ ] `phase2-plan.md` §3 第 13 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 下載(第 11 項);歌詞與桌面歌詞視窗(第 15 項);播放器 UI 版面(第 5 項);均衡器、響度、睡眠定時器、邊聽邊存(待辦)。 diff --git a/.trellis/tasks/09-27-design-playback-core/research/current-state.md b/.trellis/tasks/09-27-design-playback-core/research/current-state.md new file mode 100644 index 000000000..5d1faf351 --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/research/current-state.md @@ -0,0 +1,272 @@ +# 舊播放核心的真實形狀(current state) + +- 查證日期:2026-09-28(repo 分支 `docs/audit`,HEAD `e5d22495`,2026-09-27 22:07) +- 查證方式:只讀原始碼。沒有跑 App、沒有跑 `flutter test`、沒有打真實 API。 + - 直接核對的檔案:`lib/services/audio/*`、`lib/providers/audio/*`、`lib/services/radio/*`、`test/services/static_rules/*`、`test/support/audio_provider_size_static_rule_test.dart`、`test/ui/static_rules/watch_scope_static_rule_test.dart`、`.trellis/spec/services/audio.md`。 + - 行為面的細節大量沿用 `docs/audit/playback.md`(同一分支、純程式碼層級證據、附 `檔案:行號`)。凡轉引該檔的地方在段末標「(audit)」,本文另抽樣核對了其中約 30 條行號與敘述。與 audit 不同或本文新增的判斷另行註明。 + - 標「**推測**」的是從程式碼推導出、未實機重現的行為;查不到的直接寫「查不到」。 + +--- + +## 1. 元件與責任 + +`lib/services/audio/` 35 檔 11,930 行、`lib/providers/audio/` 5 檔 806 行、`lib/services/radio/` 3 檔 1,604 行(`docs/audit/architecture.md:86,77,96`)。 + +### 1.1 對外/頂層 + +| 元件 | 檔案:行數 | 責任 | 不擁有什麼(dartdoc 明示) | +|---|---|---|---| +| `AudioController`(`Notifier`) | `audio_provider.dart`:2,953 行,約 125 方法 / 41 欄位 | UI 唯一的播放入口;投影 `PlayerState`、transport 命令、套用路由後的動作 | 不宣告 provider;不管後端事件的分類(見 §4) | +| `QueueManager` | `queue_manager.dart`:866 行 | 純佇列邏輯與持久化;**從不操作播放器** | 不做投影、不動後端 | +| `PlaybackRequestSession` | `playback_request_session.dart`:882 行 | 發 requestId;跑 `start` / `restore`;回 `PlaybackSessionResult` | 不碰 `PlayerState` | +| `FmpAudioService`(抽象) | `audio_service.dart`:127 行 | 後端契約;**後端差異寫在每個成員的 dartdoc** | 音訊焦點/中斷不屬共同契約(Android 專屬) | +| `PlaybackHandoffGate` | `playback_handoff_gate.dart`:315 行 | 閂存「控制器正在投影哪一次請求」+延後 seek;**不是第二個計數器** | 不碰 `PlayerState`、不執行 seek | + +### 1.2 協作者(`AudioController` 拆出來的) + +| 元件 | 檔案:行數 | 責任 | +|---|---|---| +| `PlaybackEventRouter` | `playback_event_router.dart`:546 行,27 型別 | 純函數:後端事件 + `PlaybackEventContext` → **一個** `PlaybackAction`(sealed,23 個變體)。唯一允許拆 `PlaybackEndReason` 的地方 | +| `PlaybackRecoveryCoordinator` | `playback_recovery_coordinator.dart`:477 行 | 重試階梯(`maxRetries = 5`,1/2/4/8/16 秒)與世代防競態;timer 可注入 | +| `BufferStarvationWatchdog` | `buffer_starvation_watchdog.dart`:62 行 | 「一直緩衝沒人喊失敗」的兜底;**只升級成一次失敗,不停播不重解析** | +| `PlaybackSideEffect` + registry | `playback_side_effects.dart`:269 行 | 廣播 track started / state changed / stopped(播放歷史、歌詞自動比對、通知列) | +| `NowPlayingPublisher` | `now_playing_publisher.dart`:324 行 | 通知列/SMTC 的唯一出口;在音樂與電台之間仲裁 owner | +| `AudioStreamManager` → `StreamResolutionService` | `audio_stream_manager.dart`:176 行 / `stream_resolution_service.dart`:619 行 | Track → `PreparedPlaybackMedia`(local / remote);解析、快取、音質降級 | +| `QueueCommands` / `QueuePersistenceManager` / `QueueStateNotifier` | 136 / 138 / 93 行 | 佇列寫入的唯一入口/落盤/UI 投影 | +| `TemporaryPlayHandler` | `temporary_play_handler.dart`:113 行 | 臨時播放開始前「佇列停在哪」的快照;**不擁有播放模式、不啟動播放** | +| `MixSessionCoordinator` | `mix_session_coordinator.dart`:345 行 | Mix(YouTube RD 播放清單)的補歌與持久化 | +| `PlayHistoryRecorder` / `LyricsAutoMatchCoordinator` | 54 / 89 行 | 播放歷史寫入 / 歌詞自動比對 | +| `EffectivePlaybackState` | `effective_playback_state.dart`:54 行 | 純函數:「控制器正在載入而後端說 idle」→ 改報 loading、位置報 0 | +| 後端 | `just_audio_service.dart`:718 行 / `media_kit_audio_service.dart`:1,017 行 | 見 §5 | + +規則:協作者以回呼回報、**絕不碰 `PlayerState`**(`.trellis/spec/services/audio.md:21-22`);每個佇列寫入都經 `_emitQueueState`(同上 `:24`,慣例非閘門)。 + +### 1.3 混合職責的檔案(`audio_provider.dart` 之外) + +- `audio_playback_types.dart`:1 行,只有 `enum PlayMode { queue, temporary, detached, mix }`。 +- `mix_playlist_types.dart`:10 行,只有 `MixTracksFetcher` typedef + re-export。 +- `playback_capabilities.dart`:73 行,`PlaybackCapabilities`(`music` 全開 / `none` / `liveRadio` = `none`),由 `NowPlayingPublisher` 從**實際綁定的命令**推導(`playback_capabilities.dart:8-12`)。 +- `playback_end_reason_rules.dart`:148 行、`live_edge_seek_policy.dart`:90 行、`next_media_plan.dart`:50 行、`playback_media.dart`:69 行 —— 這 4 檔是**兩後端共用的純規則**(§5.3)。 +- `audio_runtime_platform.dart`:27 行,`mobile`(android/ios)vs `desktop`(windows/linux/macos)二分,`audioRuntimePlatformProvider`。 + +--- + +## 2. 呼叫關係圖 + +點一首歌(一般音樂)的收斂路徑。實線=主要流程,虛線=回報/事件。 + +```mermaid +flowchart TD + UI["UI 頁面"] --> AC["AudioController"] + AC --> TPH["TemporaryPlayHandler(只存快照)"] + AC --> QC["QueueCommands"] + AC --> PRS["PlaybackRequestSession"] + PRS --> RCstop["RadioController.stop(若電台在播)"] + PRS --> ASM["AudioStreamManager(PlaybackRequestStreamAccess)"] + ASM --> SRS["StreamResolutionService"] + SRS --> AUTH["SourceAuthContext.authForPlay"] + SRS --> SRC["音源 adapter getAudioStream"] + ASM --> BE["FmpAudioService 後端"] + BE -. "playerStateStream / endReasons / advancedToNext" .-> ROUTER["PlaybackEventRouter(純函數)"] + ROUTER -. "PlaybackAction" .-> AC + AC --> QM["QueueManager"] + AC --> HG["PlaybackHandoffGate(延後 seek)"] + AC --> SE["PlaybackSideEffect registry"] + SE --> NPP["NowPlayingPublisher"] + NPP --> AH["FmpAudioHandler Android 通知"] + NPP --> SMTC["WindowsSmtcHandler SMTC"] + BE -. "直接呼叫 playUrl / stop / seekToLive" .-> RADIO["RadioController(刻意例外)"] + RADIO --> NPP +``` + +- 兩個 `Notifier` 共用**同一個後端實例**:`AudioController` 用 `ref.read(audioServiceProvider)`(檔內 13 個 `ref.read`、2 個 `readOptional`、0 個 `watch`,`audio_provider.dart:175-206`),`RadioController` 用 `ref.watch`(`radio_controller.dart:286`)。 +- UI 直接 import `services/audio` 只有 8 次(`architecture.md:265`),所有播放 UI 走 `AudioController`;`FmpAudioService` 在 `lib/ui/` grep 無結果(`architecture.md:43`)。 + +--- + +## 3. 佇列模型 + +- 本體在 `QueueManager`:`_tracks`、`_currentIndex`、`_shuffleOrder`、`_shuffleIndex`(`queue_manager.dart:21-34`)。`AudioController` 不存佇列,只投影成 `QueueState`(`queue_state.dart:17-29`,12 欄位)。 +- `PlayMode` 四態:`queue / temporary / detached / mix`(`audio_playback_types.dart:1`)。`detached` 表示「正在播的歌不在佇列裡」(清空佇列後)。 +- **臨時播放**(App 主流程):搜尋、歌單詳情、首頁、排行、歷史、已下載、匯入預覽全部走 `playTemporary`(`playback.md` §1.2)。語意(`temporary_play_handler.dart:31-67`):不改佇列、記下 index/位置/是否在播、`persist: false`(解析結果不落盤);已在臨時模式時**保留最早那份快照**。播完或按上下首走 `_returnToQueue`,依「記住播放位置」載回原位置並倒退 `tempPlayRewindSeconds`,**原本在播才自動播**。 +- **隨機**(非破壞性):開啟時產生索引排列、當前曲放第一位(`queue_manager.dart:753-767`);`getNextIndex` / `getPreviousIndex` 沿排列走(`324-375`)。破壞性 `shuffle()` / `restoreOrder()` 存在(`616-664`):`shuffleQueue` 有呼叫端(佇列頁打亂鈕,`lib/ui/pages/queue/queue_page.dart:323`),**`restoreOrder` 無任何呼叫端**(`playback.md` §4.5)。 +- **下一首播放**:`addNext` → `insert` → `_addToShuffleOrder`,後者把新索引插在當前位置之後的**隨機**位置(`queue_manager.dart:541-547, 775-786`)。**推測**:隨機模式下「下一首播放」不會是下一首,非使用者預期(audit §3.1)。 +- **Mix 補歌**:每首開始時若剩餘 ≤ 1 首就在背景補(`mix_session_coordinator.dart:145-169`);最多試 10 次、間隔 1 秒、湊到 10 首新歌才停、`seenVideoIds` 去重(`192-330`)。Mix 佇列**只增不減**,走 `addAll` 不檢查 `maxQueueSize`(`queue_manager.dart:500`)。**推測**:長時間 Mix 佇列與記憶體持續長(audit §3.11,未量)。 +- **持久化**:`PlayQueue` 存 `trackIds`、`currentIndex`、`lastPositionMs`、`lastVolume`、`isShuffleEnabled`、`loopMode`、`originalOrder`、Mix 身分(`queue_persistence_manager.dart:78-128`)。位置每 10 秒存一次(`app_constants.dart:54`,`positionSaveInterval`),seek 後立即存。**隨機排列不持久化**,重啟重生成(`queue_manager.dart:210-212`)。 +- 加入上限:只有 `add` 檢查 `maxQueueSize = 10000`(`queue_manager.dart:472`,`app_constants.dart:35`);`addAll` / `insert` **不檢查**(audit §3.1)。 +- Mix 模式下 `add / addAll / addNext / shuffle` 被 `QueueCommands` 擋下(`queue_commands.dart:52-123`)。 +- 啟動 10 秒後刪除「不屬任何歌單、也不在佇列」的 Track 列(`queue_manager.dart:224-227, 830-843`)。 + +--- + +## 4. 播放狀態機 + +### 4.1 狀態欄位與誰能寫 + +狀態**至少 5 份**(audit §0):後端快取欄位、`PlayerState`、`QueueState`、`QueueManager` 內部索引、系統媒體控制狀態(電台另有 `RadioState`)。 + +- `PlayerState`(`player_state.dart:12-59`)21 欄:`isPlaying / isBuffering / isLoading / processingState / position / duration / bufferedPosition / speed / volume / playingTrack / error / retryAttempt / isNetworkError / isRetrying / nextRetryAt / currentBitrate / currentContainer / currentCodec / currentStreamType / audioDevices / currentAudioDevice`。`currentTrack` 是 `playingTrack` 的 getter(`:86`)。 +- `processingState` 列舉:`idle / loading / buffering / ready / completed`(`audio_types.dart:2-17`)。 +- 寫入者:`_startSessionLoadingState`、`_exitLoadingState`、`_projectPlayerState`、`_applyRecoveryState`、`_apply`(路由動作套用)、`play()` / `togglePlayPause()` 的 catch(`playback.md` §2.1 逐項列出)。 +- `error` 同時承載三種內容:音源錯誤訊息、例外 `toString()`、開流失敗文案(audit §4.4);`togglePlayPause` 見到 `error != null` 就重播當前曲(`audio_provider.dart:517-523`)。 +- **投影修正**:`EffectivePlaybackState.from`(`effective_playback_state.dart:23-47`)—— 控制器載入中而後端說 `idle` 就改報 `loading`;載入中位置一律報 0。這條過去只套用在 Android 通知列,Windows SMTC 收的是後端原始值(同檔 `:9-12`)。 + +### 4.2 轉換(使用者可見) + +| 從 | 到 | 觸發 | +|---|---|---| +| Idle | Loading | `playTemporary` / `playAt` / `next` / `previous` | +| Loading | Playing | session completed 且後端 playing | +| Loading | Loading | 新請求取代舊請求(superseded) | +| Loading | RetryScheduled | 網路/逾時類 `SourceApiException` 或 Dart Socket/Http/Tls/Timeout | +| Loading | SourceError | unavailable/geo/vip 且**非** queue 模式,或其他音源錯誤、`PlaybackTimeoutException` | +| Loading | Loading(300ms 後 `next()`) | unavailable 且 **queue 模式**有下一首 | +| Loading | TerminalErr | 開流錯誤 2 秒內沒自癒 | +| Playing | Buffering → Loading | 連續緩衝 15 秒第一次救援;同首第二次 → TerminalErr | +| Playing | RetryScheduled | `TransportFailed`(播放中)/`EndedPrematurely` | +| Paused | Dropped(記號,UI 仍 Paused) | `TransportFailed`(暫停中) | +| RetryScheduled | Loading | 計時到 1/2/4/8/16 秒 | +| RetryScheduled | RetryExhausted | 第 5 次仍失敗 | +| Playing | Playing | gapless 交界,後端自己接上(後端發 `advancedToNext`) | +| Playing | Paused | 佇列播完 `PauseAtQueueEnd` | + +完整狀態圖見 `docs/audit/playback.md` §2.2(`stateDiagram-v2`,含每一條的證據行號)。轉換的**決策**全部由 `PlaybackEventRouter` 產生 `PlaybackAction`,控制器只做一次 exhaustive `switch` 套用副作用(`.trellis/spec/services/audio.md:31-37`)。 + +### 4.3 競態防護 + +- **請求代際**:`PlaybackRequestSession` 用單調遞增 `_requestId`(`playback_request_session.dart:179`);每個 `await` 後 `isSuperseded(requestId)`(`:201`)決定結果是否採用。`cancelActive()` 遞增 id 讓進行中的請求作廢(`:203-206`)。結果四態:`completed / superseded / terminalMediaOpenError / failed`(`:13-125`)。 +- **被取代的請求不會取消網路工作**:`isSuperseded` 只決定結果要不要用,`selectPlayback` 仍跑完,`_withBudget` 的 timeout 也不取消底層 future(`playback.md` §4.2)。快速連點下一首 N 次會有 N 份解析在跑,完成後照樣寫 Isar 與快取。**推測**:真實後果未量。 +- **交接閂存**:`PlaybackHandoffGate` 是 requestId 的閂存副本(`playback_handoff_gate.dart:58-62`);`activeRequestId > 0` = 控制器正在投影一次交接(`:94`)。`isCurrent`(閂存)與 `isRequestSuperseded`(session 世代)**刻意不同、不可互換**(`:97-101`)。 +- **延後 seek**:載入中或穩定化視窗中的 seek 被接下並延後(`:143-195`);穩定化視窗長 `seekStabilizationDelay = 500ms`(`app_constants.dart:63`)。**每一條丟棄路徑都必須 `complete()`**,否則 `seekTo` 的 await 永遠 hang(`:26-35`)。 +- **`_navRequestId` 是死碼**:遞增與比較之間沒有 `await`(`audio_provider.dart:1017-1032, 1050-1070`),不可能不相等;實際防競態靠 session requestId。**與 `.trellis/spec/services/audio.md:70-72` 的「Navigation 有自己的計數器」敘述不一致**(audit §3.1、§4.6)。 +- `MediaKitAudioService._playbackCancelled` 是單一布林、每次開流開頭重設(`media_kit_audio_service.dart:653, 750, 856`)。**推測**:前一次還在 `_ensurePlayback` 迴圈時,新開流可能讓舊迴圈替新媒體呼叫 `play()`(audit §4.2)。 + +--- + +## 5. 兩個後端 + +### 5.1 共同介面 `FmpAudioService`(`audio_service.dart:18-127`) + +Android `JustAudioService`(just_audio → ExoPlayer)/Windows `MediaKitAudioService`(media_kit → libmpv),由 `audioServiceProvider` 依平台選(`providers/audio/audio_controller_provider.dart:26-32`)。介面成員:lifecycle、9 條 stream(`playerStateStream`、`playingStream`、`processingStateStream`、`positionStream`、`durationStream`、`bufferedPositionStream`、`speedStream`、`audioDevicesStream`、`audioDeviceStream`)、**`endReasons`**(單一通道承載正常播完與各種失敗,取代舊的 `completedStream` + `errorStream`)、state getters、transport(`play/pause/stop/togglePlayPause`)、seek(`seekTo` / `seekToLive`)、速度、音量、音訊裝置、開源(`playMedia/setMedia/playUrl/setUrl/playFile/setFile`)、前瞻(`setNextMedia` + `advancedToNext`)。 + +介面 dartdoc 明列**不能收斂的差異**(`audio_service.dart:9-17, 27-30, 35-38, 41-45, 88-96, 112-126`): + +| 面向 | Android | Windows | +|---|---|---| +| 音訊焦點/中斷/拔耳機 | 有(`JustAudioService.initialize`) | **無**,`audio_session` 在 Windows 無 plugin | +| `processingState` | 直譯 ExoPlayer | **合成值**(`completed > buffering > playing→ready > 有duration→ready > idle`,`media_kit_audio_service.dart:449-466`) | +| `bufferedPosition` 量級 | ExoPlayer 本段已緩衝(上限 20 秒) | mpv `cache-secs=7200` 整首一次抓完 | +| 音訊裝置 | 永遠空清單、`setAudioDevice*` 無動作 | 有裝置清單與切換 | +| `playMedia` 回傳時機 | 來源設好就回傳,`play()` 不 await(**回傳 ≠ 出聲**) | 最多等 5 秒到 ready 才 `play()`;0.5 秒仍 idle 丟 `StreamOpenFailedException` | + +### 5.2 gapless 與前瞻 + +`setNextMedia` 的交出去的前瞻媒體由後端自己接(`audio_service.dart:112-126`):Android 往 just_audio 清單 append(`useLazyPreparation: false`,`just_audio_service.dart:148-152`);Windows mpv 清單 append + `prefetch-playlist=yes`(`media_kit_audio_service.dart:250`)。交界時後端發 `advancedToNext`,控制器在 `_onBackendAdvanced` 跟帳。清單不變量「當前項目 + 最多一個前瞻」由純規則 `NextMediaPlan` 算(`next_media_plan.dart:9-49`);兩後端都設了「第二項立刻預備」,留下的項目=一條開著的連線,所以 `shouldTrimPlayedEntry` 要把播完的移掉。 + +### 5.3 共用純規則與契約測試 + +兩後端在 `flutter test` 裡都建不起來(just_audio 要 platform channel、media_kit 要 libmpv),所以「同一份斷言跑在三個後端」是靠抽純函數 + 各後端三行轉呼叫做到的(`backend_contract_test.dart:11-17`): + +| 共用檔 | 內容 | 誰轉呼叫 | +|---|---|---| +| `playback_end_reason_rules.dart` | `classifyCompletion`、`classifyMpvMessage`、`classifyExoPlayerFailure`、`transportKindOf` | 兩個真後端 + `FakeAudioService`(`classifyCompletion`) | +| `live_edge_seek_policy.dart` | `liveEdgeCandidates`(duration → buffered 兩段階梯)、`seekTookEffect` | 三者 | +| `next_media_plan.dart` | `NextMediaPlan.of` / `shouldTrimPlayedEntry` | 兩個真後端(fake 沒有播放清單) | +| `playback_media.dart` | `redactStreamUrl`(串流網址寫 log 的形狀) | 兩個真後端(fake 不寫 log) | + +- 契約測試:`test/services/audio/backend_contract_test.dart`("seekToLive ladder"、"playback end reasons"、"setNextMedia playlist plan"、"the fake answers the same table")。 +- `test/services/audio/next_medium_contract_test.dart` 另有一份前瞻契約。 +- 桌面後端有假引擎接縫 `MediaKitAudioService(platformPlayer:)`(`media_kit_audio_service.dart:21` 附近);`JustAudioService` **沒有**(`.trellis/spec/services/audio.md:59-60`)。 + +### 5.4 各自特有行為(實作層) + +- **Android/just_audio**:`AudioSessionConfiguration.music()`;duck 音量減半、pause/unknown 中斷暫停、pause 類結束且之前在播才自動恢復、`becomingNoisy` 暫停(`just_audio_service.dart:165-213`)。每次開流 `setActive(true)`、**每次 `stop()` 都 `setActive(false)`**,而每次播放請求都以 `stop()` 開場 → 切歌會放掉再搶回焦點。**推測**:其他 App 可能在切歌瞬間短暫恢復播放(audit §3.7)。`isPlaying` 讀 `_player.playing`、`processingState` 讀自己的 BehaviorSubject(`:108, 120-121`),兩者可能描述不同瞬間(**推測**)。可用 `AndroidEqualizer`(見 packages 研究),但本 repo **沒用到**。 +- **Windows/media_kit**:`_configureForAudioOnly` 設 `cache-secs=7200` + `prefetch-playlist=yes`(`media_kit_audio_service.dart:202-250`);輸出裝置可選、偏好裝置存在 Settings,裝置清單首次就緒時套用一次(`audio_provider.dart:1252-1302`)。mpv 只在 **log** stream 報輸出裝置失敗,故 `error` 與 `log` 兩條都訂閱(`.trellis/spec/services/audio.md:61-63`,issue #41/#106)。`OutputDeviceFailed` 只 toast、收回已排的提前結束重試、5 秒內任何 playing 立刻 pause(`playback.md` §3.6)。 +- 兩後端各 4 個開源方法的時長輪詢迴圈幾乎重複(`media_kit_audio_service.dart:738-935`、`just_audio_service.dart:535-652`)(audit §4.1)。 + +--- + +## 6. 串流解析、預取、URL 過期、多 P、音質 + +- 共通:`DefaultStreamResolutionService.resolvePrimary`(`stream_resolution_service.dart:123-168`)—— 先查本機下載檔(同步 `File.existsSync`)→ 讀設定與 `authForPlay` → 行程內 LRU(上限 32)→ 呼叫 adapter(限流等 3 秒重試一次,其他 1 秒)。`_applyStreamResult` 就地寫 URL/到期/cid,視 `persist` 落 Isar(`:420-481`);無 `expiry` 預設 **1 小時**(`:428-430`)。 +- **URL 過期**:`Track.hasValidAudioUrl` 在到期前 5 分鐘即視為無效,但 `audioUrlExpiry == null` **永遠有效**(`track.dart:283-293`)。重取時機三處:每請求經 `resolvePrimary`、暫停後按播放(`_resumeWithFreshUrlIfNeeded`,成功後延遲 500ms seek 回原位)、失敗時 `invalidateResolvedStream`。**播放中不檢查過期**(`seekTo` 無判斷)→ Android 只緩衝 10–20 秒,長曲播到過期後讀的片段會失敗進重試。**推測**(audit §3.3)。 +- **預取**兩層:(1) 下一首 URL 預解析(`prefetch` 不落盤、臨時播放不預取);(2) gapless arm(§5.2)。`_armNextMedia` 條件:不脫離佇列、非單曲循環、電台沒占用、Mix 沒補歌(`audio_provider.dart:1651-1662`)。**觀察**:arm 的 URL 交界時才被讀,中途長暫停可能已過期而控制器沒機會重解析(**推測**)。 +- **音質降級**:`AudioQualityLevel.high/medium/low` 依位元率排序取對應項(`audio_stream_quality_fallback.dart:9-20`);主解析只有 `unavailable` / `vipRequired` 降一級(`:42-67`);開流失敗的 fallback 從低一級開始、每級先問 alternative(`:69-96`),一次請求只 fallback 一次(`playback_request_session.dart:538-589`)。總預算 T1+T2(`PlaybackTimeoutBudget`:解析 25 秒、開流 8 秒、緩衝飢餓 15 秒,`app_constants.dart:195-224`)。 +- **多 P**:Bilibili `_getCid` 只取影片**第一個** cid,`request.pageNum` 在 `getAudioStream` 裡沒被使用(`playback.md` §3.2,`bilibili_source.dart:456-473, 213-241`)。**推測**:帶 `pageNum` 卻沒 `cid` 的 track 會解析到 P1(audit 亦標未確認這種 track 是否存在)。ADR 0005 說分 P 以 cid 區分。 +- 音源特有:B 站 DASH 寫死 `container 'm4a' / codec 'aac'`(`bilibili_source.dart:374-376`)、到期讀 URL `deadline`(缺 2 小時);YouTube 到期**寫死 1 小時**、不讀 URL 的 `expire`(`youtube_source.dart:52-54`,見 packages 研究 D9 待修);網易試聽片段(`freeTrialInfo != null`)只寫 log、照常當完整歌曲回傳(`netease_source.dart:139-150`),**推測**使用者只聽到片段然後跳下一首(D4 待修)。 +- Media 請求 header:只有 CDN Origin/Referer + UA,**不帶帳號憑證**(`source_http_policy.dart:73-84`)。 + +--- + +## 7. 錯誤恢復 + +| 失敗來源 | 處理 | 上限 | +|---|---|---| +| 解析 `SourceApiException` network/timeout、Dart Socket/Http/Tls/Timeout | 退避重試(1/2/4/8/16 秒) | 5 次(`app_constants.dart:230-237`) | +| 解析 unavailable/geo/vip | **queue 模式**且有下一首:300ms 後 `next()`;否則 stop + error | — | +| 解析 rateLimited | 設 error 不重試 | — | +| `PlaybackTimeoutException`(T1/T2 耗盡) | 不進退避、換一次 fallback 串流 | 1 次 | +| 後端 `TransportFailed`(播放中) | stop 後進退避 | 5 次 | +| 後端 `TransportFailed`(暫停中) | 只記號,按播放才重開(`DeferTransportFailureUntilPlay`) | — | +| 後端 `EndedPrematurely` | 從當前位置退避重試 | 5 次 | +| 後端 `MediaUnopenable` / `DecoderFailed` | 等 2 秒,後端自己往前走 ≥ 0.5 秒算自癒,否則 stop | 1 次(`playback_request_session.dart:162-163, 341-406`) | +| 後端 `OutputDeviceFailed` | toast、收回提前結束重試、5 秒內 playing 立刻 pause | — | +| 緩衝飢餓 15 秒 | 第一次 invalidate + `retryPlayback`;同首第二次當作開不起來 | 同首 1 次 | +| `UnclassifiedFailure` | 只記 log、丟棄 | — | + +- 重試次數**不因成功而歸零**:自動重試成功也累計,只有換歌/手動重試/網路恢復才歸零(`playback_recovery_coordinator.dart:140-147`)。世代靠 `_retryGeneration` 防舊計時器(`:157-205`)。 +- 網路恢復由 `connectivityProvider` 發事件自動重試並歸零(`playback.md` §3.6)。 +- **何時跳過**:只有 `unavailable/geo/vip` 且 `mode == PlayMode.queue` 才自動跳下一首;**Mix 模式不跳過**(條件寫死 queue,`audio_provider.dart:1955`)。**推測**不是刻意設計 —— 這條正是已勾選的 D3(Mix 與普通佇列統一「不可播放就自動跳過」)。 +- **`_RetryScheduledException` 只有 `playSingle` 一個明確 catch,而它無 UI 呼叫端**:其餘入口被通用 `catch` 接住,把內部例外的 `toString()` 寫進 `state.error`;`playTemporary` 會顯示「播放失敗」並**立刻恢復原佇列**,而退避計時器仍會在 1 秒後重播那首臨時曲目(audit §3.6,後果部分屬**推測**)。 + +--- + +## 8. 系統媒體控制、耳機鍵、音訊焦點 + +- 唯一出口 `NowPlayingPublisher`(`now_playing_publisher.dart:65-304`),owner 為 `music` 或 `radio`(`enum NowPlayingOwner`,`:17`);非 owner 推送被忽略,電台 `release` 時自動還給音樂(`:131-148`)。按鈕由 `PlaybackCapabilities` 推導(`:257-303`)。 +- **Android**:`audio_service ^0.18.15`,`AudioService.init` 在 `main.dart:172-183`(`androidStopForegroundOnPause: true`、快轉/倒轉 10 秒),失敗退回沒接系統的 `FmpAudioHandler`(`main.dart:186-195`)。`MediaItem.artUri` 用 `track.thumbnailUrl` 網址、`duration` 用 `track.durationMs` 元資料(`audio_handler.dart:75-89`)。 +- **Windows**:`smtc_windows ^1.1.0` 的 `WindowsSmtcHandler`(424 行);metadata 去重(`windows_smtc_handler.dart:12-49`)、封面經 `ThumbnailUrlUtils.getOsMediaArtwork`。**SMTC 不支援 seek**(`now_playing_publisher.dart:283-284`)。 +- 推送時機:每次請求開始先推一次(未解析),成功後再推一次;狀態由投影 + 節流後的位置更新推(位置有 500ms 節流,`audio_provider.dart:2421-2427`)。 +- `now_playing_publisher.dart:7` 從 `main.dart` import 全域 `late` 變數 `audioHandler` / `windowsSmtcHandler` —— 服務層反向依賴 `main.dart`,也是 `architecture.md` §3.5 那個 19 節點大環的成因之一。 +- **耳機鍵**:走 `audio_service` / just_audio 的通知與 media button 路徑(`audio_session` 的 `becomingNoisyEventStream` 只在 Android 被消費,`just_audio_service.dart:194-199` 附近)。**Windows 無耳機拔出事件**,只可能經 mpv `ao` 錯誤進 `OutputDeviceFailed`。 +- **音訊焦點/被電話打斷**:**Android 專屬**(§5.1)。中斷結束時 `JustAudioService` 自己呼叫 `play()`,**繞過** `AudioController.play()` 的 URL 過期檢查(`just_audio_service.dart:194-199`,audit §2.3)。 + +--- + +## 9. 電台/直播 + +- 只支援 Bilibili 直播間(`radio_source.dart:138-156`)。取流 `/room/v1/Room/playUrl` 的 `durl[0]`,`qn=80`,**沒有到期時間**(`bilibili_live_client.dart:272-301`)。 +- **驗證 AGENTS.md 的「Radio 是 FmpAudioService 例外」成立**:`RadioController` 用 `ref.watch(audioServiceProvider)` 拿同一後端(`radio_controller.dart:286`),直接 `playUrl` / `stop` / `seekToLive`(`471, 534, 587, 617, 927, 946`)。`lib/` 中除 audio 自己外只有它碰 `FmpAudioService`。 +- **互斥(對應 D8)**: + - 音樂開始前:session 呼叫 `onPlaybackStarting`,電台有站就 `stop()`(`radio_controller.dart:384-388`)。**`restore()` 路徑不呼叫它**(`playback.md` §3.12)。 + - 電台開始前:只呼叫 `audioController.pause()`(`radio_controller.dart:840-847`),記下音樂 index/位置/是否在播(`:1005-1008`),返回用 `returnFromRadio` 還原(`:564-579`)。 + - 電台占用期間 `isRadioPlaying` 讓控制器忽略後端事件與結束原因(輸出裝置失敗除外)。 +- 電台的「暫停」實際是 `stop()`(`:583-587`)。重連只在後端回報 `completed` 時觸發,先查是否還在直播,是才依 `RadioReconnectConfig` 重連(`:850-958`)。 +- **已勾選的 D8 對應的競態(現況缺陷)**:`radio.play()` 只 `pause()` 音樂,**沒有取消進行中的 `PlaybackRequestSession`**(`radio_controller.dart:843`)。若音樂正在解析串流,解析完成後 `_playSelection` 仍會 `playMedia`,把電台的流換掉,而電台 UI 認為自己在播。**推測**(audit §3.12)。 + +--- + +## 10. 舊 static-rule 守什麼 + +三條在 `test/services/static_rules/`、一條在 `test/ui/static_rules/`;都是「讀原始碼、比集合」而非比字串,且檔內都有雙向變異測試(造違規會紅、無關改名不會紅)。重寫後改用 analyzer lint(phase2-plan §6)時這幾條的**意圖**要接手。 + +| 規則 | 檔案 | 守什麼 | 收窄的介面 | +|---|---|---|---| +| `audio_backend_shared_rules` | `test/services/static_rules/audio_backend_shared_rules_static_rule_test.dart` | (1) 兩個真後端+fake 都真的轉呼叫共用入口(轉呼叫表寫死在 `_delegation`);(2) `lib/services/audio/` 下**不准有第二份關鍵字表**(27 個字串常量,如 `'timed out'`、`'ao:'`),只在 `playback_end_reason_rules.dart` | 防 issue #41 的字串比對長回後端 | +| `audio_seam` | `test/services/static_rules/audio_seam_static_rule_test.dart` | (1) `PlayerState` 與 `QueueState` **零共同欄位**;(2) `PlaybackRequestStreamAccess` 只准有 `selectPlayback` / `selectFallbackPlayback` / `prefetchTrack`;(3) 全域只有 `source_auth_context.dart` 與其 provider 引用寬的 `SourceAuthContext` | 解析內部、認證入口不外洩 | +| `playback_event_routing` | `test/services/static_rules/playback_event_routing_static_rule_test.dart` | 拆 `PlaybackEndReason` 的型樣比對(`switch (reason)` / `case X` / `is X`)**只准出現在 `playback_event_router.dart`**;controller 與 `lib/` 其餘檔案都不准(清單寫死 7 個變體,新增要補一行) | 路由決策單一處 | +| `watch_scope` | `test/ui/static_rules/watch_scope_static_rule_test.dart` | 5 個「狀態很寬、變動頻繁」的 provider 不准整包 `ref.watch`(`audioControllerProvider`、`rankingCacheServiceProvider`、`searchSelectionProvider`、`playlistDetailSelectionProvider`、`downloadProgressStateProvider`);要用 `.select(...)` 或已收窄的衍生 provider | 播放進度每秒更新不該重建整個 widget | + +另有 `test/support/audio_provider_size_static_rule_test.dart`:`audio_provider.dart` 的**程式碼行數**(去空行、去註解)上限 `2184`,雙向棘輪(超過=grew、低於上限 50 行以上=shrank),量法抄 ESLint `max-lines` 的 `skipBlankLines`/`skipComments`。 + +--- + +## 11. 給設計的關鍵事實(不只技術細節) + +1. **主流程是「臨時播放」**:UI 幾乎所有點歌都走 `playTemporary`,佇列只由「加入佇列 / 下一首播放 / Mix」建立。新設計若把「點歌=加入佇列並播」可能反而是行為變更(audit §3.10)。 +2. **狀態 5 份以上、`error` 一欄三義**:`PlayerState` + `QueueState`(已靠 seam 規則切開)+ `QueueManager` 索引 + 後端快取 + 系統媒體控制(audit §2.3、§4.4)。 +3. **單曲循環每圈重開一次流、每圈記一筆歷史**(`audio_provider.dart:2276`、`playback_event_router.dart:465`)。D6 已定調保留,但「每圈是否真的該重解析」是設計選擇。 +4. **電台是唯一繞過 `AudioController` 的播放者**,靠 `isRadioPlaying` + `onPlaybackStarting` 互斥,且 `restore()` 不觸發取消(§9)。 +5. **兩個後端的差異全部集中在 `FmpAudioService` 的 dartdoc**;可收斂的規則已抽成 4 個純檔並有契約測試與 static-rule 釘住(§5.3)。這是重寫時最值得原樣保留的結構。 +6. **錯誤政策分兩族**:解析層走 1/2/4/8/16 秒 ×5 退避;後端層走「自癒窗 2 秒 / 緩衝 15 秒 / 同首救一次」。D5 決定限流退避移到網路層、播放多次失敗才跳過(§7)。 +7. **已下載檔案在播放路徑先於網路檢查**,用同步 `File.existsSync`(§6)—— 新設計若把檔案檢查搬進 drift/非同步要留意這條熱路徑。 diff --git a/.trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md b/.trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md new file mode 100644 index 000000000..b244d4803 --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md @@ -0,0 +1,156 @@ +# 播放核心:套件與平台研究 + +- 查證日期:2026-09-27 +- 查證方式:context7(官方文檔)→ pub.dev API(版本/發佈日期/平台標籤)→ GitHub API(repo 活動、issue)→ tavily-search(補缺)。體積數據為直接下載量測。 +- 範圍:`just_audio`、`media_kit`、`audio_service`、`audio_session`、Windows SMTC、Linux MPRIS、macOS/iOS Now Playing,以及 A5「一個播放介面、每平台一個實作」下的兩方案比較。 + +## 0. 版本與維護狀態一覽(pub.dev 為準) + +| 套件 | 最新版 | 發佈日期 | 平台標籤 | 備註 | +|---|---|---|---|---| +| `just_audio` | 0.10.6 | 2026-06-29 | android, ios, macos, web | Flutter Favorite;**無 windows/linux**。[pub.dev](https://pub.dev/packages/just_audio) | +| `just_audio_background` | 0.0.1-beta.17 | 2025-05-13 | android, ios, macos, web | 仍是 beta 版本線。[pub.dev](https://pub.dev/packages/just_audio_background) | +| `audio_service` | 0.18.19 | 2026-06-29 | android, ios, macos, web | **無 windows**;Linux 靠 `audio_service_mpris`。[pub.dev](https://pub.dev/packages/audio_service) | +| `audio_session` | 0.2.4 | 2026-06-29 | android, ios, macos, web | [pub.dev](https://pub.dev/packages/audio_session) | +| `media_kit` | 1.2.6 | 2025-12-13 | android, ios, macos, windows, linux, web | [pub.dev](https://pub.dev/packages/media_kit) | +| `media_kit_libs_audio` | 1.0.7 | 2025-10-05 | — | 傘套件,依賴下方各平台 libs。[pub.dev](https://pub.dev/packages/media_kit_libs_audio) | +| `media_kit_libs_android_audio` | 1.3.8 | 2025-10-05 | android | [pub.dev](https://pub.dev/packages/media_kit_libs_android_audio) | +| `media_kit_libs_windows_audio` | 1.0.9 | **2023-09-27** | windows | 近三年未發版。[pub.dev](https://pub.dev/packages/media_kit_libs_windows_audio) | +| `media_kit_libs_macos_audio` | 1.1.4 | **2023-09-27** | macos | 近三年未發版。[pub.dev](https://pub.dev/packages/media_kit_libs_macos_audio) | +| `media_kit_libs_ios_audio` | 1.1.4 | **2023-09-27** | ios | 近三年未發版。[pub.dev](https://pub.dev/packages/media_kit_libs_ios_audio) | +| `media_kit_libs_linux` | 1.2.1 | 2025-03-24 | linux | [pub.dev](https://pub.dev/packages/media_kit_libs_linux) | +| `smtc_windows` | 1.1.0 | 2025-08-18 | windows | KRTirtho/frb_plugins 子套件。[pub.dev](https://pub.dev/packages/smtc_windows) | +| `audio_service_mpris` | 0.2.1(stable)/ 1.0.0-beta.2 | 2026-03-15 / 2026-03-26 | linux | audio_service 的 Linux federated 實作;pub points 160/160。[pub.dev](https://pub.dev/packages/audio_service_mpris) | +| `audio_service_win`(第三方) | 0.0.3 | 2026-03-29 | windows | 讓 `audio_service` 可在 Windows 跑。[pub.dev](https://pub.dev/packages/audio_service_win) | +| `just_audio_media_kit` | 2.1.0 | 2025-04-13 | 全平台 | media_kit 後端接 just_audio 介面,供 Linux/Windows 用;unverified uploader。[pub.dev](https://pub.dev/packages/just_audio_media_kit) | +| `media_kit_fork`(第三方) | 0.0.3 | 2025-01-16 | — | azkadev 的 fork,活動低。[pub.dev](https://pub.dev/packages/media_kit_fork) | + +關於「media_kit 約 9 個月沒更新」的核實:**對 pub.dev 發版成立、對 repo 開發不成立**。`media_kit` 主套件最後發版 1.2.6 是 2025-12-13(至查證日約 9.5 個月),但 GitHub repo 持續有 commit,最近到 2026-08-30(`fix: memory leaks (#1446)`),2026-06-27 有 `build(macos, ios): bump libmpv`(尚未發版);open issues 353、open PR 17。[commits](https://github.com/media-kit/media-kit/commits/main)、[repo](https://github.com/media-kit/media-kit)。Windows/macOS/iOS 的 libs 套件則確實停在 2023-09-27,近三年未發版。`ryanheise/just_audio`(stars 1218、open issues 345)、`ryanheise/audio_service`(stars 871、open issues 204)均在 2026-06 有發版與 commit,維護活躍。[just_audio repo](https://github.com/ryanheise/just_audio)、[audio_service repo](https://github.com/ryanheise/audio_service)。 + +## 1. `just_audio` + +### 背景播放 +- 官方方案是 **`just_audio_background`**:`JustAudioBackground.init(...)` 一行接入,涵蓋通知、鎖屏控制、耳機按鍵、智慧手錶、Android Auto、CarPlay;需在 AndroidManifest 宣告 `AudioService`、`MediaButtonReceiver` 與 `FOREGROUND_SERVICE_MEDIA_PLAYBACK` 權限。不需要自己接 `audio_service`。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/README.md) +- 取捨(官方原文):just_audio_background「designed for applications with a single AudioPlayer instance」;多播放器實例或要細粒度自訂通知按鈕時改用 `audio_service`。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/README.md) + +### gapless +- README 功能表:Android gapless ✅;`setAudioSources(playlist)` + `ConcatenatingAudioSource` 支援動態增刪移、shuffle、loop。Web 不支援 gapless。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) + +### 自訂 HTTP header +- `AudioSource.uri(uri, headers: {...})`、`HlsAudioSource(uri, headers: ...)` 都有 `headers` 參數。[context7 / _autodocs/audio-sources.md](https://github.com/ryanheise/just_audio/blob/minor/_autodocs/audio-sources.md) +- 預設走本機 HTTP proxy(`useProxyForRequestHeaders: true` 為預設),因此 Android/iOS/macOS 需開 cleartext;`useProxyForRequestHeaders: false` 改用平台原生 header 實作,但 iOS 無官方 API,依賴未記載的 `AVURLAssetHTTPHeaderFieldsKey`。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) + +### HLS/直播 +- 功能表 HLS:Android/iOS/macOS ✅(Windows/Linux 經桌面後端亦列 ✅);DASH:Android ✅。有 `HlsAudioSource`;`StreamAudioSource` 可自餵 byte stream。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) +- FLV:底層 ExoPlayer 官方支援格式清單(DASH、HLS、SmoothStreaming、progressive containers)**不含 FLV**;HTTP-FLV 直播在 just_audio/Android 端查不到官方支援。[Android Developers: ExoPlayer supported formats](https://developer.android.com/media/media3/exoplayer/supported-formats) + +### 均衡器 +- 內建 `AndroidEqualizer`("An AudioEffect for Android that can adjust the gain for different frequency bands")、`AndroidEqualizerBand`、`AndroidEqualizerParameters`、`AndroidLoudnessEnhancer`;**Android 限定**(README 功能表 Equalizer 僅 Android ✅),走 Android `Equalizer` AudioEffect API 掛在播放 session 上。[pub.dev documentation](https://pub.dev/documentation/just_audio/latest/just_audio/just_audio-library.html)、[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) + +### 桌面 +- Windows/Linux 非內建,README 明列需外加 `just_audio_media_kit`、`just_audio_windows` 或 `just_audio_libwinmedia`。[README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) + +## 2. `media_kit` + +### 維護狀態 +- 見 §0:主套件 ~9.5 個月未發版但 repo 活躍(2026-08 仍在修 memory leak);桌面/行動 libs 發版停在 2023-09(win/mac/ios)與 2025-03(linux)、2025-10(android)。知名 fork 只有低活動的 `media_kit_fork`(2025-01-16,0.0.3)。[pub.dev media_kit_fork](https://pub.dev/packages/media_kit_fork) + +### Android 支援品質 +- README 平台表 Android ✅(Android 5.0+);音訊輸出用 OpenSL ES(`ao: opensles`),API ≤ 25 模擬器直接靜音(`ao: null`)。[README](https://github.com/media-kit/media-kit/blob/main/README.md)、[real.dart](https://github.com/media-kit/media-kit/blob/main/media_kit/lib/src/player/native/player/real.dart) +- **沒有內建背景播放/通知/audio focus**:repo 內查無 audio focus 實作(issue #1099「two players simultaneously」仍 open);iOS 上與 `audio_service` 搭配做背景播放有未能運作的回報(issue #1227,closed 但內文顯示整合困難)。Android 上 media_kit + audio_service 混用有成功案例(同 issue 內文「implemented a mix of media_kit and audio_service working fine on Android」)。[issue #1099](https://github.com/media-kit/media-kit/issues/1099)、[issue #1227](https://github.com/media-kit/media-kit/issues/1227) + +### APK 體積 +- `media_kit_libs_android_audio` 本身不含 .so;build 時由 Gradle 從 GitHub release `libmpv-android-audio-build v1.1.8` 下載各 ABI 的 jar。實測(HTTP content-length,2026-09-27):arm64-v8a 2,983,585 B(≈2.85 MB)、armeabi-v7a 2,865,617 B、x86_64 3,114,935 B、x86 3,040,597 B——**每 ABI 約 +3 MB(壓縮後)**進 APK/AAB。[build.gradle](https://github.com/media-kit/media-kit/blob/main/libs/android/media_kit_libs_android_audio/android/build.gradle)、[release v1.1.8](https://github.com/media-kit/libmpv-android-audio-build/releases/tag/v1.1.8) +- 官方對體積的立場(issue #1089):體積來自 FFmpeg decoder,「the size needs to be this way due to FFmpeg」。[issue #1089](https://github.com/media-kit/media-kit/issues/1089) + +### 自訂 HTTP header +- `Media(url, httpHeaders: {'Foo': 'Bar', ...})` 直接傳入;mpv/FFmpeg 層處理。[README](https://github.com/media-kit/media-kit/blob/main/media_kit/README.md) + +### 直播(HLS/FLV) +- README 支援格式清單(FFmpeg demuxers)含 `hls`、`flv`、`live_flv`(live RTMP FLV)、`dash`、`rtsp`、`rtp`。Bilibili 直播的 HTTP-FLV/HLS 在格式層面有覆蓋;HTTP-FLV 實際播放品質(斷線重連等)未查證。[README](https://github.com/media-kit/media-kit/blob/main/README.md) + +### 均衡器/音訊濾鏡 +- 無內建 EQ API;走 mpv 音訊濾鏡:對 `NativePlayer` 下 `setProperty('af', ...)`(issue #205 使用者以 `af-add`/`af-append` 掛濾鏡,`firequalizer` 在該 build 不存在;issue #570 回報 equalizer 對 FLAC 無效——可用濾鏡集取決於打包的 FFmpeg build)。[issue #205](https://github.com/media-kit/media-kit/issues/205)、[issue #570](https://github.com/media-kit/media-kit/issues/570) +- 內建音量/倍速/音高:`setVolume` / `setRate` / `setPitch`(pitch 需在 `PlayerConfiguration` 啟用)。[README](https://github.com/media-kit/media-kit/blob/main/media_kit/README.md) + +### 桌面系統媒體控制 +- **SMTC(Windows):media_kit 無內建**——repo 程式碼搜尋 `smtc` 無任何結果;需搭配 `smtc_windows`(見 §5)。[gh code search repo:media-kit/media-kit smtc → 0 結果](https://github.com/media-kit/media-kit) +- **MPRIS(Linux):media_kit 無內建**;慣例是搭配 `audio_service_mpris`(見 §6)。 +- **Now Playing(macOS/iOS):media_kit 無內建**——repo 程式碼搜尋 `MPNowPlayingInfoCenter` 無結果。[gh code search](https://github.com/media-kit/media-kit) + +### gapless +- 官方文檔查不到 gapless 相關 API 或宣告;repo issue 搜尋 `gapless` 無結果。mpv 底層有 `--gapless-audio` 選項,(推測)可經 mpv property 傳入,但未查證 media_kit 是否可行。 + +## 3. `audio_service` + +- 現況:0.18.19(2026-06-29),維護活躍(repo 2026-07 仍有 commit)。[pub.dev](https://pub.dev/packages/audio_service) +- 官方定位(README 開頭):包住既有音訊程式碼,提供背景播放+通知、鎖屏、耳機按鍵、穿戴裝置、Android Auto;「It supports Android, iOS, web and Linux (via audio_service_mpris)」。功能表 macOS 通知/control center ✅。**Windows 不在支援列**;issue #609「Add windows support」open;第三方 `audio_service_win`(issue #1138 提及,0.0.3 / 2026-03-29)補 Windows。[README](https://github.com/ryanheise/audio_service/blob/minor/audio_service/README.md)、[issue #609](https://github.com/ryanheise/audio_service/issues/609)、[issue #1138](https://github.com/ryanheise/audio_service/issues/1138) +- 與 `just_audio_background` 的差異:just_audio_background 是 audio_service 之上的零組態封裝,限定單一 `AudioPlayer`;audio_service 直接給 `AudioHandler` 模型,可自訂通知按鈕、多播放器、非 just_audio 後端(例如 media_kit)也能接。[just_audio_background README](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/README.md) +- 注意(README):「this plugin will not work with other audio plugins that overlap in responsibility」(背景播放、通知、鎖屏等職責重疊的外掛不能並存)。[README](https://github.com/ryanheise/audio_service/blob/minor/audio_service/README.md) + +## 4. `audio_session` + +- 現況:0.2.4(2026-06-29),維護活躍。[pub.dev](https://pub.dev/packages/audio_session) +- 音訊焦點:設定 `androidWillPauseWhenDucked`、`androidAudioFocusGainType` 等;他 App(導航、電話)搶焦點時經 `session.interruptionEventStream` 收到 `duck` / `pause` 事件,結束時可 unduck/resume。iOS 對應 `AVAudioSession`。[README](https://github.com/ryanheise/audio_session) +- 耳機拔除:`session.becomingNoisyEventStream`(「Observe unplugged headphones」)。[README](https://github.com/ryanheise/audio_session) +- README 指出:播放外掛本身可能已自動處理 duck/pause 與拔除事件,沒有才自己聽 stream。 + +## 5. Windows SMTC + +- `smtc_windows`:1.1.0(2025-08-18),repo [KRTirtho/frb_plugins](https://github.com/KRTirtho/frb_plugins)(Spotube 作者)最後 push 2025-08-18(與發版同日),open issues 10。Windows 限定。[pub.dev](https://pub.dev/packages/smtc_windows) +- media_kit **不內建** SMTC(§2)。 +- `audio_service` 官方不支援 Windows;第三方 `audio_service_win` 0.0.3(2026-03-29)提供 Windows 平台實作,成熟度的公開資料少(推測:使用者少)。[pub.dev audio_service_win](https://pub.dev/packages/audio_service_win) +- Windows 背景播放的系統要求:不用 MediaPlayer 自動整合時,必須手動接 SMTC(至少啟用 play/pause 並處理 ButtonPressed),否則進背景音訊會停止。[Microsoft Learn](https://learn.microsoft.com/en-us/windows/apps/develop/media-playback/system-media-transport-controls) + +## 6. Linux MPRIS + +- `audio_service_mpris`:stable 0.2.1(2026-03-15),另有 1.0.0-beta.2(2026-03-26);repo [bdrazhzhov/audio-service-mpris](https://github.com/bdrazhzhov/audio-service-mpris) push 2026-03-26,open issues 0,pub points 160/160。是 `audio_service` 的 Linux federated 實作(pub.dev 標籤 `implements-federated-plugin:audio_service_platform_interface`),即沿用 audio_service 的 Dart API、底層播放引擎不限。[pub.dev](https://pub.dev/packages/audio_service_mpris) +- 其他選項:查不到同等成熟的獨立 MPRIS 套件(未逐一窮舉)。 + +## 7. macOS/iOS Now Playing + +- `audio_service`:iOS control center ✅、macOS notifications/control center ✅(README 功能表);just_audio_background 同樣覆蓋 iOS/macOS(含 CarPlay)。[audio_service README](https://github.com/ryanheise/audio_service/blob/minor/audio_service/README.md) +- media_kit 在 iOS/macOS:播放本身 ✅(iOS 9+ / macOS 10.9+),但**不整合 Now Playing**(repo 無 `MPNowPlayingInfoCenter`);iOS/macOS 的 libs 套件停在 2023-09-27(repo 2026-06 有 bump libmpv 未發版);open issue 有 iOS 播放 crash(#627、#1361)。iOS 上要 Now Playing/背景音訊仍需 audio_service 系,且有整合困難回報(issue #1227)。[README](https://github.com/media-kit/media-kit/blob/main/README.md)、[issue #627](https://github.com/media-kit/media-kit/issues/627)、[issue #1227](https://github.com/media-kit/media-kit/issues/1227) + +## 8. 補充:`just_audio_media_kit` 橋接層 + +- 2.1.0(2025-04-13),unverified uploader。用 media_kit 實作 just_audio 的平台介面,讓同一套 `AudioPlayer` API 跑 Windows/Linux。已知限制:shuffleOrder 被忽略、`SilenceAudioSource` 不支援、gapless(`prefetchPlaylist`)標示「highly experimental. Use at your own risk.」。不含 SMTC/MPRIS/背景播放整合。[pub.dev](https://pub.dev/packages/just_audio_media_kit) + +## 9. A5 比較表:全平台 media_kit vs Android just_audio + 桌面 media_kit + +| 面向 | 方案 A:全平台 media_kit | 方案 B:Android just_audio + 桌面 media_kit | +|---|---|---| +| 背景播放(Android) | 無內建;需自接 audio_service(職責重疊限制見 §3;Android 上有成功混用案例)[#1227](https://github.com/media-kit/media-kit/issues/1227)、[#1099](https://github.com/media-kit/media-kit/issues/1099) | just_audio_background 一行接入,官方方案含通知/鎖屏/Auto/CarPlay [README](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/README.md) | +| 系統媒體控制 — Android 通知 | 經 audio_service 自接(同上) | just_audio_background 內建 [README](https://github.com/ryanheise/just_audio/blob/minor/just_audio_background/README.md) | +| 系統媒體控制 — Windows SMTC | media_kit 無內建;搭配 `smtc_windows`(1.1.0/2025-08,活動中)[pub.dev](https://pub.dev/packages/smtc_windows) | 同左(桌面同為 media_kit) | +| 系統媒體控制 — Linux MPRIS | media_kit 無內建;搭配 `audio_service_mpris`(0.2.1/2026-03,160/160 分)[pub.dev](https://pub.dev/packages/audio_service_mpris) | 同左 | +| 系統媒體控制 — macOS/iOS Now Playing | media_kit 無內建(repo 無 MPNowPlayingInfoCenter);iOS 接 audio_service 有困難回報 [#1227](https://github.com/media-kit/media-kit/issues/1227) | Android 端不影響;若未來 iOS/macOS 用 just_audio 則 audio_service/just_audio_background 原生覆蓋 [audio_service README](https://github.com/ryanheise/audio_service/blob/minor/audio_service/README.md) | +| 均衡器 | 無內建 API;mpv `af` 濾鏡,可用濾鏡集依打包 FFmpeg 而定,有失效回報 [#205](https://github.com/media-kit/media-kit/issues/205)、[#570](https://github.com/media-kit/media-kit/issues/570) | Android:內建 `AndroidEqualizer`(Android 限定);桌面仍走 mpv `af` [pub.dev docs](https://pub.dev/documentation/just_audio/latest/just_audio/just_audio-library.html) | +| 直播 — HLS | 支援(FFmpeg `hls`)[README](https://github.com/media-kit/media-kit/blob/main/README.md) | Android:ExoPlayer HLS ✅(`HlsAudioSource`);桌面 media_kit ✅ [README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md) | +| 直播 — HTTP-FLV(Bilibili) | FFmpeg `flv`/`live_flv` 在支援清單 [README](https://github.com/media-kit/media-kit/blob/main/README.md) | Android:ExoPlayer 支援格式**不含 FLV**,需另謀(桌面不受限)[Android Developers](https://developer.android.com/media/media3/exoplayer/supported-formats) | +| APK 體積 | 每 ABI +約 3 MB(libmpv audio build,壓縮後實測)[build.gradle](https://github.com/media-kit/media-kit/blob/main/libs/android/media_kit_libs_android_audio/android/build.gradle)、[release](https://github.com/media-kit/libmpv-android-audio-build/releases/tag/v1.1.8) | Android 端 +0 MB(ExoPlayer 為純 Java/Kotlin);桌面仍帶 libmpv | +| 維護風險 | 主套件 9.5 個月未發版(repo 活躍);win/mac/ios libs 近三年未發版;353 open issues [repo](https://github.com/media-kit/media-kit) | Android 端 ryanheise 系 2026-06 發版、Flutter Favorite;桌面端風險同左,但僅桌面承受 [pub.dev](https://pub.dev/packages/just_audio) | +| 自訂 HTTP header | `Media(httpHeaders:)`,mpv/FFmpeg 層處理 [README](https://github.com/media-kit/media-kit/blob/main/media_kit/README.md) | Android:`headers:` 參數;預設走本機 proxy(需 cleartext),可關 [README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md);桌面 media_kit 同左 | +| gapless | 官方無宣告;mpv `--gapless-audio` 未查證可經 media_kit 使用 | Android:gapless ✅ 官方功能 [README](https://github.com/ryanheise/just_audio/blob/minor/just_audio/README.md);桌面 media_kit 同方案 A | +| 音訊焦點/打斷 | 無內建,需自接 audio_session [#1099](https://github.com/media-kit/media-kit/issues/1099) | Android:just_audio 內建處理(底層用 audio_session);桌面另行處理 [audio_session README](https://github.com/ryanheise/audio_session) | + +## 10. 事實摘要(只列影響決策的硬事實) + +1. `just_audio` 無 Windows/Linux 支援;桌面需 `just_audio_media_kit` 等橋接,其 gapless 標示「highly experimental」。([pub.dev](https://pub.dev/packages/just_audio)、[just_audio_media_kit](https://pub.dev/packages/just_audio_media_kit)) +2. `audio_service` 官方支援 Android/iOS/macOS/web,Linux 經 `audio_service_mpris`(活躍、滿分),Windows 僅有第三方 `audio_service_win`(0.0.3,資料少)。([README](https://github.com/ryanheise/audio_service/blob/minor/audio_service/README.md)) +3. media_kit **完全不內建**系統媒體控制:無 SMTC、無 MPRIS、無 Now Playing、無 Android 通知/audio focus,全部要自接對應套件。(repo 程式碼搜尋、§2) +4. media_kit 主套件 9.5 個月未發版但 repo 2026-08 仍活躍;Windows/macOS/iOS libs 停在 2023-09-27。(§0) +5. media_kit 對 APK 的影響:每 ABI 約 +3 MB(壓縮後,實測 libmpv-android-audio-build v1.1.8 jar)。(§2) +6. Android 均衡器:just_audio 有內建 `AndroidEqualizer`;media_kit 只能走 mpv `af` 濾鏡且有失效回報。(§1、§2) +7. Bilibili HTTP-FLV 直播:media_kit 的 FFmpeg demuxer 清單含 flv/live_flv;ExoPlayer 官方支援格式不含 FLV,just_audio/Android 端查不到 FLV 支援。(§1、§2) +8. HLS 兩方案都支援;just_audio 另有 `HlsAudioSource` 與 DASH。(§1、§2) +9. 自訂 HTTP header:兩邊都支援;just_audio 預設走本機 proxy 需 cleartext 權限(可關),media_kit 直接傳 `httpHeaders`。(§1、§2) +10. Android 背景播放:just_audio_background 是官方一行接入方案(仍為 0.0.1-beta 版本線,最後發版 2025-05-13);media_kit 在 Android 需自接 audio_service,且 audio_service 與「職責重疊」外掛不可並存。(§1、§3) +11. gapless:just_audio Android 官方 ✅;media_kit 官方無 gapless 宣告。(§1、§2) + +## 11. 補漏:`audio_session` 的平台缺席(2026-09-28 補) + +- `audio_session` 的平台標籤只有 android / ios / macos / web(§0 表),**沒有 windows / linux** —— 桌面端不存在這個外掛,因此「duck/pause 中斷、拔耳機事件、`setActive` 語意」在桌面**不是「換一套件」而是要自己接平台 API**(Windows 走 WASAPI session/SMTC、Linux 走 MPRIS 或 PulseAudio/ PipeWire 事件),或直接不做。本 repo 的 `lib/services/audio/audio_service.dart:9-17` dartdoc 已把「音訊焦點為 Android 專屬」寫成後端契約的一部分,兩者一致。 +- 對 A5 表「音訊焦點/打斷」列的影響:兩個方案在**桌面**都是空白,這一列不構成 A 與 B 的差異;差異只在 Android(方案 B 由 just_audio 內建處理)。 +- `just_audio` 本身底層即使用 `audio_session`(§9 該列註記),故選 just_audio 時 `audio_session` 是**傳遞依賴**,不是可選項;選 media_kit 則需自行決定是否引入。 +- 未查證:Windows/Linux 上是否有成熟、活躍的 Flutter 套件能提供 duck/中斷事件(`audio_session` 無桌面實作,其他替代未逐一搜尋)。 diff --git a/.trellis/tasks/09-27-design-playback-core/research/prior-art.md b/.trellis/tasks/09-27-design-playback-core/research/prior-art.md new file mode 100644 index 000000000..9ce37c705 --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/research/prior-art.md @@ -0,0 +1,340 @@ +# 成熟 Flutter 播放器的播放核心(prior art) + +- 查證日期:2026-09-28 +- 查證方式:`git clone --depth 1` 各 repo,逐檔讀原始碼。**沒有跑他們的 App、沒有跑他們的測試、沒有打任何 API。** +- Permalink 一律固定到 clone 當下的 commit SHA(`--depth 1` 的 HEAD),行號範圍以該 SHA 為準。 +- 選樣:Namida(本地優先、功能最廣的同類 App)、Finamp(Jellyfin 客戶端,audio_service 標準路線)、Spotube(與本專案最像 —— 平台服務商串流)、Harmonoid(老牌、桌面優先)。 +- 問題集對齊 `current-state.md`:佇列與狀態建模、臨時/插播、隨機、無限/電台、預取與 gapless、錯誤跳過策略、系統媒體控制、每平台後端、直播處理。 + +--- + +## 1. Finamp + +- repo: +- commit:`0aae9d5ed530ffdf3d62ab12dab4f475a67687dc`(2026-09-26,merge #1709) +- 定位:Jellyfin 音樂客戶端;Flutter/Dart(SDK ^3.9),flutter_riverpod 2.6 + rxdart BehaviorSubject + get_it DI,持久化 hive_ce / isar。 + +### a. 佇列與播放狀態建模 + +- 走 **audio_service 的 `AudioHandler`**:單一類別 `MusicPlayerBackgroundTask extends BaseAudioHandler with SeekHandler, QueueHandler`,直接持有 just_audio `AudioPlayer`,全 app 一個實例。 + [music_player_background_task.dart#L129](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L129)、[#L381](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L381) +- **不是單一 controller,是兩層**:`MusicPlayerBackgroundTask`(transport、媒體通知、fade、音量、media browser)+ `QueueService`(自持佇列語意模型,經 get_it 取 handler)。 + [queue_service.dart#L38](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L38) +- **沒有 enum 狀態機**。狀態就是 audio_service 的 `PlaybackState`(`idle/loading/buffering/ready/completed` + `playing`),由 just_audio `ProcessingState` 一對一映射。 + [music_player_background_task.dart#L1285-L1320](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L1285-L1320) +- 佇列是**四段式**而非單一 list:`_queuePreviousTracks` / `_currentTrack` / `_queueNextUp` / `_queue`;對外快照 `FinampQueueInfo(previousTracks, currentTrack, nextUp, queue)`,每項帶 `QueueItemQueueType`。 + [queue_service.dart#L55-L60](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L55-L60)、[finamp_models.dart#L2431](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L2431) +- **關鍵設計 —— 雙真值 + 單向反推**:just_audio 的 AudioSource 清單與四段 list 並存,靠 `_buildQueueFromNativePlayerQueue()` 從 `sequenceState.effectiveSequence` 反推內部四段;原始碼自承是 just_audio 限制下的產物。 + [queue_service.dart#L185-L285](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L185-L285)、[#L540-L541](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L540-L541) +- 上限 `maxQueueItems` 1500(iOS/macOS)/ 5000(存檔);`maxInitialQueueItems = 1000` 有定義但**無呼叫點**。 + [queue_service.dart#L101-L107](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L101-L107) + +### b. 臨時播放/插播 + +- 三個入口,都收 `PlayableSlice`: + - `addToQueue` — append 到佇列尾。[#L932](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L932) + - `addNext`(Play Next)— 插在當前曲之後,`insertFinampQueueItems(currentIndex + 1, …)`,type = nextUp。[#L967-L1001](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L967-L1001) + - `addToNextUp` — 插到整個 Next Up 區塊尾(offset = `_queueNextUp.length + 1`)。[#L1003-L1039](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1003-L1039) +- 索引換算靠 `getActualIndexByLinearIndex()`:把 shuffle 後的邏輯索引轉回 AudioSource 線性索引。[#L1393](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1393) +- **Next Up 是一次性區塊**:播過之後在反推時被改標成 `formerNextUp` 併入一般 queue。 + [#L203-L250](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L203-L250) +- 沒有「臨時播放」概念(不存在離開佇列播一首再回來的模式);點歌一律進佇列。 + +### c. 隨機(shuffle) + +- 是**索引排列**,不是打散來源清單:用 just_audio fork 的 `_player.shuffleIndices`。[#L162](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L162) +- 以 `ShuffleOrder` 抽象注入:`NextUpShuffleOrder extends ShuffleOrder`,經 `setAudioSources(shuffleOrder: _shuffleOrder)` 傳入。 + [queue_service.dart#L1526](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1526)、[#L828-L834](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L828-L834) +- 巧思:`shuffle()` 先全體洗牌,再把 current + 整個 Next Up 區塊抽出移到最前,**保證插播曲仍緊接當前曲**;`insert()` / `removeRange()` 被覆寫成維護索引偏移。 + [#L1535-L1600](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1535-L1600)、[#L1602-L1675](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1602-L1675) +- 佇列重建分兩種語意:`SliceShuffleState.preShuffled`(自己先洗,順序送播放器)vs `playerShuffled`(交給播放器洗)。[music_slices.dart#L193](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/music_slices.dart#L193) + +### d. 無限/自動電台 + +- 有,功能名 "radio",五種 `RadioMode`:reshuffle / random / similar / continuous / albumMix。[finamp_models.dart#L3791](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L3791) +- 補歌觸發**不是單一定時器**,而是三來源齊發:(1) 每 10 秒 periodic timer、(2) queue stream 每次變動、(3) radioEnabled / radioMode / isOffline / currentUser provider 變動 → 全部呼叫 `maybeAddRadioTracks()`。 + [queue_service.dart#L148-L172](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L148-L172) +- 需求量 `calculateRadioTracksNeeded() = max(10, bufferDuration/2 分鐘) − 未播曲數`。[radio_service_helper.dart#L32-L46](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L32-L46) +- 補歌方式是 `addToQueue(...)` → **append 到尾巴**(非插入)。[#L128-L150](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L128-L150) +- similar / continuous 走 Jellyfin server 端 `/Items/{id}/InstantMix`;continuous 逐首以「上一首」為 seed 迴圈抓,模擬真連續。[#L780-L855](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L780-L855)、[#L514-L550](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L514-L550) +- 防競態:`_radioCacheStateStream` 帶 generating/queueing 旗標 + BehaviorSubject identity 檢查,另有 20 秒內最多 4 次的 rate limit。[#L47-L52](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L47-L52)、[#L67-L80](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/radio_service_helper.dart#L67-L80) +- **佇列播完但 radio 開著時:只 pause + 往回 seek 500ms**,避免觸發 queue-complete 造成整串重置。[music_player_background_task.dart#L790-L811](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L790-L811) + +### e. 預取與無縫播放 + +- **沒有** `ConcatenatingAudioSource`;用 fork 過的扁平 `setAudioSources(list, preload:, shuffleOrder:)`。[#L546-L563](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L546-L563) +- gapless 靠 just_audio playlist 機制;桌面額外靠 `JustAudioMediaKit.prefetchPlaylist = true`(原始碼註解寫 "cache upcoming tracks, enable gapless playback");Android 另要求 `isGaplessSupportRequired: true` 的 offload 設定。 + [#L307](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L307)、[#L388](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L388) +- 緩衝用 `AudioLoadConfiguration`:`minBufferDuration` 90s、`bufferForPlaybackDuration` 5s、re-buffer 後 10s、設定值 `bufferDuration` 600s 作 maxBufferDuration。[#L324-L420](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L324-L420) +- **大型佇列不一次載完**:`PreCachedPlayableSlice`(cachedTracks 先播 + `fetchTracks` future 後補)→ 先 `_replaceWholeQueue(cachedTracks)` 起播,再 `_insertFollowupItems()` 插剩餘曲;插入點有 clamp 保護。 + [music_slices.dart#L130](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/music_slices.dart#L130)、[queue_service.dart#L648-L704](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L648-L704) + +### f. 錯誤跳過策略 + +- **幾乎沒有自動策略**:`AudioPlayer(maxSkipsOnError: 0)`,just_audio 語意為「整個 skip / pause-on-error 機制關閉」。[#L381-L382](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L381-L382) +- `errorStream` 只寫 log(severe),不重試、不跳過。[#L503-L505](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L503-L505) +- `setQueueItems` 只 catch `PlayerException` / `PlayerInterruptedException` → log + `GlobalSnackbar.error`。[#L560-L578](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L560-L578) +- 離線保護:`isOffline == true` 且找不到已下載檔時直接 `Future.error`,避免誤連網。[#L1349-L1360](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L1349-L1360) +- **查不到**播放錯誤 UI、重試或自動跳過(grep `playbackError` / `playerError` / `retry` 全 `lib/` 無結果)。 + +### g. 系統媒體控制 + +- 用 **audio_service**(不是 `just_audio_background`):`AudioService.init(...)`,Android channel `com.unicornsonlsd.finamp.audio`、`preloadArtwork: false`、`StubImageCache`。[main.dart#L430-L465](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/main.dart#L430-L465) +- Android / iOS / macOS 交給 audio_service 內建;Android Auto 另有 `AndroidAutoHelper` 覆寫 media browser 的 `getChildren` / `playFromMediaId` / `search`;iOS 有 `CarPlayHelper`。[#L981-L1130](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L981-L1130) +- **Windows 自寫平台實作**:`AudioServiceSMTC extends AudioServicePlatform` 換掉 audio_service 的 Windows 實作,用 `smtc_windows`(Rust/FRB),play/pause/next/prev/stop/ff/rew 全映射。[audio_service_smtc.dart#L5-L60](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/audio_service_smtc.dart#L5-L60) +- **Linux** 用 `audio_service_mpris` 的 federated plugin(`lib/` 內零引用,靠 pubspec 自動註冊)→ MPRIS。 +- Discord Rich Presence 是獨立一份 `DiscordRpc`,與系統媒體控制無關。 + +### h. 每平台後端 + +- 後端**只有 just_audio 一套**,而且是 fork:`LennartEnns/just_audio_fork`(等 upstream PR #1555,加的就是 queue / `shuffleIndices` 能力)。[pubspec.yaml#L33-L39](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L33-L39) +- **沒有共同介面抽象層**:桌面不是換後端,是換 just_audio 的 *platform implementation* —— `just_audio_media_kit`(又是 fork,`Komodo5197/just_audio_media_kit` 的 `feat/queue-shuffle`)在 Windows/Linux 以 media_kit 為底;Windows 另換成自訂 media_kit fork。[pubspec.yaml#L40-L56](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L40-L56) +- 因此 `AudioPlayer` 的 API 是唯一切面,app 程式碼**完全不感知平台差異**(除設定項)。[music_player_background_task.dart#L381](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L381) +- 串流 URI:轉碼走 HLS `Audio/{id}/main.m3u8`,否則直連 `Items/{id}/File`;token 以 query param 帶。[#L1380-L1437](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/music_player_background_task.dart#L1380-L1437) + +### i. 直播處理 + +- **沒有**。`isLive` 只存在於產生的 Jellyfin DTO,播放路徑零引用;`HlsAudioSource` 只剩一行被註解的可能用法。[jellyfin_models.dart#L1991](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/jellyfin_models.dart#L1991) +- §d 的電台是「無限自動播放清單」,與直播串流是兩件事。 + +### Finamp 最值得借鏡的三點 + +1. **雙真值反推**([queue_service.dart#L185-L285](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L185-L285)):不逃避「播放器有自己的清單」這個現實,而是指定**單一方向**(native → 內部模型)去同步,避免雙向寫入打架。 +2. **NextUpShuffleOrder**([#L1526](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/queue_service.dart#L1526)):把「插播」的語意編進 shuffle 演算法,而不是事後補救 —— 直接解掉本專案 `addNext` 在隨機模式下失效的問題。 +3. **PreCachedPlayableSlice**([music_slices.dart#L130](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/music_slices.dart#L130)):先播已快取的一段、其餘 lazy 補進播放器,是大佇列不必一次灌進播放器清單的作法。 + +--- + +## 2. Spotube + +- repo: +- commit:`69a310c78f5ceaf4eab7dfee98f187d38211c9ba`(5.1.2+45,2026-06-05) +- 定位:Spotify 前端 + 第三方音源(YouTube/Bilibili);Flutter,Riverpod(Notifier + freezed state),持久化 drift,後端 media_kit(作者 KRTirtho 也是 `smtc_windows` 作者)。 +- 核心特色:**本機 shelf HTTP server 當串流代理**,media_kit 播 `http://host:port/stream/`。 +- **本節所有 `path:line` 都可用前綴 `https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/` 解析。** + +### a. 佇列與播放狀態建模 + +- 單一 Riverpod `Notifier`(`lib/provider/audio_player/audio_player.dart:18`)。 +- state 是 freezed class,**只有 6 欄**:`playing / loopMode / shuffled / collections / currentIndex / tracks`(`lib/provider/audio_player/state.dart:8-19`)。 +- **佇列真相在 media_kit 的 `Playlist`**,不是 Dart 端 list;state 只是投影。`build()` 訂閱 media_kit 的 playing/loopMode/shuffled/playlist 四條 stream 回寫 state(`audio_player.dart:104-182`)。 +- 狀態機只是粗粒度列舉 `AudioPlaybackState {playing, paused, completed, buffering, stopped}`(`lib/services/audio_player/playback_state.dart:4-9`),由 `CustomPlayer` 把 media_kit 多條 stream 折成一條 `playerStateStream`(`lib/services/audio_player/custom_player.dart:11-49`)。 +- `collections`=「這條佇列來自哪個 album/playlist」的 id 清單,決定點歌時該 replace 還是 jump(`audio_player.dart:185-218`、`lib/components/track_presentation/use_track_tile_play_callback.dart:71-88`)。 +- 佇列與 loop/shuffle 持久化在 drift 單列表(`lib/models/database/tables/audio_player_state.dart`);啟動 `_syncSavedState()` 回填並 `openPlaylist(autoPlay: false)`(`audio_player.dart:38-91`)。 +- 底層包一層 `AudioPlayerInterface`(getter + command),早年的 just_audio 分支已全被註解(`lib/services/audio_player/audio_player.dart:44-126`、`audio_players_streams_mixin.dart` 整檔)。 + +### b. 臨時播放/插播 + +- `addTracksAtFirst`(語意=插在當前曲後面):對每首 `addTrackAt(SpotubeMedia(track), max(currentIndex,0) + i + 1)`(`audio_player.dart:220-257`);使用者入口是 track options 的 `PlayNext`(`lib/provider/track_options/track_options_provider.dart:166-167`)。 +- 底層 `addTrackAt` → `_mkPlayer.insert(index, media)`(`lib/services/audio_player/audio_player_impl.dart:107-109`)。 +- **關鍵坑**:`CustomPlayer.insert` 不用 media_kit 的 `insert`,而是 `add()` 後等 playlist stream 確認新元素 index、再 `move()` 到位(`custom_player.dart:123-141`);pubspec 註解說明原因是上游 `.move()` after `.add()` 不回應(`pubspec.yaml:148-152`)。 +- 插播不進 `collections`,所以不影響「播放來源」判定。 + +### c. 隨機 + +- 完全交給 media_kit(`setShuffle` → `_mkPlayer.setShuffle`,`audio_player_impl.dart:123-125`;讀值 `_mkPlayer.state.shuffle`,`custom_player.dart:85`);**沒有自製順序表**。 +- next/previous/loop 的邊界直接讀 `_mkPlayer.state.playlist.index` 自己算(`audio_player_impl.dart:67-87`)。 + +### d. 無限/電台式佇列 + +- 有,做成 hook `useEndlessPlayback(ref)` 掛在 app 層(`lib/hooks/configurators/use_endless_playback.dart:9-65`)。 +- 觸發:`currentIndexChangedStream` 的 index 等於 `tracks.length - 1`(進到最後一首)才呼叫 metadata plugin 的 `track.radio(track.id)`(`:20-42`)。 +- 補法:`playback.addTracks(...)`,先 `removeWhere` 掉自己與已在佇列中的重複 id(`:31-38`)。是「**最後一首才補**」,不是滾動視窗預留。由偏好開關控制。 + +### e. 預取與 gapless + +- **預取**:監聽 `positionStream`,進度超過 **80%** 且非最後一首時,先 `await ref.read(sourcedTrackProvider(nextTrack).future)` 把下一首 URL 解析完(`lib/provider/audio_player/audio_player_streams.dart:135-167`);第一首載入時也先 boost 再 `openPlaylist`,避免 media_kit 因 timeout 跳過(`audio_player.dart:366-375`)。 +- 伺服器端磁碟快取:GET 完成後把 `.part` rename 成正式快取檔(`lib/provider/server/routes/playback.dart:217-253`)。 +- **gapless 沒有顯式設定**:`PlayerConfiguration` 只給 title/logLevel/async(`lib/services/audio_player/audio_player.dart:48-54`);media_kit 本身沒有 gapless 屬性(查證 `media_kit` `native/player/real.dart` 只有 `playlist-next` / `eof-reached` / `loop-file`)。接續是 mpv internal playlist 行為,Spotube 只負責「URL 先備好」。 +- buffer 依音質切(無損 6MB / 有損 4MB),寫 `demuxer-max-bytes`、`demuxer-max-back-bytes`(`lib/provider/metadata_plugin/audio_source/quality_presets.dart:49-51`、`custom_player.dart:151-157`);網路 timeout 放寬到 120 秒(`custom_player.dart:24`)。 + +### f. 錯誤跳過/重試 + +- **player 層幾乎沒有策略**:錯誤只送 logger(`lib/services/audio_player/audio_player.dart:55-57`、`custom_player.dart:46-48`);`subscribeToPlayerError` 是空 listener(`audio_player_streams.dart:169-171`)。沒有壞軌自動跳下一首(查不到)。 +- **真正的重試在 shelf 代理層**: + - `track.url == null` → 先 `swapWithNextSibling()` 換下一個候選音源(`lib/provider/server/routes/playback.dart:106-110`,GET 路徑同理 `:159-163`)。 + - HEAD 失敗 → catch 後 `refreshStreamingUrl()` 重解析改打新 URL(`:177-192`)。 + - `refreshStream` 逐一對候選 URL 發 HEAD,只留 status < 400,全掛才重新 `streams()`(`lib/services/sourced_track/sourced_track.dart:254-299`);候選由 YouTube 搜尋結果評分排序(官方標記 + 標題含曲名/藝人加權,`:105-152`)。 + - 換源會覆寫 DB 的 source match,下次直接命中(`:219-238`)。 + +### g. 系統媒體控制 + +- 統一入口 `AudioServices`,依平台建兩個實作(`lib/services/audio_services/audio_services.dart:12-46`)。 +- Android / iOS / macOS / Linux:`audio_service` 的 `AudioService.init`(Linux 走 `audio_service_mpris`);channel id 依 stable/nightly 分(`:24-35`)。`MobileAudioService extends BaseAudioHandler`(`lib/services/audio_services/mobile_audio_service.dart:14`)。 +- Windows:`smtc_windows`(同作者);`WindowsAudioService` 監聽 `buttonPressStream` 分派 play/pause/next/previous/stop,回寫 `setPlaybackStatus` / `setPosition` / `setEndTime` / `updateMetadata`(`lib/services/audio_services/windows_audio_service.dart:10-93`)。 +- **音訊焦點**:`InterruptionEventStream`(duck→降到 0.5 音量;pause/unknown→暫停並記住以恢復)+ `becomingNoisyEventStream`→pause(`mobile_audio_service.dart:22-61`)。 + +### h. 後端與直播 + +- **全平台同一套 media_kit**,不分 Android/桌面:`static const bool _mkSupportedPlatform = true;`(`lib/services/audio_player/audio_player.dart:61`);依平台只差 `media_kit_libs_*_audio` 依賴(Linux 用 full libs,`pubspec.yaml:150-212`)。 +- 專屬 patch 集中 `CustomPlayer`:Android 產生 audio session id、設 `ao=audiotrack,opensles`、廣播 `OPEN_AUDIO_EFFECT_CONTROL_SESSION`(`custom_player.dart:53-83`)。 +- 共同介面切在 `AudioPlayerInterface` + `SpotubeAudioPlayersStreams` mixin(`audio_player.dart:44-126`、`audio_players_streams_mixin.dart:3-150`)。 +- 直播:GET 時若上游 `content-type` 是 HLS → 直接 **301 redirect** 讓播放端吃 m3u8(`playback.dart:194-207`);metadata 層有 `isLive` 欄位但**播放端無任何特判**(查不到)。 + +--- + +## 3. Harmonoid + +- repo: +- commit:`2b021f7b0b5dbcbe027aec010580977a2939a28d`(0.3.34+9045,2026-09-03) +- 定位:本機音樂庫播放器(非線上串流),media_kit 原作者作品;Flutter,狀態管理是 **`ChangeNotifier` 單例 + mixin registry**(不是 Riverpod/Bloc),持久化 drift。 +- **本節所有 `path:line` 都可用前綴 `https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/` 解析。** + +### a. 佇列與播放狀態建模 + +- `final class MediaPlayer extends ChangeNotifier`,`static final instance` 單例(`lib/core/media_player/media_player.dart:40,47`)。 +- 單一 state 物件(freezed,18 欄),含 `index/playables/rate/pitch/volume/shuffle/loop/exclusiveAudio/replayGain/crossfadeDuration/position/duration/playing/buffering/completed/audioBitrate/audioParams/mixOffset`(`lib/core/media_player/models/media_player_state.dart:11-32`)。 +- **佇列真相同樣在 media_kit `Playlist`**:`_player.stream.playlist` → `_applyPlayerPlaylistToState`(`media_player.dart:341, 496-525`)。值得借鏡的細節:用 `_comparePlayableListAndMediaList` 淺比較避免重建(`:527-533`)、重建走 `compute()` 丟 isolate(`:511`)、**只有 uri 換了才重置 position**(`:509, :513-524`)。 +- 大量批次操作時用 `disablePlayerPlaylistUpdates()` / `enablePlayerPlaylistUpdates()` 把回寫關掉再開(`media_player.dart:480-494`)。 +- playback 只持久化子集(去掉 position/duration/playing 等易變欄位,`lib/core/media_player/models/playback_state.dart:11-23`);恢復時逐項重套,**`setShuffle` 必須在 `open` 之後**(`media_player.dart:301-338`)。 +- **平台功能靠 8 個 mixin 由 registry 依平台註冊**(AudioService / AudioSession / DiscordRpc / HistoryPlaylist / LastFm / Mpris / SMTC / WindowsTaskbar,`lib/core/media_player/media_player_mixin_registry.dart:22-36`);介面只有 4 個方法(`lib/core/media_player/mixin/media_player_mixin.dart:10-18`),且每次呼叫都包 `_runCatching` 吞例外(`media_player_mixin_registry.dart:61-68`)。 + +### b. 臨時播放/插播 + +- `insert(index, playable)`:`add()` 後 `move(playlist.medias.length - 1, index + 1)`(`media_player.dart:230-245`),呼叫端傳「當前 index」、函式內部 `+1`。 +- 單曲 play next → `insert(_mediaPlayer.state.index, track)`(`lib/features/media_library/media_library_menus.dart:77-79`)。 +- **多選 play next 用 `disablePlayerPlaylistUpdates()` 包住並反向逐首 insert**,才不會彼此插隊(`media_library_menus.dart:270-275`);insert 後同步修正 `mixOffset`(`media_player.dart:240-244`)。 +- 「add to now playing」是 `add()`(附尾),與插播分開(`media_library_menus.dart:81-83`)。 + +### c. 隨機 + +- **兩套並存**:(1) `setShuffle` 交 media_kit(內部重排 playlist)再回寫 state(`media_player.dart:124-126`);(2) `open(..., shuffle: true)` 是 Dart 端先 `medias.shuffle()` 打亂再 open(`:158-160`),UI 的「隨機播放」走這條(`media_library_menus.dart:266-268`)。 +- `open()` 時一律先 `copyWith(shuffle: false, ...)` 歸零,由呼叫端之後再設(`media_player.dart:169`)。 +- 上/下一首可用性交給 extension `isFirst` / `isLast`(loop=all 時永遠 false,`lib/extensions/media_player_state.dart:11-15`),SMTC/MPRIS/工作列都吃這兩個值。 + +### d. 無限/電台式佇列 + +- 有,叫 **Mix**,補法與電台不同:**在 `open()` 當下就把整個媒體庫打亂接在後面**,不是等播到最後才抓推薦。 +- `open()`:若 `nowPlayingStartMixAfterEnding` 且曲數 < `kMixThreshold`(=100) → `mixOffset = medias.length`,再把整個媒體庫轉 Media 後 `shuffle()` 追加(`media_player.dart:44, 162-167`)。 +- `mixOffset` 是「使用者的歌到哪為止」的分界,move/remove/add/insert 都要維護它(`media_player.dart:179-203` 等)。 +- 開關 `setMix` / `mixOrUnmix`,關閉時把 playlist 裁回 `sublist(0, mixOffset)`;`_mixLock` 防重入(`:128-146`)。**預設 true**(`lib/core/configuration/configuration.g.dart:463`)。 + +### e. 預取與 gapless + +- **沒有 prefetch 實作**(全庫 grep `prefetch` / `preload` / `demuxer` 只命中 drift 產物)。 +- gapless:`PlayerConfiguration` 只有 `title` 與 `pitch`(`media_player.dart:428-433`);同樣靠 mpv internal playlist(**推測**與 Spotube 同機制)。有為接續鋪路的設定:非 iOS 設 `audio-stream-silence=yes`(註解說為了讓 crossfade 順,`:457-461`)、Android `ao=audiotrack,opensles`、iOS `audiounit`、macOS `coreaudio`(`:443-456`)。 +- **Crossfade 是自製 platform player**:把 media_kit 的 `platformPlayer` 換成 `CrossfadePlayer`(雙播放器交叉淡入),預設 5 秒、範圍 2–30 秒(`media_player.dart:41-43, 415-425, 284-299`);與獨佔音訊互斥(`:247-270, :284-292`);切換開關會**整個 dispose + 重建 Player**(`:395-468`)。 + - **查不到**:`CrossfadePlayer` 原始碼在 `lib/private` **submodule(`github.com/harmonoid/private`,私有 repo)**,本次未取得。 +- buffer 無顯式設定(`kKeyMpvOptions` 預設空 map,使用者可自行加 mpv 參數,`configuration.g.dart:458`)。 + +### f. 錯誤跳過/重試 + +- **沒有策略**:`_player.stream.error.listen` 只 `debugPrint`,原本的 `mediaPlayerOnError(e)` 被**註解掉**(`media_player.dart:353-356`);`completed` 只寫進 state 不觸發補救(`:350`)。 +- 唯一韌性是 registry 的 `_runCatching`,把 8 個 mixin 的例外吞掉,避免單一平台整合炸掉播放(`media_player_mixin_registry.dart:61-68`)。 + +### g. 系統媒體控制 + +- 靠 mixin registry 分派,每個平台一個 mixin、各自 `supported` getter: + - Android / iOS / macOS:`audio_service`(`lib/core/media_player/mixin/audio_service_mixin.dart:21-49`);`_AudioServiceImpl extends BaseAudioHandler with QueueHandler, SeekHandler`(`:196`);`skipToQueueItem` → `jump(i)`(`:241`)。 + - Windows SMTC:`system_media_transport_controls` 套件,`supported => Platform.isWindows`(`system_media_transport_controls_mixin.dart:20-93`);套件本身來自自家 submodule(`pubspec.yaml:103-104`)。 + - Linux:`mpris_service`(`mpris_mixin.dart:22-70`)。Windows 工作列縮圖按鈕另用 `windows_taskbar`(`:19-86`)。 + - 加碼:Discord RPC、Last.fm scrobble、history playlist。 +- **值得借的去重模式**:每個 mixin 持一組 `_flag*` 欄位,只在值真的變了才推更新(position 容差 1 秒),並用 `Lock` 序列化(`audio_service_mixin.dart:70-175`、`mpris_mixin.dart:90-153`)。 +- 音訊焦點:`audio_session` mixin **只註冊 Android/iOS**(macOS 沒有,`audio_session_mixin.dart:19-48`);中斷恢復較粗暴(begin→pause、end→play,無 duck)。`play()`/`pause()` 另外手動 `setActive`,註解說明為何不在 `notifyState` 做(iOS index 切換時會炸,`audio_session_mixin.dart:60-69`)。 + +### h. 後端與直播 + +- 後端同樣 media_kit,釘在 git ref `c533e446755f51cf53c7e57aea873f2aa5355f81`(`pubspec.yaml:54-84`);平台只差 libs(Linux 用 full)。 +- Android 與桌面**同一套 Player API**,差異只在建立時的 `platformPlayer` / `configuration` 與 `ao` 屬性(`media_player.dart:411-434, 443-456`)。共同介面切成三層:`MediaPlayer`(facade)+ `MediaPlayerMixin`(平台整合)+ `Playable`(模型)。 +- **直播沒有處理**:無 `isLive`、無 duration==0 特判、無 HLS/續傳邏輯(查不到);HTTP URI 甚至被標為未完成(`history_playlist_mixin.dart:44` 的 `// TODO: Add support for HTTP URIs`)。mpv 本身能播,但 App 層不管。 + +--- + +## 4. Namida + +- repo: +- commit:`e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5`(2026-09-26) +- 定位:Flutter 音樂播放器(Android / Windows / Linux / iOS / macOS),多來源(YouTube、Bilibili、本地檔、Jellyfin)。狀態管理是作者自製的 **nampack**(類 GetX 的 `.obs` / `Rx` / `Obx`),不是 riverpod / bloc。 +- **證據限制(重要)**:播放引擎的基底類別 `BasicAudioHandler` 來自套件 `basic_audio_handler`,**該 repo 不公開**(`gh api repos/namidaco/basic_audio_handler` → 404,本次獨立複核確認)。因此 shuffle 演算法、gapless 機制、`CustomAudioPlayer`、`PlayerRepeatMode` 的定義**查不到原始碼**,只能由 namida 端呼叫點推論 —— 這些地方在本節標「推測」。 +- **本節所有 `path:line` 都可用前綴 `https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/` 解析。** + +### a. 佇列與播放狀態建模 + +- 三層 facade:`Player`(單例)→ `NamidaAudioVideoHandler extends BasicAudioHandler`(真正的引擎,[audio_handler.dart#L69](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L69))→ `AVPlayer` 後端。 +- **沒有自寫狀態機**;就是 just_audio 的 `ProcessingState`(idle/loading/buffering/ready/completed),mpv 後端把 mpv 狀態映射進同一組枚舉(`lib/class/custom_mpv_player.dart:73, :210`)。 +- 佇列模型:持久化的 `Queue`(`lib/class/queue.dart`);記憶體播放清單由套件內 `BasicAudioHandler.currentQueue` 持有(推測為 `Rx>`)。 +- **多個 controller 分工**:`QueueController.inst`(持久化佇列,`lib/controller/queue_controller.dart:32`,`Rx>`)、`Player.inst`(facade,`lib/controller/player_controller.dart`)、`SMTCController.instance`、`ArtworkPrefetcher.inst`;彼此靠 nampack 的 Rx 監聽串接(`audio_handler.dart` constructor,[#L106-L213](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L106-L213))。 + +### b. 臨時播放/插播 + +- 臨時播放叫 **`gentlePlay`**:「插到下一首再跳過去」,**不取代佇列但會改佇列內容** —— 兩行 `await addToQueue(queue, insertNext: true, showSnackBar: false); await next();`,doc 註解寫「add items next and play them instead of assigning them as a new queue」([player_controller.dart#L815-L832](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/player_controller.dart#L815-L832))。 +- play-next 家族:`insertNext` / `insertAfterLatest` + `latestInsertedIndex`(`:155`)、`moveToNext`(`:563`)、`moveToAfterLatestInserted`(`:569`)、`moveToLast`。 +- `addToQueue(...)`(`:494-551`)把「往哪插」與「插什麼」都參數化(`QueueInsertionType` / `insertNext` / `insertAfterLatest` / `withLimit(maxCount)`)。 +- `createTempPlayer(...)`(`:987`)另建一個一次性 player。 + +### c. 隨機 + +- **是索引排列,不是打散原清單**,且分兩層: + 1. `settings.player.shuffleQueue` → 實體置換佇列順序,原順序另存 `originalIndices`(`originalIndices[i]` = 排在第 i 位者在原始清單的索引);**排列寫進持久化二進位檔**(`_QueueSerializer` 有 `_kFlagOriginalIndices` / `_kOriginalIndex = 'o'`)。 + [queue_controller.dart#L167-L168](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/queue_controller.dart#L167-L168)、[\#L406-L411](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/queue_controller.dart#L406-L411) + 2. `PlayerRepeatMode.shuffle` / `allShuffle`(播放順序,**查不到**定義)。 +- UI 入口 `Player.shuffleTracks(bool allTracks)`(`player_controller.dart:478-486`)。 + +### d. 無限/電台式佇列 + +- **沒有真正的自動無限補歌**。最接近的兩件: + 1. YouTube 自動電台 `tryAddingMixPlaylist(videoId)`,條件是 `settings.youtube.autoStartRadio` **且 `currentQueue.length == 1`** → 只在「單曲起播」時自動補一次,抓 mix playlist 後 `addToQueue`([audio_handler.dart#L1815-L1845](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L1815-L1845))。 + 2. `infiniyQueueOnNextPrevious`(預設 true)只在佇列頭尾 wrap,**不補歌**。 +- 「加同類曲」是**使用者觸發**(`QueueInsertionType` + generators,`lib/base/generator_base.dart`、`lib/controller/generators_controller.dart`)。 + +### e. 預取與 gapless + +- **音訊沒有做下一首預取**;唯一的 prefetch 是封面 `ArtworkPrefetcher.inst.prefetchAround(newIndex)`,掛在 `onIndexChanged`(`audio_handler.dart:627-644`)。 +- 有「預先備妥下一首」的 hook `prepareItem(...) → ItemPrepareConfig`(`audio_handler.dart:860`);**推測**基底會在當前曲播放中先 prepare 下一首,但呼叫時機在套件內、無法查證。 +- **gapless 預設 false**(`enableGaplessPlayback`,`settings.player.dart:28`);且 `InternalPlayerType.getInfoForAndroid()`(`lib/core/enums.dart:1067`)載明 **Android 的 mpv 後端缺 gapless** → gapless 由 exoplayer(just_audio)路線提供。crossfade 另計(`enableCrossFade` 等,`settings.player.dart:29-31`)。 +- 串流用 `http_cache_stream` 的 lock-caching;另有「下一首 seek 時換成新抓好的快取檔」機制(`audio_handler.dart:1388-1444, 2982-2997`)。 + +### f. 錯誤跳過策略(四者中最完整的) + +- 判斷是否真失敗,再 **7 秒倒數**(`playErrorRemainingSecondsToSkip = 7`)才 `skipItem()`,且要 `currentQueue.length > 1` 才跳,同時彈錯誤框;本地檔只在「誤判」分支重試一次([audio_handler.dart#L1064-L1108](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L1064-L1108))。 +- YouTube 串流過期 → catch 後重抓一次 streams 再 `setVideoLockCache(sameStream, positionToRestore)`(`:1278-1299`);完全失敗則退回快取,無快取就 `skipItem()`(`:2086-2132`);無效 video id 直接跳(`:1851-1880`);mpv 開啟失敗 3 秒後重試一次(`lib/class/custom_mpv_player.dart:337-347`)。 + +### g. 系統媒體控制 + +- **Android 通知 = `audio_service`**(`AudioService.init`,channel `com.msob7y.namida`、`androidStopForegroundOnPause: false`;[player_controller.dart#L219-L310](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/player_controller.dart#L219-L310));非 Android/iOS 只建純 handler、不進 media session。`_MediaSessionAudioHandler extends CompositeAudioHandler`(`:1159-1198`)。 +- **桌面**:`SMTCController.instance` → `NamidaSMTCManager.platform()`(Windows → `smtc_windows`、Linux → `anni_mpris_service`、android/ios → null)。 +- 更新觸發:`refreshNotification` → `mediaItem.add` + `playbackState.add`,再 `_refreshPlatformStatusDependers` → SMTC / home widget / Windows taskbar / tray(`audio_handler.dart:349-453`)。 + +### h. 後端 + +- 共同介面是 **`AVPlayer`**(抽象類別,來自 `basic_audio_handler`,**原始碼查不到**),**兩套實作**: + 1. `CustomMPVPlayer implements AVPlayer` —— namida 自寫,基於 **media_kit(mpv)**([custom_mpv_player.dart#L14](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/class/custom_mpv_player.dart#L14)),桌面路線。 + 2. `CustomAudioPlayer`(套件內,包作者 fork 的 just_audio)—— Android / iOS 路線。 +- 工廠 `NamidaAudioVideoHandler.createPlayer` switch `InternalPlayerType { auto, exoplayer, exoplayer_sw, mpv }`([audio_handler.dart#L2822-L2838](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L2822-L2838));`platformDefault` = Android/iOS `exoplayer`、Windows/macOS/Linux `mpv`。 +- 切法不是「按平台分兩份」,而是**同一介面 + 使用者可切換的後端 enum**(Android 上 mpv 是實驗選項)。`_createAndroidPlayer` 建 `AudioPlayer(handleInterruptions: false, androidApplyAudioAttributes: false, audioPipeline: AudioPipeline(androidAudioEffects: [equalizer, loudnessEnhancer]))`(`:2847-2865`)。 + +### i. 直播處理(四者中唯一有實作的) + +- `_resolveYTNetworkSources`([audio_handler.dart#L1575-L1599](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/base/audio_handler.dart#L1575-L1599)):`isLive == true` 時優先 `HlsSource(hlsManifestUrl)`,否則 `DashSource(dashManifestUrl)`;原始碼註解說明 live 結束後 fallback 回一般 mixed streams。 +- mpv 端 live 判斷:`_checkIsSourceLive(source) => source is HlsSource || source is DashSource`(`custom_mpv_player.dart:349`)。 +- live 的 duration / seek / 續播處理多數在套件內(**查不到**)。 + +--- + +## 5. 跨專案對照 + +| 面向 | Finamp | Spotube | Harmonoid | Namida | +|---|---|---|---|---| +| 後端(Android / 桌面) | just_audio fork(桌面換 platform impl 成 media_kit) | media_kit 全平台 | media_kit 全平台 | just_audio fork / media_kit(**同一介面 + 可切換 enum**) | +| 共同介面 | 無抽象層,只有 `AudioPlayer` API | `AudioPlayerInterface` + streams mixin | `MediaPlayer` facade + `MediaPlayerMixin` + `Playable` | `AVPlayer`(套件內,**不公開**) | +| 狀態建模 | audio_service `PlaybackState`;**無自寫狀態機** | 粗粒度 5 態列舉,由 `CustomPlayer` 折疊 | 18 欄 state + mixin registry | just_audio `ProcessingState` 直用 | +| 佇列真相 | 四段 list + **反向同步** native 清單 | media_kit `Playlist`,Dart 只投影 | media_kit `Playlist`(淺比較 + isolate 重建) | 套件 `currentQueue` + 自持久化 `Queue` | +| 臨時/插播 | `addNext` / `addToNextUp`(無臨時播放) | `addTracksAtFirst` → add+move | `insert` → add+move | `gentlePlay` = insert-next + next | +| 隨機 | 索引排列 + `NextUpShuffleOrder` | 交給 media_kit | 交給 media_kit + Dart 端先洗 | 索引排列 + `originalIndices` **持久化** | +| 無限佇列 | 伺服器 InstantMix,10 秒 + 事件驅動補 | 到最後一首才抓 radio 逐批補 | `open()` 當下把全庫洗進佇列 | **無**(僅 YouTube 單曲起播時補一次) | +| 預取 | 有(slice lazy 補) | 進度 80% 先解析下一首 URL | **無** | **無**(只預取封面) | +| gapless | just_audio playlist + 桌面 `prefetchPlaylist` | 無顯式設定(靠 mpv) | 無顯式設定(靠 mpv) | 預設 **關**;Android mpv 不支援 | +| 錯誤跳過 | **幾乎沒有**(`maxSkipsOnError: 0`) | player 層沒有,重試全在 HTTP 代理層 | **沒有**(處理整段被註解掉) | **7 秒倒數後跳**,重試一次 | +| 系統媒體控制 | audio_service + 自寫 AudioServiceSMTC + MPRIS plugin | audio_service + smtc_windows | audio_service + 自家 SMTC + mpris_service | audio_service + smtc_windows + anni_mpris_service | +| 直播 | **無** | 只做 m3u8 301 redirect | **無** | **有**(HLS/DASH source,isLive 分支) | + +### 對本專案(FMP)的意涵 + +1. **「一個介面、兩後端」在四者中只有 Namida 真的做**(`AVPlayer` + 可切換 enum),而且它的介面原始碼還不公開 —— FMP 現有的 `FmpAudioService` 抽象 + dartdoc 記錄不可收斂差異,是這批專案裡最完整的一種。重寫時值得原樣保留這個形狀(見 `current-state.md` §5)。 +2. **佇列真相的兩種路線**:Finamp 明講「native 清單是唯一真相、單向反推」;Spotube/Harmonoid 則是「native `Playlist` 是真相、Dart 只投影」。兩者都**不試圖維持 Dart 端獨立真相**——本專案 `QueueManager` 是獨立真相(含 shuffle 排列、Mix、persist),這是重寫時最需要重新決定的一點。 +3. **插播在 shuffle 下會壞,是共通坑**:Finamp 用 `NextUpShuffleOrder`、Harmonoid 用「反向 insert + 關閉回寫」、Spotube 用 `add+move`。本專案 `addNext` 把新索引插到隨機位置(`current-state.md` §3)正是同一類問題,且四者都給了可直接抄的解法。 +4. **媒體 `.add()` 後 `.move()` 回寫不即時**:Spotube 與 Harmonoid 都踩到(前者改用 git 版 media_kit、後者用 `playlist.medias.length - 1` 繞開)。FMP 若在桌面後端做插入,要注意同一處。 +5. **錯誤跳過只有 Namida 有產品化設計**(7 秒倒數 + 佇列長度 > 1 才跳)。本專案現在的「300ms 後跳下一首」比它激進,且 Mix 模式因條件寫死而完全不跳 —— 若要對齊已定的 D3,Namida 的「先給使用者看到再跳」是可參考的折衷。 +6. **直播是差異化能力**:四者只有 Namida 有 isLive 分支(HLS/DASH),且它自己也不完整。FMP 的電台(Bilibili 直播)+ `resolveStream` 的 live capability 屬於**沒有現成可抄**的部分,設計要自負。 +7. **四者都沒有把「臨時播放」做成獨立的播放模式**(Finamp/Spotube/Harmonoid 都只是插播/加佇列;Namida 的 `gentlePlay` 最接近但會改佇列)。FMP 現有的 `PlayMode.temporary`(離開佇列播一首再還原)在開源同類中是少見設計 —— 與 audit §3.10 的觀察一致。 + From 2ccdebe2483321e099110339d13014952b37ecab Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:30:47 +0800 Subject: [PATCH 050/133] chore(task): record the playback backend decision --- .trellis/tasks/09-27-design-playback-core/prd.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/09-27-design-playback-core/prd.md index 48c01390c..6f3fc5ab2 100644 --- a/.trellis/tasks/09-27-design-playback-core/prd.md +++ b/.trellis/tasks/09-27-design-playback-core/prd.md @@ -46,10 +46,14 @@ D5 限流由網路層退避、播放多次失敗才跳過並提示;D6 開流 D10 區分「未開播」與「查詢失敗」;E12 電台、E13 Mix、E19 速度/音量/輸出裝置保留(均衡器、響度、睡眠定時器在待辦); ADR 0013 的呈現表:無法取得/找不到「播放時跳過並提示」。 +## 已決定 + +1. **後端(A5,2026-09-28 選 A)**:`just_audio` 用於 Android、iOS、macOS(ExoPlayer/AVPlayer,系統媒體控制經 `audio_service`);`media_kit` 用於 Windows、Linux(libmpv,SMTC 經 `smtc_windows`、MPRIS 經 `audio_service_mpris`)。仍是一個介面、兩個實作。 + AVPlayer 格式較窄(無 FLV、無 webm/opus):平台層宣告可播的容器與編碼,插件的 `resolveStream` 依此挑格式(B 站直播在蘋果平台改用 HLS、YouTube 用 m4a);iOS/macOS 依 ADR 0009 待有機器時實作並實測。Windows 的 libmpv 庫停在 2023-09 是兩方案共同的風險。 + ## 待決定 -- [ ] A5:Android 用 just_audio+桌面 media_kit,還是全平台 media_kit -- [ ] 其餘待逐一確認 +- [ ] D7:隨機模式下「下一首播放」插到隨機位置、拖曳不更新隨機順序,是否真的保留 ## 驗收條件 From a0e94fc972521f04b0b9f38217d0a307f0833a40 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:33:41 +0800 Subject: [PATCH 051/133] chore(task): record the shuffle drag behaviour --- .trellis/tasks/09-27-design-playback-core/prd.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/09-27-design-playback-core/prd.md index 6f3fc5ab2..ff662dfbd 100644 --- a/.trellis/tasks/09-27-design-playback-core/prd.md +++ b/.trellis/tasks/09-27-design-playback-core/prd.md @@ -51,9 +51,11 @@ ADR 0013 的呈現表:無法取得/找不到「播放時跳過並提示」 1. **後端(A5,2026-09-28 選 A)**:`just_audio` 用於 Android、iOS、macOS(ExoPlayer/AVPlayer,系統媒體控制經 `audio_service`);`media_kit` 用於 Windows、Linux(libmpv,SMTC 經 `smtc_windows`、MPRIS 經 `audio_service_mpris`)。仍是一個介面、兩個實作。 AVPlayer 格式較窄(無 FLV、無 webm/opus):平台層宣告可播的容器與編碼,插件的 `resolveStream` 依此挑格式(B 站直播在蘋果平台改用 HLS、YouTube 用 m4a);iOS/macOS 依 ADR 0009 待有機器時實作並實測。Windows 的 libmpv 庫停在 2023-09 是兩方案共同的風險。 +2. **隨機模式的拖曳(D7 之二,2026-09-28)**:隨機順序是「位置」的順序,不是「歌曲」的順序。拖曳後,歌曲落在哪個位置,輪到那個位置時就播它(與舊版 `QueueManager.move` 不動 `_shuffleOrder` 的行為一致,`queue_manager.dart:593-612`)。拖進本輪已播過的位置,本輪不會再播。 + ## 待決定 -- [ ] D7:隨機模式下「下一首播放」插到隨機位置、拖曳不更新隨機順序,是否真的保留 +- [ ] D7 之一:隨機模式下「下一首播放」插到哪裡 ## 驗收條件 From 2038817633133a8fb0c5362775a8f4ce9ccb69c9 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:36:13 +0800 Subject: [PATCH 052/133] chore(task): add design and plan for playback core --- .../09-27-design-playback-core/design.md | 119 ++++++++++++++++++ .../09-27-design-playback-core/implement.md | 13 ++ .../tasks/09-27-design-playback-core/prd.md | 9 +- 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 .trellis/tasks/09-27-design-playback-core/design.md create mode 100644 .trellis/tasks/09-27-design-playback-core/implement.md diff --git a/.trellis/tasks/09-27-design-playback-core/design.md b/.trellis/tasks/09-27-design-playback-core/design.md new file mode 100644 index 000000000..c19fb09cd --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/design.md @@ -0,0 +1,119 @@ +# 設計:播放核心 + +## 1. 元件 + +```mermaid +flowchart TD + UI["UI 與系統媒體控制按鈕"] --> PC["PlaybackController
    唯一入口"] + PC --> QM["QueueModel
    純資料與操作"] + PC --> PS["PlaybackSession
    請求代際與取消"] + PS --> SR["StreamResolver
    本機檔、快取、插件 resolveStream/live"] + PS --> BE["AudioBackend 介面"] + BE --> JA["JustAudioBackend
    Android、iOS、macOS"] + BE --> MK["MediaKitBackend
    Windows、Linux"] + BE -. "事件與結束原因" .-> ER["PlaybackEventRouter
    純函數"] + ER -. "動作" .-> PC + PC --> RP["RecoveryPolicy
    純函數"] + PC --> NP["NowPlayingPublisher"] + NP --> OS["平台媒體控制轉接
    audio_service、smtc_windows、MPRIS"] +``` + +- `PlaybackController`(Riverpod Notifier)是 UI、系統媒體控制與電台的**唯一**播放入口;沒有任何其他元件直接操作後端(取消舊版電台的例外,§8)。 +- 協作者以回傳值或回呼回報,不寫狀態;狀態只由控制器寫。舊版拆出的形狀(路由純函數、請求代際、前瞻計畫、`NowPlayingPublisher`)照帶, + 死碼 `_navRequestId` 不帶。 +- 系統媒體控制的轉接器由平台層依能力提供(ADR 0009),經 provider 注入,不再從 `main.dart` 讀全域變數。 + +## 2. 狀態 + +- **一份播放狀態**(sealed):`Idle`、`Loading`、`Playing`、`Paused`、`Buffering`、`Retrying(attempt, nextAt)`、`Failed(AppError)`。 + 錯誤一律是 ADR 0013 的 `AppError`,不存字串(取代舊版 `error` 一欄三義)。 +- 高頻資料(位置、緩衝位置)走獨立 stream,不放進播放狀態,UI 只在需要的元件訂閱。 +- `QueueState` 與播放狀態沒有共同欄位(沿用舊 `audio_seam` 的意圖,由型別分開)。 +- 播放中的曲目、目前的播放模式放在 `QueueState`;播放狀態只描述「後端現在怎樣」。 + +## 3. 後端(已決定 A5 選 A) + +- `AudioBackend` 介面沿用舊 `FmpAudioService` 的形狀,**不能收斂的差異寫在介面 dartdoc**:音訊焦點只在行動平台、`processingState` 在 mpv 為合成值、 + 開源方法回傳時機不同、輸出裝置只在桌面。 +- `JustAudioBackend`:Android、iOS、macOS。`MediaKitBackend`:Windows、Linux。由平台層宣告選用哪個實作與**可播格式**(容器、編碼、是否支援 FLV/HLS)。 +- 可收斂的規則維持純函數並由兩個實作與假後端轉呼叫:結束原因分類、直播邊緣 seek 階梯、前瞻清單計畫、串流網址遮蔽(改用 ADR 0011 的遮蔽函式)。 + 契約測試(同一份斷言跑三個實作的純規則)照帶。 +- gapless:後端只持有「目前+一個前瞻」(`NextMediaPlan`),佇列真相在 Dart 端(§4)。 +- Android 音訊焦點:換歌時不放掉焦點(舊版每次 `stop()` 都 `setActive(false)`);電話打斷結束後的自動恢復經控制器的 `play()`,才會檢查網址過期。 + +## 4. 佇列與播放模式 + +- 佇列真相在 `QueueModel`(Dart 端):臨時播放、Mix、隨機位置順序與持久化都需要它;原生播放清單只拿前瞻。 +- 模式: + - `queue`:一般佇列。 + - `temporary`:臨時播放(D1)。記下佇列快照,播完或上下首時回到佇列;已在臨時模式時保留最早那份快照。 + - `mix`:插件 `mix` 能力的無限佇列(E13),不可播就自動跳過(D3),剩 1 首時補歌。已播超過 100 首時刪掉最舊的已播項目,防止無限增長。 + - `live`:電台與直播(§8),不動佇列。 + - `detached`:清空佇列後仍在播的那首。 +- 歌單「全部」只加入佇列(D2)。佇列上限 10,000 首,所有加入方式都檢查(舊版只有 `add` 檢查)。 +- **隨機**(D7): + - 隨機順序是「位置」的順序,不是歌曲的順序。打開隨機時目前這首排第一;不改動佇列本身,關掉隨機就回原順序。 + - 拖曳:只移動歌曲,不改位置順序;輪到哪個位置就播那裡的歌;拖進本輪已播過的位置,本輪不再播。 + - 「下一首播放」:新位置插在目前這首之後;連續加入時接在上一次插入的後面,依加入順序播(Namida 的 `insertAfterLatest` 慣例)。其餘未播位置順序不變。 + - 隨機順序持久化,重啟後相同(舊版每次重新產生)。 +- 單曲循環每一圈記一筆歷史(D6);網址仍在快取有效期內就 seek 回 0,不重新解析。 + +## 5. 串流解析 + +- 順序:本機下載檔 → 記憶體網址快取(ADR 0016)→ 插件 `resolveStream`。 +- `resolveStream` 輸入:曲目、分 P(`multiPart`)、音質偏好、**平台可播格式**;輸出:依優先序排好的候選串流(網址、標頭、格式、`expiresAt`)。 + 插件依可播格式挑格式(例如蘋果平台的 B 站直播用 HLS、YouTube 用 m4a)。分 P 由插件以分 P id 解析,宿主不懂 cid。 +- 開流失敗換下一個候選,一次請求最多換一次(沿用舊版)。 +- 網址過期:暫停後恢復、長時間暫停後 seek、前瞻交接前,都先檢查 `expiresAt − 5 分鐘`,過期就重新解析。 +- 預取:目前這首開始播後解析下一首並交給後端前瞻;臨時播放不預取。 +- 被取代的請求**取消**網路工作:取消訊號經宿主 `http.request` 傳到插件(舊版只丟掉結果、請求照跑)。 + +## 6. 錯誤恢復與跳過 + +依 ADR 0013 的分類,由純函數 `RecoveryPolicy` 決定: + +| 錯誤 | 播放層處理 | +|---|---| +| `NetworkError`、`RateLimited`(網路層重試後仍失敗)、播放中傳輸中斷、提前結束 | 從目前位置重試,1/3/9 秒共 3 次;網路狀態不是 `Online` 時暫停計數,恢復後再試(ADR 0016);仍失敗就跳過並提示 | +| `Unavailable`、`NotFound`、`AuthRequired`、`CredentialInvalid`、`VerificationRequired`、`Unsupported` | 不重試,立即跳過並提示(ADR 0013);需登入類附「登入」 | +| `Unavailable(只有試聽)`(D4) | 設定「跳過試聽片段」開(預設開)就跳過;關就播放並在曲目上標「試聽」 | +| 開不起來、解碼失敗 | 換候選一次,仍失敗就跳過 | +| 緩衝飢餓 15 秒 | 重新解析一次;同一首第二次就跳過 | +| 輸出裝置失敗(桌面) | 暫停並提示,不跳過 | + +- 「跳過」在 `queue`、`mix` 走下一首(D3);在 `temporary` 回到佇列並提示;在 `live` 顯示離線或查詢失敗(§8)。 +- 連續跳過次數達佇列長度(或 10 首)就停止並提示一次(ADR 0016)。同類提示短時間只出一次(ADR 0013)。 +- 重試計數在一首歌正常播放 10 秒後歸零(舊版成功後不歸零)。 + +## 7. 系統媒體控制 + +- `NowPlayingPublisher` 是唯一出口,擁有者為音樂或直播;按鈕依播放能力推導(直播沒有上下首、不能 seek)。 +- 轉接器:Android、iOS、macOS 用 `audio_service`;Linux 用 `audio_service_mpris`;Windows 用 `smtc_windows`。 +- 封面經 ADR 0016 的圖片快取;推送去重(只在值改變時推,位置有容差),並序列化避免亂序(Harmonoid 的慣例)。 + +## 8. 電台與直播 + +- 不再繞過控制器:`PlaybackController.playLive(station)` 經插件 `live` 能力取得串流,走同一個 `PlaybackSession`, + 所以開直播會取消進行中的音樂請求、音樂恢復也會停掉直播(**D8 由結構保證**,舊版 `restore()` 路徑的競態也一併消失)。 +- 進入直播時記下佇列快照,停止直播回到原佇列與位置(沿用舊 `returnFromRadio` 行為)。 +- 直播特有:`seekToLive`、無到期時間、提前結束時先問插件是否仍在直播,是才依 1/3/10 秒重連 3 次。 +- D10:直播狀態查詢失敗是 `AppError`,顯示「查詢失敗」,不再當成「未開播」。直播狀態輪詢與收聽中的直播間資訊刷新由背景排程器負責(ADR 0017)。 + +## 9. 持久化與設定 + +- 佇列持久化:曲目鍵、目前位置、播放位置、隨機位置順序、循環模式、播放模式、Mix 身分、音量。播放位置每 10 秒存一次,暫停、seek、App 進背景時立即存。 +- 「記住播放位置」「臨時播放回佇列倒退秒數」沿用;播放速度不持久化(E19 照舊);新增「跳過試聽片段」(D4,預設開)。 + +## 10. 計時器與閘門 + +- 播放模組擁有的計時器:位置檢查(每秒,**只在播放中**開)、位置存檔(每 10 秒,只在播放中)。它們是 `fmp_periodic_timer_owner`(ADR 0017)允許清單上的播放模組。 +- 舊 static-rule 的去向(ADR 0015 §6): + - `playback_event_routing` → 結束原因型別只准被後端與路由器 import(`fmp_layer_imports` 依賴表)+路由器的 exhaustive `switch`。 + - `audio_seam` → 狀態分開(§2)+串流存取的窄介面只准被 `PlaybackSession` import(依賴表)。 + - `audio_backend_shared_rules` → 契約測試照帶;「第二份關鍵字表」的防線改為分類規則只在一個檔,由依賴表限制後端只能 import 分類檔。 + - `just_audio`、`media_kit` 只准在後端實作目錄 import(依賴表)。 +- 測試: + - `QueueModel`:隨機位置語意、拖曳、連續下一首播放、臨時播放快照、Mix 修剪、上限。 + - `RecoveryPolicy`:每類錯誤的處理、離線暫停計數、歸零、連續跳過停止。 + - 開直播取消進行中的音樂請求(D8);預取後播放只解析一次(ADR 0016);單曲循環每圈一筆歷史且不重解析。 + - 後端契約測試(純規則)。 diff --git a/.trellis/tasks/09-27-design-playback-core/implement.md b/.trellis/tasks/09-27-design-playback-core/implement.md new file mode 100644 index 000000000..f9a81733b --- /dev/null +++ b/.trellis/tasks/09-27-design-playback-core/implement.md @@ -0,0 +1,13 @@ +# 執行計畫:第 13 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0018-playback-core.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§10;被否決的方案: + 全平台 media_kit、佇列真相放原生播放清單、電台繞過控制器的例外、隨機模式下「下一首播放」插隨機位置、錯誤只在 queue 模式跳過、錯誤以字串存於狀態。 + 說明它延續舊 ADR 0003(兩個後端)的形狀、適用於 `app/`。 +2. ADR 0014:`resolveStream` 輸入加上平台可播格式、輸出為候選串流清單;`live` 能力提供直播串流與直播狀態。 + ADR 0009:平台能力宣告加上「音訊後端與可播格式」。ADR 0017:`fmp_periodic_timer_owner` 的播放模組指向 ADR 0018。 +3. `phase2-plan.md`:§3 第 13 項標 ✅(ADR 0018);§7 第一個里程碑實測加入「兩個後端的前瞻交接與 Android 音訊焦點不在換歌時釋放」; + §8 延後實測加入「蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援」;§10 交接段更新,下一項 14 音樂庫與同步。 +4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 +5. `task.py finish`、`task.py archive design-playback-core --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/09-27-design-playback-core/prd.md index ff662dfbd..bc084e7e0 100644 --- a/.trellis/tasks/09-27-design-playback-core/prd.md +++ b/.trellis/tasks/09-27-design-playback-core/prd.md @@ -3,7 +3,7 @@ ## 目標 為 `app/` 定下佇列、播放模式、播放狀態機、音訊後端抽象、串流解析與網址過期、錯誤恢復、系統媒體控制, -以及電台/直播繞過播放控制器的例外是否保留。產出 ADR 0018。 +以及電台/直播繞過播放控制器的例外是否保留。產出 ADR 0018。技術設計見 `design.md`,執行步驟見 `implement.md`。 依據:parent `prd.md` 階段二第 13 項;`phase2-plan.md`(A5、D1–D10、E12、E13、E19);ADR 0013、0014、0016、0017 留給本項的部分 (播放層的恢復與跳過、`fmp_periodic_timer_owner` 的播放模組清單);ADR 0015 §6 標給本項的舊 static-rule @@ -53,9 +53,10 @@ ADR 0013 的呈現表:無法取得/找不到「播放時跳過並提示」 2. **隨機模式的拖曳(D7 之二,2026-09-28)**:隨機順序是「位置」的順序,不是「歌曲」的順序。拖曳後,歌曲落在哪個位置,輪到那個位置時就播它(與舊版 `QueueManager.move` 不動 `_shuffleOrder` 的行為一致,`queue_manager.dart:593-612`)。拖進本輪已播過的位置,本輪不會再播。 -## 待決定 - -- [ ] D7 之一:隨機模式下「下一首播放」插到哪裡 +3. **隨機模式的下一首播放(D7 之一,2026-09-28 選 A)**:插在目前這首之後,連續加入時依加入順序排;其餘未播位置順序不變。 +4. 技術選擇(`design.md`):控制器是唯一入口(含電台,D8 由結構保證);一份 sealed 播放狀態、錯誤為 `AppError`;佇列真相在 Dart 端; + 串流解析帶平台可播格式、被取代的請求取消網路工作;錯誤依 ADR 0013 分類決定重試或立即跳過(D3、D4、D5);Mix 修剪已播項目; + D10 查詢失敗與未開播分開;舊 static-rule 改由依賴表與契約測試接手。 ## 驗收條件 From 9d782d1acd4f4d8c55a8251434f281980edd05b0 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:37:46 +0800 Subject: [PATCH 053/133] docs(adr): 0018 playback core --- ...atform-layer-with-declared-capabilities.md | 1 + docs/adr/0013-unified-error-model.md | 4 +- docs/adr/0014-script-source-plugins.md | 1 + docs/adr/0016-cache-and-offline.md | 2 +- docs/adr/0017-background-task-scheduler.md | 2 +- docs/adr/0018-playback-core.md | 85 +++++++++++++++++++ 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 docs/adr/0018-playback-core.md diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 5216b75af..76fb384f8 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -42,6 +42,7 @@ Linux、macOS 加入時要回頭改介面。 `smtc_windows`…)只在實作檔 import。 2. **能力宣告**:每個平台一份不可變的 `PlatformCapabilities`。UI 依它決定是否顯示入口;service 只呼叫介面。 要在執行期才能判斷的(例如 Linux 在 Wayland 下沒有全域快捷鍵)由實作在啟動時寫進宣告。 + 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018。 3. **平台層以外禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件的 import。 4. **不寫空實作**:未驗證的平台宣告全部能力為「沒有」、沒有實作檔;該平台的 child task 開始時才加入實作。 5. **原生呼叫**:新的 MethodChannel 一律用 Pigeon 產生型別安全介面。 diff --git a/docs/adr/0013-unified-error-model.md b/docs/adr/0013-unified-error-model.md index 94cdf023c..f58168337 100644 --- a/docs/adr/0013-unified-error-model.md +++ b/docs/adr/0013-unified-error-model.md @@ -41,7 +41,7 @@ 使用者動作由呼叫端捕捉並交給呈現層。所有被處理的錯誤經 log 門面寫入(ADR 0011)。禁止空 catch 與靜默吞錯。 4. **重試只有一層**:Riverpod 自動重試全域關閉。網路層依音源宣告的策略重試:只重試冪等請求;只重試 `NetworkError`、 `RateLimited` 與音源標為可重試者;指數退避+全抖動、尊重 `Retry-After`、次數上限預設 2。每個音源有併發上限與最小請求間隔, - 事先避開限流。憑證刷新後重送(ADR 0012)另計。播放層的恢復策略由播放核心的 ADR 定。 + 事先避開限流。憑證刷新後重送(ADR 0012)另計。播放層的恢復策略見 ADR 0018。 5. **呈現**: | 類別 | 自動處理 | 使用者看到 | @@ -66,7 +66,7 @@ Finamp 以「類別+來源」去重;Riverpod 官方的全域 `retry` 設定 - 好的:使用者看到的訊息一致且可翻譯;每個音源的錯誤行為可用 fixture 測試;重試次數可預期;修正審計的 G4、G5、C5、C6、D5、D10。 - 壞的:每個音源要維護錯誤對應表;新增錯誤原因時要改 sealed 型別與所有 exhaustive `switch`(這正是想要的強制)。 -- 之後要注意:Toast 的外觀與「詳細」內容由 Toast 的設計定;播放層跳過與停止的條件由播放核心的 ADR 定; +- 之後要注意:Toast 的外觀與「詳細」內容由 Toast 的設計定;播放層跳過與停止的條件見 ADR 0018; B 站 geetest 驗證互動列在功能凍結待辦。 ## 如何確認 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index aef4ec536..692f69798 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -42,6 +42,7 @@ manifest 與腳本承擔。 只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`)。沒有檔案系統、任意 socket、其他插件的資料。 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。`resolveStream` 回傳網址期限 `expiresAt`(插件從網址本身讀), 封面為多尺寸清單 `artwork`(ADR 0016)。 + `resolveStream` 的輸入含平台可播格式、輸出為依優先序排好的候選串流;`live` 提供直播串流與直播狀態(ADR 0018)。 6. **插件庫**:官方插件在獨立 repo `1morr/fmp-plugins`,每插件一目錄(腳本、manifest、錄下的測試 fixture),其 CI 跑契約測試並產生 `index.json`(含 SHA-256)。App 插件頁預設讀官方 index,可加自訂 index 網址,也可從檔案或網址安裝;由 index 安裝時驗證 SHA-256。 安裝前顯示能力與會連的網域,並警告「此腳本會以你的登入身分存取這些網站」。 diff --git a/docs/adr/0016-cache-and-offline.md b/docs/adr/0016-cache-and-offline.md index 8f8fe5f4a..6455637f1 100644 --- a/docs/adr/0016-cache-and-offline.md +++ b/docs/adr/0016-cache-and-offline.md @@ -55,7 +55,7 @@ NewPipe/Spotube 的圖片快取交給 `cached_network_image` 系列;Android - 好的:快取只有一個位置、一個上限、一個清除;丟掉快取不會掉資料;預取失效不再發生;網址期限跟著插件修,不必發 App;離線時每頁有明確狀態;不再每 15 秒查 DNS。 - 壞的:要自建快取索引與淘汰;圖片接到統一快取庫需要實作 cache manager 介面;每個播放類插件都要正確回報 `expiresAt`。 -- 之後要注意:背景刷新與離線時的暫停、補跑見 ADR 0017;播放失敗的重試與跳過細節由播放核心的 ADR 定;邊聽邊存、手動離線模式、已下載內容容量管理列在功能凍結待辦。 +- 之後要注意:背景刷新與離線時的暫停、補跑見 ADR 0017;播放失敗的重試與跳過見 ADR 0018;邊聽邊存、手動離線模式、已下載內容容量管理列在功能凍結待辦。 ## 如何確認 diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md index 321f9f719..32b70e533 100644 --- a/docs/adr/0017-background-task-scheduler.md +++ b/docs/adr/0017-background-task-scheduler.md @@ -50,7 +50,7 @@ Riverpod 3 在 Notifier 內建立計時器並以 `ref.onDispose` 取消、由生 - 好的:一套規則管暫停、離線、退避與取消;看不見時零常駐請求;重啟不會讓刷新間隔重算;新增週期工作只要登記。 - 壞的:打開 App 的頭幾秒可能看到較舊的排行或歌單;桌面縮到托盤聽歌時,資料要等回到畫面才更新。 -- 之後要注意:播放核心若需要自己的計時器,把模組加進 `fmp_periodic_timer_owner` 的允許清單;下載的背景執行由下載的 ADR 定。 +- 之後要注意:播放模組的計時器見 ADR 0018;下載的背景執行由下載的 ADR 定。 ## 如何確認 diff --git a/docs/adr/0018-playback-core.md b/docs/adr/0018-playback-core.md new file mode 100644 index 000000000..01a33131f --- /dev/null +++ b/docs/adr/0018-playback-core.md @@ -0,0 +1,85 @@ +# 0018 — 播放核心:單一控制器(含直播)、Dart 端佇列、兩個後端、依錯誤類別恢復或跳過 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/` 的播放模組(控制器、佇列、請求、後端、路由、恢復、系統媒體控制)、`resolveStream` 與 `live` 的 DTO、平台能力宣告、播放相關設定 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-27-design-playback-core/research/current-state.md`、`docs/audit/playback.md`,已以程式碼核對): + +- `AudioController`(2,953 行)已拆出 13 個協作者;路由純函數、請求代際、前瞻計畫、`NowPlayingPublisher` 的形狀可用。 +- 狀態至少 5 份並存,`PlayerState.error` 一欄承載三種內容。 +- 只有 queue 模式遇到無法取得會跳過,Mix 完全不跳(D3);限流只設錯誤不重試(D5);重試次數成功後不歸零;被取代的請求不取消網路工作。 +- 電台直接操作後端、繞過控制器,開電台只暫停音樂、不取消進行中的解析(D8);`restore()` 路徑也不停電台。 +- 隨機模式下「下一首播放」插到隨機位置(D7)。 + +本 ADR 延續舊 ADR 0003「兩個後端」的形狀,適用於 `app/`;舊 ADR 0003 仍描述根目錄舊專案。 + +## 考慮過的選項 + +- **全平台 `media_kit`**:否決。Android 的通知、音訊焦點、拔耳機、gapless 都要自接,APK 每個 ABI 約 +3MB; + 均衡器只能靠 mpv 濾鏡且有失效回報;Windows/macOS/iOS 的 libs 停在 2023-09,蘋果平台還不接 Now Playing。 +- **佇列真相放原生播放清單、Dart 只投影**(Spotube、Harmonoid、Finamp):否決。臨時播放、Mix、位置式隨機與持久化都需要 Dart 端真相。 +- **保留電台繞過控制器的例外**:否決,它是 D8 競態的來源。 +- **隨機模式下「下一首播放」插到隨機位置**:否決(擁有者 2026-09-28 選擇插在目前這首之後)。 +- **只在 queue 模式跳過、錯誤以字串存在狀態裡**:否決(D3、ADR 0013)。 +- **Namida 的 7 秒倒數再跳過**:否決,改依 ADR 0013 的呈現表「跳過並提示」。 + +## 決定 + +1. **元件**:`PlaybackController` 是 UI、系統媒體控制與直播的唯一播放入口;協作者(`QueueModel`、`PlaybackSession`、`StreamResolver`、 + `PlaybackEventRouter` 純函數、`RecoveryPolicy` 純函數、`NowPlayingPublisher`)只回報、不寫狀態。系統媒體控制轉接器由平台層經 provider 注入。 +2. **狀態**:一份 sealed 播放狀態(`Idle`、`Loading`、`Playing`、`Paused`、`Buffering`、`Retrying`、`Failed(AppError)`);位置等高頻資料走獨立 stream; + `QueueState` 與播放狀態沒有共同欄位。 +3. **後端**:`AudioBackend` 介面,兩個實作——`JustAudioBackend`(Android、iOS、macOS)與 `MediaKitBackend`(Windows、Linux); + 不能收斂的差異寫在介面 dartdoc,可收斂的規則(結束原因分類、直播邊緣 seek、前瞻計畫)是共用純函數並有契約測試。 + 平台層宣告使用哪個實作與**可播格式**(ADR 0009)。後端只持有「目前+一個前瞻」。Android 換歌時不釋放音訊焦點。 +4. **佇列與模式**:佇列真相在 Dart 端 `QueueModel`。模式為 `queue`、`temporary`(臨時播放,D1,保留最早快照並回到佇列)、`mix`(插件 `mix` 能力, + 已播超過 100 首刪最舊的已播項目)、`live`、`detached`。歌單「全部」只加入佇列(D2)。所有加入方式檢查 10,000 首上限。 + 單曲循環每圈記一筆歷史(D6),網址有效時 seek 回 0 不重解析。 +5. **隨機**(D7):隨機順序是位置的順序;拖曳只移動歌曲、不改位置順序,拖進本輪已播的位置本輪不再播; + 「下一首播放」插在目前這首之後,連續加入依加入順序排;其餘未播位置不變;隨機順序持久化。 +6. **串流解析**:本機下載檔 → 記憶體網址快取(ADR 0016)→ 插件 `resolveStream`。輸入含分 P 與**平台可播格式**,輸出為依優先序排好的候選串流 + (網址、標頭、格式、`expiresAt`);開流失敗換候選一次。恢復播放、長暫停後 seek、前瞻交接前檢查網址過期。被取代的請求經宿主 `http.request` 取消網路工作。 +7. **錯誤恢復**(依 ADR 0013 類別,由 `RecoveryPolicy` 決定): + - `NetworkError`、`RateLimited`、傳輸中斷、提前結束:從目前位置重試 1/3/9 秒共 3 次;不在 `Online` 時暫停計數(ADR 0016);仍失敗就跳過並提示。 + - `Unavailable`、`NotFound`、需登入與驗證類、`Unsupported`:立即跳過並提示。 + - `Unavailable(只有試聽)`:新設定「跳過試聽片段」(預設開)決定跳過或標「試聽」後播放(D4)。 + - 開不起來或解碼失敗換候選一次;緩衝飢餓 15 秒重解析一次、同首第二次跳過;桌面輸出裝置失敗只暫停並提示。 + - 跳過在 `queue`、`mix` 走下一首(D3),在 `temporary` 回到佇列;連續跳過達佇列長度或 10 首就停止並提示一次。 + - 一首歌正常播放 10 秒後重試計數歸零。 +8. **系統媒體控制**:`NowPlayingPublisher` 唯一出口,按鈕依播放能力推導;轉接器 Android/iOS/macOS 用 `audio_service`、Linux 用 `audio_service_mpris`、 + Windows 用 `smtc_windows`;只在值改變時推送並序列化。 +9. **直播**:`PlaybackController.playLive` 經插件 `live` 能力取流,走同一個 `PlaybackSession`,開直播必然取消進行中的音樂請求(D8); + 進入時記佇列快照、停止時回到原佇列。提前結束時先問插件是否仍在直播,是才以 1/3/10 秒重連 3 次。 + 直播狀態查詢失敗顯示「查詢失敗」,不當成「未開播」(D10);直播狀態輪詢與收聽中刷新由 ADR 0017 的排程器負責。 +10. **持久化與設定**:佇列(曲目鍵、目前位置、播放位置、隨機位置順序、循環模式、模式、Mix 身分、音量)持久化,位置每 10 秒及暫停、seek、進背景時存。 + 「記住播放位置」「臨時播放回佇列倒退秒數」沿用;播放速度不持久化(E19)。 +11. **計時器**:播放模組的位置檢查(每秒)與位置存檔(每 10 秒)只在播放中開,是 `fmp_periodic_timer_owner`(ADR 0017)允許的播放模組。 + +採用的慣例:Namida 的「一個介面、Android ExoPlayer/桌面 mpv」與 `insertAfterLatest`;Harmonoid 的媒體控制推送去重與序列化; +Finamp 以 `audio_service` 接系統媒體控制;ADR 0013 的錯誤類別與呈現表。 + +## 後果 + +- 好的:電台與音樂不會再互相覆蓋;Mix 與佇列的壞曲處理一致;錯誤不再以字串外洩到畫面;快速切歌不再堆積網路請求; + 新平台只要選一個既有後端並宣告可播格式。 +- 壞的:仍要維護兩個後端;蘋果平台的 AVPlayer 格式較窄,插件要依可播格式挑串流;隨機位置語意要在佇列頁說清楚。 +- 之後要注意:均衡器、響度、睡眠定時器、邊聽邊存在功能凍結待辦;Windows 的 libmpv 庫停在 2023-09; + iOS/macOS 的格式支援(B 站 DASH 音訊、直播 HLS)在有機器時實測。 + +## 如何確認 + +- 單元測試: + - `QueueModel`:隨機位置語意、拖曳、連續下一首播放、臨時播放快照、Mix 修剪、上限。 + - `RecoveryPolicy`:每類錯誤的處理、離線暫停計數、歸零、連續跳過停止。 + - 開直播取消進行中的音樂請求;預取後播放只解析一次;單曲循環每圈一筆歷史且不重解析。 +- 後端契約測試:同一份純規則斷言跑兩個實作與假後端。 +- lint `fmp_layer_imports`(ADR 0015)的依賴表: + - `just_audio`、`media_kit` 只在後端實作目錄; + - 結束原因型別只給後端與路由器 import; + - 串流存取的窄介面只給 `PlaybackSession` import。 + + 這一組取代舊 `playback_event_routing`、`audio_seam`、`audio_backend_shared_rules` static-rule。 +- 第一個里程碑實測:兩個後端的前瞻交接;Android 換歌時不釋放音訊焦點。 From 1fe3d73cbab1f257b2cb8307b975ec1fb1169a56 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:37:46 +0800 Subject: [PATCH 054/133] chore(task): archive design-playback-core --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 +++++++----- .../tasks/09-27-design-playback-core/implement.md | 13 ------------- .../2026-09}/09-27-design-playback-core/check.jsonl | 0 .../2026-09}/09-27-design-playback-core/design.md | 0 .../09-27-design-playback-core/implement.jsonl | 0 .../2026-09/09-27-design-playback-core/implement.md | 13 +++++++++++++ .../2026-09}/09-27-design-playback-core/prd.md | 0 .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../research/prior-art.md | 0 .../2026-09}/09-27-design-playback-core/task.json | 6 +++--- 11 files changed, 23 insertions(+), 21 deletions(-) delete mode 100644 .trellis/tasks/09-27-design-playback-core/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-27-design-playback-core/task.json (88%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 3d19d27d4..c1eccebac 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -121,7 +121,7 @@ flowchart LR | 9 | 8 測試與開發環境(✅ 完成,ADR 0015) | 契約測試、fixture 錄製綁在插件介面上,所以緊接在 1 後面。 | | 10 | 17 快取與離線(✅ 完成,ADR 0016) | 串流 URL、圖片、排行快取的策略,播放核心要用。 | | 11 | 16 背景任務(✅ 完成,ADR 0017) | 刷新、清理、更新檢查誰來排程。 | -| 12 | 13 播放核心 | 最大的一塊;依賴 1、2、10、17。 | +| 12 | 13 播放核心(✅ 完成,ADR 0018) | 最大的一塊;依賴 1、2、10、17。 | | 13 | 14 音樂庫與同步 | B1/B2 已定方向,細節依賴 6、1、12、16。 | | 14 | 11 下載與權限 | 依賴播放核心的本地播放路徑。 | | 15 | 15 歌詞 | 依賴 1、13。 | @@ -223,12 +223,14 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 - ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。 - ADR 0014:JS 執行環境(`flutter_js`)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;`flutter_js` 在 Android、Windows 的 Promise/記憶體/啟動成本實測;YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)。 +- ADR 0018:兩個後端的前瞻交接(gapless);Android 換歌時不釋放音訊焦點。 - ADR 0015:`fmp_lints` 接上 `app/`,`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)。 ## 8. 延後到特定里程碑的實測 - ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。 - ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 +- ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -237,10 +239,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0017`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0018`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 13 項「播放核心」**,task `.trellis/tasks/09-27-design-playback-core/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 -- 之後順序:14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 14 項「音樂庫與同步」(尚未建 task)。 +- 之後順序:11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-27-design-playback-core/implement.md b/.trellis/tasks/09-27-design-playback-core/implement.md deleted file mode 100644 index f9a81733b..000000000 --- a/.trellis/tasks/09-27-design-playback-core/implement.md +++ /dev/null @@ -1,13 +0,0 @@ -# 執行計畫:第 13 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0018-playback-core.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§10;被否決的方案: - 全平台 media_kit、佇列真相放原生播放清單、電台繞過控制器的例外、隨機模式下「下一首播放」插隨機位置、錯誤只在 queue 模式跳過、錯誤以字串存於狀態。 - 說明它延續舊 ADR 0003(兩個後端)的形狀、適用於 `app/`。 -2. ADR 0014:`resolveStream` 輸入加上平台可播格式、輸出為候選串流清單;`live` 能力提供直播串流與直播狀態。 - ADR 0009:平台能力宣告加上「音訊後端與可播格式」。ADR 0017:`fmp_periodic_timer_owner` 的播放模組指向 ADR 0018。 -3. `phase2-plan.md`:§3 第 13 項標 ✅(ADR 0018);§7 第一個里程碑實測加入「兩個後端的前瞻交接與 Android 音訊焦點不在換歌時釋放」; - §8 延後實測加入「蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援」;§10 交接段更新,下一項 14 音樂庫與同步。 -4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 -5. `task.py finish`、`task.py archive design-playback-core --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-playback-core/check.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/check.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/check.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/check.jsonl diff --git a/.trellis/tasks/09-27-design-playback-core/design.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/design.md similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/design.md rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/design.md diff --git a/.trellis/tasks/09-27-design-playback-core/implement.jsonl b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.jsonl similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.md new file mode 100644 index 000000000..6d98a003b --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/implement.md @@ -0,0 +1,13 @@ +# 執行計畫:第 13 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0018-playback-core.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§10;被否決的方案: + 全平台 media_kit、佇列真相放原生播放清單、電台繞過控制器的例外、隨機模式下「下一首播放」插隨機位置、錯誤只在 queue 模式跳過、錯誤以字串存於狀態。 + 說明它延續舊 ADR 0003(兩個後端)的形狀、適用於 `app/`。 +2. [x] ADR 0014:`resolveStream` 輸入加上平台可播格式、輸出為候選串流清單;`live` 能力提供直播串流與直播狀態。 + ADR 0009:平台能力宣告加上「音訊後端與可播格式」。ADR 0017:`fmp_periodic_timer_owner` 的播放模組指向 ADR 0018。 +3. [x] `phase2-plan.md`:§3 第 13 項標 ✅(ADR 0018);§7 第一個里程碑實測加入「兩個後端的前瞻交接與 Android 音訊焦點不在換歌時釋放」; + §8 延後實測加入「蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援」;§10 交接段更新,下一項 14 音樂庫與同步。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-playback-core --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-27-design-playback-core/prd.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/prd.md similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/prd.md rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/prd.md diff --git a/.trellis/tasks/09-27-design-playback-core/research/current-state.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/research/current-state.md similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/research/current-state.md diff --git a/.trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/research/packages-and-platform.md diff --git a/.trellis/tasks/09-27-design-playback-core/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-27-design-playback-core/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/research/prior-art.md diff --git a/.trellis/tasks/09-27-design-playback-core/task.json b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/task.json similarity index 88% rename from .trellis/tasks/09-27-design-playback-core/task.json rename to .trellis/tasks/archive/2026-09/09-27-design-playback-core/task.json index 0ba7100be..cecec166e 100644 --- a/.trellis/tasks/09-27-design-playback-core/task.json +++ b/.trellis/tasks/archive/2026-09/09-27-design-playback-core/task.json @@ -3,7 +3,7 @@ "name": "design-playback-core", "title": "Design: playback core", "description": "Phase-2 item 13: queue, play modes, playback state machine, audio backend abstraction, stream resolution and expiry, error recovery, system media controls, radio/live exception", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-27", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 33c486a98301096bc6271fb1627ddc1ef01b09eb Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:38:35 +0800 Subject: [PATCH 055/133] chore(task): start design-library-sync --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-28-design-library-sync/check.jsonl | 0 .../09-28-design-library-sync/implement.jsonl | 0 .../tasks/09-28-design-library-sync/prd.md | 19 ++++++++++++++ .../tasks/09-28-design-library-sync/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-design-library-sync/check.jsonl create mode 100644 .trellis/tasks/09-28-design-library-sync/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-library-sync/prd.md create mode 100644 .trellis/tasks/09-28-design-library-sync/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index c1eccebac..fb82a12e5 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -242,7 +242,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0018`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 14 項「音樂庫與同步」(尚未建 task)。 +- **進行中:第 14 項「音樂庫與同步」**,task `.trellis/tasks/09-28-design-library-sync/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`sync-and-matching.md`),三個檔齊了才代表研究完成。 - 之後順序:11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index c2d10b157..b82ee7536 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -31,7 +31,8 @@ "09-27-design-testing", "09-27-design-cache-offline", "09-27-design-background-tasks", - "09-27-design-playback-core" + "09-27-design-playback-core", + "09-28-design-library-sync" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-library-sync/check.jsonl b/.trellis/tasks/09-28-design-library-sync/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-library-sync/implement.jsonl b/.trellis/tasks/09-28-design-library-sync/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-library-sync/prd.md b/.trellis/tasks/09-28-design-library-sync/prd.md new file mode 100644 index 000000000..f9e671e09 --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/prd.md @@ -0,0 +1,19 @@ +# Design: library and sync + +## Goal + +Phase-2 item 14: local vs imported remote playlists, sync direction and conflicts, confirmation before writing back to a platform, auto-refresh rules, metadata-only imports with matching + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-library-sync/task.json b/.trellis/tasks/09-28-design-library-sync/task.json new file mode 100644 index 000000000..5ef270d67 --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-library-sync", + "name": "design-library-sync", + "title": "Design: library and sync", + "description": "Phase-2 item 14: local vs imported remote playlists, sync direction and conflicts, confirmation before writing back to a platform, auto-refresh rules, metadata-only imports with matching", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From d186e0f8b4cb16e6fa079ce0b518a9f0eab3c7c1 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:44:00 +0800 Subject: [PATCH 056/133] chore(task): add design-library-sync research and prd draft --- .../tasks/09-28-design-library-sync/prd.md | 53 ++- .../research/current-state.md | 224 ++++++++++ .../research/prior-art.md | 403 ++++++++++++++++++ .../research/sync-and-matching.md | 324 ++++++++++++++ 4 files changed, 993 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-library-sync/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-library-sync/research/prior-art.md create mode 100644 .trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md diff --git a/.trellis/tasks/09-28-design-library-sync/prd.md b/.trellis/tasks/09-28-design-library-sync/prd.md index f9e671e09..5b98b5592 100644 --- a/.trellis/tasks/09-28-design-library-sync/prd.md +++ b/.trellis/tasks/09-28-design-library-sync/prd.md @@ -1,19 +1,50 @@ -# Design: library and sync +# 設計:音樂庫與同步(階段二第 14 項) -## Goal +## 目標 -Phase-2 item 14: local vs imported remote playlists, sync direction and conflicts, confirmation before writing back to a platform, auto-refresh rules, metadata-only imports with matching +為 `app/` 定下本地歌單與匯入歌單的資料模型、刷新(只從遠端往下)的差異處理、寫回平台的遠端操作與確認、 +僅元資料來源(Spotify、QQ)匯入的匹配流程與失敗處理。產出 ADR 0019。 -## Requirements +依據:parent `prd.md` 階段二第 14 項;`docs/audit/questions.md` 第 131 行 B1/B2 備註;E4、E5、E7 保留; +ADR 0010(drift、外鍵)、0013(錯誤呈現)、0014 決定 9(共用匹配評分)、0016(離線)、0017(自動刷新排程與間隔)。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對) -## Acceptance Criteria +- 本地與匯入歌單同一個 collection,只靠 `sourceUrl != null` 區分(`playlist.dart:70`);歌單名稱唯一,重名自動加「(2)」。 +- 曲目與歌單的關係是手動維護的整數陣列+反向 `playlistInfo`,沒有外鍵;ADR 0010 記載曾因此遺失資料(孤兒清理誤刪)。 +- 刷新:整批以遠端覆寫順序;**只有遠端資料完整時才刪除**,否則靜默變成「只增不刪」,UI 不顯示(`playlist_mutation_repository.dart:531-532,841-873`)。 + 遠端改標題不會同步下來;描述只在首次匯入寫入;封面自訂過就不動。重新匯入會覆寫「使用登入狀態刷新」與刷新間隔(M12)。 +- 遠端歌單被刪或變私人:沒有狀態,只有一次錯誤 toast(且被壓成通用「發生錯誤」),排程繼續重試。 +- 已失效曲目:`markUnavailable` 零呼叫端,`isAvailable` 只在網易建構時判定一次。 +- B1 移除遠端:有確認框、先寫遠端再刪本地、再背景刷新;B2 加入遠端:勾選歌單後送出,沒有額外確認,未登入的來源被過濾並提示。 +- Spotify/QQ 匯入:逐首搜尋(只搜 YouTube 與 B 站)、評分取前 5、第一名自動選、預覽頁可改選與重搜;手動重搜只依播放量排序、不打分。 + 與歌詞匹配是兩套評分(ADR 0014 已定合併)。 +- 沒有曲目層的收藏/喜歡。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/sync-and-matching.md`) -## Notes +- 最接近的是 Finamp 的 id 集合差集(遠端−本地=新增、本地−遠端=移除)。寫回確認只有 Namida 分得剛好:移除要確認、加入不用。 + 五個產品都沒有逐曲匹配信心分數或人工修正 UI,FMP 的匯入預覽頁已比它們完整。 +- 單向權威同步不需要 LCS/Myers,id 差集加遠端順序即可;大歌單宜「抓一頁寫一頁」加刷新代際標記,避免長時間持有寫鎖(drift `transaction()` 發 `BEGIN IMMEDIATE`)。 +- YouTube 歌單可含重複影片:關聯表不可對(歌單, 曲目鍵)設唯一。網易換版本是新 song id、新舊並存。 +- 匹配正規化:NFKC → 小寫 → 繁簡統一 → 去裝飾 → 括號內容單獨比對(不整段刪);時長取「絕對值與百分比較寬者」。 + 套件:`string_similarity` 2.2.0(MIT)、`unorm_dart` 0.3.2(MIT)、`opencc` 1.1.0(Apache-2.0,需 native assets);`fuzzywuzzy` 為 GPL-2.0,不用。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向 + +- B1/B2:遠端是權威、只往下同步;匯入歌單不能在本地增刪曲目;保留明確標示的遠端操作;名稱、描述、封面、自動刷新設定可在本地改。 +- 自動刷新的排程與間隔(ADR 0017);刷新時是否帶登入依音源設定(ADR 0012),不再每張歌單各存一份(M12 的覆寫問題隨之消失)。 + +## 待決定 + +- [ ] 刷新時,遠端清單裡已經沒有的曲目怎麼處理 + +## 驗收條件 + +- [ ] ADR 0019 記錄:資料模型與外鍵、刷新差異處理(新增、移除、順序、元資料、部分失敗)、遠端歌單失效、遠端操作與確認、匹配流程與失敗、孤兒清理。 +- [ ] B1、B2、E4、E5、E7、M12 各自對到決定。 +- [ ] `phase2-plan.md` §3 第 14 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 下載檔案的管理與刪除(第 11 項);歌詞匹配的歌詞端細節(第 15 項,但共用評分核心在本項定);歌單頁版面(第 5 項)。 diff --git a/.trellis/tasks/09-28-design-library-sync/research/current-state.md b/.trellis/tasks/09-28-design-library-sync/research/current-state.md new file mode 100644 index 000000000..12ce2ad39 --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/research/current-state.md @@ -0,0 +1,224 @@ +# 舊專案的音樂庫與同步(current state) + +- 查證日期:2026-09-28 +- 查證方式:讀 `docs/audit/`(`features.md` §3–§4、§13–§15;`data.md` §1–§2;`sources.md` §5;`errors.md` §2、§4)並以 `lib/` 程式碼逐條核對(`sed -n`/`grep -n` 直接讀原始碼,行號以查證當下的檔案為準)。**沒有**執行 App、**沒有**打真實 API、**沒有**跑 `flutter test`。 +- 標記約定:沒有標記的敘述是我在程式碼裡直接讀到的事實;「推測」表示程式碼推得但未實跑確認;「查不到」表示在 `lib/`/`test/`/`tool/` grep 不到。 + +--- + +## 1. 資料模型 + +### 1.1 本地歌單與匯入歌單怎麼區分 + +**同一個 `Playlist` collection,靠 `sourceUrl != null` 區分,不是兩個型別。** + +| 事實 | 證據 | +|---|---| +| `isImported` 是 getter:`sourceUrl != null` | `lib/data/models/playlist.dart:70` | +| 匯入歌單多帶 `importSourceType`(音源 id 字串)、`sourceUrl`、`lastRefreshed`、`useAuthForRefresh`、`ownerName`、`ownerUserId` | `lib/data/models/playlist.dart:24,27,33,45,39,42` | +| 本地歌單的 `sourceUrl` 為 null,其餘欄位共用 | 同上;新增本地歌單的建構子在 `lib/services/library/playlist_service.dart:125-130` | +| `refreshIntervalHours` 是「幾小時」而非排程表;null=不啟用 | `lib/data/models/playlist.dart:30,76-83` | +| `needsRefresh` 是**會被 Isar 持久化的 getter**(沒標 `@ignore`),存下來的值只在 `put` 當下算過 | `docs/audit/data.md:§1.2`;`playlist.dart:76-83` | +| Mix 是第三種:`isMix`,只存元資料(不存 tracks),刷新直接跳過 | `playlist.dart:48-54`;`import_service.dart:418-427` | +| 名稱 `name` 有 **unique 索引**,同名歌單匯入時自動加 ` (2)`、` (3)` 後綴 | `playlist.dart:11-12`;`import_service.dart:249,645-660` | +| 匯入歌單在詳情頁有「已匯入」badge(本地歌單沒有) | `lib/ui/pages/library/playlist_detail_page.dart:748-760` | + +### 1.2 曲目與歌單的關係、同一首歌出現在多張歌單 + +**沒有 IsarLink;`Playlist.trackIds` 是手動維護的整數陣列,反向關係存在 `Track.playlistInfo`。** + +| 事實 | 證據 | +|---|---| +| `Playlist.trackIds: List`(有序,指向 `Track.id`) | `lib/data/models/playlist.dart:57` | +| `Track.playlistInfo: List`,每筆是一個(playlistId, playlistName, downloadPath) | `lib/data/models/track.dart:10-34,53-55` | +| 同一首歌在多張歌單=**同一列 `Track`**,`playlistInfo` 多筆、多個 `Playlist.trackIds` 各含它的 id | `playlist_mutation_repository.dart:765-799`(`_ensureSinglePlaylistInfo`);`:620-659`(`mergeDuplicateTrackMembershipsInTxn`);`:661-681`(`remapPlaylistTrackReferencesInTxn`) | +| 沒有任何 `IsarLink`/`IsarLinks`/`@Backlink` | `docs/audit/data.md:§1.2`(整份 lib grep 不到) | +| 參照完整性沒有 DB 層保證;`DataIntegrityRepository.scan/repair` 能修,但 `lib/` 裡唯一呼叫點是開發者選項「重設所有資料」 | `docs/audit/data.md:§1.2`;`docs/audit/features.md:§14` | +| 重複曲目以 `uniqueKey` 判定 | `docs/adr/0005` 後果節 | + +### 1.3 曲目唯一鍵 + +| 事實 | 證據 | +|---|---| +| `TrackKey.format(sourceType, sourceId, {cid})` → 有 cid 三段式 `sourceType:sourceId:cid`,否則兩段式 | `lib/data/models/track_key.dart:19-20` | +| `Track.uniqueKey` 用 `format`,`groupKey` 永遠兩段式(同影片所有分 P 共用) | `lib/data/models/track.dart:344,341` | +| `Track.sourcePageKey` 是同一個字串,當 Isar 複合索引(`CompositeIndex('cid')`) | `track.dart:277-278` | +| B 站分 P:**每個分 P 一列 Track**,共用 `sourceId`(bvid),`cid` 不同;`pageNum` 只是顯示序號 | `docs/adr/0005`;`track.dart:260-266` | +| cid 是可空、且會被回填:搜尋/排行榜來的曲目先沒 cid,第一次解析串流時 `track.cid ??= streamResult.cid`,`uniqueKey` 從兩段式變三段式 | `docs/adr/0005`「鍵有兩種形狀」節 | +| 鍵是持久化格式,被 `LyricsMatch.trackUniqueKey`、`PlayHistory.trackKey`、備份 JSON 當外鍵 | `docs/adr/0005` 後果節;`lib/data/models/play_history.dart:47` | +| 其他會持久化的身分欄位:`originalSongId` / `originalSource`(外部平台來源 id) | `track.dart:254-263` | + +### 1.4 曲目的其他狀態 + +| 狀態 | 怎麼存 | 證據 | +|---|---|---| +| 下載標記 | `Track.playlistInfo[].downloadPath`(空字串=沒下載)+獨立的 `DownloadTask` collection;**沒有**單一布林欄位 | `track.dart:10-34`;`docs/audit/data.md:§1.2` | +| 播放歷史 | 獨立的 `PlayHistory` collection,**快照當下的標題/歌手/時長/封面**,不參照 `Track.id`,只存 `trackKey` | `lib/data/models/play_history.dart:10-77` | +| 已失效曲目 | `Track.isAvailable` / `unavailableReason`。**目前唯一寫入點是建構時**:網易雲 `st != -200` | `lib/data/sources/netease_source.dart:710` | +| 失效標記的更新路徑 | `TrackRepository.markUnavailable(id, reason)` 存在,但 `lib/`、`test/`、`tool/` grep **零呼叫端**(死代碼) | `lib/data/repositories/track_repository.dart:325-331` | +| 收藏/喜歡曲目 | **查不到**。沒有 track 層的 favorite。唯一 `isFavorite` 在 `RadioStation`(且無 UI 入口) | `lib/data/models/radio_station.dart:50`;`docs/audit/features.md:§14` | +| 孤兒曲目清理 | 啟動 10 秒後刪「`playlistInfo` 所有項目的 playlistId 都 <= 0 且不在佇列」的 Track;**不刪 `LyricsMatch`**(保留使用者手動挑的歌詞與 offset) | `lib/services/audio/queue_manager.dart:219-229`;`lib/data/repositories/track_repository.dart:634-673` | + +**代價**:孤兒清理只看 `playlistInfo`,而 `playlistInfo` 是手動維護的。`docs/adr/0010` 背景節記載這造成過資料遺失(下載同步重建關聯時對不上就丟,接著孤兒清理把曲目刪掉)。 + +--- + +## 2. 匯入流程 + +### 2.1 三條入口 + +| 入口 | 走的路 | 證據 | +|---|---|---| +| URL 匯入 B 站收藏夾/YouTube 播放清單/網易雲歌單 | `import_playlist_dialog` → `SourceManager.playlistParsingSourceForUrl` 認得 → `ImportService.importFromUrl` | `lib/ui/pages/library/widgets/import_playlist_dialog.dart:159-176`;`import_service.dart:156-330` | +| URL 匯入 QQ/Spotify 歌單 | 認不得 → `PlaylistImportService.detectSource` → 逐首搜尋比對 → 匯入預覽頁 | `import_playlist_dialog.dart:171-176`;`lib/services/import/playlist_import_service.dart` | +| 帳號歌單/電台匯入 | 帳號管理頁「管理歌單」,走 `ImportService.importFromUrl` 並帶 `useAuth=true` | `lib/ui/pages/settings/widgets/account_playlists_sheet.dart:277`;`docs/audit/features.md:§4` | + +### 2.2 `importFromUrl` 的建立/更新 + +- 解析 URL → 取 `PlaylistParseResult`(title/description/coverUrl/tracks/totalCount/ownerName/ownerUserId)→ 若是多 P 音源先展開分 P → 建或更新 `Playlist` → `addTracks` → 更新封面 → 寫 `lastRefreshed`。`import_service.dart:156-330`。 +- **更新既有歌單時刻意不覆寫 `name`、`description`**:更新分支只設 `importSourceType`、`ownerName`、`ownerUserId`、`useAuthForRefresh`、`refreshIntervalHours`、`notifyOnUpdate`、`updatedAt`(`import_service.dart:244-256`)。所以本地改過的名稱與描述在**重新匯入**時存活。 +- 但 `useAuthForRefresh` 與 `refreshIntervalHours` 會被這次呼叫的參數覆寫 —— 這正是 `questions.md` M12 說的「『使用登入狀態重新整理』會被重新匯入覆寫」。 +- 封面:`_updatePlaylistCover` 開頭 `if (playlist.hasCustomCover) return;`,沒自訂封面就用平台封面、否則退回第一首歌的縮圖、歌單空則清成 null(`import_service.dart:629-646`)。`hasCustomCover` 由 `updatePlaylist` 依「這次有沒有傳非空 coverUrl」設定(`playlist_service.dart:197-206`)。 +- B 站收藏夾的解析是**逐頁抓**(`ps=pageSize`、算 `totalPages`、每頁之間 `networkRetryDelay` 延遲),只有第一頁帶 `media_count` 當 `totalCount`(`lib/data/sources/bilibili_source.dart:535-645`)。網易雲是 `playlist/detail` 取 trackIds 後**分批抓詳情**(`netease_source.dart:258-326`、`:493-496`)。 + +### 2.3 刷新流程(`refreshPlaylist`) + +入口有兩個:手動(歌單卡「刷新」,`playlist_card_actions.dart:253-255`)與自動(`AutoRefreshService`)。兩者都走 `RefreshManagerNotifier.refreshPlaylist` → `ImportService.refreshPlaylist(playlistId)`(`lib/providers/library/refresh_provider.dart:124-266`;`import_service.dart:406-556`)。 + +差異計算是**整批集合運算,不是逐項 diff**,全部在一個 Isar 交易裡: + +`PlaylistMutationRepository.replaceTracksFromRemoteRefresh(playlistId, refreshedTracks, policy)`(`lib/data/repositories/playlist_mutation_repository.dart:427-605`): + +1. 先依 `uniqueKey` 去掉遠端回傳清單裡的重複(`:432`、`_dedupeTracksByUniqueKey`)。 +2. `_isar.writeTxn(...)` 包住整段(`:434`)。 +3. 以 `TrackSourceIdentity` 查既有曲目(`:456`、`_findTracksByIdentity` → `track_repository.getBySourceIdentities`)。 +4. 逐首: + - **新增**:既有清單查不到 → `tracks.putAll` 新增,記 `addedTrackIds`(`:483-486,537-538`)。 + - **元資料更新**:`_mergeTrackMetadataIfNeeded`(`:725-763`)只補**缺少的**欄位 —— `audioUrl`(既有 URL 失效才覆寫)、`thumbnailUrl`、`durationMs`、`artist`、`originalSongId`、`originalSource`。**`title` 不在其中**:遠端改標題不會同步下來。記 `updatedTrackIds`。 + - **成員修復**:`_ensureSinglePlaylistInfo` 修正這首歌在這個歌單的 `playlistInfo` 項(`:469-473`、`:765-799`)。 + - **不變**:記 `skippedTrackIds`。 +5. **順序**:遠端清單的順序直接覆寫 `playlist.trackIds`(`:593`)—— 這是唯一的順序來源,沒有本地排序概念。 +6. **刪除**:只有在 `canPruneRemovedTracks = policy.sourceDataComplete && errors.isEmpty` 時才真的刪(`:531-532`)。刪除會 `removeFromPlaylist`;`playlistInfo` 空了就 `tracks.deleteAll` 刪掉那一列 Track,否則只更新(`:560-591`)。 +7. **資料不完整時不刪**:`sourceDataComplete=false` 時走 `_mergePreservingExistingTrackOrder`(`:841-873`)—— 既有曲目一首不刪、順序不動,遠端新曲目插在「遠端順序裡排在它後面的第一首既有曲目」之前。回傳 `pruningSkipped=true`。 +8. 封面:`_updateRefreshCover`(`:820-840`)優先用平台封面,沒有才退回第一首歌縮圖;`hasCustomCover` 為真就完全不動。 + +`sourceDataComplete` 的判定在 `import_service.dart:469-471`:分 P 展開完整(`expansion.isComplete`)**且**(`totalCount <= 0` 或 抓到的首數 >= totalCount)。也就是說**中途任何一頁抓失敗都會讓這次刷新變成「只增不刪」**。 + +刷新成敗的呈現:成功 toast 顯示「新增 N 首/移除 N 首/N 首未變」「${name} 刷新完成!」(`lib/i18n/en/refreshProvider.i18n.json`;`refresh_provider.dart:204-218`)。失敗 toast「${name} 刷新失敗:${error}」(`refresh_provider.dart:243-247`)。 + +### 2.4 遠端歌單被刪或變私人 + +- **沒有任何「遠端歌單已消失」的處理。** 刷新時 `parsePlaylist` 直接拋:B 站 `_checkResponse` 把 -101/-111/-403/-607/11010/11201 映射成字串(11010 = `t.remote.error.contentNotFound`「內容不存在」),其餘「操作失敗 (code)」(`lib/services/account/bilibili_favorites_service.dart:247-279`)。YouTube 用伺服器原文(`youtube_playlist_service.dart:716-721`)。網易雲用 `data['message']`(`netease_playlist_service.dart:297-308`)。 +- 結果是 `refreshPlaylist` 拋出 → `RefreshManagerNotifier` 顯示 error toast → **本地歌單原封不動留著舊曲目**,`playlist` 沒有任何「已失效/遠端已刪」欄位,`needsRefresh` 仍為真,下次排程再試一次。 +- 認不出 URL 也會拋(`import_service.dart:438-440`、`:481-483`)。 +- **注意**:`ImportException` 的訊息已經是翻譯好的字串,但 `user_messageFor` 不認這個型別,會被壓成通用「發生錯誤」(`docs/audit/errors.md:§4.3` 第 1 點)。內部匯入顯示 `ImportException` 自己的文案,刷新路徑則經 `failureMessage`(`refresh_provider.dart:229-234`)。**推測**:實際 toast 文案會是通用錯誤句而非「內容不存在」。 + +### 2.5 自動刷新 + +| 事實 | 證據 | +|---|---| +| 每 30 分鐘檢查一次(類別註解誤寫「每小時」) | `lib/services/library/auto_refresh_service.dart:40-44`;`app_constants.dart:151` | +| 服務 provider 一被建立就 `start()`,且**立刻檢查一次** | `auto_refresh_service.dart:143-158` | +| 一次只刷一個歌單,刷完固定等 5 秒再下一個 | `auto_refresh_service.dart:86-116` | +| 候選排序:`needsRefresh` 為真者,`lastRefreshed` 最舊優先(null 最優先) | `auto_refresh_service.dart:69-81` | +| 不看前景/背景,app 開著就跑(唯一例外是電台輪詢會因生命週期暫停) | `docs/audit/features.md:§13.2` | +| 個別歌單間隔:`create_playlist_dialog.dart:61` 顯示新建預設;`Playlist.needsRefresh` 用 `refreshIntervalHours` | `playlist.dart:76-83` | + +**ADR 0017 的變更點(重寫版)**:舊版是 30 分鐘的固定輪詢 + 每張歌單各自的「到期」判斷;新版是單一排程器、只在可見且在線時跑、到期補跑,間隔改為 1/6/12/24/48/72/168 小時或不啟用。 + +--- + +## 3. 遠端操作(B1「從遠程播放列表移除」、B2「加入遠端歌單」) + +### 3.1 三個 adapter 與分派 + +`RemotePlaylistEditController` 以 `sourceType` 為鍵查 adapter;**查不到就回報整批失敗,刻意不 fallback**(避免把歌加到/刪掉另一個平台的歌單)。`lib/services/library/remote_playlist_edit_controller.dart:23-38,96-99,176-200`。三個 adapter 在 `lib/providers/library/remote_playlist_sync_provider.dart:39-77` 組裝。 + +- **B 站**:`getVideoAid` → `updateVideoFavorites(addFolderIds/removeFolderIds)`(`remote_playlist_edit_controller.dart:225-301`)。 +- **YouTube**:加入用 `addToPlaylist(playlistId, videoId)`;移除要先 `getSetVideoId` 拿 **setVideoId**,拿不到就記為 skipped(`:310-360`)。 +- **網易雲**:批次加入/移除 `trackIds`(`:367-428`)。 + +### 3.2 B1:從遠程播放列表移除 + +| 事實 | 證據 | +|---|---| +| 入口只在**匯入歌單**詳情頁:單曲紅色「從遠程播放列表移除」、多選同名項 | `lib/ui/pages/library/playlist_detail_page.dart:1502-1507,209-210` | +| 匯入歌單**沒有**本地「從歌單移除」;`remove_all` 也只有非匯入歌單有 | `playlist_detail_page.dart:1509-1514,1287-1294` | +| 確認框:標題「確定要從遠程播放列表中移除嗎?」、內容「同時會從本地歌單中移除。」,用 destructive 樣式 | `lib/i18n/zh-TW/remote.i18n.json`;`playlist_detail_page.dart:565-573`(批次)、`:1566-1582`(單曲) | +| 失敗處理三分支:遠端成功但本地同步失敗 → warning「已從遠程播放列表移除,但本地歌單同步失敗」;純失敗 → 第一筆誤的錯誤訊息;無變更 → 「沒有變更」 | `playlist_detail_page.dart:586-614`;`lib/services/library/remote_playlist_edit_controller.dart:101-128` | +| 成功後:先寫遠端 → 用 `confirmedRemovedTrackIds` 刪本地 → 再呼叫 `refreshMatchingImportedPlaylists`(背景刷新對應的本機匯入歌單,fire-and-forget,失敗只 log) | `remote_playlist_edit_controller.dart:101-143` | +| 「哪張本機歌單對應這個遠端 id」=用 `RemotePlaylistIdParser.parse(sourceType, sourceUrl)` 比對 | `lib/services/library/remote_playlist_sync_service.dart:30-50` | + +### 3.3 B2:加入遠端歌單 + +| 事實 | 證據 | +|---|---| +| 入口:曲目選單「加入遠端」、播放頁「加入歌單→遠端」、多選 | `lib/ui/handlers/track_action_handler.dart:218-235,298-311` | +| 未登入的來源被**過濾掉**(不是擋整批),並 toast「已跳過未登錄的 $platforms」 | `track_action_handler.dart:218-235`;`lib/services/library/remote_playlist_edit_planner.dart:55-64` | +| **沒有確認框**:勾選要加入的歌單/收藏夾 → 送出。按鈕文字只在「僅有新增、沒有移除」時顯示「添加到 N 個」,其餘顯示「確認」 | `lib/ui/widgets/dialogs/add_to_bilibili_playlist_dialog.dart:195-256`;`lib/ui/widgets/dialogs/remote_playlist_dialog_widgets.dart:408-420` | +| 對話框可新建歌單/收藏夾(B 站 `folder/add`、YouTube `playlist/create`、網易雲 `playlist/create`) | `docs/audit/features.md:§3`、§15.1 | +| 送出前先比對「該遠端歌單已有哪些 `sourceId`」,已在的不重複加 | `remote_playlist_edit_planner.dart:30-40`;`remote_playlist_edit_controller.dart:244-257,430-438` | +| 結果呈現:部分成功 → warning「部分完成 N/M」;全成功 → 「已更新收藏」;全失敗 → 第一筆錯誤;無變更 → 「沒有變更」 | `remote_playlist_dialog_widgets.dart:373-406` | +| 成功後同樣觸發對應本機匯入歌單的背景刷新 | `remote_playlist_edit_controller.dart:129-143` | + +### 3.4 與本地歌單的互斥 + +- 「加入歌單(本地)」對話框**只列非匯入歌單**(`lib/ui/widgets/dialogs/add_to_playlist_dialog.dart:96-101,252-256`)。 +- 匯入歌單在詳情頁不能加曲目、不能刪曲目、不能重排;只能改名稱/描述/封面與自動刷新設定(`lib/ui/pages/library/widgets/create_playlist_dialog.dart:118-130,448-465`)。 + +--- + +## 4. Spotify/QQ 匯入的匹配流程 + +### 4.1 演算法(自動) + +`PlaylistImportService.importAndMatch`(`lib/services/import/playlist_import_service.dart`): + +| 步驟 | 事實 | 證據 | +|---|---|---| +| 取歌單 | 第一個 `canHandle(url)` 的 `PlaylistImportSource.fetchPlaylist`;實作只有 `QQMusicPlaylistSource`、`SpotifyPlaylistSource` | `:137`;`lib/data/sources/playlist_import/playlist_import_source.dart:95-125` | +| 逐首搜尋 | **序列**執行,每首之間固定延遲:`all` 1000ms、單源 800ms | `:277-285`;`app_constants.dart:83-88` | +| 查詢字串 | `"$title ${artists.join(' ')}"` | `playlist_import_source.dart:28` | +| 取幾筆 | `maxResults × 8`,預設 `5 × 8 = 40` | `:153,312` | +| 搜尋來源 | `all`:並行搜 YouTube 與 Bilibili,單源失敗只 log;**網易雲不在內**。`bilibiliOnly`/`youtubeOnly`:單源,失敗直接拋、該首記 noResult | `:314-351,264-272` | +| 評分 | `_calculateRelevanceScore`:時長先過濾(`< -50` 直接回 -100);基礎分=標題相似度 ×0.35 + 歌手相似度 ×0.25 + 播放量 ×0.15 + 組合分 ×0.15;再加精確匹配/頻道與歌手/官方頻道/標題關鍵字/時長/版本/括號內歌名等加分 | `:443-535` | +| 相似度 | N-gram 與 Jaccard 取高者 | `:1044-1075` | +| 排序 | 過濾分數 < 0,取前 5,第一名自動選為 `selectedTrack`,狀態 `matched` | `:354-372,250-258` | +| 候選保留 | `MatchedTrack.searchResults` 保留最多 5 筆候選 | `playlist_import_source.dart:60-66` | +| 原平台 id | 建歌單時寫進 `Track.originalSongId` / `originalSource`(`'netease'\|'qqmusic'\|'spotify'`),供歌詞直取 | `:65-79,119-126` | + +### 4.2 失敗與手動改選 + +| 事實 | 證據 | +|---|---| +| 狀態機:`pending / searching / matched / noResult / userSelected / excluded` | `playlist_import_source.dart:45-53` | +| 未匹配的曲目集中顯示在預覽頁的 `_UnmatchedSection`,可逐首重搜 | `lib/ui/pages/library/import_preview_page.dart:330-466` | +| 已匹配的可展開看候選(`_AlternativeTrackTile`)並改選;改選後狀態 `userSelected`、可勾選是否納入 | `import_preview_page.dart:811-960,960-1090`;`lib/providers/library/playlist_import_provider.dart:299-310` | +| 結果持久化=寫成一般的 `Track`(帶 `originalSongId`),**沒有獨立的匹配紀錄表**,所以不會重算 | `playlist_import_service.dart:65-79` | + +### 4.3 與歌詞匹配是不是兩套評分 + +**是兩套,各自獨立的評分與門檻。** + +| 面向 | 歌單匯入 | 歌詞自動匹配 | +|---|---|---| +| 演算法位置 | `playlist_import_service.dart:443-535` | `lib/services/lyrics/lyrics_auto_match_service.dart:819-895` | +| 標題比對 | N-gram/Jaccard 取高 | Levenshtein | +| 權重 | 標題 0.35 / 歌手 0.25 / 播放量 0.15 / 組合 0.15 +多項加分 | 標題 0.4 / 歌手 0.3 / 時長 0.2 / 有同步歌詞 0.1 | +| 時長 | 差值評分表(≤10 秒 +20;>200% -100) | 差值分級(≤3 秒 1.0、≤10 秒 0.8、≤20 秒 0.5) | +| 門檻 | 過濾 < 0、取前 5、第一名自動選 | 最高分 ≥ 0.6 才採用 | +| 手動重搜 | `searchForTrack`:搜**全部已註冊音源(含網易雲)**、**只依播放量排序、不打分** | 手動搜尋走 `LyricsProvider`,與自動匹配不同的路徑 | + +手動重搜與自動匹配不一致:`playlist_import_service.dart:1156-1201`。 + +--- + +## 5. 重寫時值得注意的落差(事實,不是建議) + +1. **「遠端是權威」在舊版已經成立**(匯入歌單不能本地增刪、刷新以遠端覆寫順序),但**只在遠端資料完整時才刪除**(`sourceDataComplete`),其餘情況靜默變成「只增不刪」並回報 `pruningSkipped`。UI **不顯示** `pruningSkipped`(`refresh_provider.dart` 的 toast 只組 added/removed/skipped)。 +2. **`title` 不會被刷新更新**(`_mergeTrackMetadataIfNeeded` 不含 title),**`description` 只在首次匯入寫入**,之後遠端改描述不會同步下來。 +3. **遠端歌單消失/變私人沒有任何狀態**:只有一次 error toast,本地副本照舊、排程繼續重試。 +4. **沒有「已失效」的維護路徑**:`TrackRepository.markUnavailable` 零呼叫端;`isAvailable` 只在網易雲建構時判定一次。 +5. **沒有 track 層的收藏/喜歡**,舊版的「音樂庫」只有:本機歌單、匯入歌單、下載、播放歷史、佇列。 +6. **匹配結果沒有獨立持久層**:舊版的「不再重算」是靠寫成普通 `Track` 達成,代價是沒有「這首是匹配來的、原始平台 id 是什麼」以外的資訊(`originalSongId` / `originalSource` 有存)。 +7. **匯入歌單的遠端寫入沒有確認框(加入)/有確認框(移除)**:與擁有者「保留 App 內明確標示的遠端操作」一致,但加入方向目前沒有二次確認。 diff --git a/.trellis/tasks/09-28-design-library-sync/research/prior-art.md b/.trellis/tasks/09-28-design-library-sync/research/prior-art.md new file mode 100644 index 000000000..75f571d20 --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/research/prior-art.md @@ -0,0 +1,403 @@ +# Prior art:成熟產品怎麼處理「匯入的外部歌單」 + +- 查證日期:2026-09-28 +- 查證方式:`gh` CLI(`gh api repos//`、`/commits/`、`/git/trees/?recursive=1`、`/contents/?ref=`)讀取公開 repo 的程式碼與 git 物件;部分檔案以 base64 解碼後在本機 grep 行號。沒有使用 WebSearch、tavily-extract 或 WebFetch(所有事實都能在原始碼中找到,且原始碼比文件精確)。所有程式碼連結都固定到查證當下的 commit SHA。 +- 查證範圍:Spotube、Namida、MusicFree、Finamp(legacy 與 redesign 兩條分支)、LX Music(desktop)。共 5 個產品。 + +## 摘要對照表 + +| 產品 | 匯入歌單是唯讀鏡像或可編輯副本 | 差異比對方式 | 遠端刪除的處理 | 另存本機歌單 | 寫回前確認 | 匹配 UX | +|---|---|---|---|---|---|---| +| Spotube | 兩者皆非:**無本地副本**,純遠端視圖(drift schema 沒有歌單表) | 不適用(每次進頁面即時抓) | 不適用(無副本可刪) | 查不到 | 有加入曲目的 dialog;移除是否確認查不到 | 只在播放來源層做逐曲 id 快取(`source_match_table`),不暴露信心分數 | +| Namida | 帳號歌單=遠端即時視圖;App 內建的 YT 歌單與本地歌單才是本地物件 | 本地歌單靠 `PlaylistAddDuplicateAction` 處理重複;遠端歌單無本地鏡像故無差異比對 | 查不到(帳號歌單 live 抓取,遠端刪除自然消失) | 無「轉成本地歌單」;但加入曲目時 local / youtube 兩 tab 分流 | **有**:從遠端歌單移除前跳「確定移除?」 | 不跨平台匹配(整條路都在 YouTube 內) | +| MusicFree | **可編輯的本地副本**:匯入即複製成一份普通本地歌單 | 無(匯入後與來源完全脫鉤) | 不適用(無連結) | 匯入本身就是另存本地 | **有**:匯入前「找到 N 首,要匯入嗎?」 | 由外掛負責,App 只收一份曲目陣列;失敗=空陣列 →「無效連結」;無信心分數、無人工修正 UI | +| Finamp(legacy) | **唯讀鏡像**(下載副本),伺服器為準 | **id 集合差集**:`toAdd` / `toRemove` / `toUpdate`,先刪後載 | **自動刪除本地檔案,無確認**(同一首歌被別的 parent 需要時不刪) | 查不到 | 同步不是寫回;移除是寫回的一種,也無確認 | 不適用(Jellyfin item id 直接對應) | +| LX Music(desktop) | 不適用:無平台帳號,歌單一律本地 | 裝置對裝置同步自建歌單(list)與不喜歡清單(dislike),非外部平台匯入 | 不適用 | 不適用 | 不適用 | 不適用 | + +--- + +## Spotube + +- repo:`team-spotube/spotube`(原 `KRTirtho/spotube`,已改名;`gh api repos/KRTirtho/spotube` 會 redirect) +- 查證 commit:`69a310c78f5ceaf4eab7dfee98f187d38211c9ba`(`master`,committer date 2026-06-05) + +### 匯入歌單的模型 + +**沒有本地副本。** 我讀了 drift schema 的 v10 完整實體清單 +([`drift_schemas/app_db/drift_schema_v10.json`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/drift_schemas/app_db/drift_schema_v10.json)), +全部 10 張表是: + +``` +authentication_table, blacklist_table, preferences_table, scrobbler_table, +skip_segment_table, source_match_table, audio_player_state_table, +history_table, lyrics_table, plugins_table +``` + +沒有 playlist 表、沒有 playlist↔track 關聯表。歌單內容一律透過 metadata plugin +(Spotify / YouTube Music 的 Hetu script 外掛)向平台要,因此「匯入的歌單」與 +「平台上建立的原生歌單」在資料層是同一個東西,沒有本地鏡像可言: + +- 讀取走 [`MetadataPluginPlaylistEndpoint.getPlaylist` / `tracks`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/metadata/endpoints/playlist.dart#L13-L33) +- 編輯走 [`addTracks` / `removeTracks`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/metadata/endpoints/playlist.dart#L87-L113) +- `create` / `update` / `save` / `unsave` / `deletePlaylist` 是同一組遠端操作 + ([`playlist.dart#L43-L131`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/metadata/endpoints/playlist.dart#L43-L131)) + +呼叫端是 Riverpod 的 `MetadataPluginPlaylistNotifier`,`create` / `modify` / +`addTracks` / `removeTracks` 全部直接呼叫 plugin 後 `ref.invalidateSelf()` +([`lib/provider/metadata_plugin/playlist/playlist.dart#L60-L140`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/metadata_plugin/playlist/playlist.dart#L60-L140))。 + +### 刷新與差異比對 + +不適用:沒有本地副本,就沒有差異比對;每次進歌單頁重新向平台抓。 + +本地唯一的逐曲持久化是 **播放來源匹配快取**,不是歌單同步: +`source_match_table`(欄位 `track_id, source_info, source_type`)。這是 +Spotube「Spotify 曲目 → 可用播放來源」的比對結果快取,見 +[`lib/models/database/tables/source_match.dart`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/models/database/tables/source_match.dart) +與 [`lib/provider/server/active_track_sources.dart`](https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/server/active_track_sources.dart)。 + +### 刪除、本地修改的保留 + +不適用(沒有本地副本可被遠端刪除影響)。 + +### 寫回平台 + +寫回就是唯一的編輯途徑(`addTracks` / `removeTracks` / `update`),沒有本地暫存後再推送的流程。 + +### 匹配 UX + +Spotube 解決的是「Spotify 曲目 → 可播放來源」而不是「歌單轉換」,逐曲快取在本地, +但**沒有**信心分數、候選清單或人工修正的介面暴露給使用者(依 `source_match.dart` +的欄位形狀判斷;未逐行驗證 UI 層是否另有候選選擇器 → **推測**)。 + +### 來源清單 + +- https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/drift_schemas/app_db/drift_schema_v10.json +- https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/metadata/endpoints/playlist.dart#L13-L131 +- https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/metadata_plugin/playlist/playlist.dart#L60-L140 +- https://github.com/team-spotube/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/models/database/tables/source_match.dart + +--- + +## Namida + +- repo:`namidaco/namida` +- 查證 commit:`e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5`(`main`,committer date 2026-09-26) + +### 匯入歌單的模型 + +Namida 有兩類歌單,語意不同: + +1. **App 內建立的歌單**(含以 YouTube 曲目為成員的「YT 歌單」):本地物件, + 由 `PlaylistManager` 管理。 + [`YoutubePlaylistController extends PlaylistManager`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/controller/youtube_playlist_controller.dart#L27-L36), + `identifyBy(item) => item.id`(用 YouTube video id 當身分鍵)。 +2. **YouTube 帳號上的歌單**:**遠端即時視圖**,不落地。 + `youtube_user_playlists_page.dart` 走 + [`youtube_main_page_fetcher_acc_base`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/pages/youtube_user_playlists_page.dart#L18-L20) + 從帳號抓,編輯則透過 `YtUtilsPlaylist.promptCreatePlaylist` / + `promptEditPlaylist` 直接對 YouTube 下 API;`promptEditPlaylist` 的註解寫明 + 「we prefer always loading live info for better cross-device sync」 + ([`lib/youtube/functions/yt_playlist_utils.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/yt_playlist_utils.dart#L52-L62))。 + +**關鍵:我沒有在程式碼裡找到「把遠端 YouTube 歌單匯入成 Namida 本地歌單」這個動作。** +有的是「下載歌單」(`lib/youtube/pages/yt_playlist_download_subpage.dart`,把曲目抓成本地檔案) +與「把曲目加入歌單」時 local / remote 兩個 tab。→ 這一項標「查不到」。 + +### 刷新與差異比對 + +- 本地歌單:靠 `PlaylistAddDuplicateAction` 處理重複,寫入後跳 undo snackbar + ([`youtube_playlist_controller.dart#L65-L96`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/controller/youtube_playlist_controller.dart#L65-L96))。 +- 遠端帳號歌單:無本地鏡像,因此**沒有差異比對**;每次進頁面重新抓。 + +### 刪除、本地修改的保留 + +查不到。遠端帳號歌單因為是 live 抓取,遠端刪除後自然不再出現;本地歌單不受影響 +(**推測**,未逐行驗證是否有 tombstone 或快取)。 + +### 另存成本地歌單 + +沒有「把遠端歌單一鍵轉成本地歌單」的功能。最接近的是加入曲目時的分流 UI: +同一個 bottom sheet 有 `lang.local` / `lang.youtube` 兩個 tab +([`lib/youtube/functions/add_to_playlist_sheet.dart#L97`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/add_to_playlist_sheet.dart#L97)), +使用者直接選擇寫到本地或寫到遠端。 + +### 寫回平台 + +UI 是 `add_to_playlist_sheet.dart`;實際寫入呼叫 +`YoutiPie.playlistAction.addRemoveVideosInPlaylist(...)` +([`#L247-L284`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/add_to_playlist_sheet.dart#L247-L284))。 + +**寫回前確認**: + +- **移除**遠端歌單曲目 → `_confirmRemoveVideos()` 跳「確定移除?」對話框 + ([`#L224-L245`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/add_to_playlist_sheet.dart#L224-L245))。 +- **加入**遠端歌單 → 沒有二次確認,只有重複曲目的處理選項 + (`showDuplicatedDialogAction`)。 + +寫入回傳值是 `bool done`,失敗處理我沒讀到完整的錯誤路徑 → 查不到細節。 + +### 匹配 UX + +不適用:Namida 的歌單轉換不跨平台,整條路都在 YouTube 內。 + +### 來源清單 + +- https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/controller/youtube_playlist_controller.dart#L27-L96 +- https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/add_to_playlist_sheet.dart#L97-L336 +- https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/functions/yt_playlist_utils.dart#L52-L62 +- https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/pages/youtube_user_playlists_page.dart + +--- + +## MusicFree + +- repo:`maotoumao/MusicFree` +- 查證 commit:`d118b18b3d0c904400f7eea7bf99c0ceec6c1aee`(`master`,committer date 2026-06-20) + +### 匯入歌單的模型 + +**可編輯的本地副本,而且是「匯入即複製」的一次性動作。** + +歌單(MusicSheet)一律是本地物件,核心在 +[`src/core/musicSheet/index.ts`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/musicSheet/index.ts), +以 MMKV 持久化(同目錄 `storage.ts`、`sortedMusicList.ts`)。 +預設歌單是 `{ id: "favorite", platform: localPluginPlatform, title: "我喜欢" }`。 + +匯入外部歌單靠外掛宣告的 `importMusicSheet` 能力: + +```ts +const validPlugins = PluginManager.getSortedPluginsWithAbility("importMusicSheet"); +``` + +[`importMusicSheet.tsx#L19`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/importMusicSheet.tsx#L19) + +流程:貼上連結 → `plugin.methods.importMusicSheet(text)` 回傳 +`IMusic.IMusicItem[]` → **這份陣列就是本地歌單的內容**,之後與來源平台再無關聯。 + +### 刷新與差異比對 + +**沒有。** 匯入後就是一份普通本地歌單,跟「我喜歡」同等;沒有 re-sync、 +沒有刷新按鈕、沒有 TTL。程式碼裡看不到任何「來源歌單 id ↔ 本地歌單」的連結欄位 +(`IMusic.IMusicSheetItemBase` 只有 `id / platform / coverImg / title / worksNum`)。 + +### 刪除、本地修改的保留 + +不適用:無連結,本地增刪改完全自由。 + +### 另存成本地歌單 + +匯入流程本身就是「另存成本地歌單」: + +```ts +showDialog("SimpleDialog", { + title: t("panel.importMusicSheet.prepareImport"), + content: t("panel.importMusicSheet.foundSongs", { count: result.length }), + onOk() { showPanel("AddToMusicSheet", { musicItem: result }); }, +}) +``` + +[`importMusicSheet.tsx#L58-L80`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/importMusicSheet.tsx#L58-L80) + +`AddToMusicSheet` 面板再讓使用者選「加到既有歌單」或「新建歌單」 +([`addToMusicSheet.tsx`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/addToMusicSheet.tsx))。 + +### 寫回平台 + +不存在。本地歌單沒有遠端對應物件。 + +### 匹配 UX + +匹配完全由外掛負責,App 只收一份已經定案的曲目陣列。 +**失敗的呈現**:`result.length === 0` → `Toast.warn(t("panel.importMusicSheet.invalidLink"))` +([`#L72-L77`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/importMusicSheet.tsx#L72-L77))。 +沒有信心分數、沒有候選清單、App 層沒有逐曲人工修正。 + +### 自動刷新間隔 / 離線行為 + +不適用(無連結、無刷新)。 + +### 來源清單 + +- https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/importMusicSheet.tsx#L19-L87 +- https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/addToMusicSheet.tsx +- https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/musicSheet/index.ts + +--- + +## Finamp + +- repo:`finamp-app/finamp`(Jellyfin 音樂客戶端) +- 查證 commit: + - `legacy` 分支 `f49ba47f491fbaf3aeeb67540e8cc788ad2cd307`(committer date 2026-08-10)— 有完整下載/同步實作 + - `redesign` 分支 `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc`(committer date 2026-09-26)— 重寫版 +- 注意:`jellyfin/Finamp` 已 404,現址是 `finamp-app/finamp`。 + +### 匯入歌單的模型 + +**唯讀鏡像。** Finamp 的「匯入」就是「下載歌單」:把 Jellyfin 伺服器上某個 +playlist 的曲目下載到本地,本地集合是伺服器集合的鏡像,**伺服器為準**。 +`DOWNLOADS_PLAN.md` 也把 playlist 歸類為 download parent(與 album 同級): + +> `DownloadedParents` - stores data about parents (albums, playlists), with links to children. + +[`DOWNLOADS_PLAN.md`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/DOWNLOADS_PLAN.md) + +### 刷新與差異比對 + +**依 Jellyfin item id 做 id 集合的差集**,這是整份研究裡最明確的差異比對實作。 +`_getSyncState` 建兩個集合——「歌單現在的曲目 id」與「本地已下載且 +`requiredBy` 含這個 parent 的曲目 id」——然後回傳三組: + +```dart +Set playlistIds = playlistItems.map((e) => e.id).toSet(); +Set downloadedIds = + downloadedSongsCache.map((e) => e.mediaSourceInfo.id!).toSet(); +return SyncState( + playlistIds.difference(downloadedIds), // toAdd + downloadedIds.difference(playlistIds), // toRemove + playlistIds.intersection(downloadedIds), // toUpdate + playlistItems); +``` + +[`lib/services/sync_helper.dart#L108-L143`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L108-L143) + +`sync()` 的順序是**先刪後載**: + +```dart +await _removeDownloadedItems(parentObject.id, syncState.toRemove); +await _downloadItems(context, parentObject, syncState); +``` + +[`#L35-L49`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L35-L49); +`toAdd` 與 `toUpdate` 都會進下載佇列,註解寫明理由是 +`// we include update items in case any items have been orphaned` +([`#L52-L80`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L52-L80))。 + +**保留本地修改的機制**:沒有。本地沒有可修改的欄位,鏡像的唯一狀態就是「有沒有下載」。 + +### 遠端刪掉的曲目在本地怎麼處理 + +**自動刪除本地檔案,沒有確認、沒有痕跡。** `toRemove` 直接丟進 +`deleteDownloadChildren(jellyfinItemIds: ..., deletedFor: playlistParentId)`, +之後若該 parent 已無子項就一併 `deleteDownloadParent` +([`#L91-L107`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L91-L107))。 + +`deletedFor` 這個參數配上 `DownloadedSong.requiredBy` 是 list,暗示 +「同一首歌還被別的 album/playlist 需要時不該被刪」;我沒有逐行驗證 +`deleteDownloadChildren` 的實作 → **推測**。 + +### 另存成本地歌單 + +查不到。Finamp 的本地單位是 download parent(album / playlist 的下載副本), +不是使用者可自由編輯的歌單。 + +### 寫回平台 + +**同步不是寫回,它只下載**;寫回 Jellyfin 的編輯在 redesign 分支的 +`lib/screens/playlist_edit_screen.dart`、`lib/menus/components/menuEntries/remove_from_current_playlist_menu_entry.dart`、 +`lib/components/AlbumScreen/playlist_edit_button.dart` +(檔案清單見 [`redesign` tree](https://github.com/finamp-app/finamp/tree/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib)。 +那些編輯是否直接寫伺服器、有無確認,未逐行驗證 → **推測**)。 + +同步的 UI 入口有兩個粒度,都是 icon button、都沒有確認對話框: + +- 全部:Downloads 頁的 sync 按鈕,iterate 所有 downloaded parent + ([`lib/components/DownloadsScreen/sync_downloaded_playlists.dart#L19-L42`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/components/DownloadsScreen/sync_downloaded_playlists.dart#L19-L42)) +- 單一:專輯/歌單頁的 sync/download 按鈕 + ([`lib/components/AlbumScreen/sync_album_or_playlist_button.dart#L29-L50`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/components/AlbumScreen/sync_album_or_playlist_button.dart#L29-L50)) + +同步過程中唯一的對話框是「選下載位置」,而且只在有多個 download location 時才跳: + +```dart +final selectedDownloadLocation = FinampSettingsHelper.finampSettings.downloadLocationsMap.values.length > 1 + ? await showDialog(... DownloadDialog ...) + : FinampSettingsHelper.finampSettings.downloadLocationsMap.values.first; +``` + +([`sync_helper.dart#L68-L80`](https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L68-L80)) + +### 匹配 UX + +不適用。Jellyfin 客戶端,伺服器 item id 直接對應,沒有跨平台匹配。 + +### 自動刷新間隔 / 離線 + +**沒有排程、沒有可設定的間隔**:同步一律由使用者按 sync 按鈕觸發(原始碼裡看不到 +timer / scheduled sync)。離線時播本地已下載的檔案,這是下載系統存在的理由。 + +`DOWNLOADS_PLAN.md` 另外記載一個和 FMP 高度相關的教訓:舊下載系統用**五個各別維護的 +key-value DB**(`DownloadedItems` / `DownloadedParents` / `DownloadIds` / +`DownloadedImages` / `DownloadedImageIds`)「all need to be kept in sync」, +作者自評是「very finnicky, and frequently breaks between updates」;1.0 改用 +Isar 建立真正的關聯,並以 `background_downloader` 取代 `flutter_downloader`。 + +### 來源清單 + +- https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/services/sync_helper.dart#L35-L143 +- https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/components/DownloadsScreen/sync_downloaded_playlists.dart#L19-L42 +- https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/lib/components/AlbumScreen/sync_album_or_playlist_button.dart#L29-L50 +- https://github.com/finamp-app/finamp/blob/f49ba47f491fbaf3aeeb67540e8cc788ad2cd307/DOWNLOADS_PLAN.md + +--- + +## LX Music(desktop)— 相關性低,僅作對照 + +- repo:`lyswhut/lx-music-desktop` +- 查證 commit:`ad95d5091c9ed689fa72b5e5c849df65f5a679ce`(`master`,pushed_at 2026-09-19) + +LX Music 沒有平台帳號,它的「遠端」是使用者自己架的同步伺服器。同步模組只有兩個 +種類:自建歌單與不喜歡清單。 + +``` +src/main/modules/sync/client/modules/list +src/main/modules/sync/client/modules/dislike +src/main/modules/sync/server/modules/list +src/main/modules/sync/server/modules/dislike +``` + +(由 [`git/trees/?recursive=1`](https://github.com/lyswhut/lx-music-desktop/tree/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/sync) 過濾 `sync/(client|server)/modules/` 得到) + +**結論:LX Music 不處理「匯入外部平台歌單」,沒有可對照的唯讀鏡像/差異比對/ +寫回確認設計。** 它的 list 同步是裝置對裝置,權威方向推測與 Finamp 同向 +(伺服器 snapshot → 本地)→ **推測**,未逐行驗證。 + +### 來源清單 + +- https://github.com/lyswhut/lx-music-desktop/tree/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/sync + +--- + +## 對 FMP 的啟示(10 條) + +1. **Spotube 證明了「無本地副本」可行,但不適用於 FMP。** 它的 drift schema + 裡一張歌單表都沒有,代價是離線完全沒有歌單內容、也無處放自訂名稱/封面。 + FMP 已定案「名稱、描述、封面可本地改」,所以必須有本地表。(Spotube) +2. **差集式同步是這批產品裡唯一成形的差異比對實作,值得照抄形狀。** + Finamp 用 id 集合的 `A-B` / `B-A` / `A∩B` 三組決定刪、載、更新,配一個 + `requiredBy` 清單讓一首歌被多個 parent 需要時不誤刪。FMP 的比對鍵要能同時容納 + 「遠端曲目 id」與「本地匹配結果」,這個形狀可以直接對應。(Finamp) +3. **不要讓「遠端刪除」直接刪本地資料。** Finamp 是靜默刪檔;FMP 的比對鍵來自匹配, + 一次解析失敗不該被誤判成「遠端刪了」。遠端刪除應該是本地的一種狀態(例如標記 + 「已從遠端移除」),而非刪除。(Finamp + 推論) +4. **匯入即複製(MusicFree)與持續鏡像(Finamp)是兩個極端。** FMP 已定案站鏡像這一端, + 但應該保留 MusicFree 的匯入前 UX:「先告訴我抓到幾首,再讓我確認」。(MusicFree) +5. **寫回前的確認在 Namida 有先例,而且分得剛好。** 從遠端歌單**移除**要確認 + (`_confirmRemoveVideos`),**加入**不確認(只處理重複)。FMP 的 + 「從遠程播放列表移除」應該比照加確認。(Namida) +6. **「本地 vs 遠端」用同一個 sheet 的兩個 tab 分流**(Namida 的 + `lang.local` / `lang.youtube`)。FMP 的「加入遠端歌單」可以直接沿用這個形狀, + 讓使用者一眼看出自己正在寫哪裡。(Namida) +7. **寫回失敗要有明確回報。** Namida 的寫回只回傳 bool、失敗只 toast;FMP 的 + 「改完再同步下來」流程裡,使用者期待遠端操作成功後本地會更新,失敗必須看得見。 + (Namida) +8. **沒有產品提供逐曲匹配的信心分數或人工修正 UI。** Spotube 的匹配快取只在播放 + 來源層,不對使用者揭露;MusicFree 把匹配整包交給外掛。FMP 若要設計匹配修正, + 這裡沒有現成慣例可抄,最接近的既有模式是「匯入後列出結果讓你確認」。(Spotube / MusicFree) +9. **1–168 小時的自動刷新間隔在這些產品裡沒有先例。** Finamp 是手動 sync 按鈕 + (兩種粒度:全部/單一),Spotube 是進頁面即時抓,MusicFree 無連結,LX Music 無此概念。 + FMP 這條屬於自訂設計,無外部驗證可依賴。(全部) +10. **跨 store 一致性是這類功能的頭號失敗模式。** 舊 Finamp 的 `DOWNLOADS_PLAN.md` + 自述五個 key-value DB「all need to be kept in sync」是下載系統一直壞的主因, + 最後改用關聯式模型重寫。FMP 的「本地歌單 ↔ 遠端歌單 ↔ 本地檔案 ↔ 匹配結果」 + 同樣橫跨多個 store,這條要當警訊。(Finamp) diff --git a/.trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md b/.trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md new file mode 100644 index 000000000..39d20eaee --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md @@ -0,0 +1,324 @@ +# 同步演算法與匹配的技術事實 + +- 查證日期:2026-09-28 +- 查證方式: + - `mcp__context7__query-docs`(library `/websites/drift_simonbinder_eu`,即 )查 drift 官方文件 + - `mcp__tavily-lb__tavily-search`(basic)查 SQLite、排序演算法、各平台 id 穩定性、Unicode 正規化 + - `curl` 直接讀 `https://pub.dev/api/packages/` 與 `/score`(版本、發佈日期、pub points、likes、下載數、授權 tag),以及 GitHub REST API 取授權 + - `curl` 讀 `https://raw.githubusercontent.com/simolus3/drift/develop/drift/lib/src/sqlite3/database.dart` 確認 drift 實際發出的 transaction SQL + - 本地唯讀:`lib/services/import/playlist_import_service.dart`、`lib/services/lyrics/lyrics_auto_match_service.dart`、`lib/core/constants/app_constants.dart` +- 標記約定:**推測** = 由已知事實推導但無直接來源;**查不到** = 本次查證範圍內找不到可信來源。所有版本號與日期逐字取自 pub.dev API,非憑記憶。 + +--- + +## A. 以遠端為權威的單向同步 + +### A1 差異計算 + +**四類差異的定義與算法選擇** + +單向(遠端權威)同步與雙向同步的差異計算難度不同,這點決定了要不要引入 diff 演算法。 + +| 差異類別 | 偵測方式 | 需要 diff 演算法嗎 | +|---|---|---| +| 新增 | 遠端 key 集合 − 本地 key 集合 | 不需要(集合差) | +| 移除 | 本地 key 集合 − 遠端 key 集合 | 不需要(集合差) | +| 移動(順序) | 兩邊同一個 key 的 order 值不同 | 不需要(逐列比對欄位) | +| 元資料(標題/歌手/時長/封面) | 兩邊同一個 key 的欄位值不同 | 不需要(逐欄比對) | + +成熟做法分兩派: + +1. **遠端提供序號時直接覆寫**。YouTube Data API 的 playlist item 就帶 `snippet.position`(unsigned integer,0 起算),且 `PlaylistItems.update` 可指定 `snippet.position`——順序是伺服器端的一等公民欄位,客戶端不需要自己算「誰被移走了」(來源:;GeeksforGeeks 的 `playlist_item_update_position` 範例 )。此時差異計算退化為「把遠端 position 寫進本地 order 欄位,只 UPDATE 值不同的列」。 +2. **遠端只給一組有序陣列、自己算差異**時才用 LCS / Myers diff / 最長遞增子序列(LIS)求「最少移動次數」。這在雙向同步或要產生 patch 時才有價值,代價是 O(n·d) 或 O(n log n) 的時間與額外程式碼。 + +**關鍵事實:單向權威下不需要 LCS。** 因為本地不允許使用者改順序(決策已定:使用者不能在本地增刪匯入歌單的曲目),所以不存在「兩邊各自編輯」需要三方合併的情境。差異就是「遠端狀態 → 本地狀態」的覆寫,比較集合與欄位即可。 + +**實務上仍要注意的一點**:YouTube 允許同一支影片在同一張歌單出現多次(`ytmusicapi` 的 `add_playlist_items` 有 `duplicates` 參數說明這件事,來源:)。因此「以曲目 key 為唯一鍵」的集合運算會把重複項摺疊掉。若要保持「同一首歌在歌單裡出現兩次」,關聯表不能只用 `UNIQUE(playlist_id, track_key)`,而要允許 (playlist_id, track_key, position) 有多列——位置本身才是那一筆的身分。(**推測**:這是 ytmusicapi 文件推導出的結論,未在 YouTube 官方文件看到明文規定重複項的唯一性語意。) + +### A2 穩定排序 + +**問題**:遠端沒給穩定順序時(或遠端只給「新增到最後」的語意時),關聯表的排序欄位怎麼維護。 + +三種成熟做法: + +1. **整數連續(1,2,3…)+整表重排**。任何一次插入/移動都要 UPDATE 後續所有列。5000 列在一次 transaction 內就是 5000 次 UPDATE——SQLite 實務上完全可行(單一 transaction 內的 UPDATE 不做 fsync,只在 COMMIT 時 flush 一次),但每次刷新都寫滿全表會讓 WAL 膨脹、也讓「這次刷新動了哪幾首」難以從資料庫看出。 +2. **稀疏整數排序(sparse ordering)**:間隔 1000(1000, 2000, 3000…),插入時取中間值(`Pnew = (Pi + Pi+1) / 2`),只有新元素要寫;間隔用盡才重排一次。來源:。該文比較後明確偏好稀疏整數而非浮點 fractional indexing:「For most applications, sparse integer ordering is preferable: it is predictable, stable, and easier to monitor for rebalancing.」 +3. **字典序排序(LexoRank / fractional indexing)**:用字串 key,`generateKeyBetween(a, b)` 可在任意兩 key 之間產生新 key,永不重排。Jira 的 LexoRank 是代表實作(來源:);純 fractional indexing 的說明見 與 。 + +**drift / SQLite 上實際可行的做法** + +- 稀疏整數用 `INTEGER` 欄位配 `ORDER BY position, id`(第二鍵當 tie-breaker,避免兩列同值時順序不確定)。整數排序在 SQLite 上走 B-tree,無額外成本。 +- LexoRank 在 SQLite 就是 `TEXT` 欄位配預設 `BINARY` collation;可行但要自己實作 base-62 進位與 bucket 正規化,是三者中實作成本最高的。 +- 一個對 FMP 更省事的變體:**直接存遠端 position**(例如 YouTube 的 `snippet.position`),不自己做稀疏間隔。遠端是權威,遠端怎麼排本地就怎麼存;只有遠端沒給 position 的時候(**推測**:B 站收藏夾 API 只回有序陣列、不回 position 欄位)才退化成「陣列索引寫進 position 欄位」。此時每次刷新都是整表 position 覆寫,但因為單向且整批在同一個 transaction 裡,寫入量與第 1 種做法相同,不需要稀疏間隔的複雜度。 +- drift 宣告唯一鍵的方式是覆寫表格的 `uniqueKeys`(`List>>`),複合外鍵走 `customConstraints` 覆寫(來源:、)。 + +### A3 大歌單效能與分頁 + +**drift 的 bulk insert 官方做法:batch** + +```dart +await batch((batch) { + // functions in a batch don't have to be awaited - just + // await the whole batch afterwards. + batch.insertAll(todos, [ /* companions */ ]); +}); +``` + +來源:。要點是「batch 內的呼叫不必逐一 await,整個 batch 一起 await」,batch 本身包在單一 transaction 內。 + +Upsert 用 `insertOnConflictUpdate(...)`,或對非主鍵的唯一鍵指定衝突目標: + +```dart +return into(matches).insert( + data, + onConflict: DoUpdate((old) => data, target: [matches.teamA, matches.teamB]), +); +``` + +(同上來源;`target` 需要該欄位組已在 `uniqueKeys` 宣告。) + +**常見瓶頸(依重要性排序)** + +1. **逐列 await 各自成一個 transaction**。沒有包 transaction 時,每一條 INSERT 都是一次自己的隱式 commit,也就是一次 fsync。5000 首會變成 5000 次 fsync,這是行動裝置上真正的殺手。解法只有一個:把整批(或分批)放進 `batch()` 或顯式 `transaction()`。 +2. **`InsertMode.insertOrReplace` 的語意陷阱**:SQLite 的 `INSERT OR REPLACE` 在衝突時是 **DELETE 既有列再 INSERT**,不是 UPDATE。對有外鍵 `ON DELETE CASCADE` 的關聯表,這會連動刪掉子列;對被其他表外鍵參照的曲目列,可能觸發 cascade 或 FK 違反。要「合併」而不是「換掉」時應該用 `DoUpdate`(真 UPDATE),只有在「這列的存在與否由遠端決定」時才適合 replace。(**推測**:由 SQLite 的 `INSERT OR REPLACE` 語意推導;drift 沒有針對此語意的專文。) +3. **事務時間過長造成寫鎖持有過久**。見 A4:drift 的 sqlite3 實作在 transaction 開始就取寫鎖(`BEGIN IMMEDIATE`)。一個 5000 列的大 transaction 會在這段時間內擋住所有其他寫入。WAL 模式下讀取不受影響(見 A4)。 +4. **從遠端抓取本身的 API 分頁**,與本地寫入是兩件事,不要綁在一起。YouTube `playlistItems.list` 的 `maxResults` 上限是 50(`pageToken`/`nextPageToken` 分頁),所以 5000 首至少 100 次請求。 + +**建議的形狀(給 FMP)**:遠端抓取與本地寫入解耦成「抓一頁 → 寫一頁」的流水線,每頁一個 transaction;整張歌單的最終一致狀態由 A4 的 refresh generation 標記保證。這樣記憶體不會一次扛 5000 筆,進度可持久化、可中斷續跑,寫鎖也不會被單一巨大 transaction 長時間佔住。 + +### A4 刷新失敗的原子性(drift / SQLite) + +**drift `transaction()` 的官方語意(版本:drift 2.35.0,2026-09-09 發佈,來源 )** + +- 巢狀 transaction 自 **drift 2.0** 起支援。內層 transaction 的寫入在成功完成前只對外層可見(等於一次原子更新)。 +- 內層拋出例外時,內層被回滾,外層回到「內層開始前」的狀態。外層若 catch 掉例外,可以繼續;不 catch 則例外往上冒、連外層一起回滾。 +- 支援巢狀的實作:`NativeDatabase`、`WasmDatabase`、`WebDatabase`、`SqfliteDatabase`,以及跑在 isolate / web worker 上的遠端連線(只要底層支援)。 +- **所有查詢都必須 await**:transaction 在傳入的函式回傳時結束;漏 await 會讓查詢用到已關閉的 transaction,drift 有檢查並會拋例外。**timer 之類的非同步排程不能在 transaction 內安排**,因為它們會在 transaction 結束後才執行。 +- 來源:(官方文件,本次逐段引用前述四點) + +**drift 實際發出的 SQL:`BEGIN IMMEDIATE`(原始碼確認)** + +`drift/lib/src/sqlite3/database.dart`(develop 分支)中,`Sqlite3Delegate.transactionDelegate` 回傳: + +```dart +return const NoTransactionDelegate( + // We don't currently have readonly transactions. So we might as well + // acquire the write lock at the earliest opportunity to avoid contention + // issues on the first statement of the transaction (if multiple database + // connections are opened to the same underlying database). + start: 'BEGIN IMMEDIATE', +); +``` + +來源:(第 66–74 行)。也就是說:**在 native(Android / Windows)上,drift 的 `transaction()` 一進去就取寫鎖**,不是等到第一條寫入才升級。這對「一次刷新要嘛全成功要嘛全不動」是好消息——不會有「讀完才發現要升級鎖、然後 SQLITE_BUSY」的中途失敗。官方文件沒有明文寫這件事,**查不到**文件層級的說明,只能從原始碼確認。 + +**SQLite 層面的意義** + +- `BEGIN`(=`BEGIN DEFERRED`)一開始只是讀交易,第一條讀取才真正開始,之後若要寫入則在升級時取鎖;若此時別的連線已持有寫鎖,SQLite **立刻**回 `SQLITE_BUSY`,且**不遵守 `busy_timeout`**。來源:SQLite 官方 與官方論壇 ;實測與解說另見 。 +- `BEGIN IMMEDIATE` 立即開始寫交易;若已有其他寫交易,回 `SQLITE_BUSY`(此時可以走 `busy_timeout` 重試)。`BEGIN EXCLUSIVE` 在 **WAL 模式下與 IMMEDIATE 相同**,差異只在 rollback journal 模式。來源同上。 +- **WAL 模式**的價值:單一寫者與多個讀者可以並行。drift 官方文件在多執行緒(isolate + read pool)情境明白寫道,開 WAL 是為了避免「database locked」,且「a single writer and multiple readers can operate on the database in parallel」: + + ```dart + NativeDatabase.createInBackground( + File('path/to/database.db'), + setup: (database) { + database.execute('pragma journal_mode = WAL;'); + }, + readPool: 4, + ); + ``` + + 來源:。同一頁也說明 transaction 與 `exclusively` 區塊一定走寫 isolate。 +- **外鍵強制**:SQLite 預設不強制外鍵,必須 `PRAGMA foreign_keys = ON`。drift 官方建議在 `beforeOpen` 開、在 migration 期間關(`PRAGMA foreign_keys = OFF`),並在 debug 用 `PRAGMA foreign_key_check` 驗證沒有孤兒列: + + ```dart + beforeOpen: (details) async { + await customStatement('PRAGMA foreign_keys = ON'); + }, + ``` + + 來源:、、。 + +**對「一次刷新要嘛全成功要嘛全不動」的結論** + +- 把整次刷新的寫入包在一個 `transaction()` 裡,就能拿到這個保證:drift 發 `BEGIN IMMEDIATE` → 取寫鎖 → 全部成功才 COMMIT,任何例外(含 await 到的網路錯誤)都回滾。這是**唯一**能達到「全有全無」的機制;`batch()` 與 `transaction()` 的差別在於 batch 只是一組語句,仍需要有外層 transaction 才能跨多個 batch 原子化。(**推測**:drift 文件未明說 batch 自帶 transaction,但 `transaction()` 的說明與 batch 的「一起 await」寫法都指向 batch 在單一 transaction 內執行;此點若要絕對確定,需看 drift 原始碼 `batch()` 實作。) +- 但整張 5000 首包一個 transaction 會長時間持有寫鎖(`BEGIN IMMEDIATE` 從頭到尾),代價是所有其他寫入被擋。折衷是 A3 的「分頁 transaction + refresh generation」:每頁寫入時帶上本輪的 `refresh_generation` 標記,全部頁數寫完才把 generation 標記為 complete;查詢一律只讀「最新 completed generation」。這樣中途失敗的結果是「舊的完整版本還在」,而不是「半新半舊」。這是對 FMP 的建議(**推測**:業界的 staging/影子表模式在音樂 App 的公開文件裡查不到直接先例)。 + +--- + +## B. 遠端曲目身分 + +### B1 B 站(bvid + cid) + +- **aid / bvid 是「稿件」層級的編號**,代表 UP 主上傳的那個作品,可互相轉換(社群工具普遍支援互轉)。來源:B 站社群專欄 (「通过BV号或者av获取稿件的P数」、以 aid 或 bvid 二選一呼叫 API)。 +- **cid 是「分 P」層級的編號**,指定稿件內某一個具體的視頻檔案。一個稿件可能有多個 P,只給 bvid 伺服器不知道要播哪一個,所以取得播放位址必須 bvid + cid。來源:同上專欄;CSDN 教學 (「aid 作为视频稿件的顶层标识,cid 用于区分同一稿件下的不同分P内容」)。 +- **cid 的另一個身分**:cid 是「儲存該視頻彈幕資料的倉庫」編號,與 avid 和早期的 VID 綁定。來源:B 站專欄 (「可以理解成一个个储存指定视频的弹幕数据的仓库,它与视频编号(av号)和VID绑定」)。 +- **bvid 會不會變?** 官方沒有文件說明 bvid 的產生規則或是否可變,**查不到**。可從結構推測:bvid 是 avid 的可逆編碼(可互相轉換),因此只要 avid 不變 bvid 就不變(**推測**)。稿件被刪除後重新上傳會得到新的 aid/bvid(**推測**,未找到官方說明)。 +- **影片被替換/重新上傳時會怎樣?** B 站是否允許 UP 主在保留 bvid 的前提下替換視頻源、替換後 cid 是否改變,**查不到**官方或半官方說法。 +- **對 FMP 的意義**:`TrackKey = bilibili:bvid:cid` 是正確的粒度——它鎖定的是「那個具體的視頻」,稿件層級的變動(改標題、改封面、改 UP 名)不影響它。已存在的 cid 在分 P 被刪除後會永久消失(**推測**:cid 與檔案綁定,刪 P 等於刪檔案),此時本地參照必然失效,只能靠 B4 的可用性標記處理。 + +### B2 YouTube(videoId / playlist item id) + +- **同一筆 playlist item 上有兩個不同的 id**,官方文件把它們並列: + - playlist item 的 `id`:形如 `UEx4SkJKQzR0Q1l0eVdXbFNBQms1TlRER2kyc2ZxYnFWLkIwRDYyOTk1Nzc0NkVFQ0En`,是「這支影片在這張歌單裡的這一筆」的身分。 + - `snippet.resourceId.videoId` 與 `contentDetails.videoId`:11 字元的影片身分。 + - `snippet.position`:unsigned integer,從 0 起算的順序。 + 來源:(欄位表逐字)與 (`videoId` 參數「return only the playlist items that contain the specified video」,即一對多關係)。 +- **哪個更穩定**: + - `videoId` 是影片的身分,跨歌單、跨使用者都相同。 + - playlist item id 是「影片 × 歌單」這一筆關聯的身分。移動/刪除一筆項目要用 item id(GeeksforGeeks 的 `playlist_item_update_position` 用 `id` 指定項目,來源 );ytmusicapi 的對應概念是 `setVideoId`,文件明言「The setVideoId is the unique id of this playlist item and needed for moving/removing playlist items」(來源:)。把影片移出歌單再加入,會拿到新的 item id(**推測**:由「item 是關聯的身分」推導,未見官方明文)。 + - 結論:**對 FMP 的 TrackKey 而言,`videoId` 才是曲目身分**(`TrackKey = youtube:`);playlist item id 只在需要區分「同一支影片在同一歌單出現兩次」時才需要存。這一點與 A1 提到的重複項問題是同一個問題。 +- **影片重新上傳**:YouTube 沒有「替換同一 videoId 的內容」的公開機制;重新上傳會得到新的 videoId、舊的變成不可用。官方文件**查不到**明文,此為社群共識(例如 把不可用歸因於版權聲明、地區封鎖、帳號限制等,來源等級為一般文章,非官方文件)。 +- **歌單內已刪除/已轉私人影片**:官方文件的錯誤碼只涵蓋 `videoNotFound` / `playlistNotFound`(請求參數層級,來源 ),**沒有**說明清單內一筆已被刪除的項目在回應中的長相。社群普遍說法是被刪的項目會以 `Deleted video` / `Private video` 佔位、且取不到 `resourceId.videoId`(來源僅為社群教學,**官方文件查不到逐字條文**)。實務上必須**防禦性處理**:把 `resourceId` 或 videoId 缺失當成 `unavailable`,而不是當成解析失敗。 + +### B3 網易雲(songId) + +- **版權到期下架**:歌曲變灰,點擊顯示「因合作方要求,該資源暫時無法使用」。下架是授權狀態的變化,**songId 本身不變**;恢復上架後同一個 id 可播。來源:第一財經 2017-08-11 報導 、21 世紀經濟報導 、網易雲音樂官方聲明(同前兩篇引用)。 +- **版權方重新授權上傳新版本時,新舊是兩筆不同的歌曲**。網易雲官方公告寫得很清楚(2026-05-08): + - 「因当前版本歌曲版权到期等原因,部分歌曲会下架,若在下架前已购买,可以在已购列表中正常播放和下载。」 + - 「但有一种情况:版权方重新授权上传了新版本。此时:旧版本:可播放可下载,但暂时无法红心收藏,若旧版本恢复上架则不影响。新版本:支持红心收藏,但需要重新购买才能享有永久播放下载权益。」 + - 來源:IT之家 、新浪財經 +- **對 FMP 的意義**:songId 對「同一筆上架紀錄」穩定;但「同一首歌被換版本」在網易雲是**新 songId**,本地舊參照會指向一個已下架或已不可紅心的舊紀錄。這正是 B4 要處理的情境。 +- 平台自行換源(非版權方重新上傳)是否會換 id,**查不到**。 + +### B4 遠端替換或重新上傳 + +**業界有沒有公開做法?分層回答。** + +1. **領域模型層:MusicBrainz 的 recording 邊界(最權威的公開慣例)** + - remaster **不**建立新的 recording:「separate recordings should not be created for remastered tracks, since remastered tracks generally feature the original recording with different mastering applied」,remaster 用 release 之間的 relationship 描述。 + - 例外:被標為 remaster 但實際上是 remix 的,才走 remix 規則另立 recording。 + - live 錄音的演出資訊移到 disambiguation,而不是塞進標題。 + - 來源:(逐字引用前述句子)。 + - 意義:**「同一個錄音的不同母帶/版本」是同一首歌的屬性,不是新歌;「不同演出/不同錄音」才是新歌**。這是 FMP 判斷「重新上傳後該不該視為同一首」時可用的判準。 + +2. **串流平台層:網易雲自己揭露的模式(最貼近本題的實證)** + - 舊版本與新版本**並存為兩筆**,各自獨立可播/可收藏;使用者的已購權益綁在「購買當下的那一筆」,換版本不繼承。 + - 來源同 B3(IT之家、新浪財經)。這個模式等價於:**平台不會幫你把舊參照 relink 到新 id**,把判斷留給客戶端。 + +3. **客戶端層:Spotify / YouTube Music 的官方開發者文件** + - Spotify 有沒有「relinked track / unavailable track」的公開 API 語意或處理指引,**查不到**(搜到的都是 Local Files 的支援文章與社群除錯,例如 、,與本題無關)。 + - YouTube Music 的 item 層級身分只在非官方的反向工程套件(ytmusicapi 的 `setVideoId`)看得到,**官方文件查不到**。 + - 使用者可見行為(無法播放的曲目在介面上變灰、保留在歌單中)是普遍現象,但**查不到**把它寫成規範的官方開發者文件。**推測**:各大平台的共通做法是「保留參照 + 標示不可用」,因為刪除使用者歌單裡的一列是更糟的體驗。 + +**對 FMP 的建議(依上述證據)** + +- 本地保留參照,不因遠端消失就刪列;新增一個可用性欄位(例如 `availability`:`available` / `unavailable` / `replaced`)。依據:網易雲的「舊版本仍可播放」與 MusicBrainz 的「remaster 不另立 recording」都指向「保留並標示」而非「刪除」。 +- 遠端若以新 id 回報同一首歌,需要一個「疑似換版本」的偵測:用 C 段的評分核心比對(標題+歌手+時長),命中就標 `replaced` 並提示使用者,而不是靜默新增一列重複曲目。依據:網易雲的版本替換是新 songId(B3),而使用者心智上仍是同一首歌(MusicBrainz 的 recording 邊界)。 +- B 站的 cid 消失、YouTube 的 videoId 消失,兩者都只能標 `unavailable`,因為遠端沒有留下任何可 relink 的線索。依據:B1/B2 的查證結果。 + +--- + +## C. 匹配評分 + +### C1 字串正規化 + +**全形/半形與相容字符:用 Unicode NFKC** + +- NFKC(Normalization Form KC,compatibility composition)會把相容等價的字符摺疊:全形 `R`(U+FF32)→ `R`(U+0052)、連字 `fi`(U+FB01)→ `fi`、羅馬數字 `Ⅸ`(U+2168)→ 字母、上標 `⁵`(U+2075)→ `5`、半形與全形片假名正規化成同一串。 +- NFC/NFD(canonical)**不會**做這些摺疊,NFKC/NFKD(compatibility)才會。這是 NFKC 與 NFC 的關鍵差異。 +- 來源:Unicode 官方 UAX #15 (「Normalization Form KC additionally folds the differences between compatibility-equivalent characters…the halfwidth and fullwidth katakana characters will normalize to the same strings, as will Roman numerals and their letter equivalents」);IBM Db2 文件對四種形式的定義 ;微軟 Win32 文件對 KC/KD 的說明 。 +- 實作順序範例(Python,可對應到 Dart):先 NFKC 處理全形與連字 → 再處理空白 → 再 casefold。來源:。 + +**建議的正規化管線順序(給 FMP)** + +1. `NFKC`(全形→半形、連字、羅馬數字、上下標) +2. `toLowerCase`(casefold;拉丁字母大小寫) +3. 簡繁統一(見下方 C4 的 `opencc`) +4. 去除裝飾性標點與多餘空白(舊版 FMP 已有等價實作,見 `playlist_import_service.dart` 的 `_normalize`,涵蓋 `【】\[\]()()「」『』《》〈〉` 等與裝飾符號) +5. 版本標記的處理——**不要無條件刪除括號內容**,理由見下 + +**括號內容(feat. / Live / Remix / 官方版)** + +- 音樂領域有明確慣例:MusicBrainz 把「不屬於主標題、用來區分不同 release 或同名 track 的額外資訊」叫 **ETI(extra title information)**,規定寫在主標題之後、以單一空格加圓括號包住;且規定大小寫——純描述性的(mix、remix、live、remaster、edit)用小寫。來源:(逐字:「additional information on a release or track name that is not part of its main title…is referred to as extra title information (ETI) and should be entered after the main title, preceded by a single space and wrapped in parentheses」)。 +- 同一頁明確區分 **feat. 不屬於 ETI**:「Featured artists should not be entered in this manner, but rather as part of the artist…」。也就是說 **feat./ft. 應該歸到歌手欄位,而不是當成標題的變體標記**。 +- 推論(**推測**):因為 ETI 的分類本身帶語意(studio vs live vs remix 是**不同錄音**,remaster 是**同一個錄音**,見 B4 的 MusicBrainz recording 規則),把括號內容整段丟掉會讓 live 版和原版變成同一個字串,反而降低匹配精度。正確做法是**抽出來單獨比對**,而不是刪掉。舊版 FMP 已經這樣做(`playlist_import_service.dart` 的 `_calculateBracketContentSimilarity` 抽 `「」《》『』【】〈〉` 五種括號內容,與原標題比對後取較高分),這個方向有慣例支撐,值得沿用。 + +### C2 時長容差 + +**業界慣例的實際樣貌** + +- MusicBrainz Picard 的配對門檻是**可設定的相似度分數**,不是固定秒數(「This setting determines the minimum match between a cluster and a release on MusicBrainz for the release to be considered」)。來源:。 +- 純以時長為硬門檻的公開規範,在 MusicBrainz / AcoustID / lrclib 的文件裡**查不到**——它們主要靠錄音指紋或搜尋結果品質,時長只當輔助欄位。 +- FMP 自己的現行值(唯讀,供比較): + - 歌詞自動匹配硬門檻 `AppConstants.lyricsDurationToleranceSec = 20` 秒;評分函式內分級 ≤3 秒給 1.0、≤10 秒給 0.8、≤20 秒給 0.5。來源:`lib/core/constants/app_constants.dart:179`、`lib/services/lyrics/lyrics_auto_match_service.dart` 的 `_calculateScore`。 + - 歌單匯入用「絕對值+百分比混合」:`|Δ| ≤ 10 秒` 直接給滿分;短曲(<180 秒)放寬到 15/20/30 秒;否則按百分比分級 5/10/15/20/30/50/80/100/200%,>200% 直接過濾(判為合集/串燒)。來源:`playlist_import_service.dart` 的 `_calculateDurationMatchScore`。 +- **建議**:維持「絕對值與百分比取較寬者」的兩段式(硬門檻過濾明顯不是同一首 + 軟評分連續給分),因為純秒數對 2 分鐘的短曲太鬆、對 10 分鐘的長曲太緊。硬門檻建議 ≤10 秒或 ≤5%(取較寬者);軟評分的滿分區間 ≤3 秒(與舊版歌詞匹配一致)。**依據**:舊版兩處的實作經驗值 + Picard 以相似度門檻而非秒數的慣例。**注意**:現場版與不同母帶會有數秒差,5000 首規模下門檻不宜收緊到 ±3 秒。 + +### C3 多歌手 + +**慣例** + +- MusicBrainz 的 artist credit 是**有序列表**,每個 artist 後面可帶 join phrase(`&`、`feat.`、`,` 等),且 feat. 歸屬在 artist credit 而非標題(來源同 C1:)。這確立了「順序有意義、但順序不同不改變身分」的性質。 +- **推測**(由上述慣例推導,未見規範明文):順序對「誰是主要歌手」有語意,所以不能完全忽略順序。 + +**建議做法** + +1. 兩邊的歌手欄位都先正規化並**拆成集合**:以 `,` `&` `/` `、` `×` `x` `feat.` `ft.` `featuring` `with` `vs.` 為分隔符切開,逐項做 C1 的正規化。 +2. 集合相似度用 Jaccard(交集/聯集),或「一對一最佳配對後取平均」。 +3. 對「只有一位符合」給部分分數,不要直接判 0:取兩集合所有配對中的最高相似度當分數下限。**推測**:這是「多位歌手其中一位命中」的自然處理方式,無公開規範。 +4. 主要歌手加權:兩邊清單的**第一位**(或遠端標記為主要的那位)相似度乘上較高權重(舊版 FMP 的 0.25 權重即屬此類)。 +5. **feat. 出現在標題裡時的處理**:比對前先從標題剝離 `feat.` / `ft.` / `featuring` / `with` 之後的段落,把它當作歌手資訊的**補充來源**——只在歌手欄位缺失或明顯不完整時才採用,且打折計分。**依據**:MusicBrainz 明言 feat. 屬於 artist credit 而非標題(C1),所以它在標題中出現時是「欄位搬錯了位置」的資訊,應該搬回去而不是當成標題噪音丟掉。 +6. 舊版 FMP 已實作「歌手出現在頻道名優先、出現在標題需 >70 分才採用且打 0.8 折」的近似邏輯(`playlist_import_service.dart` 的 `_calculateRelevanceScore` 內 `artistSimilarity` 計算),可作為新評分核心的參考基準。 + +### C4 Dart 套件(版本、發佈日期、授權、維護狀態) + +以下全部逐字取自 `https://pub.dev/api/packages/` 與 `/score`(2026-09-28 讀取)。 + +| 套件 | 最新版 | 最後發佈 | 授權 | pub points | likes | 30 天下載 | 判斷 | +|---|---|---|---|---|---|---|---| +| `string_similarity` | 2.2.0 | 2026-04-04 | MIT(pub tag `license:mit`) | 160/160 | 129 | 76,594 | **建議採用**。Dice coefficient(bigram);官方描述自稱「mostly better than Levenshtein distance」,對 CJK 有效。7 個版本,最新一次 5 個月前。 | +| `unorm_dart` | 0.3.2 | 2025-10-01 | MIT | 150/160 | 29 | 263,526 | **建議採用**。NFC/NFD/NFKC/NFKD,Unicode 17.0,`walling/unorm` 的 Dart port。用來做 C1 的全形/半形正規化。 | +| `diacritic` | 0.1.6 | 2024-09-23 | 未列在 pub tag;GitHub repo 欄位為空 | 160/160 | 291 | 666,875 | **可用**(去重音符號,`café`→`cafe`)。下載量高、滿分,但已近 2 年未發版。 | +| `string_normalizer` | 0.4.0 | 2025-10-20 | MIT | 160/160 | 9 | 6,122 | 與 `diacritic` 功能重疊,二選一(`diacritic` 較熱門) | +| `opencc` | 1.1.0 | 2024-10-01 | Apache-2.0 | 150/160 | 0 | 496 | **可用於繁簡統一**。OpenCC 演算法的 Dart port(repo: `lindeer/opencc-dart`)。注意:需要在 native 端帶 assets(描述明寫「with native-assets」),且已有 `1.2.0-dev.1` 預覽版(不要用 dev)。likes 0、下載量低,維護風險需自行評估。 | +| `pinyin` | 3.3.0 | 2024-04-16 | BSD-2-Clause | 160/160 | 19 | 10,286 | 漢字→拼音,描述含「simplified or traditional Chinese」轉換。若要做中英/拼音混合比對才需要;否則 `opencc` 較貼題。 | +| `fuzzywuzzy` | 1.2.0 | 2024-08-15 | **GPL-2.0**(GitHub API `sphericalkat/dart-fuzzywuzzy`) | 150/160 | 153 | 110,856 | **不建議**。功能最完整(`ratio`/`partialRatio`/`tokenSortRatio`/`tokenSetRatio`),但 GPL-2.0 對 MIT 專案(FMP 的 `LICENSE` 為 MIT License, Copyright (c) 2026 imoR)有傳染性。repo 最後 push 2026-09-11,仍在維護。 | +| `levenshtein` | 1.0.2 | **2014-02-10** | Unlicense | 25/160 | 0 | 11 | **不要用**。pub tag 含 `is:legacy`、`is:unlisted`,12 年未更新,points 25/160。 | +| `text_similarity` | 1.0.1 | 2023-09-21 | 未查 | 150/160 | 7 | 8 | 不採用(Levenshtein automaton 查詢,非字串相似度) | +| `jaro_winkler` | — | — | — | — | — | — | **不存在**:`https://pub.dev/api/packages/jaro_winkler` 回 **404** | +| `chinese_converter` | — | — | — | — | — | — | **不存在**:`https://pub.dev/api/packages/chinese_converter` 回 **404** | + +**舊版自寫了什麼、套件能不能取代** + +- `lib/services/import/playlist_import_service.dart`:整條評分鏈(`_calculateRelevanceScore` 及其十餘個 `_calculate*` 輔助函式)約 700 行手寫。其中**純字串相似度核心**是 `_calculateSimilarity`,由三塊組成:子串包含關係加分、`_calculateNGramSimilarity`(字元 bigram 的 **Jaccard** 係數,`|A∩B| / |A∪B|`)、`_levenshteinDistance`(手寫 O(n·m) 二維 DP)。取值為三者最大。 +- `lib/services/lyrics/lyrics_auto_match_service.dart`:`_stringSimilarity` 是 `1 - levenshtein / maxLen`,而 `_levenshteinDistance` **又手寫了一份**(與上一個檔案的實作重複)。 +- **可被套件取代的部分**:bigram Jaccard 這一段。`string_similarity` 提供的 Dice coefficient 為 `2|A∩B| / (|A|+|B|)`,與 Jaccard 存在單調關係 `Dice = 2J / (1 + J)`(**推測**:這是標準的集合相似度恆等式,非來自查到的來源),因此**換成 Dice 不會改變任何兩個字串的相對排序**,可以直接取代手寫 N-gram 那一段。 +- **無法被現成套件乾淨取代的部分**:Levenshtein 沒有可用的穩定套件(`levenshtein` 已淘汰、`fuzzywuzzy` 是 GPL)。手寫一份帶早退的 Levenshtein 約 30 行,且舊版已經有兩份可合併——建議重寫時**收斂成一個共用核心**,而不是找套件。 +- 剩下的部分(播放量加權、官方頻道加分、版本關鍵字加分、標題負面關鍵字如「合集/串燒/作業用」)是**領域規則**,沒有任何通用套件能取代,只能自己維護成一份資料表。 + +--- + +## 對 FMP 的具體建議(每條附依據) + +1. **差異計算不要引入 LCS/Myers diff。** 單向權威同步下四類差異都是集合運算或逐欄比較(A1);LCS 只用於雙向或產生 patch 的場景。依據:A1 的分類表與 YouTube `snippet.position` 的存在。 +2. **關聯表的排序欄位存遠端序號,本地不自己算間隔。** 遠端給 position 就存 position,只給有序陣列就存陣列索引;每次刷新在單一 transaction 內整批覆寫 order,不引入稀疏間隔或 LexoRank 的複雜度。依據:A1/A2;稀疏整數與 LexoRank 的價值在於「只有少量項目變動時少寫幾列」,而單向刷新本來就是整批處理。 + - 若日後真的需要避免整表 position 覆寫,退化成本最低的是稀疏整數(間隔 1000),因為它不需要 base-62 實作(A2 的來源明確偏好整數而非浮點)。 +3. **關聯表要允許同一首歌在同一歌單出現兩次。** `UNIQUE(playlist_id, track_key)` 會把 YouTube 歌單裡的重複影片摺疊掉;唯一鍵要含 position,或不要對 (playlist_id, track_key) 設唯一。依據:A1(ytmusicapi 的 `duplicates` 參數)與 B2(videoId 對 playlist item id 是一對多)。 +4. **任何批次寫入都要包在 transaction 或 batch 內,不要逐列 await。** 每列一個隱式 commit 就是一次 fsync(A3 瓶頸第 1 項)。大歌單採「抓一頁寫一頁」的流水線,每頁一個 transaction。 +5. **避免在有外鍵關聯的列上用 `INSERT OR REPLACE`。** SQLite 的 `INSERT OR REPLACE` 是 DELETE + INSERT,會觸發 `ON DELETE CASCADE`;要合併欄位時用 drift 的 `DoUpdate(target: [...])`。依據:A3 瓶頸第 2 項(SQLite 語意推導,標為推測)。 +6. **「整張歌單刷新」用 refresh generation 標記達成原子性,而不是一個巨大的 transaction。** 每頁寫入時帶本輪 generation,全部頁數完成才標記 complete,讀取一律只認最新 completed generation。這樣中途失敗的結果是「舊的完整版本還在」。依據:A4(drift 的 `BEGIN IMMEDIATE` 會讓巨大 transaction 長時間持有寫鎖,因此整張包一個 transaction 在寫鎖維度上有代價)。 + - 如果產品上可以接受「刷新期間介面暫時鎖住」,那直接整張包一個 `transaction()` 是最簡單且唯一能保證全有全無的做法(A4 末段)。 +7. **在 `beforeOpen` 執行 `PRAGMA foreign_keys = ON`,並在 migration 期間關閉後重開。** 這是 drift 官方建議,且 SQLite 預設不強制外鍵。依據:A4 的 drift migrations 文件。 +8. **開啟 WAL。** 讓長達數秒的刷新寫入不阻塞 UI 的讀取查詢;drift 官方在多 isolate / read pool 的設定裡明說 WAL 是避免 "database locked" 的前提。依據:A4()。 +9. **曲目身分:YouTube 用 `videoId`、B 站用 `bvid:cid`、網易雲用 `songId`**(與已定案的 `TrackKey` 一致)。額外要記住的是:YouTube 的 playlist item id、B 站的 cid 分 P 順序,都是「關聯」而非「曲目」的身分,不該進 `TrackKey`。依據:B1(cid 指的是具體視頻檔案)、B2(videoId 對 playlist item id 一對多)。 +10. **遠端曲目消失時保留並標示 `unavailable`,不刪列。** 並用評分核心偵測「疑似換版本」標成 `replaced` 後提示使用者。依據:B3(網易雲版本替換是新 songId)、B4(網易雲新舊並存、MusicBrainz 的 remaster 不另立 recording)、以及 A4/B4 兩處的「查不到官方指引 → 依可用證據自行決定」。 +11. **正規化管線固定為:NFKC → 小寫 → 簡繁統一 → 去裝飾標點/空白 → 抽出括號內容單獨比對。** 不要把括號內容整段丟掉。依據:C1(UAX #15 的 NFKC 語意、MusicBrainz 的 ETI 規範)。 +12. **歌手比對用集合相似度,先從標題剝離 feat. 段落。** 依據:C1(MusicBrainz 明言 feat. 屬 artist credit 而非標題)與 C3。 +13. **時長用「絕對值與百分比取較寬者」的兩段式,硬門檻建議 ≤10 秒或 ≤5%。** 依據:C2(舊版實作經驗值、Picard 以相似度門檻而非固定秒數的慣例)。 +14. **套件選擇:`string_similarity` 2.2.0(MIT)取代手寫 bigram Jaccard;`unorm_dart` 0.3.2(MIT)做 NFKC;`opencc` 1.1.0(Apache-2.0)做繁簡統一;`diacritic` 0.1.6 做重音符號。Levenshtein 自己寫(沒有可用的 MIT 套件)。`fuzzywuzzy` 因 GPL-2.0 不採用(FMP 是 MIT)。** 依據:C4 的 pub.dev 逐項查證。 + - `diacritic` 的授權在 pub.dev 上沒有 tag、GitHub repo 欄位為空,採用前需自行確認授權檔(本次**查不到**其授權)。 + +--- + +## 查不到清單(明確列出,避免後人重複查) + +| 主題 | 查不到的內容 | +|---|---| +| B1 | bvid 的產生規則、是否可能變動;B 站允許 UP 主替換視頻源後 cid 是否改變;稿件刪除後重建是否沿用 bvid | +| B2 | YouTube 官方對「同一 videoId 內容被替換」的說明(重新上傳=新 videoId 僅為社群共識);`playlistItems` 對清單內已刪除/私人影片的 placeholder 明文(`Deleted video` / `Private video`) | +| B3 | 網易雲平台自行換源(非版權方重新上傳)是否會換 songId | +| B4 | Spotify 官方對 relinked / unavailable track 的開發者文件;YouTube Music 的 item 身分官方說明 | +| A4 | drift 官方**文件**對「`transaction()` 發出 `BEGIN IMMEDIATE`」的說明(只在原始碼註解看到,見本檔引用的 `database.dart` 第 66–74 行);`batch()` 是否自帶 transaction 的明文(未查證 drift 原始碼的 `batch()` 實作) | +| C2 | 業界對「曲目匹配時長容差」的公開規範值(MusicBrainz / AcoustID / lrclib 都沒有把秒數寫成規範) | +| C4 | `diacritic` 的授權(pub.dev 無 license tag、pubspec 無 repository 欄位);`jaro_winkler` 與 `chinese_converter` 在 pub.dev **不存在**(API 回 404) | From e273e8da49508d4d9b6dcb3c3e9779dfb318947a Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:45:24 +0800 Subject: [PATCH 057/133] chore(task): add design and plan for library and sync --- .../tasks/09-28-design-library-sync/design.md | 62 +++++++++++++++++++ .../09-28-design-library-sync/implement.md | 11 ++++ .../tasks/09-28-design-library-sync/prd.md | 10 ++- 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 .trellis/tasks/09-28-design-library-sync/design.md create mode 100644 .trellis/tasks/09-28-design-library-sync/implement.md diff --git a/.trellis/tasks/09-28-design-library-sync/design.md b/.trellis/tasks/09-28-design-library-sync/design.md new file mode 100644 index 000000000..d9d5ede7c --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/design.md @@ -0,0 +1,62 @@ +# 設計:音樂庫與同步 + +## 1. 資料模型(drift,ADR 0010) + +| 表 | 重點欄位 | 備註 | +|---|---|---| +| `playlists` | id、`kind`(`local`/`imported`/`mix`)、名稱、描述、封面、排序 | 名稱不再唯一(舊版重名自動加「(2)」不帶過去) | +| `playlist_remote` | 歌單 id(FK)、插件 id、遠端歌單 id、擁有者、`name_overridden`/`description_overridden`/`cover_overridden`、上次刷新時間與結果、狀態(正常/來源失效) | 只有 `imported` 有這一列 | +| `playlist_entries` | 歌單 id(FK,刪歌單時連帶刪)、位置、曲目鍵(FK)、遠端項目 id(可空) | **不對(歌單, 曲目鍵)設唯一**:YouTube 歌單可含重複影片 | +| `tracks` | 曲目鍵(ADR 0005 的 `TrackKey` 格式,照搬)、標題、歌手、時長、封面清單、可用狀態與原因 | 同一首歌只有一列 | +| `track_origins` | 曲目鍵、原始平台、原始 id | Spotify/QQ 匯入時記下,供歌詞直取與重新匹配 | +| `match_results` | 原始曲目、選定的曲目鍵、分數、`user_selected` | 匹配結果持久化,使用者改選後不再重算(ADR 0014) | + +- 開啟資料庫時 `PRAGMA foreign_keys = ON`(drift 官方建議,migration 期間關閉再開)。 +- **孤兒清理**:以 SQL 找出沒有被任何 `playlist_entries`、佇列、下載紀錄參照的曲目,登記在啟動維護清單(ADR 0017)。 + 靠外鍵與查詢判斷,不再依手動維護的反向欄位(舊版遺失資料的原因)。播放歷史存快照、不參照曲目列,不影響清理。 +- 舊資料匯入(ADR 0010)把 `trackIds`/`playlistInfo` 轉成 `playlist_entries`;舊歌單的本地改名、自訂封面換算成對應的 `*_overridden` 旗標。 + +## 2. 匯入與刷新(遠端為權威、只往下) + +- 匯入與刷新都經插件 `importPlaylist`(取完整清單,可分頁);刷新由 ADR 0017 的排程器或手動觸發。是否帶登入依 ADR 0012 的音源設定。 +- 差異處理(已決定 A): + 1. 依曲目鍵比對:遠端有、本地沒有 → 新增;本地有、遠端沒有 → **從這張歌單移除**(曲目列留著給其他歌單、下載、佇列用,沒人參照時由孤兒清理處理;下載檔不刪)。 + 2. 順序完全照遠端。 + 3. 曲目元資料(標題、歌手、時長、封面、可用狀態)照遠端更新。遠端標成失效的曲目保留並標「已失效」(ADR 0013 的 `Unavailable`)。 + 4. 歌單的名稱、描述、封面:沒有在本地改過(`*_overridden` 為否)就跟遠端;改過就保留本地值。 +- **部分失敗**:任何一頁抓取失敗或筆數不足,就只新增與更新、不移除,並記錄「上次刷新:部分完成」顯示在歌單頁;下次完整刷新時再處理移除。 +- **寫入方式**:抓一頁寫一頁,每頁一個 transaction,整輪用刷新代際標記;完整抓完後以一個 transaction 套用移除與最終順序。中途失敗不會留下半套順序。 +- **遠端歌單失效**(`NotFound`、無權限):狀態標成「來源失效」並停止自動刷新,保留本地副本唯讀可播;歌單頁顯示原因與「重試」。不再每次排程都重試並跳錯誤。 +- 刷新結果:手動刷新顯示新增/移除/更新數;自動刷新不跳 toast,只更新歌單頁的「上次刷新」狀態(ADR 0013「背景工作不跳 toast」)。 +- 重新匯入同一張遠端歌單=刷新,不覆寫本地設定(M12)。 + +## 3. 遠端操作(B1、B2、E7) + +- 經插件 `libraryWrite` 能力;只有登入且具備該能力的音源才出現入口(ADR 0014 能力驅動 UI)。 +- **B1 從遠端歌單移除**:確認框(說明「同時從本地歌單移除」),先寫遠端、成功後刪本地對應項目,再背景刷新該歌單。部分成功時列出失敗項目。 +- **B2 加入遠端歌單**:對話框勾選目標歌單後送出,**不另加確認框**(勾選本身就是明確操作;Namida 慣例:加入不確認、移除才確認)。 + 已在遠端的曲目不重複加入;未登入的音源不列出並提示;成功後背景刷新對應的匯入歌單。 +- 本地「加入歌單」只列 `local` 歌單;匯入歌單的曲目在本地不能增刪、不能重排(B1/B2)。 + +## 4. 僅元資料來源的匯入與匹配(E5) + +- Spotify、QQ 等是具備 `importPlaylist`、沒有 `resolveStream` 的插件;匯入後逐首用**共用匹配評分核心**(ADR 0014 決定 9,與歌詞共用)在使用者設定的目標音源中搜尋。 +- 評分核心(宿主,Dart): + - 正規化:NFKC(`unorm_dart`)→ 小寫 → 繁簡統一(`opencc`)→ 去裝飾標點與空白 → 括號內容(Live、Remix、feat.)抽出單獨比對,不整段刪。 + - 相似度:`string_similarity`(Dice);時長硬門檻「10 秒或 5% 取較寬」再連續給分;多歌手拆開比對取最佳。 + - 播放量等來源特有訊號不進核心(插件不回報就沒有),避免偏向特定音源。 +- 自動匹配與手動重搜走**同一個**評分(舊版手動重搜只看播放量)。每首保留前 5 名候選;第一名自動選定。 +- 匯入預覽頁(沿用):已匹配可展開候選改選,未匹配集中顯示可重搜,可排除;確認後建立 `local` 歌單並寫入 `match_results` 與 `track_origins`。 +- 匹配失敗的曲目保留在預覽的「未匹配」區;使用者不處理就不加入歌單。錯誤依 ADR 0013 呈現,不再一律「發生錯誤」。 +- 搜尋節流交給網路層的每插件限流(ADR 0013),不再寫死 800/1000ms 延遲。 + +## 5. 待辦(功能凍結,第 20 項) + +- 來源失效的匯入歌單「另存為本地歌單」、曲目層的收藏/喜歡、「疑似換版本」偵測(網易新舊 song id)——都是新功能。 + +## 6. 閘門 + +- 單元測試(差異處理):新增、移除、順序、元資料更新、覆寫旗標、部分失敗不移除、重複影片保留、來源失效停止自動刷新、重新匯入不覆寫設定。 +- 資料庫測試:外鍵連帶刪除、孤兒清理只刪無人參照的曲目、刷新中途失敗後的一致性。 +- 評分核心:正規化管線(全半形、繁簡、括號)、時長門檻、多歌手;自動與手動重搜同分。歌詞端(第 15 項)共用同一組測試。 +- 插件契約(ADR 0015):`importPlaylist` 分頁與完整性回報、`libraryWrite` 的錯誤對應。 diff --git a/.trellis/tasks/09-28-design-library-sync/implement.md b/.trellis/tasks/09-28-design-library-sync/implement.md new file mode 100644 index 000000000..0109bc238 --- /dev/null +++ b/.trellis/tasks/09-28-design-library-sync/implement.md @@ -0,0 +1,11 @@ +# 執行計畫:第 14 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0019-library-and-sync.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: + 本地與匯入同表只靠網址區分、手動維護反向關係、遠端移除後保留並標示、部分失敗靜默只增不刪、加入遠端也加確認框、 + 每張歌單各存「使用登入刷新」、匯入與歌詞兩套評分、手動重搜只看播放量、`fuzzywuzzy`(GPL)。 +2. ADR 0014 決定 9:補上評分核心的正規化與套件(見 ADR 0019)。 +3. `phase2-plan.md`:§3 第 14 項標 ✅(ADR 0019);待辦(第 20 項)加入「另存為本地歌單」「曲目收藏」「疑似換版本偵測」;§10 交接段更新,下一項 11 下載與權限。 +4. 驗證:`git grep` 確認 ADR 間引用。 +5. `task.py finish`、`task.py archive design-library-sync --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-library-sync/prd.md b/.trellis/tasks/09-28-design-library-sync/prd.md index 5b98b5592..90a285005 100644 --- a/.trellis/tasks/09-28-design-library-sync/prd.md +++ b/.trellis/tasks/09-28-design-library-sync/prd.md @@ -3,7 +3,7 @@ ## 目標 為 `app/` 定下本地歌單與匯入歌單的資料模型、刷新(只從遠端往下)的差異處理、寫回平台的遠端操作與確認、 -僅元資料來源(Spotify、QQ)匯入的匹配流程與失敗處理。產出 ADR 0019。 +僅元資料來源(Spotify、QQ)匯入的匹配流程與失敗處理。產出 ADR 0019。技術設計見 `design.md`,執行步驟見 `implement.md`。 依據:parent `prd.md` 階段二第 14 項;`docs/audit/questions.md` 第 131 行 B1/B2 備註;E4、E5、E7 保留; ADR 0010(drift、外鍵)、0013(錯誤呈現)、0014 決定 9(共用匹配評分)、0016(離線)、0017(自動刷新排程與間隔)。 @@ -35,9 +35,13 @@ ADR 0010(drift、外鍵)、0013(錯誤呈現)、0014 決定 9(共用 - B1/B2:遠端是權威、只往下同步;匯入歌單不能在本地增刪曲目;保留明確標示的遠端操作;名稱、描述、封面、自動刷新設定可在本地改。 - 自動刷新的排程與間隔(ADR 0017);刷新時是否帶登入依音源設定(ADR 0012),不再每張歌單各存一份(M12 的覆寫問題隨之消失)。 -## 待決定 +## 決定 -- [ ] 刷新時,遠端清單裡已經沒有的曲目怎麼處理 +1. **遠端已無的曲目(2026-09-28 選 A)**:從該歌單移除(下載檔不刪);只在完整抓到遠端清單時移除,部分失敗只增不刪並在歌單頁顯示「部分完成」; + 遠端標成失效的曲目保留並標「已失效」。 +2. 技術選擇(`design.md`):歌單、遠端資訊、歌單項目分表並以外鍵連結,同一首歌可在同一歌單出現多次;本地改過的名稱/描述/封面以旗標保留,其餘跟遠端; + 遠端歌單失效時停止自動刷新、保留唯讀副本;B1 移除要確認、B2 加入不另加確認;匯入匹配與手動重搜共用評分核心(NFKC、繁簡、`string_similarity`)。 +3. 新功能列待辦:另存為本地歌單、曲目收藏、疑似換版本偵測。 ## 驗收條件 From 93a352f60ae96f3f2c4075ff5d2efe4f39bfa722 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:46:30 +0800 Subject: [PATCH 058/133] docs(adr): 0019 library and sync --- docs/adr/0014-script-source-plugins.md | 1 + docs/adr/0019-library-and-sync.md | 87 ++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 docs/adr/0019-library-and-sync.md diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index 692f69798..5b543293d 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -51,6 +51,7 @@ manifest 與腳本承擔。 移除插件時清除其 storage 與憑證,曲目保留並標示。 9. **匹配**:宿主一份共用評分核心(標題、歌手、時長容差,歌詞另加同步歌詞加分),歌單匯入與歌詞共用;對所有啟用的目標來源比較取最高分, 同分依使用者排序;目標來源集合由使用者設定,自動與手動重搜一致;結果持久化,使用者改選後不再重算;匹配失敗保留並標示。 + 評分核心的正規化、相似度與套件見 ADR 0019。 10. **YouTube 退路**:可行性驗證(YouTube.js 在 `flutter_js` 能否搜尋並解出串流;它官方只寫支援 Node.js、Deno、瀏覽器,需宿主提供 fetch 與 eval) 有時限;失敗則 YouTube 暫以 Dart 實作同一個 `SourcePlugin` 介面。 diff --git a/docs/adr/0019-library-and-sync.md b/docs/adr/0019-library-and-sync.md new file mode 100644 index 000000000..58cff42c0 --- /dev/null +++ b/docs/adr/0019-library-and-sync.md @@ -0,0 +1,87 @@ +# 0019 — 音樂庫與同步:外鍵關聯、遠端權威的單向刷新、明確的遠端操作、共用匹配核心 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`playlists`/`playlist_remote`/`playlist_entries`/`tracks`/`track_origins`/`match_results` 表、匯入與刷新流程、 + 遠端歌單操作、僅元資料來源的匯入預覽、共用匹配評分核心、孤兒曲目清理 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-library-sync/research/current-state.md`,已以程式碼核對): + +- 本地與匯入歌單同一個 collection,只靠 `sourceUrl != null` 區分(`playlist.dart:70`);曲目與歌單的關係是手動維護的整數陣列加反向 `playlistInfo`, + 沒有外鍵,曾因此遺失資料(ADR 0010)。 +- 刷新只在遠端資料完整時才刪除,否則靜默「只增不刪」且 UI 不顯示(`playlist_mutation_repository.dart:531-532,841-873`); + 遠端改標題不會同步;重新匯入會覆寫「使用登入刷新」與間隔(M12)。 +- 遠端歌單被刪或變私人沒有狀態,只有一次被壓成「發生錯誤」的 toast,排程繼續重試。 +- Spotify/QQ 匯入與歌詞匹配是兩套評分;匯入的手動重搜只依播放量排序。 + +擁有者已定(`docs/audit/questions.md` B1/B2 備註):遠端是權威、只往下同步;匯入歌單不能在本地增刪曲目; +保留明確標示的遠端操作;名稱、描述、封面、自動刷新設定可在本地改。 + +## 考慮過的選項 + +- **本地與匯入同表、只靠網址區分;手動維護反向關係**:否決,資料遺失的來源。 +- **遠端已無的曲目保留並標「遠端已移除」**:否決(擁有者 2026-09-28 選擇跟遠端一致移除),會累積「刪了還在」的曲目。 +- **部分失敗時靜默只增不刪**:否決,改為顯示「部分完成」。 +- **「加入遠端歌單」也加確認框**:否決;勾選目標歌單已是明確操作(Namida:加入不確認、移除才確認)。 +- **每張歌單各存「使用登入刷新」**:否決,改依 ADR 0012 的音源設定。 +- **匯入與歌詞兩套評分、手動重搜只看播放量**:否決(ADR 0014 決定 9)。 +- **`fuzzywuzzy`**:否決,GPL-2.0。 +- **單向同步用 LCS/Myers 差異**:不需要;以曲目鍵集合差集加遠端順序即可(Finamp 的慣例)。 + +## 決定 + +1. **資料模型**: + - `playlists`(`kind`:`local`/`imported`/`mix`,名稱不唯一); + - `playlist_remote`(插件、遠端 id、擁有者、名稱/描述/封面的本地覆寫旗標、上次刷新時間與結果、狀態); + - `playlist_entries`(歌單 FK 連帶刪除、位置、曲目鍵 FK、遠端項目 id)——**不對(歌單, 曲目鍵)設唯一**,因為 YouTube 歌單可含重複影片; + - `tracks`(ADR 0005 的曲目鍵格式照搬); + - `track_origins`(原始平台與 id); + - `match_results`(選定曲目、分數、使用者改選)。 + + 開啟資料庫時 `PRAGMA foreign_keys = ON`。孤兒曲目以查詢判斷(沒有被歌單項目、佇列、下載紀錄參照),登記在啟動維護清單(ADR 0017)。 +2. **刷新**(經插件 `importPlaylist`,排程見 ADR 0017,登入依 ADR 0012): + - 以曲目鍵比對,遠端有本地無則新增,本地有遠端無則**從該歌單移除**(下載檔不刪),順序完全照遠端; + - 曲目元資料與可用狀態照遠端更新,遠端標失效的曲目保留並標「已失效」; + - 歌單名稱、描述、封面未在本地覆寫就跟遠端; + - 任何一頁失敗或筆數不足時只新增與更新、不移除,並在歌單頁顯示「上次刷新:部分完成」; + - 抓一頁寫一頁、每頁一個 transaction 加刷新代際,完整抓完後一次套用移除與順序; + - 重新匯入同一張遠端歌單等於刷新,不覆寫本地設定(M12)。 +3. **來源失效**:遠端 `NotFound` 或無權限時標「來源失效」、停止自動刷新、保留唯讀副本並提供「重試」。 + 自動刷新不跳 toast,只更新歌單頁狀態(ADR 0013)。 +4. **遠端操作**(插件 `libraryWrite`,只對已登入且具備能力的音源出現入口): + - 「從遠端歌單移除」有確認框,先寫遠端、成功後刪本地、再背景刷新,部分成功列出失敗項; + - 「加入遠端歌單」在對話框勾選後直接送出,不重複加入已存在的曲目。 + + 本地「加入歌單」只列 `local` 歌單;匯入歌單的曲目不能在本地增刪或重排。 +5. **僅元資料來源的匯入**(Spotify、QQ 等只有 `importPlaylist` 的插件):逐首以共用評分核心在使用者設定的目標音源中搜尋,保留前 5 名、第一名自動選; + 匯入預覽頁可改選、重搜、排除;確認後建立 `local` 歌單並寫入 `match_results` 與 `track_origins`。自動匹配與手動重搜同一套評分。 + 節流交給網路層的每插件限流(ADR 0013)。 +6. **共用評分核心**(宿主 Dart,歌詞共用): + - 正規化:NFKC(`unorm_dart`)→ 小寫 → 繁簡統一(`opencc`)→ 去裝飾標點與空白 → 括號內容單獨比對; + - 相似度用 `string_similarity`(Dice);時長以「10 秒或 5% 取較寬」為硬門檻再連續給分;多歌手拆開取最佳; + - 不使用播放量等來源特有訊號。 + +採用的慣例:Finamp 的 id 集合差集刷新;Namida 的「加入不確認、移除確認」;MusicBrainz 的標題延伸資訊(括號內容)不整段刪; +drift 官方的外鍵開啟方式;Unicode UAX #15 的 NFKC。 + +## 後果 + +- 好的: + - 關聯由外鍵保證,孤兒清理不再誤刪; + - 刷新結果可預期且部分失敗看得見; + - 遠端失效有明確狀態; + - 匯入與歌詞的匹配一致,手動重搜也有評分。 +- 壞的: + - 舊資料匯入要把整數陣列與反向欄位轉成關聯表,並換算覆寫旗標; + - `opencc` 需要 native assets,要在各平台建置驗證。 +- 之後要注意:來源失效時「另存為本地歌單」、曲目收藏、網易「疑似換版本」偵測列在功能凍結待辦;歌詞端如何使用評分核心由歌詞的 ADR 定。 + +## 如何確認 + +- 單元測試: + - 刷新差異:新增、移除、順序、元資料、覆寫旗標、部分失敗不移除、重複影片保留、來源失效停止自動刷新、重新匯入不覆寫設定。 + - 評分核心:全半形、繁簡、括號、時長門檻、多歌手;自動與手動重搜同分。 +- 資料庫測試:外鍵連帶刪除、孤兒清理只刪無人參照的曲目、刷新中途失敗後的一致性。 +- 插件契約(ADR 0015):`importPlaylist` 分頁與完整性回報、`libraryWrite` 的錯誤對應。 From 6946a99390cba3eb382ee78d81ff72143d8e709e Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:46:30 +0800 Subject: [PATCH 059/133] chore(task): archive design-library-sync --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 ++++++------ .../tasks/09-28-design-library-sync/implement.md | 11 ----------- .../2026-09}/09-28-design-library-sync/check.jsonl | 0 .../2026-09}/09-28-design-library-sync/design.md | 0 .../09-28-design-library-sync/implement.jsonl | 0 .../2026-09/09-28-design-library-sync/implement.md | 11 +++++++++++ .../2026-09}/09-28-design-library-sync/prd.md | 0 .../research/current-state.md | 0 .../09-28-design-library-sync/research/prior-art.md | 0 .../research/sync-and-matching.md | 0 .../2026-09}/09-28-design-library-sync/task.json | 6 +++--- 11 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 .trellis/tasks/09-28-design-library-sync/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/research/sync-and-matching.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-library-sync/task.json (89%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index fb82a12e5..589b5948c 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016) | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019) | ## 2. 依賴關係 @@ -122,7 +122,7 @@ flowchart LR | 10 | 17 快取與離線(✅ 完成,ADR 0016) | 串流 URL、圖片、排行快取的策略,播放核心要用。 | | 11 | 16 背景任務(✅ 完成,ADR 0017) | 刷新、清理、更新檢查誰來排程。 | | 12 | 13 播放核心(✅ 完成,ADR 0018) | 最大的一塊;依賴 1、2、10、17。 | -| 13 | 14 音樂庫與同步 | B1/B2 已定方向,細節依賴 6、1、12、16。 | +| 13 | 14 音樂庫與同步(✅ 完成,ADR 0019) | B1/B2 已定方向,細節依賴 6、1、12、16。 | | 14 | 11 下載與權限 | 依賴播放核心的本地播放路徑。 | | 15 | 15 歌詞 | 依賴 1、13。 | | 16 | 19 發版與更新 | 依賴 10、16;你已給出流程要求。 | @@ -239,10 +239,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0018`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0019`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 14 項「音樂庫與同步」**,task `.trellis/tasks/09-28-design-library-sync/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`sync-and-matching.md`),三個檔齊了才代表研究完成。 -- 之後順序:11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 11 項「下載與權限」(尚未建 task)。 +- 之後順序:15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-28-design-library-sync/implement.md b/.trellis/tasks/09-28-design-library-sync/implement.md deleted file mode 100644 index 0109bc238..000000000 --- a/.trellis/tasks/09-28-design-library-sync/implement.md +++ /dev/null @@ -1,11 +0,0 @@ -# 執行計畫:第 14 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0019-library-and-sync.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: - 本地與匯入同表只靠網址區分、手動維護反向關係、遠端移除後保留並標示、部分失敗靜默只增不刪、加入遠端也加確認框、 - 每張歌單各存「使用登入刷新」、匯入與歌詞兩套評分、手動重搜只看播放量、`fuzzywuzzy`(GPL)。 -2. ADR 0014 決定 9:補上評分核心的正規化與套件(見 ADR 0019)。 -3. `phase2-plan.md`:§3 第 14 項標 ✅(ADR 0019);待辦(第 20 項)加入「另存為本地歌單」「曲目收藏」「疑似換版本偵測」;§10 交接段更新,下一項 11 下載與權限。 -4. 驗證:`git grep` 確認 ADR 間引用。 -5. `task.py finish`、`task.py archive design-library-sync --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-library-sync/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/check.jsonl diff --git a/.trellis/tasks/09-28-design-library-sync/design.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/design.md similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/design.md diff --git a/.trellis/tasks/09-28-design-library-sync/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.md new file mode 100644 index 000000000..159d7932f --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/implement.md @@ -0,0 +1,11 @@ +# 執行計畫:第 14 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0019-library-and-sync.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: + 本地與匯入同表只靠網址區分、手動維護反向關係、遠端移除後保留並標示、部分失敗靜默只增不刪、加入遠端也加確認框、 + 每張歌單各存「使用登入刷新」、匯入與歌詞兩套評分、手動重搜只看播放量、`fuzzywuzzy`(GPL)。 +2. [x] ADR 0014 決定 9:補上評分核心的正規化與套件(見 ADR 0019)。 +3. [x] `phase2-plan.md`:§3 第 14 項標 ✅(ADR 0019);待辦(第 20 項)加入「另存為本地歌單」「曲目收藏」「疑似換版本偵測」;§10 交接段更新,下一項 11 下載與權限。 +4. [x] 驗證:`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-library-sync --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-library-sync/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/prd.md diff --git a/.trellis/tasks/09-28-design-library-sync/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/research/current-state.md diff --git a/.trellis/tasks/09-28-design-library-sync/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/research/sync-and-matching.md similarity index 100% rename from .trellis/tasks/09-28-design-library-sync/research/sync-and-matching.md rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/research/sync-and-matching.md diff --git a/.trellis/tasks/09-28-design-library-sync/task.json b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/task.json similarity index 89% rename from .trellis/tasks/09-28-design-library-sync/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-library-sync/task.json index 5ef270d67..7e763638b 100644 --- a/.trellis/tasks/09-28-design-library-sync/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-library-sync/task.json @@ -3,7 +3,7 @@ "name": "design-library-sync", "title": "Design: library and sync", "description": "Phase-2 item 14: local vs imported remote playlists, sync direction and conflicts, confirmation before writing back to a platform, auto-refresh rules, metadata-only imports with matching", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 28f4544810487c3dc31ccb245dd3a88bc560bc2e Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 01:47:19 +0800 Subject: [PATCH 060/133] chore(task): start design-downloads --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../tasks/09-28-design-downloads/check.jsonl | 0 .../09-28-design-downloads/implement.jsonl | 0 .trellis/tasks/09-28-design-downloads/prd.md | 19 ++++++++++++++ .../tasks/09-28-design-downloads/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-design-downloads/check.jsonl create mode 100644 .trellis/tasks/09-28-design-downloads/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-downloads/prd.md create mode 100644 .trellis/tasks/09-28-design-downloads/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 589b5948c..004ed8543 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -242,7 +242,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0019`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 11 項「下載與權限」(尚未建 task)。 +- **進行中:第 11 項「下載與權限」**,task `.trellis/tasks/09-28-design-downloads/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index b82ee7536..5bf55c2ec 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -32,7 +32,8 @@ "09-27-design-cache-offline", "09-27-design-background-tasks", "09-27-design-playback-core", - "09-28-design-library-sync" + "09-28-design-library-sync", + "09-28-design-downloads" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-downloads/check.jsonl b/.trellis/tasks/09-28-design-downloads/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-downloads/implement.jsonl b/.trellis/tasks/09-28-design-downloads/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-downloads/prd.md b/.trellis/tasks/09-28-design-downloads/prd.md new file mode 100644 index 000000000..0a79eb131 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/prd.md @@ -0,0 +1,19 @@ +# Design: downloads and permissions + +## Goal + +Phase-2 item 11: download queue and resume, storage abstraction per platform, file format and tags, permission requests through one entry point + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-downloads/task.json b/.trellis/tasks/09-28-design-downloads/task.json new file mode 100644 index 000000000..5c1779ba2 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-downloads", + "name": "design-downloads", + "title": "Design: downloads and permissions", + "description": "Phase-2 item 11: download queue and resume, storage abstraction per platform, file format and tags, permission requests through one entry point", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 55d418911018e9e1898de08e0ea70a54ddae42ba Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:00:15 +0800 Subject: [PATCH 061/133] chore(task): add design-downloads research and prd draft --- .trellis/tasks/09-28-design-downloads/prd.md | 53 +- .../research/current-state.md | 325 +++++ .../research/packages-and-platform.md | 615 +++++++++ .../research/prior-art.md | 1137 +++++++++++++++++ 4 files changed, 2119 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-downloads/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-downloads/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-downloads/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-downloads/prd.md b/.trellis/tasks/09-28-design-downloads/prd.md index 0a79eb131..bbd65cc94 100644 --- a/.trellis/tasks/09-28-design-downloads/prd.md +++ b/.trellis/tasks/09-28-design-downloads/prd.md @@ -1,19 +1,50 @@ -# Design: downloads and permissions +# 設計:下載與權限(階段二第 11 項) -## Goal +## 目標 -Phase-2 item 11: download queue and resume, storage abstraction per platform, file format and tags, permission requests through one entry point +為 `app/` 定下下載佇列與續傳、下載位置與檔案組織、檔案格式與內嵌標籤、下載與音樂庫的關聯、權限的統一入口。產出 ADR 0020。 -## Requirements +依據:parent `prd.md` 階段二第 11 項;`docs/audit/questions.md` N1–N11、B13;`phase2-plan.md` §4 對 N2–N11 的方向(使用者按建議確認); +ADR 0009(平台能力)、0012(媒體請求不帶憑證)、0014/0018(下載由宿主處理,經 `resolveStream`)、0017(下載事件驅動,不歸排程器)、0019(刷新移除曲目不刪下載)。 +舊 ADR 0004(Android 不用 MediaStore、`MANAGE_EXTERNAL_STORAGE`+裸路徑)描述舊專案。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對,另見 `docs/audit/downloads.md`) -## Acceptance Criteria +- 每任務一個 isolate、原生 `HttpClient`(不走 dio);事件驅動加 5 秒輪詢;並行預設 3(1–5);進度 5% 門檻、只在記憶體。 +- 續傳只送 `Range`,沒有 `If-Range`/ETag;回 200 才從頭(N4)。沒有自動重試;每次啟動清掉已完成與**失敗**的任務(N7)。 +- 下載與播放共用音質設定(N5);副檔名一律 `.m4a`(N6);只有 sidecar(`metadata.json`、`cover.jpg`、`avatar.jpg`),沒有內嵌標籤(B13)。 +- 檔案結構 `{根目錄}/{歌單名}/{來源id}_{標題}/P01.m4a`:**依歌單分資料夾,同一首歌在兩張歌單會下載兩份**;歌單改名不改資料夾(N3)。 +- 啟動掃描以「資料夾名=歌單名」重建關聯、掃不到就清路徑(N1 的資料遺失路徑);播放時找不到檔案就永久清掉路徑(N9)。 +- Android:`MANAGE_EXTERNAL_STORAGE`+裸路徑;Android 上改下載路徑的 UI 被隱藏(N2);權限走自有 MethodChannel(刻意避開 `permission_handler`:Windows 上會被顯示成使用位置權限); + 沒有宣告 `POST_NOTIFICATIONS`(N10)。下載只在 App 行程內跑(N8)。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- `background_downloader` 9.6.3(2026-09-25,活躍,160 分):Android 用 WorkManager/UIDT 在背景繼續下載、iOS/macOS 用背景 URLSession; + **桌面是純 Dart isolate,App 關掉就停、不產生通知**。支援自訂標頭、並行上限、重試與退避、暫停續傳(桌面以 ETag 驗證)。 + **下載到 SAF URI 時不能暫停續傳**。`flutter_downloader` 不支援桌面。 +- Android 11+ 要以裸路徑寫入使用者看得到的資料夾,只有 `MANAGE_EXTERNAL_STORAGE`(Play 受限權限,FMP 不上架故可用);SAF 免權限但要走 content URI。 + App 私有目錄卸載即刪。`POST_NOTIFICATIONS` 不豁免下載通知(只豁免媒體播放通知)。 +- `permission_handler` 沒有 macOS/Linux 實作,Windows 為 no-op。 +- 內嵌標籤:m4a、flac 有純 Dart 可寫的套件(`audio_metadata_reader` 等);**WebM/Opus 幾乎沒有純 Dart 寫入方案**,只有小眾的 `flutter_taglib`,或走已退役的 FFmpegKit 分支(GPL、體積大)。 +- 續傳唯一安全的做法是 `If-Range`/強 ETag;B 站、YouTube 的網址是時效簽名,過期必須重新解析。六個參考產品都沒有用 `If-Range`。 +- 三家成熟產品(Finamp、Namida、NewPipe)以「資料庫記錄+啟動對帳」管理下載與音樂庫的關聯。Windows 路徑預設有 260 字元上限。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向 + +- 改用成熟套件(權限、背景下載);Android 下載路徑可改並可重新授權;續傳要驗證;下載專用音質;副檔名照實際格式; + 失敗任務保留到使用者清除;權限統一入口;sidecar 保留並另外寫內嵌標籤;N1 在重寫時處理。 + +## 待決定 + +- [ ] 下載檔案怎麼組織(依歌單分資料夾、每張歌單各一份,或每首歌只存一份) + +## 驗收條件 + +- [ ] ADR 0020 記錄:下載引擎與佇列、續傳與重試、下載位置與權限、檔案組織與命名、格式與標籤、與音樂庫的關聯與對帳、刪除、平台差異。 +- [ ] N1–N11、B13 各自對到決定。 +- [ ] `phase2-plan.md` §3 第 11 項標 ✅ 與 ADR 編號。 + +## 不在範圍 + +- 下載頁版面(第 5 項);邊聽邊存與已下載內容的容量管理(待辦)。 diff --git a/.trellis/tasks/09-28-design-downloads/research/current-state.md b/.trellis/tasks/09-28-design-downloads/research/current-state.md new file mode 100644 index 000000000..82e5dc156 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/research/current-state.md @@ -0,0 +1,325 @@ +# 舊專案(現行 FMP)下載與權限現況 + +- **查證日期**:2026-09-28 +- **查證方式**:唯讀原始碼審查。讀 `lib/`(Dart)、`android/app/src/main/`(Kotlin + Manifest), + 逐條核對 `docs/audit/downloads.md` 的敘述是否與現行程式碼一致。**未執行 app、未打真實 API、 + 未跑 `flutter test`、未做實機驗證。** +- **範圍**:舊專案(repo 根目錄 `lib/`);不含 `app/` 新專案。 +- **標記約定**:`檔案:行號` 為現行 `docs/audit` 分支上的行號;推論一律標「**推測**」; + 程式碼查不到答案的寫「**查不到**」;`docs/audit/downloads.md` 的敘述若與程式碼不一致會註明。 +- **既有資料**:`docs/audit/downloads.md`(396 行)與 `docs/audit/questions.md` 已對同一主題做過 + 審計。本檔的價值在於**獨立核對**(行號可能與那份不同)與補上那份沒寫到的點。 + +--- + +## 0. 一頁摘要(端到端鏈路) + +1. 使用者從歌單詳情頁按「下載」→ `playlist_detail_page.dart:967`(整張歌單,`addPlaylistDownload`) + 或 `:1043`(選取曲目,`addTracksDownload`)。 +2. `DownloadService` 建 `DownloadTask` 寫入 Isar,狀態 `pending`,再觸發排程器。 +3. 排程器每 5 秒輪詢一次,最多同時 `maxConcurrentDownloads` 個;每個任務開一個 **isolate**。 +4. isolate 內用原生 `HttpClient` 抓位元組(**不走 Dio**),寫入 `{savePath}.downloading` 暫存檔。 +5. 下載完成後 promote 成正式檔名,寫 sidecar(`metadata.json` / `cover.jpg` / `avatar.jpg`), + DB 交易一次寫入 track 的下載路徑 + 任務 `completed`。 +6. 播放時由 `Track.playlistInfo` 的下載路徑判斷是否為本機檔。 +7. 使用者在「下載管理」頁暫停/續傳/重試/取消,或在下載頁刪除已下載分類/曲目。 + +--- + +## 1. 佇列與並行 + +| 事實 | 證據 | +|---|---| +| 下載由 `DownloadService` 統一管理,任務持久化在 Isar `DownloadTask` | `lib/services/download/download_service.dart:201`(`initialize`)、`lib/data/models/download_task.dart:25-107` | +| 狀態機 5 態:`pending / downloading / paused / completed / failed` | `lib/data/models/download_task.dart:6-21` | +| 併發上限來自設定 `maxConcurrentDownloads`,**預設 3**,可調 1–5 | `lib/data/models/settings.dart:281`(`= 3`)、`lib/providers/download/download_settings_provider.dart:81-88`(`setMaxConcurrentDownloads`,值域 1–5)、`download_service.dart:426` | +| 排程器是**事件驅動 + 5 秒 fallback 輪詢** | `download_service.dart:403`(`Timer.periodic(Duration(seconds: 5))`);事件驅動觸發點見 `:398`、`:404`(任務狀態變更後呼叫 `_scheduleDownloads`) | +| 排程邏輯:取 `downloading` 數量,補足到上限,從 `pending` 依 `priority` 升冪取 | `download_service.dart:420-456`;狀態查詢 `lib/data/repositories/download_repository.dart:99-105`(`getTasksByStatus` 按 priority 排序) | +| 新任務的 priority 由 `getNextPriority()` 遞增產生 | `download_service.dart:576-585`;`download_repository.dart:338-344` | +| 同一 track 已存在下載任務時會被跳過(去重) | `download_service.dart:507-519`(比對已下載/已存在)、`:553-586`(`getTasksBySavePaths` 去重後才建) | +| 佇列上限的防護集合:`_discardedTaskIds` / `_tasksInSetupWindow` / `_setupAbortedTasks` / `_externallyCleaned` | `download_service.dart:83-92` | + +**觀察**:任務的排序鍵是 `priority`(單調遞增整數),沒有使用者可見的「置頂/順序調整」介面 —— +下載管理頁只有 pause/resume/retry/cancel 與 pauseAll/resumeAll/clearCompleted/clearQueue +(`download_manager_page.dart:32-83, 401-420`)。**推測**:實務上等於 FIFO。 + +--- + +## 2. Isolate 模型 + +| 事實 | 證據 | +|---|---| +| **每個下載任務開一個 `Isolate`**(非 pool,非背景 isolate 常駐) | `download_service.dart:818`(`Isolate.spawn`) | +| isolate 與主 isolate 以 `SendPort`/`ReceivePort` 通訊,訊息型別 `ready / progress / completed / error`(另有 `cancelled` 字串) | `download_service.dart:922`(`_drainIsolateMessages`)、`download_service.dart:1794-1795`(isolate 內送 `ready` + cancel port) | +| isolate 內用原生 `HttpClient()`,**不是 Dio** | `download_service.dart:1819`(`client = HttpClient()`);`:1820`(`connectionTimeout`) | +| Dio 在下載服務中**只用來抓封面/頭像圖**,不是抓音訊 | `download_service.dart:192-198`(`BaseOptions`,`receiveTimeout` 30 分鐘);`:1601-1622`(`_dio.download` 抓圖) | +| 手動重導向迴圈,最多 5 次,每次都檢查 scheme 與 private host(SSRF 防護) | `download_service.dart:1831-1890`;起點允許本機、只擋公網跳內網,見 `:1808-1814` | +| 用 `File.open(mode: append/write)` 而非 `openWrite()`,以避免 Android scoped storage 拒寫時產生未處理 async error 殺掉 isolate | `download_service.dart:1913-1915` 與上方註解 `:1905-1911` | +| 每個 chunk 套 30 秒接收逾時(`response.timeout`),避免 CDN 半開連線永久卡住 | `download_service.dart:1928-1930`;註解說明無自動化測試、只能真的等 `:1923-1927` | +| 取消是合作式:主 isolate 送 cancel,isolate 檢查 `isCancelled` 後自行收尾 | `download_service.dart:1787-1791`(cancel port 監聽)、`:1866-1872`(迴圈中檢查) | + +**風險點(推測)**:每個任務一個 isolate,同時 3 個下載即 3 個 isolate;isolate 內沒有 +獨立的重試,失敗即整個任務失敗(見 §5)。開 isolate 的成本在行動裝置上不算免費, +但現行併發上限 ≤ 5,**推測**影響可接受。 + +--- + +## 3. 進度回報 + +| 事實 | 證據 | +|---|---| +| isolate 內**每累積 5%** 才送一次進度(`downloadProgressUpdateThreshold`),完成時補送 100% | `download_service.dart:1941-1955` | +| 主 isolate 把進度寫入記憶體 map `_pendingProgressUpdates`,**不寫 DB** | `download_service.dart:133`、`:367-387`(`_recordProgressUpdate`) | +| 記憶體 map 上限 256 筆,超過時丟棄最舊的 | `download_service.dart:377-387`(`_pendingProgressUpdateLimit`) | +| 每秒 flush 一次到 `progressStream`(`Timer.periodic` 1000ms) | `download_service.dart:354-357` | +| `totalBytes` 另存 `_knownTotalBytes`(暫停時算續傳進度用) | `download_service.dart:143`、`:371` | +| 進度事件型別 `DownloadProgressEvent`,由 provider 轉成 UI 狀態 | `download_service.dart:99`(`progressStream`);`lib/providers/download/download_providers.dart`(`downloadProgressStateProvider`,in-memory map) | +| 完成時(isolate 收尾)才把 `progress/totalBytes` 落 DB | `download_service.dart:1219-1253`(`_saveResumeProgress`)、`:1237`(取 `_knownTotalBytes`) | + +**設計取捨**:進度有意不寫 DB,避免每秒的寫入風暴。代價是 app 被殺掉後, +進度只剩最後一次落 DB 的值(`_saveResumeProgress` 的觸發點), +**推測** UI 上可能出現進度回退。 + +--- + +## 4. 續傳(resume) + +| 事實 | 證據 | +|---|---| +| `canResume` = `tempFilePath != null && downloadedBytes > 0` | `lib/data/models/download_task.dart:98` | +| 暫存檔路徑 = `{savePath}.downloading` | `download_service.dart:1092`(`tempPath = '$savePath.downloading'`) | +| 只有在 `canResume && tempFilePath == tempPath && 暫存檔存在` 時才真的續傳,否則重抓 | `download_service.dart:1112-1122` | +| 續傳請求只加 `Range: bytes=N-`,**沒有 `If-Range`、沒有 ETag、沒有 `Content-Range` 驗證** | `lib/services/media/media_handoff.dart:54-62`(`prepareDownloadHop` 只加 `mediaHeaders` + 條件式 `Range`) | +| 若伺服器回 **HTTP 200**(不是 206),自動改成從 0 重寫 | `download_service.dart:1904-1906`(`shouldRestartFromZero`)、`:1918-1919`(`totalBytes` 重算) | +| 續傳時開檔模式 `append`,重寫時 `write` | `download_service.dart:1913-1915` | + +**核心風險**:伺服器回 206 但**檔案內容其實已變**(同 URL 不同位元組)時,現行邏輯 +無法察覺 —— 因為沒有 `If-Range`/ETag 比對,只有「200 就重來」這一道粗糙防線。 +這正是 owner 在 `phase2-plan.md` 要求「resume 必須驗證 If-Range/ETag」的由來。 +**推測**:Bilibili / YouTube CDN 對同一 URL 的位元組通常穩定,但 signed URL 換發後 +URL 會變,理論上由「URL 變了就查不到舊暫存檔」擋掉一部分;真正會出事的是 +URL 不變而內容變的少數情形(例如直播回放轉檔完成)。 + +--- + +## 5. 失敗與重試 + +| 事實 | 證據 | +|---|---| +| 錯誤分成型別:`timeout / network / http / filesystem / unknown`(isolate 內以 JSON 字串回傳,主 isolate 解回例外) | `download_service.dart:1348-1373`(`_isolateFailure`)、isolate 端錯誤分支 `:1965+` | +| 使用者可見訊息是**已翻譯字串**(`_failureMessageFor`),存進任務 `errorMessage` | `download_service.dart:1380-1385`、`:1388-1407`(`_handleDownloadFailure`) | +| HTTP >= 400 直接當失敗,訊息 `HTTP {code}` | `download_service.dart:1892-1901` | +| `retryTask` 會**先刪掉舊檔與暫存檔**再重排 | `download_service.dart:679-692`、`:1299-1344`(重試前刪檔)、`:1263-1293`(`_deleteTaskFiles`) | +| 失敗任務**保留在佇列**,不會自動消失(符合 owner 要求「失敗任務保留到使用者清除」) | 任務僅在 `clearCompletedAndErrorTasks`/`clearQueue` 時移除:`download_repository.dart:66-96`、`:306-315`;`initialize()` 會清 `completed + failed`:`download_service.dart:207-208` | +| HLS(m3u8)串流被明確拒絕,不會嘗試下載 | `download_service.dart:1065-1070` | +| 沒有自動重試/退避(no auto-retry / backoff) | 全檔未見重試迴圈;`retryCount` 只出現在**串流解析**層(`stream_resolution_service.dart:167`),不是位元組下載層 | + +**注意**:`initialize()` 在每次啟動時清掉 `completed + failed` 任務(`download_service.dart:207-208`), +同時 `resetDownloadingToPaused()` 把 `downloading` 與 `pending` 都重設成 `paused` +(`download_repository.dart:258-273`)。**推測**:這是「重開 app 後失敗清單消失」的原因; +若新專案要求失敗任務跨重啟保留,這行為要改。 + +--- + +## 6. 下載路徑:選擇、儲存、變更 + +| 事實 | 證據 | +|---|---| +| 自訂下載目錄存 `Settings.customDownloadDir` | `lib/data/models/settings.dart:250` | +| 是否已設定:`hasConfiguredPath()` | `lib/services/download/download_path_manager.dart:25-29` | +| 選目錄流程:Android 先要權限 → `FilePicker.getDirectoryPath()` → 用 `.fmp_test` 檔寫入後刪除**驗證可寫** | `download_path_manager.dart:34-56`;`:44`(getDirectoryPath)、`:48-53`(verifyWrite)、`:59-68`(.fmp_test) | +| 生效目錄:`getEffectiveBaseDir` | `download_path_manager.dart:87-88` | +| **Android 上「變更下載路徑」的 UI 被隱藏**(`if (!Platform.isAndroid)`) | `lib/ui/pages/settings/widgets/settings_storage.dart:60` | +| 預設目錄(各平台) | `download_path_utils.dart:187-216`(`getDefaultBaseDir`) | +| Windows 預設 = 應用文件目錄下的 `FMP`(即 `Documents\FMP`) | `download_path_utils.dart:214`;`lib/data/database/database_provider.dart:51`、`lib/services/logging/log_file_sink.dart:25`(同一目錄慣例) | +| 變更 base path 時**不搬檔、不掃描**,只是清空所有下載路徑 + 刪除 completed/failed 任務 + 存新路徑 | `lib/services/download/download_path_maintenance_service.dart:59-80`(`changeBasePathAndResetDownloads`) | +| 路徑逃逸防護:`isPathInsideBase` | `download_path_utils.dart:117-122`;在 `computeDownloadPath` 內強制 `:51-56` | + +**Android 儲存策略**(見 §11):MANAGE_EXTERNAL_STORAGE + 裸路徑,不用 MediaStore / SAF, +理由記在 ADR 0004。**推測**:因為不用 SAF,所以自訂目錄才需要「先要權限再 getDirectoryPath」, +而且預設目錄(app-specific external)本身免權限。 + +--- + +## 7. 檔名與資料夾結構 + +| 事實 | 證據 | +|---|---| +| 結構:`{baseDir}/{歌單名}/{sourceId}_{parentTitle}/P{NN}.m4a` 或 `.../audio.m4a` | `download_path_utils.dart:23-57`(`computeDownloadPath`)、檔頭註解 `:12`、`:18` | +| 子目錄:有歌單名用歌單名,沒有則用 `未分类` | `download_path_utils.dart:29-32` | +| 影片資料夾名:`{sanitizePathComponent(sourceId)}_{sanitizeFileName(parentTitle)}` | `download_path_utils.dart:34-36` | +| 多 P 影片:`P{pageNum 兩位補零}.m4a`;單 P:`audio.m4a` | `download_path_utils.dart:40-46` | +| **副檔名永遠硬編 `.m4a`**,與實際容器無關 | `download_path_utils.dart:42,44`;`download_path_maintenance_service.dart:596-600` 的註解明白承認:來源設定的 opus/aac「只決定串流容器」,檔名仍是 `.m4a` | +| 非法字元清理:9 個 Windows 非法字元換全形、trim、去尾點、Windows 保留名(CON/PRN/...)、200 字截斷 | `download_path_utils.dart:81-115`(`sanitizeFileName`)、`:124-156`(保留名) | +| sidecar 檔名常數 | `lib/core/constants/download_filenames.dart:14-33`(`cover.jpg` / `avatar.jpg` / `metadata.json`;`metadataCandidatesForAudio`:`P{N}` → `metadata_P{N}.json` 再退 `metadata.json`) | + +**與 owner 要求對照**:owner 要求「副檔名要符合實際格式」。現況**不符** —— 一律 `.m4a`。 + +--- + +## 8. 附帶檔案(sidecar) + +| 檔案 | 何時寫 | 證據 | +|---|---|---| +| `metadata.json` / `metadata_P{N}.json` | 下載完成後寫入曲目中介資料(標題、藝人、時長、sourceId、pageNum 等) | `download_service.dart:1499-1599`(`_saveMetadata`);欄位 `:1509-1522`;檔名決策 `:1556-1559` | +| `cover.jpg` | 有封面 URL 時以 Dio 抓,尺寸 tier high | `download_service.dart:1567-1581`;抓圖 `:1601-1622`(`ImageTargetSizes.high`) | +| `avatar.jpg` | 僅在 `downloadImageOption` 選 coverAndAvatar 時,尺寸 tier low | `download_service.dart:1583-1598`(`ImageTargetSizes.low`) | +| **沒有歌詞 sidecar** | 下載流程不寫任何歌詞檔 | 全檔未見寫歌詞;歌詞是獨立的 lyrics cache 服務,不在下載目錄 | +| **沒有內嵌 tag(無 ID3/ffmpeg)** | `pubspec.yaml` 無任何 tag/metadata/ffmpeg 套件 | `pubspec.yaml`(依賴清單未見 audiotags / metadata_god / ffmpeg_kit 等) | + +**與 owner 要求對照**:owner 要求 B13「保留 sidecar metadata/封面 + 加內嵌音訊 tag」。 +現況是**只有 sidecar、沒有內嵌 tag**。內嵌 tag 需要新依賴(見 `packages-and-platform.md`)。 + +--- + +## 9. 下載目錄掃描同步(N1:資料遺失路徑) + +| 事實 | 證據 | +|---|---| +| 啟動時觸發一次掃描同步 | `lib/app.dart:131`(`ref.watch(startupDownloadSyncProvider)`);`lib/providers/download/startup_download_sync_provider.dart:9-40`(`syncLocalFiles`,catch + log) | +| `syncLocalFiles` 是 **REPLACE 模式**:掃描結果取代 DB 中的下載狀態 | `lib/services/download/download_path_sync_service.dart:26-232` | +| 重建 `playlistInfo` 時**只保留 `playlistName == 資料夾名` 的項目**,其餘丟棄 | `download_path_sync_service.dart:158-197`(`:158-199`) | +| 掃到但對不上任何曲目的資料夾,會以 `playlistId = 0` 加入 | `download_path_sync_service.dart:158-197` 後段 | +| 第三步:**把本機掃不到的曲目之下載路徑清空** | `download_path_sync_service.dart:214-224` | +| 配對邏輯:`cid → pageNum → true` | `download_path_sync_service.dart:234-272`(`_matchScannedDownload` / `_matchesScannedPage`) | +| 掃描只認 `.m4a`,且只在固定層數內遞迴 | `lib/providers/download/download_scanner.dart:223-233`(`_countAudioFilesInternal` 遞迴 `.m4a`)、`:305-313`(`scanFolderForTrackDto` 兩層) | +| 無 metadata 時的 fallback:用資料夾前綴當 sourceId,且 **sourceId 硬編 `SourceIds.bilibili`** | `download_scanner.dart:385-391` | +| 掃出的 `DownloadedTrackDto.toTrack()` 會把 `playlistId` 設 0,但保留 `sourceTypeName` | `download_scanner.dart:86-105` | +| `cleanupInvalidPaths` 是**死碼**(無呼叫者) | `download_path_sync_service.dart:313-318` | + +**N1 資料遺失成因(推測鏈)**:REPLACE 模式 + 「掃不到就清路徑」+「只認特定資料夾名」 +三者疊加。若使用者在 app 外改名/搬動資料夾,或來源改了 `parentTitle`, +下次啟動掃描就會把該曲目的下載路徑清成 null。`docs/audit/downloads.md` 已確認呼叫鏈, +但**未在實機重現**。owner 已在 `questions.md` 把此項標為 +「`[x]` 先不修,重寫時處理」。 + +**與 owner 要求對照**:owner 要求 N1 的資料遺失路徑在重寫時處理。現況是**資料遺失路徑存在**。 + +--- + +## 10. 播放時的本機檔判斷(N9) + +| 事實 | 證據 | +|---|---| +| 下載路徑掛在 `Track.playlistInfo`(`List`),每筆含 `playlistId/playlistName/downloadPath` | `lib/data/models/track.dart:11-33`、`:85`(`playlistInfo`) | +| 是否為本機檔:`isDownloadedForPlaylist(playlistId)` / `belongsToPlaylist` | `track.dart:156-158`、`:173-188` | +| 取路徑:`getDownloadPathForPlaylist` / byName | `track.dart:111-146`(`setDownloadPath` 同段) | +| 清除:`clearAllDownloadPaths`;`hasAnyDownload` / `allDownloadPaths` | `track.dart:193-205`、`:229-236` | +| 串流解析只有在 `purpose != download` 時才檢查本機檔 | `lib/services/audio/stream_resolution_service.dart:128` | +| **無效的本機路徑會被永久清除**(不是降級成遠端重抓就好) | `stream_resolution_service.dart:126-145`(invalid → 清 path) | +| 檔案存在性有正/負快取(各上限 5000),避免每次播放都打檔案系統 | `lib/providers/download/file_exists_cache.dart` | + +**與 owner 要求對照**:owner 要求 N9(播放時如何判定本機檔)要在重寫時明確定義。 +現況判定依據是 DB 中的路徑字串 + 檔案存在性快取,**不是**每次實際開檔驗證, +所以「檔案被外部刪掉」與「檔案存在」之間有一段快取窗口 —— **推測**會出現 +「UI 說已下載、實際播放失敗」的短暫不一致。 + +--- + +## 11. 權限 + +### Android:自建 MethodChannel(刻意的,不用 `permission_handler`) + +| 事實 | 證據 | +|---|---| +| MethodChannel 名稱 `com.personal.fmp/platform` | `android/app/src/main/kotlin/com/personal/fmp/MainActivity.kt:20-35`;Dart 端 `lib/services/platform/storage_permission_service.dart:25-28` | +| **刻意避開 `permission_handler`**:官方原因寫在 dartdoc —— Windows 上會讓 FMP 被顯示成使用「位置」權限 | `storage_permission_service.dart:22-24` | +| SDK < R(Android 11)時 `isManageExternalStorageGranted()` 直接回 true | `MainActivity.kt:62-65` | +| 要 MANAGE_EXTERNAL_STORAGE:先試 `ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION`,失敗再退到全域設定頁 | `MainActivity.kt:75-103` | +| 舊版權限清單:SDK < M 或 >= R 時回空 | `MainActivity.kt:125-136`(`legacyStoragePermissions`) | +| 開系統設定頁 `openAppSettings` | `MainActivity.kt:138-148` | +| Dart 端 `_manageExternalStorageStatus` **只回 granted / denied 兩態**,所以 `permanentlyDenied` 分支在 Android 上永遠走不到 | `storage_permission_service.dart:145-151` | +| `hasStoragePermission()` **在正式路徑沒有呼叫者**(只被測試用到) | `storage_permission_service.dart:69-77` | +| 說明對話框 + 「去設定」對話框 | `storage_permission_service.dart:180-241`、`:244-269` | +| `openInstallPermissionSettings` / `canRequestPackageInstalls`(APK 安裝權限) | `MainActivity.kt` 同檔另有實作 | + +### AndroidManifest + +| 權限 | 狀態 | 證據 | +|---|---|---| +| `MANAGE_EXTERNAL_STORAGE` | 有,帶 `tools:ignore="ScopedStorage"` | `android/app/src/main/AndroidManifest.xml:22-23` | +| `READ_EXTERNAL_STORAGE` | 有,`maxSdkVersion=32` | `AndroidManifest.xml:17-18` | +| `WRITE_EXTERNAL_STORAGE` | 有,`maxSdkVersion=29` | `AndroidManifest.xml:19-20` | +| `WAKE_LOCK` / `FOREGROUND_SERVICE` / `FOREGROUND_SERVICE_MEDIA_PLAYBACK` / `INTERNET` / `ACCESS_NETWORK_STATE` | 有 | `AndroidManifest.xml:5-23` | +| `REQUEST_INSTALL_PACKAGES` | 有 | 同上 | +| **`POST_NOTIFICATIONS`** | **沒有宣告** | 主 manifest 與合併 manifest 皆未見;**推測** Android 13+ 上背景下載的完成通知不會顯示 | +| **`READ_MEDIA_AUDIO` / `READ_MEDIA_*`** | **主 manifest 沒有**;只在 `open_filex` 合併進來 | 主 manifest 未見,來源是 `open_filex` 的 transitive manifest | + +**與 owner 要求對照**:owner 要「統一的權限入口」。現況是單一 service(`StoragePermissionService`) +但只涵蓋儲存權限,通知權限根本沒申請。ADR 0004 已「知情接受」MANAGE_EXTERNAL_STORAGE + 裸路徑; +owner 在新專案要求「Android 下載路徑可變更且可重新授權」—— 現況 Android 上該 UI 被隱藏(§6)。 + +--- + +## 12. 刪除 + +| 行為 | 入口 | 證據 | +|---|---|---| +| 刪除單一已下載曲目 | 下載分類頁 | `lib/ui/pages/library/downloaded_category_page.dart:723-724`(`deleteDownloadedTracks([track])`) | +| 批次刪除分類內曲目 | 下載分類頁 | `downloaded_category_page.dart:552-553` | +| 刪除整個已下載分類 | 下載頁 | `lib/ui/pages/library/downloaded_page.dart:467-469`(`deleteDownloadedCategory`) | +| 刪除前**先掃描**再刪,避免刪錯 | — | `download_path_maintenance_service.dart:82-116`、`:118-137` | +| base dir 解析失敗時的停用保護(`_resolveEffectiveBaseDir`) | — | `download_path_maintenance_service.dart:139-156` | +| 刪完清 DB 路徑 `_clearDeletedPaths` | — | `download_path_maintenance_service.dart:167+` | +| **孤兒 track 清理**:定義為「不在佇列 AND 沒有任何 `playlistId > 0` 的 playlistInfo」 | — | `lib/data/repositories/track_repository.dart:625`(註解)、`:635`(`deleteOrphanTracks`)、`:652-656`(判定) | +| 佇列管理器每 10 秒跑一次孤兒清理 | — | `lib/services/audio/queue_manager.dart:226-228`(`Timer(Duration(seconds: 10))` → `_cleanupOrphanTracks`)、`:830`(實作) | + +**風險(推測)**:孤兒判定**不看 `Playlist.trackIds`**,只看 `playlistInfo`。 +所以「已從歌單移除、但仍有 `playlistId>0` 的下載紀錄」的 track 不會被清; +反之若某 track 從未進過任何歌單而下載路徑被清空,就可能被判孤兒刪掉。 +owner 已在 ADR 0019 決定「refresh 移除的曲目不刪下載」,此判定邏輯在重寫時要重新設計。 + +--- + +## 13. 下載音質(owner 明確要改的一項) + +| 事實 | 證據 | +|---|---| +| **下載與播放共用同一個全域音質設定** `Settings.audioQualityLevelIndex`(高/中/低) | `lib/data/models/settings.dart:309`、`:513-534`(getter/setter)、`lib/services/audio/stream_resolution_service.dart:405`(`AudioStreamConfig.fromSettings`) | +| 下載的串流解析走 `StreamResolutionPurpose.download`,但**音質仍讀全域設定** | `download_service.dart:1047`(purpose: download)、`stream_resolution_service.dart:405` | +| 下載**刻意不重用**快取的解析結果(避免 5 分鐘 URL 失效) | `stream_resolution_service.dart:150-155` 與上方註解 | + +**與 owner 要求對照**:owner 要求「下載專用音質」。現況**沒有**下載專用音質 —— 下載與播放同一個設定。 + +--- + +## 14. N1–N11/B13 與現況對照 + +> 完整題目定義見 `docs/audit/questions.md`。下表只把「現況一句話」補上。 + +| 項 | 現況一句話 | 本檔節 | +|---|---|---| +| N1 下載目錄掃描造成資料遺失 | REPLACE + 掃不到即清路徑;呼叫鏈確認、未實機重現 | §9 | +| N2 佇列與併發 | 5 秒輪詢 + 事件驅動;上限預設 3(1–5) | §1 | +| N3 進度回報 | 5% 門檻、記憶體、每秒 flush;不寫 DB | §3 | +| N4 續傳 | 只有 `Range`,無 `If-Range`/ETag;200 即重來 | §4 | +| N5 失敗與重試 | 5 類錯誤;手動重試;**無自動重試** | §5 | +| N6 內嵌 tag | **無**(無 tag/ffmpeg 依賴),只有 sidecar | §8 | +| N7 儲存位置(Android SAF vs 裸路徑) | MANAGE_EXTERNAL_STORAGE + 裸路徑(ADR 0004) | §6、§11 | +| N8 路徑變更 | 變更即清空所有下載路徑,不搬檔 | §6 | +| N9 播放時本機檔判定 | DB 路徑 + 存在性快取,非每次開檔 | §10 | +| N10 刪除 | 4 個入口,皆先掃描再刪 | §12 | +| N11 權限 | 自建 MethodChannel;只做儲存權限;通知權限缺 | §11 | +| B13 sidecar | metadata.json / cover.jpg / avatar.jpg;無歌詞 | §8 | + +--- + +## 15. 查不到 / 未驗證 + +- **`POST_NOTIFICATIONS` 在 Android 13+ 的實際行為**:程式碼未宣告,也未申請; + 是否因 `audio_service` 的前景服務而豁免顯示,**查不到**(需實機)。 +- **N1 資料遺失是否真的會在使用者操作下發生**:呼叫鏈已確認,**未在實機重現**(`downloads.md` 亦同)。 +- **Bilibili / YouTube CDN 對 `Range` 的實際回應**(是否穩定回 206、是否回 ETag): + 未打真實 API,**查不到**(新專案要用 `packages-and-platform.md` 的公開行為描述 + 實測補)。 +- **`_dio` 抓封面失敗時的行為**(是否讓整個下載任務失敗):程式碼有各自 catch, + 但**推測**不影響音訊檔完成(`_saveMetadata` 在 promote 之後),未逐行確認到 exception 邊界。 +- **Windows 可攜版(portable)下載目錄**:現行一律用 `Documents\FMP`(§6), + 可攜版是否應改存自身資料夾是 **A4 開放問題**(`questions.md`),程式碼層面**尚未實作**。 + +--- + +## 16. 給新專案設計的三個硬約束(由現況推得) + +1. **副檔名要跟實際容器一致**:現行硬編 `.m4a`(§7),新專案要改。 +2. **下載要有自己的音質設定**:現行與播放共用(§13),新專案要拆。 +3. **續傳要有 `If-Range`/ETag 驗證**:現行只憑 200/206 粗判(§4),新專案要補。 diff --git a/.trellis/tasks/09-28-design-downloads/research/packages-and-platform.md b/.trellis/tasks/09-28-design-downloads/research/packages-and-platform.md new file mode 100644 index 000000000..757fabab1 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/research/packages-and-platform.md @@ -0,0 +1,615 @@ +# 套件與平台查證:下載引擎、權限、內嵌標籤、HTTP 續傳、平台沙盒 + +- **查證日期**:2026-09-28 +- **查證方式**:優先 **context7** 官方文檔;context7 無對應條目時改用 + **tavily-search / tavily-extract** 取官方文檔、RFC 或平台官方頁面。 + 套件版本與最後發佈日期一律以 **pub.dev**(頁面與 `https://pub.dev/api/packages/` 的 + `published` 絕對時間戳)為準;repo 狀態用 `gh api`。README 抓不到時才用搜尋工具。 +- **範圍限制**:全程唯讀。**未呼叫任何真實 API、未執行 app、未跑測試**。 + 因此凡是「CDN 實際回應」一類需要打 API 才能確認的事實,一律標「**推測**」; + 找不到可靠來源的標「**查不到**」。 +- **檔案結構**:本檔由兩份平行調查合併而成 —— **第一部(下載引擎與權限)**、 + **第二部(內嵌標籤、HTTP 續傳、平台下載位置)**。兩部各自有字母編號的章節與 + 「與 FMP 決策相關的關鍵事實」,故字母在部內有意義,跨部不連續。 + +--- + +# 第一部:下載引擎與權限 + +## A. 背景下載套件 + +### A1. `background_downloader` + +**版本與維護狀態** + +- 最新版本 **9.6.3**,發佈 **2026-09-25T20:33:49Z**。來源:`https://pub.dev/api/packages/background_downloader` +- pub points **160/160**、likes **504**、30 天下載 **237,854**。來源:`https://pub.dev/api/packages/background_downloader/score` +- Repo 已從 `bbflight/background_downloader` 移到 **`781flyingdutchman/background_downloader`**(pubspec 的 `repository` 欄位;`bbflight` 路徑已 404)。default branch `main`,最後 push 2026-09-25,238 stars,open issues 0,未 archived。來源:`gh api repos/781flyingdutchman/background_downloader`、`https://pub.dev/api/packages/background_downloader` +- 版本節奏密:9.5.9(2026-08-29)→ 9.6.0(09-07)→ 9.6.1(09-10)→ 9.6.2(09-16)→ 9.6.3(09-25)。來源:同上 API +- 需求:Dart SDK `^3.13.0`、Flutter `>=3.47.0`(`pubspec.yaml`)。Android 端要求 Kotlin 2.1.0+。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/pubspec.yaml`、`README.md` + +**平台支援** + +- pubspec 宣告 `platforms: android / ios / linux / macos / windows`,**沒有 web**。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/pubspec.yaml` +- README 標題即寫「for iOS, Android, MacOS, Windows and Linux」;Windows 與 Linux「No setup is required」。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/README.md` + +**底層實作(差異極大,是重點)** + +- Android:`WorkManager` + `JobScheduler`(Android 14+ 的 UIDT,`UIDTJobService`)。iOS/macOS:background `URLSession`。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/ARCHITECTURE.md` +- 桌面(Windows / Linux / macOS):**純 Dart 實作**,`DesktopDownloader` + 每個任務一個 `Isolate` + `package:http`(`io_client`)。原文:「Unlike mobile, desktop OSs generally allow long-running processes, so `WorkManager` or `URLSession` equivalents are not used.」來源:同上 +- 桌面**沒有系統級持久化**:「There is no 'system' persistence for tasks on Desktop. If the app closes, the Isolate dies, and the download stops.」Dart 側 `Database` 只保留 task 的*記錄*,重啟後可依 Range header 續傳(邏輯允許的話)。來源:同上 +- 桌面對照表(同頁):Background Engine = Dart `Isolate`、Persistence = **App Lifecycle only**。來源:同上 + +**通知** + +- 只在 iOS / Android 產生通知(進度/完成/暫停/取消、可設進度條、`tapOpensFile`)。桌面上**完全不產生通知**,原文:「No notifications will be generated: On desktop platforms, as there is no true background mode」。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/notifications.md` +- Android 13+ 需在 manifest 加 ``。來源:同上 +- Android 14+ 用 `TransferHint.userInitiated` 或 `priority: 0`(UIDT)時,OS **要求**有使用者可見的通知;沒設定 notificationConfig 可能排不進去或被取消,且需 `android.permission.RUN_USER_INITIATED_JOBS`。來源:`doc/notifications.md`、`doc/parameters.md` + +**暫停/續傳** + +- 要開 `allowPause: true`(或 `TransferHint.largeFile` / `userInitiated`)。原文限制:「Pausing is only possible for download GET requests, only if the `Task.allowPause` field is true, and only if the server supports pause/resume.」可用 `taskCanResume` 查伺服器是否支援。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/lifecycle.md` +- 桌面同樣走 Range + ETag:`download_isolate.dart` 送 `Range: bytes=-`,並在 resume 時驗證 ETag(不同或 weak 就丟 `TaskException('Cannot resume: ETag is not identical, or is weak')`);伺服器不支援 ranges 就不能 resume。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/lib/src/desktop/download_isolate.dart` + +**自訂 HTTP header 與並行上限** + +- `headers`(`Map`)、`urlQueryParameters`、`httpRequestMethod`、`post`、`retries`(1–10,指數退避)。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/parameters.md` +- 並行上限用 holding queue:`await FileDownloader().configure(globalConfig: (Config.holdingQueue, (maxConcurrent, maxConcurrentByHost, maxConcurrentByGroup)))`,傳 `null` 表示該項不限。holding queue 是**原生側**,app 被暫停仍會從佇列拉任務;Dart 側的 `MemoryTaskQueue`(`maxConcurrent` / `maxConcurrentByHost` / `maxConcurrentByGroup`)則會隨 app 暫停而停。來源:`doc/lifecycle.md` +- 桌面 `DesktopDownloader` 的預設值:`maxConcurrent = 10`、`maxConcurrentByHost = unlimited`、`maxConcurrentByGroup = unlimited`。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/lib/src/desktop/desktop_downloader.dart`(`var maxConcurrent = 10;` 與 `configure` 的 `?? 10`) + +**Dart 側進度** + +- 拿得到。`FileDownloader().updates` stream(`TaskStatusUpdate` / `TaskProgressUpdate`)、`registerCallbacks`、以及 `Transfer` handle 的 `progressNotifier`(0.0–1.0)、`statusNotifier`、`networkSpeedNotifier`、`timeRemainingNotifier`、`holdReasonNotifier`。來源:`README.md`、`doc/transfers.md` + +**Android 下載到 app 私有目錄 vs 自選資料夾** + +- `BaseDirectory` 的選項(`.applicationDocuments` / `.temporary` / `.applicationSupport` / `.applicationLibrary`)**全部是 app 私有**。要給使用者看到,得下載完成後 `FileDownloader().moveToSharedStorage(task, SharedStorage.downloads)`。`SharedStorage` 選項:`.downloads`(全平台,iOS 是假的)、`.images` / `.video`(Android+iOS)、`.audio`(Android+iOS,iOS 假)、`.files` / `.external`(僅 Android)。iOS 的「假」是在 app Documents 下開子目錄。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/storage.md` +- 直接寫入使用者自選資料夾要用 URI API:`downloader.uri.pickDirectory()` + `UriDownloadTask(directoryUri: ...)`;Android 上此路徑**繞過暫存檔直接寫入目的**。**但 URI 下載不能暫停或續傳**(原文:「Note that Uri downloads cannot be paused or resumed.」),且 Android 上目的 URI 有檔案不代表下載成功(可能是半截)。來源:`https://github.com/781flyingdutchman/background_downloader/blob/main/doc/URI.md` +- 桌面沒有內建檔案/目錄 picker;官方建議用 `file_picker` 拿路徑再轉 `Uri.file(path, windows: Platform.isWindows)`。來源:`doc/URI.md` +- `openFile`:Android 上 `BaseDirectory.applicationDocuments` 裡的檔案**不能開**,要改存 `.applicationSupport` 或先搬到 shared storage。來源:`doc/notifications.md` + +**Android 執行時間限制** + +- WorkManager 標準背景任務上限 **9 分鐘**;要跑更久需 `allowPause: true`(自動跨 9 分鐘循環續傳)或 Android 14+ 的 `priority: 0`(UIDT,免限)。`priority < 5` 視為 expedited,上限 **2 分鐘**。來源:`README.md`、`doc/parameters.md` +- 重定向:桌面與前景請求最多 10 個;行動平台用系統預設(iOS 16、Android 20)。來源:`README.md`(9.6.3 changelog:「Raise HTTP redirect limit to 10 for desktop and foreground requests」) + +--- + +### A2. `flutter_downloader` + +- 最新版本 **1.12.1**,發佈 **2026-08-22T08:28:20Z**。來源:`https://pub.dev/api/packages/flutter_downloader` +- pub points **140/160**、likes **1,641**、30 天下載 **156,521**。來源:`https://pub.dev/api/packages/flutter_downloader/score` +- 平台:**只有 Android 與 iOS**。`pubspec.yaml` 的 `flutter.plugin.platforms` 只有 `android` 與 `ios`;README 第一句「A plugin for creating and managing download tasks. Supports iOS and Android.」→ **不支援任何桌面平台**。來源:`https://github.com/fluttercommunity/flutter_downloader/blob/master/pubspec.yaml`、`.../README.md` +- 底層:Android 用 `WorkManager`、iOS 用 `NSURLSessionDownloadTask`。來源:`.../README.md` +- Repo:940 stars、**351 open issues**、最後 push 2026-08-22(與 pub 發佈同日)。來源:`gh api repos/fluttercommunity/flutter_downloader` +- README 有一段維護者開發註記,值得注意:「The changes of external storage APIs in Android 11 cause some problems with the current implementation. I decide to re-design this plugin with new strategy to manage download file location. It is still in triage and discussion in this PR (#550).」來源:`.../README.md` +- 安全:README 明言**舊版本有 SQL injection 漏洞**,建議升級到最新版。來源:`.../README.md` +- iOS 限制(README):「This plugin only supports save files in `NSDocumentDirectory`」。來源:`.../README.md` + +**與 `background_downloader` 的差異(事實層面)** + +- 平台:flutter_downloader 只有 Android/iOS;background_downloader 另有 Windows/Linux/macOS(桌面為 Dart isolate、無系統背景)。 +- flutter_downloader 的 Android 檔案位置策略正是它自己承認還沒重設計的部分(Android 11 外部儲存 API 變更);background_downloader 另外提供 `BaseDirectory`(app 私有)與 SAF URI 兩條路,且文件化各自的限制。 +- flutter_downloader 是高人氣舊套件(1.64k likes)但 open issues 多(351)、改版慢(1.12.0 → 1.12.1 隔了約 19 個月)。background_downloader 活躍(1 個月內 5 個版本、open issues 0)。 +- 來源:上述兩套件的 pub.dev 頁與 README。 + +--- + +### A3. 在 `dio` 自己下載 + +- `dio` 最新版本 **5.11.1**,發佈 **2026-09-04**。points **160/160**、likes **8,352**、30 天下載 **4,577,877**。來源:`https://pub.dev/api/packages/dio`、`https://pub.dev/api/packages/dio/score` + +**事實** + +- `Dio.download` 的公開簽名(5.11.1): + `Future download(String urlPath, dynamic savePath, {ProgressCallback? onReceiveProgress, Map? queryParameters, CancelToken? cancelToken, bool deleteOnError = true, FileAccessMode fileAccessMode = FileAccessMode.write, String lengthHeader = Headers.contentLengthHeader, Object? data, Options? options})`。 + 來源:`https://pub.dev/documentation/dio/latest/dio/Dio/download.html` +- `onReceiveProgress(received, total)`:若檔案被壓縮且用預設 content-length header,`total` 會是 **-1**;官方建議設 `accept-encoding: '*'` 讓 `total` 不是 -1。來源:同上 +- `deleteOnError` 預設 `true`(失敗時刪掉半截檔);`FileAccessMode.append` 存在但 **web 不支援**。**公開 API 沒有任何自動續傳/resume 參數** —— 續傳要自己送 `Range` header(`Options(headers: ...)`)並自己決定 append。來源:同上 +- 取消:`CancelToken`(一個 token 可共用於多個請求;`CancelToken.isCancel(error)`)。來源:`https://pub.dev/packages/dio` +- dio **不在背景 isolate 執行請求**;唯一的 isolate 用法是 default transformer 對 >50KB 的回應做 `jsonDecode`。下載進度與取消都在 main isolate 的 callback/token 上。來源:`https://pub.dev/packages/dio` + +**與上面兩者的取捨(事實)** + +- 控制權最大:自訂每一條 header、重試、重定向、續傳策略、寫檔位置、檔案命名(`savePath` 可傳 `FutureOr Function(Headers)`)。代價是全部要自己寫(續傳、進度持久化、失敗重試、並行上限)。 +- 沒有 OS 層背景排程:dio 跑在 app 的 Dart 執行環境。Android 要「切到背景/螢幕關掉仍跑完」需自己開 foreground service(社群常用 `flutter_foreground_task`,最新 **11.0.3**、發佈 **2026-09-07**、points 150/160、likes 583、30 天下載 218,915:`https://pub.dev/api/packages/flutter_foreground_task`);Windows 沒有等價機制(推測:Flutter 生態沒有現成的 Windows service 套件,未查證)。 +- 對比 `background_downloader`:後者已在 Android 端用 WorkManager/UIDT 處理 app 被殺後續傳、在 iOS 用 background URLSession、並處理 WorkManager 9 分鐘上限,且提供 Transfer API(進度 notifier、暫停續傳、通知)。自己用 dio 等於把這些重做一遍。 +- 對比 `flutter_downloader`:dio 至少能覆蓋桌面。 +- 「在 isolate 下載」不改變背景限制:isolate 隨 process 死亡,Android 上 app 程序被殺(非前景服務)就停;桌面 app 關閉就停。 + +--- + +## B. 權限 + +### B1. `permission_handler` + +**版本與維護狀態** + +- 最新版本 **13.0.2**,發佈 **2026-09-04T09:59:07Z**。來源:`https://pub.dev/api/packages/permission_handler` +- pub points **160/160**、likes **6,014**、30 天下載 **3,432,295**。來源:`https://pub.dev/api/packages/permission_handler/score` +- Repo `baseflow/flutter-permission-handler`:2,174 stars、開放 issue 162、最後 push 2026-09-26、未 archived。來源:`gh api repos/baseflow/flutter-permission-handler` + +**平台支援** + +- `flutter.plugin.platforms` 只宣告四個 endorsed implementation:`android` → `permission_handler_android`、`ios` → `permission_handler_apple`、`web` → `permission_handler_html`、`windows` → `permission_handler_windows`。**沒有 macOS、沒有 Linux**。來源:`https://pub.dev/api/packages/permission_handler`(pubspec) +- pub.dev 頁面平台標籤同樣是 Android / iOS / web / Windows。來源:`https://pub.dev/packages/permission_handler` +- **Windows 實作是近乎 no-op 的 stub**:`checkPermissionStatus` 永遠回 `GRANTED`;`requestPermissions` 對每個傳入的 permission 都回 `GRANTED`;`shouldShowRequestPermissionRationale` 與 `openAppSettings` 都回 `false`(唯一真正做事的只有 `checkServiceStatus` 的 location / bluetooth / ignoreBatteryOptimizations 分支)。來源:`https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_windows/windows/permission_handler_windows_plugin.cpp` + - 推測(未實測):在 Windows 上呼叫 `Permission.x.request()` 一律回 granted,且不會有任何系統 UI;`openAppSettings()` 是 no-op。 +- macOS / Linux:無實作 → 推測呼叫時會 `MissingPluginException` 或 `UnimplementedError`(未在文檔中明寫,**查不到**正式說明)。 + +**`openAppSettings()`** + +- 用途:開啟本 app 的系統設定頁,讓使用者手動開啟權限。官方範例註解:「The user opted to never again see the permission request dialog for this app. The only way to change the permission's status now is to let the user manually enable it in the system settings.」來源:`https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/README.md` + +**denied vs permanentlyDenied** + +- Android:**`status` 永遠不會回 `permanentlyDenied`**(`permission_handler_android` 14.1.0 起的刻意行為)。README:「On Android, only the result of `request()` can be `permanentlyDenied`; `status` reports `denied` instead.」實作 dartdoc 補充:OS 無法區分「從未請求」「使用者在設定裡重設為每次詢問」「永久拒絕」,所以一律回 denied;只有 `request()` 的結果能回 `permanentlyDenied`,而且真為永久拒絕時**不會彈對話框**、直接回傳。來源:`.../permission_handler/README.md`、`https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java` +- iOS:README 只對 Android 做了「status 不回 permanentlyDenied」的聲明 → **反推** iOS 的 `status` 可以回 `permanentlyDenied`(未白紙黑字寫出,標「推測」)。iOS 的實務事實:使用者拒絕後再 `request()` 不再彈,只能 `openAppSettings()` 導去設定。 +- 不彈對話框的權限(README 原文):`Notification`、`Bluetooth`。會**直接開對應設定頁**的:`manageExternalStorage`、`systemAlertWindow`、`requestInstallPackages`、`accessNotificationPolicy`。來源:`.../permission_handler/README.md` + +**FMP 相關的 permission 對應(Android 實作)** + +- `Permission.audio` → `Manifest.permission.READ_MEDIA_AUDIO`。來源:`https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionUtils.java` +- `Permission.notification` → `Manifest.permission.POST_NOTIFICATIONS`(`checkPermissionStatus` 走 `NotificationManagerCompat.areNotificationsEnabled()`;Android 13+ 實際查 `POST_NOTIFICATIONS`)。來源:`PermissionUtils.java`、`PermissionManager.java` +- `Permission.manageExternalStorage` → `MANAGE_EXTERNAL_STORAGE`;API 30+ 時 `request()` 會開 `Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION` 設定頁,狀態查 `Environment.isExternalStorageManager()`;API 30 以下回 `RESTRICTED`。來源:`PermissionManager.java` +- `Permission.storage` → `READ_EXTERNAL_STORAGE` / `WRITE_EXTERNAL_STORAGE`;README 說明這兩個在 Android 10(API 29)起 deprecated、**Android 13(API 33)起完全移除**,媒體存取要改用 `Permission.photos` / `videos` / `audio`。來源:`.../permission_handler/README.md` + +--- + +### B2. Android 13+ `POST_NOTIFICATIONS` + +- Android 13(API 33)新增的 runtime 權限,用於「non-exempt (including Foreground Services (FGS)) notifications」。Manifest:``;執行期用 `ActivityResultContracts.RequestPermission()`。來源:`https://developer.android.com/develop/ui/views/notifications/notification-permission` +- 未取得時**靜默封鎖**:新安裝預設通知關閉;使用者按「不要允許」後「all notification channels are blocked, except for a few specific roles」。若 app target 12L 或更低,使用者按一次「不要允許」就不再被問,直到重裝或 app 升到 target 13+。來源:同上 +- 檢查現況用 `NotificationManager.areNotificationsEnabled()`。來源:同上 +- **豁免(原文)**:「Notifications related to media sessions are exempt from this behavior change.」→ **media session 的通知不需要 POST_NOTIFICATIONS**。來源:同上(Exemptions 段) +- **Foreground service 通知不豁免**:沒權限時使用者只在 Task Manager 看得到 FGS 通知,通知抽屜看不到。原文:「if the user denies the notification permission, they still see notices related to foreground services in the Task Manager but don't see them in the notification drawer.」來源:同上 +- 另一項豁免是自行管理通話的 app(`MANAGE_OWN_CALLS` + `ConnectionService` + `registerPhoneAccount()`)。來源:同上 +- 對 FMP 的意義:**播放中的媒體通知**(Media3 / media session)豁免;但**下載進度/完成通知**屬 FGS 或一般通知,Android 13+ 要 `POST_NOTIFICATIONS`。`background_downloader` 也是這樣要求(見 A1)。 + +--- + +### B3. Android `READ_MEDIA_AUDIO`(13+)/`READ_EXTERNAL_STORAGE`(舊) + +- 讀取**其他 app 建立的**音訊檔,Android 13+ 宣告 `READ_MEDIA_AUDIO`;Android 9(API 28)以下要 `READ_EXTERNAL_STORAGE`(讀)與 `WRITE_EXTERNAL_STORAGE`(寫)。來源:`https://developer.android.com/training/data-storage/shared/media` +- Android 10(API 29)走舊路徑(`File` API 直接路徑)需要 `requestLegacyExternalStorage="true"` + `READ_EXTERNAL_STORAGE`。來源:同上 +- Android 11(API 30):若 app 有 `READ_EXTERNAL_STORAGE`,**可以用裸檔案路徑讀媒體檔**(File API / `fopen()`)。原文:「Running on Android 11 — 1. request the `READ_EXTERNAL_STORAGE` permission. 2. Access the files using direct file paths.」來源:`https://developer.android.com/training/data-storage/use-cases` +- 但 Android 13 起 `READ_EXTERNAL_STORAGE` 被移除/停用(見 B1 的 permission_handler FAQ)。→ 推測:Android 13+ 讀**其他 app 的**音訊檔要靠 `READ_MEDIA_AUDIO`;`READ_MEDIA_AUDIO` 是否同樣允許裸路徑讀取,官方頁面沒有像 Android 11 段落那樣白紙黑字說明(**查不到**明確聲明)。 +- 讀寫**自己建立的**媒體檔,Android 10+ 不需任何儲存權限。來源:`https://developer.android.com/training/data-storage/shared/media` +- 寫入 MediaStore:`ContentResolver.insert()` + `MediaStore.Audio.Media`,長寫入用 `IS_PENDING=1`→`0`;建立/更新時**不要**用 `DATA` 欄位,用 `DISPLAY_NAME` 與 `RELATIVE_PATH`。來源:同上 +- Android 14 部分授權:`READ_MEDIA_VISUAL_USER_SELECTED` **只管 images / videos**。原文:「Android 14 introduces Selected Photos Access, which allows users to grant apps access to specific images and videos in their library」。整頁**完全沒有提到 audio**,manifest 與 runtime 範例只搭 `READ_MEDIA_IMAGES` / `READ_MEDIA_VIDEO`。→ **音訊沒有對應的部分授權**,仍是全有全無。來源:`https://developer.android.com/about/versions/14/changes/partial-photo-video-access` +- Permission group 對應:`Permission.audio` → `READ_MEDIA_AUDIO`(見 B1)。 + +--- + +### B4. Android 11+ scoped storage 與 `MANAGE_EXTERNAL_STORAGE` + +**`MANAGE_EXTERNAL_STORAGE` 授予什麼(原文)** + +- 「Read and write access to all files within shared storage.」「Access to the contents of the `MediaStore.Files` table.」「Access to the root directory of both the USB on-the-go (OTG) drive and the SD card.」「Write access to all internal storage directories except `/Android/data/`, `/sdcard/Android`, and most subdirectories of `/sdcard/Android`. **This write access includes direct file path access.**」 +- 仍**不能**存取其他 app 的 app-specific 目錄(`Android/data/`)。來源:`https://developer.android.com/training/data-storage/manage-all-files` + +**怎麼請求與檢查** + +- Manifest:``。 +- 導向設定頁:官方 manage-all-files 頁寫的是 `Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)`(列出所有 app)。 +- **per-app 版本**:`Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION`,**API level 30 加入**,constant value `android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION`,**Intent 的 data URI 必須是 `package:`**,原文:「The Intent's data URI MUST specify the application package name whose ability of managing external storage you want to control.」啟動該 activity 需要 `MANAGE_EXTERNAL_STORAGE` 權限。來源:`https://developer.android.com/reference/android/provider/Settings#ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION` +- 檢查:`Environment.isExternalStorageManager()`。來源:`https://developer.android.com/training/data-storage/manage-all-files` +- 測試用:`adb shell appops set --uid PACKAGE_NAME MANAGE_EXTERNAL_STORAGE allow`。來源:同上 + +**Google Play 政策(受限權限)** + +- 適用範圍:target Android 11(API 30)+ 且宣告 `MANAGE_EXTERNAL_STORAGE` 的 app(`READ_EXTERNAL_STORAGE` 不受此限)。需在 Play Console 填 Permissions Declaration Form 並**通過審核**才可發佈。 +- 許可用途:file management、backup and restore、anti-virus、document management、on-device file search、disk/folder encryption、device migration。 +- **不許可**的用途明確包含:「Media files access」(改用 MediaStore API)與「Any File selection activity where the user manually selects individual files」(改用 Storage Access Framework)。 +- 強制力原文:「Apps that fail to meet policy requirements or do not submit a Permissions Declaration Form **may be removed from Google Play**.」未申報/欺騙性使用「may result in a suspension of your app and/or termination of your developer account」。來源:`https://support.google.com/googleplay/android-developer/answer/10467955` +- **對 FMP 的實際影響**:FMP 依 ADR 0004 決定不上架任何應用商店(只從 GitHub Releases 散佈),所以這條 Play 政策對它**沒有實際拘束力**;受限權限的「許可用途」清單也就不構成阻礙。政策風險只在「哪天要上架」時才成立。來源:`C:\Users\Roxy\orca\FMP\docs\adr\0004-android-storage-without-mediastore.md`(該 ADR 已引同一政策頁並做了相同判斷) + +--- + +### B5. SAF(Storage Access Framework) + +**機制與限制** + +- `ACTION_OPEN_DOCUMENT_TREE`(Android 5.0 / API 21 起)讓使用者選一個目錄,授權涵蓋該目錄下所有檔案與子目錄,但**不含**該目錄外的其他 app 檔案。來源:`https://developer.android.com/training/data-storage/shared/documents-files` +- Android 11(API 30)起**不能**要求:內部儲存根目錄、可靠 SD 卡根目錄、`Download` 目錄、`Android/data/` 與 `Android/obb/` 及其子目錄。來源:同上 +- 授權時效:一般 URI permission **只到裝置重啟為止**;`contentResolver.takePersistableUriPermission(uri, FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION)` 可跨重啟。原文警語:「Even after calling `takePersistableUriPermission()`, your app doesn't retain access to the URI if the associated document is moved or deleted.」來源:同上 +- 所有 I/O 走 `ContentResolver`(`openFileDescriptor` / `openInputStream`)與 `DocumentsContract.deleteDocument`。來源:同上 +- 官方頁面**沒有**明寫「document URI 不能轉成檔案路徑」這句話(該頁通篇以 URI 操作,未下此結論)—— 這是**查不到的原文**,見下一點的替代證據。 + +**關鍵問題:SAF 目錄下能不能用 `dart:io` 裸路徑寫檔?** + +- 答案:**不能**(在 scoped storage 生效的 Android 10+/11+ 上)。 +- 佐證一(官方語意的反面):「`MANAGE_EXTERNAL_STORAGE` grants … Write access to all internal storage directories … **This write access includes direct file path access.**」(`https://developer.android.com/training/data-storage/manage-all-files`)→ 反面即:**沒有**這個權限就沒有 shared storage 的直接路徑寫入權。 +- 佐證二(官方對「讀」的說明只給到 Android 11 的 `READ_EXTERNAL_STORAGE`,且未涵蓋寫入):`https://developer.android.com/training/data-storage/use-cases`。 +- 佐證三(套件作者的第一手陳述):`saf` 套件 README 首行即以粗體寫「**Scoped storage broke `File('/storage/emulated/0/…')`. `saf` is the fix.**」,並說明 1.x 的 path-based API 已改名 `LegacySaf`、將於 3.0.0 移除,新 API 是 URI-based「store URIs, not paths」。來源:`https://github.com/jvoltci/saf/blob/master/README.md` +- 佐證四(外掛實作證據):`file_picker` 的 Android 端把 SAF tree URI **用字串組出**路徑(見下),但這條路徑在 Android 11+ 上無寫入權;`shared_storage` 的官方文件直言 `getRealPathFromUri`(content URI → 真路徑)**在 Android 10+(API 29+)已不再支援**。來源:`https://github.com/vicajilau/flutter_file_picker`(`FileUtils.kt`)、`https://alexrintt.github.io/shared-storage/Usage/Storage%20Access%20Framework/` +- 推測(未實測):拿 SAF 授權後再用 `File(path).writeAsBytes()` 寫該目錄,在 Android 11+ 會失敗(`FileSystemException` / `EACCES`);要寫入必須走 `ContentResolver` 或 `MANAGE_EXTERNAL_STORAGE`。 + +**Dart 側相關套件** + +- **`saf`** — 最新 **2.1.2**,發佈 **2026-08-25T09:32:29Z**;points **160/160**、likes **71**、30 天下載 **2,961**;**Android only**(Dart ≥3.0、Flutter ≥3.10、minSdk 21)。能力:`pickDirectory()`、`persistedPermissions()`、`walk()`、`readFileBytes` / `writeFileBytes` / `readFileStream` / `writeFileStream`、`copyTo` / `moveTo`、`copyToLocalFile`(把 SAF 檔案複製到 app cache 拿真路徑)、`openFileDescriptor` / `withFileDescriptor`(給 `/proc/self/fd/`)、`thumbnail()`。Media picking 明言 out of scope。1.x path-based API 為 `LegacySaf`(deprecated,3.0.0 移除)。來源:`https://pub.dev/api/packages/saf`、`https://pub.dev/api/packages/saf/score`、`https://github.com/jvoltci/saf/blob/master/README.md` +- **`shared_storage`** — 最新 **0.8.1**,發佈 **2024-02-16T07:37:20Z**,pub.dev 標示 **discontinued(已停止維護)**;points 160/160、likes **61**、30 天下載 2,556;**Android only**。提供 SAF / MediaStore / Environment API 的封裝。來源:`https://pub.dev/api/packages/shared_storage`、`https://pub.dev/packages/shared_storage` +- **`file_picker`** — 最新 **13.1.0**,發佈 **2026-09-15T11:53:57Z**;points 160/160、likes **4,947**、30 天下載 **4,074,590**;平台 Android / iOS / Linux / macOS / Windows / Web。`getDirectoryPath()` 除 web 外全平台可用;`pickFileAndDirectoryPaths()` **只有 macOS**;`clearTemporaryFiles()` 只有 Android/iOS;並有 `AndroidSAFHandle`(`content://` URI + accessMode + `releaseGrant()`)。來源:`https://pub.dev/api/packages/file_picker`、`https://pub.dev/packages/file_picker` +- **`media_store_plus`** — 最新 **0.1.3**,發佈 **2024-09-22**(約 2 年未更新);points 160/160、likes 91、30 天下載 24,488;用 MediaStore API 讀寫、可把 content URI 轉真路徑。來源:`https://pub.dev/api/packages/media_store_plus` + +**`file_picker.getDirectoryPath()` 在 Android 到底回傳什麼** + +- Dart 端送 method `dir`(`file_picker_android.dart`),Android 端在 `FileUtils.kt` 處理: + - 開 `Intent(ACTION_OPEN_DOCUMENT_TREE)`(`type == "dir"` 分支)。 + - 取得結果後先 `takePersistableUriPermission`(當 SAF options 的 `grant == lifetime` 且 `autoPersist`)。 + - **若沒有傳 `androidOptions`(SAF options)**:用 `DocumentsContract.buildDocumentUriUsingTree` + `getFullPathFromTreeUri()` 把 tree URI **轉成檔案系統路徑字串**回傳。`getFullPathFromTreeUri` 的作法是把 tree document id 用 `:` 切開,`primary` 換成 `Environment.getExternalStorageDirectory()`,其他 volume 換成 `/storage//`,再接上 document path。 + - 轉不出來時回錯誤 `unknown_path`,Dart 端的訊息是:「Could not resolve directory path. Maybe it's a protected one or unsupported (such as Downloads folder). Make sure that you are on SDK 21 or above.」 + - **若有傳 `androidOptions`**:直接回傳 `content://` URI 字串(`data.data!!.toString()`),不轉路徑。 +- 來源:`https://github.com/vicajilau/flutter_file_picker/blob/main/packages/file_picker_android/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt`、`.../lib/src/file_picker_android.dart` +- 另:`file_picker_android` README 明言 `initialDirectory` 對 `pickFile` / `pickFiles` / `pickFileAndDirectoryPaths` / `getDirectoryPath` **在 Android 上無效**(原生只開 `ACTION_OPEN_DOCUMENT`、`ACTION_OPEN_DOCUMENT_TREE`、`ACTION_GET_CONTENT`,都不帶起始位置)。來源:`https://github.com/vicajilau/flutter_file_picker/blob/main/packages/file_picker_android/README.md` +- 結論(FMP 視角):`getDirectoryPath()` 在 Android 拿到的是**組出來的路徑字串**,不是有效授權的裸路徑;Downloads 等目錄直接失敗。 + +--- + +## 與 FMP 決策相關的關鍵事實 + +### 硬限制(平台不支援或政策不允許) + +1. **`flutter_downloader` 不支援桌面**(只有 Android/iOS,pubspec 與 README 皆然)→ FMP(Android + Windows)若用它得為 Windows 另寫一套。 +2. **`background_downloader` 在桌面沒有真背景**:純 Dart isolate,app 一關下載即停、沒有系統排程、**不產生任何通知**、記錄只到 app lifecycle 為止(`doc/ARCHITECTURE.md`、`doc/notifications.md`)。→ 「Windows 關掉 app 仍下載完」用現成 Flutter 套件做不到。 +3. **`background_downloader` 的 SAF/URI 下載不能暫停、不能續傳**(`doc/URI.md`)。→ 「直接下載進使用者自選資料夾」與「可暫停續傳」二選一。 +4. **SAF 目錄不能用 `dart:io` 裸路徑寫檔**(scoped storage;`MANAGE_EXTERNAL_STORAGE` 是唯一能拿「direct file path access」的路)。→ 想用裸路徑寫入 shared storage,Android 11+ 只有 `MANAGE_EXTERNAL_STORAGE` 一條路(或改走 MediaStore / SAF 的 URI I/O)。 +5. **音訊沒有部分授權**:`READ_MEDIA_VISUAL_USER_SELECTED` 只管 images/videos,Android 14 文檔完全不含 audio。→ 讀使用者音樂庫是全有全無的 `READ_MEDIA_AUDIO`。 +6. **`MANAGE_EXTERNAL_STORAGE` 是 Play 受限權限**,「Media files access」與「使用者手動選單一檔案」都列在不許可用途,不符資格未申報者「may be removed from Google Play」。**FMP 不上架任何商店(ADR 0004),此政策對它沒有實際拘束**;但它同時鎖死了「未來上架」這條路。 +7. **`POST_NOTIFICATIONS` 不豁免 foreground service 通知**;只有 media session 通知豁免。→ Android 13+ 的下載/FGS 通知必須要這個權限;播放中的媒體通知不用。 +8. **`permission_handler` 沒有 macOS / Linux 實作**;**Windows 實作是 no-op**(一律回 granted、`openAppSettings()` 回 false)。→ 在 Windows 上它不解決任何權限問題(不會彈窗、也不會壞);macOS/Linux 上不能用。 +9. **Android WorkManager 9 分鐘上限、expedited 2 分鐘**(`background_downloader`);要長下載需 `allowPause`(跨週期續傳)或 Android 14+ UIDT(需 `RUN_USER_INITIATED_JOBS` + 通知)。 + +### 可選取捨(沒有單一硬答案) + +- **下載落地位置**:(a) app 私有目錄(`BaseDirectory.*`,零權限、可暫停續傳、但不給使用者看,需事後 `moveToSharedStorage`);(b) `MANAGE_EXTERNAL_STORAGE` + 裸路徑(可暫停續傳、使用者自選資料夾,但 Play 受限——不上架則可);(c) SAF URI(`UriDownloadTask` / `saf`,Play 友善,但不能暫停續傳,且寫檔要走 content URI)。 +- **引擎**:`background_downloader`(跨平台 API 一致、含進度 notifier/通知/暫停續傳/WorkManager+UIDT/桌面 isolate)vs 自己用 `dio`(控制權最大,但續傳、進度持久化、前景服務、並行上限全要自己寫)。 +- **目錄選擇器三條路**:`file_picker.getDirectoryPath()`(Android 上等於先拿 SAF 授權再換算路徑字串,受保護目錄會失敗;桌面回真路徑,可用)/`saf` 的 `pickDirectory()`(拿 URI,Android-only,是最「正確」的 SAF 用法)/`background_downloader.uri.pickDirectory()`(拿 URI,跨平台,但桌面沒有內建 picker,官方建議桌面另用 `file_picker`)。ADR 0004 目前用的是第一條(`FilePicker.getDirectoryPath()`)加上 `MANAGE_EXTERNAL_STORAGE` 讓那條路徑真的可寫。 +- **通知策略**:Android 13+ 若要下載進度通知就得請求 `POST_NOTIFICATIONS`(且 `background_downloader` 的 UIDT 任務**強制**要有通知);不請求就是下載無聲進行。 +- **桌面下載的期待管理**:桌面(Windows)本質上只能「app 開著才下載」。要嘛接受,要嘛自己實作 OS 層服務(Flutter 生態無現成套件,**查不到**可用方案)。 + +### 查不到 / 未確認 + +- `READ_MEDIA_AUDIO` 是否也允許裸路徑讀取音訊檔(官方頁面只對 Android 11 的 `READ_EXTERNAL_STORAGE` 明說過)。 +- `permission_handler` 在 macOS / Linux 無實作時的具體失敗方式(無文檔,推測 `MissingPluginException`)。 +- `permission_handler` 的 iOS `status` 是否會回 `permanentlyDenied`(README 只明文講了 Android 的相反行為)。 +- 「SAF document URI 不能當檔案路徑」在 Android 官方文檔中的**直接原文**(僅能從 `MANAGE_EXTERNAL_STORAGE` 的 `direct file path access` 反面、以及 `saf` / `shared_storage` 的套件方陳述佐證)。 +- Windows 上「app 關閉後續傳下載」的可行做法(未找到 Flutter 套件;未查證)。 + +--- + +# 第二部:內嵌標籤、HTTP 續傳、平台下載位置 + +## A. Dart 內嵌音檔標籤(寫入,非僅讀取) + +### A.1 FMP 現況(讀 repo 得到的前提) + +- 舊版**只寫 sidecar JSON,不寫內嵌 tag**。sidecar 檔名契約在 + `lib/core/constants/download_filenames.dart`:`cover.jpg` / `avatar.jpg` / `metadata.json`, + 多頁時為 `metadata_P{NN}.json`(`metadataCandidatesForAudio()` 以 `^P(\d+)$` 正則比對音檔名)。 +- 舊版**檔名一律寫 `.m4a`**,與實際容器無關: + `lib/services/download/download_path_maintenance_service.dart` 內 + `_audioExtensions = ['.m4a', '.mp3', '.aac', '.opus']`、`_ownedAudioExtensions = ['.m4a']`, + 註解明寫「`DownloadPathUtils.computeDownloadPath` 只寫 `.m4a`」。 + 路徑佈局(`download_path_utils.dart`):`{baseDir}/{playlistName}/{sourceId}_{parentTitle}/P{n}.m4a` + 或單頁 `/audio.m4a`。 +- 來源實際可能拿到的容器與編碼(`lib/data/sources/base_source.dart`,`AudioStreamResult` 的 + `container` ∈ {`mp4`, `webm`, `m4a`}、`codec` ∈ {`aac`, `opus`};`formatPriority = [opus, aac]`)。 + `youtube_source.dart` 由 mimeType 判 `webm`。`playback_media.dart` 註解提到最後一節路徑可區分 + `.m4s` / `.m3u8` / `.flac` 三種來源。 + +→ 新設計要「寫內嵌 tag + 副檔名照實際格式(可能 m4a / opus / webm / flac)」, +這正是下面套件選型的約束。 + +### A.2 Dart 套件盤點(版本與日期取自 pub.dev) + +| 套件 | 最新版 | pub.dev 最後發佈 | 平台 | 底層 | 可否寫入 | +|---|---|---|---|---|---| +| `audiotags` | **1.4.5** | **17 個月前**(≈2025-04) | Android / iOS / Linux / macOS / Windows | Rust `lofty`(flutter_rust_bridge) | 可寫 | +| `metadata_god` | **1.1.0** | **13 個月前**(≈2025-08) | Android / iOS / Linux / macOS / Windows | Rust | 可寫(格式少) | +| `flutter_taglib` | **1.5.2** | **52 天前**(≈2026-08) | Android / iOS / Linux / macOS / Windows | TagLib(Dart FFI + Native Assets) | 可寫(格式最廣) | +| `audio_metadata_reader` | **1.8.0** | versions 頁 **18 天前** / 套件頁「5 天前」(≈2026-09) | Android / iOS / Linux / macOS / Windows | **純 Dart** | 可寫(寫入格式受限) | + +來源: +、、 +、、 +、 + +**逐套件細節** + +- `audiotags` 1.4.5 + - verified publisher `erikastaroza.com`,MIT,30 likes / 120 pub points,全五平台。 + - 透過 Rust `lofty` 寫入(`AudioTags.write(path, tag)`),**整檔覆寫語意**;`duration` 為唯讀欄位。 + - lofty 官方支援格式表():AAC (ADTS)、APE、AIFF、FLAC、 + MP3、MP4、MPC、Opus、Ogg Vorbis、Speex、WAV、WavPack。 + → **不含 Matroska / WebM**。 + - 來源:、 + +- `metadata_god` 1.1.0 + - verified publisher `krtirtho.dev`,MIT,全五平台;需要 `rustup`;Android 需 + `READ/WRITE_EXTERNAL_STORAGE`(新版 Android 需 `MANAGE_EXTERNAL_STORAGE`)。 + - 支援格式僅:mp3 → ID3v2.4、m4a/mp4 → MPEG-4 audio metadata、flac → Vorbis comment。 + → **不支援 opus / webm / aac**。 + - 來源:(context7 的 `resolve-library-id` 對 + `metadata_god` 無命中,回傳的是 Node.js 的 `music-metadata`,故直接取 pub.dev 頁面。) + +- `flutter_taglib` 1.5.2 + - **unverified uploader**,只有 2 likes / 150 pub points(小眾)。 + - 包裝 TagLib:wrapper Apache-2.0,TagLib 本身 LGPL / MPL。 + - README 列 MP3 / FLAC / M4A / WAV / OGG「及 TagLib 支援的其他格式」。 + - TagLib 官方()宣稱可讀寫 ID3v1/ID3v2、Vorbis comment 等,格式涵蓋 + MP3、MP4、AAC、Ogg、Opus、FLAC、Speex、APE、MPC、WavPack、WAV、AIFF、TrueAudio、 + **Matroska、WebM**、ASF、WMA、DSF、DFF 及 tracker 格式。TagLib **2.3.1 發佈於 2026-07-20** + (含 Matroska 相關修正)。 + - → **這是目前唯一在文件上涵蓋 WebM / Matroska / Opus 寫入的 Dart 選項**。 + - **推測**:fluter_taglib 實際能不能寫 WebM/Opus,取決於它 bundle 的 TagLib 版本與它自己有沒有 + 把對應 API 暴露出來。「bundle 的是哪個 TagLib 版本」**查不到**(repo README 取不到內容), + 故這條只能算推測,動工前必須實際驗證。 + - 來源:、 + +- `audio_metadata_reader` 1.8.0 + - 純 Dart(無 native 依賴),全五平台。 + - **可寫**:MP3 / MP4 / FLAC / WAV / APE。 + - **唯讀**:OGG / Opus / WebM / Matroska / AIFF / MOV;**AAC 不支援**。 + - 寫入為**原子寫入**(先寫 temp 再 rename)。 + - 來源: + +- `taglib`(純 Dart 套件名)→ ** 回 HTTP 404,不存在**。 + 只有 `flutter_taglib`。(這是查證結果,不是障礙。) + +### A.3 以 FFmpeg 重新封裝/寫 tag + +- **FFmpegKit 已退役**: + - `ffmpeg_kit_flutter` 最新版 **6.0.3**(另有 `6.0.3-LTS`),FFmpeg 6.0,**僅 Android / iOS / macOS**。 + - Arthenica 於 **2025-01-06** 公告退役,**2025-04-01** 從 Maven Central / CocoaPods / npm + 移除 native binaries;pub.dev 標為 discontinued / unmaintained。 + - 官方 GitHub README(2026-07 仍有更新)明說 FFmpegKit 已正式退役,後續是原作者以 + **source-only** 形式繼續的 `FFmpegKitNext`。 + - 來源:、 + +- **社群 fork**:`ffmpeg_kit_flutter_new` **4.6.2**,**54 天前**發佈,verified publisher + `antonkarpenko.com`,203 likes。內含 **FFmpeg 8.1.2**,支援 Android API 24+ / iOS 14.0+ / + macOS 10.15+ / Windows 10+ x86_64 / Linux x86_64。共八種變體; + **Full 版為 GPL**,GPL codec(x264 / x265 / xvidcore / vid.stab)只出現在 `-gpl` 變體。 + 另有較新的 `ffmpeg_kit_extended_flutter`(FFmpegKit 9.0.1 API、改用 FFI、全五平台)。 + - 來源: + +- → 用 FFmpeg 寫 tag / remux 是「最重但最一致」的路線:能吃所有容器,代價是**套件體積、 + GPL 授權傳染、平台限制**,以及多一層 native 依賴。 + +### A.4 A 段小結(決策面) + +- **B 站 DASH 音訊是 `.m4s`(fragmented MP4 / AAC)** → MP4 writer 可行; + `audiotags`(lofty)、`metadata_god`、`audio_metadata_reader` 都可寫。 +- **NetEase 取 flac**(`netease_source.dart` 以 `encodeType: 'flac'` 請求)→ FLAC writer 可行, + 上述四套件都支援。 +- **YouTube 可能拿到 Opus / WebM** → **只有 TagLib 系(`flutter_taglib`)在文件上涵蓋**; + lofty 明確不支援 Matroska,`audio_metadata_reader` 對 WebM/Opus 標唯讀,`metadata_god` 不支援。 +- 可行路線(三選一,皆為設計選項而非事實): + 1. 一律用 `flutter_taglib`(單一套件通吃),風險是套件小眾(2 likes / 150 points、unverified) + 且 WebM 寫入待實證。 + 2. 混合:m4a / flac 用 `audio_metadata_reader`(純 Dart、活躍、原子寫入),WebM/Opus 另尋或 + 改用 FFmpeg。 + 3. 一律走 FFmpeg remux / 寫 tag(最一致,但最重且有 GPL 與體積成本)。 +- 寫 tag 是**改寫既有檔案**,必須原子寫入(temp + rename)以免下載完成的檔案損毀; + `audio_metadata_reader` 已內建,其他套件需自行確認。 + +--- + +## B. HTTP Range / 續傳 + +### B.1 標準語意(RFC 9110 §14;RFC 9110 已取代 RFC 7233) + +- **RFC 9110**(HTTP Semantics, STD 97, 2022-06)**obsolete 了 RFC 7233**。 + Range 在 §14.2、`Accept-Ranges` §14.3、`Content-Range` §14.4、`multipart/byteranges` §14.6, + `If-Range` 在 §13.1.5。 + 來源:、 +- **Range 是選用功能**:server **可以忽略 Range**,直接回 **200** 與完整資源(等同 + `Accept-Ranges: none`)。客戶端不能假設一定拿得到 206。 + 來源: +- **206 Partial Content**:接受 Range 時回 206,帶 `Content-Range: bytes start-end/total`。 + 注意 206 的 `Content-Length` 是**該段長度**,不是資源總長。 + 來源: +- 單一 range → 直接 body + `Content-Range`;**多重 range → `multipart/byteranges`**。 + 來源: +- **416 Range Not Satisfiable**:range 越界或不合法時回 416。 + 來源: +- **位元組單位是 0-indexed、含頭含尾**(`bytes=0-499` 是前 500 bytes)。 + 續傳的標準寫法是 `Range: bytes={已下載位元組數}-`。 + 來源: +- **`If-Range`(續傳正確性的關鍵)**: + - 讓 Range 請求變成**條件式**。validator 相符 → 回 **206** 部分內容; + **不相符 → 忽略 Range,回 200 完整資源**。 + - validator 只接受**強 ETag**(弱 ETag 的 `W/` 前綴**不可**用於 If-Range)或 HTTP-date。 + - `If-Range` **必須與 `Range` 同時出現**,否則 server 會忽略它。 + - 原文(RFC 7233 §3.2,語意被 RFC 9110 §13.1.5 沿用): + "If the validator given in the If-Range header field matches the current validator ... + the server SHOULD process the Range header field as requested. If the validator does not + match, the server MUST ignore the Range header field." + - 來源:、 + +- **ETag**:標識資源的**特定版本**;資源內容改變**必須**產生新 ETag。 + 強 ETag 才讓 Range 請求可被 cache / 可安全續傳。 + 來源: +- **`Last-Modified`** 精度較低(秒級),是拿不到 ETag 時的 fallback。 + 來源: + +### B.2 B 站 CDN(`upos-*.bilivideo.com`)公開已知行為 + +- 播放位址由 playurl API 取得,**DASH 音視分離**,音訊是獨立的 `.m4s` 檔。 +- 社群文()明說: + 1. **連結有時效**(`deadline`/簽名參數); + 2. **不帶 `Referer` 直接訪問該連結會 403**; + 3. 慣用下載器是 **aria2c**(可多連線、可續傳)。 +- CDN 有多個 host(`upos-sz-mirroraliov` / `upos-sz-mirrorcos` / `upos-sz-mirrorhw` / + `upos-sz-estgcos` 等 `.bilivideo.com`);yt-dlp issue #14498 記錄了「手動換 CDN 網域」 + 的做法(**官方無此選項**),並指出預設 CDN 可能被限速。 + 來源: +- **推測**:既然 aria2c / IDM / yt-dlp 這類工具能對 B 站多連線與續傳,CDN 應支援 + byte range(206)。**我沒有打 API 實測**,故此條標推測,動工前必須驗證。 +- **查不到**:upos 在換 host 後是否回**相同 ETag** 的官方說明;以及它對 `If-Range` 的支援程度。 + +### B.3 YouTube CDN(`googlevideo.com`)公開已知行為 + +- YouTube 走 **DASH**;MPEG-DASH **on-demand profile** + (`urn:mpeg:dash:profile:isoff-on-demand:2011`)用 `SegmentBase@indexRange`, + **播放與 seek 本身就是用 HTTP byte-range 抓 MP4 segment**(回 206)。 + 也就是說 YouTube 的「正規」抓法本來就是 range-based。 + → 由此**推論** googlevideo 支援 Range / 206。**推測**(機制推論,非直接觀測)。 +- YouTube 官方 DASH-over-HTTP 文件同時列 **MP4 與 WebM** 容器。 +- URL 帶 **expire 簽名參數**,過期後失效(常見 403)。yt-dlp issue #7074 記錄了字幕 URL + 在任務中途過期;社群多起 403 回報(如 mpv issue #16563、r/youtubedl 討論)。 + 來源: +- yt-dlp 有 `--continue`(續傳部分下載的檔/fragment,**預設開啟**)與 `--http-chunk-size` + (分塊 HTTP 下載,**預設關閉**)。→ 顯示「分塊/續傳」在 YouTube 是常見且必要的做法。 + 來源: +- **查不到**:googlevideo 明確回 `Accept-Ranges: bytes` 的第一方聲明。故此點只能算推測。 + +### B.4 「每次續傳都重新解析 URL」的風險,與正規做法 + +風險(皆為設計推理): + +1. **簽名 URL 過期** → 403,必須重新解析(B 站與 YouTube 皆然)。 +2. **重解析可能換到不同 host / CDN edge**。不同 edge 對同一物件**未必給相同 ETag** + (**推測**)。此時正確的 `If-Range` 會直接回 200 完整檔 = 強制重來; + 但若**不**帶 `If-Range` 而只發 `Range`,就會出現「舊片段 + 新版本片段」**混拼成損壞檔**。 +3. **內容可能變動**(重解析可能選到不同畫質 / 編碼 / 位元率)→ 續傳拼檔直接壞掉。 +4. 因此「拿到新 URL 就從舊 offset 接著寫」是**不安全**的預設行為。 + +正規做法(RFC 語意下的安全續傳): + +- 第一次回應時**記錄 ETag / Last-Modified 與已下載位元組數**。 +- 續傳請求:`Range: bytes={N}-` **加上** `If-Range: `(同一次請求)。 +- 收到 **206** → **驗證 `Content-Range` 的起點 == N** 才續寫;不符就視為失敗。 +- 收到 **200** → 代表 validator 不符(或 server 不支援 Range):**丟棄暫存檔,從 0 重寫**。 +- **不要跨 CDN host 重用 ETag**(**推測**:不同 host 可能給不同 validator)。 +- 若來源本身是 DASH(B 站、YouTube),另一條路是**分段下載**(每個 segment 獨立 URL、 + 各自簽名),把「續傳」變成「已完成的 segment 不重抓」,比對單一大檔用 Range 更貼合來源模型。 + +--- + +## C. 各平台下載位置與沙盒可見性 + +### C.1 iOS / macOS 沙盒 + +- app 容器內可寫位置(官方 File System Programming Guide): + - `Documents/` — 使用者產生的資料檔。 + - `Library/` — app 資料;**除 `Library/Caches` 外會被 iTunes / iCloud 備份**。 + - `Library/Application Support/` — app 自己的資料檔(**iOS 上會被備份**); + 官方建議放在以 **bundle id 命名的子目錄**下。 + - `Library/Caches/` — **不備份**,且系統在空間不足時**可清除**。 + - `tmp/` — **不備份**,且 app 未執行時系統**可清除**。 + - 來源: +- **讓檔案在「檔案」App 可見**:`UIFileSharingEnabled = YES` **且** + `LSSupportsOpeningDocumentsInPlace = YES`,**兩個都要設**,app 的 `Documents/` 才會出現在 + 「在我的 iPhone 上」。 + - 來源(Apple 官方兩頁抓不到內文,僅回導覽框架;改用社群明述此條件者): + 、 + 、 + 、 +- **macOS 沙盒**(10.7 起):容器在 `NSHomeDirectory()` 內,`Application Support` / `Caches` / + `tmp` 都在容器裡。容器**外**的檔案需要: + - 使用者透過 open / save panel 選取 → entitlement + `com.apple.security.files.user-selected.read-write`(唯讀則 `...read-only`); + - 持久存取要 **security-scoped bookmark**:存 bookmark data,下次 resolve 後 + `startAccessingSecurityScopedResource()` / 用完 `stopAccessingSecurityScopedResource()`。 + - 有實務者指出:bookmark 只在**使用者選了 read/write** 時成功,選 read-only 會失敗 + (社群經驗,非官方文件)。 + - 另有開發者稱 `com.apple.security.files.bookmarks.app-scope` entitlement 已非必需 + (引 Jeff Johnson / FB7405463)。→ **文件與實務不一致,標為有爭議**。 + - 來源:、 + + +**FMP 相關**:Android / Windows 以外的平台若要「使用者看得到下載的音樂」, +iOS 需兩個 Info.plist key + 檔案放 `Documents/`;macOS 需使用者授權或放容器內。 + +### C.2 Linux(XDG) + +- **XDG Base Directory Spec**: + - `$XDG_DATA_HOME`(預設 `~/.local/share`)— 使用者資料。 + - `$XDG_CONFIG_HOME`(預設 `~/.config`)— 設定。 + - `$XDG_STATE_HOME`(預設 `~/.local/state`)— 狀態 / log。 + - `$XDG_CACHE_HOME`(預設 `~/.cache`)— 快取。 + - 來源: +- **使用者音樂目錄**:由 `xdg-user-dirs` 管理,設定檔在 `$XDG_CONFIG_HOME/user-dirs.dirs`, + 變數 `XDG_MUSIC_DIR`(預設 `$HOME/Music`),由 `xdg-user-dirs-update` 寫入; + 查詢用 `xdg-user-dir MUSIC`。 + - 來源: +- 慣例:使用者可見的音樂 → `XDG_MUSIC_DIR` 下自建子目錄;內部狀態 / DB → `XDG_DATA_HOME/`; + 快取 → `XDG_CACHE_HOME/`。 + +### C.3 Windows + +- **資料夾語意**: + - `Documents` — 使用者文件(**Known Folder**,可能被 OneDrive 重導向)。 + - `AppData\Roaming` — **會跟隨網域 / 漫遊 profile 同步**,適合小設定。 + - `AppData\Local` — **不漫遊**、機器專屬,適合快取與大檔。 + - `AppData\LocalLow` — 低完整性(low integrity)行程用。 + - 來源:、 + Microsoft Q&A / superuser 關於 Roaming vs Local 的官方回覆 +- **路徑長度**:Win32 API 歷史上限 **`MAX_PATH` = 260**。Windows 10 1607+ 對**部分**函式 + 移除限制,但 **app 必須 opt-in**:同時設 registry `LongPathsEnabled` **且** app manifest + 宣告 `longPathAware`;且只對有 `W` 版的函式有效。 + - 來源: +- **FMP 相關**:`{playlistName}/{sourceId}_{parentTitle}/P{n}.m4a` 這種**深層巢狀 + 中文長標題** + 佈局,很容易逼近 260;未 opt-in 時寫入會失敗。需縮短路徑或處理長路徑。 + +### C.4 Android + +- **App 專屬目錄**(internal files/cache 與 external app-specific + `Android/data//`):**卸載後一律刪除**;Android 10+ 加密;不需任何儲存權限。 + - 來源: +- **共用儲存**:音訊走 **MediaStore**(`Music/` ↔ `MediaStore.Audio`);Android 10+ + scoped storage 為預設。建立 / 更新媒體用 `DISPLAY_NAME` + `RELATIVE_PATH`(**不要**用 `DATA`); + 下載類可放 `MediaStore.Downloads`(`Download/`)。 + - 來源: +- **FMP 相關**:要「卸載後仍保留」的音樂**必須**寫共用儲存 `Music/`(要處理權限 / MediaStore); + 寫進 app 專屬目錄的使用者音樂會隨卸載消失。 +- `path_provider` **2.1.6**(verified publisher flutter.dev,約 3 個月前): + - Temporary / Application Support / Application Documents / Application Cache → 全五平台。 + - Application Library → **僅 iOS / macOS**。 + - External Storage / External Cache / External Storage Directories → **僅 Android** + (app 專屬外部目錄,卸載即刪)。 + - Downloads → 全五平台。 + - SDK 下限:Android 24+ / iOS 13.0+ / macOS 10.15+ / Windows 10+。 + - 來源:、 + +--- + +## 與 FMP 決策相關的關鍵事實 + +### 硬限制(不可繞,只能接受或改需求) + +1. **WebM / Opus 容器幾乎沒有純 Dart 寫入方案**。lofty(`audiotags` 底層)格式表**不含** + Matroska/WebM;`audio_metadata_reader` 對 WebM/Opus 標唯讀;`metadata_god` 不支援。 + 文件上涵蓋的只有 TagLib 系(`flutter_taglib`)。(A.2) +2. **`flutter_taglib` 是小眾 + unverified**(2 likes / 150 pub points),且它 bundle 的 TagLib + 版本與實際 WebM 寫入能力**查不到**,必須實證。(A.2) +3. **HTTP Range 是選用功能**:server 可忽略並回 200;416 表不合法;206 的 `Content-Length` + 是段長不是總長。(B.1) +4. **`If-Range` 是續傳唯一安全機制**:validator 不符 → 回 200 完整檔,客戶端**必須**丟棄已下載 + 部分。弱 ETag 不可用於 `If-Range`。(B.1、B.4) +5. **B 站與 YouTube 的 URL 都是時效簽名**,過期即 403,**必然**需要重解析;且 B 站連結 + **必須帶 `Referer`**。(B.2、B.3) +6. **Android app 專屬目錄卸載即刪**;要使用者可見保留必須走 MediaStore / 共用儲存。(C.4) +7. **Windows 路徑 260 上限**未 opt-in 時會硬失敗,而 FMP 的巢狀 + 中文標題佈局天然逼近上限。(C.3) +8. **iOS 要讓 `Documents/` 在「檔案」App 可見需兩個 Info.plist key 皆 YES**。(C.1) +9. **FFmpegKit 已退役**,官方 binary 已下架;社群 fork 為 GPL 且有體積成本。(A.3) + +### 可選取捨 + +- **寫 tag 套件**:單一 `flutter_taglib`(廣但小眾)vs 混合(純 Dart 為主 + WebM 另解) + vs 全走 FFmpeg(一致但最重)。三者是設計選擇,取決於「一定要支援 webm/opus 寫入嗎」。(A.4) +- **副檔名政策**:維持現行「一律 `.m4a`」可避開 WebM 寫入問題,但檔名與實際容器不符; + 改成照實際格式則拉高套件需求。(A.4) +- **續傳策略**:對 DASH 來源(B 站 / YouTube),「以 segment 為單位續傳」比「對單一大檔用 + `Range` + `If-Range`」更貼合來源模型;兩者不互斥,可並存。(B.4) +- **下載落地位置**:app 私有(簡單、卸載即消失、無權限)vs 共用儲存 / `Documents` / `Music` + (使用者可見、可保留,但要處理各平台權限與沙盒)。(C.1–C.4) + +### 查不到 / 待實證 + +- B 站 `upos` 是否支援 `If-Range`、以及換 host 後 ETag 是否一致 — **查不到**,**推測**支援 Range。 +- googlevideo 回 `Accept-Ranges: bytes` 的第一方聲明 — **查不到**,僅由 DASH byte-range 機制**推測**。 +- `flutter_taglib` bundle 的 TagLib 版本與 WebM 寫入實效 — **查不到**,需實測。 +- `com.apple.security.files.bookmarks.app-scope` 是否仍必需 — **文件與實務不一致**。 diff --git a/.trellis/tasks/09-28-design-downloads/research/prior-art.md b/.trellis/tasks/09-28-design-downloads/research/prior-art.md new file mode 100644 index 000000000..50fb68909 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/research/prior-art.md @@ -0,0 +1,1137 @@ +# 下載子系統 prior art 調查 + +- **查證日期**:2026-09-28 +- **查證方式**:以 `gh api repos/OWNER/REPO/commits/HEAD --jq .sha` 取得各 repo 當下 HEAD 的 commit SHA,再 `git clone --depth 1` 把該 SHA 的樹抓到本機,**直接讀原始碼與 README**。所有引用都附固定 SHA 的 permalink(`https://github.com/OWNER/REPO/blob//`)。**未執行任何 app、未打任何真實 API**。 +- **引用格式**:`[代號]` 對應下方各產品的 repo 與 SHA。標「**README 宣稱**」的是文件說法,標「**程式碼**」的是我在原始碼看到的事實,兩者分開。查不到的一律寫「查不到」,我的推論一律標「推測」。 + +## 受查產品與固定 SHA + +| 產品 | repo | SHA | 技術棧 | +|---|---|---|---| +| Finamp `[F]` | finamp-app/finamp | `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc` | Flutter + Jellyfin client + `background_downloader` | +| Namida `[N]` | namidaco/namida | `e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5` | Flutter + 自寫 Range/分塊下載器 | +| Spotube `[S]` | KRTirtho/spotube | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | Flutter + Dio 分塊下載 | +| NewPipe `[P]` | TeamNewPipe/NewPipe | `7e5df38aad4b2c035332b3f71aee3064d4fdaae4` | Android 原生 Kotlin(giga 下載引擎) | +| Musify `[M]` | gokadzev/Musify | `5b98d3a3cddd3fdb16ea6cc14d59d667e82cccd2` | Flutter + `youtube_explode_dart` | +| MusicFree `[X]` | maotoumao/MusicFree | `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee` | React Native + JS 插件架構 | + +避開的歧義:`[N]` 的 repo 是 **`namidaco/namida`**,不是任務描述裡寫的「author namida-app」。 + +--- + +## 總覽表 + +| 產品 | 佇列 / 併發 | 背景下載機制 | 續傳 | 儲存位置 | 內嵌 tag | 權限流程 | +|---|---|---|---|---|---|---| +| Finamp `[F]` | 任務佇列在 host(`IsarTaskQueue`),併發上限 `maxConcurrentDownloads`(預設 5),可設定 | `background_downloader` 的 `FileDownloader`,Android 走 WorkManager(該套件自身機制);app 另外呼叫 `resumeFromBackground()` | **套件支援、app 刻意不用**:`storeResumeData` 有實作,但 `pauseAll`/`resumeAll` 是空函式,註釋寫明「We do not currently pause or resume the downloads」 | app-private(`applicationSupport`)為平台預設;另有 internal/external/custom。external/custom 用 `file_picker` 取字串路徑,**沒有持續化 SAF 授權** → 官方文件自承 practically broken | **不寫 tag** | `permission_handler` 唯一一處被**註解掉**;目錄選擇靠 `FilePicker.getDirectoryPath()`,UI 對 iOS/Android 顯示紅色 `customLocationsBuggy` 警告 | +| Namida `[N]` | 兩層:**檔案數** `downloadParallelCount`(預設 4)+ **單檔執行緒數** `downloadThreadsCount`(預設 3),都可設定 | **沒有** WorkManager;下載跑在共用 isolate(`FilesDownloadManager with PortsProvider`);靠 `audio_service` 的前景服務與 battery-optimization 例外維持。**查不到**任何下載專用的 foreground service | **自寫且完整**:以「磁碟上檔案大小」為續傳位移;`Content-Range` 驗證;伺服器不理 Range 時從 0 重來;多執行緒用 `.part` 且「只以整塊成長,所以永遠是合法前綴」;5 次重試、30s 停滯逾時、指數退避 | 使用者可見的 `Namida/Downloads`(`AppDirs.YOUTUBE_DOWNLOADS`,預設 `INTERNAL_STORAGE/Downloads`),可用內建瀏覽器改路徑。**不用 SAF**,改用 `MANAGE_EXTERNAL_STORAGE` | **寫入**(`ffmpeg_controller.dart`):`-metadata k=v` + `-id3v2_version 3 -write_id3v2 1 -c copy`;opus/ogg/flac 先 `-map_metadata -1` 再整套寫回 | Android 11+ 要求 `Permission.manageExternalStorage`(`requestManageStoragePermission`);拒絕 → snackbar 報錯並 `return false`;永久拒絕另外走 `openAppSettings()`;另有 `requestIgnoreBatteryOptimizations()` | +| Spotube `[S]` | **硬編碼 1**:`_startDownloading()` 看到任何 `downloading` 就 return;佇列只存在記憶體(`build()` 回 `[]`),重啟即消失 | **無**(只有播放用的 `FOREGROUND_SERVICE_MEDIA_PLAYBACK`;`BIND_JOB_SERVICE` 屬於 `home_widget` 不是下載) | **無續傳**:分塊下載的暫存目錄在**每次開始前先整個刪掉**、失敗也刪 → 跨嘗試無法接續。Range 只是用來分塊加速,不是續傳 | Android **硬編碼** `/storage/emulated/0/Download/Spotube`;macOS 放 `Caches`;其餘 `getDownloadsDirectory()/Spotube`。路徑存 drift `PreferencesTable.downloadLocation`。用 `file_picker` 取字串路徑,同樣**沒有 SAF 授權** | **寫入**(`metadata_god`):`MetadataGod.writeMetadata`,含 title/artist/album/albumArtist/year/durationMs/fileSize 與封面 `Picture` | `use_get_storage_perms.dart` 請求 `Permission.storage` 或 Android 13+ 的 `Permission.audio`;manifest 有 `requestLegacyExternalStorage="true"` | +| NewPipe `[P]` | **預設 1**:`mPrefQueueLimit` 預設 `true`,開啟時 `getRunningMissionsCount() < 1` 才啟動下一個任務;可在設定關掉。單檔另有 `threadCount`(預設 3)分塊 | **有**:`DownloadManagerService` 是 foreground service(manifest `android:foregroundServiceType="dataSync"`),`updateForegroundState(true)` → `startForeground(...)`,同時 `mLock.acquireWifiAndCpu()` 取 WifiLock + WakeLock | **完整且有量身設計**:`blocks[]` 陣列記每個 block 的位移(-1 = 已完成),每個 mission 一個 metadata 檔(檔名 = timestamp)存在 `pending_downloads/`;`DownloadMissionRecover` + `MissionRecoveryInfo` 處理來源 URL 失效後重新協商;伺服器不允許 Range 時退回單執行緒 | **SAF 為主**:`StoredDirectoryHelper`(`DocumentFile` / tree URI),音訊與視訊各自一個 handle;`NewPipeSettings.useStorageAccessFramework()` 在 API 29+ **強制 true**,只在舊版可由偏好設定控制;非 SAF 模式才是 `Environment.getExternalStorageDirectory()/Music` 之類 | **不寫 tag**:`postprocessing/` 只做容器處理(`M4aNoDash`、`Mp4FromDashMuxer`、`OggFromWebmDemuxer`、`WebMMuxer`、`TtmlConverter`),全樹只有一個 `ffmpeg` 檔名命中(`Mp4FromDashWriter.java`),沒有任何 `-metadata` 寫入 | `PermissionHelper.checkStoragePermissions()`:**若走 SAF 就直接回 true(不需權限)**;否則請求 `READ_EXTERNAL_STORAGE` + `WRITE_EXTERNAL_STORAGE`。另有 `checkPostNotificationsPermission()`(TIRAMISU 起、只問一次) | +| Musify `[M]` | 播放清單下載:**硬編碼 3** 個 worker 的 queue;單曲 `makeSongOffline` 沒有全域佇列或限流 | **無下載專用機制**:manifest 只有 `INTERNET` / `WAKE_LOCK` / `FOREGROUND_SERVICE(MEDIA_PLAYBACK)`(屬 `audio_service` 播放用),沒有下載 foreground service。下載中切到背景是否會繼續 → **查不到保證**(推測只在播放維持前景服務時才存活) | **無續傳**:`streamsClient.get(audioManifest)` 直接 `pipe` 進 `openWrite()`,中斷就 `.delete()` 重來,無 Range | **app-private**:`applicationDirPath = (await getApplicationDocumentsDirectory()).path`,子目錄 `tracks/`、`artworks/`、`stream_buffer/`。**不需任何儲存權限**(manifest 裡沒有),也不給使用者選目錄 | **不寫 tag**:pubspec 無 `metadata_god`/taglib;封面存成 sidecar `artworks/.`;唯一讀 tag 的東西是 `youtube_explode_dart`(讀取端) | **完全沒有權限流程**(app-private 目錄不需要)。manifest 無任何 storage permission | +| MusicFree `[X]` | **可設定 1..10,預設 3**:`maxDownloadCount = clamp(config basic.maxDownload \|\| 3, 1, 10)`;任務佇列在記憶體(jotai atom) | 用 `react-native-fs` 的 `downloadFile({ background: true })`,交給 RNFS 的原生背景下載(iOS/Android 各有實作) | **無續傳**:暫存檔名用 `nanoid()`,重試等於全新下載 | `basePath` = Android `RNFS.ExternalDirectoryPath` / iOS `Documents`;下載到 `/download/music/`,暫存在 `/cache/download/`。路徑可由 `config basic.downloadPath` 覆寫。**不用 SAF** | **下載器不寫 tag**。`native/mp3Util` 雖有 `setMediaTag`,但下載流程沒呼叫它;下載後只把 `localPath` 記進 DB。`mp3Util` 只用於**讀**本地檔案 meta | **`downloadFile` 失敗 → 試著建目標目錄,建不起來就報 `DownloadFailReason.NoWritePermission`**(沒有主動請求權限的流程,靠系統授權結果) | + +--- + +## Finamp `[F]` — finamp-app/finamp @ `0aae9d5e` + +### 1. 佇列與併發 + +**程式碼**:`class IsarTaskQueue implements TaskQueue` 在 +[`lib/services/downloads_service_backend.dart#L230`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service_backend.dart#L230) +實作 `background_downloader` 的 `TaskQueue` 介面。`_advanceQueue()` 的 dartdoc 直接寫「will enqueue finampSettings.maxConcurrentDownloads at once」(同檔 L307),實際守門條件在 L329: + +```dart +while (_activeDownloads.length >= FinampSettingsHelper.finampSettings.maxConcurrentDownloads || + _finampUserHelper.currentUser == null) { + await Future.delayed(const Duration(milliseconds: 500)); +} +``` + +即 **`maxConcurrentDownloads` 是使用者可設定的併發上限**;輪詢間隔 500ms。另外每筆任務間刻意延遲 20ms,註釋說是為了「prevent choking the method channel」(註釋提到 `MemoryTaskQueue`,那是 `background_downloader` 自己的 in-memory 佇列類比)。任務優先序用 `Priority.animation + 50`。 + +**排序**:查詢時 `limit(20)`,一次取一批;排序依據我沒追到明確的欄位(**查不到**),但佇列是先進先出的 `_advanceQueue()` 補位。 + +`DownloadTask` 的組裝把 Isar 記錄翻譯成套件任務,並把 Jellyfin 的授權標頭塞進去(同檔約 L330–350):`taskId: task.isarId.toString()`、`headers: {"Authorization": _finampUserHelper.authorizationHeader}`、`baseDirectory`/`directory`/`filename` 由 `task.path` 拆解。 + +### 2. 背景下載 + +**程式碼**:`background_downloader` 本身在 Android 用 WorkManager(套件層事實,不在本 repo 內,我只在 `lib/main.dart` 的 `_setupDownloadsHelper()` 看到 +[`fileDownloader.configure(globalConfig: (Config.checkAvailableSpace, 1024))`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/main.dart) +與 `await fileDownloader.resumeFromBackground()`、`await downloadsService.startQueues()`)。Finamp 自己**沒有** foreground service。 + +### 3. 續傳 + +這是最值得注意的一點:**套件能力被接上,但 app 主動放棄使用**。 + +- `IsarPersistentStorage`(同檔 L34)**有**實作 `storeResumeData` / `retrieveResumeData` / `removeResumeData` / `storePausedTask` / `retrievePausedTask`。 +- 但 `pauseAll` / `resumeAll` 是**空覆寫**([`#L432`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service_backend.dart#L432)),旁邊的註釋明寫「We do not currently pause or resume the downloads」。 + +**啟動時的對帳**(`initializeQueue()`)反而比續傳更重要:對每個 item 檢查 `item.file?.existsSync()`,存在就標 complete 並 log「Marking download ${item.name} as complete on startup.」;狀態是 `downloading` 但不在 `allTasks(includeTasksWaitingToRetry: true)` 裡的,重新入列並 log「Re-enqueueing download ${item.name} on startup.」。**這是「重啟後靠檔案本身 + 狀態欄位對帳」的樣板**,不是靠 HTTP 續傳。 + +### 4. 儲存位置 + +**程式碼**:`class DownloadLocation`([`lib/models/finamp_models.dart#L1017`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L1017))持有 `id` / `relativePath` / `baseDirectory`。`enum DownloadLocationType`([`#L2605`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L2605))列出全部選項: + +``` +internalDocuments → BaseDirectory.applicationDocuments +internalSupport → BaseDirectory.applicationSupport +external → BaseDirectory.root +custom → BaseDirectory.root +migrated / cache / none +platformDefaultDirectory = (iOS || Android) ? internalSupport : cache +``` + +`DownloadItem.file` 是 `currentPath` 與**相對路徑** `path` 的 join;`updateCurrentPath()` 分別用 `getApplicationDocumentsDirectory()` / `getApplicationSupportDirectory()` / `getApplicationCacheDirectory()` 求解。相對路徑是刻意的設計 —— `DOWNLOADS_PLAN.md` 寫「Relative path handling by default - this will solve the absolute path issue I mentioned earlier」。 + +**外部目錄是壞的,而且官方文件自己承認**:`custom_download_location_form.dart` 用 `FilePicker.getDirectoryPath()` 取回一個**字串路徑**,沒有把 SAF 的 tree URI 權限持續化。`DOWNLOADS_PLAN.md` 的原話是「**Scoped storage support - Finamp's support for external directories is currently practically broken.**」。UI 上對 iOS/Android 直接顯示紅色 `customLocationsBuggy` 警告(`lib/screens/downloads_settings_screen.dart`)。 + +`android/app/src/main/AndroidManifest.xml` 有 `READ/WRITE_EXTERNAL_STORAGE` 與 `android:requestLegacyExternalStorage="true"`,`targetSdkVersion flutter.targetSdkVersion`。 + +### 5. 檔名與目錄結構 + +`_getTrackDownloadPath(DownloadItem)`(同檔 `downloads_service_backend.dart`): + +- **human-readable 模式**:`fileName = _filesystemSafe("${originalFilename ?? "$indexNumber$artist${item.name}"}_${item.id.raw.substring(0, 8)}")`,其中 `indexNumber = "[${item.indexNumber}] "`、`artist = "${item.artists?.first} - "`;路徑段 `pathSegments = [_filesystemSafe(item.albumArtist), _filesystemSafe(item.album)]`,最前面再補一層 `"Finamp"`(除非該 location 最後一段已經是 `finamp`)。 +- **非 human-readable 模式**:`fileName = item.id.raw`,子目錄固定 `FINAMP_BASE_DOWNLOAD_DIRECTORY`([`#L30`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service_backend.dart#L30) = `"songs"`)。 +- 淨化:`_filesystemSafe` 只做 `unsafe?.replaceAll(RegExp(r'[/?<>:*|.\\"]'), "_")`。 +- 副檔名來自 `downloadItem.syncTranscodingProfile?.codec.container ?? mediaSources?.firstOrNull?.container`。 + +**metadata 會進路徑**(artist / albumArtist / album / track index),但**會加 8 碼 id 後綴**避重名 —— 這是可以直接借的折衷。 + +圖片下載另走一條:`fileName = "${Uuid().v4()}.image"`、子目錄 `FINAMP_BASE_IMAGES_DIRECTORY`,完成後才依 `event.mimeType` 把副檔名改成 `.jpg`/`.bmp`/`.png`/`.gif`。 + +### 6. 內嵌 tag + +**程式碼**:**沒有**。全 repo 的 tag 寫入相關符號(`metadata_god`、`taglib`、`writeMetadata`、`-metadata`)我沒找到任何下載路徑上的使用。 + +### 7. 下載 ↔ 音樂庫關聯(最值得學的一段) + +`DownloadItem` 是 Isar model([`finamp_models.dart#L1613`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L1613)),帶真正的**關係鏈**: + +``` +IsarLinks requires; // 這筆下載需要誰先完成 +IsarLinks requiredBy; // 誰需要我 +IsarLinks info; // 我附帶的資訊節點(歌詞等) +IsarLinks infoFor; +String path; // 相對路徑 +@Name("viewId") int? isarViewId; +DownloadLocation? fileDownloadLocation / syncDownloadLocation // computed +``` + +節點型別是階層:**anchor → collection → album/playlist → track → image**,用一個 anchor 節點把整棵樹串起來。`DOWNLOADS_PLAN.md` 說明動機:「it will allow me to actually model relations in the database to make adding and removing downloads more reliable」,並說明舊系統散在五個 Hive DB(`DownloadedItems`、`DownloadedParents`、`DownloadIds`、`DownloadedImages`、`DownloadedImageIds`)。`DownloadIds` 的存在理由文件也寫得很清楚:「a copy of the data stored in `DownloadedItems`, but indexed by the `flutter_downloader` download ID so that we can track the download ID back to the actual song.」—— 這正是舊套件逼出來的冗餘表,換到 `background_downloader` 後被關係模型取代。 + +狀態機 `enum DownloadItemState`([`#L1798`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/models/finamp_models.dart#L1798)): +`notDownloaded, downloading, failed, complete, enqueued, syncFailed, needsRedownload, needsRedownloadComplete`,附 `isFinal` / `isComplete` 便利 getter,以及 `static DownloadItemState fromTaskStatus(TaskStatus status)` 把套件狀態映射回自家狀態。 + +### 8. 刪除 + +`deleteDownload(DownloadItem)`([`#L634`](https://github.com/finamp-app/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/services/downloads_service_backend.dart#L634)): + +1. 取消已入列的套件任務; +2. 刪檔; +3. **只在 `useHumanReadableNames` 為真、且父目錄已空時**才刪父目錄(非 human-readable 模式共用 `songs/`,所以不能刪); +4. `updateItemState(transactionItem, DownloadItemState.notDownloaded)` —— **保留記錄**,只改狀態; +5. 若是 track,順帶刪掉 `DownloadedLyrics`。 + +也就是「**記錄留下、狀態改掉**」而不是「刪 row」。 + +### 9. 權限流程 + +**程式碼**:`permission_handler` 全 repo 唯一一處使用是**被註解掉的**(`lib/services/downloads_service.dart` 約 L441),註釋引 issue #134 說「suggesting this does not make a request and always returns failure」。實務上的「權限」步驟就是 `FilePicker.getDirectoryPath()`;失敗或路徑不可寫的處理**查不到**結構化流程。**結論:Finamp 沒有可用的權限退化(fallback)設計,這點是反例。** + +### README / 文件宣稱(與程式碼分開) + +- **README 宣稱**(`DOWNLOADS_PLAN.md`,屬 repo 內設計文件):換掉 `flutter_downloader` 改用 `background_downloader` 的四個理由 ——「Better looking API」(說 `flutter_downloader` 在 iOS 有下載無法標記完成的 bug)、「Scoped storage support」(自承外部目錄 practically broken)、「Relative path handling by default」、「Better stability」。同時說明 Hive → Isar 的動機是「actually model relations」。 +- 我**驗證過為真**的部分:相對路徑(`DownloadItem.file` 用 `currentPath + path`)、Isar 關係(`IsarLinks`)、`background_downloader` 取代 `flutter_downloader`(pubspec 只有前者)。 +- 我**未能驗證**的部分:`flutter_downloader` 的 iOS bug、`background_downloader` 的穩定性比較 —— 這些是作者的判斷,不是我能從程式碼核實的事實。 + +--- + +## Namida `[N]` — namidaco/namida @ `e8363dbf` + +這是六個產品裡**下載引擎做得最完整**的一個,也是最接近「host 自己管下載」的樣板。 + +### 1. 佇列與併發 + +**兩層獨立的併發控制**: + +**檔案層**:`class YoutubeParallelDownloadsHandler`([`lib/youtube/controller/parallel_downloads_controller.dart#L10`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/youtube/controller/parallel_downloads_controller.dart#L10))持有 `_tasks`(以 `DownloadTaskFilename` 為 key)、`_queue: Queue<_ParallelDownloadTask>`、`_runningCount`。設定入口是 + +```dart +void setMaxParallelDownloads(int count) { + settings.youtube.save(downloadParallelCount: count.withMinimum(1)); + _startQueued(); +} +``` + +(同檔 L19–22)。`_startQueued()` 用 `while (_runningCount < maxCount && _queue.isNotEmpty)`,並且在真正啟動前才檢查 `shouldSkip(task.config)`;`_run` 完成後 `_finish` 再 `_startQueued()` 補位。 + +**單檔執行緒層**:`settings.youtube.downloadThreadsCount`([`lib/controller/settings.youtube.dart#L56`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/settings.youtube.dart#L56)),`downloadParallelCount = RxnF(fallback: 4)`、下一行 `downloadThreadsCount = RxnF(fallback: 3)`。 + +**預設值:4 個檔案併發 × 每檔 3 執行緒。** + +### 2. 背景下載 + +**程式碼**:**沒有 WorkManager**(pubspec 沒有 `workmanager`),**沒有下載專用 foreground service**(AndroidManifest 只有 `audio_service` 的 `AudioService` + `MediaButtonReceiver`)。下載跑在一個**共用 isolate**: + +```dart +class FilesDownloadManager with PortsProvider { + static final inst = ...; // 註釋:「Resumable downloads running in a shared isolate.」 +``` + +(`lib/controller/files_download_manager.dart`)。progress 以 100ms 批次回報,註釋寫「progress is batched, sending each chunk floods the main isolate, especially with parallel downloads」(`_kProgressReportIntervalMs = 100`)。 + +維持存活的手段是**要求電池優化例外**:`requestIgnoreBatteryOptimizations()` 先跳一個帶「dont ask again」按鈕的常駐 snackbar 才發請求(`lib/controller/platform/permission_manager/permission_manager.dart`),manifest 有 `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`。README 也把這條列在權限說明:「`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` (requested when needed): improve downloads.」 + +**這是弱點**:相比 NewPipe 的 foreground service,靠 battery-optimization 例外在現代 Android 上不可靠。**推測**這也是為何它需要 `_kStallTimeout = Duration(seconds: 30)` 與 5 次重試。 + +### 3. 續傳(本節是全文最有價值的部分) + +`abstract class DownloadWrapper`(`lib/class/download_wrapper.dart`)的常數與策略: + +- `_kMaxRetries = 5`、`_kStallTimeout = Duration(seconds: 30)`、`_retryBackoff` 註釋寫「1s, 2s, 4s, 8s, then 10s」。 +- `_isRetryable` 涵蓋 5xx / 408 / 429 / Timeout / Socket / Handshake / Http / Rhttp*。 + +**Range 的用法**:`_downloadRange(...)` 裡 + +```dart +final rangeHeader = end == null ? 'bytes=$start-' : 'bytes=$start-${end - 1}'; +``` + +**續傳位移 = 磁碟上既有檔案大小**(不是 ETag、不是 If-Range): + +```dart +start = targetBaseOffset + targetSize; // targetSize = _sizeSync(target) +FileMode.writeOnlyAppend +``` + +**三個關鍵的防護**: + +1. 伺服器回非 206 且 `targetSize > 0` → `onWritten(-targetSize, 0); targetSize = 0; writeMode = FileMode.writeOnly;`,註釋:「server didnt honor our range request, restarting from scratch to not corrupt the file」。 +2. `_contentRangeMatches` 驗證 `Content-Range` 的 start 與 total 是否與 `totalBytes` 一致。 +3. 收到 **416** 時,用 `_contentRangeTotal(contentRange) == start` 判斷是否其實已經下載完成。 + +**多執行緒的續傳設計**(`class MultiThreadedDownloadWrapper`):`_kPartExtension = '.part'`,parts 放在 `'$filePath.parts'`,檔名 `.part`,每個 part 存的是從 `index * chunkSize` 開始的位元組。設計註釋是我看過最精煉的一句: + +> file only grows by whole chunks so it always holds a valid prefix, and each `.part` holds the bytes from `index * chunkSize`, so everything resumes from file sizes alone + +搭配 `partsSizeSync` / `deleteParts` / `_parsePartIndex` / `_chunkLength`。`_kCopyBufferSize = 1 << 20`。 + +是否啟用多執行緒的條件(`files_download_manager.dart` L25/L39): + +```dart +static const _kChunkSize = 8 * 1024 * 1024; +... +if (_kMultiThreaded && threads > 1 && totalBytes > _kChunkSize) { ... } +``` + +**`ETag` / `If-Range` 完全沒有出現** —— 值得注意,因為對「URL 會過期、內容可能變動」的串流來源,用檔案大小當續傳依據本身有正確性風險(**推測**:作者接受這個風險,因為目標是 YouTube 上不會變的媒體串流)。 + +### 4. 儲存位置 + +**`AppDirs`**(`lib/core/constants.dart`): + +```dart +AppDirs.YOUTUBE_DOWNLOADS_DEFAULT = _join(INTERNAL_STORAGE, 'Downloads') +static String get YOUTUBE_DOWNLOADS => settings.youtube.ytDownloadLocation.value +AppDirs.INTERNAL_STORAGE = FileParts.joinPath(isWindowsPortable ? AppDirs.ROOT_DIR : paths[0], 'Namida') +``` + +(`AppDirs.INTERNAL_STORAGE` 的組裝在 `lib/main.dart` L204)。也就是 **`Namida/Downloads`,使用者可見,可用內建檔案瀏覽器改**:`NamidaFileBrowser.getDirectory(note: lang.defaultDownloadLocation)` → `settings.youtube.save(ytDownloadLocation: path)`。 + +**不用 SAF**,改用 `MANAGE_EXTERNAL_STORAGE`(見 §9)。這是刻意的取捨:全樹可寫,代價是要一顆被 Google Play 限縮的權限。 + +分組目錄:`_getGroupDirectoryPath(groupName) => FileParts.joinPath(AppDirs.YOUTUBE_DOWNLOADS, groupName.groupName)`;快取模式 `_getTempDirectoryPath(...) => config.cacheOnly ? AppDirs.VIDEOS_CACHE_TEMP : _getGroupDirectoryPath(groupName)`。 + +### 5. 檔名與目錄結構(yt-dlp 風格,最值得借) + +`lib/youtube/controller/yt_filename_rebuilder.dart` 的 `_YtFilenameRebuilder`: + +- 模板語法用 yt-dlp 的 `%(param)s`:`paramRegex = RegExp(r'%\((\w+)\)s')`。 +- 使用者模板裡**必須**存在的參數:`encodedParamsThatShouldExistInFilename = const ['video_id','id','video_url','url','video_title','title','playlist_index','playlist_autonumber']` —— 這是**唯一性閘門**:強制使用者模板至少含一個能保證不撞名的參數。 +- 找不到的值填 `fallback = 'NA'`。 +- `_keywordToInfo` 是一個大 switch,處理 title/artist 解析(含從 description 抽、`keepFeatKeywordsOnly`、`_removeTopicKeyword` 去掉 YouTube 自動加的 "- Topic" 後綴)。 +- 淨化:`DownloadTaskFilename.cleanupFilenameRegex = RegExp(r'[*#\$|/\\!^:"\?%<>⼸⁄⧸]', caseSensitive: false)`。 +- **長度上限分平台**:`_fullPathLimit` = Windows 258 / macOS 1024 / 其他 4096,單一組件上限 255。 +- 撞名處理:`withNumberSuffix` → `name (n).ext`。 + +README 的對應宣稱:「Downloads output filename builder (similar to yt-dlp)」、「Tags config for downloads」、「Optional Auto title/artist/album extraction for downloads and scrobbling」。 + +### 6. 內嵌 tag + +**程式碼**:**有寫**,用**內附的 ffmpeg**(`lib/controller/ffmpeg_controller.dart`)。 + +`NamidaFFMPEG.ffmpegEditMetadata({required String path, MIFormatTags? oldTags, required Map tagsMap, bool keepFileStats = true})` 的做法是寫到 `.temp_${path.hashCode}.$ext` 再搬回原路徑(避免半成品)。 + +**opus 家族的坑寫得很明確**: + +```dart +const opusEtcFormats = {'opus','ogg','oga','ogx','flac','alac'}; +// 註釋:overwriting tags for opus is not supported, we need to remove all first +// (-map_metadata -1) and write all combined +``` + +所以那類格式會加 `-map_metadata -1 -disposition:v attached_pic`。參數組裝: + +```dart +params.add('-metadata'); params.add('${e.key}=$valueCleaned'); +... '-id3v2_version','3','-write_id3v2','1','-c','copy','-y' +``` + +**這是「用 ffmpeg 統一寫 tag」路線的完整實作參考**,含格式差異的處理。讀取端另外用了 `flutter_taglib` 的 fork(**這是我的紀錄,本次未重新核對 pubspec**)。 + +### 7. 下載 ↔ 音樂庫關聯 + +**程式碼**:任務狀態存在**每個 group 一個 sqlite DB**(透過 `namico_db_wrapper` 的 `DBWrapperMainSync(params.tasksDatabasesPath)`): + +```dart +downloadTasksGroupDB.put(config.filename.key, config.toJson()); +``` + +另有舊 `.json` 任務檔的 migration。影片記錄的 model 是 `NamidaVideo { path, ytID, nameInCache, height, width, sizeInBytes, frameratePrecise, creationTimeMS, durationMS, bitrate }` —— **`path` 與 `ytID` 都在記錄裡**,且 `nameInCache` 與最終檔名分開存(下載中用 cache 名,完成後才 move 到 `moveTo` / `moveToRequiredBytes` 的最終路徑)。 + +沒有像 Finamp 那樣的關係圖;是扁平的「一筆任務 = 一列」。 + +### 8. 刪除 + +`FilesDownloadManager.deleteDownloadFiles(File)` —— **同時刪掉 `.parts` 目錄**(否則會留下孤兒分塊)。UI 入口我沒逐一追(**查不到**確切入口點,但 `DownloadTaskFilename` 為 key 讓刪除能精準對到目標)。 + +### 9. 權限流程 + +`lib/controller/platform/permission_manager/permission_manager.dart`: + +```dart +_shouldRequestManageAllFilesPermission = NamidaFeaturesAvailablity.android11and_plus.resolve(); + +Future requestManageStoragePermission({bool request = true, bool showError = true, required String? directoryToCreate}) async { + await Permission.manageExternalStorage.request(); + // 失敗 → snackyy(title: lang.storagePermissionDenied, message: lang.storagePermissionDeniedSubtitle, isError: true); return false; + // 成功 → 建立 directoryToCreate +} +``` + +(同檔 L87 起)。舊 Android 走 `Permission.storage` 或 `Permission.audio/videos/photos`(`requestStoragePermission`),**永久拒絕時呼叫 `openAppSettings()`**。 + +manifest 權限清單很長,關鍵幾條:`MANAGE_EXTERNAL_STORAGE`、`READ_EXTERNAL_STORAGE android:maxSdkVersion="32"`、`WRITE_EXTERNAL_STORAGE`、`READ_MEDIA_AUDIO/VIDEO/IMAGES`、`POST_NOTIFICATIONS`、`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`、`WRITE_SETTINGS`、`QUERY_ALL_PACKAGES`、`android:requestLegacyExternalStorage="true"`。 + +### 反例 / 要避開的 + +- **`MANAGE_EXTERNAL_STORAGE` + 自建檔案瀏覽器**換來全樹可寫,但代價是無法上 Google Play(除非符合豁免)。FMP 若要上架,這條走不通。 +- `parallel_downloads_controller.dart` 的第一行註釋是 `// rewrite by claude` —— 提醒:這個檔案有一次 AI 重寫的歷史,引用其設計時要留意它與其他檔案的風格差異。 +- 靠 `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` 而非 foreground service 維持背景下載,是這份調查裡最不可靠的一條路。 + +--- + +## Spotube `[S]` — KRTirtho/spotube @ `69a310c7` + +**這是全文最該當反面教材的實作**:功能看起來齊(佇列、分塊、tag、封面),但每一項都在關鍵處少一塊。 + +### 1. 佇列與併發 + +**程式碼**:`lib/provider/download_manager_provider.dart`。 + +```dart +enum DownloadStatus { queued, downloading, completed, failed, canceled } +class DownloadTask { track, status, cancelToken, totalSizeBytes, downloadedBytesStream } +``` + +併發**硬編碼 1**([`#L265`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/download_manager_provider.dart#L265)): + +```dart +Future _startDownloading() async { + for (final task in state) { + if (task.status == DownloadStatus.downloading) return; // 有一個在跑就整個 return + if (task.status == DownloadStatus.queued) { + try { await _downloadTrack(task); } finally { await _startDownloading(); } + } + } +} +``` + +**佇列只存在記憶體**:`build()` 回 `[]`,所以**重啟後佇列消失、沒有任何持久化**(對照 Finamp 的 Isar `DownloadItem`、Namida 的 sqlite 任務表、NewPipe 的 metadata 檔)。 + +`addToQueue` 會避重並註明「No await should be invoked to avoid stuck UI」(L102/L116/L123 都出現同一句)。 + +### 2. 背景下載 + +**程式碼**:**沒有下載用的背景機制**。`android/app/src/main/AndroidManifest.xml` 的 `FOREGROUND_SERVICE` / `FOREGROUND_SERVICE_MEDIA_PLAYBACK` 屬 `audio_service` 播放;`BIND_JOB_SERVICE` 屬於 `home_widget`(佈景小工具),不是下載。**結論:切到背景後下載是否繼續沒有保證。** + +### 3. 續傳 + +**沒有續傳,而且是刻意的**:`lib/extensions/dio.dart` 的 `chunkDownload` 在**開始前**先把暫存目錄整個刪掉: + +```dart +if (await tempSaveDir.exists()) await tempSaveDir.delete(recursive: true); +``` + +錯誤路徑上也刪。暫存路徑是 `tempRootDir/Spotube/.chunk_dl_`,分塊存成 `part_$i` 再串接成目標檔。 + +Range 只用來**加速**,不是續傳:先 HEAD 帶 `'Range': 'bytes=0-0'` 讀 content-length,再判斷 + +```dart +supportsRange = headResp?.statusCode == 206 || + headResp?.headers.value(HttpHeaders.acceptRangesHeader) == 'bytes'; +``` + +([`#L58`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/extensions/dio.dart#L58))。不支援 Range 或 `connections <= 1` 就退回套件本身的 `download()`。分塊:`chunkSize = (totalLength / connections).ceil()`、`connections = 4`。 + +**缺 `Content-Range` 驗證**(對照 Namida 的 `_contentRangeMatches`)—— 任一分塊回錯內容都會被無聲串進成品。 + +### 4. 儲存位置 + +`_getDefaultDownloadDirectory()`: + +- Android **硬編碼** `"/storage/emulated/0/Download/Spotube"` +- macOS `join((await paths.getLibraryDirectory()).path, "Caches")` +- 其餘 `getDownloadsDirectory()/Spotube` + +路徑用 drift 持久化:`setData(PreferencesTableCompanion(downloadLocation: Value(downloadDir)))`,設定頁在 `lib/pages/settings/sections/downloads.dart`。 + +**與 Finamp 同一個病**:挑目錄用 `FilePicker.platform.getDirectoryPath`(行動/macOS)或 `file_selector` 的 `getDirectoryPath`(桌面),**只拿到字串路徑、沒有 SAF 授權**。Android 硬編碼路徑 + `requestLegacyExternalStorage="true"` 在 Android 11+ 直接不可寫(**推測**這就是為什麼需要 `requestLegacyExternalStorage` —— 一個已經在 API 33 失效的旗標)。 + +### 5. 檔名與目錄結構 + +```dart +savePath = join(downloadLocation, + ServiceUtils.sanitizeFilename("${track.query.name} - ${track.query.artists.map((e) => e.name).join(", ")}.${container.getFileExtension()}")); +``` + +**完全扁平**(沒有 album/artist 子目錄),檔名是 `曲名 - 藝人1, 藝人2.ext`。淨化:`sanitizeFilename` 取代 `[\/\?<>\\:\*\|"]` 與控制字元 `[\x00-\x1f\x80-\x9f]`。撞名時跳 `_shouldReplaceFileOnExist` 對話框(`ReplaceDownloadedDialog`,用 `replaceDownloadedFileState` memo 化)。 + +### 6. 內嵌 tag + +**有**,用 `metadata_god: ^1.1.0`([`#L250`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/download_manager_provider.dart#L250)): + +```dart +await MetadataGod.writeMetadata(file: savePath, metadata: task.track.toMetadata(...)); +``` + +`toMetadata`([`lib/models/metadata/track.dart#L92`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/models/metadata/track.dart#L92))設 title、artist(join `", "`)、album、albumArtist、year(`album.releaseDate`,fallback 1970)、durationMs、`fileSize: BigInt.from(fileLength)`,封面用 `Picture(data: imageBytes, mimeType: lookupMimeType(...) ?? "image/jpeg")`,圖從 `ServiceUtils.downloadImage(...index: 1)` 取得。 + +**一個可愛的細節**:`if (container.getFileExtension() == "weba") return;` —— WebM audio 直接跳過寫 tag。這是對「有些容器寫不了 tag」的務實處理,可借。 + +### 7. 下載 ↔ 音樂庫關聯 + +**程式碼**:**幾乎沒有**。`lib/pages/library/user_downloads.dart` 只顯示**記憶體裡的當前佇列**(`context.l10n.currently_downloading(downloadQueue.length)` + 「全部取消」),**沒有已下載清單**。重啟後 app 不知道哪些歌下載過。 + +**唯一的痕跡是檔案系統**:`_downloadTrack` 開頭就是「同路徑檔案已存在 → 問要不要取代」,也就是用檔名碰撞當作「下載過」的判斷。**這是最脆弱的關聯方式**(改個 naming 就全失效)。 + +### 8. 刪除 + +`DownloadManager` 只有 cancel(`cancelToken`)。**已下載檔案沒有 app 內刪除入口**(查不到);只能靠系統檔案管理器。 + +### 9. 權限流程 + +`lib/hooks/configurators/use_get_storage_perms.dart` 請求 `Permission.storage` 或 Android 13+ 的 `Permission.audio`,檢查 `isGranted` / `isLimited`。**拒絕後的處理查不到結構化流程**(沒有 `openAppSettings` 的痕跡)。manifest:`INTERNET`、`WAKE_LOCK`、`FOREGROUND_SERVICE`、`FOREGROUND_SERVICE_MEDIA_PLAYBACK`、`WRITE/READ_EXTERNAL_STORAGE`、`READ_MEDIA_AUDIO`、`android:requestLegacyExternalStorage="true"`。 + +--- + +## NewPipe `[P]` — TeamNewPipe/NewPipe @ `7e5df38a` + +Android 原生,giga 下載引擎(`us.shandian.giga`)。**這是六個產品裡唯一有正規 foreground service + SAF + 完整災難恢復的實作**,也是這份調查裡「Android 下載」最正確的參考。 + +### 1. 佇列與併發 + +**程式碼**:`DownloadManager`([`app/src/main/java/us/shandian/giga/service/DownloadManager.java#L30`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/service/DownloadManager.java#L30))。 + +併發由一個**布林**控制,不是數字: + +```java +boolean start = !mPrefQueueLimit || getRunningMissionsCount() < 1; +if (canDownloadInCurrentNetwork() && start) { mission.start(); } +``` + +([`#L265`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/service/DownloadManager.java#L265))。`getRunningMissionsCount()`(L398)只數「running 且未完成、非後處理失敗」的任務。 + +- **`mPrefQueueLimit` 預設 `true`**([`app/src/main/res/xml/download_settings.xml#L76`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/xml/download_settings.xml#L76) 的 `android:defaultValue="true"`,偏好讀取在 `DownloadManagerService.java#L326`)→ **預設一次只跑 1 個下載**。 +- 設定標籤是「enable queue limit」(`downloads_queue_limit`),使用者可關掉 → 變成全部一起跑(**不是有限的 N**,是無上限,這點值得注意)。 + +**單檔執行緒數**:`mission.threadCount`(`DownloadMission.java#L128` 的 dartdoc「Maximum of download threads running, chosen by the user」,預設值在 L131 `public int threadCount = 3;`),由 `DownloadManagerService.startMission(...)` 的 `threads` 參數傳入(`EXTRA_THREADS`),靜態工廠 `startMission` 在 `DownloadManagerService.java#L355` 附近。 + +**重試**:`mPrefMaxRetry`(`DownloadManagerService.java#L318` 從偏好讀),mission 建立時 `this.maxRetry = 3`(`DownloadMission.java`)。 + +**排序**:`mMissionsPending` 是 `ArrayList`,搭配 `enqueued` 旗標與 `mPrefQueueLimit` 掃描;`DownloadManager.java#L459`/`L520` 附近的迴圈在 queue limit 模式下 `break`。 + +**README / 設定頁宣稱**:`max_retry_msg` = "Maximum retries"、"Maximum number of attempts before canceling the download"(`strings.xml#L666`)。 + +### 2. 背景下載(本產品最重要的參考) + +**程式碼**:`DownloadManagerService` **是 foreground service**。 + +- manifest:[`app/src/main/AndroidManifest.xml#L138`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/AndroidManifest.xml#L138) + `` + —— 型別是 **`dataSync`**(API 34 起要在 manifest 聲明,這是正確的型別)。 +- 進入前景:`public void updateForegroundState(boolean state)` → `startForeground(FOREGROUND_NOTIFICATION_ID, mNotification)`([`DownloadManagerService.java#L338`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java#L338)),離開用 `ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)`。 +- **同時加鎖**:同一個函式末尾 `manageLock(state)`,而 `manageLock`(L493)呼叫 `mLock.acquireWifiAndCpu()` / `releaseWifiAndCpu()` —— 即 **WifiLock + WakeLock 一起拿**。 +- 通知帶 `PendingIntent` 指向 `DownloadActivity`(L146–162),另有獨立的「下載完成」通知(`notifyFinishedDownload`,在 `downloadDoneNotification` 上 `setDeleteIntent(null)` 並加註「prevent NewPipe running when is killed, cleared from recent, etc」)。 +- 通知權限:`checkPostNotificationsPermission`(TIRAMISU 起),且用 `App.getInstance().getNotificationsRequested()` **只問一次**。 + +**這是本份調查裡唯一真正可靠的背景下載實作**,其他五個都沒有。 + +### 3. 續傳(設計最精細) + +**程式碼**:核心是 `int[] blocks` —— dartdoc 寫得很清楚(`DownloadMission.java` 約 L115): + +> Download blocks, the size is multiple of `BLOCK_SIZE`. Every entry (block) in this array holds an offset, used to resume the download. An block offset can be **-1 if the block was downloaded successfully**. + +區塊大小 `BLOCK_SIZE`;`DownloadInitializer.java` 算數量: + +```java +int count = (int) (mMission.length / DownloadMission.BLOCK_SIZE); +if ((count * DownloadMission.BLOCK_SIZE) < mMission.length) count++; +mMission.blocks = new int[count]; +// if one thread is required don't calculate blocks, is useless +``` + +([`DownloadInitializer.java#L123`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/DownloadInitializer.java#L123))。**`blocks == null && current == 0` 是「首次下載」的判斷**(L51)。 + +**多執行緒**:`threads = new Thread[Math.min(threadCount, remainingBlocks)]`,每個執行緒跑一個 `DownloadRunnable(this, i)` 並以 `acquireBlock()`(synchronized)搶下一個未完成的 block(`DownloadMission.java#L475`、`acquireBlock` 在 L167 附近)。單執行緒退回 `DownloadRunnableFallback`(L465),並用 `fallbackResumeOffset`。 + +**Range 的組裝**:`HttpURLConnection openConnection(boolean headRequest, long rangeStart, long rangeEnd)`([`#L217`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/DownloadMission.java#L217)): + +```java +String req = "bytes=" + rangeStart + "-"; +if (rangeEnd > 0) req += rangeEnd; +conn.setRequestProperty("Range", req); +``` + +並在 L253/L256 log 出 `Range=` 與 `Content-Range=`(可觀測性做得比別人好)。 + +**伺服器不支援 Range 時**:L509 `Log.w(TAG, "pausing a download that can not be resumed (range requests not allowed by the server).")` —— 明確放棄續傳並把任務標成無法續傳。 + +**災難恢復(最獨特的一段)**:因為 NewPipe 下載的是 YouTube 的**時效性 URL**,續傳時 URL 常常已經失效。所以有: + +- `DownloadMissionRecover`(`threads[0] instanceof DownloadMissionRecover` 用來判斷是否在恢復中,`DownloadMission.java#L684`) +- `MissionRecoveryInfo`(含 `DownloadMissionRecover.java`、`MissionRecoveryInfo.kt`) +- `recoveryInfo` 陣列存在 mission 上,並經 `EXTRA_RECOVERY_INFO` 傳遞(`DownloadManagerService.java` 的 `startMission` 參數說明寫「array of MissionRecoveryInfo, in case is required recover the download」) +- 錯誤碼 `ERROR_RESOURCE_GONE`、`ERROR_PROGRESS_LOST`、`ERROR_POSTPROCESSING_STOPPED` 等 + +**啟動時的對帳**(`DownloadManager.loadPendingMissions`,L150 起)非常值得逐條讀: + +1. 掃 `pending_downloads/` 目錄(`getPendingDir`:先試 `context.getExternalFilesDir("pending_downloads")`,失敗退 `context.getFilesDir()`,都失敗就 `throw new RuntimeException`)。 +2. `Utility.readFromFile(sub)` 讀不回來的就刪檔。 +3. `mis.isFinished()` → 移到 finished 清單(`setFinished`)並刪 metadata 檔,註釋「DON'T delete missions that are truly finished - let them be moved to finished list」。 +4. `mis.hasInvalidStorage() && errCode != ERROR_PROGRESS_LOST` → 只在 `mis.storage == null` 時才真刪,註釋「Only delete if it's truly unrecoverable (not just progress lost)」。**「進度丟失不等於任務不可回收」是這裡的核心洞見。** +5. `StoredFileHelper.deserialize(mis.storage, ctx)` 還原儲存 handle,`exists = !mis.storage.isInvalid() && mis.storage.existsAsFile()`。 +6. 後處理中斷(`mis.isPsRunning()`):若演算法是 `worksOnSameFile`,認為結果已損壞而刪檔,標 `ERROR_POSTPROCESSING_STOPPED`。 + +Metadata 檔的命名是 **timestamp**(`mission.metadata = new File(mPendingMissionsDir, String.valueOf(mission.timestamp))`,`DownloadManager.java` startMission 內),撞名就換一個 timestamp 重試。 + +**注意:完全沒有 ETag / If-Range**。NewPipe 用「block 位移 + 檔案存在」+(換 URL 的)mission recovery 取代。跟 Namida 同樣的取捨。 + +### 4. 儲存位置(SAF 做得最正確) + +**程式碼**:`org.schabi.newpipe.streams.io.StoredFileHelper`(實作 `Serializable`,因為要寫進 metadata)與 `StoredDirectoryHelper`。 + +`StoredFileHelper` 有兩條路徑: + +```java +public StoredFileHelper(final Context context, final Uri uri, final String mime) { + if (FilePickerActivityHelper.isOwnFileUri(context, uri)) { + final File ioFile = Utils.getFileForUri(uri); + ioPath = ioFile.toPath(); source = Uri.fromFile(ioFile).toString(); // 純檔案路徑 + } else { + docFile = DocumentFile.fromSingleUri(context, uri); source = uri.toString(); // SAF single URI + } +} +``` + +內部欄位同時保有 `docFile` / `docTree`(SAF)與 `ioPath`(java.nio),並用 `FileStream` / `FileStreamSAF` 兩個實作把兩種後端統一成同一個 stream 介面。**`deserialize` / `isInvalid` / `existsAsFile` / `create` / `createFile` / `createUniqueFile` 這一整套是 SAF 生命週期管理的實作參考** —— 尤其 `isInvalid()` 這個概念(SAF 授權可能在重裝/清資料後失效,必須能偵測並重建)。 + +**SAF 的強制程度**(`NewPipeSettings.java#L105`): + +```java +public static boolean useStorageAccessFramework(final Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return true; // API 29+ 一律 SAF,無商量 + } else if (DeviceUtils.isFireTv()) { + return false; // FireOS 的 SAF 對話框無法用遙控器確認 (#6455) + } + final String key = context.getString(R.string.storage_use_saf); + return prefs.getBoolean(key, true); // 舊版預設仍是 true +} +``` + +設定字串也說明得很誠實(`strings.xml#L678-680`):`downloads_storage_use_saf_title` = "Use system folder picker (SAF)"、`downloads_storage_use_saf_summary` = "The 'Storage Access Framework' allows downloads to an external SD card"、`downloads_storage_use_saf_summary_api_29` = "**Starting from Android 10 only 'Storage Access Framework' is supported**"。 + +**音訊與視訊分開的兩個 handle**:`DownloadManager` 的建構子 `DownloadManager(Context, Handler, StoredDirectoryHelper storageVideo, StoredDirectoryHelper storageAudio)`(`DownloadManager.java#L67`),tag 常數 `public static final String TAG_AUDIO = "audio"` / `TAG_VIDEO = "video"`。預設目錄(非 SAF 模式):`saveDefaultVideoDownloadDirectory` → `Environment.DIRECTORY_MOVIES`、`saveDefaultAudioDownloadDirectory` → `Environment.DIRECTORY_MUSIC`,都再包一層 `NewPipe`(`getNewPipeChildFolderPathForDir` → `new File(dir, "NewPipe").toURI().toString()`)。 + +**這個「音訊/視訊各自一個 SAF tree + 一個 tag 字串」的設計直接對應 FMP 的需求**(多來源、可能多型別),很值得照抄。 + +### 5. 檔名與目錄結構 + +`DownloadDialog`(`app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java`):`filenameTmp = getNameEditText().concat(".")`(L761),再依格式附副檔名,例如 L771 `filenameTmp += "opus"`、L774/L783/L797 `filenameTmp += format.getSuffix()`、L795 `MediaFormat.SRT.getSuffix()`。也就是**使用者可在下載對話框直接改檔名**,副檔名由串流格式決定。 + +淨化在 `FilenameUtils.kt`([`app/src/main/java/org/schabi/newpipe/util/FilenameUtils.kt`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/FilenameUtils.kt)): + +- `CHARSET_MOST_SPECIAL = "[\\n\\r|?*<\":\\\\>/']+"`、`CHARSET_ONLY_LETTERS_AND_DIGITS = "[^\\w\\d]+"` +- **取代字元也是使用者設定**:`settings_file_replacement_character_key`,預設 `"_"`;字元集也可選(`settings_file_charset_key`)或自填正則 +- 註釋引 issue 編號:「#143 #44 #42 #22: make sure that the filename does not contain illegal chars.」 +- 註解提到 `title`:「@param title the title to create a filename from」 + +**結構完全扁平**(單層目錄 + 檔名),沒有 album/artist 子目錄。**撞名處理很完整**:`checkSelectedDownload(mainStorage, mainStorage.findFile(filenameTmp), filenameTmp, mimeTmp)`(L542/L860),後續在 L880–L1006 之間用 `mainStorage.createFile` / `createUniqueFile` 嘗試;註釋提到要避開「the filename is not used in a pending/finished download」(L926)—— **撞名檢查有把「未完成的下載」算進去**,這點很多實作會漏。 + +### 6. 內嵌 tag + +**程式碼**:**不寫 tag**。`us.shandian.giga.postprocessing` 只有五個檔:`M4aNoDash.java`、`Mp4FromDashMuxer.java`、`OggFromWebmDemuxer.java`、`Postprocessing.java`、`TtmlConverter.java`、`WebMMuxer.java` —— 全是**容器層**處理(DASH 的 audio/video 合併、WebM→Ogg 解封裝、字幕轉換),沒有任何 `-metadata` / tag 寫入。全 `org/schabi/newpipe/` 只有一個檔案名命中 `ffmpeg`(`streams/Mp4FromDashWriter.java`,而那是自寫的 MP4 寫入器,不是 ffmpeg binary)。 + +**串流資訊改存在 app 自己的 DB**(見 §7)—— 這是一個合理替代方案:既然寫 tag 要嘛加 ffmpeg 依賴、要嘛加 native 庫,NewPipe 選擇「檔案是純媒體、metadata 在 app 裡」。 + +### 7. 下載 ↔ 音樂庫關聯 + +**程式碼**:`us.shandian.giga.get.sqlite.FinishedMissionStore`(SQLite,`SQLiteOpenHelper`): + +```java +private static final String DATABASE_NAME = "downloads.db"; +private static final int DATABASE_VERSION = 4; +MISSIONS_CREATE_TABLE = + "CREATE TABLE " + FINISHED_TABLE_NAME + " (" + + KEY_PATH + " TEXT NOT NULL, " + // "path" + KEY_SOURCE + " TEXT NOT NULL, " + // "url" + KEY_DONE + " INTEGER NOT NULL, " + // "bytes_downloaded" + KEY_TIMESTAMP + " INTEGER NOT NULL, " + + KEY_KIND + " TEXT NOT NULL, " + // "kind":a / v / s + " UNIQUE(" + KEY_TIMESTAMP + ", " + KEY_PATH + "));"; +``` + +([`app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java))。另有舊表 `MISSIONS_TABLE_NAME_v2 = "download_missions"` 的 migration 痕跡,`DATABASE_VERSION = 4`。 + +**重啟後如何知道**:`loadFinishedMissions()`(`DownloadManager.java#L110` 起)在載入時**逐筆檢查檔案是否還在**: + +```java +// check if the files exists, otherwise, forget the download +for (int i = finishedMissions.size() - 1; i >= 0; i--) { ... } +``` + +**「DB 記錄 + 啟動時跟檔案系統對帳」** 是這份調查裡第二種可靠模式(第一種是 Finamp 的「檔案存在 + 狀態欄位對帳」)。`path` 是完整字串(SAF URI 或檔案路徑),`kind` 區分音/視/字幕。 + +### 8. 刪除 + +`DownloadManager.deleteMission(Mission mission, boolean alsoDeleteFile)`([`#L287`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/us/shandian/giga/service/DownloadManager.java#L287)): + +```java +if (mission instanceof DownloadMission) mMissionsPending.remove(mission); +else if (mission instanceof FinishedMission) { mMissionsFinished.remove(mission); mFinishedMissionStore.deleteMission(mission); } +if (alsoDeleteFile) mission.delete(); +``` + +**「移除記錄」與「刪檔案」是兩個獨立選項**(`alsoDeleteFile`)—— 這是很好的 API 設計,讓 UI 能分別提供「只從清單移除」與「連檔案一起刪」。 + +另有一個 `forgetMission(StoredFileHelper storage)`(L305):`mission.storage = null; mission.delete();` —— **刻意忘掉儲存 handle(例如 SAF 授權已失效)**,用在 `tryRecover` 失敗時。 + +**UI 入口**:`us.shandian.giga.ui.adapter.MissionAdapter` 搭配 `us.shandian.giga.ui.common.Deleter`: + +```java +mDeleter = new Deleter(root, mContext, this, mDownloadManager, mIterator, mHandler); +... +mDownloadManager.deleteMission(mission, true); // 單筆,連檔刪 +mDeleter.append(h.item.mission, true); // 加入多重刪除佇列,連檔刪 +mDeleter.append(h.item.mission, false); // 只移除記錄 +``` + +(`MissionAdapter.java` L137/L624/L675/L680/L688)。`Deleter` 另有 `pause()` / `resume()` / `dispose()`(L796–L805),即**多重刪除是可暫停的批次作業**。 + +### 9. 權限流程(最正確的一版) + +`PermissionHelper`([`app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java)): + +```java +public static boolean checkStoragePermissions(final Activity activity, final int requestCode) { + if (NewPipeSettings.useStorageAccessFramework(activity)) { + return true; // Storage permissions are not needed for SAF + } + if (!checkReadStoragePermissions(activity, requestCode)) return false; + return checkWriteStoragePermissions(activity, requestCode); +} +``` + +**核心洞見:走 SAF 就不需要任何儲存權限。** 這是把 §4 與 §9 綁在一起的關鍵 —— SAF 不是「比較好的儲存方式」,它是「**唯一不需要權限的儲存方式**」。對照 Namida 用 `MANAGE_EXTERNAL_STORAGE` 換全樹可寫、Finamp/Spotube 用 legacy 權限 + 字串路徑,NewPipe 的做法是唯一在 API 29+ 上不需要特殊權限且真正可寫外部儲存的路。 + +請求碼有三個獨立常數:`POST_NOTIFICATIONS_REQUEST_CODE = 779`、`DOWNLOAD_DIALOG_REQUEST_CODE = 778`、`DOWNLOADS_REQUEST_CODE = 777`。 + +`checkWriteStoragePermissions` 裡原本的 `shouldShowRequestPermissionRationale` 分支被**整段註解掉**(含它自己的 `/* ... */`),留下的註釋是「No explanation needed, we can request the permission.」—— 即**不做 rationale 說明**,直接請求。這算簡化,不算最佳實務(**推測**:這條路徑在 API 29+ 已經走不到,所以沒人維護)。 + +`checkSystemAlertWindowPermission` 處理 `SYSTEM_ALERT_WINDOW`(下載浮動視窗用),在 Android R+ 因為 `ACTION_MANAGE_OVERLAY_PERMISSION` 只會開到列表頁,改成**先跳一個說明對話框**再跳設定(含把 app 名與權限名用 `` 斜體的 HTML 格式化訊息)。這是「跳系統設定前先解釋」的實作樣板。 + +--- + +## Musify `[M]` — gokadzev/Musify @ `5b98d3a3` + +最**簡**的一個:用 `youtube_explode_dart` 的高階 API 直接把串流 pipe 進檔案,其餘全部靠 app-private 目錄省掉權限問題。 + +### 1. 佇列與併發 + +**程式碼**: + +- **播放清單下載**:`OfflinePlaylistService.downloadPlaylist`(`lib/services/playlist_download_service.dart`)建一個 `Queue` 與 **3 個 worker**: + + ```dart + const maxConcurrent = 3; + final workerCount = songsList.length < maxConcurrent ? songsList.length : maxConcurrent; + await Future.wait([for (var i = 0; i < workerCount; i++) _processDownloadQueue(songQueue, progressNotifier)]) + .timeout(Duration(minutes: songsList.length * 2), onTimeout: () { ... }); + ``` + + ([`#L137`](https://github.com/gokadzev/Musify/blob/5b98d3a3cddd3fdb16ea6cc14d59d667e82cccd2/lib/services/playlist_download_service.dart#L137))。**硬編碼 3,不可設定**。整批有 `songsList.length * 2` 分鐘的總逾時。 +- **單曲下載**:`makeSongOffline`([`lib/services/common_services.dart#L832`](https://github.com/gokadzev/Musify/blob/5b98d3a3cddd3fdb16ea6cc14d59d667e82cccd2/lib/services/common_services.dart#L832))**沒有全域佇列或限流**,直接 `await`。同時下載多首單曲 → 沒有上限(**推測**這是刻意的,因為單首下載是使用者明確動作)。 +- 狀態用 `ValueNotifier` 與 `activeDownloads` 字串清單(`List activeDownloads`),**沒有持久化**(重啟後 `activeDownloads` 清空、`downloadProgressNotifiers` 清空)。 + +### 2. 背景下載 + +**程式碼**:**沒有下載專用的背景機制**。`android/app/src/main/AndroidManifest.xml` 只有: + +```xml + + + + +... + +``` + +全部是 `audio_service`(播放)用的。**下載中切到背景是否會繼續 → 查不到任何保證**(`WAKE_LOCK` 存在但沒有對應的下載服務;**推測**只在播放維持前景服務期間僥倖存活)。對照 NewPipe 的 `dataSync` foreground service,這是明顯缺口。 + +### 3. 續傳 + +**沒有**。`makeSongOffline` 的核心是: + +```dart +final audioManifest = await fetchBestAudioStream(ytid); +final stream = ytClient.videos.streamsClient.get(audioManifest); +fileStream = audioFile.openWrite(); +await stream.pipe(fileStream); +``` + +失敗路徑 `if (await audioFile.exists()) await audioFile.delete();` —— **中斷就刪、重來**,完全沒有 Range。 + +### 4. 儲存位置(最省事的一條路) + +**程式碼**:`lib/main.dart#L335`:`applicationDirPath = (await getApplicationDocumentsDirectory()).path;` + +`lib/services/io_service.dart` 的 `class FilePaths`: + +```dart +static const String tracksDir = 'tracks'; +static const String artworksDir = 'artworks'; +static const String streamBufferDir = 'stream_buffer'; + +static String getAudioPath(String songId) => '$applicationDirPath/$tracksDir/$songId$audioExtension'; +static String getArtworkPath(String songId) => '$applicationDirPath/$artworksDir/$songId$artworkExtension'; +static String getStreamBufferDirPath() => '$applicationDirPath/$streamBufferDir'; +``` + +`ensureDirectoriesExist()` 建這三個目錄。 + +**關鍵洞見:選 app-private 目錄 → 完全不需要任何儲存權限**(manifest 裡一條 storage permission 都沒有),也不需要 SAF、不需要選目錄 UI。代價是檔案使用者看不到、其他播放器讀不到、換手機帶不走。**對「以 app 為中心的下載」這是最省事的正解**;FMP 若要兩者兼得就得兩條路都做。 + +### 5. 檔名與目錄結構 + +**最極簡的路徑之一**:檔名就是 **``**(`getAudioPath`),**完全沒有 metadata 進路徑**,也沒有可讀的曲名。 + +`audioExtension` 與 `artworkExtension` 是全域常數(`io_service.dart`);實際副檔名由 `fetchBestAudioStream` 拿到的 manifest 決定(`audioManifest.audioCodec` / `audioManifest.bitrate.kiloBitsPerSecond`)。 + +**這種「id 當檔名」的做法唯一好處是零碰撞、零淨化問題、id 一查就到**;壞處是使用者完全無法辨識(除非讀 app DB)。**這是上一份 playlist 調查裡也要注意的反例**。 + +### 6. 內嵌 tag + +**程式碼**:**不寫 tag**。 + +- pubspec 沒有 `metadata_god`、沒有 taglib、沒有 ffmpeg 相關套件(`youtube_explode_dart` 與 `youtube_music_explode_dart` 是 path 依賴的本機 fork)。 +- 封面存成 **sidecar 檔案**:`_downloadAndSaveArtworkFile(offlineSong['highResImage'], artworkPath)`,然後 `offlineSong['artworkPath'] = artworkPath`。 +- `grep 'metadata_god\|taglib\|ID3\|writeMetadata'` 在 `lib/` 與 `pubspec.yaml` **零命中**。 + +**「封面當 sidecar 檔案 + DB 記路徑」是完整可行的替代方案**(很多播放器都這樣做),比寫 tag 少了格式相容性的坑。 + +### 7. 下載 ↔ 音樂庫關聯(第二好的樣板) + +**程式碼**:**Hive box `userNoBackup`**(`lib/services/common_services.dart`): + +```dart +ValueNotifier userOfflineSongs = ValueNotifier(...); +``` + +`makeSongOffline` 成功後寫入的欄位(同檔約 L912–L918): + +```dart +offlineSong['audioPath'] = audioFile.path; +offlineSong['audioBitrateKbps'] = audioBitrateKbps; +offlineSong['audioCodec'] = audioCodec; +offlineSong['dateAdded'] = DateTime.now().millisecondsSinceEpoch; +``` + +用 `ytid` 當 key 做 upsert,再 `addOrUpdateData('userNoBackup', 'offlineSongs', userOfflineSongs.value)` 持久化。 + +**最有意思的設計**:**路徑同時「存」也「可重算」**。 + +- 存:`audioPath` 在記錄裡。 +- 可重算:`FilePaths.getAudioPath(ytid)` 純函式,只要 `applicationDirPath` 對,路徑永遠能推回來。 + +`isSongAlreadyOffline(ytid)`(L532)先查 `userOfflineSongs` 的 id 集合,找到之後**還要再檢查 `File(audioPath).exists()`**: + +```dart +if (isSongAlreadyOffline(ytid)) { + final existingPath = FilePaths.getAudioPath(ytid); + if (await File(existingPath).exists()) { ... return true; } +} +``` + +(L841–L846)—— **「記錄說有 + 檔案真的在」雙重確認**,這是這份調查裡第三次出現同一個模式(Finamp、NewPipe、Musify 都做,Spotube 只有半個)。**這三家的共識比任何單一實作都更有說服力:下載狀態不可以只信 DB。** + +還有 `_cachedOfflineSongIds = _createSongIdCache(userOfflineSongs)`(L82)—— 為了避開每次都掃整個 list,維護一份 id 快取。 + +**播放清單層**:`OfflinePlaylistService.offlinePlaylists` 存另一份清單,`checkAndAutoMarkOffline(playlist)` 在所有歌都離線時自動把整個 playlist 標成 offline(含 `downloadedAt`)。也就是**下載狀態有兩層:單曲 + 歌單**,而且歌單層是**推導出來**的(不是使用者明確下載才會有)。 + +### 8. 刪除 + +`removeSongFromOffline(dynamic songId)`([`#L954`](https://github.com/gokadevz/Musify/blob/5b98d3a3cddd3fdb16ea6cc14d59d667e82cccd2/lib/services/common_services.dart#L954)): + +1. 刪 `FilePaths.getAudioPath(songId)`; +2. 刪 `FilePaths.getArtworkPath(songId)`; +3. `userOfflineSongs.value = ... removeWhere((song) => song['ytid'] == songId)`,再寫回 Hive。 + +**每一步都包在自己的 try/catch 裡**(刪檔失敗不會擋住清記錄),而且**檔案與記錄都刪**(不像 Finamp 留記錄)。 + +UI 入口:`lib/widgets/song_bar.dart` 的 toggle(`removeOfflineText` / `makeOfflineText`,L157),另有 `OfflinePlaylistService.removeSongFromOfflineAndResync`(`playlist_download_service.dart#L392`)處理「刪單曲後同步歌單離線狀態」。 + +### 9. 權限流程 + +**程式碼**:**完全沒有**。`grep 'Permission'` 在 `lib/` 零命中,manifest 也沒有任何 storage permission。 + +**結論:Musify 用「選 app-private 目錄」把權限問題整個消掉了。** 這是六個產品裡唯一一個完全不需要處理權限的 —— 也是最誠實的取捨:它放棄了「使用者可見的下載檔案」這個功能,換來零權限、零 SAF、零相容性問題。 + +### README 宣稱 + +- **README 宣稱**:「Offline listening support」(README 第 29 行)。**我驗證過為真**(`makeSongOffline` / `userOfflineSongs` / `OfflinePlaylistService`)。 + +--- + +## MusicFree `[X]` — maotoumao/MusicFree @ `d118b18b` + +React Native,**插件架構的旁證**(任務指定可簡短)。這是六個產品裡唯一一個與 FMP 新架構同型(來源 = 外部 JS 插件、host 負責下載)的實作,所以插件契約那段值得細看。 + +### 插件契約(對 FMP 的 `resolveStream` 最直接可比) + +`src/types/plugin.d.ts`([permalink](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/types/plugin.d.ts)): + +```ts +export interface IMediaSourceResult { + headers?: Record; + /** 兜底播放 */ + url?: string; + /** UA */ + userAgent?: string; + /** 音质 */ + quality?: IMusic.IQualityKey; +} +... +/** 获取根据音乐信息获取url */ +getMediaSource?: ( + musicItem: IMusic.IMusicItemBase, + quality: IMusic.IQualityKey, +) => Promise; +``` + +**三個可以直接對到 FMP 設計的點**: + +1. **插件回傳的是「一個 URL + headers + UA」,不是位元組**。host 負責所有 HTTP。這正是任務描述的「用 plugin `resolveStream` 取得候選串流清單」的形狀。 +2. **`quality` 是「一次一個音質」而不是「回一整份清單」**。要候選清單的話是**由 host 逐個音質去問**(見下)。 +3. `headers` 與 `userAgent` 分開回傳;`url` 的註釋寫「**兜底播放**」(fallback playback)—— 即這個 url 也可能來自 `musicItem.url` 而不是插件現算。 + +`IPluginDefine` 的其他欄位也值得一看:`platform`(來源名)、`primaryKey?: string[]`(「主鍵,會被存儲到 mediameta 中」)、`supportedSearchType?: ICommon.SupportMediaType[]`、`cacheControl?: "cache" | "no-cache" | "no-store"`、`userVariables?: IUserVariable[]`、`hints?: Record`。**`primaryKey` 的概念對 FMP 很有用**:跨來源辨識同一首歌時,插件自己宣告哪些欄位構成主鍵。 + +### 下載(host 端) + +`src/core/downloader.ts`([permalink](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/downloader.ts)): + +**狀態機**:`DownloadStatus { Pending, Preparing, Downloading, Completed, Error }`。 +**失敗原因列舉**(`DownloadFailReason`):`NetworkOffline` / `NotAllowToDownloadInCellular` / `FailToFetchSource` / `NoWritePermission` / `Unknown`。**把失敗原因做成明確的列舉而不是自由字串**,這點值得借。 + +**併發:可設定 1..10,預設 3**([`#L183`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/downloader.ts#L183)): + +```ts +const maxDownloadCount = Math.max(1, Math.min(+(this.configService.getConfig("basic.maxDownload") || 3), 10)); +``` + +搭配 `downloadNextPendingTask()` 的遞迴排程:先檢查 `downloadingCount >= maxDownloadCount`,再找第一個 `Pending` 任務,標成 started,**在真正 download 之前先遞迴呼叫 `downloadNextPendingTask()`**(L270 的註釋是「预处理完成,可以开始处理下一个任务」)—— 即「連結解析」與「位元組傳輸」兩階段重疊,避免解析慢的任務卡住整條佇列。**這是個聰明的排程細節。** + +**候選串流清單的取得(host 逐個音質去問插件)**(L215–L240):先由 `getQualityOrder(目標音質, config basic.downloadQualityOrder ?? "asc")` 產生一個**音質順序陣列**,再逐一 `await plugin.methods.getMediaSource(musicItem, quality, 1, true)`,取第一個有 `data.url` 的: + +```ts +for (let quality of qualityOrder) { + try { + data = await plugin.methods.getMediaSource(musicItem, quality, 1, true); + if (!data?.url) { continue; } + break; + } catch { } +} +url = data?.url ?? url; // 插件全失敗 → 退回 musicItem.url(兜底) +headers = data?.headers; +``` + +**這是「候選清單」在插件架構下的實際形狀**:不是插件一次回一個陣列,而是 host 依偏好順序**逐一協商**,失敗就降級到下一個音質,全失敗才用兜底 URL。`try { } catch { }` 空 catch 說明**插件拋錯被視為該音質不可用**,而不是任務失敗。 + +**下載本體**:`react-native-fs` 的 `downloadFile({ fromUrl, toFile, headers, background: true, begin, progress })`([`#L302`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/downloader.ts#L302))。 + +- **`background: true`** 交給 RNFS 的原生背景下載機制(**這是六個產品裡第二個有意識處理背景下載的**)。 +- **先下到暫存路徑再搬**:`cacheDownloadPath`(`nanoid().`,在 `/cache/download/`)→ 成功後 `await copyFile(cacheDownloadPath, targetDownloadPath)` → 最後 `await unlink(cacheDownloadPath)` 清理。**因為暫存檔名是 `nanoid()`,所以沒有節點──重試等於全新下載,沒有續傳。** +- 副檔名從 URL 猜:`getExtensionName(url)` 用正則抓,fallback `"mp3"`;再對 `supportLocalMediaType` 白名單,不在名單內一律改成 `mp3`。**這是「不能信任 URL 尾綴」的正確態度。** + +**寫入權限的偵測方式很務實**(L290–L296):不主動請求權限,而是**試著建目標資料夾,失敗就報 `DownloadFailReason.NoWritePermission`**: + +```ts +const folder = path.dirname(targetDownloadPath); +const folderExists = await exists(folder); +if (!folderExists) { await mkdirR(folder); } +// catch → this.emit(DownloaderEvent.DownloadTaskError, DownloadFailReason.NoWritePermission, ...) +``` + +**`NoWritePermission` 是「權限不足」的具體 symptom,不是抽象概念** —— 這比抽象地問「有沒有權限」更可靠,因為 SAF/Android 的權限狀態本來就難以窮舉。 + +### 儲存位置 + +`src/constants/pathConst.ts`: + +```ts +export const basePath = Platform.OS === "android" + ? RNFS.ExternalDirectoryPath // Android: app 專屬外部目錄(不需權限) + : RNFS.DocumentDirectoryPath; // iOS: Documents + +export default { + basePath, + pluginPath: `${basePath}/plugins/`, + localLrcPath: `${basePath}/local_lrc/`, + downloadCachePath: `${basePath}/cache/download/`, + downloadPath: `${basePath}/download/`, + downloadMusicPath: `${basePath}/download/music/`, + ... +}; +``` + +下載路徑由 `getDownloadPath(fileName)` 決定:`configService.getConfig("basic.downloadPath") ?? pathConst.downloadMusicPath`(可設定,預設 `/download/music/`)。 + +**`RNFS.ExternalDirectoryPath` 是關鍵**:它是 `/sdcard/Android/data//files/`,**使用者可見(透過檔案管理器)但不需要任何權限**。這是介於「app-private」與「SAF」之間的第三條路 —— **FMP 若不想碰 SAF 又想要使用者能看到檔案,這是值得評估的選項**(代價:Android 11+ 的使用者透過檔案管理器存取 `Android/data` 受限,且解除安裝時被清掉,跟 app-private 一樣)。 + +### 檔名 + +```ts +private static generateFilename(musicItem: IMusic.IMusicItem) { + return `${escapeCharacter(musicItem.platform)}@${escapeCharacter(musicItem.id)}@${escapeCharacter(musicItem.title)}@${escapeCharacter(musicItem.artist)}`.slice(0, 200); +} +``` + +格式:**`平台@id@標題@藝人`**,`escapeCharacter` 淨化,**整體截斷到 200 字元**。 + +**`平台@id@標題@藝人` 這個組合很聰明**:`平台@id` 保證唯一(可解析回來源)、`標題@藝人` 保證人類可讀。**「結構化分隔符 + 前段保證唯一 + 後段保證可讀 + 總長截斷」** —— 比起 Finamp 的「可讀名稱 + 8 碼 id 後綴」更明確(因為分隔符讓程式可以反解)。值得借。 + +`getExtensionName` 的正則(L152–L160)也值得一提: + +```ts +url.match(/^https?\:\/\/.+\.([^\?\.]+?$)|(?:([^\.]+?)\?.+$)/) +``` + +先試 `.ext` 結尾,再試 `?` 前的 `.ext`,都不中就 `"mp3"`。 + +### 內嵌 tag + +**程式碼**:下載流程**不寫 tag**。`src/native/mp3Util/index.ts` 的介面裡**有** `setMediaTag: (filePath, meta: IWritableMeta) => Promise` 與 `IWritableMeta { lyric?, comment?, ... }`,但 `grep` 顯示下載流程(`downloader.ts`)**沒有呼叫它**。 + +`mp3Util` 的實際用途全在**讀**本地檔案時:`localMusicSheet.ts#L170` 的 `mp3Util.getMediaMeta(...)`、`pluginManager/plugin.ts#L1041` 的 `Mp3Util.getMediaCoverImg(localPath)`、`#L1054` 的 `Mp3Util.getLyric(localPath)`、`#L1082` 的 `Mp3Util.getBasicMeta(urlLike)`。 + +**下載後只把路徑記進 DB**: + +```ts +LocalMusicSheet.addMusic({ ...musicItem, [internalSerializeKey]: { localPath: targetDownloadPath } }); +patchMediaExtra(musicItem, { downloaded: true, localPath: targetDownloadPath }); +``` + +(`downloader.ts` L330–L340)。即 **metadata 完全靠 app 自己的 DB,檔案本體是裸的**。 + +**這是一個重要的架構選擇**:MusicFree 的插件**本來就提供完整的 `IMusicItem`**(title/artist/album/封面 URL),所以不需要從檔案裡讀 metadata —— 寫 tag 的唯一理由是「給其他播放器看」。**FMP 的插件架構有同樣的性質**:既然 `resolveStream` 的來源已經知道曲名藝人,寫 tag 與否就是「要不要讓外部播放器受益」的產品決策,不是技術必需品。 + +### 下載 ↔ 音樂庫關聯 + +**兩層**: + +1. `LocalMusicSheet.addMusic({...musicItem, localPath})` —— 進「本地音樂」清單。 +2. `patchMediaExtra(musicItem, { downloaded: true, localPath })` —— 在媒體的 extra 屬性上打 `downloaded` 旗標 + 路徑。 + +`removeMusic(musicItem, alsoDeleteFile)`(`src/core/localMusicSheet.ts#L77`): + +```ts +export async function removeMusic(musicItem, alsoDeleteFile) { + ... + await unlink(localPath); // L91 +} +``` + +**刪除入口**:`src/components/panels/types/musicItemOptions.tsx` L146–L166,兩個獨立選項: + +```tsx +await LocalMusicSheet.removeMusic(musicItem); // 只從清單移除 +... +title: t("panel.musicItemOptions.deleteLocalDownload"), +content: t("panel.musicItemOptions.deleteLocalDownloadConfirm"), +... +await LocalMusicSheet.removeMusic(musicItem, true); // 連檔案刪(有確認對話框) +``` + +**「移除」與「刪檔」兩個選單項、刪檔有確認對話框、i18n key 分開** —— 跟 NewPipe 的 `alsoDeleteFile` 同一個思路,而且多了「確認」這一步。**這是 UI 層最完整的參考。** + +`remove(musicItem)`(downloader 上的另一個方法)只處理**尚未下載的任務**:只有 `Pending` / `Error` 狀態可以取消,`Preparing` / `Downloading` 回 `false`(**即已開始的任務無法取消** —— 這是個缺口,`AbortController` 之類的機制查不到)。 + +### 其他值得注意的 + +- **下載前檢查網路狀態**:`network.isOffline` → 報 `NetworkOffline`;`network.isCellular && !config basic.useCelluarNetworkDownload` → 報 `NotAllowToDownloadInCellular`(`download()` 開頭)。**「行動網路下不下載」是設定項**,這點 FMP 也該考慮(大檔案在行動網路下載是很實際的痛點)。 +- **事件匯流排**:`Downloader extends EventEmitter`,四個事件 `DownloadError` / `DownloadTaskUpdate` / `DownloadTaskError` / `DownloadQueueCompleted`,UI 用 `useDownloadTask(musicItem)` hook 訂閱(`downloader.on(...)` + cleanup `off`)。**下載器與 UI 完全解耦**。 +- **去重**:`download()` 用 `filter` 同時擋「已在 downloadTasks 裡」與 `LocalMusicSheet.isLocalMusic(m)`,並在 filter 裡順手建立任務(副作用寫在 filter 裡,可讀性差,但有效)。 + +--- + +## 對 FMP 新下載子系統的可借鏡點與反例 + +前提:FMP 新架構是「所有來源都是 JS script plugin,下載由 host 處理,用 plugin 的 `resolveStream` 取得候選串流清單」。以下按主題分。 + +### A. 可借鏡的設計(依價值排序) + +**A1. 「候選串流清單」在插件架構下的實際形狀 = host 逐個協商,不是插件回陣列。** +MusicFree 的做法值得直接照搬形狀:host 先由使用者偏好產生一個**音質順序**(`getQualityOrder(目標, "asc"/"desc")`),逐一 `getMediaSource(item, quality)`,**取第一個有 `url` 的**,全部失敗才退回 `musicItem.url` 兜底(`downloader.ts#L215-240`)。 +可借的三個細節: +- **插件拋錯 = 該候選不可用**(`try {} catch {}` 空 catch),而不是整筆下載失敗; +- **兜底 URL 與插件算出的 URL 是同一條路徑**(`url = data?.url ?? url`),所以插件完全失效時下載仍可能成功; +- 插件回傳 `{ url, headers, userAgent }` 三元組(`plugin.d.ts` 的 `IMediaSourceResult`),**headers 與 UA 分開** —— FMP 的 `resolveStream` 契約應該照這個形狀設計,因為串流來源幾乎都需要自訂 header。 +另外 MusicFree 的 `IPluginDefine.primaryKey?: string[]`(插件自己宣告哪些欄位構成主鍵)**對 FMP 的跨來源歌曲辨識很有用**,值得納入插件契約。 + +**A2. 「DB 記錄 + 啟動時與檔案系統對帳」是三家共識,不是任一家偏好。** +Finamp(`item.file?.existsSync()` → 標 complete/重新入列)、NewPipe(`loadFinishedMissions()` 逐筆檢查檔案還在不在,「check if the files exists, otherwise, forget the download」)、Musify(`isSongAlreadyOffline(ytid)` 之後**還要** `File(audioPath).exists()`)**全都做同一件事**。Spotube 沒做,而 Spotube 正是唯一「重啟後完全不知道下載過什麼」的產品。 +**這條應該當硬性要求**:下載狀態不可只信 DB,也不可只信檔案系統,必須兩者對帳。Musify 的雙重確認寫法(先查 id 集合再驗檔案)成本最低。 + +**A3. 相對路徑 / 可重算路徑,勝過存絕對路徑。** +- Finamp 用 `DownloadLocation.currentPath + item.path`(相對),文件說明動機是「this will solve the absolute path issue」—— iOS 的 app 容器路徑每次更新都會變。 +- Musify 更徹底:**路徑是純函式 `FilePaths.getAudioPath(ytid)`**,記錄裡的 `audioPath` 只是快取。 +**對 FMP**:若下載目錄可能跨平台或跨版本變動(Windows 可攜版、Android 換外部儲存),**存「相對路徑」或「可從 id 重算」是唯一穩健的做法**。Finamp 的雙軌(下載位置存 `baseDirectory` 列舉 + `relativePath`)比 Musify 的純函式更靈活,但兩者都比絕對路徑好。 + +**A4. 續傳的依據用「磁碟上檔案大小」,並配三個防護。** +Namida 的實作(`download_wrapper.dart`)是目前看過最實務的: +1. `start = targetBaseOffset + targetSize`(`targetSize = _sizeSync(target)`,即既有檔案大小); +2. 伺服器**回非 206 且 targetSize > 0 → 整個重來**(註釋:「server didnt honor our range request, restarting from scratch to not corrupt the file」); +3. `_contentRangeMatches` **驗證 `Content-Range` 的 start 與 total**; +4. **416 → 用 `_contentRangeTotal(contentRange) == start` 判斷是否其實已下載完**。 +NewPipe 的 `blocks[]`(每塊位移、-1 = 完成)是另一個更精細的變體,但對「單檔 + 少量並行」的 FMP 而言 Namida 的檔案大小法更簡單且已足夠。 +**注意:六個產品(含 NewPipe)沒有任何一個用 ETag / If-Range。** 對 FMP 的 plugin 串流(URL 有時效性、內容理論上可能變動),用檔案大小當續傳依據**有正確性風險**。NewPipe 的答案是 `DownloadMissionRecover` / `MissionRecoveryInfo`:**URL 失效時不是放棄,而是重新協商一組新 URL 並接續**。FMP 若要支援續傳,必須回答「URL 過期了怎麼辦」,這是 NewPipe 唯一提供了完整答案的地方。 + +**A5. 多執行緒的暫存設計:「整塊成長,所以永遠是合法前綴」。** +Namida 的 `MultiThreadedDownloadWrapper`:parts 放 `'$filePath.parts'`,`.part` 存從 `index * chunkSize` 起算的位元組,設計註釋是最好的一句總結: +> file only grows by whole chunks so it always holds a valid prefix, and each `.part` holds the bytes from `index * chunkSize`, so everything resumes from file sizes alone +**這讓「目標檔案」本身就是進度表**,不需要額外的分塊狀態 DB,且任何中斷點都能只用檔案大小恢復。搭配 `_kChunkSize = 8 * 1024 * 1024` 與「只有當 `threads > 1 && totalBytes > chunkSize` 才多執行緒」的守門。**FMP 若要分塊下載,這是可直接實作(而非借概念)的設計。** +反例是 Spotube:分塊暫存在**開始前先整個刪掉**、**零 `Content-Range` 驗證**、**串接成目標檔時不看每塊對不對** —— 分塊只帶來速度,帶來三個新的失敗模式。 + +**A6. 檔案命名:結構化分隔符 + 前段保證唯一 + 後段保證可讀 + 總長截斷。** +MusicFree 的 `` `${platform}@${id}@${title}@${artist}`.slice(0, 200) `` 是形狀最好的(分隔符讓程式能反解來源與 id,title/artist 給人看,200 字元上限防爆路徑)。 +Namida 的 yt-dlp 風格模板最強但最複雜,可借其中**兩條規則**: +- **強制模板必含唯一性參數**:`encodedParamsThatShouldExistInFilename = ['video_id','id','video_url','url','video_title','title','playlist_index','playlist_autonumber']` —— 使用者可以自由改模板,但模板若不含任何一個保證不撞名的參數就拒絕。**這是「可設定」與「不會壞」之間的關鍵閘門。** +- **長度上限分平台**:`_fullPathLimit` = Windows 258 / macOS 1024 / 其他 4096,單一組件 255。Windows 的 258 是 FMP 有 Windows build 時會踩到的坑。 +Finamp 的折衷也好用:可讀名稱 + **id 前 8 碼後綴**(`"$indexNumber$artist${item.name}_${item.id.raw.substring(0,8)}"`)。 +**反面**:Musify 的檔名就是 ``(人類完全不可讀)、Spotube 是完全扁平的 `曲名 - 藝人.ext`(無子目錄、無唯一性保證,靠檔名碰撞當「下載過」的判斷)。 +**要避免的淨化陷阱**:Finamp 的 `_filesystemSafe` 只取代 `[/?<>:*|.\\"]` —— **沒有處理控制字元、沒有長度限制、沒有 Windows 保留名(CON/PRN/NUL)**。Namida 的 `cleanupFilenameRegex` 與 Spotube 的 `sanitizeFilename`(含 `[\x00-\x1f\x80-\x9f]`)都更完整。NewPipe 的 `FilenameUtils` 最好用(字元集可選、取代字元可設定),但**把正則交給使用者填**是過度的自由度。 + +**A7. SAF 是「唯一不需要權限的可寫外部儲存」,NewPipe 的實作是完整參考。** +- `NewPipeSettings.useStorageAccessFramework()`:**API 29+ 一律 true,不給選**;只為 FireTV 的遙控器 bug (#6455) 例外。 +- `PermissionHelper.checkStoragePermissions()`:**走 SAF 直接 `return true; // Storage permissions are not needed for SAF`**。 +- `StoredFileHelper`:SAF(`DocumentFile` + tree URI)與 java.nio(`ioPath`)雙後端,用 `FileStream` / `FileStreamSAF` 統一成同一介面,**`Serializable` 且能 `deserialize` / `isInvalid()` / `create()`** —— 因為 SAF 授權會在重裝或清資料後失效,**可偵測 + 可重建是必要能力**。 +- **音訊與視訊各自一個 `StoredDirectoryHelper` + 一個 tag 字串**(`TAG_AUDIO`/`TAG_VIDEO`),建構子明列這兩個參數。**FMP 多來源、可能多型別,這個「每個目的地一個 handle + 一個 tag」的形狀可以直接用。** +**反例(兩個成功產品都在這裡壞掉)**:Finamp 與 Spotube 都用 `file_picker` 的 `getDirectoryPath()` 拿到**字串路徑**,沒有持續化 SAF 授權 —— Finamp 自家文件寫「practically broken」並在 UI 掛紅字警告,Spotube 只能退回硬編碼 `/storage/emulated/0/Download/Spotube` + 已失效的 `requestLegacyExternalStorage="true"`。 +**結論:要嘛完整的 SAF(NewPipe 路線),要嘛完全不碰(Musify 路線)。用 file_picker 拿字串路徑假裝支援使用者選目錄,是三者中最差的選項。** + +**A8. 背景下載只有一條可靠的路:Android foreground service with `dataSync`。** +- NewPipe 是唯一做對的:manifest `android:foregroundServiceType="dataSync"`,`startForeground(...)` 配 `ServiceCompat.stopForeground(STOP_FOREGROUND_REMOVE)`,**同時 `acquireWifiAndCpu()`(WifiLock + WakeLock 一起)**,通知帶 `PendingIntent` 回下載頁,完成另有通知(且 `setDeleteIntent(null)` 並註記「prevent NewPipe running when is killed, cleared from recent, etc」),通知權限只問一次(`App.getInstance().setNotificationsRequested()`)。 +- MusicFree 用 `react-native-fs` 的 `background: true`(把問題交給 RNFS 的原生實作)。 +- Namida 靠 `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` + **常駐 snackbar 反覆要求** —— 在現代 Android 上不可靠,**這是它需要 `_kStallTimeout = 30s` 與 5 次重試的真正原因**(推測)。 +- Finamp 交給 `background_downloader`(該套件在 Android 用 WorkManager)。 +- Spotube / Musify:**完全沒有**。 +**FMP 若在 Android 上要「鎖屏也繼續下載」,除了 foreground service 沒有第二條路**;`foregroundServiceType` 要選 `dataSync`,且必須同時拿 WakeLock(否則 CPU 睡了傳輸會停)。另外要注意 Android 13+ 的 `POST_NOTIFICATIONS` 是 foreground service 通知能否顯示的前提。 + +**A9. 使用者可設定的是「檔案併發」與「單檔執行緒」兩個獨立旋鈕,且預設值不宜大。** +- Namida:`downloadParallelCount`(預設 **4**)× `downloadThreadsCount`(預設 **3**)。 +- MusicFree:`maxDownloadCount` clamp 到 **1..10,預設 3**(`Math.max(1, Math.min(x || 3, 10))` —— **上界與下界都硬夾**)。 +- NewPipe:queueLimit 布林(預設 true = 一次 1 個)+ 單檔 `threadCount` 預設 3。 +- Finamp:`maxConcurrentDownloads`(註釋說一次 enqueue 這麼多)。 +- Spotube:**硬編碼 1**;Musify:**硬編碼 3**。 +**可借**:MusicFree 的 clamp 寫法最穩健(不會被 config 檔裡的值搞壞);Namida 的「兩層分開設」對應兩個真正獨立的資源(網路連線數 vs 單檔並行)。**要避免**:NewPipe 的 `queueLimit` 是布林 —— 關掉它變成**無上限**,不是「可設定的 N」。 + +**A10. 刪除要有「移除記錄」與「刪檔案」兩個獨立選項,且刪檔要有確認。** +- NewPipe:`deleteMission(mission, alsoDeleteFile)`,UI 三處呼叫分別傳 `true`/`false`(`MissionAdapter` L624/L675/L680),另有可 `pause()`/`resume()` 的批次 `Deleter`。 +- MusicFree:選單兩個獨立項(`deleteLocalDownload` 有確認對話框),i18n key 分開。 +- Finamp:`deleteDownload` 留記錄、只改狀態成 `notDownloaded`(並順手刪歌詞)—— **也是合法選項**(保留「這首歌使用者曾想下載」的資訊)。 +**FMP 需要明確回答一個問題**:刪檔之後,那首歌在 library 裡是「還在但沒下載」還是「消失」?Finamp 選前者、Musify 選後者(`removeWhere` 真的把記錄拿掉),NewPipe 兩者都給。 +**順手的細節**:Namida 的 `deleteDownloadFiles(File)` **同時刪 `.parts` 目錄** —— 分塊下載一定要記得清孤兒分塊。Spotube 的暫存目錄也只是「下次開始時刪掉上一次的」,沒有主動清理。 + +**A11. 失敗原因做成明確的列舉。** +MusicFree:`DownloadFailReason { NetworkOffline, NotAllowToDownloadInCellular, FailToFetchSource, NoWritePermission, Unknown }`(`downloader.ts`)。NewPipe 的錯誤碼也是列舉(`ERROR_NOTHING` / `ERROR_HTTP_FORBIDDEN` / `ERROR_RESOURCE_GONE` / `ERROR_PROGRESS_LOST` / `ERROR_POSTPROCESSING_STOPPED` …)。 +**這直接決定 UI 能不能給出有用的訊息**:「無網路」、「不允許行動網路下載」、「插件拿不到串流」、「沒有寫入權限」對使用者是四件不同的事、四種不同的處置,全部壓成「下載失敗」等於不給資訊。 + +**A12. 「行動網路下是否下載」是設定項。** +MusicFree:`network.isCellular && !config basic.useCelluarNetworkDownload` → 拒絕並報 `NotAllowToDownloadInCellular`。NewPipe:`mPrefMeteredDownloads`(`downloads_cross_network`,預設 false)+ `canDownloadInCurrentNetwork()` / `handleConnectivityState` / `NetworkState { Unavailable, Operating, MeteredOperating }`(`DownloadManager.java#L33`)—— **NewPipe 有一整套網路狀態機,並且在網路不可用時不啟動任務、等狀態變化再啟動**。這比「下載失敗後重試」正確得多。 + +**A13. 寫 tag 是可選的產品決策,不是技術必須;封面當 sidecar 檔案是完全可行的替代。** +- **寫 tag**:Namida(ffmpeg)、Spotube(`metadata_god`)。 +- **不寫 tag**:Finamp、NewPipe、Musify、MusicFree(四家)。 +而 MusicFree 的理由最清楚:**插件本來就提供完整 `IMusicItem`(title/artist/album/封面 URL),metadata 完全在 app DB 裡,寫 tag 的唯一理由是「給外部播放器看」**。FMP 的插件架構有同樣性質 —— 既然 `resolveStream` 的來源已經知道曲名藝人,**寫不寫 tag 是「要不要讓檔案離開 app 還能用」的決策**。 +若決定要寫,Spotube 的務實處理值得抄: +```dart +if (container.getFileExtension() == "weba") return; // 寫不了 tag 的容器直接跳過 +``` +以及 Namida 對格式差異的處理(`opus/ogg/oga/ogx/flac/alac` 要先 `-map_metadata -1` 再整套寫回,因為「overwriting tags for opus is not supported」),以及 finamp 那種「寫到 `.temp_.` 再搬回」的原子性做法。 +Musify 的 sidecar 封面(`artworks/.` + `offlineSong['artworkPath']`)證明**不寫 tag 也能有完整的使用者體驗**。 + +**A14. 儲存位置是「權限 vs 可見性」的四選一,三條可行路都已有人走完。** +- **app-private**(`getApplicationDocumentsDirectory`):Musify。零權限、零 SAF、零相容性問題;使用者看不到、其他 app 讀不到、解除安裝即消失。 +- **app 專屬外部目錄**(`RNFS.ExternalDirectoryPath` = `/sdcard/Android/data//files/`):MusicFree。**零權限但仍可被檔案管理器看到**;與 app-private 同樣在解除安裝時被清掉,且 Android 11+ 使用者存取受限。 +- **完整 SAF**(`ACTION_OPEN_DOCUMENT_TREE` + 持續化授權):NewPipe。唯一能寫任意使用者目錄(含 SD 卡)且不需特殊權限的路;成本是要做完整的授權生命週期管理(`isInvalid` / `deserialize` / `create`)。 +- **`MANAGE_EXTERNAL_STORAGE` + 自建瀏覽器**:Namida。全樹可寫、體驗最好;**代價是無法上 Google Play(除非符合豁免)**。 +**FMP 是 Android + Windows 雙平台**,Windows 沒有 SAF 問題(`getDownloadsDirectory()` 直接可用),所以這個決策**只需要為 Android 做**。任務的「使用者自選資料夾」需求若必須滿足,只有 SAF 一條路;若可接受 app 目錄,Musify/MusicFree 的路線能把整個 §9 的權限章節刪掉。 + +**A15. 下載器與 UI 解耦(事件匯流排)。** +MusicFree:`Downloader extends EventEmitter`,四事件 `DownloadError` / `DownloadTaskUpdate` / `DownloadTaskError` / `DownloadQueueCompleted`,UI 用 `useDownloadTask(musicItem)` hook 訂閱並在 cleanup 時 `off`(`downloader.ts` 末段)。 +Finamp 的對應是 `DownloadItemState` 的狀態機 + `fromTaskStatus(TaskStatus)` 映射 —— **把套件狀態明確映射回自家狀態**,避免套件的狀態列舉洩漏到 UI。 +Namida 的 progress 批次回報(`_kProgressReportIntervalMs = 100`,註釋「sending each chunk floods the main isolate, especially with parallel downloads」)是跨 isolate 時的必備細節。 + +### B. 反例(FMP 應主動避開) + +**B1. 不要把「檔名碰撞」當作「這首歌下載過」的判斷。** +Spotube 的 `_shouldReplaceFileOnExist`(同路徑檔案存在 → 問要不要取代)是它唯一的「下載過」判斷。**改一次 naming 規則,整個下載庫的辨識就全失效。** + +**B2. 不要用 `file_picker` 的 `getDirectoryPath()` 假裝支援使用者選目錄。** +Finamp 與 Spotube 都這樣做,兩家的結果都是「功能宣稱存在、實際不可用」(Finamp 自承 practically broken 並掛紅字;Spotube 退回硬編碼路徑 + 已失效的 `requestLegacyExternalStorage`)。**這是這份調查裡最具體的一次失敗示範 —— 同一個 bug 在兩個獨立專案裡重現。** + +**B3. 不要有「佇列只在記憶體」。** +Spotube 的 `build()` 回 `[]`,重啟後佇列與下載歷史全部消失。對照:Finamp(Isar)、Namida(per-group sqlite)、NewPipe(metadata 檔 + `downloads.db`)、MusicFree(DB 記 `localPath` + `downloaded` 旗標)、Musify(Hive)。**只有 Spotube 沒做,也只有 Spotube 有這個缺口。** + +**B4. 續傳不可用時要明確放棄,不要靜默地從頭下載。** +NewPipe 有一行明確的 log:`Log.w(TAG, "pausing a download that can not be resumed (range requests not allowed by the server).")`(`DownloadMission.java#L509`),並把任務標成無法續傳。 +Namida 的處理也好:伺服器不理 Range 時 `onWritten(-targetSize, 0)` **把已回報的進度扣回去**,讓 UI 的進度條不會顯示錯誤的百分比(註釋:「restarting from scratch to not corrupt the file」)。**「重來」要讓使用者看見進度歸零,而不是假裝還在繼續。** + +**B5. 不要相信 URL 尾綴。** +MusicFree 是唯一有意識處理的:`getExtensionName` 抓不到就 `"mp3"`,抓到之後**還要對 `supportLocalMediaType` 白名單**,不在名單內一律改 `"mp3"`。 +Spotube 的 `container.getFileExtension()` 來的容器格式是可信的(來自 API 而非 URL),但它的分塊流程**不做 `Content-Range` 驗證**,這比尾綴問題更嚴重。 + +**B6. 不要讓「已開始的下載」無法取消。** +MusicFree 的 `remove(musicItem)` 只接受 `Pending` / `Error` 狀態,`Preparing` / `Downloading` 回 `false` —— **已開始的任務使用者取消不掉**(`AbortController` / `CancelToken` 之類的機制查不到)。對照 Spotube 有 `cancelToken`、NewPipe 有 `pauseMission` / `deleteMission`、Namida 有 `stopDownload` / `stopDownloads`。**取消是基本能力,不該漏。** + +**B7. 靠 `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` 維持背景下載不可靠。** +Namida 用**常駐 snackbar 反覆要求**(`requestIgnoreBatteryOptimizations()` 先跳一個帶「dont ask again」的提示才發請求),README 也把它列在權限說明。**在現代 Android(尤其各家 OEM 的省電策略下)這不是保證。** foreground service 才是。 + +**B8. 不要用 `MANAGE_EXTERNAL_STORAGE`,除非確定不需要上架。** +Namida 用它換來全樹可寫 + 自建檔案瀏覽器(體驗確實最好),但這顆權限在 Google Play 受到嚴格限縮。**這是一個產品決策而非技術決策,FMP 若計畫上架 Google Play 就必須排除這條路。** + +### C. 查不到的部分(誠實列出) + +1. **Finamp 的任務排序依據**:`_advanceQueue()` 一次 `limit(20)`,但排序欄位我沒追到。任務優先序有 `Priority.animation + 50`,但完整的排序規則查不到。 +2. **Finamp 的權限失敗處理**:`permission_handler` 唯一一處被註解掉,`FilePicker` 回傳不可寫路徑時的後續流程我沒找到結構化的處理。 +3. **Spotube 的權限拒絕處理**:`use_get_storage_perms.dart` 檢查 `isGranted`/`isLimited`,但拒絕後沒有 `openAppSettings` 之類的痕跡,後續流程查不到。 +4. **NewPipe 的 `blockAcquired` / `writingToFileNext` / `writingToFile` 三個變數的完整協作**:看得出是「多執行緒寫同一檔案時的排序與互斥」,但我沒有讀完整段(`DownloadMission.java` 的 L800–L850 附近有 `for (Thread thread : threads)` 的收尾邏輯),**細節未核實**。 +5. **Musify 的 `audioExtension` / `artworkExtension` 具體值**:`io_service.dart` 裡是常數,我沒讀到定義處。 +6. **Namida 的下載刪除 UI 入口**:`deleteDownloadFiles` 存在,但從哪個畫面觸發我沒追。 +7. **MusicFree 下載中任務的取消機制**:`remove` 只涵蓋 Pending/Error,`Preparing`/`Downloading` 的取消方式查不到。 +8. **Spotube 已下載檔案是否有 app 內刪除入口**:`UserDownloadsPage` 只顯示記憶體佇列,沒找到已下載清單或刪除入口。 +9. **Finamp / Namida 的 `flutter_taglib` fork 這條線索**:我先前紀錄裡提到 Namida 用了 `flutter_taglib` 的 fork 來**讀** tag,**本次未重新核對 pubspec**,僅供參考。 +10. **各產品的 README 對「背景下載」的宣稱**:我沒有逐個核對 README 是否宣稱支援背景下載(Finamp / Namida / Musify / MusicFree 的 README 我只 grep 了 `download` 關鍵字)。**若 FMP 要引用某家的「背景下載」說法,需要另外回查該家 README,且必須以程式碼為準** —— 這份文件裡所有背景下載的結論都來自程式碼(manifest + service + 套件呼叫),不是 README。 From 9a2938db1629f96f1e6f6d9a9be185285bad7f92 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:03:39 +0800 Subject: [PATCH 062/133] chore(task): record the download file layout decision --- .trellis/tasks/09-28-design-downloads/prd.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-downloads/prd.md b/.trellis/tasks/09-28-design-downloads/prd.md index bbd65cc94..1e538f75d 100644 --- a/.trellis/tasks/09-28-design-downloads/prd.md +++ b/.trellis/tasks/09-28-design-downloads/prd.md @@ -35,9 +35,13 @@ ADR 0009(平台能力)、0012(媒體請求不帶憑證)、0014/0018( - 改用成熟套件(權限、背景下載);Android 下載路徑可改並可重新授權;續傳要驗證;下載專用音質;副檔名照實際格式; 失敗任務保留到使用者清除;權限統一入口;sidecar 保留並另外寫內嵌標籤;N1 在重寫時處理。 +## 已決定 + +1. **檔案組織(2026-09-28 選 A′)**:每首歌只存一份,依音源分資料夾:`{根目錄}/{音源}/{標題} [{影片 id}].{副檔名}`;多分 P:`{根目錄}/{音源}/{影片標題} [{影片 id}]/P01 {分P標題}.{副檔名}`。「已下載」頁的歌單分類記在資料庫、不看資料夾。「依歌手分資料夾」已否決:B 站、YouTube 的歌手欄位其實是上傳者。舊下載保留原位,依 sidecar 認回。 + ## 待決定 -- [ ] 下載檔案怎麼組織(依歌單分資料夾、每張歌單各一份,或每首歌只存一份) +- [ ] 下載是否只挑可寫內嵌標籤的格式(YouTube 用 AAC 而非 Opus) ## 驗收條件 From 9ca38d22a961b8509b5a22b290e278ded0f5e88b Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:06:44 +0800 Subject: [PATCH 063/133] chore(task): add design and plan for downloads and permissions --- .../tasks/09-28-design-downloads/design.md | 107 ++++++++++++++++++ .../tasks/09-28-design-downloads/implement.md | 13 +++ .trellis/tasks/09-28-design-downloads/prd.md | 9 +- 3 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 .trellis/tasks/09-28-design-downloads/design.md create mode 100644 .trellis/tasks/09-28-design-downloads/implement.md diff --git a/.trellis/tasks/09-28-design-downloads/design.md b/.trellis/tasks/09-28-design-downloads/design.md new file mode 100644 index 000000000..13ca43e23 --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/design.md @@ -0,0 +1,107 @@ +# 設計:下載與權限 + +## 1. 流程 + +```mermaid +flowchart TD + U["使用者按下載"] --> Q["建立下載紀錄
    狀態:等待"] + Q --> R["StreamResolver
    用途=下載、只收可寫標籤的格式"] + R --> D["background_downloader
    下載到 App 私有暫存"] + D --> T["寫內嵌標籤+sidecar"] + T --> M["搬到最終位置"] + M --> C["紀錄:完成"] + D -- "失敗" --> F["紀錄:失敗
    保留到使用者清除"] +``` + +- 下載由宿主處理(ADR 0014),串流經插件 `resolveStream`,用途標為「下載」,不走記憶體網址快取(網址要新鮮)。 +- **先下載到 App 私有暫存目錄**(可暫停續傳),寫完標籤再搬到最終位置。這樣最終資料夾裡不會出現半成品,寫標籤失敗也不會弄壞已完成的檔案。 + +## 2. 下載引擎與佇列 + +- 使用 `background_downloader`(跨五個平台同一套 API)。在 Android 上 App 進背景仍繼續下載(WorkManager/Android 14+ 使用者發起工作,需通知); + **桌面只在 App 執行中下載**:最小化或縮到托盤時照常下載,關掉 App 就暫停,下次開啟時自動續傳。Flutter 生態沒有桌面真背景下載方案。 +- 下載請求帶插件候選串流回傳的標頭(Referer 等),**不帶帳號憑證**(ADR 0012 媒體請求的規則)。 + 這是網路層之外唯一的 HTTP 出口:下載網址寫 log 前一律經 ADR 0011 的遮蔽函式,測試以假的下載器介面注入(零聯網,ADR 0015)。 +- 並行上限:設定「同時下載數」1–5,預設 3(沿用);同一主機最多 2 個。事件驅動,不輪詢(舊版每 5 秒的備援輪詢不帶過去)。 +- 進度由套件的 stream 提供;進度不寫資料庫,狀態轉換(等待、下載中、暫停、完成、失敗)才寫。 + +## 3. 續傳與重試 + +- 暫停與續傳由套件處理,續傳時以強 ETag 驗證;伺服器不支援或 ETag 不符就從頭下載(N4)。 +- 網址過期(ADR 0016 的 `expiresAt`)或 403:重新解析一次後從頭下載(音檔多為數 MB,重下成本低,不需要跨網址接續)。 +- 網路錯誤由套件以指數退避重試 2 次;仍失敗標「失敗」並附 ADR 0013 的錯誤類別。無法取得、找不到等不重試。 +- 失敗與暫停的任務跨重啟保留,直到使用者重試或清除(N7)。 + +## 4. 位置、組織與命名(已決定 A′) + +- 每首歌只存一份: + - 單曲:`{根目錄}/{音源}/{標題} [{影片 id}].{副檔名}`; + - 多分 P:`{根目錄}/{音源}/{影片標題} [{影片 id}]/P01 {分P標題}.{副檔名}`。 + + `{音源}` 用插件 id(穩定、不隨顯示名稱改變)。 +- 檔名:非法字元換全形、去尾點、避開 Windows 保留名;標題截到 80 字,讓整條路徑在 Windows 260 字元上限內。 +- 下載紀錄存**絕對路徑**;「已下載」頁的歌單分類由資料庫關聯算出(曲目在哪些歌單),不在任何歌單的曲目歸「其他」。 +- 根目錄預設:Android `Music/FMP`,Windows `%USERPROFILE%\Music\FMP`,Linux 的 XDG 音樂目錄下 `FMP`;iOS/macOS 依 ADR 0009 待平台任務定。 + 舊資料匯入時沿用舊版的下載目錄。 +- Android 可在設定頁更改根目錄並重新授權(N2)。更改時詢問「搬移現有下載」或「只改之後的下載位置」;舊檔不動時紀錄的絕對路徑仍有效(N3、N8)。 +- Android 寫入使用者看得到的資料夾沿用 `MANAGE_EXTERNAL_STORAGE`+路徑(舊 ADR 0004 的做法;FMP 不上架商店)。 + +## 5. 格式、標籤與 sidecar(已決定:只挑可寫標籤的格式) + +- 下載時,宿主傳給 `resolveStream` 的可接受格式只有 m4a(AAC)、flac、mp3;YouTube 下載因此取 AAC。播放不受影響。 +- 副檔名照實際格式(N6)。 +- 內嵌標籤:標題、歌手(音源回報的值,多為上傳者)、專輯(多分 P 用影片標題)、封面、備註欄寫來源網址。 + 候選套件 `audio_metadata_reader`(純 Dart、支援 m4a/flac/mp3 寫入且原子寫入),落地前驗證寫入結果能被常見播放器讀到。 +- sidecar 保留(B13):同檔名的 `.json`(曲目鍵、音源、影片 id、分 P、標題、時長、下載時間)與 `.jpg` 封面;「封面+頭像」選項另存 `.avatar.jpg`。 + sidecar 是檔案遺失資料庫時認回曲目的依據。 + +## 6. 與音樂庫的關聯與對帳(N1、N9) + +- `downloads` 表:曲目鍵(FK)、絕對路徑、格式、大小、狀態、錯誤、建立與完成時間。曲目在「沒有被任何歌單項目、佇列、下載紀錄參照」時才算孤兒(ADR 0019)。 +- 刷新把曲目移出歌單時不刪下載(ADR 0019);下載只由使用者在下載頁刪除(刪檔、sidecar 與紀錄)。 +- **啟動對帳**(登記在啟動維護清單,ADR 0017): + - 紀錄的檔案不在:標「檔案遺失」,**不刪紀錄**。播放時改走線上,下載頁提供「重新下載」或「移除紀錄」(N9)。 + - 整個根目錄不存在或不可讀(例如 SD 卡拔出):標「儲存位置無法使用」,全部紀錄不動,之後再檢查。 + - 根目錄內有 sidecar 或檔名帶影片 id、但沒有紀錄的檔案:自動建立紀錄並連回曲目(曲目不存在時依 sidecar 建立)。 + - 對帳永遠不自動刪檔或刪紀錄(舊版「掃不到就清路徑」是 N1 的來源)。 +- 舊資料匯入(ADR 0010):舊下載檔留在原位,依 sidecar 的 `metadata.json` 建立下載紀錄,不強制搬檔。 + +## 7. 權限統一入口(N10、N11) + +- 平台層提供 `PermissionGateway`,依能力宣告需要的權限(ADR 0009): + - 寫入下載資料夾(Android `MANAGE_EXTERNAL_STORAGE`); + - 下載通知(Android 13+ `POST_NOTIFICATIONS`,第一次下載時請求); + - 安裝更新(Android `REQUEST_INSTALL_PACKAGES`,第 19 項使用)。 +- 流程一致: + 1. 說明為什麼需要; + 2. 請求; + 3. 被拒時說明影響並提供「前往系統設定」; + 4. 回到 App 時重新檢查。 + + 永久拒絕與一般拒絕分開處理。 +- 套件:Android 使用 `permission_handler`。舊版刻意避開它,是因為它在 Windows 上會讓 FMP 顯示成使用位置權限;研究顯示其 Windows 實作現為 no-op。 + **第一個加入下載的里程碑實測**:Windows 隱私設定中 FMP 是否仍出現在位置清單。會出現就改為 Android 專用的自有 MethodChannel(舊版做法)。 +- 下載通知權限被拒時照樣下載,只是沒有通知;儲存權限被拒時不開始下載並引導設定。 + +## 8. 設定 + +- 下載音質(高/中/低,預設高)與播放音質分開(N5)。 +- 同時下載數(1–5,預設 3)、下載圖片選項(只封面/封面+頭像)、下載根目錄沿用。 + +## 9. 閘門 + +- 單元測試(假下載器): + - 佇列與並行上限; + - 失敗任務跨重啟保留; + - 網址過期時重新解析並從頭下載; + - ETag 不符從頭下載; + - 格式過濾只收可寫標籤的格式; + - 暫存 → 標籤 → 搬移的順序,任一步失敗時最終資料夾沒有半成品。 +- 對帳測試: + - 檔案遺失標記不刪紀錄; + - 根目錄不可用時不動紀錄; + - 無紀錄的檔案依 sidecar 或檔名認回; + - 從不刪檔。 +- 路徑測試:檔名清理、Windows 路徑長度、保留名。 +- 權限流程測試(假的 `PermissionGateway`):拒絕、永久拒絕、從設定回來重新檢查。 +- 依賴方向(`fmp_layer_imports`):`background_downloader` 只在下載模組、`permission_handler` 只在平台層。 diff --git a/.trellis/tasks/09-28-design-downloads/implement.md b/.trellis/tasks/09-28-design-downloads/implement.md new file mode 100644 index 000000000..6b619836d --- /dev/null +++ b/.trellis/tasks/09-28-design-downloads/implement.md @@ -0,0 +1,13 @@ +# 執行計畫:第 11 項(設計任務,只產出文件) + +1. 核准後寫 `docs/adr/0020-downloads-and-permissions.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9;被否決的方案: + 自寫 isolate 下載器、`flutter_downloader`(無桌面)、SAF URI 下載(不能續傳)、依歌單分資料夾、依歌手分資料夾、下載最高音質含 Opus、 + 啟動掃描以資料夾名重建關聯、掃不到就清路徑、播放時找不到檔就永久清路徑。說明它延續舊 ADR 0004 的 Android 儲存做法、適用於 `app/`。 +2. ADR 0014/0018:`resolveStream` 輸入加上用途(播放/下載)。ADR 0009:`PermissionGateway` 與權限能力宣告指向 ADR 0020。 +3. `phase2-plan.md`:§3 第 11 項標 ✅(ADR 0020);§8 延後實測加入「加入下載的里程碑:`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單; + `audio_metadata_reader` 寫入的標籤能被常見播放器讀到;`background_downloader` 在 Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾」; + §10 交接段更新,下一項 15 歌詞。 +4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 +5. `task.py finish`、`task.py archive design-downloads --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-downloads/prd.md b/.trellis/tasks/09-28-design-downloads/prd.md index 1e538f75d..a0f0345ee 100644 --- a/.trellis/tasks/09-28-design-downloads/prd.md +++ b/.trellis/tasks/09-28-design-downloads/prd.md @@ -2,7 +2,7 @@ ## 目標 -為 `app/` 定下下載佇列與續傳、下載位置與檔案組織、檔案格式與內嵌標籤、下載與音樂庫的關聯、權限的統一入口。產出 ADR 0020。 +為 `app/` 定下下載佇列與續傳、下載位置與檔案組織、檔案格式與內嵌標籤、下載與音樂庫的關聯、權限的統一入口。產出 ADR 0020。技術設計見 `design.md`,執行步驟見 `implement.md`。 依據:parent `prd.md` 階段二第 11 項;`docs/audit/questions.md` N1–N11、B13;`phase2-plan.md` §4 對 N2–N11 的方向(使用者按建議確認); ADR 0009(平台能力)、0012(媒體請求不帶憑證)、0014/0018(下載由宿主處理,經 `resolveStream`)、0017(下載事件驅動,不歸排程器)、0019(刷新移除曲目不刪下載)。 @@ -39,9 +39,10 @@ ADR 0009(平台能力)、0012(媒體請求不帶憑證)、0014/0018( 1. **檔案組織(2026-09-28 選 A′)**:每首歌只存一份,依音源分資料夾:`{根目錄}/{音源}/{標題} [{影片 id}].{副檔名}`;多分 P:`{根目錄}/{音源}/{影片標題} [{影片 id}]/P01 {分P標題}.{副檔名}`。「已下載」頁的歌單分類記在資料庫、不看資料夾。「依歌手分資料夾」已否決:B 站、YouTube 的歌手欄位其實是上傳者。舊下載保留原位,依 sidecar 認回。 -## 待決定 - -- [ ] 下載是否只挑可寫內嵌標籤的格式(YouTube 用 AAC 而非 Opus) +2. **下載格式(2026-09-28 選 A)**:下載只接受可寫內嵌標籤的格式(m4a/flac/mp3),YouTube 下載取 AAC;播放不受影響。 +3. 技術選擇(`design.md`):`background_downloader`(Android 背景下載、桌面只在 App 執行中);先下載到私有暫存、寫標籤後再搬到最終位置; + 續傳以 ETag 驗證、網址過期就重解析從頭下載;失敗任務保留;下載紀錄存絕對路徑、啟動對帳只標記不刪除; + 根目錄可改並選擇是否搬檔;權限經平台層統一入口;下載音質與播放分開。 ## 驗收條件 From 5c3b7c67ffab7defc2f9fcb81084ca861a204992 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:08:04 +0800 Subject: [PATCH 064/133] docs(adr): 0020 downloads and permissions --- ...atform-layer-with-declared-capabilities.md | 2 +- docs/adr/0014-script-source-plugins.md | 2 +- docs/adr/0018-playback-core.md | 2 +- docs/adr/0020-downloads-and-permissions.md | 108 ++++++++++++++++++ 4 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 docs/adr/0020-downloads-and-permissions.md diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 76fb384f8..7aa3c3740 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -42,7 +42,7 @@ Linux、macOS 加入時要回頭改介面。 `smtc_windows`…)只在實作檔 import。 2. **能力宣告**:每個平台一份不可變的 `PlatformCapabilities`。UI 依它決定是否顯示入口;service 只呼叫介面。 要在執行期才能判斷的(例如 Linux 在 Wayland 下沒有全域快捷鍵)由實作在啟動時寫進宣告。 - 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018。 + 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018;權限由平台層 `PermissionGateway` 統一請求,見 ADR 0020。 3. **平台層以外禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件的 import。 4. **不寫空實作**:未驗證的平台宣告全部能力為「沒有」、沒有實作檔;該平台的 child task 開始時才加入實作。 5. **原生呼叫**:新的 MethodChannel 一律用 Pigeon 產生型別安全介面。 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index 5b543293d..f7a264363 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -42,7 +42,7 @@ manifest 與腳本承擔。 只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`)。沒有檔案系統、任意 socket、其他插件的資料。 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。`resolveStream` 回傳網址期限 `expiresAt`(插件從網址本身讀), 封面為多尺寸清單 `artwork`(ADR 0016)。 - `resolveStream` 的輸入含平台可播格式、輸出為依優先序排好的候選串流;`live` 提供直播串流與直播狀態(ADR 0018)。 + `resolveStream` 的輸入含平台可播格式與用途(播放/下載,ADR 0020)、輸出為依優先序排好的候選串流;`live` 提供直播串流與直播狀態(ADR 0018)。 6. **插件庫**:官方插件在獨立 repo `1morr/fmp-plugins`,每插件一目錄(腳本、manifest、錄下的測試 fixture),其 CI 跑契約測試並產生 `index.json`(含 SHA-256)。App 插件頁預設讀官方 index,可加自訂 index 網址,也可從檔案或網址安裝;由 index 安裝時驗證 SHA-256。 安裝前顯示能力與會連的網域,並警告「此腳本會以你的登入身分存取這些網站」。 diff --git a/docs/adr/0018-playback-core.md b/docs/adr/0018-playback-core.md index 01a33131f..d1db71831 100644 --- a/docs/adr/0018-playback-core.md +++ b/docs/adr/0018-playback-core.md @@ -40,7 +40,7 @@ 單曲循環每圈記一筆歷史(D6),網址有效時 seek 回 0 不重解析。 5. **隨機**(D7):隨機順序是位置的順序;拖曳只移動歌曲、不改位置順序,拖進本輪已播的位置本輪不再播; 「下一首播放」插在目前這首之後,連續加入依加入順序排;其餘未播位置不變;隨機順序持久化。 -6. **串流解析**:本機下載檔 → 記憶體網址快取(ADR 0016)→ 插件 `resolveStream`。輸入含分 P 與**平台可播格式**,輸出為依優先序排好的候選串流 +6. **串流解析**:本機下載檔 → 記憶體網址快取(ADR 0016)→ 插件 `resolveStream`。輸入含分 P、用途(播放;下載見 ADR 0020)與**平台可播格式**,輸出為依優先序排好的候選串流 (網址、標頭、格式、`expiresAt`);開流失敗換候選一次。恢復播放、長暫停後 seek、前瞻交接前檢查網址過期。被取代的請求經宿主 `http.request` 取消網路工作。 7. **錯誤恢復**(依 ADR 0013 類別,由 `RecoveryPolicy` 決定): - `NetworkError`、`RateLimited`、傳輸中斷、提前結束:從目前位置重試 1/3/9 秒共 3 次;不在 `Online` 時暫停計數(ADR 0016);仍失敗就跳過並提示。 diff --git a/docs/adr/0020-downloads-and-permissions.md b/docs/adr/0020-downloads-and-permissions.md new file mode 100644 index 000000000..7fccc5cf2 --- /dev/null +++ b/docs/adr/0020-downloads-and-permissions.md @@ -0,0 +1,108 @@ +# 0020 — 下載與權限:background_downloader、每首一份依音源存放、可寫標籤的格式、只標記不刪除的對帳、統一權限入口 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:下載模組、`downloads` 表、下載根目錄與檔名、內嵌標籤與 sidecar、啟動對帳、平台層 `PermissionGateway`、下載相關設定 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-downloads/research/current-state.md`、`docs/audit/downloads.md`,已以程式碼核對): + +- 每任務一個 isolate、原生 `HttpClient`、事件加 5 秒輪詢;只在 App 行程內下載(N8)。 +- 續傳只送 `Range`、不驗證(N4);沒有自動重試;每次啟動清掉失敗任務(N7)。 +- 下載與播放共用音質(N5);副檔名一律 `.m4a`、沒有內嵌標籤(N6、B13)。 +- 依歌單分資料夾,同一首歌在兩張歌單下載兩份;歌單改名不改資料夾(N3)。 +- 啟動掃描以「資料夾名=歌單名」重建關聯、掃不到就清路徑(N1 的資料遺失路徑);播放時找不到檔案就永久清掉路徑(N9)。 +- Android 改下載路徑的 UI 被隱藏(N2);沒有宣告 `POST_NOTIFICATIONS`;權限走自有 MethodChannel(N10、N11)。 + +舊 ADR 0004(Android 以 `MANAGE_EXTERNAL_STORAGE`+路徑、不用 MediaStore)描述舊專案;本 ADR 在 `app/` 延續其儲存做法。 + +## 考慮過的選項 + +- **自寫 isolate 下載器(舊版)**:否決。續傳驗證、背景下載、重試、通知都要自寫。 +- **`flutter_downloader`**:否決,不支援桌面。 +- **SAF URI 下載**:否決。免權限,但 `background_downloader` 對 URI 目標不能暫停續傳;FMP 不上架商店,可用 `MANAGE_EXTERNAL_STORAGE`。 +- **依歌單分資料夾(舊版)**:否決。同一首歌多份、歌單改名要搬檔、移出歌單時檔案去留難定。 +- **依歌手分資料夾**:否決(擁有者指出)。B 站、YouTube 的「歌手」其實是上傳者。 +- **下載最高音質含 Opus/WebM**:否決(擁有者 2026-09-28 選擇)。WebM 幾乎沒有可靠的標籤寫入方案,只有小眾套件或已退役、GPL 的 FFmpeg 分支。 +- **以資料夾名重建關聯、掃不到就清路徑、找不到檔就永久清路徑**:否決,N1、N9 的來源。 +- **跨網址接續續傳**:否決。網址過期就重解析、從頭下載;音檔多為數 MB。 + +## 決定 + +1. **引擎**:`background_downloader`。 + - Android 在背景繼續下載(WorkManager,Android 14+ 使用者發起工作並顯示通知)。 + - 桌面只在 App 執行中下載:最小化或縮到托盤照常,關閉即暫停,下次啟動自動續傳。 + - 請求帶插件候選串流的標頭、不帶帳號憑證(ADR 0012)。這是網路層之外唯一的 HTTP 出口:下載網址寫 log 前經 ADR 0011 的遮蔽函式,測試以假的下載器介面注入。 + - 同時下載數 1–5(預設 3)、同一主機最多 2;事件驅動,不輪詢。 +2. **流程**:建立紀錄 → 經插件 `resolveStream`(用途=下載、不走記憶體網址快取)→ 下載到 App 私有暫存 → 寫內嵌標籤與 sidecar → 搬到最終位置 → 完成。 + 最終資料夾不會出現半成品。 +3. **續傳與失敗**: + - 續傳以強 ETag 驗證,不符或不支援就從頭下載;網址過期或 403 時重解析一次、從頭下載; + - 網路錯誤以指數退避重試 2 次; + - 失敗與暫停任務跨重啟保留,直到使用者重試或清除。 +4. **組織與命名**:每首歌只存一份,依音源(插件 id)分資料夾。 + - 單曲:`{根目錄}/{音源}/{標題} [{影片 id}].{副檔名}`; + - 多分 P:`{根目錄}/{音源}/{影片標題} [{影片 id}]/P01 {分P標題}.{副檔名}`。 + + 標題截到 80 字以符合 Windows 路徑上限。紀錄存絕對路徑;「已下載」頁的歌單分類由資料庫關聯算出。 +5. **根目錄**: + - 預設 Android `Music/FMP`、Windows `%USERPROFILE%\Music\FMP`、Linux XDG 音樂目錄下 `FMP`;舊資料匯入沿用舊下載目錄。 + - Android 可在設定頁更改並重新授權;更改時選「搬移現有下載」或「只改之後的位置」。 + - Android 以 `MANAGE_EXTERNAL_STORAGE`+路徑寫入。 +6. **格式與標籤**:下載只接受 m4a(AAC)、flac、mp3,YouTube 下載取 AAC;播放不受影響。 + - 副檔名照實際格式; + - 內嵌標題、歌手(音源回報的值)、專輯(多分 P 用影片標題)、封面、來源網址(候選 `audio_metadata_reader`); + - sidecar 保留:同檔名 `.json`(曲目鍵、音源、影片 id、分 P、標題、時長、下載時間)、`.jpg` 封面,選項開啟時另存 `.avatar.jpg`。 +7. **與音樂庫的關聯**:`downloads` 表以曲目鍵關聯(ADR 0019 的孤兒判定納入它)。刷新移出歌單不刪下載;下載只由使用者在下載頁刪除(檔案、sidecar、紀錄)。 +8. **啟動對帳**(登記在啟動維護清單,ADR 0017): + - 檔案不在就標「檔案遺失」、不刪紀錄,播放改走線上,並提供重新下載或移除紀錄; + - 根目錄不可用就標「儲存位置無法使用」、不動紀錄; + - 有 sidecar 或檔名帶影片 id 但沒紀錄的檔案,自動建立紀錄並認回曲目; + - 對帳永遠不自動刪檔或刪紀錄。 + + 舊下載檔留在原位,匯入時依舊 sidecar 建立紀錄。 +9. **權限統一入口**:平台層 `PermissionGateway` 依能力宣告需要的權限: + - 下載資料夾寫入(Android `MANAGE_EXTERNAL_STORAGE`); + - 下載通知(Android 13+ `POST_NOTIFICATIONS`,第一次下載時請求); + - 安裝更新(`REQUEST_INSTALL_PACKAGES`)。 + + 流程固定為說明 → 請求 → 被拒時說明影響並提供「前往系統設定」→ 回到 App 時重新檢查,永久拒絕另外處理。 + 通知被拒照樣下載;儲存被拒不開始下載並引導設定。Android 用 `permission_handler`(見「如何確認」的 Windows 實測)。 +10. **設定**:下載音質(高/中/低,預設高)與播放分開;同時下載數、下載圖片選項、根目錄沿用。 + +採用的慣例:Finamp、Namida、NewPipe 的「資料庫記錄+啟動對帳」;NewPipe 的下載前景通知與權限說明;RFC 9110 的 `If-Range`/強 ETag 續傳語意; +`background_downloader` 官方的暫存與背景模型。 + +## 後果 + +- 好的: + - 同一首歌不重複佔空間;歌單改名、刷新移除都不影響檔案; + - 對帳不再遺失資料; + - 所有下載檔都有正確副檔名與標籤; + - Android 背景可下載; + - 權限流程一致。 +- 壞的: + - Windows 關掉 App 就不下載; + - YouTube 下載不是最高位元率; + - 在 App 外面看,資料夾不依歌單分組; + - 下載是網路層之外的一個 HTTP 出口,要靠遮蔽與測試介面守住。 +- 之後要注意:iOS/macOS 的下載位置與「檔案」App 可見性由該平台任務定;已下載內容的容量管理在功能凍結待辦。 + +## 如何確認 + +- 單元測試(假下載器): + - 並行上限;失敗任務跨重啟保留; + - 網址過期時重解析並從頭下載;ETag 不符從頭下載; + - 格式過濾;暫存 → 標籤 → 搬移任一步失敗時最終資料夾沒有半成品。 +- 對帳測試: + - 檔案遺失不刪紀錄;根目錄不可用不動紀錄; + - 無紀錄的檔案依 sidecar 或檔名認回; + - 從不刪檔。 +- 路徑測試:檔名清理、Windows 路徑長度、保留名。 +- 權限流程測試(假的 `PermissionGateway`):拒絕、永久拒絕、從設定回來重新檢查。 +- 依賴方向(`fmp_layer_imports`,ADR 0015):`background_downloader` 只在下載模組、`permission_handler` 只在平台層。 +- 加入下載的里程碑實測: + - `permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單,會就改為 Android 專用的自有 MethodChannel; + - 寫入的標籤能被常見播放器讀到; + - Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾可行。 From 96386e34680f6fc9b284ed4f2b3678e1e58f7ec1 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:08:05 +0800 Subject: [PATCH 065/133] chore(task): archive design-downloads --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 11 ++++++----- .trellis/tasks/09-28-design-downloads/implement.md | 13 ------------- .../2026-09}/09-28-design-downloads/check.jsonl | 0 .../2026-09}/09-28-design-downloads/design.md | 0 .../2026-09}/09-28-design-downloads/implement.jsonl | 0 .../2026-09/09-28-design-downloads/implement.md | 13 +++++++++++++ .../2026-09}/09-28-design-downloads/prd.md | 0 .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../09-28-design-downloads/research/prior-art.md | 0 .../2026-09}/09-28-design-downloads/task.json | 6 +++--- 11 files changed, 22 insertions(+), 21 deletions(-) delete mode 100644 .trellis/tasks/09-28-design-downloads/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/implement.jsonl (100%) create mode 100644 .trellis/tasks/archive/2026-09/09-28-design-downloads/implement.md rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-downloads/task.json (88%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 004ed8543..22f32bbe8 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -123,7 +123,7 @@ flowchart LR | 11 | 16 背景任務(✅ 完成,ADR 0017) | 刷新、清理、更新檢查誰來排程。 | | 12 | 13 播放核心(✅ 完成,ADR 0018) | 最大的一塊;依賴 1、2、10、17。 | | 13 | 14 音樂庫與同步(✅ 完成,ADR 0019) | B1/B2 已定方向,細節依賴 6、1、12、16。 | -| 14 | 11 下載與權限 | 依賴播放核心的本地播放路徑。 | +| 14 | 11 下載與權限(✅ 完成,ADR 0020) | 依賴播放核心的本地播放路徑。 | | 15 | 15 歌詞 | 依賴 1、13。 | | 16 | 19 發版與更新 | 依賴 10、16;你已給出流程要求。 | | 17 | 3 Toast | 依賴 2、18。 | @@ -231,6 +231,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。 - ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 - ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 +- ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -239,10 +240,10 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 10. 目前進度與下一步(交接用,2026-09-27) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0019`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0020`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- **進行中:第 11 項「下載與權限」**,task `.trellis/tasks/09-28-design-downloads/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 -- 之後順序:15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 下一項:第 15 項「歌詞」(尚未建 task)。 +- 之後順序:19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-28-design-downloads/implement.md b/.trellis/tasks/09-28-design-downloads/implement.md deleted file mode 100644 index 6b619836d..000000000 --- a/.trellis/tasks/09-28-design-downloads/implement.md +++ /dev/null @@ -1,13 +0,0 @@ -# 執行計畫:第 11 項(設計任務,只產出文件) - -1. 核准後寫 `docs/adr/0020-downloads-and-permissions.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9;被否決的方案: - 自寫 isolate 下載器、`flutter_downloader`(無桌面)、SAF URI 下載(不能續傳)、依歌單分資料夾、依歌手分資料夾、下載最高音質含 Opus、 - 啟動掃描以資料夾名重建關聯、掃不到就清路徑、播放時找不到檔就永久清路徑。說明它延續舊 ADR 0004 的 Android 儲存做法、適用於 `app/`。 -2. ADR 0014/0018:`resolveStream` 輸入加上用途(播放/下載)。ADR 0009:`PermissionGateway` 與權限能力宣告指向 ADR 0020。 -3. `phase2-plan.md`:§3 第 11 項標 ✅(ADR 0020);§8 延後實測加入「加入下載的里程碑:`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單; - `audio_metadata_reader` 寫入的標籤能被常見播放器讀到;`background_downloader` 在 Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾」; - §10 交接段更新,下一項 15 歌詞。 -4. 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 -5. `task.py finish`、`task.py archive design-downloads --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 - -回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-downloads/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-downloads/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-downloads/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/check.jsonl diff --git a/.trellis/tasks/09-28-design-downloads/design.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/design.md similarity index 100% rename from .trellis/tasks/09-28-design-downloads/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/design.md diff --git a/.trellis/tasks/09-28-design-downloads/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-downloads/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-downloads/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/implement.jsonl diff --git a/.trellis/tasks/archive/2026-09/09-28-design-downloads/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/implement.md new file mode 100644 index 000000000..f139fc8c2 --- /dev/null +++ b/.trellis/tasks/archive/2026-09/09-28-design-downloads/implement.md @@ -0,0 +1,13 @@ +# 執行計畫:第 11 項(設計任務,只產出文件) + +1. [x] 核准後寫 `docs/adr/0020-downloads-and-permissions.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9;被否決的方案: + 自寫 isolate 下載器、`flutter_downloader`(無桌面)、SAF URI 下載(不能續傳)、依歌單分資料夾、依歌手分資料夾、下載最高音質含 Opus、 + 啟動掃描以資料夾名重建關聯、掃不到就清路徑、播放時找不到檔就永久清路徑。說明它延續舊 ADR 0004 的 Android 儲存做法、適用於 `app/`。 +2. [x] ADR 0014/0018:`resolveStream` 輸入加上用途(播放/下載)。ADR 0009:`PermissionGateway` 與權限能力宣告指向 ADR 0020。 +3. [x] `phase2-plan.md`:§3 第 11 項標 ✅(ADR 0020);§8 延後實測加入「加入下載的里程碑:`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單; + `audio_metadata_reader` 寫入的標籤能被常見播放器讀到;`background_downloader` 在 Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾」; + §10 交接段更新,下一項 15 歌詞。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染(設計圖已驗);`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-downloads --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-downloads/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-downloads/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/prd.md diff --git a/.trellis/tasks/09-28-design-downloads/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-downloads/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/research/current-state.md diff --git a/.trellis/tasks/09-28-design-downloads/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-downloads/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-downloads/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-downloads/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-downloads/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-downloads/task.json b/.trellis/tasks/archive/2026-09/09-28-design-downloads/task.json similarity index 88% rename from .trellis/tasks/09-28-design-downloads/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-downloads/task.json index 5c1779ba2..1c02ed8f0 100644 --- a/.trellis/tasks/09-28-design-downloads/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-downloads/task.json @@ -3,7 +3,7 @@ "name": "design-downloads", "title": "Design: downloads and permissions", "description": "Phase-2 item 11: download queue and resume, storage abstraction per platform, file format and tags, permission requests through one entry point", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 28596b5c8ebdac5e758fec51910c359c4f87970b Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:08:40 +0800 Subject: [PATCH 066/133] chore(task): start design-lyrics --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../tasks/09-28-design-lyrics/check.jsonl | 0 .../tasks/09-28-design-lyrics/implement.jsonl | 0 .trellis/tasks/09-28-design-lyrics/prd.md | 19 ++++++++++++++ .trellis/tasks/09-28-design-lyrics/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-design-lyrics/check.jsonl create mode 100644 .trellis/tasks/09-28-design-lyrics/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-lyrics/prd.md create mode 100644 .trellis/tasks/09-28-design-lyrics/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 22f32bbe8..ca3648f79 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -243,7 +243,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0020`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 -- 下一項:第 15 項「歌詞」(尚未建 task)。 +- **進行中:第 15 項「歌詞」**,task `.trellis/tasks/09-28-design-lyrics/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 5bf55c2ec..252b6435a 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -33,7 +33,8 @@ "09-27-design-background-tasks", "09-27-design-playback-core", "09-28-design-library-sync", - "09-28-design-downloads" + "09-28-design-downloads", + "09-28-design-lyrics" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-lyrics/check.jsonl b/.trellis/tasks/09-28-design-lyrics/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-lyrics/implement.jsonl b/.trellis/tasks/09-28-design-lyrics/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md new file mode 100644 index 000000000..16f531dd2 --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -0,0 +1,19 @@ +# Design: lyrics + +## Goal + +Phase-2 item 15: lyrics sources as plugins, matching with the shared scorer, cache, display, desktop lyrics window, AI features + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-lyrics/task.json b/.trellis/tasks/09-28-design-lyrics/task.json new file mode 100644 index 000000000..7aea526fc --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-lyrics", + "name": "design-lyrics", + "title": "Design: lyrics", + "description": "Phase-2 item 15: lyrics sources as plugins, matching with the shared scorer, cache, display, desktop lyrics window, AI features", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From b07e091286d104c7435ac43bdf4b4936e9afede8 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:09:30 +0800 Subject: [PATCH 067/133] chore(task): refresh the phase-two handoff note --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index ca3648f79..2a43b5d97 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -238,12 +238,19 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27),是功能凍結的唯一例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-27) +## 10. 目前進度與下一步(交接用,2026-09-28 更新) - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0020`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-27-design-*`。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0021(歌詞)。 - **進行中:第 15 項「歌詞」**,task `.trellis/tasks/09-28-design-lyrics/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 - 之後順序:19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 +- 工作守則(本輪累積): + - 使用者不是專業開發者:問題用白話、給具體例子(例如資料夾結構範例),選項附建議與代價;使用者提出反例時(例如 B 站、YouTube 的「歌手」其實是上傳者)要修正方案再問,不要辯護原方案。 + - 使用者對 `questions.md` 的勾選可能誤讀題意(例如 D7 勾「保留」其實是保留功能):勾選與推薦方向矛盾時,先用程式碼確認現況再請使用者確認。 + - 研究子代理的結論要抽查(例如它曾誤稱 ExoPlayer 不支援 FLV,官方格式表為支援、不可 seek),更正寫進 prd。 + - 子代理因額度中斷:先 SendMessage 續跑;使用者手動停掉的代理不能續跑,使用者要求時才重新發起,並告知保留已寫的研究檔。 + - 更新他項 ADR 的引用時只加一句指向新 ADR,不改原決定;新 lint 規則補記到 ADR 0015 的「後續 ADR 新增的規則」。 + - 每項最終摘要需列:你已定的、技術選擇(在核准範圍內)、放進待辦、不在範圍、核准後會做什麼、下一項。 From 60d6cd05a69287f420e2d8acf6b37c5f90a116b5 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 02:24:56 +0800 Subject: [PATCH 068/133] chore(task): add lyrics research and draft requirements --- .trellis/tasks/09-28-design-lyrics/prd.md | 64 ++- .../research/current-state.md | 154 ++++++ .../research/packages-and-platform.md | 274 ++++++++++ .../09-28-design-lyrics/research/prior-art.md | 474 ++++++++++++++++++ 4 files changed, 955 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-lyrics/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-lyrics/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index 16f531dd2..6a91f16fa 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -1,19 +1,61 @@ -# Design: lyrics +# 設計:歌詞(階段二第 15 項) -## Goal +## 目標 -Phase-2 item 15: lyrics sources as plugins, matching with the shared scorer, cache, display, desktop lyrics window, AI features +為 `app/` 定下歌詞源(插件能力)、自動匹配與手動改選、偏移、格式與解析、顯示、桌面歌詞視窗、AI 功能的形狀。產出 ADR 0021。技術設計見 `design.md`,執行步驟見 `implement.md`。 -## Requirements +依據:parent `prd.md` 階段二第 15 項;`docs/audit/questions.md` E9–E11(皆保留)、B5;`phase2-plan.md` §6 的 B5 方向與 §8 平台功能; +ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分組)、0012(第三方歌詞源不帶登入)、0014(`lyrics` 能力、共用匹配)、 +0016(歌詞內容進統一快取、匹配結果在主資料庫)、0019(共用評分核心、`track_origins`)。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對,另見 `docs/audit/features.md` §6) -## Acceptance Criteria +- 三個歌詞源(網易、QQ、lrclib)是三個獨立 Dart 類別,沒有共同介面,字串分派 5 處;lrclib 預設停用。 + 曲目有原始平台 id 時直接抓、跳過搜尋(`lyrics_auto_match_service.dart:104-151`)。 +- 自動匹配預設關,開播時在背景跑;評分為標題 40%/歌手 30%/時長 20%/有同步 10%,Levenshtein,門檻 0.6,±20 秒;只有一個候選就直接用(`:701-703,841-895`)。 +- 手動搜尋:底部面板,「全部」並行搜所有啟用源,依使用者排序串接;選定後寫 `LyricsMatch`(`offsetMs=0`)並換掉快取內容。 +- 偏移存在匹配紀錄上,正值=歌詞提前;播放頁 ±100/500/1000ms;桌面視窗可右鍵某行校正。 +- 只有 LRC 與純文字,**沒有逐字**;網易有翻譯+羅馬音、QQ 只有翻譯、lrclib 都沒有;以時間戳相等合併,顯示模式原文/優先翻譯/優先羅馬音。 +- 標題解析器(正則,3 種模式)把影片標題拆成曲名與歌手。 +- AI 兩種模式(預設關):「標題解析」只送標題與上傳者;「候選挑選」再送時長、所有候選(含每首最多 8 行/500 字的歌詞預覽)。 + 使用者自填 OpenAI 相容端點,key 在 secure storage;**端點不驗 https**(`openai_chat_endpoint.dart:1-6`),**payload 與回應原文在 debug 級別寫進 log**(`ai_lyrics_selector.dart:116,145`、`ai_title_parser.dart:57,73`)。 +- 桌面歌詞視窗(`desktop_multi_window` 0.3.1、獨立 engine)**只開在 Windows**,按鈕沒有平台守衛;有置頂、透明、hover 才顯示工具列、單行模式、11 項樣式; + **沒有點擊穿透、沒有鎖定**。主視窗推資料的程式碼掛在 `TrackDetailPanel` 的 `ref.listen`,同步綁在 UI 生命週期上。 + 字串以 map 推送,舊 static-rule `lyrics_window_strings` 守「讀的 key=推的 key」。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- 歌詞源插件化:MusicFree、LX、BetterLyrics。純歌詞插件的介面很窄:搜尋吃(標題、歌手、專輯、時長),取用吃 id;搜尋與取用分開才做得出候選清單。 +- 候選清單+手動改選:Namida、MusicFree、BetterLyrics 有,改選結果都持久化;LX、Spotube、Harmonoid 沒有。 +- 逐字格式現實只有 QQ QRC、酷狗 KRC、網易 YRC;LRC 是唯一共同下限(lrclib 只給逐行)。`flutter_lyric` 3.0.8(2026-09-16)解析 LRC/QRC/YRC 並含渲染元件,沒有 KRC 的 Dart 套件;`lyrics_parser` 與 Dart 3 不相容。 +- 桌面歌詞真正做到三平台的只有 LX(Electron `setIgnoreMouseEvents`,Linux 還要輪詢游標);沒有穿透的產品(Namida、Spotube)改用 hover 顯示控制列。 +- Flutter 官方多視窗 API(2026-08-24 公告)只在 `main` channel、標示實驗性;穩定路線仍是 `desktop_multi_window` 0.3.1(2026-08-26,Windows/macOS/Linux)。 +- `window_manager` 0.5.2 的 Linux 後端沒有 `setIgnoreMouseEvents`(已核對原始碼);Linux 透明靠 GTK CSS,#179(Arch 上透明變黑)2026-09-21 以 not planned 關閉。 + Wayland 的 XDG shell 刻意不給全域定位與置頂;GTK3+Wayland 下置頂是否生效取決於 compositor,要實機驗證。 +- Android 懸浮窗是使用者手動授予的特殊權限,12、15 持續收緊;iOS 沒有可顯示歌詞的系統級浮窗(PiP 只接受影片)。 +- 七個成熟產品沒有一個用 LLM 做歌詞匹配;BetterLyrics 的 `SongSearchMap` 記「用什麼查詢、查哪個來源」而非結果。 +- OpenAI「不要把 key 放在客戶端」指的是開發者把自己的 key 內嵌進 App;FMP 是使用者自帶 key(存在自己裝置的 secure storage),不是這種情形。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +研究更正:研究初稿說 B5 勾「修改」,實際 `questions.md:119` 勾的是「不確定」,已在 `current-state.md` 更正;方向以 `phase2-plan.md` §6 為準。 + +## 已確定的方向 + +- E9–E11 保留;歌詞源全部是插件的 `lyrics` 能力(ADR 0014),匹配用共用評分核心、結果持久化、改選後不再重算(ADR 0014 決定 9、ADR 0019 決定 6)。 +- 歌詞內容在統一快取(鍵為歌詞插件+歌詞 id),匹配結果在主資料庫,淘汰後以存下的 id 重抓(ADR 0016)。 +- B5:AI 保留、預設關;強制 https;payload 不寫進 log;送出的欄位最小化並在設定頁列出(`phase2-plan.md` §6)。 +- 桌面歌詞視窗以平台能力宣告,目標是所有桌面平台一致(ADR 0009、`phase2-plan.md` §8)。 + +## 待決定 + +1. AI 保留哪幾種模式(標題解析、候選挑選)。 + +## 不在範圍(功能凍結,列入待辦) + +- 逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android 懸浮歌詞與狀態列歌詞、本機歌詞檔匯入:舊專案都沒有,屬新功能。 +- 歌詞頁與視窗的版面(第 5 項)。 + +## 驗收條件 + +- [ ] ADR 0021 記錄:歌詞插件介面、自動匹配與手動改選、偏移、格式與解析、顯示與同步來源、桌面歌詞視窗與平台差異、AI 功能與隱私、快取與持久化。 +- [ ] E9–E11、B5 各自對到決定。 +- [ ] `phase2-plan.md` §3 第 15 項標 ✅ 與 ADR 編號。 diff --git a/.trellis/tasks/09-28-design-lyrics/research/current-state.md b/.trellis/tasks/09-28-design-lyrics/research/current-state.md new file mode 100644 index 000000000..ad6f7db87 --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/research/current-state.md @@ -0,0 +1,154 @@ +# 舊專案的歌詞(current state) + +- 查證日期:2026-09-28 +- 查證方式:讀 `docs/audit/`(`features.md` §6/§15、`sources.md`、`data.md`、`platforms.md` §1.3/§3.7、`questions.md` B5/E9–E11)、`docs/adr/`(0009–0020)、`lib/services/lyrics/`、`lib/providers/lyrics/`、`lib/ui/windows/`、`lib/ui/widgets/lyrics/`、`lib/services/audio/` 與 `test/services/static_rules/lyrics_window_strings_static_rule_test.dart` 逐檔核對。未執行 App、未跑測試、未打 API。 +- 舊專案狀態:`docs/audit/questions.md:247-249` 記 E9(多源搜尋/自動匹配/手動選擇)、E10(AI 歌詞匹配/標題解析)、E11(桌面歌詞視窗)三項擁有者都勾「保留」;B5(`questions.md:119`)勾「不確定」,方向見 `phase2-plan.md` §6。本檔描述的是被重寫的那份實作。 + +## 1. 歌詞源與取得流程 + +三個歌詞源是**三個各自獨立的 Dart 類別,沒有共同介面**,靠字串 `'netease' / 'qqmusic' / 'lrclib'` 分派(`docs/audit/sources.md:71`;`lib/services/lyrics/lyrics_auto_match_service.dart:278-300,444-461`)。分派點共 5 處(`sources.md:287`)。 + +| 源 | 端點 | 取得方式 | 證據 | +|---|---|---|---| +| 網易雲 | `https://music.163.com/api/search/get`(搜尋,POST 表單)、`/api/song/lyric`(歌詞,GET `lv=1&tv=1&rv=1`) | 搜尋 → 逐首抓歌詞,兩步 | `lib/services/lyrics/netease_source.dart:13-14,131,166-174,214-222` | +| QQ 音樂 | `https://u.y.qq.com/cgi-bin/musicu.fcg`(搜尋 `DoSearchForQQMusicDesktop`、歌詞 `GetPlayLyricInfo`,皆 POST JSON) | 搜尋 → 逐首抓歌詞;歌詞欄位 base64 解碼+HTML entity 解碼 | `lib/services/lyrics/qqmusic_source.dart:10-19,130-152,178-206,295-335` | +| lrclib | `https://lrclib.net/api`(`/search`、`/get/`、`/get` 精確匹配),**無 API key** | 一次搜尋直接回結果(含歌詞內容) | `lib/services/lyrics/lrclib_source.dart:20-24,46-127` | + +- **原始平台 id 直取**:舊專案已有這條路,但欄位名不是 `track_origins`。`Track` 上有 `originalSongId` + `originalSource`(`docs/audit/data.md:36`;`lib/data/models/track.dart:264,267`),匯入歌單時寫入(`lib/data/repositories/playlist_mutation_repository.dart:749-760`)。自動匹配時若兩者非 null 且該源已啟用,直接 `getLyricsResult(id)` 跳過搜尋(`lyrics_auto_match_service.dart:130-151`、`_tryDirectFetch` `:643-672`);失敗才退回搜尋。另有更早的一條特例:`sourceType == 'netease'` 的曲目直接用 `track.sourceId` 抓(`:104-127`)。`_tryDirectFetch` 明確標「Spotify 無歌詞 API」故不支援(`:642,658-659`;`sources.md:43`)。 +- **兩條直取路的差別**:`:104-127` 認 `sourceType`(曲目所屬平台),`:130-151` 認 `originalSource`(匯入時記下的原始平台)。前者是網易曲目、後者是外部匯入曲目。 +- lrclib 預設**停用**(`disabledLyricsSources` 預設 `'lrclib'`,`data.md:345`);預設優先序 `netease,qqmusic,lrclib`(`data.md:344`;同一字串寫在 4 檔 6 處,`sources.md:291`)。lrclib 的 User-Agent 是佔位網址 `FMP/1.0.0 (https://github.com/user/fmp)`(`lrclib_source.dart:24`;`features.md:445` 列為不一致)。 +- 網易與 QQ 都標註「非官方 API,可能隨時變更,僅供學習研究」(`netease_source.dart:16-17`、`qqmusic_source.dart:18-19`)。 + +## 2. 自動匹配:觸發時機、評分、門檻 + +**觸發**:每次開始播一首新歌,由 `LyricsAutoMatchCoordinator.onTrackStarted` 在背景 fire-and-forget 跑,播放路徑不等它(`lib/services/audio/lyrics_auto_match_coordinator.dart:8-10,37-39,48-86`)。設定開關 `autoMatchLyrics` **預設關**(`data.md:341`;`lyrics_auto_match_coordinator.dart:57`)。coordinator 由 `AudioController` 接線(`lib/services/audio/audio_provider.dart:191,1404`)。 + +**前置條件**:已有匹配就跳過(`lyrics_auto_match_service.dart:90-94`);同一首歌用 `_matchingKeys` 防併發(`:65,82-86`);無啟用源就跳過(`:98-101`)。 + +**流程分支**(`lyrics_auto_match_service.dart:72-196`): +1. 網易曲目 sourceId 直取(`:104-127`)→ 2. `originalSongId` 直取(`:130-151`)→ 3. 看 AI 模式: + - `off`(預設)→ 正則標題解析後搜尋(`:192-196`) + - `alwaysAi` → AI 標題解析後搜尋,AI 失敗退回正則(`:156-171`) + - `advancedAiSelect` → AI 標題解析後,**把所有候選送 LLM 挑**,失敗退回正則(`:173-190`) + +**評分(`_calculateScore`,`:851-895`)**:標題相似度 40% + 歌手相似度 30% + 時長分 20% + 有無同步歌詞 10%。時長分為階梯:≤3s → 1.0、≤10s → 0.8、≤容差 → 0.5、否則 0;容差是 `AppConstants.lyricsDurationToleranceSec`(**±20 秒**,`:692-696,777-781`)。相似度是 Levenshtein 正規化(`:900-944`),無 NFKC、無繁簡統一、無多歌手拆分 —— 這些是重寫後共用評分核心才加的(ADR 0019 決定 6)。 + +**門檻**:多個候選才評分,最高分須 ≥ `AppConstants.lyricsMatchScoreThreshold`(**0.6**)才採用(`:841-847`);只有一個候選就直接用(`:701-703`)。網易/QQ 源結果 `duration == 0` 時**跳過時長過濾當作合格**(`:693,736`)。 + +**允許純文字歌詞**:`allowPlainLyricsAutoMatch` 預設 false(`data.md:347`);未開時只接受有同步歌詞的結果(`_isAllowedLyricsResult`,`:223-229`)。 + +**結果寫入**:`_saveMatch` 同時寫歌詞內容快取(key 為 `track.uniqueKey`)與主資料庫 `LyricsMatch`(`lyricsSource`、`externalId`、`offsetMs=0`、`matchedAt`)(`:624-638`)。 + +## 3. 手動搜尋與選擇 + +- 入口:曲目選單「匹配歌詞」、播放頁「更多」(`features.md:166`)。UI 是 `showModalBottomSheet` 開的 `LyricsSearchSheet`(`lib/ui/pages/lyrics/lyrics_search_sheet.dart:21-30`)。 +- 篩選:頂部 `FilterChip` 列「全部 + 各源」(`lyrics_search_sheet.dart:77-150`),來源順序取自 `lyricsSourceOrderProvider`(`lib/providers/audio/audio_settings_provider.dart:348`);被停用的源仍顯示但標為 disabled(`lyrics_search_sheet.dart:78,138`)。每源的圖示/名稱是**寫死的 switch**(`:87-110`,`sources.md:333-335` 列為音源分支)。 +- 搜尋:「全部」時按使用者優先序**並行**搜所有啟用源,再按優先序串接結果;單源時只搜該源;單源被停用則回空(`lib/providers/lyrics/lyrics_provider.dart:347-493`)。有 request id 防取代(`:383,483,487`)。 +- 選定:點結果 `saveMatch` → 寫 `LyricsMatch`(`offsetMs=0`)並**先刪舊快取再寫新內容**,避免重新匹配後讀到舊歌詞(`lyrics_provider.dart:496-513`)。 +- 移除匹配:`removeMatch` 只刪資料庫那筆(`:513-516`)。 + +## 4. 偏移(offset)調整與保存 + +- 保存位置:`LyricsMatch.offsetMs`(Isar 欄位,`docs/audit/data.md:46,359`)。語意為 `adjustedMs = position + offsetMs`,正值=歌詞提前(`lib/services/lyrics/lrc_parser.dart:166,177`)。 +- 主視窗:播放頁「更多」有偏移入口(`features.md:167`);`lyrics_offset_bar.dart` 提供 ±100/500/1000ms 與重設(`lib/ui/widgets/lyrics/lyrics_offset_bar.dart:11,23`);點歌詞行可 seek 到 `timestamp - offsetMs`(`lib/ui/widgets/lyrics/lyrics_display.dart:416-426`)。 +- 桌面歌詞視窗:有偏移列(±)、點行跳轉、**右鍵某行校正偏移**(`features.md:170`)。校正公式 `line.timestamp - positionMs`,抽在 `LyricsOffsetMath.calibrationOffsetForLine`(`lib/ui/widgets/lyrics/lyrics_offset_math.dart:13,18`;子視窗 `_calibrateOffsetToLine` `lib/ui/windows/lyrics_window.dart:435`)。 +- 子視窗改 offset 是**經 IPC 回主視窗**由 `LyricsSearchNotifier.updateOffset` 寫入資料庫(`lyrics_window.dart:448` → `lyrics_window_service.dart:479-485` → `lyrics_provider.dart:519-521`)。 +- 顯示端只在 `externalId` 變時重抓內容,offset 變不重抓(`lyrics_provider.dart:134-146`)。 + +## 5. 歌詞格式、解析器、逐字/翻譯/羅馬音 + +- **只有 LRC 與純文字**。解析器是 `lib/services/lyrics/lrc_parser.dart`:時間戳正則 `\[(\d{1,2}):(\d{2})\.(\d{2,3})\]`(`:49`),一行多時間戳展開成多行(`:83-111`),2 位毫秒 ×10(`:99-102`),解析後排序(`:115`)。無時間戳則整首當純文字(`:120-131`)。二分搜尋找當前行(`:169-195`)。 +- **逐字歌詞沒有實作**。全 `lib/`(不含 `*.g.dart`)grep `yrc` / `qrc` / `krc` / `逐字`(歌詞義)/`karaoke` / `verbatim` 皆無命中。網易只要求 `lv/tv/rv`,**沒有 `yv`(逐字)**(`netease_source.dart:214-222`);QQ 的 `GetPlayLyricInfo` 只取 `lyric` 與 `trans`,**沒有 qrc/roma**(`qqmusic_source.dart:203-207`)。`LyricsResult` 也只有 `plainLyrics` / `syncedLyrics` / `translatedLyrics` / `romajiLyrics` 四欄,**沒有逐字欄位**(`lyrics_result.dart:2-20`)。 +- **翻譯與羅馬音**:`LyricsResult` 有 `translatedLyrics` 與 `romajiLyrics` 兩欄(`:16-20`)。網易同時取翻譯(`tlyric`)與羅馬音(`romalrc`)(`netease_source.dart:89-92,215-221`);**QQ 只有翻譯、沒有羅馬音**(`qqmusic_source.dart:71,206,268`);lrclib 兩者皆無(`lrclib_source.dart` 只填 `plainLyrics`/`syncedLyrics`)。 +- **合併方式**:以毫秒時間戳對齊,把附加歌詞塞進對應行的 `subText`(`lrc_parser.dart:137-160`,`LyricsLine.subText` `:12-18`);顯示模式 `original` / `preferTranslated` / `preferRomaji`(enum `lib/ui/windows/lyrics_display_mode.dart:9-32`),選附加文本的優先序在 `lyrics_provider.dart:227-240`。已解析結果會被 provider 快取,避免每次 position tick 重解析(`lyrics_provider.dart:245`)。 +- 純音樂判定:網易歌詞含「纯音乐,请欣赏」即視為 instrumental(`netease_source.dart:100-101`)。 +- 標題解析器(把 B 站/YouTube 影片標題拆成曲名/歌手)是 `lib/services/lyrics/title_parser.dart`:`RegexTitleParser` 一組中日文標籤詞(`:46-52`)與 3 種擷取模式 —— 模式 A `Artist - Title`(`:109`)、模式 B `Artist「Title」`(`:112`)、模式 C `Title / Artist`(`:115`),加上括號/後綴清理,全失敗則整串當歌名(`parse` `:127`)。介面 `TitleParser` 設計上可換 AI 實作(`:34,39`)。 + +## 6. AI 功能(E10 / B5) + +兩種模式,由 `LyricsAiTitleParsingMode` 控制:`off` / `alwaysAi`(只做標題解析)/ `advancedAiSelect`(標題解析+候選挑選)(`docs/audit/features.md:169`;`lyrics_auto_match_service.dart:156,174`)。UI 在歌詞來源設定頁(`features.md:233`)。**預設 off**(`data.md:346`)。 + +**送出的欄位**: + +| 用途 | 送出內容 | 證據 | +|---|---|---| +| 標題解析 | `title`、非空的 `uploader` | `ai_title_parser.dart:46-50` | +| 候選挑選 | `title`、`uploader`、`videoDescription`(截 500 字,目前傳 null)、`durationSeconds`、`sourcePriority`、`allowPlainLyricsAutoMatch`、`candidates[]`(id、source、優先序、曲名、歌手、專輯、時長、時長差、四種歌詞有無、**歌詞預覽**) | `ai_lyrics_selector.dart:106-116`;候選欄位 `:8-57`;預覽最多 8 行/500 字,跳過時間戳與 metadata 行(`lyrics_auto_match_service.dart:492-550`) | + +- **傳送去向**:使用者自填的 OpenAI 相容端點,`Authorization: Bearer `,`temperature 0.1`,system prompt 要求回嚴格 JSON(`lib/services/lyrics/openai_chat_client.dart:41-68`)。回應解析容忍 ```json 圍欄(`:82`)。 +- **API key 存放**:secure storage,鍵 `lyrics_ai_api_key`(`lyrics_ai_config_service.dart:32,70-82`;`data.md:202,351`)。**不在** Settings、**不在**備份(`features.md:273`)。讀不到金鑰時丟 `SecureStorageUnavailable` 不吞成空字串(`:66-72`)。 +- **endpoint / model / timeout 存 Settings**(`lyricsAiEndpoint` / `lyricsAiModel` / `lyricsAiTimeoutSeconds`,預設 timeout 20s),**AI endpoint 與 model 會進備份**(`data.md:348-350`;`features.md:298`)。 +- **B5 的三個問題(現況即缺點)**: + 1. **端點不強制 https**:`normalizeOpenAiChatCompletionsEndpoint` 只 trim 尾斜線並補 `/chat/completions`,不檢查 scheme(`openai_chat_endpoint.dart:1-6`);設定頁也**沒有** https 驗證(`lib/ui/pages/settings/lyrics_source_settings_page.dart` grep `https`/`validator`/`errorText` 皆無命中)。 + 2. **debug 級別整份 payload 寫進 log**:`ai_lyrics_selector.dart:116`(含候選與歌詞預覽)、`ai_title_parser.dart:57`;另有回應原文 `ai_lyrics_selector.dart:145`、`ai_title_parser.dart:73`。ADR 0011 開頭把這件事列為舊專案的隱私缺陷(`docs/adr/0011-settings-and-logging.md:9-10`)。 + 3. **影片描述欄位存在但未使用**:`videoDescription: null` 寫死(`lyrics_auto_match_service.dart:394`),`ai_lyrics_selector.dart:94-98` 支援截 500 字。 +- **`LyricsTitleParseCache`**:AI 標題解析結果的持久化快取(`trackUniqueKey` unique、`parsedTrackName`、`parsedArtistName`、`confidence`、`provider`、`model`、時間戳;`data.md:47`)。先查快取再呼叫 LLM(`_titleParseCacheRepo.getReusable` `lyrics_auto_match_service.dart:556-561`、寫入 `:588`;資料庫不可用時直接回 null `:558`)。每次啟動都會跑 `_relinkLyricsMatchesToCidKeys` 修補鍵(`data.md:166`,見 §8 鍵的變動)。 +- **artist 信心門檻**:AI 回 `artistName` 需 `artistConfidence >= 0.8` 才採用,否則丟棄(`ai_title_parser.dart:23,118-125`);快取讀回時套同一個門檻(`lyrics_auto_match_service.dart:608`)。 +- AI 標題解析結果是 `advancedAiSelect` 的輸入;`alwaysAi` 只用解析結果當搜尋關鍵字(``:254-266`)。AI 挑選回傳 `selectedCandidateId` 為 null 表「全部不像」就不匹配(`:413-420`)。 + +## 7. 顯示(播放頁 / 側欄) + +- 顯示模式(原文/優先翻譯/優先羅馬拼音)在播放頁與桌面側欄面板(`features.md:165`),寫入 `lyricsDisplayModeIndex`(`data.md:343`)。 +- 歌詞面板元件 `lib/ui/widgets/lyrics/lyrics_display.dart`:用 `scrollable_positioned_list`,自動捲到當前行(`:248,255`),使用者手動捲動時暫停自動捲、計時後恢復(`:279-290`)。**點歌詞行 seek**(`:321,421-426`)、**右鍵行**有次要動作(`:322`)。 +- 當前行索引由 `currentLyricsLineIndexProvider` 提供(`lyrics_provider.dart:299`);它每個 position tick 可能重算,但只在整數行號變化時通知;行號計算 `calculateCurrentLyricsLineIndex` 跳過非同步歌詞(`:283`,呼叫點 `:306`)。 +- 歌詞欄有沒有內容決定寬版右欄要不要開(`lyricsPaneHasContentProvider`,`:261-281`)。 +- 舊專案有兩個獨立的歌詞顯示實作:播放頁的 `lyrics_display.dart` 與桌面子視窗的 `lyrics_window.dart`(後者自帶 `_LyricsLine`、單行模式、樣式)。 + +## 8. 桌面歌詞視窗(E11) + +**只有 Windows**。`LyricsWindowService.open()` 非 Windows 直接 return(`lib/services/lyrics/lyrics_window_service.dart:161-162`;`docs/audit/platforms.md:61-65`)。macOS / Linux 按鈕點了沒反應,而按鈕本身**沒有平台守衛**(`lib/ui/widgets/panels/track_detail_panel.dart:533-579`),`platforms.md:65` 推測 Android 寬版面也會看到沒作用的按鈕。 + +**機制**(`docs/audit/platforms.md:185-208`): +- `desktop_multi_window` 0.3.1,開獨立 Flutter engine(`:271`)。子視窗靠命令列參數 `multi_window` 進入獨立入口 `lyricsWindowMain`(`lib/main.dart:95-98`);該參數由套件原生端寫死(`platforms.md:204`)。 +- 通訊:`WindowMethodChannel('lyrics_sync', mode: bidirectional)`(`lyrics_window_service.dart:119-122`;子視窗 `lyrics_window.dart:231-234`)。主→子:`updateLyrics`(`:307`)/ `updatePosition`(`:335`)/ `updateTheme`(`:394`)/ `updatePlaybackState`(`:415`)/ `updateLyricsDisplayMode`(`:430`)/ `close`(`:271`)。子→主:`seekTo`(`lyrics_window.dart:422`)/ `adjustOffset`(`:448`)/ `resetOffset` / `playPause`(`:392`)/ `next`(`:398`)/ `previous`(`:404`)/ `changeLyricsDisplayMode` / `changeLyricsWindowStyle` / `resetLyricsWindowStyle`(`:506`)/ `requestHide`(`:410`)(子視窗發送 `:392-506`;主視窗 handler `lyrics_window_service.dart:472-515`)。 +- 子視窗只註冊 6 個插件(`platforms.md:205`);原因是 tray/hotkey/window_manager 用全域 static channel,註冊到子 engine 會蓋掉主視窗(`platforms.md:205`,註解主張、**未在執行中驗證**)。 +- 關閉用**隱藏不銷毀**,避免 window_manager channel 被清空(`lyrics_window_service.dart:252-266`,`close()` 只呼叫 `_controller.hide()` `:255`;`destroy()` 另在 `:267`;`platforms.md:206`)。等待 channel 就緒用輪詢 `ping`,最多 3 秒(`:235-249`)。 +- 檢測子視窗被系統關掉:監聽 `onWindowsChanged` 再比對 `WindowController.getAll()`(`:440-465`)。 + +**視窗行為**(`lib/ui/windows/lyrics_window.dart`): +- 初始化:`setSize(400,500)`、`setMinimumSize(400,300)`、**`setAlwaysOnTop(true)`**、隱藏標題列、置中、show/focus(`:253-267`;尺寸常數 `lyrics_window_style.dart:7-25`)。 +- 置頂可切換:`_alwaysOnTop` 預設 true,切換呼叫 `windowManager.setAlwaysOnTop`(`:205,739`)。 +- 透明模式:`setAsFrameless()` + `setHasShadow(false)` + `setBackgroundColor(transparent)`;離開透明模式還原標題列樣式、陰影、表面色(`:524-542`)。透明模式下 hover 才顯示半透明底與工具列(`:631-667,846-850`)。 +- **沒有滑鼠穿透**:全 `lib/` grep `setIgnoreMouseEvents` / `IgnoreMouse` / `clickThrough` / `點擊穿透` 皆無命中。舊專案只有「透明」與「置頂」,`features.md:170` 的功能清單也只列到透明與置頂。 +- **沒有鎖定(lock)**:全檔 grep `lock`(UI 義)無命中。透明模式下靠「hover 才顯示工具列」降低誤觸,但沒有鎖定模式。 +- 單行模式:`_singleLineMode` 切「單行」與「整頁」,UI 在 `lyrics_single_line_view.dart`(`lyrics_window.dart:209,623,726-727`)。 +- 樣式:文字色、次要色、非當前行透明度、外框(色/寬)、陰影(色/模糊/位移),11 個欄位存 Settings(`lyrics_window_style.dart:66-106`;`data.md:352`)。樣式改動經 250ms debounce 才送主視窗(`lyrics_window_style.dart:27-63`)。樣式對話框是 `lib/ui/widgets/lyrics/lyrics_style_dialog.dart`。 +- 主視窗推資料的**呼叫點全在 `TrackDetailPanel` 這個 UI widget 的 `ref.listen`**(`features.md:173`)—— 面板只在 expanded 以上寬版面且有曲目時掛載(`lib/ui/layouts/responsive_scaffold.dart:124-141,363-365,514`),收起仍掛載(`OverflowBox` 藏起 `:498-520`)。`features.md:173` 推測縮到 compact/medium 或全螢幕播放頁蓋住 shell 時可能停止更新(**未實測**)。這是一個架構缺陷:同步邏輯綁在 UI 生命週期上。 + +**移殖到其他平台需要的**(`platforms.md:208,351,369,410`):Windows 端已在 `main.cpp` 加 `multi_window` 判斷跳過單一實例 mutex(`:331`)並選擇性註冊子視窗插件(`:334`);macOS 要在 `MainFlutterWindow.swift`、Linux 要在 `my_application.cc` 加子視窗插件註冊(套件 README),並放寬 `isWindows` 守衛。 + +## 9. 舊 static-rule `lyrics_window_strings` 守什麼 + +- 檔案:`test/services/static_rules/lyrics_window_strings_static_rule_test.dart`(`docs/audit/engineering.md:279`;`.trellis/spec/ui/widgets.md:101`)。 +- 守的性質:**子視窗讀的每一個翻譯字串 key,都必須有人從主視窗推過去**(`lyrics_window_strings_static_rule_test.dart:21-51`)。 +- 為什麼需要:子視窗是獨立 runApp 進入點,拿不到主 isolate 的 slang 實例,所以自帶一份簡體 fallback;漏推一個 key 不會壞,只是顯示未翻譯的簡體(`:22-24`)。 +- 怎麼做:從 `lyrics_window.dart` 的 `updateFrom` 本體掃 `map['key']` 取出「被讀的 key 集合」(`consumedStringKeys`,`:91-115`,只掃 `updateFrom` 本體、去註解),與 `syncTheme` 實際推的 `strings` map 比對,要求**兩集合相等**(`:35-48`)——「讀了沒推」會 fallback、「推了沒讀」是死鍵,兩邊都抓。 +- 這條規則依賴「字串用 map 推、不是型別化訊息」。`docs/audit/engineering.md:279` 標它對「寫法變化、註解」敏感(無閘門守「推送機制本身」)。重寫若改成型別化 IPC 訊息,這條規則自然消失(見 `.trellis/tasks/archive/2026-09/09-27-design-testing/design.md:153` 的判斷)。 + +## 10. 快取與持久化 + +- **歌詞內容快取**:檔案式,`{cacheDir}/lyrics/*.json`,鍵為 base64url(`track.uniqueKey`)(`lib/services/lyrics/lyrics_cache_service.dart:63-64,268-272`)。上限:檔數 `Settings.maxLyricsCacheFiles`(預設 50,可調,UI 範圍 10–200)+總量硬性 5 MB,按存取時間 LRU 淘汰(`:18-19,203-244`;`data.md:224,342`)。存取時間寫 `_metadata.json`,2 秒 debounce(`:39,311-320`)。**無 TTL**(`data.md:224`)。設定頁「清除歌詞快取」→ `clear()`(`:141-158`)。 +- **匹配結果**:Isar `LyricsMatch`,只存 `externalId` 不存歌詞內容(`data.md:46,225`)。淘汰快取後可用存下的 id 重抓、不重新匹配(ADR 0016 決定 4,`docs/adr/0016-cache-and-offline.md:41`)。 +- 重寫定案:歌詞內容快取改放**統一快取庫**(鍵為歌詞插件+歌詞 id,只靠 LRU);匹配結果存主資料庫 —— 淘汰後以存下的 id 重抓、不重新匹配(ADR 0016 決定 1、4;`0016-cache-and-offline.md:31,41`)。 +- **鍵的坑**:`trackUniqueKey` 是 `sourceType:sourceId[:cid]`;B 站回填 cid 後鍵從兩段變三段,舊的兩段式鍵匹配會失聯(ADR 0005;`docs/audit/data.md:54,166`)。重寫後改用關聯表+外鍵(ADR 0010/0019)。 + +## 11. 與重寫定案的落差(給設計的輸入) + +| 舊專案 | 重寫定案 | 證據 | +|---|---|---| +| 三源各自 Dart 類別、字串分派 5 處 | 全部改為 JS 腳本插件,帶 `lyrics` 能力宣告,同一能力多提供者全列 | ADR 0014 決定 2、4(`docs/adr/0014-script-source-plugins.md:35,38`) | +| 每源自寫評分(Levenshtein、±20s、0.6) | 宿主**一份共用評分核心**:NFKC→小寫→繁簡統一(opencc)→去標點→括號分開比;`string_similarity`(Dice);時長「10 秒或 5% 取寬」;多歌手拆開取最佳;歌詞另加同步歌詞加分;同分依使用者排序;結果持久化、改選後不重算 | ADR 0014 決定 9;ADR 0019 決定 6(`0019-library-and-sync.md:61-66`) | +| `Track.originalSongId/originalSource` 一組 | `track_origins`(原始平台 id)可供歌詞直取,涵蓋 Spotify/QQ 匯入 | ADR 0019 決定 5(`0019:58-59`) | +| 歌詞內容在自製檔案快取、匹配在 Isar | 統一快取庫+主資料庫關聯表 | ADR 0016 決定 1、4 | +| 只有 LRC/純文字,無逐字 | 未定案(本任務要研究) | 本檔 §5 | +| 同步邏輯綁在 `TrackDetailPanel` 的 `ref.listen` | 未定案;重寫的 provider 邊界另有規定 | `features.md:173`;AGENTS.md § Providers | +| AI 端點不強制 https、payload 進 debug log | B5 方向:AI 歌詞保留、**預設關**、**強制 https**、**payload 不寫進 log**、送出欄位最小化並在設定頁列出 | 任務背景 + `questions.md:119` | +| 桌面歌詞視窗只開 Windows,按鈕無平台守衛 | ADR 0009:托盤、快捷鍵、**歌詞視窗**等都在平台層以能力宣告處理,目標全桌面平台一致 | ADR 0009(`0009-platform-layer-with-declared-capabilities.md:40`);`platforms.md:14,410` | + +## 12. 查不到 / 待確認 + +- **點擊穿透(click-through)與鎖定**:舊專案查無實作(§8 已 grep 全 `lib/`)。任務描述把「穿透點擊、鎖定」列為要研究的項目,但舊專案的歌詞視窗**兩者都沒有**;若重寫要做,屬新增功能,非搬運。 +- **逐字歌詞**:舊專案完全沒有,沒有可搬的實作。 +- **`advancedAiSelect` 的實際效果**:候選挑選的品質、成功率、成本查不到(未打 API、無量測資料)。 +- **macOS / Linux 上歌詞視窗的實際行為**:程式碼只到「按了沒反應」,沒有實機驗證紀錄(`platforms.md:65,182` 為事實/推測標註)。 +- **`desktop_multi_window` 0.3.1 在 macOS/Linux 的可用度**:audit 引套件 README 說支援,但舊專案從未在那些平台註冊子視窗插件,**未實測**。 diff --git a/.trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md b/.trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md new file mode 100644 index 000000000..e6c135b73 --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md @@ -0,0 +1,274 @@ +# 套件與平台事實 + +- 查證日期:2026-09-28 +- 查證方式:context7 / tavily-search / tavily-extract / pub.dev(各節註明) + +本文件只列事實,不含設計建議。版本、最後發佈日期、平台支援一律以 pub.dev 為準;日期未標時區者為 UTC。 +查不到的項目一律寫「查不到」;不確定的推論標「推測」。 + +--- + +## A. 桌面多視窗 + +### A1. `desktop_multi_window` + +查證方式:pub.dev 套件頁與 `/versions` 頁、pub.dev API、GitHub API(context7 查不到此套件,`resolve-library-id` 無法解析,故改用 pub.dev / GitHub)。 + +- 最新版本 **0.3.1**,發佈日 **2026-08-26**(pub.dev API `published` 欄位 = `2026-08-26T06:49:31.717877Z`)。 + 來源:https://pub.dev/api/packages/desktop_multi_window +- 套件頁宣告平台:**Windows / Linux / macOS**(三平台皆有實作)。 + 來源:https://pub.dev/packages/desktop_multi_window +- 授權 Apache-2.0;Likes **289**;pub points **160**;發佈者為 mixin.dev(verified publisher)。 + 來源:https://pub.dev/packages/desktop_multi_window/score +- 版本歷史:0.0.1(2022-01-28)… 0.3.0(2025-10-28),0.3.1(2026-08-26)。 + 來源:https://pub.dev/packages/desktop_multi_window/versions +- 原始碼位於 **monorepo** `MixinNetwork/flutter-plugins` 的 `packages/desktop_multi_window` 子目錄。 + 來源:https://github.com/MixinNetwork/flutter-plugins +- 倉庫層級數字(**整個 monorepo,不是此套件單獨的數字**):stars 512、open issues 146、`pushed_at` 2026-09-01。 + 來源:https://api.github.com/repos/MixinNetwork/flutter-plugins +- 與此套件相關的近期 commit:2026-08-26 發佈準備;2026-06-22 加入 Swift Package Manager 支援(#482);2026-06-22 Windows 全螢幕修復(#483)。 +- 架構事實:README 說明**每個視窗使用各自獨立的 Flutter engine**(非共用 isolate)。 +- 維護狀態:有在持續發佈(0.3.0 → 0.3.1 間隔約 10 個月),倉庫活躍;但 open issue 數偏高(146,含 monorepo 全部外掛)。 +- 查不到:官方沒有逐平台功能對照表;也查不到 CI 對三平台的測試覆蓋說明。 + +### A2. Flutter 官方多視窗(Desktop Windowing API) + +查證方式:tavily-search + 官方部落格(WebFetch 對 flutter.dev 可用)。 + +- **截至 2026-09-28,Flutter 官方有多視窗 API,但仍是實驗性、只在 `main` channel**,尚未進入 stable。 +- 啟用方式(官方部落格逐字): + ``` + flutter channel main + flutter upgrade + flutter config --enable-windowing + ``` + 來源:https://flutter.dev/blog/desktop-windowing-apis +- 官方部落格標題 **"Introducing the Desktop Windowing API for Flutter"**,作者 Matthew Kosarek,發佈日 **2026-08-24**。 + 來源:https://flutter.dev/blog/desktop-windowing-apis +- 同名頁面 banner 顯示 **Flutter 3.47** 為當時版本。 + 來源:https://flutter.dev/blog/desktop-windowing-apis +- 官方 API 元素(部落格內文):`WindowController`、`DialogWindowController`、`Window`、`DialogWindow`、`WindowScope`、`WindowControllerDelegate`(回呼 `onWindowDestroyed`、`onWindowCloseRequested`);建立視窗用 `WindowController(title: ..., size: ...)`。 +- 入口改為 **`runWidget`** 而非 `runApp`。 +- 視窗型別:regular / dialog / tooltip / popup / satellite。 +- Material 整合(規劃中):`showDialog`、`showMenu`、`Tooltip` 在桌面會產生真正的 OS 視窗,行動平台則沿用現有 in-app 實作 —— 同一份程式碼兩邊都能跑。 +- 桌面三平台(macOS / Linux / Windows)「out of the box」可用。 +- 社群分析(**非官方來源**):此 API 目前「available on the main channel as an experimental feature … the API surface may change based on feedback. Production use is recommended only for applications that can tolerate breaking changes between Flutter versions」。 + 來源:https://blog.redlinesoft.net/posts/flutter-desktop-windowing-api (2026-09-17) +- 治理背景(**非官方新聞來源**):Google 在 I/O 2026 宣布 Canonical 成為 Flutter desktop 的 lead maintainer 與「strategic steward」(Windows/macOS/Linux);此多視窗 API 由 Canonical 主導。 + 來源:https://www.omgubuntu.co.uk/2026/05/flutter-desktop-canonical-maintained +- 查不到:正式納入 stable 的時程、以及穩定性承諾(官方文件只說實驗性、可能變更)。 + +### A3. `window_manager` 與各平台視窗能力 + +查證方式:pub.dev、GitHub 原始碼(raw)、GitHub API、tavily-search。 + +套件基本事實: + +- 最新版本 **0.5.2**,發佈日 **2026-07-04**。 + 來源:https://pub.dev/packages/window_manager/versions +- 平台:**Windows / Linux / macOS**;授權 MIT;Likes **1.13k**;pub points **160**;下載數 **728k**。 + 來源:https://pub.dev/packages/window_manager +- 倉庫 `leanflutter/window_manager`:stars 845;`pushed_at` 2026-09-19(活躍)。 + 來源:https://api.github.com/repos/leanflutter/window_manager +- README 有**遷移通知**,指向新專案 `libnativeapi/nativeapi-flutter`(作者轉向新套件)。 + 來源:https://github.com/leanflutter/window_manager +- **注意**:GitHub API 回報 `open_issues_count: 0`,但 issue #576 明顯存在 → 此欄位不可信,issue 狀態一律以網頁為準。 + 來源:https://github.com/leanflutter/window_manager/issues/576 + +逐 API 平台能力(來源:Dart 原始碼 `packages/window_manager/lib/src/window_manager.dart` 的 `@platforms` 標註, +https://github.com/leanflutter/window_manager/blob/main/packages/window_manager/lib/src/window_manager.dart ): + +| API | `@platforms` 標註 | +|---|---| +| `getId` / `blur` / `isFocused` / `setClosable` / `setProgressBar` / `setHasShadow` | `macos, windows` | +| `isDockable` / `dock` / `undock` / `setIcon` | `windows` | +| `setMovable` / `setVisibleOnAllWorkspaces` / `setBadgeLabel` | `macos` | +| `setAlwaysOnBottom` / `startResizing` | `linux, windows` | +| `grabKeyboard` / `ungrabKeyboard` | `linux` | +| `setAlwaysOnTop` / `setIgnoreMouseEvents` / `setOpacity` / `setBackgroundColor` / `setPosition` | **無 `@platforms` 標註**(宣告上三平台皆可,但各平台實作程度不同) | + +各平台實作事實: + +- **透明(Linux)**:Linux 後端把 `backgroundColor` 的 ARGB 拆成 `rgba(...)` 字串,透過 `GtkCssProvider` 套用 `window { background-color: ; }`。即 Linux 的「透明」是靠 CSS 背景色,不是視窗層的 alpha。 + 來源:https://raw.githubusercontent.com/leanflutter/window_manager/main/packages/window_manager/linux/window_manager_plugin.cc +- **置頂(Linux)**:`setAlwaysOnTop` 的 Linux 實作直接呼叫 `gtk_window_set_keep_above(get_window(self), isAlwaysOnTop);`。 + 來源:同上檔案。 +- **滑鼠穿透(`setIgnoreMouseEvents`)**:變更紀錄顯示 **0.2.0 只實作 macOS + Windows**(PR #89),**Linux 沒有**;該 Linux 後端 `.cc` 檔中完全找不到 ignore / click-through 相關實作。→ 在 Linux 上呼叫此 API 沒有對應行為。 + 來源:https://github.com/leanflutter/window_manager/blob/main/packages/window_manager/CHANGELOG.md (`## 0.2.0` 條目:「[macos & windows] Implement `setIgnoreMouseEvents` metnod #89」) +- **`setOpacity`**:0.1.4 實作於 macOS/Windows(#37 #45);**0.2.5 才實作於 Linux**(#157)。 + 來源:同上 CHANGELOG(`## 0.1.4`、`## 0.2.5`)。 +- **已知未修 issue**:#179「BackgroundColor transparent doen't work on (Arch) Linux」**建立於 2022-07-12**,累積 16 則留言後,於 **2026-09-21** 由維護者 lijy91 關為 **not planned**;回報內容為 Windows 正常、Linux 顯示黑色。**注意:報告初稿把「建立日」誤記成「關閉日」——實際關閉是 2026-09-21,不是 2022-07-12。** + 來源:https://github.com/leanflutter/window_manager/issues/179 (`gh api` 讀 `created_at` / `closed_at` / `state_reason`) +- 查不到:官方文件**沒有**逐 API 的 Wayland 支援對照表;tavily-search 只找到「Linux/macOS/Windows ✔️ Fully supported」這種籠統的功能表。 + 來源:https://leanflutter.dev/window_manager (介紹頁) + +Wayland 平台層級事實(與套件無關,屬 compositor 協定層): + +- **XDG shell 故意不提供**客戶端視窗定位(全域座標)與堆疊(置頂/置底)控制。 + 來源:https://wayland.app/protocols/xdg-shell ;https://discourse.ubuntu.com/t/gtk-backend-selection-or-why-gtk-cannot-open-display-0/17657 +- **GNOME Discourse 逐字**:「Wayland does have support for input regions, but those are limited to your own window surfaces; you cannot set input regions on windows you did not create within your process, unlike on X11」「positioning windows directly using global coordinates, or changing the input mask—are not possible with Wayland. Additionally, all the hints API may not work」。 + 來源:https://discourse.gnome.org/t/overlay-with-gtk3-on-wayland/2216 +- **GTK4 遷移指南**把 `gtk_window_set_keep_above()`、`gtk_window_set_keep_below()`、`gtk_window_move()` 列為**已移除的 X11 專有 API**。 + 來源:https://docs.gtk.org/gtk4/migrating-3to4.html +- `wlr-layer-shell` 協定可提供錨定 + 置頂/置底層,但**一個 surface 只能有一個角色**(不能同時是 xdg-shell 與 layer-shell 視窗)。 + 來源:https://wayland.app/protocols/wlr-layer-shell-unstable-v1 +- **推測**:GTK3 + Wayland 下 `gtk_window_set_keep_above()` 是否生效取決於 compositor(GNOME Mutter / KDE KWin 各有實作差異)。查不到權威說明,需實機驗證。 +- 生態系直接佐證:套件 `desktop_lyrics` README 明寫 **「Wayland:由於技術限制,目前不支援點擊穿透」**,且 Linux 上 overlay 尺寸/位置**不會自動跟隨系統縮放與解析度變化**(X11 與 Wayland 皆然)。 + 來源:https://pub.dev/packages/desktop_lyrics + +其他多視窗外掛(同類選項,只列事實): + +- `window_manager_plus` — 以 window_manager 為基礎再加多視窗;**不支援 Linux**。 +- `multi_window_native` — 原生多視窗;僅 macOS / Windows。 + +--- + +## B. 行動平台浮動歌詞(只列事實) + +### B1. Android 懸浮窗(overlay) + +查證方式:tavily-search 取 developer.android.com 與 Google Play 政策頁正文。 + +權限與版本限制: + +- 需在 `AndroidManifest.xml` 宣告 ``。 + 來源:https://developer.android.com/reference/android/Manifest.permission#SYSTEM_ALERT_WINDOW +- **API 23(Android 6)起 SAW 是 special permission**:manifest 宣告不夠,必須用 `ACTION_MANAGE_OVERLAY_PERMISSION` intent 把使用者帶到系統設定頁手動授予。 + 來源:https://developer.android.com/reference/android/content/Intent#ACTION_MANAGE_OVERLAY_PERMISSION +- **API 26(Android 8)起**,`TYPE_SYSTEM_ALERT`、`TYPE_PHONE`、`TYPE_PRIORITY_PHONE` 等視窗型別被 deprecated,**必須改用 `TYPE_APPLICATION_OVERLAY`**。 + 來源:https://developer.android.com/reference/android/view/WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY +- **Android 10(Go edition)無法取得 SYSTEM_ALERT_WINDOW**。 + 來源:https://developer.android.com/about/versions/10/behavior-changes-all +- **Android 11**:`ACTION_MANAGE_OVERLAY_PERMISSION` 一律把使用者帶到**最上層**的設定頁(不能再導到單一 App 的頁面)。 + 來源:https://developer.android.com/about/versions/11/behavior-changes-11 +- **Android 12(API 31)行為變更**(以下皆出自同一頁): + - 遮蔽(obscuring)視窗的**不透明度上限預設 0.8**,超過會擋掉穿透觸控(obscured touch)。 + - 系統封鎖**不可信觸控(untrusted touch)** 事件。 + - 新增 `HIDE_OVERLAY_WINDOWS` 權限與 `Window.setHideOverlayWindows()`,讓其他 App 可要求系統對其隱藏 overlay。 + - Android 12 起「make it more difficult to obtain the SYSTEM_ALERT_WINDOW permission」。 + 來源:https://developer.android.com/about/versions/12/behavior-changes-12 +- **Android 15 行為變更**:以 SAW 作為啟動前景服務(FGS)的豁免條件收緊 —— 必須已有**可見的** `TYPE_APPLICATION_OVERLAY` 視窗,否則拋 `ForegroundServiceStartNotAllowedException`。 + 來源:https://developer.android.com/about/versions/15/behavior-changes-15 + +Google Play 政策: + +- 敏感權限頁面允許的用法是「引導使用者前往系統設定頁批准特殊權限(例如 `SYSTEM_ALERT_WINDOW`)」。 + 來源:https://support.google.com/googleplay/android-developer/answer/9888170 +- 裝置與網路濫用政策禁止「阻擋或干擾其他 App 顯示廣告」(overlay 擋廣告是明確違規樣態)。 + 來源:https://support.google.com/googleplay/android-developer/answer/9888379 +- **查不到**:Google Play 有一條專門針對 overlay / SAW 的**申報表單或單獨禁令**(本次搜尋結果中沒有)。 + +### B2. iOS + +查證方式:tavily-search 取 Apple Developer 文件正文(Apple 文件頁為 JS 渲染,WebFetch 只回標題,故改用搜尋回傳的正文)。 + +- **沒有 API 可以讓 App 在其他 App 之上繪製系統級懸浮視窗**。系統唯一的浮動窗是 Picture in Picture。 +- `AVPictureInPictureController.ContentSource` **只接受**:`AVPlayerLayer`、`AVSampleBufferDisplayLayer`、或 `AVPictureInPictureVideoCallViewController` 來源 → **PiP 僅限影片內容**,無法用來顯示歌詞文字。誤用會被 App Review 以 "Misusing PiP" 拒絕。 + 來源:https://developer.apple.com/documentation/avkit/avpictureinpicturecontroller/contentsource +- `MPNowPlayingInfoCenter.nowPlayingInfo` 接受的是 **`MPMediaItem` 的屬性子集**:`AlbumTitle`、`AlbumTrackCount`、`AlbumTrackNumber`、`Artist`、`Artwork`、`Composer`、`DiscCount`、`DiscNumber`、`Genre`、`MediaType`、`PersistentID`、`PlaybackDuration`、`Title`,外加 `MPNowPlayingInfoProperty*` 鍵(如 elapsed time、playback rate、media type、external content id)。**歌詞不在這個子集裡。** + 來源:https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter +- Apple 文件逐字:**「You don't have direct control over what information the system displays, or its formatting.」** → 即使把歌詞塞進非標準欄位,系統也不會照 App 的意思顯示。 + 來源:https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter +- **Live Activities(ActivityKit)時間限制**:活動最長活躍 **8 小時**,之後可在鎖屏再保留最多 **4 小時**,總計最多 **12 小時**。 + 來源:https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities +- **更新預算**:ActivityKit 的推送更新有 budget,超出即被系統節流。`Info.plist` 的 `NSSupportsLiveActivitiesFrequentUpdates` 設為 `YES` 可提高預算(使用者可在系統設定關閉;以 `ActivityAuthorizationInfo.frequentPushesEnabled` 查詢目前狀態);APNs **priority 5** 的更新不計入預算,**priority 10** 計入。 + 來源:https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications +- Live Activity 的版面是**固定版型**(鎖屏卡片 + Dynamic Island 區域),可自訂的只有各區域內容,無法自由排版成長歌詞列表。 + 來源:https://developer.apple.com/design/human-interface-guidelines/live-activities +- 生態系現況:Apple Developer Forums 有一則與 FMP 需求幾乎相同的提問(音樂 App 想讓 Live Activity **隨每行歌詞**更新),回報更新被延遲或遺失,且該串在本次查證時**無人回答**。 + 來源:https://developer.apple.com/forums/ (音樂 App + Live Activity 逐行更新討論串) + +--- + +## C. LRC / 逐字歌詞解析的 Dart 套件 + +查證方式:pub.dev 套件頁、`/versions`、搜尋頁;context7 無法解析這些套件。 + +- **`lrc`** + - 版本 **1.0.2**,發佈日 **2023-09-28**;純 Dart(不依賴 Flutter);授權 BSD-3-Clause;Likes 18;pub points 160。 + - 能力:支援 simple / extended / enhanced LRC 及混合模式 `extended_enhanced`;支援**逐詞(word-level)時間戳**;提供 `stream` 屬性。 + - 倉庫:`Yivan000/lrc`。 + - 來源:https://pub.dev/packages/lrc ;https://pub.dev/packages/lrc/versions +- **`lyrics_parser`** + - 版本 **1.0.0-nullsafety.0**,發佈日 **2021-02-03**。 + - 限制:要求 **Dart < 3.0.0** → 與 Dart 3 / 現行 Flutter **不相容,無法安裝**。 + - 來源:https://pub.dev/packages/lyrics_parser +- **`lrc_parser`** + - 版本 **0.0.1**,發佈日 **2026-02-03**。 + - 能力:基於 **ANTLR4**;支援 normal / word-by-word / mixed 三種解析層級;支援時間平移(time shift)。 + - 來源:https://pub.dev/packages/lrc_parser +- **`flutter_lyric`** + - 版本 **3.0.8**,發佈日 **2026-09-16**;授權 MIT;Likes 109;pub points 160。 + - 能力:內建 **`.lrc` 解析器** + **`.qrc` 解析器**(QQ 音樂逐字格式)+ `LrcToQrcUtil.convert` 轉換工具 + **YRC**(網易雲逐字純文字格式)解析;逐字高亮渲染元件。 + - **不支援 KRC(酷狗格式)**。 + - 注意:**3.0.5 已被撤回(retracted)**,同日被 3.0.6 取代 → 鎖版本時避開 3.0.5。 + - 倉庫:`ozyl/flutter_lyric`。 + - 來源:https://pub.dev/packages/flutter_lyric ;https://pub.dev/packages/flutter_lyric/versions +- **`desktop_lyrics`** + - 版本 **0.0.8**,發佈日 **2026-07-09**;桌面置頂浮動歌詞 overlay 外掛;平台 Windows / Linux / macOS。 + - **不解析 LRC**:App 必須自己把時間軸傳進去(`DesktopLyricsFrame.fromTimedTokens` / `fromKaraokeTimeline`)。 + - 預設 `enabled: false`;README 明寫 **Wayland 不支援點擊穿透**;Linux 上 overlay 尺寸/位置不跟隨系統縮放/解析度變化。 + - 來源:https://pub.dev/packages/desktop_lyrics +- 專門的 **YRC / QRC / KRC Dart 解析套件**:**查不到**。pub.dev 搜 `qrc`、`krc`、`yrc` 只得到 QR code 與酷狗 API 相關套件;唯一覆蓋 QRC + YRC 的是上面 `flutter_lyric` 的內建解析器。 +- pub.dev 搜 `lyric` 的其他結果(第 1 頁,另有第 2 頁):`genius_lyrics`、`lyrics_parser`、`chordify_lyrics`、`lyric_xx`、`mmoo_lyric`、`flutter_lyric_custom_ui`、`my_lyric`。 + 來源:https://pub.dev/packages?q=lyric + +--- + +## D. LLM API 呼叫 + +查證方式:tavily-search + tavily-extract(OpenAI 官方文件與說明中心)、pub.dev、Sentry 官方文件。 + +OpenAI 相容端點與金鑰處理的官方立場: + +- OpenAI 說明中心文章 5112595「Best Practices for API Key Safety」(頁面標示更新日 **2026-09-28**)逐字: + - **「Never deploy your key in client-side environments like browsers or mobile apps」** + - 「requests should always be routed through your own backend server」 + - 「Never commit your key to a repository」 + - 建議每位團隊成員使用獨立金鑰;優先用 workload identity federation 取代長期金鑰。 + 來源:https://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety + → 事實:對純客戶端 App(如 FMP)而言,把 OpenAI key 內嵌在 App 內正是官方明文反對的做法。 +- OpenAI 生產最佳實踐逐字:「Avoid exposing your API keys in your code or public repositories; store them in a secure location」「expose keys to your application via environment variables or key management services」;建議為金鑰設定到期時間 + 定期輪替,且**撤銷舊金鑰前先確認新金鑰可用**。 + 來源:https://platform.openai.com/docs/guides/production-best-practices +- **OpenAI 相容端點是生態系事實標準**:`POST /v1/chat/completions` 搭配可覆寫的 `base_url`,由 Ollama、vLLM、LM Studio、DeepSeek、OpenRouter、xAI、GPUStack 等自架與第三方服務提供。 + 來源:https://platform.openai.com/docs/api-reference/chat + +客戶端儲存 API key(Flutter / Dart 生態): + +- **`flutter_secure_storage`** + - 版本 **11.2.0**,發佈日 **2026-09-16**;發佈者 steenbakker.dev;平台 Android / iOS / Linux / macOS / Web / Windows。 + - **Linux**:底層用 **libsecret**,需要系統 keyring(`gnome-keyring` / `kwalletmanager` / secret-service)以及 `libsecret-1-dev`、`libsecret-1-0` 套件。 + - **Windows**:需要 C++ **ATL** 標頭。 + - **iOS / macOS**:需要 **Keychain Sharing** entitlement(`keychain-access-groups`),除非改用 `MacOsOptions(usesDataProtectionKeychain: false)`。 + - **Android**:minSdk 23。 + 來源:https://pub.dev/packages/flutter_secure_storage +- 其他常見做法(只列事實):環境變數 / 設定檔 / 系統 keyring。keyring 與 secure storage 的關係即上一條的 libsecret / Keychain / Credential Manager 後端。 + +「不要把 API key 寫進 log」的常見實作手法: + +- **Sentry Flutter 官方文件「Scrubbing Sensitive Data」**列出的四種手法: + 1. 在 log 語句內**去識別化**(例如 email → 內部 id); + 2. 用 **`beforeBreadcrumb`** 在 breadcrumb 被附到事件前過濾掉; + 3. **關閉 logging breadcrumb integration**; + 4. 另外設定 **server-side scrubbing**(在 Sentry UI 設定,立即對新事件生效)。 + 來源:https://docs.sentry.io/platforms/dart/guides/flutter/data-management/sensitive-data +- 同一份文件的事實警告:部分 SDK(JS 與 Java 的 logging integration)會**自動抓取已執行的 log 語句**當 breadcrumb;多數 SDK 會把 **HTTP query string 與 fragment** 加進 breadcrumb → 「Do not log PII if using this feature」。 + 來源:同上 +- `sentry_logging` 套件變更紀錄中有一條 **「Sanitize sensitive data from URLs (span desc, span data, crumbs, client errors)」**,顯示 URL 內 token 的清理是 SDK 既有能力。 + 來源:https://pub.dev/packages/sentry_logging/changelog +- 通用 logger level 的事實(非 Sentry 專屬):verbose 等級(`Level.all` / `silly` / `fine` / `verbose`)可能記錄 API key、使用者識別與**完整請求 URL** → 不應在 production 開啟。 + 來源:https://pub.dev/packages/logging +- 查不到:Flutter 生態沒有一個「官方指定」的 redaction 套件;本節列出的都是各 SDK 自己的機制。 + +--- + +## 小結:FMP 重寫時要先確認的平台事實 + +1. **官方多視窗有,但不穩定**:Flutter 的 Desktop Windowing API 存在(`WindowController`、`runWidget`、`flutter config --enable-windowing`),但只在 `main` channel、標示實驗性、API 可能變更(官方部落格 2026-08-24,Canonical 主導)。要穩定就得走 `desktop_multi_window`(0.3.1 / 2026-08-26,每視窗一個 engine)。 +2. **Wayland 是桌面浮動歌詞的最大風險**:XDG shell 刻意不給全域定位與堆疊控制;`window_manager` 的 Linux 後端根本沒有 `setIgnoreMouseEvents` 實作,`desktop_lyrics` 也明寫 Wayland 不支援點擊穿透。 +3. **置頂的可行性取決於 GTK 版本與 compositor**:`gtk_window_set_keep_above()` 是 GTK4 已移除的 X11 專有 API,而 GTK3 + Wayland 下是否生效查不到權威說明 —— 必須實機驗證,不能只看文件。 +4. **Android 懸浮窗是「使用者手動授予的特殊權限」**:SAW 需 `ACTION_MANAGE_OVERLAY_PERMISSION` 引導設定;API 26 起強制 `TYPE_APPLICATION_OVERLAY`;Android 12+ 有遮蔽觸控、不可信觸控、`HIDE_OVERLAY_WINDOWS` 三重限制;Android 15 又收緊以 SAW 啟動 FGS 的豁免;Go edition 拿不到 SAW。 +5. **iOS 上「其他 App 之上的懸浮歌詞」做不到**:PiP 只接受影片來源且誤用會被拒;`MPNowPlayingInfoCenter` 的屬性子集不含歌詞,且「你無法控制系統顯示什麼」;Live Activity 有 12 小時總上限與更新預算節流 —— Apple 論壇已有同類未解問題。 +6. **LRC 解析有現成選擇,逐字格式只有部分覆蓋**:`lrc`(1.0.2 / 2023-09-28,純解析、逐詞)與 `flutter_lyric`(3.0.8 / 2026-09-16,含渲染 + QRC/YRC);`lyrics_parser` 已與 Dart 3 不相容;**沒有專門的 KRC Dart 套件**。 +7. **`desktop_lyrics` 可直接當桌面 overlay 的候選**(0.0.8 / 2026-07-09),但**它不解析 LRC**,且 Wayland 下無點擊穿透、Linux 不跟隨縮放。 +8. **LLM key 不能內嵌在客戶端**:OpenAI 官方明文要求不要在瀏覽器或行動 App 部署 key、要走自家後端;若仍採 BYOK,儲存只能靠 `flutter_secure_storage`(Linux 需系統 keyring、Windows 需 ATL、macOS/iOS 需 Keychain entitlement),且必須自行在 SDK 層遮蔽日誌(`beforeBreadcrumb` / 關閉 logging integration / server-side scrubbing)。 diff --git a/.trellis/tasks/09-28-design-lyrics/research/prior-art.md b/.trellis/tasks/09-28-design-lyrics/research/prior-art.md new file mode 100644 index 000000000..380799d6c --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/research/prior-art.md @@ -0,0 +1,474 @@ +# 成熟產品的歌詞功能(prior art) + +- 查證日期:2026-09-28 +- 查證方式:tavily-search / tavily-extract / GitHub permalink(各節註明) + +## 閱讀說明 + +- 所有 GitHub 連結都是**固定 commit SHA 的 permalink**。SHA 由 `gh api repos///commits?per_page=1` 取得,檔案內容由 `gh api repos///contents/?ref=` 讀取。 +- 本報告只寫「讀到的程式碼/文檔說了什麼」。沒查到的主題一律寫「查不到」;由間接證據推論的寫「推測」。 +- 各產品的 HEAD SHA(本報告寫作時): + + | 產品 | repo | HEAD SHA | + |---|---|---| + | Namida | `namidaco/namida` | `e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5` | + | Spotube | `KRTirtho/spotube` | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | + | LX Music Desktop | `lyswhut/lx-music-desktop` | `ad95d5091c9ed689fa72b5e5c849df65f5a679ce` | + | LX Music Mobile | `lyswhut/lx-music-mobile` | `fb8480728d875fa5e0da25eebd3a26bb71723aae` | + | MusicFree | `maotoumao/MusicFree` | `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee` | + | Harmonoid | `harmonoid/harmonoid` | `2b021f7b0b5dbcbe027aec010580977a2939a28d` | + | BetterLyrics | `jayfunc/BetterLyrics` | `97629ddf085877cdc90de8cb56006a023320fe00` | + | Lyricify-App | `WXRIW/Lyricify-App` | `2aad11e7404fc3770a90da4fa4c4403e3b7ad0f1` | + | Lyricify-Lyrics-Helper | `WXRIW/Lyricify-Lyrics-Helper` | `cabe0b71d443a9b882a35c60c4f7f21addcbe751` | + +--- + +## 1. Namida(Flutter,Android / Windows / Linux) + +查證方式:tavily-search(定位 repo)+ GitHub permalink(逐檔讀取,SHA 見上表)。 + +### 1.1 歌詞源插件化:沒有插件,硬編碼 + 本地檔案 + +歌詞**不是**插件機制。來源列舉寫死在 enum 裡: + +- `LyricsSource { auto, local, internet }`(優先序設定,不是來源清單) +- `LyricsProvider { lrclib, kugou }` + → [`lib/core/enums.dart#L750-L759`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/core/enums.dart#L750-L759) + +實際的取得順序(`Lyrics._updateLyrics` → `_fetchLRCBasedLyrics`)是: + +1. 音檔同目錄的 `.lrc`(`firstDeviceLRCFile()`) +2. 自家歌詞快取目錄的 `.lrc` +3. 音檔內嵌 tag 歌詞(`embeddedLyrics`) +4. 網路:LRCLIB 與 KuGou(`_LRCProvidersSearcher`,`allProviders` 時 KuGou 取 3 筆、否則 1 筆) +5. 以上都沒有 → `.txt` 快取 → 內嵌純文字 → 最後手段是**爬 Google 搜尋結果**(`_fetchLyricsGoogle` 打 `https://www.google.com/search?...`,再用 regex 去 HTML 標籤) + +→ [`lib/controller/lyrics_controller.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/lyrics_controller.dart)、 +[`lib/controller/lyrics_search_utils/lrc_search_utils_base.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/lyrics_search_utils/lrc_search_utils_base.dart) + +搜尋字串由來源型別決定:本機曲目用「藝人 - 標題 + 專輯 + 時長」(`searchDetailsQueries()`),YouTube 曲目用「影片標題 lyrics」(`searchQueriesGoogle()`)。 +→ [`lrc_search_utils_selectable.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/lyrics_search_utils/lrc_search_utils_selectable.dart)、[`lrc_search_utils_youtubeid.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/lyrics_search_utils/lrc_search_utils_youtubeid.dart) + +### 1.2 匹配與手動改選:有候選清單,選完寫入快取 + +- 自動匹配就是上面那條固定優先序,最後用網路搜尋的**第一筆**(`lyrics.firstOrNull`)。 +- 手動改選在 `showLRCSetDialog(item, colorScheme)`:把「內嵌 / 快取 txt / 快取 lrc / 裝置 lrc」放進 `availableLyrics`,把網路搜尋結果放進 `fetchedLyrics`(用 `onPartial` 串流進來、邊搜邊顯示),使用者可選、可**編輯**、可**刪除**。 + → [`lib/ui/dialogs/set_lrc_dialog.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/ui/dialogs/set_lrc_dialog.dart) +- 改了會不會記住:會。選定後寫進 `cachedLRCFile` / `cachedTxtFile`(檔名是曲目的 cache key),下次同一首直接命中快取,不再打網路。 +- 另有 `LrcFingerprint`:去掉 metadata 行、時間戳統一降到 centisecond,用來**去重**同一批候選,避免同一份歌詞出現兩次。 + → [`lib/class/lyrics.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/class/lyrics.dart) + +### 1.3 逐字歌詞與翻譯:逐字有,翻譯存疑 + +- 有 **卡拉 OK 逐字**。parser 有三個:`parser_lrc`、`parser_qrc`、`parser_smart`(自動判斷)。 + - `LRCParserQrc` 解 `[start,duration]` 進階標籤與 `(start,duration)` 逐字標籤,產出 `spanList: List`(每個字 span 的 `start` / `duration` / `length`)。 + - 渲染端有 `_KaraokeLayout` / `_KaraokeTextPainter`,註釋寫 "Karaoke-style word-synced line",並有 `karaokeShimmer` 效果。 + → [`lib/packages/lyrics_parser/parser_qrc.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/packages/lyrics_parser/parser_qrc.dart)、[`lib/packages/lyrics_parser/models.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/packages/lyrics_parser/models.dart)、[`lib/packages/lyrics_lrc_parsed_view.dart#L1258`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/packages/lyrics_lrc_parsed_view.dart#L1258) +- 資料格式:LRC(`[mm:ss.xx]`)與 QRC。**沒有** KRC / YRC / TTML 的 parser。 +- 翻譯/羅馬音:`LyricsLineModel` 有 `extText` 欄位(延伸歌詞)與 parser 的 `isMain` 參數,`LRCParserLrc` 在 `isMain == false` 時把文字寫進 `extText`,形式上留了「主歌詞 + 延伸歌詞」的位置;但**本次查證的 controller 只抓單一 LRC,沒有看到抓翻譯源或翻譯開關的程式碼** → 翻譯支援程度**查不到**(推測:欄位預留、未實作完整)。 + +### 1.4 桌面歌詞:有,獨立迷你歌詞視窗(desktop) + +- `MiniLyricsWindow`([`lib/ui/widgets/mini_lyrics_window.dart`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/ui/widgets/mini_lyrics_window.dart)),在 `lib/main.dart` 依 `NamidaWindowManager.isMiniLyricsMode` 切換顯示。 +- `enterMiniLyricsMode()` 的做法([`window_manager_desktop.dart#L94-L121`](https://github.com/namidaco/namida/blob/e8363dbf1cc1efb9cb9be58b409b60b692fe1eb5/lib/controller/platform/window_manager/window_manager_desktop.dart#L94-L121)): + - `setAsFrameless()`、`setHasShadow(false)`、`setBackgroundColor(transparent)`、`setMinimumSize(kMiniLyricsMinSize)` + - **置頂**:`setAlwaysOnTop(true)` + - **不佔工作列**:`setSkipTaskbar(true)`,另有 `setVisibleOnAllWorkspaces(true)` + - 記住 bounds(`settings.extra.miniLyricsWindowBounds`),退出時還原原本視窗狀態 + - 以邊緣 grip 自行實作 `windowManager.startResizing(edge)` +- **點擊穿透:沒有**。程式碼裡沒有 `setIgnoreMouseEvents` 之類用法;相反地視窗用 `_hovering` 狀態在 hover 時顯示控制列 —— 它是一個可互動、可拖曳的正常視窗。 +- 平台:走 `window_manager` 桌面路徑,程式碼中有 `Platform.isWindows` 與 `Platform.isLinux` 分支(後者是標題列重新裝飾的處理)。macOS 沒有特別分支,**能不能跑未確認**。 +- 觸發入口:托盤選單(`TrayMenuKey.miniLyricsWindow`)、桌面快捷鍵、`main_page_wrapper.dart` 的按鈕。 + +### 1.5 AI / LLM:查不到 + +沒有發現任何 LLM 相關程式碼或設定。 + +--- + +## 2. Spotube(Flutter,跨平台) + +查證方式:`gh search code` 定位 + GitHub permalink 逐檔讀取 + README/CHANGELOG 對照。 + +### 2.1 歌詞源插件化:單一硬編碼來源 LRCLIB + +- 歌詞**不是**插件。整個 `lib/provider/lyrics/` 只有一個檔案 `synced.dart`,只有一個 provider:`getLRCLibLyrics()`。 + → [`lib/provider/lyrics/synced.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/lyrics/synced.dart) +- 打的是 `https://lrclib.net/api/get`,query 參數 `artist_name` / `track_name` / `album_name` / `duration`(秒),Header 帶標明版本與 repo 的 `User-Agent`。回傳取 `syncedLyrics`,沒有就用 `plainLyrics` 逐行拆成 `time == Duration.zero` 的假同步歌詞。 +- README 的 features 寫 "Time synced lyrics regardless of the plugin support",服務清單列 "LRCLib - A public synced lyric API"。 + → [`README.md`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/README.md) +- CHANGELOG 顯示演進:早期有「use official spotify API for fetching lyrics」、「add LRCLIB lyrics provider as fallback」、後來「fallback to LRCLIB when lyrics line less than 6 lines」、「LRCLIB lyrics should be usable without logging in」。**HEAD 的程式碼只剩 LRCLIB 一條路**。 + → [`CHANGELOG.md`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/CHANGELOG.md) + +### 2.2 匹配與手動改選:精確查詢,無候選清單 + +- `/api/get` 是**精確查詢**(不是 search API),沒有候選清單、也沒有手動改選 UI。 +- 快取:drift 表 `LyricsTable { id, trackId, data }`,用 track id 當 key(`InsertMode.replace`)。快取命中條件包含「歌詞行數 > 5」,太短會重抓。 + → [`lib/models/database/tables/lyrics.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/models/database/tables/lyrics.dart) +- 模型 `SubtitleSimple { uri, name, lyrics, rating, provider }`,`rating` 是 provider 自報的分數(LRCLIB 同步歌詞給 100、純文字給 0),並記錄 `provider: "LRCLib"`。 + → [`lib/models/lyrics.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/models/lyrics.dart) + +### 2.3 逐字歌詞與翻譯:都沒有 + +- 模型只有 `LyricSlice { Duration time; String text }` → **逐行**,無逐字。 +- 播放器歌詞頁是兩個 tab:Synced 與 Plain(`PlayerLyricsPage` 的 `TabItem`)。 + → [`lib/pages/player/lyrics.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/player/lyrics.dart) +- 翻譯/羅馬音:在 repo 內 `gh search code "translation"` 沒有命中歌詞相關程式碼 → **查不到**。 +- 格式:LRC,用 pub 套件 `lrc` 解析(README 的 Dependencies 有列)。 +- 同步機制:`useSyncedLyrics` 把 `lyricsMap` 轉成 `{秒: 文字}`,用 `audioPlayer.positionStream` 比對,另有 `syncedLyricsDelayProvider` 讓使用者調延遲。 + → [`lib/modules/lyrics/use_synced_lyrics.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/lyrics/use_synced_lyrics.dart) + +### 2.4 桌面歌詞:有 mini lyrics 視窗,置頂/穿透查不到 + +- `MiniLyricsPage`([`lib/pages/lyrics/mini_lyrics.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/lyrics/mini_lyrics.dart)),route 是 `/mini-player`([`lib/collections/routes.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/collections/routes.dart))。 +- 做法:半透明背景(`background.withValues(alpha: 0.4)`)、`MouseRegion` 做到 hover 才顯示控制列,桌面平台另用 `window_manager` 讀 `isMaximized()` 記住最大化狀態。 +- 平台判定:`kIsDesktop = kIsLinux || kIsWindows || kIsMacOS`。 + → [`lib/utils/platform.dart`](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/utils/platform.dart) +- **置頂(always-on-top)與點擊穿透:查不到** —— 沒有在這次讀到的檔案裡看到 `setAlwaysOnTop` / `setIgnoreMouseEvents` 的呼叫。 +- CHANGELOG 有 "mini_player: show/hide lyrics"、"jump to specific time on lyric click"(點歌詞跳時間)等條目。 + +### 2.5 AI / LLM:查不到 + +沒有發現任何 LLM 相關程式碼。 + +--- + +## 3. LX Music(Desktop = Electron/Vue,Mobile = React Native) + +查證方式:`gh search code` 定位 + GitHub permalink 逐檔讀取;zh-cn / zh-tw / en-us 語系檔對照設定語意。 + +### 3.1 歌詞源插件化:內建音源各自 `getLyric` + 使用者自訂音源腳本 + +- 內建音源目錄 `src/renderer/utils/musicSdk/`:`wy`(網易雲)、`tx`(QQ)、`kg`(酷狗)、`kw`(酷我)、`mg`(咪咕)、`bd`(百度)、`xm`(蝦米),每個都有 `getLyric()`。 + → [`src/renderer/utils/musicSdk`](https://github.com/lyswhut/lx-music-desktop/tree/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/musicSdk) +- **使用者自訂音源腳本**(`src/main/modules/userApi/`,事件 `import_user_api` / `remove_user_api`)會被掛上同一組介面,包含 `getLyric`: + `apis[source].getLyric = (songInfo: LX.Music.MusicInfo) => {...}` + → [`src/renderer/core/useApp/useInitUserApi.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/core/useApp/useInitUserApi.ts) + → 這就是 LX 的「歌詞插件化」:自訂音源可以自己帶歌詞來源。 +- 歌詞資料結構 `LX.Music.LyricInfo` 四欄:`lyric`(主歌詞)、`tlyric`(翻譯)、`rlyric`(羅馬音)、`lxlyric` / `lxlrc`(LX 自有逐字格式)。 + → 桌面歌詞視窗的 IPC 合約 [`src/common/types/desktop_lyric.d.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/common/types/desktop_lyric.d.ts) 裡 `set_info` 帶 `lrc / tlrc / rlrc / lxlrc`。 + +### 3.2 匹配與手動改選:自動換源,無候選清單 + +- `getLyricInfo({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource })` + → [`src/renderer/core/music/online.ts#L83-L103`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/core/music/online.ts#L83-L103) + 行為:先查快取(`getCachedLyricInfo`);沒有就抓,抓不到時**自動換源**(拿同一首歌在別的平台抓歌詞),成功後 `saveLyric(targetMusicInfo, lyricInfo)` 存起來 —— 注意存的是**實際抓到的來源**那份(`targetMusicInfo.id != musicInfo.id` 時存 target)。 +- 手動候選清單:**查不到**。整份 repo 裡只有酷狗內部用的 `searchLyric(name, hash, time, tryNum)`,沒有看到「列出多份歌詞讓使用者挑」的 UI 或入口。 +- 可手動調的只有**歌詞偏移**(`setLyricOffset`)與換源。 + +### 3.3 逐字歌詞與翻譯:完整(含獨門格式) + +- 設定項(語系檔 zh-tw): + - `player.isShowLyricTranslation`「顯示歌詞翻譯」 + - `player.isShowLyricRoma`「顯示歌詞羅馬音」 + - `player.isSwapLyricTranslationAndRoma`「交換翻譯與羅馬音順序」 + - `player.isPlayLxlrc`「使用卡拉 OK 式歌詞播放(如果可用)」,其 tooltip 明說「此功能比較耗性能,低配置電腦不建議開啟」 + → [`src/lang/zh-tw.json`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/lang/zh-tw.json)、[`src/renderer/views/Setting/components/SettingPlay.vue`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/views/Setting/components/SettingPlay.vue) +- 渲染端的擴充歌詞是**疊加**上去的:`extendedLyrics.push(lyrics.tlyric)` / `rlyric`,交給 `lrc-file-parser` 這類播放器一起算行。 + → [`src/renderer-lyric/core/lyric.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer-lyric/core/lyric.ts) +- 各來源逐字格式:`tx` 用 `decodeQrc`(QRC 解密)、`kg` 用 KRC(`src/common/utils/lyricUtils/kg.js`)、`wy` 產 YRC、加上 LX 自有的 `lxlrc`。 +- **下載歌詞**時可輸出:`.lrc`、`tlrc:`(base64 編碼的翻譯行)、以及 AWLRC 格式;`buildAwlyric` 就是組這個。 + → [`src/renderer/worker/download/lrcTool.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/worker/download/lrcTool.ts) +- 同檔還有 `filterExtendedLyricLabel()`:把翻譯/羅馬音的時間標籤**過濾成只留主歌詞也有的時間戳**(再用 `[t1][t2]文字` 合併)—— 這是翻譯行與主歌詞對齊的實作。 + +### 3.4 桌面歌詞:最完整的一套,真的跨平台 + +- 獨立的 Electron `BrowserWindow`「winLyric」模組:[`src/main/modules/winLyric/`](https://github.com/lyswhut/lx-music-desktop/tree/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winLyric)(`config.ts` / `main.ts` / `mouseCheckTools.ts` / `rendererEvent.ts`),前端是獨立 renderer `src/renderer-lyric/`(橫向 / 縱向兩種版面、可顯示頻譜 `AudioVisualizer.vue`)。 +- 設定面(`desktopLyric.*`,見 [`src/common/types/desktop_lyric.d.ts#L3-L45`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/common/types/desktop_lyric.d.ts#L3-L45)): + `enable`、`isLock`、`isAlwaysOnTop`、`isAlwaysOnTopLoop`、`isShowTaskbar`、`isLockScreen`、`pauseHide`、`isHoverHide`、`isDelayScroll`、`scrollAlign`、`direction`、`audioVisualization`、`width/height/x/y`,以及一整套 `style.*`(align、font、fontSize、lineGap、lyricUnplayColor、lyricPlayedColor、lyricShadowColor、opacity、ellipsis、isFontWeightFont/Line/Extended、**isZoomActiveLrc**)。 +- **置頂**:`setAlwaysOnTop(flag, level)`,並有 `alwaysOnTopTools.startLoop()` 週期性重設置頂(註釋說明 Linux 每次重開要重設)。`isAlwaysOnTopLoop` 是給這個循環用的開關。 + → [`src/main/modules/winLyric/config.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winLyric/config.ts) +- **鎖定 / 點擊穿透**:`browserWindow.setIgnoreMouseEvents(true, { forward: !isLinux && isHoverHide })` + → [`src/main/modules/winLyric/main.ts#L78`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winLyric/main.ts#L78)、[`main.ts#L187-L190`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winLyric/main.ts#L187-L190) + 因為穿透後收不到 mouseleave,另外用 `mouseCheckTools.runCheck(sendMouseLeave)` **輪詢游標位置**來實作 hover 隱藏(`isHoverHide`)。 +- **平台差異**(程式碼明說): + - Linux:`setIgnoreMouseEvents` 的 `forward` 選項不支援(所以 `!isLinux` 才開)、每次重開視窗要重設置頂、**不能把視窗設到螢幕外**(所以只有 Windows 會強制把被移走的視窗拉回設定值)。 + - macOS:`main.ts` 註解直寫「MacOS未知」。 + - 平台:Windows / Linux / macOS 都支援(Electron),但細節處理以 Windows 最完整。 +- **Mobile 版**:Android 用原生 overlay window 做桌面歌詞/狀態欄歌詞(`android/app/src/main/java/cn/toside/music/mobile/lyric/`:`LyricView.java`、`LyricPlayer.java`、`LyricTextView.java`),RN 端 [`src/core/desktopLyric.ts`](https://github.com/lyswhut/lx-music-mobile/blob/fb8480728d875fa5e0da25eebd3a26bb71723aae/src/core/desktopLyric.ts),可調 `isSingleLine` / `maxLineNum` / `isLock` / `position` / `opacity` / `textSize` / `showToggleAnima`,權限走 `checkOverlayPermission`。另有**藍牙歌詞**(設定 `IsShowBluetoothLyric`)。 +- LX Mobile 的字串處理獨立成 [`src/plugins/lyric.ts`](https://github.com/lyswhut/lx-music-mobile/blob/fb8480728d875fa5e0da25eebd3a26bb71723aae/src/plugins/lyric.ts):`setLyric(lyric, translation?, romalrc?)` 把翻譯與羅馬音當 `extendedLyrics` 一起餵給 `lrc-file-parser`。 + +### 3.5 AI / LLM:查不到 + +沒有發現任何 LLM 相關程式碼。 + +--- + +## 4. MusicFree(React Native) + +查證方式:`gh search code` 定位 + GitHub permalink 逐檔讀取。這是本次查證中**插件化最徹底**的一個。 + +### 4.1 歌詞源插件化:完全靠插件 + +- 插件 API 直接定義了歌詞能力: + ```ts + /** 获取歌词 */ + getLyric?: ( + musicItem: IMusic.IMusicItemBase, + ) => Promise; + ``` + → [`src/types/plugin.d.ts#L101-L103`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/types/plugin.d.ts#L101-L103) +- 回傳型別:`ILyricSource { lrc? (deprecated, 歌詞 url)、rawLrc? (純文字歌詞)、translation? (純文字翻譯) }`;另有 `ILyricItem extends IMusic.IMusicItem { rawLrcTxt? }`。 + → [`src/types/lyric.d.ts`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/types/lyric.d.ts) +- 插件宣告自己支援的搜尋類型,其中包含 `"lyric"`: + `SupportMediaType = "music" | "album" | "artist" | "sheet" | "lyric"` + → [`src/types/common.d.ts#L3-L8`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/types/common.d.ts#L3-L8) +- 宿主用 `getSearchablePlugins("lyric")` 過濾出「能搜歌詞的已啟用插件」。 + → [`src/core/pluginManager/index.ts#L504-L515`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/pluginManager/index.ts#L504-L515) +- → 網易 / QQ / lrclib 等全部是社群插件,不是內建清單。 + +### 4.2 匹配與手動改選:跨插件自動匹配 + 每插件一個 tab 的候選清單,且會記住 + +`src/core/lyricManager.ts` 的 `refreshLyric()`: + +1. 先問**當前歌曲所屬插件**的 `getLyric`(`pluginManager.getByMedia(currentMusicItem)?.methods?.getLyric(...)`)。 +2. 拿不到且設定 `lyric.autoSearchLyric` 開啟 → `searchSimilarLyric(musicItem)`: + - 取 `getSearchablePlugins("lyric")`,**跳過當前歌曲自己那個平台**; + - 用 `musicItem.alias || musicItem.title` 當關鍵字,每個插件搜尋、**只取前 2 筆**; + - 先用 `item.title === keyword && item.artist === musicItem.artist` 直接判定距離 0,否則算 `minDistance(keyword, title) + minDistance(artist, artist)`(編輯距離); + - 取全域最小距離那筆,叫該插件 `getLyric` → **跨插件自動匹配**(全區域距離歸零就提前 break)。 +3. 手動改選:`SearchLrc` panel —— 輸入框(預設 `alias ?? title`)+ `TabView` 每個插件一個 tab 的候選清單,按下去執行 `lyricManager.associateLyric(currentMusic, item)`。 + → [`src/components/panels/types/searchLrc/index.tsx`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/searchLrc/index.tsx)、[`LyricList.tsx`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/searchLrc/LyricList.tsx)、[`useSearchLrc.ts`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/searchLrc/useSearchLrc.ts) +4. **記住**:`associateLyric()` 把 `patchMediaExtra(musicItem, { associatedLrc: linkToMusicItem })` 寫進該曲目的 mediaExtra;`unassociateLyric()` 清除。另有 offset `patchMediaExtra(musicItem, { lyricOffset: offset })`。 +5. 也能**手動上傳本機歌詞**:`uploadLocalLyric()` 依 `localLrcPath//.lrc`(翻譯是 `.tran.lrc`)寫檔,`removeLocalLyric()` 刪除。 + +### 4.3 逐字歌詞與翻譯:翻譯有,逐字沒有 + +- 翻譯:`ILyricSource.translation`。解析在 [`src/utils/lrcParser.ts`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/utils/lrcParser.ts):用**雙指標**依「時間戳完全相等」把翻譯行併進 `IParsedLrcItem.translation`(不相等就填空字串),並設 `hasTranslation`。UI 開關是 `PersistStatus` 的 `lyric.showTranslation`([`lyricOperations.tsx`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/musicDetail/components/content/lyric/lyricOperations.tsx))。 +- 逐字:**沒有**。`IParsedLrcItem { time, lrc, translation?, index }` 只有行級時間;渲染元件 `lyricItem.tsx` 就是一個 ``(只有 normal / highlight / light 三態)。 + → [`src/pages/musicDetail/components/content/lyric/lyricItem.tsx`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/pages/musicDetail/components/content/lyric/lyricItem.tsx) +- 羅馬音:**查不到**。 +- 格式:自寫 LRC parser(`[mm:ss.xx]`、`[key:value]` metadata、支援 `offset` meta 並與使用者 offset 疊加)。 +- 歌詞面板可調:字級(`lyric.detailFontSize`)、偏移(`SetLyricOffset`)、搜尋改選。 + +### 4.4 桌面歌詞:Android 浮動歌詞窗 + 狀態欄歌詞(不是桌面 OS 的桌面歌詞) + +- Android 原生 overlay:[`android/app/src/main/java/fun/upup/musicfree/lyricUtil/LyricView.kt`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/android/app/src/main/java/fun/upup/musicfree/lyricUtil/LyricView.kt) + - `WindowManager.LayoutParams.type = TYPE_APPLICATION_OVERLAY`(API < O 用 `TYPE_SYSTEM_ALERT`) + - 可設定項:`topPercent` / `leftPercent` / `widthPercent` / `align` / `color` / `backgroundColor` / `fontSize` + - 有 `OrientationEventListener`(轉向重算)與 `onTouch`(目前直接 `return false`) +- 「狀態欄歌詞」:`LyricUtil.setStatusBarLyricText(歌詞 + 可選翻譯)`,在換歌與換行時更新;設定 `lyric.showStatusBarLyric`、`lyric.topPercent/leftPercent/...`。 +- Windows / macOS / Linux 桌面版歌詞窗:**查不到**(MusicFree 主體是 Android / iOS 的 RN 專案,未見桌面版實作)。 + +### 4.5 AI / LLM:查不到 + +沒有發現任何 LLM 相關程式碼。 + +--- + +## 5. Harmonoid(Flutter / Dart) + +查證方式:GitHub permalink 逐檔讀取 + repo 內 `gh search code` 比對。 + +### 5.1 歌詞源插件化:沒有插件,自架後端 API + +- `LyricsGet` 打自家後端:`/functions/v1/lyrics-get?track=&artist=&duration=`,Header 帶 `X-API-Key`。 + → [`lib/state/lyrics/api/lyrics_get.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/state/lyrics/api/lyrics_get.dart) +- `apiBaseUrl` / `apiKey` 來自 `--dart-define=API_BASE_URL`(CI 用 GitHub secret 注入,[`.github/workflows/master.yml`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/.github/workflows/master.yml))或使用者在 configuration 覆寫。 + → [`lib/api/utils/constants.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/api/utils/constants.dart) + → 值得注意:`apiKey` getter 寫成 `Configuration.instance.apiBaseUrl.nullIfBlank() ?? String.fromEnvironment('API_KEY')`,看起來是把 base URL 當 API key 回傳(**疑似筆誤/bug**,這裡只描述讀到的程式碼)。 +- **後端本身沒有開源**(是 Supabase edge function)→ 後端實際查了哪些歌詞庫、怎麼匹配,**查不到**。 +- 沒有插件/擴充機制。 + +### 5.2 匹配與手動改選:單次查詢,無候選清單 + +- 一次呼叫拿一整份 `Lyrics`,用 `track` / `artist` / `duration` 三個參數查。沒有候選清單、沒有手動改選 UI(**查不到**)。 +- 有本機 DB 快取:`lib/state/lyrics/database/` 的 `lyrics_entries` 與 `lyrics_translation_entries` 兩張表,key 是 `LyricsKey { track, artist, duration }`([`lib/state/lyrics/models/lyrics_key.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/state/lyrics/models/lyrics_key.dart)),翻譯用 `LyricsTranslationKey` 再多一個 `language`。 +- 換歌時 `LyricsNotifier` 會先清索引、`_fetchLyrics()` 再 `_fetchLyricsTranslation()`,用 `SplayTreeMap.lastKeyBefore(position + 1)` 找當前行。 + +### 5.3 逐字歌詞與翻譯:翻譯有,逐字沒有 + +- 模型 `Lyric { required int timestamp, required String text }` → **逐行**,沒有逐字欄位。 + → [`lib/state/lyrics/models/lyric.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/state/lyrics/models/lyric.dart) +- 翻譯是**獨立的一次伺服器端呼叫**:`Supabase.instance.client.functions.invoke('lyrics-translation', body: { lyrics: [...], language, track, artist, duration })` + → [`lib/state/lyrics/api/lyrics_translation_get.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/state/lyrics/api/lyrics_translation_get.dart) + → 送的是**整份已解析歌詞 + 目標語言**,回傳翻譯。因為是後端黑盒,是否用 LLM **查不到**(**推測**:機器翻譯或 LLM,因為輸入是整份歌詞而非逐行)。 +- README 能力清單:「Lyrics (LRC, tags & online)」、「Lyrics translations」、「Notification lyrics」。 + → [`README.md`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/README.md) +- 格式:LRC(用 pub 套件 `lrc`),本地 tag 歌詞也算在內。 +- 羅馬音:**查不到**。 + +### 5.4 桌面歌詞:查不到;有 Android 通知欄歌詞 + +- 桌面歌詞視窗:在 repo 內**查不到**(沒有對應的 desktop lyric 檔案)。 +- 有 **Android 通知欄歌詞**:`lyrics_notifier.dart` 定義 `_kNotificationChannelName = 'Lyrics'`、channel id、category、以及 `hide` action,設定 `mobileNotificationLyricsHidden`;當當前行跳動超過 1 行或播放完成時會重發通知。 + → [`lib/state/lyrics/lyrics_notifier.dart`](https://github.com/harmonoid/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/state/lyrics/lyrics_notifier.dart) + +### 5.5 AI / LLM:伺服器端翻譯,是否為 LLM 查不到 + +- 唯一的 AI 可能性就是後端 `lyrics-translation`,實作未開源 → **查不到**。 +- 客戶端沒有任何 LLM 呼叫。 + +--- + +## 6. BetterLyrics(Windows,WinUI3 / Win2D)+ Lyricify + +查證方式:GitHub permalink 逐檔讀取(BetterLyrics 原始碼全開)+ Lyricify 讀 README;`gh search code` 交叉比對。 + +### 6.1 歌詞源插件化:內建 12 種來源 + DLL 插件 SDK + +- `LyricsProvider` enum([`Enums/LyricsProvider.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Enums/LyricsProvider.cs)): + `QQ`、`Kugou`、`Netease`、`LrcLib`、`AmllTtmlDb`、`LocalMusicFile`、`LocalLrcFile`、`LocalEslrcFile`、`LocalTtmlFile`、`AppleMusic`、`BetterLyrics`、`LibreTranslate` +- 每個來源是一筆 `LyricsSearchProviderInfo`,可個別 `IsEnabled`、可覆寫 `MatchingThreshold`(預設 60)、可 `IgnoreCacheWhenSearching`,並有 `IsPlugin` 判斷。 + → [`Models/Settings/LyricsSearchProviderInfo.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Models/Settings/LyricsSearchProviderInfo.cs) +- **插件系統**:`PluginService`(`PluginLoadContext.cs`、`PluginConfigurator.cs`、`PluginContext.cs`),SDK 是 [`.NET` 專案 `BetterLyrics.Sdk`](https://github.com/jayfunc/BetterLyrics/tree/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Sdk)。三個能力介面: + - `ILyricsSource.GetLyricsAsync(title, artist, album, duration, token) → LyricsSearchResult`(可含 Raw、Translation、Transliteration、Reference URL) + - `ILyricsTranslator.GetTranslationAsync(text, targetLangTag)` + - `ILyricsTransliterator.GetTransliterationAsync(text, targetLangTag, token)` + → [`BetterLyrics.Sdk/README.md`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Sdk/README.md)、[`ILyricsSource.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Sdk/Interfaces/Plugins/ILyricsSource.cs) + - 插件設定 UI 由 SDK **自動生成**(`SettingBuilder.Bool()/Text()/Password()/Number()/Choice()/Action()` → `GetSettingDefDict()` 回傳 `SettingDef`)。 +- AMLL TTML DB 是內建來源之一:`raw.githubusercontent.com/amll-dev/amll-ttml-db` 的 `metadata/raw-lyrics-index.jsonl`。 + → [`Constants/AmllTTmlDB.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Constants/AmllTTmlDB.cs) +- Apple Music 來源要 `Media User Token`,存在 `IPasswordVaultProvider`(OS 憑證庫)。 + → [`LyricsSearchService/Providers/AppleMusic.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Implementations/Services/LyricsSearchService/Providers/AppleMusic.cs) + +### 6.2 匹配與手動改選:候選清單 + 手動選 + 記住查詢映射 + +- 搜尋策略 `LyricsSearchType { Sequential, BestMatch }`([`Enums/LyricsSearchType.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Enums/LyricsSearchType.cs)),主流程是 [`LyricsSearchService.SearchSmartlyAsync`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Implementations/Services/LyricsSearchService/LyricsSearchService.cs)。 +- **候選清單 + 手動改選**: + `LyricsSearchControlViewModel` 有 `ObservableCollection LyricsSearchResults` 與 `SelectedLyricsSearchResult`,UI 綁在 `LyricsSearchControl.xaml`(`ItemsSource` / `SelectedItem`)。 + → [`ViewModels/LyricsSearchControlViewModel.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/ViewModels/LyricsSearchControlViewModel.cs)、[`Controls/LyricsSearchControl.xaml`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSearchControl.xaml) +- **記住**:`ISongSearchMapService.SaveMappingAsync / TryGetMappingAsync`,存 `MappedSongSearchQuery`(`MappedTitle` / `MappedArtist` / `MappedAlbum` / `LyricsSearchProvider` / `IsMarkedAsPureMusic`)。搜尋前先查映射,命中就用**使用者認可過的標題/藝人/專輯**與指定來源再查。 + → [`Interfaces/Services/ISongSearchMapService.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Interfaces/Services/ISongSearchMapService.cs) +- 被標成純音樂(`IsMarkedAsPureMusic`)的直接回 `[00:00.000]🎶🎶🎶\n[99:00.000]`,不再搜尋。 + +### 6.3 逐字歌詞與翻譯:完整 + +- 逐字:`WordByWordEffectMode { Auto, Never, Always }`([`Enums/WordByWordEffectMode.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Enums/WordByWordEffectMode.cs))。 +- 格式 `LyricsFormat { Lrc, Eslrc, Ttml, Qrc, Krc, NotSpecified }`([`Enums/LyricsFormat.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Enums/LyricsFormat.cs))。 +- 解析**不是自己寫的**:用 Lyricify 的開源庫 —— `using Lyricify.Lyrics.Decrypter.Krc; ... .Parsers; ... .Searchers; ... .Searchers.Helpers;`(見 `LyricsSearchService.cs` 的 using 區塊)。 +- 翻譯:預設走**自架的 LibreTranslate**,`TranslationService.TranslateTextAsync` 打 `/translate`,送 `q`(原文)/ `source` / `target`,並先用 `LanguageHelper.DetectLanguageTag` 偵測語言、同語言直接回原文。同檔中保留了 `ILyricsTranslator` 插件路徑(被註解掉)。 + → [`Implementations/Services/TranslateService.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Implementations/Services/TranslateService.cs) +- 另有 `TransliterationService`(羅馬音/拼音)。 + +### 6.4 桌面歌詞:產品本身就是桌面歌詞工具(Windows only) + +- BetterLyrics 是 Windows 的「歌詞可視化 + 播放器」,`Enums/` 裡有 `LyricsWindowMode`、`DockPlacement`、`TaskbarPlacement`、`SystemTrayClickCallback`、`LyricsLayerType`、`LyricsLayoutOrientation`、`NowPlayingBarBackgroundStyle` 等一整套歌詞視窗/工作列/托盤設定。 +- 媒體來源靠 **GSMTC**(Windows Global System Media Transport Controls)抓其他播放器的曲目:`GsmtcService.AlbumArtUpdater.cs` / `GsmtcService.LyricsUpdater.cs`。 + → 甚至內建 LX Music 的訂閱端點:`Constants/LXMusic.cs` 的 `/subscribe-player-status?filter=progress,duration,picUrl`。 + → [`Constants/LXMusic.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Constants/LXMusic.cs) +- 平台:**Windows only**(WinUI3 / Win2D;repo description 明寫)。 +- 置頂 / 點擊穿透的實作細節:本次未逐檔追(**查不到**)。 + +### 6.5 AI / LLM:有 AI 能力,但是給插件用的,不是用來匹配 + +- SDK 把 AI 當成**提供給插件的能力**: + ```csharp + public interface IAIService { Task ChatAsync(string systemPrompt, string userPrompt); } + ``` + 宿主實作:`PluginContext.AIService => _pluginService.GetPlugin();` + → [`Sdk/Interfaces/Plugins/IAIService.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Sdk/Interfaces/Plugins/IAIService.cs)、[`PluginService/PluginContext.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Implementations/Services/PluginService/PluginContext.cs)、[`Sdk/README.md`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Sdk/README.md) +- **核心的歌詞搜尋/匹配沒有用到 AI** —— 靠的是每來源的 `MatchingThreshold` + `BestMatch` 排序 + 使用者存下來的 `SongSearchMap`。 +- 誰實作 `IAIService`、用哪家 LLM、API key 怎麼放:**查不到**(需要在 WinUI3 專案或外部插件裡再追)。 + +### 6.6 Lyricify(同類 Windows 歌詞工具,做為格式/來源的對照基準) + +Lyricify-App repo 只有 README 與 docs(**沒有應用程式原始碼**),歌詞處理核心另開在 `WXRIW/Lyricify-Lyrics-Helper`(Apache-2.0)。 + +- 產品線:Lyricify 4(Spotify 使用者,Windows)、Lyricify Fusion(任何接 SMTC 的 app,Windows)、Lyricify Mobile(iOS/iPadOS/macOS/Android/Windows)、Lyricify 3(EOL)。Lyricify 4 / 3 可透過 Wine 跑 Linux、macOS(官方 README remark 3,並另開 `Lyricify/Lyricify-on-Wine`)。 +- 首創功能(README「Lyricify 原創」):靈動島 / Dynamic Lyrics Island、妙控條 / Magic Strip、動態專輯封面 / Live Album Cover。 +- **歌詞格式能力**(`Lyricify-Lyrics-Helper` README 的表,解析/生成): + + | 格式 | 解析 | 生成 | 說明 | + |---|:-:|:-:|---| + | Lyricify Syllable | ✓ | ✓ | Lyricify 逐字歌詞 | + | Lyricify Lines | ✓ | ✓ | Lyricify 逐行歌詞 | + | LRC | ✓ | ✓ | 標準逐行歌詞 | + | QRC | ✓ | ✓ | QQ 音樂逐字歌詞 | + | KRC | ✓ | ✓ | 酷狗逐字歌詞 | + | YRC | ✓ | ✓ | 網易雲音樂逐字歌詞 | + | TTML | ✓ | — | 逐行、逐字;支援 Apple Music 擴展 | + | Spotify (JSON) | ✓ | — | 未同步、逐行或逐字歌詞 | + | Musixmatch (JSON) | ✓ | — | 未同步、逐行或逐字歌詞 | + + 另有 `ParseHelper` / `GenerateHelper` / `TypeHelper`(自動識別格式),並支援 QRC (XML)、網易完整 YRC (JSON)、Apple Music (JSON) 等原始封裝。 +- **搜尋來源與憑證要求**(同一份 README): + + | 來源 | 歌詞能力 | 憑證要求 | + |---|---|---| + | QQ 音樂 | 歌詞及翻譯 | 無需配置 | + | 網易雲音樂 | LRC、YRC 等 | 無需配置 | + | 酷狗音樂 | 搜尋歌詞並取 KRC | 無需配置 | + | 汽水音樂 | 曲目詳情取歌詞 | 無需配置 | + | Apple Music | TTML 歌詞 | 必須提供 Media User Token(Access Token 自動取得) | + | Musixmatch | 逐字/逐行/未同步歌詞及翻譯 | User Token 自動取得,可手動設置 | + | Spotify | 未同步/逐行/逐字歌詞 | 必須提供 `sp_dc` Cookie | + | LRCLIB | 同步或純文字歌詞 | 無需配置 | + +- 另有歌詞優化(Explicit 處理、標準化 YRC/Musixmatch、資訊行識別、Apple Music TTML 擴展的翻譯/簡中替換/背景人聲/演唱者對齊)與時間軸處理(加 offset、**把逐字降級成逐行**)。 + → [`Lyricify-Lyrics-Helper/README.md`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/README.md) +- Lyricify 應用層(候選清單手動改選、桌面歌詞置頂/穿透細節):**查不到**(repo 不含 app 原始碼)。 + +--- + +## 7. 綜合觀察 + +### 7.1 候選清單 + 手動改選是常態嗎?不是,大約一半 + +| 產品 | 候選清單 | 手動改選 | 記住選擇的方式 | +|---|:-:|:-:|---| +| Namida | 有(含網路結果串流) | 有,還可編輯/刪除 | 寫 `.lrc` / `.txt` 快取檔 | +| MusicFree | 有(每插件一個 tab) | 有(associate) | mediaExtra `associatedLrc` | +| BetterLyrics | 有(`LyricsSearchResults`) | 有(`SelectedLyricsSearchResult`) | DB 存 `SongSearchMap`(含查詢字串與來源) | +| LX Music | **沒有** | 只有自動換源 + 調 offset | 存實際抓到的來源那份歌詞 | +| Spotube | **沒有** | 沒有 | DB 快取(trackId 為 key) | +| Harmonoid | **沒有** | 沒有 | DB 快取(track/artist/duration 為 key) | + +- 有候選清單的三個,共同點是:**手動改選的結果會被持久化成「這首歌用這一份」**,只是存法不同(快取檔 / mediaExtra / DB mapping)。 +- 「自動匹配」的兩條主流路線: + 1. **精確參數查詢**(Spotube、Harmonoid):artist + title + album + duration 打單一 API,不做相似度排序。簡單,但離線庫/翻唱/直播版就找不到。 + 2. **相似度挑選**(MusicFree 的 `minDistance` 編輯距離、BetterLyrics 的 `MatchingThreshold` 預設 60、LX 的自動換源):先撈一批再排序。需要一個可調門檻。 +- BetterLyrics 的 `SongSearchMap` 值得注意:它記的不是「結果」,而是**「這首歌該用什麼查詢字串、查哪個來源」**。這樣換一個新來源插件時仍有機會命中,比只存結果更有韌性。 + +### 7.2 逐字歌詞與翻譯:格式現實 + +- 真實世界的逐字格式就三種:**QQ QRC**、**酷狗 KRC**、**網易 YRC**。能在自家 App 內自成一格的只有 LX(`lxlrc`)與 Lyricify(Lyricify Syllable)。 +- **LRC 是所有人都支援的唯一下限**。LRCLIB(Spotube 唯一來源、FMP 想接的來源之一)**只給逐行 LRC**,拿不到逐字。 +- **翻譯欄位名一致的叫 `tlyric` / `translation`**,配對策略一致地用**時間戳相等**合併(MusicFree 用雙指標;LX 用 `filterExtendedLyricLabel` 先把沒有對應時間戳的翻譯行濾掉再合併)。逐字歌詞的翻譯通常由同一個來源一起回(QQ 的 `lrc` + `tlyric` + `rlyric`)。 +- **羅馬音**:LX 有完整支援(`rlyric` + `player.isShowLyricRoma` + 交換順序設定);BetterLyrics 有 `ILyricsTransliterator`;Namida / MusicFree / Spotube / Harmonoid **查不到**。 +- 逐字能力一定要有**降級路徑**:Lyricify-Lyrics-Helper 明列「將逐字歌詞降級為逐行歌詞」(來源不支援逐字、或來源只給 LRC 時)。沒有這條,UI 會被迫為不同同步級別寫兩套。 + +### 7.3 桌面歌詞:跨平台誰真的做到了 + +| 產品 | 桌面歌詞 | 平台 | 置頂 | 點擊穿透 | +|---|---|:-:|:-:|:-:| +| LX Music Desktop | 獨立 BrowserWindow(橫向/縱向 + 頻譜) | **Windows / Linux / macOS** | ✓(`isAlwaysOnTop` + 循環重設) | ✓(`setIgnoreMouseEvents(true,{forward})`,Linux 不支援 forward → 改輪詢) | +| Namida | 迷你歌詞視窗(frameless + 透明) | Windows / Linux(macOS 未確認) | ✓ | **✗**(改成 hover 顯示控制列) | +| Spotube | mini lyrics(`/mini-player`) | Linux / Windows / macOS(`kIsDesktop`) | 查不到 | 查不到 | +| BetterLyrics | 就是桌面歌詞工具 | Windows only | 查不到(未逐檔追) | 查不到 | +| Lyricify | 桌面歌詞工具(靈動島/妙控條) | Windows(+ Wine 勉強跑 Linux/macOS) | 查不到 | 查不到 | +| MusicFree | Android overlay + 狀態欄歌詞 | Android | — | — | +| Harmonoid | 查不到 | — | — | — | + +三個可帶走的結論: + +1. **只有 LX 真的做完了三平台**,而且是用 Electron 的 `setIgnoreMouseEvents`。而且連它都要為 Linux 開後門:`forward` 選項在 Linux 不支援,只能自己輪詢游標位置來補 hover 偵測。 +2. **不支援點擊穿透的產品,改用「hover 顯示/隱藏控制列」**(Namida、Spotube)。這是純 Flutter 沒有等價 API 時的低成本替代。 +3. 桌面歌詞窗的**基本設定集**幾乎一致:always-on-top、skip taskbar、記住座標/尺寸、字級、played/unplayed 兩色、透明度、對齊、點擊穿透、hover 隱藏、暫停隱藏。 + +### 7.4 有多少產品真的用了 LLM?零 + +七個產品裡,**沒有一個把 LLM 用在歌詞匹配上**。所有找得到的 AI 痕跡: + +- **BetterLyrics**:SDK 提供 `IAIService.ChatAsync(systemPrompt, userPrompt)`,但這是**給插件呼叫的能力**(`PluginContext.AIService`),核心的搜尋/匹配完全靠 `MatchingThreshold` + `BestMatch` + `SongSearchMap`。誰實作 IAIService、用哪家模型、key 放哪,查不到。 +- **Harmonoid**:唯一的後端 `lyrics-translation` 送「整份歌詞 + 目標語言」拿翻譯,**推測**是機器翻譯或 LLM,但後端未開源,查不到。 +- **BetterLyrics 的翻譯**:預設走自架 LibreTranslate(明確不是 LLM),LLM 路徑(`ILyricsTranslator` 插件)被註解掉。 + +→ 也就是說,**「用 LLM 做歌詞匹配」在成熟產品中沒有先例**。成熟產品的替代品是「編輯距離 / 相似度 + 可調門檻 + 記住使用者修正」。如果 FMP 要做「可選的 AI 歌詞匹配」,那會是差異化而非跟隨;值得參考的設計是 **BetterLyrics 的 `SongSearchMap`**(把 LLM 的產出當成「映射」存下來覆核一次,而不是每次播放都問一次 LLM)。 + +### 7.5 對 FMP 插件 API 的幾個直接啟示 + +- **歌詞插件的能力邊界**:成熟產品的歌詞接口都很窄 —— 輸入幾乎固定是 `(title, artist, album, duration)`,輸出是 `{ 主歌詞, 翻譯, 羅馬音, 來源 url }`。MusicFree 的 `getLyric(musicItem)` 是唯一帶「平台內 id」的(因為它同時是音樂來源插件);純歌詞插件(BetterLyrics 的 `ILyricsSource`)則只吃四個純量參數。 +- **憑證一定要能存**:需要 token/cookie 的來源(Spotify `sp_dc`、Apple Music Media User Token、Musixmatch token)在 Lyricify 是「自動取得 + 可手動覆寫」,在 BetterLyrics 是 OS 憑證庫(`IPasswordVaultProvider`)。FMP 的插件 manifest 需要一個 secret 欄位與一套儲存位置。 +- **搜尋與取用要分開**:MusicFree 的插件既有 `search`(可用 `"lyric"` 類型)又有 `getLyric`,Lyricify 也分 `SearchHelper`(找曲目)與 `ProviderHelper`(已知 id 直接取)。只有搜尋分離出來,「候選清單」才做得出來。 +- **來源能力要能被查詢**:MusicFree 用 `supportedSearchType.includes("lyric")` 做能力過濾、`getPluginsWithAbility(ability)` 做方法過濾;BetterLyrics 用 `[Flags]`/enum + per-provider 開關與門檻。FMP 若要「多源搜尋」,插件需要宣告「我能搜歌詞」。 + +### 7.6 本次查不到清單(彙總) + +- Namida:翻譯/羅馬音的實際抓取與 UI 開關(只確認解析層有 `extText` 欄位)。macOS 是否支援迷你歌詞視窗。 +- Spotube:mini lyrics 的置頂/點擊穿透;翻譯支援;LRCLIB 之前的 Spotify 官方歌詞路徑是否已完全移除(只知道 HEAD 沒有)。 +- LX Music:手動歌詞候選清單(沒有);桌面歌詞視窗在 macOS 的實際行為(原始碼註解寫「MacOS未知」)。 +- MusicFree:羅馬音;桌面 OS(Windows/macOS/Linux)版歌詞窗。 +- Harmonoid:後端 `lyrics-get` / `lyrics-translation` 的實作與資料庫來源;是否有候選清單;羅馬音。 +- BetterLyrics:`IAIService` 的實作者與模型;桌面歌詞窗置頂/穿透的實作細節;`MatchingThreshold` 的比較演算法。 +- Lyricify:應用層(非 library)的候選清單手動改選與桌面歌詞視窗細節(repo 不含 app 原始碼,其餘在 docs.lyricify.app,本次未逐頁讀)。 From 847ced6c3e61f28aeabd446d739b63ce0a2cd391 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 10:25:58 +0800 Subject: [PATCH 069/133] chore(task): record lyrics scope and ai decisions --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 4 +++- .trellis/tasks/09-28-design-lyrics/prd.md | 22 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 2a43b5d97..478da7c69 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -235,7 +235,9 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 9. 功能凍結的例外與里程碑規劃備忘 -- 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27),是功能凍結的唯一例外。 +- 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27)。 +- 歌詞的逐字歌詞、桌面歌詞點擊穿透與鎖定、Android/iOS 懸浮歌詞由擁有者納入第 15 項(2026-09-28)。 +- 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 ## 10. 目前進度與下一步(交接用,2026-09-28 更新) diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index 6a91f16fa..58c99d40a 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -45,13 +45,29 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 - B5:AI 保留、預設關;強制 https;payload 不寫進 log;送出的欄位最小化並在設定頁列出(`phase2-plan.md` §6)。 - 桌面歌詞視窗以平台能力宣告,目標是所有桌面平台一致(ADR 0009、`phase2-plan.md` §8)。 +## 已決定 + +1. **AI 兩種模式都保留(2026-09-28)**:標題解析與候選挑選。 +2. **歌詞的新功能解除凍結(2026-09-28)**:擁有者把逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android/iOS 的懸浮歌詞納入本項, + 依成熟做法設計;各平台做不到的以能力宣告降級。可行性補查見 `research/extra-features.md`。 + ## 待決定 -1. AI 保留哪幾種模式(標題解析、候選挑選)。 +1. 是否接入 TypeSafe Jev 這類「結構化決策」模型做候選挑選,以及以什麼形式接入(補查見 `research/ai-decision-models.md`)。 +2. 各新功能的平台範圍與降級方式(等補查結果)。 + +### Jev 已核對的事實(2026-09-28,docs.typesafe.ai 與 NanoJev README) + +- TypeSafe 於 2026-09-15 公告,early access;`POST https://api.typesafe.ai/v1/systemone`,Bearer key。 +- 不生成文字:輸入 state 與具型別的問題(Choice 從最多 255 個選項挑一個、Score 依等級評分、Noul 是非題),回傳每個選項的機率與 confidence。 +- 價格 $0.042/百萬輸入 token、輸出免費;官方宣稱 70–500ms。 +- 已知弱點(官方 jaggedness 頁):英文最佳,CJK「可處理但不一樣好」;不擅長數字與日期比較(應在程式碼算);會照字面理解;可被內容中的誘導文字影響。 +- 企業才有零資料保留;Jev 不以客戶資料訓練。 +- NanoJev(MIT,2026-09-17 建立)是研究用復刻:Qwen3-0.6B 加決策頭,只訓練在 4 個遊戲任務,需 CUDA 伺服器,不是通用模型。 -## 不在範圍(功能凍結,列入待辦) +## 不在範圍 -- 逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android 懸浮歌詞與狀態列歌詞、本機歌詞檔匯入:舊專案都沒有,屬新功能。 +- 本機歌詞檔匯入(舊專案沒有,擁有者未納入)。 - 歌詞頁與視窗的版面(第 5 項)。 ## 驗收條件 From c22b66f0aef0e4116a2f485f4c799fac3f83d80c Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 10:46:07 +0800 Subject: [PATCH 070/133] chore(task): add lyrics extras and decision-model research --- .trellis/tasks/09-28-design-lyrics/prd.md | 21 +- .../research/ai-decision-models.md | 349 ++++++++ .../research/extra-features.md | 771 ++++++++++++++++++ 3 files changed, 1139 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md create mode 100644 .trellis/tasks/09-28-design-lyrics/research/extra-features.md diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index 58c99d40a..3e5c14fa9 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -51,10 +51,27 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 2. **歌詞的新功能解除凍結(2026-09-28)**:擁有者把逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android/iOS 的懸浮歌詞納入本項, 依成熟做法設計;各平台做不到的以能力宣告降級。可行性補查見 `research/extra-features.md`。 +## 補查結論(`research/extra-features.md`、`research/ai-decision-models.md`,2026-09-28,關鍵項已抽查) + +- **逐字格式**:YRC、QRC 的字時間是絕對時間,KRC 相對行首;QRC 需非標準 DES、KRC 是 XOR+zlib,各有多份公開實作互證。 + 成熟產品一律把各格式正規化成「行+字、整數毫秒」的內部結構;降級只有逐字→逐行(行起訖=首字起、末字訖),沒有逐行→逐字。 + 逐字翻譯只有 Apple TTML 原生支援,其他來源的翻譯與羅馬音都是行級,以時間戳相等(LX 容差 100ms)合併。 +- **逐字渲染**:`flutter_lyric` 3.0.8 以 `CustomPainter`+分段 shader+`saveLayer(dstIn)` 遮罩做漸變高亮。 +- **桌面穿透**:`window_manager` 的 `setIgnoreMouseEvents` 在 Windows 只切 `WS_EX_TRANSPARENT`、`forward` 參數被忽略(已核對原始碼),macOS 可用,Linux 未實作; + `window_manager` 0.5.x 已停止維護,0.6.0 改建在 `nativeapi` 上。Linux 可用 GTK3 空 input region 穿透(`desktop_lyrics` 的做法),GTK3 的 Wayland 後端也實作了 input region,但 Wayland 下實際效果未驗證、置頂與定位不保證。 + 成熟產品的「鎖定」=不能拖+點擊穿透(+淡化);穿透後靠托盤選單、全域快捷鍵、主視窗開關解鎖,Windows 上 hover 顯示解鎖鈕要輪詢游標(LX 500ms、BetterLyrics 50ms)。 +- **Android 懸浮**:`flutter_overlay_window` 0.5.0(2025-04-20)開第二個 engine、不註冊其他插件,只能以它自帶的訊息通道與主 isolate 溝通; + LX Mobile、MusicFree 用原生 View。鎖定=`FLAG_NOT_TOUCHABLE`,Android 12 起穿透觸控要求視窗不透明度 ≤ 0.8。小米、ColorOS 另有「後台彈出介面」「懸浮窗」權限,都沒有可程式判斷的 API。 +- **Android 狀態列歌詞**:AOSP 自 API 21 不顯示 `tickerText`、`MediaMetadata` 沒有歌詞欄位;不需 root 的只有魅族 Flyme(文件化的反射 flag)與小米 HyperOS 焦點通知(需寄信申請);其餘要 root+LSPosed 模組。 +- **iOS**:系統級懸浮不可能。Live Activity 可在鎖屏/動態島顯示一行歌詞:最長 8 小時、資料 ≤ 4KB、不能連網;官方只對「推播更新」記載每小時預算,App 在前景或背景以本機 `Activity.update` 更新是否受限未記載,需實測。媒體報導 iOS 26 的 Apple Music 就在 Live Activity 逐行顯示歌詞。 +- **決策模型**:`POST /v1/systemone` 已有三個實作者——TypeSafe(官方)、OpenRouter(改 base URL 即可,用 OpenRouter 的 key 計費)、開源 Laya(Apache-2.0,可自架,宣稱 100+ 語言); + 沒有跨廠商標準,這個形狀就是事實標準。各實作的 confidence 定義不同(Laya 文件明說不能沿用 Jev 的門檻)。另有多個 9 月才出現的開源復刻,都未經驗證。 + OpenAI 相容端點可用 `logprobs` 取選項機率,但 `top_logprobs` 最多 5。音樂或歌詞領域沒有產品級先例。 + ## 待決定 -1. 是否接入 TypeSafe Jev 這類「結構化決策」模型做候選挑選,以及以什麼形式接入(補查見 `research/ai-decision-models.md`)。 -2. 各新功能的平台範圍與降級方式(等補查結果)。 +1. AI 候選挑選要不要也支援 `/v1/systemone`(Jev 類)端點,以什麼形式接入。 +2. 各新功能的平台範圍與降級方式。 ### Jev 已核對的事實(2026-09-28,docs.typesafe.ai 與 NanoJev README) diff --git a/.trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md b/.trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md new file mode 100644 index 000000000..958ae4a1e --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md @@ -0,0 +1,349 @@ +# AI 決策模型(structured decision / reranker)調查 + +- 查證日:**2026-09-28**。所有數字(star 數、版本、日期)皆為該日快照。 +- 本檔只寫事實與出處。查不到者寫「查不到」;推論者標「推測」。 +- 未呼叫任何音樂平台 API。GitHub 一律以 `gh api` / `gh search repos` 直接查,不採信搜尋摘要。 +- 本檔不重複 `current-state.md`(FMP 現況)、`prior-art.md`(7 個歌詞產品)、`packages-and-platform.md`(Flutter 桌面/Android/iOS 平台事實)。 + +## 目錄 + +- §1 TypeSafe Jev / System One +- §2 Jev 相容的開源決策伺服器 +- §3 通用 reranker / cross-encoder +- §4 zero-shot 分類(GLiClass) +- §5 約束解碼與 structured output +- §6 用 OpenAI 相容 `logprobs` 取選項機率 +- §7 是否存在多廠商共用的「決策 API」標準 +- §8 音樂/歌詞匹配領域的先例 +- §9 未確認事項 + +--- + +## §1 TypeSafe Jev / System One + +### 1.1 產品定位與事實 + +| 項目 | 值 | 出處 | +|---|---|---| +| 發表日 | 2026-09-15 | `https://typesafe.ai/blog/introducing-system-one-models-and-jev`(官方);日期亦見 `https://www.width.ai/post/what-is-jev-ai-typesafe` | +| 定位 | System One model;不做字串生成,輸入 program state + typed questions,輸出 typed answers + calibrated probabilities,所有 question 一次平行評 | `https://docs.typesafe.ai/concepts/system-one`、官方 blog | +| 延遲 | 官方稱 end-to-end 70ms–500ms;同一頁對照 frontier model 為 3–329 秒 | `https://typesafe.ai/blog/introducing-system-one-models-and-jev` | +| 訓練方法 | 官方稱 RLCD(Reinforcement Learning for Calibrated Decisions) | 同上;`https://news.lavx.hu/article/typesafe-ai-launches-system-one-models-claims-100x-speed-gains-over-frontier-llms` | +| 價格 | USD 42 / Btok = USD 0.042 / Mtok,**只計 input token,output token 免費** | `https://docs.typesafe.ai/models` | +| 目前模型 | `jev-1.13.0`;alias `jev-latest`(最近穩定版)、`jev-preview`(最近版,不論是否 official);兩個 alias 目前都指向 `jev-1.13.0` | `https://docs.typesafe.ai/models` | +| 列模型 | `GET /v1/models` 回傳帳號可用的 model 名稱 + 說明 + release date;目前只列 alias,但 versioned ID(如 `jev-1.13.0`)就算不在清單也接受 | 同上 | +| Rate limit | 250,000 tokens/second 與 1,200 requests/minute;超過任一即回 `429`;官方明說此二上限會動態調整、不另行通知;更高上限走 custom / enterprise | 同上 | +| 語言 | 官方原文:「English is the primary training language and where accuracy is currently best.」「Other languages, including CJK scripts, are handled but not equally well; test on your own content before relying on Jev」 | 同上 | +| 資料處理 | 「Jev is not trained on customer requests or responses.」「Jev is not fine-tuned or LoRA-adapted with customer data... the same weights serve every account.」;並指向 Legal 取得 DPA / Privacy Policy / enterprise 的 zero data retention (ZDR) 細節 | 同上 | +| 融資/創辦人 | 第三方報導:seed round 4,000 萬美元、由 DCVC 領投、由 Diogo Almeida 建立(其為 OpenAI RLHF / InstructGPT 共同作者) | `https://www.width.ai/post/what-is-jev-ai-typesafe`、`https://dev.to/valyuai/how-to-use-jev-a-practical-guide-to-typesafes-system-one-model-g5e`(**非官方,未經官方頁面覆核**) | + +### 1.2 沒有訓練資料?——以 cookbook 反推「買的是什麼資料」 + +官方 cookbooks 目錄(`https://docs.typesafe.ai/llms.txt`)共 111 頁,全部是「如何把 state + question 拼出來」的配方,**沒有一頁在講訓練資料來源**。官方 blog 的 FAQ 標題含「Where does our training data come from?」(`https://typesafe.ai/blog/introducing-system-one-models-and-jev`),但本次抓取只取得 FAQ 標題、未取得答案內文 → 訓練資料來源:**查不到**。 + +### 1.3 HTTP API 形狀(官方 API reference) + +出處:`https://docs.typesafe.ai/api`。 + +- Endpoint:`POST https://api.typesafe.ai/v1/systemone` +- Header:`Authorization: Bearer `、`Content-Type: application/json` +- Request 三個必填頂層欄位:`model`、`state`(string / object / array)、`questions`(map,key 由呼叫者自訂) +- 三種 question type(`https://docs.typesafe.ai/primitives`): + - `noul`(yes/no) + - `choice`(**最多 255 個選項**) + - `score`(**2–10 級**) + - 三者都有 `instructions` 與 `criteria` +- 官方註明:question 的 key **不會送進底層模型、不參與推論** +- Response:`model`(回答的 versioned ID)、`answers`(以 request 的 key 對應)、`usage`(`input_tokens` / `output_tokens`) +- 官方建議:因 alias 會隨新版移動,若 confidence 門檻是對某版本調的,應 pin versioned ID;log 時記下 response 的 `model` 以稽核 + +**Choice 的 request / response 逐字範例**(出處:`https://docs.typesafe.ai/primitives/choice`): + +```json +{ + "state": "My running shoes arrived in the wrong size. Can I swap them for a size 10?", + "questions": { + "department": { + "type": "choice", + "instructions": "Which team should handle this?", + "criteria": { + "returns": "Exchanges, wrong or damaged items", + "shipping": "Delivery status, delays, lost packages", + "billing": "Charges, invoices, payment problems" + } + } + } +} +``` + +```json +{ + "model": "jev-1.13.0", + "answers": { + "department": { + "type": "choice", + "choice": "returns", + "confidence": 1.0, + "probabilities": { + "shipping": 0.0, + "returns": 1.0, + "billing": 0.0 + } + } + }, + "usage": { "input_tokens": 328, "output_tokens": 34 } +} +``` + +- `criteria` 的 value 官方說可以是 `null`、或自訂欄名的 object / array(沒保留字) +- `choice` 欄位語意:「機率最高的選項」;`probabilities` 語意:「所有選項的完整機率分布,總和為 1」;`confidence` 語意:「由 `probabilities` 分散程度算出的 0–1 值」,分布平均→低、單峰→高(`https://docs.typesafe.ai/confidence`) +- `score` 除 `probabilities` / `confidence` 外另回 `legend` +- Noul 回 0–1 的數字,官方描述為「TypeSafe 對答案為 yes 的機率估計」 + +**錯誤碼**(出處:`https://docs.typesafe.ai/api`): + +| Code | 官方說明 | +|---|---| +| 401 | Missing or invalid API key. Check the Authorization header. | +| 422 | The request body failed validation | +| 429 | You have exceeded your rate limit. Back off and retry after a short delay. | +| 529 | TypeSafe is temporarily overloaded. Retry after a short delay. | + +官方對 429 / 529 的指示是 exponential backoff,並說 client SDK 會自動處理。 + +### 1.4 SDK(JavaScript / Python) + +| 項目 | 值 | 出處 | +|---|---|---| +| npm 套件 | `@typesafe-ai/sdk`,最新 **0.6.0**,license MIT,`engines.node >= 20`,npm 首次 publish 2026-09-12、最後 modified 2026-09-15;說明為 "TypeScript SDK for the TypeSafe API" | `https://registry.npmjs.org/@typesafe-ai/sdk` | +| PyPI 套件 | `typesafe-sdk`,最新 **0.7.2**,`requires_python >= 3.10`,首次上傳 2026-09-09 | `https://pypi.org/pypi/typesafe-sdk/json` | +| 環境變數 | 兩個 SDK 都讀 `TYPESAFE_API_KEY`,預設 model `jev-latest` | `https://docs.typesafe.ai/sdk`、`https://dev.to/valyuai/how-to-use-jev-a-practical-guide-to-typesafes-system-one-model-g5e` | +| Helper | JS SDK 提供 `choice()` / `noul()` / `score()` 建 question,answer 型別由 helper 推導;有 `AsyncTypeSafeClient` 與可設定的 retry policy | 同上;`https://docs.typesafe.ai/sdk/javascript` | +| JS 錯誤類別 | 官方 API docs 列出 `APIConnectionError` / `APITimeoutError` / `APIUserAbortError` / `AuthenticationError` / `BadRequestError` / `InternalServerError` / `NotFoundError` / `PermissionDeniedError` / `RateLimitError` / `UnprocessableEntityError`,另有 `RetryPolicy` / `Logger` / `Fetch` 介面 | `https://docs.typesafe.ai/llms.txt` 所列頁面清單 | +| 瀏覽器支援 | 官方 docs 與 npm metadata 都**沒有**任何 browser / web 支援或 bundle 大小陳述,`engines.node >= 20` → **推測**為 Node 環境;瀏覽器是否可用:**查不到** | — | +| Vercel AI SDK | AI SDK 7(自 7.0.105 起)有 `experimental_evaluate`,TypeSafe 是其 native provider;與 `@typesafe-ai/sdk` 並用需 Node 22+ | `https://flaviocopes.com/jev`(第三方) | +| 其他第三方整合 | LangChain(發表後兩天)、Pydantic AI(`typesafe:jev-latest` provider,可讀 `provider_details` 的 `confidence` / `probabilities` / `scores`)、DeepEval 的 `system_one` / `hybrid` 模式與 JevEval、OpenRouter(改 base URL 即可把既有 TypeSafe client 指向 OpenRouter,回應多回 `id` / `provider` / `usage.cost`) | `https://pydantic.dev/docs/ai/models/typesafe`、`https://deepeval.com/integrations/models/typesafe-ai`、`https://openrouter.ai/docs/guides/community/typesafe-sdk`、`https://www.width.ai/post/what-is-jev-ai-typesafe` | + +### 1.5 免費額度與 early access + +- 官方 blog 原文:「Our first public model is Jev, available today in **early access**.」 +- 官方 blog 另有「working through its waitlist and bringing developers into early access」的敘述(轉述見 `https://news.lavx.hu/article/typesafe-ai-launches-system-one-models-claims-100x-speed-gains-over-frontier-llms`) +- `https://docs.typesafe.ai/models` 上**沒有** free tier、試用額度或 waitlist 申請流程的頁面 +- 是否有免費額度、early access 是否需申請與審核:**查不到**(官方 docs 未載;`https://typesafe.ai/legal` 僅指向 DPA / Privacy Policy / ZDR,未見免費方案說明) + +### 1.6 隱私與資料保留 + +- 官方 Privacy Policy 的 Retention 章節只寫概括語句:資料保留「as long as reasonably necessary to provide you with the Services...」,並說使用者要求刪除時會採去識別化或刪除措施,法律要求更長者除外 → **未載明具體天數**(`https://typesafe.ai/legal/privacy-policy`) +- 官方 models 頁:「details on **zero data retention (ZDR) for enterprise customers**」(`https://docs.typesafe.ai/models`) +- ZDR 的具體條件、DPA 條文內容:**查不到**(需進入 `https://typesafe.ai/legal` 下的文件,本次未取得逐字內容) + +### 1.7 官方自己示範的兩個「選一個」用法 + +這兩頁官方 cookbook 是本調查中**最接近「在多個候選中選一個並取得機率」的官方範例**,逐字重點如下。 + +**Re-ranking**(`https://docs.typesafe.ai/cookbooks/rerank_typesafe`): + +- 流程:先用 BM25 取 30 篇短名單 → 對每個 (query, candidate) 各發一次 **Noul** 問題「Could this candidate passage be from the cited precedent?」 +- 每個請求完全獨立:「no request sees another」 +- 排序方式:用 Noul 回傳的 0–1 分數降序排(`key=lambda c: -pair_scores[q][c]["noul"]`) +- 規模:40 query × 30 candidate = 1,200 次呼叫,thread pool 12 workers +- 效果:官方稱 top-1 accuracy 由 5% → 18%、top-10 由 38% → 62% +- 官方限制說明:re-ranking「cannot add a passage that fast search did not select」 +- 官方對呼叫粒度的建議:一對一問「是為了清楚」,真實應用「would ask several questions about the same pair in one call」,並指向 Parallel questions cookbook 與 Speculative Fan-Out pattern + +**Entity alignment**(`https://docs.typesafe.ai/cookbooks/entity_alignment`)——官方示範的是**兩份商品目錄的 metadata 去重**: + +- 一次呼叫同時問 4 個問題:1 個 Score(三級:「different product」/「related, but possibly not the same」/「same product」)+ 3 個 Noul(same name? same brewery? same style?) +- 兩個 entity 一起放進同一份 state(`entity_a` / `entity_b`),問題是針對「這一對」 +- 官方明確說不用 Noul 比數字:「comparing two numbers is arithmetic; compute it in code if you want to.」(此例是酒精度) +- 文本「passed exactly as published, without pre-processing」,含 HTML entity 與被拆開的撇號都原樣送 +- 決策規則:把 score 四捨五入到最近的級別,「The whole decision rule: the nearest level names the outcome.」,官方強調「no threshold you had to fit to your own data」 +- 結果分布:450 對中 40 對合併(8.9%)、50 對轉人工(11.1%)、360 對不合併(80.0%) +- 分數實際落點:多數落在 0.25 附近,原因是表面欄位重疊把機率推向中間級;9 對落在合併切點 1.5 的 ±0.1 內、47 對落在人工切點 0.5 附近 +- 模糊容錯實例:`c446` 這對的 style 字串為「American Barleywine」vs「Barley Wine」,style Noul 給 0.81,最終判定合併 + +--- + +## §2 Jev 相容的開源決策伺服器 + +以下皆以 `gh api` / `gh search repos` 於 2026-09-28 查得。**共同注意事項**:這些 repo 幾乎都在 2026-09-17~09-27 之間建立,歷史極短、未經第三方審核;star 數是快照,不能當品質證明。 + +### 2.1 有 Jev wire protocol 相容實作者 + +**Laya** — `NandhaKishorM/laya`,26,804 stars,Apache-2.0,created 2026-09-18,pushed 2026-09-27。 +- 自我描述:「Non-autoregressive System 1 decision engine. Typed choice, score and yes/no decisions over any text in a single forward pass, in 100+ languages, with a router that picks the right checkpoint per request.」 +- 其 `docs/http-api.md` 載明 `laya-serve` 直接實作 TypeSafe Jev 的 `/v1/systemone` wire protocol:同一個 path、同一個 `{state, questions}` request、answers 以相同 key 對應;**額外**多出 `routing` 區塊與 `answer_confidence` / `action.act_probability` 欄位 +- Auth:`Authorization: Bearer `,以 `LAYA_API_KEY` 環境變數控制(未設則不驗) +- 其他 env:`LAYA_HOST` / `LAYA_PORT` / `LAYA_DEVICE` / `LAYA_PRELOAD` / `LAYA_MODELS` / `LAYA_MAX_CONCURRENT` +- 另有 `GET /health` +- 限制(官方文件列出):body 2 MiB、`state` 50,000 字元、64 questions、choice 每題 100 選項、score 每題 32 級、總選項數 512、concurrency 16 +- 其 encoder 為 ModernBERT / mmBERT 系(非 autoregressive) + +**NanoJev** — `TianyuCodings/NanoJev`,2,354 stars,MIT,created 2026-09-17,pushed 2026-09-21。 +- 自我描述:「A nano replica of Jev: parallel decisions, dynamic candidates, and an end-to-end training pipeline.」 +- 已知事實(前次查證):Qwen3-0.6B + decision heads;只在 4 個遊戲任務上訓練;需 CUDA + +**其他同名/衍生專案**(皆為 `gh search repos` 快照,license 以 API 回傳為準): + +| Repo | stars | license | 一句話自我描述 | +|---|---|---|---| +| `TheoLeeCJ/SemIf-OpenJev` | 4,455 | MIT | Semantic ifs from open models, on a 3090 at home. Independent; not affiliated with Jev or TypeSafe. | +| `razorback16/openjev` | 465 | Apache-2.0 | Open, Jev-compatible System One decision server on DiffusionGemma | +| `ekzhang/openjev-sglang` | 329 | **無 license 檔** | Jev-compatible API endpoint based on open models (prefill-only) | +| `Heman10x-NGU/openJev-verdict-2.0` | 290 | other | Calibrated 151M Non-Autoregressive Decision Engine(自稱勝過 TypeSafe Jev 與 Laya) | +| `kshetrajna12/reflex` | 153 | MIT | A small open decision model: state + typed questions -> calibrated probabilities. A Jev / System One re-creation on Qwen3.5. | +| `SiliconLabAI/OpenJev` | 149 | MIT | OpenSource Jev | +| `IamBusy/OpenJev-Vision` | 38 | Apache-2.0 | Open visual probability research: encode an image once, answer multiple structured questions | +| `zhihz/openjev` | 35 | other | Local bilingual probability decisions from context, questions, and candidate answers. Independent research preview inspired by TypeSafe Jev. | +| `zhangcy122/OpenJev` | 33 | other | Self-evolving cognitive decision engine & TypeSafe Jev alternative… 100% option-order invariance | + +> `zhangcy122/OpenJev` 的自我描述提到它同時支援「Open LLMs、Laya (ModernBERT)、commercial Jev」並以 calibrated logprobs 取機率 —— 這是**專案自稱**,未經驗證。 + +### 2.2 JevHarness(「不自己跑模型,只包一層」的一類) + +| Repo | stars | license | 日期 | 說明 | +|---|---|---|---|---| +| `TianyuCodings/JevHarness` | 317 | **無 license 檔**(`gh api` 回 `license: null`) | created 2026-09-21、pushed 同日 | LLM-authored task-specific Jev harnesses with optional full-trajectory reward reflection and GEPA evolution | +| `TypeSafeAI/jev-harness` | 21 | MIT | created 2026-09-22、pushed 2026-09-26 | A custom coding harness for TypeSafe AI's Jev: an LLM proposes, Jev answers narrow questions, code decides, every step leaves a receipt | + +- `TypeSafeAI` GitHub org 顯示名稱為 **「TypeSafe Community」**,blog 指向 `https://jev.works`,created 2026-09-18,public_repos 8 → 名稱與公司同名,但 org 自稱 Community;**該 org 與 TypeSafe 公司的官方關係:查不到**(`gh api orgs/TypeSafeAI`) +- 另有數個小型 `jev-harness` / `jev-harness-router` 專案(3–16 stars,多為 MIT),皆為個人或社群專案 + +--- + +## §3 通用 reranker / cross-encoder + +這一類的形狀是「給一對 (query, document) 回一個 relevance 分數」,**與 Jev 的「一次回一組選項的機率分布」不是同一個東西**。以下參數量取自 Hugging Face `safetensors.total`(即權重元素數,非檔案大小)。 + +| 模型 | license | 參數量 | downloads | 最後修改 | 出處 | +|---|---|---|---|---|---| +| `BAAI/bge-reranker-v2-m3` | **apache-2.0** | 567,755,777 | 17,069,529 | 2024-06-24 | `https://huggingface.co/api/models/BAAI/bge-reranker-v2-m3` | +| `Alibaba-NLP/gte-reranker-modernbert-base` | **apache-2.0** | 149,605,633 | 2,671,413 | 2025-07-04 | `https://huggingface.co/api/models/Alibaba-NLP/gte-reranker-modernbert-base` | +| `Qwen/Qwen3-Reranker-0.6B` | **apache-2.0** | 595,776,512 | 1,388,973 | 2026-04-16 | `https://huggingface.co/api/models/Qwen/Qwen3-Reranker-0.6B` | +| `mixedbread-ai/mxbai-rerank-base-v2` | **apache-2.0** | — | 29,818 | 2026-04-08 | `https://huggingface.co/api/models/mixedbread-ai/mxbai-rerank-base-v2` | +| `jinaai/jina-reranker-v2-base-multilingual` | **cc-by-nc-4.0** | 278,437,633 | 1,012,943 | 2025-10-21 | `https://huggingface.co/api/models/jinaai/jina-reranker-v2-base-multilingual` | +| `jinaai/jina-reranker-v3` | **cc-by-nc-4.0** | 596,836,352 | 834,931 | 2026-08-10 | `https://huggingface.co/api/models/jinaai/jina-reranker-v3` | + +重點事實: + +- **Jina 系列兩個 reranker 都是 `cc-by-nc-4.0`(非商用)** —— 這是本次查到的授權裡唯一一組非寬鬆授權。 +- BGE / gte / Qwen3 / mxbai 皆 Apache-2.0。 +- `sentence-transformers/msmarco-MiniLM-L6-cos-v5`:無 license 標註於 cardData(`gh`/HF API 回 null),downloads 11,831,最後修改 2024-11-05 → **授權查不到**。 +- 這六個模型在 HF 上都**沒有** hosted HTTP inference API 的官方保證;要 HTTP 化需自架(HF TEI、vLLM、ONNX Runtime 等)→ **推測**(本次未逐一查各推論框架的支援矩陣)。 +- reranker 輸出為單一 relevance scalar,**不是** option 分布;若要拿「選項機率」需自行做 softmax / 正規化並處理分數量尺 → **推測**。 +- `PrithivirajDamodaran/FlashRank`:1,006 stars,Apache-2.0,created 2023-12-04,pushed 2026-07-11。自我描述:「Lite & Super-fast re-ranking for your search & retrieval pipelines. Supports SoTA Listwise and Pairwise reranking based on LLMs and cross-encoders」。它是把 reranker ONNX 化、以便在裝置上跑的**函式庫**,不是模型本身(`https://api.github.com/repos/PrithivirajDamodaran/FlashRank`)。 +- **本調查未找到任何一份把 reranker 當成「在多個候選歌曲/歌詞中選一個並輸出機率」的現成方案。** + +--- + +## §4 zero-shot 分類(GLiClass) + +`knowledgator` 的 GLiClass 系列,官方定位為單次 forward pass 的 zero-shot 分類。 + +| 模型 | license | 參數量 | downloads | 最後修改 | +|---|---|---|---|---| +| `knowledgator/gliclass-large-v1.0` | **apache-2.0** | 438,111,232 | 534 | 2025-08-12 | +| `knowledgator/gliclass-modern-base-v2.0` | **apache-2.0** | 151,378,176 | 11,463 | 2025-08-12 | + +- 出處:`https://huggingface.co/api/models/knowledgator/gliclass-large-v1.0`、`.../knowledgator/gliclass-modern-base-v2.0` +- 前者 HF `pipeline_tag` 為 `zero-shot-classification` → 代表 HF 生態可直接用 pipeline 呼叫,輸出各 label 機率 +- 兩個模型都**沒有** hosted HTTP API;要 HTTP 化需自架 → **推測** +- CJK / 多語支援程度:官方 model card 描述**查不到**(本次未取得逐字內容) + +--- + +## §5 約束解碼與 structured output(保證格式,不保證機率) + +| 專案 | license | 機制 | 出處 | +|---|---|---|---| +| llama.cpp GBNF grammars | MIT | 以 GBNF 文法約束 sampler | `https://github.com/ggml-org/llama.cpp/blob/master/grammars/README.md`;repo `ggml-org/llama.cpp` pushed 2026-09-27 | +| Ollama structured outputs | MIT(`ollama/ollama`) | `format` 參數吃 JSON schema,Ollama 依 schema 產生 grammar 後交給 llama.cpp | `https://ollama.com/blog/structured-outputs`(2024-12-06 起)、`https://docs.ollama.com/capabilities/structured-outputs` | +| Outlines | Apache-2.0 | structured outputs | `https://api.github.com/repos/dottxt-ai/outlines`,pushed 2026-09-21 | +| XGrammar | Apache-2.0 | Fast, Flexible and Portable Structured Generation | `https://api.github.com/repos/mlc-ai/xgrammar`,pushed 2026-09-27 | +| llguidance | MIT | Super-fast Structured Outputs(`microsoft/llguidance` 會 redirect 到 `guidance-ai/llguidance`) | `https://api.github.com/repos/guidance-ai/llguidance`,pushed 2026-09-25 | +| Instructor | MIT | 以 Pydantic / Zod 型別包 structured output,支援 Ollama 與 OpenAI 相容 endpoint | `https://api.github.com/repos/567-labs/instructor`,13,950 stars,created 2023-06-14,pushed 2026-09-27;`https://python.useinstructor.com/integrations/ollama` | + +重點事實: + +- **Ollama Cloud 目前不支援 structured outputs**(官方 docs 原文:「Ollama's Cloud currently does not support structured outputs.」) +- Ollama 的 schema→grammar 是送給 llama.cpp 執行;第三方分析指出**模型不會在 prompt 裡看到你給的 schema**(與 tool calling 不同,tool 的 JSON spec 會被注入 system prompt)→ 該分析建議同時把格式寫進 prompt(`https://blog.danielclayton.co.uk/posts/ollama-structured-outputs`,第三方) +- 這一整類**只保證輸出符合 schema,不產生 calibrated probability**;要機率仍需 `logprobs` 或改用 decision model → **推測** + +--- + +## §6 用 OpenAI 相容 `logprobs` 取選項機率 + +官方文件(OpenAI Cookbook「Using logprobs」): + +- `logprobs`:bool。為 `true` 時回傳 message content 每個 output token 的 log probability +- `top_logprobs`:**0 到 5 的整數**,指定每個 token 位置要回傳多少個最可能的 token 及其 log probability;使用此參數時 `logprobs` 必須為 `true` +- logprob 即 `log(p)`,`p` = 在該位置給定前文的 token 機率 +- 官方 cookbook 的示範用例**就是分類**:對 headline 做分類時用 `logprobs=True, top_logprobs=2`,再讀 `response.choices.logprobs.content.top_logprobs` +- 出處:`https://developers.openai.com/cookbook/examples/using_logprobs` + +回應物件形狀(社群逐字貼出的回應,非官方頁面):`logprobs.content[]` 每項含 `token` / `logprob` / `bytes`(UTF-8 位元組的十進位值陣列)/ `top_logprobs[]`;較新的模型在 `top_logprobs[]` 每項另有 `prob` 欄位。出處:`https://community.openai.com/t/logprobs-in-chatcompletion/329471`、`https://community.openai.com/t/how-do-logprobs-work-for-chat-completion-api-for-gpt-4-1/1357590`(**社群貼文,非官方**) + +限制與事實: + +- `top_logprobs` 上限 5 → 若選項數多於 5,無法用單次呼叫取得完整選項分布 → **推測**(此限制為官方明載;推論是「需分次呼叫或改 prompt 設計」) +- 官方 API reference 曾註明此選項在 `gpt-4-vision-preview` 上不支援(社群貼文引述官方文字) +- 多個 OpenAI 相容服務都實作同一組參數:vLLM(含 `prompt_logprobs` 擴充)、DeepInfra、FuriosaAI 等 → 出處:`https://docs.deepinfra.com/chat/log-probs`、`https://developer.furiosa.ai/latest/en/furiosa_llm/examples/online_chat_completion_logprobs.html` + +--- + +## §7 是否存在多廠商共用的「決策 API」標準 + +**查不到。** + +以 tavily-search(basic)查「standardized decision API specification multiple vendors classification probability protocol」,回傳的都是**工具/API 描述類**協定,與「回傳選項機率」無關: + +- OpenAPI / AsyncAPI(API 描述格式)— `https://www.infoq.com/articles/Standardized-Specification-Driven-API-Lifecycle` +- UTCP(Universal Tool Calling Protocol)— tool discovery / tool call 格式,`https://github.com/universal-tool-calling-protocol/utcp-specification` +- MCP(Model Context Protocol)— 工具/資源/prompt 協定 +- 其餘為 DDS、Enterprise Ethereum、Klarna Agentic Product Protocol 等不相關領域的標準新聞 + +事實陳述:目前**沒有**跨廠商的決策 API 標準;形塑事實標準的是 TypeSafe 自己的 `POST /v1/systemone`,並被至少兩方照抄實作(OpenRouter 路由同一形狀並多回 `id` / `provider` / `usage.cost`;Laya 的 `laya-serve` 同 path、同 request、同 answers key)。出處:`https://openrouter.ai/docs/guides/community/typesafe-sdk`、`NandhaKishorM/laya` 的 `docs/http-api.md`。 + +--- + +## §8 音樂/歌詞匹配領域的先例 + +### 8.1 產品面 + +- 本任務 `prior-art.md` §7.4 已查證的結論:7 個歌詞產品(Namida、Spotube、LX Desktop、LX Mobile、MusicFree、Harmonoid、BetterLyrics)**零個**用 LLM 做歌詞匹配;皆為字串/fuzzy 比對。 +- 音樂領域使用 reranker 或 decision model 的**產品級實作**:**查不到**。 + +### 8.2 學術面(皆為 embedding / retrieval,非 decision model) + +| 論文 | arXiv ID | 版本時間 | 主題 | +|---|---|---|---| +| Melody-Lyrics Matching with Contrastive Alignment Loss | 2508.00123v1 | 2025-07-31 | 旋律與歌詞的對比對齊;摘要首句「The connection between music and lyrics is far beyond semantic bonds.」 | +| Leveraging Whisper Embeddings for Audio-based Lyrics Matching | 2510.08176v2 | v2 更新於 2026-02-05 | 以 Whisper embeddings 做 audio-based lyrics matching,主打替代既有 content-based retrieval | + +出處:`https://arxiv.org/abs/2508.00123v1`、`https://arxiv.org/abs/2510.08176v2`(以 arXiv API 取得 metadata)。 + +- 另有大量「metadata fuzzy matching / cross-encoder reranking」的通用教材與業界文章(如 `https://dataladder.com/fuzzy-matching-101`),但都不是音樂或歌詞領域。 +- 音樂 metadata 匹配的既有做法仍是 fuzzy matching(`rapidfuzz`)與 S-BERT embeddings;一篇 ACL 2024 NLP4MusA 論文在做 cover song identification 時比較 fuzzy matching 與 S-BERT,結論是 S-BERT 較好、fuzzy matching 只對歌名變體等情況夠用(`https://aclanthology.org/2024.nlp4musa-1.8.pdf`) + +### 8.3 最接近的業界樣板(但非音樂領域) + +TypeSafe 官方的 entity alignment cookbook(§1.7)就是「兩份商品目錄的 metadata 去重」,含模糊容錯(`American Barleywine` vs `Barley Wine`)。它是本研究找到**唯一**由模型廠商自己示範的「metadata 對不對得上」配方,但**領域是啤酒目錄,不是音樂**。出處:`https://docs.typesafe.ai/cookbooks/entity_alignment` + +--- + +## §9 未確認事項 + +以下三項是本檔最不確定的事實,皆已在上文標註,集中列出: + +1. **OpenRouter 是否為 System One 的正式合作夥伴**:`https://openrouter.ai/docs/guides/community/typesafe-sdk` 的頁面路徑含 `/community/`,且該頁同時描述「指向 OpenRouter 即可計費於 OpenRouter 帳號」;TypeSafe 官方 docs 的 111 頁清單裡**沒有**任何 OpenRouter 頁面 → 只能確認「OpenRouter 有這個能力」,雙方的合作關係性質查不到。 +2. **`@typesafe-ai/sdk` 是否能在瀏覽器跑**:npm metadata 只寫 `engines.node >= 20`、README 未提瀏覽器;官方 docs 無 browser 章節 → 未確認。若要在 Flutter Web / 桌面端直接呼叫,這一點是關鍵未知。 +3. **各開源 Jev 複刻的實際行為**:`SemIf-OpenJev`(4,455 stars)與 `razorback16/openjev`(465 stars)等高 star 專案的 star 數與描述取自 `gh search repos` 快照,repo 壽命只有 9–11 天,**未執行、未讀其推論程式碼**,其自稱(例如「beating TypeSafe Jev」)一律未經驗證。 + +### 其他查不到 / 未驗證項 + +- TypeSafe 訓練資料來源(官方 blog FAQ 有此標題,本次未取得答案內文) +- TypeSafe 是否有免費額度、early access 的申請與審核流程 +- TypeSafe ZDR / DPA 的具體條款內容 +- Jev 1.13 的官方 benchmark 數字(官方另有 `model-jaggedness/jev-1.13` 頁面,本次未讀) +- GLiClass 的 CJK / 多語能力描述 +- 行動端(Android / iOS)上跑本節任一 reranker 或 decision model 的實測數據:**查不到**(本節只查了模型大小與授權,未查 ONNX / llama.cpp 在行動裝置的支援矩陣) diff --git a/.trellis/tasks/09-28-design-lyrics/research/extra-features.md b/.trellis/tasks/09-28-design-lyrics/research/extra-features.md new file mode 100644 index 000000000..830338e7d --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/research/extra-features.md @@ -0,0 +1,771 @@ +# 額外功能的事實查證:逐字歌詞、逐字渲染、桌面穿透/鎖定、Android 懸浮與狀態列、iOS + +- 查證日:**2026-09-28**(本檔所有條目均為此日查證) +- **本檔只寫事實與出處,不含設計建議。** 查不到寫「查不到」;由間接證據推論者標「**推測**」。 +- 方法限制:**未呼叫任何音樂平台的真實 API**;**未對任何裝置下 adb / 模擬器指令**(需要實測才能定論的條目一律標「需實測」)。歌詞文本一律以佔位符表示(「字」「word」),不貼真實歌詞內容。 +- GitHub 連結一律為**固定 commit SHA 的 permalink**。 + +## 與同目錄其他研究的關係(避免重複) + +| 檔案 | 內容 | 本檔如何處理 | +|---|---|---| +| `prior-art.md` | 產品面:各家歌詞功能、插件化、匹配與改選、桌面歌詞有無 | 已查過的產品層結論**不重複**,只補「實作層」細節 | +| `packages-and-platform.md` | 套件與平台:多視窗、`window_manager` 各平台能力、Android SAW 權限、iOS 預算、Dart LRC 套件 | 標註「見 §」處僅補新事實 | +| `current-state.md` | 舊 FMP 的歌詞實作 | 不涉及 | +| `ai-decision-models.md` | 決策模型/reranker | 不涉及 | + +## 標記約定 + +| 標記 | 意義 | +|---|---| +| 逐字 | 直接引用來源文字 | +| 一手 | 官方文件、原始碼、官方 API | +| 二手 | 部落格、論壇、教學站 | +| 推測 | 非來源明言,由間接證據推得 | +| 查不到 | 本次查證未找到來源 | + +## 引用來源 SHA 一覽 + +| 專案 | repo | commit SHA | +|---|---|---| +| LX Music Desktop | `lyswhut/lx-music-desktop` | `ad95d5091c9ed689fa72b5e5c849df65f5a679ce` | +| LX Music Mobile | `lyswhut/lx-music-mobile` | `fb8480728d875fa5e0da25eebd3a26bb71723aae` | +| Lyricify-Lyrics-Helper | `WXRIW/Lyricify-Lyrics-Helper` | `cabe0b71d443a9b882a35c60c4f7f21addcbe751` | +| AMLL | `amll-dev/applemusic-like-lyrics` | `86200dead453bb067e554e989110cbadca8d4756` | +| Namida | `namidaco/namida` | `acb1e1622600440cc793f389f497e6771c732c5e` | +| BetterLyrics | `jayfunc/BetterLyrics` | `97629ddf085877cdc90de8cb56006a023320fe00` | +| go-musicfox | `anhoder/go-musicfox` | `12169a71098f8b8607bcf655eaddabf57ca14daf` | +| ESLyric-LyricsSource | `Robotxm/ESLyric-LyricsSource` | `ebaf516f01292895a02c62383717c7500acf95f1` | +| MediaIsland | `bywhite0/MediaIsland` | `c5afb2cff4f331dec70c0c99c96a6e9b738cb81d` | +| kotonoha | `locez/kotonoha` | `175cfcc04ffb67fbbba26c76437275083090233a` | +| goqdes | `lxsrcs/goqdes` | `b1886b062367ff15466d9d2d1c6ff4b1050639f9` | +| LyricTools | `blockshy/LyricTools` | `76042ecd492dd07444fab9171e6f67fa70f81416` | +| flutter_lyric | `ozyl/flutter_lyric` | `b5151e6344e39f35dbc69d2e6d531464d27f9207` | +| flutter_overlay_window | `X-SLAYER/flutter_overlay_window` | `111b21041ac3250a965a8ce1705e210c414a7a62` | +| audio_service | `ryanheise/audio_service` | `da405ddd07840d5861a09ab252cce6f40cc95a0b` | +| window_manager | `leanflutter/window_manager` | `4080b59c0b1084c6085f1613c660382cd164ad76` | +| desktop_lyrics | `587626/desktop_lyrics` | `e92aa0e2c0831285570974883f1dd99b36354958` | +| MusicFree | `maotoumao/MusicFree` | `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee` | +| StatusBarLyric | `Block-Network/StatusBarLyric` | `bd2ec998c4a4d667d5e0602923bdd9cfec330a54` | +| lyricon | `tomakino/lyricon` | `c93da0eef8b7aee015d2670b48e9e262fcf72cd1` | +| SuperLyric | `HChenX/SuperLyric` | `bfca70931651f9c5acc69e088140cc1210780405` | +| SuperLyricApi | `HChenX/SuperLyricApi` | `b7ad6e48360cb5e054b523e9f9dc5727d99755af` | +| Lyric-Getter | `xiaowine/Lyric-Getter` | `9e6d3f72694b08f56dce0b1a4524e18dc56f5c09` | +| HiMoriafly | `Moriafly/HiMoriafly` | `98e04b2cf53aa65fa998a424cf328330fe345044` | + +> 註:`Binaryify/NeteaseCloudMusicApi` 在查證日**已被清空**(root 只剩 `README.MD`,`module/` 不存在),無法作為出處;網易雲一節改用 go-musicfox 與 LX 兩個獨立實作交叉比對。 + +--- + +# §1 逐字(word-level)歌詞的取得與正規化 + +## 1.1 網易雲 YRC + +**取得**(LX desktop):`POST https://interface3.music.163.com/eapi/song/lyric/v1`,參數 `{ id, cp:false, tv:0, lv:0, rv:0, kv:0, yv:0, ytv:0, yrv:0 }`;go-musicfox 走 `https://interface.music.163.com/eapi/song/lyric/v1`,同參數但值以**字串**送出,註解稱其為 “Netease 'lyric/new' API”。兩份實作**都送 `yv`**,且全 0 仍拿得到 yrc。 +→ [LX `src/renderer/utils/musicSdk/wy/lyric.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/musicSdk/wy/lyric.js)、[go-musicfox `utils/netease/lyric.go`](https://github.com/anhoder/go-musicfox/blob/12169a71098f8b8607bcf655eaddabf57ca14daf/utils/netease/lyric.go) + +**回應欄位**(兩份實作一致,皆為 `.lyric` 字串): + +| 欄位 | 內容 | +|---|---| +| `lrc.lyric` | 行級原文 | +| `tlyric.lyric` | 行級翻譯 | +| `romalrc.lyric` | 行級羅馬音 | +| `yrc.lyric` | **逐字原文** | +| `ytlrc.lyric` | **逐字翻譯**(同 YRC 格式) | +| `yromalrc.lyric` | **逐字羅馬音**(同 YRC 格式) | + +`kv`(karaoke)對應的回應欄位名:**查不到**(兩份實作都沒讀)。各旗標字母的逐字語意**查不到**(無規範);`l/t/r/y/k` 的推測對應見來源註解 → **推測**。 +→ [go-musicfox `internal/structs/lyric.go`](https://github.com/anhoder/go-musicfox/blob/12169a71098f8b8607bcf655eaddabf57ca14daf/internal/structs/lyric.go) + +**YRC 行格式**(LX 正則 `lineTime: /^\[(\d+),\d+\]/`、`wordTime: /\(\d+,\d+,\d+\)/`): + +``` +[行開始ms, 行長度ms](詞1開始ms, 詞1長度ms, 0)字(詞2開始ms, 詞2長度ms, 0)word… +``` + +- **時間單位 = 整數毫秒**;**詞時間是絕對時間**(不是相對行首)。證據:LX 轉 lxlrc 時做的是「詞絕對 ms − 行絕對 ms」;Lyricify 產生音節時直接 `new SyllableInfo(text, wordTimespan, wordTimespan + wordDuration)`,**沒有再加行首**。 +- **詞標籤第三欄固定為 `0`**(兩份實作都忽略;AMLL 正則直接寫死 `,0)`)。 +→ [AMLL `formats/yrc.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats/yrc.ts)、[Lyricify `Parsers/YrcParser.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Parsers/YrcParser.cs) + +**metadata / credits 行**:除歌詞行外,每行一個 JSON 物件(行首 `{`)。LX 判定 `info: /^{"/`,取 `info.t`(ms)與 `info.c.map(t => t.tx).join('')`;Lyricify 解析成 `CreditsInfo`,並在首個 credit 以「作詞」開頭時抽出 `Writers`。其他欄位語意**查不到**。 + +**降級**:LX **不留逐字翻譯**——`info.tlyric = this.fixTimeTag(result.lyric, lines.join('\n'))` 傳入的是**行級** `result.lyric`。逐字翻譯的詞時間是否與主 YRC 逐詞對應:**查不到**。 + +## 1.2 QQ 音樂 QRC + +**取得**:`POST https://u.y.qq.com/cgi-bin/musicu.fcg`,body 內 `req.param` 帶 `{ format:'json', crypt:1, qrc:1, roma:1, trans:1, songID, … }`;回應位置 `body.req.data.lyric` / `.trans` / `.roma`,三者皆為**加密字串**。Lyricify 的回應 model `QqLyricsResponse { Lyrics, Trans }` —— **只有兩個欄位,沒有 roma**。 +→ [LX `tx/lyric.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/musicSdk/tx/lyric.js)、[Lyricify `Decrypter/Qrc/Model.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Decrypter/Qrc/Model.cs) + +**金鑰(固定,24 bytes ASCII)**:`!@#)(*$%123ZXC!@!@#)(NHL` —— **四份獨立來源一致**(LX byte array、Lyricify 字面字串、AMLL 拆三段各 8 bytes、ESLyric `createUtf8Bytes`)。 +→ [LX `tx/qrcDecode.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/musicSdk/tx/qrcDecode.js)、[AMLL `formats/eqrc/constants.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats/eqrc/constants.ts)、[ESLyric `current/qrc/lib/qrc-decryptor/qrc-decryptor.js`](https://github.com/Robotxm/ESLyric-LyricsSource/blob/ebaf516f01292895a02c62383717c7500acf95f1/current/qrc/lib/qrc-decryptor/qrc-decryptor.js) + +**演算法**:3DES(DES-EDE3)、ECB、8-byte 分塊、零填充,之後 **zlib inflate**。AMLL 解密序 `D(K3) → E(K2) → D(K1)`;輸入是**十六進位字串**。步驟:hex→bytes(長度需為 8 倍數)→ 每 8 bytes 3DES 解密 → zlib inflate → 去 UTF-8 BOM → UTF-8 解碼。 +→ [AMLL `formats/eqrc/index.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats/eqrc/index.ts) + +**非標準 DES S-box(陷阱)**:QRC 用的是 DES 變體,**`S2[23]=15`、`S4[53]=10`**(標準為 14、1)。LX 原始碼註解明寫此事,AMLL 與 ESLyric 的陣列人眼核對一致(**三份一致**)。→ **不能直接用現成 DES 函式庫解 QRC**。 + +**解密後格式**:外層是 XML(``),`LyricContent` 是**屬性**;剝殼後為: + +``` +[行開始ms, 行長度ms](詞1開始ms, 詞1長度ms)字(詞2開始ms, 詞2長度ms)word… +``` + +- 詞標籤**只有兩個欄位**(沒有 YRC 的第三個 `0`)。時間單位 = 整數毫秒;**詞時間絕對**(Namida `span.start = int.parse(time[0])`、Lyricify `endTime = startTime + duration` 皆未加行首)。 +→ [AMLL `formats/qrc.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats/qrc.ts)、[Namida `parser_qrc.dart`](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/packages/lyrics_parser/parser_qrc.dart) + +**翻譯 / 羅馬音**:來源是同一份 XML 內的另一個 `Lyric_1` 節點(以 `LyricType` 區分)或回應的 `.trans` / `.roma`。LX 剝殼後直接餵 `lrc-file-parser`,**沒有做詞級對齊**。`LyricType` 其他值的語意、`trans`/`roma` 是行級還是逐字:**皆查不到**(未取樣本)。 + +## 1.3 Kugou KRC + +**magic**:4-byte ASCII `krc1`(kotonoha `KRC_MAGIC = b"krc1"`;MediaIsland 註解同)。LX 只寫 `subarray(4)` 丟掉前 4 bytes,未命名該 magic。 +→ [kotonoha `krc_parser.py`](https://github.com/locez/kotonoha/blob/175cfcc04ffb67fbbba26c76437275083090233a/src/kotonoha/lyrics/krc_parser.py)、[MediaIsland `KrcDecrypter.cs`](https://github.com/bywhite0/MediaIsland/blob/c5afb2cff4f331dec70c0c99c96a6e9b738cb81d/MediaIsland/Services/Lyrics/Crypto/KrcDecrypter.cs) + +**金鑰(16 bytes,三份一致)**: + +``` +0x40,0x47,0x61,0x77,0x5e,0x32,0x74,0x47,0x51,0x36,0x31,0x2d,0xce,0xd2,0x6e,0x69 +``` + +(kotonoha 註解:「it is part of the file format, not a secret」。) + +**完整解密步驟**:① base64 解碼 → ② **丟掉前 4 bytes** → ③ 逐 byte XOR `b[i] ^= key[i % 16]`(索引自 body 起點重新起算)→ ④ **zlib inflate** → ⑤ UTF-8 解碼。 +- Lyricify 另有一步**解壓後再去掉第 1 個字元**(`res[1..]`)——這與 LX 的 `subarray(4)` 是**不同階段**,勿混淆。 +- 取檔 URL(Lyricify):`https://lyrics.kugou.com/download?ver=1&client=pc&id={id}&accesskey={accesskey}&fmt=krc&charset=utf8` +→ [LX `src/common/utils/lyricUtils/kg.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/common/utils/lyricUtils/kg.js)、[Lyricify `Decrypter/Krc/Decrypter.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Decrypter/Krc/Decrypter.cs) + +**解密後格式**:可能先有一行 `[id:$xxxx]` 標頭(LX `headExp = /^.*\[id:\$\w+\]\n/`)。 + +``` +[行開始ms, 行長度ms]<詞1開始ms, 詞1長度ms, 0>字<…>word… +``` + +- 時間單位 = 整數毫秒;**詞時間相對行首**(與 YRC/QRC 相反)。證據:Lyricify `StartTime = lineStart + start`、`EndTime = lineStart + start + duration` —— **有加行首**。 +- 拆詞(Lyricify):`line[(line.IndexOf(']')+1)..].Split(",0>")`,第一個詞去掉開頭的 `<`。純行級=刪掉所有 ``。 +→ [Lyricify `Parsers/KrcParser.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Parsers/KrcParser.cs) + +**`[language:]` metadata**:base64 解出 JSON,`json.content[]` 每項有 `type` 與 `lyricContent`:**`type:0` = 羅馬音、`type:1` = 翻譯**。`lyricContent` 是「每行一個字串陣列」的陣列。**KRC 的翻譯/羅馬音是行級,不是逐字**——證據:LX 用**同一個行序號 `i`** 把主歌詞的行時間標籤前置到 `rlyric[i]` / `tlyric[i]`。 + +## 1.4 Apple Music TTML + +**命名空間**:`tt`=`http://www.w3.org/ns/ttml`、`ttm`=`…#metadata`、`itunes`=`http://music.apple.com/lyric-ttml-internal`、`xml`=`http://www.w3.org/XML/1998/namespace`。結構:`` → ``(metadata / translations / agents / iTunesMetadata)+ `` → `

    ` → `

    `(行)→ ``(詞)。 +→ [Lyricify `Parsers/TtmlParser.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Parsers/TtmlParser.cs)、[AMLL `packages/ttml/src/constants.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/ttml/src/constants.ts) + +**逐字表達**:`字` 嵌在 `

    ` 內。 +- **`itunes:timing`** 值 `"Word"` / `"Line"`:AMLL 讀它並在**屬性不存在時靠推斷**(任一行有 >1 個 word 即判 `"Word"`);**Lyricify 不看 `itunes:timing`**,只靠 `` 是否存在判斷。 +- Ruby(注音):`tts:ruby`(`container`/`base`/`textContainer`/`text`)。 +- 背景人聲:`ttm:role="x-bg"`。對唱:`ttm:agent`;AMLL 的 `Agent.id` 有 `v1`(非對唱)/`v2`(對唱),Apple 的檔案另有 `v3`/`v4`…(各演唱者)與 `v1000`(合唱)。 +→ [AMLL `packages/ttml/src/parser.ts`、`types/index.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/ttml/src/parser.ts) + +**時間單位 = 秒(可含小數)**:結尾帶 `s` → 直接當秒;`hh:mm:ss` / `mm:ss` → 各段相加;最後乘 1000 轉 ms(Lyricify 用 `MidpointRounding.AwayFromZero`;AMLL 用 `Math.round`)。(對照:ASS 卡拉 OK 以**厘秒**計,AMLL 由 ms 導出 ASS 四捨五入,**誤差至多 10 ms**。) + +**翻譯 / 音譯**:行級放在 ``(``,以 `for` 屬性對應主 `

    `);**逐字翻譯/音譯在同一檔內以 span 的 `ttm:role` 標記**:`x-translation`(翻譯)、`x-roman`(羅馬音)、`x-bg`(背景人聲),時間與主 span 一樣用 `begin`/`end`(秒)。AMLL 產生器有 `useSidecar` 選項,但**逐字翻譯/音譯一律強制放 ``**,只有逐行可選內嵌。BetterLyrics 對內嵌逐字翻譯**只取 span 整體文字並沿用父行時間** → **逐字翻譯被壓成行級**。 +→ [AMLL `packages/ttml/src/types/index.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/ttml/src/types/index.ts)、[BetterLyrics `LyricsContentParser.Ttml.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Helpers/Lyrics/ContentParser/LyricsContentParser.Ttml.cs) + +## 1.5 Spotify richsync / Musixmatch richsync + +- **Spotify**:`SpotifyLyrics.syncType` ∈ `UNSYNCED` / `LINE_SYNCED` / `SYLLABLE_SYNCED`;行 `SpotifyLyricsLine { startTimeMs, endTimeMs(ms 的**字串**), words(整行文字), syllables }`;詞 `SyllableItem { startTimeMs, endTimeMs, numChars }` —— **詞的文字不是獨立欄位**,用累計 `numChars` 從 `line.words` 切出。時間單位 ms、**詞時間絕對**。 +- **Musixmatch**:`calls["track.richsync.get"].body.richsync.richsync_body` 是**一個 JSON 字串**,解出 `RichSyncedLine { "ts"→TimeStart(float 秒), "te"→TimeEnd(float 秒), "l"→Words[], "x"→Text }`;`Word { "c"→Chars, "o"→Position(double 秒) }`。**時間單位秒(浮點);詞的 `Position` 相對行首**(`StartTime = start + (int)(words[i].Position*1000)`;最後一詞 `EndTime = (int)(line.TimeEnd*1000)`)。 +→ [Lyricify `Parsers/Models/Spotify.cs`、`Musixmatch.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/tree/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Parsers) + +## 1.6 ESLrc / LRC A2 / SPL(Enhanced Synced LRC 系) + +- AMLL 把三者統一成一個 `LrcParser`,`mode` ∈ `"plain"`(不保留逐字)/ `"enhanced"`(逐字)/ `"spl"`(Salt Player Lyrics,前兩者超集,**解析預設值**)。 +- **逐字語法:行內時間戳 `` 或 `[mm:ss.ms]`**,置於該字之前。正則 `/(?:\[|<)(?\d{1,3}):(?\d{1,2})(?:[:.](?\d{1,6}))?(?:\]|>)/g`。 +- 時間欄位規則:分 1–3 位、秒 1–2 位、毫秒 1–6 位;**毫秒不足三位視為後位補 0**(`.1`=100 ms、`.02`=20 ms),超過三位**截斷**;秒與毫秒間也接受冒號。 +- **內部時間單位一律 ms**。 +→ [AMLL `packages/lyric/src/formats/lrc/types.ts`、`parser.ts`、`utils.ts`](https://github.com/amll-dev/applemusic-like-lyrics/tree/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats/lrc) + +**ESLrc 的正式規格文件:查不到**(找不到 Salt Player / ESLyric 的正式格式文件;以上全由實作反推)。 + +## 1.7 正規化成單一內部結構(各產品的欄位名) + +### AMLL(`@applemusic-like-lyrics/lyric`,AGPL-3.0-only) + +```ts +export interface LyricWord { startTime: number; endTime: number; word: string; romanWord?: string; } +export interface LyricLine { words: LyricWord[]; translatedLyric: string; romanLyric: string; + isBG: boolean; isDuet: boolean; startTime: number; endTime: number; } +export interface TTMLLyric { lines: LyricLine[]; metadata: [string, string[]][]; } +export type LyricParseResult = TTMLLyric; +``` + +- **時間單位 = ms(number)**;`LyricLine.startTime` **不保證等於 `words[0].startTime`**(官方註記)。 +- 翻譯與羅馬音在此結構中是**行級字串**;`LyricWord` 另有**詞級** `romanWord?`;**逐字翻譯在核心結構裡沒有欄位**。 +- TTML 專用層(`packages/ttml`)欄位更豐富:`Syllable { text, startTime, endTime, endsWithSpace?, ruby?, obscene?, emptyBeat? }`;`LyricLine { …, words?: Syllable[], translations?: SubLyricContent[], romanizations?: SubLyricContent[], backgroundVocal?, agentId?, … }`;`SubLyricContent { language?, text, words?: Syllable[] }` → **TTML 這一層支援逐字翻譯/音譯**。 +- 支援的格式函式(`parseX`/`stringifyX`):`ass`、`lqe`、`eslrc`、`lrc`、`lrcA2`、`lrcLike`、`spl`、`lyl`、`lys`、`qrc`、`ttml`、`yrc`,以及 `decryptQrcHex`/`encryptQrcHex`。**沒有 krc**。 +→ [AMLL `packages/lyric/src/types.ts`、`index.ts`、`packages/ttml/src/types/index.ts`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/types.ts) + +### Lyricify(C#) + +| 型別 | 欄位 | +|---|---| +| `ISyllableInfo` | `string Text`、`int StartTime`、`int EndTime`、`int Duration => EndTime - StartTime` | +| `ILineInfo` | `Text`、`int? StartTime/EndTime/Duration`、`StartTimeWithSubLine`…、`LyricsAlignment`、`ILineInfo? SubLine`、`FullText` | +| `SyllableLineInfo : ISyllableInfo[]` | `List Syllables`、`Text`(串接)、`StartTime => First().StartTime`、`EndTime => Last().EndTime`、`bool IsSyllable` | +| `FullLineInfo : LineInfo` | `Dictionary Translations`、`string? Pronunciation` | +| `LyricsData` | `FileInfo?`、`List? Lines`、`List? Writers`、`ITrackMetadata?` | +| `enum SyncTypes` | `Unknown=0, SyllableSynced=1, LineSynced=2, MixedSynced=3, Unsynced=4` | +| `enum LyricsTypes` | `…, LyricifySyllable=1, LyricifyLines=2, Lrc=3, Qrc=4, Krc=5, Yrc=6, Ttml=7, Spotify=8, Musixmatch=9` | + +- **時間單位 = `int` 毫秒**。**逐字翻譯不存在**:`Translations` 是 `Dictionary`,**只有行級**。另有 `SyllableWordMerger` 把相鄰非 CJK 音節併成 `FullSyllableInfo`。 +→ [Lyricify `Models/`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/tree/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Models) + +### Lyricify Syllable(`.lys`)/ Lyricify Lines(`.lyl`) + +- `.lys`:`[prop]字(startMs,durMs)word(startMs,durMs)…`。`prop`(0–8):`isDuet = prop % 3 === 2`、`isBG = prop >= 6`;主行 Left→4/Right→5/Unspecified→3,子行 Left→7/Right→8/Unspecified→6。詞時間**絕對 ms**;行頭=第一詞 start、行尾=最後一詞 end。 +- `.lyl`:`[type:LyricifyLines]` + `[startMs,endMs]字…`(純行級,無逐字)。 +→ [AMLL `formats/lys.ts`、`lyl.ts`](https://github.com/amll-dev/applemusic-like-lyrics/tree/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/src/formats) + +### BetterLyrics(WinUI3,C#) + +- 底層**直接用 Lyricify 的 parser**(QRC/KRC 走 `QrcParser` / `KrcParser`);LRC/ESLrc 與 TTML 才是自寫。 +- 自家模型 `BaseLyrics { int StartMs, int? EndMs, int DurationMs, string Text, int Length, int StartIndex, int EndIndex }`;`LyricsLine : BaseLyrics` 有 `PrimarySyllables` / `Secondary` / `Tertiary`、`PrimaryChars`、`IsPrimaryHasRealSyllableInfo`、`AgentId`。**三軌結構**:Primary=原文、Secondary=翻譯、Tertiary=注音。 +- 逐字補償:對每個音節以 `avgCharDuration = syllable.DurationMs / syllable.Length` 把時間**平均攤到每個字元**(`PrimaryChars`)。 +→ [BetterLyrics `Models/Lyrics/`](https://github.com/jayfunc/BetterLyrics/tree/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.Core/Models/Lyrics) + +### Namida(Flutter) + +| 型別 | 欄位 | +|---|---| +| `LyricsLineModel` | `String? mainText`、`extText`、`int? startTime`、`endTime`、`List? spanList`;`Duration? get timeStamp => Duration(milliseconds: startTime!)` | +| `LyricSpanInfo` | `int index`(行文字中的起始**字元**索引)、`int length`、`duration`、`start`、`String raw`、`drawWidth`、`drawHeight`;`end => start + duration`、`endIndex => index + length` | + +- 時間單位 = ms(int),QRC 詞時間**絕對**;詞與文字用**字元 index/length** 表示。 +→ [Namida `lib/packages/lyrics_parser/models.dart`](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/packages/lyrics_parser/models.dart) + +### LX(`lxlrc`,四條平行字串,不轉物件) + +| 欄位 | 內容 | 格式 | +|---|---|---| +| `lrc` | 行級原文 | `[mm:ss.xxx]字…` | +| `tlrc` | 行級翻譯 | `[mm:ss.xxx]字…` | +| `rlrc` | 行級羅馬音 | `[mm:ss.xxx]字…` | +| `lxlrc` | **逐字原文** | `[mm:ss.xxx]<詞相對ms,詞長度ms>字<…>word…` | + +- `lxlrc` 詞時間**相對行首**、單位 ms;**不含行結束時間**(行尾由最後一個詞推得)→ **推測**。IPC 合約 `set_info` 帶這四個欄位。 +→ [LX `src/common/types/desktop_lyric.d.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/common/types/desktop_lyric.d.ts) + +### 共同語意彙整 + +| 格式 / 產品 | 詞時間單位 | 相對 / 絕對 | 逐字翻譯欄位 | 逐字音譯欄位 | +|---|---|---|---|---| +| 網易雲 YRC | ms (int) | **絕對** | `ytlrc`(同格式) | `yromalrc`(同格式) | +| QQ QRC | ms (int) | **絕對** | `trans`(格式未證實) | `roma`(格式未證實) | +| Kugou KRC | ms (int) | **相對行首** | `[language:]` JSON `type:1`(**行級**) | `type:0`(**行級**) | +| Apple TTML | 秒(小數)→ ms | 絕對 | `ttm:role="x-translation"` span(**詞級**) | `x-roman` span(**詞級**) | +| ESLrc / LRC A2 / SPL | 文字 `mm:ss.ms` | 絕對 | 無原生 | 無原生 | +| Spotify richsync | ms(字串) | 絕對 | 無 | 無 | +| Musixmatch richsync | 秒(float)→ ms | 相對行首 | 無 | 無 | +| LX `lxlrc` | ms (int) | **相對行首** | 無(另存 `tlrc` 行級) | 無(另存 `rlrc` 行級) | +| Lyricify `ISyllableInfo` | ms (int) | 依來源 | **無**(行級 dictionary) | **無**(行級 `Pronunciation`) | +| BetterLyrics `BaseLyrics` | ms (int) | 依來源 | 三軌 `SecondarySyllables` | 三軌 `TertiarySyllables` | +| Namida `LyricSpanInfo` | ms (int) | 依來源 | 無 | 無 | +| AMLL `LyricWord` | ms (number) | 依來源 | 行級 `translatedLyric`;TTML 層有 `SubLyricContent.words` | 行級 `romanLyric`;`LyricWord.romanWord` | +| ASS | 厘秒 (cs) | — | 無 | 無 | + +## 1.8 word → line 降級 + +- **Lyricify `SyncDowngrade.DowngradeToLineSynced`**:遞迴處理 `SubLine`;`SyllableLineInfo` → `Text = 詞文字合併回整行`、`StartTime = Syllables.First().StartTime`、`EndTime = Syllables.Last().EndTime`;`Translations` / `Pronunciation` 原樣帶進 `FullLineInfo`(不丟)。即 **行開始=第一詞開始、行結束=最後一詞結束;文字按原順序直接串接,不另加空白**。 + → [Lyricify `Helpers/Optimization/SyncDowngrade.cs`](https://github.com/WXRIW/Lyricify-Lyrics-Helper/blob/cabe0b71d443a9b882a35c60c4f7f21addcbe751/Lyricify.Lyrics.Helper/Helpers/Optimization/SyncDowngrade.cs) +- **AMLL**:**沒有名為 downgrade 的函式**(`packages/lyric/src/` 搜不到 `downgrade`/`toLine`/`flatten`);降級發生在 generator 輸出階段。README 明文規範: + 1. 目標為純行級(`.lrc`、`.lyl`)時逐詞時間戳被剝離、整行合併; + 2. 導出至 LRC 系時翻譯/音譯作為**額外主時間戳行**插入;導出至 YRC/QRC/LYS/LYL 時**翻譯和音譯被丟棄**; + 3. 背景人聲降級為文字兩端包圓括號 `(...)`; + 4. 對唱資訊只有 `LYS`/`LQE`/`TTML` 具備,其他格式導出時**丟失**; + 5. 元數據只有 TTML 與 SPL 支援; + 6. ASS 厘秒折損,誤差至多 10 ms。 + → [AMLL `packages/lyric/README-CN.md`](https://github.com/amll-dev/applemusic-like-lyrics/blob/86200dead453bb067e554e989110cbadca8d4756/packages/lyric/README-CN.md) +- **LX**:**無獨立降級步驟**,解析當下同時產生行級與逐字兩份;KRC 的降級是**刪標籤**(`lxlrc.replace(/<\d+,\d+>/g, '')`)。 +- **line → word(自動斷詞配時)**:**Lyricify / LX / AMLL 都沒有**;BetterLyrics 只有**同一音節內重切**(`SplitIntoTokens` 把一個音節切成多 token 後均分或按比例分時,再用 `SyllableWordMerger.Merge` 併回),**不是**整行→逐字。 + +## 1.9 逐字翻譯 / 羅馬音的對齊依據 + +| 產品 | 對齊依據 | 粒度 | +|---|---|---| +| LX(桌面) | **時間標籤最近匹配,容差 < 100 ms**(`fixTimeTag`) | 行級 | +| MusicFree | **時間戳完全相等**(雙指標,見 prior-art) | 行級 | +| BetterLyrics(LRC 系) | **`StartMs` 完全相等**(`GroupBy(l => l.StartMs)`,**無容差**) | 行級 | +| Lyricify | **沒有翻譯對齊機制**(直接掛在行上) | 行級 | +| Namida | 解析器直接寫在同一行物件 | 行級 | +| AMLL(核心) | 無對齊;翻譯是行上的獨立字串 | 行級 | +| AMLL / Apple TTML | `itunes:key` / `for` 屬性接線;詞級靠 `ttm:role` span 自帶 `begin`/`end` | 行級與**詞級** | +| Kugou KRC | **行序號 `i`**(用主歌詞第 i 行的時間標籤) | 行級 | +| 網易雲 `ytlrc` | 無公開規範;LX 走 `fixTimeTag` | 行級 | + +**LX `fixTimeTag`**:對 `targetlrc` 每行取其時間標籤 `t1`,依序吃掉主歌詞行取 `t2`,若 `|t1−t2| < 100` 則把 target 行的時間標籤改寫成主行原始標籤並收進結果,否則推回;**沒配到的行直接丟棄**。它只比對「行標籤」(正則 `^\[([\d:.]+)\]`),**是行級近似匹配,不是逐字對齊**。 + +> **LX 的已知疑點**:LX 把 YRC 的 `ytlrc` 丟進 `fixTimeTag` 時,來源行仍是 `[start,dur](…)` 形式,而 `fixTimeTag` 的正則需要「僅數字、冒號、句點」的標籤,**逗號會使匹配失敗 → 該行被丟棄**。→ LX 是否真能取得逐字翻譯,**需實測**(本檔標推測)。 +→ [LX `wy/lyric.js`(`fixTimeTag` / `filterExtendedLyricLabel`)](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/musicSdk/wy/lyric.js) + +## 1.10 本節查不到 + +1. 網易雲 YRC 的**官方格式規範**(全部知識來自 LX 與 go-musicfox 實作)。 +2. 網易雲 `lv`/`tv`/`rv`/`kv` 各自對應的回應欄位名、`kv` 的回應欄位。 +3. 非 eapi 的 `/api/song/lyric` 是否接受 `yv`。 +4. QRC 的 `trans` / `roma` 是行級還是逐字;QRC `LyricType` 其他值的語意。 +5. 網易雲 `ytlrc` 的詞時間是否與主 YRC 逐詞對應。 +6. ESLrc(Enhanced Synced LRC)的**正式規格文件**。 +7. `lxlrc` 是否需要行結束時間、行尾如何決定(本檔的推論已標**推測**)。 +8. line → word(自動斷詞配時)在任何一個產品中的完整實作。 + +--- + +# §2 Flutter 的逐字(逐詞)渲染 + +## 2.1 `flutter_lyric` 3.x + +| 項目 | 值 | +|---|---| +| 最新版 | `3.0.8`,發佈 `2026-09-16`;`isDiscontinued` 無值 | +| Likes / 分數 | Likes 109;`grantedPoints 160/160` | +| 授權 | MIT(`license:mit`、`fsf-libre`、`osi-approved`) | +| 平台 | `android, ios, windows, linux, macos, web`;`is:wasm-ready`、`is:dart3-compatible` | +| 釘選 commit | `b5151e6344e39f35dbc69d2e6d531464d27f9207` | + +→ `https://pub.dev/api/packages/flutter_lyric`、`/score`、`https://github.com/ozyl/flutter_lyric` + +**入口類名 `LyricView`**(`StatefulWidget`),構造參數只有四個:`controller`、`width`、`height`、`style`。`build` 回傳 `CustomPaint(painter: LyricPainter(layout:…, playIndex:…, activeHighlightWidth:…, isSelecting:…, scrollY:…, switchState:…, size:…))`。 +→ [flutter_lyric `lib/widgets/lyric_view.dart`](https://github.com/ozyl/flutter_lyric/blob/b5151e6344e39f35dbc69d2e6d531464d27f9207/lib/widgets/lyric_view.dart) + +> **重要更正:`highlightLevel` 參數不存在。** 對 3.0.8 的 `lib/core/lyric_style.dart`、`lib/render/lyric_painter.dart`、`lib/widgets/lyric_view.dart` 三檔 grep `highlightLevel` 皆 **0 筆**。簡報假設的 `highlightLevel` 應為 1.x 版 API。 + +**`LyricStyle` 高亮與對齊參數**(`lib/core/lyric_style.dart`):高亮 `activeHighlightColor` / `activeHighlightGradient` / `activeHighlightExtraFadeWidth`;文字 `textStyle` / `activeStyle` / `translationStyle` / `selectedColor` / `translationActiveColor` / `selectedTranslationColor`;對齊 `lineTextAlign` / `contentAlignment` / `selectionAlignment` / `activeAlignment` / `selectionAnchorPosition` / `activeAnchorPosition`(0–1 相對值,>1 視為像素);行距 `lineGap` / `translationLineGap` / `contentPadding`;漸隱遮罩 `fadeRange`;捲動 `scrollDuration(s)` / `scrollCurve` / `scrollAnimationBuilder` / `selectionAutoResumeDuration` / `activeAutoResumeDuration` / `SelectionAutoResumeMode{selecting, afterSelecting, neverResume}`;行切換 `enableSwitchAnimation` / `switchEnterDuration` / `switchExitDuration`(預設 200 ms)/ `switchEnterCurve` / `switchExitCurve`;其他 `activeLineOnly` / `disableTouchEvent`。斷言:`selectionAutoResumeDuration < activeAutoResumeDuration`。預設樣式 `LyricStyles.default1`。 + +README 逐字: +> 🔥 漸變/顏色高亮:根據播放進度實時推進高亮寬度,可疊加漸變與尾部淡出 +> 📦 內置解析:默認支持 `.lrc`、`.qrc` 與 `.yrc`,可注入自定義解析器 + +**控制器**(`lib/core/lyric_controller.dart`):`ValueNotifier lyricNotifier`、`activeIndexNotifiter`(原文拼字如此)、`progressNotifier`、`selectedIndexNotifier`、`isSelectingNotifier`、`selectedLineHeightNotifier`、`anchorPositionNotifier`、`lyricOffset`(毫秒)。`setProgress(Duration)` → `getIndexByProgress`(二分搜尋);`loadLyric(String, {String? translationLyric})`。 + +**逐詞時間如何到達渲染層**:`LyricLine.words: List` → `LineMetrics.words: List`。 + +| 型別 | 欄位 | +|---|---| +| `LyricModel` | `idTags`、`lines`;getter `title/artist/album/by/offset` | +| `LyricLine` | `start: Duration`、`end: Duration?`、`text`、`translation`、`words: List?` | +| `LyricWord` | `text`、`start: Duration`、`end: Duration?` | +| `LineMetrics` | `textPainter`、`activeTextPainter`、`textMaskPainter`、`activeMaskPainter`、`translationTextPainter`、`words: List` | +| `WordMetrics` | `word`、`width`、`height`、`highlightWidth`、`highlightHeight` | + +→ [flutter_lyric `lib/core/lyric_model.dart`](https://github.com/ozyl/flutter_lyric/blob/b5151e6344e39f35dbc69d2e6d531464d27f9207/lib/core/lyric_model.dart) + +**逐詞高亮的寬度是 `WordMetrics.highlightWidth` 累加**(`lib/widgets/mixins/lyric_line_highlight.dart`):`const Duration _kHighlightTransitionDuration = Duration(milliseconds: 200);`;`updateHighlightWidth()` 以 `currentProgress = controller.progressNotifier.value + Duration(milliseconds: controller.lyricOffset)` 為準,對每個 word 累加 `highlightWidth`,對當前 word 做部分扣除 `newWidth -= wordMetric.highlightWidth * (1 - elapsed / wordDuration);`,補上 `style.activeHighlightExtraFadeWidth`,再用一個 `AnimationController` 以 `Curves.linear` 補間。逐詞 vs 整行由「有無提供逐詞時間」決定(有則 `highlightTotalWidth == activeHighlightWidth`,否則 `double.infinity`)。 + +**內建 LRC → QRC 近似逐詞工具**:`LrcToQrcUtil.convert(String lrc, {Duration? totalDuration, Duration? lastDuration})`,`assert(totalDuration != null || lastDuration != null)`,把每行時長分配給該行各字 → **純 LRC 可被轉成 QRC 形式取得近似逐字,是套件內建能力**。 +→ [flutter_lyric `lib/utils/lyric_lrc_to_qrc.dart`](https://github.com/ozyl/flutter_lyric/blob/b5151e6344e39f35dbc69d2e6d531464d27f9207/lib/utils/lyric_lrc_to_qrc.dart) + +## 2.2 漸變高亮的實作技術(逐字片段) + +**技術是 `CustomPainter` + 分段 `ui.Shader` 矩形 + `saveLayer` 遮罩,不是 `ShaderMask`。** + +```dart +void _drawMaskedHighlightSegments(Canvas canvas, TextPainter maskPainter, Rect bounds, List<_HighlightSegment> segments) { + canvas.save(); + canvas.clipRect(bounds); + canvas.saveLayer(bounds, Paint()); + final paint = Paint(); + for (final segment in segments) { paint.shader = segment.shader; canvas.drawRect(segment.rect, paint); } + canvas.saveLayer(bounds, Paint()..blendMode = BlendMode.dstIn); + maskPainter.paint(canvas, Offset.zero); + canvas.restore(); canvas.restore(); canvas.restore(); +} +``` + +- 高亮顏色:`activeHighlightGradient ?? LinearGradient(colors: [activeHighlightColor!, activeHighlightColor])`,以 `c.withValues(alpha: …)` 套用 `animationOpacity`。 +- `shouldRepaint` 比較 `layout` / `playIndex` / `scrollY` / `activeHighlightWidth` / `switchState`。 +- **`ShaderMask` 只用於上下漸隱邊界**(`lyric_mask_mixin.dart`,`style.fadeRange != null` 時 `LinearGradient(transparent→black→black→transparent, stops [0, top, 1-bottom, 1])` + `BlendMode.dstIn`),**不用於逐詞高亮**。 +- **`ClipRect` 未被用於高亮**,而是 `canvas.clipRect(bounds)`(畫布層 clip)。「`ClipRect` + 兩個 `Text` 圖層」這手法在本套件**查不到**。 +→ [flutter_lyric `lib/render/lyric_painter.dart`、`lib/widgets/mixins/lyric_mask_mixin.dart`](https://github.com/ozyl/flutter_lyric/tree/b5151e6344e39f35dbc69d2e6d531464d27f9207/lib) + +## 2.3 效能相關 + +- **套件原始碼中沒有任何 `RepaintBoundary`**(對 `lib/` 全樹 grep,僅 `lyric_painter.dart` 命中 `shouldRepaint`)。 +- `lib/widgets/highlight_listenable_builder.dart` 的 `SelectListenableBuilder` 為**四層巢狀 `ValueListenableBuilder`**。 +- CHANGELOG 效能相關條目(逐字):`3.0.4` 「Decouple active highlight rendering from active text opacity: dedicated mask painters avoid per-frame text relayout…」;`3.0.3` 「Optimize `LyricPainter` — cache style lookups, reduce redundant object creation, only rebuild TextSpan when color changes」。另 `3.0.4` 有一條非破壞性行為變更:「Active highlight vs. text opacity: Gradients/highlights on the playing line are no longer tied to `activeStyle` text opacity.」 +- `3.0.5` 曾引入動畫生命週期 regression(#39),`3.0.6` 修回。 +- **官方文件/issue 中關於「應關閉哪些效果以換效能」的明文建議:查不到。** + +## 2.4 Flutter 官方漸變技術與成本(官方逐字) + +- **`ShaderMask`**:「A widget that applies a mask generated by a Shader to its child.」→ `https://api.flutter.dev/flutter/widgets/ShaderMask-class.html` +- **`TextStyle.foreground`**(單一圖層漸層文字,不額外開圖層)逐字:「The paint drawn as a foreground for the text. … **The value should ideally be cached and reused each time** if multiple text styles are created with the same paint settings. Otherwise, each time it will appear like the style changed, which will result in unnecessary updates all the way through the framework.」→ `https://api.flutter.dev/flutter/painting/TextStyle/foreground.html` +- **`TextPainter.getBoxesForSelection`**(取字元矩形,逐字含「only returns `TextBox`es of glyphs that are entirely enclosed by the given selection」)→ `https://api.flutter.dev/flutter/painting/TextPainter/getBoxesForSelection.html`。這是「算出每個字/詞覆蓋矩形」的官方 API(`flutter_lyric` 未用它,改走 `WordMetrics.highlightWidth` 累加)。 +- **每幀重建成本**:`State.build` 逐字「This method can potentially be called in every frame…」;`docs.flutter.dev/perf/best-practices` 逐字「Avoid repetitive and costly work in build() methods…」。 +- **`RepaintBoundary`** 逐字:「A widget that creates a separate display list for its child. … Containing `RenderObject.paint` to parts of the render subtree that are actually visually changing using `RepaintBoundary` … is therefore critical to minimizing redundant work…」。 +- **`saveLayer()` 成本**(`docs.flutter.dev/perf/best-practices` 逐字):「Some Flutter code uses `saveLayer()`, **an expensive operation**, to implement various visual effects… excessive calls to `saveLayer()` can cause jank.」「Calling `saveLayer()` allocates an offscreen buffer and drawing content into the offscreen buffer might trigger a render target switch… On mobile GPUs this is particularly disruptive to rendering throughput.」→ 對照:`flutter_lyric` 的逐詞高亮每個高亮段都走 `canvas.saveLayer`。 +- 「`ClipRect` + 兩個 `Text` 圖層」手法的官方來源:**查不到**(較接近的官方替代是 `TextStyle.foreground`)。 + +## 2.5 其他 Flutter 歌詞/逐字套件(pub.dev 普查) + +| 套件 | 版本 | 發佈日 | Likes | 授權 | 平台 | 說明 | +|---|---|---|---|---|---|---| +| `flutter_lyric` | 3.0.8 | 2026-09-16 | 109 | MIT | 全平台 | **本次唯一查到、解析器明文支援 `.qrc` 的渲染套件** | +| `lyrics_parser` | 1.0.0-nullsafety.0 | 2021-02-03 | 12 | MIT | android, ios, windows, linux, macos | 解析庫,**無 `platform:web` 標籤** | +| `desktop_lyrics` | 0.0.8 | 2026-07-09 | 0 | MIT | **僅 windows/linux/macos** | 桌面歌詞視窗(非 Android) | +| `lyric_xx` | 0.7.6 | 2025-03-26 | 1 | MIT | 全平台 | 描述逐字「A Flutter package to encode and decode lrc.」→ **純編解碼** | +| `my_lyric` | 0.3.2 | 2024-11-24 | 2 | MIT | 全平台 | 描述逐字同 `lyric_xx` → **純編解碼** | +| `amlv` | 1.0.2 | 2023-11-01 | 15 | MIT | 全平台 | 「Inspired by Apple Music's Lyrics Viewer…displays lyrics(srt, lrc, json)…」→ **無逐詞字樣** | +| `lrc` | — | — | 18 | BSD-3-Clause | 全平台 | LRC 解析 | +| `lyrics` | — | — | 9 | BSD-3-Clause | — | **`is:dart3-incompatible`**、`grantedPoints 20/160` | + +- **QRC 格式的原生 Flutter 渲染套件:除 `flutter_lyric` 外查不到**(`pub.dev` 搜 `qrc` 全為 QR code 類)。 +- **`lyrics_parser` 與 Dart 3 不相容的說法在 pub.dev 標籤上查不到**(反而標 `is:dart3-compatible`);明確標 `is:dart3-incompatible` 的是 `lyrics`。→ **推測**:原始情報可能把兩套件混淆。 +- `lyric_xx` 與 `my_lyric` 為同一作者、描述相同的兩個 repo,**是否同一程式碼庫:查不到**(未逐行比對)。 + +--- + +# §3 桌面歌詞的穿透與鎖定 + +> `window_manager` 各平台能力表與 GTK4 遷移、GNOME Discourse 的 Wayland 說明已見 `packages-and-platform.md` §A3;本節只補**原始碼層**事實與新查到的官方逐字。 + +## 3.1 `window_manager` 的 `setIgnoreMouseEvents(ignore, forward)` + +`window_manager` pub.dev 最新版 `0.5.2`(2026-07-04)。讀取 SHA `4080b59c…`。 + +Dart 端簽名與 doc(逐字): +```dart +/// Makes the window ignore all mouse events. +/// +/// All mouse events happened in this window will be passed to the window below this window, but if this window has focus, it will still receive keyboard events. +Future setIgnoreMouseEvents(bool ignore, {bool forward = false}) async { … } +``` +→ [window_manager `lib/src/window_manager.dart#L701-L709`](https://github.com/leanflutter/window_manager/blob/4080b59c0b1084c6085f1613c660382cd164ad76/packages/window_manager/lib/src/window_manager.dart#L701-L709) + +**Windows:`forward` 完全沒有被讀取。** `SetIgnoreMouseEvents` 只讀 `ignore`,以 `WS_EX_TRANSPARENT | WS_EX_LAYERED` 同設/同清;無 `SetLayeredWindowAttributes`。 +→ [window_manager `windows/window_manager.cpp#L1058`](https://github.com/leanflutter/window_manager/blob/4080b59c0b1084c6085f1613c660382cd164ad76/packages/window_manager/windows/window_manager.cpp#L1058) + +**macOS:`forward` 有被實作**,對應 `NSWindow.acceptsMouseMovedEvents`(語意是「仍收到 mouse-moved 事件」,**不是**把點擊轉送給下層視窗): +```swift +mainWindow.ignoresMouseEvents = ignore +if (!ignore) { mainWindow.acceptsMouseMovedEvents = false } +else { mainWindow.acceptsMouseMovedEvents = forward } +``` +→ [window_manager `macos/…/WindowManager.swift#L501-L510`](https://github.com/leanflutter/window_manager/blob/4080b59c0b1084c6085f1613c660382cd164ad76/packages/window_manager/macos/window_manager/Sources/window_manager/WindowManager.swift#L501-L510) + +**Linux:未實作**(`linux/window_manager_plugin.cc` 搜 `setIgnoreMouseEvents` **零命中**)。 +→ [window_manager `linux/window_manager_plugin.cc`](https://github.com/leanflutter/window_manager/blob/4080b59c0b1084c6085f1613c660382cd164ad76/packages/window_manager/linux/window_manager_plugin.cc) + +**CHANGELOG 與 issue**:0.2.0 逐字「[macos & windows] Implement setIgnoreMouseEvents metnod #89」(原文拼字錯誤);#94 `[linux] Implement setIgnoreMouseEvents method` **內文空白、從未實作**;#96 原作者 `lijy91` 2022-03-19 逐字「The forward parameter is already supported on the macos platform… But I haven't found out how to implement it on windows platform」。`lijy91` **2026-09-21** 留言逐字:「window_manager 0.5.x is no longer maintained: from 0.6.0 window_manager is rebuilt on [nativeapi] … nativeapi doesn't handle this yet either, so it's now tracked in libnativeapi/nativeapi#67.」 +→ [#89](https://github.com/leanflutter/window_manager/issues/89)、[#94](https://github.com/leanflutter/window_manager/issues/94)、[#96](https://github.com/leanflutter/window_manager/issues/96) +- **查不到**:`libnativeapi/nativeapi` issue `#67` 的內容(`gh api` 回 **404**;org 與 repo 皆存在、最後 push 為 2026-09-27)。 + +`flutter_acrylic`(1.1.4,2024-06-11)與 `bitsdojo_window`(0.1.6,2023-12-23):**查不到**任何 Linux 點擊穿透實作或說明。 + +**小結(此層級)**:`forward` 在 **Windows 完全無效**、在 **macOS 只是 `acceptsMouseMovedEvents`**、在 **Linux 未實作**。Linux 若要有穿透,必須走 GTK 的 input shape。 + +## 3.2 Linux:GTK3 / GTK4 / Wayland 的 input region + +**GTK3 官方文件(逐字)**: +- `gtk_widget_input_shape_combine_region`(自 3.0):「Sets an input shape for this widget's GDK window. This allows for windows which react to mouse click in a nonrectangular region…」。`region` 參數「Shape to be added, or `NULL` to remove an existing shape.」。**`GtkWindow` 上沒有同名方法**(該 URL 回 404),此函式只在 `GtkWidget` 上。 +- `gdk_window_input_shape_combine_region`(自 2.10)逐字:「…Mouse events which happen while the pointer position corresponds to an unset bit in the mask will be **passed on the window below** `window`. … On the X11 platform, this requires version 1.1 of the shape extension. **On the Win32 platform, this functionality is not present and the function does nothing.**」 +- `gdk_window_set_pass_through`(**自 3.18**)逐字:「Sets whether input to the window is passed through to the window below. … If `pass_through` is `TRUE` then such pointer events happen as if the window wasn't there at all…」 +→ `https://docs.gtk.org/gtk3/method.Widget.input_shape_combine_region.html`、`https://docs.gtk.org/gdk3/method.Window.input_shape_combine_region.html`、`https://docs.gtk.org/gdk3/method.Window.set_pass_through.html` + +> **空 region 的語意**:mask 中未設位元的位置,事件往下方視窗傳遞 → **空 region ⇒ 整個視窗不接收輸入**。 +> **`set_pass_through` 的關鍵限制(社群澄清,非官方文件)**:**只在同一 process 的 window hierarchy 內生效**,無法穿透到**其他 process** 的視窗。GNOME Discourse 回答者逐字:「I believe it's only for a window hierarchy... Windows of other processes do not count. For that you need `gdk_window_input_shape_combine_region`」。同串提問者逐字:「…it does work for X backend desktop environment, but it has no effect on xWayland…」。 +> → **此點應標為「社群來源、非官方保證」**。`GtkOverlay` 的 `"pass-through"` 子屬性(自 3.18)逐字亦註明「implemented by calling `gdk_window_set_pass_through()`」→ 仍是同一 process 內。 +→ `https://discourse.gnome.org/t/gtk3-set-pass-through-seems-not-work/20170` + +**GTK4**:遷移指南逐字「`gdk_surface_input_shape_combine_region()` has been renamed to `gdk_surface_set_input_region()`」。替代 API `gdk_surface_set_input_region(surface, region)` 逐字「Apply the region to the surface for the purpose of event handling. Mouse events … will be passed on the surface below `surface`. … Use `gdk_display_supports_input_shapes()` to find out if a particular backend supports input regions.」;`region` 參數「…or `NULL` to make the entire surface reactive.」。`gdk_display_supports_input_shapes` 逐字:「…On modern displays, this value is always `TRUE`.」 +→ `https://docs.gtk.org/gtk4/migrating-3to4.html`、`https://docs.gtk.org/gdk4/method.Surface.set_input_region.html` +- **查不到**:`gtk_widget_set_can_target` 是否被官方定位為 input shape 的替代。 + +**GTK3 的 Wayland backend 其實有實作 input shape**(`GNOME/gtk` 分支 `backport-5702-3-24`,`gdk/wayland/gdkwindow-wayland.c`):`gdk_wayland_window_sync_input_region()` → `wl_surface_set_input_region(...)`;`gdk_wayland_set_input_region_if_empty()` 對**空 region** 特判 `wl_surface_set_input_region(wl_surface, empty)`;`impl_class->input_shape_combine_region` **已註冊**。 +→ [GNOME/gtk `gdk/wayland/gdkwindow-wayland.c`](https://github.com/GNOME/gtk/blob/backport-5702-3-24/gdk/wayland/gdkwindow-wayland.c) +→ 因此 `desktop_lyrics` README 的「Wayland 不支援穿透」**不能單純歸因於「GTK3 Wayland backend 沒有此 API」**;實際失效原因**查不到**直接出處(**推測**與 XWayland、compositor 對 input region 的處理、或該 overlay 其他 X11-only 行為如 `gtk_window_move` 有關)。 + +**Wayland 官方 protocol `wl_surface.set_input_region`(逐字)**:「This request sets the region of the surface that can receive pointer and touch events. Input events happening outside of this region will try **the next surface in the server surface stack**. … The initial value for an input region is infinite. … A NULL wl_region causes the input region to be set to infinite.」 +- 協定本身**沒有**提供「把事件轉送給其他 process 的特定視窗」的機制;穿透效果來自「區域外的部分對該 surface 而言不存在,compositor 改測堆疊中的下一個 surface」。 +- **空 region ⇒ 該 surface 永不接收 pointer/touch**:協定未明文定義「空 region」,此為**推測**(GTK 的 `gdk_wayland_set_input_region_if_empty` 實作佐證)。 +→ `https://wayland.freedesktop.org/docs/html/apa.html`、`https://wayland.app/protocols/wayland#wl_surface:request:set_input_region` +- 全域定位/置頂在 xdg-shell 不提供(見 `packages-and-platform.md` §A3);**本輪未取得 xdg-shell 官方 protocol 的逐字引文**。 +- 以 `gh search code` 搜 `set_input_region` / `gdk_window_input_shape_combine_region`,命中者為 GTK 本體、鏡像 repo、protocol headers,**未找到任何 Flutter 專案**以此實作穿透 → **Flutter 生態內無先例**。 + +## 3.3 `desktop_lyrics` 的 Linux 實作(穿透怎麼做的) + +`linux/desktop_lyrics_overlay_render.cc` 的 `ApplyWindowBehavior()` 逐字: +```cpp +gtk_widget_set_opacity(window_, 1.0); +gtk_window_set_keep_above(GTK_WINDOW(window_), TRUE); +gtk_window_set_accept_focus(GTK_WINDOW(window_), FALSE); +GdkWindow* gdk_window = gtk_widget_get_window(window_); +if (gdk_window != nullptr) { gdk_window_set_pass_through(gdk_window, click_through_); } +if (click_through_) { + cairo_region_t* empty_region = cairo_region_create(); + gtk_widget_input_shape_combine_region(window_, empty_region); + if (drawing_area_ != nullptr) { gtk_widget_input_shape_combine_region(drawing_area_, empty_region); } + cairo_region_destroy(empty_region); +} else { + gtk_widget_input_shape_combine_region(window_, nullptr); + if (drawing_area_ != nullptr) { gtk_widget_input_shape_combine_region(drawing_area_, nullptr); } +} +``` +→ [desktop_lyrics `linux/desktop_lyrics_overlay_render.cc`](https://github.com/587626/desktop_lyrics/blob/e92aa0e2c0831285570974883f1dd99b36354958/linux/desktop_lyrics_overlay_render.cc) + +- 用 **`gdk_window_set_pass_through`**(GTK3 3.18+)+**空的 `cairo_region`** 丟給 **`gtk_widget_input_shape_combine_region`**,同時對 `window_` 與 `drawing_area_` 兩個 widget 設;關閉穿透時傳 `nullptr` 還原。 +- 定位用 **`gtk_window_move(...)`** —— 該 API **只在 X11/XWayland 有效**。 +- `OnButtonPress`:`if (self->click_through_) return FALSE;`;`OnMotion`:`if (!self->dragging_ || self->click_through_) return FALSE;`;雙鍵按下降回預設位置,單鍵按下 `gtk_window_begin_move_drag`。同檔註解逐字:「Some Wayland compositors can transiently report a very small allocation for undecorated windows…」 +- `README.md` 逐字:「Linux: supported / - Wayland: click-through is currently not supported due to technical limitations.」;`README_zh.md` 逐字「Linux:已支持 / - Wayland:由于技术原因,暂不支持点击穿透。」;另有「overlay size/position does not automatically follow system scaling or resolution changes(X11 與 Wayland 皆然)」。 +→ [desktop_lyrics `README.md`](https://github.com/587626/desktop_lyrics/blob/e92aa0e2c0831285570974883f1dd99b36354958/README.md) + +## 3.4 成熟產品的「鎖定 / 解鎖」定義與入口 + +| 產品 | 平台 | 「鎖定」=不能拖? | 「鎖定」=點擊穿透? | 解鎖入口 | 來源性質 | +|---|---|---|---|---|---| +| **LX Music Desktop** | Win/macOS/Linux(Electron) | 是(收不到滑鼠) | 是(`isLock` ⇒ `setIgnoreMouseEvents(true)`) | 全域快捷鍵 `desktop_lyric.toggle_lock`;托盤選單「解鎖歌詞視窗」 | 官方原始碼 | +| **LX Music Mobile** | Android | 是(`FLAG_NOT_TOUCHABLE`) | 是(同 flag;另 alpha 0.8、去背) | 設定頁 checkbox;**長按桌面歌詞按鈕** | 官方原始碼 | +| **BetterLyrics** | Windows(WinUI3) | 是 | 是(`WS_EX_LAYERED\|WS_EX_TRANSPARENT`) | 鎖定時顯示的 `LockToggleButtonContainer`;hover 浮現的 `UnlockButton`(可用 `IsAlwaysHideUnlockButton` 整個藏掉) | 官方原始碼 | +| **Lyricify 4 / Fusion** | Windows | **查不到**(原始碼未開源、文件站無鎖定頁) | **查不到** | **查不到** | — | +| **網易雲音樂 PC** | Windows | **查不到官方** | **查不到官方** | **查不到官方** | 僅第三方 | +| **QQ 音樂 PC** | Windows | 第三方稱「不可移動」 | **查不到** | 熱鍵 `Ctrl+Alt+E`;歌詞工具列「鎖定」;下拉「點擊解鎖桌面歌詞」(**第三方**) | 僅第三方 | + +**LX Desktop 的細節**([`winLyric/config.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winLyric/config.ts)): +- `isLock = true` ⇒ 立即 `setIgnoreMouseEvents(true)`。Linux 一律 `forward: false`(`!isLinux` 短路)——因為 Electron/Linux 沒有 `forward`。 +- `mouseCheckTools`(500 ms 輪詢游標)在 `isLinux || !isLock || !isHoverHide || !isMouseInWindow` 時直接 return;**Windows 的 `forward` 無效,故用輪詢補足 hover 判斷**。 +- 歌詞視窗自己的鎖定按鈕**只能鎖不能解**(`handleLock = () => updateSetting({ 'desktopLyric.isLock': true })`)。 +- 預設值:`desktopLyric.enable: false`、`isLock: false`、`isHoverHide: false`、`isLockScreen: isWin`。 +- 相關 issue:#725(已 closed,作者稱「v2.0.0中已移除窗口穿透的管理」);#743(**仍 open**)作者 2022-04-11 逐字「…桌面歌词无法使用拖动来移动位置,并且置顶无效,**锁定歌词后无法鼠标穿透**」→ **Wayland 下失效的第一手陳述**。 + +**LX Mobile 的細節**:`LyricView.getLayoutParamsFlags()` 在 `isLock` 時加 `FLAG_NOT_TOUCHABLE`;`lockView()`/`unlockView()` 另在 `SDK_INT > R` 時設 `alpha = 0.8f / 1.0f`(原始碼註解逐字:`// 修复 Android 12 的穿透点击问题`)。 + +**BetterLyrics 的細節**:`OverlayInputHelper` 為 `DispatcherTimer`,間隔 **50 ms**,每次 tick 用 `User32.GetCursorPos` 比對已 `Register` 的 `FrameworkElement` 的螢幕座標矩形;命中 ⇒ `SetIsClickThrough(false)`,離開 ⇒ `SetIsClickThrough(true)`。檔頭註解逐字:「用于管理覆盖层窗口的鼠标交互区域检测」。→ 手法與 LX 的 `mouseCheckTools` 同型:**輪詢游標決定此刻要不要關掉穿透**,因為 Windows 的 `WS_EX_TRANSPARENT` 是全域開關。 +→ [BetterLyrics `Helpers/OverlayInputHelper.cs`](https://github.com/jayfunc/BetterLyrics/blob/97629ddf085877cdc90de8cb56006a023320fe00/src/BetterLyrics.DotNet/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helpers/OverlayInputHelper.cs) + +**Lyricify**([`WXRIW/Lyricify-App` README](https://github.com/WXRIW/Lyricify-App)):Lyricify 4 `4.3.52-release`(Windows);Fusion `1.2.5-release`(Windows);Mobile `1.5.1-release`(iOS/iPadOS/macOS/Android/Windows,官網另列 visionOS);3 已 EOL。**App 原始碼未開源**(僅 `Lyricify-Lyrics-Helper`(Apache-2.0)與 `Lyricify-Backgrounds` 開源)→ 無法讀其穿透/鎖定實作。「靈動詞島」首創 2022-09-30(Lyricify 3.8.1 公開)、「妙控條」首創 2022-10-09(Lyricify 4.0.0 公開)。 +- **妙控條不是 macOS 選單列歌詞**:它是 **Lyricify 4(Windows)** 的側邊長條快捷控件。**macOS 選單列歌詞:查不到** Lyricify 或其他產品有明示此功能。 +- `docs.lyricify.app` 全站 sitemap **查不到**任何「桌面歌詞鎖定/解鎖」官方頁。 + +## 3.5 本節查不到 + +1. `libnativeapi/nativeapi` issue **#67** 內容(`gh api` 404)。 +2. X11 SHAPE extension **官方規範**中 input shape / bounding shape 的逐字定義。 +3. xdg-shell 官方 protocol 中「不提供全域定位/置頂」的**逐字**引文。 +4. `flutter_acrylic` / `bitsdojo_window` 任何 Linux 點擊穿透實作。 +5. Lyricify 任何「桌面歌詞鎖定/解鎖」官方說明。 +6. 網易雲音樂 PC 桌面歌詞鎖定的官方說明與解鎖入口(僅第三方)。 +7. QQ 音樂 PC 桌面歌詞鎖定的官方說明(僅第三方)。 +8. `desktop_lyrics` README「Wayland 不支援穿透」的技術根因。 +9. Flutter 生態內以 GTK/Wayland input region 實作穿透的先例。 + +--- + +# §4 Android 懸浮歌詞視窗 + +## 4.1 `flutter_overlay_window` + +| 項目 | 值 | +|---|---| +| 最新版 | `0.5.0`,發佈 `2025-04-20`;`isDiscontinued` 無值 | +| Likes / 分數 | Likes 528;`grantedPoints 160/160` | +| 授權 / 平台 | MIT;`platform:android`、`is:plugin`、`is:built-in-kotlin` | +| 釘選 commit | `111b21041ac3250a965a8ce1705e210c414a7a62` | + +→ `https://pub.dev/api/packages/flutter_overlay_window`、`https://github.com/X-SLAYER/flutter_overlay_window` + +**是否獨立 FlutterEngine:是。** `OverlayService.onCreate()` 逐字: +```java +FlutterEngine flutterEngine = FlutterEngineCache.getInstance().get(OverlayConstants.CACHED_TAG); +if (flutterEngine == null) { + FlutterEngineGroup engineGroup = new FlutterEngineGroup(this); + DartExecutor.DartEntrypoint entryPoint = new DartExecutor.DartEntrypoint( + FlutterInjector.instance().flutterLoader().findAppBundlePath(), "overlayMain"); // custom entry point + flutterEngine = engineGroup.createAndRunEngine(this, entryPoint); + FlutterEngineCache.getInstance().put(OverlayConstants.CACHED_TAG, flutterEngine); +} +``` +常數:`CACHED_TAG = "myCachedEngine"`、`CHANNEL_TAG = "x-slayer/overlay_channel"`、`OVERLAY_TAG = "x-slayer/overlay"`、`MESSENGER_TAG = "x-slayer/overlay_messenger"`、`NOTIFICATION_ID = 4579`。 + +> **關鍵事實:overlay engine 上沒有跑 `GeneratedPluginRegistrant`。** 對 `OverlayService.java` 全文 grep `Registrant` 為 **0 筆**;該 engine 只被建立兩個 channel。→ **其他任何 Flutter 外掛(含 `audio_service`)都不會註冊在 overlay engine 上。** + +**三條通道**:① `MethodChannel("x-slayer/overlay_channel")` 主 isolate → 原生(`checkPermission`/`requestPermission`/`showOverlay`/`isOverlayActive`/`moveOverlay`/`getOverlayPosition`/`closeOverlay`);② `MethodChannel("x-slayer/overlay")` 原生 → overlay engine(`updateFlag`/`updateOverlayPosition`/`resizeOverlay`);③ `BasicMessageChannel("x-slayer/overlay_messenger", JSONMessageCodec())` **雙向,是主 isolate 與 overlay isolate 唯一的資料通道**。Dart 端 `FlutterOverlayWindow.shareData(x)` → 原生 `onMessage` 轉發到主引擎 → 主 isolate 的 `overlayListener` 收到。 + +**內建點擊穿透:有**,即 `clickThrough` / `flagNotTouchable`(= `FLAG_NOT_TOUCHABLE`,另加 `FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_NO_LIMITS | FLAG_LAYOUT_IN_SCREEN`)。**內建「鎖定/解鎖」切換:查不到**——`updateFlag` 只是重跑 `WindowSetup.setFlag(flag)` 並 `updateViewLayout`,**沒有鎖定狀態機**。Android 12 的 0.8 alpha 上限**有被硬編碼**:`MAXIMUM_OPACITY_ALLOWED_FOR_S_AND_HIGHER = 0.8f`,條件為 `SDK_INT >= S && WindowSetup.flag == clickableFlag`。 +→ [flutter_overlay_window `WindowSetup.java`、`OverlayService.java`](https://github.com/X-SLAYER/flutter_overlay_window/tree/111b21041ac3250a965a8ce1705e210c414a7a62/android/src/main/java/flutter/overlay/window/flutter_overlay_window) + +**Manifest 必要條目**(README 逐字):權限 `SYSTEM_ALERT_WINDOW`、`FOREGROUND_SERVICE`、`FOREGROUND_SERVICE_SPECIAL_USE`;``(內附 ``);overlay 入口點 `@pragma("vm:entry-point") void overlayMain()`。 + +## 4.2 與 `audio_service` 背景 isolate 的關係 + +`audio_service` `0.18.19`(2026-06-29);釘選 SHA `da405ddd…`。 + +> **前提修正**:`audio_service` 的「另一個 isolate」是 **Dart 層 `Isolate`**,不是第二個 engine。Activity 與 foreground Service **共用同一個 cached `FlutterEngine`**(`AudioServicePlugin.getFlutterEngine`)。 +> `IsolatedAudioHandler` 用 `IsolateNameServer.registerPortWithName(_receivePort.sendPort, portName)` 與 `lookupPortByName`,**走 `SendPort`/`ReceivePort`,不走 MethodChannel,也不開新 engine**。 +→ [audio_service `lib/audio_service.dart`、`AudioServicePlugin.java`](https://github.com/ryanheise/audio_service/blob/da405ddd07840d5861a09ab252cce6f40cc95a0b/audio_service/lib/audio_service.dart) + +**互通結論**: +- **官方支援的互通路徑:查不到。** 兩套件互不引用;overlay engine 沒有 `GeneratedPluginRegistrant`,`audio_service` 也沒有 API 指向 overlay channel。 +- **overlay isolate 直接 `IsolatedAudioHandler.lookup(...)` 是否可行:查不到**(未在查到的 Flutter 官方頁面明言 `IsolateNameServer` 跨 engine/isolate group 的可見性)。**推測**:因 `flutter_overlay_window` 用 `FlutterEngineGroup.createAndRunEngine` 產生**另一個 engine**,若兩 engine 不共享同一 isolate group,lookup 會失敗。**需實測**。 +- **唯一可用的通道(事實陳述)**:`flutter_overlay_window` 自帶的 `BasicMessageChannel("x-slayer/overlay_messenger")` 是它唯一對外資料通道。 + +**兄弟/替代套件**:`flutter_overlay_window_plus` 1.0.1(2025-07-15,`{"fork":false}`,非 fork);`easy_overlay` 1.0.1(2024-08-10,**GPL-3.0**);`floating` 6.0.0(2025-02-14)——**`floating` 是 PiP(子母畫面),不是系統 overlay**(pub.dev 描述逐字「Picture in Picture management for Flutter. Android only」,公開 API `PiPSwitcher`、`Floating()`,需 `android:supportsPictureInPicture="true"`),列為系統級懸浮窗替代品會誤導。`desktop_lyrics` **沒有 Android**。 + +## 4.3 原生 Kotlin/Java View 路線 + +**共同點**:都用 `TYPE_APPLICATION_OVERLAY`(API ≥ 26)/ `TYPE_SYSTEM_ALERT`(API < 26)、`FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_NO_LIMITS`、`PixelFormat.TRANSPARENT`、`windowManager.updateViewLayout` 更新。 + +- **LX Music Mobile**([`LyricView.java`](https://github.com/lyswhut/lx-music-mobile/blob/fb8480728d875fa5e0da25eebd3a26bb71723aae/android/app/src/main/java/cn/toside/music/mobile/lyric/LyricView.java)):`if (isLock) flag |= FLAG_NOT_TOUCHABLE;`;`lockView()`/`unlockView()` 切換該 flag,並在 `SDK_INT > R` 時設 `alpha = 0.8f / 1.0f`。**「鎖定」=不能拖+點擊穿透+視覺淡化(0.8、去圓角背景)**。解鎖入口:設定頁 checkbox、**長按桌面歌詞按鈕**(`DesktopLyricBtn.tsx` 的 `onLongPress={updateLock}`)。預設 `desktopLyric.enable: false`、`isLock: false`。`LyricTextView.java` 的註解指出其來源是 `Block-Network/StatusBarLyric` 的 `LyricTextView.kt`;常數 `SPEED_LIMIT = 0.135F`、`startScrollDelay = 1500`、`invalidateDelay = 10`。 +- **MusicFree**([`LyricView.kt`](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/android/app/src/main/java/fun/upup/musicfree/lyricUtil/LyricView.kt)):`onTouch` 直接 `return false`,flags **恆含 `FLAG_NOT_TOUCHABLE`** → **無觸控能力**(與 LX 的可鎖可拖不同)。`gravity = Gravity.TOP or Gravity.START`;選項 `topPercent`/`leftPercent`/`align`/`color`/`backgroundColor`/`widthPercent`/`fontSize`。 + +## 4.4 Android 12 不受信任觸碰(官方逐字) + +> **來源更正(重要)**:`https://developer.android.com/about/versions/12/behavior-changes-12` **不含此內容**(2026-09-28 對下載頁全文計數:`untrusted` 0 次、`obscur` 0 次)。**正確頁面是** `https://developer.android.com/about/versions/12/behavior-changes-all#untrusted-touch`。 + +逐字(節錄): +> **Untrusted touch events are blocked** — To preserve system security and a good user experience, Android 12 prevents apps from consuming touch events where an overlay obscures the app in an unsafe way. … +> **Affected apps** — This change affects apps that choose to let touches pass through their windows, for example by using the `FLAG_NOT_TOUCHABLE` flag. … Overlays that require the `SYSTEM_ALERT_WINDOW` permission, such as windows that use `TYPE_APPLICATION_OVERLAY`, and use the `FLAG_NOT_TOUCHABLE` flag. +> **Exceptions** — … Trusted windows (Accessibility / IME / Assistant windows) — **Note:** Windows of type `TYPE_APPLICATION_OVERLAY` aren't trusted. … Invisible windows … Completely transparent windows (`alpha` 0.0) … **Sufficiently translucent system alert windows.** … **In Android 12, this maximum opacity is 0.8 by default.** +> **Detect when an untrusted touch is blocked** — Logcat: `Untrusted touch due to occlusion by PACKAGE_NAME` +> **Test the change** — `adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.app` + +**`WindowManager.LayoutParams` flag 逐字**(`https://developer.android.com/reference/android/view/WindowManager.LayoutParams`): +> `FLAG_NOT_TOUCHABLE` — Window flag: this window can never receive touch events. +> `FLAG_NOT_FOCUSABLE` — Window flag: this window won't ever get key input focus…(並**隱含** `FLAG_NOT_TOUCH_MODAL`) + +## 4.5 權限流程與廠商 ROM + +- `Settings.canDrawOverlays(context)` 逐字「Returns true if the app can draw overlays on top of other apps.」;`Settings.ACTION_MANAGE_OVERLAY_PERMISSION` 逐字「Show screen for controlling which apps can draw on top of other apps. **In some cases, a matching Activity may not exist, so ensure you safeguard against this.** … Constant Value: `"android.settings.action.MANAGE_OVERLAY_PERMISSION"`」。 + → `https://developer.android.com/reference/android/provider/Settings#canDrawOverlays(android.content.Context)` +- **官方是否對「使用者拒絕後如何處理」給出建議:查不到**(該頁僅有上列 safeguard 提醒與 Android 11 起「一律路由到頂層設定頁」敘述)。 +- `flutter_overlay_window` 的實作:`checkOverlayPermission()` → `Settings.canDrawOverlays(context)`;`requestPermission` → `Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)` + `intent.setData(Uri.parse("package:" + mActivity.getPackageName()))` + `startActivityForResult(...)`;`onActivityResult` 回報 `checkOverlayPermission()`。 +- SAW 權限與 API 版本限制(manifest 宣告不足、API 23 起須 `ACTION_MANAGE_OVERLAY_PERMISSION`、API 26 起須 `TYPE_APPLICATION_OVERLAY`、Android 10 Go 無法取得、Android 11 一律頂層、Android 15 FGS 豁免收緊)**見 `packages-and-platform.md` §B1**,本檔不重複。 + +**廠商 ROM 額外權限**: +- **MIUI / HyperOS「後台彈出介面」:存在。** 官方頁 `https://dev.mi.com/console/doc/detail?pId=1735` 為 JS 渲染,`tavily-extract` 正文為空;新網域 `https://dev.mi.com/xiaomihyperos/documentation/detail?pId=1735` 顯示「暂无数据」。**逐字正文取不到**;可取得的政策文字(搜尋索引摘要 + 第三方轉引,**二手**):「该权限默认为拒绝的…针对特殊应用会提供白名单,例如音乐(歌词显示)、运动、VOIP(来电)等」。第三方(**二手**)稱其實作位於 `AppOpsManager` 擴充 op,`opCode = 10021`(小米機型)。**本次未找到小米官方對「如何以程式判斷此權限」的 API**;二手來源一致指出沒有公開 API,只能以「啟動是否成功」反推。 +- **MIUI / HyperOS「顯示在其他應用上層」:存在**,即 AOSP `SYSTEM_ALERT_WINDOW` 在 MIUI 設定中的名稱(**二手**:騰訊雲開發者社群問答)。小米官方對該權限的逐字說明**查不到**。 +- **ColorOS「懸浮窗」:存在**(設定項名稱即「懸浮窗」)。**OPPO/ColorOS 官方文件逐字說明:查不到**。`https://www.coloros.com/instruction?id=850` 是「自由浮窗」(應用內多工),**與跨應用 SAW 不同**。可取得的路徑描述(**二手**):「ColorOS 13及以上:设置> 应用> 特殊应用权限> 悬浮窗…」。未授予時懸浮窗不顯示且系統不報錯(**二手**)。 +- **共同事實**:本次查證到的四項廠商 ROM 額外權限(MIUI 後台彈出介面、MIUI 顯示在其他應用上層、ColorOS 懸浮窗、HyperOS 焦點通知權限)**都沒有可用於程式化判斷的公開 API**。 + +## 4.6 本節查不到 + +1. `flutter_overlay_window` 的 overlay isolate 能否直接使用 `IsolatedAudioHandler.lookup`(**查不到**,**推測**會因跨 engine 失敗,**未實測**)。 +2. MIUI 後台彈出介面官方頁面的**逐字正文**(JS 渲染,新舊網域皆空)。 +3. ColorOS 懸浮窗的**官方說明**(路徑描述全為二手)。 + +--- + +# §5 Android 狀態列歌詞 + +## 5.1 魅族 Flyme ticker(一手) + +官方頁:`https://open.flyme.cn/docs?id=239`(標題「【系统媒体控件 & 状态栏歌词】适配说明」;Nuxt SPA,`WebFetch` 只回導覽,正文經官方 JSON API `https://apiopen.flyme.cn/api/web/v1/doc-wiki/detail?id=239` 取得)。 + +逐字: +> (1)Flyme 状态栏歌词显示功能,是在 android 通知框架的基础上,**利用 Notification 的 tickerText 显示功能**,做的一个定制功能。 +> 如果不存在如下两个 flag 则该机型不支持此功能。 +> `mNotification.flags |= Notification.FLAG_NO_CLEAR;` // Notice. 必须添加,使该条通知常驻 +> `mNotification.extras.putBoolean("ticker_icon_switch", false);` / `mNotification.extras.putInt("ticker_icon", R.drawable.notification_icon);` +> `mNotification.flags |= mflag_show_ticker;` / `mNotification.flags |= mflag_update_ticker;` + +- 兩個 flag 以反射 `Class.forName("android.app.Notification")` 取得:`FLAG_ALWAYS_SHOW_TICKER` / `FLAG_ONLY_UPDATE_TICKER`。**沒有獨立 SDK**——「公開 API」=官方文件化的**反射 flag 名稱**,不是 `Notification.Builder` 的公開參數。 +- 其他官方要求:smallIcon 60×60(xxhdpi);RemoteView 同一條通知只設一次;取消時 `builder.setTicker(null)` 並清除兩個 flag。 +- **數值由兩個獨立開源實作相互印證**(官方頁只寫 flag 名稱):`xiaowine/Lyric-Getter` 的 `MeiZuNotification` 與 `Moriafly/HiMoriafly` 的文件皆為 `0x01000000` / `0x02000000` → **三方一致**。 +→ [Lyric-Getter `MeiZuNotification.kt`](https://github.com/xiaowine/Lyric-Getter/blob/9e6d3f72694b08f56dce0b1a4524e18dc56f5c09/app/src/main/kotlin/cn/lyric/getter/tool/MeiZuNotification.kt)、[HiMoriafly `flyme-lyrics-noti.md`](https://github.com/Moriafly/HiMoriafly/blob/98e04b2cf53aa65fa998a424cf328330fe345044/docs/android-dev/flyme-lyrics-noti.md) + +## 5.2 HyperOS / 澎湃 OS 焦點通知 / 超級島 + +官方文件:`https://dev.mi.com/xiaomihyperos/documentation/detail?pId=2146`(Q&A,標示更新於 2025-10-23)、`?pId=2131`(開發指南)。 + +- **App 可以主動提供歌詞,但需先取得權限**:焦點通知 access 需**向 `mipush-permission@xiaomi.com` 發郵件申請**(非 SDK 自助開通)。 +- 權限探測:`ContentResolver.call(Uri.parse("content://miui.statusbar.notification.public"), "canShowFocus", null, extras)` → `bundle.getBoolean("canShowFocus")`。 +- OS 版本探測:`Settings.System.getInt(cr, "notification_focus_protocol", 0)`(`1`=OS1、`2`=OS2、`3`=OS3)。 +- extra 載荷:`miui.focus.param` / `miui.focus.param_v2`,內含 `ticker`(文件稱「OS2 焦点通知状态栏显示文案」)、`tickerPic`、`aodTitle`、`islandProperty`、`islandTimeout`、`bigIslandArea`、`smallIslandArea`、`shareData`。`miui.focus.param` 大小上限 **≤ 3072 bytes**。 +- media 通知會自動上島,但文件指向另一份《Xiaomi HyperOS 媒体通知适配说明》。 +- **沒有可從 pub.dev / Maven 直接依賴的公開 SDK**;「公開」的部分是郵件申請後的協定文件 + 既有的 `content://` Provider。`islandProperty` 的具體 schema、`ticker` 的官方逐字定義**本次未逐欄取得**(頁面為 JS 渲染)。 + +## 5.3 LSPosed 模組(需 root) + +- **`StatusBarLyric`**(`bd2ec998…`,GPL-3.0):README 逐字「这是一个Xposed模块,**仅支持LSPosed框架** / 用于在状态栏显示歌词 / 理论支持 __所有__ 官方以及部分修改系统」。**需要 root/LSPosed:是。** 掛鉤作用域(`arrays.xml` 逐字)**只有 `com.android.systemui`**。**歌詞不是直接讀 `MediaSession`,而是走 `SuperLyric` 的 Binder 協定**:`SystemUILyric.kt` 從 `com.hchen.superlyricapi` 匯入 `ISuperLyric`/`SuperLyricData`,以 `registerSuperLyric(context)` 註冊 `ISuperLyric.Stub`(`onStop`/`onSuperLyric` 回呼)。另有小米焦點通知掛鉤 `xiaomi/FocusNotifyController.kt`(掛 `FocusedNotifPromptController`)。**支援應用清單:README 未列。** + → [StatusBarLyric `SystemUILyric.kt`](https://github.com/Block-Network/StatusBarLyric/blob/bd2ec998c4a4d667d5e0602923bdd9cfec330a54/app/src/main/kotlin/statusbar/lyric/hook/module/SystemUILyric.kt) +- **`Lyricon`**(正確 repo 是 `tomakino/lyricon`(`c93da0ee…`);簡報若寫 `lz233/Lyricon` 該 repo 回 **404**):Xposed 模組,需 **Root + LSPosed**、Android 9.0(API 28)+、必須以 **System UI 作用域**運行。**歌詞來自外掛(LyricProvider),不是來自 `MediaSession`**:Provider 應用在 `` 宣告 ``(另有 `lyricon_module_author`、`lyricon_module_description`、可選 `lyricon_module_tags` 值 `$syllable`/`$translation`)。主要掛鉤 `SystemUIHooker.kt` 呼叫 `subscriber.subscribeActivePlayer(LyricDataHub)`。**支援面由外掛生態決定,README 無逐應用清單。** + → [lyricon `SystemUIHooker.kt`](https://github.com/tomakino/lyricon/blob/c93da0eef8b7aee015d2670b48e9e262fcf72cd1/xposed/src/main/kotlin/cn/tomakino/lyricon/xposed/systemui/SystemUIHooker.kt) +- **相關:`SuperLyric` / `SuperLyricApi`**(`HChenX/SuperLyric` `bfca7093…`、`HChenX/SuperLyricApi` `b7ad6e48…`):**基於 Binder 的歌詞取得器/發布器**,有 Hook / 網路雙路徑,**按應用分發輸出目標**(魅族狀態欄歌詞 / 狀態欄歌詞 / 藍牙歌詞 / 桌面歌詞)。README 列出 LX Music 與 MusicFree → 桌面歌詞,Flamingo/光錐音樂 → API 原生支援,**YouTube Music 不受支援**。JitPack 依賴 `com.github.HChenX:SuperLyricApi:3.5`。 + +## 5.4 無 root 的通用方法(官方逐字) + +- **`Notification.tickerText`**(`https://developer.android.com/reference/android/app/Notification#tickerText`)逐字:「Text that summarizes this notification for accessibility services. **As of the L release, this text is no longer shown on screen**, but it is still useful to accessibility services…」;`tickerView` 逐字「Formerly, a view showing the `tickerText`. **No longer displayed in the status bar as of API 21.**」 + → **`tickerText` 未被標 deprecated,但自 Android L(API 21)起系統不再在螢幕上顯示。** 這與魅族不衝突:魅族是「利用 `tickerText` 顯示功能做的一個定製功能」,屬 ROM 端復活該行為。 +- **`MediaMetadata`**(`https://developer.android.com/reference/android/media/MediaMetadata`):有 `METADATA_KEY_TITLE` / `ARTIST` / `ALBUM` / `DISPLAY_TITLE` 等,**`METADATA_KEY_LYRICS` 在該頁出現 0 次** → **官方 `MediaMetadata` 沒有歌詞欄位**。「把當前行塞進 `METADATA_KEY_TITLE`」屬**挪用**,不是官方設計用途。 +- **哪些 ROM 會讀這些欄位顯示在狀態列**:魅族 Flyme 是(見 5.1);小米 HyperOS 是但走焦點通知(見 5.2);**其他 ROM:查不到**。**AOSP 原生不顯示**(see 上方 tickerText/tickerView 逐字)。 + +## 5.5 本節查不到 + +1. 第三方應用在**未 root** 情況下,被 AOSP 或任一廠商官方文件明示「讀取 `MediaMetadata` 特定欄位並顯示在狀態列」的做法(魅族與小米以外)。 +2. `islandProperty` 的官方 schema、`ticker` 欄位的官方逐字定義。 +3. `StatusBarLyric` / `Lyricon` 的逐應用支援清單。 + +--- + +# §6 iOS + +## 6.1 系統級懸浮歌詞:不可能(交叉引用) + +App 無法在其他 App 之上繪製系統級懸浮視窗;唯一的系統浮動窗是 Picture in Picture,且 `AVPictureInPictureController.ContentSource` 只接受影片來源(誤用會被 App Review 以 "Misusing PiP" 拒絕);`MPNowPlayingInfoCenter.nowPlayingInfo` 接受的欄位子集**不含歌詞**,且 Apple 文件逐字「You don't have direct control over what information the system displays, or its formatting.」 +→ **完整逐字與出處見 `packages-and-platform.md` §B2**,本檔不重複。 + +## 6.2 Live Activity:本地更新 vs 推播預算 + +Apple 文件為 JS 渲染,`WebFetch`/`tavily-extract` 只回導覽;**可行替代**是文件 JSON 端點 `https://developer.apple.com/tutorials/data/documentation/.json`。以下皆為該 JSON 逐字。 + +**生命週期與大小限制**(`displaying-live-data-with-live-activities`): +> 「A Live Activity can be active for up to **eight hours** unless its app or a person ends it… After the eight-hour limit, the system automatically ends the Live Activity… a Live Activity remains on the Lock Screen for a maximum of **12 hours**.」 +> 「Each Live Activity runs in its own sandbox, and — unlike a widget — **it can't access the network** or receive location updates.」 +> 「Static and dynamic data … including data for ActivityKit updates and ActivityKit push notifications, **can't exceed a combined size of 4 KB**.」 +> 「the Music app displays an extended presentation in the Dynamic Island when a person starts playing audio in the app」 + +**推播更新的預算**(`starting-and-updating-live-activities-with-activitykit-push-notifications`,章節「Determine the update frequency」): +> 「The system allows for a certain **budget of ActivityKit push notifications per hour**. As with other push notifications you send with APNs, you can set the HTTP header field `apns-priority`… If you don't specify the `apns-priority` value, APNs delivers the ActivityKit push notification immediately with the **default priority of `10`** and **counts it toward the notification budget** that the system imposes. If you exceed the budget, the system may **throttle** your ActivityKit push notifications.」 +(另提及 `NSSupportsLiveActivitiesFrequentUpdates` Info.plist 開關。) + +**本地 `Activity.update(_:)`** 逐字: +> 「Updates the dynamic content of the Live Activity. ## Discussion: Use this function to update the Live Activity while your app is in the foreground or while it's in the background… The system ignores attempts to update a Live Activity that ended.」 + +> **關鍵否定發現**:對抓下來的 Apple 文件 JSON grep `budget` / `throttl`,**只命中推播那篇**(`apple_push.json`),**未命中** `displaying-live-data…`、`Activity` class、`Activity.update(_:)`、ActivityKit 索引。 +> → **Apple 官方只對「ActivityKit *push* notifications」記載「每小時預算/可能被 throttle」;對本地 `Activity.update(_:)` 並未記載任何預算或節流。** 「本地更新不受推播預算限制」是**由官方文件的有無推得**,Apple **未明文**寫出 → **推測**(**需實測**)。 + +## 6.3 成熟 iOS 音樂 App 的做法 + +- **Apple Music**(官方,Apple Newsroom 2025-06-09):iOS 26 新增 `Lyrics Translation`(歌詞翻譯)與 `Lyrics Pronunciation`(歌詞發音),逐字「In Apple Music, Lyrics Translation helps users understand the words to their favorite songs, while Lyrics Pronunciation allows everyone to sing along, regardless of language.」。 +- **Apple Music Live Activity 的動態歌詞**:MacStories 對 iOS 26 的敘述含「That's followed by a single line for lyrics that update live in time with the music, including when your iPhone is in Always-On mode.」→ **媒體,非官方**。**Apple 官方文件明示此事的敘述:查不到。** +- **Lyricify Mobile 1.5.1** 支援 iOS/iPadOS/macOS/Android/Windows(官網另列 visionOS);iOS 版未上 App Store,需自簽 `.ipa`。 +- **第三方歌詞 App**(**非**網易雲/QQ 音樂本體):`Dynamic Lyrics` 商店敘述逐字「Dynamic Lyrics is an app that displays real-time lyrics and translations on your **lock screen, Dynamic Island, widgets, floating windows**, and more. It supports Apple Music and Spotify.」→ **App Store 商店頁,非官方技術文件**。 +- **網易雲音樂 iOS / QQ 音樂 iOS 是否用 Live Activity / Dynamic Island / 鎖屏歌詞**:**查不到**官方或可靠來源。 + +## 6.4 CarPlay 與 macOS 選單列 + +**CarPlay**: +- `CPNowPlayingTemplate` 逐字:「A shared system template that displays Now Playing information… The Now Playing template displays information from `MPNowPlayingInfoCenter` and `MPRemoteCommandCenter`. … The template displays a series of playback control buttons, as well as information about the current album and artist… `CPNowPlayingTemplate` is only available in apps with the audio entitlement.」→ **不放歌詞**。 +- `MPNowPlayingInfoCenter` 逐字:「The system displays Now Playing information on the device's Lock Screen and in the media controls in Control Center. …」→ **只涵蓋正在播放的中繼資料,沒有歌詞欄位**。 +- **iOS 26 CarPlay 支援 widgets 與 Live Activities**(Apple Newsroom 逐字):「…with **widgets and Live Activities**, users can stay in the loop without losing focus on the road. These updates also come to CarPlay Ultra…」;圖說逐字「Widgets are shown in CarPlay. / Live Activities are shown in CarPlay.」→ 官方確認這**兩個表面**存在;官方**未**說 Apple Music 在 CarPlay 上顯示逐行動態歌詞。 +- **第三方(非官方)**:CarPlay 的 widget 需在 iPhone `設定 → 一般 → CarPlay → <車> → 小工具` 手動加入堆疊;第三方歌詞 widget(如 `Dynamic Lyrics`)可把當前歌詞行放進 CarPlay widget,每秒更新。 +→ `https://developer.apple.com/documentation/carplay/cpnowplayingtemplate`、`https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter`、`https://www.apple.com/newsroom/2025/06/apple-elevates-the-iphone-experience-with-ios-26` + +**macOS 選單列歌詞**:**查不到** Lyricify 或其他產品有明示此功能(Lyricify Mobile 支援 macOS,但其文件未提選單列歌詞;「妙控條」經查是 Lyricify 4 Windows 功能,見 §3.4)。 + +## 6.5 LX 是否有 iOS 版 + +**沒有。** LX Music Mobile README 逐字:「已支持的平台:- Android 5 及以上 / ***注:目前没有计划支持 iOS 和 HarmonyOS NEXT**。」 +→ [lx-music-mobile `README.md`](https://github.com/lyswhut/lx-music-mobile/blob/fb8480728d875fa5e0da25eebd3a26bb71723aae/README.md) + +## 6.6 本節查不到 + +1. Apple 官方文件明示 Apple Music 把歌詞放進 Live Activity / Dynamic Island / 鎖定畫面。 +2. 網易雲音樂 iOS / QQ 音樂 iOS 是否使用 Live Activity / Dynamic Island / 鎖屏歌詞。 +3. Lyricify 或其他產品做 macOS 選單列歌詞的明示證據。 + +--- + +# 附錄 A:本檔全部「推測」彙總 + +- 網易雲各旗標字母(`l/t/r/y/k`)的語意對應。 +- `lxlrc` 不含行結束時間、行尾由最後一個詞推得。 +- LX 把 YRC 的 `ytlrc` 丟進 `fixTimeTag` 時因正則不接受 `[start,dur]` 標籤而**可能整行被丟棄**(未實測)。 +- `lyrics_parser` 與 Dart 3 不相容的說法可能與 `lyrics` 套件混淆。 +- Wayland 協定層「空 region ⇒ 該 surface 不接收輸入」(協定未明文;GTK 實作佐證)。 +- `desktop_lyrics` 的 Wayland 失效與 XWayland 路徑有關。 +- 本地 `Activity.update(_:)` 不受推播預算限制(Apple 只對 push 記載預算)。 +- `flutter_overlay_window` 的 overlay isolate 直接 `IsolatedAudioHandler.lookup` 會因跨 engine 失敗(**未實測**)。 + +# 附錄 B:本檔全部「查不到」彙總 + +見各節末尾的「本節查不到」小節(§1.10、§2.3/§2.4、§3.5、§4.6、§5.5、§6.6)。跨節重複出現者不再重列。 From 2a8240042971e6dd575f7b82718d3f2300233760 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 16:16:37 +0800 Subject: [PATCH 071/133] chore(task): record ai-as-plugin decision for lyrics --- .trellis/tasks/09-28-design-lyrics/prd.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index 3e5c14fa9..d14ae7e7e 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -68,10 +68,15 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 沒有跨廠商標準,這個形狀就是事實標準。各實作的 confidence 定義不同(Laya 文件明說不能沿用 Jev 的門檻)。另有多個 9 月才出現的開源復刻,都未經驗證。 OpenAI 相容端點可用 `logprobs` 取選項機率,但 `top_logprobs` 最多 5。音樂或歌詞領域沒有產品級先例。 +3. **AI 服務做成插件(2026-09-28)**:新增插件能力(標題解析、候選挑選),OpenAI 相容與 System One(`/v1/systemone`:TypeSafe、OpenRouter、Laya)各為一個官方插件; + 廠商格式、prompt、確定度門檻的解讀都在插件內,改了只更新插件。擁有者指出「插件只要更新插件就行」,推翻了「App 內建兩個客戶端」的建議—— + 介面描述的是 FMP 的需求(給標題與上傳者回曲名歌手;給候選回選擇與確定度),不是廠商格式,所以穩定。 + 宿主仍負責:送出欄位的白名單並在設定頁列出、https 檢查、key 存插件憑證區且不進 log 與備份、使用者自填的端點網域在設定頁顯示後才加入該插件的允許網域。 + ## 待決定 -1. AI 候選挑選要不要也支援 `/v1/systemone`(Jev 類)端點,以什麼形式接入。 -2. 各新功能的平台範圍與降級方式。 +1. 行動裝置系統級歌詞的範圍:Android 懸浮、Android 狀態列、iOS 鎖屏/動態島。 +2. 桌面穿透與鎖定在各平台的範圍與降級方式。 ### Jev 已核對的事實(2026-09-28,docs.typesafe.ai 與 NanoJev README) From ae3354c9e1ffee06d6618c58818a620cfb605cc8 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:06:16 +0800 Subject: [PATCH 072/133] chore(task): record mobile lyrics scope --- .trellis/tasks/09-28-design-lyrics/prd.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index d14ae7e7e..9f5c9346e 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -73,10 +73,14 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 介面描述的是 FMP 的需求(給標題與上傳者回曲名歌手;給候選回選擇與確定度),不是廠商格式,所以穩定。 宿主仍負責:送出欄位的白名單並在設定頁列出、https 檢查、key 存插件憑證區且不進 log 與備份、使用者自填的端點網域在設定頁顯示後才加入該插件的允許網域。 +4. **行動裝置系統級歌詞(2026-09-28,按建議)**: + - Android 懸浮歌詞做:可拖動,鎖定=點擊穿透+不透明度 ≤ 0.8,解鎖在播放通知按鈕與 App 內開關;需使用者授予「顯示在其他應用上層」,廠商額外權限只能在說明中提示。 + - iOS 鎖屏/動態島一行歌詞(Live Activity)列入設計,iOS 平台任務實測本機逐行更新可行才開放。 + - Android 狀態列歌詞列入待辦(AOSP 不支援;無 root 只有魅族與需申請的小米 HyperOS)。 + ## 待決定 -1. 行動裝置系統級歌詞的範圍:Android 懸浮、Android 狀態列、iOS 鎖屏/動態島。 -2. 桌面穿透與鎖定在各平台的範圍與降級方式。 +1. 桌面歌詞的鎖定定義、解鎖入口與各平台降級方式。 ### Jev 已核對的事實(2026-09-28,docs.typesafe.ai 與 NanoJev README) From 5bba97e76424c1fd0c48a943cb53b23e04cde838 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:10:02 +0800 Subject: [PATCH 073/133] chore(task): add design and plan for lyrics --- .trellis/tasks/09-28-design-lyrics/design.md | 166 ++++++++++++++++++ .../tasks/09-28-design-lyrics/implement.md | 17 ++ .trellis/tasks/09-28-design-lyrics/prd.md | 60 ++++--- 3 files changed, 214 insertions(+), 29 deletions(-) create mode 100644 .trellis/tasks/09-28-design-lyrics/design.md create mode 100644 .trellis/tasks/09-28-design-lyrics/implement.md diff --git a/.trellis/tasks/09-28-design-lyrics/design.md b/.trellis/tasks/09-28-design-lyrics/design.md new file mode 100644 index 000000000..8e82e544a --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/design.md @@ -0,0 +1,166 @@ +# 設計:歌詞 + +## 1. 全貌 + +```mermaid +flowchart LR + subgraph Plugins["插件(ADR 0014)"] + LP["歌詞插件
    lyrics 能力"] + AP["AI 插件
    aiAssist 能力"] + end + subgraph Host["宿主"] + M["LyricsMatcher
    直取 → 標題解析 → 搜尋 → 評分 → AI 挑選"] + DB[("lyrics_matches
    主資料庫")] + C[("歌詞內容
    cache.db")] + S["LyricsSession
    目前曲目的歌詞、偏移、播放狀態"] + end + subgraph Surfaces["顯示端"] + P["播放頁/側欄"] + W["桌面歌詞視窗
    子 engine"] + O["Android 懸浮
    子 engine"] + L["iOS Live Activity"] + end + LP --> M + AP --> M + M --> DB + M --> C + DB --> S + C --> S + S --> P + S -- "型別化訊息" --> W + S -- "型別化訊息" --> O + S -- "原生橋接" --> L +``` + +## 2. 插件能力 + +### 2.1 `lyrics`(歌詞源) + +- `searchLyrics({title, artist, album?, durationMs})` → 候選清單:`id`、標題、歌手陣列、專輯、時長、`hasSynced`、`hasWordSync`、`hasTranslation`、`hasRomaji`。 +- `getLyrics({id})` → 歌詞文件(§3)。 +- `lyricsForOrigin({platform, platformId})`:插件宣告自己認得的原始平台(例如網易插件認 `netease`)。曲目本身來自該平台,或 `track_origins` 有該平台 id 時,直接取、跳過搜尋。 +- 搜尋與取用分開,才能做候選清單(MusicFree、Lyricify 的慣例)。同一插件可同時是音源與歌詞源(網易)。 +- 第三方歌詞源不帶登入(ADR 0012 的 `never`)。 + +### 2.2 `aiAssist`(AI 服務,新增能力) + +- `parseTitle({title, uploader})` → `{title, artist, artistConfidence}`。 +- `pickCandidate({query, candidates})` → `{decision: chosen | noneMatch | unsure, candidateId?, confidence?}`。 + - `chosen`:採用;`noneMatch`:這次不自動匹配(等同舊版 AI 回 null);`unsure`:退回評分核心的結果。 + - 確定度門檻的解讀在插件內(各家 confidence 定義不同,Laya 文件明說不能沿用 Jev 的門檻),插件自己的設定可調門檻。 +- 一個插件可只實作其中一個。官方兩個: + - `openai-compatible`:兩者都做(chat completions、要求 JSON)。 + - `system-one`:`/v1/systemone` 的 Choice 題做候選挑選;標題解析改為「宿主正則列出的幾種拆法」當選項(官方 cookbook 的 pre-parsed value extraction 模式)。可接 TypeSafe、OpenRouter、自架 Laya。 +- **manifest `userEndpoint`**:端點由使用者填。宿主檢查 https,把該網域顯示在設定頁、使用者確認後才加入這個插件的允許網域。 +- key 存插件憑證區(ADR 0014 `credentials`,secure storage),不進 log、不進備份。 + +## 3. 歌詞文件(DTO,隨 `apiVersion` 版本化) + +```text +LyricsDocument + kind: synced | plain | instrumental + lines: [ { startMs, endMs?, text, words?: [ { startMs, endMs, text } ] } ] # 字時間一律絕對毫秒 + translation?: [ { startMs, text } ] # 行級 + romanization?: [ { startMs, text } ] # 行級 + lrc?: string # 只有 LRC 時可直接回原文,由宿主解析 + sourceUrl?, attribution? +``` + +- **各家格式由插件轉換**:YRC、QRC(非標準 DES)、KRC(XOR+zlib,插件可內附純 JS 的 inflate)在插件裡解成 `lines`,宿主不寫 QRC/KRC 解析器。KRC 的字時間相對行首,插件要換成絕對時間。 +- **宿主只有一個 LRC 解析器**(搬舊 `lrc_parser.dart` 的邏輯與測試,加上 enhanced LRC 的 `` 字時間),給 `lrc` 欄位用。 +- **合併**:翻譯與羅馬音以行開始時間對齊,容差 100ms(LX 的做法),對不上的行丟棄。 +- **降級**:沒有 `words` 或使用者關掉逐字時逐行顯示;逐字→逐行為行起=首字起、行訖=末字訖。不做逐行→逐字。 +- 純音樂判定由插件回 `instrumental`(舊版網易「纯音乐,请欣赏」的判斷搬進網易插件)。 + +## 4. 匹配(E9、E10) + +觸發:開播時在背景跑(設定「自動匹配歌詞」沿用,預設關);手動搜尋隨時可用。同一曲目以曲目鍵防併發;播放路徑不等它。 + +1. 已有匹配 → 直接用。 +2. 直取:§2.1 的 `lyricsForOrigin`,依使用者排序的歌詞插件逐一試。 +3. 標題解析:宿主正則(搬舊 `title_parser.dart`,3 種模式);AI 模式開啟時改用 `aiAssist.parseTitle`,失敗退回正則。 +4. 搜尋:以解析結果並行問所有啟用的歌詞插件。 +5. 評分:ADR 0019 的共用評分核心,歌詞另加同步歌詞加分(ADR 0014 決定 9);「允許自動匹配純文字歌詞」沿用,預設關。 +6. AI 挑選(模式為「標題解析+候選挑選」時):送評分前 8 名給 `aiAssist.pickCandidate`,依 §2.2 的三種決定處理。 +7. 寫入 `lyrics_matches`;內容進快取。 + +- **AI 模式**:關(預設)/標題解析/標題解析+候選挑選。AI 解析結果快取在 `cache.db`(可丟,丟了只是多花一次 AI 呼叫)。 +- **送出欄位(B5,設定頁逐項列出)**: + - 標題解析:影片標題、上傳者。 + - 候選挑選:影片標題、上傳者、時長、解析出的曲名與歌手;每個候選的曲名、歌手、專輯、時長、有無同步、前 8 行(至多 500 字)歌詞預覽。 + - 影片描述不送(舊版欄位存在但從未填值)。 +- **手動改選**:搜尋面板依插件分頁或「全部」,列出評分;改選後寫入並標 `manual`,自動流程永不覆寫。 +- **插件被移除**:匹配紀錄保留、標「歌詞源未安裝」,不自動重配;重新安裝即恢復。 + +## 5. 資料 + +- `lyrics_matches`(主資料庫):曲目鍵 FK(連帶刪除)、插件 id、歌詞 id、`offsetMs`、`origin`(`direct`/`scorer`/`ai`/`manual`)、分數、AI 確定度、時間。 + 與 ADR 0019 的 `match_results` 分開:那是「元資料曲目 → 可播放曲目」,這是「曲目 → 歌詞」。 +- 歌詞內容:`cache.db`,鍵為插件 id+歌詞 id,只靠 LRU(ADR 0016);淘汰後以存下的 id 重抓、不重配。 +- 偏移:`adjusted = position + offsetMs`,正值=歌詞提前;播放頁 ±100/500/1000ms 與重設;點行跳到該行;桌面視窗右鍵某行校正。 + +## 6. 同步與顯示 + +- **`LyricsSession`**(歌詞模組的 service,provider 注入)是唯一來源:持有目前曲目的歌詞文件、偏移、顯示模式、播放狀態。 + 舊版把同步掛在 `TrackDetailPanel` 的 `ref.listen`,版面切換就可能停;新版與 UI 生命週期無關。 +- **位置同步不逐 tick 推送**:播放狀態、位置、速度、時間戳只在播放、暫停、seek、換歌、換速時推送一次,各顯示端自己外推, + 以 frame callback(`Ticker`)驅動動畫與逐字漸變,不開 `Timer.periodic`。 +- **子 engine 通訊**:一個 Dart 檔定義所有型別化訊息(主→子:歌詞文件、播放狀態、主題與字串、樣式;子→主:seek、偏移、播放控制、樣式變更、鎖定), + 兩邊共用並以 JSON 序列化。舊 `lyrics_window_strings` static-rule 刪除:少推一個字串變成編譯錯誤。 +- **渲染**:播放頁、桌面視窗、Android 懸浮共用一套歌詞 widget;逐字漸變用 `CustomPainter`+分段 shader+`saveLayer(dstIn)` 遮罩(`flutter_lyric` 3.0.8 的技術)。 + `flutter_lyric` 是渲染候選,第一個加入逐字的里程碑決定直接用或自寫(避開已撤回的 3.0.5)。 +- 顯示模式沿用原文/優先翻譯/優先羅馬音,另加「逐字高亮」開關(預設開,來源沒有逐字時自動逐行)。 + +## 7. 桌面歌詞視窗(E11) + +- 平台能力 `desktopLyrics`(ADR 0009),細分 `clickThrough`、`alwaysOnTop`;按鈕只在能力宣告時出現(舊版無平台守衛)。 +- 技術:`desktop_multi_window` 0.3.1(每視窗一個 engine、三平台)。Flutter 官方多視窗 API 仍在 `main` channel、實驗性,進 stable 後再評估。 +- 功能沿用:透明、置頂、單行/整頁、11 項樣式、hover 顯示工具列、點行跳轉、右鍵校正偏移;關閉是隱藏不銷毀。 +- **鎖定**:不能拖動+點擊穿透。解鎖入口: + 1. 托盤選單; + 2. 全域快捷鍵; + 3. 主視窗播放列的歌詞按鈕; + 4. hover 浮出的解鎖鈕(設定可關)。 +- 平台實作(都在平台層): + - Windows:`window_manager.setIgnoreMouseEvents`(`WS_EX_TRANSPARENT`);它不支援 `forward`,hover 解鎖鈕靠鎖定期間每 100ms 查游標。 + - macOS:`window_manager`(`ignoresMouseEvents`,`forward` 可收到滑鼠移動事件)。 + - Linux X11:自寫 GTK 原生碼,空 input region+`gdk_window_set_pass_through`(`desktop_lyrics` 的做法);hover 同 Windows 查游標。 + - Linux Wayland:實機驗證穿透、置頂、定位;不支援的能力不宣告,鎖定只剩不能拖動,設定頁註明。 +- 查游標的計時器是平台層桌面歌詞模組的一個 `Timer.periodic`,只在「鎖定+視窗可見+hover 解鎖鈕開啟」時存在;登記為 `fmp_periodic_timer_owner`(ADR 0017)允許的擁有者。 +- `window_manager` 0.5.x 已停止維護(0.6.0 改建在 `nativeapi`),它只在平台層實作檔 import(ADR 0009),換套件不影響其他模組。 + +## 8. Android 懸浮歌詞 + +- 平台能力 `overlayLyrics`。實作候選 `flutter_overlay_window` 0.5.0:第二個 engine、共用 §6 的歌詞 widget,以它的 `BasicMessageChannel` 傳 §6 的型別化訊息; + 它不在 overlay engine 註冊其他插件,所以懸浮窗只顯示、不直接呼叫播放,控制經訊息回主 engine 的 `PlaybackController`。 + 第一個加入懸浮歌詞的里程碑實測記憶體與 Android 15 前景服務限制;不行就改原生 View(LX Mobile、MusicFree 的做法),訊息不變。 +- 可拖動;鎖定=`FLAG_NOT_TOUCHABLE`+不透明度 0.8(Android 12 規定);解鎖在播放通知的自訂按鈕與 App 內開關。 +- 權限:`PermissionGateway`(ADR 0020)新增「顯示在其他應用上層」(`Settings.canDrawOverlays`、`ACTION_MANAGE_OVERLAY_PERMISSION`,找不到設定頁時提示手動); + 說明文字提示小米「後台彈出介面」、ColorOS「懸浮窗」等廠商權限(App 偵測不到)。 + +## 9. iOS 鎖屏/動態島 + +- 平台能力 `liveActivityLyrics`:Widget Extension 以 ActivityKit 顯示目前一行(+翻譯),資料 ≤ 4KB;換行時本機 `Activity.update`,不用推播。 +- iOS 平台任務實測逐行更新(前景與背景、是否被節流、8 小時上限)後才宣告能力。 + +## 10. 設定(ADR 0011 的「歌詞」組) + +- 歌詞插件的啟用與順序(插件頁排序);自動匹配(預設關);允許純文字自動匹配(預設關);顯示模式;逐字高亮(預設開)。 +- AI:模式(預設關)、使用哪個 AI 插件、送出欄位清單(唯讀說明);端點、模型、門檻、key 在該插件的設定頁。 +- 桌面歌詞:樣式 11 項、置頂、單行、鎖定、hover 解鎖鈕(預設開)、快捷鍵。Android 懸浮:開關、位置、字級、顏色、不透明度。 + +## 11. 舊資料匯入(ADR 0010) + +- `LyricsMatch` → `lyrics_matches`:`lyricsSource`(`netease`/`qqmusic`/`lrclib`)對到官方插件 id,`externalId`、`offsetMs` 照搬,`origin` 記 `manual` + (舊版不分自動與手動,保守起見視為使用者認可,不被自動流程覆寫)。 +- 桌面歌詞樣式、顯示模式照搬。AI 端點、模型、逾時搬進 `openai-compatible` 插件設定;舊 key 在該插件安裝後搬進其憑證區,舊的 secure storage 項目刪除。 +- `LyricsTitleParseCache` 與舊歌詞檔案快取不搬(都是快取)。 + +## 12. 相關 ADR 的指向 + +- 0009:能力清單加 `clickThrough`、`overlayLyrics`、`liveActivityLyrics` → 0021。 +- 0014:能力清單加 `aiAssist`;`lyrics` 能力的介面與歌詞文件 → 0021。 +- 0015/0017:`fmp_periodic_timer_owner` 的允許擁有者加桌面歌詞 hover 查游標 → 0021。 +- 0016:AI 標題解析快取在 `cache.db` → 0021。 +- 0020:`PermissionGateway` 加懸浮窗權限 → 0021。 +- `phase2-plan.md` 第 20 項待辦加:Android 狀態列歌詞、本機歌詞檔匯入。 diff --git a/.trellis/tasks/09-28-design-lyrics/implement.md b/.trellis/tasks/09-28-design-lyrics/implement.md new file mode 100644 index 000000000..a377d31eb --- /dev/null +++ b/.trellis/tasks/09-28-design-lyrics/implement.md @@ -0,0 +1,17 @@ +# 執行計畫:第 15 項(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0021-lyrics.md`(依 `docs/adr/template.md`),內容取自 `design.md` §2–§11;被否決的方案: + 三個歌詞源各自寫死在 Dart、宿主內建 QRC/KRC 解析器、AI 只留標題解析、App 內建 AI 客戶端(擁有者指出做成插件只需更新插件)、 + 只承諾 Windows 的桌面歌詞、只有 hover 工具列沒有鎖定、同步掛在 UI 元件上、以字串 map 推子視窗、逐 tick 推送位置、 + Flutter 官方多視窗 API(仍在 `main` channel)、Android 狀態列歌詞(列待辦)、iOS 系統級懸浮(平台不允許)。 +2. [ ] 其他 ADR 各加一句指向 ADR 0021:0009(`desktopLyrics` 細分 `clickThrough`/`alwaysOnTop`、`overlayLyrics`、`liveActivityLyrics`)、 + 0014(能力加 `aiAssist`;`lyrics` 介面與歌詞文件)、0015(後續 ADR 新增的規則:`fmp_periodic_timer_owner` 允許桌面歌詞查游標)、 + 0016(AI 標題解析快取在 `cache.db`)、0017(同上的計時器擁有者)、0020(`PermissionGateway` 加懸浮窗權限)。 +3. [ ] `phase2-plan.md`:§3 第 15 項標 ✅(ADR 0021);第 20 項待辦加 Android 狀態列歌詞、本機歌詞檔匯入; + §8 延後實測加入:桌面歌詞在 macOS/Linux X11/Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在子視窗; + `flutter_overlay_window` 的記憶體與 Android 15 前景服務限制;iOS Live Activity 本機逐行更新;`flutter_lyric` 直接用或自寫; + §10 交接段更新,下一項 19 發版與更新,下一份 ADR 0022。 +4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [ ] `task.py finish`、`task.py archive design-lyrics --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/09-28-design-lyrics/prd.md index 9f5c9346e..dedabf760 100644 --- a/.trellis/tasks/09-28-design-lyrics/prd.md +++ b/.trellis/tasks/09-28-design-lyrics/prd.md @@ -38,20 +38,7 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 研究更正:研究初稿說 B5 勾「修改」,實際 `questions.md:119` 勾的是「不確定」,已在 `current-state.md` 更正;方向以 `phase2-plan.md` §6 為準。 -## 已確定的方向 - -- E9–E11 保留;歌詞源全部是插件的 `lyrics` 能力(ADR 0014),匹配用共用評分核心、結果持久化、改選後不再重算(ADR 0014 決定 9、ADR 0019 決定 6)。 -- 歌詞內容在統一快取(鍵為歌詞插件+歌詞 id),匹配結果在主資料庫,淘汰後以存下的 id 重抓(ADR 0016)。 -- B5:AI 保留、預設關;強制 https;payload 不寫進 log;送出的欄位最小化並在設定頁列出(`phase2-plan.md` §6)。 -- 桌面歌詞視窗以平台能力宣告,目標是所有桌面平台一致(ADR 0009、`phase2-plan.md` §8)。 - -## 已決定 - -1. **AI 兩種模式都保留(2026-09-28)**:標題解析與候選挑選。 -2. **歌詞的新功能解除凍結(2026-09-28)**:擁有者把逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android/iOS 的懸浮歌詞納入本項, - 依成熟做法設計;各平台做不到的以能力宣告降級。可行性補查見 `research/extra-features.md`。 - -## 補查結論(`research/extra-features.md`、`research/ai-decision-models.md`,2026-09-28,關鍵項已抽查) +補查(`research/extra-features.md`、`research/ai-decision-models.md`,關鍵項已抽查): - **逐字格式**:YRC、QRC 的字時間是絕對時間,KRC 相對行首;QRC 需非標準 DES、KRC 是 XOR+zlib,各有多份公開實作互證。 成熟產品一律把各格式正規化成「行+字、整數毫秒」的內部結構;降級只有逐字→逐行(行起訖=首字起、末字訖),沒有逐行→逐字。 @@ -67,6 +54,26 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 - **決策模型**:`POST /v1/systemone` 已有三個實作者——TypeSafe(官方)、OpenRouter(改 base URL 即可,用 OpenRouter 的 key 計費)、開源 Laya(Apache-2.0,可自架,宣稱 100+ 語言); 沒有跨廠商標準,這個形狀就是事實標準。各實作的 confidence 定義不同(Laya 文件明說不能沿用 Jev 的門檻)。另有多個 9 月才出現的開源復刻,都未經驗證。 OpenAI 相容端點可用 `logprobs` 取選項機率,但 `top_logprobs` 最多 5。音樂或歌詞領域沒有產品級先例。 +- **Jev 本身**(docs.typesafe.ai、NanoJev README): + - TypeSafe 於 2026-09-15 公告,early access;`POST https://api.typesafe.ai/v1/systemone`,Bearer key。 + - 不生成文字:輸入 state 與具型別的問題(Choice 從最多 255 個選項挑一個、Score 依等級評分、Noul 是非題),回傳每個選項的機率與 confidence。 + - 價格 $0.042/百萬輸入 token、輸出免費;官方宣稱 70–500ms。 + - 已知弱點(官方 jaggedness 頁):英文最佳,CJK「可處理但不一樣好」;不擅長數字與日期比較(應在程式碼算);會照字面理解;可被內容中的誘導文字影響。 + - 企業才有零資料保留;Jev 不以客戶資料訓練。 + - NanoJev(MIT,2026-09-17 建立)是研究用復刻:Qwen3-0.6B 加決策頭,只訓練在 4 個遊戲任務,需 CUDA 伺服器,不是通用模型。 + +## 已確定的方向 + +- E9–E11 保留;歌詞源全部是插件的 `lyrics` 能力(ADR 0014),匹配用共用評分核心、結果持久化、改選後不再重算(ADR 0014 決定 9、ADR 0019 決定 6)。 +- 歌詞內容在統一快取(鍵為歌詞插件+歌詞 id),匹配結果在主資料庫,淘汰後以存下的 id 重抓(ADR 0016)。 +- B5:AI 保留、預設關;強制 https;payload 不寫進 log;送出的欄位最小化並在設定頁列出(`phase2-plan.md` §6)。 +- 桌面歌詞視窗以平台能力宣告,目標是所有桌面平台一致(ADR 0009、`phase2-plan.md` §8)。 + +## 已決定 + +1. **AI 兩種模式都保留(2026-09-28)**:標題解析與候選挑選。 +2. **歌詞的新功能解除凍結(2026-09-28)**:擁有者把逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android/iOS 的懸浮歌詞納入本項, + 依成熟做法設計;各平台做不到的以能力宣告降級。可行性補查見 `research/extra-features.md`。 3. **AI 服務做成插件(2026-09-28)**:新增插件能力(標題解析、候選挑選),OpenAI 相容與 System One(`/v1/systemone`:TypeSafe、OpenRouter、Laya)各為一個官方插件; 廠商格式、prompt、確定度門檻的解讀都在插件內,改了只更新插件。擁有者指出「插件只要更新插件就行」,推翻了「App 內建兩個客戶端」的建議—— @@ -78,26 +85,21 @@ ADR 0009(桌面歌詞視窗是平台能力)、0011(log 遮蔽、設定分 - iOS 鎖屏/動態島一行歌詞(Live Activity)列入設計,iOS 平台任務實測本機逐行更新可行才開放。 - Android 狀態列歌詞列入待辦(AOSP 不支援;無 root 只有魅族與需申請的小米 HyperOS)。 -## 待決定 - -1. 桌面歌詞的鎖定定義、解鎖入口與各平台降級方式。 - -### Jev 已核對的事實(2026-09-28,docs.typesafe.ai 與 NanoJev README) +5. **桌面歌詞鎖定(2026-09-28,按建議)**:鎖定=不能拖動+點擊穿透;解鎖入口為托盤選單、全域快捷鍵、主視窗播放列的歌詞按鈕、 + 滑鼠停在歌詞上浮出的解鎖鈕(可在設定關閉;Windows 與 Linux 在鎖定期間約每 0.1 秒查游標,解鎖或關閉歌詞即停)。 + Windows、macOS 完整;Linux X11 以自寫 GTK 原生碼穿透;Wayland 實機驗證,不支援時鎖定只剩不能拖動並在設定頁註明。 -- TypeSafe 於 2026-09-15 公告,early access;`POST https://api.typesafe.ai/v1/systemone`,Bearer key。 -- 不生成文字:輸入 state 與具型別的問題(Choice 從最多 255 個選項挑一個、Score 依等級評分、Noul 是非題),回傳每個選項的機率與 confidence。 -- 價格 $0.042/百萬輸入 token、輸出免費;官方宣稱 70–500ms。 -- 已知弱點(官方 jaggedness 頁):英文最佳,CJK「可處理但不一樣好」;不擅長數字與日期比較(應在程式碼算);會照字面理解;可被內容中的誘導文字影響。 -- 企業才有零資料保留;Jev 不以客戶資料訓練。 -- NanoJev(MIT,2026-09-17 建立)是研究用復刻:Qwen3-0.6B 加決策頭,只訓練在 4 個遊戲任務,需 CUDA 伺服器,不是通用模型。 +6. **技術選擇(`design.md`)**:插件新增 `aiAssist` 能力、`lyrics` 能力分搜尋/取用/依原始平台直取;歌詞文件以「行+字、絕對毫秒」正規化,各家逐字格式由插件轉換,宿主只有 LRC 解析器; + `lyrics_matches` 表(手動改選永不被覆寫);`LyricsSession` 為唯一同步來源、以型別化訊息推給子 engine、各顯示端自行外推位置; + 桌面視窗沿用 `desktop_multi_window`;Android 懸浮以 `flutter_overlay_window` 為候選、不行改原生 View;iOS 以 Live Activity 顯示一行。 ## 不在範圍 -- 本機歌詞檔匯入(舊專案沒有,擁有者未納入)。 +- Android 狀態列歌詞、本機歌詞檔匯入:列入第 20 項待辦。 - 歌詞頁與視窗的版面(第 5 項)。 ## 驗收條件 -- [ ] ADR 0021 記錄:歌詞插件介面、自動匹配與手動改選、偏移、格式與解析、顯示與同步來源、桌面歌詞視窗與平台差異、AI 功能與隱私、快取與持久化。 -- [ ] E9–E11、B5 各自對到決定。 -- [ ] `phase2-plan.md` §3 第 15 項標 ✅ 與 ADR 編號。 +- [ ] ADR 0021 記錄:歌詞與 AI 插件介面、歌詞文件格式、自動匹配與手動改選、偏移、同步與顯示、桌面歌詞視窗(鎖定與平台差異)、Android 懸浮、iOS Live Activity、AI 隱私、資料與快取、舊資料匯入。 +- [ ] E9(多源搜尋、自動匹配、手動選擇)、E10(AI 兩種模式)、E11(桌面歌詞視窗到全桌面平台)、B5(預設關、https、payload 不進 log、欄位清單)各自對到決定。 +- [ ] ADR 0009、0014、0015/0017、0016、0020 加上指向 ADR 0021 的一句話;`phase2-plan.md` §3 第 15 項標 ✅、第 20 項待辦補上,§7/§8 加入實測項目。 From 95deaf530faefd9448db46a7dd9eb248b5ff64dd Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:14:02 +0800 Subject: [PATCH 074/133] docs(adr): 0021 lyrics --- ...atform-layer-with-declared-capabilities.md | 2 +- docs/adr/0014-script-source-plugins.md | 2 +- .../0015-testing-gates-and-dev-environment.md | 2 +- docs/adr/0016-cache-and-offline.md | 2 +- docs/adr/0017-background-task-scheduler.md | 2 +- docs/adr/0020-downloads-and-permissions.md | 3 +- docs/adr/0021-lyrics.md | 165 ++++++++++++++++++ 7 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 docs/adr/0021-lyrics.md diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 7aa3c3740..03b904a17 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -42,7 +42,7 @@ Linux、macOS 加入時要回頭改介面。 `smtc_windows`…)只在實作檔 import。 2. **能力宣告**:每個平台一份不可變的 `PlatformCapabilities`。UI 依它決定是否顯示入口;service 只呼叫介面。 要在執行期才能判斷的(例如 Linux 在 Wayland 下沒有全域快捷鍵)由實作在啟動時寫進宣告。 - 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018;權限由平台層 `PermissionGateway` 統一請求,見 ADR 0020。 + 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018;權限由平台層 `PermissionGateway` 統一請求,見 ADR 0020;桌面歌詞的穿透與置頂、Android 懸浮歌詞、iOS Live Activity 歌詞的能力見 ADR 0021。 3. **平台層以外禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件的 import。 4. **不寫空實作**:未驗證的平台宣告全部能力為「沒有」、沒有實作檔;該平台的 child task 開始時才加入實作。 5. **原生呼叫**:新的 MethodChannel 一律用 Pigeon 產生型別安全介面。 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index f7a264363..b221a324e 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -37,7 +37,7 @@ manifest 與腳本承擔。 3. **manifest**:`id`(字串音源 id)、名稱、版本、作者、`apiVersion`、能力、允許的網域、登入方式、重試與限流策略、遮蔽名單追加、預設值、圖示。 4. **能力**:`search`、`resolveStream`、`trackDetail`、`multiPart`、`importPlaylist`、`libraryRead`、`libraryWrite`、`charts`、`live`、`mix`、`lyrics`、`login`。 可播放音源=有 `resolveStream`;僅元資料來源與歌詞源依能力區分,不另立型別。下載由宿主處理,不是插件能力。 - 同一能力有多個提供者時 UI 全部列出。 + 同一能力有多個提供者時 UI 全部列出。`lyrics` 的介面與歌詞文件格式、新增的 AI 能力 `aiAssist` 見 ADR 0021。 5. **宿主 API v1**(腳本能用的全部):`http.request`(經 ADR 0012/0013 網路層、只能連 manifest 網域)、`crypto`、每插件 `storage`、 只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`)。沒有檔案系統、任意 socket、其他插件的資料。 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 TypeScript 型別定義。`resolveStream` 回傳網址期限 `expiresAt`(插件從網址本身讀), diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index dc3c0fe14..fe10f2fe8 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -48,7 +48,7 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 | `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | | `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只在平台層 | - 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017)。 + 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)。 每條規則以官方 `analyzer_testing` 做雙向變異測試。`flutter analyze` 目前不顯示插件診斷並回報 No issues (flutter/flutter#193203),所以 CI 跑 `dart analyze --fatal-infos`,並以接線哨兵(暫放違規檔、斷言分析失敗且含規則名)證明規則接上了 `app/`。 diff --git a/docs/adr/0016-cache-and-offline.md b/docs/adr/0016-cache-and-offline.md index 6455637f1..54e0d79bc 100644 --- a/docs/adr/0016-cache-and-offline.md +++ b/docs/adr/0016-cache-and-offline.md @@ -38,7 +38,7 @@ - 圖片:鍵為實際請求的 URL,經 ADR 0012 媒體 client;插件的封面 DTO 為多尺寸清單 `artwork: [{url, width?}]`,宿主挑最接近且不小於顯示尺寸的一張,縮放在解碼時做。 以 `cached_network_image` 的自訂 cache manager 接到快取庫;接不起來就保留它自己的索引、由統一淘汰器依檔案大小一起淘汰。 記憶體 `ImageCache` 大小由平台層宣告,不開放設定。 - - 歌詞內容:鍵為歌詞插件+歌詞 id,只靠 LRU;匹配結果在主資料庫,淘汰後以存下的 id 重抓、不重新匹配。 + - 歌詞內容:鍵為歌詞插件+歌詞 id,只靠 LRU;匹配結果在主資料庫,淘汰後以存下的 id 重抓、不重新匹配;AI 標題解析結果也在 `cache.db`(ADR 0021)。 - 排行:鍵為插件+榜單 id;先顯示快取並標「更新於 …」再背景刷新;只抓已啟用插件且在首頁啟用的榜單(B12),停用就刪掉快取。 5. **串流網址**:`resolveStream` DTO 帶可空的 `expiresAt`,由插件從網址本身讀(D9)。宿主只在記憶體保存(B6),鍵為曲目鍵+分 P+音質偏好、上限 64 筆, 有效到 `expiresAt − 5 分鐘`;為空時 5 分鐘內有效。播放失敗作廢該筆;下載一律重新解析。預取與播放共用這一份。 diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md index 32b70e533..ce4b81eac 100644 --- a/docs/adr/0017-background-task-scheduler.md +++ b/docs/adr/0017-background-task-scheduler.md @@ -63,4 +63,4 @@ Riverpod 3 在 Notifier 內建立計時器並以 `ref.onDispose` 取消、由生 - 退避與 `retryAfter`; - 上次成功時間重啟後生效。 - lint `fmp_periodic_timer_owner`(加入 ADR 0015 的 `fmp_lints`):`Timer.periodic`、`Stream.periodic` 只准在排程器與播放核心模組, - 取代舊 `periodic_timer` static-rule 的登記表;依 ADR 0015 寫雙向變異測試。 + 取代舊 `periodic_timer` static-rule 的登記表;依 ADR 0015 寫雙向變異測試。平台層桌面歌詞模組的查游標計時器也允許,見 ADR 0021。 diff --git a/docs/adr/0020-downloads-and-permissions.md b/docs/adr/0020-downloads-and-permissions.md index 7fccc5cf2..2f008baa2 100644 --- a/docs/adr/0020-downloads-and-permissions.md +++ b/docs/adr/0020-downloads-and-permissions.md @@ -65,7 +65,8 @@ 9. **權限統一入口**:平台層 `PermissionGateway` 依能力宣告需要的權限: - 下載資料夾寫入(Android `MANAGE_EXTERNAL_STORAGE`); - 下載通知(Android 13+ `POST_NOTIFICATIONS`,第一次下載時請求); - - 安裝更新(`REQUEST_INSTALL_PACKAGES`)。 + - 安裝更新(`REQUEST_INSTALL_PACKAGES`); + - 顯示在其他應用上層(Android 懸浮歌詞,ADR 0021)。 流程固定為說明 → 請求 → 被拒時說明影響並提供「前往系統設定」→ 回到 App 時重新檢查,永久拒絕另外處理。 通知被拒照樣下載;儲存被拒不開始下載並引導設定。Android 用 `permission_handler`(見「如何確認」的 Windows 實測)。 diff --git a/docs/adr/0021-lyrics.md b/docs/adr/0021-lyrics.md new file mode 100644 index 000000000..0fe5f0fa7 --- /dev/null +++ b/docs/adr/0021-lyrics.md @@ -0,0 +1,165 @@ +# 0021 — 歌詞:插件提供歌詞與 AI、正規化的逐字歌詞文件、單一同步來源、可鎖定的桌面與行動歌詞 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:插件能力 `lyrics` 與新增的 `aiAssist`、歌詞文件 DTO、歌詞匹配流程、`lyrics_matches` 表、歌詞快取、歌詞顯示與同步、 + 桌面歌詞視窗、Android 懸浮歌詞、iOS Live Activity、平台能力宣告、`PermissionGateway`、歌詞與 AI 設定、舊資料匯入 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/current-state.md`、`docs/audit/features.md` §6,已以程式碼核對): + +- 三個歌詞源是三個獨立 Dart 類別、字串分派 5 處;各自的評分用 Levenshtein、±20 秒、門檻 0.6。 +- 只有 LRC 與純文字,沒有逐字。 +- AI 有兩種模式(標題解析、候選挑選),預設關;端點不驗 https,payload 與回應原文在 debug 級別寫進 log(B5)。 +- 桌面歌詞視窗只開在 Windows、按鈕沒有平台守衛;沒有點擊穿透與鎖定。 +- 同步掛在 `TrackDetailPanel` 的 `ref.listen` 上;字串以 map 推送,靠 `lyrics_window_strings` static-rule 守。 + +擁有者決定(2026-09-28): +- E9–E11 保留,AI 兩種模式都保留; +- 逐字歌詞、桌面歌詞的點擊穿透與鎖定、Android/iOS 的懸浮歌詞解除功能凍結、納入本項; +- AI 服務做成插件; +- Android 狀態列歌詞列入待辦。 + +## 考慮過的選項 + +- **歌詞源寫死在 Dart(舊版)**:否決,ADR 0014 已決定所有來源都是插件。 +- **宿主內建 QRC/KRC/YRC 解析器**:否決。解密與格式隨來源變動,放在插件裡改了只需更新插件;宿主只留 LRC 這個共同下限。 +- **只保留 AI 標題解析**:否決(擁有者選擇保留候選挑選)。 +- **App 內建 OpenAI 相容與 System One 兩個客戶端**:否決。擁有者指出做成插件只需更新插件;介面描述的是 FMP 的需求(給標題回曲名歌手、給候選回選擇與確定度),不是廠商格式,所以穩定。 +- **只承諾 Windows 的桌面歌詞**:否決,目標是所有桌面平台一致(ADR 0009)。 +- **沒有鎖定、只靠 hover 顯示工具列**(Namida、Spotube):否決,擁有者要求穿透與鎖定。 +- **同步掛在 UI 元件、以字串 map 推子視窗、逐 tick 推送位置**:否決。版面切換就可能停;漏推欄位只能靠 static-rule 擋;計時器與 IPC 過多。 +- **Flutter 官方多視窗 API**:暫不採用,仍只在 `main` channel、標示實驗性;進 stable 後再評估。 +- **Android 狀態列歌詞**:列入待辦。AOSP 自 API 21 不顯示 `tickerText`,不需 root 的只有魅族與需寄信申請的小米 HyperOS。 +- **iOS 系統級懸浮歌詞**:不可行,系統只開放影片的子母畫面,誤用會被審核拒絕。 + +## 決定 + +1. **`lyrics` 能力**(ADR 0014): + - `searchLyrics({title, artist, album?, durationMs})` 回候選(id、標題、歌手陣列、專輯、時長、有無同步/逐字/翻譯/羅馬音); + - `getLyrics({id})` 回歌詞文件; + - `lyricsForOrigin({platform, platformId})`:插件宣告認得的原始平台;曲目來自該平台,或 `track_origins`(ADR 0019)有該平台 id 時,直接取、不搜尋。 + + 第三方歌詞源不帶登入(ADR 0012)。 +2. **歌詞文件**(隨 `apiVersion` 版本化): + - `kind`(`synced`/`plain`/`instrumental`); + - `lines[{startMs, endMs?, text, words?[{startMs, endMs, text}]}]`,一律絕對毫秒; + - 行級的 `translation[]`、`romanization[]`; + - 可選的 `lrc` 原文。 + + YRC、QRC(非標準 DES)、KRC(XOR+zlib、字時間相對行首)由插件轉成 `lines`。宿主只有一個 LRC 解析器(含 enhanced LRC 字時間),沿用舊版邏輯與測試。 + 翻譯與羅馬音以行開始時間對齊、容差 100ms。沒有逐字時逐行顯示(行起=首字起、行訖=末字訖),不做逐行→逐字。 +3. **`aiAssist` 能力**(新增): + - `parseTitle({title, uploader})` → 曲名、歌手、歌手確定度。 + - `pickCandidate({query, candidates})` → `chosen`(採用)、`noneMatch`(這次不自動匹配)或 `unsure`(改用評分核心的結果),附確定度。 + + 確定度門檻由插件解讀並可在插件設定調整(各家定義不同)。官方兩個: + - `openai-compatible`:兩者都做; + - `system-one`:`/v1/systemone`,接 TypeSafe、OpenRouter、自架 Laya;標題解析以宿主正則列出的拆法當選項。 +4. **AI 隱私(B5)**: + - AI 預設關;模式為「關/標題解析/標題解析+候選挑選」。 + - 宿主決定送出欄位並在設定頁逐項列出: + - 標題解析:影片標題、上傳者; + - 候選挑選:影片標題、上傳者、時長、解析結果,以及每個候選的曲名、歌手、專輯、時長、有無同步、前 8 行(至多 500 字)預覽; + - 影片描述不送。 + - manifest `userEndpoint`:端點由使用者填,宿主檢查 https,顯示網域、使用者確認後才加入該插件的允許網域。 + - key 存插件憑證區,不進 log、不進備份。宿主不記錄 AI payload 與回應原文。 +5. **匹配**(E9、E10): + - 觸發:開播時在背景跑,「自動匹配歌詞」沿用、預設關;播放路徑不等它,同一曲目防併發。 + - 順序: + 1. 已有匹配就用; + 2. 依使用者排序以 `lyricsForOrigin` 直取; + 3. 標題解析(宿主正則,AI 模式開啟時用 `parseTitle`、失敗退回正則); + 4. 並行搜尋所有啟用的歌詞插件; + 5. 共用評分核心加同步歌詞加分(ADR 0014 決定 9、ADR 0019 決定 6);「允許自動匹配純文字歌詞」沿用、預設關; + 6. 開啟候選挑選時送前 8 名給 `pickCandidate`。 + - 手動改選列出評分,寫入後標 `manual`,自動流程永不覆寫。 + - 歌詞插件被移除時匹配保留、標「歌詞源未安裝」、不自動重配。 +6. **資料**: + - `lyrics_matches`(主資料庫):曲目鍵 FK 連帶刪除、插件 id、歌詞 id、`offsetMs`、`origin`(`direct`/`scorer`/`ai`/`manual`)、分數、AI 確定度、時間。 + - 歌詞內容在 `cache.db`,鍵為插件 id+歌詞 id(ADR 0016);AI 標題解析結果也在 `cache.db`。 + - 偏移:`adjusted = position + offsetMs`,正值=歌詞提前;播放頁 ±100/500/1000ms;點行跳轉;桌面視窗右鍵某行校正。 +7. **同步與顯示**: + - 歌詞模組的 `LyricsSession` 是唯一來源,持有目前曲目的歌詞文件、偏移、顯示模式與播放狀態,與 UI 生命週期無關。 + - 播放狀態、位置、速度、時間戳只在播放、暫停、seek、換歌、換速時推送,各顯示端以 frame callback 外推,不開週期計時器。 + - 子 engine 與主 engine 以一個共用 Dart 檔定義的型別化訊息溝通(JSON 序列化)。 + - 播放頁、桌面視窗、Android 懸浮共用一套歌詞 widget;逐字漸變用 `CustomPainter`+分段 shader+`saveLayer(dstIn)` 遮罩。 + - 顯示模式沿用(原文/優先翻譯/優先羅馬音),另加「逐字高亮」(預設開)。 +8. **桌面歌詞視窗**(E11): + - 平台能力 `desktopLyrics`,細分 `clickThrough`、`alwaysOnTop`(ADR 0009);入口只在宣告時出現。 + - 以 `desktop_multi_window`(每視窗一個 engine)實作;透明、置頂、單行、11 項樣式、hover 工具列、點行跳轉、右鍵校正沿用;關閉是隱藏不銷毀。 + - **鎖定**=不能拖動+點擊穿透。解鎖入口:托盤選單、全域快捷鍵、主視窗播放列的歌詞按鈕,以及 hover 浮出的解鎖鈕(預設開,可關)。 + - 平台實作: + - Windows:`window_manager.setIgnoreMouseEvents`; + - macOS:`window_manager`; + - Linux X11:自寫 GTK 空 input region+`gdk_window_set_pass_through`; + - Wayland:實機驗證,不支援的能力不宣告,鎖定只剩不能拖動並在設定頁註明。 + - hover 解鎖鈕在 Windows 與 Linux 以每 100ms 查游標實作,計時器只在「鎖定+視窗可見+解鎖鈕開啟」時存在。 +9. **Android 懸浮歌詞**: + - 平台能力 `overlayLyrics`。 + - 可拖動;鎖定=`FLAG_NOT_TOUCHABLE`+不透明度 0.8(Android 12 起的規定);解鎖在播放通知的自訂按鈕與 App 內開關。 + - 以 `flutter_overlay_window`(第二個 engine、共用歌詞 widget 與型別化訊息)為候選,控制經訊息回主 engine 的 `PlaybackController`;不可行就改原生 View,訊息不變。 + - 權限經 `PermissionGateway`(ADR 0020)新增「顯示在其他應用上層」;小米、ColorOS 的額外懸浮權限只能在說明中提示。 +10. **iOS 鎖屏/動態島**:平台能力 `liveActivityLyrics`,以 ActivityKit 顯示目前一行(+翻譯)、資料 ≤ 4KB、換行時本機更新;iOS 平台任務實測後才宣告。 +11. **設定**(ADR 0011 的「歌詞」組): + - 歌詞插件的啟用與順序; + - 自動匹配、純文字自動匹配、顯示模式、逐字高亮; + - AI 模式與使用的 AI 插件,端點、模型、門檻、key 在該插件的設定頁; + - 桌面歌詞的樣式、置頂、單行、鎖定、hover 解鎖鈕、快捷鍵; + - Android 懸浮的開關、位置、字級、顏色、不透明度。 +12. **舊資料匯入**(ADR 0010): + - `LyricsMatch` → `lyrics_matches`:來源對到官方插件 id,`externalId`、`offsetMs` 照搬;`origin` 記 `manual`(舊版不分自動與手動,視為使用者認可)。 + - 桌面歌詞樣式與顯示模式照搬。 + - AI 端點、模型、逾時搬進 `openai-compatible` 插件設定;舊 key 在該插件安裝後搬進其憑證區,並刪除舊項目。 + - 標題解析快取與舊歌詞檔案快取不搬。 + +採用的慣例: +- MusicFree 的「搜尋與取用分開、跨插件候選清單」; +- AMLL、Lyricify、BetterLyrics 的「行+字、整數毫秒」正規化與逐字→逐行降級; +- LX 的翻譯行 100ms 容差對齊,以及 LX、BetterLyrics 的「鎖定=不能拖+穿透、托盤與快捷鍵解鎖、輪詢游標做 hover」; +- LX Mobile 的 Android 鎖定(`FLAG_NOT_TOUCHABLE`+0.8); +- `desktop_lyrics` 的 GTK 穿透; +- TypeSafe `/v1/systemone` 的 Choice 題與 pre-parsed value extraction。 + +## 後果 + +- 好的: + - 來源與 AI 服務改了只需更新插件; + - 逐字、翻譯、羅馬音一套結構、一套 widget; + - 同步不再隨版面停止; + - 漏推欄位變成編譯錯誤; + - B5 的三個問題都有對應; + - 桌面與 Android 都能鎖定穿透。 +- 壞的: + - 插件多一種能力與歌詞文件格式要長期相容; + - Linux 要自寫 GTK 原生碼; + - 桌面鎖定時多一個查游標的計時器; + - Android 懸浮多開一個 engine; + - `window_manager` 0.5.x 已停止維護(0.6.0 改建在 `nativeapi`),換套件的成本落在平台層。 +- 之後要注意: + - Android 狀態列歌詞、本機歌詞檔匯入在功能凍結待辦; + - Flutter 官方多視窗 API 進 stable 後再評估; + - 逐字渲染直接用 `flutter_lyric`(避開已撤回的 3.0.5)或自寫,在第一個加入逐字的里程碑決定。 + +## 如何確認 + +- 單元測試: + - LRC 解析(含 enhanced LRC 字時間)、翻譯 100ms 對齊、逐字→逐行降級; + - 匹配流程各分支:已有匹配、直取、正則與 AI 標題解析、`chosen`/`noneMatch`/`unsure`、手動改選不被覆寫、插件移除後保留; + - 偏移換算與校正;顯示端外推位置。 +- 插件契約(ADR 0015): + - `lyrics` 的搜尋、取用、直取回傳合法的歌詞文件(字時間為絕對、遞增); + - `aiAssist` 的兩個方法;官方 AI 插件的測試斷言 log 不含 payload 內容。 +- 宿主測試: + - AI 請求只含設定頁列出的欄位;非 https 端點被拒; + - 使用者端點網域確認前不在允許清單。 +- 型別化訊息的序列化往返測試;取代舊 `lyrics_window_strings` static-rule。 +- lint: + - `fmp_periodic_timer_owner`(ADR 0017)的允許擁有者加入平台層的桌面歌詞模組(查游標); + - `fmp_layer_imports`(ADR 0015):`desktop_multi_window`、`window_manager`、`flutter_overlay_window` 只在平台層實作檔。 +- 平台實測(延後): + - 桌面歌詞在 macOS、Linux X11、Wayland 的穿透、置頂、定位; + - `window_manager` 在子 engine 設穿透時作用在歌詞視窗; + - `flutter_overlay_window` 的記憶體與 Android 15 前景服務限制; + - iOS Live Activity 本機逐行更新。 From 789849d01ee5ba007a2847ac113322150e5291d4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:14:04 +0800 Subject: [PATCH 075/133] chore(task): archive design-lyrics --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 18 ++++++++++-------- .../2026-09}/09-28-design-lyrics/check.jsonl | 0 .../2026-09}/09-28-design-lyrics/design.md | 0 .../09-28-design-lyrics/implement.jsonl | 0 .../2026-09}/09-28-design-lyrics/implement.md | 10 +++++----- .../2026-09}/09-28-design-lyrics/prd.md | 0 .../research/ai-decision-models.md | 0 .../research/current-state.md | 0 .../research/extra-features.md | 0 .../research/packages-and-platform.md | 0 .../09-28-design-lyrics/research/prior-art.md | 0 .../2026-09}/09-28-design-lyrics/task.json | 6 +++--- 12 files changed, 18 insertions(+), 16 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/implement.md (83%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/research/ai-decision-models.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/research/extra-features.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-lyrics/task.json (87%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 478da7c69..8039db1bd 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019) | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) | ## 2. 依賴關係 @@ -124,7 +124,7 @@ flowchart LR | 12 | 13 播放核心(✅ 完成,ADR 0018) | 最大的一塊;依賴 1、2、10、17。 | | 13 | 14 音樂庫與同步(✅ 完成,ADR 0019) | B1/B2 已定方向,細節依賴 6、1、12、16。 | | 14 | 11 下載與權限(✅ 完成,ADR 0020) | 依賴播放核心的本地播放路徑。 | -| 15 | 15 歌詞 | 依賴 1、13。 | +| 15 | 15 歌詞(✅ 完成,ADR 0021) | 依賴 1、13。 | | 16 | 19 發版與更新 | 依賴 10、16;你已給出流程要求。 | | 17 | 3 Toast | 依賴 2、18。 | | 18 | 5 UI/UX | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | @@ -232,6 +232,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 - ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 - ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 +- ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——`flutter_overlay_window` 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——`flutter_lyric` 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -240,13 +241,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 15 項完成後) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0020`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0021(歌詞)。 -- **進行中:第 15 項「歌詞」**,task `.trellis/tasks/09-28-design-lyrics/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成。 -- 之後順序:19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0021`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0022(發版與更新)。 +- **下一項:第 19 項「發版與更新」**(尚未建 task)。已知方向:只手動檢查更新;下載後安裝或刪除;重啟後清掉舊安裝檔;release notes 由 CHANGELOG/commit 自動產生;保留自動發布。 +- 之後順序:3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 - 工作守則(本輪累積): @@ -255,4 +256,5 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 研究子代理的結論要抽查(例如它曾誤稱 ExoPlayer 不支援 FLV,官方格式表為支援、不可 seek),更正寫進 prd。 - 子代理因額度中斷:先 SendMessage 續跑;使用者手動停掉的代理不能續跑,使用者要求時才重新發起,並告知保留已寫的研究檔。 - 更新他項 ADR 的引用時只加一句指向新 ADR,不改原決定;新 lint 規則補記到 ADR 0015 的「後續 ADR 新增的規則」。 + - 使用者提出新概念(例如 Jev)或要求把新功能一起做時,先派研究查成熟做法與可行性,再把可行性表攤開問範圍;使用者反駁建議的理由時(例如「插件只要更新插件」)若成立就改建議並寫進 prd 的決定。 - 每項最終摘要需列:你已定的、技術選擇(在核准範圍內)、放進待辦、不在範圍、核准後會做什麼、下一項。 diff --git a/.trellis/tasks/09-28-design-lyrics/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/check.jsonl diff --git a/.trellis/tasks/09-28-design-lyrics/design.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/design.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/design.md diff --git a/.trellis/tasks/09-28-design-lyrics/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/implement.jsonl diff --git a/.trellis/tasks/09-28-design-lyrics/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/implement.md similarity index 83% rename from .trellis/tasks/09-28-design-lyrics/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/implement.md index a377d31eb..bfccf775a 100644 --- a/.trellis/tasks/09-28-design-lyrics/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/implement.md @@ -1,17 +1,17 @@ # 執行計畫:第 15 項(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0021-lyrics.md`(依 `docs/adr/template.md`),內容取自 `design.md` §2–§11;被否決的方案: +1. [x] 核准後寫 `docs/adr/0021-lyrics.md`(依 `docs/adr/template.md`),內容取自 `design.md` §2–§11;被否決的方案: 三個歌詞源各自寫死在 Dart、宿主內建 QRC/KRC 解析器、AI 只留標題解析、App 內建 AI 客戶端(擁有者指出做成插件只需更新插件)、 只承諾 Windows 的桌面歌詞、只有 hover 工具列沒有鎖定、同步掛在 UI 元件上、以字串 map 推子視窗、逐 tick 推送位置、 Flutter 官方多視窗 API(仍在 `main` channel)、Android 狀態列歌詞(列待辦)、iOS 系統級懸浮(平台不允許)。 -2. [ ] 其他 ADR 各加一句指向 ADR 0021:0009(`desktopLyrics` 細分 `clickThrough`/`alwaysOnTop`、`overlayLyrics`、`liveActivityLyrics`)、 +2. [x] 其他 ADR 各加一句指向 ADR 0021:0009(`desktopLyrics` 細分 `clickThrough`/`alwaysOnTop`、`overlayLyrics`、`liveActivityLyrics`)、 0014(能力加 `aiAssist`;`lyrics` 介面與歌詞文件)、0015(後續 ADR 新增的規則:`fmp_periodic_timer_owner` 允許桌面歌詞查游標)、 0016(AI 標題解析快取在 `cache.db`)、0017(同上的計時器擁有者)、0020(`PermissionGateway` 加懸浮窗權限)。 -3. [ ] `phase2-plan.md`:§3 第 15 項標 ✅(ADR 0021);第 20 項待辦加 Android 狀態列歌詞、本機歌詞檔匯入; +3. [x] `phase2-plan.md`:§3 第 15 項標 ✅(ADR 0021);第 20 項待辦加 Android 狀態列歌詞、本機歌詞檔匯入; §8 延後實測加入:桌面歌詞在 macOS/Linux X11/Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在子視窗; `flutter_overlay_window` 的記憶體與 Android 15 前景服務限制;iOS Live Activity 本機逐行更新;`flutter_lyric` 直接用或自寫; §10 交接段更新,下一項 19 發版與更新,下一份 ADR 0022。 -4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 -5. [ ] `task.py finish`、`task.py archive design-lyrics --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-lyrics --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-lyrics/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/prd.md diff --git a/.trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/ai-decision-models.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/research/ai-decision-models.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/research/ai-decision-models.md diff --git a/.trellis/tasks/09-28-design-lyrics/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/research/current-state.md diff --git a/.trellis/tasks/09-28-design-lyrics/research/extra-features.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/extra-features.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/research/extra-features.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/research/extra-features.md diff --git a/.trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-lyrics/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-lyrics/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-lyrics/task.json b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/task.json similarity index 87% rename from .trellis/tasks/09-28-design-lyrics/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-lyrics/task.json index 7aea526fc..c303ddc68 100644 --- a/.trellis/tasks/09-28-design-lyrics/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-lyrics/task.json @@ -3,7 +3,7 @@ "name": "design-lyrics", "title": "Design: lyrics", "description": "Phase-2 item 15: lyrics sources as plugins, matching with the shared scorer, cache, display, desktop lyrics window, AI features", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From cda0981da653e83df89435e095f9e08fd84087c1 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:15:19 +0800 Subject: [PATCH 076/133] chore(task): start design-release-update --- .../09-28-design-release-update/check.jsonl | 0 .../implement.jsonl | 0 .../tasks/09-28-design-release-update/prd.md | 19 ++++++++++++++ .../09-28-design-release-update/task.json | 26 +++++++++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 .trellis/tasks/09-28-design-release-update/check.jsonl create mode 100644 .trellis/tasks/09-28-design-release-update/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-release-update/prd.md create mode 100644 .trellis/tasks/09-28-design-release-update/task.json diff --git a/.trellis/tasks/09-28-design-release-update/check.jsonl b/.trellis/tasks/09-28-design-release-update/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-release-update/implement.jsonl b/.trellis/tasks/09-28-design-release-update/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md new file mode 100644 index 000000000..aeebe43a8 --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -0,0 +1,19 @@ +# Design release and in-app update + +## Goal + +Phase-2 item 19: release pipeline, versioning, changelog-driven notes, in-app manual update on each platform, checksums + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-release-update/task.json b/.trellis/tasks/09-28-design-release-update/task.json new file mode 100644 index 000000000..a4e9fe004 --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-release-update", + "name": "design-release-update", + "title": "Design release and in-app update", + "description": "Phase-2 item 19: release pipeline, versioning, changelog-driven notes, in-app manual update on each platform, checksums", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From eed6f6f89778946617ddacab28627b71c508f49d Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:40:01 +0800 Subject: [PATCH 077/133] chore(task): add release research and draft requirements --- .../tasks/09-28-design-release-update/prd.md | 71 +- .../research/current-state.md | 228 ++++++ .../research/packages-and-platform.md | 238 +++++++ .../research/prior-art.md | 658 ++++++++++++++++++ 4 files changed, 1184 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-release-update/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-release-update/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-release-update/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md index aeebe43a8..483f157d7 100644 --- a/.trellis/tasks/09-28-design-release-update/prd.md +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -1,19 +1,68 @@ -# Design release and in-app update +# 設計:發版與應用內更新(階段二第 19 項) -## Goal +## 目標 -Phase-2 item 19: release pipeline, versioning, changelog-driven notes, in-app manual update on each platform, checksums +為 `app/` 定下版本號與發版流程、發佈說明的產生方式、各平台的發佈格式,以及應用內更新(檢查、下載、驗證、安裝、清理)。產出 ADR 0022。技術設計見 `design.md`,執行步驟見 `implement.md`。 -## Requirements +依據:parent `prd.md` 階段二第 19 項;`docs/audit/questions.md` A6、B7–B9、E17;`phase2-plan.md` §4「應用內更新流程」與 §5 的 B7–B9 方向; +ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身分沿用)、0009(平台能力)、0015(dev/prod flavor、CI 分專案)、0017(更新檢查只手動)、0020(`PermissionGateway` 含安裝權限)。 -- TBD +## 現況(`research/current-state.md`,已以程式碼核對) -## Acceptance Criteria +- **檢查**:只有「設定 → 關於 → 檢查更新」手動一個入口;打 `api.github.com/repos/1morr/FMP/releases/latest`,未認證、無 rate limit 處理(`update_service.dart:396-399,500-509`)。 + 版本比較自寫、只比三段、不比 build number(`:689-712`)。 +- **選檔**:依檔名 `fmp-{tag}-android-{abi}.apk`、`fmp-{tag}-windows-installer.exe`、`fmp-{tag}-windows.zip`;ABI 用 `getprop`、找不到退 `universal`; + Windows 以程式目錄有 `unins000.exe` 判斷安裝版(`:53-58,93-104,151-197`)。 +- **驗證**:先寫 `.part`、驗證後改名;**SHA-256 只在 release 附 `*-checksums.sha256` 時才驗**,否則只比大小(B8,`:767-828`)。 +- **Windows 安裝版**:Inno Setup,`/SILENT /DIR=<目前目錄> /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS` 後 `exit(0)`(`:587-621`)。 + **免安裝版**:解壓到 Temp,產 bat+vbs,bat 等 PID 結束 → `robocopy /MIR` 備份與覆蓋,`errorlevel ≥ 8` 才回滾(`:624-686,830-875`);1–7 的部分成功會留下半套檔案(推測)。 +- **Android**:`OpenFilex.open`(ACTION_VIEW)開系統安裝器,先檢查「安裝未知應用」逐 App 授權;按一次=下載+立刻跳安裝器,**沒有「下載完選安裝或刪除」**(B9,`:247-254,540-584`)。 +- **清理**:Windows 啟動時清 Temp 殘留;Android 在下一次下載前清。沒有跨平台的「重啟後清」。Linux/macOS 沒有實作(`update_service.dart:521`)。 +- **發版**:`release.yml` 由 `v*` tag 觸發;validate → 4 個 ABI 的 APK(keystore 來自 secrets)+ Windows zip 與 Inno 安裝檔(**無 code signing**)→ verify(11 個 asset、checksums、別名逐位元相同、aapt2 版本、PE 標頭)→ 直接發布。 + versionCode = `major*1000000 + minor*1000 + patch`。**版本號要手動先改 pubspec、合併後才打 tag**,`pubspec_version_test` 擋落後。 + 發佈說明由 `prev..tag` 的 commit 依 Conventional 前綴分四段自動產生;同一段文字也顯示在 App 的更新對話框。**repo 沒有 `CHANGELOG.md`**。 +- 目前只發 Android 與 Windows;Linux、macOS、iOS 沒有發佈物。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`,關鍵項已抽查) -## Notes +- **成熟產品**:LocalSend、Finamp 完全不檢查;Spotube、Hiddify、Harmonoid、Namida 檢查後只開瀏覽器;真正自我更新只有 AppFlowy(僅 macOS,Sparkle)與 LX Music(electron-updater)。 + 7 個 Flutter 專案沒有一個在 Android 應用內下載安裝 APK;Android 自己裝的是 Seal、Obtainium。檢查來源幾乎都是 GitHub Releases API。 + **驗證 checksum 的幾乎沒有**:只有 Obtainium 比對 APK 簽章憑證。 +- **發佈說明工具**:`release-please` 有現成 `dart` 策略(改 pubspec 版本+寫 `CHANGELOG.md`,以「release PR」合併後打 tag),支援 monorepo 路徑; + `git-cliff` 只產 changelog;`standard-version` 已棄用。各家做法分歧:release-drafter、自寫腳本、手寫都有。 +- **套件**:`desktop_updater` 3.2.0(2026-09-22,三平台、Ed25519,但 Linux 仍是 candidate、3.x 破壞性變更頻繁);`auto_updater` 1.0.0(2024-10,無 Linux、停滯); + `ota_update` 7.1.0(Android 專用);`pub_semver` 2.2.1 的比較**含 build number**(`1.2.3+4 > 1.2.3`)。 +- **Android**:Play 政策禁止用 `REQUEST_INSTALL_PACKAGES` 做自我更新(FMP 不上架,不受限);升級必須同簽章;Android 14 起不能安裝 targetSdk < 23 的 APK。 +- **Windows**:SmartScreen 是信譽制,**EV 憑證自 2024 起也不給即時信譽**;SignPath Foundation 對開源專案免費簽章(需申請、在 CI 建置);Azure Artifact Signing 要付費訂閱、不發 EV。 + Inno Setup exit code 8=需重開機。 +- **macOS**:未公證的 App 在 Sequoia 起不能右鍵開啟,要到系統設定按「仍要打開」;公證需 $99/年的開發者帳號。Sparkle 2 用 EdDSA。 +- **Linux**:AppImage 可內嵌更新資訊(`gh-releases-zsync`)並以 zsync 差量更新;Flatpak 的 App 目錄唯讀、只能由系統更新;deb/rpm 由套件管理器管理。 +- **iOS**:Guideline 2.5.2 禁止下載執行改變功能的程式碼;側載免費帳號 7 天到期、付費 1 年。 +- **GitHub**:未認證 60 次/小時;`releases/latest` 不含 prerelease 與 draft;**每個 asset 自 2025-06 起有 `digest`(`sha256:…`),FMP v1.11.0 的 11 個全都有**(已實測); + 下載經兩次 302 到簽章網址(約 50 分鐘有效),支援 Range 續傳。有社群回報同名重傳後 digest 會變——但重傳需要 repo 寫入權,這種人也能改 checksums 檔,兩者防護等級相同。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向 + +- 更新流程(擁有者已定,`phase2-plan.md` §4):不在啟動或定時檢查,只有手動;檢查到後使用者點「下載」;下載完可選「安裝」或「刪除」;點安裝才安裝;重啟後清除舊安裝包。 + Release 維持 tag 後自動發布,發佈說明由 CHANGELOG 或 commit 訊息自動產生、不手寫。 +- 安裝檔一律驗 SHA-256(B8);免安裝版的自我覆蓋改成更穩的做法(B7);應用內更新 iOS 除外;不上架商店(ADR 0004)。 +- **切換相容(由 ADR 0008 推得)**:舊版 v1.x 的更新器依檔名挑 asset、驗 checksums、以 `unins000.exe` 判斷安裝版、只比三段版本。 + 新 App 的第一個版本必須沿用這些檔名、Inno AppId、Android 簽名金鑰,且版本號大於 1.11.0,舊版使用者才能在 App 內直接升上來。 + +## 待決定 + +1. 版本號與發佈說明的流程:沿用「手動改 pubspec+打 tag、說明由 commit 產生」,或改用 `release-please`(自動改版本、寫 CHANGELOG、合併 release PR 即發版)。 +2. Linux、macOS 的發佈格式與更新方式。 +3. Windows 程式碼簽章(SignPath Foundation 申請)。 +4. 新 App 第一個版本的版本號。 + +## 不在範圍 + +- 上架任何商店;iOS 的應用內更新。 +- 自動檢查更新、預發佈頻道(功能凍結)。 + +## 驗收條件 + +- [ ] ADR 0022 記錄:版本號與發版流程、發佈說明、各平台發佈格式、更新的檢查/下載/驗證/安裝/清理、各平台差異、切換相容、dev flavor 行為。 +- [ ] A6、B7、B8、B9、E17 各自對到決定。 +- [ ] `phase2-plan.md` §3 第 19 項標 ✅ 與 ADR 編號。 diff --git a/.trellis/tasks/09-28-design-release-update/research/current-state.md b/.trellis/tasks/09-28-design-release-update/research/current-state.md new file mode 100644 index 000000000..6f78b0a9e --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/research/current-state.md @@ -0,0 +1,228 @@ +# 舊專案現況:發版與應用內更新 + +- 查證日:2026-09-28 +- 查證方式:直接讀 repo 檔案(`lib/`、`android/`、`.github/workflows/`、`docs/`、`test/`、`pubspec.yaml`),行號為當下 `docs/audit` 分支工作樹的行號。工具:Read/Grep/`git log`。**未執行 App、未打任何平台 API**。 +- 範圍:發版流程(CI/release workflow)、版本號與 CHANGELOG、應用內更新服務(檢查/下載/驗證/安裝/清理)、相關 ADR/audit 文檔、相關測試與 static-rule。 +- 標記約定:**事實**=有 `檔案:行號` 佐證;**推測**=依程式碼推論但未實測;**查不到**=找過沒找到。 + +--- + +## 1. 應用內更新服務 + +### 1.1 檔案與入口 + +| 檔案 | 角色 | 證據 | +|---|---|---| +| `lib/services/update/update_service.dart`(904 行) | GitHub API 呼叫、版本比較、asset 選擇、下載、驗 SHA-256、各平台安裝、清理 | `update_service.dart:1-904` | +| `lib/providers/system/update_provider.dart`(238 行) | Riverpod `Notifier` 狀態機(`UpdateStatus` 8 態) | `update_provider.dart:13-238` | +| `lib/ui/widgets/dialogs/update_dialog.dart`(379 行) | 更新對話框;含 release notes 的 markdown 攤平 | `update_dialog.dart:100-379` | +| `lib/ui/pages/settings/widgets/settings_about.dart` | 唯一 UI 入口:「設定 → 關於 → 檢查更新」 | `settings_about.dart:42-88` | +| `android/app/src/main/kotlin/com/personal/fmp/MainActivity.kt` | Android MethodChannel:安裝來源權限 | `MainActivity.kt:22-34,150-168` | + +- **事實**:只有一個入口,且只有手動。`checkForUpdate` 的 UI 呼叫點只有 `settings_about.dart:70`;啟動時與定時都不檢查。`features.md §13.5` 記「沒有自動更新」。 +- **事實**:啟動時只在 Windows 清理上一次的殘留檔(`main.dart:230-231` → `UpdateService.cleanupOldWindowsUpdateFiles`,`update_service.dart:259-292`)。 +- **事實**:`autoCheckUpdates` 設定在 2026-09 被移除,grep 只剩註釋(`lib/services/backup/backup_service.dart:29-30`、`lib/data/database/database_migration.dart:224`;`features.md §11` 註)。 + +### 1.2 檢查來源與 rate limit + +- **事實**:`GET https://api.github.com/repos/1morr/FMP/releases/latest`,只帶標頭 `Accept: application/vnd.github.v3+json`(`update_service.dart:18-19,396-399`)。 +- **事實**:**沒有** token、**沒有** ETag/`If-None-Match`、**沒有** 條件式請求、**沒有** rate limit 處理或退避。Dio 只設 `connectTimeout` 15 秒(`AppConstants.updateConnectTimeout`)與 `receiveTimeout`(`app_constants.dart:121`;`update_service.dart:217-223`)。 +- **事實**:HTTP 404 被當成「沒有 release」回 `null`(`update_service.dart:500-503`);其他錯誤(含可能的 403 rate limit)直接 rethrow,由 provider 顯示「檢查更新失敗:<原因>」(`update_service.dart:504-509`;`update_provider.dart:95-107`)。 +- **事實**:未認證 GitHub API 有速率上限,這是既有風險但程式未處理(**推測**:未認證每小時 60 次/每 IP,官方文件;本專案每次手動檢查只打一次,正常使用不會撞到)。 + +### 1.3 版本比較 + +- **事實**:`tag_name` 去 `v` 前綴得 `latestVersion`(`update_service.dart:406-409`);當前版本取自 `PackageInfo.fromPlatform().version`(**不含** build number)(`:412-413`)。 +- **事實**:`_isNewerVersion` 只把 `current`/`latest` 以 `.` 切開、`int.tryParse`(失敗視為 0),補到 3 段後逐段比較,**不比第 4 段、不比 build number、不比 `+` 後綴**(`update_service.dart:689-712`)。→ 後果:`1.2.3+1002003` 與 `1.2.3` 視為相同。 +- **事實**:沒有用 `pub_semver`;`pubspec.yaml` 沒有 `pub_semver` 直接依賴(`grep pub_semver pubspec.yaml` 無命中)。 + +### 1.4 Asset 選擇(平台/ABI/安裝版 vs 免安裝版) + +- **事實**:檔名分類(`update_service.dart:432-465`): + - APK:regex `fmp-.+-android-(.+)\.apk$` 取 ABI;不符這個格式的 `.apk` 當 `universal`(`:433,440-451`)。 + - `-windows-installer.exe` 結尾 → installer;`-windows.zip` 結尾 → portable(`:452-461`)。 + - `-checksums.sha256` 結尾 → checksum manifest(`:462-464`)。 +- **事實**:別名 `fmp-latest-*` 與版本化檔落在同一格,**誰在 assets 清單裡排在後面誰贏**(`engineering.md §1.4`;`update_service.dart:435-465`)。 +- **事實**:Android ABI 用 `Process.run('getprop', ['ro.product.cpu.abi'])` 取得,白名單 `arm64-v8a`/`armeabi-v7a`/`x86_64`,否則 `universal`(`update_service.dart:64-77`)。 +- **事實**:選不到對應 ABI 時退回 `universal`;連 `universal` 都沒有 → 丟 `UpdateAssetUnavailableException`(`update_service.dart:151-173`)。 +- **事實**:Windows 安裝版判定=`Platform.resolvedExecutable` 同目錄存在 `unins000.exe`(`update_service.dart:53-58`)。安裝版選 installer、免安裝版選 zip(`update_service.dart:175-197`)。 +- **事實**:`checkForUpdate` 內會先觸發一次 `info.selectedAsset` 以求 checksum 問題在檢查階段就爆(`update_service.dart:494-497`)。 + +### 1.5 下載位置與完整性驗證 + +- **事實**:下載目錄都是 `getTemporaryDirectory()`(Android/Windows 的 cache/Temp)(`update_service.dart:229,545-547,592-594,629-631`)。 +- **事實**:檔名為 `fmp--android-.apk`、`fmp--windows-installer.exe`、`fmp--windows.zip`(`update_service.dart:97-104,165,187-189`)。 +- **事實**:下載一律先寫 `<檔名>.part`,驗證通過才 `rename` 成正式檔;失敗刪 `.part`(`update_service.dart:714-752`)。 +- **事實**:`_validateDownloadedAsset` 先驗檔案存在,再驗 `size`(若 GitHub 有回報),最後驗 SHA-256(`update_service.dart:800-828`)。 +- **事實**:**SHA-256 只有 release 附 `*-checksums.sha256` 才驗**。manifest 不存在 → `assetSha256s` 為空、`checksumManifestAvailable=false`,只驗 size(`update_service.dart:467-470,776-783`)。B8 現況即此。 +- **事實**:manifest 存在但缺該檔名的 hash → 直接丟 `UpdateIntegrityException`(`update_service.dart:776-783`)。 +- **事實**:manifest 格式=`sha256sum` 風格 `^([a-fA-F0-9]{64}) [ *](.+)$`,key 取 `basename`、hash 轉小寫(`update_service.dart:785-798`)。 +- **事實**:Android 若有已下載且通過完整性檢查的檔,會重用不再下載;不通過就刪掉(`update_service.dart:226-245`)。 + +### 1.6 Windows 安裝版流程 + +- **事實**:下載 `fmp--windows-installer.exe` 到 Temp,用 `Process.start(..., mode: detached)` 帶參數 `/SILENT /DIR=<目前程式目錄> /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS` 啟動,然後 `exit(0)`(`update_service.dart:587-621`)。 +- **事實**:`/DIR=` 是為了強制覆蓋安裝到「目前執行檔所在目錄」,避免裝到預設 Program Files(`update_service.dart:612` 註)。 +- **事實**:**沒有** code signing(見 §3.3);安裝檔來自 Inno Setup(見 §3.2)。 + +### 1.7 Windows 免安裝版流程 + +- **事實**:下載 `fmp--windows.zip` → 在 worker isolate 以串流方式解壓到 `Temp/fmp_update`(**不可整包讀進記憶體**:release ZIP 約 200 MB,`update_service.dart:877-879` 註)→ 寫出 `fmp_updater.bat` 與 `fmp_updater.vbs` → `Process.start('wscript', [vbsPath], detached)` 隱藏視窗執行 → `exit(0)`(`update_service.dart:624-686`)。 +- **事實**:解壓有 zip-slip 防護:拒絕絕對路徑、`..`、Windows 磁碟機前綴(`update_service.dart:359-385`)。 +- **事實**:bat 內容(`_buildPortableUpdaterBatch`,`update_service.dart:830-875`): + 1. `chcp 65001`、等原 PID 結束(`tasklist /FI "PID eq "` 迴圈); + 2. `robocopy "%DST%" "%BACKUP%" /MIR /XD fmp_update_backup` 備份程式目錄; + 3. `robocopy "%SRC%" "%DST%" /E` 覆蓋; + 4. `errorlevel 8` 以上 → `goto rollback`,從備份 `robocopy ... /MIR` 還原再啟動; + 5. cleanup 刪 `fmp_update`、備份、vbs 與自己(`update_service.dart:838-874`)。 +- **事實**:vbs 只有一行 `CreateObject("WScript.Shell").Run """""", 0, False`(`update_service.dart:675-676`)。 +- **推測**:免安裝版的自我覆蓋靠「等 PID 結束 + robocopy」;若程式目錄不可寫、防毒攔截、或 robocopy 部分成功(`errorlevel` 1–7 不觸發 rollback)會留下半套檔案。phase2-plan §5 明說要「改成更穩的做法」。 + +### 1.8 Android 安裝流程 + +- **事實**:下載 APK 到 cache(`update_service.dart:540-564`),下載前先刪同目錄其他 `fmp-*.apk`(`:549-550,567-584`)。 +- **事實**:安裝前檢查「允許此來源安裝應用程式」:`MethodChannel('com.personal.fmp/platform')` 的 `canRequestPackageInstalls`;未授權時 provider 進 `installPermissionRequired` 狀態並提供「開啟安裝設定」按鈕(`update_service.dart:295-306`;`update_provider.dart:183-193`;`update_dialog.dart:290-309,342-349`)。 +- **事實**:實際安裝用 `OpenFilex.open(filePath)` 開系統安裝器(ACTION_VIEW),**不是** `PackageInstaller` API(`update_service.dart:247-254`)。安裝器返回後狀態恢復 `readyToInstall`,可再按一次(`update_provider.dart:194-198`)。 +- **事實**:`AndroidManifest.xml` 宣告 `REQUEST_INSTALL_PACKAGES`(`AndroidManifest.xml:14`);`` 有 `VIEW` + `application/vnd.android.package-archive` 讓 open_filex 能解析(`AndroidManifest.xml:95-99`)。 +- **事實**:原生 `canRequestPackageInstalls`:API < O 直接回 true,否則查 `packageManager.canRequestPackageInstalls()`;`openInstallPermissionSettings`:API ≥ O 開 `Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES`(逐 App),否則開 `ACTION_SECURITY_SETTINGS`(`MainActivity.kt:150-168`)。 +- **事實**:目前流程是「按一次立即更新 = 下載 + 立刻跳安裝器」,**沒有**獨立的「下載完成後選擇安裝或刪除」這一步(`update_dialog.dart:330-369` 的 actions)。與 phase2-plan §4 的新需求(下載後可選安裝/刪除)不同。 + +### 1.9 舊安裝包清理 + +- **事實**:Windows:啟動時 `cleanupOldWindowsUpdateFiles` 掃 `getTemporaryDirectory()`,刪 `fmp-*.exe`、`fmp-*.zip`、`fmp_updater.bat`、`fmp_updater.vbs`、`fmp_update/` 目錄(`update_service.dart:259-293`;`main.dart:230-231`)。 +- **事實**:Android:下載前刪同目錄其他 `fmp-*.apk`(保留目標檔名)(`update_service.dart:567-584`)。 +- **事實**:**沒有**跨平台統一的「重啟後清舊安裝包」機制;Android 的清理綁在下載動作上,不是啟動時。 + +### 1.10 錯誤處理 + +- **事實**:`UpdateStatus` 8 態:`idle / checking / updateAvailable / downloading / readyToInstall / installPermissionRequired / installing / error / upToDate`(`update_provider.dart:13-23`)。 +- **事實**:`UpdateNotifier` 用遞增 `_operationId` 守競態:舊操作完成不能覆寫新狀態(`update_provider.dart:66-77`;測試 `test/providers/update_provider_test.dart:11-42`)。 +- **事實**:錯誤訊息統一走 `failureMessage()`(`lib/core/errors/user_message.dart`)後綴 i18n 前綴(`update_provider.dart:97-107,163-172,200-211`)。 +- **事實**:下載進度只在變化 ≥ 1% 或完成時更新狀態,避免過多 UI 重建(`update_provider.dart:140-146`)。 + +--- + +## 2. CI 與 release workflow + +### 2.1 `ci.yml`(`.github/workflows/ci.yml`,155 行) + +| 項目 | 內容 | 證據 | +|---|---|---| +| 觸發 | PR → `main`、push `main`、`workflow_dispatch`;**無** path filter(刻意:純文檔 commit 也要跑 validate) | `ci.yml:3-15` | +| 權限 | `contents: read` | `ci.yml:17-18` | +| 併發 | PR 以 ref、main/手動以 SHA 分組;`cancel-in-progress: true` | `ci.yml:23-25` | +| 環境 | Flutter `3.47.1`、Java 17 temurin | `ci.yml:27-30` | +| Action 版本 | 全部以 commit SHA 釘住 | `ci.yml:40,48,98,174` | +| secrets | 無 | 全檔 | + +- **事實** job: + - `validate`(ubuntu,15 分):`fetch-depth: 0`(`pubspec_version_test` 要 tag)→ `pub get` → `dart format --set-exit-if-changed lib test tool` → `build_runner build` → `slang` → `flutter analyze` → `flutter test --coverage --exclude-tags live`;上傳 `coverage-lcov`(保留 14 天)(`ci.yml:33-85`)。 + - `build-android`(needs validate):`flutter build apk --release --target-platform android-arm64` 冒煙;**沒有** `key.properties` 時 gradle 退回 debug 簽名(`ci.yml:87-122`;`android/app/build.gradle.kts:46-50`)。 + - `build-windows`(needs validate,windows-2022):`flutter build windows --release` 冒煙(`ci.yml:124-155`)。 + +### 2.2 `release.yml`(`.github/workflows/release.yml`,520 行) + +| 項目 | 內容 | 證據 | +|---|---|---| +| 觸發 | push `v*` tag;或 `workflow_dispatch` 輸入已存在的 `vX.Y.Z` tag | `release.yml:3-12` | +| 權限 | workflow 預設 `contents: read`;只有 `release` job 拿 `contents: write` | `release.yml:14-15,425-426` | +| 併發 | 同 ref 排隊、不取消 | `release.yml:17-19` | +| secrets | `KEYSTORE_BASE64`、`KEYSTORE_PASSWORD`、`KEY_PASSWORD`、`KEY_ALIAS`(Android);`GITHUB_TOKEN`(release) | `release.yml:117-141,520` | + +- **事實**:`prepare` 檢查 tag 符合 `^v[0-9]+\.[0-9]+\.[0-9]+$` 且存在;`version_code = major*1000000 + minor*1000 + patch`;`version_with_code = "+"`(`release.yml:44-72`)。 +- **事實**:`validate`(needs prepare):`flutter analyze` + `flutter test --exclude-tags live`;**沒有** format 檢查、**沒有** coverage(與 ci.yml 不同)(`release.yml:180-214`)。 +- **事實** `build-android`(matrix 4 格:`arm64-v8a`/`armeabi-v7a`/`x86_64`/`universal`):用 `sed` 把 tag 版本寫進 `pubspec.yaml`(**不回寫 repo**)→ base64 解 keystore 到 `android/release.keystore` 與 `android/key.properties`(缺任一 secret 就 `exit 1`)→ 建 APK → 改名 `fmp--android-.apk`,`arm64-v8a` 與 `universal` 另複製 `fmp-latest-android-.apk`(`release.yml:74-178`)。 +- **事實** `build-windows`(windows-2022):pwsh 改寫版本 → `flutter build windows --release` → 把 `LICENSE`/`THIRD_PARTY_LICENSES.md`/`licenses/` 放到 exe 旁 → 壓 `fmp--windows.zip` + `fmp-latest-windows.zip` → `choco install innosetup` → `dart run inno_bundle:build --release --no-app --no-installer` 產 ISS → regex 改寫 ISS → **驗證改寫生效(F8 gate,缺 `AppUserModelID` 或 `DefaultGroupName` 就紅)** → `ISCC.exe` 編譯 → `fmp--windows-installer.exe` + `fmp-latest-windows-installer.exe`(`release.yml:216-357`)。 +- **事實** ISS 改寫內容:刪 `icelandic` 語言、加 `DefaultGroupName=FMP`、加 `AppUserModelID: "com.personal.fmp"`、把 `Flags: nowait postinstall skipifsilent` 的 `skipifsilent` 拿掉(**讓靜默更新也能重啟 App**)(`release.yml:296-315`)。 +- **事實**:**Windows 產物沒有任何 code signing**(無 signtool/azure-signing 步驟;A6 現況亦如此)。 +- **事實** `verify`(needs prepare + 兩個 build):**刻意 checkout workflow 的 ref,不是 tag**(`release.yml:368` 註)→ 下載全部 artifact 合併 → 產生 `fmp--checksums.sha256`(只含 6 個版本化檔:4 APK + zip + installer;**排除** `fmp-latest-*`)(`release.yml:390-399`)→ `AAPT2=… dart run tool/release/verify_release_assets.dart release-assets `(`release.yml:401-409`)→ 上傳 `release-assets`(`release.yml:411-417`)。 +- **事實** `release`(needs prepare + verify):下載 `release-assets` → `git describe --tags --abbrev=0 ^` 找前一個 tag → 從 `..` 的 commit 依 Conventional Commits 前綴產生 body → `softprops/action-gh-release@v3.0.3` 以 `draft: false`、`prerelease: false` 直接發布,只上傳 `release-assets/*`(`release.yml:419-520`)。 +- **事實** Release notes 產生(`release.yml:452-506`): + - `git log --no-merges --pretty=format:"%s|%h" `; + - 分四段 `Features`(`^feat`)/`Fixes`(`^fix`)/`Performance`(`^perf`)/`Dependencies`(`^(chore|build)\(deps`); + - `refactor`/`docs`/`test`/`ci`/`style` 刻意不列(留給 compare 連結); + - 四段全空時退回列出全部 commit; + - 結尾 `**Full Changelog**: .../compare/...`; + - 用 `uuidgen` 產的隨機 delimiter 寫進 `$GITHUB_OUTPUT`(避免 body 撞到固定 EOF;`release_workflow_test.dart:64-83` 釘住)。 +- **事實**:ADR 0006 記一個 Release 現為 **11 個 asset**(v1.11.0 起多了 `fmp-latest-android-arm64-v8a.apk`);10 個的時代是 v1.10.2(`docs/adr/0006…md:23-34`)。 + +### 2.3 Release 驗證工具 `tool/release/verify_release_assets.dart`(211 行) + +- **事實**:檢查(`verify_release_assets.dart:28-165`): + 1. 檔案集合**剛好**等於 `expectedAssets(tag)`=6 版本化 + 4 別名 + checksums=11 個,缺一或多一都報錯(`:18-41,56-65`); + 2. checksums 每行格式、涵蓋全部 6 個版本化檔、不含別名、hash 相符(`:75-104`); + 3. 每個 `fmp-latest-*` 與同後綴版本化檔**逐位元相同**(`:109-119`;理由是 App 可能下載別名、卻用版本化檔名查 hash); + 4. 以 `aapt2 dump badging` 讀每個 APK 的 `versionName`/`versionCode` 對 tag(`:122-141,168-176`); + 5. Windows 安裝檔的 `MZ` + `PE\0\0` 簽章(`:143-165`;註解自承截斷檔擋不下)。 +- **事實**:只擋結構性錯誤,**不擋**執行期才會壞的 build(`:6-8`、ADR 0006)。 + +--- + +## 3. 版本號、CHANGELOG、commit 慣例 + +### 3.1 版本號 + +- **事實**:`pubspec.yaml:5` 現值 `version: 1.11.0+1011000`。 +- **事實**:tag 格式 `v{major}.{minor}.{patch}`;`+{versionCode}` 由 tag 算 `major*1000000 + minor*1000 + patch`(`release.yml:64-67`;`build-and-release.md:118-130`)。 +- **事實**:**版本號的補寫是手動的**:發版前先把 `pubspec.yaml` 版本升上去、合併進 main,再在合併後的 commit 打 tag push;順序反了 release 會紅(`build-and-release.md:154-180,269-287`)。 +- **事實**:`test/workflows/pubspec_version_test.dart` 守「committed 版本不得低於最新可達 tag」(允許超前、擋落後),並守 build number 公式(`:13-46`)。 +- **事實**:不用 `github.run_number` 當 build number(會導致降級拒裝)(`build-and-release.md:128-130`;`release_workflow_test.dart:115-125`)。 +- **事實**:Android `versionName`/`versionCode` 取自 `flutter.versionName`/`flutter.versionCode`(`docs/adr/0006…md:12-13`)。 + +### 3.2 Windows 安裝檔 + +- **事實**:用 `inno_bundle`(pubspec `^0.12.0`,`pubspec.yaml:101`)產生 Inno Setup 腳本,再由 `ISCC.exe` 編譯(`release.yml:289-342`)。 +- **事實**:`inno_bundle` 設定(`pubspec.yaml:110-126`):`id: BAF6CE8D-E1C8-4C29-AE0B-EDE98D5F8FAA`(AppId,註明**發布後不可更改**,改了使用者機器會當成另一個 App)、`name: FMP`、`publisher: FMP`、`installer_icon`、**`admin: false`**(非提權安裝)。 + +### 3.3 簽章 + +- **事實**:Android release 簽章用 GitHub Secrets 的 keystore(`KEYSTORE_BASE64` 等 4 個),解到 `android/release.keystore` + `android/key.properties`(`release.yml:117-141`)。 +- **事實**:本機無 `key.properties` 時 gradle 退回 **debug 簽名**(`android/app/build.gradle.kts:46-50`)。 +- **事實**:**Windows 無 code signing**(A6 現況、release.yml 全檔無簽章步驟)。 + +### 3.4 CHANGELOG 與 commit 慣例 + +- **事實**:**repo 沒有 `CHANGELOG.md`**(`ls CHANGELOG*` 無檔)。 +- **事實**:release notes 一律由 commit 訊息自動產生(`release.yml:452-506`),**沒有**手寫 notes 檔這條路(`release_workflow_test.dart:88-89` 斷言不含 `docs/release-notes/`)。 +- **事實**:commit 用 Conventional Commits(`git log` 觀察:`chore(task):`、`docs(adr):`、`feat`、`fix`、`perf`、`chore(deps)`)。 +- **事實**:release body 同時餵給 App 內更新對話框(`data['body']` → `releaseNotes`,`update_service.dart:472`),所以 body 要短、markdown 要淺(`release.yml:450-451` 註;`build-and-release.md:257-267`)。 + +--- + +## 4. ADR 與 audit 文檔要點(更新相關) + +| 文檔 | 要點 | 出處 | +|---|---|---| +| ADR 0004 | 擁有者決定**永不上架任何商店**,只從 GitHub Releases 散佈;Android 用 `MANAGE_EXTERNAL_STORAGE` + 裸路徑 | `docs/adr/0004…md:34-49,58` | +| ADR 0006 | Release 驗過產物**直接發布**,不留草稿等人按;`verify` job 的 4 項檢查;body 不再有人先讀(知情取捨);11 個 asset | `docs/adr/0006…md:40-99` | +| ADR 0008 | App 身分沿用舊版:Android `applicationId com.personal.fmp`、**同一把簽名金鑰**、Windows AppUserModelID `com.personal.fmp`;改身分會斷自動遷移,須另立 ADR | `docs/adr/0008…md:47-51,67,73` | +| ADR 0015 | flavor `dev`/`prod`,`default-flavor: dev`,發版帶 `--flavor prod`;dev 用 `applicationIdSuffix ".dev"`、AppUserModelID `com.personal.fmp.dev`、名稱「FMP Dev」、資料目錄/單一實例鎖/secure storage 命名空間加 `-dev` | `docs/adr/0015…md` 第 8 點(`sed -n '67,71p'`) | +| ADR 0017 | 背景排程器;**明確排除**「更新檢查與插件更新:只手動」;一次性啟動維護登記在「啟動維護清單」 | `docs/adr/0017…md:27-38` | +| ADR 0020 | `PermissionGateway` 依能力宣告權限,含「安裝更新(`REQUEST_INSTALL_PACKAGES`)」;流程:說明 → 請求 → 被拒說明影響並給「前往系統設定」→ 回 App 重查 | `docs/adr/0020…md` 第 9 點(`sed -n '65,72p'`) | +| audit `questions.md` A6 | 發佈管道:各平台都勾 GitHub Release;iOS「不確定」;維持自動發布;備註要求「不要手動發佈或手動設置文案,依 CHANGELOG 或 commit 信息生成」 | `docs/audit/questions.md:87-104` | +| audit `questions.md` B7/B8/B9 | B7 Windows 自動更新(installer `/SILENT`/portable bat+vbs+robocopy)勾「不確定」;B8 SHA-256 勾「修改:強制驗」;B9 Android 下載 APK 開系統安裝器勾「不確定」 | `docs/audit/questions.md:121-123` | +| audit `questions.md` E17 | 應用內更新:保留 | `docs/audit/questions.md:255` | +| audit `features.md` §11 | 檢查更新只有手動一個入口;下載安裝三平台流程;啟動時清 Temp 舊更新檔 | `docs/audit/features.md:261-264` | +| audit `features.md` §13.5 | **沒有**自動更新 | `docs/audit/features.md:361-363` | +| audit `features.md` §15.3 | 會自己下載或執行東西的行為(Windows 安裝版/免安裝版、Android、完整性、`getprop`) | `docs/audit/features.md:423-432` | +| audit `engineering.md` §1 | CI/release 逐 job 表;§1.3 驗證腳本;§1.4 自動更新時序圖 | `docs/audit/engineering.md:13-81` | +| audit `platforms.md` §6 | Linux/macOS/iOS 卡關點:`open_filex` 無 Linux/macOS;更新流程在該兩平台沒有實作(`update_service.dart:521`);iOS 2.5.2 禁止自行下載可執行碼 → 整個 `UpdateService` 不成立 | `docs/audit/platforms.md:343-399`(Linux 列 12、macOS 列 30、iOS 列 47) | +| `docs/build-and-release.md` | §4 發布流程、CI 流程、Release Notes、版本號規則、產物命名;§5 應用內更新機制 | `docs/build-and-release.md:152-372` | +| `phase2-plan.md` §4/§5 | 新需求:只手動檢查;檢查後點「下載」;下載完可選「安裝」或「刪除」;點安裝才安裝;重啟後清舊安裝包;Release 維持自動發布、說明自動產生。§5 傾向:安裝檔一律驗 SHA-256;免安裝版自我覆蓋改成更穩的做法;應用內更新 iOS 除外 | `.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md:166-167,185,205` | + +--- + +## 5. 相關測試與 static-rule + +| 檔案 | 測什麼 | 證據 | +|---|---|---| +| `test/workflows/pubspec_version_test.dart` | committed 版本不落後最新 tag;build number 公式 | 全檔 | +| `test/workflows/release_workflow_test.dart` | release gate:`verify` 等所有 `build-*`、`release` 等 `verify`、只上傳 `release-assets`;body 分組與隨機 delimiter;build number 公式 | 全檔 | +| `test/workflows/release_assets_verification_test.dart` | 以假產物證明 `verify_release_assets.dart` 每一項會紅、無關差異不紅(15 個 test) | 全檔 | +| `test/workflows/dependabot_group_static_rule_test.dart` | 0.x 直接依賴必須列在 dependabot `exclude-patterns`;`flutter_secure_storage` major 必須 ignore | 全檔 | +| `test/services/update/update_service_zip_test.dart` | zip-slip 防護;ABI fallback 時用 universal checksum | `update_service_zip_test.dart:8-60+` | +| `test/providers/update_provider_test.dart` | `_operationId` 競態;reset 取消延遲回寫;Android 等安裝權限 | `update_provider_test.dart:11-80+` | +| `test/ui/widgets/dialogs/update_dialog_release_notes_test.dart` | `plainTextReleaseNotes` 不留下 markdown 記號 | 全檔 | + +- **事實**:**沒有**專門守更新服務的 static-rule(`test/support/*static_rule*` 無 update 相關命中)。release 相關的「靜態規則」是 `release_workflow_test.dart`/`release_assets_verification_test.dart` 這種讀 workflow 與工具原始碼的測試。 +- **事實**:`test/services/update/` 只有一個檔案(`update_service_zip_test.dart`);`update_service.dart` 的 `checkForUpdate`/下載/SHA-256 路徑本身**沒有**直接單元測試(只有 `@visibleForTesting` 的選檔與 manifest 解析間接覆蓋)。 diff --git a/.trellis/tasks/09-28-design-release-update/research/packages-and-platform.md b/.trellis/tasks/09-28-design-release-update/research/packages-and-platform.md new file mode 100644 index 000000000..424f7acd9 --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/research/packages-and-platform.md @@ -0,0 +1,238 @@ +# 套件與平台事實:發版與應用內更新 + +- 查證日:2026-09-28 +- 查證方式: + - **套件(第 1 節)**:pub.dev 官方 API `https://pub.dev/api/packages/`、`/score`、`/publisher` 即時取得版本與發布日;套件能力讀 GitHub 原始碼(`README`/`pubspec.yaml`/`podspec`/`CMakeLists.txt`/`AndroidManifest.xml`),以**固定 commit SHA 的 permalink** 為準;repo 活躍度取 GitHub repo metadata(`archived`/`pushed_at`/最後 release 日)。context7 對這批 pub 套件幾乎沒有收錄(只有 `jonasbark/flutter_in_app_update`),故以原始碼與官方文件為主。 + - **平台(第 2–7 節)**:官方文件頁(Apple/Google/Microsoft/Inno Setup/Sparkle/AppImage/Flatpak/GitHub Docs)、GitHub Changelog、`gh api`、`gh attestation verify --help`、以及對 `https://github.com/1morr/FMP/releases/...` 的實際 HTTP 標頭觀測(`curl`)。 + - **未執行 App;未呼叫任何音樂平台 API。** +- 標記約定:**事實**=有出處可逐字對上;**推測**=依文件或原始碼推論但未實測;**查不到**=找過沒找到。網頁出處附 URL;GitHub 外部 repo 出處附固定 SHA permalink。 + +--- + +## 1. Flutter/Dart 套件 + +### 1.1 總覽 + +| 套件 | latest | 發布日 | 平台 | 維護狀態 | pub 分數 / likes | +|---|---|---|---|---|---| +| `auto_updater` | 1.0.0 | 2024-10-27 | macOS、Windows(**無 Linux**) | 未 archived,但最後 commit 2025-03-29、最後 release 2024-10 → **趨於停滯** | 130/160 · 218 | +| `desktop_updater` | 3.2.0 | 2026-09-22 | macOS、Windows、Linux | **活躍**(最後 commit 2026-09-22) | 140/160 · 53 | +| `ota_update` | 7.1.0 | 2025-12-03 | **Android only** | **活躍**(最後 commit 2026-02-25) | **160/160** · 335 | +| `open_filex` | 4.7.0 | 2025-03-06 | pub tag 只列 Android/iOS;原始碼另有桌面路徑 | 低度維護(最後 commit 2025-03-06,與 last release 同日) | 140/160 · 435 | +| `install_plugin` | 2.1.0 | 2023-07-11 | Android、iOS | **停滯且高風險**(`compileSdkVersion 28`) | 150/160 · 79 | +| `flutter_install_plugin` | 1.0.0 | 2019-11-19 | Android、iOS | **廢棄**(`sdk: >=2.1.0 <3.0.0`,Dart 3 無法解析) | 30/160 · 0 | +| `install_plugin_plus` | — | — | — | **pub.dev 上不存在** | — | +| `package_info_plus` | 10.2.1 | 2026-07-15 | 全平台(含 web) | **活躍**(fluttercommunity,最後 commit 2026-09-27) | 150/160 · **2805** | +| `upgrader` | 13.7.0 | 2026-08-18 | 全平台宣告;**自動支援僅 Android/iOS** | **活躍**(最後 commit 2026-08-20) | 150/160 · 2489 | +| `pub_semver` | 2.2.1 | 2026-08-28 | 純 Dart(全平台) | **活躍**(Dart 官方 team) | **160/160** · 172 | + +- **事實**:以上沒有一個在 pub.dev 被標記 `discontinued`(以 `/score` 的 tags 與頁面內容確認)。 +- **事實**(FMP 對照):`pubspec.yaml` 已依賴 `package_info_plus: ^9.0.1`、`open_filex: ^4.5.0`;`version: 1.11.0+1011000`;CI 使用 Flutter `3.47.1`,Dart SDK 約束 `>=3.9.0 <4.0.0`。 + +### 1.2 `auto_updater` 1.0.0 + +- 出處:`https://pub.dev/api/packages/auto_updater`;repo `https://github.com/leanflutter/auto_updater`(publisher `leanflutter.dev`)。 +- **事實**:平台 `macos` ✔️、`windows` ✔️、**`linux` 不支援**(README 平台表與 pub tags 一致)。`sdk: >=3.0.0 <4.0.0`、`flutter: >=3.3.0`。 +- **事實**:monorepo 拆為 `packages/auto_updater`(主)、`auto_updater_macos`、`auto_updater_windows`、`auto_updater_platform_interface`。 +- **事實(macOS 底層 Sparkle)**:`macos/auto_updater_macos.podspec` 只寫 `s.dependency 'Sparkle'`(**未鎖版本**);example 的 `Podfile.lock` 實際解析到 **Sparkle 2.5.2**;`s.platform = :osx, '10.11'`。 +- **事實(macOS 簽章)**:需 `dart run auto_updater:generate_keys` 產生金鑰,公鑰 `SUPublicEDKey` 寫進 `macos/Runner/Info.plist`;appcast 每個 `enclosure` 帶 `sparkle:edSignature`;金鑰須在 macOS 與 Windows **各自分開產生**。 +- **事實(macOS sandbox)**:quick-start 的 troubleshooting 要求 entitlements 內 `com.apple.security.app-sandbox = false`,並開 `network.client` / `network.server`。→ **推測**:不能用于 Mac App Store 上架版(Sandbox 是 MAS 必要條件,且 Sparkle 2 官方文件說明其不支援 sandboxed app)。 +- **事實(Windows 底層 WinSparkle)**:`packages/auto_updater_windows/windows/CMakeLists.txt` 綁 prebuilt **WinSparkle 0.8.1**(`set(WIN_SPARKLE_DIR ".../WinSparkle-0.8.1")`、連結 `x64/Release/WinSparkle.lib`、bundled `WinSparkle.dll`)。上游 WinSparkle 已到 **0.9.4(2026-07-21)**,插件內綁的版本明顯偏舊。**推測**:0.8.1 為 2020 年前後版本。 +- **事實(Windows 簽章)**:`generate_keys` 產生 `dsa_priv.pem` / `dsa_pub.pem`,公鑰以 `DSAPub DSAPEM "../../dsa_pub.pem"` 寫進 `windows/runner/Runner.rc`;appcast 帶 `sparkle:dsaSignature`(**DSA,非 EdDSA**);建置機需安裝 `openssl`。 +- **事實(更新來源)**:Feed 為 **Sparkle appcast.xml**(RSS 2.0 + `sparkle:` namespace),同一 appcast 可用 `sparkle:os` 區分 macos / windows 兩個 enclosure。 +- **事實(API)**:`setFeedURL(url)` → `checkForUpdates()` → `setScheduledCheckInterval(sec)`;排程間隔**預設 86400 秒、最小 3600、0 代表停用**。**無內建 UI**:叫起原生 Sparkle / WinSparkle 更新視窗。 + +### 1.3 `desktop_updater` 3.2.0 + +- 出處:`https://pub.dev/api/packages/desktop_updater`;repo `https://github.com/MarlonJD/flutter_desktop_updater`;pub publisher `radlof.com`(作者 MarlonJD)。 +- **事實**:共 **53** 個版本;平台 tags `macos`/`windows`/`linux` 三者齊;`sdk: ^3.6.0`、`flutter: >=3.3.0`;30 天下載 5333、52 stars、1 open issue。 +- **事實(更新流)**:簽章式 schema-v3:`app-archive.json` → `release.json` → `app.zip`(或安裝檔);客戶端抓精確 URL 並驗長度與 SHA-256,不需公開目錄列表。 +- **事實(簽章)**:**Ed25519(EdDSA)公鑰釘選** — `trustedReleasePublicKeys` 為每個 controller 的**必填**;同一份 key map 同時驗 `app-archive.json` 與選中的 `release.json`,且在政策選擇與下載前就驗。 +- **事實(CLI)**:`dart run desktop_updater:release keygen` / `publish` / `doctor`(含 `--platform`、`--initialize-feed`、`--package-id`);有上傳 provider 時會「先傳 versioned 檔 → 驗證 → 最後才傳 `app-archive.json`」。 +- **事實(UI)**:內建 `DesktopUpdateWidget`、`DesktopUpdateDirectCard`、`DesktopUpdateSliver`、`UpdateDialogListener`;也可自訂 UI 讀 `controller.state`。 +- **事實(更新政策)**:政策存在 `app-archive.json` 內(舊 client 不用重編就能改):optional(可略過)、mandatory(持續提示、隱藏略過)、`supportPolicy`(最低支援版本 + 截止日,逾期 fail closed)、`freshInstall`(導向重新下載)。 +- **事實**:`recoveryStore` 為 **3.1 起必填**(app 自有的 pending-install marker 儲存轉接器,需自行複製 repo 的 `JsonFileUpdateRecoveryStore` 到 app 的 support 目錄)。`additionalFiles` 可帶非 Flutter 產物。package ID 必須精確符合平台預設:macOS `macos/Runner/Configs/AppInfo.xcconfig` 的 `PRODUCT_BUNDLE_IDENTIFIER`/Windows `pubspec.yaml` 的 `name`/Linux `linux/CMakeLists.txt` 的 `APPLICATION_ID`。 +- **事實(平台信任建議)**:macOS 建議 Developer ID + hardened runtime + notarize + staple;Windows 建議 Authenticode,可發 direct zip 或 **Inno Setup** 安裝檔。 +- **事實(限制)**:**Linux 為 `preview` / candidate-only,非 production-ready**,且只支援 direct-ZIP;AppImage、deb/APT、rpm/DNF、Flatpak、Snap 明確**不在**本版範圍。跨平台原生 runtime preview 亦標 candidate-only(只有 macOS production path 有獨立驗證證據)。Microsoft Store / MSIX 為**規劃中**的獨立通路,尚未實作。3.x 有多次破壞性變更(1.x→2.0、2.x→3.0、3.0→3.1 三份 migration guide)。 + +### 1.4 `ota_update` 7.1.0 + +- 出處:`https://pub.dev/api/packages/ota_update`;repo `https://github.com/4Q-s-r-o/ota_update`(publisher `4q.eu`)。共 35 版、192 stars、5 open issues。 +- **事實**:平台 tag 只有 `platform:android`。README 明說 iOS「opens safari with specified ipa url **(not yet functioning)**」→ 實質 Android-only。 +- **事實(能力)**:下載 APK 並在 Flutter 端回報下載進度(`OtaEvent`),下載完成後觸發安裝 intent。 +- **事實(7.1.0 新增)**:支援 `PackageInstaller` 方法,需 `usePackageInstaller: true` 才啟用(**預設關閉**)。一般 app 透過插件回報安裝進度、完成後有通知(成功時 OS 可能重啟 app),**沒有系統原生安裝進度 UI**;系統 app(預裝於 `/system/` 或用平台憑證簽章)可**靜默安裝**。 +- **事實(狀態列舉)**:`DOWNLOADING` / `INSTALLING` / `INSTALLATION_DONE`(僅 PackageInstaller)/ `INSTALLATION_ERROR`(僅 PackageInstaller)/ `ALREADY_RUNNING_ERROR` / `PERMISSION_NOT_GRANTED_ERROR` / `DOWNLOAD_ERROR` / `CHECKSUM_ERROR` / `INTERNAL_ERROR` / `CANCELED`。 +- **事實(manifest 需求)**:插件**不會**自動幫 app 加權限;README 要求在 `AndroidManifest.xml` 自加 `WRITE_EXTERNAL_STORAGE` 與 `REQUEST_INSTALL_PACKAGES`。另需 `` 內加 provider `sk.fourq.otaupdate.OtaUpdateFileProvider`(authority `${applicationId}.ota_update_provider`)、receiver `sk.fourq.otaupdate.InstallResultReceiver`(intent-filter action = `${applicationId}.ACTION_INSTALL_COMPLETE`)、以及 `android/src/main/res/xml/filepaths.xml`(``)。 +- **事實**:插件自身 manifest 帶 `INSTALL_PACKAGES`(供系統 app 靜默安裝);對一般 app,Android 會無害忽略,走標準安裝流程。 +- **事實(限制)**:7.0.0+ 需 core library desugaring(`multiDexEnabled true`、`coreLibraryDesugaringEnabled true`、`com.android.tools:desugar_jdk_libs:2.0.3`)。自 4.0.0 起不用 `DownloadManager`,檔案存 app 內部目錄 → **沒有系統下載通知**。支援 `sha256checksum` 參數與 `--split-per-abi`。**不在套件範圍**:更新主機託管、版本檢查邏輯、更新伺服器認證。預設不允許 cleartext HTTP(APK 須走 https 或自加 `network_security_config.xml`)。README 註記 Google Play Protect 有時會干擾安裝。 + +### 1.5 `open_filex` 4.7.0 + +- 出處:`https://pub.dev/api/packages/open_filex`;repo `https://github.com/javaherisaber/open_file`(`open_file` 的 fork,主要為拿掉 `REQUEST_INSTALL_PACKAGES` 與修 Android 13/Gradle 8 問題)。共 22 版、38 stars、8 open issues。 +- **事實(平台實況)**:pub tags 只列 `android`/`ios`,但原始碼支援桌面:`lib/src/platform/open_filex.dart` 對非 iOS/Android 走 `dart:io` — macOS `Process.start('open', [filePath])`、Windows `Process.start('cmd', ['/c', 'start', '', filePath])`、Linux `Process.start("$linuxDesktopName-open", [filePath])`(預設 `xdg-open`)。**無 web 路徑**(README 宣稱的 `web(dart:html)` 與「PC(ffi)」已過時)。 +- **事實(能否開 APK 安裝器)**:可以。副檔名對照 `".apk" → "application/vnd.android.package-archive"`;`OpenFilePlugin.java` 建 `Intent(Intent.ACTION_VIEW)` + `setDataAndType(uri, typeString)`,URI 走它自己的 FileProvider(authority `${applicationId}.fileProvider.com.crazecoder.openfile`)並加 `FLAG_GRANT_READ_URI_PERMISSION`;Android 系統套件安裝器接管該 intent → 跳安裝提示。 +- **事實(關鍵限制)**:`open_filex` **刻意移除**自身的 `REQUEST_INSTALL_PACKAGES`(README「Notice」第一條,理由為符合 Google Play 政策);因此 **app 必須自己宣告**該權限,否則 API 26+ 上安裝 intent 會被擋。它只「發出 intent」,**不能靜默安裝、不會回報安裝結果**。 +- **事實(FileProvider 範圍)**:`android/src/main/res/xml/filepaths.xml` 內含 `external-path`/`external-cache-path`/`external-files-path`/`files-path`/`cache-path`/`root-path`(皆 `path="."`)。若與其他插件的 FileProvider 衝突,需用 `tools:replace="android:authorities"` / `tools:replace="android:resource"` 覆蓋。 + +### 1.6 `install_plugin` 與同類 + +- **事實**:`install_plugin` 2.1.0(2023-07-11,publisher `heyongjian.com`,repo `https://github.com/hui-z/flutter_install_plugin`):未 archived,但最後 commit 2023-10-17、110 stars、14 open issues。API 為 `InstallPlugin.installApk(apkFilePath, appId)`、`installApkSilent(...)`、`gotoAppStore(...)`。它的 Android manifest **直接宣告 `REQUEST_INSTALL_PACKAGES`**(透過 manifest merge 自動加給 app)。`android/build.gradle` 為 `compileSdkVersion 28`、AGP 7.3.0、Kotlin 1.7.10、依賴 `androidx.legacy:legacy-support-v4`。→ **推測**:現代 Flutter(FMP 用 3.47.1,要求 compileSdk 34/35)極可能無法乾淨建置,需自行 fork 修 gradle。**未實跑建置驗證。** +- **事實**:`flutter_install_plugin` 1.0.0(2019-11-19)— `environment.sdk: >=2.1.0 <3.0.0`,**與 Dart 3 不相容**;pub 分數 30/160、0 likes;description 仍是樣板字「A new flutter plugin project.」。 +- **查不到**:`install_plugin_plus` — `https://pub.dev/api/packages/install_plugin_plus` 回 **404 / NoSuchKey**。搜尋命中的最接近者是無關的 `package_installer_plus`(`ScalinoDev`,1.0.0,2024-11-19)。 +- **事實(其他同類,皆低採用度)**:`app_installer` 1.3.1(2024-12-03,`BytesZero/app_installer`,最後 commit 2025-01-24)、`android_package_installer` 0.0.3(2025-05-04)、`flutter_app_installer` 2.0.0(2026-03-19)、`package_installer_plus` 1.0.0(2024-11-19)、`r_upgrade` 0.4.2(2023-03-10,停滯)。 + +### 1.7 `package_info_plus` 10.2.1 + +- 出處:`https://pub.dev/api/packages/package_info_plus`;repo `https://github.com/fluttercommunity/plus_plugins`(monorepo,publisher `fluttercommunity.dev`)。共 62 版;monorepo 最後 commit 2026-09-27。 +- **事實**:平台 `android`/`ios`/`windows`/`linux`/`macos`/`web` 全列。`sdk: >=3.10.0 <4.0.0`、**`flutter: >=3.38.1`** → 與 FMP 的 Flutter 3.47.1 相容;但 FMP 目前 pin 在 `^9.0.1`,升到 10.x 是 **major bump**。 +- **事實(欄位)**:`PackageInfo.fromPlatform()` 回傳 `appName`、`packageName`、`version`(pubspec `version:` 的 `+` 之前)、`buildNumber`(`+` 之後)、`buildSignature`(Android 簽章金鑰 SHA-256 hex,其他平台空字串)、`installerStore`(**透過哪個商店安裝**,Android)、`installTime` / `updateTime`(非全平台)。 +- **事實(對 FMP 的實值)**:`1.11.0+1011000` → `version == '1.11.0'`、`buildNumber == '1011000'`。 + +### 1.8 `upgrader` 13.7.0 + +- 出處:`https://pub.dev/api/packages/upgrader`;repo `https://github.com/larryaasen/upgrader`(publisher `larryaasen.com`)。共 158 版;640 stars、76 open issues。 +- **事實(支援矩陣,README 平台表)**:ANDROID 自動 ✅ / appcast ✅;IOS 自動 ✅ / appcast ✅;FUCHSIA/LINUX/MACOS/WEB/WINDOWS 自動 ❌ / appcast ✅。 +- **事實**:Android 自動支援 = **抓取公開 Google Play 頁面**(README 明說**不使用**原生 Android In-App Updates API,也不用 Huawei AppGallery API);iOS 自動支援 = App Store lookup。`UpgraderStoreController` 可逐平台換來源(`onAndroid` 預設 `UpgraderPlayStore()`、`oniOS` 預設 `UpgraderAppStore()`、其餘預設 `null`)。 +- **事實(最小版本強制)**:在商店描述欄位塞魔法字串 — Android `[Minimum supported app version: 1.2.3]`、iOS `[:mav: 1.2.3]`;生效後自動隱藏 Ignore / Later 按鈕。 +- **事實(GitHub 可達性)**:**沒有內建 GitHub 來源**。`UpgraderAppcastStore(appcastURL: ..., osVersion: Version(0, 0, 0))` 允許把 appcast URL 指向任何位置(含 GitHub raw URL 或放在 GitHub Releases 的 XML,XML 由自己產生);也可 subclass `UpgraderStore` 自訂來源。**`upgrader` 只負責「比對 + 提示」**:`UPDATE NOW` 只是把使用者導去 App Store / Google Play 頁面,**不下載、不驗簽、不安裝**。 +- **事實(桌面侷限)**:`onWindows` / `onLinux` / `onMacOS` 預設皆 `null`,不給 appcast 就什麼都不做;即使給了 appcast,桌面也只能提示 + 開連結。iOS 非 US 商店須自帶 `countryCode`。 +- **推測**:README 只示範用一個測試用 raw GitHub URL 的 `UpgraderAppcastStore`;「能否穩定吃 GitHub Releases」是依「URL 可自訂」推論,未找到官方文件或範例正式宣告支援。 + +### 1.9 `pub_semver` 2.2.1 + +- 出處:`https://pub.dev/api/packages/pub_semver`;repo `https://github.com/dart-lang/tools/tree/main/pkgs/pub_semver`(publisher `tools.dart.dev`,屬 `dart-lang` 官方組織)。共 30 版;`dart-lang/tools` 最後 commit 2026-09-24。純 Dart,`sdk: ^3.4.0`。 +- **事實(與 vanilla semver 不同,重點)**:`Version.parse('1.2.3+4')` → `major=1`、`minor=2`、`patch=3`、`build=['4']`、`preRelease=[]`。`operator ==`(`lib/src/version.dart`,SHA `d87eaf79…`,第 172-178 行)**把 `build` 一起比**:`Version.parse('1.2.3+4') == Version.parse('1.2.3')` → **`false`**。`compareTo`(第 309-329 行)**也把 build 納入排序**,原始碼註解「Builds always come after no build string」:`1.2.3+4 > 1.2.3`、`1.2.3+1 < 1.2.3+2`。`Version.allows(other)` = `this == other`,同樣 build-sensitive。README 明文承認:「**Version ordering does take build suffixes into account.** This is unlike semver 2.0.0 but like earlier versions of semver.」 +- **事實**:`Version.parse` 對格式錯誤會 **throw**,不回 null。其他 API:`canonicalizedVersion`、`isPreRelease`、`nextBreaking`(pre-1.0 用 minor)、`nextMajor` / `nextMinor` / `nextPatch`、靜態 `Version.prioritize(a, b)`。 + +--- + +## 2. Android + +### 2.1 權限與安裝 API + +- **事實(Play 政策原文)**:「Apps targeting API level 26 or newer must hold this permission in order to use `Intent.ACTION_INSTALL_PACKAGE` or the `PackageInstaller` API.」以及「The `REQUEST_INSTALL_PACKAGES` permission **may not be used to perform self updates**, modifications, or the bundling of other APKs in the asset file unless for device management purposes. All updates or installing of packages must abide by Google Play's Device and Network Abuse policy and must be initiated and driven by the user.」出處:`https://support.google.com/googleplay/android-developer/answer/12085295?hl=en`(Use of the REQUEST_INSTALL_PACKAGES permission)。 +- **事實(許可的 core functionality 清單)**:Web browsing or search/Communication services that support attachments/File sharing, transfer or management/Enterprise device management/Backup and restore/Device migration or phone transfer。另「To use this permission, your app's core functionality must include: Sending or receiving app packages, AND Enabling user-initiated installation of app packages.」出處同上(另轉述見 `https://orangeoma.zendesk.com/hc/en-us/articles/5872194238492-Google-Play-policy-on-Request-Install-Packages-permission`)。→ **事實**:音樂播放器不在許可清單內;**推測**:若上 Google Play,這條是硬阻擋;若僅以 GitHub Releases 側載散布則不受此政策約束。 +- **事實(宣告義務)**:自 2022-09-29 起,manifest 含 `REQUEST_INSTALL_PACKAGES` 的 app 必須完成 new sensitive permission declaration,否則無法提交更新審查(須聲明許可功能、描述用到該權限的 core feature、並提供展示影片)。出處同上。 +- **事實**:`Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES` — **Added in API level 26**;常數值 `"android.settings.MANAGE_UNKNOWN_APP_SOURCES"`;「Activity Action: Show settings to allow configuration of trusted external sources」;Intent 的 data URI 可指定 `package:com.my.app` 直接跳到該 app 的設定頁。出處:`https://developer.android.com/reference/android/provider/Settings`。 +- **事實**:`PackageManager.canRequestPackageInstalls()` 存在(文件有該方法的條目,Added in API level 26)。出處:`https://developer.android.com/reference/android/content/pm/PackageManager`。 +- **事實**:`PackageInstaller` 以 session 為單位安裝;文件對多個 API 標注「Requires `Manifest.permission.INSTALL_PACKAGES` or `Manifest.permission.REQUEST_INSTALL_PACKAGES`」。出處:`https://developer.android.com/reference/android/content/pm/PackageInstaller`。 +- **事實**:`Manifest.permission.INSTALL_PACKAGES` 的常數值為 `"android.permission.INSTALL_PACKAGES"`。相鄰的 `INSTALL_PACKAGES_AS_REGISTERED_APP_STORE` 標示 `Protection level: role`。出處:`https://developer.android.com/reference/android/Manifest.permission`。**未逐字取得**:`INSTALL_PACKAGES` 本身的 protection level 那一行在抓取時被截斷 → **推測**:其為 `signature|privileged`(第三方 app 無法取得),依據是 `ota_update` README 的敘述(系統 app 才能靜默安裝)與一般 Android 權限設計,**未從官方頁面逐字確認**。 + +### 2.2 安裝的最低 targetSdk + +- **事實**:Android 官方「Behavior changes: all apps」原文 —「**Starting with Android 14, apps with a `targetSdkVersion` lower than 23 can't be installed.** Requiring apps to meet these minimum target API level requirements improves security and privacy for users.」安裝失敗時 Logcat 訊息為 `INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7`。裝置升級到 Android 14 時,既有 targetSdk < 23 的 app 會保留安裝。測試可用 `adb install --bypass-low-target-sdk-block FILENAME.apk`。出處:`https://developer.android.com/about/versions/14/behavior-changes-all`。 + +### 2.3 Android developer verification(側載相關) + +- **事實(官方時間表)**: + - 2026-08:Developer APIs、limited distribution accounts、power user advanced flow 上線(全球)。 + - **2026-09-30**:巴西、印尼、新加坡、泰國的**參與商店**(Google Play、HONOR App Market、OPPO App Market、Galaxy Store、Palm Store、V-Appstore、GetApps)之 app 註冊成為必需;「Unregistered apps can be sideloaded with Android Debug Bridge (adb) or advanced flow.」 + - 2027 起:擴展到**所有** certified 裝置上的所有 app。 + 出處:`https://developer.android.com/developer-verification`、`https://android-developers.googleblog.com/2026/06/android-developer-verification.html`、`https://support.google.com/android-developer-console/answer/16561738?hl=en`。 +- **事實**:所稱「certified device」= 出廠搭載 GMS 的裝置;未搭載 GMS 的裝置與 custom ROM 不受影響(轉述自 `https://forum.f-droid.org/t/google-will-require-developer-verification-to-install-android-apps-including-sideloading/33123` 對官方公告的引用)。 +- **事實(2026-09-30 的實際範圍)**:直接側載(adb、advanced flow)**未**被切斷;被切的只是「參與商店的安裝來源」要對應已驗證開發者。出處:官方 blog 同上。 + +--- + +## 3. Windows + +### 3.1 Inno Setup(安裝程式) + +- **事實(命令列,逐字)**:`/SILENT`「Instructs Setup to be silent or very silent.」— silent 模式「the wizard and the background window are not displayed but the installation progress window is」;very silent(`/VERYSILENT`)連進度視窗也不顯示。`/DIR="x:\dirname"`「overrides the default directory name displayed on the Select Destination Location wizard page. A fully qualified pathname must be specified.」。`/CLOSEAPPLICATIONS`「Instructs Setup to close applications using files that need to be updated by Setup if possible.」。`/RESTARTAPPLICATIONS`。「`/LOG`」在 TEMP 建立 log;`/LOG="filename"` 同義但固定路徑(覆寫既有檔)。`/NORESTART`「Prevents Setup from restarting the system following a successful installation」。`/SUPPRESSMSGBOXES`「Instructs Setup to suppress message boxes. Only has an effect when combined with /SILENT or /VERYSILENT.」。`/RESTARTEXITCODE=exit code`「Specifies the custom exit code that Setup is to return when a restart is needed.」出處:`https://jrsoftware.org/ishelp/topic_setupcmdline.htm`。 +- **事實(exit codes,逐字)**:0 = Setup 成功跑完(或用了 /HELP / /?);1 = 初始化失敗;2 = 使用者在安裝開始前取消,或拒絕開頭的「This will install...」提示;3 = 進入下一階段時致命錯誤(如記憶體不足);4 = 實際安裝過程中致命錯誤(Abort-Retry-Ignore 的錯誤不算致命;選 Abort 回 5);5 = 安裝中使用者取消或在 Abort-Retry-Ignore 選 Abort;6 = 被除錯器強制終止;7 = 「Setup cannot proceed with installation」(在 Preparing to Install 階段判定);**8 = 同 7,但「the system needs to be restarted in order to correct the problem」**。回傳 1/3/4/7/8 前通常會顯示錯誤訊息;「Any non-zero exit code indicates that Setup was not run to completion.」;文件提醒未來版本可能新增代碼。出處:`https://jrsoftware.org/ishelp/topic_setupexitcodes.htm`。 + +### 3.2 SmartScreen 與程式碼簽章 + +- **事實**:SmartScreen 是**基於信譽**(reputation)的雲端判斷層,**不是簽章有效性檢查**;簽章鏈完全有效也可能跳「Microsoft Defender SmartScreen prevented an unrecognized app from starting」。未簽章的檔案必須**每個新版本各自從零建立信譽**。出處:`https://knowledge.digicert.com/alerts/ev-signed-application-showing-microsoft-defender-smartscreen-warnings`、`https://www.cimco.com/support/guides/microsoft-defender-smartscreen-warning`。 +- **事實**:EV 憑證自 2024 年起**不再**提供即時 SmartScreen 信譽(Microsoft 更新 Trusted Root Program 要求時移除);新發行的 EV 簽章 app 與 OV 一樣需自然累積信譽。出處:`https://www.todesktop.com/blog/posts/windows-apps-psa-ev-certs-do-not-grant-immediate-reputation-anymore`。 +- **事實**:受管理環境可把 SmartScreen 設為 Block 模式,此時連「Run anyway」都沒有。出處:`https://github.com/pnp/Microsoft365-Analytics-Insights/issues/175`。 +- **事實(Azure Artifact Signing,原名 Azure Trusted Signing)**: + - 官方介紹頁現行 canonical 路徑為 `/azure/artifact-signing/overview`(原 `/azure/trusted-signing/overview`)。服務為 fully managed,憑證生命週期在 **FIPS 140-3 Level 3** 認證的 HSM 內管理;account 有 **Basic SKU** 與 **Premium SKU** 兩種。出處:`https://learn.microsoft.com/en-us/azure/artifact-signing/overview`。 + - **不支援 free / trial / sponsored Azure subscription**,必須是付費訂閱(pay-as-you-go 或 enterprise agreement)。出處:`https://learn.microsoft.com/en-us/azure/artifact-signing/faq`。 + - **不發 EV 憑證**,且「There's no plan to issue EV certificates in the future.」。出處同上。 + - 簽章配額:**Basic 5,000 signatures/月**(含 public/private signing 與「1 of each Certificate Profile type」);**Premium 100,000 signatures/月**(「10 of each Certificate Profile type」)。計費自建立 account 起算,**不按比例**。出處:`https://azure.microsoft.com/en-us/pricing/details/artifact-signing/`、FAQ 同上。**查不到**:實際月費金額 — 定價頁的 Basic / Premium 月費與超量單價皆顯示佔位符 `$-`(動態載入未渲染),官方 FAQ 只指向定價頁與 sales quote,未給數字。 + - **事實**:有 **Individual identity validation** 流程(FAQ 多處以 Individual 為題,需政府核發且帶地址的身分證件、Microsoft Authenticator + Verified ID、AU10TIX 驗證),即個人開發者可走 Public Trust;亦有 Organization identity validation。出處同上。 + - **事實**:SmartScreen 提示與簽章無關 —「SmartScreen reputation builds up automatically. The prompt stops appearing once the file hash has sufficient download history.」。出處同上。 +- **事實(SignPath Foundation)**:為 open source 專案提供免費程式碼簽章 —「For OSS projects, our services are free of charge.」;「we verify that the binary was built from your open source repository」;私鑰產生/保存在 HSM。出處:`https://signpath.org/`。**查不到**:具體資格條件與簽章憑證類型的明文(頁面只說 OSS 與需申請,細節在 Apply/Terms)。 + +--- + +## 4. macOS + +- **事實(Sparkle 2)**:簽章演算法為 **EdDSA(ed25519)**,對發布的更新封存檔(dmg/zip 等)、delta 更新與 installer package 簽章。`SUPublicEDKey` 是 `Info.plist` 中放公鑰的鍵;`generate_keys` 印出 base64 公鑰字串供貼入 plist。`generate_appcast` 掃描一包更新封存檔並產生 appcast(含簽章與 delta),金鑰自 Keychain 取得。建議以 HTTPS 提供更新並符合 App Transport Security;以 Developer ID 簽章並公證;簽章金鑰不要放在網頁伺服器。`SURequireSignedFeed`(Sparkle 2.9 起驗證)需搭配 `SUVerifyUpdateBeforeExtraction`。出處:`https://sparkle-project.org/documentation/`。**未逐字取得**:appcast 中簽章屬性的確切名稱(如 `sparkle:edSignature`)與 Sparkle 2 的最低 macOS 版本 — 該頁未寫;`auto_updater` 子代理讀其原始碼確認 appcast 用 `sparkle:edSignature`。 +- **事實(Gatekeeper 與 Sequoia 變更)**:Apple 開發者公告 —「In macOS Sequoia, users will no longer be able to Control-click to override Gatekeeper when opening software that isn't signed correctly or notarized. They'll need to visit System Settings > Privacy & Security to review security information for software before allowing it to run.」同時建議「If you distribute software outside of the Mac App Store, we recommend that you submit your software to be notarized.」出處:`https://developer.apple.com/news?id=saqachfa`(2024-08-06)。 +- **事實**:未簽章/未公證的軟體在現行 macOS 上「refuse to run」;Sequoia 的替代路徑是:先嘗試啟動並關掉對話框 → 開 System Settings → Privacy & Security → Security → 按該 app 的 **Open Anyway**(會再問一次並要求管理員密碼)。出處:`https://arstechnica.com/gadgets/2024/08/macos-15-sequoia-makes-you-jump-through-more-hoops-to-disable-gatekeeper-app-checks`、`https://mjtsai.com/blog/2024/07/05/sequoia-removes-gatekeeper-contextual-menu-override`。 +- **事實**:Apple Developer Program 年費 **$99**,可讓簽章憑證有效期從 7 天變 1 年、解除 3-app 上限。出處:`https://docs.sidestore.io/docs/faq`(原文「you can pay for a $99/year Apple Developer account」)。**推測**:公證(notarization)需 Developer ID 因而需付費會員資格 — 由 Apple 開發者公告「submit your software to be notarized」+ Developer ID 計畫需會員推得,**未取得 Apple 官方定價頁逐字**。 +- **事實(不能與 MAS 並存的一條)**:Mac App Store 的 Guideline 2.4.5 明文:「(vii) They must use the Mac App Store to distribute updates; other update mechanisms are not allowed.」「(iv) They may not download or install standalone apps, kexts, additional code, or resources to add functionality or significantly change the app from what we see during the review process.」「(ii) ... no third-party installers allowed.」出處:`https://developer.apple.com/app-store/review/guidelines/`。 + +--- + +## 5. Linux + +- **事實(AppImage 更新資訊)**:update information 直接內嵌在 AppImage 內(存在 ISO 9660 Volume Descriptor #1 的 "Application Used" 欄位),可不必重打包整個 AppImage 就更改;由 `appimagetool -u` 內嵌並同時產生對應 `.zsync` 檔,或經 linuxdeploy 的 `$UPDATE_INFORMATION` / `$UPD_INFO`。出處:`https://docs.appimage.org/packaging-guide/optional/updates.html`、`https://github.com/AppImageCommunity/AppImageUpdate`。 +- **事實(型別與語法,逐字取自 AppImageSpec draft)**:一個 AppImage 只能內嵌**恰好一種** transport 的 update info。型別:`zsync` 語法 `"zsync|https://server.domain/path/Application-latest-x86_64.AppImage.zsync"`;`gh-releases-zsync` 語法 `"gh-releases-zsync|probono|AppImages|latest|Subsurface-*x86_64.AppImage.zsync"`;`pling-v1-zsync` 語法 `"pling-v1-zsync|1623134|*-stable-x86_64.AppImage"`;`bintray-zsync`「It is deprecated.」。`gh-releases-zsync` 五個以 `|` 分隔的欄位依序為:型別字串、GitHub 使用者/組織、repo、release tag(特殊值 `latest` / `latest-pre` / `latest-all`;文件註明「pre-releases are not being considered when using `latest`」)、zsync 檔名(可用 `*` 萬用字元)。出處:`https://github.com/AppImage/AppImageSpec/blob/master/draft.md`(draft.md#update-information)。 +- **事實(消費端工具)**:`AppImageUpdate`(GUI)、`appimageupdatetool`(CLI)、`validate`(檢查內嵌簽章完整性);以 zsync 做 delta 更新,「Only the parts that have changed since the original version are downloaded」。可作為 CMake submodule 嵌入第三方 app 並連結 `libappimageupdate`。MIT 授權(樣本 GUI 部分基於 FLTK)。出處:`https://github.com/AppImageCommunity/AppImageUpdate`。 +- **事實(AppImage 更新的副作用)**:以 zsync 更新時舊檔保留為 `.zs-old` 備份,且是在原檔旁產生新檔而非就地修改。用 `electron-builder` 建的 AppImage 使用它自己的更新機制,「cannot be updated using the usual tools」除非用 `appimagetool -u` 重新打包。出處:`https://docs.appimage.org/packaging-guide/optional/updates.html`。 +- **事實(Flatpak 唯讀)**:sandboxed app「No access to any host files except the runtime, the app,」and its per-app data dirs,「Only the latter two being writable.」→ runtime 與 app 自身檔案(`/app`)在沙箱內是**唯讀**;預設可寫的只有 `~/.var/app/$FLATPAK_ID` 與 `$XDG_RUNTIME_DIR/app/$FLATPAK_ID`;`/app` 是保留路徑,用 `--filesystem` 要求寫入「will have no effect」。出處:`https://docs.flatpak.org/en/latest/sandbox-permissions.html`。 +- **推測**:Flatpak 的更新由系統端執行(`flatpak update` / 軟體中心 / systemd timer),app 自身無法就地替換自己 — 依據是上條唯讀事實加上 `https://discussion.fedoraproject.org/t/flatpak-automatic-updates-where-how/106418` 描述的自動更新由系統 timer 驅動。**未取得 Flatpak 官方文件明文**。 +- **查不到**:deb / rpm 的應用內自更新可行性 — 未找到發行版或 Debian/Fedora 官方文件明文說明 app 可否自行替換 `dpkg` / `rpm` 管理的檔案。**推測**:由套件管理器管理、app 不應自行覆寫(依據:套件管理器持有檔案清單與校驗)。**無逐字出處。** + +--- + +## 6. iOS + +- **事實(App Review Guidelines 逐字)**: + - **2.5.2**:「Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they **download, install, or execute code which introduces or changes features or functionality of the app, including other apps**. Educational apps designed to teach, develop, or allow students to test executable code may, in limited circumstances, download code provided that such code is not used for other purposes. Such apps must make the source code provided by the app completely viewable and editable by the user.」 + - **2.4.5 (ii)**(Mac App Store):「They must be packaged and submitted using technologies provided in Xcode; no third-party installers allowed. They must also be self-contained, single app installation bundles and cannot install code or resources in shared locations.」 + - **2.4.5 (iv)**:「They may not download or install standalone apps, kexts, additional code, or resources to add functionality or significantly change the app from what we see during the review process.」 + - **2.4.5 (vii)**:「They must use the Mac App Store to distribute updates; other update mechanisms are not allowed.」 + 出處:`https://developer.apple.com/app-store/review/guidelines/`。 +- **事實(側載的技術限制)**: + - 免費 Apple Account(personal team)簽出的 provisioning profile **7 天後到期**;一次最多 **3 個 app**;滾動一週內最多註冊約 **10 個 App ID**。付費 **$99/年** Apple Developer Program 後憑證改為最長 1 年、3-app 上限消失,但仍是 365 天到期。出處:`https://docs.sidestore.io/docs/faq`(原文「If using a free Apple Account, SideStore can only install 3 apps (including itself) at a time. Additionally, only 10 different apps may be installed in a week.」及「To remove this restriction (and also get a 365 day expiry), you can pay for a $99/year Apple Developer account.」)、`https://builds.io/blog/technologies/ios-technologies/stop-refreshing-sideloaded-apps-7-days`。 + - **事實**:SideStore 是 AltStore 的 fork,靠裝置上的 VPN 讓 iOS 接受安裝,並在背景週期性 refresh 以延長 7 天效期;「You only need a computer once during installation.」。出處:`https://docs.sidestore.io/docs/faq`、`https://github.com/SideStore/SideStore`。 +- **查不到**:TestFlight 每個 beta build **90 天**到期的**官方**出處 — 只找到二手頁面(`https://www.facebook.com/fb-answers/apple-testflight-beta-builds-expire-90-days-official`),**未取得 Apple 官方文件逐字**。**推測**:90 天限制存在,數字未經官方來源確認。 +- **推測**:Flutter app 在 iOS 上無法自我更新 — 依據為 Guideline 2.5.2 禁止下載/安裝/執行會改變功能的程式碼,加上 iOS 不允許 app 就地替換自己的 bundle。**未逐字取得「Flutter 不能」這種針對 Flutter 的官方敘述。** + +--- + +## 7. GitHub Releases API 與供應鏈 + +### 7.1 速率限制 + +- **事實(逐字)**:未認證請求 —「60 requests per hour」,綁來源 IP。帶 PAT / OAuth 的認證請求為「personal rate limit of 5,000 requests per hour」(GitHub Enterprise Cloud 組織擁有的 app 代你操作時可到 15,000)。超限回「403 or 429 response」,且「the `x-ratelimit-remaining` header will be `0`」;不應在 `x-ratelimit-reset` 之前重試(secondary limit 看 `retry-after`);文件警告「Continuing to make requests while you are rate limited may result in the banning of your integration.」。出處:`https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api`。 + +### 7.2 `releases/latest` 與 asset 物件 + +- **事實**:`GET /repos/{owner}/{repo}/releases/latest` 回傳的 latest release 定義為「the most recent non-prerelease, non-draft release, sorted by the `created_at` attribute」→ **不含 pre-release、不含 draft**。出處:`https://docs.github.com/en/rest/releases/releases`。 +- **事實(asset 欄位)**:`assets[]` 含 `url`、`browser_download_url`(required;「The direct URL to download the asset in a browser」)、`id`、`node_id`、`name`、`label`、`state`(`uploaded` / `open`)、`content_type`、`size`、**`digest`(string or null)**、`download_count`、`created_at`、`updated_at`、`uploader`。API 文件本身**未**指定 `digest` 的雜湊演算法或格式。出處同上。 +- **事實**:GitHub Changelog(2025-06-03)—「GitHub now automatically computes and displays **SHA256 checksums (digests)** for all uploaded release assets. These digests are generated at upload time, **immutable**, and let you verify that downloaded assets haven't been altered since publishing.」可在 Releases UI、Releases REST API、GraphQL API、`gh` CLI 取得。出處:`https://github.blog/changelog/2025-06-03-releases-now-expose-digests-for-release-assets`、GA 公告 `https://github.com/github/roadmap/issues/1136`。 +- **事實(社群反證)**:功能上線前的既有 asset `digest` 為 `null`(例:`aquaproj/aqua` v2.51.2 於 2025-05-11 發布,asset `digest: null`)。另有社群回報**移除 asset 後以同名重新上傳,digest 會改變**,因此質疑 changelog 的「immutable」說法。出處:`https://github.com/orgs/community/discussions/161656`。另一討論指出 source-code 的 zip/tar asset 沒有 SHA256。出處:`https://github.com/orgs/community/discussions/23512`。 +- **事實(FMP 自身,2026-09-28 以 `gh api repos/1morr/FMP/releases/latest` 實測)**:v1.11.0 共 11 個 asset,**每一個都帶 `digest`**,格式 `sha256:<64 hex>`。含 `fmp-latest-android-arm64-v8a.apk`、`fmp-latest-android-universal.apk`、`fmp-latest-windows-installer.exe`、`fmp-latest-windows.zip` 這組 `-latest-` 別名,以及 `fmp-v1.11.0-android-{arm64-v8a,armeabi-v7a,x86_64,universal}.apk`、`fmp-v1.11.0-windows-installer.exe`、`fmp-v1.11.0-windows.zip`、`fmp-v1.11.0-checksums.sha256`。同名的 `-latest-` 與 `-v1.11.0-` asset **digest 相同**(例:`fmp-latest-windows.zip` 與 `fmp-v1.11.0-windows.zip` 皆 `sha256:926f4bae122da377629826be3e2a2efa6fd1db9371524217d6dd77ca2f6c2923`)。`content_type` 分別為 `application/vnd.android.package-archive`、`application/x-msdos-program`、`application/zip`、`application/octet-stream`。 + +### 7.3 asset 下載的重導向(本次實測) + +- **事實**:`https://github.com/1morr/FMP/releases/latest/download/` 回 **302** → `https://github.com/1morr/FMP/releases/download/v1.11.0/`(第二個 302)→ `https://release-assets.githubusercontent.com/github-production-release-asset/<...>?...`(簽章查詢參數,含 `se=` 到期時間與 `ske=` key 到期時間)→ 最終 **200**,回應來自 `Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0`,`x-ms-blob-type: BlockBlob`、`x-ms-server-encrypted: true`。`browser_download_url` 因此**不是**最終 URL。實測(2026-09-28 09:28 UTC)取得的簽章 `se=2026-09-28T10:18:47Z`,約 50 分鐘有效。出處:本次 `curl -L -o /dev/null -D -` 對 `fmp-v1.11.0-windows.zip` 的實測。 +- **事實(最終回應標頭)**:`Content-Length: 25652422`、`Accept-Ranges: bytes`、`ETag: "0x8DF1A78B41500DB"`、`Last-Modified: Thu, 24 Sep 2026 20:16:22 GMT`、`Content-Disposition: attachment; filename=fmp-v1.11.0-windows.zip`、`Content-Type: application/octet-stream`、`x-ms-lease-status: unlocked`。→ **事實**:最終端點支援 Range 請求(可續傳/分塊下載)。出處同上。 + +### 7.4 構件證明(attestation) + +- **事實**:`actions/attest-build-provenance` 為 workflow artifact 產生簽章的 SLSA build provenance 證明(in-toto 格式),以短效 Sigstore 憑證簽章(公開 repo 用公開 Sigstore instance,private/internal 用 GitHub 私有 instance),簽好的證明上傳到 GH attestations API,可用 `gh attestation` 驗證。**「As of version 4, `actions/attest-build-provenance` is simply a wrapper on top of `actions/attest`」**。出處:`https://github.com/actions/attest-build-provenance`。**未逐字取得**:該頁所示的 workflow permissions 片段(`id-token: write` / `attestations: write`)— README 只指向 `actions/attest` repo,**未取得可逐字引用的 YAML**。 +- **事實(本地 CLI 實測)**:`gh version 2.97.0 (2026-07-31)`;`gh attestation verify --help` 顯示需 `--owner` 或 `--repo` 之一,會驗證 signer 身分(`SourceRepository`、`SourceRepositoryOwner`、`SubjectAlternativeName`),預設 predicate type 為 `https://slsa.dev/provenance/v1`。出處:本次 `gh --version`、`gh attestation verify --help`。 + +--- + +## 8. 交叉觀察(僅陳列已查得事實,不含設計建議) + +1. **桌面三平台沒有一個成熟單一套件全包**:`auto_updater` 缺 Linux 且趨於停滯、macOS 需關 sandbox、Windows 綁 WinSparkle 0.8.1;`desktop_updater` 三平台齊、活躍、有簽章與 CLI,但 Linux 仍 candidate-only 且 3.x 破壞性變更頻繁。 +2. **Android 自更新**:`ota_update` 分數與採用度最好(160/160、335 likes),但需自行處理 4 個 manifest 節點 + desugaring;Play 政策明文禁止把 `REQUEST_INSTALL_PACKAGES` 用於 self updates。 +3. **`package_info_plus` 是唯一無替代品的必需品**(FMP 已在用,9.x → 10.x 為 major bump),且其 `installerStore` 可回報安裝來源。 +4. **`upgrader` 無法承擔桌面更新**,只做「比對 + 提示」;下載與安裝要另找套件。 +5. **`pub_semver` 的 build 排序語意與 FMP 的 `1.11.0+1011000` 版號習慣一致**(build 參與 `==` 與 `compareTo`)。 +6. **GitHub 已原生提供 asset `digest`**(2025-06-03 起,FMP 全部 asset 都有),但官方 API 文件未載明演算法;另有社群對「同名重傳會改變 digest」與「舊 asset 為 null」的反證。 +7. **驗證鏈選項並存**:Sparkle 2 用 EdDSA;`desktop_updater` 用 Ed25519 公鑰釘選;GitHub 有原生 digest + Sigstore build provenance(`gh attestation verify`);Windows 另有 Authenticode(Artifact Signing 為 managed、FIPS 140-3 L3、不發 EV)與 SignPath Foundation(OSS 免費)。 + +## 9. 我認為最不確定的 3 個事實 + +1. **`Manifest.permission.INSTALL_PACKAGES` 的 protection level 是否為 `signature|privileged`** — `https://developer.android.com/reference/android/Manifest.permission` 抓取時在該行被截斷;「第三方 app 無法取得、只有系統 app 能靜默安裝」是**推測**(依據 `ota_update` README 敘述與 `PackageInstaller` 頁面「Requires INSTALL_PACKAGES or REQUEST_INSTALL_PACKAGES」的並列寫法)。 +2. **GitHub asset `digest` 的「不可變」性質** — 官方 changelog 說 generated at upload time / immutable,但社群 discussion #161656 以實測指出「移除後同名重傳 digest 會變」,且舊 asset 為 `null`;兩者矛盾,我未自行重現。 +3. **iOS/macOS 的兩個數字** — TestFlight beta build **90 天**到期只找到二手頁面(無 Apple 官方出處);Apple Developer Program 的 **$99/年**取自 SideStore 文件與第三方 blog,**未取得 Apple 官方定價頁逐字**。另外 Sparkle 2 的最低 macOS 版本與 `sparkle:edSignature` 屬性名**未從 Sparkle 官網逐字取得**(後者由 `auto_updater` 原始碼側面確認)。 diff --git a/.trellis/tasks/09-28-design-release-update/research/prior-art.md b/.trellis/tasks/09-28-design-release-update/research/prior-art.md new file mode 100644 index 000000000..e36b296f1 --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/research/prior-art.md @@ -0,0 +1,658 @@ +# Prior Art:成熟產品的發版與應用內更新 + +- 查證日:2026-09-28 +- 查證方式: + - 別人的公開 repo 一律用 `gh api` 讀取(`repos///contents/?ref=`、`.../releases`、`.../git/trees/?recursive=1`),以 `gh api repos///commits/ --jq .sha` 取得**查證日當下的 commit SHA**;**下文所有 GitHub permalink 全部釘在固定 40 碼 SHA**,不用 `main`/`master`/`dev` 這種會漂移的 ref。 + - 少數 repo 的完整檔案改用 `codeload.github.com` 抓 tarball 後在本機 `tar` + `grep -rn`(因為 `gh search code` 對所有查詢都回 0 筆,靜默失敗;故此批研究不依賴 GitHub code search)。 + - 官方文檔(release-please/git-cliff/semantic-release/Conventional Commits)以官網與 repo 內 markdown 為準。 + - 版本號、star 數、license 以 `gh api repos//` 與 npm registry API 為準,不憑記憶。 + - 實測外部服務:`https://newpipe.net/api/data.json` 於查證日抓取一次(唯讀 GET)。 + - **本次抽驗**:NewPipe manifest、Obtainium `settings_provider.dart` 預設值、release-please `dart` 策略三項由我重新以 `gh api` 逐字核對,結果與來源一致。 + - 條件:**唯讀**,未改動任何 repo、未 commit、未開 issue/PR、**未執行任何 App**、**未呼叫任何音樂平台 API**。文件中不含任何 token/key 實際值。 +- 標記約定:**事實**=有出處可逐字對上;**推測**=依原始碼或文檔推論但未實測;**查不到**=找過沒找到。**僅列事實與對照,不含設計建議。** + +## 引用 SHA 對照表 + +| 專案 | repo | 引用 SHA | 分支 | License | +|---|---|---|---|---| +| LocalSend | `localsend/localsend` | `6f6cd3ee496903e2206c51ffa3a13a5d10bc340b` | — | — | +| AppFlowy | `AppFlowy-IO/AppFlowy` | `5cf3a365dec0d59f64bad1ee4bb1050471a39b93` | — | — | +| AppFlowy(建置/appcast) | `AppFlowy-IO/AppFlowy-Builder` | `1a913f70f893cde6b5fbab1738731a7431488bb3` | — | — | +| Spotube | `KRTirtho/spotube` | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | — | — | +| Hiddify | `hiddify/hiddify-app` | `276a7effb0046a039220a745022563740968c0b8` | — | — | +| Finamp | `jmshrv/finamp` | `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc` | — | — | +| Harmonoid | `alexmercerind/harmonoid` | `2b021f7b0b5dbcbe027aec010580977a2939a28d` | — | — | +| Namida | `namidaco/namida` | `acb1e1622600440cc793f389f497e6771c732c5e` | — | — | +| NewPipe | `TeamNewPipe/NewPipe` | `7e5df38aad4b2c035332b3f71aee3064d4fdaae4` | dev | GPL-3.0 | +| LX Music Desktop | `lyswhut/lx-music-desktop` | `ad95d5091c9ed689fa72b5e5c849df65f5a679ce` | master | Apache-2.0 | +| Seal | `JunkFood02/Seal` | `7677f61a20fda4210e84215fef9e9b51d25daa47` | main | GPL-3.0 | +| Obtainium | `ImranR98/Obtainium` | `af286fa8d31d7406d6db167e2314d376d74f7696` | main | GPL-3.0 | +| release-please | `googleapis/release-please` | `edce3d805ef3ac964d1ba2b29b0f42905f2fa412` | main | Apache-2.0 | +| git-cliff | `orhun/git-cliff` | `60e0be97e945f71148172675be82399d382c9677` | main | Apache-2.0 OR MIT | +| semantic-release | `semantic-release/semantic-release` | `e8c2436e5704a6d1fa5b4aa69238f50edbe586bf` | master | MIT | +| conventional-changelog | `conventional-changelog/conventional-changelog` | `f90c80e9fe02146c1018fa1d78dea738809ab102` | master | ISC | + +> Namida 的 repo 是 **`namidaco/namida`**(`namida-music/namida` 與 `vfsfitvnm/namida` 皆 404);beta 版發在 `namidaco/namida-snapshots`。`hiddify/hiddify-next` 是 `hiddify/hiddify-app` 的**別名**(API 回傳 `full_name` 為 `hiddify/hiddify-app`)。 + +## 一句話總覽 + +| 專案 | 應用內更新? | 實際行為 | +|---|---|---| +| LocalSend | 無 | 完全不檢查,只放連結 | +| **AppFlowy** | **有(真正自我更新)** | macOS 走 Sparkle appcast 下載+替換;Linux 只丟連結;**Windows 有程式碼但官方 release 沒發 appcast,feed 404** | +| Spotube | 半套 | 啟動檢查(含 nightly),只彈對話框丟下載頁連結 | +| Hiddify | 半套 | `upgrader` appcast + 自抓 GitHub API,只丟連結;**appcast 已停更在 0.13.6** | +| Finamp | 無 | 無檢查器;Windows 只產 MSIX | +| Harmonoid | 半套 | 啟動檢查 GitHub `releases/latest`,只丟連結 | +| Namida | 半套 | 啟動檢查(自寫,含 beta 通道與節流),只丟連結 | +| NewPipe | 半套 | 自架 JSON API 檢查,`ACTION_VIEW` 交瀏覽器;**manifest 無 `REQUEST_INSTALL_PACKAGES`** | +| LX Music Desktop | 有(Electron 標準解) | electron-updater 打 GitHub Releases;`autoDownload=false`;`quitAndInstall(true,true)`;**無簽章設定** | +| Seal | 有 | 自寫 updater 打 GitHub `/releases`;**只驗檔案大小**;FileProvider + `ACTION_VIEW` | +| Obtainium | 有 | 自寫,支援約 35 來源;**唯一做 APK 簽章憑證 hash 比對**;四種安裝器 | + +**真正做到「下載+安裝+重啟」的只有兩類:桌面端的 Electron/Sparkle 系(LX Music、AppFlowy macOS),以及 Android 上自己實作安裝的 Seal/Obtainium。7 個 Flutter 專案中沒有任何一個在 Android 做 in-app 下載安裝 APK。** + +--- + +# Part 1 — Flutter 桌面/行動專案 + +## 1. LocalSend + +- repo `localsend/localsend` @ `6f6cd3ee496903e2206c51ffa3a13a5d10bc340b` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | **無**。`app/lib/pages/about/about_page.dart`([permalink](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/about/about_page.dart#L1-L222))全檔 grep `update`/`version`/`PackageInfo` **零命中**,只有官網/GitHub/Codeberg/授權/LicensePage/DebugPage 連結。`app/lib/provider/version_provider.dart` 只用 `PackageInfo.fromPlatform()` 取版本**顯示**,不比較、不連網。 | +| 版本比較 | 無(不適用) | +| 下載/安裝 | 無 in-app。使用者自行到 GitHub Releases/官網/商店取得。 | +| 驗證 | 無 app 內驗證。CI 對 Windows 產物做 **Azure Trusted Signing**(作業系統層信任簽章,非更新簽章):`build_windows_exe.yml` [L61-L90](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/.github/workflows/build_windows_exe.yml#L61-L90) 簽 MSIX helper 與 exe/dll,[L107-L130](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/.github/workflows/build_windows_exe.yml#L107-L130) 以 `/SMySignTool` 讓 Inno 在編譯時同時簽 setup 與內嵌 uninstaller。 | +| Windows | Inno Setup 安裝檔(`support/scripts/compile_windows_exe-inno.iss`)+ portable zip,`iscc` 見上。**無自我更新**。 | +| Android | manifest 有 `REQUEST_INSTALL_PACKAGES`([L14](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/android/app/src/main/AndroidManifest.xml#L14))與 `QUERY_ALL_PACKAGES`(L13),但 `lib/` 內查不到下載/安裝 APK 的程式碼 —— **該權限用途查不到**(推測與其近場分享/快速設定磚流程有關,未能證實)。 | +| Linux | 無 in-app 更新(查不到任何 AppImage/deb 相關更新邏輯)。 | +| macOS | 查不到(`lib/` 無 Sparkle/appcast)。 | +| Release notes | `release-drafter/release-drafter@v6`(`.github/workflows/release.yml` [L86](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/.github/workflows/release.yml#L86)),設定 `.github/release-drafter.yml`,模板連向 CHANGELOG.md 與 CODE_SIGNING.md。 | +| 版本策略 | 版本源頭是 `app/pubspec.yaml` [L7](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/pubspec.yaml#L7) `version: 1.18.2+64`;CI 用 `sed -n 's/^version: \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p'` 抽出 X.Y.Z([release.yml L78-L82](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/.github/workflows/release.yml#L78-L82)),tag 為 `v`(**不含 build number**,[L90](https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/.github/workflows/release.yml#L90))。 | + +## 2. AppFlowy(唯一真正的應用內自我更新) + +- repo `AppFlowy-IO/AppFlowy` @ `5cf3a365dec0d59f64bad1ee4bb1050471a39b93` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | 用 `auto_updater` 套件(pubspec [L32](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/pubspec.yaml#L32) `auto_updater: ^1.0.0`,實際指向 fork `LucasXu0/auto_updater` 的 git 依賴 [L226-L241](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/pubspec.yaml#L226-L241))。啟動時 `auto_update_task.dart` 建 feed URL:`https://github.com/AppFlowy-IO/AppFlowy/releases/latest/download/appcast-{os}-{arch}.xml`([L20-L21](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/auto_update_task.dart#L20-L21)),`setFeedUrl` [L71](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/auto_update_task.dart#L71)、`checkForUpdateInformation()` [L72](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/auto_update_task.dart#L72)、`checkForUpdate()` [L98](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/auto_update_task.dart#L98)。**行動端跳過**(同檔以平台判斷 return,推測因 appcast 只服務桌面)。 | +| 自動/定時 | `version_checker.dart` [L28](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/shared/version_checker/version_checker.dart#L28) `autoUpdater.setScheduledCheckInterval(0)` → **關閉套件內建定時檢查**,改由啟動流程與 critical-update 監聽驅動(`isCriticalUpdateNotifier`,`device_info_task.dart` [L36](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart#L36)/[L47](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart#L47)/[L51](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart#L51))。 | +| appcast 解析 | 自寫:`http.get` 抓 feed、`xml.XmlDocument.parse`、讀 `sparkle:shortVersionString`(`version_checker.dart` [L34-L43](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/shared/version_checker/version_checker.dart#L34-L43)),依賴 `xml: ^6.5.0`(pubspec [L146](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/pubspec.yaml#L146))。 | +| 版本比較 | `version: ^3.0.2`(pubspec [L145](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/pubspec.yaml#L145)),比較式 `Version.parse(latestVersion) > Version.parse(applicationVersion)`(`device_info_task.dart` [L35](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart#L35))。 | +| 下載/安裝 | macOS/Windows 由 `auto_updater`(Sparkle 系)下載並替換、需重啟;**Linux 明確只丟連結**:`checkForUpdate()` → `afLaunchUrlString('https://appflowy.com/download')`(`version_checker.dart` [L66-L71](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/shared/version_checker/version_checker.dart#L66-L71))。 | +| 驗證 | **macOS**:Sparkle EdDSA `sparkle:edSignature`,`dart run auto_updater:sign_update -f PRIVATE_KEY app.dmg` 後寫入 appcast(AppFlowy-Builder `auto_update.yaml` [L102](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L102)/[L115](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L115)/[L144](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L144),arm64 為 [L219-L261](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L219-L261))。**Windows**:DSA `sparkle:dsaSignature`,`dart run auto_updater:sign_update app.exe`([L375](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L375) 起)。金鑰以 secret 名稱傳入(`WINDOWS_AUTO_UPDATE_PRIVATE_KEY`/`PRIVATE_KEY`),本檔不記錄其值。**Linux appcast 無 enclosure、無簽章**([L492](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L492) 只寫 `sparkle:os="linux"`)。appcast 另有 `sparkle:criticalUpdate` 支援([L136-L137](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L136-L137))。 | +| Windows 關鍵落差 | 程式碼要求 feed `appcast-windows-x86_64.xml`([L398](https://github.com/AppFlowy-IO/AppFlowy-Builder/blob/1a913f70f893cde6b5fbab1738731a7431488bb3/.github/workflows/auto_update.yaml#L398)),但實查 release `0.13.0`/`0.14.0`/`0.14.5` 的 assets **都只有** `appcast-macos-{x86_64,arm64}.xml` 與 `appcast-linux-x86_64.xml`,**沒有** Windows appcast(0.14.5 assets 共 16 個,含 `AppFlowy-0.14.5-windows-x86_64.exe` 與 `.zip`,仍無 appcast)。**Windows 的 auto_updater feed URL 會 404,Windows 的應用內更新實際上不會觸發。**(appcast 產生是手動 `workflow_dispatch`。) | +| Windows 安裝 | CI 用 Inno Setup,`iscc /F... inno_setup_config.iss /DAppVersion=`(AppFlowy `release.yml` [L102](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/.github/workflows/release.yml#L102))。 | +| Android | release 有 `AppFlowy-0.14.5-android.apk`,但程式碼在行動端跳過 auto updater;in-app APK 安裝路徑**查不到**。 | +| Linux | 供 AppImage/deb/rpm/tar.gz(見 0.14.5 assets),更新走官網連結。 | +| macOS | dmg/zip + appcast(EdDSA 簽章如上)。 | +| Release notes | 從 CHANGELOG.md 以 sed 抽當前 tag 段落(`release.yml` [L26](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/.github/workflows/release.yml#L26)),非工具產生。 | +| 版本策略 | **矛盾且未解**:release tag 為 `0.14.5`,但 pubspec [L7](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/pubspec.yaml#L7) 仍寫 `version: 0.11.4`;app 內版本取自 `ApplicationInfo.applicationVersion = packageInfo.version`(`device_info_task.dart` [L75](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/device_info_task.dart#L75))→ **推測**版本號在 build 時注入(`build_flowy.dart run . `,`release.yml` [L168](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/.github/workflows/release.yml#L168)/[L395](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/.github/workflows/release.yml#L395)),但 `tool.dart` 只把 tag 當 `--env APP_VERSION=$appVersion` 傳給 cargo make([L41](https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/scripts/flutter_release_build/tool.dart#L41)),**沒有改寫 pubspec**;`package_info_plus` 在 macOS 讀 Info.plist、Windows 讀 exe 版本資源,兩者是否被注入**查不到**。 | + +## 3. Spotube(檢查 → 丟連結) + +- repo `KRTirtho/spotube` @ `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | 啟動時 post-frame 呼叫 `ServiceUtils.checkForUpdates`(`lib/modules/root/use_global_subscriptions.dart` [L23](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/root/use_global_subscriptions.dart#L23))。實作 `lib/utils/service_utils.dart` [L229](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/utils/service_utils.dart#L229) 起。 | +| 雙通道 | nightly:打 GitHub Actions workflow-runs API,比 `run_number` 與 `packageInfo.buildNumber`([L244-L265](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/utils/service_utils.dart#L244-L265))。stable:`https://api.github.com/repos/KRTirtho/spotube/releases/latest`([L271](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/utils/service_utils.dart#L271))。 | +| 開關 | `Env.enableUpdateChecker => kIsFlatpak \|\| _enableUpdateChecker == "1"`(`lib/collections/env.dart` [L34-L35](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/collections/env.dart#L34-L35))→ 可用 dart-define 關閉;**Flatpak 一律開啟**(推測:Flatpak 無法自行更新,故強制提示)。 | +| 版本比較 | `version` 套件 `Version.parse`([L277-L279](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/utils/service_utils.dart#L277-L279)),並對 pre-release 標籤做不匹配防護與 `latestVersion <= currentVersion` 早退。 | +| 下載/安裝 | **無自動下載**。對話框只有按鈕 `launchUrlString`,目標 `https://spotube.krtirtho.dev/downloads`(`lib/modules/root/update_dialog.dart` [L17-L24](https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/root/update_dialog.dart#L17-L24)),nightly 另有 `/downloads/nightly`。 | +| 驗證 | release 附 md5/sha256 checksums(`.github/workflows/spotube-release-binary.yml`),**app 端不驗**(程式碼無雜湊/簽章比對)。 | +| Windows | Inno Setup(`windows/packaging/exe/inno_setup.iss`);使用者下載 exe 自行安裝。 | +| Android | manifest **無** `REQUEST_INSTALL_PACKAGES`(實測 grep 命中 0)→ 走 GitHub/F-Droid/商店。 | +| Linux | Flatpak 強制檢查(見上),結果同樣只給下載頁連結。 | +| macOS | 查不到(推測:dmg 連結,未在樹內找到對應處理)。 | +| Release notes | release 由 `ncipollo/release-action@v1` 建立(nightly tag `nightly`,stable tag `v$PUBSPEC_VERSION`);notes 內容產生方式查不到(推測手寫或 GitHub 自動)。 | +| 版本策略 | 版本源頭 `pubspec.yaml`;CI 抽出後 tag `v`;nightly 用固定 tag `nightly`(非語意版本)。 | + +## 4. Hiddify(`upgrader` appcast + 自抓 API,但 appcast 已死) + +- repo `hiddify/hiddify-app` @ `276a7effb0046a039220a745022563740968c0b8` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | 兩條並存:(a) `upgrader` 套件——`UpgraderAppcastStore(appcastURL: Constants.appCastUrl)` 依平台選 store(`lib/features/app_update/notifier/app_update_notifier.dart` [L23](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/app_update/notifier/app_update_notifier.dart#L23));(b) 自寫 `check()`([L50](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/app_update/notifier/app_update_notifier.dart#L50) 起)打 GitHub releases API。 | +| 觸發點 | 啟動時 `UpgradeAlert(upgrader: upgrader, ...)`(`lib/features/app/widget/app.dart` L62/L94);About 頁有「檢查更新」tile → `appUpdateNotifierProvider.notifier).check()`(`lib/features/about/widget/about_page.dart` [L44-L50](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/about/widget/about_page.dart#L44-L50))。 | +| 常數 | `githubReleasesApiUrl = "https://api.github.com/repos/hiddify/hiddify-next/releases"`、`appCastUrl = "https://raw.githubusercontent.com/hiddify/hiddify-next/main/appcast.xml"`(`lib/core/model/constants.dart` [L9-L11](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/core/model/constants.dart#L9-L11))。 | +| 自我抓取邏輯 | `httpClient.get(Constants.githubReleasesApiUrl)`(`app_update_repository.dart` [L32](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/app_update/data/app_update_repository.dart#L32)),`releases.firstWhere((e) => e.preRelease == false)`([L43](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/app_update/data/app_update_repository.dart#L43))。 | +| 版本比較 | `Version.parse(remote.version)`(`app_update_notifier.dart` [L68](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/features/app_update/notifier/app_update_notifier.dart#L68) 起),另有 `ignored_release_version` 忽略已略過的版本。 | +| 下載/安裝 | **無**。對話框「Update now」→ `UriUtils.tryLaunch(Uri.parse(newVersion.url))`(`lib/core/router/dialog/widgets/new_version_dialog.dart` [L60](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/lib/core/router/dialog/widgets/new_version_dialog.dart#L60))→ 丟連結。 | +| 驗證 | appcast 項目**無簽章欄位**;GitHub release 亦查不到簽章。 | +| 通道差異 | `lib/core/model/environment.dart`:`Release.general \| googlePlay`,`allowCustomUpdateChecker => this == general`;`isPortable` 為 build flag(影響 Windows 是否用可攜版)。 | +| Windows | `flutter_distributor` 產 `exe,msix,zip`;MSIX 以 `windows/packaging/msix/make_config.yaml` 設定簽章。 | +| Android | manifest **無** `REQUEST_INSTALL_PACKAGES`(grep 0);`Release.googlePlay` 走 `UpgraderPlayStore`。 | +| Linux/macOS | 走 `UpgraderAppcastStore`(appcast 有 mac 項目)/App Store 走 `UpgraderAppStore`。 | +| Release notes | **`gitchangelog` + mustache 模板**:CI `pip install gitchangelog pystache mustache markdown`、取上一個 latest tag、`gitchangelog "${prelease}.." >> release.md`(`.github/workflows/build.yml` [L401-L404](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/.github/workflows/build.yml#L401-L404)),模板 `.release_notes.tpl`、設定 `.gitchangelog.rc`;release 以 draft/prerelease 建立([L413-L428](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/.github/workflows/build.yml#L413-L428)、[L465-L466](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/.github/workflows/build.yml#L465-L466))。 | +| 版本策略 | tag 形如 `v4.1.1`(實查 `releases/latest`);pubspec 為版本源頭。 | +| **關鍵負面事實** | repo 根 `appcast.xml`(app 實際讀的那份)內容**停在 `sparkle:version="0.13.6"`**、`pubDate` 為 `Sun, 7 Jan 2024 22:00:00 +0000`([L7](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/appcast.xml#L7) 與 [L1-L40](https://github.com/hiddify/hiddify-app/blob/276a7effb0046a039220a745022563740968c0b8/appcast.xml#L1-L40)),共 5 個項目、**無簽章**,其中一個 url 還寫成 `hhttps://`(壞的)。當前實際 latest 是 `v4.1.1` → **appcast 路徑實際上不會觸發更新**,真正會動的是自寫的 GitHub API 檢查。 | + +## 5. Finamp(無應用內更新;Windows 只有 MSIX) + +- repo `jmshrv/finamp` @ `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | **查不到任何更新檢查器**(`lib/` 內無 update checker/GitHub API 呼叫)。 | +| 版本比較 | 無 | +| 下載/安裝 | 使用者自商店/GitHub 取得。README 列 Play Store、F-Droid、App Store、GitHub APK([L92-L105](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/README.md#L92-L105)、[L125-L126](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/README.md#L125-L126)),並註明 F-Droid 一天只建一次。 | +| 驗證 | app 端無。CI 建 MSIX 帶 `--install-certificate false`(`build.yml` [L391](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L391))→ 為未簽章/自簽流程;Android 由商店簽。 | +| Windows | **只產 MSIX**:`dart run msix:create --install-certificate false`([L370-L395](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L370-L395)),且有 TODO:**沒有傳統安裝器**(原文註解 "would be nice to have an old-school installer…",[L395](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L395))。pubspec `build_windows: false`([L280](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L280))因 `msix:create` 內建 build 有 bug(註解 [L279](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L279));另有 `windows/runner/resources/MSIX_LOCAL_CERTIFICATE.pfx`。 | +| Android | 商店/APK 手動安裝;manifest **無** `REQUEST_INSTALL_PACKAGES`(grep 0)。 | +| Linux | `flutter build linux --release`([L279](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L279)),**無** AppImage/deb/rpm 打包。 | +| macOS | `build.yml` 有 macOS 區塊但被註解([L442](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L442) 附近);使用者走 App Store。 | +| Release notes | assets 由 `alexellis/upload-assets@0.5.0` 在 tag push 時上傳([L318](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L318)、[L410](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/.github/workflows/build.yml#L410));notes 產生方式查不到(推測手寫)。另有 `beta-release.md` 與 `fastlane/metadata/android` 供商店文案。 | +| 版本策略 | pubspec `version: 1.0.1+201`([L18](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L18)),但 `msix_config.msix_version: 1.0.1.0`([L261-L265](https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/pubspec.yaml#L261-L265))→ **Windows 版本號要另外手動同步**(四段式,與 pubspec 不同格式)。 | + +## 6. Harmonoid(檢查 → 丟連結) + +- repo `alexmercerind/harmonoid` @ `2b021f7b0b5dbcbe027aec010580977a2939a28d` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | constructor 內 `unawaited(check())`(`lib/features/update/state/update_notifier.dart` [L26](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L26)),`check()` [L34](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L34) 起;抓 `api.github.com/repos/harmonoid/harmonoid/releases/latest`(`lib/features/update/api/latest_release_get.dart` [L16](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/api/latest_release_get.dart#L16))。 | +| 版本比較 | 用 `identity` 套件的 `compareVersions`(子模組 `external/identity`,**tarball 內不存在,實作查不到**)。版本常數 `kVersion = 'v0.3.34'`(`lib/utils/constants.dart` [L7](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/utils/constants.dart#L7))。 | +| 略過機制 | 已提示版本記在 `Configuration.instance.updateCheckVersion`([L48](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L48)、[L53](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L53));release body 若含 `SKIP_IN_APP_UPDATE_DIALOG` 則整個對話框略過(常數 [L20](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L20))。 | +| 下載/安裝 | **無**。依平台丟連結:`kDownloadUrl = 'https://harmonoid.com/downloads'`([L21](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L21))、Android Play Store([L22](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L22))、iOS App Store([L23](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/update/state/update_notifier.dart#L23))。 | +| 驗證 | app 端無。macOS CI 有 codesign/notarize/`xcrun stapler`(`.github/workflows/master.yml` [L97-L127](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/.github/workflows/master.yml#L97-L127))。 | +| Windows | Inno Setup(`Harmonoid_InnoSetup_x64.iss`,MyAppVersion `0.3.34.0`);使用者自行下載安裝。 | +| Android | Play Store 連結;in-app APK 安裝查不到。 | +| Linux/macOS | 官網下載頁連結;macOS dmg 有公證。 | +| Release notes | `softprops/action-gh-release@v1`;**stable 先發到另一個 repo**(`secrets.REPOSITORY_2`,draft、tag `vnext`,[L130-L136](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/.github/workflows/master.yml#L130-L136)),snapshot 發到 `harmonoid/snapshots`(prerelease、tag `snapshot`,[L141-L147](https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/.github/workflows/master.yml#L141-L147));notes 產生方式查不到(推測 GitHub 自動/手寫)。 | +| 版本策略 | `kVersion` 常數與 `.iss` 的 `0.3.34.0` **手動同步**;tag 形式查不到(stable 走 draft `vnext`,推測發佈流程在另一 repo 完成)。 | + +## 7. Namida(自寫檢查器最完整:雙通道+節流) + +- repo `namidaco/namida` @ `acb1e1622600440cc793f389f497e6771c732c5e` + +| 項目 | 結論 | +|---|---| +| 更新檢查 | `VersionController` 啟動即抓;`Uri.https('api.github.com', '/repos/namidaco/$repoName/releases$endpoint', ...)`(`lib/controller/version_controller.dart` [L87-L89](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/version_controller.dart#L87-L89)),`repoName = isBeta ? 'namida-snapshots' : 'namida'`([L88](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/version_controller.dart#L88))→ **beta 通道走另一個 repo**。`/latest` 見 [L104](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/version_controller.dart#L104)。 | +| 匿名/節流 | `const String? token = null`([L90](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/version_controller.dart#L90))→ **匿名 API,未帶 token**(受 60 req/h 限制);重抓節流 `Duration(hours: 2)`([L61](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/version_controller.dart#L61))。另有分頁抓取與 422 處理。 | +| 版本比較 | **完全自寫** `VersionWrapper`(`lib/class/version_wrapper.dart` [L4](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/class/version_wrapper.dart#L4)):build number 為 `yyMMddHHP` 格式 → 解析成 `DateTime`([L44](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/class/version_wrapper.dart#L44)、[L49](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/class/version_wrapper.dart#L49)),`isAfter` 為逐段比對([L66](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/class/version_wrapper.dart#L66) 起)。 | +| 下載/安裝 | **無**。更新 sheet 的 UPDATE 按鈕依 beta 選 `AppSocial.GITHUB_RELEASES` 或 `GITHUB_RELEASES_BETA`(`lib/ui/widgets/custom_widgets.dart` [L7432](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/ui/widgets/custom_widgets.dart#L7432)),常數 `lib/core/constants.dart` [L1038-L1039](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/core/constants.dart#L1038-L1039) → 丟連結。 | +| 驗證 | 無(無雜湊/簽章比對)。 | +| Windows/Linux/macOS | 查不到(推測:無桌面版;未在樹內找到對應平台發佈流程)。 | +| Android | manifest 有大量權限與 `QUERY_ALL_PACKAGES`([L19](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/android/app/src/main/AndroidManifest.xml#L19))、有 FileProvider([L496-L504](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/android/app/src/main/AndroidManifest.xml#L496-L504),推測給分享/快取用),但**沒有** `REQUEST_INSTALL_PACKAGES` → **不支援 in-app APK 安裝**。 | +| Release notes | **自寫 Python** `scripts/chlog.py`:依 conventional-commit prefix 分類(`CHANGELOG_PREFIXES = ("feat","core","perf","chore","fix")`,[L41](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/scripts/chlog.py#L41)),固定三個段落 `### ✨ Highlights:`/`### 🎉 New Features:`/`### 🛠️ Bug fixes & Improvements:`([L52-L54](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/scripts/chlog.py#L52-L54))。CI `python3 scripts/chlog.py beta --repo `(`.github/workflows/release_beta.yml` [L96-L100](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/.github/workflows/release_beta.yml#L96-L100)),再以 `gen_downloads_table.sh` 併下載表,最後 `softprops/action-gh-release@v3` + `body_path: ./beta_changelog.md`([L114-L120](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/.github/workflows/release_beta.yml#L114-L120))。 | +| 版本策略 | pubspec `version: 7.5.0-beta+260927218`([L4](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/pubspec.yaml#L4),build number 即上述時戳格式);`bump_version.dart` 會自動改寫 pubspec version 行([L13-L59](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/bump_version.dart#L13-L59));CI 抽 `version:.*` 後,**stable tag 用 `v`、beta tag 用含 build 的完整 version**([L90](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/.github/workflows/release_beta.yml#L90)、[L93](https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/.github/workflows/release_beta.yml#L93))。 | + +### 1.8 本組橫向比較 + +**更新能力光譜** + +| 光譜位置 | 專案 | 依據 | +|---|---|---| +| 下載+替換+重啟(真正自我更新) | AppFlowy(僅 macOS;Linux 是連結) | Sparkle 系 `auto_updater`,appcast 帶 `sparkle:edSignature` | +| 檢查+提示+丟下載連結 | Spotube、Hiddify、Harmonoid、Namida | 四者都在啟動時檢查、只開瀏覽器 | +| 完全不檢查 | LocalSend、Finamp | 樹內查不到任何 update checker | + +**檢查機制對照** + +| 專案 | 來源 | 觸發 | 通道 | 節流/限制處理 | +|---|---|---|---|---| +| AppFlowy | 自家 release 的 appcast XML(`releases/latest/download/...`) | 啟動 task + critical-update 監聽;套件定時檢查關閉(interval 0) | stable 單一 | 關掉自動定時,改事件驅動 | +| Spotube | GitHub `releases/latest`(stable)/Actions runs API(nightly) | 啟動 post-frame | nightly + stable | 可用 dart-define 關;Flatpak 強制開 | +| Hiddify | `upgrader` appcast(**已死**)+ 自抓 `releases` API | 啟動 `UpgradeAlert` + About 頁按鈕 | general/googlePlay 變體 | `ignored_release_version` | +| Harmonoid | GitHub `releases/latest` | constructor 即檢查 | stable | `updateCheckVersion`;body 可 `SKIP_IN_APP_UPDATE_DIALOG` | +| Namida | GitHub `releases/latest` | 啟動即抓 | **beta repo 分離**(`namida-snapshots`) | 2 小時節流、匿名 token=null、422 處理、分頁 | + +**版本比較實作** + +| 做法 | 專案 | +|---|---| +| `version` 套件 `Version.parse` | AppFlowy、Spotube、Hiddify | +| 完全自寫 | Namida(`VersionWrapper`,把 `yyMMddHHP` 轉時間)、Harmonoid(`identity.compareVersions`,實作查不到) | +| 不做比較 | LocalSend、Finamp | + +**Release notes 工具** + +| 做法 | 專案 | +|---|---| +| 現成套件 `release-drafter` | LocalSend | +| `gitchangelog` + mustache 模板 | Hiddify | +| 自寫 Python(conventional prefix 分類+固定段落) | Namida | +| 直接 sed 抽 CHANGELOG.md 段落 | AppFlowy | +| 只上傳 assets,notes 方式查不到 | Spotube、Finamp、Harmonoid | + +**Windows 打包** + +| 做法 | 專案 | +|---|---| +| Inno Setup(+程式碼簽章) | LocalSend(Azure Trusted Signing)、Spotube、AppFlowy、Harmonoid | +| 只有 MSIX、明說沒有傳統安裝器 | Finamp | +| exe/msix/zip(flutter_distributor) | Hiddify | + +**Android in-app APK 安裝** + +**七個專案都做不到/沒做**:Spotube、Hiddify、Finamp、Namida 的 manifest 均**無** `REQUEST_INSTALL_PACKAGES`;LocalSend 有該權限但樹內查不到對應安裝程式碼;AppFlowy 有發 APK 但行動端跳過 updater。**沒有任何一個示範了程式內下載並觸發系統安裝 APK 的完整流程。** + +**本組事實層面觀察** + +- 這 7 個專案中,**只有 1 個(AppFlowy,且只在 macOS)**真的做到下載+替換;其餘 6 個即使有檢查器也止於「開瀏覽器」。 +- 「檢查更新」的**主流來源是 GitHub Releases API**(Spotube、Hiddify、Harmonoid、Namida 四家),而非自架後端;代價是匿名 60 req/h 與需要節流(只有 Namida 有 2 小時節流)。 +- **release notes 自動化在桌面/行動 OSS 並不普遍**,且做法分歧(release-drafter/gitchangelog/自寫 Python/sed 抽 CHANGELOG 各一家)。 +- **Windows 自我更新是公認的痛點**:這批專案要嘛只做 Inno 安裝檔(無更新),要嘛(AppFlowy)連 feed 都沒發出來。 +- **Android in-app 安裝 APK 沒人做**,全部走商店或叫使用者自己去 GitHub 抓。 + +--- + +# Part 2 — Android 原生與 Electron 桌面 + +## 8. NewPipe(TeamNewPipe/NewPipe,Android 原生) + +### 8.1 更新檢查的來源:自架 API,不是 GitHub Releases + +- **事實**:檢查端點是寫死的常數 `https://newpipe.net/api/data.json`: + [`NewVersionWorker.kt#L162`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L162) + `private const val NEWPIPE_API_URL = "https://newpipe.net/api/data.json"` +- **事實**:因此**不是** GitHub Releases、**不是** `teamnewpipe.github.io`、也**不是** F-Droid 的 index(API 只是把 F-Droid 的 APK 路徑轉發出來)。APK 由 `archive.newpipe.net` 托管。 +- 查證日實抓 `https://newpipe.net/api/data.json` 的回應結構(摘錄): + +``` +flavors.newpipe = { apk: "https://archive.newpipe.net/fdroid/repo/NewPipe_v0.29.1.apk", + hash: "18447bfb…", hash_type: "sha256", + version: "0.29.1", version_code: 1015 } +另有 flavors.fdroid、flavors.github.stable、stats +``` + +### 8.2 解析流程 + +- **事實**:[`NewVersionWorker.kt#L130-L135`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L130-L135):`response.responseBody()).getObject("flavors")` → 取 `getString("version")`、`getInt("version_code")`、`getString("apk")`。 +- **事實(關鍵)**:用戶端只讀 `version` / `version_code` / `apk` 三個欄位,**完全沒有讀 `hash` / `hash_type`** —— API 提供了 sha256,但 App 不做任何 checksum 驗證。(以該檔全文為依據。) + +### 8.3 只對「官方簽章版」啟用檢查 + +- **事實**:[`ReleaseVersionUtil.kt#L15`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt#L15) 定義官方 release 憑證公鑰 SHA-256(值不在此轉錄); + [`L19-L26`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt#L19-L26) `isReleaseApk` 用 `PackageInfoCompat.hasSignatures(pm, packageName, certificates, false)` 搭配 `PackageManager.CERT_INPUT_SHA256` 比對。 +- **事實**:[`NewVersionWorker.kt#L93`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L93) `if (!ReleaseVersionUtil.isReleaseApk) return` —— 官方簽章以外的任何 build(含 F-Droid 版、自編版)直接跳過更新檢查。 +- **事實(區分)**:這裡的簽章檢查是**自我識別用**(判斷自己是不是官方版),**不是下載物驗證**。 + +### 8.4 檢查頻率與快取 + +- **事實**:[`L102`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L102) `isLastUpdateCheckExpired(expiry)`;[`L117`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L117) `coerceUpdateCheckExpiry(response.getHeader("expires"))`;[`L119`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L119) 寫入 `update_expiry_key`。 +- **事實**:[`ReleaseVersionUtil.kt#L46-L50`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/util/ReleaseVersionUtil.kt#L46-L50):`nowPlus6Hours` 為下限、`nowPlus6Hours.plusHours(66)` 為上限 → 伺服器給的 `expires` 被夾在 **6h~72h**。檢查頻率由伺服器控制,非使用者設定。 +- **事實**:有測試覆蓋 `app/src/test/java/org/schabi/newpipe/NewVersionManagerTest.kt`(5 個測試,涵蓋到期與未到期、6h/72h 夾取)。 + +### 8.5 使用者設定與首次同意 + +- **事實**:[`app/src/main/res/xml/update_settings.xml`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/xml/update_settings.xml):一個 `SwitchPreferenceCompat`(key `update_app_key`,預設 **false**)+ 一個 `Preference`(key `manual_update_key`,手動檢查)。**沒有「檢查頻率」選項**。 +- **事實**:[`UpdateSettingsFragment.java`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java):`askForConsentToUpdateChecks()` / `wasUserAskedForConsent`(key `update_check_consent_key`)負責首次進入時的同意對話框。 +- **事實**:[`MainActivity.java#L197`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/MainActivity.java#L197) 同意閘門、[`L200`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/MainActivity.java#L200) 呼叫 `askForConsentToUpdateChecks`、[`L224`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/MainActivity.java#L224) 入列 `enqueueNewVersionCheckingWork(app, false)`。 + +### 8.6 不做安裝 —— 交棒給瀏覽器 + +- **事實**:[`NewVersionWorker.kt#L59`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L59):`val intent = Intent(Intent.ACTION_VIEW, apkLocationUrl?.toUri())`,包進 notification 的 `PendingIntent`。→ App 只「開一個 URL」,下載與安裝都交給系統瀏覽器,自己不經手 APK 檔案。 +- **事實**:版本比較與通知邏輯在同檔 [`L39`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/NewVersionWorker.kt#L39) `compareAppVersionAndShowNotification`;已是最新版時(手動觸發 `IS_MANUAL`)跳 `app_update_unavailable_toast`。 + +### 8.7 權限與 FileProvider + +- **事實**:[`app/src/main/AndroidManifest.xml#L6-L14`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/AndroidManifest.xml#L6-L14) 宣告的權限:`INTERNET`、`WAKE_LOCK`、`ACCESS_NETWORK_STATE`、`WRITE_EXTERNAL_STORAGE`、`SYSTEM_ALERT_WINDOW`、`FOREGROUND_SERVICE`(含 `DATA_SYNC` / `MEDIA_PLAYBACK`)、`POST_NOTIFICATIONS`。**沒有 `REQUEST_INSTALL_PACKAGES`**(本次抽驗逐行確認,與「不在 App 內安裝」的設計一致)。 +- **事實**:[`#L157-L164`](https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/AndroidManifest.xml#L157-L164) 有宣告 FileProvider(`android:authorities="${applicationId}.provider"`、`exported=false`、`android:resource="@xml/nnf_provider_paths"`)。 +- **事實(本次抽驗確認)**:`@xml/nnf_provider_paths` 指向的檔案在該 SHA 的**完整遞迴 tree 中不存在**(`truncated: false`;以 `nnf_provider|provider_paths` 比對全部路徑無命中),直接取 `app/src/main/res/xml/nnf_provider_paths.xml` 回 **404**。→ 該 SHA 處於一個**懸空引用**的狀態。此為事實陳述,非推測。 + +### 8.8 「忽略版本」 + +- **事實**:在該 SHA 的 `app/src/main/res/values/strings.xml` 中搜不到 ignore-version 相關字串(僅有無關的 `ignore_hardware_media_buttons_*`)。**NewPipe 沒有「忽略此版本」功能**。 + +### 8.9 小結 + +| 面向 | NewPipe 做法 | +|---|---| +| 來源 | 自架靜態 JSON API(`newpipe.net/api/data.json`),非 GitHub | +| 驗證 | 只驗「自己是不是官方簽章版」;**不驗下載物**(API 給了 sha256 但沒用) | +| 安裝 | 不做;`ACTION_VIEW` 開瀏覽器 | +| 權限 | 無 `REQUEST_INSTALL_PACKAGES` | +| 頻率 | 伺服器 `expires` 標頭,夾在 6–72h;使用者只能開/關 | +| 忽略版本 | 無 | + +## 9. LX Music Desktop(lyswhut/lx-music-desktop,Electron + electron-updater) + +### 9.1 Feed 來源:GitHub Releases + +- **事實**:[`build-config/build-pack.js#L46-L52`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L46-L52): + +``` +publish: [{ provider: 'github', owner: 'lyswhut', repo: 'lx-music-desktop' }] +``` + +electron-builder 的 publish provider 指向 GitHub Releases → electron-updater 讀 `latest.yml`。 + +### 9.2 打包目標 + +- **事實**:同檔 [`L59`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L59) `win:`、[`L64`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L64) `nsis: { oneClick: false, language: '2052', allowToChangeInstallationDirectory: true, shortcutName: 'LX Music' }`、[`L78`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L78) `linux:`、[`L98`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L98) `appImage:`、[`L108`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L108) `mac:`、[`L113`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/build-config/build-pack.js#L113) `dmg:`。 +- **事實**:`createTarget` 對應:`setup`→`nsis`、`green`→`7z`、`win7_setup`→`nsis`、`win7_green`→`7z`、`portable`→`portable`;Linux 有 `deb` / `appImage` / `pacman` / `rpm`;**macOS 只有 `dmg`,沒有 `zip`**。 +- **推測**:macOS 的 electron-updater 自動更新通常需要 `zip` 目標才能自我替換 App bundle;只有 `dmg` 時 macOS 端自動更新很可能不可用(或只能引導手動下載)。此為從打包設定推得,未在官方文檔找到明確說明。 + +### 9.3 簽章設定:repo 內完全沒有 + +- **事實**:在 `build-pack.js` 與 `build-config/` 下搜不到 `certificateSubjectName`、`publisherName`、`notarize`、`verifyUpdateCodeSignature` 任何一項。→ Windows/macOS 都沒有程式碼簽章設定。 +- **推測**:electron-updater 對 Windows 的 `verifyUpdateCodeSignature` 預設行為未從本 repo 原始碼確認(該邏輯在 electron-updater 套件內,不在本 repo);由於專案未簽章,任何依賴簽章驗證的路徑都無法生效。**未確認**。 + +### 9.4 更新流程(主行程) + +- **事實**:[`src/main/modules/winMain/autoUpdate.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts): + - [`L8`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts#L8) `autoUpdater.autoDownload = false` → 不自動下載,等使用者按。 + - [`L113`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts#L113) `if (!autoUpdater.isUpdaterActive()) return`;[`L114`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts#L114) `downloadUpdate()`;[`L121`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts#L121) `quitAndInstall(true, true)`(`isSilent=true, isForceRunAfter=true`)。 + - **事實**:[`L140-L145`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/winMain/autoUpdate.ts#L140-L145):註解「由于集合安装包中不包含win arm版…」→ Windows ARM 直接回報 `update_error: 'failed'`;其餘平台依 `global.lx.appSetting['common.tryAutoUpdate']` 決定 `autoDownload` 後 `checkForUpdates()`。 + +### 9.5 第二條獨立的版本資訊管道(renderer) + +- **事實**:[`src/renderer/utils/update.js#L9-L17`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/utils/update.js#L9-L17):除 electron-updater 外,另有一份 `publish/version.json` 的鏡像清單(3 次重試、10 秒 timeout): + `raw.githubusercontent.com`(master)、`registry.npmjs.org/lx-music-desktop-version-info/latest`、jsdelivr 三個節點(cdn / fastly / gcore)、`registry.npmmirror.com`、`gitee.com/lyswhut/lx-music-desktop-versions`、`http://cdn.stsky.cn/lx-music/desktop/version.json`。 +- **事實**:此設計對應「中國境內可達性」需求 —— 同時維護 GitHub、npm、jsdelivr、npmmirror、gitee、自架 CDN 六類來源。 + +### 9.6 使用者設定、忽略版本、失敗節流 + +- **事實**:[`src/renderer/core/useApp/useUpdate.ts`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/core/useApp/useUpdate.ts): + - `getIgnoreVersion()` → `if (result.version === ignoreVersion) return` —— **有「忽略此版本」**。 + - `localStorage` key `update__check_failed_tip`,節流 **7 天**(`7 * 86400000`)才再提示一次檢查失敗。 + - 下載 1 小時 timeout 的 modal;用 `compareVer` 偵測降級(downgrade);changelog 取自 `versionInfo.newVersion.history` 中對應版本。 +- **事實**:[`src/renderer/views/Setting/components/SettingUpdate.vue`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/renderer/views/Setting/components/SettingUpdate.vue):公開設定只有 `common.tryAutoUpdate`(嘗試自動更新)與 `common.showChangeLog`(顯示更新日誌);**沒有檢查頻率設定**。畫面顯示當前/最新版本、commit id 與日期、下載進度。 + +### 9.7 發佈流程與 changelog 產生方式 + +- **事實**:[`.github/workflows/release.yml`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/.github/workflows/release.yml):4 個 job(Windows:`publish:win:7z:x64`、`7z:arm64`、`setup:arm64`、`setup:x64`;Windows_7;Mac:`publish:mac:dmg` x64+arm64;Linux:deb amd64/arm64/armv7l、appImage、rpm、pacman)。用 `GITHUB_TOKEN` 與 `BT_TOKEN`,最後用 `Get-FileHash -Algorithm MD5` / `md5sum` 產生 release 附件。 +- **事實**:[`publish/utils/updateChangeLog.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/publish/utils/updateChangeLog.js):**changelog 是手寫的**(`publish/changeLog.md`),由腳本攤平進 `publish/version.json`(`desc` + 前插 `history[]`)並 bump `package.json` 版本。 +- **事實**:[`publish/utils/parseChangelog.js`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/publish/utils/parseChangelog.js):以 regex 解析 `CHANGELOG.md` 中 `## [x.y.z](url) - YYYY-MM-DD` 形式的標題。`publish/index.js` 負責編排,失敗時把 `version.json` / `package.json` 回滾。 +- **事實**:LX Music **完全沒有用** Conventional Commits 工具鏈,changelog 純人工撰寫。 + +### 9.8 小結 + +| 面向 | LX Music Desktop | +|---|---| +| 機制 | electron-updater(Electron 標準解) | +| Feed | GitHub Releases(`latest.yml`)+ 6 類鏡像的 `version.json` | +| 自動下載 | 預設關(`autoDownload=false`),使用者按才下 | +| 安裝 | `quitAndInstall(true, true)` 靜默 + 裝完自動啟動 | +| 簽章 | repo 內**完全沒有**簽章/公證設定 | +| 忽略版本 | 有 | +| 檢查頻率 | 無設定;失敗提示節流 7 天 | +| changelog | 手寫,非 Conventional Commits 工具鏈 | + +## 10. Seal(JunkFood02/Seal,Android) + +### 10.1 自寫 updater,沒有第三方套件 + +- **事實**:[`app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt) 全自寫(OkHttp + kotlinx.serialization)。repo 內**沒有** `android-updater`、`com.github.javiersantos` 之類的第三方 updater 依賴。 + +### 10.2 來源:GitHub Releases API + +- **事實**:[`L43-L45`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L43-L45) `requestForLatestRelease` → `https://api.github.com/repos/JunkFood02/Seal/releases/latest`(**宣告但未使用**,dead code)。 +- **事實**:[`L48-L49`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L48-L49) `requestForReleases` → `https://api.github.com/repos/JunkFood02/Seal/releases`(實際使用);[`L78`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L78) `client.newCall(requestForReleases)`;[`L80`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L80) 依 `UPDATE_CHANNEL`(`STABLE`);[`L84`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L84) `maxByOrNull { it.name.toVersion() }` 取最新;[`L88`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L88) `checkForUpdate()`。 + +### 10.3 下載與 ABI 選擇 + +- **事實**:[`L142`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L142) `downloadApk()`;[`L162`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L162) `preferredArch = Build.SUPPORTED_ABIS.firstOrNull()`;[`L167-L169`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L167-L169) 以 `it.name?.contains(preferredArch)` 挑 asset,取 `browserDownloadUrl`。 +- **事實**:存到 `getExternalFilesDir("apk")/latest.apk`;若已下載的 APK 其 `versionName >= release.name.toVersion()` 則跳過重下。 + +### 10.4 驗證:只有檔案大小 + +- **事實**:[`L212-L213`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L212-L213):只檢查 `progressBytes < totalBytes` → "missing bytes"、`progressBytes > totalBytes` → "too many bytes"。→ **沒有 checksum 驗證、沒有簽章驗證**。 +- **事實**:自寫的 `Version` sealed class(Alpha / Beta / ReleaseCandidate / Stable,帶數值權重),regex `v?(\d+)\.(\d+)\.(\d+)(-(\w+)\.(\d+))?`。另有一支獨立的 `updateYtDlp()`(走 `YoutubeDL.UpdateChannel.STABLE / NIGHTLY`,更新 youtubedl-android 的 binary,與 App 自身更新無關)。 + +### 10.5 安裝:FileProvider + ACTION_VIEW + +- **事實**:[`L107-L117`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/util/UpdateUtil.kt#L107-L117) `installLatestApk()`:`FileProvider.getUriForFile(this, getFileProvider(), getLatestApk())` + `Intent(ACTION_VIEW)` 配 `setDataAndType(contentUri, "application/vnd.android.package-archive")` 與 `FLAG_GRANT_READ_URI_PERMISSION`。 +- **事實**:**不是** `PackageInstaller` session,也沒有 `setRequireUserAction`/安裝器-of-record 靜默安裝。 + +### 10.6 權限與「未知來源」引導 + +- **事實**:[`app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L50`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L50) `canRequestPackageInstalls()`;[`L53`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L53) 以 `Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES` + `package:${context.packageName}` 引導使用者開權限;[`L94`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L94) `launcher.launch(Manifest.permission.REQUEST_INSTALL_PACKAGES)`。 +- **事實**:[`L64`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L64) 先檢查 `isNetworkAvailableForDownload()` 與 `isAutoUpdateEnabled()`;[`L69`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/ui/page/AppUpdater.kt#L69) `UpdateUtil.checkForUpdate()`。 +- **事實**:[`AndroidManifest.xml#L15`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/AndroidManifest.xml#L15) ``;[`#L121-L129`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/AndroidManifest.xml#L121-L129) FileProvider `${applicationId}.provider` 配 `@xml/provider_paths`。 + +### 10.7 Product flavors —— F-Droid 版關掉 updater + +- **事實**:[`app/build.gradle.kts#L117`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/build.gradle.kts#L117) `flavorDimensions += "publishChannel"`,三個 flavor:`generic`(預設)、`githubPreview`(`.preview` 後綴,名稱 "Seal Preview")、`fdroid`(versionName 後綴 `-(F-Droid)`)。同檔 [`L50`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/build.gradle.kts#L50) `versionCode = 200_000_150`;`applicationVariants` 內加 ABI 代碼,產物名 `Seal-${versionName}-${name}.apk`。 +- **事實**:[`app/src/main/java/com/junkfood/seal/App.kt#L222`](https://github.com/JunkFood02/Seal/blob/7677f61a20fda4210e84215fef9e9b51d25daa47/app/src/main/java/com/junkfood/seal/App.kt#L222) `fun isFDroidBuild(): Boolean = BuildConfig.FLAVOR == "fdroid"`;`UpdatePage.kt` 中 `showUnavailableDialog = App.isFDroidBuild()`。→ F-Droid 版一律停用應用內更新器。 +- **事實**:`UpdatePage.kt` 的設定:`AUTO_UPDATE`、`UPDATE_CHANNEL`(預設 `STABLE`)、`PRE_RELEASE`。repo 另有 `fastlane/metadata/android//changelogs/.txt`(F-Droid 的 changelog 慣例)與 `CHANGELOG.md`。 + +### 10.8 小結 + +| 面向 | Seal | +|---|---| +| 機制 | 全自寫(OkHttp + kotlinx.serialization),無第三方 updater | +| 來源 | GitHub Releases API(`/releases`,非 `/latest`) | +| 驗證 | **只有檔案大小**;無 checksum、無簽章 | +| 安裝 | FileProvider + `ACTION_VIEW`,非 PackageInstaller | +| 權限 | `REQUEST_INSTALL_PACKAGES` + 引導 `ACTION_MANAGE_UNKNOWN_APP_SOURCES` | +| flavors | `generic` / `githubPreview` / `fdroid`;**fdroid 版停用更新器** | +| ABI | 用 `SUPPORTED_ABIS.first()` 挑 asset | + +## 11. Obtainium(ImranR98/Obtainium,Android) + +Obtainium 本身即「從 GitHub Releases 更新 App」的工具,其自我更新路徑與它給其他 App 用的路徑同源。 + +### 11.1 GitHub 檢查:API、分頁、認證 + +- **事實**:[`lib/app_sources/github.dart`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart): + - [`L855-L874`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L855-L874) `getLatestAPKDetails`:URL `…/${useTagUrl ? 'tags' : 'releases'}?per_page=100` —— **只發一次請求,沒有分頁迴圈**;`tags` fallback 只在 `trackOnly == true` 時使用。 + - [`L310-L311`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L310-L311) `getAPIHost` → `https://api.github.com`。 + - [`L241-L264`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L241-L264) `getRequestHeaders`:[`L253`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L253) `headers[HttpHeaders.authorizationHeader] = 'Token $token'`;[`L256`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L256) 下載 APK 時 `accept = 'application/octet-stream'`。 + - **事實**:**沒有 `If-None-Match` / ETag 條件請求、沒有 `Cache-Control`**(以該檔與 `app_source.dart` 全文為依據)→ 每次檢查都實打 API,消耗 rate limit。 + - **事實**:認證來源 [`L31`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L31) `github-creds`(密碼欄位,helpUrl 指向 GitHub fine-grained PAT 文檔);[`L39`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L39) `GHReqPrefix`(預設提示 `gh-proxy.com`,helpUrl 指向 `sky22333/hubproxy`);[`L61`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L61) `checkRepoRename`。 + +### 11.2 Rate limit 與認證失敗的 fallback + +- **事實**:[`L957-L970`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L957-L970) `rateLimitErrorCheck`:`if (res.headers['x-ratelimit-remaining'] == '0')` → 由 `x-ratelimit-reset` 算重試時間(fallback 為 now + 3600,見 [`L15`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L15) `_fallbackCacheSeconds = 3600`)→ `throw RateLimitError(remainingMinutes)`。注意該常數是**重試時間的 fallback**,不是回應快取。 +- **事實**:[`L976-L992`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L976-L992) `githubErrorCheck`:先判 rate limit,再判非 rate limit 的 401/403 → `ObtainiumError`;[`L315-L325`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L315-L325) `_isAuthRejection`:401/403 且 body message 含 "access token" / "bad credentials"。 +- **事實**:[`L329-L345`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L329-L345) `_sourceRequestWithAuthFallback`:**去掉 token 重試一次**(`skipAuth=true`,對應 issue #3211)—— 「token 過期不該讓更新完全失敗」的設計。 +- **事實**:[`L266-L288`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L266-L288) `getTokenIfAny`(清掉舊格式的 `username:` 前綴);[`L292`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L292) `getSourceNote` 在沒 token 時給提示。代理:[`L302-L307`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L302-L307) `generalReqPrefetchModifier` 把請求改寫走 GHReqPrefix。repo 改名:[`L347-L351`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L347-L351) `convertStandardUrlToAPIUrl`;[`L360-L406`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L360-L406) `checkForRepositoryRename`(`followRedirects: false`,≥300 就讀 `Location` → 取 `html_url` → 丟 `RepositoryRenamedError`)。 +- **事實**:[`L690-L826`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/app_sources/github.dart#L690-L826) `_fetchReleaseDetails`:排序、prerelease fallback、regex 標題/內文過濾、`effectiveMinUpdateAgeDays`、`verifyLatestTag`(打 `/latest` 驗證)、`NoReleasesError` / `NoVersionError`。 +- **事實**:來源層設定包括 `includePrereleases`、`fallbackToOlderReleases`、`filterReleaseTitlesByRegEx`、`filterReleaseNotesByRegEx`、`verifyLatestTag`、`sortMethodChoice`(date / smartname / none / smartname-datefallback / name)、`useLatestAssetDateAsReleaseDate`、`releaseTitleAsVersion`。 + +### 11.3 四個專案中唯一做真實驗證的 + +- **事實**:[`lib/utils/signing_cert_utils.dart`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/signing_cert_utils.dart): + - [`L13-L19`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/signing_cert_utils.dart#L13-L19) `formatCertHash` = SHA-256 of DER → 大寫、冒號分隔。 + - [`L25-L28`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/signing_cert_utils.dart#L25-L28) `certHashesFromSigningInfo`:多簽章者用 `signingInfo.apkContentSigners`,否則用 `signingCertificateHistory`。 + - [`L43`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/signing_cert_utils.dart#L43) `apkFilesSigningCertHashes`:base + split APK 取聯集。 + - [`L66`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/signing_cert_utils.dart#L66) `parseAllowedSigningCertHashes`;`_certHashHex = RegExp(r'^[0-9a-fA-F]{64}$')`。 +- **事實**:[`lib/providers/apps_provider_install.dart#L1305-L1400`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider_install.dart#L1305-L1400) `_verifyDownloadedApkSignatures` 的三段邏輯: + 1. `userHashes` = 該 App 的 `allowedSigningCertHashes`(使用者預先設定)→ **不符即硬封鎖,無覆寫**(`SigningCertMismatchError(hardBlock: true)`);若 `apkHashes.isEmpty` 而使用者有設定,也封鎖。 + 2. 若 `settingsProvider.verifySigningCertHashes`([`settings_provider.dart#L870-L875`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L870-L875),**預設 true**;本次抽驗確認原始碼為 `_getBool('verifySigningCertHashes') ?? true`)且已安裝版本有 hash,而新 APK 不一致 → 軟性對話框 `SigningCertMismatchDialog(hardBlock: false)`,可「仍然安裝」(背景情境則封鎖)。 + 3. [`L1317`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider_install.dart#L1317) 用 `parseAllowedSigningCertHashes`;[`L1320`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider_install.dart#L1320) `appEntry.certificateHashes`;[`L1454-L1455`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider_install.dart#L1454-L1455) `apkSigningCertHashes` / `apkFilesSigningCertHashes`。 +- **事實(範圍)**:**這仍是簽章比對,不是「發佈者提供的 checksum」驗證。** 全 repo 搜不到 checksum 相關實作;出現的 hash 只有「簽章憑證 hash」與「部分下載/ETag 的識別碼」兩類。 +- **事實(非驗證的臨近機制)**:[`lib/providers/apps_provider.dart#L229-L249`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider.dart#L229-L249) `checkPartialDownloadHashDynamic`:對同一 URL 發兩次 `Range: bytes=0-N` 比對 hash,用途是**偵測遠端檔案已變更**(續傳正確性)。同檔 [`L280-L306`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider.dart#L280-L306) `checkETagHeader` 把 ETag 字串 hash 成 12 碼當識別碼用,**不是**條件請求。 + +### 11.4 下載重試與安裝器 + +- **事實**:[`lib/providers/apps_provider.dart#L172-L217`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider.dart#L172-L217) `downloadFileWithRetry`:對 `ClientException` / `SocketException` / `TimeoutException` / `HttpException` 與 429、≥500 重試;[`L42`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/apps_provider.dart#L42) `_retryDelaySeconds = 5`。 +- **事實**:安裝器抽象在 `lib/installers/`(`Installer` 有 `modeKey`、`canInstallSilently`、`installApk`),實作有 `stock_installer.dart`、`external_installer.dart`、`root_installer.dart`、`shizuku_installer.dart`。 +- **事實**:[`lib/installers/stock_installer.dart`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/installers/stock_installer.dart):[`L3`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/installers/stock_installer.dart#L3) 引入 `android_package_installer`;[`L13`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/installers/stock_installer.dart#L13) `_androidApiLevelS = 31`;[`L25-L73`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/installers/stock_installer.dart#L25-L73) `canInstallSilently`:拒絕 Obtainium 自身的變體、要求 installer-of-record 是 Obtainium 變體、SDK ≥ 31、且目標 App `targetSdkVersion >= sdk-3`;[`L94`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/installers/stock_installer.dart#L94) `AndroidPackageInstaller.installApk(apkFilePath: apkFilePaths.join(','))`(split APK 以逗號串接)。 +- **事實**:[`android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt):[`L30`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt#L30) `APK_MIME = "application/vnd.android.package-archive"`;[`L46`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt#L46) 與 [`L204-L225`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt#L204-L225) 用 `Intent.EXTRA_RETURN_RESULT` 取得安裝結果;[`L308-L311`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt#L308-L311) 用 `ACTION_VIEW` / `ACTION_INSTALL_PACKAGE` 探測裝置支援哪種;[`L323-L325`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt#L323-L325) `FileProvider.getUriForFile(...)`。InstallWatcher 追蹤 package-add broadcast,有取消寬限與 5 分鐘上限。 + +### 11.5 更新節奏與供給鏈延遲設定 + +- **事實**:[`lib/providers/settings_provider.dart`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart): + +| 設定 | 位置 | 預設 | +|---|---|---| +| `updateInterval` | [`L242-L248`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L242-L248) | **360 分鐘**(抽驗:`_getInt('updateInterval') ?? 360`) | +| `updateIntervalSliderVal` | [`L252-L258`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L252-L258) | 6.0 | +| `checkOnStart` | [`L262-L267`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L262-L267) | false | +| `onlyCheckInstalledOrTrackOnlyApps` | [`L754-L759`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L754-L759) | false | +| `minimumUpdateAgeDays` | [`L781-L786`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L781-L786) | 0(抽驗:`?? 0`) | +| `verifySigningCertHashes` | [`L870-L875`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L870-L875) | **true**(抽驗:`?? true`) | +| `enableCertificatePinning` | [`L600-L605`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L600-L605) | false | +| `externalInstallerPackage` | [`L168`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L168) | — | +| `getInstallPermission({enforce})` | [`L342`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/providers/settings_provider.dart#L342) | — | + +- **事實**:[`lib/utils/min_update_age.dart`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/lib/utils/min_update_age.dart):`effectiveMinUpdateAgeDays`(單一 App 的設定覆寫全域)、`isReleaseTooYoung`、`applyMinAgeSuppression`(把「太新」的 release 壓回抑制狀態,等它夠舊再提示,並同步更新 APK URL 的版本)。→ 屬於**供給鏈攻擊緩解**:新版本發佈後先等 N 天再讓人裝。 + +### 11.6 權限 + +- **事實**:[`android/app/src/main/AndroidManifest.xml`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml):[`L61`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml#L61) FileProvider authority `${applicationId}`;[`L86`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml#L86) `REQUEST_INSTALL_PACKAGES`;[`L87`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml#L87) `UPDATE_PACKAGES_WITHOUT_USER_ACTION`;[`L90`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml#L90) `REQUEST_DELETE_PACKAGES`;[`L91`](https://github.com/ImranR98/Obtainium/blob/af286fa8d31d7406d6db167e2314d376d74f7696/android/app/src/main/AndroidManifest.xml#L91) `ENFORCE_UPDATE_OWNERSHIP`;另有 `RECEIVE_BOOT_COMPLETED`、`WAKE_LOCK`、`QUERY_ALL_PACKAGES`、`FOREGROUND_SERVICE`、`POST_NOTIFICATIONS`。 +- **事實**:支持的來源約 35 個(`lib/app_sources/`):github、gitlab、codeberg、sourcehut、sourceforge、fdroid、fdroidrepo、izzyondroid、html、direct_apk_link、telegramapp、apkmirror、aptoide、uptodown、jenkins、rockmods、rustore、samsunggalaxystore、huaweiappgallery、vivoappstore、coolapk、liteapks、apkpure 等。 + +### 11.7 小結 + +| 面向 | Obtainium | +|---|---| +| 來源 | GitHub Releases API(+約 35 個其他來源) | +| 分頁 | 單次 `per_page=100`,**無分頁迴圈** | +| 快取 | **無 ETag / 條件請求** | +| Rate limit | 讀 `x-ratelimit-remaining` / `x-ratelimit-reset`;401/403 去 token 重試 | +| 驗證 | **簽章憑證 hash 比對**(四者唯一)+ `minimumUpdateAgeDays` 延遲 | +| 安裝 | `android_package_installer`(可靜默,條件嚴格)/外掛安裝器/root/Shizuku | +| 頻率 | 預設 360 分鐘;`checkOnStart` 預設關 | +| 忽略版本 | 由 `min_update_age` 與 `includePrereleases` 等來源層設定組合達成 | + +### 11.8 本組驗證方式對照(事實) + +| 專案 | 讀取的來源 | 下載物驗證 | 是否自行安裝 | 安裝權限 | +|---|---|---|---|---| +| NewPipe | 自架 JSON API | 無(API 有 sha256 未用) | 否(`ACTION_VIEW` 交瀏覽器) | 無 `REQUEST_INSTALL_PACKAGES` | +| LX Music Desktop | GitHub Releases(electron-updater)+6 類鏡像 JSON | 無簽章設定 | 是(`quitAndInstall`) | N/A(桌面) | +| Seal | GitHub `/releases` API | **只有檔案大小** | 是(FileProvider + `ACTION_VIEW`) | `REQUEST_INSTALL_PACKAGES` | +| Obtainium | GitHub `/releases?per_page=100` | **APK 簽章憑證 hash 比對** | 是(`android_package_installer` 等 4 種) | `REQUEST_INSTALL_PACKAGES` | + +- **事實**:四個專案**沒有一個**驗證「發佈者公佈的 checksum」;只有 Obtainium 做真實的簽章憑證 hash 比對。 + +--- + +# Part 3 — 發版說明工具與版號策略 + +## 12. release-please(googleapis/release-please) + +- **事實(版本與 metadata)**:最新 release **v17.11.2**(2026-08-24);star 7559;push 於 2026-09-14;License **Apache-2.0**(`gh api repos/googleapis/release-please`)。固定 SHA `edce3d805ef3ac964d1ba2b29b0f42905f2fa412`。 + +### 12.1 做什麼 + +- **事實**:[`README.md#L8-L12`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L8-L12):讀 git 歷史中的 Conventional Commit 訊息,自動產生 CHANGELOG、GitHub Release 與版號 bump。 +- **事實**:[`README.md#L18-L43`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L18-L43)「What's a Release PR?」:維護一個 **Release PR**;squash merge 與 merge commit 兩種都支援。合併該 PR 會 (a) 更新 changelog 檔與語言特定檔案、(b) 打 tag、(c) 建立 GitHub Release。生命週期標籤:`autorelease: pending` / `autorelease: tagged` / `autorelease: published`。 + +### 12.2 可發版單位與策略 + +- **事實**:[`README.md#L143-L151`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L143-L151):可觸發發版的 prefix 是 `feat`、`fix`、`deps`(`chore` / `build` **不算**);Java / Python 另認 `docs`。 +- **事實**:[`README.md#L185-L202`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L185-L202) 策略表,其中 **`dart` = "A repository with a pubspec.yaml and a CHANGELOG.md"**(**本次抽驗逐字確認,見 README 第 186 行**)。其他策略:`simple`(version.txt)、`node`、`python`、`rust`(workspaces 需 manifest-driven release + `cargo-workspace` plugin)、`go`、`java`、`php`、`ruby`、`helm`、`bazel`、`terraform-module`、`krm-blueprint`、`ocaml`、`sfdx`、`elixir`、`expo`。 +- **事實**:Monorepo — [`README.md#L228-L231`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L228-L231)「Supporting Monorepos via Manifest Configuration」→ `docs/manifest-releaser.md`(官方支援)。Bootstrap:[`README.md#L221`](https://github.com/googleapis/release-please/blob/edce3d805ef3ac964d1ba2b29b0f42905f2fa412/README.md#L221) → `docs/cli.md#bootstrapping`。 + +### 12.3 GitHub Actions 整合 + +- **事實**:`googleapis/release-please-action`(Apache-2.0,push 於 2026-08-28)。README 給的基本 workflow: + +```yaml +on: + push: + branches: [main] +permissions: + contents: write + issues: write + pull-requests: write +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: googleapis/release-please-action@v4 + with: + token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }} + release-type: simple +``` + +- **事實**:進階版加 `config-file: release-please-config.json` 與 `manifest-file: .release-please-manifest.json`。Action inputs 另有 `path`、`target-branch`、`include-component-in-tag`(monorepo tag 前綴)、`versioning-strategy`、`release-as`、`skip-github-release`、`skip-github-pull-request`。 + +## 13. git-cliff(orhun/git-cliff) + +- **事實(版本與 metadata)**:最新 **v2.14.2**(2026-09-18);star 12271;License **Apache-2.0 OR MIT**(雙授權;`gh api` 的主 license 欄位回報 Apache-2.0)。固定 SHA `60e0be97e945f71148172675be82399d382c9677`。 +- **事實**:[`README.md#L28`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/README.md#L28):用 conventional commits 與 regex 自訂 parser,從 git 歷史產生 changelog 檔;模板以 config 檔完全可自訂。 +- **事實**:[`README.md#L44`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/README.md#L44) 只連到一篇外部 Substack 文章「Git-cliff and monorepos」→ **官方網站文檔中沒有 monorepo 專章(查不到)**。 +- **事實**:[`README.md#L96`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/README.md#L96):'Licensed under either of Apache License Version 2.0 or The MIT License at your option.' +- **事實(monorepo 實際機制)**:[`website/docs/configuration/git.md#L44-L45`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/website/docs/configuration/git.md#L44-L45): + +```toml +include_paths = ["src/", "doc/**/*.md"] +exclude_paths = ["unrelated/"] +``` + +→ git-cliff 的 monorepo 支援是**用路徑過濾切分**(每個子專案跑一次不同 config),不是 manifest 驅動的版本管理。 +- **事實**:同檔 [`L168-L226`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/website/docs/configuration/git.md#L168-L226) 有 commit preprocessor 與 `commit_parsers`(可用 `{ body = ... }`、`{ footer = "^changelog: ?ignore", skip = true }`、`{ message = ..., body = ..., group = "Deprecation" }`)。[`website/docs/configuration/changelog.md`](https://github.com/orhun/git-cliff/blob/60e0be97e945f71148172675be82399d382c9677/website/docs/configuration/changelog.md):`header`、`header_marker`、`body`、`trim`、`footer` 等模板欄位。 +- **事實(GitHub Actions)**:`website/docs/github-actions/git-cliff-action.md` 的範例:`actions/checkout@v3` 配 `fetch-depth: 0`,再 `uses: orhun/git-cliff-action@v4`,參數 `config: cliff.toml`、`args: --verbose`,env `OUTPUT: CHANGELOG.md`、`GITHUB_REPO: ${{ github.repository }}`;文檔提到專案自己的 `cd.yml` 用這個 action 設定 GitHub release notes。`orhun/git-cliff-action` 為 Apache-2.0,push 於 2026-09-18。 +- **事實(形態)**:git-cliff 是**離線/CI 皆可**的單一 binary(Rust),不綁 Node 生態;輸出是檔案 + 可選的 GitHub release notes。 + +## 14. semantic-release(semantic-release/semantic-release) + +- **事實(版本與 metadata)**:最新 **v25.0.9**(2026-08-05);star 24070;License **MIT**;push 於 2026-09-26。固定 SHA `e8c2436e5704a6d1fa5b4aa69238f50edbe586bf`。 +- **事實**:[`README.md#L29-L44`](https://github.com/semantic-release/semantic-release/blob/e8c2436e5704a6d1fa5b4aa69238f50edbe586bf/README.md#L29-L44):全自動發版 —— 決定下一個版號、產生 release notes、發佈套件。依 git merge 決定要發到哪些 distribution channel(npm dist-tags)。透過 plugins 支援任何套件管理器/語言。npm provenance on GitHub Actions。 +- **事實**:[`README.md#L66-L73`](https://github.com/semantic-release/semantic-release/blob/e8c2436e5704a6d1fa5b4aa69238f50edbe586bf/README.md#L66-L73):設計上在 CI 上於 release branch 的每次成功 build 後執行;master/main/next/beta 這類分支上每個 commit 都會觸發。 +- **事實**:[`README.md#L75-L102`](https://github.com/semantic-release/semantic-release/blob/e8c2436e5704a6d1fa5b4aa69238f50edbe586bf/README.md#L75-L102) 發版步驟表:Verify Conditions → Get last release → Analyze commits → Verify release → Generate notes → Create Git tag → Prepare → Publish → Notify。 +- **事實**:[`README.md#L104-L110`](https://github.com/semantic-release/semantic-release/blob/e8c2436e5704a6d1fa5b4aa69238f50edbe586bf/README.md#L104-L110) 需求:git repo、能設 credentials 的 CI、git CLI、符合版本要求的 Node.js。**README 中沒有 monorepo 專章(查不到官方 monorepo 支援)**。 +- **事實(commit 慣例與版號對映)**:[`README.md#L52-L64`](https://github.com/semantic-release/semantic-release/blob/e8c2436e5704a6d1fa5b4aa69238f50edbe586bf/README.md#L52-L64):**預設用 Angular Commit Message Conventions**,可用 `@semantic-release/commit-analyzer` / `@semantic-release/release-notes-generator` 的 `preset` / `config` 改。 + +| Commit | 版號 | +|---|---| +| `fix(pencil): …` | Patch | +| `feat(pencil): …` | Minor | +| `perf(...)` + footer `BREAKING CHANGE:` | Major | + +(表中註明 `BREAKING CHANGE: ` token 必須在 **footer**。) +- **事實(內部常數)**:`lib/definitions/constants.js`:`RELEASE_TYPE = ["patch", "minor", "major"]`、`FIRST_RELEASE = "1.0.0"`、`FIRSTPRERELEASE = "1"`、`COMMIT_NAME = "semantic-release-bot"`、`RELEASE_NOTES_SEPARATOR = "\n\n"`。`lib/definitions/plugins.js`:只有 `analyzeCommits` 有明確預設(`["@semantic-release/commit-analyzer"]`);其 `preprocess` 會過濾符合 `/\[skip\s+release]|\[release\s+skip]/i` 的 commit —— 這是「跳過發版」的官方語法。 +- **事實(plugin 分工)**:`@semantic-release/changelog`:step `prepare`「Create or update a changelog file in the local project directory」;`changelogFile` 預設 `CHANGELOG.md`;其 README 帶一段**質疑「把 release notes 寫進檔案是否值得這個複雜度」**的警告。`@semantic-release/github`:step `publish`「Publish a GitHub release, optionally uploading file assets」;`addChannel` 更新 release 的 pre-release 欄位;`success` / `fail` 對 issue/PR 留言或開關 issue;需 `GITHUB_TOKEN` 或 `GH_TOKEN`。`@semantic-release/commit-analyzer` 與 `@semantic-release/release-notes-generator` 底層皆為 conventional-changelog。`@semantic-release/npm`:`verifyConditions`(NPM_TOKEN/.npmrc)、`prepare`(更新 package.json 版本、建立 tarball)。 +- **事實(GitHub Actions)**:來源 `https://semantic-release.org/recipes/ci-configurations/github-actions/`。**限制聲明**:該頁 YAML **無法由擷取工具逐字重現**(工具做了摘要/重建),以下為**重建的結構**,非逐字引用:一個 "Verify and Release" workflow;`verify` job(`actions/checkout@v4` `fetch-depth: 0` → `actions/setup-node@v4` → `npm clean-install` → `npm audit signatures` → `npm test`);`release` job(權限 `contents: write`、`issues: write`、`pull-requests: write`、`id-token: write`;`run: npx semantic-release`;`env: GITHUB_TOKEN`)。用 trusted publishing 可免 NPM_TOKEN。警告:不要在 setup-node 設 `registry-url`(會導致 `EINVALIDNPMTOKEN`)。另有使用 `actions/create-github-app-token@v1` 的變體。 + +## 15. conventional-changelog(conventional-changelog/conventional-changelog) + +- **事實(metadata)**:License **ISC**;star 8511;push 於 2026-09-25。repo 採**逐套件 tag**,最新 tag 為 `template-v1.4.0`(2026-08-18),非單一主版本號。固定 SHA `f90c80e9fe02146c1018fa1d78dea738809ab102`。npm 實測(registry.npmjs.org):`conventional-changelog` latest = **8.1.3**;`conventional-changelog-cli` latest = **5.0.0**。 +- **事實**:[`README.md#L9`](https://github.com/conventional-changelog/conventional-changelog/blob/f90c80e9fe02146c1018fa1d78dea738809ab102/README.md#L9):'Generate a CHANGELOG from git metadata.' +- **事實**:README 推薦的上層工具:**`commit-and-tag-version`**(npm `version` 指令的 drop-in replacement)、`semantic-release`、`simple-release-action`(README 描述其「Supports monorepos and extensibility via addons」)。 +- **事實**:README 列出的模組:`conventional-changelog`(full-featured CLI)、`standard-changelog`(Angular 格式 CLI)、`conventional-recommended-bump`,加上 `conventional-changelog-angular`、`conventional-changelog-conventionalcommits`、`conventional-changelog-preset-loader`、`conventional-changelog-writer`、`conventional-commits-filter`、`conventional-commits-parser`、`@conventional-changelog/git-client`、`@conventional-changelog/template`。 +- **事實**:README 內附一個 agent skill `conventional-commit-message`(在 `skills/` 下),可用 `npx skills add conventional-changelog/conventional-changelog --skill conventional-commit-message` 安裝。 +- **事實**:本身是套件 monorepo,但**沒有內建的 monorepo「發佈」支援**;monorepo 需求由 README 指向 `simple-release-action`。 + +### 15.1 standard-version 已 deprecated + +- **事實**:`conventional-changelog/standard-version` README **第 3 行**逐字:「**`standard-version` is deprecated**. If you're a GitHub user, I recommend [release-please]… you can use the [commit-and-tag-version] fork.」 +- **事實**:該 repo `archived=false`,最後 push 2026-07-16,最新 tag v9.5.0(2022-05-15),License ISC。 +- **事實**:**npm registry 的 `standard-version` 沒有 `deprecated` 欄位**,`dist-tags.latest = 9.5.0`(實測)→ deprecation 只在 README 宣告,`npm install` 不會警告。 +- **事實**:官方推薦的後繼者 `absolute-version/commit-and-tag-version`:ISC,push 於 2026-09-21,最新 v13.2.1(2026-09-14)。 + +### 15.2 四個工具的取捨對照 + +| 工具 | 語言/生態 | 輸出 | Monorepo | 備註(事實) | +|---|---|---|---|---| +| release-please | 語言無關(Node action) | Release PR → tag + GitHub Release(可含 changelog 檔) | 官方 manifest 支援 | **有 `dart` 策略**(pubspec.yaml + CHANGELOG.md);Release PR 模式讓版本變更可審 | +| git-cliff | Rust binary | changelog 檔 + 可選 release notes | 路徑過濾(非 manifest) | 可本機與 CI 跑;模板自訂彈性最大 | +| semantic-release | Node | npm/其他 channel 發佈 + 可選 changelog 檔 + GitHub Release | **無官方支援** | 綁 Node 生態;強項在「發佈套件」 | +| conventional-changelog | Node 函式庫 | changelog 檔(函式庫層) | 無(指向 `simple-release-action`) | 適合作為底層 parser | + +## 16. Conventional Commits 1.0.0 spec + +- 來源:官方網站 `https://www.conventionalcommits.org/en/v1.0.0/`;原始 markdown 在 `conventional-commits/conventionalcommits.org`(SHA `7d293dc59e88abc8ce6c6698344d4da518ff3f27`,`content/v1.0.0/index.md`)。 +- **事實(格式)**:`L21`:`[optional scope]: `;`L44`:scope 寫在括號內,例 `feat(parser): add ability to parse arrays`。 +- **事實(型別與版號對應)**:`L33` `fix:` → **PATCH**;`L34` `feat:` → **MINOR**;`L35` **BREAKING CHANGE** —— footer 含 `BREAKING CHANGE:`,或**在 type/scope 後加 `!`**,代表破壞性 API 變更(對應 **MAJOR**);BREAKING CHANGE 可屬於任何 type。 +- **事實**:`L37-L38` 其他型別(依 `@commitlint/config-conventional`,源自 Angular 慣例):`build:`、`chore:`、`ci:`、`docs:`、`style:`、`refactor:`、`perf:`、`test:` 等;`L42`:這些額外型別**沒有隱含的 semver 效果**。 +- **事實(規範細節)**:`L119-L122` BREAKING CHANGE footer 必須大寫 + 冒號 + 空格 + 描述;若寫在 prefix,必須是「緊接在 `:` 前加 `!`」,此時 footer 可省略。`L125-L126`:單位(unit)**不得**被視為大小寫敏感,**唯獨 BREAKING CHANGE 必須大寫**;`BREAKING-CHANGE` 作為 footer token 時與 `BREAKING CHANGE` 同義。 + +--- + +# 跨專案事實對照 + +1. **來源**:多數專案從 GitHub Releases 或自架靜態 JSON 讀版本。NewPipe 的自架 API 是唯一「與 GitHub 解耦」的例子,代價是自維托管。LX Music 的六類鏡像清單對應「中國可達性」需求。 +2. **驗證**:11 個應用專案中,**只有 Obtainium** 做真實的簽章憑證 hash 比對;**沒有任何一個**驗證發佈者公佈的 checksum(Spotube 的 release 附 checksums 但 app 端不驗;NewPipe 的 API 給 sha256 但 app 端不讀)。 +3. **下載+安裝的實現率**:桌面端由 Electron/Sparkle 系承擔(LX Music、AppFlowy macOS);Android 端只有 Seal 與 Obtainium 自己裝。**7 個 Flutter 專案(Part 1)無一在 Android 做 in-app 下載安裝 APK。** +4. **Android 安裝權限**:NewPipe 完全不做安裝(`ACTION_VIEW` 交棒瀏覽器,manifest 無 `REQUEST_INSTALL_PACKAGES`);Seal 與 Obtainium 自己裝,都要 `REQUEST_INSTALL_PACKAGES` + 引導 `ACTION_MANAGE_UNKNOWN_APP_SOURCES`。 +5. **F-Droid 管道**:Seal 用 product flavor 讓 F-Droid 版停用應用內更新器(`isFDroidBuild()`)。 +6. **頻率與忽略**:NewPipe 把節奏交給伺服器(`expires` 夾 6–72h)、無忽略版本;LX Music 有忽略版本、失敗提示節流 7 天;Obtainium 有完整間隔設定(預設 360 分)+ `minimumUpdateAgeDays` 供給鏈延遲;Namida 有 2 小時節流與 beta 獨立 repo。 +7. **GitHub API 的使用品質**:Obtainium 對 GitHub API 單次 `per_page=100`、無分頁迴圈、無 ETag;Namida 匿名(`token = null`)+2 小時節流;Spotube/Hiddify/Harmonoid 皆匿名打 `releases/latest`。 +8. **發版工具**:`release-please` 有現成 `dart` 策略(pubspec.yaml + CHANGELOG.md)與官方 monorepo manifest 支援;`git-cliff` 只產生 changelog 檔、monorepo 靠路徑過濾;`semantic-release` 無官方 monorepo 支援;`standard-version` 已 deprecated(僅 README 宣告,npm 無標記),後繼者為 `commit-and-tag-version`。 +9. **Release notes 自動化在 OSS 並不普遍**:LocalSend 用 `release-drafter`、Hiddify 用 `gitchangelog`+mustache、Namida 自寫 Python 依 conventional prefix 分類、AppFlowy 用 sed 抽 CHANGELOG 段落、LX Music 純手寫;Spotube/Finamp/Harmonoid 的產生方式查不到。 +10. **Windows 打包分歧**:Inno Setup(LocalSend、Spotube、AppFlowy、Harmonoid)、只有 MSIX 且明說沒有傳統安裝器(Finamp)、`flutter_distributor` 產 exe/msix/zip(Hiddify)。 + +--- + +# 本次查證中最不確定的事實 + +1. **AppFlowy 的版本號到底是什麼** —— tag `0.14.5` 對上 pubspec `0.11.4`,而 app 內版本取自 `packageInfo.version`。tag 只以 `--env APP_VERSION` 傳給 cargo make(`tool.dart` L41),**沒有改寫 pubspec**;macOS Info.plist/Windows exe 版本資源是否被注入、`VersionChecker` 實際比到哪個數字,**查不到**。若版本注入失敗,appcast 的版本比較可能恆為「有新版本」或永遠不觸發。 +2. **AppFlowy Windows 是否真的沒有可用 feed** —— 程式碼指名 `appcast-windows-x86_64.xml`,實查 0.13.0/0.14.0/0.14.5 三個 release 的 assets 都沒有它。但「官方是否在別處(官網 CDN)另發 Windows appcast」**查不到**;目前只能說「release assets 內沒有」。 +3. **Hiddify appcast 路徑是否已完全廢棄** —— appcast 停更在 0.13.6(2024-01)、無簽章、含壞 URL,實務上不會觸發更新;但程式碼仍同時掛著 `upgrader`+appcast 與自寫 API 兩條路徑,**兩者誰先生效/`upgrader` 是否已被停用**,程式碼內沒有明確開關可證。 +4. **Harmonoid 的版本比較實作** —— 依賴 `identity` 走 git 子模組 `external/identity`,tarball 內不存在 → `compareVersions` 的實際行為(是否支援前綴 `v`、是否處理 beta)**查不到**。 +5. **NewPipe 的 `@xml/nnf_provider_paths` 懸空引用** —— 本次抽驗確認該 SHA 的完整 tree(`truncated: false`)中確實沒有這個檔案、直接取檔回 404,但**為何** manifest 仍引用它(分支改動中間狀態?改名殘留?)**查不到**。 +6. **LX Music 的 macOS 自動更新是否可用** —— 打包只有 `dmg` 沒有 `zip`;repo 內完全沒有 `verifyUpdateCodeSignature` / `publisherName`,electron-updater 的 Windows 預設驗章行為在該套件內,**無法從本 repo 確認**。 +7. **semantic-release 的 GitHub Actions YAML 無法逐字重現** —— 擷取工具只回摘要,文中為重建結構;另 conventional-changelog 的 monorepo 支援只有 README 連到 `simple-release-action`,官方文檔**查不到**。 From 2a2ad25110e09fb15f23b4f887e0d050837d0e87 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:41:49 +0800 Subject: [PATCH 078/133] chore(task): record release-please decision --- .trellis/tasks/09-28-design-release-update/prd.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md index 483f157d7..5458d7aec 100644 --- a/.trellis/tasks/09-28-design-release-update/prd.md +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -49,12 +49,16 @@ ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身 - **切換相容(由 ADR 0008 推得)**:舊版 v1.x 的更新器依檔名挑 asset、驗 checksums、以 `unins000.exe` 判斷安裝版、只比三段版本。 新 App 的第一個版本必須沿用這些檔名、Inno AppId、Android 簽名金鑰,且版本號大於 1.11.0,舊版使用者才能在 App 內直接升上來。 +## 已決定 + +1. **改用 `release-please`(2026-09-28,按建議)**:commit 進 main 時機器人維護「發版 PR」(依 Conventional Commits 算下一版、改 pubspec、寫 `CHANGELOG.md`); + 合併該 PR 即打 tag 並接續建置、驗證、發布;發佈說明與 App 內更新對話框取 CHANGELOG 中該版段落。只看 `app/` 路徑。 + ## 待決定 -1. 版本號與發佈說明的流程:沿用「手動改 pubspec+打 tag、說明由 commit 產生」,或改用 `release-please`(自動改版本、寫 CHANGELOG、合併 release PR 即發版)。 -2. Linux、macOS 的發佈格式與更新方式。 -3. Windows 程式碼簽章(SignPath Foundation 申請)。 -4. 新 App 第一個版本的版本號。 +1. Linux、macOS 的發佈格式與更新方式。 +2. Windows 程式碼簽章(SignPath Foundation 申請)。 +3. 新 App 第一個版本的版本號。 ## 不在範圍 From 6d2350498f2dce2d77c70b16d13a9171112d3a61 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:42:39 +0800 Subject: [PATCH 079/133] chore(task): record linux and macos release formats --- .trellis/tasks/09-28-design-release-update/prd.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md index 5458d7aec..5cd69821c 100644 --- a/.trellis/tasks/09-28-design-release-update/prd.md +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -53,12 +53,15 @@ ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身 1. **改用 `release-please`(2026-09-28,按建議)**:commit 進 main 時機器人維護「發版 PR」(依 Conventional Commits 算下一版、改 pubspec、寫 `CHANGELOG.md`); 合併該 PR 即打 tag 並接續建置、驗證、發布;發佈說明與 App 內更新對話框取 CHANGELOG 中該版段落。只看 `app/` 路徑。 +2. **Linux 只發 AppImage、macOS 發未公證的 zip(2026-09-28,按建議)**: + - Linux:App 內下載驗證後,按「安裝」把舊檔改名、放上新檔、重啟,下次啟動刪舊檔;所在資料夾不可寫時說明並提供「打開下載頁」。不發 Flatpak、deb。 + - macOS:暫不付 Apple 開發者年費;第一次安裝要到系統設定按「仍要打開」;App 內下載驗證後替換整個 App 並重啟。 + 「App 自己下載的檔案不帶 quarantine、更新後不必再放行」為推測,列入 macOS 平台任務的實測。 ## 待決定 -1. Linux、macOS 的發佈格式與更新方式。 -2. Windows 程式碼簽章(SignPath Foundation 申請)。 -3. 新 App 第一個版本的版本號。 +1. Windows 程式碼簽章(SignPath Foundation 申請)。 +2. 新 App 第一個版本的版本號。 ## 不在範圍 From a6621159f010b8fccb66337c09bd6328c9d3ac3d Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:44:25 +0800 Subject: [PATCH 080/133] chore(task): record windows signing decision --- .trellis/tasks/09-28-design-release-update/prd.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md index 5cd69821c..4c3e1f5f1 100644 --- a/.trellis/tasks/09-28-design-release-update/prd.md +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -57,11 +57,13 @@ ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身 - Linux:App 內下載驗證後,按「安裝」把舊檔改名、放上新檔、重啟,下次啟動刪舊檔;所在資料夾不可寫時說明並提供「打開下載頁」。不發 Flatpak、deb。 - macOS:暫不付 Apple 開發者年費;第一次安裝要到系統設定按「仍要打開」;App 內下載驗證後替換整個 App 並重啟。 「App 自己下載的檔案不帶 quarantine、更新後不必再放行」為推測,列入 macOS 平台任務的實測。 +3. **Windows 維持不簽章(2026-09-28,按建議)**:SignPath Foundation 的條款要求「Every release needs manual approval for signing」, + 與自動發布衝突;發行者顯示為 SignPath Foundation;簽章也不保證 SmartScreen 不警告。列為之後的選項。 + 「App 自己下載的安裝檔不帶 Mark of the Web、更新時不跳 SmartScreen」為推測,列入 Windows 更新的實測。 ## 待決定 -1. Windows 程式碼簽章(SignPath Foundation 申請)。 -2. 新 App 第一個版本的版本號。 +1. 新 App 第一個版本的版本號。 ## 不在範圍 From 036bb7130b264ad2a55f2f2bfed00c61aab3f3a9 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:47:13 +0800 Subject: [PATCH 081/133] chore(task): add design and plan for release and update --- .../09-28-design-release-update/design.md | 110 ++++++++++++++++++ .../09-28-design-release-update/implement.md | 14 +++ .../tasks/09-28-design-release-update/prd.md | 15 +-- 3 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 .trellis/tasks/09-28-design-release-update/design.md create mode 100644 .trellis/tasks/09-28-design-release-update/implement.md diff --git a/.trellis/tasks/09-28-design-release-update/design.md b/.trellis/tasks/09-28-design-release-update/design.md new file mode 100644 index 000000000..f7d07aa1f --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/design.md @@ -0,0 +1,110 @@ +# 設計:發版與應用內更新 + +## 1. 發版流程 + +```mermaid +flowchart TD + C["commit 進 main
    (Conventional Commits)"] --> RP["release-please
    維護發版 PR:算版本、改 pubspec、寫 CHANGELOG"] + RP --> M["擁有者合併發版 PR"] + M --> T["同一個 workflow:
    release-please 建 tag 與草稿 release"] + T --> B["建置:Android 4 個 ABI、Windows zip+安裝檔
    (之後加 Linux AppImage、macOS zip)"] + B --> V["verify:檔名集合、checksums、別名一致、
    APK 版本、PE 標頭、舊版更新器相容"] + V --> P["上傳 asset 並轉為正式發布"] +``` + +- **release-please**:manifest 模式,套件路徑 `app/`、策略 `dart`,`CHANGELOG.md` 放在 `app/`;tag 維持 `v{版本}`(關掉 tag 內的元件名)。 + 第一版以 commit 註記 `Release-As: 2.0.0` 指定,之後依 commit 類型自動升版。 +- **同一個 workflow**:GitHub 預設 token 建的 tag 不會觸發其他 workflow,所以 release-please 與建置、驗證、發布放在同一個 workflow, + 以 release-please 的「本次有發版」輸出決定是否往下跑。草稿與建 tag 的確切選項名落地時以 context7 查 release-please 文件確認。 +- **不留人工閘門**(ADR 0006):合併發版 PR 是唯一的人工動作;之後驗證通過就自動轉為正式發布。 +- **版本號**:`pubspec.yaml` 的版本由 release-please 維護;versionCode 沿用 `major*1000000 + minor*1000 + patch`,由 workflow 從 tag 算並注入。 + 舊的 `pubspec_version_test`(擋 pubspec 落後 tag)改成「pubspec 版本等於 `.release-please-manifest.json`」。 +- **發佈說明**:取 CHANGELOG 中該版段落,同一段也是 App 內更新對話框的內容;段落保持短、markdown 淺(舊版對話框的限制沿用)。 +- **flavor**:發版一律 `--flavor prod`(ADR 0015)。 +- 重寫期間不發版;舊專案的 `release.yml` 在切換 PR 前維持原樣(ADR 0008)。 + +## 2. 發佈物 + +| 平台 | 檔案 | 備註 | +|---|---|---| +| Android | `fmp-v{版本}-android-{arm64-v8a,armeabi-v7a,x86_64,universal}.apk` | 同一把簽名金鑰(ADR 0008) | +| Windows | `fmp-v{版本}-windows-installer.exe`、`fmp-v{版本}-windows.zip` | Inno Setup,AppId 沿用;不簽章 | +| Linux | `fmp-v{版本}-linux-x86_64.AppImage` | Linux 平台任務加入 | +| macOS | `fmp-v{版本}-macos.zip` | 未公證;macOS 平台任務加入 | +| 全部 | `fmp-v{版本}-checksums.sha256`、`fmp-latest-*` 別名 | 別名給下載頁連結用,與版本化檔逐位元相同 | + +- iOS 沒有發佈物;iOS 的散佈方式由 iOS 平台任務決定。 +- **切換相容**:舊版 v1.x 更新器依上表的 Android、Windows 檔名挑檔、驗 checksums、以程式目錄有 `unins000.exe` 判斷安裝版、只比三段版本號。 + 新 App 沿用這些檔名、Inno AppId、Android 金鑰,並讓免安裝版 zip 的內容就是完整程式目錄(舊版以 `robocopy /MIR` 覆蓋)。 + verify 加一項「舊版更新器相容」:以舊版的選檔與 checksums 解析規則跑一遍本次產物。 + +## 3. 應用內更新 + +### 3.1 能力與入口 + +- 平台層能力 `appUpdate` 宣告這份安裝能不能更新、屬於哪一種:`androidApk`(附 ABI)、`windowsInstaller`、`windowsPortable`、`linuxAppImage`、`macosApp`、`none`。 + - 判斷:Windows 程式目錄有 `unins000.exe` 為安裝版;Linux 有 `APPIMAGE` 環境變數為 AppImage;iOS、dev flavor、其他安裝方式為 `none`。 + - `none` 時不顯示「檢查更新」,只顯示「前往下載頁」。 +- 入口只有「設定 → 關於 → 檢查更新」,不在啟動或定時檢查(ADR 0017)。 + +### 3.2 檢查 + +- 經網路層一般 client(ADR 0012,不帶憑證)打 `GET api.github.com/repos/1morr/FMP/releases/latest`(不含 prerelease、draft)。 +- 版本比較用 `pub_semver`(含 build number);沒有比目前新的就顯示「已是最新版」。 +- 403/429 且剩餘次數為 0 時轉成 `RateLimited`(附重置時間,ADR 0013),顯示「請於 HH:MM 後再試」。 +- 依能力挑 asset:Android 依 ABI,缺就退 `universal`;Windows 依安裝版或免安裝版;找不到對應檔就顯示「這一版沒有你的平台」。 +- 顯示版本、發佈說明、檔案大小,以及「下載」「前往下載頁」。 + +### 3.3 下載與驗證 + +- 使用者按「下載」才下載,經 ADR 0020 的下載引擎,所以網路層之外不會多一個 HTTP 出口;存到 App 快取目錄的 `updates/`,可暫停續傳。 +- **驗證(B8)**: + - checksums 檔必須存在且列出該檔,否則拒絕並刪檔; + - SHA-256 與大小都要相符; + - GitHub asset 的 `digest` 有值時也必須相同。 + + 驗證失敗刪檔,顯示「檔案驗證失敗,已刪除」。 +- 驗證通過後顯示「安裝」「刪除」;關掉 App 後,已下載的更新保留,下次打開關於頁仍可安裝或刪除。 + +### 3.4 安裝 + +| 類型 | 做法 | +|---|---| +| Android | 經 `PermissionGateway` 取得「安裝未知應用」(ADR 0020),以 FileProvider+`ACTION_VIEW` 開系統安裝器;系統負責同簽章檢查。 | +| Windows 安裝版 | `Process.start` detached:`/SILENT /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /DIR=<目前目錄> /LOG=`,接著結束 App。 | +| Windows 免安裝版 | 見 §3.5。 | +| Linux AppImage | 新檔下載到 AppImage 所在資料夾的 `.new`,驗證、加執行權限,舊檔改名 `.old`、新檔改成原名,執行新檔並結束 App。資料夾不可寫時改提供「前往下載頁」。 | +| macOS | 解壓到快取,由一個小腳本等 App 結束、把舊 `.app` 改名 `.old`、放上新的、`open` 新的。 | + +### 3.5 Windows 免安裝版的替換(B7) + +- 新版 zip 解壓到**程式目錄旁**的 `<目錄>.new`(同一磁碟,才能以改名替換),不再解到 Temp 後用 `robocopy` 複製。 +- 程式目錄內附一個小更新程式 `fmp_updater.exe`(Dart 編譯的主控台程式)。安裝時: + 1. 先把它複製到 Temp 再執行,因為程式目錄等下要被改名; + 2. App 結束; + 3. 更新程式等原 PID 結束; + 4. 把 `<目錄>` 改名為 `<目錄>.old`,再把 `<目錄>.new` 改名為 `<目錄>`; + 5. 任一步失敗就改名回去; + 6. 啟動新的 `fmp.exe`。 +- 使用者資料在 `Documents\FMP`(ADR 0010),不受替換影響。 +- 程式目錄的上層不可寫時,改提供「前往下載頁」。 + +### 3.6 清理(登記在啟動維護清單,ADR 0017) + +- 刪除 `updates/` 中版本 ≤ 目前版本的安裝檔、`.part`、`install.log`(先讀出寫進 log 後再刪)。 +- 刪除 Windows 免安裝版的 `<目錄>.old`、Linux 的 `.AppImage.old`、macOS 的 `.app.old`。 +- 版本比目前新、但使用者還沒安裝的更新保留。 + +### 3.7 狀態與錯誤 + +- 狀態:`Idle`、`Checking`、`UpToDate`、`Available`、`Downloading`、`Downloaded`、`NeedsPermission`、`Installing`、`Failed(AppError)`;以操作代際防競態(舊版做法)。 +- 錯誤依 ADR 0013 分類;下載網址寫 log 前經 ADR 0011 遮蔽。 + +## 4. 相關 ADR 的指向 + +舊 ADR 0004、0006 描述根目錄舊專案,不改動;ADR 0022 的背景寫明延續與差異。 + + +- 0009:能力 `appUpdate` → 0022。 +- 0017:更新檢查只手動,清理登記在啟動維護清單 → 0022。 +- 0020:下載引擎也用於更新檔 → 0022。 diff --git a/.trellis/tasks/09-28-design-release-update/implement.md b/.trellis/tasks/09-28-design-release-update/implement.md new file mode 100644 index 000000000..8f072ea04 --- /dev/null +++ b/.trellis/tasks/09-28-design-release-update/implement.md @@ -0,0 +1,14 @@ +# 執行計畫:第 19 項(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0022-release-and-in-app-update.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§3;背景寫明延續舊 ADR 0004(不上架)與 0006(驗過直接發布)、差異為改用 release-please; + 被否決的方案:手動改 pubspec+打 tag(順序錯就失敗、沒有 CHANGELOG)、Linux 發 Flatpak/deb(App 不能自己換檔)、macOS 付費公證(暫不)、 + Windows 經 SignPath 簽章(每版需手動核准、發行者非 FMP)、`desktop_updater`/`auto_updater`(Linux 不成熟或無 Linux、停滯)、 + 免安裝版解到 Temp 後 `robocopy` 覆蓋(部分成功會留下半套檔案)、只在有 checksums 檔時才驗、自動檢查更新。 +2. [ ] 其他 ADR 各加一句指向 ADR 0022:0009(能力 `appUpdate`)、0017(更新檔清理登記在啟動維護清單)、0020(下載引擎也用於更新檔)。 +3. [ ] `phase2-plan.md`:§3 第 19 項標 ✅(ADR 0022);§7 第一個里程碑加入「release-please 發版 PR 與同一 workflow 的建置發布跑通(可用測試 repo 或 dry-run)」; + §8 延後實測加入:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android 與 Windows 兩種);Windows App 自行下載的安裝檔不帶 Mark of the Web; + macOS App 自行下載的更新不帶 quarantine;Linux AppImage 的改名替換;§10 交接段更新,下一項 3 Toast,下一份 ADR 0023。 +4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [ ] `task.py finish`、`task.py archive design-release-update --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/09-28-design-release-update/prd.md index 4c3e1f5f1..9c30ba03b 100644 --- a/.trellis/tasks/09-28-design-release-update/prd.md +++ b/.trellis/tasks/09-28-design-release-update/prd.md @@ -60,10 +60,11 @@ ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身 3. **Windows 維持不簽章(2026-09-28,按建議)**:SignPath Foundation 的條款要求「Every release needs manual approval for signing」, 與自動發布衝突;發行者顯示為 SignPath Foundation;簽章也不保證 SmartScreen 不警告。列為之後的選項。 「App 自己下載的安裝檔不帶 Mark of the Web、更新時不跳 SmartScreen」為推測,列入 Windows 更新的實測。 - -## 待決定 - -1. 新 App 第一個版本的版本號。 +4. **新 App 第一版為 `2.0.0`(2026-09-28,按建議)**:以 `Release-As: 2.0.0` 指定;大於 1.11.0,舊版更新器必定認為是新版。 +5. **技術選擇(`design.md`)**:release-please 與建置、驗證、發布在同一個 workflow;發佈物檔名、Inno AppId、Android 金鑰沿用並在 verify 加「舊版更新器相容」檢查; + 平台層能力 `appUpdate` 宣告安裝類型;檢查經網路層、`pub_semver` 比版本、處理 rate limit;下載經 ADR 0020 的下載引擎; + checksums 必驗、GitHub `digest` 有值時也要相符;Windows 免安裝版改為「解壓到旁邊再以目錄改名替換」並由獨立的 `fmp_updater.exe` 執行; + 清理登記在啟動維護清單;iOS、dev flavor 不提供應用內更新。 ## 不在範圍 @@ -72,6 +73,6 @@ ADR 0004(不上架商店)、0006(驗過就直接發布)、0008(App 身 ## 驗收條件 -- [ ] ADR 0022 記錄:版本號與發版流程、發佈說明、各平台發佈格式、更新的檢查/下載/驗證/安裝/清理、各平台差異、切換相容、dev flavor 行為。 -- [ ] A6、B7、B8、B9、E17 各自對到決定。 -- [ ] `phase2-plan.md` §3 第 19 項標 ✅ 與 ADR 編號。 +- [ ] ADR 0022 記錄:release-please 發版流程與版本號、發佈說明、各平台發佈物、更新的檢查/下載/驗證/安裝/清理、各平台差異、切換相容、dev flavor 與 iOS 行為、不簽章的理由。 +- [ ] A6(各平台 GitHub Release、iOS 另定)、B7(免安裝版改名替換)、B8(checksums 必驗)、B9(Android 下載後選安裝或刪除)、E17(保留)各自對到決定。 +- [ ] ADR 0009、0017、0020 加上指向 ADR 0022 的一句話;`phase2-plan.md` §3 第 19 項標 ✅,§7/§8 加入實測項目。 From 62b772d7e5d8fb36cfaad9634567edc31c71cdd2 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:49:04 +0800 Subject: [PATCH 082/133] docs(adr): 0022 release and in-app update --- ...atform-layer-with-declared-capabilities.md | 2 +- docs/adr/0017-background-task-scheduler.md | 2 +- docs/adr/0020-downloads-and-permissions.md | 1 + docs/adr/0022-release-and-in-app-update.md | 143 ++++++++++++++++++ 4 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0022-release-and-in-app-update.md diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 03b904a17..3e3403d3b 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -42,7 +42,7 @@ Linux、macOS 加入時要回頭改介面。 `smtc_windows`…)只在實作檔 import。 2. **能力宣告**:每個平台一份不可變的 `PlatformCapabilities`。UI 依它決定是否顯示入口;service 只呼叫介面。 要在執行期才能判斷的(例如 Linux 在 Wayland 下沒有全域快捷鍵)由實作在啟動時寫進宣告。 - 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018;權限由平台層 `PermissionGateway` 統一請求,見 ADR 0020;桌面歌詞的穿透與置頂、Android 懸浮歌詞、iOS Live Activity 歌詞的能力見 ADR 0021。 + 宣告也包含音訊後端與可播格式(容器、編碼、是否支援 FLV/HLS),見 ADR 0018;權限由平台層 `PermissionGateway` 統一請求,見 ADR 0020;桌面歌詞的穿透與置頂、Android 懸浮歌詞、iOS Live Activity 歌詞的能力見 ADR 0021;應用內更新的安裝類型(`appUpdate`)見 ADR 0022。 3. **平台層以外禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件的 import。 4. **不寫空實作**:未驗證的平台宣告全部能力為「沒有」、沒有實作檔;該平台的 child task 開始時才加入實作。 5. **原生呼叫**:新的 MethodChannel 一律用 Pigeon 產生型別安全介面。 diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md index ce4b81eac..55b73267f 100644 --- a/docs/adr/0017-background-task-scheduler.md +++ b/docs/adr/0017-background-task-scheduler.md @@ -29,7 +29,7 @@ ADR 0016 定了網路狀態與「離線中不發背景請求」,把排程、 - 播放位置檢查與存檔:播放核心; - 下載:事件驅動,下載的 ADR 定; - 快取淘汰(ADR 0016)與 log 輪替(ADR 0011):寫入時觸發; - - 更新檢查與插件更新:只手動; + - 更新檢查與插件更新:只手動(App 更新見 ADR 0022,更新檔清理登記在啟動維護清單); - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次。 2. **工作宣告**:id、所屬插件(可空)、間隔(空=關閉)、執行函式。「上次成功時間」存資料庫,重啟後照算。 排程器只用一個計時器,指向最早到期的工作。 diff --git a/docs/adr/0020-downloads-and-permissions.md b/docs/adr/0020-downloads-and-permissions.md index 2f008baa2..4faf0e125 100644 --- a/docs/adr/0020-downloads-and-permissions.md +++ b/docs/adr/0020-downloads-and-permissions.md @@ -35,6 +35,7 @@ - 桌面只在 App 執行中下載:最小化或縮到托盤照常,關閉即暫停,下次啟動自動續傳。 - 請求帶插件候選串流的標頭、不帶帳號憑證(ADR 0012)。這是網路層之外唯一的 HTTP 出口:下載網址寫 log 前經 ADR 0011 的遮蔽函式,測試以假的下載器介面注入。 - 同時下載數 1–5(預設 3)、同一主機最多 2;事件驅動,不輪詢。 + - App 更新檔也經這個引擎下載(ADR 0022)。 2. **流程**:建立紀錄 → 經插件 `resolveStream`(用途=下載、不走記憶體網址快取)→ 下載到 App 私有暫存 → 寫內嵌標籤與 sidecar → 搬到最終位置 → 完成。 最終資料夾不會出現半成品。 3. **續傳與失敗**: diff --git a/docs/adr/0022-release-and-in-app-update.md b/docs/adr/0022-release-and-in-app-update.md new file mode 100644 index 000000000..cabb8052c --- /dev/null +++ b/docs/adr/0022-release-and-in-app-update.md @@ -0,0 +1,143 @@ +# 0022 — 發版與應用內更新:release-please 自動發版、沿用舊版檔名、手動檢查與必驗 SHA-256、各平台以改名替換 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/` 的版本號與 `CHANGELOG.md`、發版 workflow、發佈物與檔名、平台能力 `appUpdate`、更新模組(檢查、下載、驗證、安裝、清理)、 + Windows 免安裝版的更新程式、切換時舊版使用者的升級路徑 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-release-update/research/current-state.md`,已以程式碼核對): + +- 更新只有手動入口;打 GitHub Releases API,未處理 rate limit;版本比較只比三段。 +- SHA-256 只在 release 附 checksums 檔時才驗,否則只比大小(B8)。 +- Windows 免安裝版解到 Temp,以 bat+vbs+`robocopy /MIR` 覆蓋,部分成功會留下半套檔案(B7)。 +- Android 按一次就下載並跳安裝器,沒有「下載完選安裝或刪除」(B9)。 +- Linux、macOS 沒有實作。 +- 發版要先手動改 pubspec、合併後再打 tag,順序錯就失敗;沒有 `CHANGELOG.md`;Windows 不簽章。 + +本 ADR 延續舊 ADR 0004(不上架商店)與 0006(驗過直接發布、不留人工閘門),適用於 `app/`;這兩份仍描述根目錄舊專案。 +與舊做法的差異:版本號與發佈說明改由 release-please 產生。 + +擁有者已定(`phase2-plan.md` §4): +- 只手動檢查,不在啟動或定時檢查; +- 由使用者點「下載」,下載完選「安裝」或「刪除」,點安裝才安裝; +- 重啟後清除舊安裝包; +- 自動發布,說明由 CHANGELOG 或 commit 產生。 + +2026-09-28 另定:release-please、Linux 只發 AppImage、macOS 發未公證 zip、Windows 不簽章、第一版 2.0.0。 + +## 考慮過的選項 + +- **手動改 pubspec+打 tag(舊版)**:否決。順序錯就失敗,也沒有 CHANGELOG。 +- **Linux 發 Flatpak 或 deb**:否決。由系統或套件管理器負責更新,App 不能自己換檔,還要維護上架流程。 +- **macOS 付費公證($99/年)**:暫不採用。代價是新使用者第一次要到系統設定按「仍要打開」。 +- **Windows 經 SignPath Foundation 免費簽章**:暫不採用。條款要求「Every release needs manual approval for signing」,與自動發布衝突;發行者顯示為 SignPath Foundation;簽章也不保證 SmartScreen 不警告。列為之後的選項。 +- **`desktop_updater`、`auto_updater`**:否決。前者 Linux 仍是 candidate、3.x 破壞性變更頻繁;後者沒有 Linux 且停滯。 +- **免安裝版解到 Temp 後 `robocopy` 覆蓋(舊版)**:否決,部分成功會留下半套檔案。 +- **只在有 checksums 檔時才驗(舊版)**:否決(B8)。 +- **自動檢查更新、預發佈頻道**:否決(擁有者要求只手動;功能凍結)。 + +## 決定 + +1. **發版流程**: + - release-please 以 manifest 模式、`dart` 策略管理 `app/`。每次 commit 進 main 就維護一個發版 PR:依 Conventional Commits 算下一版、改 pubspec、寫 `app/CHANGELOG.md`。 + - 合併發版 PR 是唯一的人工動作。同一個 workflow 接著打 tag `v{版本}`、建置、驗證、上傳 asset 並轉為正式發布。 + GitHub 預設 token 建的 tag 不會觸發其他 workflow,所以放在同一個 workflow。 + - 第一版以 `Release-As: 2.0.0` 指定。 + - versionCode 沿用 `major*1000000 + minor*1000 + patch`,由 workflow 從 tag 算出。 + - 舊 `pubspec_version_test` 改為「pubspec 版本等於 release-please manifest」。 + - 發版一律 `--flavor prod`(ADR 0015);重寫期間不發版。 +2. **發佈說明**:取 `CHANGELOG.md` 中該版段落,同一段也是 App 內更新對話框的內容,保持短、markdown 淺。 +3. **發佈物**(GitHub Release): + - Android:`fmp-v{版本}-android-{arm64-v8a,armeabi-v7a,x86_64,universal}.apk`; + - Windows:`fmp-v{版本}-windows-installer.exe`(Inno Setup)、`fmp-v{版本}-windows.zip`; + - Linux:`fmp-v{版本}-linux-x86_64.AppImage`(Linux 平台任務加入); + - macOS:`fmp-v{版本}-macos.zip`(未公證,macOS 平台任務加入); + - 另有 `fmp-v{版本}-checksums.sha256` 與 `fmp-latest-*` 別名(與版本化檔逐位元相同)。 + + iOS 沒有發佈物,散佈方式由 iOS 平台任務決定。Windows 不簽章。 +4. **切換相容**:舊版 v1.x 更新器依上述 Android、Windows 檔名挑檔、驗 checksums、以 `unins000.exe` 判斷安裝版、只比三段版本號。 + - 新 App 沿用這些檔名、Inno AppId、Android 簽名金鑰(ADR 0008); + - 免安裝版 zip 的內容就是完整程式目錄; + - 版本 2.0.0 大於 1.11.0。 + - verify job 加「舊版更新器相容」檢查:以舊版的選檔與 checksums 解析規則跑本次產物。 +5. **能力與入口**: + - 平台層能力 `appUpdate` 宣告安裝類型:`androidApk`(附 ABI)、`windowsInstaller`、`windowsPortable`、`linuxAppImage`、`macosApp`、`none`(ADR 0009)。 + - 判斷方式: + - Windows:程式目錄有 `unins000.exe` 為安裝版; + - Linux:有 `APPIMAGE` 環境變數; + - iOS、dev flavor 與其他安裝方式:`none`,只顯示「前往下載頁」。 + - 入口只有「設定 → 關於 → 檢查更新」(ADR 0017)。 +6. **檢查**: + - 經網路層一般 client(ADR 0012,不帶憑證)打 `releases/latest`;以 `pub_semver` 比版本(含 build number)。 + - 403/429 且剩餘次數為 0 時轉成 `RateLimited`,附重置時間(ADR 0013)。 + - 依能力挑 asset:Android ABI 缺就退 `universal`;找不到就說明「這一版沒有你的平台」。 +7. **下載與驗證**(B8): + - 使用者按「下載」才下載,經 ADR 0020 的下載引擎存到快取目錄 `updates/`,可暫停續傳。 + - checksums 檔必須存在並列出該檔;SHA-256 與大小必須相符;GitHub asset 的 `digest` 有值時也必須相同。 + - 驗證失敗刪檔並告知。 + - 驗證通過後提供「安裝」「刪除」;已下載的更新跨重啟保留。 +8. **安裝**: + - Android(B9):經 `PermissionGateway` 取得安裝未知應用的授權(ADR 0020),以 FileProvider+`ACTION_VIEW` 開系統安裝器。 + - Windows 安裝版:detached 執行 `/SILENT /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /DIR=<目前目錄> /LOG=`,然後結束 App。 + - Windows 免安裝版(B7): + 1. 新版解壓到程式目錄旁的 `<目錄>.new`; + 2. 程式目錄內附 Dart 編譯的 `fmp_updater.exe`,複製到 Temp 後執行; + 3. 更新程式等原 PID 結束,把 `<目錄>` 改名為 `.old`、`<目錄>.new` 改名為 `<目錄>`,任一步失敗就改回,最後啟動新版。 + + 上層不可寫時改提供「前往下載頁」。使用者資料在 `Documents\FMP`,不受影響(ADR 0010)。 + - Linux AppImage:新檔下載到同資料夾的 `.new`,驗證、加執行權限,舊檔改名 `.old`、新檔改成原名,執行新檔並結束。資料夾不可寫時改提供「前往下載頁」。 + - macOS:解壓到快取,由小腳本等 App 結束後把舊 `.app` 改名 `.old`、放上新的、再開啟。 +9. **清理**(登記在啟動維護清單,ADR 0017): + - 刪除 `updates/` 中版本不大於目前版本的安裝檔、`.part`、安裝 log(先把內容寫進 log); + - 刪除 `.old` 目錄或檔案; + - 比目前新但尚未安裝的保留。 +10. **狀態與錯誤**:狀態為 `Idle`、`Checking`、`UpToDate`、`Available`、`Downloading`、`Downloaded`、`NeedsPermission`、`Installing`、`Failed(AppError)`,以操作代際防競態。 + 錯誤依 ADR 0013 分類;網址寫 log 前經 ADR 0011 遮蔽。 + +採用的慣例: +- release-please 的 `dart` 策略與 manifest 模式; +- GitHub Releases API 為更新來源(Spotube、Hiddify、Harmonoid、Namida); +- LX Music、electron-updater 的「下載後由使用者決定安裝」; +- Obtainium 的完整性檢查精神與 GitHub asset digest; +- Inno Setup 官方命令列參數。 + +## 後果 + +- 好的: + - 發版只需合併一個 PR,版本號與 CHANGELOG 不再手動; + - 所有更新檔都必驗 SHA-256; + - 免安裝版不再留下半套檔案; + - 舊版使用者能在 App 內直接升上新 App; + - Linux、macOS 也有更新路徑。 +- 壞的: + - Windows 不簽章,新使用者第一次安裝可能看到 SmartScreen 警告; + - macOS 第一次安裝要手動放行; + - 多一個要維護的 `fmp_updater.exe`; + - 版本號由 commit 類型決定,commit 分類錯會影響版號。 +- 之後要注意: + - SignPath 或 Apple 公證若日後需要,另立決定; + - release-please 草稿與建 tag 的確切選項在落地時以官方文件確認。 + +## 如何確認 + +- 單元測試: + - 版本比較(含 build number); + - 依能力挑 asset 與 ABI 退回; + - checksums 解析、缺檔拒絕、digest 不符拒絕; + - rate limit 轉成 `RateLimited`; + - 狀態機與操作代際; + - 清理只刪不大於目前版本的檔案; + - 更新程式的改名替換與失敗回復(以暫存目錄模擬); + - zip-slip 防護。 +- workflow 測試: + - release-please 輸出為否時不建置; + - verify 的檔名集合、checksums、別名一致、APK 版本、PE 標頭、舊版更新器相容; + - pubspec 版本等於 manifest。 +- 依賴方向(`fmp_layer_imports`,ADR 0015):安裝相關的平台呼叫只在平台層。 +- 延後實測: + - 切換 PR 前,以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版); + - Windows App 自行下載的安裝檔不帶 Mark of the Web; + - macOS App 自行下載的更新不帶 quarantine; + - Linux AppImage 的改名替換。 From 8b825821bbd9d507671796373d7329807fcf56e3 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:49:08 +0800 Subject: [PATCH 083/133] chore(task): archive design-release-update --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 16 +++++++++------- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-28-design-release-update/check.jsonl | 0 .../09-28-design-release-update/design.md | 0 .../09-28-design-release-update/implement.jsonl | 0 .../09-28-design-release-update/implement.md | 10 +++++----- .../2026-09}/09-28-design-release-update/prd.md | 0 .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../research/prior-art.md | 0 .../09-28-design-release-update/task.json | 6 +++--- 11 files changed, 19 insertions(+), 16 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/implement.md (82%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-release-update/task.json (88%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 8039db1bd..ffd1ed5b9 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -125,7 +125,7 @@ flowchart LR | 13 | 14 音樂庫與同步(✅ 完成,ADR 0019) | B1/B2 已定方向,細節依賴 6、1、12、16。 | | 14 | 11 下載與權限(✅ 完成,ADR 0020) | 依賴播放核心的本地播放路徑。 | | 15 | 15 歌詞(✅ 完成,ADR 0021) | 依賴 1、13。 | -| 16 | 19 發版與更新 | 依賴 10、16;你已給出流程要求。 | +| 16 | 19 發版與更新(✅ 完成,ADR 0022) | 依賴 10、16;你已給出流程要求。 | | 17 | 3 Toast | 依賴 2、18。 | | 18 | 5 UI/UX | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | | 19 | 4 Debug 頁 | 把 18、3、8 的成果收成正式工具。 | @@ -225,6 +225,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0014:JS 執行環境(`flutter_js`)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;`flutter_js` 在 Android、Windows 的 Promise/記憶體/啟動成本實測;YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)。 - ADR 0018:兩個後端的前瞻交接(gapless);Android 換歌時不釋放音訊焦點。 - ADR 0015:`fmp_lints` 接上 `app/`,`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)。 +- ADR 0022:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(測試 repo 或 dry-run)。 ## 8. 延後到特定里程碑的實測 @@ -233,6 +234,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 - ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 - ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——`flutter_overlay_window` 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——`flutter_lyric` 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。 +- ADR 0022:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版);Windows App 自行下載的安裝檔不帶 Mark of the Web。macOS 平台任務——App 自行下載的更新不帶 quarantine。Linux 平台任務——AppImage 的改名替換。 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -241,13 +243,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 15 項完成後) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 19 項完成後) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0021`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0022(發版與更新)。 -- **下一項:第 19 項「發版與更新」**(尚未建 task)。已知方向:只手動檢查更新;下載後安裝或刪除;重啟後清掉舊安裝檔;release notes 由 CHANGELOG/commit 自動產生;保留自動發布。 -- 之後順序:3 Toast → 5 UI/UX → 4 Debug 頁 → 7 里程碑定稿。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0022`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0023(Toast)。 +- **下一項:第 3 項「Toast」**(尚未建 task)。 +- 之後順序:5 UI/UX(桌面播放器版面給 2–3 種讓使用者選)→ 4 Debug 頁(含插件開發工具、音源健康檢查)→ 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 - 工作守則(本輪累積): diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 252b6435a..1820571db 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -34,7 +34,8 @@ "09-27-design-playback-core", "09-28-design-library-sync", "09-28-design-downloads", - "09-28-design-lyrics" + "09-28-design-lyrics", + "09-28-design-release-update" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-release-update/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-release-update/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-release-update/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/check.jsonl diff --git a/.trellis/tasks/09-28-design-release-update/design.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/design.md similarity index 100% rename from .trellis/tasks/09-28-design-release-update/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/design.md diff --git a/.trellis/tasks/09-28-design-release-update/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-release-update/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-release-update/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/implement.jsonl diff --git a/.trellis/tasks/09-28-design-release-update/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/implement.md similarity index 82% rename from .trellis/tasks/09-28-design-release-update/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/implement.md index 8f072ea04..06ef65ea0 100644 --- a/.trellis/tasks/09-28-design-release-update/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-release-update/implement.md @@ -1,14 +1,14 @@ # 執行計畫:第 19 項(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0022-release-and-in-app-update.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§3;背景寫明延續舊 ADR 0004(不上架)與 0006(驗過直接發布)、差異為改用 release-please; +1. [x] 核准後寫 `docs/adr/0022-release-and-in-app-update.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§3;背景寫明延續舊 ADR 0004(不上架)與 0006(驗過直接發布)、差異為改用 release-please; 被否決的方案:手動改 pubspec+打 tag(順序錯就失敗、沒有 CHANGELOG)、Linux 發 Flatpak/deb(App 不能自己換檔)、macOS 付費公證(暫不)、 Windows 經 SignPath 簽章(每版需手動核准、發行者非 FMP)、`desktop_updater`/`auto_updater`(Linux 不成熟或無 Linux、停滯)、 免安裝版解到 Temp 後 `robocopy` 覆蓋(部分成功會留下半套檔案)、只在有 checksums 檔時才驗、自動檢查更新。 -2. [ ] 其他 ADR 各加一句指向 ADR 0022:0009(能力 `appUpdate`)、0017(更新檔清理登記在啟動維護清單)、0020(下載引擎也用於更新檔)。 -3. [ ] `phase2-plan.md`:§3 第 19 項標 ✅(ADR 0022);§7 第一個里程碑加入「release-please 發版 PR 與同一 workflow 的建置發布跑通(可用測試 repo 或 dry-run)」; +2. [x] 其他 ADR 各加一句指向 ADR 0022:0009(能力 `appUpdate`)、0017(更新檔清理登記在啟動維護清單)、0020(下載引擎也用於更新檔)。 +3. [x] `phase2-plan.md`:§3 第 19 項標 ✅(ADR 0022);§7 第一個里程碑加入「release-please 發版 PR 與同一 workflow 的建置發布跑通(可用測試 repo 或 dry-run)」; §8 延後實測加入:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android 與 Windows 兩種);Windows App 自行下載的安裝檔不帶 Mark of the Web; macOS App 自行下載的更新不帶 quarantine;Linux AppImage 的改名替換;§10 交接段更新,下一項 3 Toast,下一份 ADR 0023。 -4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 -5. [ ] `task.py finish`、`task.py archive design-release-update --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-release-update --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-release-update/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-release-update/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/prd.md diff --git a/.trellis/tasks/09-28-design-release-update/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-release-update/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/research/current-state.md diff --git a/.trellis/tasks/09-28-design-release-update/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-release-update/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-release-update/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-release-update/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-release-update/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-release-update/task.json b/.trellis/tasks/archive/2026-09/09-28-design-release-update/task.json similarity index 88% rename from .trellis/tasks/09-28-design-release-update/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-release-update/task.json index a4e9fe004..e2f175759 100644 --- a/.trellis/tasks/09-28-design-release-update/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-release-update/task.json @@ -3,7 +3,7 @@ "name": "design-release-update", "title": "Design release and in-app update", "description": "Phase-2 item 19: release pipeline, versioning, changelog-driven notes, in-app manual update on each platform, checksums", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 9d90de229ca7647adc1848eb26ca662901eeebf2 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 17:49:39 +0800 Subject: [PATCH 084/133] chore(task): start design-toast --- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .trellis/tasks/09-28-design-toast/check.jsonl | 0 .../tasks/09-28-design-toast/implement.jsonl | 0 .trellis/tasks/09-28-design-toast/prd.md | 19 ++++++++++++++ .trellis/tasks/09-28-design-toast/task.json | 26 +++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 .trellis/tasks/09-28-design-toast/check.jsonl create mode 100644 .trellis/tasks/09-28-design-toast/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-toast/prd.md create mode 100644 .trellis/tasks/09-28-design-toast/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 1820571db..f67cd5e93 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -35,7 +35,8 @@ "09-28-design-library-sync", "09-28-design-downloads", "09-28-design-lyrics", - "09-28-design-release-update" + "09-28-design-release-update", + "09-28-design-toast" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-toast/check.jsonl b/.trellis/tasks/09-28-design-toast/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-toast/implement.jsonl b/.trellis/tasks/09-28-design-toast/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-toast/prd.md b/.trellis/tasks/09-28-design-toast/prd.md new file mode 100644 index 000000000..441f8bc0e --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/prd.md @@ -0,0 +1,19 @@ +# Design unified toast + +## Goal + +Phase-2 item 3: single toast entry, appearance and placement per form factor, queueing, developer details, visibility over every route + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-toast/task.json b/.trellis/tasks/09-28-design-toast/task.json new file mode 100644 index 000000000..a80b8ed12 --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-toast", + "name": "design-toast", + "title": "Design unified toast", + "description": "Phase-2 item 3: single toast entry, appearance and placement per form factor, queueing, developer details, visibility over every route", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From f4ea9b68fc1bc5b1e9a7ebcb07c5b864277da663 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:06:25 +0800 Subject: [PATCH 085/133] chore(task): add toast research and draft requirements --- .trellis/tasks/09-28-design-toast/prd.md | 59 ++- .../research/current-state.md | 127 +++++++ .../research/packages-and-platform.md | 205 +++++++++++ .../09-28-design-toast/research/prior-art.md | 346 ++++++++++++++++++ 4 files changed, 726 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-toast/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-toast/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-toast/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-toast/prd.md b/.trellis/tasks/09-28-design-toast/prd.md index 441f8bc0e..d3d74c3a8 100644 --- a/.trellis/tasks/09-28-design-toast/prd.md +++ b/.trellis/tasks/09-28-design-toast/prd.md @@ -1,19 +1,56 @@ -# Design unified toast +# 設計:統一 Toast(階段二第 3 項) -## Goal +## 目標 -Phase-2 item 3: single toast entry, appearance and placement per form factor, queueing, developer details, visibility over every route +為 `app/` 定下單一的提示入口、各裝置的外觀與位置、排隊與去重、開發者模式的「詳細」、在所有畫面上都看得到的層級,以及無障礙。產出 ADR 0023。技術設計見 `design.md`,執行步驟見 `implement.md`。 -## Requirements +依據:parent `prd.md` 階段二第 3 項;`docs/audit/questions.md` G9;ADR 0011(錯誤歷史=統一錯誤經 log 門面寫入、Debug 頁篩選;所有展示請求內容處經同一遮蔽函式)、 +ADR 0013(錯誤呈現表;同類別+同音源短時間只提示一次;背景工作不跳 toast、只在對應畫面顯示狀態;開發者模式附「詳細」)、ADR 0021(歌詞子視窗與 Android 懸浮窗是獨立 engine)。 -- TBD +## 現況(`research/current-state.md`,關鍵項已以程式碼核對) -## Acceptance Criteria +- SnackBar 只在 `lib/core/services/toast_service.dart:109` 建立,外觀統一:`floating`、四色、錯誤/警告/帶動作 3 秒、其他 1.5 秒、沒有關閉鈕。 +- **入口有三條並存**:`ToastService.failure(context, e)`、`ToastService.error(context, 翻譯(userMessageFor(e)))`、背景 stream(`showError`/`showInfo`/`showWarning`/`showSuccess`); + 靜態呼叫共 161 處、散在 45 個檔(`success` 60、`error` 42、`show` 26、`warning` 14、`failure` 13、`showWithAction` 6)。 +- **不排隊、直接覆蓋**:送出前先 `clearSnackBars()`+`removeCurrentSnackBar()`(`toast_service.dart:240-241`)。 +- 背景 stream 只有 `app_shell.dart:44` 在聽;電台錯誤另由首頁與電台頁各自監聽,停在其他頁看不到。`app.dart` 沒設 `scaffoldMessengerKey`; + 全螢幕播放頁與電台播放頁掛在根 Navigator 上(`router.dart:292-306`),是否看得到提示未實測(G9 的推測)。歌詞子視窗有自己的 `MaterialApp`,完全收不到。 +- **開發者模式對提示沒有任何影響**,沒有「詳細」按鈕;最接近的是 log 檢視頁(500 筆、級別篩選、單筆 stack、匯出)。 +- `user_message.dart` 宣稱不含例外原文,但非預期例外會以 `e.toString()` 上畫面;`audio_provider.dart:1988` 直接把 `e.message` 餵給提示。 + static-rule `error_presentation_static_rule_test.dart` 有兩條只掃 `lib/ui`,所以漏掉;沒有禁止直接建 `SnackBar(` 的規則。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- **Material 3**:一次只顯示一條、最多一個動作、無動作 4–10 秒、底部並避開 FAB 與導覽列、大螢幕維持 40–60 字行長、polite live region 且不搶焦點。M3 的 snackbar 頁沒有「錯誤」用法,嚴重或持續的錯誤改用對話框或就地狀態。 +- **Fluent 2**:in-app toast 用於「有用但不關鍵」的訊息,無動作 7 秒、最多疊 4 條;關鍵訊息用 Dialog、欄位錯誤或 Message bar。Windows 系統層通知是另一回事(出現在 App 視窗外)。 +- **Apple HIG**:沒有 toast;錯誤用 Alert 或就地狀態。 +- **Flutter App**:Finamp、Immich、LocalSend、AppFlowy 用 Material SnackBar 包一層 service;Spotube 用 `shadcn_flutter` 的 toast,並在對話框內另包一層讓提示浮在對話框之上; + Namida、Harmonoid 自製或原生。沒有一個用 `bot_toast`、`another_flushbar`。Finamp 以錯誤類型鍵(不含網址)去重。 +- **錯誤詳細的慣例**:NewPipe 的提示動作「Report」開詳情頁(動作、請求、服務、版本、系統、時間、可選取的 stack),提供「複製」與「回報到 GitHub」,送出前先顯示隱私說明。 + 共同模式:提示本身不能複製,詳細另開頁面或對話框。 +- **Flutter 行為**:`MaterialApp` 內建的根 `ScaffoldMessenger` 包住 Navigator,但 SnackBar 由 Scaffold 自己畫,後推的全螢幕頁或對話框可能蓋住它(依原始碼推測,待實測); + `showSnackBar` 本身會排隊;3.38 起帶動作的 SnackBar 不自動消失;內建 `Semantics(liveRegion: true)`。 + `SemanticsService.announce` 已棄用(與多視窗不相容),改用 `sendAnnouncement(view, …)`。 +- **套件**:`fluttertoast` 沒有 Windows 實作;`toastification` 六平台、維護中,但沒有動作參數、沒有 live region。 +- **Windows 無障礙樹**:上游有 #190357(推送的頁面內 Slider 永久凍結無障礙樹,open)等;是否波及 overlay 類提示查不到,需實測。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向 + +- 單一入口;開發者模式下錯誤提示附「詳細」,可看錯誤類型、音源、請求摘要、stack trace 並複製;所有錯誤同時進入錯誤歷史(ADR 0011);「詳細」與複製內容經同一遮蔽函式。 +- 呈現規則照 ADR 0013 的表:背景工作不跳提示;同類別+同音源短時間只提示一次;訊息一律 i18n,不顯示例外原文。 + +## 待決定 + +1. 外觀與位置(手機、桌面)。 +2. 排隊方式:新的蓋掉舊的,或依序排隊,或疊放多條。 +3. 「詳細」提供哪些動作(複製、回報到 GitHub)。 + +## 不在範圍 + +- 系統層通知(App 視窗外);Debug 頁本身的版面(第 4 項)。 + +## 驗收條件 + +- [ ] ADR 0023 記錄:單一入口與 API、外觀與位置、排隊與去重、層級(全螢幕頁、對話框、子視窗)、開發者模式詳細、無障礙、閘門。 +- [ ] G9 對到決定。 +- [ ] `phase2-plan.md` §3 第 3 項標 ✅ 與 ADR 編號。 diff --git a/.trellis/tasks/09-28-design-toast/research/current-state.md b/.trellis/tasks/09-28-design-toast/research/current-state.md new file mode 100644 index 000000000..67cee5d63 --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/research/current-state.md @@ -0,0 +1,127 @@ +# 舊專案現況:Toast 與錯誤呈現 + +- 查證日:2026-09-28 +- 查證方式:實讀 `lib/` 原始碼(`檔案:行號` 皆為本分支 `docs/audit` 的當前行號,非 audit 文件抄錄), + grep 統計呼叫點,並與 `docs/audit/devtools.md` §2–§4、`docs/audit/errors.md` §4–§5、`docs/audit/ui.md` §5–§7 交叉核對。 + 沒有執行 App、沒有跑測試;程式碼推不出來的執行期行為標 **推測**。 +- 只描述事實,不含設計建議。 + +## 1. 三種 toast/錯誤呈現寫法 + +全 app 沒有第三方 toast 套件(`pubspec.yaml` 與 `lib/` grep `fluttertoast|bot_toast|oktoast|overlay_support` 無結果)。 +底層一律 `ScaffoldMessenger`,`SnackBar` 的**建構點只有一個**:`lib/core/services/toast_service.dart:109`。 +但在這之上有三條並存的入口路徑: + +| # | 寫法 | 代表位置 | 呼叫點數(grep,不含定義檔與註解) | +|---|---|---|---| +| A | `ToastService.failure(context, e, tag:)` — 內部先 `AppLogger.error` 記原文,畫面顯示 `userMessageFor(e)` | `toast_service.dart:188-198`;例:`lib/ui/pages/search/search_page.dart:731`、`lib/ui/pages/settings/bilibili_login_page.dart:188` | 13 | +| B | `ToastService.error(context, t.xxx(error: userMessageFor(e)))` — log 由呼叫端自己另行 `AppLogger.error` | 例:`lib/ui/pages/settings/log_viewer_page.dart:140-146` | `ToastService.error(` 42 總數中含此類 | +| C | 背景服務走實例 stream:`_toastService.showError(...)` → broadcast stream → 只有 `AppShell` `ref.listen` | `lib/services/audio/audio_provider.dart:641,1604,1993,2685`;`lib/ui/app_shell.dart:44-49` | `showError` 12、`showInfo` 6、`showWarning` 5、`showSuccess` 2 | + +靜態方法呼叫點總數(grep `lib/`):`success` 60、`error` 42、`show` 26、`warning` 14、`failure` 13、`showWithAction` 6。 +使用 `ToastService` 的檔案 45 個。`.trellis/spec/ui/widgets.md`(Reuse 表「Toast」列)明文接受 A 與 B 兩種: +「`ToastService.failure(...)`,或 a plain toast whose template is fed `userMessageFor(e)`」——所以 B 不是違規。 +`toast_service.dart:182-185` 自己的註解卻宣稱 `failure` 是「UI 顯示例外的唯一入口」,與實際不符。 + +**外觀/位置/時長**(由 `buildSnackBar` 統一決定,`toast_service.dart:93-135`): + +- `behavior: SnackBarBehavior.floating`(`:110`)——不是貼底 `fixed`。 +- 依類型上色:info=primary、success=`Colors.green`、warning=`Colors.orange`、error=`colorScheme.error`; + content 是 `Row(icon + Expanded(Text))`,字與圖示寫死白色(`:112-131`)。 +- 時長:error/warning/帶 action 用 `ToastDurations.long`(3000ms),其餘 `ToastDurations.short`(1500ms) + (`:126-131`;常數 `lib/core/constants/ui_constants.dart:162-170`)。 +- `persist: action != null && MediaQuery.accessibleNavigationOf(context)`(`:134`)——只有讀屏模式才讓帶按鈕的 toast 不自動消失。 +- 動作按鈕:`showWithAction` 帶單一 `SnackBarAction`(`:219-235`),6 個呼叫點全在 + `lib/ui/pages/library/playlist_detail_page.dart:981,988,1065,1081,1102,1111`。 +- **不排隊、直接覆蓋**:`:238-243` `showSnackBarNow` 每次都先 `messenger.clearSnackBars()` 再 + `removeCurrentSnackBar()` 才 `showSnackBar`;因此連續錯誤只看到最後一則。 + `:249-257` 的 `showSnackBarWithMessenger`(給「pop 對話框前先擷取 messenger」用)語意相同。 +- 無 `showCloseIcon`、無 `width`/`margin` 客製(皆為框架預設)。 + +## 2. 成功/資訊類提示 + +- 語意上沒有專屬元件,就是 `ToastType.info/success` 的同一顆 SnackBar。 +- 例:「已加入佇列/下一首」`lib/ui/handlers/track_action_coordinator.dart:30,35`; + 清空/刪除播放歷史 `lib/ui/pages/history/play_history_page.dart:919,957,992`; + 電台刪除 `lib/ui/pages/home/home_page.dart:632`。 +- 「已複製」類:`lib/ui/pages/settings/log_viewer_page.dart:294`(`t.logViewer.copied`)、`:404`(`copiedToClipboard`)。 +- 成功/警告語意色不是 `ColorScheme` 給的,是 `ToastService.successColor` / `warningColor` + (`toast_service.dart:42-43`,`Colors.green` / `Colors.orange`),spec 明說要重用這兩個常數。 + +## 3. 背景錯誤的監聽點與看不到的路由 + +- **音樂播放錯誤**:`AudioController` 經 `_toastService`(`audio_provider.dart:75,185`)推 stream; + 全 app 唯一監聽 `toastStreamProvider` 的地方是 `lib/ui/app_shell.dart:44`(`ref.listen`), + 在 `:20-29` 轉成 SnackBar。`AppShell` 由 `ShellRoute` 包住(`lib/ui/router.dart:129-131`)。 +- **電台錯誤**:不走 stream,改由頁面級 `ref.listen(radioControllerProvider, ...)`, + 且各寫一份:`lib/ui/pages/home/home_page.dart:126`、`lib/ui/pages/radio/radio_page.dart:32`。 + 使用者停在音樂庫/搜尋/設定等頁時,電台錯誤不跳 toast(那兩頁的 listen 不存在)。 +- **蓋在 shell 之上的全螢幕路由**:`/player`、`/radio-player` 掛 `parentNavigatorKey: rootNavigatorKey` + (`lib/ui/router.dart:292-306`),是 `ShellRoute` 之外的根層 route。 + repo 自己的 static rule 註解斷言「Riverpod 3 會暫停被不透明路由蓋住的 consumer 的 `ref.watch` 訂閱」 + (`test/providers/static_rules/riverpod3_static_rule_test.dart:29-35`),且 `FMPApp.build` 之所以把 + 副作用 provider 錨在 `MaterialApp` 之上就是為了不被暫停。 + 因此 **推測**:使用者在全螢幕播放頁時,AppShell 的 `ref.listen` 可能被暫停,或即使不暫停, + SnackBar 也畫在被蓋住的 shell Scaffold 上——兩種情形都看不到。audit G9 原文即為此事, + 標「(推測)」,本次同樣**未實測**。 +- **對話框**:`MaterialApp.router`(`lib/app.dart:133`)**沒有設 `scaffoldMessengerKey`**, + 由框架自動建立的根 ScaffoldMessenger 承接。`ScaffoldMessenger` 的 SnackBar 畫在註冊的 Scaffold 內, + 對話框(`showDialog`)是 `Overlay` 上的 route;repo 另備 `showSnackBarWithMessenger` + (`toast_service.dart:249-257`),正是為了在 pop 對話框前先擷取 messenger 避免 context 失效。 +- **Windows 桌面歌詞子視窗**:走 `desktop_multi_window` 獨立 engine(`lib/ui/windows/lyrics_window.dart:28-30` + `lyricsWindowMain` 是 `@pragma('vm:entry-point')`),自己一個 `MaterialApp`(`:159`)與 `Scaffold`(`:681`), + 不共用主視窗的 ScaffoldMessenger;該檔 grep 不到 `ToastService`/`SnackBar`/`ScaffoldMessenger` 使用。 +- **Android 背景**:播放由 `audio_service` 的 `AudioService`(`android/app/src/main/AndroidManifest.xml:63-72`) + 以 foreground media notification 呈現;`AndroidManifest.xml` 沒有 `SYSTEM_ALERT_WINDOW`, + 沒有懸浮窗。背景播放時 Flutter UI 不在前景,in-app toast 無處可顯示——這一段**推測**,未實測。 + +## 4. 錯誤詳細與 log 檢視(開發者模式現況) + +- **開發者模式對 toast 沒有任何影響**:`developerOptionsProvider` 只在 + `lib/ui/pages/settings/widgets/settings_about.dart:7,94` 被讀(版本列連點 7 次解鎖), + `toast_service.dart` 與 `app_shell.dart` grep 不到 `developerOptionsProvider`。**目前沒有**「錯誤 toast 旁附『詳細』按鈕」這種東西。 +- **log 檢視**在 `lib/ui/pages/settings/log_viewer_page.dart`:開頁複製 `AppLogger.logs` 最近 500 筆、 + 訂閱 stream 追加、畫面上限 1000 筆;級別篩選(Debug+/Info+/Warning+/只看 Error)+文字搜尋; + 單筆詳情對話框顯示 error + stack(`:345-415`);可複製全部、長按單筆複製、匯出落盤檔。 +- 開發者模式本身**不持久化**(`lib/providers/settings/developer_options_provider.dart:6-34`,註釋明說不落 `Settings`), + 且 release 版也能解鎖(audit §1.1 已核)。 +- `docs/adr/0011` 目標是「錯誤歷史=統一錯誤型別經 log 門面以 warning/error 寫入,Debug 頁篩選即錯誤歷史」—— + 這是**目標**,舊專案的等價物就是上面的 log viewer;它目前沒有限制等級(warning/error)的「錯誤歷史」檢視。 + +## 5. `user_message.dart` / `failureMessage()` 的角色 + +- `lib/core/errors/user_message.dart` 是「例外 → 一句翻譯」的映射層: + `userMessageFor(error)`(`:72-87`)只認 `SourceApiException`、`DioException`、`SocketException`/`HttpException`/ + `TlsException`、`TimeoutException`、`FormatException`、`PathAccessException`;**其他型別一律回 `t.error.unknownError`**。 +- `sourceErrorReason`(`:29`)/`_reasonFor`(`:35`)以窮舉 `switch` 把 `SourceErrorKind` 映射到 i18n 句; + `rateLimited` 回 `message`、`unknown` 回 `message` 或 `unknownError`——即 adapter 的 `message` 會直接上畫面。 +- `failureMessage(error, stackTrace, what, {tag})`(`:97-105`)= 寫一筆 `AppLogger.error` 後回傳 `userMessageFor(error)`, + 給「provider 的 `state.error` 要直接畫成文字」用(搜尋、詳情、匯入)。 +- **文件與程式碼不一致**:`:64-67` 註解宣稱「回傳值裡不會有 Dart 例外的原文」, + 但 adapter 把非預期例外包成 `message: e.toString()`(例 `lib/data/sources/bilibili_source.dart` 多處), + 而 `unknown` kind 直接顯示 message。audit `errors.md` §4.3 #2 已列。 +- `AudioController` 限流分支直接把 `e.message` 餵 `showWarning`(`lib/services/audio/audio_provider.dart:1988`), + 繞過 `userMessageFor`。 + +## 6. 舊專案相關的 static rule 與測試 + +- 唯一與此相關的靜態規則:`test/ui/static_rules/error_presentation_static_rule_test.dart`,三條: + 1. `lib/ui` 內 async error 分支不得畫 `SizedBox.shrink()`(要 `ErrorDisplay(compact: true)`)。 + 2. 掃**整個 `lib/`**:`t.x(...error: ...)` 模板內不得塞 `e.toString()` 或 `$e` 插值。 + 3. `lib/ui` 內 `ToastService.*`/`ErrorDisplay.*` 的引數不得出現 `e.toString()` / `state.error.toString()` 等原文。 +- **沒有**「禁止直接 `SnackBar(`」的規則,也沒有「禁止繞過 ToastService」的規則; + 現況之所以沒人繞過,是因為全 app 只有一處 `SnackBar(` 建構(`toast_service.dart:109`), + 不是因為有閘門(audit §2.1「繞過的地方:0 處」是事實描述,非規則)。 +- 第 1、3 條的檔案集合由 `_uiDartFiles()`(`error_presentation_static_rule_test.dart:176`)決定,只掃 `lib/ui`; + 第 2 條例外,掃整個 `lib/`(`:35-57`)。 + 所以 `lib/services/audio/audio_provider.dart:1988` 的 `e.message` 漏網(audit 清單 #6 已列)。 +- Trellis spec `.trellis/spec/ui/widgets.md` 的 Gates 段列出上述 rule;Reuse 表列 Toast 入口並要求重用 `successColor`/`warningColor`。 + +## 7. 與本任務相關的 audit 出處 + +- `docs/audit/devtools.md` §2.1(呈現入口一覽、呼叫次數)、§2.3(三種寫法、原文外洩、背景兩種送達、全螢幕推測、 + 互相覆蓋)、§2.4(ErrorDisplay/NetworkStatusBanner/StartupFailureApp)、§3.4(log viewer)、§4(流向圖)、§5(不一致清單 #5–#11)。 +- `docs/audit/errors.md` §4.1(各功能失敗時看到什麼)、§4.2(catch 統計 511 個)、§4.3 #1(翻譯好的錯誤被壓成「發生錯誤」)、#2(原文上畫面)。 +- `docs/audit/ui.md` §5.1–5.2(語意現況:`Semantics(` 12 處、無 `semanticLabel`;播放頁大播放鍵無名稱)、 + §6.3(跨平台一致性)、§7(問題總表)、§8(建議放進決策清單的項目)。 +- `docs/audit/questions.md` G9(`:305`)即本項目的 audit 條目:三種寫法+背景只有 AppShell 在聽+全螢幕看不到(推測)。 diff --git a/.trellis/tasks/09-28-design-toast/research/packages-and-platform.md b/.trellis/tasks/09-28-design-toast/research/packages-and-platform.md new file mode 100644 index 000000000..892ca784a --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/research/packages-and-platform.md @@ -0,0 +1,205 @@ +# Flutter 框架、套件與平台:瞬時訊息(Toast / SnackBar) + +- 查證日:2026-09-28 +- 查證方式:Flutter 官方 API 文件(`api.flutter.dev`,WebFetch 原文)、Flutter 官方部落格與 breaking-changes(context7 `/flutter/website` 與 `/websites/api_flutter_dev`)、 + **本機 Flutter SDK 原始碼**(欄位 `6655482ec06e547f90abf8ae7590466f4415978d`,`3.47.1` stable;下方 permalink 用此 SHA)、 + `pub.dev/api/packages/` 直接核對版本與發布日、`gh api`/`gh search issues` 查上游 issue。 + 本機 toolchain:Flutter 3.47.1 stable / Dart 3.13.1;pub.dev 現行 stable 為 **3.47.5**(2026-09-18,`releases_windows.json`)。 +- 標 `推測` 的是未經官方文件或程式碼直接支持的推論;查不到寫 `查不到`。 + +## 1. Flutter 框架(3.47 世代) + +### 1.1 `ScaffoldMessenger` 與根 messenger + +- `MaterialApp` 內建一個根 `ScaffoldMessenger`:`ScaffoldMessenger` 在 `_materialBuilder` 中**包住整個 child(含 Navigator)** + ——`flutter/flutter@6655482ec0 packages/flutter/lib/src/material/app.dart#L1047`。官方 breaking-change 文件原文: + 「By default, a root `ScaffoldMessenger` is included in the `MaterialApp`」、 + 「The `ScaffoldMessenger` now handles `SnackBar`s in order to persist across routes and always be displayed on the current `Scaffold`.」 + (https://docs.flutter.dev/release/breaking-changes/scaffold-messenger) +- **SnackBar 由 `Scaffold` 自己畫,不是由 messenger 畫**:`ScaffoldMessengerState._updateScaffolds()` 對每個已註冊的 + Scaffold 呼叫 `scaffold._updateSnackBar()`(`.../material/scaffold.dart#L231-L236`),`ScaffoldState` 把 messenger 的第一個 + SnackBar 存進 `_messengerSnackBar`(`#L2320-L2329`)並在 Scaffold 的版面裡建構它(`#L3090-L3099`)。 + → **推測**(框架未明文寫,但由原始碼結構直接推出):SnackBar 被畫在該 Scaffold 的子樹內; + 任何在此之後 push 到同一 Navigator 上的 route(對話框、`showModalBottomSheet`、全螢幕播放頁)在 Overlay 中排在更上層, + 因此**會蓋住 SnackBar**。 +- **多個 Scaffold**:class 文件原文「the ScaffoldMessenger will only present the notification to the **root Scaffold of the subtree of Scaffolds**」 + (https://api.flutter.dev/flutter/material/ScaffoldMessenger-class.html);原始碼 `_isRoot()` + (`.../material/scaffold.dart#L241-L244`)「Nested Scaffolds are handled by the ScaffoldMessenger by only presenting a + MaterialBanner or SnackBar in the root Scaffold of the nested set.」。 + 但 `showSnackBar` 自己的 dartdoc 又寫「Shows a `SnackBar` across **all registered** `Scaffold`s」並說「the snack bar is shown + simultaneously on all of them」(https://api.flutter.dev/flutter/material/ScaffoldMessengerState/showSnackBar.html) + ——同一份文件裡這兩句互相矛盾,`_isRoot()` 才是實際行為。 +- **排隊**:`showSnackBar` 原文「the given snack bar will be added to a queue and displayed after the earlier snack bars have closed.」; + 原始碼 `_snackBars` 是 `Queue`,已顯示時走 `_snackBars.addLast(controller)`(`#L198-L199`、`#L348-L350`)。 + 移除:`hideCurrentSnackBar`(帶動畫)/`removeCurrentSnackBar`(無動畫)。 +- `showSnackBar` **不能在 build 期間呼叫**:dartdoc 原文「The showSnackBar() method cannot be called during build.」, + 建議 `initState`/`didChangeDependencies` 或 `SchedulerBinding.addPostFrameCallback`。 +- **沒有 `ScaffoldMessenger` 祖先會 assert**:`debugCheckHasScaffoldMessenger`; + `ScaffoldMessenger.showSnackBar was called, but there are currently no descendant Scaffolds to present to.`(`scaffold.dart#L317-L322`)。 + +### 1.2 `MaterialApp.scaffoldMessengerKey` + +- dartdoc 原文「A key to use when building the `ScaffoldMessenger`.」若提供,「can be directly manipulated without first obtaining it + from a `BuildContext`」(https://api.flutter.dev/flutter/material/MaterialApp/scaffoldMessengerKey.html)。 +- 這是「服務層不拿 context、也能推 SnackBar」的官方做法(拿 `GlobalKey.currentState` 直接呼叫 `showSnackBar`)。 +- 舊專案的 `lib/app.dart:133` **沒有**設 `scaffoldMessengerKey`,所以只有框架自動的根 messenger,且只能透過 `ScaffoldMessenger.of(context)` 取得。 + +### 1.3 `SnackBar` 屬性(3.47) + +| 屬性 | 文件/原始碼原文 | 備註 | +|---|---|---| +| `behavior` | `fixed`=「Fixes the SnackBar at the bottom of the Scaffold」「will be shown above a `BottomNavigationBar` or a `NavigationBar`」「will cause other non-fixed widgets … to be pushed above」(FAB 為例);`floating`=「shown above other widgets in the Scaffold」 | **兩者都沒有被標 deprecated**(https://api.flutter.dev/flutter/material/SnackBarBehavior.html) | +| `action` | 型別是**單一個** `SnackBarAction?`;dartdoc 沒有寫數量上限 | M3 規範另有「只有一個 action」的設計限制(見 `prior-art.md`) | +| `duration` | 「The amount of time the snack bar should be displayed.」 | 預設為私有常數 | +| `persist` | 「Whether the snack bar will stay or auto-dismiss after timeout.」啟用時「remains visible even after the timeout」直到使用者點 action 或 close icon;「If not provided, but the snackbar action is not null, the snackbar will persist as well.」(https://api.flutter.dev/flutter/material/SnackBar/persist.html) | 預設=`action != null` 就 persist | +| `showCloseIcon` | 「Whether to include a "close" icon widget.」 | 舊專案未使用(`toast_service.dart` 無此參數) | +| 無障礙 | 「A `SnackBar` with an action will not time out when TalkBack or VoiceOver are enabled.」(由 `AccessibilityFeatures.accessibleNavigation` 控制) | 舊專案 `toast_service.dart:134` 用同一旗標決定 `persist` | +| 內建語意 | `snack_bar.dart` 內建 `Semantics(... liveRegion: true ...)`(`@6a19cca`:https://github.com/flutter/flutter/blob/6a19cca56475dbfba1478ee68d7bd0c2ef891da1/packages/flutter/lib/src/material/snack_bar.dart#L828) | SnackBar 本身就是 live region | + +### 1.4 3.38–3.47 的相關變更 + +- **SnackBar 帶 action 不再自動消失**:Flutter 3.38(2026-05)「For more predictable behavior, a SnackBar that includes an action will no + longer auto-dismiss」(PR https://github.com/flutter/flutter/pull/173084,標題「SnackBar with action no longer auto-dismiss」,已 merged)。 + 這正是 `persist` 的預設語意;舊專案 `toast_service.dart:129-134` 的註解已記載,並在非讀屏模式把它覆寫回「會消失」。 +- **`OverlayPortal.targetsRootOverlay` 已 deprecated** → 改用 `OverlayPortal(overlayLocation: OverlayChildLocation.rootOverlay, ...)`; + `Overlay.of`/`Overlay.maybeOf` 不再越過 `LookupBoundary`(https://docs.flutter.dev/release/breaking-changes/deprecate-overlay-portal-targets-root)。 +- **3.38 起 `OverlayPortal.overlayChildLayoutBuilder` 可在樹上任何 Overlay 渲染子節點**(PR #174239),官方部落格舉例正是 + 「show an app-wide notification or other UI that needs to escape the layout constraints of its parent widget」 + (https://flutter.dev/blog/whats-new-in-flutter-3-38)。 +- **`Overlay` 的兩種取得方式**:`Overlay.of(context)` 取最近的(受 `LookupBoundary` 限制),要 Navigator 的那個要 root overlay。 + Navigator 的 Overlay 是最常見的一種(`Overlay` class 文件:「most common to use the overlay created by the `Navigator`」、 + 「the navigator uses its overlay to manage the visual appearance of its routes」)。 +- **Flutter 3.47 沒有 SnackBar/ScaffoldMessenger 的 breaking change**(3.47 的三條 breaking change 是 OpenGL ES render-to-texture、 + iOS/Android `header`/`headingLevel` 語意行為、移除 `describeEnum`;來源 https://docs.flutter.dev/release/breaking-changes)。 + 3.47 的無障礙變更另有:`BlockSemantics` 現在也擋鍵盤焦點、Android 高對比/反色偵測(`MediaQueryData.highContrast`/`invertColors`)。 + (來源為搜尋結果彙整的官方頁面,未逐條在 API 文件核對;標 **推測** 的部分僅指這些摘要之間無衝突。) + +## 2. 套件(資料來自 `pub.dev/api/packages/`,2026-09-28 實查) + +| 套件 | 最新版 / 發布日 | SDK / Flutter 約束 | 平台 | likes / 30d 下載 | 需 context | 佇列 | 去重 | action 鈕 | 無障礙 | +|---|---|---|---|---|---|---|---|---|---| +| `toastification` | 3.2.0 / 2026-04-19 | `>=3.0.0 <4.0.0` / `>=3.38.0` | android, ios, windows, linux, macos, web | 1294 / 205,228 | 否(`ToastificationWrapper`) | 是(`AnimatedList` + `maxToastLimit`=10) | 查不到 | `show()` 無 action 參數;`showCustom` 可自帶 | 原始碼 0 處 `Semantics`/`liveRegion` | +| `bot_toast` | 4.1.3 / **2023-09-19** | `^2.12.0` / `>=2.0.0` | 同上六平台 | 1004 / 377,808 | 否(`BotToastInit`) | 部分(回傳 `cancel`) | 否 | 否 | 0 處 | +| `another_flushbar` | 2.2.4 / 2026-05-15 | `>=2.12.0 <4.0.0` / 未宣告 flutter | 同上六平台 | 1041 / 135,539 | **是**(`Flushbar(...).show(context)`) | 推測 | 查不到 | 是(`mainButton`) | 只有 `Semantics(container: true, explicitChildNodes: true)`,**無 `liveRegion`** | +| `fluttertoast` | 10.0.0 / 2026-07-31 | `>=3.12.0 <4.0.0` / `>=3.44.0` | **只有 android, ios, web**(plugin) | 4135 / 603,523 | 否 | 否(原生 toast) | 否 | 否 | 交給原生 Android Toast,無 Flutter semantics | +| `elegant_notification` | 2.5.1 / 2025-05-08 | `>=2.19.0 <4.0.0` / 未宣告 | 同上六平台 | 521 / 10,685 | **是**(`ElegantNotification(...).show(context)`) | 是(可堆疊) | 查不到 | 是(`action` Widget) | 0 處 | +| `overlay_support` | 2.1.0 / **2022-11-13** | `>=2.14.0 <3.0.0` | 同上六平台 | 701 / 101,836 | 否(`OverlaySupport.global` + `toast()`) | 推測 | 是(以 `key` 取代既有通知) | 否 | 0 處 | + +維護狀態(GitHub repo、最後 push、最新 release): + +- **`toastification`** — `payam-zahedi/toastification`,817★,push 2026-04-19,release v3.2.0(2026-04-19)。維護中。 +- **`bot_toast`** — `MMMzq/bot_toast`,847★,push 2024-05-29,GitHub 最新 release 仍是 4.0.0(2021-02-27)。**停滯約 2 年**,但下載量最高。 +- **`another_flushbar`** — issue tracker 指向 `ideployed/another-flushbar`(建立於 2026-05-10、0★、無 release);首頁改為 `flushkit.dev`。 + 社群舊版是 `AndreHaueisen/flushbar`(push 2023-05-30)。2.x 新增自家遠端通知服務 `FlushbarRemote.init(apiKey:, context:)`, + 並多出 `http`/`shared_preferences`/`url_launcher` 依賴。**推測**是 publisher 易主,建議自行核對再決定是否採用。 +- **`fluttertoast`** — `PonnamKarthik/FlutterToast`,1530★,push 2026-08-10,99 個 open issue,無 GitHub release。 +- **`elegant_notification`** — `koukibadri/Elegant-Notification`,僅 52★,push 2026-02-07,release v2.5.1(2025-05-08),23 open issue。低度維護。 +- **`overlay_support`** — `boyan01/overlay_support`,379★,push 2023-10-04,release v2.1.0(2022-11-13)。**停滯近 3 年**。 + +**值得注意的矛盾**:`overlay_support` 的 pubspec 是 `sdk: >=2.14.0 <3.0.0`(排除 Dart 3),但 pub 的 score tags 同時標了 +`is:dart3-compatible`。**推測** tag 過時、實務上在 Dart 3 專案無法解析;要用前必須實測。 +另 `another_flushbar` 2.2.4 的 pubspec **不再宣告 `flutter:` 區塊**(1.x 有 android/ios/web plugin 條目),但 pub 平台 tag 仍列六平台。 + +**對 FMP(Android + Windows)最要緊的一點**:`fluttertoast` 是 plugin,**沒有 Windows 實作**——在 Windows 上呼叫會是 +`MissingPluginException`,且它不產生 Flutter 端 semantics。`toastification` 是六平台 Dart 套件、維護中、有佇列與上限, +但沒有內建 action 參數與 live region。 + +引用原始碼(pinned SHA): +- `another_flushbar` 的 `Semantics`:`https://github.com/ideployed/another-flushbar/blob/001ce540dd37696a9ae14e5c25151cd66b23ff56/lib/flushbar_route.dart#L99` +- `toastification` `maxToastLimit`:`https://github.com/payam-zahedi/toastification/blob/4f1068f5265a0d189aee6881d125e8a35adec74f/lib/src/core/toastification_config.dart` +- `toastification` `show()` 參數表(無 `action`):同 repo `.../lib/src/core/toastification.dart#L240` +- `overlay_support` 依 `key` 取代:`https://github.com/boyan01/overlay_support/blob/134575de99d34a4fcd366baba2fddd57435c0377/lib/src/notification/overlay_notification.dart` + +(上述四條 GitHub 原始碼為子代理查證,未逐條重跑;版本與發布日已由本代理以 pub.dev API 獨立核對,全部相符。) + +## 3. 無障礙 + +### 3.1 `SemanticsService.announce` 已 deprecated(3.35 起) + +原文(https://api.flutter.dev/flutter/semantics/SemanticsService/announce.html): + +``` +@Deprecated( + 'Use sendAnnouncement instead. ' + 'This API is incompatible with multiple windows. ' + 'This feature was deprecated after v3.35.0-0.1.pre.', +) +static Future announce(String message, TextDirection textDirection, + { Assertiveness assertiveness = Assertiveness.polite }) +``` + +替代品 `sendAnnouncement`(https://api.flutter.dev/flutter/semantics/SemanticsService/sendAnnouncement.html): + +```dart +static Future sendAnnouncement( + FlutterView view, String message, TextDirection textDirection, + { Assertiveness assertiveness = Assertiveness.polite }) +``` + +- 文件:「One can use `View.of` to get the current `FlutterView`.」——**每個 view 各自送**,這是它與 `announce` 的差別 + (`announce` 的 deprecation 理由正是「incompatible with multiple windows」)。 +- 「Not all platforms support announcements. Check to see if it is supported using `MediaQuery.supportsAnnounceOf` before calling this method.」 +- `assertiveness`「Currently, this is only supported by the web engine and has no effect on other platforms.」 +- Android 段:「Android has deprecated announcement events due to its disruptive behavior with TalkBack forcing it to clear its + speech queue … Instead, use mechanisms like `Semantics` to implicitly trigger announcements.」 +- class 層級文件:「When possible, prefer using mechanisms like `Semantics` to implicitly trigger announcements over using this event.」 + (https://api.flutter.dev/flutter/semantics/SemanticsService-class.html) + +### 3.2 live region + +`SemanticsProperties.liveRegion` 原文(https://api.flutter.dev/flutter/semantics/SemanticsProperties/liveRegion.html): + +> 「If non-null, whether the node should be considered a live region. A live region indicates that updates to semantics node are +> important. Platforms may use this information to make polite announcements to the user to inform them of updates to this node. +> An example of a live region is a `SnackBar` widget. **On Android and iOS, live region causes a polite announcement to be generated +> automatically, even if the widget does not have accessibility focus.**」 + +用法:`Semantics(liveRegion: true, child: ...)`(旗標 `SemanticsFlag.isLiveRegion`)。 +**平台缺口**:live region 在 macOS 不作用(flutter/flutter#167318,open,2025-04-16); +Android 在對話框關閉時會誤報(#166258,open)。(#167318 已由 `gh api` 核對存在。) + +### 3.3 SnackBar 的內建無障礙 + +Flutter 的 `SnackBar` 自己就包了 `Semantics(... liveRegion: true ...)` +(`@6a19cca`:https://github.com/flutter/flutter/blob/6a19cca56475dbfba1478ee68d7bd0c2ef891da1/packages/flutter/lib/src/material/snack_bar.dart#L828), +並用 `accessibleNavigation` 決定帶 action 時不自動消失。→ 自製 toast 若要等價無障礙,最省事的做法是照抄 +`Semantics(liveRegion: true)`,而不是呼叫 announce 系列。 + +### 3.4 Windows 無障礙樹與 overlay 類元件的關係 + +- repo 自己記過:`docs/troubleshooting.md` §「Windows:`Failed to update ui::AXTree`」——`OverlayPortal` 的內容實體上掛在 + Overlay 底下、走訪順序卻嫁接回觸發它的元件,落在 Navigator 的 Overlay 時 Windows 的 AccessibilityBridge 收不下, + 整批 update 被丟掉且不會自我修復(**不是噪音**)。已知觸發:Material `Slider`/`RangeSlider` 的數值指示器、 + 滑鼠 hover 的 `Tooltip`。FMP 的避法是 `ScopedSlider` 用 `Overlay.wrap` 給它一個本地 Overlay + (`lib/ui/widgets/controls/scoped_slider.dart:6,43`),並以 `test/ui/static_rules/slider_overlay_static_rule_test.dart` 擋直接建 `Slider(`。 + 上游 issue:**flutter/flutter#182444**(open,2026-02-15,標題「Windows ListView+Tooltip can trigger error: Failed to update + ui::AXTree …」,labels 含 `platform-windows`、`a: accessibility`)。 +- **`docs/troubleshooting.md` 有一句已過時**:它寫「Slider 那一種沒有最小重現…上游沒有提到 Slider」。 + 上游現在有明確的 Slider 版本:**flutter/flutter#190357**(open,2026-07-31,updated 2026-09-25,標題「[Windows] A Slider inside a + pushed route serializes an orphan semantics node, permanently freezing the accessibility tree」)。此行號出處:`docs/troubleshooting.md:40`。 +- 其他相關上游:**#175041**(Windows AccessibilityBridge::CreateRemoveReparentedNodesUpdate crash,open)、 + **#187198**(`OverlayPortal` 在 macOS 上語意樹崩壞,open)、**#190144**(web:Slider 的 value-indicator `OverlayPortal` 產生 + 無 payload 的全視窗語意節點,closed)。 +- **SnackBar/ScaffoldMessenger 的 Windows 或 multi-window 專屬 bug:查不到**(對 `flutter/flutter` 搜 `windows snackbar`、 + `ScaffoldMessenger windows` 皆無對應命中)。唯一的 multi-window 訊號是 `announce` 的 deprecation 理由。 +- **overlay 類 toast 套件是否被點名:查不到**任何 issue 直接指名 toast 套件。**推測**:這類套件(`toastification`、 + `overlay_support`、`bot_toast` 等)都把內容掛進 Overlay(多半是 Navigator 的 root Overlay),機制與 #182444/#190357 同一類, + 因此同屬高風險,但**無實測證據**;`ScopedSlider` 的 `Overlay.wrap` 是本 repo 已驗證的迴避手法。 + +## 4. 多視窗與背景 + +- **Windows 桌面歌詞子視窗**(`desktop_multi_window` 0.3.1,`pubspec.yaml:89`)跑在**獨立 Flutter engine**: + `lib/ui/windows/lyrics_window.dart:28-30` 的 `@pragma('vm:entry-point') void lyricsWindowMain(...)`, + 自己一個 `MaterialApp`(`:159`)與 `Scaffold`(`:681`),不共用主視窗的 `ScaffoldMessenger`。 + 該檔 grep 不到 `ToastService`/`SnackBar`/`ScaffoldMessenger`。子視窗要顯示提示需自備一套(管線、位置、語意都要重做)。 +- 這正是 `SemanticsService.announce` deprecation 理由「incompatible with multiple windows」所指的情境: + 多 engine 下要改用 `sendAnnouncement(view, ...)`,並先以 `MediaQuery.supportsAnnounceOf` 檢查。 +- **Android 背景**:播放由 `audio_service` 0.18.15 的 foreground `AudioService` 承擔 + (`android/app/src/main/AndroidManifest.xml:63-72`;通知 channel 在 `lib/main.dart:175-180`)。 + `AndroidManifest.xml` **沒有** `SYSTEM_ALERT_WINDOW`,App 沒有懸浮窗/overlay 權限。→ 背景播放時 Flutter UI 不在前景, + in-app toast 無處可畫,只能靠 media notification 或事後在畫面顯示狀態。**推測**,未實測。 +- **Windows 系統匣**:`tray_manager` 0.5.3(`pubspec.yaml:56`)只用 `setIcon`/`setToolTip`/`setContextMenu`/`popUpContextMenu` + (`lib/services/platform/windows_desktop_service.dart:111,120,176,199,228`),**沒有** 送 OS 通知的呼叫。 + FMP 目前沒有任何 Windows OS 層通知路徑。 +- Windows OS 層通知(`AppNotificationManager`、WinRT `ToastNotificationManager`)在 Flutter 需另外接 plugin, + FMP 的 `pubspec.yaml` 沒有這類依賴;查不到 FMP 內既有用法。 diff --git a/.trellis/tasks/09-28-design-toast/research/prior-art.md b/.trellis/tasks/09-28-design-toast/research/prior-art.md new file mode 100644 index 000000000..fe8a997ba --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/research/prior-art.md @@ -0,0 +1,346 @@ +# Prior art:統一提示 / Toast / 錯誤呈現 + +- **查證日**:2026-09-28 +- **查證方式**: + - 設計規範:直接讀官方規範頁,逐字引用,網址附於各條。M3 Snackbar、Fluent 2 Toast / Message bar、Apple HIG Alerts 由本 agent 於 2026-09-28 親自以 `tavily-extract`(`extract_depth: advanced`,因 `m3.material.io` 與 `fluent2.microsoft.design` 為 JS 渲染,`WebFetch` 只取得到標題)與 `WebFetch`(`developer.apple.com`)重新抓取核對;其餘條目由子代理抓取後附 URL。 + - Flutter 開源 App:以 `--depth 1` clone 或 `gh api` + `raw.githubusercontent.com` 讀原始碼,`grep` 定位。所有 repo 的 commit SHA 已用 `gh api repos///commits/` 驗證存在(見下表);行號以該 SHA 為準。 + - 所有引用行號本 agent 已逐一開原始檔核對(少數與子代理原報告不同處已修正,見「與子代理報告的差異」)。 + - **本檔不含任何 FMP 內部程式碼引用**;FMP 現狀見同目錄 `current-state.md`。 +- **限制**:未執行任何 App,未打任何音樂平台 API。開源 App 的行為描述一律為「讀原始碼得到的靜態事實」,不是實機觀察;凡屬推論一律標「推測」。 + +## SHA 對照表(2026-09-28 驗證) + +| App | repo | default branch | 本檔使用 commit | +|---|---|---|---| +| Spotube | `krtirtho/spotube` | `master` | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | +| Namida | `namidaco/namida` | `main` | `acb1e1622600440cc793f389f497e6771c732c5e` | +| LocalSend | `localsend/localsend` | `main` | `6f6cd3ee496903e2206c51ffa3a13a5d10bc340b` | +| AppFlowy | `AppFlowy-IO/AppFlowy` | `main` | `5cf3a365dec0d59f64bad1ee4bb1050471a39b93` | +| Immich (mobile) | `immich-app/immich` | `main` | `970c496e55bdf261e7c1247bb282d3a7204e40f2` | +| Finamp | `jmshrv/finamp` | **`redesign`** | `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc` | +| Harmonoid | `alexmercerind/harmonoid` | `master` | `2b021f7b0b5dbcbe027aec010580977a2939a28d` | +| NewPipe | `TeamNewPipe/NewPipe` | `dev` | `7e5df38aad4b2c035332b3f71aee3064d4fdaae4` | + +註:`jmshrv/finamp` 與 `UnicornsOnLSD/finamp` 是同一個 repo(redirect),default branch 是 `redesign`(改寫中的分支),不是 `main`。NewPipe 是 Android/Kotlin 專案,列在此處是因為它是「錯誤詳情頁」的參考樣本。 + +--- + +## 1. Material 3 Snackbar + +### 定義與定位 +https://m3.material.io/components/snackbar/overview + +- "Snackbars show short updates about app processes at the bottom of the screen" +- "Snackbars shouldn't interrupt the user's experience" / "Usually appear at the bottom of the UI" / "Can disappear on their own or remain on screen until the user takes action" + +### 何時用(vs dialog) +https://m3.material.io/components/snackbar/guidelines + +- "Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom of the screen." +- "When to use snackbars: Snackbars communicate messages that are minimally interruptive and don't require user action." +- 官方對照(同頁):Snackbar = "Low priority" / "Optional: Snackbars disappear automatically";Dialog = "High priority" / "Required: Dialogs block app usage until the user takes a dialog action…" +- "Dialogs are also designed to show important messages. Choose the right component based on the importance of the message. This component messaging strategy can help avoid overusing snackbars." + +### 動作按鈕數量 +- "A snackbar can contain a single action. 'Dismiss' or 'cancel' actions are optional." +- "Snackbars can display a single text button. Snackbars shouldn't be the only way to access a core use case, to make an app usable." +- Caution:"A dismiss action is unnecessary, as snackbar disappears on their own by default" +- Caution:"Avoid adding icons to snackbars. If your message needs an icon, consider using a different component such as a dialog." + +### 時長 +- "Snackbars without actions can auto-dismiss after 4–10 seconds, depending on platform. Avoid using auto-dismissing snackbars on web unless there's also inline feedback." +- "Snackbars with actions should remain on the screen until the user takes an action on the snackbar, or dismisses it." +- https://m3.material.io/components/snackbar/accessibility :"Snackbars with actions shouldn't auto-dismiss.";"common acceptable durations are 4–10 seconds" + +### 一次只顯示一條 +- "Only one snackbar may be displayed at a time." +- "Consecutive snackbars must appear one at a time." +- "However, a snackbar with updated information can immediately replace an outdated snackbar." +- Don't:"Don't stack snackbars on top of one another" + +### 位置 +- "Snackbars should be placed at the bottom of a UI, in front of the main content. In some cases, snackbars can be nudged upwards to avoid overlapping with other UI elements near the bottom, such as FABs or docked toolbars." +- "Snackbars should appear above FABs." +- "Avoid placing a snackbar in front of frequently used touch targets or navigation." +- "Snackbars can span the entire width of the screen only when a UI does not use persistent navigation components like app bars or navigation bars." + +### 大螢幕 +- "On medium and expanded breakpoints, like tablet and desktop, snackbars should scale horizontally to accommodate longer text strings, keeping in mind that the ideal line length for text is typically between 40-60 characters." +- "Whenever possible, snackbars on medium and large displays should aim for a single line of text with an optional button." +- "In wider layouts, snackbars can be left-aligned or center-aligned if they are consistently placed on the same spot at the bottom of the screen." +- Compact breakpoint:"snackbars should expand vertically from 48dp to 64dp… maintaining a fixed distance from the leading, trailing, and bottom edges" + +### 錯誤 +**M3 snackbar 頁面本身沒有「error」用法條目**。相鄰規範說的是: +- M3 Dialogs(https://m3.material.io/components/dialogs/guidelines ):"General errors such as network issues preventing saving or submitting should appear in a basic dialog when the confirming action fails.";"Errors about the dialog fields should always appear inline where they occur." +- M1(舊版)Errors pattern(https://m1.material.io/patterns/errors.html ):"The snackbar contains app feedback about a peripheral error. **Snackbars are transient. Don't use them for critical, persistent, or bulk errors.**" + +### 無障礙 +https://m3.material.io/components/snackbar/accessibility + +- "When a snackbar appears, announce the message but don't move focus." +- "On Android and web, use a live region with a polite (queued) announcement instead of an assertive announcement." + +--- + +## 2. Microsoft Fluent 2 / Windows + +### Fluent 2 Toast(in-app 訊息) +https://fluent2.microsoft.design/components/web/react/core/toast/usage + +- "A toast communicates the status of an action someone is trying to take or that something happened elsewhere in the app. **Toasts are temporary surfaces. Use them for information that's useful and relevant, but not critical.**" +- "**For critical messages, try a modal Dialog, Field error, or Message bar instead.**" +- "If there is no action to take, toast will time out after seven seconds." +- "Use conditional dismissal for toasts that should persist until a condition is met"(例:progress toast 完成才消失) +- "**Don't use toasts for necessary actions.** If you need the encourage people to take an action before moving forward, try a more forceful surface like a message bar or a dialog." +- "Include the Close button to allow people to expressly dismiss toasts **only if they can find that information again elsewhere, like in a notification center.**" +- "Toasts should always appear in a consistent location within your app… This is usually the **top-right or bottom-right**." +- "Don't show more than four toasts in a toaster and keep 16 pixels of space between them." +- "All feedback states except info have an 'assertive' aria-live… don't overload people with too many assertive toasts." +- 鍵盤:people who navigate via mouse 可以 hover 暫停計時;"toasts that don't include actions won't receive keyboard focus for people who navigate primarily by keyboard." + +### Fluent 2 Message bar(= Fluent 1 的 InfoBar) +https://fluent2.microsoft.design/components/web/react/core/messagebar/usage + +- "A message bar communicates important information about the state of the entire product or the surface where it appears, such as a page, drawer, dialog, or card." +- "If the message is intended to prevent a destructive action, try a dialog instead. **If the message is time-sensitive, but relates to an activity or status from a different location, try a toast notification instead.**" + +### Windows InfoBar(WinUI 3) +https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/infobar + +- "The InfoBar control is for displaying app-wide status messages to users that are highly visible yet non-intrusive." +- "**Use an InfoBar control when a user should be informed of, acknowledge, or take action on a changed application state. By default the notification will remain in the content area until closed by the user but will not necessarily break user flow.**" +- "An InfoBar will take up space in your layout and behave like any other child elements. It will not cover up other content or float on top of it." +- "**Do not use an InfoBar control to confirm or respond directly to a user action that doesn't change the state of the app, for time-sensitive alerts, or for non-essential messages.**" +- "For scenarios where a notification is a transient teaching moment, a TeachingTip is a better option." + +### Windows Toast = OS 層(Windows App SDK / WinRT),不是 in-app widget +https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/toast-notifications-overview + +- "**App notifications are UI popups that appear outside of your app's window**, delivering timely information or actions to the user." +- API 名稱:新的 `AppNotificationManager`(`Microsoft.Windows.AppNotifications`);舊 UWP 為 `ToastNotificationManager`(`Windows.UI.Notifications`)。https://learn.microsoft.com/en-us/windows/apps/develop/notifications/ +- 進 Notification Center:`ToastNotification.ExpirationTime` = "the time after which a toast notification should not be displayed";`ExpiresOnReboot` = "Indicates whether the toast notification will remain in the Notification Center after a reboot." https://learn.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification +- 特定情境才會一直留在畫面上:"In the reminder scenario, the notification will stay on screen until the user dismisses it or takes action.";"Incoming call notifications… stay on the user's screen till dismissed." https://learn.microsoft.com/en-us/windows/apps/develop/notifications/app-notifications/app-notifications-content + +> 註:Windows 11 系統設定已改稱「Action Center」字樣(或沿用「Notification Center」),上列 API 文件仍用後者。官方文件目前無一致命名,兩者指同一處。 + +--- + +## 3. Apple HIG + +### HIG 沒有 toast 這個概念 +- 以匿名視窗讀 https://developer.apple.com/design/human-interface-guidelines 下的 Components 全部子分類(Content / Layout and organization / Menus and actions / Navigation and search / Presentation / Selection and input / Status / System experiences),**未出現「toast」字樣**(查證日 2026-09-28)。 +- HIG 對應的角色分給 Alerts(modal 中斷)、Notifications(OS 層)、Progress indicators 與 inline status。 + +### Alerts(modal 中斷) +https://developer.apple.com/design/human-interface-guidelines/alerts + +- "An alert gives people critical information they need right away." +- "**Use alerts sparingly. Alerts give people important information, but they interrupt the current task to do so.** Encourage people to pay attention to your alerts by making certain that each one offers only essential information and useful actions." +- "**Avoid using an alert merely to provide information.** People don't appreciate an interruption from an alert that's informative, but not actionable. If you need to provide only information, prefer finding an alternative way to communicate it within the relevant context." +- "Avoid displaying alerts for common, undoable actions, even when they're destructive." +- "Avoid showing an alert when your app starts. …consider alternative ways to let people know… you could show cached or placeholder data and a **nonintrusive label** that describes the problem." + +### Notifications(OS 層) +https://developer.apple.com/design/human-interface-guidelines/notifications + +- "A notification gives people timely, high-value information they can understand at a glance." +- "**Use an alert – not a notification – to display an error message.** People are familiar with both alerts and notifications, so you don't want to cause confusion by using the wrong component." +- "**Handle notifications gracefully when your app is in the foreground.** Your app's notifications don't appear when your app is in the front, but your app still receives the information. In this scenario, present the information in a way that's discoverable but not distracting or invasive, such as incrementing a badge or subtly inserting new data into the current view." + +### Feedback(inline status) +https://developer.apple.com/design/human-interface-guidelines/feedback + +- "The most effective feedback tends to match the significance of the information to the way it's delivered." +- "**Consider integrating status feedback into your interface.** When status feedback is available near the items it describes, people get important information without having to take action or leave their current context." +- "**Use alerts to deliver critical – and ideally actionable – information.** By design, alerts disrupt the current context, so you need to match the importance of the information to the level of interruption." +- "It's generally best to reserve this type of confirmation for activities that are sufficiently important – because people typically expect their action or task to succeed, **they only need to know when it doesn't**." + +### Progress indicators(唯一的「transient」東西) +https://developer.apple.com/design/human-interface-guidelines/progress-indicators + +- "All progress indicators are transient, appearing only while an operation is ongoing and disappearing after it completes." +- "When possible, use a determinate progress indicator." + +### 三系統一致/不一致(事實陳述) +- iOS/macOS **沒有** in-app transient toast 元件;最接近的「打斷一下」語意交給 OS Notification banner(需使用者同意),app 層被導向 inline status / badge。 +- Fluent 2 的「Message bar」對應 Material 的 banner/InfoBar,Windows 端實作是 WinUI `InfoBar`;Fluent 2 的「Toast」是 in-app 訊息,與 Windows OS toast notification **同名但不同物**。Apple 對應物是 OS Notification。 +- 三系統一致:**錯誤(critical 資訊)都不建議走 transient toast/snackbar** —— Material 建議 dialog 或 inline,Fluent 2 建議 Dialog / Field error / Message bar,Apple 建議 Alert 或 inline。 + +--- + +## 4. Flutter 開源 App 怎麼做統一提示 + +以下 7 個都讀了原始碼。欄位固定:元件、單一入口 API、桌面/手機位置分流、佇列/去重、錯誤詳情或回報、與 Navigator/全螢幕的關係。 + +### 4.1 Spotube(`krtirtho/spotube` @ `69a310c`) +- **元件**:第三方元件庫 `shadcn_flutter 0.0.47` 內建的 toast。不用 Material SnackBar,**沒有自建 service 層**。 +- **單一入口**:shadcn 的 `showToast(context:, location:, builder:)`,回傳 `ToastOverlay`(可 `.close()`)。Spotube 唯一抽出的 helper 是 `showToastForAction`: + https://github.com/krtirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/components/track_presentation/presentation_actions.dart#L16-L49 + (`builder:` 內自繪 `SurfaceCard` + 關閉 IconButton,L29-L48) +- **位置**:**呼叫端每次自己指定** `ToastLocation`。多數 `topRight`(同檔 L40);全域連線狀態用 `bottomCenter`: + https://github.com/krtirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/root/use_global_subscriptions.dart#L83-L85 + desktop / mobile **沒有分流**,同一套 location。 +- **佇列/取代**:由元件庫決定 —— `showToast`(`packages/shadcn_flutter/lib/src/components/overlay/toast.dart#L265`)把 entry `addEntry`(同檔 L296)給最近的 `ToastLayer`;`ToastLayer.maxStackedEntries` 預設 **3**(同檔 L559),超過時舊的被摺疊。是**堆疊**語意,不是取代。`showToast` 內有 `assert(layer != null, 'No ToastLayer found in context')`(同檔 L284)——**必須有 `ToastLayer` 祖先**。 +- **錯誤詳情/report**:**無**。(`lib/pages/settings/logs.dart` 只是顯示 log 的頁面,不是從錯誤訊息連過去。) +- **與 Navigator/全螢幕的關係**:根層的 `ToastLayer` 由 `ShadcnApp.router` 提供;**dialog 是獨立 route/overlay,因此 Spotube 在 dialog 內額外包一層 `ToastLayer`**: + https://github.com/krtirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/modules/playlist/playlist_create_dialog.dart#L293 + (`builder: (context) => const ToastLayer(child: PlaylistCreateDialog())`)——「訊息層要跟著覆蓋它的 overlay 走」的具體範例。 + +### 4.2 Namida(`namidaco/namida` @ `acb1e162`) +- **元件**:**自製套件** `nampack`(namida 自家的 pub 套件,`lib/snackbar/` 下 5 個檔),是 pub `snackbar` 套件的 fork,類別改名 `NamSnackBar`(`snackbar_controller.dart`、`snackbars_manager.dart`、`snackbar_scope.dart`、`snackbar_widget.dart`、`snackbar_enum.dart`)。非 Material SnackBar、非 `fluttertoast`。 +- **單一入口**:全域函式 `snackyy({...})`,回傳 `SnackbarController`: + https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/navigator_controller.snackbar.dart#L11-L30 + (`part of 'navigator_controller.dart'`,宣告在 L37) +- **位置**:參數 `bool top = true`(同檔 L16)——預設頂部;`top: false` 給底部,例如「再按一次退出」: + https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/navigator_controller.dart#L705-L717 + `NamSnackBar` 內部以 `SafeArea` 處理 top/bottom。 +- **桌面/手機分流**:**有**。同檔 L89-L96 依 `view.physicalSize` 決定寬度;`WindowController.instance?.windowTitleBarHeightIfActive` 在桌面額外加上 **title bar 高度作為 top margin**,避免被自繪視窗標題列蓋住。桌面上概念位置仍是頂部,只是往下推。 +- **佇列/合併/取代**:三者都有,樣本中最完整。`_snackbarsStackManager`(同檔 L5)+ `addDurationForGenericSnackbars`(L55)會**替較舊的 snackbar 延長顯示時間**以免被新的蓋掉;`SnackbarMerge` 與 `_mergedSnackbars` map(L7、L31-L36)把同 key 的訊息**合併成同一條並累加次數**(`addCount`);`isError ??= title == lang.error`(L38)。另有教學式 `dismissHint`(滑動關閉提示,最多顯示 3 次,L9、L47-L50)。 +- **錯誤詳情/report**:**無** stack trace 檢視;`SnackbarButton`(L25、L120-L172)是通用 action 按鈕,可放「重試」,但沒有內建 report 機制。 +- **與 Navigator/全螢幕的關係**:訊息由 `nampack` 的 manager 插入。Namida 在 `lib/main.dart` 的 `MaterialApp.builder` 裡自己包了一層 `Overlay(initialEntries: [OverlayEntry(...)])`(L685-L730),訊息層在其之上。 + +### 4.3 LocalSend(`localsend/localsend` @ `6f6cd3e`) +- **元件**:純 Material `SnackBar` + `ScaffoldMessenger.of(context)`。**沒有**任何 toast 套件。 +- **單一入口**:`extension SnackbarExt on BuildContext { void showSnackBar(String text) }`,整檔 13 行: + https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/util/ui/snackbar.dart#L3-L13 +- **位置**:沿用預設 `ScaffoldMessenger`(由 `MaterialApp` 建立、**在 Navigator 之上**),所以切換路由時訊息不消失。desktop / mobile **無分流**。 +- **佇列/取代**:**取代** —— 先 `scaffold.removeCurrentSnackBar()` 再 `showSnackBar`(同檔 L6-L7)。同時最多 1 條。 +- **錯誤詳情/report**:**無**(內容只有一個 `Text`)。全 repo 只有少數檔呼叫它。另有通用 `CopyableText`(`app/lib/widget/copyable_text.dart#L18-L26`)是「點文字複製 → 用 snackbar 確認」的最輕量慣例。 + +### 4.4 AppFlowy(`AppFlowy-IO/AppFlowy` @ `5cf3a36`) +- **元件**:**兩套並存**。 + 1. `fluttertoast` 的 `FToast`(包成 `FlowyMessageToast`):https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/workspace/presentation/home/toast.dart#L10-L50 + 2. Material `SnackBar`(`showSnackBarMessage`,同檔 L52-L78),以及 `flowy_infra_ui` 的 `showSnapBar`:https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/snap_bar.dart#L6-L27 (`clearSnackBars()` L7、`duration: 8000ms` L14、桌機字級 14 / 其餘 12 在 L18-L21) +- **單一入口**:**沒有**單一 service class,是三個自由函式:`showMessageToast`、`showSnackBarMessage`、`showSnapBar`。`FToast` 由 `getIt()` 取得,需先 `initToastWithContext(context)`。 +- **桌面/手機分流**:**字級分流**(`UniversalPlatform.isDesktop ? 14 : 12`,`toast.dart#L74`;`snap_bar.dart` 用 `Platform.isLinux/Windows/MacOS`)。位置不變(toast 預設 `ToastGravity.BOTTOM`)。 +- **佇列/取代**:`showSnapBar` 先 `clearSnackBars()`(`snap_bar.dart#L7`)=**清空取代**;`showSnackBarMessage` 不清,交給 Flutter 預設**排隊**。`FToast` 自己維護 overlay entry 佇列。兩者的預設時長:SnapBar 8000ms(`snap_bar.dart#L14`)、SnackBar 4s(`toast.dart#L56`)。 +- **錯誤詳情/report**:**有,而且是一整頁**。`FlowyErrorPage.error/message/exception`: + https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/shared/error_page/error_page.dart#L17-L60 + - 可點擊複製的 message,hover tooltip:"Click to copy message"(同檔 L112-L119),複製後另彈一條 "Message copied to clipboard"(同檔 L100-L108) + - 修復提示 `howToFix`(L127) + - `GitHubRedirectButton`(同檔 L210-L272):`_gitHubNewBugUri`(L224-L230)組 `https://github.com/AppFlowy-IO/AppFlowy/issues/new?…&template=bug_report.yaml&title=[Bug]+…&context=…`,`_contextString`(L232-L245)把 message 與 stack trace 用 code fence 塞進 `context` 參數 + - `StackTracePreview`(L147 起)帶自己的 copy 按鈕 + +### 4.5 Immich mobile(`immich-app/immich` @ `970c496`, `mobile/`) +- **元件**:純 Material SnackBar,**但自建 manager**: + https://github.com/immich-app/immich/blob/970c496e55bdf261e7c1247bb282d3a7204e40f2/mobile/packages/ui/lib/src/snackbar.dart + 全域 `final scaffoldMessengerKey = GlobalKey()`(L7)、`class SnackbarManager`(L17)、`const snackbar = SnackbarManager()`(L99 附近)。 +- **單一入口**:**兩層**。低階 `snackbar.info/success/error(message, duration:, action:)`;app 層 `ToastService`: + https://github.com/immich-app/immich/blob/970c496e55bdf261e7c1247bb282d3a7204e40f2/mobile/lib/services/toast.service.dart#L12-L22 + (`success` / `error`,參數 `ToastOption(timeout, onUndo)`;`onUndo` 轉成 `SnackbarAction`) +- **外觀/位置**:`behavior: SnackBarBehavior.floating`(`snackbar.dart` L56)、`persist: false`(L61)、icon + 色彩語意(info/success/error)。desktop/mobile **無分流**(Immich mobile 本來只跑手機)。 +- **佇列/取代**:**取代** —— `messenger.hideCurrentSnackBar()` 再 `showSnackBar`(L33-L34)。 +- **錯誤詳情/report**:訊息層**沒有**。`mobile/lib/utils/error_handler.dart#L11-L36` 的 `handleError` 先用 `Trace.from(stack).foldFrames(... terse: true)` 洗掉 framework frames 再 `dPrint`,顯示只給 `snackbar.error(message)`。**詳情走獨立頁**:`mobile/lib/pages/common/app_log.page.dart#L97` → `AppLogDetailRoute`,`app_log_detail.page.dart` 分區塊(MESSAGE / DETAILS / FROM / STACK TRACE)各帶 copy IconButton;整批 log 可用 `ImmichLogger.shareLogs` 匯成檔案分享(`mobile/lib/services/immich_logger.service.dart#L18-L52`)。 +- **與 Navigator/全螢幕的關係**:`mobile/lib/main.dart` 的 `MaterialApp.router(scaffoldMessengerKey: scaffoldMessengerKey)` → **messenger 在 router/Navigator 之上**,跨路由存活。未捕捉例外只進 logger,不彈訊息。 + +### 4.6 Finamp(`jmshrv/finamp` @ `0aae9d5`, branch `redesign`) +- **元件**:Material SnackBar + 樣本中最完整的自建 service:`class GlobalSnackbar`(353 行) + https://github.com/jmshrv/finamp/blob/0aae9d5ed530ffdf3d62ab12dab4f475a67687dc/lib/components/global_snackbar.dart + 掛在 `MaterialApp.scaffoldMessengerKey` + `navigatorKey`。全 repo 呼叫點極多;舊的 `errorSnackbar(...)` 已標 `@Deprecated` 指向 `GlobalSnackbar.error`。 +- **單一入口**:靜態方法 `show` / `showPrebuilt`(L107-L113)/ `message`(L120 附近)/ `error` / `popup`(L264 附近)/ `dismissAllSnackbars`(L95-L104)。 +- **外觀/位置**:`SnackBarBehavior.floating` 被**刻意註解掉**(`lib/main.dart` 附近,理由是與 FAB 位置衝突),因此用預設 `fixed`,貼在 ScaffoldMessenger 底部。desktop / mobile **無分流**。 +- **佇列/取代**:**排隊**(用 Flutter 內建佇列,未呼叫 clear)。兩層保險:啟動完成前的呼叫進內部 `_queue`,用 `Timer.periodic` 等 MaterialApp ready;`dismissAllSnackbars()` 一次清空。 +- **去重(樣本中最特別)**:`static final Set _activeErrorKeys`(L60)只對**網路類**錯誤去重,key 為 `"network:${event.statusCode}:${underlying.runtimeType}"`(L201-L203,**不帶 URL/body**);訊息關閉後才移除 key,允許之後再出現(L254)。另有常見網路錯誤靜音:`Failed host lookup` / `HTTP connection timed out` / `TimeoutException` 直接不顯示(L159-L177)。 +- **錯誤詳情/report**:**兩條**。 + 1. 錯誤 snackbar 帶 "more" action(label 取 `MaterialLocalizations.moreButtonTooltip`,L231)→ 彈 `AlertDialog` 顯示完整 `errorText`。 + 2. **長按或右鍵點任何 snackbar**(L138、L143)→ `showSnackbarOptionsMenu` bottom sheet(L291-L296),內含 `DismissAllSnackbarsMenuEntry` 與 `ViewLogsMenuEntry`;後者導到 `LogsScreen`,其 `CopyLogsButton` 複製後再以 `GlobalSnackbar.message(..., isConfirmation: true)`(1.5 秒)確認。另有 `popup()` 用 AlertDialog 顯示雙行訊息。 +- **與 Navigator/全螢幕的關係**:messenger 在 MaterialApp 層=**Navigator 之上**;需要 context 時刻意用 navigator 的 context(原始碼註解說明 scaffold context 缺全域狀態)。 + +### 4.7 Harmonoid(`alexmercerind/harmonoid` @ `2b021f7`) +- **元件**:**不用 Flutter 層元件**。走 MethodChannel 呼叫原生: + https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/utils/platform_utils.dart#L53-L57 + `Future showToast(String text)`,第一行 `if (!Platform.isAndroid) return;` → **桌面上是 no-op**。 +- 原生端:https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/android/app/src/main/kotlin/com/alexmercerind/harmonoid/UtilsMethodCallHandler.kt#L23-L27 + `Toast.makeText(activity, text, Toast.LENGTH_SHORT).show()` +- **呼叫點**:全 repo 只有 2 處,都在 + https://github.com/alexmercerind/harmonoid/blob/2b021f7b0b5dbcbe027aec010580977a2939a28d/lib/features/media_library/playlists/utils/rendering.dart#L77-L79 (「已加入播放清單」)。 +- **位置/佇列/取代**:全交給 Android 原生 Toast(系統佇列、底部)。**錯誤詳情/report:無**。 +- **維護狀態**:最後 push 2026-09-02,且原始碼中大量功能已標為不再維護 —— 「專案停滯」屬**推測**(本檔只確認日期與檔案內容)。 + +--- + +## 5. NewPipe 的 `ErrorActivity` + +NewPipe 是 Android/Kotlin 專案,列在此處是因為它的「錯誤詳情頁」是樣本中最完整的一個。 + +### 分層準則(原始碼註解本身就是準則) +https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt#L20-L30 + +- 非致命且拿得到 root view → **snackbar**;在背景 service 或拿不到 root view → **notification**;致命 → **ErrorActivity**(最後手段)。 + +### Snackbar 的 action 就是「開詳情頁」 +同檔 L157-L168: + +```kotlin +Snackbar.make(rootView, errorInfo.getMessage(context), Snackbar.LENGTH_LONG) + .setActionTextColor(Color.YELLOW) + .setAction(context.getString(R.string.error_snackbar_action).uppercase()) { … } +``` + +- 字串:`error_snackbar_action` = "Report"、`error_snackbar_message` = "Sorry, something went wrong." + https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/values/strings.xml#L270-L271 +- 拿不到 root view 時改發 notification,並**額外補一個 Toast**(同檔 L143-L147)。 + +### 內嵌錯誤面板(不跳頁) +https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt#L66-L96 + +`showError(errorInfo)` 預設只顯示 message,依條件解鎖:`recaptchaUrl` → 解 captcha 按鈕;`isReportable` → "Report" 按鈕(呼叫 `ErrorUtil.openActivity`);`isRetryable` → retry;`openInBrowserUrl` → 用瀏覽器開。版面 `res/layout/error_panel.xml`。 + +### `ErrorActivity` 的內容 +https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.kt +(版面 `app/src/main/res/layout/activity_error.xml`) + +- 標題「Sorry…」+ 彩蛋 guru meditation +- 「What happened:」→ `errorMessageView`(人類可讀訊息,帶超連結) +- 「Info:」→ `errorInfosView`(user action / request / content language / content country / app language / service / 時間戳 ISO8601 / package / 版本 / OS;`buildInfo` L166-L181) +- 「Details:」→ `errorView`:等寬字型 + `textIsSelectable="true"` 的 stack trace,多個 trace 之間用 `-----` 分隔 +- 「Your comment (in English):」→ `errorCommentBox` 使用者留言框(寫進 `buildJson` 的 `user_comment`,L198) +- **三顆按鈕**(L90-L100): + - **Email** → `openPrivacyPolicyDialog(this, "EMAIL")`(L90-L92);確認後 `Intent.EXTRA_EMAIL = arrayOf(ERROR_EMAIL_ADDRESS)`,常數 `ERROR_EMAIL_ADDRESS = "crashreport@newpipe.schabi.org"`(L277) + - **Copy formatted report** → `ShareUtils.copyToClipboard(this, buildMarkdown())`(L94-L96);字串 `copy_for_github` = "Copy formatted report"(`strings.xml#L267`) + - **Report on GitHub** → `openPrivacyPolicyDialog(this, "GITHUB")`(L98-L100);確認後只**開啟** `ERROR_GITHUB_ISSUE_URL = "https://github.com/TeamNewPipe/NewPipe/issues"`(L280),**不代填** issue 內容 +- 上方 overflow 另有 **share** 圖示分享 **JSON**(`R.id.menu_item_share_error`,L123-L130,`buildJson()`) +- 兩顆送出按鈕都**先彈隱私政策 AlertDialog**(`openPrivacyPolicyDialog` L136 起) +- 兩種輸出格式:`buildJson()`(L183-L206,欄位 `user_action/request/content_language/content_country/app_language/service/package/version/os/time/exceptions[]/user_comment`);`buildMarkdown()`(L208-L261,先使用者留言,再 `## Exception` 清單,多個 trace 時用 GitHub 的 `

    ` 收合) +- 崩潰自動上報:ACRA 的 `AcraReportSender.java#L36-L41` 不真的送 server,而是把 ACRA 的 STACK_TRACE 轉成 `ErrorInfo` 再開 `ErrorActivity`,讓使用者自己決定要不要送 —— **同一頁 UI 吃所有來源**。 + +--- + +## 6. 「複製錯誤資訊」的其他產品慣例 + +本輪逐一看到的樣本: + +| App | 可複製的內容 | 容器 | 備註 | +|---|---|---|---| +| NewPipe | Markdown / JSON | 獨立 `ErrorActivity` | 「Copy formatted report」為 GitHub issue 而寫;另有 Email / 開 GitHub issues 頁 | +| AppFlowy | error message、stack trace(分開兩個 copy) | 獨立 `FlowyErrorPage` | 另附 GitHub issue URL prefill(`template=bug_report.yaml`,把 message 與 trace 塞進 `context` 參數) | +| Immich mobile | log 各欄位(MESSAGE / DETAILS / FROM / STACK TRACE) | 獨立 log detail 頁 | 另有整批 `shareLogs` 匯出檔案 | +| Finamp | logs | 獨立 `LogsScreen` | 從 snackbar 長按/右鍵的 bottom sheet 進入;訊息層本身只給一個「more」dialog | +| LocalSend | 任意文字(通用元件 `CopyableText`) | 就地元件 | 複製後以 snackbar 確認 | +| Spotube / Namida / Harmonoid | 無 | — | 樣本中沒有錯誤詳情或回報機制 | + +**共同模式(推測)**:訊息本身不可複製,details 一定有一個獨立容器(頁面/dialog/bottom sheet)才提供 copy 或 report。此條是從上表歸納,非任何文件的明文規定。 + +--- + +## 7. 查不到 / 無 / 與子代理報告的差異 + +### 查不到 +- **M3 規範沒有「snackbar 用於錯誤」的明文條目**;只能引相鄰的 M3 Dialogs 與 M1(已歸檔)Errors pattern。 +- **Apple HIG 完全沒有 toast 元件或 toast 一詞**(已把 Components 全部子分類頁讀過)。 +- **沒有任何一個樣本 app 使用 `bot_toast` / `another_flushbar` / `overlay_support` / `Get.snackbar`**。實際分布是:Material SnackBar 自建 service(Finamp、Immich、LocalSend、AppFlowy)、第三方元件庫內建 toast(Spotube → `shadcn_flutter`)、自製套件(Namida → `nampack`)、原生 Toast(Harmonoid)。 +- Harmonoid 的 Flutter 層沒有訊息層可言,桌面無 toast(`showToast` 是 no-op)。Spotube / LocalSend / Namida / Harmonoid 沒有錯誤詳情或回報機制。 +- Windows 官方文件對「Action Center / Notification Center」命名不一致,未找到一份統一名稱的現行文件。 + +### 我核對後修正子代理報告之處 +- AppFlowy 的 `GitHubRedirectButton` **不是獨立檔案**,class 就在 `error_page.dart` L210-L272;URL 建構在 L224-L230、`_contextString` 在 L232-L245(子代理原報告寫 L45-L68,錯)。 +- shadcn_flutter 的 toast 檔路徑是 `packages/shadcn_flutter/lib/src/components/overlay/toast.dart`(子代理只寫 `toast.dart`);`showToast` L265、`assert(layer != null, …)` L284、`addEntry` L296、`ToastLayer` L450、`maxStackedEntries` 預設 3 在 L559。核對的版本是 `master`(pub 最新 0.0.54),Spotube 實際鎖的是 0.0.47 —— 預設值 3 是否在 0.0.47 即如此,**未查**。 +- NewPipe 的 `ErrorUtil.kt` / `ErrorActivity.kt` 路徑是 `app/src/main/java/org/schabi/newpipe/error/`(子代理原報告未給完整路徑,我按 `util/` 取檔得到 404)。 +- AppFlowy 的 `snap_bar.dart` 在 `frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/` 底下(子代理寫 `packages/flowy_infra_ui/...`,少了 `frontend/appflowy_flutter/` 這段)。 +- Finamp 的 `SnackBarBehavior.floating` 在 `lib/main.dart` L1024-L1025 與 L1041-L1042 被註解掉,緊鄰的 TODO 原文是 "get rid of floating action buttons and re-enable the floating behavior and insetPadding" —— 理由確認。 +- NewPipe 的 GitHub 按鈕**不代填** issue,只開 `.../NewPipe/issues`(L280);代填 issue 的是 AppFlowy。 +- Harmonoid 的「專案已停滯」是**推測**,本檔只把它寫成日期與內容事實。 + +### 本檔已親自重新抓取核對的引文 +M3 Snackbar guidelines 與 accessibility、Fluent 2 Toast usage、Apple HIG Alerts(皆 2026-09-28);LocalSend `snackbar.dart`、Immich `snackbar.dart` + `toast.service.dart`、Finamp `global_snackbar.dart` + `main.dart`、AppFlowy `error_page.dart` + `toast.dart` + `snap_bar.dart`、Harmonoid `platform_utils.dart` + `UtilsMethodCallHandler.kt` + `rendering.dart`、NewPipe `ErrorUtil.kt` + `ErrorActivity.kt` + `strings.xml`、Spotube `presentation_actions.dart` + `use_global_subscriptions.dart` + `playlist_create_dialog.dart`、shadcn_flutter `toast.dart`。其餘(M3 overview/dialogs、Fluent 2 message bar、WinUI InfoBar、Windows toast API、Apple HIG Notifications/Feedback/Progress indicators、Namida 各檔行號)為子代理抓取後附 URL,行號未逐條重開檔核對。 From d3fe877879f5c5a5f5559cfe3cf175e6eaa13281 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:08:09 +0800 Subject: [PATCH 086/133] chore(task): record toast appearance decision --- .trellis/tasks/09-28-design-toast/prd.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-28-design-toast/prd.md b/.trellis/tasks/09-28-design-toast/prd.md index d3d74c3a8..978e66674 100644 --- a/.trellis/tasks/09-28-design-toast/prd.md +++ b/.trellis/tasks/09-28-design-toast/prd.md @@ -39,11 +39,14 @@ ADR 0013(錯誤呈現表;同類別+同音源短時間只提示一次;背 - 單一入口;開發者模式下錯誤提示附「詳細」,可看錯誤類型、音源、請求摘要、stack trace 並複製;所有錯誤同時進入錯誤歷史(ADR 0011);「詳細」與複製內容經同一遮蔽函式。 - 呈現規則照 ADR 0013 的表:背景工作不跳提示;同類別+同音源短時間只提示一次;訊息一律 i18n,不顯示例外原文。 +## 已決定 + +1. **Material 單條橫條、新的取代舊的(2026-09-28,按建議)**:手機在迷你播放列上方;桌面在播放列上方置中、最寬約 560px;一次一則,新的立刻取代。 + 錯誤不因被取代而遺失(錯誤歷史);同類別+同音源短時間只提示一次(ADR 0013)。否決:桌面右下角疊卡(兩套元件、自做無障礙)、依序排隊(連續操作回饋延遲)。 + ## 待決定 -1. 外觀與位置(手機、桌面)。 -2. 排隊方式:新的蓋掉舊的,或依序排隊,或疊放多條。 -3. 「詳細」提供哪些動作(複製、回報到 GitHub)。 +1. 「詳細」提供哪些動作,以及一般使用者遇到非預期錯誤時能否回報。 ## 不在範圍 From 916c9c8b6aa858070da0d35edce0e393ad65a733 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:10:41 +0800 Subject: [PATCH 087/133] chore(task): add design and plan for toast --- .trellis/tasks/09-28-design-toast/design.md | 79 +++++++++++++++++++ .../tasks/09-28-design-toast/implement.md | 12 +++ .trellis/tasks/09-28-design-toast/prd.md | 14 ++-- 3 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 .trellis/tasks/09-28-design-toast/design.md create mode 100644 .trellis/tasks/09-28-design-toast/implement.md diff --git a/.trellis/tasks/09-28-design-toast/design.md b/.trellis/tasks/09-28-design-toast/design.md new file mode 100644 index 000000000..2df8ee62a --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/design.md @@ -0,0 +1,79 @@ +# 設計:統一 Toast + +## 1. 入口 + +```mermaid +flowchart LR + UI["頁面與元件
    使用者操作的結果"] --> T["Toaster
    (provider,不需 BuildContext)"] + SV["service
    使用者發起的動作失敗"] --> T + SW["子視窗/懸浮窗
    型別化訊息"] --> T + T --> D["去重
    同類別+同音源"] + D --> H["ToastHost
    MaterialApp.builder,包住 Navigator"] + T --> L["log 門面
    錯誤歷史(ADR 0011)"] + H --> DP["詳細頁
    ErrorReport(已遮蔽)"] +``` + +- `Toaster` 是唯一入口,以 provider 注入,不需要 `BuildContext`(舊版有三條入口:`failure(context, e)`、`error(context, 文字)`、背景 stream)。 +- API: + - `success(String)`、`info(String)`、`warning(String)`:參數是 i18n 字串; + - `error(AppError, {Operation? operation})`:只接受 `AppError`,由對應表轉成 i18n 訊息(ADR 0013),所以不會有例外原文上畫面; + - 各自可帶一個動作(例如「登入」「復原」)。 +- 背景工作不呼叫 `Toaster`,只更新對應畫面的狀態(ADR 0013)。使用者發起、在 service 內失敗的動作可以呼叫。 +- 錯誤一律經 log 門面寫入錯誤歷史(ADR 0011),不論有沒有顯示提示。 + +## 2. 外觀、位置與時長(已決定:Material 單條、新的取代舊的) + +- Material `SnackBar`,`floating`,四種語意色(成功、資訊、警告、錯誤)加圖示;最多一個動作;錯誤另有「詳細」或「回報」(§4)。 +- 位置: + - 手機:迷你播放列與底部導覽列之上; + - 桌面:播放列之上、置中,最寬 560px; + - 全螢幕播放頁:貼底部安全區。 + + 外殼版面把「底部被佔用的高度」發佈給 `ToastHost`,由它算邊距,頁面不必各自處理。 +- 一次一則,新的立刻取代目前的(顯示前 `clearSnackBars`)。 +- 時長: + - 成功與資訊 4 秒;錯誤與警告 6 秒(M3 範圍 4–10 秒;舊版 1.5/3 秒太短、來不及讀)。 + - 帶動作的也照上述時長自動消失(`persist: false`,否則 Flutter 3.38 起會一直停著);系統開啟無障礙導覽時才改為停留到手動關閉(沿用舊版)。 +- 去重:同一類別+同一音源(非錯誤則同一訊息)5 秒內只顯示一次(ADR 0013 的「短時間」定為 5 秒)。 + +## 3. 層級與可見範圍(G9) + +- `ToastHost` 放在 `MaterialApp.builder`:一個 `ScaffoldMessenger`+透明 `Scaffold` 包住 Navigator。 + SnackBar 由這個 Scaffold 畫,所以在所有路由(全螢幕播放頁、對話框、底部面板)之上都看得到。 + 依原始碼推得 SnackBar 由最近的 Scaffold 畫,第一個里程碑實測確認。 +- 桌面歌詞子視窗、Android 懸浮窗不顯示提示;需要提示的錯誤以型別化訊息(ADR 0021)轉給主視窗的 `Toaster`。 +- App 在背景時不顯示(沒有畫面),錯誤仍進錯誤歷史;不發系統通知。 + +## 4. 詳細頁與回報(已決定) + +- **誰看得到**:開發者模式下,每則錯誤提示附「詳細」;一般使用者只有 `Unsupported`、`UnexpectedError` 附「回報」,開同一頁。 +- **`ErrorReport`**:錯誤發生時組裝一次,經 ADR 0011 的遮蔽函式;顯示、複製、回報都用這一份,不再重組。內容: + - 錯誤類型與原因、音源(插件 id 與版本)、使用者動作; + - 請求摘要(方法、已遮蔽的網址、狀態碼、耗時)、stack trace; + - App 版本與 flavor、系統與版本、時間(ISO 8601)。 +- **詳細頁**:可選取文字。按鈕: + - 「複製」:Markdown 格式; + - 「在 GitHub 回報」:先複製,再以瀏覽器開啟 repo 的新增 issue 頁(bug 範本),**內容不放進網址**。 + 第一次使用先提醒「repo 是公開的,送出前請檢查內容」,勾選不再提醒後記在設定。 +- Debug 頁的錯誤歷史(第 4 項)點開單筆時用同一個詳細頁。 +- 新增 issue 頁的網址放在 `fmp_url_literal` 允許的端點檔(ADR 0015)。落地時在 repo 新增 `.github/ISSUE_TEMPLATE/bug_report.yml`(目前沒有範本)。 + +## 5. 無障礙 + +- 使用 `SnackBar` 內建的 live region,朗讀但不搶焦點。 +- 需要單獨朗讀的地方用 `SemanticsService.sendAnnouncement(View.of(context), …)`,不用已棄用的 `announce`。 +- Windows 無障礙樹:上游有 Slider 在推送的頁面內凍結無障礙樹的 issue(#190357)。第一個里程碑以 Narrator 實測提示出現在全螢幕頁與對話框上時,樹不會凍結。 + +## 6. 閘門 + +- 新 lint `fmp_toast_entry`(加入 ADR 0015 的 `fmp_lints`):`SnackBar(`、`ScaffoldMessenger.of`、`showSnackBar`、`clearSnackBars` 只准在 toast 模組;依 ADR 0015 寫雙向變異測試。 + 取代舊 `error_presentation_static_rule_test.dart` 中「UI 不得自組錯誤文字」的部分。 +- `error(AppError)` 的型別擋掉以字串形式傳例外原文(舊版 `audio_provider.dart:1988` 的漏網點)。 +- 單元測試:去重視窗、取代、時長、開發者模式與一般使用者的按鈕、`ErrorReport` 經遮蔽(假 cookie、token、簽名網址不出現在 Markdown)、GitHub 網址不含報告內容。 +- widget 測試:全螢幕路由與對話框開啟時送出提示,提示可見;底部位移依外殼發佈的高度。 + +## 7. 相關 ADR 的指向 + +- 0013:提示外觀、去重時間與「詳細」由 0023 定。 +- 0015:後續 ADR 新增的規則加 `fmp_toast_entry`。 +- 0021:子視窗與懸浮窗的提示轉給主視窗(0023)。 diff --git a/.trellis/tasks/09-28-design-toast/implement.md b/.trellis/tasks/09-28-design-toast/implement.md new file mode 100644 index 000000000..4c415fc48 --- /dev/null +++ b/.trellis/tasks/09-28-design-toast/implement.md @@ -0,0 +1,12 @@ +# 執行計畫:第 3 項(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0023-unified-toast.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: + 三條入口並存(舊版)、桌面右下角疊卡、依序排隊、`fluttertoast`(沒有 Windows)、`toastification`(沒有動作與 live region)、 + 把報告內容放進 GitHub 網址、一般使用者完全看不到回報、子視窗各自顯示提示。 +2. [ ] 其他 ADR 各加一句指向 ADR 0023:0013(提示外觀、去重時間、詳細)、0015(`fmp_toast_entry`)、0021(子視窗提示轉主視窗)。 +3. [ ] `phase2-plan.md`:§3 第 3 項標 ✅(ADR 0023);§7 第一個里程碑加入「提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹」; + §10 交接段更新,下一項 5 UI/UX,下一份 ADR 0024。 +4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [ ] `task.py finish`、`task.py archive design-toast --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-toast/prd.md b/.trellis/tasks/09-28-design-toast/prd.md index 978e66674..69d7d990b 100644 --- a/.trellis/tasks/09-28-design-toast/prd.md +++ b/.trellis/tasks/09-28-design-toast/prd.md @@ -44,9 +44,11 @@ ADR 0013(錯誤呈現表;同類別+同音源短時間只提示一次;背 1. **Material 單條橫條、新的取代舊的(2026-09-28,按建議)**:手機在迷你播放列上方;桌面在播放列上方置中、最寬約 560px;一次一則,新的立刻取代。 錯誤不因被取代而遺失(錯誤歷史);同類別+同音源短時間只提示一次(ADR 0013)。否決:桌面右下角疊卡(兩套元件、自做無障礙)、依序排隊(連續操作回饋延遲)。 -## 待決定 - -1. 「詳細」提供哪些動作,以及一般使用者遇到非預期錯誤時能否回報。 +2. **詳細頁與回報(2026-09-28,按建議)**:詳細頁顯示錯誤類型、音源、使用者動作、已遮蔽的請求摘要、stack trace、App 與系統版本、時間; + 按鈕「複製」(Markdown)與「在 GitHub 回報」(先複製再開新增 issue 頁,內容不放進網址;第一次使用提醒 repo 公開、送出前檢查)。 + 開發者模式下每則錯誤提示附「詳細」;一般使用者只有「不支援/預期外」錯誤附「回報」,開同一個詳細頁。 +3. **技術選擇(`design.md`)**:單一 `Toaster` 服務(不需 `BuildContext`);錯誤提示只接受 `AppError`;提示宿主放在 `MaterialApp.builder`、包住 Navigator, + 全螢幕頁與對話框之上都看得到;底部位移由外殼版面發佈;子視窗與懸浮窗不顯示提示、改轉給主視窗;lint `fmp_toast_entry` 守單一入口。 ## 不在範圍 @@ -54,6 +56,6 @@ ADR 0013(錯誤呈現表;同類別+同音源短時間只提示一次;背 ## 驗收條件 -- [ ] ADR 0023 記錄:單一入口與 API、外觀與位置、排隊與去重、層級(全螢幕頁、對話框、子視窗)、開發者模式詳細、無障礙、閘門。 -- [ ] G9 對到決定。 -- [ ] `phase2-plan.md` §3 第 3 項標 ✅ 與 ADR 編號。 +- [ ] ADR 0023 記錄:單一入口與 API、外觀與位置、取代與去重、時長、層級(全螢幕頁、對話框、子視窗、懸浮窗)、詳細頁與回報、無障礙、閘門。 +- [ ] G9(三種寫法、背景錯誤只有外殼在聽、全螢幕頁看不到)對到決定。 +- [ ] ADR 0013、0015、0021 加上指向 ADR 0023 的一句話;`phase2-plan.md` §3 第 3 項標 ✅,§7 加入實測項目。 From 1ac254e0b8162f59a39e9c382f2fdcb272bf0f3d Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:12:54 +0800 Subject: [PATCH 088/133] docs(adr): 0023 unified toast --- docs/adr/0013-unified-error-model.md | 2 +- .../0015-testing-gates-and-dev-environment.md | 2 +- docs/adr/0021-lyrics.md | 2 +- docs/adr/0023-unified-toast.md | 101 ++++++++++++++++++ 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 docs/adr/0023-unified-toast.md diff --git a/docs/adr/0013-unified-error-model.md b/docs/adr/0013-unified-error-model.md index f58168337..45e94692c 100644 --- a/docs/adr/0013-unified-error-model.md +++ b/docs/adr/0013-unified-error-model.md @@ -66,7 +66,7 @@ Finamp 以「類別+來源」去重;Riverpod 官方的全域 `retry` 設定 - 好的:使用者看到的訊息一致且可翻譯;每個音源的錯誤行為可用 fixture 測試;重試次數可預期;修正審計的 G4、G5、C5、C6、D5、D10。 - 壞的:每個音源要維護錯誤對應表;新增錯誤原因時要改 sealed 型別與所有 exhaustive `switch`(這正是想要的強制)。 -- 之後要注意:Toast 的外觀與「詳細」內容由 Toast 的設計定;播放層跳過與停止的條件見 ADR 0018; +- 之後要注意:Toast 的外觀、去重時間(5 秒)與「詳細」見 ADR 0023;播放層跳過與停止的條件見 ADR 0018; B 站 geetest 驗證互動列在功能凍結待辦。 ## 如何確認 diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index fe10f2fe8..105b5538d 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -48,7 +48,7 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 | `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | | `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只在平台層 | - 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)。 + 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)、`fmp_toast_entry`(ADR 0023)。 每條規則以官方 `analyzer_testing` 做雙向變異測試。`flutter analyze` 目前不顯示插件診斷並回報 No issues (flutter/flutter#193203),所以 CI 跑 `dart analyze --fatal-infos`,並以接線哨兵(暫放違規檔、斷言分析失敗且含規則名)證明規則接上了 `app/`。 diff --git a/docs/adr/0021-lyrics.md b/docs/adr/0021-lyrics.md index 0fe5f0fa7..70635f286 100644 --- a/docs/adr/0021-lyrics.md +++ b/docs/adr/0021-lyrics.md @@ -83,7 +83,7 @@ 7. **同步與顯示**: - 歌詞模組的 `LyricsSession` 是唯一來源,持有目前曲目的歌詞文件、偏移、顯示模式與播放狀態,與 UI 生命週期無關。 - 播放狀態、位置、速度、時間戳只在播放、暫停、seek、換歌、換速時推送,各顯示端以 frame callback 外推,不開週期計時器。 - - 子 engine 與主 engine 以一個共用 Dart 檔定義的型別化訊息溝通(JSON 序列化)。 + - 子 engine 與主 engine 以一個共用 Dart 檔定義的型別化訊息溝通(JSON 序列化);子視窗與懸浮窗不顯示提示,錯誤轉給主視窗(ADR 0023)。 - 播放頁、桌面視窗、Android 懸浮共用一套歌詞 widget;逐字漸變用 `CustomPainter`+分段 shader+`saveLayer(dstIn)` 遮罩。 - 顯示模式沿用(原文/優先翻譯/優先羅馬音),另加「逐字高亮」(預設開)。 8. **桌面歌詞視窗**(E11): diff --git a/docs/adr/0023-unified-toast.md b/docs/adr/0023-unified-toast.md new file mode 100644 index 000000000..b6b4c273f --- /dev/null +++ b/docs/adr/0023-unified-toast.md @@ -0,0 +1,101 @@ +# 0023 — 統一 Toast:單一入口、Material 單條且新的取代舊的、包住 Navigator 的宿主、遮蔽後的詳細頁與回報 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/` 的 toast 模組(`Toaster`、`ToastHost`)、錯誤詳細頁與 `ErrorReport`、外殼版面的底部位移、子視窗與懸浮窗的錯誤轉送、`fmp_lints` + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-toast/research/current-state.md`,已以程式碼核對): + +- SnackBar 只在 `toast_service.dart:109` 建立,但入口有三條並存:`failure(context, e)`、`error(context, 文字)`、背景 stream。 + 靜態呼叫共 161 處、散在 45 個檔。 +- 送出前先清掉目前的提示(`:240-241`),所以新的蓋掉舊的;成功 1.5 秒、錯誤 3 秒。 +- 背景 stream 只有 `app_shell.dart:44` 在聽;`app.dart` 沒設 `scaffoldMessengerKey`。全螢幕播放頁掛在根 Navigator 上,是否看得到提示未實測(G9)。 +- 開發者模式對提示沒有任何影響,沒有「詳細」。 +- 非預期例外會以 `e.toString()` 上畫面(`audio_provider.dart:1988`);static-rule 只掃 `lib/ui`,所以漏掉。 + +已定的邊界: +- ADR 0011:錯誤歷史、遮蔽函式; +- ADR 0013:呈現表、同類提示短時間只一次、背景工作不跳提示、開發者模式附「詳細」; +- parent prd 第 3 項:單一入口;詳細可看錯誤類型、音源、請求摘要、stack trace 並複製。 + +## 考慮過的選項 + +- **三條入口並存(舊版)**:否決,G9 的來源。 +- **桌面右下角疊卡(Fluent 2)**:否決(擁有者 2026-09-28 選擇 Material 單條)。要做兩套元件並自做無障礙,連續操作時卡片會一直堆疊。 +- **依序排隊(Material 預設)**:否決。連續操作時回饋會延遲好幾秒。 +- **`fluttertoast`**:否決,沒有 Windows 實作。 +- **`toastification`**:否決,沒有動作參數、沒有 live region。 +- **把報告內容放進 GitHub 網址**:否決。網址會被瀏覽器記錄,也有長度上限。 +- **一般使用者完全看不到回報**:否決(擁有者選擇預期外的錯誤可回報)。 +- **子視窗各自顯示提示**:否決。多個 engine 各自一份提示狀態,去重會失效。 + +## 決定 + +1. **單一入口 `Toaster`**(provider 注入,不需 `BuildContext`): + - `success`、`info`、`warning` 收 i18n 字串; + - `error(AppError, {operation})` 只收 `AppError`,由 ADR 0013 的對應表轉成訊息; + - 各自最多一個動作。 + + 背景工作不呼叫它,只更新對應畫面的狀態。錯誤不論是否顯示提示,都經 log 門面寫入錯誤歷史(ADR 0011)。 +2. **外觀**:Material `SnackBar`,`floating`,四種語意色加圖示。 + - 位置: + - 手機:迷你播放列與底部導覽列之上; + - 桌面:播放列之上置中,最寬 560px; + - 全螢幕頁:貼底部安全區。 + + 外殼版面發佈「底部被佔用的高度」,由宿主算邊距。 + - 一次一則,新的立刻取代目前的。 + - 時長:成功與資訊 4 秒,錯誤與警告 6 秒。帶動作的也照此自動消失;系統開啟無障礙導覽時才停留到手動關閉。 + - 去重:同類別+同音源(非錯誤為同一訊息)5 秒內只顯示一次,即 ADR 0013 的「短時間」。 +3. **層級(G9)**: + - `ToastHost` 放在 `MaterialApp.builder`,以一個 `ScaffoldMessenger` 與透明 `Scaffold` 包住 Navigator,所以全螢幕頁、對話框、底部面板之上都看得到。 + - 桌面歌詞子視窗與 Android 懸浮窗不顯示提示,錯誤以型別化訊息(ADR 0021)轉給主視窗的 `Toaster`。 + - App 在背景時不顯示、不發系統通知,錯誤仍進錯誤歷史。 +4. **詳細頁與回報**: + - 誰看得到:開發者模式下每則錯誤提示附「詳細」;一般使用者只有 `Unsupported`、`UnexpectedError` 附「回報」,開同一頁。 + - `ErrorReport` 在錯誤發生時組裝一次並經 ADR 0011 的遮蔽函式,顯示、複製、回報都用這一份。內容: + - 錯誤類型與原因、音源(插件 id 與版本)、使用者動作; + - 請求摘要(方法、已遮蔽網址、狀態碼、耗時)、stack trace; + - App 版本與 flavor、系統與版本、ISO 8601 時間。 + - 詳細頁文字可選取,按鈕: + - 「複製」:Markdown 格式; + - 「在 GitHub 回報」:先複製,再開新增 issue 頁(bug 範本),內容不放進網址。第一次使用提醒 repo 公開、送出前檢查。 + - Debug 頁的錯誤歷史用同一個詳細頁。 +5. **無障礙**: + - 使用 `SnackBar` 內建的 live region:朗讀但不搶焦點。 + - 單獨朗讀用 `SemanticsService.sendAnnouncement(View.of(context), …)`,不用已棄用的 `announce`(與多視窗不相容)。 + +採用的慣例: +- Material 3 Snackbar 規範:一次一則、單一動作、4–10 秒、避開底部導覽、live region; +- Finamp、Immich、LocalSend 以一個 service 包 SnackBar; +- Spotube 讓提示層浮在對話框之上; +- Finamp 以錯誤類型為鍵去重; +- NewPipe `ErrorActivity` 的詳細頁、「複製」與「回報到 GitHub」。 + +## 後果 + +- 好的: + - 一個入口、一種外觀; + - 在所有畫面都看得到提示; + - 例外原文不會上畫面; + - 開發者能看詳細並複製; + - 一般使用者能回報 bug,內容先遮蔽。 +- 壞的: + - 新的會取代舊的,連續出現時較早的一則可能來不及讀,要靠錯誤歷史補看; + - 一般使用者在回報頁會看到技術內容; + - 外殼要負責發佈底部位移。 +- 之後要注意:repo 目前沒有 issue 範本,落地時新增 `.github/ISSUE_TEMPLATE/bug_report.yml`;系統層通知不在本 ADR 範圍。 + +## 如何確認 + +- lint `fmp_toast_entry`(加入 ADR 0015 的 `fmp_lints`):`SnackBar(`、`ScaffoldMessenger.of`、`showSnackBar`、`clearSnackBars` 只准在 toast 模組,依 ADR 0015 寫雙向變異測試。 + 它取代舊 `error_presentation_static_rule_test.dart` 中「UI 不得自組錯誤文字」的部分。`error(AppError)` 的型別擋掉以字串傳例外原文。 +- 單元測試: + - 去重視窗、取代、時長; + - 開發者模式與一般使用者的按鈕; + - `ErrorReport` 經遮蔽(假 cookie、token、簽名網址不出現在 Markdown); + - GitHub 網址不含報告內容。 +- widget 測試:全螢幕路由與對話框開啟時送出提示,提示可見;底部位移依外殼發佈的高度。 +- 第一個里程碑實測:提示在全螢幕頁與對話框之上可見(目前依原始碼推得);Windows Narrator 下提示不凍結無障礙樹(上游 #190357 類問題)。 From 63a04c31b7b993e37779f244deb55519570ad023 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:12:54 +0800 Subject: [PATCH 089/133] chore(task): archive design-toast --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 15 ++++++++------- .../2026-09}/09-28-design-toast/check.jsonl | 0 .../2026-09}/09-28-design-toast/design.md | 0 .../2026-09}/09-28-design-toast/implement.jsonl | 0 .../2026-09}/09-28-design-toast/implement.md | 10 +++++----- .../2026-09}/09-28-design-toast/prd.md | 0 .../09-28-design-toast/research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../09-28-design-toast/research/prior-art.md | 0 .../2026-09}/09-28-design-toast/task.json | 6 +++--- 10 files changed, 16 insertions(+), 15 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/implement.md (73%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-toast/task.json (87%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index ffd1ed5b9..90385fbcc 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -126,7 +126,7 @@ flowchart LR | 14 | 11 下載與權限(✅ 完成,ADR 0020) | 依賴播放核心的本地播放路徑。 | | 15 | 15 歌詞(✅ 完成,ADR 0021) | 依賴 1、13。 | | 16 | 19 發版與更新(✅ 完成,ADR 0022) | 依賴 10、16;你已給出流程要求。 | -| 17 | 3 Toast | 依賴 2、18。 | +| 17 | 3 Toast(✅ 完成,ADR 0023) | 依賴 2、18。 | | 18 | 5 UI/UX | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | | 19 | 4 Debug 頁 | 把 18、3、8 的成果收成正式工具。 | | 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | @@ -226,6 +226,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0018:兩個後端的前瞻交接(gapless);Android 換歌時不釋放音訊焦點。 - ADR 0015:`fmp_lints` 接上 `app/`,`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)。 - ADR 0022:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(測試 repo 或 dry-run)。 +- ADR 0023:提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹。 ## 8. 延後到特定里程碑的實測 @@ -243,13 +244,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 19 項完成後) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 3 項完成後) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0022`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0023(Toast)。 -- **下一項:第 3 項「Toast」**(尚未建 task)。 -- 之後順序:5 UI/UX(桌面播放器版面給 2–3 種讓使用者選)→ 4 Debug 頁(含插件開發工具、音源健康檢查)→ 7 里程碑定稿。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0023`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0024(UI/UX)。 +- **下一項:第 5 項「UI/UX」**(尚未建 task):設計系統 token、響應式規則、i18n、無障礙與鍵盤操作;桌面播放器頁給 2–3 個版面方案讓使用者選。 +- 之後順序:4 Debug 頁(含插件開發工具、音源健康檢查、錯誤歷史用 ADR 0023 的詳細頁)→ 7 里程碑定稿。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 - 工作守則(本輪累積): diff --git a/.trellis/tasks/09-28-design-toast/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-toast/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-toast/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-toast/check.jsonl diff --git a/.trellis/tasks/09-28-design-toast/design.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/design.md similarity index 100% rename from .trellis/tasks/09-28-design-toast/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/design.md diff --git a/.trellis/tasks/09-28-design-toast/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-toast/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-toast/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-toast/implement.jsonl diff --git a/.trellis/tasks/09-28-design-toast/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/implement.md similarity index 73% rename from .trellis/tasks/09-28-design-toast/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/implement.md index 4c415fc48..8906df6f7 100644 --- a/.trellis/tasks/09-28-design-toast/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-toast/implement.md @@ -1,12 +1,12 @@ # 執行計畫:第 3 項(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0023-unified-toast.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: +1. [x] 核准後寫 `docs/adr/0023-unified-toast.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§6;被否決的方案: 三條入口並存(舊版)、桌面右下角疊卡、依序排隊、`fluttertoast`(沒有 Windows)、`toastification`(沒有動作與 live region)、 把報告內容放進 GitHub 網址、一般使用者完全看不到回報、子視窗各自顯示提示。 -2. [ ] 其他 ADR 各加一句指向 ADR 0023:0013(提示外觀、去重時間、詳細)、0015(`fmp_toast_entry`)、0021(子視窗提示轉主視窗)。 -3. [ ] `phase2-plan.md`:§3 第 3 項標 ✅(ADR 0023);§7 第一個里程碑加入「提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹」; +2. [x] 其他 ADR 各加一句指向 ADR 0023:0013(提示外觀、去重時間、詳細)、0015(`fmp_toast_entry`)、0021(子視窗提示轉主視窗)。 +3. [x] `phase2-plan.md`:§3 第 3 項標 ✅(ADR 0023);§7 第一個里程碑加入「提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹」; §10 交接段更新,下一項 5 UI/UX,下一份 ADR 0024。 -4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 -5. [ ] `task.py finish`、`task.py archive design-toast --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-toast --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-toast/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-toast/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/prd.md diff --git a/.trellis/tasks/09-28-design-toast/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-toast/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/research/current-state.md diff --git a/.trellis/tasks/09-28-design-toast/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-toast/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-toast/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-toast/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-toast/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-toast/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-toast/task.json b/.trellis/tasks/archive/2026-09/09-28-design-toast/task.json similarity index 87% rename from .trellis/tasks/09-28-design-toast/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-toast/task.json index a80b8ed12..feb3c5784 100644 --- a/.trellis/tasks/09-28-design-toast/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-toast/task.json @@ -3,7 +3,7 @@ "name": "design-toast", "title": "Design unified toast", "description": "Phase-2 item 3: single toast entry, appearance and placement per form factor, queueing, developer details, visibility over every route", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 92ce862a5caec23ac3539c2c423a611b98a9f05f Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:13:41 +0800 Subject: [PATCH 090/133] chore(task): start design-ui-ux --- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .trellis/tasks/09-28-design-ui-ux/check.jsonl | 0 .../tasks/09-28-design-ui-ux/implement.jsonl | 0 .trellis/tasks/09-28-design-ui-ux/prd.md | 19 ++++++++++++++ .trellis/tasks/09-28-design-ui-ux/task.json | 26 +++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 .trellis/tasks/09-28-design-ui-ux/check.jsonl create mode 100644 .trellis/tasks/09-28-design-ui-ux/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-ui-ux/prd.md create mode 100644 .trellis/tasks/09-28-design-ui-ux/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index f67cd5e93..0480486b2 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -36,7 +36,8 @@ "09-28-design-downloads", "09-28-design-lyrics", "09-28-design-release-update", - "09-28-design-toast" + "09-28-design-toast", + "09-28-design-ui-ux" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-ui-ux/check.jsonl b/.trellis/tasks/09-28-design-ui-ux/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-ui-ux/implement.jsonl b/.trellis/tasks/09-28-design-ui-ux/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md new file mode 100644 index 000000000..ae1be3623 --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -0,0 +1,19 @@ +# Design UI/UX system + +## Goal + +Phase-2 item 5: design tokens, responsive layouts, i18n, accessibility and keyboard, desktop player page layout options, user guide + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-ui-ux/task.json b/.trellis/tasks/09-28-design-ui-ux/task.json new file mode 100644 index 000000000..4d152eb19 --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-ui-ux", + "name": "design-ui-ux", + "title": "Design UI/UX system", + "description": "Phase-2 item 5: design tokens, responsive layouts, i18n, accessibility and keyboard, desktop player page layout options, user guide", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From d090c5c07b22e201bc23aa3f4a1a629b55ba3a82 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:29:11 +0800 Subject: [PATCH 091/133] chore(task): add ui-ux research and draft requirements --- .trellis/tasks/09-28-design-ui-ux/prd.md | 67 ++- .../research/current-state.md | 296 ++++++++++++ .../research/packages-and-platform.md | 305 ++++++++++++ .../09-28-design-ui-ux/research/prior-art.md | 441 ++++++++++++++++++ 4 files changed, 1098 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-ui-ux/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-ui-ux/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index ae1be3623..8bcbc52c9 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -1,19 +1,64 @@ -# Design UI/UX system +# 設計:UI/UX 設計系統、響應式與桌面播放頁(階段二第 5 項) -## Goal +## 目標 -Phase-2 item 5: design tokens, responsive layouts, i18n, accessibility and keyboard, desktop player page layout options, user guide +為 `app/` 定下設計 token(間距、字級、圓角、色彩)、各視窗寬度的版面與導覽、桌面播放頁版面、i18n、無障礙與鍵盤操作、使用者指南的去留。產出 ADR 0024。技術設計見 `design.md`,執行步驟見 `implement.md`。 -## Requirements +依據:parent `prd.md` 階段二第 5 項;`docs/audit/questions.md` U1–U8(擁有者全部勾「重寫時處理」;U7 右側「正在播放」面板保留常駐;U8 大斷點實作)、E20(不確定); +`docs/audit/ui.md`;`phase2-plan.md` §5(E20 傾向刪除改連 docs)、§8(CJK 字型依平台 fallback);ADR 0009(平台層)、0011(設定分組)、0021(歌詞 widget 共用、逐字高亮)、0023(Toast 位置)。 -- TBD +## 現況(`research/current-state.md`+`docs/audit/ui.md`,關鍵項已核對) -## Acceptance Criteria +- **主題**:`ColorScheme.fromSeed`(預設紫色 seed+9 組 preset),沒有 dynamic color;深淺色與系統三態;8 個 sub-theme;`textTheme` 沒有自訂字級。 +- **token**:只有 `AppRadius` 與版面常數;`EdgeInsets` 約 250 處、`SizedBox` 約 500 處字面數字,29 處 `fontSize:` 繞過主題(U1)。事實標準是 4 的倍數。 +- **字型**:Windows fallback `Microsoft YaHei UI`、`Microsoft YaHei`(**都是簡體字形,沒有繁中**),其他平台 `Noto Sans SC`;使用者主要用繁中。 +- **斷點**:`WindowClass` 與 M3 同值(600/840/1200/1600);`large`、`extraLarge` 沒有對應版面(U8)。 +- **導覽**:手機底部導覽列、桌面 NavigationRail;右側「正在播放」面板(`TrackDetailPanel`,預設 412dp、可拖寬度)在寬度 ≥ 840 的所有頁面常駐(U7)。 + 迷你播放器 5 顆控制+桌面 2 顆(輸出裝置、音量),窄桌面視窗時標題只剩 2 個字(U4)。 +- **播放頁**:四種版面 `narrow`/`wideSingle`/`wideSplit`(左封面+控制 5:右歌詞 7)/`shortSplit`;背景是模糊封面(sigma 48)+ 60% 表面色; + 寬版沒有佇列欄,佇列要另開。 +- **i18n**:slang,38 檔 × 3 語言(zh-CN、zh-TW、en)= 1176 key,**base locale 是 zh-CN**;`formatCount` 強制一位小數造成「4600.0萬」「46.0M」,英文沒有複數(「1 tracks」)(U6)。 +- **鍵盤**:App 內 `Shortcuts`/`Actions` 0 處,Esc 離不開播放頁,深色主題焦點指示幾乎看不見,Tab 要穿過整個清單(U2);全域熱鍵(`hotkey_manager`)有設定頁。 +- **無障礙**:大播放鍵沒有名稱、迷你播放器是按鈕包按鈕(U3);沒有 golden 測試、沒有對比度測試。 +- **搜尋頁**:來源篩選列被排序鈕蓋住、沒有可捲動提示(U5)。 +- **使用者指南(E20)**:7 段可展開卡片、每語言約 40 條目。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- **M3**:寬度 class 與 FMP 同值;導覽列只到 medium,rail 從 medium 起;canonical layouts 有 list-detail、supporting pane、feed。 + Material 3 Expressive 在 Flutter 端官方表示目前不開發(#168813)。spacing token 以 4/8dp 為基礎。 +- **桌面播放頁先例**: + - 歌詞在右側:Apple Music 全螢幕播放器、Feishin(左 50% 封面,右側分頁:佇列/歌詞/相關)。 + - 右欄分頁(歌詞與佇列互斥、記住選擇):Namida 寬版播放頁(左右各半)。 + - 沉浸式歌詞佔滿、底部控制列帶小封面、網格漸層背景:Harmonoid。 + - Spotify 以右側 Now Playing 面板與底部播放列為主,佇列、歌詞是獨立頁。 + - 佇列在多數產品是獨立頁或側滑面板;背景主流是模糊封面或封面取色。 +- **快捷鍵**:Spotify 官方表(Space 播放暫停、Ctrl+F/Ctrl+K 搜尋、Ctrl+S 隨機、Ctrl+R 循環、Alt+Shift+Q 佇列);Apple Music(Space、左右鍵上下一首、Cmd+↑↓ 音量)。 +- **使用者指南**:Spotube、Namida、Finamp、Feishin 只有 About 頁並連到 GitHub 或網站;NewPipe、LocalSend 有 About 加 FAQ 連結。沒有大量內建說明頁的先例。 +- **Flutter**:`WindowSizeClass` 不在 framework;`flutter_adaptive_scaffold` 已停止維護且無官方替代;Material 正拆出為 `material_ui`(1.4.0,舊版已間接依賴 1.1.1),舊路徑移除時程不明。 + `intl` 的 `NumberFormat.compact`:en `46M`、zh_TW `4600萬`、zh_CN `4600万`(本機實測)。slang 4.19.2 支援複數與參數。 + `SemanticsRole`(dart:ui)、`meetsGuideline(textContrastGuideline)` 可用;golden 測試可用 `alchemist` 解決跨平台字型差異。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已確定的方向 + +- U1–U8 都在重寫時處理;U7 右側面板保留常駐;U8 實作大斷點版面。 +- Toast 位置照 ADR 0023;播放頁與桌面視窗的歌詞共用一套 widget(ADR 0021)。 + +## 待決定 + +1. 桌面播放頁的版面方案(2–3 選 1,含大螢幕變化)。 +2. 保留哪些語言、base locale。 +3. App 內鍵盤快捷鍵的範圍。 +4. 窄桌面視窗的迷你播放器保留哪些控制。 +5. 使用者指南(E20)去留。 + +## 不在範圍 + +- dynamic color(Material You 取色):舊版沒有,屬新功能。 +- Debug 頁的版面(第 4 項)。 + +## 驗收條件 + +- [ ] ADR 0024 記錄:token 與主題、字型 fallback、斷點與導覽、右側面板、桌面與手機播放頁、迷你播放器、i18n 與數字格式、無障礙、鍵盤與焦點、使用者指南、閘門(lint、對比度、golden)。 +- [ ] U1–U8、E20 各自對到決定。 +- [ ] `phase2-plan.md` §3 第 5 項標 ✅ 與 ADR 編號。 diff --git a/.trellis/tasks/09-28-design-ui-ux/research/current-state.md b/.trellis/tasks/09-28-design-ui-ux/research/current-state.md new file mode 100644 index 000000000..9f50adb59 --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/research/current-state.md @@ -0,0 +1,296 @@ +# current-state.md — UI/UX 現況(補 `docs/audit/ui.md` 未載者) + +> 查證日 2026-09-28。查證方式:先讀 `docs/audit/ui.md` 全文(審計日 2026-09-26,HEAD `6d78fe23`), +> 本檔**只寫它沒有的事實**;`ui.md` 已完整記載者以一行指回,不重複。 +> 證據全部來自靜態讀源碼(`檔案:行號`,branch `docs/audit`);**未執行 App、未用 VM Service、未看截圖**。 +> 工具版本:Flutter 3.47.1 stable、Dart 3.13.1(`flutter --version`)。 +> 標「推測」者為未實測的程式碼推論。 + +--- + +## 1. 主題來源(`lib/ui/theme/`) + +`lib/ui/theme/` 只有兩個檔:`app_theme.dart`(223 行)、`theme_preset_colors.dart`(45 行)。 + +**色彩是 seed,不是 dynamic color。** `dynamic_color` 既不在 `pubspec.yaml` 也不在 `pubspec.lock`; +`lib/` 內只有兩處 `ColorScheme.fromSeed`(`lib/ui/theme/app_theme.dart:28`、`lib/ui/startup_failure_app.dart:37`)。 +Material You 取色未實作,`lib/` 內也沒有 `DynamicColorBuilder`。 + +- seed 色預設 `Color(0xFF6750A4)`(`theme_preset_colors.dart:15`),另有 9 組 preset(`:17-31`)。 +- 若使用者選的是 preset 色,`colorScheme.copyWith` 只覆寫 5 個 role:`primary`、`onPrimary`、 + `primaryContainer`、`onPrimaryContainer`、`surfaceTint`(`app_theme.dart:44-50`);其餘 role 全由 + `ColorScheme.fromSeed` 決定。`primaryContainer` 用 `Color.alphaBlend`(light 0.18 / dark 0.32, + `:53-60`),`onPrimary` / `onPrimaryContainer` 用 luminance 比對挑黑或白(`:62-67`)。 + 未選色(`primaryColor == null`)時直接用 `fromSeed` 的結果(`:33-35`)。 +- 深/淺色只差一個 `Brightness`;`lightTheme` / `darkTheme`(`:209-222`)都走同一個 `_theme`(`:113-206`), + `useMaterial3: true`(`:126`)。`themeMode` 有 system / light / dark 三態(`lib/providers/settings/theme_provider.dart:17`、 + `:104-107` 的循環切換),在 `lib/app.dart:151` 傳進 `MaterialApp`。 +- 只有 8 個 sub-theme:`appBarTheme`、`cardTheme`、`listTileTheme`、`navigationBarTheme`、 + `navigationRailTheme`、`navigationDrawerTheme`、`inputDecorationTheme`、`sliderTheme` + (`app_theme.dart:134-200`)。檔內註解(`:107-112`)明說八個 sub-theme 全部只讀 `colorScheme` 與 `AppRadius`、 + 沒有一處看亮度。 +- `theme_preset_colors.dart` 的 `storesAsDefault` 只用在 `themePresetColorFor`:`color == null` 時回傳預設項 + (`:33-45`)。 + +### 字型與 CJK fallback + +- `fontFamily` 來自使用者設定,未設時為 `null`(`app_theme.dart:129-131`)。 + `textTheme` **只套 `fontFamilyFallback`,沒有自訂字級**(`:203-205`)。 +- fallback 由 `_buildFontFallback` 產生(`:96-105`),只有兩個分支: + - Windows:使用者選了具體字型時 `[選的字型, 'Microsoft YaHei UI', 'Microsoft YaHei']`(`:99-101`); + 否則 `['Microsoft YaHei UI', 'Microsoft YaHei']`(`:102`)。 + - **其餘所有平台**(含 Android、Linux、macOS):`['Noto Sans SC']`(`:104`)。 +- 這是硬編碼在 `lib/` 的清單,沒有平台條件以外的 fallback 鏈; + `app_theme.dart:1` 只 import `dart:io` 的 `Platform`,`Platform.isAndroid` / `isLinux` 沒有被檢查過。 +- 可選字型清單(`:70-93`):Windows 8 項(系統預設 + Microsoft YaHei UI / SimSun / SimHei / KaiTi / + FangSong / Yu Gothic UI / Meiryo);Android 7 項(系統預設 + `sans-serif` / `serif` / + `sans-serif-medium` / `sans-serif-light` / `sans-serif-condensed` / `monospace`)。 + +--- + +## 2. 播放頁版面結構 + +兩個全螢幕播放頁:`PlayerPage`(`lib/ui/pages/player/player_page.dart`,1220 行)與 +`RadioPlayerPage`(`lib/ui/pages/radio/radio_player_page.dart`)。相關元件檔: + +| 檔案 | 內容 | +|------|------| +| `lib/ui/pages/player/player_page.dart` | `PlayerPage` + `PlayerLayoutMode` + `resolvePlayerLayout` + `PlayerShortSplitContent` + `_DetailContent` 等私有類別 | +| `lib/ui/widgets/layout/immersive_player_scaffold.dart` | 共用沉浸式外殼(背景 Stack + 透明 AppBar + overlay alpha 常數) | +| `lib/ui/widgets/player/blurred_cover_backdrop.dart` | `TrackBlurredBackdrop` / `RadioBlurredBackdrop` / `BlurredCoverBackdrop` | +| `lib/ui/widgets/player/cover_art_container.dart` | 封面容器 | +| `lib/ui/widgets/player/player_play_pause_button.dart` | 大播放鍵(`ui.md` §5.2 的無障礙問題就在這) | +| `lib/ui/widgets/player/compact_volume_control.dart` | 播放頁頂列的音量(含靜音) | +| `lib/ui/widgets/player/fmp_audio_device_selector.dart` | 音訊輸出裝置選擇器(播放頁與迷你播放器共用) | +| `lib/ui/widgets/player/audio_stream_info_section.dart` | 詳情面板底部的音訊串流資訊 | +| `lib/ui/widgets/lyrics/lyrics_display.dart:23` | `LyricsDisplay`(`_buildLyricsPanel` 用的歌詞欄);同目錄另有 `lyrics_offset_bar.dart`、`lyrics_styled_text.dart`、`lyrics_style_dialog.dart`。獨立浮動視窗在 `lib/ui/windows/lyrics_window.dart`(`ui.md` §1.1) | + +兩者共用外殼 `ImmersivePlayerScaffold`(`lib/ui/widgets/layout/immersive_player_scaffold.dart:17`), +它的 dartdoc(`:9-15`)說明:背景由全頁 `Stack` 統一繪製、AppBar 透明且置於同一 Stack、不用 `Scaffold.appBar`。 + +### 版面決策 + +`enum PlayerLayoutMode { narrow, wideSingle, wideSplit, shortSplit }`(`player_page.dart:44-59`), +由純函式 `resolvePlayerLayout(Size size, {required bool hasLyrics})` 決定(`:74-83`): + +| 條件 | 結果 | +|------|------| +| 寬 `atLeast(WindowClass.expanded)`(≥ 840dp)**且** 高 ≥ `AppLayout.playerWideMinHeight`(520dp),有歌詞 | `wideSplit` | +| 同上,無歌詞 | `wideSingle` | +| 高 < 520dp **且** 寬 > 高 | `shortSplit` | +| 其餘 | `narrow` | + +`WindowClass.of(size.width).atLeast(...)` 在 `:77`。`hasLyrics` 來自 `lyricsPaneHasContentProvider`(`:162`)。 + +> **未記載的來源**:`player_page.dart:65` 與 `app_layout.dart:61` 的註解引用「**六個對照專案**」與 Auxio 的 +> `layout-h520dp` / `layout-land`,但 repo 內沒有任何文件列出那六個專案是誰 +> (`grep -riE "auxio|namida|harmonoid|spotube|finamp|feishin|cider"` 全 repo 只命中: +> `player_page.dart:65`、`app_layout.dart:61`、`.trellis/tasks/09-26-fmp-rewrite/prd.md:105-106` 的競品清單、 +> 以及 `09-27-design-background-tasks` 的背景任務研究)。相關 commit: +> `044889e1`(封面與控制列在矮視窗左右並排)、`4a23ae86`(高度下限 520dp 抄 Auxio, +> 見 `00-bootstrap-guidelines/research/providers-ui.md:148`)。 + +### 背景(模糊封面) + +播放頁傳給 `TrackBlurredBackdrop` 的兩層 overlay alpha **都是 0**(`player_page.dart:374-375`), +電台頁也是 0(`radio_player_page.dart:94-95`)。真正上色的 overlay 在 +`ImmersivePlayerScaffold`: + +- body 區:`surface` alpha **0.60** + `surfaceContainerHighest` alpha **0.08** + (`immersive_player_scaffold.dart:34-35`,套用點 `:88-95`)。 +- AppBar 區:`surface` alpha **0.50** + `surfaceContainerHighest` alpha **0.06**(`:36-37`,套用點 `:71-75`)。 + +底圖 `BlurredCoverBackdrop`(`lib/ui/widgets/player/blurred_cover_backdrop.dart:110-176`)三層: +`ColoredBox(surface)` → `ImageFiltered(ImageFilter.blur(sigmaX: 48, sigmaY: 48))` 包 `Image(fit: BoxFit.cover)` +(`:139-151`)→ 兩層 overlay。圖來源是 `TrackBlurredBackdrop` 用 `TrackCover.imageProviderCandidates` +(`variant: TrackCoverVariant.backdrop`,`blurred_cover_backdrop.dart:44-49`)。 + +→ 事實上的播放頁背景 = **封面模糊(sigma 48)再蓋 60% surface 色**。 +`ui.md` §6.2 觀察 7「背景模糊色塊在右半部偏灰」是這個機制的視覺結果(**推測**,未實測)。 + +### 各版面內容 + +- **`narrow`**(`_buildNarrowPlayerContent`,`:385-404`):`Padding(all: 24)` 內 `Column` → + `Expanded(_buildNarrowMediaSection)` + `SizedBox(32)` + 控制區。 + `_buildNarrowMediaSection`(`:490-519`)是 `AnimatedSwitcher`,`_showLyrics` 為 true 時顯示 + `LyricsDisplay`,否則顯示封面(`ConstrainedBox(maxWidth: AppLayout.playerCoverMax = 420)`, + 長按切換;`:503-516`)。 +- **`wideSingle`**(`:225-232`):同一份 narrow 內容置中,`ConstrainedBox(maxWidth: + AppLayout.playerContentMaxWide = 720)`。 +- **`wideSplit`**(`_buildDesktopPlayerContent`,`:406-442`):`Padding(all: 24)` 內 `Row` → + 左 `Expanded(flex: 5)` = `Column`〔`Expanded(Center(封面, max 420))` + `SizedBox(24)` + 控制區〕; + `SizedBox(width: 32)`;右 `Expanded(flex: 7)` = `LyricsDisplay` 佔滿高度。 + **這個版面沒有佇列欄、沒有右側資訊面板、沒有標題列**;flex 5:7 是寫死的(`:430`、`:440`)。 +- **`shortSplit`**(`PlayerShortSplitContent`,`:90-118`):`Padding(all: 24)` 內 `Row` → + 左 `Expanded(媒體)`、中 `SizedBox(32)`、右 `Expanded(Center(SingleChildScrollView(控制區)))`。 +- **控制區**(`_buildControlSection`,`:444-489`)由上而下:`_buildTrackInfo`(標題/作者)→ + gap 20(narrow 為 32)→ `_buildProgressBar` → gap 16(narrow 為 24)→ `_buildPlaybackControls`。 + gap 值由 `useCompactGaps = layoutMode != PlayerLayoutMode.narrow`(`:167`)決定。 +- **播放控制列**(`_buildPlaybackControls`,`:661-763`):`Row(mainAxisAlignment: spaceEvenly)`, + 5 顆依序為 隨機/亂序(`Icons.shuffle`)、上一首(`Icons.skip_previous`,`iconSize: 40`)、 + `PlayerPlayPauseButton`、下一首(`Icons.skip_next`,`iconSize: 40`)、循環(`_getLoopModeIcon`)。 +- **頂列**(`ImmersivePlayerScaffold` 提供 chrome):`leading` 固定是 + `IconButton(Icons.keyboard_arrow_down, tooltip: t.player.collapse)`(`immersive_player_scaffold.dart:47-51`); + `player_page.dart` 傳入的 `appBarActions`(`:240-364`)依序為:加入歌單 `PopupMenuButton` + (只有 `currentTrack != null` 時,`:242-271`)、`FmpAudioDeviceSelector` + (`isDesktopPlatform && hasSelectableDevices`,`:276-282`)、`CompactVolumeControl`(`isDesktopPlatform`,`:283-288`)、 + `IconButton(Icons.info_outline)`(`:292`)、`PopupMenuButton(Icons.more_vert)` 溢出選單(`:298`)。 + Windows 另有 `DragToMoveArea`(`immersive_player_scaffold.dart:76`)。 + +--- + +## 3. 導航殼與迷你播放器(UI 元件清單) + +`ui.md` §1.2 已載三種版面、導航軌寬度與 MiniPlayer 掛載位置。以下補控制項清單與右側面板細節。 + +### MiniPlayer(`lib/ui/widgets/player/mini_player.dart`,474 行) + +- 標題區:曲名 + 作者(`:345-380`)。 +- 控制群(`_buildControls` 尾段,`:420-467`)共 5 顆,順序:隨機(`Icons.shuffle`,size 20)、 + 上一首(`Icons.skip_previous`,24)、`MiniPlayerPlayPauseButton`、下一首(`Icons.skip_next`,24)、 + 循環(`Icons.repeat` / `Icons.repeat_one`,20)。 +- 桌面尾隨群 `MiniPlayerDesktopControls`(`lib/ui/widgets/player/mini_player_desktop_controls.dart:46-56`): + `SizedBox(width: 8)` + 音訊輸出裝置選擇器(僅 `hasSelectableDevices` 時)+ 音量控制。 + 該檔 dartdoc(`:9-13`)說明音樂與電台迷你播放器共用這一份。 +- 插入條件 `isDesktopPlatform`(`mini_player.dart:96`)。 +- 合計桌面寬版 5 + 2 = **7 顆**(與 `ui.md` U4 的「7 顆鈕」一致)。 + +### 右側「正在播放」面板 `TrackDetailPanel` + +- 檔案 `lib/ui/widgets/panels/track_detail_panel.dart`(1347 行)。 +- 寬度 token 在 `lib/core/constants/app_layout.dart`:預設 `detailPanelDefault = 412`、 + 下限 `detailPanelMin = 320`、比例上限 `detailPanelMaxFraction = 0.4`(`:19-25`); + 實際上限 `max(320, windowWidth * 0.4)`(`detailPanelMaxFor`,`:60-61`); + 存進 DB 的上限 `detailPanelStoredMax = 1600`(`:31`)。收起條寬 36dp/hover 54dp(`:33-36`)。 +- 掛載點 `ResponsiveScaffold._ExpandedLayout`(`lib/ui/layouts/responsive_scaffold.dart:457-577`), + spacer + 真實面板「始終在 widget tree 中」(`:457` 註解),拖曳結束時 commit 寬度(`:577`)。 +- 內容(`_DetailContent`,`:703-1043`)由上而下:可點封面(`_ClickableCover`,`:1048`)、 + owner 頭像 + 名稱 + 發布日期列(`:860-886`)、`_buildSimpleStats`、下一首(有 upcoming 才顯示,`:985-1046`)、 + 簡介(`ExpandableTextSection`)、熱門評論(`CommentPager`)、音訊串流資訊(`AudioStreamInfoSection`,最下方)。 +- `_buildSimpleStats`(`:945-983`)分兩種:歌曲來源顯示專輯名 + 留言數;影片來源顯示播放數 + 點讚數 + (部分音源再加收藏數)。 +- header 有「正在播放」標題與收起鈕(`:440-470`)。 +- 電台變體 `_RadioDetailContent`:直播公告、簡介、標籤(`:1142-1213`)。 + +--- + +## 4. i18n + +`ui.md` §4 已載三語言、38 namespace、每語言 1176 key、`slang.yaml` 的 `base_locale: zh-CN`、 +缺漏 0、同值檢查、語言選擇四選一、複數與數字格式問題。以下補結構與慣例。 + +- 目錄結構 `lib/i18n//.i18n.json`;本檔重數確認三語言各 **38 檔、1176 葉節點** + (Python 遞迴數 JSON 葉)。 +- `lib/i18n/` 內另有產物 `strings.g.dart` 與 `strings_.g.dart`(已 gitignore,`ui.md` 已載)。 +- `slang.yaml` 完整鍵值:`base_locale: zh-CN`、`namespaces: true`、`input_directory: lib/i18n`、 + `input_file_pattern: .i18n.json`、`output_directory: lib/i18n`、`output_file_name: strings.g.dart`、 + `lazy: false`(檔內註解:slang 4 預設 `lazy: true` 為 web deferred loading,Android/Windows 不支援, + 且 lazy 會讓 `LocaleSettings` 的同步版 API 拿不到未載入的語言)。 +- 命名慣例:namespace = 檔名(`player.i18n.json` → `t.player.*`),key 為 camelCase, + 值皆為**純字串**(無 ICU 巢狀、無 plural 形式)。巢狀只用到兩層以內,例如 + `t.userGuide.quickStart.title`、`t.settings.font.microsoftYaHei`、`t.audioSettings.qualityLevel.high`。 +- **全樹沒有用 slang 的 plural**:1176 個 key 沒有一個是 plural 形式;英文複數靠字串內插 + `"$n tracks"`(`ui.md` §4 已載的 `1 tracks`)。 +- locale 執行期管理在 `lib/providers/settings/locale_provider.dart`:`LocaleNotifier extends Notifier` + (`:6-60`),state 為 `AppLocale?`,`null` 代表跟隨系統(走 `LocaleSettings.instance.useDeviceLocaleSync()`, + `:24-26`);持久化字串是 `'zh_CN'` / `'zh_TW'` / `'en'`(`:46-57`)。 +- `MaterialApp` 的 localizations delegates 是 `GlobalMaterialLocalizations.delegates` + (`lib/app.dart:48`、`:140`)。 +- 數字格式 `formatCount(int)`(`lib/core/utils/number_format_utils.dart:6-38`):看 + `LocaleSettings.currentLocale`;`en` 走 B / M / K(`:17-26`),其餘走 億 / 万 + (繁 `億`/`萬`,簡 `亿`/`万`,`:28-37`);**兩條路徑都 `toStringAsFixed(1)`**,沒有千分位, + 10000(中文)/1000(英文)以下回原數字。 + +--- + +## 5. 鍵盤(補計數與位置) + +`ui.md` §5.3 已載「快捷鍵框架完全沒用」、全域熱鍵清單與預設值、實測結果。以下補本檔重數的計數與確切位置。 + +本檔 `grep -rn` 於 `lib/`(`--include=*.dart`): + +| API | 命中 | 說明 | +|-----|-----:|------| +| `Shortcuts(` | 0 | — | +| `Actions(` | 18 | **全部是誤配**:方法名 `_radioMenuActions()` / `_stationMenuActions()` 等與具名參數 `actions:`(`change_download_path_dialog.dart:48`)。真正的 Flutter `Actions` widget = 0 | +| `FocusTraversalGroup` | 0 | — | +| `CallbackShortcuts` / `SingleActivator` | 0 / 0 | — | +| `RawKeyboardListener` / `HardwareKeyboard` | 0 / 0 | — | +| `KeyboardListener` | 1 | `lib/ui/pages/settings/widgets/settings_desktop.dart:439`(快捷鍵錄製對話框) | +| `Focus(` / `FocusNode(` | 2 / 2 | `FocusNode` 用於錄製對話框(`settings_desktop.dart:425`);另 `windows_desktop_service.dart:496` 是 `onWindowFocus()` 方法名,非 widget | +| `autofocus` | 7 | 全在對話框或搜尋框 | +| `LogicalKeyboardKey` | 79 | 只出現在 `lib/data/models/hotkey_config.dart` 與 `settings_desktop.dart` | + +全域熱鍵:`hotkey_manager`,`HotKeyScope.system`(`hotkey_config.dart:78`),預設值在 +`HotkeyConfig.defaults()`(`:212`);清單與實測結果見 `ui.md` §5.3。 + +--- + +## 6. 使用者指南頁(E20) + +- 檔案 `lib/ui/pages/settings/user_guide_page.dart`(492 行)。`UserGuidePage` 是 `StatelessWidget`(`:7`), + `AppBar(title: t.settings.userGuide.title)`(`:15`)。 +- body 是 7 個可展開卡片 `_buildExpandableSection`(`:318` 起),每段內放 `_buildInfoItem` + 或 `_buildStepItem`(後者有序號)。 +- 7 段(依 i18n key 與行號): + 1. `quickStart`(`:19-49`)— 3 個步驟(匯入歌單、加入佇列、開始播放) + 2. `externalImport`(`:50-100`)— 7 個條目(支援平台、智慧配對、預覽、YouTube Mix 快捷、無限播放、授權匯入、匯入自動更新) + 3. `search`(`:101-145`)— 音源、排序與篩選、直播篩選、多選等 + 4. `playbackControl`(`:146-202`)— 播放控制、音訊設定指南、授權播放 + 5. `tips.lyricsTitle` 歌詞(`:203-241`)— 5 個條目 + 6. `download`(`:242-280`)— 5 個條目(設定路徑、下載歌曲、離線、下載同步、備份) + 7. `tips.desktopAndMaintenanceTitle` 桌面與維護(`:281-317`)— 4 個條目(桌面熱鍵、托盤開機、歷史、App 更新) +- 內容量(Python 數 JSON 葉節點):`lib/i18n//userGuide.i18n.json` 每語言 **83 個葉節點** + (title + description 成對,約 40 個條目);總字元數 **zh-TW 1358、zh-CN 1349、en 3830**。 +- `userGuide` namespace 另有 `liveRadio`、`explore`、`history`、`audioSettingsGuide`、`ytMix`、 + `appUpdate` 等群組,它們是**被塞在既有 section 內的條目標題**,不是獨立 section + (例如 `t.userGuide.liveRadio.title` 當作 search 段的一項,`:134`)。 +- 入口:設定頁 → 使用者指南,路由 `/settings/user-guide`(`ui.md` §1.1 的路由表;`questions.md` E20 標「不確定」)。 + +--- + +## 7. UI static-rule 一覽 + +`AGENTS.md` § Boundaries 記載規則的**性質**;以下是原始檔與它們守的東西(`test/ui/static_rules/` 4 檔 + +`test/services/static_rules/` 1 檔 + `test/support/` 與 `test/data/static_rules/` 各 1 檔)。 + +| 檔案 | 守的性質 | +|------|----------| +| `test/ui/static_rules/ui_consistency_static_rule_test.dart` | (a) 只有 `lib/ui/widgets/images/` 的語意 widget 可以呼叫底層 image API 或指名 `ImageTargetSizes` tier——比對**集合** `_imageApiOwners`(定義在 `:101` 起,比對點 `:20-31`);偵測器認得 `Image.network`、`loadImage`、`ImageTargetSizes`、`CachedNetworkImage` 等(`:56-66`)。(b) `ListTile` 的 `leading` 不可直接用 `Row`(`:33-44`) | +| `test/ui/static_rules/slider_overlay_static_rule_test.dart` | `lib/` 內除 `lib/ui/widgets/controls/scoped_slider.dart` 外,不可直接建 Material `Slider` / `RangeSlider`(含 `.adaptive`)——比對**集合**,理由:數值指示器落進 Navigator Overlay 會讓 Windows 無障礙樹停住(檔頭註解) | +| `test/ui/static_rules/error_presentation_static_rule_test.dart` | 三條:(a) async error 分支不可渲染成空(要 `ErrorDisplay(compact: true)` + retry,掃整個 `lib/ui`);(b) i18n error template 不可塞原始 exception(掃整個 `lib/`,`t.x.loadFailed(error: e.toString())` 違規,要 `userMessageFor(e)`);(c) 不可把原始 exception 交給使用者可見的 widget(要 `userMessageFor` / `ToastService.failure`)。偵測器有雙向變異測試(`:70-118`) | +| `test/ui/static_rules/watch_scope_static_rule_test.dart` | 5 個「寬且高頻」provider 不可整包 `ref.watch`(要 `.select(...)`):`audioControllerProvider`、`rankingCacheServiceProvider`、`searchSelectionProvider`、`playlistDetailSelectionProvider`、`downloadProgressStateProvider`(`:24-32`) | +| `test/services/static_rules/lyrics_window_strings_static_rule_test.dart` | 歌詞子視窗(獨立 engine)讀的每個翻譯字串都必須有人從主 isolate 推過去;漏推只會顯示簡體 fallback,不會壞掉(檔頭註解) | + +相鄰的邊界規則(非 UI 專屬,但影響 UI 程式碼的寫法):`test/support/layer_boundary_static_rule_test.dart` +(`lib/core/`、`lib/data/` 不 import `lib/services/`、`lib/providers/`)、 +`test/data/static_rules/isar_boundary_static_rule_test.dart`(`isar.` 只出現在 `lib/data/repositories/`)。 +`AGENTS.md` § Boundaries 另載「Test waits」(`pumpUntil` / `drainEventQueue`)與 +「Static rules 命名與位置」兩條規則,各由 `test/support/` 下的對應檔守。 + +**目前沒有任何規則守「間距/字級 token」**:`grep -rn AppSpacing lib` 為 0,`lib/core/constants/ui_constants.dart` +沒有間距常數類別(`ui.md` §3.1 已載);`fontSize:` 字面值 29 處也沒有規則擋。 + +### 相關測試覆蓋(無障礙與視覺回歸) + +- **沒有任何 golden test**:`grep -rln "matchesGoldenFile|goldenTest|alchemist"` 於 `test/`、`tool/` 命中 0。 +- 觸及語意的測試 9 檔,其中 2 檔用 `meetsGuideline`: + `test/ui/widgets/comment_pager_test.dart:33-34` 與 `test/ui/widgets/mini_player_accessibility_test.dart:117-118`, + 都只斷言 `androidTapTargetGuideline` 與 `labeledTapTargetGuideline`; + **`textContrastGuideline` 全 repo 沒有使用**。 +- 其餘語意測試(`test/ui/layouts/nav_rail_semantics_test.dart`、 + `test/ui/windows/lyrics_window_semantics_test.dart`、`test/ui/widgets/app_bars/custom_title_bar_test.dart`、 + `test/app_content_wrapper_test.dart`、`test/ui/windows/lyrics/lyrics_title_bar_test.dart`) + 斷言的是語意樹節點內容,不是 guideline helper。 + +--- + +## 8. 本檔與 `ui.md` 的差異更正 + +- `ui.md` §6.2 觀察 7 對播放頁背景的「**推測**是封面取色的漸層」→ 實際是 + 模糊封面(`sigma 48`)+ `ImmersivePlayerScaffold` 的 0.60 / 0.08 overlay,**不是取色漸層** + (`immersive_player_scaffold.dart:34-37`、`blurred_cover_backdrop.dart:139-151`)。 +- `ui.md` §3.1 說 `app_theme.dart`「從種子色產生 `ColorScheme`」,未提 dynamic color 有無 + → 確認**沒有** `dynamic_color` 依賴,只有 seed。 +- `ui.md` §5.3 說 `Actions(` 為 0「排除類別名尾碼的誤配後」→ 本檔重數 18 個命中,逐一確認為 + `*Actions()` 方法名與 `actions:` 具名參數,真 widget 使用為 0,與 `ui.md` 結論一致。 diff --git a/.trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md b/.trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md new file mode 100644 index 000000000..1e7bd93ec --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md @@ -0,0 +1,305 @@ +# packages-and-platform.md — 套件、framework 與平台事實(Flutter 3.47 世代) + +- **查證日**:2026-09-28 +- **查證方式**: + - **本機 primary source**:Flutter SDK `D:\Development\SDK\flutter`(3.47.1 stable / Dart 3.13.1,framework revision `6655482ec06e547f90abf8ae7590466f4415978d`,2026-08-19)、FMP 的 `pubspec.yaml` / `pubspec.lock` / `.dart_tool/package_config.json`。 + - **實測**:以 `dart --packages=".dart_tool/package_config.json"` 跑 FMP 自己解析出的 `intl 0.20.3`,量測 `NumberFormat.compact` 的實際輸出(**非推測**)。`dart pub deps` 讀依賴樹。 + - **外部**:pub.dev API(`https://pub.dev/api/packages/`)、`gh api`、`raw.githubusercontent.com`、context7(slang 官方 README)、api.flutter.dev / docs.flutter.dev。 + - **未執行 FMP App**、**未打任何音樂平台 API**。 +- **標記慣例**:`逐字` = 官方原文;`推測` = 推論;`查不到` = 本輪找不到可靠出處;`實測` = 本機跑出來的。 + +--- + +## 0. Flutter 3.47 世代最重要的一件事:Material / Cupertino 正在從 SDK 拆出去 + +這條不在原題目清單裡,但它直接影響 FMP 的重寫,因此記在最前面。 + +- **現況是「並存」**:本機 3.47.1 SDK 的 `packages/flutter/lib/material.dart` 仍存在,`packages/flutter/lib/src/material/` 下有 **184** 個檔案(`typography.dart`、`color_scheme.dart` 等都在)。所以 `package:flutter/material.dart` 在 3.47.1 **照常可用**。 +- **同時**,`flutter/packages` 已新增兩個獨立套件(`gh api` 列 `packages/` 目錄可見 `material_ui`、`cupertino_ui`): + - `material_ui` latest **1.4.0**(2026-09-22),`environment: {sdk: ^3.13.0, flutter: ">=3.47.0"}`,description 逐字「The official Flutter Material UI Library, implementing Google's Material Design design system.」 + - `cupertino_ui` latest **1.1.1**(2026-09-21) +- **官方 README 逐字**(,本輪抓 `main`;**非固定 SHA permalink**):「The standalone `material_ui` package was previously built directly into the core Flutter framework as `package:flutter/material.dart`. It has been decoupled from the flutter/flutter repository into its new home here in flutter/packages.」 +- **官方遷移三步**(README 逐字): + 1. `dart fix --apply --code=migrate_design_widgets` —— 效果等同於加入 `material_ui` 依賴並把 `package:flutter/material.dart` 的 import 改成 `package:material_ui/material_ui.dart` + 2. localizations:改用 `material_ui` / `cupertino_ui` 版的 `GlobalMaterialLocalizations` / `GlobalCupertinoLocalizations`(README 範例:`localizationsDelegates: GlobalMaterialLocalizations.delegates`) + 3. 第三方套件仍 import `package:flutter/material.dart` 時,用 `MaterialUiCompatibilityBridge` 橋接 `ThemeData` 與 `MaterialLocalizations` +- **FMP 的依賴樹已經踩到這條路**(實測 `dart pub deps --style=compact`):FMP **沒有**直接依賴 `material_ui`,但 `pubspec.lock` 已經解析出 **`material_ui 1.1.1`** 與 **`cupertino_ui 1.0.2`**(皆 `dependency: transitive`)。拉進來的是兩個直接依賴: + - `go_router 18.0.1` → `[collection cupertino_ui flutter flutter_web_plugins logging material_ui meta]` + - `cached_network_image 4.0.0` → `[... material_ui]`(`cached_network_image_platform_interface 5.0.0`、`cached_network_image_web 2.0.0` 同) +- **官方部落格**(Flutter 3.47 what's-new)稱 `flutter_localizations` 也一併 unbundle → (本輪未逐字核對該頁)。FMP 目前仍以 `flutter_localizations: sdk: flutter` 直接依賴(`pubspec.yaml`,`pubspec.lock:457-460` 為 `dependency: "direct main"`, `source: sdk`)。 +- **版本落差警告**:`docs.flutter.dev` 多數頁面仍標「reflects Flutter 3.44.7」,與本機 3.47.1 有落差,讀官方文檔時需留意。 + +--- + +## 1. Flutter framework 的響應式/自適應 API + +### 1.1 `WindowSizeClass` **不在** Flutter framework + +- 本機 SDK 實測:`grep -rn "class WindowSizeClass" packages/flutter/lib/` → **無命中**;`grep -rln "AdaptiveScaffold" packages/flutter/lib/` → **無命中**。 +- 外部交叉查證(子代理):`api.flutter.dev/flutter/widgets/WindowSizeClass-class.html` → **HTTP 404**;flutter/flutter code search `WindowSizeClass` total_count = **0**、`windowSizeClass` = **0**;`packages/flutter/lib/src/widgets/window_size_class.dart` 在 master → **404**;Flutter 3.47.0 release notes 未提 window size class。 +- 官方 adaptive 總覽頁()只點名 `SafeArea` 與 `MediaQuery`;子頁 `large-screens` 逐字提「use `MediaQuery` to get the app window size rather than the physical device size」,另提 `ui.Display` API、`SliverGridDelegateWithMaxCrossAxisExtent`、`BoxConstraints.maxWidth`、`NavigationRail` vs `BottomNavigationBar`。 +- **結論**:framework 內沒有 window size class API,官方路線是 `MediaQuery` + 自訂 breakpoint。`WindowSizeClass` 這個名字來自下面的套件與 Material 設計層,不是 Flutter API。 + +### 1.2 `flutter_adaptive_scaffold` **已 discontinued,且沒有官方替代品** + +實測 pub.dev API(`https://pub.dev/api/packages/flutter_adaptive_scaffold`): + +| 欄位 | 值 | +|---|---| +| latest | **0.3.3+1** | +| published | **2025-05-06** | +| `isDiscontinued` | **true** | +| `replacedBy` | **null**(官方未指名替代品) | +| pubspec `repository` | `https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold`(**該目錄現在 404**,`gh api` 實測 Not Found) | + +- pub.dev 頁面逐字:「This project has been discontinued, and will not receive further updates.」未指名替代品,只導向 GitHub issue **flutter/flutter #162965** 供社群討論 fork。 +- `#162965`「flutter_adaptive_scaffold planned to be discontinued」(2025-02-10 開,已 closed)目的是協調社群 fork,**沒有任何官方替代或框架層替代計畫**。上層統籌 issue 為 **#162960**「Packages planned to be discontinued」(同樣涵蓋 css_colors、flutter_image、flutter_markdown 等)。 +- **即:這個套件不能作為長期方案。** + +### 1.3 Material 3 Expressive:官方**尚未實作**,且目前**不開發** + +- 統籌 issue **flutter/flutter#168813**「☂️ Bring Material 3 Expressive to Flutter」:本機 `gh api` 實測 state = **open**、created 2025-05-14、updated **2026-08-17**、comments **84** → +- 2025-07-29 更新逐字:「The material and cupertino libraries are being decoupled into standalone packages to accelerate feature development. All new work for Material 3 Expressive will happen in the new packages once established in flutter/packages.」 +- 但 issue 正文同時逐字寫:「As of writing, this work is **not planned**。」後續狀態(多方引用)為「Currently, we are **not actively developing** Material 3 Expressive, and we will not be accepting contributions for Expressive features or updates at this time.」 +- **Flutter 3.47.0 release notes 完全未提 M3 Expressive**;Material 段只有 VPAT/a11y 工具、阿拉伯數字修正、lint 清理。 +- **本機 SDK 的直接證據**:`packages/flutter/lib/src/material/page_transitions_theme.dart:468` 註解逐字寫「Android is using Material 3 Expressive springs that are not currently …」—— framework 自己承認尚未支援 M3E 的動態曲線。 +- 已 merge 的相關 PR:`flutter/packages#12093`「[material_ui] Add Material 3 Expressive IconButton」→ 本輪 `gh api` 查得 state = **closed**、`merged: false`(closed_at 2026-09-10)。 +- 第三方套件 `material_3_expressive`(pub.dev,**非官方**)提供 44 個 M3E widget。**framework 內沒有官方 flag。** +- **但是**:Flutter 的 `DynamicSchemeVariant` **有** `expressive`(本機 `color_scheme.dart:51` 為 `expressive,`,`:2217` 為 `DynamicSchemeVariant.expressive => SchemeExpressive(...)`)—— 即**取色方案**層面已支援 M3E 的色調,元件與動態層面沒有。 + +### 1.4 `dynamic_color` + +實測 pub.dev API(`https://pub.dev/api/packages/dynamic_color`): + +| 欄位 | 值 | +|---|---| +| latest | **2.1.0** | +| published | **2026-08-20** | +| `isDiscontinued` | false | +| pubspec env | `sdk: >=2.16.0 <4.0.0`, `flutter: >=3.4.0-17.0.pre` | +| 依賴 | `material_color_utilities ^0.13.0`、`material_ui ^1.0.0` | + +- pubspec 的 `flutter.plugin.platforms` 明確列出 **android, linux, macos, windows**(Windows 走 `DynamicColorPluginCApi`)→ **Android 12+ 與 Windows、macOS、Linux 皆支援**。 +- **FMP 現況(事實)**:`pubspec.yaml` **沒有** `dynamic_color` 依賴;主題走 `ColorScheme.fromSeed`(見 `current-state.md` §1)。 + +--- + +## 2. i18n + +### 2.1 `slang` + +實測 pub.dev API(`https://pub.dev/api/packages/slang`):latest **4.19.2**,published **2026-09-12**,`isDiscontinued` false,env `sdk: >=3.3.0 <4.0.0`。repo 已遷至 `codeberg.org/Tienisto/slang`;依賴 `intl >=0.18.1 <2.0.0`。 + +**功能**(context7 取官方 README ): + +- **Type safety**:逐字「Type-safe i18n solution using JSON, YAML, CSV, or ARB files.」「no typos or missing arguments possible due to compile-time checking.」 +- **Plural**:用 Unicode CLDR plural rules,關鍵字 `zero/one/two/few/many/other`,支援 **cardinal 與 ordinal**;設定 `pluralization.auto`(`off` / `cardinal` / `ordinal`)與逐 key 清單。未支援的語言可用 `LocaleSettings.setPluralResolver(...)` 自訂。 +- **Linked translations**:`"sentence": "I have @:apples and @:bananas"`,可讓一句話裡有多個 plural 參數(README 範例 `t.sentence(appleCount: 1, bananaCount: 2)`)。 +- **參數 / placeholders**:三種插值模式 `dart` / `braces` / `double_braces`;參數預設型別 `Object`;RichText 用 `(rich)` modifier。 +- **Lazy loading**:`lazy: true`(**預設**);逐字「translations for secondary locales are loaded lazily if Deferred loading is supported (Web).」 +- **Namespaces**:逐字「You can split the translations into multiple files. Each file represents a namespace.」(`namespaces: true`);檔名格式 `_.`,可用目錄分(`i18n/en/widgets/welcomeCard.json`);根命名空間用 `_default`。取用語法 `t..`。 +- **Fallback locale**:`fallback_strategy` ∈ `none`(**預設**)/ `base_locale` / `base_locale_empty_string`;逐字「Missing translations will fall back to base locale.」(**只在 `base_locale` 時**)。`dart run slang analyze` 可找 missing / unused(missing 只在 `fallback_strategy: base_locale` 時才報)。 +- **Locale handling**:`locale_handling: true`(預設);`TranslationProvider` 會監聽裝置 locale 變化。另有 `setLocale` / `setLocaleRaw` / `useDeviceLocale`。 +- **其他 config key**(README 配置表):`translate_var`(預設 `t`)、`enum_name`(`AppLocale`)、`class_name`(`Translations`)、`key_case`(`snake`)、`param_case`(`pascal`)、`maps`、`contexts`(自訂 `GenderContext` 等)、`interfaces`、`obfuscation`、`format`、`autodoc`、`imports`、`generate_enum`、`timestamp`、`statistics`。 +- 文件: + +**FMP 現況(事實,`slang.yaml` 全文)**:`base_locale: zh-CN`、`namespaces: true`、`input_directory: lib/i18n`、`input_file_pattern: .i18n.json`、`output_directory: lib/i18n`、`output_file_name: strings.g.dart`、`lazy: false`(附中文註解說明理由:只出 Android 與 Windows,兩者都不支援 deferred loading)。**未設定** `fallback_strategy`(即預設 `none`)。 +規模實測:`lib/i18n/` 下 **38** 個 `*.i18n.json` × 3 locale(`en` / `zh-CN` / `zh-TW`)= **114** 檔;`enum AppLocale` 順序為 `zhCn` → `en` → `zhTw`(`lib/i18n/strings.g.dart:31-34`)。i18n 走 `dart run slang` 獨立 CLI,**不經 build_runner**(`slang_build_runner` 在 `dev_dependencies` 被刻意排除,附理由註解)。 + +### 2.2 官方 `gen-l10n`(ARB)vs slang + +官方 i18n 文件 : + +- **產物**:由 `l10n.yaml` 驅動,`flutter gen-l10n`(或 `flutter run` / `pub get` 自動觸發),產生 `AppLocalizations` 類別 + delegate + 自動 `supportedLocales`。逐字:「Alternatively, you can also run `flutter gen-l10n` to generate the same files without running the app.」 +- **型別安全**:ARB key 變成有型別的 getter / method;逐字「A placeholder... becomes a positional parameter in the generated method」。 +- **Plural / ICU**:完整支援 ICU message syntax,含 `plural`、`select`、`=0/=1/other`;逐字「Only the more general `messageOther` field is required.」`num` placeholder 可帶 `"format": "compact"`;`DateTime` placeholder 用 `DateFormat`(41 種 variation)。 +- **官方文檔完全不提 slang 或任何第三方 codegen 套件**;只把「手寫 class」與「`intl_translation` 原始工具」列為 alternative workflow。 +- **兩者差異(事實對照)**:官方 gen-l10n 的 plural 走 ICU message 字串;slang 走 JSON 巢狀物件 + CLDR 規則。官方 gen-l10n 需要 ICU literal 的語法知識;slang 不需要。官方工具 shipped with SDK,無第三方依賴。**官方沒有任何文件建議或反對用 slang。** + +### 2.3 `intl` 的 `NumberFormat.compact` —— 實測輸出 + +方法:在本機以 FMP 自己解析出的 **intl 0.20.3**(`C:\Users\Roxy\AppData\Local\Pub\Cache\hosted\pub.dev\intl-0.20.3`)+ Dart 3.13.1 實際執行(`dart --packages=".dart_tool/package_config.json"`)。 + +| locale | 1 | 999 | 1000 | 1500 | 46000 | **46000000** | 1234567890 | +|---|---|---|---|---|---|---|---| +| `en` | 1 | 999 | **1K** | **1.5K** | 46K | **46M** | **1.23B** | +| `zh` | 1 | 999 | 1000 | 1500 | **4.6万** | **4600万** | **12.3亿** | +| `zh_TW` | 1 | 999 | 1000 | 1500 | **4.6萬** | **4600萬** | **12.3億** | +| `zh_CN` | 1 | 999 | 1000 | 1500 | **4.6万** | **4600万** | **12.3亿** | +| `ja` | 1 | 999 | 1000 | 1500 | **4.6万** | **4600万** | **12.3億** | + +**三個要點**: + +1. **中文在 10000 以下不壓縮**:`1000 → "1000"`、`1500 → "1500"`(不是 `1K`)。與 FMP 自家 `formatCount` 相同(FMP 也是 `<10000` 直接回原數字)。 +2. **整數時不加小數點**:`46000000 → "46M"`(不是 `46.0M`);`4600萬`(不是 `4600.0萬`)。 +3. **有效位數是 3 位**:`1234567890 → "1.23B"`。 + +**與 FMP 自家實作的差異**(`lib/core/utils/number_format_utils.dart`,38 行全文已讀): + +| | FMP `formatCount` | `intl` `NumberFormat.compact` | +|---|---|---| +| en 1e9 帶 | `${(c/1e9).toStringAsFixed(1)}B` → `1.2B` | `1.23B` | +| en 整數 | 一律一位小數 → **`46.0M`** | 去尾 → **`46M`** | +| zh 1e8 帶 | `${(c/1e8).toStringAsFixed(1)}亿` → `4.6亿` | `12.3亿`(3 位有效) | +| zh 整數 | 一律一位小數 → **`4600.0萬`** | 去尾 → **`4600萬`** | +| 千分位 | 無 | 無(compact 不帶千分位) | +| 低於 1e3 / 1e4 門檻 | 直接回原數字 | 同 | + +即這兩個 audit 抓到的症狀(`46.0M`、`4600.0萬`)正是「自家實作強制一位小數」造成的,`intl` 的 `compact` 不會有這個尾巴。 + +**子代理補充(僅一項,需注意)**:`zh_Hant`(**只有 script、無 region**)實測落回**簡體「万」**,`zh_Hant_TW` 才是繁體「萬」。成因**未查證**(推測 locale resolution 掉到 `zh`)。FMP 走 `AppLocale.zhTw`(`languageCode: 'zh', countryCode: 'TW'`),不經這條路徑。 +**CLDR 來源**(子代理):`cldr-json/cldr-numbers-full/main//numbers.json` 的 `decimalFormats-numberSystem-latn.short`;zh / zh-Hant 的 `10000000-count-other` = `"0000萬"`、`100000000-count-other` = `"0億"`;en 的 `1000000-count-other` = `"0M"`。→ 46,000,000 落在 10^7 帶,除以 10^4 得 4600。→ + +--- + +## 3. 無障礙與鍵盤 + +### 3.1 `Shortcuts` / `Actions` / `Intent` 三者角色 + +- **`Intent`**:逐字「An abstract class representing a particular configuration of an Action.」是 `Shortcuts.shortcuts` map 的 value,由 `ActionDispatcher` 查表並 invoke。`@immutable`。→ +- **`Shortcuts`**:逐字「A widget that creates key bindings to specific actions for its descendants.」建立 `ShortcutManager`,把按鍵組合對應到 `Intent`;官方強調它「**separates key bindings and their implementations**」。→ +- **`Actions`**:逐字「A widget that maps Intents to Actions to be used by its descendants when invoking an Action.」「Actions are typically invoked using `Shortcuts`。」靜態 `Actions.invoke(context, intent)`。→ + +### 3.2 `FocusTraversalGroup` + +- 逐字:「grouping them into a separate traversal group」;「Within the group, it will use the given policy to order the elements」;「The group itself will be ordered using the parent group's policy」;預設「traverses in reading order using `ReadingOrderTraversalPolicy`」。`policy` 逐字:「The policy used to move the focus from one focus node to another when traversing them using a keyboard」。→ +- `FocusScope` vs `FocusTraversalGroup` 的差別(逐字,):「If you just want to group widgets together in a group so that they are traversed in a particular order, **but the focus can still leave the group**, use a `FocusTraversalGroup`.」 +- **FMP 現況(事實)**:`current-state.md` §5 記錄了 FMP 目前的 `Shortcuts`/`Actions`/`FocusTraversalGroup` 使用位置與全域熱鍵清單。 +- 社群分組實例見 `prior-art.md` §4.5(Fladder、flutter-adaptive-demo、Arna)。 + +### 3.3 `SemanticsRole`(**是新 API**) + +- 定義位置:**`dart:ui`(engine)**,本機路徑 `bin/cache/pkg/sky_engine/lib/ui/semantics.dart:361`(**不是** `packages/flutter`)。dartdoc 首段逐字:「An enum to describe the role for a semantics node.」「The roles are translated into native accessibility roles in each platform.」 +- **加入版本:Flutter 3.29.0**。證據(子代理):3.29.0 release notes 有「add semantics role and tab by @chunhtai in **161260**」(PR #161260);framework `semantics.dart` 對 `SemanticsRole` 的引用數在 3.27.0 = 0、3.29.0 = 17、3.32.0 = 68。 +- **本機實測 3.47.1 的完整 enum 值(33 個,`semantics.dart:361-556`)**: + + `none, tab, tabBar, tabPanel, dialog, alertDialog, table, cell, row, columnHeader, dragHandle, spinButton, comboBox, menuBar, menu, menuItem, menuItemCheckbox, menuItemRadio, list, listItem, form, tooltip, loadingSpinner, progressBar, hotKey, radioGroup, status, alert, complementary, contentInfo, main, navigation, region` + + 其中與播放器版面直接相關的:`main`、`navigation`、`region`、`complementary`、`list` / `listItem`、`hotKey`、`status`、`alert`、`tooltip`、`progressBar`、`loadingSpinner`。 +- 3.47.0 相關 PR(子代理):「Adds semantics role check to `isSemantics` and `matchesSemantics`」(#188825)、「Keep scrollable semantics role stable」(#187963)、「Map some framework semantics roles to android classes」(#185217)。 +- → + +### 3.4 widget test 的 `meetsGuideline` + +- 本機 `packages/flutter_test/lib/src/accessibility.dart` 與 `matchers.dart:1300` 實測:`AsyncMatcher meetsGuideline(AccessibilityGuideline guideline)`。 +- **可用 guideline 常數**(本機 `accessibility.dart` 實測行號): + - `androidTapTargetGuideline`(`:785`) + - `iOSTapTargetGuideline`(`:800`) + - `textContrastGuideline`(`:818`) + - `labeledTapTargetGuideline`(`:825`) +- **限制**:需先 `tester.ensureSemantics()` 且結果要 `await`(官方範例逐字:`await expectLater(tester, meetsGuideline(textContrastGuideline));`)。→ +- **FMP 現況(事實,取自 `current-state.md` §7)**:只有 2 個測試檔用到 `meetsGuideline`(`comment_pager_test.dart:33-34`、`mini_player_accessibility_test.dart:117-118`),用的是 `androidTapTargetGuideline` 與 `labeledTapTargetGuideline`;**`textContrastGuideline` 全 repo 零使用**。 + +### 3.5 Windows 焦點指示(focus highlight)已知 issue + +全部本輪以 `gh api` 實測 state: + +- **#120425「Material 3 focus rings & keyboard behavior on web/desktop」— OPEN**,P3,labels `a: accessibility` / `a: desktop` / `c: new feature` / `p: material_ui` / `team-design`。逐字:「placeholder issue for a project to draw outlined indicators ("focus rings") around focused M3 elements」,理由「improve a11y and ease of use」。**即 M3 元件目前缺 focus ring。** → +- **#172438「[Windows][Accessibility] Text can't be focused when navigating using a keyboard」— OPEN**,P2,`platform-windows`。→ +- **#151457「Windows desktop app completely losing keyboard focus」— OPEN**。→ +- **#119531「Allow `MenuBar` menus to be focused via keyboard without accelerators」— OPEN**,`f: focus`,P2。 +- **#103811「[Desktop-Windows] Chinese characters are incorrectly rendered in flutter 3」— OPEN**,P2,`c: regression` / `a: typography` / `a: internationalization` / `platform-windows`:回報 3.0.0 Windows 桌面渲染錯誤、2.10.5 正常、web 正常。 +- 官方焦點文件提到切換機制:`FocusManager.instance.highlightMode` 與 `highlightStrategy`,用於 touch 與 mouse/keyboard 兩種模式間切換焦點高亮(逐字:「the focus highlight is usually hidden」於 touch 時)→ +- **查不到**專門講「深色主題下 `focusColor` 不明顯」的 open issue(搜尋未命中 `focusColor` 相關標題)。→ **查不到** + +--- + +## 4. 視覺回歸(golden test) + +### 4.1 FMP 現況(事實) + +FMP `pubspec.yaml` / `pubspec.lock` **沒有** `alchemist`、`golden_toolkit`、`golden_test` 任一依賴;repo 內**零個 golden 測試**(見 `current-state.md` §7)。 + +### 4.2 官方 `matchesGoldenFile` 的跨平台字型問題 + +- 逐字:「The term **golden file** refers to a master image that is considered the true rendering of a given widget, state, application...」 +- 更新方式逐字:「The master golden image files that are tested against can be created or updated by running `flutter test --update-goldens`」。 +- **字型警示(逐字)**:「Custom fonts may render differently across different platforms, or between different versions of Flutter.」「a golden file generated on **Windows** with fonts will likely differ from the one produced by another operating system.」「Even on the same platform, if the generated golden is tested with a different Flutter version, the test may fail and require an updated image.」 +- **預設字型是 Ahem(方塊)**,逐字:「the Flutter framework uses a font called '**Ahem**' which shows squares instead of characters」;要載自訂字型可用 `FontLoader`,或全域放進 `flutter_test_config.dart`。 +- → +- **`flutter test --platform` 不是 3.47.1 的旗標**(子代理在本機專案目錄實跑 `flutter test --help`):有 **`--update-goldens`**,但**沒有** `--platform`(`--platform` 是 `dart test` 的旗標:vm / chrome / node)。官方 CLI 參考頁亦未記載 → + +### 4.3 `alchemist` + +實測 pub.dev API(`https://pub.dev/api/packages/alchemist`): + +| 欄位 | 值 | +|---|---| +| latest | **0.14.0** | +| published | **2026-03-13** | +| `isDiscontinued` | false | +| pubspec env | `sdk: >=3.8.0 <4.0.0`, `flutter: >=3.32.0` | +| repo | `https://github.com/Betterment/alchemist` | + +- **解決什麼**:跨平台字型渲染差異導致 golden 在 CI 失敗。做法是把 CI golden 的文字換成有色方塊(逐字:「the text blocks are replaced with colored squares」),且「always run using the **Ahem** font family」,使輸出與平台無關。 +- **API**:宣告式 `goldenTest`,搭配 `GoldenTestGroup`(表格)與 `GoldenTestScenario`(name + child);生成用 `flutter test --update-goldens`;測試帶 `"golden"` tag 可用 `--tags golden` 過濾。 +- **設定**:`AlchemistConfig`(`forceUpdateGoldenFiles`、themes、`PlatformGoldensConfig` / `CiGoldensConfig`,含 `obscureText`、`renderShadows`、`diffThreshold`),常放在 `flutter_test_config.dart`;支援 `merge` / `copyWith`。 +- **目錄慣例**:CI golden 進 `goldens/ci/`,可讀的平台 golden 進 `goldens/`(macos / linux / windows)。 +- → + +### 4.4 其他工具 + +- **`golden_toolkit` — 已 discontinued**:latest **0.15.0**,published **2023-02-21**,pub.dev `isDiscontinued: true`;repo eBay/flutter_glove_box。alchemist 即受它啟發。 +- **`patrol`**:latest **4.10.0**;是「multiplatform E2E UI testing framework... overcoming the limitations of `integration_test`」,處理 native 互動(**非** golden 工具)。 +- 另有第三方 `golden_test`(pub.dev)與商業的 Widgetbook Cloud(雲端跑 golden 以消平台差異)。→ **本輪未逐一核對這兩個的版本與成熟度。** + +--- + +## 5. 字型與 CJK fallback + +### 5.1 `fontFamilyFallback` 的官方語意 + +本機 `packages/flutter/lib/src/painting/text_style.dart` 實測: + +- `:394-408` dartdoc:fallback 是 ordered list;`:403` 逐字「`fontFamilyFallback` in order of **first to last**」;`:397` 逐字「The fonts in `fontFamilyFallback` will be used **only if the requested glyph is** [not found in the higher priority families]」。 +- **關鍵語意(本機 `:566-567`、`:588`)**:當 `fontFamily` 為 null 或未提供時,**`fontFamilyFallback` 的第一個值就成為主要字型**(逐字:「When `fontFamily` is null or not provided, the first value in `fontFamilyFallback` acts as the preferred/first font」)。 +- `:585-594`:若所有 font family 都用盡仍無 match,就畫方塊;`:594` 逐字「in `fontFamilyFallback` will be searched in order until it is found」。 +- → (dartdoc 逐字:「ordered list of font families to fall back on when a glyph cannot be found in a higher priority font family」) + +### 5.2 Flutter 各平台 Typography 的預設字型(本機 SDK 實測) + +- `packages/flutter/lib/src/material/theme_data.dart:399`:`platform ??= defaultTargetPlatform;` +- `:505-506`:`typography ??= useMaterial3 ? Typography.material2021(platform: platform, colorScheme: colorScheme) : ...` +- `packages/flutter/lib/src/material/typography.dart:219-224`(`material2021` 的平台分派): + - `TargetPlatform.iOS` → `blackCupertino` / `whiteCupertino` + - `TargetPlatform.fuchsia`、`android` → `blackMountainView` / `whiteMountainView` + - **`TargetPlatform.windows` → `blackRedmond` / `whiteRedmond`** + - `TargetPlatform.linux` → `blackHelsinki` / `whiteHelsinki` +- **`blackRedmond` 的 fontFamily 實測(`:568` 起)**:**`'Segoe UI'`**(15 個 style 全部)。 +- `Typography-class` 官方頁(子代理)列:Android = **Roboto**;iOS = San Francisco;macOS = San Francisco;**Windows = Segoe UI**;Linux = Roboto,fallback「DejaVu Sans, Liberation Sans and Arial」。→ + +**推論(本檔最關鍵的一條,標明為推測)**:FMP 的 `ThemeData(useMaterial3: true, ...)` **沒有**傳 `platform:`,因此 Windows 上文字預設 family 是 **Segoe UI**、Android 上是 **Roboto**。**兩者都沒有 CJK 字符**。所以 FMP 的 CJK 顯示完全依賴它自己加的 `fontFamilyFallback` 與 engine 的系統 fallback。 + +### 5.3 FMP 現況(事實,`lib/ui/theme/app_theme.dart`) + +- `:203-205`:`return base.copyWith(textTheme: base.textTheme.apply(fontFamilyFallback: fallback));` —— **只設 `fontFamilyFallback`,不覆寫 `fontFamily`**(除了使用者自選字型時,見下)。 +- `:96-105` `_buildFontFallback`: + - Windows:使用者選了字型 → `[fontFamily, 'Microsoft YaHei UI', 'Microsoft YaHei']`;未選 → `['Microsoft YaHei UI', 'Microsoft YaHei']` + - 其他(Android)→ `['Noto Sans SC']` +- `:70-93` `availableFonts`:Windows 8 個選項(系統預設、Microsoft YaHei UI、SimSun、SimHei、KaiTi、FangSong、Yu Gothic UI、Meiryo);Android 7 個(系統預設、sans-serif、serif、sans-serif-medium、sans-serif-light、sans-serif-condensed、monospace)。 +- `:129-130`:使用者選了字型時 `fontFamily: (fontFamily != null && fontFamily.isNotEmpty) ? fontFamily : ...` —— 即**只有自選時才覆寫 `fontFamily`**。 +- **`pubspec.yaml` 沒有 `fonts:` 區段**(實測),即 FMP **不內嵌任何字型檔**。 +- **兩個值得注意的事實**: + 1. **繁體中文沒有列入**:Windows fallback 清單是 `Microsoft YaHei UI`(**簡體**字型),**沒有 `Microsoft JhengHei UI`**(Windows 的繁中字型)。`availableFonts` 的 Windows 清單同樣沒有繁中字型。FMP 的 `base_locale` 是 `zh-CN`,但 UI 支援 `zh-TW`(`AppLocale.zhTw`)。→ 繁中字形實際由哪個字型提供,**本輪查不到官方或程式碼層的說明**;`Microsoft YaHei UI` 內含部分繁中字形,但這點**未查證**。 + 2. **Android 清單有日文字型**:`Yu Gothic UI` / `Meiryo` 在 Windows 清單裡,但 Windows 8 個選項中 **沒有** 韓文字型。 + +### 5.4 各平台內建 CJK 字型名稱(子代理查證) + +- **Windows**(Microsoft 官方 Windows 11 font list → ): + - 簡體:**Microsoft YaHei / Microsoft YaHei UI**(`Msyh.ttc`)、SimSun / NSimSun(`Simsun.ttc`)、SimHei、DengXian、FangSong、KaiTi + - 繁體:**Microsoft JhengHei / Microsoft JhengHei UI**(`Msjh.ttc`)、MingLiU / PMingLiU、DFKai-SB + - 日文:Yu Gothic / Yu Gothic UI(`YuGoth*.ttc`)、Meiryo / Meiryo UI、MS Gothic、MS Mincho + - 韓文:Malgun Gothic(`Malgun.ttf`)、Batang、Gulim、Dotum +- **Android**:`NotoSansCJK-Regular.ttc`(`/system/fonts`),於 `fonts.xml` 以 `index` 區分語境:`zh-Hans` index 2、`zh-Hant` index 3、`ja` index 0、`ko` index 1。(子代理標記:index 值來自社群貼出的 `fonts.xml`,**未逐字對上 AOSP 該檔**——googlesource 回 503;AOSP 官方頁只確認檔案位置與機制,未列 index。)→ +- **Linux**:走 fontconfig 比對;社群證據顯示常見為 Noto Sans CJK / Source Han Sans。Ubuntu 自 2016(language-selector 0.154)起,簡中預設由 Droid Sans Fallback 改為 **Noto Sans CJK**(Launchpad bug #1468027)。 +- **`fontFamilyFallback` 未命中時的落地機制**:官方 dartdoc 只說「the default platform font family will be used instead」。**Flutter 官方沒有文件明確描述 Windows/Linux 上「未宣告 fallback 的 CJK 字元會落到哪個系統字型」的機制** → **查不到**。相關 open issue 為 #103811(見 §3.5)。 + +--- + +## 本檔最不確定的 5 件事 + +1. **`material_ui` / `cupertino_ui` 的遷移時間表與對 FMP 的強制性**:官方 README 與部落格都說「decoupled」,3.47.1 SDK 仍內建 `package:flutter/material.dart`,但**沒有任何官方文件說明舊路徑何時移除**。FMP 已在依賴樹裡拿到 `material_ui 1.1.1`(transitive),卻還沒直接依賴它。 +2. **`SemanticsRole` 的加入版本(3.29.0)**:engine 在 3.27 之前是獨立 repo,`raw.githubusercontent.com/flutter/flutter//engine/...` 在 3.27.0 是 404,所以無法逐版比對 `dart:ui` 檔;結論由 framework 引用數(3.27=0 / 3.29=17)加 3.29 release notes 的 PR #161260 交叉推得,**非逐版確認 enum 定義**。enum 值本身是本機 3.47.1 實測,無疑。 +3. **FMP 的繁體中文字形實際由哪個字型提供**:`_buildFontFallback` 的 Windows 清單只有簡體 `Microsoft YaHei UI` / `Microsoft YaHei`,沒有 `Microsoft JhengHei UI`;但 `zh-TW` 是支援的 locale。`Microsoft YaHei UI` 是否足以覆蓋繁中字形、以及未覆蓋時 engine 落到哪裡,**兩者都查不到**。這是本檔我認為最可能出錯的一條。 +4. **`zh_Hant`(無 region)落回簡體「万」的成因**:實測輸出確定(intl 0.20.3),但成因未查證(推測 locale resolution 掉到 `zh`)。FMP 走 `AppLocale.zhTw`(有 countryCode),不經這條路徑,所以**這條不影響 FMP**,但若日後有人用 script-only locale 就會踩到。 +5. **Windows 焦點指示的實際嚴重度**:#120425(M3 缺 focus ring)是 placeholder issue、P3;#172438(鍵盤無法聚焦文字)與 #151457(完全失去鍵盤焦點)都是 OPEN 但**我沒有實際重現**。官方文件只描述 `highlightMode` / `highlightStrategy` 機制,未說 Windows 上有已知破損。FMP 是否會踩到,**需在裝置上實測**。 diff --git a/.trellis/tasks/09-28-design-ui-ux/research/prior-art.md b/.trellis/tasks/09-28-design-ui-ux/research/prior-art.md new file mode 100644 index 000000000..0fa29b07c --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/research/prior-art.md @@ -0,0 +1,441 @@ +# prior-art.md — 外部先例(Material 3 版面、桌面播放器版面、token 慣例、快捷鍵、使用者指南) + +- **查證日**:2026-09-28 +- **查證方式**:三個 sonnet 子代理分頭查證,工具為 context7 / tavily-search(basic)/tavily-extract/WebFetch,GitHub 內容以 `gh api` 取固定 commit SHA 的 permalink。**未下載任何圖片**,只記官方截圖的路徑與 URL。**未執行 FMP App**、**未打任何音樂平台 API**。 +- **標記慣例**:`逐字` = 官方頁原文引號;`推測` = 我的推論;`查不到` = 本輪找不到可靠出處。 +- **已知工具限制**:`m3.material.io` 為 JS render,`tavily-extract` 與 WebFetch 都只取到導覽骨架,取不到內文表格;因此 M3 的數值多數引自 `developer.android.com` 的同義頁面。此限制影響本檔多條目,個別條目會再標註。 + +--- + +## 1. Material 3 版面官方規則 + +### 1.1 Window size class 的命名與斷點數值 + +- 官方頁面已由 `foundations/layout/applying-layout` 改稱 **breakpoints**:。索引摘要逐字列出五個 class:compact, medium, expanded, large, extra-large,並說版面「typically transition from a single pane to two or three panes as window size increases」。 +- **寬度**(逐字,出處為 `developer.android.com` 而非 m3 站): + - Compact width `width < 600dp` + - Medium width `600dp ≤ width < 840dp` + - Expanded width `840dp ≤ width < 1200dp` + - Extra-large width `width ≥ 1600dp` + - **Large width = `1200dp ≤ width < 1600dp`**:該列在抓取時被截斷,由 Extra-large 下界反推 → **推測**。 +- 官方說明 Large/Extra-large 的來源(逐字):這兩個 class 是在 Material 的 compact/medium/expanded 之外「**additionally … added** to better target desktop and connected displays」→ 同上。 +- **高度**(逐字,同頁):`Compact height = height < 480dp`、`Medium height = 480dp ≤ height < 900dp`、`Expanded height = height ≥ 900dp`。**高度只有三個 class,寬度有五個**。 +- 官方對「該看寬還是看高」的立場(逐字):「Available width and height are classified separately, so at any point in time, your app has two window size classes—one for width, one for height. **Available width is usually more important than available height due to the ubiquity of vertical scrolling**, so the width window size class is likely more relevant to your app's UI.」→ 同上。 + +**與 FMP 現況的對照**(事實,不代表建議):FMP `lib/core/constants/breakpoints.dart` 的 `WindowClass` 斷點為 compact 0 / medium 600 / expanded 840 / large 1200 / extraLarge 1600 —— 與上表五個寬度 class 完全同值同序。 + +### 1.2 Canonical layouts(list-detail / supporting pane / feed) + +官方三個 canonical layout 各自有專頁: + +- supporting pane — +- list-detail — +- feed — + +- **supporting pane 的斷點行為**(逐字,supporting-pane 頁): + - Compact:「The supporting pane should appear **below** the focus pane. **A bottom sheet can be useful** for keeping focus on the primary pane while providing access to supporting information.」 + - Medium:「The supporting pane should appear **below** the focus pane.」 + - Expanded:「The supporting pane should appear on the **leading or trailing side** of the focus pane.」 +- **list-detail 的斷點行為**(逐字,M3 lists 指南 ): + - Compact:「Lists should extend **edge-to-edge** in compact windows. Selecting a list item should open a page with the details.」 + - Medium & expanded:「can display primary and secondary content in the same view. For example, **a list and the detailed information can appear side-by-side**.」 +- **兩者的判準**(逐字,`developer.android.com/develop/ui/views/layout/canonical-layouts`):「A supporting pane layout differs from a list-detail layout in the relationship of the primary and secondary content. **Secondary pane content is meaningful only in relation to the primary content**; … **The supplementary content in the detail pane of a list-detail layout, however, is meaningful even without the primary content**, for example, the description of a product from a product listing.」 +- **supporting pane 的適用情境**(逐字,同頁):「Supporting pane layouts work well on **expanded-width** displays … **Medium- or compact-width** displays support showing both the primary and secondary display areas if the content is adaptable to narrower display spaces, or if the additional content can be **initially hidden in a bottom or side sheet** accessible by means of a control such as a menu or button.」 +- feed 的**官方正文未取得**(頁面只取到骨架)。第三方(SAP Fiori for Android,非官方原文 )轉述:三種 canonical layout 由 panes(flexible 或 fixed-width 容器)組成,隨 window size class 重新排列;feed「unique for using a grid composition」→ 標記**第三方轉述**。 + +### 1.3 導覽元件切換規則 + +**Navigation bar** (逐字): + +- 「**Only use navigation bars for compact and medium**」 +- Compact:「For narrow windows, use a navigation bar or modal navigation rail.」 +- Medium:「Use a navigation bar or navigation rail. Decide based on whether horizontal or vertical space is more important.」 +- 「**Expanded and extra-large: Use a navigation rail instead.**」 +- item 方向:「Use **vertical** items in compact windows (widths smaller than 600dp)… Use **horizontal** items in medium windows (widths from 600dp to 839dp)」 + +**Navigation rail** (逐字): + +- 「**Only use navigation rails for medium breakpoints and larger. Don't use a navigation bar.**」 +- Compact:「**Don't** use a standard navigation rail for compact layouts due to space constraints. **Use a navigation bar instead.**」 +- 「If there are more than **five** destinations, consider using a **modal expanded nav rail** instead.」 +- 題目所稱的「navigation rail + extended」,M3 正式名稱是 **expanded navigation rail**:「The **expanded navigation rail** can be standard or modal, and should always open from a menu icon. … The **standard** configuration is placed beside body content… The **modal** configuration overlaps the body content.」 +- 適用範圍:「It can be used in **medium** (600dp to 839dp) … to **extra large** (1600dp and larger) … such as tablets and desktop. In medium windows with few destinations, consider using a navigation bar instead.」 + +**Navigation drawer** (逐字): + +- 「**Modal** navigation drawers can be used at **any breakpoint** but are most common in **compact** … and **medium**.」 +- 「**Standard** navigation drawers are best for **expanded** (840dp to 1199dp), **large** (1200dp to 1599dp), and **extra-large** (1600dp and larger) breakpoints.」 +- 「Use a modal navigation drawer alone or **with a navigation rail** on medium and expanded breakpoints.」 +- 「A standard navigation drawer can be used in single pane layouts in expanded breakpoints.」 +- 「切換時要做轉場動畫」這一條 → **官方逐字查不到**。 + +**第三方轉述**(非官方原文):9to5Google 報導 M3 Expressive 的導覽變化,稱 navigation rail 適用「medium, expanded, large, or extra-large window sizes」,且 Google 希望以 expanded navigation **取代** navigation drawer → 。 + +### 1.4 M3 Expressive 現況 + +- 官方定性(逐字):「Material 3 Expressive is an **evolution of the Material 3 design system**. It's a set of new features, updated components, and design tactics for creating emotionally impactful UX.」→ (頁面日期 2025-05-13) +- 官方部落格發布(2025-05-13,作者 Mindy Brooks, VP of Product Management and User Experiences, Android Platform)→ +- 官方首頁寫法(逐字):「**M3 Expressive adds** vibrant colors, intuitive motion, adaptive components, flexible typography」→ 。即官方定位為 **M3 的加值層**,沒有任何官方文字說它取代 M3 → **推測**:是延伸而非 replacement。 +- 範圍(逐字):「**Fourteen** new or updated components now feature more configuration capabilities, shape options, emphasized text, and other expressive updates.」清單含 app bars、button groups、common buttons、extended FAB、FAB menu、FABs、icon buttons、loading indicator、navigation bar 等 → 同 blog 頁。 +- 「新增 35 個 shape 與 shape morphing」為第三方轉述(supercharge.design)→ ,**非官方原文**。 +- 出貨時程(「隨 Android 16 QPR1 / 2025 九月 Pixel Drop」)本輪**未取得官方逐字** → **推測,需複查**。 + +**Flutter 端現況**(`gh api` 查證): + +- `flutter/flutter#168813`「☂️ Bring Material 3 Expressive to Flutter」,state = **open**,建立 2025-05-14,最後更新 2026-08-17 → +- `flutter/packages#12093`「[material_ui] Add Material 3 Expressive IconButton」,state = **closed**、`merged: false`(closed_at 2026-09-10)→ +- 本地 Flutter SDK 3.47.1 的 `packages/flutter/lib/src/material/page_transitions_theme.dart:468` 有一行註解:「Android is using Material 3 Expressive springs that are not currently …」→ 即 framework 自身承認尚未支援 M3E 的動態曲線。 + +--- + +## 2. 桌面音樂播放器「播放頁」版面 + +> 逐家列出:封面/歌詞/佇列/控制列位置、背景處理、窄視窗行為、官方截圖或文件 URL。**未下載圖片**。 + +### 2.1 Spotify 桌面(官方支援文件為主) + +- **Now Playing view 是右側面板**(逐字):「Click [Video vertical] to display the Now Playing view. There you can find: About the Artist / On Tour / Merch / Podcast transcripts / **Next in queue**」;「Tip: To switch between the Friend Feed and the Now Playing view, click [Group active] / [Video vertical]」→ +- **佇列位置**(逐字):「To open the queue, click **Play Queue next to the play bar at the bottom**.」→ +- **歌詞位置**(逐字):「1. Play a song. 2. **Click Lyrics at the bottom.**」→ +- **右側面板開關快捷鍵**:Alt + Shift + R(Toggle Now Playing View Sidebar)→ +- **全螢幕**:官方支援文章查不到。官方社群版主回覆(2025-02-16)稱 full screen mode 已整合進 Now Playing view —— 先展開 Now Playing view,再按方形圖示,且可切 Album view / Artist banner view → (**版主回覆,非支援文件**) +- **Miniplayer 位置**(官方社群公告):圖示在「bottom right corner between the volume and the full screen buttons」→ +- **封面位置與大小、控制列精確位置、背景處理(純色/模糊封面/取色漸層)、窄視窗行為** → **查不到官方說明**。 + +### 2.2 Apple Music(macOS) + +- **歌詞在右側**(逐字,含官方截圖說明):「**The Full Screen Player** with a song playing and **lyrics on the right**, which appear onscreen in time with the music.」;開關方式「Lyrics button」;全螢幕播放器「Choose Window > Full Screen Player」→ +- **網站版同樣歌詞在右側**(逐字):「A song is playing in the Full Screen Player in Apple Music. **Lyrics appear on the right**, in time with the music.」→ +- **佇列位置**(逐字):MiniPlayer 的「**Playing Next button in the bottom-right corner**」可檢視與編輯 upcoming songs;Full Screen Player 由 MiniPlayer 左上綠色鈕進入 → +- **窄視窗行為**(逐字,但出處是 Apple Music **Classical** 的 web 說明):「Switch from the Full Screen Player to the MiniPlayer: **Reduce the width of the window—drag the right or left edge inward—until the Close button appears.**」→ 。macOS Music 是否同規則 → **查不到官方逐字**。 +- 全螢幕進入/離開(逐字):左上 Full-Screen 鈕進入、按 **Esc** 離開 → +- **封面位置與大小、背景處理** → **查不到官方文字說明**(官方只有截圖)。 + +### 2.3 YouTube Music(桌面 web) + +- **官方版面文件查不到**。 +- 第三方描述(9to5Google, 2019-10-28,逐字):「**Media controls are docked at the bottom** with play/pause, backwards, and forwards always in the **bottom-left**, while **album art and track details are centered**. Volume, repeat, and shuffle round out this strip. Tapping slides up **full-screen controls, larger cover art, and a now-playing queue**.」→ (**第三方,2019 年描述,可能已過時**) +- 同來源的窄視窗行為(逐字,指頂部導覽列):「Depending on the window size, **the text switches to just icons**.」→ 同上 +- 手機版 2025 Now Playing 改版(控制列移到曲名/演出者下方、Up Next 雙欄、歌詞改 sheet)為第三方報導,與桌面 web 無直接關係 → (**第三方**) + +### 2.4 Tidal(桌面 app) + +- **佇列/Now Playing**(搜尋索引摘要逐字,正文抽取只取到導覽骨架):「The Play Queue menu allows you to manage your Play Queue as well as **Now Playing, Next Up, and recently played content. Desktop.**」→ +- Now Playing 畫面存在(逐字,Tidal Connect 文章):「In the Tidal app, open the **Now Playing screen** while playing a track. From the Now Playing screen, select the **device output icon**.」→ +- 歌詞官方文章只說支援 41 種語言,**未描述位置** → +- **封面位置與大小、控制列位置、背景處理、窄視窗行為** → **查不到官方說明**。 + +### 2.5 網易雲音樂 PC 版 + +- **官方版面說明查不到**。 +- 官方站(web 播放器)可見文字只有播放控制「上一首/播放暫停/下一首」與「打開客戶端播放,享受高清音質/去客戶端播放」→ +- 唯一沾到版面的官方站內文字是**使用者專欄文章**(非官方文件):「PC端:**点击歌词**,输入你要搜索的内容就可以。」→ +- 封面/歌詞/佇列/控制列位置、背景處理、窄視窗行為 → **查不到**。 + +### 2.6 QQ 音樂 PC 版 + +- **官方版面說明查不到**。官方下載頁只有版本號(Windows PC 22.6.1、Mac 11.9.1、Linux 1.1.8)→ +- 第三方(onlinedown)描述歌詞可切「竖屏」→ (**第三方**) +- 第三方(百度经验)描述桌面歌詞開關在「主界面右上角…点击『词』」→ (**第三方**) +- 其餘欄位 → **查不到**。 + +### 2.7 Namida(Flutter,開源) + +固定 SHA `acb1e1622600440cc793f389f497e6771c732c5e` + +- **寬螢幕播放頁版面**(`lib/ui/pages/wide_screen_player_page.dart`):根為 `BackgroundWrapper` → `SafeArea` → `Stack`(左上 back 鈕 top:4,left:4)→ `Padding(horizontal: 16.0, vertical: 6.0)` → `Row[ Expanded(flex: 5, _LeftPane), SizedBox(width: 26.0), Expanded(flex: 5, _RightPane) ]` —— **左右各半(50/50)**。 +- **左側**:`Center → ConstrainedBox(maxWidth: maxHeight) → Column[ 曲名(displayLarge, maxLines 2) + 演出者(displaySmall, maxLines 1), gap = (maxHeight*0.02).clamp(6,16), Expanded(_Artwork), PlayerTransportControls(waveform seekbar) ]`;封面尺寸由可用框與圖片長寬比換算(`resolvePlayableImageAspectRatio`)。 +- **右側**:`Column[ _PlayerActionsRow, 兩顆 _PaneChip(lang.lyrics / lang.queue), Expanded(IndexedStack) ]`;IndexedStack 內容為 `LyricsLRCParsedView`(字級 = `(maxWidth*0.03).clamp(15,26)`)與 `CurrentQueueList` —— **歌詞與佇列是同一個面板位置的互斥分頁**(非並排)。 +- **面板選擇會持久化**:`settings.extra.widePlayerPageIndex`。 +- **背景**:`BackgroundWrapper`(動態取色)。README 逐字:「Material3-like Theme. **Dynamic Theming, Player Colors are picked from the current album artwork.**」→ +- **官方截圖目錄**(未下載):(`collection_dark_1.jpg`、`collection_light_1.jpg`、`yt_miniplayer.png` 等) +- **窄視窗**:wide player 是獨立 route(`RouteType.PAGE_widePlayer`),窄視窗走一般 mobile now playing;**切換門檻本輪未查證**。 + +### 2.8 Harmonoid(Flutter,開源) + +固定 SHA `2b021f7b0b5dbcbe027aec010580977a2939a28d` + +- **桌面播放頁結構**(`lib/features/now_playing/desktop/desktop_now_playing_screen.dart`):`Scaffold → Stack[ Positioned.fill(桌布/carousel), Positioned.fill(黑 20% 遮罩), Positioned.fill(上下漸層:黑 0.2 → 透明 → 透明 → 黑 0.2), Positioned.fill(Column[ Expanded(歌詞區,可切換), Controls ]) ]`。 +- **歌詞位置**:佔滿控制列以上的整個 `Expanded` 區,受 `notifier.desktopNowPlayingLyrics` 切換,無歌詞時為 `SizedBox`。 +- **控制列**:`Row[ 封面(width/height = MediaQuery.height*0.28,clamp 0–256), SizedBox(32), Expanded(Column: 標題/演出者/專輯), SizedBox(32), 播放清單鈕, SizedBox(32) ]`,下方另一列為進度條與控制圖示。 +- **背景處理**:`NowPlayingBackground` 用 `AnimatedMeshGradient`,顏色取自 `NowPlayingColorPaletteNotifier` 的 palette(只取 `computeLuminance() < 0.5` 的色;palette 為空時四色皆黑)→ +- **桌布可換成自訂圖**:`DesktopNowPlayingScreenCarousel` 依 `Configuration.instance.desktopNowPlayingCarousel` 切換,index 0 為 `NowPlayingBackground`,其餘為 `Image.asset` / `Image.file` 滿版。 +- **佇列位置**:`DesktopNowPlayingPlaylist` 是**獨立畫面**,寬度 `kDesktopCenteredLayoutWidth`。 +- **窄視窗**:另有 mobile 版檔案(`mobile/m2_mobile_now_playing_bar.dart`、`m3_mobile_now_playing_bar.dart`、`mobile_now_playing_lyrics_screen.dart`);**切換門檻本輪未查證**。 +- README 逐字:「Material Design 3 & 2」、lyrics(LRC, tags & online)、lyrics translations → +- **官方截圖在另一個分支 `screenshots`**(SHA `ebc5dd7321edf2006ee5526fd9a03b5fd5f9af0c`,與 master 不同 SHA,內容可能不一致)→ + +### 2.9 Spotube(Flutter,開源) + +固定 SHA `69a310c78f5ceaf4eab7dfee98f187d38211c9ba`(分支 `master`) + +- **播放頁是自底部升起的面板**(`lib/modules/player/player_overlay.dart`):`SlidingUpPanel(maxHeight: screen height, minHeight: 63, parallaxEnabled: true, renderPanelSheet: false, header: SizedBox(height: 63, PlayerOverlayCollapsedSection), panelBuilder: PlayerView)` → +- **面板內版面**(`lib/modules/player/player.dart`):`Column[ 封面 Container, SizedBox(60), 曲名/演出者區, 控制列(showQueue: false), Row[ Expanded(→ PlayerQueueRoute), SizedBox(10), Expanded(→ PlayerLyricsRoute) ] ]` —— **歌詞與佇列都是推出去的全頁 route,不是同頁面板**。 +- **窄/寬切換(關鍵)**:`PlayerView` 內 `useEffect` 判斷 `mediaQuery.lgAndUp` 為真時,post-frame 直接 `panelController.close()` —— **大螢幕自動關閉播放面板**。 +- **斷點值**(`lib/extensions/constrains.dart`):`xs: 480.0, sm: 640.0, md: 820.0, lg: 1024.0, xl: 1280.0`;`lgAndUp` = width > 820 → +- 歌詞頁獨立目錄:`lib/pages/lyrics/`(lyrics / mini_lyrics / plain_lyrics / synced_lyrics);`lib/pages/player/`(lyrics / queue / sources)→ +- README 逐字:「**Time synced lyrics** regardless of the plugin support」→ +- **官方截圖**(未下載):桌面 `assets/branding/spotube-screenshot.png`、行動 `assets/branding/mobile-screenshots/combined.jpg` → +- **背景處理**:在 `player.dart` 未見取色或模糊封面邏輯 → **查不到**。 + +### 2.10 Finamp(Flutter,開源) + +固定 SHA `0aae9d5ed530ffdf3d62ab12dab4f475a67687dc`(**預設分支為 `redesign`,非 `main`**) + +- **封面大小**:`imageSize = min(MediaQuery.widthOf(context), MediaQuery.heightOf(context)) / 2` +- **橫豎向切換**:`MediaQuery.orientationOf(context)` 決定版面 +- **歌詞/佇列位置**:兩者都是獨立 route —— 左滑開啟 `LyricsScreen`;`QueueList` 亦為獨立 route(`QueueButton`) +- **背景處理**:`if (ref.watch(finampSettingsProvider.useCoverAsBackground)) const BlurredPlayerScreenBackground()` —— **可切換的模糊封面背景** +- **相關設定項**:`playerScreenCoverMinimumPadding`、`prioritizeCoverFactor`(widthPercent = factor*2+49;minPercent = factor*2+34)、`hidePlayerBottomActions`、`suppressPlayerPadding` +- 全部出處: +- **官方截圖目錄**:`images/screenshots/` 下只有 `linux/` → +- **窄視窗變化**:**未查證**(此為行動優先 UI)。 + +### 2.11 Feishin(開源,非 Flutter;Electron + React) + +固定 SHA `b34ffda29e0fdafe771f9c3ef470df3be88a3d42`(分支 `development`) + +- **左右分割**(`full-screen-player.module.css`):`.image-column { width: 50%; height: 100% }`;`@media (orientation: portrait)` 時 `width: 100%; height: 50%`。無 active module 時加 `.image-column-full` → `width: 100%`(TSX 逐字:`[styles.imageColumnFull]: !hasActiveModule`)→ +- **右側模組(歌詞/佇列/related/visualizer)**:`activeTab ∈ {queue, related, lyrics, visualizer}`;`.grid-container { position: absolute; top: 0; right: 0; width: 50%; height: 100% }`;portrait 時 `bottom: 0; left: 0; width: 100%; height: 50%`;收合態 `.grid-container-collapsed { transform: translateX(100%) }`(portrait 為 `translateY(100%)`),`transition: transform 0.5s ease-out` → +- **控制列位置**:`FullScreenPlayerControls` 在容器底部;設定鈕在左上(`.full-screen-player-controls-container`,預設 `opacity: 0.2`,容器 hover 時 `opacity: 1`)→ +- **背景處理(兩種並存)**:`dynamicBackground` 開啟時,`BackgroundImage` 以**專輯封面鋪滿**(`background-size: cover`)+疊一層 `backdrop-filter: blur(var(--image-blur))` 的遮罩;底色用 `useFastAverageColor({ algorithm: 'dominant' })` **取主色**;再有可調透明度的黑色遮罩(`alpha = opacity/120`)。關閉時底色為 `var(--theme-colors-background)` **純色**。 +- **容器尺寸**:`.container { position: absolute; inset: 0; z-index: 200; display: flex; justify-content: center }`、`.responsive-container { max-width: 2560px }` +- **手機版另有獨立檔案**:`mobile-fullscreen-player.tsx`、`mobile-fullscreen-player-album-art.tsx` 等 → +- **官方截圖**(未下載):`media/preview_full_screen_player.png` → +- README 逐字提及:「Synchronized and unsynchronized lyrics support」、MPV 與 web player 後端 → + +### 2.12 Cider(閉源) + +- `ciderapp/Cider` GitHub repo 已**封存**,描述為「🎵 Source code for Cider 1」,最後 push 2024-12-10 → (**v2+ 無公開原始碼**) +- **官方 changelog**:4.0.27(2026-09-22,最新)、4.0.25(2026-09-10)、4.0.0(2026-06-16)、3.1.0(2025-09-26)→ +- **官方 devlog 逐字**(Cider Collective 的 itch.io devlog): + - 佈局名單:「**Calico** - Based on Mojave, features a split view styled layout. **Montara** - Based on Mavericks, features a split view styled. **Compact** – a new slim experience… **Compact Inline** – an alternate version… Navigation is now inlined with content.」 + - 窄視窗:「**Sidebar can now be shrunken into a "Compact" form, similar to AM. Sidebar is now space aware and will enter a popout mode if Window…**」 + - 背景:「The current tracks color scheme as the background supplied by the **Apple Music API**.」 + - 歌詞:「**Immersive** layout… Modeled after the original Immersive layout from the Cider 2.0」;「Lyrics can now be viewed from **miniplayer**」 + - 快捷鍵:「**Spacebar will now toggle music playback**」、「**Alt + Enter** will now enter Fullscreen for Windows & Linux」、「Various Keybinds added around the app, can be adjusted in **General -> Keybinds**」 + - 佇列:「Added "Play" button to items in the queue. Added "Remove" button to items in the queue.」 + → +- **2.3.2 devlog 逐字**:「**New Queue List** + Replaces the current queue with a new, more powerful queue list. Featuring multi-selection and a new UI.」;「New Experiment: **Mini Player single-line lyrics**」→ +- **「Sugar layout」一詞**:本輪在官方頁面**查不到**;前段對話提到的此名 → **撤回**。 +- 遠端 App Store 頁面提到的「Immersive Lyrics」、橫向版面、垂直佇列,本輪**未重查** → 需複查。 + +--- + +## 3. 設計 token 的慣例 + +### 3.1 M3 的 token 分層與名稱 + +- **三層**:system token(前綴 `sys`)→ reference token(前綴 `ref`)→ component token。system token 指向 ref token,ref token 才指向靜態值。component token 官方標註「in development」,規範上必須指向 sys/ref token,**不可含 hex 等硬編碼值** → + +**Spacing(M3 現在官方有 spacing scale)** + +- 官方有專門的 spacing 頁(Styles > Spacing),三頁:overview / applying-spacing / tokens → +- 逐字:「Spacing units follow an **8dp scale**. Rather than defining every value, Material only defines the most recommended spacing unit values on the scale.」 +- 基準單位:**space100 = 8dp**,其餘是它的倍數(逐字:「multiplier from the baseline unit of 8dp, which is space100」) +- 官方列出的 spacing system token 名稱:**Space 75、Space 100、Space 125、Space 150、Space 175、Space 200、Space 250、Space 300、Space 400、Space 450、Space 500、Space 600、Space 700、Space 800、Space 900** → +- 同頁逐字:「The range covers **0x to 9x**」、「The main spacing units are multiples of 8dp」,另有 nested units(0.25x / 0.5x / 0.75x / 1.25x),官方只定義常用的 nested 值(2dp、4dp、6dp、10dp)。對應值:space25=2、space50=4、space75=6、space100=8、space500=40、space600=48、space700=56、space800=64、space900=72。spacing overview 頁的圖說逐字寫「2, 4, 6, 8 at the bottom range and 48, 56, 64, 72 at the top」,與上述倍數一致。 +- **兩頁說法不一致**:applying-spacing 頁逐字寫「A list of spacing system tokens from **100 to 400**」,但 tokens 頁列到 900 → 。官方未解釋此差異 → **存疑**;space125/150/175 等的實際 dp 值是由 8dp 倍數推得 → **推測**。 +- 官方明示用途(逐字,applying-spacing 頁):「Apply these to your product's custom components and layouts, **replacing any hardcoded values**. If the right system token doesn't exist, customize the system and add your own.」 +- component 屬性命名策略(逐字,tokens 頁):未來一律用 `padding` / `margin` / `gap` + 方位詞(horizontal / vertical / leading / trailing / top / bottom);舊稱用 `space`(leading-space、between-space 等)。 + +**Shape scale(corner radius)** + +- 官方頁:;M3 Expressive 另加 corner-radii 選項(Large increased 20dp、Extra large increased 32dp、Extra extra large 48dp)→ +- **可直接查證的官方值**:androidx Material3 `ShapeTokens.kt`(`// VERSION: 14_1_0`,GENERATED CODE)→ + + | Token | 值 | + |---|---| + | CornerExtraSmall | `RoundedCornerShape(4.0.dp)` | + | CornerSmall | `RoundedCornerShape(8.0.dp)` | + | CornerMedium | `RoundedCornerShape(12.0.dp)` | + | CornerLarge | `RoundedCornerShape(16.0.dp)` | + | CornerLargeIncreased | `RoundedCornerShape(20.0.dp)` | + | CornerExtraLarge | `RoundedCornerShape(28.0.dp)` | + | CornerExtraLargeIncreased | `RoundedCornerShape(32.0.dp)` | + | CornerExtraExtraLarge | `RoundedCornerShape(48.0.dp)` | + | CornerFull | `CircleShape` | + + 另有單邊變體 `CornerExtraSmallTop` / `CornerExtraLargeTop` / `CornerLargeStart` / `CornerLargeEnd`。Flutter 端對應的可覆寫介面是 `ThemeData.shapes`(`extraSmall` / `small` / `medium` / `large` / `extraLarge`;Expressive 再加 `largeIncreased` / `extraLargeIncreased` / `extraExtraLarge`)→ + +**Type scale** + +- 五個角色:**display、headline、title、body、label**,各三級共 15 個 style(M3 Expressive 另有 emphasized 變體)→ 、 +- M3 用 Major Second(1.125)音階,key base size = 14。 +- 官方字級值(取自 Flutter `Typography.material2021` 的 `_M3Typography.englishLike`,該檔註解逐字寫「match the 2021 Material Design 3 specification」)→ + + | Token | fontSize | height | weight | letterSpacing | + |---|---|---|---|---| + | displayLarge | 57 | 1.12 | w400 | -0.25 | + | displayMedium | 45 | 1.16 | w400 | 0.0 | + | displaySmall | 36 | 1.22 | w400 | 0.0 | + | headlineLarge | 32 | 1.25 | w400 | 0.0 | + | headlineMedium | 28 | 1.29 | w400 | 0.0 | + | headlineSmall | 24 | 1.33 | w400 | 0.0 | + | titleLarge | 22 | 1.27 | w400 | 0.0 | + | titleMedium | 16 | 1.50 | w500 | 0.15 | + | titleSmall | 14 | 1.43 | w500 | 0.1 | + | bodyLarge | 16 | 1.50 | w400 | 0.5 | + | bodyMedium | 14 | 1.43 | w400 | 0.25 | + | bodySmall | 12 | 1.33 | w400 | 0.4 | + | labelLarge | 14 | 1.43 | w500 | 0.1 | + | labelMedium | 12 | 1.33 | w500 | 0.5 | + | labelSmall | 11 | 1.45 | w500 | 0.5 | + +### 3.2 用 `ThemeExtension` 放間距/圓角的開源實例 + +**(A)Very Good Ventures `very_good_app_ui` brick —— 間距 token 進 ThemeExtension(最貼近本專案需求)** + +- `very_good_app_ui/__brick__/lib/src/theme/app_spacing.dart`:`class AppSpacing extends ThemeExtension`,欄位 `double xxs/xs/sm/md/lg/xlg/xxlg`,預設 `xxs=4, xs=8, sm=12, md=16, lg=24, xlg=32, xxlg=48`,實作 `copyWith` 與 `lerp`(用 `lerpDouble`)。 +- `app_theme.dart`:`ThemeData(... extensions: const [appColors, AppSpacing(), AppTextStyles()])` +- 取用:`lib/src/extensions/build_context_extensions.dart` 提供 `extension AppThemeBuildContext on BuildContext { AppSpacing get appSpacing => Theme.of(this).extension()!; }` +- Permalinks(SHA `038a0df18ec65fc4a6d9969715f7da008f795ca5`): + - + - + - + +**(B)YumNumm/EQMonitor —— 間距 token 進 ThemeExtension + codegen** + +- `app/lib/core/designsystem/extensions/spacing_theme_extension.dart`:`@tailorMixinComponent class SpacingThemeExtension(...) extends ThemeExtension with _$SpacingThemeExtensionTailorMixin`,欄位 `xs=4, sm=8, md=12, lg=16, xl=20, xxl=24, xxxl=28, xxxxl=32`(用 `theme_tailor_annotation` 生成 `copyWith` / `lerp`) +- Permalink(SHA `c89d43b631221b6e1ed8a6e8ef7bf344d7ed68f7`): + +**(C)Floating-Dartists/flutter_dsfr —— 圓角 token 進 ThemeExtension(法國政府設計系統 DSFR 的 Flutter 移植)** + +- `lib/src/theme/radius.dart`:`class DSFRRadius extends ThemeExtension`(`const DSFRRadius.regular() : this._(small: const Radius.circular(4))`),另有 `class DSFRBorderRadius extends ThemeExtension` 包住 radius 並提供 `BorderRadius get small`;皆實作 `copyWith` / `lerp` / `==` / `hashCode` +- Permalink(SHA `a93fb4dfb861fa7620b35c965bc7079eeecfc2f7`): + +**反例**:`tommyxchow/frosty`(桌面 Flutter app)的 `FrostyColors extends ThemeExtension` 只放顏色;**它的間距與圓角是行內字面值**(`EdgeInsets.symmetric(horizontal: 12)`、`BorderRadius.all(Radius.circular(12))` 直接寫在 `ThemeData` 各 component theme 裡)→ 。**即社群實際做法並不一致。** + +### 3.3 以 lint/靜態規則禁止字面數字間距的先例 + +找到 3 個可查的例子,皆為 `custom_lint` 系 analyzer 規則(非 `dart_code_metrics`): + +**(A)pattobrien/lints —— `design_system_lints`(最完整,規則族)** + +- `avoid_edge_insets_literal`(`AvoidEdgeInsetsLiteral extends LintRule`),訊息「Avoid hardcoded EdgeInsets values」,correction「Use values in design system spec instead」。實作:`visitInstanceCreationExpression`,判斷型別是否為 `EdgeInsets`,逐個 argument 檢查是否為 `Literal` 或非 design-system expression 就 `reportLint`。 +- README 列出同套還有:`avoid_sized_box_height_width_literals`、`avoid_border_radius_literal`、`avoid_color_literal`、`avoid_icon_literal`、`avoid_text_style_literal`、`avoid_box_shadow_literal`。用 `sidecar` 套件建構。 +- Permalinks(SHA `8b7d2ed0054ef4f31bc6d858600511126bac7208`): + - + - + +**(B)bcblr1993/iot_devkit_flutter —— `avoid_raw_edge_insets`** + +- `AvoidRawEdgeInsets extends DartLintRule`,`LintCode(name: 'avoid_raw_edge_insets', problemMessage: 'EdgeInsets uses a literal number. Prefer LabTokens.of(context).sXxx ...', errorSeverity: ErrorSeverity.WARNING)`。實作:`_edgeTypes = {'EdgeInsets','EdgeInsetsDirectional'}`,只當**至少一個參數是 `IntegerLiteral` 或 `DoubleLiteral`** 才告警;並有豁免清單 `_isExempt`(`/lib/ui/lab/`、`/test/`、`/tooling/`、`/integration_test/`)。 +- Permalink(SHA `5e8bffe857cd500b78688b9156681c2dd37727c4`): + +**(C)weiping/kite —— `kite_no_hardcoded_spacing`** + +- `packages/design/custom_lint/lib/no_hardcoded_style.dart`,`LintRule`,訊息「禁止硬編碼間距,請使用 AppSpacing 的令牌(packages/design)」。**該檔自述「狀態:骨架」**,visit 邏輯只以註解示意,未完成。 +- Permalink(SHA `6832ac46da12fd2319dba0184cf11918d43425b9`): + +- `dart_code_metrics` 本身:官方規則清單頁**查不到**(該套件已轉為商業產品 DCM)→ 查不到它有專門擋 `EdgeInsets` / `SizedBox` 字面值的規則名稱與出處。 +- **注意**:三個例子都是小型/範例專案。**查不到大型 App 在 CI 擋字面間距的實例**。 +- 與 FMP 現況的關係(事實):FMP 走的是**測試**而非 lint —— `test/ui/static_rules/*_static_rule_test.dart` 以讀 `lib/` 原始碼的方式擋規則(見 `current-state.md` §7)。 + +--- + +## 4. 音樂播放器鍵盤快捷鍵(官方表) + +### 4.1 Spotify 桌面(有官方表)→ + +| 功能 | 鍵 | +|---|---| +| Play/Pause | Space | +| Filter(篩選) | Cmd + F 或 Ctrl + F | +| Go to Previous | Up Arrow | +| Go to Next | Down Arrow | +| Add to Library | Left Arrow | +| Add to Queue | Right Arrow | +| Mute/Unmute | M | +| Toggle Now Playing View Sidebar | Alt + Shift + R | +| Toggle Your Library Sidebar | Alt + Shift + L | +| Go to Queue | Alt + Shift + Q | +| Go to Now Playing | Alt + Shift + J | +| Open Search | Cmd + K 或 Ctrl + K | +| Go to Search | Ctrl/Cmd + Shift + L (Mac)、Ctrl/Cmd + L (Windows) | +| Open Context Menu | Alt + J | +| Select All | Cmd + A 或 Ctrl + A | +| Shuffle | Alt + S (Mac)、Ctrl/Cmd + S (Windows) | +| Repeat | Alt + R (Mac)、Ctrl/Cmd + R (Windows) | +| Go to Library/Playlists/Podcasts/Artists/Albums | Alt + Shift + 0/1/2/3/4 | + +以上逐字出自同一頁。**Esc(返回)**:官方表**未列** → 查不到。 + +### 4.2 Apple Music(macOS,有官方表)→ + +| 動作 | 快捷鍵 | +|---|---| +| Start playing or pause the selected song | **Space bar** | +| Play the currently selected song from the beginning | Return | +| Move forward or backward within a song(seek) | **Option-Command-Right Arrow / Left Arrow** | +| Stop playing the selected song | Command-Period | +| 播放中下一首 | **Right Arrow** | +| 播放中上一首 | **Left Arrow** | +| Show the currently playing song in the list | Command-L | +| Show the queue | **Option-Command-U** | +| 上/下一張專輯 | Option-Right Arrow / Option-Left Arrow | +| 音量 | Command-Up Arrow / Command-Down Arrow | +| 開等化器 | Option-Command-E | +| 章節前後 | Shift-Command-Right Arrow / Shift-Command-Left Arrow | +| 從 URL 串流 | Command-U | + +- **Cmd+F 搜尋**:官方 Mac 表**未列**(Lifehacker 有列,屬第三方)→ 官方表查不到;**Esc**:官方表未列 → 查不到。 +- Apple Music **Windows** 另有官方表(鍵位不同)→ (本輪**未逐字重查內容**;第三方 Lifehacker 列出 Windows 為 Ctrl-Spacebar 播放/暫停、Ctrl-Alt-Left/Right seek → ) + +### 4.3 foobar2000(**查不到官方預設表**) + +- 官方 FAQ 只解釋 global keyboard shortcut 的 context 綁定(逐字):「For **global** keyboard shortcuts there is no way to chose a list of tracks automatically when they are used, so you have to chose a context when you bind the command.」——全頁沒有預設鍵表 → +- 第三方 defkey.com 聲稱官方預設 9 個:Ctrl+F(Search)、Ctrl+N(New playlist)、Ctrl+O(Open)、Ctrl+P(Preferences)、Ctrl+S(Save playlist)、Ctrl+U(Add location)、Ctrl+W(Remove playlist)、Ctrl+Enter(Properties)、Alt+A(Stay always on top);並稱「All predefined shortcuts are **non-global**」→ (**第三方**;注意其預設**沒有** Space 播放/暫停,也**沒有**方向鍵 seek) + +### 4.4 YouTube Music(**查不到官方表**) + +- YouTube Music **沒有**官方快捷鍵頁面(搜尋只找到第三方擴充與論壇討論)→ (**第三方**) +- 鄰近產品 **YouTube** 有官方表(對照用,**不是** YouTube Music)→ :Spacebar(seek bar 被選取時)Play/Pause;`k` Pause/Play;`m` Mute/Unmute;**Left/Right arrow on the seek bar = Seek backward/forward 5 seconds**;`j` Seek backward 10 seconds;`Shift+N` next video;`Shift+P` previous video(僅播放清單);`i` 開 Miniplayer;`SHIFT+?` 開清單。**Esc**:該表未列 → 查不到。 +- 第三方(9to5Google):YouTube Music 桌面 PWA「supports your device's **media keyboard shortcuts** to play, pause, and skip」→ + +### 4.5 桌面焦點順序(focus traversal)的官方 API 與社群實例 + +**官方 API 文件** + +- `FocusTraversalGroup` (逐字):「A widget that describes the inherited focus policy for focus traversal for its descendants, **grouping them into a separate traversal group**.」;「A traversal group is treated as one entity when sorted by the traversal algorithm.」;「Within the group, it will use the given policy to order the elements」;「The group itself will be ordered using the parent group's policy.」預設「traverses in reading order using `ReadingOrderTraversalPolicy`」。參數 `policy`、`descendantsAreFocusable`、`descendantsAreTraversable`。 +- `FocusTraversalOrder` :搭配 `OrderedTraversalPolicy`;`NumericFocusOrder` / `LexicalFocusOrder` 兩種 `FocusOrder`。官方 focus 指南有 `FocusTraversalGroup(policy: OrderedTraversalPolicy(), child: Row(children: [ ... FocusTraversalOrder(order: const NumericFocusOrder(2), ...) ]))` 的完整範例 → +- `TraversalEdgeBehavior` :「Controls the focus transfer at the edges of a `FocusScopeNode`」:`closedLoop`(停在 scope 內、繞回另一端)、`leaveFlutterView`、`parentScope`(無 parent 時 fallback 回 `closedLoop`)、`stop`。`showDialog` 預設 `closedLoop`;`Navigator` 有 `routeTraversalEdgeBehavior` / `routeDirectionalTraversalEdgeBehavior` → 、 +- `FocusScope` vs `FocusTraversalGroup` 的差別(逐字,):「If you just want to group widgets together in a group so that they are traversed in a particular order, **but the focus can still leave the group**, use a `FocusTraversalGroup`.」——`FocusScope` 會限制焦點不能離開;只要分組排序就用 `FocusTraversalGroup`。 + +**社群實例(用 `FocusTraversalGroup` 分組)** + +- **DonutWare/Fladder(Flutter Jellyfin 桌面/TV client)**:`lib/widgets/navigation_scaffold/components/side_navigation_bar.dart:145` 為 `FocusTraversalGroup(policy: _RailTraversalPolicy(), child: ...)`,`class _RailTraversalPolicy extends ReadingOrderTraversalPolicy`(第 241–242 行)→ **導航 rail 自成一組**;`lib/widgets/navigation_scaffold/components/navigation_body.dart:73` 為 `FocusTraversalGroup(policy: GlobalFallbackTraversalPolicy(fallbackNode: navBarNode), child: ...)` → **內容區自成一組,且提供 fallback 節點接到導航列**。另有 `lib/widgets/shared/grid_focus_traveler.dart:36` 與自製 `FocusRow`。Permalinks(SHA `91992fcd48cd83baaac1a979345e386e43beddc0`): + - + - +- **gskinnerTeam/flutter-adaptive-demo**:`lib/main_app_scaffold.dart:107` 為 `return FocusTraversalGroup(child: page ?? Container());` → 把「每個 page 內容」包成獨立 traversal group(預設 ReadingOrderTraversalPolicy)。Permalink(SHA `e8f05b33c0d37744a453f67bd73912e7e5fcfc4f`): +- **MahanRahmati/Arna**:`lib/src/base/side_scaffold.dart:164,263`、`lib/src/base/tab_view.dart:264,309` 皆出現 `FocusTraversalGroup(`(其餘檔為搜尋命中,未逐一開檔)。Permalink(SHA `c50ffcf0f0aa2c213923013c85201df429607b72`): +- **查不到**任何「官方建議把導航區/內容區/播放控制列分成三個 tab group」的 Flutter 官方文件或設計指引。官方只描述 API 語意 → **官方指引層級:查不到**;分組實作只有上述社群實例。 + +--- + +## 5. 使用者指南:內建說明頁 vs 連到網站文件 + +| App | 結論 | 證據(固定 SHA permalink) | +|---|---|---| +| **Spotube** | **兩者都有,但 app 內只有 About 頁**(無 FAQ/說明頁);About 連到官網與 GitHub/Discord。官網 `website/` 內有完整 docs(`website/src/content/docs/*.mdx`)。另有 onboarding:`lib/pages/getting_started/`(greeting / playback / region / support)。 | `lib/pages/settings/sections/about.dart` 內 `launchUrlString("https://spotube.krtirtho.dev")`、`https://github.com/KRTirtho/spotube`、`https://discord.gg/uJ94vxB6vg`、LICENSE、opencollective。
    | +| **Namida** | **內建 About 頁**,連到 GitHub / Telegram / Discord,並從 GitHub raw 抓 `CHANGELOG.md` 在 app 內顯示;**查不到**官方文件網站。另有 `lib/ui/pages/onboarding.dart`。 | `lib/ui/pages/about_page.dart`:`link: 'https://github.com/MSOB7YY'`、`https://t.me/namida_official`、`https://discord.gg/WeY7DTVChT`、`Rhttp.get('https://raw.githubusercontent.com/namidaco/namida/main/CHANGELOG.md')`。
    | +| **Finamp** | **內建 About dialog**(用 Flutter 內建 `showAboutDialog`),連到 GitHub repo / releases / Weblate;**查不到** app 內連到文件網站,也查不到專案有獨立文件站(repo 有 GitHub wiki,`has_wiki = true`)。 | `lib/screens/settings_screen.dart`:`repoLink = "https://github.com/finamp-app/finamp"`、`releaseNotesLink = ".../releases"`、`translationsLink = "https://hosted.weblate.org/projects/finamp"` + `showAboutDialog(...)`。
    | +| **Feishin** | **連到外部網站/GitHub**:Electron 原生選單有 `Help`(`role: 'help'`),項目全部 `shell.openExternal` 到 GitHub(**無內建說明頁**)。 | `src/main/menu.ts` 的 `subMenuHelp`:`'Learn More'` → github repo;`'Documentation'` → `https://github.com/jeffvli/feishin?tab=readme-ov-file#getting-started`(**用 README 當文件**);`'Community Discussions'` → `/discussions`;`'Search Issues'` → `/issues`;末項顯示版本。
    | +| **LocalSend** | **兩者都有**:內建 About 頁 + 內建「說明」dialog。 | `app/lib/pages/about/about_page.dart`:`launchUrl('https://localsend.org')`(Homepage)、GitHub、Codeberg、Apache License、`LicensePage()`、`DebugPage()`。另有 app 內說明 dialog:`app/lib/widget/dialogs/send_mode_help_dialog.dart`。
    | +| **NewPipe** | **兩者都有**:內建「About & FAQ」畫面,FAQ 條目連到官網 FAQ。 | `shared/src/commonMain/kotlin/net/newpipe/app/screen/about/AboutPage.kt` 內有 `url = Constants.URL_FAQ`、`Res.string.view_on_github`、donation、website。常數在 `shared/src/androidMain/kotlin/net/newpipe/Constants.kt`:`URL_GITHUB`、`URL_DONATION`、`URL_WEBSITE`、`URL_PRIVACY`、`URL_FAQ`。strings:`tab_about = "About & FAQ"`、`faq = "View on website"`。
    | + +**商業桌面版的 Help 選單** + +- **Spotify(Windows/macOS 桌面)**:桌面版左上「三點選單」有一個 **Help** 子選單,內含 **Troubleshooting** 等項目(社群貼文描述操作路徑「three dots menu at the top left corner > Help > Troubleshooting」)→ 。是否直接開瀏覽器到 `support.spotify.com` → **查不到官方明文,推測**。 +- **Apple Music(macOS)**:**查不到**可靠來源證實其 Help 選單內容或是否連到網站。(推測:macOS app 的 Help 選單通常開 Apple 說明書/支援頁,但無可直接引用的出處。) +- **YouTube Music(桌面)**:桌面版是網頁/PWA(`music.youtube.com`),**查不到**有原生 Help 選單的內建說明;**查不到**任何原生桌面 app 內建說明的證據。 + +--- + +## 本檔最不確定的 5 件事 + +1. **M3 寬度 class 的 Large(1200–1599dp)與 m3.material.io 的表格正文**:該站是 JS render,取不到正文;數值是 `developer.android.com` 的逐字表格與搜尋索引摘要拼合而成,Large 的上界是由 Extra-large(≥1600dp)反推。 +2. **M3 spacing token 的完整值表**:overview 頁暗示 2/4/6/8…48/56/64/72,applying-spacing 頁寫「tokens from 100 to 400」,tokens 頁列到 900 —— 三者不一致,未找到官方調和說法;space125/150/175 的實際 dp 值是推得。 +3. **Apple Music macOS 的「窄視窗 → MiniPlayer」行為**:官方只寫在 Apple Music **Classical 的 web** 說明頁,macOS Music 是否同規則無官方逐字來源。 +4. **Spotify 的全螢幕模式、封面尺寸與背景處理**:只有官方社群版主回覆與社群公告,無支援文件;「全螢幕整合進 Now Playing view、可切 Album view / Artist banner view」是版主回覆而非正式文件。 +5. **YouTube Music 與 foobar2000 的快捷鍵**:兩者都無官方預設表;foobar2000 的 9 個預設完全依賴第三方 defkey.com,且「預設沒有 Space 播放/暫停」需自行確認。另:Namida / Harmonoid / Finamp 的窄視窗切換門檻**未經真機或官方截圖驗證**,只讀到程式碼片段。 From 63b469fc47267cd1ee0f82ce73861e2564166138 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:34:02 +0800 Subject: [PATCH 092/133] chore(task): record desktop player layout decision --- .trellis/tasks/09-28-design-ui-ux/prd.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index 8bcbc52c9..63d439604 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -44,13 +44,19 @@ - U1–U8 都在重寫時處理;U7 右側面板保留常駐;U8 實作大斷點版面。 - Toast 位置照 ADR 0023;播放頁與桌面視窗的歌詞共用一套 widget(ADR 0021)。 +## 已決定 + +1. **桌面播放頁用方案 B(2026-09-28,按建議)**:示意頁 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ(私人)。 + ≥ 840dp:左右各半,左為封面、曲名、進度、控制;右欄分頁「歌詞|佇列|詳細」並記住上次的分頁;「詳細」放現行右側面板的內容。 + ≥ 1600dp:三欄——封面與控制|歌詞|佇列(分頁剩「佇列|詳細」)。< 840dp 用手機版播放頁。Esc 關閉;背景為模糊封面。 + 否決:A 左右分割(看佇列會蓋住歌詞、超寬空間用不上)、C 沉浸式歌詞(無歌詞曲目畫面空、佇列需另叫出)。 + ## 待決定 -1. 桌面播放頁的版面方案(2–3 選 1,含大螢幕變化)。 -2. 保留哪些語言、base locale。 -3. App 內鍵盤快捷鍵的範圍。 -4. 窄桌面視窗的迷你播放器保留哪些控制。 -5. 使用者指南(E20)去留。 +1. 保留哪些語言、base locale。 +2. App 內鍵盤快捷鍵的範圍。 +3. 窄桌面視窗的迷你播放器保留哪些控制。 +4. 使用者指南(E20)去留。 ## 不在範圍 From 6d6b8a8bc73aac3bb77607cdc27e74a2c2062588 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 18:35:43 +0800 Subject: [PATCH 093/133] chore(task): record i18n decision --- .trellis/tasks/09-28-design-ui-ux/prd.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index 63d439604..ba54734e4 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -51,12 +51,15 @@ ≥ 1600dp:三欄——封面與控制|歌詞|佇列(分頁剩「佇列|詳細」)。< 840dp 用手機版播放頁。Esc 關閉;背景為模糊封面。 否決:A 左右分割(看佇列會蓋住歌詞、超寬空間用不上)、C 沉浸式歌詞(無歌詞曲目畫面空、佇列需另叫出)。 +2. **三種語言保留、base locale 改為 zh-TW(2026-09-28,按建議)**:新字串先寫繁中;缺字退回繁中;測試要求三語言 key 完全一致。 + 字型 fallback 依語言分開(繁中先微軟正黑體/Noto Sans TC,簡中微軟雅黑/Noto Sans SC);數字用 `NumberFormat.compact`、英文複數用 slang 複數。 + 否決:只留繁中與英文(簡中使用者只能看英文)、簡中由 OpenCC 自動轉換(用詞不道地、要維護修正清單)。 + ## 待決定 -1. 保留哪些語言、base locale。 -2. App 內鍵盤快捷鍵的範圍。 -3. 窄桌面視窗的迷你播放器保留哪些控制。 -4. 使用者指南(E20)去留。 +1. App 內鍵盤快捷鍵的範圍。 +2. 窄桌面視窗的迷你播放器保留哪些控制。 +3. 使用者指南(E20)去留。 ## 不在範圍 From f931720725050e058e1d15b150dee2a7383da401 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:13:59 +0800 Subject: [PATCH 094/133] chore(task): record keyboard shortcut decision --- .trellis/tasks/09-28-design-ui-ux/prd.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index ba54734e4..4469277da 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -55,11 +55,18 @@ 字型 fallback 依語言分開(繁中先微軟正黑體/Noto Sans TC,簡中微軟雅黑/Noto Sans SC);數字用 `NumberFormat.compact`、英文複數用 slang 複數。 否決:只留繁中與英文(簡中使用者只能看英文)、簡中由 OpenCC 自動轉換(用詞不道地、要維護修正清單)。 +3. **App 內鍵盤快捷鍵(2026-09-28,按建議)**:固定一組、不可自訂,只在 FMP 為前景視窗且焦點不在輸入框時有效: + 空白鍵播放暫停、Ctrl+←/→ 上下一首、Shift+←/→ 倒轉快轉 5 秒、Ctrl+↑/↓ 音量、Ctrl+S 隨機、Ctrl+R 循環、Ctrl+F 搜尋、 + Ctrl+L/Ctrl+Q 播放頁右欄切歌詞/佇列、Esc 關閉播放頁與對話框、F6 在導覽列/內容/播放列之間跳、Ctrl+, 設定。 + 提示文字附按鍵,設定頁有完整清單;兩種主題都有明顯焦點框,Tab 只在同一區內移動。 + 全域快捷鍵照舊(可自訂、預設關、預設 Ctrl+Alt+…),同一組按鍵時全域優先;錄製全域快捷鍵時若與 App 內相同就提示。 + 擁有者問「只有全域不行嗎」:全域會攔走所有 App 的按鍵,只能用罕用組合,且 Esc、搜尋、焦點移動只在 App 內有意義(U2)。 + 否決:App 內只做畫面操作(在 App 內按空白鍵不能暫停)、App 內快捷鍵可自訂(要衝突檢查與錄製介面)。 + ## 待決定 -1. App 內鍵盤快捷鍵的範圍。 -2. 窄桌面視窗的迷你播放器保留哪些控制。 -3. 使用者指南(E20)去留。 +1. 窄桌面視窗的迷你播放器保留哪些控制。 +2. 使用者指南(E20)去留。 ## 不在範圍 From 46153641daa139df818bac7fa739d2686cdef717 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:15:13 +0800 Subject: [PATCH 095/133] chore(task): record player bar decision --- .trellis/tasks/09-28-design-ui-ux/prd.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index 4469277da..e6ba5800e 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -63,10 +63,13 @@ 擁有者問「只有全域不行嗎」:全域會攔走所有 App 的按鍵,只能用罕用組合,且 Esc、搜尋、焦點移動只在 App 內有意義(U2)。 否決:App 內只做畫面操作(在 App 內按空白鍵不能暫停)、App 內快捷鍵可自訂(要衝突檢查與錄製介面)。 +4. **桌面播放列依寬度分三段(2026-09-28,按建議,U4)**:曲名至少保留約 160px。 + ≥ 840:隨機、上一首、播放、下一首、循環、輸出裝置、音量滑桿;600–839:上一首、播放、下一首、音量圖示(點開滑桿)、「⋯」(隨機、循環、輸出裝置); + < 600:播放、下一首。點播放列空白處開播放頁,修正按鈕包按鈕(U3)。否決:中寬度保留五個播放控制(曲名只剩 6–7 字)。 + ## 待決定 -1. 窄桌面視窗的迷你播放器保留哪些控制。 -2. 使用者指南(E20)去留。 +1. 使用者指南(E20)去留。 ## 不在範圍 From 2e03765d27573e6b99a1330ce503c047388c9897 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:18:49 +0800 Subject: [PATCH 096/133] chore(task): add design and plan for ui-ux --- .trellis/tasks/09-28-design-ui-ux/design.md | 83 +++++++++++++++++++ .../tasks/09-28-design-ui-ux/implement.md | 12 +++ .trellis/tasks/09-28-design-ui-ux/prd.md | 13 +-- 3 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 .trellis/tasks/09-28-design-ui-ux/design.md create mode 100644 .trellis/tasks/09-28-design-ui-ux/implement.md diff --git a/.trellis/tasks/09-28-design-ui-ux/design.md b/.trellis/tasks/09-28-design-ui-ux/design.md new file mode 100644 index 000000000..441e7bf99 --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/design.md @@ -0,0 +1,83 @@ +# 設計:UI/UX 設計系統、響應式與桌面播放頁 + +## 1. 主題與 token(U1) + +- 色彩:沿用 `ColorScheme.fromSeed`(預設紫色 seed+preset)、淺色/深色/跟隨系統;不做 dynamic color(新功能)。 +- `AppTokens`(`ThemeExtension`,放在 `lib/ui/theme/`): + - 間距:`s4`、`s8`、`s12`、`s16`、`s20`、`s24`、`s32`、`s40`、`s48`,沿用現有 4 的倍數慣例; + - 圓角:`xs 4`、`sm 8`、`md 12`、`lg 16`、`xl 28`(M3 shape scale); + - 語意色:成功、警告,其餘用 `ColorScheme` 角色; + - 焦點框:2dp、`primary`、外擴 2dp。 +- 字級只用 M3 `textTheme` 角色(`titleLarge`、`bodyMedium`…),不寫 `fontSize:`;元件的固定尺寸(封面上限、面板寬度)放 `AppLayout` 常數,同樣在 theme 目錄。 +- 新 lint `fmp_design_tokens`(加入 ADR 0015 的 `fmp_lints`):`lib/ui/`(theme 目錄除外)不得在 `EdgeInsets.*`、`SizedBox` 的寬高、`BorderRadius.circular`、`fontSize:` 使用數字字面值, + 也不得寫 `Color(0x…)`、`Colors.*`;允許 `0`。依 ADR 0015 寫雙向變異測試。 +- Material 正拆出為 `material_ui` 套件:建立 `app/` 時依當時 stable 的官方建議決定 import 路徑,不提前遷移。 + +## 2. 字型(i18n 決定的一部分) + +- 不指定主字型時用各平台預設(Windows 為 Segoe UI),`fontFamilyFallback` 依目前語言排序: + - 繁中:Windows `Microsoft JhengHei UI`、`Microsoft JhengHei`,其他平台 `Noto Sans TC`; + - 簡中:Windows `Microsoft YaHei UI`、`Microsoft YaHei`,其他平台 `Noto Sans SC`; + - 英文:繁中清單在前,確保混排的中文字形正確。 +- 清單由平台層提供(ADR 0009);Linux 是否內建 Noto CJK 由 Linux 平台任務決定。 + +## 3. 斷點與導覽(U7、U8) + +- 自有 `WindowClass`:compact < 600、medium 600–839、expanded 840–1199、large 1200–1599、extraLarge ≥ 1600(與 M3 同值)。不用已停止維護的 `flutter_adaptive_scaffold`。 + +| 寬度 | 導覽 | 右側「正在播放」面板 | 播放列 | 播放頁 | +|---|---|---|---|---| +| compact | 底部導覽列 | 無 | 手機迷你播放列 | 手機版 | +| medium | NavigationRail | 無 | 桌面播放列(中) | 手機版 | +| expanded | NavigationRail | 常駐、可收起、可拖寬(U7) | 桌面播放列(寬) | 方案 B 兩欄 | +| large | 常駐導覽抽屜(圖示+文字) | 同上 | 同上 | 方案 B 兩欄 | +| extraLarge | 常駐導覽抽屜 | 同上,預設寬度較大 | 同上 | 方案 B 三欄 | + +- 播放列的寬度分段依「內容區寬度」而不是視窗寬度:≥ 840、600–839、< 600(已決定 4)。compact 的桌面視窗也用 < 600 的樣子。 + +## 4. 播放頁(已決定 1) + +- 桌面(≥ 840):左右各半。左邊是封面(上限 420dp)、曲名、歌手、進度、五個播放控制;右欄分頁「歌詞|佇列|詳細」,記住上次的分頁(per-device 設定)。 +- extraLarge:三欄,比例約 1:1.15:0.9,封面與控制|歌詞|分頁「佇列|詳細」。 +- 手機與 medium:現行 narrow 版面(封面與歌詞切換),佇列以底部面板開啟,詳細在「⋯」。 +- 背景:模糊封面+表面色遮罩(沿用)。頂列:收起、加入歌單、輸出裝置(桌面)、音量(桌面)、⋯。 +- 「詳細」分頁與右側面板共用同一個內容 widget。 + +## 5. 其他版面問題 + +- 搜尋頁(U5):來源篩選 chip 列可橫向捲動,兩端有漸層提示;排序按鈕在捲動區之外。 +- 設定頁:依 ADR 0011 的分組;expanded 以上用 list-detail(左分組、右內容),compact 為單欄。 +- 數字與複數(U6):`intl` 的 `NumberFormat.compact`(依 locale:`4600萬`、`46M`),英文複數用 slang 的複數語法。 + +## 6. i18n(已決定 2) + +- slang,`base_locale: zh-TW`,三語言;測試要求三語言 key 集合完全相同(缺一條即紅)。 +- 桌面歌詞子視窗、Android 懸浮窗的字串經型別化訊息傳入(ADR 0021),不再自帶簡體預設值。 + +## 7. 無障礙與鍵盤(U2、U3,已決定 3) + +- 所有只有圖示的按鈕都有 tooltip 與語意標籤;大播放鍵、播放列控制都有名稱;播放列點擊區與按鈕分開,不再是按鈕包按鈕。 +- `Shortcuts`/`Actions` 掛在 App 根部,`Intent` 對到 `PlaybackController` 與路由;輸入框有焦點時不觸發(以 widget test 驗證空白鍵在搜尋框內只輸入空格)。 +- `FocusTraversalGroup` 分三區(導覽、內容、播放列),F6 依序切換;焦點框用 `AppTokens` 的樣式,兩種主題都清楚。 +- 設定頁「鍵盤快捷鍵」列出 App 內與全域兩組;錄製全域快捷鍵時若與 App 內相同就提示。 + +## 8. 使用者指南(已決定 5) + +- 刪除 `user_guide_page` 與 `userGuide` 字串。新增 `docs/user-guide.md`(繁中),隨 `app/` 功能完成時撰寫。 +- 「設定 → 關於」:版本、使用說明、CHANGELOG、回報問題(ADR 0023 的 GitHub 流程)、原始碼、授權;網址放在 `fmp_url_literal` 允許的端點檔。 + +## 9. 閘門 + +- lint `fmp_design_tokens`(§1)。 +- widget 測試: + - 主要頁面(首頁、搜尋、歌單、播放頁、設定)在淺色與深色主題下通過 `meetsGuideline(labeledTapTargetGuideline)` 與 `textContrastGuideline`; + - 快捷鍵與焦點(空白鍵、Esc、F6、輸入框內不觸發); + - 播放列三段寬度的控制項集合;曲名寬度不小於 160dp。 +- golden(`alchemist`,CI 用色塊字型避開平台差異):播放頁 B 在 1000、1400、1800 寬;播放列三段寬度。只守版面結構,數量保持少。 +- i18n:三語言 key 集合相同。 + +## 10. 相關 ADR 的指向 + +- 0011:設定頁 list-detail 版面、「鍵盤快捷鍵」與「關於」頁見 0024。 +- 0015:後續 ADR 新增的規則加 `fmp_design_tokens`。 +- 0021:播放頁歌詞所在位置(右欄分頁或 extraLarge 的中欄)見 0024。 diff --git a/.trellis/tasks/09-28-design-ui-ux/implement.md b/.trellis/tasks/09-28-design-ui-ux/implement.md new file mode 100644 index 000000000..89c9cab95 --- /dev/null +++ b/.trellis/tasks/09-28-design-ui-ux/implement.md @@ -0,0 +1,12 @@ +# 執行計畫:第 5 項(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0024-ui-ux-design-system.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9,附示意頁連結(私人,擁有者可見);被否決的方案: + 播放頁 A 左右分割、C 沉浸式歌詞;只留繁中與英文、簡中自動轉換;App 內只做畫面操作、App 內快捷鍵可自訂;中寬度保留五個播放控制; + 保留 App 內使用者指南;`flutter_adaptive_scaffold`(已停止維護);dynamic color(新功能)。 +2. [ ] 其他 ADR 各加一句指向 ADR 0024:0011(設定頁版面、快捷鍵與關於頁)、0015(`fmp_design_tokens`)、0021(播放頁歌詞位置)。 +3. [ ] `phase2-plan.md`:§3 第 5 項標 ✅(ADR 0024);§7 第一個里程碑加入「空白鍵在輸入框內只輸入空格、F6 焦點切換、Windows 繁中字形由正黑體顯示」; + §10 交接段更新,下一項 4 Debug 頁,下一份 ADR 0025。 +4. [ ] 驗證:`git grep` 確認 ADR 間引用。 +5. [ ] `task.py finish`、`task.py archive design-ui-ux --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index e6ba5800e..70e62a014 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -67,9 +67,12 @@ ≥ 840:隨機、上一首、播放、下一首、循環、輸出裝置、音量滑桿;600–839:上一首、播放、下一首、音量圖示(點開滑桿)、「⋯」(隨機、循環、輸出裝置); < 600:播放、下一首。點播放列空白處開播放頁,修正按鈕包按鈕(U3)。否決:中寬度保留五個播放控制(曲名只剩 6–7 字)。 -## 待決定 - -1. 使用者指南(E20)去留。 +5. **刪除 App 內使用者指南(2026-09-28,按建議,E20)**:改為 repo 的 `docs/user-guide.md`(繁中,隨新功能重寫); + 「設定 → 關於」連到使用說明、CHANGELOG、回報問題、原始碼;容易卡住的地方在畫面上就地說明(首次引導、權限說明、快捷鍵清單)。 + 否決:保留 App 內指南(三語言、易過時)。 +6. **技術選擇(`design.md`)**:`ThemeExtension` 的間距、圓角、語意色 token 與 lint `fmp_design_tokens`;字級只用 M3 `textTheme` 角色; + 自有 `WindowClass`(不用已停止維護的 `flutter_adaptive_scaffold`);large 以上改用常駐導覽抽屜;搜尋篩選列可捲動並有漸層提示(U5); + 無障礙以 `meetsGuideline`(點擊目標標籤、對比度)測主要頁面兩種主題;少量 `alchemist` golden 守版面;`material_ui` 的遷移時機在建立 `app/` 時依官方建議定。 ## 不在範圍 @@ -78,6 +81,6 @@ ## 驗收條件 -- [ ] ADR 0024 記錄:token 與主題、字型 fallback、斷點與導覽、右側面板、桌面與手機播放頁、迷你播放器、i18n 與數字格式、無障礙、鍵盤與焦點、使用者指南、閘門(lint、對比度、golden)。 +- [ ] ADR 0024 記錄:token 與主題、字型 fallback、斷點與導覽、右側面板、桌面與手機播放頁、播放列、搜尋篩選列、i18n 與數字格式、無障礙、鍵盤與焦點、使用者指南、閘門(lint、guideline 測試、golden)。 - [ ] U1–U8、E20 各自對到決定。 -- [ ] `phase2-plan.md` §3 第 5 項標 ✅ 與 ADR 編號。 +- [ ] ADR 0011、0015、0021 加上指向 ADR 0024 的一句話;`phase2-plan.md` §3 第 5 項標 ✅,§7 加入實測項目。 From 618e05f9f0f8d60cdbbd5cac4402734032879d08 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:28:36 +0800 Subject: [PATCH 097/133] chore(task): record design style decision --- .trellis/tasks/09-28-design-ui-ux/design.md | 8 ++++++++ .trellis/tasks/09-28-design-ui-ux/implement.md | 3 ++- .trellis/tasks/09-28-design-ui-ux/prd.md | 8 +++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-28-design-ui-ux/design.md b/.trellis/tasks/09-28-design-ui-ux/design.md index 441e7bf99..77591b271 100644 --- a/.trellis/tasks/09-28-design-ui-ux/design.md +++ b/.trellis/tasks/09-28-design-ui-ux/design.md @@ -13,6 +13,14 @@ 也不得寫 `Color(0x…)`、`Colors.*`;允許 `0`。依 ADR 0015 寫雙向變異測試。 - Material 正拆出為 `material_ui` 套件:建立 `app/` 時依當時 stable 的官方建議決定 import 路徑,不提前遷移。 +## 1a. 設計風格(已決定 6) + +- 全 App 為 Material 3 元件加 §1 的 token。 +- 播放頁:背景沿用模糊封面+表面色遮罩;右欄分頁、佇列清單、控制區用半透明表面色(約 60–72% 不透明)加一般 `BackdropFilter` 模糊,不做折射。 + 背景靜態,所以模糊成本只在換歌與視窗大小改變時。 +- 系統開啟「減少透明度」或高對比(`MediaQuery.highContrast`,各平台對應設定由平台層提供)時改為不透明表面色。 +- 播放頁的對比度同樣要通過 §9 的 `textContrastGuideline`(以最淺與最深的測試封面各測一次)。 + ## 2. 字型(i18n 決定的一部分) - 不指定主字型時用各平台預設(Windows 為 Segoe UI),`fontFamilyFallback` 依目前語言排序: diff --git a/.trellis/tasks/09-28-design-ui-ux/implement.md b/.trellis/tasks/09-28-design-ui-ux/implement.md index 89c9cab95..89a735616 100644 --- a/.trellis/tasks/09-28-design-ui-ux/implement.md +++ b/.trellis/tasks/09-28-design-ui-ux/implement.md @@ -2,7 +2,8 @@ 1. [ ] 核准後寫 `docs/adr/0024-ui-ux-design-system.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9,附示意頁連結(私人,擁有者可見);被否決的方案: 播放頁 A 左右分割、C 沉浸式歌詞;只留繁中與英文、簡中自動轉換;App 內只做畫面操作、App 內快捷鍵可自訂;中寬度保留五個播放控制; - 保留 App 內使用者指南;`flutter_adaptive_scaffold`(已停止維護);dynamic color(新功能)。 + 保留 App 內使用者指南;`flutter_adaptive_scaffold`(已停止維護);dynamic color(新功能); + 全 App 毛玻璃、整套液態玻璃、各平台原生風格。 2. [ ] 其他 ADR 各加一句指向 ADR 0024:0011(設定頁版面、快捷鍵與關於頁)、0015(`fmp_design_tokens`)、0021(播放頁歌詞位置)。 3. [ ] `phase2-plan.md`:§3 第 5 項標 ✅(ADR 0024);§7 第一個里程碑加入「空白鍵在輸入框內只輸入空格、F6 焦點切換、Windows 繁中字形由正黑體顯示」; §10 交接段更新,下一項 4 Debug 頁,下一份 ADR 0025。 diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/09-28-design-ui-ux/prd.md index 70e62a014..d2fe0a940 100644 --- a/.trellis/tasks/09-28-design-ui-ux/prd.md +++ b/.trellis/tasks/09-28-design-ui-ux/prd.md @@ -70,7 +70,13 @@ 5. **刪除 App 內使用者指南(2026-09-28,按建議,E20)**:改為 repo 的 `docs/user-guide.md`(繁中,隨新功能重寫); 「設定 → 關於」連到使用說明、CHANGELOG、回報問題、原始碼;容易卡住的地方在畫面上就地說明(首次引導、權限說明、快捷鍵清單)。 否決:保留 App 內指南(三語言、易過時)。 -6. **技術選擇(`design.md`)**:`ThemeExtension` 的間距、圓角、語意色 token 與 lint `fmp_design_tokens`;字級只用 M3 `textTheme` 角色; +6. **設計風格:Material 3,播放頁局部毛玻璃(2026-09-28,按建議)**:全 App 用 Material 3 元件與本 ADR 的 token; + 播放頁在既有模糊封面背景上,把右欄分頁、佇列、控制區做成半透明霧面(一般模糊、無折射);系統「減少透明度」或高對比時改不透明。 + 擁有者問液態玻璃能否做到:Flutter 官方 2025-06-11 表示不在 Cupertino 開發 Apple '26 設計(#170310);社群套件 `liquid_glass_renderer` 實驗性且只支援 Impeller、 + 不支援 Windows/Linux/Web;`liquid_glass_easy` 真折射只在 Impeller、Skia 退化為毛玻璃、每片玻璃都要讀背景重算;`cupertino_native` 只限 Apple 平台。 + 否決:全 App 局部毛玻璃(捲動內容下每幀重算模糊、對比度難守)、整套液態玻璃(實驗性套件、Android/Windows 效果與效能無保證、需自做元件與無障礙)、 + 各平台原生風格(三套 UI)。 +7. **技術選擇(`design.md`)**:`ThemeExtension` 的間距、圓角、語意色 token 與 lint `fmp_design_tokens`;字級只用 M3 `textTheme` 角色; 自有 `WindowClass`(不用已停止維護的 `flutter_adaptive_scaffold`);large 以上改用常駐導覽抽屜;搜尋篩選列可捲動並有漸層提示(U5); 無障礙以 `meetsGuideline`(點擊目標標籤、對比度)測主要頁面兩種主題;少量 `alchemist` golden 守版面;`material_ui` 的遷移時機在建立 `app/` 時依官方建議定。 From e2359746695de1e6dd6caf6d8e0bc3a5aed6a0e4 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:31:55 +0800 Subject: [PATCH 098/133] docs(adr): 0024 ui and ux design system --- docs/adr/0011-settings-and-logging.md | 2 +- .../0015-testing-gates-and-dev-environment.md | 2 +- docs/adr/0021-lyrics.md | 2 +- docs/adr/0024-ui-ux-design-system.md | 159 ++++++++++++++++++ 4 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 docs/adr/0024-ui-ux-design-system.md diff --git a/docs/adr/0011-settings-and-logging.md b/docs/adr/0011-settings-and-logging.md index 0e95bd32f..205b7a9cd 100644 --- a/docs/adr/0011-settings-and-logging.md +++ b/docs/adr/0011-settings-and-logging.md @@ -43,7 +43,7 @@ cookie、token、簽名 URL、API key 一律遮蔽;錯誤進入可檢索的歷 非敏感設定摘要、已遮蔽的 log 與錯誤歷史;不含硬體識別資訊、帳號名稱、歌單內容。產生時組裝一次,匯出只用這份結果。 7. **設定**:依功能分組(播放、外觀、音樂庫與同步、下載、歌詞、網路、桌面、開發者),每組一張單列表、每個設定一個有型別的欄位, 每組一個 Riverpod Notifier 監看自己那一列、只寫改動的欄位。**欄位為空=使用者沒設定過**,讀取時套用程式預設; - 改預設值不需 migration,也不會動到使用者設定過的值。每個音源的設定另一張表,以音源 id 為主鍵。設定包含在備份中。 + 改預設值不需 migration,也不會動到使用者設定過的值。每個音源的設定另一張表,以音源 id 為主鍵。設定包含在備份中。設定頁版面、「鍵盤快捷鍵」與「關於」頁見 ADR 0024。 採用的慣例:talker 作資料核心;Finamp `censored_log.dart` 的已知值替換;NewPipe 錯誤報告的欄位結構; Spotube 以 drift 存設定並以 `watchSingle()` 接 Riverpod。 diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index 105b5538d..569263969 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -48,7 +48,7 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 | `fmp_ignore_reason` | `// ignore: fmp_…` 同行必須寫理由 | | `fmp_platform_checks` | `Platform.isXxx`、`defaultTargetPlatform`、`Platform.operatingSystem` 只在平台層 | - 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)、`fmp_toast_entry`(ADR 0023)。 + 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)、`fmp_toast_entry`(ADR 0023)、`fmp_design_tokens`(ADR 0024)。 每條規則以官方 `analyzer_testing` 做雙向變異測試。`flutter analyze` 目前不顯示插件診斷並回報 No issues (flutter/flutter#193203),所以 CI 跑 `dart analyze --fatal-infos`,並以接線哨兵(暫放違規檔、斷言分析失敗且含規則名)證明規則接上了 `app/`。 diff --git a/docs/adr/0021-lyrics.md b/docs/adr/0021-lyrics.md index 70635f286..261afcd57 100644 --- a/docs/adr/0021-lyrics.md +++ b/docs/adr/0021-lyrics.md @@ -85,7 +85,7 @@ - 播放狀態、位置、速度、時間戳只在播放、暫停、seek、換歌、換速時推送,各顯示端以 frame callback 外推,不開週期計時器。 - 子 engine 與主 engine 以一個共用 Dart 檔定義的型別化訊息溝通(JSON 序列化);子視窗與懸浮窗不顯示提示,錯誤轉給主視窗(ADR 0023)。 - 播放頁、桌面視窗、Android 懸浮共用一套歌詞 widget;逐字漸變用 `CustomPainter`+分段 shader+`saveLayer(dstIn)` 遮罩。 - - 顯示模式沿用(原文/優先翻譯/優先羅馬音),另加「逐字高亮」(預設開)。 + - 顯示模式沿用(原文/優先翻譯/優先羅馬音),另加「逐字高亮」(預設開)。播放頁上歌詞的位置(右欄分頁或超寬時的中欄)見 ADR 0024。 8. **桌面歌詞視窗**(E11): - 平台能力 `desktopLyrics`,細分 `clickThrough`、`alwaysOnTop`(ADR 0009);入口只在宣告時出現。 - 以 `desktop_multi_window`(每視窗一個 engine)實作;透明、置頂、單行、11 項樣式、hover 工具列、點行跳轉、右鍵校正沿用;關閉是隱藏不銷毀。 diff --git a/docs/adr/0024-ui-ux-design-system.md b/docs/adr/0024-ui-ux-design-system.md new file mode 100644 index 000000000..8e87d71e5 --- /dev/null +++ b/docs/adr/0024-ui-ux-design-system.md @@ -0,0 +1,159 @@ +# 0024 — UI/UX:Material 3 加 token、五段寬度版面、右欄分頁的桌面播放頁、繁中為主的 i18n、App 內快捷鍵 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/lib/ui/` 的主題與 token、字型 fallback、斷點與導覽殼、播放頁、播放列、搜尋頁篩選列、設定頁版面、i18n、無障礙、鍵盤與焦點、使用者指南、`fmp_lints` + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/current-state.md`、`docs/audit/ui.md`,已以程式碼核對): + +- 主題為 `ColorScheme.fromSeed`,沒有間距、字級 token:`EdgeInsets` 約 250 處、`SizedBox` 約 500 處字面數字,29 處 `fontSize:`(U1)。 +- 字型 fallback 只有簡體字形(Windows `Microsoft YaHei`、其他 `Noto Sans SC`),i18n 的 base locale 是 zh-CN;擁有者主要用繁中。 +- `large`、`extraLarge` 沒有版面(U8);右側「正在播放」面板在寬度 ≥ 840 常駐(U7)。 +- 播放頁寬版是左封面+右歌詞(5:7),沒有佇列;播放列固定 7 個控制,窄視窗時曲名只剩 2 字(U4)。 +- App 內沒有快捷鍵、Esc 離不開播放頁、焦點看不見(U2);大播放鍵沒有名稱、播放列是按鈕包按鈕(U3);搜尋篩選列被蓋住(U5);「4600.0萬」「1 tracks」(U6)。 +- 使用者指南是 7 段、每語言約 40 條的 App 內頁(E20)。 + +擁有者:U1–U8 全部重寫時處理,U7 面板保留常駐、U8 實作大斷點;parent prd 第 5 項要求桌面播放頁提供 2–3 個方案選擇。 +2026-09-28 選定: +- 播放頁方案 B(示意頁 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ ,僅擁有者可見); +- 三語言、base 改 zh-TW; +- App 內快捷鍵的清單; +- 播放列三段; +- 刪除 App 內指南; +- Material 3 加播放頁局部毛玻璃。 + +## 考慮過的選項 + +- **播放頁 A 左右分割**:否決,看佇列會蓋住歌詞,超寬空間用不上。 +- **播放頁 C 沉浸式歌詞**:否決。B 站、YouTube 曲目常沒有歌詞,畫面會空;佇列要另外叫出。 +- **只留繁中與英文**:否決,簡中使用者只能看英文。 +- **簡中由 OpenCC 自動轉換**:否決,用詞不道地,要另外維護修正清單。 +- **App 內只做畫面操作的快捷鍵、播放靠全域**:否決,在 App 內按空白鍵不能暫停。 + 擁有者問過「只有全域不行嗎」:全域快捷鍵會攔走所有 App 的按鍵,只能用罕用組合;Esc、搜尋、焦點移動只在 App 內有意義(U2)。 +- **App 內快捷鍵可自訂**:否決,要做衝突檢查與錄製介面。 +- **中寬度播放列保留五個播放控制**:否決,曲名只剩 6–7 字。 +- **保留 App 內使用者指南**:否決,三語言各一份、容易過時。 +- **整套液態玻璃**:否決。 + - Flutter 官方 2025-06-11 表示不在 Cupertino 開發 Apple '26 設計(#170310); + - `liquid_glass_renderer` 實驗性,只支援 Impeller,不支援 Windows、Linux、Web; + - `liquid_glass_easy` 真折射只在 Impeller,Skia 上退化為毛玻璃,每片玻璃都要讀背景重算; + - 在 Android、Windows 上風格不合,也要自己做元件與無障礙。 +- **全 App 毛玻璃**:否決。內容在其下捲動時每幀重算模糊,對比度也難守。 +- **各平台原生風格(Fluent、Material、Cupertino)**:否決,要做三套 UI。 +- **`flutter_adaptive_scaffold`**:否決,已停止維護,官方沒有替代。 +- **dynamic color(Material You 取色)**:不做,舊版沒有,屬新功能。 + +## 決定 + +1. **風格與 token**: + - Material 3 元件;沿用 seed 色、preset、淺色/深色/跟隨系統。 + - `AppTokens`(`ThemeExtension`): + - 間距 4、8、12、16、20、24、32、40、48; + - 圓角 4、8、12、16、28(M3 shape scale); + - 語意色:成功、警告; + - 焦點框:2dp `primary`、外擴 2dp。 + - 字級只用 M3 `textTheme` 角色;元件固定尺寸(封面上限、面板寬度)放 theme 目錄的 `AppLayout`。 + - 播放頁在模糊封面背景上,以半透明表面色(約 60–72%)+一般模糊做右欄、佇列、控制區,不做折射;系統「減少透明度」或高對比時改為不透明。 + - `material_ui` 的 import 路徑在建立 `app/` 時依當時 stable 的官方建議決定。 +2. **字型**:`fontFamilyFallback` 依目前語言排序,由平台層提供(ADR 0009);Linux 是否內建 Noto CJK 由 Linux 平台任務決定。 + - 繁中:Windows `Microsoft JhengHei UI`、`Microsoft JhengHei`,其他平台 `Noto Sans TC`; + - 簡中:Windows `Microsoft YaHei UI`、`Microsoft YaHei`,其他平台 `Noto Sans SC`; + - 英文:繁中清單在前。 +3. **斷點與導覽**:自有 `WindowClass`,與 M3 同值。 + + | 寬度 | 導覽 | 右側「正在播放」面板 | 播放頁 | + |---|---|---|---| + | compact(< 600) | 底部導覽列 | 無 | 手機版 | + | medium(600–839) | NavigationRail | 無 | 手機版 | + | expanded(840–1199) | NavigationRail | 常駐、可收起、可拖寬(U7) | B 兩欄 | + | large(1200–1599) | 常駐導覽抽屜(圖示+文字) | 同上 | B 兩欄 | + | extraLarge(≥ 1600) | 常駐導覽抽屜 | 同上,預設較寬 | B 三欄(U8) | + +4. **播放頁(方案 B)**: + - ≥ 840:左右各半。 + - 左:封面(上限 420dp)、曲名、歌手、進度、五個播放控制; + - 右欄:分頁「歌詞|佇列|詳細」,依裝置記住上次的分頁。「詳細」與右側面板共用同一個內容 widget。 + - extraLarge:三欄(約 1:1.15:0.9),依序為封面與控制|歌詞|分頁「佇列|詳細」。 + - 手機與 medium:封面與歌詞切換,佇列以底部面板開啟。 + - 共通:Esc 關閉;背景為模糊封面+遮罩。 +5. **播放列**(依內容區寬度,曲名至少約 160dp): + - ≥ 840:隨機、上一首、播放、下一首、循環、輸出裝置、音量滑桿; + - 600–839:上一首、播放、下一首、音量圖示(點開滑桿)、「⋯」(隨機、循環、輸出裝置); + - < 600:播放、下一首。 + + 點空白處開播放頁,點擊區與按鈕分開(U3、U4)。 +6. **其他版面**: + - 搜尋頁的來源 chip 列可橫向捲動、兩端有漸層提示,排序按鈕在捲動區外(U5); + - 設定頁依 ADR 0011 的分組,expanded 以上用 list-detail(左分組、右內容); + - 數字用 `intl` 的 `NumberFormat.compact`(`4600萬`、`46M`),英文複數用 slang 的複數語法(U6)。 +7. **i18n**: + - slang,`base_locale: zh-TW`,三語言(zh-TW、zh-CN、en);新字串先寫繁中,缺字退回繁中。 + - 子視窗與懸浮窗的字串經型別化訊息傳入(ADR 0021)。 +8. **無障礙與鍵盤**(U2、U3): + - 只有圖示的按鈕都有 tooltip 與語意標籤。 + - App 內快捷鍵固定、不可自訂,只在 FMP 為前景且焦點不在輸入框時有效: + + | 按鍵 | 動作 | + |---|---| + | 空白鍵 | 播放暫停 | + | Ctrl+←/→ | 上一首/下一首 | + | Shift+←/→ | 倒轉/快轉 5 秒 | + | Ctrl+↑/↓ | 音量 | + | Ctrl+S | 隨機 | + | Ctrl+R | 循環 | + | Ctrl+F | 搜尋 | + | Ctrl+L/Ctrl+Q | 播放頁右欄切到歌詞/佇列 | + | Esc | 關閉播放頁與對話框 | + | F6 | 在導覽/內容/播放列三區之間移動焦點 | + | Ctrl+, | 設定 | + + - 提示文字附按鍵;設定頁「鍵盤快捷鍵」列出 App 內與全域兩組。 + - 全域快捷鍵照舊:可自訂、預設關、預設 Ctrl+Alt+…。同一組按鍵時全域優先;錄製全域快捷鍵時若與 App 內相同就提示。 + - `FocusTraversalGroup` 分三區,Tab 只在區內移動。 +9. **使用者指南**(E20): + - 刪除 App 內指南頁與其字串,改為 repo 的 `docs/user-guide.md`(繁中,隨 `app/` 功能撰寫)。 + - 「設定 → 關於」列版本、使用說明、CHANGELOG、回報問題(ADR 0023)、原始碼、授權;網址放在 `fmp_url_literal` 允許的端點檔。 + - 容易卡住處就地說明:首次引導、權限說明、快捷鍵清單。 + +採用的慣例: +- Material 3 的 window size class、導覽元件切換、canonical layouts; +- Namida 寬版播放頁的右欄分頁與記住選擇; +- Feishin 的左右分割全螢幕播放器; +- Spotify、Apple Music 官方快捷鍵表; +- Spotube、Namida、Finamp 的「關於頁連到 GitHub 文件」; +- CLDR 的數字縮寫(`intl`)。 + +## 後果 + +- 好的: + - 間距、字級、顏色有一致來源並由 lint 守住; + - 繁中字形正確; + - 大螢幕空間用上; + - 看佇列不必離開播放畫面; + - 窄視窗曲名可讀; + - 鍵盤可完整操作; + - 說明文件跟著程式碼更新。 +- 壞的: + - 多一種三欄播放頁; + - 每改一條字串仍要動三個檔; + - App 內快捷鍵不能自訂; + - 看說明要連網; + - 播放頁毛玻璃要守對比度。 +- 之後要注意: + - Material 拆成 `material_ui` 的遷移時程; + - Flutter 若提供官方 window size class 或液態玻璃支援時再評估; + - Linux 的 CJK 字型內建由平台任務決定。 + +## 如何確認 + +- lint `fmp_design_tokens`(加入 ADR 0015 的 `fmp_lints`):`lib/ui/`(theme 目錄除外)不得在 `EdgeInsets.*`、`SizedBox` 寬高、`BorderRadius.circular`、`fontSize:` 使用數字字面值(`0` 除外), + 也不得寫 `Color(0x…)`、`Colors.*`;依 ADR 0015 寫雙向變異測試。 +- widget 測試: + - 首頁、搜尋、歌單、播放頁、設定在淺色與深色主題下通過 `meetsGuideline(labeledTapTargetGuideline)` 與 `textContrastGuideline`;播放頁以最淺與最深的測試封面各測一次。 + - 快捷鍵與焦點:空白鍵、Esc、F6,以及輸入框內空白鍵只輸入空格。 + - 播放列三段寬度的控制項集合,曲名寬度不小於 160dp。 +- golden(`alchemist`,色塊字型):播放頁 B 在 1000、1400、1800 寬,播放列三段寬度;只守版面結構,數量保持少。 +- i18n:三語言 key 集合相同(缺一條即紅)。 +- 第一個里程碑實測:輸入框內空白鍵不觸發播放;F6 焦點切換;Windows 繁中字形由正黑體顯示。 From 91e07fbdbef116cc54b60b2ccf12f3b1d7f36e4c Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:31:57 +0800 Subject: [PATCH 099/133] chore(task): archive design-ui-ux --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 16 +++++++++------- .../2026-09}/09-28-design-ui-ux/check.jsonl | 0 .../2026-09}/09-28-design-ui-ux/design.md | 0 .../2026-09}/09-28-design-ui-ux/implement.jsonl | 0 .../2026-09}/09-28-design-ui-ux/implement.md | 10 +++++----- .../2026-09}/09-28-design-ui-ux/prd.md | 0 .../09-28-design-ui-ux/research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../09-28-design-ui-ux/research/prior-art.md | 0 .../2026-09}/09-28-design-ui-ux/task.json | 6 +++--- 10 files changed, 17 insertions(+), 15 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/implement.md (77%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-ui-ux/task.json (87%) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 90385fbcc..0b4a74da8 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -127,7 +127,7 @@ flowchart LR | 15 | 15 歌詞(✅ 完成,ADR 0021) | 依賴 1、13。 | | 16 | 19 發版與更新(✅ 完成,ADR 0022) | 依賴 10、16;你已給出流程要求。 | | 17 | 3 Toast(✅ 完成,ADR 0023) | 依賴 2、18。 | -| 18 | 5 UI/UX | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | +| 18 | 5 UI/UX(✅ 完成,ADR 0024) | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | | 19 | 4 Debug 頁 | 把 18、3、8 的成果收成正式工具。 | | 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | @@ -227,6 +227,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0015:`fmp_lints` 接上 `app/`,`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)。 - ADR 0022:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(測試 repo 或 dry-run)。 - ADR 0023:提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹。 +- ADR 0024:輸入框內空白鍵只輸入空格;F6 焦點切換;Windows 繁中字形由正黑體顯示。 ## 8. 延後到特定里程碑的實測 @@ -244,13 +245,14 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 3 項完成後) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 5 項完成後) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0023`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0024(UI/UX)。 -- **下一項:第 5 項「UI/UX」**(尚未建 task):設計系統 token、響應式規則、i18n、無障礙與鍵盤操作;桌面播放器頁給 2–3 個版面方案讓使用者選。 -- 之後順序:4 Debug 頁(含插件開發工具、音源健康檢查、錯誤歷史用 ADR 0023 的詳細頁)→ 7 里程碑定稿。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0024`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0025(Debug 頁)。 +- **下一項:第 4 項「Debug 頁」**(尚未建 task):含 log 檢視與錯誤歷史(ADR 0011、0023 的詳細頁)、網路請求檢視、播放與佇列即時狀態、資料庫檢視、音源健康檢查(ADR 0015)、插件開發工具(ADR 0015)、快取管理(ADR 0016)、診斷包匯出(ADR 0011);版面用 ADR 0024 的設計系統。 +- 之後順序:7 里程碑定稿。 +- 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 - 工作守則(本輪累積): diff --git a/.trellis/tasks/09-28-design-ui-ux/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/check.jsonl diff --git a/.trellis/tasks/09-28-design-ui-ux/design.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/design.md similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/design.md diff --git a/.trellis/tasks/09-28-design-ui-ux/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/implement.jsonl diff --git a/.trellis/tasks/09-28-design-ui-ux/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/implement.md similarity index 77% rename from .trellis/tasks/09-28-design-ui-ux/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/implement.md index 89a735616..89b5834cb 100644 --- a/.trellis/tasks/09-28-design-ui-ux/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/implement.md @@ -1,13 +1,13 @@ # 執行計畫:第 5 項(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0024-ui-ux-design-system.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9,附示意頁連結(私人,擁有者可見);被否決的方案: +1. [x] 核准後寫 `docs/adr/0024-ui-ux-design-system.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§9,附示意頁連結(私人,擁有者可見);被否決的方案: 播放頁 A 左右分割、C 沉浸式歌詞;只留繁中與英文、簡中自動轉換;App 內只做畫面操作、App 內快捷鍵可自訂;中寬度保留五個播放控制; 保留 App 內使用者指南;`flutter_adaptive_scaffold`(已停止維護);dynamic color(新功能); 全 App 毛玻璃、整套液態玻璃、各平台原生風格。 -2. [ ] 其他 ADR 各加一句指向 ADR 0024:0011(設定頁版面、快捷鍵與關於頁)、0015(`fmp_design_tokens`)、0021(播放頁歌詞位置)。 -3. [ ] `phase2-plan.md`:§3 第 5 項標 ✅(ADR 0024);§7 第一個里程碑加入「空白鍵在輸入框內只輸入空格、F6 焦點切換、Windows 繁中字形由正黑體顯示」; +2. [x] 其他 ADR 各加一句指向 ADR 0024:0011(設定頁版面、快捷鍵與關於頁)、0015(`fmp_design_tokens`)、0021(播放頁歌詞位置)。 +3. [x] `phase2-plan.md`:§3 第 5 項標 ✅(ADR 0024);§7 第一個里程碑加入「空白鍵在輸入框內只輸入空格、F6 焦點切換、Windows 繁中字形由正黑體顯示」; §10 交接段更新,下一項 4 Debug 頁,下一份 ADR 0025。 -4. [ ] 驗證:`git grep` 確認 ADR 間引用。 -5. [ ] `task.py finish`、`task.py archive design-ui-ux --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 +4. [x] 驗證:`git grep` 確認 ADR 間引用。 +5. [x] `task.py finish`、`task.py archive design-ui-ux --no-commit --skip-branch-validation`;分開提交 ADR 與歸檔,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-ui-ux/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/prd.md diff --git a/.trellis/tasks/09-28-design-ui-ux/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/current-state.md diff --git a/.trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-ui-ux/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-ui-ux/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-ui-ux/task.json b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/task.json similarity index 87% rename from .trellis/tasks/09-28-design-ui-ux/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-ui-ux/task.json index 4d152eb19..a46d1dc9f 100644 --- a/.trellis/tasks/09-28-design-ui-ux/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-ui-ux/task.json @@ -3,7 +3,7 @@ "name": "design-ui-ux", "title": "Design UI/UX system", "description": "Phase-2 item 5: design tokens, responsive layouts, i18n, accessibility and keyboard, desktop player page layout options, user guide", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From ead20f19909ea4eeb6033cfec396d5dd785edace Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:32:43 +0800 Subject: [PATCH 100/133] chore(task): start design-debug-page --- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../tasks/09-28-design-debug-page/check.jsonl | 0 .../09-28-design-debug-page/implement.jsonl | 0 .trellis/tasks/09-28-design-debug-page/prd.md | 19 ++++++++++++++ .../tasks/09-28-design-debug-page/task.json | 26 +++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 .trellis/tasks/09-28-design-debug-page/check.jsonl create mode 100644 .trellis/tasks/09-28-design-debug-page/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-debug-page/prd.md create mode 100644 .trellis/tasks/09-28-design-debug-page/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 0480486b2..1bde6a478 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -37,7 +37,8 @@ "09-28-design-lyrics", "09-28-design-release-update", "09-28-design-toast", - "09-28-design-ui-ux" + "09-28-design-ui-ux", + "09-28-design-debug-page" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-debug-page/check.jsonl b/.trellis/tasks/09-28-design-debug-page/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-debug-page/implement.jsonl b/.trellis/tasks/09-28-design-debug-page/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md new file mode 100644 index 000000000..82edb9b77 --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -0,0 +1,19 @@ +# Design debug page + +## Goal + +Phase-2 item 4: developer mode entry and persistence, debug page sections (logs, error history, network, playback state, database, health check, plugin dev tools, cache, diagnostics), data integrity tools + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-debug-page/task.json b/.trellis/tasks/09-28-design-debug-page/task.json new file mode 100644 index 000000000..dd3d6bea7 --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-debug-page", + "name": "design-debug-page", + "title": "Design debug page", + "description": "Phase-2 item 4: developer mode entry and persistence, debug page sections (logs, error history, network, playback state, database, health check, plugin dev tools, cache, diagnostics), data integrity tools", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 0fa0b9c31d2038d9d3d84ccf2151b03972d34362 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:36:58 +0800 Subject: [PATCH 101/133] chore(task): refresh the phase-two handoff note --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 0b4a74da8..b88ae331f 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -245,12 +245,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 5 項完成後) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 4 項研究中) - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0024`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0025(Debug 頁)。 -- **下一項:第 4 項「Debug 頁」**(尚未建 task):含 log 檢視與錯誤歷史(ADR 0011、0023 的詳細頁)、網路請求檢視、播放與佇列即時狀態、資料庫檢視、音源健康檢查(ADR 0015)、插件開發工具(ADR 0015)、快取管理(ADR 0016)、診斷包匯出(ADR 0011);版面用 ADR 0024 的設計系統。 +- **進行中:第 4 項「Debug 頁」**,task `.trellis/tasks/09-28-design-debug-page/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成,接著抽查→prd→一次一問。 + 已知輸入:J1 開發者模式(版本連點 7 次、不持久化、沒有關閉入口;擁有者勾保留)、J2 Debug 頁區塊(不確定,重做)、J3 log 寫檔(方向:保留並加輪替與保留期限)、J4 `DataIntegrityRepository.scan/repair`(方向:收進 Debug 頁);ADR 0011 明寫「Debug 頁與開發者模式的持久化由 Debug 頁的設計定」、ADR 0015 明寫「插件開發工具的版面由 Debug 頁的設計定」。範圍:含 log 檢視與錯誤歷史(ADR 0011、0023 的詳細頁)、網路請求檢視、播放與佇列即時狀態、資料庫檢視、音源健康檢查(ADR 0015)、插件開發工具(ADR 0015)、快取管理(ADR 0016)、診斷包匯出(ADR 0011);版面用 ADR 0024 的設計系統。 - 之後順序:7 里程碑定稿。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 @@ -262,4 +263,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 子代理因額度中斷:先 SendMessage 續跑;使用者手動停掉的代理不能續跑,使用者要求時才重新發起,並告知保留已寫的研究檔。 - 更新他項 ADR 的引用時只加一句指向新 ADR,不改原決定;新 lint 規則補記到 ADR 0015 的「後續 ADR 新增的規則」。 - 使用者提出新概念(例如 Jev)或要求把新功能一起做時,先派研究查成熟做法與可行性,再把可行性表攤開問範圍;使用者反駁建議的理由時(例如「插件只要更新插件」)若成立就改建議並寫進 prd 的決定。 + - 使用者對建議提出「為什麼」類問題(例如「只有全域快捷鍵不行嗎」)時:先查證據、直接回答並說明衝突與限制,再把選項重新攤開問一次,不要把問題當成否決。 + - 使用者問「能不能用某種新風格/新技術」(例如液態玻璃)時:自己快速查 pub.dev 與官方 issue(不必派代理),給出可行性、平台限制與效能代價,再以選項問。 + - 視覺選擇先載入 Artifact quickstart(intent `other`)再寫示意頁;草稿放 scratchpad,playwright 不能開 `file://`,所以直接發布、不先截圖。 - 每項最終摘要需列:你已定的、技術選擇(在核准範圍內)、放進待辦、不在範圍、核准後會做什麼、下一項。 From cbd04d1bbc6b000664386995d0429ebe9d9541f5 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 21:59:35 +0800 Subject: [PATCH 102/133] chore(task): add debug page research and prd --- .trellis/tasks/09-28-design-debug-page/prd.md | 120 ++- .../research/current-state.md | 191 +++++ .../research/packages-and-platform.md | 335 ++++++++ .../research/prior-art.md | 721 ++++++++++++++++++ 4 files changed, 1356 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-debug-page/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md create mode 100644 .trellis/tasks/09-28-design-debug-page/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md index 82edb9b77..d6765fcc4 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -1,19 +1,117 @@ -# Design debug page +# Debug 頁與開發者模式的設計 -## Goal +## 目標 -Phase-2 item 4: developer mode entry and persistence, debug page sections (logs, error history, network, playback state, database, health check, plugin dev tools, cache, diagnostics), data integrity tools +階段二第 4 項(parent prd 第 4 項;`docs/audit/questions.md` J1–J4):把 Debug 頁做成正式工具。 +範圍包括: +- 開發者模式怎麼開、怎麼關、要不要記住; +- Debug 頁的區塊與版面; +- log 檔的輪替與保留期限; +- 資料檢查/修復。 -## Requirements +產出 ADR 0025。 -- TBD +## 現況(研究已以程式碼核對,細節見 `research/current-state.md`) -## Acceptance Criteria +- **開發者模式** + - 開法:「版本」列連點 7 次(`developer_options_provider.dart:49`)。 + - 狀態只放在記憶體,重啟就消失,也沒有關閉入口。 + - 路由無條件註冊(`router.dart:246-263`)。 + - 它只控制兩件事:設定頁是否出現入口、執行期的 log 層級。 +- **Debug 頁**:四個區塊,都沒有權限閘門。 + - 記憶體磚:只清 Flutter 記憶體圖片快取。 + - log 層級。 + - 資料庫檢視器:11 個 collection 各做一次 `findAll()`;唯讀,不能搜尋、不分頁。 + - 重設資料:`isar.clear()` 之後跑 migration。 +- **Log 檢視頁** + - 已有:記憶體 500 筆、即時串流、層級與文字篩選、匯出落盤檔(存檔)。 + - 沒有:系統分享、錯誤歷史的概念。 +- **Log 檔**:單檔 2MB、保留 3 個,每種 build 都寫。與 ADR 0011 的差異: + - 記憶體 500 筆,ADR 要 1,000 筆; + - release 也輸出到 console; + - stackTrace 沒有遮蔽; + - 沒有「保留 N 天」的概念。 +- **`DataIntegrityRepository.scan/repair`**(`data_integrity_repository.dart:59-162`) + - 檢查四件事:Track `uniqueKey` 重複、DownloadTask `savePath` 重複、Account `platform` 重複、PlayQueue 超過一筆。 + - `lib/` 裡零呼叫點,只有測試用。 +- **沒有的東西**:App 內網路請求紀錄、播放狀態除錯畫面、診斷包、音源健康檢查、插件系統、統一的清除快取入口。 + - 目前 HTTP 流量只能經 VM Service 看(`docs/development.md` §執行期除錯)。 -- [ ] TBD +## 研究結論(`research/prior-art.md`、`research/packages-and-platform.md`) -## Notes +- **入口**: + - 隱藏手勢:Firefox 連點 logo 5 次;Android 系統本身連點版本號 7 次。 + - 可見設定項:NewPipe(不列入偏好搜尋)、Home Assistant、Signal(說明頁)。 + - LocalSend:關於頁的一顆按鈕,沒有 build 閘門。 +- **log 檢視**:Immich、Signal 有層級與搜尋。有 HTTP 請求頁的只有 LocalSend(記憶體 200 筆)。 +- **上限**:LocalSend 200 筆、Immich 500 筆、Signal 單檔 20 MiB 且保留 3 天(較長者 21 天)。 +- **遮蔽**:只有 Signal(`Scrubber`)與 Namida 有自動遮蔽;Home Assistant 在分享前跳警示。 +- **匯出**:Immich、AppFlowy、Namida、Signal 都分享檔案或 zip;Spotube、NewPipe 只給剪貼簿。 +- **套件**: + - talker、alice、requests_inspector 都沒有 release 閘門,閘門要 App 自己加。 + - ADR 0011 已否決用 `TalkerScreen`、`talker_dio_logger`、alice 當 UI。 +- **資料庫**: + - drift 官方 DevTools extension 隨 `drift` 出貨,可以改資料、沒有唯讀模式,release 編譯期整段移除。 + - drift 官方沒有 App 內檢視器;`drift_db_viewer` 2.1.0 唯讀,但已 2.5 年沒發版。 + - drift 沒有唯讀 API(`customSelect` 不擋寫入語句);要唯讀就自己用 `allTables` 加 `select`。 +- **log 輪替**: + - `logging`、`talker` 都不寫檔。 + - 只有 `logger` 的 `AdvancedFileOutput` 內建依大小輪替,沒有依日期輪替。 + - 社群的 `talker_persistent` 有 `retentionDays`(預設 3)。 +- **匯出管道**: + - `share_plus` 在 Linux 與 Windows RS5 以下分享檔案會 throw; + - `file_selector.getSaveLocation` 只有桌面能用; + - Android 分享走 `ACTION_SEND`。 +- **插件開發**: + - MusicFree 沒有熱重載。 + - LX Music 切換腳本=拆掉整個 runtime 重建,除錯靠 DevTools。 + - VS Code 的做法是「Reload Window」。 + - Flutter 熱重載只在 debug build。 + - Android 以 file_picker 選資料夾後讀其中 `.js` 不成立(推測,未實機);ADR 0015 已限桌面,影響為零。 + - `watcher` 1.2.1 桌面三平台走原生事件。 -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +## 已由前面 ADR 定下的邊界 + +- **ADR 0011** + - log 門面與遮蔽函式; + - 記憶體 1,000 筆、檔案 2MB×3; + - release 預設 info,開發者模式可調到 debug; + - 網路紀錄由自己的 dio 攔截器,每請求一筆摘要經門面寫入,不記 body; + - 錯誤歷史=Debug 頁的篩選,跨重啟由 log 檔提供; + - 診斷包欄位參考 NewPipe; + - 設定裡有「開發者」一組; + - 「Debug 頁與開發者模式的持久化由 Debug 頁的設計定」。 +- **ADR 0013、0023**:開發者模式下每則錯誤提示附「詳細」;Debug 頁的錯誤歷史與提示共用同一個詳細頁。 +- **ADR 0015** + - 音源健康檢查=檢查案例的真實連線版,在 App 內手動跑。 + - 插件開發工具:開發者模式下、先限桌面、從資料夾載入、重新載入、跑案例看 log、錄 fixture、每插件切換真實/錄製/重播。 + - 「版面由 Debug 頁的設計定」。 + - flavor 分 `dev`/`prod`。 +- **ADR 0016**:「清除快取」與各類用量在設定頁。 +- **ADR 0010**:drift 以外鍵與唯一鍵保證關係;舊資料匯入先寫暫存庫並驗證。 +- **ADR 0018**:播放狀態是 sealed 型別,位置走獨立 stream。 +- **ADR 0024**:設計系統;設定頁在 expanded 以上用 list-detail。 + +## 擁有者的輸入 + +- J1 勾「保留」(連點 7 次、不持久化、無關閉入口)。 +- J2、J3、J4 勾「不確定」。 +- 備註:「如果有問題或是有更好的方案的話可以按你推薦的來改」。 +- `phase2-plan` §8 的方向: + - Debug 頁重做成正式工具; + - log 保留並加輪替與保留期限; + - 資料檢查/修復收進 Debug 頁。 + +## 待決定(一次問一題) + +1. 開發者模式:入口、要不要記住、怎麼關、開發版(dev flavor)是否預設開啟。 +2. Debug 頁的區塊清單,以及資料庫檢視器、重設資料在 release 版是否提供。 +3. log 保留期限。 +4. 資料檢查/修復在 drift 之下要做什麼。 + +## 驗收條件 + +- [ ] 以上待決定項都有擁有者的答覆,寫進 ADR 0025。 +- [ ] ADR 0025 含「如何確認」(測試或 lint 與第一個里程碑的實測項目)。 +- [ ] ADR 0011、0015 各加一句指向 0025。 +- [ ] `phase2-plan.md` 的 §3、§7/§8、§10 已更新。 diff --git a/.trellis/tasks/09-28-design-debug-page/research/current-state.md b/.trellis/tasks/09-28-design-debug-page/research/current-state.md new file mode 100644 index 000000000..7c48f909f --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/research/current-state.md @@ -0,0 +1,191 @@ +# current-state — Debug 頁相關現況(補 `docs/audit/devtools.md` 未涵蓋者) + +查證日:2026-09-28 +查證方式:唯讀原始碼(分支 `docs/audit`,repo 根目錄的現行專案),以 `檔案:行號` 逐條標註。未執行 App、未跑測試、未打任何音樂平台 API。 +前置說明:`docs/audit/devtools.md`(審計日 2026-09-26)已完整描述的段落,本檔只**指回**不重抄;本檔只補它沒有的、或需要更精確行號的。 +**重要前提**:repo 內**不存在 `app/` 目錄**(`ls app` 無此目錄),ADR 0008–0024 描述的 `app/lib/...` 是尚待建立的新專案;本檔描述的是現行 `lib/`(舊專案)。 + +--- + +## 1. 開發者模式 + +### 1.1 開啟與持久化 +已被 `devtools.md` §1.1 完整涵蓋(連點 7 次、`requiredTaps = 7`、不持久化、無關閉入口、路由無條件註冊)。此處只補「開發者模式到底控制了什麼」,因為這決定 Debug 頁的開關語意。 + +### 1.2 `developerOptionsProvider` 的**全部**消費點(grep `developerOptionsProvider`,共 4 個檔案) + +| 消費點 | 用途 | 檔案:行號 | +|---|---|---| +| 定義 | `NotifierProvider` | `lib/providers/settings/developer_options_provider.dart:76-79` | +| 設定頁的版本列 | 讀 `isEnabled`/`tapCount`,判斷要不要顯示「再點 n 次」提示 | `lib/ui/pages/settings/widgets/settings_about.dart:7-8`、`:23-32` | +| 設定頁的開發者區塊 | 只在 `isEnabled` 時顯示「開發者選項」那一列;否則 `SizedBox.shrink()` | `lib/ui/pages/settings/widgets/settings_about.dart:91-117`(`_DeveloperOptionsSection`)、掛載點 `lib/ui/pages/settings/settings_page.dart:194` | +| 開發者選項頁的日誌級別列 | 讀 `state.logLevel`、呼叫 `setLogLevel` | `lib/ui/pages/settings/developer_options_page.dart:603`、`:615` | + +**事實**:開發者模式控制的只有兩件事——(a) 設定頁是否出現「開發者選項」入口;(b) 執行期 log 級別下拉。它**不**控制任何路由保護(§1.4)、**不**控制 Debug 頁內任何區塊的顯示(頁面內所有區塊無條件顯示)、也**不**影響 Toast(`devtools.md` §5 第 1 點已列;ADR 0023 已定開發者模式要讓錯誤提示附「詳細」)。 + +### 1.3 `DeveloperOptionsState` 三個欄位 +`isEnabled`、`tapCount`、`logLevel`,皆記憶體狀態(`:6-34`);`build()` 以 `AppLogger.minLevel` 初始化 `logLevel`(`:39-40`)。`reset()`(`:70-72`)在 `lib/` 與 `test/` 都查不到呼叫點(`devtools.md` §1.1 已列)。 + +### 1.4 路由保護 +`devtools.md` §1.1 說三個路由無條件註冊。補充精確位置:路徑常數 `lib/ui/router.dart:54-56`、路由名常數 `:87-89`、註冊在 `lib/ui/router.dart:246-263`(`developer` 底下巢狀 `database` 與 `logs`)。**無 `redirect` 或 `canActivate` 之類的守衛**。 + +--- + +## 2. Debug 頁(`DeveloperOptionsPage`)逐區塊 + +`devtools.md` §1.2 已有逐區塊表;此處只補它沒點到的實作細節。 + +### 2.1 頁面骨架 +三個 `_SettingsSection`:除錯工具(`:37-57`)、資料管理(`:60-63`)、資訊(`:66-79`),區塊間 `Divider()`。 + +### 2.2 記憶體使用(`_MemoryInfoTile`,`:168-474`) +- 讀的 provider(全為 `ref.read`,非 watch):`queueProvider`(`:209`)、`rankingCacheServiceProvider`(`:210`)、`lyricsCacheServiceProvider`(`:224`)。 +- 磁碟圖片快取走靜態方法 `NetworkImageCacheService.getCacheSizeMB()`(`:197`)與常數 `NetworkImageCacheService.maxCacheSizeMB`(`:198`)。 +- 進程 RSS 只在 Android/Windows/Linux 取(`Platform.isAndroid || Platform.isWindows || Platform.isLinux`,`:202`)——這是 UI 層的平台判斷(未來 `fmp_platform_checks` lint 的對象,ADR 0015)。 +- 「Native 記憶體」= `RSS − Flutter 圖片快取 bytes`,clamp 到 `[0, RSS]`(`:358-363`),是粗估不是量測。 +- **清除按鈕只清 Flutter 記憶體**:`PaintingBinding.instance.imageCache.clear()` + `clearLiveImages()`(`:266-274`),**不動**磁碟快取、不動歌詞快取。 +- 摘要行寫死簡中 `'Flutter 图片: '`(`:307`),未走 i18n(`devtools.md` §5 第 13 點已列)。 + +### 2.3 日誌級別(`_LogLevelTile`,`:597-627`) +`DropdownButton` 列出 `LogLevel.values`(DEBUG/INFO/WARNING/ERROR),`onChanged` 呼叫 `ref.read(developerOptionsProvider.notifier).setLogLevel(next)`。**它只影響之後產生的 log(含落盤)**,重啟回復 `AppLogger.minLevel`(`devtools.md` §1.2 已列)。 + +### 2.4 資料庫檢視器(`DatabaseViewerPage`) +- 頁面:`lib/ui/pages/settings/database_viewer_page.dart:14`;collection 選擇器 `_buildCollectionSelector()`(`:50`)為頂部 chip 列;清單 `_DatabaseCollectionListView`(`:115`),`collection.query(isar)`(`:127`)一次 `findAll()`;每筆一張 `_DataCard`(`:192`)。 +- 清單來源 `lib/data/database/database_catalog.dart`,共 **11 個 collection**,全部 `findAll()`:Track(`:53`)、Playlist(`:61`)、PlayQueue(`:69`)、PlayHistory(`:77`,`sortByPlayedAtDesc()`)、Settings(`:86`)、SearchHistory(`:95`,`sortByTimestampDesc()`)、DownloadTask(`:103`)、RadioStation(`:111`)、LyricsMatch(`:119`)、LyricsTitleParseCache(`:127`)、Account(`:135`)。 +- **唯讀**:`FmpDatabaseCollection` 只宣告 `query`/`title`/`subtitle`/`sections`(`database_catalog.dart:9-29`),沒有任何寫入函式;頁面無搜尋、無分頁、無編輯(`devtools.md` §1.2 已列)。 + +### 2.5 重設資料(`_ResetDataTile`,`developer_options_page.dart:511-567`) +確認對話框(`showConfirmDestructiveDialog`)→ `DataIntegrityRepository(isar).clearEverything()`(`:551`,即 `_isar.clear()`,`data_integrity_repository.dart:55-57`)→ `runDatabaseMigration(isar)`(`:554`)。範圍限制見 `devtools.md` §1.2/§5 第 3 點。 + +### 2.6 資訊區塊的「除錯模式」 +恆真裝飾列(`:69-77`),`devtools.md` §1.2 已列。 + +--- + +## 3. Log 檢視頁(`LogViewerPage`)——補 `devtools.md` §3.4 + +`devtools.md` §3.4 已列筆數上限與篩選;補精確行為: + +| 行為 | 實作 | 檔案:行號 | +|---|---|---| +| 初始載入 | `_logs = List.from(AppLogger.logs)`(複製 500 筆記憶體緩衝) | `log_viewer_page.dart:34` | +| 訂閱即時 | `AppLogger.logStream.listen`,超過 1000 筆 `removeAt(0)` | `:35-46`(上限 `:39`) | +| 顯示篩選 | 級別門檻用 `log.level.index < _filterLevel.index` 過濾,再比對 `message`/`tag` 的小寫子字串 | `:68-80` | +| 篩選選單 | `PopupMenuButton`,四項 | `:199-219`(其中 `'Info+'` `:209`、`'Warning+'` 寫死英文) | +| 複製全部 | 只複製**已篩選**的 `_filteredLogs` | `:91-95` | +| 匯出落盤檔 | `AppLogger.fileSink.readAll()`(輪替檔由舊到新串接);Android 選目錄、其餘平台 `FilePicker.saveFile`;檔名 `fmp_log_.log` | `:102-148` | +| 清空 | `_logs.clear()` + `AppLogger.clearLogs()`,**不動落盤檔** | `:150-155` | +| 單筆詳情 | 僅對 `hasError` 的列可點(`:291`);對話框顯示時間/級別/tag/message/error/stackTrace,可複製 | `:345-415` | + +- 沒有系統分享(`share_plus` 未在 pubspec)。匯出只有「存檔」。 +- 「顯示篩選」與「開發者選項的記錄門檻」是兩個不同的級別設定(`devtools.md` §3.4 已列)。 + +--- + +## 4. Log 寫檔(位置/輪替/保留/格式)與 ADR 0011 的差異 + +現況(`devtools.md` §3 已描述一部分,此處補差異): + +| 項目 | 現況(含出處) | ADR 0011 定案 | 差異 | +|---|---|---|---| +| 記憶體歷史 | 500 筆(`lib/core/logger.dart:71-72`),`Queue` + `removeFirst`(`:262-264`) | 最近 1,000 筆 | **不同** | +| 落盤檔案 | 單檔 2MB、保留 3 個(`lib/core/log_file_sink.dart:18-19`、`_rotate()` `:90-105`) | 單檔 2MB、保留 3 個 | 相同 | +| 落盤位置 | `getApplicationDocumentsDirectory()/FMP/logs/fmp.log`(`log_file_sink.dart:24-28`) | ADR 0009 資料目錄的 `logs/` | 概念相同 | +| 落盤啟用 | `main()` 在 binding 初始化後 `attachFileSink`,**所有 build 都掛**(`lib/main.dart:135-138`,`attachFileSink` 在 `:136`;`logger.dart:163-170`) | release 寫 info 以上 | 概念相同(層級決定內容) | +| release 預設級別 | `kDebugMode ? debug : info`(`logger.dart:68`) | release 預設 `info`,開發者模式可調 `debug` | 相同 | +| console 輸出 | **不分 build 一律 `debugPrint`**(`logger.dart:272,283`),debug 另加 `developer.log`(`:283-290` 前) | console 只在 debug build | **不同**(`devtools.md` §5 第 12 點已列) | +| 遮蔽範圍 | 訊息與 error 字串遮蔽(`logger.dart:177-200` 的 `redactSensitive`;`_log` 呼叫點 `:227-238`);**stackTrace 不遮蔽**(`:256`、`:285-289`) | 遮蔽套用在訊息、error、**stackTrace**、結構化欄位 | **不同**(`devtools.md` §3.3 已列) | +| 保留期限 | **沒有**「保留 N 天」的概念,只有「保留 3 個檔」 | ADR 0011 未寫保留期限;`phase2-plan` 要求「加輪替與保留期限」 | **保留期限是新增要求** | +| 日誌套件 | 自製 `AppLogger` 靜態類別(`logger.dart:67`),**未使用 `talker`**(pubspec 無 talker;`grep talker pubspec.yaml` 無結果) | 採用 `talker` 作資料核心 | **不同**(新專案才引入) | +| 格式 | 每筆 `toFileLine()`:`[LEVEL] [tag] message` + 換行縮排的 `Error:`/`StackTrace:` | 門面參數含結構化欄位 | 結構化欄位是新增 | + +其他事實: +- 遮蔽不涵蓋 CDN 簽名 URL(`devtools.md` §3.3 已列);AI 歌詞比對在 debug 級別會把整個請求 payload 寫進 log(`lib/services/lyrics/ai_title_parser.dart:57`、`ai_lyrics_selector.dart:116`)。 +- 落盤 I/O 失敗全部吞掉,`write()` 不等待也不拋(`log_file_sink.dart:6-13,71-74`)。 + +--- + +## 5. `DataIntegrityRepository.scan/repair` + +`devtools.md` §1.2 註腳只提到「`lib/` 查不到呼叫點,只有測試用」。補它的實際行為: + +- 檔案:`lib/data/repositories/data_integrity_repository.dart`。 +- `scan()`(`:59-79`)回 `DataIntegrityReport`(`:9-27`),檢查四件事: + 1. 重複的 Track `uniqueKey`(`:66`); + 2. 重複的 DownloadTask `savePath`(僅非空的,`:67-72`); + 3. 重複的 Account `platform`(`:73-76`); + 4. PlayQueue 筆數 > 1(`:77`,`hasIssues` 的判準在 `:22-27`)。 +- `repair()`(`:81-162`)在單一 `writeTxn` 內修復:Track 群組保留「完整度分數」最高者(`_preferTrack`/`_trackCompletenessScore`,`:323-342`),合併 metadata(`_mergeTrackMetadata`,`:229-265`),並 remap 其他表的參考(`_remapTrackReferences`,`:164-180`:改寫 DownloadTask `trackId`、PlayQueue `trackIds`/`originalOrder`/`currentIndex`);DownloadTask 保留狀態分數最高者(`:344-364`);Account 保留已登入/較新者(`:366-375`);PlayQueue 只留一個(`:377-387`)。 +- **呼叫點**:`clearEverything()` 被 `developer_options_page.dart:551` 呼叫;`scan()`/`repair()` 在 `lib/` **零呼叫點**,只有 `test/data/repositories/data_integrity_repository_test.dart`(`:29,59,66,69,70,119,146,171,188,205,229,247`)使用。grep 佐證:`grep -rn "DataIntegrityRepository|\.scan()|\.repair()" lib/ test/`。 + +--- + +## 6. 現有的網路請求記錄機制 + +**查不到任何 App 內請求記錄機制。** 逐條: + +- `lib/` 內無 `LogInterceptor`、無 `PrettyDioLogger`、無請求歷史/環形緩衝(grep `LogInterceptor`、`requestLog|networkLog|httpHistory|requestHistory` 皆 0 命中)。 +- dio 實例統一由 `HttpClientFactory.create`(`lib/core/utils/http_client_factory.dart:32`)建立,只設 headers / timeouts / content type,**沒有攔截器**。 +- 既有攔截器只有三個帳號認證用:`BilibiliAuthInterceptor`(`lib/services/account/bilibili_auth_interceptor.dart:17`)、`NeteaseAuthInterceptor`(`netease_auth_interceptor.dart:12`)、`YouTubeAuthInterceptor`(`youtube_auth_interceptor.dart:11`);它們只做 cookie 注入與認證錯誤重試(例如 bilibili 的 `-101/-111`,見該檔 dartdoc `:9-14`),**不是記錄器**。 +- 唯一能看到實際 HTTP 流量的是 **VM Service**:`ext.dart.io.httpEnableTimelineLogging` + `getHttpProfile`(`docs/development.md` §執行期除錯)。該節並註明「FMP 的 Dio 沒有自訂 `httpClientAdapter`,走的是 `dart:io HttpClient`,三個音源與圖片 CDN 都攔得到」。 +- ADR 0011 已定新專案要「自己的 dio 攔截器,每請求一筆摘要(方法、主機、路徑、遮過的 query、狀態、耗時、大小、音源、錯誤類型),經門面寫入;不記 body」。**這是新功能,現況沒有。** + +--- + +## 7. 播放狀態觀察工具 + +**沒有專用除錯 UI。** 事實: + +- 唯一狀態源:`audioControllerProvider = NotifierProvider`(`lib/providers/audio/audio_controller_provider.dart:91`)。 +- `PlayerState`(`lib/services/audio/player_state.dart:12-60`)欄位:`isPlaying`、`isBuffering`、`isLoading`、`processingState`、`position`、`duration`、`bufferedPosition`、`speed`、`volume`、`playingTrack`、`error`(String)、`retryAttempt`、`isNetworkError`、`isRetrying`、`nextRetryAt`、`currentBitrate`、`currentContainer`、`currentCodec`、`currentStreamType`、`audioDevices`、`currentAudioDevice`。 +- selector 位於 `lib/providers/audio/audio_player_selectors.dart`:`playbackSpeedProvider`(`:119`)、`desktopAudioDeviceStateProvider`(`:123`)、`currentStreamMetadataProvider`(`:136`)、`currentTrackProvider`(`:169`)、`queueProvider`(`:174`)、`upcomingTracksProvider`(`:179`)、`queueControlStateProvider`(`:184`)。 +- 這些 selector 的消費者是 **播放 UI**,不是除錯頁:`lib/ui/pages/player/player_page.dart:171,819`、`lib/ui/widgets/panels/track_detail_panel.dart:753`、`lib/ui/widgets/player/mini_player_desktop_controls.dart:28`、`lib/ui/pages/radio/radio_player_page.dart:41`。 +- 「佇列即時狀態」目前只在 Debug 頁的記憶體磚顯示「佇列曲數」(`developer_options_page.dart:384-389`),沒有更多。 +- 執行期讀活物件只有 VM Service 的 `getClassList → getInstances → getObject`(`docs/development.md` §執行期除錯,含 `evaluate` 不通的地雷)。 +- ADR 0018 已定新專案的狀態是 sealed(`Idle`/`Loading`/`Playing`/`Paused`/`Buffering`/`Retrying`/`Failed(AppError)`)+ 高頻位置走獨立 stream。**與現況的單一 `PlayerState` 不同。** + +--- + +## 8. 快取清除入口 + +現況**沒有單一「清除所有快取」入口**,散在三處(皆各自為政): + +| 入口 | 位置 | 實際清除什麼 | +|---|---|---| +| 設定頁「圖片快取」對話框的「清除」 | `lib/ui/pages/settings/widgets/settings_cache.dart`(`_ImageCacheSizeListTile` 的 `_showImageCacheDialog`) | `ImageLoadingService.clearNetworkCache()` → `NetworkImageCacheService.clearCache()`(`lib/core/services/image_loading_service.dart:41-47`、`network_image_cache_service.dart:262`)。**不清** Flutter 記憶體 `ImageCache` | +| 設定頁「歌詞快取」對話框的「清除」 | 同檔(`_LyricsCacheSizeListTile`) | `lyricsCacheServiceProvider` 的 `cache.clear()` | +| 開發者選項頁記憶體磚的「清除圖片記憶體快取」 | `developer_options_page.dart:410-417`、`:266-274` | 只清 `PaintingBinding.instance.imageCache`(記憶體) | +| 設定頁「下載管理」的「清除已完成/清除佇列」 | `lib/ui/pages/settings/download_manager_page.dart:37-49` | `downloadService.clearCompleted()` / `clearQueue()`,與快取無關 | + +- 設定頁的「快取」區塊在 `lib/ui/pages/settings/settings_page.dart:118-127`,同一區塊還有排行榜/電台刷新間隔。 +- **串流網址快取**:舊版把串流網址存進 Isar(`docs/audit`/ADR 0016 背景已述),因此**沒有**「清除串流快取」的入口。 +- ADR 0016 已定新專案要「一個統一快取庫、一個總上限、設定頁顯示各類用量與一個清除快取(含 Flutter 記憶體 `ImageCache`)」。**現況與此差距大。** + +--- + +## 9. 診斷包 + +**查不到任何診斷包實作。** `grep -rni "diagnostic|診斷包|診斷" lib/` 只命中 `lib/core/errors/user_message.dart` 的「診斷(diagnostic)」字樣(`:11-13,25,42-43,78,116-120`),那是錯誤訊息措辭,不是診斷包。ADR 0011 §6 已定新專案的診斷包欄位(參考 NewPipe)。 + +--- + +## 10. VM Service 除錯做法(`docs/development.md` §執行期除錯) + +摘要(細節見該節原文): +- 只在 debug / profile build 可用;Isar 的 `ext.isar.*` 只在 debug(`Isar.open` 的 `inspector` 在 profile / release 被 tree shake)。 +- 取 BASE:`flutter run` 印出的 VM Service URL 去掉結尾 `/`;**token 是本機除錯憑證,不貼進 issue/PR/log/報告**;`getVM` 取 isolate id。 +- HTTP:先 `httpEnableTimelineLogging` 再產生流量(只記開啟之後的請求;啟動那幾秒量不到),再 `getHttpProfile` / `getHttpProfileRequest` / `clearHttpProfile`。回應含簽名串流 URL 與 Cookie,不可外流。 +- 讀活物件:`evaluate` 不通(`No compilation service available`),改用 `getClassList → getInstances → getObject`。 +- Isar:參數全包在 `args` JSON 字串;`editProperty` 路徑用 `.` 分段(清單索引寫數字段);`Settings.youtubeStreamPriority` 是 `@Deprecated` v1 欄位;寫入會與 App 自己的寫入者搶(`QueueManager` 每 10 秒存回整份 `PlayQueue`)。 +- 其他 RPC:`listInstances`、`getSchema`、`exportJson`、`importJson`;記憶體/timeline/widget tree dump 見 Dart VM Service Protocol。 + +--- + +## 11. 其他與 Debug 頁相關的既有事實 + +- **Toast**:全 app 單一 `ToastService`(靜態 + Stream 兩套入口),`devtools.md` §2 已詳列;ADR 0023 已定要換成單一 `Toaster`,並讓 Debug 頁的錯誤歷史共用錯誤詳細頁。 +- **錯誤歷史**:現況沒有「錯誤歷史」概念,只有 log 篩選;ADR 0011 §5 說錯誤歷史 = Debug 頁的 log 篩選。 +- **遮蔽函式**:現況是 `AppLogger.redactSensitive`(單一處,`logger.dart:177`),但只涵蓋訊息與 error 字串;ADR 0011 §3 要求單一遮蔽函式涵蓋 stackTrace、CDN 簽名 URL、已知憑證值。 +- **音源健康檢查**:`grep -rni "healthCheck|health_check|健康檢查|sourceHealth" lib/` **0 命中**——現況沒有。ADR 0015 §4 已定「檢查案例一份四用」,健康檢查是真實連線、App 內、手動執行。 +- **插件開發工具**:現況沒有插件系統(ADR 0014 的 script source plugins 是新專案設計);`grep -rni "plugin" lib/ --include=*.dart` 只有 3 命中(`core/secure_key_value_store.dart:65-66` 的 `MissingPluginException`、`services/audio/audio_service.dart:10` 的註釋),都與 debug 頁無關。 +- **i18n**:`devtools.md` §5 第 13 點已列三處寫死字串(`developer_options_page.dart:307`、`log_viewer_page.dart:208-212`)。 diff --git a/.trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md b/.trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md new file mode 100644 index 000000000..1b5f7e5a3 --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md @@ -0,0 +1,335 @@ +# packages-and-platform + +查證日:2026-09-28 + +查證方式:pub.dev API、context7、官方文檔、GitHub gh api(固定 commit SHA permalink)、tavily + +> 版本號一律以 `https://pub.dev/api/packages/` 或官方頁面核對;GitHub 連結為查證當下的 commit SHA permalink。 + +--- + +## 1. drift 官方 DevTools extension + +### 它是什麼 + +- drift 官方把它叫做 "DevTools extension",**不是**獨立套件:extension 的資產直接隨 `drift` 這個 pub package 出貨(repo 內目錄 `drift/extension/devtools/`,內含 `config.yaml`)。`drift/extension/devtools/config.yaml` 的內容是 `name: drift`、`version: 0.0.1`,沒有設 `requiresConnection`,因此依 `devtools_extensions` 預設為 `true`(需要連上執行中的 app)。 + 出處: +- 官方文件頁:(repo 原始檔:) +- pub.dev 上叫 `drift_devtools_extension` 的套件**不存在**(`https://pub.dev/api/packages/drift_devtools_extension` 回 404)。名稱相近的是第三方 `drift_devtools` 0.0.17(2026-04-06),見第 2 節。 + +### 功能 + +| 功能 | 事實 | 出處 | +|---|---|---| +| 列出目前開啟中的 drift 資料庫與其 class 定義位置 | 是 | devtools.md L41-L43 | +| 檢視各 table 內容 | 是 | devtools.md L43 | +| **修改** table 內容(不是唯讀) | 是 | devtools.md L43 | +| Validate schema:比對預期 schema 與實際 schema | 是 | devtools.md L48-L57 | +| 匯出資料庫(download) | 是,僅 native(`isExportSupported = true`);web / unsupported 為 `false` 並 throw | `drift/lib/src/runtime/devtools/platform_native.dart#L7`、`platform_unsupported.dart#L4-L13` | +| 清空資料庫(`clear`,刪 `sqlite_master` + `VACUUM`) | 是(破壞性) | `drift/lib/src/runtime/devtools/service_extension.dart#L99-L123` | +| 執行任意 SQL:select / insert / update / delete / custom statement | 是 | 同上 #L56-L84 | + +- 內部實作用了 `drift_db_viewer`(Koen Van Looveren),但官方明說「你不必對那個套件加依賴,它只在 DevTools context 內執行」。 + 出處:devtools.md L44-L46 +- 機制:app 內用 `dart:developer` 的 `registerExtension('ext.drift.database', ...)` 註冊 VM service extension,DevTools 端呼叫它。 + 出處: + +### 怎麼裝 / 啟用 + +1. 用 `flutter run`(會印出 DevTools 連結)、`dart run --observe`,或從 VSCode / IntelliJ / Android Studio 開 DevTools。 +2. 第一次要在 DevTools 視窗上方點 extensions 圖示,把 `package:drift` 設為 enabled(enablement 狀態存在專案根目錄的 `devtools_options.yaml`,見第 3 節)。 +3. 之後 DevTools 會出現 drift 分頁。 +出處:devtools.md L14-L33;enablement 機制 + +### 版本 / 支援平台 + +- **沒有獨立版本號**:以「drift 版本 + Flutter 版本」為準。官方 community tools 頁寫「Starting with Drift 2.13 and Flutter 3.16」。 + 出處: +- 查證當下 `drift` latest = **2.35.0**(2026-09-09),`drift_dev` = 2.35.0(2026-09-09)。 + 出處:、 +- 平台:extension 本體跑在 DevTools(瀏覽器端);被檢視的 app 端程式碼在 Android / iOS / Linux / macOS / Windows 都能用(`drift_db_viewer` 支援 Android, iOS, Linux, macOS, Web, Windows)。 + 出處: + +### 限制(重點) + +- **release build 不可用**,且 drift 原始碼有硬性編譯期開關:`const _releaseMode = bool.fromEnvironment('dart.vm.product'); const _enable = !_releaseMode;` —— release 時整個追蹤程式碼不進 build。 + 出處:(`handleCreated` 的 `if (_enable)` 在 #L44-L50) +- 需要能連上 app 的 VM Service(DevTools 是 attach 到執行中 app);VM Service / service extension 在 release mode 被關掉。Flutter 官方 build modes 表:debug「Service extensions are enabled」「DevTools can connect」;profile「Some service extensions ... enabled」「DevTools can connect」;release「Service extensions are disabled」「Debugging is disabled」「Debugging information is stripped out」。 + 出處: +- **profile mode 是否可用:文件沒明說**;依 `_enable`(只看 `dart.vm.product`)與 profile 有 VM Service 推論「profile 可能可用」,但官方文件未確認 → **推測**。 +- 匯出在 web 不支援 → **推測**(原始碼是 `platform_unsupported` 選 `dart.library.io` 以外時 throw;web 屬 unsupported 分支,故 web 上匯出會 throw)。 +- 只列出「目前開啟中」的 drift 資料庫(透過 drift runtime 建立並被 `handleCreated` 追蹤者)。 + 出處:devtools.md L41-L42;devtools.dart #L44-L50 +- 破壞性能力(`clear` 清空整個 DB、任意 insert/update/delete)沒有任何只讀模式開關。 + 出處:service_extension.dart #L56-L123 + +--- + +## 2. 在 App 內檢視 drift 資料庫 + +### drift 官方是否提供 App 內檢視器 + +- **沒有**。drift 官方 `/tools` 頁只導向 "Devtools extension" 與 "Community tools" 兩頁,沒有官方 App 內 viewer widget。 + 出處:(側欄)、 +- 官方認可的 App 內方案是 community 套件 `drift_db_viewer`("is a package to view a moor or drift database in your Flutter app directly. It includes a graphical user interface showing you all rows for each table.")。 + 出處:community_tools.md + +### drift_db_viewer(官方 community 頁推薦)事實 + +- latest = **2.1.0**(2024-04-08,距今約 2.5 年未更新);publisher `vanlooverenkoen.be`(verified);dependency constraint `drift >=2.0.0 <3.0.0`。 + 出處:、 +- 平台:Android, iOS, Linux, macOS, Web, Windows(pub.dev 標示)。 +- 用法:`Navigator.of(context).push(MaterialPageRoute(builder: (context) => DriftDbViewer(db)));`(db 需為 singleton)。 +- **唯讀**:DB 存取只有 `customSelect` / `customSelectStream` / `count`(皆 SELECT);`runCustomStatement` 雖定義在介面上,但 viewer 畫面沒有呼叫它(在 screen / viewmodel 內 grep 不到任何 delete/update/insert/customStatement 呼叫)。 + 出處: +- 已知限制:使用 named columns 時欄位要加 `@JsonKey`,否則該 table 無法處理(README "Drift Config" 段)。 + 出處: +- README 未說是否支援 release build;文中只說用在 "our development app"(暗示 dev context,未明講)→ **推測**:官方定位是開發期工具。 + +### drift_db_viewer 的替代(第三方,皆為 pub.dev 描述,未深入查證原始碼) + +| 套件 | latest | 發布日 | pub.dev 描述 | 形式 | +|---|---|---|---|---| +| `drift_devtools` | 0.0.17 | 2026-04-06 | "A Flutter package that provides a visual interface for inspecting and debugging Drift databases in real-time." | App 內即時檢視 | +| `drift_db_inspector` | 0.2.0 | 2026-07-12 | "A standalone browser-based database inspector for Drift databases, connected through the Dart VM Service." | 瀏覽器 + VM Service | +| `saropa_drift_advisor` | 4.4.1 | 2026-09-08 | "Debug-only HTTP server that exposes SQLite/Drift table data as JSON and a minimal web viewer." | debug-only HTTP server | +| `local_database_visual_debugger` | 0.0.1 | 2026-04-29 | "A plug-and-play in-app database viewer and inspector for Flutter." | App 內 | + +出處:`https://pub.dev/api/packages/` 各自查詢(2026-09-28)。 + +### 自寫查詢的官方 API 與唯讀限制 + +- `select(table)` → `get()` / `watch()`;`selectOnly`、`selectExpressions`。單值變體 `getSingle` / `getSingleOrNull` 等。 + 出處: +- `customSelect(String query, {variables, readsFrom})` 回 `Selectable`;stream 版為 `customSelectStream` 或 `.watch()`;官方建議帶 `readsFrom` 讓 stream 知道要重發。`customInsert` / `customUpdate` / `customStatement` 是寫入路徑。 + 出處:、 +- **唯讀**:drift **沒有**官方唯讀模式 / 唯讀 API(drift 端 grep 不到 readOnly 開關)。`customSelect` 底層呼叫 executor 的 `runSelect`;sqlite3 back end 的 `_selectResults` **不檢查**傳進來的語句是不是 SELECT(只 `_step()` 取值),所以 `customSelect` 不構成唯讀保證。 + 出處:、 +- sqlite3 層有 `isReadOnly`(`sqlite3_stmt_readonly()`),但 drift 未使用它做閘門;sqlite3 也有 `OpenMode.readOnly`(直接開 sqlite3 connection 時可用),drift 的 `NativeDatabase` 未暴露等價參數。 + 出處:statement.dart #L322;drift 端 `grep readOnly/OpenMode` 於 `drift/lib/src/sqlite3/database.dart`、`connection_user.dart` 無對應參數。 +- schema 列舉可用 `db.allTables`(`drift_db_viewer` 就是這樣列 table 的)。 + 出處:drift_db_viewer_database.dart #L17-L31 + +--- + +## 3. Flutter DevTools extensions 機制 + +### 套件與版本 + +- `devtools_extensions` latest = **0.5.1**(2026-05-04),publisher `flutter.dev`。 + 出處: +- 官方建置指南:;套件 README: + +### 套件如何提供自己的 DevTools 分頁 + +- extension 是**一個 Flutter web app**,被嵌進 DevTools 內的 iframe(tab)。使用者必須依賴提供 extension 的 pub package,tab 才會出現。 + 出處: +- 目錄結構:package 內要有 `extension/devtools/`,含 `config.yaml` 與預編譯好的 `build/`。companion extension 建議原始碼放在另一個 package(如 `foo_devtools_extension/`)以免膨脹主套件。 +- `config.yaml` 必填欄位:`name`、`version`、`issueTracker`、`materialIconCodePoint`;選填 `requiresConnection`(預設 `true`:是否要連上執行中的 Dart/Flutter app)。 +- `lib/main.dart` 用 `DevToolsExtension` widget 包住 root;可存取三個 global:`extensionManager`、`serviceManager`(連上的 VM service,if present)、`dtdManager`(Dart Tooling Daemon,if present)。 +- 發佈流程:`dart run devtools_extensions validate --package=...` → `dart run devtools_extensions build_and_copy --source=. --dest=/extension/devtools` → `pub publish`(缺 `config.yaml` 或空 `build/` 會 warning)。git-ignored build 目錄要在 `.pubignore` 加 `!build`。 + 出處:custom-tool 頁與 README(同上)。 + +### `devtools_options.yaml` + +- extension 的 enablement 狀態存在**使用者專案根目錄**的 `devtools_options.yaml`(類似 `analysis_options.yaml`)。進版控=全專案共用;加進 `.gitignore`=每人各自設定。格式:`extensions: [- provider: true, - shared_preferences: true, - foo: false]`。 + 出處: +- 注意:檔名是 `devtools_options.yaml`(使用者專案);套件端設定檔是 `extension/devtools/config.yaml`。兩者不同,勿混。 + +### 能否取代部分 App 內工具 / 關鍵限制 + +- 可以取代「開發期」的 App 內除錯工具(在 DevTools 內操作,不必在 app 裡做 UI)。**但無法取代 release build 內使用者可見的工具**: + - extension 需要 DevTools 連上執行中的 app(`requiresConnection` 預設 true); + - DevTools 的 VM Service 只在 debug / profile 可用,release 的 service extensions 被關掉。 + 出處:(見第 1 節引文) +- `requiresConnection: false` 的 extension 可不連 app、只從 IDE 開 DevTools 使用;此時需要 Dart SDK ≥ 3.5 且 Flutter SDK ≥ 3.23(README)。建置 extension 本身的最低需求:**Flutter SDK ≥ 3.17、Dart SDK ≥ 3.2**(custom-tool 頁)。 +- 查證當下 repo master 的 `devtools_extensions` pubspec 已到 `0.5.2-wip`,`sdk: ^3.11.0`、`flutter: ^3.41.0`。 + 出處: +- 限制:analysis-server 形式的工具「只在規劃中」(README 原文:"planned for the future")。 +- **查不到**:官方頁面沒有明文寫「extension 必須 debug/profile build」。這個結論是從 build-modes 頁(VM Service / service extensions 僅 debug、profile)+ `requiresConnection` 推得,屬強推論而非原文。 + +--- + +## 4. 桌面「選資料夾」與監看檔案變更 + +### 版本 + +| 套件 | latest | 發布日 | 出處 | +|---|---|---|---| +| `file_selector` | 1.1.0 | 2025-11-21 | | +| `file_picker` | 13.1.0 | 2026-09-15 | | +| `watcher` | 1.2.1 | 2026-01-08 | | + +### file_selector(flutter.dev) + +- 平台最低需求(README 支援矩陣,1.1.0 版):Android SDK 21+、iOS 12+、Linux Any、macOS 10.14+、Web Any、Windows 10+。 + 出處:(README 表格;main 分支 README 已改成 SDK 24+/iOS 13+/macOS 10.15+,屬尚未發佈版本) +- API:`openFile`、`openFiles`、`getSaveLocation`、`getDirectoryPath`(另有 `getDirectoryPaths`)。 +- 功能矩陣: + +| 功能 | Android | iOS | Linux | macOS | Windows | Web | +|---|---|---|---|---|---|---| +| 選單一檔案 | 可 | 可 | 可 | 可 | 可 | 可 | +| 選多個檔案 | 可 | 可 | 可 | 可 | 可 | 可 | +| 選儲存位置 | × | × | 可 | 可 | 可 | × | +| 選資料夾 | 可 | × | 可 | 可 | 可 | × | + + 出處: +- macOS 需 sandbox entitlement(`com.apple.security.files.user-selected.read-only` 或 `read-write`)。 +- 型別過濾跨平台不一致(`extensions` 不支援 Web;`mimeTypes` 不支援 Windows/iOS,macOS 需 Big Sur+;`uniformTypeIdentifiers` 只有 iOS/macOS;`webWildCards` 只有 Web),傳錯會 `ArgumentError`。 + 出處:同上 README #L93-L107 + +### file_picker(現由 vicajilau 維護) + +- 平台:Android, iOS, Linux, macOS, Web, Windows(各自有 platform package:`android_file_picker`、`file_picker_darwin`、`file_picker_linux`、`file_picker_web`、`windows_file_picker`)。 + 出處: +- API 矩陣: + +| API | Android | iOS | Linux | macOS | Windows | Web | +|---|---|---|---|---|---|---| +| `pickFile()` / `pickFiles()` | 可 | 可 | 可 | 可 | 可 | 可 | +| `saveFile()` | 可 | 可 | 可 | 可 | 可 | 可 | +| `getDirectoryPath()` | 可 | 可 | 可 | 可 | 可 | × | +| `pickFileAndDirectoryPaths()` | × | × | × | 可 | × | × | +| `clearTemporaryFiles()` | 可 | 可 | × | × | × | × | + + 出處: +- 沒有叫 `pickFolder` 的 API;選資料夾就是 `getDirectoryPath()`。 +- v13 起 `androidSafOptions` 併入統一的 `androidOptions` / `FilePickerAndroidOptions`。 + 出處:同上 README #L68-L70 +- iOS 需 14.0+(用 `PHPickerViewController`)。 + +### watcher(dart-lang/tools) + +- 純 Dart 套件(pubspec 只有 `sdk: ^3.8.0`,無 `flutter` 欄位);平台標示 Android, iOS, Linux, macOS, Windows。repo 主線版本為 `1.2.2-wip`。 + 出處:、 +- `DirectoryWatcher` 的平台分派: + - 有 custom watcher 先用; + - Linux → `LinuxDirectoryWatcher`(走 VM 原生 watcher,即 inotify;有 `WatchTree` 處理 directory move 問題); + - macOS → `RecursiveDirectoryWatcher(runInIsolate: false)`(底層 `Directory.watch(recursive: true)`,即 FSEvents); + - Windows → `RecursiveDirectoryWatcher(runInIsolate: true)`(同 `Directory.watch(recursive: true)`,即 ReadDirectoryChangesW;`runInIsolateOnWindows: false` 可關掉 isolate 以減少 buffer exhaustion); + - 其餘(含 `isWatchSupported == false`)→ `PollingDirectoryWatcher`(預設 1 秒輪詢)。 + 出處:、`.../recursive/recursive_native_watch.dart#L14`、`.../linux/native_watch.dart#L12-L40` +- 限制:Linux 是 inode 導向,directory 被搬移時會誤判成 delete 並關閉 watch(原始碼註解明列三種問題,無法復原,只能重新列目錄)。 + 出處:同上 linux/native_watch.dart #L13-L40 +- 未在 web 可用(用 `dart:io` 的 `Platform` / `FileSystemEntity`)→ **推測**。 + +### file_picker 在 Android 選資料夾 + 讀取其中 JS 檔(SAF 限制) + +以下是查到的硬事實: + +1. **選資料夾可行**:`getDirectoryPath()` 走 `ACTION_OPEN_DOCUMENT_TREE`。 + 出處:(`Intent.ACTION_OPEN_DOCUMENT_TREE`) +2. **回傳值是「真路徑」或「content:// tree URI」二選一**: + - 沒帶 SAF options 時,file_picker 用 `getFullPathFromTreeUri` 把 tree URI 轉成檔案系統路徑(`/storage//`;`primary` → `Environment.getExternalStorageDirectory()`)。**該函式只處理 external storage 類 volume**;`parts.size <= 1` 或非 Downloads 的 provider 會回 `null` → 上層回錯誤 `unknown_path`。 + - 帶 `FilePickerAndroidOptions(safOptions: ...)` 時,**直接回 content:// URI 字串**(`finishWithSuccess(data.data.toString())`),不做路徑轉換。 + 出處:FileUtils.kt #L110-L128、#L807-L825、#L828-L855 +3. **SAF grant 選項(v13)**:`AndroidSAFOptions(grant: transient | lifetime, accessMode: readOnly | readWrite, persistGrant: bool = true)`。只有 `grant: lifetime` 且 `persistGrant` 為 true 時才會呼叫 `takePersistableUriPermission`;**預設是 `transient`,不會 persist**。 + 出處:、FileUtils.kt #L72-L94 +4. grant 生命週期(Android 官方):SAF 預設 URI 授權**只到裝置重開機為止**;`takePersistableUriPermission()` 後可跨重開機存活,但文件被移動或刪除就失效。ACTION_OPEN_DOCUMENT_TREE 從 API 21+ 可用,授權整個目錄樹(含子目錄);Android 11+ 不能要求內部儲存根目錄、reliable SD 卡根目錄、`Download` 目錄,也不能從 `Android/data` / `Android/obb` 選檔案。persisted grant 有數量上限(Android 官方頁未寫數字;file_picker issue #1825 稱 API 30+ 為 512、舊版 128)。 + 出處:、(已由 PR #1989 實作,即 v13 的 SAF options) +5. **選「檔案」時,Android 端會把檔案複製到 app cache 再回傳該路徑**:`openFileStream` 把 content:// 內容寫到 `cacheDir/file_picker//`,`PlatformFile.path` 指向這個複本(另有 `uri` 與 `safHandle`)。`AndroidPlatformFile.readAsBytes()` 讀的是這個 cache 複本。 + 出處:FileUtils.kt #L741-L805、 +6. **scoped storage**:Android 11 起(targetSdk ≥ 30)direct file path 存取只對 media 檔案開放(`File` / `fopen` 可讀 media);非 media 的任意檔案要靠 MediaStore、SAF,或申請 `MANAGE_EXTERNAL_STORAGE`("all files access",需 `Environment.isExternalStorageManager()` 且上架 Google Play 受政策限制:僅限檔案管理、備份還原、防毒、文件管理等核心用途)。`ACTION_OPEN_DOCUMENT_TREE` 的授權本身不會因 `MANAGE_EXTERNAL_STORAGE` 而增加能力。 + 出處:、 +7. `getDirectoryPath()` 只回一個路徑 / URI,**file_picker 沒有提供「列出被授權目錄樹內檔案」或「用 SAF URI 讀檔」的 Dart API**;Dart 的 `dart:io` `File` 不能開 `content://` URI。 + 出處:API 矩陣(同 #3 節 file_picker README)、`file_picker_android.dart` 公開方法僅 `pickFile`/`pickFiles`/`pickFileAndDirectoryPaths`/`getDirectoryPath`/`clearTemporaryFiles`/`saveFile`/`releaseSAFGrant`();`dart:io` 不支援 content:// 屬 Dart/Android 平台事實 → 前半為事實、結論為 **推測**。 + +**綜合結論(Android 選資料夾讀 JS 檔)**:能「選到資料夾」(拿真路徑或 content:// tree URI),但**用 file_picker 單獨讀取該資料夾內任意 `.js` 檔並不成立**——沒帶 SAF 時拿到的真路徑在 scoped storage 下對非 media 檔案通常不可直接讀(除非有 `MANAGE_EXTERNAL_STORAGE`);帶 SAF 時拿到 content:// URI,但要靠額外 SAF/content resolver 能力才能列目錄與讀檔(file_picker 沒提供)。此段為 **推測**(由 #5 #6 #7 交叉推得,未實機驗證)。 + +--- + +## 5. log 檔輪替 + +### 三個套件對「檔案輸出與輪替」的原生支援 + +| 套件 | latest | 發布日 | 檔案輸出 | 輪替 | +|---|---|---|---|---| +| `logging` | 1.3.0 | 2024-10-17 | **無**(只提供 `onRecord` stream,輸出全自理;README 範例就是 `print`) | **無** | +| `talker` | 5.1.20 | 2026-07-28 | **無**(README 只講 console / in-memory history / TalkerScreen UI / observer;沒有 file output、沒有 rotation) | **無** | +| `logger` | 2.8.0 | 2026-09-05 | **有**:`FileOutput`、`AdvancedFileOutput` | **有**(僅 `AdvancedFileOutput`,依大小) | + +出處:、、;(onRecord)、(無 file 段) + +### logger 的細節 + +- `FileOutput`(基本款):ctor 只有 `{required File file, bool overrideExisting = false, Encoding encoding = utf8}` —— **沒有**任何輪替參數。 + 出處: +- `AdvancedFileOutput`(有輪替):ctor 參數 + `path`(必填)、`overrideExisting=false`、`encoding=utf8`、`fileHeader`、`fileFooter`、`writeImmediately`(列出的 level 立即 flush)、`maxDelay=2s`、`maxBufferSize=2000`、`maxFileSizeKB=1024`、`latestFileName='latest.log'`、`fileNameFormatter`、`maxRotatedFilesCount`(預設 null = 不刪)、`fileSorter`、`fileUpdateDuration=1min`。 + 出處: +- 輪替機制:`_updateTargetFile()` 每 `fileUpdateDuration` 檢查,當前檔 `length() > maxFileSizeKB * 1024` 時把 `latest.log` rename 成 `fileNameFormatter(now)`(預設 `2024-01-01-10-05-02-123.log` 這種全日期名),再刪多餘輪替檔、重新開 sink。**只依大小**(`maxFileSizeKB > 0` 才啟用輪替模式;設 0 則不輪替)——**沒有**依日期切檔的原生開關(日期只體現在輪替後的檔名)。 + 出處:advanced_file_output.dart #L129、#L131-L147、#L156-L174、#L197-L214 +- 寫檔有緩衝(預設 2 秒 flush 一次,或 buffer 滿 2000 筆,或命中 `writeImmediately` 的 level)。 +- `logger` 的 Windows 換行處理:`Platform.isWindows ? '\r\n' : '\n'`(advanced_file_output.dart #L191)。 + +### talker 若要檔案輪替 + +- 核心 `talker` 沒有;社群擴充 **`talker_persistent` 3.0.0+5(2026-05-27)** 提供:寫入輪替文字檔(`maxFileSizeMb` 預設 5.0,超過後「刪掉最舊一半的 entries」)、`saveAllLogs: true` 時檔名 `logName-YYYY-MM-DD.log` 並依 `retentionDays`(預設 3)刪舊檔、另可存 Hive(`maxCapacity` 預設 1000)、`bufferSize` 預設 100(0 = 立即寫)、`flushOnError`。平台 Android, iOS, Linux, macOS, Windows。 + 出處:、 +- 提醒:這是社群套件(repo `eduardohr-muniz/talker_persistent`),非 talker 官方 repo(talker 作者 frezycode.com)。**推測**:維護狀況未查。 + +### 生態常見輪替慣例(依官方文件可證者) + +- `logging` 的做法:只給你 `onRecord`,實務上自己接 listener 開 `File` / `openWrite()`,輪替自己實作或交給別的套件(README 明講輸出全自理)。 + 出處: +- `talker` 的建議做法:實作 `TalkerObserver`(override `onError` / `onException` / `onLog`)把 log 導去別處;README 舉 Crashlytics / Sentry / Grafana 為例,自寫檔案 observer 同一套路。 + 出處: +- `logger` 是三者中唯一有內建 size-based rotation 的(`AdvancedFileOutput`)。 + +--- + +## 6. 分享與匯出 + +### share_plus + +- latest = **13.3.0**(2026-07-23),publisher flutter.dev;平台 Android, iOS, Linux, macOS, Web, Windows。 + 出處: +- 內容支援矩陣(README): + +| 內容 | Android | iOS | macOS | Web | Linux | Windows | +|---|---|---|---|---|---|---| +| Text | 可 | 可 | 可 | 可 | 可 | 可 | +| URI | 可 | 可 | 可 | As text | As text | As text | +| Files | 可 | 可 | 可 | 可 | × | 可 | + + 出處:(Platform Support 表) +- **桌面行為(關鍵)**: + - **Windows**:Win10 RS5(build 17763)以上時註冊 C++ plugin,用 `DataTransferManager` + `ShowShareUIForWindow(GetWindow())` 開**Windows 分享飛出視窗**(不是檔案總管);檔案透過 `SetStorageItemsReadOnly` 帶入。**RS5 以下**走 Dart fallback:用 `mailto:`(url_launcher)**只能分享文字**,`params.files` 非空會 throw `UnimplementedError`。 + 出處:、、#L190-L199 + - **Linux**:只用 `mailto:`(url_launcher_linux)分享文字;`params.files` 非空 throw `UnimplementedError('Sharing files not supported on Linux')`。**不會**開檔案總管。 + 出處: + - **macOS**:走 `NSSharingServicePicker`(native share sheet)。 + 出處:、#L54-L60 + - **Android / iOS**:`ACTION_SEND` / `UIActivityViewController` 原生分享對話框(非檔案總管)。 +- API:`SharePlus.instance.share(ShareParams(text: ..., files: [XFile(...)]))`;舊的 `Share.share()` / `Share.shareXFiles()` 已 deprecated。`XFile.fromData` 需用 `fileNameOverrides`(`name` 在多数平台被忽略);`XFile.fromData` 會寫 temp 檔到 cache,需自行清理。 +- 其他限制:iPad 建議帶 `sharePositionOrigin`(否則 popover 置中;舊版可能 crash);無法辨識使用者動作的平台回 `ShareResultStatus.unavailable`;對 Facebook 系 app 的圖片+文字分享不可靠(官方明說相關 bug 會直接關閉)。 + 出處: + +### file_selector 的「另存新檔」(`getSaveLocation`) + +- 支援平台:**Linux / macOS / Windows 可;Android / iOS / Web ×**(見第 4 節功能矩陣)。 +- 用法:`final FileSaveLocation? result = await getSaveLocation(suggestedName: 'name.txt');` → 使用者取消回 `null` → 自己把內容寫到 `result.path`(例:`XFile.fromData(...).saveTo(result.path)`)。 + 出處: +- 1.1.0 新增 `canCreateDirectories` 參數(控制使用者在選位置時能否建目錄)。 + 出處: +- 各平台底層是**原生儲存對話框**: + - Windows:`IFileOpenDialog`(`file_dialog_controller.cpp`)。 + 出處:、#L46-L47 + - Linux:GTK `GTK_FILE_CHOOSER_ACTION_SAVE`。 + 出處: + - macOS:`NSSavePanel`(`runModal` / `beginSheetModal`)。 + 出處:、#L157-L167> +- macOS 另需 sandbox entitlement(見第 4 節)。 + +--- + +## 查不到 / 不確定的點 + +- **查不到**:官方明文寫「DevTools extension 僅限 debug/profile build」。此結論是從 build-modes 的 VM Service / service extensions 限制推得。 +- **推測**:drift DevTools extension 在 profile build 可用(drift 的 `_enable` 只看 `dart.vm.product`,profile 有 VM Service;但無官方確認)。 +- **推測**:drift_devtools extension 在 web 上匯出資料庫會失敗(`platform_unsupported` 分支)。 +- **推測**:`watcher` 不支援 web(用 `dart:io`)。 +- **推測**:Android「選資料夾後用 file_picker 讀取其中 .js」不成立(由 cache 複製行為、scoped storage、缺 Dart 端 SAF 讀取 API 交叉推得,未實機驗證)。 +- **推測**:`drift_db_viewer` 定位為開發期工具(README 只說用在 dev app,未明講 release 行為)。`talker_persistent` 的維護狀況未查。 +- 未查:`drift_db_inspector` / `saropa_drift_advisor` / `local_database_visual_debugger` / `drift_devtools` 的原始碼與平台限制(僅取 pub.dev 描述)。 diff --git a/.trellis/tasks/09-28-design-debug-page/research/prior-art.md b/.trellis/tasks/09-28-design-debug-page/research/prior-art.md new file mode 100644 index 000000000..025e28326 --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/research/prior-art.md @@ -0,0 +1,721 @@ +# prior-art + +查證日:2026-09-28 + +查證方式: +- 第一部分(成熟 App 的內建除錯工具):`gh api` 取固定 commit SHA 的原始碼(permalink)、 + 官方文件與官方網頁;未實際執行任何 App。 +- 第二部分(Flutter 生態的除錯套件與插件開發者工具):`https://pub.dev/api/packages/`(版本/發佈日) + 與 `/score`(分數/likes/下載量)、context7、官方文檔、`gh api`(固定 commit SHA permalink)。 + +本檔分兩部分。第一部分是 9 個成熟 App 的內建除錯工具;第二部分是 Flutter 生態的 App 內除錯套件, +以及插件/腳本開發者工具的先例。各部分保留自己的標記說明、SHA 對照與「查不到/推測」附錄。 + +--- + +## 第一部分:成熟 App 的內建除錯工具 + + +### 標記說明 + +- 每一條事實後面以 `()` 標出來源;GitHub 一律用固定 40 字元 commit SHA 的 permalink,網頁用 URL。 +- `**推測**`:原始碼或文件只給出間接線索,結論是我從現有證據推出來的,不是原文直述。 +- 「查不到」:在該專案預設分支的原始碼與可見文件中找不到對應實作或頁面,不代表該版本一定沒有。 +- 文中不出現任何實際的 cookie / token / key 值;若來源範例含有這類值,一律以 `***` 表示。 + +### 目標清單與 SHA + +| App | repo | commit SHA | +|---|---|---| +| NewPipe | TeamNewPipe/NewPipe | `7e5df38aad4b2c035332b3f71aee3064d4fdaae4` | +| Immich mobile | immich-app/immich | `aa023378477fb1a65d24f4614de0940f6a769794` | +| AppFlowy | AppFlowy-IO/AppFlowy | `5cf3a365dec0d59f64bad1ee4bb1050471a39b93` | +| LocalSend | localsend/localsend | `6f6cd3ee496903e2206c51ffa3a13a5d10bc340b` | +| Spotube | KRTirtho/spotube | `69a310c78f5ceaf4eab7dfee98f187d38211c9ba` | +| Namida | namidaco/namida | `acb1e1622600440cc793f389f497e6771c732c5e` | +| Firefox Android(fenix) | mozilla-firefox/firefox | `b478a70dbe9b20189bb57f12c05bc0d6a8f323bd` | +| Signal Android | signalapp/Signal-Android | `6151a523373e02f37d6a367fe448bd15a3de1a72` | +| Home Assistant companion | home-assistant/android | `47e0f53ac9f96f8002e0f022df7c28ee1c24a06a` | + +--- + +### NewPipe + +**入口與啟用**:Debug 是**主設定頁的一般可見項目**,不是隱藏入口、也沒有 build flag 守門。`main_settings.xml` L56-61 的 ``;字串 `settings_category_debug_title` 值為 `Debug`(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/xml/main_settings.xml、https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/values/strings.xml)。同時在 `SettingsResourceRegistry` 以 `add(DebugSettingsFragment.class, R.xml.debug_settings).setSearchable(false)` 註冊,因此**不出現在偏好搜尋結果**(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/settings/SettingsResourceRegistry.java)。 + +**有哪些區塊**:`debug_settings.xml` 是單一 PreferenceScreen;`DebugSettingsFragment` 提供開關與動作兩類(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/settings/DebugSettingsFragment.java、https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/res/xml/debug_settings.xml): + +- 開關:allow heap dumping、show memory leaks、allow disposed exceptions、show original time ago、show crash the player。 +- 動作:check new streams(`NotificationWorker.runNow`)、crash the app(`throw new RuntimeException("Dummy")`)、show error snackbar、create error notification。 + +**LeakCanary 的 build 相依**:透過 build-variant-dependent(BVD)介面 `DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI`,由實作類別以 `Class.forName(...)` 反射載入;`DebugSettingsBVDLeakCanary.java` 只存在於 `app/src/debug/` source set,內容是把 `getNewLeakDisplayActivityIntent()` 轉呼叫 `LeakCanary.INSTANCE.newLeakDisplayActivityIntent()`(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/debug/java/org/schabi/newpipe/settings/DebugSettingsBVDLeakCanary.java)。實作類別不存在時,相關偏好以 summary `leak_canary_not_available` 呈現(停用)。`app/src/` 下的 source set 為 `androidTest`、`debug`、`main`、`test`。 + +**Log 檢視**:查不到 app 內 log viewer(無 live 串流、level 篩選、搜尋或條目上限的實作)。 + +**網路檢視**:查不到 HTTP request 檢視頁。 + +**狀態檢視**:查不到即時播放/佇列狀態面板;Debug 頁只有開關與觸發動作。 + +**Export / Share**:主要落在錯誤流程 `ErrorActivity`(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.kt): + +- 顯示欄位:user action、request、content language/country、app language、service、timestamp(ISO8601 帶 offset)、package、version、OS,以及 stack traces。 +- 按鈕:email(`mailto:crashreport@newpipe.schababi.org`)、複製 markdown 到剪貼簿(`ShareUtils.copyToClipboard(this, buildMarkdown())`)、開 GitHub issue 頁;選單「share error」以 `ShareUtils.shareText` 分享 JSON。`buildMarkdown()` 產生 GitHub issue 用 markdown,多個 exception 用 `
    ` 折疊。 +- 觸發鏈:`AcraReportSender` 把 ACRA 的 stack trace 交給 `ErrorUtil.openActivity(context, new ErrorInfo(new String[]{report.getString(ReportField.STACK_TRACE)}, UserAction.UI_ERROR, "ACRA report", null, R.string.app_ui_crash))`(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/AcraReportSender.java);`ErrorUtil` 另有 `showSnackbar`、`createNotification`(id 5340681,靜音+toast)與前景/背景判斷(`KEY_IS_IN_BACKGROUND`)(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt)。 + +**遮蔽(Redaction)**:查不到自動 redaction 機制;email/GitHub 送出前有一個隱私政策對話框作為告知 gate(https://github.com/TeamNewPipe/NewPipe/blob/7e5df38aad4b2c035332b3f71aee3064d4fdaae4/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.kt)。 + +--- + +### Immich mobile + +**入口與啟用**:profile drawer 的一列 ListTile(`Icons.assignment_outlined`,label `profile_drawer_app_logs`)→ `context.pushRoute(const AppLogRoute())`(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart L103-109、L290)。路由以 `AutoRoute(page: AppLogRoute.page, guards: [_duplicateGuard])` 註冊,`AppLogDetailRoute` 同(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/routing/router.dart L135-136)。 + +**有哪些區塊**:App log 頁、App log detail 頁、app bar server info(app version+build、server version、server URL、version warning banner)、settings 的 sync status 頁(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/pages/common/app_log.page.dart、https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/pages/common/app_log_detail.page.dart、https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/widgets/common/app_bar_dialog/app_bar_server_info.dart、https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/pages/settings/sync_status.page.dart)。 + +**Log 檢視**:`AppLogPage` 讀 `LogService.I.getMessages()`;level 以顏色點表示(info=primary、severe=redAccent、warning=orangeAccent、其他=grey),tile 背景依 level 上色;每筆顯示 `at HH:mm:ss.SSS in `,訊息經 `truncateLogMessage(msg, 4)`,點擊進入 detail。detail 頁分 MESSAGE / DETAILS / FROM(logger)/ STACK TRACE 四段,每段一個複製 IconButton(`Clipboard.setData` + snackbar `copied_to_clipboard`),文字用 `SelectableText`。頁面動作:clear logs(`immichLogger.clearLogs()`)、share(`ImmichLogger.shareLogs`)。 + +**條目上限與 level 來源**:`LogService` 包 dart `logging`,監聽 `Logger.root.onRecord`,先緩衝進 `LogRepository`(DB),5 秒 flush timer;init 時 `logRepository.truncate(limit: kLogTruncateLimit)`;docstring 說超過 `maxLogEntries`(預設 500)會刪舊。level 取自設定 `SettingsKey.logLevel`,`Logger.root.level = Level.LEVELS.elementAtOrNull(...)`;`getMessages()` 回 `[..._msgBuffer.reversed, ...logsFromDb]`(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/domain/services/log.service.dart)。`kLogTruncateLimit` 的實際數值查不到。 + +**匯出檔案**:`ImmichLogger.shareLogs(context)` 寫 `${tempDir}/Immich_log_$isoDateTime.log`,行格式 `created | level(padRight 8) | logger(padRight 20) | message | error |` 後接 stack,再用 `Share.shareXFiles([XFile(filePath)], subject: "Immich logs $dateTime")`,分享完刪檔。docstring 稱格式為 CSV,但程式實際寫的是純文字行(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/services/immich_logger.service.dart)。 + +**網路檢視**:查不到 HTTP request 檢視頁;`network.service.dart` 只處理 Wi-Fi 名稱與權限(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/services/network.service.dart)。 + +**狀態檢視**:sync status 頁顯示 entity counts,並有三個動作(https://github.com/immich-app/immich/blob/aa023378477fb1a65d24f4614de0940f6a769794/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart):export database(WAL checkpoint 後複製 `immich.sqlite` → `immich_export_$ts.sqlite`,`Share.shareXFiles`,30 秒後自動刪)、clear file cache、reset SQLite DB(附確認對話框)。 + +**遮蔽**:查不到。 + +--- + +### AppFlowy + +**入口與啟用**:行動版 Settings → Support 群組;桌面版 Settings → Manage data(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/mobile/presentation/setting/support_setting_group.dart、https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_manage_data_view.dart)。桌面 Settings 對話框本體已 import `share_log_files.dart`(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart)。 + +**有哪些區塊**: + +- mobile Support 群組:Join Discord、Report issue(bottom sheet 內含「Report issue on GitHub」連結與「Export log files」→ `shareLogFiles(context)`)、Clear cache(呼叫 `WorkspaceDataManager.checkViewHealth(dryRun: false)`)。 +- desktop Manage data:export data、`FixDataWidget`、SettingsCategory「Export log files」(用 `shareLogFiles`)。 + +**Log 檢視**:查不到 app 內 log 檢視頁(無 live、level、篩選、搜尋)。 + +**匯出**:`shareLogFiles(context)` 遞迴列 `getApplicationSupportDirectory()` 下 basename `startsWith('log.')` 的檔,用 `archive` 的 `ZipEncoder` 打包成 `appflowy_logs.zip`;Android/iOS 以 `Share.shareXFiles` / `Share.shareUri` 分享後刪檔;桌面以 `afLaunchUri` 開資料夾;沒有檔案時 toast `noLogFiles`(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/util/share_log_files.dart)。 + +**網路檢視**:查不到。 + +**狀態檢視**:查不到即時狀態面板(`checkViewHealth` / `FixDataWidget` 是資料修復動作,不是狀態呈現)。 + +**遮蔽**:查不到。 + +**除錯基礎設施(非使用者可見頁面)**:`DebugTask` 用 `talker` + `talker_bloc_logger`,只在 `kDebugMode` 設 `Bloc.observer = TalkerBlocObserver(...)`,行動版 debug 時隱藏鍵盤,rust tracing 被註解掉(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/debug_task.dart);`platform_error_catcher.dart` 只在非 debug 掛 `PlatformDispatcher.instance.onError`,`ErrorWidget.builder` 在 debug 顯示紅橫幅、release 回 `SizedBox.shrink()`(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/startup/tasks/platform_error_catcher.dart)。`shared/feedback_gesture_detector.dart` 的 `FeedbackGestureDetector` 只做 haptics,**推測**與除錯入口無關(https://github.com/AppFlowy-IO/AppFlowy/blob/5cf3a365dec0d59f64bad1ee4bb1050471a39b93/frontend/appflowy_flutter/lib/shared/feedback_gesture_detector.dart)。 + +--- + +### LocalSend + +**入口與啟用**:About 頁一個純 TextButton「Debugging」→ `context.push(() => const DebugPage())`;**無 `kDebugMode` 守門**,一般使用者可達(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/about/about_page.dart L168-173)。 + +**有哪些區塊**:`DebugPage`(標題 `Debugging`):DebugEntry 列(Debug Mode=`kDebugMode`、Portable Mode、Executable Path、Working Directory、Settings Path、App Arguments、Dart SDK=`Platform.version`)+按鈕 Security、Discovery、HTTP Logs、Refena Tracing(僅 `if (kDebugMode)`)、Clear settings(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/debug/debug_page.dart)。 + +**Log 檢視**: + +- HTTP Logs:`HttpLogsPage` 監看 `httpLogsProvider`,有「Clear」按鈕;清單項為 `CopyableText`,行首 `[HH:mm:ss] ` 綠色粗體(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/debug/http_logs_page.dart)。 +- Discovery:`DiscoveryDebugPage` 監看 `discoveryLoggerProvider`,按鈕「Announce」(`StartMulticastScan`)+「Clear」,同樣 `[HH:mm:ss]` 清單(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/debug/discovery_debug_page.dart)。 +- 條目上限:`addLog` 做 `[...state, LogEntry(now, log)].take(200).toList()` → **上限 200 筆**;無 level、無搜尋、僅存記憶體(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/provider/logging/http_logs_provider.dart、https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/provider/logging/discovery_logs_provider.dart)。`LogEntry{DateTime timestamp, String log}`(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/model/log_entry.dart)。 + +**網路檢視**:有 —— HTTP Logs 頁(見上)。`addLog` 的呼叫點在 `nearby_devices_provider.dart` 與 `receive_controller.dart`(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/provider/network/nearby_devices_provider.dart、https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/provider/network/server/controller/receive_controller.dart)。 + +**狀態檢視**:查不到即時播放/連線狀態面板。 + +**匯出/分享**:清單項可逐筆複製(`CopyableText`);`troubleshoot_page.dart` 的排解卡(症狀/解法,含 Windows 防火牆 `netsh advfirewall` 指令且可複製)(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/troubleshoot_page.dart)。查不到整批檔案匯出。 + +**遮蔽**:查不到;`SecurityDebugPage` 直接顯示 Certificate SHA-256 fingerprint、Certificate、Private Key、Public Key 的原始值,未見遮蔽(https://github.com/localsend/localsend/blob/6f6cd3ee496903e2206c51ffa3a13a5d10bc340b/app/lib/pages/debug/security_debug_page.dart)。 + +--- + +### Spotube + +**入口與啟用**:Settings → Developers 區塊的單一 ListTile「Logs」→ `context.navigateTo(const LogsRoute())`;`settings.dart` 以 `if (!kIsWeb) const SettingsDevelopersSection()` 掛載(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/settings/sections/developers.dart、https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/settings/settings.dart)。 + +**有哪些區塊**:只有 Logs 一頁。 + +**Log 檢視**:`LogsPage`(`@RoutePage`,name `logs`)讀 `logsProvider`(`StreamProvider.autoDispose`,逐行讀 `.spotube_logs` 檔),body 是 Card 內 `SelectableText(value)`,空狀態 `no_logs_found`(Undraw 插圖)(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/settings/logs.dart、https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/provider/logs/logs_provider.dart)。無 level 篩選、無搜尋、無條目上限的實作。 + +**寫入端**:`AppLogger`(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/logger/logger.dart): + +- `initialize(bool verbose)` 設 `Logger(level: kDebugMode || (verbose && kReleaseMode) ? Level.all : Level.info)`;`main.dart` 以 CLI 參數呼叫 `AppLogger.initialize(arguments["verbose"])`(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/main.dart L66)。 +- `_initInternalPackageLoggers()` 只在 `kDebugMode`(橋接 `YoutubeExplode.StreamsClient`)。 +- `runZoned` 掛 `FlutterError.onError`、`PlatformDispatcher.instance.onError`、isolate 錯誤監聽;`reportError` **只在 `kReleaseMode`** 追加寫檔。 +- log 路徑:Android `getExternalStorageDirectory()`;Windows/macOS `getApplicationDocumentsDirectory()` 或 `Library/Logs`;Linux `$XDG_STATE_HOME/spotube` 或 `~/.local/state/spotube`;檔名 `.spotube_logs`。 +- `AppLoggerProviderObserver` 上報 provider 失敗。 + +**網路檢視**:查不到;`services/dio/dio.dart` 的 `final globalDio = Dio();` 沒有掛 interceptor,因此沒有 HTTP log(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/services/dio/dio.dart)。`collections/http-override.dart` 只對 `spotify.com` 放行壞憑證(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/collections/http-override.dart)。 + +**狀態檢視**:查不到。 + +**匯出/分享**:頁面 trailing 動作:複製全部到剪貼簿(`Clipboard.setData` + toast `copied_to_clipboard`)、垃圾桶 → `ref.invalidate(logsProvider)` 並 `logsFile.writeAsString("")`。查不到檔案分享(https://github.com/KRTirtho/spotube/blob/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/lib/pages/settings/logs.dart)。 + +**遮蔽**:查不到。 + +--- + +### Namida + +**入口與啟用**:About 頁的 `NamidaAboutListTile(icon: Broken.clipboard_text, title: lang.shareLogs)`,另附一個寄送按鈕(email 經 `FlutterMailer.send`,遇 `MissingPluginException` 退回 `NamidaUtils.shareFiles`);`onTap` → `shareFiles(filePaths)`;同頁另有 reportAnIssue 對話框(`_IssueReporter`)(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/ui/pages/about_page.dart L425-451)。 + +**有哪些區塊**:無獨立 log 檢視頁;除錯相關面有三個 —— About 頁的 share logs、Sync manager 頁的 diagnostics 與 actions log、Advanced 設定內的快取清除對話框。 + +**Log 檢視**:查不到 app 內 log viewer(無 live、level、篩選、搜尋頁)。 + +**Log 寫入**:`logs_controller.dart` 的 singleton `logger` 以 `RandomAccessFile` append 寫入 `AppPaths.LOGS` / `LOGS_FALLBACK`;條目以 FNV hash(error 內容+前 8 個 stack frame,`_keyStackFrames = 8`)去重,stack 截到 `_maxStackFrames = 48`;重複次數以 `x0001`–`x9999` 就地 patch;`kDebugMode` 時另 `printo`(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/logs_controller.dart)。 + +**匯出**:`AppPaths.getAllExistingLogsAndSettingsAsZip()` 在 temp 建 `namida_logs_`,複製 `device_info.txt`、`permissions.txt`(Linux 略過),以及 `AppPaths.LOGS`、`LOGS_FALLBACK`、`LOGS_TAGGER` 的遮蔽副本(`_LogsRedactor`),再加 `_writeAllSettingsRedacted`(settings、equalizer、player、youtube、extra、sync、party、tutorial、shortcuts),打包成 `namida_logs_.zip`。`LOGS` = `$USER_DATA/Logs/logs.txt`;`LOGS_FALLBACK` Android `/storage/emulated/0/Documents/namida_logs.txt`,Windows/Linux `/Logs/namida_logs.txt` 或 systemTemp(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/core/constants.dart L686 起、L955)。 + +**遮蔽**:`_LogsRedactor` 把 home 目錄換成 `~`,並 `removeExcludedDeviceInfo`(同上,`lib/core/constants.dart`)。 + +**網路檢視**:查不到 HTTP request 檢視頁。 + +**狀態檢視**:`SyncDiagnostics.run()` 產生文字報告:`namida | | sync v`;區段 `== interfaces ==`(LAN/preferred/virtual roles)、`== server ==`(tcp addr:port、advertising IPs、client count)、`== windows network ==`(PowerShell `Get-NetConnectionProfile` / `Get-NetFirewallApplicationFilter`)、`== linux firewall ==`、`== discovery ==`;`_kMaxTraceLines = 200`(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/controller/sync_manager/sync_diagnostics.dart)。呼叫點在 Sync manager 頁 app bar 動作:`_openRecentActionsLog()`(`SyncActionsLog.inst`)、`_openDiagnosticsDialog()`(`_SyncDiagnosticsDialog`)、`_openConnectByIpDialog()`(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/ui/pages/sync_manager_page.dart)。 + +**設定入口**:`settings_page.dart` 的 sections 為 Theme、Indexer、Playback、Customization、YouTube、Extras、BackupAndRestore、AdvancedSettings;L324 `const NamidaSyncManagerPage().navigate()`(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/ui/pages/settings_page.dart)。`advanced_settings.dart` 對 log / debug / diagnos / copy / export / clipboard 的 grep 無命中,只有快取刪除對話框(https://github.com/namidaco/namida/blob/acb1e1622600440cc793f389f497e6771c732c5e/lib/ui/widgets/settings/advanced_settings.dart)。 + +--- + +### Firefox Android(fenix) + +**入口與啟用**: + +- Nightly:三點選單 → Settings → About Firefox Nightly → 連點 Firefox logo 直到出現 `Debug menu: (#) click(s) left to enable` → 回 Settings 就多出「Secret Settings」與「Secret Debug Info」(https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/docs/Secret-settings-debug-menu-instructions.md)。 +- 觸發器實作:`SecretDebugMenuTrigger`,**5 次點擊**啟用(`SECRET_DEBUG_MENU_CLICKS = 5`),第 2–4 次回報剩餘次數,`onResume` 時把計數歸零(https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/about/SecretDebugMenuTrigger.kt)。 +- 另有 build 期開關:`local.properties` 的 `secretSettings.=true`,只作用於 debug build、只接受 boolean(同上 docs)。 + +**有哪些區塊**:`debugsettings/` 套件目錄含 addons、addresses、autofill、cfrs、crashtools、creditcards、data、distributions、gleandebugtools、info、integrity、ipprotection、listentopage、logins、navigation、region、store、tabprocesstools、tabs、ui。`DebugDrawerRoute.kt` 枚舉的工具:TabTools、Logins、Addresses、CreditCards、Autofill、CfrTools、GleanDebugTools、RegionDebugTools、AddonsDebugTools、CrashDebugTools、IntegrityTools、TabGroupTools、TabProcessTools、DistributionTools、IPProtectionLocationTools、ListenToPageTools(https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/navigation/DebugDrawerRoute.kt)。 + +**UI 形式**:`DebugDrawer.kt` 是 Compose NavHost drawer(`DEBUG_DRAWER_HOME_ROUTE`,TopAppBar 返回鍵);`DebugDrawerHome.kt` 以 LazyColumn 列出各 destination 並帶 app 名稱/版本表頭;`DebugOverlay.kt` 是可拖曳 FAB overlay,呈現 app-wide debug 內容(https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugDrawer.kt、https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/DebugOverlay.kt)。 + +**Log 檢視**:查不到 app 內 log viewer。 + +**網路檢視**:查不到 HTTP request 檢視頁。 + +**狀態/資訊檢視**:`DebugInfoRepository.kt` 的區段(https://github.com/mozilla-firefox/firefox/blob/b478a70dbe9b20189bb57f12c05bc0d6a8f323bd/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/info/DebugInfoRepository.kt): + +- Build:Version、VCS Commit、GeckoView、Application Services、Glean SDK、Build Date。 +- Device:Android、Manufacturer、Model、Locale。 +- Configuration:Telemetry、Crash reporting 的狀態徽章。 +- Nimbus experiments:active experiment slug / branch。 +- Homepage:feature 狀態。 +- Toolbar:position、expanded、tab strip。 + +DSL 為 `buildSection(title) { textItem(label, value); statusItem(label, enabled) }`;`DebugInfoJson.kt` 用 `JsonWriter`(縮排 3 空白)把 `List.toJson()` 轉成 JSON;`DebugInfoContent.kt` 是區段檢視加一顆 `OutlinedButton("debug_info_view_json_report")`;`DebugInfoJsonReport.kt` 是 JSON 報告頁(`SelectionContainer` + Header 複製);`DebugInfoBottomSheetFragment.kt` 用 `DebugInfoProvider.create(settings, nimbusApi, versionName, deviceLocale, secretSettingsKeys)`,版本字串格式 `"%s (Build #%s)"`(同目錄 `DebugInfoDsl.kt`、`DebugInfoJson.kt`、`ui/DebugInfoContent.kt`、`ui/DebugInfoJsonReport.kt`、`DebugInfoBottomSheetFragment.kt`)。 + +**匯出/分享**:查不到檔案匯出;JSON 報告頁可選取複製(同上)。 + +**遮蔽**:查不到。 + +**Nightly-only 與否**:文件把入口寫在 Nightly,但**推測** release / beta 是否同樣可啟用未逐條確認。 + +--- + +### Signal Android + +**入口與啟用**:Settings → Help 的 `HelpSettingsFragment` 有一列 `HelpSettingsFragment__debug_log`,導向 `action_helpSettingsFragment_to_submitDebugLogActivity`;同頁 Version 長按可複製到剪貼簿並 toast(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt)。其他啟動點:`calls/quality/CallQualityBottomSheetFragment`、`database/IssueReporter`、`messages/GroupSendEndorsementInternalNotifier`、`registration/fragments/RegistrationViewDelegate`、`registration/ui/shared/RegistrationScreen`、`mediapreview/MediaPreviewViewModel`。`HelpScreen.kt` L239-247 另有 `Checkbox(checked = state.includeDebugLog)` + 「include debug log」標籤 + 「What's this」TextButton(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/help/HelpScreen.kt)。 + +**有哪些區塊**:`SubmitDebugLogActivity` 內以 WebView 呈現(`DebugLogsViewer`)(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java)。 + +**Log 檢視**:搜尋(含大小寫敏感切換 `filterButton` / `isFiltered`)、level 篩選按鈕 **V / D / I / W / E / SignalUncaughtException**(組出 `[" V "," D ",...]` 形式的 filter string 傳給 `DebugLogsViewer.onFilterLevel`)、scroll-to-top / bottom。內容可能很慢時會先跳警告對話框(同上)。 + +**內容來源**:`SubmitDebugLogRepository` 的有序 `SECTIONS`:SystemInfo、Jobs、Constraints、Capabilities、Memory、LocalMetrics、RemoteConfig、Pin、Power(API≥28)、Battery、Notifications、NotificationProfiles、ExoPlayerPool、KeyPreferences、Stories、Badges、ChatFolders、RemoteBackups、Permissions、Trace、Threads、SuspiciousThreadDump、CurrentThreadDump、SenderKey(internal 才含)、DatabaseSchema、RemappedRecords、DatabaseIssues、Anr、Logcat、LoggerHeader;每段內容都先過 `Scrubber.scrub(...)`(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogRepository.java)。 + +**匯出/分享**:menu save → `Intent.ACTION_CREATE_DOCUMENT`,type `application/zip`,檔名 `signal-log-.zip`(zip 內含 `log.txt` + `signal.trace`);submit → `viewModel.onSubmitClicked(...)` → 結果對話框顯示可複製的 debuglogs.org URL + 分享(`ShareCompat.IntentBuilder` 到 `support@signal.org`)。上傳到 `https://debuglogs.org`(先 GET 取 presigned multipart,再 POST),body 為 GZIP。帶 `ARG_VIEW_ONLY` 時 submit 按鈕改成關閉(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogActivity.java)。 + +**遮蔽**:`Scrubber.kt` 以 regex 處理下列樣式(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/core/util-jvm/src/main/java/org/signal/core/util/logging/Scrubber.kt): + +- E164 電話號碼:以 HMAC-SHA256 雜湊成 `<8 hex>`(`KEEP_E164::` 前綴者保留原樣)。 +- 前導零的 10 位數字。 +- email(`...@...`)。 +- group IDs v1 / v2、PNI、UUID(`********-****-****-****-*********`)。 +- IPv4(`...ipv4...`)、IPv6(`...ipv6...`)。 +- URL:host+path → `***.`,用 TOP_100_TLDS allowlist;例外保留原樣者為非 cdn 的 `*.signal.org` 與 `*.debuglogs.org`。 +- call link keys、call link room IDs、MediaIds。 + +**容量**:`LogDatabase.kt` 定義 `MAX_FILE_SIZE = 20L.mebiBytes`、`DEFAULT_LIFESPAN = 3.days`、`LONGER_LIFESPAN = 21.days`;`trimToSize()` 先扣掉 `KEEP_LONGER = 1` 的量再裁,crash 用的 `trimToSize()` 刪 30 天以上(https://github.com/signalapp/Signal-Android/blob/6151a523373e02f37d6a367fe448bd15a3de1a72/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt L176-178)。 + +**網路檢視**:查不到 HTTP request 檢視頁。 + +--- + +### Home Assistant companion + +**入口與啟用**:Settings 的 ``(`preferences.xml` L224-228);`SettingsFragment.kt` L390 以 `findPreference("developer")` → `replace(R.id.content, DeveloperSettingsFragment::class.java)`。可見、非隱藏(https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/res/xml/preferences.xml、https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/kotlin/io/homeassistant/companion/android/settings/SettingsFragment.kt)。 + +**有哪些區塊**:`DeveloperSettingsFragment` → `preferences_developer.xml`(https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/kotlin/io/homeassistant/companion/android/settings/developer/DeveloperSettingsFragment.kt、https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/res/xml/preferences_developer.xml): + +- `show_share_logs`(「Show and share logs」)→ `replace(R.id.content, LogFragment::class.java)`。 +- `location_tracking`:僅 `BuildConfig.FLAVOR == "full"` 時存在。 +- `webview_debug`(`remote_debugging`):由 `DeveloperSettingsPresenterImpl` 的 `PreferenceDataStore` 接到 `WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG || value)`。 +- `thread_debug`:`presenter.appSupportsThread()` 為真才顯示,多 server 時先走 `ServerChooserFragment`。 +- `tag_clear_allowed`、`webview_clear_cache`。 + +**Log 檢視**:`LogFragment` 兩個 tab:process log(`LogcatReader.readLog()`,即時讀)與 crash log(`getLatestFatalCrash`);有 refresh 與 share 選單;另連到 FAQs#android-crash-logs 的說明連結(https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/kotlin/io/homeassistant/companion/android/settings/log/LogFragment.kt)。 + +**Logcat 讀取**:`LogcatReader.kt` 用 `ProcessBuilder("logcat", "--pid=$pid", "-d")`,一次把輸出讀成一個 String;**無條目上限、無 level 篩選、無搜尋**(https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/kotlin/io/homeassistant/companion/android/util/LogcatReader.kt)。 + +**網路檢視**:查不到 HTTP request 檢視頁。 + +**狀態檢視**:查不到即時狀態面板(thread sync debug 只呈現同步結果)。 + +**匯出/分享**:`shareLog()` 先跳敏感資料 AlertDialog,字串 `share_logs_sens_message` 原文為 `Please note: by sharing the log, you could share sensitive data like location data or your Home Assistant URL.\n\nDo you want to continue?`;確認後寫 `/logs/homeassistant_companion_log_MM-DD-YYYY_HH-MM-SS.txt`,經 FileProvider 以 `Intent.ACTION_SEND` type `text/plain` 分享,並以 `EXTRA_EXCLUDE_COMPONENTS` 排除 `com.github.android`(GitHub app)(https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/app/src/main/kotlin/io/homeassistant/companion/android/settings/log/LogFragment.kt、https://github.com/home-assistant/android/blob/47e0f53ac9f96f8002e0f022df7c28ee1c24a06a/common/src/main/res/values/strings.xml L824-825)。 + +**遮蔽**:只有分享前的警示對話框;查不到自動 redaction 實作。 + +--- + +### 跨對象對照(僅事實,不含建議) + +| 面向 | 有實作者 | +|---|---| +| HTTP request 檢視頁 | LocalSend(HttpLogsPage);其餘 8 個查不到 | +| app 內 log 檢視頁 | immich(AppLogPage/AppLogDetailPage)、Spotube(LogsPage)、Signal(SubmitDebugLogActivity + WebView)、HA(LogFragment);LocalSend 為 HTTP/Discovery 專用清單 | +| 有 level 篩選 | immich(顏色標示,非篩選按鈕)、Signal(V/D/I/W/E + SignalUncaughtException 篩選按鈕) | +| 有 log 搜尋 | Signal(含大小寫切換) | +| 明示條目/檔案上限 | LocalSend 200 筆(記憶體)、immich `maxLogEntries` 預設 500 + `kLogTruncateLimit`、Signal `MAX_FILE_SIZE` 20 MiB | +| 以檔案分享 | immich(shareXFiles)、AppFlowy(zip)、Namida(zip + email)、Signal(zip 存檔 + 上傳 debuglogs.org)、HA(txt 分享)、LocalSend 查不到 | +| 只有剪貼簿 | Spotube(複製全部)、NewPipe(複製 markdown) | +| 自動 redaction | Signal(`Scrubber` 最完整)、Namida(`_LogsRedactor` 換 home 為 `~`) | +| 僅告知/警示 | HA(分享前 AlertDialog)、NewPipe(隱私政策對話框) | +| 查不到 redaction | immich、AppFlowy、Spotube、LocalSend、Firefox | +| 隱藏入口手勢 | Firefox(logo 連點 5 次);其餘皆為可見設定項或頁面按鈕 | +| 隱藏入口無 build 守門 | LocalSend(About 頁 TextButton) | +| 需要 build flag 的功能 | NewPipe(LeakCanary 僅 `debug` source set)、Firefox(`secretSettings.*` 僅 debug build)、LocalSend(Refena Tracing 僅 `kDebugMode`) | + +--- + +## 第二部分:Flutter 生態的除錯套件與插件開發者工具 + + +### A. Flutter 生態的 App 內除錯套件 + +套件版本/發佈日一律取自 `https://pub.dev/api/packages/`(`latest.version` / `latest.published`), +分數/likes/下載量取自 `https://pub.dev/api/packages//score`。 +GitHub 狀態取自 `gh api repos/OWNER/REPO` 與 `gh api repos/OWNER/REPO/commits?per_page=1`。 +程式碼引用一律用固定 commit SHA 的 permalink(`/blob/<40 碼 SHA>/path#Lnn`)。 + +#### 總表(皆為 pub.dev API 查詢結果) + +| 套件 | 版本 | 發佈日(UTC) | pub 分數 | likes | 30 天下載 | 平台標籤 | +|---|---|---|---|---|---|---| +| talker | 5.1.20 | 2026-07-28T20:30:11 | 160/160 | 859 | 279142 | 六平台 + wasm | +| talker_flutter | 5.1.20 | 2026-07-28T20:30:22 | 160/160 | 665 | 224239 | 六平台 + wasm | +| talker_dio_logger | 5.1.20 | 2026-07-28T20:30:31 | 160/160 | 150 | 153895 | 六平台 + wasm | +| alice | 1.10.0 | 2026-09-18T10:14:52 | 160/160 | 348 | 27591 | 六平台 + wasm | +| flutter_flipper | 0.0.2 | 2022-05-05T09:55:44 | 25/160 | 0 | 24 | **is:discontinued / is:unlisted** | +| inspector | 4.0.0 | 2026-03-30T07:22:58 | 150/160 | 87 | 496649 | 六平台 + wasm | +| requests_inspector | 5.5.1 | 2026-08-16T12:19:08 | 130/160 | 167 | 6407 | **僅 android + ios** | +| chucker_flutter | 1.9.2 | 2026-05-14T09:51:50 | 130/160 | 197 | 18896 | 六平台 | +| drift_db_viewer | 2.1.0 | 2024-04-08T19:22:05 | 130/160 | 106 | 21078 | 六平台 + wasm | +| isar_inspector | 3.1.0+3 | 2023-05-15T07:46:48 | 60/160 | 0 | 0 | **is:unlisted** | +| flutter_js | 0.8.7 | 2026-01-27T20:22:28 | 140/160 | 360 | 103466 | 五平台(無 web) | +| flutter_qjs | 0.3.7 | 2022-05-19T17:04:46 | 60/160 | 31 | 86 | 無平台標籤;sdk `<3.0.0` | + +(talker 三套件同分鐘發佈,屬同一 monorepo;授權皆 MIT。alice 為 apache-2.0。 +inspector 的 30 天下載 496649 與 likes 87 的比例明顯異常,**推測**為統計口徑或自動化下載所致,查不到解釋。) + +--- + +#### talker / talker_flutter / talker_dio_logger + +- **版本/日期**:三者皆 5.1.20,2026-07-28T20:30(pub.dev API,如上表)。 + 授權 MIT。`talker_flutter` 要求 `sdk >=3.6.0 <4.0.0`、`flutter >=1.17.0`。 +- **平台**:android / ios / linux / macos / web / windows 全列,並標 `is:wasm-ready`。 +- **維護狀態**:repo `Frezyx/talker` 未 archived、MIT、846 stars、96 open issues。 + 預設分支最後 commit `654391c1a81c6a0fa4a05d46562cc0d15241d964`(2026-07-28、"Release v5.1.20"), + 但 repo `pushed_at` 為 2026-09-24,晚於預設分支最後 commit,**推測**為其他分支的推送。 +- **功能**:`Talker` 本體是 error handler + logger(`talker.handle` / `info` / `error` / `critical`); + `talker_flutter` 提供 `TalkerScreen` —— 在 app 內檢視 log、篩選、執行動作、調整設定, + 以及 log history(可設定最大保留筆數)、console 輸出開關、report 分享。 + `talker_dio_logger` 是 Dio interceptor,把 HTTP 呼叫導進同一條 log 流。 +- **是否可以只在 debug/developer 模式啟用(release 是否剝離)**: + **套件本身沒有內建 build-mode 閘門。** + 在預設分支以 `gh search/code` 查 `kReleaseMode` 與 `kDebugMode` 皆 0 筆 + (對照查詢:`TalkerScreen` 34 筆、可證明搜尋 API 正常運作,故 0 筆為真)。 + README 完全未提 release 模式下的行為;`TalkerScreen` 是開發者自己 push 的 widget: + `Navigator.of(context).push(MaterialPageRoute(builder: (context) => TalkerScreen(talker: talker)))`。 + context7 條目 `/frezyx/talker`(316 snippets)同樣只示範自行 push,未提 release。 + `TalkerDioLoggerSettings` 有 `enabled`(預設 `true`)與 print 旗標,屬執行期開關而非編譯期閘門。 + +#### alice + +- **版本/日期**:1.10.0,2026-09-18T10:14:52(pub.dev API)。授權 apache-2.0,publisher `hasoft.pl`。 + `sdk >=3.13.0 <4.0.0`、`flutter >=3.29.0`(門檻相當新)。 + pub.dev 上 1.4.0 → 1.10.0 一系列版本集中在 2026-09-15~09-18 之間發佈(快速補版)。 +- **平台**:六平台全列,標 `is:wasm-ready`。 +- **維護狀態**:repo `jhomlala/alice` 未 archived、636 stars、1 open issue, + 最後 commit `2943b1901aec10cbeed82e57d6cb9a3122a25304`(2026-09-18、 + "feat: Add programmatic call tagging and N+1 duplicate detection (#327)")。 + GitHub API 的 `license` 欄位為 `null`(pub.dev 標 apache-2.0)。 +- **架構**:monorepo 多套件:`alice`、`alice_dio`、`alice_http`、`alice_http_client`、 + `alice_chopper`、`alice_graphql_client`、`alice_objectbox`、`alice_test` + —— 讓使用者只拉自己 HTTP client 對應的那一個。 +- **功能**:HTTP 呼叫列表、單筆 request/response 詳情、JSON tree viewer、 + timeline(Gantt 時間軸)、統計 dashboard、N+1 重複呼叫偵測、程式化 tag(`alice.tag(...)`)、 + 請求重送(replay)、搖一搖開啟、通知開啟、匯出 TXT/HAR、以 ObjectBox 持久化歷史。 +- **release 是否剝離**:**沒有 inspector 的 build-mode 閘門。** + repo 內唯一用到 `kReleaseMode` 的地方是 + [`packages/alice/lib/src/utils/utils.dart#L7`](https://github.com/jhomlala/alice/blob/2943b1901aec10cbeed82e57d6cb9a3122a25304/packages/alice/lib/src/utils/utils.dart#L7), + 用途僅是抑制 `debugPrint`: + ```dart + import 'package:flutter/foundation.dart' show kReleaseMode, debugPrint; + class AliceUtils { + static void log(String logMessage) { + if (!kReleaseMode) { + debugPrint(logMessage); + } + } + } + ``` + 它不影響 inspector UI 是否掛載 —— 閘門要由 app 自己加。 +- **context7**:**查不到** `jhomlala/alice` 條目。`resolve-library-id` 對 "Alice" 只回傳無關的同名套件 + (Go middleware `/justinas/alice`、PHP fixtures `/nelmio/alice`、Yandex Alice 等),故 alice 的 + 敘述全部來自 pub.dev API 與 GitHub 原始碼/README。 + +#### flutter_flipper 與 inspector + +兩者常被放在同一格討論,但性質差很多,分開列。 + +**flutter_flipper**(舊路線,已死) +- **版本/日期**:0.0.2,2022-05-05T09:55:44(pub.dev API)。pub 標記 **`is:discontinued` 與 `is:unlisted`**, + 分數 25/160、likes 0、30 天下載 24。`sdk: 2.14.3`(精確釘死,非範圍)、`flutter >=2.5.2`。 +- **維護狀態**:repo `lwj1994/flutter_flipperkit` 未 archived 但實質停擺:1 star、0 open issues, + 最後 commit `66678eea25b815bb912498e9b7d8c57bad69033f`(2022-05-05、"Remove db and sp plugin")。 +- **上游**:`facebook/flipper` 本身**已 archived**(`gh api` `archived: true`)、13452 stars、 + 506 open issues、最後 commit `13f95a067f56bb3772937a8f281b0a7eacda7080`(2025-09-26、 + "reroute public download to github releases (#5722)")。 + **事實**:Flipper 桌面平台已終止,Flutter 綁定套件隨之無維護。 + +**inspector**(現行,純 widget 檢視器) +- **版本/日期**:4.0.0,2026-03-30T07:22:58(pub.dev API)。MIT,150/160,六平台 + wasm, + `sdk >=2.12.0 <4.0.0`、`flutter >=3.22.0`。 +- **維護狀態**:repo `kekland/inspector` 未 archived、60 stars、9 open issues, + 最後 commit `60f989097f168e384a93b7e738665109d8f8ee2c`(2026-03-30)。 + README 自述仍在開發中(WIP)。 +- **功能**:掛在 `MaterialApp.builder` 上的 widget 檢視器 —— widget 尺寸/padding/ + 顏色/TextStyle 檢視、縮放、鍵盤快捷鍵。**不涵蓋網路或 DB**,與 alice 那類 HTTP inspector 定位不同。 +- **release 是否剝離**:**有內建 build-mode 閘門。** README 原文: + > Optionally, you can pass `isEnabled` to the `Inspector` to disable it. + > By default, the inspector is disabled when `kReleaseMode == true`. + +#### requests_inspector + +- **版本/日期**:5.5.1,2026-08-16T12:19:08(pub.dev API)。MIT。130/160、likes 167、30 天下載 6407。 + `sdk >=2.17.0 <4.0.0`、`flutter >=1.20.0`。 +- **平台**:pub.dev 平台標籤**只有 `platform:android` 與 `platform:ios`**。 + README 卻記載 Web / Windows / MacOS / Linux 可用長按開啟 —— 兩者不一致(**事實陳述,未找到官方解釋**)。 +- **維護狀態**:repo `Abdelazeem777/requests_inspector` 未 archived、MIT、21 stars、14 open issues, + 最後 commit `8c08c212e7b59d5c017564cbca5c886f52caa897`(2026-08-16、"chore: Release version 5.5.1")。 +- **功能**:HTTP + GraphQL + WebSocket log、請求中止器(可編輯後重送)、 + 以 Log / cURL / HAR 格式分享。 +- **release 是否剝離**:**沒有 build-mode 閘門。** repo 內 `kReleaseMode` / `kDebugMode` 皆 0 筆。 + 掛載方式與預設值見 + [`lib/src/requests_inspector_widget.dart#L99`](https://github.com/Abdelazeem777/requests_inspector/blob/8c08c212e7b59d5c017564cbca5c886f52caa897/lib/src/requests_inspector_widget.dart#L99): + ```dart + const RequestsInspector({ + super.key, + bool enabled = true, // 預設開啟 + bool hideInspectorBanner = false, + ShowInspectorOn showInspectorOn = ShowInspectorOn.Both, + required Widget child, + }); + ... + bool _isSupportShaking() => + kIsWeb ? false : Platform.isAndroid || Platform.isIOS; + ``` + 即 `enabled` 預設 `true`,且沒有 `kDebugMode` 之類的編譯期判斷;觸發方式依平台決定為搖晃或長按。 + +#### chucker_flutter + +- **版本/日期**:1.9.2,2026-05-14T09:51:50(pub.dev API)。MIT。130/160、likes 197、30 天下載 18896。 + `sdk >=3.0.0 <4.0.0`。平台標籤六平台全列。 +- **維護狀態**:repo `syedmurtaza108/chucker-flutter` 未 archived、MIT、84 stars、26 open issues, + 最後 commit `1ecae1b90430e7260516dc4179882a10657c9fcc`(2026-06-30), + repo `pushed_at` 2026-09-24(晚於預設分支最後 commit)。 +- **功能**:HTTP 呼叫列表、依狀態碼篩選、request/response 詳情、錯誤檢視、可由通知列開啟。 + Android 需 `minSdkVersion 22`。 +- **release 是否剝離**:**有內建 build-mode 閘門。** 見 + [`lib/src/view/helper/chucker_ui_helper.dart#L189`](https://github.com/syedmurtaza108/chucker-flutter/blob/1ecae1b90430e7260516dc4179882a10657c9fcc/lib/src/view/helper/chucker_ui_helper.dart#L189): + ```dart + ///[showOnRelease] decides whether to allow Chucker Flutter working in release + ///mode or not. By default its value is `false` + static bool showOnRelease = false; + ///[isDebugMode] A wrapper of Flutter's `kDebugMode` constant + static bool isDebugMode = kDebugMode; + static final chuckerButton = (isDebugMode || ChuckerFlutter.showOnRelease) + ? ChuckerButton.getInstance() + : const SizedBox.shrink(); + ``` + README 原文: + > By default Chucker Flutter only runs in `debug` mode but you can allow it to run + > in release mode too using its `showOnRelease` property + + 整合方式需提供 `ChuckerFlutter.navigatorKey`(舊的 `navigatorObserver` 因 nested Navigator 已 deprecated)。 + +#### drift_db_viewer + +- **版本/日期**:2.1.0,2024-04-08T19:22:05(pub.dev API)。MIT。130/160、likes 106、30 天下載 21078。 + `sdk >=2.13.0 <4.0.0`、`flutter >=2.2.0`。平台標籤六平台 + wasm。 + **2.1.0 已約 2.5 年沒有新版**(但 repo 仍有 commit)。 +- **維護狀態**:repo `vanlooverenkoen/db_viewer` 未 archived、47 stars、15 open issues, + 最後 commit `775d1597326f86950b6f8c551f339ea40818c4a8`(2026-02-06、 + "Fix horizontal scrolling on non-touch devices (#61)")。GitHub `license` 欄位為 `null`。 +- **功能/用法**:`DriftDbViewer(GeneratedDatabase db)` 是一個 StatefulWidget, + `initState` 內 `DriftDbViewerDatabase.init(widget.db)`,build 出 `DbViewerNavigator`; + pubspec 依賴 `db_viewer: ^1.1.0`、`drift: >=2.0.0 <3.0.0`、`provider: >=6.0.0 <7.0.0`。 + README 原文: + > view our database in our development app without the need of exporting your database file. + > Filtering is done at database level +- **release 是否剝離**:**沒有 build-mode 閘門**(README 以 "development app" 描述用途)。 +- **適用範圍(事實)**:只支援 drift 的 `GeneratedDatabase`。 + FMP 的 DB 是 Isar(`pubspec.yaml` L18-19:`isar_community: ^3.3.2`、`isar_community_flutter_libs: ^3.3.2`), + 因此 **drift_db_viewer 不適用於 FMP**。 + +#### isar_inspector + +- **版本/日期**:3.1.0+3,2023-05-15T07:46:48(pub.dev API)。 + pub 標記 **`is:unlisted`**(已下架),分數 60/160、likes 0、30 天下載 0。 + 授權 apache-2.0。`sdk >=2.17.0 <4.0.0`(Dart 3 可解析,但仍未更新)。 + 依賴:`isar ^3.1.0+1`、`vm_service ^9.0.0`、`web_socket_channel ^2.2.0`、 + `go_router ^5.0.0`、`google_fonts ^4.0.4`、`http ^0.13.6`、`universal_io`、`flutter_svg any`。 +- **現況(repo `isar/isar`,最後 commit `713001bf1615ea15460d9bc8d3fb9c8cb4150a2e` 2025-06-14, + Apache-2.0、4023 stars、185 open issues)**: + `packages/isar_inspector/pubspec.yaml` 已標 `publish_to: "none"`、version 1.0.0+1、 + `go_router: ^15.1.2`、`vm_service: ^15.0.0`、`web: ^1.1.1`、`flutter_riverpod`, + 且有 `web/index.html` 與 `web/manifest.json` → 已改成 **Flutter web app**。 +- **運作模型**:`packages/isar_inspector/lib/main.dart` L28 路由為 `/:port/:secret`, + L18-19 歡迎字串原文: + > Welcome to the Isar Inspector! + > Please open the link displayed when running the debug version of an Isar app. + + → inspector 是獨立的 web 前端,透過 port + secret 連到 app;該連結**只在 app 的 debug build 印出**, + 這是此生態「只在 debug 可用」的實際機制。 +- **release 是否剝離**:repo 內 `kDebugMode` 0 筆(`gh search/code`)。 + 閘門不在 inspector 端,而在 app 端(debug 才印出連線連結)。 +- **查不到**:isar.dev 官方文檔的 inspector 頁面目前 404,**無法確認現行官方 inspector 說明頁 URL**。 +- **上游警語**:`isar` README 原文: + > ISAR V4 IS NOT READY FOR PRODUCTION USE + > If you want to use Isar in production, please use the stable version 3. + +--- + +### B. 插件/腳本開發者工具的先例 + +#### MusicFree(maotoumao/MusicFree) + +- **基本資料**:React Native;AGPL-3.0;27160 stars;281 open issues;預設分支 `master`; + 最後 commit `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee`(2026-06-20、"修复:稳定性与跨平台优化"); + repo `pushed_at` 2026-09-13。 +- **插件形態**:單一 CommonJS `.js` 檔。App 啟動時掃描固定資料夾;官方文檔站 + (musicfree.catcat.work)載明路徑: + Android `Android/data/fun.upup.musicfree/files/plugins`; + 桌面 `C://Users/{userName}/AppData/Roaming/MusicFree/musicfree-plugins`。 + 安裝時把 js 寫入該資料夾並以隨機檔名儲存;`platform` 相同時比較 `version`, + **較舊版本不會覆蓋較新版本**(要先解除安裝)。 +- **載入與沙箱**(`src/core/pluginManager/plugin.ts`,1121 行): + - `_require`(L69):只暴露固定的純 JS 套件表 —— `axios`、`cheerio`、`dayjs`、 + `big-integer`、`qs`、`he`、`cookies`、`webdav`、`crypto-js`、`nanoid`、`immer`、 + `object-path`、`compare-versions`、`react-native-url-polyfill` 等。插件無法自行 `require` 任意模組。 + - `_consoleBind`(L75):把插件的 `console` 導向自建 devLog。 + - `mountPlugin()`(L905)以 `new Function(...)` 包裹插件碼,注入 + `(require, __musicfree_require, module, exports, console, env, URL, process)`; + 見 [L934-949](https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/core/pluginManager/plugin.ts#L934): + ```ts + _instance = Function(` + 'use strict'; + return function(require, __musicfree_require, module, exports, console, env, URL, process) { + ${funcCode} + } + `)(_require, _require, _module, _module.exports, _console, env, URL, _process); + ``` + - 生命週期狀態機(Initializing / Loading / Error);`loadFuncCode()` 搭配 `ensureMounted()`(L890)延遲載入。 +- **App 內除錯面板**:`src/components/debug/index.tsx` 原文: + ```tsx + const showDebug = useAppConfig("debug.devLog"); + return showDebug ? ( + + ) : null; + ``` + `VDebug` 來自 vendored 的 `@/lib/react-native-vdebug`(React Native 的 in-app log/網路面板), + 由 app config `debug.devLog` 開關。 +- **檔案日誌**(`src/utils/log.ts`):用 `react-native-logs` + `fileAsyncTransport`, + 寫出 `error-log-{date-today}.log` 與 `trace-log.log`;`trace()` 由 + `Config.getConfig("debug.traceLog")` 控制;`addLog`(來自 react-native-vdebug)另外餵面板。 + `src/core/appConfig.ts` 把舊鍵映射到 `debug.errorLog` / `debug.traceLog` / `debug.devLog`。 +- **官方插件開發文檔章節**(文檔站):`introduction`、`basic-type`、`protocol`、 + `how-to-develop`、`how-to-develop-with-ai`、`internal-pkgs`、`caution`。 + 文檔把「除錯」寫成「在 Node.js 環境執行插件函式並檢查回傳值」;只允許純 JS 函式庫 + (不可有原生依賴)。**未見 devtools 或熱重載機制**。 +- **註記**:網路上大量 MusicFree 插件教學是 AIGC 生成且互相抄襲,內容與原始碼不符; + 本文只採 GitHub 原始碼(固定 SHA)與官方文檔站。 + +#### LX Music(lyswhut/lx-music-desktop、lx-music-mobile) + +- **基本資料**: + - `lyswhut/lx-music-desktop`:Apache-2.0、54016 stars、1282 open issues、 + 最後 commit `ad95d5091c9ed689fa72b5e5c849df65f5a679ce`(2026-09-19、"发布 v2.12.6"); + Electron 30+ / Vue 3。 + - `lyswhut/lx-music-mobile`:Apache-2.0、18469 stars、781 open issues、 + 最後 commit `fb8480728d875fa5e0da25eebd3a26bb71723aae`(2026-09-19、"发布 v1.9.1");React Native。 + - `lyswhut/lx-music-source`:MIT、401 stars、1 open issue、 + 最後 commit `55eb9881dad6ca895505352f3a0a7d1dfa3444e0`(2024-06-12、"修复kw url获取") + —— 自訂源腳本的 webpack 專案模板(`src/` + `dist/` + `webpack.config.js`)。 +- **自訂源介面**(官方文檔 https://lxmusic.toside.cn/desktop/custom-source): + 腳本為 UTF-8 JavaScript(ES6+),需 `@name / @description / @version / @author / @homepage` + 頭部註解。與 app 以事件溝通: + - `inited`:payload `{ sources, openDevTools }`,文檔原文「`openDevTools`:是否打开 DevTools, + 此选项可用于开发脚本时的调试」→ **每個自訂源可選擇開啟 DevTools 除錯**。 + - `request`:handler `({ source, action, info })` 必須回傳 Promise;action 為 + `musicUrl` / `lyric` / `pic`。 +- **執行模型(desktop)**:每個 user API 跑在**獨立的隱藏 Electron BrowserWindow**, + 見 `src/main/modules/userApi/main.ts`(155 行): + - `createWindow()`(L58):先 `await closeWindow()`,再建 + [BrowserWindow](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/userApi/main.ts#L58), + `webPreferences` 為 `contextIsolation: true`(L84)、`nodeIntegration: false`、 + `nodeIntegrationInWorker: false`、`sandbox: false`(L88)、自訂 preload; + 對 `will-navigate` / `will-redirect` / `will-attach-webview` / `will-prevent-unload` / + `media-started-playing` 一律 `preventDefault`。 + 以 `loadURL('data:text/html;charset=UTF-8,' + encodeURIComponent(html))`(L123)載入空白頁, + 再於 `ready-to-show` 送出 `initEnv`(含 `script: await getScript(userApi.id)` 與 proxy)。 + - `closeWindow()`(L134):清除 auth cache / storage / cache 後 `browserWindow.destroy()`。 + - `openDevTools()`(L151):對該 window 的 `webContents` 開 DevTools。 +- **重新載入模型**(`src/main/modules/userApi/index.ts`): + [`setApi(id)`](https://github.com/lyswhut/lx-music-desktop/blob/ad95d5091c9ed689fa72b5e5c849df65f5a679ce/src/main/modules/userApi/index.ts#L24)(L24) + 若已有作用中的 api 先 `closeWindow()`(L25-27)再 `loadApi(id)`(L32);`removeApi` 同樣關窗。 + → **切換/重新匯入自訂源 = 拆掉整個 JS runtime 再重建**,沒有原地熱重載; + `inited` 事件的 `openDevTools` 是唯一內建除錯入口。 + +#### VS Code extension host 的 reload + +- **架構**:extension host 是獨立程序,三種形態 —— local(Node.js)、web(WebWorker)、 + remote(Node.js)。官方頁面 `advanced-topics/extension-host` 只講這三種 host 的設定, + **未描述任何 reload 指令或熱重載**。 +- **官方開發流程**(`api/get-started/your-first-extension`):F5 啟動 Extension Development Host 視窗; + 改完擴充程式碼後,在該視窗執行 **「Developer: Reload Window」** 即可讓改動生效,再重跑命令。 + 該頁**未提及「Restart Extension Host」**,也**未描述熱重載**(查不到官方對熱重載的說明)。 +- **原始碼**(`microsoft/vscode` @ `acfc00a9e482b98f6383b4e69ba3dd771cce02b1`): + - 字串 `restartExtensionHost` 出現 11 次,含 + [`src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts#L296`](https://github.com/microsoft/vscode/blob/acfc00a9e482b98f6383b4e69ba3dd771cce02b1/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts#L296) + (`await extensionService.stopExtensionHosts(localize('restartExtensionHost.reason', "Changing workspace folders"))`) + 與 `src/vs/workbench/contrib/extensions/browser/extensionsActions.ts`。 + - 指令 ID 字面值 `workbench.action.restartExtensionHost` 只出現在 3 個檔案 + (含 `src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts` 與 + copilot 擴充),而 `workbench.action.reloadWindow` 出現 15 處 + (含 `src/vs/workbench/browser/actions/windowActions.ts`、 + `src/vs/workbench/electron-browser/actions/developerActions.ts`)。 + - `ExtensionMode` enum 定義於 + [`src/vs/workbench/api/common/extHostTypes.ts#L2719`](https://github.com/microsoft/vscode/blob/acfc00a9e482b98f6383b4e69ba3dd771cce02b1/src/vs/workbench/api/common/extHostTypes.ts#L2719); + `ExtensionMode.Development` 用於從開發路徑(`--extensionDevelopmentPath`)載入的擴充。 + +#### 從資料夾載入腳本並熱重載的一般做法 + +**Flutter 熱重載的限制**(官方 docs.flutter.dev/tools/hot-reload,原文節錄): +- 「**Only Flutter apps in debug mode can be hot reloaded or hot restarted.**」→ 熱重載/熱重啟僅限 debug。 +- 「it doesn't rerun `main()` or `initState()`」。 +- 「Global variables and static fields are treated as state, and are therefore not reinitialized + during hot reload」。 +- 失敗案例包含:更動 enum 型別、更動泛型宣告、原生程式碼變更(需整支重啟)等。 + +**release 剝離的語言機制**:`kDebugMode` / `kReleaseMode` / `kProfileMode` 是 `const bool`, +值來自 `bool.fromEnvironment('dart.vm.product' | 'dart.vm.profile')`。 +`packages/flutter/lib/src/foundation/constants.dart`(flutter @ `43596b3519f61ebd934229bb72c712caaefe6a9b`) +dartdoc 原文: +> Since this is a const value, it can be used to indicate to the compiler that a particular +> block of code will not be executed in release mode, and hence can be removed. + +dartdoc 亦註明一般建議改用 `kDebugMode` 或 `assert`,因為 `kReleaseMode` 會引入 release/profile 差異。 +→ 這是把整段除錯碼從 release 產物移除的既有機制。 + +**Dart `Isolate.spawnUri` 與 AOT**: +- API 文檔(`api.dart.dev/stable/dart-isolate/Isolate/spawnUri.html`)**未寫** AOT 限制。 +- `dart-lang/sdk` issue #54528(已關閉)原文: + > `spawnUri` throws an exception in AOT mode if `jit-snapshot`, `kernel` or a dart library + > were given (e.g. ```The uri provided to Isolate.spawnUri() does not contain a valid AOT snapshot.```) +- SDK 測試 [`runtime/tests/vm/dart/spawn_uri_aot_test.dart`](https://github.com/dart-lang/sdk/blob/815bb2e3dd88f9b6325615aaa6f338886b94dab6/runtime/tests/vm/dart/spawn_uri_aot_test.dart) + (dart-lang/sdk @ `815bb2e3dd88f9b6325615aaa6f338886b94dab6`)顯示 AOT runtime 在 `isAOTRuntime` 下 + 可以 spawn 已編譯 `.dill` / AOT snapshot 的 isolate。 +- → **AOT 下 spawnUri 必須指向合法的 AOT snapshot,不能餵原始 `.dart` 或 kernel。** + +**嵌入 JS 引擎(flutter_js)**: +- 版本 0.8.7,2026-01-27T20:22:28(pub.dev API);MIT;140/160;likes 360;30 天下載 103466; + 平台 android / ios / linux / macos / windows(無 web);`sdk >=3.0.0 <4.0.0`。 + repo `abner/flutter_js`:MIT、542 stars、81 open issues、 + 最後 commit `c3d4bba92278577c6cc73e7b10a69b358f23768b`(2026-01-27、"fix performance issue in toUTF8")。 +- 引擎配置(README):**Android / Windows / Linux 用 QuickJS;iOS / macOS 用 JavaScriptCore**。 +- 抽象介面 `JavascriptRuntime`(`lib/javascript_runtime.dart`)提供: + `dispose()`、`evaluate(String code, {String? sourceUrl})`、`evaluateAsync`、 + `setInspectable(bool)`、`setupBridge(String channelName, void Function(dynamic) fn)`、 + `getEngineInstanceId()`、`executePendingJob()`、`convertValue()`;入口 `getJavascriptRuntime()`。 +- iOS JS 除錯(README):`javascriptRuntime.setInspectable(true)`,並對 `evaluate` 傳入 `sourceUrl` + (用 Safari Web Inspector)。 +- README 明確**反對**在 iOS 使用 QuickJS,理由是 App Store Review Guidelines §4.7。 +- **推測**:README 未描述「熱重載」;從 API 形狀看,重新載入一份腳本的單位是整個 runtime 實例 + (`dispose()` 後重建 `getJavascriptRuntime()`),但沒有官方文字這樣建議。 +- 替代品 `flutter_qjs`(ekibun)0.3.7,2022-05-19T17:04:46(pub.dev API)、60/160、likes 31、30 天下載 86, + 且 `sdk: '>=2.12.0-0 <3.0.0'`(**不允許 Dart 3**)→ 已無法在 Dart 3 專案解析。 +- 另查 `js_runtime` 套件:pub.dev API **NOT_FOUND(查不到)**。 + +**Electron 以 BrowserWindow 當沙箱 JS host**:見上方 B2 LX Music +(`sandbox` / `contextIsolation` / `nodeIntegration` 設定、data-URL 載入、銷毀重建)。 + +**Apple 審查條款**(developer.apple.com/app-store/review/guidelines/,原文節錄): +- §2.5.2: + > Apps should be self-contained in their bundles, and may not read or write data outside the + > designated container area, nor may they download, install, or execute code which introduces + > or changes features or functionality of the app, including other apps. Educational apps + > designed to teach, develop, or allow students to test executable code may, in limited + > circumstances, download code provided that such code is not used for other purposes. Such + > apps must make the source code provided by the app completely viewable and editable by the user. +- §4.7(標題): + > Mini apps, mini games, streaming games, chatbots, plug-ins, and game emulators … Apps may + > offer certain software that is not embedded in the binary, specifically HTML5 and JavaScript + > mini apps and mini games, streaming games, chatbots, and plug-ins. Additionally, retro game + > console and PC emulator apps can offer to download games. +- §4.7.1:須符合 1.2(使用者產生內容)與 3.1(付款);§4.7.2: + > Your app may not extend or expose native platform APIs or technologies to the software + > without prior permission from Apple. + §4.7.3:未經逐次明示同意不得分享資料或隱私權限;§4.7.4:須提供軟體索引與 metadata + (universal links);§4.7.5:須有年齡分級機制。 +- 註:§2.5.2 與 §4.7 系列同時標註適用於 Notarization Review。 + +--- + +### 附錄:固定 SHA 出處清單 + +| 對象 | SHA(40 碼) | 備註 | +|---|---|---| +| Frezyx/talker | `654391c1a81c6a0fa4a05d46562cc0d15241d964` | 2026-07-28,預設分支最後 commit | +| jhomlala/alice | `2943b1901aec10cbeed82e57d6cb9a3122a25304` | 2026-09-18 | +| lwj1994/flutter_flipperkit | `66678eea25b815bb912498e9b7d8c57bad69033f` | 2022-05-05 | +| facebook/flipper | `13f95a067f56bb3772937a8f281b0a7eacda7080` | 2025-09-26;repo 已 archived | +| kekland/inspector | `60f989097f168e384a93b7e738665109d8f8ee2c` | 2026-03-30 | +| Abdelazeem777/requests_inspector | `8c08c212e7b59d5c017564cbca5c886f52caa897` | 2026-08-16 | +| syedmurtaza108/chucker-flutter | `1ecae1b90430e7260516dc4179882a10657c9fcc` | 2026-06-30 | +| vanlooverenkoen/db_viewer | `775d1597326f86950b6f8c551f339ea40818c4a8` | 2026-02-06 | +| isar/isar | `713001bf1615ea15460d9bc8d3fb9c8cb4150a2e` | 2025-06-14 | +| maotoumao/MusicFree | `d118b18b3d0c904400f7eea7bf99c0ceec6c1aee` | 2026-06-20 | +| lyswhut/lx-music-desktop | `ad95d5091c9ed689fa72b5e5c849df65f5a679ce` | 2026-09-19 | +| lyswhut/lx-music-mobile | `fb8480728d875fa5e0da25eebd3a26bb71723aae` | 2026-09-19 | +| lyswhut/lx-music-source | `55eb9881dad6ca895505352f3a0a7d1dfa3444e0` | 2024-06-12 | +| abner/flutter_js | `c3d4bba92278577c6cc73e7b10a69b358f23768b` | 2026-01-27 | +| microsoft/vscode | `acfc00a9e482b98f6383b4e69ba3dd771cce02b1` | 引用檔皆為此 SHA | +| flutter/flutter | `43596b3519f61ebd934229bb72c712caaefe6a9b` | `constants.dart` dartdoc | +| dart-lang/sdk | `815bb2e3dd88f9b6325615aaa6f338886b94dab6` | `spawn_uri_aot_test.dart`;issue #54528 | + +### 附錄:查不到 / 推測清單 + +- **查不到**:context7 未收錄 `jhomlala/alice`(只找到同名無關套件);alice 的資訊全部來自 + pub.dev API 與 GitHub 原始碼/README。 +- **查不到**:isar.dev 官方文檔的 inspector 說明頁(目前 404),無法確認現行官方文件 URL。 +- **查不到**:pub.dev `js_runtime`(NOT_FOUND)。 +- **查不到**:VS Code 官方文檔對「擴充程式碼熱重載」的說明 —— 官方只給 Reload Window 流程。 +- **查不到**:`inspector` 的 30 天下載 496649 相對 likes 87 的異常比例,未找到解釋。 +- **推測**:`Frezyx/talker` 與 `syedmurtaza108/chucker-flutter` 的 `pushed_at` 晚於預設分支最後 commit, + 推測來自其他分支的推送。 +- **推測**:flutter_js README 未描述熱重載;「重新載入腳本的單位是整個 runtime 實例」是從 API 形狀推得。 +- **推測**:requests_inspector 的平台標籤與 README 描述不一致(README 記 Web/Desktop 可用長按), + 未找到官方解釋。 From 08b402010f83fe576a08c98ed1a03ea5cc701d0a Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:00:48 +0800 Subject: [PATCH 103/133] chore(task): record developer mode decision --- .trellis/tasks/09-28-design-debug-page/prd.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md index d6765fcc4..94378ca61 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -102,9 +102,17 @@ - log 保留並加輪替與保留期限; - 資料檢查/修復收進 Debug 頁。 +## 已決定 + +1. **開發者模式**(2026-09-28,擁有者「按你建議」,取代 J1 的「保留」): + - 入口:「設定 → 關於」版本列連點 7 次。 + - 開啟狀態存進設定的「開發者」組,跨重啟保留。 + - Debug 頁最上方放總開關。關掉後:入口消失;錯誤提示不再附「詳細」;log 層級回到 info。 + - dev flavor 預設開啟。 + - 理由:ADR 0023 的「詳細」、ADR 0011 的 debug 層級、ADR 0015 的插件開發工具都依賴它。不記住的話,每次重啟都要再點 7 次、重新載入插件資料夾。 + ## 待決定(一次問一題) -1. 開發者模式:入口、要不要記住、怎麼關、開發版(dev flavor)是否預設開啟。 2. Debug 頁的區塊清單,以及資料庫檢視器、重設資料在 release 版是否提供。 3. log 保留期限。 4. 資料檢查/修復在 drift 之下要做什麼。 From a3f27e15dade56f4466aea0544cd5afad1dac7be Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:01:51 +0800 Subject: [PATCH 104/133] chore(task): record debug page sections decision --- .trellis/tasks/09-28-design-debug-page/prd.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md index 94378ca61..ea598e8fd 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -110,10 +110,23 @@ - Debug 頁最上方放總開關。關掉後:入口消失;錯誤提示不再附「詳細」;log 層級回到 info。 - dev flavor 預設開啟。 - 理由:ADR 0023 的「詳細」、ADR 0011 的 debug 層級、ADR 0015 的插件開發工具都依賴它。不記住的話,每次重啟都要再點 7 次、重新載入插件資料夾。 +2. **區塊與 release 版**(2026-09-28,擁有者「按你建議」): + - 版面:寬畫面左列區塊、右顯示內容;手機進子頁(同設定頁,ADR 0024)。 + - 八個區塊: + 1. 概覽:總開關、log 層級、版本/flavor/平台/資料目錄、診斷包(複製、存檔,手機可分享)。 + 2. Log 與錯誤歷史:層級、tag、文字篩選;「只看錯誤」=錯誤歷史;錯誤開 ADR 0023 詳細頁;匯出 log 檔。 + 3. 網路:取自 log 的網路摘要,不另存;可依音源、狀態碼篩選。 + 4. 播放狀態:狀態、曲目、串流格式與位元率、後端、輸出裝置、重試、佇列;可複製快照。 + 5. 音源健康檢查。 + 6. 插件開發:只有桌面。 + 7. 資料庫:唯讀瀏覽(筆數、分頁、敏感欄位遮蔽)+資料檢查。 + 8. 重設資料:先自動備份,再二次確認。 + - 拿掉:記憶體磚(改用 DevTools);快取(在設定頁,ADR 0016;概覽放連結過去)。 + - release 版:開了開發者模式就全部可用。 + - debug build:另可用 drift 官方 DevTools extension。 ## 待決定(一次問一題) -2. Debug 頁的區塊清單,以及資料庫檢視器、重設資料在 release 版是否提供。 3. log 保留期限。 4. 資料檢查/修復在 drift 之下要做什麼。 From 05537c6016470e4d7251977f3a3d73657abb893a Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:02:36 +0800 Subject: [PATCH 105/133] chore(task): record log retention decision --- .trellis/tasks/09-28-design-debug-page/prd.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md index ea598e8fd..f65a96d6e 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -124,10 +124,14 @@ - 拿掉:記憶體磚(改用 DevTools);快取(在設定頁,ADR 0016;概覽放連結過去)。 - release 版:開了開發者模式就全部可用。 - debug build:另可用 drift 官方 DevTools extension。 +3. **log 保留期限**(2026-09-28,擁有者「按你建議」): + - 最後修改超過 7 天的 log 檔,在啟動維護清單(ADR 0017)中刪除; + - 大小上限照 ADR 0011(2MB × 3),先到哪個限制就先刪; + - 不做設定項; + - Debug 頁「清除 log」同時清記憶體與檔案。 ## 待決定(一次問一題) -3. log 保留期限。 4. 資料檢查/修復在 drift 之下要做什麼。 ## 驗收條件 From 5875e50f3335f1d8c5ab0f8d198f70a5910fb3a8 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:05:36 +0800 Subject: [PATCH 106/133] chore(task): add debug page design and plan --- .../tasks/09-28-design-debug-page/design.md | 189 ++++++++++++++++++ .../09-28-design-debug-page/implement.md | 27 +++ .trellis/tasks/09-28-design-debug-page/prd.md | 33 ++- 3 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 .trellis/tasks/09-28-design-debug-page/design.md create mode 100644 .trellis/tasks/09-28-design-debug-page/implement.md diff --git a/.trellis/tasks/09-28-design-debug-page/design.md b/.trellis/tasks/09-28-design-debug-page/design.md new file mode 100644 index 000000000..a8a4d5ee6 --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/design.md @@ -0,0 +1,189 @@ +# 設計:Debug 頁與開發者模式 + +## 1. 開發者模式(已決定) + +- **狀態**:放在設定的「開發者」組(ADR 0011,每組一張單列表,空值=未設定)。 + - `developerMode`:空值時套用程式預設,prod 為關、dev flavor 為開。 + - `logLevel`:空值=info。 +- **開啟**:「設定 → 關於」的版本列連點 7 次。 + - 第 2 次起提示「再點 n 次」,離開頁面計數歸零(Firefox `SecretDebugMenuTrigger` 的做法)。 + - 開啟後寫入設定。 +- **關閉**:Debug 頁「概覽」最上方的總開關。關閉時同一筆寫入做三件事: + - `developerMode` 設為 false; + - `logLevel` 清為空值,也就是回到 info; + - 若插件開發工具載入了資料夾,一併卸載。 +- **它控制的東西**(全部讀同一個 provider): + - 設定頁的「開發者選項」入口; + - 錯誤提示的「詳細」(ADR 0023); + - log 層級可調到 debug(ADR 0011); + - Debug 頁各路由; + - 插件開發工具(ADR 0015)。 +- **路由閘門**:Debug 頁的路由在開發者模式關閉時 redirect 回設定頁,連結直達也進不去。舊版是無條件註冊(`router.dart:246-263`)。 + +## 2. 版面(已決定) + +- 沿用設定頁的 list-detail(ADR 0024): + - expanded 以上:左列區塊、右顯示內容; + - compact、medium:區塊清單,點進子頁。 +- 全部用 ADR 0024 的 token 與元件,字串走 slang(三語言)。舊版有寫死的簡中與英文(`developer_options_page.dart:307`、`log_viewer_page.dart:208-212`)。 +- 區塊依序如下。 + +| # | 區塊 | 內容 | 平台 | +|---|---|---|---| +| 1 | 概覽 | 總開關、log 層級、版本/flavor/平台/資料目錄、快取用量連到設定頁(ADR 0016)、產生診斷包 | 全部 | +| 2 | Log 與錯誤歷史 | 見 §3 | 全部 | +| 3 | 網路 | 見 §4 | 全部 | +| 4 | 播放狀態 | 見 §5 | 全部 | +| 5 | 音源健康檢查 | 見 §6 | 全部 | +| 6 | 插件開發 | 見 §7 | 平台層宣告 `pluginDevTools` 的平台(先桌面) | +| 7 | 資料庫 | 見 §8 | 全部 | +| 8 | 重設資料 | 見 §9 | 全部 | + +- release 版只要開了開發者模式,以上全部可用。 +- debug build 另可用 drift 官方 DevTools extension(隨 `drift` 出貨,release 編譯期移除),不另寫程式。 +- 拿掉舊版的記憶體磚:數字是粗估,清除按鈕也只清記憶體圖片快取。要看記憶體用 DevTools。 + +## 3. Log 與錯誤歷史 + +```mermaid +flowchart LR + SRC["各模組
    dio 攔截器
    錯誤處理"] --> F["log 門面
    先遮蔽(ADR 0011)"] + F --> M["記憶體歷史
    1,000 筆"] + F --> FILE["log 檔
    JSON Lines,2MB × 3,7 天"] + M --> V["Debug 頁
    Log/網路/錯誤歷史"] + FILE -->|"「含之前的紀錄」"| V + FILE --> DG["診斷包"] + V --> DP["錯誤詳細頁
    (ADR 0023)"] +``` + +- **log 檔格式改為 JSON Lines**:一筆一行,欄位含時間、層級、tag、訊息、error、stackTrace、結構化欄位。 + - 理由:錯誤歷史跨重啟要從檔案讀回,還要能依錯誤類型、音源篩選。舊版的純文字行(`[LEVEL] [tag] message`)讀回後分不出欄位。 +- **檢視**: + - 預設只看這次執行的記憶體歷史。 + - 開「含之前的紀錄」才在 isolate 解析 log 檔,最多 6MB,併進清單。 + - 篩選:層級、tag(模組或音源 id)、文字。 + - 「只看錯誤」=錯誤歷史(warning 以上且帶錯誤類型)。點一筆開 ADR 0023 的詳細頁。 +- **動作**: + - 複製已篩選的清單; + - 匯出 log 檔,走診斷包的匯出管道(§10); + - 「清除 log」:同時清記憶體與檔案(舊版只清記憶體,`log_viewer_page.dart:150-155`)。 +- **保留(已決定)**: + - 大小依 ADR 0011,2MB × 3; + - 最後修改超過 7 天的檔案,在啟動維護清單(ADR 0017)中刪除,先到哪個限制就先刪; + - 不做設定項。 + +## 4. 網路 + +- 資料來源是 log 門面裡 tag 為網路的紀錄,不另存一份(ADR 0011 §4:dio 攔截器每請求一筆摘要)。 +- 摘要以 `info` 層級寫入,所以 release 版也看得到;失敗的請求另外帶錯誤類型,一併進入錯誤歷史。 +- 清單欄位:時間、方法、主機、路徑、狀態、耗時、大小、音源。 + - 篩選:音源、狀態碼類別(2xx/3xx/4xx/5xx/失敗)、文字。 +- 單筆詳細:遮過的 query、錯誤類型、對應的錯誤紀錄。不記 body,也就沒有 body 可看(ADR 0011 已否決記 body)。 +- 沿用 LocalSend 的 HTTP Logs 頁:記憶體清單、可清除、可逐筆複製;並加上篩選。 + +## 5. 播放狀態 + +- 即時顯示 ADR 0018 的播放狀態: + - sealed 狀態名,`Failed` 時附 `AppError`; + - 目前曲目:插件 id、曲目鍵; + - 串流:格式、位元率、容器、來源類型(線上、快取、已下載); + - 音訊後端、輸出裝置、重試次數與下次重試時間。 +- 位置與緩衝位置來自獨立 stream,以每秒一次節流顯示,不讓 Debug 頁拖慢播放 UI。 +- 佇列:總數、目前索引、前後各 5 首、隨機與循環模式。 +- 「複製快照」:以上內容的 JSON。串流網址經遮蔽函式,簽名參數被去除(ADR 0011 §3)。 +- 只讀,不提供操作;播放控制仍只經 `AudioController` 一個入口。 + +## 6. 音源健康檢查 + +- 對已安裝、已啟用的插件,逐一跑它 `checks.json` 裡的案例,以真實連線執行(ADR 0015 §4 的第三種用法)。 +- 手動觸發:「全部檢查」或單一插件,一次跑一個插件,避免同時打多個音源。 +- 結果依插件列出每個案例: + - 通過或失敗; + - 耗時; + - 失敗時附 `AppError` 類別,可開詳細頁。 +- 結果經 log 門面以 tag `health` 寫入,不另外存。 +- 需要登入的案例在未登入時標「略過(未登入)」,不算失敗。 + +## 7. 插件開發(ADR 0015 §7 的版面) + +- 只在平台層宣告 `pluginDevTools` 的平台出現(ADR 0009),先限桌面三平台。 + - 理由:Android 以 file_picker 選資料夾後讀不到其中的 `.js`(研究推測,未實機);ADR 0015 已限桌面。 +- **載入**:以 `file_selector.getDirectoryPath` 選插件資料夾,路徑記在「開發者」組。 + - 資料夾中的插件以「開發中」標記,本次執行期間取代同 id 的已安裝插件。 + - 卸載後恢復已安裝版。 +- **重新載入**:手動按鈕,拆掉該插件的 JS runtime 再重建。 + - 沿用 LX Music(切換=銷毀重建)與 VS Code「Reload Window」的做法。 + - 不做檔案監看自動重載:編輯器存檔到一半時重載會讀到半個檔案,而且 MusicFree、LX Music 都沒有這個功能。 +- **每插件模式**:真實、錄製、重播(ADR 0015 §5)。錄製的 fixture 經遮蔽後寫到插件資料夾的 `fixtures/`。 +- **跑案例**:列出 `checks.json` 的案例,可以單跑或全跑,顯示回傳值(已遮蔽)與錯誤。 +- **log**:同一個 Log 檢視,預設篩成該插件的 tag。 + +## 8. 資料庫(已決定) + +- **唯讀瀏覽**: + - 列出 `allTables`,附各表筆數; + - 點進表以 `select(table)` 分頁,每頁 50 列。 + - 每個值轉字串後經遮蔽函式。插件 storage 表的值整欄遮蔽(可能含 token);憑證本身在 secure storage,不在資料庫(ADR 0012)。 + - 自己寫,不用 `drift_db_viewer`:該套件 2.5 年沒發版,也做不到遮蔽。 + - 不在 App 內編輯:要做寫入介面,還會和 App 自己的寫入者衝突。 +- **資料檢查**(手動按鈕,只報告,不自動修): + - `PRAGMA integrity_check`:檔案是否損壞; + - `PRAGMA foreign_key_check`:有沒有違反外鍵的列; + - 孤兒曲目數(ADR 0019 的判定查詢)、「檔案遺失」的下載數(ADR 0020)。這兩項只顯示,處理交給各自的機制。 + - 有問題時提供「從備份還原」(ADR 0010)與「重設資料」(§9)。 +- **不移植 `DataIntegrityRepository.scan/repair`**:它查的四件事在新 schema 下由唯一鍵、主鍵、單列表擋住。 +- **不在啟動時自動檢查**:`integrity_check` 會掃整個檔案,拖慢啟動。資料庫打不開時的處理屬於啟動流程,不在本 ADR 範圍。 + +## 9. 重設資料(已決定) + +- 範圍: + - 清空:資料庫(含設定與匯入紀錄)、secure storage 中 FMP 的憑證、快取。 + - 不動:已下載的檔案、使用者資料夾裡的 sidecar、log 檔。 +- 流程: + 1. 以 ADR 0010 的備份格式自動備份到資料目錄的 `backups/`; + 2. 確認對話框列出備份檔位置; + 3. 使用者確認後清空; + 4. 重啟 App。 +- 備份失敗就不清空,並顯示錯誤。 + +## 10. 診斷包與匯出管道 + +- **內容**:ADR 0011 §6 的欄位,產生時組裝一次。 + - 純文字 `diagnostics.txt`、JSON `diagnostics.json`; + - 加上目前的 log 檔。log 在寫入時已經遮蔽,組裝時不再重新遮蔽。 +- **動作**: + - 「複製」:只複製純文字摘要,不含 log; + - 「存檔」:產生 `fmp-diagnostics-<時間>.zip`; + - 「分享」:Android、iOS、macOS、Windows 以 `share_plus` 分享 zip。 +- **存檔與分享由平台層宣告**: + - 桌面「存檔」用 `file_selector.getSaveLocation`;Android 用系統的建立文件對話框。 + - `share_plus` 在 Linux 與 Windows RS5 以下不能分享檔案,這些平台不顯示「分享」。 +- 第一次匯出時提醒「內容已遮蔽,送出前仍請檢查」,與 ADR 0023 的回報提醒共用同一個「不再提醒」設定。 +- 暫存的 zip 在分享完成後刪除,殘留的由啟動維護清單清掉。 + +## 11. 閘門 + +- **既有 lint**:Debug 頁內的平台判斷同樣受 `fmp_platform_checks` 管;只能讀平台層宣告的能力,不寫 `Platform.isX`(舊版 `developer_options_page.dart:202`)。 +- **單元測試**: + - 開發者模式:連點 7 次開啟並寫入設定;關閉時 `logLevel` 清空、開發資料夾卸載;dev flavor 預設開。 + - log 保留:超過 7 天的檔被刪、未滿 7 天的保留;大小與天數同時作用。 + - log 檔 JSON Lines 讀回後欄位與寫入一致;壞行略過、不讓解析中止。 + - 網路篩選:依音源與狀態碼類別。 + - 資料檢查:人為造一筆違反外鍵的列(先關外鍵寫入再打開),報告列出它;乾淨資料庫報告無問題。 + - 重設:備份失敗時不清空;成功時已下載的檔案仍在。 + - 遮蔽:播放快照、資料庫瀏覽、診斷包都不含假憑證與假簽名網址(併入 ADR 0011 的遮蔽測試)。 +- **widget 測試**: + - 開發者模式關閉時直接進 Debug 路由會被 redirect; + - 未宣告 `pluginDevTools` 的平台不顯示插件開發區塊; + - 未宣告檔案分享的平台不顯示「分享」。 +- **第一個里程碑實測**: + - Windows release 版開啟開發者模式,重啟後仍開啟,再從總開關關掉; + - 在 Debug 頁看到一次搜尋的網路摘要; + - 匯出診斷包並用解壓工具打開。 + +## 12. 相關 ADR 的指向 + +- 0011:開發者模式的持久化、log 保留期限與 log 檔格式由 0025 定。 +- 0015:插件開發工具的版面由 0025 定。 +- 0023:Debug 頁錯誤歷史的入口見 0025。 +- 0017:啟動維護清單加入 log 檔保留與診斷包暫存清理。 diff --git a/.trellis/tasks/09-28-design-debug-page/implement.md b/.trellis/tasks/09-28-design-debug-page/implement.md new file mode 100644 index 000000000..e6ac98c7a --- /dev/null +++ b/.trellis/tasks/09-28-design-debug-page/implement.md @@ -0,0 +1,27 @@ +# 執行計畫:第 4 項(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0025-debug-page-and-developer-mode.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§11。 + 被否決的方案: + - 開發者模式不記住(J1 原狀); + - release 版只留 log 與診斷包; + - App 內可編輯資料庫; + - 重設前不備份; + - `TalkerScreen`、alice、`drift_db_viewer`; + - log 保留 3 天、30 天、只限大小、可調設定; + - 移植 `scan/repair`; + - 自動修復; + - 每次啟動自動檢查; + - 檔案監看自動重載插件。 +2. [ ] 其他 ADR 各加一句指向 ADR 0025: + - 0011:開發者模式持久化、log 保留與 JSON Lines 格式; + - 0015:插件開發工具版面; + - 0017:啟動維護清單加入 log 保留與診斷包暫存清理; + - 0023:Debug 頁錯誤歷史。 +3. [ ] 更新 `phase2-plan.md`: + - §3:第 4 項標 ✅(ADR 0025); + - §7:第一個里程碑加入 §11 的實測項目; + - §10:交接段更新,下一項為 7「里程碑定稿」。 +4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用。 +5. [ ] `task.py finish`,再 `task.py archive design-debug-page --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/09-28-design-debug-page/prd.md index f65a96d6e..71d4b1e8d 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/09-28-design-debug-page/prd.md @@ -94,8 +94,7 @@ ## 擁有者的輸入 -- J1 勾「保留」(連點 7 次、不持久化、無關閉入口)。 -- J2、J3、J4 勾「不確定」。 +- J1 勾「保留」(連點 7 次、不持久化、無關閉入口)。J2、J3 勾「不確定」。J4 勾「不確定」,選項寫「接到 Debug 頁」。 - 備註:「如果有問題或是有更好的方案的話可以按你推薦的來改」。 - `phase2-plan` §8 的方向: - Debug 頁重做成正式工具; @@ -130,13 +129,31 @@ - 不做設定項; - Debug 頁「清除 log」同時清記憶體與檔案。 -## 待決定(一次問一題) +4. **資料檢查與修復**(2026-09-28,擁有者「按你建議」,取代 J4 的「接到 Debug 頁」): + - 不移植 `scan/repair`:它查的四件事,在新 schema 下由唯一鍵、主鍵、單列表擋住。 + - 「資料庫」區塊加手動「檢查」: + - `PRAGMA integrity_check`、`PRAGMA foreign_key_check`; + - 列出孤兒曲目數與「檔案遺失」的下載數,只顯示,不處理。 + - 只報告,不自動修。有問題時提供「從備份還原」與「重設資料」。 + - 不在啟動時自動檢查。 -4. 資料檢查/修復在 drift 之下要做什麼。 +我自行定下、未另外詢問的技術細節,理由寫在 `design.md`: +- log 檔改為 JSON Lines; +- 網路摘要以 info 層級寫入; +- 插件只手動重新載入,不做檔案監看; +- 重設資料的範圍; +- 診斷包的格式與匯出管道由平台層宣告。 + +## 範圍外 + +- 資料庫打不開時的啟動錯誤畫面與還原(屬啟動流程)。 +- App 內編輯資料庫、記錄 request/response body。 +- 記憶體監看(改用 DevTools)。 +- 快取清除(ADR 0016,在設定頁)。 ## 驗收條件 -- [ ] 以上待決定項都有擁有者的答覆,寫進 ADR 0025。 -- [ ] ADR 0025 含「如何確認」(測試或 lint 與第一個里程碑的實測項目)。 -- [ ] ADR 0011、0015 各加一句指向 0025。 -- [ ] `phase2-plan.md` 的 §3、§7/§8、§10 已更新。 +- [ ] ADR 0025 記下四個已決定事項,以及 `design.md` §1–§10 的設計與被否決的方案。 +- [ ] ADR 0025 的「如何確認」含 `design.md` §11 的單元測試、widget 測試與第一個里程碑實測。 +- [ ] ADR 0011、0015、0017、0023 各加一句指向 0025。 +- [ ] `phase2-plan.md` 的 §3(第 4 項 ✅)、§7(里程碑實測)、§10(下一項 7「里程碑定稿」)已更新。 From e1958954b2d4165783482b7b68da2df0bcda1053 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:07:55 +0800 Subject: [PATCH 107/133] docs(adr): 0025 debug page and developer mode --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 16 +- docs/adr/0011-settings-and-logging.md | 2 +- .../0015-testing-gates-and-dev-environment.md | 2 +- docs/adr/0017-background-task-scheduler.md | 2 +- docs/adr/0023-unified-toast.md | 2 +- .../adr/0025-debug-page-and-developer-mode.md | 210 ++++++++++++++++++ 6 files changed, 222 insertions(+), 12 deletions(-) create mode 100644 docs/adr/0025-debug-page-and-developer-mode.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index b88ae331f..3526a58e0 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -128,7 +128,7 @@ flowchart LR | 16 | 19 發版與更新(✅ 完成,ADR 0022) | 依賴 10、16;你已給出流程要求。 | | 17 | 3 Toast(✅ 完成,ADR 0023) | 依賴 2、18。 | | 18 | 5 UI/UX(✅ 完成,ADR 0024) | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | -| 19 | 4 Debug 頁 | 把 18、3、8 的成果收成正式工具。 | +| 19 | 4 Debug 頁(✅ 完成,ADR 0025) | 把 18、3、8 的成果收成正式工具。 | | 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | ## 4. 你在 questions.md 直接問的問題 @@ -236,6 +236,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 - ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 - ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——`flutter_overlay_window` 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——`flutter_lyric` 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。 +- ADR 0025:加入 Debug 頁的里程碑——Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出的診斷包能以解壓工具打開。 - ADR 0022:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版);Windows App 自行下載的安裝檔不帶 Mark of the Web。macOS 平台任務——App 自行下載的更新不帶 quarantine。Linux 平台任務——AppImage 的改名替換。 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -245,14 +246,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 4 項研究中) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 4 項完成) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0024`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0025(Debug 頁)。 -- **進行中:第 4 項「Debug 頁」**,task `.trellis/tasks/09-28-design-debug-page/`(planning);研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`packages-and-platform.md`),三個檔齊了才代表研究完成,接著抽查→prd→一次一問。 - 已知輸入:J1 開發者模式(版本連點 7 次、不持久化、沒有關閉入口;擁有者勾保留)、J2 Debug 頁區塊(不確定,重做)、J3 log 寫檔(方向:保留並加輪替與保留期限)、J4 `DataIntegrityRepository.scan/repair`(方向:收進 Debug 頁);ADR 0011 明寫「Debug 頁與開發者模式的持久化由 Debug 頁的設計定」、ADR 0015 明寫「插件開發工具的版面由 Debug 頁的設計定」。範圍:含 log 檢視與錯誤歷史(ADR 0011、0023 的詳細頁)、網路請求檢視、播放與佇列即時狀態、資料庫檢視、音源健康檢查(ADR 0015)、插件開發工具(ADR 0015)、快取管理(ADR 0016)、診斷包匯出(ADR 0011);版面用 ADR 0024 的設計系統。 -- 之後順序:7 里程碑定稿。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0025`;舊 ADR 0001–0007 仍描述根目錄舊專案。 +- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁。 + 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0026。 +- **下一項:第 7 項「重寫策略(里程碑定稿)」**:把 ADR 0008–0025 拆成可獨立驗證的里程碑與 child task;輸入含 §7 第一個里程碑的必要驗證、§8 延後的實測、§9 功能凍結例外與里程碑備忘、ADR 0008 的高層策略。 +- 之後順序:7 里程碑定稿 → 階段三(Trellis/docs 清理)。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/docs/adr/0011-settings-and-logging.md b/docs/adr/0011-settings-and-logging.md index 205b7a9cd..3b3e44ded 100644 --- a/docs/adr/0011-settings-and-logging.md +++ b/docs/adr/0011-settings-and-logging.md @@ -52,7 +52,7 @@ Spotube 以 drift 存設定並以 `watchSingle()` 接 Riverpod。 - 好的:任何出口都不會漏出未遮蔽的內容;錯誤可依類型與音源追查;設定的預設值可以安全調整;新增音源不必改設定 schema。 - 壞的:Debug 頁的 log 檢視要自己做;遮蔽名單要隨音源維護;release 版在本機留有 info 級別的使用紀錄(已遮蔽、不上傳)。 -- 之後要注意:統一錯誤型別的欄位由錯誤模型的 ADR 定;Debug 頁與開發者模式的持久化由 Debug 頁的設計定;各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案。 +- 之後要注意:統一錯誤型別的欄位由錯誤模型的 ADR 定;開發者模式的持久化、log 保留 7 天與 JSON Lines 格式、Debug 頁見 ADR 0025;各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案。 ## 如何確認 diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index 569263969..9bf75bbe9 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -63,7 +63,7 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 媒體請求不帶憑證(0012)、只連 manifest 網域、log 經遮蔽(0011)。插件庫 CI 以固定的 FMP 版本執行;`app/` 的 CI 對 `app/test/fixtures/plugins/` 內的測試插件執行(合成資料、播放本機音檔),不依賴官方插件庫;同一個測試插件也供開發版離線開發。 7. **App 內插件開發工具**:開發者模式下從資料夾載入插件(先限桌面平台,由平台層宣告)、重新載入、跑案例看 log、 - 以 App 內登入錄 fixture、每插件切換真實/錄製/重播。命令列只負責重播。版面由 Debug 頁的設計定。 + 以 App 內登入錄 fixture、每插件切換真實/錄製/重播。命令列只負責重播。版面見 ADR 0025。 8. **開發版**:flavor `dev`/`prod`,`pubspec.yaml` 設 `default-flavor: dev`,發版明確帶 `--flavor prod`。 dev 的 Android `applicationIdSuffix ".dev"`、Windows AppUserModelID `com.personal.fmp.dev`、名稱「FMP Dev」與標記圖示、 資料目錄/單一實例鎖/secure storage 命名空間加 `-dev`;prod 維持 ADR 0008 的身分。開發版資料預設空白, diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md index 55b73267f..94344fdd4 100644 --- a/docs/adr/0017-background-task-scheduler.md +++ b/docs/adr/0017-background-task-scheduler.md @@ -30,7 +30,7 @@ ADR 0016 定了網路狀態與「離線中不發背景請求」,把排程、 - 下載:事件驅動,下載的 ADR 定; - 快取淘汰(ADR 0016)與 log 輪替(ADR 0011):寫入時觸發; - 更新檢查與插件更新:只手動(App 更新見 ADR 0022,更新檔清理登記在啟動維護清單); - - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次。 + - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次(ADR 0025 加入 log 保留期限與診斷包暫存清理)。 2. **工作宣告**:id、所屬插件(可空)、間隔(空=關閉)、執行函式。「上次成功時間」存資料庫,重啟後照算。 排程器只用一個計時器,指向最早到期的工作。 3. **何時跑**:只有 App 可見(`AppLifecycleState.resumed` 或 `inactive`)且網路狀態為 `Online`(ADR 0016)時才跑。 diff --git a/docs/adr/0023-unified-toast.md b/docs/adr/0023-unified-toast.md index b6b4c273f..7f10cc046 100644 --- a/docs/adr/0023-unified-toast.md +++ b/docs/adr/0023-unified-toast.md @@ -62,7 +62,7 @@ - 詳細頁文字可選取,按鈕: - 「複製」:Markdown 格式; - 「在 GitHub 回報」:先複製,再開新增 issue 頁(bug 範本),內容不放進網址。第一次使用提醒 repo 公開、送出前檢查。 - - Debug 頁的錯誤歷史用同一個詳細頁。 + - Debug 頁的錯誤歷史用同一個詳細頁(ADR 0025)。 5. **無障礙**: - 使用 `SnackBar` 內建的 live region:朗讀但不搶焦點。 - 單獨朗讀用 `SemanticsService.sendAnnouncement(View.of(context), …)`,不用已棄用的 `announce`(與多視窗不相容)。 diff --git a/docs/adr/0025-debug-page-and-developer-mode.md b/docs/adr/0025-debug-page-and-developer-mode.md new file mode 100644 index 000000000..74b629b4c --- /dev/null +++ b/docs/adr/0025-debug-page-and-developer-mode.md @@ -0,0 +1,210 @@ +# 0025 — Debug 頁與開發者模式:記住的開發者模式、八區塊 list-detail、log 保留 7 天、只報告的資料檢查 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/` 的 Debug 模組與路由、「開發者」設定組、log 檔格式與保留、診斷包、插件開發工具的版面、平台層能力 `pluginDevTools` 與檔案存檔/分享 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-design-debug-page/research/current-state.md`、`docs/audit/devtools.md`,已以程式碼核對): + +- **開發者模式** + - 開法:版本列連點 7 次(`developer_options_provider.dart:49`)。 + - 只存在記憶體,沒有關閉入口;路由無條件註冊(`router.dart:246-263`)。 + - 實際只控制兩件事:設定頁入口、log 層級。 +- **Debug 頁** + - 記憶體磚:粗估數字,清除只清記憶體圖片快取。 + - log 層級。 + - Isar 檢視器:11 個 collection 各一次 `findAll()`,不能搜尋、不分頁。 + - 重設資料:直接 `isar.clear()`,不先備份。 + - 另有寫死的簡中與英文字串。 +- **Log** + - 記憶體 500 筆; + - 檔案 2MB × 3,只限大小、沒有期限,內容是純文字行; + - 「清除」只清記憶體。 +- **`DataIntegrityRepository.scan/repair`** + - 檢查 Track `uniqueKey`、DownloadTask `savePath`、Account `platform` 重複,以及 PlayQueue 超過一筆。 + - `lib/` 裡零呼叫點。 +- **沒有的東西**:網路請求紀錄、播放狀態檢視、診斷包、音源健康檢查、插件開發工具。 + +已定的邊界: +- ADR 0011:log 門面、遮蔽、網路摘要、錯誤歷史、診斷包欄位。它寫明「Debug 頁與開發者模式的持久化由 Debug 頁的設計定」。 +- ADR 0015 §4、§7:健康檢查與插件開發工具。它寫明插件開發工具的「版面由 Debug 頁的設計定」。 +- ADR 0023:錯誤詳細頁。 +- ADR 0016:快取的清除入口在設定頁。 + +擁有者在 `questions.md` 的勾選:J1「保留」、J2–J4「不確定」,並註明「可以按你推薦的來改」。 +2026-09-28 選定:開發者模式、區塊、log 保留、資料檢查,四題都照建議。 + +## 考慮過的選項 + +- **開發者模式不記住(J1 原狀)**:否決。 + - 「詳細」(ADR 0023)、debug 層級(ADR 0011)、插件開發工具(ADR 0015)都依賴它; + - 每次重啟要再點 7 次、重新載入插件資料夾。 +- **可見的「開發者」設定項**(NewPipe、Home Assistant):否決。一般使用者用不到;沿用 Android 系統的隱藏手勢。 +- **release 版只留 log 與診斷包,其他限 debug build**:否決。正式版上的問題會看不到網路與播放狀態。 +- **Debug UI 用 `TalkerScreen`、alice、`requests_inspector`**:否決。 + - 不是 App 的設計系統,也繞過遮蔽(ADR 0011); + - 三者都沒有 release 閘門。 +- **`drift_db_viewer`**:否決。2.5 年沒發版,也做不到遮蔽。 +- **在 App 內編輯資料庫**:否決。要做寫入介面,還會和 App 自己的寫入者衝突(舊版以 VM Service 寫入時踩過)。 +- **重設前不備份(舊版)**:否決。一次誤按就無法挽回。 +- **log 保留期限**: + - 保留 3 天(Signal):否決,週末前遇到、週末後才回報的問題就沒有紀錄。 + - 30 天、只限大小:否決,不常用的人會在本機留下幾個月的使用紀錄。 + - 做成可調設定:否決,對一般使用者沒有意義。 +- **log 檔維持純文字行**:否決。錯誤歷史跨重啟讀回後分不出欄位,無法依錯誤類型、音源篩選。 +- **移植 `scan/repair`**:否決。它查的四件事在新 schema 下由唯一鍵、主鍵、單列表擋住(ADR 0010、0020)。 +- **自動修復損壞的資料庫**:否決。SQLite 損壞時能救回多少不一定,自動修可能默默丟資料。 +- **每次啟動自動檢查**:否決。`integrity_check` 會掃整個檔案,拖慢啟動。 +- **檔案監看自動重載插件**:否決。 + - 編輯器存檔到一半時會讀到半個檔案; + - MusicFree、LX Music 都沒有這個功能。 + +## 決定 + +1. **開發者模式** + - **狀態**:存在設定的「開發者」組(ADR 0011),兩個欄位: + - `developerMode`:空值時 prod 為關、dev flavor 為開; + - `logLevel`:空值=info。 + - **開啟**:「設定 → 關於」的版本列連點 7 次。第 2 次起提示還差幾次,離開頁面後計數歸零。 + - **關閉**:Debug 頁「概覽」最上方的總開關。關閉時在同一筆寫入中: + - `logLevel` 清為空值; + - 卸載插件開發資料夾。 + - **它控制的東西**: + - 設定頁的入口; + - 錯誤提示的「詳細」; + - log 層級可調到 debug; + - Debug 頁的路由; + - 插件開發工具。 + - **路由閘門**:開發者模式關閉時,Debug 頁路由一律 redirect 回設定頁。 +2. **版面**: + - 沿用設定頁的 list-detail(ADR 0024):expanded 以上左列區塊、右顯示內容;較窄的畫面點進子頁。 + - 全部用 token 與 slang 字串。 + - release 版只要開了開發者模式,所有區塊都可用。debug build 另可用 drift 官方 DevTools extension。 + - 拿掉記憶體磚;快取留在設定頁,概覽放連結過去。 + + | 區塊 | 內容 | + |---|---| + | 概覽 | 總開關、log 層級、版本/flavor/平台/資料目錄、快取用量連結、診斷包 | + | Log 與錯誤歷史 | 第 3 點 | + | 網路 | 第 4 點 | + | 播放狀態 | 第 5 點 | + | 音源健康檢查 | 第 6 點 | + | 插件開發 | 第 7 點,只在平台層宣告 `pluginDevTools` 的平台出現(ADR 0009),先限桌面 | + | 資料庫 | 第 8 點 | + | 重設資料 | 第 9 點 | + +3. **Log 與錯誤歷史** + - **檔案格式**:JSON Lines,一筆一行。欄位:時間、層級、tag、訊息、error、stackTrace、結構化欄位。 + - **檢視**: + - 預設看這次執行的記憶體歷史;開「含之前的紀錄」才在 isolate 解析 log 檔(最多 6MB)。 + - 篩選:層級、tag、文字。 + - 「只看錯誤」=錯誤歷史,點一筆開 ADR 0023 的詳細頁。 + - **動作**:複製已篩選的內容;匯出 log 檔(走第 10 點的管道);「清除 log」同時清記憶體與檔案。 + - **保留**:大小照 ADR 0011(2MB × 3)。最後修改超過 7 天的檔案,由啟動維護清單(ADR 0017)刪除;先到哪個限制就先刪。不做設定項。 +4. **網路** + - 資料來源是 log 門面裡的網路摘要(ADR 0011 §4),以 `info` 層級寫入,不另存一份。 + - 清單欄位:時間、方法、主機、路徑、狀態、耗時、大小、音源。 + - 篩選:音源、狀態碼類別(2xx/3xx/4xx/5xx/失敗)、文字。 + - 單筆詳細:遮過的 query、錯誤類型、對應的錯誤紀錄。 +5. **播放狀態**:唯讀,播放控制仍只經 `AudioController`。 + - 顯示內容: + - ADR 0018 的 sealed 狀態(`Failed` 附 `AppError`); + - 曲目:插件 id、曲目鍵; + - 串流:格式、位元率、容器、來源類型; + - 音訊後端、輸出裝置、重試次數與下次重試時間; + - 佇列:總數、目前索引、前後各 5 首、隨機與循環模式。 + - 位置每秒刷新一次。 + - 「複製快照」輸出 JSON,串流網址經遮蔽。 +6. **音源健康檢查** + - 對已安裝且啟用的插件,以真實連線跑 `checks.json` 的案例(ADR 0015 §4)。 + - 手動觸發:「全部」或單一插件;一次跑一個插件。 + - 結果:每個案例通過或失敗、耗時、`AppError` 類別。未登入的案例標「略過」。 + - 結果以 tag `health` 經門面寫入,不另外存。 +7. **插件開發** + - 以 `file_selector.getDirectoryPath` 選資料夾,路徑記在「開發者」組。 + - 資料夾中的插件標「開發中」,本次執行期間取代同 id 的已安裝插件;卸載後恢復已安裝版。 + - 「重新載入」按鈕:拆掉該插件的 JS runtime 再重建。 + - 每插件可切換真實、錄製、重播;錄製的 fixture 經遮蔽後寫到插件資料夾的 `fixtures/`。 + - 案例可單跑或全跑,顯示已遮蔽的回傳值與錯誤;log 預設篩成該插件的 tag。 +8. **資料庫** + - **唯讀瀏覽**: + - 列出 `allTables` 與各表筆數;點進表以 `select(table)` 分頁,每頁 50 列。 + - 每個值經遮蔽函式;插件 storage 表的值整欄遮蔽。憑證在 secure storage,不在資料庫(ADR 0012)。 + - **「檢查」按鈕**,只報告: + - `PRAGMA integrity_check`、`PRAGMA foreign_key_check`; + - 孤兒曲目數(ADR 0019)、「檔案遺失」的下載數(ADR 0020),只顯示,處理交給各自的機制。 + - 有問題時提供「從備份還原」(ADR 0010)與「重設資料」。 + - 不在啟動時自動檢查。資料庫打不開時的處理屬於啟動流程,不在本 ADR 範圍。 +9. **重設資料** + - 範圍: + - 清空:資料庫(含設定)、secure storage 中 FMP 的憑證、快取; + - 不動:已下載的檔案與 sidecar、log 檔。 + - 流程: + 1. 以 ADR 0010 的備份格式自動備份到資料目錄的 `backups/`; + 2. 對話框列出備份位置,二次確認; + 3. 清空後重啟 App。 + - 備份失敗就不清空。 +10. **診斷包** + - 內容:ADR 0011 §6 的欄位,產生時組裝一次,輸出 `diagnostics.txt`、`diagnostics.json`,加上目前的 log 檔。log 寫入時已經遮蔽。 + - 動作: + - 「複製」:只複製純文字摘要; + - 「存檔」:輸出 `fmp-diagnostics-<時間>.zip`。桌面用 `file_selector.getSaveLocation`,Android 用系統的建立文件對話框; + - 「分享」:用 `share_plus`,只在平台層宣告能分享檔案的平台顯示(Linux 與 Windows RS5 以下不能)。 + - 第一次匯出時提醒「送出前請檢查」,和 ADR 0023 的回報提醒共用同一個「不再提醒」設定。 + - 暫存的 zip 分享後刪除,殘留的由啟動維護清單清掉。 + +採用的慣例: +- Android 系統開發人員選項:連點版本號開啟、頁首總開關; +- Firefox `SecretDebugMenuTrigger`:剩餘次數提示、離開時計數歸零; +- LocalSend 的 HTTP Logs 頁; +- Immich、Signal 的 log 層級篩選與單筆詳細; +- Signal 的 log 保留期限與 zip 匯出; +- AppFlowy、Namida 的 zip 診斷包; +- LX Music「切換=銷毀重建」與 VS Code「Reload Window」的插件重載; +- drift 官方 DevTools extension 作 debug build 的資料庫工具。 + +## 後果 + +- 好的: + - 開發者模式跨重啟保留,也關得掉; + - release 版可以當場查網路、播放、資料庫,並匯出已遮蔽的診斷包; + - 錯誤歷史跨重啟、可依欄位篩選; + - 本機 log 最多留 7 天; + - 重設前一定有備份; + - 不再維護守著不可能狀態的修復碼。 +- 壞的: + - 八個區塊要自己做 UI; + - log 檔改成 JSON Lines,用文字編輯器直接看比較難讀; + - 網路摘要以 info 層級寫入,會佔用記憶體歷史與 log 檔容量; + - 資料庫損壞只能從備份還原或重設。 +- 之後要注意: + - 資料庫打不開時的啟動錯誤畫面,由啟動流程的任務決定; + - Android 插件開發若要支援,需要 SAF 讀目錄的能力(file_picker 沒有),屆時另開 ADR; + - 網路摘要若擠掉記憶體歷史中的錯誤,再考慮分開上限。 + +## 如何確認 + +- 既有 lint `fmp_platform_checks`(ADR 0015):Debug 模組只讀平台層宣告的能力,不寫 `Platform.isX`。 +- 單元測試: + - 開發者模式: + - 連點 7 次開啟並寫入設定; + - 關閉時 `logLevel` 清空、開發資料夾卸載; + - dev flavor 預設開。 + - log 保留:超過 7 天的檔被刪、未滿 7 天的保留,大小與天數同時作用。 + - log 檔:JSON Lines 讀回後欄位與寫入一致;遇到壞行略過,解析不中止。 + - 網路篩選:依音源與狀態碼類別。 + - 資料檢查: + - 關掉外鍵後寫入一筆違反外鍵的列再打開,報告會列出它; + - 乾淨的資料庫報告無問題。 + - 重設:備份失敗時不清空;成功時已下載的檔案仍在。 + - 遮蔽:播放快照、資料庫瀏覽、診斷包都不含假憑證與假簽名網址(併入 ADR 0011 的遮蔽測試)。 +- widget 測試: + - 開發者模式關閉時,直接進 Debug 路由會被 redirect; + - 未宣告 `pluginDevTools` 的平台不顯示插件開發區塊; + - 未宣告檔案分享的平台不顯示「分享」。 +- 加入 Debug 頁的里程碑實測: + - Windows release 版開啟開發者模式,重啟後仍開啟,再從總開關關掉; + - 在 Debug 頁看到一次搜尋的網路摘要; + - 匯出診斷包並以解壓工具打開。 From f7f7e7131b0f6909aa7b9a48578ee3da2afab09d Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:07:56 +0800 Subject: [PATCH 108/133] chore(task): archive design-debug-page --- .../2026-09}/09-28-design-debug-page/check.jsonl | 0 .../2026-09}/09-28-design-debug-page/design.md | 2 +- .../2026-09}/09-28-design-debug-page/implement.jsonl | 0 .../2026-09}/09-28-design-debug-page/implement.md | 12 ++++++------ .../2026-09}/09-28-design-debug-page/prd.md | 2 +- .../research/current-state.md | 0 .../research/packages-and-platform.md | 0 .../09-28-design-debug-page/research/prior-art.md | 0 .../2026-09}/09-28-design-debug-page/task.json | 6 +++--- 9 files changed, 11 insertions(+), 11 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/design.md (99%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/implement.md (72%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/prd.md (98%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/research/packages-and-platform.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-debug-page/task.json (89%) diff --git a/.trellis/tasks/09-28-design-debug-page/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-debug-page/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/check.jsonl diff --git a/.trellis/tasks/09-28-design-debug-page/design.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/design.md similarity index 99% rename from .trellis/tasks/09-28-design-debug-page/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/design.md index a8a4d5ee6..f9b2afbee 100644 --- a/.trellis/tasks/09-28-design-debug-page/design.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/design.md @@ -176,7 +176,7 @@ flowchart LR - 開發者模式關閉時直接進 Debug 路由會被 redirect; - 未宣告 `pluginDevTools` 的平台不顯示插件開發區塊; - 未宣告檔案分享的平台不顯示「分享」。 -- **第一個里程碑實測**: +- **加入 Debug 頁的里程碑實測**: - Windows release 版開啟開發者模式,重啟後仍開啟,再從總開關關掉; - 在 Debug 頁看到一次搜尋的網路摘要; - 匯出診斷包並用解壓工具打開。 diff --git a/.trellis/tasks/09-28-design-debug-page/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-debug-page/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/implement.jsonl diff --git a/.trellis/tasks/09-28-design-debug-page/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/implement.md similarity index 72% rename from .trellis/tasks/09-28-design-debug-page/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/implement.md index e6ac98c7a..eefcb7fc0 100644 --- a/.trellis/tasks/09-28-design-debug-page/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/implement.md @@ -1,6 +1,6 @@ # 執行計畫:第 4 項(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0025-debug-page-and-developer-mode.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§11。 +1. [x] 核准後寫 `docs/adr/0025-debug-page-and-developer-mode.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1–§11。 被否決的方案: - 開發者模式不記住(J1 原狀); - release 版只留 log 與診斷包; @@ -12,16 +12,16 @@ - 自動修復; - 每次啟動自動檢查; - 檔案監看自動重載插件。 -2. [ ] 其他 ADR 各加一句指向 ADR 0025: +2. [x] 其他 ADR 各加一句指向 ADR 0025: - 0011:開發者模式持久化、log 保留與 JSON Lines 格式; - 0015:插件開發工具版面; - 0017:啟動維護清單加入 log 保留與診斷包暫存清理; - 0023:Debug 頁錯誤歷史。 -3. [ ] 更新 `phase2-plan.md`: +3. [x] 更新 `phase2-plan.md`(里程碑實測放在 §8「加入 Debug 頁的里程碑」,不在 §7): - §3:第 4 項標 ✅(ADR 0025); - - §7:第一個里程碑加入 §11 的實測項目; + - §8:加入 Debug 頁的里程碑實測項目; - §10:交接段更新,下一項為 7「里程碑定稿」。 -4. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用。 -5. [ ] `task.py finish`,再 `task.py archive design-debug-page --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 +4. [x] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用。 +5. [x] `task.py finish`,再 `task.py archive design-debug-page --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-debug-page/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/prd.md similarity index 98% rename from .trellis/tasks/09-28-design-debug-page/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/prd.md index 71d4b1e8d..657b32406 100644 --- a/.trellis/tasks/09-28-design-debug-page/prd.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/prd.md @@ -156,4 +156,4 @@ - [ ] ADR 0025 記下四個已決定事項,以及 `design.md` §1–§10 的設計與被否決的方案。 - [ ] ADR 0025 的「如何確認」含 `design.md` §11 的單元測試、widget 測試與第一個里程碑實測。 - [ ] ADR 0011、0015、0017、0023 各加一句指向 0025。 -- [ ] `phase2-plan.md` 的 §3(第 4 項 ✅)、§7(里程碑實測)、§10(下一項 7「里程碑定稿」)已更新。 +- [ ] `phase2-plan.md` 的 §3(第 4 項 ✅)、§8(加入 Debug 頁的里程碑實測)、§10(下一項 7「里程碑定稿」)已更新。 diff --git a/.trellis/tasks/09-28-design-debug-page/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-debug-page/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/research/current-state.md diff --git a/.trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/research/packages-and-platform.md similarity index 100% rename from .trellis/tasks/09-28-design-debug-page/research/packages-and-platform.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/research/packages-and-platform.md diff --git a/.trellis/tasks/09-28-design-debug-page/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-debug-page/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-debug-page/task.json b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/task.json similarity index 89% rename from .trellis/tasks/09-28-design-debug-page/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-debug-page/task.json index dd3d6bea7..950793ed8 100644 --- a/.trellis/tasks/09-28-design-debug-page/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-debug-page/task.json @@ -3,7 +3,7 @@ "name": "design-debug-page", "title": "Design debug page", "description": "Phase-2 item 4: developer mode entry and persistence, debug page sections (logs, error history, network, playback state, database, health check, plugin dev tools, cache, diagnostics), data integrity tools", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From b973e043049ea01e9f14f08c20359a4415e2eb47 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:10:08 +0800 Subject: [PATCH 109/133] chore(task): start design-milestones --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 3 ++- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../tasks/09-28-design-milestones/check.jsonl | 0 .../09-28-design-milestones/implement.jsonl | 0 .trellis/tasks/09-28-design-milestones/prd.md | 19 ++++++++++++++ .../tasks/09-28-design-milestones/task.json | 26 +++++++++++++++++++ 6 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-design-milestones/check.jsonl create mode 100644 .trellis/tasks/09-28-design-milestones/implement.jsonl create mode 100644 .trellis/tasks/09-28-design-milestones/prd.md create mode 100644 .trellis/tasks/09-28-design-milestones/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 3526a58e0..a010249a5 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -251,7 +251,8 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0025`;舊 ADR 0001–0007 仍描述根目錄舊專案。 - 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁。 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0026。 -- **下一項:第 7 項「重寫策略(里程碑定稿)」**:把 ADR 0008–0025 拆成可獨立驗證的里程碑與 child task;輸入含 §7 第一個里程碑的必要驗證、§8 延後的實測、§9 功能凍結例外與里程碑備忘、ADR 0008 的高層策略。 +- **進行中:第 7 項「重寫策略(里程碑定稿)」**,task `.trellis/tasks/09-28-design-milestones/`(planning):把 ADR 0008–0025 拆成可獨立驗證的里程碑與 child task;輸入含 §7 第一個里程碑的必要驗證、§8 延後的實測、§9 功能凍結例外與里程碑備忘、ADR 0008 的高層策略。 + 研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`repo-mechanics.md`),三個檔齊了才代表研究完成,接著抽查→prd→一次一問。 - 之後順序:7 里程碑定稿 → 階段三(Trellis/docs 清理)。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 1bde6a478..405367385 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -38,7 +38,8 @@ "09-28-design-release-update", "09-28-design-toast", "09-28-design-ui-ux", - "09-28-design-debug-page" + "09-28-design-debug-page", + "09-28-design-milestones" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-design-milestones/check.jsonl b/.trellis/tasks/09-28-design-milestones/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-milestones/implement.jsonl b/.trellis/tasks/09-28-design-milestones/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md new file mode 100644 index 000000000..8ba71391c --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -0,0 +1,19 @@ +# Finalize rewrite milestones + +## Goal + +Phase-2 item 7 (final): split ADR 0008-0025 into independently verifiable milestones and child tasks, with branch, release and switch-over plan + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-design-milestones/task.json b/.trellis/tasks/09-28-design-milestones/task.json new file mode 100644 index 000000000..8b918002d --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/task.json @@ -0,0 +1,26 @@ +{ + "id": "design-milestones", + "name": "design-milestones", + "title": "Finalize rewrite milestones", + "description": "Phase-2 item 7 (final): split ADR 0008-0025 into independently verifiable milestones and child tasks, with branch, release and switch-over plan", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From e7a95b8619bb8609ae806c4cceca20163fa82b44 Mon Sep 17 00:00:00 2001 From: 1morr Date: Mon, 28 Sep 2026 22:19:17 +0800 Subject: [PATCH 110/133] chore(task): add milestone research and prd --- .trellis/tasks/09-28-design-milestones/prd.md | 78 ++++++- .../research/current-state.md | 215 ++++++++++++++++++ .../research/prior-art.md | 102 +++++++++ .../research/repo-mechanics.md | 136 +++++++++++ 4 files changed, 520 insertions(+), 11 deletions(-) create mode 100644 .trellis/tasks/09-28-design-milestones/research/current-state.md create mode 100644 .trellis/tasks/09-28-design-milestones/research/prior-art.md create mode 100644 .trellis/tasks/09-28-design-milestones/research/repo-mechanics.md diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md index 8ba71391c..2c736fa3e 100644 --- a/.trellis/tasks/09-28-design-milestones/prd.md +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -1,19 +1,75 @@ -# Finalize rewrite milestones +# 重寫里程碑定稿 -## Goal +## 目標 -Phase-2 item 7 (final): split ADR 0008-0025 into independently verifiable milestones and child tasks, with branch, release and switch-over plan +階段二第 7 項的定稿部分(parent prd 第 7 項、`phase2-plan.md` §3 第 20 列)。 +把 ADR 0008–0025 拆成可以各自驗證的里程碑,並滿足兩個條件: +- 每個里程碑結束時,`app/` 都能正常運作; +- 每個 PR 大小都在擁有者能 review 的範圍內。 -## Requirements +同時定下三件事: +- 切換到新 App 的放行條件; +- 擁有者何時開始用新 App 試用; +- 追蹤方式。 -- TBD +高層策略已由 ADR 0008 決定:同 repo 的 `app/`、搬運葉節點、主幹開發、舊版可緊急修正,第一個里程碑是 tracer bullet。 -## Acceptance Criteria +## 現況(`research/current-state.md`、`research/repo-mechanics.md`,已抽查) -- [ ] TBD +- **里程碑沒有編號**:全 repo 沒有里程碑清單,只有描述性的指稱: + - 「第一個里程碑」出現在 8 份 ADR; + - 另有「加入下載的里程碑」「加入 Debug 頁的里程碑」「切換前」這類說法。 +- **第一個里程碑已累積 10 份 ADR 的必要驗證**(`phase2-plan.md` §7)。ADR 0014 自承「第一個里程碑變重」。 +- **延後的實測**(`phase2-plan.md` §8):各自掛在「加入 X 的里程碑」或平台任務。 +- **功能凍結的例外**(`phase2-plan.md` §9): + - 腳本插件、歌詞三項; + - `1morr/fmp-plugins` repo、插件頁、首次啟動引導「排入里程碑規劃,第一個里程碑不需要」。 +- **切換條件的出處不一致**: + - ADR 0008 §決定 5(`:53`)與 parent prd 完成定義(`:203`)都寫「`features.md` 中勾『保留』的功能」; + - 但 `features.md` 沒有勾選欄,實際勾選在 `questions.md`。E1–E17 保留(`:237-258`),E18–E20 在後續 ADR 已處理(0024 刪除 E20)。 +- **其他仍未落點的事**: + - ADR 0011:「各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案」; + - ADR 0017 的啟動維護清單要在哪個里程碑實作。 +- **平台順序**(ADR 0009 §決定 9、`questions.md` A1): + - Android、Windows 從第一個里程碑起全面驗證; + - Linux、macOS、iOS 從第一個里程碑起在 CI 編譯; + - Linux 在第一個里程碑後開平台任務(虛擬機);macOS、iOS 有設備後開; + - 實機驗證完才發佈。 +- **CI**: + - `ci.yml` 只有舊專案的 3 個 job,約 17–23 分鐘,刻意不加 path filter; + - ADR 0015 §9 的 `dorny/paths-filter` 切分與 5 平台矩陣都還沒實作。 +- **追蹤**: + - Trellis 的 parent/child 不是依賴系統,先後順序要寫在 child 的 prd/implement(`workflow.md:173`); + - repo 沒有 GitHub Milestones(`[]`)、沒有 issue 範本。 +- **工具鏈**:舊專案與效能基準都是 Flutter 3.47.1/Dart 3.13.1;目前 stable 是 3.47.5/Dart 3.13.4。 +- **效能基準**(`perf-baseline.md`): + - 冷啟動首幀:Android 1239ms、Windows 1731ms; + - 記憶體:Android PSS 約 179MB、Windows Working Set 約 300MB; + - 另有長列表捲動的幀時間。 -## Notes +## 研究結論(`research/prior-art.md`) -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +- **概念**: + - walking skeleton(Cockburn)與 tracer bullet(Pragmatic Programmer)都主張:先打通端到端最薄的一條,再在能運作的系統上逐層加能力。 + - Strangler Fig 與 Branch by Abstraction 適用於同一個 codebase 內換元件,不直接適用於 FMP 這種同 repo 兩個 App 的情形。 +- **案例**: + - NewPipe:`refactor` 分支、nightly 通道,舊版只收修正。結構最接近 FMP。 + - Finamp:重寫分支成為預設分支,走 beta 通道,並明說下載資料遷移可能不一致。 + - Firefox Fenix:新 App 上架,事先明文警告資料遺失,用 project board 追蹤缺口。 + - Spotube v5:以一次 major 版本當切換點。 + - Immich:同一 App 內用開關選擇 beta 時間軸。 +- **共同點**:公開可見的都是切換機制與風險聲明,查不到任何一個專案的完整里程碑清單。 + +## 待決定(一次問一題) + +1. 里程碑的切法與順序,包括舊資料匯入、Debug 頁、插件庫放在哪一步。 +2. 里程碑與 PR 的對應:里程碑底下是否再分 PR 級的子任務。 +3. 切換放行條件的細節:勾選來源改指 `questions.md`、效能重量方式、擁有者試用多久。 + +## 驗收條件 + +- [ ] 待決定項都有擁有者的答覆。 +- [ ] 產出 ADR 0026(里程碑結構與切換放行條件)與里程碑清單。 +- [ ] 清單中每個里程碑都有:範圍、依賴、驗收,以及併入的 `phase2-plan` §7/§8 項目。 +- [ ] ADR 0008 與 parent prd 的「`features.md` 勾保留」改指實際的勾選來源。 +- [ ] `phase2-plan.md` §3 第 20 列 ✅;§10 交接改為階段三。 diff --git a/.trellis/tasks/09-28-design-milestones/research/current-state.md b/.trellis/tasks/09-28-design-milestones/research/current-state.md new file mode 100644 index 000000000..ead79229e --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/research/current-state.md @@ -0,0 +1,215 @@ +# current-state — 里程碑定稿的事實盤點 + +- 任務:`09-28-design-milestones`(Phase-2 第 7 項「重寫策略(里程碑定稿)」) +- 來源優先序:程式碼 > 測試 > 文件。本檔的事實都附 `file:line`。 +- 用途:把 ADR 0008–0025、phase2-plan、parent prd、審計檔案中所有跟「里程碑怎麼切、切換條件是什麼」有關的事實攤平,**不決定**里程碑方案。 +- 讀法:§1 是逐份 ADR 的盤點;§2 是 phase2-plan 的原話;§3 是切換條件;§4 是平台順序;§5 是矛盾與未定項。 + +--- + +## 1. ADR 0008–0025 逐份盤點 + +欄位說明: +- **模組/能力**:這份 ADR 引入什麼。 +- **依賴 ADR**:文中明確以 `ADR 00xx` 字樣引用者(由 `grep -o "ADR 00[0-9][0-9]"` 收集,排序去重)。 +- **里程碑歸屬**:文中指定屬於「第一個里程碑」或特定里程碑的項目(逐字或緊貼原文)。 +- **如何確認(一行)**:該 ADR §如何確認 的閘門摘要。 + +| ADR | 模組/能力 | 依賴 ADR | 里程碑歸屬 | 如何確認(一行) | +|---|---|---|---|---| +| **0008** 新 App 同 repo | `app/` 新專案、main 分支、舊專案凍結;葉節點複製;App 身分沿用(`applicationId`/AppUserModelID/Inno AppId/簽名金鑰) | 0014, 0015 | 第一個里程碑=tracer bullet:**一個音源能搜尋並播放,Android 與 Windows 跑通**(:44)。切換前的里程碑另加一項檢查:比對 `app/` 的 `applicationId`、AppUserModelID、Inno AppId 與現值一致(:73) | lint `fmp_layer_imports`(`app/` 不 import 舊專案);測試斷言 prod flavor 身分值;切換 PR 的 review 指南逐項列 `features.md` 勾「保留」的功能與效能量測(:70-74) | +| **0009** 平台層+能力宣告 | `app/lib/platform/`(每能力一目錄)、`PlatformCapabilities` 不可變宣告、Pigeon、平台套件只在實作檔、不寫空實作 | 0015, 0018, 0020, 0021, 0022 | 上線順序(決定 9,:55-57):**Android、Windows 從第一個里程碑起全面驗證**;**Linux、macOS、iOS 從第一個里程碑起在 CI 編譯**(iOS 加模擬器測試);**Linux 在第一個里程碑後開 child task** 於虛擬機實機驗證、之後每個里程碑冒煙測試;macOS/iOS 取得設備後各開 child task;各平台**實機驗證完成後才發佈**。CI 建置矩陣含 Linux/macOS/iOS(不簽名)從第一個里程碑起(:82) | lint `fmp_platform_checks` + `fmp_layer_imports`;每個平台 child task 驗收含「宣告為沒有的能力,UI 不出現入口」(:78-82) | +| **0010** drift 資料層+legacy_import | drift+sqlite3(native assets);`legacy_import/` 一次性模組;schema 版本 `kFmpSchemaVersion` | 0002, 0005, 0008, 0009, 0015 | 第一個里程碑在 Android、Windows 實測:`isar_community` 與 `sqlite3` 兩套原生庫共存(若衝突,legacy import 改成新 App 啟動的獨立一次性小程式);`sqlite3` 的 **Android 16KB page size 對齊**(用官方對齊檢查)(:71-72) | schema 快照+每個 migration 升級測試在 CI;「migration 不改使用者設定值」專門測試;`fmp_layer_imports`(`legacy_import` 不被 import、DB 只由資料層存取);切換前在擁有者真實資料副本跑完整匯入並把筆數比對附在切換 PR 的 review 指南(:75-79) | +| **0011** 設定+log 門面 | 單一 log 門面+單一遮蔽函式;設定 schema(新增音源不改 schema) | 0009, 0010, 0015, 0024, 0025 | **log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試**(phase2-plan §7 :224)。log 保留 7 天/JSON Lines/開發者模式持久化延到 ADR 0025(:55) | lint `fmp_log_facade`;遮蔽測試(每音源假憑證+假簽名 URL,經 log 檔/記憶體歷史/診斷包/網路紀錄都不出現,**含 stackTrace**);設定測試(使用者值不被新預設覆蓋)(:57-61) | +| **0012** 網路層+帳號 | HTTP client、`CredentialStore`、`AuthRequirement` 單一宣告點、媒體請求不帶憑證 | 0009, 0010, 0011 | **YouTube App 內網頁登入是否可用 → 第一個加入 YouTube 登入的里程碑先實測**(:64);Linux 沒有 keyring 時 secure storage 行為 → Linux child task(phase2-plan §8 :235) | 契約測試媒體請求不帶 Cookie/Authorization;`AuthRequirement` 三態(未登入/已登入開關開/已登入開關關)注入結果;刷新後重送帶新憑證;每音源「憑證無效」判定表(限流與網路錯誤碼不誤標失效);登出/重設後 `CredentialStore` 為空(:68-72) | +| **0013** 統一錯誤模型 | sealed `AppError`;重試只在網路層(指數退避+jitter、上限 2、尊重 `Retry-After`);Riverpod retry 關閉 | 0011, 0012, 0015, 0018, 0023 | 無第一個里程碑專屬項;重試與錯誤對應表貫穿 | 契約測試錯誤 fixture 對到 `AppError` 類別;`ProviderScope` retry 關閉、只對冪等請求重試;lint `fmp_no_empty_catch`;UI 不得顯示 `toString()`(以只收 i18n key 的呈現 API 在型別上擋)(:72-77) | +| **0014** 腳本音源插件 | 插件為執行期 JS 腳本(flutter_js:QuickJS Android/Windows/Linux、JavaScriptCore iOS/macOS、ES2020);manifest+宿主 API v1;`apiVersion` 相容管理;無內建音源 | 0008, 0009, 0011, 0012, 0015, 0016, 0018, 0019, 0020, 0021 | **第一個里程碑變重**(要先有 JS 執行環境與宿主 API)(:65)。第一個里程碑實測:flutter_js 在 Android/Windows 的 **Promise/記憶體/啟動成本**;以「從檔案安裝」載入第一個腳本音源;**YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)**(:65、§7 :225)。**插件庫 repo 與插件頁的建立時程在里程碑規劃定**(:67);§9:建 `1morr/fmp-plugins` repo/CI/`index.json`/App 插件頁與首次啟動引導**排入里程碑規劃,第一個里程碑不需要**(:247) | 結構測試 manifest 能力 vs 實際匯出函式、`apiVersion` 不相容拒絕載入;契約測試重播;宿主 HTTP 只准 manifest 網域;腳本無法讀其他插件的 storage/憑證;lint `fmp_source_id_literal`(:70-75) | +| **0015** 測試/閘門/開發環境 | `app/packages/fmp_lints/`(`analysis_server_plugin`)10 條 lint+後續規則;flavor dev/prod 隔離;`dorny/paths-filter` CI 依專案切分;零聯網(`dart_test.yaml` live skip+`HttpOverrides.global`);`checks.json` 一份四用 | 0008, 0011, 0014, 0017, 0021, 0023, 0024, 0025 | 第一個里程碑實測:`dart analyze` 看得到插件診斷且接線哨兵會紅(比對 `flutter analyze`);**契約執行器能否在 `flutter test` 內載入 QuickJS**(不行改用桌面 `integration_test`);dev 與 prod 同時開啟時 AppUserModelID/單一實例鎖/資料目錄各自獨立;**零聯網兩道防線**(故意聯網的測試被跳過、解除 tag 後被 `HttpOverrides` 擋下)(:93-94、§7 :226)。`app` 的 CI job 內容列在 :9(決定 9) | 每條 lint 規則 `analyzer_testing` 雙向變異測試+CI 接線哨兵;測試 prod 身分值、dev 每項都不同、開發版拒舊版正式資料路徑、掃描所有 fixture 無未遮蔽憑證(:31-96) | +| **0016** 快取與離線 | 統一快取庫(cache.db)、串流 URL 只放記憶體、`expiresAt`、離線判定以請求結果為準(不輪詢 DNS) | 0011, 0012, 0014, 0015, 0017, 0018, 0021 | 無第一個里程碑專屬項;B10「每 15 秒 DNS 偵測」在此拿掉(phase2-plan §5 :189) | 單元:串流 URL 快取安全邊界、`expiresAt` 空、作廢、下載不走快取、**預取後播放只解析一次**;快取跨類別淘汰到上限以下、移除插件刪其項目;網路狀態轉換且**沒有計時器輪詢**;widget 各頁離線狀態;插件契約 `expiresAt` 對 fixture 網址期限參數(:60-66) | +| **0017** 背景任務排程器 | 單一 `BackgroundScheduler`(一個計時器、指向最早到期);只在可見且在線時跑;到期補跑;啟動維護清單 | 0010, 0011, 0013, 0015, 0016, 0018, 0021, 0022, 0025 | 啟動維護清單「第一個畫面後依序跑一次」(:33);ADR 0025 加入 log 保留期限與診斷包暫存清理 | 單元(假時鐘/生命週期/網路):看不見與離線不跑;恢復後到期工作各跑一次;只有一個計時器;手動刷新不看間隔;停用後丟過期結果;退避與 `retryAfter`;上次成功時間重啟後生效。lint `fmp_periodic_timer_owner`(ADR 0021 加桌面歌詞查游標允許擁有者)(:55-66) | +| **0018** 播放核心 | 單一 `PlaybackController`;兩後端(JustAudioBackend Android/iOS/macOS、MediaKitBackend Windows/Linux);Dart 側 `QueueModel`;`RecoveryPolicy` | 0003, 0009, 0013, 0015, 0016, 0017, 0020 | **第一個里程碑實測:兩個後端的前瞻交接(gapless);Android 換歌時不釋放音訊焦點**(:85)。蘋果平台 AVPlayer 對 B 站 DASH/HLS → iOS/macOS child task(§8 :236) | 單元:`QueueModel`(隨機位置語意、拖曳、連續下一首、臨時播放快照、Mix 修剪、上限)、`RecoveryPolicy`、開直播取消進行中音樂請求、預取後播放只解析一次、單曲循環每圈一筆歷史不重解析;後端契約測試同一份純規則跑兩實作+假後端;lint `fmp_layer_imports` 依賴表(`just_audio`/`media_kit` 只在後端實作、結束原因型別只給後端與路由器、串流窄介面只給 `PlaybackSession`)(:72-85) | +| **0019** 音樂庫與同步 | 關聯表(外鍵)、匯入歌單刷新、共用匹配核心(`unorm_dart`/`opencc`/`string_similarity`) | 0005, 0010, 0012, 0013, 0014, 0015, 0017 | 無第一個里程碑專屬項;`opencc` native assets 要在各平台建置驗證(:78 後果) | 單元:刷新差異(新增/移除/順序/元資料/覆寫旗標/部分失敗不移除/重複影片保留/來源失效停止自動刷新/重新匯入不覆寫設定);評分核心(全半形/繁簡/括號/時長/多歌手,自動與手動同分);資料庫測試(外鍵連帶刪除、孤兒清理只刪無人參照、刷新中途失敗一致性);插件契約 `importPlaylist` 分頁完整性、`libraryWrite` 錯誤對應(:81-87) | +| **0020** 下載與權限 | `background_downloader`;`PermissionGateway`;sidecar/內嵌標籤;對帳 | 0004, 0011, 0012, 0015, 0017, 0019, 0021, 0022 | **加入下載的里程碑實測**:`permission_handler` 在 Windows 是否使 FMP 出現位置權限清單(會就改 Android 專用自有 MethodChannel);寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾可行(:107-110) | 單元(假下載器):並行上限、失敗任務跨重啟保留、網址過期重解析從頭下載、ETag 不符從頭下載、格式過濾、暫存→標籤→搬移任一步失敗不留半成品;對帳測試(檔案遺失不刪紀錄、從不刪檔);路徑測試(檔名清理、Windows 長度、保留名);權限流程測試(假 `PermissionGateway`);`fmp_layer_imports`(`background_downloader` 只在下載模組、`permission_handler` 只在平台層)(:94-110) | +| **0021** 歌詞 | 多源歌詞(插件 `lyrics`/`aiAssist` 能力)、逐行/逐字、桌面歌詞視窗、Android 懸浮歌詞、iOS Live Activity;型別化訊息 | 0009, 0010, 0011, 0012, 0014, 0015, 0016, 0017, 0019, 0020, 0023, 0024 | **逐字渲染用 `flutter_lyric`(避開已撤回 3.0.5)或自寫 → 在第一個加入逐字的里程碑決定**(:143);平台實測延後:桌面歌詞 macOS/Linux X11/Wayland 的穿透置頂定位、`window_manager` 在子 engine、`flutter_overlay_window` 記憶體與 Android 15 前景服務限制、iOS Live Activity 本機逐行更新(:161-165、§8 :237) | 單元(LRC 解析含 enhanced 字時間、翻譯 100ms 對齊、逐字→逐行降級、匹配流程各分支、偏移換算、顯示端外推);插件契約 `lyrics`/`aiAssist`(AI 插件測試斷言 log 不含 payload);宿主測試(AI 只含設定頁欄位、非 https 拒、網域確認);型別化訊息序列化往返;lint `fmp_periodic_timer_owner` 加桌面歌詞查游標、`fmp_layer_imports`(`desktop_multi_window`/`window_manager`/`flutter_overlay_window` 只在平台層實作檔)(:145-160) | +| **0022** 發版與應用內更新 | release-please(dart strategy、manifest 模式);首版 `Release-As: 2.0.0`;versionCode = major×1000000+minor×1000+patch;`appUpdate` 平台能力 | 0004, 0008, 0009, 0010, 0011, 0012, 0013, 0015, 0017, 0020 | 第一個里程碑:**release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(測試 repo 或 dry-run)**(§7 :227)。**切換 PR 前以舊版 v1.11.0 實際更新到新 App**(Android、Windows 安裝版與免安裝版);Windows App 自下載安裝檔不帶 Mark of the Web;macOS 更新不帶 quarantine(平台任務);Linux AppImage 改名替換(:139-143、§8 :240) | 單元(版本比較含 build number、依能力挑 asset 與 ABI 退回、checksums 解析/缺檔拒/digest 不符拒、RateLimited、狀態機與操作代際、清理只刪不大於目前版本、更新程式改名替換與失敗回復、zip-slip);workflow 測試(release-please 輸出否時不建置、verify 檔名集合/checksums/別名/APK 版本/PE 標頭/舊版更新器相容、pubspec 版本等於 manifest);`fmp_layer_imports`(:123-138) | +| **0023** 統一 Toast | 單一 `Toaster` 入口(provider 注入)、`ToastHost` 包住 Navigator、`ErrorReport`、錯誤詳細頁與 GitHub 回報 | 0011, 0013, 0015, 0021, 0025 | **第一個里程碑實測**:提示在全螢幕頁與對話框之上可見;**Windows Narrator 下提示不凍結無障礙樹**(:101)。之後注意:repo 目前**沒有 issue 範本**,落地時新增 `.github/ISSUE_TEMPLATE/bug_report.yml`(:89) | lint `fmp_toast_entry`(`SnackBar(`/`ScaffoldMessenger.of`/`showSnackBar`/`clearSnackBars` 只准在 toast 模組,雙向變異測試);單元(去重視窗/取代/時長/開發者與一般使用者按鈕/`ErrorReport` 經遮蔽/GitHub 網址不含報告);widget(全螢幕路由與對話框開啟時提示可見、底部位移依外殼發佈高度)(:91-101) | +| **0024** UI/UX 設計系統 | Material 3+`AppTokens` ThemeExtension;五個 WindowClass 斷點;i18n slang base `zh-TW` 三語言;App 內快捷鍵(F6/Esc/space);播放頁方案 B | 0009, 0011, 0015, 0021, 0023 | **第一個里程碑實測:輸入框內空白鍵不觸發播放;F6 焦點切換;Windows 繁中字形由正黑體顯示**(:159) | lint `fmp_design_tokens`(`lib/ui/`(theme 除外)不得在 `EdgeInsets.*`/`SizedBox` 寬高/`BorderRadius.circular`/`fontSize:` 用數字字面值(0 除外),不得寫 `Color(0x…)`/`Colors.*`);widget(首頁/搜尋/歌單/播放頁/設定淺深主題通過 `labeledTapTargetGuideline` 與 `textContrastGuideline`、快捷鍵與焦點含輸入框內空白鍵、播放列三段寬度曲名 ≥160dp);golden(alchemist 播放頁 B 在 1000/1400/1800 寬);i18n 三語言 key 集合相同(:149-159) | +| **0025** Debug 頁與開發者模式 | 8 區塊 Debug 頁;開發者模式持久化於設定;log JSON Lines、2MB×3、7 天保留;診斷包 | 0009, 0010, 0011, 0012, 0015, 0016, 0017, 0018, 0019, 0020, 0023, 0024 | **加入 Debug 頁的里程碑實測**:Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出診斷包能以解壓工具打開(:207-210、§8 :239) | lint `fmp_platform_checks`(Debug 模組只讀平台層宣告,不寫 `Platform.isX`);單元(開發者模式 7 連點/關閉清空/dev 預設開;7 天保留;JSON Lines 讀回一致且壞行略過;網路篩選;資料檢查外鍵報告;重設備份失敗不清空;遮蔽併入 0011);widget(關閉時直進 Debug 路由會被 redirect、未宣告 `pluginDevTools` 不顯示插件開發區塊、未宣告檔案分享不顯示)(:187-206) | + +補充依賴:ADR 0002 `repository-boundary` 引用 0008、0010;ADR 0007 `isar-stays-on-v3` 引用 0008、0010。舊 ADR 0001–0007 描述的是根目錄舊專案(phase2-plan §10 :252)。 + +--- + +## 2. phase2-plan 的原話(逐條引用) + +檔案:`.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md` + +### §1 設計項目(:8-34)— 第 7 項與第 20 項 + +> `| 7 | 重寫策略(全新 vs 逐步、里程碑、分支、舊版 hotfix) | N1 hotfix 已選「重寫時處理」 |`(:21) + +> `| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) |`(:34) + +### §3 建議順序(:109-132)— 第 2 與第 20 列的里程碑說明 + +> `| 2 | 7 重寫策略(高層)(✅ 完成,ADR 0008;里程碑留到第 20 步定稿) | 「全新專案 vs 在舊碼上逐步替換」決定資料遷移、分支與每個里程碑的形狀。這裡只定方向,里程碑到最後才拆。 |`(:113) + +> `| 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 |`(:131) + +### §7 第一個里程碑的必要驗證(:219-230) + +> `- ADR 0010:isar_community+sqlite3 原生庫在 Android、Windows 共存;sqlite3 的 Android 16KB page size 對齊。` +> `- ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。` +> `- ADR 0008:app/ 的 App 身分識別與舊版一致(開發版除外)。` +> `- ADR 0011:log 門面與遮蔽函式是第一個里程碑的基礎,含遮蔽測試。` +> `- ADR 0014:JS 執行環境(flutter_js)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;flutter_js 在 Android、Windows 的 Promise/記憶體/啟動成本實測;YouTube.js 可行性驗證(有時限,失敗則 YouTube 暫以 Dart 實作)。` +> `- ADR 0018:兩個後端的前瞻交接(gapless);Android 換歌時不釋放音訊焦點。` +> `- ADR 0015:fmp_lints 接上 app/,dart analyze 看得到插件診斷且接線哨兵會紅(比對 flutter analyze);契約執行器能否在 flutter test 內載入 QuickJS(不行改用桌面 integration_test);dev 與 prod flavor 同時開啟時 AppUserModelID、單一實例鎖、資料目錄各自獨立;零聯網兩道防線(故意聯網的測試被跳過、解除 tag 後被 HttpOverrides 擋下)。` +> `- ADR 0022:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(測試 repo 或 dry-run)。` +> `- ADR 0023:提示在全螢幕頁與對話框之上可見;Windows Narrator 下提示不凍結無障礙樹。` +> `- ADR 0024:輸入框內空白鍵只輸入空格;F6 焦點切換;Windows 繁中字形由正黑體顯示。` + +### §8 延後到特定里程碑的實測(:232-240) + +> `- ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。` +> `- ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。` +> `- ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。` +> `- ADR 0020:加入下載的里程碑——permission_handler 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 MANAGE_EXTERNAL_STORAGE 搬移到使用者資料夾。` +> `- ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;window_manager 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——flutter_overlay_window 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——flutter_lyric 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。` +> `- ADR 0025:加入 Debug 頁的里程碑——Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出的診斷包能以解壓工具打開。` +> `- ADR 0022:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版);Windows App 自行下載的安裝檔不帶 Mark of the Web。macOS 平台任務——App 自行下載的更新不帶 quarantine。Linux 平台任務——AppImage 的改名替換。` + +### §9 功能凍結的例外與里程碑規劃備忘(:242-247) + +> `- 腳本插件(ADR 0014)由擁有者明確納入重寫範圍(2026-09-27)。` +> `- 歌詞的逐字歌詞、桌面歌詞點擊穿透與鎖定、Android/iOS 懸浮歌詞由擁有者納入第 15 項(2026-09-28)。` +> `- 以上是功能凍結僅有的例外。` +> `- 建立 1morr/fmp-plugins repo、其 CI 與 index.json、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。` + +### §10 交接(:249-269,節錄) + +> `- 分支:docs/audit(draft PR #173)。所有設計決定以 ADR 為準:docs/adr/0008–0025;舊 ADR 0001–0007 仍描述根目錄舊專案。`(:251) +> `- 每項的 prd/design/research 在 .trellis/tasks/archive/2026-09/09-2?-design-*。下一份 ADR 編號 0026。`(:254) +> `- 每項固定流程:建 child task(task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 task.py start、寫 ADR、更新本檔 §3 標記完成、task.py finish+archive --no-commit --skip-branch-validation、commit+push。`(:257) + +--- + +## 3. 切換條件(ADR 0008 §決定 5)與「保留」清單的真實出處 + +### 3.1 ADR 0008 §決定 5(`docs/adr/0008-rewrite-as-new-app-in-same-repo.md:53-57`) + +> `5. 切換:docs/audit/features.md 中勾「保留」的功能全部在 app/ 跑通、效能不低於 docs/audit/perf-baseline.md、舊資料自動遷移在真實資料副本上驗證過之後,以一個 PR 刪除根目錄舊專案與 docs/audit/,並把 release.yml、ci.yml、orca.yaml、tool/release/ 改指向 app/。新 App 的第一個正式版本號接在舊版之後,經應用內更新送達,首次啟動執行自動遷移。` + +三個必要條件(切換 PR 的前提):(a) 勾「保留」功能全部在 `app/` 跑通;(b) 效能不低於 `perf-baseline.md`;(c) 舊資料自動遷移在**真實資料副本**上驗證過。切換動作是一個 PR,同時刪舊專案與 `docs/audit/`、改四個檔案指向 `app/`。 + +### 3.2 「保留」清單的真實出處(**與 ADR 0008 的措辭不一致**) + +- `docs/audit/features.md`(446 行,16 節)**沒有勾選欄**:全檔 `[x]` 出現 0 次(`grep -c -F '\[x\]'` = 0);「保留」只出現 2 次、「刪除」14 次、「修改」1 次,都在敘述文字裡,不是決策標記。 +- 實際的勾選在 `docs/audit/questions.md`(137 個 `[x\]`)。其中 §7 E 項(`:232-263`)自述: + +> `完整清單在 features.md;這裡只列需要你表態的功能域。狀態欄沿用 features.md 的判定。`(:234) + +→ 里程碑定稿時必須**以 `questions.md` 為勾選來源**,`features.md` 當功能清單。否則 features.md 有幾百條功能沒有去留標記。(列為 §5 待確認第 1 條。) + +### 3.3 依 questions.md 的勾選統計(依 §節分組,附行號) + +| 節 | 主題 | 已勾結果 | 行號 | +|---|---|---|---| +| §1 A1 | 目標平台 | **Android、Windows=「重寫第一版就要」**;**Linux、macOS、iOS=「之後加入」** | :31-35 | +| §1 A2 | 資料層是否更換 | **不確定**(保留 isar_community vs 更換都未勾) | :53 | +| §1 A3 | 資料相容 | 資料庫(歌單/曲目/歷史/設定/佇列)、登入憑證、已下載音檔與 sidecar、備份檔 **4/4=「保留並自動遷移」**(備份檔另註「新版能匯入舊備份」) | :62-65 | +| §1 A6 | 發佈平台 | Android、Windows、Linux、macOS=GitHub Release;**iOS 不確定**;另「維持自動發布」(推翻 ADR 0006 的選項未勾) | :95-99, :102 | +| §2 B項 | 對外寫入/第三方/自下載 | B1、B2 **保留**;B3–B14 **不確定** | :115-128 | +| §3 C項 | 安全與隱私缺陷 | C1–C7 **重寫時修正** | :140-146 | +| §4 M項 | 帳號與登入狀態播放 | M1–M13 **全部不確定** | :160-172 | +| §5 N項 | 下載與權限 | N1 **「先不修,重寫時處理」**;N2–N11 不確定 | :185, :190-198 | +| §6 D項 | 播放行為語意 | D1、D2、D7 **保留**;其餘不確定 | :212-223 | +| §7 E項 | 功能去留 | **E1–E17 保留(17/20)**;E18–E20 不確定 | :237-258 | +| §8 | 平台綁定功能在他平台去留 | 12 列**全部不確定** | :270-283 | +| §9 G項 | 架構與程式碼現況問題 | G1–G9 **重寫時處理** | :295-305 | +| §10 | 測試類別去留 | 7 列**全部不確定**;另勾「不管,重寫時處理」(main CI 現為紅) | :317-330 | +| §11 | i18n | **en、zh-CN、zh-TW 三語言保留** | :341-350 | +| §12 U項 | UI/UX 問題 | U1–U9 **重寫時處理**(U7 註「保留常駐」、U8 註「實作」、U9 註「開發版用獨立資料目錄」) | :360-370 | +| §13 J項 | 開發者模式與 log | J1 **保留**;J2–J4 不確定 | :380-385 | +| §14 §15 | ADR 逐份/CONTEXT.md 術語 | **全部未勾** | :397-405, :417-423 | + +E 項 20 條功能域(`:237-258`):E1 三音源搜尋播放、E2 B 站分 P、E3 音樂庫歌單、E4 匯入平台歌單+定時刷新、E5 僅匯入外部歌單匹配、E6 帳號登入、E7 遠端歌單編輯、E8 下載、E9 多源歌詞、E10 AI 歌詞匹配、E11 桌面歌詞視窗、E12 電台直播、E13 Mix、E14 首頁排行、E15 播放歷史、E16 備份還原、E17 應用內更新 → 全「保留」;E18 托盤/快捷鍵/開機自啟/單一實例、E19 播放速度/音量/輸出裝置(無睡眠定時器與均衡器)、E20 使用者指南頁 → 不確定。 + +### 3.4 效能基準 `docs/audit/perf-baseline.md` 量了什麼 + +- 量測日 2026-09-26,分支 `docs/audit`,HEAD `6d78fe23`(:5)。環境:**Flutter 3.47.1 stable(framework `6655482ec0`、engine `11d79658c4`)、Dart 3.13.1**(:13);profile build。 + +| 指標 | Android(AVD Medium_Phone) | Windows | +|---|---|---| +| 冷啟動到首幀 `timeToFirstFrameMicros`(3 次中位數) | **1239 ms** | **1731 ms** | +| 首幀完成光柵化 `timeToFirstFrameRasterizedMicros` | 1292 ms | 1752 ms | +| `am start -W` TotalTime(中位數) | 1482 ms | — | +| 首頁穩定後記憶體 | PSS **183,367 KB**(≈179 MB)/RSS 310,752 KB | Working Set **299.9 MB**/Private **440.6 MB** | +| 長列表捲動 UI thread `Animator::BeginFrame` 中位數/p99 | 1.00 ms/4.18 ms(歌單 154 首) | 0.45 ms/5.45 ms(佇列 1195 首) | +| 長列表捲動 raster `GPURasterizer::Draw` 中位數/p99 | 4.27 ms/21.62 ms | 1.96 ms/2.72 ms | +| 捲動中 >16.7 ms 的 raster 幀 | 43/302、17/306 | 0/312、0/316 | + +(:28-36、:184-199。)Android AVD:`Medium_Phone` API 37(`android-37.2-beta3` google_apis_playstore ps16k x86_64)、4 vCPU、2048 MB RAM、1080×2400 @ 420 dpi(:15)。此檔自述「這份文件是重寫後的比較基準:每個數字都附量測命令與原始輸出摘錄,重寫後用同一組命令重量即可對照」(:5)。 + +--- + +## 4. parent prd 的里程碑約束與平台順序 + +檔案:`.trellis/tasks/09-26-fmp-rewrite/prd.md` + +### 4.1 第 7 項原文(:130-132) + +> `7. 重寫策略 —— 全新重寫 vs 逐步替換,給建議與理由;` +> ` 拆成可獨立驗證的里程碑,每個里程碑結束時 App 都能正常運作。` +> ` 說明分支與發版策略:重寫期間舊版的修正在哪裡做、使用者跳版升級時資料與憑證如何遷移。` + +### 4.2 重構過程的約束(:198-206) + +> `- 可 review 性優先:每個 child task 產出一個 PR,大小控制在我能 review 的範圍,太大就拆;每個 PR 附 review 指南(改了什麼、為什麼、我該看哪幾個檔案、怎麼實際驗證);沒有經我確認的 ADR 的設計,不進代碼。` +> `- 功能凍結:重寫期間不加新功能,想到的記進 parent task 的待辦,不實作。` +> `- 完成定義:features.md 中我勾「保留」的功能全部在新架構上跑通,且效能不低於階段一記錄的基準。` +> `- 重寫期間不發布正式版本;舊版的緊急修正怎麼處理,在階段二的重寫策略中提出方案。` +> `- 參考其他開源專案時只參考設計;要複製代碼,先確認授權相容並告訴我。` + +### 4.3 Trellis 任務管理(:208-212) + +> `- 建立 parent task fmp-rewrite,把這整份 prompt 原文存成它的 prd.md。` +> `- 階段一建成它的第一個 child task audit(只寫 PRD,屬於輕量任務),然後開始執行。` +> `- 之後每個里程碑、每個新平台各是 fmp-rewrite 下的一個 child task,規劃時用 trellis-brainstorm 與我逐項確認,各自有 prd/design/implement。` + +→ **每個里程碑是一個 child task;每個新平台也是一個 child task**,兩者都要有 prd/design/implement。 + +### 4.4 平台相關(第 10 項,:156 附近) + +> Linux 早列為第三平台以驗證抽象;macOS/iOS 以 GitHub Actions macOS runner 做編譯檢查 + iOS 模擬器,實機之後;每個平台是一個 child task 並註明需要的硬體/環境。 + +### 4.5 平台順序(ADR 0009 §決定 9 :55-57 + questions.md A1 :31-35) + +- **第一版就要**:Android、Windows。兩者從第一個里程碑起**全面驗證**。 +- **之後加入**:Linux、macOS、iOS。三者從第一個里程碑起**在 CI 編譯**(iOS 加模擬器測試),但**實機驗證完成後才發佈**。 +- Linux:第一個里程碑後開 child task,於虛擬機實機驗證,之後每個里程碑冒煙測試。 +- macOS、iOS:取得設備後各開 child task。 + +--- + +## 5. 矛盾與未定項(「待確認」) + +1. **勾選來源不一致**:ADR 0008 §決定 5(:53)與 parent prd 完成定義(:203)都寫「`features.md` 中勾『保留』的功能」,但 `features.md` 沒有任何勾選欄(0 個 `[x]`);真正的勾選在 `questions.md`,其 §7 E 項(:232-263)自述「完整清單在 features.md;這裡只列需要你表態的功能域」。**里程碑定稿要指名以 questions.md 為準。** +2. **「切換前的里程碑」沒有編號**:ADR 0008 :73(身分比對)、ADR 0010 :79(真實資料副本匯入)、ADR 0022 :139-143(以 v1.11.0 實際升級)都說「切換前/切換 PR 前」,但沒有任何文件把「切換里程碑」命名或編號。里程碑切法要自己定。 +3. **第一個里程碑的 CI 矩陣是 5 平台,第一版只發 2 平台**:ADR 0009 :82 要求 CI 從第一個里程碑起含 Linux/macOS/iOS 不簽名建置,而 questions A1 說那三個平台「之後加入」。不是直接矛盾(編譯 ≠ 發布),但里程碑驗收要寫清楚。 +4. **第一個里程碑明顯偏重**:ADR 0014 :65 自陳「第一個里程碑變重(要先有 JS 執行環境與宿主 API)」,phase2-plan §7 又疊了 10 份 ADR 的實測項。§7 的項目是否全塞同一個里程碑、或再切成 tracer bullet + 第二里程碑,尚無定論。 +5. **功能凍結例外與里程碑規劃的掛勾**:phase2-plan §9 :247 把「建 `1morr/fmp-plugins` repo/CI/`index.json`/插件頁/首次啟動引導」排進里程碑規劃但「第一個里程碑不需要」;這些要有明確落點,否則會漏。 +6. **ADR 0011 的未定項**::55「各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案」——里程碑計畫要承接這一項。 +7. **啟動維護清單的跨 ADR 歸屬**:ADR 0017 :33 定義清單,ADR 0025 加入 log 保留期限與診斷包暫存清理;哪個里程碑實作未定。 +8. **效能基準的可比性**:`perf-baseline.md` 用 Flutter 3.47.1(:13);`app/` 會從當前 stable(3.47.5)起(見 `repo-mechanics.md`)。切換條件「效能不低於基準」要用同一組命令重量,引擎版本差異要先記錄。 +9. **舊 ADR 與新 ADR 並存**:ADR 0001–0007 描述根目錄舊專案(phase2-plan :252),切換 PR 要刪 `docs/audit/`;這些舊 ADR 的去留未在同一處寫明。 + +--- + +## 查不到/推測 + +- **查不到**:任何「里程碑」的既有編號、名稱或數量。全部 ADR 只有「第一個里程碑」「加入下載的里程碑」「加入 Debug 頁的里程碑」這類描述性指稱,沒有 M1/M2 這種清單。 +- **查不到**:`features.md` 的「保留」勾選欄。ADR 0008 與 parent prd 都指向它,但檔案裡沒有(見 §5 第 1 條)。 +- **查不到**:切換里程碑的正式名稱或它在順序中的位置。 +- **推測**:§3.3 的統計是依 `grep` 到的 `[x\]` 標記與表格欄位對位;`[x\]` 是轉義過的字面(`\[x\]`),一般 Markdown 檢視器可能不把它渲染成勾選框。 +- **推測**:`perf-baseline.md` 的 Windows 數字是在同一台主機、載入 1195 首佇列與 Detail Panel 的狀態下量的(:139 自述),換到 `app/` 後若首頁預設狀態不同,數字不可直接比;需以「同一組命令、同一初始狀態」重測。 diff --git a/.trellis/tasks/09-28-design-milestones/research/prior-art.md b/.trellis/tasks/09-28-design-milestones/research/prior-art.md new file mode 100644 index 000000000..1b5da5bbd --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/research/prior-art.md @@ -0,0 +1,102 @@ +# prior-art — 大型重寫怎麼切成里程碑、怎麼把使用者切過去 + +- 任務:`09-28-design-milestones`。本檔只收事實與來源,**不決定**里程碑方案。 +- 來源規則:repo 內程式碼/文件用 GitHub permalink(**固定 40 字元 SHA**);部落格、官方公告用原文連結。所有推論標 **推測**。 +- 已核對:本檔引用的每個 permalink,其 SHA 與路徑都以 `gh api repos///commits/` 與 `contents?ref=` 驗證存在(2026-09-28)。 + +--- + +## 1. 概念:排序策略的詞彙 + +| 概念 | 一句話 | 來源 | +|---|---|---| +| **Walking skeleton**(走動的骨架) | 先做一個「端到端可跑、但功能極薄」的骨架,把所有層與佈署管線接起來;之後每次都在**已能運作**的系統上加肉。定義出自 Alistair Cockburn《Writing Effective Use Cases》(Addison-Wesley, 2000) 的 "walking skeleton" 用法 | Cockburn, *Writing Effective Use Cases*, 2000(書,無線上 permalink) | +| **Tracer bullets**(曳光彈) | 用一小發「打得到目標」的實作把需求到佈署的整條路徑先打通,再逐發修正準度;與 walking skeleton 常被並用,差別在曳光彈強調**先取得回饋再校準** | Hunt & Thomas, *The Pragmatic Programmer*, 2nd ed. (2019), Topic 12 "Tracer Bullets" | +| **Strangler Fig**(絞殺榕) | 在舊系統旁長出新實作,逐塊把請求導過去,直到舊系統可移除;不需一次替換整個系統 | (2004 初版,2019-04-29 改名為 Strangler Fig) | +| **Branch by Abstraction** | 在程式內建立一層抽象,讓新舊實作可並存切換,避免長期 feature branch;適合「替換內部元件」而非「替換整個 app」 | (2014-01-07) | +| **Feature Toggles** | 用開關控制新舊路徑;Fowler/Hodgson 把它分成 release / experiment / ops / permission 四類,並強調**每種開關有對應的移除時機**(release toggle 上線後應刪) | Pete Hodgson, (2017-10-09) | +| **Vertical slice vs layer-by-layer** | 垂直切片=一次做完某功能的 UI→邏輯→資料;分層=一層一層做完(先全資料層,再全 UI)。業界實務文獻普遍主張重寫前期用垂直切片(與 walking skeleton/tracer bullet 同源),分層適合**替代方案已存在、只是換實作**的場景 | 無單一權威出處;**推測**(見 §4) | +| **Parity checklist / cut-over gate** | 「切換前必須逐項確認舊功能都對得上」的清單,與「切換當下的放行條件」 | 業界口語,**推測**(見 §4) | + +**推測**:Strangler Fig 與 Branch by Abstraction 都預設「同一個 codebase 內新舊並存、可切換」;FMP 的做法(`app/` 與舊專案同 repo 並存、各自獨立建置)更像**同一 repo 內兩個 app 的平行存在**,不是單一服務的絞殺。兩者能借的是「舊系統在切換完成前持續可修」與「切換是一次明確的放行事件」,不是「同進程切流量」。 + +--- + +## 2. 案例:成熟專案怎麼做 + +### 2.1 Immich — 新版時間軸放開關,使用者自行切換 + +- 事實:Immich 沒有重寫整個 app,而是替換 **timeline + sync + upload** 這條主幹。v1.136.0 的 release discussion 標題為 **"v1.136.0 - 69420 stars release"**,內容含 **"Beta timeline, sync, and upload mechanism"** 與 **"Beta timeline button"**,並在 logo 旁標 beta 符號讓使用者知道自己在用測試版時間軸。 +- 來源:(release v1.136.0 亦存在於該 repo 的 release 清單)。 +- 切法:**同一版 App 內並存新舊時間軸**,用一個按鈕切到 beta;行動端使用者不會被強制切換。 +- 對 FMP 的相關性(**推測**):這是「功能級 feature toggle + 使用者自行 opt-in」的樣本;適合**替換單一模組**,不適合「整個 app 重建」。 + +### 2.2 NewPipe — 在 side branch 重寫,舊版凍結成維護模式,另發 nightly + +- 事實:`TeamNewPipe/NewPipe` 有一個 **`refactor` branch**。該分支的 `README.md` 寫明 "We are rewriting large chunks of the codebase",且說明現行 `master` 的程式庫**進入維護模式、只收 bugfix**。重寫版以 **nightly** 形式發布於 `TeamNewPipe/NewPipe-refactor-nightly`。 +- permalink(README): +- 官方公告: +- 切法:**新的獨立分支/獨立 app 身分**,舊版停止功能開發但仍出修正;使用者要拿新版得走 nightly 通道。 +- 對 FMP 的相關性(**推測**):與 ADR 0008「同 repo 新 app」結構最接近;但 NewPipe 的舊版是**凍結**,FMP 的舊版要**繼續修**(`docs/adr/0008-rewrite-as-new-app-in-same-repo.md:52`),這點不同。 + +### 2.3 Spotube v5 — 一次改掉外掛模型,重寫 plugin 介面 + +- 事實:Spotube 5.0.0 的 release note 明列這版是 **plugin 化重寫**(把來源抽成外掛)。plugin 介面的程式碼在 `lib/models/metadata/plugin.dart`。 +- permalink(plugin.dart): +- 官方 release note: +- 切法:**以一次 versioned release 為切換點**,沒有長期並存的 toggle(release note 是 migrate-notice 風格)。 +- 對 FMP 的相關性(**推測**):FMP 的來源外掛與 Spotube 的 plugin 模型同型(runtime 腳本/介面契約);可借的是「外掛契約要先凍結、再上線」與「用一次 major release 當切換事件」。 + +### 2.4 Finamp — 重寫版直接開在預設分支 `redesign`,公開 beta,明確警告下載資料可能不一致 + +- 事實:`finamp-app/finamp` 的**預設分支是 `redesign`**(不是 `main`)。repo 內有 `beta-release.md`,內容提到設定可能變動,並寫明 "Downloads should be migrated, but since the new download system is completely different, there might be inconsistencies"。 +- permalink(beta-release.md): +- 切法:**重寫分支成為預設分支**,用 beta 通道放行;資料遷移(下載)明說可能不一致,不保證無損。 +- 對 FMP 的相關性(**推測**):FMP 的 `legacy_import` 是一次性資料匯入(見 ADR 0008–0012 群),Finamp 的樣本說明**「資料能搬但可能不一致」要事前明講**,而不是承諾無損。 + +### 2.5 Firefox for Android — Fenix 取代 Fennec,資料遺失明講+遷移 project board + +- 事實:Mozilla 的行動端遷移文件 `Fennec-Migration.md` 直接寫: + + > "Replacing a Fennec (Firefox for Android) installation with Fenix (Firefox Preview) can (and at the time of writing this definitely will) result in DATA LOSS" + + 文件同時連到一個**遷移追蹤 project board**(`mozilla-mobile/projects/40`)與一份**有日期的 changelog**。 +- permalink(Fennec-Migration.md): +- 切法:**新 app 以新身分上架**,舊 app 使用者不會自動被搬;資料遺失**明文警告**、用 project board 逐項追蹤缺口、changelog 記錄每個時間點。 +- 對 FMP 的相關性(**推測**):這是「換 app 身分、舊使用者手動遷移、事前明講資料風險」的最完整樣本。FMP 的切換條件(`docs/adr/0008-rewrite-as-new-app-in-same-repo.md:53-57`)與此高度可比。 + +### 2.6 Tusky / Mastodon 客戶端 — 漸進採用,沒有 big-bang 重寫 + +- 事實:查到的 Tusky(Mastodon Android 客戶端)變更史是**漸進式採用**(逐步導入 Compose、逐步替換畫面),沒有找到「另開分支重寫整個 app 並切換」的公開紀錄。 +- 對 FMP 的相關性:作為**反例**——不是每個成功專案都用 big-bang 重寫;漸進替換在某些情境更省風險。 + +### 2.7 AppFlowy — 查不到「整 app 重寫」的公開里程碑紀錄 + +- 查到的 AppFlowy 資料是功能迭代與版本發布,**沒有**找到「重寫整個 app 並切換使用者」的公開文件。列為查不到。 + +--- + +## 3. 橫向對照(決定排序策略時要看的維度) + +| 維度 | Immich | NewPipe | Spotube v5 | Finamp | Firefox Fenix | +|---|---|---|---|---|---| +| 重寫範圍 | 單一模組(timeline+sync+upload) | 整個 app(large chunks) | 外掛模型 | 整個 app(redesign) | 整個 app | +| 排序策略 | 模組級垂直切片 | 另起 app(vertical) | 一次 release | 另起分支(預設分支) | 另起 app/新身分 | +| 使用者切換方式 | App 內按鈕 opt-in beta | nightly 通道 | major release | beta 通道 | 新 app 上架,手動遷移 | +| 新舊並存 | 是(同一 App 內) | 是(兩份 app/兩條通道) | 否 | 是(兩條通道) | 否(舊 Fennec 不更新) | +| 資料 migration | 不涉及(後端同一份) | 不涉及 | 不涉及 | **明說可能不一致** | **明說會資料遺失** | +| 舊系統切換後狀態 | 舊路徑移除 | 舊版維護模式、只收 bugfix | — | 舊版被 redesign 取代 | Fennec 停止 | +| 明確 cut-over 事件 | 無(長期 toggle) | 無(長期並行) | 有(5.0.0) | 有(beta→stable) | 有(Fenix 上架) | + +**推測**:上表沒有「重寫者一開始就把里程碑編號寫成公開清單」的樣本;公開可見的都是**切換機制**(toggle/通道/新身分)與**風險聲明**,不是里程碑目錄。里程碑清單在這些專案裡多為內部規劃(issue/project board),不保證對外可見。 + +--- + +## 4. 查不到/推測 + +- **查不到**:Immich、NewPipe、Spotube、Finamp 任一專案的**完整里程碑清單**(含編號與每階段驗收條件)的公開文件。查到的是切換機制與 release note。 +- **查不到**:AppFlowy 的整 app 重寫里程碑紀錄。 +- **查不到**:Tusky 有 big-bang 重寫;查到的是漸進採用 Compose。 +- **查不到**:`vertical slice vs layer-by-layer` 與 `parity checklist / cut-over gate` 的**權威原始出處**。前者是實務共識用語、後兩者是業界口語;本檔標為推測。 +- **推測**:Strangler Fig/Branch by Abstraction 不直接適用於「同 repo 兩個獨立 app 並存」的 FMP 情境;能借的是「舊系統切換前持續可修」與「切換是一次明確放行」兩個性質。 +- **推測**:NewPipe 是最接近 FMP 結構的樣本(同 repo、新 app 身分、舊版維護模式),但 NewPipe 舊版停止功能開發、FMP 舊版要繼續修(ADR 0008 :52),兩者對「資源怎麼分」的答案不同。 diff --git a/.trellis/tasks/09-28-design-milestones/research/repo-mechanics.md b/.trellis/tasks/09-28-design-milestones/research/repo-mechanics.md new file mode 100644 index 000000000..4d8431a3c --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/research/repo-mechanics.md @@ -0,0 +1,136 @@ +# repo-mechanics — 里程碑怎麼變成 task/PR 的機制事實 + +- 任務:`09-28-design-milestones`。本檔只列機制事實,附 `file:line` 或指令輸出。**不決定**里程碑方案。 +- 三塊:§1 Trellis 任務機制;§2 CI 現況與 ADR 0015 對 `app/` 的規劃;§3 可追蹤里程碑的 GitHub 功能與 repo 現況;§4 工具鏈版本。 + +--- + +## 1. Trellis 任務機制(本 repo) + +### 1.1 指令面(`python ./.trellis/scripts/task.py --help`) + +可用子命令:`create / add-context / validate / list-context / start / current / finish / set-branch / set-base-branch / set-scope / set-meta / rename / archive / list / add-subtask / remove-subtask / list-archive`。 + +里程碑相關的關鍵參數: + +- `create`:`python ./.trellis/scripts/task.py create "" [--slug <name>] [--parent <dir>]`(`.trellis/workflow.md:46`)。`--parent` 建立 subtask 連結(`create --help`)。另有 `--description`(**必填非空**,空字串在 archive 時會被拒)、`--priority P0-P3`、`--package`、`--base-branch`(PR 目標分支)、`--meta k=v`、`--no-start`(建立但不設為本 session active)、`--force`。 +- `archive`:`task.py archive <name> [--no-commit] [--skip-branch-validation]`(:50)。`--no-commit` 跳過自動 git commit;`--skip-branch-validation` 供「從未 PR-backed」的任務在缺 branch metadata 時仍可 archive。 +- `add-subtask <parent> <child>` / `remove-subtask`:連結既有任務或解除(:69, :175)。 +- `list-archive`(:52)。 + +### 1.2 parent / child 的語意(**這是重點**) + +- 用途:一個使用者請求含多個可獨立驗證的交付物時,用 parent + child(`.trellis/workflow.md:169-175`)。 +- **「Parent/child structure is not a dependency system」**:child 之間若有先後,**必須寫在該 child 的 `prd.md` / `implement.md`,不能靠樹狀位置暗示**(:173, :358-359)。 +- 建法:**先建 parent,再逐個用 `--parent <parent-dir>` 建 child**;不要因為有 child 就把 parent `start`;要 start 的是「持有下一個可獨立驗證交付物」的那個 child(:333, :359)。 +- 狀態機:`create` 產生目錄並(在能取得 session 身分時)自動把「本 session active-task 指標」指過去;`start` 冪等地寫同一指標並把 `task.json.status` 由 `planning` 翻成 `in_progress`;`finish` 只刪 session 檔、**不改 status**;`archive` 會寫 `status=completed`、把目錄搬到 `archive/{year-month}/`、並清掉仍指向它的 runtime session 檔(:78, :230)。 + +### 1.3 本 repo 現況 + +| 項目 | 事實 | 來源 | +|---|---|---| +| parent task | `.trellis/tasks/09-26-fmp-rewrite/`,`task.json` 的 `id=fmp-rewrite`、`status=planning`、`priority=P2`、`base_branch=main` | `task.json` | +| parent 內容 | `prd.md`(216 行)、`phase2-plan.md`(269 行)、`task.json`、`check.jsonl`、`implement.jsonl` | `ls` | +| parent 的 children | 21 個名稱:`09-26-audit`、`09-27-design-docs`、`09-27-design-rewrite-strategy`、`09-27-design-platform`、`09-27-design-data`、`09-27-design-settings-logging`、`09-27-design-network-accounts`、`09-27-design-errors`、`09-27-design-source-plugins`、`09-27-design-testing`、`09-27-design-cache-offline`、`09-27-design-background-tasks`、`09-27-design-playback-core`、`09-28-design-library-sync`、`09-28-design-downloads`、`09-28-design-lyrics`、`09-28-design-release-update`、`09-28-design-toast`、`09-28-design-ui-ux`、`09-28-design-debug-page`、`09-28-design-milestones` | `task.json` `children` | +| 本項 task | `09-28-design-milestones/`:`task.json`(`id=design-milestones`、`status=planning`、`parent=09-26-fmp-rewrite`、`children=[]`)、`prd.md`(20 行,Requirements/Acceptance 仍 `TBD`)、`check.jsonl`、`implement.jsonl`、`research/` | `task.json`、`prd.md` | +| archive 目錄 | `.trellis/tasks/archive/2026-09/` 共 24 個目錄,含已完成的設計 child(例:`09-27-design-rewrite-strategy`、`09-28-design-debug-page`) | `ls .trellis/tasks/archive/2026-09/` | + +**注意**:parent 的 `children` 是**名稱清單**,不是路徑;已 archive 的 child(目錄在 `archive/2026-09/`)仍留在這份清單裡。`children` 不表達順序或依賴。 + +### 1.4 本項的固定流程(parent 檔案已寫定) + +`phase2-plan.md:257`: + +> `每項固定流程:建 child task(task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 task.py start、寫 ADR、更新本檔 §3 標記完成、task.py finish+archive --no-commit --skip-branch-validation、commit+push。` + +`phase2-plan.md:254`:**下一份 ADR 編號 0026**。 + +--- + +## 2. CI 現況與 `app/` 的 CI 規劃 + +### 2.1 現在的 `.github/workflows/ci.yml` + +- 標題 `CI`;觸發 `pull_request`(target `main`)、`push`(`main`)、`workflow_dispatch`(`ci.yml:9-16`)。 +- **沒有 path filter**,理由寫在檔頭註解:Markdown 也載著測試會強制的規則,所以純文件 commit 正是最不該跳過 `validate` 的那一種;`paths-ignore` 是 trigger 層級、無法只跳過 build job;**實測總時長 23 分鐘(validate 7、Android 6、Windows 10)**,不值得為省時間加一個 changed-files job(`ci.yml:3-8`)。 +- `concurrency`:以 `ci-<workflow>-<PR 的 ref 或 main 的 sha>` 分組、`cancel-in-progress: true`;註解說明 2026-09 查到 main 上有 20 個 commit 因以 ref 分組被取消而永遠沒有 CI 結果(`ci.yml:22-25`)。 +- `env`:`FLUTTER_VERSION: '3.47.1'`、`JAVA_VERSION: '17'`、`JAVA_DISTRIBUTION: 'temurin'`(`ci.yml:27-30`)。 + +| job | name | runs-on | timeout | needs | 內容 | +|---|---|---|---|---|---| +| `validate` | Analyze and Test | ubuntu-latest | 15 min | — | checkout(`fetch-depth: 0`)→ Flutter → `pub get` → `dart format --output=none --set-exit-if-changed lib test tool` → `build_runner build` → `dart run slang` → `flutter analyze` → `flutter test --coverage --exclude-tags live` → 上傳 coverage(`ci.yml:32-84`) | +| `build-android` | Android Build Smoke | ubuntu-latest | 20 min | validate | Java 17 → Flutter → codegen → `flutter build apk --release --target-platform android-arm64`(`ci.yml:86-122`) | +| `build-windows` | Windows Build Smoke | windows-2022 | 20 min | validate | `flutter config --enable-windows-desktop` → codegen → `flutter build windows --release`(`ci.yml:124-150`) | + +### 2.2 最近的 CI run(`gh run list --limit 20`,read-only,取樣當下) + +- 最近 20 筆全名為 `CI`。成功的兩筆:`2026-09-28T13:37:09Z → 13:57:54Z`(約 **20 分 45 秒**)、`2026-09-28T10:35:51Z → 10:53:18Z`(約 **17 分 27 秒**)。其餘多數 `conclusion=cancelled`(PR 上連續 push 被 concurrency 取消),最新一筆 `conclusion` 尚為空(進行中)。 + +### 2.3 現在的 `.github/workflows/release.yml` + +- 觸發:push `v*` tag 或 `workflow_dispatch`(帶 `tag` 輸入)(`release.yml:3-12`)。`env` 同 ci.yml(Flutter 3.47.1、Java 17)。 +- job:`prepare`(驗 tag 格式並算 `version_code = major*1000000+minor*1000+patch`)→ `build-android`(matrix 4 ABI:arm64-v8a/armeabi-v7a/x86_64/universal,順帶產 `fmp-latest-android-*` 別名)、`validate`(`flutter analyze` + `flutter test --exclude-tags live`)→ `build-windows`(ZIP、Inno Setup 安裝檔、ISS patch 驗證閘門、LGPL 授權檔隨二進位)→ `verify`(下載全部 artifact、產 checksums、`tool/release/verify_release_assets.dart` 檢查)→ `release`(組 release body、`softprops/action-gh-release` 直接發布,`draft: false`)(`release.yml` 全文)。 +- release body 由 commit 訊息自動分組產生(feat/fix/perf/deps),並附 compare 連結;檔內註解說明 body 也是 App 內更新對話框的來源(`release.yml`)。 + +### 2.4 ADR 0015 對 `app/` 的 CI 規劃(**尚未實作**,是里程碑要落地的部分) + +`docs/adr/0015-testing-gates-and-dev-environment.md:31-38`(決定 9): + +> `CI:dorny/paths-filter 依專案切分——app/** 與 .github/** 觸發 app 的 job,app/ 以外的任何變動(含文件)觸發舊專案的 job;一個 always() 彙總 job 當唯一必要檢查。app 的 job:format、dart analyze、接線哨兵、flutter analyze、lint 規則測試、不加參數的 flutter test、契約執行器、Android/Windows/Linux/macOS/iOS(不簽名)建置、Linux 與 Windows 的整合測試。舊專案的 job 維持現狀,只在根目錄變動時跑,app/ 的 PR 不被舊專案的不穩測試擋住。` + +ADR 0008 的後果也記了這件事:切換期 CI 要跑兩個專案、時間變長;CI 依專案切分,舊專案測試只在根目錄變動時跑、不擋 `app/` 的 PR(`docs/adr/0008-rewrite-as-new-app-in-same-repo.md:64-68`)。ADR 0009 要求 CI 建置矩陣**從第一個里程碑起**含 Linux/macOS/iOS 不簽名(`docs/adr/0009-platform-layer-with-declared-capabilities.md:82`)。 + +→ 也就是:**`app/` 的 CI job 與 5 平台建置矩陣目前都不存在**;`ci.yml` 只有舊專案的 3 個 job。里程碑 1 要把它們生出來。 + +--- + +## 3. 可追蹤里程碑的 GitHub 功能與 repo 現況 + +### 3.1 功能事實(來源限 docs.github.com) + +| 功能 | 事實 | 來源 | +|---|---|---| +| **Milestones** | 在**單一 repo** 內追蹤一組 issue/PR;milestone 頁顯示說明、到期日、**完成百分比**、open/closed 計數與清單;可直接開預設掛在該 milestone 的 issue;open 項目可拖曳排序,但**超過 500 個 open issue 就不能排序** | <https://docs.github.com/issues/using-labels-and-milestones-to-track-work/about-milestones> | +| **Sub-issues** | 把大工作拆成子 issue;**每個 parent 最多 100 個 sub-issue、最多 8 層嵌套**;parent 與 sub-issue 進度在 Projects 可見(可依 parent 篩選/分組);CLI:`gh issue create --parent <PARENT-NUMBER>`、`gh issue edit <PARENT> --add-sub-issue <N>` | <https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/adding-sub-issues> | +| **Projects** | user 或 org 層級的 table/board/roadmap,整合 issue 與 PR;可自訂 field(metadata)、多個 view(filter/sort/slice/group)、可設定圖表 | <https://docs.github.com/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects> | + +### 3.2 本 repo 現況(read-only 查詢) + +| 查詢 | 結果 | +|---|---| +| `gh api repos/1morr/FMP/milestones` | `[]`(**沒有使用 milestone**) | +| `gh api repos/1morr/FMP/projects` | HTTP 404(repo 的 Projects (classic) 端點不存在/已停用) | +| `gh api graphql` 查 `projectsV2` | 失敗:token 缺 `read:project` scope(現有 scope:`gist, read:org, repo, workflow`)→ **Projects v2 用量無法確認** | +| `gh api repos/1morr/FMP` | `has_issues: true`、`open_issues_count: 3` | +| `.github/` 內容 | `dependabot.yml`、`workflows/`;**沒有 `ISSUE_TEMPLATE/`** | +| issue 範本 | ADR 0023 :89 明說「repo 目前沒有 issue 範本,落地時新增 `.github/ISSUE_TEMPLATE/bug_report.yml`」 | + +→ 里程碑若要「一個里程碑=一個 GitHub issue 或 milestone」在 GitHub 上追蹤,目前是從零開始;Trellis 的 parent/child 任務樹與 GitHub Issues 是**兩套並行的追蹤**,沒有任何自動同步(查無同步腳本;`tool/` 下未見)。 + +--- + +## 4. 工具鏈版本 + +| 項目 | 值 | 來源 | +|---|---|---| +| 舊專案版本 | `version: 1.11.0+1011000` | `pubspec.yaml:5` | +| Dart SDK 約束(舊專案) | `sdk: '>=3.9.0 <4.0.0'` | `pubspec.yaml:8-9` | +| CI 釘住的 Flutter | `3.47.1` | `.github/workflows/ci.yml:27`、`release.yml:21` | +| `.fvmrc` | **不存在**(`cat .fvmrc` → no such file) | 指令輸出 | +| 效能基準量測環境 | Flutter **3.47.1** stable(framework `6655482ec0`、engine `11d79658c4`)、Dart **3.13.1** | `docs/audit/perf-baseline.md:13` | +| Java | 17(temurin) | `.github/workflows/ci.yml:28-29` | +| **當前 Flutter stable**(官方 release JSON,取樣 2026-09-28) | **3.47.5**(Dart **3.13.4**,2026-09-18 發布,sha `6a19cca56475dbfba1478ee68d7bd0c2ef891da1`) | <https://storage.googleapis.com/flutter_infra_release/releases/releases_windows.json> | +| 當前 beta | 3.49.0-0.1.pre(Dart 3.14.0,2026-09-21) | 同上 | +| 近期 stable 序列 | 3.47.5(09-18)、3.47.4(09-11)、3.47.3(09-09) | 同上 | + +→ `app/` 若「從當前 stable 起」,會是 **Flutter 3.47.5 / Dart 3.13.4**(舊專案與基準是 3.47.1 / Dart 3.13.1)。差距是 patch 級,但切換條件的「效能不低於基準」要在 `perf-baseline.md:13` 記下引擎版本差異。 + +--- + +## 查不到/推測 + +- **查不到**:repo 是否使用 GitHub Projects v2。`gh` token 缺 `read:project`;classic Projects 端點 404。需以有該 scope 的 token 或直接在網頁確認。 +- **查不到**:`release.yml` 的實測時長。取樣的 20 筆 run 全是 `CI`,沒有 release run。 +- **查不到**:Trellis 任務樹與 GitHub Issues/Milestones 之間的任何同步機制或腳本。 +- **推測**:`ci.yml` 檔頭「23 分鐘(validate 7、Android 6、Windows 10)」與本次取樣的成功 run 約 17–21 分鐘一致;實際時長隨 runner 快慢浮動。 +- **推測**:parent `task.json` 的 `children` 清單同時含已 archive 的 child,代表 archive 不會把 child 從 parent 的 `children` 移除;里程碑定稿若要「以里程碑為單位列 child」,需自行維護另一份對照。 From fec60790babef16747682639ca4cb16c5c905e3a Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:25:47 +0800 Subject: [PATCH 111/133] chore(task): record milestone order decision --- .trellis/tasks/09-28-design-milestones/prd.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md index 2c736fa3e..7a794e793 100644 --- a/.trellis/tasks/09-28-design-milestones/prd.md +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -60,9 +60,32 @@ - Immich:同一 App 內用開關選擇 beta 時間軸。 - **共同點**:公開可見的都是切換機制與風險聲明,查不到任何一個專案的完整里程碑清單。 +## 已決定 + +1. **里程碑的切法與順序**(2026-09-28,擁有者「按你建議」):以縱向切片排序;每個新增資料表的里程碑,同時補上那張表的舊資料匯入。 + + | # | 里程碑 | 範圍 | + |---|---|---| + | M1 | 骨架+曳光彈 | Android、Windows 能搜 B 站並播放;接上 CI 切分、lint、log 與遮蔽、drift、網路層、錯誤模型、Toast、token、JS 執行環境+B 站插件;限時的 YouTube.js 可行性驗證 | + | M2 | 完整播放 | 佇列、播放頁 B、播放列、App 內快捷鍵、系統媒體控制、速度/音量/輸出裝置、播放歷史、快取、背景排程器 | + | M3 | 三音源、帳號與開發工具 | YouTube、網易雲插件;登入;B 站分 P、Mix、電台直播;`1morr/fmp-plugins`、插件頁、首次啟動引導;Debug 頁與插件開發工具 | + | M4 | 音樂庫與同步 | 本機歌單、匯入平台歌單並刷新、Spotify/QQ 匹配、遠端歌單編輯、首頁排行、新格式的備份與還原 | + | M5 | 舊資料匯入 | 匯入歌單、曲目、歷史、設定、帳號、舊備份檔;之後擁有者以 dev flavor+真實資料副本日常試用 | + | M6 | 下載 | 下載與權限,並匯入舊下載紀錄 | + | M7 | 歌詞 | 多源與 AI 插件、逐字、桌面歌詞、Android 懸浮,並匯入舊歌詞配對 | + | M8 | 桌面整合 | 托盤、全域快捷鍵、開機自啟、單一實例 | + | M9 | 發版、更新與切換 | 應用內更新、release-please、舊更新器相容、效能重量、真實資料副本完整匯入、身分比對,最後切換 PR | + + - **Debug 頁放 M3**:寫 YouTube、網易雲插件時要用插件開發工具與網路紀錄。 + - **舊資料匯入放 M5**:音樂庫的資料表到 M4 才齊,之後擁有者可以用真實資料試用。 + - **插件庫放 M3**:有三個官方插件後才需要插件目錄。 + - **平台任務**: + - **Linux**:M1 之後開。驗收在 VMware Workstation Pro 的 Ubuntu 桌面虛擬機,X11、Wayland 各測一次;日常開發用 WSL2。之後每個里程碑在虛擬機跑一次冒煙測試。 + - 不用 WSLg 驗收的原因:它是 Weston 加 RDP,沒有托盤(wslg #532)、鑰匙圈預設沒在跑,桌面歌詞的置頂與穿透也測不準。 + - **macOS、iOS**:Mac 預計下個月到貨。到貨前只靠 GitHub macOS runner 編譯與 iOS 模擬器測試(ADR 0009)。到貨後開平台任務;iOS 要不要實機、要不要付費帳號,屆時再問。 + ## 待決定(一次問一題) -1. 里程碑的切法與順序,包括舊資料匯入、Debug 頁、插件庫放在哪一步。 2. 里程碑與 PR 的對應:里程碑底下是否再分 PR 級的子任務。 3. 切換放行條件的細節:勾選來源改指 `questions.md`、效能重量方式、擁有者試用多久。 From cdc893ec4f25fa13a347e3c4892377fde99ac4b0 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:27:08 +0800 Subject: [PATCH 112/133] chore(task): record milestone and pr structure decision --- .trellis/tasks/09-28-design-milestones/prd.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md index 7a794e793..7e472eada 100644 --- a/.trellis/tasks/09-28-design-milestones/prd.md +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -84,9 +84,22 @@ - 不用 WSLg 驗收的原因:它是 Weston 加 RDP,沒有托盤(wslg #532)、鑰匙圈預設沒在跑,桌面歌詞的置頂與穿透也測不準。 - **macOS、iOS**:Mac 預計下個月到貨。到貨前只靠 GitHub macOS runner 編譯與 iOS 模擬器測試(ADR 0009)。到貨後開平台任務;iOS 要不要實機、要不要付費帳號,屆時再問。 +2. **里程碑與 PR 的對應**(2026-09-28,擁有者「按你建議」): + - **里程碑任務**:fmp-rewrite 的 child,例 `m1-tracer-bullet`。 + - 開工時走 brainstorm,prd/design/implement 核准一次; + - implement 列出 PR 子任務與先後順序; + - 驗收=端到端實際操作,加上併入的 `phase2-plan` §7/§8 實測。 + - **PR 子任務**:里程碑任務的 child,例 `m1-log-facade`。 + - 一個分支、一個 PR; + - 只寫簡短的 prd(做什麼、驗收); + - PR 描述附 review 指南(改了什麼、為什麼、看哪幾個檔、怎麼實際驗證); + - 合進 `main` 後 `app/` 可編譯、測試全綠。 + - PR 子任務在里程碑已核准的範圍內直接做,遇到未定的事才問。 + - 追蹤只用 Trellis 任務樹,不開 GitHub Milestones/Projects。 + - 此決定調和 parent prd「每個里程碑是 child task」與「每個 child task 一個 PR」兩條規則。 + ## 待決定(一次問一題) -2. 里程碑與 PR 的對應:里程碑底下是否再分 PR 級的子任務。 3. 切換放行條件的細節:勾選來源改指 `questions.md`、效能重量方式、擁有者試用多久。 ## 驗收條件 From 3bd56ca570d919e5e4a3b9861fb1067cecf5b576 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:29:40 +0800 Subject: [PATCH 113/133] chore(task): record cut-over gate decision --- .trellis/tasks/09-28-design-milestones/prd.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md index 7e472eada..35d7b20a2 100644 --- a/.trellis/tasks/09-28-design-milestones/prd.md +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -98,9 +98,18 @@ - 追蹤只用 Trellis 任務樹,不開 GitHub Milestones/Projects。 - 此決定調和 parent prd「每個里程碑是 child task」與「每個 child task 一個 PR」兩條規則。 -## 待決定(一次問一題) - -3. 切換放行條件的細節:勾選來源改指 `questions.md`、效能重量方式、擁有者試用多久。 +3. **切換放行條件**(2026-09-28,擁有者「按你建議」): + - **功能清單**:改指 `questions.md` 勾「保留」的 E1–E17,加上各 ADR 定下的行為;ADR 0008 與 parent prd 的文字一併更正。 + - **效能**: + - 切換前在同一台電腦、同一個模擬器、同一份資料副本上,以 `perf-baseline.md` 的同一組命令把舊版與新版各量 5 次,比中位數; + - 新版每項不得比舊版差超過 5%;超出就重量一次,仍超出則不放行。 + - **試用**: + - 候選版以 dev flavor 加一份新匯入的真實資料副本,當擁有者的主要播放器滿 2 週; + - 期間沒有未解決的阻擋性 bug(資料錯誤、無法播放、當機); + - 另依 ADR 0022 在模擬器與虛擬機上以資料副本從 v1.11.0 實際升級。 + - **切換後出問題**:以 2.0.x 經應用內更新往前修,不做降版。 + - 理由:Android 同身分覆蓋升級,降版要移除 App,會刪掉私有資料。 + - 舊資料永不自動刪除(ADR 0010),可以重新匯入。 ## 驗收條件 From 2f1c92a8c03be8bc3b5257106168d0f5a6393a9b Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:30:54 +0800 Subject: [PATCH 114/133] chore(task): add milestone design and plan --- .../tasks/09-28-design-milestones/design.md | 174 ++++++++++++++++++ .../09-28-design-milestones/implement.md | 29 +++ .trellis/tasks/09-28-design-milestones/prd.md | 23 ++- 3 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 .trellis/tasks/09-28-design-milestones/design.md create mode 100644 .trellis/tasks/09-28-design-milestones/implement.md diff --git a/.trellis/tasks/09-28-design-milestones/design.md b/.trellis/tasks/09-28-design-milestones/design.md new file mode 100644 index 000000000..5347d1add --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/design.md @@ -0,0 +1,174 @@ +# 設計:重寫里程碑與切換 + +## 1. 結構(已決定) + +```mermaid +flowchart TD + R["fmp-rewrite(parent)"] --> M["里程碑任務<br/>例:m1-tracer-bullet<br/>prd/design/implement,核准一次"] + R --> P["平台任務<br/>linux/macos/ios"] + M --> PR1["PR 子任務<br/>例:m1-log-facade<br/>簡短 prd+review 指南"] + M --> PR2["PR 子任務 …"] + PR1 --> MAIN["main<br/>app/ 可編譯、測試全綠"] + PR2 --> MAIN +``` + +- **里程碑任務**: + - 開工時走 brainstorm,擁有者核准一次 prd/design/implement; + - implement 列出 PR 子任務與先後順序。Trellis 的 parent/child 不表達依賴,所以順序寫在 implement 與各子任務的 prd(`workflow.md:173`)。 +- **PR 子任務**: + - 一個分支、一個 PR,合進 `main`; + - prd 只寫做什麼與驗收;PR 描述附 review 指南(parent prd「可 review 性優先」); + - 在已核准的範圍內直接做,遇到未定的事才停下來問。 +- **里程碑驗收**: + - 端到端實際操作,Android 與 Windows 各一次,依 AGENTS.md 的 on-device 驗證; + - 加上併入的 `phase2-plan` §7/§8 實測; + - 全部通過才 archive 里程碑任務。 +- **排序原則**: + - 縱向切片,每個里程碑結束時多一件可以實際操作的事(walking skeleton、tracer bullet;ADR 0008); + - 每個新增資料表的里程碑,同時補上那張表的舊資料匯入(M5 起); + - 各組設定的欄位清單(ADR 0011 的未定項),在引入該組設定的里程碑定案。 +- **追蹤**:只用 Trellis 任務樹。里程碑清單的現況寫在 parent 的 `milestones.md`,每完成一個就更新一次。 + +## 2. 里程碑清單 + +每個里程碑一段,依序是:做完能做什麼、範圍、依賴、併入的實測。 + +### M1 骨架+曳光彈 + +- **做完**:Android、Windows 上能搜尋 B 站並連續播放兩首。 +- **範圍**: + - `app/` 新專案,Flutter 用當時的 stable(目前 3.47.5);`app/AGENTS.md`;flavor dev/prod 與 App 身分(ADR 0008、0015);單一實例鎖。 + - `fmp_lints` 與接線哨兵;CI 以 `dorny/paths-filter` 切分、五平台編譯、`always()` 彙總(ADR 0015 §9)。 + - 平台層骨架與能力宣告(ADR 0009)。 + - drift 最小 schema 與 schema 快照(ADR 0010)。 + - log 門面、遮蔽函式、log 檔(ADR 0011)。 + - 網路層(ADR 0012,不含登入)、錯誤模型(ADR 0013)。 + - JS 執行環境、宿主 API 最小集、以「從檔案安裝」載入 B 站插件(ADR 0014)。 + - 播放核心最小集:兩個後端、兩首的佇列、前瞻交接(ADR 0018)。 + - `ToastHost` 與 `Toaster`(ADR 0023,詳細頁在 M3)。 + - token、斷點、字型、slang 三語言骨架、App 內快捷鍵的播放部分(ADR 0024)。 + - 以 release-please 的 dry-run 驗證 `app/` 發版 workflow(ADR 0022)。 +- **限時探針**:YouTube.js 可行性(ADR 0014)。失敗就在 M3 以 Dart 實作 YouTube。 +- **併入的實測**:`phase2-plan` §7 全部,涵蓋 ADR 0008、0009、0010、0011、0014、0015、0018、0022、0023、0024。 +- **之後**:開 Linux 平台任務。 + +### M2 完整播放 + +- **做完**:像舊版一樣日常聽歌(單一音源)。 +- **範圍**: + - 完整 `QueueModel`(隨機、循環、拖曳、臨時播放)、`RecoveryPolicy`(ADR 0018); + - 播放頁方案 B、播放列三段、App 內快捷鍵全表、焦點三區(ADR 0024); + - 系統媒體控制(Android 通知、Windows SMTC); + - 速度、音量、輸出裝置(E19);播放歷史(E15); + - 統一快取庫、串流網址記憶體快取、圖片快取、離線狀態(ADR 0016); + - 背景排程器與啟動維護清單(ADR 0017),含 log 保留 7 天(ADR 0025)。 +- **依賴**:M1。 +- **併入的實測**:無另外指定的項目;照 ADR 0016、0017、0018 的單元與契約測試。 + +### M3 三音源、帳號與開發工具 + +- **做完**:三個音源都能搜尋、播放、登入。 +- **範圍**: + - YouTube(JS 或 Dart 備案)、網易雲插件;B 站分 P(E2)、Mix(E13)、電台直播(E12); + - 帳號與 `CredentialStore`、`AuthRequirement`(ADR 0012,E6); + - `1morr/fmp-plugins` repo、CI 與 `index.json`;App 插件頁;首次啟動引導(ADR 0014、`phase2-plan` §9); + - Debug 頁八區塊與插件開發工具(ADR 0025、0015 §7);錯誤詳細頁與 GitHub 回報、`.github/ISSUE_TEMPLATE/bug_report.yml`(ADR 0023)。 +- **依賴**:M2。 +- **併入的實測**: + - YouTube App 內網頁登入(ADR 0012,§8); + - 加入 Debug 頁的里程碑實測(ADR 0025,§8)。 + +### M4 音樂庫與同步 + +- **做完**:建歌單、匯入並刷新平台歌單、匯入 Spotify/QQ 歌單。 +- **範圍**: + - 關聯表與孤兒清理(ADR 0019);本機歌單(E3); + - 匯入平台歌單與刷新(E4);僅元資料來源的匹配(E5);遠端歌單編輯(E7); + - 首頁排行與探索(E14); + - 新格式的備份與還原(E16)。 +- **依賴**:M3(需要三個音源與帳號)。 +- **併入的實測**:`opencc` native assets 在各平台建置(ADR 0019 後果)。 + +### M5 舊資料匯入 + +- **做完**:新 App 首次啟動會自動匯入舊版的歌單、曲目、歷史、設定、帳號,也能匯入舊備份檔。擁有者從此以 dev flavor 加真實資料副本日常試用。 +- **範圍**:`legacy_import`(ADR 0010):唯讀開啟舊 Isar、讀舊 secure storage、先寫暫存庫、驗證後才換上;錯誤頁;「刪除舊版資料」。 +- **依賴**:M4(資料表到這裡才齊)。 +- **併入的實測**:`isar_community` 與 `sqlite3` 共存(M1 已驗證)在匯入路徑上再測一次;以擁有者的真實資料副本完整匯入,並比對筆數。 + +### M6 下載 + +- **做完**:下載、管理下載,並匯入舊的下載紀錄。 +- **範圍**:ADR 0020 全部(E8),以及舊下載紀錄的匯入。 +- **依賴**:M5。 +- **併入的實測**:加入下載的里程碑實測(ADR 0020,§8)。 + +### M7 歌詞 + +- **做完**:多源歌詞、逐字、桌面歌詞、Android 懸浮歌詞,並匯入舊的歌詞配對。 +- **範圍**: + - ADR 0021 全部(E9–E11); + - 官方 AI 插件 `openai-compatible`、`system-one`; + - 舊歌詞配對以 `manual` 匯入。 +- **依賴**:M5。與 M6 互不依賴,可以對調。 +- **併入的實測**:加入桌面歌詞、Android 懸浮歌詞、逐字的里程碑實測(ADR 0021,§8)。 + +### M8 桌面整合 + +- **做完**:托盤、全域快捷鍵、開機自啟、關閉縮到托盤(E18)。 +- **範圍**:平台層的對應能力(ADR 0009);設定頁「鍵盤快捷鍵」列出兩組(ADR 0024)。 +- **依賴**:M2。放在 M7 之後,是因為它不擋試用。 + +### M9 發版、更新與切換 + +- **做完**:新 App 能以 2.0.0 送到舊版使用者手上。 +- **範圍**: + - 應用內更新與 `appUpdate` 能力、正式的 release workflow(ADR 0022,E17); + - `docs/user-guide.md` 完成、關於頁(ADR 0024); + - 切換放行條件(第 3 節)全部通過; + - 最後的切換 PR 照 ADR 0008 §決定 5:刪除根目錄舊專案、`docs/audit/`、ADR 0001–0007;`release.yml`、`ci.yml`、`orca.yaml`、`tool/release/` 改指向 `app/`。 +- **依賴**:M1–M8。 +- **併入的實測**:ADR 0022 的切換前實測(§8);App 身分比對(ADR 0008)。 + +### 平台任務 + +- **Linux**:M1 之後開。 + - 驗收在 VMware Workstation Pro 的 Ubuntu LTS 桌面虛擬機,X11 與 Wayland 各一次;日常開發用 WSL2。 + - 併入 ADR 0012(沒有 keyring)、0021(X11/Wayland 桌面歌詞)、0022(AppImage 改名替換)的 §8 項目。 + - 之後每個里程碑在虛擬機跑一次冒煙測試。 +- **macOS、iOS**:Mac 到貨後開(擁有者預計 2026-10)。 + - 到貨前只靠 GitHub macOS runner 的編譯與 iOS 模擬器測試。 + - 併入 ADR 0018(AVPlayer 對 DASH/HLS)、0021(Live Activity、macOS 桌面歌詞)、0022(quarantine)的 §8 項目。 + - iOS 要不要實機、要不要付費帳號,在該任務決定。 +- 各平台實機驗證完才發佈(ADR 0009)。 + +## 3. 切換放行條件(已決定) + +1. **功能**: + - `questions.md` 勾「保留」的 E1–E17,加上各 ADR 定下的行為,全部在 `app/` 跑通; + - 切換 PR 的 review 指南逐項列出。 +2. **效能**: + - 同一台電腦、同一模擬器、同一份資料副本,以 `perf-baseline.md` 的命令把舊版與新版各量 5 次,比中位數; + - 新版每項不得比舊版差超過 5%,超出就重量一次,仍超出則不放行; + - 結果附在切換 PR。 +3. **資料**: + - 以擁有者的真實資料副本完整匯入,筆數比對附在切換 PR(ADR 0010); + - 在模擬器與虛擬機上以資料副本從 v1.11.0 實際升級:Android、Windows 安裝版與免安裝版(ADR 0022)。 +4. **試用**: + - 候選版以 dev flavor 加新匯入的真實資料副本,當擁有者的主要播放器滿 2 週; + - 期間沒有未解決的阻擋性 bug(資料錯誤、無法播放、當機)。 +5. **切換後**:以 2.0.x 經應用內更新往前修,不做降版。 + - Android 同身分覆蓋升級,降版要移除 App,會刪掉私有資料。 + - 舊資料不自動刪除,可以重新匯入(ADR 0010)。 + +## 4. 相關文件的更正與指向 + +- ADR 0008 §決定 5、「如何確認」,以及 parent prd 完成定義:把「`features.md` 中勾『保留』」改為「`questions.md` 勾『保留』的功能(E1–E17)與各 ADR 定下的行為」,並加一句指向 0026。 +- ADR 0009:平台任務的時程與環境見 0026。 +- ADR 0011:「各組設定的欄位清單在里程碑中……定案」改為指向 0026 的排序原則。 +- ADR 0014:插件庫與插件頁在 M3(0026)。 +- ADR 0017:啟動維護清單在 M2 實作(0026)。 +- `phase2-plan.md`: + - §3 第 20 列 ✅; + - §7、§8 各項標上所屬里程碑; + - §10 改為「階段二完成,下一步階段三」。 diff --git a/.trellis/tasks/09-28-design-milestones/implement.md b/.trellis/tasks/09-28-design-milestones/implement.md new file mode 100644 index 000000000..e6fd43b45 --- /dev/null +++ b/.trellis/tasks/09-28-design-milestones/implement.md @@ -0,0 +1,29 @@ +# 執行計畫:第 7 項定稿(設計任務,只產出文件) + +1. [ ] 核准後寫 `docs/adr/0026-milestones-and-cut-over.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1、§3,以及 §2 的排序原則。 + 被否決的方案: + - 舊資料匯入延到切換前; + - Debug 頁提早到 M2; + - 先蓋完一層再做下一層; + - Linux 從 M1 起全面驗證; + - 以 WSLg 驗收 Linux; + - 租雲端 Mac; + - 里程碑不開 PR 子任務; + - 每個 PR 都完整走一次 brainstorm; + - 加開 GitHub Milestones; + - 拿存下的基準數字直接比; + - 不留誤差範圍; + - 試用 1 週、不設試用、4 週以上; + - 切換後以降版退回。 +2. [ ] 新增 `.trellis/tasks/09-26-fmp-rewrite/milestones.md`:`design.md` §2 的清單,加上狀態欄。 +3. [ ] 更正與指向: + - ADR 0008(功能清單來源)、parent `prd.md` 完成定義; + - ADR 0009、0011、0014、0017 各加一句指向 0026。 +4. [ ] 更新 `phase2-plan.md`: + - §3 第 20 列 ✅; + - §7、§8 各項標上所屬里程碑; + - §10 改為階段二完成、下一步階段三(Trellis/docs 清理),之後 M1。 +5. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用,以及沒有殘留「`features.md` 中勾」。 +6. [ ] `task.py finish`,再 `task.py archive design-milestones --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 + +回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/09-28-design-milestones/prd.md index 35d7b20a2..978a96c2e 100644 --- a/.trellis/tasks/09-28-design-milestones/prd.md +++ b/.trellis/tasks/09-28-design-milestones/prd.md @@ -111,10 +111,23 @@ - 理由:Android 同身分覆蓋升級,降版要移除 App,會刪掉私有資料。 - 舊資料永不自動刪除(ADR 0010),可以重新匯入。 +我自行定下、未另外詢問的細節,理由寫在 `design.md`: +- 各里程碑的詳細範圍,以及 §7/§8 實測的歸屬; +- 單一實例鎖提早到 M1(ADR 0015 的 flavor 隔離實測需要它); +- M6、M7 可以對調; +- 里程碑清單放在 parent 的 `milestones.md`; +- `app/` 從當時的 Flutter stable 起步。 + +## 範圍外 + +- 各里程碑內部的 PR 切分:在各里程碑任務開工時定。 +- iOS 實機與付費帳號:在 iOS 平台任務定。 +- 階段三的 Trellis/docs 清理:另開任務。 + ## 驗收條件 -- [ ] 待決定項都有擁有者的答覆。 -- [ ] 產出 ADR 0026(里程碑結構與切換放行條件)與里程碑清單。 -- [ ] 清單中每個里程碑都有:範圍、依賴、驗收,以及併入的 `phase2-plan` §7/§8 項目。 -- [ ] ADR 0008 與 parent prd 的「`features.md` 勾保留」改指實際的勾選來源。 -- [ ] `phase2-plan.md` §3 第 20 列 ✅;§10 交接改為階段三。 +- [ ] ADR 0026 記下結構、排序原則、切換放行條件與被否決的方案。 +- [ ] `milestones.md` 列出 M1–M9 與平台任務,每項都有範圍、依賴、驗收,以及併入的 §7/§8 項目。 +- [ ] ADR 0008 與 parent prd 的「`features.md` 勾保留」改指 `questions.md`,`git grep` 沒有殘留。 +- [ ] ADR 0009、0011、0014、0017 各加一句指向 0026。 +- [ ] `phase2-plan.md`:§3 第 20 列 ✅;§7、§8 標上所屬里程碑;§10 交接改為階段三。 From 399890a0d84fedda9c61c82bc3badcf4d3a922a2 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:34:39 +0800 Subject: [PATCH 115/133] docs(adr): 0026 milestones and cut-over --- .../tasks/09-26-fmp-rewrite/milestones.md | 145 ++++++++++++++++++ .../tasks/09-26-fmp-rewrite/phase2-plan.md | 33 ++-- .trellis/tasks/09-26-fmp-rewrite/prd.md | 2 +- .../0008-rewrite-as-new-app-in-same-repo.md | 4 +- ...atform-layer-with-declared-capabilities.md | 2 +- docs/adr/0011-settings-and-logging.md | 2 +- docs/adr/0014-script-source-plugins.md | 2 +- docs/adr/0017-background-task-scheduler.md | 2 +- docs/adr/0026-milestones-and-cut-over.md | 128 ++++++++++++++++ 9 files changed, 298 insertions(+), 22 deletions(-) create mode 100644 .trellis/tasks/09-26-fmp-rewrite/milestones.md create mode 100644 docs/adr/0026-milestones-and-cut-over.md diff --git a/.trellis/tasks/09-26-fmp-rewrite/milestones.md b/.trellis/tasks/09-26-fmp-rewrite/milestones.md new file mode 100644 index 000000000..5ea67698b --- /dev/null +++ b/.trellis/tasks/09-26-fmp-rewrite/milestones.md @@ -0,0 +1,145 @@ +# 里程碑清單(ADR 0026) + +> 每完成一個里程碑或平台任務,就更新它的「狀態」與驗收勾選。 +> 範圍若在開工時要大改,先改這份清單並寫明原因。 +> 「§7」「§8」指 `phase2-plan.md` 的第 7 節(第一個里程碑的必要驗證)與第 8 節(延後的實測)。 + +| # | 里程碑 | 依賴 | 狀態 | +|---|---|---|---| +| M1 | 骨架+曳光彈 | — | 未開始 | +| M2 | 完整播放 | M1 | 未開始 | +| M3 | 三音源、帳號與開發工具 | M2 | 未開始 | +| M4 | 音樂庫與同步 | M3 | 未開始 | +| M5 | 舊資料匯入 | M4 | 未開始 | +| M6 | 下載 | M5 | 未開始 | +| M7 | 歌詞 | M5 | 未開始 | +| M8 | 桌面整合 | M2 | 未開始 | +| M9 | 發版、更新與切換 | M1–M8 | 未開始 | +| L | Linux 平台 | M1 | 未開始 | +| Mac | macOS 平台 | Mac 到貨 | 未開始 | +| iOS | iOS 平台 | Mac 到貨 | 未開始 | + +- M6、M7 互不依賴,可以對調。 +- M8 放在 M7 之後,是因為它不擋試用。 + +## M1 骨架+曳光彈 + +- **做完**:Android、Windows 上能搜尋 B 站並連續播放兩首。 +- **範圍**: + - `app/` 新專案,Flutter 用當時的 stable;`app/AGENTS.md`;flavor dev/prod 與 App 身分;單一實例鎖(ADR 0008、0015)。 + - `fmp_lints` 與接線哨兵;CI 以 `dorny/paths-filter` 切分、五平台編譯、`always()` 彙總(ADR 0015 §9)。 + - 平台層骨架與能力宣告(ADR 0009)。 + - drift 最小 schema 與快照(ADR 0010)。 + - log 門面、遮蔽函式、log 檔(ADR 0011)。 + - 網路層(不含登入,ADR 0012)、錯誤模型(ADR 0013)。 + - JS 執行環境、宿主 API 最小集、以「從檔案安裝」載入 B 站插件(ADR 0014)。 + - 播放核心最小集:兩個後端、兩首的佇列、前瞻交接(ADR 0018)。 + - `ToastHost` 與 `Toaster`(ADR 0023)。 + - token、斷點、字型、slang 三語言骨架、播放快捷鍵(ADR 0024)。 + - `app/` 發版 workflow 以 release-please dry-run 驗證(ADR 0022)。 +- **限時探針**:YouTube.js 可行性。失敗就在 M3 以 Dart 實作 YouTube(ADR 0014)。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] §7 全部項目 +- **之後**:開 Linux 平台任務。 + +## M2 完整播放 + +- **做完**:以單一音源像舊版一樣日常聽歌。 +- **範圍**: + - 完整 `QueueModel` 與 `RecoveryPolicy`(ADR 0018); + - 播放頁方案 B、播放列三段、App 內快捷鍵全表、焦點三區(ADR 0024); + - 系統媒體控制;速度、音量、輸出裝置(E19);播放歷史(E15); + - 統一快取庫與離線狀態(ADR 0016); + - 背景排程器與啟動維護清單(ADR 0017),含 log 保留 7 天(ADR 0025)。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] ADR 0016、0017、0018 的測試 + +## M3 三音源、帳號與開發工具 + +- **做完**:三個音源都能搜尋、播放、登入。 +- **範圍**: + - YouTube、網易雲插件;B 站分 P(E2)、Mix(E13)、電台直播(E12); + - 帳號與 `CredentialStore`、`AuthRequirement`(ADR 0012,E6); + - `1morr/fmp-plugins` repo、CI、`index.json`;插件頁;首次啟動引導(ADR 0014); + - Debug 頁與插件開發工具(ADR 0025、0015 §7);錯誤詳細頁、GitHub 回報、`.github/ISSUE_TEMPLATE/bug_report.yml`(ADR 0023)。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] §8:YouTube App 內網頁登入(ADR 0012) + - [ ] §8:加入 Debug 頁的里程碑實測(ADR 0025) + +## M4 音樂庫與同步 + +- **做完**:建歌單、匯入並刷新平台歌單、匯入 Spotify/QQ 歌單。 +- **範圍**: + - 關聯表與孤兒清理(ADR 0019);本機歌單(E3); + - 匯入與刷新(E4);僅元資料來源的匹配(E5);遠端歌單編輯(E7); + - 首頁排行(E14);新格式的備份與還原(E16)。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] `opencc` native assets 在各平台建置(ADR 0019) + +## M5 舊資料匯入 + +- **做完**:首次啟動自動匯入舊版的歌單、曲目、歷史、設定、帳號;也能匯入舊備份檔。 +- **範圍**:`legacy_import`(ADR 0010):先寫暫存庫、驗證後才換上;錯誤頁;「刪除舊版資料」。 +- **驗收**: + - [ ] 以擁有者的真實資料副本完整匯入,比對筆數 + - [ ] 擁有者開始以 dev flavor+真實資料副本日常試用 + +## M6 下載 + +- **範圍**:ADR 0020 全部(E8);匯入舊下載紀錄。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] §8:加入下載的里程碑實測(ADR 0020) + +## M7 歌詞 + +- **範圍**: + - ADR 0021 全部(E9–E11); + - 官方 AI 插件 `openai-compatible`、`system-one`; + - 舊歌詞配對以 `manual` 匯入。 +- **驗收**: + - [ ] 兩平台端到端操作 + - [ ] §8:桌面歌詞、Android 懸浮歌詞、逐字的里程碑實測(ADR 0021) + +## M8 桌面整合 + +- **範圍**:托盤、全域快捷鍵、開機自啟、關閉縮到托盤(E18);設定頁「鍵盤快捷鍵」列出兩組(ADR 0024)。 +- **驗收**: + - [ ] Windows 端到端操作 + - [ ] 錄製全域快捷鍵時,與 App 內快捷鍵衝突會提示 + +## M9 發版、更新與切換 + +- **範圍**: + - 應用內更新(ADR 0022,E17); + - `docs/user-guide.md` 與關於頁(ADR 0024); + - 切換 PR(ADR 0008 §決定 5):刪除根目錄舊專案、`docs/audit/`、ADR 0001–0007;`release.yml`、`ci.yml`、`orca.yaml`、`tool/release/` 改指向 `app/`。 +- **驗收**(ADR 0026 §決定 5): + - [ ] 功能清單 E1–E17 與各 ADR 行為逐項通過 + - [ ] 舊版與新版同機各量 5 次,新版每項不差超過 5% + - [ ] 真實資料副本完整匯入,並比對筆數 + - [ ] 從 v1.11.0 實際升級:Android、Windows 安裝版、Windows 免安裝版(§8,ADR 0022) + - [ ] Windows 自行下載的安裝檔不帶 Mark of the Web + - [ ] App 身分比對(ADR 0008) + - [ ] 試用 2 週,沒有未解決的阻擋性 bug + +## 平台任務 + +- **Linux**(M1 之後): + - 驗收在 VMware Workstation Pro 的 Ubuntu LTS 桌面虛擬機,X11 與 Wayland 各一次;日常開發用 WSL2。 + - 之後每個里程碑在虛擬機跑一次冒煙測試。 + - [ ] §8:沒有 keyring 時的 secure storage(ADR 0012) + - [ ] §8:X11/Wayland 桌面歌詞(ADR 0021) + - [ ] §8:AppImage 改名替換(ADR 0022) +- **macOS**(Mac 到貨後): + - [ ] §8:AVPlayer 對 B 站 DASH 與直播 HLS(ADR 0018) + - [ ] §8:桌面歌詞(ADR 0021) + - [ ] §8:更新不帶 quarantine(ADR 0022) +- **iOS**(Mac 到貨後,實機與付費帳號在該任務決定): + - [ ] §8:AVPlayer 對 B 站 DASH 與直播 HLS(ADR 0018) + - [ ] §8:Live Activity 本機逐行更新(ADR 0021) +- 各平台實機驗證完才發佈(ADR 0009)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index a010249a5..ba4a60c60 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -129,7 +129,7 @@ flowchart LR | 17 | 3 Toast(✅ 完成,ADR 0023) | 依賴 2、18。 | | 18 | 5 UI/UX(✅ 完成,ADR 0024) | 設計系統與桌面播放器版面方案(2–3 個讓你選)。 | | 19 | 4 Debug 頁(✅ 完成,ADR 0025) | 把 18、3、8 的成果收成正式工具。 | -| 20 | 7 重寫策略(里程碑定稿) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | +| 20 | 7 重寫策略(里程碑定稿)(✅ 完成,ADR 0026,清單見 `milestones.md`) | 所有設計確定後拆成可獨立驗證的里程碑與 child task。 | ## 4. 你在 questions.md 直接問的問題 @@ -218,6 +218,8 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 7. 第一個里程碑的必要驗證(各項設計累積) +以下全部併入 M1(ADR 0026、`milestones.md`)。 + - ADR 0010:`isar_community`+`sqlite3` 原生庫在 Android、Windows 共存;`sqlite3` 的 Android 16KB page size 對齊。 - ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 - ADR 0008:`app/` 的 App 身分識別與舊版一致(開發版除外)。 @@ -231,13 +233,15 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio ## 8. 延後到特定里程碑的實測 -- ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。 -- ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。 -- ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。 -- ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 -- ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——`flutter_overlay_window` 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——`flutter_lyric` 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。 -- ADR 0025:加入 Debug 頁的里程碑——Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出的診斷包能以解壓工具打開。 -- ADR 0022:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版);Windows App 自行下載的安裝檔不帶 Mark of the Web。macOS 平台任務——App 自行下載的更新不帶 quarantine。Linux 平台任務——AppImage 的改名替換。 +各項所屬的里程碑或平台任務標在行尾(ADR 0026、`milestones.md`)。 + +- ADR 0012:YouTube App 內網頁登入(桌面 UA)是否仍可用——第一個加入 YouTube 登入的里程碑先實測;不可用則只提供貼上 cookie。【M3】 +- ADR 0012:Linux 沒有 keyring 時 secure storage 的行為——Linux child task。【Linux】 +- ADR 0018:蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——iOS/macOS child task。【macOS、iOS】 +- ADR 0020:加入下載的里程碑——`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。【M6】 +- ADR 0021:加入桌面歌詞的里程碑——macOS、Linux X11、Wayland 的穿透、置頂、定位;`window_manager` 在子 engine 設穿透作用在歌詞視窗。加入 Android 懸浮歌詞的里程碑——`flutter_overlay_window` 的記憶體與 Android 15 前景服務限制。加入逐字的里程碑——`flutter_lyric` 直接用或自寫。iOS 平台任務——Live Activity 本機逐行更新。【M7;Linux、macOS、iOS 部分在平台任務】 +- ADR 0025:加入 Debug 頁的里程碑——Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出的診斷包能以解壓工具打開。【M3】 +- ADR 0022:切換 PR 前以舊版 v1.11.0 實際更新到新 App(Android、Windows 安裝版與免安裝版);Windows App 自行下載的安裝檔不帶 Mark of the Web。macOS 平台任務——App 自行下載的更新不帶 quarantine。Linux 平台任務——AppImage 的改名替換。【M9;quarantine、AppImage 在平台任務】 ## 9. 功能凍結的例外與里程碑規劃備忘 @@ -246,14 +250,13 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,第 4 項完成) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,階段二完成) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0025`;舊 ADR 0001–0007 仍描述根目錄舊專案。 -- 已完成(依 §3 順序):9 文檔結構 → 7 重寫策略(高層)→ 10 平台層 → 6 資料層 → 18 設定與日誌 → 12 網路與帳號 → 2 錯誤模型 → 1 音源插件 → 8 測試與開發環境 → 17 快取與離線 → 16 背景任務 → 13 播放核心 → 14 音樂庫與同步 → 11 下載與權限 → 15 歌詞 → 19 發版與更新 → 3 Toast → 5 UI/UX → 4 Debug 頁。 - 每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0026。 -- **進行中:第 7 項「重寫策略(里程碑定稿)」**,task `.trellis/tasks/09-28-design-milestones/`(planning):把 ADR 0008–0025 拆成可獨立驗證的里程碑與 child task;輸入含 §7 第一個里程碑的必要驗證、§8 延後的實測、§9 功能凍結例外與里程碑備忘、ADR 0008 的高層策略。 - 研究代理寫到 `research/`(`current-state.md`、`prior-art.md`、`repo-mechanics.md`),三個檔齊了才代表研究完成,接著抽查→prd→一次一問。 -- 之後順序:7 里程碑定稿 → 階段三(Trellis/docs 清理)。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0026`;舊 ADR 0001–0007 仍描述根目錄舊專案,於切換 PR 刪除。 +- **階段二完成**:§3 的 20 項全部 ✅;每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0027。 +- 里程碑清單與狀態:`.trellis/tasks/09-26-fmp-rewrite/milestones.md`(ADR 0026)。 +- **下一步:階段三(Trellis/docs 清理)**,依 parent prd 的階段三開 child task:刪 `docs/agents/`、AGENTS.md 的「Agent skills」段、把 CONTEXT.md 併入、修正引用、以 `git grep` 確認沒有殘留。 +- 之後順序:階段三 → M1(里程碑任務,brainstorm 核准一次,底下開 PR 子任務)→ M1 完成後開 Linux 平台任務。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/prd.md b/.trellis/tasks/09-26-fmp-rewrite/prd.md index 3f052b109..272667ee1 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/prd.md +++ b/.trellis/tasks/09-26-fmp-rewrite/prd.md @@ -200,7 +200,7 @@ FMP 是 Flutter 音樂播放器(目前支援 Android + Windows),音源為 每個 PR 附 review 指南(改了什麼、為什麼、我該看哪幾個檔案、怎麼實際驗證); 沒有經我確認的 ADR 的設計,不進代碼。 - 功能凍結:重寫期間不加新功能,想到的記進 parent task 的待辦,不實作。 -- 完成定義:`features.md` 中我勾「保留」的功能全部在新架構上跑通, +- 完成定義:`questions.md` 中我勾「保留」的功能(E1–E17,2026-09-28 更正:`features.md` 沒有勾選欄;放行條件見 ADR 0026)全部在新架構上跑通, 且效能不低於階段一記錄的基準。 - 重寫期間不發布正式版本;舊版的緊急修正怎麼處理,在階段二的重寫策略中提出方案。 - 參考其他開源專案時只參考設計;要複製代碼,先確認授權相容並告訴我。 diff --git a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md index b8d26532b..e1ea808cc 100644 --- a/docs/adr/0008-rewrite-as-new-app-in-same-repo.md +++ b/docs/adr/0008-rewrite-as-new-app-in-same-repo.md @@ -50,7 +50,7 @@ FMP 經過多輪 AI agent 自主修改(`lib/` 343 檔 99,063 行),擁有 只有同一身分,Android 上才讀得到舊 App 私有目錄的資料庫與 Keystore 保護的憑證,舊版也才能直接升級。 開發版另用身分,與正式版分開。 4. **舊版緊急修正**:在 `main` 上改根目錄舊專案、走一般 PR、照舊以 `vX.Y.Z` tag 發版;每次先經擁有者同意。 -5. **切換**:`docs/audit/features.md` 中勾「保留」的功能全部在 `app/` 跑通、效能不低於 +5. **切換**:`docs/audit/questions.md` 勾「保留」的功能(E1–E17)與各 ADR 定下的行為全部在 `app/` 跑通、效能不低於 `docs/audit/perf-baseline.md`、舊資料自動遷移在真實資料副本上驗證過之後,以一個 PR 刪除根目錄舊專案與 `docs/audit/`,並把 `release.yml`、`ci.yml`、`orca.yaml`、`tool/release/` 改指向 `app/`。 新 App 的第一個正式版本號接在舊版之後,經應用內更新送達,首次啟動執行自動遷移。 @@ -71,4 +71,4 @@ FMP 經過多輪 AI agent 自主修改(`lib/` 343 檔 99,063 行),擁有 - `app/` 不得 import 根目錄舊專案:lint `fmp_layer_imports`(ADR 0015)。 - App 身分識別:測試斷言 prod flavor 的身分值與上列一致(ADR 0015);切換前的里程碑另加一項檢查,比對 `app/` 的 `applicationId`、AppUserModelID、Inno Setup AppId 與上列現值一致。 -- 切換條件:切換 PR 的 review 指南逐項列出 `features.md` 勾「保留」的功能與效能量測結果。 +- 切換條件:切換 PR 的 review 指南逐項列出 `questions.md` 勾「保留」的功能與效能量測結果;里程碑與放行條件的細節見 ADR 0026。 diff --git a/docs/adr/0009-platform-layer-with-declared-capabilities.md b/docs/adr/0009-platform-layer-with-declared-capabilities.md index 3e3403d3b..bb1bc935f 100644 --- a/docs/adr/0009-platform-layer-with-declared-capabilities.md +++ b/docs/adr/0009-platform-layer-with-declared-capabilities.md @@ -54,7 +54,7 @@ Linux、macOS 加入時要回頭改介面。 8. **外觀**:Windows、Linux 用自訂標題列;macOS 保留系統紅綠燈按鈕。CJK 字型不內建,依平台 fallback。 9. **上線順序**:Android、Windows 從第一個里程碑起全面驗證;Linux、macOS、iOS 從第一個里程碑起在 CI 編譯 (iOS 加模擬器測試);Linux 在第一個里程碑後開 child task 於虛擬機實機驗證,之後每個里程碑冒煙測試; - macOS、iOS 取得設備後各開 child task。各平台在實機驗證完成後才發佈。 + macOS、iOS 取得設備後各開 child task。各平台在實機驗證完成後才發佈。平台任務的時程與測試環境見 ADR 0026。 ### 平台政策(決定的前提,免得重新研究) diff --git a/docs/adr/0011-settings-and-logging.md b/docs/adr/0011-settings-and-logging.md index 3b3e44ded..71a66af62 100644 --- a/docs/adr/0011-settings-and-logging.md +++ b/docs/adr/0011-settings-and-logging.md @@ -52,7 +52,7 @@ Spotube 以 drift 存設定並以 `watchSingle()` 接 Riverpod。 - 好的:任何出口都不會漏出未遮蔽的內容;錯誤可依類型與音源追查;設定的預設值可以安全調整;新增音源不必改設定 schema。 - 壞的:Debug 頁的 log 檢視要自己做;遮蔽名單要隨音源維護;release 版在本機留有 info 級別的使用紀錄(已遮蔽、不上傳)。 -- 之後要注意:統一錯誤型別的欄位由錯誤模型的 ADR 定;開發者模式的持久化、log 保留 7 天與 JSON Lines 格式、Debug 頁見 ADR 0025;各組設定的欄位清單在里程碑中依 `docs/audit/data.md` §7 定案。 +- 之後要注意:統一錯誤型別的欄位由錯誤模型的 ADR 定;開發者模式的持久化、log 保留 7 天與 JSON Lines 格式、Debug 頁見 ADR 0025;各組設定的欄位清單在引入該組設定的里程碑中依 `docs/audit/data.md` §7 定案(ADR 0026)。 ## 如何確認 diff --git a/docs/adr/0014-script-source-plugins.md b/docs/adr/0014-script-source-plugins.md index b221a324e..c42eaa335 100644 --- a/docs/adr/0014-script-source-plugins.md +++ b/docs/adr/0014-script-source-plugins.md @@ -64,7 +64,7 @@ Flutter federated plugin 的「一套介面、多種實作」;Spotube 的匹 App 本體不含非官方 API 呼叫,降低主 repo 的暴露面(不消除風險;B 站社群 API 文件庫已於 2026-01 因存證信函關閉)。 - 壞的:第一個里程碑變重(要先有 JS 執行環境與宿主 API);腳本除錯比 Dart 難;首次啟動多一步安裝;要維護第二個 repo 與其 CI; 宿主 API 一經發佈就要維持相容(以 `apiVersion` 管理)。 -- 之後要注意:`flutter_js` 在 Android 與 Windows 的 Promise、記憶體與啟動成本需實測;YouTube 可行性驗證;插件庫 repo 與插件頁的建立時程在里程碑規劃定; +- 之後要注意:`flutter_js` 在 Android 與 Windows 的 Promise、記憶體與啟動成本需實測;YouTube 可行性驗證;插件庫 repo 與插件頁在 M3 建立(ADR 0026); 自動檢查插件更新若日後需要,另立決定。 ## 如何確認 diff --git a/docs/adr/0017-background-task-scheduler.md b/docs/adr/0017-background-task-scheduler.md index 94344fdd4..3e5427c0e 100644 --- a/docs/adr/0017-background-task-scheduler.md +++ b/docs/adr/0017-background-task-scheduler.md @@ -30,7 +30,7 @@ ADR 0016 定了網路狀態與「離線中不發背景請求」,把排程、 - 下載:事件驅動,下載的 ADR 定; - 快取淘汰(ADR 0016)與 log 輪替(ADR 0011):寫入時觸發; - 更新檢查與插件更新:只手動(App 更新見 ADR 0022,更新檔清理登記在啟動維護清單); - - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次(ADR 0025 加入 log 保留期限與診斷包暫存清理)。 + - 一次性啟動維護:登記在一份「啟動維護清單」,第一個畫面後依序跑一次(ADR 0025 加入 log 保留期限與診斷包暫存清理;清單在 M2 實作,ADR 0026)。 2. **工作宣告**:id、所屬插件(可空)、間隔(空=關閉)、執行函式。「上次成功時間」存資料庫,重啟後照算。 排程器只用一個計時器,指向最早到期的工作。 3. **何時跑**:只有 App 可見(`AppLifecycleState.resumed` 或 `inactive`)且網路狀態為 `Online`(ADR 0016)時才跑。 diff --git a/docs/adr/0026-milestones-and-cut-over.md b/docs/adr/0026-milestones-and-cut-over.md new file mode 100644 index 000000000..814af1295 --- /dev/null +++ b/docs/adr/0026-milestones-and-cut-over.md @@ -0,0 +1,128 @@ +# 0026 — 里程碑與切換:九個縱向切片里程碑、里程碑任務底下開 PR 子任務、同機並量與兩週試用的放行條件 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`fmp-rewrite` 的任務結構、`.trellis/tasks/09-26-fmp-rewrite/milestones.md`、各平台任務的時程與測試環境、切換 PR 的放行條件 + +## 背景 + +ADR 0008 定了高層策略: +- 同 repo 的 `app/`; +- 主幹開發; +- 第一個里程碑是 tracer bullet; +- 切換條件是保留的功能跑通、效能不低於基準、舊資料遷移驗證過。 + +里程碑本身留到所有設計定案後才拆。 + +現況(`.trellis/tasks/archive/2026-09/09-28-design-milestones/research/`,已抽查): +- 沒有任何里程碑清單。8 份 ADR 只寫「第一個里程碑」「加入下載的里程碑」「切換前」這類描述。 +- 第一個里程碑已累積 10 份 ADR 的必要驗證(`phase2-plan.md` §7),另有 §8 的延後實測、§9 的待排項目。 +- ADR 0008 §決定 5 與 parent prd 的完成定義都寫「`features.md` 中勾『保留』」,但 `features.md` 沒有勾選欄;實際勾選在 `questions.md`(E1–E17 保留)。 +- parent prd 同時要求「每個里程碑是一個 child task」與「每個 child task 一個可 review 的 PR」,第一個里程碑一個 PR 裝不下。 +- Android 上新 App 與舊 App 同身分,是覆蓋升級,不能降版回舊版。 + +擁有者 2026-09-28 選定: +- 里程碑順序; +- 平台任務的時程與環境; +- 里程碑與 PR 的對應; +- 切換放行條件。 + +以上四題都照建議。 + +## 考慮過的選項 + +- **先蓋完一層再做下一層**:否決。違反 ADR 0008 的 tracer bullet;基礎建設的設計問題要等接上功能才會發現。 +- **舊資料匯入延到切換前**:否決。擁有者要到最後才能用真實資料試用,匯入的問題最晚才浮現。 +- **Debug 頁提早到 M2**:否決。M2 會過大;那時只有一個插件,插件開發工具用不太到。 +- **Linux 從 M1 起全面驗證**:否決,M1 已經很重。 +- **以 WSLg 驗收 Linux**:否決。它是 Weston 加 RDP: + - 沒有托盤(microsoft/wslg #532); + - 鑰匙圈預設沒在跑; + - 桌面歌詞的置頂與穿透測不準。 +- **Mac 到貨前租雲端 Mac**:否決,只等約一個月,而且 M1 本身就會超過一個月。 +- **里程碑不開 PR 子任務**:否決。每個 PR 沒有自己的驗收與檢查紀錄。 +- **每個 PR 都完整走一次 brainstorm**:否決。M1 要核准十幾次,而且多是里程碑層級已定的事。 +- **加開 GitHub Milestones 或 Projects**:否決。repo 沒有在用,與 Trellis 兩套也不會自動同步。 +- **拿存下的基準數字比較**:否決。機器、模擬器、系統更新都會讓數字漂移。 +- **效能不留誤差範圍**:否決,量測雜訊會卡住合格的版本。 +- **試用 1 週或不設試用、4 週以上**:否決。前者讓要用一陣子才會碰到的問題落到所有使用者身上;後者拉長功能凍結。 +- **切換後以降版退回**:否決。Android 降版要先移除 App,會刪掉私有資料。 + +## 決定 + +1. **結構**: + - **里程碑任務**:`fmp-rewrite` 的 child。 + - 開工時走 brainstorm,擁有者核准一次 prd/design/implement; + - implement 列出 PR 子任務與先後順序(Trellis 的 parent/child 不表達依賴)。 + - **PR 子任務**:里程碑任務的 child。 + - 一個分支、一個 PR,合進 `main`; + - prd 只寫做什麼與驗收;PR 描述附 review 指南; + - 合併後 `app/` 可編譯、測試全綠; + - 在已核准的範圍內直接做,遇到未定的事才問。 + - **里程碑驗收**:Android 與 Windows 各做一次端到端實際操作,加上併入的實測項目。 + - **平台任務**:也是 `fmp-rewrite` 的 child。 + - **追蹤**:只用 Trellis 任務樹。清單與狀態在 `.trellis/tasks/09-26-fmp-rewrite/milestones.md`。 +2. **排序原則**: + - 縱向切片,每個里程碑結束時多一件可以實際操作的事; + - 每個新增資料表的里程碑,同時補上那張表的舊資料匯入(M5 起); + - 各組設定的欄位清單(ADR 0011),在引入該組設定的里程碑定案。 +3. **里程碑**(範圍、依賴、併入的實測見 `milestones.md`): + + | # | 里程碑 | 做完能做什麼 | + |---|---|---| + | M1 | 骨架+曳光彈 | Android、Windows 搜尋 B 站並連續播放兩首;接上所有基礎建設;YouTube.js 限時探針;`phase2-plan` §7 全部實測 | + | M2 | 完整播放 | 佇列、播放頁 B、系統媒體控制、快取、背景排程器與啟動維護清單 | + | M3 | 三音源、帳號與開發工具 | YouTube、網易雲、登入;插件庫與插件頁;Debug 頁與插件開發工具 | + | M4 | 音樂庫與同步 | 歌單、匯入並刷新、外部歌單匹配、備份與還原 | + | M5 | 舊資料匯入 | 匯入舊版資料與舊備份;擁有者以 dev flavor+真實資料副本開始日常試用 | + | M6 | 下載 | 下載,並匯入舊下載紀錄 | + | M7 | 歌詞 | 多源、逐字、桌面歌詞、Android 懸浮,並匯入舊歌詞配對 | + | M8 | 桌面整合 | 托盤、全域快捷鍵、開機自啟 | + | M9 | 發版、更新與切換 | 應用內更新、使用者指南、放行條件全部通過,最後切換 PR | + + - M6、M7 互不依賴,可以對調。 +4. **平台任務**: + - **Linux**:M1 之後開。 + - 驗收在 VMware Workstation Pro(個人使用免費)的 Ubuntu LTS 桌面虛擬機,X11 與 Wayland 各一次; + - 日常開發用 WSL2; + - 之後每個里程碑在虛擬機跑一次冒煙測試。 + - **macOS、iOS**:Mac 到貨後開。 + - 到貨前只靠 GitHub macOS runner 的編譯與 iOS 模擬器測試(ADR 0009); + - iOS 要不要實機、要不要付費帳號,在該任務決定。 +5. **切換放行條件**(取代 ADR 0008 §決定 5 的功能清單來源): + 1. **功能**:`questions.md` 勾「保留」的功能(E1–E17)與各 ADR 定下的行為全部在 `app/` 跑通,切換 PR 的 review 指南逐項列出。 + 2. **效能**: + - 同一台電腦、同一模擬器、同一份資料副本,以 `perf-baseline.md` 的命令把舊版與新版各量 5 次,比中位數; + - 新版每項不得比舊版差超過 5%,超出就重量一次,仍超出則不放行。 + 3. **資料**: + - 真實資料副本完整匯入,並比對筆數(ADR 0010); + - 在模擬器與虛擬機上以資料副本從 v1.11.0 實際升級(ADR 0022)。 + 4. **試用**:候選版當擁有者的主要播放器滿 2 週,期間沒有未解決的阻擋性 bug(資料錯誤、無法播放、當機)。 + 5. **切換後**:以 2.0.x 經應用內更新往前修,不做降版。舊資料不自動刪除,可以重新匯入(ADR 0010)。 + +採用的慣例: +- Cockburn 的 walking skeleton 與 Pragmatic Programmer 的 tracer bullets; +- NewPipe 的「重寫期間舊版只收修正」; +- Firefox Fenix 以清單追蹤缺口並事先聲明資料風險; +- Spotube v5 以一次 major 版本為切換點。 + +## 後果 + +- 好的: + - 每個里程碑結束時都有可實際操作的成果; + - 每個 PR 小到能 review,又有里程碑層級的一次性核准; + - 從 M5 起用真實資料試用,匯入的問題較早浮現; + - 放行條件可重現、可量測。 +- 壞的: + - M1 很重,含全部基礎建設與 §7 的實測; + - 切換前要實際量兩個版本、試用 2 週,功能凍結的時間拉長; + - Linux、macOS、iOS 的功能會落後 Android 與 Windows。 +- 之後要注意: + - 里程碑的範圍若在開工時要大改,要回來修 `milestones.md` 並說明原因; + - 切換 PR 同時刪除 ADR 0001–0007(`docs/adr/template.md` 的例外規則)與 `docs/audit/`。 + +## 如何確認 + +- 每個里程碑任務 archive 前,`milestones.md` 的狀態欄與驗收項目逐項打勾;未打勾的不能 archive。 + - 這是 review 點,不是自動閘門:里程碑驗收要實機操作,無法寫成測試。 +- 切換 PR 的 review 指南必須附上四樣:功能清單逐項結果、效能對照表(5 次中位數)、匯入筆數比對、2 週試用期間的 bug 清單。 From 94b2a3e27c12892e151da97f99ebc18332edc9c4 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:34:43 +0800 Subject: [PATCH 116/133] chore(task): archive design-milestones --- .../2026-09}/09-28-design-milestones/check.jsonl | 0 .../2026-09}/09-28-design-milestones/design.md | 0 .../2026-09}/09-28-design-milestones/implement.jsonl | 0 .../2026-09}/09-28-design-milestones/implement.md | 12 ++++++------ .../2026-09}/09-28-design-milestones/prd.md | 0 .../research/current-state.md | 0 .../09-28-design-milestones/research/prior-art.md | 0 .../research/repo-mechanics.md | 0 .../2026-09}/09-28-design-milestones/task.json | 6 +++--- 9 files changed, 9 insertions(+), 9 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/implement.md (79%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/research/prior-art.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/research/repo-mechanics.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-design-milestones/task.json (88%) diff --git a/.trellis/tasks/09-28-design-milestones/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-milestones/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-milestones/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/check.jsonl diff --git a/.trellis/tasks/09-28-design-milestones/design.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/design.md similarity index 100% rename from .trellis/tasks/09-28-design-milestones/design.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/design.md diff --git a/.trellis/tasks/09-28-design-milestones/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-design-milestones/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-design-milestones/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/implement.jsonl diff --git a/.trellis/tasks/09-28-design-milestones/implement.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/implement.md similarity index 79% rename from .trellis/tasks/09-28-design-milestones/implement.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/implement.md index e6fd43b45..55174f149 100644 --- a/.trellis/tasks/09-28-design-milestones/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-design-milestones/implement.md @@ -1,6 +1,6 @@ # 執行計畫:第 7 項定稿(設計任務,只產出文件) -1. [ ] 核准後寫 `docs/adr/0026-milestones-and-cut-over.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1、§3,以及 §2 的排序原則。 +1. [x] 核准後寫 `docs/adr/0026-milestones-and-cut-over.md`(依 `docs/adr/template.md`),內容取自 `design.md` §1、§3,以及 §2 的排序原則。 被否決的方案: - 舊資料匯入延到切換前; - Debug 頁提早到 M2; @@ -15,15 +15,15 @@ - 不留誤差範圍; - 試用 1 週、不設試用、4 週以上; - 切換後以降版退回。 -2. [ ] 新增 `.trellis/tasks/09-26-fmp-rewrite/milestones.md`:`design.md` §2 的清單,加上狀態欄。 -3. [ ] 更正與指向: +2. [x] 新增 `.trellis/tasks/09-26-fmp-rewrite/milestones.md`:`design.md` §2 的清單,加上狀態欄。 +3. [x] 更正與指向: - ADR 0008(功能清單來源)、parent `prd.md` 完成定義; - ADR 0009、0011、0014、0017 各加一句指向 0026。 -4. [ ] 更新 `phase2-plan.md`: +4. [x] 更新 `phase2-plan.md`: - §3 第 20 列 ✅; - §7、§8 各項標上所屬里程碑; - §10 改為階段二完成、下一步階段三(Trellis/docs 清理),之後 M1。 -5. [ ] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用,以及沒有殘留「`features.md` 中勾」。 -6. [ ] `task.py finish`,再 `task.py archive design-milestones --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 +5. [x] 驗證:Mermaid 以 mermaid-cli 渲染;`git grep` 確認 ADR 間的引用,以及沒有殘留「`features.md` 中勾」。 +6. [x] `task.py finish`,再 `task.py archive design-milestones --no-commit --skip-branch-validation`;ADR 與歸檔分開提交,推上 `docs/audit`。 回退:全部是文件,revert 對應 commit 即可。 diff --git a/.trellis/tasks/09-28-design-milestones/prd.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/prd.md similarity index 100% rename from .trellis/tasks/09-28-design-milestones/prd.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/prd.md diff --git a/.trellis/tasks/09-28-design-milestones/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-design-milestones/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/research/current-state.md diff --git a/.trellis/tasks/09-28-design-milestones/research/prior-art.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/research/prior-art.md similarity index 100% rename from .trellis/tasks/09-28-design-milestones/research/prior-art.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/research/prior-art.md diff --git a/.trellis/tasks/09-28-design-milestones/research/repo-mechanics.md b/.trellis/tasks/archive/2026-09/09-28-design-milestones/research/repo-mechanics.md similarity index 100% rename from .trellis/tasks/09-28-design-milestones/research/repo-mechanics.md rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/research/repo-mechanics.md diff --git a/.trellis/tasks/09-28-design-milestones/task.json b/.trellis/tasks/archive/2026-09/09-28-design-milestones/task.json similarity index 88% rename from .trellis/tasks/09-28-design-milestones/task.json rename to .trellis/tasks/archive/2026-09/09-28-design-milestones/task.json index 8b918002d..b9bb073e8 100644 --- a/.trellis/tasks/09-28-design-milestones/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-design-milestones/task.json @@ -3,7 +3,7 @@ "name": "design-milestones", "title": "Finalize rewrite milestones", "description": "Phase-2 item 7 (final): split ADR 0008-0025 into independently verifiable milestones and child tasks, with branch, release and switch-over plan", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 6d3d61fd0e94ca4a33df3c9ac2b7d9e5bce251ff Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:36:41 +0800 Subject: [PATCH 117/133] chore(task): start phase3-docs-cleanup --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 ++- .../09-28-phase3-docs-cleanup/check.jsonl | 0 .../09-28-phase3-docs-cleanup/implement.jsonl | 0 .../tasks/09-28-phase3-docs-cleanup/prd.md | 19 ++++++++++++++ .../tasks/09-28-phase3-docs-cleanup/task.json | 26 +++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/check.jsonl create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/implement.jsonl create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/prd.md create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index ba4a60c60..3ce52160f 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -255,7 +255,7 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0026`;舊 ADR 0001–0007 仍描述根目錄舊專案,於切換 PR 刪除。 - **階段二完成**:§3 的 20 項全部 ✅;每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0027。 - 里程碑清單與狀態:`.trellis/tasks/09-26-fmp-rewrite/milestones.md`(ADR 0026)。 -- **下一步:階段三(Trellis/docs 清理)**,依 parent prd 的階段三開 child task:刪 `docs/agents/`、AGENTS.md 的「Agent skills」段、把 CONTEXT.md 併入、修正引用、以 `git grep` 確認沒有殘留。 +- **進行中:階段三(Trellis/docs 清理)**,task `.trellis/tasks/09-28-phase3-docs-cleanup/`(planning);研究代理寫到 `research/`(`current-state.md`、`open-questions.md`),兩個檔齊了才代表研究完成,接著抽查→prd→一次一問。依據是第 9 項的設計(`archive/2026-09/09-27-design-docs` 的 design §4、§6 與 implement §B)與 parent prd 的階段三。範圍:刪 `docs/agents/`、AGENTS.md 的「Agent skills」段、把 CONTEXT.md 併入、修正引用、以 `git grep` 確認沒有殘留。 - 之後順序:階段三 → M1(里程碑任務,brainstorm 核准一次,底下開 PR 子任務)→ M1 完成後開 Linux 平台任務。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index 405367385..ee1dbc899 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -39,7 +39,8 @@ "09-28-design-toast", "09-28-design-ui-ux", "09-28-design-debug-page", - "09-28-design-milestones" + "09-28-design-milestones", + "09-28-phase3-docs-cleanup" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/check.jsonl b/.trellis/tasks/09-28-phase3-docs-cleanup/check.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/implement.jsonl b/.trellis/tasks/09-28-phase3-docs-cleanup/implement.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md new file mode 100644 index 000000000..3b9aaf5f0 --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md @@ -0,0 +1,19 @@ +# Phase 3 docs and Trellis cleanup + +## Goal + +Phase 3: remove mattpocock residue, settle old ADRs and CONTEXT.md, fix Trellis/agent-file conflicts, plan verify-on-device for new platforms + +## Requirements + +- TBD + +## Acceptance Criteria + +- [ ] TBD + +## Notes + +- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. +- Lightweight tasks can remain PRD-only. +- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/task.json b/.trellis/tasks/09-28-phase3-docs-cleanup/task.json new file mode 100644 index 000000000..f172e8ee6 --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/task.json @@ -0,0 +1,26 @@ +{ + "id": "phase3-docs-cleanup", + "name": "phase3-docs-cleanup", + "title": "Phase 3 docs and Trellis cleanup", + "description": "Phase 3: remove mattpocock residue, settle old ADRs and CONTEXT.md, fix Trellis/agent-file conflicts, plan verify-on-device for new platforms", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From a41c14fb61ce9ed46d294bef26386df0fcb2a46a Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 22:43:13 +0800 Subject: [PATCH 118/133] chore(task): add phase three research and prd --- .../tasks/09-28-phase3-docs-cleanup/prd.md | 76 ++- .../research/current-state.md | 522 ++++++++++++++++++ .../research/open-questions.md | 194 +++++++ 3 files changed, 773 insertions(+), 19 deletions(-) create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md index 3b9aaf5f0..70d2885a5 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md @@ -1,19 +1,57 @@ -# Phase 3 docs and Trellis cleanup - -## Goal - -Phase 3: remove mattpocock residue, settle old ADRs and CONTEXT.md, fix Trellis/agent-file conflicts, plan verify-on-device for new platforms - -## Requirements - -- TBD - -## Acceptance Criteria - -- [ ] TBD - -## Notes - -- Keep `prd.md` focused on requirements, constraints, and acceptance criteria. -- Lightweight tasks can remain PRD-only. -- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`. +# 階段三:Trellis 與文檔清理 + +## 目標 + +依 parent prd 的「階段三」與第 9 項的設計(`archive/2026-09/09-27-design-docs` 的 design §1、§2、§4、§6,implement §B)做以下事情: +- 移除 mattpocock 的殘留; +- 收尾舊 ADR 與 `CONTEXT.md`; +- 修正 agent 指令檔之間的衝突; +- 規劃 verify-on-device 如何擴充到新平台,以及實機驗證時如何少打真實 API。 + +## 現況(`research/current-state.md`,已抽查) + +- **mattpocock 殘留** + - `docs/agents/` 三個檔;AGENTS.md「Agent skills」段(`:7-14`);`docs/README.md:21,23`。 + - 仍需要的慣例只有一條:「issue 用繁中撰寫」(`docs/agents/issue-tracker.md:43-48`)。 + - 5 個 triage label 與 5 個 `wayfinder:*` label 在 repo 內沒有任何使用者。 +- **`docs/README.md`** + - 地圖表只有三欄,沒有文件類型欄,也沒有 `docs/audit/` 這一列; + - `:12` 寫 spec 是「英文,給 agent 讀」; + - `:21` 是中英分工的規則(第 9 項 R7 要刪)。 +- **舊 ADR 0001–0007** + - 只有 0002、0007 加了「只適用舊專案」註記。 + - 0001、0003、0004、0005、0006 沒加,但都已被新 ADR 延續或取代;其中 0001 沒有任何新 ADR 寫「取代」。 + - 引用它們的地方都屬於舊專案:`lib/`、`test/`、`tool/`、`.github/`、`.trellis/spec/`、AGENTS.md、`docs/*.md`。這些在切換 PR 一起處理(ADR 0026)。 +- **`CONTEXT.md`**:5 個術語。 + - 4 條原則在 ADR 0012 有對應句(`:16` 已寫明併入)。 + - Media Handoff 的「轉址時每一跳都檢查網域」在所有新 ADR 都沒有對應;舊版在 `source_url_policy.dart:81-122`,轉址目標要在允許清單內,最多 5 次。 + - 引用它的地方:spec 7 處、AGENTS.md `:13`、parent 任務文件。 +- **衝突** + - **AGENTS.md 的 Trellis 區塊**(`:128-130`)提到 `.codex/`(不存在)與 `.agents/`(本機、已 gitignore)。這個區塊由 Trellis 管理,`trellis update` 會覆寫。 + - **本機 `.agents/skills/verify-on-device/`**:與 `.claude/` 版互有對方沒有的內容。 + - `.agents/` 版有 2026-09-07 的實測筆記; + - `.claude/` 版有 `references/` 與 `msaa_tree.ps1`。 + - **check 子代理三份定義**:Claude Code 實際用的是 `.claude/agents/trellis-check.md`(`workflow.md:237`,已依 AGENTS.md 客製)。另兩份是 Trellis 產生的 skill 與 channel 定義,會被 `trellis update` 覆寫。 + - **journal/archive commit**:三份 Trellis 管理的檔案描述會自動 commit,但 `config.yaml:34` 的 `session_auto_commit: false` 讓它不會發生。 + - **AGENTS.md「Test waits」**(`:93-96`)宣稱三件事,但閘門只守其中一件:禁止直接呼叫 `pumpEventQueue`。 +- **Trellis 管理的檔案**:84 個,其中 81 個與模板相同、`trellis update` 會直接覆寫;3 個已客製(`trellis-check.md`、`trellis-implement.md`、`config.yaml`)。AGENTS.md 只有標記區塊內會被覆寫。 +- **verify-on-device** + - 只涵蓋 Android(必要)與 Windows; + - 跑的是真實 App 對真實音源(`references/runtime-state.md:35-36`); + - ADR 0015 的零聯網只管 `flutter test`,不管這個 skill。 +- **語言**: + - 還是英文的只有 AGENTS.md(134 行)與 `.trellis/spec/` 20 檔(1444 行),兩者描述的都是凍結中的舊專案,切換 PR 時會被取代。 + - `docs/` 與 ADR 已是繁中。 + +## 待決定(一次問一題) + +1. 根目錄 AGENTS.md 與 `.trellis/spec/` 要不要現在翻成繁中(第 9 項 R7「所有文檔繁中」的適用範圍)。 +2. verify-on-device 在新平台怎麼擴充,以及實機驗證時預設用真實連線還是重播。 + +## 驗收條件 + +- [ ] 兩條 `git grep`(第 9 項 implement §B)只命中刻意保留的檔案。 +- [ ] `docs/agents/`、`CONTEXT.md` 已刪除;「issue 用繁中撰寫」寫進 AGENTS.md。 +- [ ] 舊 ADR 0001、0003–0006 都有「只適用舊專案」註記。 +- [ ] ADR 0012 補上 Media Handoff 的轉址網域檢查原則。 +- [ ] 第 9 項 design §6 的衝突各有處置,並記在 AGENTS.md 的 Trellis 段(標記區塊外)。 diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md b/.trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md new file mode 100644 index 000000000..e15bdb004 --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md @@ -0,0 +1,522 @@ +# 階段三現況盤點(current-state) + +- 盤點對象:branch `docs/audit`,HEAD `94b2a3e2`。 +- 除特別註明,`file:line` 皆指 repo 根目錄下的檔案;指令在 repo 根目錄執行。 +- 依研究指示排除 `.trellis/tasks/archive/`(歷史紀錄,不改)與 `docs/audit/`(凍結快照)。 +- 證據優先序:程式碼與測試 > 文件敘述。凡引用 `docs/audit/` 者只在「佐證文件自己的宣稱」時使用。 + +--- + +## a. mattpocock 殘留 + +### a.1 `docs/agents/` 三個檔的內容 + +`docs/agents/` 共 3 檔(`ls docs/agents/`):`domain.md`、`issue-tracker.md`、`triage-labels.md`。 + +**`docs/agents/domain.md`(53 行)** + +- `:5` 宣告本 repo 是 **single-context**:root 一份 `CONTEXT.md` + 一份 `docs/adr/`。這個檔名慣例來自 mattpocock 的 domain-modeling skill(`docs/audit/engineering.md:477`)。 +- `:7-11` 「探索前先讀」:`CONTEXT.md`(source auth 與 media handoff 的 ubiquitous language)+ `docs/adr/`(讀與你工作範圍相關的 ADR)。 +- `:13` 提到 `/domain-modeling`、`/grill-with-docs`、`/improve-codebase-architecture` 三個 skill 名稱。 +- `:15-24` 三份文件的分工:`CONTEXT.md` 管 vocabulary、`docs/adr/` 記 why、`AGENTS.md` 記 binding rules。這一段與 `design.md` §2 的分工表同義,但用詞是模板的。 +- `:26-35` 檔案結構圖(`CONTEXT.md` / `AGENTS.md` / `docs/adr/NNNN-<slug>.md` / `lib/`)。 +- `:37-41` 要求輸出用 glossary 的詞(例:寫 **Media Request Credentials** 不要寫 "playback headers")。 +- `:43-47` 「Flag ADR conflicts」,範例引用 **「ADR-0007 (event-sourced orders)」** —— 與本 repo 的 ADR 0007(Isar 停在 v3)無關,是模板殘留字串。 +- `:49-53` 語言政策:ADR 用繁中(台港用語);`CONTEXT.md` 保留英文術語名。**這條與 `docs/README.md:21` 的「中英分工」是同一個政策**,而 `docs/README.md:21` 依 design-docs R7 要刪。 + +**`docs/agents/issue-tracker.md`(58 行)** + +- `:3-5` Issues/PRD 用 GitHub Issues on `1morr/FMP`,一律用 `gh`。 +- `:9-14` gh 操作慣例:create / view / list / comment / label / close(含 `--json`+`jq` 範例)。 +- `:16-21` 「刻意沒有 issue template」:觸發條件是「**第一個非擁有者開的 issue**」,不是 repo 大小。 +- `:25` `PRs as a request surface: **no**`(旗標供 `/triage` 讀)。 +- `:35-41` 「skill 說 publish to the issue tracker」→ 開 GitHub issue。 +- `:43-48` **語言**:issue 標題與內文用繁中(台港用語);code identifier、log string、commit message、branch name、label string 保留英文;**並回指 `docs/README.md § 分工`**(該節在階段三會被改寫)。 +- `:50-59` **Wayfinding operations**(`/wayfinder` 用):map 是單一 issue(label `wayfinder:map`)、child ticket 用 sub-issue、blocking 用 GitHub native issue dependencies、frontier query、claim、resolve。用到 5 個 label 字串:`wayfinder:map`、`wayfinder:research`、`wayfinder:prototype`、`wayfinder:grilling`、`wayfinder:task`。 + +**`docs/agents/triage-labels.md`(17 行)** + +- `:5-11` 五個 triage 角色的 label 對照表,左欄(mattpocock/skills)與右欄(our tracker)**逐列相同**:`needs-triage`、`needs-info`、`ready-for-agent`、`ready-for-human`、`wontfix`。 +- `:15-17` 「FMP uses the defaults unchanged」;label string 保留英文,即使 issue body 是繁中。 + +### a.2 AGENTS.md「Agent skills」段 + +`AGENTS.md:7-14`,只有三條 bullet,全部指向 `docs/agents/`: + +- `AGENTS.md:9-10` Issue tracker → `docs/agents/issue-tracker.md` +- `AGENTS.md:11-12` Triage labels → `docs/agents/triage-labels.md` +- `AGENTS.md:13-14` Domain docs(single-context: `CONTEXT.md` + `docs/adr/`)→ `docs/agents/domain.md` + +`AGENTS.md` 全檔除這段外,只有 `:82` 引到 ADR 0002(見 § c)。 + +### a.3 design-docs implement §B 的兩條 git grep 結果 + +指令原文 `implement.md:27`: + +``` +git grep -n -E "docs/agents|CONTEXT\.md|Agent skills|wayfinder|grill-with-docs" -- . ':!.trellis/tasks/archive' ':!docs/audit' +git grep -n -E "adr/000[1-7]|ADR 000[1-7]" -- . ':!.trellis/tasks/archive' ':!docs/audit' +``` + +**第 1 條命中(`implement.md:27`)** + +| 檔案:行 | 命中的字串 | +|---|---| +| `AGENTS.md:7` | `## Agent skills` | +| `AGENTS.md:10,12,14` | `docs/agents/...` | +| `AGENTS.md:13` | `CONTEXT.md` | +| `docs/README.md:21` | `docs/agents/` | +| `docs/README.md:23` | `docs/agents/`(並提到 `/setup-matt-pocock-skills`) | +| `docs/adr/0012-network-layer-and-accounts.md:16` | `CONTEXT.md`(併入聲明) | +| `docs/agents/domain.md:5,9,13,19,30,39,52` | `CONTEXT.md`;`:13` 另有 `/grill-with-docs` | +| `docs/agents/issue-tracker.md:52,54,55` | `/wayfinder`、`wayfinder:map`、`wayfinder:<type>` | +| `.trellis/spec/data/index.md:9` | `CONTEXT.md` | +| `.trellis/spec/data/sources.md:81` | `CONTEXT.md` | +| `.trellis/spec/guides/cross-layer-thinking-guide.md:51` | `CONTEXT.md` | +| `.trellis/spec/services/download-and-auth.md:3,38` | `CONTEXT.md` | +| `.trellis/spec/services/index.md:8,24` | `CONTEXT.md` | +| `.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md:23,113,209,258` | `CONTEXT.md` | +| `.trellis/tasks/09-26-fmp-rewrite/prd.md:13,18,85,86,88,92,186,190` | `CONTEXT.md`、`docs/agents`、`Agent skills` | +| `.trellis/tasks/09-28-phase3-docs-cleanup/prd.md:5` | `CONTEXT.md`(英文描述行) | +| `.trellis/tasks/09-28-phase3-docs-cleanup/task.json:5` | `CONTEXT.md`(英文描述行) | + +**第 2 條命中(舊 ADR 編號)**:見 § c.3 的分組表。 + +兩條都還有大量命中;設計要求的「只能命中仍存在、刻意保留的檔案」目前尚未達成。 + +### a.4 `.trellis/spec/` 的 7 處 `CONTEXT.md` 引用(design.md §4 指定的清單) + +`design.md:62` 與 `implement.md:20` 點名 7 處:`.trellis/spec/data/index.md:9`、`data/sources.md:81`、`guides/cross-layer-thinking-guide.md:51`、`services/download-and-auth.md:3`、`services/download-and-auth.md:38`、`services/index.md:8`、`services/index.md:24`。實際 grep 命中與此清單完全一致(另加 `AGENTS.md:13`、`docs/adr/0012:16`、`docs/README.md` 間接、`docs/agents/*` 本身)。 + +### a.5 哪些慣例仍需要、哪些沒有消費者 + +**仍需要(design.md:72、R6 只保留這一條):** + +- **「issue 用繁中撰寫」**:`docs/agents/issue-tracker.md:43-48`。同一條 policy 也寫在 `docs/agents/domain.md:49-53`(ADR 用繁中)與 `docs/README.md:21`(語系分工)。parent prd `prd.md:187` 明說「若『issue 用繁體中文撰寫』等慣例仍需要,搬一句到 AGENTS.md」。 + +**repo 內查不到消費者(`git grep -n -E "needs-triage|needs-info|ready-for-agent|ready-for-human|wontfix|wayfinder"` 排出 archive、`docs/agents` 後零命中):** + +- `triage-labels.md` 的 5 個 label 字串:沒有任何 workflow、script、hook、`.claude/` 設定引用。 +- `wayfinder:*` 5 個 label 字串:同樣零命中。 +- `.github/` 只有 `dependabot.yml` 與 `workflows/`(`ls .github/`),**沒有** `.github/ISSUE_TEMPLATE/`(`docs/agents/issue-tracker.md:18-21` 說這是刻意的)。 +- 反之,`issue-tracker.md:9-14` 的 gh create/view/list/comment/label/close 慣例是通用 `gh` 用法,repo 內也沒有別的檔案寫。 + +**`docs/agents/domain.md` 的前提已經消失**:它整份繞著 `CONTEXT.md`(`:5,9,19,30,39,52`)—— 而 `CONTEXT.md` 在階段三要刪(design.md §4、`implement.md:20`)。 + +**沒有 CLAUDE.md**:`design.md:14` 與 `docs/audit/engineering.md:626` 都指出本 repo 沒有 `CLAUDE.md`,Claude Code 直接載入 `AGENTS.md`;`.claude/settings.json:72` `"enabledPlugins": {}`,mattpocock skills 來自使用者全域環境,不是專案設定。 + +--- + +## b. `docs/README.md` + +(全文 25 行,`docs/README.md`) + +### b.1 現況地圖 + +`docs/README.md:3` 開頭:root `README.md` 是產品入口;AI agent 規則在 `AGENTS.md`,人類貢獻者適用同一套。 + +表頭 `:5-6`:「文件 | 什麼時候讀 | 什麼變了要更新它」——**只有三欄,沒有文件類型欄**。 + +| 列 | 文件 | 備註 | +|---|---|---| +| `:7` | `README` | 產品入口;使用者可見功能、截圖、下載入口、專案定位 | +| `:8` | `building.md` | 本機建置 | +| `:9` | `development.md` | 架構與主要模組;VM Service 查 running app | +| `:10` | `build-and-release.md` | 發版、CI、產物命名、簽名 secrets、應用內更新資產 | +| `:11` | `troubleshooting.md` | 建置或 runtime log 噪音、繞不過的行為 | +| `:12` | `.trellis/spec/` | 明寫 **「(英文,給 agent 讀)」** | +| `:13` | `adr/` | 跨模組決定「當初為什麼這樣選」 | +| `:14` | `verify-on-device skill`(`.claude/skills/verify-on-device/SKILL.md`) | 改了使用者可見行為的強制實機驗證 | +| `:15` | `agents/` | **「(給 engineering skills 讀,不是給人讀)」**;更新時機寫「換 issue 追蹤系統或標籤詞彙」 | + +**沒有 `docs/audit/` 這一列。** + +`## 分工`(`:17-24`)共 6 條: + +- `:19` 單段程式碼的理由寫在旁邊;只有程式碼查不到的跨檔契約與地雷才進 `AGENTS.md`。 +- `:20` 同一條規則只寫在一個地方。 +- `:21` **語系分工**:「`AGENTS.md`、`docs/agents/` 與 `.trellis/spec/` 維持英文…`docs/` 其餘文件與根目錄 `README.zh-Hant.md` 以繁體中文撰寫。」 +- `:22` `.claude/skills/` 放 Claude Code skill;`.gitignore` 另外追蹤 Trellis 接線(`.claude/` 下的 `agents/`、`commands/`、`hooks/`、`settings.json`);`.claude/` 其餘與 `.trellis/workspace/` 是本機狀態。 +- `:23` **`docs/agents/` 三個檔是 `/setup-matt-pocock-skills` 的產出再加上 FMP 專屬修改**(repo 釘死 `1morr/FMP`、繁中語言政策),重跑那個 skill 會用泛用模板覆蓋。 +- `:24` 「審查記錄不進 `docs/`。一輪審計的結論寫進它所描述的檔案、開成 issue,或留在 git 歷史。」 + +### b.2 依 design-docs §1/§B.2 要改的地方 + +- `implement.md:18`(§B.2):地圖表**加 Diátaxis 類型欄**;刪 `:21` 的中英分工規則;刪 `:23` 的 `docs/agents/` 說明;`docs/audit/` 註明為**凍結快照**。 +- `design.md:10`(§1 地圖):`docs/*.md` 讀者是「人類開發者」,放操作指南/參考/說明,**不放 agent 規則**;採 Diátaxis,且「不預建四個空資料夾」,地圖表加一欄標每份文件的類型。 +- `design.md:18`+R7(`prd.md:28`):**所有文檔繁中**(含 ADR、`docs/`);README 例外維持英/繁雙語。→ `:21` 整條刪;`:12` 的「(英文,給 agent 讀)」與 R7 衝突,需改。 +- `:15` 的 `agents/` 列依 `implement.md:18` 一起刪(`docs/agents/` 整個目錄刪除)。 +- `:24` 與 `docs/audit/` 的例外:`design.md:66` 說凍結期保留這個例外,**最後一個里程碑**的 PR 刪 `docs/audit/` 並把 `:24` 恢復成無例外。 +- `:22` 的 Trellis 接線敘述需與 AGENTS.md「Trellis」段(`AGENTS.md:107-112`)一致:目前 `:22` 沒提 journal 留本機與 `.agents/`。 + +--- + +## c. 舊 ADR 0001–0007 + +檔案行數:0001 138、0002 77、0003 104、0004 77、0005 101、0006 101、0007 54。 + +### c.1 是否已有「只適用舊專案」註記 + +`git grep -n "只適用舊專案" -- . ':!.trellis/tasks/archive'` 只有 **`docs/adr/template.md:7`**(規則本身)。實際加註的只有兩份: + +| ADR | 註記 | 位置 | +|---|---|---| +| 0002 | **有** | `docs/adr/0002-repository-boundary.md:3`:「只適用根目錄舊專案;新專案(`app/`)見 ADR 0010…本檔在切換 PR 隨舊專案刪除(ADR 0008)。」 | +| 0007 | **有** | `docs/adr/0007-isar-stays-on-v3.md:3`:同句。 | +| 0001 | 無 | 檔頭 `0001-...md:1-5` 只有標題+狀態/日期/影響範圍 | +| 0003 | 無 | 同上(`:1-5`) | +| 0004 | 無 | 同上(`:1-5`) | +| 0005 | 無 | 同上(`:1-5`) | +| 0006 | 無 | 同上(`:1-5`;狀態是「已實作」不是「已採納」) | + +`docs/adr/template.md:7` 的例外規則:「被取代的舊 ADR 若仍描述凍結中的根目錄舊專案,改在舊檔開頭加註「只適用舊專案」,於切換 PR 隨舊專案刪除(ADR 0008)」。→ 目前 5 份(0001、0003、0004、0005、0006)未加。 + +### c.2 被哪一份新 ADR 取代(design.md §4 + 新 ADR 本文) + +phase-2 項目編號 → ADR 的對應見 `.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md:15-33`(1→0014、6→0010、11→0020、12→0012、13→0018、18→0011、19→0022)。 + +| 舊 ADR | design.md §4 的處理 | 對應新 ADR(檔內證據) | +|---|---|---| +| 0001 字串音源 id + 每源設定清單 | 字串 id 確認沿用;每源設定清單由第 6/18 項取代;第 1 項寫插件 ADR 時把字串 id 併進去,0001 同時刪除(`design.md:54`) | 字串 id → `docs/adr/0014-...md:37`(manifest `id`(字串音源 id));每源設定 → `docs/adr/0011-...md`(設定分組)+ `docs/adr/0012-...md:49`(每音源設定表)。**沒有任何新 ADR 寫「取代 ADR 0001」** | +| 0002 Isar 只在 repository 層 | 第 6 項決定後換庫則刪;原則寫進新資料層 ADR(`design.md:55`) | `docs/adr/0010-...md:16`:「本 ADR 對新專案取代 ADR 0002、0007;那兩份仍描述根目錄舊專案」 | +| 0003 兩個音訊後端 | 第 13 項重新決定,新 ADR 取代(`design.md:56`) | `docs/adr/0018-playback-core.md:17`:「本 ADR 延續舊 ADR 0003「兩個後端」的形狀,適用於 `app/`;舊 ADR 0003 仍描述根目錄舊專案」 | +| 0004 Android 所有檔案存取權 | 第 11 項重新決定,新 ADR 取代(`design.md:57`) | `docs/adr/0020-...md:18`:「舊 ADR 0004(Android 以 `MANAGE_EXTERNAL_STORAGE`+路徑、不用 MediaStore)描述舊專案;本 ADR 在 `app/` 延續其儲存做法」 | +| 0005 曲目識別鍵包含 cid | 確認沿用(也是舊資料遷移要用的格式);第 6 項視需要改寫(`design.md:58`) | `docs/adr/0010-...md:45`(曲目以 `TrackKey` 字串(含 cid,ADR 0005)為唯一鍵)、`docs/adr/0019-...md:39`(ADR 0005 的曲目鍵格式照搬) | +| 0006 Release 自動發布 | 確認沿用;第 19 項補「發佈說明由 CHANGELOG 產生」後改寫(`design.md:59`) | `docs/adr/0022-...md:19`:「本 ADR 延續舊 ADR 0004(不上架商店)與 0006(驗過直接發布、不留人工閘門),適用於 `app/`;這兩份仍描述根目錄舊專案」 | +| 0007 Isar 停在 v3 | 隨 0002 一起處理(`design.md:60`) | `docs/adr/0010-...md:16` | + +切換 PR 的刪除清單:`docs/adr/0026-milestones-and-cut-over.md:122`「切換 PR 同時刪除 ADR 0001–0007(`docs/adr/template.md` 的例外規則)與 `docs/audit/`」。 + +### c.3 所有引用(`git grep -n -E "adr/000[1-7]|ADR 000[1-7]"`,排除 archive 與 docs/audit) + +**屬舊專案的檔案(切換 PR 會一起刪或改指向 `app/`)** + +| 檔案:行 | 引用 | +|---|---| +| `.github/workflows/release.yml:359` | `docs/adr/0006`(註解:不建草稿、不等人按 publish) | +| `tool/release/verify_release_assets.dart:6` | `docs/adr/0006` | +| `test/workflows/release_workflow_test.dart:131` | `docs/adr/0006` | +| `test/workflows/release_assets_verification_test.dart:9` | `docs/adr/0006` | +| `lib/data/repositories/lyrics_repository.dart:64` | `ADR 0005` | +| `lib/data/repositories/search_history_repository.dart:10` | `docs/adr/0002-repository-boundary.md` | +| `AGENTS.md:82` | `ADR 0002`(Isar access 邊界規則) | +| `docs/build-and-release.md:159` | `ADR 0006` | +| `docs/build-and-release.md:210` | `ADR 0007` | +| `docs/development.md:12` | `ADR 0003` | +| `.trellis/spec/data/index.md:22` | `ADR 0001` | +| `.trellis/spec/data/index.md:23` | `ADR 0005` | +| `.trellis/spec/data/index.md:25` | `ADR 0002` | +| `.trellis/spec/data/persistence.md:3` | `ADR 0007`、`ADR 0002` | +| `.trellis/spec/data/persistence.md:28` | `ADR 0001` | +| `.trellis/spec/data/persistence.md:68` | `ADR 0002` | +| `.trellis/spec/data/persistence.md:118` | `ADR 0005` | +| `.trellis/spec/guides/cross-layer-thinking-guide.md:37` | `ADR 0001` | +| `.trellis/spec/guides/cross-layer-thinking-guide.md:46` | `ADR 0005` | +| `.trellis/spec/services/audio.md:3` | `ADR 0003` | +| `.trellis/spec/services/download-and-auth.md:3` | `ADR 0004` | +| `.trellis/spec/services/index.md:22` | `ADR 0003` | +| `.trellis/spec/services/index.md:23` | `ADR 0004` | +| `.trellis/spec/services/service-conventions.md:25` | `ADR 0002` | + +**屬新設計的檔案(`docs/adr/0008+`,階段三只收尾不改)** + +| 檔案:行 | 引用 | +|---|---| +| `docs/adr/0010-drift-data-layer-and-legacy-import.md:16` | 取代 `ADR 0002`、`0007` | +| `docs/adr/0010-...md:45` | `ADR 0005` | +| `docs/adr/0018-playback-core.md:17` | `ADR 0003` | +| `docs/adr/0019-library-and-sync.md:39` | `ADR 0005` | +| `docs/adr/0020-downloads-and-permissions.md:18` | `ADR 0004` | +| `docs/adr/0022-release-and-in-app-update.md:19` | `ADR 0004`、`0006` | +| `docs/adr/0026-milestones-and-cut-over.md:122` | `0001–0007`(切換 PR 刪除清單) | + +**屬進行中任務(`09-26-fmp-rewrite`,非 archive)** + +| 檔案:行 | 引用 | +|---|---| +| `.trellis/tasks/09-26-fmp-rewrite/milestones.md:120` | `ADR 0001–0007`(切換 PR 刪除) | +| `.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md:255` | 舊 `ADR 0001–0007` 於切換 PR 刪除 | + +--- + +## d. `CONTEXT.md` + +`CONTEXT.md` 共 53 行+檔尾換行。整份英文(Han 字元 0 行)。`:3-5` 定位:cross-platform music player,從 Bilibili、YouTube、Netease 解析;記錄 source auth 與 media handoff 的專案語彙。 + +### d.1 五個術語(`:9-40`) + +| # | 術語(行) | 定義摘要 | +|---|---|---| +| 1 | **Source Auth Context**(`:9-13`) | 決定某個 source operation 可以用哪些 source credentials 的 policy 概念;與 account login、credential storage 不同。_Avoid_: auth helper、header utility、account service | +| 2 | **Media Handoff**(`:15-20`) | 從 resolved stream URL 到 audio/download backend 的轉移,含 redirect 檢查、per-hop media headers、續傳的 range headers、Source Auth Context 憑證收斂成 Media Request Credentials。_Avoid_: playback URL helper、download header helper | +| 3 | **Stream Resolution Auth**(`:22-26`) | 向 source adapter 解析/刷新 stream URL 時用的憑證;比 media request credentials 寬(可能含不得送到 media/CDN 的 B 站/YouTube auth)。_Avoid_: media auth、playback headers | +| 4 | **Auth For Play**(`:28-32`) | 使用者設定,閘門範圍是 stream resolution、playback handoff、download、track detail、auth-aware metadata/detail service paths;**不含** playlist import、playlist refresh、search。_Avoid_: import auth、search auth | +| 5 | **Media Request Credentials**(`:34-40`) | 允許出現在實際 audio byte request 的憑證;現行 policy 下是**空集合**:`SourceHttpPolicy.mediaHeaders(String sourceType)`(`lib/data/sources/source_http_policy.dart`)只收 source id,故沒有 cookie/token 能到 media host;舊的 Netease media allowlist 已於 `c09aec10` 移除。_Avoid_: stream auth、source auth | + +`:42-53` 一段 Example Dialogue(Developer/Reviewer 對話,示範三個術語的用法)。 + +### d.2 原則是否已在 ADR 0012(或其他新 ADR)出現 + +`docs/adr/0012-network-layer-and-accounts.md:16` 明文:「`CONTEXT.md` 記錄的原則經審計驗證仍成立,併入本 ADR:**憑證只用在向音源解析串流與 API 請求,實際抓取音訊位元組的請求一律不帶憑證**」。 + +| 原則(CONTEXT.md 出處) | ADR 0012 的對應句 | 是否已涵蓋 | +|---|---|---| +| 憑證只用在解析串流與 API 請求;位元組請求不帶憑證(全份原則,`:9-40`) | `0012:16`(併入聲明);`0012:30-31`「另有一個**媒體 client** 專抓音訊位元組,只加媒體 headers(Referer、UA),不掛認證攔截器與 cookie 管理」 | 是 | +| Source Auth Context=哪個 operation 用哪些憑證(`:9-13`) | `0012:32-36`「每個請求在音源插件的定義處宣告 `AuthRequirement`…認證攔截器只依此標記注入」——概念沿用,**術語名換成 `AuthRequirement`** | 是(概念) | +| Stream Resolution Auth(`:22-26`) | `0012:34` `userPreference` 列舉含「串流解析」;`0012:33` `required` 含讀收藏夾/私人歌單 | 是 | +| Auth For Play 的閘門範圍(`:28-32`) | `0012:49`「**「以登入身分瀏覽與播放」**:每個音源一個開關(每音源設定表,ADR 0011),控制所有 `userPreference` 請求,三個音源語意一致」;`0012:50-51` 預設由音源宣告、legacy import 以舊開關值作使用者設定 | 是 | +| Media Request Credentials 為空集合(`:34-40`) | `0012:30`(媒體 client 不掛認證)+`0012:70`(契約測試:媒體請求不含 Cookie/Authorization) | 是 | +| Media Handoff 的 **redirect 檢查、per-hop headers、續傳 range headers**(`:15-20`) | 0012 無「redirect」或「range」字樣(`grep -nE "redirect|轉址|Range|range" docs/adr/0012-*.md` 零命中)。下載端的續傳在 `docs/adr/0020-...md:12`(續傳只送 `Range`、不驗證)與 `:76`(RFC 9110 的 `If-Range`/強 ETag 續傳語意) | **部分/未涵蓋** | + +`design.md:62` 指定:這些原則「併進第 12 項的 ADR 與 spec」,術語依新設計命名;階段三刪 `CONTEXT.md` 並改掉 `.trellis/spec/` 的 7 處引用。對應的 spec 是 `.trellis/spec/services/download-and-auth.md`(`:3`、`:38` 目前指向 `CONTEXT.md`)。 + +### d.3 所有 `CONTEXT.md` 引用(`git grep -n "CONTEXT\.md"`,排除 archive) + +**舊專案/文件(階段三要改)** + +- `.trellis/spec/data/index.md:9` +- `.trellis/spec/data/sources.md:81` +- `.trellis/spec/guides/cross-layer-thinking-guide.md:51` +- `.trellis/spec/services/download-and-auth.md:3` +- `.trellis/spec/services/download-and-auth.md:38` +- `.trellis/spec/services/index.md:8` +- `.trellis/spec/services/index.md:24` +- `AGENTS.md:13`(「Agent skills」段的 Domain docs bullet) +- `.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md:23,113,209,258` +- `.trellis/tasks/09-26-fmp-rewrite/prd.md:13,18,86,88,92,190` +- `.trellis/tasks/09-28-phase3-docs-cleanup/prd.md:5`(英文描述行) +- `.trellis/tasks/09-28-phase3-docs-cleanup/task.json:5`(英文描述行) + +**新設計/已刪除對象本身** + +- `docs/adr/0012-network-layer-and-accounts.md:16`(併入聲明,**保留**) +- `docs/agents/domain.md:5,9,19,30,39,52`(檔案本身要刪) +- `CONTEXT.md`(檔案本身要刪) + +--- + +## e. design-docs §6 各衝突的現況 + +(`design.md:68-79` 列出六項;本節逐項對照現況。) + +### e.1 AGENTS.md 的 Trellis 自動區塊提到不存在的 `.codex/`、被 gitignore 的 `.agents/` + +- `AGENTS.md:114` `<!-- TRELLIS:START -->`、`:134` `<!-- TRELLIS:END -->` 圍住的區塊;`:128-130`: + - 「If you're using Codex or another agent-capable tool, additional project-scoped helpers may live in:」 + - `:129` `.agents/skills/` — reusable Trellis skills + - `:130` `.codex/agents/` — optional custom subagents +- `.codex/`:**不存在**(`ls -la .codex` → No such file or directory)。 +- `.agents/`:**存在**(本機):`.agents/skills/verify-on-device/`,內含 `SKILL.md`(22166 bytes)與 `scripts/`(`ax_flatten.py`、`smtc_probe.ps1`)。 +- `.agents/` 被 gitignore:`.gitignore:95` `/.agents/`(同在「Local agent/tool state」段,`:93` 另有 `/.codex/`、`:92` `/.trellis/workspace/`)。另有 `.trellis/.gitignore:14` `.agents/`(指 `.trellis/` 底下的 agent runtime 檔,不是根目錄那份)。 +- `.agents/skills/verify-on-device/` 是過期副本(`design.md:73`):與 `.claude/skills/verify-on-device/` 不同,詳見 § g.4。 + +### e.2 check 子代理三份定義 + +| 檔案 | 角色 | 客製? | +|---|---|---| +| `.claude/agents/trellis-check.md`(122 行) | Claude Code subagent 定義(frontmatter `name: trellis-check`,`tools: Read, Write, Edit, Bash, Glob, Grep`,`:1-6`)。`:11-17` 遞迴守衛;`:19-24` 依 `<!-- trellis-hook-injected -->` 決定要不要自己載入 task artifacts;`:80-90` Step 4 Run Verification **指向 AGENTS.md § Verification**(`:86`)並在 `:90` 說 on-device 它跑不了、要回報主 session | **已客製**(見 § f.3) | +| `.claude/skills/trellis-check/SKILL.md`(111 行) | Claude Code Skill(frontmatter `name: trellis-check`,`:1-4`)。通用 6 步(Step 1 Identify → Step 6 Report and Fix);`:28` 用 `.trellis/scripts/get_context.py --mode packages`;`:34` 讀 `.trellis/spec/<package>/<layer>/index.md`;**全檔沒有提到 AGENTS.md § Verification、也沒有 on-device 步驟** | 未客製(hash 相符,見 § f.3) | +| `.trellis/agents/check.md`(70 行) | Trellis channel runtime 的 agent 定義(frontmatter `name: check`、`provider: claude`、`labels: [trellis, check]`,`:1-7`)。`:11` 說明它由 `trellis channel spawn --agent check` 產生;`:32-38` 明列禁止 `git commit`/`push`/`merge`;`report format` 是 typecheck/lint | 未客製(hash 相符) | + +**Claude Code 實際用哪一份**:`.trellis/workflow.md:237` 寫「`trellis-check` exists as both; **prefer the Agent form when verifying after code changes**」——Agent form 即 `.claude/agents/trellis-check.md`。`:238` 的流程 `trellis-implement` → `trellis-check` → `trellis-update-spec` 也用 agent 名。workflow.md 全檔(`grep -n "\.trellis/agents"`)**沒有**引用 `.trellis/agents/`。第三份只在 Trellis channel runtime 被用到,本 repo 沒有 channel 設定(`.trellis/config.yaml:103-109` 只有註解掉的範例)。 + +### e.3 Trellis 文件描述 journal commit,但設定已關閉 + +- 設定:`.trellis/config.yaml:34` `session_auto_commit: false`。`:21-33` 的說明:「true (default): scripts auto-stage and auto-commit journal / task changes after add_session.py / task.py archive runs」「**false: scripts do not touch git**」。`:33` 還有一行 FMP 客製註解:「FMP: journals live in the gitignored `.trellis/workspace/` (public repo).」這是本地客製(見 § f.3)。 +- 敘述:`.claude/commands/trellis/finish-work.md:51`「Each archive produces a `chore(task): archive ...` commit **via the script's auto-commit**」;`:64`「This produces a `chore: record journal` commit」;`:66` 排出 git log 順序 `<work commits>` → `chore(task): archive` → `chore: record journal`。`.trellis/workflow.md:604`「produce work commits FIRST, then bookkeeping (archive + journal) commits land after」、`:647`「three-stage three-commit flow (work commits → archive commit → journal commit)」。 +- `AGENTS.md:107-112` 已把「journals stay local」寫成客製。→ 敘述與設定不一致,但三份敘述檔(`.claude/commands/trellis/finish-work.md`、`.claude/commands/trellis/continue.md`、`.trellis/workflow.md`)都在 `.template-hashes.json` 內(`trellis update` 的目標)。 +- `.trellis/workspace/` 確實被 gitignore:`.gitignore:92`。 + +### e.4 AGENTS.md 的「等待慣例」閘門範圍比實際寬 + +- `AGENTS.md:93-96`(Boundaries 最後一條):「**Test waits** — `pumpUntil` for a condition false on entry, `drainEventQueue` to assert something did *not* happen (`test/support/pump_until.dart`); a fixed pump count is flaky in both directions (#43, #55) — `test/support/wait_convention_static_rule_test.dart`。」——三個斷言綁在同一支測試名稱後面。 +- 實際閘門:`test/support/wait_convention_static_rule_test.dart`(99 行)**只**掃 `test/` 下有沒有檔案直接呼叫 `pumpEventQueue`: + - `:11-15` allowlist 只有 `test/support/pump_until.dart`、`test/support/pump_until_test.dart`、本檔。 + - `:21-30` 用 `RegExp(r'\bpumpEventQueue\b')` 掃(`stripDartComments` 後),可抓到空格與 tear-off。 + - `:34-57` 斷言 offenders 為空,且 `:48` `expect(scanned, greaterThan(200))` 防止路徑寫錯時空過。 + - `:59-67` 另一個 test 檢查 allowlist 每個檔案仍存在。 +- **它不檢查**「`pumpUntil` 的條件必須在進入時為 false」、也**不檢查**「`drainEventQueue` 用在否定斷言」。後兩者是 `test/support/pump_until.dart` 的 dartdoc 要求(`:19-20`「[condition] 必須是『進入時還不成立』的東西」),沒有閘門。 +- `drainEventQueue` 有大量實際使用(`grep -rn drainEventQueue test/` 命中 20+ 處,如 `test/providers/account_status_check_test.dart:97`、`test/services/audio/audio_controller_handoff_and_errors_test.dart:173` 等)。 + +### e.5 `.trellis/workflow.md` 3.4「不 push」與使用者全域「自己的 repo 直接 push」 + +`design.md:77` 已判定:層級不同,repo 內不衝突,保留 Trellis 原文,不在 repo 內處理。現況:`.trellis/workflow.md:642,648`(3.4 步驟 6、Rules)都寫「Never push to remote in this step」。 + +### e.6 `trellis update` 覆寫風險 + +`design.md:79`:`.trellis/`、`.claude/` 裡由 Trellis 產生的檔案,改動前先確認 `trellis update` 會不會覆蓋;AGENTS.md「Trellis」段已記錄要保留的客製。實測結果見 § f.3。 + +--- + +## f. Trellis 管理的檔案 + +### f.1 管理機制 + +- **雜湊清單**:`.trellis/.template-hashes.json`(v2 格式,`"__version": 2`),`hashes` 物件列出 **84 個**受管檔案(`.claude/agents/*`、`.claude/commands/trellis/*`、`.claude/skills/*`、`.claude/hooks/*`、`.claude/settings.json`、`.trellis/agents/*`、`.trellis/scripts/*`、`.trellis/config.yaml`、`.trellis/workflow.md`)。完整清單可由該檔取得。 +- **版本**:`.trellis/.version` = `0.6.17`。 +- **標記式管理**:`AGENTS.md:114-134` 的 `<!-- TRELLIS:START -->` / `<!-- TRELLIS:END -->` 區塊,`:132` 自述「Managed by Trellis. Edits outside this block are preserved; edits inside may be overwritten by a future `trellis update`」。`git grep -n "Managed by Trellis"` 全 repo 只有 `AGENTS.md:132`;`TRELLIS:START/END` 也只有 `AGENTS.md:114,134`。 +- **AGENTS.md 不在雜湊清單內**(84 筆裡沒有 `AGENTS.md`),所以它的非區塊內容不受 `trellis update` 影響,區塊內容會。 + +### f.2 AGENTS.md「Trellis」段要求保留的客製 + +`AGENTS.md:102-112`(在 Trellis 區塊**外**,所以是我的客製、不會被覆寫): + +- `:104-106` Rules vs patterns:binding rules 留 `AGENTS.md`;`.trellis/spec/<layer>/` 寫該層怎麼寫並連回 AGENTS.md;一條新規則只放其中一邊。 +- `:107-112` `trellis update` 時要保留: + 1. 本機的 `.claude/agents/trellis-check.md` 與 `trellis-implement.md`(它們的 Verify 步驟跑 § Verification)。 + 2. 日誌留本機(`.trellis/workspace/` 被 gitignore、`session_auto_commit: false`、`orca.yaml` 讓 Orca worktree 共用主 checkout 的那一份)。 + 3. 「若 update 又把 journal 的 `merge=union` 行加回 `.gitattributes`,就把它拿掉。」 +- 對照現況:`.gitattributes`(17 行)**沒有** `merge=union` 行 → 第 3 點目前是空的,沒有殘留。 + +### f.3 實測:`trellis update` 會覆寫哪些 + +以 `.template-hashes.json` 的雜湊對現況比對(sha256,比對前把 CRLF 正規化成 LF;全部 84 檔都存在): + +- **81 檔與模板雜湊相符** → `trellis update` 可安全覆寫,內容與模板一致,覆寫無損。 +- **3 檔不符(本機客製,`trellis update` 可能覆蓋或報衝突):** + 1. `.claude/agents/trellis-check.md` —— 客製在 `:80-90`(Step 4 改指向 AGENTS.md § Verification、`:90` 加上 on-device 由主 session 跑的要求)。`AGENTS.md:107-108` 明確要求保留。 + 2. `.claude/agents/trellis-implement.md` —— 同組客製。`AGENTS.md:107-108` 明確要求保留。 + 3. `.trellis/config.yaml` —— 客製在 `:33`(FMP 註解)與 `:34`(`session_auto_commit: false`)。`design.md:75` 指出的 journal commit 衝突根源就在這裡。 + +→ 階段三若動 `.claude/`、`.trellis/` 下任何在清單內的檔案(含 `.claude/skills/trellis-check/SKILL.md`、`.claude/commands/trellis/finish-work.md`、`.trellis/workflow.md`),改動下次 `trellis update` 會被覆蓋。只有這 3 檔的客製在機制上「留得住」(因為它們本就被視為已客製)。 + +### f.4 其他 Trellis 檔案 + +- `.trellis/.developer`(55 bytes,本機身分,`.trellis/.gitignore:2` 排除)。 +- `.trellis/.gitignore`(32 行):`.developer`、`.current-task`、`.runtime/`、`.ralph-state.json`、`.agents/`、`.agent-log`、`.session-id`、`.plan-log`、`*.tmp`、`.backup-*`、`*.new`、`__pycache__` 等。 +- `.trellis/spec/`:6 個子目錄(`data`、`guides`、`services`、`shared`、`testing`、`ui`),**沒有**頂層 `index.md`;共 20 檔(見 § h)。 +- `.trellis/config.yaml:57-78` 有 `packages:` 區塊(monorepo 用),目前**整段註解掉**;`:62-75` 是範例(`path: packages/frontend` 等)。這與「`app/` 的 spec 放哪」相關(見 open-questions)。 + +--- + +## g. `verify-on-device` skill + +### g.1 涵蓋的平台與步驟 + +`.claude/skills/verify-on-device/SKILL.md`(149 行,6206 bytes): + +- frontmatter `:2-10`:`name: verify-on-device`;description 說「Run FMP on the **Android emulator or the Windows desktop build**…root AGENTS.md requires an on-device check」。 +- `:15-18`:「Closed loop…**bring up → run → observe → act → hot reload → tear down.** The **Android emulator is the required platform**; add Windows for Windows-specific work. If the loop cannot be completed, report the blocker.」 +- `:20-21` 驗證環境:Windows 11 host、Orca CLI 1.4.187、AVD `Medium_Phone`(Android SDK 37、x86_64)、Flutter 3.47.x。 +- `:23-27` 三份 reference 的分工: + - `references/android.md`(83 行):Android tap/輸入/時序/冷啟動不如預期時讀。 + - `references/windows.md`(122 行):驅動或量測 Windows build 時讀。 + - `references/runtime-state.md`(48 行):用狀態而非像素、UI 到不了的前置條件、離線可播媒體時讀。 +- 步驟骨架:`1. Bring up the emulator`(`:41-58`,`emulator.exe -list-avds`、detached 啟動、`adb wait-for-device` 等 boot)、`2. Run the app`(`:60` 起)…到 `8. Tear down`。 +- 平台工具差異:Android 用 `adb`/`dumpsys media_session`(`references/runtime-state.md:16-19`);Windows 用 PowerShell 與 `scripts/msaa_tree.ps1`(`.claude/skills/verify-on-device/scripts/` 內有 `ax_flatten.py`、`msaa_tree.ps1`、`smtc_probe.ps1`)。 + +### g.2 是否會打真實 API + +**會。** 這個 skill 跑真實 App 對真實來源: + +- `references/runtime-state.md:35-36`:「Playback verification needs playing media, and **all three sources can be unavailable at once on a dev machine (Bilibili `playurl` answering HTTP 412, YouTube demanding sign-in, nothing downloaded)**」。 +- `references/runtime-state.md:27-29`(在 `Setting up a precondition` 段)教用 `ext.isar.editProperty` 直接改資料庫狀態以繞過 UI 到不了的入口。 +- `references/android.md:62` 教「Turn the network off with `adb shell svc wifi disable && adb shell svc data disable`…the cheapest way to reach real error paths: search, radio playback, **login and remote playlist refresh** all fail immediately with `Failed host lookup`」——即正常情況下這些路徑是打真 API 的。 +- 它與 ADR 0015 的「預設零聯網」**不衝突但也不套用**:ADR 0015 的聯網閘門只管 `flutter test`(`docs/adr/0015-...md:55-56`:`dart_test.yaml` 對 `live` tag 設 `skip`、`flutter_test_config.dart` 用 `HttpOverrides.global` 讓真實 `HttpClient` 失敗);skill 是跑真實 `flutter run` 的 App,不在那兩個閘門內。 + +### g.3 AGENTS.md 的驗證表 + +- `AGENTS.md:16` `## Verification`;表 `:18-25`: + + | Change area | Minimum | + |---|---| + | Audio playback/controller/queue | `flutter test test/services/audio`(串流解析改動時加 `test/data/sources`) | + | Source adapters / HTTP policy | `flutter test test/data/sources test/services/account test/services/radio` | + | Download pipeline | `flutter test test/services/download test/providers/download` | + | Isar models / migrations | `dart run build_runner build` + `flutter test test/providers/database_migration_test.dart` | + | UI widgets/pages | `test/ui` 的目標測試 + `flutter analyze` + on-device | + | i18n JSON | `dart run slang` + `flutter analyze` | + +- `:27-35` 三條補充:codegen(`dart run build_runner build`/`dart run slang`,Orca worktree 在 `orca.yaml` setup 跑);full run 是 `flutter test --exclude-tags live`;`flutter analyze` 與 `dart format lib test tool` CI 閘門涵蓋 `tool/`。 +- `:37-42` **On-device verification is mandatory for user-visible changes** —— 用 Android emulator(Windows 專屬改動才加 Windows),要報觀察到的 element/log 行/screenshot;emulator 起不來或到不了就**具名回報 blocker**,「tests alone do not count」。 +- `.claude/agents/trellis-check.md:86` 把 § Verification 的表當作 Step 4 的依據;`:90` 說 on-device 它跑不了,要回報主 session。`AGENTS.md:107-108` 要求保留這個客製。 + +### g.4 `.agents/skills/verify-on-device/`(本機副本)是否不同 + +**不同,且差很多。** `diff` 結果: + +| | `.claude/skills/verify-on-device/` | `.agents/skills/verify-on-device/` | +|---|---|---| +| `SKILL.md` | 149 行/6206 bytes | **399 行/22166 bytes** | +| 結構 | 步驟 1–8、reference 拆成三檔 | 步驟 1–8 內嵌,**沒有 `references/` 目錄** | +| `scripts/` | `ax_flatten.py`、`msaa_tree.ps1`、`smtc_probe.ps1` | `ax_flatten.py`、`smtc_probe.ps1`(**缺 `msaa_tree.ps1`**) | +| 獨有內容 | `references/android.md`、`windows.md`、`runtime-state.md` 的整理版 | `SKILL.md` 尾端多一節「**Measured during the 2026-09-07 UI acceptance run**」(`adb shell am force-stop` 會讓 `flutter run` 靜默失效、toast 斷言要靠 burst screenshot、`adb shell svc wifi disable` 等實測筆記) | +| 時間戳 | `SKILL.md` Sep 25 14:58 | `SKILL.md` Sep 10 19:14 | + +→ 兩份互有對方沒有的東西(`.claude` 有 `references/` 與 `msaa_tree.ps1`;`.agents` 有實測筆記),不是單純的舊版。`design.md:73` 稱它為「過期副本」,`implement.md:21`(§B.5)要「本機刪除 `.agents/`」。 + +--- + +## h. 語言現況(design-docs R7:所有文檔繁中;README 維持英/繁雙語) + +統計法:以行計,含 CJK 漢字的行 ÷ 總行數。 + +**英文(R7 要求改成繁中)** + +| 檔案 | 行數 | 含漢字行 | 比例 | +|---|---|---|---| +| `AGENTS.md` | 134 | 1 | 1% | +| `.trellis/spec/data/index.md` | 33 | 0 | 0% | +| `.trellis/spec/data/persistence.md` | 140 | 1 | 1% | +| `.trellis/spec/data/sources.md` | 152 | 0 | 0% | +| `.trellis/spec/guides/code-reuse-thinking-guide.md` | 36 | 0 | 0% | +| `.trellis/spec/guides/cross-layer-thinking-guide.md` | 54 | 0 | 0% | +| `.trellis/spec/guides/index.md` | 20 | 0 | 0% | +| `.trellis/spec/services/audio.md` | 88 | 0 | 0% | +| `.trellis/spec/services/download-and-auth.md` | 75 | 0 | 0% | +| `.trellis/spec/services/index.md` | 33 | 0 | 0% | +| `.trellis/spec/services/service-conventions.md` | 150 | 0 | 0% | +| `.trellis/spec/shared/code-style.md` | 66 | 0 | 0% | +| `.trellis/spec/shared/errors-and-logging.md` | 69 | 0 | 0% | +| `.trellis/spec/shared/index.md` | 21 | 0 | 0% | +| `.trellis/spec/testing/index.md` | 25 | 0 | 0% | +| `.trellis/spec/testing/static-rules.md` | 56 | 0 | 0% | +| `.trellis/spec/testing/test-conventions.md` | 99 | 0 | 0% | +| `.trellis/spec/ui/i18n-and-routing.md` | 39 | 0 | 0% | +| `.trellis/spec/ui/index.md` | 30 | 1 | 3% | +| `.trellis/spec/ui/riverpod.md` | 143 | 0 | 0% | +| `.trellis/spec/ui/widgets.md` | 115 | 1 | 1% | +| `CONTEXT.md` | 53 | 0 | 0% | + +`.trellis/spec/` 合計 **6 層 20 檔 1444 行**,實質全英文(只有 3 檔各有 1 行漢字,可能是程式碼註解)。與 `design.md:14` 的敘述一致。 + +**中文(R7 已滿足;`docs/` 本來就是繁中)** + +| 檔案 | 行數 | 含漢字行 | 比例 | +|---|---|---|---| +| `docs/README.md` | 25 | 19 | 76% | +| `docs/build-and-release.md` | 386 | 180 | 47% | +| `docs/building.md` | 207 | 76 | 37% | +| `docs/development.md` | 165 | 95 | 58% | +| `docs/troubleshooting.md` | 112 | 59 | 53% | +| `docs/adr/0001` | 138 | 83 | 60% | +| `docs/adr/0002` | 77 | 52 | 68% | +| `docs/adr/0003` | 104 | 81 | 78% | +| `docs/adr/0004` | 77 | 59 | 77% | +| `docs/adr/0005` | 101 | 69 | 68% | +| `docs/adr/0006` | 101 | 77 | 76% | +| `docs/adr/0007` | 54 | 35 | 65% | +| `docs/adr/0008`–`0026`(19 檔) | 75–211 | — | 72%–90% | +| `docs/adr/template.md` | 41 | 23 | 56% | + +低比例者(`build-and-release.md` 47%、`building.md` 37%)是大量指令與程式碼區塊,本文仍為中文。 + +**尚未存在**:`app/`(`ls -d app` → No such file or directory)。ADR 0008 定案要在 `app/` 另建專案,但它還沒開始;`app/AGENTS.md`、`app/` 的 spec 都還不存在。 + +**R7 的落地範圍**:只需把 `AGENTS.md` 與 `.trellis/spec/` 20 檔翻成繁中;`docs/` 與 ADR 已是繁中。`design.md:18` 另說「README 例外,維持英/繁雙語」;`docs/README.md:12` 目前寫 spec 是「(英文,給 agent 讀)」,翻譯後要改。 + +--- + +## 附:本次使用的指令 + +```bash +git grep -n -E "docs/agents|CONTEXT\.md|Agent skills|wayfinder|grill-with-docs" -- . ':!.trellis/tasks/archive' ':!docs/audit' +git grep -n -E "adr/000[1-7]|ADR 000[1-7]" -- . ':!.trellis/tasks/archive' ':!docs/audit' +git grep -n "只適用舊專案" -- . ':!.trellis/tasks/archive' +git grep -n "CONTEXT\.md" -- . ':!.trellis/tasks/archive' +git grep -n "Managed by Trellis" -- . +git grep -n "TRELLIS:START\|TRELLIS:END" -- . +git grep -n -E "needs-triage|needs-info|ready-for-agent|ready-for-human|wontfix|wayfinder" -- . ':!.trellis/tasks/archive' ':!docs/agents' +grep -rn -E "CONTEXT\.md|docs/agents|AGENTS\.md" .claude/hooks/ +# 雜湊比對(CRLF 正規化後 sha256):.trellis/.template-hashes.json 的 84 筆 vs 現況 +``` diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md b/.trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md new file mode 100644 index 000000000..374f7103e --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md @@ -0,0 +1,194 @@ +# 階段三待決事項(open-questions) + +只列 **repo 自己回答不了、必須由擁有者決定** 的事。每項先列相關事實(附 file:line),不給建議。 + +--- + +## 1. 根目錄 `AGENTS.md` 與 `.trellis/spec/` 的翻譯時機 + +**決定點**:階段三就翻成繁中,還是留到最後里程碑的切換 PR。 + +事實: + +- 兩者描述的是**凍結中的舊專案**:`AGENTS.md` 開頭即說 FMP 是「Flutter music player for Android and Windows that plays from Bilibili, YouTube and NetEase」,即舊版;`docs/adr/0008-rewrite-as-new-app-in-same-repo.md:45-46` 說舊專案留根目錄、凍結,`app/` 有自己的 `AGENTS.md`(agents.md 慣例:讀離它最近的那一份)。→ 根目錄 `AGENTS.md` 與 `.trellis/spec/` 的 20 檔在切換 PR 會隨舊專案一起消失。 +- 體量:`AGENTS.md` 134 行(含漢字行 1);`.trellis/spec/` 6 層 20 檔共 1444 行(含漢字行共 3)。`docs/` 與 `docs/adr/*` 已是繁中(`docs/README.md` 76%、`docs/build-and-release.md` 47%、ADR 平均 65–90%)。→ R7 未落地的部分**只有這兩塊**。 +- R7 的原文:`prd.md:28`「所有文檔繁中(含 ADR、`docs/`)」;`design.md:18` 另說 README 例外、維持英/繁雙語。 +- 七處 `CONTEXT.md` 引用(`.trellis/spec/data/index.md:9`、`data/sources.md:81`、`guides/cross-layer-thinking-guide.md:51`、`services/download-and-auth.md:3,38`、`services/index.md:8,24`)無論如何都要改(`design.md:62`、`implement.md:20`),改句子時會動到檔內其他行。 +- `.trellis/spec/` 的規則本身沒有閘門測試守著(`AGENTS.md:75-76` 只對 `test/**/static_rules/` 的規則宣告閘門)。翻譯不算行為變更,沒有測試會紅。 +- 翻譯後 `docs/README.md:12` 的「(英文,給 agent 讀)」需要同步改。 + +--- + +## 2. `app/` 的 spec 放哪 + +**決定點**:`.trellis/spec/<layer>/` 沿用單一層集,還是啟用 Trellis 的 monorepo `packages:` 分層。 + +事實: + +- `.trellis/config.yaml:57-78` 有一段 **`packages:` 區塊,目前整段被註解掉**;`:62-75` 是 Trellis 的範例(`- path: packages/frontend`、`layers: [...]` 形式)。→ 這個機制存在但目前未啟用。 +- `.trellis/spec/` 現在是單層集:`data`、`guides`、`services`、`shared`、`testing`、`ui` 六個子目錄,**沒有頂層 `index.md`**(`.trellis/config.yaml:144-147` 的 context-injection caps 也沒區分 package)。 +- 目前的 spec **全部描述舊專案**:`.trellis/spec/data/persistence.md:3` 引 ADR 0007、0002;`services/audio.md:3` 引 ADR 0003;`services/download-and-auth.md:3` 引 ADR 0004;`data/index.md:22-25` 引 ADR 0001、0005、0002。→ 這些 ADR 都在切換 PR 刪除,這些 spec 檔也隨舊專案結束。 +- `app/` **還不存在**(`ls -d app` → No such file or directory)。`docs/adr/0008-...md:46` 說 `app/` 會有自己的 `AGENTS.md`,但沒說 spec 放哪。 +- `docs/adr/0015-...md:96` 要求「`AGENTS.md`(`app/`)列出的每條靜態規則都寫出對應規則名;沒有規則守的不寫進去」→ `app/` 的 spec 內容要被 `app/AGENTS.md` 引用。 +- Trellis 的 spec 載入路徑寫死 `.trellis/spec/<package>/<layer>/index.md`(`.claude/skills/trellis-check/SKILL.md:34`、`.trellis/workflow.md`);子代理的 context 由 `python ./.trellis/scripts/get_context.py --mode packages` 決定(`.claude/skills/trellis-check/SKILL.md:28`)。 +- `AGENTS.md:104-106`(Trellis 段,在 managed 區塊外)已把規則分工定成「binding rules 在 `AGENTS.md`、`.trellis/spec/<layer>/` 寫該層怎麼寫」——這是舊專案的形狀。 + +--- + +## 3. `verify-on-device` 的平台延伸與真實 API 曝險 + +**決定點**:Linux VM、macOS runner、iOS 模擬器各自要驗什麼、用什麼指令;以及如何降低打真實 API 的比例。 + +事實: + +- 現況 skill 只覆蓋 **Android(必要)+ Windows(Windows 專屬改動才加)**:`.claude/skills/verify-on-device/SKILL.md:15-18`。`:20-21` 的驗證環境寫死 Windows 11 host、AVD `Medium_Phone`、Flutter 3.47.x。reference 只有 `android.md`、`windows.md`、`runtime-state.md`,`scripts/` 只有 `ax_flatten.py`、`msaa_tree.ps1`、`smtc_probe.ps1`。 +- AGENTS.md 的規則把 on-device 綁在 Android emulator:`AGENTS.md:37-42`「Run the `verify-on-device` skill on the Android emulator (add Windows only for Windows-specific work)…When the emulator cannot come up or the change cannot be reached, report that blocker by name」。 +- skill **會打真實來源**:`.claude/skills/verify-on-device/references/runtime-state.md:35-36`「all three sources can be unavailable at once on a dev machine (Bilibili `playurl` answering HTTP 412, YouTube demanding sign-in, nothing downloaded)」;`references/android.md:62` 教用 `adb shell svc wifi disable` 製造 `Failed host lookup` 以到達真正的錯誤路徑——反向說明正常路徑是打真 API 的。 +- ADR 0015 的零聯網機制**不含**這個 skill:`docs/adr/0015-...md:55-56` 的 `dart_test.yaml` `live` skip preset 與 `HttpOverrides.global` 只管 `flutter test`;skill 跑的是真實 `flutter run`。 +- ADR 0015 另有可用的重播槓桿:`:59-66` fixture 錄製/重播在 dio `HttpClientAdapter`,`:58`「檢查案例一份四用」含 Debug 頁健康檢查(真實連線,App 內);`:65-66` 開發者模式可「每插件切換真實/錄製/重播」。 +- 平台任務的排程已定:`docs/adr/0026-milestones-and-cut-over.md:84-91`——Linux 在 M1 之後開,驗收在 VMware Workstation Pro 的 Ubuntu LTS VM,**X11 與 Wayland 各一次**,日常開發用 WSL2,之後每個里程碑在 VM 跑一次冒煙測試;macOS/iOS 在 Mac 到貨後開,到貨前只靠 GitHub macOS runner 編譯與 iOS 模擬器測試(ADR 0009)。 +- `docs/adr/0026-...md:90`:iOS 要不要實機、要不要付費帳號,**留給該任務決定**。 +- `AGENTS.md:23`(Verification 表):UI 變更的最小驗證是 `test/ui` 目標測試+`flutter analyze`+on-device。Linux/macOS/iOS 的 UI 變更算不算「user-visible change」需不需要各自 on-device,表上沒寫。 +- 本機另有一份 **`.agents/skills/verify-on-device/SKILL.md`(399 行/22166 bytes)**,與 `.claude/` 版不同(見 § 4 與 current-state § g.4)。 + +--- + +## 4. 本機 `.agents/` 怎麼處理 + +**決定點**:`.agents/` 刪掉、保留、還是把它的內容併回 `.claude/skills/verify-on-device/`。 + +事實: + +- `.agents/` **存在但被 gitignore**:`.gitignore:95` `/.agents/`(同在 local agent/tool state 段,`:93` `/.codex/`、`:92` `/.trellis/workspace/`)。另 `.trellis/.gitignore:14` 也有 `.agents/`(指 `.trellis/` 底下,不同路徑)。 +- 內容是 `.agents/skills/verify-on-device/`:`SKILL.md` 399 行/22166 bytes(Sep 10 19:14)、`scripts/` 只有 `ax_flatten.py`、`smtc_probe.ps1`(**缺** `msaa_tree.ps1`)、**沒有** `references/`。 +- `.claude/skills/verify-on-device/`:`SKILL.md` 149 行/6206 bytes(Sep 25 14:58)+ `references/{android,windows,runtime-state}.md` + `scripts/` 三支。 +- 兩份**互有對方沒有的東西**:`.agents` 版 `SKILL.md` 尾端有「Measured during the 2026-09-07 UI acceptance run」實測筆記(`adb shell am force-stop` 會讓 `flutter run` 靜默失效、toast 斷言要靠 burst screenshot 等);`.claude` 版有拆出的 references 與 `msaa_tree.ps1`。 +- `design.md:73` 說它是「stale copy of the one in `.claude/skills/`」;`implement.md:21`(§B.5)說「also delete the local `.agents/`」。 +- `AGENTS.md:128-130`(Trellis managed 區塊內)仍宣告 `.agents/skills/` 是 "reusable Trellis skills"、`.codex/agents/` 是 "optional custom subagents";`.codex/` **不存在**。 +- `.claude/settings.json:72` `"enabledPlugins": {}`;`git grep` 查不到任何 `.agents/skills` 的讀取端(除了 `AGENTS.md:129`)。 + +--- + +## 5. `docs/agents/` 哪些慣例留下、哪些隨目錄刪除 + +**決定點**:parent prd 說「若『issue 用繁體中文撰寫』等慣例仍需要,搬一句到 `AGENTS.md`」——「等」字要涵蓋哪些?5 個 triage label 與 5 個 `wayfinder:*` label 要不要保留在 repo 內? + +事實: + +- **唯一被 repo 內其他檔案引用、且是 FMP 專屬的慣例**是 issue 語言規則:`docs/agents/issue-tracker.md:43-48`(標題/內文繁中、識別字與 label 英文),它**回指 `docs/README.md § 分工`**,而 `docs/README.md:21` 依 R7 要刪 → 搬移時那句話要改寫或移除引用。 +- 同族政策另散在兩處:`docs/agents/domain.md:49-53`(ADR 用繁中、`CONTEXT.md` 保留英文術語名)、`docs/README.md:21`(語系分工)。三處講同一件事。 +- **5 個 triage label 字串**(`docs/agents/triage-labels.md:5-11`:`needs-triage`、`needs-info`、`ready-for-agent`、`ready-for-human`、`wontfix`)在 repo 內**零消費者**:`git grep -n -E "needs-triage|needs-info|ready-for-agent|ready-for-human|wontfix"` 排除 archive 與 `docs/agents` 後無命中;`.github/` 只有 `dependabot.yml` 與 `workflows/`,**沒有** `ISSUE_TEMPLATE/`(且 `issue-tracker.md:18-21` 說這是刻意的)。 +- **5 個 wayfinder label**(`docs/agents/issue-tracker.md:52-59`)同樣零消費者。 +- `docs/agents/issue-tracker.md:9-14` 的 gh 操作慣例(create/view/list/comment/label/close)在 repo 內沒有第二份。 +- `docs/agents/domain.md` 整份繞著 `CONTEXT.md`(`:5,9,19,30,39,52`),而 `CONTEXT.md` 在階段三要刪;`:47` 的範例引用「ADR-0007 (event-sourced orders)」與本 repo 的 ADR 0007 無關,是模板殘留。 +- `docs/README.md:23` 說這三個檔是 `/setup-matt-pocock-skills` 的產出加 FMP 修改,重跑該 skill 會覆蓋;`.claude/settings.json:72` `enabledPlugins: {}`,那些 skill 來自使用者全域環境。 +- **無法從 repo 回答**:GitHub 上實際存在哪些 label(要連網查 `gh label list`),以及別人的 issue 目前有沒有在用這套 label。 + +--- + +## 6. 5 份舊 ADR 的「只適用舊專案」註記何時加 + +**決定點**:現在補,還是留到切換 PR。 + +事實: + +- 規則本身:`docs/adr/template.md:7`「被取代的舊 ADR 若仍描述凍結中的根目錄舊專案,改在舊檔開頭加註「只適用舊專案」,於切換 PR 隨舊專案刪除(ADR 0008)」。 +- 現況 **2/7 已加**:`docs/adr/0002-repository-boundary.md:3`、`docs/adr/0007-isar-stays-on-v3.md:3`(兩句都寫「本檔在切換 PR 隨舊專案刪除(ADR 0008)」)。 +- **5 份未加**:`0001-...md`、`0003-...md`、`0004-...md`、`0005-...md`、`0006-...md`(檔頭只有標題+狀態/日期/影響範圍)。 +- 加的成本很低(一行),但**這 5 份都在 `.trellis/spec/` 與舊專案程式碼裡被引用**(見 current-state § c.3),改檔頭不會動到引用。 +- 5 份都被新 ADR 明示延續或取代(0003→`0018:17`;0004→`0020:18`;0006→`0022:19`;0005→`0010:45`、`0019:39`;0001 無任何新 ADR 寫「取代 ADR 0001」)。 +- 切換 PR 的刪除清單已寫死:`docs/adr/0026-...md:122`、`.trellis/tasks/09-26-fmp-rewrite/milestones.md:120`、`phase2-plan.md:255`。 + +--- + +## 7. `AGENTS.md` 的「Test waits」宣稱要縮窄還是補閘門 + +**決定點**:改寫 `AGENTS.md:93-96` 的文字讓它只宣稱實際守得到的範圍,還是為 `pumpUntil` 條件/`drainEventQueue` 用法補上真閘門。 + +事實: + +- 宣告:`AGENTS.md:93-96` 一條 bullet 同時宣稱三件事——`pumpUntil` 的條件「false on entry」、`drainEventQueue` 用於否定斷言、固定 pump 次數不穩——並在句尾掛上測試名 `test/support/wait_convention_static_rule_test.dart`。 +- 實際閘門:`test/support/wait_convention_static_rule_test.dart`(99 行)**只**掃 `test/` 下有沒有非註解行直接呼叫 `pumpEventQueue`:`:21-30` 用 `RegExp(r'\bpumpEventQueue\b')`;`:11-15` allowlist 只有 `test/support/pump_until.dart`、`test/support/pump_until_test.dart`、本檔;`:48` `expect(scanned, greaterThan(200))` 防空過。 +- **沒有**任何測試檢查「`pumpUntil` 的條件在進入時為 false」,也**沒有**檢查 `drainEventQueue` 的用法。後兩者只是 `test/support/pump_until.dart` 的 dartdoc 要求(`:19-20`)。 +- `drainEventQueue` 有 20+ 實際使用點(例:`test/providers/account_status_check_test.dart:97`、`test/services/audio/audio_controller_handoff_and_errors_test.dart:173`、`test/services/audio/audio_controller_queue_test.dart:74`),但沒有規則描述「什麼時候該用它」。 +- 全域規則(`~/.claude/CLAUDE.md`)說「沒有閘門的規則靠運氣被遵守」「新加的靜態規則要在測試檔內做雙向變異驗證」;`AGENTS.md:75-76` 自己也說 static-rule tests 的例外清單「add an entry with a reason, delete it when it goes away」。 +- 這條文字**在 managed 區塊外**(`AGENTS.md:114` 的 `<!-- TRELLIS:START -->` 之前),所以改它不會被 `trellis update` 覆蓋。 + +--- + +## 8. 重複的 check 子代理要怎麼「修」 + +**決定點**:`design.md:74` 說「fix the duplicate check sub-agent」——三份定義要刪/合併哪一份,或在 `AGENTS.md` 補說明。 + +事實: + +- 三份並存,各有不同角色,**都在 `.trellis/.template-hashes.json` 的 84 筆受管清單內**,`trellis update` 會覆寫: + 1. `.claude/agents/trellis-check.md`(122 行)— Claude Code subagent;`:86` 指向 `AGENTS.md § Verification`,`:90` 說 on-device 它跑不了。**本機已客製**(雜湊不符)。 + 2. `.claude/skills/trellis-check/SKILL.md`(111 行)— Claude Code Skill;**通用版,不含 FMP 內容**(無 § Verification、無 on-device)。雜湊相符。 + 3. `.trellis/agents/check.md`(70 行)— Trellis channel runtime 定義(`:11` `trellis channel spawn --agent check`;`:34-38` 禁止 git commit/push/merge)。雜湊相符。 +- `AGENTS.md:107-108`(managed 區塊外)已明說要保留本機的 `.claude/agents/trellis-check.md` 與 `trellis-implement.md`(它們的 Verify 步驟跑 § Verification)→ 刪它會違反這條已寫下的客製。 +- `.trellis/workflow.md:237`「`trellis-check` exists as both; prefer the **Agent** form when verifying after code changes」→ 官方立場傾向 agent 版;`.trellis/workflow.md` 全檔沒有引用 `.trellis/agents/`。 +- 本 repo 沒有 channel 設定:`.trellis/config.yaml:103-109` 只有註解掉的範例。→ 第 3 份目前沒有啟動路徑。 +- `docs/audit/engineering.md:440,446` 記錄了審計當時讀到的 check-agent 與 `.trellis/agents/` 狀況(凍結快照,僅供參照)。 +- 任何對第 2、3 份的刪改都會被下次 `trellis update` 還原(只有第 1 份因已客製而「留得住」)。 + +--- + +## 9. journal/archive commit 的敘述與 `session_auto_commit: false` 怎麼對齊 + +**決定點**:改敘述檔(會被 `trellis update` 覆寫)、改設定、還是在 `AGENTS.md` 客製段加一段說明。 + +事實: + +- 設定:`.trellis/config.yaml:34` `session_auto_commit: false`;`:21-33` 的說明寫「false: scripts do not touch git」;`:33` 有一行 FMP 客製註解「FMP: journals live in the gitignored `.trellis/workspace/` (public repo)」。**`config.yaml` 本機已客製**(雜湊不符)。 +- 敘述(三個檔案都說會產生 commit): + - `.claude/commands/trellis/finish-work.md:51`「Each archive produces a `chore(task): archive ...` commit **via the script's auto-commit**」 + - `.claude/commands/trellis/finish-work.md:64`「This produces a `chore: record journal` commit」 + - `.claude/commands/trellis/finish-work.md:66` 排出 git log 順序 + - `.trellis/workflow.md:604`「work commits FIRST, then bookkeeping (archive + journal) commits land after」 + - `.trellis/workflow.md:647`「three-stage three-commit flow (work commits → archive commit → journal commit)」 +- 這三個檔**都在** `.trellis/.template-hashes.json` 內且目前雜湊相符 → `trellis update` 會覆寫任何改動。 +- `.trellis/config.yaml:12` `session_commit_message: "chore: record journal"`(訊息模板仍在,只是 `session_auto_commit: false` 讓它不自動跑)。 +- `.trellis/workspace/` 確實被 gitignore:`.gitignore:92`。實際的 journal 有寫入(`.trellis/workspace/1morr/journal-1.md`,75 行)。 +- `AGENTS.md:107-112`(managed 區塊外)已把「journals stay local…`session_auto_commit: false`」寫成要保留的客製,但沒說那三個敘述檔怎麼辦。 +- `design.md:77` 對另一條 workflow 衝突(3.4 不 push vs 全域直接 push)判定為「層級不同、repo 內不衝突、保留原文」;journal 這條沒有同樣的判定。 + +--- + +## 10. `docs/README.md:22` 那條 Trellis 接線敘述要不要同步 + +**決定點**:`docs/README.md:22` 現在描述 `.claude/skills/` 與 gitignore 追蹤範圍,但沒提「journal 留本機」「`.agents/`」「`AGENTS.md` 的 Trellis 段」——要不要補成與 `AGENTS.md:107-112` 一致。 + +事實: + +- `docs/README.md:22`「`.claude/skills/` 放 Claude Code skill;`.gitignore` 另外追蹤 Trellis 接線(`.claude/` 下的 `agents/`、`commands/`、`hooks/`、`settings.json`);`.claude/` 其餘與 `.trellis/workspace/` 是本機狀態。」 +- 實際 gitignore:`.gitignore:85-90`(`.claude/*` 加 negations 追蹤 `skills/`、`agents/`、`commands/`、`hooks/`、`settings.json`)、`:92` `/.trellis/workspace/`、`:93` `/.codex/`、`:95` `/.agents/`。→ `:22` 的敘述與 gitignore 一致,但漏了 `.agents/`、`.codex/` 與 journal 留本機的理由。 +- `AGENTS.md:107-112` 是這些客製的唯一書面出處;`docs/README.md:20`「同一條規則只寫在一個地方」→ 兩處是否算同一條規則需判斷。 +- `docs/README.md` 不在 `.trellis/.template-hashes.json` 內 → 改它不會被 `trellis update` 覆寫。 +- `docs/README.md` 本來就要因 R7 改(`:21` 刪、`:12` 改、`:15` 刪、`docs/audit/` 補列)。 + +--- + +## 11. `docs/README.md` 是否要新增 `docs/audit/` 一列 + +**決定點**:`implement.md:18` 說「`docs/audit/` 註明為凍結快照」——是加一列進地圖表,還是在別處寫一句。 + +事實: + +- 現況地圖表(`docs/README.md:5-15`)**沒有** `docs/audit/` 一列。 +- `docs/README.md:24`「審查記錄不進 `docs/`。一輪審計的結論寫進它所描述的檔案、開成 issue,或留在 git 歷史。」與 `docs/audit/` 的存在表面衝突;`design.md:66` 說凍結期保留這個例外,最後里程碑刪 `docs/audit/` 並恢復無例外。 +- `docs/audit/` 目前有 13 檔(`architecture.md`、`engineering.md`、`questions.md`、`perf-baseline.md`、`data.md`、`ui.md` 等,`ls docs/audit/`),被 `docs/adr/0008`(`:12,53,55`)、`0015`(`:10`)、`0026`(`:17,95`)等多處引用。 +- 地圖表要在 `implement.md:18` 同時「加 Diátaxis 類型欄」——加欄與加列是同一張表的兩個改動。 + +--- + +## 12. `.gitattributes` 的 journal `merge=union` 目前不存在,要不要留一句 + +**決定點**:`AGENTS.md:111-112` 說「若 update 又把 journal 的 `merge=union` 行加回 `.gitattributes`,就把它拿掉」——這條指示是繼續留著當防守,還是連同情況消失一起移除。 + +事實: + +- `.gitattributes`(17 行)**沒有** `merge=union` 行(`grep -n merge=union .gitattributes` 零命中)。→ 現況已符合要求,指示目前沒有觸發條件。 +- `.gitattributes` 內容是 `text=auto`、`*.ps1 text eol=crlf`、二進位標記、`pubspec.lock linguist-generated=true`。 +- 這條指示在 `AGENTS.md:111-112`(managed 區塊外),是防 `trellis update` 重新加回而寫的。 +- 全域規則說「沒有閘門的規則靠運氣被遵守」「撤掉一條閘門時,同一個 commit 要交代接手的是什麼」;這條屬「防守未來 update」而非現行規則。 From 1dd380a70b4b084d430b94f8ec0dc7c0cbce9f2b Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:05:43 +0800 Subject: [PATCH 119/133] chore(task): record doc language scope decision --- .trellis/tasks/09-28-phase3-docs-cleanup/prd.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md index 70d2885a5..0ba69ba95 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md @@ -43,9 +43,16 @@ - 還是英文的只有 AGENTS.md(134 行)與 `.trellis/spec/` 20 檔(1444 行),兩者描述的都是凍結中的舊專案,切換 PR 時會被取代。 - `docs/` 與 ADR 已是繁中。 +## 已決定 + +1. **語言範圍**(2026-09-28,擁有者「按你建議」,縮小第 9 項 R7 的適用範圍): + - 根目錄 AGENTS.md 與 `.trellis/spec/` 描述凍結中的舊專案,維持英文到切換 PR,只做本次清理必要的修改; + - `app/AGENTS.md` 與 `app/` 的 spec 從 M1 起用繁中; + - `docs/README.md` 的中英分工規則改寫為:「新文件一律繁中;根目錄 AGENTS.md 與 `.trellis/spec/` 描述舊專案,維持英文到切換 PR」。 + - 理由:翻譯約 1,600 行即將被取代的內容;舊專案緊急修正時仍要依這些規則,改寫措辭有改掉規則原意的風險。 + ## 待決定(一次問一題) -1. 根目錄 AGENTS.md 與 `.trellis/spec/` 要不要現在翻成繁中(第 9 項 R7「所有文檔繁中」的適用範圍)。 2. verify-on-device 在新平台怎麼擴充,以及實機驗證時預設用真實連線還是重播。 ## 驗收條件 From 5279724e6a2883659099038cb4ff28256b4b2768 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:07:52 +0800 Subject: [PATCH 120/133] chore(task): record on-device verification decision --- .trellis/tasks/09-28-phase3-docs-cleanup/prd.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md index 0ba69ba95..e17d124d6 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md @@ -51,9 +51,17 @@ - `docs/README.md` 的中英分工規則改寫為:「新文件一律繁中;根目錄 AGENTS.md 與 `.trellis/spec/` 描述舊專案,維持英文到切換 PR」。 - 理由:翻譯約 1,600 行即將被取代的內容;舊專案緊急修正時仍要依這些規則,改寫措辭有改掉規則原意的風險。 -## 待決定(一次問一題) - -2. verify-on-device 在新平台怎麼擴充,以及實機驗證時預設用真實連線還是重播。 +2. **實機驗證**(2026-09-28,擁有者「按你建議」): + - **預設用重播**:開發版+每個插件切成「重播」(ADR 0015),或 `app/` 的測試插件(合成資料、本機音檔)。UI、播放、下載、歌詞都在這個模式下驗。 + - **改用真實連線的時機**:只在改動本身是插件、網路層、登入,或正在錄 fixture 時。 + - 只做最少的操作(搜尋一次、播放一首),不做批次或迴圈; + - 回報時寫明打了真實 API。 + - **平台分工**: + - Android 模擬器與 Windows:每個改到使用者看得到的 PR 都驗(取代舊規則「Windows 只在 Windows 專屬改動時驗」); + - Linux 虛擬機:每個里程碑跑一次冒煙測試,在 Linux 平台任務新增這個平台的操作說明; + - macOS、iOS 模擬器:Mac 到貨後在各自的平台任務新增。 + - skill 在 M1 為 `app/` 改寫;舊專案的 skill 維持原樣,給緊急修正用。階段三只把規劃寫進 ADR。 + - 理由:真實音源常被限流(B 站 412)、帳號有被風控的風險、上游一改版無關的 PR 也驗不過;上游改版改由 Debug 頁健康檢查與手動冒煙測試發現。 ## 驗收條件 From 6a7e3bb1c88fbe3fdf1d4028879c1ce22ec10ff7 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:08:56 +0800 Subject: [PATCH 121/133] chore(task): add phase three design and plan --- .../tasks/09-28-phase3-docs-cleanup/design.md | 99 +++++++++++++++++++ .../09-28-phase3-docs-cleanup/implement.md | 26 +++++ .../tasks/09-28-phase3-docs-cleanup/prd.md | 25 ++++- 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/design.md create mode 100644 .trellis/tasks/09-28-phase3-docs-cleanup/implement.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/design.md b/.trellis/tasks/09-28-phase3-docs-cleanup/design.md new file mode 100644 index 000000000..589355827 --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/design.md @@ -0,0 +1,99 @@ +# 設計:階段三清理 + +原則: +- 根目錄的 AGENTS.md、`.trellis/spec/` 描述凍結中的舊專案,**只做必要修改、維持英文**(已決定 1); +- Trellis 管理的檔案(`.trellis/.template-hashes.json` 的 84 筆,以及 AGENTS.md 標記區塊內)**不改**,因為 `trellis update` 會覆寫。需要說明的,寫在 AGENTS.md 標記區塊外的 Trellis 段。 + +## 1. mattpocock 殘留 + +- 刪除 `docs/agents/` 三個檔。 +- AGENTS.md 的「Agent skills」段(`:7-14`)改成一段 `## Issues`,只留一條慣例: + > Issue titles and bodies are written in Traditional Chinese (Taiwan/Hong Kong usage); identifiers, log strings, commit messages, branch and label names stay in English. Issues live on `1morr/FMP` and are handled with `gh`. +- 5 個 triage label、5 個 `wayfinder:*` label 在 repo 內沒有任何使用者,隨目錄刪除。GitHub 上既有的 label 不動(不在 repo 內,也沒有人在用)。 +- `docs/agents/issue-tracker.md:16-21` 的「刻意沒有 issue 範本」不搬:ADR 0023 已定 M3 新增 `bug_report.yml`。 + +## 2. `docs/README.md` + +- 地圖表加「類型」欄(Diátaxis:操作指南、參考、說明;ADR 屬說明): + - 刪 `agents/` 一列; + - 加 `audit/` 一列,類型「快照(凍結)」,說明「重寫前的現況與驗收基準,切換 PR 刪除(ADR 0008、0026)」; + - `.trellis/spec/` 一列改為「英文,描述根目錄舊專案;`app/` 的 spec 從 M1 起繁中」。 +- `## 分工`: + - `:21` 改為:「新文件一律繁中;根目錄 `AGENTS.md` 與 `.trellis/spec/` 描述舊專案,維持英文到切換 PR;README 維持英/繁雙語。」 + - `:22` 補一句:`.agents/`、`.codex/` 是 gitignore 的本機狀態。 + - `:23`(`docs/agents/` 說明)刪除。 + - `:24` 補例外:「`docs/audit/` 在重寫期間凍結保留,切換 PR 刪除」。 + +## 3. 舊 ADR 0001、0003–0006 + +各在標題下加一行(格式同 0002、0007 已有的註記): + +| ADR | 註記指向 | +|---|---| +| 0001 | 新專案的字串音源 id 見 ADR 0014,每源設定見 ADR 0011、0012 | +| 0003 | ADR 0018 | +| 0004 | ADR 0020 | +| 0005 | 格式由 ADR 0010、0019 沿用 | +| 0006 | ADR 0022 | + +每一行的結尾都是「本檔在切換 PR 隨舊專案刪除(ADR 0008)」。 +- 引用它們的舊專案檔案(`lib/`、`test/`、`tool/`、`.github/`、`.trellis/spec/`、AGENTS.md、`docs/*.md`)不改,切換 PR 一起處理。 + +## 4. `CONTEXT.md` + +- ADR 0012 §決定 1 補一句 Media Handoff 裡唯一沒有對應的原則: + > 轉址:宿主 HTTP 跟隨轉址時,每一跳都要在 manifest 網域內,最多 5 跳(舊版 `SourceUrlPolicy.resolveRedirects` 的做法);媒體 client 跟隨轉址時,每一跳都只帶媒體 headers。 +- 刪除 `CONTEXT.md`。 +- `.trellis/spec/` 的 7 處引用改指 ADR 0012,維持英文。 + - `services/download-and-auth.md` 仍描述舊程式碼的 `SourceHttpPolicy`,只換出處,不改規則。 +- AGENTS.md `:13` 隨「Agent skills」段一起刪除。 + +## 5. 衝突 + +- **AGENTS.md 標記區塊**:`.codex/`、`.agents/` 那兩行不改。在標記區塊外的 Trellis 段加一句:「The managed block's `.agents/` and `.codex/` lines do not apply here: both are gitignored local state.」 +- **本機 `.agents/`**: + - 先把 `.agents/` 版獨有的「2026-09-07 實測筆記」併進 `.claude/skills/verify-on-device/references/`:Android 的部分進 `android.md`,toast 斷言進 `runtime-state.md`,已有的不重複。 + - 再刪除本機 `.agents/`。它被 gitignore,不影響 repo。 +- **check 子代理**:三份都不改。在 Trellis 段加一句:「Claude Code runs `.claude/agents/trellis-check.md` (customised); the `trellis-check` skill and `.trellis/agents/check.md` are Trellis-generated and left as shipped.」 +- **journal/archive commit**:Trellis 管理的敘述不改。在 Trellis 段補一句:「With `session_auto_commit: false`, archive and journal steps make no commits: commit task changes by hand.」 +- **「Test waits」**:AGENTS.md 的宣稱縮成閘門實際守的範圍: + > No direct `pumpEventQueue` outside `test/support/pump_until.dart`: use its `pumpUntil` / `drainEventQueue` — `test/support/wait_convention_static_rule_test.dart`. + - 「條件進入時為 false」「`drainEventQueue` 用於否定」原本就寫在 `.trellis/spec/testing/test-conventions.md:91-94`,不重複。 +- **`merge=union` 的指示**:保留。它防的是 `trellis update` 重新加回那一行,這個情況每次更新都可能再發生。 + +## 6. 實機驗證(已決定 2)→ ADR 0027 + +新 ADR `0027-on-device-verification.md`,內容: +- 預設重播; +- 改用真實連線的條件與限制; +- 平台分工表; +- skill 在 M1 為 `app/` 改寫,舊 skill 維持原樣; +- 如何確認: + - `app/AGENTS.md` 的驗證段寫明模式; + - 回報格式含「模式:重播/真實」; + - 里程碑驗收表含 Linux 冒煙測試。 + +ADR 0015、0026 各加一句指向 0027。 + +## 7. 範圍外 + +- `app/` 的 spec 放在哪(Trellis `packages:` 或其他):M1 開 `app/` 時決定。 +- 根目錄 AGENTS.md、spec 的翻譯:不做(已決定 1)。 +- GitHub 上的 label 清理。 + +## 8. 驗證 + +```bash +git grep -n -E "docs/agents|CONTEXT\.md|Agent skills|wayfinder|grill-with-docs" -- . ':!.trellis/tasks/archive' ':!docs/audit' +git grep -n -E "adr/000[1-7]|ADR 000[1-7]" -- . ':!.trellis/tasks/archive' ':!docs/audit' +``` + +- **第一條**只允許命中: + - ADR 0012 的併入聲明; + - parent 任務文件(歷史敘述); + - 本任務文件。 +- **第二條**只允許命中: + - 仍存在的 0001–0007 本身; + - 屬舊專案的引用(切換 PR 處理); + - 新 ADR 裡的延續或取代說明。 +- 另外跑 `flutter test test/support/wait_convention_static_rule_test.dart`:AGENTS.md 改字不影響它,但確認閘門仍綠。 diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/implement.md b/.trellis/tasks/09-28-phase3-docs-cleanup/implement.md new file mode 100644 index 000000000..1f32ca105 --- /dev/null +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/implement.md @@ -0,0 +1,26 @@ +# 執行計畫:階段三 + +一個 PR:沿用 `docs/audit` 分支與 draft PR #173。每步一個 commit。 + +1. [ ] `docs(adr): 0027 on-device verification`:新增 ADR 0027;ADR 0015、0026 各加一句指向。 +2. [ ] `docs: remove mattpocock skill residue`: + - 刪除 `docs/agents/`; + - AGENTS.md 的「Agent skills」段改為 `## Issues`。 +3. [ ] `docs: fold CONTEXT.md into ADR 0012`: + - ADR 0012 補上轉址原則; + - 刪除 `CONTEXT.md`; + - spec 的 7 處改指 ADR 0012。 +4. [ ] `docs(adr): mark old ADRs as legacy-only`:0001、0003–0006 加註記。 +5. [ ] `docs: rewrite the docs map`:`docs/README.md` 照 design §2 改寫。 +6. [ ] `docs: align agent notes with trellis setup`: + - AGENTS.md Trellis 段補三句(`.agents/`/`.codex/`、check 子代理、journal commit); + - 「Test waits」縮窄。 +7. [ ] 本機(不進 git): + - 把 `.agents/` 版的實測筆記併進 `.claude/skills/verify-on-device/references/`,這部分會 commit:`docs(skill): keep measured notes from the local copy`; + - 刪除本機 `.agents/`。 +8. [ ] 驗證: + - design §8 的兩條 `git grep`; + - `flutter test test/support/wait_convention_static_rule_test.dart test/support/static_rule_placement_static_rule_test.dart`。 +9. [ ] 更新 parent `phase2-plan.md` §10:階段三完成,下一步 M1。`task.py finish` 後再 `archive --no-commit --skip-branch-validation`,commit,push。 + +回退:全部是文件,revert 對應 commit 即可。本機 `.agents/` 刪除前,實測筆記已併進受版控的 skill。 diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md index e17d124d6..82228b085 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md +++ b/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md @@ -63,10 +63,27 @@ - skill 在 M1 為 `app/` 改寫;舊專案的 skill 維持原樣,給緊急修正用。階段三只把規劃寫進 ADR。 - 理由:真實音源常被限流(B 站 412)、帳號有被風控的風險、上游一改版無關的 PR 也驗不過;上游改版改由 Debug 頁健康檢查與手動冒煙測試發現。 +我自行定下、未另外詢問的處置(design §1–§5,理由寫在該處): +- 只把「issue 用繁中」搬進 AGENTS.md,label 慣例隨目錄刪除; +- 舊 ADR 現在就補註記; +- ADR 0012 補上轉址原則; +- 本機 `.agents/` 的實測筆記併進 skill 後刪除; +- Trellis 管理的檔案不改,說明寫在 AGENTS.md 標記區塊外; +- 「Test waits」縮成閘門實際守的範圍; +- `merge=union` 的指示保留。 + +## 範圍外 + +- `app/` 的 spec 放哪:在 M1 決定。 +- 根目錄 AGENTS.md 與 spec 的翻譯:不做。 +- GitHub 上的 label 清理。 + ## 驗收條件 -- [ ] 兩條 `git grep`(第 9 項 implement §B)只命中刻意保留的檔案。 -- [ ] `docs/agents/`、`CONTEXT.md` 已刪除;「issue 用繁中撰寫」寫進 AGENTS.md。 +- [ ] design §8 的兩條 `git grep` 只命中允許的檔案。 +- [ ] `docs/agents/`、`CONTEXT.md` 已刪除;AGENTS.md 有 `## Issues`。 - [ ] 舊 ADR 0001、0003–0006 都有「只適用舊專案」註記。 -- [ ] ADR 0012 補上 Media Handoff 的轉址網域檢查原則。 -- [ ] 第 9 項 design §6 的衝突各有處置,並記在 AGENTS.md 的 Trellis 段(標記區塊外)。 +- [ ] ADR 0012 有轉址原則;ADR 0027 記下實機驗證的決定,ADR 0015、0026 有指向。 +- [ ] `docs/README.md` 地圖有類型欄與 `audit/` 列,語言規則照已決定 1 改寫。 +- [ ] AGENTS.md 的 Trellis 段有三句說明,「Test waits」已縮窄;static-rule 測試保持綠。 +- [ ] 本機 `.agents/` 的實測筆記已併進 skill 並 commit,本機 `.agents/` 已刪除。 From 587edaccf365ba84542df184fbdef3fc672d6d23 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:18:20 +0800 Subject: [PATCH 122/133] docs(adr): 0027 on-device verification --- .../0015-testing-gates-and-dev-environment.md | 2 +- docs/adr/0026-milestones-and-cut-over.md | 1 + docs/adr/0027-on-device-verification.md | 79 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0027-on-device-verification.md diff --git a/docs/adr/0015-testing-gates-and-dev-environment.md b/docs/adr/0015-testing-gates-and-dev-environment.md index 9bf75bbe9..97a5c9376 100644 --- a/docs/adr/0015-testing-gates-and-dev-environment.md +++ b/docs/adr/0015-testing-gates-and-dev-environment.md @@ -55,7 +55,7 @@ log 只經門面、禁止空 catch、音源 id 不得出現在 UI 與 service、 3. **預設零聯網**:`app/dart_test.yaml` 對 `live` tag 設 `skip`、以 preset 解除;`app/test/flutter_test_config.dart` 以 `HttpOverrides.global` 讓建立真實 `HttpClient` 直接失敗,要聯網的測試在自己的 zone 明確放行。JS 腳本只能經宿主 `http.request` 出網,同樣受限。 4. **檢查案例一份四用**:每插件每能力最多一條檢查案例(`checks.json`),同一份用於契約測試(重播 fixture,進 CI)、 - 冒煙測試(真實連線,插件庫 `--live` 手動執行)、Debug 頁健康檢查(真實連線,App 內)、錄製(真實連線,遮蔽後存 fixture)。冒煙測試不進任何 CI、不排程。 + 冒煙測試(真實連線,插件庫 `--live` 手動執行)、Debug 頁健康檢查(真實連線,App 內)、錄製(真實連線,遮蔽後存 fixture)。冒煙測試不進任何 CI、不排程。實機驗證預設用重播,見 ADR 0027。 5. **fixture**:錄製與重播在宿主網路層最底部的 dio `HttpClientAdapter`;一次請求/回應一個 JSON 檔(`meta`+`request`+`response`)。 寫檔前一律經 ADR 0011 的正式遮蔽函式;重播比對 method+排序後的 URL+順序,被遮蔽的欄位不參與比對;比對不到就讓測試失敗。 錯誤案例可手改 fixture 並標記。 diff --git a/docs/adr/0026-milestones-and-cut-over.md b/docs/adr/0026-milestones-and-cut-over.md index 814af1295..fb54f0aaf 100644 --- a/docs/adr/0026-milestones-and-cut-over.md +++ b/docs/adr/0026-milestones-and-cut-over.md @@ -86,6 +86,7 @@ ADR 0008 定了高層策略: - 驗收在 VMware Workstation Pro(個人使用免費)的 Ubuntu LTS 桌面虛擬機,X11 與 Wayland 各一次; - 日常開發用 WSL2; - 之後每個里程碑在虛擬機跑一次冒煙測試。 + - 各平台實機驗證的時機與模式見 ADR 0027。 - **macOS、iOS**:Mac 到貨後開。 - 到貨前只靠 GitHub macOS runner 的編譯與 iOS 模擬器測試(ADR 0009); - iOS 要不要實機、要不要付費帳號,在該任務決定。 diff --git a/docs/adr/0027-on-device-verification.md b/docs/adr/0027-on-device-verification.md new file mode 100644 index 000000000..7ad392ed1 --- /dev/null +++ b/docs/adr/0027-on-device-verification.md @@ -0,0 +1,79 @@ +# 0027 — 實機驗證:預設重播、只在改到音源互動時打真實 API、Android 與 Windows 每個 PR 都驗 + +- 狀態:已採納 +- 日期:2026-09-28 +- 影響範圍:`app/` 的 verify-on-device skill 與 `app/AGENTS.md` 的驗證段、各平台任務的操作說明、里程碑驗收 + +## 背景 + +舊專案(`.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/research/current-state.md` §g): + +- verify-on-device skill 只涵蓋 Android 模擬器(必要)與 Windows(只在 Windows 專屬改動時)。 +- 它跑的是真實 App 對真實音源。筆記裡記過三個音源同時用不了(B 站 `playurl` 回 412、YouTube 要求登入)(`references/runtime-state.md:35-36`)。 +- ADR 0015 的零聯網只管 `flutter test`(`dart_test.yaml` 的 `live` 跳過、`HttpOverrides`),不管實機驗證。 + +新架構已經有可以用的工具: +- 每插件可切換真實、錄製、重播(ADR 0015 §5、§7); +- `app/` 有合成資料、播放本機音檔的測試插件(ADR 0015 §6); +- Debug 頁的音源健康檢查以真實連線手動執行(ADR 0025)。 + +平台的排程已由 ADR 0026 定下:Android、Windows 全面驗證;Linux 在 M1 之後開平台任務;macOS、iOS 等 Mac 到貨。 + +parent prd 階段三要求:規劃新平台加入時實機驗證如何擴充,以及如何減少打真實 API。擁有者 2026-09-28 照建議選定。 + +## 考慮過的選項 + +- **預設打真實 API(舊版)**:否決。 + - 常被限流擋住,驗證結果時好時壞; + - 頻繁操作可能讓擁有者的帳號被風控; + - 上游一改版,無關的 UI PR 也跟著驗不過。 +- **Windows 只在 Windows 專屬改動時驗(舊規則)**:否決。Windows 在新架構是兩個主力平台之一;舊版的 Windows 無障礙樹凍結就是這樣漏掉的。 +- **Linux 每個 PR 都驗**:否決,每個 PR 都要開虛擬機,時間成本高。 +- **現在就改寫 skill**:否決。`app/` 還不存在;舊專案的緊急修正仍要用現在的 skill。 + +## 決定 + +1. **預設模式是重播**:實機驗證一律跑 dev flavor,每個插件切成「重播」,或使用 `app/` 的測試插件。UI、播放、下載、歌詞、設定的改動都在這個模式下驗。 +2. **改用真實連線的條件**: + - 只在改動本身是插件、網路層、登入,或正在錄製 fixture 時; + - 只做最少的操作(例如搜尋一次、播放一首),不做批次或迴圈; + - 回報寫明「模式:真實」與做了哪些請求。 + - 上游改版由 Debug 頁的健康檢查與手動冒煙測試發現(ADR 0015 §4),不靠每個 PR 的實機驗證。 +3. **平台分工**: + + | 平台 | 時機 | 何時加入 skill | + |---|---|---| + | Android 模擬器 | 每個改到使用者看得到的 PR | M1 | + | Windows | 每個改到使用者看得到的 PR | M1 | + | Linux 虛擬機(VMware,Ubuntu 桌面,X11 與 Wayland) | 每個里程碑一次冒煙測試 | Linux 平台任務 | + | macOS | 每個里程碑一次冒煙測試 | macOS 平台任務(Mac 到貨後) | + | iOS 模擬器 | 每個里程碑一次冒煙測試 | iOS 平台任務(Mac 到貨後) | + + - 每個平台的操作說明沿用現在 skill 的閉環:啟動 → 執行 → 觀察 → 操作 → 收尾。放在 skill 的 `references/<平台>.md`。 +4. **時程**: + - M1 時為 `app/` 改寫 skill; + - 根目錄舊專案的 skill 維持原樣,給緊急修正用,切換 PR 時移除。 + +採用的慣例: +- 契約測試與實機驗證共用錄製的 fixture(ADR 0015 §4 的「檢查案例一份四用」); +- 現在這份 skill 的閉環與「做不到就具名回報 blocker」。 + +## 後果 + +- 好的: + - 實機驗證的結果可以重現,不受上游和限流影響; + - 擁有者的帳號很少被打到; + - Windows 的問題在 PR 階段就會被發現。 +- 壞的: + - 重播看不到上游的最新行為,要靠健康檢查與冒煙測試; + - 每個 PR 要驗兩個平台,時間比舊規則長; + - fixture 要定期重錄。 +- 之後要注意: + - 若測試插件的合成資料不足以涵蓋某類 UI,先補測試插件,不要改成打真實 API; + - Linux、macOS、iOS 的操作說明由各自的平台任務負責。 + +## 如何確認 + +- `app/AGENTS.md` 的驗證段寫明「預設重播、真實連線的條件、Android 與 Windows 每個 PR」。這是 review 點:實機驗證無法寫成測試。 +- 實機驗證的回報格式包含「平台」與「模式:重播/真實」。PR review 指南缺這兩項就退回。 +- 里程碑驗收表(`milestones.md`)的每個里程碑,在 Linux 平台任務完成後都含「Linux 冒煙測試」一格。 From e11358793c907325a2d272ddf99b29beb4816ba1 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:18:42 +0800 Subject: [PATCH 123/133] docs: remove mattpocock skill residue --- AGENTS.md | 13 +++----- docs/agents/domain.md | 53 -------------------------------- docs/agents/issue-tracker.md | 59 ------------------------------------ docs/agents/triage-labels.md | 17 ----------- 4 files changed, 5 insertions(+), 137 deletions(-) delete mode 100644 docs/agents/domain.md delete mode 100644 docs/agents/issue-tracker.md delete mode 100644 docs/agents/triage-labels.md diff --git a/AGENTS.md b/AGENTS.md index 7bf25df7e..c9d372300 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,14 +4,11 @@ FMP is a Flutter music player for Android and Windows that plays from **Bilibili**, **YouTube** and **NetEase Cloud Music**. Human-facing docs live in `docs/`; `docs/README.md` is the map. -## Agent skills - -- **Issue tracker** — GitHub Issues on `1morr/FMP` via `gh`. See - `docs/agents/issue-tracker.md`. -- **Triage labels** — the five canonical roles. See - `docs/agents/triage-labels.md`. -- **Domain docs** — single-context: `CONTEXT.md` + `docs/adr/`. See - `docs/agents/domain.md`. +## Issues + +Issues live on `1morr/FMP` and are handled with `gh`. Titles and bodies are +written in Traditional Chinese (Taiwan/Hong Kong usage); identifiers, log +strings, commit messages, branch and label names stay in English. ## Verification diff --git a/docs/agents/domain.md b/docs/agents/domain.md deleted file mode 100644 index d468b86a1..000000000 --- a/docs/agents/domain.md +++ /dev/null @@ -1,53 +0,0 @@ -# Domain Docs - -How the engineering skills should consume this repo's domain documentation when exploring the codebase. - -FMP is a **single-context** repo: one `CONTEXT.md` and one `docs/adr/` at the root. - -## Before exploring, read these - -- **`CONTEXT.md`** at the repo root — the ubiquitous language for source auth and - media handoff decisions. -- **`docs/adr/`** — read ADRs that touch the area you're about to work in. - -If any of these don't exist yet, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved. - -## Relationship to `AGENTS.md` - -These are different documents with different jobs — don't merge or duplicate them: - -- **`CONTEXT.md`** defines *vocabulary* — what a term means and which synonyms to avoid. -- **`docs/adr/`** records *why* a decision was made, including rejected alternatives. -- **`AGENTS.md`** states *binding rules* for changing code. - -The reason behind a single piece of code lives in its dartdoc or in the test -that gates it; an ADR is for a decision that spans modules. - -## File structure - -``` -/ -├── CONTEXT.md -├── AGENTS.md ← binding agent rules -├── docs/adr/ -│ └── NNNN-<slug>.md -└── lib/ -``` - -## Use the glossary's vocabulary - -When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids — e.g. write **Media Request Credentials**, not "playback headers", when you mean the credentials allowed on the actual audio byte request. - -If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`). - -## Flag ADR conflicts - -If your output contradicts an existing ADR, surface it explicitly rather than silently overriding: - -> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_ - -## Language - -ADRs are written in **Traditional Chinese** (台港用語), matching the rest of -`docs/`. `CONTEXT.md` keeps its English term names so they match the identifiers -they describe, with explanations in whichever language the entry already uses. diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md deleted file mode 100644 index 104701df5..000000000 --- a/docs/agents/issue-tracker.md +++ /dev/null @@ -1,59 +0,0 @@ -# Issue tracker: GitHub - -Issues and PRDs for this repo live as GitHub issues on `1morr/FMP`. Use the `gh` -CLI for all operations — it infers the repo from `git remote -v` when run inside -a clone. - -## Conventions - -- **Create an issue**: `gh issue create --title "..." --body "..."`. Use a heredoc for multi-line bodies. -- **Read an issue**: `gh issue view <number> --comments`, filtering comments by `jq` and also fetching labels. -- **List issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'` with appropriate `--label` and `--state` filters. -- **Comment on an issue**: `gh issue comment <number> --body "..."` -- **Apply / remove labels**: `gh issue edit <number> --add-label "..."` / `--remove-label "..."` -- **Close**: `gh issue close <number> --comment "..."` - -## Issue templates - -There are none, deliberately. Every issue in this repo so far was opened by the -owner, and a template is a form you fill in for yourself. Add -`.github/ISSUE_TEMPLATE/` when the **first issue from someone else** arrives — -that is the trigger, not a repo-size milestone. - -## Pull requests as a triage surface - -**PRs as a request surface: no.** _(Set to `yes` if this repo treats external PRs as feature requests; `/triage` reads this flag.)_ - -When set to `yes`, PRs run through the same labels and states as issues, using the `gh pr` equivalents: - -- **Read a PR**: `gh pr view <number> --comments` and `gh pr diff <number>` for the diff. -- **List external PRs for triage**: `gh pr list --state open --json number,title,body,labels,author,authorAssociation,comments` then keep only `authorAssociation` of `CONTRIBUTOR`, `FIRST_TIME_CONTRIBUTOR`, or `NONE` (drop `OWNER`/`MEMBER`/`COLLABORATOR`). -- **Comment / label / close**: `gh pr comment`, `gh pr edit --add-label`/`--remove-label`, `gh pr close`. - -GitHub shares one number space across issues and PRs, so a bare `#42` may be either — resolve with `gh pr view 42` and fall back to `gh issue view 42`. - -## When a skill says "publish to the issue tracker" - -Create a GitHub issue. - -## When a skill says "fetch the relevant ticket" - -Run `gh issue view <number> --comments`. - -## Language - -Issue titles and bodies are written in **Traditional Chinese** (台港用語), matching -`docs/` and the root `README`. Keep code identifiers, log strings, commit -messages, branch names, and label strings in English — see the language split -documented in `docs/README.md` § 分工. - -## Wayfinding operations - -Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets. - -- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `gh issue create --label wayfinder:map`. -- **Child ticket**: an issue linked to the map as a GitHub sub-issue (`gh api` on the sub-issues endpoint). Where sub-issues aren't enabled, add the child to a task list in the map body and put `Part of #<map>` at the top of the child body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev. -- **Blocking**: GitHub's **native issue dependencies** — the canonical, UI-visible representation. Add an edge with `gh api --method POST repos/1morr/FMP/issues/<child>/dependencies/blocked_by -F issue_id=<blocker-db-id>`, where `<blocker-db-id>` is the blocker's numeric **database id** (`gh api repos/1morr/FMP/issues/<n> --jq .id`, _not_ the `#number` or `node_id`). GitHub reports `issue_dependencies_summary.blocked_by` (open blockers only — the live gate). Where dependencies aren't available, fall back to a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every blocker is closed. -- **Frontier query**: list the map's open children (`gh issue list --state open`, scoped to the map's sub-issues / task list), drop any with an open blocker (`issue_dependencies_summary.blocked_by > 0`, or an open issue in the `Blocked by` line) or an assignee; first in map order wins. -- **Claim**: `gh issue edit <n> --add-assignee @me` — the session's first write. -- **Resolve**: `gh issue comment <n> --body "<answer>"`, then `gh issue close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far. diff --git a/docs/agents/triage-labels.md b/docs/agents/triage-labels.md deleted file mode 100644 index a0a66b53b..000000000 --- a/docs/agents/triage-labels.md +++ /dev/null @@ -1,17 +0,0 @@ -# Triage Labels - -The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker. - -| Label in mattpocock/skills | Label in our tracker | Meaning | -| -------------------------- | -------------------- | ---------------------------------------- | -| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue | -| `needs-info` | `needs-info` | Waiting on reporter for more information | -| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent | -| `ready-for-human` | `ready-for-human` | Requires human implementation | -| `wontfix` | `wontfix` | Will not be actioned | - -When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table. - -FMP uses the defaults unchanged. Edit the right-hand column if the tracker's -vocabulary ever diverges; label strings stay in English even though issue bodies -are written in Traditional Chinese. From 540685cc9df8f975c09fd0770794b8cf5c59bd8b Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:19:59 +0800 Subject: [PATCH 124/133] docs: fold CONTEXT.md into ADR 0012 and the spec --- .trellis/spec/data/index.md | 2 +- .trellis/spec/data/sources.md | 2 +- .../spec/guides/cross-layer-thinking-guide.md | 2 +- .trellis/spec/services/download-and-auth.md | 32 +++++++++-- .trellis/spec/services/index.md | 4 +- CONTEXT.md | 53 ------------------- docs/adr/0012-network-layer-and-accounts.md | 3 +- 7 files changed, 36 insertions(+), 62 deletions(-) delete mode 100644 CONTEXT.md diff --git a/.trellis/spec/data/index.md b/.trellis/spec/data/index.md index 870a6dd97..964df06bf 100644 --- a/.trellis/spec/data/index.md +++ b/.trellis/spec/data/index.md @@ -6,7 +6,7 @@ and the shared foundation in `lib/core/` (errors, logger, constants, utils). Neither directory imports `lib/services/` or `lib/providers/` (one recorded exception, `lib/core/extensions/track_extensions.dart`, in -`test/support/layer_boundary_static_rule_test.dart`) — see AGENTS.md § Boundaries. Vocabulary for auth and media handoff is in `CONTEXT.md`. +`test/support/layer_boundary_static_rule_test.dart`) — see AGENTS.md § Boundaries. Vocabulary for auth and media handoff is in `services/download-and-auth.md` § Auth vocabulary. ## Guidelines diff --git a/.trellis/spec/data/sources.md b/.trellis/spec/data/sources.md index e383f998a..86c8e22d3 100644 --- a/.trellis/spec/data/sources.md +++ b/.trellis/spec/data/sources.md @@ -78,7 +78,7 @@ Adapters never read accounts. Credentials arrive per request as `getVideoDetail(…, {authHeaders})`, `parsePlaylist(…, {authHeaders})`), and the adapter keeps only what it needs (`NeteaseSource._withAuth` keeps `Cookie`). The caller side is `SourceAuthContext` in `lib/services/account/`; the terms are -defined in `CONTEXT.md`. +defined in `services/download-and-auth.md` § Auth vocabulary. ## Errors: one `SourceApiException` subtype per source diff --git a/.trellis/spec/guides/cross-layer-thinking-guide.md b/.trellis/spec/guides/cross-layer-thinking-guide.md index 6ea402509..62f651fab 100644 --- a/.trellis/spec/guides/cross-layer-thinking-guide.md +++ b/.trellis/spec/guides/cross-layer-thinking-guide.md @@ -48,6 +48,6 @@ relinked in the same transaction. ### Anything about credentials -Name which of the `CONTEXT.md` terms applies: Stream Resolution Auth +Name which of the auth vocabulary terms (`services/download-and-auth.md`) applies: Stream Resolution Auth (adapter request) and Media Request Credentials (byte request, empty by construction) are different arrows. Changing either needs the user's approval. diff --git a/.trellis/spec/services/download-and-auth.md b/.trellis/spec/services/download-and-auth.md index 57d03bf04..6290655df 100644 --- a/.trellis/spec/services/download-and-auth.md +++ b/.trellis/spec/services/download-and-auth.md @@ -1,6 +1,32 @@ # Download pipeline, media handoff, accounts -Vocabulary: `CONTEXT.md`. Storage paths and Android permissions: ADR 0004. +Vocabulary: § Auth vocabulary below (the principle is recorded in ADR 0012). +Storage paths and Android permissions: ADR 0004. + +## Auth vocabulary + +Use these terms as defined; avoid the synonyms in brackets. + +- **Source Auth Context** — the policy that decides which source credentials a + given source operation may use; distinct from account login and credential + storage. (Not: auth helper, header utility, account service.) +- **Media Handoff** — the move from a resolved stream URL to the audio or + download backend: redirect checks, per-hop media headers, resumed-download + range headers, and Source Auth Context credentials narrowed into Media Request + Credentials. (Not: playback URL helper, download header helper.) +- **Stream Resolution Auth** — credentials used while asking a source adapter to + resolve or refresh a stream URL; broader than Media Request Credentials and may + include Bilibili or YouTube auth that must never reach a media/CDN request. + (Not: media auth, playback headers.) +- **Auth For Play** — the user setting that gates credentials for stream + resolution, playback handoff, download, track detail and auth-aware + metadata/detail paths; it does not control playlist import, playlist refresh + or search. (Not: import auth, search auth.) +- **Media Request Credentials** — credentials allowed on the actual audio byte + request. There are none: `SourceHttpPolicy.mediaHeaders(String sourceType)` + (`lib/data/sources/source_http_policy.dart`) takes only the source id, so no + cookie or token can reach the media host through it; the former Netease media + allowlist was removed in `c09aec10`. (Not: stream auth, source auth.) ## Download (`lib/services/download/`) @@ -35,8 +61,8 @@ Media byte requests — playback and download — carry only `SourceHttpPolicy.mediaHeaders(sourceType)` plus `Range`. `streamResolutionAuth` is carried through but deliberately unused. Stream Resolution Auth is for asking the adapter for a URL, never for fetching the -bytes. Do not add credentials here without changing `CONTEXT.md` and getting the -user's approval. +bytes. Do not add credentials here without changing § Auth vocabulary and getting +the user's approval. ## Accounts and credentials (`lib/services/account/`) diff --git a/.trellis/spec/services/index.md b/.trellis/spec/services/index.md index 1c4a0239b..aeb600724 100644 --- a/.trellis/spec/services/index.md +++ b/.trellis/spec/services/index.md @@ -5,7 +5,7 @@ radio, search, cache, network, platform, update, backup, and the shared `ToastService` / image-loading services in `lib/core/services/`. Terms used here — Source Auth Context, Media Handoff, Auth For Play, Media Request -Credentials — are defined in `CONTEXT.md`; use them as defined. +Credentials — are defined in `download-and-auth.md` § Auth vocabulary; use them as defined. ## Guidelines @@ -21,7 +21,7 @@ Error and logging rules shared with other layers: [../shared/errors-and-logging. - [ ] Audio change → read `audio.md` and ADR 0003 (two backends). UI calls `AudioController`, never `FmpAudioService`; radio is the one exception (AGENTS.md § Boundaries). - [ ] Download / storage path change → read `download-and-auth.md` and ADR 0004. -- [ ] Anything that decides which credentials go where → read `CONTEXT.md` first. Changing the auth boundary needs the user's approval (AGENTS.md § Conventions). +- [ ] Anything that decides which credentials go where → read `download-and-auth.md` § Auth vocabulary first. Changing the auth boundary needs the user's approval (AGENTS.md § Conventions). - [ ] A new repeating timer, outbound host or cross-feature import → plan the static-rule entry with its reason. ## Quality Check diff --git a/CONTEXT.md b/CONTEXT.md deleted file mode 100644 index bbd528674..000000000 --- a/CONTEXT.md +++ /dev/null @@ -1,53 +0,0 @@ -# FMP Context - -FMP is a cross-platform music player that resolves tracks from Bilibili, -YouTube, and Netease sources. This context records project-specific language for -source auth and media handoff decisions. - -## Language - -**Source Auth Context**: -A policy concept that decides which source credentials may be used for a -specific source operation. It is distinct from account login and credential -storage. -_Avoid_: auth helper, header utility, account service - -**Media Handoff**: -The transition from a resolved stream URL to the audio or download backend, -including redirect checks, per-hop media headers, resumed-download range -headers, and Source Auth Context credentials narrowed into Media Request -Credentials. -_Avoid_: playback URL helper, download header helper - -**Stream Resolution Auth**: -Credentials used while asking a source adapter to resolve or refresh a stream -URL. This is broader than media request credentials and may include Bilibili or -YouTube auth that must not be sent to media/CDN requests. -_Avoid_: media auth, playback headers - -**Auth For Play**: -The user setting that gates credentials for stream resolution, playback handoff, -download, track detail, and auth-aware metadata/detail service paths. Auth -For Play does not control playlist import, playlist refresh, or search. -_Avoid_: import auth, search auth - -**Media Request Credentials**: -Credentials that are allowed on the actual audio byte request. In current FMP -policy there are none: `SourceHttpPolicy.mediaHeaders(String sourceType)` -(`lib/data/sources/source_http_policy.dart`) takes only the source id, so -no cookie or token can reach the media host through it. The former Netease -media allowlist was removed in `c09aec10`. -_Avoid_: stream auth, source auth - -## Example Dialogue - -Developer: "This download needs Stream Resolution Auth so Netease can return a -playable URL." - -Reviewer: "That does not mean the isolate can send all source auth to the media -host. Media Request Credentials are empty by construction — `mediaHeaders()` -takes a source id and nothing else." - -Developer: "The Source Auth Context will return the resolution auth for the -source adapter, then Media Handoff will recompute headers for each redirect -hop." diff --git a/docs/adr/0012-network-layer-and-accounts.md b/docs/adr/0012-network-layer-and-accounts.md index 22bb2766d..d17addce5 100644 --- a/docs/adr/0012-network-layer-and-accounts.md +++ b/docs/adr/0012-network-layer-and-accounts.md @@ -13,7 +13,7 @@ - 帶不帶憑證散落在各 service 手動組 header;每個 service 各自一個 dio。 - B 站 QR 登入可能假成功;B 站刷新憑證後用舊 options 重送;網易任何非 200 都當失效並清憑證;播放用的連線偵測不到失效;secure storage 暫時讀不到就刪憑證;失效提示每次執行只跳一次。 -`CONTEXT.md` 記錄的原則經審計驗證仍成立,併入本 ADR:**憑證只用在向音源解析串流與 API 請求,實際抓取音訊位元組的請求一律不帶憑證**。 +舊版 `CONTEXT.md`(階段三刪除,術語移到舊專案的 `.trellis/spec/services/download-and-auth.md`)記錄的原則經審計驗證仍成立,併入本 ADR:**憑證只用在向音源解析串流與 API 請求,實際抓取音訊位元組的請求一律不帶憑證**。 ## 考慮過的選項 @@ -29,6 +29,7 @@ 1. **HTTP 層**:每個音源一個 API client(dio),該音源所有 service 共用;攔截器順序為認證注入、cookie 管理、錯誤對應、 限流與退避(策略由音源宣告)、網路紀錄(ADR 0011)。另有一個**媒體 client** 專抓音訊位元組,只加媒體 headers(Referer、UA), 不掛認證攔截器與 cookie 管理。匿名用的非機密 cookie(例如 B 站 `buvid`)存資料庫。 + 轉址:宿主 HTTP 跟隨轉址時每一跳都要在 manifest 網域內,最多 5 跳(舊版 `SourceUrlPolicy.resolveRedirects` 的做法);媒體 client 跟隨轉址時每一跳只帶媒體 headers。 2. **帶憑證的單一宣告點**:每個請求在音源插件的定義處宣告 `AuthRequirement`: - `required`:寫入遠端歌單、讀收藏夾與私人歌單;未登入就不發請求,直接回「需要登入」。 - `userPreference`:搜尋、排行、詳情、串流解析、下載詳情、歌單刷新、電台、Mix;已登入且開關開啟才帶。 From 7a9674d3eb339129c8eca7c5e2a96e6a1d58a259 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:20:13 +0800 Subject: [PATCH 125/133] docs(adr): mark old ADRs as legacy-only --- docs/adr/0001-per-source-settings-and-string-source-ids.md | 2 ++ docs/adr/0003-two-audio-backends.md | 2 ++ docs/adr/0004-android-storage-without-mediastore.md | 2 ++ docs/adr/0005-track-unique-key-includes-cid.md | 2 ++ docs/adr/0006-release-publishes-after-artifact-check.md | 2 ++ 5 files changed, 10 insertions(+) diff --git a/docs/adr/0001-per-source-settings-and-string-source-ids.md b/docs/adr/0001-per-source-settings-and-string-source-ids.md index 759f4d56f..b3260e8ab 100644 --- a/docs/adr/0001-per-source-settings-and-string-source-ids.md +++ b/docs/adr/0001-per-source-settings-and-string-source-ids.md @@ -1,5 +1,7 @@ # 0001 — 每源設定收成一份清單,音源改用字串 id +> 只適用根目錄舊專案;新專案(`app/`)的字串音源 id 見 [ADR 0014](0014-script-source-plugins.md),每源設定見 [ADR 0011](0011-settings-and-logging.md)、[ADR 0012](0012-network-layer-and-accounts.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-03 - 影響範圍:`lib/data/models/`、`lib/data/sources/`、備份格式、schema v1 → v2 diff --git a/docs/adr/0003-two-audio-backends.md b/docs/adr/0003-two-audio-backends.md index 1cc86311e..4a4014dc5 100644 --- a/docs/adr/0003-two-audio-backends.md +++ b/docs/adr/0003-two-audio-backends.md @@ -1,5 +1,7 @@ # 0003 — 保留兩個音訊後端 +> 只適用根目錄舊專案;新專案(`app/`)見 [ADR 0018](0018-playback-core.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-24 - 影響範圍:`lib/services/audio/`、`lib/providers/audio/audio_controller_provider.dart`、`pubspec.yaml` 的音訊依賴 diff --git a/docs/adr/0004-android-storage-without-mediastore.md b/docs/adr/0004-android-storage-without-mediastore.md index ff323a37f..32bbb3345 100644 --- a/docs/adr/0004-android-storage-without-mediastore.md +++ b/docs/adr/0004-android-storage-without-mediastore.md @@ -1,5 +1,7 @@ # 0004 — Android 下載用所有檔案存取權與裸路徑,不用 MediaStore +> 只適用根目錄舊專案;新專案(`app/`)見 [ADR 0020](0020-downloads-and-permissions.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-24 - 影響範圍:`android/app/src/main/AndroidManifest.xml`、`lib/services/platform/storage_permission_service.dart`、`lib/services/download/`、`lib/providers/download/` diff --git a/docs/adr/0005-track-unique-key-includes-cid.md b/docs/adr/0005-track-unique-key-includes-cid.md index 242db1325..28b7791f8 100644 --- a/docs/adr/0005-track-unique-key-includes-cid.md +++ b/docs/adr/0005-track-unique-key-includes-cid.md @@ -1,5 +1,7 @@ # 0005 — 曲目識別鍵包含 Bilibili 的 cid +> 只適用根目錄舊專案;新專案(`app/`)沿用同一格式,見 [ADR 0010](0010-drift-data-layer-and-legacy-import.md)、[ADR 0019](0019-library-and-sync.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已採納 - 日期:2026-09-24 - 影響範圍:`lib/data/models/track_key.dart`、`lib/data/models/track.dart`、所有以識別鍵當外鍵的 collection 與備份格式 diff --git a/docs/adr/0006-release-publishes-after-artifact-check.md b/docs/adr/0006-release-publishes-after-artifact-check.md index 59b41df0e..11a7545c8 100644 --- a/docs/adr/0006-release-publishes-after-artifact-check.md +++ b/docs/adr/0006-release-publishes-after-artifact-check.md @@ -1,5 +1,7 @@ # 0006 — Release 驗過產物就直接發布,不再留草稿等人按 +> 只適用根目錄舊專案;新專案(`app/`)見 [ADR 0022](0022-release-and-in-app-update.md)。本檔在切換 PR 隨舊專案刪除(ADR 0008)。 + - 狀態:已實作 - 日期:2026-09-24 - 影響範圍:`.github/workflows/release.yml`、`test/workflows/release_workflow_test.dart`、`docs/build-and-release.md` 的發布流程 From 3fcd913b88ee576150c264bd195cce24aac1314a Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:20:41 +0800 Subject: [PATCH 126/133] docs: rewrite the docs map --- docs/README.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index f83b5ab36..90abecfca 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,23 +2,24 @@ 根目錄 [README](../README.md) 是產品入口;AI coding agent 的規則在 [AGENTS.md](../AGENTS.md),人類貢獻者適用同一套。 -| 文件 | 什麼時候讀 | 什麼變了要更新它 | -|------|------------|------------------| -| [README](../README.md) | 想下載或快速了解 FMP | 使用者可見功能、截圖、下載入口、專案定位 | -| [建置指南](building.md) | 在本機編譯 Android / Windows | 本機建置環境、工具鏈、打包前置條件 | -| [開發文件](development.md) | 理解架構與主要模組;用 VM Service 查正在跑的 app | 架構分層、Runtime 調試流程 | -| [建置與發布指南](build-and-release.md) | 發新版本、調整 CI 或 Release 流程 | CI、產物命名、Release workflow、簽名 secrets、應用內更新資產 | -| [疑難排解](troubleshooting.md) | 看到像錯誤的建置或 runtime log,或遇到修不掉只能繞過的行為 | 新查明的噪音或已知行為 | -| [.trellis/spec/](../.trellis/spec/) | 用 Trellis 跑任務,或想知道某一層的程式碼照什麼模式寫(英文,給 agent 讀) | 某層的寫法慣例變了;有閘門的規則改在 `AGENTS.md`,spec 只連過去 | -| [adr/](adr/) | 想知道某個跨模組決定「當初為什麼這樣選」 | 新的跨模組決策(決定、理由、被否決的方案) | -| [verify-on-device skill](../.claude/skills/verify-on-device/SKILL.md) | 改了使用者可見行為,要做強制的實機驗證 | 模擬器啟動方式、驗證流程、裝置端限制 | -| [agents/](agents/) | (給 engineering skills 讀,不是給人讀)| 換 issue 追蹤系統或標籤詞彙 | +類型依 [Diátaxis](https://diataxis.fr/):操作指南(照步驟做一件事)、參考(查事實)、說明(理解為什麼)。 + +| 文件 | 類型 | 什麼時候讀 | 什麼變了要更新它 | +|------|------|------------|------------------| +| [README](../README.md) | 說明 | 想下載或快速了解 FMP | 使用者可見功能、截圖、下載入口、專案定位 | +| [建置指南](building.md) | 操作指南 | 在本機編譯 Android / Windows | 本機建置環境、工具鏈、打包前置條件 | +| [開發文件](development.md) | 說明 | 理解架構與主要模組;用 VM Service 查正在跑的 app | 架構分層、Runtime 調試流程 | +| [建置與發布指南](build-and-release.md) | 操作指南、參考 | 發新版本、調整 CI 或 Release 流程 | CI、產物命名、Release workflow、簽名 secrets、應用內更新資產 | +| [疑難排解](troubleshooting.md) | 參考 | 看到像錯誤的建置或 runtime log,或遇到修不掉只能繞過的行為 | 新查明的噪音或已知行為 | +| [.trellis/spec/](../.trellis/spec/) | 參考 | 用 Trellis 跑任務,或想知道某一層的程式碼照什麼模式寫(英文,描述根目錄舊專案;`app/` 的 spec 從 M1 起繁中) | 某層的寫法慣例變了;有閘門的規則改在 `AGENTS.md`,spec 只連過去 | +| [adr/](adr/) | 說明 | 想知道某個跨模組決定「當初為什麼這樣選」 | 新的跨模組決策(決定、理由、被否決的方案) | +| [verify-on-device skill](../.claude/skills/verify-on-device/SKILL.md) | 操作指南 | 改了使用者可見行為,要做強制的實機驗證 | 模擬器啟動方式、驗證流程、裝置端限制 | +| [audit/](audit/) | 快照(凍結) | 對照重寫前的現況、功能勾選與效能基準 | 只允許核查更正;切換 PR 刪除(ADR 0008、0026) | ## 分工 - 單一段程式碼的理由寫在它旁邊(dartdoc 或守著它的測試);只有程式碼查不到的跨檔契約與地雷才進 `AGENTS.md`。 - 同一條規則只寫在一個地方,除非另一份文件確實有自己的讀者。 -- **語系分工是刻意的**:`AGENTS.md`、`docs/agents/` 與 `.trellis/spec/` 維持英文,與程式碼、commit、識別字一致;`docs/` 其餘文件與根目錄 `README.zh-Hant.md` 以繁體中文撰寫。 -- `.claude/skills/` 放可被 Claude Code 直接叫用的專案 skill。`.gitignore` 另外追蹤 Trellis 的接線(`.claude/` 下的 `agents/`、`commands/`、`hooks/`、`settings.json`);`.claude/` 其餘內容與 `.trellis/workspace/`(session 日誌)是本機狀態。 -- `docs/agents/` 的三個檔是 `/setup-matt-pocock-skills` 的產出**再加上 FMP 專屬修改**(repo 釘死成 `1morr/FMP`、繁中語言政策),重跑那個 skill 會用泛用模板覆蓋掉它們。 -- 審查記錄不進 `docs/`。一輪審計的結論寫進它所描述的檔案、開成 issue,或留在 git 歷史。 +- **語言**:新文件一律繁體中文;根目錄 `AGENTS.md` 與 `.trellis/spec/` 描述舊專案,維持英文到切換 PR;README 維持英/繁雙語。程式碼識別字、指令、檔名、log 字串、commit message 保留原文。 +- `.claude/skills/` 放可被 Claude Code 直接叫用的專案 skill。`.gitignore` 另外追蹤 Trellis 的接線(`.claude/` 下的 `agents/`、`commands/`、`hooks/`、`settings.json`);`.claude/` 其餘內容、`.trellis/workspace/`(session 日誌)、`.agents/` 與 `.codex/` 是本機狀態。 +- 審查記錄不進 `docs/`。一輪審計的結論寫進它所描述的檔案、開成 issue,或留在 git 歷史。例外:`docs/audit/` 在重寫期間凍結保留,切換 PR 刪除。 From 889711259c7ea1efea8da05460e1a802012c60f0 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:20:55 +0800 Subject: [PATCH 127/133] docs: align agent notes with the trellis setup --- AGENTS.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c9d372300..f1e35b1ee 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -87,10 +87,10 @@ with a reason, delete it when it goes away. - **Sliders** — build `ScopedSlider`; a raw Material `Slider` freezes the Windows accessibility tree (`docs/troubleshooting.md`) — `test/ui/static_rules/slider_overlay_static_rule_test.dart`. -- **Test waits** — `pumpUntil` for a condition false on entry, - `drainEventQueue` to assert something did *not* happen - (`test/support/pump_until.dart`); a fixed pump count is flaky in both - directions (#43, #55) — `test/support/wait_convention_static_rule_test.dart`. +- **Test waits** — no direct `pumpEventQueue` outside + `test/support/pump_until.dart`: use its `pumpUntil` / `drainEventQueue` + (how: `.trellis/spec/testing/test-conventions.md`; #43, #55) — + `test/support/wait_convention_static_rule_test.dart`. - **Static rules** — a test that reads `lib/` source is named `*_static_rule_test.dart` and lives in `test/support/` or `test/<layer>/static_rules/` — @@ -107,6 +107,13 @@ with a reason, delete it when it goes away. `session_auto_commit: false`; `orca.yaml` shares the main checkout's copy with Orca worktrees); if an update re-adds a journal `merge=union` line to `.gitattributes`, drop it. +- **Managed files left as shipped** — Claude Code runs the customised + `.claude/agents/trellis-check.md`; the `trellis-check` skill and + `.trellis/agents/check.md` are Trellis-generated and not used for FMP work. + With `session_auto_commit: false`, archive and journal steps make no commits: + commit task changes by hand, whatever the Trellis command docs say. The + managed block's `.agents/` and `.codex/` lines do not apply: both are + gitignored local state. <!-- TRELLIS:START --> # Trellis Instructions From 1820109e7fdb9ca52831ea63a80296db9afdd10a Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:24:04 +0800 Subject: [PATCH 128/133] chore(task): refresh the handoff note after phase three --- .../tasks/09-26-fmp-rewrite/phase2-plan.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 3ce52160f..0831fd893 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -250,13 +250,22 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 以上是功能凍結僅有的例外。 - 建立 `1morr/fmp-plugins` repo、其 CI 與 `index.json`、App 插件頁與首次啟動引導:排入里程碑規劃(第 20 步);第一個里程碑不需要。 -## 10. 目前進度與下一步(交接用,2026-09-28 更新,階段二完成) +## 10. 目前進度與下一步(交接用,2026-09-28 更新,階段二、三完成) -- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0026`;舊 ADR 0001–0007 仍描述根目錄舊專案,於切換 PR 刪除。 -- **階段二完成**:§3 的 20 項全部 ✅;每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0027。 +- 分支:`docs/audit`(draft PR #173)。所有設計決定以 ADR 為準:`docs/adr/0008`–`0027`;舊 ADR 0001–0007 仍描述根目錄舊專案,於切換 PR 刪除。 +- **階段二完成**:§3 的 20 項全部 ✅;每項的 prd/design/research 在 `.trellis/tasks/archive/2026-09/09-2?-design-*`。下一份 ADR 編號 0028。 - 里程碑清單與狀態:`.trellis/tasks/09-26-fmp-rewrite/milestones.md`(ADR 0026)。 -- **進行中:階段三(Trellis/docs 清理)**,task `.trellis/tasks/09-28-phase3-docs-cleanup/`(planning);研究代理寫到 `research/`(`current-state.md`、`open-questions.md`),兩個檔齊了才代表研究完成,接著抽查→prd→一次一問。依據是第 9 項的設計(`archive/2026-09/09-27-design-docs` 的 design §4、§6 與 implement §B)與 parent prd 的階段三。範圍:刪 `docs/agents/`、AGENTS.md 的「Agent skills」段、把 CONTEXT.md 併入、修正引用、以 `git grep` 確認沒有殘留。 -- 之後順序:階段三 → M1(里程碑任務,brainstorm 核准一次,底下開 PR 子任務)→ M1 完成後開 Linux 平台任務。 +- **階段三完成**(2026-09-28,`archive/2026-09/09-28-phase3-docs-cleanup`): + - `docs/agents/`、`CONTEXT.md` 已刪;術語移到舊專案的 `.trellis/spec/services/download-and-auth.md` § Auth vocabulary,原則在 ADR 0012; + - 舊 ADR 0001–0007 都加了「只適用舊專案」註記; + - `docs/README.md` 地圖有類型欄與 `audit/` 列; + - AGENTS.md 的 Trellis 段說明哪些管理檔維持原樣; + - 實機驗證規則見 ADR 0027(預設重播)。 + - 語言範圍:根目錄 AGENTS.md 與 spec 維持英文到切換 PR,`app/` 的新文件用繁中。 +- **下一步:M1「骨架+曳光彈」**(`milestones.md`)。建里程碑任務(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite`),走 brainstorm,擁有者核准一次 prd/design/implement,implement 列出 PR 子任務與順序(ADR 0026)。 + - M1 開工時要決定:`app/` 的 spec 放哪(Trellis `packages:` 或其他)。 + - 同時為 `app/` 改寫 verify-on-device(ADR 0027)。 +- 之後順序:M1 → Linux 平台任務 → M2 …(見 `milestones.md`)。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 - 每項固定流程:建 child task(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite --no-start`)→ 派研究子代理(sonnet,寫進 task 的 research/)→ 核對關鍵事實 → prd → 一次一問(附建議與取捨)→ design+implement → 最終摘要 → 使用者「核准」後 `task.py start`、寫 ADR(`docs/adr/template.md`)、更新本檔 §3 標記完成、`task.py finish`+`archive --no-commit --skip-branch-validation`、commit+push。 - 使用者偏好:全程繁中;多數細節「按推薦」,但每項仍需最終摘要與明確核准;Mermaid 圖需以 mermaid-cli 實際渲染(子圖標題含全形括號要用 `id["標題"]`)。 From 2f132e7efbec0af6e7c58d2fddea793078b92763 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:24:04 +0800 Subject: [PATCH 129/133] chore(task): archive phase3-docs-cleanup --- .../09-28-phase3-docs-cleanup/check.jsonl | 0 .../09-28-phase3-docs-cleanup/design.md | 0 .../09-28-phase3-docs-cleanup/implement.jsonl | 0 .../09-28-phase3-docs-cleanup/implement.md | 18 +++++++++--------- .../2026-09}/09-28-phase3-docs-cleanup/prd.md | 0 .../research/current-state.md | 0 .../research/open-questions.md | 0 .../09-28-phase3-docs-cleanup/task.json | 6 +++--- 8 files changed, 12 insertions(+), 12 deletions(-) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/check.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/design.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/implement.jsonl (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/implement.md (59%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/prd.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/research/current-state.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/research/open-questions.md (100%) rename .trellis/tasks/{ => archive/2026-09}/09-28-phase3-docs-cleanup/task.json (88%) diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/check.jsonl b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/check.jsonl similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/check.jsonl rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/check.jsonl diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/design.md b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/design.md similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/design.md rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/design.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/implement.jsonl b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/implement.jsonl similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/implement.jsonl rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/implement.jsonl diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/implement.md b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/implement.md similarity index 59% rename from .trellis/tasks/09-28-phase3-docs-cleanup/implement.md rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/implement.md index 1f32ca105..f1bf7e83b 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/implement.md +++ b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/implement.md @@ -2,25 +2,25 @@ 一個 PR:沿用 `docs/audit` 分支與 draft PR #173。每步一個 commit。 -1. [ ] `docs(adr): 0027 on-device verification`:新增 ADR 0027;ADR 0015、0026 各加一句指向。 -2. [ ] `docs: remove mattpocock skill residue`: +1. [x] `docs(adr): 0027 on-device verification`:新增 ADR 0027;ADR 0015、0026 各加一句指向。 +2. [x] `docs: remove mattpocock skill residue`: - 刪除 `docs/agents/`; - AGENTS.md 的「Agent skills」段改為 `## Issues`。 -3. [ ] `docs: fold CONTEXT.md into ADR 0012`: +3. [x] `docs: fold CONTEXT.md into ADR 0012 and the spec`(術語改放舊專案 spec `download-and-auth.md` § Auth vocabulary,其餘 6 處改指那裡;原則在 ADR 0012): - ADR 0012 補上轉址原則; - 刪除 `CONTEXT.md`; - spec 的 7 處改指 ADR 0012。 -4. [ ] `docs(adr): mark old ADRs as legacy-only`:0001、0003–0006 加註記。 -5. [ ] `docs: rewrite the docs map`:`docs/README.md` 照 design §2 改寫。 -6. [ ] `docs: align agent notes with trellis setup`: +4. [x] `docs(adr): mark old ADRs as legacy-only`:0001、0003–0006 加註記。 +5. [x] `docs: rewrite the docs map`:`docs/README.md` 照 design §2 改寫。 +6. [x] `docs: align agent notes with trellis setup`: - AGENTS.md Trellis 段補三句(`.agents/`/`.codex/`、check 子代理、journal commit); - 「Test waits」縮窄。 -7. [ ] 本機(不進 git): +7. [x] 本機(不進 git)。實際結果:`.agents/` 版的 25 條實測筆記全部已在 `.claude/skills/verify-on-device/` 裡(重整進 `references/`),不需要合併,也沒有這個 commit: - 把 `.agents/` 版的實測筆記併進 `.claude/skills/verify-on-device/references/`,這部分會 commit:`docs(skill): keep measured notes from the local copy`; - 刪除本機 `.agents/`。 -8. [ ] 驗證: +8. [x] 驗證: - design §8 的兩條 `git grep`; - `flutter test test/support/wait_convention_static_rule_test.dart test/support/static_rule_placement_static_rule_test.dart`。 -9. [ ] 更新 parent `phase2-plan.md` §10:階段三完成,下一步 M1。`task.py finish` 後再 `archive --no-commit --skip-branch-validation`,commit,push。 +9. [x] 更新 parent `phase2-plan.md` §10:階段三完成,下一步 M1。`task.py finish` 後再 `archive --no-commit --skip-branch-validation`,commit,push。 回退:全部是文件,revert 對應 commit 即可。本機 `.agents/` 刪除前,實測筆記已併進受版控的 skill。 diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/prd.md b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/prd.md similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/prd.md rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/prd.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/research/current-state.md similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/research/current-state.md rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/research/current-state.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/research/open-questions.md similarity index 100% rename from .trellis/tasks/09-28-phase3-docs-cleanup/research/open-questions.md rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/research/open-questions.md diff --git a/.trellis/tasks/09-28-phase3-docs-cleanup/task.json b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/task.json similarity index 88% rename from .trellis/tasks/09-28-phase3-docs-cleanup/task.json rename to .trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/task.json index f172e8ee6..272daaca8 100644 --- a/.trellis/tasks/09-28-phase3-docs-cleanup/task.json +++ b/.trellis/tasks/archive/2026-09/09-28-phase3-docs-cleanup/task.json @@ -3,7 +3,7 @@ "name": "phase3-docs-cleanup", "title": "Phase 3 docs and Trellis cleanup", "description": "Phase 3: remove mattpocock residue, settle old ADRs and CONTEXT.md, fix Trellis/agent-file conflicts, plan verify-on-device for new platforms", - "status": "planning", + "status": "completed", "dev_type": null, "scope": null, "package": null, @@ -11,8 +11,8 @@ "creator": "1morr", "assignee": "1morr", "createdAt": "2026-09-28", - "completedAt": null, - "branch": null, + "completedAt": "2026-09-28", + "branch": "docs/audit", "base_branch": "main", "worktree_path": null, "commit": null, From 4064e6c47d1c5c81f851241bea7d9ec9f056f637 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:28:05 +0800 Subject: [PATCH 130/133] chore(task): complete the feature freeze backlog list --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 0831fd893..8ee68e3c3 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡、睡眠定時器(ADR 0018);dynamic color(ADR 0024);B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) | ## 2. 依賴關係 From f3ea7ae17f1134bc5884fb5125ab11e08da155c8 Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Mon, 28 Sep 2026 23:38:22 +0800 Subject: [PATCH 131/133] chore(task): note legacy agent files to split in m1 --- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 8ee68e3c3..30cf4bf9e 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -31,7 +31,7 @@ prd 的 18 項,加上從你的勾選裡長出來、需要獨立決定的兩項 | 17 | 快取與離線 | B6 | | 18 | 設定與日誌基礎設施 | C2、J3 | | 19 | 發版與應用內更新(新增) | A6、B7–B9、E17 | -| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡、睡眠定時器(ADR 0018);dynamic color(ADR 0024);B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) | +| 20 | 功能凍結待辦(新增,不設計,只記錄) | 均衡器、響度平衡;B 站 geetest 驗證互動(ADR 0013);邊聽邊存、手動離線模式、已下載內容容量管理(ADR 0016);來源失效時另存為本地歌單、曲目收藏、疑似換版本偵測(ADR 0019);Android 狀態列歌詞、本機歌詞檔匯入(ADR 0021) | ## 2. 依賴關係 @@ -264,6 +264,16 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - 語言範圍:根目錄 AGENTS.md 與 spec 維持英文到切換 PR,`app/` 的新文件用繁中。 - **下一步:M1「骨架+曳光彈」**(`milestones.md`)。建里程碑任務(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite`),走 brainstorm,擁有者核准一次 prd/design/implement,implement 列出 PR 子任務與順序(ADR 0026)。 - M1 開工時要決定:`app/` 的 spec 放哪(Trellis `packages:` 或其他)。 + - **M1 的第一個 PR:指令檔分家**(2026-09-28 盤點,尚未問擁有者,M1 brainstorm 時提出)。舊內容會誤導在 `app/` 工作的 AI: + - 根目錄 AGENTS.md 全是舊專案的規則(`lib/` 路徑、Isar、`AudioController`、舊測試路徑的驗證表)。Claude Code 以 repo 根目錄為工作目錄時,**每個 session 開頭都會載入它**;`app/AGENTS.md` 只在讀到 `app/` 裡的檔案時才載入(code.claude.com/docs/en/memory「When Claude Code reads AGENTS.md」)。 + - `.trellis/spec/` 20 檔描述舊專案;`session-start.py` 會列出 spec 索引,`trellis-implement`/`trellis-check` 子代理依 `.trellis/spec/<package>/<layer>/` 載入。 + - `.claude/skills/verify-on-device/` 對舊專案、打真實 API(M1 依 ADR 0027 改寫)。 + - `docs/building.md`、`development.md`、`build-and-release.md`、`troubleshooting.md`、`orca.yaml` 的 setup、`ci.yml` 都只對舊專案。前四份是按需讀的人類文件,風險較低。 + - 建議做法: + - 根目錄 AGENTS.md 縮成共用部分(repo 地圖:根目錄=凍結舊專案、`app/`=新專案;Issues;ADR 位置;Trellis 段); + - 舊專案規則搬到 `lib/AGENTS.md`,讀舊程式碼時才載入; + - `app/AGENTS.md` 用繁中; + - spec 以 Trellis `packages:` 分成舊專案與 `app`。 - 同時為 `app/` 改寫 verify-on-device(ADR 0027)。 - 之後順序:M1 → Linux 平台任務 → M2 …(見 `milestones.md`)。 - 視覺選擇類的問題可用 Artifact 做示意頁(例:第 5 項的播放頁三方案 https://claude.ai/artifact/WbYKvNKgS2XpJbCuGr9xTZ )。 From e9516edd433e0d0a8fcb5fec5aed80d9677bf6bf Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Tue, 29 Sep 2026 03:27:38 +0800 Subject: [PATCH 132/133] chore(task): plan milestone m1 --- .trellis/tasks/09-26-fmp-rewrite/task.json | 3 +- .../09-28-m1-skeleton-tracer/check.jsonl | 3 + .../tasks/09-28-m1-skeleton-tracer/design.md | 179 +++++ .../09-28-m1-skeleton-tracer/implement.jsonl | 5 + .../09-28-m1-skeleton-tracer/implement.md | 210 +++++ .../tasks/09-28-m1-skeleton-tracer/prd.md | 125 +++ .../research/m1-scope-digest.md | 730 ++++++++++++++++++ .../research/m1-tooling-facts.md | 319 ++++++++ .../tasks/09-28-m1-skeleton-tracer/task.json | 26 + 9 files changed, 1599 insertions(+), 1 deletion(-) create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/check.jsonl create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/design.md create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/implement.jsonl create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/implement.md create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/prd.md create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/research/m1-tooling-facts.md create mode 100644 .trellis/tasks/09-28-m1-skeleton-tracer/task.json diff --git a/.trellis/tasks/09-26-fmp-rewrite/task.json b/.trellis/tasks/09-26-fmp-rewrite/task.json index ee1dbc899..4e7751450 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/task.json +++ b/.trellis/tasks/09-26-fmp-rewrite/task.json @@ -40,7 +40,8 @@ "09-28-design-ui-ux", "09-28-design-debug-page", "09-28-design-milestones", - "09-28-phase3-docs-cleanup" + "09-28-phase3-docs-cleanup", + "09-28-m1-skeleton-tracer" ], "parent": null, "relatedFiles": [], diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/check.jsonl b/.trellis/tasks/09-28-m1-skeleton-tracer/check.jsonl new file mode 100644 index 000000000..10ac832a2 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/check.jsonl @@ -0,0 +1,3 @@ +{"file": ".trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md", "reason": "Per-ADR M1 verification requirements to check against"} +{"file": ".trellis/tasks/09-26-fmp-rewrite/phase2-plan.md", "reason": "Section 7 lists the M1 runtime checks"} +{"file": "docs/adr/0015-testing-gates-and-dev-environment.md", "reason": "Lint, zero-network, CI and flavor gates"} diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/design.md b/.trellis/tasks/09-28-m1-skeleton-tracer/design.md new file mode 100644 index 000000000..08e5bc7ab --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/design.md @@ -0,0 +1,179 @@ +# M1 設計 + +各項行為以 ADR 0008–0027 為準。這份只寫: +- 跨 PR 的結構; +- ADR 留給「開工時決定」的技術選擇; +- 擁有者五個決定的落地方式。 + +「§3.x」指 `research/m1-scope-digest.md` 第 3 節的未定項。 + +## 1. 指令檔與 spec 分家(PR 1,擁有者決定 1) + +分家後的樣子: + +| 路徑 | 內容 | 何時載入 | +|---|---|---| +| `AGENTS.md` | 英文。repo 地圖(根目錄=凍結的舊專案,只收緊急修正;`app/`=新專案;`docs/adr/`;`.trellis/`)、Issues、ADR 規則(沒有已確認的 ADR 不寫程式碼;新決定寫新 ADR)、Trellis 段 | 每個 session | +| `lib/AGENTS.md` | 現在根目錄的 Verification、Conventions、Boundaries 原封搬來;路徑維持相對 repo 根的寫法 | 讀到 `lib/` 的檔案時 | +| `app/AGENTS.md` | 繁中,PR 2 建立,之後每個 PR 補自己那一層 | 讀到 `app/` 的檔案時 | + +- 根目錄地圖寫明:「改舊專案先讀 `lib/AGENTS.md`;在 `app/` 工作先讀 `app/AGENTS.md`」。 + - 理由:子目錄的 AGENTS.md 只在讀到該目錄的檔案時才載入(Claude Code memory 文件)。只改 `test/` 的舊專案修正可能不會觸發 `lib/AGENTS.md`,這句用來補上。 +- 根目錄 Trellis 段的「Rules vs patterns」「`trellis update`」兩條留在根目錄。它們指向的 § Verification 改成「任務所屬 package 的 `AGENTS.md` § Verification/§ 驗證」。 +- 舊 spec 搬家:`git mv .trellis/spec/{data,services,shared,testing,ui} .trellis/spec/legacy/`,`guides/` 留在原地共用。 + - 更新所有引用: + - `lib/AGENTS.md`(例如 `test-conventions.md`); + - `docs/README.md`; + - spec 之間的相對連結; + - `.claude/agents/*`; + - `.trellis/workflow.md` 內 FMP 自己加的段落。 + - Trellis 管理檔(`.trellis/.template-hashes.json` 列的)不改。 +- `.trellis/config.yaml`: + ```yaml + packages: + legacy: + path: . + app: + path: app + default_package: app + ``` + - package 名不用 `data` 或 `.`。研究查過:spec 目錄名取自 package 名;取 `data` 會回報 `Spec: not configured`,取 `.` 會讓掃描指到 spec 根。 + - 現有的 active task(`09-26-fmp-rewrite`、本任務)在 `task.json` 補 `"package": "app"`;兩者都不寫舊專案程式碼。 +- `app/` 的 spec 在 PR 2 建 `.trellis/spec/app/index.md`,各層寫到時再加 `.trellis/spec/app/<layer>/index.md`(繁中)。 +- `.claude/agents/trellis-implement.md`、`trellis-check.md` 是本機客製檔,可以改: + - 驗證步驟改成「讀 `task.json` 的 package:legacy 跑 `lib/AGENTS.md` § Verification,app 跑 `app/AGENTS.md` § 驗證」; + - spec 路徑改成 `.trellis/spec/<package>/<layer>/`。 +- skill:`git mv .claude/skills/verify-on-device .claude/skills/verify-legacy-on-device`。 + - 同步改 SKILL.md 的 `name:` 與 description,說明只給舊專案緊急修正用。 + - 更新引用:`lib/AGENTS.md`、`docs/README.md`。 + - `verify-on-device` 這個名字在 PR 11 由 `app/` 版使用。 +- 其他引用: + - `orca.yaml:14` 的註解改指 `lib/AGENTS.md`; + - 舊專案沒有測試讀 `AGENTS.md` 或 spec 的路徑(已搜尋 `test/`、`tool/`、`lib/`、`.github/`)。 +- 閘門: + - PR 1 的驗證: + - `flutter test --exclude-tags live test/support test/workflows`; + - 搜尋舊路徑 `.trellis/spec/(data|services|shared|testing|ui)/` 與 `skills/verify-on-device`,除了 archive 任務之外不得殘留; + - 開一個新 session,確認 SessionStart 只列出 `guides` 與 `app` 的 spec 索引。 +- 同一個 PR 更正 ADR 的事實錯誤,只加補充句、不改決定: + - ADR 0021:`window_manager` 0.5.2 仍在發佈; + - ADR 0015:issue 改引 flutter/flutter#187999; + - ADR 0027:舊 skill 改名 `verify-legacy-on-device`。 + +## 2. `app/` 的結構 + +``` +app/ + AGENTS.md + pubspec.yaml # flutter: default-flavor: dev;resolution: workspace + analysis_options.yaml # plugins: fmp_lints(頂層 plugins:,非 analyzer:) + dart_test.yaml # tags: live: skip(ADR 0015 §決定 3) + CHANGELOG.md # release-please(PR 13) + lib/ + main.dart # 由 flavor 決定身分;組 ProviderScope(retry 關閉) + app/ # MaterialApp、路由、外殼、ToastHost + core/ # logging/、redaction/、errors/、network/、settings/ + data/ # drift database、tables、repositories + domain/ # TrackKey 等純型別 + platform/ # 每能力一目錄:<能力>.dart+<能力>_<平台>.dart + plugins/ # JS runtime、宿主 API、manifest、SourcePlugin 轉接 + playback/ # PlaybackController、AudioBackend 兩實作、QueueModel 最小集 + ui/ # theme/(AppTokens、AppLayout)、shell/、search/、settings/、player_bar/、toast/ + i18n/ # slang:zh-TW(base)、zh-CN、en + packages/ + fmp_lints/ # analysis_server_plugin;analyzer_testing 測試 + plugin_contract/ # 契約執行器(重播 fixture 跑 checks.json) + test/ + flutter_test_config.dart # HttpOverrides.global 擋真實 HttpClient + fixtures/plugins/test_plugin/ # 合成資料、播放本機音檔 + integration_test/ +``` + +- 第一層目錄以 ADR 已定的名稱為準:`platform/`、`core/logging/`、`core/redaction/`、`legacy_import/`(M5 才建)、`packages/fmp_lints/`。 +- 其他目錄照上表,`fmp_layer_imports` 的依賴表在 PR 3 寫成規則。 +- Dart pub workspace:`app/` 是 workspace 根,`packages/*` 是成員。`analysis_server_plugin` 的 `plugins:` 只能寫在 package 或 workspace 根(研究 Part B)。 + +## 3. 技術選擇(ADR 留給開工時決定的) + +| § | 項目 | 決定 | 理由 | +|---|---|---|---| +| 3.2 | Flutter 版本 | `app/` 用 3.47.5(Dart 3.13.4),CI 的 `app` job 釘這版;舊專案 job 維持 3.47.1。本機升到 3.47.5,舊專案同一個 minor,照常建置 | ADR「當時的 stable」 | +| 3.4 | `AuthRequirement` | M1 建型別與宣告點(manifest、請求 DTO),認證攔截器在沒有 `CredentialStore` 時一律不注入;`CredentialStore` 與三種標記的注入測試在 M3 | B 站搜尋與解串流不需登入;宣告點是插件 API 的一部分,晚加會改 DTO | +| 3.5 | `PermissionGateway` | M1 不建 | M1 沒有需要執行期權限的功能;ADR 0009「不寫空實作」 | +| 3.6 | 串流網址快取 | M1 不建;`StreamResolver` 每次呼叫插件 | ADR 0016 整包在 M2;兩首的佇列用不到 | +| 3.8 | log 檔格式 | 一開始就寫 JSON Lines(ADR 0025 §決定 3 的欄位),2MB×3 | 先寫純文字、M3 再改,等於改兩次;7 天保留仍在 M2 的維護清單 | +| 3.9 | M1 的 lint | 十條核心規則全做,加 `fmp_toast_entry`、`fmp_design_tokens`;`fmp_periodic_timer_owner` 留到 M2 | 規則要在第一批程式碼寫進來前就位,事後補會先累積違規;`BackgroundScheduler` 在 M2 | +| 3.10 | 最小 schema | 見下表 | M1 只持久化需要跨重啟的東西 | +| 3.11 | isar/sqlite3 共存 | PR 5 期間開探針分支:加 `isar_community` 3.3.2+`sqlite3` 3.x,在 Android、Windows 建置並開兩個庫;檢查 APK 內 `.so` 的 16KB 對齊(`zipalign -c -P 16`)。結論寫進研究檔,不合併 | ADR 0010 規定 `isar_community` 只能在 `legacy_import/`(M5) | +| 3.13 | `material_ui` | PR 2 依 3.47.5 的官方遷移文件決定 import 路徑,寫進 `app/AGENTS.md` | ADR 0024 | +| 3.14 | `window_manager` | 用 pub 的 0.5.2;`tray_manager` 0.7.0 的 `nativeapi` 改寫留到 M8 | 0.5.2 仍在發佈(已查證) | +| 3.15 | 契約執行器與 QuickJS | PR 9 先試 `flutter test` 內載入(CI 先建置桌面產物,再設 `PATH`/`LIBQUICKJSC_TEST_PATH`);不行就照 ADR 0015 改用桌面 `integration_test`。結果寫進 `app/AGENTS.md` 的驗證段 | ADR 0015 把這題留給 M1 實測 | +| 3.16 | 兩首的佇列 | 只在記憶體、只有 `queue` 模式、依序播放、不持久化;`QueueModel` 的介面照 ADR 0018,M2 補齊 | M2 才做完整佇列 | +| — | 系統媒體控制 | M1 不做(`audio_service`、SMTC 在 M2);Android 只驗前景播放與換歌不放音訊焦點 | 屬 M2 | +| — | `orca.yaml` | PR 2 在 setup 加上 `app/` 的 `flutter pub get` 與 `dart run slang`,舊專案的步驟不動 | Orca worktree 要能直接跑 `app/`;切換 PR 再移除舊步驟 | + +M1 的 drift 表: + +| 表 | 用途 | ADR | +|---|---|---| +| `appearance_settings`(單列) | 主題模式、語言;欄位空=沒設定過 | 0011 §決定 7;擁有者決定 2 | +| `installed_plugins` | 從檔案安裝的插件:id、版本、manifest JSON、腳本、安裝時間 | 0014 | +| `plugin_storage` | 每插件的 key/value;B 站匿名 `buvid` 放這裡 | 0014 §決定 5、0012 §決定 1 | + +- `tracks` 等音樂庫表留到 M4。`TrackKey` 在 M1 是 `domain/` 的純型別加測試,佇列用它當身分。 +- schema 從 v1 起用 `drift_dev schema dump` 存快照,CI 驗證快照與程式碼一致。 + +## 4. B 站插件與 `1morr/fmp-plugins`(擁有者決定 5) + +- PR 9 之前建立公開 repo `1morr/fmp-plugins`,只放 `README.md`(繁中,寫明開發中)與 `bilibili/`: + - `manifest.json`; + - `index.js`; + - `fixtures/`; + - `checks.json`。 +- 插件以舊專案 `lib/data/sources/bilibili*` 為規格,用 JS 重寫(ADR 0008 檔頭補充)。M1 只需要 `search` 與 `resolveStream` 兩個能力。 +- fixture 以真實連線錄製一次(ADR 0027 §決定 2),寫檔前經遮蔽函式;提交前人工確認沒有 cookie 或 token 原值。 +- fmp-plugins 的變更以該 repo 自己的 PR 合併,本機跑 `app/packages/plugin_contract` 的執行器驗證。 + +## 5. CI(PR 2 起逐步擴充) + +- `ci.yml` 改成兩半,用 `dorny/paths-filter@v4` 分流(ADR 0015 §決定 9): + - 舊專案的三個 job 原樣保留,只在 `app/` 以外有變動時跑; + - `app` 的 job 由 `app/**` 與 `.github/**` 觸發; + - 最後一個 `always()` 彙總 job 是唯一必要檢查。 +- 彙總 job 的判斷:被跳過的 job 算通過,失敗或取消的算失敗。 +- `main` 的 ruleset `protect-main` 目前只有 `deletion` 與 `non_fast_forward`,沒有必要檢查(2026-09-29 查)。 + - PR 2 合併後,在 ruleset 加上 `required_status_checks`,只列彙總 job,照 ADR 0015 的「唯一必要檢查」。 + - 這是擁有者自己 repo 的設定,直接改。 +- `app` job 隨 PR 增加步驟: + + | PR | 加入的步驟 | + |---|---| + | 2 | format、`flutter analyze`、`flutter test` | + | 3 | `dart analyze --fatal-infos`、接線哨兵、lint 規則測試 | + | 5 | schema 快照檢查 | + | 9 | 契約執行器 | + | 13 | 五平台建置、Linux 與 Windows 整合測試 | + +- 發版 workflow `app-release.yml`(擁有者決定 4): + - 只有 `workflow_dispatch`,沒有 push 觸發; + - 內容照 ADR 0022 §決定 1、3、4; + - 在 `1morr/fmp-release-sandbox` 用同一份檔案跑通,那邊加上 push 觸發與臨時金鑰; + - sandbox 驗完封存。 + +## 6. `app/` 的 verify-on-device(PR 11,ADR 0027) + +- 新的 `.claude/skills/verify-on-device/`: + - `SKILL.md`:閉環「啟動 → 執行 → 觀察 → 操作 → 收尾」; + - `references/android.md`、`references/windows.md`; + - `references/runtime-state.md`:改成 drift 與 dev flavor 的資料目錄。 +- 預設:dev flavor 加測試插件或重播模式。真實連線只在 ADR 0027 §決定 2 的條件下使用。 +- 回報格式必含「平台」與「模式:重播/真實」。 +- `scripts/` 的三支工具(AX/MSAA/SMTC)與平台有關、與專案無關,從舊 skill 複製一份。舊 skill 要原樣留給緊急修正,所以不共用。 +- 每插件切換「真實、錄製、重播」是 M3 的插件開發工具(ADR 0015 §決定 7、ADR 0025)。 +- M1 不另做切換機制,UI 與播放的實機驗證改用測試插件,這是 ADR 0027 §決定 1 允許的另一條路。 +- B 站插件本身的端到端驗證屬「改動是插件」,用真實連線,只做最少操作。 + +## 7. 回滾 + +- 每個 PR 獨立合併,`app/` 以外只動 `ci.yml`、`orca.yaml`、指令檔與 spec。舊專案的程式與 `release.yml` 不動,緊急修正路徑不受影響。 +- PR 1 的搬家與 PR 2 的 CI 改動是 M1 裡唯二會影響舊專案工作流程的地方,各自可以單獨 revert。 diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/implement.jsonl b/.trellis/tasks/09-28-m1-skeleton-tracer/implement.jsonl new file mode 100644 index 000000000..a3f33de34 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/implement.jsonl @@ -0,0 +1,5 @@ +{"file": ".trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md", "reason": "Per-ADR M1 scope, fixed names, dependency order"} +{"file": ".trellis/tasks/09-28-m1-skeleton-tracer/research/m1-tooling-facts.md", "reason": "Package versions and Trellis packages mechanism as of 2026-09-28"} +{"file": ".trellis/tasks/09-26-fmp-rewrite/milestones.md", "reason": "M1 scope and acceptance"} +{"file": "docs/adr/0026-milestones-and-cut-over.md", "reason": "Milestone and PR child task structure"} +{"file": "docs/adr/0027-on-device-verification.md", "reason": "On-device verification rules for app/"} diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/implement.md b/.trellis/tasks/09-28-m1-skeleton-tracer/implement.md new file mode 100644 index 000000000..29501cc56 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/implement.md @@ -0,0 +1,210 @@ +# M1 執行計畫 + +## 通用規則(每個 PR 子任務) + +- **開工**: + - 從最新的 `main` 開分支; + - 以 `task.py create "<標題>" --slug <slug> --parent .trellis/tasks/09-28-m1-skeleton-tracer --package app` 建子任務; + - prd 只寫做什麼與驗收(ADR 0026 §決定 1),在已核准範圍內直接做,遇到未定的事才問。 +- **合併條件**: + - `app/` 可編譯、`flutter test` 全綠; + - CI 彙總 job 通過; + - PR 描述附 review 指南。 +- **實機驗證**:使用者看得到的 PR 在 Android 模擬器與 Windows 都驗,回報寫明平台與模式(ADR 0027)。 +- **收尾**: + - 子任務 `finish` 與 `archive --no-commit --skip-branch-validation`; + - 手動 commit; + - repo 慣例是以 merge commit 合併。 +- **文件**: + - 每個 PR 更新 `app/AGENTS.md` 中自己那一層(只寫查不到的契約與有閘門的規則,ADR 0015 §如何確認); + - 需要時更新 `.trellis/spec/app/<layer>/`。 +- **套件版本**:以 `research/m1-tooling-facts.md` 為起點,加依賴時再到 pub.dev 核對一次。 +- **子代理模型**(擁有者 2026-09-29 核准): + - 實作用 sonnet:PR 1、11。都是機械性工作;PR 1 的內容刪減由主對話決定。 + - 實作用 opus:PR 2–10、12、13 與 YouTube.js 探針。 + - `trellis-check` 一律 opus;研究代理一律 sonnet。 + +## 順序 + +### 0. 合併 #173(設計文件進 `main`) + +- [ ] 本任務的規劃檔 commit 到 `docs/audit`,push。 +- [ ] #173 轉為 ready,以 merge commit 合併;本機 `main` 更新。 +- 驗證:`main` 上有 `docs/adr/0027-*.md` 與本任務目錄。 + +### 1. 指令檔分家(design §1) + +- [ ] 根目錄 `AGENTS.md` 縮成共用部分;`lib/AGENTS.md` 收舊規則。 +- [ ] `git mv` 舊 spec 到 `.trellis/spec/legacy/`,更新全部引用。 +- [ ] `config.yaml` 宣告 `packages:`;兩個 active task 補 `"package": "app"`。 +- [ ] `trellis-implement.md`、`trellis-check.md` 的驗證步驟改成照 package 讀對應的 AGENTS.md。 +- [ ] skill 改名 `verify-legacy-on-device`。 +- [ ] ADR 0015、0021、0027 的更正補充句;`docs/README.md` 地圖更新。 +- 驗證: + - `flutter test --exclude-tags live test/support test/workflows`; + - 舊路徑搜尋歸零,archive 任務除外; + - 新 session 的 SessionStart 只列 `guides` 與 `app` 的 spec 索引。 + +### 2. `app/` 骨架 + +- [ ] 本機 Flutter 升到 3.47.5;舊專案 `flutter test --exclude-tags live` 仍全綠。 +- [ ] `flutter create`,加上: + - pub workspace; + - flavor dev/prod 與 `default-flavor: dev`; + - App 身分(ADR 0008、0015 §決定 8); + - 資料目錄的 `-dev` 命名空間。 +- [ ] 單一實例鎖(Windows)。 +- [ ] 零聯網兩道防線:`dart_test.yaml`、`flutter_test_config.dart`。 +- [ ] `material_ui` import 路徑的決定。 +- [ ] `app/AGENTS.md`、`.trellis/spec/app/index.md`。 +- [ ] `ci.yml` 以 paths-filter 分兩半,加 `app` 的 format/analyze/test 與 `always()` 彙總;合併後在 ruleset 設彙總 job 為必要檢查。 +- [ ] `orca.yaml` 加入 `app/` 的 setup。 +- 測試: + - prod 身分等於 ADR 0008、dev 每一項都不同; + - dev 拒絕舊版正式資料路徑; + - 故意聯網的測試被跳過,解除 tag 後被擋。 +- 實測(§7): + - dev 與 prod 同時開啟時,身分、鎖、資料目錄各自獨立(Windows); + - Android 裝 dev 與 prod 兩個 App。 + +### 3. `fmp_lints` + +- [ ] `app/packages/fmp_lints/`: + - 十條核心規則,加 `fmp_toast_entry`、`fmp_design_tokens`; + - 每條都用 `analyzer_testing` 做雙向變異測試。 +- [ ] 接線哨兵;CI 加 `dart analyze --fatal-infos`。 +- [ ] `riverpod_lint` 接上新插件系統。 +- 實測(§7):`dart analyze` 看得到插件診斷、`flutter analyze` 看不到(#187999),哨兵會紅。 + +### 4. 平台層 + +- [ ] `lib/platform/`:`PlatformCapabilities`、目錄規則、單一實例、字型 fallback 提供者;Android 與 Windows 實作,其他平台宣告「沒有」。 +- 測試:能力宣告、目錄規則;`fmp_platform_checks` 已在 PR 3 生效。 + +### 5. drift + +- [ ] `appearance_settings`、`installed_plugins`、`plugin_storage`: + - `PRAGMA foreign_keys = ON`; + - v1 schema 快照; + - repository。 +- [ ] `TrackKey`(`domain/`)照舊版格式,加測試。 +- [ ] 探針分支:`isar_community`+`sqlite3` 共存、16KB 對齊,結論寫進本任務 `research/`。 +- 測試:快照一致;設定「使用者值不被新預設蓋掉」(ADR 0011)。 + +### 6. 設定與 log + +- [ ] 設定的 Notifier 模式(外觀組)。 +- [ ] log 門面、遮蔽函式;log 檔:JSON Lines、2MB×3、在 `logs/`。 +- 測試:遮蔽,含 stackTrace(ADR 0011 §如何確認);檔案輪替;壞行略過。 + +### 7. 錯誤模型 + +- [ ] sealed `AppError` 十個子類;`ProviderScope` retry 關閉;重試策略的純函數(退避、`Retry-After`、只重試冪等請求)。 +- 測試:ADR 0013 §如何確認,M1 可測的部分。 + +### 8. 網路層 + +- [ ] API client 與媒體 client、攔截器順序、轉址規則(manifest 網域、最多 5 跳)、網路紀錄。 +- [ ] `AuthRequirement` 型別與宣告點。 +- 測試: + - 媒體請求不帶 Cookie/Authorization; + - manifest 網域外的請求被拒; + - 轉址超過 5 跳或出網域會失敗。 + +### 9. JS 執行環境與插件 + +- [ ] 在 `lib/plugins/` 建 `flutter_js`: + - 宿主 API v1 最小集; + - manifest 驗證; + - `apiVersion` 相容檢查; + - 從檔案安裝。 +- [ ] TypeScript 型別定義。 +- [ ] `packages/plugin_contract/`:契約執行器、fixture 格式、`checks.json`。 +- [ ] `test/fixtures/plugins/test_plugin/`:合成資料、本機音檔。 +- [ ] 建立 `1morr/fmp-plugins`: + - `bilibili/` 的 `search`、`resolveStream`; + - 錄一次 fixture(真實連線,最少操作)。 +- 實測(§7): + - `flutter_js` 在 Android、Windows 的 Promise、記憶體、啟動成本; + - 契約執行器能否在 `flutter test` 內載入 QuickJS;決定後,CI 加入契約執行器。 +- 測試: + - 能力與匯出一致; + - 讀不到其他插件的 storage; + - fixture 掃描不得有未遮蔽的憑證。 + +### 探針:YouTube.js(擁有者決定 3) + +- [ ] 9 合併後開一個子任務,時限約 2–3 個 session。 +- [ ] 分支不合併,結論寫進研究檔。 +- [ ] ADR 0014 補一句結論。 + +### 10. 播放核心最小集 + +- [ ] 播放核心: + - `PlaybackController`; + - sealed 播放狀態; + - `AudioBackend` 與 `JustAudioBackend`、`MediaKitBackend`; + - 兩首、只在記憶體的 `QueueModel`; + - `StreamResolver` 直接呼叫插件。 +- [ ] 前瞻交接:後端只持有「目前+一個前瞻」。 +- 測試:後端契約測試(純規則跑兩個實作與假後端)。 +- 實測(§7): + - 兩個後端的 gapless 交接; + - Android 換歌時不釋放音訊焦點。 + +### 11. `app/` 的 verify-on-device(design §6) + +- [ ] 新 skill、`references/android.md`、`references/windows.md`、`references/runtime-state.md`。 +- [ ] `app/AGENTS.md` 的驗證段(ADR 0027 §如何確認)。 +- 驗證:用新 skill 在兩個平台啟動 dev 版到首頁。 + +### 12. UI(擁有者決定 2) + +- [ ] 主題與字串: + - `AppTokens`、`AppLayout`; + - `WindowClass`; + - 字型 fallback; + - slang 三語言。 +- [ ] `Toaster`、`ToastHost`。 +- [ ] 外殼(兩個導覽項)、搜尋頁、設定頁的外觀組、播放列。 +- [ ] 快捷鍵與 F6 三區。 +- 測試: + - 三語言 key 集合相同; + - Toast 去重、取代與時長; + - 全螢幕頁與對話框之上可見; + - 空白鍵在輸入框只輸入空格; + - F6 在三區之間移動; + - 淺色與深色的點擊區、對比度 guideline。 +- 實測(§7): + - Windows Narrator 下提示不凍結無障礙樹; + - Windows 繁中字形由正黑體顯示; + - 兩平台搜尋 B 站並連續播兩首(真實連線,最少操作)。 + +### 13. 五平台建置與發版 workflow(擁有者決定 4) + +- [ ] CI 加入: + - Linux、macOS、iOS(不簽名)建置; + - Linux 與 Windows 的整合測試:搜尋→播放、從檔案安裝插件,用測試插件。 +- [ ] `app-release.yml`(只有 `workflow_dispatch`)與 release-please 設定: + - `app/CHANGELOG.md`; + - manifest; + - `dart` 策略。 +- [ ] 建立私人的 `1morr/fmp-release-sandbox`,完整跑一次後封存,結果寫進研究檔。 +- 測試:ADR 0022 §如何確認中的 workflow 檢查(檔名集合、checksums、舊版更新器相容)。 + +## 里程碑驗收(13 之後) + +- [ ] Android、Windows 端到端操作。 +- [ ] 逐項勾 phase2-plan §7,在 PR 描述或研究檔找到每項的實測紀錄。 +- [ ] 更新 `milestones.md` 的 M1 狀態與勾選;開 Linux 平台任務。 +- [ ] 本任務 `finish`、`archive`。 + +## 風險與回滾點 + +| 風險 | 處理 | +|---|---| +| QuickJS 無法在 `flutter test` 內載入 | ADR 0015 的退路:契約執行器改用桌面 `integration_test`,CI job 改在 Windows/Linux | +| isar 與 sqlite3 原生庫衝突 | ADR 0010 的退路:legacy import 改成獨立一次性小程式;M5 前決定 | +| `flutter_js` 在 Android 的記憶體或啟動成本過高 | 實測數字交擁有者,必要時另開 ADR 討論引擎 | +| B 站限流或風控擋住錄製 | 錄製只做最少操作;卡住時改用測試插件完成 UI 與播放驗證,B 站部分具名回報 blocker | +| PR 1 的搬家讓 Trellis hook 或舊工作流壞掉 | PR 1 單獨 revert | diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/prd.md b/.trellis/tasks/09-28-m1-skeleton-tracer/prd.md new file mode 100644 index 000000000..5c5aa0fe5 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/prd.md @@ -0,0 +1,125 @@ +# M1 骨架+曳光彈 + +## 目標 + +在 `app/` 建出新專案的骨架,接上所有基礎建設。做完時,Android 與 Windows 上能搜尋 B 站並連續播放兩首(ADR 0026)。 + +## 背景 + +- 範圍與驗收的來源: + - `../09-26-fmp-rewrite/milestones.md` § M1; + - `../09-26-fmp-rewrite/phase2-plan.md` §7(M1 的必要驗證)。 + - 行為以 ADR 0008–0027 為準。 +- 研究(已抽查): + - `research/m1-scope-digest.md`:各 ADR 的 M1 範圍、相依順序、19 項未定之處; + - `research/m1-tooling-facts.md`:2026-09-28 的套件版本、Trellis `packages:` 機制。 +- 結構(ADR 0026 §決定 1): + - 本任務是里程碑任務,擁有者核准一次 prd/design/implement; + - 每個 PR 是本任務的 child,一個分支、一個 PR,合進 `main`。 +- `app/` 還不存在。 +- ADR 全在 `docs/audit`(draft PR #173),還沒進 `main`。#173 只改文件與 `.trellis/`,所以 M1 第一步是合併它。 +- 舊內容會誤導在 `app/` 工作的 AI: + - 根目錄 AGENTS.md 全是舊專案規則,每個 session 都會載入。 + - 舊 spec 會被 Trellis 注入。即使宣告了 `packages:`,`session-start.py:680-682` 仍會先把扁平的 `.trellis/spec/<layer>/index.md` 全部加入,之後才做 package 篩選(`:685`)。 + - `trellis-check.md:86` 寫死扁平 spec 路徑與「AGENTS.md § Verification」。 +- 與 ADR 或現況不符、M1 要處理的事實: + - Flutter stable 是 3.47.5;本機與舊專案 CI 是 3.47.1。 + - `window_manager` 0.5.2 於 2026-07 發佈,ADR 0021「0.5.x 已停止維護」有誤。 + - `flutter analyze` 的插件診斷 issue 是 flutter/flutter#187999,ADR 0015 引用的 #193203 已以重複關閉。 + - release-please-action v5 沒有 dry-run。 + - `flutter_js` 在 `flutter test` 內要先建置桌面產物,並把 QuickJS 原生庫放進 `PATH`。 + - `main` 的 ruleset 沒有必要檢查。 + +## 擁有者的決定 + +1. **指令檔分家**(2026-09-28):M1 第 1 個 PR 一次做完,那時 `app/` 還沒有程式碼。 + - 根目錄 `AGENTS.md` 縮成共用部分,並寫明「改舊專案先讀 `lib/AGENTS.md`」。 + - 舊規則原封搬到 `lib/AGENTS.md`;`app/AGENTS.md` 用繁中。 + - 舊 spec 搬到 `.trellis/spec/legacy/`,`app/` 的 spec 在 `.trellis/spec/app/`,並宣告 `packages:`。 + - 舊 skill 改名 `verify-legacy-on-device`;`verify-on-device` 的名字給 `app/` 的新版。 +2. **M1 的畫面**(2026-09-28):照 ADR 0024 蓋真正的外殼,只放能用的東西。 + - 導覽「搜尋」「設定」兩項,照寬度切換樣式。 + - 搜尋頁:點一首就從它開始播,下一首接著播。 + - 設定頁只有外觀組(主題模式、語言)。 + - 播放列:封面、曲名、上傳者、上一首、播放暫停、下一首、進度條。 + - 快捷鍵:空白鍵、Ctrl+←/→、Shift+←/→、Ctrl+F、Ctrl+,、F6。 +3. **YouTube.js 探針**(2026-09-29): + - 時限約 2–3 個 session,不延長;第 9 個 PR 之後和其他 PR 並行。 + - 過關標準,Android 與 Windows 都要做到: + - 能載入 YouTube.js; + - 搜尋有結果; + - 解出的音訊網址 FMP 播得出聲音; + - 不需要登入,也不需要另外生成 PO token。 + - 效能數字只記錄。 + - 程式碼不合併;失敗時 M3 以 Dart 實作。 +4. **發版 workflow**(2026-09-29): + - 在私人的 `1morr/fmp-release-sandbox` 用臨時簽名金鑰完整跑一次,驗完封存。 + - FMP 裡的 workflow 只能手動觸發,M9 才開啟自動觸發,以守住「重寫期間不發版」。 +5. **B 站插件**(2026-09-29): + - M1 就建公開的 `1morr/fmp-plugins`,只放 README 與 `bilibili/`; + - CI、`index.json`、插件頁留在 M3。 + +## 需求 + +- **R1**:PR 1 完成指令檔與 spec 分家(決定 1,design §1),同時更正 ADR 0015、0021、0027 的事實。 +- **R2**:`app/` 骨架,包含: + - flavor 與 App 身分; + - 單一實例鎖; + - 零聯網兩道防線; + - `app/AGENTS.md`; + - CI 分流與彙總 job,並設為必要檢查; + - `orca.yaml` 的 `app/` setup。 +- **R3**:`fmp_lints` 十條核心規則加 `fmp_toast_entry`、`fmp_design_tokens`,每條有雙向變異測試;接線哨兵。 +- **R4**:平台層與能力宣告(Android、Windows 實作),以及目錄規則。 +- **R5**:drift 最小 schema(`appearance_settings`、`installed_plugins`、`plugin_storage`)、快照、`TrackKey`;另跑 isar/sqlite3 共存探針。 +- **R6**: + - 設定 Notifier; + - log 門面與遮蔽函式; + - JSON Lines 的 log 檔(2MB×3)。 +- **R7**:`AppError` 與重試策略;Riverpod 自動重試關閉。 +- **R8**:網路層(API client、媒體 client、轉址規則、網路紀錄)與 `AuthRequirement` 宣告點;不含登入。 +- **R9**: + - JS 執行環境與宿主 API v1 最小集; + - 從檔案安裝插件; + - 契約執行器、fixture、`checks.json`、測試插件; + - `fmp-plugins` 的 B 站插件(`search`、`resolveStream`)。 +- **R10**:播放核心最小集:`PlaybackController`、兩個後端、兩首只在記憶體的佇列、前瞻交接。 +- **R11**:`app/` 版 verify-on-device 與 `app/AGENTS.md` 的驗證段(ADR 0027)。 +- **R12**:UI(決定 2),包含 token、斷點、字型、slang 三語言、`Toaster`、快捷鍵與 F6。 +- **R13**:CI 五平台建置與整合測試;`app-release.yml` 與 sandbox 驗證(決定 4)。 +- **R14**:YouTube.js 探針(決定 3)。 + +技術選擇與 PR 順序見 `design.md`、`implement.md`。 + +## 驗收 + +- [ ] Android、Windows 端到端操作:搜尋 B 站,點一首,兩首連續播完。 +- [ ] phase2-plan §7 每一項都有實測紀錄: + - [ ] ADR 0010:`isar_community`+`sqlite3` 在 Android、Windows 共存;`sqlite3` 的 Android 16KB page size 對齊。 + - [ ] ADR 0009:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 + - [ ] ADR 0008:prod 的 App 身分與舊版一致,dev 不同。 + - [ ] ADR 0011:log 門面與遮蔽函式,含遮蔽測試。 + - [ ] ADR 0014: + - `flutter_js` 與宿主 API 最小集; + - 從檔案安裝 B 站插件; + - Android、Windows 的 Promise、記憶體、啟動成本實測; + - YouTube.js 探針有結論。 + - [ ] ADR 0018:兩個後端的前瞻交接;Android 換歌時不釋放音訊焦點。 + - [ ] ADR 0015: + - `dart analyze` 看得到插件診斷,哨兵會紅; + - 契約執行器與 QuickJS 的結論; + - dev 與 prod 同時開啟時各自獨立; + - 零聯網兩道防線。 + - [ ] ADR 0022:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布在 sandbox 跑通。 + - [ ] ADR 0023:提示在全螢幕頁與對話框之上可見;Windows Narrator 下不凍結無障礙樹。 + - [ ] ADR 0024:輸入框內空白鍵只輸入空格;F6 焦點切換;Windows 繁中字形由正黑體顯示。 +- [ ] 新 session 的 SessionStart 只列 `guides` 與 `app` 的 spec 索引(R1)。 +- [ ] `milestones.md` 的 M1 狀態與勾選已更新,並開好 Linux 平台任務。 + +## 不在範圍 + +- 播放頁、音量、隨機、循環、輸出裝置、右側面板、系統媒體控制、串流網址快取、佇列持久化(M2)。 +- 登入與 `CredentialStore`、YouTube 與網易雲插件、`fmp-plugins` 的 CI 與 `index.json`、插件頁、Debug 頁(M3)。 +- 其他設定組的欄位、音樂庫表(M4 以後);`PermissionGateway`(M6)。 +- Linux、macOS、iOS 的實作檔與實機驗證(各平台任務)。 +- 舊專案的程式、`release.yml`、舊 skill 的內容(切換 PR 前只收緊急修正)。 diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md b/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md new file mode 100644 index 000000000..eb98b25f8 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-scope-digest.md @@ -0,0 +1,730 @@ +# M1 骨架+曳光彈:ADR 0008–0027 範圍摘要 + +> 目的:讓 planner 把 M1 拆成 PR 大小的 child task。本檔只彙整既有 ADR 與計畫的內容,不新增決定。 +> 來源:`.trellis/tasks/09-26-fmp-rewrite/milestones.md` §M1、`phase2-plan.md` §7/§8/§9/§10、`docs/adr/0008`–`docs/adr/0027`。 +> 格式:每則 ADR 分四段——(a) M1 要做的、(b) M1 的驗證、(c) 不在 M1、(d) ADR 已固定的具體名稱(路徑、類別、套件、檔名)。 +> 只寫 ADR 有寫的;ADR 沒寫而由 milestones.md/phase2-plan 補的,來源標 milestones.md/phase2-plan。 +> 標「與 M1 無關」者會寫明它屬於哪個里程碑,避免 planner 誤收。 + +## 0. M1 的權威定義 + +- **做完**:`milestones.md` §M1——「Android、Windows 上能搜尋 B 站並連續播放兩首。」 +- **一句話性質**(ADR 0026 §決定 3 的表):M1 = 「骨架+曳光彈」;「接上所有基礎建設;YouTube.js 限時探針;`phase2-plan` §7 全部實測」。 +- **範圍清單**:`milestones.md` §M1 的「範圍」七條,對應 ADR 0008、0015、0009、0010、0011、0012、0013、0014、0018、0023、0024、0022。 +- **必要驗證**:`phase2-plan` §7「第一個里程碑的必要驗證(各項設計累積)」——「以下全部併入 M1(ADR 0026、`milestones.md`)」,共 10 則 ADR(0008、0009、0010、0011、0014、0015、0018、0022、0023、0024)。 +- **驗收**(`milestones.md` §M1):兩平台端到端操作;§7 全部項目。 +- **限時探針**:YouTube.js 可行性;失敗就在 M3 以 Dart 實作 YouTube(ADR 0014 §決定 10、`milestones.md` §M1)。 +- **之後**:開 Linux 平台任務(ADR 0026 §決定 4)。 + +**兩份清單的差異(planner 要注意)**:`milestones.md` 的「範圍」含 ADR 0012(網路層,不含登入)與 ADR 0013(錯誤模型),但這兩則不在 `phase2-plan` §7 的清單裡;§7 另含 ADR 0008/0009/0010 的實測。兩份合起來才是 M1 的完整範圍: + +- 要建置的模組:0008、0009、0010、0011、0012、0013、0014、0018(最小集)、0023、0024、0015、0022。 +- 只要在 M1「實測」的:0009(CI 矩陣)、0010(原生庫共存)、0011(遮蔽)、0014(`flutter_js` 與 YouTube.js)、0015(QuickJS 進 `flutter test`、dev/prod 隔離、零聯網兩道防線)、0018(前瞻交接、音訊焦點)、0022(release-please)、0023(提示層級、Narrator)、0024(空白鍵、F6、字形)。 +- 完全不在 M1:0016、0017、0019、0020、0021、0025(各屬 M2/M4/M6/M7/M3)。 + +--- + +## 1. 逐 ADR 摘錄 + +### ADR 0008 — 同一 repo 的 `app/` 另建新專案 + +**(a) M1 要做的** +- 在**同一 repo 的 `main`**、子目錄 `app/` 建新的 Flutter 專案;這是它的永久位置,舊專案留在根目錄、凍結(ADR 0008 §決定 2)。 +- `app/` 有自己的 `AGENTS.md`(ADR 0008 §決定 2)。 +- App 身分沿用舊版:Android `applicationId` `com.personal.fmp` 與**同一把簽名金鑰**;Windows AppUserModelID `com.personal.fmp`;Inno Setup AppId(ADR 0008 §決定 3)。只有同身分 Android 才讀得到舊 App 私有目錄、舊版才能直接升級。 +- 開發版另用身分,與正式版分開(ADR 0008 §決定 3;細節在 ADR 0015 §決定 8)。 +- 搬運**非音源**的葉節點邏輯(ADR 0008 檔頭補充):音源相關邏輯不搬 Dart,改以舊程式碼為規格用 JS 重寫(ADR 0014);其他葉節點例如 `TrackKey` 格式照搬。 +- 主幹開發、每個里程碑是可 review 的小 PR、直接合進 `main`(ADR 0008 §決定 1、§後果)。 + +**(b) M1 的驗證** +- `app/` 不得 import 根目錄舊專案:lint `fmp_layer_imports`(ADR 0008 §如何確認)。 +- App 身分識別:測試斷言 prod flavor 的身分值與上列一致(ADR 0008 §如何確認、ADR 0015 §決定 8 的「prod 的身分值與 ADR 0008 一致」)。 +- §7:`app/` 的 App 身分識別與舊版一致(開發版除外)。 +- 切換前才加的檢查(比對 `applicationId`、AppUserModelID、Inno Setup AppId)屬 M9,不在 M1。 + +**(c) 不在 M1** +- 刪除根目錄舊專案、`docs/audit/`、ADR 0001–0007;`release.yml`/`ci.yml`/`orca.yaml`/`tool/release/` 改指向 `app/`——切換 PR,M9(ADR 0008 §決定 5、ADR 0026 §決定 5)。 +- 舊版緊急修正在 `main` 上改根目錄舊專案、以 `vX.Y.Z` 發版——持續到切換(ADR 0008 §決定 4)。 + +**(d) ADR 已固定的名稱** +- 路徑:`app/`、`app/AGENTS.md`。 +- 值:`com.personal.fmp`(Android `applicationId` 與 Windows AppUserModelID);舊版檔案位置引用 `android/app/build.gradle.kts:29`、`windows/runner/main.cpp:43`、`pubspec.yaml:121-122`(ADR 0008 §決定 3 的引用)。 +- lint:`fmp_layer_imports`(ADR 0015)。 +- 葉節點型別:`TrackKey`(ADR 0008 檔頭補充)。 + +--- + +### ADR 0009 — 平台層與能力宣告 + +**(a) M1 要做的** +- 平台層目錄 `app/lib/platform/`,**每個能力一個目錄**,內含 `<能力>.dart`(介面與工廠)與 `<能力>_<平台>.dart`(實作)(ADR 0009 §決定 1)。 +- 能力清單:托盤、視窗與標題列、全域快捷鍵、開機自啟、**單一實例**、桌面歌詞視窗、系統媒體控制、**目錄規則**、應用內更新、登入 WebView、執行期權限(ADR 0009 §決定 1)。 +- 每個平台一份不可變的 `PlatformCapabilities`;UI 依它決定入口,service 只呼叫介面;執行期才能判斷的由實作在啟動時寫進宣告(ADR 0009 §決定 2)。 +- 平台層以外**禁止** `dart:io` 的 `Platform.isX`、`defaultTargetPlatform`、`TargetPlatform` 與平台套件 import(ADR 0009 §決定 3)。 +- **不寫空實作**:未驗證平台宣告全部能力為「沒有」、沒有實作檔(ADR 0009 §決定 4)。 +- 新的 MethodChannel 一律用 **Pigeon**(ADR 0009 §決定 5)。 +- 目錄規則:Android 私有目錄;Windows 安裝版 `%APPDATA%`、Portable 版程式旁 `data/`;Linux `~/.local/share`;macOS/iOS 沙盒 Application Support;開發版另用目錄(ADR 0009 §決定 7)。 +- 外觀:Windows、Linux 用自訂標題列;macOS 保留系統紅綠燈;CJK 字型不內建、依平台 fallback(ADR 0009 §決定 8、ADR 0024 §決定 2)。 +- 上線順序:Android、Windows 從 M1 起全面驗證;**Linux、macOS、iOS 從 M1 起在 CI 編譯**(iOS 加模擬器測試)(ADR 0009 §決定 9)。 +- 系統媒體控制套件:`audio_service`(Android/iOS/macOS)+ Windows SMTC+ Linux `audio_service_mpris`;托盤/視窗/快捷鍵/多視窗沿用現有套件並擴到其他桌面平台;`connectivity_plus`、`file_picker`、`path_provider` 五平台共用;桌面套件需修補時用 git 依賴鎖 commit 並註明上游 issue(ADR 0009 §決定 6)。 + +**(b) M1 的驗證** +- 平台層以外禁平台判斷與平台套件 import:lint `fmp_platform_checks` 與 `fmp_layer_imports`(ADR 0009 §如何確認)。 +- CI:從第一個里程碑起建置矩陣含 Linux、macOS、iOS(不簽名)(ADR 0009 §如何確認)。 +- §7:CI 建置矩陣含 Linux、macOS、iOS(不簽名)。 +- 每個平台 child task 的驗收含「宣告為沒有的能力,UI 不出現入口」——不是 M1(ADR 0009 §如何確認)。 + +**(c) 不在 M1** +- Linux/macOS/iOS 的實作檔(ADR 0009 §決定 4、附帶否決)。 +- Linux 實機驗證(VMware 虛擬機)、macOS/iOS child task(ADR 0009 §決定 9、ADR 0026 §決定 4)。 +- 桌面歌詞視窗、Android 懸浮歌詞、iOS Live Activity 的實作(ADR 0021,M7)。 + +**(d) ADR 已固定的名稱** +- 路徑:`app/lib/platform/`;`PlatformCapabilities`;`PermissionGateway`(ADR 0020 §決定 9;見 §3 矛盾表)。 +- 套件:`tray_manager`、`window_manager`、`hotkey_manager`、`smtc_windows`、`audio_service`、`audio_service_mpris`、`connectivity_plus`、`file_picker`、`path_provider`。 +- lint:`fmp_platform_checks`、`fmp_layer_imports`。 +- 能力名(後續 ADR 定義,平台層要宣告):`desktopLyrics`(`clickThrough`、`alwaysOnTop`)、`overlayLyrics`、`liveActivityLyrics`(ADR 0021 §決定 8–10)、`appUpdate`(ADR 0022 §決定 5)、`pluginDevTools`(ADR 0025 §決定 2)。 + +--- + +### ADR 0010 — drift(SQLite)+舊資料匯入 + +**(a) M1 要做的** +- 選型:`drift` + `sqlite3`(**native assets 自動打包五平台原生庫**)(ADR 0010 §決定 1)。 +- 資料庫檔在 ADR 0009 定義的資料目錄;**只有資料層(repository)能存取資料庫**(ADR 0010 §決定 1)。 +- Schema 原則:關係交給資料庫(外鍵、`ON DELETE`、唯一鍵);曲目以 `TrackKey` 字串(含 cid,ADR 0005)為唯一鍵;只存事實;串流 URL 不進資料庫;下載紀錄獨立成表;**設定存在同一個資料庫的設定表**;時間存 UTC epoch 毫秒;音源 id 用字串(ADR 0010 §決定 2)。 +- Schema 演進:每版以 `drift_dev schema dump` 存快照;每個 migration 有升級測試;migration 不得改寫使用者設定過的值;migration 失敗整個回滾、顯示錯誤頁(ADR 0010 §決定 3)。 +- M1 只建「**最小 schema 與快照**」(`milestones.md` §M1)——ADR 未列舉最小集是哪幾張表(見 §3)。 +- 目錄 `app/lib/legacy_import/` 是**唯一**依賴 `isar_community` 與 `flutter_secure_storage` 10.x 的地方(ADR 0010 §決定 4)。 + +**(b) M1 的驗證** +- Schema 快照與每個 migration 的升級測試在 CI 執行(ADR 0010 §如何確認)。 +- 「migration 不改使用者設定過的值」有專門測試(ADR 0010 §如何確認)。 +- 資料庫只由資料層存取、`legacy_import/` 不被其他模組 import:lint `fmp_layer_imports`(ADR 0010 §如何確認)。 +- §7:`isar_community`+`sqlite3` 原生庫在 **Android、Windows 共存**;`sqlite3` 的 Android **16KB page size 對齊**(ADR 0010 §後果「第一個里程碑在 Android、Windows 實測」)。 +- 若共存衝突:legacy import 改成由新 App 啟動的獨立一次性小程式(ADR 0010 §後果)。 + +**(c) 不在 M1** +- 完整的舊資料匯入流程(唯讀開舊 Isar、暫存庫、筆數驗證、抽樣比對、外鍵完整後才換上正式庫、匯入紀錄、錯誤頁、舊備份檔匯入、「刪除舊版資料」)——M5(`milestones.md` §M5、ADR 0010 §決定 4)。 +- 真實資料副本上完整跑一次匯入、筆數比對——M5/切換前(ADR 0010 §如何確認)。 +- `isate_community`/舊 secure storage 的移除(保留到另立 ADR)(ADR 0010 §決定 4 最後一項)。 + +**(d) ADR 已固定的名稱** +- 套件:`drift`、`sqlite3`、`isar_community` 3.3.2、`flutter_secure_storage` 10.x(legacy import 用)/11.x(新憑證,ADR 0012)。 +- 路徑:`app/lib/legacy_import/`;`drift_dev schema dump` 的 schema 快照。 +- 表名(ADR 0019 才定義,M4):`playlists`、`playlist_remote`、`playlist_entries`、`tracks`、`track_origins`、`match_results`;`downloads`(ADR 0020,M6);`lyrics_matches`(ADR 0021,M7);`cache.db` 為獨立索引(ADR 0016,M2)。 +- 資料庫開啟:`PRAGMA foreign_keys = ON`(ADR 0019 §決定 1)。 + +--- + +### ADR 0011 — 單一日誌門面與單一遮蔽函式;設定依功能分組 + +**(a) M1 要做的** +- **日誌門面**:全 App 只有一個 log 入口,參數含訊息、tag(模組或音源 id)、error、stackTrace、結構化欄位;門面先遮蔽再交給 `talker`(只用它的歷史與分派)。門面以外禁 `print`、`debugPrint`、`developer.log` 與直接用 talker(ADR 0011 §決定 1)。 +- **輸出**:記憶體歷史最近 1,000 筆;檔案在 ADR 0009 資料目錄的 `logs/`,**單檔 2MB、保留 3 個**,寫入失敗不影響 App;console 只在 debug build;release 預設層級 `info`,開發者模式可調 `debug`(ADR 0011 §決定 2)。 +- **遮蔽函式**(唯一一個)依序:header 名單、key 名單(query 與 body)、已知媒體 CDN 的簽名參數去除、已知憑證值逐字替換(帳號層登記各音源實際憑證值);套用在訊息、error 字串、stackTrace、結構化欄位;名單集中一處,音源插件可追加(ADR 0011 §決定 3)。 +- **網路紀錄**:自己的 dio 攔截器,每請求一筆摘要(方法、主機、路徑、遮過的 query、狀態、耗時、大小、音源、錯誤類型),經門面寫入;**不記 body**(ADR 0011 §決定 4)。 +- **錯誤歷史**:統一錯誤型別被處理時一律經門面以 `warning`/`error` 寫入(ADR 0011 §決定 5)。 +- **設定**:依功能分組(播放、外觀、音樂庫與同步、下載、歌詞、網路、桌面、開發者),**每組一張單列表**、每個設定一個有型別的欄位、每組一個 Riverpod Notifier;**欄位為空=使用者沒設定過**,讀取時套用程式預設;每個音源的設定另一張表以音源 id 為主鍵(ADR 0011 §決定 7)。 +- M1 只要「log 門面、遮蔽函式、log 檔」(`milestones.md` §M1);設定分組的表要建,但**各組的欄位清單在引入該組設定的里程碑才定案**(ADR 0011 §後果、ADR 0026 §決定 2)。 + +**(b) M1 的驗證** +- lint:門面以外禁 `print`/`debugPrint`/`developer.log`/import talker:`fmp_log_facade`(ADR 0011 §如何確認)。 +- **遮蔽測試**:每個音源一組假憑證與假簽名 URL,斷言經 log 檔、記憶體歷史、診斷包、網路紀錄後都不再出現原值,**包括出現在 stackTrace 的情況**(ADR 0011 §如何確認)。 +- 設定測試:寫入使用者值後改程式預設,斷言讀到的仍是使用者值;未設定的欄位讀到新預設(ADR 0011 §如何確認)。 +- §7:log 門面與遮蔽函式是第一個里程碑的基礎,**含遮蔽測試**。 + +**(c) 不在 M1** +- 診斷包(純文字+JSON、`diagnostics.txt`/`diagnostics.json`)——ADR 0011 §決定 6、ADR 0025 §決定 10,M3。 +- Debug 頁的 log 檢視、錯誤歷史跨重啟、JSON Lines、保留 7 天——ADR 0025(M3)與 ADR 0017(M2)。 +- 各組設定的欄位清單——各里程碑(ADR 0026 §決定 2)。 + +**(d) ADR 已固定的名稱** +- 路徑:`app/lib/core/logging/`、`app/lib/core/redaction/`;資料目錄下 `logs/`。 +- 套件:`talker`(資料核心)。 +- lint:`fmp_log_facade`。 +- 設定分組八組名:播放、外觀、音樂庫與同步、下載、歌詞、網路、桌面、開發者。 +- 參照實作:Finamp `censored_log.dart`;NewPipe 錯誤報告欄位;Spotube 的 drift 設定+`watchSingle()`。 + +--- + +### ADR 0012 — 網路層與帳號 + +**(a) M1 要做的**(`milestones.md` §M1:「網路層(不含登入)」) +- **HTTP 層**:每個音源一個 **API client**(dio),該音源所有 service 共用;攔截器順序=認證注入、cookie 管理、錯誤對應、限流與退避、網路紀錄(ADR 0011)(ADR 0012 §決定 1)。 +- 另有**媒體 client** 專抓音訊位元組,只加媒體 headers(Referer、UA),**不掛認證攔截器與 cookie 管理**(ADR 0012 §決定 1)。 +- 匿名用非機密 cookie(例如 B 站 `buvid`)存資料庫(ADR 0012 §決定 1)。 +- 轉址:宿主 HTTP 跟隨轉址時每一跳都要在 manifest 網域內、**最多 5 跳**;媒體 client 跟隨轉址時每一跳只帶媒體 headers(ADR 0012 §決定 1)。 +- **帶憑證的單一宣告點**:每個請求在音源插件的定義處宣告 `AuthRequirement`——`required`/`userPreference`/`never`(預設);認證攔截器只依此標記注入;網路紀錄記錄每請求是否帶憑證(ADR 0012 §決定 2)。 +- 舊原則併入:**憑證只用在向音源解析串流與 API 請求,抓音訊位元組的請求一律不帶憑證**(ADR 0012 §背景)。 +- cookie 用 `cookie_jar` + `dio_cookie_manager`(ADR 0012 §考慮過的選項、§採用的慣例)。 +- 憑證存放 `CredentialStore`(`flutter_secure_storage` 11.x,以音源 id 為鍵);讀取失敗狀態為「暫時無法讀取」並稍後重試、**不刪除**;憑證載入或更新時登記到遮蔽函式(ADR 0012 §決定 3)。 + +**(b) M1 的驗證** +- 契約測試:每個音源的媒體請求經媒體 client 發出後,**請求上不含任何 Cookie/Authorization**(ADR 0012 §如何確認)。 +- 測試:`AuthRequirement` 三種標記在「未登入/已登入且開關開/已登入且開關關」下的注入結果(ADR 0012 §如何確認)。 +- 測試:刷新後重送的請求帶的是新憑證;每個音源的「憑證無效」判定表;限流與網路錯誤碼不會把帳號標為失效;登出與重設後 `CredentialStore` 為空(ADR 0012 §如何確認)——**多數需要登入層,屬 M3**。 +- 註:ADR 0012 **不在** `phase2-plan` §7 的清單裡;M1 對它的驗證要求來自 §決定 1、2 與 ADR 0014 §如何確認的契約測試(媒體不帶憑證、只連 manifest 網域)。 + +**(c) 不在 M1** +- 登入(QR、App 內網頁登入、貼上 cookie)、`CredentialStore` 的實際登入流程、帳號頁、刷新與失效判定表、登出——M3(`milestones.md` §M3:「帳號與 `CredentialStore`、`AuthRequirement`(ADR 0012,E6)」)。 +- 「以登入身分瀏覽與播放」開關(ADR 0012 §決定 6)——M3。 +- YouTube App 內網頁登入實測——§8,M3。 +- Linux 沒有 keyring 時的 secure storage 行為——§8,Linux child task。 +- 只能匯入的來源 Spotify/QQ 的 `never` 標記(ADR 0012 §決定 7)——M4。 + +**(d) ADR 已固定的名稱** +- 套件:`dio`、`cookie_jar`、`dio_cookie_manager`、`flutter_secure_storage` 11.x。 +- 型別:`AuthRequirement`(`required`/`userPreference`/`never`)、`CredentialStore`、`QueuedInterceptor`。 +- 舊版參照:`SourceUrlPolicy.resolveRedirects`(轉址做法)。 + +--- + +### ADR 0013 — 統一錯誤模型 + +**(a) M1 要做的** +- **分類**:一個 sealed `AppError`,成員 `NetworkError`、`RateLimited`、`AuthRequired`、`CredentialInvalid`、`VerificationRequired`、`Unavailable`(附原因:地區、版權、會員、年齡、只有試聽)、`NotFound`、`ParseError`、`Unsupported`、`UnexpectedError`(ADR 0013 §決定 1)。 +- 共同欄位:音源 id、`retryable`、`retryAfter`、給使用者的 i18n 訊息 key 與參數、`expected`、原始 error 與 stackTrace(只進 log、經遮蔽)、對應的網路紀錄 id(ADR 0013 §決定 1)。 +- **轉換位置**:網路層把傳輸錯誤轉成 `NetworkError`;**每個音源在自己的目錄內**以對應表把狀態碼與錯誤碼轉成 `AppError`;未知例外在音源邊界包成 `UnexpectedError`;音源邊界以上只看得到 `AppError`(ADR 0013 §決定 2)。 +- **傳遞**:音源與 service 丟 `AppError`;Riverpod provider 以 `AsyncValue.error` 承接,UI 以 exhaustive `switch` 呈現;禁止空 catch 與靜默吞錯(ADR 0013 §決定 3)。 +- **重試只有一層**:Riverpod 自動重試**全域關閉**;網路層依音源宣告策略重試——只重試冪等請求、只重試 `NetworkError`/`RateLimited`/音源標為可重試者、指數退避+全抖動、尊重 `Retry-After`、**次數上限預設 2**;每音源有併發上限與最小請求間隔(ADR 0013 §決定 4)。 +- **呈現**:ADR 0013 §決定 5 的類別表(網路/限流/需登入/憑證無效/風控驗證/無法取得/找不到/解析失敗/不支援);訊息一律來自 i18n;部分成功要標出失敗音源;背景工作不跳 toast;同類別+同音源短時間只提示一次;開發者模式下附「詳細」。 + +**(b) M1 的驗證** +- 契約測試:每個音源以錄下的錯誤回應 fixture,斷言對應到的 `AppError` 類別(ADR 0013 §如何確認)。 +- 測試:`ProviderScope` 的 retry 為關閉;網路層只對冪等請求重試、尊重 `Retry-After`(ADR 0013 §如何確認)。 +- lint:禁止空 catch(`fmp_no_empty_catch`);禁止 UI 顯示 `toString()` 之類原文(以只接受 i18n key 的呈現 API 在型別上擋住)(ADR 0013 §如何確認)。 + +**(c) 不在 M1** +- 完整音源(YouTube、網易)的錯誤對應表——M3。 +- 「詳細」頁與 GitHub 回報(`ErrorReport`、`.github/ISSUE_TEMPLATE/bug_report.yml`)——ADR 0023、M3(`milestones.md` §M3)。 +- 播放層的跳過與停止條件(`RecoveryPolicy` 全表)——ADR 0018、M2。 +- B 站 geetest 驗證互動——功能凍結待辦(ADR 0013 §考慮過的選項)。 + +**(d) ADR 已固定的名稱** +- 型別:`AppError` 及十個子類別(名稱如上);欄位名 `retryable`、`retryAfter`、`expected`。 +- lint:`fmp_no_empty_catch`。 +- 設定:Riverpod 全域 `retry` 關閉。 +- 參照:NewPipe `ErrorInfo`;AWS Exponential Backoff And Jitter;Finamp 的「類別+來源」去重。 + +--- + +### ADR 0014 — 音源是執行期 JS 腳本插件 + +**(a) M1 要做的** +- 一套介面 `SourcePlugin`:App 其他部分只認介面與能力宣告,UI 與 service 沒有針對特定音源的分支(ADR 0014 §決定 1)。 +- **JS 執行環境**:引擎 `flutter_js`(Android/Windows/Linux 用 QuickJS,iOS/macOS 用 JavaScriptCore),**ES2020**(ADR 0014 §決定 2)。 +- manifest 欄位:`id`(字串音源 id)、名稱、版本、作者、`apiVersion`、能力、允許的網域、登入方式、重試與限流策略、遮蔽名單追加、預設值、圖示(ADR 0014 §決定 3)。 +- 能力枚舉:`search`、`resolveStream`、`trackDetail`、`multiPart`、`importPlaylist`、`libraryRead`、`libraryWrite`、`charts`、`live`、`mix`、`lyrics`、`login`;可播放音源=有 `resolveStream`(ADR 0014 §決定 4)。 +- **宿主 API v1**(M1 的最小集):`http.request`(經 ADR 0012/0013 網路層、只能連 manifest 網域)、`crypto`、每插件 `storage`、只讀自己音源的 `credentials`、`log`(經 ADR 0011 門面)、結構化錯誤(宿主轉成 `AppError`);沒有檔案系統、任意 socket、其他插件的資料(ADR 0014 §決定 5)。 +- 資料交換為以 `apiVersion` 版本化的 JSON DTO,宿主提供 **TypeScript 型別定義**(ADR 0014 §決定 5)。 +- `resolveStream` 輸入含平台可播格式與用途(播放;下載 ADR 0020),輸出為依優先序排好的候選串流;回傳網址期限 `expiresAt`(插件從網址本身讀);封面為多尺寸清單 `artwork`(ADR 0014 §決定 5、ADR 0016 §決定 4)。 +- **M1 的載入方式**:以「**從檔案安裝**」載入第一個腳本音源(B 站)(`milestones.md` §M1、`phase2-plan` §7)。 +- 匹配:宿主一份共用評分核心,歌單匯入與歌詞共用(ADR 0014 §決定 9)——實作屬 M4/M7。 + +**(b) M1 的驗證** +- 結構測試:每個插件的 manifest 能力與它實際匯出的函式一致;`apiVersion` 不相容時拒絕載入(ADR 0014 §如何確認)。 +- 契約測試:以錄下的 HTTP 回應重播執行每個插件的檢查案例,涵蓋 ADR 0011(遮蔽)、0012(媒體請求不帶憑證、`AuthRequirement`)、0013(錯誤對應);插件 repo 的 CI 與插件作者本機都能跑(ADR 0014 §如何確認)。執行器與 fixture 格式見 ADR 0015。 +- 測試:宿主 HTTP 拒絕 manifest 網域以外的請求;腳本無法讀取其他插件的 storage 與憑證(ADR 0014 §如何確認)。 +- lint:UI 與 service 不得出現音源 id 字串常數或特定音源的型別:`fmp_source_id_literal`(ADR 0014 §如何確認)。 +- §7:JS 執行環境(`flutter_js`)與宿主 API 最小集合;以「從檔案安裝」載入第一個腳本音源;**`flutter_js` 在 Android、Windows 的 Promise/記憶體/啟動成本實測**;**YouTube.js 可行性驗證**(有時限,失敗則 YouTube 暫以 Dart 實作)。 +- YouTube.js 探針的具體條件:YouTube.js 在 `flutter_js` 能否搜尋並解出串流(它官方只寫支援 Node.js、Deno、瀏覽器,需宿主提供 fetch 與 eval)(ADR 0014 §決定 10)。 + +**(c) 不在 M1** +- 插件庫 repo `1morr/fmp-plugins`、其 CI、`index.json`(含 SHA-256)、App 插件頁、首次啟動引導、一鍵更新——M3(ADR 0014 §決定 6–8、`phase2-plan` §9「第一個里程碑不需要」)。 +- YouTube、網易雲插件——M3。 +- Spotify/QQ 僅元資料來源——M4。 +- 歌詞源與 `aiAssist`——M7(ADR 0021)。 +- 匹配流程的實作——M4/M7。 + +**(d) ADR 已固定的名稱** +- 型別:`SourcePlugin`、`SourceCapability` 系列(舊版名,新介面為 `SourcePlugin`)。 +- 引擎:`flutter_js`(QuickJS/JavaScriptCore)。 +- 能力名:上列 12 個。 +- DTO 欄位:`apiVersion`、`expiresAt`、`artwork`(`[{url, width?}]`)、`checks.json`(ADR 0015 §4)。 +- lint:`fmp_source_id_literal`。 +- repo 名(M3):`1morr/fmp-plugins`。 + +--- + +### ADR 0015 — 測試與閘門、開發環境、CI + +**(a) M1 要做的** +- **lint 套件** `app/packages/fmp_lints/`,以官方 `analysis_server_plugin` 自寫規則;`app/analysis_options.yaml`(ADR 0015 §決定 2)。 +- 十條核心規則:`fmp_layer_imports`、`fmp_no_empty_catch`、`fmp_log_facade`、`fmp_source_id_literal`、`fmp_url_literal`、`fmp_no_for_testing`、`fmp_http_client_owner`、`fmp_test_waits`、`fmp_ignore_reason`、`fmp_platform_checks`(ADR 0015 §決定 2 的表)。 +- 後續 ADR 新增的規則:`fmp_periodic_timer_owner`(ADR 0017;ADR 0021 加入桌面歌詞查游標的允許擁有者)、`fmp_toast_entry`(ADR 0023)、`fmp_design_tokens`(ADR 0024)(ADR 0015 §決定 2 末段)。**哪幾條屬 M1 未寫死**(見 §3)。 +- 每條規則以官方 `analyzer_testing` 做**雙向變異測試**(違規會報、無關改動不報)(ADR 0015 §決定 2)。 +- CI 跑 `dart analyze --fatal-infos`(因 `flutter analyze` 目前不顯示插件診斷,flutter/flutter#193203),並以**接線哨兵**(暫放違規檔、斷言分析失敗且含規則名)證明規則接上 `app/`(ADR 0015 §決定 2)。 +- **預設零聯網**:`app/dart_test.yaml` 對 `live` tag 設 `skip`、以 preset 解除;`app/test/flutter_test_config.dart` 以 `HttpOverrides.global` 讓建立真實 `HttpClient` 直接失敗(ADR 0015 §決定 3)。 +- **檢查案例一份四用**:每插件每能力最多一條檢查案例(`checks.json`),同一份用於契約測試(重播 fixture,進 CI)、冒煙測試(真實連線,插件庫 `--live` 手動)、Debug 頁健康檢查(M3)、錄製(ADR 0015 §決定 4)。 +- **fixture**:錄製與重播在宿主網路層最底部的 dio `HttpClientAdapter`;一次請求/回應一個 JSON 檔(`meta`+`request`+`response`);寫檔前一律經 ADR 0011 遮蔽函式;重播比對 method+排序後的 URL+順序(ADR 0015 §決定 5)。 +- **契約執行器**:一個通用套件以重播執行每個案例;`app/` 的 CI 對 `app/test/fixtures/plugins/` 內的測試插件執行(合成資料、播放本機音檔),不依賴官方插件庫;同一個測試插件也供開發版離線開發(ADR 0015 §決定 6)。 +- **開發版**:flavor `dev`/`prod`,`pubspec.yaml` 設 **`default-flavor: dev`**,發版明確帶 `--flavor prod`;dev 的 Android `applicationIdSuffix ".dev"`、Windows AppUserModelID `com.personal.fmp.dev`、名稱「FMP Dev」與標記圖示、資料目錄/單一實例鎖/secure storage 命名空間加 `-dev`;prod 維持 ADR 0008 的身分;開發版資料預設空白;**開發版拒絕直接讀舊版正式資料位置**(ADR 0015 §決定 8)。 +- **CI 切分**:`dorny/paths-filter` 依專案切分——`app/**` 與 `.github/**` 觸發 `app` 的 job,`app/` 以外的任何變動(含文件)觸發舊專案的 job;**一個 `always()` 彙總 job 當唯一必要檢查**(ADR 0015 §決定 9)。 +- `app` 的 job 內容:format、`dart analyze`、接線哨兵、`flutter analyze`、lint 規則測試、不加參數的 `flutter test`、契約執行器、Android/Windows/Linux/macOS/iOS(不簽名)建置、Linux 與 Windows 的整合測試(ADR 0015 §決定 9)。 +- 整合測試只挑:搜尋→播放、從檔案安裝插件、舊資料匯入(ADR 0015 §決定 1)。 +- 分層:單元、widget(provider override 注入假資料)、插件契約、整合、golden(只給設計系統共用元件,`alchemist` 的 CI golden);**不設覆蓋率門檻**;`lib/` 不留測試掛鉤,一律經建構子或 provider 注入(ADR 0015 §決定 1)。 + +**(b) M1 的驗證** +- `fmp_lints` 每條規則的 `analyzer_testing` 測試;CI 的接線哨兵(ADR 0015 §如何確認)。 +- **第一個里程碑實測**(ADR 0015 §如何確認、§7): + - `dart analyze` 看得到插件診斷; + - **契約執行器能否在 `flutter test` 內載入 QuickJS**(不行改用桌面 `integration_test`); + - dev 與 prod 同時開啟時身分、鎖、資料目錄各自獨立; + - 一個故意聯網的測試在裸 `flutter test` 被跳過、**解除 tag 後被 `HttpOverrides` 擋下**(零聯網兩道防線)。 +- 測試:prod 的身分值與 ADR 0008 一致、dev 每一項都不同;開發版拒絕舊版正式資料路徑;掃描所有 fixture 不得有未遮蔽憑證(ADR 0015 §如何確認)。 +- `AGENTS.md`(`app/`)列出的每條靜態規則都寫出對應規則名;沒有規則守的不寫進去(ADR 0015 §如何確認)。 + +**(c) 不在 M1** +- 舊專案的 static-rule:原樣留在舊專案守舊程式碼,**切換 PR 時一併刪除**(ADR 0015 §決定 10)。 +- 舊專案的 job:維持現狀,只在根目錄變動時跑,`app/` 的 PR 不被舊專案不穩測試擋住(ADR 0015 §決定 9)。 +- App 內插件開發工具(開發者模式、資料夾載入、真實/錄製/重播切換)——M3(ADR 0015 §決定 7、ADR 0025 §決定 7)。 +- `fmp_periodic_timer_owner` 的實作(需 `BackgroundScheduler`)——M2。 +- `riverpod_lint` 是否已遷移到新插件系統「在落地時查證」(ADR 0015 §後果)。 + +**(d) ADR 已固定的名稱** +- 路徑:`app/packages/fmp_lints/`、`app/analysis_options.yaml`、`app/dart_test.yaml`、`app/test/flutter_test_config.dart`、`app/test/fixtures/plugins/`。 +- 檔名:`checks.json`。 +- 規則名:上列 10+3 條。 +- flavor:`dev`/`prod`;`default-flavor: dev`;`applicationIdSuffix ".dev"`;AppUserModelID `com.personal.fmp.dev`;名稱「FMP Dev」。 +- CI:`dorny/paths-filter`;`always()` 彙總 job;`dart analyze --fatal-infos`;接線哨兵。 +- 套件:`analysis_server_plugin`、`analyzer_testing`、`alchemist`。 +- 舊檔引用:`.trellis/tasks/archive/2026-09/09-27-design-testing/design.md` §6(舊 static-rule 去向的逐條清單)。 + +--- + +### ADR 0016 — 快取與離線 + +**與 M1 無關(主體屬 M2)**,但有兩個 M1 的鉤子要記: + +- (a) ADR 0018 §決定 6 的串流解析順序是「本機下載檔 → **記憶體網址快取(ADR 0016)** → 插件 `resolveStream`」;ADR 0018 §決定 7 的恢復策略要「**不在 `Online` 時暫停計數(ADR 0016)**」。 +- (c) `milestones.md` §M2 把「統一快取庫與離線狀態(ADR 0016)」整包放在 M2。 +- 兩者的衝突見 §3。 +- (d) 名稱(M2 才建):快取模組、`cache.db`(獨立 drift 索引)、`getApplicationCacheDirectory()`、總上限 128MB/256MB/512MB/1GB、`connectivity_plus`、`cached_network_image`;串流網址記憶體快取上限 **64 筆**、有效到 `expiresAt − 5 分鐘`、為空時 5 分鐘內有效(ADR 0016 §決定 5、6)。 +- ADR 0016 §如何確認的「**預取後播放只解析一次**」是 ADR 0018 §如何確認也列的一項——M1 做播放核心時就會碰到的行為,但完整快取庫在 M2。 + +--- + +### ADR 0017 — 背景任務排程器 + +**與 M1 無關(M2)。** + +- (c) `BackgroundScheduler`、「啟動維護清單」(ADR 0025 加入 log 保留期限與診斷包暫存清理;**清單在 M2 實作**,`milestones.md` §M2)、`fmp_periodic_timer_owner` lint、排行/匯入歌單/電台刷新間隔設定——全部 M2。 +- (b) M1 只碰到一件事:ADR 0018 §決定 11 說播放模組的位置檢查(每秒)與位置存檔(每 10 秒)是 `fmp_periodic_timer_owner` **允許的播放模組**——M1 的播放核心最小集若要持久化位置就會碰到這條 lint 的允許清單(但 lint 本身屬 M2)。 +- log 保留 7 天(ADR 0011 §後果指向 ADR 0025,再由 ADR 0017 的啟動維護清單執行)——M2/M3。 + +--- + +### ADR 0018 — 播放核心(M1 取最小集) + +**(a) M1 要做的**(`milestones.md` §M1:「播放核心最小集:兩個後端、兩首的佇列、前瞻交接」) +- `PlaybackController` 是 UI、系統媒體控制與直播的唯一播放入口;協作者(`QueueModel`、`PlaybackSession`、`StreamResolver`、`PlaybackEventRouter` 純函數、`RecoveryPolicy` 純函數、`NowPlayingPublisher`)只回報、不寫狀態(ADR 0018 §決定 1)。 +- 一份 sealed 播放狀態:`Idle`、`Loading`、`Playing`、`Paused`、`Buffering`、`Retrying`、`Failed(AppError)`;位置等高頻資料走獨立 stream;`QueueState` 與播放狀態沒有共同欄位(ADR 0018 §決定 2)。 +- **後端**:`AudioBackend` 介面,兩個實作——`JustAudioBackend`(Android、iOS、macOS)與 `MediaKitBackend`(Windows、Linux);不能收斂的差異寫在介面 dartdoc,可收斂的規則(結束原因分類、直播邊緣 seek、前瞻計畫)是共用純函數並有契約測試;平台層宣告使用哪個實作與可播格式;**後端只持有「目前+一個前瞻」**(=前瞻交接/gapless 的機制)(ADR 0018 §決定 3)。 +- **Android 換歌時不釋放音訊焦點**(ADR 0018 §決定 3)。 +- 佇列真相在 Dart 端 `QueueModel`;模式為 `queue`、`temporary`、`mix`、`live`、`detached`;所有加入方式檢查 **10,000 首上限**(ADR 0018 §決定 4)——M1 只做「兩首的佇列」,其餘模式屬 M2。 +- 串流解析:本機下載檔 → 記憶體網址快取(ADR 0016)→ 插件 `resolveStream`;輸入含分 P、用途與平台可播格式,輸出為依優先序排好的候選串流(網址、標頭、格式、`expiresAt`);開流失敗換候選一次(ADR 0018 §決定 6)。 +- 系統媒體控制:`NowPlayingPublisher` 唯一出口;轉接器 Android/iOS/macOS 用 `audio_service`、Linux 用 `audio_service_mpris`、Windows 用 `smtc_windows`(ADR 0018 §決定 8、ADR 0009 §決定 6)——M1 的「兩個後端」是否含系統媒體控制未寫死(見 §3)。 + +**(b) M1 的驗證** +- §7:兩個後端的**前瞻交接(gapless)**;**Android 換歌時不釋放音訊焦點**(ADR 0018 §如何確認、`phase2-plan` §7)。 +- 後端契約測試:同一份純規則斷言跑兩個實作與假後端(ADR 0018 §如何確認)。 +- lint `fmp_layer_imports` 的依賴表:`just_audio`、`media_kit` 只在後端實作目錄;結束原因型別只給後端與路由器 import;串流存取的窄介面只給 `PlaybackSession` import(ADR 0018 §如何確認)。這一組取代舊 `playback_event_routing`、`audio_seam`、`audio_backend_shared_rules` static-rule。 +- 單元測試的完整清單(`QueueModel`、`RecoveryPolicy`、開直播取消音樂請求、預取只解析一次、單曲循環)——多數屬 M2。 + +**(c) 不在 M1** +- 完整 `QueueModel` 與 `RecoveryPolicy`——M2(`milestones.md` §M2)。 +- 隨機、拖曳、臨時播放快照、Mix 修剪、單曲循環(D6)、播放歷史(E15)——M2。 +- 開直播取消音樂請求、直播狀態輪詢、`D10` 區分——M2/M3(電台在 M3)。 +- 位置持久化的完整規則(每 10 秒及暫停、seek、進背景時存)、速度不持久化(E19)——M2。 +- 均衡器、響度、睡眠定時器——功能凍結待辦。 +- 蘋果平台 AVPlayer 對 B 站 DASH 音訊與直播 HLS 的支援——§8,macOS/iOS child task。 + +**(d) ADR 已固定的名稱** +- 型別:`PlaybackController`、`QueueModel`、`PlaybackSession`、`StreamResolver`、`PlaybackEventRouter`、`RecoveryPolicy`、`NowPlayingPublisher`、`AudioBackend`、`JustAudioBackend`、`MediaKitBackend`;狀態列舉名如上;模式名 `queue`/`temporary`/`mix`/`live`/`detached`。 +- 設定名:「記住播放位置」、「臨時播放回佇列倒退秒數」、新設定「跳過試聽片段」(預設開)(ADR 0018 §決定 7、10)。 +- 套件:`just_audio`、`media_kit`、`audio_service`、`audio_service_mpris`、`smtc_windows`。 + +--- + +### ADR 0019 — 音樂庫與同步 + +**與 M1 無關(M4)。** + +- (c) `playlists`/`playlist_remote`/`playlist_entries`/`tracks`/`track_origins`/`match_results` 表、刷新、遠端操作、僅元資料來源匯入、共用評分核心——全部 M4(`milestones.md` §M4)。 +- M1 只借到兩件事:`TrackKey` 格式(ADR 0005,ADR 0010 §決定 2 引用為唯一鍵)、`PRAGMA foreign_keys = ON`(M1 建 schema 時的開啟方式)。 +- §8:`opencc` native assets 在各平台建置——M4 驗收。 +- (d) 匹配套件(M4):`unorm_dart`(NFKC)、`opencc`(繁簡)、`string_similarity`(Dice);`fuzzywuzzy` 已否決(GPL-2.0)。 + +--- + +### ADR 0020 — 下載與權限 + +**與 M1 無關(M6)。** + +- (c) `background_downloader`、`downloads` 表、下載根目錄與檔名、內嵌標籤與 sidecar、啟動對帳、下載設定——全部 M6(`milestones.md` §M6)。 +- (a) M1 只碰到平台層的 `PermissionGateway`(ADR 0009 §決定 1 把「執行期權限」列為平台層能力,ADR 0020 §決定 9 才定義它)——見 §3。 +- (b) §8(M6):`permission_handler` 在 Windows 是否使 FMP 出現在位置權限清單;寫入的標籤能被常見播放器讀到;Android 以 `MANAGE_EXTERNAL_STORAGE` 搬移到使用者資料夾。 +- (d) 名稱(M6):`PermissionGateway`;`MANAGE_EXTERNAL_STORAGE`、`POST_NOTIFICATIONS`、`REQUEST_INSTALL_PACKAGES`;根目錄 `Music/FMP`(Android)、`%USERPROFILE%\Music\FMP`(Windows);檔名格式 `{根目錄}/{音源}/{標題} [{影片 id}].{副檔名}`、多分 P `P01 {分P標題}.{副檔名}`;標題截到 80 字。 + +--- + +### ADR 0021 — 歌詞 + +**與 M1 無關(M7),但有兩個 M1 的平台層鉤子。** + +- (c) `lyrics`/`aiAssist` 能力、歌詞文件 DTO、`lyrics_matches` 表、`LyricsSession`、桌面歌詞視窗、Android 懸浮歌詞、iOS Live Activity——全部 M7(`milestones.md` §M7)。 +- (a) M1 相關的只有平台層:能力名 `desktopLyrics`(`clickThrough`、`alwaysOnTop`)、`overlayLyrics`、`liveActivityLyrics` 要在 `PlatformCapabilities` 裡出現但未驗證平台宣告「沒有」(ADR 0009 §決定 2、4;ADR 0021 §決定 8–10)。 +- (d) 套件(M7):`desktop_multi_window`、`window_manager`、`flutter_overlay_window`、`flutter_lyric`(避開已撤回的 3.0.5,或自寫);lint 允許:`fmp_periodic_timer_owner` 加入平台層桌面歌詞模組(查游標)、`fmp_layer_imports` 限制上述套件只在平台層實作檔。 +- (c) `window_manager` 0.5.x 已停止維護(0.6.0 改建在 `nativeapi`)——M1 就要選版本,見 §3。 + +--- + +### ADR 0022 — 發版與應用內更新(M1 只做 dry-run) + +**(a) M1 要做的**(`milestones.md` §M1:「`app/` 發版 workflow 以 release-please dry-run 驗證」) +- release-please 以 **manifest 模式、`dart` 策略**管理 `app/`:每次 commit 進 `main` 就維護一個發版 PR——依 Conventional Commits 算下一版、改 pubspec、寫 `app/CHANGELOG.md`(ADR 0022 §決定 1)。 +- 合併發版 PR 是唯一人工動作;**同一個 workflow** 接著打 tag `v{版本}`、建置、驗證、上傳 asset 並轉為正式發布(GitHub 預設 token 建的 tag 不會觸發其他 workflow,所以放同一個 workflow)(ADR 0022 §決定 1)。 +- `versionCode` 沿用 `major*1000000 + minor*1000 + patch`,由 workflow 從 tag 算出(ADR 0022 §決定 1)。 +- 發版一律 `--flavor prod`(ADR 0022 §決定 1、ADR 0015 §決定 8)。 +- **重寫期間不發版**(ADR 0022 §決定 1)——所以 M1 只能 dry-run 或測試 repo。 + +**(b) M1 的驗證** +- §7:release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(**測試 repo 或 dry-run**)。 +- workflow 測試(ADR 0022 §如何確認):release-please 輸出為否時不建置;verify 的檔名集合、checksums、別名一致、APK 版本、PE 標頭、舊版更新器相容;pubspec 版本等於 manifest。 +- 依賴方向(`fmp_layer_imports`,ADR 0015):安裝相關的平台呼叫只在平台層。 +- 延後實測(ADR 0022 §如何確認、§8):以舊版 v1.11.0 實際更新(M9);Windows 安裝檔不帶 Mark of the Web(M9);macOS quarantine、Linux AppImage 改名替換(平台任務)。 + +**(c) 不在 M1** +- 應用內更新的實作(檢查、下載、驗證、安裝、清理、`appUpdate` 能力、`fmp_updater.exe`)——M9(`milestones.md` §M9、ADR 0022 §決定 5–10)。 +- `docs/user-guide.md` 與關於頁——M9(`milestones.md` §M9)。 +- 舊 `pubspec_version_test` 改成「pubspec 版本等於 release-please manifest」——隨 `app/` 版本機制落地(ADR 0022 §決定 1)。 +- 舊專案的 `release.yml` 不動(見 §4)。 + +**(d) ADR 已固定的名稱** +- 版本策略:release-please manifest 模式、`dart` strategy;`Release-As: 2.0.0`(第一版);tag `v{版本}`;`versionCode` 公式。 +- 檔名:`app/CHANGELOG.md`;發佈物 `fmp-v{版本}-android-{arm64-v8a,armeabi-v7a,x86_64,universal}.apk`、`fmp-v{版本}-windows-installer.exe`、`fmp-v{版本}-windows.zip`、`fmp-v{版本}-linux-x86_64.AppImage`、`fmp-v{版本}-macos.zip`、`fmp-v{版本}-checksums.sha256`、`fmp-latest-*`。 +- 能力:`appUpdate`(`androidApk`/`windowsInstaller`/`windowsPortable`/`linuxAppImage`/`macosApp`/`none`)。 +- 判斷方式:Windows 有 `unins000.exe` 為安裝版;Linux 有 `APPIMAGE` 環境變數。 +- 入口:「設定 → 關於 → 檢查更新」。 +- 套件:`pub_semver`。 + +--- + +### ADR 0023 — 統一 Toast + +**(a) M1 要做的**(`milestones.md` §M1:「`ToastHost` 與 `Toaster`」) +- **單一入口 `Toaster`**(provider 注入,不需 `BuildContext`):`success`、`info`、`warning` 收 i18n 字串;`error(AppError, {operation})` 只收 `AppError`;各自最多一個動作;背景工作不呼叫它;錯誤不論是否顯示提示都經 log 門面寫入錯誤歷史(ADR 0023 §決定 1)。 +- **外觀**:Material `SnackBar`、`floating`、四種語意色加圖示;位置(手機在迷你播放列與底部導覽列之上、桌面在播放列之上置中**最寬 560px**、全螢幕頁貼底部安全區);外殼版面發佈「底部被佔用的高度」;**一次一則、新的立刻取代**;時長(成功與資訊 **4 秒**、錯誤與警告 **6 秒**);**去重:同類別+同音源(非錯誤為同一訊息)5 秒內只顯示一次**(ADR 0023 §決定 2、ADR 0013 §後果)。 +- **層級**:`ToastHost` 放在 `MaterialApp.builder`,以**一個 `ScaffoldMessenger` 與透明 `Scaffold` 包住 Navigator**,所以全螢幕頁、對話框、底部面板之上都看得到;子視窗與懸浮窗不顯示提示、錯誤以型別化訊息轉給主視窗;App 在背景不顯示、不發系統通知(ADR 0023 §決定 3)。 +- **無障礙**:用 `SnackBar` 內建 live region;單獨朗讀用 `SemanticsService.sendAnnouncement(View.of(context), …)`,**不用已棄用的 `announce`**(ADR 0023 §決定 5)。 + +**(b) M1 的驗證** +- lint `fmp_toast_entry`:`SnackBar(`、`ScaffoldMessenger.of`、`showSnackBar`、`clearSnackBars` 只准在 toast 模組,依 ADR 0015 寫雙向變異測試;它取代舊 `error_presentation_static_rule_test.dart` 中「UI 不得自組錯誤文字」的部分(ADR 0023 §如何確認)。 +- 單元測試:去重視窗、取代、時長(ADR 0023 §如何確認)。 +- widget 測試:全螢幕路由與對話框開啟時送出提示、提示可見;底部位移依外殼發佈的高度(ADR 0023 §如何確認)。 +- §7:提示在全螢幕頁與對話框之上可見;**Windows Narrator 下提示不凍結無障礙樹**(上游 #190357 類問題)。 + +**(c) 不在 M1** +- 詳細頁與 GitHub 回報(`ErrorReport` 內容、複製 Markdown、開 issue 頁、`.github/ISSUE_TEMPLATE/bug_report.yml`)——M3(`milestones.md` §M3、ADR 0023 §決定 4)。repo 目前沒有 issue 範本(`.github/` 只有 `dependabot.yml` 與 `workflows/`)。 +- Debug 頁的錯誤歷史(ADR 0025)——M3。 +- 系統層通知——不在 ADR 0023 範圍。 + +**(d) ADR 已固定的名稱** +- 型別:`Toaster`、`ToastHost`、`ErrorReport`(M3)。 +- lint:`fmp_toast_entry`。 +- 常數:4 秒/6 秒、5 秒去重、560px。 +- 參照:Material 3 Snackbar 規範;Finamp/Immich/LocalSend 的 service 包 SnackBar;NewPipe `ErrorActivity`。 + +--- + +### ADR 0024 — UI/UX(M1 取 token、斷點、字型、slang 骨架、快捷鍵) + +**(a) M1 要做的**(`milestones.md` §M1) +- **`AppTokens`(`ThemeExtension`)**:間距 **4、8、12、16、20、24、32、40、48**;圓角 **4、8、12、16、28**(M3 shape scale);語意色成功、警告;焦點框 **2dp `primary`、外擴 2dp**(ADR 0024 §決定 1)。 +- 字級只用 M3 `textTheme` 角色;元件固定尺寸(封面上限、面板寬度)放 theme 目錄的 **`AppLayout`**(ADR 0024 §決定 1)。 +- 播放頁的毛玻璃(半透明表面色約 60–72%+一般模糊、系統「減少透明度」或高對比時改不透明)——播放頁屬 M2,但 token 要先留(ADR 0024 §決定 1)。 +- `material_ui` 的 import 路徑**在建立 `app/` 時依當時 stable 的官方建議決定**(ADR 0024 §決定 1)。 +- **字型**:`fontFamilyFallback` 依目前語言排序、由平台層提供;繁中 Windows `Microsoft JhengHei UI`、`Microsoft JhengHei`,其他平台 `Noto Sans TC`;簡中 Windows `Microsoft YaHei UI`、`Microsoft YaHei`,其他平台 `Noto Sans SC`;英文清單把繁中放前(ADR 0024 §決定 2)。 +- **斷點**:自有 `WindowClass`,與 M3 同值:**compact(< 600)、medium(600–839)、expanded(840–1199)、large(1200–1599)、extraLarge(≥ 1600)**(ADR 0024 §決定 3)。 +- **i18n**:slang,**`base_locale: zh-TW`**,三語言(zh-TW、zh-CN、en);新字串先寫繁中,缺字退回繁中;子視窗與懸浮窗字串經型別化訊息傳入(後者是 M7)(ADR 0024 §決定 7)。 +- **無障礙與鍵盤**:只有圖示的按鈕都有 tooltip 與語意標籤;App 內快捷鍵固定、不可自訂、只在 FMP 為前景且焦點不在輸入框時有效——表列空白鍵、Ctrl+←/→、Shift+←/→、Ctrl+↑/↓、Ctrl+S、Ctrl+R、Ctrl+F、Ctrl+L/Ctrl+Q、Esc、F6、Ctrl+,(ADR 0024 §決定 8)。 +- `FocusTraversalGroup` 分三區(導覽/內容/播放列),Tab 只在區內移動(ADR 0024 §決定 8)。 +- 全域快捷鍵照舊:可自訂、預設關、預設 Ctrl+Alt+…;同一組按鍵時全域優先;錄製時與 App 內相同就提示(ADR 0024 §決定 8)——全域快捷鍵的實作屬 M8,M1 只需無衝突。 + +**(b) M1 的驗證** +- lint `fmp_design_tokens`:`lib/ui/`(theme 目錄除外)不得在 `EdgeInsets.*`、`SizedBox` 寬高、`BorderRadius.circular`、`fontSize:` 使用數字字面值(`0` 除外),也不得寫 `Color(0x…)`、`Colors.*`;依 ADR 0015 寫雙向變異測試(ADR 0024 §如何確認)。 +- widget 測試:首頁、搜尋、歌單、播放頁、設定在淺色與深色主題下通過 `meetsGuideline(labeledTapTargetGuideline)` 與 `textContrastGuideline`;播放頁以最淺與最深的測試封面各測一次(ADR 0024 §如何確認)——播放頁屬 M2。 +- 快捷鍵與焦點 widget 測試:空白鍵、Esc、F6,以及**輸入框內空白鍵只輸入空格**;播放列三段寬度的控制項集合、曲名不小於 160dp(ADR 0024 §如何確認)——播放列屬 M2。 +- golden(`alchemist`,色塊字型):播放頁 B 在 1000、1400、1800 寬、播放列三段寬度;只守版面結構、數量保持少(ADR 0024 §如何確認)——M2。 +- i18n:三語言 key 集合相同(缺一條即紅)(ADR 0024 §如何確認)。 +- §7:**輸入框內空白鍵只輸入空格;F6 焦點切換;Windows 繁中字形由正黑體顯示**。 + +**(c) 不在 M1** +- 播放頁方案 B、播放列三段、App 內快捷鍵**全表**、焦點三區——M2(`milestones.md` §M2)。**注意**:§7 又把「F6 焦點切換」放進 M1,見 §3。 +- 右上「正在播放」面板、搜尋頁 chip 列、設定頁 list-detail、`intl` 的 `NumberFormat.compact`(ADR 0024 §決定 3、6)——隨各頁所屬里程碑。 +- snake 導覽殼(bottom nav/NavigationRail/drawer)——ADR 0024 §決定 3 只給表;M1 是否建殼未寫死,見 §3。 +- 使用者指南刪除與 `docs/user-guide.md`——M9(ADR 0024 §決定 9、`milestones.md` §M9)。 +- dynamic color、液態玻璃、全 App 毛玻璃、各平台原生風格——皆否決(ADR 0024 §考慮過的選項)。 +- Linux 是否內建 Noto CJK——Linux 平台任務(ADR 0024 §決定 2)。 + +**(d) ADR 已固定的名稱** +- 型別:`AppTokens`、`AppLayout`、`WindowClass`。 +- 值:上列間距、圓角、斷點、字型名。 +- 設定:`base_locale: zh-TW`;三語系 zh-TW/zh-CN/en。 +- lint:`fmp_design_tokens`。 +- 套件:`intl`、`slang`、`alchemist`。 +- 檔案:`docs/user-guide.md`(M9)。 + +--- + +### ADR 0025 — Debug 頁與開發者模式 + +**主體屬 M3**(`milestones.md` §M3:「Debug 頁與插件開發工具(ADR 0025、0015 §7)」)。 + +- (a) M1 唯一相關:ADR 0011 §決定 7 的「開發者」設定組要被建出來(分組表在 M1 的 drift schema 裡),因為 ADR 0025 §決定 1 的 `developerMode`、`logLevel` 兩欄位住在那裡;但欄位清單按 ADR 0026 §決定 2「在引入該組設定的里程碑定案」——也就是 M3。 +- (c) 八區塊 list-detail、log JSON Lines/保留 7 天、網路摘要檢視、播放狀態、音源健康檢查、插件開發工具、資料庫唯讀瀏覽與「檢查」、重設資料、診斷包——全部 M3(ADR 0025 §決定 2–10)。 +- (b) §8(M3):Windows release 版開啟開發者模式、重啟後仍開啟、再從總開關關掉;Debug 頁看得到一次搜尋的網路摘要;匯出的診斷包能以解壓工具打開。 + +--- + +### ADR 0026 — 里程碑與切換(定義 M1 的任務結構) + +**(a) M1 要做的** +- **里程碑任務**:`fmp-rewrite` 的 child;開工時走 brainstorm,擁有者核准一次 prd/design/implement;implement 列出 PR 子任務與先後順序(Trellis 的 parent/child 不表達依賴)(ADR 0026 §決定 1)。 +- **PR 子任務**:里程碑任務的 child;一個分支、一個 PR,合進 `main`;prd 只寫做什麼與驗收,PR 描述附 review 指南;合併後 `app/` 可編譯、測試全綠;在已核准範圍內直接做,遇到未定的事才問(ADR 0026 §決定 1)。 +- **里程碑驗收**:Android 與 Windows 各做一次端到端實際操作,加上併入的實測項目(ADR 0026 §決定 1)。 +- 排序原則:縱向切片,每個里程碑結束時多一件可以實際操作的事(ADR 0026 §決定 2)。 +- 追蹤只用 Trellis 任務樹;清單與狀態在 `milestones.md`(ADR 0026 §決定 1)。 + +**(b) M1 的驗證** +- 每個里程碑任務 archive 前,`milestones.md` 的狀態欄與驗收項目逐項打勾;未打勾的不能 archive;**這是 review 點,不是自動閘門**(ADR 0026 §如何確認)。 +- 里程碑的範圍若在開工時要大改,要回來修 `milestones.md` 並說明原因(ADR 0026 §後果)。 + +**(c) 不在 M1** +- M2–M9 的里程碑與平台任務(ADR 0026 §決定 3、4)。 +- 切換放行條件(功能 E1–E17、效能 5%、資料比對、2 週試用)——M9(ADR 0026 §決定 5)。 +- 加開 GitHub Milestones 或 Projects——否決(ADR 0026 §考慮過的選項)。 + +**(d) ADR 已固定的名稱** +- 任務結構:`fmp-rewrite` 的 child = 里程碑任務;里程碑任務的 child = PR 子任務。 +- 清單檔:`.trellis/tasks/09-26-fmp-rewrite/milestones.md`。 + +--- + +### ADR 0027 — 實機驗證(M1 改寫 skill) + +**(a) M1 要做的** +- **M1 時為 `app/` 改寫 verify-on-device skill**;**根目錄舊專案的 skill 維持原樣**,給緊急修正用,切換 PR 時移除(ADR 0027 §決定 4)。 +- 預設模式是**重播**:實機驗證一律跑 **dev flavor**,每個插件切成「重播」,或使用 `app/` 的測試插件(ADR 0027 §決定 1)。 +- 改用真實連線的條件:只在改動本身是插件、網路層、登入,或正在錄製 fixture 時;只做最少操作;回報寫明「模式:真實」與做了哪些請求(ADR 0027 §決定 2)。 +- 平台分工:Android 模擬器與 Windows 都在**每個改到使用者看得到的 PR** 驗,**M1 加入 skill**(ADR 0027 §決定 3 的表)。 +- 每個平台的操作說明沿用現在 skill 的閉環(啟動 → 執行 → 觀察 → 操作 → 收尾),放在 `references/<平台>.md`(ADR 0027 §決定 3)。 + +**(b) M1 的驗證** +- `app/AGENTS.md` 的驗證段寫明「預設重播、真實連線的條件、Android 與 Windows 每個 PR」;**這是 review 點,實機驗證無法寫成測試**(ADR 0027 §如何確認)。 +- 實機驗證的回報格式包含「平台」與「模式:重播/真實」;PR review 指南缺這兩項就退回(ADR 0027 §如何確認)。 +- 里程碑驗收表在 Linux 平台任務完成後才含「Linux 冒煙測試」一格(ADR 0027 §如何確認)。 + +**(c) 不在 M1** +- 現在就改寫根目錄舊專案的 skill(ADR 0027 §決定 4)。 +- Linux(VMware Ubuntu 桌面,X11 與 Wayland)、macOS、iOS 模擬器的冒煙測試——各自平台任務(ADR 0027 §決定 3、ADR 0026 §決定 4)。 + +**(d) ADR 已固定的名稱** +- 檔名:`app/AGENTS.md`;skill 的 `references/<平台>.md`;`app/test/fixtures/plugins/` 的測試插件。 +- 現有 skill 的字串:`references/android.md`、`references/windows.md`、`references/runtime-state.md`;`scripts/ax_flatten.py`、`scripts/msaa_tree.ps1`、`scripts/smtc_probe.ps1`。 + +--- + +## 2. 跨 ADR 的相依圖 + +以下為 M1 各項的建議建置順序(箭頭 = 「左邊要先有/先定,右邊才能做」)。順序依 ADR 0009–0014 與 phase2-plan §2、§3 的依賴,加上 M1 的實際需要;不是 ADR 明定的強制序。 + +1. `app/` Flutter 專案骨架 + flavor `dev`/`prod` + App 身分 + `app/AGENTS.md`(ADR 0008 §決定 1–3、ADR 0015 §決定 8) +2. `fmp_lints` 套件骨架 + `analysis_options.yaml` + 接線哨兵 + 首批規則(ADR 0015 §決定 2)→ 需 1 +3. 平台層骨架 + `PlatformCapabilities` + 目錄規則 + 單一實例鎖 + dev/prod 身分與資料目錄隔離(ADR 0009 §決定 1、2、7;ADR 0015 §決定 8)→ 需 1 +4. drift + `sqlite3` + 最小 schema + schema 快照 + 資料層邊界(repository)(ADR 0010 §決定 1–3)→ 需 3(資料庫檔在平台層定義的資料目錄) +5. `TrackKey` 格式(含 cid)+ 測試(ADR 0008 檔頭補充、ADR 0005、ADR 0010 §決定 2)→ 需 4(`tracks` 的唯一鍵) +6. 設定分組表骨架(八組單列表)+ Riverpod Notifier 模式(ADR 0011 §決定 7)→ 需 4 +7. log 門面 + 遮蔽函式 + log 檔(`logs/`、2MB×3)+ 網路紀錄攔截器(ADR 0011 §決定 1–4)→ 需 3(log 目錄)、6(log 層級設定) +8. `AppError` sealed 分類 + 網路層重試策略(Riverpod retry 關閉、退避、`Retry-After`)(ADR 0013 §決定 1–4)→ 需 7(錯誤經門面寫入、遮蔽) +9. 網路層:API client + 媒體 client + 攔截器順序 + 轉址規則 + `AuthRequirement` 宣告點(ADR 0012 §決定 1、2)→ 需 7(網路紀錄)、8(錯誤對應) +10. JS 執行環境(`flutter_js`/QuickJS)+ 宿主 API v1 最小集 + manifest + 從檔案載入 B 站插件(ADR 0014 §決定 1–5)→ 需 9(`http.request`)、8(結構化錯誤)、7(`log`) +11. 播放核心最小集:`PlaybackController` + `AudioBackend` 兩實作 + 兩首的佇列 + 前瞻交接(ADR 0018 §決定 1–3、6)→ 需 10(`resolveStream`)、8(`RecoveryPolicy`)、3(後端與可播格式) +12. `Toaster` + `ToastHost`(`MaterialApp.builder`、`ScaffoldMessenger`+透明 `Scaffold`)(ADR 0023 §決定 1–3)→ 需 8(`error(AppError)`)、7(錯誤歷史) +13. UI token(`AppTokens`/`AppLayout`)+ `WindowClass` 斷點 + 字型 fallback + slang 三語言骨架 + 播放快捷鍵(ADR 0024 §決定 1、2、3、7、8)→ 需 3(字型 fallback)、12(phase2-plan §2:D3 → D5) +14. 零聯網兩道防線(`dart_test.yaml`、`flutter_test_config.dart` 的 `HttpOverrides`)+ fixture 格式 + 契約執行器 + `checks.json` + 測試插件(ADR 0015 §決定 3–6)→ 需 1、2、10(執行器要載入 QuickJS) +15. CI 切分(`dorny/paths-filter`)+ `app` job(format/analyze/哨兵/lint 測試/`flutter test`/契約執行器/五平台建置)+ `always()` 彙總(ADR 0015 §決定 9)→ 需 2、14 +16. release-please 發版 workflow dry-run(`app/CHANGELOG.md`、manifest、`dart` strategy)(ADR 0022 §決定 1)→ 需 1、15 +17. 為 `app/` 改寫 verify-on-device + `app/AGENTS.md` 驗證段(ADR 0027 §決定 1–4)→ 需 11(可播的曳光彈)、12(可驗的 UI) +18. YouTube.js 限時探針(`flutter_js` 能否搜尋並解出串流)(ADR 0014 §決定 10)→ 需 10;可與 11–17 並行,失敗時把結論帶回 M3 + +張成單線(供 PR 排序參考): + +`1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12 → 13 → 14 → 15 → 16 → 17`,18 與 11–17 並行。 + +其他單向約束(不是上面的主線,但成立): + +- 7(log 門面)→ 9(網路層):ADR 0011 §決定 4 的網路紀錄要經門面。 +- 8(`AppError`)→ 10(宿主結構化錯誤):ADR 0014 §決定 5。 +- 3(平台層)→ 11(後端與可播格式):ADR 0018 §決定 3、ADR 0009 §決定 2。 +- 4(drift schema)→ 6(設定表)→ 7(log 層級設定):ADR 0011 §決定 7、ADR 0025 §決定 1。 +- 12(Toast)→ 13(UI):phase2-plan §2 的 `D3 → D5`。 +- 14(執行器)→ 15(CI 的契約執行器 job):ADR 0015 §決定 6、9。 + +--- + +## 3. 未定或 ADR 之間矛盾之處 + +以下每一條都是 planner/brainstorm 要解掉的;沒有解掉就會在 implement 時卡住。 + +### 3.1 `app/` 的 spec 放哪 +`phase2-plan` §10:「**M1 開工時要決定:`app/` 的 spec 放哪(Trellis `packages:` 或其他)。**」 +現況:`.trellis/config.yaml:58-78` 的 `packages:` 整段是**註解掉的範例**,未啟用;`.trellis/spec/` 目前只有舊專案的六大目錄(`data`、`guides`、`services`、`shared`、`testing`、`ui`)。這同時影響 `trellis-implement`/`trellis-check` 子代理載入 spec 的路徑(`phase2-plan` §10)。 + +### 3.2 Flutter 版本:ADR 說「當時的 stable」,CI 卻必須釘一個版本 +`milestones.md` §M1:「`app/` 新專案,Flutter 用當時的 stable」。 +但 `.github/workflows/ci.yml:28` 現在釘的是 `FLUTTER_VERSION: '3.47.1'`(舊專案的 job),`.claude/skills/verify-on-device/SKILL.md:20-21` 也寫「Flutter 3.47.x」。既有的 `.github/workflows/release.yml:22` 同樣釘 `3.47.1`。**ADR 沒有指定 `app/` job 的 Flutter 版本**,也沒有說要不要跟舊專案同版。 + +### 3.3 指令檔分家尚未經擁有者核准 +`phase2-plan` §10:「**M1 的第一個 PR:指令檔分家**(2026-09-28 盤點,**尚未問擁有者**,M1 brainstorm 時提出)。」 +建議做法(同段):根目錄 `AGENTS.md` 縮成共用部分;舊專案規則搬到 `lib/AGENTS.md`;`app/AGENTS.md` 用繁中;spec 以 Trellis `packages:` 分成舊專案與 `app`。**這是提案,不是已定決定。** + +### 3.4 `AuthRequirement` 屬 M1 還是 M3 +`milestones.md` §M1:「網路層(不含登入,ADR 0012)」;§M3:「帳號與 `CredentialStore`、`AuthRequirement`(ADR 0012,E6)」。 +但 ADR 0012 §決定 2:「**帶憑證的單一宣告點**:每個請求在音源插件的定義處宣告 `AuthRequirement`」,且 ADR 0014 §如何確認要求契約測試涵蓋「`AuthRequirement`」。M1 的 B 站插件(從檔案載入)就會宣告它。→ M1 至少要落 `AuthRequirement` 的 enum 與攔截器掛鉤,登入流程仍屬 M3。 + +### 3.5 `PermissionGateway` 跨 0009(M1 能力)與 0020(M6 定義) +ADR 0009 §決定 1 把「執行期權限」列為平台層能力之一;ADR 0009 §決定 4:「**不寫空實作**:未驗證的平台宣告全部能力為『沒有』、沒有實作檔」。 +ADR 0020 §決定 9 才定義 `PermissionGateway` 的四種權限與流程(M6)。 +→ M1 的平台層是否要有 `PermissionGateway` 介面(空宣告)未寫死;M1 沒有任何需要權限的功能。 + +### 3.6 記憶體網址快取/離線狀態(ADR 0016)在 M1 還是 M2 +ADR 0018 §決定 6:「本機下載檔 → **記憶體網址快取(ADR 0016)** → 插件 `resolveStream`」;§決定 7:「**不在 `Online` 時暫停計數(ADR 0016)**」。 +但 `milestones.md` §M2 把「統一快取庫與離線狀態(ADR 0016)」整包列在 M2。 +→ M1 的曳光彈(連播兩首)需不需要 64 筆的網址快取與網路狀態判定,ADR 沒說。 + +### 3.7 F6 焦點三區同時被列在 M1 與 M2 +`phase2-plan` §7:「ADR 0024:輸入框內空白鍵只輸入空格;**F6 焦點切換**;Windows 繁中字形由正黑體顯示。」 +`milestones.md` §M2:「播放頁方案 B、播放列三段、App 內快捷鍵全表、**焦點三區**(ADR 0024)」。 +→ 「F6 焦點切換」在 §7(併入 M1)與 §M2(焦點三區)各出現一次,範圍重疊。 + +### 3.8 M1 的 log 檔格式:純文字行還是 JSON Lines +ADR 0011 §決定 2 只定「單檔 2MB、保留 3 個、寫入失敗不影響 App」,**沒定格式**。 +ADR 0011 §後果:「**log 保留 7 天與 JSON Lines 格式**、Debug 頁見 ADR 0025」。 +ADR 0025 §決定 3(M3):「**檔案格式**:JSON Lines,一筆一行」;§後果壞的也寫「log 檔**改成** JSON Lines」。 +→ M1 落地時要選:先用純文字行(M3 再改 JSON Lines),或一次到位。ADR 0011 §決定 3 的遮蔽要求兩者都成立。 + +### 3.9 `fmp_lints` 哪幾條規則進 M1 +ADR 0015 §決定 2 的表列 10 條,末段又列 3 條後續 ADR 新增(`fmp_periodic_timer_owner`(0017,M2)、`fmp_toast_entry`(0023,M1)、`fmp_design_tokens`(0024,M1))。**ADR 沒說哪些在 M1 落地**。 +依「閘門要對著現在還有人呼叫的東西」與 ADR 0015 §如何確認的「第一里程碑實測:`dart analyze` 看得到插件診斷」,`fmp_lints` 套件與至少部分規則在 M1;`fmp_periodic_timer_owner` 的消費點(排程器)在 M2。 + +### 3.10 drift「最小 schema」是哪幾張表 +`milestones.md` §M1 只說「drift 最小 schema 與快照(ADR 0010)」。ADR 0010 §決定 2 給的是原則(關係、`TrackKey` 唯一鍵、只存事實、下載紀錄獨立表、設定表、UTC epoch 毫秒),**沒有列舉 M1 的表**。 +ADR 0026 §決定 2 提供線索:「**各組設定的欄位清單**(ADR 0011),在引入該組設定的里程碑定案」。 +→ M1 要自己定:設定表(八組)、`tracks`(`TrackKey`)、佇列持久化表(ADR 0018 §決定 10)等的最小集。 + +### 3.11 isar_community 與 sqlite3 共存怎麼在 M1 驗證 +ADR 0010 §決定 4:「舊資料匯入(legacy import)… 位於 `app/lib/legacy_import/`,是**唯一**依賴 `isar_community` 與 `flutter_secure_storage` 10.x 的地方」。 +`milestones.md` §M5 才做 `legacy_import`。 +但 ADR 0010 §後果與 `phase2-plan` §7 都要求 **M1 在 Android、Windows 實測兩套原生庫共存**,以及 sqlite3 的 Android 16KB page size 對齊。 +→ M1 要如何在 `legacy_import` 還不存在時證明共存(暫時的 spike/測試依賴,或提前建一個最小 `legacy_import`)未定。 + +### 3.12 release-please dry-run 怎麼做 +ADR 0022 §決定 1:「**重寫期間不發版**」;§如何確認與 §7:「release-please 的發版 PR 與同一 workflow 的建置、驗證、發布跑通(**測試 repo 或 dry-run**)」。 +→ 「測試 repo 或 dry-run」兩種都沒被選;且 ADR 0022 §後果:「release-please **草稿與建 tag 的確切選項在落地時以官方文件確認**」。 +另外,舊專案的 `.github/workflows/release.yml` 必須留著(ADR 0008 §決定 4 的緊急修正),所以 M1 新增的 workflow **檔名未定**(`release.yml` 這個名字已被舊專案佔用)。 + +### 3.13 `material_ui` 的 import 路徑 +ADR 0024 §決定 1:「**`material_ui` 的 import 路徑在建立 `app/` 時依當時 stable 的官方建議決定。**」 +ADR 0024 §後果也把它列為「之後要注意:Material 拆成 `material_ui` 的遷移時程」。 + +### 3.14 `window_manager` 的版本(0.5.x 已停止維護) +ADR 0021 §後果:「**`window_manager` 0.5.x 已停止維護(0.6.0 改建在 `nativeapi`),換套件的成本落在平台層**。」 +ADR 0009 §決定 6:「托盤、視窗、快捷鍵、多視窗**沿用現有套件**並擴到其他桌面平台」、「桌面套件需要修補時用 **git 依賴鎖 commit**,並註明上游 issue」。 +→ M1 就要用 `window_manager` 做 Windows/Linux 自訂標題列(ADR 0009 §決定 8),選 0.5.x(停維護)或 0.6.0(換底層)未定。 + +### 3.15 契約執行器能否在 `flutter test` 內載入 QuickJS +ADR 0015 §如何確認:「第一個里程碑實測:… **契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 `integration_test`)**」。 +ADR 0015 §決定 9 的 `app` job 同時列了「契約執行器」與「Linux 與 Windows 的整合測試」。 +→ 這是 M1 要**做出來的答案**,不是先驗條件;結果直接決定 CI 有哪些 job 與它們跑在什麼 runner 上。 + +### 3.16 M1 的「兩首的佇列」邊界 +`milestones.md` §M1:「播放核心最小集:兩個後端、**兩首的佇列**、前瞻交接(ADR 0018)」;§M2 才是「完整 `QueueModel` 與 `RecoveryPolicy`」。 +ADR 0018 §決定 4 的模式(`queue`/`temporary`/`mix`/`live`/`detached`)、§決定 5 的隨機、§決定 10 的持久化**哪些屬 M1 的「兩首」未寫死**。 +→ 需要 planner 明定 M1 的佇列:是否持久化、是否只有 `queue` 模式、位置存檔要不要做。 + +### 3.17 M1 是否建導覽殼 +`milestones.md` §M1:「token、斷點、字型、slang 三語言骨架、播放快捷鍵(ADR 0024)」——只提 token/斷點/字型/i18n/快捷鍵。 +ADR 0024 §決定 3 的 `WindowClass` 表把導覽(底部導覽列/NavigationRail/常駐導覽抽屜)綁在斷點上。 +→ M1 是只出 `WindowClass` enum,還是連導覽殼一起(曳光彈要有搜尋頁與播放入口)未寫死。 + +### 3.18 ADR 0026 的「一個 PR」與 M1 的大小 +ADR 0026 §背景已記:parent prd 同時要求「每個里程碑是一個 child task」與「每個 child task 一個可 review 的 PR」,**第一個里程碑一個 PR 裝不下**;§決定 1 的解方是「里程碑任務底下開 PR 子任務」,§後果也寫「M1 很重」。這是給 planner 的前提:M1 必然是多個 PR。 + +### 3.19 舊 ADR 0001–0007 的適用範圍 +`phase2-plan` §10:「所有設計決定以 ADR 為準:`docs/adr/0008`–`0027`;**舊 ADR 0001–0007 仍描述根目錄舊專案,於切換 PR 刪除**。」 +M1 會用到的舊 ADR:0005(`TrackKey` 含 cid,確認沿用;`phase2-plan` §5「§14 ADR」列「0005 分 P 以 cid 區分:確認(也是舊資料遷移要用的格式)」)。0002、0007 由 0010/0009 取代;0003、0004 在 0018/0020 重新決定;0001、0006 已確認。→ 讀 M1 相關 ADR 時不要把 0001–0007 當現行規範。 + +--- + +## 4. 現況 repo 檔案:M1 要改或不要動 + +### `.github/workflows/ci.yml` +- **現況**:單一 workflow、**沒有路徑過濾**(`:3-7` 的註解刻意說明:純文件改動不能跳過 `validate`,因為文件承載規則);三個 job——`validate`(`:33`)、`build-android`(`:87`)、`build-windows`(`:124`),全部是舊專案;`:28` 釘 `FLUTTER_VERSION: '3.47.1'`;`:64-68` 跑 `dart run build_runner build`+`dart run slang`(Isar 與 slang);`:71` `flutter analyze`;`:77` `flutter test --coverage --exclude-tags live`。 +- **M1 要改**:ADR 0015 §決定 9 要求 `dorny/paths-filter` 依專案切分——`app/**` 與 `.github/**` 觸發 `app` 的 job,`app/` 以外的任何變動觸發舊專案的 job;**一個 `always()` 彙總 job 當唯一必要檢查**。`app` 的 job 另含 `dart analyze --fatal-infos`、接線哨兵、lint 規則測試、不加參數的 `flutter test`、契約執行器、五平台建置、Linux 與 Windows 整合測試。 +- **M1 不要動**:舊專案的三個 job 維持現狀,只在根目錄變動時跑(ADR 0015 §決定 9:「舊專案的 job 維持現狀…`app/` 的 PR 不被舊專案的不穩測試擋住」)。`:3-7` 那段「不用 `paths-ignore`」的理由仍適用於舊專案那一半。 +- 注意:`app/` 的零聯網用 `dart_test.yaml` 的 `skip`(ADR 0015 §決定 3),跟舊專案 `--exclude-tags live`(`:77`)是兩套。 + +### `.github/workflows/release.yml` +- **現況**:tag 驅動(`v*`)+ `workflow_dispatch`;`prepare`(`:27`)解析 tag 與 `versionCode`;`build-android`(`:74`)、`validate`(`:180`)、`build-windows`(`:216`)、`verify`(`:361`)、`release`(`:419`);以 `sed`/`pwsh` 手改 `pubspec.yaml` 版本(`:113-115`、`:239-244`);checksums 產生(`:390-399`);`draft: false` 直接發布(`:508-518`);`:309-310` 把 AppUserModelID 寫進 Inno ISS。 +- **M1 不要動**:ADR 0008 §決定 4 的舊版緊急修正要靠它;ADR 0026 §決定 5 的切換才把 `release.yml` 改指向 `app/`。ADR 0022 的 release-please 對 `app/` 是新的 workflow(檔名未定,見 §3.12)。 +- 相關:`tool/release/verify_release_assets.dart`(`:406`)與 `inno_bundle` 設定(`pubspec.yaml:121-122` 的 AppId)都屬舊專案,切換 PR 才動(ADR 0008 §決定 5、ADR 0022 §決定 4 要沿用檔名與 Inno AppId)。 + +### `orca.yaml` +- **現況**:`worktree.sharedDirectories` 共用 `.trellis/workspace`(`:3-8`);`setupAgentStartupPolicy: wait-for-setup`(`:11`);`scripts.setup` 在 repo 根跑 `flutter pub get`、`dart run build_runner build`、`dart run slang`(`:18-21`)——全部針對舊專案。 +- **M1 的關係**:`phase2-plan` §10 把它列在「舊內容會誤導在 `app/` 工作的 AI」的清單(「`orca.yaml` 的 setup…都只對舊專案」)。但 ADR 0008 §決定 5 把 `orca.yaml` 改指向 `app/` 排在切換 PR。 +- → M1 至少要處理:在 `app/` 開 Orca worktree 時,setup 要在 `app/` 內跑(且 `app/` 的 codegen 只有 slang,沒有 Isar build_runner);`orca.yaml` 目前沒有第二個專案的概念。這是未定項。 + +### 根目錄 `AGENTS.md` +- **現況**:全為舊專案——Verification 表(`:15-22` 的舊測試路徑)、`:24-32` 的 codegen 與 `flutter test --exclude-tags live`、`:34-39` 的 on-device 規則(指向舊 `verify-on-device`)、`:43-51` Conventions(Isar/`docs/development.md`)、`:53-97` Boundaries(`lib/` 路徑、`AudioController`、`Isar`、`test/*/static_rules/*`)、`:99-116` Trellis 段。 +- **M1 要改**:`phase2-plan` §10 指出「Claude Code 以 repo 根目錄為工作目錄時,**每個 session 開頭都會載入它**;`app/AGENTS.md` 只在讀到 `app/` 裡的檔案時才載入」,建議把根目錄縮成共用部分、舊規則搬到 `lib/AGENTS.md`、`app/AGENTS.md` 用繁中。**尚未問擁有者**(§3.3)。 +- **M1 不要動**:`lib/` 的規則本身(搬到 `lib/AGENTS.md` 是移動不是修改);`:118-138` 的 Trellis managed block 由 `trellis update` 管。 +- ADR 0015 §如何確認 要求 `app/AGENTS.md` 列出的每條靜態規則都寫出對應規則名;ADR 0027 §如何確認 要求 `app/AGENTS.md` 的驗證段寫「預設重播、真實連線的條件、Android 與 Windows 每個 PR」。→ `app/AGENTS.md` 的內容有兩則 ADR 的硬要求。 + +### `.claude/skills/verify-on-device/` +- **現況**:`SKILL.md` 是舊專案的閉環——Android 模擬器必要、Windows 只在 Windows 專屬改動(`:17-18`);`:20-21` 記「Flutter 3.47.x」;`:23-27` 三個 `references/`;`:90` 的觀測表把「Live object fields, HTTP traffic, **Isar**」指向 `references/runtime-state.md`;`:117` 用 `com.personal.fmp` 當 launch 目標;`:79-81` 提到 Windows AXTree 凍結(`docs/troubleshooting.md`)。 +- `references/`:`android.md`、`windows.md`、`runtime-state.md`;`scripts/`:`ax_flatten.py`、`msaa_tree.ps1`、`smtc_probe.ps1`。 +- **M1 要改**:ADR 0027 §決定 4「**M1 時為 `app/` 改寫 skill**」;§決定 1–3:預設重播、跑 dev flavor、Android 與 Windows 每個使用者可見的 PR 都驗、`references/<平台>.md`。`runtime-state.md` 的 **Isar 檢查要改成 drift**(ADR 0009/0010);`:117` 的 launch 目標要含 dev 身分(`com.personal.fmp.dev`,ADR 0015 §決定 8)。 +- **M1 不要動**:**根目錄舊專案的 skill 維持原樣**,給緊急修正用,切換 PR 時才移除(ADR 0027 §決定 4)。→ 若改寫方式是就地改同一份 skill,會違反這條;較可能是新增一份 app 範圍的 skill 或在 skill 內分兩套指令,這未定。 +- `scripts/` 三支工具與平台無關(AX/MSAA/SMTC),可沿用。 + +### 其他(`phase2-plan` §10 點名,風險較低) +- `.trellis/spec/` 20 檔描述舊專案;`session-start.py` 會列出 spec 索引,`trellis-implement`/`trellis-check` 依 `.trellis/spec/<package>/<layer>/` 載入。→ 與 §3.1 同一個未定項。 +- `docs/building.md`、`development.md`、`build-and-release.md`、`troubleshooting.md`:只對舊專案,是按需讀的人類文件,風險較低(`phase2-plan` §10)。 +- `.github/` 目前**只有** `dependabot.yml` 與 `workflows/`,**沒有** `ISSUE_TEMPLATE/`(ADR 0023 §後果明說「repo 目前沒有 issue 範本,落地時新增 `.github/ISSUE_TEMPLATE/bug_report.yml`」——屬 M3)。 + +--- + +## 5. 候選 PR 分組(供 planner 參考;非 ADR 決定) + +依第 2 節的順序,把 M1 切成可 review 的 PR。**這是建議,不是 ADR 或計畫的決定**;擁有者核准 prd/design/implement 時再定案(ADR 0026 §決定 1)。 + +1. 指令檔分家+`app/` 骨架:`app/` 專案、flavor、App 身分、單一實例鎖、`app/AGENTS.md`;根 `AGENTS.md` 縮成共用部分、舊規則搬到 `lib/AGENTS.md`;spec 的 `packages:` 決定(§3.1、§3.3;ADR 0008、0015 §決定 8、0027)。 +2. `fmp_lints` 骨架+接線哨兵+首批規則(ADR 0015 §決定 2;批次見 §3.9)。 +3. 平台層骨架+`PlatformCapabilities`+目錄規則(ADR 0009 §決定 1–8)。 +4. drift+`sqlite3`+最小 schema+快照+`TrackKey`(ADR 0010 §決定 1–3;表集見 §3.10)。 +5. 設定分組表+log 門面+遮蔽函式+log 檔(ADR 0011;格式見 §3.8)。 +6. `AppError`+重試策略(ADR 0013)。 +7. 網路層:API client+媒體 client+攔截器+`AuthRequirement` 掛鉤(ADR 0012;掛鉤範圍見 §3.4)。 +8. JS 執行環境+宿主 API v1+從檔案載入 B 站插件(ADR 0014 §決定 1–5)。 +9. 播放核心最小集:兩個後端+兩首的佇列+前瞻交接(ADR 0018;邊界見 §3.16)。 +10. `Toaster`+`ToastHost`(ADR 0023 §決定 1–3、5)。 +11. UI token+斷點+字型+slang 骨架+播放快捷鍵(ADR 0024;殼的範圍見 §3.17)。 +12. 零聯網防線+fixture+契約執行器+測試插件(ADR 0015 §決定 3–6;QuickJS 結論見 §3.15)。 +13. CI 切分+`app` job+`always()` 彙總(ADR 0015 §決定 9)。 +14. release-please dry-run workflow(ADR 0022 §決定 1;做法見 §3.12)。 +15. `app/` 的 verify-on-device 改寫+`app/AGENTS.md` 驗證段(ADR 0027)。 +16. 限時探針任務:YouTube.js 可行性(ADR 0014 §決定 10)——可插在第 9–15 之間並行。 + +`milestones.md` §M1 的兩格驗收(「兩平台端到端操作」「§7 全部項目」)在第 15 個 PR 之後由擁有者實機確認,依 ADR 0026 §如何確認(review 點,不寫成測試)。 diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-tooling-facts.md b/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-tooling-facts.md new file mode 100644 index 000000000..d7f56a3c8 --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/research/m1-tooling-facts.md @@ -0,0 +1,319 @@ +# M1 工具事實:套件版本與 Trellis `packages:` 機制 + +- 查證日期:2026-09-28(全部數字皆為當日所見) +- 來源規則:pub.dev JSON API(`https://pub.dev/api/packages/<pkg>`)、官方文檔、GitHub raw 檔與 `gh api`。 + 沒有一條來自記憶。每條事實後附來源與所見版本/日期。 +- 用途:餵 M1(`../prd.md`)的開工決策,以及 `../09-26-fmp-rewrite/phase2-plan.md` §7、§10 的未決事項。 + +--- + +## Part A — Trellis `packages:` 的實際行為(含實測) + +實測方式:在 scratchpad 複製一份最小 repo(`.trellis/scripts`、`.trellis/spec`、`.claude/hooks/session-start.py`), +填不同 `config.yaml` 後直接 import hook 的函式呼叫,並跑 `task.py create`。 + +### A0 現況(尚未宣告 packages) + +- `.trellis/config.yaml:58-78` 的 `packages:` / `default_package:` 整段被註解掉;`config.yaml:34` 是 + `session_auto_commit: false`,**沒有 `session:` 區塊** → `get_spec_scope` 回 `None`(`config.py:462-482`)。 +- 因此 `is_monorepo()` 為 `False`(`config.py:391-393`),spec 目錄是扁平的 + `.trellis/spec/<layer>/`(`config.py:396-405` 的 `get_spec_base` 回 `"spec"`)。 +- 現有兩個 active task 的 `task.json` 都是 `"package": null`。 + +### A1 spec 檔該放哪、扁平的能不能混用、有沒有 migration + +- 宣告 `packages:` 後 spec 必須放 `.trellis/spec/<package>/<layer>/`: + `get_spec_base` 回 `f"spec/{package}"`(`config.py:403-405`), + `get_spec_dir` = `repo_root / .trellis / get_spec_base(package)`(`paths.py:491`), + `_scan_spec_layers` 掃 `spec_dir / package`(`packages_context.py:30-41`)。 +- **可以混用,而且不會有任何提示**。舊的扁平 `.trellis/spec/<layer>/` 不會被刪、不會被擋、也不會被納入 + package 掃描;在 `get_context.py --mode packages` 的輸出裡它們只是消失(實測:宣告一個 `legacy` 套件後, + 扁平層 `data/services/shared/testing/ui` 全部不出現,該套件顯示 `Spec: not configured`)。 +- **沒有 migration 指令**。Trellis CLI 0.6.17 只有 `init / update / upgrade / uninstall / ablate / restore / mem / + workflow / platforms / channel`。唯一的相關提示是 `_check_legacy_spec`(`session-start.py:561-607`), + 而它**寫死只認 `backend` 與 `frontend`**(`session-start.py:575`);FMP 的層名是 + data/services/shared/testing/ui,實測回 `None` → 宣告 packages 後**不會出現任何「扁平 spec 已成孤兒」的警告**。 +- 要注意的細節:spec 目錄名來自**package 名**,不是 `path`。所以 `app: path: app` 與 + `legacy: path: .` 會產生 `.trellis/spec/app/` 與 `.trellis/spec/legacy/`,磁碟上不重疊。 +- 另:`_scan_spec_layers` 排除的是字面值 `"guides"`(`packages_context.py:40`), + `session-start` 另外排除 `.` 開頭的目錄(`session-start.py:677`)。 + +### A2 任務怎麼綁 package、session-start 與 subagent 怎麼選 index + +- 建立時:`task.py create ... --package <pkg>`。`task_store.py:363-376` 是 fail-fast 三段: + 非 monorepo → 只印 `Warning: --package ignored in single-repo project` 然後清成 `None`; + monorepo 且給的值不合法 → `Error: unknown package '<x>'. Available: ...` 並 `return 1`; + 沒給 → `resolve_package(repo_root=repo_root)`,順序是 **task_package → `default_package` → None** + (`config.py:420-440`)。值寫進 `task.json` 的 `"package"`(`task_store.py:536`)。 +- `add_session.py:1514-1537` 同一套,但推斷來源是**當前 active task 的 `package`** → `default_package`。 + `task.py list` 會多一個 `@<pkg>` 標籤(`task.py:453`)。 +- session-start:`_load_trellis_config`(`session-start.py:517-557`)直接讀 active `task.json` 的 + `package` 字串(`539-546`),再交 `_resolve_spec_scope`(`609-659`)決定 `allowed_pkgs`。 +- **subagent 注入完全不看 package**:`inject-subagent-context.py:483` 的 `get_agent_context` 只讀 + `<task>/implement.jsonl` 與 `check.jsonl`(空的時候回一段說明文字), + `get_implement_context`(`534`)的順序固定是 jsonl → prd.md → design.md → implement.md。 + 整個檔案裡沒有 package 或 spec_scope 的分支。**要注入 spec,就寫進 jsonl。** +- 已知落差:`.claude/agents/trellis-implement.md:59` 已寫 package-aware 的 + `.trellis/spec/<package>/<layer>/`,但 `.claude/agents/trellis-check.md:86` 仍寫死扁平的 + `.trellis/spec/<layer>/index.md`(monorepo 模式下會指到不存在的位置)。 + +### A3 根目錄(`.`)當一個 package、與其他 package 重疊 + +- 可以宣告,實測 `legacy: path: .` 只回報 `Path: .`,沒有錯誤。 +- spec 路徑不會重疊(見 A1:目錄名用 package 名)。 +- 真正的地雷在**命名**,兩個都實測過: + - package 取名 `.` → `_scan_spec_layers` 的 `spec_dir / "."` 解析成 spec 根, + 列出 `app, data, services, shared, testing, ui`,路徑長成 `.trellis/spec/./data/index.md`。 + - package 取名與既有扁層同名(例:`data`)→ `_scan_spec_layers` 掃 `spec/data/` 底下沒有子目錄, + 回 `[]` → 輸出 `Spec: not configured`;**但** `spec/data/index.md` 仍會被當扁平層注入(見下)。 +- **扁平層繞過 scope 過濾(本次最重要的發現)**:`_collect_spec_index_paths` + (`session-start.py:666-695`)的迴圈裡,`index_file.is_file()` 為真就 `append` 並 `continue` + (`680-682`),**這行在 `allowed_pkgs` 檢查(`685`)之前**。實測:`spec_scope: active_task` 且只允許 + `{app}` 時,扁平的 `data/services/shared/testing/ui` 五個 index 全部照樣注入。 + 結論:宣告 packages 之後若不搬 spec,等於每個 session 都多載入舊專案的 spec,而且沒有任何警告。 + (`spec/guides/index.md` 一律注入,是設計如此,`session-start.py:668-670`。) + +### A4 加 packages 對「現在跑得動的東西」有什麼改變 + +- package 目前**純屬 metadata**:沒有任何分支/worktree/路徑命名用到它 + (`resolve_session_branch`,`add_session.py:222`,只看 task.json 的 `branch` 或當前 git 分支)。 + 既有任務是 `package: null`,不會被回頭改寫。 +- 因為 root 本身是 git repo,`_discover_child_git_repos` 的 `discover_unconfigured=not isRepo` + 永遠是 `False`(`session_context.py:533/615/779/852`)→ polyrepo 掃描本來就不會啟動,宣告 packages 亦然。 +- 實際會變的行為只有四項: + 1. session-start 與 `get_context.py --mode packages` 改走 monorepo 輸出格式; + 2. `default_package` 會**自動蓋到新建立**的 task(`task_store.py:376`、`add_session.py:1528`); + 3. `--package` 給未知值從「被忽略」變成**硬錯誤 exit 1**(`task_store.py:370-373`)—— + 既有文檔/指令若寫了亂七八糟的 package 名,從此會失敗; + 4. 扁平 spec 仍被注入(A3 的 bug),沒有任何警告(A1)。 +- 沒有動到任何既有 task 的資料,也沒有動到 journal(`add_session.py:465` 的 package 只寫進 session 記錄, + 不影響既有檔案)。 + +--- + +## Part B — 版本事實 + +參照點:**Flutter stable 3.47.5(2026-09-18,內含 Dart 3.13.4)**。 +來源:官方 releases manifest `https://storage.googleapis.com/flutter_infra_release/releases/releases_windows.json` +(`current_release.stable` = `hash 6a19cca56475dbfba1478ee68d7bd0c2ef891da1`)。 +`release.yml` 目前釘 `FLUTTER_VERSION: '3.47.1'`(Dart 3.13.1)→ 落後現行 stable 四個 patch。 +近幾版:3.47.0/Dart 3.13.0 (2026-08-12)、3.47.1/3.13.1 (2026-08-19)、3.47.2/3.13.2 (2026-08-27)、 +3.47.3/3.13.3 (2026-09-09)、3.47.4/3.13.3 (2026-09-11)、3.47.5/3.13.4 (2026-09-18)。 + +### 表格 + +版本與日期全部取自 pub.dev JSON API(`https://pub.dev/api/packages/<pkg>`,欄位 +`latest.version` / `latest.published` / `latest.pubspec.environment`),所見日期 2026-09-28。 +「平台」取自 `latest.pubspec.flutter.plugin.platforms`。 + +| package | version | date | 平台 | notes | +|---|---|---|---|---| +| Flutter / Dart SDK | 3.47.5 / Dart 3.13.4 | 2026-09-18 | — | 現行 stable;CI 釘的 3.47.1 需更新 | +| `flutter_riverpod` | 3.4.3 | 2026-09-03 | 純 Dart | sdk `^3.12.0` | +| `riverpod_lint` | 3.1.9 | 2026-09-03 | 純 Dart | sdk `>=3.13.0-0`;**已遷移到新插件系統**,依賴 `analysis_server_plugin ^0.3.0` | +| `drift` | 2.35.0 | 2026-09-09 | 純 Dart | sdk `>=3.10.0 <4.0.0` | +| `drift_dev` | 2.35.0 | 2026-09-09 | 純 Dart | 與 drift 同版 | +| `drift_flutter` | 0.3.1 | 2026-07-11 | 純 Dart | | +| `sqlite3` | 3.6.0 | 2026-09-13 | 純 Dart | **3.x 內建 build hooks**,自行打包原生庫 | +| `sqlite3_flutter_libs` | 0.6.0+eol | 2026-02-15 | — | **已 EOL**。ADR 0010 不可用這個 | +| `isar_community` | 3.3.2 | 2026-03-23 | android/ios/linux/macos/windows | 只在 `legacy_import` 用(ADR 0010) | +| `isar_community_flutter_libs` | 3.3.2 | 2026-03-23 | android/ios/linux/macos/windows | 隨上面 | +| `flutter_secure_storage` | 11.2.0 | 2026-09-16 | android/ios/linux/macos/web/windows | 舊專案 pubspec 用 10.x 是**發版順序**考量,非技術阻礙 | +| `talker` | 5.1.20 | 2026-07-28 | 純 Dart | 日誌核心(ADR 0011) | +| `talker_flutter` | 5.1.20 | 2026-07-28 | 純 Dart | | +| `dio` | 5.11.1 | 2026-09-04 | 純 Dart | 與舊專案同版 | +| `slang` | 4.19.2 | 2026-09-12 | 純 Dart | | +| `slang_flutter` | 4.19.0 | 2026-08-06 | 純 Dart | | +| `slang_build_runner` | 4.19.0 | 2026-08-06 | 純 Dart | | +| `go_router` | 18.0.1 | 2026-09-02 | 純 Dart | flutter `>=3.44.0` | +| `just_audio` | 0.10.6 | 2026-06-29 | android/ios/macos/web | 後端 A(ADR 0018);無 Windows/Linux | +| `media_kit` | 1.2.6 | 2025-12-13 | 純 Dart(+libs 套件) | 後端 B;距今 9 個月 | +| `media_kit_libs_windows_audio` | 1.0.9 | 2023-09-27 | windows | **停在 2023-09**,與 ADR 0018 的註記相符 | +| `media_kit_libs_linux` | 1.2.1 | 2025-03-24 | linux | | +| `audio_service` | 0.18.19 | 2026-06-29 | android/ios/macos/web | 舊專案 pubspec 寫 0.18.15 | +| `audio_service_mpris` | 0.2.1 | 2026-03-15 | linux | | +| `smtc_windows` | 1.1.0 | 2025-08-18 | windows | 距今約 1 年 | +| `flutter_js` | 0.8.7 | 2026-01-27 | android/ios/linux/macos/windows | QuickJS/JSC + dart:ffi;見下方專節 | +| `window_manager` | 0.5.2 | 2026-07-04 | linux/macos/windows | **仍在出貨**;ADR 0021 說法有誤 | +| `nativeapi` | 0.4.0 | 2026-09-25 | 純 Dart | sdk `^3.13.0` | +| `nativeapi_flutter` | 0.4.0 | 2026-09-25 | —(未宣告 plugin platforms) | sdk `^3.13.0`、flutter `>=3.47.0`;**強制 Flutter 3.47+** | +| `tray_manager` | 0.7.0 | 2026-09-19 | linux/macos/windows | **大改**:改寫在 `nativeapi ^0.3.0` 上,flutter `>=3.47.0` | +| `hotkey_manager` | 0.2.3 | 2024-05-18 | linux/macos/windows | **最舊的一個**,約 2 年 4 個月無 release | +| `launch_at_startup` | 0.5.1 | 2025-04-01 | linux/macos/windows | 約 1 年 5 個月無 release | +| `desktop_multi_window` | 0.3.1 | 2026-08-26 | linux/macos/windows | | +| `connectivity_plus` | 7.3.1 | 2026-07-23 | android/ios/linux/macos/web/windows | | +| `file_picker` | 13.1.0 | 2026-09-15 | android/ios/linux/macos/web/windows | 聯邦化;v13 有 breaking | +| `path_provider` | 2.1.6 | 2026-06-15 | android/ios/linux/macos/windows | Flutter 官方維護,最穩 | +| `package_info_plus` | 10.2.1 | 2026-07-15 | android/ios/linux/macos/web/windows | | +| `permission_handler` | 13.0.2 | 2026-09-04 | android/ios/web/windows | v13 有 breaking;**macOS 未宣告** | +| `flutter_inappwebview` | 6.1.5 | 2024-10-08 | android/ios/macos/web/windows | stable 停在 2024-10;6.2 一直 beta | +| `share_plus` | 13.3.0 | 2026-07-23 | android/ios/linux/macos/web/windows | | +| `inno_bundle` | 0.12.0 | 2026-08-18 | windows(build-time) | v0.12 有 breaking | +| `flutter_lints` | 6.0.0 | 2025-05-27 | 純 Dart | 與舊專案同版 | +| `analysis_server_plugin` | 0.3.23 | 2026-09-11 | 純 Dart | 仍是 0.x;見下方專節 | +| `analyzer_testing` | 0.4.2 | 2026-09-11 | 純 Dart | 同名系列,一起升 | +| `analyzer` | 14.4.0 | 2026-09-11 | 純 Dart | sdk `^3.11.0` | +| `custom_lint` / `custom_lint_builder` | 0.8.1 | 2025-09-09 | 純 Dart | ADR 0015 已否決;最後發版 2025-09 | +| `alchemist` | 0.14.0 | 2026-03-13 | 純 Dart | CI golden | +| `googleapis/release-please-action` | **v5.0.0** | 2026-04-22 | node24 | 見下方專節 | +| `dorny/paths-filter` | **v4.0.3** | 2026-08-05 | node24 | 見下方專節 | + +### 需要改 ADR 的落差 + +1. **`sqlite3_flutter_libs` 不可用**(`0.6.0+eol`,2026-02-15)。ADR 0010 寫的「native assets 自動打包五平台原生庫」 + 要靠 `sqlite3` 3.x 內建的 build hooks,不是這個套件。ADR 0010 的套件名要改。 +2. **ADR 0021 對 `window_manager` 的敘述不成立**:0.5.2 於 2026-07-04 仍正常發版;真正的變化是 + `tray_manager` 0.7.0(2026-09-19)改寫到 `nativeapi` 之上,而 `nativeapi`/`nativeapi_flutter` 是 2026-09-25 的新套件。 +3. **`hotkey_manager` 0.2.3(2024-05-18)是這個清單裡最舊的相依** —— 全域快捷鍵是 ADR 0009 宣告的能力之一, + 而它兩年多沒 release。M1 若要在 Windows 做全域快捷鍵,這條值得先確認能不能用(含 repo 是否仍在維護)。 +4. **`tray_manager` 0.7.0 與 `nativeapi_flutter` 都把 Flutter 下限拉到 3.47.0**。專案目前用 3.47.5 沒問題, + 但這等於把「可用的 Flutter 版本」綁在很新的地方;`release.yml` 的釘版要一起往上。 +5. **`media_kit_libs_windows_audio` 停在 2023-09-27**(ADR 0018 已註記),目前仍是最新版。 + +--- + +## 專節:ADR 直接問到的四件事 + +### 1. `analysis_server_plugin` 是不是 stable、怎麼開、診斷看不看得到 + +- 官方文件 `pkg/analysis_server_plugin/doc/using_plugins.md`(Dart SDK main 分支,2026-09-28 所見): + - 「Analyzer plugins are supported starting in Dart 3.10 (Flutter 3.38).」 + - 開法是在 **top-level `plugins:`**(不是 `analyzer:` 底下): + + ```yaml + plugins: + fmp_lints: + path: packages/fmp_lints + diagnostics: + fmp_no_empty_catch: true + ``` + + - 「Analyzer plugins cannot be enabled, disabled, or otherwise specified or configured in a nested analysis + options file」→ **只能寫在 package 或 workspace 根**。若 `app/` 用 pub workspace,就必須寫在 workspace 根。 + - 外掛的 **warnings 預設開、lint rules 預設關**,要在 `diagnostics:` 逐條打開。 + - 「Dart 3.10 (Flutter 3.38) sets its own constraint on the `analysis_server_plugin` package, `^0.3.0`. + This may change with each release of Dart and Flutter.」→ 版本由 SDK 綁定,不是自由挑。 + - 改過 `plugins:` 之後 **需要重啟 analysis server**;啟用時會用 `dart pub upgrade` 解析一個 synthetic package, + 所以 CI 要有 pub 存取。 + - 版本仍是 **0.x**(`analysis_server_plugin` 0.3.23、`analyzer_testing` 0.4.2,同為 2026-09-11)—— + 依 pub 語意,0.x 代表沒有穩定保證。 +- **`dart analyze` 看得到、`flutter analyze` 看不到**(實測引用): + - flutter/flutter#187999 **open**: + 「flutter analyze (CLI) does not report new-system analyzer plugin diagnostics that dart analyze reports」。 + - flutter/flutter#193203 **已於 2026-09-23 關閉**,是 #187999 的重複。 + - → ADR 0015 決定在 CI 跑 `dart analyze --fatal-infos` 是對的,但**引用的 issue 號要改成 #187999**, + 且它尚未修好(ADR 0015 §後果「bug 修好後可以拿掉重複步驟」仍然成立、還不能做)。 +- ADR 0015 留的未決項有答案了:**`riverpod_lint` 3.1.9(2026-09-03)已遷移到新插件系統**, + 依賴 `analysis_server_plugin ^0.3.0`,且要求 sdk `>=3.13.0-0`。 + +### 2. `flutter_js` + +- 版本 0.8.7(2026-01-27),是現行最新;0.8.6 同日發佈,**之後 8 個月沒有新 release**。 + repo `abner/flutter_js`:未 archive、最後 push 2026-01-27、542 stars、81 open issues + (`gh api repos/abner/flutter_js`,2026-09-28)。 +- 平台:pubspec 宣告 android / ios / linux / macos / windows(**無 web**)。 + 實作方式:Android 與 Windows/Linux 用 QuickJS,iOS/macOS 用系統 JavascriptCore,全部走 **dart:ffi** + (依賴 `ffi`、`http`、`sync_http`),README 明說「no PlatformChannels needed」。 +- **能不能在 `flutter test` 裡跑** —— README §"Unit Testing javascript evaluation" 給了明確答案,而且有前置條件: + > We can unit test evaluation of expressions on flutter_js using the desktop platforms (windows, linux and macos). + > For `Windows` and `Linux` you need to build your app Desktop executable first: `flutter build -d windows` … On + > Windows … add the path `build\windows\runner\Debug` … to your environment path … For `Linux` you need to export + > an environment variable called `LIBQUICKJSC_TEST_PATH` pointing to + > `build/linux/debug/bundle/lib/libquickjs_c_bridge_plugin.so`. + - 也就是說:**裸 `flutter test` 不能直接載入 QuickJS**,要先做一次桌面建置、再把原生庫的路徑塞進 + `PATH`(Windows)或 `LIBQUICKJSC_TEST_PATH`(Linux)。 + - 這正是 `phase2-plan.md` §7 那條「契約執行器能否在 `flutter test` 內載入 QuickJS(不行改用桌面 + `integration_test`)」的答案:**可以,但不是乾淨的 `flutter test`** —— 它需要桌面建置產物與環境變數, + 等於 CI 的測試步驟要先跑 `flutter build windows`。若不想揹這個耦合,就走桌面 `integration_test` + (那本來就會有建置產物)。這是 M1 要拍板的取捨。 +- 上游周邊:QuickJS C wrapper 在 `abner/quickjs-c-bridge`,Android 原生庫在 + `fast-development/android-js-runtimes`(jitpack),兩者都不必自行編譯。 + +### 3. `googleapis/release-please-action` + +- **現行 major 是 v5**,最新 tag `v5.0.0`(2026-04-22)。v5 的**唯一 breaking change 是升到 node24** + (release notes #1188);v4 最後一版 v4.4.1(2026-04-13)。 +- **沒有 `dry-run`**。逐項核對 `v5.0.0` 的 `action.yml`:inputs 是 + `token / release-type / path / target-branch / config-file / manifest-file / repo-url / github-api-url / + github-graphql-url / fork / include-component-in-tag / proxy-server / skip-github-release / + skip-github-pull-request / skip-labeling / changelog-host / versioning-strategy / release-as`, + 沒有任何 dry-run 或「傳 CLI 參數」的入口;README 全文搜不到 "dry"。 + 最接近的是 `skip-github-pull-request: true` / `skip-github-release: true`,但官方定位是「把開 PR 與 + tagging 拆成兩段」,**不是 preview,別當 dry-run 用**。 + → `phase2-plan.md` §7 說的「以測試 repo 或 dry-run 跑通」:**只有測試 repo 這條路**。 + 真要用 CLI 的 `--dry-run`(global option,「reports the activity that would happen without taking effect」), + 得直接跑 CLI,例如 `npx release-please release-pr --repo-url=<owner/repo> --token=<PAT> --dry-run`。 +- **子目錄(`app/`)支援:支援,但 `path` 不是 config 欄位。** 官方 manifest 文件的 `packages` 是 + **path → 設定的 map,path 就是 key**;`schemas/config.json` 沒有 `path`/`package-name`/`component` + (schema 落後),但 `src/manifest.ts`/`src/strategies/*` 為準: + `RepositoryConfig = Record<string, ReleaserConfig> // path => config`。 + `path` 這個名字只出現在 Action 的 `path` input 與 CLI 的 `--path`(都是「單一套件、不寫 manifest」模式)。 +- `release-type: dart` 是內建策略(README:「`dart` | A repository with a pubspec.yaml and a CHANGELOG.md」)。 + + 最小可用設定(對 ADR 0022 的「manifest 模式、`dart` 策略管理 `app/`」): + + `release-please-config.json` + ```json + { "release-type": "dart", "packages": { "app": { "release-type": "dart" } } } + ``` + `.release-please-manifest.json` + ```json + { "app": "0.1.0" } + ``` + workflow + ```yaml + - uses: googleapis/release-please-action@v5 + with: + token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }} + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + ``` +- **子目錄的 outputs 會帶 path 前綴**:`app--release_created`、`app--tag_name`、`app--version`、`app--sha`… + 含 `/` 的 path 要用 JS property access:`steps.release.outputs['app--release_created']`。 + (root component 才會有無前綴的 `release_created` / `upload_url` / `tag_name` / `version` / + `major` / `minor` / `patch` / `body`。)ADR 0022 的「release-please 輸出為否時不建置」要寫成 + `if: steps.release.outputs['app--release_created'] == 'true'`。 +- 另外 v4.4.0 加了 action input **`versioning-strategy` 與 `release-as`**,所以 ADR 0022 的 + 「第一版以 `Release-As: 2.0.0` 指定」除了 commit footer,也可以直接用 `release-as: 2.0.0` 這個 input。 + 相關旗標另有 `--draft-pull-request`、`--draft`、`--prerelease`、`--force-tag-creation`。 +- 注意 `action.yml` v5.0.0 **沒有宣告 `outputs:` 區塊**,但 outputs 仍以 `core.setOutput` 提供(README 有列)—— + 依賴的是「未宣告的 output 仍可讀」,不是文件化的介面。 + +### 4. `dorny/paths-filter` + +- **現行 major 是 v4**,最新 `v4.0.3`(2026-08-05)。v4.0.0 的 breaking change **同樣只是升到 node24** + (v3.0.4 同日有 backport)。 +- `filters` input 吃「設定檔路徑或 YAML 字串」,兩種都支援: + + ```yaml + - uses: dorny/paths-filter@v4 + id: changes + with: + filters: | + app: + - 'app/**' + legacy: + - '**' + - '!app/**' + - if: steps.changes.outputs.app == 'true' + run: ... + ``` +- 其他 input:`predicate-quantifier`(`some`|`every`|`some-with-excludes`)、 + `list-files`(`none`|`csv`|`json`|`shell`|`escape`)、`base` / `ref` / `working-directory` / `token`。 + output 是 `changes`(JSON array)與每個 filter 的 `<name>` / `<name>_files`;glob 用 picomatch(`dot: true`)。 +- v4.0.3 含一個安全性修正(multi-line 檔名在 list-files shell/csv 輸出的跳脫,GHSA-7hc6-8hq5-9q2m) + → 新專案直接用 v4.0.3。ADR 0015 只說「用 `dorny/paths-filter`」,沒有指定版本。 + +--- + +## 未能查證 / 保留 + +1. `release-please-action` 未來版本會不會補 dry-run —— 只能確認 v5.0.0 沒有。 +2. `nativeapi` / `nativeapi_flutter` 的實際原生庫交付機制(pubspec 未宣告 plugin platforms、 + 依賴 `cnativeapi`,看起來是 build hooks/native assets,但我沒看到 `hook/build.dart` 的證據)。 + M1 真要採用 `tray_manager` 0.7.0 前,值得實測一次 Windows 建置。 +3. `hotkey_manager` 0.2.3 的變更內容 —— 上游 repo 根目錄已無 `CHANGELOG.md`,只能報版本與日期。 +4. `permission_handler` 的 macOS 支援 —— facade 只宣告 android/ios/web/windows。 + 這是「未宣告」,不等於「已移除」。 +5. A3 的 A3/A4 行為全部來自 scratchpad 的實測;Trellis 未提供 migration 指令這件事, + 是 0.6.17 的 CLI 子命令清單所見,未來版本可能補上。 diff --git a/.trellis/tasks/09-28-m1-skeleton-tracer/task.json b/.trellis/tasks/09-28-m1-skeleton-tracer/task.json new file mode 100644 index 000000000..2d10bedce --- /dev/null +++ b/.trellis/tasks/09-28-m1-skeleton-tracer/task.json @@ -0,0 +1,26 @@ +{ + "id": "m1-skeleton-tracer", + "name": "m1-skeleton-tracer", + "title": "M1 骨架+曳光彈", + "description": "fmp-rewrite milestone M1: app/ skeleton, all infrastructure, Bilibili search and play two tracks on Android and Windows (ADR 0026)", + "status": "in_progress", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "1morr", + "assignee": "1morr", + "createdAt": "2026-09-28", + "completedAt": null, + "branch": "docs/audit", + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": "09-26-fmp-rewrite", + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file From 20350232d70d78ee3809e9d7be17a4c54b9b57ef Mon Sep 17 00:00:00 2001 From: 1morr <ivanspwong@gmail.com> Date: Tue, 29 Sep 2026 03:27:50 +0800 Subject: [PATCH 133/133] chore(task): mark m1 as started --- .trellis/tasks/09-26-fmp-rewrite/milestones.md | 2 +- .trellis/tasks/09-26-fmp-rewrite/phase2-plan.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.trellis/tasks/09-26-fmp-rewrite/milestones.md b/.trellis/tasks/09-26-fmp-rewrite/milestones.md index 5ea67698b..6f5908ad0 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/milestones.md +++ b/.trellis/tasks/09-26-fmp-rewrite/milestones.md @@ -6,7 +6,7 @@ | # | 里程碑 | 依賴 | 狀態 | |---|---|---|---| -| M1 | 骨架+曳光彈 | — | 未開始 | +| M1 | 骨架+曳光彈 | — | 進行中(`09-28-m1-skeleton-tracer`) | | M2 | 完整播放 | M1 | 未開始 | | M3 | 三音源、帳號與開發工具 | M2 | 未開始 | | M4 | 音樂庫與同步 | M3 | 未開始 | diff --git a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md index 30cf4bf9e..f23764140 100644 --- a/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md +++ b/.trellis/tasks/09-26-fmp-rewrite/phase2-plan.md @@ -262,7 +262,8 @@ mpv 的音訊濾鏡可以做等化與響度正規化。Android 端(just_audio - AGENTS.md 的 Trellis 段說明哪些管理檔維持原樣; - 實機驗證規則見 ADR 0027(預設重播)。 - 語言範圍:根目錄 AGENTS.md 與 spec 維持英文到切換 PR,`app/` 的新文件用繁中。 -- **下一步:M1「骨架+曳光彈」**(`milestones.md`)。建里程碑任務(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite`),走 brainstorm,擁有者核准一次 prd/design/implement,implement 列出 PR 子任務與順序(ADR 0026)。 +- **M1 已開工**(2026-09-29 核准):`.trellis/tasks/09-28-m1-skeleton-tracer/`,prd 記擁有者五個決定,design 記技術選擇,implement 記 PR 順序(0 合併 #173 → 1 指令檔分家 → … → 13)與子代理模型。下面這段是開工前的盤點,已併入該任務。 +- **(開工前)下一步:M1「骨架+曳光彈」**(`milestones.md`)。建里程碑任務(`task.py create --parent .trellis/tasks/09-26-fmp-rewrite`),走 brainstorm,擁有者核准一次 prd/design/implement,implement 列出 PR 子任務與順序(ADR 0026)。 - M1 開工時要決定:`app/` 的 spec 放哪(Trellis `packages:` 或其他)。 - **M1 的第一個 PR:指令檔分家**(2026-09-28 盤點,尚未問擁有者,M1 brainstorm 時提出)。舊內容會誤導在 `app/` 工作的 AI: - 根目錄 AGENTS.md 全是舊專案的規則(`lib/` 路徑、Isar、`AudioController`、舊測試路徑的驗證表)。Claude Code 以 repo 根目錄為工作目錄時,**每個 session 開頭都會載入它**;`app/AGENTS.md` 只在讀到 `app/` 裡的檔案時才載入(code.claude.com/docs/en/memory「When Claude Code reads AGENTS.md」)。

    sA0J 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-compact-home.png b/docs/audit/screenshots/windows-compact-home.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8c1995694fd4606c9a1ae69322b3ba330c7543 GIT binary patch literal 155431 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 {;QQ9dJ7J=Ko?O~=4d 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 literal 0 HcmV?d00001 diff --git a/docs/audit/screenshots/windows-compact-player.png b/docs/audit/screenshots/windows-compact-player.png new file mode 100644 index 0000000000000000000000000000000000000000..bce457ae2c857c62163770353e518b90953e37de GIT binary patch literal 205708 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�%Mb^KQ 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