blun-king-cli 9.1.24 → 9.1.26

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.
Files changed (2) hide show
  1. package/blun.mjs +1527 -292
  2. package/package.json +1 -1
package/blun.mjs CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:420510ac14726514cc4725577c2fe8d0fd038c1471bdbda1c15ace32f3ceaba0
2
+ // BLUN_BUILD_INPUT_SHA256:7d2032417fd49eb3d28a7006057755559c5bb8da252a52c972b2ccc12a33dd14
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);
6
6
  const __dirname = __cjsShimDirname(__filename);
7
7
  import { createRequire } from "node:module";
8
8
  import crypto$1, { createHash, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
9
- import * as fs$16 from "node:fs";
9
+ import * as fs$17 from "node:fs";
10
10
  import Kt, { accessSync, appendFileSync, chmodSync, closeSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, promises, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
11
11
  import * as path$17 from "node:path";
12
12
  import path, { basename, dirname, extname, isAbsolute, join, normalize, posix, relative, resolve, sep, win32 } from "node:path";
13
13
  import { Blob as Blob$1, Buffer as Buffer$1, File as File$1 } from "node:buffer";
14
14
  import * as nodeOs from "node:os";
15
15
  import os, { arch, homedir, hostname, networkInterfaces, platform, release, tmpdir, type, userInfo } from "node:os";
16
- import ro, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
16
+ import fs, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
17
17
  import { execFile, execFileSync, execSync, spawn, spawnSync } from "node:child_process";
18
18
  import * as sysPath from "path";
19
19
  import path$1, { basename as basename$1, dirname as dirname$1, join as join$1, parse } from "path";
@@ -1167,7 +1167,7 @@ function normalizeBlunToolSchema(schema) {
1167
1167
  }
1168
1168
  function ensureBlunPropertyTypes(schema) {
1169
1169
  const normalized = cloneJsonValue(schema);
1170
- if (!isRecord$23(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1170
+ if (!isRecord$24(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1171
1171
  recurseSchema(normalized);
1172
1172
  return normalized;
1173
1173
  }
@@ -1228,7 +1228,7 @@ function resolveLocalJsonPointer(root, ref) {
1228
1228
  let current = root;
1229
1229
  for (const rawPart of ref.slice(2).split("/")) {
1230
1230
  const part = unescapeJsonPointerPart(rawPart);
1231
- if (isRecord$23(current)) {
1231
+ if (isRecord$24(current)) {
1232
1232
  if (!hasOwn(current, part)) return { found: false };
1233
1233
  current = current[part];
1234
1234
  } else if (Array.isArray(current)) {
@@ -1250,20 +1250,20 @@ function parseJsonPointerArrayIndex(part) {
1250
1250
  return Number(part);
1251
1251
  }
1252
1252
  function recurseSchema(node) {
1253
- if (!isRecord$23(node)) return;
1253
+ if (!isRecord$24(node)) return;
1254
1254
  visitChildSchemas(node, normalizeProperty);
1255
1255
  }
1256
1256
  function visitChildSchemas(node, visit) {
1257
1257
  for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
1258
1258
  const value = node[key];
1259
1259
  if (kind === "single") {
1260
- if (isRecord$23(value)) visit(value);
1260
+ if (isRecord$24(value)) visit(value);
1261
1261
  } else if (kind === "array") {
1262
1262
  if (Array.isArray(value)) for (const item of value) visit(item);
1263
1263
  } else if (kind === "map") {
1264
- if (isRecord$23(value)) for (const item of Object.values(value)) visit(item);
1264
+ if (isRecord$24(value)) for (const item of Object.values(value)) visit(item);
1265
1265
  } else if (kind === "schema-or-array") {
1266
- if (isRecord$23(value)) visit(value);
1266
+ if (isRecord$24(value)) visit(value);
1267
1267
  else if (Array.isArray(value)) for (const item of value) visit(item);
1268
1268
  }
1269
1269
  }
@@ -1275,7 +1275,7 @@ function childSchemaKeysForParentType(parentType) {
1275
1275
  });
1276
1276
  }
1277
1277
  function normalizeProperty(node) {
1278
- if (!isRecord$23(node)) return;
1278
+ if (!isRecord$24(node)) return;
1279
1279
  if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
1280
1280
  const enumValues = node["enum"];
1281
1281
  if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
@@ -1359,14 +1359,14 @@ function hasAnyKey(obj, keys) {
1359
1359
  }
1360
1360
  function cloneJsonValue(value) {
1361
1361
  if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
1362
- if (isRecord$23(value)) {
1362
+ if (isRecord$24(value)) {
1363
1363
  const cloned = {};
1364
1364
  for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
1365
1365
  return cloned;
1366
1366
  }
1367
1367
  return value;
1368
1368
  }
1369
- function isRecord$23(value) {
1369
+ function isRecord$24(value) {
1370
1370
  return typeof value === "object" && value !== null && !Array.isArray(value);
1371
1371
  }
1372
1372
  function hasOwn(obj, key) {
@@ -2072,11 +2072,11 @@ var init_blun_files = __esmMin((() => {
2072
2072
  async uploadVideo(input, options) {
2073
2073
  let file;
2074
2074
  if (typeof input === "string") {
2075
- if (!fs$16.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2075
+ if (!fs$17.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2076
2076
  const filename = path$17.basename(input);
2077
2077
  const mimeType = guessMimeTypeFromExt(filename);
2078
2078
  if (mimeType === void 0 || !mimeType.startsWith("video/")) throw new ChatProviderError(`BlunFiles.uploadVideo: file extension does not indicate a video type: ${filename}`);
2079
- const data = await fs$16.promises.readFile(input);
2079
+ const data = await fs$17.promises.readFile(input);
2080
2080
  file = new File$1([new Blob$1([new Uint8Array(data)], { type: mimeType })], filename, { type: mimeType });
2081
2081
  } else {
2082
2082
  if (!input.mimeType.startsWith("video/")) throw new ChatProviderError(`Expected a video mime type, got ${input.mimeType}`);
@@ -2428,6 +2428,10 @@ function isEffectivelyEmptyContent(parts) {
2428
2428
  }
2429
2429
  return true;
2430
2430
  }
2431
+ function isEmptyAssistantHistoryMessage(message) {
2432
+ if (message.role !== "assistant" || message.toolCalls.length > 0) return false;
2433
+ return message.content.every((part) => part.type === "think" || part.type === "text" && part.text.trim() === "");
2434
+ }
2431
2435
  function collectBlunVisionAttachments(messages) {
2432
2436
  const attachments = [];
2433
2437
  for (const message of messages) for (const part of message.content) {
@@ -2690,7 +2694,10 @@ var init_blun = __esmMin((() => {
2690
2694
  content: systemPrompt
2691
2695
  });
2692
2696
  const normalizedHistory = normalizeToolCallIdsForProvider(history, BLUN_TOOL_CALL_ID_POLICY);
2693
- for (const msg of normalizedHistory) messages.push(convertMessage(msg));
2697
+ for (const msg of normalizedHistory) {
2698
+ if (isEmptyAssistantHistoryMessage(msg)) continue;
2699
+ messages.push(convertMessage(msg));
2700
+ }
2694
2701
  const kwargs = { ...this._generationKwargs };
2695
2702
  for (const key of Object.keys(kwargs)) if (kwargs[key] === void 0) delete kwargs[key];
2696
2703
  if (kwargs["max_completion_tokens"] === void 0 && kwargs["max_tokens"] !== void 0) kwargs["max_completion_tokens"] = kwargs["max_tokens"];
@@ -2911,7 +2918,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
2911
2918
  if (signal?.aborted) throwAbortError();
2912
2919
  options?.onRequestStart?.();
2913
2920
  const stream = await provider.generate(systemPrompt, tools, history, options);
2914
- await throwIfAborted$1(signal, stream);
2921
+ await throwIfAborted$2(signal, stream);
2915
2922
  const abortListener = () => {
2916
2923
  cancelStream(stream);
2917
2924
  };
@@ -2957,10 +2964,10 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
2957
2964
  if (firstPartAt === void 0) firstPartAt = arrivedAt;
2958
2965
  else serverDecodeMs += arrivedAt - lastResumeAt;
2959
2966
  try {
2960
- await throwIfAborted$1(signal, stream);
2967
+ await throwIfAborted$2(signal, stream);
2961
2968
  if (callbacks?.onMessagePart !== void 0) {
2962
2969
  await callbacks.onMessagePart(deepCopyPart(part));
2963
- await throwIfAborted$1(signal, stream);
2970
+ await throwIfAborted$2(signal, stream);
2964
2971
  }
2965
2972
  if (isToolCallPart(part) && part.index !== void 0 && !isPendingToolCallAtIndex(pendingPart, part.index)) {
2966
2973
  const arrayIdx = toolCallIndexMap.get(part.index);
@@ -2980,7 +2987,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
2980
2987
  clientConsumeMs += lastResumeAt - arrivedAt;
2981
2988
  }
2982
2989
  }
2983
- await throwIfAborted$1(signal, stream);
2990
+ await throwIfAborted$2(signal, stream);
2984
2991
  if (firstPartAt !== void 0) serverDecodeMs += Date.now() - lastResumeAt;
2985
2992
  options?.onStreamEnd?.(firstPartAt === void 0 ? void 0 : {
2986
2993
  serverDecodeMs,
@@ -2999,7 +3006,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
2999
3006
  rawFinishReason: stream.rawFinishReason
3000
3007
  });
3001
3008
  if (callbacks?.onToolCall !== void 0) for (const toolCall of message.toolCalls) {
3002
- await throwIfAborted$1(signal, stream);
3009
+ await throwIfAborted$2(signal, stream);
3003
3010
  await callbacks.onToolCall(toolCall);
3004
3011
  }
3005
3012
  return {
@@ -3027,7 +3034,7 @@ async function cancelStream(stream) {
3027
3034
  await cancelable.return?.();
3028
3035
  } catch {}
3029
3036
  }
3030
- async function throwIfAborted$1(signal, stream) {
3037
+ async function throwIfAborted$2(signal, stream) {
3031
3038
  if (!signal?.aborted) return;
3032
3039
  if (stream !== void 0) await cancelStream(stream);
3033
3040
  throwAbortError();
@@ -10433,7 +10440,7 @@ function tokenFromWire(wire) {
10433
10440
  var init_types$17 = __esmMin((() => {}));
10434
10441
  //#endregion
10435
10442
  //#region ../../packages/oauth/src/utils.ts
10436
- function isRecord$22(value) {
10443
+ function isRecord$23(value) {
10437
10444
  return typeof value === "object" && value !== null && !Array.isArray(value);
10438
10445
  }
10439
10446
  var init_utils$1 = __esmMin((() => {}));
@@ -10757,7 +10764,7 @@ var init_storage = __esmMin((() => {
10757
10764
  } catch {
10758
10765
  return;
10759
10766
  }
10760
- if (!isRecord$22(parsed)) return void 0;
10767
+ if (!isRecord$23(parsed)) return void 0;
10761
10768
  return tokenFromWire(parsed);
10762
10769
  }
10763
10770
  async save(name, token) {
@@ -10851,7 +10858,7 @@ function extractApiErrorMessage(value) {
10851
10858
  }
10852
10859
  return;
10853
10860
  }
10854
- if (!isRecord$22(value)) return void 0;
10861
+ if (!isRecord$23(value)) return void 0;
10855
10862
  for (const key of DIRECT_ERROR_KEYS) {
10856
10863
  const message = stringField$4(value, key);
10857
10864
  if (message !== void 0) return message;
@@ -10859,7 +10866,7 @@ function extractApiErrorMessage(value) {
10859
10866
  const error = value["error"];
10860
10867
  const errorString = nonEmptyString$7(error);
10861
10868
  if (errorString !== void 0) return errorString;
10862
- if (isRecord$22(error)) for (const key of NESTED_ERROR_KEYS) {
10869
+ if (isRecord$23(error)) for (const key of NESTED_ERROR_KEYS) {
10863
10870
  const message = stringField$4(error, key);
10864
10871
  if (message !== void 0) return message;
10865
10872
  }
@@ -10949,7 +10956,7 @@ async function postForm(url, params, deviceHeaders, options) {
10949
10956
  let data = {};
10950
10957
  try {
10951
10958
  const parsed = await response.json();
10952
- if (isRecord$22(parsed)) data = parsed;
10959
+ if (isRecord$23(parsed)) data = parsed;
10953
10960
  } catch {}
10954
10961
  return {
10955
10962
  status,
@@ -11425,7 +11432,7 @@ var require_clone$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11425
11432
  //#endregion
11426
11433
  //#region ../../node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js
11427
11434
  var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11428
- var fs$15 = __require("fs");
11435
+ var fs$16 = __require("fs");
11429
11436
  var polyfills = require_polyfills();
11430
11437
  var legacy = require_legacy_streams();
11431
11438
  var clone = require_clone$1();
@@ -11454,36 +11461,36 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11454
11461
  m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
11455
11462
  console.error(m);
11456
11463
  };
11457
- if (!fs$15[gracefulQueue]) {
11458
- publishQueue(fs$15, global[gracefulQueue] || []);
11459
- fs$15.close = (function(fs$close) {
11464
+ if (!fs$16[gracefulQueue]) {
11465
+ publishQueue(fs$16, global[gracefulQueue] || []);
11466
+ fs$16.close = (function(fs$close) {
11460
11467
  function close(fd, cb) {
11461
- return fs$close.call(fs$15, fd, function(err) {
11468
+ return fs$close.call(fs$16, fd, function(err) {
11462
11469
  if (!err) resetQueue();
11463
11470
  if (typeof cb === "function") cb.apply(this, arguments);
11464
11471
  });
11465
11472
  }
11466
11473
  Object.defineProperty(close, previousSymbol, { value: fs$close });
11467
11474
  return close;
11468
- })(fs$15.close);
11469
- fs$15.closeSync = (function(fs$closeSync) {
11475
+ })(fs$16.close);
11476
+ fs$16.closeSync = (function(fs$closeSync) {
11470
11477
  function closeSync(fd) {
11471
- fs$closeSync.apply(fs$15, arguments);
11478
+ fs$closeSync.apply(fs$16, arguments);
11472
11479
  resetQueue();
11473
11480
  }
11474
11481
  Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync });
11475
11482
  return closeSync;
11476
- })(fs$15.closeSync);
11483
+ })(fs$16.closeSync);
11477
11484
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) process.on("exit", function() {
11478
- debug(fs$15[gracefulQueue]);
11479
- __require("assert").equal(fs$15[gracefulQueue].length, 0);
11485
+ debug(fs$16[gracefulQueue]);
11486
+ __require("assert").equal(fs$16[gracefulQueue].length, 0);
11480
11487
  });
11481
11488
  }
11482
- if (!global[gracefulQueue]) publishQueue(global, fs$15[gracefulQueue]);
11483
- module.exports = patch(clone(fs$15));
11484
- if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$15.__patched) {
11485
- module.exports = patch(fs$15);
11486
- fs$15.__patched = true;
11489
+ if (!global[gracefulQueue]) publishQueue(global, fs$16[gracefulQueue]);
11490
+ module.exports = patch(clone(fs$16));
11491
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$16.__patched) {
11492
+ module.exports = patch(fs$16);
11493
+ fs$16.__patched = true;
11487
11494
  }
11488
11495
  function patch(fs) {
11489
11496
  polyfills(fs);
@@ -11738,23 +11745,23 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11738
11745
  }
11739
11746
  function enqueue(elem) {
11740
11747
  debug("ENQUEUE", elem[0].name, elem[1]);
11741
- fs$15[gracefulQueue].push(elem);
11748
+ fs$16[gracefulQueue].push(elem);
11742
11749
  retry();
11743
11750
  }
11744
11751
  var retryTimer;
11745
11752
  function resetQueue() {
11746
11753
  var now = Date.now();
11747
- for (var i = 0; i < fs$15[gracefulQueue].length; ++i) if (fs$15[gracefulQueue][i].length > 2) {
11748
- fs$15[gracefulQueue][i][3] = now;
11749
- fs$15[gracefulQueue][i][4] = now;
11754
+ for (var i = 0; i < fs$16[gracefulQueue].length; ++i) if (fs$16[gracefulQueue][i].length > 2) {
11755
+ fs$16[gracefulQueue][i][3] = now;
11756
+ fs$16[gracefulQueue][i][4] = now;
11750
11757
  }
11751
11758
  retry();
11752
11759
  }
11753
11760
  function retry() {
11754
11761
  clearTimeout(retryTimer);
11755
11762
  retryTimer = void 0;
11756
- if (fs$15[gracefulQueue].length === 0) return;
11757
- var elem = fs$15[gracefulQueue].shift();
11763
+ if (fs$16[gracefulQueue].length === 0) return;
11764
+ var elem = fs$16[gracefulQueue].shift();
11758
11765
  var fn = elem[0];
11759
11766
  var args = elem[1];
11760
11767
  var err = elem[2];
@@ -11773,7 +11780,7 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11773
11780
  if (sinceAttempt >= Math.min(sinceStart * 1.2, 100)) {
11774
11781
  debug("RETRY", fn.name, args);
11775
11782
  fn.apply(null, args.concat([startTime]));
11776
- } else fs$15[gracefulQueue].push(elem);
11783
+ } else fs$16[gracefulQueue].push(elem);
11777
11784
  }
11778
11785
  if (retryTimer === void 0) retryTimer = setTimeout(retry, 0);
11779
11786
  }
@@ -12861,9 +12868,9 @@ function blunContextWindowsUrl(oauthHost) {
12861
12868
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}/api/verbrauch/tarife`;
12862
12869
  }
12863
12870
  function parseManagedContextWindow(payload, plan) {
12864
- if (!isRecord$22(payload)) return void 0;
12871
+ if (!isRecord$23(payload)) return void 0;
12865
12872
  const contextWindows = payload["kontext"];
12866
- if (!isRecord$22(contextWindows)) return void 0;
12873
+ if (!isRecord$23(contextWindows)) return void 0;
12867
12874
  const value = contextWindows[plan];
12868
12875
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
12869
12876
  }
@@ -12898,7 +12905,7 @@ function parseManagedUsagePayload(payload) {
12898
12905
  const plan = typeof rec["plan"] === "string" && rec["plan"].trim().length > 0 ? rec["plan"].trim() : void 0;
12899
12906
  const contextWindowTokens = managedContextWindowFrom(rec);
12900
12907
  const unlimited = rec["unlimited"] === true;
12901
- const stand = isRecord$22(rec["stand"]) ? rec["stand"] : void 0;
12908
+ const stand = isRecord$23(rec["stand"]) ? rec["stand"] : void 0;
12902
12909
  if (stand !== void 0) for (const [sourceKey, id, label] of ACCOUNT_USAGE_WINDOWS) {
12903
12910
  const row = toAccountUsageRow(stand[sourceKey], id, label, unlimited);
12904
12911
  if (row !== null) limits.push(row);
@@ -12908,9 +12915,9 @@ function parseManagedUsagePayload(payload) {
12908
12915
  const item = rawLimits[idx];
12909
12916
  if (!item || typeof item !== "object") continue;
12910
12917
  const detailRaw = item["detail"];
12911
- const detail = isRecord$22(detailRaw) ? detailRaw : item;
12918
+ const detail = isRecord$23(detailRaw) ? detailRaw : item;
12912
12919
  const windowRaw = item["window"];
12913
- const row = toUsageRow(detail, limitLabel(item, detail, isRecord$22(windowRaw) ? windowRaw : {}, idx));
12920
+ const row = toUsageRow(detail, limitLabel(item, detail, isRecord$23(windowRaw) ? windowRaw : {}, idx));
12914
12921
  if (row !== null) limits.push(row);
12915
12922
  }
12916
12923
  return {
@@ -12934,7 +12941,7 @@ function managedContextWindowFrom(payload) {
12934
12941
  return values.every((value) => value === first) ? first : void 0;
12935
12942
  }
12936
12943
  function toAccountUsageRow(raw, id, label, accountUnlimited) {
12937
- if (!isRecord$22(raw)) return null;
12944
+ if (!isRecord$23(raw)) return null;
12938
12945
  const used = toInt(raw["verbraucht"]);
12939
12946
  const unlimited = accountUnlimited || raw["unlimited"] === true;
12940
12947
  const fraction = raw["anteil"];
@@ -12967,7 +12974,7 @@ function toAccountUsageRow(raw, id, label, accountUnlimited) {
12967
12974
  };
12968
12975
  }
12969
12976
  function toUsageRow(raw, defaultLabel) {
12970
- if (!isRecord$22(raw)) return null;
12977
+ if (!isRecord$23(raw)) return null;
12971
12978
  const unlimited = raw["unlimited"] === true;
12972
12979
  const limit = toInt(raw["limit"]);
12973
12980
  let used = toInt(raw["used"]);
@@ -13088,7 +13095,7 @@ function isManagedQuotaErrorMessage(message) {
13088
13095
  return /you(?:'|’)?ve reached your usage limit/.test(normalized) && /billing cycle|quota will be (?:refreshed|reset)|purchase extra usage/.test(normalized);
13089
13096
  }
13090
13097
  function hasManagedUsageShape(payload) {
13091
- if (!isRecord$22(payload)) return false;
13098
+ if (!isRecord$23(payload)) return false;
13092
13099
  let recognized = false;
13093
13100
  if ("context_window_tokens" in payload || "contextWindowTokens" in payload) {
13094
13101
  recognized = true;
@@ -13104,15 +13111,15 @@ function hasManagedUsageShape(payload) {
13104
13111
  if (!Array.isArray(limits)) return false;
13105
13112
  for (let index = 0; index < limits.length; index++) {
13106
13113
  const item = limits[index];
13107
- if (!isRecord$22(item)) return false;
13108
- const detail = isRecord$22(item["detail"]) ? item["detail"] : item;
13109
- if (toUsageRow(detail, limitLabel(item, detail, isRecord$22(item["window"]) ? item["window"] : {}, index)) === null) return false;
13114
+ if (!isRecord$23(item)) return false;
13115
+ const detail = isRecord$23(item["detail"]) ? item["detail"] : item;
13116
+ if (toUsageRow(detail, limitLabel(item, detail, isRecord$23(item["window"]) ? item["window"] : {}, index)) === null) return false;
13110
13117
  }
13111
13118
  }
13112
13119
  if ("stand" in payload) {
13113
13120
  recognized = true;
13114
13121
  const stand = payload["stand"];
13115
- if (!isRecord$22(stand)) return false;
13122
+ if (!isRecord$23(stand)) return false;
13116
13123
  const windows = ACCOUNT_USAGE_WINDOWS.filter(([sourceKey]) => sourceKey in stand);
13117
13124
  if (windows.length === 0) return false;
13118
13125
  const unlimited = payload["unlimited"] === true;
@@ -13208,8 +13215,8 @@ function userExtras(existing, remoteOwnedFields) {
13208
13215
  return out;
13209
13216
  }
13210
13217
  function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
13211
- const current = isRecord$22(existing) ? existing : {};
13212
- const overrides = cloneOverrides(isRecord$22(current["overrides"]) ? current["overrides"] : void 0);
13218
+ const current = isRecord$23(existing) ? existing : {};
13219
+ const overrides = cloneOverrides(isRecord$23(current["overrides"]) ? current["overrides"] : void 0);
13213
13220
  return {
13214
13221
  ...userExtras(current, remoteOwnedFields),
13215
13222
  ...remote,
@@ -13260,16 +13267,16 @@ function capabilitiesForModel(model) {
13260
13267
  function defaultBaseUrl(baseUrl) {
13261
13268
  return (baseUrl ?? blunCodeBaseUrl()).replace(/\/+$/, "");
13262
13269
  }
13263
- function normalizeBaseUrl(baseUrl) {
13270
+ function normalizeBaseUrl$1(baseUrl) {
13264
13271
  return baseUrl.replace(/\/+$/, "");
13265
13272
  }
13266
- function normalizeEndpoint(value) {
13273
+ function normalizeEndpoint$1(value) {
13267
13274
  return value.trim().replace(/\/+$/, "");
13268
13275
  }
13269
13276
  function persistedOAuthHost(options) {
13270
13277
  const oauthHost = options.oauthHost;
13271
- const normalized = normalizeEndpoint(oauthHost ?? "https://account.blun.ai");
13272
- if (options.key === "oauth/blun" && normalized === normalizeEndpoint("https://account.blun.ai")) return;
13278
+ const normalized = normalizeEndpoint$1(oauthHost ?? "https://account.blun.ai");
13279
+ if (options.key === "oauth/blun" && normalized === normalizeEndpoint$1("https://account.blun.ai")) return;
13273
13280
  return normalized;
13274
13281
  }
13275
13282
  function managedOAuthRef(options) {
@@ -13297,7 +13304,7 @@ function blunCodeEnvOAuthHost(env = process.env) {
13297
13304
  return env.BLUN_OAUTH_HOST;
13298
13305
  }
13299
13306
  function resolveBlunCodeOAuthKey(options) {
13300
- const oauthHost = normalizeEndpoint(options.oauthHost ?? "https://account.blun.ai");
13307
+ const oauthHost = normalizeEndpoint$1(options.oauthHost ?? "https://account.blun.ai");
13301
13308
  const baseUrl = defaultBaseUrl(options.baseUrl);
13302
13309
  if (SHARED_DEFAULT_OAUTH_HOSTS.has(oauthHost) && SHARED_DEFAULT_BASE_URLS.has(baseUrl)) return BLUN_OAUTH_KEY;
13303
13310
  return `${BLUN_SCOPED_OAUTH_KEY_PREFIX}${createHash("sha256").update(JSON.stringify({
@@ -13326,7 +13333,7 @@ function resolveBlunCodeRuntimeAuth(options) {
13326
13333
  const envBaseUrl = blunCodeEnvBaseUrl(env);
13327
13334
  const envOAuthHost = blunCodeEnvOAuthHost(env);
13328
13335
  const hasEnvOverride = envBaseUrl !== void 0 || envOAuthHost !== void 0;
13329
- const baseUrl = envBaseUrl !== void 0 ? normalizeBaseUrl(envBaseUrl) : options.configuredBaseUrl;
13336
+ const baseUrl = envBaseUrl !== void 0 ? normalizeBaseUrl$1(envBaseUrl) : options.configuredBaseUrl;
13330
13337
  const expected = resolveBlunCodeOAuthRef({
13331
13338
  oauthHost: hasEnvOverride ? envOAuthHost : options.configuredOAuthRef?.oauthHost,
13332
13339
  baseUrl
@@ -13354,7 +13361,7 @@ function resolveBlunCodeLoginAuth(options) {
13354
13361
  const envBaseUrl = blunCodeEnvBaseUrl(env);
13355
13362
  const envOAuthHost = blunCodeEnvOAuthHost(env);
13356
13363
  const hasOverride = options.requestedBaseUrl !== void 0 || options.requestedOAuthHost !== void 0 || envBaseUrl !== void 0 || envOAuthHost !== void 0;
13357
- const baseUrl = options.requestedBaseUrl !== void 0 ? normalizeBaseUrl(options.requestedBaseUrl) : envBaseUrl !== void 0 ? normalizeBaseUrl(envBaseUrl) : options.configuredBaseUrl;
13364
+ const baseUrl = options.requestedBaseUrl !== void 0 ? normalizeBaseUrl$1(options.requestedBaseUrl) : envBaseUrl !== void 0 ? normalizeBaseUrl$1(envBaseUrl) : options.configuredBaseUrl;
13358
13365
  const oauthHost = options.requestedOAuthHost ?? envOAuthHost;
13359
13366
  if (hasOverride) return {
13360
13367
  baseUrl,
@@ -13391,7 +13398,7 @@ function parseModelContextLength(item, modelId) {
13391
13398
  return values[0];
13392
13399
  }
13393
13400
  function toModelInfo(item) {
13394
- if (!isRecord$22(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13401
+ if (!isRecord$23(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13395
13402
  const contextLength = parseModelContextLength(item, item["id"]);
13396
13403
  const displayName = item["display_name"];
13397
13404
  const normalizedDisplayName = typeof displayName === "string" && displayName.length > 0 ? displayName : void 0;
@@ -13478,7 +13485,7 @@ async function fetchManagedBlunCodeModels(options) {
13478
13485
  throw new Error(message);
13479
13486
  }
13480
13487
  const payload = await response.json();
13481
- if (!isRecord$22(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
13488
+ if (!isRecord$23(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
13482
13489
  return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
13483
13490
  }
13484
13491
  throw new Error(`Failed to list BLUN models for ${baseUrl}.`);
@@ -13521,11 +13528,11 @@ function applyManagedBlunCodeConfig(config, options) {
13521
13528
  apiKey
13522
13529
  };
13523
13530
  const upstreamKeys = new Set(options.models.map((m) => managedModelKey(m.id)));
13524
- for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$22(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
13531
+ for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$23(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
13525
13532
  for (const model of options.models) {
13526
13533
  const capabilities = capabilitiesForModel(model);
13527
13534
  const key = managedModelKey(model.id);
13528
- const existing = isRecord$22(existingModels[key]) ? existingModels[key] : {};
13535
+ const existing = isRecord$23(existingModels[key]) ? existingModels[key] : {};
13529
13536
  const supportsAdaptiveThinking = capabilities?.includes("thinking") === true || capabilities?.includes("always_thinking") === true;
13530
13537
  existingModels[key] = mergeRefreshedModelAlias(existing, {
13531
13538
  provider: BLUN_PROVIDER_NAME$1,
@@ -13573,7 +13580,7 @@ function applyManagedBlunCodeLogoutConfig(config) {
13573
13580
  let removedDefaultModel = false;
13574
13581
  const existingModels = config.models ?? {};
13575
13582
  for (const [key, model] of Object.entries(existingModels)) {
13576
- if (!isRecord$22(model) || model["provider"] !== "managed:blun") continue;
13583
+ if (!isRecord$23(model) || model["provider"] !== "managed:blun") continue;
13577
13584
  delete existingModels[key];
13578
13585
  if (config.defaultModel === key) removedDefaultModel = true;
13579
13586
  }
@@ -13613,7 +13620,7 @@ function selectDefaultModel(config, models, options) {
13613
13620
  function canPreserveDefaultModel(existingModels, defaultModel, managedModels) {
13614
13621
  if (managedModels.has(defaultModel)) return true;
13615
13622
  const existing = existingModels[defaultModel];
13616
- return isRecord$22(existing) && existing["provider"] !== "managed:blun";
13623
+ return isRecord$23(existing) && existing["provider"] !== "managed:blun";
13617
13624
  }
13618
13625
  function assertPositiveContextLength(model) {
13619
13626
  if (!Number.isInteger(model.contextLength) || model.contextLength <= 0) throw new Error(`BLUN model "${model.id}" must include a positive context_length.`);
@@ -13677,8 +13684,8 @@ var init_managed_blun = __esmMin((() => {
13677
13684
  this.baseUrl = options.baseUrl;
13678
13685
  }
13679
13686
  };
13680
- SHARED_DEFAULT_BASE_URLS = new Set([normalizeEndpoint(DEFAULT_BLUN_BASE_URL), normalizeEndpoint("https://api.blun.ai/coding/v1")]);
13681
- SHARED_DEFAULT_OAUTH_HOSTS = new Set([normalizeEndpoint(DEFAULT_BLUN_OAUTH_HOST), normalizeEndpoint("https://auth.blun.ai")]);
13687
+ SHARED_DEFAULT_BASE_URLS = new Set([normalizeEndpoint$1(DEFAULT_BLUN_BASE_URL), normalizeEndpoint$1("https://api.blun.ai/coding/v1")]);
13688
+ SHARED_DEFAULT_OAUTH_HOSTS = new Set([normalizeEndpoint$1(DEFAULT_BLUN_OAUTH_HOST), normalizeEndpoint$1("https://auth.blun.ai")]);
13682
13689
  MODEL_CONTEXT_LENGTH_FIELDS = [
13683
13690
  "context_length",
13684
13691
  "max_model_len",
@@ -13691,13 +13698,13 @@ function blunManagedQuotaUrl(oauthHost) {
13691
13698
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}${MANAGED_QUOTA_PATH}`;
13692
13699
  }
13693
13700
  function parseManagedQuotaPayload(payload) {
13694
- if (!isRecord$22(payload)) return void 0;
13701
+ if (!isRecord$23(payload)) return void 0;
13695
13702
  const plan = nonEmptyString$6(payload["plan"]);
13696
13703
  const paid = payload["bezahlt"];
13697
13704
  const creditCents = payload["guthaben_cent"];
13698
13705
  const billingKind = nonEmptyString$6(payload["art"]);
13699
13706
  const globalUnlimited = payload["unlimited"];
13700
- if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$22(payload["stand"])) return;
13707
+ if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$23(payload["stand"])) return;
13701
13708
  if (!hasStrictQuotaStand(payload["stand"], globalUnlimited === true)) return void 0;
13702
13709
  const limits = parseManagedUsagePayload(payload).limits;
13703
13710
  if (limits.length !== REQUIRED_WINDOWS.length || REQUIRED_WINDOWS.some(([, id]) => limits.filter((row) => row.id === id).length !== 1)) return;
@@ -13767,7 +13774,7 @@ function nonEmptyString$6(value) {
13767
13774
  function hasStrictQuotaStand(stand, globalUnlimited) {
13768
13775
  return REQUIRED_WINDOWS.every(([sourceKey]) => {
13769
13776
  const row = stand[sourceKey];
13770
- if (!isRecord$22(row)) return false;
13777
+ if (!isRecord$23(row)) return false;
13771
13778
  const used = row["verbraucht"];
13772
13779
  const rowUnlimited = row["unlimited"];
13773
13780
  if (rowUnlimited !== void 0 && typeof rowUnlimited !== "boolean") return false;
@@ -14609,7 +14616,7 @@ async function syncDir(dirPath) {
14609
14616
  */
14610
14617
  function syncFd(fd) {
14611
14618
  return new Promise((resolve, reject) => {
14612
- fs$16.fsync(fd, (err) => {
14619
+ fs$17.fsync(fd, (err) => {
14613
14620
  if (err) {
14614
14621
  reject(err);
14615
14622
  return;
@@ -20943,7 +20950,7 @@ function parseSkillText(options) {
20943
20950
  throw error;
20944
20951
  }
20945
20952
  const frontmatter = parsed.data ?? {};
20946
- if (!isRecord$21(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
20953
+ if (!isRecord$22(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
20947
20954
  const metadata = normalizeMetadata(frontmatter);
20948
20955
  if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
20949
20956
  const name = nonEmptyString$4(metadata.name);
@@ -21056,7 +21063,7 @@ function tokenizeArgs(raw) {
21056
21063
  function nonEmptyString$4(value) {
21057
21064
  return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
21058
21065
  }
21059
- function isRecord$21(value) {
21066
+ function isRecord$22(value) {
21060
21067
  return typeof value === "object" && value !== null && !Array.isArray(value);
21061
21068
  }
21062
21069
  var import_regexp_escape, FrontmatterError, SkillParseError, UnsupportedSkillTypeError, FENCE, METADATA_ALIASES;
@@ -21105,7 +21112,7 @@ var init_parser$1 = __esmMin((() => {
21105
21112
  function parseCommandText(input) {
21106
21113
  const { text, commandPath, pluginId } = input;
21107
21114
  const parsed = parseFrontmatter(text);
21108
- const frontmatter = isRecord$20(parsed.data) ? parsed.data : {};
21115
+ const frontmatter = isRecord$21(parsed.data) ? parsed.data : {};
21109
21116
  const baseName = input.fallbackName ?? path.basename(commandPath).replace(/\.md$/i, "");
21110
21117
  const name = nonEmptyString$3(frontmatter["name"]) ?? baseName;
21111
21118
  const body = parsed.body.trim();
@@ -21147,7 +21154,7 @@ function descriptionFromBody(body) {
21147
21154
  if (firstLine === void 0) return "No description provided.";
21148
21155
  return firstLine.length > 240 ? `${firstLine.slice(0, 239)}…` : firstLine;
21149
21156
  }
21150
- function isRecord$20(value) {
21157
+ function isRecord$21(value) {
21151
21158
  return typeof value === "object" && value !== null && !Array.isArray(value);
21152
21159
  }
21153
21160
  var init_commands = __esmMin((() => {
@@ -26786,7 +26793,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26786
26793
  };
26787
26794
  return _setPrototypeOf(o, p);
26788
26795
  }
26789
- var fs$14 = __require("fs");
26796
+ var fs$15 = __require("fs");
26790
26797
  var path$14 = __require("path");
26791
26798
  var Loader = require_loader();
26792
26799
  var PrecompiledLoader = require_precompiled_loader().PrecompiledLoader;
@@ -26810,7 +26817,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26810
26817
  } catch (e) {
26811
26818
  throw new Error("watch requires chokidar to be installed");
26812
26819
  }
26813
- var paths = _this.searchPaths.filter(fs$14.existsSync);
26820
+ var paths = _this.searchPaths.filter(fs$15.existsSync);
26814
26821
  var watcher = chokidar.watch(paths);
26815
26822
  watcher.on("all", function(event, fullname) {
26816
26823
  fullname = path$14.resolve(fullname);
@@ -26829,7 +26836,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26829
26836
  for (var i = 0; i < paths.length; i++) {
26830
26837
  var basePath = path$14.resolve(paths[i]);
26831
26838
  var p = path$14.resolve(paths[i], name);
26832
- if (p.indexOf(basePath) === 0 && fs$14.existsSync(p)) {
26839
+ if (p.indexOf(basePath) === 0 && fs$15.existsSync(p)) {
26833
26840
  fullpath = p;
26834
26841
  break;
26835
26842
  }
@@ -26837,7 +26844,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26837
26844
  if (!fullpath) return null;
26838
26845
  this.pathsToNames[fullpath] = name;
26839
26846
  var source = {
26840
- src: fs$14.readFileSync(fullpath, "utf-8"),
26847
+ src: fs$15.readFileSync(fullpath, "utf-8"),
26841
26848
  path: fullpath,
26842
26849
  noCache: this.noCache
26843
26850
  };
@@ -26885,7 +26892,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26885
26892
  }
26886
26893
  this.pathsToNames[fullpath] = name;
26887
26894
  var source = {
26888
- src: fs$14.readFileSync(fullpath, "utf-8"),
26895
+ src: fs$15.readFileSync(fullpath, "utf-8"),
26889
26896
  path: fullpath,
26890
26897
  noCache: this.noCache
26891
26898
  };
@@ -27629,7 +27636,7 @@ var require_precompile_global = /* @__PURE__ */ __commonJSMin(((exports, module)
27629
27636
  //#endregion
27630
27637
  //#region ../../node_modules/.pnpm/nunjucks@3.2.4_chokidar@4.0.3/node_modules/nunjucks/src/precompile.js
27631
27638
  var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27632
- var fs$13 = __require("fs");
27639
+ var fs$14 = __require("fs");
27633
27640
  var path$12 = __require("path");
27634
27641
  var _prettifyError = require_lib$7()._prettifyError;
27635
27642
  var compiler = require_compiler();
@@ -27654,27 +27661,27 @@ var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27654
27661
  var env = opts.env || new Environment([]);
27655
27662
  var wrapper = opts.wrapper || precompileGlobal;
27656
27663
  if (opts.isString) return precompileString(input, opts);
27657
- var pathStats = fs$13.existsSync(input) && fs$13.statSync(input);
27664
+ var pathStats = fs$14.existsSync(input) && fs$14.statSync(input);
27658
27665
  var precompiled = [];
27659
27666
  var templates = [];
27660
27667
  function addTemplates(dir) {
27661
- fs$13.readdirSync(dir).forEach(function(file) {
27668
+ fs$14.readdirSync(dir).forEach(function(file) {
27662
27669
  var filepath = path$12.join(dir, file);
27663
27670
  var subpath = filepath.substr(path$12.join(input, "/").length);
27664
- var stat = fs$13.statSync(filepath);
27671
+ var stat = fs$14.statSync(filepath);
27665
27672
  if (stat && stat.isDirectory()) {
27666
27673
  subpath += "/";
27667
27674
  if (!match(subpath, opts.exclude)) addTemplates(filepath);
27668
27675
  } else if (match(subpath, opts.include)) templates.push(filepath);
27669
27676
  });
27670
27677
  }
27671
- if (pathStats.isFile()) precompiled.push(_precompile(fs$13.readFileSync(input, "utf-8"), opts.name || input, env));
27678
+ if (pathStats.isFile()) precompiled.push(_precompile(fs$14.readFileSync(input, "utf-8"), opts.name || input, env));
27672
27679
  else if (pathStats.isDirectory()) {
27673
27680
  addTemplates(input);
27674
27681
  for (var i = 0; i < templates.length; i++) {
27675
27682
  var name = templates[i].replace(path$12.join(input, "/"), "");
27676
27683
  try {
27677
- precompiled.push(_precompile(fs$13.readFileSync(templates[i], "utf-8"), name, env));
27684
+ precompiled.push(_precompile(fs$14.readFileSync(templates[i], "utf-8"), name, env));
27678
27685
  } catch (e) {
27679
27686
  if (opts.force) console.error(e);
27680
27687
  else throw e;
@@ -28750,12 +28757,12 @@ function legacyStatusToCurrent$1(task) {
28750
28757
  return task.status;
28751
28758
  }
28752
28759
  function isReadablePersistedTask$1(obj) {
28753
- return isRecord$19(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
28760
+ return isRecord$20(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
28754
28761
  }
28755
28762
  function isLegacyPersistedTask$1(task) {
28756
28763
  return "task_id" in task;
28757
28764
  }
28758
- function isRecord$19(value) {
28765
+ function isRecord$20(value) {
28759
28766
  return typeof value === "object" && value !== null;
28760
28767
  }
28761
28768
  function optionalNonEmptyString$2(value) {
@@ -36239,7 +36246,7 @@ var require_gifframe = /* @__PURE__ */ __commonJSMin(((exports) => {
36239
36246
  //#region ../../node_modules/.pnpm/gifwrap@0.10.1/node_modules/gifwrap/src/gifutil.js
36240
36247
  var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
36241
36248
  /** @namespace GifUtil */
36242
- const fs$12 = __require("fs");
36249
+ const fs$13 = __require("fs");
36243
36250
  const ImageQ = require_image_q();
36244
36251
  const BitmapImage = require_bitmapimage();
36245
36252
  const { GifFrame } = require_gifframe();
@@ -36506,7 +36513,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
36506
36513
  }
36507
36514
  function _readBinary(path) {
36508
36515
  return new Promise((resolve, reject) => {
36509
- fs$12.readFile(path, (err, buffer) => {
36516
+ fs$13.readFile(path, (err, buffer) => {
36510
36517
  if (err) return reject(err);
36511
36518
  return resolve(buffer);
36512
36519
  });
@@ -36514,7 +36521,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
36514
36521
  }
36515
36522
  function _writeBinary(path, buffer) {
36516
36523
  return new Promise((resolve, reject) => {
36517
- fs$12.writeFile(path, buffer, (err) => {
36524
+ fs$13.writeFile(path, buffer, (err) => {
36518
36525
  if (err) return reject(err);
36519
36526
  return resolve();
36520
36527
  });
@@ -50319,7 +50326,7 @@ function addIssueToContext(ctx, issueData) {
50319
50326
  });
50320
50327
  ctx.common.issues.push(issue);
50321
50328
  }
50322
- var makeIssue, EMPTY_PATH, ParseStatus, INVALID, DIRTY, OK, isAborted, isDirty, isValid$1, isAsync;
50329
+ var makeIssue, EMPTY_PATH, ParseStatus, INVALID, DIRTY, OK, isAborted$1, isDirty, isValid$1, isAsync;
50323
50330
  var init_parseUtil = __esmMin((() => {
50324
50331
  init_errors$3();
50325
50332
  init_en();
@@ -50407,7 +50414,7 @@ var init_parseUtil = __esmMin((() => {
50407
50414
  status: "valid",
50408
50415
  value
50409
50416
  });
50410
- isAborted = (x) => x.status === "aborted";
50417
+ isAborted$1 = (x) => x.status === "aborted";
50411
50418
  isDirty = (x) => x.status === "dirty";
50412
50419
  isValid$1 = (x) => x.status === "valid";
50413
50420
  isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
@@ -52624,7 +52631,7 @@ var init_types$11 = __esmMin((() => {
52624
52631
  _parse(input) {
52625
52632
  const { status, ctx } = this._processInputParams(input);
52626
52633
  const handleParsed = (parsedLeft, parsedRight) => {
52627
- if (isAborted(parsedLeft) || isAborted(parsedRight)) return INVALID;
52634
+ if (isAborted$1(parsedLeft) || isAborted$1(parsedRight)) return INVALID;
52628
52635
  const merged = mergeValues(parsedLeft.value, parsedRight.value);
52629
52636
  if (!merged.valid) {
52630
52637
  addIssueToContext(ctx, { code: ZodIssueCode.invalid_intersection_types });
@@ -53712,7 +53719,7 @@ var external_exports = /* @__PURE__ */ __exportAll({
53712
53719
  getParsedType: () => getParsedType,
53713
53720
  instanceof: () => instanceOfType,
53714
53721
  intersection: () => intersectionType,
53715
- isAborted: () => isAborted,
53722
+ isAborted: () => isAborted$1,
53716
53723
  isAsync: () => isAsync,
53717
53724
  isDirty: () => isDirty,
53718
53725
  isValid: () => isValid$1,
@@ -62332,7 +62339,7 @@ var init_file_type = __esmMin((() => {
62332
62339
  }
62333
62340
  async fromFile(path) {
62334
62341
  this.options.signal?.throwIfAborted();
62335
- const fileHandle = await ro.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
62342
+ const fileHandle = await fs.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
62336
62343
  const fileStat = await fileHandle.stat();
62337
62344
  if (!fileStat.isFile()) {
62338
62345
  await fileHandle.close();
@@ -73854,7 +73861,7 @@ function escapeXml(value) {
73854
73861
  function locationKey(messageIndex, partIndex) {
73855
73862
  return `${String(messageIndex)}:${String(partIndex)}`;
73856
73863
  }
73857
- function isRecord$18(value) {
73864
+ function isRecord$19(value) {
73858
73865
  return value !== null && typeof value === "object" && !Array.isArray(value);
73859
73866
  }
73860
73867
  function isNonNegativeInteger$1(value) {
@@ -74053,7 +74060,7 @@ var init_vision_reader = __esmMin((() => {
74053
74060
  reason: "malformed"
74054
74061
  };
74055
74062
  }
74056
- if (!isRecord$18(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
74063
+ if (!isRecord$19(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
74057
74064
  ok: false,
74058
74065
  reason: "malformed"
74059
74066
  };
@@ -76378,7 +76385,7 @@ var init_telemetry_events = __esmMin((() => {
76378
76385
  //#endregion
76379
76386
  //#region ../../packages/agent-core/src/agent/cron/manager.ts
76380
76387
  var STALE_THRESHOLD_MS, CronManager;
76381
- var init_manager$2 = __esmMin((() => {
76388
+ var init_manager$3 = __esmMin((() => {
76382
76389
  init_clock();
76383
76390
  init_cron_fire_xml();
76384
76391
  init_persist();
@@ -76790,7 +76797,7 @@ var init_manager$2 = __esmMin((() => {
76790
76797
  //#endregion
76791
76798
  //#region ../../packages/agent-core/src/agent/cron/index.ts
76792
76799
  var init_cron$1 = __esmMin((() => {
76793
- init_manager$2();
76800
+ init_manager$3();
76794
76801
  }));
76795
76802
  //#endregion
76796
76803
  //#region ../../packages/agent-core/src/tools/policies/sensitive.ts
@@ -229885,7 +229892,7 @@ function killProcessTreeWindows(child, force) {
229885
229892
  } catch {}
229886
229893
  }
229887
229894
  }
229888
- function isRecord$17(value) {
229895
+ function isRecord$18(value) {
229889
229896
  return typeof value === "object" && value !== null && !Array.isArray(value);
229890
229897
  }
229891
229898
  function errorMessage$11(error) {
@@ -229901,7 +229908,7 @@ var init_runner = __esmMin((() => {
229901
229908
  if (typeof value === "string") return value;
229902
229909
  if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
229903
229910
  }, string().optional());
229904
- HookSpecificOutputSchema = preprocess((value) => isRecord$17(value) ? value : void 0, looseObject({
229911
+ HookSpecificOutputSchema = preprocess((value) => isRecord$18(value) ? value : void 0, looseObject({
229905
229912
  message: OptionalStringSchema,
229906
229913
  permissionDecision: unknown().optional(),
229907
229914
  permissionDecisionReason: OptionalStringSchema
@@ -230811,7 +230818,7 @@ function parsePersonalMemoryRecall(output) {
230811
230818
  } catch {
230812
230819
  return { kind: "invalid" };
230813
230820
  }
230814
- if (!isRecord$16(parsed) || !isRecord$16(parsed["personal_memory"])) return { kind: "invalid" };
230821
+ if (!isRecord$17(parsed) || !isRecord$17(parsed["personal_memory"])) return { kind: "invalid" };
230815
230822
  const memory = parsed["personal_memory"];
230816
230823
  const savedRaw = memory["saved"];
230817
230824
  const threadsRaw = memory["threads"];
@@ -230820,7 +230827,7 @@ function parsePersonalMemoryRecall(output) {
230820
230827
  if (savedRaw.length > MAX_SAVED_MEMORIES || threadsRaw.length > MAX_THREADS || historyRaw.length > 0) return { kind: "invalid" };
230821
230828
  const saved = [];
230822
230829
  for (const value of savedRaw) {
230823
- if (!isRecord$16(value)) return { kind: "invalid" };
230830
+ if (!isRecord$17(value)) return { kind: "invalid" };
230824
230831
  const text = boundedTrimmedString(value["text"], MAX_MEMORY_TEXT_CHARS);
230825
230832
  const confidence = value["confidence"];
230826
230833
  if (text === void 0 || typeof confidence !== "string" || !CONFIDENCE_VALUES.has(confidence)) return { kind: "invalid" };
@@ -230831,7 +230838,7 @@ function parsePersonalMemoryRecall(output) {
230831
230838
  }
230832
230839
  const threads = [];
230833
230840
  for (const value of threadsRaw) {
230834
- if (!isRecord$16(value)) return { kind: "invalid" };
230841
+ if (!isRecord$17(value)) return { kind: "invalid" };
230835
230842
  const title = boundedTrimmedString(value["title"], MAX_THREAD_TITLE_CHARS);
230836
230843
  const summary = boundedTrimmedString(value["summary"], MAX_THREAD_SUMMARY_CHARS);
230837
230844
  if (title === void 0 || summary === void 0) return { kind: "invalid" };
@@ -230885,7 +230892,7 @@ function boundedTrimmedString(value, maxChars) {
230885
230892
  const trimmed = value.trim();
230886
230893
  return trimmed.length > 0 ? trimmed : void 0;
230887
230894
  }
230888
- function isRecord$16(value) {
230895
+ function isRecord$17(value) {
230889
230896
  return typeof value === "object" && value !== null && !Array.isArray(value);
230890
230897
  }
230891
230898
  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;
@@ -232048,7 +232055,7 @@ var init_mission_contract_bridge = __esmMin((() => {
232048
232055
  //#endregion
232049
232056
  //#region ../../packages/agent-core/src/agent/injection/manager.ts
232050
232057
  var ACTIVE_BACKGROUND_TASK_GUIDANCE, InjectionManager;
232051
- var init_manager$1 = __esmMin((() => {
232058
+ var init_manager$2 = __esmMin((() => {
232052
232059
  init_task_list();
232053
232060
  init_action_style();
232054
232061
  init_error_memory$1();
@@ -252193,6 +252200,26 @@ var init_edit$1 = __esmMin((() => {
252193
252200
  edit_default = "Perform exact replacements in existing files.\n\n- Edit is mandatory for every incremental change, especially small edits. DO NOT use Write or Bash `sed`.\n- Read the target file before every Edit. DO NOT call Edit from memory, stale context, or a guessed `old_string`.\n- Take `old_string` and `new_string` from the Read output view.\n- Drop the line-number prefix and tab; match only file content.\n- `old_string` must be unique unless `replace_all` is set.\n- If `old_string` is ambiguous, add surrounding context. Use `replace_all` only when every occurrence should change — for example, renaming a symbol throughout the file.\n- Multiple Edit calls may run in one response only when they do not target the same file.\n- DO NOT issue consecutive Edit calls on the same file. A previous Edit can invalidate a later Edit's `old_string`, causing `old_string not found`. Read the file again before the next Edit.\n- A write lock serializes same-file edits in response order, but serialization does not make stale `old_string` valid.\n- For pure CRLF files, Read shows LF; use LF in `old_string` and `new_string`, and Edit writes CRLF back.\n- For mixed endings or lone carriage returns, Read shows carriage returns as \\r; include actual \\r escapes in those positions.\n- Source files may contain at most 500 lines. An already oversized source may only be edited when the result has fewer lines.\n- Set `single_file_override=true` only when the latest direct user message explicitly requires one single file. The accepted override is reported visibly.\n";
252194
252201
  }));
252195
252202
  //#endregion
252203
+ //#region ../../packages/agent-core/src/tools/builtin/file/lsp-diagnostics.ts
252204
+ async function appendLspDiagnostics(result, path, lsp) {
252205
+ if (lsp === void 0 || result.isError === true || typeof result.output !== "string") return result;
252206
+ try {
252207
+ const diagnostics = await lsp.diagnosticsAfterChange(path);
252208
+ if (diagnostics === void 0 || diagnostics.length === 0) return result;
252209
+ return {
252210
+ ...result,
252211
+ output: `${result.output}\nLSP diagnostics:\n${JSON.stringify(diagnostics, null, 2)}`
252212
+ };
252213
+ } catch (error) {
252214
+ const message = error instanceof Error ? error.message : String(error);
252215
+ return {
252216
+ ...result,
252217
+ output: `${result.output}\nLSP diagnostics unavailable: ${message}`
252218
+ };
252219
+ }
252220
+ }
252221
+ var init_lsp_diagnostics = __esmMin((() => {}));
252222
+ //#endregion
252196
252223
  //#region ../../packages/agent-core/src/tools/builtin/file/edit.ts
252197
252224
  function replaceOnceLiteral(content, oldString, newString) {
252198
252225
  const index = content.indexOf(oldString);
@@ -252209,6 +252236,7 @@ var init_edit = __esmMin((() => {
252209
252236
  init_line_endings();
252210
252237
  init_source_file_line_limit();
252211
252238
  init_edit$1();
252239
+ init_lsp_diagnostics();
252212
252240
  EditInputSchema = object({
252213
252241
  path: string().describe("Path to the text file to edit. Relative paths resolve against the working directory; a path outside the working directory must be absolute."),
252214
252242
  old_string: string().min(1).describe("Exact content to replace from the Read output view, without the line-number prefix. Use LF for pure CRLF files; use actual \\r escapes where Read shows \\r."),
@@ -252220,13 +252248,15 @@ var init_edit = __esmMin((() => {
252220
252248
  kaos;
252221
252249
  workspace;
252222
252250
  history;
252251
+ lsp;
252223
252252
  name = "Edit";
252224
252253
  description = edit_default;
252225
252254
  parameters = toInputJsonSchema(EditInputSchema);
252226
- constructor(kaos, workspace, history) {
252255
+ constructor(kaos, workspace, history, lsp) {
252227
252256
  this.kaos = kaos;
252228
252257
  this.workspace = workspace;
252229
252258
  this.history = history;
252259
+ this.lsp = lsp;
252230
252260
  }
252231
252261
  resolveExecution(args) {
252232
252262
  const path = resolvePathAccessPath(args.path, {
@@ -252317,7 +252347,7 @@ var init_edit = __esmMin((() => {
252317
252347
  await this.kaos.writeText(safePath, materialized);
252318
252348
  const occurrence = replacementCount === 1 ? "occurrence" : "occurrences";
252319
252349
  const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
252320
- return { output: `Replaced ${String(replacementCount)} ${occurrence} in ${args.path}.` + notice };
252350
+ return appendLspDiagnostics({ output: `Replaced ${String(replacementCount)} ${occurrence} in ${args.path}.` + notice }, safePath, this.lsp);
252321
252351
  }
252322
252352
  };
252323
252353
  }));
@@ -252333,7 +252363,7 @@ function Yn(s, t) {
252333
252363
  function Kn(s, t) {
252334
252364
  s.head = new ue$1(t, void 0, s.head, s), s.tail || (s.tail = s.head), s.length++;
252335
252365
  }
252336
- var zr, Ur, Ds, Wr, Gr, Zr, Q$1, J$1, nt$1, De$1, qt, Ne$1, Ns, Ae$1, As, z$1, Mt, g$1, Qt, Bt, b$1, N$1, _$1, bi, Ie$1, L$1, S, _i, Oi, Is, Ti, Z$1, xi, Ce$1, Jt$1, Rt, C, jt, Yr, Kr, Vr, $r, Fe$1, Li, Xr, qr, A$1, Jr, ht, H$1, te, m$1, Ni, tt$1, Ai, ki, vi, ie$1, ke$1, Ut$1, Ht, Ii, Pt, at, U$1, ot, Y$1, zt, Ci, j$1, ee$1, Fi, ve$1, gt$2, Me, bt, _t, Be$1, et$1, Wt$1, jr, Fs, ks, vs, Ms, Bs, tn, se$1, K$1, sn, M$1, rn, zs, nn, Bi, Tt, Gt, Pi, re, Pe$1, ze$1, Ue, He$1, We$1, Ge$1, Ze$1, Ye$1, Ke$1, Us, hn, an, Hs, ln, cn, Ws, Gs, Hi, ne, dn, Ui, oe$1, Ve$1, un, F$1, mn, xt, Wi, pn, lt, En, wn, Sn, ct, yn, Rn, gn, Gi, bn, Lt, ft, On, Tn, xn, f, $e$1, Dt, Nn, Xi, qi, An, B$1, Nt, it, Zi, Zs, V$1, he$1, dt, Ys, p, st$1, ut, Yi, At, w$1, Xe$1, qe$1, Ki, Ks, Vs, ae$1, Vi, Qe$1, Yt$1, $$1, Je$1, It, je$1, ti, $s, In, le$1, $i, Xs, Cn, rt$1, mt, vn, Qi, Mn, Bn, Ct, Ji, zn, qs, ce$1, ei, ji, Un, Hn, ts, Qs, rr, Wn, tr, er, ir, is$2, sr, fe$1, ii, ss, si, rs, ns, os$6, hs, pt, ri, as, es, q$1, de$1, ni, oi, Gn, hi, ue$1, pi, nr, li, me$1, W$1, pe$2, Et, Ft$1, Ee$1, ai, G, ls, ci, or, ds, us, fi, di, hr, cs, ui, lr, fs$11, wt, kt, Vn, $n, fr, dr, Xn, qn, Er, wr, ur, Sr, yr, Rr, jn, to, eo, mr, ms, ps, Ei, io, Es, so, ws, Se$1, St, no, gr, Ss, br, oo, _r, ys, Or, Vt$1, Tr, ao, lo, yi, Lr, Dr, _s, Nr, Os, P$1, Ts, xs, gi, Ar, Ir, Re, Cr, Fr, Rs, yt, O$1, Ri, kr, $t, gs, bs, Ls, ge$1, be, _e$1, Oe$1, Te$1, uo, mo, po, vr, Xt$1, ye$1, xe$1, Eo, wo, So, yo, Ro, go, bo, _o, vt, To;
252366
+ var zr, Ur, Ds, Wr, Gr, Zr, Q$1, J$1, nt$1, De$1, qt, Ne$1, Ns, Ae$1, As, z$1, Mt, g$1, Qt, Bt, b$1, N$1, _$1, bi, Ie$1, L$1, S, _i, Oi, Is, Ti, Z$1, xi, Ce$1, Jt$1, Rt, C, jt, Yr, Kr, Vr, $r, Fe$1, Li, Xr, qr, A$1, Jr, ht, H$1, te, m$1, Ni, tt$1, Ai, ki, vi, ie$1, ke$1, Ut$1, Ht, Ii, Pt, at, U$1, ot, Y$1, zt, Ci, j$1, ee$1, Fi, ve$1, gt$2, Me, bt, _t, Be$1, et$1, Wt$1, jr, Fs, ks, vs, Ms, Bs, tn, se$1, K$1, sn, M$1, rn, zs, nn, Bi, Tt, Gt, Pi, re, Pe$1, ze$1, Ue, He$1, We$1, Ge$1, Ze$1, Ye$1, Ke$1, Us, hn, an, Hs, ln, cn, Ws, Gs, Hi, ne, dn, Ui, oe$1, Ve$1, un, F$1, mn, xt, Wi, pn, lt, En, wn, Sn, ct, yn, Rn, gn, Gi, bn, Lt, ft, On, Tn, xn, f, $e$1, Dt, Nn, Xi, qi, An, B$1, Nt, it, Zi, Zs, V$1, he$1, dt, Ys, p, st$1, ut, Yi, At, w$1, Xe$1, qe$1, Ki, Ks, Vs, ae$1, Vi, Qe$1, Yt$1, $$1, Je$1, It, je$1, ti, $s, In, le$1, $i, Xs, Cn, rt$1, mt, vn, Qi, Mn, Bn, Ct, Ji, zn, qs, ce$1, ei, ji, Un, Hn, ts, Qs, rr, Wn, tr, er, ir, is$2, sr, fe$1, ii, ss, si, rs, ns, os$6, hs, pt, ri, as, es, q$1, de$1, ni, oi, Gn, hi, ue$1, pi, nr, li, me$1, W$1, pe$2, Et, Ft$1, Ee$1, ai, G, ls, ci, or, ds, us, fi, di, hr, cs, ui, lr, fs$12, wt, kt, Vn, $n, fr, dr, Xn, qn, Er, wr, ur, Sr, yr, Rr, jn, to, eo, mr, ms, ps, Ei, io, Es, so, ws, Se$1, St, no, gr, Ss, br, oo, _r, ys, Or, Vt$1, Tr, ao, lo, yi, Lr, Dr, _s, Nr, Os, P$1, Ts, xs, gi, Ar, Ir, Re, Cr, Fr, Rs, yt, O$1, Ri, kr, $t, gs, bs, Ls, ge$1, be, _e$1, Oe$1, Te$1, uo, mo, po, vr, Xt$1, ye$1, xe$1, Eo, wo, So, yo, Ro, go, bo, _o, vt, To;
252337
252367
  var init_index_min = __esmMin((() => {
252338
252368
  zr = Object.defineProperty;
252339
252369
  Ur = (s, t) => {
@@ -254303,7 +254333,7 @@ while (this[Zs](this[st$1].shift()));
254303
254333
  constructor(t, e) {
254304
254334
  this.path = t || "./", this.absolute = e;
254305
254335
  }
254306
- }, nr = Buffer.alloc(1024), li = Symbol("onStat"), me$1 = Symbol("ended"), W$1 = Symbol("queue"), pe$2 = Symbol("pendingLinks"), Et = Symbol("current"), Ft$1 = Symbol("process"), Ee$1 = Symbol("processing"), ai = Symbol("processJob"), G = Symbol("jobs"), ls = Symbol("jobDone"), ci = Symbol("addFSEntry"), or = Symbol("addTarEntry"), ds = Symbol("stat"), us = Symbol("readdir"), fi = Symbol("onreaddir"), di = Symbol("pipe"), hr = Symbol("entry"), cs = Symbol("entryOpt"), ui = Symbol("writeEntryClass"), lr = Symbol("write"), fs$11 = Symbol("ondrain"), wt = class extends A$1 {
254336
+ }, nr = Buffer.alloc(1024), li = Symbol("onStat"), me$1 = Symbol("ended"), W$1 = Symbol("queue"), pe$2 = Symbol("pendingLinks"), Et = Symbol("current"), Ft$1 = Symbol("process"), Ee$1 = Symbol("processing"), ai = Symbol("processJob"), G = Symbol("jobs"), ls = Symbol("jobDone"), ci = Symbol("addFSEntry"), or = Symbol("addTarEntry"), ds = Symbol("stat"), us = Symbol("readdir"), fi = Symbol("onreaddir"), di = Symbol("pipe"), hr = Symbol("entry"), cs = Symbol("entryOpt"), ui = Symbol("writeEntryClass"), lr = Symbol("write"), fs$12 = Symbol("ondrain"), wt = class extends A$1 {
254307
254337
  sync = !1;
254308
254338
  opt;
254309
254339
  cwd;
@@ -254336,8 +254366,8 @@ while (this[Zs](this[st$1].shift()));
254336
254366
  if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
254337
254367
  if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = !0), this.zip = new ze$1(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new We$1(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ye$1(t.zstd)), !this.zip) throw new Error("impossible");
254338
254368
  let e = this.zip;
254339
- e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$11]()), this.on("resume", () => e.resume());
254340
- } else this.on("drain", this[fs$11]);
254369
+ e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$12]()), this.on("resume", () => e.resume());
254370
+ } else this.on("drain", this[fs$12]);
254341
254371
  this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => !0, this[W$1] = new hi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[Ee$1] = !1, this[me$1] = !1;
254342
254372
  }
254343
254373
  [lr](t) {
@@ -254464,7 +254494,7 @@ while (this[Zs](this[st$1].shift()));
254464
254494
  this.emit("error", e);
254465
254495
  }
254466
254496
  }
254467
- [fs$11]() {
254497
+ [fs$12]() {
254468
254498
  this[Et] && this[Et].entry && this[Et].entry.resume();
254469
254499
  }
254470
254500
  [di](t) {
@@ -254630,7 +254660,7 @@ while (this[Zs](this[st$1].shift()));
254630
254660
  E ? e(E) : x && a ? Es(x, o, h, (Le) => y(Le)) : n ? Kt.chmod(s, r, e) : e();
254631
254661
  };
254632
254662
  if (s === d) return no(s, y);
254633
- if (l) return ro.mkdir(s, {
254663
+ if (l) return fs.mkdir(s, {
254634
254664
  mode: r,
254635
254665
  recursive: !0
254636
254666
  }).then((E) => y(null, E ?? void 0), y);
@@ -255389,7 +255419,7 @@ var require_pend = /* @__PURE__ */ __commonJSMin(((exports, module) => {
255389
255419
  //#endregion
255390
255420
  //#region ../../node_modules/.pnpm/yauzl@3.3.0/node_modules/yauzl/fd-slicer.js
255391
255421
  var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255392
- var fs$10 = __require("fs");
255422
+ var fs$11 = __require("fs");
255393
255423
  var util$6 = __require("util");
255394
255424
  var stream$2 = __require("stream");
255395
255425
  var Readable = stream$2.Readable;
@@ -255414,7 +255444,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255414
255444
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
255415
255445
  var self = this;
255416
255446
  self.pend.go(function(cb) {
255417
- fs$10.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
255447
+ fs$11.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
255418
255448
  cb();
255419
255449
  callback(err, bytesRead, buffer);
255420
255450
  });
@@ -255423,7 +255453,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255423
255453
  FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
255424
255454
  var self = this;
255425
255455
  self.pend.go(function(cb) {
255426
- fs$10.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
255456
+ fs$11.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
255427
255457
  cb();
255428
255458
  callback(err, written, buffer);
255429
255459
  });
@@ -255443,7 +255473,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255443
255473
  self.refCount -= 1;
255444
255474
  if (self.refCount > 0) return;
255445
255475
  if (self.refCount < 0) throw new Error("invalid unref");
255446
- if (self.autoClose) fs$10.close(self.fd, onCloseDone);
255476
+ if (self.autoClose) fs$11.close(self.fd, onCloseDone);
255447
255477
  function onCloseDone(err) {
255448
255478
  if (err) self.emit("error", err);
255449
255479
  else self.emit("close");
@@ -255474,7 +255504,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255474
255504
  self.context.pend.go(function(cb) {
255475
255505
  if (self.destroyed) return cb();
255476
255506
  var buffer = Buffer.allocUnsafe(toRead);
255477
- fs$10.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
255507
+ fs$11.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
255478
255508
  if (err) self.destroy(err);
255479
255509
  else if (bytesRead === 0) {
255480
255510
  self.destroyed = true;
@@ -255520,7 +255550,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
255520
255550
  }
255521
255551
  self.context.pend.go(function(cb) {
255522
255552
  if (self.destroyed) return cb();
255523
- fs$10.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
255553
+ fs$11.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
255524
255554
  if (err) {
255525
255555
  self.destroy();
255526
255556
  cb();
@@ -258404,6 +258434,7 @@ var init_write = __esmMin((() => {
258404
258434
  init_rule_match();
258405
258435
  init_source_file_line_limit();
258406
258436
  init_write$1();
258437
+ init_lsp_diagnostics();
258407
258438
  S_IFMT = 61440;
258408
258439
  S_IFDIR = 16384;
258409
258440
  WriteInputSchema = object({
@@ -258419,13 +258450,15 @@ bytesWritten: number$1().int().nonnegative() });
258419
258450
  kaos;
258420
258451
  workspace;
258421
258452
  history;
258453
+ lsp;
258422
258454
  name = "Write";
258423
258455
  description = write_default;
258424
258456
  parameters = toInputJsonSchema(WriteInputSchema);
258425
- constructor(kaos, workspace, history) {
258457
+ constructor(kaos, workspace, history, lsp) {
258426
258458
  this.kaos = kaos;
258427
258459
  this.workspace = workspace;
258428
258460
  this.history = history;
258461
+ this.lsp = lsp;
258429
258462
  }
258430
258463
  resolveExecution(args) {
258431
258464
  const path = resolvePathAccessPath(args.path, {
@@ -258482,7 +258515,7 @@ bytesWritten: number$1().int().nonnegative() });
258482
258515
  else await this.kaos.writeText(safePath, args.content);
258483
258516
  const bytesWritten = Buffer.byteLength(args.content, "utf8");
258484
258517
  const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
258485
- return { output: `${mode === "append" ? "Appended" : "Wrote"} ${String(bytesWritten)} bytes to ${args.path}.${notice}` };
258518
+ return appendLspDiagnostics({ output: `${mode === "append" ? "Appended" : "Wrote"} ${String(bytesWritten)} bytes to ${args.path}.${notice}` }, safePath, this.lsp);
258486
258519
  } catch (error) {
258487
258520
  if (error?.code === "ENOENT") return {
258488
258521
  isError: true,
@@ -261010,6 +261043,83 @@ var init_codebase_search = __esmMin((() => {
261010
261043
  };
261011
261044
  }));
261012
261045
  //#endregion
261046
+ //#region ../../packages/agent-core/src/tools/builtin/search/lsp.md?raw
261047
+ var lsp_default;
261048
+ var init_lsp$2 = __esmMin((() => {
261049
+ lsp_default = "Query a configured Language Server Protocol (LSP) server for precise code intelligence.\n\nUse this tool for definitions, references, hover/type information, document or workspace symbols, implementations, and current diagnostics. Line and character positions are one-based. Use `workspace_symbols` with `query`; all other operations require `path`. Position-based operations also require `line` and `character`.\n\nLanguage servers are provided by enabled plugins and start only when first used. If the required server executable is missing, report that exact setup error instead of falling back to a guess.\n";
261050
+ }));
261051
+ //#endregion
261052
+ //#region ../../packages/agent-core/src/tools/builtin/search/lsp.ts
261053
+ var LspInputSchema, LspTool;
261054
+ var init_lsp$1 = __esmMin((() => {
261055
+ init_zod$1();
261056
+ init_tool_access();
261057
+ init_path_access();
261058
+ init_input_schema();
261059
+ init_rule_match();
261060
+ init_lsp$2();
261061
+ LspInputSchema = object({
261062
+ operation: _enum([
261063
+ "definition",
261064
+ "references",
261065
+ "hover",
261066
+ "document_symbols",
261067
+ "workspace_symbols",
261068
+ "implementation",
261069
+ "diagnostics"
261070
+ ]),
261071
+ path: string().optional().describe("Source file path, relative to the working directory or absolute."),
261072
+ line: number$1().int().positive().optional().describe("One-based source line."),
261073
+ character: number$1().int().positive().optional().describe("One-based character offset."),
261074
+ query: string().optional().describe("Symbol query for workspace_symbols.")
261075
+ });
261076
+ LspTool = class {
261077
+ service;
261078
+ kaos;
261079
+ workspace;
261080
+ name = "LSP";
261081
+ description = lsp_default;
261082
+ parameters = toInputJsonSchema(LspInputSchema);
261083
+ constructor(service, kaos, workspace) {
261084
+ this.service = service;
261085
+ this.kaos = kaos;
261086
+ this.workspace = workspace;
261087
+ }
261088
+ resolveExecution(args) {
261089
+ const safePath = args.path === void 0 || this.kaos === void 0 || this.workspace === void 0 ? args.path : resolvePathAccessPath(args.path, {
261090
+ kaos: this.kaos,
261091
+ workspace: this.workspace,
261092
+ operation: "read"
261093
+ });
261094
+ return {
261095
+ description: `LSP ${args.operation}${args.path === void 0 ? "" : `: ${args.path}`}`,
261096
+ accesses: safePath === void 0 ? ToolAccesses.searchTree(this.workspace?.workspaceDir ?? ".") : ToolAccesses.readFile(safePath),
261097
+ approvalRule: literalRulePattern(this.name, args.operation),
261098
+ matchesRule: safePath === void 0 || this.kaos === void 0 || this.workspace === void 0 ? void 0 : (ruleArgs) => matchesPathRuleSubject(ruleArgs, safePath, {
261099
+ cwd: this.workspace.workspaceDir,
261100
+ pathClass: this.kaos.pathClass(),
261101
+ homeDir: this.kaos.gethome()
261102
+ }),
261103
+ execute: () => this.execute({
261104
+ ...args,
261105
+ path: safePath
261106
+ })
261107
+ };
261108
+ }
261109
+ async execute(args) {
261110
+ try {
261111
+ const result = await this.service.request(args);
261112
+ return { output: JSON.stringify(result ?? null, null, 2) };
261113
+ } catch (error) {
261114
+ return {
261115
+ isError: true,
261116
+ output: error instanceof Error ? error.message : String(error)
261117
+ };
261118
+ }
261119
+ }
261120
+ };
261121
+ }));
261122
+ //#endregion
261013
261123
  //#region ../../packages/agent-core/src/tools/builtin/mistake-record.md?raw
261014
261124
  var mistake_record_default;
261015
261125
  var init_mistake_record$1 = __esmMin((() => {
@@ -261384,6 +261494,7 @@ var init_builtin = __esmMin((() => {
261384
261494
  init_fetch_url();
261385
261495
  init_web_search();
261386
261496
  init_codebase_search();
261497
+ init_lsp$1();
261387
261498
  init_mistake_record();
261388
261499
  init_blun_media$1();
261389
261500
  }));
@@ -261782,8 +261893,8 @@ var init_tool$1 = __esmMin((() => {
261782
261893
  const goalToolsEnabled = this.agent.type === "main";
261783
261894
  this.builtinTools = new Map([
261784
261895
  new ReadTool(kaos, workspace),
261785
- new WriteTool(kaos, workspace, () => this.agent.context.history),
261786
- new EditTool(kaos, workspace, () => this.agent.context.history),
261896
+ new WriteTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
261897
+ new EditTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
261787
261898
  new GrepTool(kaos, workspace, this.agent.telemetry),
261788
261899
  new GlobTool(kaos, workspace, this.agent.telemetry),
261789
261900
  new BashTool(kaos, cwd, background, { allowBackground }),
@@ -261819,7 +261930,8 @@ var init_tool$1 = __esmMin((() => {
261819
261930
  toolServices?.media && new LipSyncMediaTool(toolServices.media),
261820
261931
  toolServices?.media && new GetMediaTool(toolServices.media),
261821
261932
  new MistakeRecordTool(this.agent),
261822
- new CodebaseSearchTool(cwd)
261933
+ new CodebaseSearchTool(cwd),
261934
+ toolServices?.lsp && new LspTool(toolServices.lsp, kaos, workspace)
261823
261935
  ].filter((tool) => !!tool).map((tool) => [tool.name, tool]));
261824
261936
  }
261825
261937
  refreshBuiltinTools() {
@@ -262213,7 +262325,7 @@ var init_agent = __esmMin((() => {
262213
262325
  init_error_memory();
262214
262326
  init_goal$1();
262215
262327
  init_hooks();
262216
- init_manager$1();
262328
+ init_manager$2();
262217
262329
  init_permission();
262218
262330
  init_plan();
262219
262331
  init_records();
@@ -263948,7 +264060,7 @@ var init_ajv_provider = __esmMin((() => {
263948
264060
  //#endregion
263949
264061
  //#region ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js
263950
264062
  var ExperimentalClientTasks;
263951
- var init_client$2 = __esmMin((() => {
264063
+ var init_client$3 = __esmMin((() => {
263952
264064
  init_types$4();
263953
264065
  ExperimentalClientTasks = class {
263954
264066
  constructor(_client) {
@@ -264206,12 +264318,12 @@ function getSupportedElicitationModes(capabilities) {
264206
264318
  };
264207
264319
  }
264208
264320
  var Client;
264209
- var init_client$1 = __esmMin((() => {
264321
+ var init_client$2 = __esmMin((() => {
264210
264322
  init_protocol();
264211
264323
  init_types$4();
264212
264324
  init_ajv_provider();
264213
264325
  init_zod_compat();
264214
- init_client$2();
264326
+ init_client$3();
264215
264327
  init_helpers$1();
264216
264328
  Client = class extends Protocol {
264217
264329
  /**
@@ -265230,7 +265342,7 @@ function buildMcpHttpHeaders(config, envLookup) {
265230
265342
  }
265231
265343
  var HttpMcpClient;
265232
265344
  var init_client_http = __esmMin((() => {
265233
- init_client$1();
265345
+ init_client$2();
265234
265346
  init_streamableHttp();
265235
265347
  init_client_shared();
265236
265348
  init_client_remote();
@@ -265752,7 +265864,7 @@ function isTerminalSseTransportError(error) {
265752
265864
  }
265753
265865
  var SseMcpClient;
265754
265866
  var init_client_sse = __esmMin((() => {
265755
- init_client$1();
265867
+ init_client$2();
265756
265868
  init_sse();
265757
265869
  init_client_shared();
265758
265870
  init_client_remote();
@@ -292370,7 +292482,7 @@ var init_proxy = __esmMin((() => {
292370
292482
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
292371
292483
  module.exports = isexe;
292372
292484
  isexe.sync = sync;
292373
- var fs$8 = __require("fs");
292485
+ var fs$9 = __require("fs");
292374
292486
  function checkPathExt(path, options) {
292375
292487
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
292376
292488
  if (!pathext) return true;
@@ -292387,12 +292499,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
292387
292499
  return checkPathExt(path, options);
292388
292500
  }
292389
292501
  function isexe(path, options, cb) {
292390
- fs$8.stat(path, function(er, stat) {
292502
+ fs$9.stat(path, function(er, stat) {
292391
292503
  cb(er, er ? false : checkStat(stat, path, options));
292392
292504
  });
292393
292505
  }
292394
292506
  function sync(path, options) {
292395
- return checkStat(fs$8.statSync(path), path, options);
292507
+ return checkStat(fs$9.statSync(path), path, options);
292396
292508
  }
292397
292509
  }));
292398
292510
  //#endregion
@@ -292400,14 +292512,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
292400
292512
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
292401
292513
  module.exports = isexe;
292402
292514
  isexe.sync = sync;
292403
- var fs$7 = __require("fs");
292515
+ var fs$8 = __require("fs");
292404
292516
  function isexe(path, options, cb) {
292405
- fs$7.stat(path, function(er, stat) {
292517
+ fs$8.stat(path, function(er, stat) {
292406
292518
  cb(er, er ? false : checkStat(stat, options));
292407
292519
  });
292408
292520
  }
292409
292521
  function sync(path, options) {
292410
- return checkStat(fs$7.statSync(path), options);
292522
+ return checkStat(fs$8.statSync(path), options);
292411
292523
  }
292412
292524
  function checkStat(stat, options) {
292413
292525
  return stat.isFile() && checkMode(stat, options);
@@ -292622,16 +292734,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
292622
292734
  //#endregion
292623
292735
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
292624
292736
  var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
292625
- const fs$6 = __require("fs");
292737
+ const fs$7 = __require("fs");
292626
292738
  const shebangCommand = require_shebang_command();
292627
292739
  function readShebang(command) {
292628
292740
  const size = 150;
292629
292741
  const buffer = Buffer.alloc(size);
292630
292742
  let fd;
292631
292743
  try {
292632
- fd = fs$6.openSync(command, "r");
292633
- fs$6.readSync(fd, buffer, 0, size, 0);
292634
- fs$6.closeSync(fd);
292744
+ fd = fs$7.openSync(command, "r");
292745
+ fs$7.readSync(fd, buffer, 0, size, 0);
292746
+ fs$7.closeSync(fd);
292635
292747
  } catch (e) {}
292636
292748
  return shebangCommand(buffer.toString());
292637
292749
  }
@@ -292962,7 +293074,7 @@ var STDERR_BUFFER_CAPACITY, StdioMcpClient, BoundedTail;
292962
293074
  var init_client_stdio = __esmMin((() => {
292963
293075
  init_errors$8();
292964
293076
  init_proxy();
292965
- init_client$1();
293077
+ init_client$2();
292966
293078
  init_stdio();
292967
293079
  init_dist$6();
292968
293080
  init_client_shared();
@@ -293228,7 +293340,7 @@ async function withTimeout(promise, timeoutMs, onTimeout) {
293228
293340
  if (timer !== void 0) clearTimeout(timer);
293229
293341
  }
293230
293342
  }
293231
- var DEFAULT_STARTUP_TIMEOUT_MS, McpConnectionManager;
293343
+ var DEFAULT_STARTUP_TIMEOUT_MS$1, McpConnectionManager;
293232
293344
  var init_connection_manager = __esmMin((() => {
293233
293345
  init_errors$8();
293234
293346
  init_logger$1();
@@ -293239,7 +293351,7 @@ var init_connection_manager = __esmMin((() => {
293239
293351
  init_client_stdio();
293240
293352
  init_public_display();
293241
293353
  init_types$1();
293242
- DEFAULT_STARTUP_TIMEOUT_MS = 3e4;
293354
+ DEFAULT_STARTUP_TIMEOUT_MS$1 = 3e4;
293243
293355
  McpConnectionManager = class {
293244
293356
  options;
293245
293357
  entries = /* @__PURE__ */ new Map();
@@ -293396,7 +293508,7 @@ var init_connection_manager = __esmMin((() => {
293396
293508
  await Promise.allSettled(tasks);
293397
293509
  }
293398
293510
  async connectOne(entry, attemptId) {
293399
- const timeoutMs = entry.config.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
293511
+ const timeoutMs = entry.config.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS$1;
293400
293512
  let client;
293401
293513
  try {
293402
293514
  const startupClient = this.createClient(entry.config, entry.name);
@@ -293738,6 +293850,446 @@ var init_legacy_memory = __esmMin((() => {
293738
293850
  LEGACY_LOCAL_MEMORY_SAVE = "When the user tells you something worth remembering (preferences, facts about them, project context, corrections), SAVE it:";
293739
293851
  }));
293740
293852
  //#endregion
293853
+ //#region ../../packages/agent-core/src/lsp/client.ts
293854
+ async function waitForExit$1(child, timeoutMs) {
293855
+ if (child.exitCode !== null) return;
293856
+ await Promise.race([new Promise((resolve) => {
293857
+ child.once("exit", () => resolve());
293858
+ }), delay(timeoutMs)]);
293859
+ }
293860
+ function delay(timeoutMs) {
293861
+ return new Promise((resolve) => {
293862
+ setTimeout(resolve, timeoutMs).unref?.();
293863
+ });
293864
+ }
293865
+ var DEFAULT_STARTUP_TIMEOUT_MS, DEFAULT_SHUTDOWN_TIMEOUT_MS, REQUEST_TIMEOUT_MS, StdioLspClient;
293866
+ var init_client$1 = __esmMin((() => {
293867
+ DEFAULT_STARTUP_TIMEOUT_MS = 1e4;
293868
+ DEFAULT_SHUTDOWN_TIMEOUT_MS = 2e3;
293869
+ REQUEST_TIMEOUT_MS = 3e4;
293870
+ StdioLspClient = class {
293871
+ name;
293872
+ config;
293873
+ cwd;
293874
+ process;
293875
+ startPromise;
293876
+ stdout = Buffer.alloc(0);
293877
+ nextId = 1;
293878
+ stopped = false;
293879
+ _generation = 0;
293880
+ pending = /* @__PURE__ */ new Map();
293881
+ diagnosticsByUri = /* @__PURE__ */ new Map();
293882
+ diagnosticsWaiters = /* @__PURE__ */ new Map();
293883
+ constructor(name, config, cwd) {
293884
+ this.name = name;
293885
+ this.config = config;
293886
+ this.cwd = cwd;
293887
+ }
293888
+ get running() {
293889
+ return this.process !== void 0 && this.process.exitCode === null && !this.stopped;
293890
+ }
293891
+ get generation() {
293892
+ return this._generation;
293893
+ }
293894
+ async start() {
293895
+ if (this.running) return;
293896
+ if (this.startPromise !== void 0) return this.startPromise;
293897
+ this.startPromise = this.startInternal().catch((error) => {
293898
+ this.startPromise = void 0;
293899
+ throw error;
293900
+ });
293901
+ return this.startPromise;
293902
+ }
293903
+ async request(method, params) {
293904
+ await this.start();
293905
+ return this.sendRequest(method, params, REQUEST_TIMEOUT_MS);
293906
+ }
293907
+ notify(method, params) {
293908
+ if (!this.running) throw new Error(`LSP server "${this.name}" is not running`);
293909
+ this.write({
293910
+ jsonrpc: "2.0",
293911
+ method,
293912
+ params
293913
+ });
293914
+ }
293915
+ diagnostics(uri) {
293916
+ return this.diagnosticsByUri.get(uri);
293917
+ }
293918
+ clearDiagnostics(uri) {
293919
+ this.diagnosticsByUri.delete(uri);
293920
+ }
293921
+ async waitForDiagnostics(uri, timeoutMs = 300) {
293922
+ const current = this.diagnosticsByUri.get(uri);
293923
+ if (current !== void 0) return current;
293924
+ let notify;
293925
+ const notification = new Promise((resolve) => {
293926
+ notify = resolve;
293927
+ const waiters = this.diagnosticsWaiters.get(uri) ?? [];
293928
+ waiters.push(resolve);
293929
+ this.diagnosticsWaiters.set(uri, waiters);
293930
+ });
293931
+ await Promise.race([notification, delay(timeoutMs)]);
293932
+ const waiters = this.diagnosticsWaiters.get(uri);
293933
+ if (waiters !== void 0) {
293934
+ const remaining = waiters.filter((waiter) => waiter !== notify);
293935
+ if (remaining.length === 0) this.diagnosticsWaiters.delete(uri);
293936
+ else this.diagnosticsWaiters.set(uri, remaining);
293937
+ }
293938
+ return this.diagnosticsByUri.get(uri) ?? [];
293939
+ }
293940
+ async shutdown() {
293941
+ this.stopped = true;
293942
+ const child = this.process;
293943
+ if (child === void 0 || child.exitCode !== null) return;
293944
+ try {
293945
+ await this.sendRequest("shutdown", null, this.config.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS);
293946
+ this.write({
293947
+ jsonrpc: "2.0",
293948
+ method: "exit",
293949
+ params: null
293950
+ });
293951
+ } catch {}
293952
+ await waitForExit$1(child, this.config.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS);
293953
+ if (child.exitCode === null) child.kill();
293954
+ this.process = void 0;
293955
+ this.startPromise = void 0;
293956
+ }
293957
+ async startInternal() {
293958
+ this.stopped = false;
293959
+ const child = spawn(this.config.command, [...this.config.args ?? []], {
293960
+ cwd: this.config.workspaceFolder ?? this.cwd,
293961
+ env: {
293962
+ ...process.env,
293963
+ ...this.config.env
293964
+ },
293965
+ stdio: [
293966
+ "pipe",
293967
+ "pipe",
293968
+ "pipe"
293969
+ ],
293970
+ windowsHide: true
293971
+ });
293972
+ this.process = child;
293973
+ child.stdout.on("data", (chunk) => this.onStdout(chunk));
293974
+ child.stderr.on("data", () => {});
293975
+ child.once("error", (error) => this.failProcess(error));
293976
+ child.once("exit", (code, signal) => {
293977
+ if (!this.stopped) this.failProcess(/* @__PURE__ */ new Error(`LSP server "${this.name}" exited unexpectedly (${code === null ? signal : String(code)})`));
293978
+ });
293979
+ const rootPath = this.config.workspaceFolder ?? this.cwd;
293980
+ const rootUri = pathToFileURL(rootPath).href;
293981
+ try {
293982
+ await this.sendRequest("initialize", {
293983
+ processId: process.pid,
293984
+ clientInfo: {
293985
+ name: "BLUN Code",
293986
+ version: "1"
293987
+ },
293988
+ rootPath,
293989
+ rootUri,
293990
+ workspaceFolders: [{
293991
+ uri: rootUri,
293992
+ name: this.name
293993
+ }],
293994
+ capabilities: {
293995
+ textDocument: {
293996
+ hover: { contentFormat: ["markdown", "plaintext"] },
293997
+ definition: { linkSupport: true },
293998
+ implementation: { linkSupport: true },
293999
+ publishDiagnostics: { relatedInformation: true }
294000
+ },
294001
+ workspace: { symbol: { resolveSupport: { properties: ["location.range"] } } }
294002
+ },
294003
+ initializationOptions: this.config.initializationOptions
294004
+ }, this.config.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS);
294005
+ this.notify("initialized", {});
294006
+ this._generation++;
294007
+ if (this.config.settings !== void 0) this.notify("workspace/didChangeConfiguration", { settings: this.config.settings });
294008
+ } catch (error) {
294009
+ if (child.exitCode === null) child.kill();
294010
+ const message = error instanceof Error ? error.message : String(error);
294011
+ throw new Error(`Failed to start LSP server "${this.name}" (${this.config.command}): ${message}`, { cause: error });
294012
+ }
294013
+ }
294014
+ sendRequest(method, params, timeoutMs) {
294015
+ const id = this.nextId++;
294016
+ return new Promise((resolve, reject) => {
294017
+ const timer = setTimeout(() => {
294018
+ this.pending.delete(id);
294019
+ reject(/* @__PURE__ */ new Error(`LSP request "${method}" timed out after ${String(timeoutMs)} ms`));
294020
+ }, timeoutMs);
294021
+ timer.unref?.();
294022
+ this.pending.set(id, {
294023
+ resolve,
294024
+ reject,
294025
+ timer
294026
+ });
294027
+ try {
294028
+ this.write({
294029
+ jsonrpc: "2.0",
294030
+ id,
294031
+ method,
294032
+ params
294033
+ });
294034
+ } catch (error) {
294035
+ clearTimeout(timer);
294036
+ this.pending.delete(id);
294037
+ reject(error instanceof Error ? error : new Error(String(error)));
294038
+ }
294039
+ });
294040
+ }
294041
+ write(message) {
294042
+ const stdin = this.process?.stdin;
294043
+ if (stdin === void 0 || stdin.destroyed) throw new Error(`LSP server "${this.name}" is not available`);
294044
+ const body = Buffer.from(JSON.stringify(message), "utf8");
294045
+ stdin.write(`Content-Length: ${String(body.length)}\r\n\r\n`);
294046
+ stdin.write(body);
294047
+ }
294048
+ onStdout(chunk) {
294049
+ this.stdout = Buffer.concat([this.stdout, chunk]);
294050
+ while (true) {
294051
+ const headerEnd = this.stdout.indexOf("\r\n\r\n");
294052
+ if (headerEnd < 0) return;
294053
+ const header = this.stdout.subarray(0, headerEnd).toString("ascii");
294054
+ const match = /(?:^|\r\n)Content-Length:\s*(\d+)/i.exec(header);
294055
+ if (match === null) {
294056
+ this.failProcess(/* @__PURE__ */ new Error(`Invalid LSP response header from "${this.name}"`));
294057
+ return;
294058
+ }
294059
+ const length = Number(match[1]);
294060
+ const bodyStart = headerEnd + 4;
294061
+ if (this.stdout.length < bodyStart + length) return;
294062
+ const body = this.stdout.subarray(bodyStart, bodyStart + length).toString("utf8");
294063
+ this.stdout = this.stdout.subarray(bodyStart + length);
294064
+ try {
294065
+ this.handleMessage(JSON.parse(body));
294066
+ } catch (error) {
294067
+ this.failProcess(error instanceof Error ? error : new Error(String(error)));
294068
+ return;
294069
+ }
294070
+ }
294071
+ }
294072
+ handleMessage(message) {
294073
+ if (message.id !== void 0 && message.method !== void 0) {
294074
+ this.handleServerRequest(message.id, message.method, message.params);
294075
+ return;
294076
+ }
294077
+ if (message.id !== void 0) {
294078
+ const pending = this.pending.get(message.id);
294079
+ if (pending === void 0) return;
294080
+ clearTimeout(pending.timer);
294081
+ this.pending.delete(message.id);
294082
+ if (message.error !== void 0) pending.reject(/* @__PURE__ */ new Error(`LSP request failed${message.error.code === void 0 ? "" : ` (${String(message.error.code)})`}: ${message.error.message ?? "unknown error"}`));
294083
+ else pending.resolve(message.result);
294084
+ return;
294085
+ }
294086
+ if (message.method !== "textDocument/publishDiagnostics") return;
294087
+ const params = message.params;
294088
+ if (typeof params?.uri !== "string" || !Array.isArray(params.diagnostics)) return;
294089
+ this.diagnosticsByUri.set(params.uri, params.diagnostics);
294090
+ const waiters = this.diagnosticsWaiters.get(params.uri) ?? [];
294091
+ this.diagnosticsWaiters.delete(params.uri);
294092
+ for (const resolve of waiters) resolve();
294093
+ }
294094
+ handleServerRequest(id, method, params) {
294095
+ if (method === "workspace/configuration") {
294096
+ const items = params?.items;
294097
+ const count = Array.isArray(items) ? items.length : 0;
294098
+ this.write({
294099
+ jsonrpc: "2.0",
294100
+ id,
294101
+ result: Array.from({ length: count }, () => this.config.settings ?? null)
294102
+ });
294103
+ return;
294104
+ }
294105
+ if (method === "workspace/workspaceFolders") {
294106
+ const rootPath = this.config.workspaceFolder ?? this.cwd;
294107
+ this.write({
294108
+ jsonrpc: "2.0",
294109
+ id,
294110
+ result: [{
294111
+ uri: pathToFileURL(rootPath).href,
294112
+ name: this.name
294113
+ }]
294114
+ });
294115
+ return;
294116
+ }
294117
+ if (method === "client/registerCapability" || method === "client/unregisterCapability" || method === "window/workDoneProgress/create") {
294118
+ this.write({
294119
+ jsonrpc: "2.0",
294120
+ id,
294121
+ result: null
294122
+ });
294123
+ return;
294124
+ }
294125
+ this.write({
294126
+ jsonrpc: "2.0",
294127
+ id,
294128
+ error: {
294129
+ code: -32601,
294130
+ message: `Client method not supported: ${method}`
294131
+ }
294132
+ });
294133
+ }
294134
+ failProcess(error) {
294135
+ const wrapped = new Error(`LSP server "${this.name}" (${this.config.command}) failed: ${error.message}`, { cause: error });
294136
+ for (const pending of this.pending.values()) {
294137
+ clearTimeout(pending.timer);
294138
+ pending.reject(wrapped);
294139
+ }
294140
+ this.pending.clear();
294141
+ this.process = void 0;
294142
+ if (this.config.restartOnCrash !== false && !this.stopped) this.startPromise = void 0;
294143
+ }
294144
+ };
294145
+ }));
294146
+ //#endregion
294147
+ //#region ../../packages/agent-core/src/lsp/manager.ts
294148
+ function methodForOperation(operation) {
294149
+ switch (operation) {
294150
+ case "definition": return "textDocument/definition";
294151
+ case "references": return "textDocument/references";
294152
+ case "hover": return "textDocument/hover";
294153
+ case "document_symbols": return "textDocument/documentSymbol";
294154
+ case "implementation": return "textDocument/implementation";
294155
+ }
294156
+ }
294157
+ function oneBasedToZeroBased(value, name) {
294158
+ if (value === void 0 || !Number.isInteger(value) || value < 1) throw new Error(`LSP operation requires a one-based ${name}`);
294159
+ return value - 1;
294160
+ }
294161
+ function positionFrom(input) {
294162
+ return {
294163
+ line: oneBasedToZeroBased(input.line, "line"),
294164
+ character: oneBasedToZeroBased(input.character, "character")
294165
+ };
294166
+ }
294167
+ var LspManager;
294168
+ var init_manager$1 = __esmMin((() => {
294169
+ init_client$1();
294170
+ LspManager = class {
294171
+ options;
294172
+ clients = /* @__PURE__ */ new Map();
294173
+ openedDocuments = /* @__PURE__ */ new Map();
294174
+ constructor(options) {
294175
+ this.options = options;
294176
+ }
294177
+ serverNames() {
294178
+ return Object.keys(this.options.servers).toSorted();
294179
+ }
294180
+ runningServerNames() {
294181
+ return [...this.clients.entries()].filter(([, client]) => client.running).map(([name]) => name).toSorted();
294182
+ }
294183
+ async diagnosticsAfterChange(filePath) {
294184
+ const resolvedPath = path.resolve(this.options.cwd, filePath);
294185
+ if (!this.supportsPath(resolvedPath)) return void 0;
294186
+ const diagnostics = await this.request({
294187
+ operation: "diagnostics",
294188
+ path: resolvedPath
294189
+ });
294190
+ return Array.isArray(diagnostics) ? diagnostics : [];
294191
+ }
294192
+ async request(input) {
294193
+ if (input.operation === "workspace_symbols") {
294194
+ if (input.query === void 0) throw new Error("workspace_symbols requires query");
294195
+ const results = await Promise.allSettled(this.serverNames().map(async (name) => {
294196
+ const result = await this.client(name, this.options.servers[name]).request("workspace/symbol", { query: input.query });
294197
+ return Array.isArray(result) ? result : [];
294198
+ }));
294199
+ const fulfilled = results.filter((result) => result.status === "fulfilled");
294200
+ if (fulfilled.length === 0) throw results.find((result) => result.status === "rejected")?.reason ?? /* @__PURE__ */ new Error("No LSP servers are configured");
294201
+ return fulfilled.flatMap((result) => result.value);
294202
+ }
294203
+ const documentPath = this.requireDocumentPath(input.path);
294204
+ const { client, languageId } = this.clientForPath(documentPath);
294205
+ const uri = pathToFileURL(documentPath).href;
294206
+ await this.openOrUpdateDocument(client, uri, documentPath, languageId);
294207
+ if (input.operation === "diagnostics") return client.waitForDiagnostics(uri);
294208
+ const method = methodForOperation(input.operation);
294209
+ const params = input.operation === "document_symbols" ? { textDocument: { uri } } : input.operation === "references" ? {
294210
+ textDocument: { uri },
294211
+ position: positionFrom(input),
294212
+ context: { includeDeclaration: true }
294213
+ } : {
294214
+ textDocument: { uri },
294215
+ position: positionFrom(input)
294216
+ };
294217
+ return client.request(method, params);
294218
+ }
294219
+ async shutdown() {
294220
+ await Promise.allSettled([...this.clients.values()].map((client) => client.shutdown()));
294221
+ this.clients.clear();
294222
+ this.openedDocuments.clear();
294223
+ }
294224
+ clientForPath(filePath) {
294225
+ const extension = path.extname(filePath).toLowerCase();
294226
+ for (const [name, config] of Object.entries(this.options.servers)) {
294227
+ const languageId = config.extensionToLanguage[extension];
294228
+ if (languageId !== void 0) return {
294229
+ client: this.client(name, config),
294230
+ languageId
294231
+ };
294232
+ }
294233
+ throw new Error(`No LSP server is configured for "${extension || path.basename(filePath)}". Configured servers: ${this.serverNames().join(", ") || "none"}`);
294234
+ }
294235
+ supportsPath(filePath) {
294236
+ const extension = path.extname(filePath).toLowerCase();
294237
+ return Object.values(this.options.servers).some((config) => config.extensionToLanguage[extension] !== void 0);
294238
+ }
294239
+ client(name, config) {
294240
+ const existing = this.clients.get(name);
294241
+ if (existing !== void 0) return existing;
294242
+ const client = new StdioLspClient(name, config, this.options.cwd);
294243
+ this.clients.set(name, client);
294244
+ return client;
294245
+ }
294246
+ async openOrUpdateDocument(client, uri, filePath, languageId) {
294247
+ await client.start();
294248
+ const text = await readFile(filePath, "utf8");
294249
+ const key = `${client.name}\0${uri}`;
294250
+ const current = this.openedDocuments.get(key);
294251
+ if (current === void 0 || current.generation !== client.generation) {
294252
+ this.openedDocuments.set(key, {
294253
+ text,
294254
+ version: 1,
294255
+ generation: client.generation
294256
+ });
294257
+ client.notify("textDocument/didOpen", { textDocument: {
294258
+ uri,
294259
+ languageId,
294260
+ version: 1,
294261
+ text
294262
+ } });
294263
+ return;
294264
+ }
294265
+ if (current.text === text) return;
294266
+ const version = current.version + 1;
294267
+ this.openedDocuments.set(key, {
294268
+ text,
294269
+ version,
294270
+ generation: client.generation
294271
+ });
294272
+ client.clearDiagnostics(uri);
294273
+ client.notify("textDocument/didChange", {
294274
+ textDocument: {
294275
+ uri,
294276
+ version
294277
+ },
294278
+ contentChanges: [{ text }]
294279
+ });
294280
+ }
294281
+ requireDocumentPath(input) {
294282
+ if (input === void 0 || input.trim().length === 0) throw new Error("LSP operation requires path");
294283
+ return path.resolve(this.options.cwd, input);
294284
+ }
294285
+ };
294286
+ }));
294287
+ //#endregion
294288
+ //#region ../../packages/agent-core/src/lsp/index.ts
294289
+ var init_lsp = __esmMin((() => {
294290
+ init_manager$1();
294291
+ }));
294292
+ //#endregion
293741
294293
  //#region ../../packages/agent-core/src/session/index.ts
293742
294294
  async function waitForSettlementOrTimeout(promise, timeoutMs) {
293743
294295
  let timeout;
@@ -293782,6 +294334,7 @@ var init_session$1 = __esmMin((() => {
293782
294334
  init_flags();
293783
294335
  init_abort();
293784
294336
  init_vision_reader();
294337
+ init_lsp();
293785
294338
  init_subagent_host();
293786
294339
  BACKGROUND_KEEP_ALIVE_ON_EXIT_ENV = "BLUN_BACKGROUND_KEEP_ALIVE_ON_EXIT";
293787
294340
  ACTIVE_TURN_CLOSE_TIMEOUT_MS = 8e3;
@@ -293793,6 +294346,7 @@ var init_session$1 = __esmMin((() => {
293793
294346
  skills;
293794
294347
  agents = /* @__PURE__ */ new Map();
293795
294348
  mcp;
294349
+ lsp;
293796
294350
  log;
293797
294351
  logHandle;
293798
294352
  hookEngine;
@@ -293842,6 +294396,10 @@ var init_session$1 = __esmMin((() => {
293842
294396
  log: this.log,
293843
294397
  stdioCwd: options.kaos.getcwd()
293844
294398
  });
294399
+ this.lsp = options.lspServers === void 0 || Object.keys(options.lspServers).length === 0 ? void 0 : new LspManager({
294400
+ cwd: options.kaos.getcwd(),
294401
+ servers: options.lspServers
294402
+ });
293845
294403
  this.mcp.onStatusChange((entry) => {
293846
294404
  this.onMcpServerStatusChange(entry);
293847
294405
  });
@@ -293944,7 +294502,7 @@ var init_session$1 = __esmMin((() => {
293944
294502
  await this.triggerSessionEnd("exit");
293945
294503
  } finally {
293946
294504
  try {
293947
- await this.mcp.shutdown();
294505
+ await Promise.allSettled([this.mcp.shutdown(), this.lsp?.shutdown()]);
293948
294506
  } finally {
293949
294507
  await this.logHandle?.close();
293950
294508
  }
@@ -293956,7 +294514,7 @@ var init_session$1 = __esmMin((() => {
293956
294514
  await this.flushMetadata();
293957
294515
  } finally {
293958
294516
  try {
293959
- await this.mcp.shutdown();
294517
+ await Promise.allSettled([this.mcp.shutdown(), this.lsp?.shutdown()]);
293960
294518
  } finally {
293961
294519
  await this.logHandle?.close();
293962
294520
  }
@@ -294344,7 +294902,10 @@ var init_session$1 = __esmMin((() => {
294344
294902
  ...config,
294345
294903
  type,
294346
294904
  kaos: this.toolKaos.withCwd(cwd),
294347
- toolServices: this.options.toolServices,
294905
+ toolServices: {
294906
+ ...this.options.toolServices,
294907
+ lsp: this.lsp
294908
+ },
294348
294909
  config: this.options.config,
294349
294910
  blunHomeDir: this.options.blunHomeDir,
294350
294911
  homedir,
@@ -294643,6 +295204,7 @@ async function parseManifest(pluginRoot) {
294643
295204
  skills,
294644
295205
  sessionStart: readSessionStart(raw["sessionStart"], diagnostics),
294645
295206
  mcpServers: await readMcpServers(pluginRoot, raw["mcpServers"], diagnostics),
295207
+ lspServers: await readLspServers(pluginRoot, raw["lspServers"], diagnostics),
294646
295208
  hooks: readHooks(raw["hooks"], diagnostics),
294647
295209
  commands: await readCommands(pluginRoot, raw["commands"], diagnostics),
294648
295210
  interface: readInterface(raw["interface"]),
@@ -294791,6 +295353,114 @@ async function readMcpServers(pluginRoot, raw, diagnostics) {
294791
295353
  }
294792
295354
  return Object.keys(out).length === 0 ? void 0 : out;
294793
295355
  }
295356
+ async function readLspServers(pluginRoot, manifestValue, diagnostics) {
295357
+ let raw = manifestValue;
295358
+ if (raw === void 0) {
295359
+ const configPath = path.join(pluginRoot, ".lsp.json");
295360
+ if (!await isFile$1(configPath)) return void 0;
295361
+ try {
295362
+ raw = JSON.parse(await readFile(configPath, "utf8"));
295363
+ } catch (error) {
295364
+ diagnostics.push({
295365
+ severity: "warn",
295366
+ message: `Failed to parse .lsp.json: ${error.message}`
295367
+ });
295368
+ return;
295369
+ }
295370
+ }
295371
+ if (!isObject$4(raw)) {
295372
+ diagnostics.push({
295373
+ severity: "warn",
295374
+ message: "\"lspServers\" must be an object"
295375
+ });
295376
+ return;
295377
+ }
295378
+ const out = {};
295379
+ for (const [name, value] of Object.entries(raw)) {
295380
+ const config = await normalizePluginLspServer(pluginRoot, name, value, diagnostics);
295381
+ if (config !== void 0) out[name] = config;
295382
+ }
295383
+ return out;
295384
+ }
295385
+ async function normalizePluginLspServer(pluginRoot, name, raw, diagnostics) {
295386
+ const field = `lspServers.${name}`;
295387
+ if (!isObject$4(raw)) {
295388
+ diagnostics.push({
295389
+ severity: "warn",
295390
+ message: `"${field}" must be an object`
295391
+ });
295392
+ return;
295393
+ }
295394
+ let command = stringField$3(raw, "command");
295395
+ if (command === void 0) {
295396
+ diagnostics.push({
295397
+ severity: "warn",
295398
+ message: `"${field}.command" is required`
295399
+ });
295400
+ return;
295401
+ }
295402
+ const extensionToLanguage = stringRecordField(raw["extensionToLanguage"]);
295403
+ if (extensionToLanguage === void 0 || Object.keys(extensionToLanguage).length === 0) {
295404
+ diagnostics.push({
295405
+ severity: "warn",
295406
+ message: `"${field}.extensionToLanguage" must map at least one extension to a language`
295407
+ });
295408
+ return;
295409
+ }
295410
+ if (command.startsWith("./")) {
295411
+ command = await resolvePluginPathField({
295412
+ pluginRoot,
295413
+ field: `${field}.command`,
295414
+ value: command,
295415
+ diagnostics
295416
+ });
295417
+ if (command === void 0) return void 0;
295418
+ } else if (command.includes("/") || path.isAbsolute(command)) {
295419
+ diagnostics.push({
295420
+ severity: "warn",
295421
+ message: `"${field}.command" must be a PATH command or start with "./"`
295422
+ });
295423
+ return;
295424
+ }
295425
+ let workspaceFolder = stringField$3(raw, "workspaceFolder");
295426
+ if (workspaceFolder !== void 0) {
295427
+ workspaceFolder = await resolvePluginPathField({
295428
+ pluginRoot,
295429
+ field: `${field}.workspaceFolder`,
295430
+ value: workspaceFolder,
295431
+ diagnostics
295432
+ });
295433
+ if (workspaceFolder === void 0) return void 0;
295434
+ }
295435
+ const args = stringArrayField$1(raw, "args");
295436
+ if (raw["args"] !== void 0 && args === void 0) {
295437
+ diagnostics.push({
295438
+ severity: "warn",
295439
+ message: `"${field}.args" must be a string[]`
295440
+ });
295441
+ return;
295442
+ }
295443
+ const env = stringRecordField(raw["env"]);
295444
+ if (raw["env"] !== void 0 && env === void 0) {
295445
+ diagnostics.push({
295446
+ severity: "warn",
295447
+ message: `"${field}.env" must contain string values`
295448
+ });
295449
+ return;
295450
+ }
295451
+ return {
295452
+ command,
295453
+ args,
295454
+ extensionToLanguage,
295455
+ env,
295456
+ initializationOptions: objectField(raw["initializationOptions"]),
295457
+ settings: objectField(raw["settings"]),
295458
+ workspaceFolder,
295459
+ startupTimeoutMs: positiveNumberField(raw["startupTimeoutMs"]),
295460
+ shutdownTimeoutMs: positiveNumberField(raw["shutdownTimeoutMs"]),
295461
+ restartOnCrash: booleanField(raw["restartOnCrash"])
295462
+ };
295463
+ }
294794
295464
  function readHooks(raw, diagnostics) {
294795
295465
  if (raw === void 0) return void 0;
294796
295466
  if (!Array.isArray(raw)) {
@@ -294938,6 +295608,19 @@ function stringArrayField$1(raw, key) {
294938
295608
  if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string")) return;
294939
295609
  return value;
294940
295610
  }
295611
+ function stringRecordField(value) {
295612
+ if (!isObject$4(value) || !Object.values(value).every((entry) => typeof entry === "string")) return;
295613
+ return value;
295614
+ }
295615
+ function objectField(value) {
295616
+ return isObject$4(value) ? value : void 0;
295617
+ }
295618
+ function positiveNumberField(value) {
295619
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
295620
+ }
295621
+ function booleanField(value) {
295622
+ return typeof value === "boolean" ? value : void 0;
295623
+ }
294941
295624
  function isObject$4(value) {
294942
295625
  return typeof value === "object" && value !== null && !Array.isArray(value);
294943
295626
  }
@@ -295467,7 +296150,7 @@ function pluginMcpServerInfo(record, name, config) {
295467
296150
  }
295468
296151
  function publicPluginManifest(manifest) {
295469
296152
  if (manifest === void 0) return void 0;
295470
- const { mcpServers: _privateMcpServers, ...publicManifest } = manifest;
296153
+ const { mcpServers: _privateMcpServers, lspServers: _privateLspServers, ...publicManifest } = manifest;
295471
296154
  return publicManifest;
295472
296155
  }
295473
296156
  function sanitizePluginOriginalSource(value) {
@@ -295717,6 +296400,14 @@ var init_manager = __esmMin((() => {
295717
296400
  enabledMcpServers() {
295718
296401
  return Object.fromEntries(this.mcpServerConfigs().filter((entry) => entry.config.enabled !== false).map((entry) => [entry.runtimeName, entry.config]));
295719
296402
  }
296403
+ enabledLspServers() {
296404
+ const out = {};
296405
+ for (const record of this.records.values()) {
296406
+ if (!this.runtimeEnabled(record) || record.state !== "ok" || record.manifest === void 0) continue;
296407
+ for (const [name, config] of Object.entries(record.manifest.lspServers ?? {})) out[`plugin-${record.id}:${name}`] = config;
296408
+ }
296409
+ return out;
296410
+ }
295720
296411
  /** All installed plugin MCPs, including disabled plugin/server entries. */
295721
296412
  mcpServerConfigs() {
295722
296413
  const out = [];
@@ -309801,7 +310492,7 @@ var require_dist$5 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
309801
310492
  //#endregion
309802
310493
  //#region ../../node_modules/.pnpm/yazl@3.3.1/node_modules/yazl/index.js
309803
310494
  var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
309804
- var fs$5 = __require("fs");
310495
+ var fs$6 = __require("fs");
309805
310496
  var Transform$2 = __require("stream").Transform;
309806
310497
  var PassThrough$2 = __require("stream").PassThrough;
309807
310498
  var zlib$1 = __require("zlib");
@@ -309830,14 +310521,14 @@ var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
309830
310521
  if (shouldIgnoreAdding(self)) return;
309831
310522
  var entry = new Entry(metadataPath, false, options);
309832
310523
  self.entries.push(entry);
309833
- fs$5.stat(realPath, function(err, stats) {
310524
+ fs$6.stat(realPath, function(err, stats) {
309834
310525
  if (err) return self.emit("error", err);
309835
310526
  if (!stats.isFile()) return self.emit("error", /* @__PURE__ */ new Error("not a file: " + realPath));
309836
310527
  entry.uncompressedSize = stats.size;
309837
310528
  if (options.mtime == null) entry.setLastModDate(stats.mtime);
309838
310529
  if (options.mode == null) entry.setFileAttributesMode(stats.mode);
309839
310530
  entry.setFileDataPumpFunction(function() {
309840
- var readStream = fs$5.createReadStream(realPath);
310531
+ var readStream = fs$6.createReadStream(realPath);
309841
310532
  entry.state = Entry.FILE_DATA_IN_PROGRESS;
309842
310533
  readStream.on("error", function(err) {
309843
310534
  self.emit("error", err);
@@ -311169,10 +311860,10 @@ async function appendForkedMarkers(state) {
311169
311860
  time: Date.now()
311170
311861
  };
311171
311862
  const agents = state["agents"];
311172
- if (!isRecord$15(agents)) return;
311863
+ if (!isRecord$16(agents)) return;
311173
311864
  const paths = /* @__PURE__ */ new Set();
311174
311865
  for (const agentMeta of Object.values(agents)) {
311175
- if (!isRecord$15(agentMeta)) continue;
311866
+ if (!isRecord$16(agentMeta)) continue;
311176
311867
  const homedir = agentMeta["homedir"];
311177
311868
  if (typeof homedir !== "string") continue;
311178
311869
  paths.add(join$4(homedir, "wire.jsonl"));
@@ -311184,7 +311875,7 @@ async function appendForkedMarkers(state) {
311184
311875
  }));
311185
311876
  }
311186
311877
  function customMetadataForFork(value) {
311187
- if (!isRecord$15(value)) return {};
311878
+ if (!isRecord$16(value)) return {};
311188
311879
  const custom = {};
311189
311880
  for (const [key, entry] of Object.entries(value)) {
311190
311881
  if (key === "goal" || key === "managedQuotaWarningThreshold") continue;
@@ -311239,10 +311930,10 @@ function normalizeForkTitle(title, fallback) {
311239
311930
  return typeof fallback === "string" && fallback.trim().length > 0 ? fallback : "New Session";
311240
311931
  }
311241
311932
  function rewriteAgentHomedirs(value, sourceDir, targetDir) {
311242
- if (!isRecord$15(value)) return {};
311933
+ if (!isRecord$16(value)) return {};
311243
311934
  const agents = {};
311244
311935
  for (const [agentId, agentMeta] of Object.entries(value)) {
311245
- if (!isRecord$15(agentMeta)) {
311936
+ if (!isRecord$16(agentMeta)) {
311246
311937
  agents[agentId] = agentMeta;
311247
311938
  continue;
311248
311939
  }
@@ -311260,7 +311951,7 @@ function remapSessionPath(value, sourceDir, targetDir) {
311260
311951
  if (rel.startsWith("..") || isAbsolute$2(rel)) return value;
311261
311952
  return join$4(targetDir, rel);
311262
311953
  }
311263
- function isRecord$15(value) {
311954
+ function isRecord$16(value) {
311264
311955
  return typeof value === "object" && value !== null && !Array.isArray(value);
311265
311956
  }
311266
311957
  async function statIfExists(path) {
@@ -311508,7 +312199,7 @@ var init_session_store$1 = __esmMin((() => {
311508
312199
  } catch (error) {
311509
312200
  throw new BlunError(ErrorCodes.SESSION_STATE_NOT_FOUND, `Session "${input.sourceId}" state.json was not found`, { cause: error });
311510
312201
  }
311511
- if (!isRecord$15(parsed)) throw new BlunError(ErrorCodes.SESSION_STATE_INVALID, `Session "${input.sourceId}" state.json is invalid`);
312202
+ if (!isRecord$16(parsed)) throw new BlunError(ErrorCodes.SESSION_STATE_INVALID, `Session "${input.sourceId}" state.json is invalid`);
311512
312203
  const title = normalizeForkTitle(input.title, parsed["title"]);
311513
312204
  const now = (/* @__PURE__ */ new Date()).toISOString();
311514
312205
  const next = {
@@ -312938,6 +313629,7 @@ var init_core_impl = __esmMin((() => {
312938
313629
  permissionRules: config.permission?.rules,
312939
313630
  skills: this.resolveSessionSkillConfig(config),
312940
313631
  mcpConfig,
313632
+ lspServers: this.plugins.enabledLspServers(),
312941
313633
  experimentalFlags: this.experimentalFlags,
312942
313634
  telemetry: sessionTelemetry,
312943
313635
  pluginSessionStarts,
@@ -313034,6 +313726,7 @@ var init_core_impl = __esmMin((() => {
313034
313726
  permissionRules: config.permission?.rules,
313035
313727
  skills: this.resolveSessionSkillConfig(config),
313036
313728
  mcpConfig,
313729
+ lspServers: this.plugins.enabledLspServers(),
313037
313730
  experimentalFlags: this.experimentalFlags,
313038
313731
  telemetry: withTelemetryContext$1(this.telemetry, { sessionId: summary.id }),
313039
313732
  initializeMainAgent: false,
@@ -326416,7 +327109,7 @@ var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
326416
327109
  const EventEmitter$12 = __require("node:events").EventEmitter;
326417
327110
  const childProcess = __require("node:child_process");
326418
327111
  const path$7 = __require("node:path");
326419
- const fs$4 = __require("node:fs");
327112
+ const fs$5 = __require("node:fs");
326420
327113
  const process$2 = __require("node:process");
326421
327114
  const { Argument, humanReadableArgName } = require_argument();
326422
327115
  const { CommanderError } = require_error$2();
@@ -327299,7 +327992,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
327299
327992
  * @param {string} subcommandName
327300
327993
  */
327301
327994
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
327302
- if (fs$4.existsSync(executableFile)) return;
327995
+ if (fs$5.existsSync(executableFile)) return;
327303
327996
  const executableMissing = `'${executableFile}' does not exist
327304
327997
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
327305
327998
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
@@ -327323,9 +328016,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
327323
328016
  ];
327324
328017
  function findFile(baseDir, baseName) {
327325
328018
  const localBin = path$7.resolve(baseDir, baseName);
327326
- if (fs$4.existsSync(localBin)) return localBin;
328019
+ if (fs$5.existsSync(localBin)) return localBin;
327327
328020
  if (sourceExt.includes(path$7.extname(baseName))) return void 0;
327328
- const foundExt = sourceExt.find((ext) => fs$4.existsSync(`${localBin}${ext}`));
328021
+ const foundExt = sourceExt.find((ext) => fs$5.existsSync(`${localBin}${ext}`));
327329
328022
  if (foundExt) return `${localBin}${foundExt}`;
327330
328023
  }
327331
328024
  this._checkForMissingMandatoryOptions();
@@ -327335,7 +328028,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
327335
328028
  if (this._scriptPath) {
327336
328029
  let resolvedScriptPath;
327337
328030
  try {
327338
- resolvedScriptPath = fs$4.realpathSync(this._scriptPath);
328031
+ resolvedScriptPath = fs$5.realpathSync(this._scriptPath);
327339
328032
  } catch {
327340
328033
  resolvedScriptPath = this._scriptPath;
327341
328034
  }
@@ -337013,8 +337706,8 @@ function createAccountMemoryClient(auth, options = {}) {
337013
337706
  }
337014
337707
  function readAccountMemoryConsentStatus(payload) {
337015
337708
  const settings = unwrapPayload(payload)?.["settings"];
337016
- const dataControls = isRecord$14(settings) ? settings["data_controls"] : void 0;
337017
- if (!isRecord$14(dataControls)) throw new Error("Account memory returned an invalid response.");
337709
+ const dataControls = isRecord$15(settings) ? settings["data_controls"] : void 0;
337710
+ if (!isRecord$15(dataControls)) throw new Error("Account memory returned an invalid response.");
337018
337711
  if (dataControls["memory_consent_asked"] !== true) return "never_asked";
337019
337712
  if (dataControls["allow_memory"] === true) return "enabled";
337020
337713
  if (dataControls["allow_memory"] === false) return "disabled";
@@ -337137,8 +337830,8 @@ function memoryContextSummary(facts, included) {
337137
337830
  })}`;
337138
337831
  }
337139
337832
  function unwrapPayload(value) {
337140
- if (!isRecord$14(value)) return void 0;
337141
- return isRecord$14(value["data"]) ? value["data"] : value;
337833
+ if (!isRecord$15(value)) return void 0;
337834
+ return isRecord$15(value["data"]) ? value["data"] : value;
337142
337835
  }
337143
337836
  function readFacts(root) {
337144
337837
  let rawFacts = [];
@@ -337146,7 +337839,7 @@ function readFacts(root) {
337146
337839
  else {
337147
337840
  const factsJson = parseFactsJson(root["facts_json"]);
337148
337841
  if (Array.isArray(factsJson)) rawFacts = factsJson;
337149
- else if (isRecord$14(factsJson) && Array.isArray(factsJson["facts"])) rawFacts = factsJson["facts"];
337842
+ else if (isRecord$15(factsJson) && Array.isArray(factsJson["facts"])) rawFacts = factsJson["facts"];
337150
337843
  }
337151
337844
  const facts = [];
337152
337845
  const seen = /* @__PURE__ */ new Set();
@@ -337175,7 +337868,7 @@ function parseFactsJson(value) {
337175
337868
  }
337176
337869
  }
337177
337870
  function normalizeFact(value) {
337178
- const raw = typeof value === "string" ? value : isRecord$14(value) && typeof value["text"] === "string" ? value["text"] : void 0;
337871
+ const raw = typeof value === "string" ? value : isRecord$15(value) && typeof value["text"] === "string" ? value["text"] : void 0;
337179
337872
  if (raw === void 0) return void 0;
337180
337873
  const normalized = raw.replaceAll(/\s+/gu, " ").trim();
337181
337874
  if (normalized.length === 0) return void 0;
@@ -337184,7 +337877,7 @@ function normalizeFact(value) {
337184
337877
  truncated: normalized.length > ACCOUNT_MEMORY_MAX_FACT_CHARS
337185
337878
  };
337186
337879
  }
337187
- function isRecord$14(value) {
337880
+ function isRecord$15(value) {
337188
337881
  return typeof value === "object" && value !== null && !Array.isArray(value);
337189
337882
  }
337190
337883
  //#endregion
@@ -338625,7 +339318,7 @@ function formatErrorMessage$4(error, filePath) {
338625
339318
  function findValidationIssues(error) {
338626
339319
  if (!(error instanceof Error)) return void 0;
338627
339320
  const details = "details" in error ? error.details : void 0;
338628
- if (!isRecord$13(details)) return void 0;
339321
+ if (!isRecord$14(details)) return void 0;
338629
339322
  const validationIssues = details["validationIssues"];
338630
339323
  return isValidationIssueArray(validationIssues) ? validationIssues : void 0;
338631
339324
  }
@@ -338633,11 +339326,11 @@ function isValidationIssueArray(value) {
338633
339326
  return Array.isArray(value) && value.every(isValidationIssue);
338634
339327
  }
338635
339328
  function isValidationIssue(value) {
338636
- if (!isRecord$13(value) || typeof value["message"] !== "string") return false;
339329
+ if (!isRecord$14(value) || typeof value["message"] !== "string") return false;
338637
339330
  const path = value["path"];
338638
339331
  return Array.isArray(path) && path.every((segment) => typeof segment === "string" || typeof segment === "number");
338639
339332
  }
338640
- function isRecord$13(value) {
339333
+ function isRecord$14(value) {
338641
339334
  return typeof value === "object" && value !== null;
338642
339335
  }
338643
339336
  function findZodError(error) {
@@ -339132,7 +339825,7 @@ function assertEntryCount(value) {
339132
339825
  return value;
339133
339826
  }
339134
339827
  function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
339135
- if (!isRecord$12(value) || !hasOnlyKeys(value, [
339828
+ if (!isRecord$13(value) || !hasOnlyKeys(value, [
339136
339829
  "version",
339137
339830
  "records",
339138
339831
  "relations"
@@ -339145,7 +339838,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
339145
339838
  return {
339146
339839
  version: 1,
339147
339840
  records: value["records"].map((candidate, index) => {
339148
- if (!isRecord$12(candidate) || !hasOnlyKeys(candidate, [
339841
+ if (!isRecord$13(candidate) || !hasOnlyKeys(candidate, [
339149
339842
  "source_record_id",
339150
339843
  "type",
339151
339844
  "raw_locator"
@@ -339165,7 +339858,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
339165
339858
  };
339166
339859
  }),
339167
339860
  relations: value["relations"].map((candidate, index) => {
339168
- if (!isRecord$12(candidate) || !hasOnlyKeys(candidate, [
339861
+ if (!isRecord$13(candidate) || !hasOnlyKeys(candidate, [
339169
339862
  "from_source_record_id",
339170
339863
  "type",
339171
339864
  "to"
@@ -339175,7 +339868,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
339175
339868
  const target = candidate["to"];
339176
339869
  if (typeof fromRecordId !== "string" || !isValidRecordId(fromRecordId) || !recordIds.has(fromRecordId)) throw new Error(`record relation ${index} must start at a declared local record`);
339177
339870
  if (typeof type !== "string" || !MISTAKE_RELATION_TYPES.includes(type)) throw new Error(`record relation ${index} has an invalid relation type`);
339178
- if (!isRecord$12(target) || !hasOnlyKeys(target, ["source_id", "source_record_id"])) throw new Error(`record relation ${index} has an invalid target`);
339871
+ if (!isRecord$13(target) || !hasOnlyKeys(target, ["source_id", "source_record_id"])) throw new Error(`record relation ${index} has an invalid target`);
339179
339872
  const targetSourceId = target["source_id"];
339180
339873
  const targetRecordId = target["source_record_id"];
339181
339874
  if (typeof targetSourceId !== "string" || !isNormalizedSourceId(targetSourceId)) throw new Error(`record relation ${index} has an invalid target source id`);
@@ -339445,7 +340138,7 @@ function receiptsEqual(left, right) {
339445
340138
  return left.version === right.version && left.accepted === right.accepted && left.event_id === right.event_id && left.client_event_id === right.client_event_id && left.source_id === right.source_id && left.canonical_agent_id === right.canonical_agent_id && left.received_at === right.received_at && left.raw_count === right.raw_count && left.accepted_count === right.accepted_count && left.rejected_count === right.rejected_count && left.raw_bytes === right.raw_bytes && left.raw_sha256 === right.raw_sha256 && left.declared_entry_count === right.declared_entry_count;
339446
340139
  }
339447
340140
  function isStateActionReceipt(value) {
339448
- if (!isRecord$12(value) || !hasOnlyKeys(value, STATE_ACTION_KEYS)) return false;
340141
+ if (!isRecord$13(value) || !hasOnlyKeys(value, STATE_ACTION_KEYS)) return false;
339449
340142
  const reason = value["reason"];
339450
340143
  return value["version"] === 1 && typeof value["action_id"] === "string" && UUID_RE$1.test(value["action_id"]) && (value["action"] === "remove" || value["action"] === "restore") && typeof value["target_event_id"] === "string" && UUID_RE$1.test(value["target_event_id"]) && typeof value["acted_at"] === "string" && isIsoTimestamp(value["acted_at"]) && Number.isSafeInteger(value["server_sequence"]) && value["server_sequence"] >= 1 && typeof value["principal_id"] === "string" && isNormalizedSourceId(value["principal_id"]) && typeof reason === "string" && reason.trim() === reason && reason.length >= 3 && reason.length <= 500;
339451
340144
  }
@@ -339548,7 +340241,7 @@ function assertInventoryInvariants(bestandsstatus, aktualitaetsstatus, declaredE
339548
340241
  if (aktualitaetsstatus === "fresh" && lastRawObservedAt === null) throw new Error("fresh inventory requires a last raw observed timestamp");
339549
340242
  if (capturedAt !== void 0 && lastRawObservedAt !== null && Date.parse(lastRawObservedAt) > Date.parse(capturedAt)) throw new Error("last raw observed timestamp must not be later than captured at");
339550
340243
  }
339551
- function isRecord$12(value) {
340244
+ function isRecord$13(value) {
339552
340245
  return typeof value === "object" && value !== null && !Array.isArray(value);
339553
340246
  }
339554
340247
  function hasOnlyKeys(value, allowedKeys) {
@@ -340454,6 +341147,9 @@ function resolveDeps(overrides) {
340454
341147
  };
340455
341148
  }
340456
341149
  //#endregion
341150
+ //#region src/constant/account-consent.ts
341151
+ const ACCOUNT_CONSENT_PATH = "/api/account/consent";
341152
+ //#endregion
340457
341153
  //#region src/personal-memory/phase1-contract.json
340458
341154
  var clientOperations = {
340459
341155
  "settingsRead": {
@@ -340509,7 +341205,7 @@ var PersonalMemoryBrokerError = class extends Error {
340509
341205
  }
340510
341206
  };
340511
341207
  function parsePersonalMemorySettings(payload) {
340512
- if (!isRecord$11(payload)) return void 0;
341208
+ if (!isRecord$12(payload)) return void 0;
340513
341209
  const status = payload["status"];
340514
341210
  if (status !== "configured" && status !== "never_asked") return void 0;
340515
341211
  const memoryEnabled = payload["memory_enabled"];
@@ -340556,6 +341252,10 @@ var PersonalMemoryBrokerClient = class {
340556
341252
  async updateSettings(patch) {
340557
341253
  await this.request("PUT", PERSONAL_MEMORY_SETTINGS_PATH, patch);
340558
341254
  }
341255
+ async putConsent(allowed) {
341256
+ if (typeof allowed !== "boolean") throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
341257
+ await this.request("POST", ACCOUNT_CONSENT_PATH, { memory: allowed });
341258
+ }
340559
341259
  async request(method, path, body) {
340560
341260
  if (!isAllowedBrokerRequest(method, path)) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
340561
341261
  const idempotencyKey = method === "GET" ? void 0 : this.idempotencyKey();
@@ -340620,15 +341320,15 @@ async function brokerHttpError(response) {
340620
341320
  async function safeBrokerResponseCode(response) {
340621
341321
  try {
340622
341322
  const payload = await response.json();
340623
- if (!isRecord$11(payload)) return void 0;
340624
- const nested = isRecord$11(payload["error"]) ? payload["error"]["code"] : void 0;
341323
+ if (!isRecord$12(payload)) return void 0;
341324
+ const nested = isRecord$12(payload["error"]) ? payload["error"]["code"] : void 0;
340625
341325
  const candidate = payload["code"] ?? payload["error_code"] ?? nested;
340626
341326
  return typeof candidate === "string" && SAFE_BROKER_ERROR_CODES.has(candidate) ? candidate : void 0;
340627
341327
  } catch {
340628
341328
  return;
340629
341329
  }
340630
341330
  }
340631
- function isRecord$11(value) {
341331
+ function isRecord$12(value) {
340632
341332
  return typeof value === "object" && value !== null && !Array.isArray(value);
340633
341333
  }
340634
341334
  function isAllowedBrokerRequest(method, path) {
@@ -340642,6 +341342,7 @@ function isAllowedBrokerRequest(method, path) {
340642
341342
  if (url.search.length > 0 || url.hash.length > 0) return false;
340643
341343
  const pathname = url.pathname;
340644
341344
  if (pathname === PERSONAL_MEMORY_SETTINGS_PATH) return method === "GET" || method === "PUT";
341345
+ if (pathname === "/api/account/consent") return method === "POST";
340645
341346
  if (pathname === PERSONAL_MEMORY_MEMORIES_PATH) return method === "GET" || method === "POST";
340646
341347
  if (/^\/v1\/me\/memories\/[0-9a-f-]{36}$/i.test(pathname)) return false;
340647
341348
  if (pathname === PERSONAL_MEMORY_RECALL_PATH) return method === PERSONAL_MEMORY_RECALL_METHOD;
@@ -341334,7 +342035,7 @@ function createAttestation(value, createdAt) {
341334
342035
  };
341335
342036
  }
341336
342037
  function parseProof(value) {
341337
- if (!isRecord$10(value) || value["schema"] !== "blun.proof" || value["schemaVersion"] !== 1) throw new Error("Unsupported proof document.");
342038
+ if (!isRecord$11(value) || value["schema"] !== "blun.proof" || value["schemaVersion"] !== 1) throw new Error("Unsupported proof document.");
341338
342039
  assertObjectKeys(value, [
341339
342040
  "schema",
341340
342041
  "schemaVersion",
@@ -341354,12 +342055,12 @@ function parseProof(value) {
341354
342055
  "incomplete",
341355
342056
  "failed"
341356
342057
  ].includes(proof.outcome)) throw new Error("Invalid proof outcome.");
341357
- if (!isRecord$10(proof.source) || proof.source.kind !== "workspace") throw new Error("Invalid proof source.");
342058
+ if (!isRecord$11(proof.source) || proof.source.kind !== "workspace") throw new Error("Invalid proof source.");
341358
342059
  assertObjectKeys(proof.source, ["kind"], ["git"], "proof source");
341359
342060
  if (proof.source.git !== void 0) validateGitSnapshot(proof.source.git);
341360
342061
  if (!Array.isArray(proof.checks) || !Array.isArray(proof.artifacts)) throw new TypeError("Invalid proof collections.");
341361
342062
  if (proof.checks.length > MAX_COMMANDS || proof.artifacts.length > MAX_ARTIFACTS) throw new Error("Proof collections exceed their limits.");
341362
- if (!isRecord$10(proof.attestation) || proof.attestation.algorithm !== "SHA-256" || proof.attestation.scope !== "content-integrity-only" || !SHA256_PATTERN.test(proof.attestation.hash)) throw new Error("Invalid proof attestation.");
342063
+ if (!isRecord$11(proof.attestation) || proof.attestation.algorithm !== "SHA-256" || proof.attestation.scope !== "content-integrity-only" || !SHA256_PATTERN.test(proof.attestation.hash)) throw new Error("Invalid proof attestation.");
341363
342064
  assertObjectKeys(proof.attestation, [
341364
342065
  "algorithm",
341365
342066
  "scope",
@@ -341374,7 +342075,7 @@ function parseProof(value) {
341374
342075
  screenshot: 0
341375
342076
  };
341376
342077
  for (const artifact of proof.artifacts) {
341377
- if (!isRecord$10(artifact) || artifact.kind !== "file" && artifact.kind !== "screenshot" || typeof artifact.id !== "string" || typeof artifact.size !== "number" || !Number.isSafeInteger(artifact.size) || artifact.size < 0 || typeof artifact.sha256 !== "string" || !SHA256_PATTERN.test(artifact.sha256)) throw new Error("Invalid proof artifact.");
342078
+ if (!isRecord$11(artifact) || artifact.kind !== "file" && artifact.kind !== "screenshot" || typeof artifact.id !== "string" || typeof artifact.size !== "number" || !Number.isSafeInteger(artifact.size) || artifact.size < 0 || typeof artifact.sha256 !== "string" || !SHA256_PATTERN.test(artifact.sha256)) throw new Error("Invalid proof artifact.");
341378
342079
  assertObjectKeys(artifact, [
341379
342080
  "id",
341380
342081
  "kind",
@@ -341391,14 +342092,14 @@ function parseProof(value) {
341391
342092
  return proof;
341392
342093
  }
341393
342094
  function validateGitSnapshot(value) {
341394
- if (!isRecord$10(value)) throw new Error("Invalid proof git snapshot.");
342095
+ if (!isRecord$11(value)) throw new Error("Invalid proof git snapshot.");
341395
342096
  assertObjectKeys(value, ["dirty", "changedCount"], [], "proof git snapshot");
341396
342097
  if (typeof value["dirty"] !== "boolean") throw new TypeError("Invalid proof git dirty flag.");
341397
342098
  if (typeof value["changedCount"] !== "number" || !Number.isSafeInteger(value["changedCount"]) || value["changedCount"] < 0) throw new Error("Invalid proof git changed count.");
341398
342099
  if (value["dirty"] !== value["changedCount"] > 0) throw new Error("Inconsistent proof git state.");
341399
342100
  }
341400
342101
  function validateProofCheck(value, index) {
341401
- if (!isRecord$10(value)) throw new Error("Invalid proof check.");
342102
+ if (!isRecord$11(value)) throw new Error("Invalid proof check.");
341402
342103
  assertObjectKeys(value, [
341403
342104
  "id",
341404
342105
  "outcome",
@@ -341410,13 +342111,13 @@ function validateProofCheck(value, index) {
341410
342111
  if (value["outcome"] !== expectedOutcome) throw new Error("Invalid proof check outcome.");
341411
342112
  }
341412
342113
  function attestedContent(value) {
341413
- if (!isRecord$10(value)) return value;
342114
+ if (!isRecord$11(value)) return value;
341414
342115
  const { attestation: _attestation, createdAt: _createdAt, ...content } = value;
341415
342116
  return content;
341416
342117
  }
341417
342118
  function canonicalize(value) {
341418
342119
  if (Array.isArray(value)) return value.map(canonicalize);
341419
- if (!isRecord$10(value)) return value;
342120
+ if (!isRecord$11(value)) return value;
341420
342121
  return Object.keys(value).toSorted().reduce((result, key) => {
341421
342122
  result[key] = canonicalize(value[key]);
341422
342123
  return result;
@@ -341493,7 +342194,7 @@ function sameFileIdentity$1(left, right) {
341493
342194
  function sameFileSnapshot(left, right) {
341494
342195
  return sameFileIdentity$1(left, right) && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
341495
342196
  }
341496
- function isRecord$10(value) {
342197
+ function isRecord$11(value) {
341497
342198
  return typeof value === "object" && value !== null && !Array.isArray(value);
341498
342199
  }
341499
342200
  //#endregion
@@ -345765,7 +346466,7 @@ var require_atomic_sleep = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345765
346466
  //#endregion
345766
346467
  //#region ../../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js
345767
346468
  var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345768
- const fs$3 = __require("fs");
346469
+ const fs$4 = __require("fs");
345769
346470
  const EventEmitter$10 = __require("events");
345770
346471
  const inherits$6 = __require("util").inherits;
345771
346472
  const path$6 = __require("path");
@@ -345808,17 +346509,17 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345808
346509
  const flags = sonic.append ? "a" : "w";
345809
346510
  const mode = sonic.mode;
345810
346511
  if (sonic.sync) try {
345811
- if (sonic.mkdir) fs$3.mkdirSync(path$6.dirname(file), { recursive: true });
345812
- fileOpened(null, fs$3.openSync(file, flags, mode));
346512
+ if (sonic.mkdir) fs$4.mkdirSync(path$6.dirname(file), { recursive: true });
346513
+ fileOpened(null, fs$4.openSync(file, flags, mode));
345813
346514
  } catch (err) {
345814
346515
  fileOpened(err);
345815
346516
  throw err;
345816
346517
  }
345817
- else if (sonic.mkdir) fs$3.mkdir(path$6.dirname(file), { recursive: true }, (err) => {
346518
+ else if (sonic.mkdir) fs$4.mkdir(path$6.dirname(file), { recursive: true }, (err) => {
345818
346519
  if (err) return fileOpened(err);
345819
- fs$3.open(file, flags, mode, fileOpened);
346520
+ fs$4.open(file, flags, mode, fileOpened);
345820
346521
  });
345821
- else fs$3.open(file, flags, mode, fileOpened);
346522
+ else fs$4.open(file, flags, mode, fileOpened);
345822
346523
  }
345823
346524
  function SonicBoom(opts) {
345824
346525
  if (!(this instanceof SonicBoom)) return new SonicBoom(opts);
@@ -345856,8 +346557,8 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345856
346557
  this.flush = flushBuffer;
345857
346558
  this.flushSync = flushBufferSync;
345858
346559
  this._actualWrite = actualWriteBuffer;
345859
- fsWriteSync = () => fs$3.writeSync(this.fd, this._writingBuf);
345860
- fsWrite = () => fs$3.write(this.fd, this._writingBuf, this.release);
346560
+ fsWriteSync = () => fs$4.writeSync(this.fd, this._writingBuf);
346561
+ fsWrite = () => fs$4.write(this.fd, this._writingBuf, this.release);
345861
346562
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
345862
346563
  this._writingBuf = "";
345863
346564
  this.write = write;
@@ -345865,12 +346566,12 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345865
346566
  this.flushSync = flushSync;
345866
346567
  this._actualWrite = actualWrite;
345867
346568
  fsWriteSync = () => {
345868
- if (Buffer.isBuffer(this._writingBuf)) return fs$3.writeSync(this.fd, this._writingBuf);
345869
- return fs$3.writeSync(this.fd, this._writingBuf, "utf8");
346569
+ if (Buffer.isBuffer(this._writingBuf)) return fs$4.writeSync(this.fd, this._writingBuf);
346570
+ return fs$4.writeSync(this.fd, this._writingBuf, "utf8");
345870
346571
  };
345871
346572
  fsWrite = () => {
345872
- if (Buffer.isBuffer(this._writingBuf)) return fs$3.write(this.fd, this._writingBuf, this.release);
345873
- return fs$3.write(this.fd, this._writingBuf, "utf8", this.release);
346573
+ if (Buffer.isBuffer(this._writingBuf)) return fs$4.write(this.fd, this._writingBuf, this.release);
346574
+ return fs$4.write(this.fd, this._writingBuf, "utf8", this.release);
345874
346575
  };
345875
346576
  } else throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
345876
346577
  if (typeof fd === "number") {
@@ -345915,7 +346616,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
345915
346616
  return;
345916
346617
  }
345917
346618
  }
345918
- if (this._fsync) fs$3.fsyncSync(this.fd);
346619
+ if (this._fsync) fs$4.fsyncSync(this.fd);
345919
346620
  const len = this._len;
345920
346621
  if (this._reopening) {
345921
346622
  this._writing = false;
@@ -346012,7 +346713,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346012
346713
  this._flushPending = true;
346013
346714
  const onDrain = () => {
346014
346715
  if (!this._fsync) try {
346015
- fs$3.fsync(this.fd, (err) => {
346716
+ fs$4.fsync(this.fd, (err) => {
346016
346717
  this._flushPending = false;
346017
346718
  cb(err);
346018
346719
  });
@@ -346089,7 +346790,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346089
346790
  if (this._writing) return;
346090
346791
  const fd = this.fd;
346091
346792
  this.once("ready", () => {
346092
- if (fd !== this.fd) fs$3.close(fd, (err) => {
346793
+ if (fd !== this.fd) fs$4.close(fd, (err) => {
346093
346794
  if (err) return this.emit("error", err);
346094
346795
  });
346095
346796
  });
@@ -346120,7 +346821,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346120
346821
  while (this._bufs.length || buf.length) {
346121
346822
  if (buf.length <= 0) buf = this._bufs[0];
346122
346823
  try {
346123
- const n = Buffer.isBuffer(buf) ? fs$3.writeSync(this.fd, buf) : fs$3.writeSync(this.fd, buf, "utf8");
346824
+ const n = Buffer.isBuffer(buf) ? fs$4.writeSync(this.fd, buf) : fs$4.writeSync(this.fd, buf, "utf8");
346124
346825
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
346125
346826
  buf = releasedBufObj.writingBuf;
346126
346827
  this._len = releasedBufObj.len;
@@ -346131,7 +346832,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346131
346832
  }
346132
346833
  }
346133
346834
  try {
346134
- fs$3.fsyncSync(this.fd);
346835
+ fs$4.fsyncSync(this.fd);
346135
346836
  } catch {}
346136
346837
  }
346137
346838
  function flushBufferSync() {
@@ -346145,7 +346846,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346145
346846
  while (this._bufs.length || buf.length) {
346146
346847
  if (buf.length <= 0) buf = mergeBuf(this._bufs[0], this._lens[0]);
346147
346848
  try {
346148
- const n = fs$3.writeSync(this.fd, buf);
346849
+ const n = fs$4.writeSync(this.fd, buf);
346149
346850
  buf = buf.subarray(n);
346150
346851
  this._len = Math.max(this._len - n, 0);
346151
346852
  if (buf.length <= 0) {
@@ -346167,24 +346868,24 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346167
346868
  this._writing = true;
346168
346869
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
346169
346870
  if (this.sync) try {
346170
- release(null, Buffer.isBuffer(this._writingBuf) ? fs$3.writeSync(this.fd, this._writingBuf) : fs$3.writeSync(this.fd, this._writingBuf, "utf8"));
346871
+ release(null, Buffer.isBuffer(this._writingBuf) ? fs$4.writeSync(this.fd, this._writingBuf) : fs$4.writeSync(this.fd, this._writingBuf, "utf8"));
346171
346872
  } catch (err) {
346172
346873
  release(err);
346173
346874
  }
346174
- else fs$3.write(this.fd, this._writingBuf, release);
346875
+ else fs$4.write(this.fd, this._writingBuf, release);
346175
346876
  }
346176
346877
  function actualWriteBuffer() {
346177
346878
  const release = this.release;
346178
346879
  this._writing = true;
346179
346880
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
346180
346881
  if (this.sync) try {
346181
- release(null, fs$3.writeSync(this.fd, this._writingBuf));
346882
+ release(null, fs$4.writeSync(this.fd, this._writingBuf));
346182
346883
  } catch (err) {
346183
346884
  release(err);
346184
346885
  }
346185
346886
  else {
346186
346887
  if (kCopyBuffer) this._writingBuf = Buffer.from(this._writingBuf);
346187
- fs$3.write(this.fd, this._writingBuf, release);
346888
+ fs$4.write(this.fd, this._writingBuf, release);
346188
346889
  }
346189
346890
  }
346190
346891
  function actualClose(sonic) {
@@ -346198,10 +346899,10 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
346198
346899
  sonic._lens = [];
346199
346900
  assert$8(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
346200
346901
  try {
346201
- fs$3.fsync(sonic.fd, closeWrapped);
346902
+ fs$4.fsync(sonic.fd, closeWrapped);
346202
346903
  } catch {}
346203
346904
  function closeWrapped() {
346204
- if (sonic.fd !== 1 && sonic.fd !== 2) fs$3.close(sonic.fd, done);
346905
+ if (sonic.fd !== 1 && sonic.fd !== 2) fs$4.close(sonic.fd, done);
346205
346906
  else done();
346206
346907
  }
346207
346908
  function done(err) {
@@ -368824,7 +369525,7 @@ var require_constants$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
368824
369525
  //#endregion
368825
369526
  //#region ../../../../node_modules/node-gyp-build/node-gyp-build.js
368826
369527
  var require_node_gyp_build$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
368827
- var fs$2 = __require("fs");
369528
+ var fs$3 = __require("fs");
368828
369529
  var path$5 = __require("path");
368829
369530
  var os$3 = __require("os");
368830
369531
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
@@ -368880,7 +369581,7 @@ var require_node_gyp_build$1 = /* @__PURE__ */ __commonJSMin(((exports, module)
368880
369581
  };
368881
369582
  function readdirSync(dir) {
368882
369583
  try {
368883
- return fs$2.readdirSync(dir);
369584
+ return fs$3.readdirSync(dir);
368884
369585
  } catch (err) {
368885
369586
  return [];
368886
369587
  }
@@ -368968,7 +369669,7 @@ var require_node_gyp_build$1 = /* @__PURE__ */ __commonJSMin(((exports, module)
368968
369669
  return typeof window !== "undefined" && window.process && window.process.type === "renderer";
368969
369670
  }
368970
369671
  function isAlpine(platform) {
368971
- return platform === "linux" && fs$2.existsSync("/etc/alpine-release");
369672
+ return platform === "linux" && fs$3.existsSync("/etc/alpine-release");
368972
369673
  }
368973
369674
  load.parseTags = parseTags;
368974
369675
  load.matchTags = matchTags;
@@ -389121,7 +389822,7 @@ var require_dist$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
389121
389822
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/mode/static.js
389122
389823
  var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
389123
389824
  const path$3 = __require("node:path");
389124
- const fs$1 = __require("node:fs");
389825
+ const fs$2 = __require("node:fs");
389125
389826
  const yaml = require_dist$1();
389126
389827
  module.exports = function(fastify, opts, done) {
389127
389828
  if (!opts.specification) return done(/* @__PURE__ */ new Error("specification is missing in the module options"));
@@ -389130,14 +389831,14 @@ var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
389130
389831
  if (!opts.specification.path && !opts.specification.document) return done(/* @__PURE__ */ new Error("both specification.path and specification.document are missing, should be path to the file or swagger document spec"));
389131
389832
  else if (opts.specification.path) {
389132
389833
  if (typeof opts.specification.path !== "string") return done(/* @__PURE__ */ new Error("specification.path is not a string"));
389133
- if (!fs$1.existsSync(path$3.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
389834
+ if (!fs$2.existsSync(path$3.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
389134
389835
  const extName = path$3.extname(opts.specification.path).toLowerCase();
389135
389836
  if ([".yaml", ".json"].indexOf(extName) === -1) return done(/* @__PURE__ */ new Error("specification.path extension name is not supported, should be one from ['.yaml', '.json']"));
389136
389837
  if (opts.specification.postProcessor && typeof opts.specification.postProcessor !== "function") return done(/* @__PURE__ */ new Error("specification.postProcessor should be a function"));
389137
389838
  if (opts.specification.baseDir && typeof opts.specification.baseDir !== "string") return done(/* @__PURE__ */ new Error("specification.baseDir should be string"));
389138
389839
  if (!opts.specification.baseDir) opts.specification.baseDir = path$3.resolve(path$3.dirname(opts.specification.path));
389139
389840
  else while (opts.specification.baseDir.endsWith("/")) opts.specification.baseDir = opts.specification.baseDir.slice(0, -1);
389140
- const source = fs$1.readFileSync(path$3.resolve(opts.specification.path), "utf8");
389841
+ const source = fs$2.readFileSync(path$3.resolve(opts.specification.path), "utf8");
389141
389842
  switch (extName) {
389142
389843
  case ".yaml":
389143
389844
  swaggerObject = yaml.parse(source);
@@ -389404,11 +390105,11 @@ var require_should_route_hide = /* @__PURE__ */ __commonJSMin(((exports, module)
389404
390105
  //#endregion
389405
390106
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/util/read-package-json.js
389406
390107
  var require_read_package_json = /* @__PURE__ */ __commonJSMin(((exports, module) => {
389407
- const fs = __require("node:fs");
390108
+ const fs$1 = __require("node:fs");
389408
390109
  const path$2 = __require("node:path");
389409
390110
  function readPackageJson() {
389410
390111
  try {
389411
- return JSON.parse(fs.readFileSync(path$2.join(__dirname, "..", "..", "package.json")));
390112
+ return JSON.parse(fs$1.readFileSync(path$2.join(__dirname, "..", "..", "package.json")));
389412
390113
  } catch {
389413
390114
  return {};
389414
390115
  }
@@ -396535,12 +397236,12 @@ function legacyStatusToCurrent(task) {
396535
397236
  return task.status;
396536
397237
  }
396537
397238
  function isReadablePersistedTask(obj) {
396538
- return isRecord$9(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
397239
+ return isRecord$10(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
396539
397240
  }
396540
397241
  function isLegacyPersistedTask(task) {
396541
397242
  return "task_id" in task;
396542
397243
  }
396543
- function isRecord$9(value) {
397244
+ function isRecord$10(value) {
396544
397245
  return typeof value === "object" && value !== null;
396545
397246
  }
396546
397247
  function optionalNonEmptyString(value) {
@@ -396949,11 +397650,11 @@ const WINDOWS_RESERVED_NAMES = new Set([
396949
397650
  ...Array.from({ length: 9 }, (_value, index) => `COM${String(index + 1)}`),
396950
397651
  ...Array.from({ length: 9 }, (_value, index) => `LPT${String(index + 1)}`)
396951
397652
  ]);
396952
- function isRecord$8(value) {
397653
+ function isRecord$9(value) {
396953
397654
  return typeof value === "object" && value !== null && !Array.isArray(value);
396954
397655
  }
396955
397656
  function assertRecord(value, label) {
396956
- if (!isRecord$8(value)) throw new Error(`${label} must be an object.`);
397657
+ if (!isRecord$9(value)) throw new Error(`${label} must be an object.`);
396957
397658
  }
396958
397659
  function assertExactKeys(value, required, optional, label) {
396959
397660
  const allowed = new Set([...required, ...optional]);
@@ -397244,7 +397945,7 @@ function currentArtifactRecord(artifacts) {
397244
397945
  return result;
397245
397946
  }
397246
397947
  function readAttestationHash(value) {
397247
- if (!isRecord$8(value) || !isRecord$8(value["attestation"])) return null;
397948
+ if (!isRecord$9(value) || !isRecord$9(value["attestation"])) return null;
397248
397949
  const hash = value["attestation"]["hash"];
397249
397950
  return typeof hash === "string" && /^[a-f0-9]{64}$/.test(hash) ? hash : null;
397250
397951
  }
@@ -398016,26 +398717,26 @@ async function ensureSafeDirectory(path, create, recursive) {
398016
398717
  return true;
398017
398718
  }
398018
398719
  function validateRegistry(value, context) {
398019
- if (!isRecord$7(value) || value["version"] !== 1) throw new WorkspaceError("registry_invalid", "Unsupported workspace registry version.");
398020
- if (!hasExactKeys(value, REGISTRY_KEYS)) throw new WorkspaceError("registry_invalid", "Workspace registry contains unknown fields.");
398021
- if (value["repoFingerprint"] !== context.repoFingerprint || value["primaryRoot"] !== context.primaryRoot || !isRecord$7(value["workspaces"])) throw new WorkspaceError("registry_invalid", "Workspace registry does not match this repository.");
398720
+ if (!isRecord$8(value) || value["version"] !== 1) throw new WorkspaceError("registry_invalid", "Unsupported workspace registry version.");
398721
+ if (!hasExactKeys$1(value, REGISTRY_KEYS)) throw new WorkspaceError("registry_invalid", "Workspace registry contains unknown fields.");
398722
+ if (value["repoFingerprint"] !== context.repoFingerprint || value["primaryRoot"] !== context.primaryRoot || !isRecord$8(value["workspaces"])) throw new WorkspaceError("registry_invalid", "Workspace registry does not match this repository.");
398022
398723
  for (const [name, record] of Object.entries(value["workspaces"])) if (!isWorkspaceRecord(record) || record.name !== name) throw new WorkspaceError("registry_invalid", "Workspace registry contains an invalid entry.");
398023
398724
  return value;
398024
398725
  }
398025
398726
  function isWorkspaceRecord(value) {
398026
- if (!isRecord$7(value) || !hasExactKeys(value, WORKSPACE_RECORD_KEYS)) return false;
398727
+ if (!isRecord$8(value) || !hasExactKeys$1(value, WORKSPACE_RECORD_KEYS)) return false;
398027
398728
  return typeof value["name"] === "string" && typeof value["path"] === "string" && typeof value["branch"] === "string" && typeof value["baseCommit"] === "string" && typeof value["repoFingerprint"] === "string" && isCanonicalIsoTimestamp(value["createdAt"]);
398028
398729
  }
398029
398730
  function isCanonicalIsoTimestamp(value) {
398030
398731
  if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) return false;
398031
398732
  return new Date(value).toISOString() === value;
398032
398733
  }
398033
- function isRecord$7(value) {
398734
+ function isRecord$8(value) {
398034
398735
  if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
398035
398736
  const prototype = Object.getPrototypeOf(value);
398036
398737
  return prototype === Object.prototype || prototype === null;
398037
398738
  }
398038
- function hasExactKeys(value, keys) {
398739
+ function hasExactKeys$1(value, keys) {
398039
398740
  return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
398040
398741
  }
398041
398742
  async function writeRegistryAtomic(repoStorageRoot, registry) {
@@ -398121,7 +398822,7 @@ async function readRegistryLockMetadata(lockPath) {
398121
398822
  if (error.code !== void 0) throw error;
398122
398823
  return;
398123
398824
  }
398124
- if (!isRecord$7(value) || !hasExactKeys(value, [
398825
+ if (!isRecord$8(value) || !hasExactKeys$1(value, [
398125
398826
  "version",
398126
398827
  "pid",
398127
398828
  "createdAt",
@@ -404358,7 +405059,7 @@ var TUI = class TUI extends Container {
404358
405059
  if (!debugRedraw) return;
404359
405060
  const logPath = path$17.join(nodeOs.homedir(), ".pi", "agent", "pi-debug.log");
404360
405061
  const msg = `[${(/* @__PURE__ */ new Date()).toISOString()}] fullRender: ${reason} (prev=${this.previousLines.length}, new=${newLines.length}, height=${height})\n`;
404361
- fs$16.appendFileSync(logPath, msg);
405062
+ fs$17.appendFileSync(logPath, msg);
404362
405063
  };
404363
405064
  if (this.previousLines.length === 0 && !widthChanged && !heightChanged) {
404364
405065
  logRedraw("first render");
@@ -404505,7 +405206,7 @@ var TUI = class TUI extends Container {
404505
405206
  buffer += "\x1B[?2026l";
404506
405207
  if (process.env["PI_TUI_DEBUG"] === "1") {
404507
405208
  const debugDir = "/tmp/tui";
404508
- fs$16.mkdirSync(debugDir, { recursive: true });
405209
+ fs$17.mkdirSync(debugDir, { recursive: true });
404509
405210
  const debugPath = path$17.join(debugDir, `render-${Date.now()}-${Math.random().toString(36).slice(2)}.log`);
404510
405211
  const debugData = [
404511
405212
  `firstChanged: ${firstChanged}`,
@@ -404529,7 +405230,7 @@ var TUI = class TUI extends Container {
404529
405230
  "=== buffer ===",
404530
405231
  JSON.stringify(buffer)
404531
405232
  ].join("\n");
404532
- fs$16.writeFileSync(debugPath, debugData);
405233
+ fs$17.writeFileSync(debugPath, debugData);
404533
405234
  }
404534
405235
  this.terminal.write(buffer);
404535
405236
  this.cursorRow = Math.max(0, newLines.length - 1);
@@ -409188,7 +409889,7 @@ var ProcessTerminal = class {
409188
409889
  const env = process.env["PI_TUI_WRITE_LOG"] || "";
409189
409890
  if (!env) return "";
409190
409891
  try {
409191
- if (fs$16.statSync(env).isDirectory()) {
409892
+ if (fs$17.statSync(env).isDirectory()) {
409192
409893
  const now = /* @__PURE__ */ new Date();
409193
409894
  const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}_${String(now.getHours()).padStart(2, "0")}-${String(now.getMinutes()).padStart(2, "0")}-${String(now.getSeconds()).padStart(2, "0")}`;
409194
409895
  return path$17.join(env, `tui-${ts}-${process.pid}.log`);
@@ -409471,7 +410172,7 @@ var ProcessTerminal = class {
409471
410172
  write(data) {
409472
410173
  process.stdout.write(data);
409473
410174
  if (this.writeLogPath) try {
409474
- fs$16.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
410175
+ fs$17.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
409475
410176
  } catch {}
409476
410177
  }
409477
410178
  get columns() {
@@ -413799,7 +414500,7 @@ const execFileAsync = promisify(execFile);
413799
414500
  async function scanCodebase(rootInput, options = {}) {
413800
414501
  const root = resolve(rootInput);
413801
414502
  const limits = resolveLimits(options.limits);
413802
- throwIfAborted(options.signal);
414503
+ throwIfAborted$1(options.signal);
413803
414504
  const usedGitIgnore = await isInsideGitWorkTree(root);
413804
414505
  const collected = usedGitIgnore ? await scanWithGit(root, limits, options.signal) : await scanWithoutFilter(root, limits, options.signal);
413805
414506
  const sortedFiles = collected.files.toSorted((a, b) => a.path.localeCompare(b.path));
@@ -413844,13 +414545,13 @@ async function scanWithGit(root, limits, signal) {
413844
414545
  maxBuffer: 1024 * 1024 * 64,
413845
414546
  signal
413846
414547
  });
413847
- throwIfAborted(signal);
414548
+ throwIfAborted$1(signal);
413848
414549
  const relativePaths = splitNull(stdout);
413849
414550
  const files = [];
413850
414551
  let exceedsLimit;
413851
414552
  let totalSize = 0;
413852
414553
  for (const relativePath of relativePaths) {
413853
- throwIfAborted(signal);
414554
+ throwIfAborted$1(signal);
413854
414555
  if (files.length >= limits.maxFiles) {
413855
414556
  exceedsLimit = {
413856
414557
  reason: "file-count",
@@ -413885,11 +414586,11 @@ async function scanWithoutFilter(root, limits, signal) {
413885
414586
  let totalSize = 0;
413886
414587
  async function walk(dir) {
413887
414588
  if (stopped) return;
413888
- throwIfAborted(signal);
414589
+ throwIfAborted$1(signal);
413889
414590
  const entries = await readdir(dir, { withFileTypes: true });
413890
414591
  for (const entry of entries) {
413891
414592
  if (stopped) return;
413892
- throwIfAborted(signal);
414593
+ throwIfAborted$1(signal);
413893
414594
  if (files.length >= limits.maxFiles) {
413894
414595
  exceedsLimit = {
413895
414596
  reason: "file-count",
@@ -413942,7 +414643,7 @@ async function statFile(root, relativePath) {
413942
414643
  mtimeMs: stat.mtimeMs
413943
414644
  };
413944
414645
  }
413945
- function throwIfAborted(signal) {
414646
+ function throwIfAborted$1(signal) {
413946
414647
  if (signal?.aborted) {
413947
414648
  const error = /* @__PURE__ */ new Error("Codebase scan aborted.");
413948
414649
  error.name = "AbortError";
@@ -414950,6 +415651,9 @@ function resolveTelegramBridgeLaunch(bridge, options = {}) {
414950
415651
  }
414951
415652
  };
414952
415653
  }
415654
+ function queueIdentity(stats) {
415655
+ return `${stats.dev}:${stats.ino}:${stats.birthtimeMs}`;
415656
+ }
414953
415657
  function telegramStateDir() {
414954
415658
  return process.env["BLUN_TELEGRAM_STATE_DIR"] ?? join(homedir(), ".blun", "channels", "telegram");
414955
415659
  }
@@ -415021,7 +415725,10 @@ var TelegramChannelController = class {
415021
415725
  activationTimer;
415022
415726
  handoffTimer;
415023
415727
  offset = 0;
415024
- remainder = "";
415728
+ checkpointOffset = 0;
415729
+ queueFileId = "";
415730
+ remainder = Buffer.alloc(0);
415731
+ pendingQueueLines = [];
415025
415732
  started = false;
415026
415733
  stopped = false;
415027
415734
  activeOwner = false;
@@ -415063,6 +415770,9 @@ var TelegramChannelController = class {
415063
415770
  get queueFile() {
415064
415771
  return join(this.dir, "inbound-queue.jsonl");
415065
415772
  }
415773
+ get queueCheckpointFile() {
415774
+ return join(this.dir, "inbound-queue.checkpoint.json");
415775
+ }
415066
415776
  get botPidFile() {
415067
415777
  return join(this.dir, "bot.pid");
415068
415778
  }
@@ -415091,9 +415801,19 @@ var TelegramChannelController = class {
415091
415801
  this.heartbeatTimer = setInterval(() => this.writeLease(), HEARTBEAT_MS);
415092
415802
  this.heartbeatTimer.unref();
415093
415803
  try {
415094
- this.offset = statSync(this.queueFile).size;
415804
+ const stats = statSync(this.queueFile);
415805
+ this.queueFileId = queueIdentity(stats);
415806
+ const checkpoint = this.readQueueCheckpoint();
415807
+ if (checkpoint?.fileId === this.queueFileId && checkpoint.offset >= 0 && checkpoint.offset <= stats.size) this.offset = checkpoint.offset;
415808
+ else {
415809
+ this.offset = stats.size;
415810
+ this.writeQueueCheckpoint(this.offset);
415811
+ }
415812
+ this.checkpointOffset = this.offset;
415095
415813
  } catch {
415096
415814
  this.offset = 0;
415815
+ this.checkpointOffset = 0;
415816
+ this.queueFileId = "";
415097
415817
  }
415098
415818
  this.tailTimer = setInterval(() => this.drainQueue(), TAIL_POLL_MS);
415099
415819
  this.tailTimer.unref();
@@ -415271,24 +415991,34 @@ var TelegramChannelController = class {
415271
415991
  this.loseOwnership();
415272
415992
  return;
415273
415993
  }
415274
- let size;
415994
+ let stats;
415275
415995
  try {
415276
- size = statSync(this.queueFile).size;
415996
+ stats = statSync(this.queueFile);
415277
415997
  } catch {
415278
415998
  return;
415279
415999
  }
415280
- if (size < this.offset) {
416000
+ const size = stats.size;
416001
+ const fileId = queueIdentity(stats);
416002
+ if (this.queueFileId === "") {
416003
+ this.queueFileId = fileId;
416004
+ this.writeQueueCheckpoint(this.checkpointOffset);
416005
+ } else if (fileId !== this.queueFileId || size < this.offset) {
416006
+ this.queueFileId = fileId;
415281
416007
  this.offset = 0;
415282
- this.remainder = "";
416008
+ this.checkpointOffset = 0;
416009
+ this.remainder = Buffer.alloc(0);
416010
+ this.pendingQueueLines.length = 0;
416011
+ this.writeQueueCheckpoint(0);
415283
416012
  }
415284
416013
  if (size === this.offset) return;
415285
416014
  let chunk;
416015
+ const chunkStart = this.offset;
415286
416016
  try {
415287
416017
  const fd = openSync(this.queueFile, "r");
415288
416018
  try {
415289
416019
  const buf = Buffer.alloc(size - this.offset);
415290
416020
  const read = readSync(fd, buf, 0, buf.length, this.offset);
415291
- chunk = buf.subarray(0, read).toString("utf8");
416021
+ chunk = buf.subarray(0, read);
415292
416022
  this.offset += read;
415293
416023
  } finally {
415294
416024
  closeSync(fd);
@@ -415296,11 +416026,54 @@ var TelegramChannelController = class {
415296
416026
  } catch {
415297
416027
  return;
415298
416028
  }
415299
- const lines = (this.remainder + chunk).split("\n");
415300
- this.remainder = lines.pop() ?? "";
415301
- for (const line of lines) {
416029
+ const combinedStart = chunkStart - this.remainder.byteLength;
416030
+ const combined = this.remainder.byteLength === 0 ? chunk : Buffer.concat([this.remainder, chunk]);
416031
+ let lineStart = 0;
416032
+ for (let index = 0; index < combined.byteLength; index += 1) {
416033
+ if (combined[index] !== 10) continue;
416034
+ const line = combined.subarray(lineStart, index).toString("utf8");
416035
+ const pending = {
416036
+ endOffset: combinedStart + index + 1,
416037
+ acknowledged: false
416038
+ };
416039
+ this.pendingQueueLines.push(pending);
415302
416040
  const envelope = parseChannelEnvelope(line);
415303
- if (envelope !== void 0) this.host.inject(envelope);
416041
+ if (envelope === void 0) this.acknowledgeQueueLine(pending);
416042
+ else this.host.inject(envelope, () => this.acknowledgeQueueLine(pending));
416043
+ lineStart = index + 1;
416044
+ }
416045
+ this.remainder = combined.subarray(lineStart);
416046
+ }
416047
+ acknowledgeQueueLine(pending) {
416048
+ if (this.stopped || !this.ownsChannel() || pending.acknowledged) return;
416049
+ pending.acknowledged = true;
416050
+ let nextOffset = this.checkpointOffset;
416051
+ while (this.pendingQueueLines[0]?.acknowledged === true) nextOffset = this.pendingQueueLines.shift().endOffset;
416052
+ if (nextOffset === this.checkpointOffset) return;
416053
+ this.checkpointOffset = nextOffset;
416054
+ this.writeQueueCheckpoint(nextOffset);
416055
+ }
416056
+ readQueueCheckpoint() {
416057
+ try {
416058
+ const parsed = JSON.parse(readFileSync(this.queueCheckpointFile, "utf8"));
416059
+ if (parsed.version === 1 && typeof parsed.fileId === "string" && parsed.fileId.length > 0 && Number.isSafeInteger(parsed.offset) && (parsed.offset ?? -1) >= 0) return parsed;
416060
+ } catch {}
416061
+ }
416062
+ writeQueueCheckpoint(offset) {
416063
+ if (this.queueFileId.length === 0) return;
416064
+ const temporary = join(this.dir, `.inbound-queue.checkpoint.${process.pid}.${this.ownerId}.tmp`);
416065
+ try {
416066
+ const checkpoint = {
416067
+ version: 1,
416068
+ fileId: this.queueFileId,
416069
+ offset
416070
+ };
416071
+ writeFileSync(temporary, `${JSON.stringify(checkpoint)}\n`, { mode: 384 });
416072
+ renameSync(temporary, this.queueCheckpointFile);
416073
+ } catch (error) {
416074
+ this.host.warn(uiText("telegramChannel.leaseWriteFailed", { error: String(error) }));
416075
+ } finally {
416076
+ rmSync(temporary, { force: true });
415304
416077
  }
415305
416078
  }
415306
416079
  /**
@@ -417882,14 +418655,14 @@ function findGoalIndex(file, goalId) {
417882
418655
  return index;
417883
418656
  }
417884
418657
  function isGoalQueueFile(value) {
417885
- if (!isRecord$6(value)) return false;
418658
+ if (!isRecord$7(value)) return false;
417886
418659
  return value["version"] === GOAL_QUEUE_VERSION && Array.isArray(value["goals"]) && value["goals"].every(isUpcomingGoal);
417887
418660
  }
417888
418661
  function isUpcomingGoal(value) {
417889
- if (!isRecord$6(value)) return false;
418662
+ if (!isRecord$7(value)) return false;
417890
418663
  return isNonEmptyString(value["id"]) && isNonEmptyString(value["objective"]) && isNonEmptyString(value["createdAt"]) && isNonEmptyString(value["updatedAt"]);
417891
418664
  }
417892
- function isRecord$6(value) {
418665
+ function isRecord$7(value) {
417893
418666
  return typeof value === "object" && value !== null && !Array.isArray(value);
417894
418667
  }
417895
418668
  function isNonEmptyString(value) {
@@ -417902,7 +418675,7 @@ function timestampAfter(previous) {
417902
418675
  return now.toISOString();
417903
418676
  }
417904
418677
  function isErrno(error, code) {
417905
- return isRecord$6(error) && error["code"] === code;
418678
+ return isRecord$7(error) && error["code"] === code;
417906
418679
  }
417907
418680
  function describeError(error) {
417908
418681
  return error instanceof Error ? error.message : String(error);
@@ -419874,7 +420647,7 @@ function parsePluginMarketplace(raw, location) {
419874
420647
  } catch (error) {
419875
420648
  throw new Error(`Plugin marketplace is not valid JSON: ${formatParseError(error)}`, { cause: error });
419876
420649
  }
419877
- if (!isRecord$5(parsed)) throw new TypeError("Plugin marketplace must be an object.");
420650
+ if (!isRecord$6(parsed)) throw new TypeError("Plugin marketplace must be an object.");
419878
420651
  const rawPlugins = parsed["plugins"];
419879
420652
  if (!Array.isArray(rawPlugins)) throw new TypeError("Plugin marketplace must contain a \"plugins\" array.");
419880
420653
  return {
@@ -419918,7 +420691,7 @@ async function readMarketplaceText(location, fetchImpl) {
419918
420691
  return response.text();
419919
420692
  }
419920
420693
  function parseMarketplaceEntry(value, index, location) {
419921
- if (!isRecord$5(value)) throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`);
420694
+ if (!isRecord$6(value)) throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`);
419922
420695
  const id = requiredString(value, "id", index);
419923
420696
  validateMarketplaceEntryType(value, id);
419924
420697
  const source = stringField$2(value, "source") ?? stringField$2(value, "url") ?? stringField$2(value, "downloadUrl");
@@ -420054,7 +420827,7 @@ function stringArrayField(value, field) {
420054
420827
  const out = raw.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
420055
420828
  return out.length > 0 ? out : void 0;
420056
420829
  }
420057
- function isRecord$5(value) {
420830
+ function isRecord$6(value) {
420058
420831
  return typeof value === "object" && value !== null && !Array.isArray(value);
420059
420832
  }
420060
420833
  function formatParseError(error) {
@@ -487941,10 +488714,10 @@ function parseGoalValue(output) {
487941
488714
  } catch {
487942
488715
  return;
487943
488716
  }
487944
- if (!isRecord$4(parsed) || !("goal" in parsed)) return void 0;
488717
+ if (!isRecord$5(parsed) || !("goal" in parsed)) return void 0;
487945
488718
  const goal = parsed["goal"];
487946
488719
  if (goal === null) return null;
487947
- if (!isRecord$4(goal)) return void 0;
488720
+ if (!isRecord$5(goal)) return void 0;
487948
488721
  return goal;
487949
488722
  }
487950
488723
  function formatGoalStats(goal) {
@@ -487966,7 +488739,7 @@ function stringArg(args, key) {
487966
488739
  const value = args[key];
487967
488740
  return typeof value === "string" && value.length > 0 ? value : void 0;
487968
488741
  }
487969
- function isRecord$4(value) {
488742
+ function isRecord$5(value) {
487970
488743
  return typeof value === "object" && value !== null && !Array.isArray(value);
487971
488744
  }
487972
488745
  function stringField$1(record, key) {
@@ -490832,6 +491605,7 @@ function webSessionUrl(origin, sessionId, token) {
490832
491605
  function dispatchInput(host, text) {
490833
491606
  const parsed = parseSlashInput(text);
490834
491607
  if (parsed !== null) {
491608
+ if (parsed.name === "goal" || parsed.name === "loop") return executeSlashCommand(host, text);
490835
491609
  const isBusy = host.state.appState.streamingPhase !== "idle" || host.state.appState.isCompacting;
490836
491610
  const canRunAlongsideMain = (parsed.name === "btw" || parsed.name === "memory") && !host.state.appState.isCompacting;
490837
491611
  if (host.deferUserMessages || isBusy && !canRunAlongsideMain) {
@@ -491839,6 +492613,320 @@ function formatTurnEndedFailure(event) {
491839
492613
  return `Prompt turn ended with reason: ${event.reason}`;
491840
492614
  }
491841
492615
  //#endregion
492616
+ //#region src/customer-mistake/client-state.ts
492617
+ var CustomerMistakeClientState = class {
492618
+ broker;
492619
+ effectiveStatus = "disabled";
492620
+ generation = 0;
492621
+ preparationController;
492622
+ constructor(broker) {
492623
+ this.broker = broker;
492624
+ }
492625
+ get status() {
492626
+ return this.effectiveStatus;
492627
+ }
492628
+ async prepareHeadless() {
492629
+ const operation = this.beginPreparation();
492630
+ try {
492631
+ const consent = await this.broker.getConsent(operation.controller.signal);
492632
+ if (!this.isCurrent(operation)) return "disabled";
492633
+ this.effectiveStatus = consent.status === "share_sanitized" ? "share_sanitized" : "disabled";
492634
+ } catch {
492635
+ if (this.isCurrent(operation)) this.effectiveStatus = "disabled";
492636
+ } finally {
492637
+ this.finishPreparation(operation);
492638
+ }
492639
+ return this.effectiveStatus;
492640
+ }
492641
+ async prepareInteractive(prompt) {
492642
+ const operation = this.beginPreparation();
492643
+ let persistenceAttempted = false;
492644
+ try {
492645
+ const consent = await this.broker.getConsent(operation.controller.signal);
492646
+ if (!this.isCurrent(operation)) return "disabled";
492647
+ if (consent.status === "share_sanitized") {
492648
+ this.effectiveStatus = "share_sanitized";
492649
+ return this.effectiveStatus;
492650
+ }
492651
+ this.effectiveStatus = "disabled";
492652
+ if (consent.status === "disabled") return this.effectiveStatus;
492653
+ const choice = await prompt();
492654
+ if (!this.isCurrent(operation)) return "disabled";
492655
+ if (choice === "exit") return "exit";
492656
+ if (choice === "cancelled") return "disabled";
492657
+ persistenceAttempted = true;
492658
+ await this.broker.putConsent(choice, operation.controller.signal);
492659
+ if (!this.isCurrent(operation)) return "disabled";
492660
+ const authoritative = await this.broker.getConsent(operation.controller.signal);
492661
+ if (!this.isCurrent(operation)) return "disabled";
492662
+ this.effectiveStatus = choice === "share_sanitized" && authoritative.status === "share_sanitized" ? "share_sanitized" : "disabled";
492663
+ return this.effectiveStatus;
492664
+ } catch {
492665
+ const isCurrent = this.isCurrent(operation);
492666
+ if (isCurrent) this.effectiveStatus = "disabled";
492667
+ return isCurrent && persistenceAttempted ? "persistence_failed" : "disabled";
492668
+ } finally {
492669
+ this.finishPreparation(operation);
492670
+ }
492671
+ }
492672
+ async disable() {
492673
+ this.generation += 1;
492674
+ this.effectiveStatus = "disabled";
492675
+ this.abortPreparation();
492676
+ const controller = new AbortController();
492677
+ this.preparationController = controller;
492678
+ try {
492679
+ await this.broker.putConsent("disabled", controller.signal);
492680
+ } finally {
492681
+ if (this.preparationController === controller) this.preparationController = void 0;
492682
+ }
492683
+ }
492684
+ reset() {
492685
+ this.generation += 1;
492686
+ this.effectiveStatus = "disabled";
492687
+ this.abortPreparation();
492688
+ }
492689
+ beginPreparation() {
492690
+ this.generation += 1;
492691
+ this.effectiveStatus = "disabled";
492692
+ this.abortPreparation();
492693
+ const controller = new AbortController();
492694
+ this.preparationController = controller;
492695
+ return {
492696
+ controller,
492697
+ generation: this.generation
492698
+ };
492699
+ }
492700
+ isCurrent(operation) {
492701
+ return !operation.controller.signal.aborted && operation.generation === this.generation && this.preparationController === operation.controller;
492702
+ }
492703
+ finishPreparation(operation) {
492704
+ if (this.preparationController === operation.controller) this.preparationController = void 0;
492705
+ }
492706
+ abortPreparation() {
492707
+ this.preparationController?.abort();
492708
+ this.preparationController = void 0;
492709
+ }
492710
+ };
492711
+ const MISTAKE_CONSENT_PATH = "/v1/me/mistake/consent";
492712
+ var CustomerMistakeBrokerError = class extends Error {
492713
+ code;
492714
+ status;
492715
+ constructor(code, status) {
492716
+ super(`Customer mistake broker request failed: ${code}.`);
492717
+ this.code = code;
492718
+ this.status = status;
492719
+ this.name = "CustomerMistakeBrokerError";
492720
+ }
492721
+ };
492722
+ function parseMistakeConsent(payload) {
492723
+ if (!isRecord$4(payload) || !hasExactKeys(payload, ["status"])) return void 0;
492724
+ const status = payload["status"];
492725
+ return status === "disabled" || status === "never_asked" || status === "share_sanitized" ? { status } : void 0;
492726
+ }
492727
+ var CustomerMistakeBrokerClient = class {
492728
+ options;
492729
+ baseUrl;
492730
+ fetchImpl;
492731
+ idempotencyKey;
492732
+ timeoutMs;
492733
+ constructor(options) {
492734
+ this.options = options;
492735
+ this.baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://account.blun.ai");
492736
+ this.fetchImpl = options.fetchImpl ?? fetch;
492737
+ this.idempotencyKey = options.idempotencyKey ?? randomUUID;
492738
+ this.timeoutMs = options.timeoutMs ?? 1e4;
492739
+ }
492740
+ async getConsent(signal) {
492741
+ throwIfAborted(signal);
492742
+ const parsed = parseMistakeConsent(await this.request("GET", MISTAKE_CONSENT_PATH, void 0, signal));
492743
+ if (parsed === void 0) throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
492744
+ return parsed;
492745
+ }
492746
+ async putConsent(status, signal) {
492747
+ throwIfAborted(signal);
492748
+ if (status !== "disabled" && status !== "share_sanitized") throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
492749
+ await this.request("POST", ACCOUNT_CONSENT_PATH, { mistake: status === "share_sanitized" }, signal);
492750
+ }
492751
+ async request(method, path, body, signal) {
492752
+ const response = await this.fetchAuthorized(method, path, body, signal);
492753
+ if (!response.ok) throw httpError(response.status);
492754
+ if (response.status === 204) return void 0;
492755
+ const text = await response.text();
492756
+ if (text.trim().length === 0) return void 0;
492757
+ try {
492758
+ return JSON.parse(text);
492759
+ } catch {
492760
+ throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
492761
+ }
492762
+ }
492763
+ async fetchAuthorized(method, path, body, signal) {
492764
+ const idempotencyKey = method === "GET" ? void 0 : this.idempotencyKey();
492765
+ const firstToken = await this.accessToken();
492766
+ let response = await this.fetchWithToken(method, path, body, firstToken, idempotencyKey, signal);
492767
+ if (response.status === 401) {
492768
+ throwIfAborted(signal);
492769
+ const refreshedToken = await this.accessToken({ force: true });
492770
+ throwIfAborted(signal);
492771
+ response = await this.fetchWithToken(method, path, body, refreshedToken, idempotencyKey, signal);
492772
+ }
492773
+ return response;
492774
+ }
492775
+ async accessToken(options) {
492776
+ try {
492777
+ const token = await this.options.tokenProvider.getAccessToken(options);
492778
+ if (token.trim().length === 0) throw new Error("empty account OAuth token");
492779
+ return token;
492780
+ } catch {
492781
+ throw new CustomerMistakeBrokerError("AUTHENTICATION_REQUIRED");
492782
+ }
492783
+ }
492784
+ async fetchWithToken(method, path, body, token, idempotencyKey, signal) {
492785
+ if (signal?.aborted === true) throw new CustomerMistakeBrokerError("CANCELLED");
492786
+ const timeoutController = new AbortController();
492787
+ const timeout = setTimeout(() => {
492788
+ timeoutController.abort();
492789
+ }, this.timeoutMs);
492790
+ timeout.unref?.();
492791
+ const requestSignal = signal === void 0 ? timeoutController.signal : AbortSignal.any([signal, timeoutController.signal]);
492792
+ const headers = new Headers({
492793
+ Accept: "application/json",
492794
+ Authorization: `Bearer ${token}`
492795
+ });
492796
+ if (body !== void 0) headers.set("Content-Type", "application/json");
492797
+ if (idempotencyKey !== void 0) headers.set("Idempotency-Key", idempotencyKey);
492798
+ try {
492799
+ return await this.fetchImpl(`${this.baseUrl}${path}`, {
492800
+ method,
492801
+ headers,
492802
+ body: body === void 0 ? void 0 : JSON.stringify(body),
492803
+ redirect: "error",
492804
+ signal: requestSignal
492805
+ });
492806
+ } catch {
492807
+ throw new CustomerMistakeBrokerError(isAborted(signal) ? "CANCELLED" : "UNAVAILABLE");
492808
+ } finally {
492809
+ clearTimeout(timeout);
492810
+ }
492811
+ }
492812
+ };
492813
+ function throwIfAborted(signal) {
492814
+ if (signal?.aborted === true) throw new CustomerMistakeBrokerError("CANCELLED");
492815
+ }
492816
+ function isAborted(signal) {
492817
+ return signal?.aborted ?? false;
492818
+ }
492819
+ function httpError(status) {
492820
+ if (status === 401) return new CustomerMistakeBrokerError("AUTHENTICATION_REQUIRED", status);
492821
+ if (status === 422) return new CustomerMistakeBrokerError("INVALID_PAYLOAD", status);
492822
+ return new CustomerMistakeBrokerError("UNAVAILABLE", status);
492823
+ }
492824
+ function normalizeBaseUrl(value) {
492825
+ let url;
492826
+ try {
492827
+ url = new URL(value);
492828
+ } catch {
492829
+ throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
492830
+ }
492831
+ if (url.protocol !== "https:" || url.username.length > 0 || url.password.length > 0 || url.search.length > 0 || url.hash.length > 0 || url.pathname !== "/" && url.pathname !== "") throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
492832
+ return url.origin;
492833
+ }
492834
+ function hasExactKeys(value, expected) {
492835
+ const keys = Object.keys(value);
492836
+ return keys.length === expected.length && expected.every((key) => keys.includes(key));
492837
+ }
492838
+ function isRecord$4(value) {
492839
+ return typeof value === "object" && value !== null && !Array.isArray(value);
492840
+ }
492841
+ //#endregion
492842
+ //#region src/customer-mistake/runtime.ts
492843
+ init_src$3();
492844
+ const OFFICIAL_BLUN_API_BASE_URL = "https://api.blun.ai/v1";
492845
+ const OFFICIAL_BLUN_OAUTH_HOST = "https://account.blun.ai";
492846
+ const OFFICIAL_BLUN_OAUTH_KEY = "oauth/blun";
492847
+ async function createCustomerMistakeBrokerClient(harness) {
492848
+ const provider = loadRuntimeConfigSafe(harness.configPath).config.providers[DEFAULT_OAUTH_PROVIDER_NAME];
492849
+ if (provider?.oauth === void 0 || typeof provider.apiKey === "string" && provider.apiKey.trim().length > 0) return void 0;
492850
+ const runtime = resolveBlunCodeRuntimeAuth({
492851
+ configuredBaseUrl: provider.baseUrl,
492852
+ configuredOAuthRef: provider.oauth
492853
+ });
492854
+ if (!isOfficialManagedOAuthRuntime(runtime)) return void 0;
492855
+ let status;
492856
+ try {
492857
+ status = await harness.auth.status(DEFAULT_OAUTH_PROVIDER_NAME);
492858
+ } catch {
492859
+ return;
492860
+ }
492861
+ if (status.providers.find((candidate) => candidate.providerName === "managed:blun")?.hasToken !== true) return void 0;
492862
+ return new CustomerMistakeBrokerClient({ tokenProvider: harness.auth.resolveOAuthTokenProvider(DEFAULT_OAUTH_PROVIDER_NAME, runtime.oauthRef) });
492863
+ }
492864
+ function isOfficialManagedOAuthRuntime(runtime) {
492865
+ return normalizeEndpoint(runtime.baseUrl) === OFFICIAL_BLUN_API_BASE_URL && runtime.oauthRef.key === OFFICIAL_BLUN_OAUTH_KEY && (runtime.oauthRef.oauthHost === void 0 || normalizeEndpoint(runtime.oauthRef.oauthHost) === OFFICIAL_BLUN_OAUTH_HOST);
492866
+ }
492867
+ function normalizeEndpoint(value) {
492868
+ if (value === void 0) return void 0;
492869
+ try {
492870
+ const url = new URL(value);
492871
+ if (url.username.length > 0 || url.password.length > 0 || url.search || url.hash) return;
492872
+ return `${url.origin}${url.pathname.replace(/\/+$/, "")}`;
492873
+ } catch {
492874
+ return;
492875
+ }
492876
+ }
492877
+ //#endregion
492878
+ //#region src/customer-mistake/host-controller.ts
492879
+ /**
492880
+ * Prepared host boundary for TUI and headless CLI. It intentionally exposes
492881
+ * consent state only; contribution POST remains unavailable until the local
492882
+ * provenance catalog and the independent server gates are both proven.
492883
+ */
492884
+ var CustomerMistakeHostController = class {
492885
+ state;
492886
+ epoch = 0;
492887
+ get status() {
492888
+ return this.state?.status ?? "disabled";
492889
+ }
492890
+ async prepareInteractive(harness, prompt, onPersistenceFailed = () => {}) {
492891
+ this.reset();
492892
+ const epoch = this.epoch;
492893
+ const broker = await this.createBroker(harness);
492894
+ if (epoch !== this.epoch || broker === void 0) return "disabled";
492895
+ const state = new CustomerMistakeClientState(broker);
492896
+ this.state = state;
492897
+ const result = await state.prepareInteractive(prompt);
492898
+ if (epoch !== this.epoch) return "disabled";
492899
+ if (result === "persistence_failed") onPersistenceFailed();
492900
+ return result;
492901
+ }
492902
+ async prepareHeadless(harness) {
492903
+ this.reset();
492904
+ const epoch = this.epoch;
492905
+ const broker = await this.createBroker(harness);
492906
+ if (epoch !== this.epoch || broker === void 0) return "disabled";
492907
+ const state = new CustomerMistakeClientState(broker);
492908
+ this.state = state;
492909
+ const result = await state.prepareHeadless();
492910
+ return epoch === this.epoch ? result : "disabled";
492911
+ }
492912
+ async disable() {
492913
+ if (this.state === void 0) return;
492914
+ await this.state.disable();
492915
+ }
492916
+ reset() {
492917
+ this.epoch += 1;
492918
+ this.state?.reset();
492919
+ this.state = void 0;
492920
+ }
492921
+ async createBroker(harness) {
492922
+ try {
492923
+ return await createCustomerMistakeBrokerClient(harness);
492924
+ } catch {
492925
+ return;
492926
+ }
492927
+ }
492928
+ };
492929
+ //#endregion
491842
492930
  //#region src/native/native-require.ts
491843
492931
  function createNativePackageRequire(packageName, options = {}) {
491844
492932
  if (getNativePackageRoot(packageName, options) === null) return null;
@@ -499206,7 +500294,11 @@ var PersonalMemoryController = class {
499206
500294
  host: this.host,
499207
500295
  consentStatus: preparation.consentStatus,
499208
500296
  copy: startupPersonalMemoryConsentCopy(),
499209
- updateSettings: (patch) => client.updateSettings(patch)
500297
+ updateSettings: async (patch) => {
500298
+ if (typeof patch.memory_enabled !== "boolean") throw new Error("Personal memory consent requires an explicit decision.");
500299
+ await client.putConsent(patch.memory_enabled);
500300
+ await client.updateSettings(patch);
500301
+ }
499210
500302
  });
499211
500303
  if (!this.isCurrent(generation, session)) {
499212
500304
  resetPersonalMemorySession();
@@ -503994,6 +505086,7 @@ var FooterComponent = class {
503994
505086
  const key = this.backgroundAgentCount === 1 ? "footer.backgroundAgent.one" : "footer.backgroundAgent.other";
503995
505087
  left.push(chalk.hex(colors.primary)(uiText(key, { count: this.backgroundAgentCount })));
503996
505088
  }
505089
+ const priorityLeftLine = left.join(" ");
503997
505090
  const cwd = shortenCwd(state.workDir);
503998
505091
  if (cwd) left.push(chalk.hex(colors.textDim)(cwd));
503999
505092
  const git = this.gitCache.getStatus();
@@ -504009,7 +505102,8 @@ var FooterComponent = class {
504009
505102
  const pad = width - leftWidth - rightWidth;
504010
505103
  line1 = leftLine + " ".repeat(Math.max(0, pad)) + right;
504011
505104
  } else {
504012
- const shownLeft = truncateToWidth(leftLine, Math.max(0, width - rightWidth - 2), "…");
505105
+ const availLeft = Math.max(0, width - rightWidth - 2);
505106
+ const shownLeft = truncateToWidth(visibleWidth(priorityLeftLine) <= availLeft ? priorityLeftLine : leftLine, availLeft, "…");
504013
505107
  const pad = Math.max(0, width - visibleWidth(shownLeft) - rightWidth);
504014
505108
  line1 = shownLeft + " ".repeat(pad) + right;
504015
505109
  }
@@ -506423,6 +507517,101 @@ var TasksBrowserController = class {
506423
507517
  }
506424
507518
  };
506425
507519
  //#endregion
507520
+ //#region src/tui/startup/customer-mistake-consent.copy.ts
507521
+ registerUiCatalogFragment({
507522
+ en: {
507523
+ "startupCustomerMistake.title": "Improve BLUN from mistakes",
507524
+ "startupCustomerMistake.details": "Share only sanitized, general mistake patterns with BLUN. File paths, credentials, personal data, chat text, and code are not uploaded. This stays off until you enable it.",
507525
+ "startupCustomerMistake.enable": "Share sanitized patterns",
507526
+ "startupCustomerMistake.decline": "Do not share",
507527
+ "startupCustomerMistake.persistenceFailed": "Your choice could not be saved. Sharing remains off."
507528
+ },
507529
+ de: {
507530
+ "startupCustomerMistake.title": "BLUN aus Fehlern verbessern",
507531
+ "startupCustomerMistake.details": "Teile ausschließlich bereinigte, allgemeine Fehlermuster mit BLUN. Dateipfade, Zugangsdaten, personenbezogene Daten, Chattexte und Code werden nicht hochgeladen. Die Funktion bleibt deaktiviert, bis du sie einschaltest.",
507532
+ "startupCustomerMistake.enable": "Bereinigte Muster teilen",
507533
+ "startupCustomerMistake.decline": "Nicht teilen",
507534
+ "startupCustomerMistake.persistenceFailed": "Deine Auswahl konnte nicht gespeichert werden. Das Teilen bleibt deaktiviert."
507535
+ },
507536
+ es: {
507537
+ "startupCustomerMistake.title": "Mejorar BLUN a partir de los errores",
507538
+ "startupCustomerMistake.details": "Comparte con BLUN únicamente patrones generales de errores que hayan sido depurados. No se suben rutas de archivos, credenciales, datos personales, textos de chats ni código. Esta función permanece desactivada hasta que la actives.",
507539
+ "startupCustomerMistake.enable": "Compartir patrones depurados",
507540
+ "startupCustomerMistake.decline": "No compartir",
507541
+ "startupCustomerMistake.persistenceFailed": "No se pudo guardar tu elección. El uso compartido permanece desactivado."
507542
+ },
507543
+ fr: {
507544
+ "startupCustomerMistake.title": "Améliorer BLUN à partir des erreurs",
507545
+ "startupCustomerMistake.details": "Partagez avec BLUN uniquement des schémas d’erreurs généraux et nettoyés. Les chemins de fichiers, identifiants, données personnelles, textes de discussion et extraits de code ne sont pas envoyés. Cette fonction reste désactivée tant que vous ne l’activez pas.",
507546
+ "startupCustomerMistake.enable": "Partager les schémas nettoyés",
507547
+ "startupCustomerMistake.decline": "Ne pas partager",
507548
+ "startupCustomerMistake.persistenceFailed": "Votre choix n’a pas pu être enregistré. Le partage reste désactivé."
507549
+ },
507550
+ sv: {
507551
+ "startupCustomerMistake.title": "Förbättra BLUN med hjälp av misstag",
507552
+ "startupCustomerMistake.details": "Dela endast sanerade, allmänna felmönster med BLUN. Filsökvägar, inloggningsuppgifter, personuppgifter, chattmeddelanden och kod laddas inte upp. Funktionen är avstängd tills du aktiverar den.",
507553
+ "startupCustomerMistake.enable": "Dela sanerade mönster",
507554
+ "startupCustomerMistake.decline": "Dela inte",
507555
+ "startupCustomerMistake.persistenceFailed": "Ditt val kunde inte sparas. Delning förblir avstängd."
507556
+ },
507557
+ cs: {
507558
+ "startupCustomerMistake.title": "Zlepšování BLUN na základě chyb",
507559
+ "startupCustomerMistake.details": "Sdílejte s BLUN pouze očištěné obecné vzorce chyb. Cesty k souborům, přihlašovací údaje, osobní údaje, texty konverzací ani kód se neodesílají. Funkce zůstane vypnutá, dokud ji nezapnete.",
507560
+ "startupCustomerMistake.enable": "Sdílet očištěné vzorce",
507561
+ "startupCustomerMistake.decline": "Nesdílet",
507562
+ "startupCustomerMistake.persistenceFailed": "Vaši volbu se nepodařilo uložit. Sdílení zůstává vypnuté."
507563
+ }
507564
+ });
507565
+ //#endregion
507566
+ //#region src/tui/startup/customer-mistake-consent.ts
507567
+ function startupCustomerMistakeConsentCopy() {
507568
+ return {
507569
+ title: uiText("startupCustomerMistake.title"),
507570
+ details: uiText("startupCustomerMistake.details"),
507571
+ enable: uiText("startupCustomerMistake.enable"),
507572
+ decline: uiText("startupCustomerMistake.decline"),
507573
+ persistenceFailed: uiText("startupCustomerMistake.persistenceFailed")
507574
+ };
507575
+ }
507576
+ function showStartupCustomerMistakePersistenceFailure(host, copy) {
507577
+ host.showWarning(copy.persistenceFailed);
507578
+ }
507579
+ function promptStartupCustomerMistakeConsent(host, copy) {
507580
+ return new Promise((resolve) => {
507581
+ let settled = false;
507582
+ const finish = (choice) => {
507583
+ if (settled) return;
507584
+ settled = true;
507585
+ host.dismissEditorReplacement();
507586
+ resolve(choice);
507587
+ };
507588
+ host.mountEditorReplacement(new ChoicePickerComponent({
507589
+ title: copy.title,
507590
+ currentValue: "disabled",
507591
+ options: [{
507592
+ value: "disabled",
507593
+ label: copy.decline
507594
+ }, {
507595
+ value: "share_sanitized",
507596
+ label: copy.enable,
507597
+ description: copy.details
507598
+ }],
507599
+ onSelect: (value) => {
507600
+ finish(value === "share_sanitized" ? "share_sanitized" : "disabled");
507601
+ },
507602
+ onCancel: () => {
507603
+ finish("cancelled");
507604
+ },
507605
+ onCtrlC: () => {
507606
+ finish("exit");
507607
+ },
507608
+ onCtrlD: () => {
507609
+ finish("exit");
507610
+ }
507611
+ }));
507612
+ });
507613
+ }
507614
+ //#endregion
506426
507615
  //#region src/tui/reverse-rpc/base-controller.ts
506427
507616
  var ReverseRpcController = class {
506428
507617
  uiHooks = null;
@@ -509309,6 +510498,7 @@ var BlunTUI = class {
509309
510498
  editorKeyboard;
509310
510499
  scrollbackController;
509311
510500
  personalMemoryController;
510501
+ customerMistakeController;
509312
510502
  managedQuotaWarningController;
509313
510503
  managedQuotaWarningPersistence = Promise.resolve();
509314
510504
  footerMounted = false;
@@ -509380,6 +510570,7 @@ var BlunTUI = class {
509380
510570
  this.streamingUI = new StreamingUIController(this);
509381
510571
  this.authFlow = new AuthFlowController(this);
509382
510572
  this.personalMemoryController = new PersonalMemoryController(this);
510573
+ this.customerMistakeController = new CustomerMistakeHostController();
509383
510574
  this.btwPanelController = new BtwPanelController(this);
509384
510575
  this.sessionEventHandler = new SessionEventHandler(this);
509385
510576
  this.sessionReplay = new SessionReplayRenderer(this);
@@ -509622,6 +510813,7 @@ var BlunTUI = class {
509622
510813
  if (this.session === void 0 && this.state.startupState !== "picker") return;
509623
510814
  if (this.session !== void 0) {
509624
510815
  await this.refreshPersonalMemory(true);
510816
+ await this.refreshCustomerMistakeConsent();
509625
510817
  await this.authFlow.refreshManagedQuotaWindows();
509626
510818
  }
509627
510819
  this.showTmuxKeyboardWarningIfNeeded();
@@ -510095,6 +511287,7 @@ var BlunTUI = class {
510095
511287
  };
510096
511288
  try {
510097
511289
  if (!(await this.harness.withInteractiveAgent(item.agentId ?? "main", () => session.steerActive(input, expectedTurnId === void 0 ? {} : { expectedTurnId }))).accepted) return restoreHead();
511290
+ item.channelAcknowledge?.();
510098
511291
  } catch (error) {
510099
511292
  return restoreHead(error);
510100
511293
  }
@@ -510236,12 +511429,12 @@ var BlunTUI = class {
510236
511429
  * queuedMessages mechanic as typed input; a completed tool/step boundary
510237
511430
  * steers one FIFO head into the active turn without interrupting it.
510238
511431
  */
510239
- injectChannelMessage(envelope) {
511432
+ injectChannelMessage(envelope, acknowledge) {
510240
511433
  injectChannelEnvelope({
510241
511434
  canDeliver: () => this.session !== void 0 && this.state.appState.model.trim().length > 0,
510242
511435
  isBusy: () => this.state.queuedMessages.length > 0 || this.queueSteerInFlight !== void 0 || this.deferUserMessages || this.state.appState.streamingPhase !== "idle" || this.state.appState.isCompacting,
510243
511436
  deliverNow: (modelInput, displayText, origin, contextOnly) => {
510244
- this.sendChannelMessageInternal(this.requireSession(), modelInput, displayText, origin, envelope.meta.chat_id, envelope.meta["image_path"], contextOnly);
511437
+ this.sendChannelMessageInternal(this.requireSession(), modelInput, displayText, origin, envelope.meta.chat_id, envelope.meta["image_path"], contextOnly, false, acknowledge);
510245
511438
  },
510246
511439
  enqueue: (modelInput, displayText, origin, contextOnly) => {
510247
511440
  this.state.queuedMessages.push({
@@ -510252,6 +511445,7 @@ var BlunTUI = class {
510252
511445
  mode: "channel",
510253
511446
  channelChatId: envelope.meta.chat_id,
510254
511447
  channelContextOnly: contextOnly,
511448
+ channelAcknowledge: acknowledge,
510255
511449
  ...envelope.meta["image_path"] !== void 0 ? { channelImagePath: envelope.meta["image_path"] } : {}
510256
511450
  });
510257
511451
  this.syncChannelQueueDeadline();
@@ -510268,6 +511462,7 @@ var BlunTUI = class {
510268
511462
  content: displayText,
510269
511463
  origin
510270
511464
  });
511465
+ acknowledge?.();
510271
511466
  this.state.ui.requestRender();
510272
511467
  },
510273
511468
  reportUndeliverable: (reason) => {
@@ -510275,7 +511470,7 @@ var BlunTUI = class {
510275
511470
  }
510276
511471
  }, envelope, this.channelPreamble);
510277
511472
  }
510278
- sendChannelMessageInternal(session, modelInput, displayText, origin, channelChatId, channelImagePath, contextOnly = false, transcriptRendered = false) {
511473
+ sendChannelMessageInternal(session, modelInput, displayText, origin, channelChatId, channelImagePath, contextOnly = false, transcriptRendered = false, acknowledge) {
510279
511474
  if (!transcriptRendered) this.appendTranscriptEntry({
510280
511475
  id: nextTranscriptId(),
510281
511476
  kind: "user",
@@ -510285,12 +511480,14 @@ var BlunTUI = class {
510285
511480
  origin
510286
511481
  });
510287
511482
  this.beginSessionRequest();
510288
- if (channelChatId !== void 0) this.pendingChannelReplyGuard = {
511483
+ const previousGuard = this.pendingChannelReplyGuard;
511484
+ const installedGuard = channelChatId === void 0 ? void 0 : {
510289
511485
  chatId: channelChatId,
510290
511486
  outboxMarker: outboxMarker(),
510291
511487
  transcriptStart: this.state.transcriptEntries.length,
510292
511488
  contextOnly
510293
511489
  };
511490
+ if (installedGuard !== void 0) this.pendingChannelReplyGuard = installedGuard;
510294
511491
  const imagePart = channelImagePath !== void 0 ? buildChannelImagePart(channelImagePath) : void 0;
510295
511492
  const visionReaderEnabled = isExperimentalFlagEnabled("vision_reader");
510296
511493
  this.setAppState({
@@ -510301,7 +511498,29 @@ var BlunTUI = class {
510301
511498
  type: "text",
510302
511499
  text: modelInput
510303
511500
  }, imagePart] : modelInput;
510304
- session.promptAccepted(promptInput).catch((error) => {
511501
+ session.promptAccepted(promptInput).then((result) => {
511502
+ if (result.accepted) {
511503
+ acknowledge?.();
511504
+ return;
511505
+ }
511506
+ if (installedGuard !== void 0 && this.pendingChannelReplyGuard === installedGuard) this.pendingChannelReplyGuard = previousGuard;
511507
+ this.state.queuedMessages = [{
511508
+ text: modelInput,
511509
+ displayText,
511510
+ origin,
511511
+ agentId: this.harness.interactiveAgentId,
511512
+ mode: "channel",
511513
+ channelChatId,
511514
+ channelContextOnly: contextOnly,
511515
+ channelTranscriptRendered: true,
511516
+ channelAcknowledge: acknowledge,
511517
+ ...channelImagePath === void 0 ? {} : { channelImagePath }
511518
+ }, ...this.state.queuedMessages];
511519
+ this.syncChannelQueueDeadline();
511520
+ this.track("input_queue");
511521
+ this.updateQueueDisplay();
511522
+ this.state.ui.requestRender();
511523
+ }).catch((error) => {
510305
511524
  this.failSessionRequest(uiText("blunTui.session.sendFailed", { error: formatErrorMessage$2(error) }));
510306
511525
  });
510307
511526
  this.updateQueueDisplay();
@@ -510345,8 +511564,8 @@ var BlunTUI = class {
510345
511564
  }
510346
511565
  let controller;
510347
511566
  controller = new TelegramChannelController({
510348
- inject: (envelope) => {
510349
- this.injectChannelMessage(envelope);
511567
+ inject: (envelope, acknowledge) => {
511568
+ this.injectChannelMessage(envelope, acknowledge);
510350
511569
  },
510351
511570
  warn: (message) => {
510352
511571
  this.showStatus(message, "warning");
@@ -510470,7 +511689,7 @@ var BlunTUI = class {
510470
511689
  const activeSession = this.session ?? session;
510471
511690
  if (item.mode === "channel") {
510472
511691
  this.harness.withInteractiveAgent(item.agentId ?? "main", () => {
510473
- this.sendChannelMessageInternal(activeSession, item.text, item.displayText ?? "", item.origin, item.channelChatId, item.channelImagePath, item.channelContextOnly, item.channelTranscriptRendered);
511692
+ this.sendChannelMessageInternal(activeSession, item.text, item.displayText ?? "", item.origin, item.channelChatId, item.channelImagePath, item.channelContextOnly, item.channelTranscriptRendered, item.channelAcknowledge);
510474
511693
  });
510475
511694
  return;
510476
511695
  }
@@ -510654,6 +511873,21 @@ var BlunTUI = class {
510654
511873
  async refreshPersonalMemory(promptIfNeverAsked = false) {
510655
511874
  await this.personalMemoryController.refresh({ promptIfNeverAsked });
510656
511875
  }
511876
+ async refreshCustomerMistakeConsent() {
511877
+ const copy = startupCustomerMistakeConsentCopy();
511878
+ const host = {
511879
+ mountEditorReplacement: (panel) => {
511880
+ this.mountEditorReplacement(panel);
511881
+ },
511882
+ dismissEditorReplacement: () => {
511883
+ this.dismissEditorReplacement();
511884
+ },
511885
+ showWarning: (message) => {
511886
+ this.showStatus(message, "warning");
511887
+ }
511888
+ };
511889
+ await this.customerMistakeController.prepareInteractive(this.harness, () => promptStartupCustomerMistakeConsent(host, copy), () => showStartupCustomerMistakePersistenceFailure(host, copy));
511890
+ }
510657
511891
  patchLivePane(patch) {
510658
511892
  if (!hasPatchChanges(this.state.livePane, patch)) return;
510659
511893
  Object.assign(this.state.livePane, patch);
@@ -510814,7 +512048,7 @@ var BlunTUI = class {
510814
512048
  streamingPhase: "idle"
510815
512049
  });
510816
512050
  if (!this.preserveQueueAcrossSessionReset) {
510817
- this.state.queuedMessages = [];
512051
+ this.state.queuedMessages = this.state.queuedMessages.filter((item) => item.mode === "channel");
510818
512052
  this.queueFlushBatchRemaining = 0;
510819
512053
  this.queueSteerInFlight = void 0;
510820
512054
  }
@@ -511800,6 +513034,7 @@ var BlunTUI = class {
511800
513034
  this.hideSessionPicker();
511801
513035
  if (applyStartupModes) {
511802
513036
  await this.refreshPersonalMemory(true);
513037
+ await this.refreshCustomerMistakeConsent();
511803
513038
  await this.authFlow.refreshManagedQuotaWindows();
511804
513039
  await this.promptStartupResumeGoalIfNeeded();
511805
513040
  }