wuying-agentbay-sdk 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -129,10 +129,10 @@ var require_main = __commonJS({
129
129
  "node_modules/dotenv/lib/main.js"(exports, module) {
130
130
  "use strict";
131
131
  init_esm_shims();
132
- var fs2 = __require("fs");
133
- var path3 = __require("path");
132
+ var fs3 = __require("fs");
133
+ var path4 = __require("path");
134
134
  var os = __require("os");
135
- var crypto = __require("crypto");
135
+ var crypto2 = __require("crypto");
136
136
  var packageJson = require_package();
137
137
  var version = packageJson.version;
138
138
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
@@ -245,7 +245,7 @@ var require_main = __commonJS({
245
245
  if (options && options.path && options.path.length > 0) {
246
246
  if (Array.isArray(options.path)) {
247
247
  for (const filepath of options.path) {
248
- if (fs2.existsSync(filepath)) {
248
+ if (fs3.existsSync(filepath)) {
249
249
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
250
250
  }
251
251
  }
@@ -253,16 +253,16 @@ var require_main = __commonJS({
253
253
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
254
254
  }
255
255
  } else {
256
- possibleVaultPath = path3.resolve(process.cwd(), ".env.vault");
256
+ possibleVaultPath = path4.resolve(process.cwd(), ".env.vault");
257
257
  }
258
- if (fs2.existsSync(possibleVaultPath)) {
258
+ if (fs3.existsSync(possibleVaultPath)) {
259
259
  return possibleVaultPath;
260
260
  }
261
261
  return null;
262
262
  }
263
263
  __name(_vaultPath, "_vaultPath");
264
264
  function _resolveHome(envPath) {
265
- return envPath[0] === "~" ? path3.join(os.homedir(), envPath.slice(1)) : envPath;
265
+ return envPath[0] === "~" ? path4.join(os.homedir(), envPath.slice(1)) : envPath;
266
266
  }
267
267
  __name(_resolveHome, "_resolveHome");
268
268
  function _configVault(options) {
@@ -281,7 +281,7 @@ var require_main = __commonJS({
281
281
  }
282
282
  __name(_configVault, "_configVault");
283
283
  function configDotenv(options) {
284
- const dotenvPath = path3.resolve(process.cwd(), ".env");
284
+ const dotenvPath = path4.resolve(process.cwd(), ".env");
285
285
  let encoding = "utf8";
286
286
  const debug = Boolean(options && options.debug);
287
287
  const quiet = options && "quiet" in options ? options.quiet : true;
@@ -305,13 +305,13 @@ var require_main = __commonJS({
305
305
  }
306
306
  let lastError;
307
307
  const parsedAll = {};
308
- for (const path4 of optionPaths) {
308
+ for (const path5 of optionPaths) {
309
309
  try {
310
- const parsed = DotenvModule.parse(fs2.readFileSync(path4, { encoding }));
310
+ const parsed = DotenvModule.parse(fs3.readFileSync(path5, { encoding }));
311
311
  DotenvModule.populate(parsedAll, parsed, options);
312
312
  } catch (e) {
313
313
  if (debug) {
314
- _debug(`Failed to load ${path4} ${e.message}`);
314
+ _debug(`Failed to load ${path5} ${e.message}`);
315
315
  }
316
316
  lastError = e;
317
317
  }
@@ -326,7 +326,7 @@ var require_main = __commonJS({
326
326
  const shortPaths = [];
327
327
  for (const filePath of optionPaths) {
328
328
  try {
329
- const relative = path3.relative(process.cwd(), filePath);
329
+ const relative = path4.relative(process.cwd(), filePath);
330
330
  shortPaths.push(relative);
331
331
  } catch (e) {
332
332
  if (debug) {
@@ -363,7 +363,7 @@ var require_main = __commonJS({
363
363
  const authTag = ciphertext.subarray(-16);
364
364
  ciphertext = ciphertext.subarray(12, -16);
365
365
  try {
366
- const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
366
+ const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
367
367
  aesgcm.setAuthTag(authTag);
368
368
  return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
369
369
  } catch (error) {
@@ -4209,6 +4209,28 @@ function defaultConfig() {
4209
4209
  };
4210
4210
  }
4211
4211
  __name(defaultConfig, "defaultConfig");
4212
+ var dotEnvLoaded = false;
4213
+ function loadDotEnv() {
4214
+ if (dotEnvLoaded) {
4215
+ return;
4216
+ }
4217
+ try {
4218
+ const envPath = path2.resolve(process.cwd(), ".env");
4219
+ if (fs.existsSync(envPath)) {
4220
+ const envConfig = dotenv.parse(fs.readFileSync(envPath));
4221
+ for (const k in envConfig) {
4222
+ if (!process.env.hasOwnProperty(k)) {
4223
+ process.env[k] = envConfig[k];
4224
+ }
4225
+ }
4226
+ log(`Loaded .env file at: ${envPath}`);
4227
+ dotEnvLoaded = true;
4228
+ }
4229
+ } catch (error) {
4230
+ log(`Warning: Failed to load .env file: ${error}`);
4231
+ }
4232
+ }
4233
+ __name(loadDotEnv, "loadDotEnv");
4212
4234
  function loadConfig(customConfig) {
4213
4235
  if (customConfig) {
4214
4236
  return customConfig;
@@ -4229,16 +4251,16 @@ function loadConfig(customConfig) {
4229
4251
  const envPath = path2.resolve(process.cwd(), ".env");
4230
4252
  if (fs.existsSync(envPath)) {
4231
4253
  const envConfig = dotenv.parse(fs.readFileSync(envPath));
4232
- for (const k in envConfig) {
4233
- if (!process.env.hasOwnProperty(k)) {
4234
- if (k === "AGENTBAY_REGION_ID") config.region_id = envConfig[k];
4235
- else if (k === "AGENTBAY_ENDPOINT") config.endpoint = envConfig[k];
4236
- else if (k === "AGENTBAY_TIMEOUT_MS") {
4237
- const timeout = parseInt(envConfig[k], 10);
4238
- if (!isNaN(timeout) && timeout > 0) {
4239
- config.timeout_ms = timeout;
4240
- }
4241
- }
4254
+ if (!process.env.AGENTBAY_REGION_ID && envConfig.AGENTBAY_REGION_ID) {
4255
+ config.region_id = envConfig.AGENTBAY_REGION_ID;
4256
+ }
4257
+ if (!process.env.AGENTBAY_ENDPOINT && envConfig.AGENTBAY_ENDPOINT) {
4258
+ config.endpoint = envConfig.AGENTBAY_ENDPOINT;
4259
+ }
4260
+ if (!process.env.AGENTBAY_TIMEOUT_MS && envConfig.AGENTBAY_TIMEOUT_MS) {
4261
+ const timeout = parseInt(envConfig.AGENTBAY_TIMEOUT_MS, 10);
4262
+ if (!isNaN(timeout) && timeout > 0) {
4263
+ config.timeout_ms = timeout;
4242
4264
  }
4243
4265
  }
4244
4266
  log(`Loaded .env file at: ${envPath}`);
@@ -5329,7 +5351,7 @@ var _ContextManager = class _ContextManager {
5329
5351
  async info() {
5330
5352
  return this.infoWithParams();
5331
5353
  }
5332
- async infoWithParams(contextId, path3, taskType) {
5354
+ async infoWithParams(contextId, path4, taskType) {
5333
5355
  const request = new GetContextInfoRequest({
5334
5356
  authorization: `Bearer ${this.session.getAPIKey()}`,
5335
5357
  sessionId: this.session.getSessionId()
@@ -5337,8 +5359,8 @@ var _ContextManager = class _ContextManager {
5337
5359
  if (contextId) {
5338
5360
  request.contextId = contextId;
5339
5361
  }
5340
- if (path3) {
5341
- request.path = path3;
5362
+ if (path4) {
5363
+ request.path = path4;
5342
5364
  }
5343
5365
  if (taskType) {
5344
5366
  request.taskType = taskType;
@@ -5388,7 +5410,7 @@ var _ContextManager = class _ContextManager {
5388
5410
  async sync() {
5389
5411
  return this.syncWithParams();
5390
5412
  }
5391
- async syncWithParams(contextId, path3, mode) {
5413
+ async syncWithParams(contextId, path4, mode) {
5392
5414
  const request = new SyncContextRequest({
5393
5415
  authorization: `Bearer ${this.session.getAPIKey()}`,
5394
5416
  sessionId: this.session.getSessionId()
@@ -5396,8 +5418,8 @@ var _ContextManager = class _ContextManager {
5396
5418
  if (contextId) {
5397
5419
  request.contextId = contextId;
5398
5420
  }
5399
- if (path3) {
5400
- request.path = path3;
5421
+ if (path4) {
5422
+ request.path = path4;
5401
5423
  }
5402
5424
  if (mode) {
5403
5425
  request.mode = mode;
@@ -5527,10 +5549,10 @@ var _FileSystem = class _FileSystem {
5527
5549
  * @param path - Path to the directory to create.
5528
5550
  * @returns BoolResult with creation result and requestId
5529
5551
  */
5530
- async createDirectory(path3) {
5552
+ async createDirectory(path4) {
5531
5553
  try {
5532
5554
  const args = {
5533
- path: path3
5555
+ path: path4
5534
5556
  };
5535
5557
  const result = await this.session.callMcpTool(
5536
5558
  "create_directory",
@@ -5565,10 +5587,10 @@ var _FileSystem = class _FileSystem {
5565
5587
  * @param dryRun - Optional: If true, preview changes without applying them.
5566
5588
  * @returns BoolResult with edit result and requestId
5567
5589
  */
5568
- async editFile(path3, edits, dryRun = false) {
5590
+ async editFile(path4, edits, dryRun = false) {
5569
5591
  try {
5570
5592
  const args = {
5571
- path: path3,
5593
+ path: path4,
5572
5594
  edits,
5573
5595
  dryRun
5574
5596
  };
@@ -5603,10 +5625,10 @@ var _FileSystem = class _FileSystem {
5603
5625
  * @param path - Path to the file or directory to inspect.
5604
5626
  * @returns FileInfoResult with file info and requestId
5605
5627
  */
5606
- async getFileInfo(path3) {
5628
+ async getFileInfo(path4) {
5607
5629
  try {
5608
5630
  const args = {
5609
- path: path3
5631
+ path: path4
5610
5632
  };
5611
5633
  const result = await this.session.callMcpTool(
5612
5634
  "get_file_info",
@@ -5649,10 +5671,10 @@ var _FileSystem = class _FileSystem {
5649
5671
  * @param path - Path to the directory to list.
5650
5672
  * @returns DirectoryListResult with directory entries and requestId
5651
5673
  */
5652
- async listDirectory(path3) {
5674
+ async listDirectory(path4) {
5653
5675
  try {
5654
5676
  const args = {
5655
- path: path3
5677
+ path: path4
5656
5678
  };
5657
5679
  const result = await this.session.callMcpTool(
5658
5680
  "list_directory",
@@ -5720,18 +5742,17 @@ var _FileSystem = class _FileSystem {
5720
5742
  }
5721
5743
  }
5722
5744
  /**
5723
- * Reads the content of a file.
5724
- * Corresponds to Python's read_file() method
5745
+ * Internal method to read a file chunk. Used for chunked file operations.
5725
5746
  *
5726
5747
  * @param path - Path to the file to read.
5727
5748
  * @param offset - Optional: Byte offset to start reading from (0-based).
5728
5749
  * @param length - Optional: Number of bytes to read. If 0, reads the entire file from offset.
5729
5750
  * @returns FileContentResult with file content and requestId
5730
5751
  */
5731
- async readFile(path3, offset = 0, length = 0) {
5752
+ async readFileChunk(path4, offset = 0, length = 0) {
5732
5753
  try {
5733
5754
  const args = {
5734
- path: path3
5755
+ path: path4
5735
5756
  };
5736
5757
  if (offset > 0) {
5737
5758
  args.offset = offset;
@@ -5797,8 +5818,8 @@ var _FileSystem = class _FileSystem {
5797
5818
  for (const line of lines) {
5798
5819
  const colonIndex = line.indexOf(":");
5799
5820
  if (colonIndex > 0 && currentPath === "" && !line.substring(0, colonIndex).includes(" ")) {
5800
- const path3 = line.substring(0, colonIndex).trim();
5801
- currentPath = path3;
5821
+ const path4 = line.substring(0, colonIndex).trim();
5822
+ currentPath = path4;
5802
5823
  if (line.length > colonIndex + 1) {
5803
5824
  const contentStart = line.substring(colonIndex + 1).trim();
5804
5825
  if (contentStart) {
@@ -5818,8 +5839,8 @@ var _FileSystem = class _FileSystem {
5818
5839
  if (currentPath) {
5819
5840
  fileContents[currentPath] = currentContent.join("\n");
5820
5841
  }
5821
- for (const path3 in fileContents) {
5822
- fileContents[path3] = fileContents[path3].replace(/\n+$/, "");
5842
+ for (const path4 in fileContents) {
5843
+ fileContents[path4] = fileContents[path4].replace(/\n+$/, "");
5823
5844
  }
5824
5845
  }
5825
5846
  return {
@@ -5845,10 +5866,10 @@ var _FileSystem = class _FileSystem {
5845
5866
  * @param excludePatterns - Optional: Array of patterns to exclude.
5846
5867
  * @returns FileSearchResult with search results and requestId
5847
5868
  */
5848
- async searchFiles(path3, pattern, excludePatterns = []) {
5869
+ async searchFiles(path4, pattern, excludePatterns = []) {
5849
5870
  try {
5850
5871
  const args = {
5851
- path: path3,
5872
+ path: path4,
5852
5873
  pattern
5853
5874
  };
5854
5875
  if (excludePatterns.length > 0) {
@@ -5885,15 +5906,14 @@ var _FileSystem = class _FileSystem {
5885
5906
  }
5886
5907
  }
5887
5908
  /**
5888
- * Writes content to a file.
5889
- * Corresponds to Python's write_file() method
5909
+ * Internal method to write a file chunk. Used for chunked file operations.
5890
5910
  *
5891
5911
  * @param path - Path to the file to write.
5892
5912
  * @param content - Content to write to the file.
5893
5913
  * @param mode - Optional: Write mode. One of "overwrite", "append", or "create_new". Default is "overwrite".
5894
5914
  * @returns BoolResult with write result and requestId
5895
5915
  */
5896
- async writeFile(path3, content, mode = "overwrite") {
5916
+ async writeFileChunk(path4, content, mode = "overwrite") {
5897
5917
  try {
5898
5918
  const validModes = ["overwrite", "append", "create_new"];
5899
5919
  if (!validModes.includes(mode)) {
@@ -5906,7 +5926,7 @@ var _FileSystem = class _FileSystem {
5906
5926
  };
5907
5927
  }
5908
5928
  const args = {
5909
- path: path3,
5929
+ path: path4,
5910
5930
  content,
5911
5931
  mode
5912
5932
  };
@@ -5935,16 +5955,15 @@ var _FileSystem = class _FileSystem {
5935
5955
  }
5936
5956
  }
5937
5957
  /**
5938
- * Reads a large file in chunks to handle size limitations of the underlying API.
5939
- * Corresponds to Python's read_large_file() method
5958
+ * Reads the contents of a file. Automatically handles large files by chunking.
5940
5959
  *
5941
5960
  * @param path - Path to the file to read.
5942
- * @param chunkSize - Optional: Size of each chunk in bytes. Default is 60KB.
5943
5961
  * @returns FileContentResult with complete file content and requestId
5944
5962
  */
5945
- async readLargeFile(path3, chunkSize = DEFAULT_CHUNK_SIZE) {
5963
+ async readFile(path4) {
5964
+ const chunkSize = DEFAULT_CHUNK_SIZE;
5946
5965
  try {
5947
- const fileInfoResult = await this.getFileInfo(path3);
5966
+ const fileInfoResult = await this.getFileInfo(path4);
5948
5967
  if (!fileInfoResult.success) {
5949
5968
  return {
5950
5969
  requestId: fileInfoResult.requestId,
@@ -5958,7 +5977,7 @@ var _FileSystem = class _FileSystem {
5958
5977
  requestId: fileInfoResult.requestId,
5959
5978
  success: false,
5960
5979
  content: "",
5961
- errorMessage: `Path does not exist or is a directory: ${path3}`
5980
+ errorMessage: `Path does not exist or is a directory: ${path4}`
5962
5981
  };
5963
5982
  }
5964
5983
  const fileSize = fileInfoResult.fileInfo.size || 0;
@@ -5978,7 +5997,7 @@ var _FileSystem = class _FileSystem {
5978
5997
  length = fileSize - offset;
5979
5998
  }
5980
5999
  try {
5981
- const chunkResult = await this.readFile(path3, offset, length);
6000
+ const chunkResult = await this.readFileChunk(path4, offset, length);
5982
6001
  if (!chunkResult.success) {
5983
6002
  return chunkResult;
5984
6003
  }
@@ -6009,25 +6028,25 @@ var _FileSystem = class _FileSystem {
6009
6028
  }
6010
6029
  }
6011
6030
  /**
6012
- * Writes a large file in chunks to handle size limitations of the underlying API.
6013
- * Corresponds to Python's write_large_file() method
6031
+ * Writes content to a file. Automatically handles large files by chunking.
6014
6032
  *
6015
6033
  * @param path - Path to the file to write.
6016
6034
  * @param content - Content to write to the file.
6017
- * @param chunkSize - Optional: Size of each chunk in bytes. Default is 60KB.
6035
+ * @param mode - Optional: Write mode. One of "overwrite", "append", or "create_new". Default is "overwrite".
6018
6036
  * @returns BoolResult indicating success or failure with requestId
6019
6037
  */
6020
- async writeLargeFile(path3, content, chunkSize = DEFAULT_CHUNK_SIZE) {
6038
+ async writeFile(path4, content, mode = "overwrite") {
6039
+ const chunkSize = DEFAULT_CHUNK_SIZE;
6021
6040
  try {
6022
6041
  const contentLen = content.length;
6023
6042
  if (contentLen <= chunkSize) {
6024
- return await this.writeFile(path3, content, "overwrite");
6043
+ return await this.writeFileChunk(path4, content, mode);
6025
6044
  }
6026
6045
  const firstChunkEnd = Math.min(chunkSize, contentLen);
6027
- const firstResult = await this.writeFile(
6028
- path3,
6046
+ const firstResult = await this.writeFileChunk(
6047
+ path4,
6029
6048
  content.substring(0, firstChunkEnd),
6030
- "overwrite"
6049
+ mode
6031
6050
  );
6032
6051
  if (!firstResult.success) {
6033
6052
  return firstResult;
@@ -6035,8 +6054,8 @@ var _FileSystem = class _FileSystem {
6035
6054
  let chunkCount = 1;
6036
6055
  for (let offset = firstChunkEnd; offset < contentLen; ) {
6037
6056
  const end = Math.min(offset + chunkSize, contentLen);
6038
- const chunkResult = await this.writeFile(
6039
- path3,
6057
+ const chunkResult = await this.writeFileChunk(
6058
+ path4,
6040
6059
  content.substring(offset, end),
6041
6060
  "append"
6042
6061
  );
@@ -6156,12 +6175,12 @@ var _Oss = class _Oss {
6156
6175
  * @returns OSSUploadResult with upload result and requestId
6157
6176
  * @throws APIError if the operation fails.
6158
6177
  */
6159
- async upload(bucket, object, path3) {
6178
+ async upload(bucket, object, path4) {
6160
6179
  try {
6161
6180
  const args = {
6162
6181
  bucket,
6163
6182
  object,
6164
- path: path3
6183
+ path: path4
6165
6184
  };
6166
6185
  const result = await this.session.callMcpTool("oss_upload", args);
6167
6186
  return {
@@ -6188,11 +6207,11 @@ var _Oss = class _Oss {
6188
6207
  * @returns OSSUploadResult with upload result and requestId
6189
6208
  * @throws APIError if the operation fails.
6190
6209
  */
6191
- async uploadAnonymous(url, path3) {
6210
+ async uploadAnonymous(url, path4) {
6192
6211
  try {
6193
6212
  const args = {
6194
6213
  url,
6195
- path: path3
6214
+ path: path4
6196
6215
  };
6197
6216
  const result = await this.session.callMcpTool("oss_upload_anonymous", args);
6198
6217
  return {
@@ -6220,12 +6239,12 @@ var _Oss = class _Oss {
6220
6239
  * @returns OSSDownloadResult with download result and requestId
6221
6240
  * @throws APIError if the operation fails.
6222
6241
  */
6223
- async download(bucket, object, path3) {
6242
+ async download(bucket, object, path4) {
6224
6243
  try {
6225
6244
  const args = {
6226
6245
  bucket,
6227
6246
  object,
6228
- path: path3
6247
+ path: path4
6229
6248
  };
6230
6249
  const result = await this.session.callMcpTool("oss_download", args);
6231
6250
  return {
@@ -6252,11 +6271,11 @@ var _Oss = class _Oss {
6252
6271
  * @returns OSSDownloadResult with download result and requestId
6253
6272
  * @throws APIError if the operation fails.
6254
6273
  */
6255
- async downloadAnonymous(url, path3) {
6274
+ async downloadAnonymous(url, path4) {
6256
6275
  try {
6257
6276
  const args = {
6258
6277
  url,
6259
- path: path3
6278
+ path: path4
6260
6279
  };
6261
6280
  const result = await this.session.callMcpTool("oss_download_anonymous", args);
6262
6281
  return {
@@ -7314,6 +7333,7 @@ var _BrowserOptionClass = class _BrowserOptionClass {
7314
7333
  this.screen = screen;
7315
7334
  this.fingerprint = fingerprint;
7316
7335
  this.proxies = proxies;
7336
+ this.extensionPath = "/tmp/extensions/";
7317
7337
  if (proxies !== void 0) {
7318
7338
  if (!Array.isArray(proxies)) {
7319
7339
  throw new Error("proxies must be a list");
@@ -7325,6 +7345,9 @@ var _BrowserOptionClass = class _BrowserOptionClass {
7325
7345
  }
7326
7346
  toMap() {
7327
7347
  const optionMap = {};
7348
+ if (process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE) {
7349
+ optionMap["behaviorSimulate"] = process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE !== "0";
7350
+ }
7328
7351
  if (this.useStealth !== void 0) {
7329
7352
  optionMap["useStealth"] = this.useStealth;
7330
7353
  }
@@ -7347,6 +7370,9 @@ var _BrowserOptionClass = class _BrowserOptionClass {
7347
7370
  if (this.proxies !== void 0) {
7348
7371
  optionMap["proxies"] = this.proxies.map((proxy) => proxy.toMap());
7349
7372
  }
7373
+ if (this.extensionPath !== void 0) {
7374
+ optionMap["extensionPath"] = this.extensionPath;
7375
+ }
7350
7376
  return optionMap;
7351
7377
  }
7352
7378
  fromMap(m) {
@@ -7384,6 +7410,9 @@ var _BrowserOptionClass = class _BrowserOptionClass {
7384
7410
  return BrowserProxyClass.fromMap(proxyData);
7385
7411
  }).filter(Boolean);
7386
7412
  }
7413
+ if (map.extensionPath !== void 0) {
7414
+ this.extensionPath = map.extensionPath;
7415
+ }
7387
7416
  return this;
7388
7417
  }
7389
7418
  };
@@ -7544,7 +7573,6 @@ var _Session = class _Session {
7544
7573
  * @param sessionId - The ID of this session.
7545
7574
  */
7546
7575
  constructor(agentBay, sessionId) {
7547
- this.resourceUrl = "";
7548
7576
  // VPC-related information
7549
7577
  this.isVpc = false;
7550
7578
  // Whether this session uses VPC resources
@@ -7555,7 +7583,6 @@ var _Session = class _Session {
7555
7583
  this.mcpTools = [];
7556
7584
  this.agentBay = agentBay;
7557
7585
  this.sessionId = sessionId;
7558
- this.resourceUrl = "";
7559
7586
  this.fileSystem = new FileSystem(this);
7560
7587
  this.command = new Command(this);
7561
7588
  this.code = new Code(this);
@@ -7845,7 +7872,6 @@ var _Session = class _Session {
7845
7872
  }
7846
7873
  if (data?.resourceUrl) {
7847
7874
  sessionInfo.resourceUrl = data.resourceUrl;
7848
- this.resourceUrl = data.resourceUrl;
7849
7875
  }
7850
7876
  if (data?.desktopInfo) {
7851
7877
  const desktopInfo = data.desktopInfo;
@@ -8157,6 +8183,7 @@ var _AgentBay = class _AgentBay {
8157
8183
  */
8158
8184
  constructor(options = {}) {
8159
8185
  this.sessions = /* @__PURE__ */ new Map();
8186
+ loadDotEnv();
8160
8187
  this.apiKey = options.apiKey || process.env.AGENTBAY_API_KEY || "";
8161
8188
  if (!this.apiKey) {
8162
8189
  throw new AuthenticationError(
@@ -8289,9 +8316,6 @@ var _AgentBay = class _AgentBay {
8289
8316
  log("session_id =", sessionId);
8290
8317
  log("resource_url =", resourceUrl);
8291
8318
  const session = new Session(this, sessionId);
8292
- if (resourceUrl) {
8293
- session.resourceUrl = resourceUrl;
8294
- }
8295
8319
  session.isVpc = params.isVpc || false;
8296
8320
  if (data.networkInterfaceIp) {
8297
8321
  session.networkInterfaceIp = data.networkInterfaceIp;
@@ -8496,6 +8520,366 @@ var AgentBay = _AgentBay;
8496
8520
  // src/agent/index.ts
8497
8521
  init_esm_shims();
8498
8522
 
8523
+ // src/extension.ts
8524
+ init_esm_shims();
8525
+ import * as fs2 from "fs";
8526
+ import * as path3 from "path";
8527
+ import * as crypto from "crypto";
8528
+ import fetch2 from "node-fetch";
8529
+ var EXTENSIONS_BASE_PATH = "/tmp/extensions";
8530
+ var _Extension = class _Extension {
8531
+ /**
8532
+ * Initialize an Extension object.
8533
+ *
8534
+ * @param id - The unique identifier of the extension.
8535
+ * @param name - The name of the extension.
8536
+ * @param createdAt - Date and time when the extension was created.
8537
+ */
8538
+ constructor(id, name, createdAt) {
8539
+ this.id = id;
8540
+ this.name = name;
8541
+ this.createdAt = createdAt;
8542
+ }
8543
+ };
8544
+ __name(_Extension, "Extension");
8545
+ var Extension = _Extension;
8546
+ var _ExtensionOption = class _ExtensionOption {
8547
+ /**
8548
+ * Initialize ExtensionOption with context and extension configuration.
8549
+ *
8550
+ * @param contextId - ID of the extension context for browser extensions.
8551
+ * This should match the context where extensions are stored.
8552
+ * @param extensionIds - List of extension IDs to be loaded in the browser session.
8553
+ * Each ID should correspond to a valid extension in the context.
8554
+ *
8555
+ * @throws {Error} If contextId is empty or extensionIds is empty.
8556
+ */
8557
+ constructor(contextId, extensionIds) {
8558
+ if (!contextId || !contextId.trim()) {
8559
+ throw new Error("contextId cannot be empty");
8560
+ }
8561
+ if (!extensionIds || extensionIds.length === 0) {
8562
+ throw new Error("extensionIds cannot be empty");
8563
+ }
8564
+ this.contextId = contextId;
8565
+ this.extensionIds = extensionIds;
8566
+ }
8567
+ /**
8568
+ * String representation of ExtensionOption.
8569
+ */
8570
+ toString() {
8571
+ return `ExtensionOption(contextId='${this.contextId}', extensionIds=${JSON.stringify(this.extensionIds)})`;
8572
+ }
8573
+ /**
8574
+ * Human-readable string representation.
8575
+ */
8576
+ toDisplayString() {
8577
+ return `Extension Config: ${this.extensionIds.length} extension(s) in context '${this.contextId}'`;
8578
+ }
8579
+ /**
8580
+ * Validate the extension option configuration.
8581
+ *
8582
+ * @returns True if configuration is valid, false otherwise.
8583
+ */
8584
+ validate() {
8585
+ try {
8586
+ if (!this.contextId || !this.contextId.trim()) {
8587
+ return false;
8588
+ }
8589
+ if (!this.extensionIds || this.extensionIds.length === 0) {
8590
+ return false;
8591
+ }
8592
+ for (const extId of this.extensionIds) {
8593
+ if (typeof extId !== "string" || !extId.trim()) {
8594
+ return false;
8595
+ }
8596
+ }
8597
+ return true;
8598
+ } catch (error) {
8599
+ return false;
8600
+ }
8601
+ }
8602
+ };
8603
+ __name(_ExtensionOption, "ExtensionOption");
8604
+ var ExtensionOption = _ExtensionOption;
8605
+ var _ExtensionsService = class _ExtensionsService {
8606
+ /**
8607
+ * Initializes the ExtensionsService with a context.
8608
+ *
8609
+ * @param agentBay - The AgentBay client instance.
8610
+ * @param contextId - The context ID or name. If empty or not provided,
8611
+ * a default context name will be generated automatically.
8612
+ * If the context doesn't exist, it will be automatically created.
8613
+ *
8614
+ * Note:
8615
+ * The service automatically detects if the context exists. If not,
8616
+ * it creates a new context with the provided name or a generated default name.
8617
+ * Context initialization is handled lazily on first use.
8618
+ */
8619
+ constructor(agentBay, contextId = "") {
8620
+ this._initializationPromise = null;
8621
+ if (!agentBay) {
8622
+ throw new AgentBayError("AgentBay instance is required");
8623
+ }
8624
+ if (!agentBay.context) {
8625
+ throw new AgentBayError("AgentBay instance must have a context service");
8626
+ }
8627
+ this.agentBay = agentBay;
8628
+ this.contextService = agentBay.context;
8629
+ this.autoCreated = true;
8630
+ if (!contextId || contextId.trim() === "") {
8631
+ contextId = `extensions-${Math.floor(Date.now() / 1e3)}`;
8632
+ log(`Generated default context name: ${contextId}`);
8633
+ }
8634
+ this.contextName = contextId;
8635
+ this._initializationPromise = this._initializeContext();
8636
+ }
8637
+ /**
8638
+ * Internal method to initialize the context.
8639
+ * This ensures the context is ready before any operations.
8640
+ */
8641
+ async _initializeContext() {
8642
+ try {
8643
+ const contextResult = await this.contextService.get(this.contextName, true);
8644
+ if (!contextResult.success || !contextResult.context) {
8645
+ throw new AgentBayError(`Failed to create extension repository context: ${this.contextName}`);
8646
+ }
8647
+ this.extensionContext = contextResult.context;
8648
+ this.contextId = this.extensionContext.id;
8649
+ } catch (error) {
8650
+ throw new AgentBayError(`Failed to initialize ExtensionsService: ${error instanceof Error ? error.message : String(error)}`);
8651
+ }
8652
+ }
8653
+ /**
8654
+ * Ensures the service is initialized before performing operations.
8655
+ */
8656
+ async _ensureInitialized() {
8657
+ if (this._initializationPromise) {
8658
+ await this._initializationPromise;
8659
+ this._initializationPromise = null;
8660
+ }
8661
+ }
8662
+ /**
8663
+ * An internal helper method that encapsulates the flow of "get upload URL for a specific path and upload".
8664
+ * Uses the existing context service for file operations.
8665
+ *
8666
+ * @param localPath - The path to the local file.
8667
+ * @param remotePath - The path of the file in context storage.
8668
+ *
8669
+ * @throws {AgentBayError} If getting the credential or uploading fails.
8670
+ */
8671
+ async _uploadToCloud(localPath, remotePath) {
8672
+ try {
8673
+ const urlResult = await this.contextService.getFileUploadUrl(this.contextId, remotePath);
8674
+ if (!urlResult.success || !urlResult.url) {
8675
+ throw new AgentBayError(`Failed to get upload URL: ${urlResult.url || "No URL returned"}`);
8676
+ }
8677
+ const preSignedUrl = urlResult.url;
8678
+ const fileBuffer = fs2.readFileSync(localPath);
8679
+ const response = await fetch2(preSignedUrl, {
8680
+ method: "PUT",
8681
+ body: fileBuffer
8682
+ });
8683
+ if (!response.ok) {
8684
+ throw new AgentBayError(`HTTP error uploading file: ${response.status} ${response.statusText}`);
8685
+ }
8686
+ } catch (error) {
8687
+ if (error instanceof AgentBayError) {
8688
+ throw error;
8689
+ }
8690
+ throw new AgentBayError(`An error occurred while uploading the file: ${error instanceof Error ? error.message : String(error)}`);
8691
+ }
8692
+ }
8693
+ /**
8694
+ * Lists all available browser extensions within this context from the cloud.
8695
+ * Uses the context service to list files under the extensions directory.
8696
+ *
8697
+ * @returns Promise that resolves to an array of Extension objects.
8698
+ * @throws {AgentBayError} If listing extensions fails.
8699
+ */
8700
+ async list() {
8701
+ await this._ensureInitialized();
8702
+ try {
8703
+ const fileListResult = await this.contextService.listFiles(
8704
+ this.contextId,
8705
+ EXTENSIONS_BASE_PATH,
8706
+ 1,
8707
+ // pageNumber
8708
+ 100
8709
+ // pageSize - reasonable limit for extensions
8710
+ );
8711
+ if (!fileListResult.success) {
8712
+ throw new AgentBayError("Failed to list extensions: Context file listing failed.");
8713
+ }
8714
+ const extensions = [];
8715
+ for (const fileEntry of fileListResult.entries) {
8716
+ const extensionId = fileEntry.fileName || fileEntry.filePath;
8717
+ extensions.push(new Extension(
8718
+ extensionId,
8719
+ fileEntry.fileName || extensionId,
8720
+ fileEntry.gmtCreate
8721
+ ));
8722
+ }
8723
+ return extensions;
8724
+ } catch (error) {
8725
+ if (error instanceof AgentBayError) {
8726
+ throw error;
8727
+ }
8728
+ throw new AgentBayError(`An error occurred while listing browser extensions: ${error instanceof Error ? error.message : String(error)}`);
8729
+ }
8730
+ }
8731
+ /**
8732
+ * Uploads a new browser extension from a local path into the current context.
8733
+ *
8734
+ * @param localPath - Path to the local extension file (must be a .zip file).
8735
+ * @returns Promise that resolves to an Extension object.
8736
+ * @throws {Error} If the local file doesn't exist.
8737
+ * @throws {Error} If the file format is not supported (only .zip is supported).
8738
+ * @throws {AgentBayError} If upload fails.
8739
+ */
8740
+ async create(localPath) {
8741
+ await this._ensureInitialized();
8742
+ if (!fs2.existsSync(localPath)) {
8743
+ throw new Error(`The specified local file was not found: ${localPath}`);
8744
+ }
8745
+ const fileExtension = path3.extname(localPath).toLowerCase();
8746
+ if (fileExtension !== ".zip") {
8747
+ throw new Error(`Unsupported plugin format '${fileExtension}'. Only ZIP format (.zip) is supported.`);
8748
+ }
8749
+ const extensionId = `ext_${crypto.randomBytes(16).toString("hex")}${fileExtension}`;
8750
+ const extensionName = path3.basename(localPath);
8751
+ const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;
8752
+ await this._uploadToCloud(localPath, remotePath);
8753
+ return new Extension(extensionId, extensionName);
8754
+ }
8755
+ /**
8756
+ * Updates an existing browser extension in the current context with a new file.
8757
+ *
8758
+ * @param extensionId - ID of the extension to update.
8759
+ * @param newLocalPath - Path to the new local extension file.
8760
+ * @returns Promise that resolves to an Extension object.
8761
+ * @throws {Error} If the new local file doesn't exist.
8762
+ * @throws {Error} If the extension doesn't exist in the context.
8763
+ * @throws {AgentBayError} If update fails.
8764
+ */
8765
+ async update(extensionId, newLocalPath) {
8766
+ await this._ensureInitialized();
8767
+ if (!fs2.existsSync(newLocalPath)) {
8768
+ throw new Error(`The specified new local file was not found: ${newLocalPath}`);
8769
+ }
8770
+ const existingExtensions = await this.list();
8771
+ const extensionExists = existingExtensions.some((ext) => ext.id === extensionId);
8772
+ if (!extensionExists) {
8773
+ throw new Error(`Browser extension with ID '${extensionId}' not found in the context. Cannot update.`);
8774
+ }
8775
+ const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;
8776
+ await this._uploadToCloud(newLocalPath, remotePath);
8777
+ return new Extension(extensionId, path3.basename(newLocalPath));
8778
+ }
8779
+ /**
8780
+ * Gets detailed information about a specific browser extension.
8781
+ *
8782
+ * @param extensionId - The ID of the extension to get info for.
8783
+ * @returns Promise that resolves to an Extension object if found, undefined otherwise.
8784
+ */
8785
+ async _getExtensionInfo(extensionId) {
8786
+ await this._ensureInitialized();
8787
+ try {
8788
+ const extensions = await this.list();
8789
+ return extensions.find((ext) => ext.id === extensionId);
8790
+ } catch (error) {
8791
+ logError(`An error occurred while getting extension info for '${extensionId}':`, error);
8792
+ return void 0;
8793
+ }
8794
+ }
8795
+ /**
8796
+ * Cleans up the auto-created context if it was created by this service.
8797
+ *
8798
+ * @returns Promise that resolves to true if cleanup was successful or not needed, false if cleanup failed.
8799
+ *
8800
+ * Note:
8801
+ * This method only works if the context was auto-created by this service.
8802
+ * For existing contexts, no cleanup is performed.
8803
+ */
8804
+ async cleanup() {
8805
+ await this._ensureInitialized();
8806
+ if (!this.autoCreated) {
8807
+ return true;
8808
+ }
8809
+ try {
8810
+ const deleteResult = await this.contextService.delete(this.extensionContext);
8811
+ if (deleteResult) {
8812
+ log(`Extension context deleted: ${this.contextName} (ID: ${this.contextId})`);
8813
+ return true;
8814
+ } else {
8815
+ logError(`Warning: Failed to delete extension context: ${this.contextName}`, new Error("Delete operation returned false"));
8816
+ return false;
8817
+ }
8818
+ } catch (error) {
8819
+ logError(`Warning: Failed to delete extension context:`, error);
8820
+ return false;
8821
+ }
8822
+ }
8823
+ /**
8824
+ * Deletes a browser extension from the current context.
8825
+ *
8826
+ * @param extensionId - ID of the extension to delete.
8827
+ * @returns Promise that resolves to true if deletion was successful, false otherwise.
8828
+ */
8829
+ async delete(extensionId) {
8830
+ await this._ensureInitialized();
8831
+ const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;
8832
+ try {
8833
+ const deleteResult = await this.contextService.deleteFile(this.contextId, remotePath);
8834
+ return deleteResult.success;
8835
+ } catch (error) {
8836
+ logError(`An error occurred while deleting browser extension '${extensionId}':`, error);
8837
+ return false;
8838
+ }
8839
+ }
8840
+ /**
8841
+ * Create an ExtensionOption for the current context with specified extension IDs.
8842
+ *
8843
+ * This is a convenience method that creates an ExtensionOption using the current
8844
+ * service's contextId and the provided extension IDs. This option can then be
8845
+ * used with BrowserContext for browser session creation.
8846
+ *
8847
+ * @param extensionIds - List of extension IDs to include in the option.
8848
+ * These should be extensions that exist in the current context.
8849
+ * @returns ExtensionOption configuration object for browser extension integration.
8850
+ * @throws {Error} If extensionIds is empty or invalid.
8851
+ *
8852
+ * @example
8853
+ * ```typescript
8854
+ * // Create extensions
8855
+ * const ext1 = await extensionsService.create("/path/to/ext1.zip");
8856
+ * const ext2 = await extensionsService.create("/path/to/ext2.zip");
8857
+ *
8858
+ * // Create extension option for browser integration
8859
+ * const extOption = extensionsService.createExtensionOption([ext1.id, ext2.id]);
8860
+ *
8861
+ * // Use with BrowserContext
8862
+ * const browserContext = new BrowserContext({
8863
+ * contextId: "browser_session",
8864
+ * autoUpload: true,
8865
+ * extensionContextId: extOption.contextId,
8866
+ * extensionIds: extOption.extensionIds
8867
+ * });
8868
+ * ```
8869
+ */
8870
+ createExtensionOption(extensionIds) {
8871
+ if (!this.contextId) {
8872
+ throw new Error("Service not initialized. Please call an async method first or ensure context is created.");
8873
+ }
8874
+ return new ExtensionOption(
8875
+ this.contextId,
8876
+ extensionIds
8877
+ );
8878
+ }
8879
+ };
8880
+ __name(_ExtensionsService, "ExtensionsService");
8881
+ var ExtensionsService = _ExtensionsService;
8882
+
8499
8883
  // src/context-sync.ts
8500
8884
  init_esm_shims();
8501
8885
  var UploadStrategy = /* @__PURE__ */ ((UploadStrategy2) => {
@@ -8506,12 +8890,41 @@ var DownloadStrategy = /* @__PURE__ */ ((DownloadStrategy2) => {
8506
8890
  DownloadStrategy2["DownloadAsync"] = "DownloadAsync";
8507
8891
  return DownloadStrategy2;
8508
8892
  })(DownloadStrategy || {});
8893
+ var _ExtractPolicyClass = class _ExtractPolicyClass {
8894
+ constructor(extract = true, deleteSrcFile = true, extractToCurrentFolder = false) {
8895
+ this.extract = true;
8896
+ this.deleteSrcFile = true;
8897
+ this.extractToCurrentFolder = false;
8898
+ this.extract = extract;
8899
+ this.deleteSrcFile = deleteSrcFile;
8900
+ this.extractToCurrentFolder = extractToCurrentFolder;
8901
+ }
8902
+ /**
8903
+ * Creates a new extract policy with default values
8904
+ */
8905
+ static default() {
8906
+ return new _ExtractPolicyClass();
8907
+ }
8908
+ /**
8909
+ * Converts to plain object for JSON serialization
8910
+ */
8911
+ toDict() {
8912
+ return {
8913
+ extract: this.extract,
8914
+ deleteSrcFile: this.deleteSrcFile,
8915
+ extractToCurrentFolder: this.extractToCurrentFolder
8916
+ };
8917
+ }
8918
+ };
8919
+ __name(_ExtractPolicyClass, "ExtractPolicyClass");
8920
+ var ExtractPolicyClass = _ExtractPolicyClass;
8509
8921
  var _SyncPolicyImpl = class _SyncPolicyImpl {
8510
8922
  constructor(policy) {
8511
8923
  if (policy) {
8512
8924
  this.uploadPolicy = policy.uploadPolicy;
8513
8925
  this.downloadPolicy = policy.downloadPolicy;
8514
8926
  this.deletePolicy = policy.deletePolicy;
8927
+ this.extractPolicy = policy.extractPolicy;
8515
8928
  this.bwList = policy.bwList;
8516
8929
  }
8517
8930
  this.ensureDefaults();
@@ -8526,6 +8939,9 @@ var _SyncPolicyImpl = class _SyncPolicyImpl {
8526
8939
  if (!this.deletePolicy) {
8527
8940
  this.deletePolicy = newDeletePolicy();
8528
8941
  }
8942
+ if (!this.extractPolicy) {
8943
+ this.extractPolicy = newExtractPolicy();
8944
+ }
8529
8945
  if (!this.bwList) {
8530
8946
  this.bwList = {
8531
8947
  whiteLists: [
@@ -8543,6 +8959,7 @@ var _SyncPolicyImpl = class _SyncPolicyImpl {
8543
8959
  uploadPolicy: this.uploadPolicy,
8544
8960
  downloadPolicy: this.downloadPolicy,
8545
8961
  deletePolicy: this.deletePolicy,
8962
+ extractPolicy: this.extractPolicy,
8546
8963
  bwList: this.bwList
8547
8964
  };
8548
8965
  }
@@ -8550,9 +8967,9 @@ var _SyncPolicyImpl = class _SyncPolicyImpl {
8550
8967
  __name(_SyncPolicyImpl, "SyncPolicyImpl");
8551
8968
  var SyncPolicyImpl = _SyncPolicyImpl;
8552
8969
  var _ContextSync = class _ContextSync {
8553
- constructor(contextId, path3, policy) {
8970
+ constructor(contextId, path4, policy) {
8554
8971
  this.contextId = contextId;
8555
- this.path = path3;
8972
+ this.path = path4;
8556
8973
  this.policy = policy;
8557
8974
  }
8558
8975
  // WithPolicy sets the policy and returns the context sync for chaining
@@ -8585,11 +9002,20 @@ function newDeletePolicy() {
8585
9002
  };
8586
9003
  }
8587
9004
  __name(newDeletePolicy, "newDeletePolicy");
9005
+ function newExtractPolicy() {
9006
+ return {
9007
+ extract: true,
9008
+ deleteSrcFile: true,
9009
+ extractToCurrentFolder: false
9010
+ };
9011
+ }
9012
+ __name(newExtractPolicy, "newExtractPolicy");
8588
9013
  function newSyncPolicy() {
8589
9014
  return {
8590
9015
  uploadPolicy: newUploadPolicy(),
8591
9016
  downloadPolicy: newDownloadPolicy(),
8592
9017
  deletePolicy: newDeletePolicy(),
9018
+ extractPolicy: newExtractPolicy(),
8593
9019
  bwList: {
8594
9020
  whiteLists: [
8595
9021
  {
@@ -8605,13 +9031,98 @@ function newSyncPolicyWithDefaults(policy) {
8605
9031
  return new SyncPolicyImpl(policy).toJSON();
8606
9032
  }
8607
9033
  __name(newSyncPolicyWithDefaults, "newSyncPolicyWithDefaults");
8608
- function newContextSync(contextId, path3, policy) {
8609
- return new ContextSync(contextId, path3, policy);
9034
+ function newContextSync(contextId, path4, policy) {
9035
+ return new ContextSync(contextId, path4, policy);
8610
9036
  }
8611
9037
  __name(newContextSync, "newContextSync");
8612
9038
 
8613
9039
  // src/session-params.ts
8614
9040
  init_esm_shims();
9041
+ var _BrowserContext = class _BrowserContext {
9042
+ /**
9043
+ * Initialize BrowserContextImpl with optional extension support.
9044
+ *
9045
+ * @param contextId - ID of the browser context to bind to the session.
9046
+ * This identifies the browser instance for the session.
9047
+ * @param autoUpload - Whether to automatically upload browser data
9048
+ * when the session ends. Defaults to true.
9049
+ * @param extensionOption - Extension configuration object containing
9050
+ * contextId and extensionIds. This encapsulates
9051
+ * all extension-related configuration.
9052
+ * Defaults to undefined.
9053
+ *
9054
+ * Extension Configuration:
9055
+ * - **ExtensionOption**: Use extensionOption parameter with an ExtensionOption object
9056
+ * - **No Extensions**: Don't provide extensionOption parameter
9057
+ *
9058
+ * Auto-generation:
9059
+ * - extensionContextSyncs is automatically generated when extensionOption is provided
9060
+ * - extensionContextSyncs will be undefined if no extensionOption is provided
9061
+ * - extensionContextSyncs will be a ContextSync[] if extensionOption is valid
9062
+ */
9063
+ constructor(contextId, autoUpload = true, extensionOption) {
9064
+ this.contextId = contextId;
9065
+ this.autoUpload = autoUpload;
9066
+ this.extensionOption = extensionOption;
9067
+ if (extensionOption) {
9068
+ this.extensionContextId = extensionOption.contextId;
9069
+ this.extensionIds = extensionOption.extensionIds;
9070
+ this.extensionContextSyncs = this._createExtensionContextSyncs();
9071
+ } else {
9072
+ this.extensionContextId = void 0;
9073
+ this.extensionIds = [];
9074
+ this.extensionContextSyncs = void 0;
9075
+ }
9076
+ }
9077
+ /**
9078
+ * Create ContextSync configurations for browser extensions.
9079
+ *
9080
+ * This method is called only when extensionOption is provided and contains
9081
+ * valid extension configuration (contextId and extensionIds).
9082
+ *
9083
+ * @returns ContextSync[] - List of context sync configurations for extensions.
9084
+ * Returns empty list if extension configuration is invalid.
9085
+ */
9086
+ _createExtensionContextSyncs() {
9087
+ if (!this.extensionIds || this.extensionIds.length === 0 || !this.extensionContextId) {
9088
+ return [];
9089
+ }
9090
+ const whiteLists = this.extensionIds.map((extId) => ({
9091
+ path: extId,
9092
+ excludePaths: []
9093
+ }));
9094
+ const syncPolicy = {
9095
+ uploadPolicy: {
9096
+ ...newUploadPolicy(),
9097
+ autoUpload: false
9098
+ },
9099
+ extractPolicy: {
9100
+ ...newExtractPolicy(),
9101
+ extract: true,
9102
+ deleteSrcFile: true
9103
+ },
9104
+ bwList: {
9105
+ whiteLists
9106
+ }
9107
+ };
9108
+ const extensionSync = new ContextSync(
9109
+ this.extensionContextId,
9110
+ "/tmp/extensions/",
9111
+ syncPolicy
9112
+ );
9113
+ return [extensionSync];
9114
+ }
9115
+ /**
9116
+ * Get all context syncs including extension syncs.
9117
+ *
9118
+ * @returns ContextSync[] - All context sync configurations. Returns empty list if no extensions configured.
9119
+ */
9120
+ getAllContextSyncs() {
9121
+ return this.extensionContextSyncs || [];
9122
+ }
9123
+ };
9124
+ __name(_BrowserContext, "BrowserContext");
9125
+ var BrowserContext = _BrowserContext;
8615
9126
  var _CreateSessionParams = class _CreateSessionParams {
8616
9127
  constructor() {
8617
9128
  this.labels = {};
@@ -8674,8 +9185,8 @@ var _CreateSessionParams = class _CreateSessionParams {
8674
9185
  /**
8675
9186
  * AddContextSync adds a context sync configuration to the session parameters.
8676
9187
  */
8677
- addContextSync(contextId, path3, policy) {
8678
- const contextSync = new ContextSync(contextId, path3, policy);
9188
+ addContextSync(contextId, path4, policy) {
9189
+ const contextSync = new ContextSync(contextId, path4, policy);
8679
9190
  this.contextSync.push(contextSync);
8680
9191
  return this;
8681
9192
  }
@@ -8697,10 +9208,15 @@ var _CreateSessionParams = class _CreateSessionParams {
8697
9208
  * Convert to plain object for JSON serialization
8698
9209
  */
8699
9210
  toJSON() {
9211
+ let allContextSyncs = [...this.contextSync];
9212
+ if (this.browserContext && "getAllContextSyncs" in this.browserContext) {
9213
+ const extensionSyncs = this.browserContext.getAllContextSyncs();
9214
+ allContextSyncs = allContextSyncs.concat(extensionSyncs);
9215
+ }
8700
9216
  return {
8701
9217
  labels: this.labels,
8702
9218
  imageId: this.imageId,
8703
- contextSync: this.contextSync,
9219
+ contextSync: allContextSyncs,
8704
9220
  browserContext: this.browserContext,
8705
9221
  isVpc: this.isVpc,
8706
9222
  mcpPolicyId: this.mcpPolicyId
@@ -8714,7 +9230,18 @@ var _CreateSessionParams = class _CreateSessionParams {
8714
9230
  params.labels = config.labels || {};
8715
9231
  params.imageId = config.imageId;
8716
9232
  params.contextSync = config.contextSync || [];
8717
- params.browserContext = config.browserContext;
9233
+ if (config.browserContext) {
9234
+ if ("getAllContextSyncs" in config.browserContext) {
9235
+ params.browserContext = config.browserContext;
9236
+ } else {
9237
+ const bc = config.browserContext;
9238
+ params.browserContext = new BrowserContext(
9239
+ bc.contextId,
9240
+ bc.autoUpload,
9241
+ bc.extensionOption
9242
+ );
9243
+ }
9244
+ }
8718
9245
  params.isVpc = config.isVpc || false;
8719
9246
  params.mcpPolicyId = config.mcpPolicyId;
8720
9247
  return params;
@@ -8740,6 +9267,7 @@ export {
8740
9267
  AuthenticationError,
8741
9268
  Browser,
8742
9269
  BrowserAgent,
9270
+ BrowserContext,
8743
9271
  BrowserError,
8744
9272
  BrowserOptionClass,
8745
9273
  BrowserProxyClass,
@@ -8770,6 +9298,10 @@ export {
8770
9298
  DescribeContextFilesResponse,
8771
9299
  DescribeContextFilesResponseBody,
8772
9300
  DownloadStrategy,
9301
+ Extension,
9302
+ ExtensionOption,
9303
+ ExtensionsService,
9304
+ ExtractPolicyClass,
8773
9305
  FileError,
8774
9306
  FileSystem,
8775
9307
  GetContextFileDownloadUrlRequest,
@@ -8835,6 +9367,8 @@ export {
8835
9367
  UI,
8836
9368
  UIError,
8837
9369
  UploadStrategy,
9370
+ loadConfig,
9371
+ loadDotEnv,
8838
9372
  log,
8839
9373
  logError,
8840
9374
  newContextManager,
@@ -8842,6 +9376,7 @@ export {
8842
9376
  newCreateSessionParams,
8843
9377
  newDeletePolicy,
8844
9378
  newDownloadPolicy,
9379
+ newExtractPolicy,
8845
9380
  newSyncPolicy,
8846
9381
  newSyncPolicyWithDefaults,
8847
9382
  newUploadPolicy