- pyproject.toml + puga/cli.py: `pip install -e .` installs a `puga <tool>` command, so no venv path is needed (replaces requirements.txt) - tools/plan_push.py: `pull <uuid>` reads a plan (incl. UI edits) back into a YAML spec; recipe entries may carry an amount so switched-off recipes round trip; fixes a variable that overwrote the plan name in build_payload, with a regression test - README: usage with the puga command, and a section on working on the same plans in the PRUNplanner UI and from Claude (write, edit in UI, read back) - CLAUDE.md updated accordingly Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
52 lines
6.5 KiB
Markdown
52 lines
6.5 KiB
Markdown
# PuGa: Prosperous Universe advisory toolkit
|
|
|
|
Agent-first toolkit for advising a Prosperous Universe player. The player asks questions; you answer by running the tools in `tools/` against live data, not by guessing.
|
|
|
|
## Read first
|
|
1. `empire/PROFILE.md` if it exists: who the player is, how they want answers, their company and current plans. `empire/` is gitignored and holds everything specific to this player's empire (see Layout). If it does not exist, ask the player the basics and create it.
|
|
2. `docs/mechanics.md` for game mechanics (source of truth order below).
|
|
3. `empire/state/company.yaml` for the current position; refresh it with `tools/state.py sync` before answering anything about it.
|
|
|
|
## Working rules
|
|
- Numbers, tables, ROI per day. Short answers, no fluff. Match the style in the player's profile.
|
|
- The player plays on browser APEX and may send screenshots; read them carefully, they override assumptions.
|
|
- Never guess APEX commands or numbers. Pull data (tools, FIO, PRUNplanner) or search.
|
|
- Label every number: live (tool output), state (company.yaml), or estimate; say which in-game command would confirm an estimate.
|
|
- Prices move; re-run tools before quoting. Anything older than a day is stale.
|
|
- Do not commit or push unless asked. Writes to the player's PRUNplanner account follow the guardrails in `docs/decisions.md`.
|
|
|
|
## Source-of-truth rules
|
|
1. **PRUNplanner code wins** over our own docs for game mechanics (`ref/frontend/src/features/planning/calculations/`, `ref/backend/`). If any older handoff or note conflicts with it, the note is wrong; fix `docs/mechanics.md`.
|
|
2. In-game numbers the player reports beat both, especially for planet resource factors.
|
|
3. `ref/` is a gitignored copy of the PRUNplanner repos; refresh with `tools/refresh_refs.sh`.
|
|
|
|
## Setup
|
|
- Python venv at `.venv`, package installed editable (`pip install -e ".[dev]"`), which provides the `puga` command: `puga <tool> [args]` (`.venv/bin/puga` if the venv is not activated). `tools/*.py` also run directly with `.venv/bin/python`. Dependencies are in `pyproject.toml`.
|
|
- Secrets in `.env` (gitignored; template `.env.example`): FIO REST key, FIO API key, PRUNplanner key, FIO username, company code. Never print or commit them; do not ask the player to paste keys into chat.
|
|
- Scope: whole universe supported; default exchange from `DEFAULT_CX` (AI1 = Antares), `--cx` to change.
|
|
|
|
## Layout
|
|
- `CLAUDE.md` this file; `README.md` for humans.
|
|
- `docs/` GAME and toolkit knowledge, safe to publish: `mechanics.md` (verified rules), `saturation-design.md` (market model), `decisions.md` (toolkit decisions and guardrails), `roadmap.md`.
|
|
- `empire/` (**gitignored**) OUR game state, nothing here goes public: `PROFILE.md`, `state/company.yaml` (synced from FIO), `plans/` (own plan specs), `docs/` (handoffs, build plans, personal notes).
|
|
- `puga/` library; `tools/` CLIs; `plans/examples/` generic plan specs (also test fixtures); `state/company.example.yaml` example state; `tests/`; `data/` (gitignored fetched data cache); `ref/` (gitignored PRUNplanner source).
|
|
- Rule: game facts and generic methods go in `docs/`; anything about the player's own bases, cash, decisions or preferences goes in `empire/`.
|
|
|
|
## Tools
|
|
Run as `puga <tool> ...` (e.g. `puga scan --min-n 3`, `puga plan pull <uuid>`); the `tools/x.py` paths below are the same programs.
|
|
- `tools/state.py sync|show` refreshes `empire/state/company.yaml` from live FIO (cash, permits, buildings, real production efficiency, storage, ships).
|
|
- `tools/plan_push.py` builds/validates PRUNplanner plans from YAML specs (`plans/examples/`, `empire/plans/`). Dry run by default; `--apply` only after the player says yes; only `[PuGa]`-named plans are created/updated/deleted (`delete <uuid>`, only when asked); `list` shows the account's plans, `pull <uuid> -o file.yaml` reads a plan back into a YAML spec including edits made in the PRUNplanner UI. Workflow: push a plan, the player refines it in the UI and saves, then `pull` / `simulate --uuid` read it back and you continue from there.
|
|
- `tools/simulate.py <spec.yaml | --uuid U> [--off EXT,SME] [--basis real|uni30|vwap30|ask|...]` replica of PRUNplanner's simulator (efficiency, workforce, material I/O, profit). Flows and efficiency verified exact vs screenshots; profit within ~2%. The NEW CAPEX line = planned minus already built (from state), the honest payback; ignore the plan-level ROI (PRUNplanner always adds a core module). `--uuid` reads the SAVED plan from the account (UI edits must be saved first).
|
|
- `tools/scan.py` DEPTH-AWARE recipe scan (use this): buildings the market could absorb, ROI for our own size, patient prices, ask-walked inputs. Fully staffed AND understaffed variants by default (`--staffing`), freight netted out (`--trip-cost`, `--cargo`), HQ/COGC/experts/faction, `--planet ID` adds that planet's extraction, fertility and COGC (a planet not in state is a new base: no HQ, permits+1), `--deprec 60` prices demolish-later. `--min-n` is ONLY a noise filter on market capacity (use 3, ideally 10); ROI is always for our own size (`--own`, default 1 building), never at the filtered scale. Below 1 lets sub-building junk in. `--json rows.json` feeds `persistence.py`. Library: `puga/saturation.py`.
|
|
- `tools/history.py TICKER` monthly margin history of the recipe producing TICKER; `tools/persistence.py rows.json` re-prices scan rows over history (mean ROI 7/14/30/90/180d, payback, net gain over 7 and 14 days, % days profitable). ALWAYS check persistence before recommending: current margins are often a spike.
|
|
- `tools/chain.py TICKER` make-vs-buy cost tree plus sourcing depth of inputs.
|
|
- `tools/price.py` prices across exchanges with VWAP, volume, fill price for a quantity; `tools/book.py` order-book ladder.
|
|
- `tools/prun_scan.py`, `tools/prun_cxarb.py` legacy top-of-book scans; overstate thin markets. Baseline only. `tools/arb.py` replacement is on the roadmap.
|
|
- `puga/econ.py` pure formulas ported from PRUNplanner (efficiency stack, workforce, extraction, production I/O, hab optimizer); `tests/test_econ.py` holds the reference values.
|
|
|
|
## Model policy
|
|
Sonnet builds; spawn a bigger model (Agent `model: opus|fable`) for the review points in `docs/decisions.md`. Roadmap: `docs/roadmap.md`.
|
|
|
|
## Key analytic rule: depth matters
|
|
PRUNplanner's ROI Overview ranks recipes as if the market absorbs unlimited output (e.g. 0.25 day ROI on a recipe whose whole market fits in 2 buildings). Every opportunity we report must include **saturation** (buildings the market can absorb) and, for anything we would act on, **persistence** (is the margin a spike?). Report ROI at realistic fill prices, not top-of-book.
|