@aipanel/provider-opencode 1.2.0-beta.0

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.
@@ -0,0 +1,683 @@
1
+ import { DEFAULT_OPENCODE_SETTINGS, OPENCODE_STORAGE_KEYS } from "./constants.js";
2
+ import { WIDGET_MSG } from "@aipanel/core";
3
+ function mergeSettings(defaultSettings, userSettings) {
4
+ if (!userSettings) return defaultSettings;
5
+ const result = { ...defaultSettings };
6
+ if (userSettings.general) {
7
+ result.general = { ...defaultSettings.general, ...userSettings.general };
8
+ }
9
+ if (userSettings.appearance) {
10
+ result.appearance = userSettings.appearance;
11
+ }
12
+ if (userSettings.permissions) {
13
+ result.permissions = userSettings.permissions;
14
+ }
15
+ if (userSettings.notifications) {
16
+ result.notifications = userSettings.notifications;
17
+ }
18
+ if (userSettings.sounds) {
19
+ result.sounds = userSettings.sounds;
20
+ }
21
+ return result;
22
+ }
23
+ function generateBridgeScript(options = {}) {
24
+ const { theme = "auto", language, settings } = options;
25
+ const mergedSettings = mergeSettings(DEFAULT_OPENCODE_SETTINGS, settings);
26
+ return `
27
+ (function() {
28
+ // \u7ACB\u5373\u6E05\u7406\u6B8B\u7559\u7684 session tabs \u5B58\u50A8\uFF0C\u5FC5\u987B\u5728 DOMContentLoaded \u4E4B\u524D\u6267\u884C
29
+ // \u5426\u5219 Web UI \u6A21\u5757\u811A\u672C\u4F1A\u5148\u8BFB\u53D6 localStorage \u5E76\u53D1\u51FA 404 \u8BF7\u6C42
30
+ (function cleanupTabsStorage() {
31
+ try {
32
+ var keysToRemove = [];
33
+ for (var i = 0; i < localStorage.length; i++) {
34
+ var key = localStorage.key(i);
35
+ if (key && (key.indexOf('opencode.window') === 0 || key.indexOf('opencode.workspace') === 0)) {
36
+ keysToRemove.push(key);
37
+ }
38
+ }
39
+ for (var j = 0; j < keysToRemove.length; j++) {
40
+ localStorage.removeItem(keysToRemove[j]);
41
+ }
42
+ } catch (e) {
43
+ // localStorage \u4E0D\u53EF\u7528\u65F6\u5FFD\u7565
44
+ }
45
+ })();
46
+
47
+ // === \u52AB\u6301 matchMedia\uFF0C\u5F3A\u5236\u684C\u9762\u7AEF\u5E03\u5C40\u4EE5\u6E32\u67D3\u5BA1\u67E5\u9762\u677F ===
48
+ // \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
49
+ (function() {
50
+ var _origMatchMedia = window.matchMedia.bind(window);
51
+ var DESKTOP_QUERY = '(min-width: 768px)';
52
+ window.matchMedia = function(query) {
53
+ var result = _origMatchMedia(query);
54
+ if (query === DESKTOP_QUERY) {
55
+ return {
56
+ get matches() { return true; },
57
+ get media() { return result.media; },
58
+ onchange: null,
59
+ addListener: function(cb) { result.addListener(cb); },
60
+ removeListener: function(cb) { result.removeListener(cb); },
61
+ addEventListener: function(t, cb) { result.addEventListener(t, cb); },
62
+ removeEventListener: function(t, cb) { result.removeEventListener(t, cb); },
63
+ dispatchEvent: function(e) { return result.dispatchEvent(e); }
64
+ };
65
+ }
66
+ return result;
67
+ };
68
+ })();
69
+
70
+ const STORAGE_KEYS = ${JSON.stringify(OPENCODE_STORAGE_KEYS)};
71
+ const THEME_KEY = STORAGE_KEYS.COLOR_SCHEME;
72
+ const SETTINGS_KEY = STORAGE_KEYS.SETTINGS;
73
+
74
+ // === \u521D\u59CB\u5316\u914D\u7F6E ===
75
+ const initialConfig = {
76
+ theme: ${JSON.stringify(theme)},
77
+ language: ${JSON.stringify(language || null)},
78
+ settings: ${JSON.stringify(mergedSettings)}
79
+ };
80
+
81
+ // \u521D\u59CB\u5316\u4E3B\u9898
82
+ if (initialConfig.theme && initialConfig.theme !== "auto") {
83
+ localStorage.setItem(THEME_KEY, initialConfig.theme);
84
+ document.documentElement.setAttribute("data-color-scheme", initialConfig.theme);
85
+ }
86
+
87
+ // \u521D\u59CB\u5316\u8BBE\u7F6E
88
+ // \u6DF1\u5EA6\u5408\u5E76 initialConfig.settings \u5230\u5DF2\u6709\u914D\u7F6E\uFF1A\u53EA\u8986\u76D6\u63D2\u4EF6\u58F0\u660E\u7684\u5B57\u6BB5\uFF0C
89
+ // web \u81EA\u5DF1\u7BA1\u7406\u7684\u5176\u4ED6\u914D\u7F6E\u4E0D\u53D7\u5F71\u54CD
90
+ function deepMerge(target, source) {
91
+ for (var key in source) {
92
+ if (!{}.hasOwnProperty.call(source, key)) continue;
93
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
94
+ if (!target[key] || typeof target[key] !== "object") target[key] = {};
95
+ deepMerge(target[key], source[key]);
96
+ } else {
97
+ target[key] = source[key];
98
+ }
99
+ }
100
+ return target;
101
+ }
102
+
103
+ try {
104
+ var existing = JSON.parse(localStorage.getItem(SETTINGS_KEY) || "{}");
105
+ localStorage.setItem(SETTINGS_KEY, JSON.stringify(deepMerge(existing, initialConfig.settings)));
106
+ } catch {
107
+ localStorage.setItem(SETTINGS_KEY, JSON.stringify(initialConfig.settings));
108
+ }
109
+
110
+ // === \u4E3B\u9898\u540C\u6B65\u51FD\u6570 ===
111
+ function getTheme() {
112
+ try {
113
+ return localStorage.getItem(THEME_KEY) || "system";
114
+ } catch {
115
+ return "system";
116
+ }
117
+ }
118
+
119
+ function setTheme(theme) {
120
+ try {
121
+ const oldTheme = localStorage.getItem(THEME_KEY);
122
+ localStorage.setItem(THEME_KEY, theme);
123
+ document.documentElement.setAttribute('data-color-scheme', theme);
124
+
125
+ if (oldTheme !== theme) {
126
+ window.dispatchEvent(new StorageEvent('storage', {
127
+ key: THEME_KEY,
128
+ oldValue: oldTheme,
129
+ newValue: theme,
130
+ url: window.location.href
131
+ }));
132
+ }
133
+ } catch {
134
+ // ignore
135
+ }
136
+ }
137
+
138
+ // === \u9009\u62E9\u6A21\u5F0F\u72B6\u6001 ===
139
+ let isInSelectMode = false;
140
+
141
+ function handleSelectModeChange(selectMode) {
142
+ isInSelectMode = selectMode;
143
+ }
144
+
145
+ // === \u6D88\u606F\u76D1\u542C ===
146
+ window.addEventListener("message", function(event) {
147
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.SET_THEME)}) {
148
+ setTheme(event.data.theme);
149
+ }
150
+
151
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.INSERT_FILE_PART)}) {
152
+ insertFilePart(event.data.element);
153
+ }
154
+
155
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.MINIMIZE_STATE)}) {
156
+ handleMinimizeStateChange(event.data.minimized);
157
+ }
158
+
159
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.PROMPT_DOCK_VISIBILITY)}) {
160
+ handlePromptDockVisibilityChange(event.data.visible);
161
+ }
162
+
163
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.SELECT_MODE_CHANGE)}) {
164
+ handleSelectModeChange(event.data.selectMode);
165
+ }
166
+
167
+ if (event.data && event.data.type === ${JSON.stringify(WIDGET_MSG.REVIEW_PANEL_TOGGLE)}) {
168
+ handleReviewPanelToggle(event.data.visible);
169
+ }
170
+ });
171
+
172
+ // === \u952E\u76D8\u4E8B\u4EF6\u8F6C\u53D1\uFF08\u7528\u4E8E\u9000\u51FA\u9009\u62E9\u6A21\u5F0F\uFF09 ===
173
+ window.addEventListener("keydown", function(event) {
174
+ if (event.key === "Escape" || (event.ctrlKey && event.key.toLowerCase() === "p")) {
175
+ // \u9009\u62E9\u6A21\u5F0F\u5F00\u542F\u65F6\uFF0C\u4F18\u5148\u9000\u51FA\u9009\u62E9\u6A21\u5F0F\uFF0C\u963B\u6B62 iframe \u5185\u7684\u5176\u4ED6 ESC \u5904\u7406\uFF08\u5982\u4E2D\u6B62\u4F1A\u8BDD\uFF09
176
+ if (isInSelectMode) {
177
+ event.preventDefault();
178
+ event.stopPropagation();
179
+ if (window.parent !== window) {
180
+ window.parent.postMessage({
181
+ type: ${JSON.stringify(WIDGET_MSG.KEYDOWN)},
182
+ key: event.key,
183
+ ctrlKey: event.ctrlKey,
184
+ metaKey: event.metaKey,
185
+ shiftKey: event.shiftKey,
186
+ altKey: event.altKey
187
+ }, "*");
188
+ }
189
+ return;
190
+ }
191
+
192
+
193
+ if (window.parent !== window) {
194
+ window.parent.postMessage({
195
+ type: ${JSON.stringify(WIDGET_MSG.KEYDOWN)},
196
+ key: event.key,
197
+ ctrlKey: event.ctrlKey,
198
+ metaKey: event.metaKey,
199
+ shiftKey: event.shiftKey,
200
+ altKey: event.altKey
201
+ }, "*");
202
+ }
203
+ }
204
+ }, true);
205
+
206
+ // === \u6700\u5C0F\u5316\u72B6\u6001\u6837\u5F0F ===
207
+ const minimizeStyles = \`
208
+ #root header {
209
+ display: none !important;
210
+ }
211
+ .opencode-minimized [data-dock-surface="tray"]:not([data-slot="permission-footer"]) {
212
+ display: none !important;
213
+ }
214
+ .opencode-minimized [data-slot="session-turn-list"] {
215
+ padding-bottom: 10px !important;
216
+ }
217
+ .opencode-prompt-dock-hidden [data-component="session-prompt-dock"]:not(:has([data-kind="permission"])) {
218
+ display: none !important;
219
+ }
220
+ button[data-slot="dropdown-menu-trigger"][icon="dot-grid"] {
221
+ display: none !important;
222
+ }
223
+ [data-component="icon-button-v2"][aria-label="\u66F4\u591A\u9009\u9879"],
224
+ [data-component="icon-button-v2"][aria-label="More options"] {
225
+ display: none !important;
226
+ }
227
+ \`;
228
+
229
+ // === \u901A\u7528\u6837\u5F0F ===
230
+ const generalStyles = \`
231
+ /* \u9690\u85CF\u4F1A\u8BDD\u9762\u677F\u6807\u9898\u53F3\u4FA7\u6309\u94AE\u533A */
232
+ [data-session-title] .shrink-0 {
233
+ display: none !important;
234
+ }
235
+ \`;
236
+
237
+ // === \u5BA1\u67E5\u9762\u677F\u8986\u76D6\u6837\u5F0F ===
238
+ // \u5BA1\u67E5\u9762\u677F\u5168\u5C4F\uFF0C\u4F1A\u8BDD\u9762\u677F\u6D6E\u5728\u53F3\u4E0B\u89D2\uFF08\u7C7B\u4F3C\u63D2\u4EF6\u6700\u5C0F\u5316\u72B6\u6001\uFF09
239
+ const reviewPanelStyles = \`
240
+ .opencode-review-panel-overlay [data-ref="panel-row"] {
241
+ flex-direction: column !important;
242
+ gap: 8px !important;
243
+ padding: 8px !important;
244
+ }
245
+
246
+ /* \u5BA1\u67E5\u9762\u677F\u5360\u6EE1\u5269\u4F59\u7A7A\u95F4 */
247
+ .opencode-review-panel-overlay [data-ref="side-panel-container"] {
248
+ flex: 1 !important;
249
+ width: 100% !important;
250
+ transition: none !important;
251
+ min-height: 0 !important;
252
+ }
253
+
254
+ /* \u4F1A\u8BDD\u9762\u677F\u6D6E\u5728\u53F3\u4E0B\u89D2 */
255
+ .opencode-review-panel-overlay [data-ref="session-panel"] {
256
+ position: fixed !important;
257
+ bottom: 16px !important;
258
+ right: 16px !important;
259
+ width: 380px !important;
260
+ max-height: 70vh !important;
261
+ display: flex !important;
262
+ flex-direction: column !important;
263
+ z-index: 600 !important;
264
+ border-radius: 12px !important;
265
+ box-shadow:
266
+ 0 0 0 1px rgba(0, 0, 0, 0.04),
267
+ 0 2px 4px rgba(0, 0, 0, 0.04),
268
+ 0 8px 16px rgba(0, 0, 0, 0.08),
269
+ 0 16px 40px rgba(0, 0, 0, 0.12) !important;
270
+ overflow: hidden !important;
271
+ transition: none;
272
+ }
273
+ .opencode-review-panel-overlay [data-ref="session-panel"] * {
274
+ max-width: none !important;
275
+ }
276
+
277
+ /* \u4F1A\u8BDD\u6D6E\u7A97\u5185\u5C42\u80CC\u666F\u62AC\u9AD8\uFF0C\u4E0E\u5BA1\u67E5\u9762\u677F\u5E95\u8272\u5F62\u6210\u5C42\u6B21 */
278
+ .opencode-review-panel-overlay [data-ref="session-panel"] [class*="bg-v2-background-bg-base"] {
279
+ background: color-mix(in srgb, var(--v2-background-bg-base, #1e1e1e) 96%, #fff) !important;
280
+ }
281
+
282
+ /* \u9690\u85CF\u4F1A\u8BDD\u9762\u677F\u5185\u7684\u6807\u9898 */
283
+ .opencode-review-panel-overlay [data-ref="session-panel"] [data-session-title] {
284
+ display: none !important;
285
+ }
286
+
287
+
288
+
289
+ /* \u9690\u85CF\u6D6E\u52A8\u4F1A\u8BDD\uFF08\u7528 visibility+opacity \u907F\u514D\u5207\u6362\u95EA\u70C1\uFF09 */
290
+ .opencode-review-panel-overlay.hide-chat [data-ref="session-panel"] {
291
+ visibility: hidden !important;
292
+ opacity: 0 !important;
293
+ pointer-events: none !important;
294
+ }
295
+
296
+ /* \u5BA1\u67E5\u9762\u677F\u53F3\u4E0A\u89D2\u60AC\u6D6E\u5207\u6362\u6309\u94AE */
297
+ .opencode-chat-toggle-btn {
298
+ position: fixed !important;
299
+ top: 16px !important;
300
+ right: 16px !important;
301
+ z-index: 700 !important;
302
+ width: 36px !important;
303
+ height: 36px !important;
304
+ border-radius: 8px !important;
305
+ border: none !important;
306
+ background: var(--v2-background-bg-base, #1e1e1e) !important;
307
+ color: var(--v2-icon-icon-base, #ccc) !important;
308
+ cursor: pointer !important;
309
+ display: flex !important;
310
+ align-items: center !important;
311
+ justify-content: center !important;
312
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
313
+ transition: background 0.15s !important;
314
+ }
315
+ .opencode-chat-toggle-btn:hover {
316
+ background: var(--v2-overlay-simple-overlay-hover, #333) !important;
317
+ }
318
+ .opencode-chat-toggle-btn.active {
319
+ background: var(--v2-overlay-simple-overlay-pressed, #444) !important;
320
+ }
321
+ \`;
322
+
323
+ function injectMinimizeStyles() {
324
+ if (document.getElementById('opencode-minimize-styles')) return;
325
+ const style = document.createElement('style');
326
+ style.id = 'opencode-minimize-styles';
327
+ style.textContent = minimizeStyles;
328
+ document.head.appendChild(style);
329
+ }
330
+
331
+ function injectReviewPanelStyles() {
332
+ if (document.getElementById('opencode-review-panel-styles')) return;
333
+ const style = document.createElement('style');
334
+ style.id = 'opencode-review-panel-styles';
335
+ style.textContent = reviewPanelStyles;
336
+ document.head.appendChild(style);
337
+ }
338
+
339
+ function injectGeneralStyles() {
340
+ if (document.getElementById('opencode-general-styles')) return;
341
+ const style = document.createElement('style');
342
+ style.id = 'opencode-general-styles';
343
+ style.textContent = generalStyles;
344
+ document.head.appendChild(style);
345
+ }
346
+
347
+ // === \u6700\u5C0F\u5316\u72B6\u6001\u5904\u7406 ===
348
+ let savedMinimizedState = null;
349
+ let savedPromptDockVisibleState = null;
350
+ let savedReviewPanelState = null;
351
+
352
+ function handleMinimizeStateChange(minimized) {
353
+ savedMinimizedState = minimized;
354
+ if (minimized) {
355
+ document.documentElement.classList.add('opencode-minimized');
356
+ } else {
357
+ document.documentElement.classList.remove('opencode-minimized');
358
+ }
359
+ }
360
+
361
+ // === \u5BF9\u8BDD\u6846\u663E\u793A\u72B6\u6001\u5904\u7406 ===
362
+ function handlePromptDockVisibilityChange(visible) {
363
+ savedPromptDockVisibleState = visible;
364
+ if (!visible) {
365
+ document.documentElement.classList.add('opencode-prompt-dock-hidden');
366
+ } else {
367
+ document.documentElement.classList.remove('opencode-prompt-dock-hidden');
368
+ }
369
+ }
370
+
371
+ // === \u5BA1\u67E5\u9762\u677F\u8986\u76D6\u72B6\u6001\u5904\u7406 ===
372
+ // \u7B56\u7565\uFF1A\u7EAF CSS class \u63A7\u5236\u3002\u9996\u6B21\u6253\u5F00\u65F6\u7ED9\u5173\u952E\u5143\u7D20\u6253 data-ref \u6807\u8BB0\uFF0C
373
+ // \u540E\u7EED\u53EA\u9700 toggle class\u3002\u5173\u95ED\u65F6\u79FB\u9664 class\uFF0CCSS \u89C4\u5219\u81EA\u52A8\u6062\u590D\u539F\u59CB\u5E03\u5C40\u3002
374
+ // \u4E0D\u4FEE\u6539\u4EFB\u4F55 inline style\uFF0C\u907F\u514D\u4FDD\u5B58/\u6062\u590D\u7684\u65F6\u673A\u548C DOM \u5F15\u7528\u95EE\u9898\u3002
375
+
376
+ function ensureReviewPanelRefs() {
377
+ var reviewPanel = document.querySelector('[data-component="session-review-v2"]')
378
+ || document.querySelector('[data-component="session-review"]');
379
+ if (!reviewPanel) return false;
380
+
381
+ // \u5411\u4E0A\u904D\u5386\u627E\u5230 panelRow
382
+ var panelRow = reviewPanel.parentElement;
383
+ while (panelRow) {
384
+ var cls = panelRow.className || '';
385
+ if (cls.indexOf('flex-col') !== -1 && cls.indexOf('md:flex-row') !== -1) break;
386
+ panelRow = panelRow.parentElement;
387
+ }
388
+ if (!panelRow) return false;
389
+ panelRow.setAttribute('data-ref', 'panel-row');
390
+
391
+ // \u627E\u5230\u4F1A\u8BDD\u9762\u677F\u548C\u4FA7\u8FB9\u9762\u677F\u5BB9\u5668
392
+ for (var i = 0; i < panelRow.children.length; i++) {
393
+ var child = panelRow.children[i];
394
+ if (child.nodeType !== 1) continue;
395
+ var c = child.className || '';
396
+ if (c.indexOf('@container') !== -1) {
397
+ child.setAttribute('data-ref', 'session-panel');
398
+ } else if (c.indexOf('min-w-0') !== -1 && c.indexOf('flex-col') !== -1) {
399
+ child.setAttribute('data-ref', 'side-panel-container');
400
+ }
401
+ }
402
+
403
+ return true;
404
+ }
405
+
406
+ function injectChatToggleBtn() {
407
+ if (document.getElementById('opencode-chat-toggle-btn')) return;
408
+ var btn = document.createElement('button');
409
+ btn.id = 'opencode-chat-toggle-btn';
410
+ btn.className = 'opencode-chat-toggle-btn';
411
+ btn.innerHTML = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>';
412
+ btn.title = '\u5C55\u5F00\u804A\u5929\u9762\u677F';
413
+ // \u4ECE localStorage \u6062\u590D\u4E0A\u6B21\u7684\u5C55\u5F00/\u6536\u8D77\u72B6\u6001\uFF0C\u9ED8\u8BA4\u6536\u8D77
414
+ var chatVisible = localStorage.getItem('opencode-review-chat-visible');
415
+ if (chatVisible === 'true') {
416
+ document.documentElement.classList.remove('hide-chat');
417
+ btn.classList.add('active');
418
+ btn.title = '\u9690\u85CF\u804A\u5929\u9762\u677F';
419
+ } else {
420
+ document.documentElement.classList.add('hide-chat');
421
+ }
422
+ btn.onclick = function() {
423
+ document.documentElement.classList.toggle('hide-chat');
424
+ btn.classList.toggle('active');
425
+ var isVisible = btn.classList.contains('active');
426
+ btn.title = isVisible ? '\u9690\u85CF\u804A\u5929\u9762\u677F' : '\u5C55\u5F00\u804A\u5929\u9762\u677F';
427
+ localStorage.setItem('opencode-review-chat-visible', isVisible ? 'true' : 'false');
428
+ };
429
+ document.body.appendChild(btn);
430
+ }
431
+
432
+ function removeChatToggleBtn() {
433
+ var btn = document.getElementById('opencode-chat-toggle-btn');
434
+ if (btn) btn.remove();
435
+ }
436
+
437
+ function handleReviewPanelToggle(visible) {
438
+ // \u5982\u679C\u72B6\u6001\u6CA1\u6709\u53D8\u5316\uFF0C\u8DF3\u8FC7\uFF08\u907F\u514D MutationObserver \u91CD\u590D\u89E6\u53D1\uFF09
439
+ if (savedReviewPanelState === visible) return;
440
+ savedReviewPanelState = visible;
441
+
442
+ if (visible) {
443
+ // \u5148\u70B9\u51FB\u539F\u751F\u6309\u94AE\u6253\u5F00\u9762\u677F\uFF0C\u8BA9 DOM \u6E32\u67D3\u51FA\u6765
444
+ var reviewBtn = document.querySelector('[aria-controls="review-panel"]');
445
+ if (reviewBtn && reviewBtn.getAttribute('aria-expanded') !== 'true') {
446
+ reviewBtn.click();
447
+ }
448
+
449
+ // \u7B49 DOM \u5C31\u7EEA\u540E\u6253\u6807\u8BB0\u5E76\u5E94\u7528 CSS
450
+ var attempts = 0;
451
+ function tryApply() {
452
+ if (ensureReviewPanelRefs()) {
453
+ document.documentElement.classList.add('opencode-review-panel-overlay');
454
+ injectChatToggleBtn();
455
+ return;
456
+ }
457
+ attempts++;
458
+ if (attempts < 20) requestAnimationFrame(tryApply);
459
+ }
460
+ requestAnimationFrame(tryApply);
461
+ } else {
462
+ // \u5173\u95ED\u524D\u5148\u5C06\u4F1A\u8BDD\u9762\u677F\u5BBD\u5EA6\u8BBE\u4E3A 100%\uFF0C\u907F\u514D SolidJS \u5F02\u6B65\u6E32\u67D3\u7684\u5BBD\u5EA6\u8DF3\u53D8
463
+ var sessionPanel = document.querySelector('[data-ref="session-panel"]');
464
+ if (sessionPanel) sessionPanel.style.width = '100%';
465
+ document.body.offsetHeight; // \u5F3A\u5236\u56DE\u6D41
466
+
467
+ document.documentElement.classList.remove('opencode-review-panel-overlay');
468
+ document.documentElement.classList.remove('hide-chat');
469
+ removeChatToggleBtn();
470
+
471
+ // \u7B49\u4E00\u5E27\u8BA9 CSS \u5E03\u5C40\u53D8\u5316\u5148\u6E32\u67D3\uFF0C\u518D\u5173\u95ED\u539F\u751F\u9762\u677F
472
+ // \u907F\u514D SolidJS \u5F02\u6B65 DOM \u53D8\u5316\u548C CSS \u5E03\u5C40\u53D8\u5316\u53D1\u751F\u5728\u540C\u4E00\u5E27\u5BFC\u81F4\u89C6\u89C9\u8DF3\u52A8
473
+ requestAnimationFrame(function() {
474
+ var reviewBtn = document.querySelector('[aria-controls="review-panel"]');
475
+ if (reviewBtn && reviewBtn.getAttribute('aria-expanded') === 'true') {
476
+ reviewBtn.click();
477
+ }
478
+ });
479
+ }
480
+ }
481
+
482
+ // === \u5E94\u7528\u4FDD\u5B58\u7684\u72B6\u6001 ===
483
+ function applySavedStates() {
484
+ if (savedMinimizedState !== null) {
485
+ handleMinimizeStateChange(savedMinimizedState);
486
+ }
487
+ if (savedPromptDockVisibleState !== null) {
488
+ handlePromptDockVisibilityChange(savedPromptDockVisibleState);
489
+ }
490
+ if (savedReviewPanelState !== null) {
491
+ handleReviewPanelToggle(savedReviewPanelState);
492
+ }
493
+ }
494
+
495
+ // === \u4FDD\u5B58\u8F93\u5165\u6846\u5149\u6807\u4F4D\u7F6E ===
496
+ let savedRange = null;
497
+
498
+ function setupPromptInputListener() {
499
+ const promptInput = document.querySelector('[data-component="prompt-input"]');
500
+ if (!promptInput) return;
501
+
502
+ promptInput.addEventListener('blur', function() {
503
+ const selection = window.getSelection();
504
+ if (selection && selection.rangeCount > 0) {
505
+ const range = selection.getRangeAt(0);
506
+ if (promptInput.contains(range.commonAncestorContainer)) {
507
+ savedRange = range.cloneRange();
508
+ }
509
+ }
510
+ });
511
+
512
+ promptInput.addEventListener('focus', function() {
513
+ savedRange = null;
514
+ });
515
+ }
516
+
517
+ // === \u63D2\u5165 File Part \u5230\u8F93\u5165\u6846 ===
518
+ function insertFilePart(element) {
519
+ const promptInput = document.querySelector('[data-component="prompt-input"]');
520
+ if (!promptInput) {
521
+ console.warn('Prompt input not found');
522
+ return;
523
+ }
524
+
525
+ const { filePath, line, column, description, innerText, previewPageUrl, previewPageTitle } = element;
526
+
527
+ const selector = description || 'element';
528
+ let textPreview = '';
529
+ if (innerText && innerText.trim()) {
530
+ const trimmed = innerText.trim();
531
+ textPreview = trimmed.length > 5 ? trimmed.substring(0, 5) + '...' : trimmed;
532
+ }
533
+ const displayText = '@' + selector + (textPreview ? '(' + textPreview + ')' : '');
534
+
535
+ const jsonStr = JSON.stringify({
536
+ nodeContext: {
537
+ "filePath": {
538
+ "value": filePath ?? '\u672A\u77E5',
539
+ "desc": "\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84"
540
+ },
541
+ "line": {
542
+ "value": line ?? '\u672A\u77E5',
543
+ "desc": "\u4EE3\u7801\u6240\u5728\u884C\u53F7"
544
+ },
545
+ "column": {
546
+ "value": column ?? '\u672A\u77E5',
547
+ "desc": "\u4EE3\u7801\u6240\u5728\u5217\u53F7"
548
+ },
549
+ "description": {
550
+ "value": description ?? '\u672A\u77E5',
551
+ "desc": "DOM \u5143\u7D20\u9009\u62E9\u5668"
552
+ },
553
+ "innerText": {
554
+ "value": innerText ? innerText.substring(0, 500) : '',
555
+ "desc": "DOM \u5143\u7D20\u5185\u90E8\u6587\u672C"
556
+ },
557
+ "selectAt": {
558
+ "value": previewPageUrl || '\u672A\u77E5',
559
+ "desc": "\u7528\u6237\u9009\u4E2D\u8282\u70B9\u65F6\u7684\u9875\u9762 URL"
560
+ }
561
+ }
562
+ });
563
+
564
+ const span = document.createElement('span');
565
+ span.setAttribute('data-mention', 'file');
566
+ span.setAttribute('data-path', jsonStr);
567
+ span.setAttribute('contenteditable', 'false');
568
+
569
+ span.textContent = displayText;
570
+
571
+ if (savedRange) {
572
+ const range = savedRange;
573
+ range.collapse(false);
574
+ range.insertNode(span);
575
+
576
+ const space = document.createTextNode('\\u00A0');
577
+ span.parentNode.insertBefore(space, span.nextSibling);
578
+
579
+ const newRange = document.createRange();
580
+ newRange.setStartAfter(space);
581
+ newRange.collapse(true);
582
+
583
+ promptInput.focus();
584
+
585
+ const selection = window.getSelection();
586
+ if (selection) {
587
+ selection.removeAllRanges();
588
+ selection.addRange(newRange);
589
+ }
590
+ savedRange = null;
591
+
592
+ promptInput.dispatchEvent(new Event('input', { bubbles: true }));
593
+ return;
594
+ }
595
+
596
+ const selection = window.getSelection();
597
+ if (selection && selection.rangeCount > 0) {
598
+ const range = selection.getRangeAt(0);
599
+
600
+ if (promptInput.contains(range.commonAncestorContainer)) {
601
+ range.collapse(false);
602
+ range.insertNode(span);
603
+
604
+ const space = document.createTextNode('\\u00A0');
605
+ span.parentNode.insertBefore(space, span.nextSibling);
606
+
607
+ const newRange = document.createRange();
608
+ newRange.setStartAfter(space);
609
+ newRange.collapse(true);
610
+ selection.removeAllRanges();
611
+ selection.addRange(newRange);
612
+
613
+ promptInput.dispatchEvent(new Event('input', { bubbles: true }));
614
+ return;
615
+ }
616
+ }
617
+
618
+ promptInput.appendChild(span);
619
+ const space = document.createTextNode('\\u00A0');
620
+ promptInput.appendChild(space);
621
+
622
+ const newRange = document.createRange();
623
+ newRange.setStartAfter(space);
624
+ newRange.collapse(true);
625
+ const newSelection = window.getSelection();
626
+ if (newSelection) {
627
+ newSelection.removeAllRanges();
628
+ newSelection.addRange(newRange);
629
+ }
630
+
631
+ promptInput.dispatchEvent(new Event('input', { bubbles: true }));
632
+ promptInput.focus();
633
+ }
634
+
635
+ // === \u5C31\u7EEA\u901A\u77E5 ===
636
+ function init() {
637
+ injectMinimizeStyles();
638
+ injectReviewPanelStyles();
639
+ injectGeneralStyles();
640
+ setupPromptInputListener();
641
+ applySavedStates();
642
+
643
+ let readySent = false;
644
+ function trySendReady() {
645
+ if (readySent) return;
646
+ const promptInput = document.querySelector('[data-component="prompt-input"]');
647
+ if (promptInput && window.parent !== window) {
648
+ window.parent.postMessage({ type: ${JSON.stringify(WIDGET_MSG.READY)} }, "*");
649
+ readySent = true;
650
+ }
651
+ }
652
+ trySendReady();
653
+
654
+ const observer = new MutationObserver(function(mutations) {
655
+ trySendReady();
656
+
657
+ const promptInput = document.querySelector('[data-component="prompt-input"]');
658
+ if (promptInput && !promptInput._aipanelListenerAttached) {
659
+ setupPromptInputListener();
660
+ promptInput._aipanelListenerAttached = true;
661
+ }
662
+
663
+ // \u5F53\u76EE\u6807\u5143\u7D20\u51FA\u73B0\u65F6\u5E94\u7528\u4FDD\u5B58\u7684\u72B6\u6001
664
+ const promptDock = document.querySelector('[data-component="session-prompt-dock"]');
665
+ const dockSurface = document.querySelector('[data-dock-surface="tray"]');
666
+ if (promptDock || dockSurface) {
667
+ applySavedStates();
668
+ }
669
+ });
670
+ observer.observe(document.body, { childList: true, subtree: true });
671
+ }
672
+
673
+ if (document.readyState === 'loading') {
674
+ document.addEventListener('DOMContentLoaded', init);
675
+ } else {
676
+ init();
677
+ }
678
+ })();
679
+ `;
680
+ }
681
+ export {
682
+ generateBridgeScript
683
+ };