From 3ae44a727759b0d8a2b083dcf176ba61995a892a Mon Sep 17 00:00:00 2001 From: xuxu777xu <1728019186@qq.com> Date: Sat, 7 Feb 2026 13:29:59 +0800 Subject: [PATCH 1/2] feat: add Windows drive switcher dropdown in FolderPicker When navigating to a drive root on Windows (e.g. C:\), path.dirname returns itself, disabling the "go up" button and trapping the user on that drive. This adds a compact dropdown next to the up button that lists all available drives (auto-detected via fs.accessSync), allowing quick switching between drives. macOS/Linux are unaffected (empty array, dropdown not rendered). Co-Authored-By: Claude Opus 4.6 --- src/app/api/files/browse/route.ts | 18 ++++++++++++++ src/components/chat/FolderPicker.tsx | 36 +++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/app/api/files/browse/route.ts b/src/app/api/files/browse/route.ts index a264bd45..d51674b2 100644 --- a/src/app/api/files/browse/route.ts +++ b/src/app/api/files/browse/route.ts @@ -4,6 +4,21 @@ import path from 'path'; import os from 'os'; import type { ErrorResponse } from '@/types'; +function getWindowsDrives(): string[] { + if (process.platform !== 'win32') return []; + const drives: string[] = []; + for (let i = 65; i <= 90; i++) { + const drive = String.fromCharCode(i) + ':\\'; + try { + fs.accessSync(drive); + drives.push(drive); + } catch { + // drive not available + } + } + return drives; +} + // List only directories for folder browsing (no safety restriction since user is choosing where to work) export async function GET(request: NextRequest) { const { searchParams } = request.nextUrl; @@ -28,10 +43,13 @@ export async function GET(request: NextRequest) { })) .sort((a, b) => a.name.localeCompare(b.name)); + const drives = getWindowsDrives(); + return NextResponse.json({ current: resolvedDir, parent: path.dirname(resolvedDir) !== resolvedDir ? path.dirname(resolvedDir) : null, directories, + drives, }); } catch { return NextResponse.json( diff --git a/src/components/chat/FolderPicker.tsx b/src/components/chat/FolderPicker.tsx index d56bb8dd..bf61862a 100644 --- a/src/components/chat/FolderPicker.tsx +++ b/src/components/chat/FolderPicker.tsx @@ -11,6 +11,12 @@ import { DialogTitle, DialogFooter, } from '@/components/ui/dialog'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from '@/components/ui/dropdown-menu'; import { Input } from '@/components/ui/input'; import { ScrollArea } from '@/components/ui/scroll-area'; @@ -23,6 +29,7 @@ interface BrowseResponse { current: string; parent: string | null; directories: FolderEntry[]; + drives?: string[]; } interface FolderPickerProps { @@ -38,6 +45,7 @@ export function FolderPicker({ open, onOpenChange, onSelect, initialPath }: Fold const [directories, setDirectories] = useState([]); const [loading, setLoading] = useState(false); const [pathInput, setPathInput] = useState(''); + const [drives, setDrives] = useState([]); const browse = useCallback(async (dir?: string) => { setLoading(true); @@ -52,6 +60,7 @@ export function FolderPicker({ open, onOpenChange, onSelect, initialPath }: Fold setParentDir(data.parent); setDirectories(data.directories); setPathInput(data.current); + setDrives(data.drives || []); } } catch { // silently fail @@ -108,7 +117,7 @@ export function FolderPicker({ open, onOpenChange, onSelect, initialPath }: Fold {/* Directory browser */}
- {/* Current path + go up */} + {/* Current path + go up + drive switcher */}
+ {drives.length > 0 && ( + + + + + + {drives.map((drive) => { + const letter = drive.charAt(0).toUpperCase(); + const isCurrent = currentDir.toUpperCase().startsWith(letter + ':'); + return ( + browse(drive)} + > + {letter}: + {drive} + + ); + })} + + + )} {currentDir} From 0234240066c50e4c0b82cecb193297e789b81be7 Mon Sep 17 00:00:00 2001 From: xuxu777xu <1728019186@qq.com> Date: Sat, 7 Feb 2026 13:35:04 +0800 Subject: [PATCH 2/2] feat: full Windows platform adaptation - Add src/lib/platform.ts: cross-platform Claude CLI discovery (candidate paths, .cmd/.bat shell handling, where/which fallback) - Refactor claude-status route and claude-client to use shared platform utils - Electron main: Windows process spawning (windowsHide), PATH construction with AppData/npm dirs, titleBarOverlay, .ico icon support - electron-builder.yml: add win/nsis build targets - package.json: add electron:pack:win script - FolderPicker: drive switcher dropdown for navigating between drives - SkillsManager: fix duplicate key warning with filePath fallback Co-Authored-By: Claude Opus 4.6 --- build/icon.ico | Bin 0 -> 285478 bytes electron-builder.yml | 14 +++ electron/main.ts | 78 +++++++++--- package.json | 4 +- src/app/api/claude-status/route.ts | 70 +---------- src/components/skills/SkillsManager.tsx | 2 +- src/lib/claude-client.ts | 53 ++------ src/lib/platform.ts | 156 ++++++++++++++++++++++++ 8 files changed, 251 insertions(+), 126 deletions(-) create mode 100644 build/icon.ico create mode 100644 src/lib/platform.ts diff --git a/build/icon.ico b/build/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..af7fa09c49a72498a817d5678dbad317e467a09c GIT binary patch literal 285478 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 { + // Only macOS needs login-shell env loading; Windows/Linux GUI apps inherit full env + if (process.platform !== 'darwin') { + return {}; + } try { const shell = process.env.SHELL || '/bin/zsh'; const result = execFileSync(shell, ['-ilc', 'env'], { @@ -106,12 +110,32 @@ function startServer(port: number): ChildProcess { serverErrors = []; const home = os.homedir(); - const basePath = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin`; const shellPath = userShellEnv.PATH || process.env.PATH || ''; + const sep = path.delimiter; // ';' on Windows, ':' on Unix + + let constructedPath: string; + if (process.platform === 'win32') { + const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming'); + const localAppData = process.env.LOCALAPPDATA || path.join(home, 'AppData', 'Local'); + const winExtra = [ + path.join(appData, 'npm'), + path.join(localAppData, 'npm'), + path.join(home, '.npm-global', 'bin'), + path.join(home, '.local', 'bin'), + path.join(home, '.claude', 'bin'), + ]; + const allParts = [shellPath, ...winExtra].join(sep).split(sep).filter(Boolean); + constructedPath = [...new Set(allParts)].join(sep); + } else { + const basePath = `/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin`; + const raw = `${basePath}:${home}/.npm-global/bin:${home}/.local/bin:${home}/.claude/bin:${shellPath}`; + const allParts = raw.split(':').filter(Boolean); + constructedPath = [...new Set(allParts)].join(':'); + } const env: Record = { ...userShellEnv, - ...process.env as Record, + ...(process.env as Record), // Ensure user shell env vars override (especially API keys) ...userShellEnv, PORT: String(port), @@ -119,17 +143,28 @@ function startServer(port: number): ChildProcess { CLAUDE_GUI_DATA_DIR: path.join(home, '.codepilot'), ELECTRON_RUN_AS_NODE: '1', HOME: home, - PATH: `${basePath}:${home}/.npm-global/bin:${home}/.local/bin:${home}/.claude/bin:${shellPath}`, + USERPROFILE: home, + PATH: constructedPath, }; - // Spawn via /bin/sh to prevent the Electron binary from appearing - // as a separate Dock icon on macOS (even with ELECTRON_RUN_AS_NODE=1, - // macOS may show a Dock entry for the Electron Framework binary). - const child = spawn('/bin/sh', ['-c', `exec "${nodePath}" "${serverPath}"`], { - env, - stdio: 'pipe', - cwd: standaloneDir, - }); + // On Windows, spawn Node.js directly with windowsHide to prevent console flash. + // On macOS, spawn via /bin/sh to prevent the Electron binary from appearing + // as a separate Dock icon (even with ELECTRON_RUN_AS_NODE=1). + let child: ChildProcess; + if (process.platform === 'win32') { + child = spawn(nodePath, [serverPath], { + env, + stdio: 'pipe', + cwd: standaloneDir, + windowsHide: true, + }); + } else { + child = spawn('/bin/sh', ['-c', `exec "${nodePath}" "${serverPath}"`], { + env, + stdio: 'pipe', + cwd: standaloneDir, + }); + } child.stdout?.on('data', (data: Buffer) => { const msg = data.toString().trim(); @@ -155,23 +190,38 @@ function getIconPath(): string { if (isDev) { return path.join(process.cwd(), 'build', 'icon.png'); } + if (process.platform === 'win32') { + return path.join(process.resourcesPath, 'icon.ico'); + } return path.join(process.resourcesPath, 'icon.icns'); } function createWindow(port: number) { - mainWindow = new BrowserWindow({ + const windowOptions: Electron.BrowserWindowConstructorOptions = { width: 1280, height: 860, minWidth: 800, minHeight: 600, icon: getIconPath(), - titleBarStyle: 'hiddenInset', webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false, }, - }); + }; + + if (process.platform === 'darwin') { + windowOptions.titleBarStyle = 'hiddenInset'; + } else if (process.platform === 'win32') { + windowOptions.titleBarStyle = 'hidden'; + windowOptions.titleBarOverlay = { + color: '#00000000', + symbolColor: '#888888', + height: 44, + }; + } + + mainWindow = new BrowserWindow(windowOptions); mainWindow.loadURL(`http://127.0.0.1:${port}`); diff --git a/package.json b/package.json index 51402898..9b207162 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "lint": "eslint", "electron:dev": "concurrently -k \"next dev\" \"wait-on http://localhost:3000 && electron .\"", "electron:build": "next build && node scripts/build-electron.mjs", - "electron:pack": "npm run electron:build && electron-builder --mac --config electron-builder.yml" + "electron:pack": "npm run electron:build && electron-builder --config electron-builder.yml", + "electron:pack:mac": "npm run electron:build && electron-builder --mac --config electron-builder.yml", + "electron:pack:win": "npm run electron:build && electron-builder --win --config electron-builder.yml" }, "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.33", diff --git a/src/app/api/claude-status/route.ts b/src/app/api/claude-status/route.ts index fe36ad16..16ee488d 100644 --- a/src/app/api/claude-status/route.ts +++ b/src/app/api/claude-status/route.ts @@ -1,76 +1,14 @@ import { NextResponse } from 'next/server'; -import { execFile, execFileSync } from 'child_process'; -import { promisify } from 'util'; -import os from 'os'; -import path from 'path'; - -const execFileAsync = promisify(execFile); - -function getExpandedPath(): string { - const home = os.homedir(); - const extra = [ - '/usr/local/bin', - '/opt/homebrew/bin', - '/usr/bin', - '/bin', - path.join(home, '.npm-global', 'bin'), - path.join(home, '.nvm', 'current', 'bin'), - path.join(home, '.local', 'bin'), - path.join(home, '.claude', 'bin'), - ]; - const current = process.env.PATH || ''; - const parts = current.split(':'); - for (const p of extra) { - if (!parts.includes(p)) parts.push(p); - } - return parts.join(':'); -} - -function findClaudePath(): string | null { - const home = os.homedir(); - const candidates = [ - '/usr/local/bin/claude', - '/opt/homebrew/bin/claude', - path.join(home, '.npm-global', 'bin', 'claude'), - path.join(home, '.local', 'bin', 'claude'), - path.join(home, '.claude', 'bin', 'claude'), - ]; - - for (const p of candidates) { - try { - execFileSync(p, ['--version'], { timeout: 3000, stdio: 'pipe' }); - return p; - } catch { - // not found, try next - } - } - - // Fallback: use `which claude` with expanded PATH - try { - const result = execFileSync('/usr/bin/which', ['claude'], { - timeout: 3000, - stdio: 'pipe', - env: { ...process.env, PATH: getExpandedPath() }, - }); - return result.toString().trim() || null; - } catch { - return null; - } -} +import { findClaudeBinary, getClaudeVersion } from '@/lib/platform'; export async function GET() { try { - const claudePath = findClaudePath(); + const claudePath = findClaudeBinary(); if (!claudePath) { return NextResponse.json({ connected: false, version: null }); } - - const { stdout } = await execFileAsync(claudePath, ['--version'], { - timeout: 5000, - env: { ...process.env, PATH: getExpandedPath() }, - }); - const version = stdout.trim(); - return NextResponse.json({ connected: true, version }); + const version = await getClaudeVersion(claudePath); + return NextResponse.json({ connected: !!version, version }); } catch { return NextResponse.json({ connected: false, version: null }); } diff --git a/src/components/skills/SkillsManager.tsx b/src/components/skills/SkillsManager.tsx index b2fc3f9c..61303b07 100644 --- a/src/components/skills/SkillsManager.tsx +++ b/src/components/skills/SkillsManager.tsx @@ -210,7 +210,7 @@ export function SkillsManager() { {pluginSkills.map((skill) => ( = { ...process.env as Record }; - // Ensure HOME is explicitly set so Claude Code can find ~/.claude/commands/ - if (!sdkEnv.HOME) { - sdkEnv.HOME = os.homedir(); - } + // Ensure HOME/USERPROFILE are set so Claude Code can find ~/.claude/commands/ + if (!sdkEnv.HOME) sdkEnv.HOME = os.homedir(); + if (!sdkEnv.USERPROFILE) sdkEnv.USERPROFILE = os.homedir(); + // Ensure SDK subprocess has expanded PATH (consistent with Electron mode) + sdkEnv.PATH = getExpandedPath(); const appToken = getSetting('anthropic_auth_token'); const appBaseUrl = getSetting('anthropic_base_url'); diff --git a/src/lib/platform.ts b/src/lib/platform.ts new file mode 100644 index 00000000..de0a5d10 --- /dev/null +++ b/src/lib/platform.ts @@ -0,0 +1,156 @@ +import { execFileSync, execFile } from 'child_process'; +import { promisify } from 'util'; +import os from 'os'; +import path from 'path'; + +const execFileAsync = promisify(execFile); + +export const isWindows = process.platform === 'win32'; +export const isMac = process.platform === 'darwin'; + +/** + * Whether the given binary path requires shell execution. + * On Windows, .cmd/.bat files cannot be executed directly by execFileSync. + */ +function needsShell(binPath: string): boolean { + return isWindows && /\.(cmd|bat)$/i.test(binPath); +} + +/** + * Extra PATH directories to search for Claude CLI and other tools. + */ +export function getExtraPathDirs(): string[] { + const home = os.homedir(); + if (isWindows) { + const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming'); + const localAppData = process.env.LOCALAPPDATA || path.join(home, 'AppData', 'Local'); + return [ + path.join(appData, 'npm'), + path.join(localAppData, 'npm'), + path.join(home, '.npm-global', 'bin'), + path.join(home, '.claude', 'bin'), + path.join(home, '.local', 'bin'), + path.join(home, '.nvm', 'current', 'bin'), + ]; + } + return [ + '/usr/local/bin', + '/opt/homebrew/bin', + '/usr/bin', + '/bin', + path.join(home, '.npm-global', 'bin'), + path.join(home, '.nvm', 'current', 'bin'), + path.join(home, '.local', 'bin'), + path.join(home, '.claude', 'bin'), + ]; +} + +/** + * Claude CLI candidate installation paths. + */ +export function getClaudeCandidatePaths(): string[] { + const home = os.homedir(); + if (isWindows) { + const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming'); + const localAppData = process.env.LOCALAPPDATA || path.join(home, 'AppData', 'Local'); + return [ + path.join(appData, 'npm', 'claude.cmd'), + path.join(localAppData, 'npm', 'claude.cmd'), + path.join(home, '.npm-global', 'bin', 'claude.cmd'), + path.join(home, '.claude', 'bin', 'claude.exe'), + path.join(home, '.local', 'bin', 'claude.cmd'), + ]; + } + return [ + '/usr/local/bin/claude', + '/opt/homebrew/bin/claude', + path.join(home, '.npm-global', 'bin', 'claude'), + path.join(home, '.local', 'bin', 'claude'), + path.join(home, '.claude', 'bin', 'claude'), + ]; +} + +/** + * Build an expanded PATH string with extra directories, deduped and filtered. + */ +export function getExpandedPath(): string { + const current = process.env.PATH || ''; + const parts = current.split(path.delimiter).filter(Boolean); + const seen = new Set(parts); + for (const p of getExtraPathDirs()) { + if (p && !seen.has(p)) { + parts.push(p); + seen.add(p); + } + } + return parts.join(path.delimiter); +} + +/** + * Find and validate the Claude CLI binary. + * Tests each candidate with --version before returning. + */ +export function findClaudeBinary(): string | undefined { + // Try known candidate paths first + for (const p of getClaudeCandidatePaths()) { + try { + execFileSync(p, ['--version'], { + timeout: 3000, + stdio: 'pipe', + shell: needsShell(p), + }); + return p; + } catch { + // not found, try next + } + } + + // Fallback: use `where` (Windows) or `which` (Unix) with expanded PATH + try { + const cmd = isWindows ? 'where' : '/usr/bin/which'; + const args = isWindows ? ['claude'] : ['claude']; + const result = execFileSync(cmd, args, { + timeout: 3000, + stdio: 'pipe', + env: { ...process.env, PATH: getExpandedPath() }, + shell: isWindows, + }); + // where.exe may return multiple lines; try each with --version validation + const lines = result.toString().trim().split(/\r?\n/); + for (const line of lines) { + const candidate = line.trim(); + if (!candidate) continue; + try { + execFileSync(candidate, ['--version'], { + timeout: 3000, + stdio: 'pipe', + shell: needsShell(candidate), + }); + return candidate; + } catch { + continue; + } + } + } catch { + // not found + } + + return undefined; +} + +/** + * Execute claude --version and return the version string. + * Handles .cmd shell execution on Windows. + */ +export async function getClaudeVersion(claudePath: string): Promise { + try { + const { stdout } = await execFileAsync(claudePath, ['--version'], { + timeout: 5000, + env: { ...process.env, PATH: getExpandedPath() }, + shell: needsShell(claudePath), + }); + return stdout.trim() || null; + } catch { + return null; + } +}