Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Sources/CodexBar/MenuCardView+ModelHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,12 @@ extension UsageMenuCardView.Model {
} else {
L("Unavailable")
}
let title = input.provider == .doubao && namedWindow.id.contains("-team-")
? "\(L(namedWindow.title)) (\(L("Team")))"
: L(namedWindow.title)
return Metric(
id: namedWindow.id,
title: namedWindow.title,
title: title,
percent: Self.clamped(
input.usageBarsShowUsed
? namedWindow.window.usedPercent
Expand Down
47 changes: 42 additions & 5 deletions Sources/CodexBar/MenuCardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -612,13 +612,50 @@ private struct UsageMenuCardUsageContentView: View {
let showBottomDivider: Bool
@Environment(\.menuItemHighlighted) private var isHighlighted

/// Doubao ships Coding Plan and Agent Plan subscriptions, each with personal
/// and team editions whose windows share period labels. Split the two plan
/// families here; team rows keep distinct ids and disclose their edition.
private var doubaoSplitMetrics: (
coding: [UsageMenuCardView.Model.Metric],
agent: [UsageMenuCardView.Model.Metric])?
{
guard self.model.provider == .doubao else { return nil }
let agent = self.model.metrics.filter { $0.id.hasPrefix("doubao-agent-") }
guard !agent.isEmpty else { return nil }
let coding = self.model.metrics.filter { !$0.id.hasPrefix("doubao-agent-") }
return (coding, agent)
}

private func groupHeader(_ title: String) -> some View {
Text(L(title))
.font(.caption.weight(.semibold))
.foregroundStyle(MenuHighlightStyle.secondary(self.isHighlighted))
.textCase(.uppercase)
}

private func metricRows(_ metrics: [UsageMenuCardView.Model.Metric]) -> some View {
ForEach(metrics, id: \.id) { metric in
MetricRow(
metric: metric,
title: UsageMenuCardView.popupMetricTitle(provider: self.model.provider, metric: metric),
progressColor: self.model.progressColor)
}
}

var body: some View {
VStack(alignment: .leading, spacing: 12) {
ForEach(self.model.metrics, id: \.id) { metric in
MetricRow(
metric: metric,
title: UsageMenuCardView.popupMetricTitle(provider: self.model.provider, metric: metric),
progressColor: self.model.progressColor)
if let split = self.doubaoSplitMetrics {
if !split.coding.isEmpty {
self.groupHeader("Coding Plan")
self.metricRows(split.coding)
}
if !split.coding.isEmpty {
Divider()
}
self.groupHeader("Agent Plan")
self.metricRows(split.agent)
} else {
self.metricRows(self.model.metrics)
}
if let resetCredits = self.model.codexResetCredits {
if !self.model.metrics.isEmpty {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ struct DoubaoProviderImplementation: ProviderImplementation {
ProviderSettingsFieldDescriptor(
id: "doubao-api-token",
title: "API key / Access key ID",
subtitle: "Use a Volcengine access key ID with the secret field for Coding Plan usage, "
+ "or leave the secret blank to use an Ark API key.",
subtitle: "Without configured API credentials, install and authenticate 'arkcli' for "
+ "Coding/Agent Plan usage. Existing API credentials remain authoritative.",
kind: .secure,
placeholder: "ark-... or AKLT...",
binding: context.stringBinding(\.doubaoAPIToken),
Expand All @@ -40,7 +40,7 @@ struct DoubaoProviderImplementation: ProviderImplementation {
ProviderSettingsFieldDescriptor(
id: "doubao-secret-access-key",
title: "Secret access key",
subtitle: "Volcengine secret access key for the signed Coding Plan usage API.",
subtitle: "Optional. Only needed if arkcli is unavailable and you use Volcengine AK/SK signing.",
kind: .secure,
placeholder: "",
binding: context.stringBinding(\.doubaoSecretAccessKey),
Expand Down
8 changes: 7 additions & 1 deletion Sources/CodexBar/Resources/ProviderIcon-doubao.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/ar.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "حسب الاشتراك";
"No model-level history" = "لا يوجد سجل على مستوى النموذج";
"Daily estimated spend" = "الإنفاق اليومي التقديري";
"Coding Plan" = "خطة البرمجة";
"Agent Plan" = "خطة الوكيل";
"Team" = "فريق";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/ca.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1261,3 +1261,6 @@
"By subscription" = "Per subscripció";
"No model-level history" = "Sense historial per model";
"Daily estimated spend" = "Despesa diària estimada";
"Coding Plan" = "Pla de programació";
"Agent Plan" = "Pla d'agent";
"Team" = "Equip";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,6 @@
"By subscription" = "Nach Abonnement";
"No model-level history" = "Kein Verlauf auf Modellebene";
"Daily estimated spend" = "Geschätzte tägliche Ausgaben";
"Coding Plan" = "Coding-Plan";
"Agent Plan" = "Agentenplan";
"Team" = "Team";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1263,3 +1263,6 @@
"By subscription" = "By subscription";
"No model-level history" = "No model-level history";
"Daily estimated spend" = "Daily estimated spend";
"Coding Plan" = "Coding Plan";
"Agent Plan" = "Agent Plan";
"Team" = "Team";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1257,3 +1257,6 @@
"By subscription" = "Por suscripción";
"No model-level history" = "No hay historial por modelo";
"Daily estimated spend" = "Gasto diario estimado";
"Coding Plan" = "Plan de programación";
"Agent Plan" = "Plan de agente";
"Team" = "Equipo";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/fa.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "بر اساس اشتراک";
"No model-level history" = "تاریخچه‌ای در سطح مدل وجود ندارد";
"Daily estimated spend" = "برآورد هزینه روزانه";
"Coding Plan" = "طرح کدنویسی";
"Agent Plan" = "طرح عامل";
"Team" = "تیم";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1258,3 +1258,6 @@
"By subscription" = "Par abonnement";
"No model-level history" = "Aucun historique au niveau des modèles";
"Daily estimated spend" = "Dépenses quotidiennes estimées";
"Coding Plan" = "Plan de codage";
"Agent Plan" = "Plan d'agent";
"Team" = "Équipe";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/gl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1258,3 +1258,6 @@
"By subscription" = "Por subscrición";
"No model-level history" = "Sen historial por modelo";
"Daily estimated spend" = "Gasto diario estimado";
"Coding Plan" = "Plan de programación";
"Agent Plan" = "Plan de axente";
"Team" = "Equipo";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/id.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "Berdasarkan langganan";
"No model-level history" = "Tidak ada riwayat tingkat model";
"Daily estimated spend" = "Perkiraan pengeluaran harian";
"Coding Plan" = "Paket Coding";
"Agent Plan" = "Paket Agen";
"Team" = "Tim";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "Per abbonamento";
"No model-level history" = "Nessuna cronologia a livello di modello";
"Daily estimated spend" = "Spesa giornaliera stimata";
"Coding Plan" = "Piano di codifica";
"Agent Plan" = "Piano agente";
"Team" = "Team";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,6 @@
"By subscription" = "サブスクリプション別";
"No model-level history" = "モデル別の履歴はありません";
"Daily estimated spend" = "日別推定支出";
"Coding Plan" = "コーディングプラン";
"Agent Plan" = "エージェントプラン";
"Team" = "チーム";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1226,3 +1226,6 @@
"By subscription" = "구독별";
"No model-level history" = "모델별 내역이 없습니다";
"Daily estimated spend" = "일별 예상 지출";
"Coding Plan" = "코딩 요금제";
"Agent Plan" = "에이전트 요금제";
"Team" = "팀";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/nl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1258,3 +1258,6 @@
"By subscription" = "Per abonnement";
"No model-level history" = "Geen geschiedenis op modelniveau";
"Daily estimated spend" = "Geschatte dagelijkse uitgaven";
"Coding Plan" = "Codeerplan";
"Agent Plan" = "Agentplan";
"Team" = "Team";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/pl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "Według subskrypcji";
"No model-level history" = "Brak historii na poziomie modeli";
"Daily estimated spend" = "Szacowane dzienne wydatki";
"Coding Plan" = "Plan kodowania";
"Agent Plan" = "Plan agenta";
"Team" = "Zespół";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,6 @@
"By subscription" = "Por assinatura";
"No model-level history" = "Sem histórico por modelo";
"Daily estimated spend" = "Gasto diário estimado";
"Coding Plan" = "Plano de codificação";
"Agent Plan" = "Plano de agente";
"Team" = "Equipe";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1260,3 +1260,6 @@
"By subscription" = "По подпискам";
"No model-level history" = "Нет истории по моделям";
"Daily estimated spend" = "Предполагаемые ежедневные расходы";
"Coding Plan" = "План программирования";
"Agent Plan" = "План агента";
"Team" = "Команда";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/sv.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1257,3 +1257,6 @@
"By subscription" = "Per abonnemang";
"No model-level history" = "Ingen historik på modellnivå";
"Daily estimated spend" = "Uppskattade dagliga utgifter";
"Coding Plan" = "Kodningsplan";
"Agent Plan" = "Agentplan";
"Team" = "Team";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/th.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1262,3 +1262,6 @@
"By subscription" = "แยกตามการสมัครสมาชิก";
"No model-level history" = "ไม่มีประวัติระดับโมเดล";
"Daily estimated spend" = "ค่าใช้จ่ายรายวันโดยประมาณ";
"Coding Plan" = "แผนการเขียนโค้ด";
"Agent Plan" = "แผนเอเจนต์";
"Team" = "ทีม";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/tr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1260,3 +1260,6 @@
"By subscription" = "Aboneliğe göre";
"No model-level history" = "Model düzeyinde geçmiş yok";
"Daily estimated spend" = "Günlük tahmini harcama";
"Coding Plan" = "Kodlama Planı";
"Agent Plan" = "Ajan Planı";
"Team" = "Ekip";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/uk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1258,3 +1258,6 @@
"By subscription" = "За підписками";
"No model-level history" = "Немає історії за моделями";
"Daily estimated spend" = "Орієнтовні щоденні витрати";
"Coding Plan" = "План кодування";
"Agent Plan" = "План агента";
"Team" = "Команда";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/vi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,6 @@
"By subscription" = "Theo gói đăng ký";
"No model-level history" = "Không có lịch sử theo mô hình";
"Daily estimated spend" = "Chi tiêu ước tính hằng ngày";
"Coding Plan" = "Gói lập trình";
"Agent Plan" = "Gói tác nhân";
"Team" = "Nhóm";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1234,3 +1234,6 @@
"By subscription" = "按订阅";
"No model-level history" = "暂无模型级历史";
"Daily estimated spend" = "每日估算支出";
"Coding Plan" = "编程套餐";
"Agent Plan" = "智能体套餐";
"Team" = "团队";
3 changes: 3 additions & 0 deletions Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1289,3 +1289,6 @@
"By subscription" = "依訂閱";
"No model-level history" = "尚無模型層級歷史";
"Daily estimated spend" = "每日預估支出";
"Coding Plan" = "程式設計方案";
"Agent Plan" = "智慧體方案";
"Team" = "團隊";
25 changes: 25 additions & 0 deletions Sources/CodexBarCore/PathEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,31 @@ public enum BinaryLocator {
home: home)
}

public static func resolveArkcliBinary(
env: [String: String] = ProcessInfo.processInfo.environment,
loginPATH: [String]? = LoginShellPathCache.shared.current,
commandV: (String, String?, TimeInterval, FileManager) -> String? = ShellCommandLocator.commandV,
aliasResolver: (String, String?, TimeInterval, FileManager, String) -> String? = ShellCommandLocator
.resolveAlias,
fileManager: FileManager = .default,
home: String = NSHomeDirectory()) -> String?
{
self.resolveBinary(
name: "arkcli",
overrideKey: "ARKCLI_PATH",
env: env,
loginPATH: loginPATH,
commandV: commandV,
aliasResolver: aliasResolver,
wellKnownPaths: [
"\(home)/.local/bin/arkcli",
"/opt/homebrew/bin/arkcli",
"/usr/local/bin/arkcli",
],
fileManager: fileManager,
home: home)
}

/// Well-known installation paths for the Claude CLI binary.
/// Covers Anthropic's native installer (`~/.local/bin`), the `claude migrate-installer`
/// self-updating location (`~/.claude/local`), the legacy per-user installer
Expand Down
Loading
Loading