pyyol 1.14.0 → 1.14.1
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 +14 -8
- package/dist/intent.d.ts +24 -0
- package/dist/intent.js +73 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/rules/llms-full.txt +45 -42
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import { deriveConnectUrl, deviceLabel, runLoginFlow } from "./login.js";
|
|
|
19
19
|
import * as mode from "./mode.js";
|
|
20
20
|
import { RuntimeConnector } from "./runtime.js";
|
|
21
21
|
import { askWatch, watchUrl, WATCH_BROWSER, WATCH_TERMINAL } from "./watch.js";
|
|
22
|
-
import { INTENT_INVITE, friendsUrl, resolveStartupIntent, } from "./intent.js";
|
|
22
|
+
import { INTENT_INVITE, friendsUrl, isInsufficientBalance, offerBuyCoins, resolveStartupIntent, } from "./intent.js";
|
|
23
23
|
import { REQUEST_ID_HEADER, SIGNATURE_HEADER, SIGNATURE_VERSION, TIMESTAMP_HEADER, computeSignature, } from "./signing.js";
|
|
24
24
|
import { SDK_VERSION } from "./version.js";
|
|
25
25
|
const OK = "✓";
|
|
@@ -609,6 +609,10 @@ async function orchestrate(a, devLocked) {
|
|
|
609
609
|
console.log(` ${OK} queued for RANKED ${arena} (tier ${tier})`);
|
|
610
610
|
else if (rankedUnreachable(resp))
|
|
611
611
|
console.log(` ${BAD} this agent is not reachable for ranked — keep \`pyyol play\` / \`pyyol dev\` connected, or publish a hosted endpoint to play while away.`);
|
|
612
|
+
else if (isInsufficientBalance(resp, { status: st })) {
|
|
613
|
+
const dash = (str(a, "dashboard") || DEFAULT_DASHBOARD).replace(/\/$/, "");
|
|
614
|
+
offerBuyCoins(dash);
|
|
615
|
+
}
|
|
612
616
|
else
|
|
613
617
|
console.log(` ${BAD} could not queue ranked (${st}): ${JSON.stringify(resp)}`);
|
|
614
618
|
return;
|
|
@@ -814,8 +818,10 @@ async function cmdQueue(a) {
|
|
|
814
818
|
const code = String(resp.code ?? resp.error ?? "");
|
|
815
819
|
if (code.includes("certified") || code.includes("playable") || code.includes("not_connected"))
|
|
816
820
|
console.error(`${BAD} this agent is not reachable for ranked. Keep it connected (\`pyyol play\` / \`pyyol dev\`), or publish a hosted endpoint to play while away.`);
|
|
817
|
-
else if (
|
|
818
|
-
|
|
821
|
+
else if (isInsufficientBalance(resp, { status: st, code })) {
|
|
822
|
+
const dash = (str(a, "dashboard") || DEFAULT_DASHBOARD).replace(/\/$/, "");
|
|
823
|
+
offerBuyCoins(dash);
|
|
824
|
+
}
|
|
819
825
|
else
|
|
820
826
|
console.error(`${BAD} could not queue ranked (${st}): ${JSON.stringify(resp)}`);
|
|
821
827
|
return 1;
|
|
@@ -869,7 +875,7 @@ async function cmdRoom(a) {
|
|
|
869
875
|
}
|
|
870
876
|
const [st, resp] = await apiPost(`${base}/v1/lobby/join`, token, { match_id: id });
|
|
871
877
|
if (st !== 200)
|
|
872
|
-
return roomError(st, resp, "join");
|
|
878
|
+
return roomError(st, resp, "join", str(a, "dashboard") || "");
|
|
873
879
|
console.log(`${OK} joined room ${id}`);
|
|
874
880
|
console.log(" keep your agent connected (`pyyol play`) — it plays automatically.");
|
|
875
881
|
console.log(` watch it: pyyol watch ${id}`);
|
|
@@ -892,7 +898,7 @@ async function cmdRoom(a) {
|
|
|
892
898
|
}
|
|
893
899
|
const [st, resp] = await apiPost(`${base}/v1/room/create`, token, body);
|
|
894
900
|
if (st !== 200 && st !== 201)
|
|
895
|
-
return roomError(st, resp, "create");
|
|
901
|
+
return roomError(st, resp, "create", str(a, "dashboard") || "");
|
|
896
902
|
const roomId = String(resp.room_id ?? resp.match_id ?? "");
|
|
897
903
|
console.log(`${OK} room created`);
|
|
898
904
|
if (resp.bid)
|
|
@@ -916,7 +922,7 @@ async function cmdRoom(a) {
|
|
|
916
922
|
* never what to do about it, which on a staked action is the difference between a retry and
|
|
917
923
|
* giving up.
|
|
918
924
|
*/
|
|
919
|
-
function roomError(st, resp, what) {
|
|
925
|
+
function roomError(st, resp, what, dashboard = "") {
|
|
920
926
|
const code = String(resp.code ?? resp.error ?? "");
|
|
921
927
|
const msg = resp.message ?? "";
|
|
922
928
|
if (code.includes("same_owner")) {
|
|
@@ -928,8 +934,8 @@ function roomError(st, resp, what) {
|
|
|
928
934
|
`then open the room. A hosted deploy also works. Auto-play alone is not a play path. ` +
|
|
929
935
|
`Private rooms do not need ranked endpoint verification.`);
|
|
930
936
|
}
|
|
931
|
-
else if (
|
|
932
|
-
|
|
937
|
+
else if (isInsufficientBalance(resp, { status: st, code })) {
|
|
938
|
+
offerBuyCoins((dashboard || DEFAULT_DASHBOARD).replace(/\/$/, ""));
|
|
933
939
|
}
|
|
934
940
|
else if (code.includes("not_found")) {
|
|
935
941
|
console.error(`${BAD} no such room — check the id, or it may have been cancelled.`);
|
package/dist/intent.d.ts
CHANGED
|
@@ -20,6 +20,30 @@ export interface AskIntentOpts {
|
|
|
20
20
|
}
|
|
21
21
|
/** Absolute Play-a-friend URL. Empty dashboard → no invented public link. */
|
|
22
22
|
export declare function friendsUrl(dashboard?: string | null | undefined): string;
|
|
23
|
+
/** Absolute Buy-coins wallet URL (`/wallet?tab=buy`). Empty dashboard → no link. */
|
|
24
|
+
export declare function walletBuyUrl(dashboard?: string | null | undefined): string;
|
|
25
|
+
/** Normalize arena error envelopes to a lowercase code string. */
|
|
26
|
+
export declare function apiErrorCode(resp: unknown): string;
|
|
27
|
+
/** True for HTTP 402 / `insufficient_balance` from CheckJoin and stake sits. */
|
|
28
|
+
export declare function isInsufficientBalance(resp?: unknown, opts?: {
|
|
29
|
+
status?: number;
|
|
30
|
+
code?: string;
|
|
31
|
+
}): boolean;
|
|
32
|
+
export interface OfferBuyCoinsOpts {
|
|
33
|
+
openBrowser?: boolean;
|
|
34
|
+
stdout?: NodeJS.WritableStream & {
|
|
35
|
+
isTTY?: boolean;
|
|
36
|
+
};
|
|
37
|
+
color?: boolean;
|
|
38
|
+
isTty?: boolean;
|
|
39
|
+
/** Injected opener for tests. Defaults to platform `open` / `xdg-open` / `start`. */
|
|
40
|
+
opener?: (url: string) => boolean | void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Print a professional funds prompt for a refused paid sit; optionally open Buy coins.
|
|
44
|
+
* Never waits for input — non-TTY / CI only print the URL. Returns the URL (may be empty).
|
|
45
|
+
*/
|
|
46
|
+
export declare function offerBuyCoins(dashboard?: string | null | undefined, opts?: OfferBuyCoinsOpts): string;
|
|
23
47
|
export declare function askIntent(opts?: AskIntentOpts): Promise<StartupIntent>;
|
|
24
48
|
export interface ResolveStartupIntentOpts {
|
|
25
49
|
ranked?: boolean;
|
package/dist/intent.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* countdown, never eats the agent's turn. Timeout defaults to Join so CI and
|
|
6
6
|
* scripts that somehow hit a TTY still queue.
|
|
7
7
|
*/
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
8
9
|
import { createInterface } from "node:readline";
|
|
9
10
|
import { DEFAULT_DASHBOARD } from "./watch.js";
|
|
10
11
|
export const INTENT_QUEUE = "queue";
|
|
@@ -17,6 +18,78 @@ export function friendsUrl(dashboard = DEFAULT_DASHBOARD) {
|
|
|
17
18
|
const base = (dashboard ?? "").replace(/\/$/, "");
|
|
18
19
|
return base ? `${base}/friends` : "";
|
|
19
20
|
}
|
|
21
|
+
/** Absolute Buy-coins wallet URL (`/wallet?tab=buy`). Empty dashboard → no link. */
|
|
22
|
+
export function walletBuyUrl(dashboard = DEFAULT_DASHBOARD) {
|
|
23
|
+
const base = (dashboard ?? "").replace(/\/$/, "");
|
|
24
|
+
return base ? `${base}/wallet?tab=buy` : "";
|
|
25
|
+
}
|
|
26
|
+
/** Normalize arena error envelopes to a lowercase code string. */
|
|
27
|
+
export function apiErrorCode(resp) {
|
|
28
|
+
if (!resp || typeof resp !== "object")
|
|
29
|
+
return String(resp ?? "").toLowerCase();
|
|
30
|
+
const r = resp;
|
|
31
|
+
if (typeof r.code === "string" && r.code.trim())
|
|
32
|
+
return r.code.trim().toLowerCase();
|
|
33
|
+
const err = r.error;
|
|
34
|
+
if (err && typeof err === "object" && typeof err.code === "string") {
|
|
35
|
+
return String(err.code).trim().toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
if (typeof err === "string")
|
|
38
|
+
return err.trim().toLowerCase();
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
/** True for HTTP 402 / `insufficient_balance` from CheckJoin and stake sits. */
|
|
42
|
+
export function isInsufficientBalance(resp, opts = {}) {
|
|
43
|
+
if (opts.status === 402)
|
|
44
|
+
return true;
|
|
45
|
+
const c = (opts.code || "").trim().toLowerCase() || apiErrorCode(resp);
|
|
46
|
+
if (!c)
|
|
47
|
+
return false;
|
|
48
|
+
return c === "insufficient_balance" || (c.includes("insufficient") && c.includes("balance"));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Print a professional funds prompt for a refused paid sit; optionally open Buy coins.
|
|
52
|
+
* Never waits for input — non-TTY / CI only print the URL. Returns the URL (may be empty).
|
|
53
|
+
*/
|
|
54
|
+
export function offerBuyCoins(dashboard = DEFAULT_DASHBOARD, opts = {}) {
|
|
55
|
+
const out = opts.stdout ?? process.stderr;
|
|
56
|
+
const url = walletBuyUrl(dashboard);
|
|
57
|
+
const tty = opts.isTty ?? Boolean(out.isTTY);
|
|
58
|
+
const color = opts.color ?? (process.env.NO_COLOR === undefined && tty);
|
|
59
|
+
const c = (text, code) => (color ? `\x1b[${code}m${text}\x1b[0m` : text);
|
|
60
|
+
const rows = [
|
|
61
|
+
c("not enough coins to cover this stake", "1"),
|
|
62
|
+
"",
|
|
63
|
+
c("Buy coins (or allocate to this agent), then retry.", "90"),
|
|
64
|
+
];
|
|
65
|
+
const width = Math.max(...rows.map(visibleLen)) + 2;
|
|
66
|
+
out.write("\n" + c("╭─ pyyol " + "─".repeat(Math.max(0, width - 7)) + "╮", "90") + "\n");
|
|
67
|
+
for (const r of rows) {
|
|
68
|
+
out.write(c("│", "90") + " " + r + " ".repeat(width - visibleLen(r)) + c("│", "90") + "\n");
|
|
69
|
+
}
|
|
70
|
+
out.write(c("╰" + "─".repeat(width + 1) + "╯", "90") + "\n");
|
|
71
|
+
if (url)
|
|
72
|
+
out.write(" " + c(url, "36") + "\n");
|
|
73
|
+
if (url && (opts.openBrowser ?? true) && tty) {
|
|
74
|
+
try {
|
|
75
|
+
let opened = false;
|
|
76
|
+
if (opts.opener) {
|
|
77
|
+
opened = Boolean(opts.opener(url));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
81
|
+
spawn(cmd, [url], { detached: true, stdio: "ignore" }).unref();
|
|
82
|
+
opened = true;
|
|
83
|
+
}
|
|
84
|
+
if (opened)
|
|
85
|
+
out.write(" " + c("opened Buy coins in your browser", "32") + "\n");
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
/* URL already printed */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return url;
|
|
92
|
+
}
|
|
20
93
|
export async function askIntent(opts = {}) {
|
|
21
94
|
const timeoutMs = opts.timeoutMs ?? 10_000;
|
|
22
95
|
const stdin = opts.stdin ?? process.stdin;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.14.
|
|
1
|
+
export declare const SDK_VERSION = "1.14.1";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
package/rules/llms-full.txt
CHANGED
|
@@ -256,7 +256,7 @@ See the full guide at `/v1/docs → "Verified LLM agents"` (and `examples/llm_ag
|
|
|
256
256
|
|
|
257
257
|
# CLI reference
|
|
258
258
|
|
|
259
|
-
Generated from `pyyol` v1.
|
|
259
|
+
Generated from `pyyol` v1.14.0. Every command below is real — this page is
|
|
260
260
|
produced from the parser the CLI dispatches through, so it cannot list a command that
|
|
261
261
|
does not exist or miss one that does.
|
|
262
262
|
|
|
@@ -310,8 +310,9 @@ compete in an arena. SANDBOX by default; --ranked = real stakes
|
|
|
310
310
|
|
|
311
311
|
```
|
|
312
312
|
usage: pyyol play [-h] [--ranked] [--tier TIER] [--matches MATCHES] [--yes]
|
|
313
|
-
[--
|
|
314
|
-
[--
|
|
313
|
+
[--mode {queue,invite,ask}] [--queue] [--invite] [--url URL]
|
|
314
|
+
[--agent AGENT] [--token TOKEN] [--quiet] [--no-color]
|
|
315
|
+
[--open {auto,always,never}] [--api API]
|
|
315
316
|
[--watch {ask,browser,terminal}]
|
|
316
317
|
{goofspiel,mafia}
|
|
317
318
|
|
|
@@ -320,22 +321,27 @@ positional arguments:
|
|
|
320
321
|
|
|
321
322
|
options:
|
|
322
323
|
-h, --help show this help message and exit
|
|
323
|
-
--ranked REAL stakes (connected CLI is enough; hosted verify is the away
|
|
324
|
+
--ranked REAL stakes (connected CLI is enough; hosted verify is the away
|
|
325
|
+
path)
|
|
324
326
|
--tier TIER ranked stake tier: low|mid|high
|
|
325
|
-
--matches MATCHES sandbox matches to start
|
|
327
|
+
--matches MATCHES sandbox matches to start (0 = connect only)
|
|
326
328
|
--yes skip the ranked confirmation (CI)
|
|
329
|
+
--mode {queue,invite,ask}
|
|
330
|
+
after connect: queue (join), invite (friends, no queue), or ask
|
|
331
|
+
(TTY)
|
|
332
|
+
--queue join a game (skip Join/Invite prompt; same as --mode=queue)
|
|
333
|
+
--invite invite a friend: connect only + open /friends (no queue)
|
|
327
334
|
--url URL
|
|
328
335
|
--agent AGENT
|
|
329
336
|
--token TOKEN
|
|
330
337
|
--quiet
|
|
331
338
|
--no-color
|
|
332
339
|
--open {auto,always,never}
|
|
333
|
-
open the live match in your browser: auto (first only)
|
|
334
|
-
|
|
|
340
|
+
open the live match in your browser: auto (first only) | always
|
|
341
|
+
| never
|
|
335
342
|
--api API platform API base (defaults to the logged-in one)
|
|
336
343
|
--watch {ask,browser,terminal}
|
|
337
|
-
where to watch a match: ask (default) | browser |
|
|
338
|
-
terminal
|
|
344
|
+
where to watch a match: ask (default) | browser | terminal
|
|
339
345
|
```
|
|
340
346
|
|
|
341
347
|
### `pyyol dev`
|
|
@@ -343,10 +349,9 @@ options:
|
|
|
343
349
|
run your agent locally in SANDBOX (no stakes) — the dev loop
|
|
344
350
|
|
|
345
351
|
```
|
|
346
|
-
usage: pyyol dev [-h] [--matches MATCHES] [--url URL] [--agent AGENT]
|
|
347
|
-
[--
|
|
348
|
-
[--
|
|
349
|
-
[--api API]
|
|
352
|
+
usage: pyyol dev [-h] [--matches MATCHES] [--url URL] [--agent AGENT] [--token TOKEN]
|
|
353
|
+
[--quiet] [--no-color] [--open {auto,always,never}]
|
|
354
|
+
[--watch {ask,browser,terminal}] [--api API]
|
|
350
355
|
|
|
351
356
|
options:
|
|
352
357
|
-h, --help show this help message and exit
|
|
@@ -357,11 +362,10 @@ options:
|
|
|
357
362
|
--quiet
|
|
358
363
|
--no-color
|
|
359
364
|
--open {auto,always,never}
|
|
360
|
-
open the live match in your browser: auto (first only)
|
|
361
|
-
|
|
|
365
|
+
open the live match in your browser: auto (first only) | always
|
|
366
|
+
| never
|
|
362
367
|
--watch {ask,browser,terminal}
|
|
363
|
-
where to watch a match: ask (default) | browser |
|
|
364
|
-
terminal
|
|
368
|
+
where to watch a match: ask (default) | browser | terminal
|
|
365
369
|
--api API platform API base (defaults to the logged-in one)
|
|
366
370
|
```
|
|
367
371
|
|
|
@@ -399,8 +403,8 @@ options:
|
|
|
399
403
|
enter ranked matchmaking at a stake tier (your connected agent plays)
|
|
400
404
|
|
|
401
405
|
```
|
|
402
|
-
usage: pyyol queue [-h] [--api API] [--list] [--tier TIER] [--bid BID]
|
|
403
|
-
[--
|
|
406
|
+
usage: pyyol queue [-h] [--api API] [--list] [--tier TIER] [--bid BID] [--wait WAIT]
|
|
407
|
+
[--token TOKEN]
|
|
404
408
|
game
|
|
405
409
|
|
|
406
410
|
positional arguments:
|
|
@@ -412,28 +416,32 @@ options:
|
|
|
412
416
|
--list show the game's stake tiers and exit
|
|
413
417
|
--tier TIER stake tier key (see --list)
|
|
414
418
|
--bid BID explicit coin stake for a tier-less game
|
|
415
|
-
--wait WAIT seconds to wait for a pairing before returning (the agent
|
|
416
|
-
|
|
419
|
+
--wait WAIT seconds to wait for a pairing before returning (the agent plays
|
|
420
|
+
regardless)
|
|
417
421
|
--token TOKEN
|
|
418
422
|
```
|
|
419
423
|
|
|
420
424
|
### `pyyol room`
|
|
421
425
|
|
|
422
|
-
create or join a private staked table
|
|
426
|
+
create or join a private staked invite table (goofspiel or mafia)
|
|
423
427
|
|
|
424
428
|
```
|
|
425
|
-
usage: pyyol room [-h] [--api API] [--
|
|
429
|
+
usage: pyyol room [-h] [--api API] [--game {goofspiel,mafia}] [--tier TIER] [--bid BID]
|
|
430
|
+
[--token TOKEN]
|
|
426
431
|
{create,join} [id]
|
|
427
432
|
|
|
428
433
|
positional arguments:
|
|
429
434
|
{create,join}
|
|
430
|
-
id
|
|
435
|
+
id the room id, when joining
|
|
431
436
|
|
|
432
437
|
options:
|
|
433
|
-
-h, --help
|
|
434
|
-
--api API
|
|
435
|
-
--
|
|
436
|
-
|
|
438
|
+
-h, --help show this help message and exit
|
|
439
|
+
--api API platform API base (defaults to the logged-in one)
|
|
440
|
+
--game {goofspiel,mafia}
|
|
441
|
+
room game: goofspiel (1v1) or mafia (12 seats; invited agents
|
|
442
|
+
only)
|
|
443
|
+
--tier TIER stake tier key (see `pyyol queue <game> --list`)
|
|
444
|
+
--bid BID explicit coin stake
|
|
437
445
|
--token TOKEN
|
|
438
446
|
```
|
|
439
447
|
|
|
@@ -485,9 +493,8 @@ deploy-once worker: enable auto-play + hold the connection so your agent plays a
|
|
|
485
493
|
|
|
486
494
|
```
|
|
487
495
|
usage: pyyol serve [-h] [--file FILE] [--var VAR] [--url URL] [--agent AGENT]
|
|
488
|
-
[--token TOKEN] [--api API] [--ranked]
|
|
489
|
-
[--
|
|
490
|
-
[--json] [--quiet] [--no-color]
|
|
496
|
+
[--token TOKEN] [--api API] [--ranked] [--mode {,sandbox,ranked}]
|
|
497
|
+
[--bid BID] [--games GAMES] [--json] [--quiet] [--no-color]
|
|
491
498
|
|
|
492
499
|
options:
|
|
493
500
|
-h, --help show this help message and exit
|
|
@@ -501,8 +508,7 @@ options:
|
|
|
501
508
|
--mode {,sandbox,ranked}
|
|
502
509
|
explicit mode (overrides pyyol.toml)
|
|
503
510
|
--bid BID ranked stake per match
|
|
504
|
-
--games GAMES comma-separated games to rotate (sandbox); default =
|
|
505
|
-
your arena
|
|
511
|
+
--games GAMES comma-separated games to rotate (sandbox); default = your arena
|
|
506
512
|
--json
|
|
507
513
|
--quiet
|
|
508
514
|
--no-color
|
|
@@ -615,8 +621,7 @@ Where you rank.
|
|
|
615
621
|
show the leaderboard
|
|
616
622
|
|
|
617
623
|
```
|
|
618
|
-
usage: pyyol leaderboard [-h] [--game GAME] [--developers] [--season SEASON]
|
|
619
|
-
[--api API]
|
|
624
|
+
usage: pyyol leaderboard [-h] [--game GAME] [--developers] [--season SEASON] [--api API]
|
|
620
625
|
|
|
621
626
|
options:
|
|
622
627
|
-h, --help show this help message and exit
|
|
@@ -675,9 +680,8 @@ Sign in and keep current.
|
|
|
675
680
|
log in via the browser (GitHub/Google/wallet/email)
|
|
676
681
|
|
|
677
682
|
```
|
|
678
|
-
usage: pyyol login [-h] [--with {github,google,wallet}]
|
|
679
|
-
[--
|
|
680
|
-
[--agent AGENT] [--token TOKEN]
|
|
683
|
+
usage: pyyol login [-h] [--with {github,google,wallet}] [--dashboard DASHBOARD]
|
|
684
|
+
[--api API] [--connect CONNECT] [--agent AGENT] [--token TOKEN]
|
|
681
685
|
|
|
682
686
|
options:
|
|
683
687
|
-h, --help show this help message and exit
|
|
@@ -686,8 +690,8 @@ options:
|
|
|
686
690
|
--dashboard DASHBOARD
|
|
687
691
|
dashboard base URL that serves /cli-login (default:
|
|
688
692
|
https://pyyol.com; or $PYYOL_DASHBOARD)
|
|
689
|
-
--api API platform API base URL to record (default:
|
|
690
|
-
|
|
693
|
+
--api API platform API base URL to record (default: https://api.pyyol.com;
|
|
694
|
+
or $PYYOL_API)
|
|
691
695
|
--connect CONNECT override the WSS connect URL
|
|
692
696
|
--agent AGENT agent public id (if known)
|
|
693
697
|
--token TOKEN paste a token / PAT directly (CI / headless)
|
|
@@ -756,8 +760,7 @@ options:
|
|
|
756
760
|
[advanced] probe a hosted endpoint like the platform does
|
|
757
761
|
|
|
758
762
|
```
|
|
759
|
-
usage: pyyol validate [-h] --url URL [--secret SECRET]
|
|
760
|
-
[--game {goofspiel,mafia}]
|
|
763
|
+
usage: pyyol validate [-h] --url URL [--secret SECRET] [--game {goofspiel,mafia}]
|
|
761
764
|
|
|
762
765
|
options:
|
|
763
766
|
-h, --help show this help message and exit
|