@quanta-intellect/vessel-browser 0.1.148 → 0.1.153

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/out/main/index.js CHANGED
@@ -11482,9 +11482,7 @@ async function fetchCodexBackendModelsWithRefresh(tokens) {
11482
11482
  return await fetchCodexBackendModels(freshTokens);
11483
11483
  } catch (err) {
11484
11484
  if (err instanceof CodexBackendModelDiscoveryError && err.status === 401) {
11485
- return fetchCodexBackendModels(
11486
- await refreshCodexTokensForDiscovery(freshTokens)
11487
- );
11485
+ return fetchCodexBackendModels(await refreshCodexTokensForDiscovery(freshTokens));
11488
11486
  }
11489
11487
  throw err;
11490
11488
  }
@@ -11511,38 +11509,65 @@ async function fetchProviderModels(config) {
11511
11509
  if (error) {
11512
11510
  throw new Error(error);
11513
11511
  }
11514
- if (normalized.id === "anthropic") {
11515
- const client2 = new Anthropic({ apiKey: normalized.apiKey });
11516
- const page2 = await client2.models.list();
11517
- return okResult({ models: page2.data.map((model) => model.id) });
11512
+ const handler = PROVIDER_HANDLERS.get(normalized.id) ?? openAICompatHandler;
11513
+ return handler.listModels(normalized);
11514
+ }
11515
+ function createProvider(config) {
11516
+ const normalized = sanitizeProviderConfig(config);
11517
+ const error = validateProviderConfig(normalized);
11518
+ if (error) {
11519
+ throw new Error(error);
11518
11520
  }
11519
- if (normalized.id === "openai_codex") {
11520
- const tokens = readStoredCodexTokens();
11521
- if (!tokens) {
11522
- throw new Error("Codex provider requires authentication. Connect your ChatGPT account in settings.");
11523
- }
11524
- try {
11525
- const models2 = await fetchCodexBackendModelsWithRefresh(tokens);
11526
- if (models2.length > 0) {
11527
- return okResult({ models: models2 });
11528
- }
11529
- throw new Error("Codex backend model discovery returned no models");
11530
- } catch (err) {
11531
- return okResult({
11532
- models: PROVIDERS.openai_codex.models,
11533
- warning: `Using built-in Codex model list because live discovery failed: ${err instanceof Error ? err.message : "Unknown error"}`
11534
- });
11521
+ const handler = PROVIDER_HANDLERS.get(normalized.id) ?? openAICompatHandler;
11522
+ return handler.create(normalized);
11523
+ }
11524
+ async function listAnthropicModels(config) {
11525
+ const client = new Anthropic({ apiKey: config.apiKey });
11526
+ const page = await client.models.list();
11527
+ return okResult({ models: page.data.map((model) => model.id) });
11528
+ }
11529
+ function createAnthropicProvider(config) {
11530
+ return new AnthropicProvider(config.apiKey, config.model, config.reasoningEffort ?? "off");
11531
+ }
11532
+ async function listCodexModels(_config) {
11533
+ const tokens = readStoredCodexTokens();
11534
+ if (!tokens) {
11535
+ throw new Error(
11536
+ "Codex provider requires authentication. Connect your ChatGPT account in settings."
11537
+ );
11538
+ }
11539
+ try {
11540
+ const models = await fetchCodexBackendModelsWithRefresh(tokens);
11541
+ if (models.length > 0) {
11542
+ return okResult({ models });
11535
11543
  }
11544
+ throw new Error("Codex backend model discovery returned no models");
11545
+ } catch (err) {
11546
+ return okResult({
11547
+ models: PROVIDERS.openai_codex.models,
11548
+ warning: `Using built-in Codex model list because live discovery failed: ${err instanceof Error ? err.message : "Unknown error"}`
11549
+ });
11536
11550
  }
11537
- const meta = PROVIDERS[normalized.id];
11538
- const baseURL = normalized.baseUrl || meta?.defaultBaseUrl || "https://api.openai.com/v1";
11551
+ }
11552
+ function createCodexProvider(config) {
11553
+ const tokens = readStoredCodexTokens();
11554
+ if (!tokens) {
11555
+ throw new Error(
11556
+ "OpenAI Codex requires authentication. Open settings to connect your ChatGPT account."
11557
+ );
11558
+ }
11559
+ return new CodexProvider(tokens, config.model);
11560
+ }
11561
+ async function listOpenAICompatModels(config) {
11562
+ const meta = PROVIDERS[config.id];
11563
+ const baseURL = config.baseUrl || meta?.defaultBaseUrl || "https://api.openai.com/v1";
11539
11564
  const client = new OpenAI({
11540
- apiKey: normalized.apiKey || "ollama",
11565
+ apiKey: config.apiKey || "ollama",
11541
11566
  baseURL
11542
11567
  });
11543
11568
  const page = await client.models.list();
11544
11569
  const models = page.data.map((model) => model.id);
11545
- const warning = normalized.id === "llama_cpp" ? await probeLlamaCppCtxWarning(baseURL) : void 0;
11570
+ const warning = config.id === "llama_cpp" ? await probeLlamaCppCtxWarning(baseURL) : void 0;
11546
11571
  return {
11547
11572
  ...okResult({
11548
11573
  models,
@@ -11550,30 +11575,25 @@ async function fetchProviderModels(config) {
11550
11575
  })
11551
11576
  };
11552
11577
  }
11553
- function createProvider(config) {
11554
- const normalized = sanitizeProviderConfig(config);
11555
- const error = validateProviderConfig(normalized);
11556
- if (error) {
11557
- throw new Error(error);
11558
- }
11559
- if (normalized.id === "anthropic") {
11560
- return new AnthropicProvider(
11561
- normalized.apiKey,
11562
- normalized.model,
11563
- normalized.reasoningEffort
11564
- );
11565
- }
11566
- if (normalized.id === "openai_codex") {
11567
- const tokens = readStoredCodexTokens();
11568
- if (!tokens) {
11569
- throw new Error(
11570
- "OpenAI Codex requires authentication. Open settings to connect your ChatGPT account."
11571
- );
11572
- }
11573
- return new CodexProvider(tokens, normalized.model);
11574
- }
11575
- return new OpenAICompatProvider(normalized);
11578
+ function createOpenAICompatProvider(config) {
11579
+ return new OpenAICompatProvider(config);
11576
11580
  }
11581
+ const anthropicHandler = {
11582
+ create: createAnthropicProvider,
11583
+ listModels: listAnthropicModels
11584
+ };
11585
+ const codexHandler = {
11586
+ create: createCodexProvider,
11587
+ listModels: listCodexModels
11588
+ };
11589
+ const openAICompatHandler = {
11590
+ create: createOpenAICompatProvider,
11591
+ listModels: listOpenAICompatModels
11592
+ };
11593
+ const PROVIDER_HANDLERS = /* @__PURE__ */ new Map([
11594
+ ["anthropic", anthropicHandler],
11595
+ ["openai_codex", codexHandler]
11596
+ ]);
11577
11597
  function buildSubAgentSystemPrompt(thread) {
11578
11598
  const domainBlock = thread.blockedDomains.length > 0 ? `
11579
11599
  BLOCKED DOMAINS (never visit): ${thread.blockedDomains.join(", ")}` : "";
@@ -13071,16 +13091,9 @@ function isTextEntryControl$1(el) {
13071
13091
  if (el.disabled) return false;
13072
13092
  if (el.type !== "input" && el.type !== "textarea") return false;
13073
13093
  const inputType = (el.inputType || "text").toLowerCase();
13074
- return ![
13075
- "button",
13076
- "checkbox",
13077
- "file",
13078
- "hidden",
13079
- "image",
13080
- "radio",
13081
- "reset",
13082
- "submit"
13083
- ].includes(inputType);
13094
+ return !["button", "checkbox", "file", "hidden", "image", "radio", "reset", "submit"].includes(
13095
+ inputType
13096
+ );
13084
13097
  }
13085
13098
  function hasRenderedValue(el) {
13086
13099
  return Boolean(summarizeElementValue(el));
@@ -13111,22 +13124,12 @@ function appendFieldAffordances(parts, el) {
13111
13124
  if (hint) parts.push(hint);
13112
13125
  }
13113
13126
  function isQuantityLike(el) {
13114
- const text = [
13115
- el.label,
13116
- el.name,
13117
- el.placeholder,
13118
- el.text,
13119
- el.description,
13120
- el.selector
13121
- ].filter(Boolean).join(" ").toLowerCase();
13127
+ const text = [el.label, el.name, el.placeholder, el.text, el.description, el.selector].filter(Boolean).join(" ").toLowerCase();
13122
13128
  return /\b(qty|quantity|count|items?)\b/.test(text) || el.inputType === "number" && (/\b(quantity|qty|count|items?)\b/.test(text) || el.name === "quantity" || el.name === "qty");
13123
13129
  }
13124
13130
  function getQuantityElements(page) {
13125
13131
  const seen = /* @__PURE__ */ new Set();
13126
- const elements = [
13127
- ...page.interactiveElements,
13128
- ...page.forms.flatMap((form) => form.fields)
13129
- ];
13132
+ const elements = [...page.interactiveElements, ...page.forms.flatMap((form) => form.fields)];
13130
13133
  return elements.filter((el) => {
13131
13134
  if (!isQuantityLike(el)) return false;
13132
13135
  const key2 = String(
@@ -13215,10 +13218,7 @@ function formatCartSnapshot(page) {
13215
13218
  if (quantityElements.length > 0) {
13216
13219
  if (numericQuantities.length === quantityElements.length && numericQuantities.length > 0) {
13217
13220
  const unique = Array.from(new Set(numericQuantities));
13218
- const totalUnits = numericQuantities.reduce(
13219
- (sum, value) => sum + value,
13220
- 0
13221
- );
13221
+ const totalUnits = numericQuantities.reduce((sum, value) => sum + value, 0);
13222
13222
  lines.push(
13223
13223
  unique.length === 1 ? `Quantity controls: ${quantityElements.length} (all set to ${unique[0]})` : `Quantity controls: ${quantityElements.length} (${numericQuantities.join(", ")})`
13224
13224
  );
@@ -13279,9 +13279,7 @@ function dateOrShowtimeControlPriority(el) {
13279
13279
  )) {
13280
13280
  return 0;
13281
13281
  }
13282
- if (/\b(showtimes?|showings?|screenings?|movie times?|date|calendar)\b/.test(
13283
- haystack
13284
- )) {
13282
+ if (/\b(showtimes?|showings?|screenings?|movie times?|date|calendar)\b/.test(haystack)) {
13285
13283
  return 1;
13286
13284
  }
13287
13285
  if (/\b(ticketing|tickets?|formovietickets|seat selection)\b/.test(haystack)) {
@@ -13333,19 +13331,13 @@ function getOffscreenPurchaseActionElements(page) {
13333
13331
  });
13334
13332
  }
13335
13333
  function getDialogFocusedElements(page) {
13336
- return page.interactiveElements.filter(
13337
- (el) => isVisibleToUser(el) && el.context === "dialog"
13338
- );
13334
+ return page.interactiveElements.filter((el) => isVisibleToUser(el) && el.context === "dialog");
13339
13335
  }
13340
13336
  function normalizeOverlayText(value) {
13341
13337
  return (value || "").trim().toLowerCase();
13342
13338
  }
13343
13339
  function isCartConfirmationLike(page) {
13344
- const overlayText = page.overlays.map(
13345
- (overlay) => normalizeOverlayText(
13346
- [overlay.label, overlay.text].filter(Boolean).join(" ")
13347
- )
13348
- ).join(" ");
13340
+ const overlayText = page.overlays.map((overlay) => normalizeOverlayText([overlay.label, overlay.text].filter(Boolean).join(" "))).join(" ");
13349
13341
  const dialogText = getDialogFocusedElements(page).map((el) => normalizeOverlayText(el.text || el.label || el.description)).join(" ");
13350
13342
  const haystack = `${overlayText} ${dialogText}`.trim();
13351
13343
  if (!haystack) return false;
@@ -13473,17 +13465,13 @@ function formatNavigation(nav) {
13473
13465
  function formatForms(forms) {
13474
13466
  if (forms.length === 0) return "None";
13475
13467
  return forms.map((form, index) => {
13476
- const parts = [
13477
- `Form ${index + 1}${form.id ? ` (#${form.id})` : ""}:`
13478
- ];
13468
+ const parts = [`Form ${index + 1}${form.id ? ` (#${form.id})` : ""}:`];
13479
13469
  if (form.action) parts.push(` Action: ${form.action}`);
13480
13470
  if (form.method) parts.push(` Method: ${form.method.toUpperCase()}`);
13481
13471
  if (form.fields.length > 0) {
13482
13472
  parts.push(" Fields:");
13483
13473
  form.fields.forEach((field) => {
13484
- const fieldParts = [
13485
- field.index ? ` [#${field.index}]` : " -"
13486
- ];
13474
+ const fieldParts = [field.index ? ` [#${field.index}]` : " -"];
13487
13475
  if (field.type === "button") {
13488
13476
  fieldParts.push(`[${field.text || "Submit"}]`);
13489
13477
  fieldParts.push(field.role === "radio" ? "radio" : "button");
@@ -13502,9 +13490,7 @@ function formatForms(forms) {
13502
13490
  appendFieldAffordances(fieldParts, field);
13503
13491
  if (field.options?.length) {
13504
13492
  const maxOptions = isDateOrShowtimeControl(field) ? 10 : 5;
13505
- fieldParts.push(
13506
- `options=${formatElementOptions(field.options, maxOptions)}`
13507
- );
13493
+ fieldParts.push(`options=${formatElementOptions(field.options, maxOptions)}`);
13508
13494
  }
13509
13495
  } else if (field.type === "textarea") {
13510
13496
  fieldParts.push(`[${field.label || "Text"}]`);
@@ -13527,10 +13513,7 @@ function formatLandmarks(landmarks) {
13527
13513
  return items.map((lm) => {
13528
13514
  const parts = [`- ${lm.role}`];
13529
13515
  if (lm.label) parts.push(`(label: "${lm.label}")`);
13530
- if (lm.text)
13531
- parts.push(
13532
- `- "${lm.text.slice(0, 100)}${lm.text.length > 100 ? "..." : ""}"`
13533
- );
13516
+ if (lm.text) parts.push(`- "${lm.text.slice(0, 100)}${lm.text.length > 100 ? "..." : ""}"`);
13534
13517
  return parts.join(" ");
13535
13518
  }).join("\n");
13536
13519
  }
@@ -13630,10 +13613,7 @@ function formatStructuredEntities(entities) {
13630
13613
  if (entity.url && entity.url !== entity.name) {
13631
13614
  lines.push(` url: ${entity.url}`);
13632
13615
  }
13633
- for (const [key2, value] of Object.entries(entity.attributes).slice(
13634
- 0,
13635
- 8
13636
- )) {
13616
+ for (const [key2, value] of Object.entries(entity.attributes).slice(0, 8)) {
13637
13617
  const rendered = formatStructuredValue(value);
13638
13618
  if (rendered) {
13639
13619
  lines.push(` ${key2}: ${rendered}`);
@@ -13676,13 +13656,7 @@ function getHighlightsForPage(url) {
13676
13656
  function formatJsonLd(items) {
13677
13657
  if (!items || items.length === 0) return "";
13678
13658
  const lines = [];
13679
- const SKIP = /* @__PURE__ */ new Set([
13680
- "@context",
13681
- "image",
13682
- "logo",
13683
- "thumbnail",
13684
- "potentialAction"
13685
- ]);
13659
+ const SKIP = /* @__PURE__ */ new Set(["@context", "image", "logo", "thumbnail", "potentialAction"]);
13686
13660
  const TYPE_FIELDS = {
13687
13661
  Recipe: [
13688
13662
  "name",
@@ -13695,15 +13669,7 @@ function formatJsonLd(items) {
13695
13669
  "recipeIngredient",
13696
13670
  "recipeInstructions"
13697
13671
  ],
13698
- Article: [
13699
- "headline",
13700
- "name",
13701
- "url",
13702
- "datePublished",
13703
- "dateModified",
13704
- "author",
13705
- "description"
13706
- ],
13672
+ Article: ["headline", "name", "url", "datePublished", "dateModified", "author", "description"],
13707
13673
  Product: ["name", "url", "description", "offers"],
13708
13674
  BreadcrumbList: ["itemListElement"],
13709
13675
  Organization: ["name", "url", "description"]
@@ -13716,8 +13682,7 @@ function formatJsonLd(items) {
13716
13682
  const renderValue = (val, depth = 0) => {
13717
13683
  if (val === null || val === void 0) return "";
13718
13684
  if (typeof val === "string") return val;
13719
- if (typeof val === "number" || typeof val === "boolean")
13720
- return String(val);
13685
+ if (typeof val === "number" || typeof val === "boolean") return String(val);
13721
13686
  if (Array.isArray(val)) {
13722
13687
  if (depth > 0)
13723
13688
  return val.map((v) => renderValue(v, depth + 1)).filter(Boolean).join(", ");
@@ -13752,22 +13717,18 @@ function formatJsonLd(items) {
13752
13717
  }
13753
13718
  function chooseAgentReadMode(page) {
13754
13719
  const pageType = detectPageType(page);
13755
- switch (pageType) {
13756
- case "SEARCH_RESULTS":
13757
- case "PAGINATED_LIST":
13758
- return "results_only";
13759
- case "LOGIN":
13760
- case "SEARCH_READY":
13761
- case "SHOPPING":
13762
- case "FORM":
13763
- return "visible_only";
13764
- case "ARTICLE":
13765
- return "summary";
13766
- case "GENERAL":
13767
- default:
13768
- return "visible_only";
13769
- }
13770
- }
13720
+ return PAGE_TYPE_READ_MODE[pageType];
13721
+ }
13722
+ const PAGE_TYPE_READ_MODE = {
13723
+ LOGIN: "visible_only",
13724
+ SEARCH_READY: "visible_only",
13725
+ SEARCH_RESULTS: "results_only",
13726
+ SHOPPING: "visible_only",
13727
+ FORM: "visible_only",
13728
+ PAGINATED_LIST: "results_only",
13729
+ ARTICLE: "summary",
13730
+ GENERAL: "visible_only"
13731
+ };
13771
13732
  const SITE_RESULT_FILTERS = [
13772
13733
  {
13773
13734
  hostname: "news.ycombinator.com",
@@ -13829,12 +13790,7 @@ function isSiteUtilityLink(element) {
13829
13790
  function isSearchOrListingPage(page) {
13830
13791
  if (isSiteListingPage(page.url)) return true;
13831
13792
  const haystack = normalizeComparable(
13832
- [
13833
- page.url,
13834
- page.title,
13835
- page.excerpt,
13836
- page.headings.map((heading) => heading.text).join(" ")
13837
- ].filter(Boolean).join(" ")
13793
+ [page.url, page.title, page.excerpt, page.headings.map((heading) => heading.text).join(" ")].filter(Boolean).join(" ")
13838
13794
  );
13839
13795
  return /\b(search|results|find|discover|browse|repositories|repository|issues|pull requests|prs|users|events|listings)\b/.test(
13840
13796
  haystack
@@ -13850,9 +13806,7 @@ function collectJsonLdEntityItems(input, results = []) {
13850
13806
  const item = input;
13851
13807
  const type = item["@type"];
13852
13808
  const types = Array.isArray(type) ? type : [type];
13853
- const typeNames = types.filter(
13854
- (entry) => typeof entry === "string"
13855
- );
13809
+ const typeNames = types.filter((entry) => typeof entry === "string");
13856
13810
  if ((typeof item.name === "string" || typeof item.url === "string") && !typeNames.some(
13857
13811
  (entry) => ["BreadcrumbList", "Organization", "WebSite", "WebPage"].includes(entry)
13858
13812
  )) {
@@ -13867,14 +13821,10 @@ function collectJsonLdEntityItems(input, results = []) {
13867
13821
  function getResultCandidates(page) {
13868
13822
  const entityItems = collectJsonLdEntityItems(page.jsonLd ?? []);
13869
13823
  const entityNames = new Set(
13870
- entityItems.map(
13871
- (item) => typeof item.name === "string" ? normalizeComparable(item.name) : ""
13872
- ).filter(Boolean)
13824
+ entityItems.map((item) => typeof item.name === "string" ? normalizeComparable(item.name) : "").filter(Boolean)
13873
13825
  );
13874
13826
  const entityUrls = new Set(
13875
- entityItems.map(
13876
- (item) => typeof item.url === "string" ? normalizeUrlForMatch(item.url) : null
13877
- ).filter((value) => Boolean(value))
13827
+ entityItems.map((item) => typeof item.url === "string" ? normalizeUrlForMatch(item.url) : null).filter((value) => Boolean(value))
13878
13828
  );
13879
13829
  const pageHost = normalizeUrlForMatch(page.url);
13880
13830
  const searchOrListingPage = isSearchOrListingPage(page);
@@ -13897,8 +13847,7 @@ function getResultCandidates(page) {
13897
13847
  score += 4;
13898
13848
  }
13899
13849
  if (element.context === "article") score += 3;
13900
- else if (element.context === "main" || element.context === "content")
13901
- score += 1;
13850
+ else if (element.context === "main" || element.context === "content") score += 1;
13902
13851
  if (href && pageHost) {
13903
13852
  try {
13904
13853
  if (new URL(href).origin === new URL(pageHost).origin) score += 1;
@@ -13912,9 +13861,7 @@ function getResultCandidates(page) {
13912
13861
  score += 2;
13913
13862
  }
13914
13863
  if (/\b(card|tile|result|rating|review)\b/.test(haystack)) score += 1;
13915
- if (/\b(item|list|row|repo|repository|issue|pull request|event)\b/.test(
13916
- haystack
13917
- )) {
13864
+ if (/\b(item|list|row|repo|repository|issue|pull request|event)\b/.test(haystack)) {
13918
13865
  score += 1;
13919
13866
  }
13920
13867
  if (text.length >= 12 && text.split(/\s+/).length >= 2) score += 1;
@@ -13933,9 +13880,7 @@ function getResultCandidates(page) {
13933
13880
  return score >= 4 || score >= 3 && (element.context === "article" || element.context === "main" || element.context === "content");
13934
13881
  }
13935
13882
  return score >= 4 || score >= 3 && element.context === "article";
13936
- }).sort(
13937
- (a, b) => b.score - a.score || (a.element.index ?? 0) - (b.element.index ?? 0)
13938
- );
13883
+ }).sort((a, b) => b.score - a.score || (a.element.index ?? 0) - (b.element.index ?? 0));
13939
13884
  const seen = /* @__PURE__ */ new Set();
13940
13885
  return scored.map(({ element }) => element).filter((element) => {
13941
13886
  const key2 = `${normalizeComparable(element.text || "")}|${normalizeUrlForMatch(element.href) || ""}`;
@@ -13945,365 +13890,362 @@ function getResultCandidates(page) {
13945
13890
  });
13946
13891
  }
13947
13892
  function buildScopedContext(page, mode) {
13948
- switch (mode) {
13949
- case "summary": {
13950
- const sections = [];
13951
- const cartSnapshot = formatCartSnapshot(page);
13952
- sections.push(`**URL:** ${page.url}`);
13953
- sections.push(`**Title:** ${page.title}`);
13954
- sections.push(`**Viewport:** ${formatViewport(page)}`);
13955
- if (page.byline) sections.push(`**Author:** ${page.byline}`);
13956
- if (page.excerpt) sections.push(`**Summary:** ${page.excerpt}`);
13957
- const largePageHint = formatLargePageHint(page);
13958
- if (largePageHint) sections.push(`**Reading Hint:** ${largePageHint}`);
13959
- const scrollHints = getScrollHints(page);
13960
- if (scrollHints.length > 0) {
13961
- sections.push(`**Scroll Hint:** ${scrollHints[0]}`);
13962
- }
13963
- sections.push("");
13964
- const summaryIntent = analyzePageIntent(page);
13965
- if (summaryIntent) {
13966
- sections.push(summaryIntent);
13967
- sections.push("");
13968
- }
13969
- if (cartSnapshot) {
13970
- sections.push("### Cart Snapshot");
13971
- sections.push(cartSnapshot);
13972
- sections.push("");
13973
- }
13974
- if ((page.pageIssues?.length ?? 0) > 0) {
13975
- sections.push("### Page Access Warnings");
13976
- sections.push(formatPageIssues(page.pageIssues ?? []));
13977
- sections.push("");
13978
- }
13979
- sections.push("### Document Outline");
13980
- sections.push(formatHeadings(page.headings));
13981
- sections.push("");
13982
- const summaryHighlights = getHighlightsForPage(page.url);
13983
- sections.push(
13984
- `Stats: ${page.interactiveElements.length} interactives, ${page.forms.length} forms, ${page.navigation.length} nav links, ${page.headings.length} headings, ${page.content.length} chars`
13985
- );
13986
- if (summaryHighlights.length > 0) {
13987
- sections.push("");
13988
- sections.push("### Highlights & Annotations");
13989
- sections.push(formatHighlights(summaryHighlights));
13990
- }
13991
- if ((page.structuredData?.length ?? 0) > 0) {
13992
- if (hasOnlyFallbackStructuredData(page)) {
13993
- const rawSources = [
13994
- (page.jsonLd?.length ?? 0) > 0 ? `${page.jsonLd.length} JSON-LD` : "",
13995
- (page.microdata?.length ?? 0) > 0 ? `${page.microdata.length} microdata` : "",
13996
- (page.rdfa?.length ?? 0) > 0 ? `${page.rdfa.length} RDFa` : ""
13997
- ].filter(Boolean);
13998
- if (rawSources.length > 0) {
13999
- sections.push(
14000
- `Structured data: generic page metadata only (raw sources present: ${rawSources.join(", ")} — use extract_structured_data or read_page with mode=structured for details)`
14001
- );
14002
- } else {
14003
- sections.push("Structured data: generic page metadata only");
14004
- }
14005
- } else {
14006
- sections.push(
14007
- `Structured entities: ${page.structuredData?.map((entity) => entity.types[0]).join(", ")}`
14008
- );
14009
- }
14010
- }
14011
- if (page.overlays.length > 0) {
14012
- sections.push(
14013
- `Blocking overlays: ${page.overlays.filter((overlay) => overlay.blocksInteraction).length}`
14014
- );
14015
- }
14016
- if (page.dormantOverlays.length > 0) {
14017
- sections.push(
14018
- `Dormant consent/modal surfaces: ${page.dormantOverlays.length}`
14019
- );
14020
- }
14021
- return sections.join("\n");
14022
- }
14023
- case "interactives_only": {
14024
- const sections = [];
14025
- const quantityElements = getQuantityElements(page);
14026
- const cartSnapshot = formatCartSnapshot(page);
14027
- const dialogFocus = formatDialogFocus(page);
14028
- sections.push(`**URL:** ${page.url}`);
14029
- sections.push(`**Title:** ${page.title}`);
14030
- sections.push(`**Viewport:** ${formatViewport(page)}`);
14031
- const interactivesScrollHints = getScrollHints(page);
14032
- if (interactivesScrollHints.length > 0) {
14033
- sections.push(`**Scroll Hint:** ${interactivesScrollHints[0]}`);
14034
- }
14035
- sections.push("");
14036
- const interactivesIntent = analyzePageIntent(page);
14037
- if (interactivesIntent) {
14038
- sections.push(interactivesIntent);
14039
- sections.push("");
14040
- }
14041
- const interactivesHighlights = getHighlightsForPage(page.url);
14042
- if (interactivesHighlights.length > 0) {
14043
- sections.push("### Highlights & Annotations");
14044
- sections.push(formatHighlights(interactivesHighlights));
14045
- sections.push("");
14046
- }
14047
- if (cartSnapshot) {
14048
- sections.push("### Cart Snapshot");
14049
- sections.push(cartSnapshot);
14050
- sections.push("");
14051
- }
14052
- if ((page.pageIssues?.length ?? 0) > 0) {
14053
- sections.push("### Page Access Warnings");
14054
- sections.push(formatPageIssues(page.pageIssues ?? []));
14055
- sections.push("");
14056
- }
14057
- if (page.overlays.length > 0) {
14058
- sections.push("### Active Overlays");
14059
- sections.push(formatOverlays(page));
14060
- sections.push("");
14061
- }
14062
- if (dialogFocus) {
14063
- sections.push("### Immediate Overlay Actions");
14064
- sections.push(dialogFocus);
14065
- sections.push("");
14066
- }
14067
- if (page.dormantOverlays.length > 0) {
14068
- sections.push("### Dormant Consent / Modal UI");
14069
- sections.push(formatDormantOverlays(page.dormantOverlays));
14070
- sections.push("");
14071
- }
14072
- if (page.navigation.length > 0) {
14073
- sections.push("### Navigation");
14074
- sections.push(formatNavigation(page.navigation));
14075
- sections.push("");
14076
- }
14077
- if (quantityElements.length > 0) {
14078
- sections.push("### Quantity / Count Controls");
14079
- sections.push(formatQuantityElements(quantityElements));
14080
- sections.push("");
14081
- }
14082
- if (page.interactiveElements.length > 0) {
13893
+ const render = SCOPED_CONTEXT_RENDERERS.get(mode) ?? buildStructuredContext;
13894
+ return render(page);
13895
+ }
13896
+ function buildSummaryContext(page) {
13897
+ const sections = [];
13898
+ const cartSnapshot = formatCartSnapshot(page);
13899
+ sections.push(`**URL:** ${page.url}`);
13900
+ sections.push(`**Title:** ${page.title}`);
13901
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
13902
+ if (page.byline) sections.push(`**Author:** ${page.byline}`);
13903
+ if (page.excerpt) sections.push(`**Summary:** ${page.excerpt}`);
13904
+ const largePageHint = formatLargePageHint(page);
13905
+ if (largePageHint) sections.push(`**Reading Hint:** ${largePageHint}`);
13906
+ const scrollHints = getScrollHints(page);
13907
+ if (scrollHints.length > 0) {
13908
+ sections.push(`**Scroll Hint:** ${scrollHints[0]}`);
13909
+ }
13910
+ sections.push("");
13911
+ const summaryIntent = analyzePageIntent(page);
13912
+ if (summaryIntent) {
13913
+ sections.push(summaryIntent);
13914
+ sections.push("");
13915
+ }
13916
+ if (cartSnapshot) {
13917
+ sections.push("### Cart Snapshot");
13918
+ sections.push(cartSnapshot);
13919
+ sections.push("");
13920
+ }
13921
+ if ((page.pageIssues?.length ?? 0) > 0) {
13922
+ sections.push("### Page Access Warnings");
13923
+ sections.push(formatPageIssues(page.pageIssues ?? []));
13924
+ sections.push("");
13925
+ }
13926
+ sections.push("### Document Outline");
13927
+ sections.push(formatHeadings(page.headings));
13928
+ sections.push("");
13929
+ const summaryHighlights = getHighlightsForPage(page.url);
13930
+ sections.push(
13931
+ `Stats: ${page.interactiveElements.length} interactives, ${page.forms.length} forms, ${page.navigation.length} nav links, ${page.headings.length} headings, ${page.content.length} chars`
13932
+ );
13933
+ if (summaryHighlights.length > 0) {
13934
+ sections.push("");
13935
+ sections.push("### Highlights & Annotations");
13936
+ sections.push(formatHighlights(summaryHighlights));
13937
+ }
13938
+ if ((page.structuredData?.length ?? 0) > 0) {
13939
+ if (hasOnlyFallbackStructuredData(page)) {
13940
+ const rawSources = [
13941
+ (page.jsonLd?.length ?? 0) > 0 ? `${page.jsonLd.length} JSON-LD` : "",
13942
+ (page.microdata?.length ?? 0) > 0 ? `${page.microdata.length} microdata` : "",
13943
+ (page.rdfa?.length ?? 0) > 0 ? `${page.rdfa.length} RDFa` : ""
13944
+ ].filter(Boolean);
13945
+ if (rawSources.length > 0) {
14083
13946
  sections.push(
14084
- `### Interactive Elements (${page.interactiveElements.length})`
13947
+ `Structured data: generic page metadata only (raw sources present: ${rawSources.join(", ")} — use extract_structured_data or read_page with mode=structured for details)`
14085
13948
  );
14086
- sections.push(formatInteractiveElements(page.interactiveElements));
14087
- }
14088
- return sections.join("\n");
14089
- }
14090
- case "forms_only": {
14091
- const sections = [];
14092
- const quantityElements = getQuantityElements(page);
14093
- const cartSnapshot = formatCartSnapshot(page);
14094
- sections.push(`**URL:** ${page.url}`);
14095
- sections.push(`**Title:** ${page.title}`);
14096
- sections.push(`**Viewport:** ${formatViewport(page)}`);
14097
- const visibleScrollHints = getScrollHints(page);
14098
- if (visibleScrollHints.length > 0) {
14099
- sections.push(`**Scroll Hint:** ${visibleScrollHints[0]}`);
14100
- }
14101
- sections.push("");
14102
- const formsHighlights = getHighlightsForPage(page.url);
14103
- if (formsHighlights.length > 0) {
14104
- sections.push("### Highlights & Annotations");
14105
- sections.push(formatHighlights(formsHighlights));
14106
- sections.push("");
14107
- }
14108
- if (cartSnapshot) {
14109
- sections.push("### Cart Snapshot");
14110
- sections.push(cartSnapshot);
14111
- sections.push("");
14112
- }
14113
- if ((page.pageIssues?.length ?? 0) > 0) {
14114
- sections.push("### Page Access Warnings");
14115
- sections.push(formatPageIssues(page.pageIssues ?? []));
14116
- sections.push("");
14117
- }
14118
- if (page.overlays.length > 0) {
14119
- sections.push("### Active Overlays");
14120
- sections.push(formatOverlays(page));
14121
- sections.push("");
14122
- }
14123
- if (page.dormantOverlays.length > 0) {
14124
- sections.push("### Dormant Consent / Modal UI");
14125
- sections.push(formatDormantOverlays(page.dormantOverlays));
14126
- sections.push("");
14127
- }
14128
- if (quantityElements.length > 0) {
14129
- sections.push("### Quantity / Count Controls");
14130
- sections.push(formatQuantityElements(quantityElements));
14131
- sections.push("");
14132
- }
14133
- if (page.forms.length > 0) {
14134
- sections.push(`### Forms (${page.forms.length})`);
14135
- sections.push(formatForms(page.forms));
14136
13949
  } else {
14137
- sections.push("No forms found on this page.");
14138
- }
14139
- return sections.join("\n");
14140
- }
14141
- case "text_only": {
14142
- const sections = [];
14143
- sections.push(`**URL:** ${page.url}`);
14144
- sections.push(`**Title:** ${page.title}`);
14145
- sections.push(`**Viewport:** ${formatViewport(page)}`);
14146
- sections.push("");
14147
- const textHighlights = getHighlightsForPage(page.url);
14148
- if (textHighlights.length > 0) {
14149
- sections.push("### Highlights & Annotations");
14150
- sections.push(formatHighlights(textHighlights));
14151
- sections.push("");
14152
- }
14153
- if ((page.pageIssues?.length ?? 0) > 0) {
14154
- sections.push("### Page Access Warnings");
14155
- sections.push(formatPageIssues(page.pageIssues ?? []));
14156
- sections.push("");
14157
- }
14158
- const truncated = page.content.length > MAX_CONTEXT_CONTENT_LENGTH ? page.content.slice(0, MAX_CONTEXT_CONTENT_LENGTH) + "\n[Content truncated...]" : page.content;
14159
- sections.push(truncated);
14160
- return sections.join("\n");
14161
- }
14162
- case "visible_only": {
14163
- const visibleElements = page.interactiveElements.filter(isVisibleToUser);
14164
- const visibleNav = page.navigation.filter(isVisibleToUser);
14165
- const dialogFocusedElements = getDialogFocusedElements(page);
14166
- const visiblePage = {
14167
- ...page,
14168
- interactiveElements: dialogFocusedElements.length > 0 ? dialogFocusedElements : visibleElements,
14169
- forms: page.forms.map((form) => ({
14170
- ...form,
14171
- fields: form.fields.filter(
14172
- (field) => isVisibleToUser(field) && (dialogFocusedElements.length === 0 || field.context === "dialog")
14173
- )
14174
- })).filter((form) => form.fields.length > 0)
14175
- };
14176
- const quantityElements = getQuantityElements(visiblePage);
14177
- const purchaseActions = getPurchaseActionElements(visiblePage, {
14178
- visibleOnly: true
14179
- });
14180
- const offscreenPurchaseActions = getOffscreenPurchaseActionElements(page);
14181
- const cartSnapshot = formatCartSnapshot(visiblePage);
14182
- const visibleForms = visiblePage.forms;
14183
- const dialogFocus = formatDialogFocus(page);
14184
- const flightBookingFormHint = getFlightBookingFormHint(page);
14185
- const sections = [];
14186
- sections.push(`**URL:** ${page.url}`);
14187
- sections.push(`**Title:** ${page.title}`);
14188
- sections.push(`**Viewport:** ${formatViewport(page)}`);
14189
- sections.push("");
14190
- const visibleHighlights = getHighlightsForPage(page.url);
14191
- if (visibleHighlights.length > 0) {
14192
- sections.push("### Highlights & Annotations");
14193
- sections.push(formatHighlights(visibleHighlights));
14194
- sections.push("");
14195
- }
14196
- if (cartSnapshot) {
14197
- sections.push("### Cart Snapshot");
14198
- sections.push(cartSnapshot);
14199
- sections.push("");
14200
- }
14201
- if ((page.pageIssues?.length ?? 0) > 0) {
14202
- sections.push("### Page Access Warnings");
14203
- sections.push(formatPageIssues(page.pageIssues ?? []));
14204
- sections.push("");
14205
- }
14206
- if (flightBookingFormHint) {
14207
- sections.push("### Flight Booking Hint");
14208
- sections.push(flightBookingFormHint);
14209
- sections.push("");
14210
- }
14211
- if (page.overlays.length > 0) {
14212
- sections.push("### Active Overlays");
14213
- sections.push(formatOverlays(page));
14214
- sections.push("");
14215
- }
14216
- if (dialogFocus) {
14217
- sections.push("### Immediate Overlay Actions");
14218
- sections.push(dialogFocus);
14219
- if (visibleElements.length > dialogFocusedElements.length) {
14220
- sections.push("");
14221
- sections.push(
14222
- `Background controls hidden while the dialog is active: ${visibleElements.length - dialogFocusedElements.length}`
14223
- );
14224
- }
14225
- sections.push("");
14226
- }
14227
- if (page.dormantOverlays.length > 0) {
14228
- sections.push("### Dormant Consent / Modal UI");
14229
- sections.push(formatDormantOverlays(page.dormantOverlays));
14230
- sections.push("");
14231
- }
14232
- if (visibleNav.length > 0) {
14233
- sections.push("### Visible Navigation");
14234
- sections.push(formatNavigation(visibleNav));
14235
- sections.push("");
14236
- }
14237
- if (quantityElements.length > 0) {
14238
- sections.push("### Quantity / Count Controls");
14239
- sections.push(formatQuantityElements(quantityElements));
14240
- sections.push("");
14241
- }
14242
- if (purchaseActions.length > 0) {
14243
- sections.push("### Primary Purchase Actions");
14244
- sections.push(formatInteractiveElements(purchaseActions));
14245
- sections.push("");
14246
- }
14247
- if (offscreenPurchaseActions.length > 0) {
14248
- sections.push("### Offscreen Purchase Actions");
14249
- sections.push(
14250
- "These purchase controls are present on the page but currently outside the viewport. You can scroll to reveal them or click them by index."
14251
- );
14252
- sections.push(formatInteractiveElements(offscreenPurchaseActions));
14253
- sections.push("");
14254
- }
14255
- if (visiblePage.interactiveElements.length > 0) {
14256
- sections.push(
14257
- `### Visible In-Viewport Interactive Elements (${visiblePage.interactiveElements.length})`
14258
- );
14259
- sections.push(
14260
- formatInteractiveElements(visiblePage.interactiveElements)
14261
- );
14262
- sections.push("");
14263
- }
14264
- if (visibleForms.length > 0) {
14265
- sections.push("### Visible Forms");
14266
- sections.push(formatForms(visibleForms));
14267
- } else if (visibleElements.length === 0 && visibleNav.length === 0) {
14268
- sections.push(
14269
- "No currently visible, unobstructed interactive elements were detected in the viewport."
14270
- );
13950
+ sections.push("Structured data: generic page metadata only");
14271
13951
  }
14272
- return sections.join("\n");
13952
+ } else {
13953
+ sections.push(
13954
+ `Structured entities: ${page.structuredData?.map((entity) => entity.types[0]).join(", ")}`
13955
+ );
14273
13956
  }
14274
- case "results_only": {
14275
- const resultElements = getResultCandidates(page);
14276
- const sections = [];
14277
- sections.push(`**URL:** ${page.url}`);
14278
- sections.push(`**Title:** ${page.title}`);
14279
- sections.push(`**Viewport:** ${formatViewport(page)}`);
13957
+ }
13958
+ if (page.overlays.length > 0) {
13959
+ sections.push(
13960
+ `Blocking overlays: ${page.overlays.filter((overlay) => overlay.blocksInteraction).length}`
13961
+ );
13962
+ }
13963
+ if (page.dormantOverlays.length > 0) {
13964
+ sections.push(`Dormant consent/modal surfaces: ${page.dormantOverlays.length}`);
13965
+ }
13966
+ return sections.join("\n");
13967
+ }
13968
+ function buildInteractivesOnlyContext(page) {
13969
+ const sections = [];
13970
+ const quantityElements = getQuantityElements(page);
13971
+ const cartSnapshot = formatCartSnapshot(page);
13972
+ const dialogFocus = formatDialogFocus(page);
13973
+ sections.push(`**URL:** ${page.url}`);
13974
+ sections.push(`**Title:** ${page.title}`);
13975
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
13976
+ const interactivesScrollHints = getScrollHints(page);
13977
+ if (interactivesScrollHints.length > 0) {
13978
+ sections.push(`**Scroll Hint:** ${interactivesScrollHints[0]}`);
13979
+ }
13980
+ sections.push("");
13981
+ const interactivesIntent = analyzePageIntent(page);
13982
+ if (interactivesIntent) {
13983
+ sections.push(interactivesIntent);
13984
+ sections.push("");
13985
+ }
13986
+ const interactivesHighlights = getHighlightsForPage(page.url);
13987
+ if (interactivesHighlights.length > 0) {
13988
+ sections.push("### Highlights & Annotations");
13989
+ sections.push(formatHighlights(interactivesHighlights));
13990
+ sections.push("");
13991
+ }
13992
+ if (cartSnapshot) {
13993
+ sections.push("### Cart Snapshot");
13994
+ sections.push(cartSnapshot);
13995
+ sections.push("");
13996
+ }
13997
+ if ((page.pageIssues?.length ?? 0) > 0) {
13998
+ sections.push("### Page Access Warnings");
13999
+ sections.push(formatPageIssues(page.pageIssues ?? []));
14000
+ sections.push("");
14001
+ }
14002
+ if (page.overlays.length > 0) {
14003
+ sections.push("### Active Overlays");
14004
+ sections.push(formatOverlays(page));
14005
+ sections.push("");
14006
+ }
14007
+ if (dialogFocus) {
14008
+ sections.push("### Immediate Overlay Actions");
14009
+ sections.push(dialogFocus);
14010
+ sections.push("");
14011
+ }
14012
+ if (page.dormantOverlays.length > 0) {
14013
+ sections.push("### Dormant Consent / Modal UI");
14014
+ sections.push(formatDormantOverlays(page.dormantOverlays));
14015
+ sections.push("");
14016
+ }
14017
+ if (page.navigation.length > 0) {
14018
+ sections.push("### Navigation");
14019
+ sections.push(formatNavigation(page.navigation));
14020
+ sections.push("");
14021
+ }
14022
+ if (quantityElements.length > 0) {
14023
+ sections.push("### Quantity / Count Controls");
14024
+ sections.push(formatQuantityElements(quantityElements));
14025
+ sections.push("");
14026
+ }
14027
+ if (page.interactiveElements.length > 0) {
14028
+ sections.push(`### Interactive Elements (${page.interactiveElements.length})`);
14029
+ sections.push(formatInteractiveElements(page.interactiveElements));
14030
+ }
14031
+ return sections.join("\n");
14032
+ }
14033
+ function buildFormsOnlyContext(page) {
14034
+ const sections = [];
14035
+ const quantityElements = getQuantityElements(page);
14036
+ const cartSnapshot = formatCartSnapshot(page);
14037
+ sections.push(`**URL:** ${page.url}`);
14038
+ sections.push(`**Title:** ${page.title}`);
14039
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
14040
+ const visibleScrollHints = getScrollHints(page);
14041
+ if (visibleScrollHints.length > 0) {
14042
+ sections.push(`**Scroll Hint:** ${visibleScrollHints[0]}`);
14043
+ }
14044
+ sections.push("");
14045
+ const formsHighlights = getHighlightsForPage(page.url);
14046
+ if (formsHighlights.length > 0) {
14047
+ sections.push("### Highlights & Annotations");
14048
+ sections.push(formatHighlights(formsHighlights));
14049
+ sections.push("");
14050
+ }
14051
+ if (cartSnapshot) {
14052
+ sections.push("### Cart Snapshot");
14053
+ sections.push(cartSnapshot);
14054
+ sections.push("");
14055
+ }
14056
+ if ((page.pageIssues?.length ?? 0) > 0) {
14057
+ sections.push("### Page Access Warnings");
14058
+ sections.push(formatPageIssues(page.pageIssues ?? []));
14059
+ sections.push("");
14060
+ }
14061
+ if (page.overlays.length > 0) {
14062
+ sections.push("### Active Overlays");
14063
+ sections.push(formatOverlays(page));
14064
+ sections.push("");
14065
+ }
14066
+ if (page.dormantOverlays.length > 0) {
14067
+ sections.push("### Dormant Consent / Modal UI");
14068
+ sections.push(formatDormantOverlays(page.dormantOverlays));
14069
+ sections.push("");
14070
+ }
14071
+ if (quantityElements.length > 0) {
14072
+ sections.push("### Quantity / Count Controls");
14073
+ sections.push(formatQuantityElements(quantityElements));
14074
+ sections.push("");
14075
+ }
14076
+ if (page.forms.length > 0) {
14077
+ sections.push(`### Forms (${page.forms.length})`);
14078
+ sections.push(formatForms(page.forms));
14079
+ } else {
14080
+ sections.push("No forms found on this page.");
14081
+ }
14082
+ return sections.join("\n");
14083
+ }
14084
+ function buildTextOnlyContext(page) {
14085
+ const sections = [];
14086
+ sections.push(`**URL:** ${page.url}`);
14087
+ sections.push(`**Title:** ${page.title}`);
14088
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
14089
+ sections.push("");
14090
+ const textHighlights = getHighlightsForPage(page.url);
14091
+ if (textHighlights.length > 0) {
14092
+ sections.push("### Highlights & Annotations");
14093
+ sections.push(formatHighlights(textHighlights));
14094
+ sections.push("");
14095
+ }
14096
+ if ((page.pageIssues?.length ?? 0) > 0) {
14097
+ sections.push("### Page Access Warnings");
14098
+ sections.push(formatPageIssues(page.pageIssues ?? []));
14099
+ sections.push("");
14100
+ }
14101
+ const truncated = page.content.length > MAX_CONTEXT_CONTENT_LENGTH ? page.content.slice(0, MAX_CONTEXT_CONTENT_LENGTH) + "\n[Content truncated...]" : page.content;
14102
+ sections.push(truncated);
14103
+ return sections.join("\n");
14104
+ }
14105
+ function buildVisibleOnlyContext(page) {
14106
+ const visibleElements = page.interactiveElements.filter(isVisibleToUser);
14107
+ const visibleNav = page.navigation.filter(isVisibleToUser);
14108
+ const dialogFocusedElements = getDialogFocusedElements(page);
14109
+ const visiblePage = {
14110
+ ...page,
14111
+ interactiveElements: dialogFocusedElements.length > 0 ? dialogFocusedElements : visibleElements,
14112
+ forms: page.forms.map((form) => ({
14113
+ ...form,
14114
+ fields: form.fields.filter(
14115
+ (field) => isVisibleToUser(field) && (dialogFocusedElements.length === 0 || field.context === "dialog")
14116
+ )
14117
+ })).filter((form) => form.fields.length > 0)
14118
+ };
14119
+ const quantityElements = getQuantityElements(visiblePage);
14120
+ const purchaseActions = getPurchaseActionElements(visiblePage, {
14121
+ visibleOnly: true
14122
+ });
14123
+ const offscreenPurchaseActions = getOffscreenPurchaseActionElements(page);
14124
+ const cartSnapshot = formatCartSnapshot(visiblePage);
14125
+ const visibleForms = visiblePage.forms;
14126
+ const dialogFocus = formatDialogFocus(page);
14127
+ const flightBookingFormHint = getFlightBookingFormHint(page);
14128
+ const sections = [];
14129
+ sections.push(`**URL:** ${page.url}`);
14130
+ sections.push(`**Title:** ${page.title}`);
14131
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
14132
+ sections.push("");
14133
+ const visibleHighlights = getHighlightsForPage(page.url);
14134
+ if (visibleHighlights.length > 0) {
14135
+ sections.push("### Highlights & Annotations");
14136
+ sections.push(formatHighlights(visibleHighlights));
14137
+ sections.push("");
14138
+ }
14139
+ if (cartSnapshot) {
14140
+ sections.push("### Cart Snapshot");
14141
+ sections.push(cartSnapshot);
14142
+ sections.push("");
14143
+ }
14144
+ if ((page.pageIssues?.length ?? 0) > 0) {
14145
+ sections.push("### Page Access Warnings");
14146
+ sections.push(formatPageIssues(page.pageIssues ?? []));
14147
+ sections.push("");
14148
+ }
14149
+ if (flightBookingFormHint) {
14150
+ sections.push("### Flight Booking Hint");
14151
+ sections.push(flightBookingFormHint);
14152
+ sections.push("");
14153
+ }
14154
+ if (page.overlays.length > 0) {
14155
+ sections.push("### Active Overlays");
14156
+ sections.push(formatOverlays(page));
14157
+ sections.push("");
14158
+ }
14159
+ if (dialogFocus) {
14160
+ sections.push("### Immediate Overlay Actions");
14161
+ sections.push(dialogFocus);
14162
+ if (visibleElements.length > dialogFocusedElements.length) {
14280
14163
  sections.push("");
14281
- const resultsHighlights = getHighlightsForPage(page.url);
14282
- if (resultsHighlights.length > 0) {
14283
- sections.push("### Highlights & Annotations");
14284
- sections.push(formatHighlights(resultsHighlights));
14285
- sections.push("");
14286
- }
14287
- if ((page.pageIssues?.length ?? 0) > 0) {
14288
- sections.push("### Page Access Warnings");
14289
- sections.push(formatPageIssues(page.pageIssues ?? []));
14290
- sections.push("");
14291
- }
14292
- if (resultElements.length > 0) {
14293
- sections.push(`### Likely Search Results (${resultElements.length})`);
14294
- sections.push(formatInteractiveElements(resultElements));
14295
- } else {
14296
- sections.push(
14297
- "No likely primary result links were detected on this page."
14298
- );
14299
- }
14300
- return sections.join("\n");
14164
+ sections.push(
14165
+ `Background controls hidden while the dialog is active: ${visibleElements.length - dialogFocusedElements.length}`
14166
+ );
14301
14167
  }
14302
- case "full":
14303
- default:
14304
- return buildStructuredContext(page);
14168
+ sections.push("");
14169
+ }
14170
+ if (page.dormantOverlays.length > 0) {
14171
+ sections.push("### Dormant Consent / Modal UI");
14172
+ sections.push(formatDormantOverlays(page.dormantOverlays));
14173
+ sections.push("");
14174
+ }
14175
+ if (visibleNav.length > 0) {
14176
+ sections.push("### Visible Navigation");
14177
+ sections.push(formatNavigation(visibleNav));
14178
+ sections.push("");
14179
+ }
14180
+ if (quantityElements.length > 0) {
14181
+ sections.push("### Quantity / Count Controls");
14182
+ sections.push(formatQuantityElements(quantityElements));
14183
+ sections.push("");
14184
+ }
14185
+ if (purchaseActions.length > 0) {
14186
+ sections.push("### Primary Purchase Actions");
14187
+ sections.push(formatInteractiveElements(purchaseActions));
14188
+ sections.push("");
14189
+ }
14190
+ if (offscreenPurchaseActions.length > 0) {
14191
+ sections.push("### Offscreen Purchase Actions");
14192
+ sections.push(
14193
+ "These purchase controls are present on the page but currently outside the viewport. You can scroll to reveal them or click them by index."
14194
+ );
14195
+ sections.push(formatInteractiveElements(offscreenPurchaseActions));
14196
+ sections.push("");
14197
+ }
14198
+ if (visiblePage.interactiveElements.length > 0) {
14199
+ sections.push(
14200
+ `### Visible In-Viewport Interactive Elements (${visiblePage.interactiveElements.length})`
14201
+ );
14202
+ sections.push(formatInteractiveElements(visiblePage.interactiveElements));
14203
+ sections.push("");
14305
14204
  }
14205
+ if (visibleForms.length > 0) {
14206
+ sections.push("### Visible Forms");
14207
+ sections.push(formatForms(visibleForms));
14208
+ } else if (visibleElements.length === 0 && visibleNav.length === 0) {
14209
+ sections.push(
14210
+ "No currently visible, unobstructed interactive elements were detected in the viewport."
14211
+ );
14212
+ }
14213
+ return sections.join("\n");
14214
+ }
14215
+ function buildResultsOnlyContext(page) {
14216
+ const resultElements = getResultCandidates(page);
14217
+ const sections = [];
14218
+ sections.push(`**URL:** ${page.url}`);
14219
+ sections.push(`**Title:** ${page.title}`);
14220
+ sections.push(`**Viewport:** ${formatViewport(page)}`);
14221
+ sections.push("");
14222
+ const resultsHighlights = getHighlightsForPage(page.url);
14223
+ if (resultsHighlights.length > 0) {
14224
+ sections.push("### Highlights & Annotations");
14225
+ sections.push(formatHighlights(resultsHighlights));
14226
+ sections.push("");
14227
+ }
14228
+ if ((page.pageIssues?.length ?? 0) > 0) {
14229
+ sections.push("### Page Access Warnings");
14230
+ sections.push(formatPageIssues(page.pageIssues ?? []));
14231
+ sections.push("");
14232
+ }
14233
+ if (resultElements.length > 0) {
14234
+ sections.push(`### Likely Search Results (${resultElements.length})`);
14235
+ sections.push(formatInteractiveElements(resultElements));
14236
+ } else {
14237
+ sections.push("No likely primary result links were detected on this page.");
14238
+ }
14239
+ return sections.join("\n");
14306
14240
  }
14241
+ const SCOPED_CONTEXT_RENDERERS = /* @__PURE__ */ new Map([
14242
+ ["summary", buildSummaryContext],
14243
+ ["interactives_only", buildInteractivesOnlyContext],
14244
+ ["forms_only", buildFormsOnlyContext],
14245
+ ["text_only", buildTextOnlyContext],
14246
+ ["visible_only", buildVisibleOnlyContext],
14247
+ ["results_only", buildResultsOnlyContext]
14248
+ ]);
14307
14249
  function detectPageType(page) {
14308
14250
  const url = page.url.toLowerCase();
14309
14251
  const hasPasswordField = page.forms.some(
@@ -14313,9 +14255,7 @@ function detectPageType(page) {
14313
14255
  (el) => el.inputType === "search" || el.name === "q" || el.name === "query" || el.name === "search" || (el.placeholder || "").toLowerCase().includes("search")
14314
14256
  );
14315
14257
  const hasSearchInput = searchInputs.length > 0 || page.forms.some(
14316
- (f) => f.fields.some(
14317
- (el) => el.inputType === "search" || el.name === "q" || el.name === "query"
14318
- )
14258
+ (f) => f.fields.some((el) => el.inputType === "search" || el.name === "q" || el.name === "query")
14319
14259
  );
14320
14260
  const hasVisibleSearchInput = searchInputs.some(
14321
14261
  (el) => el.visible === true && el.inViewport === true && el.obscured !== true && el.blockedByOverlay !== true
@@ -14342,8 +14282,7 @@ function detectPageType(page) {
14342
14282
  if (isSiteListingPage(page.url)) return "PAGINATED_LIST";
14343
14283
  if (hasPagination && listingLike) return "PAGINATED_LIST";
14344
14284
  if (hasSearchInput && !listingLike) return "SEARCH_READY";
14345
- if (page.content.length > 3e3 && page.interactiveElements.length < 10)
14346
- return "ARTICLE";
14285
+ if (page.content.length > 3e3 && page.interactiveElements.length < 10) return "ARTICLE";
14347
14286
  return "GENERAL";
14348
14287
  }
14349
14288
  function isFlightBookingPage(page) {
@@ -14356,18 +14295,13 @@ function isFlightBookingPage(page) {
14356
14295
  if (/google\.com\/travel\/flights|google flights/.test(pageText)) {
14357
14296
  return true;
14358
14297
  }
14359
- const controlsText = [
14360
- ...page.interactiveElements,
14361
- ...page.forms.flatMap((form) => form.fields)
14362
- ].map(
14298
+ const controlsText = [...page.interactiveElements, ...page.forms.flatMap((form) => form.fields)].map(
14363
14299
  (el) => [el.label, el.placeholder, el.name, el.text, el.role, el.inputType].filter(Boolean).join(" ")
14364
14300
  ).join(" ").toLowerCase();
14365
14301
  const hasRouteControls = /\b(?:where from|where to|origin|destination|from|to)\b/.test(
14366
14302
  controlsText
14367
14303
  );
14368
- const hasDateControls = /\b(?:departure|depart|return|date)\b/.test(
14369
- controlsText
14370
- );
14304
+ const hasDateControls = /\b(?:departure|depart|return|date)\b/.test(controlsText);
14371
14305
  const hasFlightLanguage = /\b(?:flight|flights|airfare|airline)\b/.test(
14372
14306
  `${pageText} ${controlsText}`
14373
14307
  );
@@ -14377,70 +14311,77 @@ function getFlightBookingFormHint(page) {
14377
14311
  if (!isFlightBookingPage(page)) return null;
14378
14312
  return "Flight booking form: use the visible route, destination, and date controls with type_text/select_option/click/submit_form before constructing direct Google Flights or travel-search URLs. Direct travel URLs are a fallback only after visible controls fail or the page is unusable.";
14379
14313
  }
14314
+ function buildLoginIntentHints(ctx) {
14315
+ const { page } = ctx;
14316
+ const hints = [
14317
+ "Page type: LOGIN/SIGNUP",
14318
+ "Suggested: vessel_login or vessel_fill_form → auto-fills credentials and submits"
14319
+ ];
14320
+ const userField = page.forms.flatMap((f) => f.fields).find(
14321
+ (el) => el.inputType === "email" || el.name === "email" || el.name === "username" || el.autocomplete === "username"
14322
+ );
14323
+ if (userField) {
14324
+ hints.push(
14325
+ `Username field: #${userField.index} [${userField.label || userField.name || userField.placeholder || "input"}]`
14326
+ );
14327
+ }
14328
+ return hints;
14329
+ }
14330
+ function buildSearchReadyIntentHints(ctx) {
14331
+ const hints = [
14332
+ "Page type: SEARCH READY",
14333
+ "Suggested: vessel_search → auto-finds search box, types query, and submits",
14334
+ "Treat the visible site search box as the primary navigation control before jumping to direct URLs."
14335
+ ];
14336
+ if (ctx.flightBookingFormHint) hints.push(ctx.flightBookingFormHint);
14337
+ return hints;
14338
+ }
14339
+ function buildSearchResultsIntentHints(ctx) {
14340
+ const hints = [
14341
+ "Page type: SEARCH RESULTS",
14342
+ "Suggested: click a result link, or vessel_paginate for more results"
14343
+ ];
14344
+ if (ctx.hasPagination) hints.push("Pagination detected — vessel_paginate available");
14345
+ return hints;
14346
+ }
14347
+ function buildShoppingIntentHints(_ctx) {
14348
+ return ["Page type: SHOPPING/CHECKOUT", "Suggested: vessel_fill_form for payment/address fields"];
14349
+ }
14350
+ function buildFormIntentHints(ctx) {
14351
+ const { page } = ctx;
14352
+ const formCount = page.forms.length;
14353
+ const totalFields = page.forms.reduce((n, f) => n + f.fields.length, 0);
14354
+ const hints = [
14355
+ `Page type: FORM (${formCount} form${formCount > 1 ? "s" : ""}, ${totalFields} fields)`,
14356
+ "Suggested: vessel_fill_form → fill all fields in one call"
14357
+ ];
14358
+ if (ctx.flightBookingFormHint) hints.push(ctx.flightBookingFormHint);
14359
+ return hints;
14360
+ }
14361
+ function buildPaginatedListIntentHints(_ctx) {
14362
+ return ["Page type: PAGINATED LIST", "Suggested: vessel_paginate to navigate between pages"];
14363
+ }
14364
+ function buildArticleIntentHints(_ctx) {
14365
+ return ["Page type: ARTICLE/CONTENT", "Suggested: vessel_extract_content for readable text"];
14366
+ }
14367
+ const PAGE_INTENT_BUILDERS = /* @__PURE__ */ new Map([
14368
+ ["LOGIN", buildLoginIntentHints],
14369
+ ["SEARCH_READY", buildSearchReadyIntentHints],
14370
+ ["SEARCH_RESULTS", buildSearchResultsIntentHints],
14371
+ ["SHOPPING", buildShoppingIntentHints],
14372
+ ["FORM", buildFormIntentHints],
14373
+ ["PAGINATED_LIST", buildPaginatedListIntentHints],
14374
+ ["ARTICLE", buildArticleIntentHints]
14375
+ ]);
14380
14376
  function analyzePageIntent(page) {
14381
- const hints = [];
14382
14377
  const pageType = detectPageType(page);
14383
14378
  const flightBookingFormHint = getFlightBookingFormHint(page);
14384
14379
  const hasPagination = page.interactiveElements.some(
14385
14380
  (el) => (el.text || "").toLowerCase() === "next" || el.text === "›" || el.text === "»" || (el.label || "").toLowerCase().includes("next page")
14386
14381
  );
14387
- switch (pageType) {
14388
- case "LOGIN": {
14389
- hints.push("Page type: LOGIN/SIGNUP");
14390
- hints.push(
14391
- "Suggested: vessel_login or vessel_fill_form → auto-fills credentials and submits"
14392
- );
14393
- const userField = page.forms.flatMap((f) => f.fields).find(
14394
- (el) => el.inputType === "email" || el.name === "email" || el.name === "username" || el.autocomplete === "username"
14395
- );
14396
- if (userField) {
14397
- hints.push(
14398
- `Username field: #${userField.index} [${userField.label || userField.name || userField.placeholder || "input"}]`
14399
- );
14400
- }
14401
- break;
14402
- }
14403
- case "SEARCH_READY":
14404
- hints.push("Page type: SEARCH READY");
14405
- hints.push(
14406
- "Suggested: vessel_search → auto-finds search box, types query, and submits"
14407
- );
14408
- hints.push(
14409
- "Treat the visible site search box as the primary navigation control before jumping to direct URLs."
14410
- );
14411
- if (flightBookingFormHint) hints.push(flightBookingFormHint);
14412
- break;
14413
- case "SEARCH_RESULTS":
14414
- hints.push("Page type: SEARCH RESULTS");
14415
- hints.push(
14416
- "Suggested: click a result link, or vessel_paginate for more results"
14417
- );
14418
- if (hasPagination)
14419
- hints.push("Pagination detected — vessel_paginate available");
14420
- break;
14421
- case "SHOPPING":
14422
- hints.push("Page type: SHOPPING/CHECKOUT");
14423
- hints.push("Suggested: vessel_fill_form for payment/address fields");
14424
- break;
14425
- case "FORM": {
14426
- const formCount = page.forms.length;
14427
- const totalFields = page.forms.reduce((n, f) => n + f.fields.length, 0);
14428
- hints.push(
14429
- `Page type: FORM (${formCount} form${formCount > 1 ? "s" : ""}, ${totalFields} fields)`
14430
- );
14431
- hints.push("Suggested: vessel_fill_form → fill all fields in one call");
14432
- if (flightBookingFormHint) hints.push(flightBookingFormHint);
14433
- break;
14434
- }
14435
- case "PAGINATED_LIST":
14436
- hints.push("Page type: PAGINATED LIST");
14437
- hints.push("Suggested: vessel_paginate to navigate between pages");
14438
- break;
14439
- case "ARTICLE":
14440
- hints.push("Page type: ARTICLE/CONTENT");
14441
- hints.push("Suggested: vessel_extract_content for readable text");
14442
- break;
14443
- }
14382
+ const ctx = { page, flightBookingFormHint, hasPagination };
14383
+ const builder = PAGE_INTENT_BUILDERS.get(pageType);
14384
+ const hints = builder ? builder(ctx) : [];
14444
14385
  if (hints.length === 0 && !flightBookingFormHint) return "";
14445
14386
  if (flightBookingFormHint && pageType !== "SEARCH_READY" && pageType !== "FORM") {
14446
14387
  hints.push(flightBookingFormHint);
@@ -14515,9 +14456,7 @@ function buildStructuredContext(page) {
14515
14456
  }
14516
14457
  if (page.interactiveElements.length > 0) {
14517
14458
  sections.push("### Interactive Elements");
14518
- sections.push(
14519
- `Found ${page.interactiveElements.length} interactive elements:`
14520
- );
14459
+ sections.push(`Found ${page.interactiveElements.length} interactive elements:`);
14521
14460
  sections.push(formatInteractiveElements(page.interactiveElements));
14522
14461
  sections.push("");
14523
14462
  }
@@ -14537,9 +14476,7 @@ function buildStructuredContext(page) {
14537
14476
  sections.push(
14538
14477
  `**Blocking Overlays:** ${page.overlays.filter((overlay) => overlay.blocksInteraction).length}`
14539
14478
  );
14540
- sections.push(
14541
- `**Dormant Consent / Modal UI:** ${page.dormantOverlays.length}`
14542
- );
14479
+ sections.push(`**Dormant Consent / Modal UI:** ${page.dormantOverlays.length}`);
14543
14480
  sections.push(`**Landmarks:** ${page.landmarks.length}`);
14544
14481
  return sections.join("\n");
14545
14482
  }
@@ -23624,6 +23561,12 @@ const GroupIdSchema = zod.z.string().min(1);
23624
23561
  const UrlSchema = zod.z.string().min(1);
23625
23562
  const ColorSchema = zod.z.string().min(1);
23626
23563
  const FindActionSchema = zod.z.enum(["clearSelection", "keepSelection", "activateSelection"]);
23564
+ const FindTextSchema = zod.z.string().min(1).max(1e4);
23565
+ const FindOptionsSchema = zod.z.object({
23566
+ forward: zod.z.boolean().optional(),
23567
+ findNext: zod.z.boolean().optional()
23568
+ }).optional();
23569
+ const FindForwardSchema = zod.z.boolean().optional();
23627
23570
  function registerTabHandlers(windowState, _sendToRendererViews) {
23628
23571
  const { tabManager, mainWindow } = windowState;
23629
23572
  electron.ipcMain.handle(Channels.OPEN_PRIVATE_WINDOW, (event) => {
@@ -23738,16 +23681,13 @@ function registerTabHandlers(windowState, _sendToRendererViews) {
23738
23681
  assertTrustedIpcSender(event);
23739
23682
  return tabManager.toggleGroupCollapsed(parseIpc(GroupIdSchema, groupId, "groupId"));
23740
23683
  });
23741
- electron.ipcMain.handle(
23742
- Channels.TAB_GROUP_SET_COLOR,
23743
- (event, groupId, color) => {
23744
- assertTrustedIpcSender(event);
23745
- tabManager.setGroupColor(
23746
- parseIpc(GroupIdSchema, groupId, "groupId"),
23747
- parseIpc(ColorSchema, color, "color")
23748
- );
23749
- }
23750
- );
23684
+ electron.ipcMain.handle(Channels.TAB_GROUP_SET_COLOR, (event, groupId, color) => {
23685
+ assertTrustedIpcSender(event);
23686
+ tabManager.setGroupColor(
23687
+ parseIpc(GroupIdSchema, groupId, "groupId"),
23688
+ parseIpc(ColorSchema, color, "color")
23689
+ );
23690
+ });
23751
23691
  electron.ipcMain.handle(Channels.TAB_TOGGLE_MUTE, (event, id) => {
23752
23692
  assertTrustedIpcSender(event);
23753
23693
  return tabManager.toggleMuted(parseIpc(TabIdSchema$1, id, "id"));
@@ -23762,7 +23702,12 @@ function registerTabHandlers(windowState, _sendToRendererViews) {
23762
23702
  });
23763
23703
  electron.ipcMain.on(Channels.TAB_CONTEXT_MENU, (event, id) => {
23764
23704
  assertTrustedIpcSender(event);
23765
- showTabContextMenu(tabManager, parseIpc(TabIdSchema$1, id, "id"), mainWindow, () => layoutViews(windowState));
23705
+ showTabContextMenu(
23706
+ tabManager,
23707
+ parseIpc(TabIdSchema$1, id, "id"),
23708
+ mainWindow,
23709
+ () => layoutViews(windowState)
23710
+ );
23766
23711
  });
23767
23712
  electron.ipcMain.on(Channels.TAB_GROUP_CONTEXT_MENU, (event, groupId) => {
23768
23713
  assertTrustedIpcSender(event);
@@ -23778,16 +23723,22 @@ function registerTabHandlers(windowState, _sendToRendererViews) {
23778
23723
  const findBridge = createFindInPageBridge(tabManager, windowState.chromeView);
23779
23724
  electron.ipcMain.handle(Channels.FIND_IN_PAGE_START, (event, text, options) => {
23780
23725
  assertTrustedIpcSender(event);
23781
- return findBridge.start(text, options);
23726
+ return findBridge.start(
23727
+ parseIpc(FindTextSchema, text, "text"),
23728
+ parseIpc(FindOptionsSchema, options, "options")
23729
+ );
23782
23730
  });
23783
23731
  electron.ipcMain.handle(Channels.FIND_IN_PAGE_NEXT, (event, forward) => {
23784
23732
  assertTrustedIpcSender(event);
23785
- return findBridge.next(forward);
23786
- });
23787
- electron.ipcMain.handle(Channels.FIND_IN_PAGE_STOP, (event, action) => {
23788
- assertTrustedIpcSender(event);
23789
- findBridge.stop(action ? parseIpc(FindActionSchema, action, "action") : void 0);
23733
+ return findBridge.next(parseIpc(FindForwardSchema, forward, "forward"));
23790
23734
  });
23735
+ electron.ipcMain.handle(
23736
+ Channels.FIND_IN_PAGE_STOP,
23737
+ (event, action) => {
23738
+ assertTrustedIpcSender(event);
23739
+ findBridge.stop(action ? parseIpc(FindActionSchema, action, "action") : void 0);
23740
+ }
23741
+ );
23791
23742
  }
23792
23743
  const require$1 = node_module.createRequire(require("url").pathToFileURL(__filename).href);
23793
23744
  const logger$l = createLogger("DevTrace");
@@ -24932,13 +24883,14 @@ function setMcpHealth(update) {
24932
24883
  }
24933
24884
  const ApprovalModeSchema = zod.z.enum(["auto", "confirm-dangerous", "manual"]);
24934
24885
  const CheckpointIdSchema = zod.z.string().min(1);
24886
+ const ApprovalIdSchema = zod.z.string().min(1);
24887
+ const OptionalCheckpointNameSchema = zod.z.string().trim().max(200).optional();
24888
+ const OptionalNoteSchema = zod.z.string().trim().max(2e4).optional();
24889
+ const BooleanSchema$2 = zod.z.boolean();
24935
24890
  const TaskTextSchema = zod.z.string().trim().min(1).max(2e4);
24936
24891
  const OptionalTaskTextSchema = zod.z.string().trim().max(2e4).optional();
24937
24892
  const OptionalNullableTaskTextSchema = zod.z.string().trim().max(2e4).nullable().optional();
24938
- const TaskFactsSchema = zod.z.record(
24939
- zod.z.string().trim().min(1).max(200),
24940
- zod.z.string().max(2e4)
24941
- );
24893
+ const TaskFactsSchema = zod.z.record(zod.z.string().trim().min(1).max(200), zod.z.string().max(2e4));
24942
24894
  const TaskMemoryPatchSchema = zod.z.object({
24943
24895
  nextStep: OptionalNullableTaskTextSchema,
24944
24896
  facts: TaskFactsSchema.optional()
@@ -24999,55 +24951,55 @@ function registerAgentRuntimeHandlers(runtime2, chromeView, sidebarView, sendToR
24999
24951
  Channels.AGENT_APPROVAL_RESOLVE,
25000
24952
  (event, approvalId, approved) => {
25001
24953
  assertTrustedIpcSender(event);
25002
- return runtime2.resolveApproval(approvalId, approved);
25003
- }
25004
- );
25005
- electron.ipcMain.handle(
25006
- Channels.AGENT_CHECKPOINT_CREATE,
25007
- (event, name, note) => {
25008
- assertTrustedIpcSender(event);
25009
- return runtime2.createCheckpoint(name, note);
24954
+ return runtime2.resolveApproval(
24955
+ parseIpc(ApprovalIdSchema, approvalId, "approvalId"),
24956
+ parseIpc(BooleanSchema$2, approved, "approved")
24957
+ );
25010
24958
  }
25011
24959
  );
25012
- electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_RESTORE, (event, checkpointId) => {
24960
+ electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_CREATE, (event, name, note) => {
25013
24961
  assertTrustedIpcSender(event);
25014
- return runtime2.restoreCheckpoint(parseIpc(CheckpointIdSchema, checkpointId, "checkpointId"));
24962
+ return runtime2.createCheckpoint(
24963
+ name == null ? void 0 : parseIpc(OptionalCheckpointNameSchema, name, "name"),
24964
+ note == null ? void 0 : parseIpc(OptionalNoteSchema, note, "note")
24965
+ );
25015
24966
  });
25016
- electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_UPDATE_NOTE, (event, checkpointId, note) => {
24967
+ electron.ipcMain.handle(Channels.AGENT_CHECKPOINT_RESTORE, (event, checkpointId) => {
25017
24968
  assertTrustedIpcSender(event);
25018
- return runtime2.updateCheckpointNote(
25019
- parseIpc(CheckpointIdSchema, checkpointId, "checkpointId"),
25020
- note || ""
25021
- );
24969
+ return runtime2.restoreCheckpoint(parseIpc(CheckpointIdSchema, checkpointId, "checkpointId"));
25022
24970
  });
24971
+ electron.ipcMain.handle(
24972
+ Channels.AGENT_CHECKPOINT_UPDATE_NOTE,
24973
+ (event, checkpointId, note) => {
24974
+ assertTrustedIpcSender(event);
24975
+ return runtime2.updateCheckpointNote(
24976
+ parseIpc(CheckpointIdSchema, checkpointId, "checkpointId"),
24977
+ note == null ? "" : parseIpc(OptionalNoteSchema, note, "note")
24978
+ );
24979
+ }
24980
+ );
25023
24981
  electron.ipcMain.handle(Channels.AGENT_UNDO_LAST_ACTION, (event) => {
25024
24982
  assertTrustedIpcSender(event);
25025
24983
  return runtime2.undoLastAction();
25026
24984
  });
25027
24985
  electron.ipcMain.handle(Channels.AGENT_SESSION_CAPTURE, (event, note) => {
25028
24986
  assertTrustedIpcSender(event);
25029
- return runtime2.captureSession(note);
24987
+ return runtime2.captureSession(
24988
+ note == null ? void 0 : parseIpc(OptionalNoteSchema, note, "note")
24989
+ );
24990
+ });
24991
+ electron.ipcMain.handle(Channels.AGENT_SESSION_RESTORE, (event, snapshot2) => {
24992
+ assertTrustedIpcSender(event);
24993
+ return runtime2.restoreSession(snapshot2);
25030
24994
  });
25031
- electron.ipcMain.handle(
25032
- Channels.AGENT_SESSION_RESTORE,
25033
- (event, snapshot2) => {
25034
- assertTrustedIpcSender(event);
25035
- return runtime2.restoreSession(snapshot2);
25036
- }
25037
- );
25038
24995
  electron.ipcMain.handle(Channels.AGENT_TASK_START, (event, goal) => {
25039
24996
  assertTrustedIpcSender(event);
25040
24997
  return runtime2.startTaskMemory(parseIpc(TaskTextSchema, goal, "goal"));
25041
24998
  });
25042
- electron.ipcMain.handle(
25043
- Channels.AGENT_TASK_UPDATE,
25044
- (event, patch) => {
25045
- assertTrustedIpcSender(event);
25046
- return runtime2.updateTaskMemory(
25047
- parseIpc(TaskMemoryPatchSchema, patch ?? {}, "patch")
25048
- );
25049
- }
25050
- );
24999
+ electron.ipcMain.handle(Channels.AGENT_TASK_UPDATE, (event, patch) => {
25000
+ assertTrustedIpcSender(event);
25001
+ return runtime2.updateTaskMemory(parseIpc(TaskMemoryPatchSchema, patch ?? {}, "patch"));
25002
+ });
25051
25003
  electron.ipcMain.handle(Channels.AGENT_TASK_NOTE, (event, text) => {
25052
25004
  assertTrustedIpcSender(event);
25053
25005
  return runtime2.addTaskNote(parseIpc(TaskTextSchema, text, "text"));
@@ -31638,17 +31590,20 @@ function stopScheduler() {
31638
31590
  const KitIdSchema = zod.z.string().min(1);
31639
31591
  const SkillSourceSchema = zod.z.string().min(1).max(1e5);
31640
31592
  const OriginSchema = zod.z.string().min(1);
31593
+ const DownloadIdSchema = zod.z.string().min(1);
31641
31594
  const DevToolsHeightSchema = zod.z.number().finite().min(0).max(2e3);
31595
+ const ClearDataTimeRangeSchema = zod.z.enum(["hour", "day", "week", "month", "all"]);
31596
+ const ClearDataOptionsSchema = zod.z.object({
31597
+ cache: zod.z.boolean(),
31598
+ cookies: zod.z.boolean(),
31599
+ history: zod.z.boolean(),
31600
+ localStorage: zod.z.boolean(),
31601
+ timeRange: ClearDataTimeRangeSchema
31602
+ });
31642
31603
  const DevToolsPageMapRevealSchema = zod.z.object({
31643
31604
  selector: zod.z.string().min(1)
31644
31605
  });
31645
- const DevToolsPanelTabSchema = zod.z.enum([
31646
- "console",
31647
- "network",
31648
- "activity",
31649
- "agentTrace",
31650
- "pageMap"
31651
- ]);
31606
+ const DevToolsPanelTabSchema = zod.z.enum(["console", "network", "activity", "agentTrace", "pageMap"]);
31652
31607
  const RendererViewSchema = zod.z.enum(["chrome", "sidebar", "devtools"]);
31653
31608
  function registerSystemHandlers(windowState, sendToRendererViews) {
31654
31609
  const { tabManager } = windowState;
@@ -31783,18 +31738,11 @@ function registerSystemHandlers(windowState, sendToRendererViews) {
31783
31738
  }
31784
31739
  return await refreshDevToolsPageMap(tabManager);
31785
31740
  });
31786
- electron.ipcMain.handle(
31787
- Channels.DEVTOOLS_PAGE_MAP_REVEAL,
31788
- async (event, payload) => {
31789
- assertTrustedIpcSender(event);
31790
- const { selector } = parseIpc(
31791
- DevToolsPageMapRevealSchema,
31792
- payload,
31793
- "payload"
31794
- );
31795
- return await revealPageMapElement(tabManager, selector);
31796
- }
31797
- );
31741
+ electron.ipcMain.handle(Channels.DEVTOOLS_PAGE_MAP_REVEAL, async (event, payload) => {
31742
+ assertTrustedIpcSender(event);
31743
+ const { selector } = parseIpc(DevToolsPageMapRevealSchema, payload, "payload");
31744
+ return await revealPageMapElement(tabManager, selector);
31745
+ });
31798
31746
  electron.ipcMain.handle(Channels.DEVTOOLS_PANEL_HOST_STATE_GET, (event) => {
31799
31747
  assertTrustedIpcSender(event);
31800
31748
  return getDevToolsPanelHostState(windowState);
@@ -31822,29 +31770,33 @@ function registerSystemHandlers(windowState, sendToRendererViews) {
31822
31770
  electron.ipcMain.handle(Channels.AUTOMATION_CREATE_FROM_TEXT, async (event, source) => {
31823
31771
  assertTrustedIpcSender(event);
31824
31772
  assertFeatureUnlocked("automation_kits", "Skills");
31825
- return await createKitFromText(
31826
- parseIpc(SkillSourceSchema, source, "source")
31827
- );
31828
- });
31829
- electron.ipcMain.handle(Channels.AUTOMATION_UPDATE_FROM_TEXT, async (event, id, source) => {
31830
- assertTrustedIpcSender(event);
31831
- assertFeatureUnlocked("automation_kits", "Skills");
31832
- return await updateKitFromText(
31833
- parseIpc(KitIdSchema, id, "id"),
31834
- parseIpc(SkillSourceSchema, source, "source")
31835
- );
31773
+ return await createKitFromText(parseIpc(SkillSourceSchema, source, "source"));
31836
31774
  });
31775
+ electron.ipcMain.handle(
31776
+ Channels.AUTOMATION_UPDATE_FROM_TEXT,
31777
+ async (event, id, source) => {
31778
+ assertTrustedIpcSender(event);
31779
+ assertFeatureUnlocked("automation_kits", "Skills");
31780
+ return await updateKitFromText(
31781
+ parseIpc(KitIdSchema, id, "id"),
31782
+ parseIpc(SkillSourceSchema, source, "source")
31783
+ );
31784
+ }
31785
+ );
31837
31786
  electron.ipcMain.handle(Channels.AUTOMATION_UNINSTALL, async (event, id) => {
31838
31787
  assertTrustedIpcSender(event);
31839
31788
  assertFeatureUnlocked("automation_kits", "Skills");
31840
- return await uninstallKit(
31841
- parseIpc(KitIdSchema, id, "id"),
31842
- getScheduledKitIds()
31843
- );
31789
+ return await uninstallKit(parseIpc(KitIdSchema, id, "id"), getScheduledKitIds());
31844
31790
  });
31845
31791
  electron.ipcMain.handle(Channels.CLEAR_BROWSING_DATA, async (event, options) => {
31846
31792
  assertTrustedIpcSender(event);
31847
- const { cache, cookies, history, localStorage: clearLs, timeRange } = options;
31793
+ const {
31794
+ cache,
31795
+ cookies,
31796
+ history,
31797
+ localStorage: clearLs,
31798
+ timeRange
31799
+ } = parseIpc(ClearDataOptionsSchema, options, "options");
31848
31800
  if (cache) {
31849
31801
  await electron.session.defaultSession.clearCache();
31850
31802
  }
@@ -31871,11 +31823,11 @@ function registerSystemHandlers(windowState, sendToRendererViews) {
31871
31823
  });
31872
31824
  electron.ipcMain.handle(Channels.DOWNLOADS_OPEN, (event, id) => {
31873
31825
  assertTrustedIpcSender(event);
31874
- return openDownload(id);
31826
+ return openDownload(parseIpc(DownloadIdSchema, id, "id"));
31875
31827
  });
31876
31828
  electron.ipcMain.handle(Channels.DOWNLOADS_SHOW_IN_FOLDER, (event, id) => {
31877
31829
  assertTrustedIpcSender(event);
31878
- return showDownloadInFolder(id);
31830
+ return showDownloadInFolder(parseIpc(DownloadIdSchema, id, "id"));
31879
31831
  });
31880
31832
  electron.ipcMain.handle(Channels.PERMISSIONS_GET, (event) => {
31881
31833
  assertTrustedIpcSender(event);
@@ -35111,16 +35063,15 @@ async function createSplashWindow() {
35111
35063
  backgroundColor: "#1a1a1e",
35112
35064
  webPreferences: {
35113
35065
  nodeIntegration: false,
35114
- contextIsolation: true
35066
+ contextIsolation: true,
35067
+ sandbox: true
35115
35068
  }
35116
35069
  });
35117
35070
  splash.once("ready-to-show", () => splash.show());
35118
35071
  const iconSrc = await findIconBase64();
35119
35072
  const html = buildSplashHTML(iconSrc);
35120
35073
  try {
35121
- const tmpDir = await promises.mkdtemp(
35122
- path.join(os.tmpdir(), "vessel-splash-")
35123
- );
35074
+ const tmpDir = await promises.mkdtemp(path.join(os.tmpdir(), "vessel-splash-"));
35124
35075
  const tmpPath = path.join(tmpDir, "index.html");
35125
35076
  splash.once("closed", () => {
35126
35077
  void rmSafe(tmpDir);