feat(FN-3396): bundle Cursor CLI as a plugin provider with dashboard auth w

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
This commit is contained in:
Fusion
2026-05-07 04:10:15 -07:00
committed by gsxdsm
parent 2eba5a007c
commit dca07892ff
50 changed files with 1292 additions and 3 deletions

View File

@@ -6,6 +6,7 @@ export const cliRoot = join(__dirname, "..", "..");
export const workspaceRoot = join(cliRoot, "..", "..");
export const bundlePath = join(cliRoot, "dist", "bin.js");
export const clientIndexPath = join(cliRoot, "dist", "client", "index.html");
const cursorPluginManifestPath = join(cliRoot, "dist", "plugins", "fusion-plugin-cursor-runtime", "manifest.json");
export const dashboardClientStubMarker = "Dashboard assets not built";
@@ -28,7 +29,7 @@ function runBuildCommand(command: string, cwd: string) {
}
function hasBuiltDashboardAssets(): boolean {
if (!existsSync(bundlePath) || !existsSync(clientIndexPath)) {
if (!existsSync(bundlePath) || !existsSync(clientIndexPath) || !existsSync(cursorPluginManifestPath)) {
return false;
}

View File

@@ -169,6 +169,17 @@ describe("CLI bundle output", () => {
expect(manifest.name?.length).toBeGreaterThan(0);
});
it("dist/plugins/fusion-plugin-cursor-runtime/ is staged with a valid manifest", () => {
const stagedRoot = join(cliRoot, "dist", "plugins", "fusion-plugin-cursor-runtime");
const manifestPath = join(stagedRoot, "manifest.json");
expect(existsSync(manifestPath)).toBe(true);
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8")) as { id?: string; name?: string };
expect(manifest.id).toBe("fusion-plugin-cursor-runtime");
expect(typeof manifest.name).toBe("string");
expect(manifest.name?.length).toBeGreaterThan(0);
});
it("pi-claude-cli source imports child process helpers from node:child_process", () => {
const processManagerSource = readFileSync(join(cliRoot, "dist", "pi-claude-cli", "src", "process-manager.ts"), "utf-8");