新增新建會話和提交後自動執行命令功能

This commit is contained in:
Minidoracat 2025-06-28 21:44:08 +08:00
parent 867f29e2e9
commit cb6edccbb4
7 changed files with 444 additions and 6 deletions

View File

@ -91,7 +91,23 @@
"running": "Running...", "running": "Running...",
"completed": "Completed", "completed": "Completed",
"error": "Execution Error", "error": "Execution Error",
"history": "Command History" "history": "Command History",
"autoCommand": {
"title": "🤖 Auto Command Settings",
"description": "Configure commands to execute automatically at specific times",
"enabled": "Enable Auto Commands",
"onNewSession": "Execute on New Session",
"onNewSessionPlaceholder": "e.g., pwd or git status",
"onFeedbackSubmit": "Execute on Feedback Submit",
"onFeedbackSubmitPlaceholder": "e.g., echo 'Feedback submitted'",
"testOnNewSession": "Test New Session Command",
"testOnFeedbackSubmit": "Test Feedback Submit Command",
"help": "These commands will execute automatically at the corresponding times. Leave empty to skip execution."
},
"autoSettings": {
"exampleNewSession": "💡 Example: pwd, git status, ls -la",
"exampleFeedback": "💡 Example: date, echo \"Done\", git log -1"
}
}, },
"combined": { "combined": {
"summaryTitle": "📋 AI Work Summary", "summaryTitle": "📋 AI Work Summary",

View File

@ -91,7 +91,23 @@
"running": "执行中...", "running": "执行中...",
"completed": "执行完成", "completed": "执行完成",
"error": "执行错误", "error": "执行错误",
"history": "命令历史" "history": "命令历史",
"autoCommand": {
"title": "🤖 自动执行命令设置",
"description": "设置在特定时机自动执行的命令",
"enabled": "启用自动执行命令",
"onNewSession": "新会话建立时执行",
"onNewSessionPlaceholder": "例如pwd 或 git status",
"onFeedbackSubmit": "提交反馈后执行",
"onFeedbackSubmitPlaceholder": "例如echo '反馈已提交'",
"testOnNewSession": "测试新会话命令",
"testOnFeedbackSubmit": "测试反馈提交命令",
"help": "这些命令会在对应的时机自动执行。留空表示不执行任何命令。"
},
"autoSettings": {
"exampleNewSession": "💡 示例pwd, git status, ls -la",
"exampleFeedback": "💡 示例date, echo \"Done\", git log -1"
}
}, },
"combined": { "combined": {
"summaryTitle": "📋 AI 工作摘要", "summaryTitle": "📋 AI 工作摘要",

View File

@ -96,7 +96,23 @@
"running": "執行中...", "running": "執行中...",
"completed": "執行完成", "completed": "執行完成",
"error": "執行錯誤", "error": "執行錯誤",
"history": "命令歷史" "history": "命令歷史",
"autoCommand": {
"title": "🤖 自動執行命令設定",
"description": "設定在特定時機自動執行的命令",
"enabled": "啟用自動執行命令",
"onNewSession": "新會話建立時執行",
"onNewSessionPlaceholder": "例如pwd 或 git status",
"onFeedbackSubmit": "提交回饋後執行",
"onFeedbackSubmitPlaceholder": "例如echo '回饋已提交'",
"testOnNewSession": "測試新會話命令",
"testOnFeedbackSubmit": "測試回饋提交命令",
"help": "這些命令會在對應的時機自動執行。留空表示不執行任何命令。"
},
"autoSettings": {
"exampleNewSession": "💡 範例pwd, git status, ls -la",
"exampleFeedback": "💡 範例date, echo \"Done\", git log -1"
}
}, },
"combined": { "combined": {
"summaryTitle": "📋 AI 工作摘要", "summaryTitle": "📋 AI 工作摘要",

View File

@ -2075,3 +2075,129 @@ textarea:-ms-input-placeholder,
100% { opacity: 1; } 100% { opacity: 1; }
} }
/* 自動執行命令設定樣式 */
.command-auto-settings {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 16px;
margin: 16px 0;
}
.command-auto-settings .settings-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.command-auto-settings .settings-title {
margin: 0;
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
}
.command-auto-settings .settings-content {
transition: opacity 0.3s ease;
}
.command-auto-settings .settings-content.disabled {
opacity: 0.5;
pointer-events: none;
}
.auto-command-item {
margin-bottom: 20px;
padding: 12px;
background: var(--bg-tertiary);
border-radius: 6px;
border: 1px solid var(--border-color);
}
.auto-command-item:last-child {
margin-bottom: 0;
}
.command-label {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
font-weight: 500;
color: var(--text-primary);
}
.command-icon {
font-size: 18px;
}
.command-input-wrapper {
display: flex;
align-items: center;
margin: 8px 0;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 0 12px;
transition: border-color 0.3s ease;
}
.command-input-wrapper:focus-within {
border-color: var(--accent-color);
}
.command-prefix {
color: var(--accent-color);
font-weight: bold;
margin-right: 8px;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}
.auto-command-input {
flex: 1;
border: none;
background: transparent;
padding: 8px 0;
color: var(--text-primary);
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 14px;
outline: none;
}
.command-actions {
display: flex;
align-items: center;
gap: 12px;
margin-top: 8px;
}
.btn-test {
background: var(--info-color);
color: white;
border: none;
padding: 4px 12px;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
transition: background 0.3s ease;
}
.btn-test:hover {
background: #1976d2;
}
.command-hint {
color: var(--text-secondary);
font-size: 12px;
}
.btn-small {
padding: 4px 8px;
font-size: 12px;
border-radius: 4px;
border: none;
cursor: pointer;
transition: all 0.3s ease;
}

View File

@ -367,6 +367,10 @@
}); });
} }
// 自動命令設定相關事件
self.setupAutoCommandEvents();
// 設置設定管理器的事件監聽器 // 設置設定管理器的事件監聽器
self.settingsManager.setupEventListeners(); self.settingsManager.setupEventListeners();
@ -693,6 +697,14 @@
console.log('🖥️ 收到桌面關閉請求'); console.log('🖥️ 收到桌面關閉請求');
this.handleDesktopCloseRequest(data); this.handleDesktopCloseRequest(data);
break; break;
case 'notification':
console.log('📢 收到通知:', data);
// 處理 FEEDBACK_SUBMITTED 通知
if (data.code === 'session.feedbackSubmitted' || data.code === 'FEEDBACK_SUBMITTED' || data.code === 201) {
console.log('✅ 回饋提交成功通知');
this.handleFeedbackReceived(data);
}
break;
} }
}; };
@ -751,6 +763,9 @@
// 更新 AI 摘要區域顯示「已送出反饋」狀態 // 更新 AI 摘要區域顯示「已送出反饋」狀態
const submittedMessage = window.i18nManager ? window.i18nManager.t('feedback.submittedWaiting') : '已送出反饋,等待下次 MCP 調用...'; const submittedMessage = window.i18nManager ? window.i18nManager.t('feedback.submittedWaiting') : '已送出反饋,等待下次 MCP 調用...';
this.updateSummaryStatus(submittedMessage); this.updateSummaryStatus(submittedMessage);
// 執行提交回饋後的自動命令
this.executeAutoCommandOnFeedbackSubmit();
// 刷新會話列表以顯示最新狀態 // 刷新會話列表以顯示最新狀態
this.refreshSessionList(); this.refreshSessionList();
@ -815,6 +830,9 @@
if (this.audioManager) { if (this.audioManager) {
this.audioManager.playNotification(); this.audioManager.playNotification();
} }
// 執行新會話自動命令
this.executeAutoCommandOnNewSession();
// 發送瀏覽器通知 // 發送瀏覽器通知
if (this.notificationManager && data.session_info) { if (this.notificationManager && data.session_info) {
@ -1451,6 +1469,68 @@
} }
}; };
/**
* 執行新會話自動命令
*/
FeedbackApp.prototype.executeAutoCommandOnNewSession = function() {
if (!this.settingsManager) return;
const settings = this.settingsManager.currentSettings;
if (!settings.autoCommandEnabled || !settings.commandOnNewSession) {
console.log('⏩ 新會話自動命令未啟用或未設定');
return;
}
const command = settings.commandOnNewSession.trim();
if (!command) return;
console.log('🚀 執行新會話自動命令:', command);
this.appendCommandOutput('🆕 [自動執行] $ ' + command + '\n');
// 使用 WebSocket 發送命令
if (this.webSocketManager && this.webSocketManager.isConnected) {
console.log('📡 WebSocket 已連接,發送命令:', command);
this.webSocketManager.send({
type: 'run_command',
command: command
});
} else {
console.error('❌ 無法執行自動命令WebSocket 未連接');
this.appendCommandOutput('[錯誤] WebSocket 未連接,無法執行命令\n');
}
};
/**
* 執行提交回饋後自動命令
*/
FeedbackApp.prototype.executeAutoCommandOnFeedbackSubmit = function() {
if (!this.settingsManager) return;
const settings = this.settingsManager.currentSettings;
if (!settings.autoCommandEnabled || !settings.commandOnFeedbackSubmit) {
console.log('⏩ 提交回饋後自動命令未啟用或未設定');
return;
}
const command = settings.commandOnFeedbackSubmit.trim();
if (!command) return;
console.log('🚀 執行提交回饋後自動命令:', command);
this.appendCommandOutput('✅ [自動執行] $ ' + command + '\n');
// 使用 WebSocket 發送命令
if (this.webSocketManager && this.webSocketManager.isConnected) {
console.log('📡 WebSocket 已連接,發送命令:', command);
this.webSocketManager.send({
type: 'run_command',
command: command
});
} else {
console.error('❌ 無法執行自動命令WebSocket 未連接');
this.appendCommandOutput('[錯誤] WebSocket 未連接,無法執行命令\n');
}
};
/** /**
* 更新摘要狀態 * 更新摘要狀態
*/ */
@ -1461,6 +1541,127 @@
}); });
}; };
/**
* 設置自動命令相關事件
*/
FeedbackApp.prototype.setupAutoCommandEvents = function() {
const self = this;
// 自動命令開關
const autoCommandEnabled = window.MCPFeedback.Utils.safeQuerySelector('#autoCommandEnabled');
if (autoCommandEnabled) {
// 載入設定
if (this.settingsManager) {
autoCommandEnabled.checked = this.settingsManager.currentSettings.autoCommandEnabled;
this.updateAutoCommandUI(autoCommandEnabled.checked);
}
autoCommandEnabled.addEventListener('change', function() {
const enabled = autoCommandEnabled.checked;
self.updateAutoCommandUI(enabled);
if (self.settingsManager) {
self.settingsManager.saveSettings({
autoCommandEnabled: enabled
});
}
});
}
// 新會話命令輸入
const commandOnNewSession = window.MCPFeedback.Utils.safeQuerySelector('#commandOnNewSession');
if (commandOnNewSession) {
// 載入設定
if (this.settingsManager) {
commandOnNewSession.value = this.settingsManager.currentSettings.commandOnNewSession || '';
}
commandOnNewSession.addEventListener('change', function() {
if (self.settingsManager) {
self.settingsManager.saveSettings({
commandOnNewSession: commandOnNewSession.value
});
}
});
}
// 提交回饋後命令輸入
const commandOnFeedbackSubmit = window.MCPFeedback.Utils.safeQuerySelector('#commandOnFeedbackSubmit');
if (commandOnFeedbackSubmit) {
// 載入設定
if (this.settingsManager) {
commandOnFeedbackSubmit.value = this.settingsManager.currentSettings.commandOnFeedbackSubmit || '';
}
commandOnFeedbackSubmit.addEventListener('change', function() {
if (self.settingsManager) {
self.settingsManager.saveSettings({
commandOnFeedbackSubmit: commandOnFeedbackSubmit.value
});
}
});
}
// 測試執行按鈕
const testNewSessionCommand = window.MCPFeedback.Utils.safeQuerySelector('#testNewSessionCommand');
if (testNewSessionCommand) {
testNewSessionCommand.addEventListener('click', function() {
const command = commandOnNewSession ? commandOnNewSession.value.trim() : '';
if (command) {
self.testCommand(command, '🆕 [測試] ');
} else {
window.MCPFeedback.Utils.showMessage('請先輸入命令', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
}
});
}
const testFeedbackCommand = window.MCPFeedback.Utils.safeQuerySelector('#testFeedbackCommand');
if (testFeedbackCommand) {
testFeedbackCommand.addEventListener('click', function() {
const command = commandOnFeedbackSubmit ? commandOnFeedbackSubmit.value.trim() : '';
if (command) {
self.testCommand(command, '✅ [測試] ');
} else {
window.MCPFeedback.Utils.showMessage('請先輸入命令', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
}
});
}
};
/**
* 更新自動命令 UI 狀態
*/
FeedbackApp.prototype.updateAutoCommandUI = function(enabled) {
const autoCommandContent = window.MCPFeedback.Utils.safeQuerySelector('#autoCommandContent');
if (autoCommandContent) {
if (enabled) {
autoCommandContent.classList.remove('disabled');
} else {
autoCommandContent.classList.add('disabled');
}
}
};
/**
* 測試命令執行
*/
FeedbackApp.prototype.testCommand = function(command, prefix) {
if (!command) return;
console.log('🧪 測試執行命令:', command);
this.appendCommandOutput(prefix + '$ ' + command + '\n');
// 使用 WebSocket 發送命令
if (this.webSocketManager && this.webSocketManager.isConnected) {
this.webSocketManager.send({
type: 'run_command',
command: command
});
} else {
this.appendCommandOutput('❌ WebSocket 未連接\n');
}
};
/** /**
* 處理會話更新來自自動刷新 * 處理會話更新來自自動刷新
*/ */

View File

@ -53,7 +53,11 @@
combinedFeedbackTextHeight: 150, // combinedFeedbackText textarea 的高度px combinedFeedbackTextHeight: 150, // combinedFeedbackText textarea 的高度px
// 會話超時設定 // 會話超時設定
sessionTimeoutEnabled: false, // 預設關閉 sessionTimeoutEnabled: false, // 預設關閉
sessionTimeoutSeconds: 3600 // 預設 1 小時(秒) sessionTimeoutSeconds: 3600, // 預設 1 小時(秒)
// 自動執行命令設定
autoCommandEnabled: true, // 是否啟用自動執行命令
commandOnNewSession: '', // 新會話建立時執行的命令
commandOnFeedbackSubmit: '' // 提交回饋後執行的命令
}; };
// 當前設定 // 當前設定

View File

@ -514,8 +514,8 @@
<div id="commandOutput" class="command-output"></div> <div id="commandOutput" class="command-output"></div>
</div> </div>
<!-- 命令輸入區域 - 放在下面 --> <!-- 命令輸入區域 -->
<div class="input-group" style="margin-bottom: 0;"> <div class="input-group" style="margin-bottom: 20px;">
<label class="input-label" data-i18n="command.inputLabel">命令輸入</label> <label class="input-label" data-i18n="command.inputLabel">命令輸入</label>
<div style="display: flex; gap: 10px; align-items: flex-start;"> <div style="display: flex; gap: 10px; align-items: flex-start;">
<div style="flex: 1; display: flex; align-items: center; gap: 8px;"> <div style="flex: 1; display: flex; align-items: center; gap: 8px;">
@ -534,6 +534,65 @@
</button> </button>
</div> </div>
</div> </div>
<!-- 自動執行命令設定 -->
<div class="command-auto-settings">
<div class="settings-header">
<h4 class="settings-title" data-i18n="command.autoCommand.title">🤖 自動執行命令設定</h4>
<label class="toggle-switch">
<input type="checkbox" id="autoCommandEnabled" class="toggle-input">
<span class="toggle-slider"></span>
</label>
</div>
<p class="settings-description" data-i18n="command.autoCommand.description">設定在特定時機自動執行的命令</p>
<div class="settings-content" id="autoCommandContent">
<!-- 新會話建立時執行 -->
<div class="auto-command-item">
<div class="command-label">
<span class="command-icon">🆕</span>
<span data-i18n="command.autoCommand.onNewSession">新會話建立時執行</span>
</div>
<div class="command-input-wrapper">
<span class="command-prefix">$</span>
<input type="text"
id="commandOnNewSession"
class="auto-command-input"
data-i18n-placeholder="command.autoCommand.onNewSessionPlaceholder"
placeholder="輸入要自動執行的命令...">
</div>
<div class="command-actions">
<button class="btn-small btn-test" id="testNewSessionCommand" data-i18n="command.autoCommand.testOnNewSession">測試新會話命令</button>
<span class="command-hint" data-i18n="command.autoSettings.exampleNewSession">💡 範例pwd, git status, ls -la</span>
</div>
</div>
<!-- 提交回饋後執行 -->
<div class="auto-command-item">
<div class="command-label">
<span class="command-icon"></span>
<span data-i18n="command.autoCommand.onFeedbackSubmit">提交回饋後執行</span>
</div>
<div class="command-input-wrapper">
<span class="command-prefix">$</span>
<input type="text"
id="commandOnFeedbackSubmit"
class="auto-command-input"
data-i18n-placeholder="command.autoCommand.onFeedbackSubmitPlaceholder"
placeholder="輸入要自動執行的命令...">
</div>
<div class="command-actions">
<button class="btn-small btn-test" id="testFeedbackCommand" data-i18n="command.autoCommand.testOnFeedbackSubmit">測試回饋提交命令</button>
<span class="command-hint" data-i18n="command.autoSettings.exampleFeedback">💡 範例date, echo "Done", git log -1</span>
</div>
</div>
<!-- 說明文字 -->
<div class="auto-command-help">
<p class="help-text" data-i18n="command.autoCommand.help">這些命令會在對應的時機自動執行。留空表示不執行任何命令。</p>
</div>
</div>
</div>
</div> </div>
<!-- 工作區分頁 - 主要分頁 --> <!-- 工作區分頁 - 主要分頁 -->