cursor-feedback 1.0.5 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release-please.yml +19 -0
- package/CHANGELOG.md +59 -0
- package/README.md +124 -105
- package/README_CN.md +268 -0
- package/demo.gif +0 -0
- package/dist/extension.js +62 -9
- package/dist/extension.js.map +1 -1
- package/dist/i18n/en.json +34 -0
- package/dist/i18n/index.js +127 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/zh-CN.json +34 -0
- package/dist/webview/index.html +14 -11
- package/dist/webview/script.js +24 -9
- package/dist/webview/styles.css +17 -1
- package/icon.png +0 -0
- package/mcp-install-dark.png +0 -0
- package/package.json +35 -4
- package/src/extension.ts +77 -9
- package/src/i18n/en.json +34 -0
- package/src/i18n/index.ts +131 -0
- package/src/i18n/zh-CN.json +34 -0
- package/src/webview/index.html +14 -11
- package/src/webview/script.js +24 -9
- package/src/webview/styles.css +17 -1
package/src/webview/index.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="{{LANG}}">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
<!-- 服务器状态 -->
|
|
14
14
|
<div id="serverStatus" class="server-status">
|
|
15
15
|
<span class="dot"></span>
|
|
16
|
-
<span id="serverStatusText"
|
|
16
|
+
<span id="serverStatusText">{{i18n.checkingConnection}}</span>
|
|
17
|
+
<button id="langSwitchBtn" class="lang-switch-btn" title="Switch Language / 切换语言">🌐</button>
|
|
17
18
|
<span id="debugIcon" class="debug-icon">🔍</span>
|
|
18
19
|
<div id="debugTooltip" class="debug-tooltip"></div>
|
|
19
20
|
</div>
|
|
@@ -21,29 +22,29 @@
|
|
|
21
22
|
<!-- 等待状态 -->
|
|
22
23
|
<div id="waitingStatus" class="status waiting">
|
|
23
24
|
<div class="status-icon">⏳</div>
|
|
24
|
-
<p
|
|
25
|
-
<p style="font-size: 11px; margin-top: 10px; opacity: 0.8;"
|
|
25
|
+
<p>{{i18n.waitingForAI}}</p>
|
|
26
|
+
<p style="font-size: 11px; margin-top: 10px; opacity: 0.8;">{{i18n.waitingHint}}</p>
|
|
26
27
|
</div>
|
|
27
28
|
|
|
28
29
|
<!-- 反馈表单 -->
|
|
29
30
|
<div id="feedbackForm" class="hidden">
|
|
30
31
|
<!-- AI 摘要 -->
|
|
31
32
|
<div class="section">
|
|
32
|
-
<div class="section-title">📋
|
|
33
|
+
<div class="section-title">📋 {{i18n.aiSummary}}</div>
|
|
33
34
|
<div id="summaryContent" class="summary-content"></div>
|
|
34
35
|
<div id="projectInfo" class="project-info"></div>
|
|
35
36
|
</div>
|
|
36
37
|
|
|
37
38
|
<!-- 反馈输入 -->
|
|
38
39
|
<div class="section">
|
|
39
|
-
<div class="section-title">💬
|
|
40
|
-
<textarea id="feedbackInput" class="feedback-input" placeholder="
|
|
40
|
+
<div class="section-title">💬 {{i18n.yourFeedback}}</div>
|
|
41
|
+
<textarea id="feedbackInput" class="feedback-input" placeholder="{{i18n.feedbackPlaceholder}}"></textarea>
|
|
41
42
|
|
|
42
43
|
<!-- 附件区域 -->
|
|
43
44
|
<div class="attachments-area">
|
|
44
45
|
<div class="attachment-buttons">
|
|
45
|
-
<button id="uploadBtn" class="attachment-btn" data-tooltip="
|
|
46
|
-
<button id="selectPathBtn" class="attachment-btn" data-tooltip="
|
|
46
|
+
<button id="uploadBtn" class="attachment-btn" data-tooltip="{{i18n.uploadImage}}">🖼️</button>
|
|
47
|
+
<button id="selectPathBtn" class="attachment-btn" data-tooltip="{{i18n.selectFilesOrFolders}}">📁</button>
|
|
47
48
|
</div>
|
|
48
49
|
<input type="file" id="imageInput" accept="image/*" multiple class="hidden">
|
|
49
50
|
<div id="imagePreview" class="image-preview"></div>
|
|
@@ -55,12 +56,14 @@
|
|
|
55
56
|
|
|
56
57
|
<!-- 提交按钮组 -->
|
|
57
58
|
<div class="submit-group">
|
|
58
|
-
<button id="submitBtn" class="submit-btn"
|
|
59
|
-
<button id="toggleKeyModeBtn" class="toggle-key-mode-btn" title="
|
|
59
|
+
<button id="submitBtn" class="submit-btn">{{i18n.ctrlEnterSubmitMode}}</button>
|
|
60
|
+
<button id="toggleKeyModeBtn" class="toggle-key-mode-btn" title="{{i18n.toggleKeyMode}}">⌨️</button>
|
|
60
61
|
</div>
|
|
61
62
|
</div>
|
|
62
63
|
</div>
|
|
63
64
|
|
|
65
|
+
<!-- 注入 i18n 数据 -->
|
|
66
|
+
<script>window.i18n = {{I18N_JSON}};</script>
|
|
64
67
|
<script src="{{SCRIPT_JS_URI}}"></script>
|
|
65
68
|
</body>
|
|
66
69
|
</html>
|
package/src/webview/script.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// WebView 脚本
|
|
2
2
|
(function() {
|
|
3
3
|
const vscode = acquireVsCodeApi();
|
|
4
|
+
const i18n = window.i18n || {};
|
|
4
5
|
|
|
5
6
|
// 恢复之前保存的文本
|
|
6
7
|
const previousState = vscode.getState();
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
const serverStatus = document.getElementById('serverStatus');
|
|
24
25
|
const serverStatusText = document.getElementById('serverStatusText');
|
|
25
26
|
const debugTooltip = document.getElementById('debugTooltip');
|
|
27
|
+
const langSwitchBtn = document.getElementById('langSwitchBtn');
|
|
26
28
|
const waitingStatus = document.getElementById('waitingStatus');
|
|
27
29
|
const feedbackForm = document.getElementById('feedbackForm');
|
|
28
30
|
const summaryContent = document.getElementById('summaryContent');
|
|
@@ -37,6 +39,11 @@
|
|
|
37
39
|
const timeoutInfo = document.getElementById('timeoutInfo');
|
|
38
40
|
const toggleKeyModeBtn = document.getElementById('toggleKeyModeBtn');
|
|
39
41
|
|
|
42
|
+
// 语言切换按钮
|
|
43
|
+
langSwitchBtn.addEventListener('click', () => {
|
|
44
|
+
vscode.postMessage({ type: 'switchLanguage' });
|
|
45
|
+
});
|
|
46
|
+
|
|
40
47
|
let uploadedImages = [];
|
|
41
48
|
let attachedFiles = [];
|
|
42
49
|
let currentRequestId = '';
|
|
@@ -51,13 +58,13 @@
|
|
|
51
58
|
// 更新快捷键模式 UI
|
|
52
59
|
function updateKeyModeUI() {
|
|
53
60
|
if (enterToSubmit) {
|
|
54
|
-
submitBtn.textContent = 'Enter
|
|
61
|
+
submitBtn.textContent = i18n.enterSubmitMode || 'Enter to submit · Shift+Enter for newline';
|
|
55
62
|
toggleKeyModeBtn.classList.add('enter-mode');
|
|
56
|
-
toggleKeyModeBtn.title = '
|
|
63
|
+
toggleKeyModeBtn.title = i18n.switchToCtrlEnter || 'Click to switch to Ctrl+Enter submit';
|
|
57
64
|
} else {
|
|
58
|
-
submitBtn.textContent = 'Ctrl+Enter
|
|
65
|
+
submitBtn.textContent = i18n.ctrlEnterSubmitMode || 'Ctrl+Enter to submit · Enter for newline';
|
|
59
66
|
toggleKeyModeBtn.classList.remove('enter-mode');
|
|
60
|
-
toggleKeyModeBtn.title = '
|
|
67
|
+
toggleKeyModeBtn.title = i18n.switchToEnter || 'Click to switch to Enter submit';
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
@@ -184,10 +191,11 @@
|
|
|
184
191
|
const remaining = Math.max(0, requestTimeout - elapsed);
|
|
185
192
|
const minutes = Math.floor(remaining / 60);
|
|
186
193
|
const seconds = remaining % 60;
|
|
187
|
-
|
|
194
|
+
const remainingLabel = i18n.remainingTime || 'Remaining time';
|
|
195
|
+
timeoutInfo.textContent = remainingLabel + ': ' + minutes + ':' + seconds.toString().padStart(2, '0');
|
|
188
196
|
if (remaining <= 0) {
|
|
189
197
|
clearInterval(countdownInterval);
|
|
190
|
-
timeoutInfo.textContent = '
|
|
198
|
+
timeoutInfo.textContent = i18n.timeout || 'Timeout';
|
|
191
199
|
}
|
|
192
200
|
}
|
|
193
201
|
|
|
@@ -276,16 +284,23 @@
|
|
|
276
284
|
case 'serverStatus':
|
|
277
285
|
if (message.payload.connected) {
|
|
278
286
|
serverStatus.classList.add('connected');
|
|
279
|
-
serverStatusText.textContent = 'MCP Server
|
|
287
|
+
serverStatusText.textContent = i18n.mcpServerConnected || 'MCP Server connected';
|
|
280
288
|
} else {
|
|
281
289
|
serverStatus.classList.remove('connected');
|
|
282
|
-
serverStatusText.textContent = 'MCP Server
|
|
290
|
+
serverStatusText.textContent = i18n.mcpServerDisconnected || 'MCP Server disconnected';
|
|
283
291
|
}
|
|
284
292
|
break;
|
|
285
293
|
|
|
286
294
|
case 'updateDebugInfo':
|
|
287
295
|
const d = message.payload;
|
|
288
|
-
|
|
296
|
+
const debugLabel = i18n.debugInfo || 'Debug Info';
|
|
297
|
+
const scanPortLabel = i18n.scanPort || 'Scan port';
|
|
298
|
+
const workspaceLabel = i18n.workspace || 'Workspace';
|
|
299
|
+
const currentPortLabel = i18n.currentPort || 'Current port';
|
|
300
|
+
const connectedLabel = i18n.connected || 'Connected';
|
|
301
|
+
const noneLabel = i18n.none || 'None';
|
|
302
|
+
const statusLabel = i18n.status || 'Status';
|
|
303
|
+
debugTooltip.textContent = `🔍 ${debugLabel}\n━━━━━━━━━━━━\n${scanPortLabel}: ${d.portRange}\n${workspaceLabel}: ${d.workspacePath}\n${currentPortLabel}: ${d.activePort || '-'}\n${connectedLabel}: ${d.connectedPorts.length > 0 ? d.connectedPorts.join(', ') : noneLabel}\n${statusLabel}: ${d.lastStatus}`;
|
|
289
304
|
break;
|
|
290
305
|
|
|
291
306
|
case 'filesSelected':
|
package/src/webview/styles.css
CHANGED
|
@@ -224,8 +224,24 @@ body {
|
|
|
224
224
|
background: var(--vscode-notificationsInfoIcon-foreground);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
.
|
|
227
|
+
.lang-switch-btn {
|
|
228
228
|
margin-left: auto;
|
|
229
|
+
padding: 2px 6px;
|
|
230
|
+
background: transparent;
|
|
231
|
+
border: 1px solid var(--vscode-input-border);
|
|
232
|
+
border-radius: 3px;
|
|
233
|
+
cursor: pointer;
|
|
234
|
+
font-size: 12px;
|
|
235
|
+
opacity: 0.7;
|
|
236
|
+
transition: opacity 0.15s, background 0.15s;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.lang-switch-btn:hover {
|
|
240
|
+
opacity: 1;
|
|
241
|
+
background: var(--vscode-button-secondaryBackground);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.debug-icon {
|
|
229
245
|
cursor: pointer;
|
|
230
246
|
opacity: 0.6;
|
|
231
247
|
font-size: 12px;
|