Skip to content
Aolun edited this page Sep 26, 2026 · 3 revisions

Manapoint Wiki

Manapoint 是一個常駐桌面的小面板,顯示各家 AI 訂閱(opencode Go、Claude Code、Codex、Grok、Antigravity)的用量與重置倒數。 下載與使用說明見 README。

開發文件(在程式庫裡)

  • manapoint/CONTRACT.md:前後端介面、資料形狀、DOM 結構
  • docs/providers.md:各家取數途徑、端點、token 換發
  • .claude/skills/tinyjs-windows/SKILL.md、.claude/skills/manapoint-providers/SKILL.md:開發時累積的細節

Tauri → tinyjs 遷移紀錄(2026-09-26)

Manapoint 在 v0.3.0 從 Tauri 2(Rust 後端 + JS 前端) 整個改寫成 tinyjs 0.42(txiki.js 後端 + WebView2 視窗,前後端都是 JavaScript)。 這一節記錄為什麼換、換了什麼、踩了哪些坑,以及換完之後的評價,給之後維護或考慮再換框架時參考。

遷移前最後版本 v0.2.1(commit f49d51a,2026-09-18)
遷移版本 v0.3.0(1aa7ba5)→ v0.3.1(607df08)→ v0.3.2(b7e8e61),皆 2026-09-26
舊程式碼 已從 master 移除;要看請 git show f49d51a:manapoint-tauri/...
新程式碼 manapoint/(介面約定見 manapoint/CONTRACT.md)

1. 為什麼換

  • 目標是「少一點語言、精巧一些」。Tauri 版要同時維護 Rust(約 4,750 行)和 JS(約 2,200 行), 改一個取數規則常常要兩邊都動,還得裝 Rust 工具鏈才能建置。
  • 評估 tinyjs 時看中兩點:
    1. 後端也是 JS,整個專案只剩一種語言,Node 就能跑全部單元測試。
    2. 官方宣稱的發布體積比 Tauri 小。

實際結果:語言目標完全達成;體積只有「下載檔」變小(見第 2 節)。


2. 前後對照

項目 Tauri 版(v0.2.1) tinyjs 版(v0.3.2)
語言 Rust + JS 只有 JS
程式行數 Rust 4,752 + JS/CSS/HTML 2,225 JS 4,292(前後端)+ 測試 1,209
建置需求 Rust 工具鏈、Node tinyjs、Node(Node 只跑測試)
第三方依賴 tauri、reqwest、tokio、serde、chrono、windows、winreg、single-instance 外掛 無 npm 依賴;用系統內建 curl.exe、PowerShell
發布物 單一 Manapoint.exe 4.97 MB zip 3.39 MB,解壓後 Manapoint.exe 5.8 MB + launcher.exe 0.9 MB,共 6.7 MB
簽章 exe 可簽 只能簽 launcher.exe;Manapoint.exe 的程式包附加在 PE 尾端,簽章後能否讀回未驗證
自動更新 無 有(v0.3.2 起,tinyjs 內建機制)
單元測試 前端 3 個檔 8 個檔、171 個測試,涵蓋取數解析、token 規則、磁吸幾何、提醒與預估

使用者資料相容:%APPDATA%\Manapoint\settings.json 和 usage-snapshot.json 位置與格式不變, 升級後設定和上次數字都會保留。

⚠ 開機啟動值名稱改了:Tauri 版寫的是 HKCU\...\Run 下的 Manapoint,tinyjs 寫的是 tinyjs-Manapoint。從 v0.2.x 升上來、而且開過開機啟動的人,舊的 Manapoint 值還會指向舊 exe, 開機時可能新舊兩版一起跑。目前程式沒有自動清掉舊值(待辦,見第 8 節)。


3. 架構對照

3.1 Rust 模組 → JS 模組

Tauri(src-tauri/src/) tinyjs(manapoint/src/) 備註
lib.rs、main.rs(commands、輪詢) main.js #[tauri::command] → export const api 的方法
model.rs、error.rs providers/model.js、lib/errors.js 錯誤種類 NotReady / Transient / Failed 不變
providers/*.rs、*_token.rs providers/*.js、*_token.js 一對一移植,規則與測試一起搬
settings.rs、cache.rs、paths.rs lib/settings.js、lib/cache.js、lib/paths.js 檔案格式相同
snap.rs frontend/snap.js 幾何純函式,改在頁面端算
win.rs(WM_MOVING 子類化、工作區) frontend/panel.js 見 3.2
autostart.rs(winreg) app.launchAtLogin tinyjs 內建
Credential Manager(windows crate) lib/keyring.js(tjs:ffi 呼叫 CredReadW) x64 CREDENTIALW:blob 大小在 +32、指標在 +40
reqwest lib/io.js 的 request / requestNoOrigin 見第 5 節的 Origin 與 TLS 問題
tokio 計時 setTimeout 每 300 秒 手動重新整理會併入進行中的那一輪
— lib/opencode_db.js、lib/opencode_logins.js、lib/accounts.js 遷移時新增,見第 4 節

3.2 平台能力對照

需求 Tauri 做法 tinyjs 做法
前後端呼叫 invoke / emit tiny.api.call / 後端 app.push + 頁面 tiny.api.on
拖曳即時磁吸 Rust 子類化視窗、攔 WM_MOVING 頁面用 pointer capture 自己移動視窗,每幀一次 tiny.win.setPosition;座標換算比例 k = getState().width / innerWidth
螢幕工作區 Win32 GetMonitorInfoW 取 rcWork tiny.app.screens() 的 visible
無邊框透明視窗 tauri.conf.json tinyjs.json 的 chrome: { frame: false, transparent: true },加上 activation: "accessory"(啟動時隱藏,量好尺寸再顯示)
右鍵選單、托盤 tauri menu / tray-icon tiny.menu.setContext、tiny.tray.set(選單是資料,狀態改變就重設)
單一實體 single-instance 外掛 內建
通知 — app.notify(),在 Windows 顯示為原生 toast

打包限制:tinyjs build 會把後端資料夾(不含 frontend/)編進 exe,所以後端不能 import 前端檔案。 兩邊都要用的規則(例如門檻值)只能各放一份,或都放在後端再傳給頁面。


4. 遷移時一起做的功能

tinyjs 讓加功能變便宜,所以同一天一起加了這些:

  • 支援新版 opencode:新版把登入存在 opencode.db 的 credential 表,auth.json 已不再更新。 改為用 tjs:sqlite 唯讀讀取;換發 token 時用 BEGIN IMMEDIATE 合併寫回。
  • opencode console 登入也顯示 Go 用量:用 console token 呼叫 {server}/api/config 取得組織與閘道,用量打 https://opencode.ai/inference/go/v1/usage。 /api/config 回的 apiKey 只是 {env:OPENCODE_CONSOLE_TOKEN} 範本,真正要用的是 access token。
  • 多途徑取數:每家嘗試所有找得到的登入(自家 CLI、opencode 代存的登入、多帳號外掛), 任一條成功就顯示,全部失敗才報錯;同一帳號依身分或「百分比 + 重置時間」指紋去重。
  • 多帳號:不同帳號各畫一組 bar(account 欄位,見 CONTRACT.md §1.2)。
  • v0.3.2:用量提醒通知、托盤圖示依用量變色、耗用速度預估、自動更新。

各家的取數途徑與端點細節見 docs/providers.md。


5. 踩過的坑

症狀 原因 解法
Claude 卡片 401「CORS requests are not allowed for this Organization」 txiki 的 fetch 一律加 Origin 標頭,而且拿不掉;Anthropic 把它當瀏覽器請求 Anthropic 的請求改走 %SystemRoot%\System32\curl.exe --config -,網址、標頭、內容都從 stdin 傳,不出現在命令列
偶發「Timed out waiting SSL」 txiki 內建 TLS 偶爾卡在交握 網路層失敗時,自動改用系統 curl(Schannel)重試一次
PATH 上的 curl 不支援某些選項 Git 附的 mingw curl 蓋過了系統版 寫死 System32\curl.exe
錯誤種類全變成 Failed txiki 會用不同路徑寫法把同一模組載入兩份,instanceof 失效 改看 kind 欄位(duck typing)
重新整理時跳出 Windows Terminal 視窗(v0.3.0) 同樣是模組載入兩份:main.js 設定的 app.spawnHidden 只進到其中一份 io.js 設定改存在 globalThis[Symbol.for(...)](v0.3.1)
opencode Go 401 把 /api/config 的 apiKey 範本當成金鑰 改用 console access token 打推論閘道
自動更新後程式消失 tinyjs 0.42 在舊程式還活著時就啟動新版,新版被單一實體機制擋下;接著舊的退出。而且程式自己開的子程序會跟著它一起結束 安裝前先經 WMI 建立一個獨立的輔助程序(lib/relaunch.js),等舊程序結束、而且旗標檔還在時才啟動新版;安裝失敗會移除旗標
背景執行 tinyjs dev 出現「failed to create webview」 從 agent 的背景 shell 啟動時建不了 webview 在同一個指令內用 (timeout N tinyjs dev &) 前景啟動
tjs run 的相對 import 找不到檔 相對路徑以目前工作目錄為準,不是腳本所在位置 腳本放在專案根目錄,或先 cd 到模組所在資料夾
程式碼裡的反斜線被吃掉 經 Git Bash heredoc 或 sed 寫檔時跳脫被轉換 改用編輯工具寫檔,或用 String.fromCharCode(92)、split/join,寫完跑 node --check
release.ps1 產生的 manifest 網址錯誤 PowerShell 變數不分大小寫,參數 $Repo 撞到既有的 $repo 參數改名 $GitHubRepo
截圖只拍到鎖定畫面 螢幕鎖定時 CopyFromScreen 只拿得到鎖定畫面 改用 PrintWindow(hwnd, hdc, 2)

6. 驗證方法(沒辦法直接看螢幕時)

  • 面板截圖:PrintWindow(..., PW_RENDERFULLCONTENT),鎖定畫面時也能拍到 WebView2 內容。
  • 有沒有跳出視窗:啟動時用 EnumWindows 輪詢新出現的可見視窗;出現 CASCADIA_HOSTING_WINDOW_CLASS 或 PseudoConsoleWindow 就表示有主控台漏出來。
  • 通知有沒有送出:複製 %LOCALAPPDATA%\Microsoft\Windows\Notifications\wpndatabase.db,只查 Payload 含 Manapoint 的列。
  • 托盤圖示與提示文字:開發模式下暫時加 tiny.log(...),頁面的紀錄會帶 [web] 印在終端機。 新圖示在 Win11 預設收在隱藏區,登錄檔裡的圖示快照也只記第一次,兩者都不能拿來證明圖示有變。
  • 自動更新:manifest 允許用 http://127.0.0.1。先建一份指向本機伺服器的舊版,再建一份較新版本打成 zip, 啟動舊版後用模擬按鍵點選單,確認檔案有換、新程序有起來。v0.3.2 另外從真實 GitHub 更新過一次, 換上的 exe 與 release zip 內的逐位元組相同。
  • 憑證問題:不直接讀或印任何憑證。diagnose.js 只印檔案是否存在、欄位名稱與長度、到期時間、HTTP 狀態。

7. 發布歷程

版本 內容
v0.3.0 tinyjs 重製、支援 opencode.db 與 console 登入、多途徑取數、多帳號;改用 zip 發布
v0.3.1 修正重新整理時跳出 curl 主控台視窗
v0.3.2 用量提醒、托盤變色、耗用速度預估、自動更新(之後的版本會自動更新)

發版流程(v0.3.2 起):執行 scripts/release.ps1 -NotesFile <說明>,它會產生 zip 與 dist/manifest.json。 兩個檔案都要上傳到 GitHub release,已安裝的程式透過 releases/latest/download/manifest.json 找新版;少傳 manifest,就等於沒發新版。


8. 評價、風險與待辦

整體評價:值得,7.5 / 10。 語言統一和加功能的速度是最大收穫; 代價是依賴一個很年輕的框架,並為它的 bug 加了幾個繞道。

風險

  1. tinyjs 還在 0.x:Origin 標頭、TLS、模組載入兩份、呼叫外部程式跳視窗、更新後不重啟,都是這次遇到的平台問題。 繞道依賴它的內部行為(launcher --run、系統 curl),升級 tinyjs 後要重新驗證。
  2. 更新重啟的輔助程序可能被防毒誤判:「WMI 建立程序 + PowerShell -EncodedCommand」是惡意程式常見手法。
  3. 簽章受限:只能簽 launcher.exe,被 SmartScreen 攔的機率沒有降低。

未實測

  • 經 opencode 登入的 Claude、Codex 途徑:開發機上沒有這種登入。
  • 真實的多帳號資料:只用假資料測過畫面。
  • 用量真的跨過提醒門檻的情況:只有單元測試;通知本身已確認能送出。
  • 分段條風格下的預估顯示。
  • Antigravity:開發機上的登入已失效。

待辦

  • 向 tinyjs 回報「更新後不重啟」與「無法移除 Origin 標頭」;修好後移除對應繞道。
  • 啟動時清掉 Tauri 版留下的 HKCU\...\Run\Manapoint 舊值。
  • 取得代碼簽章憑證,至少簽 launcher.exe。
  • 觀察 lib/relaunch.js 有沒有被防毒攔。