Trang này dành cho người muốn hiểu hoặc sửa mã: luồng dữ liệu, các thành phần và những bẫy đã gặp.
Luồng dữ liệu
claude.ai · Anthropic Console · chatgpt.com · agy · Google Cloud · ~/.claude · ~/.codex · máy từ xa (SSH)
|
fetch_one.sh <nguồn> (mỗi nguồn chạy độc lập, song song)
| ghi nguyên tử, có khoá file
~/.ai_usage_cache.json
| |
AIUsage.app (SwiftUI) AIUsageWidget (WidgetKit)
Ứng dụng và widget chỉ đọc cache. Nút làm mới chỉ ghi một file kích hoạt, LaunchAgent lo phần còn lại.
Thành phần
fetch_one.shnhận một nguồn (claude,codex,codexhist,agy,gemini,insights) và gộp kết quả vào cache. Lỗi parser được ghi vào một file log thay vì bị nuốt.ClaudeHelperlà ứng dụng nhỏ dùng WKWebView, giữ phiên đăng nhập và in nội dung trang cho script phân tích. Các chế độ:login,fetch,login-aistudio,fetch-aistudio,login-console,fetch-console.remote_insights.pychạy trên máy từ xa, đọc nhật ký phiên theo kiểu tăng dần và trả về JSON nén.Shared.swiftđược biên dịch vào cả ứng dụng và widget: parser logo, mô hình dữ liệu và logic dự báo dùng chung.
Quy tắc dữ liệu
- Mỗi nguồn ghi vào khoá riêng của cache, kèm
fetched_at. Cờ_freshbáo một lần lấy thật sự thành công; chỉ khi đó đồng hồ chung mới nhích. - Lấy dữ liệu lỗi tạm thời thì giữ nguyên số cũ, không ghi đè bằng rỗng.
- Phiên hết hạn thì giữ số cũ và đặt
needs_loginđể thẻ hiện nút đăng nhập.
Các bẫy đã gặp
- Cửa sổ nền của helper phải nằm trên màn hình. Cửa sổ ngoài màn hình làm WebKit báo
visibilityState=hidden,requestAnimationFramebị đình, và các trang Next.js như Anthropic Console không render. Helper dùng cửa sổ trong suốt 99% nằm trong màn hình, không nhận chuột. - Cookie gắn với bundle id của helper. Chạy tệp thực thi rời ngoài gói
.appsẽ không thấy phiên đăng nhập. - Trang usage của claude.ai có nút chứa ký tự icon ở cuối chữ, nên biểu thức chính quy không được neo
$; văn bản của Console cũng chứa ký tự icon trên dòng riêng giữa nhãn và số. - Tiến trình mở rộng của widget sống dai qua nhiều lần deploy. Sau mỗi lần deploy có sửa widget, kết thúc tiến trình
AIUsageWidgetExtensionđể hệ thống chạy bản mới. - Build hỏng bị chép nhầm. Không đưa kết quả
xcodebuildquagrepmà bỏ qua việc kiểmBUILD SUCCEEDED. - Ký ad-hoc trong thư mục đồng bộ bị lỗi "detritus not allowed"; ký trên bản sao ở thư mục tạm.
- Widget không có
NSHomeDirectory()thật vì chạy trong sandbox; đường dẫn tới cache được dựng từ tên người dùng.
Ảnh minh hoạ
Ứng dụng có hai biến môi trường dành cho việc chụp ảnh giới thiệu: AIUSAGE_HOME trỏ cache và script sang một thư mục chứa số liệu mẫu, và AIUSAGE_APPEARANCE (light hoặc dark) ghim giao diện. Nhờ vậy ảnh công khai không bao giờ chứa số liệu thật.