Metadata-Version: 2.5
Name: fused-render
Version: 0.6.82
Summary: Local file explorer with Python-powered renderable HTML previews
Project-URL: Homepage, https://github.com/fusedio/fused-render
Project-URL: Repository, https://github.com/fusedio/fused-render
Project-URL: Releases, https://github.com/fusedio/fused-render/releases
Project-URL: Issues, https://github.com/fusedio/fused-render/issues
License-Expression: MIT
License-File: LICENSE
Keywords: data-viz,duckdb,file-explorer,geospatial,html,preview
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.110
Requires-Dist: fused==2.9.3b12
Requires-Dist: httpx
Requires-Dist: packaging>=22
Requires-Dist: pyte>=0.8.2
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: uv>=0.5
Requires-Dist: uvicorn>=0.29
Requires-Dist: websockets>=12
Provides-Extra: all
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'all'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'all'
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'all'
Requires-Dist: duckdb<2,>=1.1; extra == 'all'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'all'
Requires-Dist: httptools>=0.6.3; extra == 'all'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'all'
Requires-Dist: pillow<13; extra == 'all'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'all'
Requires-Dist: pyarrow>=14; extra == 'all'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'all'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'all'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'all'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'all'
Requires-Dist: watchfiles>=1.0; extra == 'all'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'all'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'all'
Provides-Extra: app
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'app'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'app'
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'app'
Requires-Dist: duckdb<2,>=1.1; extra == 'app'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'app'
Requires-Dist: httptools>=0.6.3; extra == 'app'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'app'
Requires-Dist: pillow<13; extra == 'app'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'app'
Requires-Dist: pyarrow>=14; extra == 'app'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: pyobjc-framework-webkit; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: rumps; (sys_platform == 'darwin') and extra == 'app'
Requires-Dist: watchfiles>=1.0; extra == 'app'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'app'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'app'
Provides-Extra: bundled
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'bundled'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'bundled'
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'bundled'
Requires-Dist: drain3>=0.9.11; extra == 'bundled'
Requires-Dist: duckdb<2,>=1.1; extra == 'bundled'
Requires-Dist: fpdf2>=2.8.7; extra == 'bundled'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'bundled'
Requires-Dist: httptools>=0.6.3; extra == 'bundled'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'bundled'
Requires-Dist: msgpack>=1.0; extra == 'bundled'
Requires-Dist: numpy; extra == 'bundled'
Requires-Dist: openpyxl; extra == 'bundled'
Requires-Dist: pandas; extra == 'bundled'
Requires-Dist: pillow<13; extra == 'bundled'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'bundled'
Requires-Dist: pyarrow>=14; extra == 'bundled'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'bundled'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'bundled'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'bundled'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'bundled'
Requires-Dist: python-pptx; extra == 'bundled'
Requires-Dist: requests; extra == 'bundled'
Requires-Dist: watchfiles>=1.0; extra == 'bundled'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'bundled'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'bundled'
Provides-Extra: cli
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'cli'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'cli'
Requires-Dist: duckdb<2,>=1.1; extra == 'cli'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'cli'
Requires-Dist: httptools>=0.6.3; extra == 'cli'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'cli'
Requires-Dist: pillow<13; extra == 'cli'
Requires-Dist: pyarrow>=14; extra == 'cli'
Requires-Dist: watchfiles>=1.0; extra == 'cli'
Provides-Extra: data
Requires-Dist: pyarrow>=14; extra == 'data'
Provides-Extra: desktop
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'desktop'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'desktop'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'desktop'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'desktop'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'desktop'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'desktop'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'desktop'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'desktop'
Provides-Extra: dev
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'dev'
Requires-Dist: cryptography; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'dev'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'dev'
Requires-Dist: cryptography<=48.0.1; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'dev'
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'dev'
Requires-Dist: duckdb<2,>=1.1; extra == 'dev'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'dev'
Requires-Dist: httptools>=0.6.3; extra == 'dev'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'dev'
Requires-Dist: jinja2; extra == 'dev'
Requires-Dist: matplotlib; extra == 'dev'
Requires-Dist: pillow<13; extra == 'dev'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'dev'
Requires-Dist: pyarrow>=14; extra == 'dev'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'dev'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'dev'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'dev'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-xdist; extra == 'dev'
Requires-Dist: watchfiles>=1.0; extra == 'dev'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'dev'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'dev'
Provides-Extra: fused
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'fused'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'fused'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'fused'
Provides-Extra: hf
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'hf'
Provides-Extra: index
Requires-Dist: duckdb<2,>=1.1; extra == 'index'
Requires-Dist: pyarrow>=14; extra == 'index'
Requires-Dist: watchfiles>=1.0; extra == 'index'
Provides-Extra: linux-desktop
Requires-Dist: anthropic>=0.40.0; (python_version >= '3.11') and extra == 'linux-desktop'
Requires-Dist: cryptography<=48.0.1; (python_version >= '3.11' and sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'linux-desktop'
Requires-Dist: dbus-fast; (sys_platform == 'linux') and extra == 'linux-desktop'
Requires-Dist: duckdb<2,>=1.1; extra == 'linux-desktop'
Requires-Dist: fused[aws,mcp]==2.9.3b12; (python_version >= '3.11') and extra == 'linux-desktop'
Requires-Dist: httptools>=0.6.3; extra == 'linux-desktop'
Requires-Dist: huggingface-hub<2,>=1.28; extra == 'linux-desktop'
Requires-Dist: pasimple; (sys_platform == 'linux') and extra == 'linux-desktop'
Requires-Dist: pillow<13; extra == 'linux-desktop'
Requires-Dist: pillow<13; (sys_platform == 'linux') and extra == 'linux-desktop'
Requires-Dist: pyarrow>=14; extra == 'linux-desktop'
Requires-Dist: pygobject<3.51,>=3.48; (sys_platform == 'linux') and extra == 'linux-desktop'
Requires-Dist: pyobjc-framework-avfoundation; (sys_platform == 'darwin') and extra == 'linux-desktop'
Requires-Dist: pyobjc-framework-cocoa; (sys_platform == 'darwin') and extra == 'linux-desktop'
Requires-Dist: pyobjc-framework-coreaudio; (sys_platform == 'darwin') and extra == 'linux-desktop'
Requires-Dist: pyobjc-framework-screencapturekit; (sys_platform == 'darwin') and extra == 'linux-desktop'
Requires-Dist: watchfiles>=1.0; extra == 'linux-desktop'
Requires-Dist: zeroconf<=0.148.0,>=0.130; (sys_platform == 'darwin' and platform_machine == 'x86_64') and extra == 'linux-desktop'
Requires-Dist: zeroconf>=0.130; (sys_platform != 'darwin' or platform_machine != 'x86_64') and extra == 'linux-desktop'
Description-Content-Type: text/markdown

# fused-render

**[Download for macOS and Linux →](https://render.fused.io)**

Your files, your AI, your apps — on your own machine. Browse any directory in
the browser, run AI models locally, and describe an app for Claude Code to
build. Any `.html` file you open gets a tiny injected runtime that can call a
Python `main()` function and sync its state to the URL.

Runs entirely on `127.0.0.1`. No accounts, no cloud, no sandboxing — your own
machine, your own trusted code.

## Download

Download from **[render.fused.io](https://render.fused.io)**:

- **macOS** — `.dmg`, Apple silicon
- **Linux** — AppImage

macOS is the native build; Linux has limited support. Windows is not
supported. Trouble on
first run? See [troubleshooting](https://render.fused.io/#troubleshooting).

### Other ways in

**Homebrew** — the same macOS app, from the tap:

```
brew install --cask fusedio/tap/fused-render
```

**GitHub releases** — every build the download page serves is also attached to
its [release](https://github.com/fusedio/fused-render/releases), if you want an
older version or a checksum.

**Python package** — for running fused-render inside a Python environment you
already have, rather than as a desktop app. Each release attaches a wheel (see
the release notes for its URL). The base install runs one app:

```
pip install <wheel-url>
fused-render open https://github.com/<owner>/<repo>/tree/main/<app>
```

There are three tiers. The base install runs `fused-render open`. The file
explorer (`fused-render serve`) needs `pip install '<wheel-url>[cli]'`: search,
the index, Repos, previews, the Hugging Face login, plus deploy, share and MCP,
about 230 MB on top of the base. `[all]` adds the native desktop integrations
(LAN discovery, screen capture, pasteboard); `serve` runs without them and says
so at startup. The extras on their own are `[index]` (file
search), `[data]` (pyarrow for scripts), `[hf]` (Hugging Face login),
`[desktop]` (LAN sharing, capture, clipboard) and `[fused]` (deploy, share,
MCP). From a source checkout:

```
pip install -e '.[all]'
```

Requires Python 3.11+. Building from source and the local dev loop live in
[CONTRIBUTING.md](https://github.com/fusedio/fused-render/blob/main/CONTRIBUTING.md).

## What's in it

Home opens on a file search, with everything on this machine below it:

- **Apps** — describe one in a sentence; Claude Code names it, scaffolds it,
  and opens a chat on it. Community apps from the showcase are yours to open
  and edit in place.
- **AI models** — image, video (Apple silicon), speech-to-text and embeddings
  run locally, from the Playground or from your own pages. The AI Models page
  shows what's on disk and what fits this machine.
- **Claude Code, without the terminal** — every Claude session on this machine
  in one place, and Tasks: prompts that run on a schedule.
- **Files** — comes with apps for opening Parquet, PDF, notebook, spreadsheet,
  point clouds, and more.

## Run

The downloaded app opens Home in a browser tab. From a pip install with `[cli]`
or `[all]` it's a command:

```
fused-render
```

Either way you land on `http://127.0.0.1:1777/`. Useful flags:

```
fused-render --start-dir ~/data --port 9000 --no-browser
```

`--start-dir` is where the explorer starts (default `~/Fused`); the whole
filesystem stays browsable from there.

## Authoring

Any `.py` file is a runnable target as long as it defines a `main()`
function:

```python
# sine.py
import math

def main(n: int = 80, freq: float = 1.0):
    return {"points": [[i / n, math.sin(2 * math.pi * freq * i / n)] for i in range(n)]}
```

Any `.html` file can call it and bind the result to the URL:

```html
<input id="freq" type="range" min="0.1" max="5" step="0.1" />
<script>
  const slider = document.getElementById("freq");
  slider.addEventListener("input", () => fused.params.set("freq", slider.value));
  fused.params.onChange(draw);

  async function draw() {
    const freq = fused.params.get("freq") || "1.0";
    const { points } = await fused.runPython("./sine.py", { freq });
    // ...render points...
  }
  draw();
</script>
```

A page can do a lot through `fused`:

- `fused.runPython(pyPath, params)` and `fused.params` — call `main(**params)`
  and keep a string key/value store in sync with the URL, so a refresh or a
  bookmark reproduces the view. `fused.readFile` / `writeFile` / `uploadFile` /
  `mkdir` / `stat` / `rawUrl` work on files directly, no Python needed.
  → [fused-render-authoring](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-authoring/SKILL.md)
- `fused.ai.text({prompt, ...})` — ask Claude Code, or a local model when
  `opts.model` is a Hugging Face repo id (or pin the tier with
  `opts.provider: "local" | "claude"`). `fused.ai.image` / `.video` /
  `.transcribe` / `.embed` run locally; `fused.ai.models` lists, downloads,
  loads and unloads them.
  → [fused-render-ai](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-ai/SKILL.md)
- `fused.capture` — record the screen or the microphone, or grab a screenshot.
  → [fused-render-capture](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-capture/SKILL.md)
- `fused.fileIndex` — search and query the machine-wide file index instead of
  walking the filesystem.
  → [fused-render-index](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-index/SKILL.md)
- `fused.daemon` — start, stop and talk to a folder's background daemon, one
  the server keeps running after the page closes.
  → [fused-render-background-apps](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-background-apps/SKILL.md)
- `fused.trackJob` / `fused.watchJob` — long-running work in the download
  manager, whether your page is doing it or the server is.
  → [fused-render-jobs](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-jobs/SKILL.md)
- `fused.tasks` — list, create, follow up, cancel and observe the app's Claude
  tasks from a page; a handle follows a new task from pending to its session,
  and `ui()` hands back the shell's Tasks page as an iframe URL.
  → [fused-render-tasks](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-tasks/SKILL.md)
- App skills — an app ships a `SKILL.md` that tells a bot what each `.py`
  does and how to call it; the bot loads it when a task needs the app and
  runs the file through the same `/api/run` the page uses. The format is the
  "App SKILL.md" section of the authoring skill.
  → [fused-render-authoring](https://github.com/fusedio/fused-render/blob/main/skills/fused-render-authoring/SKILL.md)

`fused.env` says whether a page is running here (`"local"`) or exported and
hosted (`"hosted"`). The complete list, with every option, is the header of
[`fused_render/static/runtime.js`](https://github.com/fusedio/fused-render/blob/main/fused_render/static/runtime.js).

Every built-in preview template is an HTML file on these same primitives —
`fused_render/templates/` has 140 of them to copy from.

## Configuration

[docs/usage.md](https://github.com/fusedio/fused-render/blob/main/docs/usage.md) covers the
[execution engine](https://github.com/fusedio/fused-render/blob/main/docs/usage.md#execution-engine),
the [AI Models page](https://github.com/fusedio/fused-render/blob/main/docs/usage.md#ai-models),
[preferences](https://github.com/fusedio/fused-render/blob/main/docs/usage.md#preferences), and
[export for hosted serving](https://github.com/fusedio/fused-render/blob/main/docs/usage.md#export-for-hosted-serving).

## Claude Code plugin

This repo doubles as a [Claude Code](https://code.claude.com/docs) plugin
marketplace. Its skills teach Claude to run the app, author views, use local AI
and jobs, and build preview templates — the same skills under `skills/`.

From inside Claude Code:

```
/plugin marketplace add fusedio/fused-render
/plugin install fused-render@fused-render
```

Or from the command line:

```
claude plugin marketplace add fusedio/fused-render
claude plugin install fused-render@fused-render
```

The manifests live in `.claude-plugin/` (`marketplace.json` + `plugin.json`).

Installing is optional and only affects *your own* Claude Code sessions. Chats
started from inside fused-render already get these skills: the app assembles
the same plugin under `~/.fused-render/skill-plugin/` and loads it per session
with `--plugin-dir`, so they work on a plain DMG or wheel install with nothing
cloned.

## Security

[SECURITY.md](https://github.com/fusedio/fused-render/blob/main/SECURITY.md) has the trust model and how to report a
vulnerability.

## License

Open source under the [MIT license](https://github.com/fusedio/fused-render/blob/main/LICENSE), made by
[Fused](https://www.fused.io).
