Add simulator replica, persistence, planet scan, README; split empire state out of the repo
- tools/simulate.py + puga/simulate.py: replica of PRUNplanner's simulator (flows and efficiency verified against screenshots), reports real new capex (planned minus built) - tools/scan.py: staffing variants, freight, HQ/experts, --planet mode, demolish-later, --min-n as a pure market-size filter, --json output - tools/history.py, tools/persistence.py: margin history and short-horizon payback checks - tools/plan_push.py: guarded delete; tools/state.py: syncs to empire/ - README with features and setup; CLAUDE.md made generic - Own-empire material (profile, state, plans, notes) moved to gitignored empire/; generic examples in plans/examples and state/company.example.yaml Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+18
-8
@@ -1,13 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Turn a YAML plan spec (plans/*.yaml) into a PRUNplanner plan, via the Api-Key API.
|
||||
DEFAULT IS DRY RUN. Guardrails (docs/decisions.md): only plans named '[PuGa] ...' are created/updated; never delete;
|
||||
--update refuses if the existing plan's name does not start with '[PuGa]'. Show the dry-run to Dominik and get a yes before --apply.
|
||||
DEFAULT IS DRY RUN. Guardrails (docs/decisions.md): only plans named '[PuGa] ...' are created/updated; deletes only [PuGa] plans and only when asked;
|
||||
--update refuses if the existing plan's name does not start with '[PuGa]'. Show the dry-run to the user and get a yes before --apply.
|
||||
|
||||
tools/plan_push.py list
|
||||
tools/plan_push.py plans/deimos_bhp.yaml # dry run: validated payload summary
|
||||
tools/plan_push.py plans/deimos_bhp.yaml --json # full JSON payload
|
||||
tools/plan_push.py plans/deimos_bhp.yaml --apply # create (after user says yes)
|
||||
tools/plan_push.py plans/deimos_bhp.yaml --apply --update <uuid>
|
||||
tools/plan_push.py plans/examples/base_plus_hwp.yaml # dry run: validated payload summary
|
||||
tools/plan_push.py plans/examples/base_plus_hwp.yaml --json # full JSON payload
|
||||
tools/plan_push.py plans/examples/base_plus_hwp.yaml --apply # create (after user says yes)
|
||||
tools/plan_push.py plans/examples/base_plus_hwp.yaml --apply --update <uuid>
|
||||
tools/plan_push.py delete <uuid> # only [PuGa] plans, only when the user asks
|
||||
|
||||
Spec: name, planet (natural id), permits, cogc (e.g. METALLURGY or null), hq, experts {METALLURGY: 2}, lux {pioneer: [true,true]},
|
||||
infrastructure {HB1: 4, HB2: 1}, buildings: [{building: SME, amount: 5, recipes: ["ALO,FLX,C,O=>4AL"|"AL,STL,HE=>BHP"|"EXT#ALO"]}]
|
||||
@@ -79,7 +80,8 @@ def build_payload(spec: dict, recipes: list[dict], building_tickers: set[str]) -
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("spec", help="plans/*.yaml or 'list'")
|
||||
ap.add_argument("spec", help="plans/*.yaml, 'list', or 'delete'")
|
||||
ap.add_argument("target", nargs="?", help="uuid for 'delete'")
|
||||
ap.add_argument("--apply", action="store_true", help="actually write to PRUNplanner (creates a new plan)")
|
||||
ap.add_argument("--update", metavar="UUID", help="with --apply: update this existing [PuGa] plan instead of creating")
|
||||
ap.add_argument("--json", action="store_true")
|
||||
@@ -89,6 +91,14 @@ def main():
|
||||
for p in pp.request("GET", "/planning/plan/"):
|
||||
print(p["uuid"], p.get("plan_name"), p.get("planet_natural_id"))
|
||||
return
|
||||
if a.spec == "delete":
|
||||
# delete is allowed only on request, and only for plans this tool made ([PuGa] prefix).
|
||||
cur = pp.request("GET", f"/planning/plan/{a.target}/")
|
||||
if not str(cur.get("plan_name", "")).startswith(PREFIX):
|
||||
sys.exit(f"REFUSED: '{cur.get('plan_name')}' is not a {PREFIX} plan")
|
||||
pp.request("DELETE", f"/planning/plan/{a.target}/")
|
||||
print("DELETED:", cur["plan_name"], a.target)
|
||||
return
|
||||
spec = yaml.safe_load(Path(a.spec).read_text())
|
||||
payload = build_payload(spec, pp.recipes(), {b["building_ticker"] for b in pp.buildings()})
|
||||
d = payload["plan_data"]
|
||||
@@ -100,7 +110,7 @@ def main():
|
||||
if a.json:
|
||||
print(json.dumps(payload, indent=1))
|
||||
if not a.apply:
|
||||
print("\nDRY RUN: nothing sent. Re-run with --apply after Dominik confirms.")
|
||||
print("\nDRY RUN: nothing sent. Re-run with --apply after the user confirms.")
|
||||
return
|
||||
if a.update:
|
||||
cur = pp.request("GET", f"/planning/plan/{a.update}/")
|
||||
|
||||
Reference in New Issue
Block a user