Skip to content

Commit 3880691

Browse files
authored
Merge pull request #144 from ApocDev/docs/user-guide
docs: add hosted user and developer documentation
2 parents 0446569 + 9b1c0ff commit 3880691

96 files changed

Lines changed: 7935 additions & 2129 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docs.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Documentation
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "docs/**"
8+
- ".github/workflows/docs.yml"
9+
pull_request:
10+
paths:
11+
- "docs/**"
12+
- ".github/workflows/docs.yml"
13+
workflow_dispatch:
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: pages-${{ github.ref }}
20+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
defaults:
26+
run:
27+
working-directory: docs
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: voidzero-dev/setup-vp@v1
31+
with:
32+
working-directory: docs
33+
node-version: "24"
34+
cache: true
35+
run-install: false
36+
- run: vp install --frozen-lockfile
37+
- run: vp check
38+
- run: vp run docs:build
39+
env:
40+
VITEPRESS_BASE: /pyops/
41+
- uses: actions/upload-pages-artifact@v4
42+
if: github.event_name != 'pull_request'
43+
with:
44+
path: docs/.vitepress/dist
45+
46+
deploy:
47+
if: github.event_name != 'pull_request'
48+
needs: build
49+
runs-on: ubuntu-latest
50+
permissions:
51+
pages: write
52+
id-token: write
53+
environment:
54+
name: github-pages
55+
url: ${{ steps.deployment.outputs.page_url }}
56+
steps:
57+
- name: Deploy GitHub Pages
58+
id: deployment
59+
uses: actions/deploy-pages@v4

AGENTS.md

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ This is a single repo with three cooperating parts:
1515
all work happens. It has its own `AGENTS.md`/`CLAUDE.md` (Vite+ toolchain notes).
1616
`app/src-tauri/` is the Tauri **desktop shell** that wraps this server in a native
1717
window and packages it into a self-contained bundle (vendored Node + bundled
18-
resources) with self-update — see [`docs/desktop.md`](docs/desktop.md).
19-
- **`mod/`** — the Factorio mod (`pyops`, Factorio 2.0): in-game panel, UDP link to
18+
resources) with self-update — see [`docs/development/desktop.md`](docs/development/desktop.md).
19+
- **`mod/`** — the Factorio mod (`pyops`, Factorio 2.1): in-game panel, UDP link to
2020
the app, data-dump trigger, Helmod-style production-block view, and the
2121
request-combinator planner. Pure Lua, no build step.
2222
- **`scripts/`** — dev-only helpers (currently `tunnel-dev`, to expose the dev
@@ -38,15 +38,16 @@ dev, a per-OS user-data dir for a packaged build, overridable via `PYOPS_DATA_DI
3838
- `factory-solve.server.ts`, `cost-analysis.server.ts`, `effects.ts`, `additives.ts` — planning logic.
3939
- `agent.ts`, `agent-tools.server.ts` — the AI assistant (AI SDK v6 + OpenRouter,
4040
read-only tools + propose-then-apply writes: draft-a-block, draft-a-plan,
41-
revise-a-block's rate).
41+
and revise a block's rate or recipe set).
4242
- `bridge/` — UDP bridge to the mod. `protocol.ts` defines the wire contract;
4343
**`PROTOCOL_VERSION` must stay in lockstep with the same constant in
4444
`mod/control.lua`** (each side warns on mismatch).
45-
- `solver/` — pure-TS sparse **linear system** per "block" (`block.ts`,
46-
`linalg.ts`). A pinned output goal + `Match` items become equations;
47-
`export`/`import` items are free boundary flows. Recipes and splits are
48-
user-chosen, so there is no LP/optimizer. Handles Py's cyclic recipe chains and
49-
reports fractional building counts.
45+
- `solver/` — the HiGHS-backed linear-program model for each block (`lp.ts`),
46+
constraint diagnosis (`diagnose.ts`), and composed sub-blocks (`subblock.ts`).
47+
Goals, goods made inside the block, and recipe pins become constraints; other
48+
goods remain free boundary flows. Recipes and splits are user-chosen rather than
49+
globally optimized. The solver handles Py's cyclic chains and reports fractional
50+
building counts.
5051
- `db/` — Drizzle ORM over `better-sqlite3`. `schema.ts` is the source of truth;
5152
`import-factorio.ts` loads the dump; `synthesize.ts` builds pass-2 synthetic
5253
recipes (mining/boiling/burning/spoiling/planting/rocket-launch, temperature
@@ -90,10 +91,50 @@ build` packages a bundle (run `src-tauri/vendor-node.sh` first). Releases are
9091
automated by **release-please** (one product version) — **don't hand-edit the
9192
version** in `version.txt` / `app/package.json` / `Cargo.toml` / `tauri.conf.json` /
9293
`mod/info.json`; it bumps them all in lockstep from conventional commits. See
93-
[`docs/desktop.md`](docs/desktop.md).
94+
[`docs/development/desktop.md`](docs/development/desktop.md).
9495

9596
If setup/runtime/package-manager behavior looks wrong, run `vp env doctor`.
9697

98+
## Documentation site (`docs/`)
99+
100+
`docs/` is a separate Vite+ package that builds the public VitePress site. The
101+
top-level sections are user-facing; subsystem internals live under
102+
`docs/development/`. Keeping this package separate prevents VitePress's Vite
103+
dependency from entering the desktop app's dependency graph.
104+
105+
Run documentation commands from inside `docs/`:
106+
107+
- `vp install` — install the pinned documentation toolchain.
108+
- `vp check` — format, lint, and typecheck documentation sources and config.
109+
- `vp run docs:dev` — start the local documentation server.
110+
- `vp run docs:build` — build the static site and validate internal links.
111+
- `vp run docs:preview` — serve the production build locally.
112+
113+
The GitHub Pages build sets `VITEPRESS_BASE=/pyops/`; local development uses `/`.
114+
The app and docs have independent lockfiles, so run the relevant package's
115+
install/check commands after changing it.
116+
117+
Documentation is a practical manual, not a marketing site:
118+
119+
- Organize user pages around tasks and questions. Lead with the outcome, use the
120+
exact visible UI labels, and state what the user should see after each workflow.
121+
- Assume readers know Factorio production basics, but explain PyOps-specific
122+
concepts and planner terminology when first introduced.
123+
- Prefer current dark-mode screenshots from the real app for UI workflows. Use
124+
localized names and representative project data; never expose API keys, local
125+
paths, personal information, or other secrets in an image.
126+
- Use generated raster illustrations selectively for confusing mental models or
127+
workflows that the UI cannot show. Do not use generated images as fake UI, and
128+
prefer Mermaid/SVG for simple deterministic diagrams.
129+
- Keep screenshots purposeful and maintainable: capture stable states after the
130+
prose is correct rather than illustrating every click.
131+
- Keep published documentation evergreen. Describe the product and architecture
132+
as they exist; do not include issue or PR numbers, commit references,
133+
implementation chronology, migration anecdotes, conversational asides, or
134+
notes about what older versions called something. Put history in GitHub and
135+
the changelog. Mention an upgrade or compatibility distinction only when the
136+
reader must act on it.
137+
97138
## The Factorio mod (`mod/`)
98139

99140
Pure Lua, edited in place — no build step. Key files: `control.lua` (panel +
@@ -112,7 +153,7 @@ bridge + live-state sync), `summary.lua` (production-block view), `combinator.lu
112153
`.github/workflows/mod-test.yml` (manual — needs a Factorio binary). See
113154
`mod/tests/README.md`. Game-API logic (entities/blueprints/GUI) is still
114155
hands-on.
115-
- Never assume Py mechanics or Factorio 2.0 API behavior — read the data dump or
156+
- Never assume Py mechanics or Factorio 2.1 API behavior — read the data dump or
116157
the relevant Lua and cite the exact value/line.
117158

118159
## Conventions
@@ -140,7 +181,7 @@ bridge + live-state sync), `summary.lua` (production-block view), `combinator.lu
140181
dynamic imports of server code trip import protection too. The only sanctioned
141182
dynamic imports: heavyweight optional deps (`sharp`), Tauri plugins in client
142183
code, and the bridge server↔handlers cycle guard.
143-
- **UI work follows the design system**[`docs/design.md`](docs/design.md): theme
184+
- **UI work follows the design system**[`docs/development/design.md`](docs/development/design.md): theme
144185
tokens (never raw palette colors), the `components/ui` primitives (never
145186
hand-rolled buttons/inputs/badges), square corners, `PageHeader`/`EmptyState`/
146187
`Skeleton`, and loading/empty/error states on every async surface.
@@ -157,9 +198,12 @@ bridge + live-state sync), `summary.lua` (production-block view), `combinator.lu
157198
change adds/renames/removes a user-facing surface (a page, tab, setting, install
158199
flow, env var, CLI command) or alters how a subsystem works, update the docs in
159200
the same pass:
160-
- User-facing behavior, setup, config → [`README.md`](README.md).
161-
- How a subsystem works → the matching file in [`docs/`](docs/) (architecture,
162-
data-pipeline, solver, bridge, ai-assistant, design).
201+
- User-facing behavior, setup, config → the matching guide in [`docs/`](docs/).
202+
- Product pitch, download path, and contributor entry points →
203+
[`README.md`](README.md).
204+
- How a subsystem works → the matching file in
205+
[`docs/development/`](docs/development/) (architecture, data-pipeline, solver,
206+
bridge, ai-assistant, design).
163207
- A structural or workflow change (new top-level dir, build/verify step,
164208
convention) → this `AGENTS.md`.
165209

README.md

Lines changed: 74 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -2,124 +2,100 @@
22

33
<img src="app/public/logo.svg" alt="PyOps logo" width="100">
44

5-
A web-based factory planner and in-game ops assistant for **Factorio**, built for
6-
the **Pyanodons (Py)** overhaul — like [YAFC](https://github.com/Yafc-CE/yafc-ce),
7-
but in the browser, with deep in-game integration and an AI-assisted planner. It
8-
runs locally alongside your Factorio install and reads recipe data straight from
9-
the game; Py-specific views (like TURD) appear only when that data is present, but
10-
it loads whatever mod set you sync.
11-
12-
**Just want to run it?** PyOps ships as a self-updating **desktop app** for Linux,
13-
macOS, and Windows — no toolchain needed. Grab a build from the
14-
[Releases](https://github.com/ApocDev/pyops/releases) page (it still needs Factorio
15-
installed locally to sync recipe data), or [run it from source](#run-it) to hack on
16-
it. Build/release details: [`docs/desktop.md`](docs/desktop.md).
17-
18-
---
19-
20-
## What it does
21-
22-
- **Design production blocks** — set output goals + rates, pick recipes/machines/
23-
modules, and PyOps solves the run-rates and building counts for the whole chain
24-
(cyclic loops, fluid temperatures, byproducts, spoilage). Pin counts, route
25-
byproducts, fold chains into sub-blocks, or extract a recipe into its own block.
26-
- **Balance the whole factory** — every block's imports/exports roll into one
27-
ledger (deficits, surpluses, built-vs-required machines), with what-if. Supply
28-
priorities let recovery blocks feed demand before dedicated fallback production.
29-
- **Explore the data** — a searchable catalogue with a recipe explorer (producers/
30-
consumers ranked and availability-grouped) and a dependency-tree explorer.
31-
- **Track TURD & research** — Py's tech upgrades are first-class; pick a path and
32-
every block re-solves against your research horizon.
33-
- **Plan with AI** — an OpenRouter-backed assistant drafts whole chains, honouring
34-
what you can build now vs. after research, and can read the live factory.
35-
- **Reach into the running game** — a companion mod links over localhost UDP: an
36-
in-game block panel, locate, live sync of research/TURD/machines, and more.
37-
- **Quality of life** — command palette (Ctrl+K), undo (Ctrl+Z), per-block
38-
snapshots, backup/share, tasks & notes, light/dark theme, responsive to phone.
39-
40-
Each subsystem has its own doc under [`docs/`](#documentation).
41-
42-
---
5+
PyOps is a local factory planner and in-game operations assistant for
6+
**Factorio**. It is designed around the **Pyanodons** mods, but works with vanilla
7+
Factorio and other mod packs by synchronizing recipes, technologies, machines,
8+
and icons from your own game.
439

44-
## Screenshots
10+
**[Read the PyOps documentation →](https://apocdev.github.io/pyops/)**
4511

46-
**Factory ledger** — every block's flows in one balance sheet; deficits rank by %
47-
of demand met.
48-
![Factory ledger — whole-factory balance with deficits, surpluses, and built-vs-required machines](docs/images/factory.png)
12+
Installation, first project, planning workflows, game integration, reference,
13+
and troubleshooting.
4914

50-
**Block editor** — goals in, solved rates and building counts out; toggle recipes/
51-
blocks off, fold into sub-blocks, or switch to a flow diagram.
52-
![Block editor — the Basic substrate bio-chain, solved with byproducts](docs/images/block-editor.png)
15+
**[Download the latest release →](https://github.com/ApocDev/pyops/releases)**
5316

54-
**AI assistant** — drafts a whole block from a goal, flagging byproducts, spoilage,
55-
and TURD upgrades.
56-
![AI assistant drafting a py science 1 production block](docs/images/assistant.png)
17+
Self-updating desktop builds for Linux, macOS, and Windows.
5718

58-
**Browse** — every item, fluid, and recipe with produced-by / used-in, grouped by
59-
availability and annotated with waste %.
60-
![Browse — Iron plate with its producers and consumers](docs/images/browse.png)
19+
## What PyOps does
6120

62-
---
21+
- **Design production blocks** — set output goals and rates, choose recipes and
22+
machines, and solve full production chains including cycles, byproducts,
23+
spoilage, and fluid temperatures.
24+
- **Balance the factory** — combine every block's imports and exports in one
25+
ledger, identify shortfalls and surpluses, and test changes with what-if plans.
26+
- **Explore game data** — search items, fluids, recipes, producers, consumers,
27+
and dependency trees from the mod set you actually use.
28+
- **Plan around progression** — model research horizons and, when present,
29+
Pyanodons TURD choices throughout the factory.
30+
- **Connect to Factorio** — use the companion mod for live research, machine,
31+
location, and production-plan integration.
32+
- **Draft with the Assistant** — optionally use an OpenRouter-backed planning
33+
assistant that understands the current project and can propose production
34+
blocks for review.
6335

64-
## Run it
36+
The [planning guide](https://apocdev.github.io/pyops/guide/) explains how these
37+
parts fit into a complete workflow.
6538

66-
```bash
67-
cd app
68-
vp install # install dependencies (Node LTS + pnpm; Vite+ handles the rest)
69-
vp dev # start PyOps at http://localhost:3000
70-
```
39+
## Screenshots
40+
41+
**Factory ledger** — the balance across every production block, including
42+
deficits, surpluses, and machine requirements.
7143

72-
Then open **⚙ Settings › Game data** and run a sync: PyOps launches Factorio
73-
headlessly, reads its recipe data, and loads it into a local database (~1–2 min the
74-
first time). Needs **Factorio 2.1** with the **Pyanodons** suite +
75-
**pypostprocessing**.
44+
![Factory ledger showing whole-factory balance](docs/images/factory.png)
7645

77-
- **Configuration** (env vars, remote access): [`docs/configuration.md`](docs/configuration.md)
78-
- **In-game features** (companion mod, launching the bridge): [`docs/bridge.md`](docs/bridge.md)
79-
- **AI assistant** needs an [OpenRouter](https://openrouter.ai) key (set it in
80-
Settings or `OPENROUTER_API_KEY`).
46+
**Block editor** — goals in, solved rates and building counts out.
8147

82-
The dev server also exposes the PyOps MCP tool surface at
83-
`http://localhost:3000/mcp` (project configs for Codex and Claude Code ship in the
84-
repo).
48+
![Block editor showing a solved production chain](docs/images/block-editor.png)
8549

86-
---
50+
**Assistant** — project-aware help for investigating and drafting production
51+
plans.
8752

88-
## Documentation
53+
![Assistant drafting a production block](docs/images/assistant.png)
8954

90-
How PyOps works under the hood lives in [`docs/`](docs/):
55+
## Developing PyOps
9156

92-
- [Architecture](docs/architecture.md) — the one-app-plus-mod model and repo layout.
93-
- [Data pipeline](docs/data-pipeline.md) — how the Factorio data sync works.
94-
- [Block solver](docs/solver.md) — the planning math.
95-
- [Factorio bridge](docs/bridge.md) — the in-game link and its setup.
96-
- [AI assistant](docs/ai-assistant.md) — the planning agent.
97-
- [Configuration](docs/configuration.md) — environment variables and remote access.
98-
- [Desktop app](docs/desktop.md) — how the Tauri bundle is built and released.
57+
The repository contains three cooperating parts:
9958

100-
Contributing: `vp check` and `vp test` must be clean; the mod (`mod/`) is pure Lua,
101-
no build step. See [`AGENTS.md`](AGENTS.md) for the full toolchain and conventions.
59+
- `app/` — the TanStack Start application and Tauri desktop shell;
60+
- `mod/` — the Factorio companion mod;
61+
- `docs/` — the VitePress documentation site.
10262

103-
---
63+
Start the application from source with [Vite+](https://viteplus.dev/):
10464

105-
## Credits & inspiration
65+
```bash
66+
cd app
67+
vp install
68+
vp dev
69+
```
70+
71+
Run `vp check` and `vp test` from `app/` before submitting application changes.
72+
The companion mod is pure Lua and has no build step.
73+
74+
For architecture, subsystem contracts, desktop packaging, and contributor
75+
workflows, read the hosted
76+
[development documentation](https://apocdev.github.io/pyops/development/).
77+
Repository-specific agent conventions remain in [`AGENTS.md`](AGENTS.md).
78+
79+
To work on the documentation site:
80+
81+
```bash
82+
cd docs
83+
vp install
84+
vp run docs:dev
85+
```
10686

107-
- **[YAFC](https://github.com/Yafc-CE/yafc-ce)** — the planner model, cost-analysis
108-
approach, and the "design blocks, balance the factory" shape.
109-
- **[Helmod](https://mods.factorio.com/mod/helmod)** — the in-game production-block
110-
panel is heavily inspired by Helmod's; no Helmod assets are bundled.
111-
- **[Factory Search](https://mods.factorio.com/mod/FactorySearch)** — the "locate in
112-
game" feature relays to its remote interface.
113-
- **[pypostprocessing](https://mods.factorio.com/mod/pypostprocessing)** — makes a
114-
clean, planner-friendly data dump possible.
87+
## Credits and inspiration
11588

116-
---
89+
- **[YAFC](https://github.com/Yafc-CE/yafc-ce)** — the planner model,
90+
cost-analysis approach, and the design-blocks/balance-factory workflow.
91+
- **[Helmod](https://mods.factorio.com/mod/helmod)** — inspiration for the
92+
in-game production-block panel; no Helmod assets are bundled.
93+
- **[Factory Search](https://mods.factorio.com/mod/FactorySearch)** — the locate
94+
action can relay to its remote interface.
95+
- **[pypostprocessing](https://mods.factorio.com/mod/pypostprocessing)**
96+
supplies additional planner-oriented metadata for Pyanodons data dumps.
11797

11898
## License
11999

120-
Free software under the **GNU General Public License v3.0** — see [`LICENSE`](LICENSE).
121-
Copyright (C) 2026 ApocDev. You're free to use, study, modify, and share it
122-
(including commercially), but any distributed version or derivative must stay open
123-
under the same GPLv3 terms — matching [YAFC](https://github.com/Yafc-CE/yafc-ce) and
124-
[Helmod](https://mods.factorio.com/mod/helmod). Contributions accepted under the same
125-
license.
100+
PyOps is free software under the **GNU General Public License v3.0**. See
101+
[`LICENSE`](LICENSE). Copyright (C) 2026 ApocDev.

app/src/components/context-menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { cn } from "#/lib/utils.ts";
1010

1111
/**
12-
* Right-click context menu shell (docs/design.md): a Radix `DropdownMenu`
12+
* Right-click context menu shell (docs/development/design.md): a Radix `DropdownMenu`
1313
* anchored at the pointer, so Escape-to-close, focus containment/roving,
1414
* `role="menu"` semantics, and click-away come from the primitive rather than a
1515
* hand-rolled backdrop (#86). Callers stay declarative — own the open state and

app/src/components/empty-state.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { LucideIcon } from "lucide-react";
44
import { cn } from "#/lib/utils.ts";
55

66
/**
7-
* The one empty-state component (docs/design.md): say what's missing and, via
7+
* The one empty-state component (docs/development/design.md): say what's missing and, via
88
* `action`, how to fill it. Async surfaces must never render blank.
99
*/
1010
export function EmptyState({

0 commit comments

Comments
 (0)