@quanta-intellect/vessel-browser 0.1.17 → 0.1.19

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.
@@ -13,6 +13,7 @@ const UNOWNED = {
13
13
  context: null,
14
14
  owner: null
15
15
  };
16
+ const NO_INIT = {};
16
17
  var Owner = null;
17
18
  let Transition = null;
18
19
  let ExternalSourceConfig = null;
@@ -52,6 +53,10 @@ function createSignal(value, options) {
52
53
  };
53
54
  return [readSignal.bind(s), setter];
54
55
  }
56
+ function createComputed(fn, value, options) {
57
+ const c = createComputation(fn, value, true, STALE);
58
+ updateComputation(c);
59
+ }
55
60
  function createRenderEffect(fn, value, options) {
56
61
  const c = createComputation(fn, value, false, STALE);
57
62
  updateComputation(c);
@@ -71,6 +76,123 @@ function createMemo(fn, value, options) {
71
76
  updateComputation(c);
72
77
  return readSignal.bind(c);
73
78
  }
79
+ function isPromise(v) {
80
+ return v && typeof v === "object" && "then" in v;
81
+ }
82
+ function createResource(pSource, pFetcher, pOptions) {
83
+ let source;
84
+ let fetcher;
85
+ let options;
86
+ if (typeof pFetcher === "function") {
87
+ source = pSource;
88
+ fetcher = pFetcher;
89
+ options = {};
90
+ } else {
91
+ source = true;
92
+ fetcher = pSource;
93
+ options = pFetcher || {};
94
+ }
95
+ let pr = null, initP = NO_INIT, scheduled = false, resolved = "initialValue" in options, dynamic = typeof source === "function" && createMemo(source);
96
+ const contexts = /* @__PURE__ */ new Set(), [value, setValue] = (options.storage || createSignal)(options.initialValue), [error, setError] = createSignal(void 0), [track, trigger] = createSignal(void 0, {
97
+ equals: false
98
+ }), [state, setState] = createSignal(resolved ? "ready" : "unresolved");
99
+ function loadEnd(p, v, error2, key) {
100
+ if (pr === p) {
101
+ pr = null;
102
+ key !== void 0 && (resolved = true);
103
+ if ((p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
104
+ value: v
105
+ }));
106
+ initP = NO_INIT;
107
+ completeLoad(v, error2);
108
+ }
109
+ return v;
110
+ }
111
+ function completeLoad(v, err) {
112
+ runUpdates(() => {
113
+ if (err === void 0) setValue(() => v);
114
+ setState(err !== void 0 ? "errored" : resolved ? "ready" : "unresolved");
115
+ setError(err);
116
+ for (const c of contexts.keys()) c.decrement();
117
+ contexts.clear();
118
+ }, false);
119
+ }
120
+ function read() {
121
+ const c = SuspenseContext, v = value(), err = error();
122
+ if (err !== void 0 && !pr) throw err;
123
+ if (Listener && !Listener.user && c) ;
124
+ return v;
125
+ }
126
+ function load(refetching = true) {
127
+ if (refetching !== false && scheduled) return;
128
+ scheduled = false;
129
+ const lookup = dynamic ? dynamic() : source;
130
+ if (lookup == null || lookup === false) {
131
+ loadEnd(pr, untrack(value));
132
+ return;
133
+ }
134
+ let error2;
135
+ const p = initP !== NO_INIT ? initP : untrack(() => {
136
+ try {
137
+ return fetcher(lookup, {
138
+ value: value(),
139
+ refetching
140
+ });
141
+ } catch (fetcherError) {
142
+ error2 = fetcherError;
143
+ }
144
+ });
145
+ if (error2 !== void 0) {
146
+ loadEnd(pr, void 0, castError(error2), lookup);
147
+ return;
148
+ } else if (!isPromise(p)) {
149
+ loadEnd(pr, p, void 0, lookup);
150
+ return p;
151
+ }
152
+ pr = p;
153
+ if ("v" in p) {
154
+ if (p.s === 1) loadEnd(pr, p.v, void 0, lookup);
155
+ else loadEnd(pr, void 0, castError(p.v), lookup);
156
+ return p;
157
+ }
158
+ scheduled = true;
159
+ queueMicrotask(() => scheduled = false);
160
+ runUpdates(() => {
161
+ setState(resolved ? "refreshing" : "pending");
162
+ trigger();
163
+ }, false);
164
+ return p.then((v) => loadEnd(p, v, void 0, lookup), (e) => loadEnd(p, void 0, castError(e), lookup));
165
+ }
166
+ Object.defineProperties(read, {
167
+ state: {
168
+ get: () => state()
169
+ },
170
+ error: {
171
+ get: () => error()
172
+ },
173
+ loading: {
174
+ get() {
175
+ const s = state();
176
+ return s === "pending" || s === "refreshing";
177
+ }
178
+ },
179
+ latest: {
180
+ get() {
181
+ if (!resolved) return read();
182
+ const err = error();
183
+ if (err && !pr) throw err;
184
+ return value();
185
+ }
186
+ }
187
+ });
188
+ let owner = Owner;
189
+ if (dynamic) createComputed(() => (owner = Owner, load(false)));
190
+ else load(false);
191
+ return [read, {
192
+ refetch: (info) => runWithOwner(owner, () => load(info)),
193
+ mutate: setValue
194
+ }];
195
+ }
74
196
  function untrack(fn) {
75
197
  if (Listener === null) return fn();
76
198
  const listener = Listener;
@@ -91,6 +213,22 @@ function onCleanup(fn) {
91
213
  else Owner.cleanups.push(fn);
92
214
  return fn;
93
215
  }
216
+ function runWithOwner(o, fn) {
217
+ const prev = Owner;
218
+ const prevListener = Listener;
219
+ Owner = o;
220
+ Listener = null;
221
+ try {
222
+ return runUpdates(fn, true);
223
+ } catch (err) {
224
+ handleError(err);
225
+ } finally {
226
+ Owner = prev;
227
+ Listener = prevListener;
228
+ }
229
+ }
230
+ const [transPending, setTransPending] = /* @__PURE__ */ createSignal(false);
231
+ let SuspenseContext;
94
232
  function readSignal() {
95
233
  if (this.sources && this.state) {
96
234
  if (this.state === STALE) updateComputation(this);
@@ -703,13 +841,54 @@ function cleanChildren(parent, current, marker, replacement) {
703
841
  } else parent.insertBefore(node, marker);
704
842
  return [node];
705
843
  }
706
- var _tmpl$$b = /* @__PURE__ */ template(`<div class=title-bar><div class=title-bar-drag></div><div class=window-controls><button class=window-btn data-tooltip=Minimize><svg width=10 height=10 viewBox="0 0 10 10"><rect x=1 y=5 width=8 height=1 fill=currentColor></rect></svg></button><button class=window-btn data-tooltip=Maximize><svg width=10 height=10 viewBox="0 0 10 10"><rect x=1 y=1 width=8 height=8 fill=none stroke=currentColor stroke-width=1></rect></svg></button><button class="window-btn window-btn-close"data-tooltip=Close><svg width=10 height=10 viewBox="0 0 10 10"><line x1=1 y1=1 x2=9 y2=9 stroke=currentColor stroke-width=1.2></line><line x1=9 y1=1 x2=1 y2=9 stroke=currentColor stroke-width=1.2>`);
844
+ var _tmpl$$c = /* @__PURE__ */ template(`<div class=title-bar><div class=title-bar-drag></div><div class=mcp-status-area><button class=mcp-status-indicator><span class=mcp-dot></span><span class=mcp-label>MCP</span></button></div><div class=window-controls><button class=window-btn data-tooltip=Minimize><svg width=10 height=10 viewBox="0 0 10 10"><rect x=1 y=5 width=8 height=1 fill=currentColor></rect></svg></button><button class=window-btn data-tooltip=Maximize><svg width=10 height=10 viewBox="0 0 10 10"><rect x=1 y=1 width=8 height=8 fill=none stroke=currentColor stroke-width=1></rect></svg></button><button class="window-btn window-btn-close"data-tooltip=Close><svg width=10 height=10 viewBox="0 0 10 10"><line x1=1 y1=1 x2=9 y2=9 stroke=currentColor stroke-width=1.2></line><line x1=9 y1=1 x2=1 y2=9 stroke=currentColor stroke-width=1.2>`);
707
845
  const TitleBar = () => {
846
+ const [mcpStatus, setMcpStatus] = createSignal("starting");
847
+ const [mcpTooltip, setMcpTooltip] = createSignal("MCP: starting...");
848
+ const pollHealth = async () => {
849
+ try {
850
+ const health = await window.vessel.settings.getHealth();
851
+ setMcpStatus(health.mcp.status);
852
+ if (health.mcp.status === "ready") {
853
+ setMcpTooltip(`MCP ready — ${health.mcp.endpoint}`);
854
+ } else if (health.mcp.status === "error") {
855
+ setMcpTooltip(`MCP error: ${health.mcp.message}`);
856
+ } else {
857
+ setMcpTooltip(`MCP: ${health.mcp.status}`);
858
+ }
859
+ } catch {
860
+ setMcpStatus("error");
861
+ setMcpTooltip("MCP: status unavailable");
862
+ }
863
+ };
864
+ let healthInterval;
865
+ onMount(() => {
866
+ void pollHealth();
867
+ healthInterval = setInterval(() => void pollHealth(), 1e4);
868
+ });
869
+ onCleanup(() => clearInterval(healthInterval));
870
+ const handleMcpClick = () => {
871
+ window.vessel.ui.setSettingsVisibility(true);
872
+ };
708
873
  return (() => {
709
- var _el$ = _tmpl$$b(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling;
710
- _el$4.$$click = () => window.vessel.window.minimize();
711
- _el$5.$$click = () => window.vessel.window.maximize();
712
- _el$6.$$click = () => window.vessel.window.close();
874
+ var _el$ = _tmpl$$c(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$5 = _el$3.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling;
875
+ _el$4.$$click = handleMcpClick;
876
+ _el$6.$$click = () => window.vessel.window.minimize();
877
+ _el$7.$$click = () => window.vessel.window.maximize();
878
+ _el$8.$$click = () => window.vessel.window.close();
879
+ createRenderEffect((_p$) => {
880
+ var _v$ = !!(mcpStatus() === "ready"), _v$2 = !!(mcpStatus() === "error"), _v$3 = !!(mcpStatus() === "starting" || mcpStatus() === "stopped"), _v$4 = mcpTooltip();
881
+ _v$ !== _p$.e && _el$4.classList.toggle("mcp-ready", _p$.e = _v$);
882
+ _v$2 !== _p$.t && _el$4.classList.toggle("mcp-error", _p$.t = _v$2);
883
+ _v$3 !== _p$.a && _el$4.classList.toggle("mcp-starting", _p$.a = _v$3);
884
+ _v$4 !== _p$.o && setAttribute(_el$4, "title", _p$.o = _v$4);
885
+ return _p$;
886
+ }, {
887
+ e: void 0,
888
+ t: void 0,
889
+ a: void 0,
890
+ o: void 0
891
+ });
713
892
  return _el$;
714
893
  })();
715
894
  };
@@ -905,7 +1084,7 @@ function getAgentPresence(state, currentTime = Date.now()) {
905
1084
  }
906
1085
  return "idle";
907
1086
  }
908
- var _tmpl$$a = /* @__PURE__ */ template(`<img class=tab-favicon alt>`), _tmpl$2$9 = /* @__PURE__ */ template(`<span class=tab-favicon-fallback>`), _tmpl$3$6 = /* @__PURE__ */ template(`<div class=tab-bar><div class=tab-list><button class=tab-new data-tooltip="New Tab">+`), _tmpl$4$5 = /* @__PURE__ */ template(`<div role=tab><span class=tab-title></span><button class=tab-close>×`), _tmpl$5$3 = /* @__PURE__ */ template(`<span class=tab-agent-indicator aria-hidden=true title="Agent active on this tab">`), _tmpl$6$3 = /* @__PURE__ */ template(`<span class=tab-loading>`);
1087
+ var _tmpl$$b = /* @__PURE__ */ template(`<img class=tab-favicon alt>`), _tmpl$2$a = /* @__PURE__ */ template(`<span class=tab-favicon-fallback>`), _tmpl$3$7 = /* @__PURE__ */ template(`<div class=tab-bar><div class=tab-list><button class=tab-new data-tooltip="New Tab">+`), _tmpl$4$7 = /* @__PURE__ */ template(`<div role=tab><span class=tab-title></span><button class=tab-close>×`), _tmpl$5$5 = /* @__PURE__ */ template(`<span class=tab-agent-indicator aria-hidden=true title="Agent active on this tab">`), _tmpl$6$5 = /* @__PURE__ */ template(`<span class=tab-loading>`);
909
1088
  function stringToHue(str) {
910
1089
  let hash = 0;
911
1090
  for (let i = 0; i < str.length; i++) {
@@ -931,14 +1110,14 @@ const TabFavicon = (props) => {
931
1110
  },
932
1111
  get fallback() {
933
1112
  return (() => {
934
- var _el$2 = _tmpl$2$9();
1113
+ var _el$2 = _tmpl$2$a();
935
1114
  insert(_el$2, letter);
936
1115
  createRenderEffect((_$p) => setStyleProperty(_el$2, "--favicon-hue", `${hue()}`));
937
1116
  return _el$2;
938
1117
  })();
939
1118
  },
940
1119
  get children() {
941
- var _el$ = _tmpl$$a();
1120
+ var _el$ = _tmpl$$b();
942
1121
  _el$.addEventListener("error", () => setFailed(true));
943
1122
  createRenderEffect(() => setAttribute(_el$, "src", props.favicon));
944
1123
  return _el$;
@@ -961,13 +1140,13 @@ const TabBar = () => {
961
1140
  onCleanup(() => clearInterval(ticker));
962
1141
  const modelActiveTabIds = createMemo(() => getAgentActiveTabIds(runtimeState2(), now()));
963
1142
  return (() => {
964
- var _el$3 = _tmpl$3$6(), _el$4 = _el$3.firstChild, _el$5 = _el$4.firstChild;
1143
+ var _el$3 = _tmpl$3$7(), _el$4 = _el$3.firstChild, _el$5 = _el$4.firstChild;
965
1144
  insert(_el$4, createComponent(For, {
966
1145
  get each() {
967
1146
  return tabs2();
968
1147
  },
969
1148
  children: (tab) => (() => {
970
- var _el$6 = _tmpl$4$5(), _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
1149
+ var _el$6 = _tmpl$4$7(), _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
971
1150
  _el$6.addEventListener("auxclick", (e) => {
972
1151
  if (e.button === 1) closeTab(tab.id);
973
1152
  });
@@ -985,12 +1164,12 @@ const TabBar = () => {
985
1164
  }), _el$7);
986
1165
  insert(_el$6, (() => {
987
1166
  var _c$ = memo(() => !!modelActiveTabIds().has(tab.id));
988
- return () => _c$() && _tmpl$5$3();
1167
+ return () => _c$() && _tmpl$5$5();
989
1168
  })(), _el$7);
990
1169
  insert(_el$7, () => tab.title || "New Tab");
991
1170
  insert(_el$6, (() => {
992
1171
  var _c$2 = memo(() => !!tab.isLoading);
993
- return () => _c$2() && _tmpl$6$3();
1172
+ return () => _c$2() && _tmpl$6$5();
994
1173
  })(), _el$8);
995
1174
  _el$8.$$click = (e) => {
996
1175
  e.stopPropagation();
@@ -1094,7 +1273,7 @@ function useUI() {
1094
1273
  }
1095
1274
  };
1096
1275
  }
1097
- var _tmpl$$9 = /* @__PURE__ */ template(`<span class=nav-btn-badge>`), _tmpl$2$8 = /* @__PURE__ */ template(`<div class=address-bar><div class=nav-controls><button class=nav-btn data-tooltip=Back><svg width=14 height=14 viewBox="0 0 14 14"><path d="M9 2L4 7l5 5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=nav-btn data-tooltip=Forward><svg width=14 height=14 viewBox="0 0 14 14"><path d="M5 2l5 5-5 5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=nav-btn data-tooltip=Reload><svg width=14 height=14 viewBox="0 0 14 14"><path d="M2.5 7a4.5 4.5 0 1 1 1 3"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M2 4v3.5h3.5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button></div><div class=url-shell><form class=url-form><input class=url-input type=text placeholder="Search or enter URL"></form><div><span class=agent-status-dot aria-hidden=true></span><span class=agent-status-text></span></div></div><div class=toolbar-actions><button class=nav-btn data-tooltip="Reader Mode"><svg width=14 height=14 viewBox="0 0 14 14"><rect x=2 y=1 width=10 height=12 rx=1 fill=none stroke=currentColor stroke-width=1.2></rect><line x1=4 y1=4 x2=10 y2=4 stroke=currentColor stroke-width=1></line><line x1=4 y1=6.5 x2=10 y2=6.5 stroke=currentColor stroke-width=1></line><line x1=4 y1=9 x2=8 y2=9 stroke=currentColor stroke-width=1></line></svg></button><button class=nav-btn data-tooltip="Dev Tools"><svg width=14 height=14 viewBox="0 0 14 14"><polyline points="3,5 1,7 3,9"fill=none stroke=currentColor stroke-width=1.2 stroke-linecap=round stroke-linejoin=round></polyline><polyline points="11,5 13,7 11,9"fill=none stroke=currentColor stroke-width=1.2 stroke-linecap=round stroke-linejoin=round></polyline><line x1=8.5 y1=2 x2=5.5 y2=12 stroke=currentColor stroke-width=1.2 stroke-linecap=round></line></svg></button><button class="nav-btn nav-btn-sidebar"><svg width=14 height=14 viewBox="0 0 14 14"><rect x=1 y=1 width=12 height=12 rx=1.5 fill=none stroke=currentColor stroke-width=1.2></rect><line x1=9 y1=1 x2=9 y2=13 stroke=currentColor stroke-width=1.2></line></svg></button><button class=nav-btn data-tooltip=Settings><svg width=14 height=14 viewBox="0 0 14 14"><circle cx=7 cy=7 r=2 fill=none stroke=currentColor stroke-width=1.2></circle><path d="M7 1v2M7 11v2M1 7h2M11 7h2M2.8 2.8l1.4 1.4M9.8 9.8l1.4 1.4M11.2 2.8l-1.4 1.4M4.2 9.8l-1.4 1.4"stroke=currentColor stroke-width=1 stroke-linecap=round>`);
1276
+ var _tmpl$$a = /* @__PURE__ */ template(`<span class=nav-btn-badge>`), _tmpl$2$9 = /* @__PURE__ */ template(`<div class=address-bar><div class=nav-controls><button class=nav-btn data-tooltip=Back><svg width=14 height=14 viewBox="0 0 14 14"><path d="M9 2L4 7l5 5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=nav-btn data-tooltip=Forward><svg width=14 height=14 viewBox="0 0 14 14"><path d="M5 2l5 5-5 5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button><button class=nav-btn data-tooltip=Reload><svg width=14 height=14 viewBox="0 0 14 14"><path d="M2.5 7a4.5 4.5 0 1 1 1 3"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round></path><path d="M2 4v3.5h3.5"fill=none stroke=currentColor stroke-width=1.5 stroke-linecap=round stroke-linejoin=round></path></svg></button></div><div class=url-shell><form class=url-form><input class=url-input type=text placeholder="Search or enter URL"></form><div><span class=agent-status-dot aria-hidden=true></span><span class=agent-status-text></span></div></div><div class=toolbar-actions><button class=nav-btn data-tooltip="Reader Mode"><svg width=14 height=14 viewBox="0 0 14 14"><rect x=2 y=1 width=10 height=12 rx=1 fill=none stroke=currentColor stroke-width=1.2></rect><line x1=4 y1=4 x2=10 y2=4 stroke=currentColor stroke-width=1></line><line x1=4 y1=6.5 x2=10 y2=6.5 stroke=currentColor stroke-width=1></line><line x1=4 y1=9 x2=8 y2=9 stroke=currentColor stroke-width=1></line></svg></button><button class=nav-btn data-tooltip="Dev Tools"><svg width=14 height=14 viewBox="0 0 14 14"><polyline points="3,5 1,7 3,9"fill=none stroke=currentColor stroke-width=1.2 stroke-linecap=round stroke-linejoin=round></polyline><polyline points="11,5 13,7 11,9"fill=none stroke=currentColor stroke-width=1.2 stroke-linecap=round stroke-linejoin=round></polyline><line x1=8.5 y1=2 x2=5.5 y2=12 stroke=currentColor stroke-width=1.2 stroke-linecap=round></line></svg></button><button class="nav-btn nav-btn-sidebar"><svg width=14 height=14 viewBox="0 0 14 14"><rect x=1 y=1 width=12 height=12 rx=1.5 fill=none stroke=currentColor stroke-width=1.2></rect><line x1=9 y1=1 x2=9 y2=13 stroke=currentColor stroke-width=1.2></line></svg></button><button class=nav-btn data-tooltip=Settings><svg width=14 height=14 viewBox="0 0 14 14"><circle cx=7 cy=7 r=2 fill=none stroke=currentColor stroke-width=1.2></circle><path d="M7 1v2M7 11v2M1 7h2M11 7h2M2.8 2.8l1.4 1.4M9.8 9.8l1.4 1.4M11.2 2.8l-1.4 1.4M4.2 9.8l-1.4 1.4"stroke=currentColor stroke-width=1 stroke-linecap=round>`);
1098
1277
  const AddressBar = () => {
1099
1278
  const {
1100
1279
  activeTab,
@@ -1135,7 +1314,7 @@ const AddressBar = () => {
1135
1314
  }
1136
1315
  };
1137
1316
  return (() => {
1138
- var _el$ = _tmpl$2$8(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$2.nextSibling, _el$7 = _el$6.firstChild, _el$8 = _el$7.firstChild, _el$9 = _el$7.nextSibling, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$6.nextSibling, _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, _el$13 = _el$12.nextSibling;
1317
+ var _el$ = _tmpl$2$9(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$4.nextSibling, _el$6 = _el$2.nextSibling, _el$7 = _el$6.firstChild, _el$8 = _el$7.firstChild, _el$9 = _el$7.nextSibling, _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$10 = _el$6.nextSibling, _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, _el$13 = _el$12.nextSibling;
1139
1318
  _el$13.firstChild;
1140
1319
  var _el$16 = _el$13.nextSibling;
1141
1320
  addEventListener(_el$3, "click", goBack);
@@ -1156,7 +1335,7 @@ const AddressBar = () => {
1156
1335
  return pendingApprovalCount() > 0;
1157
1336
  },
1158
1337
  get children() {
1159
- var _el$15 = _tmpl$$9();
1338
+ var _el$15 = _tmpl$$a();
1160
1339
  insert(_el$15, pendingApprovalCount);
1161
1340
  createRenderEffect(() => setAttribute(_el$15, "aria-label", `${pendingApprovalCount()} pending`));
1162
1341
  return _el$15;
@@ -1189,7 +1368,7 @@ const AddressBar = () => {
1189
1368
  })();
1190
1369
  };
1191
1370
  delegateEvents(["click", "input"]);
1192
- var _tmpl$$8 = /* @__PURE__ */ template(`<div class=bookmark-toast-stack aria-live=polite aria-atomic=true>`), _tmpl$2$7 = /* @__PURE__ */ template(`<div class=bookmark-toast role=status><div class=bookmark-toast-title></div><div class=bookmark-toast-message>`);
1371
+ var _tmpl$$9 = /* @__PURE__ */ template(`<div class=bookmark-toast-stack aria-live=polite aria-atomic=true>`), _tmpl$2$8 = /* @__PURE__ */ template(`<div class=bookmark-toast role=status><div class=bookmark-toast-title></div><div class=bookmark-toast-message>`);
1193
1372
  const TOAST_DURATION_MS$1 = 4200;
1194
1373
  const TOAST_EXIT_MS$1 = 300;
1195
1374
  function isBookmarkToastCandidate(action) {
@@ -1249,13 +1428,13 @@ const BookmarkNotifications = () => {
1249
1428
  timeoutIds.clear();
1250
1429
  });
1251
1430
  return (() => {
1252
- var _el$ = _tmpl$$8();
1431
+ var _el$ = _tmpl$$9();
1253
1432
  insert(_el$, createComponent(For, {
1254
1433
  get each() {
1255
1434
  return toasts();
1256
1435
  },
1257
1436
  children: (toast) => (() => {
1258
- var _el$2 = _tmpl$2$7(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
1437
+ var _el$2 = _tmpl$2$8(), _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
1259
1438
  insert(_el$3, () => toast.title);
1260
1439
  insert(_el$4, () => toast.message);
1261
1440
  createRenderEffect(() => _el$2.classList.toggle("bookmark-toast-leaving", !!toast.leaving));
@@ -1265,7 +1444,7 @@ const BookmarkNotifications = () => {
1265
1444
  return _el$;
1266
1445
  })();
1267
1446
  };
1268
- var _tmpl$$7 = /* @__PURE__ */ template(`<div class=bookmark-toast-stack aria-live=polite><div class="bookmark-toast highlight-toast"role=status><div class=bookmark-toast-title></div><div class=bookmark-toast-message>`);
1447
+ var _tmpl$$8 = /* @__PURE__ */ template(`<div class=bookmark-toast-stack aria-live=polite><div class="bookmark-toast highlight-toast"role=status><div class=bookmark-toast-title></div><div class=bookmark-toast-message>`);
1269
1448
  const TOAST_DURATION_MS = 3e3;
1270
1449
  const TOAST_EXIT_MS = 300;
1271
1450
  const HighlightNotifications = (props) => {
@@ -1304,7 +1483,7 @@ const HighlightNotifications = (props) => {
1304
1483
  return memo(() => !!visible())() && current();
1305
1484
  },
1306
1485
  get children() {
1307
- var _el$ = _tmpl$$7(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
1486
+ var _el$ = _tmpl$$8(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
1308
1487
  insert(_el$3, () => current().title);
1309
1488
  insert(_el$4, () => current().message);
1310
1489
  createRenderEffect(() => _el$2.classList.toggle("bookmark-toast-leaving", !!leaving()));
@@ -1330,7 +1509,7 @@ function useScrollFade(el) {
1330
1509
  observer.disconnect();
1331
1510
  });
1332
1511
  }
1333
- var _tmpl$$6 = /* @__PURE__ */ template(`<span class=agent-transcript-live><span class=agent-transcript-live-dot aria-hidden=true></span>Live`), _tmpl$2$6 = /* @__PURE__ */ template(`<div class=agent-transcript-list>`), _tmpl$3$5 = /* @__PURE__ */ template(`<aside class=agent-transcript-dock><div class=agent-transcript-header><div class=agent-transcript-title-row><span class=agent-transcript-title>Agent Transcript</span></div><div class=agent-transcript-actions><button class=agent-transcript-icon></button><button class=agent-transcript-icon data-tooltip=Hide>×`), _tmpl$4$4 = /* @__PURE__ */ template(`<article><div class=agent-transcript-meta><span class=agent-transcript-badge></span><span class=agent-transcript-time></span></div><div class=agent-transcript-text>`);
1512
+ var _tmpl$$7 = /* @__PURE__ */ template(`<span class=agent-transcript-live><span class=agent-transcript-live-dot aria-hidden=true></span>Live`), _tmpl$2$7 = /* @__PURE__ */ template(`<div class=agent-transcript-list>`), _tmpl$3$6 = /* @__PURE__ */ template(`<aside class=agent-transcript-dock><div class=agent-transcript-header><div class=agent-transcript-title-row><span class=agent-transcript-title>Agent Transcript</span></div><div class=agent-transcript-actions><button class=agent-transcript-icon></button><button class=agent-transcript-icon data-tooltip=Hide>×`), _tmpl$4$6 = /* @__PURE__ */ template(`<article><div class=agent-transcript-meta><span class=agent-transcript-badge></span><span class=agent-transcript-time></span></div><div class=agent-transcript-text>`);
1334
1513
  const AgentTranscriptDock = () => {
1335
1514
  const {
1336
1515
  runtimeState: runtimeState2
@@ -1365,7 +1544,7 @@ const AgentTranscriptDock = () => {
1365
1544
  return memo(() => mode() === "full")() && visibleEntries().length > 0;
1366
1545
  },
1367
1546
  get children() {
1368
- var _el$ = _tmpl$3$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild;
1547
+ var _el$ = _tmpl$3$6(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild;
1369
1548
  _el$3.firstChild;
1370
1549
  var _el$6 = _el$3.nextSibling, _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
1371
1550
  insert(_el$3, createComponent(Show, {
@@ -1373,7 +1552,7 @@ const AgentTranscriptDock = () => {
1373
1552
  return hasStreamingEntry();
1374
1553
  },
1375
1554
  get children() {
1376
- return _tmpl$$6();
1555
+ return _tmpl$$7();
1377
1556
  }
1378
1557
  }), null);
1379
1558
  _el$7.$$click = () => setCollapsed((value) => !value);
@@ -1384,14 +1563,14 @@ const AgentTranscriptDock = () => {
1384
1563
  return !collapsed();
1385
1564
  },
1386
1565
  get children() {
1387
- var _el$9 = _tmpl$2$6();
1566
+ var _el$9 = _tmpl$2$7();
1388
1567
  use((el) => useScrollFade(el), _el$9);
1389
1568
  insert(_el$9, createComponent(For, {
1390
1569
  get each() {
1391
1570
  return visibleEntries();
1392
1571
  },
1393
1572
  children: (entry) => (() => {
1394
- var _el$0 = _tmpl$4$4(), _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$1.nextSibling;
1573
+ var _el$0 = _tmpl$4$6(), _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$1.nextSibling;
1395
1574
  insert(_el$10, () => entry.title || entry.kind);
1396
1575
  insert(_el$11, () => formatTime2(entry.updatedAt));
1397
1576
  insert(_el$12, () => entry.text);
@@ -1486,12 +1665,13 @@ function useAI() {
1486
1665
  clearHistory: () => setMessages([])
1487
1666
  };
1488
1667
  }
1489
- var _tmpl$$5 = /* @__PURE__ */ template(`<div class=command-bar-recent><span class=command-bar-recent-label>Recent</span><div class=command-bar-recent-list>`), _tmpl$2$5 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=command-bar><form><div class=command-bar-icon><svg width=16 height=16 viewBox="0 0 16 16"><circle cx=8 cy=8 r=6 fill=none stroke=var(--accent-primary) stroke-width=1.5></circle><circle cx=6 cy=7 r=0.8 fill=var(--accent-primary)></circle><circle cx=10 cy=7 r=0.8 fill=var(--accent-primary)></circle><path d="M6 10c0.5 0.8 3.5 0.8 4 0"fill=none stroke=var(--accent-primary) stroke-width=0.8 stroke-linecap=round></path></svg></div><input class=command-bar-input type=text placeholder="Ask about this page, summarize, or search..."></form><div class=command-bar-hints><span><kbd>Enter</kbd> to ask</span><span><kbd>Esc</kbd> to close</span><span>Try "summarize" or ask a question`), _tmpl$3$4 = /* @__PURE__ */ template(`<button class=command-bar-recent-item type=button>`);
1668
+ var _tmpl$$6 = /* @__PURE__ */ template(`<div class=command-bar-no-provider><p>Configure a chat provider to start using the AI assistant.</p><button class=command-bar-no-provider-btn>Open Settings <kbd>Ctrl+,`), _tmpl$2$6 = /* @__PURE__ */ template(`<div class=command-bar-recent><span class=command-bar-recent-label>Recent</span><div class=command-bar-recent-list>`), _tmpl$3$5 = /* @__PURE__ */ template(`<span>Try "summarize" or ask a question`), _tmpl$4$5 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=command-bar><form><div class=command-bar-icon><svg width=16 height=16 viewBox="0 0 16 16"><circle cx=8 cy=8 r=6 fill=none stroke=var(--accent-primary) stroke-width=1.5></circle><circle cx=6 cy=7 r=0.8 fill=var(--accent-primary)></circle><circle cx=10 cy=7 r=0.8 fill=var(--accent-primary)></circle><path d="M6 10c0.5 0.8 3.5 0.8 4 0"fill=none stroke=var(--accent-primary) stroke-width=0.8 stroke-linecap=round></path></svg></div><input class=command-bar-input type=text></form><div class=command-bar-hints><span><kbd>Enter</kbd> to ask</span><span><kbd>Esc</kbd> to close`), _tmpl$5$4 = /* @__PURE__ */ template(`<button class=command-bar-recent-item type=button>`), _tmpl$6$4 = /* @__PURE__ */ template(`<span>Set up a provider in Settings first`);
1490
1669
  const CommandBar = () => {
1491
1670
  const {
1492
1671
  commandBarOpen: commandBarOpen2,
1493
1672
  closeCommandBar,
1494
- toggleSidebar
1673
+ toggleSidebar,
1674
+ openSettings
1495
1675
  } = useUI();
1496
1676
  const {
1497
1677
  query,
@@ -1500,6 +1680,8 @@ const CommandBar = () => {
1500
1680
  cancel
1501
1681
  } = useAI();
1502
1682
  const [input, setInput] = createSignal("");
1683
+ const [settings] = createResource(() => commandBarOpen2(), async (open) => open ? window.vessel.settings.get() : null);
1684
+ const hasProvider = () => settings()?.chatProvider !== null && settings()?.chatProvider !== void 0;
1503
1685
  const handleSubmit = async (e) => {
1504
1686
  e.preventDefault();
1505
1687
  const val = input().trim();
@@ -1531,7 +1713,8 @@ const CommandBar = () => {
1531
1713
  return commandBarOpen2();
1532
1714
  },
1533
1715
  get children() {
1534
- var _el$ = _tmpl$2$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$9 = _el$3.nextSibling;
1716
+ var _el$ = _tmpl$4$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$10 = _el$3.nextSibling, _el$11 = _el$10.firstChild;
1717
+ _el$11.nextSibling;
1535
1718
  addEventListener(_el$, "click", closeCommandBar);
1536
1719
  _el$2.$$click = (e) => e.stopPropagation();
1537
1720
  _el$3.addEventListener("submit", handleSubmit);
@@ -1541,24 +1724,57 @@ const CommandBar = () => {
1541
1724
  setAttribute(_el$5, "spellcheck", false);
1542
1725
  insert(_el$2, createComponent(Show, {
1543
1726
  get when() {
1544
- return memo(() => recentQueries2().length > 0)() && !input().trim();
1727
+ return !hasProvider();
1545
1728
  },
1546
1729
  get children() {
1547
- var _el$6 = _tmpl$$5(), _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
1548
- insert(_el$8, createComponent(For, {
1730
+ var _el$6 = _tmpl$$6(), _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling;
1731
+ _el$8.$$click = () => {
1732
+ closeCommandBar();
1733
+ openSettings();
1734
+ };
1735
+ return _el$6;
1736
+ }
1737
+ }), _el$10);
1738
+ insert(_el$2, createComponent(Show, {
1739
+ get when() {
1740
+ return memo(() => !!(hasProvider() && recentQueries2().length > 0))() && !input().trim();
1741
+ },
1742
+ get children() {
1743
+ var _el$9 = _tmpl$2$6(), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling;
1744
+ insert(_el$1, createComponent(For, {
1549
1745
  get each() {
1550
1746
  return recentQueries2();
1551
1747
  },
1552
1748
  children: (q) => (() => {
1553
- var _el$0 = _tmpl$3$4();
1554
- _el$0.$$click = () => void handleRecentClick(q);
1555
- insert(_el$0, q);
1556
- return _el$0;
1749
+ var _el$14 = _tmpl$5$4();
1750
+ _el$14.$$click = () => void handleRecentClick(q);
1751
+ insert(_el$14, q);
1752
+ return _el$14;
1557
1753
  })()
1558
1754
  }));
1559
- return _el$6;
1755
+ return _el$9;
1560
1756
  }
1561
- }), _el$9);
1757
+ }), _el$10);
1758
+ insert(_el$10, createComponent(Show, {
1759
+ get when() {
1760
+ return hasProvider();
1761
+ },
1762
+ get fallback() {
1763
+ return _tmpl$6$4();
1764
+ },
1765
+ get children() {
1766
+ return _tmpl$3$5();
1767
+ }
1768
+ }), null);
1769
+ createRenderEffect((_p$) => {
1770
+ var _v$ = hasProvider() ? "Ask about this page, summarize, or search..." : "No chat provider configured", _v$2 = !hasProvider();
1771
+ _v$ !== _p$.e && setAttribute(_el$5, "placeholder", _p$.e = _v$);
1772
+ _v$2 !== _p$.t && (_el$5.disabled = _p$.t = _v$2);
1773
+ return _p$;
1774
+ }, {
1775
+ e: void 0,
1776
+ t: void 0
1777
+ });
1562
1778
  createRenderEffect(() => _el$5.value = input());
1563
1779
  return _el$;
1564
1780
  }
@@ -3070,7 +3286,7 @@ function getBookmarkSearchMatch(args) {
3070
3286
  }
3071
3287
  return { matchedFields, score };
3072
3288
  }
3073
- var _tmpl$$4 = /* @__PURE__ */ template(`<div class=dropdown-select-menu role=listbox>`), _tmpl$2$4 = /* @__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$3$3 = /* @__PURE__ */ template(`<span class=dropdown-select-option-description>`), _tmpl$4$3 = /* @__PURE__ */ template(`<button class=dropdown-select-option type=button role=option><span class=dropdown-select-option-copy><span class=dropdown-select-option-label>`);
3289
+ var _tmpl$$5 = /* @__PURE__ */ template(`<div class=dropdown-select-menu role=listbox>`), _tmpl$2$5 = /* @__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$3$4 = /* @__PURE__ */ template(`<span class=dropdown-select-option-description>`), _tmpl$4$4 = /* @__PURE__ */ template(`<button class=dropdown-select-option type=button role=option><span class=dropdown-select-option-copy><span class=dropdown-select-option-label>`);
3074
3290
  const DropdownSelect = (props) => {
3075
3291
  const [open, setOpen] = createSignal(false);
3076
3292
  let rootRef;
@@ -3094,7 +3310,7 @@ const DropdownSelect = (props) => {
3094
3310
  });
3095
3311
  });
3096
3312
  return (() => {
3097
- var _el$ = _tmpl$2$4(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
3313
+ var _el$ = _tmpl$2$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling;
3098
3314
  var _ref$ = rootRef;
3099
3315
  typeof _ref$ === "function" ? use(_ref$, _el$) : rootRef = _el$;
3100
3316
  _el$2.$$click = () => setOpen((current) => !current);
@@ -3104,13 +3320,13 @@ const DropdownSelect = (props) => {
3104
3320
  return open();
3105
3321
  },
3106
3322
  get children() {
3107
- var _el$5 = _tmpl$$4();
3323
+ var _el$5 = _tmpl$$5();
3108
3324
  insert(_el$5, createComponent(For, {
3109
3325
  get each() {
3110
3326
  return props.options;
3111
3327
  },
3112
3328
  children: (option) => (() => {
3113
- var _el$6 = _tmpl$4$3(), _el$7 = _el$6.firstChild, _el$8 = _el$7.firstChild;
3329
+ var _el$6 = _tmpl$4$4(), _el$7 = _el$6.firstChild, _el$8 = _el$7.firstChild;
3114
3330
  _el$6.$$click = () => {
3115
3331
  props.onChange(option.value);
3116
3332
  setOpen(false);
@@ -3121,7 +3337,7 @@ const DropdownSelect = (props) => {
3121
3337
  return option.description;
3122
3338
  },
3123
3339
  get children() {
3124
- var _el$9 = _tmpl$3$3();
3340
+ var _el$9 = _tmpl$3$4();
3125
3341
  insert(_el$9, () => option.description);
3126
3342
  return _el$9;
3127
3343
  }
@@ -3159,7 +3375,7 @@ const DropdownSelect = (props) => {
3159
3375
  };
3160
3376
  delegateEvents(["click"]);
3161
3377
  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`);
3378
+ var _tmpl$$4 = /* @__PURE__ */ template(`<div class="message-content markdown-content">`), _tmpl$2$4 = /* @__PURE__ */ template(`<span class=sidebar-tab-badge>`), _tmpl$3$3 = /* @__PURE__ */ template(`<div class=agent-section-title>Pending approvals`), _tmpl$4$3 = /* @__PURE__ */ template(`<button class=agent-section-toggle type=button>`), _tmpl$5$3 = /* @__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$3 = /* @__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$1 = /* @__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$1 = /* @__PURE__ */ template(`<div class=agent-muted>No actions yet.`), _tmpl$22$1 = /* @__PURE__ */ template(`<div class=agent-muted>Recent actions are collapsed to reduce noise.`), _tmpl$23$1 = /* @__PURE__ */ template(`<div class="agent-card-copy success">`), _tmpl$24$1 = /* @__PURE__ */ template(`<div class="agent-card-copy error">`), _tmpl$25$1 = /* @__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$1 = /* @__PURE__ */ template(`<div class=bookmark-empty-folder>`), _tmpl$27$1 = /* @__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
3379
  const UNSORTED_FOLDER = {
3164
3380
  id: "unsorted",
3165
3381
  name: "Unsorted",
@@ -3168,7 +3384,7 @@ const UNSORTED_FOLDER = {
3168
3384
  const MarkdownMessage = (props) => {
3169
3385
  const html2 = createMemo(() => renderMarkdown(props.content));
3170
3386
  return (() => {
3171
- var _el$ = _tmpl$$3();
3387
+ var _el$ = _tmpl$$4();
3172
3388
  createRenderEffect(() => _el$.innerHTML = html2());
3173
3389
  return _el$;
3174
3390
  })();
@@ -3317,7 +3533,7 @@ ${contextBlock}` : contextBlock);
3317
3533
  const [editingFolderSummary, setEditingFolderSummary] = createSignal("");
3318
3534
  const [expandedFolderIds, setExpandedFolderIds] = createSignal([UNSORTED_FOLDER.id]);
3319
3535
  const [actionsExpanded, setActionsExpanded] = createSignal(false);
3320
- createSignal(false);
3536
+ const [checkpointsExpanded, setCheckpointsExpanded] = createSignal(false);
3321
3537
  const [isDragging, setIsDragging] = createSignal(false);
3322
3538
  const [elapsedSeconds, setElapsedSeconds] = createSignal(0);
3323
3539
  let messagesContainerRef;
@@ -3498,7 +3714,7 @@ ${contextBlock}` : contextBlock);
3498
3714
  return props.forceOpen || sidebarOpen2();
3499
3715
  },
3500
3716
  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;
3717
+ 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
3718
  _el$1.firstChild;
3503
3719
  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
3720
  _el$3.$$pointerdown = startResize;
@@ -3511,7 +3727,7 @@ ${contextBlock}` : contextBlock);
3511
3727
  return runtimeState2().supervisor.pendingApprovals.length > 0;
3512
3728
  },
3513
3729
  get children() {
3514
- var _el$11 = _tmpl$2$3();
3730
+ var _el$11 = _tmpl$2$4();
3515
3731
  insert(_el$11, () => runtimeState2().supervisor.pendingApprovals.length);
3516
3732
  return _el$11;
3517
3733
  }
@@ -3528,7 +3744,7 @@ ${contextBlock}` : contextBlock);
3528
3744
  return sidebarTab() === "supervisor";
3529
3745
  },
3530
3746
  get children() {
3531
- var _el$16 = _tmpl$5$2(), _el$17 = _el$16.firstChild, _el$18 = _el$17.firstChild, _el$19 = _el$18.firstChild, _el$20 = _el$19.nextSibling, _el$21 = _el$18.nextSibling, _el$22 = _el$17.nextSibling, _el$23 = _el$22.firstChild, _el$24 = _el$23.nextSibling, _el$25 = _el$22.nextSibling, _el$27 = _el$25.nextSibling;
3747
+ var _el$16 = _tmpl$5$3(), _el$17 = _el$16.firstChild, _el$18 = _el$17.firstChild, _el$19 = _el$18.firstChild, _el$20 = _el$19.nextSibling, _el$21 = _el$18.nextSibling, _el$22 = _el$17.nextSibling, _el$23 = _el$22.firstChild, _el$24 = _el$23.nextSibling, _el$25 = _el$22.nextSibling, _el$27 = _el$25.nextSibling;
3532
3748
  _el$27.firstChild;
3533
3749
  insert(_el$20, () => runtimeState2().supervisor.paused ? "Agent is paused" : "Agent is live");
3534
3750
  insert(_el$21, () => runtimeState2().supervisor.paused ? "Paused" : "Running");
@@ -3552,15 +3768,15 @@ ${contextBlock}` : contextBlock);
3552
3768
  return runtimeState2().supervisor.pendingApprovals.length > 0;
3553
3769
  },
3554
3770
  get fallback() {
3555
- return _tmpl$19();
3771
+ return _tmpl$19$1();
3556
3772
  },
3557
3773
  get children() {
3558
- return [_tmpl$3$2(), createComponent(For, {
3774
+ return [_tmpl$3$3(), createComponent(For, {
3559
3775
  get each() {
3560
3776
  return runtimeState2().supervisor.pendingApprovals;
3561
3777
  },
3562
3778
  children: (approval) => (() => {
3563
- var _el$85 = _tmpl$20(), _el$86 = _el$85.firstChild, _el$87 = _el$86.nextSibling, _el$88 = _el$87.nextSibling, _el$89 = _el$88.nextSibling, _el$90 = _el$89.nextSibling, _el$91 = _el$90.firstChild, _el$92 = _el$91.nextSibling;
3779
+ var _el$85 = _tmpl$20$1(), _el$86 = _el$85.firstChild, _el$87 = _el$86.nextSibling, _el$88 = _el$87.nextSibling, _el$89 = _el$88.nextSibling, _el$90 = _el$89.nextSibling, _el$91 = _el$90.firstChild, _el$92 = _el$91.nextSibling;
3564
3780
  insert(_el$87, () => approval.name);
3565
3781
  insert(_el$88, () => approval.argsSummary);
3566
3782
  insert(_el$89, () => approval.reason);
@@ -3576,7 +3792,7 @@ ${contextBlock}` : contextBlock);
3576
3792
  return recentActions().length > 0;
3577
3793
  },
3578
3794
  get children() {
3579
- var _el$29 = _tmpl$4$2();
3795
+ var _el$29 = _tmpl$4$3();
3580
3796
  _el$29.$$click = () => setActionsExpanded((current) => !current);
3581
3797
  insert(_el$29, (() => {
3582
3798
  var _c$ = memo(() => !!actionsExpanded());
@@ -3590,7 +3806,7 @@ ${contextBlock}` : contextBlock);
3590
3806
  return recentActions().length > 0;
3591
3807
  },
3592
3808
  get fallback() {
3593
- return _tmpl$21();
3809
+ return _tmpl$21$1();
3594
3810
  },
3595
3811
  get children() {
3596
3812
  return createComponent(Show, {
@@ -3598,7 +3814,7 @@ ${contextBlock}` : contextBlock);
3598
3814
  return actionsExpanded();
3599
3815
  },
3600
3816
  get fallback() {
3601
- return _tmpl$22();
3817
+ return _tmpl$22$1();
3602
3818
  },
3603
3819
  get children() {
3604
3820
  return createComponent(For, {
@@ -3606,7 +3822,7 @@ ${contextBlock}` : contextBlock);
3606
3822
  return recentActions();
3607
3823
  },
3608
3824
  children: (action) => (() => {
3609
- var _el$95 = _tmpl$25(), _el$96 = _el$95.firstChild, _el$97 = _el$96.firstChild, _el$98 = _el$97.nextSibling, _el$99 = _el$96.nextSibling;
3825
+ var _el$95 = _tmpl$25$1(), _el$96 = _el$95.firstChild, _el$97 = _el$96.firstChild, _el$98 = _el$97.nextSibling, _el$99 = _el$96.nextSibling;
3610
3826
  insert(_el$97, () => action.name);
3611
3827
  insert(_el$98, () => action.status);
3612
3828
  insert(_el$99, () => action.argsSummary);
@@ -3615,7 +3831,7 @@ ${contextBlock}` : contextBlock);
3615
3831
  return action.resultSummary;
3616
3832
  },
3617
3833
  get children() {
3618
- var _el$100 = _tmpl$23();
3834
+ var _el$100 = _tmpl$23$1();
3619
3835
  insert(_el$100, () => action.resultSummary);
3620
3836
  return _el$100;
3621
3837
  }
@@ -3625,7 +3841,7 @@ ${contextBlock}` : contextBlock);
3625
3841
  return action.error;
3626
3842
  },
3627
3843
  get children() {
3628
- var _el$101 = _tmpl$24();
3844
+ var _el$101 = _tmpl$24$1();
3629
3845
  insert(_el$101, () => action.error);
3630
3846
  return _el$101;
3631
3847
  }
@@ -3657,7 +3873,7 @@ ${contextBlock}` : contextBlock);
3657
3873
  return currentTabSaved();
3658
3874
  },
3659
3875
  get children() {
3660
- return _tmpl$6$2();
3876
+ return _tmpl$6$3();
3661
3877
  }
3662
3878
  }), null);
3663
3879
  _el$36.$$input = (e) => setBookmarkSearchQuery(e.currentTarget.value);
@@ -3697,7 +3913,7 @@ ${contextBlock}` : contextBlock);
3697
3913
  },
3698
3914
  get fallback() {
3699
3915
  return (() => {
3700
- var _el$102 = _tmpl$26();
3916
+ var _el$102 = _tmpl$26$1();
3701
3917
  insert(_el$102, (() => {
3702
3918
  var _c$5 = memo(() => !!normalizedBookmarkSearch());
3703
3919
  return () => _c$5() ? `No bookmarks matched "${bookmarkSearchQuery().trim()}".` : "No bookmarks saved yet.";
@@ -3726,7 +3942,7 @@ ${contextBlock}` : contextBlock);
3726
3942
  return folder.summary;
3727
3943
  },
3728
3944
  get children() {
3729
- var _el$111 = _tmpl$27();
3945
+ var _el$111 = _tmpl$27$1();
3730
3946
  insert(_el$111, () => folder.summary);
3731
3947
  return _el$111;
3732
3948
  }
@@ -3998,7 +4214,7 @@ ${contextBlock}` : contextBlock);
3998
4214
  return isStreaming2() || messages2().length > 0;
3999
4215
  },
4000
4216
  get children() {
4001
- var _el$73 = _tmpl$15();
4217
+ var _el$73 = _tmpl$15$1();
4002
4218
  insert(_el$73, createComponent(Show, {
4003
4219
  get when() {
4004
4220
  return isStreaming2();
@@ -4026,7 +4242,7 @@ ${contextBlock}` : contextBlock);
4026
4242
  return highlightCount() > 0;
4027
4243
  },
4028
4244
  get children() {
4029
- var _el$76 = _tmpl$16(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
4245
+ var _el$76 = _tmpl$16$1(), _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
4030
4246
  _el$78.firstChild;
4031
4247
  var _el$80 = _el$78.nextSibling;
4032
4248
  _el$77.$$click = () => void scrollToHighlight(highlightIndex() - 1);
@@ -4048,7 +4264,7 @@ ${contextBlock}` : contextBlock);
4048
4264
  return _el$76;
4049
4265
  }
4050
4266
  }), (() => {
4051
- var _el$81 = _tmpl$17(), _el$82 = _el$81.firstChild, _el$83 = _el$82.nextSibling;
4267
+ var _el$81 = _tmpl$17$1(), _el$82 = _el$81.firstChild, _el$83 = _el$82.nextSibling;
4052
4268
  _el$82.$$keydown = (e) => {
4053
4269
  if (e.key === "Enter" && !e.shiftKey) {
4054
4270
  e.preventDefault();
@@ -4095,7 +4311,7 @@ ${contextBlock}` : contextBlock);
4095
4311
  });
4096
4312
  };
4097
4313
  delegateEvents(["pointerdown", "click", "input", "keydown"]);
4098
- var _tmpl$$2 = /* @__PURE__ */ template(`<div class=devtools-console>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for console output... Console monitoring activates when an agent uses devtools.`), _tmpl$3$1 = /* @__PURE__ */ template(`<div><span></span><span class=console-time></span><span class=console-text></span><span class=console-source>`), _tmpl$4$1 = /* @__PURE__ */ template(`<div class=devtools-network><div class=network-header><span>Method</span><span>URL</span><span>Status</span><span>Type</span><span>Time`), _tmpl$5$1 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for network requests... Network monitoring activates when an agent uses devtools.`), _tmpl$6$1 = /* @__PURE__ */ template(`<div><span class=network-method></span><span class=network-url></span><span></span><span class=network-type></span><span class=network-duration>`), _tmpl$7$1 = /* @__PURE__ */ template(`<div class=devtools-activity>`), _tmpl$8$1 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for agent devtools activity...`), _tmpl$9$1 = /* @__PURE__ */ template(`<div class=activity-entry><span class=activity-time></span><span class=activity-tool></span><span class=activity-args></span><span></span><span class=activity-duration>`), _tmpl$0$1 = /* @__PURE__ */ template(`<span class="devtools-tab-badge error">`), _tmpl$1$1 = /* @__PURE__ */ template(`<span class="devtools-tab-badge count">`), _tmpl$10$1 = /* @__PURE__ */ template(`<div class=export-date-inputs><div class=export-date-row><span class=export-date-label>From</span><input class=export-date-input type=date></div><div class=export-date-row><span class=export-date-label>To</span><input class=export-date-input type=date>`), _tmpl$11$1 = /* @__PURE__ */ template(`<div class=devtools-export-dropdown><div class=export-section><div class=export-section-label>Log Types</div><label class=export-checkbox><input type=checkbox>Console</label><label class=export-checkbox><input type=checkbox>Network</label><label class=export-checkbox><input type=checkbox>Activity</label></div><div class=export-section><div class=export-section-label>Date Range</div><div class=export-date-btns><button>Today</button><button>Custom</button></div></div><button class=export-submit>Export JSON`), _tmpl$12$1 = /* @__PURE__ */ template(`<div class=devtools-panel><div class=devtools-tabs><button>Console</button><button>Network</button><button>Activity</button><div class=devtools-tab-spacer></div><div class=devtools-export-wrap><button title="Export Logs"><svg width=13 height=13 viewBox="0 0 13 13"fill=none style=vertical-align:middle><path d="M6.5 1v7M3.5 5l3 3 3-3"stroke=currentColor stroke-width=1.3 stroke-linecap=round stroke-linejoin=round></path><path d="M1 9.5v1A1.5 1.5 0 0 0 2.5 12h8A1.5 1.5 0 0 0 12 10.5v-1"stroke=currentColor stroke-width=1.3 stroke-linecap=round></path></svg></button></div><button class=devtools-close-btn title="Close DevTools">×</button></div><div class=devtools-content>`);
4314
+ var _tmpl$$3 = /* @__PURE__ */ template(`<div class=devtools-console>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for console output... Console monitoring activates when an agent uses devtools.`), _tmpl$3$2 = /* @__PURE__ */ template(`<div><span></span><span class=console-time></span><span class=console-text></span><span class=console-source>`), _tmpl$4$2 = /* @__PURE__ */ template(`<div class=devtools-network><div class=network-header><span>Method</span><span>URL</span><span>Status</span><span>Type</span><span>Time`), _tmpl$5$2 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for network requests... Network monitoring activates when an agent uses devtools.`), _tmpl$6$2 = /* @__PURE__ */ template(`<div><span class=network-method></span><span class=network-url></span><span></span><span class=network-type></span><span class=network-duration>`), _tmpl$7$1 = /* @__PURE__ */ template(`<div class=devtools-activity>`), _tmpl$8$1 = /* @__PURE__ */ template(`<div class=devtools-empty>Waiting for agent devtools activity...`), _tmpl$9$1 = /* @__PURE__ */ template(`<div class=activity-entry><span class=activity-time></span><span class=activity-tool></span><span class=activity-args></span><span></span><span class=activity-duration>`), _tmpl$0$1 = /* @__PURE__ */ template(`<span class="devtools-tab-badge error">`), _tmpl$1$1 = /* @__PURE__ */ template(`<span class="devtools-tab-badge count">`), _tmpl$10$1 = /* @__PURE__ */ template(`<div class=export-date-inputs><div class=export-date-row><span class=export-date-label>From</span><input class=export-date-input type=date></div><div class=export-date-row><span class=export-date-label>To</span><input class=export-date-input type=date>`), _tmpl$11$1 = /* @__PURE__ */ template(`<div class=devtools-export-dropdown><div class=export-section><div class=export-section-label>Log Types</div><label class=export-checkbox><input type=checkbox>Console</label><label class=export-checkbox><input type=checkbox>Network</label><label class=export-checkbox><input type=checkbox>Activity</label></div><div class=export-section><div class=export-section-label>Date Range</div><div class=export-date-btns><button>Today</button><button>Custom</button></div></div><button class=export-submit>Export JSON`), _tmpl$12$1 = /* @__PURE__ */ template(`<div class=devtools-panel><div class=devtools-tabs><button>Console</button><button>Network</button><button>Activity</button><div class=devtools-tab-spacer></div><div class=devtools-export-wrap><button title="Export Logs"><svg width=13 height=13 viewBox="0 0 13 13"fill=none style=vertical-align:middle><path d="M6.5 1v7M3.5 5l3 3 3-3"stroke=currentColor stroke-width=1.3 stroke-linecap=round stroke-linejoin=round></path><path d="M1 9.5v1A1.5 1.5 0 0 0 2.5 12h8A1.5 1.5 0 0 0 12 10.5v-1"stroke=currentColor stroke-width=1.3 stroke-linecap=round></path></svg></button></div><button class=devtools-close-btn title="Close DevTools">×</button></div><div class=devtools-content>`);
4099
4315
  function formatTime(iso) {
4100
4316
  try {
4101
4317
  const d = new Date(iso);
@@ -4168,10 +4384,10 @@ const ConsoleView = (props) => {
4168
4384
  return props.entries.length > 0;
4169
4385
  },
4170
4386
  get fallback() {
4171
- return _tmpl$2$2();
4387
+ return _tmpl$2$3();
4172
4388
  },
4173
4389
  get children() {
4174
- var _el$ = _tmpl$$2();
4390
+ var _el$ = _tmpl$$3();
4175
4391
  _el$.addEventListener("scroll", onScroll);
4176
4392
  var _ref$ = scrollRef;
4177
4393
  typeof _ref$ === "function" ? use(_ref$, _el$) : scrollRef = _el$;
@@ -4180,7 +4396,7 @@ const ConsoleView = (props) => {
4180
4396
  return props.entries;
4181
4397
  },
4182
4398
  children: (entry) => (() => {
4183
- var _el$3 = _tmpl$3$1(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling, _el$7 = _el$6.nextSibling;
4399
+ var _el$3 = _tmpl$3$2(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$5.nextSibling, _el$7 = _el$6.nextSibling;
4184
4400
  insert(_el$4, () => entry.level);
4185
4401
  insert(_el$5, () => formatTime(entry.timestamp));
4186
4402
  insert(_el$6, () => entry.text);
@@ -4222,10 +4438,10 @@ const NetworkView = (props) => {
4222
4438
  return props.entries.length > 0;
4223
4439
  },
4224
4440
  get fallback() {
4225
- return _tmpl$5$1();
4441
+ return _tmpl$5$2();
4226
4442
  },
4227
4443
  get children() {
4228
- var _el$8 = _tmpl$4$1();
4444
+ var _el$8 = _tmpl$4$2();
4229
4445
  _el$8.firstChild;
4230
4446
  _el$8.addEventListener("scroll", onScroll);
4231
4447
  var _ref$2 = scrollRef;
@@ -4235,7 +4451,7 @@ const NetworkView = (props) => {
4235
4451
  return props.entries;
4236
4452
  },
4237
4453
  children: (entry) => (() => {
4238
- var _el$1 = _tmpl$6$1(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.nextSibling, _el$13 = _el$12.nextSibling, _el$14 = _el$13.nextSibling;
4454
+ var _el$1 = _tmpl$6$2(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling, _el$12 = _el$11.nextSibling, _el$13 = _el$12.nextSibling, _el$14 = _el$13.nextSibling;
4239
4455
  insert(_el$10, () => entry.method);
4240
4456
  insert(_el$11, () => shortenUrl(entry.url));
4241
4457
  insert(_el$12, (() => {
@@ -4542,7 +4758,7 @@ const DevToolsPanel = () => {
4542
4758
  })();
4543
4759
  };
4544
4760
  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>
4761
+ var _tmpl$$2 = /* @__PURE__ */ template(`<div class=welcome-banner><div class=welcome-banner-header><span class=welcome-banner-title>Welcome to Vessel</span><button class=welcome-banner-dismiss>&times;</button></div><p class=welcome-banner-text>Get started in three steps:</p><ol class=welcome-banner-steps><li><strong>Configure a chat provider</strong> — scroll to Chat Assistant below and add an API key</li><li><strong>Connect your agent harness</strong> — point it at the MCP endpoint shown below</li><li><strong>Learn the shortcuts</strong> — press <kbd>?</kbd> anytime for a quick reference`), _tmpl$2$2 = /* @__PURE__ */ template(`<input id=max-tool-iterations class=settings-input type=number min=10 max=1000 placeholder=200>`), _tmpl$3$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$4$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$5$1 = /* @__PURE__ */ template(`<select id=chat-model class="settings-input settings-select"style=flex:1>`), _tmpl$6$1 = /* @__PURE__ */ template(`<p class=settings-hint style=color:var(--error)>Could not fetch models — check your API key and connection.`), _tmpl$7 = /* @__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$8 = /* @__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$9 = /* @__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$0 = /* @__PURE__ */ template(`<span class=vault-premium-badge>Premium`), _tmpl$1 = /* @__PURE__ */ template(`<p class=settings-hint style=margin-bottom:10px>Store credentials for agent-driven logins. Credentials are encrypted at rest and never sent to AI providers — they are filled directly into login forms with your consent.`), _tmpl$10 = /* @__PURE__ */ template(`<div class=vault-entries>`), _tmpl$11 = /* @__PURE__ */ template(`<button class=vault-add-btn>+ Add Credential`), _tmpl$12 = /* @__PURE__ */ template(`<div class=vault-add-form><input class=settings-input placeholder="Label (e.g. Work GitHub)"><input class=settings-input placeholder="Domain pattern (e.g. github.com, *.aws.amazon.com)"><input class=settings-input placeholder="Username / email"><input class=settings-input type=password placeholder=Password><input class=settings-input placeholder="TOTP secret (optional, base32)"><input class=settings-input placeholder="Notes (optional)"><div class=vault-add-actions><button class="premium-btn premium-btn-activate">Save Credential</button><button class="premium-btn premium-btn-reset">Cancel`), _tmpl$13 = /* @__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-label>Agent Credential Vault</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$14 = /* @__PURE__ */ template(`<style>
4546
4762
  .settings-panel {
4547
4763
  width: min(440px, calc(100vw - 32px));
4548
4764
  max-height: calc(100vh - 48px);
@@ -4767,7 +4983,284 @@ var _tmpl$$1 = /* @__PURE__ */ template(`<div class=settings-field><label class=
4767
4983
  opacity: 0.4;
4768
4984
  cursor: default;
4769
4985
  }
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>`);
4986
+
4987
+ .settings-input-disabled {
4988
+ opacity: 0.5;
4989
+ cursor: not-allowed;
4990
+ user-select: none;
4991
+ display: flex;
4992
+ align-items: center;
4993
+ }
4994
+
4995
+ /* Premium section */
4996
+ .premium-section {
4997
+ display: flex;
4998
+ flex-direction: column;
4999
+ gap: 10px;
5000
+ }
5001
+ .premium-description {
5002
+ color: var(--text-secondary);
5003
+ font-size: 12px;
5004
+ line-height: 1.5;
5005
+ margin: 0;
5006
+ }
5007
+ .premium-activate-row {
5008
+ display: flex;
5009
+ gap: 8px;
5010
+ align-items: center;
5011
+ }
5012
+ .premium-email-input {
5013
+ flex: 1;
5014
+ min-width: 0;
5015
+ }
5016
+ .premium-btn {
5017
+ height: 34px;
5018
+ padding: 0 16px;
5019
+ border-radius: var(--radius-md);
5020
+ font-size: 12px;
5021
+ font-weight: 500;
5022
+ cursor: pointer;
5023
+ border: none;
5024
+ transition:
5025
+ background var(--duration-fast) var(--ease-in-out),
5026
+ transform var(--duration-fast) var(--ease-out-expo);
5027
+ white-space: nowrap;
5028
+ }
5029
+ .premium-btn:active {
5030
+ transform: scale(0.97);
5031
+ }
5032
+ .premium-btn:disabled {
5033
+ opacity: 0.5;
5034
+ cursor: default;
5035
+ }
5036
+ .premium-btn-activate {
5037
+ background: var(--bg-tertiary);
5038
+ color: var(--text-primary);
5039
+ border: 1px solid var(--border-subtle);
5040
+ }
5041
+ .premium-btn-activate:hover:not(:disabled) {
5042
+ background: var(--border-visible);
5043
+ }
5044
+ .premium-btn-upgrade {
5045
+ background: var(--accent-primary);
5046
+ color: white;
5047
+ width: 100%;
5048
+ }
5049
+ .premium-btn-upgrade:hover {
5050
+ background: #d4b06a;
5051
+ }
5052
+ .premium-btn-manage {
5053
+ background: var(--bg-tertiary);
5054
+ color: var(--text-secondary);
5055
+ border: 1px solid var(--border-subtle);
5056
+ align-self: flex-start;
5057
+ }
5058
+ .premium-btn-manage:hover {
5059
+ background: var(--border-visible);
5060
+ color: var(--text-primary);
5061
+ }
5062
+ .premium-active-badge {
5063
+ display: inline-flex;
5064
+ align-items: center;
5065
+ gap: 6px;
5066
+ background: rgba(240, 198, 54, 0.15);
5067
+ color: #f0c636;
5068
+ font-size: 12px;
5069
+ font-weight: 600;
5070
+ padding: 4px 12px;
5071
+ border-radius: var(--radius-md);
5072
+ align-self: flex-start;
5073
+ }
5074
+ .premium-detail {
5075
+ color: var(--text-secondary);
5076
+ font-size: 12px;
5077
+ margin: 0;
5078
+ }
5079
+ .premium-actions-row {
5080
+ display: flex;
5081
+ gap: 8px;
5082
+ align-items: center;
5083
+ }
5084
+ .premium-btn-reset {
5085
+ background: transparent;
5086
+ color: var(--text-tertiary, #71717a);
5087
+ border: 1px solid var(--border-subtle);
5088
+ font-size: 11px;
5089
+ padding: 0 12px;
5090
+ height: 30px;
5091
+ }
5092
+ .premium-btn-reset:hover {
5093
+ color: var(--text-secondary);
5094
+ background: var(--bg-tertiary);
5095
+ }
5096
+
5097
+ /* Welcome banner */
5098
+ .welcome-banner {
5099
+ margin-bottom: 20px;
5100
+ padding: 16px;
5101
+ border-radius: var(--radius-md);
5102
+ border: 1px solid rgba(196, 160, 90, 0.25);
5103
+ background: rgba(196, 160, 90, 0.08);
5104
+ }
5105
+ .welcome-banner-header {
5106
+ display: flex;
5107
+ justify-content: space-between;
5108
+ align-items: center;
5109
+ margin-bottom: 8px;
5110
+ }
5111
+ .welcome-banner-title {
5112
+ font-size: 13px;
5113
+ font-weight: 600;
5114
+ color: var(--accent-primary);
5115
+ }
5116
+ .welcome-banner-dismiss {
5117
+ width: 22px;
5118
+ height: 22px;
5119
+ border-radius: 4px;
5120
+ background: transparent;
5121
+ border: none;
5122
+ color: var(--text-muted);
5123
+ font-size: 16px;
5124
+ cursor: pointer;
5125
+ display: flex;
5126
+ align-items: center;
5127
+ justify-content: center;
5128
+ }
5129
+ .welcome-banner-dismiss:hover {
5130
+ background: rgba(255, 255, 255, 0.08);
5131
+ color: var(--text-primary);
5132
+ }
5133
+ .welcome-banner-text {
5134
+ font-size: 12px;
5135
+ color: var(--text-secondary);
5136
+ margin: 0 0 8px;
5137
+ }
5138
+ .welcome-banner-steps {
5139
+ margin: 0;
5140
+ padding-left: 20px;
5141
+ font-size: 12px;
5142
+ line-height: 1.7;
5143
+ color: var(--text-secondary);
5144
+ }
5145
+ .welcome-banner-steps li {
5146
+ margin-bottom: 2px;
5147
+ }
5148
+ .welcome-banner-steps li.done {
5149
+ color: var(--text-muted);
5150
+ text-decoration: line-through;
5151
+ opacity: 0.6;
5152
+ }
5153
+ .welcome-banner-steps kbd {
5154
+ display: inline-block;
5155
+ padding: 0 5px;
5156
+ font-size: 11px;
5157
+ font-family: var(--font-mono);
5158
+ background: rgba(255, 255, 255, 0.08);
5159
+ border: 1px solid rgba(255, 255, 255, 0.1);
5160
+ border-radius: 3px;
5161
+ color: var(--text-primary);
5162
+ }
5163
+
5164
+ /* Agent Credential Vault */
5165
+ .vault-premium-badge {
5166
+ display: inline-block;
5167
+ font-size: 10px;
5168
+ font-weight: 600;
5169
+ color: #f0c636;
5170
+ background: rgba(240, 198, 54, 0.15);
5171
+ padding: 1px 6px;
5172
+ border-radius: 4px;
5173
+ margin-left: 8px;
5174
+ vertical-align: middle;
5175
+ }
5176
+ .vault-entries {
5177
+ display: flex;
5178
+ flex-direction: column;
5179
+ gap: 6px;
5180
+ margin-bottom: 10px;
5181
+ }
5182
+ .vault-entry {
5183
+ display: flex;
5184
+ align-items: center;
5185
+ justify-content: space-between;
5186
+ padding: 8px 12px;
5187
+ background: var(--bg-tertiary);
5188
+ border: 1px solid var(--border-subtle);
5189
+ border-radius: var(--radius-md);
5190
+ }
5191
+ .vault-entry-info {
5192
+ display: flex;
5193
+ flex-direction: column;
5194
+ gap: 2px;
5195
+ min-width: 0;
5196
+ }
5197
+ .vault-entry-label {
5198
+ font-size: 12px;
5199
+ font-weight: 500;
5200
+ color: var(--text-primary);
5201
+ white-space: nowrap;
5202
+ overflow: hidden;
5203
+ text-overflow: ellipsis;
5204
+ }
5205
+ .vault-entry-detail {
5206
+ font-size: 11px;
5207
+ color: var(--text-muted);
5208
+ white-space: nowrap;
5209
+ overflow: hidden;
5210
+ text-overflow: ellipsis;
5211
+ }
5212
+ .vault-entry-remove {
5213
+ flex-shrink: 0;
5214
+ width: 24px;
5215
+ height: 24px;
5216
+ border-radius: 4px;
5217
+ background: transparent;
5218
+ border: none;
5219
+ color: var(--text-tertiary, #71717a);
5220
+ font-size: 16px;
5221
+ cursor: pointer;
5222
+ display: flex;
5223
+ align-items: center;
5224
+ justify-content: center;
5225
+ transition: background var(--duration-fast), color var(--duration-fast);
5226
+ }
5227
+ .vault-entry-remove:hover {
5228
+ background: rgba(255, 108, 91, 0.12);
5229
+ color: #ff8e8e;
5230
+ }
5231
+ .vault-add-btn {
5232
+ height: 32px;
5233
+ padding: 0 14px;
5234
+ border-radius: var(--radius-md);
5235
+ font-size: 12px;
5236
+ font-weight: 500;
5237
+ background: var(--bg-tertiary);
5238
+ border: 1px dashed var(--border-subtle);
5239
+ color: var(--text-secondary);
5240
+ cursor: pointer;
5241
+ width: 100%;
5242
+ transition: background var(--duration-fast), border-color var(--duration-fast);
5243
+ }
5244
+ .vault-add-btn:hover {
5245
+ background: var(--border-visible);
5246
+ border-color: var(--border-visible);
5247
+ }
5248
+ .vault-add-form {
5249
+ display: flex;
5250
+ flex-direction: column;
5251
+ gap: 8px;
5252
+ padding: 12px;
5253
+ background: rgba(255, 255, 255, 0.02);
5254
+ border: 1px solid var(--border-subtle);
5255
+ border-radius: var(--radius-md);
5256
+ }
5257
+ .vault-add-actions {
5258
+ display: flex;
5259
+ gap: 8px;
5260
+ justify-content: flex-end;
5261
+ margin-top: 4px;
5262
+ }
5263
+ `), _tmpl$15 = /* @__PURE__ */ template(`<div class="settings-input settings-input-disabled"title="Upgrade to Vessel Premium for unlimited tool iterations">50`), _tmpl$16 = /* @__PURE__ */ template(`<div class=settings-health-issues>`), _tmpl$17 = /* @__PURE__ */ template(`<div class=settings-health><div class=settings-callout-title>Runtime Health</div><p class=settings-hint>MCP status: <strong></strong> `), _tmpl$18 = /* @__PURE__ */ template(`<p class=settings-hint>Active endpoint: <code>`), _tmpl$19 = /* @__PURE__ */ template(`<div class=settings-health-issue><strong></strong><div>`), _tmpl$20 = /* @__PURE__ */ template(`<div>`), _tmpl$21 = /* @__PURE__ */ template(`<option>`), _tmpl$22 = /* @__PURE__ */ template(`<input id=chat-model class=settings-input style=flex:1>`), _tmpl$23 = /* @__PURE__ */ template(`<button class="premium-btn premium-btn-reset">Clear Saved Email`), _tmpl$24 = /* @__PURE__ */ template(`<div class=premium-section><p class=premium-description>Unlock screenshot/vision analysis, session management, Obsidian integration, workflow tracking, DevTools tools, table extraction, Agent Credential Vault, 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$25 = /* @__PURE__ */ template(`<p class=settings-status>`), _tmpl$26 = /* @__PURE__ */ template(`<p class=settings-hint>Securely store credentials for agent-driven logins. Upgrade to Premium to unlock the Agent Credential Vault.`), _tmpl$27 = /* @__PURE__ */ template(`<div class=vault-entry><div class=vault-entry-info><span class=vault-entry-label></span><span class=vault-entry-detail> &middot; </span></div><button class=vault-entry-remove title="Remove credential">&times;`);
4771
5264
  const CHAT_PROVIDERS = [{
4772
5265
  id: "anthropic",
4773
5266
  name: "Anthropic",
@@ -4848,6 +5341,95 @@ const Settings = () => {
4848
5341
  const [health, setHealth] = createSignal(null);
4849
5342
  const [defaultUrl, setDefaultUrl] = createSignal("https://start.duckduckgo.com");
4850
5343
  const [status, setStatus] = createSignal(null);
5344
+ const [telemetryEnabled, setTelemetryEnabled] = createSignal(true);
5345
+ const [vaultEntries, setVaultEntries] = createSignal([]);
5346
+ const [vaultExpanded, setVaultExpanded] = createSignal(false);
5347
+ const [vaultAdding, setVaultAdding] = createSignal(false);
5348
+ const [vaultNewLabel, setVaultNewLabel] = createSignal("");
5349
+ const [vaultNewDomain, setVaultNewDomain] = createSignal("");
5350
+ const [vaultNewUsername, setVaultNewUsername] = createSignal("");
5351
+ const [vaultNewPassword, setVaultNewPassword] = createSignal("");
5352
+ const [vaultNewTotp, setVaultNewTotp] = createSignal("");
5353
+ const [vaultNewNotes, setVaultNewNotes] = createSignal("");
5354
+ const [vaultMessage, setVaultMessage] = createSignal(null);
5355
+ const FIRST_RUN_KEY = "vessel.onboarding.dismissed";
5356
+ const [showWelcome, setShowWelcome] = createSignal(!localStorage.getItem(FIRST_RUN_KEY));
5357
+ const dismissWelcome = () => {
5358
+ localStorage.setItem(FIRST_RUN_KEY, "1");
5359
+ setShowWelcome(false);
5360
+ };
5361
+ const loadVaultEntries = async () => {
5362
+ try {
5363
+ const entries2 = await window.vessel.vault.list();
5364
+ setVaultEntries(entries2);
5365
+ } catch {
5366
+ }
5367
+ };
5368
+ const handleVaultAdd = async () => {
5369
+ if (!vaultNewLabel().trim() || !vaultNewDomain().trim() || !vaultNewUsername().trim() || !vaultNewPassword().trim()) {
5370
+ setVaultMessage({
5371
+ kind: "error",
5372
+ text: "Label, domain, username, and password are required."
5373
+ });
5374
+ return;
5375
+ }
5376
+ try {
5377
+ await window.vessel.vault.add({
5378
+ label: vaultNewLabel().trim(),
5379
+ domainPattern: vaultNewDomain().trim(),
5380
+ username: vaultNewUsername().trim(),
5381
+ password: vaultNewPassword().trim(),
5382
+ totpSecret: vaultNewTotp().trim() || void 0,
5383
+ notes: vaultNewNotes().trim() || void 0
5384
+ });
5385
+ setVaultNewLabel("");
5386
+ setVaultNewDomain("");
5387
+ setVaultNewUsername("");
5388
+ setVaultNewPassword("");
5389
+ setVaultNewTotp("");
5390
+ setVaultNewNotes("");
5391
+ setVaultAdding(false);
5392
+ setVaultMessage({
5393
+ kind: "success",
5394
+ text: "Credential added."
5395
+ });
5396
+ await loadVaultEntries();
5397
+ } catch (err) {
5398
+ setVaultMessage({
5399
+ kind: "error",
5400
+ text: err instanceof Error ? err.message : "Failed to add credential."
5401
+ });
5402
+ }
5403
+ };
5404
+ const handleVaultRemove = async (id) => {
5405
+ try {
5406
+ await window.vessel.vault.remove(id);
5407
+ await loadVaultEntries();
5408
+ setVaultMessage({
5409
+ kind: "success",
5410
+ text: "Credential removed."
5411
+ });
5412
+ } catch {
5413
+ setVaultMessage({
5414
+ kind: "error",
5415
+ text: "Failed to remove credential."
5416
+ });
5417
+ }
5418
+ };
5419
+ const [premiumState, setPremiumState] = createSignal({
5420
+ status: "free",
5421
+ customerId: "",
5422
+ email: "",
5423
+ validatedAt: "",
5424
+ expiresAt: ""
5425
+ });
5426
+ const [premiumEmail, setPremiumEmail] = createSignal("");
5427
+ const [premiumLoading, setPremiumLoading] = createSignal(false);
5428
+ const [premiumMessage, setPremiumMessage] = createSignal(null);
5429
+ const premiumActive = () => {
5430
+ const s = premiumState().status;
5431
+ return s === "active" || s === "trialing";
5432
+ };
4851
5433
  const [chatEnabled, setChatEnabled] = createSignal(false);
4852
5434
  const [chatProviderId, setChatProviderId] = createSignal("anthropic");
4853
5435
  const [chatApiKey, setChatApiKey] = createSignal("");
@@ -4920,6 +5502,14 @@ const Settings = () => {
4920
5502
  setChatModel(cp.model);
4921
5503
  setChatBaseUrl(cp.baseUrl ?? "");
4922
5504
  }
5505
+ setTelemetryEnabled(settings.telemetryEnabled !== false);
5506
+ try {
5507
+ const ps = await window.vessel.premium.getState();
5508
+ setPremiumState(ps);
5509
+ if (ps.email) setPremiumEmail(ps.email);
5510
+ } catch {
5511
+ }
5512
+ await loadVaultEntries();
4923
5513
  };
4924
5514
  onMount(() => {
4925
5515
  void loadState();
@@ -4947,6 +5537,7 @@ const Settings = () => {
4947
5537
  const parsedIterations = Number(maxToolIterations().trim()) || 200;
4948
5538
  await window.vessel.settings.set("maxToolIterations", Math.max(10, Math.min(1e3, parsedIterations)));
4949
5539
  await window.vessel.settings.set("agentTranscriptMode", agentTranscriptMode());
5540
+ await window.vessel.settings.set("telemetryEnabled", telemetryEnabled());
4950
5541
  const chatConfig = chatEnabled() ? {
4951
5542
  id: chatProviderId(),
4952
5543
  apiKey: chatApiKey().trim(),
@@ -4975,85 +5566,120 @@ const Settings = () => {
4975
5566
  },
4976
5567
  get children() {
4977
5568
  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;
5569
+ var _el$ = _tmpl$13(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$1 = _el$3.nextSibling, _el$10 = _el$1.nextSibling, _el$11 = _el$10.firstChild, _el$12 = _el$11.nextSibling, _el$13 = _el$10.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.nextSibling, _el$16 = _el$13.nextSibling, _el$17 = _el$16.firstChild, _el$19 = _el$17.nextSibling, _el$20 = _el$16.nextSibling, _el$21 = _el$20.firstChild, _el$22 = _el$21.nextSibling, _el$23 = _el$20.nextSibling, _el$24 = _el$23.firstChild, _el$25 = _el$24.nextSibling, _el$26 = _el$23.nextSibling, _el$27 = _el$26.firstChild, _el$28 = _el$27.firstChild, _el$29 = _el$26.nextSibling, _el$30 = _el$29.firstChild, _el$31 = _el$30.firstChild, _el$32 = _el$29.nextSibling, _el$33 = _el$32.nextSibling, _el$34 = _el$33.firstChild, _el$35 = _el$34.firstChild, _el$51 = _el$33.nextSibling, _el$52 = _el$51.nextSibling;
5570
+ _el$52.firstChild;
5571
+ var _el$61 = _el$52.nextSibling, _el$62 = _el$61.nextSibling, _el$63 = _el$62.firstChild;
5572
+ _el$63.firstChild;
5573
+ var _el$79 = _el$62.nextSibling, _el$80 = _el$79.nextSibling, _el$81 = _el$80.firstChild, _el$82 = _el$81.firstChild, _el$83 = _el$80.nextSibling, _el$84 = _el$83.firstChild, _el$85 = _el$84.nextSibling;
4979
5574
  addEventListener(_el$, "click", closeSettings);
4980
5575
  _el$2.$$keydown = handleKeyDown;
4981
5576
  _el$2.$$click = (e) => e.stopPropagation();
4982
- _el$7.$$input = (e) => setDefaultUrl(e.currentTarget.value);
4983
- setAttribute(_el$7, "spellcheck", false);
4984
- _el$0.$$input = (e) => setMcpPort(e.currentTarget.value);
4985
- setAttribute(_el$0, "spellcheck", false);
4986
- _el$11.$$input = (e) => setMaxToolIterations(e.currentTarget.value);
5577
+ insert(_el$2, createComponent(Show, {
5578
+ get when() {
5579
+ return showWelcome();
5580
+ },
5581
+ get children() {
5582
+ var _el$4 = _tmpl$$2(), _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$5.nextSibling, _el$9 = _el$8.nextSibling, _el$0 = _el$9.firstChild;
5583
+ _el$7.$$click = dismissWelcome;
5584
+ createRenderEffect(() => _el$0.classList.toggle("done", !!chatEnabled()));
5585
+ return _el$4;
5586
+ }
5587
+ }), _el$1);
5588
+ _el$12.$$input = (e) => setDefaultUrl(e.currentTarget.value);
5589
+ setAttribute(_el$12, "spellcheck", false);
5590
+ _el$15.$$input = (e) => setMcpPort(e.currentTarget.value);
5591
+ setAttribute(_el$15, "spellcheck", false);
5592
+ insert(_el$16, createComponent(Show, {
5593
+ get when() {
5594
+ return premiumActive();
5595
+ },
5596
+ get fallback() {
5597
+ return _tmpl$15();
5598
+ },
5599
+ get children() {
5600
+ var _el$18 = _tmpl$2$2();
5601
+ _el$18.$$input = (e) => setMaxToolIterations(e.currentTarget.value);
5602
+ createRenderEffect(() => _el$18.value = maxToolIterations());
5603
+ return _el$18;
5604
+ }
5605
+ }), _el$19);
5606
+ insert(_el$19, createComponent(Show, {
5607
+ get when() {
5608
+ return premiumActive();
5609
+ },
5610
+ fallback: "Free tier: 50 tool calls per conversation turn. Upgrade to Vessel Premium to customize this limit (up to 1,000).",
5611
+ 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."
5612
+ }));
4987
5613
  insert(_el$2, createComponent(Show, {
4988
5614
  get when() {
4989
5615
  return health();
4990
5616
  },
4991
5617
  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, {
5618
+ var _el$88 = _tmpl$17(), _el$89 = _el$88.firstChild, _el$90 = _el$89.nextSibling, _el$91 = _el$90.firstChild, _el$93 = _el$91.nextSibling;
5619
+ _el$93.nextSibling;
5620
+ insert(_el$93, () => currentHealth().mcp.status);
5621
+ insert(_el$90, () => currentHealth().mcp.message, null);
5622
+ insert(_el$88, createComponent(Show, {
4997
5623
  get when() {
4998
5624
  return currentHealth().mcp.endpoint;
4999
5625
  },
5000
5626
  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;
5627
+ var _el$96 = _tmpl$18(), _el$97 = _el$96.firstChild, _el$98 = _el$97.nextSibling;
5628
+ insert(_el$98, endpoint);
5629
+ return _el$96;
5004
5630
  })()
5005
5631
  }), null);
5006
- insert(_el$47, createComponent(Show, {
5632
+ insert(_el$88, createComponent(Show, {
5007
5633
  get when() {
5008
5634
  return currentHealth().startupIssues.length > 0;
5009
5635
  },
5010
5636
  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, {
5637
+ var _el$95 = _tmpl$16();
5638
+ insert(_el$95, () => currentHealth().startupIssues.map((issue) => (() => {
5639
+ var _el$99 = _tmpl$19(), _el$100 = _el$99.firstChild, _el$101 = _el$100.nextSibling;
5640
+ insert(_el$100, () => issue.title);
5641
+ insert(_el$101, () => issue.detail);
5642
+ insert(_el$99, createComponent(Show, {
5017
5643
  get when() {
5018
5644
  return issue.action;
5019
5645
  },
5020
5646
  children: (action) => (() => {
5021
- var _el$61 = _tmpl$11();
5022
- insert(_el$61, action);
5023
- return _el$61;
5647
+ var _el$102 = _tmpl$20();
5648
+ insert(_el$102, action);
5649
+ return _el$102;
5024
5650
  })()
5025
5651
  }), null);
5026
5652
  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);
5653
+ var _v$9 = !!(issue.severity === "warning"), _v$0 = !!(issue.severity === "error");
5654
+ _v$9 !== _p$.e && _el$99.classList.toggle("warning", _p$.e = _v$9);
5655
+ _v$0 !== _p$.t && _el$99.classList.toggle("error", _p$.t = _v$0);
5030
5656
  return _p$;
5031
5657
  }, {
5032
5658
  e: void 0,
5033
5659
  t: void 0
5034
5660
  });
5035
- return _el$58;
5661
+ return _el$99;
5036
5662
  })()));
5037
- return _el$54;
5663
+ return _el$95;
5038
5664
  }
5039
5665
  }), null);
5040
- return _el$47;
5666
+ return _el$88;
5041
5667
  })()
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());
5668
+ }), _el$20);
5669
+ _el$22.$$input = (e) => setObsidianVaultPath(e.currentTarget.value);
5670
+ setAttribute(_el$22, "spellcheck", false);
5671
+ _el$25.addEventListener("change", (e) => setAgentTranscriptMode(e.currentTarget.value));
5672
+ _el$28.$$click = () => setAutoRestoreSession(!autoRestoreSession());
5673
+ _el$31.$$click = () => setClearBookmarksOnLaunch(!clearBookmarksOnLaunch());
5674
+ _el$35.$$click = () => setChatEnabled(!chatEnabled());
5049
5675
  insert(_el$2, createComponent(Show, {
5050
5676
  get when() {
5051
5677
  return chatEnabled();
5052
5678
  },
5053
5679
  get children() {
5054
5680
  return [(() => {
5055
- var _el$28 = _tmpl$$1(), _el$29 = _el$28.firstChild, _el$30 = _el$29.nextSibling;
5056
- _el$30.addEventListener("change", (e) => {
5681
+ var _el$36 = _tmpl$3$1(), _el$37 = _el$36.firstChild, _el$38 = _el$37.nextSibling;
5682
+ _el$38.addEventListener("change", (e) => {
5057
5683
  const id = e.currentTarget.value;
5058
5684
  setChatProviderId(id);
5059
5685
  setChatModel("");
@@ -5062,118 +5688,345 @@ const Settings = () => {
5062
5688
  setProviderModels([]);
5063
5689
  setModelFetchState("idle");
5064
5690
  });
5065
- insert(_el$30, createComponent(For, {
5691
+ insert(_el$38, createComponent(For, {
5066
5692
  each: CHAT_PROVIDERS,
5067
5693
  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;
5694
+ var _el$103 = _tmpl$21();
5695
+ insert(_el$103, () => p.name);
5696
+ createRenderEffect(() => _el$103.value = p.id);
5697
+ return _el$103;
5072
5698
  })()
5073
5699
  }));
5074
- createRenderEffect(() => _el$30.value = chatProviderId());
5075
- return _el$28;
5700
+ createRenderEffect(() => _el$38.value = chatProviderId());
5701
+ return _el$36;
5076
5702
  })(), createComponent(Show, {
5077
5703
  get when() {
5078
5704
  return chatProviderMeta().requiresKey;
5079
5705
  },
5080
5706
  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;
5707
+ var _el$39 = _tmpl$4$1(), _el$40 = _el$39.firstChild, _el$41 = _el$40.nextSibling;
5708
+ _el$41.$$input = (e) => setChatApiKey(e.currentTarget.value);
5709
+ setAttribute(_el$41, "spellcheck", false);
5710
+ createRenderEffect(() => setAttribute(_el$41, "placeholder", chatProviderMeta().keyPlaceholder));
5711
+ createRenderEffect(() => _el$41.value = chatApiKey());
5712
+ return _el$39;
5087
5713
  }
5088
5714
  }), (() => {
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, {
5715
+ var _el$42 = _tmpl$7(), _el$43 = _el$42.firstChild, _el$44 = _el$43.nextSibling, _el$46 = _el$44.firstChild;
5716
+ insert(_el$44, createComponent(Show, {
5091
5717
  get when() {
5092
5718
  return providerModels().length > 0;
5093
5719
  },
5094
5720
  get fallback() {
5095
5721
  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;
5722
+ var _el$104 = _tmpl$22();
5723
+ _el$104.$$input = (e) => setChatModel(e.currentTarget.value);
5724
+ setAttribute(_el$104, "spellcheck", false);
5725
+ createRenderEffect(() => setAttribute(_el$104, "placeholder", modelFetchState() === "loading" ? "Fetching models…" : chatProviderMeta().requiresKey && !chatApiKey().trim() ? "Enter API key to load models" : chatProviderMeta().defaultModel || "model name"));
5726
+ createRenderEffect(() => _el$104.value = chatModel());
5727
+ return _el$104;
5102
5728
  })();
5103
5729
  },
5104
5730
  get children() {
5105
- var _el$37 = _tmpl$3();
5106
- _el$37.addEventListener("change", (e) => setChatModel(e.currentTarget.value));
5107
- insert(_el$37, createComponent(For, {
5731
+ var _el$45 = _tmpl$5$1();
5732
+ _el$45.addEventListener("change", (e) => setChatModel(e.currentTarget.value));
5733
+ insert(_el$45, createComponent(For, {
5108
5734
  get each() {
5109
5735
  return providerModels();
5110
5736
  },
5111
5737
  children: (m) => (() => {
5112
- var _el$64 = _tmpl$12();
5113
- _el$64.value = m;
5114
- insert(_el$64, m);
5115
- return _el$64;
5738
+ var _el$105 = _tmpl$21();
5739
+ _el$105.value = m;
5740
+ insert(_el$105, m);
5741
+ return _el$105;
5116
5742
  })()
5117
5743
  }));
5118
- createRenderEffect(() => _el$37.value = chatModel());
5119
- return _el$37;
5744
+ createRenderEffect(() => _el$45.value = chatModel());
5745
+ return _el$45;
5120
5746
  }
5121
- }), _el$38);
5122
- _el$38.$$click = doFetchModels;
5123
- insert(_el$34, createComponent(Show, {
5747
+ }), _el$46);
5748
+ _el$46.$$click = doFetchModels;
5749
+ insert(_el$42, createComponent(Show, {
5124
5750
  get when() {
5125
5751
  return modelFetchState() === "error";
5126
5752
  },
5127
5753
  get children() {
5128
- return _tmpl$4();
5754
+ return _tmpl$6$1();
5129
5755
  }
5130
5756
  }), null);
5131
- createRenderEffect(() => _el$38.disabled = modelFetchState() === "loading");
5132
- return _el$34;
5757
+ createRenderEffect(() => _el$46.disabled = modelFetchState() === "loading");
5758
+ return _el$42;
5133
5759
  })(), createComponent(Show, {
5134
5760
  get when() {
5135
5761
  return chatProviderMeta().needsBaseUrl || chatProviderId() === "custom";
5136
5762
  },
5137
5763
  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;
5764
+ var _el$48 = _tmpl$8(), _el$49 = _el$48.firstChild, _el$50 = _el$49.nextSibling;
5765
+ _el$50.$$input = (e) => setChatBaseUrl(e.currentTarget.value);
5766
+ setAttribute(_el$50, "spellcheck", false);
5767
+ createRenderEffect(() => setAttribute(_el$50, "placeholder", chatProviderMeta().defaultBaseUrl ?? "https://..."));
5768
+ createRenderEffect(() => _el$50.value = chatBaseUrl());
5769
+ return _el$48;
5144
5770
  }
5145
5771
  })];
5146
5772
  }
5147
- }), _el$43);
5148
- _el$44.$$click = handleSave;
5149
- addEventListener(_el$45, "click", closeSettings);
5773
+ }), _el$51);
5774
+ insert(_el$52, createComponent(Show, {
5775
+ get when() {
5776
+ return premiumActive();
5777
+ },
5778
+ get fallback() {
5779
+ return (() => {
5780
+ var _el$106 = _tmpl$24(), _el$107 = _el$106.firstChild, _el$108 = _el$107.nextSibling, _el$109 = _el$108.firstChild, _el$110 = _el$109.nextSibling, _el$111 = _el$108.nextSibling;
5781
+ _el$109.$$input = (e) => setPremiumEmail(e.currentTarget.value);
5782
+ setAttribute(_el$109, "spellcheck", false);
5783
+ _el$110.$$click = async () => {
5784
+ setPremiumLoading(true);
5785
+ setPremiumMessage(null);
5786
+ try {
5787
+ const result = await window.vessel.premium.activate(premiumEmail().trim());
5788
+ setPremiumState(result.state);
5789
+ if (result.ok) {
5790
+ setPremiumMessage({
5791
+ kind: "success",
5792
+ text: "Premium activated!"
5793
+ });
5794
+ } else {
5795
+ setPremiumMessage({
5796
+ kind: "error",
5797
+ text: result.error || "Activation failed"
5798
+ });
5799
+ }
5800
+ } catch (err) {
5801
+ setPremiumMessage({
5802
+ kind: "error",
5803
+ text: err instanceof Error ? err.message : "Activation failed"
5804
+ });
5805
+ } finally {
5806
+ setPremiumLoading(false);
5807
+ }
5808
+ };
5809
+ insert(_el$110, () => premiumLoading() ? "Checking..." : "Activate");
5810
+ _el$111.$$click = () => {
5811
+ void window.vessel.premium.checkout(premiumEmail().trim() || void 0);
5812
+ };
5813
+ insert(_el$106, createComponent(Show, {
5814
+ get when() {
5815
+ return premiumMessage();
5816
+ },
5817
+ children: (msg) => (() => {
5818
+ var _el$113 = _tmpl$25();
5819
+ insert(_el$113, () => msg().text);
5820
+ createRenderEffect((_p$) => {
5821
+ var _v$1 = !!(msg().kind === "success"), _v$10 = !!(msg().kind === "error");
5822
+ _v$1 !== _p$.e && _el$113.classList.toggle("success", _p$.e = _v$1);
5823
+ _v$10 !== _p$.t && _el$113.classList.toggle("error", _p$.t = _v$10);
5824
+ return _p$;
5825
+ }, {
5826
+ e: void 0,
5827
+ t: void 0
5828
+ });
5829
+ return _el$113;
5830
+ })()
5831
+ }), null);
5832
+ insert(_el$106, createComponent(Show, {
5833
+ get when() {
5834
+ return premiumState().email || premiumEmail();
5835
+ },
5836
+ get children() {
5837
+ var _el$112 = _tmpl$23();
5838
+ _el$112.$$click = async () => {
5839
+ const state = await window.vessel.premium.reset();
5840
+ setPremiumState(state);
5841
+ setPremiumEmail("");
5842
+ setPremiumMessage(null);
5843
+ };
5844
+ return _el$112;
5845
+ }
5846
+ }), null);
5847
+ createRenderEffect(() => _el$110.disabled = premiumLoading() || !premiumEmail().trim());
5848
+ createRenderEffect(() => _el$109.value = premiumEmail());
5849
+ return _el$106;
5850
+ })();
5851
+ },
5852
+ get children() {
5853
+ var _el$54 = _tmpl$9(), _el$55 = _el$54.firstChild;
5854
+ _el$55.firstChild;
5855
+ var _el$57 = _el$55.nextSibling, _el$58 = _el$57.nextSibling, _el$59 = _el$58.firstChild, _el$60 = _el$59.nextSibling;
5856
+ insert(_el$55, createComponent(Show, {
5857
+ get when() {
5858
+ return premiumState().status === "trialing";
5859
+ },
5860
+ get children() {
5861
+ return [" ", "(Trial)"];
5862
+ }
5863
+ }), null);
5864
+ insert(_el$57, () => premiumState().email, null);
5865
+ insert(_el$57, createComponent(Show, {
5866
+ get when() {
5867
+ return premiumState().expiresAt;
5868
+ },
5869
+ get children() {
5870
+ return [" ", "· Renews", " ", memo(() => new Date(premiumState().expiresAt).toLocaleDateString())];
5871
+ }
5872
+ }), null);
5873
+ _el$59.$$click = () => {
5874
+ void window.vessel.premium.portal();
5875
+ };
5876
+ _el$60.$$click = async () => {
5877
+ const state = await window.vessel.premium.reset();
5878
+ setPremiumState(state);
5879
+ setPremiumEmail("");
5880
+ setPremiumMessage(null);
5881
+ };
5882
+ return _el$54;
5883
+ }
5884
+ }), null);
5885
+ insert(_el$63, createComponent(Show, {
5886
+ get when() {
5887
+ return !premiumActive();
5888
+ },
5889
+ get children() {
5890
+ return _tmpl$0();
5891
+ }
5892
+ }), null);
5893
+ insert(_el$62, createComponent(Show, {
5894
+ get when() {
5895
+ return premiumActive();
5896
+ },
5897
+ get fallback() {
5898
+ return _tmpl$26();
5899
+ },
5900
+ get children() {
5901
+ return [_tmpl$1(), createComponent(Show, {
5902
+ get when() {
5903
+ return vaultEntries().length > 0;
5904
+ },
5905
+ get children() {
5906
+ var _el$67 = _tmpl$10();
5907
+ insert(_el$67, createComponent(For, {
5908
+ get each() {
5909
+ return vaultEntries();
5910
+ },
5911
+ children: (entry) => (() => {
5912
+ var _el$115 = _tmpl$27(), _el$116 = _el$115.firstChild, _el$117 = _el$116.firstChild, _el$118 = _el$117.nextSibling, _el$119 = _el$118.firstChild, _el$120 = _el$116.nextSibling;
5913
+ insert(_el$117, () => entry.label);
5914
+ insert(_el$118, () => entry.username, _el$119);
5915
+ insert(_el$118, () => entry.domainPattern, null);
5916
+ insert(_el$118, createComponent(Show, {
5917
+ get when() {
5918
+ return entry.useCount > 0;
5919
+ },
5920
+ get children() {
5921
+ return [" ", "· Used ", memo(() => entry.useCount), "x"];
5922
+ }
5923
+ }), null);
5924
+ _el$120.$$click = () => handleVaultRemove(entry.id);
5925
+ return _el$115;
5926
+ })()
5927
+ }));
5928
+ return _el$67;
5929
+ }
5930
+ }), createComponent(Show, {
5931
+ get when() {
5932
+ return !vaultAdding();
5933
+ },
5934
+ get children() {
5935
+ var _el$68 = _tmpl$11();
5936
+ _el$68.$$click = () => {
5937
+ setVaultAdding(true);
5938
+ setVaultMessage(null);
5939
+ };
5940
+ return _el$68;
5941
+ }
5942
+ }), createComponent(Show, {
5943
+ get when() {
5944
+ return vaultAdding();
5945
+ },
5946
+ get children() {
5947
+ var _el$69 = _tmpl$12(), _el$70 = _el$69.firstChild, _el$71 = _el$70.nextSibling, _el$72 = _el$71.nextSibling, _el$73 = _el$72.nextSibling, _el$74 = _el$73.nextSibling, _el$75 = _el$74.nextSibling, _el$76 = _el$75.nextSibling, _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling;
5948
+ _el$70.$$input = (e) => setVaultNewLabel(e.currentTarget.value);
5949
+ setAttribute(_el$70, "spellcheck", false);
5950
+ _el$71.$$input = (e) => setVaultNewDomain(e.currentTarget.value);
5951
+ setAttribute(_el$71, "spellcheck", false);
5952
+ _el$72.$$input = (e) => setVaultNewUsername(e.currentTarget.value);
5953
+ setAttribute(_el$72, "spellcheck", false);
5954
+ _el$73.$$input = (e) => setVaultNewPassword(e.currentTarget.value);
5955
+ _el$74.$$input = (e) => setVaultNewTotp(e.currentTarget.value);
5956
+ setAttribute(_el$74, "spellcheck", false);
5957
+ _el$75.$$input = (e) => setVaultNewNotes(e.currentTarget.value);
5958
+ setAttribute(_el$75, "spellcheck", false);
5959
+ _el$77.$$click = handleVaultAdd;
5960
+ _el$78.$$click = () => {
5961
+ setVaultAdding(false);
5962
+ setVaultNewLabel("");
5963
+ setVaultNewDomain("");
5964
+ setVaultNewUsername("");
5965
+ setVaultNewPassword("");
5966
+ setVaultNewTotp("");
5967
+ setVaultNewNotes("");
5968
+ };
5969
+ createRenderEffect(() => _el$70.value = vaultNewLabel());
5970
+ createRenderEffect(() => _el$71.value = vaultNewDomain());
5971
+ createRenderEffect(() => _el$72.value = vaultNewUsername());
5972
+ createRenderEffect(() => _el$73.value = vaultNewPassword());
5973
+ createRenderEffect(() => _el$74.value = vaultNewTotp());
5974
+ createRenderEffect(() => _el$75.value = vaultNewNotes());
5975
+ return _el$69;
5976
+ }
5977
+ }), createComponent(Show, {
5978
+ get when() {
5979
+ return vaultMessage();
5980
+ },
5981
+ children: (msg) => (() => {
5982
+ var _el$121 = _tmpl$25();
5983
+ insert(_el$121, () => msg().text);
5984
+ createRenderEffect((_p$) => {
5985
+ var _v$11 = !!(msg().kind === "success"), _v$12 = !!(msg().kind === "error");
5986
+ _v$11 !== _p$.e && _el$121.classList.toggle("success", _p$.e = _v$11);
5987
+ _v$12 !== _p$.t && _el$121.classList.toggle("error", _p$.t = _v$12);
5988
+ return _p$;
5989
+ }, {
5990
+ e: void 0,
5991
+ t: void 0
5992
+ });
5993
+ return _el$121;
5994
+ })()
5995
+ })];
5996
+ }
5997
+ }), null);
5998
+ _el$82.$$click = () => setTelemetryEnabled(!telemetryEnabled());
5999
+ _el$84.$$click = handleSave;
6000
+ addEventListener(_el$85, "click", closeSettings);
5150
6001
  insert(_el$2, createComponent(Show, {
5151
6002
  get when() {
5152
6003
  return status();
5153
6004
  },
5154
6005
  children: (currentStatus) => (() => {
5155
- var _el$65 = _tmpl$14();
5156
- insert(_el$65, () => currentStatus().text);
6006
+ var _el$122 = _tmpl$25();
6007
+ insert(_el$122, () => currentStatus().text);
5157
6008
  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);
6009
+ var _v$13 = !!(currentStatus().kind === "success"), _v$14 = !!(currentStatus().kind === "error");
6010
+ _v$13 !== _p$.e && _el$122.classList.toggle("success", _p$.e = _v$13);
6011
+ _v$14 !== _p$.t && _el$122.classList.toggle("error", _p$.t = _v$14);
5161
6012
  return _p$;
5162
6013
  }, {
5163
6014
  e: void 0,
5164
6015
  t: void 0
5165
6016
  });
5166
- return _el$65;
6017
+ return _el$122;
5167
6018
  })()
5168
6019
  }), null);
5169
6020
  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);
6021
+ var _v$ = !!autoRestoreSession(), _v$2 = autoRestoreSession(), _v$3 = !!clearBookmarksOnLaunch(), _v$4 = clearBookmarksOnLaunch(), _v$5 = !!chatEnabled(), _v$6 = chatEnabled(), _v$7 = !!telemetryEnabled(), _v$8 = telemetryEnabled();
6022
+ _v$ !== _p$.e && _el$28.classList.toggle("on", _p$.e = _v$);
6023
+ _v$2 !== _p$.t && setAttribute(_el$28, "aria-checked", _p$.t = _v$2);
6024
+ _v$3 !== _p$.a && _el$31.classList.toggle("on", _p$.a = _v$3);
6025
+ _v$4 !== _p$.o && setAttribute(_el$31, "aria-checked", _p$.o = _v$4);
6026
+ _v$5 !== _p$.i && _el$35.classList.toggle("on", _p$.i = _v$5);
6027
+ _v$6 !== _p$.n && setAttribute(_el$35, "aria-checked", _p$.n = _v$6);
6028
+ _v$7 !== _p$.s && _el$82.classList.toggle("on", _p$.s = _v$7);
6029
+ _v$8 !== _p$.h && setAttribute(_el$82, "aria-checked", _p$.h = _v$8);
5177
6030
  return _p$;
5178
6031
  }, {
5179
6032
  e: void 0,
@@ -5181,19 +6034,158 @@ const Settings = () => {
5181
6034
  a: void 0,
5182
6035
  o: void 0,
5183
6036
  i: void 0,
5184
- n: void 0
6037
+ n: void 0,
6038
+ s: void 0,
6039
+ h: void 0
5185
6040
  });
5186
- createRenderEffect(() => _el$7.value = defaultUrl());
5187
- createRenderEffect(() => _el$0.value = mcpPort());
5188
- createRenderEffect(() => _el$11.value = maxToolIterations());
5189
- createRenderEffect(() => _el$14.value = obsidianVaultPath());
5190
- createRenderEffect(() => _el$17.value = agentTranscriptMode());
6041
+ createRenderEffect(() => _el$12.value = defaultUrl());
6042
+ createRenderEffect(() => _el$15.value = mcpPort());
6043
+ createRenderEffect(() => _el$22.value = obsidianVaultPath());
6044
+ createRenderEffect(() => _el$25.value = agentTranscriptMode());
5191
6045
  return _el$;
5192
- })(), _tmpl$8()];
6046
+ })(), _tmpl$14()];
5193
6047
  }
5194
6048
  });
5195
6049
  };
5196
6050
  delegateEvents(["click", "keydown", "input"]);
6051
+ var _tmpl$$1 = /* @__PURE__ */ template(`<div class=command-bar-overlay><div class=keyboard-help><div class=keyboard-help-header><h2 class=keyboard-help-title>Keyboard Shortcuts</h2><button class=keyboard-help-close><kbd>Esc</kbd></button></div><div class=keyboard-help-grid>`), _tmpl$2$1 = /* @__PURE__ */ template(`<style>
6052
+ .keyboard-help {
6053
+ width: min(380px, calc(100vw - 32px));
6054
+ background: var(--bg-elevated);
6055
+ border: 1px solid var(--border-visible);
6056
+ border-radius: 14px;
6057
+ padding: 24px;
6058
+ box-shadow:
6059
+ 0 4px 24px rgba(0, 0, 0, 0.2),
6060
+ 0 24px 64px rgba(0, 0, 0, 0.3),
6061
+ inset 0 1px 0 rgba(255, 255, 255, 0.04);
6062
+ animation: command-bar-enter 350ms var(--ease-out-expo) both;
6063
+ }
6064
+ .keyboard-help-header {
6065
+ display: flex;
6066
+ justify-content: space-between;
6067
+ align-items: center;
6068
+ margin-bottom: 20px;
6069
+ }
6070
+ .keyboard-help-title {
6071
+ font-size: 15px;
6072
+ font-weight: 600;
6073
+ color: var(--text-primary);
6074
+ margin: 0;
6075
+ }
6076
+ .keyboard-help-close {
6077
+ background: transparent;
6078
+ border: none;
6079
+ cursor: pointer;
6080
+ padding: 0;
6081
+ }
6082
+ .keyboard-help-close kbd {
6083
+ background: rgba(255, 255, 255, 0.06);
6084
+ border: 1px solid rgba(255, 255, 255, 0.08);
6085
+ padding: 2px 8px;
6086
+ border-radius: 4px;
6087
+ font-size: 11px;
6088
+ color: var(--text-muted);
6089
+ font-family: var(--font-ui);
6090
+ }
6091
+ .keyboard-help-close:hover kbd {
6092
+ background: rgba(255, 255, 255, 0.1);
6093
+ color: var(--text-secondary);
6094
+ }
6095
+ .keyboard-help-grid {
6096
+ display: grid;
6097
+ grid-template-columns: auto 1fr;
6098
+ gap: 10px 20px;
6099
+ align-items: center;
6100
+ }
6101
+ .keyboard-help-keys {
6102
+ display: flex;
6103
+ align-items: center;
6104
+ gap: 2px;
6105
+ justify-self: end;
6106
+ }
6107
+ .keyboard-help-keys kbd {
6108
+ display: inline-block;
6109
+ min-width: 24px;
6110
+ padding: 3px 7px;
6111
+ text-align: center;
6112
+ font-size: 11px;
6113
+ font-family: var(--font-mono);
6114
+ font-weight: 500;
6115
+ background: rgba(255, 255, 255, 0.06);
6116
+ border: 1px solid rgba(255, 255, 255, 0.08);
6117
+ border-radius: 4px;
6118
+ color: var(--text-primary);
6119
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
6120
+ }
6121
+ .keyboard-help-plus {
6122
+ font-size: 10px;
6123
+ color: var(--text-muted);
6124
+ margin: 0 1px;
6125
+ }
6126
+ .keyboard-help-action {
6127
+ font-size: 13px;
6128
+ color: var(--text-secondary);
6129
+ }
6130
+ `), _tmpl$3 = /* @__PURE__ */ template(`<div class=keyboard-help-keys>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=keyboard-help-action>`), _tmpl$5 = /* @__PURE__ */ template(`<kbd>`), _tmpl$6 = /* @__PURE__ */ template(`<span class=keyboard-help-plus>+`);
6131
+ const SHORTCUTS = [{
6132
+ keys: "Ctrl+L",
6133
+ action: "AI Command Bar"
6134
+ }, {
6135
+ keys: "Ctrl+Shift+L",
6136
+ action: "Toggle AI Sidebar"
6137
+ }, {
6138
+ keys: "Ctrl+Shift+F",
6139
+ action: "Toggle Focus Mode"
6140
+ }, {
6141
+ keys: "F12",
6142
+ action: "Toggle Dev Tools Panel"
6143
+ }, {
6144
+ keys: "Ctrl+T",
6145
+ action: "New Tab"
6146
+ }, {
6147
+ keys: "Ctrl+W",
6148
+ action: "Close Tab"
6149
+ }, {
6150
+ keys: "Ctrl+,",
6151
+ action: "Settings"
6152
+ }, {
6153
+ keys: "Ctrl+H",
6154
+ action: "Capture Highlight"
6155
+ }, {
6156
+ keys: "?",
6157
+ action: "This help overlay"
6158
+ }];
6159
+ const KeyboardHelp = (props) => {
6160
+ return createComponent(Show, {
6161
+ get when() {
6162
+ return props.open;
6163
+ },
6164
+ get children() {
6165
+ return [(() => {
6166
+ var _el$ = _tmpl$$1(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$3.nextSibling;
6167
+ addEventListener(_el$, "click", props.onClose);
6168
+ _el$2.$$click = (e) => e.stopPropagation();
6169
+ addEventListener(_el$5, "click", props.onClose);
6170
+ insert(_el$6, () => SHORTCUTS.map((s) => [(() => {
6171
+ var _el$8 = _tmpl$3();
6172
+ insert(_el$8, () => s.keys.split("+").map((k, i) => [i > 0 && _tmpl$6(), (() => {
6173
+ var _el$0 = _tmpl$5();
6174
+ insert(_el$0, k);
6175
+ return _el$0;
6176
+ })()]));
6177
+ return _el$8;
6178
+ })(), (() => {
6179
+ var _el$9 = _tmpl$4();
6180
+ insert(_el$9, () => s.action);
6181
+ return _el$9;
6182
+ })()]));
6183
+ return _el$;
6184
+ })(), _tmpl$2$1()];
6185
+ }
6186
+ });
6187
+ };
6188
+ delegateEvents(["click"]);
5197
6189
  function setupKeybindings(handlers) {
5198
6190
  const listener = (e) => {
5199
6191
  const ctrl = e.ctrlKey || e.metaKey;
@@ -5237,6 +6229,14 @@ function setupKeybindings(handlers) {
5237
6229
  handlers.toggleDevTools?.();
5238
6230
  return;
5239
6231
  }
6232
+ if (e.key === "?" && !ctrl && !e.altKey) {
6233
+ const tag = e.target?.tagName;
6234
+ if (tag !== "INPUT" && tag !== "TEXTAREA" && !e.target?.isContentEditable) {
6235
+ e.preventDefault();
6236
+ handlers.toggleKeyboardHelp?.();
6237
+ return;
6238
+ }
6239
+ }
5240
6240
  };
5241
6241
  document.addEventListener("keydown", listener);
5242
6242
  return () => document.removeEventListener("keydown", listener);
@@ -5258,6 +6258,7 @@ const App = () => {
5258
6258
  activeTab
5259
6259
  } = useTabs();
5260
6260
  const [highlightToast, setHighlightToast] = createSignal(null);
6261
+ const [keyboardHelpOpen, setKeyboardHelpOpen] = createSignal(false);
5261
6262
  const captureHighlight = async () => {
5262
6263
  try {
5263
6264
  const result = await window.vessel.highlights.capture();
@@ -5309,7 +6310,8 @@ const App = () => {
5309
6310
  captureHighlight,
5310
6311
  toggleDevTools: () => {
5311
6312
  window.vessel.devtoolsPanel.toggle();
5312
- }
6313
+ },
6314
+ toggleKeyboardHelp: () => setKeyboardHelpOpen((v) => !v)
5313
6315
  });
5314
6316
  const cleanupCapture = window.vessel.highlights.onCaptureResult(showHighlightResult);
5315
6317
  onCleanup(() => {
@@ -5348,6 +6350,12 @@ const App = () => {
5348
6350
  }), null);
5349
6351
  insert(_el$, createComponent(CommandBar, {}), null);
5350
6352
  insert(_el$, createComponent(Settings, {}), null);
6353
+ insert(_el$, createComponent(KeyboardHelp, {
6354
+ get open() {
6355
+ return keyboardHelpOpen();
6356
+ },
6357
+ onClose: () => setKeyboardHelpOpen(false)
6358
+ }), null);
5351
6359
  createRenderEffect(() => _el$.classList.toggle("focus-mode", !!focusMode2()));
5352
6360
  return _el$;
5353
6361
  })();