Skip to content

Commit bbda935

Browse files
Nathan Erorclaude
andcommitted
feat: add Kiro provider for AWS kiro-cli usage tracking
Add support for tracking Kiro (AWS) usage via the kiro-cli tool. Uses CLI PTY approach running `kiro-cli chat --no-interactive "/usage"` to fetch monthly credits and bonus credits data. - Add UsageProvider.kiro case and IconStyle.kiro - Add KiroProviderDescriptor with CLI fetch strategy - Add KiroStatusProbe for parsing ANSI-decorated CLI output - Add KiroProviderImplementation (minimal, no custom login flow) - Add ProviderIcon-kiro.svg (stylized K in AWS orange) - Update widget views and provider registry - Add docs/kiro.md and update README.md, docs/providers.md - Gate Kiro usage on whoami login check 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8fd6a61 commit bbda935

18 files changed

Lines changed: 805 additions & 4 deletions

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CodexBar 🎚️ - May your tokens never run out.
22

3-
Tiny macOS 14+ menu bar app that keeps your Codex, Claude, Cursor, Gemini, Antigravity, Droid (Factory), Copilot, and z.ai limits visible (session + weekly where available) and shows when each window resets. One status item per provider (or Merge Icons mode); enable what you use from Settings. No Dock icon, minimal UI, dynamic bar icons in the menu bar.
3+
Tiny macOS 14+ menu bar app that keeps your Codex, Claude, Cursor, Gemini, Antigravity, Droid (Factory), Copilot, z.ai, and Kiro limits visible (session + weekly where available) and shows when each window resets. One status item per provider (or Merge Icons mode); enable what you use from Settings. No Dock icon, minimal UI, dynamic bar icons in the menu bar.
44

55
<img src="codexbar.png" alt="CodexBar menu screenshot" width="520" />
66

@@ -32,6 +32,7 @@ brew install --cask steipete/tap/codexbar
3232
- [Droid](docs/factory.md) — Browser cookies + WorkOS token flows for Factory usage + billing.
3333
- [Copilot](docs/copilot.md) — GitHub device flow + Copilot internal usage API.
3434
- [z.ai](docs/zai.md) — API token (Keychain) for quota + MCP windows.
35+
- [Kiro](docs/kiro.md) — CLI-based usage via `kiro-cli /usage` command; monthly credits + bonus credits.
3536
- Open to new providers: [provider authoring guide](docs/provider.md).
3637

3738
## Icon & Screenshot

Sources/CodexBar/IconRenderer.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,7 @@ enum IconRenderer {
712712
case .cursor: 6
713713
case .factory: 7
714714
case .copilot: 8
715+
case .kiro: 9
715716
case .combined: 99
716717
}
717718
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import CodexBarCore
2+
import CodexBarMacroSupport
3+
import Foundation
4+
5+
@ProviderImplementationRegistration
6+
struct KiroProviderImplementation: ProviderImplementation {
7+
let id: UsageProvider = .kiro
8+
}

Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ enum ProviderImplementationRegistry {
1919
_ = ProviderImplementationRegistry.register(GeminiProviderImplementation())
2020
_ = ProviderImplementationRegistry.register(AntigravityProviderImplementation())
2121
_ = ProviderImplementationRegistry.register(CopilotProviderImplementation())
22+
_ = ProviderImplementationRegistry.register(KiroProviderImplementation())
2223
}()
2324

2425
private static func ensureBootstrapped() {
Lines changed: 19 additions & 0 deletions
Loading

Sources/CodexBar/UsageStore.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ final class UsageStore {
203203
var zaiVersion: String?
204204
var antigravityVersion: String?
205205
var cursorVersion: String?
206+
var kiroVersion: String?
206207
var isRefreshing = false
207208
private(set) var refreshingProviders: Set<UsageProvider> = []
208209
var debugForceAnimation = false
@@ -307,6 +308,7 @@ final class UsageStore {
307308
case .factory: nil
308309
case .copilot: nil
309310
case .minimax: nil
311+
case .kiro: self.kiroVersion
310312
}
311313
}
312314

@@ -1227,6 +1229,10 @@ extension UsageStore {
12271229
let text = "MINIMAX_COOKIE=\(hasAny ? "present" : "missing") source=\(source)"
12281230
await MainActor.run { self.probeLogs[.minimax] = text }
12291231
return text
1232+
case .kiro:
1233+
let text = "Kiro debug log not yet implemented"
1234+
await MainActor.run { self.probeLogs[.kiro] = text }
1235+
return text
12301236
}
12311237
}.value
12321238
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import CodexBarMacroSupport
2+
import Foundation
3+
4+
@ProviderDescriptorRegistration
5+
@ProviderDescriptorDefinition
6+
public enum KiroProviderDescriptor {
7+
static func makeDescriptor() -> ProviderDescriptor {
8+
ProviderDescriptor(
9+
id: .kiro,
10+
metadata: ProviderMetadata(
11+
id: .kiro,
12+
displayName: "Kiro",
13+
sessionLabel: "Credits",
14+
weeklyLabel: "Bonus",
15+
opusLabel: nil,
16+
supportsOpus: false,
17+
supportsCredits: false,
18+
creditsHint: "",
19+
toggleTitle: "Show Kiro usage",
20+
cliName: "kiro-cli",
21+
defaultEnabled: false,
22+
isPrimaryProvider: false,
23+
usesAccountFallback: false,
24+
dashboardURL: "https://app.kiro.dev/account/usage",
25+
statusPageURL: nil,
26+
statusLinkURL: "https://health.aws.amazon.com/health/status"),
27+
branding: ProviderBranding(
28+
iconStyle: .kiro,
29+
iconResourceName: "ProviderIcon-kiro",
30+
color: ProviderColor(red: 255 / 255, green: 153 / 255, blue: 0 / 255)),
31+
tokenCost: ProviderTokenCostConfig(
32+
supportsTokenCost: false,
33+
noDataMessage: { "Kiro cost summary is not supported." }),
34+
fetchPlan: ProviderFetchPlan(
35+
sourceModes: [.auto, .cli],
36+
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [KiroCLIFetchStrategy()] })),
37+
cli: ProviderCLIConfig(
38+
name: "kiro-cli",
39+
versionDetector: { KiroStatusProbe.detectVersion() }))
40+
}
41+
}
42+
43+
struct KiroCLIFetchStrategy: ProviderFetchStrategy {
44+
let id: String = "kiro.cli"
45+
let kind: ProviderFetchKind = .cli
46+
47+
func isAvailable(_: ProviderFetchContext) async -> Bool {
48+
TTYCommandRunner.which("kiro-cli") != nil
49+
}
50+
51+
func fetch(_: ProviderFetchContext) async throws -> ProviderFetchResult {
52+
let probe = KiroStatusProbe()
53+
let snap = try await probe.fetch()
54+
return self.makeResult(
55+
usage: snap.toUsageSnapshot(),
56+
sourceLabel: "cli")
57+
}
58+
59+
func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
60+
false
61+
}
62+
}

0 commit comments

Comments
 (0)