Last active
January 7, 2026 16:00
-
-
Save Mgrmjp/a4207e166121d152ed41e56eac01bdb5 to your computer and use it in GitHub Desktop.
AutoHotkey script to open VS Code, Zed, and Terminal in WSL or Windows context.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires AutoHotkey v2.0 | |
| #SingleInstance Force | |
| #UseHook | |
| ; ============================================================================== | |
| ; USER CONFIGURATION | |
| ; ============================================================================== | |
| global WSL_DISTRO := "Ubuntu-24.04" | |
| global WT_PROFILE := "Ubuntu-24.04" | |
| ; Optional. If VS Code is not in PATH, set this to your code.cmd path and it will be used. | |
| ; Example: | |
| ; global VSCODE_BIN := "C:\Users\miige\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd" | |
| global VSCODE_BIN := "" | |
| ; ============================================================================== | |
| ; HOTKEYS | |
| ; ============================================================================== | |
| ^!#t::LaunchTool("Terminal") ; Ctrl + Alt + Win + T -> Windows Terminal | |
| ^!#c::LaunchTool("VSCode") ; Ctrl + Alt + Win + C -> VS Code | |
| ^!#z::LaunchTool("Zed") ; Ctrl + Alt + Win + Z -> Zed Editor | |
| ^!#a::LaunchTool("Antigravity") ; Ctrl + Alt + Win + A -> Antigravity | |
| ; ============================================================================== | |
| ; CORE LOGIC | |
| ; ============================================================================== | |
| LaunchTool(toolName) { | |
| try { | |
| targetPath := GetExplorerPathStrict() | |
| } catch as err { | |
| Notify("Error", "Could not determine path: " err.Message) | |
| return | |
| } | |
| if (targetPath = "") { | |
| Notify("⚠️", "No active path found. (Are you in Quick Access?)") | |
| return | |
| } | |
| Notify("🚀", "Opening " toolName "...") | |
| if IsWSLPath(targetPath) { | |
| LaunchWSL(toolName, targetPath) | |
| } else { | |
| LaunchWindows(toolName, targetPath) | |
| } | |
| } | |
| LaunchWindows(toolName, path) { | |
| try { | |
| switch toolName { | |
| case "Terminal": | |
| Run('wt.exe -d "' path '"') | |
| case "VSCode": | |
| RunVSCodeWindows(path) | |
| case "Zed": | |
| ; If zed is a .cmd shim too, this is the most reliable way | |
| Run(A_ComSpec ' /c zed .', path, "Hide") | |
| case "Antigravity": | |
| Run(A_ComSpec ' /c agy .', path, "Hide") | |
| } | |
| } catch { | |
| Notify("Error", "Failed to launch " toolName ". Is it in your PATH?") | |
| } | |
| } | |
| LaunchWSL(toolName, rawPath) { | |
| linuxPath := WslUncToLinuxPath(rawPath) | |
| if (linuxPath = "") { | |
| Notify("Error", "Could not convert path to Linux format.") | |
| return | |
| } | |
| try { | |
| switch toolName { | |
| case "Terminal": | |
| Run('wt.exe -p "' WT_PROFILE '" --startingDirectory "' rawPath '"') | |
| case "VSCode": | |
| RunVSCodeWSL(linuxPath) | |
| default: | |
| safePath := BashEscape(linuxPath) | |
| cmd := (toolName = "Zed") ? "zed ." : "agy ." | |
| fullCmd := 'wsl.exe -d ' WSL_DISTRO ' bash -l -c "cd ' safePath ' && ' cmd '"' | |
| Run(fullCmd, , "Hide") | |
| } | |
| } catch { | |
| Notify("Error", "Failed to launch WSL command.") | |
| } | |
| } | |
| ; ============================================================================== | |
| ; VS CODE LAUNCH HELPERS | |
| ; ============================================================================== | |
| RunVSCodeWindows(path) { | |
| ; Use explicit code.cmd if provided, else call "code" via cmd.exe (AHK can struggle with .cmd shims) | |
| if (VSCODE_BIN != "") { | |
| Run(A_ComSpec ' /c "' VSCODE_BIN '" .', path, "Hide") | |
| } else { | |
| Run(A_ComSpec ' /c code .', path, "Hide") | |
| } | |
| } | |
| RunVSCodeWSL(linuxPath) { | |
| ; Still uses Windows "code" client. Run through cmd.exe for reliability. | |
| if (VSCODE_BIN != "") { | |
| Run(A_ComSpec ' /c "' VSCODE_BIN '" --remote wsl+' WSL_DISTRO ' "' linuxPath '"', , "Hide") | |
| } else { | |
| Run(A_ComSpec ' /c code --remote wsl+' WSL_DISTRO ' "' linuxPath '"', , "Hide") | |
| } | |
| } | |
| ; ============================================================================== | |
| ; PATH RESOLVERS (STRICT) | |
| ; ============================================================================== | |
| GetExplorerPathStrict() { | |
| explorerHwnd := WinActive("ahk_class CabinetWClass") | |
| desktopHwnd := WinActive("ahk_class Progman") || WinActive("ahk_class WorkerW") | |
| if (desktopHwnd) | |
| return A_Desktop | |
| if (explorerHwnd) { | |
| for window in ComObject("Shell.Application").Windows { | |
| if (window.HWND != explorerHwnd) | |
| continue | |
| ; STRICT: | |
| ; Only use a folder when EXACTLY ONE folder is SELECTED. | |
| ; Do NOT use FocusedItem (it can become the first item when background is clicked). | |
| try { | |
| sel := window.Document.SelectedItems | |
| if (sel && sel.Count = 1) { | |
| item := sel.Item(0) | |
| if (item && item.IsFolder) | |
| return item.Path | |
| } | |
| } | |
| ; Otherwise, always return current open folder | |
| try { | |
| return window.Document.Folder.Self.Path | |
| } | |
| } | |
| } | |
| return "" | |
| } | |
| ; ============================================================================== | |
| ; WSL UTILITIES | |
| ; ============================================================================== | |
| IsWSLPath(path) { | |
| return RegExMatch(path, "i)^\\\\wsl(\$|\.localhost)\\") | |
| } | |
| WslUncToLinuxPath(uncPath) { | |
| ; Matches: | |
| ; \\wsl$\DistroName\path\to\file | |
| ; \\wsl.localhost\DistroName\path... | |
| if RegExMatch(uncPath, "i)^\\\\wsl(?:(?:\.localhost)|(?:\$))\\([^\\]+)(.*)$", &match) { | |
| linuxPath := StrReplace(match[2], "\", "/") | |
| return linuxPath | |
| } | |
| return "" | |
| } | |
| BashEscape(str) { | |
| return "'" StrReplace(str, "'", "'\''") "'" | |
| } | |
| ; ============================================================================== | |
| ; UI HELPER | |
| ; ============================================================================== | |
| Notify(title, msg) { | |
| ToolTip(title ": " msg) | |
| SetTimer () => ToolTip(), -2000 | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Summary:
agy .Setup on WindowsThe
agy .command is Antigravity’s CLI launcher (similar tocode .for VS Code), but on Windows it requires three critical fixes to work correctly, especially with WSL.The Three Issues & Fixes
1. Make
agyAccessible from WSLCreate a symlink in WSL that points to the Windows Antigravity binary:
Make sure
~/.local/binis in your$PATH.2. Fix the WSL Extension ID
Edit the following file:
Change the extension ID:
Without this change, Antigravity will try to use the VS Code WSL extension and fail.
3. Add Missing Helper Scripts
Antigravity expects helper scripts that are not bundled by default.
Source:
Destination:
Required files:
wslCode.shwslDownload.shCopy both files into the destination folder.
Notes for AutoHotkey Scripts
Because
agy .has platform-specific complexity, your automation should be defensive.Recommended Strategy
Windows paths
WSL paths
agy .only if the user has manually applied all three fixes above.Safe Fallback
If fixes are not guaranteed, fall back to a direct remote launch:
This avoids silent failures and keeps the script predictable.
Summary
agy .can work on Windows + WSL, but only after:Without all three, expect inconsistent or broken behavior.