Merges FN-3396's full Cursor CLI provider integration (Steps 1–4): defines a CLI-backed provider contract, adds the `fusion-plugin-cursor-runtime` plugin package with process management and runtime probes, wires dashboard auth flows and UI (ProviderCard, onboarding modal, settings), and bundles the Fusion-Task-Id: FN-3396
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { runCursorCommand } from "./cli-spawn.js";
|
|
import type { CursorBinaryStatus } from "./types.js";
|
|
|
|
const CANDIDATES = ["cursor-agent", "cursor"] as const;
|
|
|
|
export async function probeCursorBinary(options?: { timeoutMs?: number; binaryPath?: string }): Promise<CursorBinaryStatus> {
|
|
const startedAt = Date.now();
|
|
const timeoutMs = options?.timeoutMs ?? 3000;
|
|
const candidates = options?.binaryPath ? [options.binaryPath] : [...CANDIDATES];
|
|
|
|
for (const binary of candidates) {
|
|
const version = await runCursorCommand(binary, ["--version"], timeoutMs);
|
|
if (version.code === 0) {
|
|
// NOTE: Cursor CLI currently lacks a stable auth-status contract we can
|
|
// invoke without side effects. Treating successful --version as ready is
|
|
// a best-effort heuristic; keychain/auth errors are handled by fallback
|
|
// probes below when surfaced in stderr/stdout.
|
|
return {
|
|
available: true,
|
|
authenticated: true,
|
|
binaryName: binary,
|
|
binaryPath: binary,
|
|
version: version.stdout.trim() || undefined,
|
|
probeDurationMs: Date.now() - startedAt,
|
|
};
|
|
}
|
|
|
|
const combined = `${version.stdout}\n${version.stderr}`.toLowerCase();
|
|
if (combined.includes("keychain is locked")) {
|
|
return {
|
|
available: true,
|
|
authenticated: false,
|
|
binaryName: binary,
|
|
binaryPath: binary,
|
|
reason: "macOS login keychain is locked",
|
|
probeDurationMs: Date.now() - startedAt,
|
|
};
|
|
}
|
|
|
|
if (combined.includes("no cursor ide installation found")) {
|
|
return {
|
|
available: true,
|
|
authenticated: false,
|
|
binaryName: binary,
|
|
binaryPath: binary,
|
|
reason: "Cursor IDE installation not found",
|
|
probeDurationMs: Date.now() - startedAt,
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
available: false,
|
|
authenticated: false,
|
|
reason: "cursor-agent/cursor not found on PATH",
|
|
probeDurationMs: Date.now() - startedAt,
|
|
};
|
|
}
|