@ash-cloud/ash-ai 0.1.13 → 0.1.15

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.js CHANGED
@@ -5261,6 +5261,23 @@ function isSandboxRunning(sessionId) {
5261
5261
  const cached = sandboxCache.get(sessionId);
5262
5262
  return cached !== void 0 && !cached.isExpired;
5263
5263
  }
5264
+ function getCachedSandbox(sessionId) {
5265
+ const cached = sandboxCache.get(sessionId);
5266
+ if (!cached || cached.isExpired) {
5267
+ return null;
5268
+ }
5269
+ cached.lastUsedAt = Date.now();
5270
+ return {
5271
+ sandbox: cached.sandbox,
5272
+ sandboxId: cached.sandbox.sandboxId,
5273
+ sdkInstalled: cached.sdkInstalled,
5274
+ startupScriptRan: cached.startupScriptRan,
5275
+ startupScriptHash: cached.startupScriptHash,
5276
+ isNew: false,
5277
+ configFileUrl: cached.configFileUrl,
5278
+ configInstalledAt: cached.configInstalledAt
5279
+ };
5280
+ }
5264
5281
  async function writeFileToSandbox(sessionId, path15, content) {
5265
5282
  const cached = sandboxCache.get(sessionId);
5266
5283
  if (!cached) {
@@ -5329,6 +5346,54 @@ async function readFileFromSandbox(sessionId, path15) {
5329
5346
  };
5330
5347
  }
5331
5348
  }
5349
+ async function executeCommandInSandbox(sessionId, command, options) {
5350
+ const cached = sandboxCache.get(sessionId);
5351
+ if (!cached) {
5352
+ return { success: false, error: "No active sandbox for session" };
5353
+ }
5354
+ if (cached.isExpired) {
5355
+ return { success: false, error: "Sandbox has expired" };
5356
+ }
5357
+ const startTime = Date.now();
5358
+ try {
5359
+ const sandbox = cached.sandbox;
5360
+ let fullCommand = command;
5361
+ if (options?.cwd) {
5362
+ fullCommand = `cd ${JSON.stringify(options.cwd)} && ${command}`;
5363
+ }
5364
+ const result = await sandbox.runCommand({
5365
+ cmd: "bash",
5366
+ args: ["-c", fullCommand],
5367
+ env: options?.env
5368
+ });
5369
+ const stdout = await result.stdout();
5370
+ const stderr = await result.stderr();
5371
+ const durationMs = Date.now() - startTime;
5372
+ cached.lastUsedAt = Date.now();
5373
+ return {
5374
+ success: result.exitCode === 0,
5375
+ exitCode: result.exitCode,
5376
+ stdout,
5377
+ stderr,
5378
+ durationMs
5379
+ };
5380
+ } catch (error) {
5381
+ const durationMs = Date.now() - startTime;
5382
+ if (isSandboxExpiredError(error)) {
5383
+ cached.isExpired = true;
5384
+ return {
5385
+ success: false,
5386
+ error: "Sandbox has expired",
5387
+ durationMs
5388
+ };
5389
+ }
5390
+ return {
5391
+ success: false,
5392
+ error: error instanceof Error ? error.message : "Unknown error",
5393
+ durationMs
5394
+ };
5395
+ }
5396
+ }
5332
5397
  async function listFilesInSandbox(sessionId, path15) {
5333
5398
  const cached = sandboxCache.get(sessionId);
5334
5399
  if (!cached) {
@@ -5808,19 +5873,7 @@ function getFileWatcherManager() {
5808
5873
  function createFileWatcherManager() {
5809
5874
  return new FileWatcherManager();
5810
5875
  }
5811
- function createRemoteFileWatcher(options) {
5812
- return new RemoteSandboxFileWatcher(options);
5813
- }
5814
- function getRemoteFileWatcherManager() {
5815
- if (!globalRemoteWatcherManager) {
5816
- globalRemoteWatcherManager = new RemoteFileWatcherManager();
5817
- }
5818
- return globalRemoteWatcherManager;
5819
- }
5820
- function createRemoteFileWatcherManager() {
5821
- return new RemoteFileWatcherManager();
5822
- }
5823
- var SandboxFileWatcher, FileWatcherManager, globalWatcherManager, RemoteSandboxFileWatcher, RemoteFileWatcherManager, globalRemoteWatcherManager;
5876
+ var SandboxFileWatcher, FileWatcherManager, globalWatcherManager;
5824
5877
  var init_sandbox_file_watcher = __esm({
5825
5878
  "src/runtime/sandbox-file-watcher.ts"() {
5826
5879
  SandboxFileWatcher = class {
@@ -6062,214 +6115,327 @@ var init_sandbox_file_watcher = __esm({
6062
6115
  }
6063
6116
  };
6064
6117
  globalWatcherManager = null;
6065
- RemoteSandboxFileWatcher = class {
6118
+ }
6119
+ });
6120
+
6121
+ // src/runtime/in-sandbox-watcher.ts
6122
+ function createInSandboxWatcher(options) {
6123
+ return new InSandboxWatcher(options);
6124
+ }
6125
+ function getInSandboxWatcherManager() {
6126
+ if (!globalInSandboxManager) {
6127
+ globalInSandboxManager = new InSandboxWatcherManager();
6128
+ }
6129
+ return globalInSandboxManager;
6130
+ }
6131
+ function createInSandboxWatcherManager() {
6132
+ return new InSandboxWatcherManager();
6133
+ }
6134
+ var WATCHER_SCRIPT, InSandboxWatcher, InSandboxWatcherManager, globalInSandboxManager;
6135
+ var init_in_sandbox_watcher = __esm({
6136
+ "src/runtime/in-sandbox-watcher.ts"() {
6137
+ init_vercel_sandbox_executor();
6138
+ WATCHER_SCRIPT = `
6139
+ const fs = require('fs');
6140
+ const path = require('path');
6141
+
6142
+ const watchPath = process.argv[2] || '.';
6143
+ const ignored = new Set(['node_modules', '.git', '.cache', '__pycache__']);
6144
+
6145
+ // Track all watchers for cleanup
6146
+ const watchers = new Map();
6147
+
6148
+ // Debounce map to coalesce rapid changes
6149
+ const pending = new Map();
6150
+ const DEBOUNCE_MS = 100;
6151
+
6152
+ function emit(type, filePath) {
6153
+ const event = {
6154
+ type,
6155
+ path: filePath,
6156
+ timestamp: Date.now()
6157
+ };
6158
+ console.log(JSON.stringify(event));
6159
+ }
6160
+
6161
+ function shouldIgnore(name) {
6162
+ return ignored.has(name) || name.startsWith('.');
6163
+ }
6164
+
6165
+ function watchDir(dir) {
6166
+ try {
6167
+ const watcher = fs.watch(dir, { persistent: true }, (eventType, filename) => {
6168
+ if (!filename || shouldIgnore(filename)) return;
6169
+
6170
+ const fullPath = path.join(dir, filename);
6171
+ const key = fullPath;
6172
+
6173
+ // Debounce
6174
+ if (pending.has(key)) {
6175
+ clearTimeout(pending.get(key));
6176
+ }
6177
+
6178
+ pending.set(key, setTimeout(() => {
6179
+ pending.delete(key);
6180
+
6181
+ fs.stat(fullPath, (err, stats) => {
6182
+ if (err) {
6183
+ if (err.code === 'ENOENT') {
6184
+ emit('unlink', fullPath);
6185
+ // Stop watching if it was a directory
6186
+ if (watchers.has(fullPath)) {
6187
+ watchers.get(fullPath).close();
6188
+ watchers.delete(fullPath);
6189
+ }
6190
+ }
6191
+ } else {
6192
+ const type = eventType === 'rename' ? 'add' : 'change';
6193
+ emit(type, fullPath);
6194
+
6195
+ // If it's a new directory, start watching it
6196
+ if (stats.isDirectory() && !watchers.has(fullPath)) {
6197
+ watchDir(fullPath);
6198
+ }
6199
+ }
6200
+ });
6201
+ }, DEBOUNCE_MS));
6202
+ });
6203
+
6204
+ watchers.set(dir, watcher);
6205
+
6206
+ // Watch subdirectories
6207
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
6208
+ for (const entry of entries) {
6209
+ if (entry.isDirectory() && !shouldIgnore(entry.name)) {
6210
+ watchDir(path.join(dir, entry.name));
6211
+ }
6212
+ }
6213
+ } catch (err) {
6214
+ // Directory may not exist or be inaccessible
6215
+ console.error(JSON.stringify({ error: err.message, dir }));
6216
+ }
6217
+ }
6218
+
6219
+ // Start watching
6220
+ watchDir(watchPath);
6221
+
6222
+ // Keep alive
6223
+ process.on('SIGTERM', () => {
6224
+ for (const watcher of watchers.values()) {
6225
+ watcher.close();
6226
+ }
6227
+ process.exit(0);
6228
+ });
6229
+
6230
+ // Heartbeat to indicate we're running
6231
+ setInterval(() => {
6232
+ console.log(JSON.stringify({ heartbeat: true, timestamp: Date.now() }));
6233
+ }, 5000);
6234
+
6235
+ console.log(JSON.stringify({ started: true, path: watchPath }));
6236
+ `;
6237
+ InSandboxWatcher = class {
6066
6238
  sessionId;
6067
- sandboxOps;
6068
- basePath;
6069
- pollIntervalMs;
6070
- ignored;
6071
- pollTimer = null;
6072
- previousFiles = /* @__PURE__ */ new Map();
6239
+ watchPath;
6240
+ outputPollIntervalMs;
6241
+ sandboxState = null;
6242
+ outputPollTimer = null;
6073
6243
  subscribers = /* @__PURE__ */ new Set();
6074
- isWatching = false;
6244
+ isRunning = false;
6075
6245
  startedAt;
6076
- lastPollAt;
6077
- pollCount = 0;
6246
+ lastHeartbeat;
6247
+ lastOutputPosition = 0;
6078
6248
  onError;
6249
+ onReady;
6079
6250
  constructor(options) {
6080
6251
  this.sessionId = options.sessionId;
6081
- this.sandboxOps = options.sandboxOps;
6082
- this.basePath = options.basePath;
6083
- this.pollIntervalMs = options.pollIntervalMs ?? 2e3;
6084
- this.ignored = options.ignored ?? ["**/node_modules/**", "**/.git/**"];
6252
+ this.watchPath = options.watchPath;
6253
+ this.outputPollIntervalMs = options.outputPollIntervalMs ?? 1e3;
6085
6254
  this.onError = options.onError;
6255
+ this.onReady = options.onReady;
6086
6256
  if (options.onFileChange) {
6087
6257
  this.subscribers.add(options.onFileChange);
6088
6258
  }
6089
6259
  }
6090
6260
  /**
6091
- * Start polling for file changes
6261
+ * Start the watcher process inside the sandbox
6092
6262
  */
6093
6263
  async start() {
6094
- if (this.isWatching) {
6095
- console.warn(`[REMOTE_WATCHER] Already watching session ${this.sessionId}`);
6264
+ if (this.isRunning) {
6265
+ console.warn(`[IN_SANDBOX_WATCHER] Already running for session ${this.sessionId}`);
6096
6266
  return;
6097
6267
  }
6098
- if (!this.sandboxOps.isSandboxRunning(this.sessionId)) {
6099
- throw new Error(`Sandbox is not running for session ${this.sessionId}`);
6100
- }
6101
- await this.scan(true);
6102
- this.pollTimer = setInterval(async () => {
6103
- try {
6104
- await this.scan(false);
6105
- } catch (error) {
6106
- console.error(`[REMOTE_WATCHER] Poll error for session ${this.sessionId}:`, error);
6107
- if (this.onError && error instanceof Error) {
6108
- this.onError(error);
6109
- }
6268
+ try {
6269
+ this.sandboxState = getCachedSandbox(this.sessionId);
6270
+ if (!this.sandboxState) {
6271
+ throw new Error(`No active sandbox found for session ${this.sessionId}. Sandbox must be created before starting file watcher.`);
6110
6272
  }
6111
- }, this.pollIntervalMs);
6112
- this.isWatching = true;
6113
- this.startedAt = /* @__PURE__ */ new Date();
6114
- console.log(`[REMOTE_WATCHER] Started watching session ${this.sessionId} at ${this.basePath}`);
6115
- }
6116
- /**
6117
- * Stop polling and cleanup
6118
- */
6119
- async stop() {
6120
- if (!this.isWatching) {
6121
- return;
6122
- }
6123
- if (this.pollTimer) {
6124
- clearInterval(this.pollTimer);
6125
- this.pollTimer = null;
6273
+ const { sandbox } = this.sandboxState;
6274
+ const scriptPath = "/tmp/.file-watcher.js";
6275
+ const outputPath = "/tmp/.file-watcher-output.log";
6276
+ const writeScriptCmd = `cat > ${scriptPath} << 'WATCHER_EOF'
6277
+ ${WATCHER_SCRIPT}
6278
+ WATCHER_EOF`;
6279
+ await sandbox.runCommand({
6280
+ cmd: "sh",
6281
+ args: ["-c", writeScriptCmd]
6282
+ });
6283
+ const startCmd = `nohup node ${scriptPath} "${this.watchPath}" > ${outputPath} 2>&1 &`;
6284
+ await sandbox.runCommand({
6285
+ cmd: "sh",
6286
+ args: ["-c", startCmd]
6287
+ });
6288
+ console.log(`[IN_SANDBOX_WATCHER] Started watcher in sandbox for ${this.watchPath}`);
6289
+ this.isRunning = true;
6290
+ this.startedAt = /* @__PURE__ */ new Date();
6291
+ this.outputPollTimer = setInterval(async () => {
6292
+ try {
6293
+ await this.pollOutput(outputPath);
6294
+ } catch (error) {
6295
+ console.error("[IN_SANDBOX_WATCHER] Error polling output:", error);
6296
+ if (this.onError && error instanceof Error) {
6297
+ this.onError(error);
6298
+ }
6299
+ }
6300
+ }, this.outputPollIntervalMs);
6301
+ setTimeout(() => {
6302
+ this.pollOutput(outputPath).catch(console.error);
6303
+ }, 500);
6304
+ } catch (error) {
6305
+ console.error(`[IN_SANDBOX_WATCHER] Failed to start watcher:`, error);
6306
+ throw error;
6126
6307
  }
6127
- this.isWatching = false;
6128
- this.previousFiles.clear();
6129
- console.log(`[REMOTE_WATCHER] Stopped watching session ${this.sessionId}`);
6130
- }
6131
- /**
6132
- * Subscribe to file change events
6133
- */
6134
- subscribe(callback) {
6135
- this.subscribers.add(callback);
6136
- return () => this.subscribers.delete(callback);
6137
6308
  }
6138
6309
  /**
6139
- * Remove a subscriber
6310
+ * Poll the output file for new events
6140
6311
  */
6141
- unsubscribe(callback) {
6142
- this.subscribers.delete(callback);
6312
+ async pollOutput(outputPath) {
6313
+ if (!this.sandboxState?.sandbox) return;
6314
+ try {
6315
+ const result = await this.sandboxState.sandbox.runCommand({
6316
+ cmd: "sh",
6317
+ args: ["-c", `tail -c +${this.lastOutputPosition + 1} ${outputPath} 2>/dev/null || true`]
6318
+ });
6319
+ const output = await result.stdout();
6320
+ if (output && output.trim()) {
6321
+ const sizeResult = await this.sandboxState.sandbox.runCommand({
6322
+ cmd: "sh",
6323
+ args: ["-c", `stat -c%s ${outputPath} 2>/dev/null || echo 0`]
6324
+ });
6325
+ const sizeStr = await sizeResult.stdout();
6326
+ this.lastOutputPosition = parseInt(sizeStr.trim(), 10) || 0;
6327
+ this.processOutput(output);
6328
+ }
6329
+ } catch {
6330
+ }
6143
6331
  }
6144
6332
  /**
6145
- * Check if watcher is active
6333
+ * Process output from the watcher script
6146
6334
  */
6147
- isActive() {
6148
- return this.isWatching;
6149
- }
6150
- /**
6151
- * Get watcher status
6152
- */
6153
- getStatus() {
6154
- return {
6155
- sessionId: this.sessionId,
6156
- watchPath: this.basePath,
6157
- isWatching: this.isWatching,
6158
- watchedFileCount: this.previousFiles.size,
6159
- pendingEventCount: 0,
6160
- startedAt: this.startedAt,
6161
- lastPollAt: this.lastPollAt,
6162
- pollCount: this.pollCount
6163
- };
6164
- }
6165
- /**
6166
- * Force an immediate scan (useful for testing or manual refresh)
6167
- */
6168
- async forceScan() {
6169
- await this.scan(false);
6335
+ processOutput(stdout) {
6336
+ const lines = stdout.split("\n").filter(Boolean);
6337
+ for (const line of lines) {
6338
+ try {
6339
+ const data = JSON.parse(line);
6340
+ if (data.started) {
6341
+ console.log(`[IN_SANDBOX_WATCHER] Watcher started for ${data.path}`);
6342
+ if (this.onReady) {
6343
+ this.onReady();
6344
+ }
6345
+ } else if (data.heartbeat) {
6346
+ this.lastHeartbeat = new Date(data.timestamp);
6347
+ } else if (data.error) {
6348
+ console.warn(`[IN_SANDBOX_WATCHER] Error in sandbox:`, data.error);
6349
+ } else if (data.type && data.path) {
6350
+ this.emitEvent({
6351
+ type: data.type,
6352
+ relativePath: data.path.replace(/^\.\//, ""),
6353
+ absolutePath: data.path,
6354
+ basePath: this.watchPath,
6355
+ sessionId: this.sessionId,
6356
+ timestamp: new Date(data.timestamp)
6357
+ });
6358
+ }
6359
+ } catch {
6360
+ }
6361
+ }
6170
6362
  }
6171
6363
  /**
6172
- * Scan the sandbox for file changes
6364
+ * Stop the watcher process
6173
6365
  */
6174
- async scan(isInitial) {
6175
- if (!this.sandboxOps.isSandboxRunning(this.sessionId)) {
6176
- console.warn(`[REMOTE_WATCHER] Sandbox stopped for session ${this.sessionId}`);
6177
- await this.stop();
6366
+ async stop() {
6367
+ if (!this.isRunning) {
6178
6368
  return;
6179
6369
  }
6180
- const listResult = await this.sandboxOps.listFiles(this.sessionId, this.basePath);
6181
- if (!listResult.success || !listResult.files) {
6182
- throw new Error(listResult.error ?? "Failed to list files in sandbox");
6183
- }
6184
- const currentFiles = /* @__PURE__ */ new Map();
6185
- for (const filePath of listResult.files) {
6186
- if (this.shouldIgnore(filePath)) {
6187
- continue;
6188
- }
6189
- currentFiles.set(filePath, { path: filePath });
6190
- }
6191
- this.lastPollAt = /* @__PURE__ */ new Date();
6192
- this.pollCount++;
6193
- if (isInitial) {
6194
- this.previousFiles = currentFiles;
6195
- return;
6370
+ if (this.outputPollTimer) {
6371
+ clearInterval(this.outputPollTimer);
6372
+ this.outputPollTimer = null;
6196
6373
  }
6197
- const changes = [];
6198
- for (const [filePath, info] of currentFiles) {
6199
- const previous = this.previousFiles.get(filePath);
6200
- if (!previous) {
6201
- changes.push({
6202
- type: "add",
6203
- relativePath: filePath,
6204
- absolutePath: `${this.basePath}/${filePath}`,
6205
- basePath: this.basePath,
6206
- sessionId: this.sessionId,
6207
- fileSize: info.size,
6208
- timestamp: /* @__PURE__ */ new Date()
6374
+ try {
6375
+ if (this.sandboxState?.sandbox) {
6376
+ await this.sandboxState.sandbox.runCommand({
6377
+ cmd: "sh",
6378
+ args: ["-c", "pkill -f file-watcher.js 2>/dev/null || true"]
6209
6379
  });
6210
- }
6211
- }
6212
- for (const [filePath] of this.previousFiles) {
6213
- if (!currentFiles.has(filePath)) {
6214
- changes.push({
6215
- type: "unlink",
6216
- relativePath: filePath,
6217
- absolutePath: `${this.basePath}/${filePath}`,
6218
- basePath: this.basePath,
6219
- sessionId: this.sessionId,
6220
- timestamp: /* @__PURE__ */ new Date()
6380
+ await this.sandboxState.sandbox.runCommand({
6381
+ cmd: "sh",
6382
+ args: ["-c", "rm -f /tmp/.file-watcher.js /tmp/.file-watcher-output.log"]
6221
6383
  });
6222
6384
  }
6385
+ } catch {
6223
6386
  }
6224
- this.previousFiles = currentFiles;
6225
- for (const event of changes) {
6226
- await this.emitEvent(event);
6227
- }
6387
+ this.isRunning = false;
6388
+ this.sandboxState = null;
6389
+ this.lastOutputPosition = 0;
6390
+ console.log(`[IN_SANDBOX_WATCHER] Stopped watcher for session ${this.sessionId}`);
6228
6391
  }
6229
6392
  /**
6230
- * Check if a path should be ignored
6393
+ * Subscribe to file change events
6231
6394
  */
6232
- shouldIgnore(filePath) {
6233
- for (const pattern of this.ignored) {
6234
- if (this.matchesGlob(filePath, pattern)) {
6235
- return true;
6236
- }
6237
- }
6238
- return false;
6395
+ subscribe(callback) {
6396
+ this.subscribers.add(callback);
6397
+ return () => this.subscribers.delete(callback);
6239
6398
  }
6240
6399
  /**
6241
- * Simple glob matching (supports ** and *)
6400
+ * Check if watcher is running
6242
6401
  */
6243
- matchesGlob(filePath, pattern) {
6244
- const regexPattern = pattern.replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/{{GLOBSTAR}}/g, ".*").replace(/\//g, "\\/");
6245
- const regex = new RegExp(`^${regexPattern}$`);
6246
- return regex.test(filePath);
6402
+ isActive() {
6403
+ return this.isRunning;
6247
6404
  }
6248
6405
  /**
6249
- * Emit a file change event to all subscribers
6406
+ * Get watcher status
6407
+ */
6408
+ getStatus() {
6409
+ return {
6410
+ sessionId: this.sessionId,
6411
+ watchPath: this.watchPath,
6412
+ isRunning: this.isRunning,
6413
+ startedAt: this.startedAt,
6414
+ lastHeartbeat: this.lastHeartbeat
6415
+ };
6416
+ }
6417
+ /**
6418
+ * Emit event to all subscribers
6250
6419
  */
6251
6420
  async emitEvent(event) {
6252
6421
  for (const callback of this.subscribers) {
6253
6422
  try {
6254
6423
  await callback(event);
6255
6424
  } catch (error) {
6256
- console.error("[REMOTE_WATCHER] Error in subscriber callback:", error);
6425
+ console.error("[IN_SANDBOX_WATCHER] Error in subscriber callback:", error);
6257
6426
  }
6258
6427
  }
6259
6428
  }
6260
6429
  };
6261
- RemoteFileWatcherManager = class {
6430
+ InSandboxWatcherManager = class {
6262
6431
  watchers = /* @__PURE__ */ new Map();
6263
6432
  /**
6264
- * Start watching a session's sandbox
6433
+ * Start watching a sandbox
6265
6434
  */
6266
6435
  async startWatching(options) {
6267
6436
  const { sessionId } = options;
6268
- const existing = this.watchers.get(sessionId);
6269
- if (existing) {
6270
- await existing.stop();
6271
- }
6272
- const watcher = new RemoteSandboxFileWatcher(options);
6437
+ await this.stopWatching(sessionId);
6438
+ const watcher = new InSandboxWatcher(options);
6273
6439
  await watcher.start();
6274
6440
  this.watchers.set(sessionId, watcher);
6275
6441
  return watcher;
@@ -6285,17 +6451,16 @@ var init_sandbox_file_watcher = __esm({
6285
6451
  }
6286
6452
  }
6287
6453
  /**
6288
- * Get a watcher for a session
6454
+ * Get watcher for a session
6289
6455
  */
6290
6456
  getWatcher(sessionId) {
6291
6457
  return this.watchers.get(sessionId);
6292
6458
  }
6293
6459
  /**
6294
- * Check if a session is being watched
6460
+ * Check if watching
6295
6461
  */
6296
6462
  isWatching(sessionId) {
6297
- const watcher = this.watchers.get(sessionId);
6298
- return watcher?.isActive() ?? false;
6463
+ return this.watchers.get(sessionId)?.isActive() ?? false;
6299
6464
  }
6300
6465
  /**
6301
6466
  * Stop all watchers
@@ -6306,7 +6471,7 @@ var init_sandbox_file_watcher = __esm({
6306
6471
  this.watchers.clear();
6307
6472
  }
6308
6473
  };
6309
- globalRemoteWatcherManager = null;
6474
+ globalInSandboxManager = null;
6310
6475
  }
6311
6476
  });
6312
6477
  function extractErrorMessage(error) {
@@ -6355,6 +6520,7 @@ var SandboxFileSync;
6355
6520
  var init_sandbox_file_sync = __esm({
6356
6521
  "src/runtime/sandbox-file-sync.ts"() {
6357
6522
  init_sandbox_file_watcher();
6523
+ init_in_sandbox_watcher();
6358
6524
  init_types();
6359
6525
  SandboxFileSync = class {
6360
6526
  fileStore;
@@ -6365,7 +6531,7 @@ var init_sandbox_file_sync = __esm({
6365
6531
  eventStorage;
6366
6532
  webhookConfig;
6367
6533
  // Watcher management
6368
- remoteWatchers = /* @__PURE__ */ new Map();
6534
+ inSandboxWatchers = /* @__PURE__ */ new Map();
6369
6535
  localWatchers = /* @__PURE__ */ new Map();
6370
6536
  fileChangeSubscribers = /* @__PURE__ */ new Set();
6371
6537
  // Sequence number cache per session (for event storage)
@@ -7156,34 +7322,27 @@ var init_sandbox_file_sync = __esm({
7156
7322
  this.localWatchers.set(sessionId, watcher);
7157
7323
  console.log(`[FILE_SYNC] Started local file watching for session ${sessionId} at ${opts.localPath}`);
7158
7324
  } else {
7159
- if (!this.sandboxOps) {
7160
- throw new Error("Sandbox operations not configured. Call setSandboxOperations first.");
7161
- }
7162
- const watcher = new RemoteSandboxFileWatcher({
7325
+ const watcher = new InSandboxWatcher({
7163
7326
  sessionId,
7164
- sandboxOps: this.sandboxOps,
7165
- basePath: watchPath,
7166
- // Use watchPath instead of sandboxBasePath
7167
- pollIntervalMs: opts.pollIntervalMs ?? 2e3,
7168
- ignored: opts.ignored ?? ["**/node_modules/**", "**/.git/**"],
7327
+ watchPath,
7169
7328
  onFileChange: handleFileChange,
7170
7329
  onError: (error) => {
7171
- console.error(`[FILE_SYNC] Remote watcher error for session ${sessionId}:`, error);
7330
+ console.error(`[FILE_SYNC] In-sandbox watcher error for session ${sessionId}:`, error);
7172
7331
  }
7173
7332
  });
7174
7333
  await watcher.start();
7175
- this.remoteWatchers.set(sessionId, watcher);
7176
- console.log(`[FILE_SYNC] Started remote file watching for session ${sessionId} at path: ${watchPath}`);
7334
+ this.inSandboxWatchers.set(sessionId, watcher);
7335
+ console.log(`[FILE_SYNC] Started in-sandbox file watching for session ${sessionId} at path: ${watchPath}`);
7177
7336
  }
7178
7337
  }
7179
7338
  /**
7180
7339
  * Stop watching a session's sandbox
7181
7340
  */
7182
7341
  async stopWatching(sessionId) {
7183
- const remoteWatcher = this.remoteWatchers.get(sessionId);
7184
- if (remoteWatcher) {
7185
- await remoteWatcher.stop();
7186
- this.remoteWatchers.delete(sessionId);
7342
+ const inSandboxWatcher = this.inSandboxWatchers.get(sessionId);
7343
+ if (inSandboxWatcher) {
7344
+ await inSandboxWatcher.stop();
7345
+ this.inSandboxWatchers.delete(sessionId);
7187
7346
  }
7188
7347
  const localWatcher = this.localWatchers.get(sessionId);
7189
7348
  if (localWatcher) {
@@ -7195,7 +7354,7 @@ var init_sandbox_file_sync = __esm({
7195
7354
  * Check if a session is being watched
7196
7355
  */
7197
7356
  isWatching(sessionId) {
7198
- return this.remoteWatchers.has(sessionId) || this.localWatchers.has(sessionId);
7357
+ return this.inSandboxWatchers.has(sessionId) || this.localWatchers.has(sessionId);
7199
7358
  }
7200
7359
  /**
7201
7360
  * Subscribe to file change events across all watched sessions.
@@ -7229,10 +7388,10 @@ var init_sandbox_file_sync = __esm({
7229
7388
  * Stop all watchers and cleanup
7230
7389
  */
7231
7390
  async stopAllWatching() {
7232
- const remotePromises = Array.from(this.remoteWatchers.values()).map((w) => w.stop());
7391
+ const inSandboxPromises = Array.from(this.inSandboxWatchers.values()).map((w) => w.stop());
7233
7392
  const localPromises = Array.from(this.localWatchers.values()).map((w) => w.stop());
7234
- await Promise.all([...remotePromises, ...localPromises]);
7235
- this.remoteWatchers.clear();
7393
+ await Promise.all([...inSandboxPromises, ...localPromises]);
7394
+ this.inSandboxWatchers.clear();
7236
7395
  this.localWatchers.clear();
7237
7396
  }
7238
7397
  /**
@@ -7240,8 +7399,8 @@ var init_sandbox_file_sync = __esm({
7240
7399
  */
7241
7400
  getWatchingStatus() {
7242
7401
  const statuses = [];
7243
- for (const [sessionId, watcher] of this.remoteWatchers) {
7244
- statuses.push({ sessionId, type: "remote", isActive: watcher.isActive() });
7402
+ for (const [sessionId, watcher] of this.inSandboxWatchers) {
7403
+ statuses.push({ sessionId, type: "in-sandbox", isActive: watcher.isActive() });
7245
7404
  }
7246
7405
  for (const [sessionId, watcher] of this.localWatchers) {
7247
7406
  statuses.push({ sessionId, type: "local", isActive: watcher.isActive() });
@@ -7252,364 +7411,6 @@ var init_sandbox_file_sync = __esm({
7252
7411
  }
7253
7412
  });
7254
7413
 
7255
- // src/runtime/in-sandbox-watcher.ts
7256
- function createInSandboxWatcher(options) {
7257
- return new InSandboxWatcher(options);
7258
- }
7259
- function getInSandboxWatcherManager() {
7260
- if (!globalInSandboxManager) {
7261
- globalInSandboxManager = new InSandboxWatcherManager();
7262
- }
7263
- return globalInSandboxManager;
7264
- }
7265
- function createInSandboxWatcherManager() {
7266
- return new InSandboxWatcherManager();
7267
- }
7268
- var WATCHER_SCRIPT, InSandboxWatcher, InSandboxWatcherManager, globalInSandboxManager;
7269
- var init_in_sandbox_watcher = __esm({
7270
- "src/runtime/in-sandbox-watcher.ts"() {
7271
- init_vercel_sandbox_executor();
7272
- WATCHER_SCRIPT = `
7273
- const fs = require('fs');
7274
- const path = require('path');
7275
-
7276
- const watchPath = process.argv[2] || '.';
7277
- const ignored = new Set(['node_modules', '.git', '.cache', '__pycache__']);
7278
-
7279
- // Track all watchers for cleanup
7280
- const watchers = new Map();
7281
-
7282
- // Debounce map to coalesce rapid changes
7283
- const pending = new Map();
7284
- const DEBOUNCE_MS = 100;
7285
-
7286
- function emit(type, filePath) {
7287
- const event = {
7288
- type,
7289
- path: filePath,
7290
- timestamp: Date.now()
7291
- };
7292
- console.log(JSON.stringify(event));
7293
- }
7294
-
7295
- function shouldIgnore(name) {
7296
- return ignored.has(name) || name.startsWith('.');
7297
- }
7298
-
7299
- function watchDir(dir) {
7300
- try {
7301
- const watcher = fs.watch(dir, { persistent: true }, (eventType, filename) => {
7302
- if (!filename || shouldIgnore(filename)) return;
7303
-
7304
- const fullPath = path.join(dir, filename);
7305
- const key = fullPath;
7306
-
7307
- // Debounce
7308
- if (pending.has(key)) {
7309
- clearTimeout(pending.get(key));
7310
- }
7311
-
7312
- pending.set(key, setTimeout(() => {
7313
- pending.delete(key);
7314
-
7315
- fs.stat(fullPath, (err, stats) => {
7316
- if (err) {
7317
- if (err.code === 'ENOENT') {
7318
- emit('unlink', fullPath);
7319
- // Stop watching if it was a directory
7320
- if (watchers.has(fullPath)) {
7321
- watchers.get(fullPath).close();
7322
- watchers.delete(fullPath);
7323
- }
7324
- }
7325
- } else {
7326
- const type = eventType === 'rename' ? 'add' : 'change';
7327
- emit(type, fullPath);
7328
-
7329
- // If it's a new directory, start watching it
7330
- if (stats.isDirectory() && !watchers.has(fullPath)) {
7331
- watchDir(fullPath);
7332
- }
7333
- }
7334
- });
7335
- }, DEBOUNCE_MS));
7336
- });
7337
-
7338
- watchers.set(dir, watcher);
7339
-
7340
- // Watch subdirectories
7341
- const entries = fs.readdirSync(dir, { withFileTypes: true });
7342
- for (const entry of entries) {
7343
- if (entry.isDirectory() && !shouldIgnore(entry.name)) {
7344
- watchDir(path.join(dir, entry.name));
7345
- }
7346
- }
7347
- } catch (err) {
7348
- // Directory may not exist or be inaccessible
7349
- console.error(JSON.stringify({ error: err.message, dir }));
7350
- }
7351
- }
7352
-
7353
- // Start watching
7354
- watchDir(watchPath);
7355
-
7356
- // Keep alive
7357
- process.on('SIGTERM', () => {
7358
- for (const watcher of watchers.values()) {
7359
- watcher.close();
7360
- }
7361
- process.exit(0);
7362
- });
7363
-
7364
- // Heartbeat to indicate we're running
7365
- setInterval(() => {
7366
- console.log(JSON.stringify({ heartbeat: true, timestamp: Date.now() }));
7367
- }, 5000);
7368
-
7369
- console.log(JSON.stringify({ started: true, path: watchPath }));
7370
- `;
7371
- InSandboxWatcher = class {
7372
- sessionId;
7373
- watchPath;
7374
- outputPollIntervalMs;
7375
- sandboxState = null;
7376
- outputPollTimer = null;
7377
- subscribers = /* @__PURE__ */ new Set();
7378
- isRunning = false;
7379
- startedAt;
7380
- lastHeartbeat;
7381
- lastOutputPosition = 0;
7382
- onError;
7383
- onReady;
7384
- constructor(options) {
7385
- this.sessionId = options.sessionId;
7386
- this.watchPath = options.watchPath;
7387
- this.outputPollIntervalMs = options.outputPollIntervalMs ?? 1e3;
7388
- this.onError = options.onError;
7389
- this.onReady = options.onReady;
7390
- if (options.onFileChange) {
7391
- this.subscribers.add(options.onFileChange);
7392
- }
7393
- }
7394
- /**
7395
- * Start the watcher process inside the sandbox
7396
- */
7397
- async start() {
7398
- if (this.isRunning) {
7399
- console.warn(`[IN_SANDBOX_WATCHER] Already running for session ${this.sessionId}`);
7400
- return;
7401
- }
7402
- try {
7403
- this.sandboxState = await getOrCreateSandbox({
7404
- sessionId: this.sessionId,
7405
- runtime: "node22",
7406
- timeout: 600
7407
- });
7408
- const { sandbox } = this.sandboxState;
7409
- const scriptPath = "/tmp/.file-watcher.js";
7410
- const outputPath = "/tmp/.file-watcher-output.log";
7411
- const writeScriptCmd = `cat > ${scriptPath} << 'WATCHER_EOF'
7412
- ${WATCHER_SCRIPT}
7413
- WATCHER_EOF`;
7414
- await sandbox.runCommand({
7415
- cmd: "sh",
7416
- args: ["-c", writeScriptCmd]
7417
- });
7418
- const startCmd = `nohup node ${scriptPath} "${this.watchPath}" > ${outputPath} 2>&1 &`;
7419
- await sandbox.runCommand({
7420
- cmd: "sh",
7421
- args: ["-c", startCmd]
7422
- });
7423
- console.log(`[IN_SANDBOX_WATCHER] Started watcher in sandbox for ${this.watchPath}`);
7424
- this.isRunning = true;
7425
- this.startedAt = /* @__PURE__ */ new Date();
7426
- this.outputPollTimer = setInterval(async () => {
7427
- try {
7428
- await this.pollOutput(outputPath);
7429
- } catch (error) {
7430
- console.error("[IN_SANDBOX_WATCHER] Error polling output:", error);
7431
- if (this.onError && error instanceof Error) {
7432
- this.onError(error);
7433
- }
7434
- }
7435
- }, this.outputPollIntervalMs);
7436
- setTimeout(() => {
7437
- this.pollOutput(outputPath).catch(console.error);
7438
- }, 500);
7439
- } catch (error) {
7440
- console.error(`[IN_SANDBOX_WATCHER] Failed to start watcher:`, error);
7441
- throw error;
7442
- }
7443
- }
7444
- /**
7445
- * Poll the output file for new events
7446
- */
7447
- async pollOutput(outputPath) {
7448
- if (!this.sandboxState?.sandbox) return;
7449
- try {
7450
- const result = await this.sandboxState.sandbox.runCommand({
7451
- cmd: "sh",
7452
- args: ["-c", `tail -c +${this.lastOutputPosition + 1} ${outputPath} 2>/dev/null || true`]
7453
- });
7454
- const output = await result.stdout();
7455
- if (output && output.trim()) {
7456
- const sizeResult = await this.sandboxState.sandbox.runCommand({
7457
- cmd: "sh",
7458
- args: ["-c", `stat -c%s ${outputPath} 2>/dev/null || echo 0`]
7459
- });
7460
- const sizeStr = await sizeResult.stdout();
7461
- this.lastOutputPosition = parseInt(sizeStr.trim(), 10) || 0;
7462
- this.processOutput(output);
7463
- }
7464
- } catch {
7465
- }
7466
- }
7467
- /**
7468
- * Process output from the watcher script
7469
- */
7470
- processOutput(stdout) {
7471
- const lines = stdout.split("\n").filter(Boolean);
7472
- for (const line of lines) {
7473
- try {
7474
- const data = JSON.parse(line);
7475
- if (data.started) {
7476
- console.log(`[IN_SANDBOX_WATCHER] Watcher started for ${data.path}`);
7477
- if (this.onReady) {
7478
- this.onReady();
7479
- }
7480
- } else if (data.heartbeat) {
7481
- this.lastHeartbeat = new Date(data.timestamp);
7482
- } else if (data.error) {
7483
- console.warn(`[IN_SANDBOX_WATCHER] Error in sandbox:`, data.error);
7484
- } else if (data.type && data.path) {
7485
- this.emitEvent({
7486
- type: data.type,
7487
- relativePath: data.path.replace(/^\.\//, ""),
7488
- absolutePath: data.path,
7489
- basePath: this.watchPath,
7490
- sessionId: this.sessionId,
7491
- timestamp: new Date(data.timestamp)
7492
- });
7493
- }
7494
- } catch {
7495
- }
7496
- }
7497
- }
7498
- /**
7499
- * Stop the watcher process
7500
- */
7501
- async stop() {
7502
- if (!this.isRunning) {
7503
- return;
7504
- }
7505
- if (this.outputPollTimer) {
7506
- clearInterval(this.outputPollTimer);
7507
- this.outputPollTimer = null;
7508
- }
7509
- try {
7510
- if (this.sandboxState?.sandbox) {
7511
- await this.sandboxState.sandbox.runCommand({
7512
- cmd: "sh",
7513
- args: ["-c", "pkill -f file-watcher.js 2>/dev/null || true"]
7514
- });
7515
- await this.sandboxState.sandbox.runCommand({
7516
- cmd: "sh",
7517
- args: ["-c", "rm -f /tmp/.file-watcher.js /tmp/.file-watcher-output.log"]
7518
- });
7519
- }
7520
- } catch {
7521
- }
7522
- this.isRunning = false;
7523
- this.sandboxState = null;
7524
- this.lastOutputPosition = 0;
7525
- console.log(`[IN_SANDBOX_WATCHER] Stopped watcher for session ${this.sessionId}`);
7526
- }
7527
- /**
7528
- * Subscribe to file change events
7529
- */
7530
- subscribe(callback) {
7531
- this.subscribers.add(callback);
7532
- return () => this.subscribers.delete(callback);
7533
- }
7534
- /**
7535
- * Check if watcher is running
7536
- */
7537
- isActive() {
7538
- return this.isRunning;
7539
- }
7540
- /**
7541
- * Get watcher status
7542
- */
7543
- getStatus() {
7544
- return {
7545
- sessionId: this.sessionId,
7546
- watchPath: this.watchPath,
7547
- isRunning: this.isRunning,
7548
- startedAt: this.startedAt,
7549
- lastHeartbeat: this.lastHeartbeat
7550
- };
7551
- }
7552
- /**
7553
- * Emit event to all subscribers
7554
- */
7555
- async emitEvent(event) {
7556
- for (const callback of this.subscribers) {
7557
- try {
7558
- await callback(event);
7559
- } catch (error) {
7560
- console.error("[IN_SANDBOX_WATCHER] Error in subscriber callback:", error);
7561
- }
7562
- }
7563
- }
7564
- };
7565
- InSandboxWatcherManager = class {
7566
- watchers = /* @__PURE__ */ new Map();
7567
- /**
7568
- * Start watching a sandbox
7569
- */
7570
- async startWatching(options) {
7571
- const { sessionId } = options;
7572
- await this.stopWatching(sessionId);
7573
- const watcher = new InSandboxWatcher(options);
7574
- await watcher.start();
7575
- this.watchers.set(sessionId, watcher);
7576
- return watcher;
7577
- }
7578
- /**
7579
- * Stop watching a session
7580
- */
7581
- async stopWatching(sessionId) {
7582
- const watcher = this.watchers.get(sessionId);
7583
- if (watcher) {
7584
- await watcher.stop();
7585
- this.watchers.delete(sessionId);
7586
- }
7587
- }
7588
- /**
7589
- * Get watcher for a session
7590
- */
7591
- getWatcher(sessionId) {
7592
- return this.watchers.get(sessionId);
7593
- }
7594
- /**
7595
- * Check if watching
7596
- */
7597
- isWatching(sessionId) {
7598
- return this.watchers.get(sessionId)?.isActive() ?? false;
7599
- }
7600
- /**
7601
- * Stop all watchers
7602
- */
7603
- async stopAll() {
7604
- const promises = Array.from(this.watchers.values()).map((w) => w.stop());
7605
- await Promise.all(promises);
7606
- this.watchers.clear();
7607
- }
7608
- };
7609
- globalInSandboxManager = null;
7610
- }
7611
- });
7612
-
7613
7414
  // src/runtime/index.ts
7614
7415
  function generateDockerCommand(config) {
7615
7416
  const args = ["docker", "run"];
@@ -18990,6 +18791,6 @@ var init_src = __esm({
18990
18791
  });
18991
18792
  init_src();
18992
18793
 
18993
- export { AVAILABLE_MODELS, AgentConfigSchema, AgentError, AgentHarness, AgentStatus, AshCloud, AshCloudApiError, AshCloudClient, AttachmentConfigSchema, AttachmentStorage, ClaudeSdkClient, CloudSandbox, CloudStorage, ConfigBuilder, ConfigError, CredentialManager, DEFAULT_MODELS, DEFAULT_SANDBOX_PROVIDER_CONFIG, EventCategory, FileWatcherManager, GCSBundleStore, GeminiCliClient, GitHubFileProvider, HarnessConfigSchema, HarnessError, HarnessErrorCode, HarnessEventEmitter, InSandboxWatcher, InSandboxWatcherManager, LocalBundleStore, LocalFileProvider, LocalSandbox, McpConfigBuilder, McpPresets, McpServers, MemoryBundleStore, MemoryCredentialStorage, MemoryQueueStorage, MemoryRateLimitStore, MemoryStorage, MessageRole, NotFoundError, PostgresQueueStorage, PostgresStorage, ProviderSandbox, QueueItemStatus, QueueProcessor, RemoteFileWatcherManager, RemoteSandboxFileWatcher, RuntimeConfigBuilder, RuntimePresets, S3BundleStore, S3FileStore, SENSITIVE_PATHS, SandboxFileSync, SandboxFileWatcher, SandboxGitRepo, SandboxLogger, SandboxPool, ServerConfigSchema, SessionError, SessionManager, SessionStatus, SkillCatalog, SkillManager, StorageConfigSchema, StorageError, StreamEventType, SupabaseBundleStore, SupabaseStorage, ToolCallProcessor, ToolError, ValidationError, Workspace, WorkspaceManager, attachmentSchema, attachmentToDataUrl, checkSecurityConfig, claudeClient, cleanupAllSandboxes, configureMcp, configureRuntime, convertClaudeMessage, createAgentsRouter, createAshCloud, createBackendExecutor, createCloudSandbox, createConfig, createCredentialManager, createOpenAPIServer as createDocumentedServer, createE2BSandbox, createEventHandler, createEventMiddlewareChain, createFileWatcher, createFileWatcherManager, createGCSBundleStore, createGeminiExecutor, createGitHubFileProvider, createGitRepo, createHarnessServer, createInSandboxWatcher, createInSandboxWatcherManager, createLocalBundleStore, createLocalFileProvider, createLocalSandbox, createLogger, createMemoryBundleStore, createMinioBundleStore, createMinioFileStore, createModalSandbox, createAgentsRouter2 as createOpenAPIAgentsRouter, createOpenAPIServer, createSessionsRouter2 as createOpenAPISessionsRouter, createSkillsRouter2 as createOpenAPISkillsRouter, createProviderSandbox, createQueueProcessor, createQueueRouter, createR2BundleStore, createR2FileStore, createRemoteFileWatcher, createRemoteFileWatcherManager, createS3BundleStore, createS3FileStore, createSandboxFileOperations, createSandboxFileSync, createSandboxLogger, createSandboxOptions, createSessionWorkspace, createSessionsRouter, createSkillCatalog, createSkillManager, createSupabaseBundleStore, createSupabaseBundleStoreFromEnv, createToolCall, createToolCallProcessor, createVercelSandbox, createVercelSandboxExecutor, createWorkspace, createWorkspaceHooks, createWorkspaceManager, dataUrlToBuffer, defineAgent, defineConfig, ensureSandboxPoolInitialized, env, envOptional, extractTextContent, extractTextFromMessage, fileEntrySchema, formatToolName, generateDockerCommand, generateMcpServerPackage, generateMcpServers, generateProxyEnv, generateToolSummary, getActionIcon, getActionLabel, getAllHeartbeatStatuses, getApiKeyEnvVar, getDefaultModel, getFileWatcherManager, getHeartbeatStatus, getInSandboxWatcherManager, getOrCreateSandbox, getRemoteFileWatcherManager, getSandboxCacheStats, getSandboxPool, getWorkspaceManager, gitHubSkillSourceSchema, globalEventEmitter, hasErrorCode, hashStartupScript, httpMcpWithAuth, initializeSandboxPool, introspectMcpServer, invalidateSandbox, isCommandRunAction, isDocumentMimeType, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isHarnessError, isHttpMcpConfig, isImageMimeType, isMcpToolAction, isSandboxExpiredError, isSandboxRunning, isSearchAction, isSensitivePath, isStdioMcpConfig, isTodoWriteAction, isToolCallEntry, isValidModel, isWebFetchAction, isWebSearchAction, listFilesInSandbox, loadConfig, loadGitHubSkill, loadGitHubSkills, loadWorkspaceState, localSkillSourceSchema, log, mapClaudeOptionsToGemini, mapToolToActionType, markConfigInstalled, markSdkInstalled, markStartupScriptRan, mcpAuthToHeaders, messageContentSchema, messageSchema, needsStartupScriptRerun, normalizeGitHubConfigs, normalizeMcpServers, normalizeMessages, normalizeToolResult, onHeartbeat, schemas_exports as openApiSchemas, parseCommandResult, parseGitHubUrl, parseMcpToolName, processStreamEvents, rateLimit, rateLimiters, readFileFromSandbox, rekeySessionId, releaseSandbox, requestLogger, saveWorkspaceState, schema_exports as schema, sessionSchema, shouldUseSandbox, shutdownSandboxPool, skillConfigSchema, skillSourceSchema, sseMcpWithAuth, startServer, updateToolCallWithResult, writeFileToSandbox };
18794
+ export { AVAILABLE_MODELS, AgentConfigSchema, AgentError, AgentHarness, AgentStatus, AshCloud, AshCloudApiError, AshCloudClient, AttachmentConfigSchema, AttachmentStorage, ClaudeSdkClient, CloudSandbox, CloudStorage, ConfigBuilder, ConfigError, CredentialManager, DEFAULT_MODELS, DEFAULT_SANDBOX_PROVIDER_CONFIG, EventCategory, FileWatcherManager, GCSBundleStore, GeminiCliClient, GitHubFileProvider, HarnessConfigSchema, HarnessError, HarnessErrorCode, HarnessEventEmitter, InSandboxWatcher, InSandboxWatcherManager, LocalBundleStore, LocalFileProvider, LocalSandbox, McpConfigBuilder, McpPresets, McpServers, MemoryBundleStore, MemoryCredentialStorage, MemoryQueueStorage, MemoryRateLimitStore, MemoryStorage, MessageRole, NotFoundError, PostgresQueueStorage, PostgresStorage, ProviderSandbox, QueueItemStatus, QueueProcessor, RuntimeConfigBuilder, RuntimePresets, S3BundleStore, S3FileStore, SENSITIVE_PATHS, SandboxFileSync, SandboxFileWatcher, SandboxGitRepo, SandboxLogger, SandboxPool, ServerConfigSchema, SessionError, SessionManager, SessionStatus, SkillCatalog, SkillManager, StorageConfigSchema, StorageError, StreamEventType, SupabaseBundleStore, SupabaseStorage, ToolCallProcessor, ToolError, ValidationError, Workspace, WorkspaceManager, attachmentSchema, attachmentToDataUrl, checkSecurityConfig, claudeClient, cleanupAllSandboxes, configureMcp, configureRuntime, convertClaudeMessage, createAgentsRouter, createAshCloud, createBackendExecutor, createCloudSandbox, createConfig, createCredentialManager, createOpenAPIServer as createDocumentedServer, createE2BSandbox, createEventHandler, createEventMiddlewareChain, createFileWatcher, createFileWatcherManager, createGCSBundleStore, createGeminiExecutor, createGitHubFileProvider, createGitRepo, createHarnessServer, createInSandboxWatcher, createInSandboxWatcherManager, createLocalBundleStore, createLocalFileProvider, createLocalSandbox, createLogger, createMemoryBundleStore, createMinioBundleStore, createMinioFileStore, createModalSandbox, createAgentsRouter2 as createOpenAPIAgentsRouter, createOpenAPIServer, createSessionsRouter2 as createOpenAPISessionsRouter, createSkillsRouter2 as createOpenAPISkillsRouter, createProviderSandbox, createQueueProcessor, createQueueRouter, createR2BundleStore, createR2FileStore, createS3BundleStore, createS3FileStore, createSandboxFileOperations, createSandboxFileSync, createSandboxLogger, createSandboxOptions, createSessionWorkspace, createSessionsRouter, createSkillCatalog, createSkillManager, createSupabaseBundleStore, createSupabaseBundleStoreFromEnv, createToolCall, createToolCallProcessor, createVercelSandbox, createVercelSandboxExecutor, createWorkspace, createWorkspaceHooks, createWorkspaceManager, dataUrlToBuffer, defineAgent, defineConfig, ensureSandboxPoolInitialized, env, envOptional, executeCommandInSandbox, extractTextContent, extractTextFromMessage, fileEntrySchema, formatToolName, generateDockerCommand, generateMcpServerPackage, generateMcpServers, generateProxyEnv, generateToolSummary, getActionIcon, getActionLabel, getAllHeartbeatStatuses, getApiKeyEnvVar, getCachedSandbox, getDefaultModel, getFileWatcherManager, getHeartbeatStatus, getInSandboxWatcherManager, getOrCreateSandbox, getSandboxCacheStats, getSandboxPool, getWorkspaceManager, gitHubSkillSourceSchema, globalEventEmitter, hasErrorCode, hashStartupScript, httpMcpWithAuth, initializeSandboxPool, introspectMcpServer, invalidateSandbox, isCommandRunAction, isDocumentMimeType, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isHarnessError, isHttpMcpConfig, isImageMimeType, isMcpToolAction, isSandboxExpiredError, isSandboxRunning, isSearchAction, isSensitivePath, isStdioMcpConfig, isTodoWriteAction, isToolCallEntry, isValidModel, isWebFetchAction, isWebSearchAction, listFilesInSandbox, loadConfig, loadGitHubSkill, loadGitHubSkills, loadWorkspaceState, localSkillSourceSchema, log, mapClaudeOptionsToGemini, mapToolToActionType, markConfigInstalled, markSdkInstalled, markStartupScriptRan, mcpAuthToHeaders, messageContentSchema, messageSchema, needsStartupScriptRerun, normalizeGitHubConfigs, normalizeMcpServers, normalizeMessages, normalizeToolResult, onHeartbeat, schemas_exports as openApiSchemas, parseCommandResult, parseGitHubUrl, parseMcpToolName, processStreamEvents, rateLimit, rateLimiters, readFileFromSandbox, rekeySessionId, releaseSandbox, requestLogger, saveWorkspaceState, schema_exports as schema, sessionSchema, shouldUseSandbox, shutdownSandboxPool, skillConfigSchema, skillSourceSchema, sseMcpWithAuth, startServer, updateToolCallWithResult, writeFileToSandbox };
18994
18795
  //# sourceMappingURL=index.js.map
18995
18796
  //# sourceMappingURL=index.js.map