Repository navigation
Home
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:開發時累積的細節
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) |
- 目標是「少一點語言、精巧一些」。Tauri 版要同時維護 Rust(約 4,750 行)和 JS(約 2,200 行), 改一個取數規則常常要兩邊都動,還得裝 Rust 工具鏈才能建置。
- 評估 tinyjs 時看中兩點:
- 後端也是 JS,整個專案只剩一種語言,Node 就能跑全部單元測試。
- 官方宣稱的發布體積比 Tauri 小。
實際結果:語言目標完全達成;體積只有「下載檔」變小(見第 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 節)。
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 節 |
| 需求 | 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 前端檔案。
兩邊都要用的規則(例如門檻值)只能各放一份,或都放在後端再傳給頁面。
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。
| 症狀 | 原因 | 解法 |
|---|---|---|
| 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)
|
-
面板截圖:
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 狀態。
| 版本 | 內容 |
|---|---|
| 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,就等於沒發新版。
整體評價:值得,7.5 / 10。 語言統一和加功能的速度是最大收穫; 代價是依賴一個很年輕的框架,並為它的 bug 加了幾個繞道。
風險
-
tinyjs 還在 0.x:Origin 標頭、TLS、模組載入兩份、呼叫外部程式跳視窗、更新後不重啟,都是這次遇到的平台問題。
繞道依賴它的內部行為(
launcher --run、系統 curl),升級 tinyjs 後要重新驗證。 -
更新重啟的輔助程序可能被防毒誤判:「WMI 建立程序 + PowerShell
-EncodedCommand」是惡意程式常見手法。 -
簽章受限:只能簽
launcher.exe,被 SmartScreen 攔的機率沒有降低。
未實測
- 經 opencode 登入的 Claude、Codex 途徑:開發機上沒有這種登入。
- 真實的多帳號資料:只用假資料測過畫面。
- 用量真的跨過提醒門檻的情況:只有單元測試;通知本身已確認能送出。
- 分段條風格下的預估顯示。
- Antigravity:開發機上的登入已失效。
待辦
- 向 tinyjs 回報「更新後不重啟」與「無法移除 Origin 標頭」;修好後移除對應繞道。
- 啟動時清掉 Tauri 版留下的
HKCU\...\Run\Manapoint舊值。 - 取得代碼簽章憑證,至少簽
launcher.exe。 - 觀察
lib/relaunch.js有沒有被防毒攔。