vite-plugin-opencode-assistant 1.0.11 → 1.0.13

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.
@@ -41,11 +41,39 @@ var import_vue = require("vue");
41
41
  var import_components = require("@vite-plugin-opencode-assistant/components");
42
42
  var import_style = require("@vite-plugin-opencode-assistant/components/style.css");
43
43
  var import_shared = require("@vite-plugin-opencode-assistant/shared");
44
+ function parseHotkey(hotkeyStr) {
45
+ if (!hotkeyStr) return { ctrl: true, shift: false, alt: false, key: "k" };
46
+ const parts = hotkeyStr.toLowerCase().split("+");
47
+ const key = parts.pop();
48
+ return {
49
+ ctrl: parts.includes("ctrl") || parts.includes("cmd") || parts.includes("meta"),
50
+ shift: parts.includes("shift"),
51
+ alt: parts.includes("alt"),
52
+ key: key || "k"
53
+ };
54
+ }
55
+ function matchHotkey(e, hotkeyConfig) {
56
+ const ctrlMatch = hotkeyConfig.ctrl ? e.ctrlKey || e.metaKey : !(e.ctrlKey || e.metaKey);
57
+ const shiftMatch = hotkeyConfig.shift ? e.shiftKey : !e.shiftKey;
58
+ const altMatch = hotkeyConfig.alt ? e.altKey : !e.altKey;
59
+ const keyMatch = e.key.toLowerCase() === hotkeyConfig.key.toLowerCase();
60
+ return ctrlMatch && shiftMatch && altMatch && keyMatch;
61
+ }
44
62
  function utf8ToBase64(str) {
45
63
  const bytes = new TextEncoder().encode(str);
46
64
  const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
47
65
  return btoa(binString);
48
66
  }
67
+ let proxyUrl = "";
68
+ function toProxyUrl(url) {
69
+ if (!url || !proxyUrl) return url;
70
+ try {
71
+ const urlObj = new URL(url, window.location.origin);
72
+ return `${proxyUrl}${urlObj.pathname}${urlObj.search}`;
73
+ } catch (e) {
74
+ return url;
75
+ }
76
+ }
49
77
  let config = {};
50
78
  const scriptTag = document.querySelector(`script[${import_shared.CONFIG_DATA_ATTR}]`);
51
79
  if (scriptTag) {
@@ -74,15 +102,19 @@ const App = {
74
102
  const selectedElements = (0, import_vue.ref)([]);
75
103
  const widgetRef = (0, import_vue.ref)(null);
76
104
  const {
77
- webUrl = "",
78
105
  position = "bottom-right",
79
- theme = "auto",
106
+ theme: initialTheme = "auto",
80
107
  open: autoOpen = false,
81
108
  sessionUrl: initialSessionUrl = "",
109
+ proxyUrl: configProxyUrl = "",
82
110
  lazy = false,
83
111
  hotkey = "ctrl+k",
84
112
  cwd = ""
85
113
  } = config;
114
+ if (configProxyUrl) {
115
+ proxyUrl = configProxyUrl;
116
+ }
117
+ const theme = (0, import_vue.ref)(initialTheme);
86
118
  const isWaitingForSession = (0, import_vue.ref)(!initialSessionUrl);
87
119
  const computedLoading = (0, import_vue.computed)(() => loading.value || isWaitingForSession.value);
88
120
  let servicesStarted = !lazy;
@@ -93,7 +125,7 @@ const App = {
93
125
  };
94
126
  currentSessionId.value = extractSessionId(initialSessionUrl);
95
127
  if (servicesStarted && initialSessionUrl) {
96
- iframeSrc.value = initialSessionUrl;
128
+ iframeSrc.value = toProxyUrl(initialSessionUrl);
97
129
  }
98
130
  try {
99
131
  const stored = sessionStorage.getItem("__opencode_selected_elements__");
@@ -140,7 +172,7 @@ const App = {
140
172
  updatedAt: Date.now()
141
173
  });
142
174
  currentSessionId.value = newSession.id;
143
- iframeSrc.value = `${webUrl}/${utf8ToBase64(cwd)}/session/${newSession.id}`;
175
+ iframeSrc.value = `${proxyUrl}/${utf8ToBase64(cwd)}/session/${newSession.id}`;
144
176
  loadSessions();
145
177
  } catch (e) {
146
178
  showNotification("\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25");
@@ -155,7 +187,7 @@ const App = {
155
187
  if (sessions.value.length > 0) {
156
188
  const nextSession = sessions.value[0];
157
189
  currentSessionId.value = nextSession.id;
158
- iframeSrc.value = `${webUrl}/${utf8ToBase64(cwd)}/session/${nextSession.id}`;
190
+ iframeSrc.value = `${proxyUrl}/${utf8ToBase64(cwd)}/session/${nextSession.id}`;
159
191
  } else {
160
192
  currentSessionId.value = null;
161
193
  iframeSrc.value = "";
@@ -169,7 +201,7 @@ const App = {
169
201
  if (currentSessionId.value === session.id) return;
170
202
  currentSessionId.value = session.id;
171
203
  loading.value = true;
172
- iframeSrc.value = `${webUrl}/${utf8ToBase64(cwd)}/session/${session.id}`;
204
+ iframeSrc.value = `${proxyUrl}/${utf8ToBase64(cwd)}/session/${session.id}`;
173
205
  setTimeout(() => {
174
206
  loading.value = false;
175
207
  }, 500);
@@ -185,7 +217,7 @@ const App = {
185
217
  updateContext(true);
186
218
  } else if (data.type === "SESSION_READY") {
187
219
  if (data.sessionUrl && !iframeSrc.value) {
188
- iframeSrc.value = data.sessionUrl;
220
+ iframeSrc.value = toProxyUrl(data.sessionUrl);
189
221
  currentSessionId.value = extractSessionId(data.sessionUrl);
190
222
  }
191
223
  isWaitingForSession.value = false;
@@ -225,7 +257,7 @@ const App = {
225
257
  if (data.success) {
226
258
  servicesStarted = true;
227
259
  if (data.sessionUrl) {
228
- iframeSrc.value = data.sessionUrl;
260
+ iframeSrc.value = toProxyUrl(data.sessionUrl);
229
261
  currentSessionId.value = extractSessionId(data.sessionUrl);
230
262
  isWaitingForSession.value = false;
231
263
  }
@@ -236,6 +268,8 @@ const App = {
236
268
  }
237
269
  return false;
238
270
  });
271
+ const mainHotkey = parseHotkey(hotkey);
272
+ const selectHotkey = parseHotkey("ctrl+p");
239
273
  (0, import_vue.onMounted)(() => {
240
274
  if (servicesStarted) {
241
275
  loadSessions();
@@ -265,6 +299,25 @@ const App = {
265
299
  if (document.head) {
266
300
  titleObserver.observe(document.head, { childList: true, subtree: true });
267
301
  }
302
+ const handleKeydown = (e) => {
303
+ if (matchHotkey(e, mainHotkey)) {
304
+ e.preventDefault();
305
+ handleToggle(!open.value);
306
+ }
307
+ if (matchHotkey(e, selectHotkey)) {
308
+ e.preventDefault();
309
+ const win = window;
310
+ if (win.__VUE_INSPECTOR__) {
311
+ selectMode.value = !selectMode.value;
312
+ } else {
313
+ showNotification("Vue Inspector \u672A\u52A0\u8F7D\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5143\u7D20\u9009\u62E9\u529F\u80FD");
314
+ }
315
+ }
316
+ };
317
+ document.addEventListener("keydown", handleKeydown);
318
+ return () => {
319
+ document.removeEventListener("keydown", handleKeydown);
320
+ };
268
321
  });
269
322
  const handleToggle = (val) => __async(null, null, function* () {
270
323
  if (lazy && !servicesStarted && val) {
@@ -300,7 +353,7 @@ const App = {
300
353
  return (0, import_vue.h)(import_components.OpenCodeWidget, {
301
354
  ref: widgetRef,
302
355
  position,
303
- theme,
356
+ theme: theme.value,
304
357
  open: open.value,
305
358
  selectMode: selectMode.value,
306
359
  sessionListCollapsed: sessionListCollapsed.value,
@@ -315,10 +368,19 @@ const App = {
315
368
  "onUpdate:open": handleToggle,
316
369
  "onUpdate:selectMode": (val) => {
317
370
  selectMode.value = val;
371
+ if (!val && !open.value) {
372
+ open.value = true;
373
+ }
318
374
  },
319
375
  "onUpdate:sessionListCollapsed": (val) => {
320
376
  sessionListCollapsed.value = val;
321
377
  },
378
+ "onUpdate:theme": (val) => {
379
+ theme.value = val;
380
+ },
381
+ "onToggle-theme": (val) => {
382
+ theme.value = val;
383
+ },
322
384
  "onCreate-session": createSession,
323
385
  "onDelete-session": deleteSession,
324
386
  "onSelect-session": selectSession,