feat(oauth): complete Windsurf / Devin CLI OAuth + API-token flows (#2168)

Integrated into release/v3.8.0 — complete Windsurf/Devin CLI OAuth + API-token executor flows with unit tests.
This commit is contained in:
Aleksandr
2026-05-12 03:49:32 +03:00
committed by GitHub
parent 95944dad92
commit ff730b372e
17 changed files with 2409 additions and 168 deletions

View File

@@ -67,6 +67,24 @@ const CLI_TOOLS: Record<string, any> = {
healthcheckTimeoutMs: 4000,
paths: {},
},
devin: {
defaultCommand: "devin",
envBinKey: "CLI_DEVIN_BIN",
requiresBinary: true,
// devin acp cold-start can take a few seconds on first run
healthcheckTimeoutMs: 12000,
paths: {
// %APPDATA%\devin\config.json (Windows)
// ~/.config/devin/config.json (Linux/macOS)
config: isWindows()
? path.join(
process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming"),
"devin",
"config.json"
)
: path.join(os.homedir(), ".config", "devin", "config.json"),
},
},
cline: {
defaultCommand: "cline",
envBinKey: "CLI_CLINE_BIN",
@@ -439,6 +457,10 @@ const getKnownToolPaths = (toolId: string): string[] => {
["qodercli.cmd", "qodercli"],
["qodercli.exe", "qodercli"],
],
devin: [
["devin.exe", "devin"],
["devin.cmd", "devin"],
],
};
const bins = toolBins[toolId] || [];
@@ -464,6 +486,11 @@ const getKnownToolPaths = (toolId: string): string[] => {
paths.push(path.join(home, "bin", "droid.exe"));
}
// Devin CLI installs to %LOCALAPPDATA%\devin\cli\bin\devin.exe
if (toolId === "devin" && localAppData) {
paths.push(path.join(localAppData, "devin", "cli", "bin", "devin.exe"));
}
for (const [winName] of bins) {
if (npmPrefix) paths.push(path.join(npmPrefix, winName));
if (appData) {
@@ -501,6 +528,12 @@ const getKnownToolPaths = (toolId: string): string[] => {
if (toolId === "claude") {
paths.push(path.join(home, ".claude", "bin", posixName));
}
// Devin CLI installs to ~/.local/share/devin/bin/devin (Linux)
// or via shell installer to ~/.devin/bin/devin
if (toolId === "devin") {
paths.push(path.join(home, ".local", "share", "devin", "bin", "devin"));
paths.push(path.join(home, ".devin", "bin", "devin"));
}
}
}