blun-king-cli 9.1.460 → 9.1.462

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.
@@ -7,6 +7,7 @@ const STATUS_FILE = 'telegram-console-status.json';
7
7
  const MAX_STATUS_BYTES = 16_384;
8
8
  const MAX_TASK_CHARS = 240;
9
9
  const MAX_TOOL_NAME_CHARS = 80;
10
+ const MAX_VERSION_CHARS = 80;
10
11
 
11
12
  function validInstant(value) {
12
13
  if (typeof value !== 'string' || value.length === 0) return undefined;
@@ -25,6 +26,16 @@ function boundedToolName(value) {
25
26
  return name.length > 0 ? name.slice(0, MAX_TOOL_NAME_CHARS) : undefined;
26
27
  }
27
28
 
29
+ function boundedVersion(value) {
30
+ if (typeof value !== 'string') return undefined;
31
+ const version = value.trim();
32
+ return version.length > 0
33
+ && version.length <= MAX_VERSION_CHARS
34
+ && /^[0-9A-Za-z][0-9A-Za-z.+-]*$/u.test(version)
35
+ ? version
36
+ : undefined;
37
+ }
38
+
28
39
  function instantFromMilliseconds(value) {
29
40
  if (!Number.isFinite(value) || value < 0) return undefined;
30
41
  try {
@@ -54,6 +65,7 @@ function buildTurnDiagnostics(turnActive, activity) {
54
65
 
55
66
  function buildTelegramConsoleStatus(input = {}) {
56
67
  const capturedAt = validInstant(input.capturedAt);
68
+ const loadedVersion = boundedVersion(input.loadedVersion);
57
69
  const processStartedAt = validInstant(input.processStartedAt);
58
70
  const pid = Number.isSafeInteger(input.pid) && input.pid > 1 ? input.pid : undefined;
59
71
  const step = Number.isSafeInteger(input.step) && input.step >= 0 ? input.step : 0;
@@ -66,6 +78,7 @@ function buildTelegramConsoleStatus(input = {}) {
66
78
  : undefined;
67
79
  return {
68
80
  version: 1,
81
+ ...(loadedVersion === undefined ? {} : { loadedVersion }),
69
82
  pid,
70
83
  capturedAt,
71
84
  processStartedAt,
@@ -88,6 +101,8 @@ function parseTelegramConsoleStatus(value, options = {}) {
88
101
  || typeof parsed.turnActive !== 'boolean'
89
102
  || !Number.isSafeInteger(parsed.step) || parsed.step < 0) return undefined;
90
103
  const activeTask = boundedTask(parsed.activeTask);
104
+ const hasLoadedVersion = Object.hasOwn(parsed, 'loadedVersion');
105
+ const loadedVersion = boundedVersion(parsed.loadedVersion);
91
106
  const hasTurnStartedAt = Object.hasOwn(parsed, 'turnStartedAt');
92
107
  const hasLastProgressAt = Object.hasOwn(parsed, 'lastProgressAt');
93
108
  const hasLastToolName = Object.hasOwn(parsed, 'lastToolName');
@@ -96,7 +111,8 @@ function parseTelegramConsoleStatus(value, options = {}) {
96
111
  const lastProgressAt = validInstant(parsed.lastProgressAt);
97
112
  const lastToolName = boundedToolName(parsed.lastToolName);
98
113
  const failedRepetitions = parsed.failedRepetitions;
99
- if ((hasTurnStartedAt && turnStartedAt === undefined)
114
+ if ((hasLoadedVersion && loadedVersion === undefined)
115
+ || (hasTurnStartedAt && turnStartedAt === undefined)
100
116
  || (hasLastProgressAt && lastProgressAt === undefined)
101
117
  || (hasLastToolName && lastToolName === undefined)
102
118
  || (hasFailedRepetitions && (!Number.isSafeInteger(failedRepetitions)
@@ -109,6 +125,7 @@ function parseTelegramConsoleStatus(value, options = {}) {
109
125
  } : {};
110
126
  return {
111
127
  version: 1,
128
+ ...(loadedVersion === undefined ? {} : { loadedVersion }),
112
129
  pid: parsed.pid,
113
130
  capturedAt: parsed.capturedAt,
114
131
  processStartedAt: parsed.processStartedAt,
@@ -13,6 +13,16 @@ function resolveTelegramRemoteVersion(input = {}) {
13
13
  || 'unbekannt';
14
14
  }
15
15
 
16
+ function resolveVersionDisplay(input = {}) {
17
+ const loaded = trustedVersion(input.consoleStatus?.loadedVersion)
18
+ || trustedVersion(input.version)
19
+ || 'unbekannt';
20
+ const installed = trustedVersion(input.installedVersion);
21
+ return installed !== undefined && installed !== loaded
22
+ ? `${loaded} -> ${installed}`
23
+ : loaded;
24
+ }
25
+
16
26
  function formatDuration(seconds) {
17
27
  const minutes = Math.max(0, Math.floor(Number(seconds) / 60));
18
28
  if (minutes < 60) return `${minutes} min`;
@@ -89,7 +99,7 @@ function buildTelegramRemoteStatus(input) {
89
99
  return [
90
100
  `BLUN-Fernstatus für ${username}`,
91
101
  `Rechner: ${input.machineName || 'unbekannt'}`,
92
- `Version: ${input.version || 'unbekannt'}`,
102
+ `Version: ${resolveVersionDisplay(input)}`,
93
103
  `Brücke: aktiv (PID ${input.bridgePid}, ${formatDuration(input.bridgeUptimeSeconds)})`,
94
104
  `Konsole: ${tui}`,
95
105
  `Zustellung: ${delivery}`,
package/blun.mjs CHANGED
@@ -341020,6 +341020,14 @@ function getVersion() {
341020
341020
  if (BLUN_BUILD_INFO.version !== void 0) return BLUN_BUILD_INFO.version;
341021
341021
  return JSON.parse(readFileSync(getHostPackageJsonPath(), "utf-8")).version;
341022
341022
  }
341023
+ function getInstalledPackageVersion() {
341024
+ try {
341025
+ const version = JSON.parse(readFileSync(getHostPackageJsonPath(), "utf-8")).version;
341026
+ return typeof version === "string" && version.trim().length > 0 ? version.trim() : void 0;
341027
+ } catch {
341028
+ return void 0;
341029
+ }
341030
+ }
341023
341031
  function createBlunHostIdentity(version = getVersion()) {
341024
341032
  return {
341025
341033
  userAgentProduct: CLI_USER_AGENT_PRODUCT,
@@ -342538,7 +342546,7 @@ function parseTuiConfig(tomlText) {
342538
342546
  }
342539
342547
  async function saveTuiConfig(config, filePath = getTuiConfigPath()) {
342540
342548
  assertConfiguredAppearanceContrast(config);
342541
- await withTuiConfigLock(filePath, () => writeTuiConfigAtomic(config, filePath));
342549
+ return withTuiConfigLock(filePath, () => writeTuiConfigIfChanged(config, filePath));
342542
342550
  }
342543
342551
  async function updateTuiAppearance(appearance, filePath = getTuiConfigPath()) {
342544
342552
  const parsedAppearance = normalizeAppearanceConfig(appearance === void 0 ? void 0 : AppearanceConfigSchema.parse(appearance));
@@ -342559,7 +342567,7 @@ async function updateTuiAppearance(appearance, filePath = getTuiConfigPath()) {
342559
342567
  ...parsedAppearance === void 0 ? { appearance: void 0 } : { appearance: parsedAppearance }
342560
342568
  });
342561
342569
  assertConfiguredAppearanceContrast(next);
342562
- await writeTuiConfigAtomic(next, filePath);
342570
+ await writeTuiConfigIfChanged(next, filePath);
342563
342571
  return next;
342564
342572
  });
342565
342573
  }
@@ -342630,12 +342638,12 @@ async function withTuiConfigLock(filePath, action) {
342630
342638
  await release();
342631
342639
  }
342632
342640
  }
342633
- async function writeTuiConfigAtomic(config, filePath) {
342641
+ async function writeTuiConfigAtomic(config, filePath, rendered = renderTuiConfig(config)) {
342634
342642
  const temporary = join(dirname(filePath), `.${basename(filePath)}.${process.pid}.${randomUUID()}.tmp`);
342635
342643
  const handle = await open(temporary, "wx", 384);
342636
342644
  try {
342637
342645
  try {
342638
- await handle.writeFile(renderTuiConfig(config), "utf-8");
342646
+ await handle.writeFile(rendered, "utf-8");
342639
342647
  await handle.sync();
342640
342648
  } finally {
342641
342649
  await handle.close();
@@ -342646,6 +342654,12 @@ async function writeTuiConfigAtomic(config, filePath) {
342646
342654
  throw error;
342647
342655
  }
342648
342656
  }
342657
+ async function writeTuiConfigIfChanged(config, filePath) {
342658
+ const rendered = renderTuiConfig(config);
342659
+ if (await configFileMatches(filePath, rendered)) return false;
342660
+ await writeTuiConfigAtomic(config, filePath, rendered);
342661
+ return true;
342662
+ }
342649
342663
  function isNotFound$3(error) {
342650
342664
  return typeof error === "object" && error !== null && error.code === "ENOENT";
342651
342665
  }
@@ -417986,6 +418000,10 @@ function buildStatusReportLines(options) {
417986
418000
  value: sessionId
417987
418001
  }
417988
418002
  ];
418003
+ if (options.installedVersion !== void 0 && options.installedVersion !== options.version) rows.push({
418004
+ label: uiText("status.label.warning"),
418005
+ value: uiText("plugins.market.status.installedVersion", { version: options.installedVersion })
418006
+ });
417989
418007
  const title = options.sessionTitle?.trim();
417990
418008
  if (title !== void 0 && title.length > 0) rows.push({
417991
418009
  label: uiText("status.label.title"),
@@ -418882,6 +418900,7 @@ async function showStatusReport(host) {
418882
418900
  const appState = host.state.appState;
418883
418901
  const reportArgs = {
418884
418902
  version: appState.version,
418903
+ installedVersion: getInstalledPackageVersion(),
418885
418904
  model: appState.model,
418886
418905
  workDir: appState.workDir,
418887
418906
  sessionId: appState.sessionId,
@@ -511609,6 +511628,7 @@ var StreamingUIController = class {
511609
511628
  writeTelegramConsoleStatus({
511610
511629
  directory: telegramStateDir(),
511611
511630
  capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
511631
+ loadedVersion: this.host.state.appState.version,
511612
511632
  pid: process.pid,
511613
511633
  processStartedAt: this._remoteProcessStartedAt,
511614
511634
  step: this._currentStep,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "9.1.460",
3
+ "version": "9.1.462",
4
4
  "description": "BLUN CLI - your own AI agent with a Telegram channel. Get it done. With BLUN.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -4809,6 +4809,7 @@ bot.command("status", async (ctx) => {
4809
4809
  queueCheckpointAt,
4810
4810
  queueUnreadBytes: queueSnapshot.unreadBytes,
4811
4811
  senderId,
4812
+ installedVersion: version,
4812
4813
  tuiFresh: isTuiLeaseFresh(),
4813
4814
  tuiHeartbeatAt,
4814
4815
  tuiPid: Number.isInteger(tuiPid) ? tuiPid : void 0,