@quanta-intellect/vessel-browser 0.1.17 → 0.1.18

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
@@ -26,7 +26,15 @@ const defaults = {
26
26
  chatProvider: null,
27
27
  maxToolIterations: 200,
28
28
  domainPolicy: { allowedDomains: [], blockedDomains: [] },
29
- downloadPath: ""
29
+ downloadPath: "",
30
+ telemetryEnabled: true,
31
+ premium: {
32
+ status: "free",
33
+ customerId: "",
34
+ email: "",
35
+ validatedAt: "",
36
+ expiresAt: ""
37
+ }
30
38
  };
31
39
  const SETTABLE_KEYS = new Set(Object.keys(defaults));
32
40
  let settings = null;
@@ -2334,6 +2342,13 @@ const Channels = {
2334
2342
  DOWNLOAD_STARTED: "download:started",
2335
2343
  DOWNLOAD_PROGRESS: "download:progress",
2336
2344
  DOWNLOAD_DONE: "download:done",
2345
+ // Premium
2346
+ PREMIUM_GET_STATE: "premium:get-state",
2347
+ PREMIUM_ACTIVATE: "premium:activate",
2348
+ PREMIUM_CHECKOUT: "premium:checkout",
2349
+ PREMIUM_PORTAL: "premium:portal",
2350
+ PREMIUM_RESET: "premium:reset",
2351
+ PREMIUM_UPDATE: "premium:update",
2337
2352
  // Window controls
2338
2353
  WINDOW_MINIMIZE: "window:minimize",
2339
2354
  WINDOW_MAXIMIZE: "window:maximize",
@@ -4396,6 +4411,288 @@ function setMcpHealth(update) {
4396
4411
  }
4397
4412
  }
4398
4413
  }
4414
+ const VERIFICATION_API = process.env.VESSEL_PREMIUM_API || "https://vesselpremium.quantaintellect.com";
4415
+ const FREE_TOOL_ITERATION_LIMIT = 50;
4416
+ const REVALIDATION_INTERVAL_MS = 24 * 60 * 60 * 1e3;
4417
+ const OFFLINE_GRACE_PERIOD_MS = 7 * 24 * 60 * 60 * 1e3;
4418
+ const PREMIUM_TOOLS = /* @__PURE__ */ new Set([
4419
+ "screenshot",
4420
+ "save_session",
4421
+ "load_session",
4422
+ "list_sessions",
4423
+ "delete_session",
4424
+ "flow_start",
4425
+ "flow_advance",
4426
+ "flow_status",
4427
+ "flow_end",
4428
+ "metrics",
4429
+ "extract_table"
4430
+ ]);
4431
+ function isPremium() {
4432
+ const { premium } = loadSettings();
4433
+ if (premium.status === "active" || premium.status === "trialing") {
4434
+ return true;
4435
+ }
4436
+ if (premium.validatedAt && premium.status !== "free") {
4437
+ const lastValidated = new Date(premium.validatedAt).getTime();
4438
+ if (Date.now() - lastValidated < OFFLINE_GRACE_PERIOD_MS) {
4439
+ return true;
4440
+ }
4441
+ }
4442
+ return false;
4443
+ }
4444
+ function getPremiumState() {
4445
+ return { ...loadSettings().premium };
4446
+ }
4447
+ function getEffectiveMaxIterations() {
4448
+ if (isPremium()) {
4449
+ return loadSettings().maxToolIterations || 200;
4450
+ }
4451
+ return FREE_TOOL_ITERATION_LIMIT;
4452
+ }
4453
+ function resetPremium() {
4454
+ const fresh = {
4455
+ status: "free",
4456
+ customerId: "",
4457
+ email: "",
4458
+ validatedAt: "",
4459
+ expiresAt: ""
4460
+ };
4461
+ setSetting("premium", fresh);
4462
+ return fresh;
4463
+ }
4464
+ function isToolGated(toolName) {
4465
+ return PREMIUM_TOOLS.has(toolName) && !isPremium();
4466
+ }
4467
+ async function getCheckoutUrl(email) {
4468
+ try {
4469
+ const params = new URLSearchParams();
4470
+ if (email) params.set("email", email);
4471
+ const res = await fetch(`${VERIFICATION_API}/checkout?${params}`, {
4472
+ method: "POST",
4473
+ headers: { "Content-Type": "application/json" }
4474
+ });
4475
+ if (!res.ok) {
4476
+ const body = await res.text();
4477
+ return { ok: false, error: body || `HTTP ${res.status}` };
4478
+ }
4479
+ const { url } = await res.json();
4480
+ return { ok: true, url };
4481
+ } catch (err) {
4482
+ return {
4483
+ ok: false,
4484
+ error: err instanceof Error ? err.message : "Failed to create checkout"
4485
+ };
4486
+ }
4487
+ }
4488
+ async function getPortalUrl() {
4489
+ const { premium } = loadSettings();
4490
+ if (!premium.customerId) {
4491
+ return { ok: false, error: "No active subscription" };
4492
+ }
4493
+ try {
4494
+ const res = await fetch(`${VERIFICATION_API}/portal`, {
4495
+ method: "POST",
4496
+ headers: { "Content-Type": "application/json" },
4497
+ body: JSON.stringify({ customerId: premium.customerId })
4498
+ });
4499
+ if (!res.ok) {
4500
+ return { ok: false, error: `HTTP ${res.status}` };
4501
+ }
4502
+ const { url } = await res.json();
4503
+ return { ok: true, url };
4504
+ } catch (err) {
4505
+ return {
4506
+ ok: false,
4507
+ error: err instanceof Error ? err.message : "Failed to get portal URL"
4508
+ };
4509
+ }
4510
+ }
4511
+ async function verifySubscription(emailOrCustomerId) {
4512
+ const current = loadSettings().premium;
4513
+ const identifier = emailOrCustomerId || current.customerId || current.email;
4514
+ if (!identifier) {
4515
+ return current;
4516
+ }
4517
+ try {
4518
+ const res = await fetch(`${VERIFICATION_API}/verify`, {
4519
+ method: "POST",
4520
+ headers: { "Content-Type": "application/json" },
4521
+ body: JSON.stringify({ identifier })
4522
+ });
4523
+ if (!res.ok) {
4524
+ console.warn("[Vessel Premium] Verification API returned", res.status);
4525
+ return current;
4526
+ }
4527
+ const data = await res.json();
4528
+ const updated = {
4529
+ status: data.status,
4530
+ customerId: data.customerId,
4531
+ email: data.email,
4532
+ validatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4533
+ expiresAt: data.expiresAt
4534
+ };
4535
+ setSetting("premium", updated);
4536
+ return updated;
4537
+ } catch (err) {
4538
+ console.warn("[Vessel Premium] Verification failed:", err);
4539
+ return current;
4540
+ }
4541
+ }
4542
+ async function activateWithEmail(email) {
4543
+ if (!email.trim()) {
4544
+ return { ok: false, state: getPremiumState(), error: "Email is required" };
4545
+ }
4546
+ const state2 = await verifySubscription(email.trim());
4547
+ if (state2.status === "active" || state2.status === "trialing") {
4548
+ return { ok: true, state: state2 };
4549
+ }
4550
+ return {
4551
+ ok: false,
4552
+ state: state2,
4553
+ error: state2.status === "canceled" ? "Subscription is canceled. Resubscribe to continue." : state2.status === "past_due" ? "Subscription payment is past due. Update your payment method." : "No active subscription found for this email."
4554
+ };
4555
+ }
4556
+ let revalidationTimer = null;
4557
+ function startBackgroundRevalidation() {
4558
+ if (revalidationTimer) return;
4559
+ const { premium } = loadSettings();
4560
+ if (premium.customerId || premium.email) {
4561
+ const lastValidated = premium.validatedAt ? new Date(premium.validatedAt).getTime() : 0;
4562
+ if (Date.now() - lastValidated > REVALIDATION_INTERVAL_MS) {
4563
+ void verifySubscription();
4564
+ }
4565
+ }
4566
+ revalidationTimer = setInterval(() => {
4567
+ const { premium: p } = loadSettings();
4568
+ if (p.customerId || p.email) {
4569
+ void verifySubscription();
4570
+ }
4571
+ }, REVALIDATION_INTERVAL_MS);
4572
+ }
4573
+ function stopBackgroundRevalidation() {
4574
+ if (revalidationTimer) {
4575
+ clearInterval(revalidationTimer);
4576
+ revalidationTimer = null;
4577
+ }
4578
+ }
4579
+ const POSTHOG_API_KEY = process.env.POSTHOG_API_KEY || "phc_OMeM3P5cxJwl14lOKxYad0Yre52xvjNfkLEFnPtXyM";
4580
+ const POSTHOG_HOST = process.env.POSTHOG_HOST || "https://us.i.posthog.com";
4581
+ const BATCH_INTERVAL_MS = 6e4;
4582
+ const MAX_BATCH_SIZE = 50;
4583
+ function getDeviceIdPath() {
4584
+ return path.join(electron.app.getPath("userData"), ".vessel-device-id");
4585
+ }
4586
+ let deviceId = null;
4587
+ function getDeviceId() {
4588
+ if (deviceId) return deviceId;
4589
+ const idPath = getDeviceIdPath();
4590
+ try {
4591
+ deviceId = fs.readFileSync(idPath, "utf-8").trim();
4592
+ if (deviceId) return deviceId;
4593
+ } catch {
4594
+ }
4595
+ deviceId = crypto.randomUUID();
4596
+ try {
4597
+ fs.mkdirSync(path.dirname(idPath), { recursive: true });
4598
+ fs.writeFileSync(idPath, deviceId, "utf-8");
4599
+ } catch {
4600
+ }
4601
+ return deviceId;
4602
+ }
4603
+ let eventQueue = [];
4604
+ let flushTimer = null;
4605
+ let sessionStartedAt = null;
4606
+ function isEnabled() {
4607
+ if (POSTHOG_API_KEY === "YOUR_POSTHOG_KEY_HERE") return false;
4608
+ return loadSettings().telemetryEnabled !== false;
4609
+ }
4610
+ function trackEvent(event, properties = {}) {
4611
+ if (!isEnabled()) return;
4612
+ eventQueue.push({
4613
+ event,
4614
+ properties: {
4615
+ ...properties,
4616
+ premium_status: isPremium() ? "premium" : "free",
4617
+ app_version: electron.app.getVersion(),
4618
+ platform: process.platform,
4619
+ arch: process.arch
4620
+ },
4621
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4622
+ });
4623
+ if (eventQueue.length >= MAX_BATCH_SIZE) {
4624
+ void flush();
4625
+ }
4626
+ }
4627
+ function trackToolCall(toolName, pageType) {
4628
+ trackEvent("tool_called", {
4629
+ tool_name: toolName,
4630
+ page_type: "unknown"
4631
+ });
4632
+ }
4633
+ function trackProviderConfigured(providerId) {
4634
+ trackEvent("provider_configured", {
4635
+ provider_id: providerId
4636
+ });
4637
+ }
4638
+ function startTelemetry() {
4639
+ if (!isEnabled()) return;
4640
+ sessionStartedAt = Date.now();
4641
+ trackEvent("app_launched", {
4642
+ electron_version: process.versions.electron,
4643
+ chrome_version: process.versions.chrome
4644
+ });
4645
+ flushTimer = setInterval(() => {
4646
+ void flush();
4647
+ }, BATCH_INTERVAL_MS);
4648
+ }
4649
+ function stopTelemetry() {
4650
+ if (sessionStartedAt) {
4651
+ const durationMinutes = Math.round(
4652
+ (Date.now() - sessionStartedAt) / 6e4
4653
+ );
4654
+ trackEvent("app_session_ended", {
4655
+ duration_minutes: durationMinutes
4656
+ });
4657
+ sessionStartedAt = null;
4658
+ }
4659
+ if (flushTimer) {
4660
+ clearInterval(flushTimer);
4661
+ flushTimer = null;
4662
+ }
4663
+ void flush();
4664
+ }
4665
+ async function flush() {
4666
+ if (eventQueue.length === 0) return;
4667
+ if (!isEnabled()) {
4668
+ eventQueue = [];
4669
+ return;
4670
+ }
4671
+ const batch = eventQueue.splice(0);
4672
+ const distinctId = getDeviceId();
4673
+ const payload = {
4674
+ api_key: POSTHOG_API_KEY,
4675
+ batch: batch.map((e) => ({
4676
+ event: e.event,
4677
+ properties: {
4678
+ distinct_id: distinctId,
4679
+ ...e.properties
4680
+ },
4681
+ timestamp: e.timestamp
4682
+ }))
4683
+ };
4684
+ try {
4685
+ await fetch(`${POSTHOG_HOST}/batch`, {
4686
+ method: "POST",
4687
+ headers: { "Content-Type": "application/json" },
4688
+ body: JSON.stringify(payload)
4689
+ });
4690
+ } catch {
4691
+ if (eventQueue.length < MAX_BATCH_SIZE * 2) {
4692
+ eventQueue.unshift(...batch);
4693
+ }
4694
+ }
4695
+ }
4399
4696
  function isRichToolResult(value) {
4400
4697
  return typeof value === "object" && value !== null && value.__richResult === true;
4401
4698
  }
@@ -4409,7 +4706,6 @@ function makeImageResult(base64, description, mediaType = "image/png") {
4409
4706
  };
4410
4707
  return JSON.stringify(result);
4411
4708
  }
4412
- const DEFAULT_MAX_ITERATIONS$1 = 200;
4413
4709
  class AnthropicProvider {
4414
4710
  client;
4415
4711
  model;
@@ -4457,7 +4753,7 @@ class AnthropicProvider {
4457
4753
  { role: "user", content: userMessage }
4458
4754
  ];
4459
4755
  try {
4460
- const maxIterations = loadSettings().maxToolIterations || DEFAULT_MAX_ITERATIONS$1;
4756
+ const maxIterations = getEffectiveMaxIterations();
4461
4757
  let iterationsUsed = 0;
4462
4758
  for (let i = 0; i < maxIterations; i++) {
4463
4759
  iterationsUsed = i + 1;
@@ -4698,7 +4994,6 @@ const PROVIDERS = {
4698
4994
  apiKeyHint: "Any OpenAI-compatible API endpoint"
4699
4995
  }
4700
4996
  };
4701
- const DEFAULT_MAX_ITERATIONS = 200;
4702
4997
  function toOpenAITools(tools) {
4703
4998
  return tools.map((t) => ({
4704
4999
  type: "function",
@@ -4764,7 +5059,7 @@ class OpenAICompatProvider {
4764
5059
  { role: "user", content: userMessage }
4765
5060
  ];
4766
5061
  try {
4767
- const maxIterations = loadSettings().maxToolIterations || DEFAULT_MAX_ITERATIONS;
5062
+ const maxIterations = getEffectiveMaxIterations();
4768
5063
  let iterationsUsed = 0;
4769
5064
  for (let i = 0; i < maxIterations; i++) {
4770
5065
  iterationsUsed = i + 1;
@@ -7275,7 +7570,7 @@ function pruneToolsForContext(tools, pageType, query = "") {
7275
7570
  const ctx = pageType ?? "GENERAL";
7276
7571
  const hints = CONTEXT_HINTS[ctx] ?? {};
7277
7572
  const intents = inferIntent(query);
7278
- const scored = tools.filter((tool) => shouldIncludeTool(tool.name, ctx, intents)).map((tool) => ({
7573
+ const scored = tools.filter((tool) => !isToolGated(tool.name)).filter((tool) => shouldIncludeTool(tool.name, ctx, intents)).map((tool) => ({
7279
7574
  tool,
7280
7575
  score: scoreForContext(tool.name, ctx)
7281
7576
  }));
@@ -10773,6 +11068,10 @@ async function executeAction(name, args, ctx) {
10773
11068
  ].includes(name)) {
10774
11069
  return "Error: No active tab";
10775
11070
  }
11071
+ trackToolCall(name);
11072
+ if (isToolGated(name)) {
11073
+ return `This tool (${name}) requires Vessel Premium. Upgrade at Settings > Premium to unlock screenshot, session management, workflow tracking, and more.`;
11074
+ }
10776
11075
  const wc = tab?.view.webContents;
10777
11076
  const result = await ctx.runtime.runControlledAction({
10778
11077
  source: "ai",
@@ -17398,6 +17697,7 @@ function registerIpcHandlers(windowState, runtime2) {
17398
17697
  }
17399
17698
  try {
17400
17699
  activeChatProvider = createProvider(chatConfig);
17700
+ trackProviderConfigured(chatConfig.id);
17401
17701
  const activeTab = tabManager.getActiveTab();
17402
17702
  await handleAIQuery(
17403
17703
  query,
@@ -17698,6 +17998,35 @@ function registerIpcHandlers(windowState, runtime2) {
17698
17998
  layoutViews(windowState);
17699
17999
  return clamped;
17700
18000
  });
18001
+ electron.ipcMain.handle(Channels.PREMIUM_GET_STATE, () => {
18002
+ return getPremiumState();
18003
+ });
18004
+ electron.ipcMain.handle(Channels.PREMIUM_ACTIVATE, async (_, email) => {
18005
+ const result = await activateWithEmail(email);
18006
+ if (result.ok) {
18007
+ sendToRendererViews(Channels.PREMIUM_UPDATE, result.state);
18008
+ }
18009
+ return result;
18010
+ });
18011
+ electron.ipcMain.handle(Channels.PREMIUM_CHECKOUT, async (_, email) => {
18012
+ const result = await getCheckoutUrl(email);
18013
+ if (result.ok && result.url) {
18014
+ tabManager.createTab(result.url);
18015
+ }
18016
+ return result;
18017
+ });
18018
+ electron.ipcMain.handle(Channels.PREMIUM_RESET, () => {
18019
+ const state2 = resetPremium();
18020
+ sendToRendererViews(Channels.PREMIUM_UPDATE, state2);
18021
+ return state2;
18022
+ });
18023
+ electron.ipcMain.handle(Channels.PREMIUM_PORTAL, async () => {
18024
+ const result = await getPortalUrl();
18025
+ if (result.ok && result.url) {
18026
+ tabManager.createTab(result.url);
18027
+ }
18028
+ return result;
18029
+ });
17701
18030
  electron.ipcMain.handle(Channels.WINDOW_MINIMIZE, () => {
17702
18031
  mainWindow.minimize();
17703
18032
  });
@@ -18466,6 +18795,8 @@ async function bootstrap() {
18466
18795
  sidebarView.webContents.send(Channels.HISTORY_UPDATE, state2);
18467
18796
  });
18468
18797
  installDownloadHandler(chromeView);
18798
+ startBackgroundRevalidation();
18799
+ startTelemetry();
18469
18800
  const chromeUrl = rendererUrlFor("chrome");
18470
18801
  const sidebarUrl = rendererUrlFor("sidebar");
18471
18802
  const devtoolsUrl = rendererUrlFor("devtools");
@@ -18505,6 +18836,8 @@ electron.app.whenReady().then(bootstrap).catch((error) => {
18505
18836
  });
18506
18837
  electron.app.on("window-all-closed", () => {
18507
18838
  electron.globalShortcut.unregisterAll();
18839
+ stopTelemetry();
18840
+ stopBackgroundRevalidation();
18508
18841
  runtime?.flushPersist();
18509
18842
  void stopMcpServer().finally(() => {
18510
18843
  electron.app.quit();
@@ -74,6 +74,13 @@ const Channels = {
74
74
  HISTORY_SEARCH: "history:search",
75
75
  HISTORY_CLEAR: "history:clear",
76
76
  HISTORY_UPDATE: "history:update",
77
+ // Premium
78
+ PREMIUM_GET_STATE: "premium:get-state",
79
+ PREMIUM_ACTIVATE: "premium:activate",
80
+ PREMIUM_CHECKOUT: "premium:checkout",
81
+ PREMIUM_PORTAL: "premium:portal",
82
+ PREMIUM_RESET: "premium:reset",
83
+ PREMIUM_UPDATE: "premium:update",
77
84
  // Window controls
78
85
  WINDOW_MINIMIZE: "window:minimize",
79
86
  WINDOW_MAXIMIZE: "window:maximize",
@@ -223,6 +230,18 @@ const api = {
223
230
  return () => electron.ipcRenderer.removeListener(Channels.HISTORY_UPDATE, handler);
224
231
  }
225
232
  },
233
+ premium: {
234
+ getState: () => electron.ipcRenderer.invoke(Channels.PREMIUM_GET_STATE),
235
+ activate: (email) => electron.ipcRenderer.invoke(Channels.PREMIUM_ACTIVATE, email),
236
+ checkout: (email) => electron.ipcRenderer.invoke(Channels.PREMIUM_CHECKOUT, email),
237
+ portal: () => electron.ipcRenderer.invoke(Channels.PREMIUM_PORTAL),
238
+ reset: () => electron.ipcRenderer.invoke(Channels.PREMIUM_RESET),
239
+ onUpdate: (cb) => {
240
+ const handler = (_, state) => cb(state);
241
+ electron.ipcRenderer.on(Channels.PREMIUM_UPDATE, handler);
242
+ return () => electron.ipcRenderer.removeListener(Channels.PREMIUM_UPDATE, handler);
243
+ }
244
+ },
226
245
  window: {
227
246
  minimize: () => electron.ipcRenderer.invoke(Channels.WINDOW_MINIMIZE),
228
247
  maximize: () => electron.ipcRenderer.invoke(Channels.WINDOW_MAXIMIZE),
@@ -3159,7 +3159,7 @@ const DropdownSelect = (props) => {
3159
3159
  };
3160
3160
  delegateEvents(["click"]);
3161
3161
  const vesselLogo = "" + new URL("vessel-logo-transparent-IT25qr-Z.png", import.meta.url).href;
3162
- var _tmpl$$3 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$3 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$4$2 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$5$2 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div><div class=agent-panel-title>Supervisor</div><div class=agent-panel-subtitle></div></div><span class=agent-status-pill></span></div><div class=agent-panel-controls><button class=agent-control-button type=button></button><button class=agent-control-button type=button>Restore session</button></div><div class=agent-muted></div><div class=agent-section-header><div class=agent-section-title>Recent actions`), _tmpl$6$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$7$2 = /* @__PURE__ */ template(`<div class=bookmark-save-card><div class=bookmark-current-title></div><div class=bookmark-current-url></div><div class=bookmark-save-controls><button class=bookmark-primary-button type=button>Save page</button></div><textarea class=bookmark-note-input placeholder="Optional note about why this matters"rows=2>`), _tmpl$8$2 = /* @__PURE__ */ template(`<section class=bookmark-panel><div class=bookmark-panel-header><div><div class=bookmark-panel-title>Bookmarks</div><div class=bookmark-panel-subtitle></div></div></div><input class="bookmark-input bookmark-search-input"placeholder="Search titles, URLs, notes, and folders"><div class=bookmark-save-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Save Current Page</span><span class=bookmark-save-toggle-subtitle>Manual bookmark save options</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><form class=bookmark-folder-create><div class=bookmark-folder-form-fields><input class=bookmark-input placeholder="Create a folder"><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=submit>New folder</button></form><div class=bookmark-folder-list>`), _tmpl$9$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$0$2 = /* @__PURE__ */ template(`<section class="agent-panel checkpoint-panel"><div class=agent-panel-header><div><div class=agent-panel-title>Checkpoints</div><div class=agent-panel-subtitle></div></div></div><div class=agent-panel-body><div class=agent-checkpoint-row><input class=agent-input placeholder="Checkpoint name"><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$1$2 = /* @__PURE__ */ template(`<span>`), _tmpl$10$2 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$11$2 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$12$2 = /* @__PURE__ */ template(`<div class=sidebar-empty><svg class=sidebar-empty-icon width=48 height=48 viewBox="0 0 48 48"aria-hidden=true><line x1=8 y1=8 x2=24 y2=5 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=24 y1=5 x2=40 y2=10 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=8 y1=8 x2=6 y2=24 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=40 y1=10 x2=44 y2=26 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=6 y1=24 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=44 y1=26 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=10 y1=38 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=38 y1=40 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=8 y1=8 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=24 y1=5 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=40 y1=10 x2=32 y2=20 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=20 y1=18 x2=32 y2=20 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.3></line><line x1=6 y1=24 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=20 y1=18 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=32 y1=20 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=44 y1=26 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=18 y1=30 x2=36 y2=30 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.25></line><line x1=18 y1=30 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=36 y1=30 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=18 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><line x1=36 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><circle cx=8 cy=8 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=24 cy=5 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=40 cy=10 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.7></circle><circle cx=6 cy=24 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=44 cy=26 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=10 cy=38 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=38 cy=40 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=24 cy=44 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=20 cy=18 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.85></circle><circle cx=32 cy=20 r=4 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.9></circle><circle cx=18 cy=30 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.75></circle><circle cx=36 cy=30 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.8></circle></svg><p class=sidebar-empty-title>Your move.</p><p class=sidebar-empty-hint>Configure a provider in Settings (Ctrl+,) then ask anything about the current page or beyond.`), _tmpl$13$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Stop generating"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><rect x=2 y=2 width=10 height=10 rx=1.5 fill=currentColor></rect></svg>Stop`), _tmpl$14$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Retry last prompt"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M11.5 7a4.5 4.5 0 1 1-1.3-3.2"stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M10.5 1v3h-3"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Retry`), _tmpl$15 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$16 = /* @__PURE__ */ template(`<div class=highlight-nav><button class=highlight-nav-btn type=button title="Previous highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M8 10L4 6l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=highlight-nav-label type=button title="Go to current highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><circle cx=6 cy=6 r=3 fill="rgba(196, 160, 90, 0.6)"stroke="rgba(196, 160, 90, 0.9)"stroke-width=1></circle></svg></button><button class=highlight-nav-btn type=button title="Next highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M4 2l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$17 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2 placeholder="Ask anything..."></textarea><button class=sidebar-send>Send`), _tmpl$18 = /* @__PURE__ */ template(`<div class=sidebar><div class=sidebar-resize-handle></div><div class=sidebar-header><div class=sidebar-brand><img class=sidebar-logo alt=Vessel><span class=sidebar-brand-text>Vessel Browser</span></div><div class=sidebar-header-actions><button class=sidebar-clear title="Clear chat">Clear</button><button class=sidebar-close title="Close AI chat (Esc)"aria-label="Close AI chat"><svg width=14 height=14 viewBox="0 0 14 14"aria-hidden=true><path d="M3.5 3.5l7 7M10.5 3.5l-7 7"fill=none stroke=currentColor stroke-width=1.4 stroke-linecap=round></path></svg></button></div></div><div class=sidebar-tabs role=tablist><button class=sidebar-tab role=tab>Supervisor</button><button class=sidebar-tab role=tab>Bookmarks</button><button class=sidebar-tab role=tab>Checkpoints</button><button class=sidebar-tab role=tab>Chat</button></div><div class=sidebar-messages><div>`), _tmpl$19 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$20 = /* @__PURE__ */ template(`<div class="agent-card agent-card-approval"><div class=agent-card-approval-stripe aria-hidden=true></div><div class=agent-card-title></div><div class=agent-card-copy></div><div class=agent-card-copy></div><div class=agent-card-actions><button class=agent-primary-button type=button>Approve</button><button class=agent-control-button type=button>Reject`), _tmpl$21 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$22 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$23 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$24 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$25 = /* @__PURE__ */ template(`<div class=agent-card><div class=agent-action-row><span class=agent-card-title></span><span></span></div><div class=agent-card-copy>`), _tmpl$26 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$27 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$28 = /* @__PURE__ */ template(`<div class=bookmark-folder-actions><button class=bookmark-ghost-button type=button>Rename</button><button class="bookmark-ghost-button danger"type=button>Delete`), _tmpl$29 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><div class=bookmark-folder-form-fields><input class=bookmark-input><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=button>Save</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$30 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$31 = /* @__PURE__ */ template(`<div class=bookmark-folder-section><div class="bookmark-folder-header clickable"role=button tabindex=0><div class=bookmark-folder-overview><span class=bookmark-folder-chevron aria-hidden=true>▸</span><div><div class=bookmark-folder-name></div><div class=bookmark-folder-meta> saved`), _tmpl$32 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$33 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$34 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$35 = /* @__PURE__ */ template(`<div class=bookmark-item><button class=bookmark-item-link type=button><span class=bookmark-item-title></span><span class=bookmark-item-url></span></button><div class=bookmark-item-footer><span class=bookmark-item-time></span><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$36 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$37 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$38 = /* @__PURE__ */ template(`<div class=checkpoint-timeline-item><div class=checkpoint-timeline-rail><span class=checkpoint-timeline-dot></span></div><div class=checkpoint-timeline-content><div class=checkpoint-timeline-name></div><div class=checkpoint-timeline-time></div><button class=agent-control-button type=button>Restore`), _tmpl$39 = /* @__PURE__ */ template(`<div>`), _tmpl$40 = /* @__PURE__ */ template(`<div class=thinking-state><div class=thinking-orb aria-hidden=true><span></span><span></span><span></span></div><div class=thinking-copy><div class=thinking-title>Thinking`), _tmpl$41 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$42 = /* @__PURE__ */ template(`<div class=chat-approval><div class=chat-approval-icon aria-hidden=true><svg width=16 height=16 viewBox="0 0 16 16"fill=none><path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM7.25 4.75a.75.75 0 011.5 0v3.5a.75.75 0 01-1.5 0v-3.5zM8 11.5a.75.75 0 110-1.5.75.75 0 010 1.5z"fill=currentColor></path></svg></div><div class=chat-approval-body><div class=chat-approval-title>Approval needed: <strong></strong></div><div class=chat-approval-detail></div><div class=chat-approval-actions><button class="chat-approval-btn chat-approval-approve"type=button>Approve</button><button class="chat-approval-btn chat-approval-reject"type=button>Reject`);
3162
+ var _tmpl$$3 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$3 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$4$2 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$5$2 = /* @__PURE__ */ template(`<section class=agent-panel><div class=agent-panel-header><div><div class=agent-panel-title>Supervisor</div><div class=agent-panel-subtitle></div></div><span class=agent-status-pill></span></div><div class=agent-panel-controls><button class=agent-control-button type=button></button><button class=agent-control-button type=button>Restore session</button></div><div class=agent-muted></div><div class=agent-section-header><div class=agent-section-title>Recent actions`), _tmpl$6$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$7$2 = /* @__PURE__ */ template(`<div class=bookmark-save-card><div class=bookmark-current-title></div><div class=bookmark-current-url></div><div class=bookmark-save-controls><button class=bookmark-primary-button type=button>Save page</button></div><textarea class=bookmark-note-input placeholder="Optional note about why this matters"rows=2>`), _tmpl$8$2 = /* @__PURE__ */ template(`<section class=bookmark-panel><div class=bookmark-panel-header><div><div class=bookmark-panel-title>Bookmarks</div><div class=bookmark-panel-subtitle></div></div></div><input class="bookmark-input bookmark-search-input"placeholder="Search titles, URLs, notes, and folders"><div class=bookmark-save-shell><button class=bookmark-save-toggle type=button><span class=bookmark-save-toggle-copy><span class=bookmark-save-toggle-title>Save Current Page</span><span class=bookmark-save-toggle-subtitle>Manual bookmark save options</span></span><span class=bookmark-save-toggle-caret aria-hidden=true>▾</span></button></div><form class=bookmark-folder-create><div class=bookmark-folder-form-fields><input class=bookmark-input placeholder="Create a folder"><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=submit>New folder</button></form><div class=bookmark-folder-list>`), _tmpl$9$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$0$2 = /* @__PURE__ */ template(`<section class="agent-panel checkpoint-panel"><div class=agent-panel-header><div><div class=agent-panel-title>Checkpoints</div><div class=agent-panel-subtitle></div></div></div><div class=agent-panel-body><div class=agent-checkpoint-row><input class=agent-input placeholder="Checkpoint name"><button class=agent-primary-button type=button>Save checkpoint</button></div><div class=agent-section-title>Recent checkpoints`), _tmpl$1$2 = /* @__PURE__ */ template(`<span>`), _tmpl$10$2 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$11$2 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$12$2 = /* @__PURE__ */ template(`<div class=sidebar-empty><svg class=sidebar-empty-icon width=48 height=48 viewBox="0 0 48 48"aria-hidden=true><line x1=8 y1=8 x2=24 y2=5 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=24 y1=5 x2=40 y2=10 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=8 y1=8 x2=6 y2=24 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=40 y1=10 x2=44 y2=26 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=6 y1=24 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=44 y1=26 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=10 y1=38 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=38 y1=40 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 opacity=0.35></line><line x1=8 y1=8 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=24 y1=5 x2=20 y2=18 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=40 y1=10 x2=32 y2=20 stroke=var(--border-visible) stroke-width=1 opacity=0.5></line><line x1=20 y1=18 x2=32 y2=20 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.3></line><line x1=6 y1=24 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=20 y1=18 x2=18 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=32 y1=20 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=44 y1=26 x2=36 y2=30 stroke=var(--border-visible) stroke-width=1 opacity=0.45></line><line x1=18 y1=30 x2=36 y2=30 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.25></line><line x1=18 y1=30 x2=10 y2=38 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=36 y1=30 x2=38 y2=40 stroke=var(--border-visible) stroke-width=1 opacity=0.4></line><line x1=18 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><line x1=36 y1=30 x2=24 y2=44 stroke=var(--accent-primary) stroke-width=0.75 opacity=0.2></line><circle cx=8 cy=8 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=24 cy=5 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=40 cy=10 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.7></circle><circle cx=6 cy=24 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=44 cy=26 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.55></circle><circle cx=10 cy=38 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=38 cy=40 r=2 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.45></circle><circle cx=24 cy=44 r=2.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.5></circle><circle cx=20 cy=18 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.85></circle><circle cx=32 cy=20 r=4 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.9></circle><circle cx=18 cy=30 r=3 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.75></circle><circle cx=36 cy=30 r=3.5 fill=var(--bg-secondary) stroke=var(--accent-primary) stroke-width=1.5 opacity=0.8></circle></svg><p class=sidebar-empty-title>Your move.</p><p class=sidebar-empty-hint>Configure a provider in Settings (Ctrl+,) then ask anything about the current page or beyond.`), _tmpl$13$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Stop generating"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><rect x=2 y=2 width=10 height=10 rx=1.5 fill=currentColor></rect></svg>Stop`), _tmpl$14$1 = /* @__PURE__ */ template(`<button class=chat-action-btn title="Retry last prompt"><svg width=14 height=14 viewBox="0 0 14 14"fill=none aria-hidden=true><path d="M11.5 7a4.5 4.5 0 1 1-1.3-3.2"stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M10.5 1v3h-3"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg>Retry`), _tmpl$15$1 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$16$1 = /* @__PURE__ */ template(`<div class=highlight-nav><button class=highlight-nav-btn type=button title="Previous highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M8 10L4 6l4-4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=highlight-nav-label type=button title="Go to current highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><circle cx=6 cy=6 r=3 fill="rgba(196, 160, 90, 0.6)"stroke="rgba(196, 160, 90, 0.9)"stroke-width=1></circle></svg></button><button class=highlight-nav-btn type=button title="Next highlight"><svg width=12 height=12 viewBox="0 0 12 12"fill=none aria-hidden=true><path d="M4 2l4 4-4 4"stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round>`), _tmpl$17$1 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2 placeholder="Ask anything..."></textarea><button class=sidebar-send>Send`), _tmpl$18$1 = /* @__PURE__ */ template(`<div class=sidebar><div class=sidebar-resize-handle></div><div class=sidebar-header><div class=sidebar-brand><img class=sidebar-logo alt=Vessel><span class=sidebar-brand-text>Vessel Browser</span></div><div class=sidebar-header-actions><button class=sidebar-clear title="Clear chat">Clear</button><button class=sidebar-close title="Close AI chat (Esc)"aria-label="Close AI chat"><svg width=14 height=14 viewBox="0 0 14 14"aria-hidden=true><path d="M3.5 3.5l7 7M10.5 3.5l-7 7"fill=none stroke=currentColor stroke-width=1.4 stroke-linecap=round></path></svg></button></div></div><div class=sidebar-tabs role=tablist><button class=sidebar-tab role=tab>Supervisor</button><button class=sidebar-tab role=tab>Bookmarks</button><button class=sidebar-tab role=tab>Checkpoints</button><button class=sidebar-tab role=tab>Chat</button></div><div class=sidebar-messages><div>`), _tmpl$19$1 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$20 = /* @__PURE__ */ template(`<div class="agent-card agent-card-approval"><div class=agent-card-approval-stripe aria-hidden=true></div><div class=agent-card-title></div><div class=agent-card-copy></div><div class=agent-card-copy></div><div class=agent-card-actions><button class=agent-primary-button type=button>Approve</button><button class=agent-control-button type=button>Reject`), _tmpl$21 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$22 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$23 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$24 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$25 = /* @__PURE__ */ template(`<div class=agent-card><div class=agent-action-row><span class=agent-card-title></span><span></span></div><div class=agent-card-copy>`), _tmpl$26 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$27 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$28 = /* @__PURE__ */ template(`<div class=bookmark-folder-actions><button class=bookmark-ghost-button type=button>Rename</button><button class="bookmark-ghost-button danger"type=button>Delete`), _tmpl$29 = /* @__PURE__ */ template(`<div class=bookmark-folder-edit><div class=bookmark-folder-form-fields><input class=bookmark-input><input class=bookmark-input placeholder="Optional one-line summary"></div><button class=bookmark-secondary-button type=button>Save</button><button class=bookmark-ghost-button type=button>Cancel`), _tmpl$30 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$31 = /* @__PURE__ */ template(`<div class=bookmark-folder-section><div class="bookmark-folder-header clickable"role=button tabindex=0><div class=bookmark-folder-overview><span class=bookmark-folder-chevron aria-hidden=true>▸</span><div><div class=bookmark-folder-name></div><div class=bookmark-folder-meta> saved`), _tmpl$32 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$33 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$34 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$35 = /* @__PURE__ */ template(`<div class=bookmark-item><button class=bookmark-item-link type=button><span class=bookmark-item-title></span><span class=bookmark-item-url></span></button><div class=bookmark-item-footer><span class=bookmark-item-time></span><button class="bookmark-ghost-button danger"type=button>Remove`), _tmpl$36 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$37 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$38 = /* @__PURE__ */ template(`<div class=checkpoint-timeline-item><div class=checkpoint-timeline-rail><span class=checkpoint-timeline-dot></span></div><div class=checkpoint-timeline-content><div class=checkpoint-timeline-name></div><div class=checkpoint-timeline-time></div><button class=agent-control-button type=button>Restore`), _tmpl$39 = /* @__PURE__ */ template(`<div>`), _tmpl$40 = /* @__PURE__ */ template(`<div class=thinking-state><div class=thinking-orb aria-hidden=true><span></span><span></span><span></span></div><div class=thinking-copy><div class=thinking-title>Thinking`), _tmpl$41 = /* @__PURE__ */ template(`<div class=chat-approval-detail>`), _tmpl$42 = /* @__PURE__ */ template(`<div class=chat-approval><div class=chat-approval-icon aria-hidden=true><svg width=16 height=16 viewBox="0 0 16 16"fill=none><path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM7.25 4.75a.75.75 0 011.5 0v3.5a.75.75 0 01-1.5 0v-3.5zM8 11.5a.75.75 0 110-1.5.75.75 0 010 1.5z"fill=currentColor></path></svg></div><div class=chat-approval-body><div class=chat-approval-title>Approval needed: <strong></strong></div><div class=chat-approval-detail></div><div class=chat-approval-actions><button class="chat-approval-btn chat-approval-approve"type=button>Approve</button><button class="chat-approval-btn chat-approval-reject"type=button>Reject`);
3163
3163
  const UNSORTED_FOLDER = {
3164
3164
  id: "unsorted",
3165
3165
  name: "Unsorted",
@@ -3498,7 +3498,7 @@ ${contextBlock}` : contextBlock);
3498
3498
  return props.forceOpen || sidebarOpen2();
3499
3499
  },
3500
3500
  get children() {
3501
- var _el$2 = _tmpl$18(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$5.nextSibling, _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$0 = _el$4.nextSibling, _el$1 = _el$0.firstChild;
3501
+ var _el$2 = _tmpl$18$1(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$5.nextSibling, _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$0 = _el$4.nextSibling, _el$1 = _el$0.firstChild;
3502
3502
  _el$1.firstChild;
3503
3503
  var _el$12 = _el$1.nextSibling, _el$13 = _el$12.nextSibling, _el$14 = _el$13.nextSibling, _el$15 = _el$0.nextSibling, _el$72 = _el$15.firstChild;
3504
3504
  _el$3.$$pointerdown = startResize;
@@ -3552,7 +3552,7 @@ ${contextBlock}` : contextBlock);
3552
3552
  return runtimeState2().supervisor.pendingApprovals.length > 0;
3553
3553
  },
3554
3554
  get fallback() {
3555
- return _tmpl$19();
3555
+ return _tmpl$19$1();
3556
3556
  },
3557
3557
  get children() {
3558
3558
  return [_tmpl$3$2(), createComponent(For, {
@@ -3998,7 +3998,7 @@ ${contextBlock}` : contextBlock);
3998
3998
  return isStreaming2() || messages2().length > 0;
3999
3999
  },
4000
4000
  get children() {
4001
- var _el$73 = _tmpl$15();
4001
+ var _el$73 = _tmpl$15$1();
4002
4002
  insert(_el$73, createComponent(Show, {
4003
4003
  get when() {
4004
4004
  return isStreaming2();
@@ -4026,7 +4026,7 @@ ${contextBlock}` : contextBlock);
4026
4026
  return highlightCount() > 0;
4027
4027
  },
4028
4028
  get children() {
4029
- var _el$76 = _tmpl$16(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
4029
+ var _el$76 = _tmpl$16$1(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
4030
4030
  _el$78.firstChild;
4031
4031
  var _el$80 = _el$78.nextSibling;
4032
4032
  _el$77.$$click = () => void scrollToHighlight(highlightIndex() - 1);
@@ -4048,7 +4048,7 @@ ${contextBlock}` : contextBlock);
4048
4048
  return _el$76;
4049
4049
  }
4050
4050
  }), (() => {
4051
- var _el$81 = _tmpl$17(), _el$82 = _el$81.firstChild, _el$83 = _el$82.nextSibling;
4051
+ var _el$81 = _tmpl$17$1(), _el$82 = _el$81.firstChild, _el$83 = _el$82.nextSibling;
4052
4052
  _el$82.$$keydown = (e) => {
4053
4053
  if (e.key === "Enter" && !e.shiftKey) {
4054
4054
  e.preventDefault();
@@ -4542,7 +4542,7 @@ const DevToolsPanel = () => {
4542
4542
  })();
4543
4543
  };
4544
4544
  delegateEvents(["click", "input"]);
4545
- var _tmpl$$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-provider>Provider</label><select id=chat-provider class="settings-input settings-select">`), _tmpl$2$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-api-key>API Key</label><input id=chat-api-key class=settings-input type=password>`), _tmpl$3 = /* @__PURE__ */ template(`<select id=chat-model class="settings-input settings-select"style=flex:1>`), _tmpl$4 = /* @__PURE__ */ template(`<p class=settings-hint style=color:var(--error)>Could not fetch models — check your API key and connection.`), _tmpl$5 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-model>Model</label><div style=display:flex;gap:6px;align-items:center><button type=button class=settings-refresh-btn title="Refresh model list">↺`), _tmpl$6 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-base-url>Base URL</label><input id=chat-base-url class=settings-input>`), _tmpl$7 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=settings-panel><h2 class=settings-title>Runtime Settings</h2><div class=settings-callout><div class=settings-callout-title>External Agent Control</div><p class=settings-callout-copy>Vessel is configured to run under an external harness such as Hermes Agent or OpenClaw. Provider and model selection are not configured inside Vessel.</p></div><div class=settings-field><label class=settings-label for=default-homepage>Homepage</label><input id=default-homepage class=settings-input placeholder=https://start.duckduckgo.com><p class=settings-hint>The page that opens when you create a new tab or launch Vessel without restoring a previous session.</p></div><div class=settings-field><label class=settings-label for=mcp-port>MCP Port</label><input id=mcp-port class=settings-input placeholder=3100><p class=settings-hint>External harnesses connect to Vessel at <code>http://127.0.0.1:&lt;port&gt;/mcp</code>. Changing this value restarts the MCP server immediately.</p></div><div class=settings-field><label class=settings-label for=max-tool-iterations>Max Tool Iterations</label><input id=max-tool-iterations class=settings-input type=number min=10 max=1000 placeholder=200><p class=settings-hint>Maximum number of tool calls the AI agent can make per conversation turn before pausing. Higher values let the agent complete longer multi-step workflows without stopping. Range: 10–1000.</p></div><div class=settings-field><label class=settings-label for=obsidian-vault-path>Obsidian Vault Path</label><input id=obsidian-vault-path class=settings-input placeholder=/home/you/Documents/MyVault><p class=settings-hint>Optional. When set, Vessel memory tools can write markdown notes into this vault for research breadcrumbs and summaries.</p></div><div class=settings-field><label class=settings-label for=agent-transcript-mode>Agent Transcript Monitor</label><select id=agent-transcript-mode class="settings-input settings-select"><option value=off>Off</option><option value=summary>Summary HUD</option><option value=full>Full transcript</option></select><p class=settings-hint>Controls the in-browser transcript monitor when an external harness publishes reasoning or status updates into Vessel via the<code>vessel_publish_transcript</code> MCP tool. Summary HUD shows a compact 2-line status surface; Full transcript shows the recent entry list.</p></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Restore last browser session on launch</span></label></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Start bookmarks fresh on launch</span></label><p class=settings-hint>Off by default. When enabled, bookmark folders and saved pages are cleared each time Vessel starts.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Enable Chat Assistant</span></label><p class=settings-hint>Adds a Chat tab to the sidebar for conversing with an AI provider of your choice.</p></div><div class=settings-actions><button class=settings-save>Save</button><button class=settings-close>Close`), _tmpl$8 = /* @__PURE__ */ template(`<style>
4545
+ var _tmpl$$1 = /* @__PURE__ */ template(`<input id=max-tool-iterations class=settings-input type=number min=10 max=1000 placeholder=200>`), _tmpl$2$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-provider>Provider</label><select id=chat-provider class="settings-input settings-select">`), _tmpl$3 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-api-key>API Key</label><input id=chat-api-key class=settings-input type=password>`), _tmpl$4 = /* @__PURE__ */ template(`<select id=chat-model class="settings-input settings-select"style=flex:1>`), _tmpl$5 = /* @__PURE__ */ template(`<p class=settings-hint style=color:var(--error)>Could not fetch models — check your API key and connection.`), _tmpl$6 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-model>Model</label><div style=display:flex;gap:6px;align-items:center><button type=button class=settings-refresh-btn title="Refresh model list">↺`), _tmpl$7 = /* @__PURE__ */ template(`<div class=settings-field><label class=settings-label for=chat-base-url>Base URL</label><input id=chat-base-url class=settings-input>`), _tmpl$8 = /* @__PURE__ */ template(`<div class=premium-section><div class=premium-active-badge>Premium Active</div><p class=premium-detail></p><div class=premium-actions-row><button class="premium-btn premium-btn-manage">Manage Subscription</button><button class="premium-btn premium-btn-reset">Sign Out`), _tmpl$9 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=settings-panel><h2 class=settings-title>Runtime Settings</h2><div class=settings-callout><div class=settings-callout-title>External Agent Control</div><p class=settings-callout-copy>Vessel is configured to run under an external harness such as Hermes Agent or OpenClaw. Provider and model selection are not configured inside Vessel.</p></div><div class=settings-field><label class=settings-label for=default-homepage>Homepage</label><input id=default-homepage class=settings-input placeholder=https://start.duckduckgo.com><p class=settings-hint>The page that opens when you create a new tab or launch Vessel without restoring a previous session.</p></div><div class=settings-field><label class=settings-label for=mcp-port>MCP Port</label><input id=mcp-port class=settings-input placeholder=3100><p class=settings-hint>External harnesses connect to Vessel at <code>http://127.0.0.1:&lt;port&gt;/mcp</code>. Changing this value restarts the MCP server immediately.</p></div><div class=settings-field><label class=settings-label for=max-tool-iterations>Max Tool Iterations</label><p class=settings-hint></p></div><div class=settings-field><label class=settings-label for=obsidian-vault-path>Obsidian Vault Path</label><input id=obsidian-vault-path class=settings-input placeholder=/home/you/Documents/MyVault><p class=settings-hint>Optional. When set, Vessel memory tools can write markdown notes into this vault for research breadcrumbs and summaries.</p></div><div class=settings-field><label class=settings-label for=agent-transcript-mode>Agent Transcript Monitor</label><select id=agent-transcript-mode class="settings-input settings-select"><option value=off>Off</option><option value=summary>Summary HUD</option><option value=full>Full transcript</option></select><p class=settings-hint>Controls the in-browser transcript monitor when an external harness publishes reasoning or status updates into Vessel via the<code>vessel_publish_transcript</code> MCP tool. Summary HUD shows a compact 2-line status surface; Full transcript shows the recent entry list.</p></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Restore last browser session on launch</span></label></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Start bookmarks fresh on launch</span></label><p class=settings-hint>Off by default. When enabled, bookmark folders and saved pages are cleared each time Vessel starts.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Enable Chat Assistant</span></label><p class=settings-hint>Adds a Chat tab to the sidebar for conversing with an AI provider of your choice.</p></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-label>Vessel Premium</label></div><div class=settings-section-divider></div><div class=settings-field><label class=settings-toggle><button type=button class=toggle-switch role=switch><span class=toggle-switch-thumb></span></button><span>Anonymous Usage Analytics</span></label><p class=settings-hint>Help improve Vessel by sending anonymous usage data (tool popularity, session duration, provider type). No URLs, page content, queries, or personal data is ever collected.</p></div><div class=settings-actions><button class=settings-save>Save</button><button class=settings-close>Close`), _tmpl$0 = /* @__PURE__ */ template(`<style>
4546
4546
  .settings-panel {
4547
4547
  width: min(440px, calc(100vw - 32px));
4548
4548
  max-height: calc(100vh - 48px);
@@ -4767,7 +4767,117 @@ var _tmpl$$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=
4767
4767
  opacity: 0.4;
4768
4768
  cursor: default;
4769
4769
  }
4770
- `), _tmpl$9 = /* @__PURE__ */ template(`<div class=settings-health-issues>`), _tmpl$0 = /* @__PURE__ */ template(`<div class=settings-health><div class=settings-callout-title>Runtime Health</div><p class=settings-hint>MCP status: <strong></strong> `), _tmpl$1 = /* @__PURE__ */ template(`<p class=settings-hint>Active endpoint: <code>`), _tmpl$10 = /* @__PURE__ */ template(`<div class=settings-health-issue><strong></strong><div>`), _tmpl$11 = /* @__PURE__ */ template(`<div>`), _tmpl$12 = /* @__PURE__ */ template(`<option>`), _tmpl$13 = /* @__PURE__ */ template(`<input id=chat-model class=settings-input style=flex:1>`), _tmpl$14 = /* @__PURE__ */ template(`<p class=settings-status>`);
4770
+
4771
+ .settings-input-disabled {
4772
+ opacity: 0.5;
4773
+ cursor: not-allowed;
4774
+ user-select: none;
4775
+ display: flex;
4776
+ align-items: center;
4777
+ }
4778
+
4779
+ /* Premium section */
4780
+ .premium-section {
4781
+ display: flex;
4782
+ flex-direction: column;
4783
+ gap: 10px;
4784
+ }
4785
+ .premium-description {
4786
+ color: var(--text-secondary);
4787
+ font-size: 12px;
4788
+ line-height: 1.5;
4789
+ margin: 0;
4790
+ }
4791
+ .premium-activate-row {
4792
+ display: flex;
4793
+ gap: 8px;
4794
+ align-items: center;
4795
+ }
4796
+ .premium-email-input {
4797
+ flex: 1;
4798
+ min-width: 0;
4799
+ }
4800
+ .premium-btn {
4801
+ height: 34px;
4802
+ padding: 0 16px;
4803
+ border-radius: var(--radius-md);
4804
+ font-size: 12px;
4805
+ font-weight: 500;
4806
+ cursor: pointer;
4807
+ border: none;
4808
+ transition:
4809
+ background var(--duration-fast) var(--ease-in-out),
4810
+ transform var(--duration-fast) var(--ease-out-expo);
4811
+ white-space: nowrap;
4812
+ }
4813
+ .premium-btn:active {
4814
+ transform: scale(0.97);
4815
+ }
4816
+ .premium-btn:disabled {
4817
+ opacity: 0.5;
4818
+ cursor: default;
4819
+ }
4820
+ .premium-btn-activate {
4821
+ background: var(--bg-tertiary);
4822
+ color: var(--text-primary);
4823
+ border: 1px solid var(--border-subtle);
4824
+ }
4825
+ .premium-btn-activate:hover:not(:disabled) {
4826
+ background: var(--border-visible);
4827
+ }
4828
+ .premium-btn-upgrade {
4829
+ background: var(--accent-primary);
4830
+ color: white;
4831
+ width: 100%;
4832
+ }
4833
+ .premium-btn-upgrade:hover {
4834
+ background: #d4b06a;
4835
+ }
4836
+ .premium-btn-manage {
4837
+ background: var(--bg-tertiary);
4838
+ color: var(--text-secondary);
4839
+ border: 1px solid var(--border-subtle);
4840
+ align-self: flex-start;
4841
+ }
4842
+ .premium-btn-manage:hover {
4843
+ background: var(--border-visible);
4844
+ color: var(--text-primary);
4845
+ }
4846
+ .premium-active-badge {
4847
+ display: inline-flex;
4848
+ align-items: center;
4849
+ gap: 6px;
4850
+ background: rgba(240, 198, 54, 0.15);
4851
+ color: #f0c636;
4852
+ font-size: 12px;
4853
+ font-weight: 600;
4854
+ padding: 4px 12px;
4855
+ border-radius: var(--radius-md);
4856
+ align-self: flex-start;
4857
+ }
4858
+ .premium-detail {
4859
+ color: var(--text-secondary);
4860
+ font-size: 12px;
4861
+ margin: 0;
4862
+ }
4863
+ .premium-actions-row {
4864
+ display: flex;
4865
+ gap: 8px;
4866
+ align-items: center;
4867
+ }
4868
+ .premium-btn-reset {
4869
+ background: transparent;
4870
+ color: var(--text-tertiary, #71717a);
4871
+ border: 1px solid var(--border-subtle);
4872
+ font-size: 11px;
4873
+ padding: 0 12px;
4874
+ height: 30px;
4875
+ }
4876
+ .premium-btn-reset:hover {
4877
+ color: var(--text-secondary);
4878
+ background: var(--bg-tertiary);
4879
+ }
4880
+ `), _tmpl$1 = /* @__PURE__ */ template(`<div class="settings-input settings-input-disabled"title="Upgrade to Vessel Premium for unlimited tool iterations">50`), _tmpl$10 = /* @__PURE__ */ template(`<div class=settings-health-issues>`), _tmpl$11 = /* @__PURE__ */ template(`<div class=settings-health><div class=settings-callout-title>Runtime Health</div><p class=settings-hint>MCP status: <strong></strong> `), _tmpl$12 = /* @__PURE__ */ template(`<p class=settings-hint>Active endpoint: <code>`), _tmpl$13 = /* @__PURE__ */ template(`<div class=settings-health-issue><strong></strong><div>`), _tmpl$14 = /* @__PURE__ */ template(`<div>`), _tmpl$15 = /* @__PURE__ */ template(`<option>`), _tmpl$16 = /* @__PURE__ */ template(`<input id=chat-model class=settings-input style=flex:1>`), _tmpl$17 = /* @__PURE__ */ template(`<button class="premium-btn premium-btn-reset">Clear Saved Email`), _tmpl$18 = /* @__PURE__ */ template(`<div class=premium-section><p class=premium-description>Unlock screenshot/vision analysis, session management, Obsidian integration, workflow tracking, DevTools tools, table extraction, and unlimited tool iterations.</p><div class=premium-activate-row><input class="settings-input premium-email-input"type=email placeholder="Enter your subscription email"><button class="premium-btn premium-btn-activate"></button></div><button class="premium-btn premium-btn-upgrade">Subscribe to Premium — 5-day free trial`), _tmpl$19 = /* @__PURE__ */ template(`<p class=settings-status>`);
4771
4881
  const CHAT_PROVIDERS = [{
4772
4882
  id: "anthropic",
4773
4883
  name: "Anthropic",
@@ -4848,6 +4958,21 @@ const Settings = () => {
4848
4958
  const [health, setHealth] = createSignal(null);
4849
4959
  const [defaultUrl, setDefaultUrl] = createSignal("https://start.duckduckgo.com");
4850
4960
  const [status, setStatus] = createSignal(null);
4961
+ const [telemetryEnabled, setTelemetryEnabled] = createSignal(true);
4962
+ const [premiumState, setPremiumState] = createSignal({
4963
+ status: "free",
4964
+ customerId: "",
4965
+ email: "",
4966
+ validatedAt: "",
4967
+ expiresAt: ""
4968
+ });
4969
+ const [premiumEmail, setPremiumEmail] = createSignal("");
4970
+ const [premiumLoading, setPremiumLoading] = createSignal(false);
4971
+ const [premiumMessage, setPremiumMessage] = createSignal(null);
4972
+ const premiumActive = () => {
4973
+ const s = premiumState().status;
4974
+ return s === "active" || s === "trialing";
4975
+ };
4851
4976
  const [chatEnabled, setChatEnabled] = createSignal(false);
4852
4977
  const [chatProviderId, setChatProviderId] = createSignal("anthropic");
4853
4978
  const [chatApiKey, setChatApiKey] = createSignal("");
@@ -4920,6 +5045,13 @@ const Settings = () => {
4920
5045
  setChatModel(cp.model);
4921
5046
  setChatBaseUrl(cp.baseUrl ?? "");
4922
5047
  }
5048
+ setTelemetryEnabled(settings.telemetryEnabled !== false);
5049
+ try {
5050
+ const ps = await window.vessel.premium.getState();
5051
+ setPremiumState(ps);
5052
+ if (ps.email) setPremiumEmail(ps.email);
5053
+ } catch {
5054
+ }
4923
5055
  };
4924
5056
  onMount(() => {
4925
5057
  void loadState();
@@ -4947,6 +5079,7 @@ const Settings = () => {
4947
5079
  const parsedIterations = Number(maxToolIterations().trim()) || 200;
4948
5080
  await window.vessel.settings.set("maxToolIterations", Math.max(10, Math.min(1e3, parsedIterations)));
4949
5081
  await window.vessel.settings.set("agentTranscriptMode", agentTranscriptMode());
5082
+ await window.vessel.settings.set("telemetryEnabled", telemetryEnabled());
4950
5083
  const chatConfig = chatEnabled() ? {
4951
5084
  id: chatProviderId(),
4952
5085
  apiKey: chatApiKey().trim(),
@@ -4975,7 +5108,9 @@ const Settings = () => {
4975
5108
  },
4976
5109
  get children() {
4977
5110
  return [(() => {
4978
- var _el$ = _tmpl$7(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$5.nextSibling, _el$9 = _el$8.firstChild, _el$0 = _el$9.nextSibling, _el$1 = _el$8.nextSibling, _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$1.nextSibling, _el$13 = _el$12.firstChild, _el$14 = _el$13.nextSibling, _el$15 = _el$12.nextSibling, _el$16 = _el$15.firstChild, _el$17 = _el$16.nextSibling, _el$18 = _el$15.nextSibling, _el$19 = _el$18.firstChild, _el$20 = _el$19.firstChild, _el$21 = _el$18.nextSibling, _el$22 = _el$21.firstChild, _el$23 = _el$22.firstChild, _el$24 = _el$21.nextSibling, _el$25 = _el$24.nextSibling, _el$26 = _el$25.firstChild, _el$27 = _el$26.firstChild, _el$43 = _el$25.nextSibling, _el$44 = _el$43.firstChild, _el$45 = _el$44.nextSibling;
5111
+ var _el$ = _tmpl$9(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$5.nextSibling, _el$9 = _el$8.firstChild, _el$0 = _el$9.nextSibling, _el$1 = _el$8.nextSibling, _el$10 = _el$1.firstChild, _el$12 = _el$10.nextSibling, _el$13 = _el$1.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.nextSibling, _el$16 = _el$13.nextSibling, _el$17 = _el$16.firstChild, _el$18 = _el$17.nextSibling, _el$19 = _el$16.nextSibling, _el$20 = _el$19.firstChild, _el$21 = _el$20.firstChild, _el$22 = _el$19.nextSibling, _el$23 = _el$22.firstChild, _el$24 = _el$23.firstChild, _el$25 = _el$22.nextSibling, _el$26 = _el$25.nextSibling, _el$27 = _el$26.firstChild, _el$28 = _el$27.firstChild, _el$44 = _el$26.nextSibling, _el$45 = _el$44.nextSibling;
5112
+ _el$45.firstChild;
5113
+ var _el$54 = _el$45.nextSibling, _el$55 = _el$54.nextSibling, _el$56 = _el$55.firstChild, _el$57 = _el$56.firstChild, _el$58 = _el$55.nextSibling, _el$59 = _el$58.firstChild, _el$60 = _el$59.nextSibling;
4979
5114
  addEventListener(_el$, "click", closeSettings);
4980
5115
  _el$2.$$keydown = handleKeyDown;
4981
5116
  _el$2.$$click = (e) => e.stopPropagation();
@@ -4983,77 +5118,97 @@ const Settings = () => {
4983
5118
  setAttribute(_el$7, "spellcheck", false);
4984
5119
  _el$0.$$input = (e) => setMcpPort(e.currentTarget.value);
4985
5120
  setAttribute(_el$0, "spellcheck", false);
4986
- _el$11.$$input = (e) => setMaxToolIterations(e.currentTarget.value);
5121
+ insert(_el$1, createComponent(Show, {
5122
+ get when() {
5123
+ return premiumActive();
5124
+ },
5125
+ get fallback() {
5126
+ return _tmpl$1();
5127
+ },
5128
+ get children() {
5129
+ var _el$11 = _tmpl$$1();
5130
+ _el$11.$$input = (e) => setMaxToolIterations(e.currentTarget.value);
5131
+ createRenderEffect(() => _el$11.value = maxToolIterations());
5132
+ return _el$11;
5133
+ }
5134
+ }), _el$12);
5135
+ insert(_el$12, createComponent(Show, {
5136
+ get when() {
5137
+ return premiumActive();
5138
+ },
5139
+ fallback: "Free tier: 50 tool calls per conversation turn. Upgrade to Vessel Premium to customize this limit (up to 1,000).",
5140
+ children: "Maximum number of tool calls the AI agent can make per conversation turn before pausing. Higher values let the agent complete longer multi-step workflows without stopping. Range: 10–1000."
5141
+ }));
4987
5142
  insert(_el$2, createComponent(Show, {
4988
5143
  get when() {
4989
5144
  return health();
4990
5145
  },
4991
5146
  children: (currentHealth) => (() => {
4992
- var _el$47 = _tmpl$0(), _el$48 = _el$47.firstChild, _el$49 = _el$48.nextSibling, _el$50 = _el$49.firstChild, _el$52 = _el$50.nextSibling;
4993
- _el$52.nextSibling;
4994
- insert(_el$52, () => currentHealth().mcp.status);
4995
- insert(_el$49, () => currentHealth().mcp.message, null);
4996
- insert(_el$47, createComponent(Show, {
5147
+ var _el$63 = _tmpl$11(), _el$64 = _el$63.firstChild, _el$65 = _el$64.nextSibling, _el$66 = _el$65.firstChild, _el$68 = _el$66.nextSibling;
5148
+ _el$68.nextSibling;
5149
+ insert(_el$68, () => currentHealth().mcp.status);
5150
+ insert(_el$65, () => currentHealth().mcp.message, null);
5151
+ insert(_el$63, createComponent(Show, {
4997
5152
  get when() {
4998
5153
  return currentHealth().mcp.endpoint;
4999
5154
  },
5000
5155
  children: (endpoint) => (() => {
5001
- var _el$55 = _tmpl$1(), _el$56 = _el$55.firstChild, _el$57 = _el$56.nextSibling;
5002
- insert(_el$57, endpoint);
5003
- return _el$55;
5156
+ var _el$71 = _tmpl$12(), _el$72 = _el$71.firstChild, _el$73 = _el$72.nextSibling;
5157
+ insert(_el$73, endpoint);
5158
+ return _el$71;
5004
5159
  })()
5005
5160
  }), null);
5006
- insert(_el$47, createComponent(Show, {
5161
+ insert(_el$63, createComponent(Show, {
5007
5162
  get when() {
5008
5163
  return currentHealth().startupIssues.length > 0;
5009
5164
  },
5010
5165
  get children() {
5011
- var _el$54 = _tmpl$9();
5012
- insert(_el$54, () => currentHealth().startupIssues.map((issue) => (() => {
5013
- var _el$58 = _tmpl$10(), _el$59 = _el$58.firstChild, _el$60 = _el$59.nextSibling;
5014
- insert(_el$59, () => issue.title);
5015
- insert(_el$60, () => issue.detail);
5016
- insert(_el$58, createComponent(Show, {
5166
+ var _el$70 = _tmpl$10();
5167
+ insert(_el$70, () => currentHealth().startupIssues.map((issue) => (() => {
5168
+ var _el$74 = _tmpl$13(), _el$75 = _el$74.firstChild, _el$76 = _el$75.nextSibling;
5169
+ insert(_el$75, () => issue.title);
5170
+ insert(_el$76, () => issue.detail);
5171
+ insert(_el$74, createComponent(Show, {
5017
5172
  get when() {
5018
5173
  return issue.action;
5019
5174
  },
5020
5175
  children: (action) => (() => {
5021
- var _el$61 = _tmpl$11();
5022
- insert(_el$61, action);
5023
- return _el$61;
5176
+ var _el$77 = _tmpl$14();
5177
+ insert(_el$77, action);
5178
+ return _el$77;
5024
5179
  })()
5025
5180
  }), null);
5026
5181
  createRenderEffect((_p$) => {
5027
- var _v$7 = !!(issue.severity === "warning"), _v$8 = !!(issue.severity === "error");
5028
- _v$7 !== _p$.e && _el$58.classList.toggle("warning", _p$.e = _v$7);
5029
- _v$8 !== _p$.t && _el$58.classList.toggle("error", _p$.t = _v$8);
5182
+ var _v$9 = !!(issue.severity === "warning"), _v$0 = !!(issue.severity === "error");
5183
+ _v$9 !== _p$.e && _el$74.classList.toggle("warning", _p$.e = _v$9);
5184
+ _v$0 !== _p$.t && _el$74.classList.toggle("error", _p$.t = _v$0);
5030
5185
  return _p$;
5031
5186
  }, {
5032
5187
  e: void 0,
5033
5188
  t: void 0
5034
5189
  });
5035
- return _el$58;
5190
+ return _el$74;
5036
5191
  })()));
5037
- return _el$54;
5192
+ return _el$70;
5038
5193
  }
5039
5194
  }), null);
5040
- return _el$47;
5195
+ return _el$63;
5041
5196
  })()
5042
- }), _el$12);
5043
- _el$14.$$input = (e) => setObsidianVaultPath(e.currentTarget.value);
5044
- setAttribute(_el$14, "spellcheck", false);
5045
- _el$17.addEventListener("change", (e) => setAgentTranscriptMode(e.currentTarget.value));
5046
- _el$20.$$click = () => setAutoRestoreSession(!autoRestoreSession());
5047
- _el$23.$$click = () => setClearBookmarksOnLaunch(!clearBookmarksOnLaunch());
5048
- _el$27.$$click = () => setChatEnabled(!chatEnabled());
5197
+ }), _el$13);
5198
+ _el$15.$$input = (e) => setObsidianVaultPath(e.currentTarget.value);
5199
+ setAttribute(_el$15, "spellcheck", false);
5200
+ _el$18.addEventListener("change", (e) => setAgentTranscriptMode(e.currentTarget.value));
5201
+ _el$21.$$click = () => setAutoRestoreSession(!autoRestoreSession());
5202
+ _el$24.$$click = () => setClearBookmarksOnLaunch(!clearBookmarksOnLaunch());
5203
+ _el$28.$$click = () => setChatEnabled(!chatEnabled());
5049
5204
  insert(_el$2, createComponent(Show, {
5050
5205
  get when() {
5051
5206
  return chatEnabled();
5052
5207
  },
5053
5208
  get children() {
5054
5209
  return [(() => {
5055
- var _el$28 = _tmpl$$1(), _el$29 = _el$28.firstChild, _el$30 = _el$29.nextSibling;
5056
- _el$30.addEventListener("change", (e) => {
5210
+ var _el$29 = _tmpl$2$1(), _el$30 = _el$29.firstChild, _el$31 = _el$30.nextSibling;
5211
+ _el$31.addEventListener("change", (e) => {
5057
5212
  const id = e.currentTarget.value;
5058
5213
  setChatProviderId(id);
5059
5214
  setChatModel("");
@@ -5062,118 +5217,232 @@ const Settings = () => {
5062
5217
  setProviderModels([]);
5063
5218
  setModelFetchState("idle");
5064
5219
  });
5065
- insert(_el$30, createComponent(For, {
5220
+ insert(_el$31, createComponent(For, {
5066
5221
  each: CHAT_PROVIDERS,
5067
5222
  children: (p) => (() => {
5068
- var _el$62 = _tmpl$12();
5069
- insert(_el$62, () => p.name);
5070
- createRenderEffect(() => _el$62.value = p.id);
5071
- return _el$62;
5223
+ var _el$78 = _tmpl$15();
5224
+ insert(_el$78, () => p.name);
5225
+ createRenderEffect(() => _el$78.value = p.id);
5226
+ return _el$78;
5072
5227
  })()
5073
5228
  }));
5074
- createRenderEffect(() => _el$30.value = chatProviderId());
5075
- return _el$28;
5229
+ createRenderEffect(() => _el$31.value = chatProviderId());
5230
+ return _el$29;
5076
5231
  })(), createComponent(Show, {
5077
5232
  get when() {
5078
5233
  return chatProviderMeta().requiresKey;
5079
5234
  },
5080
5235
  get children() {
5081
- var _el$31 = _tmpl$2$1(), _el$32 = _el$31.firstChild, _el$33 = _el$32.nextSibling;
5082
- _el$33.$$input = (e) => setChatApiKey(e.currentTarget.value);
5083
- setAttribute(_el$33, "spellcheck", false);
5084
- createRenderEffect(() => setAttribute(_el$33, "placeholder", chatProviderMeta().keyPlaceholder));
5085
- createRenderEffect(() => _el$33.value = chatApiKey());
5086
- return _el$31;
5236
+ var _el$32 = _tmpl$3(), _el$33 = _el$32.firstChild, _el$34 = _el$33.nextSibling;
5237
+ _el$34.$$input = (e) => setChatApiKey(e.currentTarget.value);
5238
+ setAttribute(_el$34, "spellcheck", false);
5239
+ createRenderEffect(() => setAttribute(_el$34, "placeholder", chatProviderMeta().keyPlaceholder));
5240
+ createRenderEffect(() => _el$34.value = chatApiKey());
5241
+ return _el$32;
5087
5242
  }
5088
5243
  }), (() => {
5089
- var _el$34 = _tmpl$5(), _el$35 = _el$34.firstChild, _el$36 = _el$35.nextSibling, _el$38 = _el$36.firstChild;
5090
- insert(_el$36, createComponent(Show, {
5244
+ var _el$35 = _tmpl$6(), _el$36 = _el$35.firstChild, _el$37 = _el$36.nextSibling, _el$39 = _el$37.firstChild;
5245
+ insert(_el$37, createComponent(Show, {
5091
5246
  get when() {
5092
5247
  return providerModels().length > 0;
5093
5248
  },
5094
5249
  get fallback() {
5095
5250
  return (() => {
5096
- var _el$63 = _tmpl$13();
5097
- _el$63.$$input = (e) => setChatModel(e.currentTarget.value);
5098
- setAttribute(_el$63, "spellcheck", false);
5099
- createRenderEffect(() => setAttribute(_el$63, "placeholder", modelFetchState() === "loading" ? "Fetching models…" : chatProviderMeta().requiresKey && !chatApiKey().trim() ? "Enter API key to load models" : chatProviderMeta().defaultModel || "model name"));
5100
- createRenderEffect(() => _el$63.value = chatModel());
5101
- return _el$63;
5251
+ var _el$79 = _tmpl$16();
5252
+ _el$79.$$input = (e) => setChatModel(e.currentTarget.value);
5253
+ setAttribute(_el$79, "spellcheck", false);
5254
+ createRenderEffect(() => setAttribute(_el$79, "placeholder", modelFetchState() === "loading" ? "Fetching models…" : chatProviderMeta().requiresKey && !chatApiKey().trim() ? "Enter API key to load models" : chatProviderMeta().defaultModel || "model name"));
5255
+ createRenderEffect(() => _el$79.value = chatModel());
5256
+ return _el$79;
5102
5257
  })();
5103
5258
  },
5104
5259
  get children() {
5105
- var _el$37 = _tmpl$3();
5106
- _el$37.addEventListener("change", (e) => setChatModel(e.currentTarget.value));
5107
- insert(_el$37, createComponent(For, {
5260
+ var _el$38 = _tmpl$4();
5261
+ _el$38.addEventListener("change", (e) => setChatModel(e.currentTarget.value));
5262
+ insert(_el$38, createComponent(For, {
5108
5263
  get each() {
5109
5264
  return providerModels();
5110
5265
  },
5111
5266
  children: (m) => (() => {
5112
- var _el$64 = _tmpl$12();
5113
- _el$64.value = m;
5114
- insert(_el$64, m);
5115
- return _el$64;
5267
+ var _el$80 = _tmpl$15();
5268
+ _el$80.value = m;
5269
+ insert(_el$80, m);
5270
+ return _el$80;
5116
5271
  })()
5117
5272
  }));
5118
- createRenderEffect(() => _el$37.value = chatModel());
5119
- return _el$37;
5273
+ createRenderEffect(() => _el$38.value = chatModel());
5274
+ return _el$38;
5120
5275
  }
5121
- }), _el$38);
5122
- _el$38.$$click = doFetchModels;
5123
- insert(_el$34, createComponent(Show, {
5276
+ }), _el$39);
5277
+ _el$39.$$click = doFetchModels;
5278
+ insert(_el$35, createComponent(Show, {
5124
5279
  get when() {
5125
5280
  return modelFetchState() === "error";
5126
5281
  },
5127
5282
  get children() {
5128
- return _tmpl$4();
5283
+ return _tmpl$5();
5129
5284
  }
5130
5285
  }), null);
5131
- createRenderEffect(() => _el$38.disabled = modelFetchState() === "loading");
5132
- return _el$34;
5286
+ createRenderEffect(() => _el$39.disabled = modelFetchState() === "loading");
5287
+ return _el$35;
5133
5288
  })(), createComponent(Show, {
5134
5289
  get when() {
5135
5290
  return chatProviderMeta().needsBaseUrl || chatProviderId() === "custom";
5136
5291
  },
5137
5292
  get children() {
5138
- var _el$40 = _tmpl$6(), _el$41 = _el$40.firstChild, _el$42 = _el$41.nextSibling;
5139
- _el$42.$$input = (e) => setChatBaseUrl(e.currentTarget.value);
5140
- setAttribute(_el$42, "spellcheck", false);
5141
- createRenderEffect(() => setAttribute(_el$42, "placeholder", chatProviderMeta().defaultBaseUrl ?? "https://..."));
5142
- createRenderEffect(() => _el$42.value = chatBaseUrl());
5143
- return _el$40;
5293
+ var _el$41 = _tmpl$7(), _el$42 = _el$41.firstChild, _el$43 = _el$42.nextSibling;
5294
+ _el$43.$$input = (e) => setChatBaseUrl(e.currentTarget.value);
5295
+ setAttribute(_el$43, "spellcheck", false);
5296
+ createRenderEffect(() => setAttribute(_el$43, "placeholder", chatProviderMeta().defaultBaseUrl ?? "https://..."));
5297
+ createRenderEffect(() => _el$43.value = chatBaseUrl());
5298
+ return _el$41;
5144
5299
  }
5145
5300
  })];
5146
5301
  }
5147
- }), _el$43);
5148
- _el$44.$$click = handleSave;
5149
- addEventListener(_el$45, "click", closeSettings);
5302
+ }), _el$44);
5303
+ insert(_el$45, createComponent(Show, {
5304
+ get when() {
5305
+ return premiumActive();
5306
+ },
5307
+ get fallback() {
5308
+ return (() => {
5309
+ var _el$81 = _tmpl$18(), _el$82 = _el$81.firstChild, _el$83 = _el$82.nextSibling, _el$84 = _el$83.firstChild, _el$85 = _el$84.nextSibling, _el$86 = _el$83.nextSibling;
5310
+ _el$84.$$input = (e) => setPremiumEmail(e.currentTarget.value);
5311
+ setAttribute(_el$84, "spellcheck", false);
5312
+ _el$85.$$click = async () => {
5313
+ setPremiumLoading(true);
5314
+ setPremiumMessage(null);
5315
+ try {
5316
+ const result = await window.vessel.premium.activate(premiumEmail().trim());
5317
+ setPremiumState(result.state);
5318
+ if (result.ok) {
5319
+ setPremiumMessage({
5320
+ kind: "success",
5321
+ text: "Premium activated!"
5322
+ });
5323
+ } else {
5324
+ setPremiumMessage({
5325
+ kind: "error",
5326
+ text: result.error || "Activation failed"
5327
+ });
5328
+ }
5329
+ } catch (err) {
5330
+ setPremiumMessage({
5331
+ kind: "error",
5332
+ text: err instanceof Error ? err.message : "Activation failed"
5333
+ });
5334
+ } finally {
5335
+ setPremiumLoading(false);
5336
+ }
5337
+ };
5338
+ insert(_el$85, () => premiumLoading() ? "Checking..." : "Activate");
5339
+ _el$86.$$click = () => {
5340
+ void window.vessel.premium.checkout(premiumEmail().trim() || void 0);
5341
+ };
5342
+ insert(_el$81, createComponent(Show, {
5343
+ get when() {
5344
+ return premiumMessage();
5345
+ },
5346
+ children: (msg) => (() => {
5347
+ var _el$88 = _tmpl$19();
5348
+ insert(_el$88, () => msg().text);
5349
+ createRenderEffect((_p$) => {
5350
+ var _v$1 = !!(msg().kind === "success"), _v$10 = !!(msg().kind === "error");
5351
+ _v$1 !== _p$.e && _el$88.classList.toggle("success", _p$.e = _v$1);
5352
+ _v$10 !== _p$.t && _el$88.classList.toggle("error", _p$.t = _v$10);
5353
+ return _p$;
5354
+ }, {
5355
+ e: void 0,
5356
+ t: void 0
5357
+ });
5358
+ return _el$88;
5359
+ })()
5360
+ }), null);
5361
+ insert(_el$81, createComponent(Show, {
5362
+ get when() {
5363
+ return premiumState().email || premiumEmail();
5364
+ },
5365
+ get children() {
5366
+ var _el$87 = _tmpl$17();
5367
+ _el$87.$$click = async () => {
5368
+ const state = await window.vessel.premium.reset();
5369
+ setPremiumState(state);
5370
+ setPremiumEmail("");
5371
+ setPremiumMessage(null);
5372
+ };
5373
+ return _el$87;
5374
+ }
5375
+ }), null);
5376
+ createRenderEffect(() => _el$85.disabled = premiumLoading() || !premiumEmail().trim());
5377
+ createRenderEffect(() => _el$84.value = premiumEmail());
5378
+ return _el$81;
5379
+ })();
5380
+ },
5381
+ get children() {
5382
+ var _el$47 = _tmpl$8(), _el$48 = _el$47.firstChild;
5383
+ _el$48.firstChild;
5384
+ var _el$50 = _el$48.nextSibling, _el$51 = _el$50.nextSibling, _el$52 = _el$51.firstChild, _el$53 = _el$52.nextSibling;
5385
+ insert(_el$48, createComponent(Show, {
5386
+ get when() {
5387
+ return premiumState().status === "trialing";
5388
+ },
5389
+ get children() {
5390
+ return [" ", "(Trial)"];
5391
+ }
5392
+ }), null);
5393
+ insert(_el$50, () => premiumState().email, null);
5394
+ insert(_el$50, createComponent(Show, {
5395
+ get when() {
5396
+ return premiumState().expiresAt;
5397
+ },
5398
+ get children() {
5399
+ return [" ", "· Renews", " ", memo(() => new Date(premiumState().expiresAt).toLocaleDateString())];
5400
+ }
5401
+ }), null);
5402
+ _el$52.$$click = () => {
5403
+ void window.vessel.premium.portal();
5404
+ };
5405
+ _el$53.$$click = async () => {
5406
+ const state = await window.vessel.premium.reset();
5407
+ setPremiumState(state);
5408
+ setPremiumEmail("");
5409
+ setPremiumMessage(null);
5410
+ };
5411
+ return _el$47;
5412
+ }
5413
+ }), null);
5414
+ _el$57.$$click = () => setTelemetryEnabled(!telemetryEnabled());
5415
+ _el$59.$$click = handleSave;
5416
+ addEventListener(_el$60, "click", closeSettings);
5150
5417
  insert(_el$2, createComponent(Show, {
5151
5418
  get when() {
5152
5419
  return status();
5153
5420
  },
5154
5421
  children: (currentStatus) => (() => {
5155
- var _el$65 = _tmpl$14();
5156
- insert(_el$65, () => currentStatus().text);
5422
+ var _el$89 = _tmpl$19();
5423
+ insert(_el$89, () => currentStatus().text);
5157
5424
  createRenderEffect((_p$) => {
5158
- var _v$9 = !!(currentStatus().kind === "success"), _v$0 = !!(currentStatus().kind === "error");
5159
- _v$9 !== _p$.e && _el$65.classList.toggle("success", _p$.e = _v$9);
5160
- _v$0 !== _p$.t && _el$65.classList.toggle("error", _p$.t = _v$0);
5425
+ var _v$11 = !!(currentStatus().kind === "success"), _v$12 = !!(currentStatus().kind === "error");
5426
+ _v$11 !== _p$.e && _el$89.classList.toggle("success", _p$.e = _v$11);
5427
+ _v$12 !== _p$.t && _el$89.classList.toggle("error", _p$.t = _v$12);
5161
5428
  return _p$;
5162
5429
  }, {
5163
5430
  e: void 0,
5164
5431
  t: void 0
5165
5432
  });
5166
- return _el$65;
5433
+ return _el$89;
5167
5434
  })()
5168
5435
  }), null);
5169
5436
  createRenderEffect((_p$) => {
5170
- var _v$ = !!autoRestoreSession(), _v$2 = autoRestoreSession(), _v$3 = !!clearBookmarksOnLaunch(), _v$4 = clearBookmarksOnLaunch(), _v$5 = !!chatEnabled(), _v$6 = chatEnabled();
5171
- _v$ !== _p$.e && _el$20.classList.toggle("on", _p$.e = _v$);
5172
- _v$2 !== _p$.t && setAttribute(_el$20, "aria-checked", _p$.t = _v$2);
5173
- _v$3 !== _p$.a && _el$23.classList.toggle("on", _p$.a = _v$3);
5174
- _v$4 !== _p$.o && setAttribute(_el$23, "aria-checked", _p$.o = _v$4);
5175
- _v$5 !== _p$.i && _el$27.classList.toggle("on", _p$.i = _v$5);
5176
- _v$6 !== _p$.n && setAttribute(_el$27, "aria-checked", _p$.n = _v$6);
5437
+ var _v$ = !!autoRestoreSession(), _v$2 = autoRestoreSession(), _v$3 = !!clearBookmarksOnLaunch(), _v$4 = clearBookmarksOnLaunch(), _v$5 = !!chatEnabled(), _v$6 = chatEnabled(), _v$7 = !!telemetryEnabled(), _v$8 = telemetryEnabled();
5438
+ _v$ !== _p$.e && _el$21.classList.toggle("on", _p$.e = _v$);
5439
+ _v$2 !== _p$.t && setAttribute(_el$21, "aria-checked", _p$.t = _v$2);
5440
+ _v$3 !== _p$.a && _el$24.classList.toggle("on", _p$.a = _v$3);
5441
+ _v$4 !== _p$.o && setAttribute(_el$24, "aria-checked", _p$.o = _v$4);
5442
+ _v$5 !== _p$.i && _el$28.classList.toggle("on", _p$.i = _v$5);
5443
+ _v$6 !== _p$.n && setAttribute(_el$28, "aria-checked", _p$.n = _v$6);
5444
+ _v$7 !== _p$.s && _el$57.classList.toggle("on", _p$.s = _v$7);
5445
+ _v$8 !== _p$.h && setAttribute(_el$57, "aria-checked", _p$.h = _v$8);
5177
5446
  return _p$;
5178
5447
  }, {
5179
5448
  e: void 0,
@@ -5181,15 +5450,16 @@ const Settings = () => {
5181
5450
  a: void 0,
5182
5451
  o: void 0,
5183
5452
  i: void 0,
5184
- n: void 0
5453
+ n: void 0,
5454
+ s: void 0,
5455
+ h: void 0
5185
5456
  });
5186
5457
  createRenderEffect(() => _el$7.value = defaultUrl());
5187
5458
  createRenderEffect(() => _el$0.value = mcpPort());
5188
- createRenderEffect(() => _el$11.value = maxToolIterations());
5189
- createRenderEffect(() => _el$14.value = obsidianVaultPath());
5190
- createRenderEffect(() => _el$17.value = agentTranscriptMode());
5459
+ createRenderEffect(() => _el$15.value = obsidianVaultPath());
5460
+ createRenderEffect(() => _el$18.value = agentTranscriptMode());
5191
5461
  return _el$;
5192
- })(), _tmpl$8()];
5462
+ })(), _tmpl$0()];
5193
5463
  }
5194
5464
  });
5195
5465
  };
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self' data:;" />
7
7
  <title>Vessel</title>
8
- <script type="module" crossorigin src="./assets/index-iB-6qrfG.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-DAaJOss-.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-DMd-y6tm.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@quanta-intellect/vessel-browser",
3
3
  "mcpName": "io.github.unmodeled-tyler/vessel-browser",
4
- "version": "0.1.17",
4
+ "version": "0.1.18",
5
5
  "description": "AI-native web browser for Linux — persistent browser runtime for autonomous agents with human supervision",
6
6
  "main": "./out/main/index.js",
7
7
  "bin": {