Add settings UI with WSL configuration support

- Add settings button to webview UI
- Implement settings panel with WSL bridge configuration
- Add real-time settings updates via VS Code configuration API
- Support for WSL distro, node path, and claude path configuration
- Improve user experience by eliminating manual config file editing
This commit is contained in:
erwinh22
2025-06-19 15:10:04 -04:00
parent 39ff5bb4e4
commit a0bbc5764e
7 changed files with 349 additions and 27 deletions

View File

@@ -7,9 +7,11 @@ import html from './ui';
const exec = util.promisify(cp.exec);
export function activate(context: vscode.ExtensionContext) {
console.log('Claude Code Chat extension is being activated!');
const provider = new ClaudeChatProvider(context.extensionUri, context);
const disposable = vscode.commands.registerCommand('claude-code-chat.openChat', () => {
console.log('Claude Code Chat command executed!');
provider.show();
});
@@ -33,6 +35,7 @@ export function activate(context: vscode.ExtensionContext) {
statusBarItem.show();
context.subscriptions.push(disposable, loadConversationDisposable, statusBarItem);
console.log('Claude Code Chat extension activation completed successfully!');
}
export function deactivate() { }
@@ -197,6 +200,12 @@ class ClaudeChatProvider {
case 'stopRequest':
this._stopClaudeProcess();
return;
case 'getSettings':
this._sendCurrentSettings();
return;
case 'updateSettings':
this._updateSettings(message.settings);
return;
}
},
null,
@@ -252,7 +261,7 @@ class ClaudeChatProvider {
await this._createBackupCommit(message);
}
catch (e) {
console.log("error", e)
console.log("error", e);
}
// Show loading indicator
@@ -281,15 +290,40 @@ class ClaudeChatProvider {
console.log('Claude command args:', args);
const claudeProcess = cp.spawn('claude', args, {
cwd: cwd,
stdio: ['pipe', 'pipe', 'pipe'],
env: {
...process.env,
FORCE_COLOR: '0',
NO_COLOR: '1'
}
});
// Get configuration
const config = vscode.workspace.getConfiguration('claudeCodeChat');
const wslEnabled = config.get<boolean>('wsl.enabled', false);
const wslDistro = config.get<string>('wsl.distro', 'Ubuntu');
const nodePath = config.get<string>('wsl.nodePath', '/usr/bin/node');
const claudePath = config.get<string>('wsl.claudePath', '/usr/local/bin/claude');
let claudeProcess: cp.ChildProcess;
if (wslEnabled) {
// Use WSL
console.log('Using WSL configuration:', { wslDistro, nodePath, claudePath });
claudeProcess = cp.spawn('wsl', ['-d', wslDistro, nodePath, '--no-warnings', '--enable-source-maps', claudePath, ...args], {
cwd: cwd,
stdio: ['pipe', 'pipe', 'pipe'],
env: {
...process.env,
FORCE_COLOR: '0',
NO_COLOR: '1'
}
});
} else {
// Use native claude command
console.log('Using native Claude command');
claudeProcess = cp.spawn('claude', args, {
cwd: cwd,
stdio: ['pipe', 'pipe', 'pipe'],
env: {
...process.env,
FORCE_COLOR: '0',
NO_COLOR: '1'
}
});
}
// Store process reference for potential termination
this._currentClaudeProcess = claudeProcess;
@@ -582,9 +616,19 @@ class ClaudeChatProvider {
type: 'loginRequired'
});
// Get configuration to check if WSL is enabled
const config = vscode.workspace.getConfiguration('claudeCodeChat');
const wslEnabled = config.get<boolean>('wsl.enabled', false);
const wslDistro = config.get<string>('wsl.distro', 'Ubuntu');
const claudePath = config.get<string>('wsl.claudePath', '/usr/local/bin/claude');
// Open terminal and run claude login
const terminal = vscode.window.createTerminal('Claude Login');
terminal.sendText('claude');
if (wslEnabled) {
terminal.sendText(`wsl -d ${wslDistro} ${claudePath}`);
} else {
terminal.sendText('claude');
}
terminal.show();
// Show info message
@@ -597,7 +641,7 @@ class ClaudeChatProvider {
private async _initializeBackupRepo(): Promise<void> {
try {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (!workspaceFolder) return;
if (!workspaceFolder) {return;}
const storagePath = this._context.storageUri?.fsPath;
if (!storagePath) {
@@ -630,7 +674,7 @@ class ClaudeChatProvider {
private async _createBackupCommit(userMessage: string): Promise<void> {
try {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (!workspaceFolder || !this._backupRepoPath) return;
if (!workspaceFolder || !this._backupRepoPath) {return;}
const workspacePath = workspaceFolder.uri.fsPath;
const now = new Date();
@@ -739,10 +783,10 @@ class ClaudeChatProvider {
private async _initializeConversations(): Promise<void> {
try {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (!workspaceFolder) return;
if (!workspaceFolder) {return;}
const storagePath = this._context.storageUri?.fsPath;
if (!storagePath) return;
if (!storagePath) {return;}
this._conversationsPath = path.join(storagePath, 'conversations');
@@ -765,7 +809,7 @@ class ClaudeChatProvider {
}
if (message.type === 'sessionInfo') {
message.data.sessionId
message.data.sessionId;
}
// Send to UI
@@ -783,7 +827,7 @@ class ClaudeChatProvider {
}
private async _saveCurrentConversation(): Promise<void> {
if (!this._conversationsPath || this._currentConversation.length === 0) return;
if (!this._conversationsPath || this._currentConversation.length === 0) {return;}
try {
// Create filename from first user message and timestamp
@@ -1009,12 +1053,12 @@ class ClaudeChatProvider {
}
private async _loadConversationHistory(filename: string): Promise<void> {
console.log("_loadConversationHistory")
if (!this._conversationsPath) return;
console.log("_loadConversationHistory");
if (!this._conversationsPath) {return;}
try {
const filePath = path.join(this._conversationsPath, filename);
console.log("filePath", filePath)
console.log("filePath", filePath);
let conversationData;
try {
@@ -1025,7 +1069,7 @@ class ClaudeChatProvider {
return;
}
console.log("conversationData", conversationData)
console.log("conversationData", conversationData);
// Load conversation into current state
this._currentConversation = conversationData.messages || [];
this._conversationStartTime = conversationData.startTime;
@@ -1069,7 +1113,37 @@ class ClaudeChatProvider {
}
private _getHtmlForWebview(): string {
return html
return html;
}
private _sendCurrentSettings(): void {
const config = vscode.workspace.getConfiguration('claudeCodeChat');
const settings = {
'wsl.enabled': config.get<boolean>('wsl.enabled', false),
'wsl.distro': config.get<string>('wsl.distro', 'Ubuntu'),
'wsl.nodePath': config.get<string>('wsl.nodePath', '/usr/bin/node'),
'wsl.claudePath': config.get<string>('wsl.claudePath', '/usr/local/bin/claude')
};
this._panel?.webview.postMessage({
type: 'settingsData',
data: settings
});
}
private async _updateSettings(settings: { [key: string]: any }): Promise<void> {
const config = vscode.workspace.getConfiguration('claudeCodeChat');
try {
for (const [key, value] of Object.entries(settings)) {
await config.update(key, value, vscode.ConfigurationTarget.Global);
}
vscode.window.showInformationMessage('Settings updated successfully');
} catch (error) {
console.error('Failed to update settings:', error);
vscode.window.showErrorMessage('Failed to update settings');
}
}
public dispose() {