@quanta-intellect/vessel-browser 0.1.6 → 0.1.9

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/README.md CHANGED
@@ -23,6 +23,19 @@ The preferred MVP install path is the Linux AppImage from GitHub Releases:
23
23
  3. Launch it: `./Vessel-*.AppImage`
24
24
  4. Open Settings (`Ctrl+,`) and confirm the MCP endpoint shown there
25
25
 
26
+ ### Install via npm
27
+
28
+ ```bash
29
+ npm install -g @quanta-intellect/vessel-browser
30
+ vessel-browser
31
+ ```
32
+
33
+ Or run it directly without installing:
34
+
35
+ ```bash
36
+ npx @quanta-intellect/vessel-browser
37
+ ```
38
+
26
39
  ### Source Install
27
40
 
28
41
  ```bash
package/out/main/index.js CHANGED
@@ -124,6 +124,14 @@ class Tab {
124
124
  });
125
125
  wc.on("dom-ready", () => {
126
126
  syncNavigationState();
127
+ wc.insertCSS(`
128
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
129
+ ::-webkit-scrollbar-track { background: transparent; }
130
+ ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 999px; }
131
+ ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); }
132
+ ::-webkit-scrollbar-corner { background: transparent; }
133
+ `).catch(() => {
134
+ });
127
135
  });
128
136
  wc.on("page-favicon-updated", (_, favicons) => {
129
137
  this._state.favicon = favicons[0] || "";
@@ -4049,7 +4057,7 @@ class OpenAICompatProvider {
4049
4057
  }
4050
4058
  };
4051
4059
  messages.push(assistantMsg);
4052
- if (finishReason !== "tool_calls" || toolCalls.length === 0) break;
4060
+ if (toolCalls.length === 0) break;
4053
4061
  for (const tc of toolCalls) {
4054
4062
  let args = {};
4055
4063
  try {
@@ -2615,7 +2615,7 @@ function sanitizeUrl(url) {
2615
2615
  function applyInlineMarkdown(text2) {
2616
2616
  const codeSpans = [];
2617
2617
  let withCodeTokens = text2.replace(/`([^`]+)`/g, (_, code) => {
2618
- const token = `@@CODE_SPAN_${codeSpans.length}@@`;
2618
+ const token = `\0CS${codeSpans.length}\0`;
2619
2619
  codeSpans.push(`<code>${escapeHtml(code)}</code>`);
2620
2620
  return token;
2621
2621
  });
@@ -2633,7 +2633,7 @@ function applyInlineMarkdown(text2) {
2633
2633
  );
2634
2634
  html2 = html2.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>").replace(/__([^_]+)__/g, "<strong>$1</strong>").replace(/(^|[^\*])\*([^*\n]+)\*/g, "$1<em>$2</em>").replace(/(^|[^_])_([^_\n]+)_/g, "$1<em>$2</em>");
2635
2635
  return codeSpans.reduce(
2636
- (output, snippet, index) => output.replace(`@@CODE_SPAN_${index}@@`, snippet),
2636
+ (output, snippet, index) => output.replace(`\0CS${index}\0`, snippet),
2637
2637
  html2
2638
2638
  );
2639
2639
  }
@@ -2645,7 +2645,7 @@ function renderList(block, ordered) {
2645
2645
  function renderBlock(block) {
2646
2646
  const trimmed = block.trim();
2647
2647
  if (!trimmed) return "";
2648
- const codeMatch = trimmed.match(/^@@CODE_BLOCK_(\d+)@@$/);
2648
+ const codeMatch = trimmed.match(/^\x00CB\d+\x00$/);
2649
2649
  if (codeMatch) {
2650
2650
  return trimmed;
2651
2651
  }
@@ -2674,7 +2674,7 @@ function renderMarkdown(source) {
2674
2674
  const normalized = source.replace(/\r\n?/g, "\n").replace(
2675
2675
  /```([\w-]+)?\n([\s\S]*?)```/g,
2676
2676
  (_, language, code) => {
2677
- const token = `@@CODE_BLOCK_${codeBlocks.length}@@`;
2677
+ const token = `\0CB${codeBlocks.length}\0`;
2678
2678
  const langAttr = language ? ` data-language="${escapeHtml(language)}"` : "";
2679
2679
  codeBlocks.push(
2680
2680
  `<pre><code${langAttr}>${escapeHtml(code.replace(/\n$/, ""))}</code></pre>`
@@ -2684,7 +2684,7 @@ function renderMarkdown(source) {
2684
2684
  );
2685
2685
  const rendered = normalized.split(/\n{2,}/).map(renderBlock).filter(Boolean).join("");
2686
2686
  const withCodeBlocks = codeBlocks.reduce(
2687
- (output, snippet, index) => output.replace(`@@CODE_BLOCK_${index}@@`, snippet),
2687
+ (output, snippet, index) => output.replace(`\0CB${index}\0`, snippet),
2688
2688
  rendered
2689
2689
  );
2690
2690
  return purify.sanitize(withCodeBlocks, {
@@ -2767,7 +2767,7 @@ function getBookmarkSearchMatch(args) {
2767
2767
  return { matchedFields, score };
2768
2768
  }
2769
2769
  const vesselLogo = "" + new URL("vessel-logo-transparent-IT25qr-Z.png", import.meta.url).href;
2770
- var _tmpl$$3 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class=dropdown-select-menu role=listbox>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div><button class=dropdown-select-trigger type=button aria-haspopup=listbox><span class=dropdown-select-value></span><span class=dropdown-select-caret aria-hidden=true>▾`), _tmpl$4$2 = /* @__PURE__ */ template(`<span class=dropdown-select-option-description>`), _tmpl$5$2 = /* @__PURE__ */ template(`<button class=dropdown-select-option type=button role=option><span class=dropdown-select-option-copy><span class=dropdown-select-option-label>`), _tmpl$6$2 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$7$2 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$8$2 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$9$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$0$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$1$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$10$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$11$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$12$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$13$1 = /* @__PURE__ */ template(`<span>`), _tmpl$14$1 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$15 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$16 = /* @__PURE__ */ template(`<div class=sidebar-empty><svg class=sidebar-empty-icon width=48 height=48 viewBox="0 0 48 48"aria-hidden=true><circle cx=24 cy=24 r=20 fill=none stroke=var(--border-visible) stroke-width=1.5></circle><circle cx=24 cy=24 r=12 fill=none stroke=var(--accent-primary) stroke-width=1 opacity=0.3></circle><circle cx=24 cy=24 r=4 fill=none stroke=var(--accent-primary) stroke-width=1.5 opacity=0.6></circle><line x1=24 y1=4 x2=24 y2=12 stroke=var(--border-visible) stroke-width=1 stroke-linecap=round></line><line x1=24 y1=36 x2=24 y2=44 stroke=var(--border-visible) stroke-width=1 stroke-linecap=round></line><line x1=4 y1=24 x2=12 y2=24 stroke=var(--border-visible) stroke-width=1 stroke-linecap=round></line><line x1=36 y1=24 x2=44 y2=24 stroke=var(--border-visible) stroke-width=1 stroke-linecap=round></line></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$17 = /* @__PURE__ */ template(`<button class=sidebar-cancel>Stop`), _tmpl$18 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2 placeholder="Ask anything...">`), _tmpl$19 = /* @__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$20 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$21 = /* @__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$22 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$23 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$24 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$25 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$26 = /* @__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$27 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$28 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$29 = /* @__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$30 = /* @__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$31 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$32 = /* @__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$33 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$34 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$35 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$36 = /* @__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$37 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$38 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$39 = /* @__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$40 = /* @__PURE__ */ template(`<div>`), _tmpl$41 = /* @__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$42 = /* @__PURE__ */ template(`<button class=sidebar-send>Send`);
2770
+ var _tmpl$$3 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class=dropdown-select-menu role=listbox>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div><button class=dropdown-select-trigger type=button aria-haspopup=listbox><span class=dropdown-select-value></span><span class=dropdown-select-caret aria-hidden=true>▾`), _tmpl$4$2 = /* @__PURE__ */ template(`<span class=dropdown-select-option-description>`), _tmpl$5$2 = /* @__PURE__ */ template(`<button class=dropdown-select-option type=button role=option><span class=dropdown-select-option-copy><span class=dropdown-select-option-label>`), _tmpl$6$2 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$7$2 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$8$2 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$9$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$0$2 = /* @__PURE__ */ template(`<span class=bookmark-status-pill>Saved`), _tmpl$1$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$10$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$11$2 = /* @__PURE__ */ template(`<div class=checkpoint-timeline>`), _tmpl$12$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$13$1 = /* @__PURE__ */ template(`<span>`), _tmpl$14$1 = /* @__PURE__ */ template(`<div><div class=streaming-status><span class=streaming-pulse aria-hidden=true></span><span>Generating`), _tmpl$15 = /* @__PURE__ */ template(`<div class="message message-assistant"><div class=message-content>`), _tmpl$16 = /* @__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$17 = /* @__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$18 = /* @__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$19 = /* @__PURE__ */ template(`<div class=chat-actions>`), _tmpl$20 = /* @__PURE__ */ template(`<div class=sidebar-input-area><textarea class=sidebar-input rows=2 placeholder="Ask anything..."></textarea><button class=sidebar-send>Send`), _tmpl$21 = /* @__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$22 = /* @__PURE__ */ template(`<div class=agent-muted>No pending approvals.`), _tmpl$23 = /* @__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$24 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$25 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$26 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$27 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$28 = /* @__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$29 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$30 = /* @__PURE__ */ template(`<div class=bookmark-folder-summary>`), _tmpl$31 = /* @__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$32 = /* @__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$33 = /* @__PURE__ */ template(`<div class=bookmark-items>`), _tmpl$34 = /* @__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$35 = /* @__PURE__ */ template(`<div class=bookmark-folder-collapsed-hint>Click to view saved links.`), _tmpl$36 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>No bookmarks in this folder yet.`), _tmpl$37 = /* @__PURE__ */ template(`<div class=bookmark-item-note>`), _tmpl$38 = /* @__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$39 = /* @__PURE__ */ template(`<div class=agent-muted>No checkpoints yet.`), _tmpl$40 = /* @__PURE__ */ template(`<span class=checkpoint-timeline-line>`), _tmpl$41 = /* @__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$42 = /* @__PURE__ */ template(`<div>`), _tmpl$43 = /* @__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`);
2771
2771
  const UNSORTED_FOLDER = {
2772
2772
  id: "unsorted",
2773
2773
  name: "Unsorted",
@@ -2915,6 +2915,15 @@ const Sidebar = (props) => {
2915
2915
  setChatInput("");
2916
2916
  await query(prompt);
2917
2917
  };
2918
+ const handleRetry = () => {
2919
+ const msgs = messages2();
2920
+ for (let i = msgs.length - 1; i >= 0; i--) {
2921
+ if (msgs[i].role === "user") {
2922
+ void query(msgs[i].content);
2923
+ return;
2924
+ }
2925
+ }
2926
+ };
2918
2927
  const [checkpointName, setCheckpointName] = createSignal("");
2919
2928
  const [bookmarkNote, setBookmarkNote] = createSignal("");
2920
2929
  const [bookmarkSaveExpanded, setBookmarkSaveExpanded] = createSignal(false);
@@ -3107,7 +3116,7 @@ const Sidebar = (props) => {
3107
3116
  return props.forceOpen || sidebarOpen2();
3108
3117
  },
3109
3118
  get children() {
3110
- var _el$1 = _tmpl$19(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$14 = _el$12.nextSibling, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling, _el$17 = _el$11.nextSibling, _el$18 = _el$17.firstChild;
3119
+ var _el$1 = _tmpl$21(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$14 = _el$12.nextSibling, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling, _el$17 = _el$11.nextSibling, _el$18 = _el$17.firstChild;
3111
3120
  _el$18.firstChild;
3112
3121
  var _el$21 = _el$18.nextSibling, _el$22 = _el$21.nextSibling, _el$23 = _el$22.nextSibling, _el$24 = _el$17.nextSibling, _el$81 = _el$24.firstChild;
3113
3122
  _el$10.$$pointerdown = startResize;
@@ -3161,7 +3170,7 @@ const Sidebar = (props) => {
3161
3170
  return runtimeState2().supervisor.pendingApprovals.length > 0;
3162
3171
  },
3163
3172
  get fallback() {
3164
- return _tmpl$20();
3173
+ return _tmpl$22();
3165
3174
  },
3166
3175
  get children() {
3167
3176
  return [_tmpl$7$2(), createComponent(For, {
@@ -3169,13 +3178,13 @@ const Sidebar = (props) => {
3169
3178
  return runtimeState2().supervisor.pendingApprovals;
3170
3179
  },
3171
3180
  children: (approval) => (() => {
3172
- var _el$86 = _tmpl$21(), _el$87 = _el$86.firstChild, _el$88 = _el$87.nextSibling, _el$89 = _el$88.nextSibling, _el$90 = _el$89.nextSibling, _el$91 = _el$90.nextSibling, _el$92 = _el$91.firstChild, _el$93 = _el$92.nextSibling;
3173
- insert(_el$88, () => approval.name);
3174
- insert(_el$89, () => approval.argsSummary);
3175
- insert(_el$90, () => approval.reason);
3176
- _el$92.$$click = () => void resolveApproval(approval.id, true);
3177
- _el$93.$$click = () => void resolveApproval(approval.id, false);
3178
- return _el$86;
3181
+ var _el$89 = _tmpl$23(), _el$90 = _el$89.firstChild, _el$91 = _el$90.nextSibling, _el$92 = _el$91.nextSibling, _el$93 = _el$92.nextSibling, _el$94 = _el$93.nextSibling, _el$95 = _el$94.firstChild, _el$96 = _el$95.nextSibling;
3182
+ insert(_el$91, () => approval.name);
3183
+ insert(_el$92, () => approval.argsSummary);
3184
+ insert(_el$93, () => approval.reason);
3185
+ _el$95.$$click = () => void resolveApproval(approval.id, true);
3186
+ _el$96.$$click = () => void resolveApproval(approval.id, false);
3187
+ return _el$89;
3179
3188
  })()
3180
3189
  })];
3181
3190
  }
@@ -3199,7 +3208,7 @@ const Sidebar = (props) => {
3199
3208
  return recentActions().length > 0;
3200
3209
  },
3201
3210
  get fallback() {
3202
- return _tmpl$22();
3211
+ return _tmpl$24();
3203
3212
  },
3204
3213
  get children() {
3205
3214
  return createComponent(Show, {
@@ -3207,7 +3216,7 @@ const Sidebar = (props) => {
3207
3216
  return actionsExpanded();
3208
3217
  },
3209
3218
  get fallback() {
3210
- return _tmpl$23();
3219
+ return _tmpl$25();
3211
3220
  },
3212
3221
  get children() {
3213
3222
  return createComponent(For, {
@@ -3215,32 +3224,32 @@ const Sidebar = (props) => {
3215
3224
  return recentActions();
3216
3225
  },
3217
3226
  children: (action) => (() => {
3218
- var _el$96 = _tmpl$26(), _el$97 = _el$96.firstChild, _el$98 = _el$97.firstChild, _el$99 = _el$98.nextSibling, _el$100 = _el$97.nextSibling;
3219
- insert(_el$98, () => action.name);
3220
- insert(_el$99, () => action.status);
3221
- insert(_el$100, () => action.argsSummary);
3222
- insert(_el$96, createComponent(Show, {
3227
+ var _el$99 = _tmpl$28(), _el$100 = _el$99.firstChild, _el$101 = _el$100.firstChild, _el$102 = _el$101.nextSibling, _el$103 = _el$100.nextSibling;
3228
+ insert(_el$101, () => action.name);
3229
+ insert(_el$102, () => action.status);
3230
+ insert(_el$103, () => action.argsSummary);
3231
+ insert(_el$99, createComponent(Show, {
3223
3232
  get when() {
3224
3233
  return action.resultSummary;
3225
3234
  },
3226
3235
  get children() {
3227
- var _el$101 = _tmpl$24();
3228
- insert(_el$101, () => action.resultSummary);
3229
- return _el$101;
3236
+ var _el$104 = _tmpl$26();
3237
+ insert(_el$104, () => action.resultSummary);
3238
+ return _el$104;
3230
3239
  }
3231
3240
  }), null);
3232
- insert(_el$96, createComponent(Show, {
3241
+ insert(_el$99, createComponent(Show, {
3233
3242
  get when() {
3234
3243
  return action.error;
3235
3244
  },
3236
3245
  get children() {
3237
- var _el$102 = _tmpl$25();
3238
- insert(_el$102, () => action.error);
3239
- return _el$102;
3246
+ var _el$105 = _tmpl$27();
3247
+ insert(_el$105, () => action.error);
3248
+ return _el$105;
3240
3249
  }
3241
3250
  }), null);
3242
- createRenderEffect(() => className(_el$99, `agent-action-status ${action.status}`));
3243
- return _el$96;
3251
+ createRenderEffect(() => className(_el$102, `agent-action-status ${action.status}`));
3252
+ return _el$99;
3244
3253
  })()
3245
3254
  });
3246
3255
  }
@@ -3306,12 +3315,12 @@ const Sidebar = (props) => {
3306
3315
  },
3307
3316
  get fallback() {
3308
3317
  return (() => {
3309
- var _el$103 = _tmpl$27();
3310
- insert(_el$103, (() => {
3318
+ var _el$106 = _tmpl$29();
3319
+ insert(_el$106, (() => {
3311
3320
  var _c$4 = memo(() => !!normalizedBookmarkSearch());
3312
3321
  return () => _c$4() ? `No bookmarks matched "${bookmarkSearchQuery().trim()}".` : "No bookmarks saved yet.";
3313
3322
  })());
3314
- return _el$103;
3323
+ return _el$106;
3315
3324
  })();
3316
3325
  },
3317
3326
  get children() {
@@ -3320,71 +3329,71 @@ const Sidebar = (props) => {
3320
3329
  return filteredGroupedBookmarks();
3321
3330
  },
3322
3331
  children: (folder) => (() => {
3323
- var _el$104 = _tmpl$32(), _el$105 = _el$104.firstChild, _el$106 = _el$105.firstChild, _el$107 = _el$106.firstChild, _el$108 = _el$107.nextSibling, _el$109 = _el$108.firstChild, _el$110 = _el$109.nextSibling, _el$111 = _el$110.firstChild;
3324
- _el$105.$$keydown = (e) => {
3332
+ var _el$107 = _tmpl$34(), _el$108 = _el$107.firstChild, _el$109 = _el$108.firstChild, _el$110 = _el$109.firstChild, _el$111 = _el$110.nextSibling, _el$112 = _el$111.firstChild, _el$113 = _el$112.nextSibling, _el$114 = _el$113.firstChild;
3333
+ _el$108.$$keydown = (e) => {
3325
3334
  if (e.key === "Enter" || e.key === " ") {
3326
3335
  e.preventDefault();
3327
3336
  toggleFolderExpanded(folder.id);
3328
3337
  }
3329
3338
  };
3330
- _el$105.$$click = () => toggleFolderExpanded(folder.id);
3331
- insert(_el$109, () => folder.name);
3332
- insert(_el$110, () => folder.items.length, _el$111);
3333
- insert(_el$108, createComponent(Show, {
3339
+ _el$108.$$click = () => toggleFolderExpanded(folder.id);
3340
+ insert(_el$112, () => folder.name);
3341
+ insert(_el$113, () => folder.items.length, _el$114);
3342
+ insert(_el$111, createComponent(Show, {
3334
3343
  get when() {
3335
3344
  return folder.summary;
3336
3345
  },
3337
3346
  get children() {
3338
- var _el$112 = _tmpl$28();
3339
- insert(_el$112, () => folder.summary);
3340
- return _el$112;
3347
+ var _el$115 = _tmpl$30();
3348
+ insert(_el$115, () => folder.summary);
3349
+ return _el$115;
3341
3350
  }
3342
3351
  }), null);
3343
- insert(_el$105, createComponent(Show, {
3352
+ insert(_el$108, createComponent(Show, {
3344
3353
  get when() {
3345
3354
  return folder.id !== UNSORTED_FOLDER.id;
3346
3355
  },
3347
3356
  get children() {
3348
- var _el$113 = _tmpl$29(), _el$114 = _el$113.firstChild, _el$115 = _el$114.nextSibling;
3349
- _el$114.$$click = (e) => {
3357
+ var _el$116 = _tmpl$31(), _el$117 = _el$116.firstChild, _el$118 = _el$117.nextSibling;
3358
+ _el$117.$$click = (e) => {
3350
3359
  e.stopPropagation();
3351
3360
  setEditingFolderId(folder.id);
3352
3361
  setEditingFolderName(folder.name);
3353
3362
  setEditingFolderSummary(folder.summary || "");
3354
3363
  };
3355
- _el$115.$$click = (e) => {
3364
+ _el$118.$$click = (e) => {
3356
3365
  e.stopPropagation();
3357
3366
  void handleRemoveFolder(folder.id);
3358
3367
  };
3359
- return _el$113;
3368
+ return _el$116;
3360
3369
  }
3361
3370
  }), null);
3362
- insert(_el$104, createComponent(Show, {
3371
+ insert(_el$107, createComponent(Show, {
3363
3372
  get when() {
3364
3373
  return editingFolderId() === folder.id;
3365
3374
  },
3366
3375
  get children() {
3367
- var _el$116 = _tmpl$30(), _el$117 = _el$116.firstChild, _el$118 = _el$117.firstChild, _el$119 = _el$118.nextSibling, _el$120 = _el$117.nextSibling, _el$121 = _el$120.nextSibling;
3368
- _el$118.$$input = (e) => setEditingFolderName(e.currentTarget.value);
3369
- _el$119.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
3370
- _el$120.$$click = () => void handleRenameFolder(folder.id);
3371
- _el$121.$$click = () => {
3376
+ var _el$119 = _tmpl$32(), _el$120 = _el$119.firstChild, _el$121 = _el$120.firstChild, _el$122 = _el$121.nextSibling, _el$123 = _el$120.nextSibling, _el$124 = _el$123.nextSibling;
3377
+ _el$121.$$input = (e) => setEditingFolderName(e.currentTarget.value);
3378
+ _el$122.$$input = (e) => setEditingFolderSummary(e.currentTarget.value);
3379
+ _el$123.$$click = () => void handleRenameFolder(folder.id);
3380
+ _el$124.$$click = () => {
3372
3381
  setEditingFolderId(null);
3373
3382
  setEditingFolderName("");
3374
3383
  setEditingFolderSummary("");
3375
3384
  };
3376
- createRenderEffect(() => _el$120.disabled = !editingFolderName().trim());
3377
- createRenderEffect(() => _el$118.value = editingFolderName());
3378
- createRenderEffect(() => _el$119.value = editingFolderSummary());
3379
- return _el$116;
3385
+ createRenderEffect(() => _el$123.disabled = !editingFolderName().trim());
3386
+ createRenderEffect(() => _el$121.value = editingFolderName());
3387
+ createRenderEffect(() => _el$122.value = editingFolderSummary());
3388
+ return _el$119;
3380
3389
  }
3381
3390
  }), null);
3382
- insert(_el$104, createComponent(Show, {
3391
+ insert(_el$107, createComponent(Show, {
3383
3392
  get when() {
3384
3393
  return isFolderExpanded(folder.id);
3385
3394
  },
3386
3395
  get fallback() {
3387
- return _tmpl$33();
3396
+ return _tmpl$35();
3388
3397
  },
3389
3398
  get children() {
3390
3399
  return createComponent(Show, {
@@ -3392,41 +3401,41 @@ const Sidebar = (props) => {
3392
3401
  return folder.items.length > 0;
3393
3402
  },
3394
3403
  get fallback() {
3395
- return _tmpl$34();
3404
+ return _tmpl$36();
3396
3405
  },
3397
3406
  get children() {
3398
- var _el$122 = _tmpl$31();
3399
- insert(_el$122, createComponent(For, {
3407
+ var _el$125 = _tmpl$33();
3408
+ insert(_el$125, createComponent(For, {
3400
3409
  get each() {
3401
3410
  return folder.items;
3402
3411
  },
3403
3412
  children: (bookmark) => (() => {
3404
- var _el$125 = _tmpl$36(), _el$126 = _el$125.firstChild, _el$127 = _el$126.firstChild, _el$128 = _el$127.nextSibling, _el$130 = _el$126.nextSibling, _el$131 = _el$130.firstChild, _el$132 = _el$131.nextSibling;
3405
- _el$126.$$click = () => void createTab(bookmark.url);
3406
- insert(_el$127, () => bookmark.title || bookmark.url);
3407
- insert(_el$128, () => bookmark.url);
3408
- insert(_el$125, createComponent(Show, {
3413
+ var _el$128 = _tmpl$38(), _el$129 = _el$128.firstChild, _el$130 = _el$129.firstChild, _el$131 = _el$130.nextSibling, _el$133 = _el$129.nextSibling, _el$134 = _el$133.firstChild, _el$135 = _el$134.nextSibling;
3414
+ _el$129.$$click = () => void createTab(bookmark.url);
3415
+ insert(_el$130, () => bookmark.title || bookmark.url);
3416
+ insert(_el$131, () => bookmark.url);
3417
+ insert(_el$128, createComponent(Show, {
3409
3418
  get when() {
3410
3419
  return bookmark.note;
3411
3420
  },
3412
3421
  get children() {
3413
- var _el$129 = _tmpl$35();
3414
- insert(_el$129, () => bookmark.note);
3415
- return _el$129;
3422
+ var _el$132 = _tmpl$37();
3423
+ insert(_el$132, () => bookmark.note);
3424
+ return _el$132;
3416
3425
  }
3417
- }), _el$130);
3418
- insert(_el$131, () => formatBookmarkDate(bookmark.savedAt));
3419
- _el$132.$$click = () => void removeBookmark(bookmark.id);
3420
- return _el$125;
3426
+ }), _el$133);
3427
+ insert(_el$134, () => formatBookmarkDate(bookmark.savedAt));
3428
+ _el$135.$$click = () => void removeBookmark(bookmark.id);
3429
+ return _el$128;
3421
3430
  })()
3422
3431
  }));
3423
- return _el$122;
3432
+ return _el$125;
3424
3433
  }
3425
3434
  });
3426
3435
  }
3427
3436
  }), null);
3428
- createRenderEffect(() => _el$107.classList.toggle("expanded", !!isFolderExpanded(folder.id)));
3429
- return _el$104;
3437
+ createRenderEffect(() => _el$110.classList.toggle("expanded", !!isFolderExpanded(folder.id)));
3438
+ return _el$107;
3430
3439
  })()
3431
3440
  });
3432
3441
  }
@@ -3468,7 +3477,7 @@ const Sidebar = (props) => {
3468
3477
  return recentCheckpoints().length > 0;
3469
3478
  },
3470
3479
  get fallback() {
3471
- return _tmpl$37();
3480
+ return _tmpl$39();
3472
3481
  },
3473
3482
  get children() {
3474
3483
  var _el$72 = _tmpl$11$2();
@@ -3477,20 +3486,20 @@ const Sidebar = (props) => {
3477
3486
  return recentCheckpoints();
3478
3487
  },
3479
3488
  children: (checkpoint, i) => (() => {
3480
- var _el$134 = _tmpl$39(), _el$135 = _el$134.firstChild, _el$136 = _el$135.firstChild, _el$138 = _el$135.nextSibling, _el$139 = _el$138.firstChild, _el$140 = _el$139.nextSibling, _el$141 = _el$140.nextSibling;
3481
- insert(_el$135, createComponent(Show, {
3489
+ var _el$137 = _tmpl$41(), _el$138 = _el$137.firstChild, _el$139 = _el$138.firstChild, _el$141 = _el$138.nextSibling, _el$142 = _el$141.firstChild, _el$143 = _el$142.nextSibling, _el$144 = _el$143.nextSibling;
3490
+ insert(_el$138, createComponent(Show, {
3482
3491
  get when() {
3483
3492
  return i() < recentCheckpoints().length - 1;
3484
3493
  },
3485
3494
  get children() {
3486
- return _tmpl$38();
3495
+ return _tmpl$40();
3487
3496
  }
3488
3497
  }), null);
3489
- insert(_el$139, () => checkpoint.name);
3490
- insert(_el$140, () => new Date(checkpoint.createdAt).toLocaleString());
3491
- _el$141.$$click = () => void restoreCheckpoint(checkpoint.id);
3492
- createRenderEffect(() => _el$136.classList.toggle("latest", !!(i() === 0)));
3493
- return _el$134;
3498
+ insert(_el$142, () => checkpoint.name);
3499
+ insert(_el$143, () => new Date(checkpoint.createdAt).toLocaleString());
3500
+ _el$144.$$click = () => void restoreCheckpoint(checkpoint.id);
3501
+ createRenderEffect(() => _el$139.classList.toggle("latest", !!(i() === 0)));
3502
+ return _el$137;
3494
3503
  })()
3495
3504
  }));
3496
3505
  return _el$72;
@@ -3510,14 +3519,14 @@ const Sidebar = (props) => {
3510
3519
  return messages2();
3511
3520
  },
3512
3521
  children: (msg) => (() => {
3513
- var _el$142 = _tmpl$40();
3514
- insert(_el$142, createComponent(MarkdownMessage, {
3522
+ var _el$145 = _tmpl$42();
3523
+ insert(_el$145, createComponent(MarkdownMessage, {
3515
3524
  get content() {
3516
3525
  return msg.content;
3517
3526
  }
3518
3527
  }));
3519
- createRenderEffect(() => className(_el$142, `message message-${msg.role}`));
3520
- return _el$142;
3528
+ createRenderEffect(() => className(_el$145, `message message-${msg.role}`));
3529
+ return _el$145;
3521
3530
  })()
3522
3531
  }), createComponent(Show, {
3523
3532
  get when() {
@@ -3530,7 +3539,7 @@ const Sidebar = (props) => {
3530
3539
  return hasFirstChunk2();
3531
3540
  },
3532
3541
  get fallback() {
3533
- return _tmpl$41();
3542
+ return _tmpl$43();
3534
3543
  },
3535
3544
  get children() {
3536
3545
  var _el$75 = _tmpl$14$1(), _el$76 = _el$75.firstChild, _el$77 = _el$76.firstChild;
@@ -3572,34 +3581,48 @@ const Sidebar = (props) => {
3572
3581
  return sidebarTab() === "chat";
3573
3582
  },
3574
3583
  get children() {
3575
- var _el$82 = _tmpl$18(), _el$83 = _el$82.firstChild;
3576
- _el$83.$$keydown = (e) => {
3577
- if (e.key === "Enter" && !e.shiftKey) {
3578
- e.preventDefault();
3579
- void handleChatSend();
3580
- }
3581
- };
3582
- _el$83.$$input = (e) => setChatInput(e.currentTarget.value);
3583
- insert(_el$82, createComponent(Show, {
3584
+ return [createComponent(Show, {
3584
3585
  get when() {
3585
- return isStreaming2();
3586
- },
3587
- get fallback() {
3588
- return (() => {
3589
- var _el$144 = _tmpl$42();
3590
- _el$144.$$click = () => void handleChatSend();
3591
- createRenderEffect(() => _el$144.disabled = !chatInput().trim());
3592
- return _el$144;
3593
- })();
3586
+ return isStreaming2() || messages2().length > 0;
3594
3587
  },
3595
3588
  get children() {
3596
- var _el$84 = _tmpl$17();
3597
- _el$84.$$click = () => cancel();
3598
- return _el$84;
3589
+ var _el$82 = _tmpl$19();
3590
+ insert(_el$82, createComponent(Show, {
3591
+ get when() {
3592
+ return isStreaming2();
3593
+ },
3594
+ get children() {
3595
+ var _el$83 = _tmpl$17();
3596
+ _el$83.$$click = () => cancel();
3597
+ return _el$83;
3598
+ }
3599
+ }), null);
3600
+ insert(_el$82, createComponent(Show, {
3601
+ get when() {
3602
+ return memo(() => !!!isStreaming2())() && messages2().length > 0;
3603
+ },
3604
+ get children() {
3605
+ var _el$84 = _tmpl$18();
3606
+ _el$84.$$click = handleRetry;
3607
+ return _el$84;
3608
+ }
3609
+ }), null);
3610
+ return _el$82;
3599
3611
  }
3600
- }), null);
3601
- createRenderEffect(() => _el$83.value = chatInput());
3602
- return _el$82;
3612
+ }), (() => {
3613
+ var _el$85 = _tmpl$20(), _el$86 = _el$85.firstChild, _el$87 = _el$86.nextSibling;
3614
+ _el$86.$$keydown = (e) => {
3615
+ if (e.key === "Enter" && !e.shiftKey) {
3616
+ e.preventDefault();
3617
+ void handleChatSend();
3618
+ }
3619
+ };
3620
+ _el$86.$$input = (e) => setChatInput(e.currentTarget.value);
3621
+ _el$87.$$click = () => void handleChatSend();
3622
+ createRenderEffect(() => _el$87.disabled = !chatInput().trim() || isStreaming2());
3623
+ createRenderEffect(() => _el$86.value = chatInput());
3624
+ return _el$85;
3625
+ })()];
3603
3626
  }
3604
3627
  }), null);
3605
3628
  createRenderEffect((_p$) => {
@@ -2049,6 +2049,7 @@
2049
2049
  max-width: 92%;
2050
2050
  white-space: pre-wrap;
2051
2051
  word-break: break-word;
2052
+ user-select: text;
2052
2053
  animation: message-enter 300ms var(--ease-out-expo) both;
2053
2054
  }
2054
2055
 
@@ -2332,6 +2333,34 @@
2332
2333
  max-width: 240px;
2333
2334
  }
2334
2335
 
2336
+ .chat-actions {
2337
+ display: flex;
2338
+ gap: 6px;
2339
+ padding: 6px 14px;
2340
+ flex-shrink: 0;
2341
+ }
2342
+
2343
+ .chat-action-btn {
2344
+ display: inline-flex;
2345
+ align-items: center;
2346
+ gap: 5px;
2347
+ padding: 4px 10px;
2348
+ font-size: 11px;
2349
+ font-weight: 500;
2350
+ color: var(--text-muted);
2351
+ background: var(--bg-tertiary);
2352
+ border: 1px solid var(--border-subtle);
2353
+ border-radius: var(--radius-md);
2354
+ cursor: pointer;
2355
+ transition: color var(--duration-fast) var(--ease-in-out),
2356
+ border-color var(--duration-fast) var(--ease-in-out);
2357
+ }
2358
+
2359
+ .chat-action-btn:hover {
2360
+ color: var(--text-primary);
2361
+ border-color: var(--border-visible);
2362
+ }
2363
+
2335
2364
  .sidebar-input-area {
2336
2365
  display: flex;
2337
2366
  gap: 6px;
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Vessel</title>
7
- <script type="module" crossorigin src="./assets/index-BYA528aQ.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-Bz1EMkt-.css">
7
+ <script type="module" crossorigin src="./assets/index-CCVxW0YM.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-Cud0VqFQ.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quanta-intellect/vessel-browser",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "AI-native web browser for Linux — persistent browser runtime for autonomous agents with human supervision",
5
5
  "main": "./out/main/index.js",
6
6
  "bin": {