mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-17 12:16:59 +00:00
fix(macos-bar): correct set-default key, lead account, asset name
Send the composite provider:accountId (row.id) for Set as default so the server can resolve the CLIProxy account; feature the account closest to exhaustion (lowest remaining quota) in the title instead of the healthiest; rename the packaged asset to CCS-Bar.app.zip to match what 'ccs bar install' downloads.
This commit is contained in:
@@ -54,10 +54,10 @@ case "$SIGNING" in
|
||||
;;
|
||||
esac
|
||||
|
||||
ZIP="$DIST/CCS-Bar.zip"
|
||||
ZIP="$DIST/CCS-Bar.app.zip"
|
||||
echo "[i] Zipping -> $ZIP"
|
||||
rm -f "$ZIP"
|
||||
( cd "$DIST" && ditto -c -k --keepParent "$APP_NAME.app" "CCS-Bar.zip" )
|
||||
( cd "$DIST" && ditto -c -k --keepParent "$APP_NAME.app" "CCS-Bar.app.zip" )
|
||||
|
||||
echo "[OK] Packaged: $APP"
|
||||
echo "[OK] Asset: $ZIP"
|
||||
|
||||
@@ -83,7 +83,10 @@ final class BarViewModel: ObservableObject {
|
||||
perform { try await $0.solo(provider: row.provider, accountId: row.accountId) }
|
||||
}
|
||||
func setDefault(_ row: BarSummaryRow) {
|
||||
perform { try await $0.setDefault(name: row.accountId) }
|
||||
// The server's /api/accounts/default parses CLIProxy accounts as the
|
||||
// composite "provider:accountId" key; row.id already has that shape.
|
||||
// Sending the bare accountId fails parseCliproxyKey and 500s / no-ops.
|
||||
perform { try await $0.setDefault(name: row.id) }
|
||||
}
|
||||
func tierLock(_ row: BarSummaryRow, tier: String?) {
|
||||
perform { try await $0.tierLock(provider: row.provider, tier: tier) }
|
||||
|
||||
@@ -127,6 +127,16 @@ do {
|
||||
check(title.contains("$3.20"), "title shows total cost")
|
||||
}
|
||||
|
||||
// leadRow features the account CLOSEST TO EXHAUSTION (lowest remaining %),
|
||||
// not the healthiest. quota_percentage is REMAINING quota.
|
||||
let twoActive = [
|
||||
BarSummaryRow(accountId: "a", provider: "agy", quotaPercentage: 90, health: "ok"),
|
||||
BarSummaryRow(accountId: "b", provider: "agy", quotaPercentage: 30, health: "ok"),
|
||||
]
|
||||
let twoTitle = BarFormatting.statusTitle(rows: twoActive)
|
||||
check(twoTitle.contains("30%"), "title features lowest-remaining (closest to exhaustion)")
|
||||
check(!twoTitle.contains("90%"), "title does not feature the healthiest account")
|
||||
|
||||
// MARK: RefreshDebouncer (arms at decision time)
|
||||
|
||||
var deb = RefreshDebouncer(interval: 15)
|
||||
|
||||
@@ -30,12 +30,16 @@ public enum BarFormatting {
|
||||
return parts.joined(separator: " \u{00B7} ")
|
||||
}
|
||||
|
||||
/// The row to surface in the compact title: the one closest to exhaustion
|
||||
/// (highest quota used). Rows without a known percentage sort last.
|
||||
/// The row to surface in the compact title: the one closest to exhaustion.
|
||||
/// `quota_percentage` is REMAINING quota (higher = more left), so the lead is
|
||||
/// the LOWEST remaining percentage. Rows without a known percentage are not
|
||||
/// chosen unless no row has one.
|
||||
static func leadRow(_ rows: [BarSummaryRow]) -> BarSummaryRow? {
|
||||
rows.max { lhs, rhs in
|
||||
(lhs.quotaPercentage ?? -1) < (rhs.quotaPercentage ?? -1)
|
||||
let withPct = rows.filter { $0.quotaPercentage != nil }
|
||||
if let lead = withPct.min(by: { ($0.quotaPercentage ?? 0) < ($1.quotaPercentage ?? 0) }) {
|
||||
return lead
|
||||
}
|
||||
return rows.first
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user