Integrate external CLI tools (Claude, Node, npx) in Electron apps with proper PATH handling
View on GitHubplugins/aai-stack-electron/skills/electron-cli-integration/SKILL.md
February 1, 2026
Select agents to install to:
npx add-skill https://github.com/the-answerai/alphaagent-team/blob/main/plugins/aai-stack-electron/skills/electron-cli-integration/SKILL.md -a claude-code --skill electron-cli-integrationInstallation paths:
.claude/skills/electron-cli-integration/# Electron CLI Integration Skill
When Electron apps launch from Finder/Explorer, the PATH is minimal. This skill covers detecting and using CLI tools reliably.
## The PATH Problem
When launched from terminal:
```
PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:~/.nvm/versions/node/v20/bin:...
```
When launched from Finder (macOS):
```
PATH=/usr/bin:/bin:/usr/sbin:/sbin
```
## CLI Detector Pattern
```typescript
// electron/cli-detector.ts
import { exec } from 'child_process';
import { promisify } from 'util';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
const execAsync = promisify(exec);
export interface CliStatus {
found: boolean;
path?: string;
version?: string;
error?: string;
}
// Common installation paths for various tools
function getCommonPaths(toolName: string): string[] {
const home = os.homedir();
return [
// Homebrew (macOS)
`/usr/local/bin/${toolName}`,
`/opt/homebrew/bin/${toolName}`,
// User-local installations
path.join(home, '.local', 'bin', toolName),
// Tool-specific locations
path.join(home, '.claude', 'bin', toolName),
// Node.js via nvm
path.join(home, '.nvm', 'versions', 'node', 'current', 'bin', toolName),
// System paths
`/usr/bin/${toolName}`,
// Windows-specific (if on Windows)
path.join(home, 'AppData', 'Roaming', 'npm', `${toolName}.cmd`),
`C:\\Program Files\\nodejs\\${toolName}.cmd`,
];
}
function isExecutable(filePath: string): boolean {
try {
fs.accessSync(filePath, fs.constants.X_OK);
return true;
} catch {
return false;
}
}
function findInCommonPaths(toolName: string): string | null {
for (const toolPath of getCommonPaths(toolName)) {
if (fs.existsSync(toolPath) && isExecutable(toolPath)) {
return toolPath;
}
}
return null;
}
export async function detectCli(toolName: string): Promise<CliStatus> {
// First, check common installation paths
let toolPath = findInCommonPa