-
Notifications
You must be signed in to change notification settings - Fork 953
feat: initial windows support #2322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1dd383d
5357fcd
fb4c6fd
14caca7
1997945
ce07ee0
422e26f
48c0c35
5464f76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,7 +43,7 @@ const BUNDLE_ID_CANDIDATES: Partial<Record<ExternalApp, string[]>> = { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** Map of app IDs to their Linux CLI commands */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const LINUX_CLI_COMMANDS: Record<ExternalApp, string | null> = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CLI_COMMANDS: Record<ExternalApp, string | null> = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| finder: null, // Handled specially with shell.showItemInFolder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vscode: "code", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "vscode-insiders": "code-insiders", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -77,7 +77,7 @@ const LINUX_CLI_COMMANDS: Record<ExternalApp, string | null> = { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * JetBrains Toolbox typically creates `idea`/`pycharm` launchers, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * while package managers may use edition-specific names. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const LINUX_CLI_CANDIDATES: Partial<Record<ExternalApp, string[]>> = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CLI_CANDIDATES: Partial<Record<ExternalApp, string[]>> = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| intellij: ["idea", "intellij-idea-ultimate", "intellij-idea-community"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pycharm: ["pycharm", "pycharm-professional", "pycharm-community"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -109,16 +109,33 @@ export function getAppCommand( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [{ command: "open", args: ["-a", appName, targetPath] }]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Linux (and other non-macOS platforms) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const linuxCandidates = LINUX_CLI_CANDIDATES[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (platform === "win32") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (app === "finder") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [{ command: "explorer.exe", args: [targetPath] }]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const winCandidates = CLI_CANDIDATES[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (winCandidates) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return winCandidates.map((cmd) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| command: cmd, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args: [targetPath], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const winCommand = CLI_COMMANDS[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!winCommand) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [{ command: winCommand, args: [targetPath] }]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+117
to
+127
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Windows app commands are returned as raw CLI names, but they are executed with Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const linuxCandidates = CLI_CANDIDATES[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (linuxCandidates) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return linuxCandidates.map((cmd) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| command: cmd, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args: [targetPath], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cliCommand = LINUX_CLI_COMMANDS[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cliCommand = CLI_COMMANDS[app]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!cliCommand) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [{ command: cliCommand, args: [targetPath] }]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -149,9 +166,11 @@ const TRAILING_PUNCTUATION = /[.,;:!?]+$/; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function looksLikePath(str: string): boolean { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.includes("/") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.includes("\\") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.startsWith(".") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.startsWith("~") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.startsWith("/") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| str.startsWith("/") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /^[A-Za-z]:/.test(str) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+169
to
+173
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -335,6 +335,9 @@ export function getShellArgs( | |||||
| if (["zsh", "sh", "ksh"].includes(shellName)) { | ||||||
| return ["-l"]; | ||||||
| } | ||||||
| if (["powershell", "pwsh", "powershell.exe", "pwsh.exe"].includes(shellName)) { | ||||||
| return ["-NoLogo"]; | ||||||
| } | ||||||
| return []; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -370,5 +373,11 @@ export function getCommandShellArgs( | |||||
| `source ${quoteShellLiteral(bashRcfile)} &&\n${commandWithManagedPrelude}`, | ||||||
| ]; | ||||||
| } | ||||||
| if (["powershell", "pwsh", "powershell.exe", "pwsh.exe"].includes(shellName)) { | ||||||
| return ["-NoLogo", "-Command", command]; | ||||||
| } | ||||||
| if (["cmd", "cmd.exe"].includes(shellName)) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Normalize cmd shell detection to handle Windows-style absolute paths. As written, (Based on your team's feedback about using cross-platform path utilities instead of split.) Prompt for AI agents
Suggested change
|
||||||
| return ["/C", command]; | ||||||
| } | ||||||
| return ["-lc", commandWithManagedPrelude]; | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,7 +21,8 @@ function isPrereleaseBuild(): boolean { | |||||||
| } | ||||||||
|
|
||||||||
| const IS_PRERELEASE = isPrereleaseBuild(); | ||||||||
| const IS_AUTO_UPDATE_PLATFORM = PLATFORM.IS_MAC || PLATFORM.IS_LINUX; | ||||||||
| const IS_AUTO_UPDATE_PLATFORM = | ||||||||
| PLATFORM.IS_MAC || PLATFORM.IS_LINUX || PLATFORM.IS_WINDOWS; | ||||||||
|
Comment on lines
+24
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update the unsupported-platform copy to include Windows. Line 24 now enables Windows here, but Line 135 still tells users that auto-updates are only available on macOS and Linux. 📝 Suggested fix- message: "Auto-updates are only available on macOS and Linux.",
+ message: "Auto-updates are only available on macOS, Linux, and Windows.",📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: Update the unsupported-platform message to include Windows now that Prompt for AI agents |
||||||||
|
|
||||||||
| // Use explicit feed URLs to ensure we always fetch platform-specific manifests | ||||||||
| // (for example latest-mac.yml and latest-linux.yml) from the correct release. | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { existsSync } from "node:fs"; | ||
| import { join } from "node:path"; | ||
| import { PLATFORM } from "shared/constants"; | ||
|
|
||
| /** | ||
| * Returns the IPC socket/pipe path for the terminal host daemon. | ||
| * On Unix, this is a Unix domain socket file inside the superset home directory. | ||
| * On Windows, this is a named pipe (named pipes don't exist as files on disk). | ||
| */ | ||
| export function getSocketPath( | ||
| supersetDirName: string, | ||
| supersetHomeDir: string, | ||
| ): string { | ||
| if (PLATFORM.IS_WINDOWS) { | ||
| return `\\\\?\\pipe\\superset-terminal-host-${supersetDirName}`; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Windows named pipe name is not user-scoped, so different local users can collide on the same terminal-host pipe. Prompt for AI agents |
||
| } | ||
| return join(supersetHomeDir, "terminal-host.sock"); | ||
| } | ||
|
|
||
| /** | ||
| * Whether the IPC transport uses a file-based socket (Unix domain socket) | ||
| * rather than a named pipe. Only file-based sockets can be checked with `existsSync`. | ||
| */ | ||
| export function isFileBasedSocket(): boolean { | ||
| return !PLATFORM.IS_WINDOWS; | ||
| } | ||
|
|
||
| /** | ||
| * Checks whether the IPC socket/pipe exists. | ||
| * On Unix, checks for the socket file on disk. | ||
| * On Windows, named pipes can't be checked via the filesystem, so assumes true. | ||
| */ | ||
| export function socketMayExist(socketPath: string): boolean { | ||
| if (!isFileBasedSocket()) return true; | ||
| return existsSync(socketPath); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| export const SESSION_CLEANUP_DELAY_MS = 5000; | ||
| export const DEBUG_TERMINAL = process.env.SUPERSET_TERMINAL_DEBUG === "1"; | ||
| export const CREATE_OR_ATTACH_CONCURRENCY = 3; | ||
| export const MAX_SCROLLBACK_BYTES = 500_000; | ||
| export const MAX_SCROLLBACK_BYTES = 150_000; | ||
| export const MAX_HISTORY_SCROLLBACK_BYTES = 512 * 1024; | ||
| export const MAX_KILLED_SESSION_TOMBSTONES = 1000; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,11 @@ let cachedMacosSystemCertAvailable: boolean | null = null; | |
|
|
||
| function startLocaleProbe(): void { | ||
| if (cachedUtf8Locale || localeProbeInFlight) return; | ||
| // The `locale` command does not exist on Windows | ||
| if (os.platform() === "win32") { | ||
| cachedUtf8Locale = "en_US.UTF-8"; | ||
| return; | ||
| } | ||
| localeProbeInFlight = true; | ||
|
|
||
| exec( | ||
|
|
@@ -42,7 +47,8 @@ function startLocaleProbe(): void { | |
| */ | ||
| export const HOOK_PROTOCOL_VERSION = "2"; | ||
|
|
||
| export const FALLBACK_SHELL = os.platform() === "win32" ? "cmd.exe" : "/bin/sh"; | ||
| export const FALLBACK_SHELL = | ||
| os.platform() === "win32" ? "powershell.exe" : "/bin/sh"; | ||
| export const SHELL_CRASH_THRESHOLD_MS = 1000; | ||
|
|
||
| type DefaultShellModuleShape = | ||
|
|
@@ -73,15 +79,18 @@ export function normalizeDefaultShell( | |
| } | ||
|
|
||
| export function getDefaultShell(): string { | ||
| const resolvedDefaultShell = normalizeDefaultShell(defaultShell); | ||
| if (resolvedDefaultShell) { | ||
| return resolvedDefaultShell; | ||
| } | ||
|
|
||
| const platform = os.platform(); | ||
|
|
||
| // On Windows, always use PowerShell. The `default-shell` package returns | ||
| // COMSPEC (cmd.exe), which can't handle the subexpressions and file-read | ||
| // syntax used by agent launch commands. | ||
| if (platform === "win32") { | ||
| return process.env.COMSPEC || "powershell.exe"; | ||
| return "powershell.exe"; | ||
| } | ||
|
Comment on lines
+50
to
+89
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep the Windows fallback shell distinct from the primary shell. In 🤖 Prompt for AI Agents |
||
|
|
||
| const resolvedDefaultShell = normalizeDefaultShell(defaultShell); | ||
| if (resolvedDefaultShell) { | ||
| return resolvedDefaultShell; | ||
| } | ||
|
|
||
| if (process.env.SHELL) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Gate the Windows symlink/junction removal flags behind a runtime platform check instead of changing the shared path for all OSes.
(Based on your team's feedback about gating platform-specific changes with runtime checks.)
View Feedback
Prompt for AI agents