Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ the **Pyanodons (Py)** overhaul — like [YAFC](https://github.com/Yafc-CE/yafc-
but in the browser, simpler, with deep in-game integration and an AI-assisted
planner that actually understands Py's tangled recipe graph.

**Just want to run it?** PyOps ships as a **cross-platform desktop app** — Linux,
macOS, and Windows — that bundles its own runtime and self-updates, so it needs no
toolchain. [**Download the latest release ↓**](#desktop-app) — or [run it from
source](#setup) to hack on it.

---

## What it does
Expand Down Expand Up @@ -61,6 +66,25 @@ the recipe data straight from the game and (optionally) talks to a running sessi

---

## Desktop app

The easiest way to run PyOps is the self-contained **desktop app** — a
[Tauri](https://tauri.app) window around the same server, bundling its own Node
runtime so it needs no toolchain. It runs on **Linux, macOS, and Windows**, and
**checks for updates on launch** (self-updating in place). Grab the build for your OS
from the [Releases](https://github.com/ApocDev/pyops/releases) page:

- **Linux** — `.AppImage` (`chmod +x` it and run; self-updates) or `.deb`
- **macOS** — `.dmg`
- **Windows** — the `-setup.exe` installer

It still needs **Factorio + the Py mods** installed locally (it reads your recipe
data via a data sync), and a fresh install starts empty — open **⚙ Settings › Game
data** and run a sync on first launch, same as [from source](#setup) below. For how
it's built and released, see [`docs/desktop.md`](docs/desktop.md).

---

## Screenshots

The **Factory** view rolls every block's imports/exports into one ledger — deficits,
Expand Down Expand Up @@ -91,25 +115,6 @@ set, with produced-by / used-in (here: Iron plate — 14 producers, 160 consumer

---

## Desktop app

PyOps also ships as a self-contained **desktop app** — a [Tauri](https://tauri.app)
window around the same server, bundling its own Node runtime so it needs no toolchain
to run. Grab the build for your OS from the
[Releases](https://github.com/ApocDev/pyops/releases) page:

- **Linux** — `.AppImage` (`chmod +x` it and run; self-updates) or `.deb`
- **macOS** — `.dmg`
- **Windows** — the `-setup.exe` installer

It still needs **Factorio + the Py mods** installed locally (it reads your recipe
data via a data sync), and a fresh install starts empty — open **⚙ Settings › Game
data** and run a sync on first launch, same as below. Bundled builds **check for
updates on launch** and prompt to install. For how it's built and released, see
[`docs/desktop.md`](docs/desktop.md).

---

## Requirements

_To run from source (below). The desktop app needs none of this._
Expand Down
1 change: 0 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"@tanstack/react-start": "latest",
"@tanstack/react-table": "latest",
"@tanstack/router-plugin": "^1.132.0",
"@tauri-apps/api": "^2.11.1",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-updater": "^2.10.1",
"ai": "^6.0.204",
Expand Down
3 changes: 0 additions & 3 deletions app/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 15 additions & 9 deletions docs/desktop.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ cd .. && vp run tauri build --bundles deb,appimage # or dmg / nsis on mac / wi
### Plugins in the shell

`single-instance`, `window-state` (remembers size/position), `opener` (external
links open in the system browser), `dialog` (the update prompt), `updater`, and
links open in the system browser), `updater` + `process` (the self-update flow), and
`shell` (the node sidecar).

## Releases
Expand Down Expand Up @@ -104,15 +104,21 @@ The app updates itself from GitHub Releases.
The updater artifact is picked explicitly per platform (AppImage / `.app.tar.gz` /
`-setup.exe`), and the macOS `.app.tar.gz` is arch-suffixed so the two Mac builds
don't collide.
- On launch the desktop shell checks `releases/latest/download/latest.json` (the
`updater_check` command). If a newer version exists, the **web UI** pins a small
- On launch the **web UI** checks `releases/latest/download/latest.json` via
`@tauri-apps/plugin-updater`'s `check()`. If a newer version exists it pins a small
toast bottom-right that opens a changelog dialog (rendered markdown, scrollable);
**Install & Restart** runs `updater_install` — download with streaming progress,
signature-verify against the baked-in public key, install, then `app.restart()`.
The updater logic is Rust (`tauri-plugin-updater`); only these two commands cross
into JS, guarded by `window.isTauri` so the web app stays Tauri-agnostic (a
`?mockUpdate=` dev switch previews the toast + dialog in `vp dev`). No JS
`plugin-updater`/`plugin-process` — just a lazy `@tauri-apps/api` for `invoke`.
**Install & Restart** calls the update's `downloadAndInstall()` (streaming progress,
signature-verify against the baked-in public key) then `relaunch()` from
`@tauri-apps/plugin-process`. The plugin JS is imported **lazily behind
`window.isTauri`**, so the browser build never loads it and the web app stays
Tauri-agnostic (a `?mockUpdate=` dev switch previews the toast + dialog in `vp dev`).
- **Why the built-in plugins, not custom commands:** the window loads the app over
HTTP, so Tauri treats that content as *remote* and won't let it call a command
without an explicit ACL grant. Custom app commands have no permission you can
grant to remote content — but plugin commands do, so `capabilities/default.json`
lists `updater:default` + `process:default` alongside the `remote.urls` rule for
`http://localhost:*/**`. (Hand-rolled `invoke` commands were silently ACL-denied;
this is the fix.)
- Self-update rides the **AppImage / NSIS / .app** artifacts — the `.deb` does not
self-update (use the AppImage on Linux for updates).

Expand Down
Loading