Skip to content

Commit 1642719

Browse files
authored
Merge pull request AndyMik90#53 from AndyMik90/v2.5.6
V2.5.6
2 parents c7dde1f + 3efab86 commit 1642719

26 files changed

+1471
-304
lines changed

auto-claude-ui/src/main/agent/agent-process.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ export class AgentProcessManager {
241241
const log = data.toString('utf8');
242242
this.emitter.emit('log', taskId, log);
243243
processLog(log);
244+
// Print to console when DEBUG is enabled (visible in pnpm dev terminal)
245+
if (['true', '1', 'yes', 'on'].includes(process.env.DEBUG?.toLowerCase() ?? '')) {
246+
console.log(`[Agent:${taskId}] ${log.trim()}`);
247+
}
244248
});
245249

246250
// Handle stderr - explicitly decode as UTF-8 for cross-platform Unicode support
@@ -250,6 +254,10 @@ export class AgentProcessManager {
250254
// so we treat it as log, not error
251255
this.emitter.emit('log', taskId, log);
252256
processLog(log);
257+
// Print to console when DEBUG is enabled (visible in pnpm dev terminal)
258+
if (['true', '1', 'yes', 'on'].includes(process.env.DEBUG?.toLowerCase() ?? '')) {
259+
console.log(`[Agent:${taskId}] ${log.trim()}`);
260+
}
253261
});
254262

255263
// Handle process exit

auto-claude-ui/src/main/auto-claude-updater.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type {
2727
} from './updater/types';
2828

2929
// Export version management
30-
export { getBundledVersion } from './updater/version-manager';
30+
export { getBundledVersion, getEffectiveVersion } from './updater/version-manager';
3131

3232
// Export path resolution
3333
export {

auto-claude-ui/src/main/ipc-handlers/autobuild-source-handlers.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import type { IPCResult } from '../../shared/types';
55
import path from 'path';
66
import { existsSync, readFileSync, writeFileSync } from 'fs';
77
import type { AutoBuildSourceUpdateProgress, SourceEnvConfig, SourceEnvCheckResult } from '../../shared/types';
8-
import { checkForUpdates as checkSourceUpdates, downloadAndApplyUpdate, getBundledVersion, getEffectiveSourcePath } from '../auto-claude-updater';
8+
import { checkForUpdates as checkSourceUpdates, downloadAndApplyUpdate, getBundledVersion, getEffectiveVersion, getEffectiveSourcePath } from '../auto-claude-updater';
9+
import { debugLog } from '../../shared/utils/debug-logger';
910

1011

1112
/**
@@ -21,10 +22,16 @@ export function registerAutobuildSourceHandlers(
2122
ipcMain.handle(
2223
IPC_CHANNELS.AUTOBUILD_SOURCE_CHECK,
2324
async (): Promise<IPCResult<{ updateAvailable: boolean; currentVersion: string; latestVersion?: string; releaseNotes?: string; releaseUrl?: string; error?: string }>> => {
25+
console.log('[autobuild-source] Check for updates called');
26+
debugLog('[IPC] AUTOBUILD_SOURCE_CHECK called');
2427
try {
2528
const result = await checkSourceUpdates();
29+
console.log('[autobuild-source] Check result:', JSON.stringify(result, null, 2));
30+
debugLog('[IPC] AUTOBUILD_SOURCE_CHECK result:', result);
2631
return { success: true, data: result };
2732
} catch (error) {
33+
console.error('[autobuild-source] Check error:', error);
34+
debugLog('[IPC] AUTOBUILD_SOURCE_CHECK error:', error);
2835
return {
2936
success: false,
3037
error: error instanceof Error ? error.message : 'Failed to check for updates'
@@ -36,25 +43,33 @@ export function registerAutobuildSourceHandlers(
3643
ipcMain.on(
3744
IPC_CHANNELS.AUTOBUILD_SOURCE_DOWNLOAD,
3845
() => {
46+
debugLog('[IPC] Autobuild source download requested');
3947
const mainWindow = getMainWindow();
40-
if (!mainWindow) return;
48+
if (!mainWindow) {
49+
debugLog('[IPC] No main window available, aborting update');
50+
return;
51+
}
4152

4253
// Start download in background
4354
downloadAndApplyUpdate((progress) => {
55+
debugLog('[IPC] Update progress:', progress.stage, progress.message);
4456
mainWindow.webContents.send(
4557
IPC_CHANNELS.AUTOBUILD_SOURCE_PROGRESS,
4658
progress
4759
);
4860
}).then((result) => {
4961
if (result.success) {
62+
debugLog('[IPC] Update completed successfully, version:', result.version);
5063
mainWindow.webContents.send(
5164
IPC_CHANNELS.AUTOBUILD_SOURCE_PROGRESS,
5265
{
5366
stage: 'complete',
54-
message: `Updated to version ${result.version}`
67+
message: `Updated to version ${result.version}`,
68+
newVersion: result.version // Include new version for UI refresh
5569
} as AutoBuildSourceUpdateProgress
5670
);
5771
} else {
72+
debugLog('[IPC] Update failed:', result.error);
5873
mainWindow.webContents.send(
5974
IPC_CHANNELS.AUTOBUILD_SOURCE_PROGRESS,
6075
{
@@ -64,6 +79,7 @@ export function registerAutobuildSourceHandlers(
6479
);
6580
}
6681
}).catch((error) => {
82+
debugLog('[IPC] Update error:', error instanceof Error ? error.message : error);
6783
mainWindow.webContents.send(
6884
IPC_CHANNELS.AUTOBUILD_SOURCE_PROGRESS,
6985
{
@@ -88,7 +104,9 @@ export function registerAutobuildSourceHandlers(
88104
IPC_CHANNELS.AUTOBUILD_SOURCE_VERSION,
89105
async (): Promise<IPCResult<string>> => {
90106
try {
91-
const version = getBundledVersion();
107+
// Use effective version which accounts for source updates
108+
const version = getEffectiveVersion();
109+
debugLog('[IPC] Returning effective version:', version);
92110
return { success: true, data: version };
93111
} catch (error) {
94112
return {

auto-claude-ui/src/main/ipc-handlers/env-handlers.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export function registerEnvHandlers(
6262
if (config.githubAutoSync !== undefined) {
6363
existingVars['GITHUB_AUTO_SYNC'] = config.githubAutoSync ? 'true' : 'false';
6464
}
65+
// Git/Worktree Settings
66+
if (config.defaultBranch !== undefined) {
67+
existingVars['DEFAULT_BRANCH'] = config.defaultBranch;
68+
}
6569
if (config.graphitiEnabled !== undefined) {
6670
existingVars['GRAPHITI_ENABLED'] = config.graphitiEnabled ? 'true' : 'false';
6771
}
@@ -109,6 +113,13 @@ ${existingVars['GITHUB_TOKEN'] ? `GITHUB_TOKEN=${existingVars['GITHUB_TOKEN']}`
109113
${existingVars['GITHUB_REPO'] ? `GITHUB_REPO=${existingVars['GITHUB_REPO']}` : '# GITHUB_REPO=owner/repo'}
110114
${existingVars['GITHUB_AUTO_SYNC'] !== undefined ? `GITHUB_AUTO_SYNC=${existingVars['GITHUB_AUTO_SYNC']}` : '# GITHUB_AUTO_SYNC=false'}
111115
116+
# =============================================================================
117+
# GIT/WORKTREE SETTINGS (OPTIONAL)
118+
# =============================================================================
119+
# Default base branch for worktree creation
120+
# If not set, Auto Claude will auto-detect main/master, or fall back to current branch
121+
${existingVars['DEFAULT_BRANCH'] ? `DEFAULT_BRANCH=${existingVars['DEFAULT_BRANCH']}` : '# DEFAULT_BRANCH=main'}
122+
112123
# =============================================================================
113124
# UI SETTINGS (OPTIONAL)
114125
# =============================================================================
@@ -216,6 +227,11 @@ ${existingVars['GRAPHITI_DATABASE'] ? `GRAPHITI_DATABASE=${existingVars['GRAPHIT
216227
config.githubAutoSync = true;
217228
}
218229

230+
// Git/Worktree config
231+
if (vars['DEFAULT_BRANCH']) {
232+
config.defaultBranch = vars['DEFAULT_BRANCH'];
233+
}
234+
219235
if (vars['GRAPHITI_ENABLED']?.toLowerCase() === 'true') {
220236
config.graphitiEnabled = true;
221237
}

auto-claude-ui/src/main/ipc-handlers/settings-handlers.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
} from '../../shared/types';
1111
import { AgentManager } from '../agent';
1212
import type { BrowserWindow } from 'electron';
13+
import { getEffectiveVersion } from '../auto-claude-updater';
1314

1415
const settingsPath = path.join(app.getPath('userData'), 'settings.json');
1516

@@ -264,7 +265,10 @@ export function registerSettingsHandlers(
264265
// ============================================
265266

266267
ipcMain.handle(IPC_CHANNELS.APP_VERSION, async (): Promise<string> => {
267-
return app.getVersion();
268+
// Use effective version which accounts for source updates
269+
const version = getEffectiveVersion();
270+
console.log('[settings-handlers] APP_VERSION returning:', version);
271+
return version;
268272
});
269273

270274
// ============================================

auto-claude-ui/src/main/ipc-handlers/terminal-handlers.ts

Lines changed: 105 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { getUsageMonitor } from '../claude-profile/usage-monitor';
77
import { TerminalManager } from '../terminal-manager';
88
import { projectStore } from '../project-store';
99
import { terminalNameGenerator } from '../terminal-name-generator';
10+
import { debugLog, debugError } from '../../shared/utils/debug-logger';
11+
import { escapeShellArg } from '../../shared/utils/shell-escape';
1012

1113

1214
/**
@@ -162,14 +164,108 @@ export function registerTerminalHandlers(
162164
ipcMain.handle(
163165
IPC_CHANNELS.CLAUDE_PROFILE_SET_ACTIVE,
164166
async (_, profileId: string): Promise<IPCResult> => {
167+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] ========== PROFILE SWITCH START ==========');
168+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Requested profile ID:', profileId);
169+
165170
try {
166171
const profileManager = getClaudeProfileManager();
172+
const previousProfile = profileManager.getActiveProfile();
173+
const previousProfileId = previousProfile.id;
174+
const newProfile = profileManager.getProfile(profileId);
175+
176+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Previous profile:', {
177+
id: previousProfile.id,
178+
name: previousProfile.name,
179+
hasOAuthToken: !!previousProfile.oauthToken,
180+
isDefault: previousProfile.isDefault
181+
});
182+
183+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] New profile:', newProfile ? {
184+
id: newProfile.id,
185+
name: newProfile.name,
186+
hasOAuthToken: !!newProfile.oauthToken,
187+
isDefault: newProfile.isDefault
188+
} : 'NOT FOUND');
189+
167190
const success = profileManager.setActiveProfile(profileId);
191+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] setActiveProfile result:', success);
192+
168193
if (!success) {
194+
debugError('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Profile not found, aborting');
169195
return { success: false, error: 'Profile not found' };
170196
}
197+
198+
// If the profile actually changed, restart Claude in active terminals
199+
// This ensures existing Claude sessions use the new profile's OAuth token
200+
const profileChanged = previousProfileId !== profileId;
201+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Profile changed:', profileChanged, {
202+
previousProfileId,
203+
newProfileId: profileId
204+
});
205+
206+
if (profileChanged) {
207+
const activeTerminalIds = terminalManager.getActiveTerminalIds();
208+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Active terminal IDs:', activeTerminalIds);
209+
210+
const switchPromises: Promise<void>[] = [];
211+
const terminalsInClaudeMode: string[] = [];
212+
const terminalsNotInClaudeMode: string[] = [];
213+
214+
for (const terminalId of activeTerminalIds) {
215+
const isClaudeMode = terminalManager.isClaudeMode(terminalId);
216+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Terminal check:', {
217+
terminalId,
218+
isClaudeMode
219+
});
220+
221+
if (isClaudeMode) {
222+
terminalsInClaudeMode.push(terminalId);
223+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Queuing terminal for profile switch:', terminalId);
224+
switchPromises.push(
225+
terminalManager.switchClaudeProfile(terminalId, profileId)
226+
.then(() => {
227+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Terminal profile switch SUCCESS:', terminalId);
228+
})
229+
.catch((err) => {
230+
debugError('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Terminal profile switch FAILED:', terminalId, err);
231+
throw err; // Re-throw so Promise.allSettled correctly reports rejections
232+
})
233+
);
234+
} else {
235+
terminalsNotInClaudeMode.push(terminalId);
236+
}
237+
}
238+
239+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Terminal summary:', {
240+
total: activeTerminalIds.length,
241+
inClaudeMode: terminalsInClaudeMode.length,
242+
notInClaudeMode: terminalsNotInClaudeMode.length,
243+
terminalsToSwitch: terminalsInClaudeMode,
244+
terminalsSkipped: terminalsNotInClaudeMode
245+
});
246+
247+
// Wait for all switches to complete (but don't fail the main operation if some fail)
248+
if (switchPromises.length > 0) {
249+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Waiting for', switchPromises.length, 'terminal switches...');
250+
const results = await Promise.allSettled(switchPromises);
251+
const fulfilled = results.filter(r => r.status === 'fulfilled').length;
252+
const rejected = results.filter(r => r.status === 'rejected').length;
253+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Switch results:', {
254+
total: results.length,
255+
fulfilled,
256+
rejected
257+
});
258+
} else {
259+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] No terminals in Claude mode to switch');
260+
}
261+
} else {
262+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] Same profile selected, no terminal switches needed');
263+
}
264+
265+
debugLog('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] ========== PROFILE SWITCH COMPLETE ==========');
171266
return { success: true };
172267
} catch (error) {
268+
debugError('[terminal-handlers:CLAUDE_PROFILE_SET_ACTIVE] EXCEPTION:', error);
173269
return {
174270
success: false,
175271
error: error instanceof Error ? error.message : 'Failed to set active Claude profile'
@@ -208,7 +304,7 @@ export function registerTerminalHandlers(
208304
const { mkdirSync, existsSync } = await import('fs');
209305
if (!existsSync(profile.configDir)) {
210306
mkdirSync(profile.configDir, { recursive: true });
211-
console.warn('[IPC] Created config directory:', profile.configDir);
307+
debugLog('[IPC] Created config directory:', profile.configDir);
212308
}
213309
}
214310

@@ -217,7 +313,7 @@ export function registerTerminalHandlers(
217313
const terminalId = `claude-login-${profileId}-${Date.now()}`;
218314
const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp';
219315

220-
console.warn('[IPC] Initializing Claude profile:', {
316+
debugLog('[IPC] Initializing Claude profile:', {
221317
profileId,
222318
profileName: profile.name,
223319
configDir: profile.configDir,
@@ -235,12 +331,14 @@ export function registerTerminalHandlers(
235331
let loginCommand: string;
236332
if (!profile.isDefault && profile.configDir) {
237333
// Use export and run in subshell to ensure CLAUDE_CONFIG_DIR is properly set
238-
loginCommand = `export CLAUDE_CONFIG_DIR="${profile.configDir}" && echo "Config dir: $CLAUDE_CONFIG_DIR" && claude setup-token`;
334+
// SECURITY: Use escapeShellArg to prevent command injection via configDir
335+
const escapedConfigDir = escapeShellArg(profile.configDir);
336+
loginCommand = `export CLAUDE_CONFIG_DIR=${escapedConfigDir} && echo "Config dir: $CLAUDE_CONFIG_DIR" && claude setup-token`;
239337
} else {
240338
loginCommand = 'claude setup-token';
241339
}
242340

243-
console.warn('[IPC] Sending login command to terminal:', loginCommand);
341+
debugLog('[IPC] Sending login command to terminal:', loginCommand);
244342

245343
// Write the login command to the terminal
246344
terminalManager.write(terminalId, `${loginCommand}\r`);
@@ -263,7 +361,7 @@ export function registerTerminalHandlers(
263361
}
264362
};
265363
} catch (error) {
266-
console.error('[IPC] Failed to initialize Claude profile:', error);
364+
debugError('[IPC] Failed to initialize Claude profile:', error);
267365
return {
268366
success: false,
269367
error: error instanceof Error ? error.message : 'Failed to initialize Claude profile'
@@ -284,7 +382,7 @@ export function registerTerminalHandlers(
284382
}
285383
return { success: true };
286384
} catch (error) {
287-
console.error('[IPC] Failed to set OAuth token:', error);
385+
debugError('[IPC] Failed to set OAuth token:', error);
288386
return {
289387
success: false,
290388
error: error instanceof Error ? error.message : 'Failed to set OAuth token'
@@ -569,5 +667,5 @@ export function initializeUsageMonitorForwarding(mainWindow: BrowserWindow): voi
569667
mainWindow.webContents.send(IPC_CHANNELS.PROACTIVE_SWAP_NOTIFICATION, notification);
570668
});
571669

572-
console.warn('[terminal-handlers] Usage monitor event forwarding initialized');
670+
debugLog('[terminal-handlers] Usage monitor event forwarding initialized');
573671
}

0 commit comments

Comments
 (0)