@@ -15,9 +15,10 @@ final class StatusBarTextTests: XCTestCase {
1515 balance: 42, isLoading: false,
1616 hyperConfigured: true,
1717 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
18− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
18+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
19+ zaiInPeakHours: false
1920 )
20− XCTAssertEqual(title, "⚡42 · 🕐62% · 📅8%")
21+ XCTAssertEqual(title, "⚡42 · \u{2055}62% 8%")
2122 }
2223
2324 func testHyperOnly() {
@@ -25,7 +26,8 @@ final class StatusBarTextTests: XCTestCase {
2526 balance: 42, isLoading: false,
2627 hyperConfigured: true,
2728 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
28− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
29+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
30+ zaiInPeakHours: false
2931 )
3032 XCTAssertEqual(title, "⚡42")
3133 }
@@ -35,9 +37,10 @@ final class StatusBarTextTests: XCTestCase {
3537 balance: nil, isLoading: false,
3638 hyperConfigured: false,
3739 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
38− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
40+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
41+ zaiInPeakHours: false
3942 )
40− XCTAssertEqual(title, "🕐62% · 📅8%")
43+ XCTAssertEqual(title, "\u{2055}62% 8%")
4144 }
4245
4346 func testLoadingWithNothingToShow() {
@@ -45,7 +48,8 @@ final class StatusBarTextTests: XCTestCase {
4548 balance: nil, isLoading: true,
4649 hyperConfigured: false,
4750 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
48− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
51+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
52+ zaiInPeakHours: false
4953 )
5054 XCTAssertEqual(title, "…")
5155 }
@@ -55,7 +59,8 @@ final class StatusBarTextTests: XCTestCase {
5559 balance: nil, isLoading: false,
5660 hyperConfigured: false,
5761 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
58− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
62+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
63+ zaiInPeakHours: false
5964 )
6065 XCTAssertEqual(title, "")
6166 }
@@ -68,9 +73,10 @@ final class StatusBarTextTests: XCTestCase {
6873 balance: nil, isLoading: true,
6974 hyperConfigured: false,
7075 claudeFiveHourPercent: 62, claudeSevenDayPercent: nil,
71− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
76+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
77+ zaiInPeakHours: false
7278 )
73− XCTAssertEqual(title, "🕐62%")
79+ XCTAssertEqual(title, "\u{2055}62%")
7480 }
7581
7682 func testLoadingKeepsAStaleBalanceOnScreen() {
@@ -78,19 +84,21 @@ final class StatusBarTextTests: XCTestCase {
7884 balance: 42, isLoading: true,
7985 hyperConfigured: true,
8086 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
81− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
87+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
88+ zaiInPeakHours: false
8289 )
83− XCTAssertEqual(title, "⚡42 · 🕐62% · 📅8%")
90+ XCTAssertEqual(title, "⚡42 · \u{2055}62% 8%")
8491 }
8592
86− func testZeroPercentIsShownRatherThanOmitted() {
93+ func testZeroPercentIsShown() {
8794 let title = ViewModel.statusBarText(
8895 balance: 42, isLoading: false,
8996 hyperConfigured: true,
9097 claudeFiveHourPercent: 0, claudeSevenDayPercent: 8,
91− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
98+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
99+ zaiInPeakHours: false
92100 )
93− XCTAssertEqual(title, "⚡42 · 📅8%")
101+ XCTAssertEqual(title, "⚡42 · \u{2055}0% 8%")
94102 }
95103
96104 func testBothClaudeWindowsZero() {
@@ -98,9 +106,10 @@ final class StatusBarTextTests: XCTestCase {
98106 balance: 42, isLoading: false,
99107 hyperConfigured: true,
100108 claudeFiveHourPercent: 0, claudeSevenDayPercent: 0,
101− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
109+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
110+ zaiInPeakHours: false
102111 )
103− XCTAssertEqual(title, "⚡42")
112+ XCTAssertEqual(title, "⚡42 · \u{2055}0% 0%")
104113 }
105114
106115 func testFiveHourOnly() {
@@ -108,9 +117,10 @@ final class StatusBarTextTests: XCTestCase {
108117 balance: nil, isLoading: false,
109118 hyperConfigured: false,
110119 claudeFiveHourPercent: 62, claudeSevenDayPercent: nil,
111− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
120+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
121+ zaiInPeakHours: false
112122 )
113− XCTAssertEqual(title, "🕐62%")
123+ XCTAssertEqual(title, "\u{2055}62%")
114124 }
115125
116126 func testSevenDayOnly() {
@@ -118,9 +128,10 @@ final class StatusBarTextTests: XCTestCase {
118128 balance: nil, isLoading: false,
119129 hyperConfigured: false,
120130 claudeFiveHourPercent: nil, claudeSevenDayPercent: 8,
121− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
131+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
132+ zaiInPeakHours: false
122133 )
123− XCTAssertEqual(title, "📅8%")
134+ XCTAssertEqual(title, "\u{2055}8%")
124135 }
125136
126137 // MARK: - Hyper not configured
@@ -132,7 +143,8 @@ final class StatusBarTextTests: XCTestCase {
132143 balance: 42, isLoading: false,
133144 hyperConfigured: false,
134145 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
135− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
146+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
147+ zaiInPeakHours: false
136148 )
137149 XCTAssertEqual(title, "")
138150 }
@@ -142,7 +154,8 @@ final class StatusBarTextTests: XCTestCase {
142154 balance: nil, isLoading: true,
143155 hyperConfigured: false,
144156 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
145− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
157+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
158+ zaiInPeakHours: false
146159 )
147160 XCTAssertEqual(title, "…")
148161 }
@@ -152,9 +165,10 @@ final class StatusBarTextTests: XCTestCase {
152165 balance: nil, isLoading: false,
153166 hyperConfigured: false,
154167 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
155− zaiFiveHourPercent: nil, zaiWeeklyPercent: nil
168+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
169+ zaiInPeakHours: false
156170 )
157− XCTAssertEqual(title, "🕐62% · 📅8%")
171+ XCTAssertEqual(title, "\u{2055}62% 8%")
158172 }
159173
160174 // MARK: - z.ai in Title
@@ -164,9 +178,10 @@ final class StatusBarTextTests: XCTestCase {
164178 balance: nil, isLoading: false,
165179 hyperConfigured: false,
166180 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
167− zaiFiveHourPercent: 12, zaiWeeklyPercent: nil
181+ zaiFiveHourPercent: 12, zaiWeeklyPercent: nil,
182+ zaiInPeakHours: false
168183 )
169− XCTAssertEqual(title, "🤖12%")
184+ XCTAssertEqual(title, "\u{005A}12%")
170185 }
171186
172187 func testZaiWithHyper() {
@@ -174,9 +189,10 @@ final class StatusBarTextTests: XCTestCase {
174189 balance: 42, isLoading: false,
175190 hyperConfigured: true,
176191 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
177− zaiFiveHourPercent: 12, zaiWeeklyPercent: nil
192+ zaiFiveHourPercent: 12, zaiWeeklyPercent: nil,
193+ zaiInPeakHours: false
178194 )
179− XCTAssertEqual(title, "⚡42 · 🤖12%")
195+ XCTAssertEqual(title, "⚡42 · \u{005A}12%")
180196 }
181197
182198 func testZaiWithClaude() {
@@ -184,9 +200,10 @@ final class StatusBarTextTests: XCTestCase {
184200 balance: nil, isLoading: false,
185201 hyperConfigured: false,
186202 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
187− zaiFiveHourPercent: 12, zaiWeeklyPercent: nil
203+ zaiFiveHourPercent: 12, zaiWeeklyPercent: nil,
204+ zaiInPeakHours: false
188205 )
189− XCTAssertEqual(title, "🕐62% · 📅8% · 🤖12%")
206+ XCTAssertEqual(title, "\u{2055}62% 8% · \u{005A}12%")
190207 }
191208
192209 func testAllThreeServices() {
@@ -194,19 +211,21 @@ final class StatusBarTextTests: XCTestCase {
194211 balance: 42, isLoading: false,
195212 hyperConfigured: true,
196213 claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
197− zaiFiveHourPercent: 12, zaiWeeklyPercent: 3
214+ zaiFiveHourPercent: 12, zaiWeeklyPercent: 3,
215+ zaiInPeakHours: false
198216 )
199− XCTAssertEqual(title, "⚡42 · 🕐62% · 📅8% · 🤖12% · 📆3%")
217+ XCTAssertEqual(title, "⚡42 · \u{2055}62% 8% · \u{005A}12% 3%")
200218 }
201219
202− func testZaiZeroIsOmitted() {
220+ func testZaiZeroIsShown() {
203221 let title = ViewModel.statusBarText(
204222 balance: 42, isLoading: false,
205223 hyperConfigured: true,
206224 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
207− zaiFiveHourPercent: 0, zaiWeeklyPercent: 0
225+ zaiFiveHourPercent: 0, zaiWeeklyPercent: 0,
226+ zaiInPeakHours: false
208227 )
209− XCTAssertEqual(title, "⚡42")
228+ XCTAssertEqual(title, "⚡42 · \u{005A}0% 0%")
210229 }
211230
212231 func testLoadingKeepsZaiPercentOnScreen() {
@@ -214,9 +233,10 @@ final class StatusBarTextTests: XCTestCase {
214233 balance: nil, isLoading: true,
215234 hyperConfigured: false,
216235 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
217− zaiFiveHourPercent: 12, zaiWeeklyPercent: nil
236+ zaiFiveHourPercent: 12, zaiWeeklyPercent: nil,
237+ zaiInPeakHours: false
218238 )
219− XCTAssertEqual(title, "🤖12%")
239+ XCTAssertEqual(title, "\u{005A}12%")
220240 }
221241
222242 // MARK: - z.ai Weekly
@@ -226,9 +246,10 @@ final class StatusBarTextTests: XCTestCase {
226246 balance: nil, isLoading: false,
227247 hyperConfigured: false,
228248 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
229− zaiFiveHourPercent: nil, zaiWeeklyPercent: 3
249+ zaiFiveHourPercent: nil, zaiWeeklyPercent: 3,
250+ zaiInPeakHours: false
230251 )
231− XCTAssertEqual(title, "📆3%")
252+ XCTAssertEqual(title, "\u{005A}3%")
232253 }
233254
234255 func testZaiWeeklyWithFiveHour() {
@@ -236,19 +257,21 @@ final class StatusBarTextTests: XCTestCase {
236257 balance: nil, isLoading: false,
237258 hyperConfigured: false,
238259 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
239− zaiFiveHourPercent: 12, zaiWeeklyPercent: 3
260+ zaiFiveHourPercent: 12, zaiWeeklyPercent: 3,
261+ zaiInPeakHours: false
240262 )
241− XCTAssertEqual(title, "🤖12% · 📆3%")
263+ XCTAssertEqual(title, "\u{005A}12% 3%")
242264 }
243265
244− func testZaiWeeklyZeroIsOmitted() {
266+ func testZaiWeeklyZeroIsShown() {
245267 let title = ViewModel.statusBarText(
246268 balance: nil, isLoading: false,
247269 hyperConfigured: false,
248270 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
249− zaiFiveHourPercent: 12, zaiWeeklyPercent: 0
271+ zaiFiveHourPercent: 12, zaiWeeklyPercent: 0,
272+ zaiInPeakHours: false
250273 )
251− XCTAssertEqual(title, "🤖12%")
274+ XCTAssertEqual(title, "\u{005A}12% 0%")
252275 }
253276
254277 func testLoadingKeepsZaiWeeklyOnScreen() {
@@ -256,9 +279,46 @@ final class StatusBarTextTests: XCTestCase {
256279 balance: nil, isLoading: true,
257280 hyperConfigured: false,
258281 claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
259− zaiFiveHourPercent: nil, zaiWeeklyPercent: 3
282+ zaiFiveHourPercent: nil, zaiWeeklyPercent: 3,
283+ zaiInPeakHours: false
284+ )
285+ XCTAssertEqual(title, "\u{005A}3%")
286+ }
287+
288+ // MARK: - z.ai Peak Hours
289+
290+ func testPeakHoursAddsDiamondToZaiSegment() {
291+ let title = ViewModel.statusBarText(
292+ balance: 42, isLoading: false,
293+ hyperConfigured: true,
294+ claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
295+ zaiFiveHourPercent: 12, zaiWeeklyPercent: 3,
296+ zaiInPeakHours: true
297+ )
298+ XCTAssertEqual(title, "⚡42 · \u{2055}62% 8% · \u{005A}12% 3%\u{1F536}")
299+ }
300+
301+ func testPeakHoursWithZaiOnly() {
302+ let title = ViewModel.statusBarText(
303+ balance: nil, isLoading: false,
304+ hyperConfigured: false,
305+ claudeFiveHourPercent: nil, claudeSevenDayPercent: nil,
306+ zaiFiveHourPercent: 12, zaiWeeklyPercent: nil,
307+ zaiInPeakHours: true
308+ )
309+ XCTAssertEqual(title, "\u{005A}12%\u{1F536}")
310+ }
311+
312+ func testPeakHoursIgnoredWhenZaiNotConfigured() {
313+ let title = ViewModel.statusBarText(
314+ balance: 42, isLoading: false,
315+ hyperConfigured: true,
316+ claudeFiveHourPercent: 62, claudeSevenDayPercent: 8,
317+ zaiFiveHourPercent: nil, zaiWeeklyPercent: nil,
318+ zaiInPeakHours: true
260319 )
261− XCTAssertEqual(title, "📆3%")
320+ // No z.ai segment, so peak marker has nothing to attach to.
321+ XCTAssertEqual(title, "⚡42 · \u{2055}62% 8%")
262322 }
263323
264324 // MARK: - Claude Window Percentages