Skip to content
fusion-ai-host

fusion-ai-host

Local tool execution for the Fusion stack — the hands on the user's machine. Where fusion-ai is the brain (the model + agent loop), fusion-ai-host is the set of tools that execute where the user's files and local toolchains live — list a folder, search a repo, rename a file, convert an IFC — reachable from the loop over an outbound-only connection, with no inbound port on the machine.

The device half is compiled to a single self-contained binary with bun build --compile; the server half is source-published (consumers bundle the TypeScript directly).

Install

Published to GitHub Packages under the @tikab-interactive scope, so an .npmrc with a read:packages token is required:

.npmrc
@tikab-interactive:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
bun add @tikab-interactive/fusion-ai-host zod

zod is used for tool input schemas.

The two halves

Two entry points, mirroring fusion-ai and fusion-ai/agent:

Loading diagram...

A headless CLI, on purpose

The connector is, and stays, a headless command line. There is no desktop or GUI app, no Tauri port, and no tray / menu-bar wrapper planned: the runtime is the server-side agent loop, and this binary is only the hand it reaches with — the browser is the interface. (Contrast a no-server desktop agent, where the app is the runtime and a window is unavoidable.)

That holds because of who runs it. The connector is for power users doing in-place work on local files — surveyors, scan-to-BIM specialists, heavy Revit / AutoCAD users — who are terminal-adjacent and tend to prefer a scriptable, re-runnable command (fusion-host convert e57 --to las --merge ./scans) to a window. The heavy domain pipelines those commands drive are the named-shell-out tier, not the built-in filesystem tools, and a CLI is arguably the better surface for them. A tray wrapper is demoted, not planned — worth building only if a concrete need for in-place local work from a non-terminal user actually appears.

The one ergonomic debt worth paying regardless is enrollment: the click-the-link device flow has to be smooth — a clear link, an unmistakable "you're connected" confirmation, and good errors when the internal CA isn't trusted — because it is the single point of friction even a power user meets.

The product-side framing — the audience split and the two data-locality scenarios — lives in the stack docs: a headless CLI, on purpose.

Quick start

The whole device side is one entrypoint — declare a tool set, point it at your server, compile:

host.ts
import { ,  } from "@tikab-interactive/fusion-ai-host";
 
await ({
  : .. ?? "https://pulsn.internal",
  : , // list_directory, read_file, grep, write_file, …
  : [.. ?? "."], // the canonicalized scope
});
bun build --compile --target=bun-windows-x64 ./host.ts --outfile fusion-host.exe

On first run the CLI enrols with a pairing code, then dials out and waits for calls. From here:

  • Tools — the defineLocalTool contract, the built-in catalogue, propose/apply, and the scope model.
  • The device runtimerunHost, enrollment, the dispatch loop, and packaging/signing.
  • The dispatcher — wiring …/server into an app: routes, presence, and the approve flow.