claude-use 11.54.1 → 11.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -138,12 +138,37 @@ var init_proxyBypass = __esm({
138
138
  }
139
139
  });
140
140
 
141
+ // src/statusline/blank.ts
142
+ function drawsNothing(text) {
143
+ return (0, import_string_width.default)(text.replace(BLANK_CELLS, "")) === 0;
144
+ }
145
+ var import_string_width, BLANK_CELLS;
146
+ var init_blank = __esm({
147
+ "src/statusline/blank.ts"() {
148
+ "use strict";
149
+ import_string_width = __toESM(require("string-width"), 1);
150
+ BLANK_CELLS = /[\p{Zs}\u2800\u3164\uFFA0]/gu;
151
+ }
152
+ });
153
+
154
+ // src/statusline/graphemes.ts
155
+ function graphemesOf(text) {
156
+ return Array.from(SEGMENTER.segment(text), (part) => part.segment);
157
+ }
158
+ var SEGMENTER;
159
+ var init_graphemes = __esm({
160
+ "src/statusline/graphemes.ts"() {
161
+ "use strict";
162
+ SEGMENTER = new Intl.Segmenter(void 0, { granularity: "grapheme" });
163
+ }
164
+ });
165
+
141
166
  // src/config/statusline.ts
142
167
  function distinctList(member) {
143
168
  return import_zod.z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat an entry");
144
169
  }
145
170
  function isSingleVisibleGrapheme(text) {
146
- return [...GRAPHEMES.segment(text)].length === 1 && !/[\p{C}\p{Z}]/u.test(text);
171
+ return graphemesOf(text).length === 1 && (0, import_string_width2.default)(text) === 1 && !/[\p{C}\p{Z}]/u.test(text) && !drawsNothing(text);
147
172
  }
148
173
  function isPlainObject(value) {
149
174
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -165,11 +190,14 @@ function resolveStatusline(settings) {
165
190
  }
166
191
  return resolved;
167
192
  }
168
- var import_zod, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, GRAPHEMES, barCharacter, labelText, overrideText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
193
+ var import_string_width2, import_zod, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, barCharacter, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
169
194
  var init_statusline = __esm({
170
195
  "src/config/statusline.ts"() {
171
196
  "use strict";
197
+ import_string_width2 = __toESM(require("string-width"), 1);
172
198
  import_zod = require("zod");
199
+ init_blank();
200
+ init_graphemes();
173
201
  STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle"];
174
202
  STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles"];
175
203
  STATUSLINE_COLOUR_NAMES = [
@@ -195,20 +223,23 @@ var init_statusline = __esm({
195
223
  DEFAULT_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom"];
196
224
  DEFAULT_ROWS = ["context", "quota"];
197
225
  STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
226
+ STATUSLINE_USAGE_VALUES = ["used", "remaining"];
227
+ STATUSLINE_TIME_FORMATS = ["relative", "absolute", "both", "elapsed", "elapsedAndAbsolute"];
228
+ STATUSLINE_HOUR_CYCLES = ["auto", "h11", "h12", "h23", "h24"];
198
229
  MAX_PERCENT = 100;
199
230
  MAX_STATUSLINE_PALETTE_INDEX = 255;
200
- MAX_STATUSLINE_LABEL_CHARS = 12;
231
+ MAX_STATUSLINE_LABEL_COLUMNS = 12;
201
232
  MAX_BAR_CELLS = 40;
202
233
  MAX_ACCOUNT_USER_CHARS = 254;
203
234
  MAX_DISPLAY_TEXT_CHARS = 80;
204
235
  LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
205
236
  OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
206
237
  colourValue = import_zod.z.union([import_zod.z.enum(STATUSLINE_COLOUR_NAMES), import_zod.z.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), import_zod.z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
207
- GRAPHEMES = new Intl.Segmenter(void 0, { granularity: "grapheme" });
208
- barCharacter = import_zod.z.string().refine(isSingleVisibleGrapheme, "must be a single visible character");
209
- labelText = import_zod.z.string().max(MAX_STATUSLINE_LABEL_CHARS).regex(LABEL_RE2, "must be visible text without control characters");
238
+ barCharacter = import_zod.z.string().refine(isSingleVisibleGrapheme, "must be a single visible character that takes one terminal column");
239
+ labelText = import_zod.z.string().refine((text) => (0, import_string_width2.default)(text) <= MAX_STATUSLINE_LABEL_COLUMNS, `must take no more than ${String(MAX_STATUSLINE_LABEL_COLUMNS)} terminal columns`).refine((text) => !drawsNothing(text), "must show something: a label of only combining marks or blank characters draws nothing").regex(LABEL_RE2, "must be visible text without control characters");
210
240
  overrideText = import_zod.z.string().max(MAX_DISPLAY_TEXT_CHARS).regex(OPTIONAL_LABEL_RE, "must be visible text without control characters");
211
241
  wholePercent = import_zod.z.number().int().min(1).max(MAX_PERCENT);
242
+ thresholdPercent = import_zod.z.number().int().min(0).max(MAX_PERCENT);
212
243
  SHAPES = {
213
244
  layout: {
214
245
  header: distinctList(import_zod.z.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
@@ -245,6 +276,20 @@ var init_statusline = __esm({
245
276
  filled: barCharacter.describe("The character that draws the used part of a bar."),
246
277
  empty: barCharacter.describe("The character that draws the unused part of a bar.")
247
278
  },
279
+ usage: {
280
+ value: import_zod.z.enum(STATUSLINE_USAGE_VALUES).describe("Whether a quota window's figure is the share of it used or the share left; the bar and the colour always follow the share used."),
281
+ bar: import_zod.z.boolean().describe("Whether each quota window is drawn as a bar, or as text alone."),
282
+ compact: import_zod.z.boolean().describe("Whether the quota windows are drawn as one short line of text (`5h: 25.0% (1h 30m)`) in place of bars; it takes precedence over usage.bar."),
283
+ resetLabel: import_zod.z.boolean().describe("Whether a window's reset time is introduced with `resets in` (`resets` for a wall-clock time), as in `(resets in 1h 30m)`, rather than the bare `(1h 30m)`."),
284
+ modelScoped: import_zod.z.boolean().describe("Whether the per-model weekly windows the client reports (rate_limits.model_scoped) are drawn after the account's own windows; they describe the signed-in account, so a session that selected a provider never shows them."),
285
+ timeFormat: import_zod.z.enum(STATUSLINE_TIME_FORMATS).describe("How a window's reset is shown: the time left (`1h 30m`), the wall-clock time (`at 14:30`), both, the share of the window already gone (`53% elapsed`), or that share and the wall-clock time. A window whose length is not known shows no share."),
286
+ threshold: thresholdPercent.describe("The whole percentage of use that at least one quota window must reach for the quota row to be drawn at all; 0 always draws it."),
287
+ sevenDayThreshold: thresholdPercent.describe("The whole percentage of use at which the weekly window is drawn beside the five-hour one; below it the weekly window is hidden. A weekly window with no five-hour window beside it is always drawn, and 0 always draws it.")
288
+ },
289
+ clock: {
290
+ hourCycle: import_zod.z.enum(STATUSLINE_HOUR_CYCLES).describe("The hour cycle of a wall-clock time: `auto` follows the system locale, `h23` and `h24` are 24-hour time (`h24` writes midnight as 24:00), and `h12` and `h11` are 12-hour time with am or pm (`h11` writes the hour after midnight as 0)."),
291
+ seconds: import_zod.z.boolean().describe("Whether a wall-clock time includes seconds (`14:30:07`).")
292
+ },
248
293
  colours: {
249
294
  context: colourValue.describe("The colour of the context bar and its figures below the warning threshold."),
250
295
  usage: colourValue.describe("The colour of the quota bars and their figures below the warning threshold."),
@@ -287,6 +332,8 @@ var init_statusline = __esm({
287
332
  bands: import_zod.z.strictObject(SHAPES.bands).partial().optional(),
288
333
  labels: import_zod.z.strictObject(SHAPES.labels).partial().optional(),
289
334
  bar: import_zod.z.strictObject(SHAPES.bar).partial().optional(),
335
+ usage: import_zod.z.strictObject(SHAPES.usage).partial().optional(),
336
+ clock: import_zod.z.strictObject(SHAPES.clock).partial().optional(),
290
337
  colours: import_zod.z.strictObject(SHAPES.colours).partial().optional(),
291
338
  project: import_zod.z.strictObject(SHAPES.project).partial().optional(),
292
339
  git: import_zod.z.strictObject(SHAPES.git).partial().optional(),
@@ -302,6 +349,8 @@ var init_statusline = __esm({
302
349
  bands: import_zod.z.strictObject(SHAPES.bands),
303
350
  labels: import_zod.z.strictObject(SHAPES.labels),
304
351
  bar: import_zod.z.strictObject(SHAPES.bar),
352
+ usage: import_zod.z.strictObject(SHAPES.usage),
353
+ clock: import_zod.z.strictObject(SHAPES.clock),
305
354
  colours: import_zod.z.strictObject(SHAPES.colours),
306
355
  project: import_zod.z.strictObject(SHAPES.project),
307
356
  git: import_zod.z.strictObject(SHAPES.git),
@@ -317,6 +366,8 @@ var init_statusline = __esm({
317
366
  bands: { warnAt: 70, criticalAt: 90 },
318
367
  labels: { fiveHour: "5h", sevenDay: "Wk" },
319
368
  bar: { width: 10, filled: "\u2588", empty: "\u2591" },
369
+ usage: { value: "used", bar: true, compact: false, resetLabel: false, modelScoped: false, timeFormat: "relative", threshold: 0, sevenDayThreshold: 0 },
370
+ clock: { hourCycle: "auto", seconds: false },
320
371
  colours: {
321
372
  context: "green",
322
373
  usage: "green",
@@ -4399,7 +4450,7 @@ var init_package = __esm({
4399
4450
  "package.json"() {
4400
4451
  package_default = {
4401
4452
  name: "claude-use",
4402
- version: "11.54.1",
4453
+ version: "11.55.0",
4403
4454
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
4404
4455
  license: "MIT",
4405
4456
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4457,6 +4508,7 @@ var init_package = __esm({
4457
4508
  commander: "^15.0.0",
4458
4509
  cosmiconfig: "^10.0.1",
4459
4510
  picomatch: "^4.0.7",
4511
+ "string-width": "8.3.0",
4460
4512
  trilean: "1.7.1",
4461
4513
  undici: "7.29.1",
4462
4514
  zod: "^4.6.1"
@@ -11993,7 +12045,7 @@ var init_identityClaude = __esm({
11993
12045
  });
11994
12046
 
11995
12047
  // src/usage/providerQuota.ts
11996
- var import_zod34, MS_PER_SECOND9, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
12048
+ var import_zod34, MS_PER_SECOND9, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY2, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
11997
12049
  var init_providerQuota = __esm({
11998
12050
  "src/usage/providerQuota.ts"() {
11999
12051
  "use strict";
@@ -12030,7 +12082,7 @@ var init_providerQuota = __esm({
12030
12082
  OPENROUTER_HOST = "openrouter.ai";
12031
12083
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
12032
12084
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
12033
- MS_PER_DAY3 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12085
+ MS_PER_DAY2 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12034
12086
  OpenRouterKeySchema = import_zod34.z.object({
12035
12087
  data: import_zod34.z.object({
12036
12088
  limit: import_zod34.z.number().nonnegative().nullable(),
@@ -18634,13 +18686,8 @@ function createDoorHealthPublisher(hub, now, pid) {
18634
18686
  }
18635
18687
 
18636
18688
  // src/frontdoor/quotaExpiringEvents.ts
18689
+ init_pick();
18637
18690
  init_schema2();
18638
- var MS_PER_HOUR5 = 36e5;
18639
- var MS_PER_DAY2 = 864e5;
18640
- var FIVE_HOUR_WINDOW_HOURS = 5;
18641
- var SEVEN_DAY_WINDOW_DAYS = 7;
18642
- var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR5;
18643
- var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
18644
18691
  var FINAL_SPAN_DENOMINATOR = 30;
18645
18692
  var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
18646
18693
  function createQuotaExpiringPublisher(hub, deps) {
@@ -18660,11 +18707,11 @@ function createQuotaExpiringPublisher(hub, deps) {
18660
18707
  const unified = snapshot.providers[provider]?.rateLimit?.unified;
18661
18708
  const fiveHour = unified?.fiveHour;
18662
18709
  if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
18663
- views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
18710
+ views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
18664
18711
  }
18665
18712
  const sevenDay = unified?.sevenDay;
18666
18713
  if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
18667
- views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
18714
+ views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
18668
18715
  }
18669
18716
  }
18670
18717
  return views;
package/dist/index.mjs CHANGED
@@ -116,13 +116,39 @@ var init_proxyBypass = __esm({
116
116
  }
117
117
  });
118
118
 
119
+ // src/statusline/blank.ts
120
+ import stringWidth from "string-width";
121
+ function drawsNothing(text) {
122
+ return stringWidth(text.replace(BLANK_CELLS, "")) === 0;
123
+ }
124
+ var BLANK_CELLS;
125
+ var init_blank = __esm({
126
+ "src/statusline/blank.ts"() {
127
+ "use strict";
128
+ BLANK_CELLS = /[\p{Zs}\u2800\u3164\uFFA0]/gu;
129
+ }
130
+ });
131
+
132
+ // src/statusline/graphemes.ts
133
+ function graphemesOf(text) {
134
+ return Array.from(SEGMENTER.segment(text), (part) => part.segment);
135
+ }
136
+ var SEGMENTER;
137
+ var init_graphemes = __esm({
138
+ "src/statusline/graphemes.ts"() {
139
+ "use strict";
140
+ SEGMENTER = new Intl.Segmenter(void 0, { granularity: "grapheme" });
141
+ }
142
+ });
143
+
119
144
  // src/config/statusline.ts
145
+ import stringWidth2 from "string-width";
120
146
  import { z } from "zod";
121
147
  function distinctList(member) {
122
148
  return z.array(member).refine((items) => new Set(items).size === items.length, "must not repeat an entry");
123
149
  }
124
150
  function isSingleVisibleGrapheme(text) {
125
- return [...GRAPHEMES.segment(text)].length === 1 && !/[\p{C}\p{Z}]/u.test(text);
151
+ return graphemesOf(text).length === 1 && stringWidth2(text) === 1 && !/[\p{C}\p{Z}]/u.test(text) && !drawsNothing(text);
126
152
  }
127
153
  function isPlainObject(value) {
128
154
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -144,10 +170,12 @@ function resolveStatusline(settings) {
144
170
  }
145
171
  return resolved;
146
172
  }
147
- var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_CHARS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, GRAPHEMES, barCharacter, labelText, overrideText, wholePercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
173
+ var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, barCharacter, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
148
174
  var init_statusline = __esm({
149
175
  "src/config/statusline.ts"() {
150
176
  "use strict";
177
+ init_blank();
178
+ init_graphemes();
151
179
  STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle"];
152
180
  STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles"];
153
181
  STATUSLINE_COLOUR_NAMES = [
@@ -173,20 +201,23 @@ var init_statusline = __esm({
173
201
  DEFAULT_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom"];
174
202
  DEFAULT_ROWS = ["context", "quota"];
175
203
  STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
204
+ STATUSLINE_USAGE_VALUES = ["used", "remaining"];
205
+ STATUSLINE_TIME_FORMATS = ["relative", "absolute", "both", "elapsed", "elapsedAndAbsolute"];
206
+ STATUSLINE_HOUR_CYCLES = ["auto", "h11", "h12", "h23", "h24"];
176
207
  MAX_PERCENT = 100;
177
208
  MAX_STATUSLINE_PALETTE_INDEX = 255;
178
- MAX_STATUSLINE_LABEL_CHARS = 12;
209
+ MAX_STATUSLINE_LABEL_COLUMNS = 12;
179
210
  MAX_BAR_CELLS = 40;
180
211
  MAX_ACCOUNT_USER_CHARS = 254;
181
212
  MAX_DISPLAY_TEXT_CHARS = 80;
182
213
  LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
183
214
  OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
184
215
  colourValue = z.union([z.enum(STATUSLINE_COLOUR_NAMES), z.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
185
- GRAPHEMES = new Intl.Segmenter(void 0, { granularity: "grapheme" });
186
- barCharacter = z.string().refine(isSingleVisibleGrapheme, "must be a single visible character");
187
- labelText = z.string().max(MAX_STATUSLINE_LABEL_CHARS).regex(LABEL_RE2, "must be visible text without control characters");
216
+ barCharacter = z.string().refine(isSingleVisibleGrapheme, "must be a single visible character that takes one terminal column");
217
+ labelText = z.string().refine((text) => stringWidth2(text) <= MAX_STATUSLINE_LABEL_COLUMNS, `must take no more than ${String(MAX_STATUSLINE_LABEL_COLUMNS)} terminal columns`).refine((text) => !drawsNothing(text), "must show something: a label of only combining marks or blank characters draws nothing").regex(LABEL_RE2, "must be visible text without control characters");
188
218
  overrideText = z.string().max(MAX_DISPLAY_TEXT_CHARS).regex(OPTIONAL_LABEL_RE, "must be visible text without control characters");
189
219
  wholePercent = z.number().int().min(1).max(MAX_PERCENT);
220
+ thresholdPercent = z.number().int().min(0).max(MAX_PERCENT);
190
221
  SHAPES = {
191
222
  layout: {
192
223
  header: distinctList(z.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
@@ -223,6 +254,20 @@ var init_statusline = __esm({
223
254
  filled: barCharacter.describe("The character that draws the used part of a bar."),
224
255
  empty: barCharacter.describe("The character that draws the unused part of a bar.")
225
256
  },
257
+ usage: {
258
+ value: z.enum(STATUSLINE_USAGE_VALUES).describe("Whether a quota window's figure is the share of it used or the share left; the bar and the colour always follow the share used."),
259
+ bar: z.boolean().describe("Whether each quota window is drawn as a bar, or as text alone."),
260
+ compact: z.boolean().describe("Whether the quota windows are drawn as one short line of text (`5h: 25.0% (1h 30m)`) in place of bars; it takes precedence over usage.bar."),
261
+ resetLabel: z.boolean().describe("Whether a window's reset time is introduced with `resets in` (`resets` for a wall-clock time), as in `(resets in 1h 30m)`, rather than the bare `(1h 30m)`."),
262
+ modelScoped: z.boolean().describe("Whether the per-model weekly windows the client reports (rate_limits.model_scoped) are drawn after the account's own windows; they describe the signed-in account, so a session that selected a provider never shows them."),
263
+ timeFormat: z.enum(STATUSLINE_TIME_FORMATS).describe("How a window's reset is shown: the time left (`1h 30m`), the wall-clock time (`at 14:30`), both, the share of the window already gone (`53% elapsed`), or that share and the wall-clock time. A window whose length is not known shows no share."),
264
+ threshold: thresholdPercent.describe("The whole percentage of use that at least one quota window must reach for the quota row to be drawn at all; 0 always draws it."),
265
+ sevenDayThreshold: thresholdPercent.describe("The whole percentage of use at which the weekly window is drawn beside the five-hour one; below it the weekly window is hidden. A weekly window with no five-hour window beside it is always drawn, and 0 always draws it.")
266
+ },
267
+ clock: {
268
+ hourCycle: z.enum(STATUSLINE_HOUR_CYCLES).describe("The hour cycle of a wall-clock time: `auto` follows the system locale, `h23` and `h24` are 24-hour time (`h24` writes midnight as 24:00), and `h12` and `h11` are 12-hour time with am or pm (`h11` writes the hour after midnight as 0)."),
269
+ seconds: z.boolean().describe("Whether a wall-clock time includes seconds (`14:30:07`).")
270
+ },
226
271
  colours: {
227
272
  context: colourValue.describe("The colour of the context bar and its figures below the warning threshold."),
228
273
  usage: colourValue.describe("The colour of the quota bars and their figures below the warning threshold."),
@@ -265,6 +310,8 @@ var init_statusline = __esm({
265
310
  bands: z.strictObject(SHAPES.bands).partial().optional(),
266
311
  labels: z.strictObject(SHAPES.labels).partial().optional(),
267
312
  bar: z.strictObject(SHAPES.bar).partial().optional(),
313
+ usage: z.strictObject(SHAPES.usage).partial().optional(),
314
+ clock: z.strictObject(SHAPES.clock).partial().optional(),
268
315
  colours: z.strictObject(SHAPES.colours).partial().optional(),
269
316
  project: z.strictObject(SHAPES.project).partial().optional(),
270
317
  git: z.strictObject(SHAPES.git).partial().optional(),
@@ -280,6 +327,8 @@ var init_statusline = __esm({
280
327
  bands: z.strictObject(SHAPES.bands),
281
328
  labels: z.strictObject(SHAPES.labels),
282
329
  bar: z.strictObject(SHAPES.bar),
330
+ usage: z.strictObject(SHAPES.usage),
331
+ clock: z.strictObject(SHAPES.clock),
283
332
  colours: z.strictObject(SHAPES.colours),
284
333
  project: z.strictObject(SHAPES.project),
285
334
  git: z.strictObject(SHAPES.git),
@@ -295,6 +344,8 @@ var init_statusline = __esm({
295
344
  bands: { warnAt: 70, criticalAt: 90 },
296
345
  labels: { fiveHour: "5h", sevenDay: "Wk" },
297
346
  bar: { width: 10, filled: "\u2588", empty: "\u2591" },
347
+ usage: { value: "used", bar: true, compact: false, resetLabel: false, modelScoped: false, timeFormat: "relative", threshold: 0, sevenDayThreshold: 0 },
348
+ clock: { hourCycle: "auto", seconds: false },
298
349
  colours: {
299
350
  context: "green",
300
351
  usage: "green",
@@ -4375,7 +4426,7 @@ var init_package = __esm({
4375
4426
  "package.json"() {
4376
4427
  package_default = {
4377
4428
  name: "claude-use",
4378
- version: "11.54.1",
4429
+ version: "11.55.0",
4379
4430
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
4380
4431
  license: "MIT",
4381
4432
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4433,6 +4484,7 @@ var init_package = __esm({
4433
4484
  commander: "^15.0.0",
4434
4485
  cosmiconfig: "^10.0.1",
4435
4486
  picomatch: "^4.0.7",
4487
+ "string-width": "8.3.0",
4436
4488
  trilean: "1.7.1",
4437
4489
  undici: "7.29.1",
4438
4490
  zod: "^4.6.1"
@@ -11963,7 +12015,7 @@ var init_identityClaude = __esm({
11963
12015
 
11964
12016
  // src/usage/providerQuota.ts
11965
12017
  import { z as z34 } from "zod";
11966
- var MS_PER_SECOND9, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
12018
+ var MS_PER_SECOND9, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY2, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
11967
12019
  var init_providerQuota = __esm({
11968
12020
  "src/usage/providerQuota.ts"() {
11969
12021
  "use strict";
@@ -11999,7 +12051,7 @@ var init_providerQuota = __esm({
11999
12051
  OPENROUTER_HOST = "openrouter.ai";
12000
12052
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
12001
12053
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
12002
- MS_PER_DAY3 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12054
+ MS_PER_DAY2 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12003
12055
  OpenRouterKeySchema = z34.object({
12004
12056
  data: z34.object({
12005
12057
  limit: z34.number().nonnegative().nullable(),
@@ -18219,13 +18271,8 @@ function createDoorHealthPublisher(hub, now, pid) {
18219
18271
  }
18220
18272
 
18221
18273
  // src/frontdoor/quotaExpiringEvents.ts
18274
+ init_pick();
18222
18275
  init_schema2();
18223
- var MS_PER_HOUR5 = 36e5;
18224
- var MS_PER_DAY2 = 864e5;
18225
- var FIVE_HOUR_WINDOW_HOURS = 5;
18226
- var SEVEN_DAY_WINDOW_DAYS = 7;
18227
- var FIVE_HOUR_WINDOW_MS2 = FIVE_HOUR_WINDOW_HOURS * MS_PER_HOUR5;
18228
- var SEVEN_DAY_WINDOW_MS2 = SEVEN_DAY_WINDOW_DAYS * MS_PER_DAY2;
18229
18276
  var FINAL_SPAN_DENOMINATOR = 30;
18230
18277
  var QUOTA_EXPIRING_WINDOW_FRACTION = 1 / FINAL_SPAN_DENOMINATOR;
18231
18278
  function createQuotaExpiringPublisher(hub, deps) {
@@ -18245,11 +18292,11 @@ function createQuotaExpiringPublisher(hub, deps) {
18245
18292
  const unified = snapshot.providers[provider]?.rateLimit?.unified;
18246
18293
  const fiveHour = unified?.fiveHour;
18247
18294
  if (fiveHour?.utilization !== void 0 && fiveHour.resetsAt !== void 0) {
18248
- views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS2, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
18295
+ views.push({ provider, view: { window: "fiveHour", spanMs: FIVE_HOUR_WINDOW_MS, utilization: fiveHour.utilization, resetsAtMs: Date.parse(fiveHour.resetsAt) } });
18249
18296
  }
18250
18297
  const sevenDay = unified?.sevenDay;
18251
18298
  if (sevenDay?.utilization !== void 0 && sevenDay.resetsAt !== void 0) {
18252
- views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS2, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
18299
+ views.push({ provider, view: { window: "sevenDay", spanMs: SEVEN_DAY_WINDOW_MS, utilization: sevenDay.utilization, resetsAtMs: Date.parse(sevenDay.resetsAt) } });
18253
18300
  }
18254
18301
  }
18255
18302
  return views;