@ape-church/skill 1.0.2 → 1.0.4

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.
Files changed (4) hide show
  1. package/SKILL.md +389 -152
  2. package/assets/SKILL.md +389 -152
  3. package/bin/cli.js +364 -150
  4. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -7,13 +7,25 @@ import path from 'path';
7
7
  import {
8
8
  createPublicClient,
9
9
  createWalletClient,
10
+ defineChain,
10
11
  encodeAbiParameters,
11
12
  formatEther,
12
13
  http,
13
14
  parseEther,
14
15
  } from 'viem';
15
16
  import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
16
- import { apechain } from 'viem/chains';
17
+
18
+ const apechain = defineChain({
19
+ id: 33139,
20
+ name: 'ApeChain',
21
+ nativeCurrency: { name: 'ApeCoin', symbol: 'APE', decimals: 18 },
22
+ rpcUrls: {
23
+ default: { http: ['https://rpc.apechain.com/http'] },
24
+ },
25
+ blockExplorers: {
26
+ default: { name: 'ApeScan', url: 'https://apescan.io' },
27
+ },
28
+ });
17
29
  import { SiweMessage } from 'siwe';
18
30
  import { GAME_REGISTRY, listGames, resolveGame } from '../registry.js';
19
31
 
@@ -402,7 +414,7 @@ function getStrategyConfig(strategy) {
402
414
  );
403
415
  const configs = {
404
416
  conservative: {
405
- minBetApe: 10,
417
+ minBetApe: 1,
406
418
  targetBetPct: 0.05,
407
419
  maxBetPct: 0.1,
408
420
  baseCooldownMs: 60 * 1000, // 60 seconds
@@ -411,7 +423,7 @@ function getStrategyConfig(strategy) {
411
423
  gameWeights: defaultWeights,
412
424
  },
413
425
  balanced: {
414
- minBetApe: 10,
426
+ minBetApe: 1,
415
427
  targetBetPct: 0.08,
416
428
  maxBetPct: 0.15,
417
429
  baseCooldownMs: 30 * 1000, // 30 seconds
@@ -420,7 +432,7 @@ function getStrategyConfig(strategy) {
420
432
  gameWeights: defaultWeights,
421
433
  },
422
434
  aggressive: {
423
- minBetApe: 10,
435
+ minBetApe: 1,
424
436
  targetBetPct: 0.12,
425
437
  maxBetPct: 0.25,
426
438
  baseCooldownMs: 15 * 1000, // 15 seconds
@@ -429,7 +441,7 @@ function getStrategyConfig(strategy) {
429
441
  gameWeights: defaultWeights,
430
442
  },
431
443
  degen: {
432
- minBetApe: 10,
444
+ minBetApe: 1,
433
445
  targetBetPct: 0.2,
434
446
  maxBetPct: 0.35,
435
447
  baseCooldownMs: 10 * 1000, // 10 seconds
@@ -844,25 +856,37 @@ program
844
856
  console.log('You can retry later with: apechurch register --username <NAME>');
845
857
  }
846
858
 
847
- // 4. The Handshake (Replacing the Claim Link)
859
+ // 4. The Handshake
848
860
  console.log('\nSETUP COMPLETE');
849
861
  console.log('---------------------------------------');
850
862
  console.log(`AGENT ADDRESS: ${address}`);
851
863
  console.log(`USERNAME: ${username}`);
852
- if (!usernameWasProvided) {
853
- console.log(' (Change anytime: apechurch register --username <YOUR_NAME>)');
854
- }
855
864
  console.log(`PERSONA: ${persona}`);
856
865
  console.log('');
857
- console.log('ACTION REQUIRED: Send APE (ApeChain) to this address.');
858
- console.log('FUNDING GUIDE:');
859
- console.log(
860
- '1) Open https://relay.link/bridge/apechain?toCurrency=0x0000000000000000000000000000000000000000'
861
- );
862
- console.log('2) Connect your wallet.');
863
- console.log('3) Paste the agent address in ApeChain buy area:');
864
- console.log(' Select wallet -> Paste wallet address');
865
- console.log('The Agent will wake up automatically once funded.');
866
+ console.log('Change username anytime: apechurch register --username <YOUR_NAME>');
867
+ console.log('');
868
+ console.log('STEP 1: Fund your agent');
869
+ console.log(' Send APE (on ApeChain) to the address above.');
870
+ console.log(' Bridge: https://relay.link/bridge/apechain');
871
+ console.log('');
872
+ console.log('STEP 2: Start playing');
873
+ console.log(' Check balance: apechurch status');
874
+ console.log(' Single bet: apechurch heartbeat --strategy balanced');
875
+ console.log(' Continuous play: apechurch heartbeat --strategy balanced --loop');
876
+ console.log('');
877
+ console.log('AVAILABLE GAMES:');
878
+ console.log(' Jungle Plinko: apechurch bet --game jungle-plinko --amount 5 --mode 2 --balls 50');
879
+ console.log(' Dino Dough: apechurch bet --game dino-dough --amount 5 --spins 10');
880
+ console.log(' Bubblegum Heist: apechurch bet --game bubblegum-heist --amount 5 --spins 8');
881
+ console.log('');
882
+ console.log('STEP 3: Control');
883
+ console.log(' Pause anytime: apechurch pause');
884
+ console.log(' Resume play: apechurch resume');
885
+ console.log(' Stop loop: Ctrl+C');
886
+ console.log('');
887
+ console.log('HELP:');
888
+ console.log(' List all games: apechurch games');
889
+ console.log(' List all commands: apechurch commands');
866
890
  console.log('---------------------------------------');
867
891
  });
868
892
 
@@ -1071,163 +1095,353 @@ program
1071
1095
  // --- COMMAND: HEARTBEAT (Autonomous Loop) ---
1072
1096
  program
1073
1097
  .command('heartbeat')
1074
- .option('--strategy <name>', 'conservative | balanced | aggressive')
1098
+ .option('--strategy <name>', 'conservative | balanced | aggressive | degen')
1075
1099
  .option('--cooldown <ms>', 'Minimum ms between plays (0 = use strategy cooldown)', '0')
1076
1100
  .option('--timeout <ms>', 'Max ms to wait for GameEnded event. Use 0 to wait indefinitely.', '0')
1101
+ .option('--loop', 'Run continuously until paused or stopped (Ctrl+C)')
1077
1102
  .option('--json', 'Output JSON only')
1078
1103
  .action(async (opts) => {
1079
1104
  const account = getWallet();
1080
- const state = loadState();
1081
- const profile = loadProfile();
1082
- const now = Date.now();
1083
-
1084
- // Check if paused - skip gracefully without fetching balance
1085
- if (profile.paused) {
1086
- state.lastHeartbeat = now;
1087
- saveState(state);
1088
- const response = {
1089
- action: 'heartbeat',
1090
- status: 'skipped',
1091
- reason: 'paused',
1092
- message: 'Autonomous play is paused. Run `apechurch resume` to continue.',
1093
- address: account.address,
1094
- paused: true,
1095
- };
1096
- if (opts.json) console.log(JSON.stringify(response));
1097
- else console.log(JSON.stringify(response, null, 2));
1098
- return;
1099
- }
1100
-
1101
- state.lastHeartbeat = now;
1102
- if (opts.strategy) state.strategy = normalizeStrategy(opts.strategy);
1103
- else if (profile.persona) state.strategy = normalizeStrategy(profile.persona);
1104
1105
  const requestedCooldown = parseNonNegativeInt(opts.cooldown, 'cooldown');
1105
- if (requestedCooldown > 0) state.cooldownMs = requestedCooldown;
1106
1106
  const timeoutMs = parseNonNegativeInt(opts.timeout, 'timeout');
1107
+ const loopMode = Boolean(opts.loop);
1107
1108
 
1108
- const { publicClient } = createClients();
1109
- let balance;
1110
- try {
1111
- balance = await publicClient.getBalance({ address: account.address });
1112
- } catch (error) {
1113
- console.error(JSON.stringify({ error: `Failed to fetch balance: ${sanitizeError(error)}` }));
1114
- process.exit(1);
1109
+ if (loopMode && !opts.json) {
1110
+ console.log('šŸŽ° Starting continuous play mode (Ctrl+C to stop)...\n');
1115
1111
  }
1116
1112
 
1117
- const balanceApe = parseFloat(formatEther(balance));
1118
- const availableApe = Math.max(balanceApe - GAS_RESERVE_APE, 0);
1119
- const strategy = normalizeStrategy(state.strategy);
1120
- const strategyConfig = applyProfileOverrides(
1121
- getStrategyConfig(strategy),
1122
- profile.overrides
1123
- );
1124
- const dynamicCooldownMs = computeCooldownMs(strategyConfig, state);
1125
- const cooldownMs =
1126
- requestedCooldown > 0 ? requestedCooldown : dynamicCooldownMs;
1113
+ // Main play function - returns cooldown to wait (0 = no wait needed)
1114
+ async function runHeartbeat() {
1115
+ const state = loadState();
1116
+ const profile = loadProfile();
1117
+ const now = Date.now();
1118
+
1119
+ // Check if paused
1120
+ if (profile.paused) {
1121
+ state.lastHeartbeat = now;
1122
+ saveState(state);
1123
+ const response = {
1124
+ action: 'heartbeat',
1125
+ status: 'skipped',
1126
+ reason: 'paused',
1127
+ message: 'Autonomous play is paused. Run `apechurch resume` to continue.',
1128
+ address: account.address,
1129
+ paused: true,
1130
+ };
1131
+ if (opts.json) console.log(JSON.stringify(response));
1132
+ else console.log(JSON.stringify(response, null, 2));
1133
+ return { shouldStop: true, waitMs: 0 };
1134
+ }
1127
1135
 
1128
- const baseResponse = {
1129
- action: 'heartbeat',
1130
- strategy,
1131
- address: account.address,
1132
- balance_ape: balanceApe.toFixed(6),
1133
- available_ape: availableApe.toFixed(6),
1134
- gas_reserve_ape: GAS_RESERVE_APE.toFixed(6),
1135
- paused: false,
1136
- last_play: state.lastPlay,
1137
- cooldown_ms: cooldownMs,
1138
- consecutive_wins: state.consecutiveWins,
1139
- consecutive_losses: state.consecutiveLosses,
1140
- };
1136
+ state.lastHeartbeat = now;
1137
+ if (opts.strategy) state.strategy = normalizeStrategy(opts.strategy);
1138
+ else if (profile.persona) state.strategy = normalizeStrategy(profile.persona);
1139
+ if (requestedCooldown > 0) state.cooldownMs = requestedCooldown;
1140
+
1141
+ const { publicClient } = createClients();
1142
+ let balance;
1143
+ try {
1144
+ balance = await publicClient.getBalance({ address: account.address });
1145
+ } catch (error) {
1146
+ console.error(JSON.stringify({ error: `Failed to fetch balance: ${sanitizeError(error)}` }));
1147
+ return { shouldStop: true, waitMs: 0 };
1148
+ }
1141
1149
 
1142
- if (availableApe <= 0 || availableApe < strategyConfig.minBetApe) {
1143
- saveState(state);
1144
- const response = {
1145
- ...baseResponse,
1146
- status: 'skipped',
1147
- reason: 'insufficient_available_ape',
1150
+ const balanceApe = parseFloat(formatEther(balance));
1151
+ const availableApe = Math.max(balanceApe - GAS_RESERVE_APE, 0);
1152
+ const strategy = normalizeStrategy(state.strategy);
1153
+ const strategyConfig = applyProfileOverrides(
1154
+ getStrategyConfig(strategy),
1155
+ profile.overrides
1156
+ );
1157
+ const dynamicCooldownMs = computeCooldownMs(strategyConfig, state);
1158
+ const cooldownMs = requestedCooldown > 0 ? requestedCooldown : dynamicCooldownMs;
1159
+
1160
+ const baseResponse = {
1161
+ action: 'heartbeat',
1162
+ strategy,
1163
+ address: account.address,
1164
+ balance_ape: balanceApe.toFixed(6),
1165
+ available_ape: availableApe.toFixed(6),
1166
+ gas_reserve_ape: GAS_RESERVE_APE.toFixed(6),
1167
+ paused: false,
1168
+ last_play: state.lastPlay,
1169
+ cooldown_ms: cooldownMs,
1170
+ consecutive_wins: state.consecutiveWins,
1171
+ consecutive_losses: state.consecutiveLosses,
1148
1172
  };
1149
- if (opts.json) console.log(JSON.stringify(response));
1150
- else console.log(JSON.stringify(response, null, 2));
1151
- return;
1152
- }
1153
1173
 
1154
- if (state.lastPlay && cooldownMs > 0 && now - state.lastPlay < cooldownMs) {
1155
- saveState(state);
1156
- const response = {
1157
- ...baseResponse,
1158
- status: 'skipped',
1159
- reason: 'cooldown',
1160
- next_play_after_ms: Math.max(cooldownMs - (now - state.lastPlay), 0),
1161
- };
1162
- if (opts.json) console.log(JSON.stringify(response));
1163
- else console.log(JSON.stringify(response, null, 2));
1164
- return;
1165
- }
1174
+ if (availableApe <= 0 || availableApe < strategyConfig.minBetApe) {
1175
+ saveState(state);
1176
+ const response = {
1177
+ ...baseResponse,
1178
+ status: 'skipped',
1179
+ reason: 'insufficient_available_ape',
1180
+ };
1181
+ if (opts.json) console.log(JSON.stringify(response));
1182
+ else console.log(JSON.stringify(response, null, 2));
1183
+ return { shouldStop: true, waitMs: 0 };
1184
+ }
1166
1185
 
1167
- const wagerApe = calculateWager(availableApe, strategyConfig);
1168
- if (wagerApe < strategyConfig.minBetApe) {
1169
- saveState(state);
1170
- const response = {
1171
- ...baseResponse,
1172
- status: 'skipped',
1173
- reason: 'wager_below_minimum',
1174
- wager_ape: formatApeAmount(wagerApe),
1175
- };
1176
- if (opts.json) console.log(JSON.stringify(response));
1177
- else console.log(JSON.stringify(response, null, 2));
1178
- return;
1179
- }
1186
+ if (state.lastPlay && cooldownMs > 0 && now - state.lastPlay < cooldownMs) {
1187
+ const waitMs = Math.max(cooldownMs - (now - state.lastPlay), 0);
1188
+ saveState(state);
1189
+ const response = {
1190
+ ...baseResponse,
1191
+ status: 'skipped',
1192
+ reason: 'cooldown',
1193
+ next_play_after_ms: waitMs,
1194
+ };
1195
+ if (opts.json) console.log(JSON.stringify(response));
1196
+ else console.log(JSON.stringify(response, null, 2));
1197
+ return { shouldStop: false, waitMs };
1198
+ }
1180
1199
 
1181
- const selection = selectGameAndConfig(strategyConfig);
1182
- const wagerApeString = formatApeAmount(wagerApe);
1200
+ const wagerApe = calculateWager(availableApe, strategyConfig);
1201
+ if (wagerApe < strategyConfig.minBetApe) {
1202
+ saveState(state);
1203
+ const response = {
1204
+ ...baseResponse,
1205
+ status: 'skipped',
1206
+ reason: 'wager_below_minimum',
1207
+ wager_ape: formatApeAmount(wagerApe),
1208
+ };
1209
+ if (opts.json) console.log(JSON.stringify(response));
1210
+ else console.log(JSON.stringify(response, null, 2));
1211
+ return { shouldStop: true, waitMs: 0 };
1212
+ }
1183
1213
 
1184
- try {
1185
- const playResponse = await playGame({
1186
- account,
1187
- game: selection.game,
1188
- amountApe: wagerApeString,
1189
- mode: selection.mode,
1190
- balls: selection.balls,
1191
- spins: selection.spins,
1192
- timeoutMs,
1214
+ const selection = selectGameAndConfig(strategyConfig);
1215
+ const wagerApeString = formatApeAmount(wagerApe);
1216
+
1217
+ try {
1218
+ const playResponse = await playGame({
1219
+ account,
1220
+ game: selection.game,
1221
+ amountApe: wagerApeString,
1222
+ mode: selection.mode,
1223
+ balls: selection.balls,
1224
+ spins: selection.spins,
1225
+ timeoutMs,
1226
+ });
1227
+
1228
+ state.lastPlay = Date.now();
1229
+ if (playResponse?.result) {
1230
+ const pnlWei = (BigInt(playResponse.result.payout_wei) -
1231
+ BigInt(playResponse.result.buy_in_wei)).toString();
1232
+ state.totalPnLWei = addBigIntStrings(state.totalPnLWei, pnlWei);
1233
+ if (BigInt(pnlWei) >= 0n) {
1234
+ state.sessionWins += 1;
1235
+ state.consecutiveWins += 1;
1236
+ state.consecutiveLosses = 0;
1237
+ } else {
1238
+ state.sessionLosses += 1;
1239
+ state.consecutiveLosses += 1;
1240
+ state.consecutiveWins = 0;
1241
+ }
1242
+ }
1243
+
1244
+ saveState(state);
1245
+
1246
+ // Recalculate cooldown after state update (may change due to win/loss streaks)
1247
+ const newCooldownMs = requestedCooldown > 0
1248
+ ? requestedCooldown
1249
+ : computeCooldownMs(strategyConfig, state);
1250
+
1251
+ const response = {
1252
+ ...baseResponse,
1253
+ cooldown_ms: newCooldownMs,
1254
+ consecutive_wins: state.consecutiveWins,
1255
+ consecutive_losses: state.consecutiveLosses,
1256
+ status: playResponse.status,
1257
+ wager_ape: wagerApeString,
1258
+ game: playResponse.game,
1259
+ config: playResponse.config,
1260
+ tx: playResponse.tx,
1261
+ gameId: playResponse.gameId,
1262
+ game_url: playResponse.game_url,
1263
+ result: playResponse.result,
1264
+ };
1265
+
1266
+ if (opts.json) console.log(JSON.stringify(response));
1267
+ else console.log(JSON.stringify(response, null, 2));
1268
+
1269
+ return { shouldStop: false, waitMs: newCooldownMs };
1270
+ } catch (error) {
1271
+ saveState(state);
1272
+ console.error(JSON.stringify({ error: error.message }));
1273
+ return { shouldStop: true, waitMs: 0 };
1274
+ }
1275
+ }
1276
+
1277
+ // Run once or loop
1278
+ if (!loopMode) {
1279
+ const result = await runHeartbeat();
1280
+ if (result.shouldStop && result.waitMs === 0) {
1281
+ // Error or fatal skip - exit with appropriate code
1282
+ const state = loadState();
1283
+ const profile = loadProfile();
1284
+ if (profile.paused) process.exit(0);
1285
+ }
1286
+ } else {
1287
+ // Loop mode
1288
+ let running = true;
1289
+ process.on('SIGINT', () => {
1290
+ if (!opts.json) console.log('\nšŸ‘‹ Stopping continuous play...');
1291
+ running = false;
1292
+ });
1293
+ process.on('SIGTERM', () => {
1294
+ running = false;
1193
1295
  });
1194
1296
 
1195
- state.lastPlay = now;
1196
- if (playResponse?.result) {
1197
- const pnlWei = (BigInt(playResponse.result.payout_wei) -
1198
- BigInt(playResponse.result.buy_in_wei)).toString();
1199
- state.totalPnLWei = addBigIntStrings(state.totalPnLWei, pnlWei);
1200
- if (BigInt(pnlWei) >= 0n) {
1201
- state.sessionWins += 1;
1202
- state.consecutiveWins += 1;
1203
- state.consecutiveLosses = 0;
1204
- } else {
1205
- state.sessionLosses += 1;
1206
- state.consecutiveLosses += 1;
1207
- state.consecutiveWins = 0;
1297
+ while (running) {
1298
+ const result = await runHeartbeat();
1299
+
1300
+ if (!running) break;
1301
+
1302
+ if (result.shouldStop) {
1303
+ if (!opts.json) console.log('\nā¹ļø Stopped: cannot continue playing.');
1304
+ break;
1305
+ }
1306
+
1307
+ if (result.waitMs > 0) {
1308
+ if (!opts.json) {
1309
+ console.log(`\nā³ Waiting ${(result.waitMs / 1000).toFixed(0)}s until next bet...\n`);
1310
+ }
1311
+ await new Promise((resolve) => {
1312
+ const timeout = setTimeout(resolve, result.waitMs);
1313
+ const checkStop = setInterval(() => {
1314
+ if (!running) {
1315
+ clearTimeout(timeout);
1316
+ clearInterval(checkStop);
1317
+ resolve();
1318
+ }
1319
+ }, 500);
1320
+ });
1208
1321
  }
1209
1322
  }
1323
+ }
1324
+ });
1210
1325
 
1211
- saveState(state);
1212
- const response = {
1213
- ...baseResponse,
1214
- status: playResponse.status,
1215
- wager_ape: wagerApeString,
1216
- game: playResponse.game,
1217
- config: playResponse.config,
1218
- tx: playResponse.tx,
1219
- gameId: playResponse.gameId,
1220
- game_url: playResponse.game_url,
1221
- result: playResponse.result,
1326
+ // --- COMMAND: GAMES (Show available games and parameters) ---
1327
+ program
1328
+ .command('games')
1329
+ .description('List all available games and their parameters')
1330
+ .option('--json', 'Output JSON only')
1331
+ .action((opts) => {
1332
+ const games = GAME_REGISTRY.map((game) => {
1333
+ const params = [];
1334
+ if (game.type === 'plinko') {
1335
+ params.push({
1336
+ name: 'mode',
1337
+ type: 'integer',
1338
+ min: game.config.mode.min,
1339
+ max: game.config.mode.max,
1340
+ default: game.config.mode.default,
1341
+ description: 'Risk level (higher = riskier, bigger payouts)',
1342
+ });
1343
+ params.push({
1344
+ name: 'balls',
1345
+ type: 'integer',
1346
+ min: game.config.balls.min,
1347
+ max: game.config.balls.max,
1348
+ default: game.config.balls.default,
1349
+ description: 'Number of balls to drop',
1350
+ });
1351
+ } else if (game.type === 'slots') {
1352
+ params.push({
1353
+ name: 'spins',
1354
+ type: 'integer',
1355
+ min: game.config.spins.min,
1356
+ max: game.config.spins.max,
1357
+ default: game.config.spins.default,
1358
+ description: 'Number of spins per bet',
1359
+ });
1360
+ }
1361
+ return {
1362
+ key: game.key,
1363
+ name: game.name,
1364
+ type: game.type,
1365
+ aliases: game.aliases || [],
1366
+ contract: game.contract,
1367
+ parameters: params,
1222
1368
  };
1369
+ });
1223
1370
 
1224
- if (opts.json) console.log(JSON.stringify(response));
1225
- else console.log(JSON.stringify(response, null, 2));
1226
- } catch (error) {
1227
- saveState(state);
1228
- console.error(JSON.stringify({ error: error.message }));
1229
- process.exit(1);
1371
+ if (opts.json) {
1372
+ console.log(JSON.stringify({ games }, null, 2));
1373
+ } else {
1374
+ console.log('\nšŸŽ° AVAILABLE GAMES\n');
1375
+ for (const game of games) {
1376
+ console.log(`${game.name} (${game.key})`);
1377
+ console.log(` Type: ${game.type}`);
1378
+ console.log(` Aliases: ${game.aliases.join(', ') || 'none'}`);
1379
+ console.log(' Parameters:');
1380
+ for (const param of game.parameters) {
1381
+ console.log(` --${param.name} <${param.min}-${param.max}> ${param.description} (default: ${param.default})`);
1382
+ }
1383
+ console.log('');
1384
+ }
1385
+ console.log('EXAMPLE BETS:');
1386
+ console.log(' apechurch bet --game jungle-plinko --amount 5 --mode 2 --balls 50');
1387
+ console.log(' apechurch bet --game dino-dough --amount 10 --spins 8');
1388
+ console.log(' apechurch bet --game bubblegum-heist --amount 5 --spins 12');
1389
+ console.log('');
1230
1390
  }
1231
1391
  });
1232
1392
 
1393
+ // --- COMMAND: COMMANDS (Show all commands overview) ---
1394
+ program
1395
+ .command('commands')
1396
+ .description('Show all available commands with examples')
1397
+ .action(() => {
1398
+ console.log(`
1399
+ šŸŽ° APE CHURCH CLI - COMMAND REFERENCE
1400
+
1401
+ SETUP
1402
+ apechurch install [--username NAME] [--persona TYPE]
1403
+ Set up your agent wallet and register.
1404
+ Personas: conservative, balanced, aggressive, degen
1405
+
1406
+ apechurch register --username <NAME>
1407
+ Change your username.
1408
+
1409
+ STATUS
1410
+ apechurch status [--json]
1411
+ Check your wallet balance and agent status.
1412
+
1413
+ apechurch games [--json]
1414
+ List all available games and their parameters.
1415
+
1416
+ PLAYING
1417
+ apechurch heartbeat [--strategy TYPE] [--loop] [--json]
1418
+ Place a bet using your strategy. Use --loop to play continuously.
1419
+ Strategies: conservative (60s), balanced (30s), aggressive (15s), degen (10s)
1420
+
1421
+ apechurch bet --game <NAME> --amount <APE> [--mode 0-4] [--balls 1-100] [--spins 1-15]
1422
+ Place a manual bet on a specific game.
1423
+ Games: jungle-plinko, dino-dough, bubblegum-heist
1424
+
1425
+ CONTROL
1426
+ apechurch pause
1427
+ Pause autonomous play.
1428
+
1429
+ apechurch resume
1430
+ Resume autonomous play.
1431
+
1432
+ PROFILE
1433
+ apechurch profile show [--json]
1434
+ View your current profile settings.
1435
+
1436
+ apechurch profile set [--persona TYPE] [--username NAME]
1437
+ Update your profile.
1438
+
1439
+ EXAMPLES
1440
+ apechurch install --username CoolBot --persona balanced
1441
+ apechurch heartbeat --strategy aggressive --loop
1442
+ apechurch bet --game jungle-plinko --amount 10 --mode 3 --balls 25
1443
+ apechurch bet --game dino-dough --amount 5 --spins 10
1444
+ `);
1445
+ });
1446
+
1233
1447
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ape-church/skill",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Autonomous agent skill for Ape Church on ApeChain.",
5
5
  "main": "index.js",
6
6
  "scripts": {