@ash-cloud/ash-ai 0.1.13 → 0.1.16

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.cjs CHANGED
@@ -4233,6 +4233,50 @@ VERCEL_EOF`);
4233
4233
  }
4234
4234
  });
4235
4235
 
4236
+ // src/runtime/providers/firecracker/types.ts
4237
+ var init_types3 = __esm({
4238
+ "src/runtime/providers/firecracker/types.ts"() {
4239
+ }
4240
+ });
4241
+
4242
+ // src/runtime/providers/firecracker/image-manager.ts
4243
+ var init_image_manager = __esm({
4244
+ "src/runtime/providers/firecracker/image-manager.ts"() {
4245
+ }
4246
+ });
4247
+
4248
+ // src/runtime/providers/firecracker/network-manager.ts
4249
+ var init_network_manager = __esm({
4250
+ "src/runtime/providers/firecracker/network-manager.ts"() {
4251
+ }
4252
+ });
4253
+
4254
+ // src/runtime/providers/firecracker/ssh-executor.ts
4255
+ var init_ssh_executor = __esm({
4256
+ "src/runtime/providers/firecracker/ssh-executor.ts"() {
4257
+ }
4258
+ });
4259
+
4260
+ // src/runtime/providers/firecracker/vm-manager.ts
4261
+ var init_vm_manager = __esm({
4262
+ "src/runtime/providers/firecracker/vm-manager.ts"() {
4263
+ init_types3();
4264
+ }
4265
+ });
4266
+
4267
+ // src/runtime/providers/firecracker.ts
4268
+ var init_firecracker = __esm({
4269
+ "src/runtime/providers/firecracker.ts"() {
4270
+ init_types2();
4271
+ init_types3();
4272
+ init_image_manager();
4273
+ init_network_manager();
4274
+ init_ssh_executor();
4275
+ init_vm_manager();
4276
+ init_types3();
4277
+ }
4278
+ });
4279
+
4236
4280
  // src/runtime/providers/index.ts
4237
4281
  var init_providers = __esm({
4238
4282
  "src/runtime/providers/index.ts"() {
@@ -4244,6 +4288,7 @@ var init_providers = __esm({
4244
4288
  init_fly();
4245
4289
  init_daytona();
4246
4290
  init_vercel();
4291
+ init_firecracker();
4247
4292
  init_local();
4248
4293
  init_modal();
4249
4294
  init_e2b();
@@ -4251,6 +4296,7 @@ var init_providers = __esm({
4251
4296
  init_fly();
4252
4297
  init_daytona();
4253
4298
  init_vercel();
4299
+ init_firecracker();
4254
4300
  }
4255
4301
  });
4256
4302
 
@@ -5289,6 +5335,23 @@ function isSandboxRunning(sessionId) {
5289
5335
  const cached = sandboxCache.get(sessionId);
5290
5336
  return cached !== void 0 && !cached.isExpired;
5291
5337
  }
5338
+ function getCachedSandbox(sessionId) {
5339
+ const cached = sandboxCache.get(sessionId);
5340
+ if (!cached || cached.isExpired) {
5341
+ return null;
5342
+ }
5343
+ cached.lastUsedAt = Date.now();
5344
+ return {
5345
+ sandbox: cached.sandbox,
5346
+ sandboxId: cached.sandbox.sandboxId,
5347
+ sdkInstalled: cached.sdkInstalled,
5348
+ startupScriptRan: cached.startupScriptRan,
5349
+ startupScriptHash: cached.startupScriptHash,
5350
+ isNew: false,
5351
+ configFileUrl: cached.configFileUrl,
5352
+ configInstalledAt: cached.configInstalledAt
5353
+ };
5354
+ }
5292
5355
  async function writeFileToSandbox(sessionId, path15, content) {
5293
5356
  const cached = sandboxCache.get(sessionId);
5294
5357
  if (!cached) {
@@ -5357,6 +5420,54 @@ async function readFileFromSandbox(sessionId, path15) {
5357
5420
  };
5358
5421
  }
5359
5422
  }
5423
+ async function executeCommandInSandbox(sessionId, command, options) {
5424
+ const cached = sandboxCache.get(sessionId);
5425
+ if (!cached) {
5426
+ return { success: false, error: "No active sandbox for session" };
5427
+ }
5428
+ if (cached.isExpired) {
5429
+ return { success: false, error: "Sandbox has expired" };
5430
+ }
5431
+ const startTime = Date.now();
5432
+ try {
5433
+ const sandbox = cached.sandbox;
5434
+ let fullCommand = command;
5435
+ if (options?.cwd) {
5436
+ fullCommand = `cd ${JSON.stringify(options.cwd)} && ${command}`;
5437
+ }
5438
+ const result = await sandbox.runCommand({
5439
+ cmd: "bash",
5440
+ args: ["-c", fullCommand],
5441
+ env: options?.env
5442
+ });
5443
+ const stdout = await result.stdout();
5444
+ const stderr = await result.stderr();
5445
+ const durationMs = Date.now() - startTime;
5446
+ cached.lastUsedAt = Date.now();
5447
+ return {
5448
+ success: result.exitCode === 0,
5449
+ exitCode: result.exitCode,
5450
+ stdout,
5451
+ stderr,
5452
+ durationMs
5453
+ };
5454
+ } catch (error) {
5455
+ const durationMs = Date.now() - startTime;
5456
+ if (isSandboxExpiredError(error)) {
5457
+ cached.isExpired = true;
5458
+ return {
5459
+ success: false,
5460
+ error: "Sandbox has expired",
5461
+ durationMs
5462
+ };
5463
+ }
5464
+ return {
5465
+ success: false,
5466
+ error: error instanceof Error ? error.message : "Unknown error",
5467
+ durationMs
5468
+ };
5469
+ }
5470
+ }
5360
5471
  async function listFilesInSandbox(sessionId, path15) {
5361
5472
  const cached = sandboxCache.get(sessionId);
5362
5473
  if (!cached) {
@@ -5836,19 +5947,7 @@ function getFileWatcherManager() {
5836
5947
  function createFileWatcherManager() {
5837
5948
  return new exports.FileWatcherManager();
5838
5949
  }
5839
- function createRemoteFileWatcher(options) {
5840
- return new exports.RemoteSandboxFileWatcher(options);
5841
- }
5842
- function getRemoteFileWatcherManager() {
5843
- if (!globalRemoteWatcherManager) {
5844
- globalRemoteWatcherManager = new exports.RemoteFileWatcherManager();
5845
- }
5846
- return globalRemoteWatcherManager;
5847
- }
5848
- function createRemoteFileWatcherManager() {
5849
- return new exports.RemoteFileWatcherManager();
5850
- }
5851
- exports.SandboxFileWatcher = void 0; exports.FileWatcherManager = void 0; var globalWatcherManager; exports.RemoteSandboxFileWatcher = void 0; exports.RemoteFileWatcherManager = void 0; var globalRemoteWatcherManager;
5950
+ exports.SandboxFileWatcher = void 0; exports.FileWatcherManager = void 0; var globalWatcherManager;
5852
5951
  var init_sandbox_file_watcher = __esm({
5853
5952
  "src/runtime/sandbox-file-watcher.ts"() {
5854
5953
  exports.SandboxFileWatcher = class {
@@ -5874,7 +5973,18 @@ var init_sandbox_file_watcher = __esm({
5874
5973
  this.watchPath = options.watchPath;
5875
5974
  this.debounceMs = options.debounceMs ?? 300;
5876
5975
  this.patterns = options.patterns ?? ["**/*"];
5877
- this.ignored = options.ignored ?? ["**/node_modules/**", "**/.git/**", "**/*.log"];
5976
+ this.ignored = options.ignored ?? [
5977
+ "**/node_modules/**",
5978
+ "**/.git/**",
5979
+ "**/*.log",
5980
+ // Temporary files from atomic saves and editors
5981
+ "**/*.tmp",
5982
+ "**/*.tmp.*",
5983
+ "**/*~",
5984
+ "**/*.swp",
5985
+ "**/*.swo",
5986
+ "**/.DS_Store"
5987
+ ];
5878
5988
  this.emitInitialEvents = options.emitInitialEvents ?? false;
5879
5989
  this.followSymlinks = options.followSymlinks ?? false;
5880
5990
  this.usePolling = options.usePolling ?? false;
@@ -6090,214 +6200,343 @@ var init_sandbox_file_watcher = __esm({
6090
6200
  }
6091
6201
  };
6092
6202
  globalWatcherManager = null;
6093
- exports.RemoteSandboxFileWatcher = class {
6203
+ }
6204
+ });
6205
+
6206
+ // src/runtime/in-sandbox-watcher.ts
6207
+ function createInSandboxWatcher(options) {
6208
+ return new exports.InSandboxWatcher(options);
6209
+ }
6210
+ function getInSandboxWatcherManager() {
6211
+ if (!globalInSandboxManager) {
6212
+ globalInSandboxManager = new exports.InSandboxWatcherManager();
6213
+ }
6214
+ return globalInSandboxManager;
6215
+ }
6216
+ function createInSandboxWatcherManager() {
6217
+ return new exports.InSandboxWatcherManager();
6218
+ }
6219
+ var WATCHER_SCRIPT; exports.InSandboxWatcher = void 0; exports.InSandboxWatcherManager = void 0; var globalInSandboxManager;
6220
+ var init_in_sandbox_watcher = __esm({
6221
+ "src/runtime/in-sandbox-watcher.ts"() {
6222
+ init_vercel_sandbox_executor();
6223
+ WATCHER_SCRIPT = `
6224
+ const fs = require('fs');
6225
+ const path = require('path');
6226
+
6227
+ const watchPath = process.argv[2] || '.';
6228
+ const ignoredDirs = new Set(['node_modules', '.git', '.cache', '__pycache__']);
6229
+
6230
+ // Track all watchers for cleanup
6231
+ const watchers = new Map();
6232
+
6233
+ // Debounce map to coalesce rapid changes
6234
+ const pending = new Map();
6235
+ const DEBOUNCE_MS = 100;
6236
+
6237
+ function emit(type, filePath) {
6238
+ const event = {
6239
+ type,
6240
+ path: filePath,
6241
+ timestamp: Date.now()
6242
+ };
6243
+ console.log(JSON.stringify(event));
6244
+ }
6245
+
6246
+ function shouldIgnore(name) {
6247
+ // Ignore hidden files/dirs (starting with .)
6248
+ if (name.startsWith('.')) return true;
6249
+
6250
+ // Ignore known directories
6251
+ if (ignoredDirs.has(name)) return true;
6252
+
6253
+ // Ignore temporary files from atomic saves and editors:
6254
+ // - filename.tmp (ends with .tmp)
6255
+ // - filename.tmp.123456789 (has .tmp. in middle - atomic write pattern)
6256
+ // - filename~ (editor backup files)
6257
+ // - filename.swp / filename.swo (Vim swap files)
6258
+ if (name.endsWith('.tmp')) return true;
6259
+ if (name.includes('.tmp.')) return true;
6260
+ if (name.endsWith('~')) return true;
6261
+ if (name.endsWith('.swp') || name.endsWith('.swo')) return true;
6262
+
6263
+ return false;
6264
+ }
6265
+
6266
+ function watchDir(dir) {
6267
+ try {
6268
+ const watcher = fs.watch(dir, { persistent: true }, (eventType, filename) => {
6269
+ if (!filename || shouldIgnore(filename)) return;
6270
+
6271
+ const fullPath = path.join(dir, filename);
6272
+ const key = fullPath;
6273
+
6274
+ // Debounce
6275
+ if (pending.has(key)) {
6276
+ clearTimeout(pending.get(key));
6277
+ }
6278
+
6279
+ pending.set(key, setTimeout(() => {
6280
+ pending.delete(key);
6281
+
6282
+ fs.stat(fullPath, (err, stats) => {
6283
+ if (err) {
6284
+ if (err.code === 'ENOENT') {
6285
+ emit('unlink', fullPath);
6286
+ // Stop watching if it was a directory
6287
+ if (watchers.has(fullPath)) {
6288
+ watchers.get(fullPath).close();
6289
+ watchers.delete(fullPath);
6290
+ }
6291
+ }
6292
+ } else {
6293
+ const type = eventType === 'rename' ? 'add' : 'change';
6294
+ emit(type, fullPath);
6295
+
6296
+ // If it's a new directory, start watching it
6297
+ if (stats.isDirectory() && !watchers.has(fullPath)) {
6298
+ watchDir(fullPath);
6299
+ }
6300
+ }
6301
+ });
6302
+ }, DEBOUNCE_MS));
6303
+ });
6304
+
6305
+ watchers.set(dir, watcher);
6306
+
6307
+ // Watch subdirectories
6308
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
6309
+ for (const entry of entries) {
6310
+ if (entry.isDirectory() && !shouldIgnore(entry.name)) {
6311
+ watchDir(path.join(dir, entry.name));
6312
+ }
6313
+ }
6314
+ } catch (err) {
6315
+ // Directory may not exist or be inaccessible
6316
+ console.error(JSON.stringify({ error: err.message, dir }));
6317
+ }
6318
+ }
6319
+
6320
+ // Start watching
6321
+ watchDir(watchPath);
6322
+
6323
+ // Keep alive
6324
+ process.on('SIGTERM', () => {
6325
+ for (const watcher of watchers.values()) {
6326
+ watcher.close();
6327
+ }
6328
+ process.exit(0);
6329
+ });
6330
+
6331
+ // Heartbeat to indicate we're running
6332
+ setInterval(() => {
6333
+ console.log(JSON.stringify({ heartbeat: true, timestamp: Date.now() }));
6334
+ }, 5000);
6335
+
6336
+ console.log(JSON.stringify({ started: true, path: watchPath }));
6337
+ `;
6338
+ exports.InSandboxWatcher = class {
6094
6339
  sessionId;
6095
- sandboxOps;
6096
- basePath;
6097
- pollIntervalMs;
6098
- ignored;
6099
- pollTimer = null;
6100
- previousFiles = /* @__PURE__ */ new Map();
6340
+ watchPath;
6341
+ outputPollIntervalMs;
6342
+ sandboxState = null;
6343
+ outputPollTimer = null;
6101
6344
  subscribers = /* @__PURE__ */ new Set();
6102
- isWatching = false;
6345
+ isRunning = false;
6103
6346
  startedAt;
6104
- lastPollAt;
6105
- pollCount = 0;
6347
+ lastHeartbeat;
6348
+ lastOutputPosition = 0;
6106
6349
  onError;
6350
+ onReady;
6107
6351
  constructor(options) {
6108
6352
  this.sessionId = options.sessionId;
6109
- this.sandboxOps = options.sandboxOps;
6110
- this.basePath = options.basePath;
6111
- this.pollIntervalMs = options.pollIntervalMs ?? 2e3;
6112
- this.ignored = options.ignored ?? ["**/node_modules/**", "**/.git/**"];
6353
+ this.watchPath = options.watchPath;
6354
+ this.outputPollIntervalMs = options.outputPollIntervalMs ?? 1e3;
6113
6355
  this.onError = options.onError;
6356
+ this.onReady = options.onReady;
6114
6357
  if (options.onFileChange) {
6115
6358
  this.subscribers.add(options.onFileChange);
6116
6359
  }
6117
6360
  }
6118
6361
  /**
6119
- * Start polling for file changes
6362
+ * Start the watcher process inside the sandbox
6120
6363
  */
6121
6364
  async start() {
6122
- if (this.isWatching) {
6123
- console.warn(`[REMOTE_WATCHER] Already watching session ${this.sessionId}`);
6365
+ if (this.isRunning) {
6366
+ console.warn(`[IN_SANDBOX_WATCHER] Already running for session ${this.sessionId}`);
6124
6367
  return;
6125
6368
  }
6126
- if (!this.sandboxOps.isSandboxRunning(this.sessionId)) {
6127
- throw new Error(`Sandbox is not running for session ${this.sessionId}`);
6128
- }
6129
- await this.scan(true);
6130
- this.pollTimer = setInterval(async () => {
6131
- try {
6132
- await this.scan(false);
6133
- } catch (error) {
6134
- console.error(`[REMOTE_WATCHER] Poll error for session ${this.sessionId}:`, error);
6135
- if (this.onError && error instanceof Error) {
6136
- this.onError(error);
6137
- }
6369
+ try {
6370
+ this.sandboxState = getCachedSandbox(this.sessionId);
6371
+ if (!this.sandboxState) {
6372
+ throw new Error(`No active sandbox found for session ${this.sessionId}. Sandbox must be created before starting file watcher.`);
6138
6373
  }
6139
- }, this.pollIntervalMs);
6140
- this.isWatching = true;
6141
- this.startedAt = /* @__PURE__ */ new Date();
6142
- console.log(`[REMOTE_WATCHER] Started watching session ${this.sessionId} at ${this.basePath}`);
6143
- }
6144
- /**
6145
- * Stop polling and cleanup
6146
- */
6147
- async stop() {
6148
- if (!this.isWatching) {
6149
- return;
6150
- }
6151
- if (this.pollTimer) {
6152
- clearInterval(this.pollTimer);
6153
- this.pollTimer = null;
6374
+ const { sandbox } = this.sandboxState;
6375
+ const scriptPath = "/tmp/.file-watcher.js";
6376
+ const outputPath = "/tmp/.file-watcher-output.log";
6377
+ const writeScriptCmd = `cat > ${scriptPath} << 'WATCHER_EOF'
6378
+ ${WATCHER_SCRIPT}
6379
+ WATCHER_EOF`;
6380
+ await sandbox.runCommand({
6381
+ cmd: "sh",
6382
+ args: ["-c", writeScriptCmd]
6383
+ });
6384
+ const startCmd = `nohup node ${scriptPath} "${this.watchPath}" > ${outputPath} 2>&1 &`;
6385
+ await sandbox.runCommand({
6386
+ cmd: "sh",
6387
+ args: ["-c", startCmd]
6388
+ });
6389
+ console.log(`[IN_SANDBOX_WATCHER] Started watcher in sandbox for ${this.watchPath}`);
6390
+ this.isRunning = true;
6391
+ this.startedAt = /* @__PURE__ */ new Date();
6392
+ this.outputPollTimer = setInterval(async () => {
6393
+ try {
6394
+ await this.pollOutput(outputPath);
6395
+ } catch (error) {
6396
+ console.error("[IN_SANDBOX_WATCHER] Error polling output:", error);
6397
+ if (this.onError && error instanceof Error) {
6398
+ this.onError(error);
6399
+ }
6400
+ }
6401
+ }, this.outputPollIntervalMs);
6402
+ setTimeout(() => {
6403
+ this.pollOutput(outputPath).catch(console.error);
6404
+ }, 500);
6405
+ } catch (error) {
6406
+ console.error(`[IN_SANDBOX_WATCHER] Failed to start watcher:`, error);
6407
+ throw error;
6154
6408
  }
6155
- this.isWatching = false;
6156
- this.previousFiles.clear();
6157
- console.log(`[REMOTE_WATCHER] Stopped watching session ${this.sessionId}`);
6158
6409
  }
6159
6410
  /**
6160
- * Subscribe to file change events
6411
+ * Poll the output file for new events
6161
6412
  */
6162
- subscribe(callback) {
6163
- this.subscribers.add(callback);
6164
- return () => this.subscribers.delete(callback);
6165
- }
6166
- /**
6167
- * Remove a subscriber
6168
- */
6169
- unsubscribe(callback) {
6170
- this.subscribers.delete(callback);
6171
- }
6172
- /**
6173
- * Check if watcher is active
6174
- */
6175
- isActive() {
6176
- return this.isWatching;
6177
- }
6178
- /**
6179
- * Get watcher status
6180
- */
6181
- getStatus() {
6182
- return {
6183
- sessionId: this.sessionId,
6184
- watchPath: this.basePath,
6185
- isWatching: this.isWatching,
6186
- watchedFileCount: this.previousFiles.size,
6187
- pendingEventCount: 0,
6188
- startedAt: this.startedAt,
6189
- lastPollAt: this.lastPollAt,
6190
- pollCount: this.pollCount
6191
- };
6413
+ async pollOutput(outputPath) {
6414
+ if (!this.sandboxState?.sandbox) return;
6415
+ try {
6416
+ const result = await this.sandboxState.sandbox.runCommand({
6417
+ cmd: "sh",
6418
+ args: ["-c", `tail -c +${this.lastOutputPosition + 1} ${outputPath} 2>/dev/null || true`]
6419
+ });
6420
+ const output = await result.stdout();
6421
+ if (output && output.trim()) {
6422
+ const sizeResult = await this.sandboxState.sandbox.runCommand({
6423
+ cmd: "sh",
6424
+ args: ["-c", `stat -c%s ${outputPath} 2>/dev/null || echo 0`]
6425
+ });
6426
+ const sizeStr = await sizeResult.stdout();
6427
+ this.lastOutputPosition = parseInt(sizeStr.trim(), 10) || 0;
6428
+ this.processOutput(output);
6429
+ }
6430
+ } catch {
6431
+ }
6192
6432
  }
6193
6433
  /**
6194
- * Force an immediate scan (useful for testing or manual refresh)
6434
+ * Process output from the watcher script
6195
6435
  */
6196
- async forceScan() {
6197
- await this.scan(false);
6436
+ processOutput(stdout) {
6437
+ const lines = stdout.split("\n").filter(Boolean);
6438
+ for (const line of lines) {
6439
+ try {
6440
+ const data = JSON.parse(line);
6441
+ if (data.started) {
6442
+ console.log(`[IN_SANDBOX_WATCHER] Watcher started for ${data.path}`);
6443
+ if (this.onReady) {
6444
+ this.onReady();
6445
+ }
6446
+ } else if (data.heartbeat) {
6447
+ this.lastHeartbeat = new Date(data.timestamp);
6448
+ } else if (data.error) {
6449
+ console.warn(`[IN_SANDBOX_WATCHER] Error in sandbox:`, data.error);
6450
+ } else if (data.type && data.path) {
6451
+ this.emitEvent({
6452
+ type: data.type,
6453
+ relativePath: data.path.replace(/^\.\//, ""),
6454
+ absolutePath: data.path,
6455
+ basePath: this.watchPath,
6456
+ sessionId: this.sessionId,
6457
+ timestamp: new Date(data.timestamp)
6458
+ });
6459
+ }
6460
+ } catch {
6461
+ }
6462
+ }
6198
6463
  }
6199
6464
  /**
6200
- * Scan the sandbox for file changes
6465
+ * Stop the watcher process
6201
6466
  */
6202
- async scan(isInitial) {
6203
- if (!this.sandboxOps.isSandboxRunning(this.sessionId)) {
6204
- console.warn(`[REMOTE_WATCHER] Sandbox stopped for session ${this.sessionId}`);
6205
- await this.stop();
6467
+ async stop() {
6468
+ if (!this.isRunning) {
6206
6469
  return;
6207
6470
  }
6208
- const listResult = await this.sandboxOps.listFiles(this.sessionId, this.basePath);
6209
- if (!listResult.success || !listResult.files) {
6210
- throw new Error(listResult.error ?? "Failed to list files in sandbox");
6211
- }
6212
- const currentFiles = /* @__PURE__ */ new Map();
6213
- for (const filePath of listResult.files) {
6214
- if (this.shouldIgnore(filePath)) {
6215
- continue;
6216
- }
6217
- currentFiles.set(filePath, { path: filePath });
6218
- }
6219
- this.lastPollAt = /* @__PURE__ */ new Date();
6220
- this.pollCount++;
6221
- if (isInitial) {
6222
- this.previousFiles = currentFiles;
6223
- return;
6471
+ if (this.outputPollTimer) {
6472
+ clearInterval(this.outputPollTimer);
6473
+ this.outputPollTimer = null;
6224
6474
  }
6225
- const changes = [];
6226
- for (const [filePath, info] of currentFiles) {
6227
- const previous = this.previousFiles.get(filePath);
6228
- if (!previous) {
6229
- changes.push({
6230
- type: "add",
6231
- relativePath: filePath,
6232
- absolutePath: `${this.basePath}/${filePath}`,
6233
- basePath: this.basePath,
6234
- sessionId: this.sessionId,
6235
- fileSize: info.size,
6236
- timestamp: /* @__PURE__ */ new Date()
6475
+ try {
6476
+ if (this.sandboxState?.sandbox) {
6477
+ await this.sandboxState.sandbox.runCommand({
6478
+ cmd: "sh",
6479
+ args: ["-c", "pkill -f file-watcher.js 2>/dev/null || true"]
6237
6480
  });
6238
- }
6239
- }
6240
- for (const [filePath] of this.previousFiles) {
6241
- if (!currentFiles.has(filePath)) {
6242
- changes.push({
6243
- type: "unlink",
6244
- relativePath: filePath,
6245
- absolutePath: `${this.basePath}/${filePath}`,
6246
- basePath: this.basePath,
6247
- sessionId: this.sessionId,
6248
- timestamp: /* @__PURE__ */ new Date()
6481
+ await this.sandboxState.sandbox.runCommand({
6482
+ cmd: "sh",
6483
+ args: ["-c", "rm -f /tmp/.file-watcher.js /tmp/.file-watcher-output.log"]
6249
6484
  });
6250
6485
  }
6486
+ } catch {
6251
6487
  }
6252
- this.previousFiles = currentFiles;
6253
- for (const event of changes) {
6254
- await this.emitEvent(event);
6255
- }
6488
+ this.isRunning = false;
6489
+ this.sandboxState = null;
6490
+ this.lastOutputPosition = 0;
6491
+ console.log(`[IN_SANDBOX_WATCHER] Stopped watcher for session ${this.sessionId}`);
6256
6492
  }
6257
6493
  /**
6258
- * Check if a path should be ignored
6494
+ * Subscribe to file change events
6259
6495
  */
6260
- shouldIgnore(filePath) {
6261
- for (const pattern of this.ignored) {
6262
- if (this.matchesGlob(filePath, pattern)) {
6263
- return true;
6264
- }
6265
- }
6266
- return false;
6496
+ subscribe(callback) {
6497
+ this.subscribers.add(callback);
6498
+ return () => this.subscribers.delete(callback);
6267
6499
  }
6268
6500
  /**
6269
- * Simple glob matching (supports ** and *)
6501
+ * Check if watcher is running
6270
6502
  */
6271
- matchesGlob(filePath, pattern) {
6272
- const regexPattern = pattern.replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/{{GLOBSTAR}}/g, ".*").replace(/\//g, "\\/");
6273
- const regex = new RegExp(`^${regexPattern}$`);
6274
- return regex.test(filePath);
6503
+ isActive() {
6504
+ return this.isRunning;
6275
6505
  }
6276
6506
  /**
6277
- * Emit a file change event to all subscribers
6507
+ * Get watcher status
6508
+ */
6509
+ getStatus() {
6510
+ return {
6511
+ sessionId: this.sessionId,
6512
+ watchPath: this.watchPath,
6513
+ isRunning: this.isRunning,
6514
+ startedAt: this.startedAt,
6515
+ lastHeartbeat: this.lastHeartbeat
6516
+ };
6517
+ }
6518
+ /**
6519
+ * Emit event to all subscribers
6278
6520
  */
6279
6521
  async emitEvent(event) {
6280
6522
  for (const callback of this.subscribers) {
6281
6523
  try {
6282
6524
  await callback(event);
6283
6525
  } catch (error) {
6284
- console.error("[REMOTE_WATCHER] Error in subscriber callback:", error);
6526
+ console.error("[IN_SANDBOX_WATCHER] Error in subscriber callback:", error);
6285
6527
  }
6286
6528
  }
6287
6529
  }
6288
6530
  };
6289
- exports.RemoteFileWatcherManager = class {
6531
+ exports.InSandboxWatcherManager = class {
6290
6532
  watchers = /* @__PURE__ */ new Map();
6291
6533
  /**
6292
- * Start watching a session's sandbox
6534
+ * Start watching a sandbox
6293
6535
  */
6294
6536
  async startWatching(options) {
6295
6537
  const { sessionId } = options;
6296
- const existing = this.watchers.get(sessionId);
6297
- if (existing) {
6298
- await existing.stop();
6299
- }
6300
- const watcher = new exports.RemoteSandboxFileWatcher(options);
6538
+ await this.stopWatching(sessionId);
6539
+ const watcher = new exports.InSandboxWatcher(options);
6301
6540
  await watcher.start();
6302
6541
  this.watchers.set(sessionId, watcher);
6303
6542
  return watcher;
@@ -6313,17 +6552,16 @@ var init_sandbox_file_watcher = __esm({
6313
6552
  }
6314
6553
  }
6315
6554
  /**
6316
- * Get a watcher for a session
6555
+ * Get watcher for a session
6317
6556
  */
6318
6557
  getWatcher(sessionId) {
6319
6558
  return this.watchers.get(sessionId);
6320
6559
  }
6321
6560
  /**
6322
- * Check if a session is being watched
6561
+ * Check if watching
6323
6562
  */
6324
6563
  isWatching(sessionId) {
6325
- const watcher = this.watchers.get(sessionId);
6326
- return watcher?.isActive() ?? false;
6564
+ return this.watchers.get(sessionId)?.isActive() ?? false;
6327
6565
  }
6328
6566
  /**
6329
6567
  * Stop all watchers
@@ -6334,7 +6572,7 @@ var init_sandbox_file_watcher = __esm({
6334
6572
  this.watchers.clear();
6335
6573
  }
6336
6574
  };
6337
- globalRemoteWatcherManager = null;
6575
+ globalInSandboxManager = null;
6338
6576
  }
6339
6577
  });
6340
6578
  function extractErrorMessage(error) {
@@ -6383,6 +6621,7 @@ exports.SandboxFileSync = void 0;
6383
6621
  var init_sandbox_file_sync = __esm({
6384
6622
  "src/runtime/sandbox-file-sync.ts"() {
6385
6623
  init_sandbox_file_watcher();
6624
+ init_in_sandbox_watcher();
6386
6625
  init_types();
6387
6626
  exports.SandboxFileSync = class {
6388
6627
  fileStore;
@@ -6393,7 +6632,7 @@ var init_sandbox_file_sync = __esm({
6393
6632
  eventStorage;
6394
6633
  webhookConfig;
6395
6634
  // Watcher management
6396
- remoteWatchers = /* @__PURE__ */ new Map();
6635
+ inSandboxWatchers = /* @__PURE__ */ new Map();
6397
6636
  localWatchers = /* @__PURE__ */ new Map();
6398
6637
  fileChangeSubscribers = /* @__PURE__ */ new Set();
6399
6638
  // Sequence number cache per session (for event storage)
@@ -7184,34 +7423,27 @@ var init_sandbox_file_sync = __esm({
7184
7423
  this.localWatchers.set(sessionId, watcher);
7185
7424
  console.log(`[FILE_SYNC] Started local file watching for session ${sessionId} at ${opts.localPath}`);
7186
7425
  } else {
7187
- if (!this.sandboxOps) {
7188
- throw new Error("Sandbox operations not configured. Call setSandboxOperations first.");
7189
- }
7190
- const watcher = new exports.RemoteSandboxFileWatcher({
7426
+ const watcher = new exports.InSandboxWatcher({
7191
7427
  sessionId,
7192
- sandboxOps: this.sandboxOps,
7193
- basePath: watchPath,
7194
- // Use watchPath instead of sandboxBasePath
7195
- pollIntervalMs: opts.pollIntervalMs ?? 2e3,
7196
- ignored: opts.ignored ?? ["**/node_modules/**", "**/.git/**"],
7428
+ watchPath,
7197
7429
  onFileChange: handleFileChange,
7198
7430
  onError: (error) => {
7199
- console.error(`[FILE_SYNC] Remote watcher error for session ${sessionId}:`, error);
7431
+ console.error(`[FILE_SYNC] In-sandbox watcher error for session ${sessionId}:`, error);
7200
7432
  }
7201
7433
  });
7202
7434
  await watcher.start();
7203
- this.remoteWatchers.set(sessionId, watcher);
7204
- console.log(`[FILE_SYNC] Started remote file watching for session ${sessionId} at path: ${watchPath}`);
7435
+ this.inSandboxWatchers.set(sessionId, watcher);
7436
+ console.log(`[FILE_SYNC] Started in-sandbox file watching for session ${sessionId} at path: ${watchPath}`);
7205
7437
  }
7206
7438
  }
7207
7439
  /**
7208
7440
  * Stop watching a session's sandbox
7209
7441
  */
7210
7442
  async stopWatching(sessionId) {
7211
- const remoteWatcher = this.remoteWatchers.get(sessionId);
7212
- if (remoteWatcher) {
7213
- await remoteWatcher.stop();
7214
- this.remoteWatchers.delete(sessionId);
7443
+ const inSandboxWatcher = this.inSandboxWatchers.get(sessionId);
7444
+ if (inSandboxWatcher) {
7445
+ await inSandboxWatcher.stop();
7446
+ this.inSandboxWatchers.delete(sessionId);
7215
7447
  }
7216
7448
  const localWatcher = this.localWatchers.get(sessionId);
7217
7449
  if (localWatcher) {
@@ -7223,7 +7455,7 @@ var init_sandbox_file_sync = __esm({
7223
7455
  * Check if a session is being watched
7224
7456
  */
7225
7457
  isWatching(sessionId) {
7226
- return this.remoteWatchers.has(sessionId) || this.localWatchers.has(sessionId);
7458
+ return this.inSandboxWatchers.has(sessionId) || this.localWatchers.has(sessionId);
7227
7459
  }
7228
7460
  /**
7229
7461
  * Subscribe to file change events across all watched sessions.
@@ -7257,10 +7489,10 @@ var init_sandbox_file_sync = __esm({
7257
7489
  * Stop all watchers and cleanup
7258
7490
  */
7259
7491
  async stopAllWatching() {
7260
- const remotePromises = Array.from(this.remoteWatchers.values()).map((w) => w.stop());
7492
+ const inSandboxPromises = Array.from(this.inSandboxWatchers.values()).map((w) => w.stop());
7261
7493
  const localPromises = Array.from(this.localWatchers.values()).map((w) => w.stop());
7262
- await Promise.all([...remotePromises, ...localPromises]);
7263
- this.remoteWatchers.clear();
7494
+ await Promise.all([...inSandboxPromises, ...localPromises]);
7495
+ this.inSandboxWatchers.clear();
7264
7496
  this.localWatchers.clear();
7265
7497
  }
7266
7498
  /**
@@ -7268,8 +7500,8 @@ var init_sandbox_file_sync = __esm({
7268
7500
  */
7269
7501
  getWatchingStatus() {
7270
7502
  const statuses = [];
7271
- for (const [sessionId, watcher] of this.remoteWatchers) {
7272
- statuses.push({ sessionId, type: "remote", isActive: watcher.isActive() });
7503
+ for (const [sessionId, watcher] of this.inSandboxWatchers) {
7504
+ statuses.push({ sessionId, type: "in-sandbox", isActive: watcher.isActive() });
7273
7505
  }
7274
7506
  for (const [sessionId, watcher] of this.localWatchers) {
7275
7507
  statuses.push({ sessionId, type: "local", isActive: watcher.isActive() });
@@ -7280,364 +7512,6 @@ var init_sandbox_file_sync = __esm({
7280
7512
  }
7281
7513
  });
7282
7514
 
7283
- // src/runtime/in-sandbox-watcher.ts
7284
- function createInSandboxWatcher(options) {
7285
- return new exports.InSandboxWatcher(options);
7286
- }
7287
- function getInSandboxWatcherManager() {
7288
- if (!globalInSandboxManager) {
7289
- globalInSandboxManager = new exports.InSandboxWatcherManager();
7290
- }
7291
- return globalInSandboxManager;
7292
- }
7293
- function createInSandboxWatcherManager() {
7294
- return new exports.InSandboxWatcherManager();
7295
- }
7296
- var WATCHER_SCRIPT; exports.InSandboxWatcher = void 0; exports.InSandboxWatcherManager = void 0; var globalInSandboxManager;
7297
- var init_in_sandbox_watcher = __esm({
7298
- "src/runtime/in-sandbox-watcher.ts"() {
7299
- init_vercel_sandbox_executor();
7300
- WATCHER_SCRIPT = `
7301
- const fs = require('fs');
7302
- const path = require('path');
7303
-
7304
- const watchPath = process.argv[2] || '.';
7305
- const ignored = new Set(['node_modules', '.git', '.cache', '__pycache__']);
7306
-
7307
- // Track all watchers for cleanup
7308
- const watchers = new Map();
7309
-
7310
- // Debounce map to coalesce rapid changes
7311
- const pending = new Map();
7312
- const DEBOUNCE_MS = 100;
7313
-
7314
- function emit(type, filePath) {
7315
- const event = {
7316
- type,
7317
- path: filePath,
7318
- timestamp: Date.now()
7319
- };
7320
- console.log(JSON.stringify(event));
7321
- }
7322
-
7323
- function shouldIgnore(name) {
7324
- return ignored.has(name) || name.startsWith('.');
7325
- }
7326
-
7327
- function watchDir(dir) {
7328
- try {
7329
- const watcher = fs.watch(dir, { persistent: true }, (eventType, filename) => {
7330
- if (!filename || shouldIgnore(filename)) return;
7331
-
7332
- const fullPath = path.join(dir, filename);
7333
- const key = fullPath;
7334
-
7335
- // Debounce
7336
- if (pending.has(key)) {
7337
- clearTimeout(pending.get(key));
7338
- }
7339
-
7340
- pending.set(key, setTimeout(() => {
7341
- pending.delete(key);
7342
-
7343
- fs.stat(fullPath, (err, stats) => {
7344
- if (err) {
7345
- if (err.code === 'ENOENT') {
7346
- emit('unlink', fullPath);
7347
- // Stop watching if it was a directory
7348
- if (watchers.has(fullPath)) {
7349
- watchers.get(fullPath).close();
7350
- watchers.delete(fullPath);
7351
- }
7352
- }
7353
- } else {
7354
- const type = eventType === 'rename' ? 'add' : 'change';
7355
- emit(type, fullPath);
7356
-
7357
- // If it's a new directory, start watching it
7358
- if (stats.isDirectory() && !watchers.has(fullPath)) {
7359
- watchDir(fullPath);
7360
- }
7361
- }
7362
- });
7363
- }, DEBOUNCE_MS));
7364
- });
7365
-
7366
- watchers.set(dir, watcher);
7367
-
7368
- // Watch subdirectories
7369
- const entries = fs.readdirSync(dir, { withFileTypes: true });
7370
- for (const entry of entries) {
7371
- if (entry.isDirectory() && !shouldIgnore(entry.name)) {
7372
- watchDir(path.join(dir, entry.name));
7373
- }
7374
- }
7375
- } catch (err) {
7376
- // Directory may not exist or be inaccessible
7377
- console.error(JSON.stringify({ error: err.message, dir }));
7378
- }
7379
- }
7380
-
7381
- // Start watching
7382
- watchDir(watchPath);
7383
-
7384
- // Keep alive
7385
- process.on('SIGTERM', () => {
7386
- for (const watcher of watchers.values()) {
7387
- watcher.close();
7388
- }
7389
- process.exit(0);
7390
- });
7391
-
7392
- // Heartbeat to indicate we're running
7393
- setInterval(() => {
7394
- console.log(JSON.stringify({ heartbeat: true, timestamp: Date.now() }));
7395
- }, 5000);
7396
-
7397
- console.log(JSON.stringify({ started: true, path: watchPath }));
7398
- `;
7399
- exports.InSandboxWatcher = class {
7400
- sessionId;
7401
- watchPath;
7402
- outputPollIntervalMs;
7403
- sandboxState = null;
7404
- outputPollTimer = null;
7405
- subscribers = /* @__PURE__ */ new Set();
7406
- isRunning = false;
7407
- startedAt;
7408
- lastHeartbeat;
7409
- lastOutputPosition = 0;
7410
- onError;
7411
- onReady;
7412
- constructor(options) {
7413
- this.sessionId = options.sessionId;
7414
- this.watchPath = options.watchPath;
7415
- this.outputPollIntervalMs = options.outputPollIntervalMs ?? 1e3;
7416
- this.onError = options.onError;
7417
- this.onReady = options.onReady;
7418
- if (options.onFileChange) {
7419
- this.subscribers.add(options.onFileChange);
7420
- }
7421
- }
7422
- /**
7423
- * Start the watcher process inside the sandbox
7424
- */
7425
- async start() {
7426
- if (this.isRunning) {
7427
- console.warn(`[IN_SANDBOX_WATCHER] Already running for session ${this.sessionId}`);
7428
- return;
7429
- }
7430
- try {
7431
- this.sandboxState = await getOrCreateSandbox({
7432
- sessionId: this.sessionId,
7433
- runtime: "node22",
7434
- timeout: 600
7435
- });
7436
- const { sandbox } = this.sandboxState;
7437
- const scriptPath = "/tmp/.file-watcher.js";
7438
- const outputPath = "/tmp/.file-watcher-output.log";
7439
- const writeScriptCmd = `cat > ${scriptPath} << 'WATCHER_EOF'
7440
- ${WATCHER_SCRIPT}
7441
- WATCHER_EOF`;
7442
- await sandbox.runCommand({
7443
- cmd: "sh",
7444
- args: ["-c", writeScriptCmd]
7445
- });
7446
- const startCmd = `nohup node ${scriptPath} "${this.watchPath}" > ${outputPath} 2>&1 &`;
7447
- await sandbox.runCommand({
7448
- cmd: "sh",
7449
- args: ["-c", startCmd]
7450
- });
7451
- console.log(`[IN_SANDBOX_WATCHER] Started watcher in sandbox for ${this.watchPath}`);
7452
- this.isRunning = true;
7453
- this.startedAt = /* @__PURE__ */ new Date();
7454
- this.outputPollTimer = setInterval(async () => {
7455
- try {
7456
- await this.pollOutput(outputPath);
7457
- } catch (error) {
7458
- console.error("[IN_SANDBOX_WATCHER] Error polling output:", error);
7459
- if (this.onError && error instanceof Error) {
7460
- this.onError(error);
7461
- }
7462
- }
7463
- }, this.outputPollIntervalMs);
7464
- setTimeout(() => {
7465
- this.pollOutput(outputPath).catch(console.error);
7466
- }, 500);
7467
- } catch (error) {
7468
- console.error(`[IN_SANDBOX_WATCHER] Failed to start watcher:`, error);
7469
- throw error;
7470
- }
7471
- }
7472
- /**
7473
- * Poll the output file for new events
7474
- */
7475
- async pollOutput(outputPath) {
7476
- if (!this.sandboxState?.sandbox) return;
7477
- try {
7478
- const result = await this.sandboxState.sandbox.runCommand({
7479
- cmd: "sh",
7480
- args: ["-c", `tail -c +${this.lastOutputPosition + 1} ${outputPath} 2>/dev/null || true`]
7481
- });
7482
- const output = await result.stdout();
7483
- if (output && output.trim()) {
7484
- const sizeResult = await this.sandboxState.sandbox.runCommand({
7485
- cmd: "sh",
7486
- args: ["-c", `stat -c%s ${outputPath} 2>/dev/null || echo 0`]
7487
- });
7488
- const sizeStr = await sizeResult.stdout();
7489
- this.lastOutputPosition = parseInt(sizeStr.trim(), 10) || 0;
7490
- this.processOutput(output);
7491
- }
7492
- } catch {
7493
- }
7494
- }
7495
- /**
7496
- * Process output from the watcher script
7497
- */
7498
- processOutput(stdout) {
7499
- const lines = stdout.split("\n").filter(Boolean);
7500
- for (const line of lines) {
7501
- try {
7502
- const data = JSON.parse(line);
7503
- if (data.started) {
7504
- console.log(`[IN_SANDBOX_WATCHER] Watcher started for ${data.path}`);
7505
- if (this.onReady) {
7506
- this.onReady();
7507
- }
7508
- } else if (data.heartbeat) {
7509
- this.lastHeartbeat = new Date(data.timestamp);
7510
- } else if (data.error) {
7511
- console.warn(`[IN_SANDBOX_WATCHER] Error in sandbox:`, data.error);
7512
- } else if (data.type && data.path) {
7513
- this.emitEvent({
7514
- type: data.type,
7515
- relativePath: data.path.replace(/^\.\//, ""),
7516
- absolutePath: data.path,
7517
- basePath: this.watchPath,
7518
- sessionId: this.sessionId,
7519
- timestamp: new Date(data.timestamp)
7520
- });
7521
- }
7522
- } catch {
7523
- }
7524
- }
7525
- }
7526
- /**
7527
- * Stop the watcher process
7528
- */
7529
- async stop() {
7530
- if (!this.isRunning) {
7531
- return;
7532
- }
7533
- if (this.outputPollTimer) {
7534
- clearInterval(this.outputPollTimer);
7535
- this.outputPollTimer = null;
7536
- }
7537
- try {
7538
- if (this.sandboxState?.sandbox) {
7539
- await this.sandboxState.sandbox.runCommand({
7540
- cmd: "sh",
7541
- args: ["-c", "pkill -f file-watcher.js 2>/dev/null || true"]
7542
- });
7543
- await this.sandboxState.sandbox.runCommand({
7544
- cmd: "sh",
7545
- args: ["-c", "rm -f /tmp/.file-watcher.js /tmp/.file-watcher-output.log"]
7546
- });
7547
- }
7548
- } catch {
7549
- }
7550
- this.isRunning = false;
7551
- this.sandboxState = null;
7552
- this.lastOutputPosition = 0;
7553
- console.log(`[IN_SANDBOX_WATCHER] Stopped watcher for session ${this.sessionId}`);
7554
- }
7555
- /**
7556
- * Subscribe to file change events
7557
- */
7558
- subscribe(callback) {
7559
- this.subscribers.add(callback);
7560
- return () => this.subscribers.delete(callback);
7561
- }
7562
- /**
7563
- * Check if watcher is running
7564
- */
7565
- isActive() {
7566
- return this.isRunning;
7567
- }
7568
- /**
7569
- * Get watcher status
7570
- */
7571
- getStatus() {
7572
- return {
7573
- sessionId: this.sessionId,
7574
- watchPath: this.watchPath,
7575
- isRunning: this.isRunning,
7576
- startedAt: this.startedAt,
7577
- lastHeartbeat: this.lastHeartbeat
7578
- };
7579
- }
7580
- /**
7581
- * Emit event to all subscribers
7582
- */
7583
- async emitEvent(event) {
7584
- for (const callback of this.subscribers) {
7585
- try {
7586
- await callback(event);
7587
- } catch (error) {
7588
- console.error("[IN_SANDBOX_WATCHER] Error in subscriber callback:", error);
7589
- }
7590
- }
7591
- }
7592
- };
7593
- exports.InSandboxWatcherManager = class {
7594
- watchers = /* @__PURE__ */ new Map();
7595
- /**
7596
- * Start watching a sandbox
7597
- */
7598
- async startWatching(options) {
7599
- const { sessionId } = options;
7600
- await this.stopWatching(sessionId);
7601
- const watcher = new exports.InSandboxWatcher(options);
7602
- await watcher.start();
7603
- this.watchers.set(sessionId, watcher);
7604
- return watcher;
7605
- }
7606
- /**
7607
- * Stop watching a session
7608
- */
7609
- async stopWatching(sessionId) {
7610
- const watcher = this.watchers.get(sessionId);
7611
- if (watcher) {
7612
- await watcher.stop();
7613
- this.watchers.delete(sessionId);
7614
- }
7615
- }
7616
- /**
7617
- * Get watcher for a session
7618
- */
7619
- getWatcher(sessionId) {
7620
- return this.watchers.get(sessionId);
7621
- }
7622
- /**
7623
- * Check if watching
7624
- */
7625
- isWatching(sessionId) {
7626
- return this.watchers.get(sessionId)?.isActive() ?? false;
7627
- }
7628
- /**
7629
- * Stop all watchers
7630
- */
7631
- async stopAll() {
7632
- const promises = Array.from(this.watchers.values()).map((w) => w.stop());
7633
- await Promise.all(promises);
7634
- this.watchers.clear();
7635
- }
7636
- };
7637
- globalInSandboxManager = null;
7638
- }
7639
- });
7640
-
7641
7515
  // src/runtime/index.ts
7642
7516
  function generateDockerCommand(config) {
7643
7517
  const args = ["docker", "run"];
@@ -8070,7 +7944,7 @@ var init_credentials = __esm({
8070
7944
  }
8071
7945
  });
8072
7946
  exports.gitHubSkillSourceSchema = void 0; exports.localSkillSourceSchema = void 0; exports.skillSourceSchema = void 0; exports.skillConfigSchema = void 0; exports.fileEntrySchema = void 0;
8073
- var init_types3 = __esm({
7947
+ var init_types4 = __esm({
8074
7948
  "src/skills/types.ts"() {
8075
7949
  exports.gitHubSkillSourceSchema = zod.z.object({
8076
7950
  type: zod.z.literal("github"),
@@ -8614,7 +8488,7 @@ var init_manager2 = __esm({
8614
8488
  // src/skills/index.ts
8615
8489
  var init_skills = __esm({
8616
8490
  "src/skills/index.ts"() {
8617
- init_types3();
8491
+ init_types4();
8618
8492
  init_local_provider();
8619
8493
  init_github_provider();
8620
8494
  init_manager2();
@@ -18134,7 +18008,7 @@ var init_storage3 = __esm({
18134
18008
  }
18135
18009
  if (options.filePath) {
18136
18010
  query = query.or(
18137
- `event_data->>filePath.eq.${options.filePath},and(category.eq.tool,tool_name.in.(Read,Write,Edit),event_data->input->>file_path.eq.${options.filePath})`
18011
+ `event_data->>filePath.eq.${options.filePath},event_data->>canonicalPath.eq.${options.filePath},and(category.eq.tool,tool_name.in.(Read,Write,Edit),event_data->input->>file_path.eq.${options.filePath})`
18138
18012
  );
18139
18013
  }
18140
18014
  const ascending = options.order !== "desc";
@@ -19064,8 +18938,6 @@ exports.createQueueProcessor = createQueueProcessor;
19064
18938
  exports.createQueueRouter = createQueueRouter;
19065
18939
  exports.createR2BundleStore = createR2BundleStore;
19066
18940
  exports.createR2FileStore = createR2FileStore;
19067
- exports.createRemoteFileWatcher = createRemoteFileWatcher;
19068
- exports.createRemoteFileWatcherManager = createRemoteFileWatcherManager;
19069
18941
  exports.createS3BundleStore = createS3BundleStore;
19070
18942
  exports.createS3FileStore = createS3FileStore;
19071
18943
  exports.createSandboxFileOperations = createSandboxFileOperations;
@@ -19091,6 +18963,7 @@ exports.defineConfig = defineConfig;
19091
18963
  exports.ensureSandboxPoolInitialized = ensureSandboxPoolInitialized;
19092
18964
  exports.env = env;
19093
18965
  exports.envOptional = envOptional;
18966
+ exports.executeCommandInSandbox = executeCommandInSandbox;
19094
18967
  exports.extractTextContent = extractTextContent;
19095
18968
  exports.extractTextFromMessage = extractTextFromMessage;
19096
18969
  exports.formatToolName = formatToolName;
@@ -19103,12 +18976,12 @@ exports.getActionIcon = getActionIcon;
19103
18976
  exports.getActionLabel = getActionLabel;
19104
18977
  exports.getAllHeartbeatStatuses = getAllHeartbeatStatuses;
19105
18978
  exports.getApiKeyEnvVar = getApiKeyEnvVar;
18979
+ exports.getCachedSandbox = getCachedSandbox;
19106
18980
  exports.getDefaultModel = getDefaultModel;
19107
18981
  exports.getFileWatcherManager = getFileWatcherManager;
19108
18982
  exports.getHeartbeatStatus = getHeartbeatStatus;
19109
18983
  exports.getInSandboxWatcherManager = getInSandboxWatcherManager;
19110
18984
  exports.getOrCreateSandbox = getOrCreateSandbox;
19111
- exports.getRemoteFileWatcherManager = getRemoteFileWatcherManager;
19112
18985
  exports.getSandboxCacheStats = getSandboxCacheStats;
19113
18986
  exports.getSandboxPool = getSandboxPool;
19114
18987
  exports.getWorkspaceManager = getWorkspaceManager;