feat(FN-3046): add fn binary panel and standalone CLI entrypoint

This merge introduces a standalone CLI binary mode ("droid") with a new dashboard panel for binary management, adds a todo planning entrypoint with peer exchange shutdown, and includes documentation updates for the CLI reference and standalone deployment. Key additions span the core database layer,

Fusion-Task-Id: FN-3046
This commit is contained in:
Fusion
2026-05-01 13:54:53 -07:00
committed by gsxdsm
parent dbf75e5d31
commit 1634ea39ad
14 changed files with 589 additions and 1 deletions

View File

@@ -177,6 +177,19 @@ The pi extension exposes tools to create tasks, check progress, attach files, an
Fusion also works as a standalone CLI outside of pi. See [STANDALONE.md](./STANDALONE.md) for installation and usage without the pi extension.
## Optional provider: Factory AI via Droid CLI
`@runfusion/fusion` now ships a vendored `@fusion/droid-cli` extension in the published CLI bundle.
To use it:
1. Install the `droid` binary and ensure it is on your `PATH`
2. Authenticate with Droid CLI (`droid auth login`)
3. In Fusion dashboard, go to **Settings → Authentication** and enable **Factory AI — via Droid CLI**
4. Restart Fusion when prompted so the extension is loaded into the runtime
Once enabled, `droid-cli` models appear in Fusion model selection.
## Full documentation
Architecture details, development setup, and contributor info live in the [project README](https://github.com/Runfusion/Fusion#readme).

View File

@@ -16,6 +16,20 @@ If you don't have pi set up yet: `npm i -g @mariozechner/pi-coding-agent && pi`
## Usage
### Optional provider: Factory AI via Droid CLI
The published `@runfusion/fusion` package includes a vendored `@fusion/droid-cli` provider extension.
To enable it:
1. Install the `droid` CLI binary and confirm it is available on `PATH`
2. Authenticate with `droid auth login`
3. Open Fusion dashboard → **Settings → Authentication** and enable **Factory AI — via Droid CLI**
4. Restart Fusion when prompted to apply provider extension loading
After restart, `droid-cli` models are available in model pickers.
### Start the dashboard
Launch the web UI and AI engine:

View File

@@ -34,6 +34,7 @@
"dist/**/*.js.map",
"dist/client/**",
"dist/pi-claude-cli/**",
"dist/droid-cli/**",
"skill/**",
"README.md"
],

View File

@@ -11,6 +11,7 @@ import {
readClientIndexHtml,
} from "./bundle-output-helpers";
import { resolveClaudeCliExtensionFromModuleUrl } from "../commands/claude-cli-extension";
import { resolveDroidCliExtensionFromModuleUrl } from "../commands/droid-cli-extension";
const tsupConfigPath = join(cliRoot, "tsup.config.ts");
@@ -119,6 +120,24 @@ describe("CLI bundle output", () => {
expect(existsSync(join(stagedRoot, "src", "process-manager.ts"))).toBe(true);
});
it("resolveDroidCliExtension succeeds against the staged dist/ layout", () => {
const result = resolveDroidCliExtensionFromModuleUrl(pathToFileURL(bundlePath).href);
expect(result.status).toBe("ok");
if (result.status === "ok") {
expect(result.path).toBe(join(cliRoot, "dist", "droid-cli", "index.ts"));
expect(result.packageVersion).toMatch(/\d+\.\d+\.\d+/);
}
});
it("dist/droid-cli/ is staged with correct files", () => {
const stagedRoot = join(cliRoot, "dist", "droid-cli");
expect(existsSync(join(stagedRoot, "package.json"))).toBe(true);
expect(existsSync(join(stagedRoot, "index.ts"))).toBe(true);
expect(existsSync(join(stagedRoot, "src", "process-manager.ts"))).toBe(true);
});
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");