@diegosouzacdv/jev-browser-mcp 0.6.2 → 0.7.1

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.
@@ -170,11 +170,20 @@ function validProviderUrl(value) {
170
170
  return parsed.toString();
171
171
  }
172
172
 
173
- function profileDirectory(template, channel, override) {
174
- const value = expandHomeDirectory(override?.trim() || template.replace("{browser}", channel));
175
- if (!path.isAbsolute(value)) throw new JevBrowserError("JEV_BROWSER_PROFILE must be an absolute path");
176
- return requireOutsidePackage(path.resolve(value), "browser profile");
177
- }
173
+ function profileDirectory(template, channel, sessionId, override) {
174
+ const requestedOverride = override?.trim();
175
+ const unsupportedPlaceholder = requestedOverride?.replaceAll("{session}", "");
176
+ if (unsupportedPlaceholder?.includes("{") || unsupportedPlaceholder?.includes("}")) {
177
+ throw new JevBrowserError("JEV_BROWSER_PROFILE supports only the {session} placeholder");
178
+ }
179
+ const hasSessionPlaceholder = Boolean(requestedOverride?.includes("{session}"));
180
+ const profileBase = requestedOverride?.replaceAll("{session}", sessionId);
181
+ const value = expandHomeDirectory(requestedOverride
182
+ ? hasSessionPlaceholder ? profileBase : `${profileBase}-session-${sessionId}`
183
+ : template.replace("{browser}", channel).replace("{session}", sessionId));
184
+ if (!path.isAbsolute(value)) throw new JevBrowserError("JEV_BROWSER_PROFILE must be an absolute path");
185
+ return requireOutsidePackage(path.resolve(value), "browser profile");
186
+ }
178
187
 
179
188
  export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {}) {
180
189
  let document;
@@ -213,12 +222,17 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
213
222
  if (!new Set(["chrome", "msedge"]).has(channel)) {
214
223
  throw new JevBrowserError("JEV_BROWSER_CHANNEL must be chrome or msedge");
215
224
  }
216
- const profileTemplate = document.browser.computer_user_data_dir;
217
- const profileRemainder = typeof profileTemplate === "string" ? profileTemplate.replace("{browser}", "") : "";
218
- if (typeof profileTemplate !== "string" || profileTemplate.split("{browser}").length !== 2
219
- || profileRemainder.includes("{") || profileRemainder.includes("}")) {
220
- throw new JevBrowserError("config/ui-testing.json browser.computer_user_data_dir must contain {browser}");
221
- }
225
+ const profileTemplate = document.browser.computer_user_data_dir;
226
+ const profileRemainder = typeof profileTemplate === "string"
227
+ ? profileTemplate.replace("{browser}", "").replace("{session}", "") : "";
228
+ if (typeof profileTemplate !== "string" || profileTemplate.split("{browser}").length !== 2
229
+ || profileTemplate.split("{session}").length !== 2 || profileRemainder.includes("{") || profileRemainder.includes("}")) {
230
+ throw new JevBrowserError("config/ui-testing.json browser.computer_user_data_dir must contain {browser} and {session}");
231
+ }
232
+ const sessionId = (env.JEV_BROWSER_SESSION_ID?.trim() || `pid-${process.pid}`);
233
+ if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(sessionId)) {
234
+ throw new JevBrowserError("JEV_BROWSER_SESSION_ID must contain 1-64 letters, numbers, underscores, or hyphens");
235
+ }
222
236
 
223
237
  const configuredProviderUrl = validProviderUrl(document.jev.provider_url);
224
238
  const providerUrl = validProviderUrl(env.JEV_PROVIDER_URL?.trim() || configuredProviderUrl);
@@ -296,7 +310,8 @@ export function loadSettings({ env = process.env, configPath = CONFIG_PATH } = {
296
310
  browser: Object.freeze({
297
311
  mode,
298
312
  channel,
299
- profileDir: profileDirectory(profileTemplate, channel, env.JEV_BROWSER_PROFILE),
313
+ profileDir: profileDirectory(profileTemplate, channel, sessionId, env.JEV_BROWSER_PROFILE),
314
+ sessionId,
300
315
  maxFlowSteps: positiveNumber(document.browser.max_flow_steps, "browser.max_flow_steps", true),
301
316
  maxTextEntryChars: positiveNumber(document.browser.max_text_entry_chars, "browser.max_text_entry_chars", true),
302
317
  actionTimeoutMs: positiveNumber(browserOptions.max_action_timeout_seconds, "jev_browser_mcp.browser.max_action_timeout_seconds") * 1000,