* fix(frontend): use getAugmentedEnv in insights and changelog services Fixed 'Process exited with code null/1' errors in Insights panel by using getAugmentedEnv() instead of raw process.env. When Electron launches from Finder/Dock on macOS, process.env.PATH is minimal and doesn't include tools like 'claude' CLI. Changed files: - insights/config.ts: Use getAugmentedEnv() in getProcessEnv() - changelog/generator.ts: Use getAugmentedEnv() instead of manual PATH additions - changelog/version-suggester.ts: Use getAugmentedEnv() instead of manual PATH additions This reuses existing infrastructure (getAugmentedEnv) that's already used throughout the frontend for GitHub/GitLab operations, ensuring consistency. Fixes #558 Signed-off-by: Hunter Luisi <hluisi@gmail.com> * chore: pin electron version for monorepo builds electron-builder cannot compute version from hoisted node_modules in npm workspaces when using caret versions (^39.2.7). This is a known electron-builder issue. Pinning to exact version (39.2.7) allows electron-builder to proceed without looking for electron in local node_modules. Signed-off-by: Hunter Luisi <hluisi@gmail.com> * fix(frontend): show only stderr in error messages for cleaner output Separate stderr tracking from combined output. Error messages now show only actual errors (stderr) instead of mixed stdout+stderr, making debugging clearer. Combined output still used for rate limit detection. --------- Signed-off-by: Hunter Luisi <hluisi@gmail.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
This commit is contained in:
@@ -114,7 +114,7 @@
|
||||
"@vitejs/plugin-react": "^5.1.2",
|
||||
"autoprefixer": "^10.4.22",
|
||||
"cross-env": "^10.1.0",
|
||||
"electron": "^39.2.7",
|
||||
"electron": "39.2.7",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-vite": "^5.0.0",
|
||||
"eslint": "^9.39.1",
|
||||
|
||||
@@ -13,6 +13,7 @@ import { extractChangelog } from './parser';
|
||||
import { getCommits, getBranchDiffCommits } from './git-integration';
|
||||
import { detectRateLimit, createSDKRateLimitInfo, getProfileEnv } from '../rate-limit-detector';
|
||||
import { parsePythonCommand } from '../python-detector';
|
||||
import { getAugmentedEnv } from '../env-utils';
|
||||
|
||||
/**
|
||||
* Core changelog generation logic
|
||||
@@ -246,21 +247,9 @@ export class ChangelogGenerator extends EventEmitter {
|
||||
const homeDir = os.homedir();
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
// Build PATH with platform-appropriate separator and locations
|
||||
const pathAdditions = isWindows
|
||||
? [
|
||||
path.join(homeDir, 'AppData', 'Local', 'Programs', 'claude'),
|
||||
path.join(homeDir, 'AppData', 'Roaming', 'npm'),
|
||||
path.join(homeDir, '.local', 'bin'),
|
||||
'C:\\Program Files\\Claude',
|
||||
'C:\\Program Files (x86)\\Claude'
|
||||
]
|
||||
: [
|
||||
'/usr/local/bin',
|
||||
'/opt/homebrew/bin',
|
||||
path.join(homeDir, '.local', 'bin'),
|
||||
path.join(homeDir, 'bin')
|
||||
];
|
||||
// Use getAugmentedEnv() to ensure common tool paths are available
|
||||
// even when app is launched from Finder/Dock
|
||||
const augmentedEnv = getAugmentedEnv();
|
||||
|
||||
// Get active Claude profile environment (OAuth token preferred, falls back to CLAUDE_CONFIG_DIR)
|
||||
const profileEnv = getProfileEnv();
|
||||
@@ -271,15 +260,13 @@ export class ChangelogGenerator extends EventEmitter {
|
||||
});
|
||||
|
||||
const spawnEnv: Record<string, string> = {
|
||||
...process.env as Record<string, string>,
|
||||
...augmentedEnv,
|
||||
...this.autoBuildEnv,
|
||||
...profileEnv, // Include active Claude profile config
|
||||
// Ensure critical env vars are set for claude CLI
|
||||
// Use USERPROFILE on Windows, HOME on Unix
|
||||
...(isWindows ? { USERPROFILE: homeDir } : { HOME: homeDir }),
|
||||
USER: process.env.USER || process.env.USERNAME || 'user',
|
||||
// Add common binary locations to PATH for claude CLI
|
||||
PATH: [process.env.PATH || '', ...pathAdditions].filter(Boolean).join(path.delimiter),
|
||||
PYTHONUNBUFFERED: '1',
|
||||
PYTHONIOENCODING: 'utf-8',
|
||||
PYTHONUTF8: '1'
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as os from 'os';
|
||||
import type { GitCommit } from '../../shared/types';
|
||||
import { getProfileEnv } from '../rate-limit-detector';
|
||||
import { parsePythonCommand } from '../python-detector';
|
||||
import { getAugmentedEnv } from '../env-utils';
|
||||
|
||||
interface VersionSuggestion {
|
||||
version: string;
|
||||
@@ -215,31 +216,19 @@ except Exception as e:
|
||||
const homeDir = os.homedir();
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
// Build PATH with platform-appropriate separator and locations
|
||||
const pathAdditions = isWindows
|
||||
? [
|
||||
path.join(homeDir, 'AppData', 'Local', 'Programs', 'claude'),
|
||||
path.join(homeDir, 'AppData', 'Roaming', 'npm'),
|
||||
path.join(homeDir, '.local', 'bin'),
|
||||
'C:\\Program Files\\Claude',
|
||||
'C:\\Program Files (x86)\\Claude'
|
||||
]
|
||||
: [
|
||||
'/usr/local/bin',
|
||||
'/opt/homebrew/bin',
|
||||
path.join(homeDir, '.local', 'bin'),
|
||||
path.join(homeDir, 'bin')
|
||||
];
|
||||
// Use getAugmentedEnv() to ensure common tool paths are available
|
||||
// even when app is launched from Finder/Dock
|
||||
const augmentedEnv = getAugmentedEnv();
|
||||
|
||||
// Get active Claude profile environment
|
||||
const profileEnv = getProfileEnv();
|
||||
|
||||
const spawnEnv: Record<string, string> = {
|
||||
...process.env as Record<string, string>,
|
||||
...augmentedEnv,
|
||||
...profileEnv,
|
||||
// Ensure critical env vars are set for claude CLI
|
||||
...(isWindows ? { USERPROFILE: homeDir } : { HOME: homeDir }),
|
||||
USER: process.env.USER || process.env.USERNAME || 'user',
|
||||
PATH: [process.env.PATH || '', ...pathAdditions].filter(Boolean).join(path.delimiter),
|
||||
PYTHONUNBUFFERED: '1',
|
||||
PYTHONIOENCODING: 'utf-8',
|
||||
PYTHONUTF8: '1'
|
||||
|
||||
@@ -3,7 +3,8 @@ import { existsSync, readFileSync } from 'fs';
|
||||
import { app } from 'electron';
|
||||
import { getProfileEnv } from '../rate-limit-detector';
|
||||
import { getValidatedPythonPath } from '../python-detector';
|
||||
import { getConfiguredPythonPath } from '../python-env-manager';
|
||||
import { getConfiguredPythonPath, pythonEnvManager } from '../python-env-manager';
|
||||
import { getAugmentedEnv } from '../env-utils';
|
||||
|
||||
/**
|
||||
* Configuration manager for insights service
|
||||
@@ -107,9 +108,15 @@ export class InsightsConfig {
|
||||
getProcessEnv(): Record<string, string> {
|
||||
const autoBuildEnv = this.loadAutoBuildEnv();
|
||||
const profileEnv = getProfileEnv();
|
||||
// Get Python environment (PYTHONPATH for bundled packages like python-dotenv)
|
||||
const pythonEnv = pythonEnvManager.getPythonEnv();
|
||||
// Use getAugmentedEnv() to ensure common tool paths (claude, dotnet, etc.)
|
||||
// are available even when app is launched from Finder/Dock
|
||||
const augmentedEnv = getAugmentedEnv();
|
||||
|
||||
return {
|
||||
...process.env as Record<string, string>,
|
||||
...augmentedEnv,
|
||||
...pythonEnv, // Include PYTHONPATH for bundled site-packages
|
||||
...autoBuildEnv,
|
||||
...profileEnv,
|
||||
PYTHONUNBUFFERED: '1',
|
||||
|
||||
@@ -130,6 +130,7 @@ export class InsightsExecutor extends EventEmitter {
|
||||
let suggestedTask: InsightsChatMessage['suggestedTask'] | undefined;
|
||||
const toolsUsed: InsightsToolUsage[] = [];
|
||||
let allInsightsOutput = '';
|
||||
let stderrOutput = '';
|
||||
|
||||
proc.stdout?.on('data', (data: Buffer) => {
|
||||
const text = data.toString();
|
||||
@@ -159,8 +160,9 @@ export class InsightsExecutor extends EventEmitter {
|
||||
|
||||
proc.stderr?.on('data', (data: Buffer) => {
|
||||
const text = data.toString();
|
||||
// Collect stderr for rate limit detection too
|
||||
// Collect stderr for rate limit detection and error reporting
|
||||
allInsightsOutput = (allInsightsOutput + text).slice(-10000);
|
||||
stderrOutput = (stderrOutput + text).slice(-2000);
|
||||
console.error('[Insights]', text);
|
||||
});
|
||||
|
||||
@@ -196,7 +198,11 @@ export class InsightsExecutor extends EventEmitter {
|
||||
toolsUsed
|
||||
});
|
||||
} else {
|
||||
const error = `Process exited with code ${code}`;
|
||||
// Include stderr output in error message for debugging
|
||||
const stderrSummary = stderrOutput.trim()
|
||||
? `\n\nError output:\n${stderrOutput.slice(-500)}`
|
||||
: '';
|
||||
const error = `Process exited with code ${code}${stderrSummary}`;
|
||||
this.emit('stream-chunk', projectId, {
|
||||
type: 'error',
|
||||
error
|
||||
|
||||
Reference in New Issue
Block a user