blun-king-cli 9.1.596 → 9.1.599

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/blun.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:2c4b3f451c41d328bb5eb43ffb226f0f3b0c458270217cecb6e1ffc63287e8bd
2
+ // BLUN_BUILD_INPUT_SHA256:25c271186c418490335e30ef395705d13d90d816c66cac47bb57835f2482f093
3
3
  import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
4
4
  import { dirname as __cjsShimDirname } from 'node:path';
5
5
  const __filename = __cjsShimFileURLToPath(import.meta.url);
@@ -1175,7 +1175,7 @@ function normalizeBlunToolSchema(schema) {
1175
1175
  }
1176
1176
  function ensureBlunPropertyTypes(schema) {
1177
1177
  const normalized = cloneJsonValue(schema);
1178
- if (!isRecord$26(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1178
+ if (!isRecord$27(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1179
1179
  recurseSchema(normalized);
1180
1180
  return normalized;
1181
1181
  }
@@ -1236,7 +1236,7 @@ function resolveLocalJsonPointer(root, ref) {
1236
1236
  let current = root;
1237
1237
  for (const rawPart of ref.slice(2).split("/")) {
1238
1238
  const part = unescapeJsonPointerPart(rawPart);
1239
- if (isRecord$26(current)) {
1239
+ if (isRecord$27(current)) {
1240
1240
  if (!hasOwn(current, part)) return { found: false };
1241
1241
  current = current[part];
1242
1242
  } else if (Array.isArray(current)) {
@@ -1258,20 +1258,20 @@ function parseJsonPointerArrayIndex(part) {
1258
1258
  return Number(part);
1259
1259
  }
1260
1260
  function recurseSchema(node) {
1261
- if (!isRecord$26(node)) return;
1261
+ if (!isRecord$27(node)) return;
1262
1262
  visitChildSchemas(node, normalizeProperty);
1263
1263
  }
1264
1264
  function visitChildSchemas(node, visit) {
1265
1265
  for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
1266
1266
  const value = node[key];
1267
1267
  if (kind === "single") {
1268
- if (isRecord$26(value)) visit(value);
1268
+ if (isRecord$27(value)) visit(value);
1269
1269
  } else if (kind === "array") {
1270
1270
  if (Array.isArray(value)) for (const item of value) visit(item);
1271
1271
  } else if (kind === "map") {
1272
- if (isRecord$26(value)) for (const item of Object.values(value)) visit(item);
1272
+ if (isRecord$27(value)) for (const item of Object.values(value)) visit(item);
1273
1273
  } else if (kind === "schema-or-array") {
1274
- if (isRecord$26(value)) visit(value);
1274
+ if (isRecord$27(value)) visit(value);
1275
1275
  else if (Array.isArray(value)) for (const item of value) visit(item);
1276
1276
  }
1277
1277
  }
@@ -1283,7 +1283,7 @@ function childSchemaKeysForParentType(parentType) {
1283
1283
  });
1284
1284
  }
1285
1285
  function normalizeProperty(node) {
1286
- if (!isRecord$26(node)) return;
1286
+ if (!isRecord$27(node)) return;
1287
1287
  if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
1288
1288
  const enumValues = node["enum"];
1289
1289
  if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
@@ -1367,14 +1367,14 @@ function hasAnyKey(obj, keys) {
1367
1367
  }
1368
1368
  function cloneJsonValue(value) {
1369
1369
  if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
1370
- if (isRecord$26(value)) {
1370
+ if (isRecord$27(value)) {
1371
1371
  const cloned = {};
1372
1372
  for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
1373
1373
  return cloned;
1374
1374
  }
1375
1375
  return value;
1376
1376
  }
1377
- function isRecord$26(value) {
1377
+ function isRecord$27(value) {
1378
1378
  return typeof value === "object" && value !== null && !Array.isArray(value);
1379
1379
  }
1380
1380
  function hasOwn(obj, key) {
@@ -1536,6 +1536,7 @@ function parseExplicitMaxContextTokens(message) {
1536
1536
  return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : void 0;
1537
1537
  }
1538
1538
  function isRetryableGenerateError(error) {
1539
+ if (error instanceof APIContextOverflowError) return false;
1539
1540
  if (error instanceof CompactionStallError$1) return true;
1540
1541
  if (error instanceof APIConnectionError || error instanceof APITimeoutError) return true;
1541
1542
  if (error instanceof APIEmptyResponseError) return true;
@@ -1572,7 +1573,8 @@ function isProviderQuotaExhaustedMessage(message) {
1572
1573
  return PROVIDER_QUOTA_EXHAUSTED_MESSAGE_PATTERN.test(lowerMessage) && PROVIDER_QUOTA_EXHAUSTED_CONTEXT_PATTERNS.some((pattern) => pattern.test(lowerMessage));
1573
1574
  }
1574
1575
  function isContextOverflowStatusError(statusCode, message) {
1575
- if (statusCode !== 400 && statusCode !== 413 && statusCode !== 422) return false;
1576
+ const wrappedRejection = statusCode === 502 && /\bHTTP(?: Error)? (?:400|413|422):/i.test(message);
1577
+ if (statusCode !== 400 && statusCode !== 413 && statusCode !== 422 && !wrappedRejection) return false;
1576
1578
  const lowerMessage = message.toLowerCase();
1577
1579
  return CONTEXT_OVERFLOW_MESSAGE_PATTERNS.some((pattern) => pattern.test(lowerMessage));
1578
1580
  }
@@ -1998,7 +2000,8 @@ var init_fetch_http_client = __esmMin((() => {
1998
2000
  const startedAt = performance.now();
1999
2001
  try {
2000
2002
  const response = await this.fetch(`${this.baseUrl}${pathname}`, init);
2001
- const willRetry = attempt < maxRetries && shouldRetryResponse(response);
2003
+ const gatewayError = response.status === 502 ? await responseError(response) : void 0;
2004
+ const willRetry = attempt < maxRetries && shouldRetryResponse(response) && !(gatewayError instanceof APIContextOverflowError);
2002
2005
  notifyTransportAttempt(requestOptions?.onTransportAttempt, {
2003
2006
  transportAttempt: attempt + 1,
2004
2007
  ...requestBytes === void 0 ? {} : { requestBytes },
@@ -2010,12 +2013,12 @@ var init_fetch_http_client = __esmMin((() => {
2010
2013
  if (response.ok) return response;
2011
2014
  if (willRetry) {
2012
2015
  const delayMs = retryDelayMs(response.headers, attempt);
2013
- await response.body?.cancel();
2016
+ if (gatewayError === void 0) await response.body?.cancel();
2014
2017
  await waitForRetry(delayMs, init.signal);
2015
2018
  attempt += 1;
2016
2019
  continue;
2017
2020
  }
2018
- throw await responseError(response);
2021
+ throw gatewayError ?? await responseError(response);
2019
2022
  } catch (error) {
2020
2023
  if (error instanceof ChatProviderError) throw error;
2021
2024
  const willRetry = attempt < maxRetries && init.signal?.aborted !== true && isRetryableTransportFailure(error);
@@ -2578,9 +2581,23 @@ function extractUsageFromChunk(chunk) {
2578
2581
  if (choiceUsage !== null && choiceUsage !== void 0 && typeof choiceUsage === "object") return choiceUsage;
2579
2582
  return null;
2580
2583
  }
2584
+ function contextOverflowOutputCap(error, currentCap) {
2585
+ const maxContext = error.maxContextTokens;
2586
+ const counts = /requested ([\d,_]+) output tokens and your prompt contains (at least )?([\d,_]+) input tokens/i.exec(error.message);
2587
+ if (maxContext === void 0 || counts === null || !Number.isSafeInteger(maxContext) || maxContext <= 0) return;
2588
+ const requestedOutput = Number(counts[1].replaceAll(/[,_]/g, ""));
2589
+ const input = Number(counts[3].replaceAll(/[,_]/g, ""));
2590
+ if (!Number.isSafeInteger(input) || input < 0 || !Number.isSafeInteger(requestedOutput) || requestedOutput <= 0 || !Number.isSafeInteger(input + requestedOutput) || input + requestedOutput <= maxContext) return;
2591
+ const available = maxContext - input;
2592
+ const headroom = Math.min(1024, Math.max(1, Math.ceil(available * .01)));
2593
+ const cap = Math.min(counts[2] === void 0 ? requestedOutput - 1 : Math.floor(requestedOutput / 2), available - headroom);
2594
+ if (cap < 1 || currentCap !== void 0 && (typeof currentCap !== "number" || !Number.isSafeInteger(currentCap) || cap >= currentCap)) return;
2595
+ return cap;
2596
+ }
2581
2597
  var BLUN_TOOL_CALL_ID_POLICY, BLUN_INBOUND_REASONING_KEYS, BLUN_VISION_DATA_URL, BLUN_VISION_MAX_ATTACHMENTS, BLUN_VISION_MAX_IMAGE_BYTES, BlunStreamedMessage, BlunChatProvider;
2582
2598
  var init_blun = __esmMin((() => {
2583
2599
  init_blun_schema();
2600
+ init_errors$10();
2584
2601
  init_blun_files();
2585
2602
  init_chat_completions_wire();
2586
2603
  init_chat_completions_stream();
@@ -2844,8 +2861,23 @@ var init_blun = __esmMin((() => {
2844
2861
  ...options.onTransportAttempt !== void 0 ? { onTransportAttempt: options.onTransportAttempt } : {}
2845
2862
  } : void 0;
2846
2863
  options?.onRequestSent?.();
2847
- return new BlunStreamedMessage(await client.chat.completions.create(createParams, requestOptions), this._stream, reasoningRequested);
2864
+ let response;
2865
+ try {
2866
+ response = await client.chat.completions.create(createParams, requestOptions);
2867
+ } catch (error) {
2868
+ const rejection = normalizeFetchHttpError(error);
2869
+ const cap = rejection instanceof APIContextOverflowError ? contextOverflowOutputCap(rejection, createParams["max_completion_tokens"]) : void 0;
2870
+ if (cap === void 0) throw rejection;
2871
+ options?.signal?.throwIfAborted();
2872
+ options?.onRequestSent?.();
2873
+ response = await client.chat.completions.create({
2874
+ ...createParams,
2875
+ max_completion_tokens: cap
2876
+ }, requestOptions);
2877
+ }
2878
+ return new BlunStreamedMessage(response, this._stream, reasoningRequested);
2848
2879
  } catch (error) {
2880
+ if (options?.signal?.aborted === true) throw options.signal.reason ?? error;
2849
2881
  throw normalizeFetchHttpError(error);
2850
2882
  }
2851
2883
  }
@@ -10610,7 +10642,7 @@ function tokenFromWire(wire) {
10610
10642
  var init_types$17 = __esmMin((() => {}));
10611
10643
  //#endregion
10612
10644
  //#region ../../packages/oauth/src/utils.ts
10613
- function isRecord$25(value) {
10645
+ function isRecord$26(value) {
10614
10646
  return typeof value === "object" && value !== null && !Array.isArray(value);
10615
10647
  }
10616
10648
  var init_utils$1 = __esmMin((() => {}));
@@ -10934,7 +10966,7 @@ var init_storage = __esmMin((() => {
10934
10966
  } catch {
10935
10967
  return;
10936
10968
  }
10937
- if (!isRecord$25(parsed)) return void 0;
10969
+ if (!isRecord$26(parsed)) return void 0;
10938
10970
  return tokenFromWire(parsed);
10939
10971
  }
10940
10972
  async save(name, token) {
@@ -11028,7 +11060,7 @@ function extractApiErrorMessage(value) {
11028
11060
  }
11029
11061
  return;
11030
11062
  }
11031
- if (!isRecord$25(value)) return void 0;
11063
+ if (!isRecord$26(value)) return void 0;
11032
11064
  for (const key of DIRECT_ERROR_KEYS) {
11033
11065
  const message = stringField$4(value, key);
11034
11066
  if (message !== void 0) return message;
@@ -11036,7 +11068,7 @@ function extractApiErrorMessage(value) {
11036
11068
  const error = value["error"];
11037
11069
  const errorString = nonEmptyString$7(error);
11038
11070
  if (errorString !== void 0) return errorString;
11039
- if (isRecord$25(error)) for (const key of NESTED_ERROR_KEYS) {
11071
+ if (isRecord$26(error)) for (const key of NESTED_ERROR_KEYS) {
11040
11072
  const message = stringField$4(error, key);
11041
11073
  if (message !== void 0) return message;
11042
11074
  }
@@ -11126,7 +11158,7 @@ async function postForm(url, params, deviceHeaders, options) {
11126
11158
  let data = {};
11127
11159
  try {
11128
11160
  const parsed = await response.json();
11129
- if (isRecord$25(parsed)) data = parsed;
11161
+ if (isRecord$26(parsed)) data = parsed;
11130
11162
  } catch {}
11131
11163
  return {
11132
11164
  status,
@@ -13038,9 +13070,9 @@ function blunContextWindowsUrl(oauthHost) {
13038
13070
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}/api/verbrauch/tarife`;
13039
13071
  }
13040
13072
  function parseManagedContextWindow(payload, plan) {
13041
- if (!isRecord$25(payload)) return void 0;
13073
+ if (!isRecord$26(payload)) return void 0;
13042
13074
  const contextWindows = payload["kontext"];
13043
- if (!isRecord$25(contextWindows)) return void 0;
13075
+ if (!isRecord$26(contextWindows)) return void 0;
13044
13076
  const value = contextWindows[plan];
13045
13077
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
13046
13078
  }
@@ -13075,7 +13107,7 @@ function parseManagedUsagePayload(payload) {
13075
13107
  const plan = typeof rec["plan"] === "string" && rec["plan"].trim().length > 0 ? rec["plan"].trim() : void 0;
13076
13108
  const contextWindowTokens = managedContextWindowFrom(rec);
13077
13109
  const unlimited = rec["unlimited"] === true;
13078
- const stand = isRecord$25(rec["stand"]) ? rec["stand"] : void 0;
13110
+ const stand = isRecord$26(rec["stand"]) ? rec["stand"] : void 0;
13079
13111
  if (stand !== void 0) for (const [sourceKey, id, label] of ACCOUNT_USAGE_WINDOWS) {
13080
13112
  const row = toAccountUsageRow(stand[sourceKey], id, label, unlimited);
13081
13113
  if (row !== null) limits.push(row);
@@ -13085,9 +13117,9 @@ function parseManagedUsagePayload(payload) {
13085
13117
  const item = rawLimits[idx];
13086
13118
  if (!item || typeof item !== "object") continue;
13087
13119
  const detailRaw = item["detail"];
13088
- const detail = isRecord$25(detailRaw) ? detailRaw : item;
13120
+ const detail = isRecord$26(detailRaw) ? detailRaw : item;
13089
13121
  const windowRaw = item["window"];
13090
- const row = toUsageRow(detail, limitLabel(item, detail, isRecord$25(windowRaw) ? windowRaw : {}, idx));
13122
+ const row = toUsageRow(detail, limitLabel(item, detail, isRecord$26(windowRaw) ? windowRaw : {}, idx));
13091
13123
  if (row !== null) limits.push(row);
13092
13124
  }
13093
13125
  return {
@@ -13111,7 +13143,7 @@ function managedContextWindowFrom(payload) {
13111
13143
  return values.every((value) => value === first) ? first : void 0;
13112
13144
  }
13113
13145
  function toAccountUsageRow(raw, id, label, accountUnlimited) {
13114
- if (!isRecord$25(raw)) return null;
13146
+ if (!isRecord$26(raw)) return null;
13115
13147
  const used = toInt(raw["verbraucht"]);
13116
13148
  const unlimited = accountUnlimited || raw["unlimited"] === true;
13117
13149
  const fraction = raw["anteil"];
@@ -13144,7 +13176,7 @@ function toAccountUsageRow(raw, id, label, accountUnlimited) {
13144
13176
  };
13145
13177
  }
13146
13178
  function toUsageRow(raw, defaultLabel) {
13147
- if (!isRecord$25(raw)) return null;
13179
+ if (!isRecord$26(raw)) return null;
13148
13180
  const unlimited = raw["unlimited"] === true;
13149
13181
  const limit = toInt(raw["limit"]);
13150
13182
  let used = toInt(raw["used"]);
@@ -13265,7 +13297,7 @@ function isManagedQuotaErrorMessage(message) {
13265
13297
  return /you(?:'|’)?ve reached your usage limit/.test(normalized) && /billing cycle|quota will be (?:refreshed|reset)|purchase extra usage/.test(normalized);
13266
13298
  }
13267
13299
  function hasManagedUsageShape(payload) {
13268
- if (!isRecord$25(payload)) return false;
13300
+ if (!isRecord$26(payload)) return false;
13269
13301
  let recognized = false;
13270
13302
  if ("context_window_tokens" in payload || "contextWindowTokens" in payload) {
13271
13303
  recognized = true;
@@ -13281,15 +13313,15 @@ function hasManagedUsageShape(payload) {
13281
13313
  if (!Array.isArray(limits)) return false;
13282
13314
  for (let index = 0; index < limits.length; index++) {
13283
13315
  const item = limits[index];
13284
- if (!isRecord$25(item)) return false;
13285
- const detail = isRecord$25(item["detail"]) ? item["detail"] : item;
13286
- if (toUsageRow(detail, limitLabel(item, detail, isRecord$25(item["window"]) ? item["window"] : {}, index)) === null) return false;
13316
+ if (!isRecord$26(item)) return false;
13317
+ const detail = isRecord$26(item["detail"]) ? item["detail"] : item;
13318
+ if (toUsageRow(detail, limitLabel(item, detail, isRecord$26(item["window"]) ? item["window"] : {}, index)) === null) return false;
13287
13319
  }
13288
13320
  }
13289
13321
  if ("stand" in payload) {
13290
13322
  recognized = true;
13291
13323
  const stand = payload["stand"];
13292
- if (!isRecord$25(stand)) return false;
13324
+ if (!isRecord$26(stand)) return false;
13293
13325
  const windows = ACCOUNT_USAGE_WINDOWS.filter(([sourceKey]) => sourceKey in stand);
13294
13326
  if (windows.length === 0) return false;
13295
13327
  const unlimited = payload["unlimited"] === true;
@@ -13385,8 +13417,8 @@ function userExtras(existing, remoteOwnedFields) {
13385
13417
  return out;
13386
13418
  }
13387
13419
  function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
13388
- const current = isRecord$25(existing) ? existing : {};
13389
- const overrides = cloneOverrides(isRecord$25(current["overrides"]) ? current["overrides"] : void 0);
13420
+ const current = isRecord$26(existing) ? existing : {};
13421
+ const overrides = cloneOverrides(isRecord$26(current["overrides"]) ? current["overrides"] : void 0);
13390
13422
  return {
13391
13423
  ...userExtras(current, remoteOwnedFields),
13392
13424
  ...remote,
@@ -13568,7 +13600,7 @@ function parseModelContextLength(item, modelId) {
13568
13600
  return values[0];
13569
13601
  }
13570
13602
  function toModelInfo(item) {
13571
- if (!isRecord$25(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13603
+ if (!isRecord$26(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13572
13604
  const contextLength = parseModelContextLength(item, item["id"]);
13573
13605
  const displayName = item["display_name"];
13574
13606
  const normalizedDisplayName = typeof displayName === "string" && displayName.length > 0 ? displayName : void 0;
@@ -13655,7 +13687,7 @@ async function fetchManagedBlunCodeModels(options) {
13655
13687
  throw new Error(message);
13656
13688
  }
13657
13689
  const payload = await response.json();
13658
- if (!isRecord$25(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
13690
+ if (!isRecord$26(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
13659
13691
  return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
13660
13692
  }
13661
13693
  throw new Error(`Failed to list BLUN models for ${baseUrl}.`);
@@ -13698,11 +13730,11 @@ function applyManagedBlunCodeConfig(config, options) {
13698
13730
  apiKey
13699
13731
  };
13700
13732
  const upstreamKeys = new Set(options.models.map((m) => managedModelKey(m.id)));
13701
- for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$25(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
13733
+ for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$26(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
13702
13734
  for (const model of options.models) {
13703
13735
  const capabilities = capabilitiesForModel(model);
13704
13736
  const key = managedModelKey(model.id);
13705
- const existing = isRecord$25(existingModels[key]) ? existingModels[key] : {};
13737
+ const existing = isRecord$26(existingModels[key]) ? existingModels[key] : {};
13706
13738
  const supportsAdaptiveThinking = capabilities?.includes("thinking") === true || capabilities?.includes("always_thinking") === true;
13707
13739
  existingModels[key] = mergeRefreshedModelAlias(existing, {
13708
13740
  provider: BLUN_PROVIDER_NAME$1,
@@ -13750,7 +13782,7 @@ function applyManagedBlunCodeLogoutConfig(config) {
13750
13782
  let removedDefaultModel = false;
13751
13783
  const existingModels = config.models ?? {};
13752
13784
  for (const [key, model] of Object.entries(existingModels)) {
13753
- if (!isRecord$25(model) || model["provider"] !== "managed:blun") continue;
13785
+ if (!isRecord$26(model) || model["provider"] !== "managed:blun") continue;
13754
13786
  delete existingModels[key];
13755
13787
  if (config.defaultModel === key) removedDefaultModel = true;
13756
13788
  }
@@ -13790,7 +13822,7 @@ function selectDefaultModel(config, models, options) {
13790
13822
  function canPreserveDefaultModel(existingModels, defaultModel, managedModels) {
13791
13823
  if (managedModels.has(defaultModel)) return true;
13792
13824
  const existing = existingModels[defaultModel];
13793
- return isRecord$25(existing) && existing["provider"] !== "managed:blun";
13825
+ return isRecord$26(existing) && existing["provider"] !== "managed:blun";
13794
13826
  }
13795
13827
  function assertPositiveContextLength(model) {
13796
13828
  if (!Number.isInteger(model.contextLength) || model.contextLength <= 0) throw new Error(`BLUN model "${model.id}" must include a positive context_length.`);
@@ -13868,13 +13900,13 @@ function blunManagedQuotaUrl(oauthHost) {
13868
13900
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}${MANAGED_QUOTA_PATH}`;
13869
13901
  }
13870
13902
  function parseManagedQuotaPayload(payload) {
13871
- if (!isRecord$25(payload)) return void 0;
13903
+ if (!isRecord$26(payload)) return void 0;
13872
13904
  const plan = nonEmptyString$6(payload["plan"]);
13873
13905
  const paid = payload["bezahlt"];
13874
13906
  const creditCents = payload["guthaben_cent"];
13875
13907
  const billingKind = nonEmptyString$6(payload["art"]);
13876
13908
  const globalUnlimited = payload["unlimited"];
13877
- if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$25(payload["stand"])) return;
13909
+ if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$26(payload["stand"])) return;
13878
13910
  if (!hasStrictQuotaStand(payload["stand"], globalUnlimited === true)) return void 0;
13879
13911
  const limits = parseManagedUsagePayload(payload).limits;
13880
13912
  if (limits.length !== REQUIRED_WINDOWS.length || REQUIRED_WINDOWS.some(([, id]) => limits.filter((row) => row.id === id).length !== 1)) return;
@@ -13944,7 +13976,7 @@ function nonEmptyString$6(value) {
13944
13976
  function hasStrictQuotaStand(stand, globalUnlimited) {
13945
13977
  return REQUIRED_WINDOWS.every(([sourceKey]) => {
13946
13978
  const row = stand[sourceKey];
13947
- if (!isRecord$25(row)) return false;
13979
+ if (!isRecord$26(row)) return false;
13948
13980
  const used = row["verbraucht"];
13949
13981
  const rowUnlimited = row["unlimited"];
13950
13982
  if (rowUnlimited !== void 0 && typeof rowUnlimited !== "boolean") return false;
@@ -21131,7 +21163,7 @@ function parseSkillText(options) {
21131
21163
  throw error;
21132
21164
  }
21133
21165
  const frontmatter = parsed.data ?? {};
21134
- if (!isRecord$24(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
21166
+ if (!isRecord$25(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
21135
21167
  const metadata = normalizeMetadata(frontmatter);
21136
21168
  if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
21137
21169
  const name = nonEmptyString$4(metadata.name);
@@ -21244,7 +21276,7 @@ function tokenizeArgs(raw) {
21244
21276
  function nonEmptyString$4(value) {
21245
21277
  return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
21246
21278
  }
21247
- function isRecord$24(value) {
21279
+ function isRecord$25(value) {
21248
21280
  return typeof value === "object" && value !== null && !Array.isArray(value);
21249
21281
  }
21250
21282
  var import_regexp_escape, FrontmatterError, SkillParseError, UnsupportedSkillTypeError, FENCE, METADATA_ALIASES;
@@ -21293,7 +21325,7 @@ var init_parser$1 = __esmMin((() => {
21293
21325
  function parseCommandText(input) {
21294
21326
  const { text, commandPath, pluginId } = input;
21295
21327
  const parsed = parseFrontmatter(text);
21296
- const frontmatter = isRecord$23(parsed.data) ? parsed.data : {};
21328
+ const frontmatter = isRecord$24(parsed.data) ? parsed.data : {};
21297
21329
  const baseName = input.fallbackName ?? path.basename(commandPath).replace(/\.md$/i, "");
21298
21330
  const name = nonEmptyString$3(frontmatter["name"]) ?? baseName;
21299
21331
  const body = parsed.body.trim();
@@ -21335,7 +21367,7 @@ function descriptionFromBody(body) {
21335
21367
  if (firstLine === void 0) return "No description provided.";
21336
21368
  return firstLine.length > 240 ? `${firstLine.slice(0, 239)}…` : firstLine;
21337
21369
  }
21338
- function isRecord$23(value) {
21370
+ function isRecord$24(value) {
21339
21371
  return typeof value === "object" && value !== null && !Array.isArray(value);
21340
21372
  }
21341
21373
  var init_commands = __esmMin((() => {
@@ -28886,7 +28918,7 @@ var init_per_id_json_store = __esmMin((() => {
28886
28918
  }));
28887
28919
  //#endregion
28888
28920
  //#region ../../packages/agent-core/src/agent/background/resume-store.ts
28889
- var BACKGROUND_TASK_ID, id, digest$2, timestamp$2, ResumeIntentSchema, hash$3, isRecord$22, TaskResumeStore;
28921
+ var BACKGROUND_TASK_ID, id, digest$2, timestamp$2, ResumeIntentSchema, hash$3, isRecord$23, TaskResumeStore;
28890
28922
  var init_resume_store = __esmMin((() => {
28891
28923
  init_zod$1();
28892
28924
  BACKGROUND_TASK_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-z]{8}$/;
@@ -28911,7 +28943,7 @@ var init_resume_store = __esmMin((() => {
28911
28943
  startedAt: timestamp$2.nullable()
28912
28944
  }).strict();
28913
28945
  hash$3 = (value) => createHash("sha256").update(value).digest("hex");
28914
- isRecord$22 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
28946
+ isRecord$23 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
28915
28947
  TaskResumeStore = class {
28916
28948
  home;
28917
28949
  constructor(home) {
@@ -28966,9 +28998,9 @@ var init_resume_store = __esmMin((() => {
28966
28998
  }
28967
28999
  async readOwnedTask(taskId) {
28968
29000
  const task = await this.read("tasks", taskId);
28969
- if (!isRecord$22(task)) throw new Error("Task has no persisted local record.");
29001
+ if (!isRecord$23(task)) throw new Error("Task has no persisted local record.");
28970
29002
  const owner = task["resumeOwnership"];
28971
- if (!isRecord$22(owner) || owner["version"] !== 1 || owner["scope"] !== hash$3(await this.root()) || owner["taskId"] !== taskId || task["taskId"] !== taskId || task["kind"] !== "agent" || owner["agentId"] !== task["agentId"] || owner["startedAt"] !== task["startedAt"]) throw new Error("Task ownership is unverified; historical or foreign records cannot be resumed automatically.");
29003
+ if (!isRecord$23(owner) || owner["version"] !== 1 || owner["scope"] !== hash$3(await this.root()) || owner["taskId"] !== taskId || task["taskId"] !== taskId || task["kind"] !== "agent" || owner["agentId"] !== task["agentId"] || owner["startedAt"] !== task["startedAt"]) throw new Error("Task ownership is unverified; historical or foreign records cannot be resumed automatically.");
28972
29004
  const { resumeOwnership: _ownership, ...info } = task;
28973
29005
  return info;
28974
29006
  }
@@ -29089,12 +29121,12 @@ function legacyStatusToCurrent$1(task) {
29089
29121
  return task.status;
29090
29122
  }
29091
29123
  function isReadablePersistedTask$1(obj) {
29092
- return isRecord$21(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
29124
+ return isRecord$22(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
29093
29125
  }
29094
29126
  function isLegacyPersistedTask$1(task) {
29095
29127
  return "task_id" in task;
29096
29128
  }
29097
- function isRecord$21(value) {
29129
+ function isRecord$22(value) {
29098
29130
  return typeof value === "object" && value !== null;
29099
29131
  }
29100
29132
  function optionalNonEmptyString$2(value) {
@@ -228671,7 +228703,7 @@ function escapeXml(value) {
228671
228703
  function locationKey(messageIndex, partIndex) {
228672
228704
  return `${String(messageIndex)}:${String(partIndex)}`;
228673
228705
  }
228674
- function isRecord$20(value) {
228706
+ function isRecord$21(value) {
228675
228707
  return value !== null && typeof value === "object" && !Array.isArray(value);
228676
228708
  }
228677
228709
  function isNonNegativeInteger$1(value) {
@@ -228872,7 +228904,7 @@ var init_vision_reader = __esmMin((() => {
228872
228904
  reason: "malformed"
228873
228905
  };
228874
228906
  }
228875
- if (!isRecord$20(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
228907
+ if (!isRecord$21(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
228876
228908
  ok: false,
228877
228909
  reason: "malformed"
228878
228910
  };
@@ -235010,7 +235042,7 @@ function structuredOutput(stdout, input) {
235010
235042
  return {
235011
235043
  ...result,
235012
235044
  additionalContext: input["hook_event_name"] === "UserPromptSubmit" && hookSpecificOutput?.hookEventName === "UserPromptSubmit" ? hookSpecificOutput.additionalContext : void 0,
235013
- updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$19(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
235045
+ updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$20(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
235014
235046
  };
235015
235047
  }
235016
235048
  return {
@@ -235079,7 +235111,7 @@ function killProcessTreeWindows(child, force) {
235079
235111
  } catch {}
235080
235112
  }
235081
235113
  }
235082
- function isRecord$19(value) {
235114
+ function isRecord$20(value) {
235083
235115
  return typeof value === "object" && value !== null && !Array.isArray(value);
235084
235116
  }
235085
235117
  function errorMessage$12(error) {
@@ -235096,7 +235128,7 @@ var init_runner = __esmMin((() => {
235096
235128
  if (typeof value === "string") return value;
235097
235129
  if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
235098
235130
  }, string().optional());
235099
- HookSpecificOutputSchema = preprocess((value) => isRecord$19(value) ? value : void 0, looseObject({
235131
+ HookSpecificOutputSchema = preprocess((value) => isRecord$20(value) ? value : void 0, looseObject({
235100
235132
  message: OptionalStringSchema,
235101
235133
  additionalContext: OptionalStringSchema,
235102
235134
  permissionDecision: unknown().optional(),
@@ -235271,7 +235303,16 @@ var init_engine = __esmMin((() => {
235271
235303
  };
235272
235304
  }
235273
235305
  if (this.admissionClosed) return void 0;
235274
- return runHook(hook.command, inputData, {
235306
+ let hookInput;
235307
+ try {
235308
+ hookInput = this.options.runtimeInput?.(hook, inputData) ?? inputData;
235309
+ } catch {
235310
+ return {
235311
+ action: "block",
235312
+ reason: "Hook input preparation failed."
235313
+ };
235314
+ }
235315
+ return runHook(hook.command, hookInput, {
235275
235316
  timeout: hook.timeout ?? DEFAULT_HOOK_TIMEOUT_SECONDS,
235276
235317
  cwd: hook.cwd ?? (this.options.cwd === "" ? void 0 : this.options.cwd),
235277
235318
  env: hook.env,
@@ -236358,7 +236399,7 @@ function isTelegramGroupInput(input) {
236358
236399
  return chatId === void 0 || chatId.startsWith("-");
236359
236400
  });
236360
236401
  }
236361
- function isPersonalMemoryToolName$1(name) {
236402
+ function isPersonalMemoryToolName$2(name) {
236362
236403
  return name.startsWith("mcp__personal-memory__");
236363
236404
  }
236364
236405
  function isPersonalMemoryRecallToolName(name) {
@@ -236372,7 +236413,7 @@ function parsePersonalMemoryRecall(output) {
236372
236413
  } catch {
236373
236414
  return { kind: "invalid" };
236374
236415
  }
236375
- if (!isRecord$18(parsed) || !isRecord$18(parsed["personal_memory"])) return { kind: "invalid" };
236416
+ if (!isRecord$19(parsed) || !isRecord$19(parsed["personal_memory"])) return { kind: "invalid" };
236376
236417
  const memory = parsed["personal_memory"];
236377
236418
  const savedRaw = memory["saved"];
236378
236419
  const threadsRaw = memory["threads"];
@@ -236381,7 +236422,7 @@ function parsePersonalMemoryRecall(output) {
236381
236422
  if (savedRaw.length > MAX_SAVED_MEMORIES || threadsRaw.length > MAX_THREADS || historyRaw.length > 0) return { kind: "invalid" };
236382
236423
  const saved = [];
236383
236424
  for (const value of savedRaw) {
236384
- if (!isRecord$18(value)) return { kind: "invalid" };
236425
+ if (!isRecord$19(value)) return { kind: "invalid" };
236385
236426
  const text = boundedTrimmedString(value["text"], MAX_MEMORY_TEXT_CHARS);
236386
236427
  const confidence = value["confidence"];
236387
236428
  if (text === void 0 || typeof confidence !== "string" || !CONFIDENCE_VALUES.has(confidence)) return { kind: "invalid" };
@@ -236392,7 +236433,7 @@ function parsePersonalMemoryRecall(output) {
236392
236433
  }
236393
236434
  const threads = [];
236394
236435
  for (const value of threadsRaw) {
236395
- if (!isRecord$18(value)) return { kind: "invalid" };
236436
+ if (!isRecord$19(value)) return { kind: "invalid" };
236396
236437
  const title = boundedTrimmedString(value["title"], MAX_THREAD_TITLE_CHARS);
236397
236438
  const summary = boundedTrimmedString(value["summary"], MAX_THREAD_SUMMARY_CHARS);
236398
236439
  if (title === void 0 || summary === void 0) return { kind: "invalid" };
@@ -236446,7 +236487,7 @@ function boundedTrimmedString(value, maxChars) {
236446
236487
  const trimmed = value.trim();
236447
236488
  return trimmed.length > 0 ? trimmed : void 0;
236448
236489
  }
236449
- function isRecord$18(value) {
236490
+ function isRecord$19(value) {
236450
236491
  return typeof value === "object" && value !== null && !Array.isArray(value);
236451
236492
  }
236452
236493
  var PERSONAL_MEMORY_HOST_RECALL_HANDLER$1, RECALL_LIMIT, RECALL_TIMEOUT_MS, MAX_QUERY_CHARS, MAX_WIRE_CHARS, MAX_SAVED_MEMORIES, MAX_THREADS, MAX_MEMORY_TEXT_CHARS, MAX_THREAD_TITLE_CHARS, MAX_THREAD_SUMMARY_CHARS, CONFIDENCE_VALUES, TELEGRAM_GROUP_MARKER_RE, TELEGRAM_MARKER_RE, TELEGRAM_CHANNEL_RE, TELEGRAM_SOURCE_RE, TELEGRAM_CHAT_ID_RE, TELEGRAM_SENDER_LINE_RE, TELEGRAM_ATTACHMENT_BLOCK_RE, TELEGRAM_ATTACHMENT_NOTICE_RE, TELEGRAM_IMAGE_ATTACHMENT_RE, GENERIC_IMAGE_QUERY, GENERIC_FILE_QUERY, GENERIC_EMPTY_QUERY, PERSONAL_MEMORY_RECALL_VARIANT, PersonalMemoryRecallInjector;
@@ -236536,8 +236577,8 @@ var init_personal_memory_recall = __esmMin((() => {
236536
236577
  * to read, write, list, or change any personal-memory state.
236537
236578
  */
236538
236579
  filterToolsForTurn(turnId, input, origin, tools) {
236539
- if (this.toolsAllowedForTurn(turnId, input, origin)) return tools.filter((tool) => !isPersonalMemoryRecallToolName(tool.name) && (!isPersonalMemoryToolName$1(tool.name) || this.isTrustedHostTool(tool.name)));
236540
- return tools.filter((tool) => !isPersonalMemoryToolName$1(tool.name));
236580
+ if (this.toolsAllowedForTurn(turnId, input, origin)) return tools.filter((tool) => !isPersonalMemoryRecallToolName(tool.name) && (!isPersonalMemoryToolName$2(tool.name) || this.isTrustedHostTool(tool.name)));
236581
+ return tools.filter((tool) => !isPersonalMemoryToolName$2(tool.name));
236541
236582
  }
236542
236583
  isTrustedHostTool(name) {
236543
236584
  const isHostTool = this.agent.isPersonalMemoryHostTool;
@@ -301492,8 +301533,38 @@ var init_mcp$1 = __esmMin((() => {
301492
301533
  }));
301493
301534
  //#endregion
301494
301535
  //#region ../../packages/agent-core/src/plugin/agent-spine-runtime.ts
301495
- var EMPTY_RUNTIME, AgentSpineSessionRuntime;
301536
+ /** AgentSpine reads prompt text; binary media stays in the original model input. */
301537
+ function projectAgentSpinePrompt(input) {
301538
+ if (typeof input["hook_event_name"] !== "string" || !PROMPT_EVENTS.has(input["hook_event_name"]) || !Array.isArray(input["prompt"])) return input;
301539
+ let changed = false;
301540
+ const prompt = input["prompt"].map((part) => {
301541
+ if (!isRecord$18(part)) return part;
301542
+ const field = part["type"] === "image_url" ? "imageUrl" : part["type"] === "audio_url" ? "audioUrl" : part["type"] === "video_url" ? "videoUrl" : void 0;
301543
+ if (field === void 0 || !isRecord$18(part[field]) || typeof part[field]["url"] !== "string") return part;
301544
+ const serialized = JSON.stringify(part);
301545
+ changed = true;
301546
+ return {
301547
+ type: "media_reference",
301548
+ media_type: part["type"],
301549
+ sha256: createHash("sha256").update(serialized).digest("hex"),
301550
+ original_bytes: Buffer.byteLength(serialized)
301551
+ };
301552
+ });
301553
+ return changed ? {
301554
+ ...input,
301555
+ prompt
301556
+ } : input;
301557
+ }
301558
+ function isRecord$18(value) {
301559
+ return typeof value === "object" && value !== null && !Array.isArray(value);
301560
+ }
301561
+ var PROMPT_EVENTS, EMPTY_RUNTIME, AgentSpineSessionRuntime;
301496
301562
  var init_agent_spine_runtime = __esmMin((() => {
301563
+ PROMPT_EVENTS = new Set([
301564
+ "UserPromptSubmit",
301565
+ "TurnStart",
301566
+ "SubagentStart"
301567
+ ]);
301497
301568
  EMPTY_RUNTIME = Object.freeze({
301498
301569
  AGENTSPINE_KING_TIMELINE_SOURCE: "",
301499
301570
  AGENTSPINE_KING_WIRE_PROTOCOL_VERSION: "",
@@ -302089,9 +302160,11 @@ var init_session$1 = __esmMin((() => {
302089
302160
  this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
302090
302161
  this.agentSpineRuntime = this.experimentalFlags.enabled("agent_spine_timeline") ? new AgentSpineSessionRuntime(options.agentSpineRuntime) : void 0;
302091
302162
  this.visionReader = (this.experimentalFlags.enabled("vision_reader") ? createVisionReader(options.config?.services?.visionReader) : void 0) ?? createManagedMediaVisionReader(options.toolServices?.media);
302163
+ const agentSpineHooks = new Set(options.agentSpineRuntime?.hooks);
302092
302164
  this.hookEngine = new HookEngine(options.hooks, {
302093
302165
  cwd: options.kaos.getcwd(),
302094
302166
  sessionId: options.id,
302167
+ runtimeInput: (hook, input) => agentSpineHooks.has(hook) ? projectAgentSpinePrompt(input) : input,
302095
302168
  runtimeEnv: (hook) => {
302096
302169
  const hostEnv = options.hookRuntimeEnv?.(hook);
302097
302170
  const timelineEnv = this.agentSpineRuntime?.forHook(hook);
@@ -338166,7 +338239,6 @@ var init_core_impl = __esmMin((() => {
338166
338239
  };
338167
338240
  }
338168
338241
  agentSpineRuntimeRecipients(pluginHooks, mcpConfig) {
338169
- if (!this.experimentalFlags.enabled("agent_spine_timeline")) return void 0;
338170
338242
  const plugin = this.plugins.get("agent-spine");
338171
338243
  if (plugin?.state !== "ok" || !plugin.enabled) return void 0;
338172
338244
  const hooks = pluginHooks.filter((hook) => hook.env?.["BLUN_PLUGIN_ROOT"] === plugin.root);
@@ -502931,7 +503003,7 @@ const BLUN_SPINNER_FRAMES = [
502931
503003
  "▝",
502932
503004
  "▗"
502933
503005
  ];
502934
- const THINKING_WORD_INTERVAL_MS = 6e3;
503006
+ const THINKING_WORD_INTERVAL_MS = 3e3;
502935
503007
  //#endregion
502936
503008
  //#region src/tui/components/messages/goal-format.ts
502937
503009
  function formatGoalElapsed(ms) {
@@ -514489,6 +514561,321 @@ var PluginCommandComponent = class extends Container {
514489
514561
  }
514490
514562
  };
514491
514563
  //#endregion
514564
+ //#region src/tui/components/messages/thinking-activity.ts
514565
+ const THINKING_ACTIVITY_WORDS = {
514566
+ Thinking: [
514567
+ "Thinkering",
514568
+ "Reasoning",
514569
+ "Pondering",
514570
+ "Analyzing",
514571
+ "Exploring",
514572
+ "Connecting",
514573
+ "Unraveling",
514574
+ "Imagining",
514575
+ "Envisioning",
514576
+ "Strategizing",
514577
+ "Deciphering",
514578
+ "Framing",
514579
+ "Ideating",
514580
+ "Synthesizing",
514581
+ "Reflecting"
514582
+ ],
514583
+ Planning: [
514584
+ "Architecting",
514585
+ "Blueprinting",
514586
+ "Structuring",
514587
+ "Orchestrating",
514588
+ "Sequencing",
514589
+ "Scoping",
514590
+ "Prioritizing",
514591
+ "Coordinating",
514592
+ "Decomposing",
514593
+ "Aligning",
514594
+ "Roadmapping",
514595
+ "Modeling",
514596
+ "Designing",
514597
+ "Drafting",
514598
+ "Preparing"
514599
+ ],
514600
+ Researching: [
514601
+ "Searching",
514602
+ "Browsing",
514603
+ "Discovering",
514604
+ "Investigating",
514605
+ "Examining",
514606
+ "Inspecting",
514607
+ "Tracing",
514608
+ "Comparing",
514609
+ "Verifying",
514610
+ "Cross-checking",
514611
+ "Fact-finding",
514612
+ "Source-hunting",
514613
+ "Deep-diving",
514614
+ "Contextualizing",
514615
+ "Evidence-gathering"
514616
+ ],
514617
+ Building: [
514618
+ "Building",
514619
+ "Crafting",
514620
+ "Coding",
514621
+ "Engineering",
514622
+ "Assembling",
514623
+ "Integrating",
514624
+ "Implementing",
514625
+ "Wiring",
514626
+ "Configuring",
514627
+ "Compiling",
514628
+ "Rendering",
514629
+ "Generating",
514630
+ "Prototyping",
514631
+ "Shaping",
514632
+ "Forging"
514633
+ ],
514634
+ Solving: [
514635
+ "Debugging",
514636
+ "Diagnosing",
514637
+ "Troubleshooting",
514638
+ "Untangling",
514639
+ "Repairing",
514640
+ "Patching",
514641
+ "Resolving",
514642
+ "Reworking",
514643
+ "Refining",
514644
+ "Optimizing",
514645
+ "Simplifying",
514646
+ "Stabilizing",
514647
+ "Recovering",
514648
+ "Calibrating",
514649
+ "Tuning"
514650
+ ],
514651
+ Validating: [
514652
+ "Testing",
514653
+ "Validating",
514654
+ "Reviewing",
514655
+ "Auditing",
514656
+ "Proofreading",
514657
+ "Measuring",
514658
+ "Benchmarking",
514659
+ "Stress-testing",
514660
+ "Safeguarding",
514661
+ "Hardening",
514662
+ "Polishing",
514663
+ "Fine-tuning",
514664
+ "Checking",
514665
+ "Confirming",
514666
+ "Certifying"
514667
+ ],
514668
+ Processing: [
514669
+ "Reading",
514670
+ "Parsing",
514671
+ "Indexing",
514672
+ "Remembering",
514673
+ "Recalling",
514674
+ "Organizing",
514675
+ "Classifying",
514676
+ "Filtering",
514677
+ "Sorting",
514678
+ "Matching",
514679
+ "Merging",
514680
+ "Summarizing",
514681
+ "Compressing",
514682
+ "Transforming",
514683
+ "Learning"
514684
+ ],
514685
+ Collaborating: [
514686
+ "Delegating",
514687
+ "Collaborating",
514688
+ "Consulting",
514689
+ "Briefing",
514690
+ "Dispatching",
514691
+ "Synchronizing",
514692
+ "Negotiating",
514693
+ "Handshaking",
514694
+ "Queuing",
514695
+ "Routing",
514696
+ "Supervising",
514697
+ "Monitoring",
514698
+ "Reconciling",
514699
+ "Reporting",
514700
+ "Converging"
514701
+ ],
514702
+ Creating: [
514703
+ "Writing",
514704
+ "Rewriting",
514705
+ "Translating",
514706
+ "Localizing",
514707
+ "Narrating",
514708
+ "Explaining",
514709
+ "Illustrating",
514710
+ "Visualizing",
514711
+ "Formatting",
514712
+ "Styling",
514713
+ "Presenting",
514714
+ "Documenting",
514715
+ "Captioning",
514716
+ "Storyboarding",
514717
+ "Publishing"
514718
+ ],
514719
+ "BLUN Magic": [
514720
+ "BLUNing",
514721
+ "Sparkering",
514722
+ "Wondermaking",
514723
+ "Dreamweaving",
514724
+ "Futurecrafting",
514725
+ "Brightening",
514726
+ "Flowing",
514727
+ "Accelerating",
514728
+ "Automating",
514729
+ "Empowering",
514730
+ "Launching",
514731
+ "Scaling",
514732
+ "Evolving",
514733
+ "Delivering",
514734
+ "Finishing"
514735
+ ]
514736
+ };
514737
+ const EVIDENCE_KEYS = new Set([
514738
+ "command",
514739
+ "cmd",
514740
+ "description",
514741
+ "file",
514742
+ "file_path",
514743
+ "path",
514744
+ "pattern",
514745
+ "prompt",
514746
+ "query",
514747
+ "task",
514748
+ "title",
514749
+ "url"
514750
+ ]);
514751
+ function activityEvidence(toolCall) {
514752
+ if (toolCall === void 0) return "";
514753
+ const values = [toolCall.name];
514754
+ if (toolCall.args !== void 0) {
514755
+ for (const [key, value] of Object.entries(toolCall.args)) if (EVIDENCE_KEYS.has(key.toLowerCase()) && typeof value === "string") values.push(value.slice(0, 2e3));
514756
+ } else if (toolCall.argumentsText !== void 0) values.push(toolCall.argumentsText.slice(0, 2e3));
514757
+ return values.filter(Boolean).join(" ").toLowerCase();
514758
+ }
514759
+ function matchesAny(text, patterns) {
514760
+ return patterns.some((pattern) => text.includes(pattern));
514761
+ }
514762
+ function inferThinkingActivityGroup(toolCall, options = {}) {
514763
+ if (options.completing === true) return "BLUN Magic";
514764
+ if (options.retrying === true || options.failed === true) return "Solving";
514765
+ const name = toolCall?.name?.toLowerCase() ?? "";
514766
+ const evidence = activityEvidence(toolCall);
514767
+ if (!name) return "Thinking";
514768
+ if (name === "todolist" || matchesAny(evidence, [
514769
+ " plan",
514770
+ "roadmap",
514771
+ "architect",
514772
+ "scope"
514773
+ ])) return "Planning";
514774
+ if (matchesAny(name, [
514775
+ "agent",
514776
+ "swarm",
514777
+ "telegram"
514778
+ ]) || matchesAny(evidence, [
514779
+ "delegate",
514780
+ "handoff",
514781
+ "telegram",
514782
+ "report to"
514783
+ ])) return "Collaborating";
514784
+ if (matchesAny(name, [
514785
+ "mnemo",
514786
+ "memory",
514787
+ "compact"
514788
+ ]) || matchesAny(evidence, [
514789
+ "memory",
514790
+ "mnemo",
514791
+ "compact",
514792
+ "summar",
514793
+ "index"
514794
+ ])) return "Processing";
514795
+ if (matchesAny(name, [
514796
+ "grep",
514797
+ "glob",
514798
+ "search",
514799
+ "webfetch",
514800
+ "web_fetch",
514801
+ "websearch",
514802
+ "web_search",
514803
+ "ls"
514804
+ ]) || matchesAny(evidence, [
514805
+ "search",
514806
+ "find ",
514807
+ "inspect",
514808
+ "trace"
514809
+ ])) return "Researching";
514810
+ if (matchesAny(evidence, [
514811
+ "publish",
514812
+ "release",
514813
+ "deploy",
514814
+ "launch",
514815
+ "deliver",
514816
+ "finish"
514817
+ ])) return "BLUN Magic";
514818
+ if (matchesAny(evidence, [
514819
+ "error",
514820
+ "fail",
514821
+ "debug",
514822
+ "diagnos",
514823
+ "repair",
514824
+ "patch",
514825
+ "fix ",
514826
+ "recover",
514827
+ "troubleshoot"
514828
+ ])) return "Solving";
514829
+ if (matchesAny(evidence, [
514830
+ "test",
514831
+ "check",
514832
+ "verify",
514833
+ "validat",
514834
+ "audit",
514835
+ "benchmark",
514836
+ "measure",
514837
+ "compare",
514838
+ "sha256",
514839
+ "diff "
514840
+ ])) return "Validating";
514841
+ if (name === "read" || name === "readbatch") return "Processing";
514842
+ if (name === "write" || name === "edit") return matchesAny(evidence, [
514843
+ ".md",
514844
+ ".txt",
514845
+ "readme",
514846
+ "changelog",
514847
+ "document",
514848
+ "translat",
514849
+ "localiz"
514850
+ ]) ? "Creating" : "Building";
514851
+ if (matchesAny(name, [
514852
+ "bash",
514853
+ "shell",
514854
+ "programmatictool"
514855
+ ]) || matchesAny(evidence, [
514856
+ "build",
514857
+ "compile",
514858
+ "npm ",
514859
+ "node ",
514860
+ "code"
514861
+ ])) return "Building";
514862
+ return "Processing";
514863
+ }
514864
+ var ThinkingActivityRotator = class {
514865
+ currentWord;
514866
+ changedAtMs = 0;
514867
+ nextIndexByGroup = /* @__PURE__ */ new Map();
514868
+ resolve(group, now = Date.now()) {
514869
+ if (this.currentWord !== void 0 && now - this.changedAtMs < 3e3) return this.currentWord;
514870
+ const words = THINKING_ACTIVITY_WORDS[group];
514871
+ const index = this.nextIndexByGroup.get(group) ?? 0;
514872
+ this.currentWord = words[index % words.length];
514873
+ this.nextIndexByGroup.set(group, (index + 1) % words.length);
514874
+ this.changedAtMs = now;
514875
+ return this.currentWord;
514876
+ }
514877
+ };
514878
+ //#endregion
514492
514879
  //#region src/tui/components/messages/thinking.ts
514493
514880
  /**
514494
514881
  * Renders thinking content in the transcript.
@@ -514541,14 +514928,9 @@ registerUiCatalogFragment({
514541
514928
  }
514542
514929
  });
514543
514930
  function rotatingThinkingLabel(name, startedAtMs, now = Date.now()) {
514544
- const keys = [
514545
- "thinking.label",
514546
- "thinking.pondering",
514547
- "thinking.unraveling"
514548
- ];
514931
+ const words = THINKING_ACTIVITY_WORDS.Thinking;
514549
514932
  const elapsed = startedAtMs === void 0 ? 0 : Math.max(0, now - startedAtMs);
514550
- const key = keys[Math.floor(elapsed / THINKING_WORD_INTERVAL_MS) % keys.length];
514551
- return `${uiText(key, { name })}…`;
514933
+ return `${name} ${words[Math.floor(elapsed / THINKING_WORD_INTERVAL_MS) % words.length]}…`;
514552
514934
  }
514553
514935
  function liveActivityLabels(label, metrics, now = Date.now()) {
514554
514936
  const elapsed = formatLiveElapsed(metrics.startedAtMs === void 0 ? 0 : (now - metrics.startedAtMs) / 1e3);
@@ -514597,6 +514979,7 @@ function formatLiveElapsed(seconds) {
514597
514979
  return `${String(hours)}h ${String(remainingMinutes).padStart(2, "0")}m`;
514598
514980
  }
514599
514981
  var ThinkingComponent = class {
514982
+ activityLabel;
514600
514983
  text;
514601
514984
  showMarker;
514602
514985
  mode;
@@ -514608,12 +514991,14 @@ var ThinkingComponent = class {
514608
514991
  thinkStartMs = null;
514609
514992
  thinkElapsedMs = 0;
514610
514993
  thinkAborted = false;
514994
+ abortedActivityLabel;
514611
514995
  estimatedOutputTokens = 0;
514612
514996
  sessionTotalTokens;
514613
514997
  step;
514614
514998
  textComponent;
514615
514999
  renderCache;
514616
- constructor(text, showMarker = true, mode = "finalized", ui, metrics) {
515000
+ constructor(text, showMarker = true, mode = "finalized", ui, metrics, activityLabel) {
515001
+ this.activityLabel = activityLabel;
514617
515002
  this.text = text;
514618
515003
  this.showMarker = showMarker;
514619
515004
  this.mode = mode;
@@ -514680,7 +515065,7 @@ var ThinkingComponent = class {
514680
515065
  const abortMark = this.thinkAborted ? ` (${uiText("thinking.aborted")})` : "";
514681
515066
  const now = Date.now();
514682
515067
  const startedAtMs = now - this.formatElapsedSeconds() * 1e3;
514683
- const labels = liveActivityLabels(rotatingThinkingLabel(this.persona, startedAtMs, now), {
515068
+ const labels = liveActivityLabels(this.abortedActivityLabel ?? (this.activityLabel === void 0 ? rotatingThinkingLabel(this.persona, startedAtMs, now) : `${this.persona} ${this.activityLabel()}`), {
514684
515069
  startedAtMs,
514685
515070
  estimatedOutputTokens: this.estimatedOutputTokens,
514686
515071
  sessionTotalTokens: this.sessionTotalTokens,
@@ -514707,6 +515092,7 @@ var ThinkingComponent = class {
514707
515092
  }
514708
515093
  /** Called when the connection dies or the request times out. */
514709
515094
  abort() {
515095
+ this.abortedActivityLabel ??= this.activityLabel === void 0 ? rotatingThinkingLabel(this.persona, this.thinkStartMs ?? void 0) : `${this.persona} ${this.activityLabel()}`;
514710
515096
  if (this.thinkStartMs !== null) {
514711
515097
  this.thinkElapsedMs = Date.now() - this.thinkStartMs;
514712
515098
  this.thinkStartMs = null;
@@ -515162,6 +515548,184 @@ function decodeMcpToolName(name) {
515162
515548
  };
515163
515549
  }
515164
515550
  //#endregion
515551
+ //#region src/personal-memory/tool-input.ts
515552
+ init_zod$1();
515553
+ const PERSONAL_MEMORY_TOOL_NAMES = [
515554
+ "memory_status",
515555
+ "memory_settings_update",
515556
+ "memory_remember",
515557
+ "memory_list",
515558
+ "memory_recall"
515559
+ ];
515560
+ const personalMemorySettingsInputSchema = object$1({
515561
+ memoryEnabled: boolean$1().optional(),
515562
+ useSavedMemories: boolean$1().optional(),
515563
+ allowNewMemories: boolean$1().optional()
515564
+ }).strict().refine((value) => Object.keys(value).length > 0);
515565
+ const personalMemoryRememberInputSchema = object$1({ content: string().min(1).max(4e3) }).strict();
515566
+ function isPersonalMemoryToolName$1(qualifiedName) {
515567
+ return PERSONAL_MEMORY_TOOL_NAMES.some((name) => qualifiedName === `mcp__personal-memory__${name}`);
515568
+ }
515569
+ function mutationNameFromQualifiedTool(name) {
515570
+ if (name === "mcp__personal-memory__memory_settings_update") return "memory_settings_update";
515571
+ if (name === "mcp__personal-memory__memory_remember") return "memory_remember";
515572
+ }
515573
+ function parsePersonalMemoryMutation(name, input) {
515574
+ if (name === "memory_settings_update") {
515575
+ const parsed = personalMemorySettingsInputSchema.safeParse(input);
515576
+ if (!parsed.success) return { ok: false };
515577
+ const args = parsed.data;
515578
+ const body = {
515579
+ memory_enabled: args.memoryEnabled,
515580
+ use_saved_memories: args.useSavedMemories ?? (args.memoryEnabled === true ? true : void 0),
515581
+ allow_new_memories: args.allowNewMemories ?? (args.memoryEnabled === true ? true : void 0),
515582
+ use_chat_history: args.memoryEnabled === true ? false : void 0
515583
+ };
515584
+ return {
515585
+ ok: true,
515586
+ kind: "settings",
515587
+ body: Object.fromEntries(Object.entries(body).filter(([, value]) => value !== void 0))
515588
+ };
515589
+ }
515590
+ if (name === "memory_remember") {
515591
+ const parsed = personalMemoryRememberInputSchema.safeParse(input);
515592
+ if (!parsed.success) return { ok: false };
515593
+ return {
515594
+ ok: true,
515595
+ kind: "remember",
515596
+ content: parsed.data.content
515597
+ };
515598
+ }
515599
+ return { ok: false };
515600
+ }
515601
+ //#endregion
515602
+ //#region src/tui/utils/personal-memory-display.copy.ts
515603
+ registerUiCatalogFragment({
515604
+ en: {
515605
+ "personalMemoryDisplay.settingsAction": "Change personal memory settings",
515606
+ "personalMemoryDisplay.rememberAction": "Save a personal memory",
515607
+ "personalMemoryDisplay.memoryEnabled": "Personal memory",
515608
+ "personalMemoryDisplay.useSavedMemories": "Use saved memories",
515609
+ "personalMemoryDisplay.allowNewMemories": "Allow new memories",
515610
+ "personalMemoryDisplay.useChatHistory": "Use chat history",
515611
+ "personalMemoryDisplay.enabled": "On",
515612
+ "personalMemoryDisplay.disabled": "Off",
515613
+ "personalMemoryDisplay.invalidInput": "The requested memory change could not be verified.",
515614
+ "personalMemoryDisplay.settingLine": "{setting}: {value}"
515615
+ },
515616
+ de: {
515617
+ "personalMemoryDisplay.settingsAction": "Einstellungen des persönlichen Gedächtnisses ändern",
515618
+ "personalMemoryDisplay.rememberAction": "Persönliche Erinnerung speichern",
515619
+ "personalMemoryDisplay.memoryEnabled": "Persönliches Gedächtnis",
515620
+ "personalMemoryDisplay.useSavedMemories": "Gespeicherte Erinnerungen verwenden",
515621
+ "personalMemoryDisplay.allowNewMemories": "Neue Erinnerungen zulassen",
515622
+ "personalMemoryDisplay.useChatHistory": "Chatverlauf verwenden",
515623
+ "personalMemoryDisplay.enabled": "An",
515624
+ "personalMemoryDisplay.disabled": "Aus",
515625
+ "personalMemoryDisplay.invalidInput": "Die gewünschte Änderung am Gedächtnis konnte nicht überprüft werden.",
515626
+ "personalMemoryDisplay.settingLine": "{setting}: {value}"
515627
+ },
515628
+ es: {
515629
+ "personalMemoryDisplay.settingsAction": "Cambiar la configuración de la memoria personal",
515630
+ "personalMemoryDisplay.rememberAction": "Guardar un recuerdo personal",
515631
+ "personalMemoryDisplay.memoryEnabled": "Memoria personal",
515632
+ "personalMemoryDisplay.useSavedMemories": "Usar recuerdos guardados",
515633
+ "personalMemoryDisplay.allowNewMemories": "Permitir nuevos recuerdos",
515634
+ "personalMemoryDisplay.useChatHistory": "Usar el historial de chats",
515635
+ "personalMemoryDisplay.enabled": "Sí",
515636
+ "personalMemoryDisplay.disabled": "No",
515637
+ "personalMemoryDisplay.invalidInput": "No se pudo verificar el cambio solicitado en la memoria.",
515638
+ "personalMemoryDisplay.settingLine": "{setting}: {value}"
515639
+ },
515640
+ fr: {
515641
+ "personalMemoryDisplay.settingsAction": "Modifier les réglages de la mémoire personnelle",
515642
+ "personalMemoryDisplay.rememberAction": "Enregistrer un souvenir personnel",
515643
+ "personalMemoryDisplay.memoryEnabled": "Mémoire personnelle",
515644
+ "personalMemoryDisplay.useSavedMemories": "Utiliser les souvenirs enregistrés",
515645
+ "personalMemoryDisplay.allowNewMemories": "Autoriser de nouveaux souvenirs",
515646
+ "personalMemoryDisplay.useChatHistory": "Utiliser l’historique des discussions",
515647
+ "personalMemoryDisplay.enabled": "Oui",
515648
+ "personalMemoryDisplay.disabled": "Non",
515649
+ "personalMemoryDisplay.invalidInput": "La modification demandée de la mémoire n’a pas pu être vérifiée.",
515650
+ "personalMemoryDisplay.settingLine": "{setting}\xA0: {value}"
515651
+ },
515652
+ sv: {
515653
+ "personalMemoryDisplay.settingsAction": "Ändra inställningarna för det personliga minnet",
515654
+ "personalMemoryDisplay.rememberAction": "Spara ett personligt minne",
515655
+ "personalMemoryDisplay.memoryEnabled": "Personligt minne",
515656
+ "personalMemoryDisplay.useSavedMemories": "Använd sparade minnen",
515657
+ "personalMemoryDisplay.allowNewMemories": "Tillåt nya minnen",
515658
+ "personalMemoryDisplay.useChatHistory": "Använd chatthistorik",
515659
+ "personalMemoryDisplay.enabled": "På",
515660
+ "personalMemoryDisplay.disabled": "Av",
515661
+ "personalMemoryDisplay.invalidInput": "Den begärda ändringen av minnet kunde inte verifieras.",
515662
+ "personalMemoryDisplay.settingLine": "{setting}: {value}"
515663
+ },
515664
+ cs: {
515665
+ "personalMemoryDisplay.settingsAction": "Změnit nastavení osobní paměti",
515666
+ "personalMemoryDisplay.rememberAction": "Uložit osobní vzpomínku",
515667
+ "personalMemoryDisplay.memoryEnabled": "Osobní paměť",
515668
+ "personalMemoryDisplay.useSavedMemories": "Používat uložené vzpomínky",
515669
+ "personalMemoryDisplay.allowNewMemories": "Povolit nové vzpomínky",
515670
+ "personalMemoryDisplay.useChatHistory": "Používat historii chatů",
515671
+ "personalMemoryDisplay.enabled": "Ano",
515672
+ "personalMemoryDisplay.disabled": "Ne",
515673
+ "personalMemoryDisplay.invalidInput": "Požadovanou změnu paměti se nepodařilo ověřit.",
515674
+ "personalMemoryDisplay.settingLine": "{setting}: {value}"
515675
+ }
515676
+ });
515677
+ //#endregion
515678
+ //#region src/tui/utils/personal-memory-display.ts
515679
+ const settingLabels = {
515680
+ memory_enabled: "personalMemoryDisplay.memoryEnabled",
515681
+ use_saved_memories: "personalMemoryDisplay.useSavedMemories",
515682
+ allow_new_memories: "personalMemoryDisplay.allowNewMemories",
515683
+ use_chat_history: "personalMemoryDisplay.useChatHistory"
515684
+ };
515685
+ function personalMemoryApprovalDisplay(toolName, display) {
515686
+ const name = mutationNameFromQualifiedTool(toolName);
515687
+ if (name === void 0) return void 0;
515688
+ const action = personalMemoryActionLabel(toolName);
515689
+ const parsed = parsePersonalMemoryMutation(name, display.kind === "generic" ? display.detail : void 0);
515690
+ const invalid = {
515691
+ action,
515692
+ description: uiText("personalMemoryDisplay.invalidInput"),
515693
+ blocks: [],
515694
+ valid: false
515695
+ };
515696
+ if (!parsed.ok) return invalid;
515697
+ const text = parsed.kind === "remember" ? memoryContentPreview(parsed.content) : Object.keys(settingLabels).filter((key) => parsed.body[key] !== void 0).map((key) => uiText("personalMemoryDisplay.settingLine", {
515698
+ setting: uiText(settingLabels[key]),
515699
+ value: uiText(parsed.body[key] ? "personalMemoryDisplay.enabled" : "personalMemoryDisplay.disabled")
515700
+ })).join("\n");
515701
+ if (text.length === 0) return invalid;
515702
+ return {
515703
+ action,
515704
+ description: "",
515705
+ blocks: [{
515706
+ type: "brief",
515707
+ text
515708
+ }],
515709
+ valid: true
515710
+ };
515711
+ }
515712
+ function memoryContentPreview(content) {
515713
+ const controls = /[\u0000-\u0009\u000B-\u001F\u007F-\u009F\u2028-\u202E\u2066-\u2069]/gu;
515714
+ if (!controls.test(content)) return content;
515715
+ return JSON.stringify(content).replaceAll(controls, (character) => `\\u${character.codePointAt(0).toString(16).padStart(4, "0")}`);
515716
+ }
515717
+ function personalMemoryArgumentPreview(toolName, value) {
515718
+ return isPersonalMemoryToolName$1(toolName) ? memoryContentPreview(value) : value;
515719
+ }
515720
+ function personalMemoryActionLabel(toolName) {
515721
+ const name = mutationNameFromQualifiedTool(toolName);
515722
+ if (name === void 0) return void 0;
515723
+ return uiText(name === "memory_settings_update" ? "personalMemoryDisplay.settingsAction" : "personalMemoryDisplay.rememberAction");
515724
+ }
515725
+ function personalMemoryActivityLabel(toolName) {
515726
+ return isPersonalMemoryToolName$1(toolName) ? uiText("startupPersonalMemory.title") : void 0;
515727
+ }
515728
+ //#endregion
515165
515729
  //#region src/tui/utils/shell-output.copy.ts
515166
515730
  registerUiCatalogFragment({
515167
515731
  en: { "shellOutput.noOutput": "(no output)" },
@@ -516785,7 +517349,8 @@ function extractKeyArgument(toolName, args, workspaceDir) {
516785
517349
  for (const key of candidates) {
516786
517350
  const val = args[key];
516787
517351
  if (typeof val === "string" && val.length > 0) {
516788
- const firstLine = val.split("\n")[0] ?? val;
517352
+ const preview = personalMemoryArgumentPreview(toolName, val);
517353
+ const firstLine = preview.split("\n")[0] ?? preview;
516789
517354
  return formatKeyArgument(toolName, key, toolName === "Bash" && val.includes("\n") ? `${firstLine}…` : firstLine, workspaceDir);
516790
517355
  }
516791
517356
  }
@@ -517594,6 +518159,8 @@ var ToolCallComponent = class ToolCallComponent extends Container {
517594
518159
  if (phrase !== void 0) return `${bullet}${currentTheme.boldFg("primary", phrase)}${argStr}${chipStr}`;
517595
518160
  }
517596
518161
  const verbStyled = isTruncated ? currentTheme.fg("error", verb) : verb;
518162
+ const memoryLabel = personalMemoryActivityLabel(toolCall.name);
518163
+ if (memoryLabel !== void 0) return `${bullet}${isTruncated ? `${verbStyled} ` : ""}${currentTheme.boldFg("primary", memoryLabel)}${argStr}${chipStr}`;
517597
518164
  const toolLabel = decoded !== null ? `${currentTheme.boldFg("primary", decoded.toolName)}${currentTheme.dim(` · MCP/${decoded.serverName}`)}` : currentTheme.boldFg("primary", toolCall.name);
517598
518165
  return `${bullet}${verbStyled} ${toolLabel}${argStr}${chipStr}`;
517599
518166
  }
@@ -517680,15 +518247,19 @@ var ToolCallComponent = class ToolCallComponent extends Container {
517680
518247
  for (const sub of this.finishedSubCalls) {
517681
518248
  const mark = sub.isError ? currentTheme.fg("error", "✗") : currentTheme.fg("success", "•");
517682
518249
  const keyArg = extractKeyArgument(sub.name, sub.args, this.workspaceDir);
517683
- const nameCol = currentTheme.fg("primary", sub.name);
518250
+ const memoryLabel = personalMemoryActivityLabel(sub.name);
518251
+ const nameCol = currentTheme.fg("primary", memoryLabel ?? sub.name);
518252
+ const verb = memoryLabel === void 0 ? `${uiText("toolCall.activity.used")} ` : "";
517684
518253
  const argCol = keyArg ? currentTheme.dim(` (${keyArg})`) : "";
517685
- this.addChild(new Text(` ${mark} ${uiText("toolCall.activity.used")} ${nameCol}${argCol}`, 0, 0));
518254
+ this.addChild(new Text(` ${mark} ${verb}${nameCol}${argCol}`, 0, 0));
517686
518255
  }
517687
518256
  for (const [id, call] of this.ongoingSubCalls) {
517688
518257
  const keyArg = extractKeyArgument(call.name, call.args, this.workspaceDir);
517689
- const nameCol = currentTheme.fg("primary", call.name);
518258
+ const memoryLabel = personalMemoryActivityLabel(call.name);
518259
+ const nameCol = currentTheme.fg("primary", memoryLabel ?? call.name);
518260
+ const verb = memoryLabel === void 0 ? `${uiText("toolCall.activity.using")} ` : "";
517690
518261
  const argCol = keyArg ? currentTheme.dim(` (${keyArg})`) : "";
517691
- this.addChild(new Text(` ${currentTheme.dim("…")} ${uiText("toolCall.activity.using")} ${nameCol}${argCol}`, 0, 0));
518262
+ this.addChild(new Text(` ${currentTheme.dim("…")} ${verb}${nameCol}${argCol}`, 0, 0));
517692
518263
  }
517693
518264
  if (this.subagentText.length > 0) {
517694
518265
  const tailLines = this.subagentText.split("\n").slice(-3);
@@ -517858,10 +518429,11 @@ var ToolCallComponent = class ToolCallComponent extends Container {
517858
518429
  if (current === void 0) return currentTheme.dim(` · ${countLabel}`);
517859
518430
  const verb = current.phase === "ongoing" ? uiText("toolCall.activity.using") : uiText("toolCall.activity.used");
517860
518431
  const keyArg = extractKeyArgument(current.name, current.args, this.workspaceDir);
517861
- const nameCol = currentTheme.fg("primary", current.name);
518432
+ const memoryLabel = personalMemoryActivityLabel(current.name);
518433
+ const nameCol = currentTheme.fg("primary", memoryLabel ?? current.name);
517862
518434
  const argCol = keyArg ? currentTheme.dim(` (${keyArg})`) : "";
517863
518435
  const mark = current.phase === "failed" ? currentTheme.fg("error", " ✗") : current.phase === "done" ? currentTheme.fg("success", " ✓") : "";
517864
- return `${currentTheme.dim(` · ${countLabel} · `)}${verb} ${nameCol}${argCol}${mark}`;
518436
+ return `${currentTheme.dim(` · ${countLabel} · `)}${memoryLabel === void 0 ? `${verb} ` : ""}${nameCol}${argCol}${mark}`;
517865
518437
  }
517866
518438
  buildSingleSubagentActiveWindow() {
517867
518439
  const gutter = currentTheme.dim("│");
@@ -520963,7 +521535,7 @@ function renderDisplayBlock(block, s, contentWidth) {
520963
521535
  if (block.description !== void 0 && block.description.length > 0) lines.push(s.dim(truncateOneLine(block.description, 200)));
520964
521536
  return lines;
520965
521537
  }
520966
- case "brief": return block.text ? block.text.split("\n").map((line) => line.length > 0 ? s.strong(line) : "") : [];
521538
+ case "brief": return block.text ? block.text.split("\n").flatMap((line) => line.length > 0 ? wrapTextWithAnsi(s.strong(line), contentWidth) : [""]) : [];
520967
521539
  case "background_task": return [s.strong(uiText("approval.backgroundTask", {
520968
521540
  status: block.status,
520969
521541
  kind: block.kind,
@@ -520988,6 +521560,8 @@ function isDuplicateBriefBlock(block, description) {
520988
521560
  return normalizeApprovalText(blockLines.slice(1).join("\n")) === normalizedDescription;
520989
521561
  }
520990
521562
  function headerFor(toolName) {
521563
+ const memoryAction = personalMemoryActionLabel(toolName);
521564
+ if (memoryAction !== void 0) return memoryAction;
520991
521565
  switch (toolName) {
520992
521566
  case "Bash": return uiText("approval.header.runCommand");
520993
521567
  case "Write": return uiText("approval.header.writeFile");
@@ -523524,7 +524098,8 @@ function planRejectChoices() {
523524
524098
  }];
523525
524099
  }
523526
524100
  function adaptApprovalRequest(event) {
523527
- const resolved = resolveDisplay(event.toolName, event.display, event.action);
524101
+ const memory = personalMemoryApprovalDisplay(event.toolName, event.display);
524102
+ const resolved = memory ?? resolveDisplay(event.toolName, event.display, event.action);
523528
524103
  return {
523529
524104
  id: event.toolCallId,
523530
524105
  tool_call_id: event.toolCallId,
@@ -523532,7 +524107,7 @@ function adaptApprovalRequest(event) {
523532
524107
  action: resolved.action ?? event.action,
523533
524108
  description: resolved.description,
523534
524109
  display: resolved.blocks,
523535
- choices: adaptChoices(event.toolName, event.display)
524110
+ choices: memory === void 0 ? adaptChoices(event.toolName, event.display) : defaultApprovalChoices().filter((choice) => choice.response === "rejected" || memory.valid && choice.response === "approved")
523536
524111
  };
523537
524112
  }
523538
524113
  function resolveDisplay(toolName, display, action) {
@@ -527602,13 +528177,6 @@ async function preparePersonalMemorySession(options) {
527602
528177
  //#endregion
527603
528178
  //#region src/personal-memory/mcp-server.ts
527604
528179
  init_zod$1();
527605
- const PERSONAL_MEMORY_TOOL_NAMES = [
527606
- "memory_status",
527607
- "memory_settings_update",
527608
- "memory_remember",
527609
- "memory_list",
527610
- "memory_recall"
527611
- ];
527612
528180
  const MANAGEMENT_TOOL_NAMES = [
527613
528181
  "memory_status",
527614
528182
  "memory_settings_update",
@@ -527625,12 +528193,8 @@ function personalMemoryToolNames(mode, capabilities = defaultPersonalMemoryCapab
527625
528193
  const noInputSchema = object$1({}).strict();
527626
528194
  const schemas = {
527627
528195
  memory_status: noInputSchema,
527628
- memory_settings_update: object$1({
527629
- memoryEnabled: boolean$1().optional(),
527630
- useSavedMemories: boolean$1().optional(),
527631
- allowNewMemories: boolean$1().optional()
527632
- }).strict().refine((value) => Object.keys(value).length > 0),
527633
- memory_remember: object$1({ content: string().min(1).max(4e3) }).strict(),
528196
+ memory_settings_update: personalMemorySettingsInputSchema,
528197
+ memory_remember: personalMemoryRememberInputSchema,
527634
528198
  memory_list: noInputSchema,
527635
528199
  memory_recall: object$1({
527636
528200
  query: string().min(1).max(1e3),
@@ -527652,20 +528216,18 @@ function personalMemoryToolDefinition(name) {
527652
528216
  }
527653
528217
  async function invokePersonalMemoryTool(client, name, input, context) {
527654
528218
  if (!isPersonalMemoryToolName(name)) throw new Error("Unsupported personal-memory tool.");
528219
+ if (name === "memory_settings_update" || name === "memory_remember") {
528220
+ const parsed = parsePersonalMemoryMutation(name, input);
528221
+ if (!parsed.ok) throw new Error("Invalid personal-memory tool arguments.");
528222
+ if (parsed.kind === "settings") return client.request("PUT", PERSONAL_MEMORY_SETTINGS_PATH, parsed.body);
528223
+ if (context?.explicitRememberAttested !== true) throw new PersonalMemoryBrokerError("EXPLICIT_CONSENT_REQUIRED");
528224
+ return client.request(PERSONAL_MEMORY_MEMORY_CREATE_METHOD, PERSONAL_MEMORY_MEMORIES_PATH, explicitPersonalMemoryBody(parsed.content));
528225
+ }
527655
528226
  const parsed = schemas[name].safeParse(input);
527656
528227
  if (!parsed.success) throw new Error("Invalid personal-memory tool arguments.");
527657
528228
  const args = parsed.data;
527658
528229
  switch (name) {
527659
528230
  case "memory_status": return client.request("GET", PERSONAL_MEMORY_SETTINGS_PATH);
527660
- case "memory_settings_update": return await client.request("PUT", PERSONAL_MEMORY_SETTINGS_PATH, compactObject({
527661
- memory_enabled: args["memoryEnabled"],
527662
- use_saved_memories: args["useSavedMemories"] ?? (args["memoryEnabled"] === true ? true : void 0),
527663
- allow_new_memories: args["allowNewMemories"] ?? (args["memoryEnabled"] === true ? true : void 0),
527664
- use_chat_history: args["memoryEnabled"] === true ? false : void 0
527665
- }));
527666
- case "memory_remember":
527667
- if (context?.explicitRememberAttested !== true) throw new PersonalMemoryBrokerError("EXPLICIT_CONSENT_REQUIRED");
527668
- return client.request(PERSONAL_MEMORY_MEMORY_CREATE_METHOD, PERSONAL_MEMORY_MEMORIES_PATH, explicitPersonalMemoryBody(args["content"]));
527669
528231
  case "memory_list": return client.request("GET", PERSONAL_MEMORY_MEMORIES_PATH);
527670
528232
  case "memory_recall": return normalizePhaseOneRecall(await client.request(PERSONAL_MEMORY_RECALL_METHOD, PERSONAL_MEMORY_RECALL_PATH, { query: args["query"] }), args["limit"]);
527671
528233
  }
@@ -527673,9 +528235,6 @@ async function invokePersonalMemoryTool(client, name, input, context) {
527673
528235
  function isPersonalMemoryToolName(name) {
527674
528236
  return PERSONAL_MEMORY_TOOL_NAMES.includes(name);
527675
528237
  }
527676
- function compactObject(input) {
527677
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
527678
- }
527679
528238
  function normalizePhaseOneRecall(payload, limit) {
527680
528239
  if (!isRecord$2(payload) || !Array.isArray(payload["ergebnis"])) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
527681
528240
  const results = payload["ergebnis"];
@@ -530675,7 +531234,9 @@ var SessionEventHandler = class {
530675
531234
  this.handleStepCompleted(event);
530676
531235
  this.host.releaseChannelQueueAtSafePoint();
530677
531236
  break;
530678
- case "turn.step.retrying": break;
531237
+ case "turn.step.retrying":
531238
+ this.host.streamingUI.setActivityRetrying();
531239
+ break;
530679
531240
  case "tool.progress":
530680
531241
  this.handleToolProgress(event);
530681
531242
  break;
@@ -533458,6 +534019,9 @@ var StreamingUIController = class {
533458
534019
  _currentTurnId = void 0;
533459
534020
  _currentStep = 0;
533460
534021
  _lastToolName = "none";
534022
+ activityWords = new ThinkingActivityRotator();
534023
+ activityRetrying = false;
534024
+ activityFailed = false;
533461
534025
  _liveTurnStartedAtMs = void 0;
533462
534026
  _sessionTotalTokens;
533463
534027
  _liveOutputTokens = new LiveOutputTokenCounter();
@@ -533487,18 +534051,37 @@ var StreamingUIController = class {
533487
534051
  }
533488
534052
  setStep(step) {
533489
534053
  this._currentStep = step;
534054
+ this.activityRetrying = false;
534055
+ }
534056
+ setActivityRetrying() {
534057
+ this.activityRetrying = true;
534058
+ }
534059
+ getActivityLabel(composing = false) {
534060
+ let activeCall;
534061
+ for (const call of this._activeToolCalls.values()) if (call.result === void 0 && !call.truncated) activeCall = call;
534062
+ const group = composing && activeCall === void 0 && !this.activityRetrying ? "Creating" : inferThinkingActivityGroup(activeCall, {
534063
+ retrying: this.activityRetrying,
534064
+ failed: this.activityFailed
534065
+ });
534066
+ return `${this.activityWords.resolve(group)}…`;
533490
534067
  }
533491
534068
  getLastToolName() {
533492
534069
  return this._lastToolName;
533493
534070
  }
533494
534071
  resetSessionDiagnostics() {
533495
534072
  this._lastToolName = "none";
534073
+ this.activityWords = new ThinkingActivityRotator();
534074
+ this.activityRetrying = false;
534075
+ this.activityFailed = false;
533496
534076
  }
533497
534077
  hasActiveTurn() {
533498
534078
  return this._currentTurnId !== void 0;
533499
534079
  }
533500
534080
  beginLiveTurn() {
533501
534081
  this._liveTurnStartedAtMs = Date.now();
534082
+ this.activityWords = new ThinkingActivityRotator();
534083
+ this.activityRetrying = false;
534084
+ this.activityFailed = false;
533502
534085
  this._liveOutputTokens.reset();
533503
534086
  this._countedToolCallIds.clear();
533504
534087
  }
@@ -533714,6 +534297,8 @@ var StreamingUIController = class {
533714
534297
  * component, and returns whether the call was new (no previous entry). */
533715
534298
  registerToolCall(toolCall) {
533716
534299
  this._lastToolName = toolCall.name;
534300
+ this.activityRetrying = false;
534301
+ this.activityFailed = false;
533717
534302
  if (!this._countedToolCallIds.has(toolCall.id)) {
533718
534303
  this._countedToolCallIds.add(toolCall.id);
533719
534304
  this.recordLiveOutput(`${toolCall.name}${JSON.stringify(toolCall.args)}`);
@@ -533763,7 +534348,10 @@ var StreamingUIController = class {
533763
534348
  * Returns the matched ToolCallBlockData, or undefined if no call was tracked. */
533764
534349
  completeToolResult(toolCallId, result) {
533765
534350
  const matchedCall = this._activeToolCalls.get(toolCallId);
533766
- if (matchedCall !== void 0) this.onToolCallEnd(toolCallId, result);
534351
+ if (matchedCall !== void 0) {
534352
+ this.activityFailed = result.is_error === true;
534353
+ this.onToolCallEnd(toolCallId, result);
534354
+ }
533767
534355
  this._activeToolCalls.delete(toolCallId);
533768
534356
  this._streamingToolCallArguments.delete(toolCallId);
533769
534357
  return matchedCall;
@@ -533976,7 +534564,7 @@ var StreamingUIController = class {
533976
534564
  if (this._activeThinkingComponent === void 0) {
533977
534565
  this._pendingAgentGroup = null;
533978
534566
  this._pendingReadGroup = null;
533979
- this._activeThinkingComponent = new ThinkingComponent(fullText, true, "live", state.ui, { ...this.getLiveActivityMetrics() });
534567
+ this._activeThinkingComponent = new ThinkingComponent(fullText, true, "live", state.ui, { ...this.getLiveActivityMetrics() }, () => this.getActivityLabel());
533980
534568
  if (state.toolOutputExpanded) this._activeThinkingComponent.setExpanded(true);
533981
534569
  state.transcriptContainer.addChild(this._activeThinkingComponent);
533982
534570
  } else {
@@ -535815,6 +536403,7 @@ var ApprovalController = class extends ReverseRpcController {
535815
536403
  if (response.decision !== "approved") return void 0;
535816
536404
  if (response.scope !== "session") return void 0;
535817
536405
  if (!resolvedPayload.choices.some((choice) => choice.response === "approved_for_session")) return;
536406
+ if (!queuedPayload.choices.some((choice) => choice.response === "approved_for_session")) return;
535818
536407
  if (resolvedPayload.action !== queuedPayload.action) return void 0;
535819
536408
  return {
535820
536409
  decision: "approved",
@@ -540353,7 +540942,7 @@ var BlunTUI = class {
540353
540942
  const metrics = this.streamingUI.getLiveActivityMetrics();
540354
540943
  const startedAtMs = metrics.startedAtMs ?? this.activitySpinnerFallbackStartMs;
540355
540944
  const mode = this.resolveActivityPaneMode();
540356
- return liveActivityLabels(mode === "waiting" || mode === "thinking" ? rotatingThinkingLabel(personaName() ?? "King", startedAtMs) : this.activitySpinnerBaseLabel, {
540945
+ return liveActivityLabels(mode === "waiting" || mode === "thinking" || mode === "tool" || mode === "composing" ? `${personaName() ?? "King"} ${this.streamingUI.getActivityLabel(mode === "composing")}` : this.activitySpinnerBaseLabel, {
540357
540946
  ...metrics,
540358
540947
  startedAtMs
540359
540948
  });