Skip to content

Commit 3755675

Browse files
committed
wave9: migrate docs and demos to async Client release prep
1 parent c0a2181 commit 3755675

36 files changed

+622
-1556
lines changed

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Py-Ritone is a zero-setup local bridge between a Fabric Minecraft client (with B
44

55
## Monorepo Layout
66

7-
- `mod/`: Fabric client mod (`pyritone_bridge`) exposing a local NDJSON socket bridge.
8-
- `python/`: PyPI-ready package (`pyritone`) with async client, sync wrapper, and CLI.
7+
- `mod/`: Fabric client mod (`pyritone_bridge`) exposing a local WebSocket v2 bridge.
8+
- `python/`: PyPI-ready package (`pyritone`) with async client, compatibility aliases, and CLI.
99
- `protocol/`: Versioned bridge protocol docs and JSON schema.
1010
- `docs/`: Developer setup and runbook.
1111

@@ -20,16 +20,22 @@ Py-Ritone is a zero-setup local bridge between a Fabric Minecraft client (with B
2020
pip install pyritone
2121
```
2222

23-
5. Start Minecraft client. Py-Ritone opens `127.0.0.1:27841` automatically.
23+
5. Start Minecraft client. Py-Ritone opens the local bridge at `ws://127.0.0.1:27841/ws` automatically.
2424
6. Use the package:
2525

2626
```python
27-
from pyritone import PyritoneClient
27+
import asyncio
28+
from pyritone import Client
2829

29-
with PyritoneClient() as client:
30-
print(client.ping())
31-
print(client.status_get())
32-
print(client.execute("goto 100 70 100"))
30+
31+
async def main() -> None:
32+
async with Client() as client:
33+
print(await client.ping())
34+
print(await client.status_get())
35+
print(await client.execute("goto 100 70 100"))
36+
37+
38+
asyncio.run(main())
3339
```
3440

3541
## Demos / Videos
@@ -58,6 +64,11 @@ python demos/01_connect_discovery.py
5864
- `09` local-path build helper: `python demos/09_build_file_local_path.py "house.schem" --coords 100 -60 100 --wait`
5965
- `10` CLI entrypoints: `python demos/10_cli_entrypoints.py`
6066

67+
## Release Prep
68+
69+
- Async-only release checklist: `docs/release-checklist.md`
70+
- Parity/fallback debt snapshot: `python/docs/release-parity-fallback-report.md`
71+
6172
## One-Click Dev Client
6273

6374
- Double-click `run_dev_client.bat` at repo root, or run it in terminal:

docs/dev-setup.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ python -m twine check dist/*
3939
3. From Python:
4040

4141
```python
42-
from pyritone import PyritoneClient
42+
import asyncio
43+
from pyritone import Client
4344

44-
with PyritoneClient() as client:
45-
print(client.ping())
46-
print(client.status_get())
45+
46+
async def main() -> None:
47+
async with Client() as client:
48+
print(await client.ping())
49+
print(await client.status_get())
50+
51+
52+
asyncio.run(main())
4753
```

docs/release-checklist.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Release Checklist (Async-Only Client Era)
2+
3+
Use this checklist before publishing a release from `feat/ws-v2-async`.
4+
5+
## 1. Quality Gates
6+
7+
- `python -m pytest -q`
8+
- `cd mod && .\gradlew.bat test --no-daemon`
9+
- `python python/tools/generate_baritone_commands.py --check`
10+
11+
## 2. Documentation Gates
12+
13+
- Root docs show `pyritone.Client` as the primary client.
14+
- Python docs/examples are async-only (`await` + `async with Client()` flows).
15+
- Demo scripts run with async client helpers.
16+
- Migration notes are confined to:
17+
- `python/docs/migration-from-legacy-aliases.md`
18+
19+
## 3. Parity + Debt Review
20+
21+
- Confirm typed parity matrix is current:
22+
- `python/docs/baritone-typed-parity.md`
23+
- Confirm release parity/debt snapshot is current:
24+
- `python/docs/release-parity-fallback-report.md`
25+
- Confirm fallback debt gates are green:
26+
- `python/tests/test_fallback_debt.py`
27+
28+
## 4. Versioning + Changelog
29+
30+
- Record user-facing changes in changelog under an `Unreleased` (or release) section.
31+
- If compatibility aliases/shims are removed, treat as a breaking change release.
32+
- Ensure release notes call out websocket v2 + async-only client direction.
33+
34+
## 5. Publish Readiness
35+
36+
- Build Python package:
37+
- `cd python && python -m build`
38+
- `cd python && python -m twine check dist/*`
39+
- Validate release artifacts and docs links before tagging.

docs/runbook.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Runbook
22

3+
## Release Prep
4+
5+
- Async-only release checklist: `docs/release-checklist.md`
6+
- Parity/fallback debt snapshot: `python/docs/release-parity-fallback-report.md`
7+
38
## Bridge Not Starting
49

510
- Check Minecraft client logs for `pyritone_bridge` startup errors.

python/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ python demos/01_connect_discovery.py
5050
- Full docs index: `python/docs/index.md`
5151
- Quickstart: `python/docs/quickstart.md`
5252
- Async client guide: `python/docs/async-client.md`
53+
- Legacy import migration: `python/docs/migration-from-legacy-aliases.md`
5354
- Settings API: `python/docs/settings-api.md`
5455
- Tasks/events/waiting: `python/docs/tasks-events-and-waiting.md`
5556
- Errors/troubleshooting: `python/docs/errors-and-troubleshooting.md`
@@ -64,14 +65,13 @@ python demos/01_connect_discovery.py
6465
- `python/docs/commands/aliases.md`
6566
- Raw Baritone appendix: `python/docs/baritone-commands.md`
6667
- Typed parity matrix: `python/docs/baritone-typed-parity.md`
68+
- Release parity/debt report: `python/docs/release-parity-fallback-report.md`
6769

6870
## Public API Map
6971

7072
- Clients:
71-
- `Client` (primary)
72-
- `PyritoneClient`
73-
- `AsyncPyritoneClient`
74-
- `PyritoneClient` and `AsyncPyritoneClient` are temporary async aliases of `Client`.
73+
- `Client` (primary async surface)
74+
- Legacy aliases (`PyritoneClient`, `AsyncPyritoneClient`) are compatibility-only; use `Client` in docs and new code.
7575
- Low-level methods:
7676
- `ping`, `status_get`, `status_subscribe`, `status_unsubscribe`, `execute`, `cancel`, `next_event`, `wait_for`, `wait_for_task`
7777
- Typed API substrate: `api_metadata_get`, `api_construct`, `api_invoke`
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
from __future__ import annotations
22

3-
from _common import print_json, run_sync_demo, step
3+
from _common import print_json, run_async_demo, step
44

55

6-
def demo(client):
6+
async def demo(client):
77
step("Using default discovery: bridge-info file or PYRITONE_* overrides.")
8-
print_json("ping()", client.ping())
9-
print_json("status_get()", client.status_get())
8+
print_json("ping()", await client.ping())
9+
print_json("status_get()", await client.status_get())
1010
return 0
1111

1212

1313
if __name__ == "__main__":
14-
raise SystemExit(run_sync_demo("01 - Connect + Discovery", demo))
14+
raise SystemExit(run_async_demo("01 - Connect + Discovery", demo))

python/demos/02_basic_commands.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
from __future__ import annotations
22

3-
from _common import print_json, run_sync_demo, step, summarize_dispatch
3+
from _common import print_json, run_async_demo, step, summarize_dispatch
44

55

6-
def demo(client):
6+
async def demo(client):
77
step("High-level wrappers first: help(), version(), set(...).")
88

9-
help_dispatch = client.help()
9+
help_dispatch = await client.help()
1010
print(f"help() summary: {summarize_dispatch(help_dispatch)}")
1111
print_json("help()", help_dispatch)
1212

13-
version_dispatch = client.version()
13+
version_dispatch = await client.version()
1414
print(f"version() summary: {summarize_dispatch(version_dispatch)}")
1515
print_json("version()", version_dispatch)
1616

17-
set_dispatch = client.set("allowPlace", True)
17+
set_dispatch = await client.set("allowPlace", True)
1818
print(f"set('allowPlace', True) summary: {summarize_dispatch(set_dispatch)}")
1919
print_json("set('allowPlace', True)", set_dispatch)
2020

21-
step("Raw fallback: execute('help').")
22-
print_json("execute('help')", client.execute("help"))
21+
step("Raw command transport: execute('help').")
22+
print_json("execute('help')", await client.execute("help"))
2323
return 0
2424

2525

2626
if __name__ == "__main__":
27-
raise SystemExit(run_sync_demo("02 - Basic Commands", demo))
27+
raise SystemExit(run_async_demo("02 - Basic Commands", demo))

python/demos/03_goto_completion.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from _common import (
66
print_json,
7-
run_sync_demo,
7+
run_async_demo,
88
step,
99
summarize_pause_update,
1010
summarize_dispatch,
@@ -21,9 +21,9 @@
2121
args = parser.parse_args()
2222

2323

24-
def demo(client):
24+
async def demo(client):
2525
step(f"Dispatching goto({args.x}, {args.y}, {args.z})")
26-
dispatch = client.goto(args.x, args.y, args.z)
26+
dispatch = await client.goto(args.x, args.y, args.z)
2727
print(f"goto dispatch summary: {summarize_dispatch(dispatch)}")
2828
print_json("goto dispatch", dispatch)
2929

@@ -58,12 +58,12 @@ def on_update(event):
5858
print(f"task update: {line}")
5959
last_line = line
6060

61-
terminal_event = client.wait_for_task(task_id, on_update=on_update)
61+
terminal_event = await client.wait_for_task(task_id, on_update=on_update)
6262
print(f"terminal event summary: {summarize_event(terminal_event)}")
6363
print_json("terminal event", terminal_event)
6464
step(terminal_summary(terminal_event))
6565
return 0
6666

6767

6868
if __name__ == "__main__":
69-
raise SystemExit(run_sync_demo("03 - Goto + Completion", demo))
69+
raise SystemExit(run_async_demo("03 - Goto + Completion", demo))

python/demos/04_live_event_feed.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import argparse
44

5-
from _common import run_sync_demo, step, task_reason
5+
from _common import run_async_demo, step, task_reason
66

77

88
parser = argparse.ArgumentParser(description="Dispatch demo goto and print concise live bridge events")
@@ -71,11 +71,11 @@ def _event_line(index: int, event: dict) -> str:
7171
)
7272

7373

74-
def demo(client):
74+
async def demo(client):
7575
step(
7676
"Dispatching demo goto to an intentionally high Y so recording clearly shows live path/task behavior."
7777
)
78-
dispatch = client.goto(args.x, args.y, args.z)
78+
dispatch = await client.goto(args.x, args.y, args.z)
7979
task_id = dispatch.get("task_id")
8080
accepted = dispatch.get("accepted")
8181
print(
@@ -94,7 +94,7 @@ def demo(client):
9494

9595
while args.max_events <= 0 or displayed < args.max_events:
9696
try:
97-
event = client.next_event(timeout=args.timeout)
97+
event = await client.next_event(timeout=args.timeout)
9898
except TimeoutError:
9999
step(f"No event in {args.timeout:.1f}s window; still listening...")
100100
continue
@@ -145,4 +145,4 @@ def demo(client):
145145

146146

147147
if __name__ == "__main__":
148-
raise SystemExit(run_sync_demo("04 - Live Event Feed", demo))
148+
raise SystemExit(run_async_demo("04 - Live Event Feed", demo))

python/demos/05_cancel_task.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from __future__ import annotations
22

33
import argparse
4-
import time
4+
import asyncio
55

66
from _common import (
77
print_json,
8-
run_sync_demo,
8+
run_async_demo,
99
step,
1010
summarize_dispatch,
1111
summarize_event,
@@ -18,31 +18,31 @@
1818
args = parser.parse_args()
1919

2020

21-
def demo(client):
21+
async def demo(client):
2222
step("Starting a long-running task with high-level wrapper: explore()")
23-
dispatch = client.explore()
23+
dispatch = await client.explore()
2424
print(f"explore() dispatch summary: {summarize_dispatch(dispatch)}")
2525
print_json("explore() dispatch", dispatch)
2626

2727
task_id = dispatch.get("task_id")
2828
if not task_id:
2929
step("No task_id returned, cannot target a specific cancel. Sending global cancel instead.")
30-
print_json("cancel()", client.cancel())
30+
print_json("cancel()", await client.cancel())
3131
return 0
3232

3333
step(f"Waiting {args.delay:.1f}s before canceling task_id={task_id}")
34-
time.sleep(max(args.delay, 0.0))
34+
await asyncio.sleep(max(args.delay, 0.0))
3535

36-
cancel_result = client.cancel(task_id=task_id)
36+
cancel_result = await client.cancel(task_id=task_id)
3737
print_json("cancel(task_id)", cancel_result)
3838

3939
step("Waiting for terminal task event after cancel")
40-
terminal_event = client.wait_for_task(task_id)
40+
terminal_event = await client.wait_for_task(task_id)
4141
print(f"terminal event summary: {summarize_event(terminal_event)}")
4242
print_json("terminal event", terminal_event)
4343
step(terminal_summary(terminal_event))
4444
return 0
4545

4646

4747
if __name__ == "__main__":
48-
raise SystemExit(run_sync_demo("05 - Cancel Task", demo))
48+
raise SystemExit(run_async_demo("05 - Cancel Task", demo))

0 commit comments

Comments
 (0)