@hedge-layer/cli 1.8.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command5 } from "commander";
4
+ import { Command as Command4 } from "commander";
5
5
 
6
6
  // src/commands/auth.ts
7
7
  import readline from "readline/promises";
@@ -1073,10 +1073,9 @@ function registerFeedCommand(program2) {
1073
1073
  });
1074
1074
  }
1075
1075
 
1076
- // src/commands/allocator.ts
1077
- import { InvalidArgumentError } from "commander";
1078
- import { readFile } from "fs/promises";
1079
- import chalk6 from "chalk";
1076
+ // src/commands/lp.ts
1077
+ import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
1078
+ import { writeFile } from "fs/promises";
1080
1079
 
1081
1080
  // src/allocator-display.ts
1082
1081
  import chalk5 from "chalk";
@@ -1100,38 +1099,6 @@ function num(value, fallback = 0) {
1100
1099
  const n = Number(value);
1101
1100
  return Number.isFinite(n) ? n : fallback;
1102
1101
  }
1103
- function feedMarketsToAllocatorMarkets(markets) {
1104
- return markets.slice(0, 25).map((m) => {
1105
- const probability = num(m.probability ?? m.yesPrice, 0.5);
1106
- const daysToEnd = m.daysToEnd == null || m.daysToEnd === void 0 ? void 0 : num(m.daysToEnd);
1107
- return {
1108
- slug: String(m.slug ?? ""),
1109
- question: String(m.question ?? ""),
1110
- yesTokenId: m.yesTokenId ? String(m.yesTokenId) : void 0,
1111
- noTokenId: m.noTokenId ? String(m.noTokenId) : void 0,
1112
- yesPrice: num(m.yesPrice, probability),
1113
- noPrice: num(m.noPrice, 1 - probability),
1114
- liquidity: num(m.liquidity),
1115
- volume24h: num(m.volume24h),
1116
- spread: num(m.spread),
1117
- rewardsDailyRate: num(m.rewardsDailyRate),
1118
- oneDayPriceChange: num(m.oneDayPriceChange),
1119
- ...daysToEnd !== void 0 && { daysToEnd },
1120
- active: m.active == null ? true : Boolean(m.active)
1121
- };
1122
- });
1123
- }
1124
- function allocationsFromDecisions(decisions) {
1125
- return decisions.filter((d) => String(d.market_slug ?? "")).map((d) => ({
1126
- market_slug: String(d.market_slug),
1127
- status: String(d.action ?? "planned").toLowerCase(),
1128
- allocated_capital: num(d.target_capital),
1129
- locked_capital: 0,
1130
- inventory_yes: 0,
1131
- inventory_no: 0,
1132
- open_order_notional: Array.isArray(d.order_plan) ? d.order_plan.reduce((sum, order) => sum + num(order.notional), 0) : 0
1133
- }));
1134
- }
1135
1102
  function displayAllocatorCycleResult(result, globalOpts) {
1136
1103
  if (globalOpts.json) {
1137
1104
  json(result);
@@ -1145,7 +1112,7 @@ function displayAllocatorCycleResult(result, globalOpts) {
1145
1112
  chalk5.dim(
1146
1113
  ` ${num(result.total_markets, decisions.length)} markets \xB7 ${currency(
1147
1114
  num(summary.target_capital)
1148
- )} target capital \xB7 ${num(summary.orders_planned)} planned orders
1115
+ )} target capital
1149
1116
 
1150
1117
  `
1151
1118
  )
@@ -1158,7 +1125,6 @@ function displayAllocatorCycleResult(result, globalOpts) {
1158
1125
  const action = String(d.action ?? "UNKNOWN");
1159
1126
  const score = num(d.score?.score);
1160
1127
  const expected = num(d.score?.expected_return_daily_pct);
1161
- const orders = Array.isArray(d.order_plan) ? d.order_plan.length : 0;
1162
1128
  const failedChecks = Array.isArray(d.safety_checks) ? d.safety_checks.filter((check) => check.passed === false).length : 0;
1163
1129
  return [
1164
1130
  truncate(String(d.question ?? d.market_slug ?? "\u2014"), 42),
@@ -1166,12 +1132,21 @@ function displayAllocatorCycleResult(result, globalOpts) {
1166
1132
  currency(num(d.target_capital)),
1167
1133
  signedCurrency(num(d.capital_delta)),
1168
1134
  `${expected.toFixed(3)}%`,
1135
+ regimeLabel(String(d.quote_regime ?? "\u2014")),
1169
1136
  String(Math.round(score)),
1170
- String(orders),
1171
1137
  failedChecks === 0 ? chalk5.green("0") : chalk5.yellow(String(failedChecks))
1172
1138
  ];
1173
1139
  });
1174
- table(rows, ["Market", "Action", "Target", "Delta", "Exp/day", "Score", "Orders", "Fails"]);
1140
+ table(rows, [
1141
+ "Market",
1142
+ "Action",
1143
+ "Target",
1144
+ "Delta",
1145
+ "Exp/day",
1146
+ "Regime",
1147
+ "Score",
1148
+ "Fails"
1149
+ ]);
1175
1150
  process.stdout.write("\n");
1176
1151
  for (const decision of decisions.slice(0, 5)) {
1177
1152
  const action = String(decision.action ?? "UNKNOWN");
@@ -1181,17 +1156,13 @@ function displayAllocatorCycleResult(result, globalOpts) {
1181
1156
  process.stdout.write(" " + chalk5.dim("Rationale: ") + truncate(decision.rationale, 120));
1182
1157
  }
1183
1158
  process.stdout.write("\n");
1184
- const orders = Array.isArray(decision.order_plan) ? decision.order_plan : [];
1185
- for (const order of orders.slice(0, 2)) {
1159
+ const economics = decision.economics ?? {};
1160
+ if (economics.realized_spread_pnl !== void 0 || economics.reward_income !== void 0 || economics.net_realized_pnl !== void 0) {
1186
1161
  process.stdout.write(
1187
- " " + chalk5.dim("Order: ") + `${String(order.side ?? "BUY")} ${String(order.outcome ?? "?")} @ ${num(order.price).toFixed(3)} for ${currency(num(order.notional))}
1162
+ " " + chalk5.dim("Economics: ") + `spread ${signedCurrency(num(economics.realized_spread_pnl))}, rewards ${signedCurrency(num(economics.reward_income))}, net ${signedCurrency(num(economics.net_realized_pnl))}
1188
1163
  `
1189
1164
  );
1190
1165
  }
1191
- if (orders.length > 2) {
1192
- process.stdout.write(chalk5.dim(` \u2026 ${orders.length - 2} more orders
1193
- `));
1194
- }
1195
1166
  }
1196
1167
  if (decisions.length > 5) {
1197
1168
  process.stdout.write(chalk5.dim(`
@@ -1199,6 +1170,18 @@ function displayAllocatorCycleResult(result, globalOpts) {
1199
1170
  `));
1200
1171
  }
1201
1172
  }
1173
+ function regimeLabel(value) {
1174
+ switch (value) {
1175
+ case "reward_optimized":
1176
+ return chalk5.green("reward");
1177
+ case "defensive":
1178
+ return chalk5.yellow("defense");
1179
+ case "no_quote":
1180
+ return chalk5.red("no quote");
1181
+ default:
1182
+ return chalk5.dim(value);
1183
+ }
1184
+ }
1202
1185
  function signedCurrency(value) {
1203
1186
  const formatted = currency(Math.abs(value));
1204
1187
  if (value > 0) return chalk5.green(`+${formatted}`);
@@ -1207,23 +1190,8 @@ function signedCurrency(value) {
1207
1190
  }
1208
1191
 
1209
1192
  // src/commands/allocator.ts
1210
- var PROFILE_CHOICES2 = ["lp-opportunity", "liquidity-provider", "liquid-new-or-long"];
1211
- function requireAuth5(client) {
1212
- if (!client.isAuthenticated) {
1213
- error("Not authenticated. Run `hl auth login` first.");
1214
- process.exit(1);
1215
- }
1216
- }
1217
- function isProfile2(s) {
1218
- return s !== void 0 && PROFILE_CHOICES2.includes(s);
1219
- }
1220
- function parseNonNegative(value) {
1221
- const n = Number(value);
1222
- if (!Number.isFinite(n) || n < 0) {
1223
- throw new InvalidArgumentError("Expected a non-negative number");
1224
- }
1225
- return n;
1226
- }
1193
+ import { InvalidArgumentError } from "commander";
1194
+ import { readFile } from "fs/promises";
1227
1195
  function parsePositiveNumber(value) {
1228
1196
  const n = Number(value);
1229
1197
  if (!Number.isFinite(n) || n <= 0) {
@@ -1231,61 +1199,6 @@ function parsePositiveNumber(value) {
1231
1199
  }
1232
1200
  return n;
1233
1201
  }
1234
- function parsePositiveInt(value) {
1235
- const n = Number(value);
1236
- if (!Number.isInteger(n) || n < 1) {
1237
- throw new InvalidArgumentError("Expected a positive integer");
1238
- }
1239
- return n;
1240
- }
1241
- function maybeAdd(entries, key, value) {
1242
- if (value !== void 0 && value !== "") entries.push([key, value]);
1243
- }
1244
- function feedQueryParams2(profile, opts) {
1245
- const entries = [];
1246
- maybeAdd(entries, "profile", profile);
1247
- maybeAdd(entries, "sortBy", opts.sortBy);
1248
- maybeAdd(entries, "tag", opts.tag);
1249
- maybeAdd(entries, "minVolume", opts.minVolume);
1250
- maybeAdd(entries, "minLiquidity", opts.minLiquidity);
1251
- maybeAdd(entries, "maxLiquidity", opts.maxLiquidity);
1252
- maybeAdd(entries, "minRewardsDailyRate", opts.minRewardsDailyRate);
1253
- maybeAdd(entries, "minDaysToEnd", opts.minDaysToEnd);
1254
- maybeAdd(entries, "maxDaysToEnd", opts.maxDaysToEnd);
1255
- maybeAdd(entries, "maxMarketAgeHours", opts.maxMarketAgeHours);
1256
- maybeAdd(entries, "liquidProfile", opts.liquidProfile);
1257
- maybeAdd(entries, "limit", opts.limit);
1258
- return Object.fromEntries(entries);
1259
- }
1260
- function strategyFromOptions(opts) {
1261
- return {
1262
- id: "cli-dry-run",
1263
- name: "CLI dry-run LP strategy",
1264
- status: opts.paused ? "paused" : "dry_run",
1265
- ...opts.totalHoldings !== void 0 && { total_holdings: opts.totalHoldings },
1266
- ...opts.capitalLimitPct !== void 0 && { capital_limit_pct: opts.capitalLimitPct },
1267
- ...opts.perMarketLimitPct !== void 0 && { per_market_limit_pct: opts.perMarketLimitPct },
1268
- capital_limit: opts.capitalLimit,
1269
- per_market_limit: opts.perMarketLimit,
1270
- min_expected_return_daily_pct: opts.minExpectedReturnDailyPct,
1271
- max_inventory_imbalance: opts.maxInventoryImbalance,
1272
- max_order_notional: opts.maxOrderNotional,
1273
- quote_edge_bps: opts.quoteEdgeBps,
1274
- min_liquidity: opts.allocatorMinLiquidity,
1275
- max_spread: opts.maxSpread,
1276
- min_days_to_end: opts.allocatorMinDaysToEnd,
1277
- max_markets: opts.maxMarkets
1278
- };
1279
- }
1280
- function validatePercentageSizing(opts) {
1281
- const usesPercentageSizing = opts.capitalLimitPct !== void 0 || opts.perMarketLimitPct !== void 0;
1282
- if (usesPercentageSizing && opts.totalHoldings === void 0) {
1283
- error(
1284
- "Percentage sizing requires --total-holdings so the allocator can convert percentages into dollar caps."
1285
- );
1286
- process.exit(1);
1287
- }
1288
- }
1289
1202
  async function readAllocations(path) {
1290
1203
  if (!path) return [];
1291
1204
  const raw = path === "-" ? await readStdin() : await readFile(path, "utf8");
@@ -1295,6 +1208,18 @@ async function readAllocations(path) {
1295
1208
  }
1296
1209
  return parsed;
1297
1210
  }
1211
+ async function readMarketPayload(path) {
1212
+ if (!path) return void 0;
1213
+ const raw = path === "-" ? await readStdin() : await readFile(path, "utf8");
1214
+ const parsed = JSON.parse(raw);
1215
+ if (Array.isArray(parsed)) {
1216
+ return parsed;
1217
+ }
1218
+ if (parsed && typeof parsed === "object" && Array.isArray(parsed.markets)) {
1219
+ return parsed.markets;
1220
+ }
1221
+ throw new Error("Markets JSON must be an array or { markets: [...] }");
1222
+ }
1298
1223
  async function readStdin() {
1299
1224
  const chunks = [];
1300
1225
  for await (const chunk of process.stdin) {
@@ -1302,92 +1227,18 @@ async function readStdin() {
1302
1227
  }
1303
1228
  return Buffer.concat(chunks).toString("utf8");
1304
1229
  }
1305
- async function runAllocatorCycle(client, payload) {
1306
- return client.post("/api/allocator/cycle", payload);
1307
- }
1308
- function registerAllocatorCommands(program2) {
1309
- const allocator = program2.command("allocator").description("Run dry-run liquidity allocation cycles");
1310
- allocator.command("cycle").description("Find LP candidates from /api/feed and run a dry-run allocator cycle").argument(
1311
- "[screening]",
1312
- `Optional screening preset: ${PROFILE_CHOICES2.join(" | ")} (same as --profile)`,
1313
- "lp-opportunity"
1314
- ).option("--profile <name>", `Screening defaults: ${PROFILE_CHOICES2.join(", ")}`).option("--sort-by <key>", "score | volume | liquidity | movement | spread | rewards | rewardYield | lpExpectedReturn | horizon").option("--tag <slug>", "Polymarket category tag, e.g. crypto, politics").option("--min-volume <usd>", "Minimum 24h volume (USD)").option("--min-liquidity <usd>", "Minimum displayed liquidity (USD)").option("--max-liquidity <usd>", "Maximum displayed liquidity (USD)").option("--min-rewards-daily-rate <usd>", "Minimum LP rewards USD/day").option("--min-days-to-end <n>", "Feed filter: minimum days until resolution").option("--max-days-to-end <n>", "Feed filter: maximum days until resolution").option("--max-market-age-hours <n>", "With liquid-new-or-long: max age for the new branch").option("--liquid-profile <mode>", "new-or-long (used by liquid-new-or-long screen)").option("--limit <n>", "Max feed markets to fetch (1-100, default 15)", "15").option("--total-holdings <usd>", "Total user holdings / portfolio value used for percentage sizing", parsePositiveNumber).option("--capital-limit-pct <pct>", "Portfolio-level allocation cap as a percent of total holdings", parsePositiveNumber).option("--per-market-limit-pct <pct>", "Per-market target cap as a percent of total holdings", parsePositiveNumber).option("--capital-limit <usd>", "Portfolio capital limit for this cycle", parseNonNegative, 500).option("--per-market-limit <usd>", "Per-market target cap", parseNonNegative, 100).option("--min-expected-return-daily-pct <pct>", "Minimum expected daily return percent", parseNonNegative, 0.02).option("--max-inventory-imbalance <ratio>", "Maximum inventory imbalance", parseNonNegative, 0.25).option("--max-order-notional <usd>", "Maximum notional per planned passive order", parseNonNegative, 25).option("--quote-edge-bps <bps>", "Passive quote edge in basis points", parseNonNegative, 100).option("--allocator-min-liquidity <usd>", "Allocator safety gate: minimum market liquidity", parseNonNegative, 500).option("--max-spread <ratio>", "Allocator safety gate: maximum spread", parseNonNegative, 0.12).option("--allocator-min-days-to-end <n>", "Allocator safety gate: minimum days to resolution", parseNonNegative, 3).option("--max-markets <n>", "Maximum markets allocator may target", parsePositiveInt, 5).option("--allocations <file>", "Existing allocations JSON array; use '-' to read stdin").option("--repeat", "Run a second cycle using targets returned by the first cycle").option("--paused", "Send strategy status paused instead of dry_run").action(async (screening, o) => {
1315
- const globalOpts = program2.opts();
1316
- const client = new ApiClient(globalOpts);
1317
- requireAuth5(client);
1318
- validatePercentageSizing(o);
1319
- let profile = o.profile ?? screening ?? "lp-opportunity";
1320
- if (!isProfile2(profile)) {
1321
- error(`Unknown screening "${profile}". Use: ${PROFILE_CHOICES2.join(" or ")}`);
1322
- process.exit(1);
1323
- }
1324
- if (o.profile && screening && screening !== "lp-opportunity" && o.profile !== screening) {
1325
- warn(`Both positional and --profile set; using --profile (${o.profile}).`);
1326
- profile = o.profile;
1327
- }
1328
- const feed = await client.get("/api/feed", feedQueryParams2(profile, o));
1329
- if (feed.error) {
1330
- error(feed.error);
1331
- process.exit(1);
1332
- }
1333
- if (feed.markets.length === 0) {
1334
- warn("No feed markets matched the allocator criteria.");
1335
- return;
1336
- }
1337
- const allocations = await readAllocations(o.allocations);
1338
- const payload = {
1339
- strategy: strategyFromOptions(o),
1340
- markets: feedMarketsToAllocatorMarkets(feed.markets),
1341
- allocations
1342
- };
1343
- if (!globalOpts.json) {
1344
- process.stderr.write(
1345
- chalk6.dim(
1346
- ` Running allocator dry-run on ${feed.markets.length} ${profile} candidates...
1347
- `
1348
- )
1349
- );
1350
- }
1351
- const first = await runAllocatorCycle(client, payload);
1352
- const firstResult = first.result ?? {};
1353
- if (o.repeat) {
1354
- const repeatPayload = {
1355
- ...payload,
1356
- allocations: allocationsFromDecisions(firstResult.decisions ?? [])
1357
- };
1358
- const second = await runAllocatorCycle(client, repeatPayload);
1359
- if (globalOpts.json) {
1360
- json({ initial: first, repeat: second });
1361
- } else {
1362
- displayAllocatorCycleResult(firstResult, globalOpts);
1363
- process.stdout.write("\n" + chalk6.bold("Repeated with target allocations") + "\n");
1364
- displayAllocatorCycleResult(second.result ?? {}, globalOpts);
1365
- }
1366
- return;
1367
- }
1368
- if (globalOpts.json) {
1369
- json(first);
1370
- } else {
1371
- displayAllocatorCycleResult(firstResult, globalOpts);
1372
- }
1373
- });
1374
- }
1375
-
1376
- // src/commands/lp.ts
1377
- import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
1378
- import { writeFile } from "fs/promises";
1379
1230
 
1380
1231
  // src/lp-display.ts
1381
- import chalk7 from "chalk";
1232
+ import chalk6 from "chalk";
1382
1233
  function num2(value, fallback = 0) {
1383
1234
  const n = Number(value);
1384
1235
  return Number.isFinite(n) ? n : fallback;
1385
1236
  }
1386
1237
  function signedCurrency2(value) {
1387
1238
  const formatted = currency(Math.abs(value));
1388
- if (value > 0) return chalk7.green(`+${formatted}`);
1389
- if (value < 0) return chalk7.yellow(`-${formatted}`);
1390
- return chalk7.dim("$0.00");
1239
+ if (value > 0) return chalk6.green(`+${formatted}`);
1240
+ if (value < 0) return chalk6.yellow(`-${formatted}`);
1241
+ return chalk6.dim("$0.00");
1391
1242
  }
1392
1243
  function actionSummary(actions) {
1393
1244
  if (!actions) return "none";
@@ -1400,13 +1251,13 @@ function displayLpScanResult(result, globalOpts) {
1400
1251
  }
1401
1252
  heading("LP Scan");
1402
1253
  process.stdout.write(
1403
- chalk7.dim(
1254
+ chalk6.dim(
1404
1255
  ` scan ${result.scanId} \xB7 strategy ${result.strategyId} \xB7 ${result.evidenceSaved} evidence rows saved
1405
1256
  `
1406
1257
  )
1407
1258
  );
1408
1259
  process.stdout.write(
1409
- chalk7.dim(
1260
+ chalk6.dim(
1410
1261
  ` ${result.totalScanned.toLocaleString()} scanned \xB7 ${result.totalAfterFilter.toLocaleString()} after filters \xB7 profile ${result.profile}
1411
1262
 
1412
1263
  `
@@ -1435,13 +1286,13 @@ function displayLpRecommendResult(result, globalOpts) {
1435
1286
  }
1436
1287
  heading("LP Recommendations");
1437
1288
  process.stdout.write(
1438
- chalk7.dim(
1289
+ chalk6.dim(
1439
1290
  ` cycle ${result.cycleId} \xB7 strategy ${result.strategyId} \xB7 ${result.candidatesSubmitted} markets \xB7 ${result.allocationsSubmitted} current allocations
1440
1291
  `
1441
1292
  )
1442
1293
  );
1443
1294
  process.stdout.write(
1444
- chalk7.dim(
1295
+ chalk6.dim(
1445
1296
  ` PnL context ${result.pnlContextCount} rows${result.pnlSynced ? " \xB7 synced" : ""} \xB7 approvals required
1446
1297
 
1447
1298
  `
@@ -1456,11 +1307,11 @@ function displayLpEvaluateResult(result, globalOpts) {
1456
1307
  }
1457
1308
  heading("LP Evaluation");
1458
1309
  process.stdout.write(
1459
- chalk7.dim(
1310
+ chalk6.dim(
1460
1311
  ` strategy ${result.strategyId} \xB7 ${result.summary.snapshots} snapshots \xB7 ${result.summary.markets} markets`
1461
1312
  )
1462
1313
  );
1463
- if (result.pnlSynced) process.stdout.write(chalk7.dim(" \xB7 synced"));
1314
+ if (result.pnlSynced) process.stdout.write(chalk6.dim(" \xB7 synced"));
1464
1315
  process.stdout.write("\n\n");
1465
1316
  if (result.syncError) warn(result.syncError);
1466
1317
  table(
@@ -1488,58 +1339,58 @@ function displayLpEvaluateResult(result, globalOpts) {
1488
1339
  ["Market", "Outcome", "Net", "Lesson"]
1489
1340
  );
1490
1341
  }
1491
- function displayLpRunResult(result, globalOpts) {
1492
- if (globalOpts.json) {
1493
- json(result);
1494
- return;
1495
- }
1496
- heading("LP Run");
1497
- process.stdout.write(
1498
- chalk7.dim(
1499
- ` cycle ${result.run.cycleId} \xB7 scan ${result.run.scanId ?? "n/a"} \xB7 strategy ${result.run.strategyId}
1500
- `
1501
- )
1502
- );
1503
- process.stdout.write(
1504
- chalk7.dim(
1505
- ` ${result.run.opportunitiesFound} opportunities \xB7 PnL ${result.run.pnlSynced ? "synced" : "not synced"} \xB7 approvals required
1506
-
1507
- `
1508
- )
1509
- );
1510
- displayAllocatorCycleResult(result.run.result, globalOpts);
1511
- if (result.evaluation) {
1512
- process.stdout.write("\n");
1513
- process.stdout.write(
1514
- chalk7.dim(
1515
- ` Evaluation: ${signedCurrency2(result.evaluation.summary.netPnl)} net PnL across ${result.evaluation.summary.markets} markets
1516
- `
1517
- )
1518
- );
1519
- }
1520
- }
1521
1342
 
1522
1343
  // src/commands/lp.ts
1523
- function requireAuth6(client) {
1344
+ function requireAuth5(client) {
1524
1345
  if (!client.isAuthenticated) {
1525
1346
  error("Not authenticated. Run `hl auth login` first.");
1526
1347
  process.exit(1);
1527
1348
  }
1528
1349
  }
1529
- function parseNonNegative2(value) {
1350
+ function parseNonNegative(value) {
1530
1351
  const n = Number(value);
1531
1352
  if (!Number.isFinite(n) || n < 0) {
1532
1353
  throw new InvalidArgumentError2("Expected a non-negative number");
1533
1354
  }
1534
1355
  return n;
1535
1356
  }
1536
- function parsePositiveInt2(value) {
1357
+ function parsePositiveInt(value) {
1537
1358
  const n = Number(value);
1538
1359
  if (!Number.isInteger(n) || n < 1) {
1539
1360
  throw new InvalidArgumentError2("Expected a positive integer");
1540
1361
  }
1541
1362
  return n;
1542
1363
  }
1364
+ function strategyFromAllocatorOptions(opts) {
1365
+ return {
1366
+ id: "cli-lp-allocator",
1367
+ name: "CLI LP allocator dry run",
1368
+ status: opts.paused ? "paused" : "dry_run",
1369
+ ...opts.totalHoldings !== void 0 && { total_holdings: opts.totalHoldings },
1370
+ ...opts.capitalLimitPct !== void 0 && { capital_limit_pct: opts.capitalLimitPct },
1371
+ ...opts.perMarketLimitPct !== void 0 && { per_market_limit_pct: opts.perMarketLimitPct },
1372
+ capital_limit: opts.capitalLimit,
1373
+ per_market_limit: opts.perMarketLimit,
1374
+ min_expected_return_daily_pct: opts.minExpectedReturnDailyPct,
1375
+ max_inventory_imbalance: opts.maxInventoryImbalance,
1376
+ volatility_fill_spike_threshold: opts.volatilityFillSpikeThreshold,
1377
+ event_no_quote_minutes_before: opts.eventNoQuoteMinutesBefore,
1378
+ event_no_quote_minutes_after: opts.eventNoQuoteMinutesAfter,
1379
+ min_liquidity: opts.allocatorMinLiquidity,
1380
+ max_spread: opts.maxSpread,
1381
+ min_days_to_end: opts.allocatorMinDaysToEnd,
1382
+ max_markets: opts.maxMarkets
1383
+ };
1384
+ }
1385
+ function validateAllocatorPercentageSizing(opts) {
1386
+ const usesPercentageSizing = opts.capitalLimitPct !== void 0 || opts.perMarketLimitPct !== void 0;
1387
+ if (usesPercentageSizing && opts.totalHoldings === void 0) {
1388
+ error(
1389
+ "Percentage sizing requires --total-holdings so the allocator can convert percentages into dollar caps."
1390
+ );
1391
+ process.exit(1);
1392
+ }
1393
+ }
1543
1394
  function compact(payload) {
1544
1395
  return Object.fromEntries(
1545
1396
  Object.entries(payload).filter(([, value]) => value !== void 0 && value !== "")
@@ -1587,19 +1438,43 @@ function buildLpEvaluatePayload(opts) {
1587
1438
  limit: opts.limit
1588
1439
  });
1589
1440
  }
1590
- function buildLpRunPayload(opts) {
1591
- return compact({
1592
- strategyId: opts.strategyId,
1593
- limit: opts.limit,
1594
- syncPnl: opts.syncPnl
1595
- });
1441
+ async function runAllocatorCycle(client, payload) {
1442
+ return client.post("/api/lp/allocator", payload);
1596
1443
  }
1597
1444
  function registerLpCommands(program2) {
1598
1445
  const lp = program2.command("lp").description("Run persisted liquidity-provider scan, recommendation, and evaluation workflows");
1599
- lp.command("scan").description("Scan LP candidates and persist them as evidence").argument("[topic]", "Human label for this scan, e.g. liquidity opportunities").option("--profile <name>", "lp-opportunity | liquidity-provider | liquid-new-or-long", "liquidity-provider").option("--sort-by <key>", "score | volume | liquidity | movement | spread | rewards | rewardYield | lpExpectedReturn | horizon").option("--tag <slug>", "Polymarket category tag, e.g. crypto, politics").option("--min-volume <usd>", "Minimum 24h volume (USD)", parseNonNegative2).option("--min-liquidity <usd>", "Minimum displayed liquidity (USD)", parseNonNegative2).option("--max-liquidity <usd>", "Maximum displayed liquidity (USD)", parseNonNegative2).option("--min-rewards-daily-rate <usd>", "Minimum LP rewards USD/day", parseNonNegative2).option("--min-days-to-end <n>", "Minimum days until resolution", parseNonNegative2).option("--max-days-to-end <n>", "Maximum days until resolution", parseNonNegative2).option("--max-market-age-hours <n>", "With liquid-new-or-long: max age for the new branch", parseNonNegative2).option("--liquid-profile <mode>", "new-or-long").option("--limit <n>", "Max markets to scan/save (1-100, default 15)", parsePositiveInt2, 15).option("--strategy-id <uuid>", "LP strategy id").option("--output <file>", "Write the evidence JSON response to a local file").action(async (topic, opts) => {
1446
+ lp.command("allocator").description("Run the allocator agent on an explicit market list").requiredOption("--markets <file>", "Candidate market JSON array or { markets }; use '-' to read stdin").option("--allocations <file>", "Existing allocations JSON array; use '-' to read stdin").option("--total-holdings <usd>", "Total holdings / portfolio value used for percentage sizing", parsePositiveNumber).option("--capital-limit-pct <pct>", "Portfolio-level allocation cap as a percent of total holdings", parsePositiveNumber).option("--per-market-limit-pct <pct>", "Per-market target cap as a percent of total holdings", parsePositiveNumber).option("--capital-limit <usd>", "Portfolio capital limit for this allocator request", parseNonNegative, 500).option("--per-market-limit <usd>", "Per-market target cap", parseNonNegative, 100).option("--min-expected-return-daily-pct <pct>", "Minimum expected daily return percent", parseNonNegative, 0.02).option("--max-inventory-imbalance <ratio>", "Maximum inventory imbalance", parseNonNegative, 0.25).option("--volatility-fill-spike-threshold <ratio>", "Fill-rate imbalance that switches quotes to defensive mode", parseNonNegative, 0.35).option("--event-no-quote-minutes-before <n>", "No-quote window before scheduled events", parseNonNegative, 60).option("--event-no-quote-minutes-after <n>", "No-quote window after scheduled events", parseNonNegative, 30).option("--allocator-min-liquidity <usd>", "Allocator safety gate: minimum market liquidity", parseNonNegative, 500).option("--max-spread <ratio>", "Allocator safety gate: maximum spread", parseNonNegative, 0.12).option("--allocator-min-days-to-end <n>", "Allocator safety gate: minimum days to resolution", parseNonNegative, 3).option("--max-markets <n>", "Maximum markets allocator may target", parsePositiveInt, 5).option("--paused", "Send strategy status paused instead of dry_run").action(async (opts) => {
1600
1447
  const globalOpts = program2.opts();
1601
1448
  const client = new ApiClient(globalOpts);
1602
- requireAuth6(client);
1449
+ requireAuth5(client);
1450
+ validateAllocatorPercentageSizing(opts);
1451
+ const markets = await readMarketPayload(opts.markets);
1452
+ if (!markets || markets.length === 0) {
1453
+ error("Markets JSON must include at least one market.");
1454
+ process.exit(1);
1455
+ }
1456
+ const payload = {
1457
+ strategy: strategyFromAllocatorOptions(opts),
1458
+ markets,
1459
+ allocations: await readAllocations(opts.allocations)
1460
+ };
1461
+ if (!globalOpts.json) {
1462
+ process.stderr.write(
1463
+ dim(` Running allocator dry-run on ${markets.length} provided candidates...
1464
+ `)
1465
+ );
1466
+ }
1467
+ const response = await runAllocatorCycle(client, payload);
1468
+ if (globalOpts.json) {
1469
+ json(response);
1470
+ } else {
1471
+ displayAllocatorCycleResult(response.result ?? {}, globalOpts);
1472
+ }
1473
+ });
1474
+ lp.command("scan").description("Scan LP candidates and persist them as evidence").argument("[topic]", "Human label for this scan, e.g. liquidity opportunities").option("--profile <name>", "lp-opportunity | liquidity-provider | liquid-new-or-long", "liquidity-provider").option("--sort-by <key>", "score | volume | liquidity | movement | spread | rewards | rewardYield | lpExpectedReturn | horizon").option("--tag <slug>", "Polymarket category tag, e.g. crypto, politics").option("--min-volume <usd>", "Minimum 24h volume (USD)", parseNonNegative).option("--min-liquidity <usd>", "Minimum displayed liquidity (USD)", parseNonNegative).option("--max-liquidity <usd>", "Maximum displayed liquidity (USD)", parseNonNegative).option("--min-rewards-daily-rate <usd>", "Minimum LP rewards USD/day", parseNonNegative).option("--min-days-to-end <n>", "Minimum days until resolution", parseNonNegative).option("--max-days-to-end <n>", "Maximum days until resolution", parseNonNegative).option("--max-market-age-hours <n>", "With liquid-new-or-long: max age for the new branch", parseNonNegative).option("--liquid-profile <mode>", "new-or-long").option("--limit <n>", "Max markets to scan/save (1-100, default 15)", parsePositiveInt, 15).option("--strategy-id <uuid>", "LP strategy id").option("--output <file>", "Write the evidence JSON response to a local file").action(async (topic, opts) => {
1475
+ const globalOpts = program2.opts();
1476
+ const client = new ApiClient(globalOpts);
1477
+ requireAuth5(client);
1603
1478
  const result = await client.post(
1604
1479
  "/api/lp/scan",
1605
1480
  buildLpScanPayload(topic, opts)
@@ -1607,10 +1482,10 @@ function registerLpCommands(program2) {
1607
1482
  await writeArtifact(opts.output, result, Boolean(globalOpts.json));
1608
1483
  displayLpScanResult(result, globalOpts);
1609
1484
  });
1610
- lp.command("recommend").description("Run allocator recommendations from saved LP evidence and current allocations").option("--strategy-id <uuid>", "LP strategy id").option("--scan-id <uuid>", "Use candidates from a specific saved scan").option("--limit <n>", "Max saved candidates to submit (1-25, default 15)", parsePositiveInt2, 15).option("--sync-pnl", "Refresh wallet PnL before recommending").option("--output <file>", "Write the recommendation JSON response to a local file").action(async (opts) => {
1485
+ lp.command("recommend").description("Run allocator recommendations from saved LP evidence and current allocations").option("--strategy-id <uuid>", "LP strategy id").option("--scan-id <uuid>", "Use candidates from a specific saved scan").option("--limit <n>", "Max saved candidates to submit (1-25, default 15)", parsePositiveInt, 15).option("--sync-pnl", "Refresh wallet PnL before recommending").option("--output <file>", "Write the recommendation JSON response to a local file").action(async (opts) => {
1611
1486
  const globalOpts = program2.opts();
1612
1487
  const client = new ApiClient(globalOpts);
1613
- requireAuth6(client);
1488
+ requireAuth5(client);
1614
1489
  const result = await client.post(
1615
1490
  "/api/lp/recommend",
1616
1491
  buildLpRecommendPayload(opts)
@@ -1618,10 +1493,10 @@ function registerLpCommands(program2) {
1618
1493
  await writeArtifact(opts.output, result, Boolean(globalOpts.json));
1619
1494
  displayLpRecommendResult(result, globalOpts);
1620
1495
  });
1621
- lp.command("evaluate").description("Evaluate LP performance and return compact lessons").option("--strategy-id <uuid>", "LP strategy id").option("--wallet-address <address>", "Wallet address to sync PnL from").option("--no-sync-pnl", "Use existing PnL snapshots without refreshing").option("--limit <n>", "Max PnL snapshots to evaluate (1-100, default 50)", parsePositiveInt2, 50).option("--output <file>", "Write the evaluation JSON response to a local file").action(async (opts) => {
1496
+ lp.command("evaluate").description("Evaluate LP performance and return compact lessons").option("--strategy-id <uuid>", "LP strategy id").option("--wallet-address <address>", "Wallet address to sync PnL from").option("--no-sync-pnl", "Use existing PnL snapshots without refreshing").option("--limit <n>", "Max PnL snapshots to evaluate (1-100, default 50)", parsePositiveInt, 50).option("--output <file>", "Write the evaluation JSON response to a local file").action(async (opts) => {
1622
1497
  const globalOpts = program2.opts();
1623
1498
  const client = new ApiClient(globalOpts);
1624
- requireAuth6(client);
1499
+ requireAuth5(client);
1625
1500
  const result = await client.post(
1626
1501
  "/api/lp/evaluate",
1627
1502
  buildLpEvaluatePayload(opts)
@@ -1629,31 +1504,6 @@ function registerLpCommands(program2) {
1629
1504
  await writeArtifact(opts.output, result, Boolean(globalOpts.json));
1630
1505
  displayLpEvaluateResult(result, globalOpts);
1631
1506
  });
1632
- lp.command("run").description("Run scan, recommendation, and evaluation as one dry-run chain").option("--strategy-id <uuid>", "LP strategy id").option("--limit <n>", "Max candidates to scan/recommend (1-25, default 15)", parsePositiveInt2, 15).option("--no-sync-pnl", "Use existing PnL snapshots without refreshing").option("--output <file>", "Write the chained run JSON response to a local file").action(async (opts) => {
1633
- const globalOpts = program2.opts();
1634
- const client = new ApiClient(globalOpts);
1635
- requireAuth6(client);
1636
- const run = await client.post(
1637
- "/api/lp/run",
1638
- buildLpRunPayload(opts)
1639
- );
1640
- let evaluation = null;
1641
- try {
1642
- evaluation = await client.post("/api/lp/evaluate", {
1643
- strategyId: run.strategyId,
1644
- syncPnl: false
1645
- });
1646
- } catch (error2) {
1647
- if (!globalOpts.json) {
1648
- warn(
1649
- `Could not load evaluation summary: ${error2 instanceof Error ? error2.message : String(error2)}`
1650
- );
1651
- }
1652
- }
1653
- const combined = { run, evaluation };
1654
- await writeArtifact(opts.output, combined, Boolean(globalOpts.json));
1655
- displayLpRunResult(combined, globalOpts);
1656
- });
1657
1507
  }
1658
1508
 
1659
1509
  // src/commands/wallet.ts
@@ -1664,7 +1514,7 @@ var POLYGON_NATIVE_USDC = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
1664
1514
  var SUPPORTED_ASSETS = ["pUsd", "usdcE", "matic"];
1665
1515
  var POLYGON_NATIVE_ASSET_LABEL = "POL";
1666
1516
  var TERMINAL_WITHDRAWAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled", "expired"]);
1667
- function requireAuth7(client) {
1517
+ function requireAuth6(client) {
1668
1518
  if (!client.isAuthenticated) {
1669
1519
  error("Not authenticated. Run `hl auth login` first.");
1670
1520
  process.exit(1);
@@ -1849,7 +1699,7 @@ function registerWalletCommands(program2) {
1849
1699
  wallet.command("status").description("Show linked owner and Polymarket deposit wallet status").action(async () => {
1850
1700
  const globalOpts = program2.opts();
1851
1701
  const client = new ApiClient(globalOpts);
1852
- requireAuth7(client);
1702
+ requireAuth6(client);
1853
1703
  const status = await client.get("/api/wallet/status");
1854
1704
  if (globalOpts.json) {
1855
1705
  json(status);
@@ -1860,7 +1710,7 @@ function registerWalletCommands(program2) {
1860
1710
  wallet.command("balances").alias("funds").description("Show available wallet funds").action(async () => {
1861
1711
  const globalOpts = program2.opts();
1862
1712
  const client = new ApiClient(globalOpts);
1863
- requireAuth7(client);
1713
+ requireAuth6(client);
1864
1714
  const balances = await client.get("/api/wallet/balances");
1865
1715
  if (globalOpts.json) {
1866
1716
  json(balances);
@@ -1871,7 +1721,7 @@ function registerWalletCommands(program2) {
1871
1721
  wallet.command("deposit").description("Show deposit address and supported Polygon assets").option("--asset <asset>", "pUSD | USDC.e | POL").option("--bridge", "Also request Polymarket Bridge deposit addresses").action(async (opts) => {
1872
1722
  const globalOpts = program2.opts();
1873
1723
  const client = new ApiClient(globalOpts);
1874
- requireAuth7(client);
1724
+ requireAuth6(client);
1875
1725
  const asset = normalizeWalletAsset(opts.asset);
1876
1726
  const result = await client.post("/api/wallet/deposit", {
1877
1727
  bridge: Boolean(opts.bridge)
@@ -1894,7 +1744,7 @@ function registerWalletCommands(program2) {
1894
1744
  wallet.command("withdraw").description("Create a browser-signed withdrawal intent and poll for completion").requiredOption("--to <address>", "Recipient EVM wallet address", parseWalletAddress).requiredOption("--amount <amount>", "Amount to withdraw", parsePositiveNumber2).option("--asset <asset>", "Source asset; currently only pUSD is supported", "pUSD").option("--to-chain-id <id>", "Destination chain id", "137").option("--to-token-address <address>", "Destination token address", parseWalletAddress, POLYGON_NATIVE_USDC).option("--no-open", "Do not open the browser signing URL").option("--no-wait", "Do not poll for completion after creating the intent").option("--poll-interval <seconds>", "Polling interval in seconds", parsePositiveNumber2, 5).option("--timeout <seconds>", "Maximum seconds to wait for completion", parsePositiveNumber2, 600).action(async (opts) => {
1895
1745
  const globalOpts = program2.opts();
1896
1746
  const client = new ApiClient(globalOpts);
1897
- requireAuth7(client);
1747
+ requireAuth6(client);
1898
1748
  const created = await client.post(
1899
1749
  "/api/wallet/withdraw/intents",
1900
1750
  buildWithdrawRequestPayload(opts)
@@ -1924,7 +1774,7 @@ import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
1924
1774
  import { readFile as readFile2 } from "fs/promises";
1925
1775
 
1926
1776
  // src/signal-display.ts
1927
- import chalk8 from "chalk";
1777
+ import chalk7 from "chalk";
1928
1778
  function pctFromSignalValue(value) {
1929
1779
  if (value === null || value === void 0 || Number.isNaN(value)) return null;
1930
1780
  return Math.abs(value) <= 1 ? value * 100 : value;
@@ -1937,14 +1787,14 @@ function formatGap(value) {
1937
1787
  if (value === null || value === void 0 || Number.isNaN(value)) return "n/a";
1938
1788
  const points = Math.abs(value) <= 1 ? value * 100 : value;
1939
1789
  const formatted = `${points >= 0 ? "+" : ""}${points.toFixed(1)}pp`;
1940
- if (points > 0) return chalk8.green(formatted);
1941
- if (points < 0) return chalk8.red(formatted);
1942
- return chalk8.dim(formatted);
1790
+ if (points > 0) return chalk7.green(formatted);
1791
+ if (points < 0) return chalk7.red(formatted);
1792
+ return chalk7.dim(formatted);
1943
1793
  }
1944
1794
  function formatStrength(value) {
1945
- if (value === "strong") return chalk8.green("strong");
1946
- if (value === "weak") return chalk8.yellow("weak");
1947
- return value ? chalk8.dim(value) : "n/a";
1795
+ if (value === "strong") return chalk7.green("strong");
1796
+ if (value === "weak") return chalk7.yellow("weak");
1797
+ return value ? chalk7.dim(value) : "n/a";
1948
1798
  }
1949
1799
  function analysisItems(result) {
1950
1800
  if (!result) return [];
@@ -1991,27 +1841,27 @@ function displaySignalAnalysis(response, globalOpts) {
1991
1841
  for (const item of items.slice(0, 3)) {
1992
1842
  const analysis = item.analysis;
1993
1843
  if (!analysis) continue;
1994
- process.stdout.write("\n " + chalk8.bold(truncate(titleFor(analysis), 76)) + "\n");
1844
+ process.stdout.write("\n " + chalk7.bold(truncate(titleFor(analysis), 76)) + "\n");
1995
1845
  if (analysis.market_link) {
1996
- process.stdout.write(" " + chalk8.dim("Polymarket: ") + analysis.market_link + "\n");
1846
+ process.stdout.write(" " + chalk7.dim("Polymarket: ") + analysis.market_link + "\n");
1997
1847
  }
1998
1848
  if (analysis.key_factors && analysis.key_factors.length > 0) {
1999
- process.stdout.write(" " + chalk8.dim("Key factors: ") + analysis.key_factors.slice(0, 4).join("; ") + "\n");
1849
+ process.stdout.write(" " + chalk7.dim("Key factors: ") + analysis.key_factors.slice(0, 4).join("; ") + "\n");
2000
1850
  }
2001
1851
  if (analysis.research_findings) {
2002
1852
  process.stdout.write(
2003
- " " + chalk8.dim("Research: ") + truncate(analysis.research_findings, 180) + "\n"
1853
+ " " + chalk7.dim("Research: ") + truncate(analysis.research_findings, 180) + "\n"
2004
1854
  );
2005
1855
  }
2006
1856
  }
2007
1857
  if (items.length > 3) {
2008
- process.stdout.write(chalk8.dim(`
1858
+ process.stdout.write(chalk7.dim(`
2009
1859
  ... and ${items.length - 3} more
2010
1860
  `));
2011
1861
  }
2012
1862
  if (result?.strong_signal_count !== void 0) {
2013
1863
  process.stdout.write(
2014
- chalk8.dim(`
1864
+ chalk7.dim(`
2015
1865
  Strong signals: ${result.strong_signal_count}
2016
1866
  `)
2017
1867
  );
@@ -2019,7 +1869,7 @@ function displaySignalAnalysis(response, globalOpts) {
2019
1869
  }
2020
1870
 
2021
1871
  // src/commands/signal.ts
2022
- function requireAuth8(client) {
1872
+ function requireAuth7(client) {
2023
1873
  if (!client.isAuthenticated) {
2024
1874
  error("Not authenticated. Run `hl auth login` first.");
2025
1875
  process.exit(1);
@@ -2042,7 +1892,7 @@ async function readStdin2() {
2042
1892
  }
2043
1893
  return Buffer.concat(chunks).toString("utf8");
2044
1894
  }
2045
- async function readMarketPayload(path) {
1895
+ async function readMarketPayload2(path) {
2046
1896
  if (!path) return {};
2047
1897
  const raw = path === "-" ? await readStdin2() : await readFile2(path, "utf8");
2048
1898
  const parsed = JSON.parse(raw);
@@ -2074,7 +1924,7 @@ async function buildSignalPayload(positionalUrl, opts) {
2074
1924
  const urls = [positionalUrl, ...opts.url ?? []].filter(
2075
1925
  (value) => Boolean(value)
2076
1926
  );
2077
- const filePayload = await readMarketPayload(opts.market);
1927
+ const filePayload = await readMarketPayload2(opts.market);
2078
1928
  const inlineMarket = inlineMarketFromOptions(opts);
2079
1929
  const hasMarketInput = Boolean(filePayload.market || filePayload.markets || inlineMarket);
2080
1930
  if (urls.length > 0 && hasMarketInput) {
@@ -2103,7 +1953,7 @@ function registerSignalCommands(program2) {
2103
1953
  signal.command("analyze").description("Estimate true YES probability and compare it with market pricing").argument("[url]", "Polymarket market/event URL to analyze").option("--url <url>", "Additional Polymarket URL; repeat for multiple markets", collect, []).option("--market <file>", "Inline market JSON object/array; use '-' to read stdin").option("--context <text>", "Prior search notes or analysis context for the agent").option("--question <text>", "Inline market question when not using a URL").option("--description <text>", "Inline market description or resolution criteria").option("--yes-prob <prob>", "Current YES probability or price, e.g. 0.52 or 52", parseProbability).option("--no-prob <prob>", "Current NO probability or price, e.g. 0.48 or 48", parseProbability).option("--slug <slug>", "Inline market slug").option("--link <url>", "Inline market link").action(async (url, o) => {
2104
1954
  const globalOpts = program2.opts();
2105
1955
  const client = new ApiClient(globalOpts);
2106
- requireAuth8(client);
1956
+ requireAuth7(client);
2107
1957
  let payload;
2108
1958
  try {
2109
1959
  payload = await buildSignalPayload(url, o);
@@ -2120,8 +1970,8 @@ function registerSignalCommands(program2) {
2120
1970
  }
2121
1971
 
2122
1972
  // src/index.ts
2123
- var program = new Command5();
2124
- program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.8.0").option("--json", "Output as JSON (machine-readable)").option("--api-url <url>", "Override API base URL").option("--token <token>", "Override stored API token").option("--verbose", "Show HTTP request details").option("--no-color", "Disable colored output");
1973
+ var program = new Command4();
1974
+ program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("2.0.0").option("--json", "Output as JSON (machine-readable)").option("--api-url <url>", "Override API base URL").option("--token <token>", "Override stored API token").option("--verbose", "Show HTTP request details").option("--no-color", "Disable colored output");
2125
1975
  registerAuthCommands(program);
2126
1976
  registerBriefCommands(program);
2127
1977
  registerProfileCommand(program);
@@ -2129,7 +1979,6 @@ registerResearchCommands(program);
2129
1979
  registerFeedCommand(program);
2130
1980
  registerWalletCommands(program);
2131
1981
  registerLpCommands(program);
2132
- registerAllocatorCommands(program);
2133
1982
  registerSignalCommands(program);
2134
1983
  program.hook("preAction", (_thisCommand, actionCommand) => {
2135
1984
  const opts = program.opts();