claude-use 11.63.0 → 11.64.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 CHANGED
@@ -25490,7 +25490,7 @@ var init_statusline = __esm({
25490
25490
  init_graphemes();
25491
25491
  init_languages();
25492
25492
  STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed"];
25493
- STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens"];
25493
+ STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens", "tools", "skills", "mcp", "agents", "todos"];
25494
25494
  STATUSLINE_SESSION_TIME_PARTS = ["started", "lastReply"];
25495
25495
  PROMPT_CACHE_TTL_SECONDS = { fiveMinutes: 300, oneHour: 3600 };
25496
25496
  STATUSLINE_COLOUR_NAMES = [
@@ -25521,13 +25521,13 @@ var init_statusline = __esm({
25521
25521
  PRESET_BUNDLES = {
25522
25522
  standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
25523
25523
  full: {
25524
- layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "promptCache", "compactions", "tokens"] },
25524
+ layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
25525
25525
  git: GIT_WITH_DIRTY_MARKER,
25526
25526
  jj: { enabled: true, showDirty: true, showConflicts: true },
25527
25527
  usage: { resetLabel: true },
25528
25528
  context: { breakdown: "critical" }
25529
25529
  },
25530
- essential: { layout: { header: ["model", "project", "vcs", "duration"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
25530
+ essential: { layout: { header: ["model", "project", "vcs", "duration"], rows: ["context", "addedDirs", "tools", "agents", "todos"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
25531
25531
  minimal: { layout: { header: ["model", "project", "vcs"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
25532
25532
  };
25533
25533
  STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
@@ -25643,6 +25643,10 @@ var init_statusline = __esm({
25643
25643
  promptCache: {
25644
25644
  ttlSeconds: external_exports.number().int().min(1).describe("How long the prompt cache lives, in seconds, when the transcript has not yet shown which tier the session writes (five minutes or one hour); the tier the transcript shows takes over once it does.")
25645
25645
  },
25646
+ tools: {
25647
+ nameMaxLength: external_exports.number().int().min(0).describe("The most terminal columns of a tool's name the tools row draws, cut with an ellipsis. With a limit set, a tool of an MCP server is shown by its own name, without the server's, whether or not it needs cutting. 0 draws every name whole, an MCP tool's with its server."),
25648
+ 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.")
25649
+ },
25646
25650
  colours: {
25647
25651
  context: colourValue.describe("The colour of the context bar and its figures below the warning threshold."),
25648
25652
  usage: colourValue.describe("The colour of the quota bars and their figures below the warning threshold."),
@@ -25654,7 +25658,9 @@ var init_statusline = __esm({
25654
25658
  empty: colourValue.describe("The colour of the unused part of a bar."),
25655
25659
  project: colourValue.describe("The colour of the project path segment."),
25656
25660
  git: colourValue.describe("The colour of the version control segment's wrapper text (`git:(` and `)`)."),
25657
- gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers.")
25661
+ gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers."),
25662
+ activity: colourValue.describe("The colour of the names of the tools, skills and MCP servers the tools, skills and mcp rows draw. Their running markers take colours.warning and their finished markers colours.context."),
25663
+ agent: colourValue.describe("The colour of an agent's type in the agents row.")
25658
25664
  },
25659
25665
  project: {
25660
25666
  pathLevels: external_exports.enum(STATUSLINE_PATH_LEVELS).describe("How many trailing directories of the working directory the project segment shows: 1, 2 or 3, or full for the whole absolute path."),
@@ -25681,7 +25687,7 @@ var init_statusline = __esm({
25681
25687
  LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
25682
25688
  TOP_LEVEL = {
25683
25689
  language: external_exports.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
25684
- 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 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, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration and the added directories row, and minimal adds the added directories row alone.")
25690
+ 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 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.")
25685
25691
  };
25686
25692
  StatuslineSchema = external_exports.strictObject({
25687
25693
  language: external_exports.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
@@ -25702,6 +25708,7 @@ var init_statusline = __esm({
25702
25708
  environment: external_exports.strictObject(SHAPES.environment).partial().optional(),
25703
25709
  sessionTime: external_exports.strictObject(SHAPES.sessionTime).partial().optional(),
25704
25710
  promptCache: external_exports.strictObject(SHAPES.promptCache).partial().optional(),
25711
+ tools: external_exports.strictObject(SHAPES.tools).partial().optional(),
25705
25712
  colours: external_exports.strictObject(SHAPES.colours).partial().optional(),
25706
25713
  project: external_exports.strictObject(SHAPES.project).partial().optional(),
25707
25714
  git: external_exports.strictObject(SHAPES.git).partial().optional(),
@@ -25726,6 +25733,7 @@ var init_statusline = __esm({
25726
25733
  environment: external_exports.strictObject(SHAPES.environment),
25727
25734
  sessionTime: external_exports.strictObject(SHAPES.sessionTime),
25728
25735
  promptCache: external_exports.strictObject(SHAPES.promptCache),
25736
+ tools: external_exports.strictObject(SHAPES.tools),
25729
25737
  colours: external_exports.strictObject(SHAPES.colours),
25730
25738
  project: external_exports.strictObject(SHAPES.project),
25731
25739
  git: external_exports.strictObject(SHAPES.git),
@@ -25750,6 +25758,7 @@ var init_statusline = __esm({
25750
25758
  environment: { threshold: 0 },
25751
25759
  sessionTime: { parts: [...STATUSLINE_SESSION_TIME_PARTS] },
25752
25760
  promptCache: { ttlSeconds: PROMPT_CACHE_TTL_SECONDS.fiveMinutes },
25761
+ tools: { nameMaxLength: 0, maxVisible: 4 },
25753
25762
  colours: {
25754
25763
  context: "green",
25755
25764
  usage: "green",
@@ -25761,7 +25770,9 @@ var init_statusline = __esm({
25761
25770
  empty: "brightBlack",
25762
25771
  project: "yellow",
25763
25772
  git: "magenta",
25764
- gitBranch: "cyan"
25773
+ gitBranch: "cyan",
25774
+ activity: "cyan",
25775
+ agent: "magenta"
25765
25776
  },
25766
25777
  project: { pathLevels: "1", addedDirsLayout: "inline" },
25767
25778
  git: { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false, branchOverflow: "truncate", pushWarnAt: 0, pushCriticalAt: 0 },
@@ -28902,17 +28913,17 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
28902
28913
  nextId += 1;
28903
28914
  const id2 = nextId;
28904
28915
  append({ kind: "stream", id: id2, host });
28905
- const stored = { "client-to-server": 0, "server-to-client": 0 };
28916
+ const stored2 = { "client-to-server": 0, "server-to-client": 0 };
28906
28917
  const sequences = { "client-to-server": 0, "server-to-client": 0 };
28907
28918
  return {
28908
28919
  onChunk: (direction, chunk2) => {
28909
28920
  sequences[direction] += 1;
28910
- const budget = STREAM_LOG_CAP_BYTES - stored[direction];
28921
+ const budget = STREAM_LOG_CAP_BYTES - stored2[direction];
28911
28922
  if (budget <= 0) {
28912
28923
  return;
28913
28924
  }
28914
28925
  const excerpt2 = chunk2.subarray(0, Math.min(CHUNK_LOG_CAP_BYTES, budget));
28915
- stored[direction] += excerpt2.length;
28926
+ stored2[direction] += excerpt2.length;
28916
28927
  const text5 = excerpt2.toString("utf8");
28917
28928
  const faithful = Buffer.from(text5, "utf8").equals(excerpt2);
28918
28929
  append({
@@ -28927,7 +28938,7 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
28927
28938
  });
28928
28939
  },
28929
28940
  onEnd: () => {
28930
- append({ kind: "stream-end", id: id2, clientToServerCapped: stored["client-to-server"] >= STREAM_LOG_CAP_BYTES, serverToClientCapped: stored["server-to-client"] >= STREAM_LOG_CAP_BYTES });
28941
+ append({ kind: "stream-end", id: id2, clientToServerCapped: stored2["client-to-server"] >= STREAM_LOG_CAP_BYTES, serverToClientCapped: stored2["server-to-client"] >= STREAM_LOG_CAP_BYTES });
28931
28942
  }
28932
28943
  };
28933
28944
  },
@@ -37073,7 +37084,7 @@ var init_package = __esm({
37073
37084
  "package.json"() {
37074
37085
  package_default = {
37075
37086
  name: "claude-use",
37076
- version: "11.63.0",
37087
+ version: "11.64.0",
37077
37088
  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.",
37078
37089
  license: "MIT",
37079
37090
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -69813,15 +69824,15 @@ function createQuotaRefresher(deps) {
69813
69824
  if (failed !== void 0 && deps.now() - failed < QUOTA_REQUEST_TIMEOUT_MS) {
69814
69825
  return { status: "fresh" };
69815
69826
  }
69816
- let stored;
69827
+ let stored2;
69817
69828
  try {
69818
- stored = deps.readQuota(identity, provider);
69829
+ stored2 = deps.readQuota(identity, provider);
69819
69830
  } catch (error63) {
69820
69831
  const message = describeError2(error63);
69821
69832
  deps.log(`usage: quota refresh for ${identity} via ${provider} failed: ${message}`);
69822
69833
  return { status: "failed", message };
69823
69834
  }
69824
- if (stored !== void 0 && deps.now() - Date.parse(stored.observedAt) < quotaFreshnessMs(stored)) {
69835
+ if (stored2 !== void 0 && deps.now() - Date.parse(stored2.observedAt) < quotaFreshnessMs(stored2)) {
69825
69836
  return { status: "fresh" };
69826
69837
  }
69827
69838
  }
@@ -114009,8 +114020,8 @@ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
114009
114020
  var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
114010
114021
  var getStringTruncatedWidth = (input2, truncationOptions = {}, widthOptions = {}) => {
114011
114022
  const LIMIT = truncationOptions.limit ?? Infinity;
114012
- const ELLIPSIS = truncationOptions.ellipsis ?? "";
114013
- const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
114023
+ const ELLIPSIS2 = truncationOptions.ellipsis ?? "";
114024
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS2 ? getStringTruncatedWidth(ELLIPSIS2, NO_TRUNCATION, widthOptions).width : 0);
114014
114025
  const ANSI_WIDTH = 0;
114015
114026
  const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
114016
114027
  const TAB_WIDTH = widthOptions.tabWidth ?? 8;
@@ -131194,8 +131205,8 @@ function createConfigApiRouter(deps) {
131194
131205
  ...input2.codex === void 0 ? {} : { codex: input2.codex }
131195
131206
  });
131196
131207
  const cache = input2.credential.cache;
131197
- const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input2.name, { cache });
131198
- return { action: "created", kind: "provider", name: input2.name, value: providerValue(input2.name, stored) };
131208
+ const stored2 = cache === void 0 || cache === false ? created : updateProvider(paths, input2.name, { cache });
131209
+ return { action: "created", kind: "provider", name: input2.name, value: providerValue(input2.name, stored2) };
131199
131210
  })
131200
131211
  ),
131201
131212
  set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
@@ -138849,6 +138860,19 @@ function accountSegment({ summary, settings: settings2 }) {
138849
138860
  return namesLogin && shown.length > 0 ? shown.join(" \xB7 ") : void 0;
138850
138861
  }
138851
138862
 
138863
+ // src/statusline/modelId.ts
138864
+ var MODEL_ID = /^(?:claude-)?(?:(\d{1,2})(?:-(\d{1,2}))?-)?(opus|sonnet|haiku)(?:-(\d{1,2})(?:-(\d{1,2}))?)?(?:-\d{8})?$/i;
138865
+ function parseClaudeModelId(id2) {
138866
+ const match = MODEL_ID.exec(id2);
138867
+ if (match === null) {
138868
+ return void 0;
138869
+ }
138870
+ const [, leadingMajor, leadingMinor, family = "", trailingMajor, trailingMinor] = match;
138871
+ const major = leadingMajor ?? trailingMajor;
138872
+ const minor = leadingMajor === void 0 ? trailingMinor : leadingMinor;
138873
+ return { family: family.toLowerCase(), version: major === void 0 ? void 0 : `${major}${minor === void 0 ? "" : `.${minor}`}` };
138874
+ }
138875
+
138852
138876
  // src/statusline/sanitise.ts
138853
138877
  init_statusline();
138854
138878
 
@@ -138881,6 +138905,12 @@ function truncateToColumns(text5, columns) {
138881
138905
  });
138882
138906
  return kept;
138883
138907
  }
138908
+ function truncateWithEllipsis(text5, columns, ellipsis) {
138909
+ if (visibleLength(text5) <= columns) {
138910
+ return text5;
138911
+ }
138912
+ return `${truncateToColumns(text5, Math.max(0, columns - visibleLength(ellipsis)))}${ellipsis}`;
138913
+ }
138884
138914
 
138885
138915
  // src/statusline/sanitise.ts
138886
138916
  init_blank();
@@ -138908,17 +138938,12 @@ function visibleDisplayText(text5) {
138908
138938
  }
138909
138939
 
138910
138940
  // src/statusline/elements/header/advisor.ts
138911
- var MODEL_ID = /^(?:claude-)?(?:(\d{1,2})(?:-(\d{1,2}))?-)?(opus|sonnet|haiku)(?:-(\d{1,2})(?:-(\d{1,2}))?)?(?:-\d{8})?$/i;
138912
138941
  function prettifyModelId(id2) {
138913
- const match = MODEL_ID.exec(id2);
138914
- if (match === null) {
138942
+ const model = parseClaudeModelId(id2);
138943
+ if (model === void 0) {
138915
138944
  return id2.replace(/^claude-/i, "");
138916
138945
  }
138917
- const [, leadingMajor, leadingMinor, family = "", trailingMajor, trailingMinor] = match;
138918
- const major = leadingMajor ?? trailingMajor;
138919
- const minor = leadingMajor === void 0 ? trailingMinor : leadingMinor;
138920
- const version2 = major === void 0 ? "" : ` ${major}${minor === void 0 ? "" : `.${minor}`}`;
138921
- return `${family.charAt(0).toUpperCase()}${family.slice(1).toLowerCase()}${version2}`;
138946
+ return `${model.family.charAt(0).toUpperCase()}${model.family.slice(1)}${model.version === void 0 ? "" : ` ${model.version}`}`;
138922
138947
  }
138923
138948
  function advisorSegment({ settings: settings2, transcriptIdentity, t: t10 }) {
138924
138949
  if (settings2.advisor.override !== "") {
@@ -139069,6 +139094,20 @@ function formatElapsed(ms2) {
139069
139094
  }
139070
139095
  return `${String(Math.floor(minutes / MINUTES_PER_HOUR4))}h ${String(minutes % MINUTES_PER_HOUR4)}m`;
139071
139096
  }
139097
+ function formatSpan(ms2) {
139098
+ if (ms2 < MS_PER_SECOND18) {
139099
+ return "<1s";
139100
+ }
139101
+ const seconds = Math.floor(ms2 / MS_PER_SECOND18);
139102
+ if (seconds < SECONDS_PER_MINUTE2) {
139103
+ return `${String(seconds)}s`;
139104
+ }
139105
+ const minutes = Math.floor(seconds / SECONDS_PER_MINUTE2);
139106
+ if (minutes < MINUTES_PER_HOUR4) {
139107
+ return `${String(minutes)}m ${String(seconds % SECONDS_PER_MINUTE2)}s`;
139108
+ }
139109
+ return `${String(Math.floor(minutes / MINUTES_PER_HOUR4))}h ${String(minutes % MINUTES_PER_HOUR4)}m`;
139110
+ }
139072
139111
  function twoUnits(larger2, smaller, largerUnit, smallerUnit) {
139073
139112
  return smaller > 0 ? `${String(larger2)}${largerUnit} ${String(smaller)}${smallerUnit}` : `${String(larger2)}${largerUnit}`;
139074
139113
  }
@@ -139495,8 +139534,8 @@ function speedBetween(previous, current) {
139495
139534
  }
139496
139535
  function trackSpeed(ports, transcriptPath, current) {
139497
139536
  const file2 = cacheFileFor(ports, CACHE_KIND, transcriptPath);
139498
- const { tokensPerSecond, remember } = speedBetween(loadCache(ports, file2, SpeedSampleSchema), current);
139499
- if (remember) {
139537
+ const { tokensPerSecond, remember: remember2 } = speedBetween(loadCache(ports, file2, SpeedSampleSchema), current);
139538
+ if (remember2) {
139500
139539
  saveCache(ports, file2, current, current.at);
139501
139540
  }
139502
139541
  return tokensPerSecond;
@@ -139806,20 +139845,19 @@ function aroundValue(message, value2, paint) {
139806
139845
  }
139807
139846
  return `${paintCore(before, paint)}${value2}${paintCore(after, paint)}`;
139808
139847
  }
139809
- function marked(t10, id2) {
139810
- switch (id2) {
139811
- case "sessionTime.started":
139812
- return t10(id2, { time: VALUE_MARK });
139813
- case "sessionTime.lastReply":
139814
- return t10(id2, { ago: VALUE_MARK });
139815
- case "addedDirs.label":
139816
- return t10(id2, { dirs: VALUE_MARK });
139817
- default:
139818
- return id2;
139848
+ var AROUND_MESSAGES = {
139849
+ "sessionTime.started": { counted: false, write: (t10, mark) => t10("sessionTime.started", { time: mark }) },
139850
+ "sessionTime.lastReply": { counted: false, write: (t10, mark) => t10("sessionTime.lastReply", { ago: mark }) },
139851
+ "addedDirs.label": { counted: false, write: (t10, mark) => t10("addedDirs.label", { dirs: mark }) },
139852
+ "skills.label": { counted: true, write: (t10, mark, count2) => t10("skills.label", { count: count2, names: mark }) },
139853
+ "mcp.label": { counted: true, write: (t10, mark, count2) => t10("mcp.label", { count: count2, names: mark }) }
139854
+ };
139855
+ function writeAround(t10, id2, value2, paint, count2) {
139856
+ const message = AROUND_MESSAGES[id2];
139857
+ if (message.counted && count2 === void 0) {
139858
+ throw new TypeError(`message "${id2}" names a count, and none was given`);
139819
139859
  }
139820
- }
139821
- function writeAround(t10, id2, value2, paint) {
139822
- return aroundValue(marked(t10, id2), value2, paint);
139860
+ return aroundValue(message.write(t10, VALUE_MARK, count2 ?? ""), value2, paint);
139823
139861
  }
139824
139862
 
139825
139863
  // src/statusline/elements/rows/addedDirs.ts
@@ -139833,6 +139871,159 @@ function addedDirsRow({ payload, settings: settings2, palette, t: t10 }) {
139833
139871
  return { kind: "text", lines: [writeAround(t10, "addedDirs.label", drawn.join(label2(t10("list.separator"))), label2)] };
139834
139872
  }
139835
139873
 
139874
+ // src/statusline/headerLayout.ts
139875
+ var SEPARATOR2 = " | ";
139876
+ function headerUnits(parts, overflow) {
139877
+ const units = [];
139878
+ parts.forEach((part, index) => {
139879
+ const before = parts[index - 1];
139880
+ if (overflow === "truncate" && part.name === "vcs" && before?.name === "project") {
139881
+ units[units.length - 1] = `${units.at(-1) ?? ""} ${part.text}`;
139882
+ } else {
139883
+ units.push(part.text);
139884
+ }
139885
+ });
139886
+ return units;
139887
+ }
139888
+ function justify(texts, maxWidth, separator) {
139889
+ if (texts.length < 2) {
139890
+ return texts.join(separator);
139891
+ }
139892
+ const separatorLength = visibleLength(separator);
139893
+ const total = texts.reduce((sum2, text5) => sum2 + visibleLength(text5), 0) + separatorLength * (texts.length - 1);
139894
+ const spare = maxWidth - total;
139895
+ if (spare <= 0) {
139896
+ return texts.join(separator);
139897
+ }
139898
+ const gaps = texts.length - 1;
139899
+ const extraPerGap = Math.floor(spare / gaps);
139900
+ let remainder = spare % gaps;
139901
+ const parts = [];
139902
+ texts.forEach((text5, index) => {
139903
+ if (index > 0) {
139904
+ const extra = extraPerGap + (remainder > 0 ? 1 : 0);
139905
+ if (remainder > 0) {
139906
+ remainder -= 1;
139907
+ }
139908
+ const left = Math.floor(extra / 2);
139909
+ parts.push(`${" ".repeat(left + 1)}|${" ".repeat(extra - left + 1)}`);
139910
+ }
139911
+ parts.push(text5);
139912
+ });
139913
+ return parts.join("");
139914
+ }
139915
+ function packLines(texts, maxWidth, separator) {
139916
+ const separatorLength = visibleLength(separator);
139917
+ const lines = [];
139918
+ let current = [];
139919
+ let currentWidth = 0;
139920
+ for (const text5 of texts) {
139921
+ const width = visibleLength(text5);
139922
+ const added = current.length === 0 ? width : width + separatorLength;
139923
+ if (current.length > 0 && currentWidth + added > maxWidth) {
139924
+ lines.push(current);
139925
+ current = [text5];
139926
+ currentWidth = width;
139927
+ } else {
139928
+ current.push(text5);
139929
+ currentWidth += added;
139930
+ }
139931
+ }
139932
+ if (current.length > 0) {
139933
+ lines.push(current);
139934
+ }
139935
+ return lines;
139936
+ }
139937
+ function layoutHeader(texts, maxWidth, separator) {
139938
+ return packLines(texts, maxWidth, separator).map((line) => justify(line, maxWidth, separator)).join("\n");
139939
+ }
139940
+
139941
+ // src/statusline/elements/rows/activityParts.ts
139942
+ var RUNNING_MARK = "\u25D0";
139943
+ var DONE_MARK = "\u2713";
139944
+ var ACTIVE_MARK = "\u25B8";
139945
+ var ELLIPSIS = "\u2026";
139946
+ var MAX_NAME_COLUMNS = 64;
139947
+ var MAX_NAMES_SHOWN = 4;
139948
+ var NO_LINES = { kind: "text", lines: [] };
139949
+ function markedLine(t10, mark, text5) {
139950
+ return t10("mark.line", { mark, text: text5 });
139951
+ }
139952
+ function markColumns(t10) {
139953
+ return visibleLength(markedLine(t10, DONE_MARK, ""));
139954
+ }
139955
+ function fitToWidth(line, width) {
139956
+ return truncateWithEllipsis(line, width, ELLIPSIS);
139957
+ }
139958
+ function columnsLeft(width, used) {
139959
+ return Math.max(1, width - used);
139960
+ }
139961
+ function nameListRow(id2, facts, complete, { palette, width, t: t10 }) {
139962
+ if (facts.names.length === 0) {
139963
+ return NO_LINES;
139964
+ }
139965
+ const label2 = (text5) => palette.paint("label", text5);
139966
+ const plain = (text5) => text5;
139967
+ const countText = `${String(facts.total)}${complete && facts.exact ? "" : "+"}`;
139968
+ const count2 = label2(t10("list.count", { count: countText }));
139969
+ const mark = palette.paint("context", DONE_MARK);
139970
+ const headColumns = visibleLength(markedLine(t10, DONE_MARK, writeAround(t10, id2, "", plain, t10("list.count", { count: countText }))));
139971
+ const paintName = (name, columns) => palette.paint("activity", truncateWithEllipsis(name, columns, ELLIPSIS));
139972
+ const [firstName = "", ...otherNames] = facts.names.slice(0, MAX_NAMES_SHOWN);
139973
+ const first = paintName(firstName, Math.min(MAX_NAME_COLUMNS, columnsLeft(width, headColumns)));
139974
+ const rest = otherNames.map((name) => paintName(name, Math.min(MAX_NAME_COLUMNS, width)));
139975
+ const hidden = facts.total - 1 - rest.length;
139976
+ const items = [...rest, ...hidden > 0 ? [label2(t10("more", { count: hidden }))] : []];
139977
+ const head = markedLine(t10, mark, writeAround(t10, id2, first, plain, count2));
139978
+ const separator = t10("list.separator");
139979
+ return { kind: "text", lines: packLines([head, ...items], width, separator).map((line) => fitToWidth(line.join(separator), width)) };
139980
+ }
139981
+
139982
+ // src/statusline/elements/rows/agents.ts
139983
+ var MAX_AGENTS_SHOWN = 3;
139984
+ var MAX_RECENT_FINISHED = 2;
139985
+ var FINISHED_RETENTION_MS = 6e4;
139986
+ var TYPE_COLUMNS = 24;
139987
+ var DESCRIPTION_COLUMNS = 40;
139988
+ var BRACKETED_SUFFIX = /\[[^\]]*\]$/;
139989
+ function modelLabel(model) {
139990
+ const id2 = model?.replace(BRACKETED_SUFFIX, "").trim();
139991
+ if (id2 === void 0 || id2 === "" || /^claude-$/i.test(id2)) {
139992
+ return void 0;
139993
+ }
139994
+ const parsed = parseClaudeModelId(id2);
139995
+ return parsed === void 0 ? id2 : `${parsed.family}${parsed.version === void 0 ? "" : `-${parsed.version}`}`;
139996
+ }
139997
+ function agentsShown(agents, nowMs) {
139998
+ const running = agents.filter((agent) => agent.status === "running").slice(-MAX_AGENTS_SHOWN);
139999
+ const slots = Math.min(MAX_RECENT_FINISHED, MAX_AGENTS_SHOWN - running.length);
140000
+ const recent = agents.filter((agent) => agent.status === "completed" && agent.endedAtMs !== void 0 && agent.endedAtMs <= nowMs && nowMs - agent.endedAtMs <= FINISHED_RETENTION_MS);
140001
+ return [...running, ...slots > 0 ? recent.slice(-slots) : []];
140002
+ }
140003
+ var DESCRIPTION_ELLIPSIS = "...";
140004
+ var MIN_DESCRIPTION_COLUMNS = DESCRIPTION_ELLIPSIS.length + 1;
140005
+ function agentLine(agent, context) {
140006
+ const { palette, nowMs, width, t: t10 } = context;
140007
+ const marker = agent.status === "running" ? palette.paint("warning", RUNNING_MARK) : palette.paint("context", DONE_MARK);
140008
+ const elapsed = formatSpan(Math.max(0, (agent.endedAtMs ?? nowMs) - (agent.startedAtMs ?? nowMs)));
140009
+ const timeText = t10("agents.elapsed", { time: elapsed });
140010
+ const fixed = markColumns(t10) + visibleLength(timeText);
140011
+ const type2 = truncateWithEllipsis(agent.type ?? t10("agents.defaultType"), Math.min(TYPE_COLUMNS, Math.max(1, width - fixed)), ELLIPSIS);
140012
+ const model = modelLabel(agent.model);
140013
+ const modelText = model === void 0 ? "" : t10("agents.model", { model });
140014
+ const showModel = modelText !== "" && fixed + visibleLength(type2) + visibleLength(modelText) <= width;
140015
+ const used = fixed + visibleLength(type2) + (showModel ? visibleLength(modelText) : 0);
140016
+ const room = Math.min(DESCRIPTION_COLUMNS, width - used - visibleLength(t10("agents.description", { description: "" })));
140017
+ const description = agent.description === void 0 || room < MIN_DESCRIPTION_COLUMNS ? "" : palette.paint("label", t10("agents.description", { description: truncateWithEllipsis(agent.description, room, DESCRIPTION_ELLIPSIS) }));
140018
+ const label2 = (text5) => palette.paint("label", text5);
140019
+ return fitToWidth(markedLine(t10, marker, `${palette.paint("agent", type2)}${showModel ? paintCore(modelText, label2) : ""}${description}${paintCore(timeText, label2)}`), width);
140020
+ }
140021
+ function agentsRow(context) {
140022
+ const facts = context.transcript();
140023
+ const shown = facts === void 0 ? [] : agentsShown(facts.activity.agents, context.nowMs);
140024
+ return shown.length === 0 ? NO_LINES : { kind: "text", lines: shown.map((agent) => agentLine(agent, context)) };
140025
+ }
140026
+
139836
140027
  // src/statusline/elements/rows/compactions.ts
139837
140028
  function compactionsRow(context) {
139838
140029
  const transcript = context.transcript();
@@ -140114,73 +140305,6 @@ function countConfiguration(ports, projectDirectory) {
140114
140305
  return { claudeMd, rules, mcpServers: userServers.size + projectServers.size, hookEvents };
140115
140306
  }
140116
140307
 
140117
- // src/statusline/headerLayout.ts
140118
- var SEPARATOR2 = " | ";
140119
- function headerUnits(parts, overflow) {
140120
- const units = [];
140121
- parts.forEach((part, index) => {
140122
- const before = parts[index - 1];
140123
- if (overflow === "truncate" && part.name === "vcs" && before?.name === "project") {
140124
- units[units.length - 1] = `${units.at(-1) ?? ""} ${part.text}`;
140125
- } else {
140126
- units.push(part.text);
140127
- }
140128
- });
140129
- return units;
140130
- }
140131
- function justify(texts, maxWidth, separator) {
140132
- if (texts.length < 2) {
140133
- return texts.join(separator);
140134
- }
140135
- const separatorLength = visibleLength(separator);
140136
- const total = texts.reduce((sum2, text5) => sum2 + visibleLength(text5), 0) + separatorLength * (texts.length - 1);
140137
- const spare = maxWidth - total;
140138
- if (spare <= 0) {
140139
- return texts.join(separator);
140140
- }
140141
- const gaps = texts.length - 1;
140142
- const extraPerGap = Math.floor(spare / gaps);
140143
- let remainder = spare % gaps;
140144
- const parts = [];
140145
- texts.forEach((text5, index) => {
140146
- if (index > 0) {
140147
- const extra = extraPerGap + (remainder > 0 ? 1 : 0);
140148
- if (remainder > 0) {
140149
- remainder -= 1;
140150
- }
140151
- const left = Math.floor(extra / 2);
140152
- parts.push(`${" ".repeat(left + 1)}|${" ".repeat(extra - left + 1)}`);
140153
- }
140154
- parts.push(text5);
140155
- });
140156
- return parts.join("");
140157
- }
140158
- function packLines(texts, maxWidth, separator) {
140159
- const separatorLength = visibleLength(separator);
140160
- const lines = [];
140161
- let current = [];
140162
- let currentWidth = 0;
140163
- for (const text5 of texts) {
140164
- const width = visibleLength(text5);
140165
- const added = current.length === 0 ? width : width + separatorLength;
140166
- if (current.length > 0 && currentWidth + added > maxWidth) {
140167
- lines.push(current);
140168
- current = [text5];
140169
- currentWidth = width;
140170
- } else {
140171
- current.push(text5);
140172
- currentWidth += added;
140173
- }
140174
- }
140175
- if (current.length > 0) {
140176
- lines.push(current);
140177
- }
140178
- return lines;
140179
- }
140180
- function layoutHeader(texts, maxWidth, separator) {
140181
- return packLines(texts, maxWidth, separator).map((line) => justify(line, maxWidth, separator)).join("\n");
140182
- }
140183
-
140184
140308
  // src/statusline/elements/rows/environment.ts
140185
140309
  function counted(count2, one2, other) {
140186
140310
  if (count2 === 0) {
@@ -140220,6 +140344,12 @@ function environmentRow(context) {
140220
140344
  return { kind: "text", lines: packLines(parts.map((part) => palette.paint("label", part)), context.width, SEPARATOR2).map((line) => line.join(SEPARATOR2)) };
140221
140345
  }
140222
140346
 
140347
+ // src/statusline/elements/rows/mcp.ts
140348
+ function mcpRow(context) {
140349
+ const facts = context.transcript();
140350
+ return facts === void 0 ? NO_LINES : nameListRow("mcp.label", facts.activity.mcpServers, facts.complete, context);
140351
+ }
140352
+
140223
140353
  // src/statusline/elements/rows/memory.ts
140224
140354
  function memoryRow(context) {
140225
140355
  const use2 = context.ports.memoryUse();
@@ -140419,6 +140549,94 @@ function sessionTimeRow(context) {
140419
140549
  return { kind: "text", lines: parts.length === 0 ? [] : [parts.join(` ${palette.paint("label", "\u2502")} `)] };
140420
140550
  }
140421
140551
 
140552
+ // src/statusline/elements/rows/skills.ts
140553
+ function skillsRow(context) {
140554
+ const facts = context.transcript();
140555
+ return facts === void 0 ? NO_LINES : nameListRow("skills.label", facts.activity.skills, facts.complete, context);
140556
+ }
140557
+
140558
+ // src/statusline/elements/rows/todos.ts
140559
+ var MAX_TODO_COLUMNS = 50;
140560
+ var TODO_ELLIPSIS = "...";
140561
+ var MIN_TODO_COLUMNS = TODO_ELLIPSIS.length + 1;
140562
+ function todosRow({ palette, transcript, width, t: t10 }) {
140563
+ const todos = transcript()?.activity.todos ?? [];
140564
+ const done = todos.filter((todo) => todo.status === "completed").length;
140565
+ const active = todos.find((todo) => todo.status === "in_progress");
140566
+ const allDone = todos.length > 0 && done === todos.length;
140567
+ if (active === void 0 && !allDone) {
140568
+ return NO_LINES;
140569
+ }
140570
+ const progressText = t10("todos.progress", { done, total: todos.length });
140571
+ const mark = active === void 0 ? palette.paint("context", DONE_MARK) : palette.paint("warning", ACTIVE_MARK);
140572
+ const room = Math.min(MAX_TODO_COLUMNS, width - markColumns(t10) - visibleLength(progressText));
140573
+ const words = room < MIN_TODO_COLUMNS ? "" : truncateWithEllipsis(active === void 0 ? t10("todos.allComplete") : active.content ?? t10("todos.untitled"), room, TODO_ELLIPSIS);
140574
+ const label2 = (text5) => palette.paint("label", text5);
140575
+ const progress = words === "" ? paintCore(progressText.trimStart(), label2) : `${words}${paintCore(progressText, label2)}`;
140576
+ return { kind: "text", lines: [fitToWidth(markedLine(t10, mark, progress), width)] };
140577
+ }
140578
+
140579
+ // src/statusline/elements/rows/tools.ts
140580
+ var MAX_RUNNING_SHOWN = 2;
140581
+ var TARGET_COLUMNS = 20;
140582
+ var FILE_TOOLS = ["Read", "Write", "Edit"];
140583
+ var DIRECTORY_ELLIPSIS = ".../";
140584
+ var FILE_ELLIPSIS = "...";
140585
+ var MCP_TOOL_NAME = /^mcp__.+__.+$/;
140586
+ function shortToolName3(name, maxColumns, available) {
140587
+ const own2 = maxColumns !== 0 && MCP_TOOL_NAME.test(name) ? name.split("__").pop() ?? name : name;
140588
+ return truncateWithEllipsis(own2, maxColumns === 0 ? available : Math.min(maxColumns, available), ELLIPSIS);
140589
+ }
140590
+ function targetText(tool, columns) {
140591
+ const target = tool.target ?? "";
140592
+ const room = Math.min(TARGET_COLUMNS, columns);
140593
+ if (!FILE_TOOLS.includes(tool.name)) {
140594
+ return truncateWithEllipsis(target, room, ELLIPSIS);
140595
+ }
140596
+ const path71 = target.replaceAll("\\", "/");
140597
+ if (visibleLength(path71) <= room) {
140598
+ return path71;
140599
+ }
140600
+ const file2 = path71.split("/").pop() ?? path71;
140601
+ return visibleLength(DIRECTORY_ELLIPSIS) + visibleLength(file2) > room ? truncateWithEllipsis(file2, room, FILE_ELLIPSIS) : `${DIRECTORY_ELLIPSIS}${file2}`;
140602
+ }
140603
+ function finishedByKind(tools) {
140604
+ const counts = /* @__PURE__ */ new Map();
140605
+ for (const tool of tools) {
140606
+ if (tool.status !== "running") {
140607
+ counts.set(tool.name, (counts.get(tool.name) ?? 0) + 1);
140608
+ }
140609
+ }
140610
+ return [...counts.entries()].sort((left, right) => right[1] - left[1]);
140611
+ }
140612
+ function toolsRow(context) {
140613
+ const { palette, settings: settings2, width, t: t10 } = context;
140614
+ const label2 = (text5) => palette.paint("label", text5);
140615
+ const hideSkills = settings2.layout.rows.includes("skills");
140616
+ const tools = (context.transcript()?.activity.tools ?? []).filter((tool) => !(hideSkills && tool.name === "Skill"));
140617
+ const { nameMaxLength, maxVisible } = settings2.tools;
140618
+ const available = columnsLeft(width, markColumns(t10));
140619
+ const running = tools.filter((tool) => tool.status === "running").slice(-MAX_RUNNING_SHOWN);
140620
+ const parts = running.map((tool) => {
140621
+ const name = shortToolName3(tool.name, nameMaxLength, available);
140622
+ const room = available - visibleLength(name) - visibleLength(t10("tools.target", { target: "" }));
140623
+ const target = tool.target === void 0 || room < 1 ? "" : targetText(tool, room);
140624
+ return markedLine(t10, palette.paint("warning", RUNNING_MARK), `${palette.paint("activity", name)}${target === "" ? "" : label2(t10("tools.target", { target }))}`);
140625
+ });
140626
+ const kinds = finishedByKind(tools);
140627
+ const named = maxVisible === 0 ? kinds : kinds.slice(0, maxVisible);
140628
+ parts.push(
140629
+ ...named.map(([name, count2]) => {
140630
+ const countText = t10("tools.count", { count: count2 });
140631
+ return markedLine(t10, palette.paint("context", DONE_MARK), `${shortToolName3(name, nameMaxLength, columnsLeft(available, visibleLength(countText)))}${paintCore(countText, label2)}`);
140632
+ })
140633
+ );
140634
+ if (named.length < kinds.length) {
140635
+ parts.push(label2(t10("more", { count: kinds.length - named.length })));
140636
+ }
140637
+ return parts.length === 0 ? NO_LINES : { kind: "text", lines: packLines(parts.map((part) => fitToWidth(part, width)), width, SEPARATOR2).map((line) => line.join(SEPARATOR2)) };
140638
+ }
140639
+
140422
140640
  // src/statusline/transcript/tokens.ts
140423
140641
  init_zod();
140424
140642
  var tokenCount = external_exports.number().nonnegative();
@@ -140530,7 +140748,7 @@ var ELEMENTS = {
140530
140748
  duration: durationSegment,
140531
140749
  speed: speedSegment
140532
140750
  },
140533
- rows: { context: contextRow, quota: quotaRow, addedDirs: addedDirsRow, gitFiles: gitFilesRow, memory: memoryRow, environment: environmentRow, sessionTime: sessionTimeRow, promptCache: promptCacheRow, compactions: compactionsRow, tokens: tokensRow }
140751
+ rows: { context: contextRow, quota: quotaRow, addedDirs: addedDirsRow, gitFiles: gitFilesRow, memory: memoryRow, environment: environmentRow, sessionTime: sessionTimeRow, promptCache: promptCacheRow, compactions: compactionsRow, tokens: tokensRow, tools: toolsRow, skills: skillsRow, mcp: mcpRow, agents: agentsRow, todos: todosRow }
140534
140752
  };
140535
140753
 
140536
140754
  // src/statusline/identityTranscript.ts
@@ -140672,6 +140890,19 @@ var EN2 = {
140672
140890
  "tokens.output": "out: {count}",
140673
140891
  "tokens.cache": "cache: {count}",
140674
140892
  "list.separator": ", ",
140893
+ "mark.line": "{mark} {text}",
140894
+ "list.count": "({count})",
140895
+ "skills.label": "Skills {count}: {names}",
140896
+ "mcp.label": "MCPs {count}: {names}",
140897
+ "tools.target": ": {target}",
140898
+ "tools.count": " \xD7{count}",
140899
+ "agents.defaultType": "agent",
140900
+ "agents.model": " [{model}]",
140901
+ "agents.description": ": {description}",
140902
+ "agents.elapsed": " ({time})",
140903
+ "todos.progress": " ({done}/{total})",
140904
+ "todos.allComplete": "All todos complete",
140905
+ "todos.untitled": "Untitled task",
140675
140906
  "compactions.label": "Compactions: {count}",
140676
140907
  "environment.claudeMd.one": "{count} CLAUDE.md",
140677
140908
  "environment.claudeMd.other": "{count} CLAUDE.md",
@@ -140732,6 +140963,19 @@ var ZH_HANS = {
140732
140963
  "tokens.output": "\u8F93\u51FA {count}",
140733
140964
  "tokens.cache": "\u7F13\u5B58 {count}",
140734
140965
  "list.separator": "\uFF0C",
140966
+ "mark.line": "{mark} {text}",
140967
+ "list.count": "\uFF08{count}\uFF09",
140968
+ "skills.label": "\u6280\u80FD{count}\uFF1A{names}",
140969
+ "mcp.label": "MCP{count}\uFF1A{names}",
140970
+ "tools.target": "\uFF1A{target}",
140971
+ "tools.count": " {count} \u6B21",
140972
+ "agents.defaultType": "\u667A\u80FD\u4F53",
140973
+ "agents.model": " \u3010{model}\u3011",
140974
+ "agents.description": "\uFF1A{description}",
140975
+ "agents.elapsed": "\uFF08{time}\uFF09",
140976
+ "todos.progress": "\uFF08{done}/{total}\uFF09",
140977
+ "todos.allComplete": "\u5168\u90E8\u5B8C\u6210",
140978
+ "todos.untitled": "\u672A\u547D\u540D\u4EFB\u52A1",
140735
140979
  "compactions.label": "\u538B\u7F29\u6B21\u6570\uFF1A{count}",
140736
140980
  "environment.claudeMd.one": "{count} \u4E2A CLAUDE.md",
140737
140981
  "environment.claudeMd.other": "{count} \u4E2A CLAUDE.md",
@@ -140792,6 +141036,19 @@ var ZH_HANT = {
140792
141036
  "tokens.output": "\u8F38\u51FA {count}",
140793
141037
  "tokens.cache": "\u5FEB\u53D6 {count}",
140794
141038
  "list.separator": "\uFF0C",
141039
+ "mark.line": "{mark} {text}",
141040
+ "list.count": "\uFF08{count}\uFF09",
141041
+ "skills.label": "\u6280\u80FD{count}\uFF1A{names}",
141042
+ "mcp.label": "MCP{count}\uFF1A{names}",
141043
+ "tools.target": "\uFF1A{target}",
141044
+ "tools.count": " {count} \u6B21",
141045
+ "agents.defaultType": "\u4EE3\u7406\u7A0B\u5F0F",
141046
+ "agents.model": " \u3010{model}\u3011",
141047
+ "agents.description": "\uFF1A{description}",
141048
+ "agents.elapsed": "\uFF08{time}\uFF09",
141049
+ "todos.progress": "\uFF08{done}/{total}\uFF09",
141050
+ "todos.allComplete": "\u5168\u90E8\u5B8C\u6210",
141051
+ "todos.untitled": "\u672A\u547D\u540D\u4EFB\u52D9",
140795
141052
  "compactions.label": "\u58D3\u7E2E\u6B21\u6578\uFF1A{count}",
140796
141053
  "environment.claudeMd.one": "{count} \u500B CLAUDE.md",
140797
141054
  "environment.claudeMd.other": "{count} \u500B CLAUDE.md",
@@ -140991,15 +141248,30 @@ function compactUnits(rows, barCells) {
140991
141248
  }
140992
141249
 
140993
141250
  // src/statusline/transcript/reader.ts
141251
+ var import_node_crypto28 = require("node:crypto");
141252
+ init_zod();
141253
+
141254
+ // src/statusline/transcript/activity.ts
140994
141255
  var import_node_crypto27 = require("node:crypto");
140995
141256
  init_zod();
141257
+ init_graphemes();
140996
141258
 
140997
141259
  // src/statusline/transcript/record.ts
140998
141260
  init_zod();
140999
141261
  var text4 = external_exports.string().optional().catch(void 0);
141000
141262
  var number5 = external_exports.number().optional().catch(void 0);
141001
141263
  var count = external_exports.number().nonnegative().optional().catch(void 0);
141002
- var ContentBlockSchema2 = external_exports.looseObject({ type: text4, text: text4 });
141264
+ var ContentBlockSchema2 = external_exports.looseObject({
141265
+ type: text4,
141266
+ text: text4,
141267
+ id: text4,
141268
+ name: text4,
141269
+ input: external_exports.record(external_exports.string(), external_exports.unknown()).optional().catch(void 0),
141270
+ tool_use_id: text4,
141271
+ is_error: external_exports.boolean().optional().catch(void 0),
141272
+ /** What a tool returned: text, or blocks of it. */
141273
+ content: external_exports.union([external_exports.string(), external_exports.array(external_exports.looseObject({ type: text4, text: text4 }))]).optional().catch(void 0)
141274
+ });
141003
141275
  var TranscriptRecordSchema = external_exports.looseObject({
141004
141276
  type: text4,
141005
141277
  subtype: text4,
@@ -141011,6 +141283,17 @@ var TranscriptRecordSchema = external_exports.looseObject({
141011
141283
  /** The title Claude Code generated for the session. */
141012
141284
  aiTitle: text4,
141013
141285
  isSidechain: external_exports.boolean().optional().catch(void 0),
141286
+ /** What a `queue-operation` record did to the client's queue of notifications, and the notification's text: a background agent that has finished is announced by an `enqueue` naming its task and the tool call that started it. */
141287
+ operation: text4,
141288
+ content: text4,
141289
+ /** The outcome the client stamps onto the record that carries a tool's result: for an agent call, the model it ran on and whether it was started in the background, and for a `TaskCreate`, the task made. */
141290
+ toolUseResult: external_exports.looseObject({
141291
+ resolvedModel: text4,
141292
+ isAsync: external_exports.boolean().optional().catch(void 0),
141293
+ status: text4,
141294
+ /** The task a `TaskCreate` made, whose identifier the client assigns and only the result carries. */
141295
+ task: external_exports.looseObject({ id: external_exports.union([external_exports.string(), external_exports.number()]).optional().catch(void 0) }).optional().catch(void 0)
141296
+ }).optional().catch(void 0),
141014
141297
  /** Shared by the records one API request produced. */
141015
141298
  requestId: text4,
141016
141299
  message: external_exports.looseObject({
@@ -141043,6 +141326,484 @@ function recordTimeMs(record2) {
141043
141326
  return Number.isNaN(ms2) ? void 0 : ms2;
141044
141327
  }
141045
141328
 
141329
+ // src/statusline/transcript/activity.ts
141330
+ var MAX_TRACKED_TOOL_CALLS = 20;
141331
+ var MAX_TRACKED_AGENTS = 10;
141332
+ var MAX_TRACKED_TODOS = 200;
141333
+ var BYTES_PER_KIBIBYTE2 = 1024;
141334
+ var MAX_STORED_TEXT_CHARS = 200;
141335
+ var CALL_MEMORY_KIBIBYTES = 64;
141336
+ var CALL_MEMORY_BYTES = CALL_MEMORY_KIBIBYTES * BYTES_PER_KIBIBYTE2;
141337
+ var CALL_MEMORY_COPIES = 2;
141338
+ var SKIPPED_MEMORY_KIBIBYTES = 4;
141339
+ var SKIPPED_MEMORY_BYTES = SKIPPED_MEMORY_KIBIBYTES * BYTES_PER_KIBIBYTE2;
141340
+ var NAME_MEMORY_KIBIBYTES = 16;
141341
+ var NAME_MEMORY_BYTES = NAME_MEMORY_KIBIBYTES * BYTES_PER_KIBIBYTE2;
141342
+ var QUOTES_AND_COMMA_BYTES = 3;
141343
+ var ARRAY_BRACKET_BYTES = 2;
141344
+ var ARRAY_COMMA_BYTES = 1;
141345
+ var CALL_TIME_CHARS = 9;
141346
+ var CALL_TIME_RADIX = 36;
141347
+ var SESSION_CALLS_BOUND_BITS = 20;
141348
+ var SESSION_LOSS_TOLERANCE_BITS = 10;
141349
+ var DIGEST_BITS_PER_CHAR = 6;
141350
+ function rememberedCallBytes(digestChars) {
141351
+ return digestChars + CALL_TIME_CHARS + QUOTES_AND_COMMA_BYTES;
141352
+ }
141353
+ function callsRemembered(digestChars) {
141354
+ return Math.floor(CALL_MEMORY_BYTES / (CALL_MEMORY_COPIES * rememberedCallBytes(digestChars)));
141355
+ }
141356
+ function callsSkippedAtMost(digestChars) {
141357
+ return Math.floor(SKIPPED_MEMORY_BYTES / (CALL_MEMORY_COPIES * rememberedCallBytes(digestChars)));
141358
+ }
141359
+ function namesCounted(digestChars) {
141360
+ return Math.floor(NAME_MEMORY_BYTES / (digestChars + QUOTES_AND_COMMA_BYTES));
141361
+ }
141362
+ function shortestDigestChars(bitsBeyondEntries, entriesAt) {
141363
+ let chars = 1;
141364
+ while (DIGEST_BITS_PER_CHAR * chars <= bitsBeyondEntries + Math.log2(entriesAt(chars))) {
141365
+ chars += 1;
141366
+ }
141367
+ return chars;
141368
+ }
141369
+ var CALL_DIGEST_CHARS = shortestDigestChars(SESSION_CALLS_BOUND_BITS + SESSION_LOSS_TOLERANCE_BITS, (chars) => Math.max(callsRemembered(chars) + callsSkippedAtMost(chars), namesCounted(chars)));
141370
+ var MAX_OLDER_SHARE = 0.5;
141371
+ var MAX_REMEMBERED_CALLS = callsRemembered(CALL_DIGEST_CHARS);
141372
+ var MAX_SKIPPED_CALLS = callsSkippedAtMost(CALL_DIGEST_CHARS);
141373
+ var MAX_COUNTED_NAMES = namesCounted(CALL_DIGEST_CHARS);
141374
+ var MS_PER_SECOND22 = 1e3;
141375
+ var SECONDS_PER_MINUTE5 = 60;
141376
+ var MINUTES_PER_HOUR7 = 60;
141377
+ var HOURS_PER_DAY11 = 24;
141378
+ var BASH_DEFAULT_TIMEOUT_MS = 12e4;
141379
+ var BASH_MAX_TIMEOUT_MS = 6e5;
141380
+ function timeoutFromEnv(env, name, fallback) {
141381
+ const value2 = Number(env[name]);
141382
+ return Number.isInteger(value2) && value2 > 0 ? value2 : fallback;
141383
+ }
141384
+ function bashLiveLimitMs(env) {
141385
+ return Math.max(timeoutFromEnv(env, "BASH_DEFAULT_TIMEOUT_MS", BASH_DEFAULT_TIMEOUT_MS), timeoutFromEnv(env, "BASH_MAX_TIMEOUT_MS", BASH_MAX_TIMEOUT_MS));
141386
+ }
141387
+ var MAX_LIVE_AGENT_MS = HOURS_PER_DAY11 * MINUTES_PER_HOUR7 * SECONDS_PER_MINUTE5 * MS_PER_SECOND22;
141388
+ var AGENT_TOOLS = ["Task", "Agent"];
141389
+ var TODO_WRITE_TOOL = "TodoWrite";
141390
+ var TASK_CREATE_TOOL = "TaskCreate";
141391
+ var TASK_UPDATE_TOOL = "TaskUpdate";
141392
+ var SKILL_TOOL = "Skill";
141393
+ var BASH_TOOL = "Bash";
141394
+ var STILL_RUNNING_STATUSES = ["async_launched", "teammate_spawned"];
141395
+ var MCP_TOOL_NAME2 = /^mcp__(.+?)__(.+)$/;
141396
+ var QUEUED_TASK_ID = /<task-id>([^<]+)<\/task-id>/;
141397
+ var QUEUED_TOOL_USE_ID = /<tool-use-id>([^<]+)<\/tool-use-id>/;
141398
+ var ToolCallSchema = external_exports.strictObject({
141399
+ id: external_exports.string(),
141400
+ name: external_exports.string(),
141401
+ /** What the call acts on, when its input names one: a file, a pattern, a skill or the start of a command. */
141402
+ target: external_exports.string().optional(),
141403
+ startedAtMs: external_exports.number().optional(),
141404
+ /** When the call's result was written; absent while it has none. */
141405
+ endedAtMs: external_exports.number().optional(),
141406
+ failed: external_exports.literal(true).optional(),
141407
+ /** True once the session wrote its next response with the call still unanswered. A result can still come after that (results are not always written in order), which finishes the call. */
141408
+ abandoned: external_exports.literal(true).optional()
141409
+ });
141410
+ var AgentCallSchema = external_exports.strictObject({
141411
+ id: external_exports.string(),
141412
+ /** The kind of agent the call asked for; absent when the call names none, which the row draws as its own word. */
141413
+ type: external_exports.string().optional(),
141414
+ /** The model the agent asked to run on, replaced by the one it resolved to when the result says. */
141415
+ model: external_exports.string().optional(),
141416
+ description: external_exports.string().optional(),
141417
+ startedAtMs: external_exports.number().optional(),
141418
+ endedAtMs: external_exports.number().optional(),
141419
+ /** True for an agent that keeps running after the call that started it has returned; its result comes much earlier than its end. */
141420
+ background: external_exports.literal(true).optional(),
141421
+ /** As for a tool call: the session wrote its next response with the agent unanswered. */
141422
+ abandoned: external_exports.literal(true).optional(),
141423
+ /** When the client announced the agent finished, read before the result that says the agent was started in the background; the agent ends then. */
141424
+ announcedAtMs: external_exports.number().optional()
141425
+ });
141426
+ var CallResultSchema = external_exports.strictObject({
141427
+ id: external_exports.string(),
141428
+ atMs: external_exports.number().optional(),
141429
+ failed: external_exports.literal(true).optional(),
141430
+ /** The model an agent's result says it ran on. */
141431
+ resolvedModel: external_exports.string().optional(),
141432
+ /** True when the result says the agent was started in the background. */
141433
+ async: external_exports.literal(true).optional(),
141434
+ /** The identifier the client gave the task a `TaskCreate` made. */
141435
+ taskId: external_exports.string().optional(),
141436
+ /** True for the client's announcement that a background agent finished, which can be queued ahead of the call that started the agent; `atMs` is then when the agent ended. */
141437
+ announced: external_exports.literal(true).optional()
141438
+ });
141439
+ var TodoStatusSchema = external_exports.enum(["pending", "in_progress", "completed"]);
141440
+ var TodoSchema = external_exports.strictObject({
141441
+ content: external_exports.string(),
141442
+ status: TodoStatusSchema,
141443
+ /** The identifier a later `TaskUpdate` names the item by. The client assigns it, and only the result of the `TaskCreate` that made the item carries it; an item from a `TodoWrite` has none. */
141444
+ id: external_exports.string().optional(),
141445
+ /** The `TaskCreate` call that made the item while its result has not been read: the item has no identifier yet, is not drawn, and is dropped when the result says the call failed. */
141446
+ pendingCallId: external_exports.string().optional()
141447
+ });
141448
+ var ActivityLatestSchema = external_exports.strictObject({
141449
+ tools: external_exports.array(ToolCallSchema),
141450
+ agents: external_exports.array(AgentCallSchema),
141451
+ todos: external_exports.array(TodoSchema),
141452
+ todosReplaced: external_exports.literal(true).optional(),
141453
+ /** True once a `TaskCreate` or `TaskUpdate` has been read: the list was edited in place, so a list read from before that is out of date. */
141454
+ todosEdited: external_exports.literal(true).optional(),
141455
+ /** Results read before their calls, oldest first. */
141456
+ unmatchedResults: external_exports.array(CallResultSchema),
141457
+ /** The latest calls made, of every kind, oldest first, each as the digest of its id followed by its time in `CALL_TIME_CHARS` characters of base 36, or nothing when it has none: a call remembered is not made again by a record that repeats it. */
141458
+ rememberedCalls: external_exports.array(external_exports.string()),
141459
+ /** The forgotten calls that were stamped out of order, in the form of `rememberedCalls`, kept while the floor has not passed them. */
141460
+ skippedCalls: external_exports.array(external_exports.string()),
141461
+ /** The time of the newest in-order call forgotten from `rememberedCalls`: a call at or before it is history written again, whatever its id. */
141462
+ forgottenUpToMs: external_exports.number().optional(),
141463
+ /** The response of the session's latest assistant record, which the records of one response share. A call is made in one response and answered before the next is written, so a call with no result when a response of another key appears was abandoned (an interrupted tool call). */
141464
+ responseKey: external_exports.string().optional()
141465
+ });
141466
+ var NameSetSchema = external_exports.strictObject({
141467
+ names: external_exports.array(external_exports.string()),
141468
+ others: external_exports.array(external_exports.string()),
141469
+ /** True once a name was used that the digests had no room for: the count is then a floor. */
141470
+ overflowed: external_exports.literal(true).optional()
141471
+ });
141472
+ var ActivityCumulativeSchema = external_exports.strictObject({
141473
+ skills: NameSetSchema,
141474
+ mcpServers: NameSetSchema
141475
+ });
141476
+ var ActivityStateSchema = external_exports.strictObject({ cumulative: ActivityCumulativeSchema, latest: ActivityLatestSchema });
141477
+ var EMPTY_NAME_SET = { names: [], others: [] };
141478
+ var EMPTY_ACTIVITY_LATEST = { tools: [], agents: [], todos: [], unmatchedResults: [], rememberedCalls: [], skippedCalls: [] };
141479
+ var EMPTY_ACTIVITY_STATE = { cumulative: { skills: EMPTY_NAME_SET, mcpServers: EMPTY_NAME_SET }, latest: EMPTY_ACTIVITY_LATEST };
141480
+ function stored(text5) {
141481
+ return graphemesOf(text5.slice(0, MAX_STORED_TEXT_CHARS * 2)).slice(0, MAX_STORED_TEXT_CHARS).join("");
141482
+ }
141483
+ function stringField2(input2, key) {
141484
+ const value2 = input2?.[key];
141485
+ return typeof value2 === "string" && value2 !== "" ? value2 : void 0;
141486
+ }
141487
+ function targetOf2(name, input2) {
141488
+ switch (name) {
141489
+ case "Read":
141490
+ case "Write":
141491
+ case "Edit":
141492
+ return stringField2(input2, "file_path") ?? stringField2(input2, "path");
141493
+ case "Glob":
141494
+ case "Grep":
141495
+ return stringField2(input2, "pattern");
141496
+ case SKILL_TOOL:
141497
+ return stringField2(input2, "skill");
141498
+ case BASH_TOOL: {
141499
+ const command = stringField2(input2, "command")?.replace(/\s+/g, " ").trim();
141500
+ if (command === void 0 || command === "") {
141501
+ return void 0;
141502
+ }
141503
+ return command;
141504
+ }
141505
+ default:
141506
+ return void 0;
141507
+ }
141508
+ }
141509
+ function todoStatusOf(status) {
141510
+ switch (status) {
141511
+ case "pending":
141512
+ case "not_started":
141513
+ return "pending";
141514
+ case "in_progress":
141515
+ case "running":
141516
+ return "in_progress";
141517
+ case "completed":
141518
+ case "complete":
141519
+ case "done":
141520
+ return "completed";
141521
+ default:
141522
+ return void 0;
141523
+ }
141524
+ }
141525
+ function replacedTodos(previous, written) {
141526
+ const idsByContent = /* @__PURE__ */ new Map();
141527
+ for (const item of previous) {
141528
+ if (item.id !== void 0) {
141529
+ idsByContent.set(item.content, [...idsByContent.get(item.content) ?? [], item.id]);
141530
+ }
141531
+ }
141532
+ return written.slice(-MAX_TRACKED_TODOS).flatMap((entry) => {
141533
+ if (typeof entry !== "object" || entry === null || !("content" in entry) || typeof entry.content !== "string") {
141534
+ return [];
141535
+ }
141536
+ const content = stored(entry.content);
141537
+ const id2 = idsByContent.get(content)?.shift();
141538
+ const status = "status" in entry ? todoStatusOf(entry.status) ?? "pending" : "pending";
141539
+ return [{ content, status, ...id2 === void 0 ? {} : { id: id2 } }];
141540
+ });
141541
+ }
141542
+ function todoIndexOf(todos, taskId) {
141543
+ if (typeof taskId !== "string" && typeof taskId !== "number") {
141544
+ return void 0;
141545
+ }
141546
+ const index = todos.findIndex((item) => item.id === String(taskId));
141547
+ return index === -1 ? void 0 : index;
141548
+ }
141549
+ function foldTodoCall(state, call2) {
141550
+ const { input: input2 } = call2;
141551
+ if (call2.name === TODO_WRITE_TOOL) {
141552
+ const written = input2?.todos;
141553
+ return Array.isArray(written) ? { ...state, todos: replacedTodos(state.todos, written), todosReplaced: true } : state;
141554
+ }
141555
+ if (call2.name === TASK_CREATE_TOOL) {
141556
+ const content = stored(stringField2(input2, "subject") ?? stringField2(input2, "description") ?? "");
141557
+ const status = todoStatusOf(input2?.status) ?? "pending";
141558
+ return { ...state, todos: [...state.todos, { content, status, pendingCallId: call2.id }].slice(-MAX_TRACKED_TODOS), todosEdited: true };
141559
+ }
141560
+ const index = todoIndexOf(state.todos, input2?.taskId);
141561
+ const current = index === void 0 ? void 0 : state.todos[index];
141562
+ if (index === void 0 || current === void 0) {
141563
+ return { ...state, todosEdited: true };
141564
+ }
141565
+ if (input2?.status === "deleted") {
141566
+ return { ...state, todos: state.todos.filter((_, at2) => at2 !== index), todosEdited: true };
141567
+ }
141568
+ const subject = stringField2(input2, "subject");
141569
+ const updated = { ...current, status: todoStatusOf(input2?.status) ?? current.status, content: subject === void 0 ? current.content : stored(subject) };
141570
+ return { ...state, todos: state.todos.map((item, at2) => at2 === index ? updated : item), todosEdited: true };
141571
+ }
141572
+ function digestOf(id2) {
141573
+ return (0, import_node_crypto27.createHash)("sha256").update(id2).digest("base64url").slice(0, CALL_DIGEST_CHARS);
141574
+ }
141575
+ function timeKeyOf(atMs) {
141576
+ const key = atMs === void 0 || atMs < 0 ? "" : atMs.toString(CALL_TIME_RADIX);
141577
+ return key.length > CALL_TIME_CHARS ? "" : key.padStart(key === "" ? 0 : CALL_TIME_CHARS, "0");
141578
+ }
141579
+ var timeKeyOfEntry = (entry) => entry.slice(CALL_DIGEST_CHARS);
141580
+ function isRemembered(state, id2, atMs) {
141581
+ if (atMs !== void 0 && state.forgottenUpToMs !== void 0 && atMs <= state.forgottenUpToMs) {
141582
+ return true;
141583
+ }
141584
+ const digest2 = digestOf(id2);
141585
+ return state.rememberedCalls.some((entry) => entry.startsWith(digest2)) || state.skippedCalls.some((entry) => entry.startsWith(digest2));
141586
+ }
141587
+ function beyondFloor(entries, floorMs) {
141588
+ return entries.filter((entry) => floorMs === void 0 || Number.parseInt(timeKeyOfEntry(entry), CALL_TIME_RADIX) > floorMs);
141589
+ }
141590
+ function remember(state, id2, atMs) {
141591
+ const all2 = [...state.rememberedCalls, `${digestOf(id2)}${timeKeyOf(atMs)}`];
141592
+ const kept = all2.slice(-MAX_REMEMBERED_CALLS);
141593
+ const [forgotten] = all2.slice(0, -MAX_REMEMBERED_CALLS);
141594
+ const forgottenKey = forgotten === void 0 ? "" : timeKeyOfEntry(forgotten);
141595
+ if (forgotten === void 0 || forgottenKey === "") {
141596
+ return { ...state, rememberedCalls: kept };
141597
+ }
141598
+ const keptTimes = kept.map(timeKeyOfEntry).filter((key) => key !== "");
141599
+ if (keptTimes.filter((key) => key < forgottenKey).length <= keptTimes.length * MAX_OLDER_SHARE) {
141600
+ const forgottenUpToMs = Math.max(state.forgottenUpToMs ?? Number.NEGATIVE_INFINITY, Number.parseInt(forgottenKey, CALL_TIME_RADIX));
141601
+ return { ...state, rememberedCalls: kept, skippedCalls: beyondFloor(state.skippedCalls, forgottenUpToMs), forgottenUpToMs };
141602
+ }
141603
+ return { ...state, rememberedCalls: kept, skippedCalls: beyondFloor([...state.skippedCalls, forgotten], state.forgottenUpToMs).slice(-MAX_SKIPPED_CALLS) };
141604
+ }
141605
+ function replayMemoryOf(earlier) {
141606
+ return { ...EMPTY_ACTIVITY_LATEST, rememberedCalls: earlier.rememberedCalls, skippedCalls: earlier.skippedCalls, ...earlier.forgottenUpToMs === void 0 ? {} : { forgottenUpToMs: earlier.forgottenUpToMs } };
141607
+ }
141608
+ function foldToolUse(state, call2, atMs) {
141609
+ const added = foldTrackedCall(state, call2, atMs);
141610
+ const waiting = added.unmatchedResults.filter((result) => result.id === call2.id);
141611
+ return waiting.reduce((folded, result) => applyResult(folded, result) ?? folded, { ...added, unmatchedResults: added.unmatchedResults.filter((result) => result.id !== call2.id) });
141612
+ }
141613
+ function foldTrackedCall(state, call2, atMs) {
141614
+ if (AGENT_TOOLS.includes(call2.name)) {
141615
+ const { input: input2 } = call2;
141616
+ const type2 = stringField2(input2, "subagent_type");
141617
+ const model = stringField2(input2, "model");
141618
+ const description = stringField2(input2, "description");
141619
+ const agent = {
141620
+ id: call2.id,
141621
+ ...type2 === void 0 ? {} : { type: stored(type2) },
141622
+ ...model === void 0 ? {} : { model: stored(model) },
141623
+ ...description === void 0 ? {} : { description: stored(description) },
141624
+ ...atMs === void 0 ? {} : { startedAtMs: atMs },
141625
+ ...input2?.run_in_background === true || input2?.run_in_background === "true" ? { background: true } : {}
141626
+ };
141627
+ return { ...state, agents: [...state.agents, agent].slice(-MAX_TRACKED_AGENTS) };
141628
+ }
141629
+ if (call2.name === TODO_WRITE_TOOL || call2.name === TASK_CREATE_TOOL || call2.name === TASK_UPDATE_TOOL) {
141630
+ return foldTodoCall(state, call2);
141631
+ }
141632
+ const target = targetOf2(call2.name, call2.input);
141633
+ const tool = { id: call2.id, name: stored(call2.name), ...target === void 0 ? {} : { target: stored(target) }, ...atMs === void 0 ? {} : { startedAtMs: atMs } };
141634
+ return { ...state, tools: [...state.tools, tool].slice(-MAX_TRACKED_TOOL_CALLS) };
141635
+ }
141636
+ function applyResult(state, result) {
141637
+ const answersAgent = state.agents.some((agent) => agent.id === result.id);
141638
+ if (result.announced === true ? !answersAgent : !state.tools.some((tool) => tool.id === result.id) && !answersAgent && !state.todos.some((item) => item.pendingCallId === result.id)) {
141639
+ return void 0;
141640
+ }
141641
+ const tools = state.tools.map((tool) => tool.id === result.id ? { ...tool, ...result.atMs === void 0 ? {} : { endedAtMs: result.atMs }, ...result.failed === true ? { failed: true } : {} } : tool);
141642
+ const agents = state.agents.map((agent) => {
141643
+ if (agent.id !== result.id) {
141644
+ return agent;
141645
+ }
141646
+ if (result.announced === true) {
141647
+ return result.atMs === void 0 ? agent : agent.background === true ? { ...agent, endedAtMs: result.atMs } : { ...agent, announcedAtMs: result.atMs };
141648
+ }
141649
+ const background = agent.background === true || result.async === true;
141650
+ const model = result.resolvedModel === void 0 ? agent.model : stored(result.resolvedModel);
141651
+ const endedAtMs = background ? agent.announcedAtMs : result.atMs;
141652
+ return { ...agent, ...model === void 0 ? {} : { model }, ...background ? { background: true } : {}, ...endedAtMs === void 0 ? {} : { endedAtMs } };
141653
+ });
141654
+ const restarted = state.todos.some((item) => item.pendingCallId === result.id && result.failed !== true && result.taskId !== void 0 && state.todos.some((other) => other.id === result.taskId));
141655
+ const todos = (restarted ? state.todos.filter((item) => item.pendingCallId !== void 0) : state.todos).flatMap((item) => {
141656
+ if (item.pendingCallId !== result.id) {
141657
+ return [item];
141658
+ }
141659
+ return result.failed === true || result.taskId === void 0 ? [] : [{ content: item.content, status: item.status, id: result.taskId }];
141660
+ });
141661
+ return { ...state, tools, agents, todos };
141662
+ }
141663
+ function foldToolResult(state, result) {
141664
+ const applied = applyResult(state, result);
141665
+ if (applied !== void 0) {
141666
+ return applied;
141667
+ }
141668
+ return isRemembered(state, result.id, result.atMs) ? state : { ...state, unmatchedResults: [...state.unmatchedResults, result].slice(-MAX_TRACKED_TOOL_CALLS) };
141669
+ }
141670
+ var CREATED_TASK = /^Task #([^\s:]+) created/;
141671
+ function createdTaskId(content, outcome) {
141672
+ const text5 = typeof content === "string" ? content : content?.find((part) => part.text !== void 0)?.text;
141673
+ const named = text5 === void 0 ? void 0 : CREATED_TASK.exec(text5)?.[1];
141674
+ const stamped = outcome?.task?.id;
141675
+ return named ?? (stamped === void 0 ? void 0 : String(stamped));
141676
+ }
141677
+ function foldAgentAnnouncement(state, toolUseId, atMs) {
141678
+ return foldToolResult(state, { id: toolUseId, atMs, announced: true });
141679
+ }
141680
+ function withUnanswered(tools, agents) {
141681
+ return {
141682
+ tools: tools.map((tool) => tool.endedAtMs === void 0 ? { ...tool, abandoned: true } : tool),
141683
+ agents: agents.map((agent) => agent.endedAtMs === void 0 && agent.background !== true ? { ...agent, abandoned: true } : agent)
141684
+ };
141685
+ }
141686
+ function foldNewResponse(state, key) {
141687
+ return { ...state, responseKey: key, ...withUnanswered(state.tools, state.agents) };
141688
+ }
141689
+ function foldActivityLatest(state, record2) {
141690
+ if (record2.isSidechain === true) {
141691
+ return state;
141692
+ }
141693
+ const atMs = recordTimeMs(record2);
141694
+ let next = state;
141695
+ if (record2.type === "queue-operation" && record2.operation === "enqueue" && record2.content !== void 0 && atMs !== void 0) {
141696
+ const toolUseId = QUEUED_TOOL_USE_ID.exec(record2.content)?.[1];
141697
+ if (toolUseId !== void 0 && QUEUED_TASK_ID.test(record2.content)) {
141698
+ next = foldAgentAnnouncement(next, toolUseId, atMs);
141699
+ }
141700
+ }
141701
+ const responseKey = record2.type === "assistant" ? record2.message?.id ?? record2.requestId : void 0;
141702
+ if (responseKey !== void 0 && responseKey !== next.responseKey) {
141703
+ next = next.responseKey === void 0 ? { ...next, responseKey } : foldNewResponse(next, responseKey);
141704
+ }
141705
+ const content = record2.message?.content;
141706
+ if (!Array.isArray(content)) {
141707
+ return next;
141708
+ }
141709
+ const resultCount = content.filter((block2) => block2.type === "tool_result").length;
141710
+ for (const block2 of content) {
141711
+ if (record2.type === "assistant" && block2.type === "tool_use" && block2.id !== void 0 && block2.name !== void 0 && !isRemembered(next, block2.id, atMs)) {
141712
+ next = foldToolUse(remember(next, block2.id, atMs), { id: block2.id, name: block2.name, input: block2.input }, atMs);
141713
+ } else if (record2.type === "user" && block2.type === "tool_result" && block2.tool_use_id !== void 0) {
141714
+ const outcome = resultCount === 1 ? record2.toolUseResult : void 0;
141715
+ const taskId = createdTaskId(block2.content, outcome);
141716
+ next = foldToolResult(next, {
141717
+ id: block2.tool_use_id,
141718
+ ...taskId === void 0 ? {} : { taskId },
141719
+ ...atMs === void 0 ? {} : { atMs },
141720
+ ...block2.is_error === true ? { failed: true } : {},
141721
+ ...outcome?.resolvedModel === void 0 ? {} : { resolvedModel: outcome.resolvedModel },
141722
+ ...outcome?.isAsync === true || outcome?.status !== void 0 && STILL_RUNNING_STATUSES.includes(outcome.status) ? { async: true } : {}
141723
+ });
141724
+ }
141725
+ }
141726
+ return next;
141727
+ }
141728
+ function nameBytes(name) {
141729
+ return Buffer.byteLength(JSON.stringify([name])) - ARRAY_BRACKET_BYTES + ARRAY_COMMA_BYTES;
141730
+ }
141731
+ function withName(set3, name) {
141732
+ if (name === void 0 || name === "" || set3.names.includes(name)) {
141733
+ return set3;
141734
+ }
141735
+ if (set3.others.length === 0 && set3.names.reduce((total, kept) => total + nameBytes(kept), nameBytes(name)) <= NAME_MEMORY_BYTES) {
141736
+ return { ...set3, names: [...set3.names, name] };
141737
+ }
141738
+ const digest2 = digestOf(name);
141739
+ if (set3.others.includes(digest2)) {
141740
+ return set3;
141741
+ }
141742
+ if (set3.others.length >= MAX_COUNTED_NAMES) {
141743
+ return set3.overflowed === true ? set3 : { ...set3, overflowed: true };
141744
+ }
141745
+ return { ...set3, others: [...set3.others, digest2] };
141746
+ }
141747
+ function foldActivityCumulative(state, record2) {
141748
+ const content = record2.message?.content;
141749
+ if (record2.isSidechain === true || record2.type !== "assistant" || !Array.isArray(content)) {
141750
+ return state;
141751
+ }
141752
+ let { skills, mcpServers } = state;
141753
+ for (const block2 of content) {
141754
+ if (block2.type !== "tool_use" || block2.name === void 0) {
141755
+ continue;
141756
+ }
141757
+ if (block2.name === SKILL_TOOL) {
141758
+ const skill = stringField2(block2.input, "skill");
141759
+ skills = withName(skills, skill === void 0 ? void 0 : stored(skill));
141760
+ }
141761
+ const server = MCP_TOOL_NAME2.exec(block2.name)?.[1];
141762
+ mcpServers = withName(mcpServers, server === void 0 ? void 0 : stored(server));
141763
+ }
141764
+ return skills === state.skills && mcpServers === state.mcpServers ? state : { skills, mcpServers };
141765
+ }
141766
+ function foldActivity(state, record2) {
141767
+ return { cumulative: foldActivityCumulative(state.cumulative, record2), latest: foldActivityLatest(state.latest, record2) };
141768
+ }
141769
+ function isLive(startedAtMs, nowMs, maxMs) {
141770
+ return startedAtMs === void 0 || nowMs - startedAtMs <= maxMs;
141771
+ }
141772
+ function visibleNames(set3) {
141773
+ const names = [...new Set(set3.names.map(visibleDisplayText).filter((name) => name !== ""))];
141774
+ return { names, total: names.length + set3.others.length, exact: set3.overflowed !== true };
141775
+ }
141776
+ function activityFactsOf(state, nowMs, limits, newer) {
141777
+ const latest = newer === void 0 ? state.latest : { tools: newer.tools, agents: newer.agents, todos: newer.todosReplaced === true ? newer.todos : [], unmatchedResults: [], rememberedCalls: [], skippedCalls: [] };
141778
+ return {
141779
+ tools: latest.tools.flatMap((tool) => {
141780
+ const name = visibleDisplayText(tool.name);
141781
+ const resolved = tool.endedAtMs !== void 0;
141782
+ if (name === "" || !resolved && (tool.abandoned === true || tool.name === BASH_TOOL && !isLive(tool.startedAtMs, nowMs, limits.bashMs))) {
141783
+ return [];
141784
+ }
141785
+ const target = tool.target === void 0 ? "" : visibleDisplayText(tool.target);
141786
+ return [{ name, target: target === "" ? void 0 : target, status: !resolved ? "running" : tool.failed === true ? "error" : "completed" }];
141787
+ }),
141788
+ skills: visibleNames(state.cumulative.skills),
141789
+ mcpServers: visibleNames(state.cumulative.mcpServers),
141790
+ agents: latest.agents.flatMap((agent) => {
141791
+ const ended = agent.endedAtMs !== void 0;
141792
+ if (!ended && (agent.abandoned === true || !isLive(agent.startedAtMs, nowMs, MAX_LIVE_AGENT_MS))) {
141793
+ return [];
141794
+ }
141795
+ const type2 = agent.type === void 0 ? "" : visibleDisplayText(agent.type);
141796
+ const model = agent.model === void 0 ? "" : visibleDisplayText(agent.model);
141797
+ const description = agent.description === void 0 ? "" : visibleDisplayText(agent.description);
141798
+ return [{ type: type2 === "" ? void 0 : type2, model: model === "" ? void 0 : model, description: description === "" ? void 0 : description, status: ended ? "completed" : "running", startedAtMs: agent.startedAtMs, endedAtMs: agent.endedAtMs }];
141799
+ }),
141800
+ todos: latest.todos.flatMap((todo) => {
141801
+ const content = visibleDisplayText(todo.content);
141802
+ return todo.pendingCallId !== void 0 ? [] : [{ content: content === "" ? void 0 : content, status: todo.status }];
141803
+ })
141804
+ };
141805
+ }
141806
+
141046
141807
  // src/statusline/transcript/session.ts
141047
141808
  init_zod();
141048
141809
  init_statusline();
@@ -141164,7 +141925,7 @@ var MAX_TRANSCRIPT_READ_BYTES = 4194304;
141164
141925
  var FINGERPRINT_BYTES = 4096;
141165
141926
  var NEWLINE2 = 10;
141166
141927
  var CACHE_KIND2 = "transcript";
141167
- var CACHE_VERSION = 5;
141928
+ var CACHE_VERSION = 8;
141168
141929
  var TranscriptCacheSchema = external_exports.strictObject({
141169
141930
  version: external_exports.literal(CACHE_VERSION),
141170
141931
  /** A digest of the transcript's first line when this was written: another file at the same path has another one. */
@@ -141177,8 +141938,9 @@ var TranscriptCacheSchema = external_exports.strictObject({
141177
141938
  skipping: external_exports.literal(true).optional(),
141178
141939
  session: SessionStateSchema2,
141179
141940
  tokens: TokenStateSchema,
141941
+ activity: ActivityStateSchema,
141180
141942
  /** While the cumulative facts are being caught up, the latest-state facts folded from the end of the transcript, and where that fold has read to. Absent once the cumulative fold has reached the end, when it holds them itself. */
141181
- newer: external_exports.strictObject({ offset: external_exports.number().int().nonnegative(), state: LatestStateSchema }).optional()
141943
+ newer: external_exports.strictObject({ offset: external_exports.number().int().nonnegative(), state: LatestStateSchema, activity: ActivityLatestSchema }).optional()
141182
141944
  });
141183
141945
  function eachRecord(bytes, visit2) {
141184
141946
  const end = bytes.lastIndexOf(NEWLINE2) + 1;
@@ -141191,20 +141953,20 @@ function eachRecord(bytes, visit2) {
141191
141953
  return end;
141192
141954
  }
141193
141955
  function foldLines(state, bytes) {
141194
- let session = state.session;
141195
- let tokens = state.tokens;
141956
+ let { session, tokens, activity } = state;
141196
141957
  const consumed = eachRecord(bytes, (record2) => {
141197
141958
  session = foldSession(session, record2);
141198
141959
  tokens = foldTokens(tokens, record2);
141960
+ activity = foldActivity(activity, record2);
141199
141961
  });
141200
- return { session, tokens, consumed };
141962
+ return { session, tokens, activity, consumed };
141201
141963
  }
141202
141964
  function fingerprintOf(head) {
141203
141965
  const newline = head.subarray(0, FINGERPRINT_BYTES).indexOf(NEWLINE2);
141204
- return (0, import_node_crypto27.createHash)("sha256").update(head.subarray(0, newline === -1 ? FINGERPRINT_BYTES : newline + 1)).digest("hex");
141966
+ return (0, import_node_crypto28.createHash)("sha256").update(head.subarray(0, newline === -1 ? FINGERPRINT_BYTES : newline + 1)).digest("hex");
141205
141967
  }
141206
- function factsOf(size, cache, reachedEnd) {
141207
- return { bytes: size, complete: cache.complete && reachedEnd, session: sessionFactsOf(cache.session, cache.newer?.state), tokens: cache.tokens.totals };
141968
+ function factsOf(size, cache, reachedEnd, nowMs, env) {
141969
+ return { bytes: size, complete: cache.complete && reachedEnd, session: sessionFactsOf(cache.session, cache.newer?.state), tokens: cache.tokens.totals, activity: activityFactsOf(cache.activity, nowMs, { bashMs: bashLiveLimitMs(env) }, cache.newer?.activity) };
141208
141970
  }
141209
141971
  var START_UNKNOWN = { startUnknown: true };
141210
141972
  function advance2(cache, window, reachedEnd) {
@@ -141218,13 +141980,13 @@ function advance2(cache, window, reachedEnd) {
141218
141980
  offset += lineEnd + 1;
141219
141981
  bytes = bytes.subarray(lineEnd + 1);
141220
141982
  }
141221
- const { session: folded, tokens, consumed } = foldLines(cache, bytes);
141983
+ const { session: folded, tokens, activity, consumed } = foldLines(cache, bytes);
141222
141984
  if (consumed === 0 && bytes.length > 0 && !reachedEnd) {
141223
141985
  const { cumulative } = cache.session;
141224
141986
  const session = cumulative.startedAtMs === void 0 ? { ...cache.session, cumulative: { ...cumulative, ...START_UNKNOWN } } : cache.session;
141225
141987
  return { ...cache, offset: offset + bytes.length, complete: false, skipping: true, session };
141226
141988
  }
141227
- return { version: cache.version, fingerprint: cache.fingerprint, offset: offset + consumed, complete: cache.complete, session: folded, tokens };
141989
+ return { version: cache.version, fingerprint: cache.fingerprint, offset: offset + consumed, complete: cache.complete, session: folded, tokens, activity };
141228
141990
  }
141229
141991
  function readTranscript(ports, transcriptPath, nowMs) {
141230
141992
  const file2 = cacheFileFor(ports, CACHE_KIND2, transcriptPath);
@@ -141236,20 +141998,20 @@ function readTranscript(ports, transcriptPath, nowMs) {
141236
141998
  if (window === void 0) {
141237
141999
  return void 0;
141238
142000
  }
141239
- const { newer: previousNewer, ...base } = cached2 ?? { version: CACHE_VERSION, fingerprint: "", offset: 0, complete: true, session: EMPTY_SESSION_STATE, tokens: EMPTY_TOKEN_STATE };
142001
+ const { newer: previousNewer, ...base } = cached2 ?? { version: CACHE_VERSION, fingerprint: "", offset: 0, complete: true, session: EMPTY_SESSION_STATE, tokens: EMPTY_TOKEN_STATE, activity: EMPTY_ACTIVITY_STATE };
141240
142002
  const reachedEnd = window.size - from <= MAX_TRANSCRIPT_READ_BYTES;
141241
142003
  const advanced = advance2(base, window.bytes, reachedEnd);
141242
- const newer = reachedEnd ? void 0 : newerFrom(ports, transcriptPath, window.size, previousNewer);
142004
+ const newer = reachedEnd ? void 0 : newerFrom(ports, transcriptPath, window.size, previousNewer, advanced);
141243
142005
  const next = { ...advanced, ...newer === void 0 ? {} : { newer } };
141244
142006
  if (next.offset > base.offset) {
141245
142007
  saveCache(ports, file2, { ...next, fingerprint: cached2 === void 0 ? fingerprintOf(window.bytes) : base.fingerprint }, nowMs);
141246
142008
  }
141247
- return factsOf(window.size, next, reachedEnd);
142009
+ return factsOf(window.size, next, reachedEnd, nowMs, ports.env);
141248
142010
  }
141249
- function newerFrom(ports, transcriptPath, size, previous) {
142011
+ function newerFrom(ports, transcriptPath, size, previous, cumulative) {
141250
142012
  if (previous !== void 0 && previous.offset <= size && size - previous.offset <= MAX_TRANSCRIPT_READ_BYTES) {
141251
142013
  const appended = ports.readRange(transcriptPath, previous.offset, MAX_TRANSCRIPT_READ_BYTES);
141252
- return appended === void 0 ? void 0 : foldNewer(previous.state, appended.bytes, previous.offset);
142014
+ return appended === void 0 ? void 0 : foldNewer(previous, appended.bytes, previous.offset);
141253
142015
  }
141254
142016
  const from = Math.max(0, size - MAX_TRANSCRIPT_READ_BYTES - 1);
141255
142017
  const tail = ports.readRange(transcriptPath, from, MAX_TRANSCRIPT_READ_BYTES + 1);
@@ -141257,14 +142019,16 @@ function newerFrom(ports, transcriptPath, size, previous) {
141257
142019
  return void 0;
141258
142020
  }
141259
142021
  const firstLine = from === 0 ? 0 : tail.bytes.indexOf(NEWLINE2) + 1;
141260
- return firstLine === 0 && from > 0 ? void 0 : foldNewer(EMPTY_LATEST_STATE, tail.bytes.subarray(firstLine), from + firstLine);
142022
+ const start = from + firstLine;
142023
+ return firstLine === 0 && from > 0 ? void 0 : foldNewer({ state: EMPTY_LATEST_STATE, activity: cumulative.offset <= start ? replayMemoryOf(cumulative.activity.latest) : EMPTY_ACTIVITY_LATEST }, tail.bytes.subarray(firstLine), start);
141261
142024
  }
141262
- function foldNewer(state, bytes, offset) {
141263
- let folded = state;
142025
+ function foldNewer(from, bytes, offset) {
142026
+ let { state, activity } = from;
141264
142027
  const consumed = eachRecord(bytes, (record2) => {
141265
- folded = foldLatest(folded, record2);
142028
+ state = foldLatest(state, record2);
142029
+ activity = foldActivityLatest(activity, record2);
141266
142030
  });
141267
- return { offset: offset + consumed, state: folded };
142031
+ return { offset: offset + consumed, state, activity };
141268
142032
  }
141269
142033
 
141270
142034
  // src/statusline/render.ts
@@ -151234,8 +151998,8 @@ function writeStoredMcpPermissions(paths, permissions) {
151234
151998
  writeJsonAtomic(paths.mcpPermissionsFile, { writes: permissions.writes, remoteControl: permissions.remoteControl, history: permissions.history });
151235
151999
  import_node_fs24.default.chmodSync(paths.mcpPermissionsFile, OWNER_ONLY_MODE);
151236
152000
  }
151237
- function effectiveMcpPermissions(flags, stored) {
151238
- return { writes: flags.writes || stored.writes, remoteControl: flags.remoteControl || stored.remoteControl, history: flags.history || stored.history };
152001
+ function effectiveMcpPermissions(flags, stored2) {
152002
+ return { writes: flags.writes || stored2.writes, remoteControl: flags.remoteControl || stored2.remoteControl, history: flags.history || stored2.history };
151239
152003
  }
151240
152004
  function watchMcpPermissions(paths, onChange) {
151241
152005
  const directory = import_node_path62.default.dirname(paths.mcpPermissionsFile);
@@ -151378,14 +152142,14 @@ function registerMcpCommand(program2, deps) {
151378
152142
  );
151379
152143
  withExamples(
151380
152144
  permissions.command("show").description("Print the permissions the stored file grants.").option("--json", "Print them as JSON.").action((options) => {
151381
- const stored = readStoredMcpPermissions(deps.paths);
152145
+ const stored2 = readStoredMcpPermissions(deps.paths);
151382
152146
  if (options.json === true) {
151383
- printJson(stored);
152147
+ printJson(stored2);
151384
152148
  return;
151385
152149
  }
151386
- console.log(`writes: ${stored.writes ? "allowed" : "not allowed"}`);
151387
- console.log(`remote-control: ${stored.remoteControl ? "allowed" : "not allowed"}`);
151388
- console.log(`history: ${stored.history ? "allowed" : "not allowed"}`);
152150
+ console.log(`writes: ${stored2.writes ? "allowed" : "not allowed"}`);
152151
+ console.log(`remote-control: ${stored2.remoteControl ? "allowed" : "not allowed"}`);
152152
+ console.log(`history: ${stored2.history ? "allowed" : "not allowed"}`);
151389
152153
  }),
151390
152154
  ["agent-shim mcp permissions show"]
151391
152155
  );
@@ -151653,8 +152417,8 @@ function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps
151653
152417
  if (deps.isInteractive()) {
151654
152418
  throw new UsageError("Pass the token on standard input, so it never lands in your shell history: run `claude setup-token`, then pipe or redirect its token into this command.");
151655
152419
  }
151656
- const stored = storeIdentityToken(deps.paths, name, await readStandardInput());
151657
- const updated = setIdentityCredential(deps.paths, name, { sources: [{ file: stored }], target: "oauthToken" });
152420
+ const stored2 = storeIdentityToken(deps.paths, name, await readStandardInput());
152421
+ const updated = setIdentityCredential(deps.paths, name, { sources: [{ file: stored2 }], target: "oauthToken" });
151658
152422
  if (updated.credential !== void 0) {
151659
152423
  console.log(`Identity "${name}" now authenticates with credential ${describeCredential(updated.credential)}.`);
151660
152424
  }
@@ -153878,7 +154642,7 @@ async function realRefresher(params) {
153878
154642
  }
153879
154643
 
153880
154644
  // src/supervise/launch.ts
153881
- var import_node_crypto28 = require("node:crypto");
154645
+ var import_node_crypto29 = require("node:crypto");
153882
154646
  init_claudeSession();
153883
154647
  init_pool();
153884
154648
  init_realPorts();
@@ -154470,7 +155234,7 @@ async function runSupervised(params) {
154470
155234
  log.warn(`agent-shim: pool "${pool}" resumes on a spent quota, which needs a POSIX terminal; this launch runs unsupervised`);
154471
155235
  return void 0;
154472
155236
  }
154473
- const first = initialConversationOf(params.passthrough, { newId: import_node_crypto28.randomUUID, latestId: () => latestConversationId(farm.fs, { claudeHome: farm.claudeHome, cwd: farm.cwd }) });
155237
+ const first = initialConversationOf(params.passthrough, { newId: import_node_crypto29.randomUUID, latestId: () => latestConversationId(farm.fs, { claudeHome: farm.claudeHome, cwd: farm.cwd }) });
154474
155238
  if ("reason" in first) {
154475
155239
  log.warn(`agent-shim: pool "${pool}" resumes on a spent quota, but this launch runs unsupervised: ${first.reason}`);
154476
155240
  return void 0;