claude-use 11.66.3 → 11.67.1

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/cli.cjs CHANGED
@@ -25495,6 +25495,9 @@ function isSingleVisibleGrapheme(text5) {
25495
25495
  function unsettable(setting) {
25496
25496
  return setting.unwrap().nullable().optional().describe(`${setting.description ?? ""} ${UNSET_NOTE}`);
25497
25497
  }
25498
+ function resettable(setting) {
25499
+ return setting.nullable().optional().describe(`${setting.description ?? ""} ${RESET_NOTE}`);
25500
+ }
25498
25501
  function canonicalLanguage(tag) {
25499
25502
  return tag === "zh" || tag === "zh-TW" ? LANGUAGE_ALIASES[tag] : tag;
25500
25503
  }
@@ -25515,8 +25518,8 @@ function mergeKeys(base, over) {
25515
25518
  }
25516
25519
  return merged;
25517
25520
  }
25518
- function contextBands({ bands, context }) {
25519
- return { warnAt: context.warnAt ?? bands.warnAt, criticalAt: context.criticalAt ?? bands.criticalAt };
25521
+ function contextBreakdownAt({ context }) {
25522
+ return context.breakdownAt ?? context.criticalAt;
25520
25523
  }
25521
25524
  function isPresetName(value2) {
25522
25525
  return STATUSLINE_PRESETS.some((name) => name === value2);
@@ -25526,13 +25529,12 @@ function mergeStatuslineSettings(base, over) {
25526
25529
  return mergeKeys(isPresetName(preset) ? mergeKeys(base, PRESET_BUNDLES[preset]) : base, over);
25527
25530
  }
25528
25531
  function resolveStatusline(settings2) {
25529
- const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, settings2));
25532
+ const resolved = ResolvedStatuslineSchema.parse(mergeStatuslineSettings(STATUSLINE_DEFAULTS, mergeKeys(void 0, settings2)));
25530
25533
  if (resolved.bands.warnAt >= resolved.bands.criticalAt) {
25531
25534
  throw new RangeError(`statusline bands.warnAt (${String(resolved.bands.warnAt)}) must be below bands.criticalAt (${String(resolved.bands.criticalAt)})`);
25532
25535
  }
25533
- const forContext = contextBands(resolved);
25534
- if (forContext.warnAt >= forContext.criticalAt) {
25535
- throw new RangeError(`statusline context.warnAt (${String(forContext.warnAt)}) must be below context.criticalAt (${String(forContext.criticalAt)}), each following bands while it is unset`);
25536
+ if (resolved.context.warnAt >= resolved.context.criticalAt) {
25537
+ throw new RangeError(`statusline context.warnAt (${String(resolved.context.warnAt)}) must be below context.criticalAt (${String(resolved.context.criticalAt)}); set both when moving one`);
25536
25538
  }
25537
25539
  const merged = new Set(resolved.layout.merge.flat());
25538
25540
  const unmerged = resolved.layout.rightAlign.filter((row) => !merged.has(row));
@@ -25544,7 +25546,7 @@ function resolveStatusline(settings2) {
25544
25546
  }
25545
25547
  return resolved;
25546
25548
  }
25547
- 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;
25549
+ 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;
25548
25550
  var init_statusline = __esm({
25549
25551
  "src/config/statusline.ts"() {
25550
25552
  "use strict";
@@ -25578,13 +25580,18 @@ var init_statusline = __esm({
25578
25580
  "brightCyan",
25579
25581
  "brightWhite"
25580
25582
  ];
25581
- DEFAULT_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom"];
25582
- DEFAULT_ROWS = ["context", "quota"];
25583
+ DEFAULT_HEADER_SEGMENTS = ["model", "project", "vcs", "provider", "route", "account", "identity", "headroom", "extra"];
25584
+ DEFAULT_ROWS = ["context", "quota", "addedDirs"];
25585
+ CLAUDE_HUD_DEFAULTS = {
25586
+ model: { platform: true },
25587
+ usage: { resetLabel: true, modelScoped: true, sevenDayThreshold: 80 },
25588
+ context: { estimate: "buffered", breakdown: "critical", warnAt: 70, criticalAt: 85 }
25589
+ };
25583
25590
  STATUSLINE_PRESETS = ["standard", "full", "essential", "minimal"];
25584
25591
  GIT_WITH_DIRTY_MARKER = { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false };
25585
25592
  JJ_OFF = { enabled: false, showDirty: true, showConflicts: true };
25586
25593
  PRESET_BUNDLES = {
25587
- standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
25594
+ 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 } },
25588
25595
  full: {
25589
25596
  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"] },
25590
25597
  git: GIT_WITH_DIRTY_MARKER,
@@ -25641,7 +25648,7 @@ var init_statusline = __esm({
25641
25648
  rows: distinctList(external_exports.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."),
25642
25649
  mode: external_exports.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."),
25643
25650
  rule: external_exports.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.`),
25644
- mergeBars: external_exports.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."),
25651
+ mergeBars: external_exports.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."),
25645
25652
  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."),
25646
25653
  rightAlign: distinctList(external_exports.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."),
25647
25654
  maxWidth: external_exports.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.`),
@@ -25650,7 +25657,8 @@ var init_statusline = __esm({
25650
25657
  model: {
25651
25658
  format: external_exports.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."),
25652
25659
  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."),
25653
- source: external_exports.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.")
25660
+ source: external_exports.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."),
25661
+ platform: external_exports.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.")
25654
25662
  },
25655
25663
  provider: {
25656
25664
  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.")
@@ -25668,11 +25676,16 @@ var init_statusline = __esm({
25668
25676
  context: {
25669
25677
  bar: external_exports.enum(["shown", "hidden"]).describe("Whether the context row draws its bar, or only its figures on one line of text."),
25670
25678
  value: external_exports.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)."),
25671
- 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."),
25672
- 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."),
25679
+ 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."),
25680
+ 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."),
25681
+ breakdownAt: wholePercent.optional().describe(
25682
+ "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."
25683
+ ),
25673
25684
  autoCompactWindow: external_exports.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."),
25674
- estimate: external_exports.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)}%).`),
25675
- breakdown: external_exports.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.")
25685
+ estimate: external_exports.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)}%).`),
25686
+ breakdown: external_exports.enum(["never", "critical"]).describe(
25687
+ "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."
25688
+ )
25676
25689
  },
25677
25690
  customLine: {
25678
25691
  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.`),
@@ -25684,17 +25697,17 @@ var init_statusline = __esm({
25684
25697
  )
25685
25698
  },
25686
25699
  bands: {
25687
- 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."),
25688
- 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.")
25700
+ 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."),
25701
+ 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.")
25689
25702
  },
25690
25703
  labels: {
25691
- fiveHour: windowLabel.describe("The name of the five-hour subscription window; empty uses the language's own name for it."),
25692
- sevenDay: windowLabel.describe("The name of the weekly subscription window; empty uses the language's own name for it.")
25704
+ fiveHour: windowLabel.describe("The name of the five-hour window; empty uses the language's own name for it."),
25705
+ sevenDay: windowLabel.describe("The name of the weekly window; empty uses the language's own name for it.")
25693
25706
  },
25694
25707
  bar: {
25695
25708
  width: external_exports.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."),
25696
25709
  gradient: external_exports.enum(STATUSLINE_BAR_GRADIENTS).describe(
25697
- "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."
25710
+ "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."
25698
25711
  ),
25699
25712
  filled: barCharacter.describe("The character that draws the used part of a bar."),
25700
25713
  empty: barCharacter.describe("The character that draws the unused part of a bar.")
@@ -25704,10 +25717,10 @@ var init_statusline = __esm({
25704
25717
  bar: external_exports.boolean().describe("Whether each quota window is drawn as a bar, or as text alone."),
25705
25718
  compact: external_exports.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."),
25706
25719
  resetLabel: external_exports.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)`."),
25707
- modelScoped: external_exports.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."),
25720
+ modelScoped: external_exports.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."),
25708
25721
  timeFormat: external_exports.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."),
25709
- 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."),
25710
- 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.")
25722
+ 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."),
25723
+ 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.")
25711
25724
  },
25712
25725
  clock: {
25713
25726
  hourCycle: external_exports.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)."),
@@ -25730,11 +25743,11 @@ var init_statusline = __esm({
25730
25743
  maxVisible: external_exports.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.")
25731
25744
  },
25732
25745
  colours: {
25733
- 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."),
25746
+ 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."),
25734
25747
  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."),
25735
- 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."),
25748
+ 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."),
25736
25749
  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."),
25737
- 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."),
25750
+ 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."),
25738
25751
  model: colourValue.describe("The colour of the model and provider segments."),
25739
25752
  label: colourValue.describe("The colour of labels and secondary text: row labels, and the route, account, identity and headroom segments."),
25740
25753
  empty: colourValue.describe("The colour of the unused part of a bar."),
@@ -25765,12 +25778,13 @@ var init_statusline = __esm({
25765
25778
  }
25766
25779
  };
25767
25780
  UNSET_NOTE = "A layer may write null to return it to unset when a shallower layer sets it.";
25781
+ RESET_NOTE = "A layer may write null to return it to its default when a shallower layer sets it.";
25768
25782
  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.";
25769
25783
  LANGUAGE_TAGS = [...STATUSLINE_LANGUAGES, "zh", "zh-TW"];
25770
25784
  LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
25771
25785
  TOP_LEVEL = {
25772
25786
  language: external_exports.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
25773
- preset: external_exports.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.")
25787
+ preset: external_exports.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.")
25774
25788
  };
25775
25789
  StatuslineSchema = external_exports.strictObject({
25776
25790
  language: external_exports.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
@@ -25781,7 +25795,7 @@ var init_statusline = __esm({
25781
25795
  account: external_exports.strictObject(SHAPES.account).partial().optional(),
25782
25796
  effort: external_exports.strictObject(SHAPES.effort).partial().optional(),
25783
25797
  advisor: external_exports.strictObject(SHAPES.advisor).partial().optional(),
25784
- context: external_exports.strictObject({ ...SHAPES.context, warnAt: unsettable(SHAPES.context.warnAt), criticalAt: unsettable(SHAPES.context.criticalAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
25798
+ context: external_exports.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(),
25785
25799
  customLine: external_exports.strictObject(SHAPES.customLine).partial().optional(),
25786
25800
  extra: external_exports.strictObject(SHAPES.extra).partial().optional(),
25787
25801
  bands: external_exports.strictObject(SHAPES.bands).partial().optional(),
@@ -25830,18 +25844,18 @@ var init_statusline = __esm({
25830
25844
  language: "en",
25831
25845
  preset: "standard",
25832
25846
  layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS], mode: "expanded", rule: "none", mergeBars: true, merge: [], rightAlign: [], maxWidth: 0, forceMaxWidth: false },
25833
- model: { format: "full", override: "", source: "client" },
25847
+ model: { format: "full", override: "", source: "client", platform: CLAUDE_HUD_DEFAULTS.model.platform },
25834
25848
  provider: { name: "" },
25835
25849
  account: { parts: ["user", "organisation", "plan"], userLength: 0 },
25836
25850
  effort: { format: "full" },
25837
25851
  advisor: { override: "" },
25838
- context: { bar: "shown", value: "both", estimate: "never", breakdown: "never" },
25852
+ 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 },
25839
25853
  customLine: { text: "", position: "last" },
25840
25854
  extra: { command: [] },
25841
25855
  bands: { warnAt: 70, criticalAt: 90 },
25842
25856
  labels: { fiveHour: "", sevenDay: "" },
25843
25857
  bar: { width: 10, gradient: "off", filled: "\u2588", empty: "\u2591" },
25844
- usage: { value: "used", bar: true, compact: false, resetLabel: false, modelScoped: false, timeFormat: "relative", threshold: 0, sevenDayThreshold: 0 },
25858
+ 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 },
25845
25859
  clock: { hourCycle: "auto", seconds: false },
25846
25860
  cost: { routed: false },
25847
25861
  environment: { threshold: 0 },
@@ -29661,6 +29675,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
29661
29675
  return HEADROOM_SUPERVISOR_STILL_RUNNING;
29662
29676
  }
29663
29677
  ticks += 1;
29678
+ if (ports.rotateDaemonLog({ maxBytes: HEADROOM_LOG_MAX_BYTES, keptGenerations: HEADROOM_LOG_KEPT_GENERATIONS })) {
29679
+ ports.log(`agent-shim headroom supervisor: rotated the daemon log past ${String(HEADROOM_LOG_MAX_BYTES)} bytes, keeping ${String(HEADROOM_LOG_KEPT_GENERATIONS)} earlier file(s)`);
29680
+ }
29664
29681
  config2 = ports.readConfig();
29665
29682
  const settingsHash = hashSettings(config2.settings);
29666
29683
  const inputs = currentHeadroomAllowlistInputs(fs31, paths, ports.frontDoorLiveness);
@@ -29811,7 +29828,7 @@ function lastLines(output2) {
29811
29828
  const lines = redactText(output2).split("\n").map((line) => line.trim()).filter((line) => line !== "").map((line) => line.length > DAEMON_EXIT_LOG_LINE_CHARS ? `${line.slice(0, DAEMON_EXIT_LOG_LINE_CHARS)}...` : line);
29812
29829
  return lines.length === 0 ? "(the daemon wrote nothing)" : lines.slice(-DAEMON_EXIT_LOG_LINES).join(" | ");
29813
29830
  }
29814
- var import_node_path9, HEADROOM_BACKOFF_BASE_MS, HEADROOM_BACKOFF_CAP_MS, HEADROOM_START_RETRY_BUDGET, HEADROOM_READY_TIMEOUT_MS, DAEMON_EXIT_LOG_LINES, DAEMON_EXIT_LOG_LINE_CHARS, DAEMON_LOG_TAIL_BYTES, HEADROOM_POLL_MS, MS_PER_MINUTE, STOP_POLL_MS, TERM_GRACE_MS, KILL_GRACE_MS, HEADROOM_SUPERVISOR_STILL_RUNNING;
29831
+ var import_node_path9, HEADROOM_BACKOFF_BASE_MS, HEADROOM_BACKOFF_CAP_MS, HEADROOM_START_RETRY_BUDGET, HEADROOM_READY_TIMEOUT_MS, DAEMON_EXIT_LOG_LINES, DAEMON_EXIT_LOG_LINE_CHARS, DAEMON_LOG_TAIL_BYTES, BYTES_PER_KIB, BYTES_PER_MIB, HEADROOM_LOG_MAX_MIB, HEADROOM_LOG_MAX_BYTES, HEADROOM_LOG_KEPT_GENERATIONS, HEADROOM_POLL_MS, MS_PER_MINUTE, STOP_POLL_MS, TERM_GRACE_MS, KILL_GRACE_MS, HEADROOM_SUPERVISOR_STILL_RUNNING;
29815
29832
  var init_supervisor = __esm({
29816
29833
  "src/headroom/supervisor.ts"() {
29817
29834
  "use strict";
@@ -29831,6 +29848,11 @@ var init_supervisor = __esm({
29831
29848
  DAEMON_EXIT_LOG_LINES = 6;
29832
29849
  DAEMON_EXIT_LOG_LINE_CHARS = 400;
29833
29850
  DAEMON_LOG_TAIL_BYTES = 8192;
29851
+ BYTES_PER_KIB = 1024;
29852
+ BYTES_PER_MIB = BYTES_PER_KIB * BYTES_PER_KIB;
29853
+ HEADROOM_LOG_MAX_MIB = 64;
29854
+ HEADROOM_LOG_MAX_BYTES = HEADROOM_LOG_MAX_MIB * BYTES_PER_MIB;
29855
+ HEADROOM_LOG_KEPT_GENERATIONS = 2;
29834
29856
  HEADROOM_POLL_MS = 1e3;
29835
29857
  MS_PER_MINUTE = 6e4;
29836
29858
  STOP_POLL_MS = 100;
@@ -32914,10 +32936,14 @@ function valueAt(source, path72) {
32914
32936
  }
32915
32937
  return current;
32916
32938
  }
32939
+ function acceptsNull(path72) {
32940
+ const layer = path72.reduceRight((inner, part) => ({ [part]: inner }), null);
32941
+ return StatuslineSchema.safeParse(layer).success;
32942
+ }
32917
32943
  function keyOf(path72, declared) {
32918
32944
  const optional2 = declared instanceof external_exports.ZodOptional;
32919
32945
  const leaf = optional2 ? declared.unwrap() : declared;
32920
- const common = { path: path72.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path72), optional: optional2 };
32946
+ const common = { path: path72.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path72), optional: optional2, unsettable: acceptsNull(path72) };
32921
32947
  if (leaf instanceof external_exports.ZodNumber) {
32922
32948
  return { ...common, kind: "integer", choices: [] };
32923
32949
  }
@@ -32950,10 +32976,17 @@ function walk(shape, prefix) {
32950
32976
  function statuslineKeys() {
32951
32977
  return walk(ResolvedStatuslineSchema.shape, []);
32952
32978
  }
32979
+ function defaultText(key) {
32980
+ if (key.optional) {
32981
+ return "no default; none unsets it over shallower layers";
32982
+ }
32983
+ const value2 = `default ${JSON.stringify(key.defaultValue)}`;
32984
+ return key.unsettable ? `${value2}; none returns it to the default over shallower layers` : value2;
32985
+ }
32953
32986
  function formatStatuslineKeys(keys) {
32954
32987
  return keys.map((key) => {
32955
32988
  const takes = key.kind === "choice" || key.kind === "list" || key.kind === "groups" || key.kind === "colour" ? `${key.kind} of ${key.choices.join(", ")}` : key.kind;
32956
- return `${key.path} (${takes}; ${key.optional ? "no default; none unsets it over shallower layers" : `default ${JSON.stringify(key.defaultValue)}`})
32989
+ return `${key.path} (${takes}; ${defaultText(key)})
32957
32990
  ${key.description}`;
32958
32991
  }).join("\n");
32959
32992
  }
@@ -32996,7 +33029,7 @@ function parseStatuslineAssignment(text5) {
32996
33029
  const path72 = text5.slice(0, split);
32997
33030
  const raw = text5.slice(split + 1);
32998
33031
  const key = keyNamed(path72);
32999
- if (key.optional && raw === UNSET_WORD) {
33032
+ if (key.unsettable && raw === UNSET_WORD) {
33000
33033
  return { path: path72, value: null };
33001
33034
  }
33002
33035
  switch (key.kind) {
@@ -37354,7 +37387,7 @@ var init_package = __esm({
37354
37387
  "package.json"() {
37355
37388
  package_default = {
37356
37389
  name: "claude-use",
37357
- version: "11.66.3",
37390
+ version: "11.67.1",
37358
37391
  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.",
37359
37392
  license: "MIT",
37360
37393
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -134038,9 +134071,9 @@ async function headroomReady(deps, signal) {
134038
134071
  }
134039
134072
  var HOP_RESET_RETRIES = 1;
134040
134073
  var HOP_RESET_CODES = /* @__PURE__ */ new Set(["ECONNRESET", "EPIPE"]);
134041
- var BYTES_PER_MIB = 1048576;
134074
+ var BYTES_PER_MIB2 = 1048576;
134042
134075
  var MESSAGES_API_LIMIT_MIB = 32;
134043
- var MAX_BODY_BYTES = MESSAGES_API_LIMIT_MIB * BYTES_PER_MIB;
134076
+ var MAX_BODY_BYTES = MESSAGES_API_LIMIT_MIB * BYTES_PER_MIB2;
134044
134077
  async function collectBody(body) {
134045
134078
  return await new Promise((resolve3) => {
134046
134079
  const chunks = [];
@@ -135729,9 +135762,9 @@ var import_node_stream3 = require("node:stream");
135729
135762
 
135730
135763
  // src/frontdoor/requestScan.ts
135731
135764
  var import_node_stream2 = require("node:stream");
135732
- var BYTES_PER_KIB = 1024;
135765
+ var BYTES_PER_KIB2 = 1024;
135733
135766
  var SCAN_KIB = 64;
135734
- var REQUEST_SCAN_CAP_BYTES = SCAN_KIB * BYTES_PER_KIB;
135767
+ var REQUEST_SCAN_CAP_BYTES = SCAN_KIB * BYTES_PER_KIB2;
135735
135768
  async function scanRequestHead(request7, wholeBody = false) {
135736
135769
  const body = request7.body;
135737
135770
  const head = [];
@@ -140435,6 +140468,45 @@ init_modelsStore();
140435
140468
  // src/statusline/doorCost.ts
140436
140469
  init_read();
140437
140470
 
140471
+ // src/statusline/platform.ts
140472
+ var SWITCH_ON = "1";
140473
+ var MINIMAX_ENDPOINTS = /* @__PURE__ */ new Set(["https://api.minimax.io/anthropic", "https://api.minimaxi.com/anthropic"]);
140474
+ var ENTERPRISE_MODEL_IDS = /* @__PURE__ */ new Set(["opusplan", "sonnetplan", "haikuplan"]);
140475
+ function isMiniMaxEndpoint(env) {
140476
+ const base = [env.ANTHROPIC_BASE_URL, env.ANTHROPIC_API_BASE_URL].map((value2) => value2?.trim() ?? "").find((value2) => value2 !== "");
140477
+ if (base === void 0 || !URL.canParse(base)) {
140478
+ return false;
140479
+ }
140480
+ const url2 = new URL(base);
140481
+ return MINIMAX_ENDPOINTS.has(`${url2.origin}${url2.pathname.replace(/\/+$/, "")}`);
140482
+ }
140483
+ function modelPlatformOf(env, modelId) {
140484
+ if (env.CLAUDE_CODE_USE_BEDROCK === SWITCH_ON) {
140485
+ return "Bedrock";
140486
+ }
140487
+ if (env.CLAUDE_CODE_USE_VERTEX === SWITCH_ON) {
140488
+ return "Vertex";
140489
+ }
140490
+ if (isMiniMaxEndpoint(env)) {
140491
+ return "MiniMax";
140492
+ }
140493
+ if (modelId !== void 0 && ENTERPRISE_MODEL_IDS.has(modelId.toLowerCase())) {
140494
+ return "Enterprise";
140495
+ }
140496
+ return void 0;
140497
+ }
140498
+ var BEDROCK_MODEL_ID_MARK = "anthropic.claude-";
140499
+ function isBedrockModelId(modelId) {
140500
+ return modelId?.toLowerCase().includes(BEDROCK_MODEL_ID_MARK) === true;
140501
+ }
140502
+ function hidesSubscriptionWindows(env, modelId) {
140503
+ return modelPlatformOf(env, modelId) === "Bedrock" || isBedrockModelId(modelId);
140504
+ }
140505
+ var NONE2 = { env: {}, modelId: void 0 };
140506
+ function platformInputsOf(payload, env, modelId) {
140507
+ return isAntigravityPayload(payload) ? NONE2 : { env, modelId };
140508
+ }
140509
+
140438
140510
  // src/statusline/cost.ts
140439
140511
  var TOKENS_PER_MILLION = 1e6;
140440
140512
  var CACHE_WRITE_PRICE_RATIO = 1.25;
@@ -140458,7 +140530,7 @@ function doorCostUsdOf(records, prices) {
140458
140530
  return costed === 0 ? void 0 : totalUsd;
140459
140531
  }
140460
140532
  function isCloudModelId(modelId) {
140461
- return modelId !== void 0 && (modelId.toLowerCase().includes("anthropic.claude-") || modelId.includes("@"));
140533
+ return modelId !== void 0 && (isBedrockModelId(modelId) || modelId.includes("@"));
140462
140534
  }
140463
140535
  function isRoutedSession(summary, payload) {
140464
140536
  return summary.provider !== void 0 || isCloudModelId(payload.model?.id);
@@ -140504,6 +140576,291 @@ function readDoorCostUsd(params) {
140504
140576
 
140505
140577
  // src/statusline/payload.ts
140506
140578
  init_zod();
140579
+
140580
+ // src/statusline/colour.ts
140581
+ init_statusline();
140582
+ var FULL_CHANNEL = 255;
140583
+ var NORMAL_PRIMARY = 205;
140584
+ var SCHEME_WHITE = 229;
140585
+ var SCHEME_BLUE = 238;
140586
+ var BRIGHT_BLACK_GREY = 127;
140587
+ var BRIGHT_BLUE_TINT = 92;
140588
+ var NAMED_DEFAULT_RGB = {
140589
+ black: [0, 0, 0],
140590
+ red: [NORMAL_PRIMARY, 0, 0],
140591
+ green: [0, NORMAL_PRIMARY, 0],
140592
+ yellow: [NORMAL_PRIMARY, NORMAL_PRIMARY, 0],
140593
+ blue: [0, 0, SCHEME_BLUE],
140594
+ magenta: [NORMAL_PRIMARY, 0, NORMAL_PRIMARY],
140595
+ cyan: [0, NORMAL_PRIMARY, NORMAL_PRIMARY],
140596
+ white: [SCHEME_WHITE, SCHEME_WHITE, SCHEME_WHITE],
140597
+ brightBlack: [BRIGHT_BLACK_GREY, BRIGHT_BLACK_GREY, BRIGHT_BLACK_GREY],
140598
+ brightRed: [FULL_CHANNEL, 0, 0],
140599
+ brightGreen: [0, FULL_CHANNEL, 0],
140600
+ brightYellow: [FULL_CHANNEL, FULL_CHANNEL, 0],
140601
+ brightBlue: [BRIGHT_BLUE_TINT, BRIGHT_BLUE_TINT, FULL_CHANNEL],
140602
+ brightMagenta: [FULL_CHANNEL, 0, FULL_CHANNEL],
140603
+ brightCyan: [0, FULL_CHANNEL, FULL_CHANNEL],
140604
+ brightWhite: [FULL_CHANNEL, FULL_CHANNEL, FULL_CHANNEL]
140605
+ };
140606
+ function isNamedColour(value2) {
140607
+ return value2 !== "default" && value2 !== "dim" && STATUSLINE_COLOUR_NAMES.some((name) => name === value2);
140608
+ }
140609
+ var NAMED_RGB_IN_PALETTE_ORDER = STATUSLINE_COLOUR_NAMES.filter(isNamedColour).map((name) => NAMED_DEFAULT_RGB[name]);
140610
+ var CUBE_SIDE = 6;
140611
+ var CUBE_FIRST_INDEX = 16;
140612
+ var GREYSCALE_FIRST_INDEX = CUBE_FIRST_INDEX + CUBE_SIDE * CUBE_SIDE * CUBE_SIDE;
140613
+ var GREYSCALE_START = 8;
140614
+ var GREYSCALE_STEP = 10;
140615
+ var CUBE_CHANNEL_BASE = 55;
140616
+ var CUBE_CHANNEL_STEP = 40;
140617
+ function cubeChannel(level) {
140618
+ return level === 0 ? 0 : CUBE_CHANNEL_BASE + CUBE_CHANNEL_STEP * level;
140619
+ }
140620
+ function paletteIndexRgb(index) {
140621
+ if (index < CUBE_FIRST_INDEX) {
140622
+ return NAMED_RGB_IN_PALETTE_ORDER[index];
140623
+ }
140624
+ if (index < GREYSCALE_FIRST_INDEX) {
140625
+ const cube = index - CUBE_FIRST_INDEX;
140626
+ return [cubeChannel(Math.floor(cube / CUBE_SIDE ** 2)), cubeChannel(Math.floor(cube / CUBE_SIDE) % CUBE_SIDE), cubeChannel(cube % CUBE_SIDE)];
140627
+ }
140628
+ const grey = GREYSCALE_START + GREYSCALE_STEP * (index - GREYSCALE_FIRST_INDEX);
140629
+ return [grey, grey, grey];
140630
+ }
140631
+ var CHANNEL_DIGITS = 2;
140632
+ var HEX_RADIX2 = 16;
140633
+ var HASH_LENGTH = 1;
140634
+ function rgbOfHex(value2) {
140635
+ const channel = (index) => Number.parseInt(value2.slice(HASH_LENGTH + index * CHANNEL_DIGITS, HASH_LENGTH + (index + 1) * CHANNEL_DIGITS), HEX_RADIX2);
140636
+ return [channel(0), channel(1), channel(2)];
140637
+ }
140638
+ function rgbOfSetting(value2) {
140639
+ if (typeof value2 === "number") {
140640
+ return paletteIndexRgb(value2);
140641
+ }
140642
+ if (value2.startsWith("#")) {
140643
+ return rgbOfHex(value2);
140644
+ }
140645
+ return isNamedColour(value2) ? NAMED_DEFAULT_RGB[value2] : void 0;
140646
+ }
140647
+ function blendRgb(from, to2, at2) {
140648
+ const channel = (start, end) => Math.round(start + (end - start) * at2);
140649
+ return [channel(from[0], to2[0]), channel(from[1], to2[1]), channel(from[2], to2[2])];
140650
+ }
140651
+
140652
+ // src/statusline/ansi.ts
140653
+ init_string_width();
140654
+ init_graphemes();
140655
+ var ESCAPE_CHAR_CODE = 27;
140656
+ var ESCAPE = String.fromCharCode(ESCAPE_CHAR_CODE);
140657
+ var BELL = "\\u0007";
140658
+ var ESCAPE_SEQUENCE_PATTERN = [`${ESCAPE}\\[[0-?]*[ -/]*[@-~]`, `${ESCAPE}\\][^${BELL}${ESCAPE}]*(?:${BELL}|${ESCAPE}\\\\)?`, `${ESCAPE}[@-Z\\\\-_]`].join("|");
140659
+ var SPLIT_ON_ESCAPES = new RegExp(`(${ESCAPE_SEQUENCE_PATTERN})`);
140660
+ function visibleLength(text5) {
140661
+ return stringWidth(text5);
140662
+ }
140663
+ function truncateToColumns(text5, columns) {
140664
+ let used = 0;
140665
+ let kept = "";
140666
+ text5.split(SPLIT_ON_ESCAPES).forEach((part, index) => {
140667
+ if (index % 2 === 1) {
140668
+ kept += part;
140669
+ return;
140670
+ }
140671
+ for (const grapheme of graphemesOf(part)) {
140672
+ used += visibleLength(grapheme);
140673
+ if (used > columns) {
140674
+ return;
140675
+ }
140676
+ kept += grapheme;
140677
+ }
140678
+ });
140679
+ return kept;
140680
+ }
140681
+ function truncateWithEllipsis(text5, columns, ellipsis) {
140682
+ if (visibleLength(text5) <= columns) {
140683
+ return text5;
140684
+ }
140685
+ return `${truncateToColumns(text5, Math.max(0, columns - visibleLength(ellipsis)))}${ellipsis}`;
140686
+ }
140687
+
140688
+ // src/statusline/palette.ts
140689
+ init_statusline();
140690
+ var RESET = `${ESCAPE}[0m`;
140691
+ var SGR_BY_NAME = {
140692
+ default: "",
140693
+ dim: "2",
140694
+ black: "30",
140695
+ red: "31",
140696
+ green: "32",
140697
+ yellow: "33",
140698
+ blue: "34",
140699
+ magenta: "35",
140700
+ cyan: "36",
140701
+ white: "37",
140702
+ brightBlack: "90",
140703
+ brightRed: "91",
140704
+ brightGreen: "92",
140705
+ brightYellow: "93",
140706
+ brightBlue: "94",
140707
+ brightMagenta: "95",
140708
+ brightCyan: "96",
140709
+ brightWhite: "97"
140710
+ };
140711
+ function isColourName(value2) {
140712
+ return STATUSLINE_COLOUR_NAMES.some((name) => name === value2);
140713
+ }
140714
+ function rgbSgr(channels) {
140715
+ return `38;2;${channels.join(";")}`;
140716
+ }
140717
+ function sgrOf(value2) {
140718
+ if (typeof value2 === "number") {
140719
+ return `38;5;${String(value2)}`;
140720
+ }
140721
+ if (value2.startsWith("#")) {
140722
+ return rgbSgr(rgbOfHex(value2));
140723
+ }
140724
+ return isColourName(value2) ? SGR_BY_NAME[value2] : "";
140725
+ }
140726
+ function colourEnabled(env) {
140727
+ return env.NO_COLOR === void 0;
140728
+ }
140729
+ function createPalette(colours, enabled) {
140730
+ const ansi = (role) => {
140731
+ const sgr = enabled ? sgrOf(colours[role]) : "";
140732
+ return sgr === "" ? "" : `${ESCAPE}[${sgr}m`;
140733
+ };
140734
+ return {
140735
+ ansi,
140736
+ paint: (role, text5) => {
140737
+ const start = ansi(role);
140738
+ return start === "" ? text5 : `${start}${text5}${RESET}`;
140739
+ },
140740
+ rgb: (channels) => enabled ? `${ESCAPE}[${rgbSgr(channels)}m` : "",
140741
+ rgbOf: (role) => rgbOfSetting(colours[role])
140742
+ };
140743
+ }
140744
+
140745
+ // src/statusline/style.ts
140746
+ var SECONDS_PER_MINUTE2 = 60;
140747
+ var MINUTES_PER_HOUR4 = 60;
140748
+ var SECONDS_PER_DAY = 86400;
140749
+ var THOUSAND = 1e3;
140750
+ var MILLION = 1e6;
140751
+ var TEN = 10;
140752
+ var FULL_PERCENT3 = 100;
140753
+ var ONE_PERCENT = 1;
140754
+ function withColor(color, text5) {
140755
+ return color === "" ? text5 : `${color}${text5}${RESET}`;
140756
+ }
140757
+ function warningRoleOf(style) {
140758
+ return style.okRole === "usage" ? "usageWarning" : "warning";
140759
+ }
140760
+ function statusColor(fraction, isUsedMetric, style) {
140761
+ const yellowAt = style.bands.warnAt / FULL_PERCENT3;
140762
+ const redAt = style.bands.criticalAt / FULL_PERCENT3;
140763
+ const { ansi } = style.palette;
140764
+ if (isUsedMetric) {
140765
+ if (fraction >= redAt) {
140766
+ return ansi("critical");
140767
+ }
140768
+ return fraction >= yellowAt ? ansi(warningRoleOf(style)) : ansi(style.okRole);
140769
+ }
140770
+ if (fraction <= (FULL_PERCENT3 - style.bands.criticalAt) / FULL_PERCENT3) {
140771
+ return ansi("critical");
140772
+ }
140773
+ return fraction <= (FULL_PERCENT3 - style.bands.warnAt) / FULL_PERCENT3 ? ansi(warningRoleOf(style)) : ansi(style.okRole);
140774
+ }
140775
+ function stopOf(role, style) {
140776
+ const rgb = style.palette.rgbOf(role);
140777
+ return rgb === void 0 ? void 0 : { role, rgb };
140778
+ }
140779
+ function colourBetween(from, to2, at2, style) {
140780
+ if (at2 <= 0) {
140781
+ return style.palette.ansi(from.role);
140782
+ }
140783
+ if (at2 >= 1) {
140784
+ return style.palette.ansi(to2.role);
140785
+ }
140786
+ return style.palette.rgb(blendRgb(from.rgb, to2.rgb, at2));
140787
+ }
140788
+ function gradientColorOf(fraction, style) {
140789
+ const ok2 = stopOf(style.okRole, style);
140790
+ const warning = stopOf(warningRoleOf(style), style);
140791
+ const critical = stopOf("critical", style);
140792
+ if (ok2 === void 0 || warning === void 0 || critical === void 0) {
140793
+ return void 0;
140794
+ }
140795
+ const warnAt = style.bands.warnAt / FULL_PERCENT3;
140796
+ const criticalAt = style.bands.criticalAt / FULL_PERCENT3;
140797
+ return fraction < warnAt ? colourBetween(ok2, warning, fraction / warnAt, style) : colourBetween(warning, critical, (fraction - warnAt) / (criticalAt - warnAt), style);
140798
+ }
140799
+ function widthStopsOf(style) {
140800
+ const ok2 = stopOf(style.okRole, style);
140801
+ const critical = stopOf("critical", style);
140802
+ return ok2 === void 0 || critical === void 0 ? void 0 : { ok: ok2, critical };
140803
+ }
140804
+ function acrossBar(column, cells) {
140805
+ return cells <= 1 ? 0 : column / (cells - 1);
140806
+ }
140807
+ function fillOf(fraction, filled, cells, style) {
140808
+ const stops = style.gradient === "width" ? widthStopsOf(style) : void 0;
140809
+ if (stops !== void 0 && filled > 0) {
140810
+ return Array.from({ length: filled }, (_, column) => `${colourBetween(stops.ok, stops.critical, acrossBar(column, cells), style)}${style.filled}`).join("");
140811
+ }
140812
+ const color = style.gradient === "use" ? gradientColorOf(fraction, style) : void 0;
140813
+ return `${color ?? statusColor(style.bandFraction ?? fraction, true, style)}${style.filled.repeat(filled)}`;
140814
+ }
140815
+ function drawBar(fraction, cells, style) {
140816
+ const clamped = Math.max(0, Math.min(1, fraction));
140817
+ const filled = Math.round(clamped * cells);
140818
+ const emptyColor = style.palette.ansi("empty");
140819
+ const fill = fillOf(clamped, filled, cells, style);
140820
+ const empty = style.empty.repeat(cells - filled);
140821
+ return fill === style.filled.repeat(filled) && emptyColor === "" ? `[${fill}${empty}]` : `[${fill}${emptyColor}${empty}${RESET}]`;
140822
+ }
140823
+ function formatTokens(num) {
140824
+ if (num >= MILLION) {
140825
+ const val = num / MILLION;
140826
+ return val % 1 === 0 ? `${String(Math.round(val))}M` : `${val.toFixed(1)}M`;
140827
+ }
140828
+ if (num >= THOUSAND) {
140829
+ const val = num / THOUSAND;
140830
+ return val >= TEN ? `${String(Math.round(val))}k` : `${val.toFixed(1)}k`;
140831
+ }
140832
+ return String(Math.round(num));
140833
+ }
140834
+ function formatDuration(seconds, t10) {
140835
+ if (seconds === void 0 || seconds <= 0) {
140836
+ return t10("quota.available");
140837
+ }
140838
+ if (seconds < SECONDS_PER_MINUTE2) {
140839
+ return `${String(seconds)}s`;
140840
+ }
140841
+ const days = Math.floor(seconds / SECONDS_PER_DAY);
140842
+ const hours = Math.floor(seconds % SECONDS_PER_DAY / (MINUTES_PER_HOUR4 * SECONDS_PER_MINUTE2));
140843
+ const minutes = Math.floor(seconds % (MINUTES_PER_HOUR4 * SECONDS_PER_MINUTE2) / SECONDS_PER_MINUTE2);
140844
+ if (days > 0) {
140845
+ return `${String(days)}d ${String(hours)}h`;
140846
+ }
140847
+ if (hours > 0) {
140848
+ return `${String(hours)}h ${String(minutes).padStart(2, "0")}m`;
140849
+ }
140850
+ return `${String(minutes)}m`;
140851
+ }
140852
+ function secondsUntil(resetAt, nowMs) {
140853
+ if (resetAt === void 0) {
140854
+ return void 0;
140855
+ }
140856
+ const resetMs = Date.parse(resetAt);
140857
+ return Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.round((resetMs - nowMs) / THOUSAND));
140858
+ }
140859
+ function barCell(prefix, suffix, fraction, style) {
140860
+ return { prefix, suffix, draw: (cells) => drawBar(fraction, cells, style) };
140861
+ }
140862
+
140863
+ // src/statusline/payload.ts
140507
140864
  var number4 = external_exports.number().optional().catch(void 0);
140508
140865
  var text2 = external_exports.string().optional().catch(void 0);
140509
140866
  var ClientPayloadSchema = external_exports.looseObject({
@@ -140517,7 +140874,7 @@ var ClientPayloadSchema = external_exports.looseObject({
140517
140874
  workspace: external_exports.looseObject({
140518
140875
  current_dir: text2,
140519
140876
  project_dir: text2,
140520
- added_dirs: external_exports.array(external_exports.string()).optional().catch(void 0),
140877
+ added_dirs: external_exports.array(external_exports.unknown()).transform((dirs) => dirs.filter((dir) => typeof dir === "string")).optional().catch(void 0),
140521
140878
  git_worktree: text2
140522
140879
  }).optional().catch(void 0),
140523
140880
  model: external_exports.looseObject({ id: text2, display_name: text2 }).optional().catch(void 0),
@@ -140534,17 +140891,28 @@ var ClientPayloadSchema = external_exports.looseObject({
140534
140891
  rate_limits: external_exports.looseObject({
140535
140892
  five_hour: external_exports.looseObject({ used_percentage: number4, resets_at: number4 }).optional().catch(void 0),
140536
140893
  seven_day: external_exports.looseObject({ used_percentage: number4, resets_at: number4 }).optional().catch(void 0),
140537
- model_scoped: external_exports.array(external_exports.looseObject({ display_name: text2, utilization: number4, resets_at: text2 })).optional().catch(void 0)
140894
+ model_scoped: external_exports.array(external_exports.looseObject({ display_name: text2, utilization: number4, resets_at: text2 }).optional().catch(void 0)).transform((windows) => windows.filter((window) => window !== void 0)).optional().catch(void 0)
140538
140895
  }).optional().catch(void 0)
140539
140896
  }).catch({});
140540
140897
  function parseClientPayload(raw) {
140541
140898
  return ClientPayloadSchema.parse(raw);
140542
140899
  }
140900
+ function nonNegative(value2) {
140901
+ return value2 !== void 0 && value2 < 0 ? void 0 : value2;
140902
+ }
140903
+ function reportedPercent(value2) {
140904
+ const kept = nonNegative(value2);
140905
+ return kept === void 0 ? void 0 : Math.min(kept, FULL_PERCENT3);
140906
+ }
140907
+ function nonBlank(value2) {
140908
+ const trimmed = value2?.trim();
140909
+ return trimmed === "" ? void 0 : trimmed;
140910
+ }
140543
140911
  function viewOf(payload) {
140544
140912
  return {
140545
- modelDisplayName: payload.model?.display_name,
140546
- contextUsedPercentage: payload.context_window?.used_percentage,
140547
- contextTotalTokens: payload.context_window?.total_input_tokens,
140913
+ clientModelName: nonBlank(payload.model?.display_name) ?? nonBlank(payload.model?.id),
140914
+ contextUsedPercentage: reportedPercent(payload.context_window?.used_percentage),
140915
+ contextTotalTokens: nonNegative(payload.context_window?.total_input_tokens),
140548
140916
  contextWindowTokens: payload.context_window?.context_window_size,
140549
140917
  cacheHitRatio: payload.prompt_cache?.hit_ratio,
140550
140918
  cacheReadTokens: payload.context_window?.current_usage?.cache_read_input_tokens,
@@ -140846,44 +141214,6 @@ function parseClaudeModelId(id2) {
140846
141214
 
140847
141215
  // src/statusline/sanitise.ts
140848
141216
  init_statusline();
140849
-
140850
- // src/statusline/ansi.ts
140851
- init_string_width();
140852
- init_graphemes();
140853
- var ESCAPE_CHAR_CODE = 27;
140854
- var ESCAPE = String.fromCharCode(ESCAPE_CHAR_CODE);
140855
- var BELL = "\\u0007";
140856
- var ESCAPE_SEQUENCE_PATTERN = [`${ESCAPE}\\[[0-?]*[ -/]*[@-~]`, `${ESCAPE}\\][^${BELL}${ESCAPE}]*(?:${BELL}|${ESCAPE}\\\\)?`, `${ESCAPE}[@-Z\\\\-_]`].join("|");
140857
- var SPLIT_ON_ESCAPES = new RegExp(`(${ESCAPE_SEQUENCE_PATTERN})`);
140858
- function visibleLength(text5) {
140859
- return stringWidth(text5);
140860
- }
140861
- function truncateToColumns(text5, columns) {
140862
- let used = 0;
140863
- let kept = "";
140864
- text5.split(SPLIT_ON_ESCAPES).forEach((part, index) => {
140865
- if (index % 2 === 1) {
140866
- kept += part;
140867
- return;
140868
- }
140869
- for (const grapheme of graphemesOf(part)) {
140870
- used += visibleLength(grapheme);
140871
- if (used > columns) {
140872
- return;
140873
- }
140874
- kept += grapheme;
140875
- }
140876
- });
140877
- return kept;
140878
- }
140879
- function truncateWithEllipsis(text5, columns, ellipsis) {
140880
- if (visibleLength(text5) <= columns) {
140881
- return text5;
140882
- }
140883
- return `${truncateToColumns(text5, Math.max(0, columns - visibleLength(ellipsis)))}${ellipsis}`;
140884
- }
140885
-
140886
- // src/statusline/sanitise.ts
140887
141217
  init_blank();
140888
141218
  init_graphemes();
140889
141219
  var ESCAPE_SEQUENCES = new RegExp(ESCAPE_SEQUENCE_PATTERN, "g");
@@ -141186,32 +141516,32 @@ function dailyCostSegment(context) {
141186
141516
 
141187
141517
  // src/statusline/elements/sessionFormat.ts
141188
141518
  var MS_PER_SECOND18 = 1e3;
141189
- var SECONDS_PER_MINUTE2 = 60;
141190
- var MINUTES_PER_HOUR4 = 60;
141519
+ var SECONDS_PER_MINUTE3 = 60;
141520
+ var MINUTES_PER_HOUR5 = 60;
141191
141521
  var HOURS_PER_DAY9 = 24;
141192
141522
  function formatElapsed(ms2) {
141193
- const minutes = Math.floor(ms2 / (MS_PER_SECOND18 * SECONDS_PER_MINUTE2));
141523
+ const minutes = Math.floor(ms2 / (MS_PER_SECOND18 * SECONDS_PER_MINUTE3));
141194
141524
  if (minutes < 1) {
141195
141525
  return "<1m";
141196
141526
  }
141197
- if (minutes < MINUTES_PER_HOUR4) {
141527
+ if (minutes < MINUTES_PER_HOUR5) {
141198
141528
  return `${String(minutes)}m`;
141199
141529
  }
141200
- return `${String(Math.floor(minutes / MINUTES_PER_HOUR4))}h ${String(minutes % MINUTES_PER_HOUR4)}m`;
141530
+ return `${String(Math.floor(minutes / MINUTES_PER_HOUR5))}h ${String(minutes % MINUTES_PER_HOUR5)}m`;
141201
141531
  }
141202
141532
  function formatSpan(ms2) {
141203
141533
  if (ms2 < MS_PER_SECOND18) {
141204
141534
  return "<1s";
141205
141535
  }
141206
141536
  const seconds = Math.floor(ms2 / MS_PER_SECOND18);
141207
- if (seconds < SECONDS_PER_MINUTE2) {
141537
+ if (seconds < SECONDS_PER_MINUTE3) {
141208
141538
  return `${String(seconds)}s`;
141209
141539
  }
141210
- const minutes = Math.floor(seconds / SECONDS_PER_MINUTE2);
141211
- if (minutes < MINUTES_PER_HOUR4) {
141212
- return `${String(minutes)}m ${String(seconds % SECONDS_PER_MINUTE2)}s`;
141540
+ const minutes = Math.floor(seconds / SECONDS_PER_MINUTE3);
141541
+ if (minutes < MINUTES_PER_HOUR5) {
141542
+ return `${String(minutes)}m ${String(seconds % SECONDS_PER_MINUTE3)}s`;
141213
141543
  }
141214
- return `${String(Math.floor(minutes / MINUTES_PER_HOUR4))}h ${String(minutes % MINUTES_PER_HOUR4)}m`;
141544
+ return `${String(Math.floor(minutes / MINUTES_PER_HOUR5))}h ${String(minutes % MINUTES_PER_HOUR5)}m`;
141215
141545
  }
141216
141546
  function twoUnits(larger2, smaller, largerUnit, smallerUnit) {
141217
141547
  return smaller > 0 ? `${String(larger2)}${largerUnit} ${String(smaller)}${smallerUnit}` : `${String(larger2)}${largerUnit}`;
@@ -141221,16 +141551,16 @@ function formatAgo(ms2, t10) {
141221
141551
  return t10("time.justNow");
141222
141552
  }
141223
141553
  const seconds = Math.floor(ms2 / MS_PER_SECOND18);
141224
- if (seconds < SECONDS_PER_MINUTE2) {
141554
+ if (seconds < SECONDS_PER_MINUTE3) {
141225
141555
  return t10("time.ago", { value: `${String(seconds)}s` });
141226
141556
  }
141227
- const minutes = Math.floor(seconds / SECONDS_PER_MINUTE2);
141228
- if (minutes < MINUTES_PER_HOUR4) {
141557
+ const minutes = Math.floor(seconds / SECONDS_PER_MINUTE3);
141558
+ if (minutes < MINUTES_PER_HOUR5) {
141229
141559
  return t10("time.ago", { value: `${String(minutes)}m` });
141230
141560
  }
141231
- const hours = Math.floor(minutes / MINUTES_PER_HOUR4);
141561
+ const hours = Math.floor(minutes / MINUTES_PER_HOUR5);
141232
141562
  if (hours < HOURS_PER_DAY9) {
141233
- return t10("time.ago", { value: twoUnits(hours, minutes % MINUTES_PER_HOUR4, "h", "m") });
141563
+ return t10("time.ago", { value: twoUnits(hours, minutes % MINUTES_PER_HOUR5, "h", "m") });
141234
141564
  }
141235
141565
  return t10("time.ago", { value: twoUnits(Math.floor(hours / HOURS_PER_DAY9), hours % HOURS_PER_DAY9, "d", "h") });
141236
141566
  }
@@ -141241,253 +141571,6 @@ function durationSegment(context) {
141241
141571
  return startedAtMs === void 0 ? void 0 : `\u23F1\uFE0F ${formatElapsed(context.nowMs - startedAtMs)}`;
141242
141572
  }
141243
141573
 
141244
- // src/statusline/colour.ts
141245
- init_statusline();
141246
- var FULL_CHANNEL = 255;
141247
- var NORMAL_PRIMARY = 205;
141248
- var SCHEME_WHITE = 229;
141249
- var SCHEME_BLUE = 238;
141250
- var BRIGHT_BLACK_GREY = 127;
141251
- var BRIGHT_BLUE_TINT = 92;
141252
- var NAMED_DEFAULT_RGB = {
141253
- black: [0, 0, 0],
141254
- red: [NORMAL_PRIMARY, 0, 0],
141255
- green: [0, NORMAL_PRIMARY, 0],
141256
- yellow: [NORMAL_PRIMARY, NORMAL_PRIMARY, 0],
141257
- blue: [0, 0, SCHEME_BLUE],
141258
- magenta: [NORMAL_PRIMARY, 0, NORMAL_PRIMARY],
141259
- cyan: [0, NORMAL_PRIMARY, NORMAL_PRIMARY],
141260
- white: [SCHEME_WHITE, SCHEME_WHITE, SCHEME_WHITE],
141261
- brightBlack: [BRIGHT_BLACK_GREY, BRIGHT_BLACK_GREY, BRIGHT_BLACK_GREY],
141262
- brightRed: [FULL_CHANNEL, 0, 0],
141263
- brightGreen: [0, FULL_CHANNEL, 0],
141264
- brightYellow: [FULL_CHANNEL, FULL_CHANNEL, 0],
141265
- brightBlue: [BRIGHT_BLUE_TINT, BRIGHT_BLUE_TINT, FULL_CHANNEL],
141266
- brightMagenta: [FULL_CHANNEL, 0, FULL_CHANNEL],
141267
- brightCyan: [0, FULL_CHANNEL, FULL_CHANNEL],
141268
- brightWhite: [FULL_CHANNEL, FULL_CHANNEL, FULL_CHANNEL]
141269
- };
141270
- function isNamedColour(value2) {
141271
- return value2 !== "default" && value2 !== "dim" && STATUSLINE_COLOUR_NAMES.some((name) => name === value2);
141272
- }
141273
- var NAMED_RGB_IN_PALETTE_ORDER = STATUSLINE_COLOUR_NAMES.filter(isNamedColour).map((name) => NAMED_DEFAULT_RGB[name]);
141274
- var CUBE_SIDE = 6;
141275
- var CUBE_FIRST_INDEX = 16;
141276
- var GREYSCALE_FIRST_INDEX = CUBE_FIRST_INDEX + CUBE_SIDE * CUBE_SIDE * CUBE_SIDE;
141277
- var GREYSCALE_START = 8;
141278
- var GREYSCALE_STEP = 10;
141279
- var CUBE_CHANNEL_BASE = 55;
141280
- var CUBE_CHANNEL_STEP = 40;
141281
- function cubeChannel(level) {
141282
- return level === 0 ? 0 : CUBE_CHANNEL_BASE + CUBE_CHANNEL_STEP * level;
141283
- }
141284
- function paletteIndexRgb(index) {
141285
- if (index < CUBE_FIRST_INDEX) {
141286
- return NAMED_RGB_IN_PALETTE_ORDER[index];
141287
- }
141288
- if (index < GREYSCALE_FIRST_INDEX) {
141289
- const cube = index - CUBE_FIRST_INDEX;
141290
- return [cubeChannel(Math.floor(cube / CUBE_SIDE ** 2)), cubeChannel(Math.floor(cube / CUBE_SIDE) % CUBE_SIDE), cubeChannel(cube % CUBE_SIDE)];
141291
- }
141292
- const grey = GREYSCALE_START + GREYSCALE_STEP * (index - GREYSCALE_FIRST_INDEX);
141293
- return [grey, grey, grey];
141294
- }
141295
- var CHANNEL_DIGITS = 2;
141296
- var HEX_RADIX2 = 16;
141297
- var HASH_LENGTH = 1;
141298
- function rgbOfHex(value2) {
141299
- const channel = (index) => Number.parseInt(value2.slice(HASH_LENGTH + index * CHANNEL_DIGITS, HASH_LENGTH + (index + 1) * CHANNEL_DIGITS), HEX_RADIX2);
141300
- return [channel(0), channel(1), channel(2)];
141301
- }
141302
- function rgbOfSetting(value2) {
141303
- if (typeof value2 === "number") {
141304
- return paletteIndexRgb(value2);
141305
- }
141306
- if (value2.startsWith("#")) {
141307
- return rgbOfHex(value2);
141308
- }
141309
- return isNamedColour(value2) ? NAMED_DEFAULT_RGB[value2] : void 0;
141310
- }
141311
- function blendRgb(from, to2, at2) {
141312
- const channel = (start, end) => Math.round(start + (end - start) * at2);
141313
- return [channel(from[0], to2[0]), channel(from[1], to2[1]), channel(from[2], to2[2])];
141314
- }
141315
-
141316
- // src/statusline/palette.ts
141317
- init_statusline();
141318
- var RESET = `${ESCAPE}[0m`;
141319
- var SGR_BY_NAME = {
141320
- default: "",
141321
- dim: "2",
141322
- black: "30",
141323
- red: "31",
141324
- green: "32",
141325
- yellow: "33",
141326
- blue: "34",
141327
- magenta: "35",
141328
- cyan: "36",
141329
- white: "37",
141330
- brightBlack: "90",
141331
- brightRed: "91",
141332
- brightGreen: "92",
141333
- brightYellow: "93",
141334
- brightBlue: "94",
141335
- brightMagenta: "95",
141336
- brightCyan: "96",
141337
- brightWhite: "97"
141338
- };
141339
- function isColourName(value2) {
141340
- return STATUSLINE_COLOUR_NAMES.some((name) => name === value2);
141341
- }
141342
- function rgbSgr(channels) {
141343
- return `38;2;${channels.join(";")}`;
141344
- }
141345
- function sgrOf(value2) {
141346
- if (typeof value2 === "number") {
141347
- return `38;5;${String(value2)}`;
141348
- }
141349
- if (value2.startsWith("#")) {
141350
- return rgbSgr(rgbOfHex(value2));
141351
- }
141352
- return isColourName(value2) ? SGR_BY_NAME[value2] : "";
141353
- }
141354
- function colourEnabled(env) {
141355
- return env.NO_COLOR === void 0;
141356
- }
141357
- function createPalette(colours, enabled) {
141358
- const ansi = (role) => {
141359
- const sgr = enabled ? sgrOf(colours[role]) : "";
141360
- return sgr === "" ? "" : `${ESCAPE}[${sgr}m`;
141361
- };
141362
- return {
141363
- ansi,
141364
- paint: (role, text5) => {
141365
- const start = ansi(role);
141366
- return start === "" ? text5 : `${start}${text5}${RESET}`;
141367
- },
141368
- rgb: (channels) => enabled ? `${ESCAPE}[${rgbSgr(channels)}m` : "",
141369
- rgbOf: (role) => rgbOfSetting(colours[role])
141370
- };
141371
- }
141372
-
141373
- // src/statusline/style.ts
141374
- var SECONDS_PER_MINUTE3 = 60;
141375
- var MINUTES_PER_HOUR5 = 60;
141376
- var SECONDS_PER_DAY = 86400;
141377
- var THOUSAND = 1e3;
141378
- var MILLION = 1e6;
141379
- var TEN = 10;
141380
- var FULL_PERCENT3 = 100;
141381
- var ONE_PERCENT = 1;
141382
- function withColor(color, text5) {
141383
- return color === "" ? text5 : `${color}${text5}${RESET}`;
141384
- }
141385
- function warningRoleOf(style) {
141386
- return style.okRole === "usage" ? "usageWarning" : "warning";
141387
- }
141388
- function statusColor(fraction, isUsedMetric, style) {
141389
- const yellowAt = style.bands.warnAt / FULL_PERCENT3;
141390
- const redAt = style.bands.criticalAt / FULL_PERCENT3;
141391
- const { ansi } = style.palette;
141392
- if (isUsedMetric) {
141393
- if (fraction >= redAt) {
141394
- return ansi("critical");
141395
- }
141396
- return fraction >= yellowAt ? ansi(warningRoleOf(style)) : ansi(style.okRole);
141397
- }
141398
- if (fraction <= 1 - redAt) {
141399
- return ansi("critical");
141400
- }
141401
- return fraction <= 1 - yellowAt ? ansi(warningRoleOf(style)) : ansi(style.okRole);
141402
- }
141403
- function stopOf(role, style) {
141404
- const rgb = style.palette.rgbOf(role);
141405
- return rgb === void 0 ? void 0 : { role, rgb };
141406
- }
141407
- function colourBetween(from, to2, at2, style) {
141408
- if (at2 <= 0) {
141409
- return style.palette.ansi(from.role);
141410
- }
141411
- if (at2 >= 1) {
141412
- return style.palette.ansi(to2.role);
141413
- }
141414
- return style.palette.rgb(blendRgb(from.rgb, to2.rgb, at2));
141415
- }
141416
- function gradientColorOf(fraction, style) {
141417
- const ok2 = stopOf(style.okRole, style);
141418
- const warning = stopOf(warningRoleOf(style), style);
141419
- const critical = stopOf("critical", style);
141420
- if (ok2 === void 0 || warning === void 0 || critical === void 0) {
141421
- return void 0;
141422
- }
141423
- const warnAt = style.bands.warnAt / FULL_PERCENT3;
141424
- const criticalAt = style.bands.criticalAt / FULL_PERCENT3;
141425
- return fraction < warnAt ? colourBetween(ok2, warning, fraction / warnAt, style) : colourBetween(warning, critical, (fraction - warnAt) / (criticalAt - warnAt), style);
141426
- }
141427
- function widthStopsOf(style) {
141428
- const ok2 = stopOf(style.okRole, style);
141429
- const critical = stopOf("critical", style);
141430
- return ok2 === void 0 || critical === void 0 ? void 0 : { ok: ok2, critical };
141431
- }
141432
- function acrossBar(column, cells) {
141433
- return cells <= 1 ? 0 : column / (cells - 1);
141434
- }
141435
- function fillOf(fraction, filled, cells, style) {
141436
- const stops = style.gradient === "width" ? widthStopsOf(style) : void 0;
141437
- if (stops !== void 0 && filled > 0) {
141438
- return Array.from({ length: filled }, (_, column) => `${colourBetween(stops.ok, stops.critical, acrossBar(column, cells), style)}${style.filled}`).join("");
141439
- }
141440
- const color = style.gradient === "use" ? gradientColorOf(fraction, style) : void 0;
141441
- return `${color ?? statusColor(fraction, true, style)}${style.filled.repeat(filled)}`;
141442
- }
141443
- function drawBar(fraction, cells, style) {
141444
- const clamped = Math.max(0, Math.min(1, fraction));
141445
- const filled = Math.round(clamped * cells);
141446
- const emptyColor = style.palette.ansi("empty");
141447
- const fill = fillOf(clamped, filled, cells, style);
141448
- const empty = style.empty.repeat(cells - filled);
141449
- return fill === style.filled.repeat(filled) && emptyColor === "" ? `[${fill}${empty}]` : `[${fill}${emptyColor}${empty}${RESET}]`;
141450
- }
141451
- function formatTokens(num) {
141452
- if (num >= MILLION) {
141453
- const val = num / MILLION;
141454
- return val % 1 === 0 ? `${String(Math.round(val))}M` : `${val.toFixed(1)}M`;
141455
- }
141456
- if (num >= THOUSAND) {
141457
- const val = num / THOUSAND;
141458
- return val >= TEN ? `${String(Math.round(val))}k` : `${val.toFixed(1)}k`;
141459
- }
141460
- return String(Math.round(num));
141461
- }
141462
- function formatDuration(seconds, t10) {
141463
- if (seconds === void 0 || seconds <= 0) {
141464
- return t10("quota.available");
141465
- }
141466
- if (seconds < SECONDS_PER_MINUTE3) {
141467
- return `${String(seconds)}s`;
141468
- }
141469
- const days = Math.floor(seconds / SECONDS_PER_DAY);
141470
- const hours = Math.floor(seconds % SECONDS_PER_DAY / (MINUTES_PER_HOUR5 * SECONDS_PER_MINUTE3));
141471
- const minutes = Math.floor(seconds % (MINUTES_PER_HOUR5 * SECONDS_PER_MINUTE3) / SECONDS_PER_MINUTE3);
141472
- if (days > 0) {
141473
- return `${String(days)}d ${String(hours)}h`;
141474
- }
141475
- if (hours > 0) {
141476
- return `${String(hours)}h ${String(minutes).padStart(2, "0")}m`;
141477
- }
141478
- return `${String(minutes)}m`;
141479
- }
141480
- function secondsUntil(resetAt, nowMs) {
141481
- if (resetAt === void 0) {
141482
- return void 0;
141483
- }
141484
- const resetMs = Date.parse(resetAt);
141485
- return Number.isNaN(resetMs) ? void 0 : Math.max(0, Math.round((resetMs - nowMs) / THOUSAND));
141486
- }
141487
- function barCell(prefix, suffix, fraction, style) {
141488
- return { prefix, suffix, draw: (cells) => drawBar(fraction, cells, style) };
141489
- }
141490
-
141491
141574
  // src/statusline/elements/header/headroom.ts
141492
141575
  function headroomText(stats, t10) {
141493
141576
  if (stats === void 0) {
@@ -141513,6 +141596,73 @@ function identitySegment({ summary }) {
141513
141596
  return void 0;
141514
141597
  }
141515
141598
 
141599
+ // src/statusline/headerLayout.ts
141600
+ var SEPARATOR3 = " | ";
141601
+ function headerUnits(parts, overflow) {
141602
+ const units = [];
141603
+ parts.forEach((part, index) => {
141604
+ const before = parts[index - 1];
141605
+ if (overflow === "truncate" && part.name === "vcs" && before?.name === "project") {
141606
+ units[units.length - 1] = `${units.at(-1) ?? ""} ${part.text}`;
141607
+ } else {
141608
+ units.push(part.text);
141609
+ }
141610
+ });
141611
+ return units;
141612
+ }
141613
+ function justify(texts, maxWidth, separator) {
141614
+ if (texts.length < 2) {
141615
+ return texts.join(separator);
141616
+ }
141617
+ const separatorLength = visibleLength(separator);
141618
+ const total = texts.reduce((sum2, text5) => sum2 + visibleLength(text5), 0) + separatorLength * (texts.length - 1);
141619
+ const spare = maxWidth - total;
141620
+ if (spare <= 0) {
141621
+ return texts.join(separator);
141622
+ }
141623
+ const gaps = texts.length - 1;
141624
+ const extraPerGap = Math.floor(spare / gaps);
141625
+ let remainder = spare % gaps;
141626
+ const parts = [];
141627
+ texts.forEach((text5, index) => {
141628
+ if (index > 0) {
141629
+ const extra = extraPerGap + (remainder > 0 ? 1 : 0);
141630
+ if (remainder > 0) {
141631
+ remainder -= 1;
141632
+ }
141633
+ const left = Math.floor(extra / 2);
141634
+ parts.push(`${" ".repeat(left + 1)}|${" ".repeat(extra - left + 1)}`);
141635
+ }
141636
+ parts.push(text5);
141637
+ });
141638
+ return parts.join("");
141639
+ }
141640
+ function packLines(texts, maxWidth, separator) {
141641
+ const separatorLength = visibleLength(separator);
141642
+ const lines = [];
141643
+ let current = [];
141644
+ let currentWidth = 0;
141645
+ for (const text5 of texts) {
141646
+ const width = visibleLength(text5);
141647
+ const added = current.length === 0 ? width : width + separatorLength;
141648
+ if (current.length > 0 && currentWidth + added > maxWidth) {
141649
+ lines.push(current);
141650
+ current = [text5];
141651
+ currentWidth = width;
141652
+ } else {
141653
+ current.push(text5);
141654
+ currentWidth += added;
141655
+ }
141656
+ }
141657
+ if (current.length > 0) {
141658
+ lines.push(current);
141659
+ }
141660
+ return lines;
141661
+ }
141662
+ function layoutHeader(texts, maxWidth, separator) {
141663
+ return packLines(texts, maxWidth, separator).map((line) => justify(line, maxWidth, separator)).join("\n");
141664
+ }
141665
+
141516
141666
  // src/statusline/elements/header/model.ts
141517
141667
  function choiceNamesProvider(summary) {
141518
141668
  return summary.modelChoice !== void 0 && (summary.modelChoice.providers.length > 1 || summary.routedTarget !== void 0);
@@ -141539,9 +141689,18 @@ function modelNameOf({ view, settings: settings2, transcriptIdentity }) {
141539
141689
  return { name: formatModelName(served, settings2.model.format), isServed: true };
141540
141690
  }
141541
141691
  }
141542
- return view.modelDisplayName === void 0 || view.modelDisplayName === "" ? void 0 : { name: formatModelName(view.modelDisplayName, settings2.model.format), isServed: false };
141692
+ return view.clientModelName === void 0 ? void 0 : { name: formatModelName(view.clientModelName, settings2.model.format), isServed: false };
141543
141693
  }
141544
141694
  function modelSegment(context) {
141695
+ const name = modelName(context);
141696
+ const inputs = platformInputsOf(context.payload, context.ports.env, context.payload.model?.id);
141697
+ const platform = context.settings.model.platform ? modelPlatformOf(inputs.env, inputs.modelId) : void 0;
141698
+ if (platform === void 0) {
141699
+ return name;
141700
+ }
141701
+ return name === void 0 ? platform : `${name}${SEPARATOR3}${platform}`;
141702
+ }
141703
+ function modelName(context) {
141545
141704
  const { summary } = context;
141546
141705
  const model = modelNameOf(context);
141547
141706
  if (model === void 0 || model.name === "") {
@@ -142088,73 +142247,6 @@ function addedDirsRow({ payload, settings: settings2, palette, t: t10 }) {
142088
142247
  return { kind: "text", lines: [writeAround(t10, "addedDirs.label", drawn.join(label2(t10("list.separator"))), label2)] };
142089
142248
  }
142090
142249
 
142091
- // src/statusline/headerLayout.ts
142092
- var SEPARATOR3 = " | ";
142093
- function headerUnits(parts, overflow) {
142094
- const units = [];
142095
- parts.forEach((part, index) => {
142096
- const before = parts[index - 1];
142097
- if (overflow === "truncate" && part.name === "vcs" && before?.name === "project") {
142098
- units[units.length - 1] = `${units.at(-1) ?? ""} ${part.text}`;
142099
- } else {
142100
- units.push(part.text);
142101
- }
142102
- });
142103
- return units;
142104
- }
142105
- function justify(texts, maxWidth, separator) {
142106
- if (texts.length < 2) {
142107
- return texts.join(separator);
142108
- }
142109
- const separatorLength = visibleLength(separator);
142110
- const total = texts.reduce((sum2, text5) => sum2 + visibleLength(text5), 0) + separatorLength * (texts.length - 1);
142111
- const spare = maxWidth - total;
142112
- if (spare <= 0) {
142113
- return texts.join(separator);
142114
- }
142115
- const gaps = texts.length - 1;
142116
- const extraPerGap = Math.floor(spare / gaps);
142117
- let remainder = spare % gaps;
142118
- const parts = [];
142119
- texts.forEach((text5, index) => {
142120
- if (index > 0) {
142121
- const extra = extraPerGap + (remainder > 0 ? 1 : 0);
142122
- if (remainder > 0) {
142123
- remainder -= 1;
142124
- }
142125
- const left = Math.floor(extra / 2);
142126
- parts.push(`${" ".repeat(left + 1)}|${" ".repeat(extra - left + 1)}`);
142127
- }
142128
- parts.push(text5);
142129
- });
142130
- return parts.join("");
142131
- }
142132
- function packLines(texts, maxWidth, separator) {
142133
- const separatorLength = visibleLength(separator);
142134
- const lines = [];
142135
- let current = [];
142136
- let currentWidth = 0;
142137
- for (const text5 of texts) {
142138
- const width = visibleLength(text5);
142139
- const added = current.length === 0 ? width : width + separatorLength;
142140
- if (current.length > 0 && currentWidth + added > maxWidth) {
142141
- lines.push(current);
142142
- current = [text5];
142143
- currentWidth = width;
142144
- } else {
142145
- current.push(text5);
142146
- currentWidth += added;
142147
- }
142148
- }
142149
- if (current.length > 0) {
142150
- lines.push(current);
142151
- }
142152
- return lines;
142153
- }
142154
- function layoutHeader(texts, maxWidth, separator) {
142155
- return packLines(texts, maxWidth, separator).map((line) => justify(line, maxWidth, separator)).join("\n");
142156
- }
142157
-
142158
142250
  // src/statusline/elements/rows/activityParts.ts
142159
142251
  var RUNNING_MARK = "\u25D0";
142160
142252
  var DONE_MARK = "\u2713";
@@ -142277,10 +142369,11 @@ function cacheShareText(view, style, t10) {
142277
142369
  function windowTokensOf({ settings: settings2, view }) {
142278
142370
  return settings2.context.autoCompactWindow ?? view.contextWindowTokens;
142279
142371
  }
142372
+ var ROUNDING_HALF_POINT = 0.5;
142280
142373
  function bufferedPercent(tokens, windowTokens) {
142281
142374
  const held = tokens / windowTokens;
142282
142375
  const ramp = Math.max(0, Math.min(1, (held - AUTOCOMPACT_RESERVE_RAMP_START) / (AUTOCOMPACT_RESERVE_RAMP_END - AUTOCOMPACT_RESERVE_RAMP_START)));
142283
- return Math.min(FULL_PERCENT3, (held + AUTOCOMPACT_RESERVE_FRACTION * ramp) * FULL_PERCENT3);
142376
+ return Math.min(FULL_PERCENT3, (tokens + windowTokens * AUTOCOMPACT_RESERVE_FRACTION * ramp) / windowTokens * FULL_PERCENT3);
142284
142377
  }
142285
142378
  function usedPercentOf(context) {
142286
142379
  const { settings: settings2, view } = context;
@@ -142312,9 +142405,10 @@ function contextRow(context) {
142312
142405
  return settings2.context.bar === "shown" ? { kind: "bars", cells: [] } : { kind: "text", lines: [] };
142313
142406
  }
142314
142407
  const style = barStyleOf(context, "context");
142315
- const bands = contextBands(settings2);
142408
+ const bands = { warnAt: settings2.context.warnAt - ROUNDING_HALF_POINT, criticalAt: settings2.context.criticalAt - ROUNDING_HALF_POINT };
142316
142409
  const fraction = Math.max(0, Math.min(1, percent2 / FULL_PERCENT3));
142317
- const color = statusColor(fraction, true, { ...style, bands });
142410
+ const bandFraction = Math.max(0, Math.min(1, Math.round(percent2) / FULL_PERCENT3));
142411
+ const color = statusColor(bandFraction, true, { ...style, bands });
142318
142412
  const windowTokens = windowTokensOf(context);
142319
142413
  const tokens = view.contextTotalTokens;
142320
142414
  const heldAgainstWindow = tokens === void 0 || windowTokens === void 0 ? void 0 : `${formatTokens(tokens)}/${formatTokens(windowTokens)}`;
@@ -142344,7 +142438,7 @@ function contextRow(context) {
142344
142438
  default:
142345
142439
  return settings2.context.value;
142346
142440
  }
142347
- const high = settings2.context.breakdown === "critical" && percent2 >= bands.criticalAt ? breakdownText(context) : void 0;
142441
+ const high = settings2.context.breakdown === "critical" && Math.round(percent2) >= contextBreakdownAt(settings2) ? breakdownText(context) : void 0;
142348
142442
  if (settings2.context.bar === "hidden" && afterBar.length === 0) {
142349
142443
  return { kind: "text", lines: [] };
142350
142444
  }
@@ -142352,7 +142446,7 @@ function contextRow(context) {
142352
142446
  const label2 = [context.t("context.label"), ...beforeBar].join(" ");
142353
142447
  if (settings2.context.bar === "shown") {
142354
142448
  const suffix = afterBar.length === 0 ? trailer : ` ${afterBar.join(" ")}${trailer}`;
142355
- return { kind: "bars", cells: [barCell(palette.paint("label", `${label2} `), suffix, fraction, { ...style, bands })] };
142449
+ return { kind: "bars", cells: [barCell(palette.paint("label", `${label2} `), suffix, fraction, { ...style, bands, bandFraction })] };
142356
142450
  }
142357
142451
  return { kind: "text", lines: [`${[palette.paint("label", label2), ...afterBar].join(" ")}${trailer}`] };
142358
142452
  }
@@ -142631,8 +142725,8 @@ function promptCacheRow(context) {
142631
142725
  }
142632
142726
 
142633
142727
  // src/statusline/elements/rows/quota.ts
142634
- init_statusline();
142635
142728
  init_pick();
142729
+ init_graphemes();
142636
142730
 
142637
142731
  // src/statusline/resetTime.ts
142638
142732
  function elapsedPercent(resetMs, periodMs, nowMs) {
@@ -142675,55 +142769,69 @@ function formatResetTime(window, nowMs, settings2, clock, t10, labelled) {
142675
142769
  }
142676
142770
 
142677
142771
  // src/statusline/elements/rows/quota.ts
142678
- function safeLabel(label2) {
142679
- return truncateToColumns(visibleDisplayText(label2), MAX_STATUSLINE_LABEL_COLUMNS).trim();
142772
+ var MODEL_WINDOW_NAME_CHARACTERS = 64;
142773
+ function modelWindowName(name) {
142774
+ return leadingGraphemes(visibleDisplayText(name), MODEL_WINDOW_NAME_CHARACTERS).join("").trim();
142680
142775
  }
142681
142776
  function modelScopedWindows({ payload }) {
142682
142777
  return (payload.rate_limits?.model_scoped ?? []).flatMap((window) => {
142683
- const label2 = safeLabel(window.display_name ?? "");
142684
- if (label2 === "" || window.utilization === void 0 || !Number.isFinite(window.utilization)) {
142778
+ const label2 = modelWindowName(window.display_name ?? "");
142779
+ if (label2 === "") {
142685
142780
  return [];
142686
142781
  }
142687
- return [{ label: label2, fraction: window.utilization / FULL_PERCENT3, resetsAt: window.resets_at, periodMs: SEVEN_DAY_WINDOW_MS, weekly: false }];
142782
+ const fraction = window.utilization !== void 0 && Number.isFinite(window.utilization) ? Math.max(0, Math.min(FULL_PERCENT3, window.utilization)) / FULL_PERCENT3 : void 0;
142783
+ return [{ label: label2, fraction, resetsAt: window.resets_at, periodMs: SEVEN_DAY_WINDOW_MS, weekly: false }];
142688
142784
  });
142689
142785
  }
142690
- function candidateWindows(context) {
142786
+ function unifiedWindows(context) {
142691
142787
  const { summary, settings: settings2 } = context;
142692
- if (summary.quotaFamilies.length > 0) {
142693
- return summary.quotaFamilies.map((window) => ({ label: window.measures, fraction: window.utilization, resetsAt: window.resetsAt, periodMs: void 0, weekly: false }));
142788
+ const inputs = platformInputsOf(context.payload, context.ports.env, context.payload.model?.id);
142789
+ if (summary.provider === void 0 && hidesSubscriptionWindows(inputs.env, inputs.modelId)) {
142790
+ return { unified: [], modelScoped: [] };
142694
142791
  }
142695
- const windows = [];
142792
+ const unified = [];
142696
142793
  if (summary.fiveHourUsed !== void 0) {
142697
- windows.push({ label: settings2.labels.fiveHour === "" ? context.t("quota.fiveHour") : settings2.labels.fiveHour, fraction: summary.fiveHourUsed / FULL_PERCENT3, resetsAt: summary.fiveHourResetAt, periodMs: FIVE_HOUR_WINDOW_MS, weekly: false });
142794
+ unified.push({ label: settings2.labels.fiveHour === "" ? context.t("quota.fiveHour") : settings2.labels.fiveHour, fraction: summary.fiveHourUsed / FULL_PERCENT3, resetsAt: summary.fiveHourResetAt, periodMs: FIVE_HOUR_WINDOW_MS, weekly: false });
142698
142795
  }
142699
142796
  if (summary.sevenDayUsed !== void 0) {
142700
- windows.push({ label: settings2.labels.sevenDay === "" ? context.t("quota.sevenDay") : settings2.labels.sevenDay, fraction: summary.sevenDayUsed / FULL_PERCENT3, resetsAt: summary.sevenDayResetAt, periodMs: SEVEN_DAY_WINDOW_MS, weekly: true });
142701
- }
142702
- if (summary.fiveHourUsed === void 0 && summary.sevenDayUsed === void 0) {
142703
- windows.push(...summary.providerQuotaWindows.map((window) => ({ label: window.measures, fraction: window.utilization, resetsAt: window.resetsAt, periodMs: window.periodMs, weekly: false })));
142797
+ unified.push({ label: settings2.labels.sevenDay === "" ? context.t("quota.sevenDay") : settings2.labels.sevenDay, fraction: summary.sevenDayUsed / FULL_PERCENT3, resetsAt: summary.sevenDayResetAt, periodMs: SEVEN_DAY_WINDOW_MS, weekly: true });
142704
142798
  }
142705
- if (settings2.usage.modelScoped && summary.provider === void 0) {
142706
- windows.push(...modelScopedWindows(context));
142799
+ return { unified, modelScoped: settings2.usage.modelScoped && summary.provider === void 0 ? modelScopedWindows(context) : [] };
142800
+ }
142801
+ function candidateWindows(context) {
142802
+ const { summary } = context;
142803
+ if (summary.quotaFamilies.length > 0) {
142804
+ return summary.quotaFamilies.map((window) => ({ label: window.measures, fraction: window.utilization, resetsAt: window.resetsAt, periodMs: void 0, weekly: false }));
142707
142805
  }
142708
- return windows;
142806
+ const { unified, modelScoped } = unifiedWindows(context);
142807
+ const providerWindows = unified.length > 0 ? [] : summary.providerQuotaWindows.map((window) => ({ label: window.measures, fraction: window.utilization, resetsAt: window.resetsAt, periodMs: window.periodMs, weekly: false }));
142808
+ return [...unified, ...providerWindows, ...modelScoped];
142809
+ }
142810
+ var REPORTED_PERCENT_DIGITS = 9;
142811
+ function wholePercentOf(fraction) {
142812
+ return Math.round(Number((fraction * FULL_PERCENT3).toFixed(REPORTED_PERCENT_DIGITS)));
142709
142813
  }
142710
142814
  function visibleWindows(context) {
142711
142815
  const { summary, settings: settings2 } = context;
142712
142816
  const candidates = candidateWindows(context);
142713
- const mostUsed = Math.max(0, ...candidates.map((window) => window.fraction * FULL_PERCENT3));
142817
+ const mostUsed = Math.max(0, ...candidates.map((window) => window.fraction === void 0 ? 0 : wholePercentOf(window.fraction)));
142714
142818
  if (mostUsed < settings2.usage.threshold) {
142715
142819
  return [];
142716
142820
  }
142717
- const hidesWeekly = summary.fiveHourUsed !== void 0 && summary.sevenDayUsed !== void 0 && summary.sevenDayUsed < settings2.usage.sevenDayThreshold;
142821
+ const hidesWeekly = summary.fiveHourUsed !== void 0 && summary.sevenDayUsed !== void 0 && Math.round(summary.sevenDayUsed) < settings2.usage.sevenDayThreshold;
142718
142822
  return hidesWeekly ? candidates.filter((window) => !window.weekly) : candidates;
142719
142823
  }
142824
+ var NO_FIGURE = "--";
142720
142825
  function figuresOf(window, context, style) {
142721
142826
  const { settings: settings2, nowMs, ports } = context;
142827
+ const reset = formatResetTime(window, nowMs, settings2, ports.clock, context.t, settings2.usage.resetLabel).text;
142828
+ const plainReset = settings2.usage.resetLabel ? formatResetTime(window, nowMs, settings2, ports.clock, context.t, false).text : reset;
142829
+ if (window.fraction === void 0) {
142830
+ return { value: NO_FIGURE, reset, plainReset };
142831
+ }
142722
142832
  const clamped = Math.max(0, Math.min(1, window.fraction));
142723
142833
  const used = window.fraction * FULL_PERCENT3;
142724
142834
  const shown = settings2.usage.value === "remaining" ? Math.max(0, FULL_PERCENT3 - used) : used;
142725
- const reset = formatResetTime(window, nowMs, settings2, ports.clock, context.t, settings2.usage.resetLabel).text;
142726
- const plainReset = settings2.usage.resetLabel ? formatResetTime(window, nowMs, settings2, ports.clock, context.t, false).text : reset;
142727
142835
  return { value: withColor(statusColor(clamped, true, style), `${shown.toFixed(1)}%`), reset, plainReset };
142728
142836
  }
142729
142837
  function parenthesised(reset) {
@@ -142748,7 +142856,7 @@ function quotaRow(context) {
142748
142856
  const lines = parts.map(({ window, value: value2, suffix }) => `${palette.paint("label", `${window.label} `)}${value2}${suffix === "" ? "" : ` ${suffix}`}`);
142749
142857
  return { kind: "text", lines: wrapped(lines, context.width) };
142750
142858
  }
142751
- const cells = parts.map(({ window, value: value2, suffix }) => barCell(palette.paint("label", `${window.label} `), ` ${value2}${suffix === "" ? "" : ` ${suffix}`}`, Math.max(0, Math.min(1, window.fraction)), style));
142859
+ const cells = parts.map(({ window, value: value2, suffix }) => barCell(palette.paint("label", `${window.label} `), ` ${value2}${suffix === "" ? "" : ` ${suffix}`}`, Math.max(0, Math.min(1, window.fraction ?? 0)), style));
142752
142860
  return { kind: "bars", cells };
142753
142861
  }
142754
142862
 
@@ -143373,7 +143481,11 @@ function layoutBarGrid(units, maxWidth, separator, baseBarCells) {
143373
143481
  if (groups.length > 1) {
143374
143482
  return groups.flatMap((group) => layoutBarGrid([[group]], maxWidth, separator, baseBarCells));
143375
143483
  }
143376
- return renderGrid(chunked(1), maxWidth, separator, baseBarCells);
143484
+ const oneToARow = chunked(1);
143485
+ if (oneToARow.baseWidth <= maxWidth) {
143486
+ return renderGrid(oneToARow, maxWidth, separator, baseBarCells);
143487
+ }
143488
+ return oneToARow.rows.flatMap((row) => renderGrid(measureGrid([row], separatorLength, baseBarCells), maxWidth, separator, baseBarCells));
143377
143489
  }
143378
143490
 
143379
143491
  // src/statusline/rowsLayout.ts
@@ -144441,7 +144553,7 @@ function registerStatuslineCommand(program2, deps) {
144441
144553
  stackedUnderDefault = false;
144442
144554
  }
144443
144555
  }
144444
- const view = { ...viewOf(clientPayload), ...stackedUnderDefault ? { modelDisplayName: void 0 } : {} };
144556
+ const view = { ...viewOf(clientPayload), ...stackedUnderDefault ? { clientModelName: void 0 } : {} };
144445
144557
  const widths = widthsOf(payload, process.env, settings2.layout);
144446
144558
  console.log(renderStatuslineBlock({ summary, view, payload: clientPayload, terminalWidth: widths.terminal, lineWidth: widths.line, nowMs, settings: settings2, ports: realStatuslinePorts(process.env, deps.paths.statuslineDir) }));
144447
144559
  }),
@@ -154220,9 +154332,9 @@ var StoredMcpPermissionsSchema = external_exports.strictObject({
154220
154332
  history: external_exports.boolean().default(false)
154221
154333
  });
154222
154334
  var OWNER_ONLY_MODE = 384;
154223
- var NONE2 = { writes: false, remoteControl: false, history: false };
154335
+ var NONE3 = { writes: false, remoteControl: false, history: false };
154224
154336
  function readStoredMcpPermissions(paths) {
154225
- return readJson(paths.mcpPermissionsFile, StoredMcpPermissionsSchema) ?? NONE2;
154337
+ return readJson(paths.mcpPermissionsFile, StoredMcpPermissionsSchema) ?? NONE3;
154226
154338
  }
154227
154339
  function writeStoredMcpPermissions(paths, permissions) {
154228
154340
  writeJsonAtomic(paths.mcpPermissionsFile, { writes: permissions.writes, remoteControl: permissions.remoteControl, history: permissions.history });
@@ -154744,6 +154856,25 @@ var import_node_path65 = __toESM(require("node:path"), 1);
154744
154856
  var import_node_child_process10 = require("node:child_process");
154745
154857
  init_commandDeps();
154746
154858
  init_configProfilesStore();
154859
+
154860
+ // src/logRotation.ts
154861
+ function rotateLogIfOver(fs31, logPath, limits) {
154862
+ if ((fs31.lstat(logPath)?.sizeBytes ?? 0) <= limits.maxBytes) {
154863
+ return false;
154864
+ }
154865
+ const generation = (index) => `${logPath}.${String(index)}`;
154866
+ fs31.removeRecursive(generation(limits.keptGenerations));
154867
+ for (let index = limits.keptGenerations - 1; index >= 1; index -= 1) {
154868
+ if (fs31.lstat(generation(index)) !== void 0) {
154869
+ fs31.rename(generation(index), generation(index + 1));
154870
+ }
154871
+ }
154872
+ fs31.copyRecursive(logPath, generation(1));
154873
+ fs31.writeFileUtf8(logPath, "");
154874
+ return true;
154875
+ }
154876
+
154877
+ // src/headroom/commands.ts
154747
154878
  init_realFrontDoorPort();
154748
154879
  init_trust();
154749
154880
 
@@ -154960,6 +155091,7 @@ function realSupervisorPorts(paths) {
154960
155091
  daemonCommandLine: realProcessCommandLine,
154961
155092
  daemonLogSize: () => realFileSize(paths.headroomLogPath),
154962
155093
  readDaemonLogTail: (fromByte, maxBytes) => realReadFileTail(paths.headroomLogPath, fromByte, maxBytes),
155094
+ rotateDaemonLog: (limits) => rotateLogIfOver(realFarmFs, paths.headroomLogPath, limits),
154963
155095
  socketTrust: realHeadroomSocketTrust,
154964
155096
  readConfig: () => resolveSupervisorConfig(readGlobalConfig(paths)?.headroom ?? {}),
154965
155097
  spawnHeadroom: (socketPath, allowlistFile, settings2) => {