@axiom-lattice/core 2.1.84 → 2.1.86

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/dist/index.mjs CHANGED
@@ -2468,7 +2468,7 @@ var InMemoryBindingStore = class {
2468
2468
  * @returns Array of matching {@link Binding} objects
2469
2469
  */
2470
2470
  async list(params) {
2471
- let results = Array.from(this.bindings.values()).filter((b) => {
2471
+ const results = Array.from(this.bindings.values()).filter((b) => {
2472
2472
  if (b.tenantId !== params.tenantId) return false;
2473
2473
  if (params.channel && b.channel !== params.channel) return false;
2474
2474
  if (params.agentId && b.agentId !== params.agentId) return false;
@@ -5717,9 +5717,9 @@ var VolumeFilesystem = class {
5717
5717
  this.client = client;
5718
5718
  this.mountPrefix = mountPrefix;
5719
5719
  }
5720
- async lsInfo(path3) {
5721
- console.log(`[VolumeFilesystem.lsInfo] path=${path3} mountPrefix=${this.mountPrefix}`);
5722
- const entries = await this.client.list(path3);
5720
+ async lsInfo(path5) {
5721
+ console.log(`[VolumeFilesystem.lsInfo] path=${path5} mountPrefix=${this.mountPrefix}`);
5722
+ const entries = await this.client.list(path5);
5723
5723
  console.log(`[VolumeFilesystem.lsInfo] got ${entries.length} entries`);
5724
5724
  const prefix = this.mountPrefix.endsWith("/") ? this.mountPrefix : this.mountPrefix + "/";
5725
5725
  return entries.map((entry) => ({
@@ -8032,8 +8032,8 @@ function truncateIfTooLong(result) {
8032
8032
  }
8033
8033
  return result;
8034
8034
  }
8035
- function validatePath(path3) {
8036
- const pathStr = path3 || "/";
8035
+ function validatePath(path5) {
8036
+ const pathStr = path5 || "/";
8037
8037
  if (!pathStr || pathStr.trim() === "") {
8038
8038
  throw new Error("Path cannot be empty");
8039
8039
  }
@@ -8050,10 +8050,10 @@ function validatePath(path3) {
8050
8050
  }
8051
8051
  return normalized;
8052
8052
  }
8053
- function globSearchFiles(files, pattern, path3 = "/") {
8053
+ function globSearchFiles(files, pattern, path5 = "/") {
8054
8054
  let normalizedPath;
8055
8055
  try {
8056
- normalizedPath = validatePath(path3);
8056
+ normalizedPath = validatePath(path5);
8057
8057
  } catch {
8058
8058
  return "No files found";
8059
8059
  }
@@ -8105,7 +8105,7 @@ function formatGrepResults(results, outputMode) {
8105
8105
  }
8106
8106
  return lines.join("\n");
8107
8107
  }
8108
- function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode = "files_with_matches") {
8108
+ function grepSearchFiles(files, pattern, path5 = null, glob = null, outputMode = "files_with_matches") {
8109
8109
  let regex;
8110
8110
  try {
8111
8111
  regex = new RegExp(pattern);
@@ -8114,7 +8114,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
8114
8114
  }
8115
8115
  let normalizedPath;
8116
8116
  try {
8117
- normalizedPath = validatePath(path3);
8117
+ normalizedPath = validatePath(path5);
8118
8118
  } catch {
8119
8119
  return "No matches found";
8120
8120
  }
@@ -8146,7 +8146,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
8146
8146
  }
8147
8147
  return formatGrepResults(results, outputMode);
8148
8148
  }
8149
- function grepMatchesFromFiles(files, pattern, path3 = null, glob = null) {
8149
+ function grepMatchesFromFiles(files, pattern, path5 = null, glob = null) {
8150
8150
  let regex;
8151
8151
  try {
8152
8152
  regex = new RegExp(pattern);
@@ -8155,7 +8155,7 @@ function grepMatchesFromFiles(files, pattern, path3 = null, glob = null) {
8155
8155
  }
8156
8156
  let normalizedPath;
8157
8157
  try {
8158
- normalizedPath = validatePath(path3);
8158
+ normalizedPath = validatePath(path5);
8159
8159
  } catch {
8160
8160
  return [];
8161
8161
  }
@@ -8216,11 +8216,11 @@ var StateBackend = class {
8216
8216
  * @returns List of FileInfo objects for files and directories directly in the directory.
8217
8217
  * Directories have a trailing / in their path and is_dir=true.
8218
8218
  */
8219
- lsInfo(path3) {
8219
+ lsInfo(path5) {
8220
8220
  const files = this.getFiles();
8221
8221
  const infos = [];
8222
8222
  const subdirs = /* @__PURE__ */ new Set();
8223
- const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
8223
+ const normalizedPath = path5.endsWith("/") ? path5 : path5 + "/";
8224
8224
  for (const [k, fd] of Object.entries(files)) {
8225
8225
  if (!k.startsWith(normalizedPath)) {
8226
8226
  continue;
@@ -8326,16 +8326,16 @@ var StateBackend = class {
8326
8326
  /**
8327
8327
  * Structured search results or error string for invalid input.
8328
8328
  */
8329
- grepRaw(pattern, path3 = "/", glob = null) {
8329
+ grepRaw(pattern, path5 = "/", glob = null) {
8330
8330
  const files = this.getFiles();
8331
- return grepMatchesFromFiles(files, pattern, path3, glob);
8331
+ return grepMatchesFromFiles(files, pattern, path5, glob);
8332
8332
  }
8333
8333
  /**
8334
8334
  * Structured glob matching returning FileInfo objects.
8335
8335
  */
8336
- globInfo(pattern, path3 = "/") {
8336
+ globInfo(pattern, path5 = "/") {
8337
8337
  const files = this.getFiles();
8338
- const result = globSearchFiles(files, pattern, path3);
8338
+ const result = globSearchFiles(files, pattern, path5);
8339
8339
  if (result === "No files found") {
8340
8340
  return [];
8341
8341
  }
@@ -8429,10 +8429,10 @@ function createLsTool(backend, options) {
8429
8429
  ...runConfig
8430
8430
  };
8431
8431
  const resolvedBackend = await getBackend(backend, stateAndStore);
8432
- const path3 = input.path || "/";
8433
- const infos = await resolvedBackend.lsInfo(path3);
8432
+ const path5 = input.path || "/";
8433
+ const infos = await resolvedBackend.lsInfo(path5);
8434
8434
  if (infos.length === 0) {
8435
- return `No files found in ${path3}`;
8435
+ return `No files found in ${path5}`;
8436
8436
  }
8437
8437
  const lines = [];
8438
8438
  for (const info of infos) {
@@ -8575,8 +8575,8 @@ function createGlobTool(backend, options) {
8575
8575
  ...runConfig
8576
8576
  };
8577
8577
  const resolvedBackend = await getBackend(backend, stateAndStore);
8578
- const { pattern, path: path3 = "/" } = input;
8579
- const infos = await resolvedBackend.globInfo(pattern, path3);
8578
+ const { pattern, path: path5 = "/" } = input;
8579
+ const infos = await resolvedBackend.globInfo(pattern, path5);
8580
8580
  if (infos.length === 0) {
8581
8581
  return `No files found matching pattern '${pattern}'`;
8582
8582
  }
@@ -8603,8 +8603,8 @@ function createGrepTool(backend, options) {
8603
8603
  ...runConfig
8604
8604
  };
8605
8605
  const resolvedBackend = await getBackend(backend, stateAndStore);
8606
- const { pattern, path: path3 = "/", glob = null } = input;
8607
- const result = await resolvedBackend.grepRaw(pattern, path3, glob);
8606
+ const { pattern, path: path5 = "/", glob = null } = input;
8607
+ const result = await resolvedBackend.grepRaw(pattern, path5, glob);
8608
8608
  if (typeof result === "string") {
8609
8609
  return result;
8610
8610
  }
@@ -12721,8 +12721,7 @@ var Agent = class {
12721
12721
  if (signal?.aborted) {
12722
12722
  throw new Error("Agent execution was aborted");
12723
12723
  }
12724
- let result;
12725
- result = await runnable_agent.invoke(
12724
+ const result = await runnable_agent.invoke(
12726
12725
  inputMessage.command ? new Command2(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
12727
12726
  {
12728
12727
  context: { runConfig },
@@ -13081,7 +13080,7 @@ var Agent = class {
13081
13080
  includeTypes: ["ai", "human", "tool"]
13082
13081
  //["human", "ai", "tool"],
13083
13082
  });
13084
- let messagesArray = filteredMessages.map((message) => ({
13083
+ const messagesArray = filteredMessages.map((message) => ({
13085
13084
  id: message.id,
13086
13085
  role: message.getType(),
13087
13086
  content: message.content,
@@ -14178,12 +14177,12 @@ var AgentManager = class _AgentManager {
14178
14177
  return _AgentManager.instance;
14179
14178
  }
14180
14179
  callAgentInQueue(queue, return_agent_state) {
14181
- return new Promise((resolve3, reject) => {
14180
+ return new Promise((resolve4, reject) => {
14182
14181
  const callback_event = `${queue.assistant_id}::${queue.thread_id}`;
14183
14182
  if (return_agent_state) {
14184
14183
  event_bus_default.subscribeOnce(callback_event, (data) => {
14185
14184
  if (data.success) {
14186
- resolve3(data.state);
14185
+ resolve4(data.state);
14187
14186
  } else {
14188
14187
  reject(data.error);
14189
14188
  }
@@ -14198,7 +14197,7 @@ var AgentManager = class _AgentManager {
14198
14197
  },
14199
14198
  true
14200
14199
  );
14201
- !return_agent_state && resolve3({ callback_event_id: callback_event, success: true });
14200
+ !return_agent_state && resolve4({ callback_event_id: callback_event, success: true });
14202
14201
  } catch (error) {
14203
14202
  !return_agent_state && reject({
14204
14203
  callback_event_id: callback_event,
@@ -15097,13 +15096,13 @@ var StoreBackend = class {
15097
15096
  * @returns List of FileInfo objects for files and directories directly in the directory.
15098
15097
  * Directories have a trailing / in their path and is_dir=true.
15099
15098
  */
15100
- async lsInfo(path3) {
15099
+ async lsInfo(path5) {
15101
15100
  const store = this.getStore();
15102
15101
  const namespace = this.getNamespace();
15103
15102
  const items = await this.searchStorePaginated(store, namespace);
15104
15103
  const infos = [];
15105
15104
  const subdirs = /* @__PURE__ */ new Set();
15106
- const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
15105
+ const normalizedPath = path5.endsWith("/") ? path5 : path5 + "/";
15107
15106
  for (const item of items) {
15108
15107
  const itemKey = String(item.key);
15109
15108
  if (!itemKey.startsWith(normalizedPath)) {
@@ -15221,7 +15220,7 @@ var StoreBackend = class {
15221
15220
  /**
15222
15221
  * Structured search results or error string for invalid input.
15223
15222
  */
15224
- async grepRaw(pattern, path3 = "/", glob = null) {
15223
+ async grepRaw(pattern, path5 = "/", glob = null) {
15225
15224
  const store = this.getStore();
15226
15225
  const namespace = this.getNamespace();
15227
15226
  const items = await this.searchStorePaginated(store, namespace);
@@ -15233,12 +15232,12 @@ var StoreBackend = class {
15233
15232
  continue;
15234
15233
  }
15235
15234
  }
15236
- return grepMatchesFromFiles(files, pattern, path3, glob);
15235
+ return grepMatchesFromFiles(files, pattern, path5, glob);
15237
15236
  }
15238
15237
  /**
15239
15238
  * Structured glob matching returning FileInfo objects.
15240
15239
  */
15241
- async globInfo(pattern, path3 = "/") {
15240
+ async globInfo(pattern, path5 = "/") {
15242
15241
  const store = this.getStore();
15243
15242
  const namespace = this.getNamespace();
15244
15243
  const items = await this.searchStorePaginated(store, namespace);
@@ -15250,7 +15249,7 @@ var StoreBackend = class {
15250
15249
  continue;
15251
15250
  }
15252
15251
  }
15253
- const result = globSearchFiles(files, pattern, path3);
15252
+ const result = globSearchFiles(files, pattern, path5);
15254
15253
  if (result === "No files found") {
15255
15254
  return [];
15256
15255
  }
@@ -15335,8 +15334,8 @@ var FilesystemBackend = class {
15335
15334
  async lsInfo(dirPath) {
15336
15335
  try {
15337
15336
  const resolvedPath = this.resolvePath(dirPath);
15338
- const stat3 = await fs2.stat(resolvedPath);
15339
- if (!stat3.isDirectory()) {
15337
+ const stat4 = await fs2.stat(resolvedPath);
15338
+ if (!stat4.isDirectory()) {
15340
15339
  return [];
15341
15340
  }
15342
15341
  const entries = await fs2.readdir(resolvedPath, { withFileTypes: true });
@@ -15415,8 +15414,8 @@ var FilesystemBackend = class {
15415
15414
  const resolvedPath = this.resolvePath(filePath);
15416
15415
  let content;
15417
15416
  if (SUPPORTS_NOFOLLOW) {
15418
- const stat3 = await fs2.stat(resolvedPath);
15419
- if (!stat3.isFile()) {
15417
+ const stat4 = await fs2.stat(resolvedPath);
15418
+ if (!stat4.isFile()) {
15420
15419
  return `Error: File '${filePath}' not found`;
15421
15420
  }
15422
15421
  const fd = await fs2.open(
@@ -15429,11 +15428,11 @@ var FilesystemBackend = class {
15429
15428
  await fd.close();
15430
15429
  }
15431
15430
  } else {
15432
- const stat3 = await fs2.lstat(resolvedPath);
15433
- if (stat3.isSymbolicLink()) {
15431
+ const stat4 = await fs2.lstat(resolvedPath);
15432
+ if (stat4.isSymbolicLink()) {
15434
15433
  return `Error: Symlinks are not allowed: ${filePath}`;
15435
15434
  }
15436
- if (!stat3.isFile()) {
15435
+ if (!stat4.isFile()) {
15437
15436
  return `Error: File '${filePath}' not found`;
15438
15437
  }
15439
15438
  content = await fs2.readFile(resolvedPath, "utf-8");
@@ -15463,10 +15462,10 @@ var FilesystemBackend = class {
15463
15462
  async readRaw(filePath) {
15464
15463
  const resolvedPath = this.resolvePath(filePath);
15465
15464
  let content;
15466
- let stat3;
15465
+ let stat4;
15467
15466
  if (SUPPORTS_NOFOLLOW) {
15468
- stat3 = await fs2.stat(resolvedPath);
15469
- if (!stat3.isFile()) throw new Error(`File '${filePath}' not found`);
15467
+ stat4 = await fs2.stat(resolvedPath);
15468
+ if (!stat4.isFile()) throw new Error(`File '${filePath}' not found`);
15470
15469
  const fd = await fs2.open(
15471
15470
  resolvedPath,
15472
15471
  fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW
@@ -15477,17 +15476,17 @@ var FilesystemBackend = class {
15477
15476
  await fd.close();
15478
15477
  }
15479
15478
  } else {
15480
- stat3 = await fs2.lstat(resolvedPath);
15481
- if (stat3.isSymbolicLink()) {
15479
+ stat4 = await fs2.lstat(resolvedPath);
15480
+ if (stat4.isSymbolicLink()) {
15482
15481
  throw new Error(`Symlinks are not allowed: ${filePath}`);
15483
15482
  }
15484
- if (!stat3.isFile()) throw new Error(`File '${filePath}' not found`);
15483
+ if (!stat4.isFile()) throw new Error(`File '${filePath}' not found`);
15485
15484
  content = await fs2.readFile(resolvedPath, "utf-8");
15486
15485
  }
15487
15486
  return {
15488
15487
  content: content.split("\n"),
15489
- created_at: stat3.ctime.toISOString(),
15490
- modified_at: stat3.mtime.toISOString()
15488
+ created_at: stat4.ctime.toISOString(),
15489
+ modified_at: stat4.mtime.toISOString()
15491
15490
  };
15492
15491
  }
15493
15492
  /**
@@ -15498,8 +15497,8 @@ var FilesystemBackend = class {
15498
15497
  try {
15499
15498
  const resolvedPath = this.resolvePath(filePath);
15500
15499
  try {
15501
- const stat3 = await fs2.lstat(resolvedPath);
15502
- if (stat3.isSymbolicLink()) {
15500
+ const stat4 = await fs2.lstat(resolvedPath);
15501
+ if (stat4.isSymbolicLink()) {
15503
15502
  return {
15504
15503
  error: `Cannot write to ${filePath} because it is a symlink. Symlinks are not allowed.`
15505
15504
  };
@@ -15535,8 +15534,8 @@ var FilesystemBackend = class {
15535
15534
  const resolvedPath = this.resolvePath(filePath);
15536
15535
  let content;
15537
15536
  if (SUPPORTS_NOFOLLOW) {
15538
- const stat3 = await fs2.stat(resolvedPath);
15539
- if (!stat3.isFile()) {
15537
+ const stat4 = await fs2.stat(resolvedPath);
15538
+ if (!stat4.isFile()) {
15540
15539
  return { error: `Error: File '${filePath}' not found` };
15541
15540
  }
15542
15541
  const fd = await fs2.open(
@@ -15549,11 +15548,11 @@ var FilesystemBackend = class {
15549
15548
  await fd.close();
15550
15549
  }
15551
15550
  } else {
15552
- const stat3 = await fs2.lstat(resolvedPath);
15553
- if (stat3.isSymbolicLink()) {
15551
+ const stat4 = await fs2.lstat(resolvedPath);
15552
+ if (stat4.isSymbolicLink()) {
15554
15553
  return { error: `Error: Symlinks are not allowed: ${filePath}` };
15555
15554
  }
15556
- if (!stat3.isFile()) {
15555
+ if (!stat4.isFile()) {
15557
15556
  return { error: `Error: File '${filePath}' not found` };
15558
15557
  }
15559
15558
  content = await fs2.readFile(resolvedPath, "utf-8");
@@ -15621,7 +15620,7 @@ var FilesystemBackend = class {
15621
15620
  * Returns null if ripgrep is not available or fails.
15622
15621
  */
15623
15622
  async ripgrepSearch(pattern, baseFull, includeGlob) {
15624
- return new Promise((resolve3) => {
15623
+ return new Promise((resolve4) => {
15625
15624
  const args = ["--json"];
15626
15625
  if (includeGlob) {
15627
15626
  args.push("--glob", includeGlob);
@@ -15635,7 +15634,7 @@ var FilesystemBackend = class {
15635
15634
  });
15636
15635
  proc.on("close", (code) => {
15637
15636
  if (code !== 0 && code !== 1) {
15638
- resolve3(null);
15637
+ resolve4(null);
15639
15638
  return;
15640
15639
  }
15641
15640
  for (const line of output.split("\n")) {
@@ -15671,10 +15670,10 @@ var FilesystemBackend = class {
15671
15670
  continue;
15672
15671
  }
15673
15672
  }
15674
- resolve3(results);
15673
+ resolve4(results);
15675
15674
  });
15676
15675
  proc.on("error", () => {
15677
- resolve3(null);
15676
+ resolve4(null);
15678
15677
  });
15679
15678
  });
15680
15679
  }
@@ -15689,8 +15688,8 @@ var FilesystemBackend = class {
15689
15688
  return {};
15690
15689
  }
15691
15690
  const results = {};
15692
- const stat3 = await fs2.stat(baseFull);
15693
- const root = stat3.isDirectory() ? baseFull : path2.dirname(baseFull);
15691
+ const stat4 = await fs2.stat(baseFull);
15692
+ const root = stat4.isDirectory() ? baseFull : path2.dirname(baseFull);
15694
15693
  const files = await fg("**/*", {
15695
15694
  cwd: root,
15696
15695
  absolute: true,
@@ -15702,8 +15701,8 @@ var FilesystemBackend = class {
15702
15701
  if (includeGlob && !micromatch2.isMatch(path2.basename(fp), includeGlob)) {
15703
15702
  continue;
15704
15703
  }
15705
- const stat4 = await fs2.stat(fp);
15706
- if (stat4.size > this.maxFileSizeBytes) {
15704
+ const stat5 = await fs2.stat(fp);
15705
+ if (stat5.size > this.maxFileSizeBytes) {
15707
15706
  continue;
15708
15707
  }
15709
15708
  const content = await fs2.readFile(fp, "utf-8");
@@ -15745,8 +15744,8 @@ var FilesystemBackend = class {
15745
15744
  }
15746
15745
  const resolvedSearchPath = searchPath === "/" ? this.cwd : this.resolvePath(searchPath);
15747
15746
  try {
15748
- const stat3 = await fs2.stat(resolvedSearchPath);
15749
- if (!stat3.isDirectory()) {
15747
+ const stat4 = await fs2.stat(resolvedSearchPath);
15748
+ if (!stat4.isDirectory()) {
15750
15749
  return [];
15751
15750
  }
15752
15751
  } catch {
@@ -15762,15 +15761,15 @@ var FilesystemBackend = class {
15762
15761
  });
15763
15762
  for (const matchedPath of matches) {
15764
15763
  try {
15765
- const stat3 = await fs2.stat(matchedPath);
15766
- if (!stat3.isFile()) continue;
15764
+ const stat4 = await fs2.stat(matchedPath);
15765
+ if (!stat4.isFile()) continue;
15767
15766
  const normalizedPath = matchedPath.split("/").join(path2.sep);
15768
15767
  if (!this.virtualMode) {
15769
15768
  results.push({
15770
15769
  path: normalizedPath,
15771
15770
  is_dir: false,
15772
- size: stat3.size,
15773
- modified_at: stat3.mtime.toISOString()
15771
+ size: stat4.size,
15772
+ modified_at: stat4.mtime.toISOString()
15774
15773
  });
15775
15774
  } else {
15776
15775
  const cwdStr = this.cwd.endsWith(path2.sep) ? this.cwd : this.cwd + path2.sep;
@@ -15787,8 +15786,8 @@ var FilesystemBackend = class {
15787
15786
  results.push({
15788
15787
  path: virt,
15789
15788
  is_dir: false,
15790
- size: stat3.size,
15791
- modified_at: stat3.mtime.toISOString()
15789
+ size: stat4.size,
15790
+ modified_at: stat4.mtime.toISOString()
15792
15791
  });
15793
15792
  }
15794
15793
  } catch {
@@ -15835,10 +15834,10 @@ var CompositeBackend = class {
15835
15834
  * @returns List of FileInfo objects with route prefixes added, for files and directories
15836
15835
  * directly in the directory. Directories have a trailing / in their path and is_dir=true.
15837
15836
  */
15838
- async lsInfo(path3) {
15837
+ async lsInfo(path5) {
15839
15838
  for (const [routePrefix, backend] of this.sortedRoutes) {
15840
- if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
15841
- const suffix = path3.substring(routePrefix.length);
15839
+ if (path5.startsWith(routePrefix.replace(/\/$/, ""))) {
15840
+ const suffix = path5.substring(routePrefix.length);
15842
15841
  const searchPath = suffix ? "/" + suffix : "/";
15843
15842
  const infos = await backend.lsInfo(searchPath);
15844
15843
  const prefixed = [];
@@ -15851,9 +15850,9 @@ var CompositeBackend = class {
15851
15850
  return prefixed;
15852
15851
  }
15853
15852
  }
15854
- if (path3 === "/") {
15853
+ if (path5 === "/") {
15855
15854
  const results = [];
15856
- const defaultInfos = await this.default.lsInfo(path3);
15855
+ const defaultInfos = await this.default.lsInfo(path5);
15857
15856
  results.push(...defaultInfos);
15858
15857
  for (const [routePrefix] of this.sortedRoutes) {
15859
15858
  results.push({
@@ -15866,7 +15865,7 @@ var CompositeBackend = class {
15866
15865
  results.sort((a, b) => a.path.localeCompare(b.path));
15867
15866
  return results;
15868
15867
  }
15869
- return await this.default.lsInfo(path3);
15868
+ return await this.default.lsInfo(path5);
15870
15869
  }
15871
15870
  /**
15872
15871
  * Read file content, routing to appropriate backend.
@@ -15893,10 +15892,10 @@ var CompositeBackend = class {
15893
15892
  /**
15894
15893
  * Structured search results or error string for invalid input.
15895
15894
  */
15896
- async grepRaw(pattern, path3 = "/", glob = null) {
15895
+ async grepRaw(pattern, path5 = "/", glob = null) {
15897
15896
  for (const [routePrefix, backend] of this.sortedRoutes) {
15898
- if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
15899
- const searchPath = path3.substring(routePrefix.length - 1);
15897
+ if (path5.startsWith(routePrefix.replace(/\/$/, ""))) {
15898
+ const searchPath = path5.substring(routePrefix.length - 1);
15900
15899
  const raw = await backend.grepRaw(pattern, searchPath || "/", glob);
15901
15900
  if (typeof raw === "string") {
15902
15901
  return raw;
@@ -15908,7 +15907,7 @@ var CompositeBackend = class {
15908
15907
  }
15909
15908
  }
15910
15909
  const allMatches = [];
15911
- const rawDefault = await this.default.grepRaw(pattern, path3, glob);
15910
+ const rawDefault = await this.default.grepRaw(pattern, path5, glob);
15912
15911
  if (typeof rawDefault === "string") {
15913
15912
  return rawDefault;
15914
15913
  }
@@ -15930,11 +15929,11 @@ var CompositeBackend = class {
15930
15929
  /**
15931
15930
  * Structured glob matching returning FileInfo objects.
15932
15931
  */
15933
- async globInfo(pattern, path3 = "/") {
15932
+ async globInfo(pattern, path5 = "/") {
15934
15933
  const results = [];
15935
15934
  for (const [routePrefix, backend] of this.sortedRoutes) {
15936
- if (path3.startsWith(routePrefix.replace(/\/$/, ""))) {
15937
- const searchPath = path3.substring(routePrefix.length - 1);
15935
+ if (path5.startsWith(routePrefix.replace(/\/$/, ""))) {
15936
+ const searchPath = path5.substring(routePrefix.length - 1);
15938
15937
  const infos = await backend.globInfo(pattern, searchPath || "/");
15939
15938
  return infos.map((fi) => ({
15940
15939
  ...fi,
@@ -15942,7 +15941,7 @@ var CompositeBackend = class {
15942
15941
  }));
15943
15942
  }
15944
15943
  }
15945
- const defaultInfos = await this.default.globInfo(pattern, path3);
15944
+ const defaultInfos = await this.default.globInfo(pattern, path5);
15946
15945
  results.push(...defaultInfos);
15947
15946
  for (const [routePrefix, backend] of Object.entries(this.routes)) {
15948
15947
  const infos = await backend.globInfo(pattern, "/");
@@ -15990,11 +15989,11 @@ var MemoryBackend = class {
15990
15989
  getFiles() {
15991
15990
  return Object.fromEntries(this.files);
15992
15991
  }
15993
- lsInfo(path3) {
15992
+ lsInfo(path5) {
15994
15993
  const files = this.getFiles();
15995
15994
  const infos = [];
15996
15995
  const subdirs = /* @__PURE__ */ new Set();
15997
- const normalizedPath = path3.endsWith("/") ? path3 : path3 + "/";
15996
+ const normalizedPath = path5.endsWith("/") ? path5 : path5 + "/";
15998
15997
  for (const [k, fd] of Object.entries(files)) {
15999
15998
  if (!k.startsWith(normalizedPath)) {
16000
15999
  continue;
@@ -16069,13 +16068,13 @@ var MemoryBackend = class {
16069
16068
  this.files.set(filePath, newFileData);
16070
16069
  return { path: filePath, filesUpdate: null, occurrences };
16071
16070
  }
16072
- grepRaw(pattern, path3 = "/", glob = null) {
16071
+ grepRaw(pattern, path5 = "/", glob = null) {
16073
16072
  const files = this.getFiles();
16074
- return grepMatchesFromFiles(files, pattern, path3, glob);
16073
+ return grepMatchesFromFiles(files, pattern, path5, glob);
16075
16074
  }
16076
- globInfo(pattern, path3 = "/") {
16075
+ globInfo(pattern, path5 = "/") {
16077
16076
  const files = this.getFiles();
16078
- const result = globSearchFiles(files, pattern, path3);
16077
+ const result = globSearchFiles(files, pattern, path5);
16079
16078
  if (result === "No files found") {
16080
16079
  return [];
16081
16080
  }
@@ -17118,16 +17117,16 @@ function createTeammateTools(options) {
17118
17117
  update: { team_mailbox: relevantMsgs2, messages: [toolMessage2] }
17119
17118
  });
17120
17119
  }
17121
- const messagePromise = new Promise((resolve3) => {
17120
+ const messagePromise = new Promise((resolve4) => {
17122
17121
  const handler = async (msg) => {
17123
17122
  mailboxStore.offMessage(teamId, agentId, handler);
17124
17123
  const allMsgs = await mailboxStore.getUnreadMessages(teamId, agentId);
17125
- resolve3(allMsgs);
17124
+ resolve4(allMsgs);
17126
17125
  };
17127
17126
  mailboxStore.onMessage(teamId, agentId, handler);
17128
17127
  });
17129
- const timeoutPromise = new Promise((resolve3) => {
17130
- setTimeout(() => resolve3([]), READ_MESSAGES_TIMEOUT_MS2);
17128
+ const timeoutPromise = new Promise((resolve4) => {
17129
+ setTimeout(() => resolve4([]), READ_MESSAGES_TIMEOUT_MS2);
17131
17130
  });
17132
17131
  msgs = await Promise.race([messagePromise, timeoutPromise]);
17133
17132
  mailboxStore.offMessage(teamId, agentId, () => {
@@ -17859,19 +17858,19 @@ Task Status Values:
17859
17858
  update: { team_mailbox: allTeamMessages2, messages: [toolMessage2] }
17860
17859
  });
17861
17860
  }
17862
- const messagePromise = new Promise((resolve3) => {
17861
+ const messagePromise = new Promise((resolve4) => {
17863
17862
  const handler = async (msg) => {
17864
17863
  mailboxStore.offMessage(teamId, TEAM_LEAD_AGENT_ID, handler);
17865
17864
  const allMsgs = await mailboxStore.getUnreadMessages(
17866
17865
  teamId,
17867
17866
  TEAM_LEAD_AGENT_ID
17868
17867
  );
17869
- resolve3(allMsgs);
17868
+ resolve4(allMsgs);
17870
17869
  };
17871
17870
  mailboxStore.onMessage(teamId, TEAM_LEAD_AGENT_ID, handler);
17872
17871
  });
17873
- const timeoutPromise = new Promise((resolve3) => {
17874
- setTimeout(() => resolve3([]), READ_MESSAGES_TIMEOUT_MS);
17872
+ const timeoutPromise = new Promise((resolve4) => {
17873
+ setTimeout(() => resolve4([]), READ_MESSAGES_TIMEOUT_MS);
17875
17874
  });
17876
17875
  msgs = await Promise.race([messagePromise, timeoutPromise]);
17877
17876
  mailboxStore.offMessage(
@@ -22344,10 +22343,10 @@ var MicrosandboxRemoteInstance = class {
22344
22343
  content
22345
22344
  );
22346
22345
  },
22347
- listPath: async (path3, options) => {
22346
+ listPath: async (path5, options) => {
22348
22347
  const result = await this.client.listPath(
22349
22348
  this.name,
22350
- normalizeExternalSandboxPath(path3),
22349
+ normalizeExternalSandboxPath(path5),
22351
22350
  options?.recursive
22352
22351
  );
22353
22352
  const files = result.entries.map((entry) => ({
@@ -22356,10 +22355,10 @@ var MicrosandboxRemoteInstance = class {
22356
22355
  }));
22357
22356
  return { files };
22358
22357
  },
22359
- findFiles: async (path3, glob) => {
22358
+ findFiles: async (path5, glob) => {
22360
22359
  const result = await this.client.findFiles(
22361
22360
  this.name,
22362
- normalizeExternalSandboxPath(path3),
22361
+ normalizeExternalSandboxPath(path5),
22363
22362
  glob
22364
22363
  );
22365
22364
  return {
@@ -22401,15 +22400,15 @@ var MicrosandboxRemoteInstance = class {
22401
22400
  }
22402
22401
  return Buffer.from(result.content ?? "");
22403
22402
  },
22404
- deletePath: async (path3) => {
22405
- const resolved = normalizeExternalSandboxPath(path3);
22403
+ deletePath: async (path5) => {
22404
+ const resolved = normalizeExternalSandboxPath(path5);
22406
22405
  await this.client.execCommand({
22407
22406
  sandboxName: this.name,
22408
22407
  command: `rm -rf "${resolved}"`
22409
22408
  });
22410
22409
  },
22411
- createDirectory: async (path3) => {
22412
- const resolved = normalizeExternalSandboxPath(path3);
22410
+ createDirectory: async (path5) => {
22411
+ const resolved = normalizeExternalSandboxPath(path5);
22413
22412
  await this.client.execCommand({
22414
22413
  sandboxName: this.name,
22415
22414
  command: `mkdir -p "${resolved}"`
@@ -22457,13 +22456,18 @@ var MicrosandboxServiceClient = class {
22457
22456
  this.apiKey = config.apiKey;
22458
22457
  }
22459
22458
  async ensureSandbox(name, input) {
22459
+ const tStart = Date.now();
22460
22460
  console.log(
22461
- `[MicrosandboxClient] ensureSandbox name=${name} image=${input.image ?? "not set"} envKeys=${Object.keys(input.env ?? {}).join(",") || "none"}`
22461
+ `[MicrosandboxClient] ensureSandbox START name=${name} image=${input.image ?? "not set"} envKeys=${Object.keys(input.env ?? {}).join(",") || "none"}`
22462
22462
  );
22463
- return this.request(`/api/sandboxes/${encodeURIComponent(name)}`, {
22463
+ const result = await this.request(`/api/sandboxes/${encodeURIComponent(name)}`, {
22464
22464
  method: "PUT",
22465
22465
  body: input
22466
22466
  });
22467
+ console.log(
22468
+ `[MicrosandboxClient] ensureSandbox DONE name=${name} status=${result.status} elapsed=${Date.now() - tStart}ms`
22469
+ );
22470
+ return result;
22467
22471
  }
22468
22472
  async startSandbox(name) {
22469
22473
  return this.request(`/api/sandboxes/${encodeURIComponent(name)}/start`, {
@@ -22490,34 +22494,34 @@ var MicrosandboxServiceClient = class {
22490
22494
  method: "GET"
22491
22495
  });
22492
22496
  }
22493
- async readFile(sandboxName, path3) {
22497
+ async readFile(sandboxName, path5) {
22494
22498
  return this.request("/api/files/read", {
22495
22499
  method: "POST",
22496
- body: { sandboxName, path: path3 }
22500
+ body: { sandboxName, path: path5 }
22497
22501
  });
22498
22502
  }
22499
- async writeFile(sandboxName, path3, content) {
22503
+ async writeFile(sandboxName, path5, content) {
22500
22504
  return this.request("/api/files/write", {
22501
22505
  method: "POST",
22502
- body: { sandboxName, path: path3, content }
22506
+ body: { sandboxName, path: path5, content }
22503
22507
  });
22504
22508
  }
22505
- async listPath(sandboxName, path3, recursive) {
22509
+ async listPath(sandboxName, path5, recursive) {
22506
22510
  return this.request("/api/files/list", {
22507
22511
  method: "POST",
22508
- body: { sandboxName, path: path3, recursive }
22512
+ body: { sandboxName, path: path5, recursive }
22509
22513
  });
22510
22514
  }
22511
- async findFiles(sandboxName, path3, pattern) {
22515
+ async findFiles(sandboxName, path5, pattern) {
22512
22516
  return this.request("/api/files/find", {
22513
22517
  method: "POST",
22514
- body: { sandboxName, path: path3, pattern }
22518
+ body: { sandboxName, path: path5, pattern }
22515
22519
  });
22516
22520
  }
22517
- async searchInFile(sandboxName, path3, query) {
22521
+ async searchInFile(sandboxName, path5, query) {
22518
22522
  return this.request("/api/files/search", {
22519
22523
  method: "POST",
22520
- body: { sandboxName, path: path3, query }
22524
+ body: { sandboxName, path: path5, query }
22521
22525
  });
22522
22526
  }
22523
22527
  async replaceInFile(sandboxName, input) {
@@ -22526,14 +22530,14 @@ var MicrosandboxServiceClient = class {
22526
22530
  body: { sandboxName, ...input }
22527
22531
  });
22528
22532
  }
22529
- async uploadFile(sandboxName, path3, content) {
22533
+ async uploadFile(sandboxName, path5, content) {
22530
22534
  return this.request("/api/files/upload", {
22531
22535
  method: "POST",
22532
- body: { sandboxName, path: path3, contentBase64: content.toString("base64") }
22536
+ body: { sandboxName, path: path5, contentBase64: content.toString("base64") }
22533
22537
  });
22534
22538
  }
22535
- async downloadFile(sandboxName, path3) {
22536
- const query = new URLSearchParams({ sandboxName, path: path3 });
22539
+ async downloadFile(sandboxName, path5) {
22540
+ const query = new URLSearchParams({ sandboxName, path: path5 });
22537
22541
  return this.request(`/api/files/download?${query.toString()}`, {
22538
22542
  method: "GET"
22539
22543
  });
@@ -22544,32 +22548,32 @@ var MicrosandboxServiceClient = class {
22544
22548
  body: input
22545
22549
  });
22546
22550
  }
22547
- async volumeFsRead(volumeName, path3) {
22551
+ async volumeFsRead(volumeName, path5) {
22548
22552
  const result = await this.request(
22549
22553
  `/api/volumes/${encodeURIComponent(volumeName)}/fs/read`,
22550
22554
  {
22551
22555
  method: "POST",
22552
- body: { path: path3 }
22556
+ body: { path: path5 }
22553
22557
  }
22554
22558
  );
22555
22559
  return result.content;
22556
22560
  }
22557
- async volumeFsWrite(volumeName, path3, content) {
22561
+ async volumeFsWrite(volumeName, path5, content) {
22558
22562
  await this.request(
22559
22563
  `/api/volumes/${encodeURIComponent(volumeName)}/fs/write`,
22560
22564
  {
22561
22565
  method: "POST",
22562
- body: { path: path3, content }
22566
+ body: { path: path5, content }
22563
22567
  }
22564
22568
  );
22565
22569
  }
22566
- async volumeFsList(volumeName, path3) {
22567
- console.log(`[volumeFsList] volume=${volumeName} path="${path3}" url=POST /api/volumes/${encodeURIComponent(volumeName)}/fs/list`);
22570
+ async volumeFsList(volumeName, path5) {
22571
+ console.log(`[volumeFsList] volume=${volumeName} path="${path5}" url=POST /api/volumes/${encodeURIComponent(volumeName)}/fs/list`);
22568
22572
  const result = await this.request(
22569
22573
  `/api/volumes/${encodeURIComponent(volumeName)}/fs/list`,
22570
22574
  {
22571
22575
  method: "POST",
22572
- body: { path: path3 }
22576
+ body: { path: path5 }
22573
22577
  }
22574
22578
  );
22575
22579
  console.log(
@@ -22578,25 +22582,25 @@ var MicrosandboxServiceClient = class {
22578
22582
  );
22579
22583
  return result.entries;
22580
22584
  }
22581
- async volumeFsDownload(volumeName, path3) {
22585
+ async volumeFsDownload(volumeName, path5) {
22582
22586
  const result = await this.request(
22583
- `/api/volumes/${encodeURIComponent(volumeName)}/fs/download?path=${encodeURIComponent(path3)}`,
22587
+ `/api/volumes/${encodeURIComponent(volumeName)}/fs/download?path=${encodeURIComponent(path5)}`,
22584
22588
  {
22585
22589
  method: "GET"
22586
22590
  }
22587
22591
  );
22588
22592
  return Buffer.from(result.contentBase64, "base64");
22589
22593
  }
22590
- async volumeFsUpload(volumeName, path3, data) {
22594
+ async volumeFsUpload(volumeName, path5, data) {
22591
22595
  await this.request(
22592
22596
  `/api/volumes/${encodeURIComponent(volumeName)}/fs/upload`,
22593
22597
  {
22594
22598
  method: "POST",
22595
- body: { path: path3, contentBase64: data.toString("base64") }
22599
+ body: { path: path5, contentBase64: data.toString("base64") }
22596
22600
  }
22597
22601
  );
22598
22602
  }
22599
- async request(path3, init) {
22603
+ async request(path5, init) {
22600
22604
  const headers = {};
22601
22605
  if (init.body) {
22602
22606
  headers["content-type"] = "application/json";
@@ -22604,7 +22608,7 @@ var MicrosandboxServiceClient = class {
22604
22608
  if (this.apiKey) {
22605
22609
  headers.Authorization = `Bearer ${this.apiKey}`;
22606
22610
  }
22607
- const response = await fetch(`${this.baseURL}${path3}`, {
22611
+ const response = await fetch(`${this.baseURL}${path5}`, {
22608
22612
  method: init.method,
22609
22613
  headers: Object.keys(headers).length > 0 ? headers : void 0,
22610
22614
  body: init.body ? JSON.stringify(init.body) : void 0
@@ -22655,16 +22659,21 @@ var MicrosandboxRemoteProvider = class {
22655
22659
  });
22656
22660
  }
22657
22661
  async createSandbox(name, config) {
22658
- const existing = this.instances.get(name);
22659
- if (existing) {
22660
- return existing;
22661
- }
22662
22662
  const inFlight = this.creating.get(name);
22663
22663
  if (inFlight) {
22664
22664
  return inFlight;
22665
22665
  }
22666
+ const existing = this.instances.get(name);
22667
+ if (existing) {
22668
+ console.log(`[MicrosandboxRemote] createSandbox name=${name} INSTANCE_CACHE_HIT`);
22669
+ return existing;
22670
+ }
22666
22671
  const creation = (async () => {
22667
- await this.client.ensureSandbox(name, this.buildEnsureInput(config));
22672
+ const tStart = Date.now();
22673
+ const input = this.buildEnsureInput(config);
22674
+ console.log(`[MicrosandboxRemote] createSandbox name=${name} calling ensureSandbox...`);
22675
+ await this.client.ensureSandbox(name, input);
22676
+ console.log(`[MicrosandboxRemote] createSandbox DONE name=${name} elapsed=${Date.now() - tStart}ms`);
22668
22677
  const instance = new MicrosandboxRemoteInstance(name, this.client);
22669
22678
  this.instances.set(name, instance);
22670
22679
  return instance;
@@ -22700,11 +22709,11 @@ var MicrosandboxRemoteProvider = class {
22700
22709
  }
22701
22710
  createVolumeFsClient(volumeName, _pathPrefix) {
22702
22711
  return {
22703
- read: (path3) => this.client.volumeFsRead(volumeName, path3),
22704
- write: (path3, content) => this.client.volumeFsWrite(volumeName, path3, content),
22705
- list: (path3) => this.client.volumeFsList(volumeName, path3),
22706
- readRaw: (path3) => this.client.volumeFsDownload(volumeName, path3),
22707
- writeRaw: (path3, data) => this.client.volumeFsUpload(volumeName, path3, data)
22712
+ read: (path5) => this.client.volumeFsRead(volumeName, path5),
22713
+ write: (path5, content) => this.client.volumeFsWrite(volumeName, path5, content),
22714
+ list: (path5) => this.client.volumeFsList(volumeName, path5),
22715
+ readRaw: (path5) => this.client.volumeFsDownload(volumeName, path5),
22716
+ writeRaw: (path5, data) => this.client.volumeFsUpload(volumeName, path5, data)
22708
22717
  };
22709
22718
  }
22710
22719
  async listSandboxes() {
@@ -22803,8 +22812,8 @@ var RemoteSandboxInstance = class {
22803
22812
  throw new Error(`writeFile failed: ${extractFetcherError(result.error)}`);
22804
22813
  }
22805
22814
  },
22806
- listPath: async (path3, options) => {
22807
- const resolved = this.resolvePath(path3);
22815
+ listPath: async (path5, options) => {
22816
+ const resolved = this.resolvePath(path5);
22808
22817
  const result = await this.client.file.listPath({
22809
22818
  path: resolved,
22810
22819
  recursive: options?.recursive ?? false
@@ -22820,8 +22829,8 @@ var RemoteSandboxInstance = class {
22820
22829
  }));
22821
22830
  return { files };
22822
22831
  },
22823
- findFiles: async (path3, glob) => {
22824
- const resolved = this.resolvePath(path3);
22832
+ findFiles: async (path5, glob) => {
22833
+ const resolved = this.resolvePath(path5);
22825
22834
  const result = await this.client.file.findFiles({ path: resolved, glob });
22826
22835
  if (!result.ok) {
22827
22836
  throw new Error(`findFiles failed: ${extractFetcherError(result.error)}`);
@@ -22871,8 +22880,8 @@ var RemoteSandboxInstance = class {
22871
22880
  const buffer2 = await result.body.arrayBuffer();
22872
22881
  return Buffer.from(buffer2);
22873
22882
  },
22874
- deletePath: async (path3) => {
22875
- const resolved = this.resolvePath(path3);
22883
+ deletePath: async (path5) => {
22884
+ const resolved = this.resolvePath(path5);
22876
22885
  const result = await this.client.shell.execCommand({
22877
22886
  command: `rm -rf "${resolved}"`
22878
22887
  });
@@ -22880,8 +22889,8 @@ var RemoteSandboxInstance = class {
22880
22889
  throw new Error(`deletePath failed: ${extractFetcherError(result.error)}`);
22881
22890
  }
22882
22891
  },
22883
- createDirectory: async (path3) => {
22884
- const resolved = this.resolvePath(path3);
22892
+ createDirectory: async (path5) => {
22893
+ const resolved = this.resolvePath(path5);
22885
22894
  const result = await this.client.shell.execCommand({
22886
22895
  command: `mkdir -p "${resolved}"`
22887
22896
  });
@@ -23008,7 +23017,7 @@ var RemoteSandboxProvider = class {
23008
23017
  }
23009
23018
  createVolumeFsClient(_volumeName, pathPrefix) {
23010
23019
  const workspace = this.workspace;
23011
- const resolve3 = (p) => {
23020
+ const resolve4 = (p) => {
23012
23021
  if (!p || p === "/") {
23013
23022
  if (pathPrefix) {
23014
23023
  return `${workspace}${pathPrefix}`;
@@ -23028,23 +23037,23 @@ var RemoteSandboxProvider = class {
23028
23037
  return `${workspace}/${p}`;
23029
23038
  };
23030
23039
  return {
23031
- read: async (path3) => {
23032
- const resolved = resolve3(path3);
23040
+ read: async (path5) => {
23041
+ const resolved = resolve4(path5);
23033
23042
  const result = await this.client.file.readFile({ file: resolved });
23034
23043
  if (!result.ok) {
23035
23044
  throw new Error(`Volume read failed: ${extractFetcherError(result.error)}`);
23036
23045
  }
23037
23046
  return result.body.data?.content ?? "";
23038
23047
  },
23039
- write: async (path3, content) => {
23040
- const resolved = resolve3(path3);
23048
+ write: async (path5, content) => {
23049
+ const resolved = resolve4(path5);
23041
23050
  const result = await this.client.file.writeFile({ file: resolved, content });
23042
23051
  if (!result.ok) {
23043
23052
  throw new Error(`Volume write failed: ${extractFetcherError(result.error)}`);
23044
23053
  }
23045
23054
  },
23046
- list: async (path3) => {
23047
- const resolved = resolve3(path3);
23055
+ list: async (path5) => {
23056
+ const resolved = resolve4(path5);
23048
23057
  const result = await this.client.file.listPath({
23049
23058
  path: resolved,
23050
23059
  recursive: false
@@ -23061,8 +23070,8 @@ var RemoteSandboxProvider = class {
23061
23070
  }));
23062
23071
  return entries;
23063
23072
  },
23064
- readRaw: async (path3) => {
23065
- const resolved = resolve3(path3);
23073
+ readRaw: async (path5) => {
23074
+ const resolved = resolve4(path5);
23066
23075
  const result = await this.client.file.downloadFile({ path: resolved });
23067
23076
  if (!result.ok) {
23068
23077
  throw new Error(`Volume download failed: ${extractFetcherError(result.error)}`);
@@ -23070,8 +23079,8 @@ var RemoteSandboxProvider = class {
23070
23079
  const buffer2 = await result.body.arrayBuffer();
23071
23080
  return Buffer.from(buffer2);
23072
23081
  },
23073
- writeRaw: async (path3, data) => {
23074
- const resolved = resolve3(path3);
23082
+ writeRaw: async (path5, data) => {
23083
+ const resolved = resolve4(path5);
23075
23084
  const result = await this.client.file.uploadFile({
23076
23085
  file: data,
23077
23086
  path: resolved
@@ -23099,8 +23108,8 @@ var E2BInstance = class {
23099
23108
  writeFile: async (file, content) => {
23100
23109
  await this.native.files.write(file, content);
23101
23110
  },
23102
- listPath: async (path3, options) => {
23103
- const entries = await this.native.files.list(path3);
23111
+ listPath: async (path5, options) => {
23112
+ const entries = await this.native.files.list(path5);
23104
23113
  const files = entries.map((e) => ({
23105
23114
  path: e.path,
23106
23115
  is_dir: e.type === "dir",
@@ -23109,9 +23118,9 @@ var E2BInstance = class {
23109
23118
  }));
23110
23119
  return { files };
23111
23120
  },
23112
- findFiles: async (path3, glob) => {
23121
+ findFiles: async (path5, glob) => {
23113
23122
  const result = await this.native.commands.run(
23114
- `find "${path3}" -name "${glob}" -type f`
23123
+ `find "${path5}" -name "${glob}" -type f`
23115
23124
  );
23116
23125
  const lines = result.stdout.split("\n").filter(Boolean);
23117
23126
  return { files: lines };
@@ -23134,13 +23143,13 @@ var E2BInstance = class {
23134
23143
  return { matches, line_numbers };
23135
23144
  },
23136
23145
  strReplaceEditor: async (params) => {
23137
- const { path: path3, old_str, new_str, replace_mode } = params;
23146
+ const { path: path5, old_str, new_str, replace_mode } = params;
23138
23147
  const delim = "#";
23139
23148
  const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
23140
23149
  const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
23141
23150
  const flag = replace_mode === "ALL" ? "g" : "";
23142
23151
  await this.native.commands.run(
23143
- `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path3}"`
23152
+ `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path5}"`
23144
23153
  );
23145
23154
  },
23146
23155
  uploadFile: async (params) => {
@@ -23152,11 +23161,11 @@ var E2BInstance = class {
23152
23161
  const data = await this.native.files.read(params.file, { format: "bytes" });
23153
23162
  return Buffer.isBuffer(data) ? data : Buffer.from(data);
23154
23163
  },
23155
- deletePath: async (path3) => {
23156
- await this.native.commands.run(`rm -rf "${path3}"`);
23164
+ deletePath: async (path5) => {
23165
+ await this.native.commands.run(`rm -rf "${path5}"`);
23157
23166
  },
23158
- createDirectory: async (path3) => {
23159
- await this.native.commands.run(`mkdir -p "${path3}"`);
23167
+ createDirectory: async (path5) => {
23168
+ await this.native.commands.run(`mkdir -p "${path5}"`);
23160
23169
  }
23161
23170
  };
23162
23171
  this.shell = {
@@ -23275,8 +23284,8 @@ var DaytonaInstance = class {
23275
23284
  writeFile: async (file, content) => {
23276
23285
  await this.native.fs.uploadFile(Buffer.from(content, "utf-8"), toRelativePath(file));
23277
23286
  },
23278
- listPath: async (path3, options) => {
23279
- const entries = await this.native.fs.listFiles(toRelativePath(path3));
23287
+ listPath: async (path5, options) => {
23288
+ const entries = await this.native.fs.listFiles(toRelativePath(path5));
23280
23289
  const files = entries.map((e) => {
23281
23290
  const rawPath = e.name || "";
23282
23291
  return {
@@ -23288,8 +23297,8 @@ var DaytonaInstance = class {
23288
23297
  });
23289
23298
  return { files };
23290
23299
  },
23291
- findFiles: async (path3, glob) => {
23292
- const result = await this.native.fs.searchFiles(toRelativePath(path3), glob);
23300
+ findFiles: async (path5, glob) => {
23301
+ const result = await this.native.fs.searchFiles(toRelativePath(path5), glob);
23293
23302
  return { files: (result.files || []).map((filePath) => normalizeExternalSandboxPath(filePath)) };
23294
23303
  },
23295
23304
  searchInFile: async (file, regex) => {
@@ -23303,8 +23312,8 @@ var DaytonaInstance = class {
23303
23312
  return { matches: matchTexts, line_numbers };
23304
23313
  },
23305
23314
  strReplaceEditor: async (params) => {
23306
- const { path: path3, old_str, new_str, replace_mode } = params;
23307
- const relPath = toRelativePath(path3);
23315
+ const { path: path5, old_str, new_str, replace_mode } = params;
23316
+ const relPath = toRelativePath(path5);
23308
23317
  if (replace_mode === "ALL") {
23309
23318
  await this.native.fs.replaceInFiles([relPath], old_str, new_str);
23310
23319
  } else {
@@ -23324,11 +23333,11 @@ var DaytonaInstance = class {
23324
23333
  const buffer2 = await this.native.fs.downloadFile(toRelativePath(params.file));
23325
23334
  return Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
23326
23335
  },
23327
- deletePath: async (path3) => {
23328
- await this.native.process.executeCommand(`rm -rf "${toRelativePath(path3)}"`, void 0, void 0);
23336
+ deletePath: async (path5) => {
23337
+ await this.native.process.executeCommand(`rm -rf "${toRelativePath(path5)}"`, void 0, void 0);
23329
23338
  },
23330
- createDirectory: async (path3) => {
23331
- await this.native.process.executeCommand(`mkdir -p "${toRelativePath(path3)}"`, void 0, void 0);
23339
+ createDirectory: async (path5) => {
23340
+ await this.native.process.executeCommand(`mkdir -p "${toRelativePath(path5)}"`, void 0, void 0);
23332
23341
  }
23333
23342
  };
23334
23343
  this.shell = {
@@ -23567,6 +23576,277 @@ var DaytonaProvider = class {
23567
23576
  }
23568
23577
  };
23569
23578
 
23579
+ // src/sandbox_lattice/providers/LocalSandboxProvider.ts
23580
+ import * as path4 from "path";
23581
+ import * as os from "os";
23582
+
23583
+ // src/sandbox_lattice/LocalSandboxInstance.ts
23584
+ import { execFile } from "child_process";
23585
+ import * as fs3 from "fs/promises";
23586
+ import * as path3 from "path";
23587
+ import * as posix from "path/posix";
23588
+ import { promisify } from "util";
23589
+ var execFileAsync = promisify(execFile);
23590
+ var isWin = process.platform === "win32";
23591
+ var LocalSandboxInstance = class {
23592
+ constructor(name, rootDir) {
23593
+ this.file = {
23594
+ readFile: async (file) => {
23595
+ const content = await fs3.readFile(this.hostPath(file), "utf-8");
23596
+ return { content };
23597
+ },
23598
+ writeFile: async (file, content) => {
23599
+ const hp = this.hostPath(file);
23600
+ await fs3.mkdir(path3.dirname(hp), { recursive: true });
23601
+ await fs3.writeFile(hp, content, "utf-8");
23602
+ },
23603
+ listPath: async (targetPath, options) => {
23604
+ const hp = this.hostPath(targetPath);
23605
+ const files = [];
23606
+ if (options?.recursive) {
23607
+ await this.walkDir(hp, targetPath, files);
23608
+ } else {
23609
+ const entries = await fs3.readdir(hp, { withFileTypes: true });
23610
+ for (const e of entries) {
23611
+ const full = path3.join(hp, e.name);
23612
+ const stat4 = await fs3.stat(full).catch(() => null);
23613
+ files.push({
23614
+ path: posix.join(targetPath, e.name),
23615
+ is_dir: e.isDirectory(),
23616
+ size: stat4?.size ?? 0,
23617
+ modified_at: stat4?.mtime.toISOString()
23618
+ });
23619
+ }
23620
+ }
23621
+ return { files };
23622
+ },
23623
+ findFiles: async (targetPath, glob) => {
23624
+ const hp = this.hostPath(targetPath);
23625
+ const results = [];
23626
+ const regex = new RegExp(
23627
+ "^" + glob.replace(/\*+/g, "(.*)").replace(/\?/g, ".") + "$"
23628
+ );
23629
+ await this.walkDirFilter(hp, regex, results);
23630
+ const hpNorm = hp + path3.sep;
23631
+ const toSandboxPath = (hostPath) => posix.join(targetPath, hostPath.slice(hpNorm.length).split(path3.sep).join("/"));
23632
+ return { files: results.map(toSandboxPath) };
23633
+ },
23634
+ searchInFile: async (file, regex) => {
23635
+ const content = await fs3.readFile(this.hostPath(file), "utf-8");
23636
+ const lines = content.split("\n");
23637
+ const matches = [];
23638
+ const line_numbers = [];
23639
+ try {
23640
+ const re = new RegExp(regex);
23641
+ for (let i = 0; i < lines.length; i++) {
23642
+ if (re.test(lines[i])) {
23643
+ matches.push(lines[i]);
23644
+ line_numbers.push(i + 1);
23645
+ }
23646
+ }
23647
+ } catch {
23648
+ }
23649
+ return { matches, line_numbers };
23650
+ },
23651
+ strReplaceEditor: async (params) => {
23652
+ const content = await fs3.readFile(this.hostPath(params.path), "utf-8");
23653
+ let result;
23654
+ if (params.replace_mode === "ALL") {
23655
+ result = content.split(params.old_str).join(params.new_str);
23656
+ } else {
23657
+ const idx = content.indexOf(params.old_str);
23658
+ if (idx === -1) {
23659
+ throw new Error(`Old string not found in ${params.path}`);
23660
+ }
23661
+ result = content.slice(0, idx) + params.new_str + content.slice(idx + params.old_str.length);
23662
+ }
23663
+ await fs3.writeFile(this.hostPath(params.path), result, "utf-8");
23664
+ },
23665
+ uploadFile: async (params) => {
23666
+ const hp = this.hostPath(params.file);
23667
+ await fs3.mkdir(path3.dirname(hp), { recursive: true });
23668
+ await fs3.writeFile(hp, params.data);
23669
+ },
23670
+ downloadFile: async (params) => {
23671
+ const data = await fs3.readFile(this.hostPath(params.file));
23672
+ return data;
23673
+ },
23674
+ deletePath: async (targetPath) => {
23675
+ await fs3.rm(this.hostPath(targetPath), { recursive: true, force: true });
23676
+ },
23677
+ createDirectory: async (targetPath) => {
23678
+ await fs3.mkdir(this.hostPath(targetPath), { recursive: true });
23679
+ }
23680
+ };
23681
+ this.shell = {
23682
+ execCommand: async (params) => {
23683
+ const hp = params.exec_dir ? this.hostPath(params.exec_dir) : this.rootDir;
23684
+ const timeoutMs = params.timeout ? params.timeout * 1e3 : void 0;
23685
+ const [shell, shellArg] = isWin ? ["cmd.exe", "/c"] : ["/bin/sh", "-c"];
23686
+ try {
23687
+ const { stdout, stderr } = await execFileAsync(
23688
+ shell,
23689
+ [shellArg, params.command],
23690
+ {
23691
+ cwd: hp,
23692
+ timeout: timeoutMs,
23693
+ maxBuffer: 10 * 1024 * 1024,
23694
+ // 10MB
23695
+ env: { ...process.env, HOME: this.rootDir }
23696
+ }
23697
+ );
23698
+ const output = stderr ? `${stdout}
23699
+ ${stderr}`.trim() : stdout.trim();
23700
+ return { output, exit_code: 0 };
23701
+ } catch (err) {
23702
+ const execErr = err;
23703
+ const out = execErr.stdout ?? "";
23704
+ const errOut = execErr.stderr ?? "";
23705
+ const output = errOut ? `${out}
23706
+ ${errOut}`.trim() : out.trim();
23707
+ return { output, exit_code: execErr.code ?? 1 };
23708
+ }
23709
+ }
23710
+ };
23711
+ this.name = name;
23712
+ this.rootDir = rootDir;
23713
+ }
23714
+ /** Map sandbox path (absolute, e.g. `/root/foo`) to host filesystem path. */
23715
+ hostPath(sandboxPath) {
23716
+ const normalized = sandboxPath.startsWith("/") ? sandboxPath : `/${sandboxPath}`;
23717
+ const clean = normalized.replace(/\/+/g, "/");
23718
+ const resolved = path3.resolve(this.rootDir, `.${clean}`);
23719
+ if (!resolved.startsWith(this.rootDir + path3.sep) && resolved !== this.rootDir) {
23720
+ throw new Error(`Path traversal denied: ${sandboxPath}`);
23721
+ }
23722
+ return resolved;
23723
+ }
23724
+ async start() {
23725
+ await fs3.mkdir(this.rootDir, { recursive: true });
23726
+ }
23727
+ async stop() {
23728
+ }
23729
+ async kill() {
23730
+ await fs3.rm(this.rootDir, { recursive: true, force: true });
23731
+ }
23732
+ async getStatus() {
23733
+ try {
23734
+ await fs3.access(this.rootDir);
23735
+ return "running";
23736
+ } catch {
23737
+ return "stopped";
23738
+ }
23739
+ }
23740
+ async walkDir(rootHost, sandboxPrefix, result) {
23741
+ const walk = async (hostDir, sandboxDir) => {
23742
+ let entries;
23743
+ try {
23744
+ entries = await fs3.readdir(hostDir, { withFileTypes: true });
23745
+ } catch {
23746
+ return;
23747
+ }
23748
+ for (const e of entries) {
23749
+ const fullHost = path3.join(hostDir, e.name);
23750
+ const fullSandbox = posix.join(sandboxDir, e.name);
23751
+ try {
23752
+ const stat4 = await fs3.stat(fullHost);
23753
+ result.push({
23754
+ path: fullSandbox,
23755
+ is_dir: e.isDirectory(),
23756
+ size: stat4.size,
23757
+ modified_at: stat4.mtime.toISOString()
23758
+ });
23759
+ } catch {
23760
+ result.push({
23761
+ path: fullSandbox,
23762
+ is_dir: e.isDirectory()
23763
+ });
23764
+ }
23765
+ if (e.isDirectory()) {
23766
+ await walk(fullHost, fullSandbox);
23767
+ }
23768
+ }
23769
+ };
23770
+ await walk(rootHost, sandboxPrefix);
23771
+ }
23772
+ async walkDirFilter(dir, regex, result) {
23773
+ let entries;
23774
+ try {
23775
+ entries = await fs3.readdir(dir, { withFileTypes: true });
23776
+ } catch {
23777
+ return;
23778
+ }
23779
+ for (const e of entries) {
23780
+ const full = path3.join(dir, e.name);
23781
+ if (e.isFile() && regex.test(e.name)) {
23782
+ result.push(full);
23783
+ }
23784
+ if (e.isDirectory()) {
23785
+ await this.walkDirFilter(full, regex, result);
23786
+ }
23787
+ }
23788
+ }
23789
+ };
23790
+
23791
+ // src/sandbox_lattice/providers/LocalSandboxProvider.ts
23792
+ var LocalSandboxProvider = class {
23793
+ constructor(config = {}) {
23794
+ this.instances = /* @__PURE__ */ new Map();
23795
+ this.creating = /* @__PURE__ */ new Map();
23796
+ this.basePath = config.basePath ?? path4.join(os.homedir(), ".axiom-local-sandbox");
23797
+ }
23798
+ async createSandbox(name, _config) {
23799
+ const existing = this.instances.get(name);
23800
+ if (existing) {
23801
+ const running = await existing.getStatus();
23802
+ if (running === "running") {
23803
+ return existing;
23804
+ }
23805
+ this.instances.delete(name);
23806
+ }
23807
+ const inFlight = this.creating.get(name);
23808
+ if (inFlight) {
23809
+ return inFlight;
23810
+ }
23811
+ const sandboxDir = path4.join(this.basePath, name);
23812
+ const creation = (async () => {
23813
+ const instance = new LocalSandboxInstance(name, sandboxDir);
23814
+ await instance.start();
23815
+ this.instances.set(name, instance);
23816
+ return instance;
23817
+ })();
23818
+ this.creating.set(name, creation);
23819
+ creation.catch(() => this.instances.delete(name)).finally(() => this.creating.delete(name));
23820
+ return creation;
23821
+ }
23822
+ async getSandbox(name) {
23823
+ const instance = this.instances.get(name);
23824
+ if (!instance) {
23825
+ throw new Error(`Sandbox ${name} not found`);
23826
+ }
23827
+ return instance;
23828
+ }
23829
+ async stopSandbox(name) {
23830
+ const instance = this.instances.get(name);
23831
+ if (instance) {
23832
+ try {
23833
+ await instance.stop();
23834
+ } catch {
23835
+ }
23836
+ }
23837
+ }
23838
+ async deleteSandbox(name) {
23839
+ const instance = this.instances.get(name);
23840
+ this.instances.delete(name);
23841
+ if (instance) {
23842
+ await instance.kill();
23843
+ }
23844
+ }
23845
+ async listSandboxes() {
23846
+ return Array.from(this.instances.values());
23847
+ }
23848
+ };
23849
+
23570
23850
  // src/sandbox_lattice/SandboxProviderFactory.ts
23571
23851
  function createSandboxProvider(config) {
23572
23852
  switch (config.type) {
@@ -23611,6 +23891,9 @@ function createSandboxProvider(config) {
23611
23891
  volumeName: config.daytonaVolumeName
23612
23892
  });
23613
23893
  }
23894
+ case "local": {
23895
+ return new LocalSandboxProvider({ basePath: config.localSandboxBasePath });
23896
+ }
23614
23897
  default: {
23615
23898
  const exhaustiveCheck = config.type;
23616
23899
  throw new Error(`Unknown sandbox provider type: ${exhaustiveCheck}`);
@@ -23901,6 +24184,8 @@ export {
23901
24184
  InMemoryUserStore,
23902
24185
  InMemoryUserTenantLinkStore,
23903
24186
  LINE_NUMBER_WIDTH,
24187
+ LocalSandboxInstance,
24188
+ LocalSandboxProvider,
23904
24189
  LoggerLatticeManager,
23905
24190
  MAX_LINE_LENGTH,
23906
24191
  McpLatticeManager,