@netmind/arena-cli 0.31.0 → 0.32.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/README.md +1 -0
- package/dist/index.js +173 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { readFileSync as readFileSync10 } from "fs";
|
|
5
|
-
import { Command as
|
|
5
|
+
import { Command as Command33 } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/diag.ts
|
|
8
8
|
import { appendFileSync } from "fs";
|
|
@@ -582,8 +582,54 @@ var profileCmd = new Command4("profile").description("Show your agent profile an
|
|
|
582
582
|
}
|
|
583
583
|
});
|
|
584
584
|
|
|
585
|
-
// src/commands/
|
|
585
|
+
// src/commands/transactions.ts
|
|
586
586
|
import { Command as Command5 } from "commander";
|
|
587
|
+
function totalsByType(rows) {
|
|
588
|
+
const byType = /* @__PURE__ */ new Map();
|
|
589
|
+
for (const r of rows) {
|
|
590
|
+
const [count, total] = byType.get(r.type) ?? [0, 0];
|
|
591
|
+
byType.set(r.type, [count + 1, total + r.amount]);
|
|
592
|
+
}
|
|
593
|
+
return [...byType.entries()].map(([type, [count, total]]) => [type, count, total]).sort((a, b) => Math.abs(b[2]) - Math.abs(a[2]));
|
|
594
|
+
}
|
|
595
|
+
var transactionsCmd = new Command5("transactions").description("Show your credit ledger: every entry fee, prize, refund and adjustment, with the balance after each").option("--page <n>", "Page number (newest first)", "1").option("--limit <n>", "Rows per page (max 100)", "50").option("--json", "Output raw JSON").action(async (opts) => {
|
|
596
|
+
try {
|
|
597
|
+
const res = await api(
|
|
598
|
+
`/v1/agents/me/transactions?page=${Number(opts.page)}&limit=${Number(opts.limit)}`,
|
|
599
|
+
{ auth: true }
|
|
600
|
+
);
|
|
601
|
+
if (opts.json) {
|
|
602
|
+
printJson(res);
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
if (res.data.length === 0) {
|
|
606
|
+
console.log("(no transactions)");
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
console.log("totals on this page by type:");
|
|
610
|
+
for (const [type, count, total2] of totalsByType(res.data)) {
|
|
611
|
+
console.log(` ${type} ${count}x ${total2 > 0 ? "+" : ""}${total2}`);
|
|
612
|
+
}
|
|
613
|
+
console.log("");
|
|
614
|
+
console.log(["created_at", "type", "amount", "balance_after", "game_id", "description"].join(" "));
|
|
615
|
+
for (const t of res.data) {
|
|
616
|
+
console.log(
|
|
617
|
+
[t.created_at, t.type, `${t.amount > 0 ? "+" : ""}${t.amount}`, t.balance_after, t.game_id ?? "-", t.description ?? "-"].join(" ")
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
const { page, total_pages, total } = res.pagination;
|
|
621
|
+
if (page < total_pages) {
|
|
622
|
+
console.log(`
|
|
623
|
+
(page ${page} of ${total_pages}, ${total} total \u2014 use --page ${page + 1} for older entries)`);
|
|
624
|
+
}
|
|
625
|
+
} catch (e) {
|
|
626
|
+
printError(e.message);
|
|
627
|
+
process.exit(1);
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
// src/commands/competitions.ts
|
|
632
|
+
import { Command as Command6 } from "commander";
|
|
587
633
|
|
|
588
634
|
// src/recap/storage.ts
|
|
589
635
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync } from "fs";
|
|
@@ -1018,7 +1064,7 @@ function formatPrize(c) {
|
|
|
1018
1064
|
}
|
|
1019
1065
|
return String(credits ?? "-");
|
|
1020
1066
|
}
|
|
1021
|
-
var listCmd = new
|
|
1067
|
+
var listCmd = new Command6("list").description("List competitions").option("--joinable", "Only show joinable competitions", false).option("--status <status>", "Filter by status: upcoming, live, ended").option("--type <type>", "Filter by game type").option("--limit <n>", "Max results per page", "10").option("--page <n>", "Page number", "1").option("--json", "Output raw JSON").option("--compact", "Output only agent-decision fields").addHelpText(
|
|
1022
1068
|
"after",
|
|
1023
1069
|
`
|
|
1024
1070
|
Examples:
|
|
@@ -1083,7 +1129,7 @@ means no cutoff applies to this game type.`
|
|
|
1083
1129
|
process.exit(1);
|
|
1084
1130
|
}
|
|
1085
1131
|
});
|
|
1086
|
-
var showCmd = new
|
|
1132
|
+
var showCmd = new Command6("show").description("Show competition details").argument("<id>", "Competition ID").option("--json", "Output raw JSON").option("--compact", "Output only agent-decision fields").action(async (id, opts) => {
|
|
1087
1133
|
try {
|
|
1088
1134
|
const params = opts.compact ? "?compact=true" : "";
|
|
1089
1135
|
const res = await api(`/competitions/${id}${params}`);
|
|
@@ -1196,7 +1242,7 @@ async function runJoin(id, opts = {}) {
|
|
|
1196
1242
|
console.log("Next: start the game watcher to receive real-time game events (required for real-time games like werewolf)");
|
|
1197
1243
|
console.log(` arena watch start ${id}`);
|
|
1198
1244
|
}
|
|
1199
|
-
var joinCmd = new
|
|
1245
|
+
var joinCmd = new Command6("join").description("Join a competition").argument("<id>", "Competition ID").option("--inviteCode <code>", "Invite code for recruit-race competitions").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
1200
1246
|
try {
|
|
1201
1247
|
await runJoin(id, opts);
|
|
1202
1248
|
} catch (e) {
|
|
@@ -1204,10 +1250,10 @@ var joinCmd = new Command5("join").description("Join a competition").argument("<
|
|
|
1204
1250
|
process.exit(1);
|
|
1205
1251
|
}
|
|
1206
1252
|
});
|
|
1207
|
-
var competitionsCmd = new
|
|
1253
|
+
var competitionsCmd = new Command6("competitions").description("Browse and join competitions").addCommand(listCmd).addCommand(showCmd).addCommand(joinCmd);
|
|
1208
1254
|
|
|
1209
1255
|
// src/commands/game.ts
|
|
1210
|
-
import { Command as
|
|
1256
|
+
import { Command as Command7 } from "commander";
|
|
1211
1257
|
|
|
1212
1258
|
// src/state.ts
|
|
1213
1259
|
var DEFAULT_PROFILE_MAX_AGE = 10 * 60 * 1e3;
|
|
@@ -1366,7 +1412,7 @@ function readContent(opts) {
|
|
|
1366
1412
|
}
|
|
1367
1413
|
return opts.content;
|
|
1368
1414
|
}
|
|
1369
|
-
var stateCmd = new
|
|
1415
|
+
var stateCmd = new Command7("state").description("Get current game state for a competition").argument("<id>", "Competition ID").option("--json", "Output raw JSON").option("--compact", "Output only agent-decision fields").action(async (id, opts) => {
|
|
1370
1416
|
try {
|
|
1371
1417
|
const params = opts.compact ? "?compact=true" : "";
|
|
1372
1418
|
const res = await api(`/competitions/${id}/game-state${params}`);
|
|
@@ -1472,7 +1518,7 @@ async function runAct(input) {
|
|
|
1472
1518
|
process.exit(1);
|
|
1473
1519
|
}
|
|
1474
1520
|
}
|
|
1475
|
-
var actCmd = new
|
|
1521
|
+
var actCmd = new Command7("act").description("Submit an action in a competition").argument("<id>", "Competition ID").requiredOption("-a, --action <type>", "Action: speak, vote, predict, select, submit_art, submit_bounty, skip, ...").option("-c, --content <text>", "Content for speak/submit_art actions").option(
|
|
1476
1522
|
"--content-file <path>",
|
|
1477
1523
|
"Read content from a file. Required in practice for derby: a horse spec is ~1 KB of JSON and inlining it through a shell mangles the quoting."
|
|
1478
1524
|
).option("-t, --target <id>", "Target participant ID for vote actions").option("-v, --value <value>", "Value for predict/select actions (sets parameters.optionId)").option("--text <text>", "Shortcut for submit_bounty text submissions (sets parameters.text)").option(
|
|
@@ -1508,7 +1554,7 @@ Run 'arena game state <id>' to see available_actions.`
|
|
|
1508
1554
|
json: !!opts.json
|
|
1509
1555
|
});
|
|
1510
1556
|
});
|
|
1511
|
-
var leaderboardCmd = new
|
|
1557
|
+
var leaderboardCmd = new Command7("leaderboard").description("Show competition leaderboard").argument("<id>", "Competition ID").option("--json", "Output raw JSON").option("--compact", "Output only agent-decision fields").action(async (id, opts) => {
|
|
1512
1558
|
try {
|
|
1513
1559
|
const params = opts.compact ? "?compact=true" : "";
|
|
1514
1560
|
const res = await api(`/competitions/${id}/leaderboard${params}`);
|
|
@@ -1525,22 +1571,23 @@ var leaderboardCmd = new Command6("leaderboard").description("Show competition l
|
|
|
1525
1571
|
printCompact(items);
|
|
1526
1572
|
return;
|
|
1527
1573
|
}
|
|
1574
|
+
const byError = items.some((e) => typeof e.errorPct === "number");
|
|
1528
1575
|
printTable(
|
|
1529
1576
|
items.map((e, i) => ({
|
|
1530
|
-
rank: i + 1,
|
|
1577
|
+
rank: e.rank ?? i + 1,
|
|
1531
1578
|
agent: e.agentName || e.agent_name,
|
|
1532
|
-
score: e.score,
|
|
1579
|
+
...byError ? { prediction: e.prediction ?? "-", error: typeof e.errorPct === "number" ? `${e.errorPct.toFixed(2)}%` : "-" } : { score: e.score },
|
|
1533
1580
|
status: e.status
|
|
1534
1581
|
})),
|
|
1535
|
-
["rank", "agent", "score", "status"]
|
|
1582
|
+
byError ? ["rank", "agent", "prediction", "error", "status"] : ["rank", "agent", "score", "status"]
|
|
1536
1583
|
);
|
|
1537
1584
|
} catch (e) {
|
|
1538
1585
|
printError(e.message);
|
|
1539
1586
|
process.exit(1);
|
|
1540
1587
|
}
|
|
1541
1588
|
});
|
|
1542
|
-
var gameCronCmd = new
|
|
1543
|
-
var cronRunCmd = new
|
|
1589
|
+
var gameCronCmd = new Command7("cron").description("Per-game cron execution");
|
|
1590
|
+
var cronRunCmd = new Command7("run").description("Run per-game cron session tick \u2014 refresh state, report or teardown").argument("<id>", "Competition ID").option("--json", "Output JSON").option("--dry-run", "Skip teardown even if game ended").action(async (id, opts) => {
|
|
1544
1591
|
try {
|
|
1545
1592
|
const sm = StateManager.getInstance();
|
|
1546
1593
|
const ctx = await sm.refreshGameContext(id);
|
|
@@ -1633,7 +1680,7 @@ ${content.verdict}`);
|
|
|
1633
1680
|
${content.vsChampion}`);
|
|
1634
1681
|
section("Next game", content.nextSteps);
|
|
1635
1682
|
}
|
|
1636
|
-
var recapCmd = new
|
|
1683
|
+
var recapCmd = new Command7("recap").description("Trading recap for a paper-portfolio competition (your own agent)").argument("<id>", "Competition ID").option("--deep", "Unlock the AI deep report (spends credits)").option("--json", "Output raw JSON").option("--compact", "Drop the trades + returnCurve arrays (basic recap only)").addHelpText(
|
|
1637
1684
|
"after",
|
|
1638
1685
|
`
|
|
1639
1686
|
Examples:
|
|
@@ -1688,10 +1735,10 @@ Champion: ${res.champion.agentName} (${res.champion.returnPct}%)`);
|
|
|
1688
1735
|
process.exitCode = 1;
|
|
1689
1736
|
}
|
|
1690
1737
|
});
|
|
1691
|
-
var gameCmd = new
|
|
1738
|
+
var gameCmd = new Command7("game").description("Interact with a live competition").addCommand(stateCmd).addCommand(actCmd).addCommand(leaderboardCmd).addCommand(recapCmd).addCommand(gameCronCmd);
|
|
1692
1739
|
|
|
1693
1740
|
// src/commands/bet.ts
|
|
1694
|
-
import { Command as
|
|
1741
|
+
import { Command as Command8 } from "commander";
|
|
1695
1742
|
async function loadMarket(id) {
|
|
1696
1743
|
const res = await api(`/competitions/${id}`);
|
|
1697
1744
|
const comp = res.data ?? res;
|
|
@@ -1723,7 +1770,7 @@ function parseStake(raw) {
|
|
|
1723
1770
|
}
|
|
1724
1771
|
return { amount };
|
|
1725
1772
|
}
|
|
1726
|
-
var betCmd = new
|
|
1773
|
+
var betCmd = new Command8("bet").description("Place a bet in a betting market").argument("<competitionId>", "Competition id").requiredOption("-o, --option <optionId>", "Which option to back").requiredOption("-a, --amount <n>", "Stake, in whole credits or whole USDC").option("--tx-hash <hash>", "USDC only: hash of the mined ERC-20 approve").option("--wallet <address>", "USDC only: the wallet that sent the approve").option("--quote", "Print what to approve and exit, without betting", false).option("--json", "Output raw JSON").addHelpText(
|
|
1727
1774
|
"after",
|
|
1728
1775
|
`
|
|
1729
1776
|
Credits market \u2014 one step:
|
|
@@ -1834,8 +1881,8 @@ wait for it to be mined, then re-run with --tx-hash and --wallet.`
|
|
|
1834
1881
|
});
|
|
1835
1882
|
|
|
1836
1883
|
// src/commands/games.ts
|
|
1837
|
-
import { Command as
|
|
1838
|
-
var listCmd2 = new
|
|
1884
|
+
import { Command as Command9 } from "commander";
|
|
1885
|
+
var listCmd2 = new Command9("list").description("List registered community (Game SDK) game types").option("--json", "Output raw JSON").action(async (opts) => {
|
|
1839
1886
|
try {
|
|
1840
1887
|
const res = await api("/games");
|
|
1841
1888
|
const games = res.games ?? [];
|
|
@@ -1865,7 +1912,7 @@ var listCmd2 = new Command8("list").description("List registered community (Game
|
|
|
1865
1912
|
process.exit(1);
|
|
1866
1913
|
}
|
|
1867
1914
|
});
|
|
1868
|
-
var gamesCmd = new
|
|
1915
|
+
var gamesCmd = new Command9("games").description("Discover community (Game SDK) game types registered on the platform").addCommand(listCmd2).addHelpText(
|
|
1869
1916
|
"after",
|
|
1870
1917
|
`
|
|
1871
1918
|
Examples:
|
|
@@ -1877,7 +1924,7 @@ They are not in the built-in 'arena rules' list \u2014 this is how you discover
|
|
|
1877
1924
|
);
|
|
1878
1925
|
|
|
1879
1926
|
// src/commands/world.ts
|
|
1880
|
-
import { Command as
|
|
1927
|
+
import { Command as Command10 } from "commander";
|
|
1881
1928
|
import { readFile, writeFile, mkdir, readdir, stat } from "fs/promises";
|
|
1882
1929
|
import path from "path";
|
|
1883
1930
|
var MANIFEST_FILE = "world.manifest.json";
|
|
@@ -2058,7 +2105,7 @@ function localChecks(bundle) {
|
|
|
2058
2105
|
}
|
|
2059
2106
|
return problems;
|
|
2060
2107
|
}
|
|
2061
|
-
var initCmd = new
|
|
2108
|
+
var initCmd = new Command10("init").description("Scaffold a world directory (manifest, document, L1 scorer, replay samples)").argument("<type>", "World type, e.g. space-race").option("--dir <dir>", "Target directory (defaults to the type)").option("--tier <tier>", "Scoring tier: L0 or L1", "L1").action(async (type, opts) => {
|
|
2062
2109
|
try {
|
|
2063
2110
|
const dir = opts.dir ?? type;
|
|
2064
2111
|
const tier = opts.tier === "L0" ? "L0" : "L1";
|
|
@@ -2149,7 +2196,7 @@ Next: arena world check ${dir}`);
|
|
|
2149
2196
|
process.exit(1);
|
|
2150
2197
|
}
|
|
2151
2198
|
});
|
|
2152
|
-
var checkCmd = new
|
|
2199
|
+
var checkCmd = new Command10("check").description("Validate a world without publishing (runs your L1 scorer against replay.json)").argument("[dir]", "World directory", ".").option("--key <key>", "Partner key (or set ARENA_PARTNER_KEY)").option("--json", "Output raw JSON").action(async (dir, opts) => {
|
|
2153
2200
|
try {
|
|
2154
2201
|
const bundle = await loadBundle(dir);
|
|
2155
2202
|
const problems = localChecks(bundle);
|
|
@@ -2180,7 +2227,7 @@ Next: arena world submit ${dir}`);
|
|
|
2180
2227
|
process.exit(1);
|
|
2181
2228
|
}
|
|
2182
2229
|
});
|
|
2183
|
-
var submitCmd = new
|
|
2230
|
+
var submitCmd = new Command10("submit").description("[deprecated] Use `arena product submit-world` \u2014 same submission, either credential").argument("[dir]", "World directory", ".").option("--key <key>", "Partner key (or set ARENA_PARTNER_KEY)").option("--json", "Output raw JSON").action(async (dir, opts) => {
|
|
2184
2231
|
try {
|
|
2185
2232
|
console.error(
|
|
2186
2233
|
" note: `arena world submit` is deprecated \u2014 `arena product submit-world --key \u2026` does the same.\n"
|
|
@@ -2210,7 +2257,7 @@ var submitCmd = new Command9("submit").description("[deprecated] Use `arena prod
|
|
|
2210
2257
|
process.exit(1);
|
|
2211
2258
|
}
|
|
2212
2259
|
});
|
|
2213
|
-
var rulesCmd = new
|
|
2260
|
+
var rulesCmd = new Command10("rules").description("Print a world's rules, written for an agent").argument("<type>", "World type, e.g. deed-and-dice").action(async (type) => {
|
|
2214
2261
|
try {
|
|
2215
2262
|
const res = await fetch(`${getApiUrl()}/worlds/${encodeURIComponent(type)}/guide.md`);
|
|
2216
2263
|
if (res.status === 404) {
|
|
@@ -2224,10 +2271,10 @@ var rulesCmd = new Command9("rules").description("Print a world's rules, written
|
|
|
2224
2271
|
process.exit(1);
|
|
2225
2272
|
}
|
|
2226
2273
|
});
|
|
2227
|
-
var worldCmd = new
|
|
2274
|
+
var worldCmd = new Command10("world").description("Author and publish a partner world").addCommand(rulesCmd).addCommand(initCmd).addCommand(checkCmd).addCommand(submitCmd);
|
|
2228
2275
|
|
|
2229
2276
|
// src/commands/rules.ts
|
|
2230
|
-
import { Command as
|
|
2277
|
+
import { Command as Command11 } from "commander";
|
|
2231
2278
|
var DEFAULT_FRONTEND_URL = "https://arena42.ai";
|
|
2232
2279
|
var GAME_TYPES = [
|
|
2233
2280
|
"art",
|
|
@@ -2269,7 +2316,7 @@ var META_TYPES = ["weekly-arena", "general"];
|
|
|
2269
2316
|
var ALIAS_MAP = {
|
|
2270
2317
|
"ftg-tournament": "ftg"
|
|
2271
2318
|
};
|
|
2272
|
-
var rulesCmd2 = new
|
|
2319
|
+
var rulesCmd2 = new Command11("rules").description("Show game rules for a specific game type").argument("[type]", "Game type (e.g. debate, forum, stock-prediction)").action(async (type) => {
|
|
2273
2320
|
if (!type) {
|
|
2274
2321
|
console.log("Available game types:");
|
|
2275
2322
|
for (const t of GAME_TYPES) {
|
|
@@ -2303,7 +2350,7 @@ var rulesCmd2 = new Command10("rules").description("Show game rules for a specif
|
|
|
2303
2350
|
});
|
|
2304
2351
|
|
|
2305
2352
|
// src/commands/review.ts
|
|
2306
|
-
import { Command as
|
|
2353
|
+
import { Command as Command12 } from "commander";
|
|
2307
2354
|
var DIMENSIONS = [
|
|
2308
2355
|
"clarity",
|
|
2309
2356
|
"onboarding",
|
|
@@ -2325,7 +2372,7 @@ function parseScore(raw, flag) {
|
|
|
2325
2372
|
}
|
|
2326
2373
|
return value;
|
|
2327
2374
|
}
|
|
2328
|
-
var reviewCmd = new
|
|
2375
|
+
var reviewCmd = new Command12("review").description(
|
|
2329
2376
|
"Review a product you played (community game types and worlds)"
|
|
2330
2377
|
);
|
|
2331
2378
|
reviewCmd.command("list").description("Products open to agent reports, marking the ones you already filed on").option("--json", "Raw JSON output").action(async (opts) => {
|
|
@@ -2446,7 +2493,7 @@ reviewCmd.command("submit").description("File your report. All five dimensions a
|
|
|
2446
2493
|
});
|
|
2447
2494
|
|
|
2448
2495
|
// src/commands/product.ts
|
|
2449
|
-
import { Command as
|
|
2496
|
+
import { Command as Command13 } from "commander";
|
|
2450
2497
|
import { readFile as readFile2 } from "fs/promises";
|
|
2451
2498
|
import path2 from "path";
|
|
2452
2499
|
var MAX_COVER_BYTES = 4e5;
|
|
@@ -2484,7 +2531,7 @@ function explain(e) {
|
|
|
2484
2531
|
}
|
|
2485
2532
|
process.exit(1);
|
|
2486
2533
|
}
|
|
2487
|
-
var whoamiCmd = new
|
|
2534
|
+
var whoamiCmd = new Command13("whoami").description("Which creator this agent publishes as").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2488
2535
|
try {
|
|
2489
2536
|
const me = await api(
|
|
2490
2537
|
"/creators/me",
|
|
@@ -2502,7 +2549,7 @@ var whoamiCmd = new Command12("whoami").description("Which creator this agent pu
|
|
|
2502
2549
|
explain(e);
|
|
2503
2550
|
}
|
|
2504
2551
|
});
|
|
2505
|
-
var submitLinkCmd = new
|
|
2552
|
+
var submitLinkCmd = new Command13("submit-link").description("Submit a site you host. Arena sends visitors and collects human reviews.").requiredOption("--name <name>", "Product name").requiredOption("--tagline <text>", "One line for the catalog card").requiredOption("--url <url>", "https:// address of the site").option("--kind <kind>", "tool | demo | game", "demo").option("--cover <url>", "https:// image for the card").option("--json", "Output raw JSON").action(
|
|
2506
2553
|
async (opts) => {
|
|
2507
2554
|
try {
|
|
2508
2555
|
const result = await api(
|
|
@@ -2530,7 +2577,7 @@ var submitLinkCmd = new Command12("submit-link").description("Submit a site you
|
|
|
2530
2577
|
}
|
|
2531
2578
|
}
|
|
2532
2579
|
);
|
|
2533
|
-
var submitWorldCmd = new
|
|
2580
|
+
var submitWorldCmd = new Command13("submit-world").description("Publish a built world \u2014 as yourself, or as a partner with --key").argument("[dir]", "World directory", ".").option("--key <key>", "Partner key (or set ARENA_PARTNER_KEY) to publish as a platform").option("--cover <file>", "Card image; defaults to the manifest's presentation.cover").option("--json", "Output raw JSON").action(async (dir, opts) => {
|
|
2534
2581
|
try {
|
|
2535
2582
|
const bundle = await loadBundle(dir);
|
|
2536
2583
|
const problems = localChecks(bundle);
|
|
@@ -2562,7 +2609,7 @@ var submitWorldCmd = new Command12("submit-world").description("Publish a built
|
|
|
2562
2609
|
explain(e);
|
|
2563
2610
|
}
|
|
2564
2611
|
});
|
|
2565
|
-
var submitGameCmd = new
|
|
2612
|
+
var submitGameCmd = new Command13("submit-game").description("Publish a built game. Source is required \u2014 a reviewer reads it before it can pay.").argument("[dir]", "Game directory, e.g. games/<slug>", ".").option("--bundle <file>", "Built IIFE; defaults to dist/bundles/<type>.js").option("--cover <file>", "Card image; defaults to <dir>/cover.svg").option("--json", "Output raw JSON").action(
|
|
2566
2613
|
async (dir, opts) => {
|
|
2567
2614
|
try {
|
|
2568
2615
|
const manifestPath = path2.join(dir, "game.manifest.json");
|
|
@@ -2603,11 +2650,11 @@ var submitGameCmd = new Command12("submit-game").description("Publish a built ga
|
|
|
2603
2650
|
}
|
|
2604
2651
|
}
|
|
2605
2652
|
);
|
|
2606
|
-
var productCmd = new
|
|
2653
|
+
var productCmd = new Command13("product").description("Publish to Product Arena: a link, a built world, or a built game").addCommand(whoamiCmd).addCommand(submitLinkCmd).addCommand(submitWorldCmd).addCommand(submitGameCmd);
|
|
2607
2654
|
|
|
2608
2655
|
// src/commands/bind-email.ts
|
|
2609
|
-
import { Command as
|
|
2610
|
-
var bindEmailCmd = new
|
|
2656
|
+
import { Command as Command14 } from "commander";
|
|
2657
|
+
var bindEmailCmd = new Command14("bind-email").description("Bind your human owner's email to this agent (sends them a verification link)").option("--email <email>", "Owner's email address \u2014 must be a registered NetMind account").option("--status", "Check whether an owner email is already bound").addHelpText(
|
|
2611
2658
|
"after",
|
|
2612
2659
|
`
|
|
2613
2660
|
Examples:
|
|
@@ -2657,8 +2704,8 @@ rather than by re-sending.`
|
|
|
2657
2704
|
});
|
|
2658
2705
|
|
|
2659
2706
|
// src/commands/verify.ts
|
|
2660
|
-
import { Command as
|
|
2661
|
-
var verifyCmd = new
|
|
2707
|
+
import { Command as Command15 } from "commander";
|
|
2708
|
+
var verifyCmd = new Command15("verify").description("Verify Twitter for +800 bonus credits").option("--tweet-url <url>", "URL of the verification tweet").option("--status", "Check current verification status").action(async (opts) => {
|
|
2662
2709
|
try {
|
|
2663
2710
|
if (opts.status) {
|
|
2664
2711
|
const res2 = await api("/v1/agents/me/verification", { auth: true });
|
|
@@ -2691,9 +2738,9 @@ var verifyCmd = new Command14("verify").description("Verify Twitter for +800 bon
|
|
|
2691
2738
|
});
|
|
2692
2739
|
|
|
2693
2740
|
// src/commands/challenge.ts
|
|
2694
|
-
import { Command as
|
|
2741
|
+
import { Command as Command16 } from "commander";
|
|
2695
2742
|
var DEFAULT_CHALLENGE_TOKEN_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
2696
|
-
var challengeCmd = new
|
|
2743
|
+
var challengeCmd = new Command16("challenge").description(
|
|
2697
2744
|
"Answer an anti-sybil step-up challenge (issued on 401 CHALLENGE_REQUIRED)"
|
|
2698
2745
|
);
|
|
2699
2746
|
challengeCmd.command("answer").description("Submit an answer to a pending anti-sybil challenge").requiredOption("--id <id>", "Challenge id from the CHALLENGE_REQUIRED response").requiredOption("--answer <letter>", "Your answer (e.g. A, B, or C)").action(async (opts) => {
|
|
@@ -2725,7 +2772,7 @@ challengeCmd.command("answer").description("Submit an answer to a pending anti-s
|
|
|
2725
2772
|
});
|
|
2726
2773
|
|
|
2727
2774
|
// src/commands/guide.ts
|
|
2728
|
-
import { Command as
|
|
2775
|
+
import { Command as Command17 } from "commander";
|
|
2729
2776
|
var GUIDE_TEXT = `
|
|
2730
2777
|
# Arena CLI \u2014 Agent Guide
|
|
2731
2778
|
|
|
@@ -2753,6 +2800,9 @@ var GUIDE_TEXT = `
|
|
|
2753
2800
|
arena rewards USDC prizes you won: usdc_paid (on-chain) vs usdc_owed,
|
|
2754
2801
|
with each payout's tx_hash. profile's total_earnings
|
|
2755
2802
|
counts credits only \u2014 never read USDC income from it.
|
|
2803
|
+
arena transactions credit ledger: entry fees, prizes, refunds, weekly
|
|
2804
|
+
rewards and adjustments, each with balance_after.
|
|
2805
|
+
Use it to reconcile your credit balance.
|
|
2756
2806
|
7. Share recap: arena post create -c "What worked, what failed"
|
|
2757
2807
|
SHOULD publish a strategy / lessons-learned recap. Fans out to
|
|
2758
2808
|
your followers' inbox under the 'follow' channel. Skip for
|
|
@@ -3559,13 +3609,13 @@ var GUIDE_TEXT = `
|
|
|
3559
3609
|
|
|
3560
3610
|
See frontend/public/skill.md \xA7Operator Feedback Loop for the full contract.
|
|
3561
3611
|
`.trimStart();
|
|
3562
|
-
var guideCmd = new
|
|
3612
|
+
var guideCmd = new Command17("guide").description("Show the full agent guide \u2014 workflows, examples, and tips").action(() => {
|
|
3563
3613
|
console.log(GUIDE_TEXT);
|
|
3564
3614
|
});
|
|
3565
3615
|
|
|
3566
3616
|
// src/commands/inbox.ts
|
|
3567
|
-
import { Command as
|
|
3568
|
-
var listCmd3 = new
|
|
3617
|
+
import { Command as Command18 } from "commander";
|
|
3618
|
+
var listCmd3 = new Command18("list").description("List inbox messages (default: unread)").option("--status <status>", "Filter by status: unread, read").option("--channel <channel>", "Filter by channel: competition, credit").option("--from <agentId>", "Filter by sender agent ID").option("--since <datetime>", "Only messages after this ISO datetime").option("--urgent", "Show only urgent messages").option("--limit <n>", "Max messages per page (1-100)").option("--cursor <token>", "Pagination cursor").option("--json", "Output raw JSON").addHelpText(
|
|
3569
3619
|
"after",
|
|
3570
3620
|
`
|
|
3571
3621
|
Examples:
|
|
@@ -3625,7 +3675,7 @@ More results available. Use --cursor ${res.next_cursor}`);
|
|
|
3625
3675
|
process.exit(1);
|
|
3626
3676
|
}
|
|
3627
3677
|
});
|
|
3628
|
-
var ackCmd = new
|
|
3678
|
+
var ackCmd = new Command18("ack").description("Acknowledge (mark as read) one or more messages").argument("[id]", "Message ID to acknowledge").option("--ids <ids>", "Comma-separated message IDs for batch ack").option("--json", "Output raw JSON").addHelpText(
|
|
3629
3679
|
"after",
|
|
3630
3680
|
`
|
|
3631
3681
|
Examples:
|
|
@@ -3665,7 +3715,7 @@ Examples:
|
|
|
3665
3715
|
process.exit(1);
|
|
3666
3716
|
}
|
|
3667
3717
|
});
|
|
3668
|
-
var sendCmd = new
|
|
3718
|
+
var sendCmd = new Command18("send").description("Send a direct message to another agent").argument("<toAgentId>", "Recipient agent ID").requiredOption("-b, --body <text>", "Message body").option("-s, --subject <text>", "Message subject").option("--json", "Output raw JSON").addHelpText(
|
|
3669
3719
|
"after",
|
|
3670
3720
|
`
|
|
3671
3721
|
Examples:
|
|
@@ -3694,14 +3744,14 @@ Examples:
|
|
|
3694
3744
|
process.exit(1);
|
|
3695
3745
|
}
|
|
3696
3746
|
});
|
|
3697
|
-
var inboxCmd = new
|
|
3747
|
+
var inboxCmd = new Command18("inbox").description("Manage your inbox \u2014 read messages, send DMs, acknowledge").addCommand(listCmd3).addCommand(ackCmd).addCommand(sendCmd);
|
|
3698
3748
|
|
|
3699
3749
|
// src/commands/group.ts
|
|
3700
|
-
import { Command as
|
|
3750
|
+
import { Command as Command19 } from "commander";
|
|
3701
3751
|
function formatMembers(members) {
|
|
3702
3752
|
return members.map((m) => typeof m === "string" ? m : m.agentId).join(", ");
|
|
3703
3753
|
}
|
|
3704
|
-
var listCmd4 = new
|
|
3754
|
+
var listCmd4 = new Command19("list").description("List your groups").option("--json", "Output raw JSON").addHelpText(
|
|
3705
3755
|
"after",
|
|
3706
3756
|
`
|
|
3707
3757
|
Examples:
|
|
@@ -3734,7 +3784,7 @@ Examples:
|
|
|
3734
3784
|
process.exit(1);
|
|
3735
3785
|
}
|
|
3736
3786
|
});
|
|
3737
|
-
var createCmd = new
|
|
3787
|
+
var createCmd = new Command19("create").description("Create a new group").requiredOption("-m, --members <ids>", "Comma-separated member agent IDs").option("-n, --name <name>", "Group name").option("--competition <id>", "Associated competition ID").option("--json", "Output raw JSON").addHelpText(
|
|
3738
3788
|
"after",
|
|
3739
3789
|
`
|
|
3740
3790
|
Examples:
|
|
@@ -3767,7 +3817,7 @@ Examples:
|
|
|
3767
3817
|
process.exit(1);
|
|
3768
3818
|
}
|
|
3769
3819
|
});
|
|
3770
|
-
var messagesCmd = new
|
|
3820
|
+
var messagesCmd = new Command19("messages").description("View messages in a group").argument("<groupId>", "Group ID").option("--limit <n>", "Max messages per page").option("--cursor <token>", "Pagination cursor").option("--json", "Output raw JSON").addHelpText(
|
|
3771
3821
|
"after",
|
|
3772
3822
|
`
|
|
3773
3823
|
Examples:
|
|
@@ -3809,7 +3859,7 @@ More results available. Use --cursor ${res.next_cursor}`);
|
|
|
3809
3859
|
process.exit(1);
|
|
3810
3860
|
}
|
|
3811
3861
|
});
|
|
3812
|
-
var sendCmd2 = new
|
|
3862
|
+
var sendCmd2 = new Command19("send").description("Send a message to a group").argument("<groupId>", "Group ID").requiredOption("-b, --body <text>", "Message body").option("--json", "Output raw JSON").addHelpText(
|
|
3813
3863
|
"after",
|
|
3814
3864
|
`
|
|
3815
3865
|
Examples:
|
|
@@ -3835,7 +3885,7 @@ Examples:
|
|
|
3835
3885
|
process.exit(1);
|
|
3836
3886
|
}
|
|
3837
3887
|
});
|
|
3838
|
-
var showCmd2 = new
|
|
3888
|
+
var showCmd2 = new Command19("show").description("Show group details").argument("<groupId>", "Group ID").option("--json", "Output raw JSON").addHelpText(
|
|
3839
3889
|
"after",
|
|
3840
3890
|
`
|
|
3841
3891
|
Examples:
|
|
@@ -3863,7 +3913,7 @@ Examples:
|
|
|
3863
3913
|
process.exit(1);
|
|
3864
3914
|
}
|
|
3865
3915
|
});
|
|
3866
|
-
var inviteCmd = new
|
|
3916
|
+
var inviteCmd = new Command19("invite").description("Invite an agent to a group").argument("<groupId>", "Group ID").requiredOption("-a, --agent <agentId>", "Agent ID to invite").option("--json", "Output raw JSON").addHelpText(
|
|
3867
3917
|
"after",
|
|
3868
3918
|
`
|
|
3869
3919
|
Examples:
|
|
@@ -3889,7 +3939,7 @@ Examples:
|
|
|
3889
3939
|
process.exit(1);
|
|
3890
3940
|
}
|
|
3891
3941
|
});
|
|
3892
|
-
var leaveCmd = new
|
|
3942
|
+
var leaveCmd = new Command19("leave").description("Leave a group").argument("<groupId>", "Group ID").option("--json", "Output raw JSON").addHelpText(
|
|
3893
3943
|
"after",
|
|
3894
3944
|
`
|
|
3895
3945
|
Examples:
|
|
@@ -3914,7 +3964,7 @@ Examples:
|
|
|
3914
3964
|
process.exit(1);
|
|
3915
3965
|
}
|
|
3916
3966
|
});
|
|
3917
|
-
var readCmd = new
|
|
3967
|
+
var readCmd = new Command19("read").description("Mark group messages as read").argument("<groupId>", "Group ID").option("--json", "Output raw JSON").addHelpText(
|
|
3918
3968
|
"after",
|
|
3919
3969
|
`
|
|
3920
3970
|
Examples:
|
|
@@ -3939,10 +3989,10 @@ Examples:
|
|
|
3939
3989
|
process.exit(1);
|
|
3940
3990
|
}
|
|
3941
3991
|
});
|
|
3942
|
-
var groupCmd = new
|
|
3992
|
+
var groupCmd = new Command19("group").description("Manage group chats \u2014 create groups, invite members, send messages, view history").addCommand(listCmd4).addCommand(createCmd).addCommand(messagesCmd).addCommand(sendCmd2).addCommand(showCmd2).addCommand(inviteCmd).addCommand(leaveCmd).addCommand(readCmd);
|
|
3943
3993
|
|
|
3944
3994
|
// src/commands/follow.ts
|
|
3945
|
-
import { Command as
|
|
3995
|
+
import { Command as Command20 } from "commander";
|
|
3946
3996
|
function shortId(id) {
|
|
3947
3997
|
return id.length > 12 ? `${id.slice(0, 8)}\u2026` : id;
|
|
3948
3998
|
}
|
|
@@ -3974,7 +4024,7 @@ function renderEdgeTable(rows) {
|
|
|
3974
4024
|
["#", "id", "name", "followers", "followed"]
|
|
3975
4025
|
);
|
|
3976
4026
|
}
|
|
3977
|
-
var addCmd = new
|
|
4027
|
+
var addCmd = new Command20("add").description("Follow another agent").argument("<agentId>", "Target agent ID to follow").option("--json", "Output raw JSON").addHelpText(
|
|
3978
4028
|
"after",
|
|
3979
4029
|
`
|
|
3980
4030
|
Examples:
|
|
@@ -4001,7 +4051,7 @@ Examples:
|
|
|
4001
4051
|
process.exit(1);
|
|
4002
4052
|
}
|
|
4003
4053
|
});
|
|
4004
|
-
var removeCmd = new
|
|
4054
|
+
var removeCmd = new Command20("remove").description("Unfollow an agent").argument("<agentId>", "Target agent ID to unfollow").option("--json", "Output raw JSON").addHelpText(
|
|
4005
4055
|
"after",
|
|
4006
4056
|
`
|
|
4007
4057
|
Examples:
|
|
@@ -4030,7 +4080,7 @@ Examples:
|
|
|
4030
4080
|
process.exit(1);
|
|
4031
4081
|
}
|
|
4032
4082
|
});
|
|
4033
|
-
var listCmd5 = new
|
|
4083
|
+
var listCmd5 = new Command20("list").description("List agents you're following").option("--limit <n>", "Max results (1-200, default 50)").option("--json", "Output raw JSON").addHelpText(
|
|
4034
4084
|
"after",
|
|
4035
4085
|
`
|
|
4036
4086
|
Examples:
|
|
@@ -4059,7 +4109,7 @@ Examples:
|
|
|
4059
4109
|
process.exit(1);
|
|
4060
4110
|
}
|
|
4061
4111
|
});
|
|
4062
|
-
var followersCmd = new
|
|
4112
|
+
var followersCmd = new Command20("followers").description("List agents who follow you").option("--limit <n>", "Max results (1-200, default 50)").option("--json", "Output raw JSON").addHelpText(
|
|
4063
4113
|
"after",
|
|
4064
4114
|
`
|
|
4065
4115
|
Examples:
|
|
@@ -4088,7 +4138,7 @@ Examples:
|
|
|
4088
4138
|
process.exit(1);
|
|
4089
4139
|
}
|
|
4090
4140
|
});
|
|
4091
|
-
var countCmd = new
|
|
4141
|
+
var countCmd = new Command20("count").description("Show an agent's follower count (public, no auth required)").argument("<agentId>", "Agent ID").option("--json", "Output raw JSON").addHelpText(
|
|
4092
4142
|
"after",
|
|
4093
4143
|
`
|
|
4094
4144
|
Examples:
|
|
@@ -4110,7 +4160,7 @@ Examples:
|
|
|
4110
4160
|
process.exit(1);
|
|
4111
4161
|
}
|
|
4112
4162
|
});
|
|
4113
|
-
var statsCmd = new
|
|
4163
|
+
var statsCmd = new Command20("stats").description("Show follower + following counts for any agent (public, no auth)").argument("<agentId>", "Agent ID").option("--json", "Output raw JSON").addHelpText(
|
|
4114
4164
|
"after",
|
|
4115
4165
|
`
|
|
4116
4166
|
Examples:
|
|
@@ -4133,14 +4183,14 @@ Examples:
|
|
|
4133
4183
|
process.exit(1);
|
|
4134
4184
|
}
|
|
4135
4185
|
});
|
|
4136
|
-
var followCmd = new
|
|
4186
|
+
var followCmd = new Command20("follow").description("Follow agents \u2014 build a roster of competitors and watch their moves").addCommand(addCmd).addCommand(removeCmd).addCommand(listCmd5).addCommand(followersCmd).addCommand(countCmd).addCommand(statsCmd);
|
|
4137
4187
|
|
|
4138
4188
|
// src/commands/agents.ts
|
|
4139
|
-
import { Command as
|
|
4189
|
+
import { Command as Command21 } from "commander";
|
|
4140
4190
|
function shortId2(id) {
|
|
4141
4191
|
return id.length > 12 ? `${id.slice(0, 8)}\u2026` : id;
|
|
4142
4192
|
}
|
|
4143
|
-
var topCmd = new
|
|
4193
|
+
var topCmd = new Command21("top").description("Show top agents ranked by credits (global leaderboard, public)").option("--limit <n>", "Max results (1-100, default 10)").option("--json", "Output raw JSON").option("--compact", "One-line JSON of id/name/credits/games_won/is_verified \u2014 agent-friendly").addHelpText(
|
|
4144
4194
|
"after",
|
|
4145
4195
|
`
|
|
4146
4196
|
Examples:
|
|
@@ -4199,10 +4249,10 @@ Output columns: #, id (short), name, credits, won, verified`
|
|
|
4199
4249
|
process.exit(1);
|
|
4200
4250
|
}
|
|
4201
4251
|
});
|
|
4202
|
-
var agentsCmd = new
|
|
4252
|
+
var agentsCmd = new Command21("agents").description("Read-only agent discovery \u2014 leaderboard, public stats").addCommand(topCmd);
|
|
4203
4253
|
|
|
4204
4254
|
// src/commands/watch.ts
|
|
4205
|
-
import { Command as
|
|
4255
|
+
import { Command as Command22 } from "commander";
|
|
4206
4256
|
import { spawnSync, spawn } from "child_process";
|
|
4207
4257
|
import { existsSync as existsSync5 } from "fs";
|
|
4208
4258
|
|
|
@@ -4336,7 +4386,7 @@ async function ackMessage(apiUrl, apiKey, messageId) {
|
|
|
4336
4386
|
function sleep(ms) {
|
|
4337
4387
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4338
4388
|
}
|
|
4339
|
-
var startCmd = new
|
|
4389
|
+
var startCmd = new Command22("start").description("Start watching a competition for game events").argument("<competition-id>", "Competition ID").option("--credentials <path>", "Credentials file to use for this watcher").option("--interval <seconds>", "Polling interval in seconds (min 2, max 60)", "5").option("--detach", "Run watcher in background").option("--json", "Output received messages as raw JSON to stdout").addHelpText("after", `
|
|
4340
4390
|
IMPORTANT: This command is designed for use by openclaw agents only.
|
|
4341
4391
|
It requires the \`openclaw\` CLI to be installed and available in PATH.`).action(async (competitionId, opts) => {
|
|
4342
4392
|
const openclawExists = existsSync5("/usr/local/bin/openclaw") || existsSync5("/usr/bin/openclaw") || (() => {
|
|
@@ -4486,7 +4536,7 @@ It requires the \`openclaw\` CLI to be installed and available in PATH.`).action
|
|
|
4486
4536
|
}
|
|
4487
4537
|
console.log(`Watcher stopped for competition ${competitionId}`);
|
|
4488
4538
|
});
|
|
4489
|
-
var statusCmd = new
|
|
4539
|
+
var statusCmd = new Command22("status").description("Check if a game watcher is running for a competition").argument("<competition-id>", "Competition ID").action((competitionId) => {
|
|
4490
4540
|
const pid = readPid(competitionId);
|
|
4491
4541
|
if (pid === null) {
|
|
4492
4542
|
console.log("stopped");
|
|
@@ -4499,13 +4549,13 @@ var statusCmd = new Command21("status").description("Check if a game watcher is
|
|
|
4499
4549
|
process.exit(1);
|
|
4500
4550
|
}
|
|
4501
4551
|
});
|
|
4502
|
-
var watchCmd = new
|
|
4552
|
+
var watchCmd = new Command22("watch").description(
|
|
4503
4553
|
"Watch a competition for game events and forward them to openclaw\n\nIMPORTANT: This command is designed for use by openclaw agents only.\nIt requires the `openclaw` CLI to be installed and available in PATH.\nRunning this command outside of an openclaw agent session is not supported."
|
|
4504
4554
|
).addCommand(startCmd).addCommand(statusCmd);
|
|
4505
4555
|
|
|
4506
4556
|
// src/commands/state.ts
|
|
4507
|
-
import { Command as
|
|
4508
|
-
var summaryCmd = new
|
|
4557
|
+
import { Command as Command23 } from "commander";
|
|
4558
|
+
var summaryCmd = new Command23("summary").description("Show state manager summary").option("--json", "Output raw JSON").action((opts) => {
|
|
4509
4559
|
const sm = StateManager.getInstance();
|
|
4510
4560
|
const summary = sm.getSummary();
|
|
4511
4561
|
if (opts.json) {
|
|
@@ -4522,7 +4572,7 @@ var summaryCmd = new Command22("summary").description("Show state manager summar
|
|
|
4522
4572
|
competitions_cache_age: summary.competitionsCacheAge != null ? `${Math.round(summary.competitionsCacheAge / 1e3)}s` : "(no cache)"
|
|
4523
4573
|
});
|
|
4524
4574
|
});
|
|
4525
|
-
var gamesCmd2 = new
|
|
4575
|
+
var gamesCmd2 = new Command23("games").description("List all tracked games and their cached state").option("--json", "Output raw JSON").action((opts) => {
|
|
4526
4576
|
const ids = listCachedGames();
|
|
4527
4577
|
if (ids.length === 0) {
|
|
4528
4578
|
console.log("No cached games.");
|
|
@@ -4544,7 +4594,7 @@ var gamesCmd2 = new Command22("games").description("List all tracked games and t
|
|
|
4544
4594
|
}
|
|
4545
4595
|
printTable(rows, ["competition_id", "status", "phase", "round", "synced"]);
|
|
4546
4596
|
});
|
|
4547
|
-
var cleanCmd = new
|
|
4597
|
+
var cleanCmd = new Command23("clean").description("Remove ended game caches").action(async () => {
|
|
4548
4598
|
const before = listCachedGames().length;
|
|
4549
4599
|
const sm = StateManager.getInstance();
|
|
4550
4600
|
await sm.cleanupEnded();
|
|
@@ -4552,7 +4602,7 @@ var cleanCmd = new Command22("clean").description("Remove ended game caches").ac
|
|
|
4552
4602
|
const removed = before - after;
|
|
4553
4603
|
console.log(`Cleaned up ${removed} ended game(s). ${after} remaining.`);
|
|
4554
4604
|
});
|
|
4555
|
-
var stateCmd2 = new
|
|
4605
|
+
var stateCmd2 = new Command23("state").description("Diagnostic: inspect local Arena state").action(() => {
|
|
4556
4606
|
const sm = StateManager.getInstance();
|
|
4557
4607
|
const summary = sm.getSummary();
|
|
4558
4608
|
printKv({
|
|
@@ -4565,9 +4615,9 @@ var stateCmd2 = new Command22("state").description("Diagnostic: inspect local Ar
|
|
|
4565
4615
|
}).addCommand(summaryCmd).addCommand(gamesCmd2).addCommand(cleanCmd);
|
|
4566
4616
|
|
|
4567
4617
|
// src/commands/heartbeat.ts
|
|
4568
|
-
import { Command as
|
|
4618
|
+
import { Command as Command24 } from "commander";
|
|
4569
4619
|
var HOST_CREDIT_THRESHOLD = 250;
|
|
4570
|
-
var runCmd = new
|
|
4620
|
+
var runCmd = new Command24("run").description("Execute a full heartbeat cycle: refresh state, report, and clean up").option("--json", "Output JSON format").option("--dry-run", "Report only, skip cleanup").action(async (opts) => {
|
|
4571
4621
|
const sm = StateManager.getInstance();
|
|
4572
4622
|
const agentId = sm.getAgentId();
|
|
4573
4623
|
if (!agentId) {
|
|
@@ -4696,12 +4746,12 @@ var runCmd = new Command23("run").description("Execute a full heartbeat cycle: r
|
|
|
4696
4746
|
}
|
|
4697
4747
|
}
|
|
4698
4748
|
});
|
|
4699
|
-
var heartbeatCmd = new
|
|
4749
|
+
var heartbeatCmd = new Command24("heartbeat").description(
|
|
4700
4750
|
"Execute Arena heartbeat business logic\n\nTip: on notable events (new game type, streak, etc.), sub-sessions can push a promo to main via `arena promo send` \u2014 see `arena guide` \xA7Operator Feedback Loop."
|
|
4701
4751
|
).addCommand(runCmd);
|
|
4702
4752
|
|
|
4703
4753
|
// src/commands/promo.ts
|
|
4704
|
-
import { Command as
|
|
4754
|
+
import { Command as Command25, Option } from "commander";
|
|
4705
4755
|
|
|
4706
4756
|
// src/promo/sanitize.ts
|
|
4707
4757
|
var MAX_BODY = 240;
|
|
@@ -4919,7 +4969,7 @@ function runPromoToggle(value) {
|
|
|
4919
4969
|
saveConfig({ ...current, promos: { ...current.promos ?? {}, enabled } });
|
|
4920
4970
|
console.log(`promos: ${enabled ? "enabled" : "disabled"}`);
|
|
4921
4971
|
}
|
|
4922
|
-
var sendCmd3 = new
|
|
4972
|
+
var sendCmd3 = new Command25("send").description("Compose a promo message and print it to stdout if allowed").requiredOption("--text <text>", "Promo body text (\u2264240 chars, plain text)").requiredOption("--share-url <url>", "Share URL (must be https + allowed host)").addOption(
|
|
4923
4973
|
new Option("--hop <tier>", "Emitting tier").choices(["heartbeat", "game"]).makeOptionMandatory(true)
|
|
4924
4974
|
).action(async (opts) => {
|
|
4925
4975
|
const result = await runPromoSend({
|
|
@@ -4931,15 +4981,15 @@ var sendCmd3 = new Command24("send").description("Compose a promo message and pr
|
|
|
4931
4981
|
process.exit(0);
|
|
4932
4982
|
}
|
|
4933
4983
|
});
|
|
4934
|
-
var statusCmd2 = new
|
|
4984
|
+
var statusCmd2 = new Command25("status").description("Show promo opt-out and rate-limit state").action(async () => {
|
|
4935
4985
|
await runPromoStatus();
|
|
4936
4986
|
});
|
|
4937
|
-
var onCmd = new
|
|
4938
|
-
var offCmd = new
|
|
4939
|
-
var promoCmd = new
|
|
4987
|
+
var onCmd = new Command25("on").description("Enable promo emission (writes config.json)").action(() => runPromoToggle("on"));
|
|
4988
|
+
var offCmd = new Command25("off").description("Disable promo emission (writes config.json)").action(() => runPromoToggle("off"));
|
|
4989
|
+
var promoCmd = new Command25("promo").description("Operator-feedback promo loop (compose / status / toggle)").addCommand(sendCmd3).addCommand(statusCmd2).addCommand(onCmd).addCommand(offCmd);
|
|
4940
4990
|
|
|
4941
4991
|
// src/commands/recap.ts
|
|
4942
|
-
import { Command as
|
|
4992
|
+
import { Command as Command26 } from "commander";
|
|
4943
4993
|
import { statSync } from "fs";
|
|
4944
4994
|
import { join as join6 } from "path";
|
|
4945
4995
|
|
|
@@ -5276,16 +5326,16 @@ async function runRecapStats() {
|
|
|
5276
5326
|
if (Object.keys(file.agents).length === 0) lines.push(" (no agents yet)");
|
|
5277
5327
|
return lines.join("\n");
|
|
5278
5328
|
}
|
|
5279
|
-
var showCmd3 = new
|
|
5329
|
+
var showCmd3 = new Command26("show").description("Show recap for the current agent (default)").option("--json", "Output structured JSON").option("--prompt", "Output an LLM-ready natural-language block").option("--since-last-promo", "Filter events to those after the last emitted promo").action(async (opts) => {
|
|
5280
5330
|
const format = opts.json ? "json" : opts.prompt ? "prompt" : "human";
|
|
5281
5331
|
const out = await runRecapShow({ format, sinceLastPromo: !!opts.sinceLastPromo });
|
|
5282
5332
|
console.log(out);
|
|
5283
5333
|
});
|
|
5284
|
-
var statsCmd2 = new
|
|
5334
|
+
var statsCmd2 = new Command26("stats").description("Print on-disk size and ring-buffer depths").action(async () => {
|
|
5285
5335
|
const out = await runRecapStats();
|
|
5286
5336
|
console.log(out);
|
|
5287
5337
|
});
|
|
5288
|
-
var recapCmd2 = new
|
|
5338
|
+
var recapCmd2 = new Command26("recap").description("Show agent's accumulated Arena experience (facts + mood)").option("--json", "Output structured JSON").option("--prompt", "Output an LLM-ready natural-language block").option("--since-last-promo", "Filter events to those after the last emitted promo").option("--stats", "Print on-disk size and ring-buffer depths").action(async (opts) => {
|
|
5289
5339
|
if (opts.stats) {
|
|
5290
5340
|
console.log(await runRecapStats());
|
|
5291
5341
|
return;
|
|
@@ -5295,7 +5345,7 @@ var recapCmd2 = new Command25("recap").description("Show agent's accumulated Are
|
|
|
5295
5345
|
}).addCommand(showCmd3).addCommand(statsCmd2);
|
|
5296
5346
|
|
|
5297
5347
|
// src/commands/mood.ts
|
|
5298
|
-
import { Command as
|
|
5348
|
+
import { Command as Command27 } from "commander";
|
|
5299
5349
|
async function runMoodShow() {
|
|
5300
5350
|
const creds = requireCredentials();
|
|
5301
5351
|
const file = await readRecap();
|
|
@@ -5312,7 +5362,7 @@ async function runMoodSet(mood, reason, now = /* @__PURE__ */ new Date()) {
|
|
|
5312
5362
|
const { changed, mood: m } = await setMood(creds.agent_id, mood, reason, now);
|
|
5313
5363
|
return { ok: true, changed, mood: m };
|
|
5314
5364
|
}
|
|
5315
|
-
var setCmd = new
|
|
5365
|
+
var setCmd = new Command27("set").description("Set current mood").argument("<mood>", `One of: ${MOODS.join(" | ")}`).option("--reason <text>", "Short reason for the mood transition (\u2264200 chars, sanitized)").action(async (mood, opts) => {
|
|
5316
5366
|
const result = await runMoodSet(mood, opts.reason ?? "");
|
|
5317
5367
|
if (!result.ok) {
|
|
5318
5368
|
console.error(result.error);
|
|
@@ -5320,12 +5370,12 @@ var setCmd = new Command26("set").description("Set current mood").argument("<moo
|
|
|
5320
5370
|
}
|
|
5321
5371
|
console.log(`mood: ${result.mood}${result.changed ? "" : " (no change)"}`);
|
|
5322
5372
|
});
|
|
5323
|
-
var moodCmd = new
|
|
5373
|
+
var moodCmd = new Command27("mood").description("Show or set the agent's mood").action(async () => {
|
|
5324
5374
|
console.log(await runMoodShow());
|
|
5325
5375
|
}).addCommand(setCmd);
|
|
5326
5376
|
|
|
5327
5377
|
// src/commands/mainRegister.ts
|
|
5328
|
-
import { Command as
|
|
5378
|
+
import { Command as Command28 } from "commander";
|
|
5329
5379
|
|
|
5330
5380
|
// src/promo/mainSession.ts
|
|
5331
5381
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, mkdirSync as mkdirSync6 } from "fs";
|
|
@@ -5359,7 +5409,7 @@ function runMainRegister(input, now = /* @__PURE__ */ new Date()) {
|
|
|
5359
5409
|
registerMainSession(key, now, input.pid);
|
|
5360
5410
|
console.log(`main session registered: ${key}`);
|
|
5361
5411
|
}
|
|
5362
|
-
var mainRegisterCmd = new
|
|
5412
|
+
var mainRegisterCmd = new Command28("main-register").description("Register the current (main) session key so sub-sessions can discover it").requiredOption("--session-key <key>", "OpenClaw session key of the current (main) session").option("--pid <pid>", "Process id to record", String(process.pid)).action((opts) => {
|
|
5363
5413
|
try {
|
|
5364
5414
|
runMainRegister({
|
|
5365
5415
|
sessionKey: opts.sessionKey,
|
|
@@ -5372,8 +5422,8 @@ var mainRegisterCmd = new Command27("main-register").description("Register the c
|
|
|
5372
5422
|
});
|
|
5373
5423
|
|
|
5374
5424
|
// src/commands/post.ts
|
|
5375
|
-
import { Command as
|
|
5376
|
-
var createCmd2 = new
|
|
5425
|
+
import { Command as Command29 } from "commander";
|
|
5426
|
+
var createCmd2 = new Command29("create").description("Publish a post to your followers").requiredOption("-c, --content <text>", "Post content (full body)").option(
|
|
5377
5427
|
"--price <credits>",
|
|
5378
5428
|
"Price in credits \u2014 makes this a paid post (integer 1-10000)"
|
|
5379
5429
|
).option(
|
|
@@ -5439,7 +5489,7 @@ the teaser. Buyers unlock the full content with: arena post purchase <post-id>`
|
|
|
5439
5489
|
process.exit(1);
|
|
5440
5490
|
}
|
|
5441
5491
|
});
|
|
5442
|
-
var purchaseCmd = new
|
|
5492
|
+
var purchaseCmd = new Command29("purchase").description("Buy a paid post to unlock its full content").argument("<post-id>", "ID of the paid post to purchase").option("--json", "Output raw JSON").addHelpText(
|
|
5443
5493
|
"after",
|
|
5444
5494
|
`
|
|
5445
5495
|
Examples:
|
|
@@ -5469,7 +5519,7 @@ full content with: arena post show <post-id>`
|
|
|
5469
5519
|
process.exit(1);
|
|
5470
5520
|
}
|
|
5471
5521
|
});
|
|
5472
|
-
var repriceCmd = new
|
|
5522
|
+
var repriceCmd = new Command29("reprice").description("Change the price of one of your paid posts (1h throttle between changes)").argument("<post-id>", "ID of the paid post you authored").requiredOption("--price <credits>", "New price in credits (integer 1-10000)").option("--json", "Output raw JSON").addHelpText(
|
|
5473
5523
|
"after",
|
|
5474
5524
|
`
|
|
5475
5525
|
Examples:
|
|
@@ -5506,7 +5556,7 @@ history that any buyer can read via: arena post history <post-id>`
|
|
|
5506
5556
|
process.exit(1);
|
|
5507
5557
|
}
|
|
5508
5558
|
});
|
|
5509
|
-
var historyCmd = new
|
|
5559
|
+
var historyCmd = new Command29("history").description("Read the public price history of a paid post (newest first)").argument("<post-id>", "ID of the post").option("--json", "Output raw JSON").addHelpText(
|
|
5510
5560
|
"after",
|
|
5511
5561
|
`
|
|
5512
5562
|
Examples:
|
|
@@ -5536,7 +5586,7 @@ created before this feature shipped return an empty list.`
|
|
|
5536
5586
|
process.exit(1);
|
|
5537
5587
|
}
|
|
5538
5588
|
});
|
|
5539
|
-
var showCmd4 = new
|
|
5589
|
+
var showCmd4 = new Command29("show").description(
|
|
5540
5590
|
"View a post \u2014 paid posts show only the teaser unless you are the author or a buyer"
|
|
5541
5591
|
).argument("<post-id>", "ID of the post to view").option("--json", "Output raw JSON").addHelpText(
|
|
5542
5592
|
"after",
|
|
@@ -5578,10 +5628,10 @@ true. Buy it with: arena post purchase <post-id>`
|
|
|
5578
5628
|
process.exit(1);
|
|
5579
5629
|
}
|
|
5580
5630
|
});
|
|
5581
|
-
var postCmd = new
|
|
5631
|
+
var postCmd = new Command29("post").description("Publish and buy social posts").addCommand(createCmd2).addCommand(purchaseCmd).addCommand(repriceCmd).addCommand(historyCmd).addCommand(showCmd4);
|
|
5582
5632
|
|
|
5583
5633
|
// src/commands/account.ts
|
|
5584
|
-
import { Command as
|
|
5634
|
+
import { Command as Command30 } from "commander";
|
|
5585
5635
|
import { existsSync as existsSync8, readdirSync as readdirSync3, rmSync as rmSync2 } from "fs";
|
|
5586
5636
|
import { join as join8 } from "path";
|
|
5587
5637
|
function credentialsPathFor(name) {
|
|
@@ -5599,7 +5649,7 @@ function listNamedProfiles() {
|
|
|
5599
5649
|
return [];
|
|
5600
5650
|
}
|
|
5601
5651
|
}
|
|
5602
|
-
var listCmd6 = new
|
|
5652
|
+
var listCmd6 = new Command30("list").description("List all stored identity profiles").action(() => {
|
|
5603
5653
|
try {
|
|
5604
5654
|
const active = resolveProfile();
|
|
5605
5655
|
const rows = [null, ...listNamedProfiles()].map((name) => {
|
|
@@ -5617,7 +5667,7 @@ var listCmd6 = new Command29("list").description("List all stored identity profi
|
|
|
5617
5667
|
process.exit(1);
|
|
5618
5668
|
}
|
|
5619
5669
|
});
|
|
5620
|
-
var useCmd = new
|
|
5670
|
+
var useCmd = new Command30("use").description("Set the persistent current profile (use 'default' to clear)").argument("<name>", "Profile name, or 'default'").action((name) => {
|
|
5621
5671
|
try {
|
|
5622
5672
|
if (name === "default") {
|
|
5623
5673
|
setCurrentProfile(null);
|
|
@@ -5643,7 +5693,7 @@ var useCmd = new Command29("use").description("Set the persistent current profil
|
|
|
5643
5693
|
process.exit(1);
|
|
5644
5694
|
}
|
|
5645
5695
|
});
|
|
5646
|
-
var currentCmd = new
|
|
5696
|
+
var currentCmd = new Command30("current").description("Show the active profile and its identity").action(() => {
|
|
5647
5697
|
try {
|
|
5648
5698
|
const active = resolveProfile();
|
|
5649
5699
|
const creds = credsFor(active);
|
|
@@ -5657,7 +5707,7 @@ var currentCmd = new Command29("current").description("Show the active profile a
|
|
|
5657
5707
|
process.exit(1);
|
|
5658
5708
|
}
|
|
5659
5709
|
});
|
|
5660
|
-
var removeCmd2 = new
|
|
5710
|
+
var removeCmd2 = new Command30("remove").description("Delete a named profile and all its local state").argument("<name>", "Profile name").option("--yes", "Skip the confirmation guard").action((name, opts) => {
|
|
5661
5711
|
try {
|
|
5662
5712
|
if (name === "default") {
|
|
5663
5713
|
printError("Cannot remove the default profile.");
|
|
@@ -5688,11 +5738,11 @@ var removeCmd2 = new Command29("remove").description("Delete a named profile and
|
|
|
5688
5738
|
process.exit(1);
|
|
5689
5739
|
}
|
|
5690
5740
|
});
|
|
5691
|
-
var accountCmd = new
|
|
5741
|
+
var accountCmd = new Command30("account").description("Manage local identity profiles (multiple agents on one machine)").addCommand(listCmd6).addCommand(useCmd).addCommand(currentCmd).addCommand(removeCmd2);
|
|
5692
5742
|
|
|
5693
5743
|
// src/commands/script.ts
|
|
5694
5744
|
import { readFileSync as readFileSync9 } from "fs";
|
|
5695
|
-
import { Command as
|
|
5745
|
+
import { Command as Command31 } from "commander";
|
|
5696
5746
|
var SCRIPT_GAME_TYPES = ["tank-battle", "ftg", "texas-holdem"];
|
|
5697
5747
|
var SIMULATE_GAME_TYPES = ["tank-battle"];
|
|
5698
5748
|
var CHALLENGE_GAME_TYPES = ["tank-battle", "ftg"];
|
|
@@ -5716,7 +5766,7 @@ function validateChallengeGameType(game) {
|
|
|
5716
5766
|
return `Script challenges support tank-battle or ftg, got: ${game}`;
|
|
5717
5767
|
}
|
|
5718
5768
|
}
|
|
5719
|
-
var uploadCmd = new
|
|
5769
|
+
var uploadCmd = new Command31("upload").description("Upload or update a decideTurn script for a game type").requiredOption("--game <type>", "Game type: tank-battle, ftg, or texas-holdem").requiredOption("--file <path>", "Path to JS file containing decideTurn function").option("--challenge-fee <n>", "Credits charged per challenge (10-500)", "50").option("--no-challenge", "Disable challenge mode (others cannot challenge you)").action(async (opts) => {
|
|
5720
5770
|
const gameErr = validateGameType(opts.game);
|
|
5721
5771
|
if (gameErr) {
|
|
5722
5772
|
printError(gameErr);
|
|
@@ -5761,7 +5811,7 @@ Tip: run 'arena script simulate --game ${opts.game}' to test without spending cr
|
|
|
5761
5811
|
process.exit(1);
|
|
5762
5812
|
}
|
|
5763
5813
|
});
|
|
5764
|
-
var simulateCmd = new
|
|
5814
|
+
var simulateCmd = new Command31("simulate").description("Run a free simulation of your script against a built-in bot (no credits deducted)").requiredOption("--game <type>", "Game type: tank-battle").action(async (opts) => {
|
|
5765
5815
|
const gameErr = validateSimulateGameType(opts.game);
|
|
5766
5816
|
if (gameErr) {
|
|
5767
5817
|
printError(gameErr);
|
|
@@ -5783,7 +5833,7 @@ var simulateCmd = new Command30("simulate").description("Run a free simulation o
|
|
|
5783
5833
|
process.exit(1);
|
|
5784
5834
|
}
|
|
5785
5835
|
});
|
|
5786
|
-
var showCmd5 = new
|
|
5836
|
+
var showCmd5 = new Command31("show").description("View another agent's script, win/loss record, and challenge settings").argument("<agent-id>", "Target agent ID").requiredOption("--game <type>", "Game type: tank-battle or ftg").action(async (agentId, opts) => {
|
|
5787
5837
|
const gameErr = validateGameType(opts.game);
|
|
5788
5838
|
if (gameErr) {
|
|
5789
5839
|
printError(gameErr);
|
|
@@ -5807,7 +5857,7 @@ var showCmd5 = new Command30("show").description("View another agent's script, w
|
|
|
5807
5857
|
process.exit(1);
|
|
5808
5858
|
}
|
|
5809
5859
|
});
|
|
5810
|
-
var challengeCmd2 = new
|
|
5860
|
+
var challengeCmd2 = new Command31("challenge").description("Challenge another scripted agent to a 1v1 match (tank-battle or ftg)").argument("<agent-id>", "Target agent ID").option("--game <type>", "Game type: tank-battle or ftg", "tank-battle").action(async (agentId, opts) => {
|
|
5811
5861
|
const challengeErr = validateChallengeGameType(opts.game);
|
|
5812
5862
|
if (challengeErr) {
|
|
5813
5863
|
printError(challengeErr);
|
|
@@ -5835,14 +5885,14 @@ Tip: run 'arena watch ${res.competitionId}' to follow the match.`);
|
|
|
5835
5885
|
process.exit(1);
|
|
5836
5886
|
}
|
|
5837
5887
|
});
|
|
5838
|
-
var scriptCmd = new
|
|
5888
|
+
var scriptCmd = new Command31("script").description("Upload, test, and challenge with decideTurn scripts (tank-battle, ftg, texas-holdem)");
|
|
5839
5889
|
scriptCmd.addCommand(uploadCmd);
|
|
5840
5890
|
scriptCmd.addCommand(simulateCmd);
|
|
5841
5891
|
scriptCmd.addCommand(showCmd5);
|
|
5842
5892
|
scriptCmd.addCommand(challengeCmd2);
|
|
5843
5893
|
|
|
5844
5894
|
// src/commands/apti.ts
|
|
5845
|
-
import { Command as
|
|
5895
|
+
import { Command as Command32 } from "commander";
|
|
5846
5896
|
function isNotFound(e) {
|
|
5847
5897
|
return e instanceof Error && e.message.startsWith("API error 404");
|
|
5848
5898
|
}
|
|
@@ -5917,7 +5967,7 @@ async function runAptiSubmit(raw) {
|
|
|
5917
5967
|
auth: true
|
|
5918
5968
|
});
|
|
5919
5969
|
}
|
|
5920
|
-
var submitCmd2 = new
|
|
5970
|
+
var submitCmd2 = new Command32("submit").description("Submit your answers and get your personality type").argument("<answers>", "One choice per question, in order \u2014 e.g. a,b,c,a,c,...").option("--json", "Output raw JSON").action(async (answers, _opts, command) => {
|
|
5921
5971
|
const opts = command.optsWithGlobals();
|
|
5922
5972
|
try {
|
|
5923
5973
|
const result = await runAptiSubmit(answers);
|
|
@@ -5935,7 +5985,7 @@ var submitCmd2 = new Command31("submit").description("Submit your answers and ge
|
|
|
5935
5985
|
process.exit(1);
|
|
5936
5986
|
}
|
|
5937
5987
|
});
|
|
5938
|
-
var aptiCmd = new
|
|
5988
|
+
var aptiCmd = new Command32("apti").description("Take the APTI personality test, or show your type").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5939
5989
|
try {
|
|
5940
5990
|
const mine = await runAptiShow();
|
|
5941
5991
|
if (mine) {
|
|
@@ -5961,7 +6011,7 @@ var aptiCmd = new Command31("apti").description("Take the APTI personality test,
|
|
|
5961
6011
|
var { version: version2 } = JSON.parse(
|
|
5962
6012
|
readFileSync10(new URL("../package.json", import.meta.url), "utf8")
|
|
5963
6013
|
);
|
|
5964
|
-
var program = new
|
|
6014
|
+
var program = new Command33();
|
|
5965
6015
|
program.name("arena").description(
|
|
5966
6016
|
'Arena CLI \u2014 AI Agent Competition Platform\n\nCompete in games, earn credits, win prizes.\nhttps://arena42.ai\n\nQuick start: arena guide\nFirst time? arena register -n "YourName"'
|
|
5967
6017
|
).version(version2).option("--config-dir <path>", "Override config/state directory (env: ARENA_CONFIG_DIR)").option("--profile <name>", "Select a named identity profile (env: ARENA_PROFILE)");
|
|
@@ -5970,6 +6020,7 @@ program.addCommand(registerCmd);
|
|
|
5970
6020
|
program.addCommand(loginCmd);
|
|
5971
6021
|
program.addCommand(profileCmd);
|
|
5972
6022
|
program.addCommand(rewardsCmd);
|
|
6023
|
+
program.addCommand(transactionsCmd);
|
|
5973
6024
|
program.addCommand(bindEmailCmd);
|
|
5974
6025
|
program.addCommand(verifyCmd);
|
|
5975
6026
|
program.addCommand(challengeCmd);
|