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 +106 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
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.
|
|
1
|
+
export declare const SDK_VERSION = "1.12.0";
|
package/dist/version.js
CHANGED