claude-use 11.60.2 → 11.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +264 -131
- package/dist/index.cjs +28 -4
- package/dist/index.mjs +28 -4
- package/dist/types/index.d.ts +774 -4
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -25451,9 +25451,17 @@ function resolveStatusline(settings2) {
|
|
|
25451
25451
|
if (forContext.warnAt >= forContext.criticalAt) {
|
|
25452
25452
|
throw new RangeError(`statusline context.warnAt (${String(forContext.warnAt)}) must be below context.criticalAt (${String(forContext.criticalAt)}), each following bands while it is unset`);
|
|
25453
25453
|
}
|
|
25454
|
+
const merged = new Set(resolved.layout.merge.flat());
|
|
25455
|
+
const unmerged = resolved.layout.rightAlign.filter((row) => !merged.has(row));
|
|
25456
|
+
if (unmerged.length > 0) {
|
|
25457
|
+
throw new RangeError(`statusline layout.rightAlign names ${unmerged.join(", ")}, which no group in layout.merge contains`);
|
|
25458
|
+
}
|
|
25459
|
+
if (resolved.layout.forceMaxWidth && resolved.layout.maxWidth === 0) {
|
|
25460
|
+
throw new RangeError("statusline layout.forceMaxWidth needs layout.maxWidth to be set");
|
|
25461
|
+
}
|
|
25454
25462
|
return resolved;
|
|
25455
25463
|
}
|
|
25456
|
-
var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
25464
|
+
var STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, 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, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
25457
25465
|
var init_statusline = __esm({
|
|
25458
25466
|
"src/config/statusline.ts"() {
|
|
25459
25467
|
"use strict";
|
|
@@ -25494,11 +25502,17 @@ var init_statusline = __esm({
|
|
|
25494
25502
|
MAX_PERCENT = 100;
|
|
25495
25503
|
MAX_STATUSLINE_PALETTE_INDEX = 255;
|
|
25496
25504
|
MAX_STATUSLINE_LABEL_COLUMNS = 12;
|
|
25505
|
+
MIN_STATUSLINE_COLUMNS = 20;
|
|
25506
|
+
MAX_STATUSLINE_COLUMNS = 1e3;
|
|
25497
25507
|
MAX_BAR_CELLS = 40;
|
|
25498
25508
|
MAX_ACCOUNT_USER_CHARS = 254;
|
|
25499
25509
|
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
25500
25510
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
25501
25511
|
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
25512
|
+
mergeGroups = external_exports.array(distinctList(external_exports.enum(STATUSLINE_ROWS)).min(2)).refine((groups) => {
|
|
25513
|
+
const rows = groups.flat();
|
|
25514
|
+
return new Set(rows).size === rows.length;
|
|
25515
|
+
}, "must not name a row in more than one group");
|
|
25502
25516
|
colourValue = external_exports.union([external_exports.enum(STATUSLINE_COLOUR_NAMES), external_exports.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), external_exports.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
|
|
25503
25517
|
barCharacter = external_exports.string().refine(isSingleVisibleGrapheme, "must be a single visible character that takes one terminal column");
|
|
25504
25518
|
STATUSLINE_CONTEXT_VALUES = ["both", "percent", "tokens", "remaining"];
|
|
@@ -25513,7 +25527,14 @@ var init_statusline = __esm({
|
|
|
25513
25527
|
SHAPES = {
|
|
25514
25528
|
layout: {
|
|
25515
25529
|
header: distinctList(external_exports.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
|
|
25516
|
-
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.")
|
|
25530
|
+
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."),
|
|
25531
|
+
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."),
|
|
25532
|
+
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.`),
|
|
25533
|
+
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."),
|
|
25534
|
+
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."),
|
|
25535
|
+
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."),
|
|
25536
|
+
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.`),
|
|
25537
|
+
forceMaxWidth: external_exports.boolean().describe("Whether maxWidth is the exact width lines are drawn to for whatever the client reports, even when the terminal is narrower or wider; it needs maxWidth to be set.")
|
|
25517
25538
|
},
|
|
25518
25539
|
model: {
|
|
25519
25540
|
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."),
|
|
@@ -25659,7 +25680,7 @@ var init_statusline = __esm({
|
|
|
25659
25680
|
jj: external_exports.strictObject(SHAPES.jj)
|
|
25660
25681
|
});
|
|
25661
25682
|
STATUSLINE_DEFAULTS = {
|
|
25662
|
-
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS] },
|
|
25683
|
+
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS], mode: "expanded", rule: "none", mergeBars: true, merge: [], rightAlign: [], maxWidth: 0, forceMaxWidth: false },
|
|
25663
25684
|
model: { format: "full", override: "", source: "client" },
|
|
25664
25685
|
provider: { name: "" },
|
|
25665
25686
|
account: { parts: ["user", "organisation", "plan"], userLength: 0 },
|
|
@@ -32600,6 +32621,9 @@ function keyOf(path70, declared) {
|
|
|
32600
32621
|
if (leaf instanceof external_exports.ZodArray && leaf.element instanceof external_exports.ZodEnum) {
|
|
32601
32622
|
return { ...common, kind: "list", choices: Object.values(leaf.element.enum).map(String) };
|
|
32602
32623
|
}
|
|
32624
|
+
if (leaf instanceof external_exports.ZodArray && leaf.element instanceof external_exports.ZodArray && leaf.element.element instanceof external_exports.ZodEnum) {
|
|
32625
|
+
return { ...common, kind: "groups", choices: Object.values(leaf.element.element.enum).map(String) };
|
|
32626
|
+
}
|
|
32603
32627
|
throw new TypeError(`statusline setting ${path70.join(".")} has a kind the key listing does not describe`);
|
|
32604
32628
|
}
|
|
32605
32629
|
function walk(shape, prefix) {
|
|
@@ -32610,7 +32634,7 @@ function statuslineKeys() {
|
|
|
32610
32634
|
}
|
|
32611
32635
|
function formatStatuslineKeys(keys) {
|
|
32612
32636
|
return keys.map((key) => {
|
|
32613
|
-
const takes = key.kind === "choice" || key.kind === "list" || key.kind === "colour" ? `${key.kind} of ${key.choices.join(", ")}` : key.kind;
|
|
32637
|
+
const takes = key.kind === "choice" || key.kind === "list" || key.kind === "groups" || key.kind === "colour" ? `${key.kind} of ${key.choices.join(", ")}` : key.kind;
|
|
32614
32638
|
return `${key.path} (${takes}; ${key.optional ? "no default; none unsets it over shallower layers" : `default ${JSON.stringify(key.defaultValue)}`})
|
|
32615
32639
|
${key.description}`;
|
|
32616
32640
|
}).join("\n");
|
|
@@ -32662,6 +32686,8 @@ function parseStatuslineAssignment(text5) {
|
|
|
32662
32686
|
return { path: path70, value: /^\d+$/.test(raw) ? Number(raw) : raw };
|
|
32663
32687
|
case "list":
|
|
32664
32688
|
return { path: path70, value: raw === "" ? [] : raw.split(",") };
|
|
32689
|
+
case "groups":
|
|
32690
|
+
return { path: path70, value: raw === "" ? [] : raw.split(";").map((group) => group.split(",")) };
|
|
32665
32691
|
default:
|
|
32666
32692
|
return key.kind;
|
|
32667
32693
|
}
|
|
@@ -36952,7 +36978,7 @@ var init_package = __esm({
|
|
|
36952
36978
|
"package.json"() {
|
|
36953
36979
|
package_default = {
|
|
36954
36980
|
name: "claude-use",
|
|
36955
|
-
version: "11.
|
|
36981
|
+
version: "11.61.0",
|
|
36956
36982
|
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.",
|
|
36957
36983
|
license: "MIT",
|
|
36958
36984
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -116251,7 +116277,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
116251
116277
|
withExamples(
|
|
116252
116278
|
profile.command("set <name>").description(
|
|
116253
116279
|
"Update a configuration profile's categories, entries, extends list, description or launch settings. With no options on a terminal, walks through its categories."
|
|
116254
|
-
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").option("--launch-claude-version <version>", "Launches under this profile run exactly this installed Claude Code version (such as 2.1.220); a version that is not installed fails the launch.").option("--no-launch-claude-version", "Clear this profile's Claude Code version pin.").option("--launch-delay <duration>", "Launches under this profile wait this long (such as 5s) after the launcher's own output before starting claude, so the output can be read.", parseDurationLiteral).option("--no-launch-delay", "Clear this profile's launch delay.").option("--launch-pause", "Launches under this profile wait for a key press after the launcher's own output before starting claude.").option("--no-launch-pause", "Launches under this profile start claude without waiting for a key press.").option("--launch-explain", "Launches under this profile that pick from a pool list every member the pick ranked and why, in the launcher's report.").option("--no-launch-explain", "Launches under this profile name only the member a pool pick chose.").option("--launch-proxy-bypass <host>", "Launches under this profile keep this host off the front door by adding it to NO_PROXY, so its traffic goes direct (repeatable; replaces the profile's list).", collectRepeated).option("--no-launch-proxy-bypass", "Clear this profile's list of hosts kept off the front door.").option("--statusline <setting=value>", "Set one statusline setting for launches under this profile (repeatable; `agent-shim statusline keys` lists them; a list is comma-separated, and an empty value is the empty list).", collectRepeated).option("--unset-statusline <setting>", "Remove one statusline setting from this profile so the shallower layers or the default apply again (repeatable).", collectRepeated).option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
116280
|
+
).option("--category <category=bool>", "Share (true) or hide (false) a whole category (repeatable).", collectBoolPair).option("--entry <path=bool>", "Share (true) or hide (false) one <category>/<path> entry (repeatable).", collectBoolPair).option("--extends <profile>", "Replace the extends list with these profiles (repeatable, in order).", collectRepeated).option("--no-extends", "Clear the extends list.").option("--description <text>", "Replace the description.").option("--no-description", "Clear the description.").option("--launch-skip-permissions", "Launches under this profile skip permission prompts.").option("--no-launch-skip-permissions", "Launches under this profile keep permission prompts.").option("--launch-remote-control", "Launches under this profile enable Remote Control.").option("--no-launch-remote-control", "Launches under this profile leave Remote Control off.").option("--launch-headroom", "Launches under this profile route through headroom.").option("--no-launch-headroom", "Launches under this profile route direct.").option("--launch-track-usage", "Launches under this profile route through the front door so their requests and quota are recorded, with no headroom needed.").option("--no-launch-track-usage", "Launches under this profile are not recorded unless a provider or headroom routes them anyway.").option("--launch-provider <provider>", "Launches under this profile route through this provider.").option("--no-launch-provider", "Clear this profile's provider selection.").option("--launch-claude-version <version>", "Launches under this profile run exactly this installed Claude Code version (such as 2.1.220); a version that is not installed fails the launch.").option("--no-launch-claude-version", "Clear this profile's Claude Code version pin.").option("--launch-delay <duration>", "Launches under this profile wait this long (such as 5s) after the launcher's own output before starting claude, so the output can be read.", parseDurationLiteral).option("--no-launch-delay", "Clear this profile's launch delay.").option("--launch-pause", "Launches under this profile wait for a key press after the launcher's own output before starting claude.").option("--no-launch-pause", "Launches under this profile start claude without waiting for a key press.").option("--launch-explain", "Launches under this profile that pick from a pool list every member the pick ranked and why, in the launcher's report.").option("--no-launch-explain", "Launches under this profile name only the member a pool pick chose.").option("--launch-proxy-bypass <host>", "Launches under this profile keep this host off the front door by adding it to NO_PROXY, so its traffic goes direct (repeatable; replaces the profile's list).", collectRepeated).option("--no-launch-proxy-bypass", "Clear this profile's list of hosts kept off the front door.").option("--statusline <setting=value>", "Set one statusline setting for launches under this profile (repeatable; `agent-shim statusline keys` lists them; a list is comma-separated, a list of groups such as layout.merge is groups separated by semicolons with commas inside each group, and an empty value is the empty list).", collectRepeated).option("--unset-statusline <setting>", "Remove one statusline setting from this profile so the shallower layers or the default apply again (repeatable).", collectRepeated).option("--json", "Print the result as JSON.").action(async (name, allOptions) => {
|
|
116255
116281
|
const { json: json2, ...options } = allOptions;
|
|
116256
116282
|
requireProfileExists(paths, name);
|
|
116257
116283
|
if (Object.entries(allOptions).every(([key, value2]) => key === "json" || value2 === void 0)) {
|
|
@@ -138264,106 +138290,6 @@ function realStatuslinePorts(env, stateDirectory) {
|
|
|
138264
138290
|
// src/statusline/render.ts
|
|
138265
138291
|
init_statusline();
|
|
138266
138292
|
|
|
138267
|
-
// src/statusline/ansi.ts
|
|
138268
|
-
init_string_width();
|
|
138269
|
-
init_graphemes();
|
|
138270
|
-
var ESCAPE_CHAR_CODE = 27;
|
|
138271
|
-
var ESCAPE = String.fromCharCode(ESCAPE_CHAR_CODE);
|
|
138272
|
-
var BELL = "\\u0007";
|
|
138273
|
-
var ESCAPE_SEQUENCE_PATTERN = [`${ESCAPE}\\[[0-?]*[ -/]*[@-~]`, `${ESCAPE}\\][^${BELL}${ESCAPE}]*(?:${BELL}|${ESCAPE}\\\\)?`, `${ESCAPE}[@-Z\\\\-_]`].join("|");
|
|
138274
|
-
var SPLIT_ON_ESCAPES = new RegExp(`(${ESCAPE_SEQUENCE_PATTERN})`);
|
|
138275
|
-
function visibleLength(text5) {
|
|
138276
|
-
return stringWidth(text5);
|
|
138277
|
-
}
|
|
138278
|
-
function truncateToColumns(text5, columns) {
|
|
138279
|
-
let used = 0;
|
|
138280
|
-
let kept = "";
|
|
138281
|
-
text5.split(SPLIT_ON_ESCAPES).forEach((part, index) => {
|
|
138282
|
-
if (index % 2 === 1) {
|
|
138283
|
-
kept += part;
|
|
138284
|
-
return;
|
|
138285
|
-
}
|
|
138286
|
-
for (const grapheme of graphemesOf(part)) {
|
|
138287
|
-
used += visibleLength(grapheme);
|
|
138288
|
-
if (used > columns) {
|
|
138289
|
-
return;
|
|
138290
|
-
}
|
|
138291
|
-
kept += grapheme;
|
|
138292
|
-
}
|
|
138293
|
-
});
|
|
138294
|
-
return kept;
|
|
138295
|
-
}
|
|
138296
|
-
|
|
138297
|
-
// src/statusline/barGrid.ts
|
|
138298
|
-
var BRACKET_COLUMNS = 2;
|
|
138299
|
-
function chunk(items, size) {
|
|
138300
|
-
const chunks = [];
|
|
138301
|
-
for (let start = 0; start < items.length; start += size) {
|
|
138302
|
-
chunks.push(items.slice(start, start + size));
|
|
138303
|
-
}
|
|
138304
|
-
return chunks;
|
|
138305
|
-
}
|
|
138306
|
-
function lastColumnOf(index, rowLength, columns) {
|
|
138307
|
-
return index === rowLength - 1 ? columns - 1 : index;
|
|
138308
|
-
}
|
|
138309
|
-
function measureGrid(rows, separatorLength, baseBarCells) {
|
|
138310
|
-
const columns = Math.max(...rows.map((row) => row.length));
|
|
138311
|
-
const prefixWidths = Array.from({ length: columns }, () => 0);
|
|
138312
|
-
const suffixWidths = Array.from({ length: columns }, () => 0);
|
|
138313
|
-
for (const row of rows) {
|
|
138314
|
-
row.forEach((cell, index) => {
|
|
138315
|
-
const last = lastColumnOf(index, row.length, columns);
|
|
138316
|
-
prefixWidths[index] = Math.max(prefixWidths[index] ?? 0, visibleLength(cell.prefix));
|
|
138317
|
-
suffixWidths[last] = Math.max(suffixWidths[last] ?? 0, visibleLength(cell.suffix));
|
|
138318
|
-
});
|
|
138319
|
-
}
|
|
138320
|
-
const fixed = [...prefixWidths, ...suffixWidths].reduce((total, width) => total + width, 0) + columns * (baseBarCells + BRACKET_COLUMNS);
|
|
138321
|
-
return { rows, columns, prefixWidths, suffixWidths, baseWidth: fixed + separatorLength * (columns - 1) };
|
|
138322
|
-
}
|
|
138323
|
-
function padTo(text5, width) {
|
|
138324
|
-
return text5 + " ".repeat(Math.max(0, width - visibleLength(text5)));
|
|
138325
|
-
}
|
|
138326
|
-
function renderGrid(grid, maxWidth, separator, baseBarCells) {
|
|
138327
|
-
const separatorLength = visibleLength(separator);
|
|
138328
|
-
const spare = Math.max(0, maxWidth - grid.baseWidth);
|
|
138329
|
-
const barCells = Array.from({ length: grid.columns }, (_, column) => baseBarCells + Math.floor(spare / grid.columns) + (column < spare % grid.columns ? 1 : 0));
|
|
138330
|
-
const blockWidths = barCells.map((cells) => cells + BRACKET_COLUMNS);
|
|
138331
|
-
return grid.rows.map(
|
|
138332
|
-
(row) => row.map((cell, index) => {
|
|
138333
|
-
const last = lastColumnOf(index, row.length, grid.columns);
|
|
138334
|
-
let blockWidth = blockWidths[index] ?? 0;
|
|
138335
|
-
for (let column = index + 1; column <= last; column += 1) {
|
|
138336
|
-
blockWidth += separatorLength + (grid.suffixWidths[column - 1] ?? 0) + (grid.prefixWidths[column] ?? 0) + (blockWidths[column] ?? 0);
|
|
138337
|
-
}
|
|
138338
|
-
const prefix = padTo(cell.prefix, grid.prefixWidths[index] ?? 0);
|
|
138339
|
-
const bar = cell.draw(blockWidth - BRACKET_COLUMNS);
|
|
138340
|
-
const suffix = index === row.length - 1 ? cell.suffix : padTo(cell.suffix, grid.suffixWidths[last] ?? 0);
|
|
138341
|
-
return `${prefix}${bar}${suffix}`;
|
|
138342
|
-
}).join(separator)
|
|
138343
|
-
);
|
|
138344
|
-
}
|
|
138345
|
-
function layoutBarGrid(groups, maxWidth, separator, baseBarCells) {
|
|
138346
|
-
const nonEmpty = groups.filter((group) => group.length > 0);
|
|
138347
|
-
if (nonEmpty.length === 0) {
|
|
138348
|
-
return [];
|
|
138349
|
-
}
|
|
138350
|
-
const separatorLength = visibleLength(separator);
|
|
138351
|
-
const widest = Math.max(...nonEmpty.map((group) => group.length));
|
|
138352
|
-
const layoutFor = (perRow) => measureGrid(nonEmpty.flatMap((group) => chunk(group, perRow)), separatorLength, baseBarCells);
|
|
138353
|
-
const candidates = [measureGrid([nonEmpty.flat()], separatorLength, baseBarCells)];
|
|
138354
|
-
for (let perRow = widest; perRow > 1; perRow -= 1) {
|
|
138355
|
-
candidates.push(layoutFor(perRow));
|
|
138356
|
-
}
|
|
138357
|
-
const fitting = candidates.find((grid) => grid.baseWidth <= maxWidth);
|
|
138358
|
-
if (fitting !== void 0) {
|
|
138359
|
-
return renderGrid(fitting, maxWidth, separator, baseBarCells);
|
|
138360
|
-
}
|
|
138361
|
-
if (nonEmpty.length > 1) {
|
|
138362
|
-
return nonEmpty.flatMap((group) => layoutBarGrid([group], maxWidth, separator, baseBarCells));
|
|
138363
|
-
}
|
|
138364
|
-
return renderGrid(layoutFor(1), maxWidth, separator, baseBarCells);
|
|
138365
|
-
}
|
|
138366
|
-
|
|
138367
138293
|
// src/statusline/elements/header/account.ts
|
|
138368
138294
|
init_graphemes();
|
|
138369
138295
|
function tierSuffixOf(tier) {
|
|
@@ -138433,6 +138359,38 @@ function accountSegment({ summary, settings: settings2 }) {
|
|
|
138433
138359
|
|
|
138434
138360
|
// src/statusline/sanitise.ts
|
|
138435
138361
|
init_statusline();
|
|
138362
|
+
|
|
138363
|
+
// src/statusline/ansi.ts
|
|
138364
|
+
init_string_width();
|
|
138365
|
+
init_graphemes();
|
|
138366
|
+
var ESCAPE_CHAR_CODE = 27;
|
|
138367
|
+
var ESCAPE = String.fromCharCode(ESCAPE_CHAR_CODE);
|
|
138368
|
+
var BELL = "\\u0007";
|
|
138369
|
+
var ESCAPE_SEQUENCE_PATTERN = [`${ESCAPE}\\[[0-?]*[ -/]*[@-~]`, `${ESCAPE}\\][^${BELL}${ESCAPE}]*(?:${BELL}|${ESCAPE}\\\\)?`, `${ESCAPE}[@-Z\\\\-_]`].join("|");
|
|
138370
|
+
var SPLIT_ON_ESCAPES = new RegExp(`(${ESCAPE_SEQUENCE_PATTERN})`);
|
|
138371
|
+
function visibleLength(text5) {
|
|
138372
|
+
return stringWidth(text5);
|
|
138373
|
+
}
|
|
138374
|
+
function truncateToColumns(text5, columns) {
|
|
138375
|
+
let used = 0;
|
|
138376
|
+
let kept = "";
|
|
138377
|
+
text5.split(SPLIT_ON_ESCAPES).forEach((part, index) => {
|
|
138378
|
+
if (index % 2 === 1) {
|
|
138379
|
+
kept += part;
|
|
138380
|
+
return;
|
|
138381
|
+
}
|
|
138382
|
+
for (const grapheme of graphemesOf(part)) {
|
|
138383
|
+
used += visibleLength(grapheme);
|
|
138384
|
+
if (used > columns) {
|
|
138385
|
+
return;
|
|
138386
|
+
}
|
|
138387
|
+
kept += grapheme;
|
|
138388
|
+
}
|
|
138389
|
+
});
|
|
138390
|
+
return kept;
|
|
138391
|
+
}
|
|
138392
|
+
|
|
138393
|
+
// src/statusline/sanitise.ts
|
|
138436
138394
|
init_blank();
|
|
138437
138395
|
init_graphemes();
|
|
138438
138396
|
var ESCAPE_SEQUENCES = new RegExp(ESCAPE_SEQUENCE_PATTERN, "g");
|
|
@@ -138693,7 +138651,6 @@ var SECONDS_PER_DAY = 86400;
|
|
|
138693
138651
|
var THOUSAND = 1e3;
|
|
138694
138652
|
var MILLION = 1e6;
|
|
138695
138653
|
var TEN = 10;
|
|
138696
|
-
var TWENTY = 20;
|
|
138697
138654
|
var FULL_PERCENT3 = 100;
|
|
138698
138655
|
var ONE_PERCENT = 1;
|
|
138699
138656
|
function withColor(color, text5) {
|
|
@@ -140096,6 +140053,176 @@ function readTranscriptIdentity(ports, transcriptPath) {
|
|
|
140096
140053
|
return floor === 0 ? identityOfLine(decoder.decode(joined2(carry))) ?? NOT_FOUND : NOT_FOUND;
|
|
140097
140054
|
}
|
|
140098
140055
|
|
|
140056
|
+
// src/statusline/barGrid.ts
|
|
140057
|
+
var BRACKET_COLUMNS = 2;
|
|
140058
|
+
function chunk(items, size) {
|
|
140059
|
+
const chunks = [];
|
|
140060
|
+
for (let start = 0; start < items.length; start += size) {
|
|
140061
|
+
chunks.push(items.slice(start, start + size));
|
|
140062
|
+
}
|
|
140063
|
+
return chunks;
|
|
140064
|
+
}
|
|
140065
|
+
function lastColumnOf(index, rowLength, columns) {
|
|
140066
|
+
return index === rowLength - 1 ? columns - 1 : index;
|
|
140067
|
+
}
|
|
140068
|
+
function measureGrid(rows, separatorLength, baseBarCells) {
|
|
140069
|
+
const columns = Math.max(...rows.map((row) => row.length));
|
|
140070
|
+
const prefixWidths = Array.from({ length: columns }, () => 0);
|
|
140071
|
+
const suffixWidths = Array.from({ length: columns }, () => 0);
|
|
140072
|
+
for (const row of rows) {
|
|
140073
|
+
row.forEach((cell, index) => {
|
|
140074
|
+
const last = lastColumnOf(index, row.length, columns);
|
|
140075
|
+
prefixWidths[index] = Math.max(prefixWidths[index] ?? 0, visibleLength(cell.prefix));
|
|
140076
|
+
suffixWidths[last] = Math.max(suffixWidths[last] ?? 0, visibleLength(cell.suffix));
|
|
140077
|
+
});
|
|
140078
|
+
}
|
|
140079
|
+
const fixed = [...prefixWidths, ...suffixWidths].reduce((total, width) => total + width, 0) + columns * (baseBarCells + BRACKET_COLUMNS);
|
|
140080
|
+
return { rows, columns, prefixWidths, suffixWidths, baseWidth: fixed + separatorLength * (columns - 1) };
|
|
140081
|
+
}
|
|
140082
|
+
function padTo(text5, width) {
|
|
140083
|
+
return text5 + " ".repeat(Math.max(0, width - visibleLength(text5)));
|
|
140084
|
+
}
|
|
140085
|
+
function renderGrid(grid, maxWidth, separator, baseBarCells) {
|
|
140086
|
+
const separatorLength = visibleLength(separator);
|
|
140087
|
+
const spare = Math.max(0, maxWidth - grid.baseWidth);
|
|
140088
|
+
const barCells = Array.from({ length: grid.columns }, (_, column) => baseBarCells + Math.floor(spare / grid.columns) + (column < spare % grid.columns ? 1 : 0));
|
|
140089
|
+
const blockWidths = barCells.map((cells) => cells + BRACKET_COLUMNS);
|
|
140090
|
+
return grid.rows.map(
|
|
140091
|
+
(row) => row.map((cell, index) => {
|
|
140092
|
+
const last = lastColumnOf(index, row.length, grid.columns);
|
|
140093
|
+
let blockWidth = blockWidths[index] ?? 0;
|
|
140094
|
+
for (let column = index + 1; column <= last; column += 1) {
|
|
140095
|
+
blockWidth += separatorLength + (grid.suffixWidths[column - 1] ?? 0) + (grid.prefixWidths[column] ?? 0) + (blockWidths[column] ?? 0);
|
|
140096
|
+
}
|
|
140097
|
+
const prefix = padTo(cell.prefix, grid.prefixWidths[index] ?? 0);
|
|
140098
|
+
const bar = cell.draw(blockWidth - BRACKET_COLUMNS);
|
|
140099
|
+
const suffix = index === row.length - 1 ? cell.suffix : padTo(cell.suffix, grid.suffixWidths[last] ?? 0);
|
|
140100
|
+
return `${prefix}${bar}${suffix}`;
|
|
140101
|
+
}).join(separator)
|
|
140102
|
+
);
|
|
140103
|
+
}
|
|
140104
|
+
function drawInline(group, separator, baseBarCells) {
|
|
140105
|
+
return group.map((cell) => `${cell.prefix}${cell.draw(baseBarCells)}${cell.suffix}`).join(separator);
|
|
140106
|
+
}
|
|
140107
|
+
function layoutBarGrid(units, maxWidth, separator, baseBarCells) {
|
|
140108
|
+
const nonEmpty = units.map((unit) => unit.filter((group) => group.length > 0)).filter((unit) => unit.length > 0);
|
|
140109
|
+
if (nonEmpty.length === 0) {
|
|
140110
|
+
return [];
|
|
140111
|
+
}
|
|
140112
|
+
const separatorLength = visibleLength(separator);
|
|
140113
|
+
const groups = nonEmpty.flat();
|
|
140114
|
+
const candidates = [measureGrid(nonEmpty.map((unit) => unit.flat()), separatorLength, baseBarCells)];
|
|
140115
|
+
const chunked = (perRow) => measureGrid(groups.flatMap((group) => chunk(group, perRow)), separatorLength, baseBarCells);
|
|
140116
|
+
const fewest = nonEmpty.length > 1 ? 1 : 2;
|
|
140117
|
+
for (let perRow = Math.max(...groups.map((group) => group.length)); perRow >= fewest; perRow -= 1) {
|
|
140118
|
+
candidates.push(chunked(perRow));
|
|
140119
|
+
}
|
|
140120
|
+
const fitting = candidates.find((grid) => grid.baseWidth <= maxWidth);
|
|
140121
|
+
if (fitting !== void 0) {
|
|
140122
|
+
return renderGrid(fitting, maxWidth, separator, baseBarCells);
|
|
140123
|
+
}
|
|
140124
|
+
if (groups.length > 1) {
|
|
140125
|
+
return groups.flatMap((group) => layoutBarGrid([[group]], maxWidth, separator, baseBarCells));
|
|
140126
|
+
}
|
|
140127
|
+
return renderGrid(chunked(1), maxWidth, separator, baseBarCells);
|
|
140128
|
+
}
|
|
140129
|
+
|
|
140130
|
+
// src/statusline/rowsLayout.ts
|
|
140131
|
+
var BREAK = { kind: "lines", lines: [] };
|
|
140132
|
+
function isEmpty(output2) {
|
|
140133
|
+
return output2.kind === "bars" ? output2.cells.length === 0 : output2.lines.length === 0;
|
|
140134
|
+
}
|
|
140135
|
+
function oneLineOf(output2, barCells) {
|
|
140136
|
+
if (output2.kind === "bars") {
|
|
140137
|
+
return drawInline(output2.cells, SEPARATOR2, barCells);
|
|
140138
|
+
}
|
|
140139
|
+
return output2.lines.length === 1 ? output2.lines[0] : void 0;
|
|
140140
|
+
}
|
|
140141
|
+
function alignRight(lines, rightAlign, width) {
|
|
140142
|
+
const split = lines.findIndex(({ name }) => rightAlign.has(name));
|
|
140143
|
+
if (split < 1) {
|
|
140144
|
+
return void 0;
|
|
140145
|
+
}
|
|
140146
|
+
const left = lines.slice(0, split).map(({ text: text5 }) => text5).join(SEPARATOR2);
|
|
140147
|
+
const right = lines.slice(split).map(({ text: text5 }) => text5).join(SEPARATOR2);
|
|
140148
|
+
return `${left}${" ".repeat(width - visibleLength(left) - visibleLength(right))}${right}`;
|
|
140149
|
+
}
|
|
140150
|
+
function itemOf(row) {
|
|
140151
|
+
return row.output.kind === "bars" ? { kind: "bars", unit: [row.output.cells] } : { kind: "lines", lines: row.output.lines };
|
|
140152
|
+
}
|
|
140153
|
+
function mergedItems(rows, settings2, width) {
|
|
140154
|
+
const rightAlign = new Set(settings2.rightAlign);
|
|
140155
|
+
const aligned = rows.some((row, index) => index > 0 && rightAlign.has(row.name));
|
|
140156
|
+
if (!aligned && rows.every((row) => row.output.kind === "bars")) {
|
|
140157
|
+
return [{ kind: "bars", unit: rows.flatMap((row) => row.output.kind === "bars" ? [row.output.cells] : []) }];
|
|
140158
|
+
}
|
|
140159
|
+
const lines = rows.map((row) => ({ name: row.name, text: oneLineOf(row.output, settings2.barCells) }));
|
|
140160
|
+
const texts = lines.flatMap(({ name, text: text5 }) => text5 === void 0 ? [] : [{ name, text: text5 }]);
|
|
140161
|
+
if (texts.length === rows.length) {
|
|
140162
|
+
const joined3 = texts.map(({ text: text5 }) => text5).join(SEPARATOR2);
|
|
140163
|
+
if (visibleLength(joined3) <= width) {
|
|
140164
|
+
return [{ kind: "lines", lines: [alignRight(texts, rightAlign, width) ?? joined3] }];
|
|
140165
|
+
}
|
|
140166
|
+
}
|
|
140167
|
+
return rows.map(itemOf);
|
|
140168
|
+
}
|
|
140169
|
+
var BARS_RUN = -1;
|
|
140170
|
+
function runsOf(rows, settings2) {
|
|
140171
|
+
const groupOf2 = new Map(settings2.merge.flatMap((group, index) => group.map((name) => [name, index])));
|
|
140172
|
+
const keyOf3 = (row) => groupOf2.get(row.name) ?? (settings2.mergeBars && row.output.kind === "bars" ? BARS_RUN : void 0);
|
|
140173
|
+
const runs = [];
|
|
140174
|
+
const add = (key, row) => {
|
|
140175
|
+
const last = runs.at(-1);
|
|
140176
|
+
if (last !== void 0 && key !== void 0 && last.key === key) {
|
|
140177
|
+
last.rows.push(row);
|
|
140178
|
+
} else {
|
|
140179
|
+
runs.push({ key, rows: [row] });
|
|
140180
|
+
}
|
|
140181
|
+
};
|
|
140182
|
+
for (const row of rows) {
|
|
140183
|
+
add(keyOf3(row), row);
|
|
140184
|
+
}
|
|
140185
|
+
const silent = (run) => run.rows.every((row) => isEmpty(row.output) && row.output.kind === "bars");
|
|
140186
|
+
const kept = [];
|
|
140187
|
+
for (const run of runs.filter((candidate) => !silent(candidate))) {
|
|
140188
|
+
const last = kept.at(-1);
|
|
140189
|
+
if (last !== void 0 && run.key === BARS_RUN && last.key === BARS_RUN) {
|
|
140190
|
+
last.rows.push(...run.rows);
|
|
140191
|
+
} else {
|
|
140192
|
+
kept.push(run);
|
|
140193
|
+
}
|
|
140194
|
+
}
|
|
140195
|
+
return kept.map((run) => run.rows);
|
|
140196
|
+
}
|
|
140197
|
+
function layoutRows(rows, settings2, width) {
|
|
140198
|
+
const items = runsOf(rows, settings2).flatMap((run) => {
|
|
140199
|
+
const present = run.filter((row) => !isEmpty(row.output));
|
|
140200
|
+
if (present.length === 0) {
|
|
140201
|
+
return [BREAK];
|
|
140202
|
+
}
|
|
140203
|
+
return present.length > 1 ? mergedItems(present, settings2, width) : present.map(itemOf);
|
|
140204
|
+
});
|
|
140205
|
+
const lines = [];
|
|
140206
|
+
let units = [];
|
|
140207
|
+
const flushBars = () => {
|
|
140208
|
+
lines.push(...layoutBarGrid(units, width, SEPARATOR2, settings2.barCells));
|
|
140209
|
+
units = [];
|
|
140210
|
+
};
|
|
140211
|
+
for (const item of items) {
|
|
140212
|
+
if (item.kind === "bars") {
|
|
140213
|
+
units.push(item.unit);
|
|
140214
|
+
} else {
|
|
140215
|
+
flushBars();
|
|
140216
|
+
lines.push(...item.lines);
|
|
140217
|
+
}
|
|
140218
|
+
}
|
|
140219
|
+
flushBars();
|
|
140220
|
+
return lines;
|
|
140221
|
+
}
|
|
140222
|
+
function compactUnits(rows, barCells) {
|
|
140223
|
+
return rows.flatMap(({ output: output2 }) => output2.kind === "bars" ? output2.cells.map((cell) => drawInline([cell], SEPARATOR2, barCells)) : [...output2.lines]);
|
|
140224
|
+
}
|
|
140225
|
+
|
|
140099
140226
|
// src/statusline/transcript/reader.ts
|
|
140100
140227
|
var import_node_crypto27 = require("node:crypto");
|
|
140101
140228
|
init_zod();
|
|
@@ -140375,6 +140502,9 @@ function foldNewer(state, bytes, offset) {
|
|
|
140375
140502
|
|
|
140376
140503
|
// src/statusline/render.ts
|
|
140377
140504
|
var RESERVED_COLUMNS = 4;
|
|
140505
|
+
function lineWidthOf(terminalColumns) {
|
|
140506
|
+
return Math.max(MIN_STATUSLINE_COLUMNS, terminalColumns - RESERVED_COLUMNS);
|
|
140507
|
+
}
|
|
140378
140508
|
function once2(read) {
|
|
140379
140509
|
let kept;
|
|
140380
140510
|
return () => {
|
|
@@ -140382,9 +140512,14 @@ function once2(read) {
|
|
|
140382
140512
|
return kept.value;
|
|
140383
140513
|
};
|
|
140384
140514
|
}
|
|
140515
|
+
var RULE_CHARACTER = "\u2500";
|
|
140516
|
+
function ruleLine(headerLines, width, palette) {
|
|
140517
|
+
const widest = Math.max(MIN_STATUSLINE_COLUMNS, ...headerLines.map(visibleLength));
|
|
140518
|
+
return palette.paint("label", RULE_CHARACTER.repeat(Math.min(width, widest)));
|
|
140519
|
+
}
|
|
140385
140520
|
function renderStatuslineBlock(input2) {
|
|
140386
140521
|
const { terminalWidth, settings: settings2 = STATUSLINE_DEFAULTS, elements = ELEMENTS } = input2;
|
|
140387
|
-
const width =
|
|
140522
|
+
const width = input2.lineWidth ?? lineWidthOf(terminalWidth);
|
|
140388
140523
|
const context = {
|
|
140389
140524
|
summary: input2.summary,
|
|
140390
140525
|
view: input2.view,
|
|
@@ -140406,26 +140541,14 @@ function renderStatuslineBlock(input2) {
|
|
|
140406
140541
|
return text5 === void 0 ? [] : { name, text: context.palette.paint(HEADER_ROLES[name], text5) };
|
|
140407
140542
|
});
|
|
140408
140543
|
const header = headerUnits(parts, settings2.git.branchOverflow);
|
|
140409
|
-
const
|
|
140410
|
-
if (
|
|
140411
|
-
|
|
140412
|
-
}
|
|
140413
|
-
let barGroups = [];
|
|
140414
|
-
const flushBars = () => {
|
|
140415
|
-
lines.push(...layoutBarGrid(barGroups, width, SEPARATOR2, settings2.bar.width));
|
|
140416
|
-
barGroups = [];
|
|
140417
|
-
};
|
|
140418
|
-
for (const name of settings2.layout.rows) {
|
|
140419
|
-
const output2 = elements.rows[name](context);
|
|
140420
|
-
if (output2.kind === "bars") {
|
|
140421
|
-
barGroups.push(output2.cells);
|
|
140422
|
-
} else {
|
|
140423
|
-
flushBars();
|
|
140424
|
-
lines.push(...output2.lines);
|
|
140425
|
-
}
|
|
140544
|
+
const drawn = settings2.layout.rows.map((name) => ({ name, output: elements.rows[name](context) }));
|
|
140545
|
+
if (settings2.layout.mode === "compact") {
|
|
140546
|
+
return packLines([...header, ...compactUnits(drawn, settings2.bar.width)], width, SEPARATOR2).map((line) => line.join(SEPARATOR2)).join("\n");
|
|
140426
140547
|
}
|
|
140427
|
-
|
|
140428
|
-
|
|
140548
|
+
const headerLines = header.length > 0 ? layoutHeader(header, width, SEPARATOR2).split("\n") : [];
|
|
140549
|
+
const rowLines = layoutRows(drawn, { mergeBars: settings2.layout.mergeBars, merge: settings2.layout.merge, rightAlign: settings2.layout.rightAlign, barCells: settings2.bar.width }, width);
|
|
140550
|
+
const rule = settings2.layout.rule === "belowHeader" && headerLines.length > 0 && rowLines.length > 0 ? [ruleLine(headerLines, width, context.palette)] : [];
|
|
140551
|
+
return [...headerLines, ...rule, ...rowLines].join("\n");
|
|
140429
140552
|
}
|
|
140430
140553
|
|
|
140431
140554
|
// src/statusline/commands.ts
|
|
@@ -140433,13 +140556,22 @@ init_keys();
|
|
|
140433
140556
|
init_settings2();
|
|
140434
140557
|
|
|
140435
140558
|
// src/statusline/width.ts
|
|
140559
|
+
init_statusline();
|
|
140436
140560
|
var DEFAULT_COLUMNS = 80;
|
|
140437
|
-
function
|
|
140561
|
+
function widthsOf(payload, env, layout) {
|
|
140562
|
+
const configured = { terminal: layout.maxWidth, line: layout.maxWidth };
|
|
140563
|
+
if (layout.forceMaxWidth) {
|
|
140564
|
+
return configured;
|
|
140565
|
+
}
|
|
140566
|
+
const reported = (terminal) => ({ terminal, line: lineWidthOf(terminal) });
|
|
140438
140567
|
if (typeof payload === "object" && payload !== null && "terminal_width" in payload && typeof payload.terminal_width === "number" && Number.isFinite(payload.terminal_width) && payload.terminal_width > 0) {
|
|
140439
|
-
return Math.floor(payload.terminal_width);
|
|
140568
|
+
return reported(Math.floor(payload.terminal_width));
|
|
140440
140569
|
}
|
|
140441
140570
|
const columns = Number.parseInt(env.COLUMNS ?? "", 10);
|
|
140442
|
-
|
|
140571
|
+
if (Number.isFinite(columns) && columns > 0) {
|
|
140572
|
+
return reported(columns);
|
|
140573
|
+
}
|
|
140574
|
+
return layout.maxWidth >= MIN_STATUSLINE_COLUMNS ? configured : reported(DEFAULT_COLUMNS);
|
|
140443
140575
|
}
|
|
140444
140576
|
|
|
140445
140577
|
// src/statusline/commands.ts
|
|
@@ -140548,7 +140680,8 @@ function registerStatuslineCommand(program2, deps) {
|
|
|
140548
140680
|
}
|
|
140549
140681
|
}
|
|
140550
140682
|
const view = { ...viewOf(clientPayload), ...stackedUnderDefault ? { modelDisplayName: void 0 } : {} };
|
|
140551
|
-
|
|
140683
|
+
const widths = widthsOf(payload, process.env, settings2.layout);
|
|
140684
|
+
console.log(renderStatuslineBlock({ summary, view, payload: clientPayload, terminalWidth: widths.terminal, lineWidth: widths.line, nowMs, settings: settings2, ports: realStatuslinePorts(process.env, deps.paths.statuslineDir) }));
|
|
140552
140685
|
}),
|
|
140553
140686
|
["$ agent-shim statusline # a client's statusline setting names this; it renders or delegates"]
|
|
140554
140687
|
);
|
package/dist/index.cjs
CHANGED
|
@@ -289,9 +289,17 @@ function resolveStatusline(settings) {
|
|
|
289
289
|
if (forContext.warnAt >= forContext.criticalAt) {
|
|
290
290
|
throw new RangeError(`statusline context.warnAt (${String(forContext.warnAt)}) must be below context.criticalAt (${String(forContext.criticalAt)}), each following bands while it is unset`);
|
|
291
291
|
}
|
|
292
|
+
const merged = new Set(resolved.layout.merge.flat());
|
|
293
|
+
const unmerged = resolved.layout.rightAlign.filter((row) => !merged.has(row));
|
|
294
|
+
if (unmerged.length > 0) {
|
|
295
|
+
throw new RangeError(`statusline layout.rightAlign names ${unmerged.join(", ")}, which no group in layout.merge contains`);
|
|
296
|
+
}
|
|
297
|
+
if (resolved.layout.forceMaxWidth && resolved.layout.maxWidth === 0) {
|
|
298
|
+
throw new RangeError("statusline layout.forceMaxWidth needs layout.maxWidth to be set");
|
|
299
|
+
}
|
|
292
300
|
return resolved;
|
|
293
301
|
}
|
|
294
|
-
var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
302
|
+
var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, 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, labelText, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
295
303
|
var init_statusline = __esm({
|
|
296
304
|
"src/config/statusline.ts"() {
|
|
297
305
|
"use strict";
|
|
@@ -332,11 +340,17 @@ var init_statusline = __esm({
|
|
|
332
340
|
MAX_PERCENT = 100;
|
|
333
341
|
MAX_STATUSLINE_PALETTE_INDEX = 255;
|
|
334
342
|
MAX_STATUSLINE_LABEL_COLUMNS = 12;
|
|
343
|
+
MIN_STATUSLINE_COLUMNS = 20;
|
|
344
|
+
MAX_STATUSLINE_COLUMNS = 1e3;
|
|
335
345
|
MAX_BAR_CELLS = 40;
|
|
336
346
|
MAX_ACCOUNT_USER_CHARS = 254;
|
|
337
347
|
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
338
348
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
339
349
|
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
350
|
+
mergeGroups = import_zod2.z.array(distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).min(2)).refine((groups) => {
|
|
351
|
+
const rows = groups.flat();
|
|
352
|
+
return new Set(rows).size === rows.length;
|
|
353
|
+
}, "must not name a row in more than one group");
|
|
340
354
|
colourValue = import_zod2.z.union([import_zod2.z.enum(STATUSLINE_COLOUR_NAMES), import_zod2.z.number().int().min(0).max(MAX_STATUSLINE_PALETTE_INDEX), import_zod2.z.string().regex(/^#[0-9a-fA-F]{6}$/, "must be a colour name, a palette index from 0 to 255 or #rrggbb")]);
|
|
341
355
|
barCharacter = import_zod2.z.string().refine(isSingleVisibleGrapheme, "must be a single visible character that takes one terminal column");
|
|
342
356
|
STATUSLINE_CONTEXT_VALUES = ["both", "percent", "tokens", "remaining"];
|
|
@@ -351,7 +365,14 @@ var init_statusline = __esm({
|
|
|
351
365
|
SHAPES = {
|
|
352
366
|
layout: {
|
|
353
367
|
header: distinctList(import_zod2.z.enum(STATUSLINE_HEADER_SEGMENTS)).describe("The header segments to draw, in drawing order; a segment left out is hidden, and an empty list hides the header."),
|
|
354
|
-
rows: distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row.")
|
|
368
|
+
rows: distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).describe("The rows to draw below the header, in drawing order; a row left out is hidden, and an empty list hides every row."),
|
|
369
|
+
mode: import_zod2.z.enum(["expanded", "compact"]).describe("How the statusline is laid out: expanded draws the header and then the rows, each on lines of its own as layout.merge allows, and compact draws the header segments and every row's content on one line, starting a new line only where the line would be wider than the width. layout.mergeBars, layout.merge, layout.rightAlign and layout.rule have no effect in compact."),
|
|
370
|
+
rule: import_zod2.z.enum(["none", "belowHeader"]).describe(`Whether a rule is drawn across the line between the header and the rows beneath it, as wide as the header's widest line (at least ${String(MIN_STATUSLINE_COLUMNS)} columns, at most the width); it is drawn only when both the header and the rows have something to show, and not in the compact layout.`),
|
|
371
|
+
mergeBars: import_zod2.z.boolean().describe("Whether bar rows that sit next to each other in layout.rows share a line, and one grid, when they fit (the context and quota bars do by default); when false each bar row is on a line of its own, its bars still aligned to its neighbours'. A row of text is never joined by this setting, whichever form the quota row takes: layout.merge does that."),
|
|
372
|
+
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."),
|
|
373
|
+
rightAlign: distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).describe("Rows that start the right-aligned part of a merged line: the first of them to appear on a line, and the rows after it, are pushed to the right edge, with the gap padded by spaces. A row named here must belong to a group in layout.merge, and it has no effect when it is the first row of its line."),
|
|
374
|
+
maxWidth: import_zod2.z.number().int().min(0).max(MAX_STATUSLINE_COLUMNS).refine((columns) => columns === 0 || columns >= MIN_STATUSLINE_COLUMNS, `must be 0, or at least ${String(MIN_STATUSLINE_COLUMNS)} columns`).describe(`The exact width in columns lines are drawn to when the client reports none and the COLUMNS environment variable names none, in place of the default width it would assume for the terminal; unlike a terminal's width, it is not reduced by the columns Claude Code keeps back for itself. It is 0, to leave it unset, or from ${String(MIN_STATUSLINE_COLUMNS)} to ${String(MAX_STATUSLINE_COLUMNS)}; a value outside that is refused, not clamped.`),
|
|
375
|
+
forceMaxWidth: import_zod2.z.boolean().describe("Whether maxWidth is the exact width lines are drawn to for whatever the client reports, even when the terminal is narrower or wider; it needs maxWidth to be set.")
|
|
355
376
|
},
|
|
356
377
|
model: {
|
|
357
378
|
format: import_zod2.z.enum(["full", "compact", "short"]).describe("How the model's name is written: full is the name as the client gives it, compact drops a context-window suffix such as (1M context), and short also drops a leading Claude."),
|
|
@@ -497,7 +518,7 @@ var init_statusline = __esm({
|
|
|
497
518
|
jj: import_zod2.z.strictObject(SHAPES.jj)
|
|
498
519
|
});
|
|
499
520
|
STATUSLINE_DEFAULTS = {
|
|
500
|
-
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS] },
|
|
521
|
+
layout: { header: [...DEFAULT_HEADER_SEGMENTS], rows: [...DEFAULT_ROWS], mode: "expanded", rule: "none", mergeBars: true, merge: [], rightAlign: [], maxWidth: 0, forceMaxWidth: false },
|
|
501
522
|
model: { format: "full", override: "", source: "client" },
|
|
502
523
|
provider: { name: "" },
|
|
503
524
|
account: { parts: ["user", "organisation", "plan"], userLength: 0 },
|
|
@@ -4577,7 +4598,7 @@ var init_package = __esm({
|
|
|
4577
4598
|
"package.json"() {
|
|
4578
4599
|
package_default = {
|
|
4579
4600
|
name: "claude-use",
|
|
4580
|
-
version: "11.
|
|
4601
|
+
version: "11.61.0",
|
|
4581
4602
|
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.",
|
|
4582
4603
|
license: "MIT",
|
|
4583
4604
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -7815,6 +7836,9 @@ function keyOf(path41, declared) {
|
|
|
7815
7836
|
if (leaf instanceof import_zod16.z.ZodArray && leaf.element instanceof import_zod16.z.ZodEnum) {
|
|
7816
7837
|
return { ...common, kind: "list", choices: Object.values(leaf.element.enum).map(String) };
|
|
7817
7838
|
}
|
|
7839
|
+
if (leaf instanceof import_zod16.z.ZodArray && leaf.element instanceof import_zod16.z.ZodArray && leaf.element.element instanceof import_zod16.z.ZodEnum) {
|
|
7840
|
+
return { ...common, kind: "groups", choices: Object.values(leaf.element.element.enum).map(String) };
|
|
7841
|
+
}
|
|
7818
7842
|
throw new TypeError(`statusline setting ${path41.join(".")} has a kind the key listing does not describe`);
|
|
7819
7843
|
}
|
|
7820
7844
|
function walk(shape, prefix) {
|