pyyol 1.11.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -784,6 +784,108 @@ async function cmdQueue(a) {
784
784
  console.log(` ${OK} matched → ${resp.match_id}\n watch it: pyyol watch ${resp.match_id}`);
785
785
  return 0;
786
786
  }
787
+ /** `pyyol room create|join [id] [--tier low|mid|high | --bid N]` — a PRIVATE staked table.
788
+ *
789
+ * The queue supplies whoever is waiting. A room is for the other case: two developers who
790
+ * want THEIR two agents to play each other. One creates it, sends the id, the other joins.
791
+ *
792
+ * Deliberately the same match as everywhere else: same stake path, same escrow, same
793
+ * certification gate, same refusal to seat both sides on one account. The only thing a room
794
+ * changes is that it is not listed in the open lobby, so the seat cannot be taken by a
795
+ * stranger between the moment the id is shared and the moment it is used.
796
+ */
797
+ async function cmdRoom(a) {
798
+ const c = creds.load();
799
+ const base = httpBase(a, c);
800
+ if (!base) {
801
+ console.error(`${BAD} no arena to talk to — run \`pyyol login\`, or pass --api.`);
802
+ return 2;
803
+ }
804
+ const action = a.positionals[0] ?? "";
805
+ if (action !== "create" && action !== "join") {
806
+ console.error(`${BAD} usage: pyyol room create [--tier low|mid|high | --bid N]`);
807
+ console.error(` pyyol room join <room-id>`);
808
+ return 2;
809
+ }
810
+ // A room is staked on both sides, so it needs a session exactly like `queue` does.
811
+ let token = c?.accessToken || str(a, "token") || process.env.PYYOL_TOKEN || "";
812
+ if (!token) {
813
+ const got = await ensureLogin(a);
814
+ if (!got)
815
+ return 2;
816
+ token = got.accessToken || got.apiKey || "";
817
+ }
818
+ if (action === "join") {
819
+ const id = a.positionals[1] ?? "";
820
+ if (!id) {
821
+ console.error(`${BAD} which room? \`pyyol room join <room-id>\``);
822
+ return 2;
823
+ }
824
+ const [st, resp] = await apiPost(`${base}/v1/lobby/join`, token, { match_id: id });
825
+ if (st !== 200)
826
+ return roomError(st, resp, "join");
827
+ console.log(`${OK} joined room ${id}`);
828
+ console.log(" keep your agent connected (`pyyol run`) — it plays automatically.");
829
+ console.log(` watch it: pyyol watch ${id}`);
830
+ return 0;
831
+ }
832
+ const body = {};
833
+ if (str(a, "tier"))
834
+ body.tier = str(a, "tier");
835
+ else if (num(a, "bid", 0) > 0)
836
+ body.bid = num(a, "bid", 0);
837
+ else {
838
+ console.error(`${BAD} a room is staked: pass --tier <low|mid|high> ` +
839
+ `(see \`pyyol queue goofspiel --list\`) or --bid <coins>.`);
840
+ return 2;
841
+ }
842
+ const [st, resp] = await apiPost(`${base}/v1/room/create`, token, body);
843
+ if (st !== 200 && st !== 201)
844
+ return roomError(st, resp, "create");
845
+ const roomId = String(resp.room_id ?? resp.match_id ?? "");
846
+ console.log(`${OK} room created`);
847
+ if (resp.bid)
848
+ console.log(` stake: ${resp.bid} coins each`);
849
+ // The id gets its own line with nothing around it, because the next thing anyone does is
850
+ // drag-select it to paste into a chat, and a line with prose on it selects badly.
851
+ console.log();
852
+ console.log(` ${roomId}`);
853
+ console.log();
854
+ console.log(" send that to the other player. they run:");
855
+ console.log(` pyyol room join ${roomId}`);
856
+ console.log(" keep your agent connected (`pyyol run`) — it plays as soon as they join.");
857
+ return 0;
858
+ }
859
+ /** Turn the arena's refusal codes into something a developer can act on.
860
+ *
861
+ * Every branch here is a real first-try failure. The raw JSON says what was refused and
862
+ * never what to do about it, which on a staked action is the difference between a retry and
863
+ * giving up.
864
+ */
865
+ function roomError(st, resp, what) {
866
+ const code = String(resp.code ?? resp.error ?? "");
867
+ const msg = resp.message ?? "";
868
+ if (code.includes("same_owner")) {
869
+ console.error(`${BAD} that is your own room — a match needs two different accounts. ` +
870
+ `Send the id to the other player.`);
871
+ }
872
+ else if (code.includes("certified")) {
873
+ console.error(`${BAD} agent not certified — run \`pyyol publish\` to verify your endpoint first.`);
874
+ }
875
+ else if (code.includes("balance") || code.includes("insufficient")) {
876
+ console.error(`${BAD} not enough coins to stake this room.`);
877
+ }
878
+ else if (code.includes("not_found")) {
879
+ console.error(`${BAD} no such room — check the id, or it may have been cancelled.`);
880
+ }
881
+ else if (code.includes("not_waiting")) {
882
+ console.error(`${BAD} that room is no longer open (already started or cancelled).`);
883
+ }
884
+ else {
885
+ console.error(`${BAD} could not ${what} room (${st}): ${msg || JSON.stringify(resp)}`);
886
+ }
887
+ return 1;
888
+ }
787
889
  async function cmdLeaderboard(a) {
788
890
  const base = httpBase(a, creds.load());
789
891
  if (!base) {
@@ -1671,6 +1773,8 @@ Commands:
1671
1773
  play <arena> [--ranked] [--tier] compete; --ranked = real stakes
1672
1774
  publish --manifest <file> certify your agent for ranked
1673
1775
  queue <game> [--tier low|mid|high | --bid N] [--list] enter ranked matchmaking
1776
+ room create [--tier low|mid|high | --bid N] open a PRIVATE staked table
1777
+ room join <room-id> play a specific opponent by their room id
1674
1778
  wallet [--json] your coin balance + per-agent wallets
1675
1779
  replay <match_id> [--game] [--json]
1676
1780
  profile [handle]
@@ -1721,6 +1825,8 @@ export async function main(argv = process.argv.slice(2)) {
1721
1825
  return cmdWallet(a);
1722
1826
  case "queue":
1723
1827
  return cmdQueue(a);
1828
+ case "room":
1829
+ return cmdRoom(a);
1724
1830
  case "replay":
1725
1831
  return cmdReplay(a);
1726
1832
  case "status":
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "1.11.0";
1
+ export declare const SDK_VERSION = "1.12.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // GENERATED by scripts/genversion.mjs — do not edit by hand.
2
2
  // Source of truth is the "version" field in package.json.
3
- export const SDK_VERSION = "1.11.0"; // x-release-please-version
3
+ export const SDK_VERSION = "1.12.0"; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pyyol",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Official JS/TS SDK for pyyol — run AI game-playing agents locally over a WebSocket (Beta)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",