Open OAuth login URLs during setup

This commit is contained in:
Advait Paliwal
2026-03-25 10:04:45 -07:00
parent 151956ea24
commit 584d065902
6 changed files with 108 additions and 5 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@companion-ai/feynman",
"version": "0.2.13",
"version": "0.2.14",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@companion-ai/feynman",
"version": "0.2.13",
"version": "0.2.14",
"license": "MIT",
"dependencies": {
"@companion-ai/alpha-hub": "^0.1.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@companion-ai/feynman",
"version": "0.2.13",
"version": "0.2.14",
"description": "Research-first CLI agent built on Pi and alphaXiv",
"license": "MIT",
"type": "module",

View File

@@ -3,6 +3,7 @@ import { writeFileSync } from "node:fs";
import { readJson } from "../pi/settings.js";
import { promptChoice, promptText } from "../setup/prompts.js";
import { openUrl } from "../system/open-url.js";
import { printInfo, printSection, printSuccess, printWarning } from "../ui/terminal.js";
import {
buildModelStatusSnapshotFromRecords,
@@ -126,7 +127,13 @@ export async function loginModelProvider(authPath: string, providerId?: string,
await authStorage.login(provider.id, {
onAuth: (info: { url: string; instructions?: string }) => {
printSection(`Login: ${provider.name ?? provider.id}`);
printInfo(`Open this URL: ${info.url}`);
const opened = openUrl(info.url);
if (opened) {
printInfo("Opened the login URL in your browser.");
} else {
printWarning("Couldn't open your browser automatically.");
}
printInfo(`Auth URL: ${info.url}`);
if (info.instructions) {
printInfo(info.instructions);
}

51
src/system/open-url.ts Normal file
View File

@@ -0,0 +1,51 @@
import { spawn } from "node:child_process";
import { resolveExecutable } from "./executables.js";
type ResolveExecutableFn = (name: string, fallbackPaths?: string[]) => string | undefined;
type OpenUrlCommand = {
command: string;
args: string[];
};
export function getOpenUrlCommand(
url: string,
platform = process.platform,
resolveCommand: ResolveExecutableFn = resolveExecutable,
): OpenUrlCommand | undefined {
if (platform === "win32") {
return {
command: "cmd",
args: ["/c", "start", "", url],
};
}
if (platform === "darwin") {
const command = resolveCommand("open");
return command ? { command, args: [url] } : undefined;
}
const command = resolveCommand("xdg-open");
return command ? { command, args: [url] } : undefined;
}
export function openUrl(url: string): boolean {
const command = getOpenUrlCommand(url);
if (!command) {
return false;
}
try {
const child = spawn(command.command, command.args, {
detached: true,
stdio: "ignore",
windowsHide: true,
});
child.on("error", () => {});
child.unref();
return true;
} catch {
return false;
}
}

45
tests/open-url.test.ts Normal file
View File

@@ -0,0 +1,45 @@
import test from "node:test";
import assert from "node:assert/strict";
import { getOpenUrlCommand } from "../src/system/open-url.js";
test("getOpenUrlCommand uses open on macOS when available", () => {
const command = getOpenUrlCommand(
"https://example.com",
"darwin",
(name) => (name === "open" ? "/usr/bin/open" : undefined),
);
assert.deepEqual(command, {
command: "/usr/bin/open",
args: ["https://example.com"],
});
});
test("getOpenUrlCommand uses xdg-open on Linux when available", () => {
const command = getOpenUrlCommand(
"https://example.com",
"linux",
(name) => (name === "xdg-open" ? "/usr/bin/xdg-open" : undefined),
);
assert.deepEqual(command, {
command: "/usr/bin/xdg-open",
args: ["https://example.com"],
});
});
test("getOpenUrlCommand uses cmd start on Windows", () => {
const command = getOpenUrlCommand("https://example.com", "win32");
assert.deepEqual(command, {
command: "cmd",
args: ["/c", "start", "", "https://example.com"],
});
});
test("getOpenUrlCommand returns undefined when no opener is available", () => {
const command = getOpenUrlCommand("https://example.com", "linux", () => undefined);
assert.equal(command, undefined);
});

View File

@@ -41,7 +41,7 @@ On Windows:
& ([scriptblock]::Create((irm https://feynman.is/install.ps1))) -Version stable
```
You can also pin an exact version by replacing `stable` with a version such as `0.2.13`.
You can also pin an exact version by replacing `stable` with a version such as `0.2.14`.
## pnpm