@google/gemini-cli-a2a-server 0.57.0 → 0.58.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -68743,11 +68743,38 @@ function getSupportedAudioMimeTypeForFile(filePath) {
68743
68743
  }
68744
68744
  return extensionMimeType;
68745
68745
  }
68746
+ function canonicalizeMacosPath(p2) {
68747
+ if (process.platform === "darwin") {
68748
+ if (p2 === "/var" || p2.startsWith("/var/")) {
68749
+ return "/private" + p2;
68750
+ }
68751
+ if (p2 === "/tmp" || p2.startsWith("/tmp/")) {
68752
+ return "/private" + p2;
68753
+ }
68754
+ if (p2 === "/etc" || p2.startsWith("/etc/")) {
68755
+ return "/private" + p2;
68756
+ }
68757
+ }
68758
+ return p2;
68759
+ }
68746
68760
  function isWithinRoot(pathToCheck, rootDirectory) {
68747
- const normalizedPathToCheck = path8.resolve(pathToCheck);
68748
- const normalizedRootDirectory = path8.resolve(rootDirectory);
68761
+ const normalizedPathToCheck = canonicalizeMacosPath(path8.resolve(pathToCheck));
68762
+ const normalizedRootDirectory = canonicalizeMacosPath(path8.resolve(rootDirectory));
68749
68763
  const rootWithSeparator = normalizedRootDirectory === path8.sep || normalizedRootDirectory.endsWith(path8.sep) ? normalizedRootDirectory : normalizedRootDirectory + path8.sep;
68750
- return normalizedPathToCheck === normalizedRootDirectory || normalizedPathToCheck.startsWith(rootWithSeparator);
68764
+ if (normalizedPathToCheck === normalizedRootDirectory || normalizedPathToCheck.startsWith(rootWithSeparator)) {
68765
+ return true;
68766
+ }
68767
+ if (process.platform === "darwin") {
68768
+ try {
68769
+ const realPathToCheck = resolveToRealPath(normalizedPathToCheck);
68770
+ const realRootDirectory = resolveToRealPath(normalizedRootDirectory);
68771
+ const realRootWithSeparator = realRootDirectory === path8.sep || realRootDirectory.endsWith(path8.sep) ? realRootDirectory : realRootDirectory + path8.sep;
68772
+ return realPathToCheck === realRootDirectory || realPathToCheck.startsWith(realRootWithSeparator);
68773
+ } catch {
68774
+ return false;
68775
+ }
68776
+ }
68777
+ return false;
68751
68778
  }
68752
68779
  async function isEmpty(filePath) {
68753
68780
  try {
@@ -69020,6 +69047,7 @@ var init_fileUtils = __esm({
69020
69047
  init_tool_error();
69021
69048
  init_ignorePatterns();
69022
69049
  init_debugLogger();
69050
+ init_paths();
69023
69051
  init_constants();
69024
69052
  requireModule = createModuleRequire(import.meta.url);
69025
69053
  SUPPORTED_AUDIO_MIME_TYPES_BY_EXTENSION = /* @__PURE__ */ new Map([
@@ -72854,6 +72882,54 @@ var init_baseProfile = __esm({
72854
72882
  (subpath "/dev")
72855
72883
  )
72856
72884
 
72885
+ ; Block Docker & container daemon UNIX domain sockets (read & write)
72886
+ (deny file-read* file-write*
72887
+ (literal "/var/run/docker.sock")
72888
+ (literal "/var/run/docker.sock.raw")
72889
+ (literal "/private/var/run/docker.sock")
72890
+ (literal "/private/var/run/docker.sock.raw")
72891
+ (subpath "/var/run/docker")
72892
+ (subpath "/private/var/run/docker")
72893
+ (subpath "/Users/Shared/.docker")
72894
+ (regex #"^/Users/[^/]+/\\.docker/run/")
72895
+ (regex #"^/Users/[^/]+/\\.docker/desktop/")
72896
+ (regex #"^/Users/[^/]+/\\.colima/")
72897
+ (regex #"^/Users/[^/]+/\\.orbstack/run/")
72898
+ (regex #"^/Users/[^/]+/\\.rd/")
72899
+ )
72900
+
72901
+ ; Block container CLI and daemon binaries from execution
72902
+ (deny process-exec
72903
+ (literal "/usr/local/bin/docker")
72904
+ (literal "/usr/local/bin/dockerd")
72905
+ (literal "/usr/local/bin/docker-compose")
72906
+ (literal "/usr/bin/docker")
72907
+ (literal "/opt/homebrew/bin/docker")
72908
+ (literal "/opt/homebrew/bin/dockerd")
72909
+ (literal "/opt/homebrew/bin/docker-compose")
72910
+ (literal "/opt/homebrew/bin/podman")
72911
+ (literal "/usr/local/bin/podman")
72912
+ (literal "/opt/homebrew/bin/colima")
72913
+ (literal "/usr/local/bin/colima")
72914
+ (literal "/opt/homebrew/bin/orb")
72915
+ (literal "/Applications/Docker.app/Contents/Resources/bin/docker")
72916
+ (subpath "/Applications/Docker.app/Contents/MacOS/")
72917
+ (subpath "/Applications/OrbStack.app/Contents/MacOS/")
72918
+ (subpath "/Applications/Rancher Desktop.app/Contents/MacOS/")
72919
+ )
72920
+
72921
+ ; Block com.docker.* and container manager Mach lookup / XPC services
72922
+ (deny mach-lookup
72923
+ (xpc-service-name-prefix "com.docker.")
72924
+ (global-name-prefix "com.docker.")
72925
+ (global-name-prefix "dev.kdrag0n.OrbStack")
72926
+ )
72927
+
72928
+ ; Block Docker POSIX Shared Memory
72929
+ (deny ipc-posix-shm*
72930
+ (ipc-posix-name-prefix "docker")
72931
+ (ipc-posix-name-prefix "com.docker.")
72932
+ )
72857
72933
  `;
72858
72934
  NETWORK_SEATBELT_PROFILE = `
72859
72935
  ; Network Access
@@ -148686,13 +148762,13 @@ var require_path = __commonJS({
148686
148762
  "node_modules/@protobufjs/path/index.js"(exports2) {
148687
148763
  "use strict";
148688
148764
  var path99 = exports2;
148689
- var isAbsolute7 = (
148765
+ var isAbsolute8 = (
148690
148766
  /**
148691
148767
  * Tests if the specified path is absolute.
148692
148768
  * @param {string} path Path to test
148693
148769
  * @returns {boolean} `true` if path is absolute
148694
148770
  */
148695
- path99.isAbsolute = function isAbsolute8(path100) {
148771
+ path99.isAbsolute = function isAbsolute9(path100) {
148696
148772
  return /^(?:\/|\w+:)/.test(path100);
148697
148773
  }
148698
148774
  );
@@ -148704,7 +148780,7 @@ var require_path = __commonJS({
148704
148780
  */
148705
148781
  path99.normalize = function normalize7(path100) {
148706
148782
  path100 = path100.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
148707
- var parts2 = path100.split("/"), absolute = isAbsolute7(path100), prefix = "";
148783
+ var parts2 = path100.split("/"), absolute = isAbsolute8(path100), prefix = "";
148708
148784
  if (absolute)
148709
148785
  prefix = parts2.shift() + "/";
148710
148786
  for (var i3 = 0; i3 < parts2.length; ) {
@@ -148726,7 +148802,7 @@ var require_path = __commonJS({
148726
148802
  path99.resolve = function resolve23(originPath, includePath, alreadyNormalized) {
148727
148803
  if (!alreadyNormalized)
148728
148804
  includePath = normalize6(includePath);
148729
- if (isAbsolute7(includePath))
148805
+ if (isAbsolute8(includePath))
148730
148806
  return includePath;
148731
148807
  if (!alreadyNormalized)
148732
148808
  originPath = normalize6(originPath);
@@ -220988,8 +221064,8 @@ var GIT_COMMIT_INFO, CLI_VERSION;
220988
221064
  var init_git_commit = __esm({
220989
221065
  "packages/core/dist/src/generated/git-commit.js"() {
220990
221066
  "use strict";
220991
- GIT_COMMIT_INFO = "1110ce8bc";
220992
- CLI_VERSION = "0.57.0";
221067
+ GIT_COMMIT_INFO = "812f7a2bc";
221068
+ CLI_VERSION = "0.58.0-preview.0";
220993
221069
  }
220994
221070
  });
220995
221071
 
@@ -336720,7 +336796,7 @@ function getVersion() {
336720
336796
  }
336721
336797
  versionPromise = (async () => {
336722
336798
  const pkgJson = await getPackageJson(__dirname4);
336723
- return "0.57.0";
336799
+ return "0.58.0-preview.0";
336724
336800
  })();
336725
336801
  return versionPromise;
336726
336802
  }
@@ -343683,7 +343759,18 @@ function getNormalizedRelativePath(projectRoot, filePath, isDirectory) {
343683
343759
  if (!isWithinRoot(absoluteFilePath, projectRoot)) {
343684
343760
  return null;
343685
343761
  }
343686
- const relativePath = path46.relative(projectRoot, absoluteFilePath);
343762
+ const canonicalRoot = canonicalizeMacosPath(projectRoot);
343763
+ const canonicalAbs = canonicalizeMacosPath(absoluteFilePath);
343764
+ let relativePath = path46.relative(canonicalRoot, canonicalAbs);
343765
+ if (process.platform === "darwin" && relativePath.startsWith("..")) {
343766
+ try {
343767
+ const crossPlatformRel = path46.relative(resolveToRealPath(projectRoot), resolveToRealPath(absoluteFilePath));
343768
+ if (!crossPlatformRel.startsWith("..")) {
343769
+ relativePath = crossPlatformRel;
343770
+ }
343771
+ } catch {
343772
+ }
343773
+ }
343687
343774
  let normalized = relativePath.replace(/\\/g, "/");
343688
343775
  if (isDirectory && !normalized.endsWith("/") && normalized !== "") {
343689
343776
  normalized += "/";
@@ -343700,6 +343787,7 @@ var init_ignorePathUtils = __esm({
343700
343787
  "packages/core/dist/src/utils/ignorePathUtils.js"() {
343701
343788
  "use strict";
343702
343789
  init_fileUtils();
343790
+ init_paths();
343703
343791
  }
343704
343792
  });
343705
343793
 
@@ -343963,6 +344051,7 @@ var init_fileDiscoveryService = __esm({
343963
344051
  init_constants4();
343964
344052
  init_errors2();
343965
344053
  init_debugLogger();
344054
+ init_paths();
343966
344055
  FileDiscoveryService = class {
343967
344056
  gitIgnoreFilter = null;
343968
344057
  geminiIgnoreFilter = null;
@@ -344018,14 +344107,18 @@ var init_fileDiscoveryService = __esm({
344018
344107
  }
344019
344108
  await Promise.all(dirEntries.map(async (entry) => {
344020
344109
  const fullPath = path50.join(currentDir, entry.name);
344110
+ const entryOptions = {
344111
+ ...options,
344112
+ isSymbolicLink: entry.isSymbolicLink()
344113
+ };
344021
344114
  if (entry.isDirectory()) {
344022
- if (this.shouldIgnoreDirectory(fullPath, options)) {
344115
+ if (this.shouldIgnoreDirectory(fullPath, entryOptions)) {
344023
344116
  ignoredPaths.push(fullPath);
344024
344117
  } else {
344025
344118
  await walk(fullPath);
344026
344119
  }
344027
344120
  } else {
344028
- if (this.shouldIgnoreFile(fullPath, options)) {
344121
+ if (this.shouldIgnoreFile(fullPath, entryOptions)) {
344029
344122
  ignoredPaths.push(fullPath);
344030
344123
  }
344031
344124
  }
@@ -344086,10 +344179,7 @@ var init_fileDiscoveryService = __esm({
344086
344179
  shouldIgnoreDirectory(dirPath, options = {}) {
344087
344180
  return this._shouldIgnore(dirPath, true, options);
344088
344181
  }
344089
- /**
344090
- * Internal unified check for paths.
344091
- */
344092
- _shouldIgnore(filePath, isDirectory, options = {}) {
344182
+ _checkIgnoreFilters(filePath, isDirectory, options = {}) {
344093
344183
  const { respectGitIgnore = this.defaultFilterFileOptions.respectGitIgnore, respectGeminiIgnore = this.defaultFilterFileOptions.respectGeminiIgnore } = options;
344094
344184
  if (respectGitIgnore && respectGeminiIgnore && this.combinedIgnoreFilter) {
344095
344185
  return this.combinedIgnoreFilter.isIgnored(filePath, isDirectory);
@@ -344105,6 +344195,31 @@ var init_fileDiscoveryService = __esm({
344105
344195
  }
344106
344196
  return false;
344107
344197
  }
344198
+ /**
344199
+ * Internal unified check for paths.
344200
+ */
344201
+ _shouldIgnore(filePath, isDirectory, options = {}) {
344202
+ if (this._checkIgnoreFilters(filePath, isDirectory, options)) {
344203
+ return true;
344204
+ }
344205
+ try {
344206
+ const absolutePath = path50.isAbsolute(filePath) ? filePath : path50.resolve(this.projectRoot, filePath);
344207
+ const isSymlink = options.isSymbolicLink ?? fs46.lstatSync(absolutePath, { throwIfNoEntry: false })?.isSymbolicLink() ?? false;
344208
+ if (isSymlink) {
344209
+ const realPath = resolveToRealPath(absolutePath);
344210
+ let targetIsDir = isDirectory;
344211
+ try {
344212
+ targetIsDir = fs46.statSync(realPath).isDirectory();
344213
+ } catch {
344214
+ }
344215
+ if (this._checkIgnoreFilters(realPath, targetIsDir, options)) {
344216
+ return true;
344217
+ }
344218
+ }
344219
+ } catch {
344220
+ }
344221
+ return false;
344222
+ }
344108
344223
  /**
344109
344224
  * Returns the list of ignore files being used (e.g. .geminiignore) excluding .gitignore.
344110
344225
  */
@@ -344278,7 +344393,7 @@ ${result2.llmContent}`;
344278
344393
  return "start_line cannot be greater than end_line";
344279
344394
  }
344280
344395
  const fileFilteringOptions = this.config.getFileFilteringOptions();
344281
- if (this.fileDiscoveryService.shouldIgnoreFile(resolvedPath, fileFilteringOptions)) {
344396
+ if (this.fileDiscoveryService.shouldIgnoreFile(sanitizedPath, fileFilteringOptions) || this.fileDiscoveryService.shouldIgnoreFile(resolvedPath, fileFilteringOptions)) {
344282
344397
  return `File path '${resolvedPath}' is ignored by configured ignore patterns.`;
344283
344398
  }
344284
344399
  return null;
@@ -358075,6 +358190,8 @@ ${truncated}`;
358075
358190
  }
358076
358191
  let spawnedPty;
358077
358192
  let cmdCleanup;
358193
+ let headlessTerminal;
358194
+ const disposables = [];
358078
358195
  try {
358079
358196
  const cols = shellExecutionConfig.terminalWidth ?? 80;
358080
358197
  const rows = shellExecutionConfig.terminalHeight ?? 30;
@@ -358100,17 +358217,18 @@ ${truncated}`;
358100
358217
  ...isWindowsPlatform ? { useConpty: true } : {}
358101
358218
  });
358102
358219
  spawnedPty = ptyProcess;
358103
- const ptyPid = Number(ptyProcess.pid);
358104
- const headlessTerminal = new Terminal({
358220
+ const pty = spawnedPty;
358221
+ const ptyPid = Number(pty.pid);
358222
+ headlessTerminal = new Terminal({
358105
358223
  allowProposedApi: true,
358106
358224
  cols,
358107
358225
  rows,
358108
358226
  scrollback: shellExecutionConfig.scrollback ?? SCROLLBACK_LIMIT
358109
358227
  });
358110
358228
  headlessTerminal.scrollToTop();
358229
+ const terminal = headlessTerminal;
358111
358230
  this.activePtys.set(ptyPid, {
358112
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
358113
- ptyProcess,
358231
+ ptyProcess: pty,
358114
358232
  headlessTerminal,
358115
358233
  maxSerializedLines: shellExecutionConfig.maxSerializedLines,
358116
358234
  command: shellExecutionConfig.originalCommand ?? commandToExecute,
@@ -358122,13 +358240,12 @@ ${truncated}`;
358122
358240
  if (!ExecutionLifecycleService.isActive(ptyPid)) {
358123
358241
  return;
358124
358242
  }
358125
- ptyProcess.write(input);
358243
+ pty.write(input);
358126
358244
  },
358127
358245
  kill: () => {
358128
358246
  killProcessGroup({
358129
358247
  pid: ptyPid,
358130
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
358131
- pty: ptyProcess
358248
+ pty
358132
358249
  }).catch(() => {
358133
358250
  });
358134
358251
  },
@@ -358142,11 +358259,11 @@ ${truncated}`;
358142
358259
  return false;
358143
358260
  }
358144
358261
  },
358145
- getBackgroundOutput: () => getFullBufferText(headlessTerminal),
358262
+ getBackgroundOutput: () => getFullBufferText(terminal),
358146
358263
  getSubscriptionSnapshot: () => {
358147
- const endLine = headlessTerminal.buffer.active.length;
358264
+ const endLine = terminal.buffer.active.length;
358148
358265
  const startLine = Math.max(0, endLine - (shellExecutionConfig.maxSerializedLines ?? 2e3));
358149
- const bufferData = serializeTerminalToObject(headlessTerminal, startLine, endLine);
358266
+ const bufferData = serializeTerminalToObject(terminal, startLine, endLine);
358150
358267
  return bufferData.length > 0 ? bufferData : void 0;
358151
358268
  },
358152
358269
  formatInjection: (output2, error3) => _ShellExecutionService.formatShellBackgroundCompletion(ptyPid, shellExecutionConfig.backgroundCompletionBehavior || "silent", output2, error3 ?? void 0),
@@ -358172,21 +358289,21 @@ ${truncated}`;
358172
358289
  }
358173
358290
  if (!shellExecutionConfig.disableDynamicLineTrimming) {
358174
358291
  if (!hasStartedOutput) {
358175
- const bufferText = getFullBufferText(headlessTerminal);
358292
+ const bufferText = getFullBufferText(terminal);
358176
358293
  if (bufferText.trim().length === 0) {
358177
358294
  return;
358178
358295
  }
358179
358296
  hasStartedOutput = true;
358180
358297
  }
358181
358298
  }
358182
- const buffer = headlessTerminal.buffer.active;
358299
+ const buffer = terminal.buffer.active;
358183
358300
  const endLine = buffer.length;
358184
358301
  const startLine = Math.max(0, endLine - (shellExecutionConfig.maxSerializedLines ?? 2e3));
358185
358302
  let newOutput;
358186
358303
  if (shellExecutionConfig.showColor) {
358187
- newOutput = serializeTerminalToObject(headlessTerminal, startLine, endLine);
358304
+ newOutput = serializeTerminalToObject(terminal, startLine, endLine);
358188
358305
  } else {
358189
- newOutput = (serializeTerminalToObject(headlessTerminal, startLine, endLine) || []).map((line) => line.map((token2) => {
358306
+ newOutput = (serializeTerminalToObject(terminal, startLine, endLine) || []).map((line) => line.map((token2) => {
358190
358307
  token2.fg = "";
358191
358308
  token2.bg = "";
358192
358309
  return token2;
@@ -358269,7 +358386,7 @@ ${truncated}`;
358269
358386
  _ShellExecutionService.syncBackgroundLog(ptyPid, decodedChunk);
358270
358387
  }
358271
358388
  isWriting = true;
358272
- headlessTerminal.write(decodedChunk, () => {
358389
+ terminal.write(decodedChunk, () => {
358273
358390
  render3();
358274
358391
  isWriting = false;
358275
358392
  resolveChunk();
@@ -358286,17 +358403,24 @@ ${truncated}`;
358286
358403
  }
358287
358404
  }));
358288
358405
  };
358289
- ptyProcess.onData((data) => {
358406
+ const dataListener = pty.onData((data) => {
358290
358407
  const bufferData = Buffer.from(data, "utf-8");
358291
358408
  handleOutput(bufferData);
358292
358409
  });
358293
- ptyProcess.onExit(({ exitCode, signal }) => {
358410
+ disposables.push(dataListener);
358411
+ const exitListener = pty.onExit(({ exitCode, signal }) => {
358294
358412
  exited = true;
358295
358413
  abortSignal.removeEventListener("abort", abortHandler);
358296
- _ShellExecutionService.destroyPtyProcess(ptyProcess);
358414
+ _ShellExecutionService.destroyPtyProcess(pty);
358297
358415
  const finalize = () => {
358298
358416
  render3(true);
358299
358417
  cmdCleanup?.();
358418
+ disposables.forEach((d) => {
358419
+ try {
358420
+ d.dispose();
358421
+ } catch {
358422
+ }
358423
+ });
358300
358424
  const event = {
358301
358425
  type: "exit",
358302
358426
  exitCode,
@@ -358312,12 +358436,12 @@ ${truncated}`;
358312
358436
  historyItem.endTime = Date.now();
358313
358437
  }
358314
358438
  onOutputEvent(event);
358315
- const endLine = headlessTerminal.buffer.active.length;
358439
+ const endLine = headlessTerminal ? headlessTerminal.buffer.active.length : 0;
358316
358440
  const startLine = Math.max(0, endLine - (shellExecutionConfig.maxSerializedLines ?? 2e3));
358317
- const ansiOutputSnapshot = serializeTerminalToObject(headlessTerminal, startLine, endLine);
358318
- const finalOutput = getFullBufferText(headlessTerminal);
358441
+ const ansiOutputSnapshot = headlessTerminal ? serializeTerminalToObject(headlessTerminal, startLine, endLine) : [];
358442
+ const finalOutput = headlessTerminal ? getFullBufferText(headlessTerminal) : "";
358319
358443
  try {
358320
- headlessTerminal.dispose();
358444
+ headlessTerminal?.dispose();
358321
358445
  } catch {
358322
358446
  }
358323
358447
  _ShellExecutionService.cleanupLogStream(ptyPid).then(() => {
@@ -358353,6 +358477,7 @@ ${truncated}`;
358353
358477
  finalize();
358354
358478
  });
358355
358479
  });
358480
+ disposables.push(exitListener);
358356
358481
  const abortHandler = async () => {
358357
358482
  if (ptyProcess.pid && !exited) {
358358
358483
  await killProcessGroup({
@@ -358372,10 +358497,23 @@ ${truncated}`;
358372
358497
  if (spawnedPty) {
358373
358498
  _ShellExecutionService.destroyPtyProcess(spawnedPty);
358374
358499
  }
358375
- if (error2?.message?.includes("posix_spawnp failed")) {
358500
+ if (headlessTerminal) {
358501
+ try {
358502
+ headlessTerminal.dispose();
358503
+ } catch {
358504
+ }
358505
+ }
358506
+ disposables.forEach((d) => {
358507
+ try {
358508
+ d.dispose();
358509
+ } catch {
358510
+ }
358511
+ });
358512
+ const isPtyCreationFailure = error2?.message?.includes("posix_spawnp failed") || error2?.message?.includes("ENXIO") || isNodeError(error2) && error2.code === "ENXIO" || error2?.message?.includes("Device not configured");
358513
+ if (isPtyCreationFailure) {
358376
358514
  onOutputEvent({
358377
358515
  type: "data",
358378
- chunk: "[GEMINI_CLI_WARNING] PTY execution failed, falling back to child_process. This may be due to sandbox restrictions.\n"
358516
+ chunk: "[GEMINI_CLI_WARNING] PTY execution failed, falling back to child_process. This may be due to terminal exhaustion or sandbox restrictions.\n"
358379
358517
  });
358380
358518
  throw e3;
358381
358519
  } else {
@@ -366425,13 +366563,13 @@ function stripToolCallIdPrefixes(contents) {
366425
366563
  };
366426
366564
  }
366427
366565
  }
366428
- const hasOtherKeys = Object.keys(newPart).some((key) => key !== "text" && key !== "thought" && key !== "callIndex" && newPart[key] !== void 0);
366566
+ const hasOtherKeys = Object.keys(newPart).some((key) => key !== "text" && key !== "thought" && key !== "callIndex");
366429
366567
  if (newPart.text !== void 0 && newPart.text === "" && hasOtherKeys) {
366430
366568
  delete newPart.text;
366431
366569
  }
366432
366570
  return newPart;
366433
366571
  }).filter((part) => {
366434
- const hasOtherKeys = Object.keys(part).some((key) => key !== "text" && key !== "thought" && key !== "callIndex" && part[key] !== void 0);
366572
+ const hasOtherKeys = Object.keys(part).some((key) => key !== "text" && key !== "thought" && key !== "callIndex");
366435
366573
  if (part.text !== void 0 && part.text === "" && !hasOtherKeys) {
366436
366574
  return false;
366437
366575
  }
@@ -439368,6 +439506,7 @@ var Task4 = class _Task {
439368
439506
  );
439369
439507
  }
439370
439508
  async *acceptUserMessage(requestContext, aborted2) {
439509
+ this.cancellationError = void 0;
439371
439510
  const userMessage = requestContext.userMessage;
439372
439511
  const llmParts = [];
439373
439512
  let anyConfirmationHandled = false;
@@ -439568,12 +439707,12 @@ var CoderAgentExecutor = class {
439568
439707
  }
439569
439708
  tasks = /* @__PURE__ */ new Map();
439570
439709
  // Track tasks with an active execution loop.
439571
- executingTasks = /* @__PURE__ */ new Set();
439710
+ executingTasks = /* @__PURE__ */ new Map();
439572
439711
  activeAbortControllers = /* @__PURE__ */ new Map();
439573
439712
  // Track tasks currently initializing to prevent race conditions.
439574
439713
  initializingTasks = /* @__PURE__ */ new Set();
439575
439714
  initializationPromises = /* @__PURE__ */ new Map();
439576
- // Track explicitly canceled task IDs to handle cancellation during initialization.
439715
+ // Track explicitly canceled abort controllers to handle cancellation during initialization.
439577
439716
  explicitlyCanceledTasks = /* @__PURE__ */ new Set();
439578
439717
  async getConfigWithEnv(agentSettings, taskId, isTrusted, workspaceRoot) {
439579
439718
  const settings = loadSettings(workspaceRoot, isTrusted);
@@ -439598,9 +439737,15 @@ var CoderAgentExecutor = class {
439598
439737
  return fn2(isTrusted, workspaceRoot);
439599
439738
  });
439600
439739
  }
439601
- cleanupAndEvictTask(taskId) {
439740
+ cleanupAndEvictTask(taskId, expectedWrapper) {
439602
439741
  const wrapper = this.tasks.get(taskId);
439603
439742
  if (wrapper) {
439743
+ if (expectedWrapper && wrapper !== expectedWrapper) {
439744
+ logger.info(
439745
+ `[CoderAgentExecutor] cleanupAndEvictTask: wrapper mismatch for task ${taskId}. Skipping eviction.`
439746
+ );
439747
+ return;
439748
+ }
439604
439749
  wrapper.task.dispose();
439605
439750
  this.tasks.delete(taskId);
439606
439751
  }
@@ -439707,11 +439852,11 @@ var CoderAgentExecutor = class {
439707
439852
  );
439708
439853
  const abortControllers = this.activeAbortControllers.get(taskId);
439709
439854
  if (abortControllers && abortControllers.size > 0) {
439710
- this.explicitlyCanceledTasks.add(taskId);
439711
439855
  logger.info(
439712
439856
  `[CoderAgentExecutor] Aborting ${abortControllers.size} active execution loop(s) for task ${taskId}.`
439713
439857
  );
439714
439858
  for (const controller of Array.from(abortControllers)) {
439859
+ this.explicitlyCanceledTasks.add(controller);
439715
439860
  controller.abort();
439716
439861
  }
439717
439862
  const wrapper2 = this.tasks.get(taskId);
@@ -439725,6 +439870,7 @@ var CoderAgentExecutor = class {
439725
439870
  void 0,
439726
439871
  true
439727
439872
  );
439873
+ this.cleanupAndEvictTask(taskId, wrapper2);
439728
439874
  try {
439729
439875
  await this.taskStore?.save(wrapper2.toSDKTask());
439730
439876
  logger.info(
@@ -439736,7 +439882,6 @@ var CoderAgentExecutor = class {
439736
439882
  saveError
439737
439883
  );
439738
439884
  }
439739
- this.cleanupAndEvictTask(taskId);
439740
439885
  }
439741
439886
  return;
439742
439887
  }
@@ -439812,9 +439957,9 @@ var CoderAgentExecutor = class {
439812
439957
  logger.info(
439813
439958
  `[CoderAgentExecutor] Task ${taskId} cancellation processed. Saving state.`
439814
439959
  );
439960
+ this.cleanupAndEvictTask(taskId, wrapper);
439815
439961
  await this.taskStore?.save(wrapper.toSDKTask());
439816
439962
  logger.info(`[CoderAgentExecutor] Task ${taskId} state CANCELED saved.`);
439817
- this.cleanupAndEvictTask(taskId);
439818
439963
  } catch (error2) {
439819
439964
  const errorMessage = error2 instanceof Error ? error2.message : "Unknown error";
439820
439965
  logger.error(
@@ -440028,16 +440173,16 @@ var CoderAgentExecutor = class {
440028
440173
  }
440029
440174
  const currentTask2 = wrapper.task;
440030
440175
  if (["canceled", "failed", "completed"].includes(currentTask2.taskState)) {
440031
- logger.warn(
440032
- `[CoderAgentExecutor] Attempted to execute task ${taskId} which is already in state ${currentTask2.taskState}. Ignoring.`
440176
+ logger.info(
440177
+ `[CoderAgentExecutor] Re-activating task ${taskId} from terminal state ${currentTask2.taskState}.`
440033
440178
  );
440034
- return;
440179
+ currentTask2.taskState = "submitted";
440035
440180
  }
440036
440181
  if (abortSignal.aborted) {
440037
440182
  logger.warn(
440038
440183
  `[CoderAgentExecutor] Task ${taskId} was aborted during initialization.`
440039
440184
  );
440040
- const isExplicitCancel = this.explicitlyCanceledTasks.has(taskId);
440185
+ const isExplicitCancel = this.explicitlyCanceledTasks.has(abortController);
440041
440186
  const finalState = isExplicitCancel ? "canceled" : "input-required";
440042
440187
  const message = isExplicitCancel ? "Task canceled by user request." : "Execution aborted by client.";
440043
440188
  currentTask2.setTaskStateAndPublishUpdate(
@@ -440056,11 +440201,12 @@ var CoderAgentExecutor = class {
440056
440201
  );
440057
440202
  }
440058
440203
  if (isExplicitCancel) {
440059
- this.cleanupAndEvictTask(taskId);
440204
+ this.cleanupAndEvictTask(taskId, wrapper);
440060
440205
  }
440061
440206
  return;
440062
440207
  }
440063
- if (this.executingTasks.has(taskId)) {
440208
+ const activeController = this.executingTasks.get(taskId);
440209
+ if (activeController && !activeController.signal.aborted) {
440064
440210
  logger.info(
440065
440211
  `[CoderAgentExecutor] Task ${taskId} has a pending execution. Processing message and yielding.`
440066
440212
  );
@@ -440087,7 +440233,7 @@ var CoderAgentExecutor = class {
440087
440233
  isPrimaryExecution = true;
440088
440234
  proceedToMainLoop = true;
440089
440235
  } finally {
440090
- this.explicitlyCanceledTasks.delete(taskId);
440236
+ this.explicitlyCanceledTasks.delete(abortController);
440091
440237
  if (!proceedToMainLoop) {
440092
440238
  const controllers = this.activeAbortControllers.get(taskId);
440093
440239
  if (controllers) {
@@ -440103,7 +440249,7 @@ var CoderAgentExecutor = class {
440103
440249
  logger.info(
440104
440250
  `[CoderAgentExecutor] Starting main execution for message ${userMessage.messageId} for task ${taskId}.`
440105
440251
  );
440106
- this.executingTasks.add(taskId);
440252
+ this.executingTasks.set(taskId, abortController);
440107
440253
  let agentTurnActive = true;
440108
440254
  logger.info(
440109
440255
  `[CoderAgentExecutor] Task ${taskId}: Processing user turn.`
@@ -440252,7 +440398,14 @@ var CoderAgentExecutor = class {
440252
440398
  this.activeAbortControllers.delete(taskId);
440253
440399
  }
440254
440400
  }
440255
- this.executingTasks.delete(taskId);
440401
+ if (this.executingTasks.get(taskId) === abortController) {
440402
+ this.executingTasks.delete(taskId);
440403
+ }
440404
+ if (["canceled", "failed", "completed"].includes(
440405
+ currentTask.taskState
440406
+ )) {
440407
+ this.cleanupAndEvictTask(taskId, wrapper);
440408
+ }
440256
440409
  logger.info(
440257
440410
  `[CoderAgentExecutor] Saving final state for task ${taskId}.`
440258
440411
  );
@@ -440265,11 +440418,6 @@ var CoderAgentExecutor = class {
440265
440418
  saveError
440266
440419
  );
440267
440420
  }
440268
- if (["canceled", "failed", "completed"].includes(
440269
- currentTask.taskState
440270
- )) {
440271
- this.cleanupAndEvictTask(taskId);
440272
- }
440273
440421
  }
440274
440422
  }
440275
440423
  } catch (error2) {
@@ -39,7 +39,11 @@ decision = "allow"
39
39
  priority = 15
40
40
  modes = ["autoEdit"]
41
41
 
42
- [rule.safety_checker]
42
+ [[safety_checker]]
43
+ toolName = "replace"
44
+ priority = 15
45
+ modes = ["autoEdit"]
46
+ [safety_checker.checker]
43
47
  type = "in-process"
44
48
  name = "allowed-path"
45
49
  required_context = ["environment"]
@@ -68,7 +72,11 @@ decision = "allow"
68
72
  priority = 15
69
73
  modes = ["autoEdit"]
70
74
 
71
- [rule.safety_checker]
75
+ [[safety_checker]]
76
+ toolName = "write_file"
77
+ priority = 15
78
+ modes = ["autoEdit"]
79
+ [safety_checker.checker]
72
80
  type = "in-process"
73
81
  name = "allowed-path"
74
82
  required_context = ["environment"]