vite-plugin-opencode-assistant 1.1.10 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/es/core/api.d.ts CHANGED
@@ -7,6 +7,8 @@ export declare class OpenCodeAPI {
7
7
  private warmupChromeMcpConfig;
8
8
  private chromeDevtoolsPort;
9
9
  constructor(hostname: string, getPort: () => number, getProxyPort: () => number, warmupChromeMcpConfig?: boolean, chromeDevtoolsPort?: number);
10
+ /** 构建代理 iframe URL(旧版格式:/{base64(projectDir)}/session/{id}) */
11
+ private buildSessionProxyUrl;
10
12
  private createHttpRequest;
11
13
  getSessions(projectDir: string, retries?: number): Promise<SessionInfo[]>;
12
14
  createSession(projectDir: string, retries?: number, title?: string): Promise<SessionInfo>;
package/es/core/api.mjs CHANGED
@@ -60,6 +60,10 @@ class OpenCodeAPI {
60
60
  __publicField(this, "warmupChromeMcpConfig", warmupChromeMcpConfig);
61
61
  __publicField(this, "chromeDevtoolsPort", chromeDevtoolsPort);
62
62
  }
63
+ /** 构建代理 iframe URL(旧版格式:/{base64(projectDir)}/session/{id}) */
64
+ buildSessionProxyUrl(projectDir, sessionId) {
65
+ return `http://${this.hostname}:${this.getProxyPort()}/${base64Encode(projectDir)}/session/${sessionId}`;
66
+ }
63
67
  createHttpRequest(options, body, timeout) {
64
68
  const timer = new PerformanceTimer("HTTP Request", {
65
69
  operation: `${options.method || "GET"} ${options.path}`
@@ -107,7 +111,7 @@ class OpenCodeAPI {
107
111
  path: `/session?directory=${encodeURIComponent(projectDir)}`
108
112
  });
109
113
  const sessionsWithUrl = sessions.map((s) => __spreadProps(__spreadValues({}, s), {
110
- url: s.directory ? `http://${this.hostname}:${this.getProxyPort()}/${base64Encode(s.directory)}/session/${s.id}` : ""
114
+ url: s.directory && s.id ? this.buildSessionProxyUrl(s.directory, s.id) : ""
111
115
  }));
112
116
  timer.end(`Found ${sessions.length} sessions`);
113
117
  return sessionsWithUrl;
@@ -151,7 +155,7 @@ class OpenCodeAPI {
151
155
  requestBody
152
156
  );
153
157
  const sessionWithUrl = __spreadProps(__spreadValues({}, session), {
154
- url: `http://${this.hostname}:${this.getProxyPort()}/${base64Encode(projectDir)}/session/${session.id}`
158
+ url: this.buildSessionProxyUrl(projectDir, session.id)
155
159
  });
156
160
  timer.end(`Created session: ${session.id}`);
157
161
  return sessionWithUrl;
@@ -450,13 +454,13 @@ class OpenCodeAPI {
450
454
  });
451
455
  const matchingSession = sessions.find((s) => s.directory === projectDir);
452
456
  if (matchingSession) {
453
- const url2 = `http://${this.hostname}:${this.getProxyPort()}/${base64Encode(projectDir)}/session/${matchingSession.id}`;
457
+ const url2 = this.buildSessionProxyUrl(projectDir, matchingSession.id);
454
458
  timer.end(`Using existing session: ${matchingSession.id}`);
455
459
  return url2;
456
460
  }
457
461
  log.debug("Creating new session...", { projectDir });
458
462
  const newSession = yield this.createSession(projectDir);
459
- const url = `http://${this.hostname}:${this.getProxyPort()}/${base64Encode(projectDir)}/session/${newSession.id}`;
463
+ const url = this.buildSessionProxyUrl(projectDir, newSession.id);
460
464
  timer.end(`Created new session: ${newSession.id}`);
461
465
  return url;
462
466
  });
@@ -9,8 +9,6 @@ export interface ProxyServerOptions {
9
9
  settings?: OpenCodeSettings;
10
10
  /** 绑定地址,需与端口检查使用的地址族一致,避免 IPv4/IPv6 不匹配 */
11
11
  hostname?: string;
12
- /** 项目目录,用于路径重写(代理 /session/* 请求时添加 base64 目录前缀) */
13
- projectDir?: string;
14
12
  }
15
13
  export interface ProxyServerResult {
16
14
  server: http.Server;
@@ -23,8 +23,7 @@ import {
23
23
  DEFAULT_OPENCODE_SETTINGS,
24
24
  OPENCODE_STORAGE_KEYS,
25
25
  WIDGET_MSG,
26
- BRIDGE_SCRIPT_PATH,
27
- base64Encode
26
+ BRIDGE_SCRIPT_PATH
28
27
  } from "@vite-plugin-opencode-assistant/shared";
29
28
  const log = createLogger("ProxyServer");
30
29
  function mergeSettings(defaultSettings, userSettings) {
@@ -52,6 +51,25 @@ function generateBridgeScript(options) {
52
51
  const mergedSettings = mergeSettings(DEFAULT_OPENCODE_SETTINGS, settings);
53
52
  return `
54
53
  (function() {
54
+ // \u7ACB\u5373\u6E05\u7406\u6B8B\u7559\u7684 session tabs \u5B58\u50A8\uFF0C\u5FC5\u987B\u5728 DOMContentLoaded \u4E4B\u524D\u6267\u884C
55
+ // \u5426\u5219 OpenCode \u6A21\u5757\u811A\u672C\u4F1A\u5148\u8BFB\u53D6 localStorage \u5E76\u53D1\u51FA 404 \u8BF7\u6C42
56
+ (function cleanupTabsStorage() {
57
+ try {
58
+ var keysToRemove = [];
59
+ for (var i = 0; i < localStorage.length; i++) {
60
+ var key = localStorage.key(i);
61
+ if (key && (key.indexOf('opencode.window') === 0 || key.indexOf('opencode.workspace') === 0)) {
62
+ keysToRemove.push(key);
63
+ }
64
+ }
65
+ for (var j = 0; j < keysToRemove.length; j++) {
66
+ localStorage.removeItem(keysToRemove[j]);
67
+ }
68
+ } catch (e) {
69
+ // localStorage \u4E0D\u53EF\u7528\u65F6\u5FFD\u7565
70
+ }
71
+ })();
72
+
55
73
  // === \u52AB\u6301 matchMedia\uFF0C\u5F3A\u5236\u684C\u9762\u7AEF\u5E03\u5C40\u4EE5\u6E32\u67D3\u5BA1\u67E5\u9762\u677F ===
56
74
  // \u53EA\u52AB\u6301 opencode \u5224\u65AD\u684C\u9762\u7AEF\u7684\u5A92\u4F53\u67E5\u8BE2 (min-width: 768px)\uFF0C\u4E0D\u5F71\u54CD\u5176\u4ED6\u67E5\u8BE2
57
75
  (function() {
@@ -680,7 +698,6 @@ function startProxyServer(targetUrl, port, options = {}) {
680
698
  return new Promise((resolve, reject) => {
681
699
  const target = new URL(targetUrl);
682
700
  const bridgeScript = generateBridgeScript(options);
683
- const base64Dir = options.projectDir ? base64Encode(options.projectDir) : "";
684
701
  const server = http.createServer((req, res) => {
685
702
  if (req.url === BRIDGE_SCRIPT_PATH) {
686
703
  const body = bridgeScript;
@@ -692,14 +709,10 @@ function startProxyServer(targetUrl, port, options = {}) {
692
709
  res.end(body);
693
710
  return;
694
711
  }
695
- let reqPath = req.url || "/";
696
- if (base64Dir && reqPath.startsWith("/session/") && !reqPath.startsWith(`/${base64Dir}/`)) {
697
- reqPath = `/${base64Dir}${reqPath}`;
698
- }
699
712
  const requestOptions = {
700
713
  hostname: target.hostname,
701
714
  port: target.port,
702
- path: reqPath,
715
+ path: req.url,
703
716
  method: req.method,
704
717
  headers: __spreadProps(__spreadValues({}, req.headers), {
705
718
  host: target.host,
@@ -98,7 +98,7 @@ class OpenCodeService {
98
98
  return this.startPromise;
99
99
  }
100
100
  this.startPromise = (() => __async(this, null, function* () {
101
- var _a, _b, _c, _d, _e, _f, _g;
101
+ var _a, _b, _c, _d, _e;
102
102
  const timer = log.timer("startServices", {
103
103
  corsOrigins,
104
104
  contextApiUrl,
@@ -205,8 +205,7 @@ Please install OpenCode first:
205
205
  theme: this.config.theme,
206
206
  language: this.config.language,
207
207
  settings: this.config.settings,
208
- hostname: this.config.hostname,
209
- projectDir: (_f = this.workspaceRoot) != null ? _f : void 0
208
+ hostname: this.config.hostname
210
209
  });
211
210
  this.proxyServer = result.server;
212
211
  if (result.actualPort !== this.actualProxyPort) {
@@ -225,8 +224,7 @@ Please install OpenCode first:
225
224
  theme: this.config.theme,
226
225
  language: this.config.language,
227
226
  settings: this.config.settings,
228
- hostname: this.config.hostname,
229
- projectDir: (_g = this.workspaceRoot) != null ? _g : void 0
227
+ hostname: this.config.hostname
230
228
  });
231
229
  this.proxyServer = result.server;
232
230
  this.actualProxyPort = result.actualPort;
package/lib/core/api.cjs CHANGED
@@ -81,6 +81,10 @@ class OpenCodeAPI {
81
81
  __publicField(this, "warmupChromeMcpConfig", warmupChromeMcpConfig);
82
82
  __publicField(this, "chromeDevtoolsPort", chromeDevtoolsPort);
83
83
  }
84
+ /** 构建代理 iframe URL(旧版格式:/{base64(projectDir)}/session/{id}) */
85
+ buildSessionProxyUrl(projectDir, sessionId) {
86
+ return `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${sessionId}`;
87
+ }
84
88
  createHttpRequest(options, body, timeout) {
85
89
  const timer = new import_node.PerformanceTimer("HTTP Request", {
86
90
  operation: `${options.method || "GET"} ${options.path}`
@@ -128,7 +132,7 @@ class OpenCodeAPI {
128
132
  path: `/session?directory=${encodeURIComponent(projectDir)}`
129
133
  });
130
134
  const sessionsWithUrl = sessions.map((s) => __spreadProps(__spreadValues({}, s), {
131
- url: s.directory ? `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(s.directory)}/session/${s.id}` : ""
135
+ url: s.directory && s.id ? this.buildSessionProxyUrl(s.directory, s.id) : ""
132
136
  }));
133
137
  timer.end(`Found ${sessions.length} sessions`);
134
138
  return sessionsWithUrl;
@@ -172,7 +176,7 @@ class OpenCodeAPI {
172
176
  requestBody
173
177
  );
174
178
  const sessionWithUrl = __spreadProps(__spreadValues({}, session), {
175
- url: `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${session.id}`
179
+ url: this.buildSessionProxyUrl(projectDir, session.id)
176
180
  });
177
181
  timer.end(`Created session: ${session.id}`);
178
182
  return sessionWithUrl;
@@ -471,13 +475,13 @@ class OpenCodeAPI {
471
475
  });
472
476
  const matchingSession = sessions.find((s) => s.directory === projectDir);
473
477
  if (matchingSession) {
474
- const url2 = `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${matchingSession.id}`;
478
+ const url2 = this.buildSessionProxyUrl(projectDir, matchingSession.id);
475
479
  timer.end(`Using existing session: ${matchingSession.id}`);
476
480
  return url2;
477
481
  }
478
482
  log.debug("Creating new session...", { projectDir });
479
483
  const newSession = yield this.createSession(projectDir);
480
- const url = `http://${this.hostname}:${this.getProxyPort()}/${(0, import_shared.base64Encode)(projectDir)}/session/${newSession.id}`;
484
+ const url = this.buildSessionProxyUrl(projectDir, newSession.id);
481
485
  timer.end(`Created new session: ${newSession.id}`);
482
486
  return url;
483
487
  });
package/lib/core/api.d.ts CHANGED
@@ -7,6 +7,8 @@ export declare class OpenCodeAPI {
7
7
  private warmupChromeMcpConfig;
8
8
  private chromeDevtoolsPort;
9
9
  constructor(hostname: string, getPort: () => number, getProxyPort: () => number, warmupChromeMcpConfig?: boolean, chromeDevtoolsPort?: number);
10
+ /** 构建代理 iframe URL(旧版格式:/{base64(projectDir)}/session/{id}) */
11
+ private buildSessionProxyUrl;
10
12
  private createHttpRequest;
11
13
  getSessions(projectDir: string, retries?: number): Promise<SessionInfo[]>;
12
14
  createSession(projectDir: string, retries?: number, title?: string): Promise<SessionInfo>;
@@ -75,6 +75,25 @@ function generateBridgeScript(options) {
75
75
  const mergedSettings = mergeSettings(import_shared.DEFAULT_OPENCODE_SETTINGS, settings);
76
76
  return `
77
77
  (function() {
78
+ // \u7ACB\u5373\u6E05\u7406\u6B8B\u7559\u7684 session tabs \u5B58\u50A8\uFF0C\u5FC5\u987B\u5728 DOMContentLoaded \u4E4B\u524D\u6267\u884C
79
+ // \u5426\u5219 OpenCode \u6A21\u5757\u811A\u672C\u4F1A\u5148\u8BFB\u53D6 localStorage \u5E76\u53D1\u51FA 404 \u8BF7\u6C42
80
+ (function cleanupTabsStorage() {
81
+ try {
82
+ var keysToRemove = [];
83
+ for (var i = 0; i < localStorage.length; i++) {
84
+ var key = localStorage.key(i);
85
+ if (key && (key.indexOf('opencode.window') === 0 || key.indexOf('opencode.workspace') === 0)) {
86
+ keysToRemove.push(key);
87
+ }
88
+ }
89
+ for (var j = 0; j < keysToRemove.length; j++) {
90
+ localStorage.removeItem(keysToRemove[j]);
91
+ }
92
+ } catch (e) {
93
+ // localStorage \u4E0D\u53EF\u7528\u65F6\u5FFD\u7565
94
+ }
95
+ })();
96
+
78
97
  // === \u52AB\u6301 matchMedia\uFF0C\u5F3A\u5236\u684C\u9762\u7AEF\u5E03\u5C40\u4EE5\u6E32\u67D3\u5BA1\u67E5\u9762\u677F ===
79
98
  // \u53EA\u52AB\u6301 opencode \u5224\u65AD\u684C\u9762\u7AEF\u7684\u5A92\u4F53\u67E5\u8BE2 (min-width: 768px)\uFF0C\u4E0D\u5F71\u54CD\u5176\u4ED6\u67E5\u8BE2
80
99
  (function() {
@@ -703,7 +722,6 @@ function startProxyServer(targetUrl, port, options = {}) {
703
722
  return new Promise((resolve, reject) => {
704
723
  const target = new URL(targetUrl);
705
724
  const bridgeScript = generateBridgeScript(options);
706
- const base64Dir = options.projectDir ? (0, import_shared.base64Encode)(options.projectDir) : "";
707
725
  const server = import_http.default.createServer((req, res) => {
708
726
  if (req.url === import_shared.BRIDGE_SCRIPT_PATH) {
709
727
  const body = bridgeScript;
@@ -715,14 +733,10 @@ function startProxyServer(targetUrl, port, options = {}) {
715
733
  res.end(body);
716
734
  return;
717
735
  }
718
- let reqPath = req.url || "/";
719
- if (base64Dir && reqPath.startsWith("/session/") && !reqPath.startsWith(`/${base64Dir}/`)) {
720
- reqPath = `/${base64Dir}${reqPath}`;
721
- }
722
736
  const requestOptions = {
723
737
  hostname: target.hostname,
724
738
  port: target.port,
725
- path: reqPath,
739
+ path: req.url,
726
740
  method: req.method,
727
741
  headers: __spreadProps(__spreadValues({}, req.headers), {
728
742
  host: target.host,
@@ -9,8 +9,6 @@ export interface ProxyServerOptions {
9
9
  settings?: OpenCodeSettings;
10
10
  /** 绑定地址,需与端口检查使用的地址族一致,避免 IPv4/IPv6 不匹配 */
11
11
  hostname?: string;
12
- /** 项目目录,用于路径重写(代理 /session/* 请求时添加 base64 目录前缀) */
13
- projectDir?: string;
14
12
  }
15
13
  export interface ProxyServerResult {
16
14
  server: http.Server;
@@ -106,7 +106,7 @@ class OpenCodeService {
106
106
  return this.startPromise;
107
107
  }
108
108
  this.startPromise = (() => __async(this, null, function* () {
109
- var _a, _b, _c, _d, _e, _f, _g;
109
+ var _a, _b, _c, _d, _e;
110
110
  const timer = log.timer("startServices", {
111
111
  corsOrigins,
112
112
  contextApiUrl,
@@ -213,8 +213,7 @@ Please install OpenCode first:
213
213
  theme: this.config.theme,
214
214
  language: this.config.language,
215
215
  settings: this.config.settings,
216
- hostname: this.config.hostname,
217
- projectDir: (_f = this.workspaceRoot) != null ? _f : void 0
216
+ hostname: this.config.hostname
218
217
  });
219
218
  this.proxyServer = result.server;
220
219
  if (result.actualPort !== this.actualProxyPort) {
@@ -233,8 +232,7 @@ Please install OpenCode first:
233
232
  theme: this.config.theme,
234
233
  language: this.config.language,
235
234
  settings: this.config.settings,
236
- hostname: this.config.hostname,
237
- projectDir: (_g = this.workspaceRoot) != null ? _g : void 0
235
+ hostname: this.config.hostname
238
236
  });
239
237
  this.proxyServer = result.server;
240
238
  this.actualProxyPort = result.actualPort;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-opencode-assistant",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "description": "Embed OpenCode Web UI in your Vite dev server for real-time code modification and preview",
5
5
  "type": "module",
6
6
  "main": "lib/index.cjs",
@@ -37,15 +37,15 @@
37
37
  "dependencies": {
38
38
  "unplugin-vue-inspector": "^3.0.0",
39
39
  "execa": "^9.6.1",
40
- "@vite-plugin-opencode-assistant/opencode": "1.1.10",
41
- "@vite-plugin-opencode-assistant/shared": "1.1.10",
42
- "@vite-plugin-opencode-assistant/components": "1.1.10"
40
+ "@vite-plugin-opencode-assistant/components": "1.1.12",
41
+ "@vite-plugin-opencode-assistant/opencode": "1.1.12",
42
+ "@vite-plugin-opencode-assistant/shared": "1.1.12"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "vite": ">=5.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@vite-plugin-opencode-assistant/client": "1.1.10"
48
+ "@vite-plugin-opencode-assistant/client": "1.1.12"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "pagoda-cli build && vite build -c vite.client.config.ts",