blun-king-cli 9.1.613 → 9.1.615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/blun.mjs CHANGED
@@ -1,27 +1,28 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:5c7277a864ffcc0a6909494ad5ada6956f900fe23735200c5aca26b1e7d78834
2
+ // BLUN_BUILD_INPUT_SHA256:57a7160081cd6a2ce9e3535b31b87f9410c0dafd58da9629b68cb0042a8e57e5
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, createHmac, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
9
- import * as fs$17 from "node:fs";
9
+ import * as fs$16 from "node:fs";
10
10
  import Kt, { accessSync, appendFileSync, chmodSync, closeSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, opendirSync, promises, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
11
- import * as path$17 from "node:path";
11
+ import * as path$16 from "node:path";
12
12
  import path, { basename, dirname, extname, isAbsolute, join, normalize, parse, 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
- import fs, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
14
+ import ro, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
15
15
  import * as nodeOs from "node:os";
16
16
  import os, { arch, homedir, hostname, networkInterfaces, platform, release, tmpdir, type, userInfo } from "node:os";
17
17
  import { execFile, execFileSync, execSync, spawn, spawnSync } from "node:child_process";
18
18
  import { Worker } from "node:worker_threads";
19
19
  import * as sysPath from "path";
20
- import path$1, { basename as basename$1, dirname as dirname$1, join as join$1, parse as parse$1 } from "path";
20
+ import js, { basename as basename$1, dirname as dirname$1, join as join$1, parse as parse$1 } from "path";
21
21
  import I, { existsSync as existsSync$1, promises as promises$1, readdirSync as readdirSync$1, stat as stat$1, statSync as statSync$1, unwatchFile, watch, watchFile } from "fs";
22
22
  import { Readable } from "stream";
23
23
  import zi from "assert";
24
24
  import Qr, { EventEmitter } from "events";
25
+ import { StringDecoder } from "node:string_decoder";
25
26
  import { lstat as lstat$1, open as open$1, readdir as readdir$1, realpath as realpath$1, stat as stat$2 } from "fs/promises";
26
27
  import Cs, { PassThrough, Readable as Readable$1, Writable, pipeline } from "node:stream";
27
28
  import { homedir as homedir$1, type as type$1 } from "os";
@@ -37,7 +38,6 @@ import * as win32Path from "node:path/win32";
37
38
  import { createServer } from "node:http";
38
39
  import { pipeline as pipeline$1 } from "node:stream/promises";
39
40
  import { EventEmitter as EventEmitter$1 } from "node:events";
40
- import { StringDecoder } from "node:string_decoder";
41
41
  import co from "node:assert";
42
42
  import { fileURLToPath, pathToFileURL } from "node:url";
43
43
  import { QuickJSAsyncWASMModule, RELEASE_ASYNC, newQuickJSAsyncWASMModule, shouldInterruptAfterDeadline } from "quickjs-emscripten";
@@ -2271,11 +2271,11 @@ var init_blun_files = __esmMin((() => {
2271
2271
  async uploadVideo(input, options) {
2272
2272
  let file;
2273
2273
  if (typeof input === "string") {
2274
- if (!fs$17.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2275
- const filename = path$17.basename(input);
2274
+ if (!fs$16.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2275
+ const filename = path$16.basename(input);
2276
2276
  const mimeType = guessMimeTypeFromExt(filename);
2277
2277
  if (mimeType === void 0 || !mimeType.startsWith("video/")) throw new ChatProviderError(`BlunFiles.uploadVideo: file extension does not indicate a video type: ${filename}`);
2278
- const data = await fs$17.promises.readFile(input);
2278
+ const data = await fs$16.promises.readFile(input);
2279
2279
  file = new File$1([new Blob$1([new Uint8Array(data)], { type: mimeType })], filename, { type: mimeType });
2280
2280
  } else {
2281
2281
  if (!input.mimeType.startsWith("video/")) throw new ChatProviderError(`Expected a video mime type, got ${input.mimeType}`);
@@ -2658,12 +2658,22 @@ function collectBlunVisionAttachments(messages) {
2658
2658
  }
2659
2659
  return attachments;
2660
2660
  }
2661
- function estimateBlunRequestExtraBytes(tools, messages) {
2662
- const attachments = collectBlunVisionAttachments(messages);
2663
- return {
2664
- toolsBytes: tools.length === 0 ? 0 : Buffer.byteLength(JSON.stringify({ tools: tools.map(convertTool) }), "utf8"),
2665
- visionBytes: attachments.length === 0 ? 0 : Buffer.byteLength(JSON.stringify({ visionAttachments: attachments }), "utf8")
2666
- };
2661
+ function estimateBlunSerializedBodyBytes(systemPrompt, tools, history) {
2662
+ const normalizedHistory = normalizeToolCallIdsForProvider([...history], BLUN_TOOL_CALL_ID_POLICY);
2663
+ const messages = systemPrompt ? [{
2664
+ role: "system",
2665
+ content: systemPrompt
2666
+ }] : [];
2667
+ for (const message of normalizedHistory) if (!isEmptyAssistantHistoryMessage(message)) messages.push(convertMessage(message));
2668
+ const attachments = collectBlunVisionAttachments(normalizedHistory);
2669
+ return Buffer.byteLength(JSON.stringify({
2670
+ model: "king",
2671
+ messages,
2672
+ stream: true,
2673
+ ...tools.length > 0 ? { tools: tools.map(convertTool) } : {},
2674
+ ...attachments.length > 0 ? { visionAttachments: attachments } : {},
2675
+ stream_options: { include_usage: true }
2676
+ }), "utf8");
2667
2677
  }
2668
2678
  function convertMessage(message) {
2669
2679
  let reasoningContent = "";
@@ -11949,7 +11959,7 @@ var require_clone$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11949
11959
  //#endregion
11950
11960
  //#region ../../node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js
11951
11961
  var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11952
- var fs$16 = __require("fs");
11962
+ var fs$15 = __require("fs");
11953
11963
  var polyfills = require_polyfills();
11954
11964
  var legacy = require_legacy_streams();
11955
11965
  var clone = require_clone$1();
@@ -11978,36 +11988,36 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11978
11988
  m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
11979
11989
  console.error(m);
11980
11990
  };
11981
- if (!fs$16[gracefulQueue]) {
11982
- publishQueue(fs$16, global[gracefulQueue] || []);
11983
- fs$16.close = (function(fs$close) {
11991
+ if (!fs$15[gracefulQueue]) {
11992
+ publishQueue(fs$15, global[gracefulQueue] || []);
11993
+ fs$15.close = (function(fs$close) {
11984
11994
  function close(fd, cb) {
11985
- return fs$close.call(fs$16, fd, function(err) {
11995
+ return fs$close.call(fs$15, fd, function(err) {
11986
11996
  if (!err) resetQueue();
11987
11997
  if (typeof cb === "function") cb.apply(this, arguments);
11988
11998
  });
11989
11999
  }
11990
12000
  Object.defineProperty(close, previousSymbol, { value: fs$close });
11991
12001
  return close;
11992
- })(fs$16.close);
11993
- fs$16.closeSync = (function(fs$closeSync) {
12002
+ })(fs$15.close);
12003
+ fs$15.closeSync = (function(fs$closeSync) {
11994
12004
  function closeSync(fd) {
11995
- fs$closeSync.apply(fs$16, arguments);
12005
+ fs$closeSync.apply(fs$15, arguments);
11996
12006
  resetQueue();
11997
12007
  }
11998
12008
  Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync });
11999
12009
  return closeSync;
12000
- })(fs$16.closeSync);
12010
+ })(fs$15.closeSync);
12001
12011
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) process.on("exit", function() {
12002
- debug(fs$16[gracefulQueue]);
12003
- __require("assert").equal(fs$16[gracefulQueue].length, 0);
12012
+ debug(fs$15[gracefulQueue]);
12013
+ __require("assert").equal(fs$15[gracefulQueue].length, 0);
12004
12014
  });
12005
12015
  }
12006
- if (!global[gracefulQueue]) publishQueue(global, fs$16[gracefulQueue]);
12007
- module.exports = patch(clone(fs$16));
12008
- if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$16.__patched) {
12009
- module.exports = patch(fs$16);
12010
- fs$16.__patched = true;
12016
+ if (!global[gracefulQueue]) publishQueue(global, fs$15[gracefulQueue]);
12017
+ module.exports = patch(clone(fs$15));
12018
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$15.__patched) {
12019
+ module.exports = patch(fs$15);
12020
+ fs$15.__patched = true;
12011
12021
  }
12012
12022
  function patch(fs) {
12013
12023
  polyfills(fs);
@@ -12262,23 +12272,23 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12262
12272
  }
12263
12273
  function enqueue(elem) {
12264
12274
  debug("ENQUEUE", elem[0].name, elem[1]);
12265
- fs$16[gracefulQueue].push(elem);
12275
+ fs$15[gracefulQueue].push(elem);
12266
12276
  retry();
12267
12277
  }
12268
12278
  var retryTimer;
12269
12279
  function resetQueue() {
12270
12280
  var now = Date.now();
12271
- for (var i = 0; i < fs$16[gracefulQueue].length; ++i) if (fs$16[gracefulQueue][i].length > 2) {
12272
- fs$16[gracefulQueue][i][3] = now;
12273
- fs$16[gracefulQueue][i][4] = now;
12281
+ for (var i = 0; i < fs$15[gracefulQueue].length; ++i) if (fs$15[gracefulQueue][i].length > 2) {
12282
+ fs$15[gracefulQueue][i][3] = now;
12283
+ fs$15[gracefulQueue][i][4] = now;
12274
12284
  }
12275
12285
  retry();
12276
12286
  }
12277
12287
  function retry() {
12278
12288
  clearTimeout(retryTimer);
12279
12289
  retryTimer = void 0;
12280
- if (fs$16[gracefulQueue].length === 0) return;
12281
- var elem = fs$16[gracefulQueue].shift();
12290
+ if (fs$15[gracefulQueue].length === 0) return;
12291
+ var elem = fs$15[gracefulQueue].shift();
12282
12292
  var fn = elem[0];
12283
12293
  var args = elem[1];
12284
12294
  var err = elem[2];
@@ -12297,7 +12307,7 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12297
12307
  if (sinceAttempt >= Math.min(sinceStart * 1.2, 100)) {
12298
12308
  debug("RETRY", fn.name, args);
12299
12309
  fn.apply(null, args.concat([startTime]));
12300
- } else fs$16[gracefulQueue].push(elem);
12310
+ } else fs$15[gracefulQueue].push(elem);
12301
12311
  }
12302
12312
  if (retryTimer === void 0) retryTimer = setTimeout(retry, 0);
12303
12313
  }
@@ -12649,7 +12659,7 @@ var require_mtime_precision = /* @__PURE__ */ __commonJSMin(((exports, module) =
12649
12659
  //#endregion
12650
12660
  //#region ../../node_modules/.pnpm/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js
12651
12661
  var require_lockfile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12652
- const path$16 = __require("path");
12662
+ const path$15 = __require("path");
12653
12663
  const fs = require_graceful_fs();
12654
12664
  const retry = require_retry$3();
12655
12665
  const onExit = require_signal_exit();
@@ -12659,7 +12669,7 @@ var require_lockfile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12659
12669
  return options.lockfilePath || `${file}.lock`;
12660
12670
  }
12661
12671
  function resolveCanonicalPath(file, options, callback) {
12662
- if (!options.realpath) return callback(null, path$16.resolve(file));
12672
+ if (!options.realpath) return callback(null, path$15.resolve(file));
12663
12673
  options.fs.realpath(file, callback);
12664
12674
  }
12665
12675
  function acquireLock(file, options, callback) {
@@ -15175,7 +15185,7 @@ async function syncDir(dirPath) {
15175
15185
  */
15176
15186
  function syncFd(fd) {
15177
15187
  return new Promise((resolve, reject) => {
15178
- fs$17.fsync(fd, (err) => {
15188
+ fs$16.fsync(fd, (err) => {
15179
15189
  if (err) {
15180
15190
  reject(err);
15181
15191
  return;
@@ -22286,6 +22296,31 @@ var init_instruction_provenance = __esmMin((() => {
22286
22296
  get content() {
22287
22297
  return this.pieces.map((piece) => piece.text).join("");
22288
22298
  }
22299
+ prefixUtf8(maxBytes) {
22300
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) throw new RangeError("Invalid instruction byte budget");
22301
+ const kept = [];
22302
+ let remaining = maxBytes;
22303
+ let totalBytes = 0;
22304
+ let readBytes = 0;
22305
+ for (const piece of this.pieces) {
22306
+ const encoded = Buffer.from(piece.text, "utf8");
22307
+ totalBytes += encoded.length;
22308
+ if (remaining <= 0) continue;
22309
+ const content = encoded.length <= remaining ? piece.text : new StringDecoder("utf8").write(encoded.subarray(0, remaining));
22310
+ const bytes = Buffer.byteLength(content, "utf8");
22311
+ if (content.length > 0) kept.push({
22312
+ ...piece,
22313
+ text: content
22314
+ });
22315
+ readBytes += bytes;
22316
+ remaining -= bytes;
22317
+ if (bytes < encoded.length) remaining = 0;
22318
+ }
22319
+ return {
22320
+ text: new InstructionText(kept, new Map(this.sources)),
22321
+ omittedBytes: totalBytes - readBytes
22322
+ };
22323
+ }
22289
22324
  replaceFirst(needle, replacement) {
22290
22325
  const start = this.content.indexOf(needle);
22291
22326
  if (start >= 0) this.replaceRange(start, start + needle.length, replacement);
@@ -22339,6 +22374,64 @@ var init_instruction_provenance = __esmMin((() => {
22339
22374
  }));
22340
22375
  //#endregion
22341
22376
  //#region ../../packages/agent-core/src/profile/context.ts
22377
+ function fitAgentsMdContext(context, maxFixedRequestBytes, measureFixedRequestBytes) {
22378
+ if (!Number.isSafeInteger(maxFixedRequestBytes) || maxFixedRequestBytes <= 0) throw new RangeError("Invalid fixed request byte budget");
22379
+ const originalBytes = measureFixedRequestBytes(context);
22380
+ if (originalBytes <= maxFixedRequestBytes) return {
22381
+ context,
22382
+ fixedRequestBytes: originalBytes,
22383
+ omittedBytes: 0,
22384
+ fits: true
22385
+ };
22386
+ const source = context.agentsMdText;
22387
+ if (source === void 0) return {
22388
+ context,
22389
+ fixedRequestBytes: originalBytes,
22390
+ omittedBytes: 0,
22391
+ fits: false
22392
+ };
22393
+ const totalBytes = source.measure().totalBytes;
22394
+ const candidateAt = (maxBytes) => {
22395
+ const { text } = source.prefixUtf8(maxBytes);
22396
+ return {
22397
+ ...context,
22398
+ agentsMd: text.content,
22399
+ agentsMdSources: text.measure(),
22400
+ agentsMdText: text
22401
+ };
22402
+ };
22403
+ let low = 0;
22404
+ let high = totalBytes;
22405
+ let fitted = candidateAt(0);
22406
+ let fittedBytes = measureFixedRequestBytes(fitted);
22407
+ if (fittedBytes > maxFixedRequestBytes) {
22408
+ const omittedBytes = context.agentsMdSources?.files.reduce((sum, file) => sum + file.bytes, 0) ?? totalBytes;
22409
+ return {
22410
+ context: fitted,
22411
+ fixedRequestBytes: fittedBytes,
22412
+ omittedBytes,
22413
+ fits: false
22414
+ };
22415
+ }
22416
+ while (low < high) {
22417
+ const middle = Math.ceil((low + high) / 2);
22418
+ const candidate = candidateAt(middle);
22419
+ const bytes = measureFixedRequestBytes(candidate);
22420
+ if (bytes <= maxFixedRequestBytes) {
22421
+ low = middle;
22422
+ fitted = candidate;
22423
+ fittedBytes = bytes;
22424
+ } else high = middle - 1;
22425
+ }
22426
+ const omittedBytes = context.agentsMdSources?.files.reduce((sum, file) => sum + file.bytes, 0) ?? totalBytes;
22427
+ const retainedBytes = fitted.agentsMdSources?.files.reduce((sum, file) => sum + file.bytes, 0) ?? 0;
22428
+ return {
22429
+ context: fitted,
22430
+ fixedRequestBytes: fittedBytes,
22431
+ omittedBytes: omittedBytes - retainedBytes,
22432
+ fits: true
22433
+ };
22434
+ }
22342
22435
  async function prepareSystemPromptContext(kaos, brandHome, options) {
22343
22436
  const additionalDirs = normalizeAdditionalDirs(options?.additionalDirs ?? []);
22344
22437
  const [cwdListing, agentsMdResult, additionalDirsInfo] = await Promise.all([
@@ -22351,7 +22444,8 @@ async function prepareSystemPromptContext(kaos, brandHome, options) {
22351
22444
  agentsMd: agentsMdResult.content,
22352
22445
  additionalDirsInfo,
22353
22446
  agentsMdWarning: agentsMdResult.warning,
22354
- agentsMdSources: agentsMdResult.sources
22447
+ agentsMdSources: agentsMdResult.sources,
22448
+ agentsMdText: agentsMdResult.text
22355
22449
  };
22356
22450
  }
22357
22451
  async function loadAgentsMd(kaos, brandHome) {
@@ -22405,6 +22499,7 @@ async function loadAgentsMdForRoots(kaos, brandHome, workDirs) {
22405
22499
  return {
22406
22500
  content,
22407
22501
  warning: totalBytes > AGENTS_MD_RECOMMENDED_MAX_BYTES ? `AGENTS.md total ${formatKB(totalBytes)} KB exceeds the recommended ${formatKB(AGENTS_MD_RECOMMENDED_MAX_BYTES)} KB. Large instruction files increase cost and may impact performance; consider trimming.` : void 0,
22502
+ text: rendered,
22408
22503
  sources: {
22409
22504
  ...rendered.measure(),
22410
22505
  ...notLoadedCandidates.size === 0 ? {} : { notLoadedCandidates: [...notLoadedCandidates] }
@@ -26140,7 +26235,7 @@ var require_loader = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26140
26235
  };
26141
26236
  return _setPrototypeOf(o, p);
26142
26237
  }
26143
- var path$15 = __require("path");
26238
+ var path$14 = __require("path");
26144
26239
  module.exports = /* @__PURE__ */ function(_EmitterObj) {
26145
26240
  _inheritsLoose(Loader, _EmitterObj);
26146
26241
  function Loader() {
@@ -26148,7 +26243,7 @@ var require_loader = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26148
26243
  }
26149
26244
  var _proto = Loader.prototype;
26150
26245
  _proto.resolve = function resolve(from, to) {
26151
- return path$15.resolve(path$15.dirname(from), to);
26246
+ return path$14.resolve(path$14.dirname(from), to);
26152
26247
  };
26153
26248
  _proto.isRelative = function isRelative(filename) {
26154
26249
  return filename.indexOf("./") === 0 || filename.indexOf("../") === 0;
@@ -27804,8 +27899,8 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27804
27899
  };
27805
27900
  return _setPrototypeOf(o, p);
27806
27901
  }
27807
- var fs$15 = __require("fs");
27808
- var path$14 = __require("path");
27902
+ var fs$14 = __require("fs");
27903
+ var path$13 = __require("path");
27809
27904
  var Loader = require_loader();
27810
27905
  var PrecompiledLoader = require_precompiled_loader().PrecompiledLoader;
27811
27906
  var chokidar;
@@ -27820,7 +27915,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27820
27915
  _this.noCache = !!opts.noCache;
27821
27916
  if (searchPaths) {
27822
27917
  searchPaths = Array.isArray(searchPaths) ? searchPaths : [searchPaths];
27823
- _this.searchPaths = searchPaths.map(path$14.normalize);
27918
+ _this.searchPaths = searchPaths.map(path$13.normalize);
27824
27919
  } else _this.searchPaths = ["."];
27825
27920
  if (opts.watch) {
27826
27921
  try {
@@ -27828,10 +27923,10 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27828
27923
  } catch (e) {
27829
27924
  throw new Error("watch requires chokidar to be installed");
27830
27925
  }
27831
- var paths = _this.searchPaths.filter(fs$15.existsSync);
27926
+ var paths = _this.searchPaths.filter(fs$14.existsSync);
27832
27927
  var watcher = chokidar.watch(paths);
27833
27928
  watcher.on("all", function(event, fullname) {
27834
- fullname = path$14.resolve(fullname);
27929
+ fullname = path$13.resolve(fullname);
27835
27930
  if (event === "change" && fullname in _this.pathsToNames) _this.emit("update", _this.pathsToNames[fullname], fullname);
27836
27931
  });
27837
27932
  watcher.on("error", function(error) {
@@ -27845,9 +27940,9 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27845
27940
  var fullpath = null;
27846
27941
  var paths = this.searchPaths;
27847
27942
  for (var i = 0; i < paths.length; i++) {
27848
- var basePath = path$14.resolve(paths[i]);
27849
- var p = path$14.resolve(paths[i], name);
27850
- if (p.indexOf(basePath) === 0 && fs$15.existsSync(p)) {
27943
+ var basePath = path$13.resolve(paths[i]);
27944
+ var p = path$13.resolve(paths[i], name);
27945
+ if (p.indexOf(basePath) === 0 && fs$14.existsSync(p)) {
27851
27946
  fullpath = p;
27852
27947
  break;
27853
27948
  }
@@ -27855,7 +27950,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27855
27950
  if (!fullpath) return null;
27856
27951
  this.pathsToNames[fullpath] = name;
27857
27952
  var source = {
27858
- src: fs$15.readFileSync(fullpath, "utf-8"),
27953
+ src: fs$14.readFileSync(fullpath, "utf-8"),
27859
27954
  path: fullpath,
27860
27955
  noCache: this.noCache
27861
27956
  };
@@ -27903,7 +27998,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27903
27998
  }
27904
27999
  this.pathsToNames[fullpath] = name;
27905
28000
  var source = {
27906
- src: fs$15.readFileSync(fullpath, "utf-8"),
28001
+ src: fs$14.readFileSync(fullpath, "utf-8"),
27907
28002
  path: fullpath,
27908
28003
  noCache: this.noCache
27909
28004
  };
@@ -28205,13 +28300,13 @@ var require_globals = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28205
28300
  //#endregion
28206
28301
  //#region ../../node_modules/.pnpm/nunjucks@3.2.4_chokidar@4.0.3/node_modules/nunjucks/src/express-app.js
28207
28302
  var require_express_app = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28208
- var path$13 = __require("path");
28303
+ var path$12 = __require("path");
28209
28304
  module.exports = function express(env, app) {
28210
28305
  function NunjucksView(name, opts) {
28211
28306
  this.name = name;
28212
28307
  this.path = name;
28213
28308
  this.defaultEngine = opts.defaultEngine;
28214
- this.ext = path$13.extname(name);
28309
+ this.ext = path$12.extname(name);
28215
28310
  if (!this.ext && !this.defaultEngine) throw new Error("No default engine was specified and no extension was provided.");
28216
28311
  if (!this.ext) this.name += this.ext = (this.defaultEngine[0] !== "." ? "." : "") + this.defaultEngine;
28217
28312
  }
@@ -28647,8 +28742,8 @@ var require_precompile_global = /* @__PURE__ */ __commonJSMin(((exports, module)
28647
28742
  //#endregion
28648
28743
  //#region ../../node_modules/.pnpm/nunjucks@3.2.4_chokidar@4.0.3/node_modules/nunjucks/src/precompile.js
28649
28744
  var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28650
- var fs$14 = __require("fs");
28651
- var path$12 = __require("path");
28745
+ var fs$13 = __require("fs");
28746
+ var path$11 = __require("path");
28652
28747
  var _prettifyError = require_lib$8()._prettifyError;
28653
28748
  var compiler = require_compiler();
28654
28749
  var Environment = require_environment().Environment;
@@ -28672,27 +28767,27 @@ var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28672
28767
  var env = opts.env || new Environment([]);
28673
28768
  var wrapper = opts.wrapper || precompileGlobal;
28674
28769
  if (opts.isString) return precompileString(input, opts);
28675
- var pathStats = fs$14.existsSync(input) && fs$14.statSync(input);
28770
+ var pathStats = fs$13.existsSync(input) && fs$13.statSync(input);
28676
28771
  var precompiled = [];
28677
28772
  var templates = [];
28678
28773
  function addTemplates(dir) {
28679
- fs$14.readdirSync(dir).forEach(function(file) {
28680
- var filepath = path$12.join(dir, file);
28681
- var subpath = filepath.substr(path$12.join(input, "/").length);
28682
- var stat = fs$14.statSync(filepath);
28774
+ fs$13.readdirSync(dir).forEach(function(file) {
28775
+ var filepath = path$11.join(dir, file);
28776
+ var subpath = filepath.substr(path$11.join(input, "/").length);
28777
+ var stat = fs$13.statSync(filepath);
28683
28778
  if (stat && stat.isDirectory()) {
28684
28779
  subpath += "/";
28685
28780
  if (!match(subpath, opts.exclude)) addTemplates(filepath);
28686
28781
  } else if (match(subpath, opts.include)) templates.push(filepath);
28687
28782
  });
28688
28783
  }
28689
- if (pathStats.isFile()) precompiled.push(_precompile(fs$14.readFileSync(input, "utf-8"), opts.name || input, env));
28784
+ if (pathStats.isFile()) precompiled.push(_precompile(fs$13.readFileSync(input, "utf-8"), opts.name || input, env));
28690
28785
  else if (pathStats.isDirectory()) {
28691
28786
  addTemplates(input);
28692
28787
  for (var i = 0; i < templates.length; i++) {
28693
- var name = templates[i].replace(path$12.join(input, "/"), "");
28788
+ var name = templates[i].replace(path$11.join(input, "/"), "");
28694
28789
  try {
28695
- precompiled.push(_precompile(fs$14.readFileSync(templates[i], "utf-8"), name, env));
28790
+ precompiled.push(_precompile(fs$13.readFileSync(templates[i], "utf-8"), name, env));
28696
28791
  } catch (e) {
28697
28792
  if (opts.force) console.error(e);
28698
28793
  else throw e;
@@ -32733,7 +32828,7 @@ var require_buffer_from = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32733
32828
  //#region ../../node_modules/.pnpm/source-map-support@0.5.21/node_modules/source-map-support/source-map-support.js
32734
32829
  var require_source_map_support = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32735
32830
  var SourceMapConsumer = require_source_map().SourceMapConsumer;
32736
- var path$11 = __require("path");
32831
+ var path$10 = __require("path");
32737
32832
  var fs;
32738
32833
  try {
32739
32834
  fs = __require("fs");
@@ -32810,15 +32905,15 @@ var require_source_map_support = /* @__PURE__ */ __commonJSMin(((exports, module
32810
32905
  });
32811
32906
  function supportRelativeURL(file, url) {
32812
32907
  if (!file) return url;
32813
- var dir = path$11.dirname(file);
32908
+ var dir = path$10.dirname(file);
32814
32909
  var match = /^\w+:\/\/[^\/]*/.exec(dir);
32815
32910
  var protocol = match ? match[0] : "";
32816
32911
  var startPath = dir.slice(protocol.length);
32817
32912
  if (protocol && /^\/\w\:/.test(startPath)) {
32818
32913
  protocol += "/";
32819
- return protocol + path$11.resolve(dir.slice(protocol.length), url).replace(/\\/g, "/");
32914
+ return protocol + path$10.resolve(dir.slice(protocol.length), url).replace(/\\/g, "/");
32820
32915
  }
32821
- return protocol + path$11.resolve(dir.slice(protocol.length), url);
32916
+ return protocol + path$10.resolve(dir.slice(protocol.length), url);
32822
32917
  }
32823
32918
  function retrieveSourceMapURL(source) {
32824
32919
  var fileData;
@@ -181397,6 +181492,10 @@ var init_goal$1 = __esmMin((() => {
181397
181492
  restoreUpdate(record) {
181398
181493
  const state = this.state;
181399
181494
  if (state === void 0) return;
181495
+ if (record.objective !== void 0) {
181496
+ state.objective = record.objective;
181497
+ this.lifecycleRevision += 1;
181498
+ }
181400
181499
  const status = record.status;
181401
181500
  if (status !== void 0) {
181402
181501
  this.lifecycleRevision += 1;
@@ -181411,7 +181510,17 @@ var init_goal$1 = __esmMin((() => {
181411
181510
  state.wallClockResumedAt = void 0;
181412
181511
  }
181413
181512
  if (record.budgetLimits !== void 0) state.budgetLimits = record.budgetLimits;
181414
- if (status === void 0) return;
181513
+ if (status === void 0) {
181514
+ if (record.objective !== void 0) this.agent.replayBuilder.push({
181515
+ type: "goal_updated",
181516
+ snapshot: this.toSnapshot(state),
181517
+ change: {
181518
+ kind: "edited",
181519
+ actor: record.actor
181520
+ }
181521
+ });
181522
+ return;
181523
+ }
181415
181524
  this.agent.replayBuilder.push({
181416
181525
  type: "goal_updated",
181417
181526
  snapshot: this.toSnapshot(state),
@@ -181455,11 +181564,11 @@ var init_goal$1 = __esmMin((() => {
181455
181564
  if (objective.length === 0) throw new BlunError(ErrorCodes.GOAL_OBJECTIVE_EMPTY, "Goal objective cannot be empty");
181456
181565
  if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH$3) throw new BlunError(ErrorCodes.GOAL_OBJECTIVE_TOO_LONG, `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH$3} characters`);
181457
181566
  const verificationScope = normalizeVerificationScope(input.verificationScope);
181567
+ const completionCriterion = normalizeCompletionCriterion(input.completionCriterion);
181458
181568
  if (this.state !== void 0) {
181459
181569
  if (input.replace !== true) throw new BlunError(ErrorCodes.GOAL_ALREADY_EXISTS, "A goal already exists; use replace to start a new one");
181460
181570
  this.clearInternal("system");
181461
181571
  }
181462
- const completionCriterion = normalizeCompletionCriterion(input.completionCriterion);
181463
181572
  const state = {
181464
181573
  goalId: randomUUID(),
181465
181574
  objective,
@@ -181483,6 +181592,35 @@ var init_goal$1 = __esmMin((() => {
181483
181592
  this.trackGoalCreated(actor, input.replace === true);
181484
181593
  return this.toSnapshot(state);
181485
181594
  }
181595
+ async completeGoal() {
181596
+ const state = this.requireState();
181597
+ if (state.status !== "active") throw new BlunError(ErrorCodes.GOAL_STATUS_INVALID, `Cannot complete a goal in status "${state.status}"`);
181598
+ return this.markComplete({}, "user");
181599
+ }
181600
+ async blockGoal(input = {}) {
181601
+ const state = this.requireState();
181602
+ if (state.status === "blocked") return this.toSnapshot(state);
181603
+ if (state.status !== "active") throw new BlunError(ErrorCodes.GOAL_STATUS_INVALID, `Cannot block a goal in status "${state.status}"`);
181604
+ return await this.markBlocked(input, "user");
181605
+ }
181606
+ async editGoal(input, actor = "user") {
181607
+ const state = this.requireState();
181608
+ const objective = input.objective.trim();
181609
+ if (objective.length === 0) throw new BlunError(ErrorCodes.GOAL_OBJECTIVE_EMPTY, "Goal objective cannot be empty");
181610
+ if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH$3) throw new BlunError(ErrorCodes.GOAL_OBJECTIVE_TOO_LONG, `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH$3} characters`);
181611
+ if (objective === state.objective) return this.toSnapshot(state);
181612
+ state.objective = objective;
181613
+ this.lifecycleRevision += 1;
181614
+ this.appendGoalUpdate({
181615
+ objective,
181616
+ actor
181617
+ });
181618
+ this.persistState(state, { change: {
181619
+ kind: "edited",
181620
+ actor
181621
+ } });
181622
+ return this.toSnapshot(state);
181623
+ }
181486
181624
  async pauseGoal(input = {}, actor = "user") {
181487
181625
  const state = this.requireState();
181488
181626
  if (state.status === "paused") return this.toSnapshot(state);
@@ -182225,6 +182363,621 @@ var init_provider_retry_wait = __esmMin((() => {
182225
182363
  };
182226
182364
  }));
182227
182365
  //#endregion
182366
+ //#region ../../packages/agent-core/src/tools/support/file-type.ts
182367
+ function toBuffer$2(data) {
182368
+ return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
182369
+ }
182370
+ function startsWith(buf, prefix) {
182371
+ const needle = Buffer.isBuffer(prefix) ? prefix : Buffer.from(prefix);
182372
+ if (buf.length < needle.length) return false;
182373
+ for (let i = 0; i < needle.length; i += 1) if (buf[i] !== needle[i]) return false;
182374
+ return true;
182375
+ }
182376
+ function sniffFtypBrand(header) {
182377
+ if (header.length < 12) return null;
182378
+ if (header.subarray(4, 8).toString("latin1") !== "ftyp") return null;
182379
+ return header.subarray(8, 12).toString("latin1").toLowerCase().replaceAll(/[\s\u0000]+$/g, "").trim();
182380
+ }
182381
+ function sniffMediaFromMagic(data) {
182382
+ const buf = toBuffer$2(data);
182383
+ const header = buf.length > 512 ? buf.subarray(0, 512) : buf;
182384
+ if (startsWith(header, [
182385
+ 137,
182386
+ 80,
182387
+ 78,
182388
+ 71,
182389
+ 13,
182390
+ 10,
182391
+ 26,
182392
+ 10
182393
+ ])) return {
182394
+ kind: "image",
182395
+ mimeType: "image/png"
182396
+ };
182397
+ if (startsWith(header, [
182398
+ 255,
182399
+ 216,
182400
+ 255
182401
+ ])) return {
182402
+ kind: "image",
182403
+ mimeType: "image/jpeg"
182404
+ };
182405
+ if (startsWith(header, Buffer.from("GIF87a")) || startsWith(header, Buffer.from("GIF89a"))) return {
182406
+ kind: "image",
182407
+ mimeType: "image/gif"
182408
+ };
182409
+ if (startsWith(header, Buffer.from("BM"))) return {
182410
+ kind: "image",
182411
+ mimeType: "image/bmp"
182412
+ };
182413
+ if (startsWith(header, [
182414
+ 73,
182415
+ 73,
182416
+ 42,
182417
+ 0
182418
+ ]) || startsWith(header, [
182419
+ 77,
182420
+ 77,
182421
+ 0,
182422
+ 42
182423
+ ])) return {
182424
+ kind: "image",
182425
+ mimeType: "image/tiff"
182426
+ };
182427
+ if (startsWith(header, [
182428
+ 0,
182429
+ 0,
182430
+ 1,
182431
+ 0
182432
+ ])) return {
182433
+ kind: "image",
182434
+ mimeType: "image/x-icon"
182435
+ };
182436
+ if (startsWith(header, Buffer.from("RIFF")) && header.length >= 12) {
182437
+ const chunk = header.subarray(8, 12).toString("latin1");
182438
+ if (chunk === "WEBP") return {
182439
+ kind: "image",
182440
+ mimeType: "image/webp"
182441
+ };
182442
+ if (chunk === "AVI ") return {
182443
+ kind: "video",
182444
+ mimeType: "video/x-msvideo"
182445
+ };
182446
+ }
182447
+ if (startsWith(header, Buffer.from("FLV"))) return {
182448
+ kind: "video",
182449
+ mimeType: "video/x-flv"
182450
+ };
182451
+ if (startsWith(header, ASF_HEADER)) return {
182452
+ kind: "video",
182453
+ mimeType: "video/x-ms-wmv"
182454
+ };
182455
+ if (startsWith(header, [
182456
+ 26,
182457
+ 69,
182458
+ 223,
182459
+ 163
182460
+ ])) {
182461
+ const lowered = header.toString("latin1").toLowerCase();
182462
+ if (lowered.includes("webm")) return {
182463
+ kind: "video",
182464
+ mimeType: "video/webm"
182465
+ };
182466
+ if (lowered.includes("matroska")) return {
182467
+ kind: "video",
182468
+ mimeType: "video/x-matroska"
182469
+ };
182470
+ }
182471
+ const brand = sniffFtypBrand(header);
182472
+ if (brand !== null && brand !== "") {
182473
+ if (brand in FTYP_IMAGE_BRANDS) return {
182474
+ kind: "image",
182475
+ mimeType: FTYP_IMAGE_BRANDS[brand]
182476
+ };
182477
+ if (brand in FTYP_VIDEO_BRANDS) return {
182478
+ kind: "video",
182479
+ mimeType: FTYP_VIDEO_BRANDS[brand]
182480
+ };
182481
+ }
182482
+ return null;
182483
+ }
182484
+ /**
182485
+ * Best-effort pixel-dimension reader for common raster formats.
182486
+ *
182487
+ * Inspects only the fixed region near the start of the file where each
182488
+ * format records its dimensions (the IHDR/DIB header, the RIFF chunk
182489
+ * after the `WEBP` tag, or the first JPEG SOFn segment). Returns `null`
182490
+ * for formats whose dimensions are not locatable from that region, or
182491
+ * when the supplied buffer is too short to cover it.
182492
+ */
182493
+ function sniffImageDimensions(data) {
182494
+ const buf = toBuffer$2(data);
182495
+ if (startsWith(buf, [
182496
+ 137,
182497
+ 80,
182498
+ 78,
182499
+ 71,
182500
+ 13,
182501
+ 10,
182502
+ 26,
182503
+ 10
182504
+ ]) && buf.length >= 24) return {
182505
+ width: buf.readUInt32BE(16),
182506
+ height: buf.readUInt32BE(20)
182507
+ };
182508
+ if ((startsWith(buf, Buffer.from("GIF87a")) || startsWith(buf, Buffer.from("GIF89a"))) && buf.length >= 10) return {
182509
+ width: buf.readUInt16LE(6),
182510
+ height: buf.readUInt16LE(8)
182511
+ };
182512
+ if (startsWith(buf, Buffer.from("BM")) && buf.length >= 26) return {
182513
+ width: buf.readInt32LE(18),
182514
+ height: Math.abs(buf.readInt32LE(22))
182515
+ };
182516
+ if (startsWith(buf, Buffer.from("RIFF")) && buf.length >= 30) {
182517
+ const fourCc = buf.subarray(12, 16).toString("latin1");
182518
+ if (fourCc === "VP8 ") return {
182519
+ width: buf.readUInt16LE(26) & 16383,
182520
+ height: buf.readUInt16LE(28) & 16383
182521
+ };
182522
+ if (fourCc === "VP8L" && buf.length >= 25) {
182523
+ const bits = buf.readUInt32LE(21);
182524
+ return {
182525
+ width: (bits & 16383) + 1,
182526
+ height: (bits >> 14 & 16383) + 1
182527
+ };
182528
+ }
182529
+ if (fourCc === "VP8X") return {
182530
+ width: 1 + (buf[24] | buf[25] << 8 | buf[26] << 16),
182531
+ height: 1 + (buf[27] | buf[28] << 8 | buf[29] << 16)
182532
+ };
182533
+ }
182534
+ if (startsWith(buf, [255, 216])) {
182535
+ let offset = 2;
182536
+ while (offset + 9 < buf.length) {
182537
+ if (buf[offset] !== 255) {
182538
+ offset += 1;
182539
+ continue;
182540
+ }
182541
+ const marker = buf[offset + 1];
182542
+ if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) return {
182543
+ height: buf.readUInt16BE(offset + 5),
182544
+ width: buf.readUInt16BE(offset + 7)
182545
+ };
182546
+ if (marker === 216 || marker === 217 || marker >= 208 && marker <= 215) {
182547
+ offset += 2;
182548
+ continue;
182549
+ }
182550
+ const segmentLength = buf.readUInt16BE(offset + 2);
182551
+ if (segmentLength < 2) break;
182552
+ offset += 2 + segmentLength;
182553
+ }
182554
+ }
182555
+ return null;
182556
+ }
182557
+ function getSuffix(path) {
182558
+ const idx = path.lastIndexOf(".");
182559
+ if (idx === -1) return "";
182560
+ if (idx <= Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1) return "";
182561
+ return path.slice(idx).toLowerCase();
182562
+ }
182563
+ function detectFileType(path, header, type = "text") {
182564
+ const suffix = getSuffix(path);
182565
+ let mediaHint = null;
182566
+ if (suffix in TEXT_MIME_BY_SUFFIX) mediaHint = {
182567
+ kind: "text",
182568
+ mimeType: TEXT_MIME_BY_SUFFIX[suffix]
182569
+ };
182570
+ else if (suffix in IMAGE_MIME_BY_SUFFIX) mediaHint = {
182571
+ kind: "image",
182572
+ mimeType: IMAGE_MIME_BY_SUFFIX[suffix]
182573
+ };
182574
+ else if (suffix in VIDEO_MIME_BY_SUFFIX$1) mediaHint = {
182575
+ kind: "video",
182576
+ mimeType: VIDEO_MIME_BY_SUFFIX$1[suffix]
182577
+ };
182578
+ if (header !== void 0) {
182579
+ const buf = toBuffer$2(header);
182580
+ const sniffed = sniffMediaFromMagic(buf);
182581
+ if (sniffed) {
182582
+ if (type === "media") return sniffed;
182583
+ if (mediaHint) {
182584
+ if (sniffed.kind !== mediaHint.kind) return {
182585
+ kind: "unknown",
182586
+ mimeType: ""
182587
+ };
182588
+ return mediaHint;
182589
+ }
182590
+ return sniffed;
182591
+ }
182592
+ if (mediaHint?.kind === "image") return {
182593
+ kind: "unknown",
182594
+ mimeType: ""
182595
+ };
182596
+ if (type === "media" && mediaHint?.kind === "video") return mediaHint;
182597
+ if (buf.includes(0)) return {
182598
+ kind: "unknown",
182599
+ mimeType: ""
182600
+ };
182601
+ }
182602
+ if (mediaHint) return mediaHint;
182603
+ if (NON_TEXT_SUFFIXES.has(suffix)) return {
182604
+ kind: "unknown",
182605
+ mimeType: ""
182606
+ };
182607
+ return {
182608
+ kind: "text",
182609
+ mimeType: "text/plain"
182610
+ };
182611
+ }
182612
+ var IMAGE_MIME_BY_SUFFIX, VIDEO_MIME_BY_SUFFIX$1, TEXT_MIME_BY_SUFFIX, NON_TEXT_SUFFIXES, ASF_HEADER, FTYP_IMAGE_BRANDS, FTYP_VIDEO_BRANDS;
182613
+ var init_file_type$1 = __esmMin((() => {
182614
+ IMAGE_MIME_BY_SUFFIX = Object.freeze({
182615
+ ".png": "image/png",
182616
+ ".jpg": "image/jpeg",
182617
+ ".jpeg": "image/jpeg",
182618
+ ".gif": "image/gif",
182619
+ ".bmp": "image/bmp",
182620
+ ".tif": "image/tiff",
182621
+ ".tiff": "image/tiff",
182622
+ ".webp": "image/webp",
182623
+ ".ico": "image/x-icon",
182624
+ ".heic": "image/heic",
182625
+ ".heif": "image/heif",
182626
+ ".avif": "image/avif",
182627
+ ".svgz": "image/svg+xml"
182628
+ });
182629
+ VIDEO_MIME_BY_SUFFIX$1 = Object.freeze({
182630
+ ".mp4": "video/mp4",
182631
+ ".mpg": "video/mpeg",
182632
+ ".mpeg": "video/mpeg",
182633
+ ".mkv": "video/x-matroska",
182634
+ ".avi": "video/x-msvideo",
182635
+ ".mov": "video/quicktime",
182636
+ ".ogv": "video/ogg",
182637
+ ".wmv": "video/x-ms-wmv",
182638
+ ".webm": "video/webm",
182639
+ ".m4v": "video/x-m4v",
182640
+ ".flv": "video/x-flv",
182641
+ ".3gp": "video/3gpp",
182642
+ ".3g2": "video/3gpp2"
182643
+ });
182644
+ TEXT_MIME_BY_SUFFIX = Object.freeze({ ".svg": "image/svg+xml" });
182645
+ NON_TEXT_SUFFIXES = new Set([
182646
+ ".icns",
182647
+ ".psd",
182648
+ ".ai",
182649
+ ".eps",
182650
+ ".pdf",
182651
+ ".doc",
182652
+ ".docx",
182653
+ ".dot",
182654
+ ".dotx",
182655
+ ".rtf",
182656
+ ".odt",
182657
+ ".xls",
182658
+ ".xlsx",
182659
+ ".xlsm",
182660
+ ".xlt",
182661
+ ".xltx",
182662
+ ".xltm",
182663
+ ".ods",
182664
+ ".ppt",
182665
+ ".pptx",
182666
+ ".pptm",
182667
+ ".pps",
182668
+ ".ppsx",
182669
+ ".odp",
182670
+ ".pages",
182671
+ ".numbers",
182672
+ ".key",
182673
+ ".zip",
182674
+ ".rar",
182675
+ ".7z",
182676
+ ".tar",
182677
+ ".gz",
182678
+ ".tgz",
182679
+ ".bz2",
182680
+ ".xz",
182681
+ ".zst",
182682
+ ".lz",
182683
+ ".lz4",
182684
+ ".br",
182685
+ ".cab",
182686
+ ".ar",
182687
+ ".deb",
182688
+ ".rpm",
182689
+ ".mp3",
182690
+ ".wav",
182691
+ ".flac",
182692
+ ".ogg",
182693
+ ".oga",
182694
+ ".opus",
182695
+ ".aac",
182696
+ ".m4a",
182697
+ ".wma",
182698
+ ".ttf",
182699
+ ".otf",
182700
+ ".woff",
182701
+ ".woff2",
182702
+ ".exe",
182703
+ ".dll",
182704
+ ".so",
182705
+ ".dylib",
182706
+ ".bin",
182707
+ ".apk",
182708
+ ".ipa",
182709
+ ".jar",
182710
+ ".class",
182711
+ ".pyc",
182712
+ ".pyo",
182713
+ ".wasm",
182714
+ ".dmg",
182715
+ ".iso",
182716
+ ".img",
182717
+ ".sqlite",
182718
+ ".sqlite3",
182719
+ ".db",
182720
+ ".db3"
182721
+ ]);
182722
+ ASF_HEADER = Buffer.from([
182723
+ 48,
182724
+ 38,
182725
+ 178,
182726
+ 117,
182727
+ 142,
182728
+ 102,
182729
+ 207,
182730
+ 17,
182731
+ 166,
182732
+ 217,
182733
+ 0,
182734
+ 170,
182735
+ 0,
182736
+ 98,
182737
+ 206,
182738
+ 108
182739
+ ]);
182740
+ FTYP_IMAGE_BRANDS = Object.freeze({
182741
+ avif: "image/avif",
182742
+ avis: "image/avif",
182743
+ heic: "image/heic",
182744
+ heif: "image/heif",
182745
+ heix: "image/heif",
182746
+ hevc: "image/heic",
182747
+ mif1: "image/heif",
182748
+ msf1: "image/heif"
182749
+ });
182750
+ FTYP_VIDEO_BRANDS = Object.freeze({
182751
+ isom: "video/mp4",
182752
+ iso2: "video/mp4",
182753
+ iso5: "video/mp4",
182754
+ mp41: "video/mp4",
182755
+ mp42: "video/mp4",
182756
+ avc1: "video/mp4",
182757
+ mp4v: "video/mp4",
182758
+ m4v: "video/x-m4v",
182759
+ qt: "video/quicktime",
182760
+ "3gp4": "video/3gpp",
182761
+ "3gp5": "video/3gpp",
182762
+ "3gp6": "video/3gpp",
182763
+ "3gp7": "video/3gpp",
182764
+ "3g2": "video/3gpp2"
182765
+ });
182766
+ }));
182767
+ //#endregion
182768
+ //#region ../../packages/agent-core/src/utils/tokens.ts
182769
+ /** Open assistant messages grow while streaming; completed history stays cached. */
182770
+ function invalidateMessageTokenEstimate(message) {
182771
+ messageTokenEstimateCache.delete(message);
182772
+ }
182773
+ /**
182774
+ * Estimate token count from text using a character-based heuristic.
182775
+ * - ASCII (~4 chars per token)
182776
+ * - CJK and other non-ASCII (~1 char per token)
182777
+ * The estimate is transient — the next LLM call returns the real count
182778
+ * and supersedes this value. Used to keep `tokenCountWithPending`
182779
+ * monotonic between LLM round-trips without paying for a tokenizer.
182780
+ */
182781
+ function estimateTokens(text) {
182782
+ let asciiCount = 0;
182783
+ let nonAsciiCount = 0;
182784
+ for (const char of text) if (char.codePointAt(0) <= 127) asciiCount++;
182785
+ else nonAsciiCount++;
182786
+ return Math.ceil(asciiCount / 4) + nonAsciiCount;
182787
+ }
182788
+ function estimateTokensForMessages(messages) {
182789
+ let total = 0;
182790
+ for (const message of messages) total += estimateTokensForMessage(message);
182791
+ return total;
182792
+ }
182793
+ /** With stopAfter, the result is a lower bound once it exceeds that budget. */
182794
+ function estimateTokensForTools(tools, stopAfter = Infinity) {
182795
+ let total = 0;
182796
+ for (const tool of tools) {
182797
+ total += estimateTokens(tool.name);
182798
+ total += estimateTokens(tool.description);
182799
+ total += estimateTokens(JSON.stringify(tool.parameters));
182800
+ if (total > stopAfter) return total;
182801
+ }
182802
+ return total;
182803
+ }
182804
+ function estimateTokensForMessage(message) {
182805
+ const cached = messageTokenEstimateCache.get(message);
182806
+ if (cached !== void 0) return cached;
182807
+ let total = estimateTokens(message.role);
182808
+ total += estimateTokensForContentParts(message.content);
182809
+ if (message.toolCalls !== void 0) for (const call of message.toolCalls) {
182810
+ total += estimateTokens(call.name);
182811
+ total += estimateTokens(JSON.stringify(call.arguments));
182812
+ }
182813
+ messageTokenEstimateCache.set(message, total);
182814
+ return total;
182815
+ }
182816
+ function estimateTokensForContentParts(parts) {
182817
+ let total = 0;
182818
+ for (const part of parts) total += estimateTokensForContentPart(part);
182819
+ return total;
182820
+ }
182821
+ function imageDimensionsFromDataUrl(url) {
182822
+ const commaIndex = url.indexOf(",");
182823
+ if (commaIndex <= 0) return null;
182824
+ const metadata = url.slice(0, commaIndex).toLowerCase();
182825
+ if (!metadata.startsWith("data:image/") || !metadata.split(";").includes("base64")) return null;
182826
+ const maxBase64Chars = Math.ceil(MAX_IMAGE_HEADER_BYTES / 3) * 4;
182827
+ const encodedHeader = url.slice(commaIndex + 1, commaIndex + 1 + maxBase64Chars);
182828
+ if (encodedHeader.length === 0) return null;
182829
+ try {
182830
+ const dimensions = sniffImageDimensions(Buffer.from(encodedHeader, "base64"));
182831
+ if (dimensions === null || !Number.isSafeInteger(dimensions.width) || !Number.isSafeInteger(dimensions.height) || dimensions.width <= 0 || dimensions.height <= 0) return null;
182832
+ return dimensions;
182833
+ } catch {
182834
+ return null;
182835
+ }
182836
+ }
182837
+ function estimateImageTokensFromDimensions(width, height) {
182838
+ if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width <= 0 || height <= 0) return MEDIA_TOKEN_ESTIMATE;
182839
+ const patchSize = BigInt(32);
182840
+ const tokens = (BigInt(width) + patchSize - 1n) / patchSize * ((BigInt(height) + patchSize - 1n) / patchSize);
182841
+ return tokens > BigInt(Number.MAX_SAFE_INTEGER) ? Number.MAX_SAFE_INTEGER : Number(tokens);
182842
+ }
182843
+ function estimateImageTokens(url) {
182844
+ const dimensions = imageDimensionsFromDataUrl(url);
182845
+ return dimensions === null ? MEDIA_TOKEN_ESTIMATE : estimateImageTokensFromDimensions(dimensions.width, dimensions.height);
182846
+ }
182847
+ function estimateTokensForContentPart(part) {
182848
+ switch (part.type) {
182849
+ case "text": return estimateTokens(part.text);
182850
+ case "think": return estimateTokens(part.think);
182851
+ case "image_url": return estimateImageTokens(part.imageUrl.url);
182852
+ case "audio_url":
182853
+ case "video_url": return MEDIA_TOKEN_ESTIMATE;
182854
+ default: return 0;
182855
+ }
182856
+ }
182857
+ var messageTokenEstimateCache, MEDIA_TOKEN_ESTIMATE, MAX_IMAGE_HEADER_BYTES;
182858
+ var init_tokens = __esmMin((() => {
182859
+ init_file_type$1();
182860
+ messageTokenEstimateCache = /* @__PURE__ */ new WeakMap();
182861
+ MEDIA_TOKEN_ESTIMATE = 2e3;
182862
+ MAX_IMAGE_HEADER_BYTES = 1024 * 1024;
182863
+ }));
182864
+ //#endregion
182865
+ //#region ../../packages/agent-core/src/agent/compaction/tool-continuity.ts
182866
+ function saturatingAdd(left, right) {
182867
+ return left + Math.min(right, Number.MAX_SAFE_INTEGER - left);
182868
+ }
182869
+ function renderUnchecked(value) {
182870
+ return [
182871
+ "",
182872
+ "",
182873
+ "<tool-continuity>",
182874
+ "Observed tool-result flags; may be synthetic, not verified job success or permission. omitted counts excluded observations cumulatively, not jobs.",
182875
+ JSON.stringify(value).replaceAll(/[<>&]/g, (character) => {
182876
+ return `\\u${character.codePointAt(0).toString(16).padStart(4, "0")}`;
182877
+ }),
182878
+ "</tool-continuity>"
182879
+ ].join("\n");
182880
+ }
182881
+ function hasExactKeys$1(value, expected) {
182882
+ const prototype = Object.getPrototypeOf(value);
182883
+ if (prototype !== Object.prototype && prototype !== null) return false;
182884
+ return Reflect.ownKeys(value).length === expected.length && expected.every((key) => {
182885
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
182886
+ return descriptor !== void 0 && descriptor.enumerable === true && Object.hasOwn(descriptor, "value");
182887
+ });
182888
+ }
182889
+ function isDataArray(value) {
182890
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length > 8 || Reflect.ownKeys(value).length !== value.length + 1) return false;
182891
+ for (let index = 0; index < value.length; index++) {
182892
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
182893
+ if (descriptor === void 0 || descriptor.enumerable !== true || !Object.hasOwn(descriptor, "value")) return false;
182894
+ }
182895
+ return true;
182896
+ }
182897
+ /** Validate restored metadata without interpreting any summarizer or tool prose. */
182898
+ function isToolContinuity(value) {
182899
+ try {
182900
+ if (value === null || typeof value !== "object" || !hasExactKeys$1(value, ["receipts", "omitted"])) return false;
182901
+ const candidate = value;
182902
+ if (!Number.isSafeInteger(candidate["omitted"]) || candidate["omitted"] < 0 || !isDataArray(candidate["receipts"]) || candidate["receipts"].length > 8) return false;
182903
+ for (const receipt of candidate["receipts"]) if (receipt === null || typeof receipt !== "object" || !hasExactKeys$1(receipt, ["toolCallId", "observedIsError"]) || !("toolCallId" in receipt) || !("observedIsError" in receipt) || typeof receipt.toolCallId !== "string" || receipt.toolCallId.length === 0 || Buffer.byteLength(receipt.toolCallId, "utf8") > 256 || receipt.observedIsError !== null && typeof receipt.observedIsError !== "boolean") return false;
182904
+ return Buffer.byteLength(JSON.stringify(renderUnchecked(value)), "utf8") <= MAX_TOOL_CONTINUITY_SERIALIZED_BYTES;
182905
+ } catch {
182906
+ return false;
182907
+ }
182908
+ }
182909
+ function renderToolContinuity(value) {
182910
+ if (!isToolContinuity(value) || value.receipts.length === 0 && value.omitted === 0) return void 0;
182911
+ return renderUnchecked(value);
182912
+ }
182913
+ /** The caller passes only the compactable prefix, excluding the preserved tool suffix. */
182914
+ function collectToolContinuity(messages) {
182915
+ const observed = /* @__PURE__ */ new Map();
182916
+ let ordinal = 0;
182917
+ let inheritedOmitted = 0;
182918
+ let excluded = 0;
182919
+ const remember = (toolCallId, observedIsError) => {
182920
+ if (toolCallId.length === 0 || Buffer.byteLength(toolCallId, "utf8") > 256) {
182921
+ excluded = saturatingAdd(excluded, 1);
182922
+ return;
182923
+ }
182924
+ const key = JSON.stringify([toolCallId, observedIsError]);
182925
+ observed.set(key, {
182926
+ toolCallId,
182927
+ observedIsError,
182928
+ ordinal: ordinal++
182929
+ });
182930
+ };
182931
+ for (const message of messages) if (message.role === "tool" && typeof message.toolCallId === "string") remember(message.toolCallId, typeof message.isError === "boolean" ? message.isError : null);
182932
+ else if (message.role === "user" && message.origin?.kind === "compaction_summary") {
182933
+ const previous = message.origin.toolContinuity;
182934
+ if (!isToolContinuity(previous)) continue;
182935
+ for (const receipt of previous.receipts.toReversed()) remember(receipt.toolCallId, receipt.observedIsError);
182936
+ inheritedOmitted = Math.max(inheritedOmitted, previous.omitted);
182937
+ }
182938
+ const prioritized = [...observed.values()].toSorted((left, right) => Number(right.observedIsError === true) - Number(left.observedIsError === true) || right.ordinal - left.ordinal);
182939
+ const receipts = prioritized.slice(0, 8).map(({ toolCallId, observedIsError }) => ({
182940
+ toolCallId,
182941
+ observedIsError
182942
+ }));
182943
+ let omitted = saturatingAdd(saturatingAdd(inheritedOmitted, excluded), prioritized.length - receipts.length);
182944
+ while (true) {
182945
+ const result = {
182946
+ receipts: [...receipts],
182947
+ omitted
182948
+ };
182949
+ if (renderToolContinuity(result) !== void 0) return result;
182950
+ if (receipts.length === 0) return void 0;
182951
+ receipts.pop();
182952
+ omitted = saturatingAdd(omitted, 1);
182953
+ }
182954
+ }
182955
+ /** Fit complete tuples and their disclaimer; never start a new failure or retry path. */
182956
+ function fitToolContinuity(value, additionalTokenBudget) {
182957
+ if (value === void 0 || !isToolContinuity(value) || !(additionalTokenBudget > 0)) return void 0;
182958
+ const receipts = [...value.receipts];
182959
+ let omitted = value.omitted;
182960
+ while (true) {
182961
+ const continuity = {
182962
+ receipts: [...receipts],
182963
+ omitted
182964
+ };
182965
+ const text = renderToolContinuity(continuity);
182966
+ if (text !== void 0 && estimateTokens(text) <= additionalTokenBudget) return {
182967
+ continuity,
182968
+ text
182969
+ };
182970
+ if (receipts.length === 0) return void 0;
182971
+ receipts.pop();
182972
+ omitted = saturatingAdd(omitted, 1);
182973
+ }
182974
+ }
182975
+ var MAX_TOOL_CONTINUITY_SERIALIZED_BYTES;
182976
+ var init_tool_continuity = __esmMin((() => {
182977
+ init_tokens();
182978
+ MAX_TOOL_CONTINUITY_SERIALIZED_BYTES = 4096;
182979
+ }));
182980
+ //#endregion
182228
182981
  //#region ../../packages/agent-core/src/agent/records/resume-snapshot.ts
182229
182982
  function resumeRecordKind(type) {
182230
182983
  if ([
@@ -182313,6 +183066,7 @@ var init_resume_snapshot = __esmMin((() => {
182313
183066
  init_schema();
182314
183067
  init_goal$1();
182315
183068
  init_provider_retry_wait();
183069
+ init_tool_continuity();
182316
183070
  init_migration();
182317
183071
  integer$1 = number$1().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
182318
183072
  finite = number$1().finite().nonnegative();
@@ -182406,6 +183160,7 @@ var init_resume_snapshot = __esmMin((() => {
182406
183160
  verificationScope: _enum(GOAL_VERIFICATION_SCOPES).optional()
182407
183161
  }),
182408
183162
  record$1("goal.update", {
183163
+ objective: text.min(1).max(4e3).regex(/\S/).optional(),
182409
183164
  status: _enum([
182410
183165
  "active",
182411
183166
  "paused",
@@ -182457,7 +183212,7 @@ var init_resume_snapshot = __esmMin((() => {
182457
183212
  }).passthrough();
182458
183213
  origin = union([
182459
183214
  originCase("user"),
182460
- originCase("compaction_summary"),
183215
+ originCase("compaction_summary", { toolContinuity: custom$1(isToolContinuity).optional() }),
182461
183216
  originCase("skill_activation", {
182462
183217
  activationId: text,
182463
183218
  skillName: text,
@@ -182694,6 +183449,7 @@ async function writeResumeCheckpoint(wirePath, position, snapshot) {
182694
183449
  if (Buffer.byteLength(bytes) > MAX_CHECKPOINT_BYTES) return false;
182695
183450
  const target = resumeCheckpointPath(wirePath);
182696
183451
  const temporary = `${target}.tmp-${process.pid}-${randomBytes(8).toString("hex")}`;
183452
+ let renamed = false;
182697
183453
  try {
182698
183454
  const output = await open(temporary, "wx", 384);
182699
183455
  try {
@@ -182703,10 +183459,11 @@ async function writeResumeCheckpoint(wirePath, position, snapshot) {
182703
183459
  await output.close();
182704
183460
  }
182705
183461
  await rename(temporary, target);
183462
+ renamed = true;
182706
183463
  await syncDir(dirname$3(target));
182707
183464
  return true;
182708
183465
  } finally {
182709
- await rm(temporary, { force: true }).catch(() => {});
183466
+ if (!renamed) await rm(temporary, { force: true }).catch(() => {});
182710
183467
  }
182711
183468
  }
182712
183469
  var MAX_RESUME_SNAPSHOT_BYTES, MAX_CHECKPOINT_BYTES, SAMPLE_BYTES, integer, digest$1, exactInteger, samplesSchema, identitySchema, envelopeSchema$2, resumeCheckpointPath, sha256$6, milliseconds;
@@ -186120,503 +186877,6 @@ var init_todo_list = __esmMin((() => {
186120
186877
  };
186121
186878
  }));
186122
186879
  //#endregion
186123
- //#region ../../packages/agent-core/src/tools/support/file-type.ts
186124
- function toBuffer$2(data) {
186125
- return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
186126
- }
186127
- function startsWith(buf, prefix) {
186128
- const needle = Buffer.isBuffer(prefix) ? prefix : Buffer.from(prefix);
186129
- if (buf.length < needle.length) return false;
186130
- for (let i = 0; i < needle.length; i += 1) if (buf[i] !== needle[i]) return false;
186131
- return true;
186132
- }
186133
- function sniffFtypBrand(header) {
186134
- if (header.length < 12) return null;
186135
- if (header.subarray(4, 8).toString("latin1") !== "ftyp") return null;
186136
- return header.subarray(8, 12).toString("latin1").toLowerCase().replaceAll(/[\s\u0000]+$/g, "").trim();
186137
- }
186138
- function sniffMediaFromMagic(data) {
186139
- const buf = toBuffer$2(data);
186140
- const header = buf.length > 512 ? buf.subarray(0, 512) : buf;
186141
- if (startsWith(header, [
186142
- 137,
186143
- 80,
186144
- 78,
186145
- 71,
186146
- 13,
186147
- 10,
186148
- 26,
186149
- 10
186150
- ])) return {
186151
- kind: "image",
186152
- mimeType: "image/png"
186153
- };
186154
- if (startsWith(header, [
186155
- 255,
186156
- 216,
186157
- 255
186158
- ])) return {
186159
- kind: "image",
186160
- mimeType: "image/jpeg"
186161
- };
186162
- if (startsWith(header, Buffer.from("GIF87a")) || startsWith(header, Buffer.from("GIF89a"))) return {
186163
- kind: "image",
186164
- mimeType: "image/gif"
186165
- };
186166
- if (startsWith(header, Buffer.from("BM"))) return {
186167
- kind: "image",
186168
- mimeType: "image/bmp"
186169
- };
186170
- if (startsWith(header, [
186171
- 73,
186172
- 73,
186173
- 42,
186174
- 0
186175
- ]) || startsWith(header, [
186176
- 77,
186177
- 77,
186178
- 0,
186179
- 42
186180
- ])) return {
186181
- kind: "image",
186182
- mimeType: "image/tiff"
186183
- };
186184
- if (startsWith(header, [
186185
- 0,
186186
- 0,
186187
- 1,
186188
- 0
186189
- ])) return {
186190
- kind: "image",
186191
- mimeType: "image/x-icon"
186192
- };
186193
- if (startsWith(header, Buffer.from("RIFF")) && header.length >= 12) {
186194
- const chunk = header.subarray(8, 12).toString("latin1");
186195
- if (chunk === "WEBP") return {
186196
- kind: "image",
186197
- mimeType: "image/webp"
186198
- };
186199
- if (chunk === "AVI ") return {
186200
- kind: "video",
186201
- mimeType: "video/x-msvideo"
186202
- };
186203
- }
186204
- if (startsWith(header, Buffer.from("FLV"))) return {
186205
- kind: "video",
186206
- mimeType: "video/x-flv"
186207
- };
186208
- if (startsWith(header, ASF_HEADER)) return {
186209
- kind: "video",
186210
- mimeType: "video/x-ms-wmv"
186211
- };
186212
- if (startsWith(header, [
186213
- 26,
186214
- 69,
186215
- 223,
186216
- 163
186217
- ])) {
186218
- const lowered = header.toString("latin1").toLowerCase();
186219
- if (lowered.includes("webm")) return {
186220
- kind: "video",
186221
- mimeType: "video/webm"
186222
- };
186223
- if (lowered.includes("matroska")) return {
186224
- kind: "video",
186225
- mimeType: "video/x-matroska"
186226
- };
186227
- }
186228
- const brand = sniffFtypBrand(header);
186229
- if (brand !== null && brand !== "") {
186230
- if (brand in FTYP_IMAGE_BRANDS) return {
186231
- kind: "image",
186232
- mimeType: FTYP_IMAGE_BRANDS[brand]
186233
- };
186234
- if (brand in FTYP_VIDEO_BRANDS) return {
186235
- kind: "video",
186236
- mimeType: FTYP_VIDEO_BRANDS[brand]
186237
- };
186238
- }
186239
- return null;
186240
- }
186241
- /**
186242
- * Best-effort pixel-dimension reader for common raster formats.
186243
- *
186244
- * Inspects only the fixed region near the start of the file where each
186245
- * format records its dimensions (the IHDR/DIB header, the RIFF chunk
186246
- * after the `WEBP` tag, or the first JPEG SOFn segment). Returns `null`
186247
- * for formats whose dimensions are not locatable from that region, or
186248
- * when the supplied buffer is too short to cover it.
186249
- */
186250
- function sniffImageDimensions(data) {
186251
- const buf = toBuffer$2(data);
186252
- if (startsWith(buf, [
186253
- 137,
186254
- 80,
186255
- 78,
186256
- 71,
186257
- 13,
186258
- 10,
186259
- 26,
186260
- 10
186261
- ]) && buf.length >= 24) return {
186262
- width: buf.readUInt32BE(16),
186263
- height: buf.readUInt32BE(20)
186264
- };
186265
- if ((startsWith(buf, Buffer.from("GIF87a")) || startsWith(buf, Buffer.from("GIF89a"))) && buf.length >= 10) return {
186266
- width: buf.readUInt16LE(6),
186267
- height: buf.readUInt16LE(8)
186268
- };
186269
- if (startsWith(buf, Buffer.from("BM")) && buf.length >= 26) return {
186270
- width: buf.readInt32LE(18),
186271
- height: Math.abs(buf.readInt32LE(22))
186272
- };
186273
- if (startsWith(buf, Buffer.from("RIFF")) && buf.length >= 30) {
186274
- const fourCc = buf.subarray(12, 16).toString("latin1");
186275
- if (fourCc === "VP8 ") return {
186276
- width: buf.readUInt16LE(26) & 16383,
186277
- height: buf.readUInt16LE(28) & 16383
186278
- };
186279
- if (fourCc === "VP8L" && buf.length >= 25) {
186280
- const bits = buf.readUInt32LE(21);
186281
- return {
186282
- width: (bits & 16383) + 1,
186283
- height: (bits >> 14 & 16383) + 1
186284
- };
186285
- }
186286
- if (fourCc === "VP8X") return {
186287
- width: 1 + (buf[24] | buf[25] << 8 | buf[26] << 16),
186288
- height: 1 + (buf[27] | buf[28] << 8 | buf[29] << 16)
186289
- };
186290
- }
186291
- if (startsWith(buf, [255, 216])) {
186292
- let offset = 2;
186293
- while (offset + 9 < buf.length) {
186294
- if (buf[offset] !== 255) {
186295
- offset += 1;
186296
- continue;
186297
- }
186298
- const marker = buf[offset + 1];
186299
- if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) return {
186300
- height: buf.readUInt16BE(offset + 5),
186301
- width: buf.readUInt16BE(offset + 7)
186302
- };
186303
- if (marker === 216 || marker === 217 || marker >= 208 && marker <= 215) {
186304
- offset += 2;
186305
- continue;
186306
- }
186307
- const segmentLength = buf.readUInt16BE(offset + 2);
186308
- if (segmentLength < 2) break;
186309
- offset += 2 + segmentLength;
186310
- }
186311
- }
186312
- return null;
186313
- }
186314
- function getSuffix(path) {
186315
- const idx = path.lastIndexOf(".");
186316
- if (idx === -1) return "";
186317
- if (idx <= Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1) return "";
186318
- return path.slice(idx).toLowerCase();
186319
- }
186320
- function detectFileType(path, header, type = "text") {
186321
- const suffix = getSuffix(path);
186322
- let mediaHint = null;
186323
- if (suffix in TEXT_MIME_BY_SUFFIX) mediaHint = {
186324
- kind: "text",
186325
- mimeType: TEXT_MIME_BY_SUFFIX[suffix]
186326
- };
186327
- else if (suffix in IMAGE_MIME_BY_SUFFIX) mediaHint = {
186328
- kind: "image",
186329
- mimeType: IMAGE_MIME_BY_SUFFIX[suffix]
186330
- };
186331
- else if (suffix in VIDEO_MIME_BY_SUFFIX$1) mediaHint = {
186332
- kind: "video",
186333
- mimeType: VIDEO_MIME_BY_SUFFIX$1[suffix]
186334
- };
186335
- if (header !== void 0) {
186336
- const buf = toBuffer$2(header);
186337
- const sniffed = sniffMediaFromMagic(buf);
186338
- if (sniffed) {
186339
- if (type === "media") return sniffed;
186340
- if (mediaHint) {
186341
- if (sniffed.kind !== mediaHint.kind) return {
186342
- kind: "unknown",
186343
- mimeType: ""
186344
- };
186345
- return mediaHint;
186346
- }
186347
- return sniffed;
186348
- }
186349
- if (mediaHint?.kind === "image") return {
186350
- kind: "unknown",
186351
- mimeType: ""
186352
- };
186353
- if (type === "media" && mediaHint?.kind === "video") return mediaHint;
186354
- if (buf.includes(0)) return {
186355
- kind: "unknown",
186356
- mimeType: ""
186357
- };
186358
- }
186359
- if (mediaHint) return mediaHint;
186360
- if (NON_TEXT_SUFFIXES.has(suffix)) return {
186361
- kind: "unknown",
186362
- mimeType: ""
186363
- };
186364
- return {
186365
- kind: "text",
186366
- mimeType: "text/plain"
186367
- };
186368
- }
186369
- var IMAGE_MIME_BY_SUFFIX, VIDEO_MIME_BY_SUFFIX$1, TEXT_MIME_BY_SUFFIX, NON_TEXT_SUFFIXES, ASF_HEADER, FTYP_IMAGE_BRANDS, FTYP_VIDEO_BRANDS;
186370
- var init_file_type$1 = __esmMin((() => {
186371
- IMAGE_MIME_BY_SUFFIX = Object.freeze({
186372
- ".png": "image/png",
186373
- ".jpg": "image/jpeg",
186374
- ".jpeg": "image/jpeg",
186375
- ".gif": "image/gif",
186376
- ".bmp": "image/bmp",
186377
- ".tif": "image/tiff",
186378
- ".tiff": "image/tiff",
186379
- ".webp": "image/webp",
186380
- ".ico": "image/x-icon",
186381
- ".heic": "image/heic",
186382
- ".heif": "image/heif",
186383
- ".avif": "image/avif",
186384
- ".svgz": "image/svg+xml"
186385
- });
186386
- VIDEO_MIME_BY_SUFFIX$1 = Object.freeze({
186387
- ".mp4": "video/mp4",
186388
- ".mpg": "video/mpeg",
186389
- ".mpeg": "video/mpeg",
186390
- ".mkv": "video/x-matroska",
186391
- ".avi": "video/x-msvideo",
186392
- ".mov": "video/quicktime",
186393
- ".ogv": "video/ogg",
186394
- ".wmv": "video/x-ms-wmv",
186395
- ".webm": "video/webm",
186396
- ".m4v": "video/x-m4v",
186397
- ".flv": "video/x-flv",
186398
- ".3gp": "video/3gpp",
186399
- ".3g2": "video/3gpp2"
186400
- });
186401
- TEXT_MIME_BY_SUFFIX = Object.freeze({ ".svg": "image/svg+xml" });
186402
- NON_TEXT_SUFFIXES = new Set([
186403
- ".icns",
186404
- ".psd",
186405
- ".ai",
186406
- ".eps",
186407
- ".pdf",
186408
- ".doc",
186409
- ".docx",
186410
- ".dot",
186411
- ".dotx",
186412
- ".rtf",
186413
- ".odt",
186414
- ".xls",
186415
- ".xlsx",
186416
- ".xlsm",
186417
- ".xlt",
186418
- ".xltx",
186419
- ".xltm",
186420
- ".ods",
186421
- ".ppt",
186422
- ".pptx",
186423
- ".pptm",
186424
- ".pps",
186425
- ".ppsx",
186426
- ".odp",
186427
- ".pages",
186428
- ".numbers",
186429
- ".key",
186430
- ".zip",
186431
- ".rar",
186432
- ".7z",
186433
- ".tar",
186434
- ".gz",
186435
- ".tgz",
186436
- ".bz2",
186437
- ".xz",
186438
- ".zst",
186439
- ".lz",
186440
- ".lz4",
186441
- ".br",
186442
- ".cab",
186443
- ".ar",
186444
- ".deb",
186445
- ".rpm",
186446
- ".mp3",
186447
- ".wav",
186448
- ".flac",
186449
- ".ogg",
186450
- ".oga",
186451
- ".opus",
186452
- ".aac",
186453
- ".m4a",
186454
- ".wma",
186455
- ".ttf",
186456
- ".otf",
186457
- ".woff",
186458
- ".woff2",
186459
- ".exe",
186460
- ".dll",
186461
- ".so",
186462
- ".dylib",
186463
- ".bin",
186464
- ".apk",
186465
- ".ipa",
186466
- ".jar",
186467
- ".class",
186468
- ".pyc",
186469
- ".pyo",
186470
- ".wasm",
186471
- ".dmg",
186472
- ".iso",
186473
- ".img",
186474
- ".sqlite",
186475
- ".sqlite3",
186476
- ".db",
186477
- ".db3"
186478
- ]);
186479
- ASF_HEADER = Buffer.from([
186480
- 48,
186481
- 38,
186482
- 178,
186483
- 117,
186484
- 142,
186485
- 102,
186486
- 207,
186487
- 17,
186488
- 166,
186489
- 217,
186490
- 0,
186491
- 170,
186492
- 0,
186493
- 98,
186494
- 206,
186495
- 108
186496
- ]);
186497
- FTYP_IMAGE_BRANDS = Object.freeze({
186498
- avif: "image/avif",
186499
- avis: "image/avif",
186500
- heic: "image/heic",
186501
- heif: "image/heif",
186502
- heix: "image/heif",
186503
- hevc: "image/heic",
186504
- mif1: "image/heif",
186505
- msf1: "image/heif"
186506
- });
186507
- FTYP_VIDEO_BRANDS = Object.freeze({
186508
- isom: "video/mp4",
186509
- iso2: "video/mp4",
186510
- iso5: "video/mp4",
186511
- mp41: "video/mp4",
186512
- mp42: "video/mp4",
186513
- avc1: "video/mp4",
186514
- mp4v: "video/mp4",
186515
- m4v: "video/x-m4v",
186516
- qt: "video/quicktime",
186517
- "3gp4": "video/3gpp",
186518
- "3gp5": "video/3gpp",
186519
- "3gp6": "video/3gpp",
186520
- "3gp7": "video/3gpp",
186521
- "3g2": "video/3gpp2"
186522
- });
186523
- }));
186524
- //#endregion
186525
- //#region ../../packages/agent-core/src/utils/tokens.ts
186526
- /** Open assistant messages grow while streaming; completed history stays cached. */
186527
- function invalidateMessageTokenEstimate(message) {
186528
- messageTokenEstimateCache.delete(message);
186529
- }
186530
- /**
186531
- * Estimate token count from text using a character-based heuristic.
186532
- * - ASCII (~4 chars per token)
186533
- * - CJK and other non-ASCII (~1 char per token)
186534
- * The estimate is transient — the next LLM call returns the real count
186535
- * and supersedes this value. Used to keep `tokenCountWithPending`
186536
- * monotonic between LLM round-trips without paying for a tokenizer.
186537
- */
186538
- function estimateTokens(text) {
186539
- let asciiCount = 0;
186540
- let nonAsciiCount = 0;
186541
- for (const char of text) if (char.codePointAt(0) <= 127) asciiCount++;
186542
- else nonAsciiCount++;
186543
- return Math.ceil(asciiCount / 4) + nonAsciiCount;
186544
- }
186545
- function estimateTokensForMessages(messages) {
186546
- let total = 0;
186547
- for (const message of messages) total += estimateTokensForMessage(message);
186548
- return total;
186549
- }
186550
- function estimateTokensForTools(tools) {
186551
- let total = 0;
186552
- for (const tool of tools) {
186553
- total += estimateTokens(tool.name);
186554
- total += estimateTokens(tool.description);
186555
- total += estimateTokens(JSON.stringify(tool.parameters));
186556
- }
186557
- return total;
186558
- }
186559
- function estimateTokensForMessage(message) {
186560
- const cached = messageTokenEstimateCache.get(message);
186561
- if (cached !== void 0) return cached;
186562
- let total = estimateTokens(message.role);
186563
- total += estimateTokensForContentParts(message.content);
186564
- if (message.toolCalls !== void 0) for (const call of message.toolCalls) {
186565
- total += estimateTokens(call.name);
186566
- total += estimateTokens(JSON.stringify(call.arguments));
186567
- }
186568
- messageTokenEstimateCache.set(message, total);
186569
- return total;
186570
- }
186571
- function estimateTokensForContentParts(parts) {
186572
- let total = 0;
186573
- for (const part of parts) total += estimateTokensForContentPart(part);
186574
- return total;
186575
- }
186576
- function imageDimensionsFromDataUrl(url) {
186577
- const commaIndex = url.indexOf(",");
186578
- if (commaIndex <= 0) return null;
186579
- const metadata = url.slice(0, commaIndex).toLowerCase();
186580
- if (!metadata.startsWith("data:image/") || !metadata.split(";").includes("base64")) return null;
186581
- const maxBase64Chars = Math.ceil(MAX_IMAGE_HEADER_BYTES / 3) * 4;
186582
- const encodedHeader = url.slice(commaIndex + 1, commaIndex + 1 + maxBase64Chars);
186583
- if (encodedHeader.length === 0) return null;
186584
- try {
186585
- const dimensions = sniffImageDimensions(Buffer.from(encodedHeader, "base64"));
186586
- if (dimensions === null || !Number.isSafeInteger(dimensions.width) || !Number.isSafeInteger(dimensions.height) || dimensions.width <= 0 || dimensions.height <= 0) return null;
186587
- return dimensions;
186588
- } catch {
186589
- return null;
186590
- }
186591
- }
186592
- function estimateImageTokensFromDimensions(width, height) {
186593
- if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width <= 0 || height <= 0) return MEDIA_TOKEN_ESTIMATE;
186594
- const patchSize = BigInt(32);
186595
- const tokens = (BigInt(width) + patchSize - 1n) / patchSize * ((BigInt(height) + patchSize - 1n) / patchSize);
186596
- return tokens > BigInt(Number.MAX_SAFE_INTEGER) ? Number.MAX_SAFE_INTEGER : Number(tokens);
186597
- }
186598
- function estimateImageTokens(url) {
186599
- const dimensions = imageDimensionsFromDataUrl(url);
186600
- return dimensions === null ? MEDIA_TOKEN_ESTIMATE : estimateImageTokensFromDimensions(dimensions.width, dimensions.height);
186601
- }
186602
- function estimateTokensForContentPart(part) {
186603
- switch (part.type) {
186604
- case "text": return estimateTokens(part.text);
186605
- case "think": return estimateTokens(part.think);
186606
- case "image_url": return estimateImageTokens(part.imageUrl.url);
186607
- case "audio_url":
186608
- case "video_url": return MEDIA_TOKEN_ESTIMATE;
186609
- default: return 0;
186610
- }
186611
- }
186612
- var messageTokenEstimateCache, MEDIA_TOKEN_ESTIMATE, MAX_IMAGE_HEADER_BYTES;
186613
- var init_tokens = __esmMin((() => {
186614
- init_file_type$1();
186615
- messageTokenEstimateCache = /* @__PURE__ */ new WeakMap();
186616
- MEDIA_TOKEN_ESTIMATE = 2e3;
186617
- MAX_IMAGE_HEADER_BYTES = 1024 * 1024;
186618
- }));
186619
- //#endregion
186620
186880
  //#region ../../node_modules/.pnpm/bmp-ts@1.0.9/node_modules/bmp-ts/dist/esm/header-types.js
186621
186881
  var HeaderTypes, header_types_default;
186622
186882
  var init_header_types = __esmMin((() => {
@@ -192061,7 +192321,7 @@ var require_gifframe = /* @__PURE__ */ __commonJSMin(((exports) => {
192061
192321
  //#region ../../node_modules/.pnpm/gifwrap@0.10.1/node_modules/gifwrap/src/gifutil.js
192062
192322
  var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
192063
192323
  /** @namespace GifUtil */
192064
- const fs$13 = __require("fs");
192324
+ const fs$12 = __require("fs");
192065
192325
  const ImageQ = require_image_q();
192066
192326
  const BitmapImage = require_bitmapimage();
192067
192327
  const { GifFrame } = require_gifframe();
@@ -192328,7 +192588,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
192328
192588
  }
192329
192589
  function _readBinary(path) {
192330
192590
  return new Promise((resolve, reject) => {
192331
- fs$13.readFile(path, (err, buffer) => {
192591
+ fs$12.readFile(path, (err, buffer) => {
192332
192592
  if (err) return reject(err);
192333
192593
  return resolve(buffer);
192334
192594
  });
@@ -192336,7 +192596,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
192336
192596
  }
192337
192597
  function _writeBinary(path, buffer) {
192338
192598
  return new Promise((resolve, reject) => {
192339
- fs$13.writeFile(path, buffer, (err) => {
192599
+ fs$12.writeFile(path, buffer, (err) => {
192340
192600
  if (err) return reject(err);
192341
192601
  return resolve();
192342
192602
  });
@@ -218154,7 +218414,7 @@ var init_file_type = __esmMin((() => {
218154
218414
  }
218155
218415
  async fromFile(path) {
218156
218416
  this.options.signal?.throwIfAborted();
218157
- const fileHandle = await fs.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
218417
+ const fileHandle = await ro.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
218158
218418
  const fileStat = await fileHandle.stat();
218159
218419
  if (!fileStat.isFile()) {
218160
218420
  await fileHandle.close();
@@ -228659,7 +228919,7 @@ async function processBitmapFont(file, font) {
228659
228919
  ...font,
228660
228920
  chars,
228661
228921
  kernings,
228662
- pages: await Promise.all(font.pages.map(async (page) => CharacterJimp.read(path$1.join(path$1.dirname(file), page))))
228922
+ pages: await Promise.all(font.pages.map(async (page) => CharacterJimp.read(js.join(js.dirname(file), page))))
228663
228923
  };
228664
228924
  }
228665
228925
  var import_parse_bmfont_ascii, import_lib$1, import_parse_bmfont_binary, convertXML, isWebWorker, CharacterJimp, HEADER;
@@ -230997,7 +231257,7 @@ var init_full = __esmMin((() => {
230997
231257
  MAX_SESSION_COMPACTION_FAILURES = 2;
230998
231258
  DEFAULT_COMPACTION_MAX_COMPLETION_TOKENS = 128 * 1024;
230999
231259
  COMPACTION_SUMMARY_RESERVE_RATIO = .1;
231000
- BLUN_COMPACTION_REQUEST_BUDGET_BYTES = 75e4;
231260
+ BLUN_COMPACTION_REQUEST_BUDGET_BYTES = 48e4;
231001
231261
  MAX_HIERARCHICAL_COMPACTION_PASSES = 64;
231002
231262
  HIERARCHICAL_COMPACTION_PREFIX = "This is a complete summary of an earlier chronological segment. Preserve it as source material when merging it with the following conversation:";
231003
231263
  CompactionTruncatedError = class extends Error {
@@ -231153,26 +231413,10 @@ var init_full = __esmMin((() => {
231153
231413
  const model = this.agent.activeResponderModel ?? this.agent.config.modelAlias;
231154
231414
  if (model === void 0 || this.agent.config.runtimeModel(model).provider.name !== "blun") return void 0;
231155
231415
  const systemPrompt = context.systemPrompt ?? this.agent.effectiveSystemPrompt;
231156
- const tools = (context.tools ?? this.agent.tools.loopTools).map((tool) => ({
231157
- name: tool.name,
231158
- description: tool.description,
231159
- parameters: tool.parameters
231160
- }));
231161
- let extraBytes;
231162
- try {
231163
- extraBytes = estimateBlunRequestExtraBytes(tools, messages);
231164
- } catch {
231165
- return;
231166
- }
231167
- if (Buffer.byteLength(JSON.stringify({
231168
- systemPrompt,
231169
- messages: []
231170
- }), "utf8") >= BLUN_COMPACTION_REQUEST_BUDGET_BYTES) return void 0;
231416
+ const tools = context.tools ?? this.agent.tools.loopTools;
231417
+ if (estimateBlunSerializedBodyBytes(systemPrompt, [], []) + 4096 >= BLUN_COMPACTION_REQUEST_BUDGET_BYTES) return void 0;
231171
231418
  return {
231172
- usedRequestBytesEstimate: Buffer.byteLength(JSON.stringify({
231173
- systemPrompt,
231174
- messages
231175
- }), "utf8") + extraBytes.toolsBytes + extraBytes.visionBytes,
231419
+ usedRequestBytesEstimate: estimateBlunSerializedBodyBytes(systemPrompt, tools, messages) + 4096,
231176
231420
  thresholdRequestBytes: BLUN_COMPACTION_REQUEST_BUDGET_BYTES
231177
231421
  };
231178
231422
  }
@@ -231527,10 +231771,7 @@ var init_full = __esmMin((() => {
231527
231771
  dropOrphanResults: true
231528
231772
  }), createUserMessage(requestInstruction)], capability));
231529
231773
  };
231530
- const estimateRequestBytes = (messages) => Buffer.byteLength(JSON.stringify({
231531
- systemPrompt: this.agent.effectiveSystemPrompt,
231532
- messages
231533
- }), "utf8");
231774
+ const estimateRequestBytes = (messages) => estimateBlunSerializedBodyBytes(this.agent.effectiveSystemPrompt, compactionTools, messages) + 4096;
231534
231775
  while (true) {
231535
231776
  signal.throwIfAborted();
231536
231777
  if (hierarchicalPassCount >= MAX_HIERARCHICAL_COMPACTION_PASSES) throw new BlunError(ErrorCodes.COMPACTION_FAILED, `Compaction stopped after ${String(MAX_HIERARCHICAL_COMPACTION_PASSES)} staged requests without reaching a final summary. The conversation history was not changed.`, { details: {
@@ -235027,8 +235268,9 @@ function makeSyntheticToolResult(toolCallId) {
235027
235268
  }
235028
235269
  function mergeAdjacentUserMessages(history, onAnomaly) {
235029
235270
  const out = [];
235030
- for (const source of history) {
235031
- const message = prepareMessageForProjection(source, onAnomaly);
235271
+ const latestUserIndex = history.findLastIndex((message) => message.role === "user" && message.partial !== true && (message.origin === void 0 || message.origin.kind === "user"));
235272
+ for (const [index, source] of history.entries()) {
235273
+ const message = prepareMessageForProjection(source, onAnomaly, index < latestUserIndex);
235032
235274
  if (message === null) continue;
235033
235275
  const previous = out.at(-1);
235034
235276
  if (canMergeUserMessage(message) && previous !== void 0 && canMergeUserMessage(previous)) {
@@ -235039,7 +235281,7 @@ function mergeAdjacentUserMessages(history, onAnomaly) {
235039
235281
  }
235040
235282
  return out.map(stripContextMetadata);
235041
235283
  }
235042
- function prepareMessageForProjection(message, onAnomaly) {
235284
+ function prepareMessageForProjection(message, onAnomaly, historical = false) {
235043
235285
  if (message.partial === true) return null;
235044
235286
  let content;
235045
235287
  for (const [index, part] of message.content.entries()) {
@@ -235051,6 +235293,19 @@ function prepareMessageForProjection(message, onAnomaly) {
235051
235293
  });
235052
235294
  continue;
235053
235295
  }
235296
+ if (historical && message.role === "user" && part.type === "text") {
235297
+ const text = withoutHistoricalTelegramGroupReminder(part.text);
235298
+ if (text !== part.text) {
235299
+ content ??= message.content.slice(0, index);
235300
+ const shortened = {
235301
+ ...part,
235302
+ text
235303
+ };
235304
+ copyRequestTextOrigin(part, shortened, message.origin);
235305
+ content.push(shortened);
235306
+ continue;
235307
+ }
235308
+ }
235054
235309
  content?.push(part);
235055
235310
  }
235056
235311
  const next = content === void 0 ? message : {
@@ -235060,6 +235315,14 @@ function prepareMessageForProjection(message, onAnomaly) {
235060
235315
  if (next.role === "tool" && next.content.length === 0) throw new BlunError(ErrorCodes.REQUEST_INVALID, "Tool result message content cannot be empty after removing empty text blocks.", { details: { toolCallId: next.toolCallId } });
235061
235316
  return next.content.length === 0 && next.toolCalls.length === 0 ? null : next;
235062
235317
  }
235318
+ function withoutHistoricalTelegramGroupReminder(text) {
235319
+ if (!text.startsWith("<channel source=\"telegram\"") && !text.startsWith("You are connected to a Telegram channel.")) return text;
235320
+ const start = text.lastIndexOf(`</channel>\n[GRUPPENANTWORT:`);
235321
+ if (start < 0) return text;
235322
+ const reminder = text.slice(start + 10 + 1);
235323
+ if (!/^\[GRUPPENANTWORT:[^\r\n]*\]$/.test(reminder)) return text;
235324
+ return text.slice(0, start + 10);
235325
+ }
235063
235326
  function canMergeUserMessage(message) {
235064
235327
  return message.role === "user" && message.origin?.kind === "user";
235065
235328
  }
@@ -235191,6 +235454,7 @@ var init_context$2 = __esmMin((() => {
235191
235454
  init_tokens();
235192
235455
  init_xml_escape();
235193
235456
  init_compaction();
235457
+ init_tool_continuity();
235194
235458
  init_projector();
235195
235459
  init_types$6();
235196
235460
  init_types$6();
@@ -235201,6 +235465,8 @@ var init_context$2 = __esmMin((() => {
235201
235465
  TOOL_INTERRUPTED_ON_RESUME_OUTPUT$2 = "Tool execution was interrupted before its result was recorded. Do not assume the tool completed successfully.";
235202
235466
  ContextMemory = class {
235203
235467
  agent;
235468
+ mutationGeneration = randomUUID();
235469
+ mutationRevision = 0;
235204
235470
  _history = [];
235205
235471
  _tokenCount = 0;
235206
235472
  tokenCountCoveredMessageCount = 0;
@@ -235212,6 +235478,15 @@ var init_context$2 = __esmMin((() => {
235212
235478
  constructor(agent) {
235213
235479
  this.agent = agent;
235214
235480
  }
235481
+ publishMutation(reason) {
235482
+ if (this.agent.records.restoring) return;
235483
+ this.agent.emitEvent({
235484
+ type: "context.changed",
235485
+ generation: this.mutationGeneration,
235486
+ revision: ++this.mutationRevision,
235487
+ reason
235488
+ });
235489
+ }
235215
235490
  get lastAssistantAt() {
235216
235491
  return this._lastAssistantAt;
235217
235492
  }
@@ -235365,6 +235640,7 @@ var init_context$2 = __esmMin((() => {
235365
235640
  return removedMessages.size;
235366
235641
  }
235367
235642
  clear() {
235643
+ const changed = this._history.length > 0;
235368
235644
  this.agent.records.logRecord({ type: "context.clear" });
235369
235645
  this._history = [];
235370
235646
  this._tokenCount = 0;
@@ -235376,6 +235652,7 @@ var init_context$2 = __esmMin((() => {
235376
235652
  this.agent.microCompaction.reset();
235377
235653
  this.agent.injection.onContextClear();
235378
235654
  this.agent.emitStatusUpdated();
235655
+ if (changed) this.publishMutation("clear");
235379
235656
  }
235380
235657
  undo(count) {
235381
235658
  if (count <= 0) return;
@@ -235413,6 +235690,7 @@ var init_context$2 = __esmMin((() => {
235413
235690
  this.deferredMessages = [];
235414
235691
  this.agent.microCompaction.reset(this._history.length);
235415
235692
  this.agent.emitStatusUpdated();
235693
+ if (removedMessages.size > 0) this.publishMutation("undo");
235416
235694
  if (!this.agent.records.restoring && (stoppedAtBoundary || removedUserCount < count)) throw new BlunError(ErrorCodes.REQUEST_INVALID, formatUndoUnavailableMessage(count, removedUserCount, stoppedAtBoundary), { details: {
235417
235695
  reason: "undo_limit",
235418
235696
  requestedCount: count,
@@ -235421,6 +235699,7 @@ var init_context$2 = __esmMin((() => {
235421
235699
  } });
235422
235700
  }
235423
235701
  applyCompaction(input, options = {}) {
235702
+ if (this.agent.records.restoring !== null && input.toolContinuity !== void 0 && !isToolContinuity(input.toolContinuity)) throw new Error("Invalid compaction tool continuity");
235424
235703
  let preservedToolTailCount = input.preservedToolTailCount;
235425
235704
  if (this.agent.records.restoring === null && this.hasOpenToolExchange()) {
235426
235705
  const start = this._history.findIndex((message) => message.role === "assistant" && message.toolCalls.some((call) => this.pendingToolResultIds.has(call.id)));
@@ -235457,25 +235736,75 @@ var init_context$2 = __esmMin((() => {
235457
235736
  elisionMessage,
235458
235737
  ...selection.tail
235459
235738
  ];
235460
- const contextSummary = input.contextSummary ?? input.summary;
235461
- const summaryMessage = {
235739
+ let contextSummary = input.contextSummary ?? input.summary;
235740
+ let toolContinuity = this.agent.records.restoring === null ? void 0 : input.toolContinuity;
235741
+ let summaryMessage = {
235462
235742
  role: "user",
235463
235743
  content: [{
235464
235744
  type: "text",
235465
235745
  text: contextSummary
235466
235746
  }],
235467
235747
  toolCalls: [],
235468
- origin: { kind: "compaction_summary" }
235748
+ origin: {
235749
+ kind: "compaction_summary",
235750
+ ...toolContinuity === void 0 ? {} : { toolContinuity }
235751
+ }
235469
235752
  };
235470
- const replacement = [
235753
+ let replacement = [
235471
235754
  ...keptMessages,
235472
235755
  summaryMessage,
235473
235756
  ...preservedToolTail
235474
235757
  ];
235758
+ const previousHistoryTokens = options.requireReduction && this.agent.records.restoring === null ? estimateTokensForMessages(project(this.agent.microCompaction.compact(this._history), { dropOrphanResults: true })) : void 0;
235759
+ if (this.agent.records.restoring === null) {
235760
+ toolContinuity = void 0;
235761
+ const observations = collectToolContinuity(this._history.slice(0, tailStart));
235762
+ if (observations !== void 0) {
235763
+ const baseProjected = project(replacement, { dropOrphanResults: true });
235764
+ const baseTokens = estimateTokensForMessages(baseProjected);
235765
+ let extraTokens = previousHistoryTokens === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, previousHistoryTokens - baseTokens - 1);
235766
+ if (this.agent.config.hasProvider) {
235767
+ const window = this.agent.fullCompaction.getEffectiveMaxContextTokens();
235768
+ const budget = this.agent.fullCompaction.getCompactionBudgetTokens();
235769
+ const requestLimit = Math.min(window > 0 ? window - 1 : Number.POSITIVE_INFINITY, budget ?? Number.POSITIVE_INFINITY);
235770
+ extraTokens = Math.min(extraTokens, Math.max(0, requestLimit - this.agent.fullCompaction.estimateProjectedRequestTokens({ messages: baseProjected }) - 1));
235771
+ }
235772
+ let fitted = fitToolContinuity(observations, extraTokens);
235773
+ while (fitted !== void 0) {
235774
+ const candidateSummary = {
235775
+ ...summaryMessage,
235776
+ content: [{
235777
+ type: "text",
235778
+ text: contextSummary + fitted.text
235779
+ }],
235780
+ origin: {
235781
+ kind: "compaction_summary",
235782
+ toolContinuity: fitted.continuity
235783
+ }
235784
+ };
235785
+ const candidate = [
235786
+ ...keptMessages,
235787
+ candidateSummary,
235788
+ ...preservedToolTail
235789
+ ];
235790
+ const projected = project(candidate, { dropOrphanResults: true });
235791
+ const status = this.agent.fullCompaction.proactiveCompactionStatus({ messages: projected });
235792
+ const reducing = previousHistoryTokens === void 0 || estimateTokensForMessages(projected) < previousHistoryTokens;
235793
+ const bytesFit = (status.usedHistoryBytes === void 0 || status.thresholdHistoryBytes === void 0 || status.usedHistoryBytes < status.thresholdHistoryBytes) && (status.usedRequestBytesEstimate === void 0 || status.thresholdRequestBytes === void 0 || status.usedRequestBytesEstimate < status.thresholdRequestBytes);
235794
+ if (reducing && bytesFit) {
235795
+ toolContinuity = fitted.continuity;
235796
+ contextSummary += fitted.text;
235797
+ summaryMessage = candidateSummary;
235798
+ replacement = candidate;
235799
+ break;
235800
+ }
235801
+ fitted = fitToolContinuity(observations, estimateTokens(fitted.text) - 1);
235802
+ }
235803
+ }
235804
+ }
235475
235805
  if (options.requireReduction && this.agent.records.restoring === null) {
235476
- const previousHistoryTokens = estimateTokensForMessages(project(this.agent.microCompaction.compact(this._history), { dropOrphanResults: true }));
235477
235806
  const nextHistoryTokens = estimateTokensForMessages(project(replacement, { dropOrphanResults: true }));
235478
- if (nextHistoryTokens >= previousHistoryTokens) throw new BlunError(ErrorCodes.COMPACTION_FAILED, "Automatic compaction did not reduce the history. The conversation history was not changed.", { details: {
235807
+ if (previousHistoryTokens !== void 0 && nextHistoryTokens >= previousHistoryTokens) throw new BlunError(ErrorCodes.COMPACTION_FAILED, "Automatic compaction did not reduce the history. The conversation history was not changed.", { details: {
235479
235808
  reason: "non_reducing_summary",
235480
235809
  contextUnchanged: true,
235481
235810
  previousHistoryTokens,
@@ -235488,6 +235817,7 @@ var init_context$2 = __esmMin((() => {
235488
235817
  const result = {
235489
235818
  summary: input.summary,
235490
235819
  contextSummary,
235820
+ ...toolContinuity === void 0 ? {} : { toolContinuity },
235491
235821
  compactedCount: input.compactedCount,
235492
235822
  tokensBefore: input.tokensBefore,
235493
235823
  tokensAfter,
@@ -235504,6 +235834,7 @@ var init_context$2 = __esmMin((() => {
235504
235834
  this.agent.replayBuilder.patchLast("compaction", { result: {
235505
235835
  summary: result.summary,
235506
235836
  contextSummary: result.contextSummary,
235837
+ ...result.toolContinuity === void 0 ? {} : { toolContinuity: result.toolContinuity },
235507
235838
  compactedCount: result.compactedCount,
235508
235839
  tokensBefore: result.tokensBefore,
235509
235840
  tokensAfter: result.tokensAfter,
@@ -237058,20 +237389,75 @@ function fingerprintTitle(title) {
237058
237389
  return createHash("sha256").update(title.trim().toLowerCase()).digest("hex");
237059
237390
  }
237060
237391
  async function loadRegister(mistakeDir = defaultMistakeDir()) {
237392
+ const target = join(mistakeDir, REGISTER_FILENAME);
237061
237393
  try {
237062
237394
  await mkdir(mistakeDir, { recursive: true });
237063
- const content = await readFile(join(mistakeDir, REGISTER_FILENAME), "utf-8");
237064
- return JSON.parse(content);
237065
- } catch {
237066
- return {
237395
+ const before = await lstat(target).catch((error) => {
237396
+ if (error.code === "ENOENT") return void 0;
237397
+ throw error;
237398
+ });
237399
+ if (before === void 0) return {
237067
237400
  version: 1,
237068
237401
  entries: []
237069
237402
  };
237403
+ if (!before.isFile() || before.isSymbolicLink()) throw new Error("Mistake register must be a regular file.");
237404
+ const handle = await open(target, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
237405
+ let content;
237406
+ try {
237407
+ const opened = await handle.stat();
237408
+ if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino) throw new Error("Mistake register changed while opening.");
237409
+ content = await handle.readFile("utf8");
237410
+ } finally {
237411
+ await handle.close();
237412
+ }
237413
+ let parsed;
237414
+ try {
237415
+ parsed = JSON.parse(content);
237416
+ } catch {
237417
+ throw new Error("Mistake register has invalid JSON.");
237418
+ }
237419
+ assertRegister(parsed);
237420
+ return parsed;
237421
+ } catch (error) {
237422
+ throw registerError(error, "read");
237070
237423
  }
237071
237424
  }
237072
237425
  async function saveRegister(register, mistakeDir = defaultMistakeDir()) {
237073
- await mkdir(mistakeDir, { recursive: true });
237074
- await writeFile(join(mistakeDir, REGISTER_FILENAME), JSON.stringify(register, null, 2), "utf-8");
237426
+ assertRegister(register);
237427
+ const target = join(mistakeDir, REGISTER_FILENAME);
237428
+ const temporary = `${target}.tmp.${process.pid}.${randomUUID()}`;
237429
+ let created = false;
237430
+ try {
237431
+ await loadRegister(mistakeDir);
237432
+ const handle = await open(temporary, "wx", 384);
237433
+ created = true;
237434
+ try {
237435
+ await handle.writeFile(JSON.stringify(register, null, 2), "utf8");
237436
+ await handle.sync();
237437
+ } finally {
237438
+ await handle.close();
237439
+ }
237440
+ await rename(temporary, target);
237441
+ } catch (error) {
237442
+ throw registerError(error, "write");
237443
+ } finally {
237444
+ if (created) await unlink(temporary).catch(() => {});
237445
+ }
237446
+ }
237447
+ function assertRegister(value) {
237448
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Mistake register has an invalid v1 schema.");
237449
+ const register = value;
237450
+ if (register["version"] !== 1 || !Array.isArray(register["entries"]) || !register["entries"].every((entry) => {
237451
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return false;
237452
+ const fields = entry;
237453
+ return typeof fields["entryIndex"] === "number" && Number.isSafeInteger(fields["entryIndex"]) && fields["entryIndex"] >= 0 && typeof fields["titleFingerprint"] === "string" && fields["titleFingerprint"].trim().length > 0 && typeof fields["title"] === "string" && fields["title"].trim().length > 0 && typeof fields["count"] === "number" && Number.isSafeInteger(fields["count"]) && fields["count"] >= 0 && typeof fields["lastHitAt"] === "string" && fields["lastHitAt"].trim().length > 0 && (fields["origin"] === "program" || fields["origin"] === "hand");
237454
+ })) throw new Error("Mistake register has an invalid v1 schema.");
237455
+ }
237456
+ function registerError(error, operation) {
237457
+ if (error instanceof Error && error.message.startsWith("Mistake register ")) return error;
237458
+ const code = typeof error === "object" && error !== null ? error.code : void 0;
237459
+ const suffix = typeof code === "string" && /^[A-Z0-9_]+$/u.test(code) ? ` (${code})` : "";
237460
+ return /* @__PURE__ */ new Error(`Mistake register ${operation} failed${suffix}.`);
237075
237461
  }
237076
237462
  /**
237077
237463
  * Findet einen Register-Eintrag anhand des Titels (Fingerabdruck).
@@ -239861,6 +240247,7 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
239861
240247
  const DEFERRED_TOOL_LOADER_NAME = "ToolSearch";
239862
240248
  const MAX_PERSISTENT_DEFERRED_TOOLS = 12;
239863
240249
  const MAX_TOOL_SEARCH_QUERY_CHARS = 1e3;
240250
+ const MAX_TOOL_CATALOG_RESULT_BYTES = 4096;
239864
240251
  const MAX_AUTO_RANKED_TOOLS = 6;
239865
240252
  const deferredToolLoaders = /* @__PURE__ */ new WeakSet();
239866
240253
  const TOOL_RANK_EMBEDDED_CONTENT_RE = /<(attached_documents?|attachment_content|document_content|file_content)\b[^>]*>[\s\S]*?<\/\1>/giu;
@@ -240105,6 +240492,27 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240105
240492
  for (const leaf of leaves) leafCounts.set(leaf, (leafCounts.get(leaf) || 0) + 1);
240106
240493
  return names.map((name, index) => leafCounts.get(leaves[index]) === 1 ? leaves[index] : name).sort((left, right) => left.localeCompare(right));
240107
240494
  }
240495
+ function boundedDeferredToolCatalog(tools, filter) {
240496
+ const needle = filter.toLowerCase();
240497
+ const matched = deferredToolCatalog(tools).filter((name) => name.toLowerCase().includes(needle));
240498
+ const names = [];
240499
+ let bytes = Buffer.byteLength(JSON.stringify({
240500
+ names,
240501
+ total: matched.length,
240502
+ truncated: false
240503
+ }));
240504
+ for (const name of matched) {
240505
+ const nextBytes = Buffer.byteLength(JSON.stringify(name)) + (names.length > 0 ? 1 : 0);
240506
+ if (bytes + nextBytes > MAX_TOOL_CATALOG_RESULT_BYTES) break;
240507
+ names.push(name);
240508
+ bytes += nextBytes;
240509
+ }
240510
+ return JSON.stringify({
240511
+ names,
240512
+ total: matched.length,
240513
+ truncated: names.length < matched.length
240514
+ });
240515
+ }
240108
240516
  function normalizeDeferredToolQuery(value) {
240109
240517
  const query = String(value ?? "").trim();
240110
240518
  if (query.length <= MAX_TOOL_SEARCH_QUERY_CHARS) return query;
@@ -240179,14 +240587,14 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240179
240587
  function rankingTokens(value) {
240180
240588
  return [...new Set(String(value || "").normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}]{3,}/gu) || [])].filter((token) => !TOOL_RANK_STOP_WORDS.has(token));
240181
240589
  }
240182
- function toolRankingDocument(tool) {
240590
+ function toolRankingDocument(tool, trustedToolNames) {
240183
240591
  const name = String(tool?.name || "");
240184
240592
  const leaf = name.split(/__|:/).at(-1) || name;
240185
240593
  const splitToolName = (value) => String(value || "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replaceAll("_", " ");
240186
240594
  const nameTokens = rankingTokens(`${splitToolName(name)} ${splitToolName(leaf)}`);
240187
240595
  const descriptionTokens = rankingTokens(tool?.description);
240188
240596
  const parameterText = [];
240189
- const properties = tool?.parameters?.properties;
240597
+ const properties = /^mcp__/iu.test(name) && !trustedToolNames?.has(name) ? void 0 : tool?.parameters?.properties;
240190
240598
  if (properties && typeof properties === "object") for (const [parameterName, definition] of Object.entries(properties)) parameterText.push(parameterName, definition?.description || "");
240191
240599
  const exampleText = Array.isArray(tool?.examples) ? tool.examples.map((example) => example?.prompt || "").join(" ") : "";
240192
240600
  return {
@@ -240218,7 +240626,7 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240218
240626
  const queryTokens = [...new Set(rankingIntentTexts(value).flatMap(rankingTokens))];
240219
240627
  if (queryTokens.length === 0) return /* @__PURE__ */ new Set();
240220
240628
  const ranked = (Array.isArray(tools) ? tools : []).map((tool) => {
240221
- const document = toolRankingDocument(tool);
240629
+ const document = toolRankingDocument(tool, options.trustedToolNames);
240222
240630
  if (!document.name) return null;
240223
240631
  let score = 0;
240224
240632
  let matchedTokens = 0;
@@ -240326,8 +240734,8 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240326
240734
  name: loaderName,
240327
240735
  description: [
240328
240736
  `Search ${deferredCount} deferred ${deferredCount === 1 ? "tool schema" : "tool schemas"} without loading all definitions.`,
240329
- "Use select:leaf_name for one known tool, plain keywords to search, or +word to require that word in the tool name.",
240330
- `Loaded tools are available in the next step; the ${MAX_PERSISTENT_DEFERRED_TOOLS} most recently selected schemas remain loaded.`
240737
+ "Use select:leaf_name for one known tool, plain keywords to search, +word to require a name word, or catalog:fragment to list matching names.",
240738
+ `Loaded tools are available in the next step; up to ${MAX_PERSISTENT_DEFERRED_TOOLS} recently selected schemas remain loaded when the context budget allows.`
240331
240739
  ].join("\n"),
240332
240740
  parameters: {
240333
240741
  type: "object",
@@ -240344,7 +240752,12 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240344
240752
  return {
240345
240753
  description: query ? `Searching tool schemas for ${query}` : "Searching tool schemas",
240346
240754
  approvalRule: loaderName,
240347
- execute: async () => {
240755
+ execute: async (context) => {
240756
+ context?.signal?.throwIfAborted();
240757
+ if (query.toLowerCase().startsWith("catalog:")) return {
240758
+ isError: false,
240759
+ output: boundedDeferredToolCatalog([...available.values()], query.slice(8).trim())
240760
+ };
240348
240761
  let matches = searchDeferredTools([...available.values()], query);
240349
240762
  let relatedFallback = false;
240350
240763
  if (matches.length === 0) {
@@ -252331,7 +252744,7 @@ var init_modelCatalog$2 = __esmMin((() => {
252331
252744
  function isVolatileEventType(type) {
252332
252745
  return volatileEventTypeSet.has(type);
252333
252746
  }
252334
- var MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE, tokenUsageSchema, finishReasonSchema, usageStatusSchema, permissionModeSchema, skillSourceSchema, userPromptOriginSchema, skillActivationOriginSchema, pluginCommandOriginSchema, injectionOriginSchema, shellCommandOriginSchema, compactionSummaryOriginSchema, systemTriggerOriginSchema, agentCoreBackgroundTaskStatusSchema, backgroundTaskOriginSchema, cronJobOriginSchema, cronMissedOriginSchema, hookResultOriginSchema, retryOriginSchema, promptOriginSchema, goalStatusSchema, goalActorSchema, goalBudgetReportSchema, goalSnapshotSchema, goalChangeStatsSchema, goalChangeKindSchema, goalChangeSchema, blunErrorCodeSchema, blunErrorPayloadSchema, backgroundTaskInfoBaseSchema, processBackgroundTaskInfoSchema, agentBackgroundTaskInfoSchema, questionBackgroundTaskInfoSchema, backgroundTaskInfoSchema, compactionResultSchema, toolUpdateSchema, turnEndReasonSchema, agentStatusUpdatedEventSchema, sessionMetaUpdatedEventSchema, sessionCreatedEventSchema, workspaceCreatedEventSchema, workspaceUpdatedEventSchema, workspaceDeletedEventSchema, sessionStatusChangedEventSchema, modelCatalogChangedEventSchema, goalUpdatedEventSchema, skillActivatedEventSchema, pluginCommandActivatedEventSchema, errorEventSchema, warningEventSchema, turnStartedEventSchema, turnEndedEventSchema, turnStepStartedEventSchema, turnStepCompletedEventSchema, turnStepRetryingEventSchema, turnStepInterruptedEventSchema, assistantDeltaEventSchema, hookResultEventSchema, thinkingDeltaEventSchema, toolCallDeltaEventSchema, toolCallStartedEventSchema, toolProgressEventSchema, shellOutputEventSchema, shellStartedEventSchema, toolResultEventSchema, subagentSpawnedEventSchema, subagentStartedEventSchema, subagentSuspendedEventSchema, subagentCompletedEventSchema, subagentFailedEventSchema, compactionStartedEventSchema, compactionBlockedEventSchema, compactionCancelledEventSchema, compactionProgressEventSchema, compactionCompletedEventSchema, backgroundTaskStartedEventSchema, backgroundTaskTerminatedEventSchema, cronFiredEventSchema, cronRunUpdatedEventSchema, promptSubmittedEventSchema, toolListUpdatedReasonSchema, toolListUpdatedEventSchema, mcpServerStatusPayloadSchema, mcpServerStatusEventSchema, mediaDroppedEventSchema, agentEventSchema, eventSchema, VOLATILE_EVENT_TYPES, volatileEventTypeSet;
252747
+ var MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE, tokenUsageSchema, finishReasonSchema, usageStatusSchema, permissionModeSchema, skillSourceSchema, userPromptOriginSchema, skillActivationOriginSchema, pluginCommandOriginSchema, injectionOriginSchema, shellCommandOriginSchema, compactionSummaryOriginSchema, systemTriggerOriginSchema, agentCoreBackgroundTaskStatusSchema, backgroundTaskOriginSchema, cronJobOriginSchema, cronMissedOriginSchema, hookResultOriginSchema, retryOriginSchema, promptOriginSchema, goalStatusSchema, goalActorSchema, goalBudgetReportSchema, goalSnapshotSchema, goalChangeStatsSchema, goalChangeKindSchema, goalChangeSchema, blunErrorCodeSchema, blunErrorPayloadSchema, backgroundTaskInfoBaseSchema, processBackgroundTaskInfoSchema, agentBackgroundTaskInfoSchema, questionBackgroundTaskInfoSchema, backgroundTaskInfoSchema, compactionResultSchema, toolUpdateSchema, turnEndReasonSchema, contextChangedEventSchema, agentStatusUpdatedEventSchema, sessionMetaUpdatedEventSchema, sessionCreatedEventSchema, workspaceCreatedEventSchema, workspaceUpdatedEventSchema, workspaceDeletedEventSchema, sessionStatusChangedEventSchema, modelCatalogChangedEventSchema, goalUpdatedEventSchema, skillActivatedEventSchema, pluginCommandActivatedEventSchema, errorEventSchema, warningEventSchema, turnStartedEventSchema, turnEndedEventSchema, turnStepStartedEventSchema, turnStepCompletedEventSchema, turnStepRetryingEventSchema, turnStepInterruptedEventSchema, assistantDeltaEventSchema, hookResultEventSchema, thinkingDeltaEventSchema, toolCallDeltaEventSchema, toolCallStartedEventSchema, toolProgressEventSchema, shellOutputEventSchema, shellStartedEventSchema, toolResultEventSchema, subagentSpawnedEventSchema, subagentStartedEventSchema, subagentSuspendedEventSchema, subagentCompletedEventSchema, subagentFailedEventSchema, compactionStartedEventSchema, compactionBlockedEventSchema, compactionCancelledEventSchema, compactionProgressEventSchema, compactionCompletedEventSchema, backgroundTaskStartedEventSchema, backgroundTaskTerminatedEventSchema, cronFiredEventSchema, cronRunUpdatedEventSchema, promptSubmittedEventSchema, toolListUpdatedReasonSchema, toolListUpdatedEventSchema, mcpServerStatusPayloadSchema, mcpServerStatusEventSchema, mediaDroppedEventSchema, agentEventSchema, eventSchema, VOLATILE_EVENT_TYPES, volatileEventTypeSet;
252335
252748
  var init_events$1 = __esmMin((() => {
252336
252749
  init_zod$1();
252337
252750
  init_display();
@@ -252507,7 +252920,11 @@ var init_events$1 = __esmMin((() => {
252507
252920
  tokensUsed: number$1(),
252508
252921
  wallClockMs: number$1()
252509
252922
  });
252510
- goalChangeKindSchema = _enum(["lifecycle", "completion"]);
252923
+ goalChangeKindSchema = _enum([
252924
+ "lifecycle",
252925
+ "completion",
252926
+ "edited"
252927
+ ]);
252511
252928
  goalChangeSchema = object$1({
252512
252929
  kind: goalChangeKindSchema,
252513
252930
  status: goalStatusSchema.optional(),
@@ -252664,6 +253081,12 @@ var init_events$1 = __esmMin((() => {
252664
253081
  "failed",
252665
253082
  "filtered"
252666
253083
  ]);
253084
+ contextChangedEventSchema = object$1({
253085
+ type: literal("context.changed"),
253086
+ generation: string().uuid(),
253087
+ revision: number$1().int().positive().max(Number.MAX_SAFE_INTEGER),
253088
+ reason: _enum(["clear", "undo"])
253089
+ });
252667
253090
  agentStatusUpdatedEventSchema = object$1({
252668
253091
  type: literal("agent.status.updated"),
252669
253092
  model: string().optional(),
@@ -253000,6 +253423,7 @@ var init_events$1 = __esmMin((() => {
253000
253423
  errorEventSchema,
253001
253424
  warningEventSchema,
253002
253425
  agentStatusUpdatedEventSchema,
253426
+ contextChangedEventSchema,
253003
253427
  sessionMetaUpdatedEventSchema,
253004
253428
  sessionCreatedEventSchema,
253005
253429
  workspaceCreatedEventSchema,
@@ -259338,7 +259762,7 @@ function Yn(s, t) {
259338
259762
  function Kn(s, t) {
259339
259763
  s.head = new ue$1(t, void 0, s.head, s), s.tail || (s.tail = s.head), s.length++;
259340
259764
  }
259341
- 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;
259765
+ 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;
259342
259766
  var init_index_min = __esmMin((() => {
259343
259767
  zr = Object.defineProperty;
259344
259768
  Ur = (s, t) => {
@@ -260866,7 +261290,7 @@ while (this[Zs](this[st$1].shift()));
260866
261290
  let [o, h] = ce$1(this.path);
260867
261291
  o && typeof h == "string" && (this.path = h, r = o);
260868
261292
  }
260869
- this.win32 = !!i.win32 || process.platform === "win32", this.win32 && (this.path = Qs(this.path.replaceAll(/\\/g, "/")), t = t.replaceAll(/\\/g, "/")), this.absolute = f(i.absolute || path$1.resolve(this.cwd, t)), this.path === "" && (this.path = "./"), r && this.warn("TAR_ENTRY_INFO", `stripping ${r} from absolute path`, {
261293
+ this.win32 = !!i.win32 || process.platform === "win32", this.win32 && (this.path = Qs(this.path.replaceAll(/\\/g, "/")), t = t.replaceAll(/\\/g, "/")), this.absolute = f(i.absolute || js.resolve(this.cwd, t)), this.path === "" && (this.path = "./"), r && this.warn("TAR_ENTRY_INFO", `stripping ${r} from absolute path`, {
260870
261294
  entry: this,
260871
261295
  path: r + this.path
260872
261296
  });
@@ -260949,7 +261373,7 @@ while (this[Zs](this[st$1].shift()));
260949
261373
  }
260950
261374
  [sr](t) {
260951
261375
  if (!this.stat) throw new Error("cannot create link entry without stat");
260952
- this.type = "Link", this.linkpath = f(path$1.relative(this.cwd, t)), this.stat.size = 0, this[fe$1](), this.end();
261376
+ this.type = "Link", this.linkpath = f(js.relative(this.cwd, t)), this.stat.size = 0, this[fe$1](), this.end();
260953
261377
  }
260954
261378
  [er]() {
260955
261379
  if (!this.stat) throw new Error("cannot create file entry without stat");
@@ -261308,7 +261732,7 @@ while (this[Zs](this[st$1].shift()));
261308
261732
  constructor(t, e) {
261309
261733
  this.path = t || "./", this.absolute = e;
261310
261734
  }
261311
- }, 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 {
261735
+ }, 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 {
261312
261736
  sync = !1;
261313
261737
  opt;
261314
261738
  cwd;
@@ -261341,8 +261765,8 @@ while (this[Zs](this[st$1].shift()));
261341
261765
  if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
261342
261766
  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");
261343
261767
  let e = this.zip;
261344
- e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$12]()), this.on("resume", () => e.resume());
261345
- } else this.on("drain", this[fs$12]);
261768
+ e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$11]()), this.on("resume", () => e.resume());
261769
+ } else this.on("drain", this[fs$11]);
261346
261770
  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;
261347
261771
  }
261348
261772
  [lr](t) {
@@ -261359,7 +261783,7 @@ while (this[Zs](this[st$1].shift()));
261359
261783
  return typeof t == "string" ? this[ci](t) : this[or](t), this.flowing;
261360
261784
  }
261361
261785
  [or](t) {
261362
- let e = f(path$1.resolve(this.cwd, t.path));
261786
+ let e = f(js.resolve(this.cwd, t.path));
261363
261787
  if (!this.filter(t.path, t)) t.resume();
261364
261788
  else {
261365
261789
  let i = new pi(t.path, e);
@@ -261368,7 +261792,7 @@ while (this[Zs](this[st$1].shift()));
261368
261792
  this[Ft$1]();
261369
261793
  }
261370
261794
  [ci](t) {
261371
- let e = f(path$1.resolve(this.cwd, t));
261795
+ let e = f(js.resolve(this.cwd, t));
261372
261796
  this[W$1].push(new pi(t, e)), this[Ft$1]();
261373
261797
  }
261374
261798
  [ds](t) {
@@ -261469,7 +261893,7 @@ while (this[Zs](this[st$1].shift()));
261469
261893
  this.emit("error", e);
261470
261894
  }
261471
261895
  }
261472
- [fs$12]() {
261896
+ [fs$11]() {
261473
261897
  this[Et] && this[Et].entry && this[Et].entry.resume();
261474
261898
  }
261475
261899
  [di](t) {
@@ -261635,7 +262059,7 @@ while (this[Zs](this[st$1].shift()));
261635
262059
  E ? e(E) : x && a ? Es(x, o, h, (Le) => y(Le)) : n ? Kt.chmod(s, r, e) : e();
261636
262060
  };
261637
262061
  if (s === d) return no(s, y);
261638
- if (l) return fs.mkdir(s, {
262062
+ if (l) return ro.mkdir(s, {
261639
262063
  mode: r,
261640
262064
  recursive: !0
261641
262065
  }).then((E) => y(null, E ?? void 0), y);
@@ -262394,7 +262818,7 @@ var require_pend = /* @__PURE__ */ __commonJSMin(((exports, module) => {
262394
262818
  //#endregion
262395
262819
  //#region ../../node_modules/.pnpm/yauzl@3.3.0/node_modules/yauzl/fd-slicer.js
262396
262820
  var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262397
- var fs$11 = __require("fs");
262821
+ var fs$10 = __require("fs");
262398
262822
  var util$6 = __require("util");
262399
262823
  var stream$2 = __require("stream");
262400
262824
  var Readable = stream$2.Readable;
@@ -262419,7 +262843,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262419
262843
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
262420
262844
  var self = this;
262421
262845
  self.pend.go(function(cb) {
262422
- fs$11.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
262846
+ fs$10.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
262423
262847
  cb();
262424
262848
  callback(err, bytesRead, buffer);
262425
262849
  });
@@ -262428,7 +262852,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262428
262852
  FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
262429
262853
  var self = this;
262430
262854
  self.pend.go(function(cb) {
262431
- fs$11.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
262855
+ fs$10.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
262432
262856
  cb();
262433
262857
  callback(err, written, buffer);
262434
262858
  });
@@ -262448,7 +262872,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262448
262872
  self.refCount -= 1;
262449
262873
  if (self.refCount > 0) return;
262450
262874
  if (self.refCount < 0) throw new Error("invalid unref");
262451
- if (self.autoClose) fs$11.close(self.fd, onCloseDone);
262875
+ if (self.autoClose) fs$10.close(self.fd, onCloseDone);
262452
262876
  function onCloseDone(err) {
262453
262877
  if (err) self.emit("error", err);
262454
262878
  else self.emit("close");
@@ -262479,7 +262903,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262479
262903
  self.context.pend.go(function(cb) {
262480
262904
  if (self.destroyed) return cb();
262481
262905
  var buffer = Buffer.allocUnsafe(toRead);
262482
- fs$11.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
262906
+ fs$10.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
262483
262907
  if (err) self.destroy(err);
262484
262908
  else if (bytesRead === 0) {
262485
262909
  self.destroyed = true;
@@ -262525,7 +262949,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262525
262949
  }
262526
262950
  self.context.pend.go(function(cb) {
262527
262951
  if (self.destroyed) return cb();
262528
- fs$11.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
262952
+ fs$10.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
262529
262953
  if (err) {
262530
262954
  self.destroy();
262531
262955
  cb();
@@ -266239,9 +266663,16 @@ var init_tool_dedup = __esmMin((() => {
266239
266663
  }));
266240
266664
  //#endregion
266241
266665
  //#region ../../packages/agent-core/src/agent/turn/tool-result-budget.ts
266666
+ function toolResultMaxChars(maxContextTokens) {
266667
+ if (maxContextTokens === void 0 || !Number.isFinite(maxContextTokens) || maxContextTokens <= 0) return TOOL_RESULT_MAX_CHARS;
266668
+ if (maxContextTokens < 1e5) return 16e3;
266669
+ if (maxContextTokens < 2e5) return 32e3;
266670
+ return TOOL_RESULT_MAX_CHARS;
266671
+ }
266242
266672
  async function budgetToolResultForModel(options) {
266243
266673
  const text = persistableToolResultText(options.result.output);
266244
- if (text === void 0 || text.length <= TOOL_RESULT_MAX_CHARS) return options.result;
266674
+ const maxChars = toolResultMaxChars(options.maxContextTokens);
266675
+ if (text === void 0 || text.length <= maxChars) return options.result;
266245
266676
  if (options.result.truncated === true) return options.result;
266246
266677
  if (options.homedir === void 0) return options.result;
266247
266678
  if (text.includes("\0") || Buffer.from(text, "utf8").toString("utf8") !== text || text.split("\n").some((line) => line.length > 2e3)) return options.result;
@@ -266252,7 +266683,7 @@ async function budgetToolResultForModel(options) {
266252
266683
  toolCallId: options.toolCallId
266253
266684
  }, text);
266254
266685
  if (outputPath === void 0) return options.result;
266255
- const output = renderPersistedToolResult(options.toolName, options.toolCallId, text, outputPath);
266686
+ const output = renderPersistedToolResult(options.toolName, options.toolCallId, text, outputPath, maxChars);
266256
266687
  return options.result.isError === true ? {
266257
266688
  ...options.result,
266258
266689
  output,
@@ -266284,9 +266715,9 @@ async function saveToolResult(options, text) {
266284
266715
  return;
266285
266716
  }
266286
266717
  }
266287
- function renderPersistedToolResult(toolName, toolCallId, text, outputPath) {
266718
+ function renderPersistedToolResult(toolName, toolCallId, text, outputPath, maxChars) {
266288
266719
  const lines = [
266289
- `Tool output exceeded ${String(TOOL_RESULT_MAX_CHARS)} characters; showing a preview only.`,
266720
+ `Tool output exceeded ${String(maxChars)} characters; showing a preview only.`,
266290
266721
  `tool_name: ${toolName}`,
266291
266722
  `tool_call_id: ${toolCallId}`,
266292
266723
  `output_size_chars: ${String(text.length)}`,
@@ -266438,14 +266869,14 @@ async function readGitExecPath(deps, gitExe) {
266438
266869
  }
266439
266870
  }
266440
266871
  function gitBashCandidatesFromGitExe(gitExe) {
266441
- const normalizedGitExe = path$17.win32.normalize(normalizeWindowsPath(gitExe));
266442
- const gitDir = path$17.win32.dirname(normalizedGitExe);
266443
- const gitDirName = path$17.win32.basename(gitDir).toLowerCase();
266872
+ const normalizedGitExe = path$16.win32.normalize(normalizeWindowsPath(gitExe));
266873
+ const gitDir = path$16.win32.dirname(normalizedGitExe);
266874
+ const gitDirName = path$16.win32.basename(gitDir).toLowerCase();
266444
266875
  if (gitDirName !== "cmd" && gitDirName !== "bin") return;
266445
- return gitBashCandidatesFromGitRoot(path$17.win32.dirname(gitDir));
266876
+ return gitBashCandidatesFromGitRoot(path$16.win32.dirname(gitDir));
266446
266877
  }
266447
266878
  function gitBashCandidatesFromGitExecPath(execPath) {
266448
- const normalized = path$17.win32.normalize(normalizeWindowsPath(execPath));
266879
+ const normalized = path$16.win32.normalize(normalizeWindowsPath(execPath));
266449
266880
  const parts = normalized.split("\\");
266450
266881
  for (let i = parts.length - 1; i >= 0; i -= 1) {
266451
266882
  const segment = parts[i]?.toLowerCase();
@@ -266454,16 +266885,16 @@ function gitBashCandidatesFromGitExecPath(execPath) {
266454
266885
  if (root.length > 0) return gitBashCandidatesFromGitRoot(root);
266455
266886
  }
266456
266887
  }
266457
- return gitBashCandidatesFromGitRoot(path$17.win32.join(normalized, "..", ".."));
266888
+ return gitBashCandidatesFromGitRoot(path$16.win32.join(normalized, "..", ".."));
266458
266889
  }
266459
266890
  function gitBashCandidatesFromGitRoot(root) {
266460
- return [path$17.win32.normalize(path$17.win32.join(root, "bin", "bash.exe")), path$17.win32.normalize(path$17.win32.join(root, "usr", "bin", "bash.exe"))];
266891
+ return [path$16.win32.normalize(path$16.win32.join(root, "bin", "bash.exe")), path$16.win32.normalize(path$16.win32.join(root, "usr", "bin", "bash.exe"))];
266461
266892
  }
266462
266893
  function normalizeWindowsPath(path) {
266463
266894
  return path.replaceAll("/", "\\");
266464
266895
  }
266465
266896
  function isAbsoluteWindowsPath(path) {
266466
- return path$17.win32.isAbsolute(normalizeWindowsPath(path));
266897
+ return path$16.win32.isAbsolute(normalizeWindowsPath(path));
266467
266898
  }
266468
266899
  function dedupeWindowsPaths(paths) {
266469
266900
  const deduped = [];
@@ -268244,14 +268675,27 @@ function blunToolsForOrigin(tools, origin) {
268244
268675
  * the ordinary permission pipeline.
268245
268676
  */
268246
268677
  function blunSelectTurnTools(tools, maxContextTokens, loadedToolNames = /* @__PURE__ */ new Set(), requiredToolNames = /* @__PURE__ */ new Set(), selected = []) {
268247
- if (estimateTokensForTools(tools) <= (0, import_turn_tool_performance_policy.toolSchemaBudgetTokens)(maxContextTokens) || tools.some(import_turn_tool_performance_policy.isDeferredToolLoader)) {
268678
+ const schemaBudget = (0, import_turn_tool_performance_policy.toolSchemaBudgetTokens)(maxContextTokens);
268679
+ if (estimateTokensForTools(tools, schemaBudget) <= schemaBudget || tools.some(import_turn_tool_performance_policy.isDeferredToolLoader)) {
268248
268680
  selected.splice(0, selected.length, ...tools);
268249
268681
  return selected;
268250
268682
  }
268251
- selected.splice(0, selected.length, ...tools.filter((tool) => BLUN_LEAN_TOOL_NAMES.has(tool.name) || BLUN_LEAN_KEEP_RE.test(tool.name) || BLUN_LANGUAGE_REVIEW_TOOL_NAMES.has(tool.name) || loadedToolNames.has(tool.name) || requiredToolNames.has(tool.name)));
268252
- const names = new Set(selected.map((tool) => tool.name));
268253
- const deferred = tools.filter((tool) => !names.has(tool.name));
268254
- if (deferred.length > 0) selected.push((0, import_turn_tool_performance_policy.createDeferredToolLoader)(selected, deferred, loadedToolNames));
268683
+ const priorLoaderIndex = selected.findIndex(import_turn_tool_performance_policy.isDeferredToolLoader);
268684
+ const justLoaded = new Set(priorLoaderIndex < 0 ? [] : selected.slice(priorLoaderIndex + 1).filter((tool) => loadedToolNames.has(tool.name)).map((tool) => tool.name));
268685
+ const remembered = new Set(loadedToolNames);
268686
+ const choose = () => {
268687
+ selected.splice(0, selected.length, ...tools.filter((tool) => BLUN_LEAN_TOOL_NAMES.has(tool.name) || BLUN_LEAN_KEEP_RE.test(tool.name) || BLUN_LANGUAGE_REVIEW_TOOL_NAMES.has(tool.name) || remembered.has(tool.name) || requiredToolNames.has(tool.name)));
268688
+ const names = new Set(selected.map((tool) => tool.name));
268689
+ const deferred = tools.filter((tool) => !names.has(tool.name));
268690
+ if (deferred.length > 0) selected.push((0, import_turn_tool_performance_policy.createDeferredToolLoader)(selected, deferred, loadedToolNames));
268691
+ };
268692
+ choose();
268693
+ for (const name of loadedToolNames) {
268694
+ if (estimateTokensForTools(selected, schemaBudget) <= schemaBudget) break;
268695
+ if (justLoaded.has(name)) continue;
268696
+ if (!remembered.delete(name)) continue;
268697
+ choose();
268698
+ }
268255
268699
  return selected;
268256
268700
  }
268257
268701
  function goalContinuationOrigin(origin) {
@@ -269280,10 +269724,12 @@ var init_turn = __esmMin((() => {
269280
269724
  taskToolsNeeded ||= blunTurnNeedsTools(intent, origin) || blunTurnHasAttachment(toolInput);
269281
269725
  const required = (0, import_turn_tool_performance_policy.mediaToolNamesForTurnText)(blunExtractText(toolInput));
269282
269726
  if (taskToolsNeeded) {
269283
- blunSelectTurnTools(eligibleTools, this.agent.config.modelCapabilities?.max_context_tokens, this.loadedToolNames, required, selectedTools);
269284
- for (const name of (0, import_turn_tool_performance_policy.rankedToolNamesForTurnText)(eligibleTools, blunExtractText(intent))) {
269727
+ const maxContextTokens = this.agent.fullCompaction.getEffectiveMaxContextTokens();
269728
+ blunSelectTurnTools(eligibleTools, maxContextTokens, this.loadedToolNames, required, selectedTools);
269729
+ const trustedToolNames = new Set(eligibleTools.filter((tool) => this.agent.tools.isUserTool(tool)).map((tool) => tool.name));
269730
+ for (const name of (0, import_turn_tool_performance_policy.rankedToolNamesForTurnText)(eligibleTools, blunExtractText(intent), { trustedToolNames })) {
269285
269731
  const tool = eligibleTools.find((candidate) => candidate.name === name);
269286
- if (tool !== void 0 && !selectedTools.some((candidate) => candidate.name === name) && estimateTokensForTools([...selectedTools, tool]) <= (0, import_turn_tool_performance_policy.toolSchemaBudgetTokens)(this.agent.config.modelCapabilities?.max_context_tokens)) selectedTools.push(tool);
269732
+ if (tool !== void 0 && !selectedTools.some((candidate) => candidate.name === name) && estimateTokensForTools([...selectedTools, tool]) <= (0, import_turn_tool_performance_policy.toolSchemaBudgetTokens)(maxContextTokens)) selectedTools.push(tool);
269287
269733
  }
269288
269734
  } else selectedTools.splice(0, selectedTools.length, ...eligibleTools.filter((tool) => BLUN_LANGUAGE_REVIEW_TOOL_NAMES.has(tool.name) || BLUN_TELEGRAM_OUTBOUND_TOOL_RE.test(tool.name)));
269289
269735
  recordPreRequestPhase("tool-selection", selectionStartedAt);
@@ -269424,6 +269870,7 @@ var init_turn = __esmMin((() => {
269424
269870
  });
269425
269871
  return budgetToolResultForModel({
269426
269872
  homedir: this.agent.homedir,
269873
+ maxContextTokens: this.agent.fullCompaction.getEffectiveMaxContextTokens(),
269427
269874
  toolName: ctx.toolCall.name,
269428
269875
  toolCallId: ctx.toolCall.id,
269429
269876
  result: finalResult
@@ -270134,10 +270581,10 @@ var init_bash = __esmMin((() => {
270134
270581
  },
270135
270582
  approvalRule: literalRulePattern(this.name, args.command),
270136
270583
  matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.command),
270137
- execute: ({ signal, onUpdate, onForegroundTaskStart }) => this.execution(args, signal, onUpdate, onForegroundTaskStart)
270584
+ execute: ({ signal, onUpdate, onForegroundTaskStart, executionOrigin }) => this.execution(args, signal, onUpdate, onForegroundTaskStart, executionOrigin)
270138
270585
  };
270139
270586
  }
270140
- spawn(effectiveCwd, command) {
270587
+ spawn(effectiveCwd, command, executionOrigin) {
270141
270588
  const shellCwd = this.isWindowsBash ? windowsPathToPosixPath(effectiveCwd) : effectiveCwd;
270142
270589
  const shellArgs = [
270143
270590
  this.kaos.osEnv.shellPath,
@@ -270154,9 +270601,11 @@ var init_bash = __esmMin((() => {
270154
270601
  ...process.env,
270155
270602
  ...noninteractiveEnv
270156
270603
  };
270604
+ delete mergedEnv["BLUN_SHELL"];
270605
+ if (executionOrigin === "operator_shell") mergedEnv["BLUN_SHELL"] = "operator-local";
270157
270606
  return this.kaos.execWithEnv(shellArgs, mergedEnv);
270158
270607
  }
270159
- async execution(args, signal, onUpdate, onForegroundTaskStart) {
270608
+ async execution(args, signal, onUpdate, onForegroundTaskStart, executionOrigin) {
270160
270609
  const validationError = this.validateRunRequest(args, signal);
270161
270610
  if (validationError !== void 0) return validationError;
270162
270611
  const startsInBackground = args.run_in_background === true;
@@ -270168,7 +270617,7 @@ var init_bash = __esmMin((() => {
270168
270617
  const builder = new ToolResultBuilder();
270169
270618
  let proc;
270170
270619
  try {
270171
- proc = await this.spawn(effectiveCwd, command);
270620
+ proc = await this.spawn(effectiveCwd, command, executionOrigin);
270172
270621
  } catch (error) {
270173
270622
  return {
270174
270623
  isError: true,
@@ -270503,7 +270952,7 @@ var init_web_search = __esmMin((() => {
270503
270952
  //#region ../../packages/agent-core/src/tools/builtin/search/codebase-search.md?raw
270504
270953
  var codebase_search_default;
270505
270954
  var init_codebase_search$1 = __esmMin((() => {
270506
- codebase_search_default = "Find code by **meaning**, not by keywords.\n\nThis tool runs a semantic search over the codebase index. It understands what a file or function *does*, not just what words appear in it. Use it when you are looking for *where* something is handled, *which file* implements a concept, or *how* a particular concern is addressed — even when the exact term never appears in the source.\n\n**When to use this tool:**\n- \"Where is keyboard input handled?\" — finds the handler even if the word \"keyboard\" never appears.\n- \"Which file manages the retry logic for API calls?\"\n- \"How does the app decide which model to route a message to?\"\n- \"Find the code that handles user authentication flow.\"\n- Any question where you want to locate code by its *purpose* or *behavior*.\n\n**When NOT to use this tool — use a different one instead:**\n- Exact string matches, regex patterns, or specific identifiers → `Grep`\n- Finding files by name, extension, or path glob → `Glob`\n- Reading a known file path → `Read`\n\n**Parameters:**\n- `query` (required): A natural-language question, concept, or phrase describing what the code does. Examples: `\"keyboard event handling\"`, `\"retry with exponential backoff\"`, `\"where chat messages are routed to the model\"`.\n- `top` (optional, default 5): Maximum number of results to return.\n\n**Output:**\nEach result includes a file path and a relevance snippet. The index is rebuilt incrementally; if a file was recently added it may not appear until the next index update. Always verify the finding by reading the file before relying on it.\n";
270955
+ codebase_search_default = "Find code by **meaning**, not by keywords.\n\nThis tool runs a semantic search over the codebase index. It understands what a file or function *does*, not just what words appear in it. Use it when you are looking for *where* something is handled, *which file* implements a concept, or *how* a particular concern is addressed — even when the exact term never appears in the source.\n\n**When to use this tool:**\n- \"Where is keyboard input handled?\" — finds the handler even if the word \"keyboard\" never appears.\n- \"Which file manages the retry logic for API calls?\"\n- \"How does the app decide which model to route a message to?\"\n- \"Find the code that handles user authentication flow.\"\n- Any question where you want to locate code by its *purpose* or *behavior*.\n\n**When NOT to use this tool — use a different one instead:**\n- Exact string matches, regex patterns, or specific identifiers → `Grep`\n- Finding files by name, extension, or path glob → `Glob`\n- Reading a known file path → `Read`\n\n**Parameters:**\n- `query` (required): A natural-language question, concept, or phrase describing what the code does. Examples: `\"keyboard event handling\"`, `\"retry with exponential backoff\"`, `\"where chat messages are routed to the model\"`.\n- `top` (optional, default 5, maximum 100): Maximum number of results to return.\n\n**Output:**\nEach result includes a file path and a relevance score, plus the index model and revision. The index is rebuilt incrementally; if a file was recently added it may not appear until the next index update. Always verify the finding by reading the file before relying on it.\n";
270507
270956
  }));
270508
270957
  //#endregion
270509
270958
  //#region ../../packages/agent-core/src/tools/builtin/search/codebase-search.ts
@@ -270511,7 +270960,7 @@ var init_codebase_search$1 = __esmMin((() => {
270511
270960
  * CodebaseSearchTool — semantic code search via the codebase-index.
270512
270961
  *
270513
270962
  * Shells out to `python codebase_index.py query <repo> "<frage>" --top N`
270514
- * through spawnSync. The script lives at
270963
+ * through asynchronous execFile. The script lives at
270515
270964
  * `packages/codebase-index/codebase_index.py` relative to the workspace root.
270516
270965
  *
270517
270966
  * Unlike Grep (keyword/regex) or Glob (file-name patterns), this tool finds
@@ -270535,18 +270984,20 @@ function resolveScriptPath() {
270535
270984
  }
270536
270985
  return "";
270537
270986
  }
270538
- var CodebaseSearchInputSchema, SCRIPT_TIMEOUT_MS, CodebaseSearchTool;
270987
+ var MAX_SEARCH_RESULTS, CodebaseSearchInputSchema, SCRIPT_TIMEOUT_MS, SCRIPT_MAX_BUFFER, CodebaseSearchTool;
270539
270988
  var init_codebase_search = __esmMin((() => {
270540
270989
  init_zod$1();
270541
270990
  init_rule_match();
270542
270991
  init_input_schema();
270543
270992
  init_result_builder();
270544
270993
  init_codebase_search$1();
270994
+ MAX_SEARCH_RESULTS = 100;
270545
270995
  CodebaseSearchInputSchema = object$1({
270546
270996
  query: string().min(1, "Query cannot be empty.").describe("A natural-language question or concept describing what the code does. Examples: \"keyboard event handling\", \"retry with exponential backoff\", \"where chat messages are routed to the model\"."),
270547
- top: number$1().int().positive().default(5).describe("Maximum number of results to return. Defaults to 5.")
270997
+ top: number$1().int().positive().max(MAX_SEARCH_RESULTS).default(5).describe(`Maximum number of results to return (1-${String(MAX_SEARCH_RESULTS)}). Defaults to 5.`)
270548
270998
  });
270549
270999
  SCRIPT_TIMEOUT_MS = 6e4;
271000
+ SCRIPT_MAX_BUFFER = 1024 * 1024;
270550
271001
  CodebaseSearchTool = class {
270551
271002
  cwd;
270552
271003
  name = "CodebaseSearch";
@@ -270569,45 +271020,72 @@ var init_codebase_search = __esmMin((() => {
270569
271020
  },
270570
271021
  approvalRule: literalRulePattern(this.name, args.query),
270571
271022
  matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.query),
270572
- execute: () => this.execution(args)
271023
+ execute: async (context) => {
271024
+ context.signal.throwIfAborted();
271025
+ return this.execution(args, context.signal);
271026
+ }
270573
271027
  };
270574
271028
  }
270575
- execution(args) {
271029
+ async execution(args, signal) {
270576
271030
  const builder = new ToolResultBuilder();
270577
- if (this.scriptPath.length === 0) return Promise.resolve(builder.error("Could not locate codebase_index.py. Set CODEBASE_INDEX_SCRIPT to its absolute path."));
271031
+ if (!Number.isSafeInteger(args.top) || args.top < 1 || args.top > MAX_SEARCH_RESULTS) return builder.error(`Codebase search top must be between 1 and ${String(MAX_SEARCH_RESULTS)}.`);
271032
+ if (this.scriptPath.length === 0) return builder.error("Could not locate codebase_index.py. Set CODEBASE_INDEX_SCRIPT to its absolute path.");
270578
271033
  try {
270579
- const result = spawnSync("python", [
270580
- this.scriptPath,
270581
- "query",
270582
- this.cwd,
270583
- args.query,
270584
- "--top",
270585
- String(args.top),
270586
- "--model",
270587
- "auto"
270588
- ], {
270589
- cwd: this.cwd,
270590
- timeout: SCRIPT_TIMEOUT_MS,
270591
- encoding: "utf-8",
270592
- windowsHide: true
271034
+ const result = await new Promise((resolve) => {
271035
+ let closed = false;
271036
+ let output;
271037
+ const finish = () => {
271038
+ if (closed && output !== void 0) resolve(output);
271039
+ };
271040
+ execFile("python", [
271041
+ this.scriptPath,
271042
+ "query",
271043
+ this.cwd,
271044
+ args.query,
271045
+ "--top",
271046
+ String(args.top),
271047
+ "--model",
271048
+ "auto"
271049
+ ], {
271050
+ cwd: this.cwd,
271051
+ timeout: SCRIPT_TIMEOUT_MS,
271052
+ encoding: "utf-8",
271053
+ windowsHide: true,
271054
+ shell: false,
271055
+ maxBuffer: SCRIPT_MAX_BUFFER,
271056
+ signal
271057
+ }, (error, stdout, stderr) => {
271058
+ output = {
271059
+ error,
271060
+ stdout,
271061
+ stderr
271062
+ };
271063
+ finish();
271064
+ }).once("close", () => {
271065
+ closed = true;
271066
+ finish();
271067
+ });
270593
271068
  });
270594
- if (result.error !== void 0) {
271069
+ signal.throwIfAborted();
271070
+ if (result.error !== null && typeof result.error.code !== "number") {
270595
271071
  const msg = result.error instanceof Error ? result.error.message : String(result.error);
270596
- return Promise.resolve(builder.error(`Failed to run codebase_index.py: ${msg}`));
271072
+ builder.write(result.stdout + result.stderr);
271073
+ return builder.error(`Failed to run codebase_index.py: ${msg}`);
270597
271074
  }
270598
271075
  const stdout = result.stdout ?? "";
270599
271076
  const stderr = result.stderr ?? "";
270600
- const exitCode = result.status ?? -1;
271077
+ const exitCode = result.error?.code ?? 0;
270601
271078
  if (exitCode !== 0) {
270602
271079
  const combined = stderr.trim().length > 0 ? `${stdout}${stdout.length > 0 ? "\n" : ""}Error: ${stderr.trim()}` : stdout;
270603
271080
  builder.write(combined.length > 0 ? combined : `codebase_index.py exited with code ${String(exitCode)}`);
270604
- return Promise.resolve(builder.error(`Codebase search failed with exit code ${String(exitCode)}.`));
271081
+ return builder.error(`Codebase search failed with exit code ${String(exitCode)}.`);
270605
271082
  }
270606
271083
  builder.write(stdout.length > 0 ? stdout : "No results found.");
270607
- return Promise.resolve(builder.ok());
271084
+ return builder.ok();
270608
271085
  } catch (error) {
271086
+ signal.throwIfAborted();
270609
271087
  const msg = error instanceof Error ? error.message : String(error);
270610
- return Promise.resolve(builder.error(`Codebase search error: ${msg}`));
271088
+ return builder.error(`Codebase search error: ${msg}`);
270611
271089
  }
270612
271090
  }
270613
271091
  };
@@ -271941,6 +272419,7 @@ var init_tool$1 = __esmMin((() => {
271941
272419
  const result = await execution.execute({
271942
272420
  turnId: "",
271943
272421
  toolCallId: "shell-command",
272422
+ executionOrigin: "operator_shell",
271944
272423
  signal: controller.signal,
271945
272424
  onUpdate: (update) => {
271946
272425
  if (update.kind === "stdout") stdout += update.text ?? "";
@@ -272029,6 +272508,9 @@ var init_tool$1 = __esmMin((() => {
272029
272508
  hasUserTool(name) {
272030
272509
  return this.userTools.has(name);
272031
272510
  }
272511
+ isUserTool(tool) {
272512
+ return this.userTools.get(tool.name) === tool;
272513
+ }
272032
272514
  inheritUserTools(parent) {
272033
272515
  for (const tool of parent.userTools.values()) {
272034
272516
  if (!parent.enabledTools.has(tool.name)) continue;
@@ -273256,6 +273738,7 @@ var init_agent = __esmMin((() => {
273256
273738
  init_errors$8();
273257
273739
  init_logger$1();
273258
273740
  init_src$4();
273741
+ init_blun();
273259
273742
  init_commands();
273260
273743
  init_flags();
273261
273744
  init_profile();
@@ -273342,6 +273825,9 @@ var init_agent = __esmMin((() => {
273342
273825
  additionalDirs;
273343
273826
  systemPromptStartedAt = /* @__PURE__ */ new Date();
273344
273827
  activeProfile;
273828
+ rawSystemPromptContext;
273829
+ profileSystemPromptText;
273830
+ agentsMdRequestWarningShown = false;
273345
273831
  brandHome;
273346
273832
  _activeResponderModel;
273347
273833
  allowModelFallback = true;
@@ -273496,6 +273982,7 @@ var init_agent = __esmMin((() => {
273496
273982
  tools: requestTools,
273497
273983
  messages: await rebuildMessages()
273498
273984
  };
273985
+ if (this.activeProfile !== void 0 && this.rawSystemPromptContext !== void 0 && this.config.systemPrompt === this.profileSystemPromptText) this.updateSystemPromptFromProfile(this.activeProfile, this.fitProfileInstructions(this.activeProfile, this.rawSystemPromptContext, requestTools, true));
273499
273986
  let systemPrompt = this.effectiveSystemPrompt;
273500
273987
  const preflightStartedAt = performance.now();
273501
273988
  const compacted = await this.fullCompaction.beforeStep(params.signal, {
@@ -273524,6 +274011,13 @@ var init_agent = __esmMin((() => {
273524
274011
  ...params,
273525
274012
  messages: await rebuildMessages()
273526
274013
  };
274014
+ if (this.config.runtimeModel(_candidate.alias).provider.name === "blun") {
274015
+ const requestBytes = estimateBlunSerializedBodyBytes(systemPrompt, tools, params.messages) + 4096;
274016
+ if (requestBytes >= 5e5) throw new BlunError(ErrorCodes.CONTEXT_OVERFLOW, "The BLUN request is too large after compaction. Shorten fixed instructions or tools.", { details: {
274017
+ estimatedRequestBytes: requestBytes,
274018
+ requestBudgetBytes: 5e5
274019
+ } });
274020
+ }
273527
274021
  return {
273528
274022
  params: {
273529
274023
  ...params,
@@ -273602,8 +274096,14 @@ var init_agent = __esmMin((() => {
273602
274096
  }
273603
274097
  useProfile(profile, context, brandHome) {
273604
274098
  this.setActiveProfile(profile, brandHome);
273605
- this.updateSystemPromptFromProfile(profile, context);
274099
+ this.rawSystemPromptContext = context;
274100
+ if (context?.agentsMdText === void 0) {
274101
+ this.updateSystemPromptFromProfile(profile, context);
274102
+ this.tools.setActiveTools(profile.tools);
274103
+ return;
274104
+ }
273606
274105
  this.tools.setActiveTools(profile.tools);
274106
+ this.updateSystemPromptFromProfile(profile, this.fitProfileInstructions(profile, context));
273607
274107
  }
273608
274108
  setActiveProfile(profile, brandHome) {
273609
274109
  this.activeProfile = profile;
@@ -273618,7 +274118,68 @@ var init_agent = __esmMin((() => {
273618
274118
  async refreshSystemPrompt() {
273619
274119
  if (this.activeProfile === void 0) return;
273620
274120
  const context = this.systemPromptContextProvider === void 0 ? await prepareSystemPromptContext(this.kaos, this.brandHome, { additionalDirs: this.additionalDirs }) : await this.systemPromptContextProvider();
273621
- this.updateSystemPromptFromProfile(this.activeProfile, context);
274121
+ this.rawSystemPromptContext = context;
274122
+ this.updateSystemPromptFromProfile(this.activeProfile, this.fitProfileInstructions(this.activeProfile, context));
274123
+ }
274124
+ fitProfileInstructions(profile, context, tools = this.tools.loopTools, notify = false) {
274125
+ if (context?.agentsMdText === void 0 || this.config.modelAlias === void 0) return context;
274126
+ if (this.config.runtimeModel(this.config.modelAlias).provider.name !== "blun") return context;
274127
+ const renderFixedPrompt = (candidate) => {
274128
+ const rendered = profile.systemPrompt({
274129
+ osEnv: this.kaos.osEnv,
274130
+ now: this.systemPromptStartedAt,
274131
+ cwd: this.config.cwd,
274132
+ skills: this.skills?.registry,
274133
+ cwdListing: candidate.cwdListing,
274134
+ agentsMd: candidate.agentsMd,
274135
+ additionalDirsInfo: candidate.additionalDirsInfo
274136
+ });
274137
+ const compact = this.skills?.registry === void 0 ? rendered : compactLegacyModelSkillListing(rendered, this.skills.registry);
274138
+ return this.runtimeSystemPromptAppend.length === 0 ? compact : compact.length === 0 ? this.runtimeSystemPromptAppend : `${compact}\n\n${this.runtimeSystemPromptAppend}`;
274139
+ };
274140
+ const fitted = fitAgentsMdContext(context, 4e5, (candidate) => {
274141
+ return estimateBlunSerializedBodyBytes(renderFixedPrompt(candidate), tools, []) + 4096;
274142
+ });
274143
+ const describeFixedEstimate = () => {
274144
+ const systemPrompt = renderFixedPrompt(fitted.context);
274145
+ const envelopeBytes = estimateBlunSerializedBodyBytes("", [], []);
274146
+ const withoutToolsBytes = estimateBlunSerializedBodyBytes(systemPrompt, [], []);
274147
+ return {
274148
+ estimationStage: notify ? "request" : "profile",
274149
+ toolCount: tools.length,
274150
+ serializedPromptBytes: withoutToolsBytes - envelopeBytes,
274151
+ serializedToolsBytes: fitted.fixedRequestBytes - 4096 - withoutToolsBytes,
274152
+ envelopeBytes,
274153
+ reserveBytes: 4096,
274154
+ instructionBytes: fitted.context.agentsMdSources?.totalBytes ?? 0,
274155
+ runtimeAppendBytes: Buffer.byteLength(this.runtimeSystemPromptAppend, "utf8")
274156
+ };
274157
+ };
274158
+ if (!fitted.fits) this.log.warn("fixed BLUN request exceeds 400000 bytes without AGENTS.md", {
274159
+ fixedRequestBytes: fitted.fixedRequestBytes,
274160
+ ...describeFixedEstimate()
274161
+ });
274162
+ else if (fitted.omittedBytes > 0) {
274163
+ this.log.warn("AGENTS.md content shortened for BLUN request budget", {
274164
+ omittedBytes: fitted.omittedBytes,
274165
+ fixedRequestBytes: fitted.fixedRequestBytes,
274166
+ ...describeFixedEstimate()
274167
+ });
274168
+ if (notify && !this.agentsMdRequestWarningShown) {
274169
+ this.agentsMdRequestWarningShown = true;
274170
+ const retained = new Map(fitted.context.agentsMdSources?.files.map((file) => [file.path, file.bytes]));
274171
+ const files = context.agentsMdSources?.files.flatMap((file) => {
274172
+ const read = retained.get(file.path) ?? 0;
274173
+ return read < file.bytes ? [`${file.path}: ${file.bytes} bytes, ${read} read, ${file.bytes - read} omitted`] : [];
274174
+ }) ?? [];
274175
+ this.emitEvent({
274176
+ type: "warning",
274177
+ code: "agents-md-request-truncated",
274178
+ message: `Instructions shortened for the request size limit: ${files.join("; ")}.`
274179
+ });
274180
+ }
274181
+ }
274182
+ return fitted.context;
273622
274183
  }
273623
274184
  updateSystemPromptFromProfile(profile, context) {
273624
274185
  let contributions;
@@ -273639,6 +274200,7 @@ var init_agent = __esmMin((() => {
273639
274200
  profileName: profile.name,
273640
274201
  systemPrompt
273641
274202
  });
274203
+ this.profileSystemPromptText = systemPrompt;
273642
274204
  this.renderedPromptContributions = contributions === void 0 ? void 0 : {
273643
274205
  text: systemPrompt,
273644
274206
  value: structuredClone(contributions)
@@ -273815,6 +274377,9 @@ var init_agent = __esmMin((() => {
273815
274377
  },
273816
274378
  startBtw: () => this.subagentHost.startBtw(),
273817
274379
  createGoal: (payload) => this.goal.createGoal(payload),
274380
+ editGoal: (payload) => this.goal.editGoal(payload),
274381
+ blockGoal: (payload) => this.goal.blockGoal(payload),
274382
+ completeGoal: () => this.goal.completeGoal(),
273818
274383
  getGoal: () => this.goal.getGoal(),
273819
274384
  pauseGoal: () => this.goal.pauseGoal(),
273820
274385
  resumeGoal: () => this.goal.resumeGoal(),
@@ -303542,7 +304107,7 @@ var init_proxy = __esmMin((() => {
303542
304107
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303543
304108
  module.exports = isexe;
303544
304109
  isexe.sync = sync;
303545
- var fs$9 = __require("fs");
304110
+ var fs$8 = __require("fs");
303546
304111
  function checkPathExt(path, options) {
303547
304112
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
303548
304113
  if (!pathext) return true;
@@ -303559,12 +304124,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303559
304124
  return checkPathExt(path, options);
303560
304125
  }
303561
304126
  function isexe(path, options, cb) {
303562
- fs$9.stat(path, function(er, stat) {
304127
+ fs$8.stat(path, function(er, stat) {
303563
304128
  cb(er, er ? false : checkStat(stat, path, options));
303564
304129
  });
303565
304130
  }
303566
304131
  function sync(path, options) {
303567
- return checkStat(fs$9.statSync(path), path, options);
304132
+ return checkStat(fs$8.statSync(path), path, options);
303568
304133
  }
303569
304134
  }));
303570
304135
  //#endregion
@@ -303572,14 +304137,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303572
304137
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303573
304138
  module.exports = isexe;
303574
304139
  isexe.sync = sync;
303575
- var fs$8 = __require("fs");
304140
+ var fs$7 = __require("fs");
303576
304141
  function isexe(path, options, cb) {
303577
- fs$8.stat(path, function(er, stat) {
304142
+ fs$7.stat(path, function(er, stat) {
303578
304143
  cb(er, er ? false : checkStat(stat, options));
303579
304144
  });
303580
304145
  }
303581
304146
  function sync(path, options) {
303582
- return checkStat(fs$8.statSync(path), options);
304147
+ return checkStat(fs$7.statSync(path), options);
303583
304148
  }
303584
304149
  function checkStat(stat, options) {
303585
304150
  return stat.isFile() && checkMode(stat, options);
@@ -303643,7 +304208,7 @@ var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303643
304208
  //#region ../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
303644
304209
  var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303645
304210
  const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
303646
- const path$10 = __require("path");
304211
+ const path$9 = __require("path");
303647
304212
  const COLON = isWindows ? ";" : ":";
303648
304213
  const isexe = require_isexe();
303649
304214
  const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -303673,7 +304238,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303673
304238
  if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
303674
304239
  const ppRaw = pathEnv[i];
303675
304240
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
303676
- const pCmd = path$10.join(pathPart, cmd);
304241
+ const pCmd = path$9.join(pathPart, cmd);
303677
304242
  resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
303678
304243
  });
303679
304244
  const subStep = (p, i, ii) => new Promise((resolve, reject) => {
@@ -303694,7 +304259,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303694
304259
  for (let i = 0; i < pathEnv.length; i++) {
303695
304260
  const ppRaw = pathEnv[i];
303696
304261
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
303697
- const pCmd = path$10.join(pathPart, cmd);
304262
+ const pCmd = path$9.join(pathPart, cmd);
303698
304263
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
303699
304264
  for (let j = 0; j < pathExt.length; j++) {
303700
304265
  const cur = p + pathExt[j];
@@ -303725,7 +304290,7 @@ var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303725
304290
  //#endregion
303726
304291
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
303727
304292
  var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303728
- const path$9 = __require("path");
304293
+ const path$8 = __require("path");
303729
304294
  const which = require_which();
303730
304295
  const getPathKey = require_path_key();
303731
304296
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -303740,12 +304305,12 @@ var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) =>
303740
304305
  try {
303741
304306
  resolved = which.sync(parsed.command, {
303742
304307
  path: env[getPathKey({ env })],
303743
- pathExt: withoutPathExt ? path$9.delimiter : void 0
304308
+ pathExt: withoutPathExt ? path$8.delimiter : void 0
303744
304309
  });
303745
304310
  } catch (e) {} finally {
303746
304311
  if (shouldSwitchCwd) process.chdir(cwd);
303747
304312
  }
303748
- if (resolved) resolved = path$9.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
304313
+ if (resolved) resolved = path$8.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
303749
304314
  return resolved;
303750
304315
  }
303751
304316
  function resolveCommand(parsed) {
@@ -303794,16 +304359,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
303794
304359
  //#endregion
303795
304360
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
303796
304361
  var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303797
- const fs$7 = __require("fs");
304362
+ const fs$6 = __require("fs");
303798
304363
  const shebangCommand = require_shebang_command();
303799
304364
  function readShebang(command) {
303800
304365
  const size = 150;
303801
304366
  const buffer = Buffer.alloc(size);
303802
304367
  let fd;
303803
304368
  try {
303804
- fd = fs$7.openSync(command, "r");
303805
- fs$7.readSync(fd, buffer, 0, size, 0);
303806
- fs$7.closeSync(fd);
304369
+ fd = fs$6.openSync(command, "r");
304370
+ fs$6.readSync(fd, buffer, 0, size, 0);
304371
+ fs$6.closeSync(fd);
303807
304372
  } catch (e) {}
303808
304373
  return shebangCommand(buffer.toString());
303809
304374
  }
@@ -303812,7 +304377,7 @@ var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303812
304377
  //#endregion
303813
304378
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
303814
304379
  var require_parse$5 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303815
- const path$8 = __require("path");
304380
+ const path$7 = __require("path");
303816
304381
  const resolveCommand = require_resolveCommand();
303817
304382
  const escape = require_escape();
303818
304383
  const readShebang = require_readShebang();
@@ -303835,7 +304400,7 @@ var require_parse$5 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303835
304400
  const needsShell = !isExecutableRegExp.test(commandFile);
303836
304401
  if (parsed.options.forceShell || needsShell) {
303837
304402
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
303838
- parsed.command = path$8.normalize(parsed.command);
304403
+ parsed.command = path$7.normalize(parsed.command);
303839
304404
  parsed.command = escape.command(parsed.command);
303840
304405
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
303841
304406
  parsed.args = [
@@ -337965,7 +338530,7 @@ var require_dist$5 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
337965
338530
  //#endregion
337966
338531
  //#region ../../node_modules/.pnpm/yazl@3.3.1/node_modules/yazl/index.js
337967
338532
  var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
337968
- var fs$6 = __require("fs");
338533
+ var fs$5 = __require("fs");
337969
338534
  var Transform$2 = __require("stream").Transform;
337970
338535
  var PassThrough$2 = __require("stream").PassThrough;
337971
338536
  var zlib$1 = __require("zlib");
@@ -337994,14 +338559,14 @@ var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
337994
338559
  if (shouldIgnoreAdding(self)) return;
337995
338560
  var entry = new Entry(metadataPath, false, options);
337996
338561
  self.entries.push(entry);
337997
- fs$6.stat(realPath, function(err, stats) {
338562
+ fs$5.stat(realPath, function(err, stats) {
337998
338563
  if (err) return self.emit("error", err);
337999
338564
  if (!stats.isFile()) return self.emit("error", /* @__PURE__ */ new Error("not a file: " + realPath));
338000
338565
  entry.uncompressedSize = stats.size;
338001
338566
  if (options.mtime == null) entry.setLastModDate(stats.mtime);
338002
338567
  if (options.mode == null) entry.setFileAttributesMode(stats.mode);
338003
338568
  entry.setFileDataPumpFunction(function() {
338004
- var readStream = fs$6.createReadStream(realPath);
338569
+ var readStream = fs$5.createReadStream(realPath);
338005
338570
  entry.state = Entry.FILE_DATA_IN_PROGRESS;
338006
338571
  readStream.on("error", function(err) {
338007
338572
  self.emit("error", err);
@@ -339138,6 +339703,15 @@ var init_rpc$1 = __esmMin((() => {
339138
339703
  async createGoal({ agentId, ...payload }) {
339139
339704
  return (await this.getAgent(agentId)).createGoal(payload);
339140
339705
  }
339706
+ async editGoal({ agentId, ...payload }) {
339707
+ return (await this.getAgent(agentId)).editGoal(payload);
339708
+ }
339709
+ async blockGoal({ agentId, ...payload }) {
339710
+ return (await this.getAgent(agentId)).blockGoal(payload);
339711
+ }
339712
+ async completeGoal({ agentId }) {
339713
+ return (await this.getAgent(agentId)).completeGoal({});
339714
+ }
339141
339715
  async getGoal({ agentId, ...payload }) {
339142
339716
  return (await this.getAgent(agentId, true)).getGoal(payload);
339143
339717
  }
@@ -340572,6 +341146,15 @@ var init_core_impl = __esmMin((() => {
340572
341146
  getGoal({ sessionId, ...payload }) {
340573
341147
  return Promise.resolve(this.sessionApi(sessionId).getGoal(payload));
340574
341148
  }
341149
+ editGoal({ sessionId, ...payload }) {
341150
+ return Promise.resolve(this.sessionApi(sessionId).editGoal(payload));
341151
+ }
341152
+ blockGoal({ sessionId, ...payload }) {
341153
+ return Promise.resolve(this.sessionApi(sessionId).blockGoal(payload));
341154
+ }
341155
+ completeGoal({ sessionId, ...payload }) {
341156
+ return Promise.resolve(this.sessionApi(sessionId).completeGoal(payload));
341157
+ }
340575
341158
  pauseGoal({ sessionId, ...payload }) {
340576
341159
  return Promise.resolve(this.sessionApi(sessionId).pauseGoal(payload));
340577
341160
  }
@@ -348185,7 +348768,10 @@ function reduceWireRecords(records) {
348185
348768
  text: record.summary
348186
348769
  }],
348187
348770
  toolCalls: [],
348188
- origin: { kind: "compaction_summary" }
348771
+ origin: {
348772
+ kind: "compaction_summary",
348773
+ ...record.toolContinuity === void 0 ? {} : { toolContinuity: record.toolContinuity }
348774
+ }
348189
348775
  },
348190
348776
  time: record.time
348191
348777
  };
@@ -350459,6 +351045,24 @@ var Session = class {
350459
351045
  this.ensureOpen();
350460
351046
  return this.rpc.getGoal({ sessionId: this.id });
350461
351047
  }
351048
+ async editGoal(input) {
351049
+ this.ensureOpen();
351050
+ return this.rpc.editGoal({
351051
+ sessionId: this.id,
351052
+ objective: input.objective
351053
+ });
351054
+ }
351055
+ async blockGoal(input = {}) {
351056
+ this.ensureOpen();
351057
+ return this.rpc.blockGoal({
351058
+ sessionId: this.id,
351059
+ reason: input.reason
351060
+ });
351061
+ }
351062
+ async completeGoal() {
351063
+ this.ensureOpen();
351064
+ return this.rpc.completeGoal({ sessionId: this.id });
351065
+ }
350462
351066
  async pauseGoal() {
350463
351067
  this.ensureOpen();
350464
351068
  return this.rpc.pauseGoal({ sessionId: this.id });
@@ -351848,6 +352452,26 @@ var SDKRpcClientBase = class {
351848
352452
  replace: input.replace
351849
352453
  });
351850
352454
  }
352455
+ async editGoal(input) {
352456
+ return (await this.getRpc()).editGoal({
352457
+ sessionId: input.sessionId,
352458
+ agentId: this.interactiveAgentId,
352459
+ objective: input.objective
352460
+ });
352461
+ }
352462
+ async blockGoal(input) {
352463
+ return (await this.getRpc()).blockGoal({
352464
+ sessionId: input.sessionId,
352465
+ agentId: this.interactiveAgentId,
352466
+ reason: input.reason
352467
+ });
352468
+ }
352469
+ async completeGoal(input) {
352470
+ return (await this.getRpc()).completeGoal({
352471
+ sessionId: input.sessionId,
352472
+ agentId: this.interactiveAgentId
352473
+ });
352474
+ }
351851
352475
  async getGoal(input) {
351852
352476
  return (await this.getRpc()).getGoal({
351853
352477
  sessionId: input.sessionId,
@@ -353902,8 +354526,8 @@ var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
353902
354526
  var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
353903
354527
  const EventEmitter$12 = __require("node:events").EventEmitter;
353904
354528
  const childProcess = __require("node:child_process");
353905
- const path$7 = __require("node:path");
353906
- const fs$5 = __require("node:fs");
354529
+ const path$6 = __require("node:path");
354530
+ const fs$4 = __require("node:fs");
353907
354531
  const process$2 = __require("node:process");
353908
354532
  const { Argument, humanReadableArgName } = require_argument();
353909
354533
  const { CommanderError } = require_error$2();
@@ -354786,7 +355410,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
354786
355410
  * @param {string} subcommandName
354787
355411
  */
354788
355412
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
354789
- if (fs$5.existsSync(executableFile)) return;
355413
+ if (fs$4.existsSync(executableFile)) return;
354790
355414
  const executableMissing = `'${executableFile}' does not exist
354791
355415
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
354792
355416
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
@@ -354809,10 +355433,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
354809
355433
  ".cjs"
354810
355434
  ];
354811
355435
  function findFile(baseDir, baseName) {
354812
- const localBin = path$7.resolve(baseDir, baseName);
354813
- if (fs$5.existsSync(localBin)) return localBin;
354814
- if (sourceExt.includes(path$7.extname(baseName))) return void 0;
354815
- const foundExt = sourceExt.find((ext) => fs$5.existsSync(`${localBin}${ext}`));
355436
+ const localBin = path$6.resolve(baseDir, baseName);
355437
+ if (fs$4.existsSync(localBin)) return localBin;
355438
+ if (sourceExt.includes(path$6.extname(baseName))) return void 0;
355439
+ const foundExt = sourceExt.find((ext) => fs$4.existsSync(`${localBin}${ext}`));
354816
355440
  if (foundExt) return `${localBin}${foundExt}`;
354817
355441
  }
354818
355442
  this._checkForMissingMandatoryOptions();
@@ -354822,21 +355446,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
354822
355446
  if (this._scriptPath) {
354823
355447
  let resolvedScriptPath;
354824
355448
  try {
354825
- resolvedScriptPath = fs$5.realpathSync(this._scriptPath);
355449
+ resolvedScriptPath = fs$4.realpathSync(this._scriptPath);
354826
355450
  } catch {
354827
355451
  resolvedScriptPath = this._scriptPath;
354828
355452
  }
354829
- executableDir = path$7.resolve(path$7.dirname(resolvedScriptPath), executableDir);
355453
+ executableDir = path$6.resolve(path$6.dirname(resolvedScriptPath), executableDir);
354830
355454
  }
354831
355455
  if (executableDir) {
354832
355456
  let localFile = findFile(executableDir, executableFile);
354833
355457
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
354834
- const legacyName = path$7.basename(this._scriptPath, path$7.extname(this._scriptPath));
355458
+ const legacyName = path$6.basename(this._scriptPath, path$6.extname(this._scriptPath));
354835
355459
  if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
354836
355460
  }
354837
355461
  executableFile = localFile || executableFile;
354838
355462
  }
354839
- launchWithNode = sourceExt.includes(path$7.extname(executableFile));
355463
+ launchWithNode = sourceExt.includes(path$6.extname(executableFile));
354840
355464
  let proc;
354841
355465
  if (process$2.platform !== "win32") if (launchWithNode) {
354842
355466
  args.unshift(executableFile);
@@ -355540,7 +356164,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
355540
356164
  * @return {Command}
355541
356165
  */
355542
356166
  nameFromFilename(filename) {
355543
- this._name = path$7.basename(filename, path$7.extname(filename));
356167
+ this._name = path$6.basename(filename, path$6.extname(filename));
355544
356168
  return this;
355545
356169
  }
355546
356170
  /**
@@ -361756,6 +362380,25 @@ var AcpSession = class {
361756
362380
  });
361757
362381
  return;
361758
362382
  }
362383
+ if (event.type === "warning" && event.code === "agents-md-request-truncated") {
362384
+ if (!isFromMainAgent(event)) return;
362385
+ conn.sessionUpdate({
362386
+ sessionId,
362387
+ update: {
362388
+ sessionUpdate: "agent_message_chunk",
362389
+ content: {
362390
+ type: "text",
362391
+ text: `${event.message}\n`
362392
+ }
362393
+ }
362394
+ }).catch((err) => {
362395
+ log.warn("acp: failed to push instruction warning", {
362396
+ sessionId,
362397
+ error: err instanceof Error ? err.message : String(err)
362398
+ });
362399
+ });
362400
+ return;
362401
+ }
361759
362402
  if (event.type === "assistant.delta") {
361760
362403
  if (!isFromMainAgent(event)) return;
361761
362404
  conn.sessionUpdate(assistantDeltaToSessionUpdate(sessionId, event)).catch((err) => {
@@ -373383,10 +374026,10 @@ var require_atomic_sleep = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373383
374026
  //#endregion
373384
374027
  //#region ../../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js
373385
374028
  var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373386
- const fs$4 = __require("fs");
374029
+ const fs$3 = __require("fs");
373387
374030
  const EventEmitter$10 = __require("events");
373388
374031
  const inherits$6 = __require("util").inherits;
373389
- const path$6 = __require("path");
374032
+ const path$5 = __require("path");
373390
374033
  const sleep = require_atomic_sleep();
373391
374034
  const assert$8 = __require("assert");
373392
374035
  const BUSY_WRITE_TIMEOUT = 100;
@@ -373426,17 +374069,17 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373426
374069
  const flags = sonic.append ? "a" : "w";
373427
374070
  const mode = sonic.mode;
373428
374071
  if (sonic.sync) try {
373429
- if (sonic.mkdir) fs$4.mkdirSync(path$6.dirname(file), { recursive: true });
373430
- fileOpened(null, fs$4.openSync(file, flags, mode));
374072
+ if (sonic.mkdir) fs$3.mkdirSync(path$5.dirname(file), { recursive: true });
374073
+ fileOpened(null, fs$3.openSync(file, flags, mode));
373431
374074
  } catch (err) {
373432
374075
  fileOpened(err);
373433
374076
  throw err;
373434
374077
  }
373435
- else if (sonic.mkdir) fs$4.mkdir(path$6.dirname(file), { recursive: true }, (err) => {
374078
+ else if (sonic.mkdir) fs$3.mkdir(path$5.dirname(file), { recursive: true }, (err) => {
373436
374079
  if (err) return fileOpened(err);
373437
- fs$4.open(file, flags, mode, fileOpened);
374080
+ fs$3.open(file, flags, mode, fileOpened);
373438
374081
  });
373439
- else fs$4.open(file, flags, mode, fileOpened);
374082
+ else fs$3.open(file, flags, mode, fileOpened);
373440
374083
  }
373441
374084
  function SonicBoom(opts) {
373442
374085
  if (!(this instanceof SonicBoom)) return new SonicBoom(opts);
@@ -373474,8 +374117,8 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373474
374117
  this.flush = flushBuffer;
373475
374118
  this.flushSync = flushBufferSync;
373476
374119
  this._actualWrite = actualWriteBuffer;
373477
- fsWriteSync = () => fs$4.writeSync(this.fd, this._writingBuf);
373478
- fsWrite = () => fs$4.write(this.fd, this._writingBuf, this.release);
374120
+ fsWriteSync = () => fs$3.writeSync(this.fd, this._writingBuf);
374121
+ fsWrite = () => fs$3.write(this.fd, this._writingBuf, this.release);
373479
374122
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
373480
374123
  this._writingBuf = "";
373481
374124
  this.write = write;
@@ -373483,12 +374126,12 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373483
374126
  this.flushSync = flushSync;
373484
374127
  this._actualWrite = actualWrite;
373485
374128
  fsWriteSync = () => {
373486
- if (Buffer.isBuffer(this._writingBuf)) return fs$4.writeSync(this.fd, this._writingBuf);
373487
- return fs$4.writeSync(this.fd, this._writingBuf, "utf8");
374129
+ if (Buffer.isBuffer(this._writingBuf)) return fs$3.writeSync(this.fd, this._writingBuf);
374130
+ return fs$3.writeSync(this.fd, this._writingBuf, "utf8");
373488
374131
  };
373489
374132
  fsWrite = () => {
373490
- if (Buffer.isBuffer(this._writingBuf)) return fs$4.write(this.fd, this._writingBuf, this.release);
373491
- return fs$4.write(this.fd, this._writingBuf, "utf8", this.release);
374133
+ if (Buffer.isBuffer(this._writingBuf)) return fs$3.write(this.fd, this._writingBuf, this.release);
374134
+ return fs$3.write(this.fd, this._writingBuf, "utf8", this.release);
373492
374135
  };
373493
374136
  } else throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
373494
374137
  if (typeof fd === "number") {
@@ -373533,7 +374176,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373533
374176
  return;
373534
374177
  }
373535
374178
  }
373536
- if (this._fsync) fs$4.fsyncSync(this.fd);
374179
+ if (this._fsync) fs$3.fsyncSync(this.fd);
373537
374180
  const len = this._len;
373538
374181
  if (this._reopening) {
373539
374182
  this._writing = false;
@@ -373630,7 +374273,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373630
374273
  this._flushPending = true;
373631
374274
  const onDrain = () => {
373632
374275
  if (!this._fsync) try {
373633
- fs$4.fsync(this.fd, (err) => {
374276
+ fs$3.fsync(this.fd, (err) => {
373634
374277
  this._flushPending = false;
373635
374278
  cb(err);
373636
374279
  });
@@ -373707,7 +374350,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373707
374350
  if (this._writing) return;
373708
374351
  const fd = this.fd;
373709
374352
  this.once("ready", () => {
373710
- if (fd !== this.fd) fs$4.close(fd, (err) => {
374353
+ if (fd !== this.fd) fs$3.close(fd, (err) => {
373711
374354
  if (err) return this.emit("error", err);
373712
374355
  });
373713
374356
  });
@@ -373738,7 +374381,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373738
374381
  while (this._bufs.length || buf.length) {
373739
374382
  if (buf.length <= 0) buf = this._bufs[0];
373740
374383
  try {
373741
- const n = Buffer.isBuffer(buf) ? fs$4.writeSync(this.fd, buf) : fs$4.writeSync(this.fd, buf, "utf8");
374384
+ const n = Buffer.isBuffer(buf) ? fs$3.writeSync(this.fd, buf) : fs$3.writeSync(this.fd, buf, "utf8");
373742
374385
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
373743
374386
  buf = releasedBufObj.writingBuf;
373744
374387
  this._len = releasedBufObj.len;
@@ -373749,7 +374392,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373749
374392
  }
373750
374393
  }
373751
374394
  try {
373752
- fs$4.fsyncSync(this.fd);
374395
+ fs$3.fsyncSync(this.fd);
373753
374396
  } catch {}
373754
374397
  }
373755
374398
  function flushBufferSync() {
@@ -373763,7 +374406,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373763
374406
  while (this._bufs.length || buf.length) {
373764
374407
  if (buf.length <= 0) buf = mergeBuf(this._bufs[0], this._lens[0]);
373765
374408
  try {
373766
- const n = fs$4.writeSync(this.fd, buf);
374409
+ const n = fs$3.writeSync(this.fd, buf);
373767
374410
  buf = buf.subarray(n);
373768
374411
  this._len = Math.max(this._len - n, 0);
373769
374412
  if (buf.length <= 0) {
@@ -373785,24 +374428,24 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373785
374428
  this._writing = true;
373786
374429
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
373787
374430
  if (this.sync) try {
373788
- release(null, Buffer.isBuffer(this._writingBuf) ? fs$4.writeSync(this.fd, this._writingBuf) : fs$4.writeSync(this.fd, this._writingBuf, "utf8"));
374431
+ release(null, Buffer.isBuffer(this._writingBuf) ? fs$3.writeSync(this.fd, this._writingBuf) : fs$3.writeSync(this.fd, this._writingBuf, "utf8"));
373789
374432
  } catch (err) {
373790
374433
  release(err);
373791
374434
  }
373792
- else fs$4.write(this.fd, this._writingBuf, release);
374435
+ else fs$3.write(this.fd, this._writingBuf, release);
373793
374436
  }
373794
374437
  function actualWriteBuffer() {
373795
374438
  const release = this.release;
373796
374439
  this._writing = true;
373797
374440
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
373798
374441
  if (this.sync) try {
373799
- release(null, fs$4.writeSync(this.fd, this._writingBuf));
374442
+ release(null, fs$3.writeSync(this.fd, this._writingBuf));
373800
374443
  } catch (err) {
373801
374444
  release(err);
373802
374445
  }
373803
374446
  else {
373804
374447
  if (kCopyBuffer) this._writingBuf = Buffer.from(this._writingBuf);
373805
- fs$4.write(this.fd, this._writingBuf, release);
374448
+ fs$3.write(this.fd, this._writingBuf, release);
373806
374449
  }
373807
374450
  }
373808
374451
  function actualClose(sonic) {
@@ -373816,10 +374459,10 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373816
374459
  sonic._lens = [];
373817
374460
  assert$8(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
373818
374461
  try {
373819
- fs$4.fsync(sonic.fd, closeWrapped);
374462
+ fs$3.fsync(sonic.fd, closeWrapped);
373820
374463
  } catch {}
373821
374464
  function closeWrapped() {
373822
- if (sonic.fd !== 1 && sonic.fd !== 2) fs$4.close(sonic.fd, done);
374465
+ if (sonic.fd !== 1 && sonic.fd !== 2) fs$3.close(sonic.fd, done);
373823
374466
  else done();
373824
374467
  }
373825
374468
  function done(err) {
@@ -403459,7 +404102,7 @@ var import_multipart = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((
403459
404102
  const fp = require_plugin();
403460
404103
  const { createWriteStream: createWriteStream$1 } = __require("node:fs");
403461
404104
  const { unlink: unlink$1 } = __require("node:fs/promises");
403462
- const path$5 = __require("node:path");
404105
+ const path$4 = __require("node:path");
403463
404106
  const { generateId } = require_generateId();
403464
404107
  const createError = require_error$1();
403465
404108
  const streamToNull = require_stream_consumer();
@@ -403754,7 +404397,7 @@ var import_multipart = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((
403754
404397
  for await (const part of parts) {
403755
404398
  values = part.fields;
403756
404399
  if (!part.file) continue;
403757
- const filepath = path$5.join(tmpdir, generateId() + path$5.extname(part.filename || "file" + i++));
404400
+ const filepath = path$4.join(tmpdir, generateId() + path$4.extname(part.filename || "file" + i++));
403758
404401
  const target = createWriteStream$1(filepath);
403759
404402
  try {
403760
404403
  this.tmpUploads.push(filepath);
@@ -416495,8 +417138,8 @@ var require_dist$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
416495
417138
  //#endregion
416496
417139
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/mode/static.js
416497
417140
  var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416498
- const path$4 = __require("node:path");
416499
- const fs$3 = __require("node:fs");
417141
+ const path$3 = __require("node:path");
417142
+ const fs$2 = __require("node:fs");
416500
417143
  const yaml = require_dist$1();
416501
417144
  module.exports = function(fastify, opts, done) {
416502
417145
  if (!opts.specification) return done(/* @__PURE__ */ new Error("specification is missing in the module options"));
@@ -416505,14 +417148,14 @@ var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416505
417148
  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"));
416506
417149
  else if (opts.specification.path) {
416507
417150
  if (typeof opts.specification.path !== "string") return done(/* @__PURE__ */ new Error("specification.path is not a string"));
416508
- if (!fs$3.existsSync(path$4.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
416509
- const extName = path$4.extname(opts.specification.path).toLowerCase();
417151
+ if (!fs$2.existsSync(path$3.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
417152
+ const extName = path$3.extname(opts.specification.path).toLowerCase();
416510
417153
  if ([".yaml", ".json"].indexOf(extName) === -1) return done(/* @__PURE__ */ new Error("specification.path extension name is not supported, should be one from ['.yaml', '.json']"));
416511
417154
  if (opts.specification.postProcessor && typeof opts.specification.postProcessor !== "function") return done(/* @__PURE__ */ new Error("specification.postProcessor should be a function"));
416512
417155
  if (opts.specification.baseDir && typeof opts.specification.baseDir !== "string") return done(/* @__PURE__ */ new Error("specification.baseDir should be string"));
416513
- if (!opts.specification.baseDir) opts.specification.baseDir = path$4.resolve(path$4.dirname(opts.specification.path));
417156
+ if (!opts.specification.baseDir) opts.specification.baseDir = path$3.resolve(path$3.dirname(opts.specification.path));
416514
417157
  else while (opts.specification.baseDir.endsWith("/")) opts.specification.baseDir = opts.specification.baseDir.slice(0, -1);
416515
- const source = fs$3.readFileSync(path$4.resolve(opts.specification.path), "utf8");
417158
+ const source = fs$2.readFileSync(path$3.resolve(opts.specification.path), "utf8");
416516
417159
  switch (extName) {
416517
417160
  case ".yaml":
416518
417161
  swaggerObject = yaml.parse(source);
@@ -416779,11 +417422,11 @@ var require_should_route_hide = /* @__PURE__ */ __commonJSMin(((exports, module)
416779
417422
  //#endregion
416780
417423
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/util/read-package-json.js
416781
417424
  var require_read_package_json = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416782
- const fs$2 = __require("node:fs");
416783
- const path$3 = __require("node:path");
417425
+ const fs$1 = __require("node:fs");
417426
+ const path$2 = __require("node:path");
416784
417427
  function readPackageJson() {
416785
417428
  try {
416786
- return JSON.parse(fs$2.readFileSync(path$3.join(__dirname, "..", "..", "package.json")));
417429
+ return JSON.parse(fs$1.readFileSync(path$2.join(__dirname, "..", "..", "package.json")));
416787
417430
  } catch {
416788
417431
  return {};
416789
417432
  }
@@ -426506,7 +427149,7 @@ async function searchLocalToolEvents(homeDir, sessions, query, limit = 8) {
426506
427149
  skippedRecords++;
426507
427150
  continue;
426508
427151
  }
426509
- const searchable = `${event.tool} ${event.filePath ?? ""}`.normalize("NFKC").toLocaleLowerCase();
427152
+ const searchable = `${event.tool} ${event.status} ${event.filePath ?? ""}`.normalize("NFKC").toLocaleLowerCase();
426510
427153
  if (terms.every((term) => searchable.includes(term))) {
426511
427154
  hits.push(event);
426512
427155
  hits.sort((a, b) => b.at - a.at || a.sessionId.localeCompare(b.sessionId));
@@ -433766,9 +434409,9 @@ var TUI = class TUI extends Container {
433766
434409
  const debugRedraw = process.env["PI_DEBUG_REDRAW"] === "1";
433767
434410
  const logRedraw = (reason) => {
433768
434411
  if (!debugRedraw) return;
433769
- const logPath = path$17.join(nodeOs.homedir(), ".pi", "agent", "pi-debug.log");
434412
+ const logPath = path$16.join(nodeOs.homedir(), ".pi", "agent", "pi-debug.log");
433770
434413
  const msg = `[${(/* @__PURE__ */ new Date()).toISOString()}] fullRender: ${reason} (prev=${this.previousLines.length}, new=${newLines.length}, height=${height})\n`;
433771
- fs$17.appendFileSync(logPath, msg);
434414
+ fs$16.appendFileSync(logPath, msg);
433772
434415
  };
433773
434416
  if (this.previousLines.length === 0 && !widthChanged && !heightChanged) {
433774
434417
  logRedraw("first render");
@@ -433915,8 +434558,8 @@ var TUI = class TUI extends Container {
433915
434558
  buffer += "\x1B[?2026l";
433916
434559
  if (process.env["PI_TUI_DEBUG"] === "1") {
433917
434560
  const debugDir = "/tmp/tui";
433918
- fs$17.mkdirSync(debugDir, { recursive: true });
433919
- const debugPath = path$17.join(debugDir, `render-${Date.now()}-${Math.random().toString(36).slice(2)}.log`);
434561
+ fs$16.mkdirSync(debugDir, { recursive: true });
434562
+ const debugPath = path$16.join(debugDir, `render-${Date.now()}-${Math.random().toString(36).slice(2)}.log`);
433920
434563
  const debugData = [
433921
434564
  `firstChanged: ${firstChanged}`,
433922
434565
  `viewportTop: ${viewportTop}`,
@@ -433939,7 +434582,7 @@ var TUI = class TUI extends Container {
433939
434582
  "=== buffer ===",
433940
434583
  JSON.stringify(buffer)
433941
434584
  ].join("\n");
433942
- fs$17.writeFileSync(debugPath, debugData);
434585
+ fs$16.writeFileSync(debugPath, debugData);
433943
434586
  }
433944
434587
  this.terminal.write(buffer);
433945
434588
  this.cursorRow = Math.max(0, newLines.length - 1);
@@ -438525,12 +439168,12 @@ function loadNativeModifiersHelper() {
438525
439168
  if (process.platform !== "darwin") return void 0;
438526
439169
  const arch = process.arch;
438527
439170
  if (arch !== "x64" && arch !== "arm64") return void 0;
438528
- const moduleDir = path$17.dirname(fileURLToPath(import.meta.url));
438529
- const nativePath = path$17.join("native", "darwin", "prebuilds", `darwin-${arch}`, "darwin-modifiers.node");
439171
+ const moduleDir = path$16.dirname(fileURLToPath(import.meta.url));
439172
+ const nativePath = path$16.join("native", "darwin", "prebuilds", `darwin-${arch}`, "darwin-modifiers.node");
438530
439173
  const candidates = [
438531
- path$17.join(moduleDir, "..", nativePath),
438532
- path$17.join(moduleDir, nativePath),
438533
- path$17.join(path$17.dirname(process.execPath), nativePath)
439174
+ path$16.join(moduleDir, "..", nativePath),
439175
+ path$16.join(moduleDir, nativePath),
439176
+ path$16.join(path$16.dirname(process.execPath), nativePath)
438534
439177
  ];
438535
439178
  for (const modulePath of candidates) try {
438536
439179
  const helper = cjsRequire$1(modulePath);
@@ -438603,10 +439246,10 @@ var ProcessTerminal = class {
438603
439246
  const env = process.env["PI_TUI_WRITE_LOG"] || "";
438604
439247
  if (!env) return "";
438605
439248
  try {
438606
- if (fs$17.statSync(env).isDirectory()) {
439249
+ if (fs$16.statSync(env).isDirectory()) {
438607
439250
  const now = /* @__PURE__ */ new Date();
438608
439251
  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")}`;
438609
- return path$17.join(env, `tui-${ts}-${process.pid}.log`);
439252
+ return path$16.join(env, `tui-${ts}-${process.pid}.log`);
438610
439253
  }
438611
439254
  } catch {}
438612
439255
  return env;
@@ -438809,12 +439452,12 @@ var ProcessTerminal = class {
438809
439452
  try {
438810
439453
  const arch = process.arch;
438811
439454
  if (arch !== "x64" && arch !== "arm64") return;
438812
- const moduleDir = path$17.dirname(fileURLToPath(import.meta.url));
438813
- const nativePath = path$17.join("native", "win32", "prebuilds", `win32-${arch}`, "win32-console-mode.node");
439455
+ const moduleDir = path$16.dirname(fileURLToPath(import.meta.url));
439456
+ const nativePath = path$16.join("native", "win32", "prebuilds", `win32-${arch}`, "win32-console-mode.node");
438814
439457
  const candidates = [
438815
- path$17.join(moduleDir, "..", nativePath),
438816
- path$17.join(moduleDir, nativePath),
438817
- path$17.join(path$17.dirname(process.execPath), nativePath)
439458
+ path$16.join(moduleDir, "..", nativePath),
439459
+ path$16.join(moduleDir, nativePath),
439460
+ path$16.join(path$16.dirname(process.execPath), nativePath)
438818
439461
  ];
438819
439462
  for (const modulePath of candidates) try {
438820
439463
  cjsRequire(modulePath).enableVirtualTerminalInput?.();
@@ -438886,7 +439529,7 @@ var ProcessTerminal = class {
438886
439529
  write(data) {
438887
439530
  process.stdout.write(data);
438888
439531
  if (this.writeLogPath) try {
438889
- fs$17.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
439532
+ fs$16.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
438890
439533
  } catch {}
438891
439534
  }
438892
439535
  get columns() {
@@ -439421,7 +440064,7 @@ function buildUsageReportLines(options) {
439421
440064
  const errorStyle = (text) => currentTheme.fg("error", text);
439422
440065
  const severityColor = (sev) => sev === "danger" ? "error" : sev === "warn" ? "warning" : "success";
439423
440066
  const lines = [accent(uiText("usage.session.title")), ...buildSessionUsageSection(options.sessionUsage, options.sessionUsageError, value, muted, errorStyle)];
439424
- if (options.maxContextTokens > 0) {
440067
+ if (Number.isFinite(options.maxContextTokens) && options.maxContextTokens > 0) {
439425
440068
  const ratio = safeUsageRatio(options.contextTokens / options.maxContextTokens);
439426
440069
  const bar = renderProgressBar(ratio, 20);
439427
440070
  const pct = `${(ratio * 100).toFixed(1)}%`;
@@ -439672,7 +440315,7 @@ function buildStatusReportLines(options) {
439672
440315
  const { ratio, tokens, maxTokens } = contextValues(options);
439673
440316
  lines.push("");
439674
440317
  lines.push(accent(uiText("usage.context.title")));
439675
- if (maxTokens > 0) {
440318
+ if (Number.isFinite(maxTokens) && maxTokens > 0) {
439676
440319
  const safeRatio = safeUsageRatio(ratio);
439677
440320
  const bar = renderProgressBar(safeRatio, 20);
439678
440321
  const barColoured = currentTheme.fg(severityToken(ratioSeverity(safeRatio)), bar);
@@ -440623,11 +441266,18 @@ registerUiCatalogFragment({
440623
441266
  //#endregion
440624
441267
  //#region src/tui/utils/event-payload.ts
440625
441268
  function appendStreamingArgsPreview(current, next) {
440626
- const existing = (current ?? "").slice(0, STREAMING_ARGS_PREVIEW_MAX_CHARS);
441269
+ let existing = (current ?? "").slice(0, STREAMING_ARGS_PREVIEW_MAX_CHARS);
441270
+ const boundary = existing.charCodeAt(existing.length - 1);
441271
+ if (existing.length === 65536 && boundary >= 55296 && boundary <= 56319) existing = existing.slice(0, -1);
440627
441272
  if (next === null || next === void 0 || next.length === 0) return existing;
440628
441273
  const remaining = STREAMING_ARGS_PREVIEW_MAX_CHARS - existing.length;
440629
441274
  if (remaining <= 0) return existing;
440630
- return `${existing}${next.slice(0, remaining)}`;
441275
+ const first = next.charCodeAt(0);
441276
+ const previous = existing.charCodeAt(existing.length - 1);
441277
+ const continuation = first >= 56320 && first <= 57343 && !(previous >= 55296 && previous <= 56319) ? next.slice(1) : next;
441278
+ const preview = `${existing}${continuation.slice(0, remaining)}`;
441279
+ const last = preview.charCodeAt(preview.length - 1);
441280
+ return preview.length === 65536 && last >= 55296 && last <= 56319 ? preview.slice(0, -1) : preview;
440631
441281
  }
440632
441282
  function unescapeJsonString$1(s) {
440633
441283
  return s.replaceAll(/\\(["\\/bfnrt])/g, (_, ch) => {
@@ -502538,6 +503188,7 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
502538
503188
  const tokens = trimmed.split(/\s+/);
502539
503189
  const action = tokens[0]?.toLowerCase();
502540
503190
  if (action === "next") return "always";
503191
+ if (action === "edit" || action === "block") return "always";
502541
503192
  if (tokens.length === 1 && (action === "status" || action === "pause" || action === "paused" || action === "cancel" || action === "clear" || action === "stop")) return "always";
502542
503193
  return "idle-only";
502543
503194
  }
@@ -509362,7 +510013,9 @@ registerUiCatalogFragment({
509362
510013
  //#region src/tui/commands/goal.ts
509363
510014
  const MAX_GOAL_OBJECTIVE_LENGTH = 4e3;
509364
510015
  const RESUME_GOAL_INPUT = "Resume the active goal.";
510016
+ const pendingGoalEdits = /* @__PURE__ */ new WeakMap();
509365
510017
  const CONTROL_SUBCOMMANDS = new Map([
510018
+ ["complete", "complete"],
509366
510019
  ["pause", "pause"],
509367
510020
  ["paused", "pause"],
509368
510021
  ["resume", "resume"],
@@ -509384,6 +510037,26 @@ function parseGoalCommand(rawArgs) {
509384
510037
  if (args.length === 0 || args.toLowerCase() === "status") return { kind: "status" };
509385
510038
  const tokens = args.split(/\s+/);
509386
510039
  const first = tokens[0]?.toLowerCase();
510040
+ if (first === "block") return {
510041
+ kind: "block",
510042
+ reason: tokens.slice(1).join(" ").trim() || void 0
510043
+ };
510044
+ if (first === "edit") {
510045
+ const objective = tokens.slice(1).join(" ").trim();
510046
+ if (objective.length === 0) return {
510047
+ kind: "error",
510048
+ severity: "hint",
510049
+ message: uiText("goal.error.objectiveRequired")
510050
+ };
510051
+ if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) return {
510052
+ kind: "error",
510053
+ message: uiText("goal.error.objectiveTooLong", { max: MAX_GOAL_OBJECTIVE_LENGTH })
510054
+ };
510055
+ return {
510056
+ kind: "edit",
510057
+ objective
510058
+ };
510059
+ }
509387
510060
  if (first === "next") return parseNextGoalCommand(tokens);
509388
510061
  const control = first === void 0 ? void 0 : CONTROL_SUBCOMMANDS.get(first);
509389
510062
  if (control !== void 0 && tokens.length === 1) return { kind: control };
@@ -509421,6 +510094,15 @@ async function handleGoalCommand(host, args) {
509421
510094
  case "status":
509422
510095
  await showGoalStatus(host);
509423
510096
  return;
510097
+ case "edit":
510098
+ await editGoal(host, parsed.objective);
510099
+ return;
510100
+ case "block":
510101
+ await blockGoal(host, parsed.reason);
510102
+ return;
510103
+ case "complete":
510104
+ await completeGoal(host);
510105
+ return;
509424
510106
  case "pause":
509425
510107
  await pauseGoal(host);
509426
510108
  return;
@@ -509666,12 +510348,78 @@ async function startGoal(host, parsed, options) {
509666
510348
  else host.sendNormalUserInput(parsed.objective);
509667
510349
  return true;
509668
510350
  }
510351
+ async function completeGoal(host) {
510352
+ if (isBusy(host)) {
510353
+ host.showStatus(slashBusyMessage("goal", host.state.appState.isCompacting ? "compacting" : "streaming"));
510354
+ return;
510355
+ }
510356
+ const session = host.requireSession();
510357
+ pendingGoalEdits.delete(host);
510358
+ try {
510359
+ const result = await session.completeGoal();
510360
+ if (host.session !== session || result !== null) return;
510361
+ const { goal } = await session.getGoal();
510362
+ if (host.session !== session) return;
510363
+ host.setAppState({ goal });
510364
+ if (goal === null) host.showStatus(uiText("goal.status.noneSet"));
510365
+ else renderGoalStatus(host, goal);
510366
+ } catch (error) {
510367
+ if (host.session !== session) return;
510368
+ if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
510369
+ host.showStatus(uiText("goal.status.noneSet"));
510370
+ return;
510371
+ }
510372
+ host.showError(formatErrorMessage$2(error));
510373
+ }
510374
+ }
510375
+ async function blockGoal(host, reason) {
510376
+ const session = host.requireSession();
510377
+ pendingGoalEdits.delete(host);
510378
+ try {
510379
+ const goal = await session.blockGoal({ reason });
510380
+ if (host.session !== session) return;
510381
+ if (isStreaming$1(host)) await session.cancel();
510382
+ if (host.session !== session) return;
510383
+ host.setAppState({ goal });
510384
+ renderGoalStatus(host, goal);
510385
+ } catch (error) {
510386
+ if (host.session !== session) return;
510387
+ if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
510388
+ host.showStatus(uiText("goal.status.noneSet"));
510389
+ return;
510390
+ }
510391
+ host.showError(formatErrorMessage$2(error));
510392
+ }
510393
+ }
510394
+ async function editGoal(host, objective) {
510395
+ const session = host.requireSession();
510396
+ const request = Symbol("goal-edit");
510397
+ pendingGoalEdits.set(host, request);
510398
+ try {
510399
+ const goal = await session.editGoal({ objective });
510400
+ if (host.session !== session || pendingGoalEdits.get(host) !== request) return;
510401
+ host.setAppState({ goal });
510402
+ renderGoalStatus(host, goal);
510403
+ } catch (error) {
510404
+ if (host.session !== session || pendingGoalEdits.get(host) !== request) return;
510405
+ if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
510406
+ host.showStatus(uiText("goal.status.noneSet"));
510407
+ return;
510408
+ }
510409
+ host.showError(formatErrorMessage$2(error));
510410
+ } finally {
510411
+ if (pendingGoalEdits.get(host) === request) pendingGoalEdits.delete(host);
510412
+ }
510413
+ }
509669
510414
  async function pauseGoal(host) {
509670
510415
  const session = host.requireSession();
510416
+ pendingGoalEdits.delete(host);
509671
510417
  try {
509672
510418
  await session.pauseGoal();
510419
+ if (host.session !== session) return;
509673
510420
  if (isStreaming$1(host)) await session.cancel();
509674
510421
  } catch (error) {
510422
+ if (host.session !== session) return;
509675
510423
  if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
509676
510424
  host.showStatus(uiText("goal.status.noneToPause"));
509677
510425
  return;
@@ -509679,6 +510427,7 @@ async function pauseGoal(host) {
509679
510427
  host.showError(formatErrorMessage$2(error));
509680
510428
  return;
509681
510429
  }
510430
+ if (host.session !== session) return;
509682
510431
  host.track("goal_pause");
509683
510432
  host.showStatus(uiText("goal.status.paused"));
509684
510433
  }
@@ -509687,9 +510436,12 @@ async function resumeGoal(host) {
509687
510436
  host.showError(uiText("goal.error.modelNotSet"));
509688
510437
  return;
509689
510438
  }
510439
+ const session = host.requireSession();
510440
+ pendingGoalEdits.delete(host);
509690
510441
  try {
509691
- await host.requireSession().resumeGoal();
510442
+ await session.resumeGoal();
509692
510443
  } catch (error) {
510444
+ if (host.session !== session) return;
509693
510445
  if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
509694
510446
  host.showStatus(uiText("goal.status.noneToResume"));
509695
510447
  return;
@@ -509697,15 +510449,19 @@ async function resumeGoal(host) {
509697
510449
  host.showError(formatErrorMessage$2(error));
509698
510450
  return;
509699
510451
  }
510452
+ if (host.session !== session) return;
509700
510453
  host.track("goal_resume");
509701
510454
  host.sendNormalUserInput(RESUME_GOAL_INPUT);
509702
510455
  }
509703
510456
  async function cancelGoal(host) {
509704
510457
  const session = host.requireSession();
510458
+ pendingGoalEdits.delete(host);
509705
510459
  try {
509706
510460
  await session.cancelGoal();
510461
+ if (host.session !== session) return;
509707
510462
  if (isStreaming$1(host)) await session.cancel();
509708
510463
  } catch (error) {
510464
+ if (host.session !== session) return;
509709
510465
  if (isBlunError(error) && error.code === ErrorCodes.GOAL_NOT_FOUND) {
509710
510466
  host.showStatus(uiText("goal.status.noneToCancel"));
509711
510467
  return;
@@ -509713,6 +510469,7 @@ async function cancelGoal(host) {
509713
510469
  host.showError(formatErrorMessage$2(error));
509714
510470
  return;
509715
510471
  }
510472
+ if (host.session !== session) return;
509716
510473
  host.track("goal_cancel");
509717
510474
  host.showNotice(uiText("goal.status.cancelled"));
509718
510475
  }
@@ -509723,6 +510480,9 @@ async function showGoalStatus(host) {
509723
510480
  host.showStatus(uiText("goal.status.noneSet"));
509724
510481
  return;
509725
510482
  }
510483
+ renderGoalStatus(host, goal);
510484
+ }
510485
+ function renderGoalStatus(host, goal) {
509726
510486
  if (host.getChannelCommandContext?.() !== void 0) {
509727
510487
  host.showStatus(`${goalPanelTitle(goal).trim()}\n${goal.objective}`);
509728
510488
  return;
@@ -521035,6 +521795,196 @@ function numberField(record, key) {
521035
521795
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
521036
521796
  }
521037
521797
  //#endregion
521798
+ //#region src/tui/components/media/image-thumbnail.ts
521799
+ /**
521800
+ * Transcript-side rendering of a pasted image.
521801
+ *
521802
+ * On terminals that speak the Kitty graphics protocol or iTerm2 inline
521803
+ * image protocol (detected by pi-tui's `getCapabilities()`), we show
521804
+ * the actual image. Everywhere else we fall back to a one-line text
521805
+ * marker matching the placeholder the user sees in the input box —
521806
+ * this keeps the transcript readable on Terminal.app / Linux default
521807
+ * terminals / `script` recordings without extra chrome.
521808
+ *
521809
+ * Height is capped at ~12 rows so a single screenshot can't monopolize
521810
+ * the viewport; pi-tui handles proportional scaling internally.
521811
+ */
521812
+ const MAX_IMAGE_ROWS = 12;
521813
+ const MAX_IMAGE_WIDTH = 40;
521814
+ var ImageThumbnail = class extends Container {
521815
+ attachment;
521816
+ image;
521817
+ lastBuiltProtocol;
521818
+ constructor(attachment) {
521819
+ super();
521820
+ this.attachment = attachment;
521821
+ this.buildChildren();
521822
+ }
521823
+ buildChildren() {
521824
+ this.clear();
521825
+ const caps = getCapabilities();
521826
+ const supportsInline = caps.images === "kitty" || caps.images === "iterm2";
521827
+ this.lastBuiltProtocol = caps.images;
521828
+ if (!supportsInline) {
521829
+ this.addChild(new Text(currentTheme.fg("accent", this.attachment.placeholder), 0, 0));
521830
+ return;
521831
+ }
521832
+ const theme = { fallbackColor: (s) => currentTheme.fg("textDim", s) };
521833
+ this.image ??= new Image(Buffer.from(this.attachment.bytes).toString("base64"), this.attachment.mime, theme, {
521834
+ maxHeightCells: MAX_IMAGE_ROWS,
521835
+ maxWidthCells: MAX_IMAGE_WIDTH,
521836
+ filename: this.attachment.placeholder
521837
+ }, {
521838
+ widthPx: this.attachment.width,
521839
+ heightPx: this.attachment.height
521840
+ });
521841
+ this.image.invalidate();
521842
+ this.addChild(this.image);
521843
+ }
521844
+ render(width) {
521845
+ const safeWidth = Math.max(0, width);
521846
+ if (safeWidth === 0) return [""];
521847
+ if (safeWidth < MAX_IMAGE_WIDTH + 2) return new Text(currentTheme.fg("accent", this.attachment.placeholder), 0, 0).render(safeWidth);
521848
+ const caps = getCapabilities();
521849
+ if (this.lastBuiltProtocol !== caps.images) this.buildChildren();
521850
+ return super.render(safeWidth);
521851
+ }
521852
+ invalidate() {
521853
+ this.buildChildren();
521854
+ super.invalidate();
521855
+ }
521856
+ };
521857
+ //#endregion
521858
+ //#region src/utils/image/image-mime.ts
521859
+ function parseImageMeta(bytes) {
521860
+ if (isPng(bytes)) return parsePng(bytes);
521861
+ if (isJpeg(bytes)) return parseJpeg(bytes);
521862
+ if (isGif(bytes)) return parseGif(bytes);
521863
+ if (isWebp(bytes)) return parseWebp(bytes);
521864
+ return null;
521865
+ }
521866
+ function isPng(b) {
521867
+ return b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71 && b[4] === 13 && b[5] === 10 && b[6] === 26 && b[7] === 10;
521868
+ }
521869
+ function parsePng(b) {
521870
+ if (b.length < 24) return null;
521871
+ const width = readUInt32BE(b, 16);
521872
+ const height = readUInt32BE(b, 20);
521873
+ if (width <= 0 || height <= 0) return null;
521874
+ return {
521875
+ mime: "image/png",
521876
+ width,
521877
+ height
521878
+ };
521879
+ }
521880
+ function isJpeg(b) {
521881
+ return b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255;
521882
+ }
521883
+ function parseJpeg(b) {
521884
+ let i = 2;
521885
+ while (i < b.length) {
521886
+ if (b[i] !== 255) {
521887
+ i += 1;
521888
+ continue;
521889
+ }
521890
+ while (i < b.length && b[i] === 255) i += 1;
521891
+ if (i >= b.length) return null;
521892
+ const marker = b[i];
521893
+ i += 1;
521894
+ if (marker === 216 || marker === 217) continue;
521895
+ if (i + 1 >= b.length) return null;
521896
+ const segLen = readUInt16BE(b, i);
521897
+ if (isSofMarker(marker)) {
521898
+ if (i + 7 >= b.length) return null;
521899
+ const height = readUInt16BE(b, i + 3);
521900
+ const width = readUInt16BE(b, i + 5);
521901
+ if (width <= 0 || height <= 0) return null;
521902
+ return {
521903
+ mime: "image/jpeg",
521904
+ width,
521905
+ height
521906
+ };
521907
+ }
521908
+ i += segLen;
521909
+ }
521910
+ return null;
521911
+ }
521912
+ function isSofMarker(marker) {
521913
+ if (marker < 192 || marker > 207) return false;
521914
+ return marker !== 196 && marker !== 200 && marker !== 204;
521915
+ }
521916
+ function isGif(b) {
521917
+ return b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70 && b[3] === 56 && (b[4] === 55 || b[4] === 57) && b[5] === 97;
521918
+ }
521919
+ function parseGif(b) {
521920
+ if (b.length < 10) return null;
521921
+ const width = readUInt16LE(b, 6);
521922
+ const height = readUInt16LE(b, 8);
521923
+ if (width <= 0 || height <= 0) return null;
521924
+ return {
521925
+ mime: "image/gif",
521926
+ width,
521927
+ height
521928
+ };
521929
+ }
521930
+ function isWebp(b) {
521931
+ return b.length >= 12 && b[0] === 82 && b[1] === 73 && b[2] === 70 && b[3] === 70 && b[8] === 87 && b[9] === 69 && b[10] === 66 && b[11] === 80;
521932
+ }
521933
+ function parseWebp(b) {
521934
+ if (b.length < 30) return null;
521935
+ const chunk = String.fromCodePoint(b[12], b[13], b[14], b[15]);
521936
+ if (chunk === "VP8 ") {
521937
+ const widthRaw = readUInt16LE(b, 26);
521938
+ const heightRaw = readUInt16LE(b, 28);
521939
+ const width = widthRaw & 16383;
521940
+ const height = heightRaw & 16383;
521941
+ if (width <= 0 || height <= 0) return null;
521942
+ return {
521943
+ mime: "image/webp",
521944
+ width,
521945
+ height
521946
+ };
521947
+ }
521948
+ if (chunk === "VP8L") {
521949
+ if (b[20] !== 47) return null;
521950
+ const b1 = b[21];
521951
+ const b2 = b[22];
521952
+ const b3 = b[23];
521953
+ const b4 = b[24];
521954
+ const width = 1 + ((b2 & 63) << 8 | b1);
521955
+ const height = 1 + ((b4 & 15) << 10 | b3 << 2 | (b2 & 192) >> 6);
521956
+ if (width <= 0 || height <= 0) return null;
521957
+ return {
521958
+ mime: "image/webp",
521959
+ width,
521960
+ height
521961
+ };
521962
+ }
521963
+ if (chunk === "VP8X") {
521964
+ const width = 1 + readUInt24LE(b, 24);
521965
+ const height = 1 + readUInt24LE(b, 27);
521966
+ if (width <= 0 || height <= 0) return null;
521967
+ return {
521968
+ mime: "image/webp",
521969
+ width,
521970
+ height
521971
+ };
521972
+ }
521973
+ return null;
521974
+ }
521975
+ function readUInt16BE(b, off) {
521976
+ return b[off] << 8 | b[off + 1];
521977
+ }
521978
+ function readUInt16LE(b, off) {
521979
+ return b[off] | b[off + 1] << 8;
521980
+ }
521981
+ function readUInt24LE(b, off) {
521982
+ return b[off] | b[off + 1] << 8 | b[off + 2] << 16;
521983
+ }
521984
+ function readUInt32BE(b, off) {
521985
+ return Math.trunc(b[off] * 16777216 + (b[off + 1] << 16) + (b[off + 2] << 8) + b[off + 3]);
521986
+ }
521987
+ //#endregion
521038
521988
  //#region src/tui/components/messages/tool-renderers/media.copy.ts
521039
521989
  registerUiCatalogFragment({
521040
521990
  en: { "mediaChip.uploaded": "uploaded" },
@@ -521049,6 +521999,51 @@ registerUiCatalogFragment({
521049
521999
  const PATH_TAG_RE = /^<(image|video)\s+path="([^"]+)">$/;
521050
522000
  const ORIGINAL_SIZE_RE = /original size\s+(\d+x\d+px)/;
521051
522001
  const DATA_URL_RE = /^data:([^;]+);base64,(.*)$/s;
522002
+ const MAX_PREVIEW_BYTES = 8 * 1024 * 1024;
522003
+ const MAX_PREVIEW_IMAGES = 4;
522004
+ function imagePreviews(output) {
522005
+ const protocol = getCapabilities().images;
522006
+ if (protocol !== "kitty" && protocol !== "iterm2") return [];
522007
+ let parts;
522008
+ try {
522009
+ parts = JSON.parse(output);
522010
+ } catch {
522011
+ return [];
522012
+ }
522013
+ if (!Array.isArray(parts)) return [];
522014
+ const previews = [];
522015
+ let remainingBytes = MAX_PREVIEW_BYTES;
522016
+ for (const raw of parts) {
522017
+ if (previews.length >= MAX_PREVIEW_IMAGES || remainingBytes <= 0) break;
522018
+ if (typeof raw !== "object" || raw === null) continue;
522019
+ const part = raw;
522020
+ if (part["type"] !== "image_url") continue;
522021
+ const holder = part["imageUrl"];
522022
+ if (typeof holder !== "object" || holder === null) continue;
522023
+ const url = holder["url"];
522024
+ if (typeof url !== "string") continue;
522025
+ const data = DATA_URL_RE.exec(url);
522026
+ if (data === null || data[2] === void 0) continue;
522027
+ const encoded = data[2];
522028
+ if (bytesFromBase64(encoded) > remainingBytes || !/^[A-Za-z0-9+/]*={0,2}$/.test(encoded)) continue;
522029
+ const bytes = Buffer.from(encoded, "base64");
522030
+ if (bytes.length > remainingBytes) continue;
522031
+ const meta = parseImageMeta(bytes);
522032
+ if (meta === null || meta.mime !== data[1]) continue;
522033
+ const attachment = {
522034
+ id: 0,
522035
+ kind: "image",
522036
+ bytes,
522037
+ mime: meta.mime,
522038
+ width: meta.width,
522039
+ height: meta.height,
522040
+ placeholder: `${meta.mime} (${meta.width}x${meta.height})`
522041
+ };
522042
+ previews.push(new ImageThumbnail(attachment));
522043
+ remainingBytes -= bytes.length;
522044
+ }
522045
+ return previews;
522046
+ }
521052
522047
  function bytesFromBase64(b64) {
521053
522048
  const len = b64.length;
521054
522049
  if (len === 0) return 0;
@@ -521132,7 +522127,6 @@ const readMediaChip = (_toolCall, result) => {
521132
522127
  return `${summary.kind} (${meta.join(", ")})`;
521133
522128
  };
521134
522129
  const readMediaSummary = (toolCall, result, ctx) => {
521135
- if (result.is_error) return renderTruncated(toolCall, result, ctx);
521136
522130
  const summary = parseReadMediaOutput(result.output);
521137
522131
  if (summary === null) return renderTruncated(toolCall, result, ctx);
521138
522132
  if (!ctx.expanded) return [];
@@ -521144,6 +522138,22 @@ const readMediaSummary = (toolCall, result, ctx) => {
521144
522138
  if (meta.length > 0) tail.push(meta.join(", "));
521145
522139
  if (summary.url !== void 0) tail.push(summary.url);
521146
522140
  out.push(new Text(` ${dim(tail.join(" · "))}`, 0, 0));
522141
+ if (!result.is_error && summary.kind === "image") out.push(...imagePreviews(result.output));
522142
+ return out;
522143
+ };
522144
+ const genericMediaResult = (toolCall, result, ctx) => {
522145
+ if (!result.output.includes("\"image_url\"") && !result.output.includes("\"video_url\"")) return renderTruncated(toolCall, result, ctx);
522146
+ const summary = parseReadMediaOutput(result.output);
522147
+ if (summary === null) return renderTruncated(toolCall, result, ctx);
522148
+ const textParts = JSON.parse(result.output).filter((part) => typeof part === "object" && part !== null && part["type"] === "text" && typeof part["text"] === "string").map((part) => part.text);
522149
+ const meta = metaSegments(summary);
522150
+ const label = [summary.kind, ...meta].join(" · ");
522151
+ const out = [new Text(` ${chalk.dim(label)}`, 0, 0)];
522152
+ if (textParts.length > 0) out.push(...renderTruncated(toolCall, {
522153
+ ...result,
522154
+ output: textParts.join("\n")
522155
+ }, ctx));
522156
+ if (ctx.expanded && !result.is_error) out.push(...imagePreviews(result.output));
521147
522157
  return out;
521148
522158
  };
521149
522159
  //#endregion
@@ -521310,8 +522320,8 @@ const globSummary = withGlance(globGlance);
521310
522320
  *
521311
522321
  * Each tool name maps to a `ResultRenderer` that turns the tool's
521312
522322
  * `ToolResultBlockData` into renderable Components. Tools without an
521313
- * explicit entry fall through to `renderTruncated` (the original
521314
- * 3-line + ctrl+o behavior).
522323
+ * explicit entry fall through to the generic renderer, which keeps the
522324
+ * original 3-line + ctrl+o behavior for text results.
521315
522325
  *
521316
522326
  * Keep this dispatch flat — tool names live next to the renderer they
521317
522327
  * choose, so adding a new tool means appending one case.
@@ -521323,7 +522333,7 @@ const globSummary = withGlance(globGlance);
521323
522333
  * the main agent previews it.
521324
522334
  */
521325
522335
  function isGenericToolResult(toolName) {
521326
- return pickResultRenderer(toolName) === renderTruncated;
522336
+ return pickResultRenderer(toolName) === genericMediaResult;
521327
522337
  }
521328
522338
  function pickResultRenderer(toolName) {
521329
522339
  switch (toolName) {
@@ -521341,7 +522351,7 @@ function pickResultRenderer(toolName) {
521341
522351
  case "GetGoal":
521342
522352
  case "SetGoalBudget":
521343
522353
  case "UpdateGoal": return goalSummary;
521344
- default: return renderTruncated;
522354
+ default: return genericMediaResult;
521345
522355
  }
521346
522356
  }
521347
522357
  //#endregion
@@ -523296,66 +524306,6 @@ function formatActivityLine(phase, toolName, args, workspaceDir) {
523296
524306
  return keyArg ? `${verb} ${toolName} (${keyArg})` : `${verb} ${toolName}`;
523297
524307
  }
523298
524308
  //#endregion
523299
- //#region src/tui/components/media/image-thumbnail.ts
523300
- /**
523301
- * Transcript-side rendering of a pasted image.
523302
- *
523303
- * On terminals that speak the Kitty graphics protocol or iTerm2 inline
523304
- * image protocol (detected by pi-tui's `getCapabilities()`), we show
523305
- * the actual image. Everywhere else we fall back to a one-line text
523306
- * marker matching the placeholder the user sees in the input box —
523307
- * this keeps the transcript readable on Terminal.app / Linux default
523308
- * terminals / `script` recordings without extra chrome.
523309
- *
523310
- * Height is capped at ~12 rows so a single screenshot can't monopolize
523311
- * the viewport; pi-tui handles proportional scaling internally.
523312
- */
523313
- const MAX_IMAGE_ROWS = 12;
523314
- const MAX_IMAGE_WIDTH = 40;
523315
- var ImageThumbnail = class extends Container {
523316
- attachment;
523317
- image;
523318
- lastBuiltProtocol;
523319
- constructor(attachment) {
523320
- super();
523321
- this.attachment = attachment;
523322
- this.buildChildren();
523323
- }
523324
- buildChildren() {
523325
- this.clear();
523326
- const caps = getCapabilities();
523327
- const supportsInline = caps.images === "kitty" || caps.images === "iterm2";
523328
- this.lastBuiltProtocol = caps.images;
523329
- if (!supportsInline) {
523330
- this.addChild(new Text(currentTheme.fg("accent", this.attachment.placeholder), 0, 0));
523331
- return;
523332
- }
523333
- const theme = { fallbackColor: (s) => currentTheme.fg("textDim", s) };
523334
- this.image ??= new Image(Buffer.from(this.attachment.bytes).toString("base64"), this.attachment.mime, theme, {
523335
- maxHeightCells: MAX_IMAGE_ROWS,
523336
- maxWidthCells: MAX_IMAGE_WIDTH,
523337
- filename: this.attachment.placeholder
523338
- }, {
523339
- widthPx: this.attachment.width,
523340
- heightPx: this.attachment.height
523341
- });
523342
- this.image.invalidate();
523343
- this.addChild(this.image);
523344
- }
523345
- render(width) {
523346
- const safeWidth = Math.max(0, width);
523347
- if (safeWidth === 0) return [""];
523348
- if (safeWidth < MAX_IMAGE_WIDTH + 2) return new Text(currentTheme.fg("accent", this.attachment.placeholder), 0, 0).render(safeWidth);
523349
- const caps = getCapabilities();
523350
- if (this.lastBuiltProtocol !== caps.images) this.buildChildren();
523351
- return super.render(safeWidth);
523352
- }
523353
- invalidate() {
523354
- this.buildChildren();
523355
- super.invalidate();
523356
- }
523357
- };
523358
- //#endregion
523359
524309
  //#region src/tui/components/messages/user-message.ts
523360
524310
  /**
523361
524311
  * Renders a user message in the transcript.
@@ -523460,6 +524410,14 @@ async function handleUndoCommand(host, args = "") {
523460
524410
  await undoByCount(host, count);
523461
524411
  }
523462
524412
  async function undoByCount(host, count) {
524413
+ const finish = host.beginLocalContextMutation?.();
524414
+ try {
524415
+ return await undoByCountOwned(host, count);
524416
+ } finally {
524417
+ finish?.();
524418
+ }
524419
+ }
524420
+ async function undoByCountOwned(host, count) {
523463
524421
  const session = host.session;
523464
524422
  if (session === void 0) {
523465
524423
  host.showError(uiText("undo.error.noActiveSession"));
@@ -532435,136 +533393,6 @@ var ClipboardImageHintController = class {
532435
533393
  }
532436
533394
  };
532437
533395
  //#endregion
532438
- //#region src/utils/image/image-mime.ts
532439
- function parseImageMeta(bytes) {
532440
- if (isPng(bytes)) return parsePng(bytes);
532441
- if (isJpeg(bytes)) return parseJpeg(bytes);
532442
- if (isGif(bytes)) return parseGif(bytes);
532443
- if (isWebp(bytes)) return parseWebp(bytes);
532444
- return null;
532445
- }
532446
- function isPng(b) {
532447
- return b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71 && b[4] === 13 && b[5] === 10 && b[6] === 26 && b[7] === 10;
532448
- }
532449
- function parsePng(b) {
532450
- if (b.length < 24) return null;
532451
- const width = readUInt32BE(b, 16);
532452
- const height = readUInt32BE(b, 20);
532453
- if (width <= 0 || height <= 0) return null;
532454
- return {
532455
- mime: "image/png",
532456
- width,
532457
- height
532458
- };
532459
- }
532460
- function isJpeg(b) {
532461
- return b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255;
532462
- }
532463
- function parseJpeg(b) {
532464
- let i = 2;
532465
- while (i < b.length) {
532466
- if (b[i] !== 255) {
532467
- i += 1;
532468
- continue;
532469
- }
532470
- while (i < b.length && b[i] === 255) i += 1;
532471
- if (i >= b.length) return null;
532472
- const marker = b[i];
532473
- i += 1;
532474
- if (marker === 216 || marker === 217) continue;
532475
- if (i + 1 >= b.length) return null;
532476
- const segLen = readUInt16BE(b, i);
532477
- if (isSofMarker(marker)) {
532478
- if (i + 7 >= b.length) return null;
532479
- const height = readUInt16BE(b, i + 3);
532480
- const width = readUInt16BE(b, i + 5);
532481
- if (width <= 0 || height <= 0) return null;
532482
- return {
532483
- mime: "image/jpeg",
532484
- width,
532485
- height
532486
- };
532487
- }
532488
- i += segLen;
532489
- }
532490
- return null;
532491
- }
532492
- function isSofMarker(marker) {
532493
- if (marker < 192 || marker > 207) return false;
532494
- return marker !== 196 && marker !== 200 && marker !== 204;
532495
- }
532496
- function isGif(b) {
532497
- return b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70 && b[3] === 56 && (b[4] === 55 || b[4] === 57) && b[5] === 97;
532498
- }
532499
- function parseGif(b) {
532500
- if (b.length < 10) return null;
532501
- const width = readUInt16LE(b, 6);
532502
- const height = readUInt16LE(b, 8);
532503
- if (width <= 0 || height <= 0) return null;
532504
- return {
532505
- mime: "image/gif",
532506
- width,
532507
- height
532508
- };
532509
- }
532510
- function isWebp(b) {
532511
- return b.length >= 12 && b[0] === 82 && b[1] === 73 && b[2] === 70 && b[3] === 70 && b[8] === 87 && b[9] === 69 && b[10] === 66 && b[11] === 80;
532512
- }
532513
- function parseWebp(b) {
532514
- if (b.length < 30) return null;
532515
- const chunk = String.fromCodePoint(b[12], b[13], b[14], b[15]);
532516
- if (chunk === "VP8 ") {
532517
- const widthRaw = readUInt16LE(b, 26);
532518
- const heightRaw = readUInt16LE(b, 28);
532519
- const width = widthRaw & 16383;
532520
- const height = heightRaw & 16383;
532521
- if (width <= 0 || height <= 0) return null;
532522
- return {
532523
- mime: "image/webp",
532524
- width,
532525
- height
532526
- };
532527
- }
532528
- if (chunk === "VP8L") {
532529
- if (b[20] !== 47) return null;
532530
- const b1 = b[21];
532531
- const b2 = b[22];
532532
- const b3 = b[23];
532533
- const b4 = b[24];
532534
- const width = 1 + ((b2 & 63) << 8 | b1);
532535
- const height = 1 + ((b4 & 15) << 10 | b3 << 2 | (b2 & 192) >> 6);
532536
- if (width <= 0 || height <= 0) return null;
532537
- return {
532538
- mime: "image/webp",
532539
- width,
532540
- height
532541
- };
532542
- }
532543
- if (chunk === "VP8X") {
532544
- const width = 1 + readUInt24LE(b, 24);
532545
- const height = 1 + readUInt24LE(b, 27);
532546
- if (width <= 0 || height <= 0) return null;
532547
- return {
532548
- mime: "image/webp",
532549
- width,
532550
- height
532551
- };
532552
- }
532553
- return null;
532554
- }
532555
- function readUInt16BE(b, off) {
532556
- return b[off] << 8 | b[off + 1];
532557
- }
532558
- function readUInt16LE(b, off) {
532559
- return b[off] | b[off + 1] << 8;
532560
- }
532561
- function readUInt24LE(b, off) {
532562
- return b[off] | b[off + 1] << 8 | b[off + 2] << 16;
532563
- }
532564
- function readUInt32BE(b, off) {
532565
- return Math.trunc(b[off] * 16777216 + (b[off + 1] << 16) + (b[off + 2] << 8) + b[off + 3]);
532566
- }
532567
- //#endregion
532568
533396
  //#region src/utils/clipboard/clipboard-image.ts
532569
533397
  /**
532570
533398
  * Read media from the system clipboard with graceful platform fallbacks.
@@ -535490,7 +536318,7 @@ function isTelegramBridgeFraming(value) {
535490
536318
  let remaining = value.trim();
535491
536319
  let foundFrame = false;
535492
536320
  while (remaining.length > 0) {
535493
- const frame = /^(?:\[(?:REPLY-PFLICHT|SEMANTISCHE ADRESSIERUNG|NUR MITLESEN|SPRACH-GATE)\b[\s\S]*?\]|<vision-observation\s+source="telegram"\b[^>]*>[\s\S]*?<\/vision-observation>)/i.exec(remaining);
536321
+ const frame = /^(?:\[GRUPPENANTWORT:[^[\]\r\n]*(?:\[\[BLUN_TELEGRAM_SILENT\]\][^[\]\r\n]*)*\]|\[(?:REPLY-PFLICHT|SEMANTISCHE ADRESSIERUNG|NUR MITLESEN|SPRACH-GATE)\b[\s\S]*?\]|<vision-observation\s+source="telegram"\b[^>]*>[\s\S]*?<\/vision-observation>)/i.exec(remaining);
535494
536322
  if (frame === null) return false;
535495
536323
  foundFrame = true;
535496
536324
  remaining = remaining.slice(frame[0].length).trim();
@@ -536701,10 +537529,71 @@ var SessionEventHandler = class {
536701
537529
  pendingCompactionRetry;
536702
537530
  compactionRetryPanel;
536703
537531
  localToolEvents;
537532
+ contextRefreshEpoch = 0;
537533
+ contextRefreshPending = false;
537534
+ contextRefreshRunning = false;
537535
+ contextRefreshTurnActive = false;
537536
+ contextRefreshFailed = false;
537537
+ localContextMutations = 0;
537538
+ contextRevisions = /* @__PURE__ */ new Map();
537539
+ beginLocalContextMutation() {
537540
+ const epoch = this.contextRefreshEpoch;
537541
+ this.localContextMutations++;
537542
+ let finished = false;
537543
+ return () => {
537544
+ if (finished) return;
537545
+ finished = true;
537546
+ if (epoch !== this.contextRefreshEpoch) return;
537547
+ this.localContextMutations--;
537548
+ this.drainContextRefresh();
537549
+ };
537550
+ }
537551
+ handleContextChanged(event) {
537552
+ if (event.agentId !== "main") return;
537553
+ const previous = this.contextRevisions.get(event.generation) ?? 0;
537554
+ if (event.revision < previous || event.revision === previous && !this.contextRefreshFailed) return;
537555
+ this.contextRevisions.delete(event.generation);
537556
+ this.contextRevisions.set(event.generation, event.revision);
537557
+ if (this.contextRevisions.size > 64) {
537558
+ const oldest = this.contextRevisions.keys().next().value;
537559
+ if (oldest !== void 0) this.contextRevisions.delete(oldest);
537560
+ }
537561
+ this.contextRefreshPending = true;
537562
+ this.drainContextRefresh();
537563
+ }
537564
+ drainContextRefresh() {
537565
+ const session = this.host.session;
537566
+ const refresh = this.host.refreshContextFromReplay;
537567
+ if (!this.contextRefreshPending || this.contextRefreshRunning || this.contextRefreshTurnActive || this.localContextMutations > 0 || session === void 0 || refresh === void 0) return;
537568
+ const epoch = this.contextRefreshEpoch;
537569
+ const isCurrent = () => epoch === this.contextRefreshEpoch && !this.host.aborted && this.host.session === session && this.host.state.appState.sessionId === session.id && this.localContextMutations === 0 && !this.contextRefreshPending && !this.contextRefreshTurnActive;
537570
+ this.contextRefreshPending = false;
537571
+ this.contextRefreshRunning = true;
537572
+ this.contextRefreshFailed = false;
537573
+ refresh.call(this.host, session, isCurrent).then((result) => {
537574
+ if (result === false && isCurrent()) this.contextRefreshFailed = true;
537575
+ }).catch((error) => {
537576
+ if (isCurrent()) {
537577
+ this.contextRefreshFailed = true;
537578
+ this.host.showError(formatErrorMessage$2(error));
537579
+ }
537580
+ }).finally(() => {
537581
+ if (epoch !== this.contextRefreshEpoch) return;
537582
+ this.contextRefreshRunning = false;
537583
+ this.drainContextRefresh();
537584
+ });
537585
+ }
536704
537586
  setLocalToolEventRecordingEnabled(enabled) {
536705
537587
  this.localToolEvents?.setEnabled(enabled);
536706
537588
  }
536707
537589
  resetRuntimeState() {
537590
+ this.contextRefreshEpoch++;
537591
+ this.contextRefreshPending = false;
537592
+ this.contextRefreshRunning = false;
537593
+ this.contextRefreshTurnActive = false;
537594
+ this.contextRefreshFailed = false;
537595
+ this.localContextMutations = 0;
537596
+ this.contextRevisions.clear();
536708
537597
  this.backgroundTasks.clear();
536709
537598
  this.backgroundTaskTranscriptedTerminal.clear();
536710
537599
  this.subAgentEventHandler.resetRuntimeState();
@@ -536826,10 +537715,14 @@ var SessionEventHandler = class {
536826
537715
  if ("turnId" in event && event.turnId !== void 0) this.host.streamingUI.setTurnId(String(event.turnId));
536827
537716
  switch (event.type) {
536828
537717
  case "turn.started":
537718
+ this.contextRefreshTurnActive = true;
537719
+ if (this.contextRefreshRunning) this.contextRefreshPending = true;
536829
537720
  this.handleTurnBegin(event);
536830
537721
  break;
536831
537722
  case "turn.ended":
537723
+ this.contextRefreshTurnActive = false;
536832
537724
  this.handleTurnEnd(event, sendQueued);
537725
+ this.drainContextRefresh();
536833
537726
  break;
536834
537727
  case "turn.step.started":
536835
537728
  this.handleStepBegin(event);
@@ -536875,6 +537768,9 @@ var SessionEventHandler = class {
536875
537768
  case "agent.status.updated":
536876
537769
  this.handleStatusUpdate(event);
536877
537770
  break;
537771
+ case "context.changed":
537772
+ this.handleContextChanged(event);
537773
+ break;
536878
537774
  case "session.meta.updated":
536879
537775
  this.handleSessionMetaChanged(event);
536880
537776
  break;
@@ -537270,7 +538166,7 @@ var SessionEventHandler = class {
537270
538166
  if (change.kind === "completion" && event.snapshot !== null) {
537271
538167
  this.pendingModelBlockedFallback = void 0;
537272
538168
  this.goalCompletionAwaitingClear = true;
537273
- this.goalCompletionTurnEnded = false;
538169
+ this.goalCompletionTurnEnded = change.actor === "user" && state.appState.streamingPhase === "idle";
537274
538170
  this.host.appendTranscriptEntry({
537275
538171
  id: nextTranscriptId(),
537276
538172
  kind: "assistant",
@@ -537342,7 +538238,7 @@ var SessionEventHandler = class {
537342
538238
  this.scheduleQueuedGoalPromotion();
537343
538239
  }
537344
538240
  isReadyForQueuedGoalPromotion(session) {
537345
- return (session === void 0 || this.host.session === session) && !this.host.aborted && this.host.state.appState.streamingPhase === "idle" && this.host.state.queuedMessages.length === 0;
538241
+ return (session === void 0 || this.host.session === session) && !this.host.aborted && this.host.state.appState.streamingPhase === "idle" && !this.host.state.appState.isCompacting && this.host.state.queuedMessages.length === 0;
537346
538242
  }
537347
538243
  async promoteNextQueuedGoal() {
537348
538244
  const { host } = this;
@@ -537947,6 +538843,14 @@ var SessionReplayRenderer = class {
537947
538843
  constructor(host) {
537948
538844
  this.host = host;
537949
538845
  }
538846
+ async refreshFromReplay(session, isCurrent, clearTranscript, historyLimit = 200) {
538847
+ if (!isCurrent()) return false;
538848
+ await session.refreshResumeState({ historyLimit });
538849
+ if (!isCurrent()) return false;
538850
+ if (session.getResumeState()?.agents["main"] === void 0) return this.hydrateFromReplay(session);
538851
+ clearTranscript();
538852
+ return this.hydrateFromReplay(session);
538853
+ }
537950
538854
  /** Records-only projection for a detached page; never hydrates the live snapshot. */
537951
538855
  renderHistoricalPage(agent) {
537952
538856
  this.renderRecords(agent);
@@ -539255,7 +540159,8 @@ function contextMetrics(state) {
539255
540159
  const responder = state.availableModels[responderAlias];
539256
540160
  const responderMax = responder === void 0 ? void 0 : effectiveModelAlias(responder).maxContextSize;
539257
540161
  const runtimeMax = Number.isFinite(state.maxContextTokens) ? Math.max(0, state.maxContextTokens) : 0;
539258
- const maxTokens = runtimeMax > 0 ? runtimeMax : responderMax ?? 0;
540162
+ const hardMaxTokens = runtimeMax > 0 ? runtimeMax : responderMax ?? 0;
540163
+ const maxTokens = Number.isFinite(hardMaxTokens) && hardMaxTokens > 0 ? hardMaxTokens : 0;
539259
540164
  return {
539260
540165
  tokens,
539261
540166
  maxTokens,
@@ -542927,9 +543832,12 @@ function isGroupNoiseReply(text) {
542927
543832
  function isGroupSuppressed(text, _contextOnly) {
542928
543833
  return isGroupNoiseReply(text);
542929
543834
  }
543835
+ function isSilentTurnMarker(text) {
543836
+ return text.trim() === "[[BLUN_TELEGRAM_SILENT]]";
543837
+ }
542930
543838
  async function sendReplyFallback(chatId, text, contextOnly = false, requireDelivery = false, progress, threadId) {
542931
543839
  if (threadId !== void 0 && !validChannelThreadId(threadId)) return false;
542932
- if (text.trim() === "[[BLUN_TELEGRAM_SILENT]]") return !requireDelivery;
543840
+ if (isSilentTurnMarker(text)) return !requireDelivery;
542933
543841
  const topic = threadId === void 0 ? {} : { message_thread_id: Number(threadId) };
542934
543842
  if (isGroupChat(chatId) && isGroupSuppressed(text, contextOnly)) {
542935
543843
  try {
@@ -545617,7 +546525,7 @@ var BlunTUI = class {
545617
546525
  })) return;
545618
546526
  if (outboxGrewForChat(guard.outboxMarker, guard.chatId, guard.threadId)) return;
545619
546527
  const finalText = this.state.transcriptEntries.slice(guard.transcriptStart).filter((entry) => entry.kind === "assistant" && entry.content.trim().length > 0).map((entry) => entry.content.trim()).at(-1) ?? "";
545620
- if (finalText.length === 0) return;
546528
+ if (finalText.length === 0 || isSilentTurnMarker(finalText)) return;
545621
546529
  (guard.threadId === void 0 ? sendReplyFallback(guard.chatId, finalText, guard.contextOnly) : sendReplyFallback(guard.chatId, finalText, guard.contextOnly, false, void 0, guard.threadId)).then((sent) => {
545622
546530
  if (sent) this.showStatus(uiText("blunTui.telegram.fallbackDelivered"));
545623
546531
  });
@@ -546566,6 +547474,14 @@ var BlunTUI = class {
546566
547474
  mergeSteps: (state) => this.mergeAllTurnSteps(state)
546567
547475
  });
546568
547476
  }
547477
+ beginLocalContextMutation() {
547478
+ return this.sessionEventHandler.beginLocalContextMutation();
547479
+ }
547480
+ async refreshContextFromReplay(session, isCurrent) {
547481
+ return this.sessionReplay.refreshFromReplay(session, isCurrent, () => {
547482
+ this.clearTranscriptAndRedraw();
547483
+ }, this.historyLimit);
547484
+ }
546569
547485
  createTranscriptComponent(entry, state = this.state) {
546570
547486
  if (entry.compactionData !== void 0) {
546571
547487
  const data = entry.compactionData;
@@ -547550,13 +548466,13 @@ var BlunTUI = class {
547550
548466
  //#endregion
547551
548467
  //#region src/constant/update.ts
547552
548468
  var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
547553
- const fs$1 = __require("node:fs");
548469
+ const fs = __require("node:fs");
547554
548470
  const os$1 = __require("node:os");
547555
- const path$2 = __require("node:path");
548471
+ const path$1 = __require("node:path");
547556
548472
  const DEFAULT_MAX_BYTES = 1024 * 1024;
547557
548473
  const DEFAULT_RETAIN_BYTES = 512 * 1024;
547558
548474
  function runtimeExitLedgerPath(homeDir) {
547559
- return path$2.join(homeDir, "diagnostics", "runtime-exits.jsonl");
548475
+ return path$1.join(homeDir, "diagnostics", "runtime-exits.jsonl");
547560
548476
  }
547561
548477
  function sanitizeExitText(input, maxChars = 2048) {
547562
548478
  let value = String(input ?? "");
@@ -547565,7 +548481,7 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
547565
548481
  process.env.USERPROFILE,
547566
548482
  process.env.HOME
547567
548483
  ].filter((entry) => typeof entry === "string" && entry.length > 2));
547568
- for (const home of homes) for (const variant of [path$2.normalize(home), home.replaceAll("\\", "/")]) {
548484
+ for (const home of homes) for (const variant of [path$1.normalize(home), home.replaceAll("\\", "/")]) {
547569
548485
  const escaped = variant.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
547570
548486
  value = value.replace(new RegExp(escaped, process.platform === "win32" ? "giu" : "gu"), "$HOME");
547571
548487
  }
@@ -547604,7 +548520,7 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
547604
548520
  return record;
547605
548521
  }
547606
548522
  function directoryIdentity(directory) {
547607
- const stat = fs$1.lstatSync(directory, { bigint: true });
548523
+ const stat = fs.lstatSync(directory, { bigint: true });
547608
548524
  if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("Unsafe exit directory");
547609
548525
  return stat;
547610
548526
  }
@@ -547616,46 +548532,46 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
547616
548532
  return stat;
547617
548533
  }
547618
548534
  function trimLedger(descriptor, maxBytes, retainBytes, incomingBytes) {
547619
- const size = Number(regularLedger(fs$1.fstatSync(descriptor, { bigint: true })).size);
548535
+ const size = Number(regularLedger(fs.fstatSync(descriptor, { bigint: true })).size);
547620
548536
  if (!Number.isSafeInteger(size)) throw new Error("Invalid exit ledger size");
547621
548537
  if (size + incomingBytes <= maxBytes) return;
547622
548538
  const keepBytes = Math.max(0, Math.min(size, retainBytes, maxBytes - incomingBytes));
547623
548539
  const contents = Buffer.alloc(keepBytes);
547624
- const read = fs$1.readSync(descriptor, contents, 0, keepBytes, size - keepBytes);
548540
+ const read = fs.readSync(descriptor, contents, 0, keepBytes, size - keepBytes);
547625
548541
  const tail = contents.subarray(0, read);
547626
548542
  const lineStart = size > keepBytes ? tail.indexOf(10) + 1 : 0;
547627
- fs$1.ftruncateSync(descriptor, 0);
547628
- fs$1.writeFileSync(descriptor, lineStart > 0 || size === keepBytes ? tail.subarray(lineStart) : "");
548543
+ fs.ftruncateSync(descriptor, 0);
548544
+ fs.writeFileSync(descriptor, lineStart > 0 || size === keepBytes ? tail.subarray(lineStart) : "");
547629
548545
  }
547630
548546
  function recordRuntimeExit(input = {}) {
547631
548547
  let descriptor;
547632
548548
  let appendDescriptor;
547633
548549
  try {
547634
548550
  const homeDir = typeof input.homeDir === "string" ? input.homeDir.trim() : "";
547635
- if (!homeDir || !path$2.isAbsolute(homeDir)) return false;
547636
- fs$1.mkdirSync(homeDir, {
548551
+ if (!homeDir || !path$1.isAbsolute(homeDir)) return false;
548552
+ fs.mkdirSync(homeDir, {
547637
548553
  recursive: true,
547638
548554
  mode: 448
547639
548555
  });
547640
548556
  const homeIdentity = directoryIdentity(homeDir);
547641
548557
  const file = runtimeExitLedgerPath(homeDir);
547642
- const directory = path$2.dirname(file);
548558
+ const directory = path$1.dirname(file);
547643
548559
  try {
547644
- fs$1.mkdirSync(directory, { mode: 448 });
548560
+ fs.mkdirSync(directory, { mode: 448 });
547645
548561
  } catch (error) {
547646
548562
  if (error.code !== "EEXIST") throw error;
547647
548563
  }
547648
548564
  const directoryStat = directoryIdentity(directory);
547649
548565
  let before;
547650
548566
  try {
547651
- before = regularLedger(fs$1.lstatSync(file, { bigint: true }));
548567
+ before = regularLedger(fs.lstatSync(file, { bigint: true }));
547652
548568
  } catch (error) {
547653
548569
  if (error.code !== "ENOENT") throw error;
547654
548570
  }
547655
- const flags = fs$1.constants.O_RDWR | (fs$1.constants.O_NOFOLLOW ?? 0) | (fs$1.constants.O_NONBLOCK ?? 0) | (before ? 0 : fs$1.constants.O_CREAT | fs$1.constants.O_EXCL);
547656
- descriptor = fs$1.openSync(file, flags, 384);
547657
- const opened = regularLedger(fs$1.fstatSync(descriptor, { bigint: true }));
547658
- if (before && !sameIdentity(before, opened) || !sameIdentity(opened, regularLedger(fs$1.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
548571
+ const flags = fs.constants.O_RDWR | (fs.constants.O_NOFOLLOW ?? 0) | (fs.constants.O_NONBLOCK ?? 0) | (before ? 0 : fs.constants.O_CREAT | fs.constants.O_EXCL);
548572
+ descriptor = fs.openSync(file, flags, 384);
548573
+ const opened = regularLedger(fs.fstatSync(descriptor, { bigint: true }));
548574
+ if (before && !sameIdentity(before, opened) || !sameIdentity(opened, regularLedger(fs.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
547659
548575
  const maxBytes = Math.max(1024, Number.isInteger(input.maxBytes) ? input.maxBytes : DEFAULT_MAX_BYTES);
547660
548576
  const retainBytes = Math.max(0, Number.isInteger(input.retainBytes) ? input.retainBytes : DEFAULT_RETAIN_BYTES);
547661
548577
  const record = buildRuntimeExitRecord(input);
@@ -547678,21 +548594,21 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
547678
548594
  line = `${JSON.stringify(record)}\n`;
547679
548595
  }
547680
548596
  trimLedger(descriptor, maxBytes, retainBytes, Buffer.byteLength(line));
547681
- appendDescriptor = fs$1.openSync(file, fs$1.constants.O_WRONLY | fs$1.constants.O_APPEND | (fs$1.constants.O_NOFOLLOW ?? 0) | (fs$1.constants.O_NONBLOCK ?? 0));
547682
- if (!sameIdentity(opened, regularLedger(fs$1.fstatSync(appendDescriptor, { bigint: true }))) || !sameIdentity(opened, regularLedger(fs$1.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
547683
- fs$1.appendFileSync(appendDescriptor, line, { encoding: "utf8" });
548597
+ appendDescriptor = fs.openSync(file, fs.constants.O_WRONLY | fs.constants.O_APPEND | (fs.constants.O_NOFOLLOW ?? 0) | (fs.constants.O_NONBLOCK ?? 0));
548598
+ if (!sameIdentity(opened, regularLedger(fs.fstatSync(appendDescriptor, { bigint: true }))) || !sameIdentity(opened, regularLedger(fs.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
548599
+ fs.appendFileSync(appendDescriptor, line, { encoding: "utf8" });
547684
548600
  try {
547685
- fs$1.fchmodSync(descriptor, 384);
548601
+ fs.fchmodSync(descriptor, 384);
547686
548602
  } catch {}
547687
548603
  return true;
547688
548604
  } catch {
547689
548605
  return false;
547690
548606
  } finally {
547691
548607
  if (appendDescriptor !== void 0) try {
547692
- fs$1.closeSync(appendDescriptor);
548608
+ fs.closeSync(appendDescriptor);
547693
548609
  } catch {}
547694
548610
  if (descriptor !== void 0) try {
547695
- fs$1.closeSync(descriptor);
548611
+ fs.closeSync(descriptor);
547696
548612
  } catch {}
547697
548613
  }
547698
548614
  }