claude-use 11.66.2 → 11.67.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
@@ -275,6 +275,9 @@ function isSingleVisibleGrapheme(text) {
275
275
  function unsettable(setting) {
276
276
  return setting.unwrap().nullable().optional().describe(`${setting.description ?? ""} ${UNSET_NOTE}`);
277
277
  }
278
+ function resettable(setting) {
279
+ return setting.nullable().optional().describe(`${setting.description ?? ""} ${RESET_NOTE}`);
280
+ }
278
281
  function canonicalLanguage(tag) {
279
282
  return tag === "zh" || tag === "zh-TW" ? LANGUAGE_ALIASES[tag] : tag;
280
283
  }
@@ -295,9 +298,6 @@ function mergeKeys(base, over) {
295
298
  }
296
299
  return merged;
297
300
  }
298
- function contextBands({ bands, context }) {
299
- return { warnAt: context.warnAt ?? bands.warnAt, criticalAt: context.criticalAt ?? bands.criticalAt };
300
- }
301
301
  function isPresetName(value) {
302
302
  return STATUSLINE_PRESETS.some((name) => name === value);
303
303
  }
@@ -306,13 +306,12 @@ function mergeStatuslineSettings(base, over) {
306
306
  return mergeKeys(isPresetName(preset) ? mergeKeys(base, PRESET_BUNDLES[preset]) : base, over);
307
307
  }
308
308
  function resolveStatusline(settings) {
309
- const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, settings));
309
+ const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, mergeKeys(void 0, settings)));
310
310
  if (resolved.bands.warnAt >= resolved.bands.criticalAt) {
311
311
  throw new RangeError(`statusline bands.warnAt (${String(resolved.bands.warnAt)}) must be below bands.criticalAt (${String(resolved.bands.criticalAt)})`);
312
312
  }
313
- const forContext = contextBands(resolved);
314
- if (forContext.warnAt >= forContext.criticalAt) {
315
- throw new RangeError(`statusline context.warnAt (${String(forContext.warnAt)}) must be below context.criticalAt (${String(forContext.criticalAt)}), each following bands while it is unset`);
313
+ if (resolved.context.warnAt >= resolved.context.criticalAt) {
314
+ throw new RangeError(`statusline context.warnAt (${String(resolved.context.warnAt)}) must be below context.criticalAt (${String(resolved.context.criticalAt)}); set both when moving one`);
316
315
  }
317
316
  const merged = new Set(resolved.layout.merge.flat());
318
317
  const unmerged = resolved.layout.rightAlign.filter((row) => !merged.has(row));
@@ -324,7 +323,7 @@ function resolveStatusline(settings) {
324
323
  }
325
324
  return resolved;
326
325
  }
327
- var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, ORANGE_PALETTE_INDEX, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_BAR_GRADIENTS, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, MAX_EXTRA_COMMAND_ARGUMENTS, MAX_EXTRA_COMMAND_ARGUMENT_CHARS, STATUSLINE_EXTRA_GROUP, commandArgument, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
326
+ var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, ORANGE_PALETTE_INDEX, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, CLAUDE_HUD_DEFAULTS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_BAR_GRADIENTS, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, MAX_EXTRA_COMMAND_ARGUMENTS, MAX_EXTRA_COMMAND_ARGUMENT_CHARS, STATUSLINE_EXTRA_GROUP, commandArgument, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, RESET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
328
327
  var init_statusline = __esm({
329
328
  "src/config/statusline.ts"() {
330
329
  "use strict";
@@ -358,13 +357,18 @@ var init_statusline = __esm({
358
357
  "brightCyan",
359
358
  "brightWhite"
360
359
  ];
361
- DEFAULT_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom"];
362
- DEFAULT_ROWS = ["context", "quota"];
360
+ DEFAULT_HEADER_SEGMENTS = ["model", "project", "vcs", "provider", "route", "account", "identity", "headroom", "extra"];
361
+ DEFAULT_ROWS = ["context", "quota", "addedDirs"];
362
+ CLAUDE_HUD_DEFAULTS = {
363
+ model: { platform: true },
364
+ usage: { resetLabel: true, modelScoped: true, sevenDayThreshold: 80 },
365
+ context: { estimate: "buffered", breakdown: "critical", warnAt: 70, criticalAt: 85 }
366
+ };
363
367
  STATUSLINE_PRESETS = ["standard", "full", "essential", "minimal"];
364
368
  GIT_WITH_DIRTY_MARKER = { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false };
365
369
  JJ_OFF = { enabled: false, showDirty: true, showConflicts: true };
366
370
  PRESET_BUNDLES = {
367
- standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
371
+ standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: CLAUDE_HUD_DEFAULTS.usage.resetLabel }, context: { breakdown: CLAUDE_HUD_DEFAULTS.context.breakdown } },
368
372
  full: {
369
373
  layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "extra", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
370
374
  git: GIT_WITH_DIRTY_MARKER,
@@ -421,7 +425,7 @@ var init_statusline = __esm({
421
425
  rows: distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row."),
422
426
  mode: import_zod2.z.enum(["expanded", "compact"]).describe("How the statusline is laid out: expanded draws the header and then the rows, each on lines of its own as layout.merge allows, and compact draws the header segments and every row's content on one line, starting a new line only where the line would be wider than the width. layout.mergeBars, layout.merge, layout.rightAlign and layout.rule have no effect in compact."),
423
427
  rule: import_zod2.z.enum(["none", "belowHeader"]).describe(`Whether a rule is drawn across the line between the header and the rows beneath it, as wide as the header's widest line (at least ${String(MIN_STATUSLINE_COLUMNS)} columns, at most the width); it is drawn only when both the header and the rows have something to show, and not in the compact layout.`),
424
- mergeBars: import_zod2.z.boolean().describe("Whether bar rows that sit next to each other in layout.rows share a line, and one grid, when they fit (the context and quota bars do by default); when false each bar row is on a line of its own, its bars still aligned to its neighbours'. A row of text is never joined by this setting, whichever form the quota row takes: layout.merge does that."),
428
+ mergeBars: import_zod2.z.boolean().describe("Whether bar rows that sit next to each other in layout.rows share a line, and one grid, when they fit (the context and quota bars do by default); when false each bar row is on a line of its own, its bars aligned to its neighbours' while the line is wide enough for that. A row of text is never joined by this setting, whichever form the quota row takes: layout.merge does that."),
425
429
  merge: mergeGroups.describe("Groups of rows that share a line when they sit next to each other in layout.rows and fit on one line together, and are drawn on lines of their own when they do not; each group names at least two rows, and no row belongs to two groups. A group may mix bar rows and rows of text, which are joined with the separator when every member is a single line. Bar rows outside a group follow layout.mergeBars. A group in which no row has anything to show draws nothing: one with a row of text in it still ends a run of bars sharing a line, as an empty row of text does, and one of bar rows alone is left out, so the bars either side of it share as if it were not there."),
426
430
  rightAlign: distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).describe("Rows that start the right-aligned part of a merged line: the first of them to appear on a line, and the rows after it, are pushed to the right edge, with the gap padded by spaces. A row named here must belong to a group in layout.merge, and it has no effect when it is the first row of its line."),
427
431
  maxWidth: import_zod2.z.number().int().min(0).max(MAX_STATUSLINE_COLUMNS).refine((columns) => columns === 0 || columns >= MIN_STATUSLINE_COLUMNS, `must be 0, or at least ${String(MIN_STATUSLINE_COLUMNS)} columns`).describe(`The exact width in columns lines are drawn to when the client reports none and the COLUMNS environment variable names none, in place of the default width it would assume for the terminal; unlike a terminal's width, it is not reduced by the columns Claude Code keeps back for itself. It is 0, to leave it unset, or from ${String(MIN_STATUSLINE_COLUMNS)} to ${String(MAX_STATUSLINE_COLUMNS)}; a value outside that is refused, not clamped.`),
@@ -430,7 +434,8 @@ var init_statusline = __esm({
430
434
  model: {
431
435
  format: import_zod2.z.enum(["full", "compact", "short"]).describe("How the model's name is written: full is the name as the client gives it, compact drops a context-window suffix such as (1M context), and short also drops a leading Claude."),
432
436
  override: overrideText.describe("A name to show in place of the client's own model name, whatever model is running; empty shows the model's own name. A dynamic mode's served model still follows it."),
433
- source: import_zod2.z.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports, transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like.")
437
+ source: import_zod2.z.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports (its display name, else its model id, each trimmed and read as absent when blank), transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like."),
438
+ platform: import_zod2.z.boolean().describe("Whether the model segment ends with the label claude-hud draws beside the model name, chosen from the client's environment and model id as claude-hud chooses it, the first that holds: Bedrock when CLAUDE_CODE_USE_BEDROCK is 1, Vertex when CLAUDE_CODE_USE_VERTEX is 1, MiniMax when ANTHROPIC_BASE_URL (else ANTHROPIC_API_BASE_URL), trimmed, is https://api.minimax.io/anthropic or https://api.minimaxi.com/anthropic compared by origin and path with any trailing slash, query or default port ignored, and Enterprise when the model id is opusplan, sonnetplan or haikuplan in any case. Nothing is drawn when none holds, and the label stands alone when no name is known: the client's display name and model id are both absent or blank, no override is set, and model.source supplies no transcript name (under transcript it supplies one when the transcript has an assistant record with a model, and under auto only for such a model that is not a Claude one), or model.format leaves nothing of the name. The switches and the model ids are Claude Code's, so an Antigravity client never draws the label. It is not the provider segment, which names the agent-shim provider the launch selected and the door routes to.")
434
439
  },
435
440
  provider: {
436
441
  name: overrideText.describe("A label to show in place of the launch's provider name, or on its own when the launch has no provider; empty shows the provider's own name.")
@@ -448,11 +453,16 @@ var init_statusline = __esm({
448
453
  context: {
449
454
  bar: import_zod2.z.enum(["shown", "hidden"]).describe("Whether the context row draws its bar, or only its figures on one line of text."),
450
455
  value: import_zod2.z.enum(STATUSLINE_CONTEXT_VALUES).describe("The context figure: both (the tokens held against the window, then the percentage), percent, tokens, or remaining (the percentage of the window left)."),
451
- warnAt: wholePercent.optional().describe("The whole percentage of the context window at which the context bar turns yellow when bar.gradient is off (a bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn); while it is unset the context bar follows bands.warnAt."),
452
- criticalAt: wholePercent.optional().describe("The whole percentage of the context window at which the context bar turns red when bar.gradient is off (a bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn) and, with context.breakdown set to critical, the token breakdown appears; while it is unset the context bar follows bands.criticalAt."),
456
+ warnAt: wholePercent.describe("The whole percentage of the context window at which the context bar turns yellow when bar.gradient is off (a bar.gradient of use holds the warning colour exactly where the bar turns yellow, half a point below this percentage for the rounding, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn); it must be below context.criticalAt. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It is the context bar's own threshold, apart from bands.warnAt, which colours the other bars and the context row's cache hit share, and its default is claude-hud's contextWarningThreshold."),
457
+ criticalAt: wholePercent.describe("The whole percentage of the context window at which the context bar turns red when bar.gradient is off (a bar.gradient of use holds the critical colour from where the bar turns red, half a point below this percentage for the rounding, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn), and from which the token breakdown appears while context.breakdownAt is unset. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It is the context bar's own threshold, apart from bands.criticalAt, which colours the other bars and the context row's cache hit share, and its default is claude-hud's contextCriticalThreshold, which also starts claude-hud's breakdown."),
458
+ breakdownAt: wholePercent.optional().describe(
459
+ "The whole percentage of the context window from which the token breakdown appears, with context.breakdown set to critical; while it is unset the breakdown appears from context.criticalAt. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It need not relate to context.warnAt or context.criticalAt, since it decides when a piece of information is shown and not a colour, so it may sit below, at or above either."
460
+ ),
453
461
  autoCompactWindow: import_zod2.z.number().int().positive().optional().describe("A window in tokens to measure the context against instead of the model's, matching the figure /context gives once Claude Code compacts before the window is full. While it is set, the row draws nothing until the client reports the tokens held, since without them there is nothing to measure against it; while it is unset the model's own window is used."),
454
- estimate: import_zod2.z.enum(STATUSLINE_CONTEXT_ESTIMATES).describe(`What to draw when the client reports no percentage of the window in use, or reports 0 while tokens are already held (which is how a client says it has not worked it out yet): never (nothing is estimated: a percentage reported, 0 included, is drawn as it is, and none reported draws nothing), raw (the tokens held over the window), or buffered (that, plus the ${String(AUTOCOMPACT_RESERVE_FRACTION * MAX_PERCENT)}% of the window Claude Code reserves for compaction, rising from nothing at ${String(AUTOCOMPACT_RESERVE_RAMP_START * MAX_PERCENT)}% of the window held to the whole reserve at ${String(AUTOCOMPACT_RESERVE_RAMP_END * MAX_PERCENT)}%).`),
455
- breakdown: import_zod2.z.enum(["never", "critical"]).describe("Whether to add the input and cache tokens of the last request to the context row once its use reaches context.criticalAt.")
462
+ estimate: import_zod2.z.enum(STATUSLINE_CONTEXT_ESTIMATES).describe(`What to draw when the client reports no percentage of the window in use (a negative one counts as none), or reports 0 while tokens are already held (which is how a client says it has not worked it out yet): never (nothing is estimated: a percentage reported from 0 to 100 is drawn as it is, one above 100 as 100, and a negative or missing one draws nothing), raw (the tokens held over the window), or buffered (that, plus the ${String(AUTOCOMPACT_RESERVE_FRACTION * MAX_PERCENT)}% of the window Claude Code reserves for compaction, rising from nothing at ${String(AUTOCOMPACT_RESERVE_RAMP_START * MAX_PERCENT)}% of the window held to the whole reserve at ${String(AUTOCOMPACT_RESERVE_RAMP_END * MAX_PERCENT)}%).`),
463
+ breakdown: import_zod2.z.enum(["never", "critical"]).describe(
464
+ "Whether to add the input and cache tokens of the last request to the context row: critical adds them once the percentage the row draws (the one the client reports, or the estimate context.estimate makes, or, with context.autoCompactWindow set, the tokens held over that window), rounded to a whole number, reaches the breakdown threshold, which is context.breakdownAt, or context.criticalAt while that is unset, and never leaves them off. With no percentage to draw the row draws nothing, and when the client does not report the last request's tokens there is no breakdown to add."
465
+ )
456
466
  },
457
467
  customLine: {
458
468
  text: overrideText.describe(`A line of your own text to draw, in colours.custom; empty draws nothing. It is refused when longer than ${String(MAX_DISPLAY_TEXT_CHARS)} characters or when it holds control, format or separator characters, and words are separated by single spaces. A character that passes but draws nothing, such as a braille blank, is removed, and the line is cut to the usable width.`),
@@ -464,17 +474,17 @@ var init_statusline = __esm({
464
474
  )
465
475
  },
466
476
  bands: {
467
- warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow when bar.gradient is off; it must be below criticalAt. A bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn."),
468
- criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red when bar.gradient is off. A bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn.")
477
+ warnAt: wholePercent.describe("The whole percentage of use at which a bar other than the context bar turns yellow when bar.gradient is off (the context bar has context.warnAt); it must be below criticalAt. A bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn. The context row's cache hit share is coloured by these bands too."),
478
+ criticalAt: wholePercent.describe("The whole percentage of use at which a bar other than the context bar turns red when bar.gradient is off (the context bar has context.criticalAt). A bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn. The context row's cache hit share is coloured by these bands too.")
469
479
  },
470
480
  labels: {
471
- fiveHour: windowLabel.describe("The name of the five-hour subscription window; empty uses the language's own name for it."),
472
- sevenDay: windowLabel.describe("The name of the weekly subscription window; empty uses the language's own name for it.")
481
+ fiveHour: windowLabel.describe("The name of the five-hour window; empty uses the language's own name for it."),
482
+ sevenDay: windowLabel.describe("The name of the weekly window; empty uses the language's own name for it.")
473
483
  },
474
484
  bar: {
475
485
  width: import_zod2.z.number().int().min(1).max(MAX_BAR_CELLS).describe("A bar's width in cells before the line's spare width is shared out among the bars."),
476
486
  gradient: import_zod2.z.enum(STATUSLINE_BAR_GRADIENTS).describe(
477
- "How a bar's used part is coloured: off (the default) draws the band's single colour, the bar's own colour below the warning threshold, the warning colour from there and the critical one from the critical threshold; use blends the bar's colour with its use, from its own colour at none in use to the warning colour at the warning threshold and the critical one at the critical threshold, holding exactly the colour the bands draw at each threshold and the critical colour above it; and width colours each cell of the used part across the bar's width, from the bar's own colour at the first cell to the critical one at the last, whatever the use, with a bar one cell wide drawing that cell in its own colour. A bar's thresholds are bands.warnAt and bands.criticalAt, the context bar's own where it sets them, and the figures beside a bar keep the band's colours in every mode. The unused part keeps colours.empty in every mode, and when that is default or dim, which set no colour of their own, it draws in the colour the used part ends in: under off the band's colour, under use the blend for the bar's use (even where no cell of the used part is drawn), and under width the last drawn cell's colour (the band's colour where no cell is drawn). A gradient blends RGB values, so a colour name, or a palette index below 16, is blended at the default RGB the xterm scheme gives it rather than the shade a themed terminal draws it in, while a stop itself, where a mode holds it exactly, is drawn as the bands draw that role. A bar whose stops include a role set to default or dim, which names no colour of its own, is drawn in the band's single colour: for use those stops are the bar's own, warning and critical roles, and for width its own and critical roles. A width bar with no cell of its used part drawn has no cell to colour, so it takes the band's colours as off does."
487
+ "How a bar's used part is coloured: off (the default) draws the band's single colour, the bar's own colour below the warning threshold, the warning colour from there and the critical one from the critical threshold; use blends the bar's colour with its use, from its own colour at none in use to the warning colour at the warning threshold and the critical one at the critical threshold, holding exactly the colour the bar draws without a gradient at each threshold (the context bar's sit half a point below its whole percentages) and the critical colour above it; and width colours each cell of the used part across the bar's width, from the bar's own colour at the first cell to the critical one at the last, whatever the use, with a bar one cell wide drawing that cell in its own colour. A bar's thresholds are bands.warnAt and bands.criticalAt, and the context bar's are context.warnAt and context.criticalAt, and the figures beside a bar keep the band's colours in every mode. The unused part keeps colours.empty in every mode, and when that is default or dim, which set no colour of their own, it draws in the colour the used part ends in: under off the band's colour, under use the blend for the bar's use (even where no cell of the used part is drawn), and under width the last drawn cell's colour (the band's colour where no cell is drawn). A gradient blends RGB values, so a colour name, or a palette index below 16, is blended at the default RGB the xterm scheme gives it rather than the shade a themed terminal draws it in, while a stop itself, where a mode holds it exactly, is drawn as the bands draw that role. A bar whose stops include a role set to default or dim, which names no colour of its own, is drawn in the band's single colour: for use those stops are the bar's own, warning and critical roles, and for width its own and critical roles. A width bar with no cell of its used part drawn has no cell to colour, so it takes the band's colours as off does."
478
488
  ),
479
489
  filled: barCharacter.describe("The character that draws the used part of a bar."),
480
490
  empty: barCharacter.describe("The character that draws the unused part of a bar.")
@@ -484,10 +494,10 @@ var init_statusline = __esm({
484
494
  bar: import_zod2.z.boolean().describe("Whether each quota window is drawn as a bar, or as text alone."),
485
495
  compact: import_zod2.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."),
486
496
  resetLabel: import_zod2.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)`."),
487
- modelScoped: import_zod2.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."),
497
+ modelScoped: import_zod2.z.boolean().describe("Whether the per-model weekly windows the client reports (rate_limits.model_scoped) are drawn after the five-hour and weekly windows (one reported with a null, missing or non-numeric figure is drawn as two hyphens beside its reset); they describe the signed-in account, so a session that selected a provider never shows them, nor does a Bedrock session, whose subscription windows do not apply."),
488
498
  timeFormat: import_zod2.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."),
489
- 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."),
490
- 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.")
499
+ 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, the use compared after rounding to a whole percentage, as claude-hud compares it; 0 never hides it. A Bedrock session that selected no provider draws no five-hour, weekly or per-model window, whatever this is."),
500
+ sevenDayThreshold: thresholdPercent.describe("The whole percentage of use at which the weekly window is drawn beside the five-hour one, the use compared after rounding to a whole percentage, as claude-hud compares it; below it the weekly window is hidden, and 0 never hides it. A weekly window with no five-hour window beside it is never hidden by this setting. A Bedrock session that selected no provider draws no five-hour, weekly or per-model window, so this setting has nothing to hide there, and usage.threshold can still hide the whole row.")
491
501
  },
492
502
  clock: {
493
503
  hourCycle: import_zod2.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)."),
@@ -510,11 +520,11 @@ var init_statusline = __esm({
510
520
  maxVisible: import_zod2.z.number().int().min(0).describe("The most kinds of finished tool call the tools row names, the most-used first, with the rest counted as +N more. 0 names every kind.")
511
521
  },
512
522
  colours: {
513
- context: colourValue.describe("The colour of the context bar below the warning threshold while bar.gradient is off, of the figures beside it below that threshold in every mode, and the colour a bar.gradient of use or width blends the context bar from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
523
+ context: colourValue.describe("The colour of the context bar below the warning threshold while bar.gradient is off, of the figures beside it below that threshold in every mode, of a cache hit share above 100 less bands.warnAt percent, and the colour a bar.gradient of use or width blends the context bar from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
514
524
  usage: colourValue.describe("The colour of the quota bars and the memory bar below the warning threshold while bar.gradient is off, of the figures beside them below that threshold in every mode, and the colour a bar.gradient of use or width blends those bars from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
515
- warning: colourValue.describe("The colour of the context bar from its warning threshold (bands.warnAt, or context.warnAt where that is set) up to its critical threshold (bands.criticalAt, or context.criticalAt where that is set) when bar.gradient is off (a bar.gradient of use holds it exactly at the threshold, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), of the figures beside the bar from that threshold up to its critical threshold in every mode, and of a cache hit share that is middling."),
525
+ warning: colourValue.describe("The colour of the context bar from context.warnAt up to context.criticalAt when bar.gradient is off (a bar.gradient of use holds it exactly where the bar turns yellow, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), of the figures beside the bar from that threshold up to context.criticalAt in every mode, and of a cache hit share above 100 less bands.criticalAt percent and at most 100 less bands.warnAt percent."),
516
526
  usageWarning: colourValue.describe("The colour of a quota bar or the memory bar from bands.warnAt up to bands.criticalAt when bar.gradient is off (a bar.gradient of use holds it exactly at bands.warnAt, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), and of the figures beside the bar from that threshold up to bands.criticalAt in every mode."),
517
- critical: colourValue.describe("The colour of a bar at or above its critical threshold (bands.criticalAt, or context.criticalAt for the context bar where that is set) when bar.gradient is off or use, of the last cell of a full bar more than one cell wide under a bar.gradient of width (a bar one cell wide draws its cell in its own colour, and a width bar whose own colour or this one is default or dim, or that has no cell of its used part drawn, draws the band's colours instead), of the figures beside a bar from its critical threshold in every mode, and of a cache hit share that is nearly nothing."),
527
+ critical: colourValue.describe("The colour of a bar at or above its critical threshold (context.criticalAt for the context bar, bands.criticalAt for any other bar) when bar.gradient is off or use, of the last cell of a full bar more than one cell wide under a bar.gradient of width (a bar one cell wide draws its cell in its own colour, and a width bar whose own colour or this one is default or dim, or that has no cell of its used part drawn, draws the band's colours instead), of the figures beside a bar from its critical threshold in every mode, and of a cache hit share of at most 100 less bands.criticalAt percent."),
518
528
  model: colourValue.describe("The colour of the model and provider segments."),
519
529
  label: colourValue.describe("The colour of labels and secondary text: row labels, and the route, account, identity and headroom segments."),
520
530
  empty: colourValue.describe("The colour of the unused part of a bar."),
@@ -545,12 +555,13 @@ var init_statusline = __esm({
545
555
  }
546
556
  };
547
557
  UNSET_NOTE = "A layer may write null to return it to unset when a shallower layer sets it.";
558
+ RESET_NOTE = "A layer may write null to return it to its default when a shallower layer sets it.";
548
559
  LANGUAGE_DESCRIPTION = "The language of the words the statusline writes (labels, units of waiting such as `ago`, the names of effort levels): en, zh-Hans for Chinese in simplified characters, and zh-Hant for traditional; zh and zh-TW are read as zh-Hans and zh-Hant, and any other tag is refused. Durations, token counts, the dollar sign and clock times are written the same in every language, and a clock time follows the system locale and the clock settings.";
549
560
  LANGUAGE_TAGS = [...STATUSLINE_LANGUAGES, "zh", "zh-TW"];
550
561
  LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
551
562
  TOP_LEVEL = {
552
563
  language: import_zod2.z.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
553
- preset: import_zod2.z.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments, the extra segment once extra.command is set, and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
564
+ preset: import_zod2.z.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own default, everything claude-hud's default configuration draws plus agent-shim's own segments; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments, the extra segment once extra.command is set, and the context row; standard adds the provider, route, account, identity and headroom segments and the quota and added directories rows, with the reset label and the token breakdown from its threshold, full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown from its threshold, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
554
565
  };
555
566
  StatuslineSchema = import_zod2.z.strictObject({
556
567
  language: import_zod2.z.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
@@ -561,7 +572,7 @@ var init_statusline = __esm({
561
572
  account: import_zod2.z.strictObject(SHAPES.account).partial().optional(),
562
573
  effort: import_zod2.z.strictObject(SHAPES.effort).partial().optional(),
563
574
  advisor: import_zod2.z.strictObject(SHAPES.advisor).partial().optional(),
564
- context: import_zod2.z.strictObject({ ...SHAPES.context, warnAt: unsettable(SHAPES.context.warnAt), criticalAt: unsettable(SHAPES.context.criticalAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
575
+ context: import_zod2.z.strictObject({ ...SHAPES.context, warnAt: resettable(SHAPES.context.warnAt), criticalAt: resettable(SHAPES.context.criticalAt), breakdownAt: unsettable(SHAPES.context.breakdownAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
565
576
  customLine: import_zod2.z.strictObject(SHAPES.customLine).partial().optional(),
566
577
  extra: import_zod2.z.strictObject(SHAPES.extra).partial().optional(),
567
578
  bands: import_zod2.z.strictObject(SHAPES.bands).partial().optional(),
@@ -610,18 +621,18 @@ var init_statusline = __esm({
610
621
  language: "en",
611
622
  preset: "standard",
612
623
  layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS], mode: "expanded", rule: "none", mergeBars: true, merge: [], rightAlign: [], maxWidth: 0, forceMaxWidth: false },
613
- model: { format: "full", override: "", source: "client" },
624
+ model: { format: "full", override: "", source: "client", platform: CLAUDE_HUD_DEFAULTS.model.platform },
614
625
  provider: { name: "" },
615
626
  account: { parts: ["user", "organisation", "plan"], userLength: 0 },
616
627
  effort: { format: "full" },
617
628
  advisor: { override: "" },
618
- context: { bar: "shown", value: "both", estimate: "never", breakdown: "never" },
629
+ context: { bar: "shown", value: "both", warnAt: CLAUDE_HUD_DEFAULTS.context.warnAt, criticalAt: CLAUDE_HUD_DEFAULTS.context.criticalAt, estimate: CLAUDE_HUD_DEFAULTS.context.estimate, breakdown: CLAUDE_HUD_DEFAULTS.context.breakdown },
619
630
  customLine: { text: "", position: "last" },
620
631
  extra: { command: [] },
621
632
  bands: { warnAt: 70, criticalAt: 90 },
622
633
  labels: { fiveHour: "", sevenDay: "" },
623
634
  bar: { width: 10, gradient: "off", filled: "\u2588", empty: "\u2591" },
624
- usage: { value: "used", bar: true, compact: false, resetLabel: false, modelScoped: false, timeFormat: "relative", threshold: 0, sevenDayThreshold: 0 },
635
+ usage: { value: "used", bar: true, compact: false, resetLabel: CLAUDE_HUD_DEFAULTS.usage.resetLabel, modelScoped: CLAUDE_HUD_DEFAULTS.usage.modelScoped, timeFormat: "relative", threshold: 0, sevenDayThreshold: CLAUDE_HUD_DEFAULTS.usage.sevenDayThreshold },
625
636
  clock: { hourCycle: "auto", seconds: false },
626
637
  cost: { routed: false },
627
638
  environment: { threshold: 0 },
@@ -4751,7 +4762,7 @@ var init_package = __esm({
4751
4762
  "package.json"() {
4752
4763
  package_default = {
4753
4764
  name: "claude-use",
4754
- version: "11.66.2",
4765
+ version: "11.67.0",
4755
4766
  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.",
4756
4767
  license: "MIT",
4757
4768
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4810,7 +4821,7 @@ var init_package = __esm({
4810
4821
  cosmiconfig: "^10.0.1",
4811
4822
  picomatch: "^4.0.7",
4812
4823
  "string-width": "8.3.0",
4813
- trilean: "1.7.1",
4824
+ trilean: "1.9.0",
4814
4825
  undici: "7.30.1",
4815
4826
  zod: "^4.6.7"
4816
4827
  },
@@ -7973,10 +7984,14 @@ function valueAt(source, path42) {
7973
7984
  }
7974
7985
  return current;
7975
7986
  }
7987
+ function acceptsNull(path42) {
7988
+ const layer = path42.reduceRight((inner, part) => ({ [part]: inner }), null);
7989
+ return StatuslineSchema.safeParse(layer).success;
7990
+ }
7976
7991
  function keyOf(path42, declared) {
7977
7992
  const optional = declared instanceof import_zod16.z.ZodOptional;
7978
7993
  const leaf = optional ? declared.unwrap() : declared;
7979
- const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional };
7994
+ const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional, unsettable: acceptsNull(path42) };
7980
7995
  if (leaf instanceof import_zod16.z.ZodNumber) {
7981
7996
  return { ...common, kind: "integer", choices: [] };
7982
7997
  }
package/dist/index.mjs CHANGED
@@ -255,6 +255,9 @@ function isSingleVisibleGrapheme(text) {
255
255
  function unsettable(setting) {
256
256
  return setting.unwrap().nullable().optional().describe(`${setting.description ?? ""} ${UNSET_NOTE}`);
257
257
  }
258
+ function resettable(setting) {
259
+ return setting.nullable().optional().describe(`${setting.description ?? ""} ${RESET_NOTE}`);
260
+ }
258
261
  function canonicalLanguage(tag) {
259
262
  return tag === "zh" || tag === "zh-TW" ? LANGUAGE_ALIASES[tag] : tag;
260
263
  }
@@ -275,9 +278,6 @@ function mergeKeys(base, over) {
275
278
  }
276
279
  return merged;
277
280
  }
278
- function contextBands({ bands, context }) {
279
- return { warnAt: context.warnAt ?? bands.warnAt, criticalAt: context.criticalAt ?? bands.criticalAt };
280
- }
281
281
  function isPresetName(value) {
282
282
  return STATUSLINE_PRESETS.some((name) => name === value);
283
283
  }
@@ -286,13 +286,12 @@ function mergeStatuslineSettings(base, over) {
286
286
  return mergeKeys(isPresetName(preset) ? mergeKeys(base, PRESET_BUNDLES[preset]) : base, over);
287
287
  }
288
288
  function resolveStatusline(settings) {
289
- const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, settings));
289
+ const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, mergeKeys(void 0, settings)));
290
290
  if (resolved.bands.warnAt >= resolved.bands.criticalAt) {
291
291
  throw new RangeError(`statusline bands.warnAt (${String(resolved.bands.warnAt)}) must be below bands.criticalAt (${String(resolved.bands.criticalAt)})`);
292
292
  }
293
- const forContext = contextBands(resolved);
294
- if (forContext.warnAt >= forContext.criticalAt) {
295
- throw new RangeError(`statusline context.warnAt (${String(forContext.warnAt)}) must be below context.criticalAt (${String(forContext.criticalAt)}), each following bands while it is unset`);
293
+ if (resolved.context.warnAt >= resolved.context.criticalAt) {
294
+ throw new RangeError(`statusline context.warnAt (${String(resolved.context.warnAt)}) must be below context.criticalAt (${String(resolved.context.criticalAt)}); set both when moving one`);
296
295
  }
297
296
  const merged = new Set(resolved.layout.merge.flat());
298
297
  const unmerged = resolved.layout.rightAlign.filter((row) => !merged.has(row));
@@ -304,7 +303,7 @@ function resolveStatusline(settings) {
304
303
  }
305
304
  return resolved;
306
305
  }
307
- var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, ORANGE_PALETTE_INDEX, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_BAR_GRADIENTS, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, MAX_EXTRA_COMMAND_ARGUMENTS, MAX_EXTRA_COMMAND_ARGUMENT_CHARS, STATUSLINE_EXTRA_GROUP, commandArgument, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
306
+ var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, ORANGE_PALETTE_INDEX, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, CLAUDE_HUD_DEFAULTS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_BAR_GRADIENTS, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, MAX_EXTRA_COMMAND_ARGUMENTS, MAX_EXTRA_COMMAND_ARGUMENT_CHARS, STATUSLINE_EXTRA_GROUP, commandArgument, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, RESET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
308
307
  var init_statusline = __esm({
309
308
  "src/config/statusline.ts"() {
310
309
  "use strict";
@@ -336,13 +335,18 @@ var init_statusline = __esm({
336
335
  "brightCyan",
337
336
  "brightWhite"
338
337
  ];
339
- DEFAULT_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom"];
340
- DEFAULT_ROWS = ["context", "quota"];
338
+ DEFAULT_HEADER_SEGMENTS = ["model", "project", "vcs", "provider", "route", "account", "identity", "headroom", "extra"];
339
+ DEFAULT_ROWS = ["context", "quota", "addedDirs"];
340
+ CLAUDE_HUD_DEFAULTS = {
341
+ model: { platform: true },
342
+ usage: { resetLabel: true, modelScoped: true, sevenDayThreshold: 80 },
343
+ context: { estimate: "buffered", breakdown: "critical", warnAt: 70, criticalAt: 85 }
344
+ };
341
345
  STATUSLINE_PRESETS = ["standard", "full", "essential", "minimal"];
342
346
  GIT_WITH_DIRTY_MARKER = { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false };
343
347
  JJ_OFF = { enabled: false, showDirty: true, showConflicts: true };
344
348
  PRESET_BUNDLES = {
345
- standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
349
+ standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: CLAUDE_HUD_DEFAULTS.usage.resetLabel }, context: { breakdown: CLAUDE_HUD_DEFAULTS.context.breakdown } },
346
350
  full: {
347
351
  layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "extra", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
348
352
  git: GIT_WITH_DIRTY_MARKER,
@@ -399,7 +403,7 @@ var init_statusline = __esm({
399
403
  rows: distinctList(z2.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row."),
400
404
  mode: z2.enum(["expanded", "compact"]).describe("How the statusline is laid out: expanded draws the header and then the rows, each on lines of its own as layout.merge allows, and compact draws the header segments and every row's content on one line, starting a new line only where the line would be wider than the width. layout.mergeBars, layout.merge, layout.rightAlign and layout.rule have no effect in compact."),
401
405
  rule: z2.enum(["none", "belowHeader"]).describe(`Whether a rule is drawn across the line between the header and the rows beneath it, as wide as the header's widest line (at least ${String(MIN_STATUSLINE_COLUMNS)} columns, at most the width); it is drawn only when both the header and the rows have something to show, and not in the compact layout.`),
402
- mergeBars: z2.boolean().describe("Whether bar rows that sit next to each other in layout.rows share a line, and one grid, when they fit (the context and quota bars do by default); when false each bar row is on a line of its own, its bars still aligned to its neighbours'. A row of text is never joined by this setting, whichever form the quota row takes: layout.merge does that."),
406
+ mergeBars: z2.boolean().describe("Whether bar rows that sit next to each other in layout.rows share a line, and one grid, when they fit (the context and quota bars do by default); when false each bar row is on a line of its own, its bars aligned to its neighbours' while the line is wide enough for that. A row of text is never joined by this setting, whichever form the quota row takes: layout.merge does that."),
403
407
  merge: mergeGroups.describe("Groups of rows that share a line when they sit next to each other in layout.rows and fit on one line together, and are drawn on lines of their own when they do not; each group names at least two rows, and no row belongs to two groups. A group may mix bar rows and rows of text, which are joined with the separator when every member is a single line. Bar rows outside a group follow layout.mergeBars. A group in which no row has anything to show draws nothing: one with a row of text in it still ends a run of bars sharing a line, as an empty row of text does, and one of bar rows alone is left out, so the bars either side of it share as if it were not there."),
404
408
  rightAlign: distinctList(z2.enum(STATUSLINE_ROWS)).describe("Rows that start the right-aligned part of a merged line: the first of them to appear on a line, and the rows after it, are pushed to the right edge, with the gap padded by spaces. A row named here must belong to a group in layout.merge, and it has no effect when it is the first row of its line."),
405
409
  maxWidth: z2.number().int().min(0).max(MAX_STATUSLINE_COLUMNS).refine((columns) => columns === 0 || columns >= MIN_STATUSLINE_COLUMNS, `must be 0, or at least ${String(MIN_STATUSLINE_COLUMNS)} columns`).describe(`The exact width in columns lines are drawn to when the client reports none and the COLUMNS environment variable names none, in place of the default width it would assume for the terminal; unlike a terminal's width, it is not reduced by the columns Claude Code keeps back for itself. It is 0, to leave it unset, or from ${String(MIN_STATUSLINE_COLUMNS)} to ${String(MAX_STATUSLINE_COLUMNS)}; a value outside that is refused, not clamped.`),
@@ -408,7 +412,8 @@ var init_statusline = __esm({
408
412
  model: {
409
413
  format: z2.enum(["full", "compact", "short"]).describe("How the model's name is written: full is the name as the client gives it, compact drops a context-window suffix such as (1M context), and short also drops a leading Claude."),
410
414
  override: overrideText.describe("A name to show in place of the client's own model name, whatever model is running; empty shows the model's own name. A dynamic mode's served model still follows it."),
411
- source: z2.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports, transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like.")
415
+ source: z2.enum(["client", "transcript", "auto"]).describe("Where the model's name comes from: client is the name the client reports (its display name, else its model id, each trimmed and read as absent when blank), transcript is the model the session's last reply came from (what a proxy actually served), and auto uses the transcript's model only when it is not a Claude model, which is what a proxy redirect looks like."),
416
+ platform: z2.boolean().describe("Whether the model segment ends with the label claude-hud draws beside the model name, chosen from the client's environment and model id as claude-hud chooses it, the first that holds: Bedrock when CLAUDE_CODE_USE_BEDROCK is 1, Vertex when CLAUDE_CODE_USE_VERTEX is 1, MiniMax when ANTHROPIC_BASE_URL (else ANTHROPIC_API_BASE_URL), trimmed, is https://api.minimax.io/anthropic or https://api.minimaxi.com/anthropic compared by origin and path with any trailing slash, query or default port ignored, and Enterprise when the model id is opusplan, sonnetplan or haikuplan in any case. Nothing is drawn when none holds, and the label stands alone when no name is known: the client's display name and model id are both absent or blank, no override is set, and model.source supplies no transcript name (under transcript it supplies one when the transcript has an assistant record with a model, and under auto only for such a model that is not a Claude one), or model.format leaves nothing of the name. The switches and the model ids are Claude Code's, so an Antigravity client never draws the label. It is not the provider segment, which names the agent-shim provider the launch selected and the door routes to.")
412
417
  },
413
418
  provider: {
414
419
  name: overrideText.describe("A label to show in place of the launch's provider name, or on its own when the launch has no provider; empty shows the provider's own name.")
@@ -426,11 +431,16 @@ var init_statusline = __esm({
426
431
  context: {
427
432
  bar: z2.enum(["shown", "hidden"]).describe("Whether the context row draws its bar, or only its figures on one line of text."),
428
433
  value: z2.enum(STATUSLINE_CONTEXT_VALUES).describe("The context figure: both (the tokens held against the window, then the percentage), percent, tokens, or remaining (the percentage of the window left)."),
429
- warnAt: wholePercent.optional().describe("The whole percentage of the context window at which the context bar turns yellow when bar.gradient is off (a bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn); while it is unset the context bar follows bands.warnAt."),
430
- criticalAt: wholePercent.optional().describe("The whole percentage of the context window at which the context bar turns red when bar.gradient is off (a bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn) and, with context.breakdown set to critical, the token breakdown appears; while it is unset the context bar follows bands.criticalAt."),
434
+ warnAt: wholePercent.describe("The whole percentage of the context window at which the context bar turns yellow when bar.gradient is off (a bar.gradient of use holds the warning colour exactly where the bar turns yellow, half a point below this percentage for the rounding, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn); it must be below context.criticalAt. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It is the context bar's own threshold, apart from bands.warnAt, which colours the other bars and the context row's cache hit share, and its default is claude-hud's contextWarningThreshold."),
435
+ criticalAt: wholePercent.describe("The whole percentage of the context window at which the context bar turns red when bar.gradient is off (a bar.gradient of use holds the critical colour from where the bar turns red, half a point below this percentage for the rounding, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn), and from which the token breakdown appears while context.breakdownAt is unset. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It is the context bar's own threshold, apart from bands.criticalAt, which colours the other bars and the context row's cache hit share, and its default is claude-hud's contextCriticalThreshold, which also starts claude-hud's breakdown."),
436
+ breakdownAt: wholePercent.optional().describe(
437
+ "The whole percentage of the context window from which the token breakdown appears, with context.breakdown set to critical; while it is unset the breakdown appears from context.criticalAt. The percentage is rounded to a whole number before it is compared with this, as claude-hud rounds it, so a reading within half a point below counts as at it. It need not relate to context.warnAt or context.criticalAt, since it decides when a piece of information is shown and not a colour, so it may sit below, at or above either."
438
+ ),
431
439
  autoCompactWindow: z2.number().int().positive().optional().describe("A window in tokens to measure the context against instead of the model's, matching the figure /context gives once Claude Code compacts before the window is full. While it is set, the row draws nothing until the client reports the tokens held, since without them there is nothing to measure against it; while it is unset the model's own window is used."),
432
- estimate: z2.enum(STATUSLINE_CONTEXT_ESTIMATES).describe(`What to draw when the client reports no percentage of the window in use, or reports 0 while tokens are already held (which is how a client says it has not worked it out yet): never (nothing is estimated: a percentage reported, 0 included, is drawn as it is, and none reported draws nothing), raw (the tokens held over the window), or buffered (that, plus the ${String(AUTOCOMPACT_RESERVE_FRACTION * MAX_PERCENT)}% of the window Claude Code reserves for compaction, rising from nothing at ${String(AUTOCOMPACT_RESERVE_RAMP_START * MAX_PERCENT)}% of the window held to the whole reserve at ${String(AUTOCOMPACT_RESERVE_RAMP_END * MAX_PERCENT)}%).`),
433
- breakdown: z2.enum(["never", "critical"]).describe("Whether to add the input and cache tokens of the last request to the context row once its use reaches context.criticalAt.")
440
+ estimate: z2.enum(STATUSLINE_CONTEXT_ESTIMATES).describe(`What to draw when the client reports no percentage of the window in use (a negative one counts as none), or reports 0 while tokens are already held (which is how a client says it has not worked it out yet): never (nothing is estimated: a percentage reported from 0 to 100 is drawn as it is, one above 100 as 100, and a negative or missing one draws nothing), raw (the tokens held over the window), or buffered (that, plus the ${String(AUTOCOMPACT_RESERVE_FRACTION * MAX_PERCENT)}% of the window Claude Code reserves for compaction, rising from nothing at ${String(AUTOCOMPACT_RESERVE_RAMP_START * MAX_PERCENT)}% of the window held to the whole reserve at ${String(AUTOCOMPACT_RESERVE_RAMP_END * MAX_PERCENT)}%).`),
441
+ breakdown: z2.enum(["never", "critical"]).describe(
442
+ "Whether to add the input and cache tokens of the last request to the context row: critical adds them once the percentage the row draws (the one the client reports, or the estimate context.estimate makes, or, with context.autoCompactWindow set, the tokens held over that window), rounded to a whole number, reaches the breakdown threshold, which is context.breakdownAt, or context.criticalAt while that is unset, and never leaves them off. With no percentage to draw the row draws nothing, and when the client does not report the last request's tokens there is no breakdown to add."
443
+ )
434
444
  },
435
445
  customLine: {
436
446
  text: overrideText.describe(`A line of your own text to draw, in colours.custom; empty draws nothing. It is refused when longer than ${String(MAX_DISPLAY_TEXT_CHARS)} characters or when it holds control, format or separator characters, and words are separated by single spaces. A character that passes but draws nothing, such as a braille blank, is removed, and the line is cut to the usable width.`),
@@ -442,17 +452,17 @@ var init_statusline = __esm({
442
452
  )
443
453
  },
444
454
  bands: {
445
- warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow when bar.gradient is off; it must be below criticalAt. A bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn."),
446
- criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red when bar.gradient is off. A bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn.")
455
+ warnAt: wholePercent.describe("The whole percentage of use at which a bar other than the context bar turns yellow when bar.gradient is off (the context bar has context.warnAt); it must be below criticalAt. A bar.gradient of use holds the warning colour exactly there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn. The context row's cache hit share is coloured by these bands too."),
456
+ criticalAt: wholePercent.describe("The whole percentage of use at which a bar other than the context bar turns red when bar.gradient is off (the context bar has context.criticalAt). A bar.gradient of use holds the critical colour from there, and width colours a bar by its cells, not its use, once a cell of its used part is drawn; both fall back to the band colours when a stop's colour is default or dim, and width also when no cell of its used part is drawn. The context row's cache hit share is coloured by these bands too.")
447
457
  },
448
458
  labels: {
449
- fiveHour: windowLabel.describe("The name of the five-hour subscription window; empty uses the language's own name for it."),
450
- sevenDay: windowLabel.describe("The name of the weekly subscription window; empty uses the language's own name for it.")
459
+ fiveHour: windowLabel.describe("The name of the five-hour window; empty uses the language's own name for it."),
460
+ sevenDay: windowLabel.describe("The name of the weekly window; empty uses the language's own name for it.")
451
461
  },
452
462
  bar: {
453
463
  width: z2.number().int().min(1).max(MAX_BAR_CELLS).describe("A bar's width in cells before the line's spare width is shared out among the bars."),
454
464
  gradient: z2.enum(STATUSLINE_BAR_GRADIENTS).describe(
455
- "How a bar's used part is coloured: off (the default) draws the band's single colour, the bar's own colour below the warning threshold, the warning colour from there and the critical one from the critical threshold; use blends the bar's colour with its use, from its own colour at none in use to the warning colour at the warning threshold and the critical one at the critical threshold, holding exactly the colour the bands draw at each threshold and the critical colour above it; and width colours each cell of the used part across the bar's width, from the bar's own colour at the first cell to the critical one at the last, whatever the use, with a bar one cell wide drawing that cell in its own colour. A bar's thresholds are bands.warnAt and bands.criticalAt, the context bar's own where it sets them, and the figures beside a bar keep the band's colours in every mode. The unused part keeps colours.empty in every mode, and when that is default or dim, which set no colour of their own, it draws in the colour the used part ends in: under off the band's colour, under use the blend for the bar's use (even where no cell of the used part is drawn), and under width the last drawn cell's colour (the band's colour where no cell is drawn). A gradient blends RGB values, so a colour name, or a palette index below 16, is blended at the default RGB the xterm scheme gives it rather than the shade a themed terminal draws it in, while a stop itself, where a mode holds it exactly, is drawn as the bands draw that role. A bar whose stops include a role set to default or dim, which names no colour of its own, is drawn in the band's single colour: for use those stops are the bar's own, warning and critical roles, and for width its own and critical roles. A width bar with no cell of its used part drawn has no cell to colour, so it takes the band's colours as off does."
465
+ "How a bar's used part is coloured: off (the default) draws the band's single colour, the bar's own colour below the warning threshold, the warning colour from there and the critical one from the critical threshold; use blends the bar's colour with its use, from its own colour at none in use to the warning colour at the warning threshold and the critical one at the critical threshold, holding exactly the colour the bar draws without a gradient at each threshold (the context bar's sit half a point below its whole percentages) and the critical colour above it; and width colours each cell of the used part across the bar's width, from the bar's own colour at the first cell to the critical one at the last, whatever the use, with a bar one cell wide drawing that cell in its own colour. A bar's thresholds are bands.warnAt and bands.criticalAt, and the context bar's are context.warnAt and context.criticalAt, and the figures beside a bar keep the band's colours in every mode. The unused part keeps colours.empty in every mode, and when that is default or dim, which set no colour of their own, it draws in the colour the used part ends in: under off the band's colour, under use the blend for the bar's use (even where no cell of the used part is drawn), and under width the last drawn cell's colour (the band's colour where no cell is drawn). A gradient blends RGB values, so a colour name, or a palette index below 16, is blended at the default RGB the xterm scheme gives it rather than the shade a themed terminal draws it in, while a stop itself, where a mode holds it exactly, is drawn as the bands draw that role. A bar whose stops include a role set to default or dim, which names no colour of its own, is drawn in the band's single colour: for use those stops are the bar's own, warning and critical roles, and for width its own and critical roles. A width bar with no cell of its used part drawn has no cell to colour, so it takes the band's colours as off does."
456
466
  ),
457
467
  filled: barCharacter.describe("The character that draws the used part of a bar."),
458
468
  empty: barCharacter.describe("The character that draws the unused part of a bar.")
@@ -462,10 +472,10 @@ var init_statusline = __esm({
462
472
  bar: z2.boolean().describe("Whether each quota window is drawn as a bar, or as text alone."),
463
473
  compact: z2.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."),
464
474
  resetLabel: z2.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)`."),
465
- modelScoped: z2.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."),
475
+ modelScoped: z2.boolean().describe("Whether the per-model weekly windows the client reports (rate_limits.model_scoped) are drawn after the five-hour and weekly windows (one reported with a null, missing or non-numeric figure is drawn as two hyphens beside its reset); they describe the signed-in account, so a session that selected a provider never shows them, nor does a Bedrock session, whose subscription windows do not apply."),
466
476
  timeFormat: z2.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."),
467
- 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."),
468
- 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.")
477
+ 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, the use compared after rounding to a whole percentage, as claude-hud compares it; 0 never hides it. A Bedrock session that selected no provider draws no five-hour, weekly or per-model window, whatever this is."),
478
+ sevenDayThreshold: thresholdPercent.describe("The whole percentage of use at which the weekly window is drawn beside the five-hour one, the use compared after rounding to a whole percentage, as claude-hud compares it; below it the weekly window is hidden, and 0 never hides it. A weekly window with no five-hour window beside it is never hidden by this setting. A Bedrock session that selected no provider draws no five-hour, weekly or per-model window, so this setting has nothing to hide there, and usage.threshold can still hide the whole row.")
469
479
  },
470
480
  clock: {
471
481
  hourCycle: z2.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)."),
@@ -488,11 +498,11 @@ var init_statusline = __esm({
488
498
  maxVisible: z2.number().int().min(0).describe("The most kinds of finished tool call the tools row names, the most-used first, with the rest counted as +N more. 0 names every kind.")
489
499
  },
490
500
  colours: {
491
- context: colourValue.describe("The colour of the context bar below the warning threshold while bar.gradient is off, of the figures beside it below that threshold in every mode, and the colour a bar.gradient of use or width blends the context bar from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
501
+ context: colourValue.describe("The colour of the context bar below the warning threshold while bar.gradient is off, of the figures beside it below that threshold in every mode, of a cache hit share above 100 less bands.warnAt percent, and the colour a bar.gradient of use or width blends the context bar from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
492
502
  usage: colourValue.describe("The colour of the quota bars and the memory bar below the warning threshold while bar.gradient is off, of the figures beside them below that threshold in every mode, and the colour a bar.gradient of use or width blends those bars from (at none in use for use, at the first cell for width), while a gradient bar with a stop whose colour is default or dim, or a width bar with no cell of its used part drawn, takes the band's colours."),
493
- warning: colourValue.describe("The colour of the context bar from its warning threshold (bands.warnAt, or context.warnAt where that is set) up to its critical threshold (bands.criticalAt, or context.criticalAt where that is set) when bar.gradient is off (a bar.gradient of use holds it exactly at the threshold, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), of the figures beside the bar from that threshold up to its critical threshold in every mode, and of a cache hit share that is middling."),
503
+ warning: colourValue.describe("The colour of the context bar from context.warnAt up to context.criticalAt when bar.gradient is off (a bar.gradient of use holds it exactly where the bar turns yellow, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), of the figures beside the bar from that threshold up to context.criticalAt in every mode, and of a cache hit share above 100 less bands.criticalAt percent and at most 100 less bands.warnAt percent."),
494
504
  usageWarning: colourValue.describe("The colour of a quota bar or the memory bar from bands.warnAt up to bands.criticalAt when bar.gradient is off (a bar.gradient of use holds it exactly at bands.warnAt, and a gradient bar with a stop whose colour is default or dim draws the band's colours instead, and so does a width bar with no cell of its used part drawn), and of the figures beside the bar from that threshold up to bands.criticalAt in every mode."),
495
- critical: colourValue.describe("The colour of a bar at or above its critical threshold (bands.criticalAt, or context.criticalAt for the context bar where that is set) when bar.gradient is off or use, of the last cell of a full bar more than one cell wide under a bar.gradient of width (a bar one cell wide draws its cell in its own colour, and a width bar whose own colour or this one is default or dim, or that has no cell of its used part drawn, draws the band's colours instead), of the figures beside a bar from its critical threshold in every mode, and of a cache hit share that is nearly nothing."),
505
+ critical: colourValue.describe("The colour of a bar at or above its critical threshold (context.criticalAt for the context bar, bands.criticalAt for any other bar) when bar.gradient is off or use, of the last cell of a full bar more than one cell wide under a bar.gradient of width (a bar one cell wide draws its cell in its own colour, and a width bar whose own colour or this one is default or dim, or that has no cell of its used part drawn, draws the band's colours instead), of the figures beside a bar from its critical threshold in every mode, and of a cache hit share of at most 100 less bands.criticalAt percent."),
496
506
  model: colourValue.describe("The colour of the model and provider segments."),
497
507
  label: colourValue.describe("The colour of labels and secondary text: row labels, and the route, account, identity and headroom segments."),
498
508
  empty: colourValue.describe("The colour of the unused part of a bar."),
@@ -523,12 +533,13 @@ var init_statusline = __esm({
523
533
  }
524
534
  };
525
535
  UNSET_NOTE = "A layer may write null to return it to unset when a shallower layer sets it.";
536
+ RESET_NOTE = "A layer may write null to return it to its default when a shallower layer sets it.";
526
537
  LANGUAGE_DESCRIPTION = "The language of the words the statusline writes (labels, units of waiting such as `ago`, the names of effort levels): en, zh-Hans for Chinese in simplified characters, and zh-Hant for traditional; zh and zh-TW are read as zh-Hans and zh-Hant, and any other tag is refused. Durations, token counts, the dollar sign and clock times are written the same in every language, and a clock time follows the system locale and the clock settings.";
527
538
  LANGUAGE_TAGS = [...STATUSLINE_LANGUAGES, "zh", "zh-TW"];
528
539
  LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
529
540
  TOP_LEVEL = {
530
541
  language: z2.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
531
- preset: z2.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments, the extra segment once extra.command is set, and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
542
+ preset: z2.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own default, everything claude-hud's default configuration draws plus agent-shim's own segments; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments, the extra segment once extra.command is set, and the context row; standard adds the provider, route, account, identity and headroom segments and the quota and added directories rows, with the reset label and the token breakdown from its threshold, full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown from its threshold, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
532
543
  };
533
544
  StatuslineSchema = z2.strictObject({
534
545
  language: z2.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
@@ -539,7 +550,7 @@ var init_statusline = __esm({
539
550
  account: z2.strictObject(SHAPES.account).partial().optional(),
540
551
  effort: z2.strictObject(SHAPES.effort).partial().optional(),
541
552
  advisor: z2.strictObject(SHAPES.advisor).partial().optional(),
542
- context: z2.strictObject({ ...SHAPES.context, warnAt: unsettable(SHAPES.context.warnAt), criticalAt: unsettable(SHAPES.context.criticalAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
553
+ context: z2.strictObject({ ...SHAPES.context, warnAt: resettable(SHAPES.context.warnAt), criticalAt: resettable(SHAPES.context.criticalAt), breakdownAt: unsettable(SHAPES.context.breakdownAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
543
554
  customLine: z2.strictObject(SHAPES.customLine).partial().optional(),
544
555
  extra: z2.strictObject(SHAPES.extra).partial().optional(),
545
556
  bands: z2.strictObject(SHAPES.bands).partial().optional(),
@@ -588,18 +599,18 @@ var init_statusline = __esm({
588
599
  language: "en",
589
600
  preset: "standard",
590
601
  layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS], mode: "expanded", rule: "none", mergeBars: true, merge: [], rightAlign: [], maxWidth: 0, forceMaxWidth: false },
591
- model: { format: "full", override: "", source: "client" },
602
+ model: { format: "full", override: "", source: "client", platform: CLAUDE_HUD_DEFAULTS.model.platform },
592
603
  provider: { name: "" },
593
604
  account: { parts: ["user", "organisation", "plan"], userLength: 0 },
594
605
  effort: { format: "full" },
595
606
  advisor: { override: "" },
596
- context: { bar: "shown", value: "both", estimate: "never", breakdown: "never" },
607
+ context: { bar: "shown", value: "both", warnAt: CLAUDE_HUD_DEFAULTS.context.warnAt, criticalAt: CLAUDE_HUD_DEFAULTS.context.criticalAt, estimate: CLAUDE_HUD_DEFAULTS.context.estimate, breakdown: CLAUDE_HUD_DEFAULTS.context.breakdown },
597
608
  customLine: { text: "", position: "last" },
598
609
  extra: { command: [] },
599
610
  bands: { warnAt: 70, criticalAt: 90 },
600
611
  labels: { fiveHour: "", sevenDay: "" },
601
612
  bar: { width: 10, gradient: "off", filled: "\u2588", empty: "\u2591" },
602
- usage: { value: "used", bar: true, compact: false, resetLabel: false, modelScoped: false, timeFormat: "relative", threshold: 0, sevenDayThreshold: 0 },
613
+ usage: { value: "used", bar: true, compact: false, resetLabel: CLAUDE_HUD_DEFAULTS.usage.resetLabel, modelScoped: CLAUDE_HUD_DEFAULTS.usage.modelScoped, timeFormat: "relative", threshold: 0, sevenDayThreshold: CLAUDE_HUD_DEFAULTS.usage.sevenDayThreshold },
603
614
  clock: { hourCycle: "auto", seconds: false },
604
615
  cost: { routed: false },
605
616
  environment: { threshold: 0 },
@@ -4727,7 +4738,7 @@ var init_package = __esm({
4727
4738
  "package.json"() {
4728
4739
  package_default = {
4729
4740
  name: "claude-use",
4730
- version: "11.66.2",
4741
+ version: "11.67.0",
4731
4742
  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.",
4732
4743
  license: "MIT",
4733
4744
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4786,7 +4797,7 @@ var init_package = __esm({
4786
4797
  cosmiconfig: "^10.0.1",
4787
4798
  picomatch: "^4.0.7",
4788
4799
  "string-width": "8.3.0",
4789
- trilean: "1.7.1",
4800
+ trilean: "1.9.0",
4790
4801
  undici: "7.30.1",
4791
4802
  zod: "^4.6.7"
4792
4803
  },
@@ -7949,10 +7960,14 @@ function valueAt(source, path42) {
7949
7960
  }
7950
7961
  return current;
7951
7962
  }
7963
+ function acceptsNull(path42) {
7964
+ const layer = path42.reduceRight((inner, part) => ({ [part]: inner }), null);
7965
+ return StatuslineSchema.safeParse(layer).success;
7966
+ }
7952
7967
  function keyOf(path42, declared) {
7953
7968
  const optional = declared instanceof z16.ZodOptional;
7954
7969
  const leaf = optional ? declared.unwrap() : declared;
7955
- const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional };
7970
+ const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional, unsettable: acceptsNull(path42) };
7956
7971
  if (leaf instanceof z16.ZodNumber) {
7957
7972
  return { ...common, kind: "integer", choices: [] };
7958
7973
  }