@hedge-layer/cli 1.4.0 → 1.6.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/README.md +7 -107
- package/dist/index.mjs +328 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@hedge-layer/cli)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
|
|
6
|
-
Command-line interface for [Hedge Layer](https://hedgelayer.ai)
|
|
6
|
+
Command-line interface for [Hedge Layer](https://hedgelayer.ai): prediction market intelligence from the terminal.
|
|
7
|
+
|
|
8
|
+
The canonical CLI guide now lives in the Hedge Layer web app docs:
|
|
9
|
+
[hedgelayer.ai/docs/cli](https://hedgelayer.ai/docs/cli).
|
|
7
10
|
|
|
8
11
|
## Install
|
|
9
12
|
|
|
@@ -16,7 +19,7 @@ Requires Node.js 22 or later.
|
|
|
16
19
|
## Quick Start
|
|
17
20
|
|
|
18
21
|
```bash
|
|
19
|
-
# 1. Create an API token at https://hedgelayer.ai/settings
|
|
22
|
+
# 1. Create an API token at https://hedgelayer.ai/account/settings
|
|
20
23
|
# 2. Authenticate the CLI
|
|
21
24
|
hl auth login
|
|
22
25
|
|
|
@@ -27,113 +30,10 @@ hl brief "US China trade war tariffs"
|
|
|
27
30
|
hl research
|
|
28
31
|
```
|
|
29
32
|
|
|
30
|
-
## Authentication
|
|
31
|
-
|
|
32
|
-
The CLI uses API tokens created in the Hedge Layer web app. Tokens are stored locally in `~/.hedgelayer/config.json`.
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
hl auth login # Paste your API token (interactive)
|
|
36
|
-
hl auth status # Check current authentication
|
|
37
|
-
hl auth logout # Remove stored token
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
You can also pass a token inline for CI/scripts:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
hl --token hl_abc123... research list
|
|
44
|
-
```
|
|
45
|
-
|
|
46
33
|
## Commands
|
|
47
34
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Generate a Market Brief directly from a topic — no Q&A, no interactive session. The AI researches current events, discovers relevant prediction markets, and synthesizes a structured brief with causal reasoning and coverage gaps.
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# Generate a brief (streams progress to stderr, brief to stdout)
|
|
54
|
-
hl brief "US China trade war tariffs"
|
|
55
|
-
hl brief "hurricane season impact on Florida" --location "US Southeast" --time-horizon "6 months"
|
|
56
|
-
|
|
57
|
-
# Pipe the brief as JSON
|
|
58
|
-
hl --json brief "crypto regulation 2026" | jq '.markets'
|
|
59
|
-
|
|
60
|
-
# Filter by tags and volume
|
|
61
|
-
hl brief "energy policy" --tags "geopolitics,energy" --min-volume 10000
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
| Option | Description |
|
|
65
|
-
|--------|-------------|
|
|
66
|
-
| `-l, --location <loc>` | Geographic context (e.g. `"Middle East"`, `"US"`) |
|
|
67
|
-
| `-t, --time-horizon <h>` | Time frame (e.g. `"3 months"`, `"2026"`) |
|
|
68
|
-
| `--tags <tags>` | Comma-separated focus area tags (e.g. `"geopolitics,energy"`) |
|
|
69
|
-
| `--min-volume <n>` | Minimum market volume in USD |
|
|
70
|
-
| `--max-yes-price <n>` | Maximum YES price (0-1) |
|
|
71
|
-
|
|
72
|
-
### Research
|
|
73
|
-
|
|
74
|
-
AI-powered interactive research sessions. Describe a topic or thesis, and the AI researches current events, discovers relevant prediction markets, and synthesizes a structured Market Brief through a multi-turn conversation.
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
# Start an interactive research session (Q&A)
|
|
78
|
-
hl research
|
|
79
|
-
|
|
80
|
-
# Non-interactive: same Market Brief as `hl brief`, JSON on stdout (blocking `POST /api/brief` with stream off)
|
|
81
|
-
hl research run "US election forecasting"
|
|
82
|
-
|
|
83
|
-
# List past research sessions
|
|
84
|
-
hl research list
|
|
85
|
-
hl research list --status completed
|
|
86
|
-
|
|
87
|
-
# View a specific session and its Market Brief
|
|
88
|
-
hl research show <id>
|
|
89
|
-
|
|
90
|
-
# Delete a session
|
|
91
|
-
hl research delete <id>
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
For a **non-interactive** JSON brief from the shell, use `hl research run` (blocking) or `hl brief` (streams progress on stderr). Both use the same `POST /api/brief` endpoint.
|
|
95
|
-
|
|
96
|
-
### Feed
|
|
97
|
-
|
|
98
|
-
Deterministic ranking of active Polymarket markets (same engine as the in-app **getFeed** tool and `GET /api/feed`). No LLM — fast quantitative screens.
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
# LP-style screen: thinner books with meaningful daily rewards (reward yield ranking)
|
|
102
|
-
hl feed lp-opportunity
|
|
103
|
-
hl --json feed lp-opportunity | jq '.markets[:5]'
|
|
104
|
-
|
|
105
|
-
# Deep books that are either new (last 7d) or long-dated (90d+ to resolution), sorted by liquidity
|
|
106
|
-
hl feed liquid-new-or-long
|
|
107
|
-
|
|
108
|
-
# Custom: e.g. crypto tag only, sort by movement
|
|
109
|
-
hl feed --tag crypto --sort-by movement --limit 25
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Curated defaults live in the API (`profile=lp-opportunity` and `profile=liquid-new-or-long`); CLI flags override those defaults. Use `hl feed --help` for every filter.
|
|
113
|
-
|
|
114
|
-
### Profile
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
hl profile
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Global Options
|
|
121
|
-
|
|
122
|
-
| Flag | Description |
|
|
123
|
-
|------|-------------|
|
|
124
|
-
| `--json` | Machine-readable JSON output |
|
|
125
|
-
| `--api-url <url>` | Override API base URL (default: `https://hedgelayer.ai`) |
|
|
126
|
-
| `--token <token>` | Override stored API token |
|
|
127
|
-
| `--verbose` | Show HTTP request/response details |
|
|
128
|
-
| `--no-color` | Disable colored output |
|
|
129
|
-
|
|
130
|
-
### JSON output
|
|
131
|
-
|
|
132
|
-
Every command supports `--json` for pipe-friendly output:
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
hl --json research list | jq '.[0].id'
|
|
136
|
-
```
|
|
35
|
+
Full command documentation is available at
|
|
36
|
+
[hedgelayer.ai/docs/cli](https://hedgelayer.ai/docs/cli).
|
|
137
37
|
|
|
138
38
|
## Changelog
|
|
139
39
|
|
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 } from "commander";
|
|
4
|
+
import { Command as Command2 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth.ts
|
|
7
7
|
import readline from "readline/promises";
|
|
@@ -300,7 +300,7 @@ function registerAuthCommands(program2) {
|
|
|
300
300
|
try {
|
|
301
301
|
heading("Hedge Layer CLI \u2014 Login");
|
|
302
302
|
process.stderr.write(
|
|
303
|
-
`Create an API token at ${bold("https://hedgelayer.ai/settings")} \u2192 API Tokens
|
|
303
|
+
`Create an API token at ${bold("https://hedgelayer.ai/account/settings")} \u2192 API Tokens
|
|
304
304
|
|
|
305
305
|
`
|
|
306
306
|
);
|
|
@@ -646,6 +646,7 @@ var SORT_LABELS = {
|
|
|
646
646
|
extremity: "uncertainty",
|
|
647
647
|
rewards: "rewards",
|
|
648
648
|
rewardYield: "reward yield (per $ liq)",
|
|
649
|
+
lpExpectedReturn: "LP expected return",
|
|
649
650
|
horizon: "time to resolution"
|
|
650
651
|
};
|
|
651
652
|
function scoreBar(score) {
|
|
@@ -945,10 +946,24 @@ function requireAuth4(client) {
|
|
|
945
946
|
process.exit(1);
|
|
946
947
|
}
|
|
947
948
|
}
|
|
948
|
-
var PROFILE_CHOICES = ["lp-opportunity", "liquid-new-or-long"];
|
|
949
|
+
var PROFILE_CHOICES = ["lp-opportunity", "liquidity-provider", "liquid-new-or-long"];
|
|
949
950
|
function isProfile(s) {
|
|
950
951
|
return s !== void 0 && PROFILE_CHOICES.includes(s);
|
|
951
952
|
}
|
|
953
|
+
function resolveFeedProfile(screening, profile, warn2 = () => void 0) {
|
|
954
|
+
if (profile && !isProfile(profile)) {
|
|
955
|
+
throw new Error(`Unknown feed profile "${profile}". Use: ${PROFILE_CHOICES.join(" or ")}`);
|
|
956
|
+
}
|
|
957
|
+
if (!screening) return profile;
|
|
958
|
+
if (!isProfile(screening)) {
|
|
959
|
+
throw new Error(`Unknown screening "${screening}". Use: ${PROFILE_CHOICES.join(" or ")}`);
|
|
960
|
+
}
|
|
961
|
+
if (profile && profile !== screening) {
|
|
962
|
+
warn2(`Both positional and --profile set; using --profile (${profile}).`);
|
|
963
|
+
return profile;
|
|
964
|
+
}
|
|
965
|
+
return profile ?? screening;
|
|
966
|
+
}
|
|
952
967
|
function feedQueryParams(opts) {
|
|
953
968
|
const entries = [];
|
|
954
969
|
const add = (k, v) => {
|
|
@@ -978,19 +993,14 @@ function registerFeedCommand(program2) {
|
|
|
978
993
|
).option(
|
|
979
994
|
"--profile <name>",
|
|
980
995
|
`Screening defaults: ${PROFILE_CHOICES.join(", ")} \u2014 explicit flags override`
|
|
981
|
-
).option("--sort-by <key>", "score | volume | liquidity | movement | spread | recency | extremity | rewards | rewardYield | horizon").option("--preset <name>", "Attention weight preset (default, volume-hunter, lp-opportunity, \u2026)").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>", "Min calendar days until resolution").option("--max-days-to-end <n>", "Max calendar days until resolution").option("--max-market-age-hours <n>", 'With liquid-new-or-long: max age (hours) for the "new" branch').option("--liquid-profile <mode>", "new-or-long (used by liquid-new-or-long screen)").option("--limit <n>", "Max markets to return (1\u2013100, default 15)", "15").action(async (screening, o) => {
|
|
996
|
+
).option("--sort-by <key>", "score | volume | liquidity | movement | spread | recency | extremity | rewards | rewardYield | lpExpectedReturn | horizon").option("--preset <name>", "Attention weight preset (default, volume-hunter, lp-opportunity, \u2026)").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>", "Min calendar days until resolution").option("--max-days-to-end <n>", "Max calendar days until resolution").option("--max-market-age-hours <n>", 'With liquid-new-or-long: max age (hours) for the "new" branch').option("--liquid-profile <mode>", "new-or-long (used by liquid-new-or-long screen)").option("--limit <n>", "Max markets to return (1\u2013100, default 15)", "15").action(async (screening, o) => {
|
|
982
997
|
const globalOpts = program2.opts();
|
|
983
|
-
let profile
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (profile && profile !== screening) {
|
|
990
|
-
warn(`Both positional and --profile set; using --profile (${profile}).`);
|
|
991
|
-
} else if (!profile) {
|
|
992
|
-
profile = screening;
|
|
993
|
-
}
|
|
998
|
+
let profile;
|
|
999
|
+
try {
|
|
1000
|
+
profile = resolveFeedProfile(screening, o.profile, warn);
|
|
1001
|
+
} catch (e) {
|
|
1002
|
+
error(e instanceof Error ? e.message : String(e));
|
|
1003
|
+
process.exit(1);
|
|
994
1004
|
}
|
|
995
1005
|
const client = new ApiClient(globalOpts);
|
|
996
1006
|
requireAuth4(client);
|
|
@@ -1023,14 +1033,315 @@ function registerFeedCommand(program2) {
|
|
|
1023
1033
|
});
|
|
1024
1034
|
}
|
|
1025
1035
|
|
|
1036
|
+
// src/commands/allocator.ts
|
|
1037
|
+
import { InvalidArgumentError } from "commander";
|
|
1038
|
+
import { readFile } from "fs/promises";
|
|
1039
|
+
import chalk6 from "chalk";
|
|
1040
|
+
|
|
1041
|
+
// src/allocator-display.ts
|
|
1042
|
+
import chalk5 from "chalk";
|
|
1043
|
+
function actionColor(action) {
|
|
1044
|
+
switch (action) {
|
|
1045
|
+
case "ALLOCATE":
|
|
1046
|
+
case "INCREASE":
|
|
1047
|
+
return chalk5.green(action);
|
|
1048
|
+
case "REDUCE":
|
|
1049
|
+
case "EXIT":
|
|
1050
|
+
return chalk5.yellow(action);
|
|
1051
|
+
case "SKIP":
|
|
1052
|
+
return chalk5.dim(action);
|
|
1053
|
+
case "WATCH":
|
|
1054
|
+
return chalk5.cyan(action);
|
|
1055
|
+
default:
|
|
1056
|
+
return action;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
function num(value, fallback = 0) {
|
|
1060
|
+
const n = Number(value);
|
|
1061
|
+
return Number.isFinite(n) ? n : fallback;
|
|
1062
|
+
}
|
|
1063
|
+
function feedMarketsToAllocatorMarkets(markets) {
|
|
1064
|
+
return markets.slice(0, 25).map((m) => {
|
|
1065
|
+
const probability = num(m.probability ?? m.yesPrice, 0.5);
|
|
1066
|
+
const daysToEnd = m.daysToEnd == null || m.daysToEnd === void 0 ? void 0 : num(m.daysToEnd);
|
|
1067
|
+
return {
|
|
1068
|
+
slug: String(m.slug ?? ""),
|
|
1069
|
+
question: String(m.question ?? ""),
|
|
1070
|
+
yesTokenId: m.yesTokenId ? String(m.yesTokenId) : void 0,
|
|
1071
|
+
noTokenId: m.noTokenId ? String(m.noTokenId) : void 0,
|
|
1072
|
+
yesPrice: num(m.yesPrice, probability),
|
|
1073
|
+
noPrice: num(m.noPrice, 1 - probability),
|
|
1074
|
+
liquidity: num(m.liquidity),
|
|
1075
|
+
volume24h: num(m.volume24h),
|
|
1076
|
+
spread: num(m.spread),
|
|
1077
|
+
rewardsDailyRate: num(m.rewardsDailyRate),
|
|
1078
|
+
oneDayPriceChange: num(m.oneDayPriceChange),
|
|
1079
|
+
...daysToEnd !== void 0 && { daysToEnd },
|
|
1080
|
+
active: m.active == null ? true : Boolean(m.active)
|
|
1081
|
+
};
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
function allocationsFromDecisions(decisions) {
|
|
1085
|
+
return decisions.filter((d) => String(d.market_slug ?? "")).map((d) => ({
|
|
1086
|
+
market_slug: String(d.market_slug),
|
|
1087
|
+
status: String(d.action ?? "planned").toLowerCase(),
|
|
1088
|
+
allocated_capital: num(d.target_capital),
|
|
1089
|
+
locked_capital: 0,
|
|
1090
|
+
inventory_yes: 0,
|
|
1091
|
+
inventory_no: 0,
|
|
1092
|
+
open_order_notional: Array.isArray(d.order_plan) ? d.order_plan.reduce((sum, order) => sum + num(order.notional), 0) : 0
|
|
1093
|
+
}));
|
|
1094
|
+
}
|
|
1095
|
+
function displayAllocatorCycleResult(result, globalOpts) {
|
|
1096
|
+
if (globalOpts.json) {
|
|
1097
|
+
json(result);
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
const decisions = Array.isArray(result.decisions) ? result.decisions : [];
|
|
1101
|
+
const summary = result.summary ?? {};
|
|
1102
|
+
const dryRun = result.dry_run === false ? "live" : "dry run";
|
|
1103
|
+
heading(`Allocator Cycle \u2014 ${dryRun}`);
|
|
1104
|
+
process.stdout.write(
|
|
1105
|
+
chalk5.dim(
|
|
1106
|
+
` ${num(result.total_markets, decisions.length)} markets \xB7 ${currency(
|
|
1107
|
+
num(summary.target_capital)
|
|
1108
|
+
)} target capital \xB7 ${num(summary.orders_planned)} planned orders
|
|
1109
|
+
|
|
1110
|
+
`
|
|
1111
|
+
)
|
|
1112
|
+
);
|
|
1113
|
+
if (decisions.length === 0) {
|
|
1114
|
+
warn("No allocator decisions returned.");
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
const rows = decisions.map((d) => {
|
|
1118
|
+
const action = String(d.action ?? "UNKNOWN");
|
|
1119
|
+
const score = num(d.score?.score);
|
|
1120
|
+
const expected = num(d.score?.expected_return_daily_pct);
|
|
1121
|
+
const orders = Array.isArray(d.order_plan) ? d.order_plan.length : 0;
|
|
1122
|
+
const failedChecks = Array.isArray(d.safety_checks) ? d.safety_checks.filter((check) => check.passed === false).length : 0;
|
|
1123
|
+
return [
|
|
1124
|
+
truncate(String(d.question ?? d.market_slug ?? "\u2014"), 42),
|
|
1125
|
+
actionColor(action),
|
|
1126
|
+
currency(num(d.target_capital)),
|
|
1127
|
+
signedCurrency(num(d.capital_delta)),
|
|
1128
|
+
`${expected.toFixed(3)}%`,
|
|
1129
|
+
String(Math.round(score)),
|
|
1130
|
+
String(orders),
|
|
1131
|
+
failedChecks === 0 ? chalk5.green("0") : chalk5.yellow(String(failedChecks))
|
|
1132
|
+
];
|
|
1133
|
+
});
|
|
1134
|
+
table(rows, ["Market", "Action", "Target", "Delta", "Exp/day", "Score", "Orders", "Fails"]);
|
|
1135
|
+
process.stdout.write("\n");
|
|
1136
|
+
for (const decision of decisions.slice(0, 5)) {
|
|
1137
|
+
const action = String(decision.action ?? "UNKNOWN");
|
|
1138
|
+
process.stdout.write(" " + chalk5.dim("\u25B8 ") + truncate(String(decision.question ?? decision.market_slug ?? "\u2014"), 65) + "\n");
|
|
1139
|
+
process.stdout.write(" " + chalk5.dim("Action: ") + actionColor(action));
|
|
1140
|
+
if (decision.rationale) {
|
|
1141
|
+
process.stdout.write(" " + chalk5.dim("Rationale: ") + truncate(decision.rationale, 120));
|
|
1142
|
+
}
|
|
1143
|
+
process.stdout.write("\n");
|
|
1144
|
+
const orders = Array.isArray(decision.order_plan) ? decision.order_plan : [];
|
|
1145
|
+
for (const order of orders.slice(0, 2)) {
|
|
1146
|
+
process.stdout.write(
|
|
1147
|
+
" " + chalk5.dim("Order: ") + `${String(order.side ?? "BUY")} ${String(order.outcome ?? "?")} @ ${num(order.price).toFixed(3)} for ${currency(num(order.notional))}
|
|
1148
|
+
`
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
if (orders.length > 2) {
|
|
1152
|
+
process.stdout.write(chalk5.dim(` \u2026 ${orders.length - 2} more orders
|
|
1153
|
+
`));
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
if (decisions.length > 5) {
|
|
1157
|
+
process.stdout.write(chalk5.dim(`
|
|
1158
|
+
\u2026 and ${decisions.length - 5} more decisions
|
|
1159
|
+
`));
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
function signedCurrency(value) {
|
|
1163
|
+
const formatted = currency(Math.abs(value));
|
|
1164
|
+
if (value > 0) return chalk5.green(`+${formatted}`);
|
|
1165
|
+
if (value < 0) return chalk5.yellow(`-${formatted}`);
|
|
1166
|
+
return chalk5.dim("$0.00");
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// src/commands/allocator.ts
|
|
1170
|
+
var PROFILE_CHOICES2 = ["lp-opportunity", "liquidity-provider", "liquid-new-or-long"];
|
|
1171
|
+
function requireAuth5(client) {
|
|
1172
|
+
if (!client.isAuthenticated) {
|
|
1173
|
+
error("Not authenticated. Run `hl auth login` first.");
|
|
1174
|
+
process.exit(1);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
function isProfile2(s) {
|
|
1178
|
+
return s !== void 0 && PROFILE_CHOICES2.includes(s);
|
|
1179
|
+
}
|
|
1180
|
+
function parseNonNegative(value) {
|
|
1181
|
+
const n = Number(value);
|
|
1182
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
1183
|
+
throw new InvalidArgumentError("Expected a non-negative number");
|
|
1184
|
+
}
|
|
1185
|
+
return n;
|
|
1186
|
+
}
|
|
1187
|
+
function parsePositiveNumber(value) {
|
|
1188
|
+
const n = Number(value);
|
|
1189
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
1190
|
+
throw new InvalidArgumentError("Expected a positive number");
|
|
1191
|
+
}
|
|
1192
|
+
return n;
|
|
1193
|
+
}
|
|
1194
|
+
function parsePositiveInt(value) {
|
|
1195
|
+
const n = Number(value);
|
|
1196
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
1197
|
+
throw new InvalidArgumentError("Expected a positive integer");
|
|
1198
|
+
}
|
|
1199
|
+
return n;
|
|
1200
|
+
}
|
|
1201
|
+
function maybeAdd(entries, key, value) {
|
|
1202
|
+
if (value !== void 0 && value !== "") entries.push([key, value]);
|
|
1203
|
+
}
|
|
1204
|
+
function feedQueryParams2(profile, opts) {
|
|
1205
|
+
const entries = [];
|
|
1206
|
+
maybeAdd(entries, "profile", profile);
|
|
1207
|
+
maybeAdd(entries, "sortBy", opts.sortBy);
|
|
1208
|
+
maybeAdd(entries, "tag", opts.tag);
|
|
1209
|
+
maybeAdd(entries, "minVolume", opts.minVolume);
|
|
1210
|
+
maybeAdd(entries, "minLiquidity", opts.minLiquidity);
|
|
1211
|
+
maybeAdd(entries, "maxLiquidity", opts.maxLiquidity);
|
|
1212
|
+
maybeAdd(entries, "minRewardsDailyRate", opts.minRewardsDailyRate);
|
|
1213
|
+
maybeAdd(entries, "minDaysToEnd", opts.minDaysToEnd);
|
|
1214
|
+
maybeAdd(entries, "maxDaysToEnd", opts.maxDaysToEnd);
|
|
1215
|
+
maybeAdd(entries, "maxMarketAgeHours", opts.maxMarketAgeHours);
|
|
1216
|
+
maybeAdd(entries, "liquidProfile", opts.liquidProfile);
|
|
1217
|
+
maybeAdd(entries, "limit", opts.limit);
|
|
1218
|
+
return Object.fromEntries(entries);
|
|
1219
|
+
}
|
|
1220
|
+
function strategyFromOptions(opts) {
|
|
1221
|
+
return {
|
|
1222
|
+
id: "cli-dry-run",
|
|
1223
|
+
name: "CLI dry-run LP strategy",
|
|
1224
|
+
status: opts.paused ? "paused" : "dry_run",
|
|
1225
|
+
...opts.totalHoldings !== void 0 && { total_holdings: opts.totalHoldings },
|
|
1226
|
+
...opts.capitalLimitPct !== void 0 && { capital_limit_pct: opts.capitalLimitPct },
|
|
1227
|
+
...opts.perMarketLimitPct !== void 0 && { per_market_limit_pct: opts.perMarketLimitPct },
|
|
1228
|
+
capital_limit: opts.capitalLimit,
|
|
1229
|
+
per_market_limit: opts.perMarketLimit,
|
|
1230
|
+
min_expected_return_daily_pct: opts.minExpectedReturnDailyPct,
|
|
1231
|
+
max_inventory_imbalance: opts.maxInventoryImbalance,
|
|
1232
|
+
max_order_notional: opts.maxOrderNotional,
|
|
1233
|
+
quote_edge_bps: opts.quoteEdgeBps,
|
|
1234
|
+
min_liquidity: opts.allocatorMinLiquidity,
|
|
1235
|
+
max_spread: opts.maxSpread,
|
|
1236
|
+
min_days_to_end: opts.allocatorMinDaysToEnd,
|
|
1237
|
+
max_markets: opts.maxMarkets
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
function validatePercentageSizing(opts) {
|
|
1241
|
+
const usesPercentageSizing = opts.capitalLimitPct !== void 0 || opts.perMarketLimitPct !== void 0;
|
|
1242
|
+
if (usesPercentageSizing && opts.totalHoldings === void 0) {
|
|
1243
|
+
error(
|
|
1244
|
+
"Percentage sizing requires --total-holdings so the allocator can convert percentages into dollar caps."
|
|
1245
|
+
);
|
|
1246
|
+
process.exit(1);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
async function readAllocations(path) {
|
|
1250
|
+
if (!path) return [];
|
|
1251
|
+
const raw = path === "-" ? await readStdin() : await readFile(path, "utf8");
|
|
1252
|
+
const parsed = JSON.parse(raw);
|
|
1253
|
+
if (!Array.isArray(parsed)) {
|
|
1254
|
+
throw new Error("Allocations JSON must be an array");
|
|
1255
|
+
}
|
|
1256
|
+
return parsed;
|
|
1257
|
+
}
|
|
1258
|
+
async function readStdin() {
|
|
1259
|
+
const chunks = [];
|
|
1260
|
+
for await (const chunk of process.stdin) {
|
|
1261
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
1262
|
+
}
|
|
1263
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
1264
|
+
}
|
|
1265
|
+
async function runAllocatorCycle(client, payload) {
|
|
1266
|
+
return client.post("/api/allocator/cycle", payload);
|
|
1267
|
+
}
|
|
1268
|
+
function registerAllocatorCommands(program2) {
|
|
1269
|
+
const allocator = program2.command("allocator").description("Run dry-run liquidity allocation cycles");
|
|
1270
|
+
allocator.command("cycle").description("Find LP candidates from /api/feed and run a dry-run allocator cycle").argument(
|
|
1271
|
+
"[screening]",
|
|
1272
|
+
`Optional screening preset: ${PROFILE_CHOICES2.join(" | ")} (same as --profile)`,
|
|
1273
|
+
"lp-opportunity"
|
|
1274
|
+
).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) => {
|
|
1275
|
+
const globalOpts = program2.opts();
|
|
1276
|
+
const client = new ApiClient(globalOpts);
|
|
1277
|
+
requireAuth5(client);
|
|
1278
|
+
validatePercentageSizing(o);
|
|
1279
|
+
let profile = o.profile ?? screening ?? "lp-opportunity";
|
|
1280
|
+
if (!isProfile2(profile)) {
|
|
1281
|
+
error(`Unknown screening "${profile}". Use: ${PROFILE_CHOICES2.join(" or ")}`);
|
|
1282
|
+
process.exit(1);
|
|
1283
|
+
}
|
|
1284
|
+
if (o.profile && screening && screening !== "lp-opportunity" && o.profile !== screening) {
|
|
1285
|
+
warn(`Both positional and --profile set; using --profile (${o.profile}).`);
|
|
1286
|
+
profile = o.profile;
|
|
1287
|
+
}
|
|
1288
|
+
const feed = await client.get("/api/feed", feedQueryParams2(profile, o));
|
|
1289
|
+
if (feed.error) {
|
|
1290
|
+
error(feed.error);
|
|
1291
|
+
process.exit(1);
|
|
1292
|
+
}
|
|
1293
|
+
if (feed.markets.length === 0) {
|
|
1294
|
+
warn("No feed markets matched the allocator criteria.");
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
const allocations = await readAllocations(o.allocations);
|
|
1298
|
+
const payload = {
|
|
1299
|
+
strategy: strategyFromOptions(o),
|
|
1300
|
+
markets: feedMarketsToAllocatorMarkets(feed.markets),
|
|
1301
|
+
allocations
|
|
1302
|
+
};
|
|
1303
|
+
if (!globalOpts.json) {
|
|
1304
|
+
process.stderr.write(
|
|
1305
|
+
chalk6.dim(
|
|
1306
|
+
` Running allocator dry-run on ${feed.markets.length} ${profile} candidates...
|
|
1307
|
+
`
|
|
1308
|
+
)
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
const first = await runAllocatorCycle(client, payload);
|
|
1312
|
+
const firstResult = first.result ?? {};
|
|
1313
|
+
if (o.repeat) {
|
|
1314
|
+
const repeatPayload = {
|
|
1315
|
+
...payload,
|
|
1316
|
+
allocations: allocationsFromDecisions(firstResult.decisions ?? [])
|
|
1317
|
+
};
|
|
1318
|
+
const second = await runAllocatorCycle(client, repeatPayload);
|
|
1319
|
+
if (globalOpts.json) {
|
|
1320
|
+
json({ initial: first, repeat: second });
|
|
1321
|
+
} else {
|
|
1322
|
+
displayAllocatorCycleResult(firstResult, globalOpts);
|
|
1323
|
+
process.stdout.write("\n" + chalk6.bold("Repeated with target allocations") + "\n");
|
|
1324
|
+
displayAllocatorCycleResult(second.result ?? {}, globalOpts);
|
|
1325
|
+
}
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
if (globalOpts.json) {
|
|
1329
|
+
json(first);
|
|
1330
|
+
} else {
|
|
1331
|
+
displayAllocatorCycleResult(firstResult, globalOpts);
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1026
1336
|
// src/index.ts
|
|
1027
|
-
var program = new
|
|
1028
|
-
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.
|
|
1337
|
+
var program = new Command2();
|
|
1338
|
+
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.6.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");
|
|
1029
1339
|
registerAuthCommands(program);
|
|
1030
1340
|
registerBriefCommands(program);
|
|
1031
1341
|
registerProfileCommand(program);
|
|
1032
1342
|
registerResearchCommands(program);
|
|
1033
1343
|
registerFeedCommand(program);
|
|
1344
|
+
registerAllocatorCommands(program);
|
|
1034
1345
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
1035
1346
|
const opts = program.opts();
|
|
1036
1347
|
if (opts.color === false) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/client.ts","../src/output.ts","../src/commands/brief.ts","../src/stream.ts","../src/commands/profile.ts","../src/commands/research.ts","../src/feed-display.ts","../src/commands/feed.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerBriefCommands } from \"./commands/brief.js\";\n\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerResearchCommands } from \"./commands/research.js\";\nimport { registerFeedCommand } from \"./commands/feed.js\";\nimport * as out from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"hl\")\n .description(\"Hedge Layer CLI — prediction market intelligence from the terminal\")\n .version(__VERSION__)\n .option(\"--json\", \"Output as JSON (machine-readable)\")\n .option(\"--api-url <url>\", \"Override API base URL\")\n .option(\"--token <token>\", \"Override stored API token\")\n .option(\"--verbose\", \"Show HTTP request details\")\n .option(\"--no-color\", \"Disable colored output\");\n\nregisterAuthCommands(program);\nregisterBriefCommands(program);\n\nregisterProfileCommand(program);\nregisterResearchCommands(program);\nregisterFeedCommand(program);\n\nprogram.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const opts = program.opts();\n if (opts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n if (opts.verbose) {\n const cmdName = actionCommand.name();\n process.stderr.write(out.dim(`[verbose] Running: hl ${cmdName}\\n`));\n }\n});\n\nasync function main() {\n try {\n await program.parseAsync(process.argv);\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"API error\")) {\n out.error(e.message);\n } else {\n out.error(`Unexpected error: ${e instanceof Error ? e.message : String(e)}`);\n if (program.opts().verbose) {\n console.error(e);\n }\n }\n process.exit(1);\n }\n}\n\nmain();\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport { loadConfig, saveConfig, clearConfig, configPath, DEFAULT_API_URL } from \"../config.js\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage API authentication\");\n\n auth\n .command(\"login\")\n .description(\"Authenticate with a Hedge Layer API token\")\n .option(\"--api-url <url>\", \"API base URL\", DEFAULT_API_URL)\n .action(async (cmdOpts: { apiUrl?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n try {\n out.heading(\"Hedge Layer CLI — Login\");\n process.stderr.write(\n `Create an API token at ${out.bold(\"https://hedgelayer.ai/settings\")} → API Tokens\\n\\n`,\n );\n\n const token = (await rl.question(\"Paste your API token: \")).trim();\n\n if (!token.startsWith(\"hl_\") || token.length !== 43) {\n out.error('Invalid token format. Tokens start with \"hl_\" and are 43 characters.');\n process.exit(1);\n }\n\n const apiUrl = globalOpts.apiUrl ?? cmdOpts.apiUrl ?? DEFAULT_API_URL;\n const client = new ApiClient({ token, apiUrl });\n\n process.stderr.write(\"\\nValidating token...\");\n let profile: UserProfile;\n try {\n profile = await client.get<UserProfile>(\"/api/profile\");\n } catch {\n process.stderr.write(\"\\n\");\n out.error(\"Token validation failed. Check your token and try again.\");\n process.exit(1);\n }\n process.stderr.write(\" done\\n\\n\");\n\n saveConfig({ api_url: apiUrl, token });\n\n out.success(`Logged in as ${out.bold(profile.handle || profile.user_id)}`);\n process.stderr.write(` Config saved to ${out.dim(configPath())}\\n`);\n } finally {\n rl.close();\n }\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const config = loadConfig();\n const token = globalOpts.token ?? config.token;\n\n if (!token) {\n out.warn(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" to authenticate.\");\n process.exit(1);\n }\n\n const client = new ApiClient(globalOpts);\n\n try {\n const profile = await client.get<UserProfile>(\"/api/profile\");\n if (globalOpts.json) {\n out.json({\n authenticated: true,\n handle: profile.handle,\n user_id: profile.user_id,\n api_url: client.apiUrl,\n });\n } else {\n out.heading(\"Auth Status\");\n out.table(\n [\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"API URL\", client.apiUrl],\n [\"Config\", configPath()],\n ],\n );\n }\n } catch {\n out.error(\"Token is invalid or expired. Run \" + out.bold(\"hl auth login\") + \" to re-authenticate.\");\n process.exit(1);\n }\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored API token\")\n .action(() => {\n clearConfig();\n out.success(\"Logged out. Token removed from \" + out.dim(configPath()));\n });\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst CONFIG_DIR = join(homedir(), \".hedgelayer\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport const DEFAULT_API_URL = \"https://hedgelayer.ai\";\n\nexport interface Config {\n api_url: string;\n token: string | null;\n}\n\nfunction defaultConfig(): Config {\n return { api_url: DEFAULT_API_URL, token: null };\n}\n\nexport function loadConfig(): Config {\n try {\n if (!existsSync(CONFIG_FILE)) return defaultConfig();\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n return {\n api_url: parsed.api_url ?? DEFAULT_API_URL,\n token: parsed.token ?? null,\n };\n } catch {\n return defaultConfig();\n }\n}\n\nexport function saveConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\nexport function clearConfig(): void {\n try {\n if (existsSync(CONFIG_FILE)) unlinkSync(CONFIG_FILE);\n } catch {\n // ignore\n }\n}\n\nexport function configPath(): string {\n return CONFIG_FILE;\n}\n","import type { GlobalOptions } from \"./types.js\";\nimport { loadConfig, DEFAULT_API_URL } from \"./config.js\";\n\nexport class ApiClient {\n private baseUrl: string;\n private token: string | null;\n private verbose: boolean;\n\n constructor(opts: GlobalOptions = {}) {\n const config = loadConfig();\n this.baseUrl = (opts.apiUrl ?? config.api_url ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.token = opts.token ?? config.token ?? null;\n this.verbose = opts.verbose ?? false;\n }\n\n get isAuthenticated(): boolean {\n return this.token !== null;\n }\n\n get apiUrl(): string {\n return this.baseUrl;\n }\n\n private headers(extra: Record<string, string> = {}): Record<string, string> {\n const h: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n if (this.token) {\n h[\"Authorization\"] = `Bearer ${this.token}`;\n }\n return h;\n }\n\n private log(method: string, path: string, status?: number): void {\n if (!this.verbose) return;\n const statusStr = status ? ` → ${status}` : \"\";\n process.stderr.write(`[verbose] ${method} ${this.baseUrl}${path}${statusStr}\\n`);\n }\n\n async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(path, this.baseUrl);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== \"\") url.searchParams.set(k, v);\n }\n }\n\n this.log(\"GET\", `${url.pathname}${url.search}`);\n const res = await fetch(url.toString(), { headers: this.headers() });\n this.log(\"GET\", `${url.pathname}${url.search}`, res.status);\n\n if (!res.ok) {\n const body = await res.text();\n throw new ApiError(res.status, body);\n }\n return res.json() as Promise<T>;\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n this.log(\"POST\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n this.log(\"POST\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n /**\n * POST /api/brief with stream: false — returns the Market Brief JSON body\n * plus optional telemetry from response headers.\n */\n async postBriefSync(query: string): Promise<{\n brief: Record<string, unknown>;\n durationMs: number | null;\n stepsCompleted: number | null;\n toolsUsed: string[];\n }> {\n const path = \"/api/brief\";\n this.log(\"POST\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify({ query, stream: false }),\n });\n this.log(\"POST\", path, res.status);\n\n const text = await res.text();\n if (!res.ok) {\n throw new ApiError(res.status, text);\n }\n\n let brief: Record<string, unknown>;\n try {\n brief = JSON.parse(text) as Record<string, unknown>;\n } catch {\n throw new ApiError(res.status, text || \"Invalid JSON from /api/brief\");\n }\n\n const dur = res.headers.get(\"X-Duration-Ms\");\n const steps = res.headers.get(\"X-Steps-Completed\");\n const tools = res.headers.get(\"X-Tools-Used\");\n\n return {\n brief,\n durationMs: dur != null ? Number(dur) : null,\n stepsCompleted: steps != null ? Number(steps) : null,\n toolsUsed: tools ? tools.split(\",\").filter(Boolean) : [],\n };\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n this.log(\"PATCH\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"PATCH\",\n headers: this.headers(),\n body: JSON.stringify(body),\n });\n this.log(\"PATCH\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n async delete(path: string): Promise<void> {\n this.log(\"DELETE\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"DELETE\",\n headers: this.headers(),\n });\n this.log(\"DELETE\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n }\n\n async stream(path: string, body: unknown): Promise<ReadableStream<Uint8Array>> {\n this.log(\"POST (stream)\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers({ Accept: \"text/event-stream\" }),\n body: JSON.stringify(body),\n });\n this.log(\"POST (stream)\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n if (!res.body) {\n throw new ApiError(0, \"No response body for stream\");\n }\n return res.body;\n }\n\n async streamNdjson(path: string, body: unknown): Promise<ReadableStream<Uint8Array>> {\n this.log(\"POST (ndjson)\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers({ Accept: \"application/x-ndjson\" }),\n body: JSON.stringify(body),\n });\n this.log(\"POST (ndjson)\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n if (!res.body) {\n throw new ApiError(0, \"No response body for stream\");\n }\n return res.body;\n }\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public body: string,\n ) {\n let msg: string;\n try {\n const parsed = JSON.parse(body);\n msg = parsed.error ?? parsed.message ?? body;\n } catch {\n msg = body;\n }\n super(`API error ${status}: ${msg}`);\n this.name = \"ApiError\";\n }\n}\n","import chalk from \"chalk\";\n\nexport function json(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function table(rows: string[][], headers?: string[]): void {\n const allRows = headers ? [headers, ...rows] : rows;\n const colWidths: number[] = [];\n for (const row of allRows) {\n for (let i = 0; i < row.length; i++) {\n colWidths[i] = Math.max(colWidths[i] ?? 0, stripAnsi(row[i]).length);\n }\n }\n\n for (let r = 0; r < allRows.length; r++) {\n const row = allRows[r];\n const padded = row.map((cell, i) => {\n const bare = stripAnsi(cell);\n const pad = colWidths[i] - bare.length;\n return cell + \" \".repeat(Math.max(0, pad));\n });\n process.stdout.write(\" \" + padded.join(\" \") + \"\\n\");\n\n if (r === 0 && headers) {\n const sep = colWidths.map((w) => \"─\".repeat(w)).join(\"──\");\n process.stdout.write(\" \" + sep + \"\\n\");\n }\n }\n}\n\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function heading(text: string): void {\n process.stdout.write(\"\\n\" + chalk.bold(text) + \"\\n\\n\");\n}\n\nexport function success(text: string): void {\n process.stdout.write(chalk.green(\"✓\") + \" \" + text + \"\\n\");\n}\n\nexport function warn(text: string): void {\n process.stdout.write(chalk.yellow(\"⚠\") + \" \" + text + \"\\n\");\n}\n\nexport function error(text: string): void {\n process.stderr.write(chalk.red(\"✗\") + \" \" + text + \"\\n\");\n}\n\nexport function dim(text: string): string {\n return chalk.dim(text);\n}\n\nexport function bold(text: string): string {\n return chalk.bold(text);\n}\n\nexport function currency(n: number): string {\n return \"$\" + n.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n}\n\nexport function compactCurrency(n: number): string {\n if (!n || isNaN(n)) return \"$0\";\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nexport function percent(n: number): string {\n return (n * 100).toFixed(1) + \"%\";\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function relativeTime(date: string): string {\n const diff = Date.now() - new Date(date).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseNdjsonStream } from \"../stream.js\";\nimport type { MarketBrief, BriefRequest, BriefRequestFilters, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerBriefCommands(program: Command): void {\n program\n .command(\"brief <query>\")\n .description(\"Generate a Market Brief for a topic (non-interactive)\")\n .option(\"-l, --location <location>\", \"Geographic context (e.g. 'Middle East', 'US')\")\n .option(\"-t, --time-horizon <horizon>\", \"Time frame (e.g. '3 months', '2026')\")\n .option(\"--tags <tags>\", \"Comma-separated focus area tags (e.g. 'geopolitics,energy')\")\n .option(\"--min-volume <n>\", \"Minimum market volume in USD\", parseFloat)\n .option(\"--max-yes-price <n>\", \"Maximum YES price (0-1)\", parseFloat)\n .action(async (query: string, cmdOpts: BriefCmdOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const filters = buildFilters(cmdOpts);\n const body: BriefRequest = {\n query,\n ...(cmdOpts.location && { location: cmdOpts.location }),\n ...(cmdOpts.timeHorizon && { timeHorizon: cmdOpts.timeHorizon }),\n ...(filters && { filters }),\n stream: true,\n };\n\n await runStreaming(client, body, globalOpts);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Command option types\n// ---------------------------------------------------------------------------\n\ninterface BriefCmdOpts {\n location?: string;\n timeHorizon?: string;\n tags?: string;\n minVolume?: number;\n maxYesPrice?: number;\n}\n\nfunction buildFilters(opts: BriefCmdOpts): BriefRequestFilters | undefined {\n const tags = opts.tags?.split(\",\").map((t) => t.trim()).filter(Boolean);\n const hasFilters = opts.minVolume != null || opts.maxYesPrice != null || (tags && tags.length > 0);\n if (!hasFilters) return undefined;\n return {\n ...(opts.minVolume != null && { minVolume: opts.minVolume }),\n ...(opts.maxYesPrice != null && { maxYesPrice: opts.maxYesPrice }),\n ...(tags && tags.length > 0 && { tags }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Streaming mode (default)\n// ---------------------------------------------------------------------------\n\nasync function runStreaming(client: ApiClient, body: BriefRequest, globalOpts: GlobalOptions): Promise<void> {\n const startTime = Date.now();\n process.stderr.write(chalk.dim(` Generating brief for \"${out.truncate(body.query, 50)}\"...\\n`));\n\n const stream = await client.streamNdjson(\"/api/brief\", body);\n const result = await parseNdjsonStream(stream, {\n onProgress: (step, message) => {\n process.stderr.write(chalk.dim(` [${step}] `) + message + \"\\n\");\n },\n });\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n if (result.error) {\n out.error(`Brief failed (${result.error.code}): ${result.error.message}`);\n process.exit(1);\n }\n\n if (!result.brief) {\n out.error(\"No Market Brief was produced.\");\n process.exit(1);\n }\n\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n displayBrief(result.brief as unknown as MarketBrief, globalOpts);\n}\n\n// ---------------------------------------------------------------------------\n// Display\n// ---------------------------------------------------------------------------\n\nfunction displayBrief(brief: MarketBrief, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(brief);\n return;\n }\n\n out.heading(\"Market Brief\");\n\n process.stdout.write(\" \" + chalk.bold(brief.title) + \"\\n\\n\");\n process.stdout.write(\" \" + chalk.italic(brief.thesis) + \"\\n\");\n\n if (brief.markets.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Markets\") + \"\\n\\n\");\n const rows = brief.markets.map((m) => {\n const prob = out.percent(m.yesPrice);\n const signals = m.signals.length > 0 ? m.signals.join(\", \") : \"—\";\n const liq = m.liquidity ? out.currency(m.liquidity) : \"—\";\n return [out.truncate(m.question, 40), prob, signals, liq];\n });\n out.table(rows, [\"Market\", \"Prob\", \"Signals\", \"Liq\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of brief.markets) {\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 50) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Causal link: \") + m.causalLink + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + m.polymarketUrl + \"\\n\");\n }\n }\n\n if (brief.gaps.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Coverage Gaps\") + \"\\n\\n\");\n for (const gap of brief.gaps) {\n process.stdout.write(\" \" + chalk.yellow(\"▸\") + \" \" + gap + \"\\n\");\n }\n }\n\n const marketCount = brief.marketCount ?? brief.markets.length;\n process.stdout.write(\"\\n \" + chalk.dim(`${marketCount} markets · ${brief.gaps.length} coverage gaps`) + \"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","/**\n * Parses the Vercel AI SDK UI Message Stream protocol (SSE format).\n *\n * The server sends Server-Sent Events where each `data:` line contains\n * a JSON object with a `type` field:\n * text-delta: { type, id, delta }\n * tool-input-start: { type, toolCallId, toolName }\n * tool-input-delta: { type, toolCallId, inputTextDelta }\n * tool-input-available: { type, toolCallId, toolName, input }\n * tool-output-available:{ type, toolCallId, output }\n * error: { type, errorText }\n * [DONE]: stream termination sentinel\n */\n\nexport interface StreamCallbacks {\n onText?: (text: string) => void;\n onToolCall?: (name: string, args: unknown) => void;\n onToolResult?: (name: string, result: unknown) => void;\n}\n\nexport interface StreamResult {\n assistantText: string;\n toolCalls: Array<{ name: string; args: unknown }>;\n marketBrief: Record<string, unknown> | null;\n feedResult: Record<string, unknown> | null;\n}\n\nexport async function parseStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks = {},\n): Promise<StreamResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let assistantText = \"\";\n const toolCalls: Array<{ name: string; args: unknown }> = [];\n const activeToolCalls = new Map<string, { name: string; argStr: string }>();\n let marketBrief: Record<string, unknown> | null = null;\n let feedResult: Record<string, unknown> | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\":\")) continue;\n\n if (!trimmed.startsWith(\"data:\")) continue;\n const payload = trimmed.slice(5).trim();\n\n if (payload === \"[DONE]\") continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(payload);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"text-delta\": {\n const delta = msg.delta as string;\n if (delta) {\n assistantText += delta;\n callbacks.onText?.(delta);\n }\n break;\n }\n\n case \"tool-input-start\": {\n const id = msg.toolCallId as string;\n const name = msg.toolName as string;\n if (id && name) {\n activeToolCalls.set(id, { name, argStr: \"\" });\n }\n break;\n }\n\n case \"tool-input-delta\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n active.argStr += msg.inputTextDelta as string;\n }\n break;\n }\n\n case \"tool-input-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n const args = msg.input ?? active.argStr;\n toolCalls.push({ name: active.name, args });\n callbacks.onToolCall?.(active.name, args);\n }\n break;\n }\n\n case \"tool-output-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n callbacks.onToolResult?.(active.name, msg.output);\n if (active.name === \"buildMarketBrief\" && isMarketBrief(msg.output)) {\n marketBrief = msg.output as Record<string, unknown>;\n }\n if (active.name === \"getFeed\" && isFeedResult(msg.output)) {\n feedResult = msg.output as Record<string, unknown>;\n }\n activeToolCalls.delete(id);\n }\n break;\n }\n\n case \"error\": {\n throw new Error((msg.errorText as string) ?? \"Unknown stream error\");\n }\n }\n }\n\n if (done) break;\n }\n\n return { assistantText, toolCalls, marketBrief, feedResult };\n}\n\nfunction isMarketBrief(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"title\" in (val as Record<string, unknown>) &&\n \"markets\" in (val as Record<string, unknown>)\n );\n}\n\nfunction isFeedResult(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"markets\" in (val as Record<string, unknown>) &&\n \"sortedBy\" in (val as Record<string, unknown>)\n );\n}\n\n// ---------------------------------------------------------------------------\n// NDJSON stream parser (for POST /api/brief)\n// ---------------------------------------------------------------------------\n\nexport interface NdjsonCallbacks {\n onProgress?: (step: string, message: string) => void;\n}\n\nexport interface NdjsonBriefResult {\n brief: Record<string, unknown> | null;\n error: { code: string; message: string } | null;\n}\n\n/**\n * Parses an NDJSON stream from the /api/brief endpoint.\n *\n * Each line is a JSON object with a `type` field:\n * progress: { type, step, message }\n * brief: { type, data: MarketBrief }\n * error: { type, code, message }\n */\nexport async function parseNdjsonStream(\n body: ReadableStream<Uint8Array>,\n callbacks: NdjsonCallbacks = {},\n): Promise<NdjsonBriefResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let brief: Record<string, unknown> | null = null;\n let error: { code: string; message: string } | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"progress\": {\n callbacks.onProgress?.(msg.step as string, msg.message as string);\n break;\n }\n case \"brief\": {\n brief = msg.data as Record<string, unknown>;\n break;\n }\n case \"error\": {\n error = {\n code: msg.code as string,\n message: msg.message as string,\n };\n break;\n }\n }\n }\n\n if (done) break;\n }\n\n return { brief, error };\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerProfileCommand(program: Command): void {\n program\n .command(\"profile\")\n .description(\"Show your user profile\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const profile = await client.get<UserProfile>(\"/api/profile\");\n\n if (globalOpts.json) {\n out.json(profile);\n return;\n }\n\n out.heading(\"Profile\");\n out.table([\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"Created\", new Date(profile.created_at).toLocaleDateString()],\n ]);\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseStream } from \"../stream.js\";\nimport type { Assessment, MarketBrief, FeedResult, GlobalOptions } from \"../types.js\";\nimport { displayFeedResult } from \"../feed-display.js\";\nimport * as out from \"../output.js\";\n\nexport function registerResearchCommands(program: Command): void {\n const research = program.command(\"research\").description(\"AI-powered market research\");\n\n research\n .command(\"start\", { isDefault: true })\n .description(\"Start an interactive market research session\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const { id } = await client.post<{ id: string }>(\"/api/assessments\");\n\n out.heading(\"Market Research\");\n process.stderr.write(\n chalk.dim(\" Describe a topic or thesis to explore. Type /quit to exit.\\n\\n\"),\n );\n\n let msgCounter = 0;\n const uiMsg = (role: string, content: string) => ({\n id: `msg-${++msgCounter}`,\n role,\n content,\n parts: [{ type: \"text\" as const, text: content }],\n });\n\n const messages: ReturnType<typeof uiMsg>[] = [];\n let firstMessageTs: number | null = null;\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n\n try {\n while (true) {\n const userInput = await rl.question(chalk.cyan(\"You: \"));\n if (!userInput.trim()) continue;\n if (userInput.trim() === \"/quit\") break;\n\n if (firstMessageTs === null) firstMessageTs = Date.now();\n messages.push(uiMsg(\"user\", userInput));\n\n process.stderr.write(chalk.dim(\"\\nAssistant: \"));\n\n try {\n const body = await client.stream(\"/api/chat\", {\n messages,\n assessmentId: id,\n });\n\n const result = await parseStream(body, {\n onText: (text) => process.stderr.write(text),\n onToolCall: (name) => {\n process.stderr.write(chalk.dim(`\\n [tool: ${name}]\\n`));\n },\n onToolResult: (name, toolResult) => {\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` [result: ${name}] ${JSON.stringify(toolResult).slice(0, 200)}\\n`));\n }\n },\n });\n\n process.stderr.write(\"\\n\\n\");\n\n if (result.assistantText) {\n messages.push(uiMsg(\"assistant\", result.assistantText));\n }\n\n try {\n await persistAssessment(client, id, messages, result.marketBrief, firstMessageTs);\n } catch (persistErr) {\n out.warn(\n `Could not save session: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}`,\n );\n }\n\n if (result.feedResult) {\n displayFeedResult(result.feedResult as unknown as FeedResult, globalOpts);\n }\n\n if (result.marketBrief) {\n displayMarketBrief(result.marketBrief as unknown as MarketBrief, globalOpts);\n break;\n }\n } catch (e) {\n process.stderr.write(\"\\n\");\n out.error(`Chat error: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n } finally {\n rl.close();\n }\n });\n\n research\n .command(\"run <query>\")\n .description(\"Run research on a topic and return the final Market Brief as JSON (via /api/brief)\")\n .action(async (query: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n process.stderr.write(chalk.dim(` Researching \"${out.truncate(query, 60)}\"...\\n`));\n const startTime = Date.now();\n\n const { brief, durationMs, stepsCompleted, toolsUsed } = await client.postBriefSync(query);\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n\n const looksLikeBrief =\n brief &&\n typeof brief === \"object\" &&\n Array.isArray((brief as { markets?: unknown }).markets) &&\n typeof (brief as { title?: unknown }).title === \"string\";\n\n if (looksLikeBrief) {\n out.json(brief as unknown as MarketBrief);\n } else {\n process.stderr.write(chalk.yellow(\"No market brief was produced.\\n\"));\n out.json({\n brief: null,\n text: null,\n metadata: {\n model: \"\",\n stepsUsed: stepsCompleted ?? 0,\n toolsUsed,\n durationMs: durationMs ?? Date.now() - startTime,\n },\n raw: brief,\n });\n }\n });\n\n research\n .command(\"list\")\n .description(\"List past research sessions\")\n .option(\"-s, --status <status>\", \"Filter by status\")\n .action(async (cmdOpts: { status?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const params: Record<string, string> = { list: \"true\" };\n if (cmdOpts.status) params.status = cmdOpts.status;\n\n const data = await client.get<{ assessments: Assessment[] }>(\"/api/assessments\", params);\n\n if (globalOpts.json) {\n out.json(data.assessments);\n return;\n }\n\n if (data.assessments.length === 0) {\n out.warn(\"No research sessions found.\");\n return;\n }\n\n out.heading(`Research Sessions (${data.assessments.length})`);\n\n const rows = data.assessments.map((a) => {\n const status = formatStatus(a.status);\n const brief = a.market_brief?.title ?? \"—\";\n const markets = a.market_brief ? String(a.market_brief.marketCount) : \"—\";\n return [a.id.slice(0, 8), status, out.truncate(brief, 30), markets, out.relativeTime(a.created_at)];\n });\n\n out.table(rows, [\"ID\", \"Status\", \"Brief\", \"Markets\", \"Created\"]);\n });\n\n research\n .command(\"show <id>\")\n .description(\"Show research session details\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const assessment = await client.get<Assessment>(`/api/assessments/${id}`);\n\n if (globalOpts.json) {\n out.json(assessment);\n return;\n }\n\n out.heading(\"Research Session \" + out.dim(assessment.id.slice(0, 8)));\n\n out.table([\n [\"Status\", formatStatus(assessment.status)],\n [\"Created\", new Date(assessment.created_at).toLocaleString()],\n [\"Updated\", new Date(assessment.updated_at).toLocaleString()],\n ]);\n\n if (assessment.market_brief) {\n displayMarketBrief(assessment.market_brief, globalOpts);\n }\n });\n\n research\n .command(\"delete <id>\")\n .description(\"Delete a research session\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n await client.delete(`/api/assessments/${id}`);\n out.success(\"Research session deleted.\");\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n\n/** Mirrors web ChatInterface assessment PATCH (simplified metadata without tool-part extraction). */\nfunction buildAssessmentPatch(\n messages: unknown[],\n marketBrief: Record<string, unknown> | null,\n firstMessageTs: number | null,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = { messages };\n const meta: Record<string, unknown> = {\n timeToBriefMs: null,\n searchQueries: [],\n searchResultCounts: [],\n coverageHit: false,\n completedAt: null,\n };\n\n if (\n marketBrief &&\n typeof marketBrief === \"object\" &&\n Array.isArray((marketBrief as { markets?: unknown }).markets)\n ) {\n const markets = (marketBrief as { markets: unknown[] }).markets;\n patch.market_brief = marketBrief;\n patch.status = \"completed\";\n meta.timeToBriefMs = firstMessageTs != null ? Date.now() - firstMessageTs : null;\n meta.coverageHit = markets.length > 0;\n meta.completedAt = new Date().toISOString();\n }\n\n patch.metadata = meta;\n return patch;\n}\n\nasync function persistAssessment(\n client: ApiClient,\n assessmentId: string,\n messages: unknown[],\n marketBrief: Record<string, unknown> | null,\n firstMessageTs: number | null,\n): Promise<void> {\n await client.patch(`/api/assessments/${assessmentId}`, buildAssessmentPatch(messages, marketBrief, firstMessageTs));\n}\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case \"completed\":\n return chalk.green(status);\n case \"in_progress\":\n return chalk.yellow(status);\n case \"abandoned\":\n return chalk.red(status);\n default:\n return status;\n }\n}\n\nfunction displayMarketBrief(brief: MarketBrief, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(brief);\n return;\n }\n\n out.heading(\"Market Brief\");\n\n process.stdout.write(\" \" + chalk.bold(brief.title) + \"\\n\\n\");\n process.stdout.write(\" \" + chalk.italic(brief.thesis) + \"\\n\");\n\n if (brief.markets.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Markets\") + \"\\n\\n\");\n const rows = brief.markets.map((m) => {\n const prob = out.percent(m.yesPrice);\n const signals = m.signals.length > 0 ? m.signals.join(\", \") : \"—\";\n const liq = m.liquidity ? out.currency(m.liquidity) : \"—\";\n return [out.truncate(m.question, 40), prob, signals, liq];\n });\n out.table(rows, [\"Market\", \"Prob\", \"Signals\", \"Liq\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of brief.markets) {\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 50) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Causal link: \") + m.causalLink + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + m.polymarketUrl + \"\\n\");\n }\n }\n\n if (brief.gaps.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Coverage Gaps\") + \"\\n\\n\");\n for (const gap of brief.gaps) {\n process.stdout.write(\" \" + chalk.yellow(\"▸\") + \" \" + gap + \"\\n\");\n }\n }\n\n process.stdout.write(\"\\n \" + chalk.dim(`${brief.marketCount} markets · ${brief.gaps.length} coverage gaps`) + \"\\n\");\n}\n","import chalk from \"chalk\";\nimport type { FeedResult, FeedResultMarket, GlobalOptions } from \"./types.js\";\nimport * as out from \"./output.js\";\n\nconst SORT_LABELS: Record<string, string> = {\n score: \"attention score\",\n volume: \"24h volume\",\n liquidity: \"liquidity\",\n movement: \"price movement\",\n spread: \"spread tightness\",\n recency: \"recency\",\n extremity: \"uncertainty\",\n rewards: \"rewards\",\n rewardYield: \"reward yield (per $ liq)\",\n horizon: \"time to resolution\",\n};\n\nfunction scoreBar(score: number): string {\n const width = 15;\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 70 ? chalk.green : score >= 45 ? chalk.yellow : chalk.dim;\n return color(\"█\".repeat(filled)) + chalk.dim(\"░\".repeat(empty)) + ` ${Math.round(score)}`;\n}\n\nexport function displayFeedResult(feed: FeedResult, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(feed);\n return;\n }\n\n const sortLabel = SORT_LABELS[feed.sortedBy] ?? feed.sortedBy;\n out.heading(`Market Feed — ${feed.marketsReturned} markets by ${sortLabel}`);\n process.stdout.write(\n chalk.dim(\n ` ${feed.totalScanned.toLocaleString()} scanned · ${feed.totalAfterFilter.toLocaleString()} after filters · preset ${feed.preset}\\n\\n`,\n ),\n );\n\n if (feed.markets.length === 0) {\n out.warn(\"No markets matched the criteria.\");\n return;\n }\n\n const rows = feed.markets.map((m: FeedResultMarket) => {\n const prob = out.percent(m.yesPrice);\n const change = m.oneDayPriceChange;\n const changeStr =\n change > 0\n ? chalk.green(`+${(change * 100).toFixed(1)}%`)\n : change < 0\n ? chalk.red(`${(change * 100).toFixed(1)}%`)\n : chalk.dim(\"0.0%\");\n return [\n String(m.rank),\n out.truncate(m.question, 42),\n prob,\n String(Math.round(m.score)),\n out.compactCurrency(m.volume24h),\n out.compactCurrency(m.liquidity),\n changeStr,\n ];\n });\n\n out.table(rows, [\"#\", \"Market\", \"Prob\", \"Score\", \"24h Vol\", \"Liq\", \"Chg\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of feed.markets.slice(0, 5)) {\n const url = m.polymarketUrl;\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 55) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Score: \") + scoreBar(m.score) + \" \");\n process.stdout.write(chalk.dim(\"Spread: \") + m.spread.toFixed(3) + \" \");\n if (m.rewardsDailyRate > 0) {\n process.stdout.write(chalk.dim(\"Rewards: \") + `$${m.rewardsDailyRate.toFixed(2)}/day`);\n }\n process.stdout.write(\"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + url + \"\\n\");\n }\n\n if (feed.markets.length > 5) {\n process.stdout.write(chalk.dim(`\\n … and ${feed.markets.length - 5} more\\n`));\n }\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport { displayFeedResult } from \"../feed-display.js\";\nimport type { FeedResult, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\ninterface FeedCmdOpts {\n profile?: string;\n sortBy?: string;\n preset?: string;\n tag?: string;\n minVolume?: string;\n minLiquidity?: string;\n maxLiquidity?: string;\n minRewardsDailyRate?: string;\n minDaysToEnd?: string;\n maxDaysToEnd?: string;\n maxMarketAgeHours?: string;\n liquidProfile?: string;\n limit?: string;\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not authenticated. Run `hl auth login` first.\");\n process.exit(1);\n }\n}\n\nconst PROFILE_CHOICES = [\"lp-opportunity\", \"liquid-new-or-long\"] as const;\n\nfunction isProfile(s: string | undefined): s is (typeof PROFILE_CHOICES)[number] {\n return s !== undefined && (PROFILE_CHOICES as readonly string[]).includes(s);\n}\n\n/**\n * Build query params for GET /api/feed. Omits undefined / empty string.\n */\nfunction feedQueryParams(opts: {\n profile?: string;\n sortBy?: string;\n preset?: string;\n tag?: string;\n minVolume?: string;\n minLiquidity?: string;\n maxLiquidity?: string;\n minRewardsDailyRate?: string;\n minDaysToEnd?: string;\n maxDaysToEnd?: string;\n maxMarketAgeHours?: string;\n liquidProfile?: string;\n limit?: string;\n}): Record<string, string> {\n const entries: [string, string][] = [];\n const add = (k: string, v: string | undefined) => {\n if (v !== undefined && v !== \"\") entries.push([k, v]);\n };\n add(\"profile\", opts.profile);\n add(\"sortBy\", opts.sortBy);\n add(\"preset\", opts.preset);\n add(\"tag\", opts.tag);\n add(\"minVolume\", opts.minVolume);\n add(\"minLiquidity\", opts.minLiquidity);\n add(\"maxLiquidity\", opts.maxLiquidity);\n add(\"minRewardsDailyRate\", opts.minRewardsDailyRate);\n add(\"minDaysToEnd\", opts.minDaysToEnd);\n add(\"maxDaysToEnd\", opts.maxDaysToEnd);\n add(\"maxMarketAgeHours\", opts.maxMarketAgeHours);\n add(\"liquidProfile\", opts.liquidProfile);\n add(\"limit\", opts.limit);\n return Object.fromEntries(entries);\n}\n\nexport function registerFeedCommand(program: Command): void {\n program\n .command(\"feed\")\n .description(\n \"Rank active Polymarket markets (same engine as chat getFeed / GET /api/feed). \" +\n \"Use --profile for curated screens.\",\n )\n .argument(\n \"[screening]\",\n `Optional screening preset: ${PROFILE_CHOICES.join(\" | \")} (same as --profile)`,\n )\n .option(\n \"--profile <name>\",\n `Screening defaults: ${PROFILE_CHOICES.join(\", \")} — explicit flags override`,\n )\n .option(\"--sort-by <key>\", \"score | volume | liquidity | movement | spread | recency | extremity | rewards | rewardYield | horizon\")\n .option(\"--preset <name>\", \"Attention weight preset (default, volume-hunter, lp-opportunity, …)\")\n .option(\"--tag <slug>\", \"Polymarket category tag, e.g. crypto, politics\")\n .option(\"--min-volume <usd>\", \"Minimum 24h volume (USD)\")\n .option(\"--min-liquidity <usd>\", \"Minimum displayed liquidity (USD)\")\n .option(\"--max-liquidity <usd>\", \"Maximum displayed liquidity (USD)\")\n .option(\"--min-rewards-daily-rate <usd>\", \"Minimum LP rewards USD/day\")\n .option(\"--min-days-to-end <n>\", \"Min calendar days until resolution\")\n .option(\"--max-days-to-end <n>\", \"Max calendar days until resolution\")\n .option(\"--max-market-age-hours <n>\", \"With liquid-new-or-long: max age (hours) for the \\\"new\\\" branch\")\n .option(\"--liquid-profile <mode>\", \"new-or-long (used by liquid-new-or-long screen)\")\n .option(\"--limit <n>\", \"Max markets to return (1–100, default 15)\", \"15\")\n .action(async (screening: string | undefined, o: FeedCmdOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n\n let profile = o.profile;\n if (screening) {\n if (!isProfile(screening)) {\n out.error(`Unknown screening \"${screening}\". Use: ${PROFILE_CHOICES.join(\" or \")}`);\n process.exit(1);\n }\n if (profile && profile !== screening) {\n out.warn(`Both positional and --profile set; using --profile (${profile}).`);\n } else if (!profile) {\n profile = screening;\n }\n }\n\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const params = feedQueryParams({\n profile,\n sortBy: o.sortBy,\n preset: o.preset,\n tag: o.tag,\n minVolume: o.minVolume,\n minLiquidity: o.minLiquidity,\n maxLiquidity: o.maxLiquidity,\n minRewardsDailyRate: o.minRewardsDailyRate,\n minDaysToEnd: o.minDaysToEnd,\n maxDaysToEnd: o.maxDaysToEnd,\n maxMarketAgeHours: o.maxMarketAgeHours,\n liquidProfile: o.liquidProfile,\n limit: o.limit,\n });\n\n try {\n const result = await client.get<FeedResult>(\"/api/feed\", params);\n if (result.error) {\n out.error(result.error);\n process.exit(1);\n }\n displayFeedResult(result, globalOpts);\n } catch (e) {\n out.error(e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["program","chalk","error","program","chalk","program","requireAuth","readline","chalk","chalk","chalk","program","requireAuth","chalk","readline","requireAuth","program"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/client.ts","../src/output.ts","../src/commands/brief.ts","../src/stream.ts","../src/commands/profile.ts","../src/commands/research.ts","../src/feed-display.ts","../src/commands/feed.ts","../src/commands/allocator.ts","../src/allocator-display.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerBriefCommands } from \"./commands/brief.js\";\n\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerResearchCommands } from \"./commands/research.js\";\nimport { registerFeedCommand } from \"./commands/feed.js\";\nimport { registerAllocatorCommands } from \"./commands/allocator.js\";\nimport * as out from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"hl\")\n .description(\"Hedge Layer CLI — prediction market intelligence from the terminal\")\n .version(__VERSION__)\n .option(\"--json\", \"Output as JSON (machine-readable)\")\n .option(\"--api-url <url>\", \"Override API base URL\")\n .option(\"--token <token>\", \"Override stored API token\")\n .option(\"--verbose\", \"Show HTTP request details\")\n .option(\"--no-color\", \"Disable colored output\");\n\nregisterAuthCommands(program);\nregisterBriefCommands(program);\n\nregisterProfileCommand(program);\nregisterResearchCommands(program);\nregisterFeedCommand(program);\nregisterAllocatorCommands(program);\n\nprogram.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const opts = program.opts();\n if (opts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n if (opts.verbose) {\n const cmdName = actionCommand.name();\n process.stderr.write(out.dim(`[verbose] Running: hl ${cmdName}\\n`));\n }\n});\n\nasync function main() {\n try {\n await program.parseAsync(process.argv);\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"API error\")) {\n out.error(e.message);\n } else {\n out.error(`Unexpected error: ${e instanceof Error ? e.message : String(e)}`);\n if (program.opts().verbose) {\n console.error(e);\n }\n }\n process.exit(1);\n }\n}\n\nmain();\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport { loadConfig, saveConfig, clearConfig, configPath, DEFAULT_API_URL } from \"../config.js\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage API authentication\");\n\n auth\n .command(\"login\")\n .description(\"Authenticate with a Hedge Layer API token\")\n .option(\"--api-url <url>\", \"API base URL\", DEFAULT_API_URL)\n .action(async (cmdOpts: { apiUrl?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n try {\n out.heading(\"Hedge Layer CLI — Login\");\n process.stderr.write(\n `Create an API token at ${out.bold(\"https://hedgelayer.ai/account/settings\")} → API Tokens\\n\\n`,\n );\n\n const token = (await rl.question(\"Paste your API token: \")).trim();\n\n if (!token.startsWith(\"hl_\") || token.length !== 43) {\n out.error('Invalid token format. Tokens start with \"hl_\" and are 43 characters.');\n process.exit(1);\n }\n\n const apiUrl = globalOpts.apiUrl ?? cmdOpts.apiUrl ?? DEFAULT_API_URL;\n const client = new ApiClient({ token, apiUrl });\n\n process.stderr.write(\"\\nValidating token...\");\n let profile: UserProfile;\n try {\n profile = await client.get<UserProfile>(\"/api/profile\");\n } catch {\n process.stderr.write(\"\\n\");\n out.error(\"Token validation failed. Check your token and try again.\");\n process.exit(1);\n }\n process.stderr.write(\" done\\n\\n\");\n\n saveConfig({ api_url: apiUrl, token });\n\n out.success(`Logged in as ${out.bold(profile.handle || profile.user_id)}`);\n process.stderr.write(` Config saved to ${out.dim(configPath())}\\n`);\n } finally {\n rl.close();\n }\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const config = loadConfig();\n const token = globalOpts.token ?? config.token;\n\n if (!token) {\n out.warn(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" to authenticate.\");\n process.exit(1);\n }\n\n const client = new ApiClient(globalOpts);\n\n try {\n const profile = await client.get<UserProfile>(\"/api/profile\");\n if (globalOpts.json) {\n out.json({\n authenticated: true,\n handle: profile.handle,\n user_id: profile.user_id,\n api_url: client.apiUrl,\n });\n } else {\n out.heading(\"Auth Status\");\n out.table(\n [\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"API URL\", client.apiUrl],\n [\"Config\", configPath()],\n ],\n );\n }\n } catch {\n out.error(\"Token is invalid or expired. Run \" + out.bold(\"hl auth login\") + \" to re-authenticate.\");\n process.exit(1);\n }\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored API token\")\n .action(() => {\n clearConfig();\n out.success(\"Logged out. Token removed from \" + out.dim(configPath()));\n });\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst CONFIG_DIR = join(homedir(), \".hedgelayer\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport const DEFAULT_API_URL = \"https://hedgelayer.ai\";\n\nexport interface Config {\n api_url: string;\n token: string | null;\n}\n\nfunction defaultConfig(): Config {\n return { api_url: DEFAULT_API_URL, token: null };\n}\n\nexport function loadConfig(): Config {\n try {\n if (!existsSync(CONFIG_FILE)) return defaultConfig();\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n return {\n api_url: parsed.api_url ?? DEFAULT_API_URL,\n token: parsed.token ?? null,\n };\n } catch {\n return defaultConfig();\n }\n}\n\nexport function saveConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\nexport function clearConfig(): void {\n try {\n if (existsSync(CONFIG_FILE)) unlinkSync(CONFIG_FILE);\n } catch {\n // ignore\n }\n}\n\nexport function configPath(): string {\n return CONFIG_FILE;\n}\n","import type { GlobalOptions } from \"./types.js\";\nimport { loadConfig, DEFAULT_API_URL } from \"./config.js\";\n\nexport class ApiClient {\n private baseUrl: string;\n private token: string | null;\n private verbose: boolean;\n\n constructor(opts: GlobalOptions = {}) {\n const config = loadConfig();\n this.baseUrl = (opts.apiUrl ?? config.api_url ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.token = opts.token ?? config.token ?? null;\n this.verbose = opts.verbose ?? false;\n }\n\n get isAuthenticated(): boolean {\n return this.token !== null;\n }\n\n get apiUrl(): string {\n return this.baseUrl;\n }\n\n private headers(extra: Record<string, string> = {}): Record<string, string> {\n const h: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n if (this.token) {\n h[\"Authorization\"] = `Bearer ${this.token}`;\n }\n return h;\n }\n\n private log(method: string, path: string, status?: number): void {\n if (!this.verbose) return;\n const statusStr = status ? ` → ${status}` : \"\";\n process.stderr.write(`[verbose] ${method} ${this.baseUrl}${path}${statusStr}\\n`);\n }\n\n async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(path, this.baseUrl);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== \"\") url.searchParams.set(k, v);\n }\n }\n\n this.log(\"GET\", `${url.pathname}${url.search}`);\n const res = await fetch(url.toString(), { headers: this.headers() });\n this.log(\"GET\", `${url.pathname}${url.search}`, res.status);\n\n if (!res.ok) {\n const body = await res.text();\n throw new ApiError(res.status, body);\n }\n return res.json() as Promise<T>;\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n this.log(\"POST\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n this.log(\"POST\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n /**\n * POST /api/brief with stream: false — returns the Market Brief JSON body\n * plus optional telemetry from response headers.\n */\n async postBriefSync(query: string): Promise<{\n brief: Record<string, unknown>;\n durationMs: number | null;\n stepsCompleted: number | null;\n toolsUsed: string[];\n }> {\n const path = \"/api/brief\";\n this.log(\"POST\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify({ query, stream: false }),\n });\n this.log(\"POST\", path, res.status);\n\n const text = await res.text();\n if (!res.ok) {\n throw new ApiError(res.status, text);\n }\n\n let brief: Record<string, unknown>;\n try {\n brief = JSON.parse(text) as Record<string, unknown>;\n } catch {\n throw new ApiError(res.status, text || \"Invalid JSON from /api/brief\");\n }\n\n const dur = res.headers.get(\"X-Duration-Ms\");\n const steps = res.headers.get(\"X-Steps-Completed\");\n const tools = res.headers.get(\"X-Tools-Used\");\n\n return {\n brief,\n durationMs: dur != null ? Number(dur) : null,\n stepsCompleted: steps != null ? Number(steps) : null,\n toolsUsed: tools ? tools.split(\",\").filter(Boolean) : [],\n };\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n this.log(\"PATCH\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"PATCH\",\n headers: this.headers(),\n body: JSON.stringify(body),\n });\n this.log(\"PATCH\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n async delete(path: string): Promise<void> {\n this.log(\"DELETE\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"DELETE\",\n headers: this.headers(),\n });\n this.log(\"DELETE\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n }\n\n async stream(path: string, body: unknown): Promise<ReadableStream<Uint8Array>> {\n this.log(\"POST (stream)\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers({ Accept: \"text/event-stream\" }),\n body: JSON.stringify(body),\n });\n this.log(\"POST (stream)\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n if (!res.body) {\n throw new ApiError(0, \"No response body for stream\");\n }\n return res.body;\n }\n\n async streamNdjson(path: string, body: unknown): Promise<ReadableStream<Uint8Array>> {\n this.log(\"POST (ndjson)\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers({ Accept: \"application/x-ndjson\" }),\n body: JSON.stringify(body),\n });\n this.log(\"POST (ndjson)\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n if (!res.body) {\n throw new ApiError(0, \"No response body for stream\");\n }\n return res.body;\n }\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public body: string,\n ) {\n let msg: string;\n try {\n const parsed = JSON.parse(body);\n msg = parsed.error ?? parsed.message ?? body;\n } catch {\n msg = body;\n }\n super(`API error ${status}: ${msg}`);\n this.name = \"ApiError\";\n }\n}\n","import chalk from \"chalk\";\n\nexport function json(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function table(rows: string[][], headers?: string[]): void {\n const allRows = headers ? [headers, ...rows] : rows;\n const colWidths: number[] = [];\n for (const row of allRows) {\n for (let i = 0; i < row.length; i++) {\n colWidths[i] = Math.max(colWidths[i] ?? 0, stripAnsi(row[i]).length);\n }\n }\n\n for (let r = 0; r < allRows.length; r++) {\n const row = allRows[r];\n const padded = row.map((cell, i) => {\n const bare = stripAnsi(cell);\n const pad = colWidths[i] - bare.length;\n return cell + \" \".repeat(Math.max(0, pad));\n });\n process.stdout.write(\" \" + padded.join(\" \") + \"\\n\");\n\n if (r === 0 && headers) {\n const sep = colWidths.map((w) => \"─\".repeat(w)).join(\"──\");\n process.stdout.write(\" \" + sep + \"\\n\");\n }\n }\n}\n\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function heading(text: string): void {\n process.stdout.write(\"\\n\" + chalk.bold(text) + \"\\n\\n\");\n}\n\nexport function success(text: string): void {\n process.stdout.write(chalk.green(\"✓\") + \" \" + text + \"\\n\");\n}\n\nexport function warn(text: string): void {\n process.stdout.write(chalk.yellow(\"⚠\") + \" \" + text + \"\\n\");\n}\n\nexport function error(text: string): void {\n process.stderr.write(chalk.red(\"✗\") + \" \" + text + \"\\n\");\n}\n\nexport function dim(text: string): string {\n return chalk.dim(text);\n}\n\nexport function bold(text: string): string {\n return chalk.bold(text);\n}\n\nexport function currency(n: number): string {\n return \"$\" + n.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n}\n\nexport function compactCurrency(n: number): string {\n if (!n || isNaN(n)) return \"$0\";\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nexport function percent(n: number): string {\n return (n * 100).toFixed(1) + \"%\";\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function relativeTime(date: string): string {\n const diff = Date.now() - new Date(date).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseNdjsonStream } from \"../stream.js\";\nimport type { MarketBrief, BriefRequest, BriefRequestFilters, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerBriefCommands(program: Command): void {\n program\n .command(\"brief <query>\")\n .description(\"Generate a Market Brief for a topic (non-interactive)\")\n .option(\"-l, --location <location>\", \"Geographic context (e.g. 'Middle East', 'US')\")\n .option(\"-t, --time-horizon <horizon>\", \"Time frame (e.g. '3 months', '2026')\")\n .option(\"--tags <tags>\", \"Comma-separated focus area tags (e.g. 'geopolitics,energy')\")\n .option(\"--min-volume <n>\", \"Minimum market volume in USD\", parseFloat)\n .option(\"--max-yes-price <n>\", \"Maximum YES price (0-1)\", parseFloat)\n .action(async (query: string, cmdOpts: BriefCmdOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const filters = buildFilters(cmdOpts);\n const body: BriefRequest = {\n query,\n ...(cmdOpts.location && { location: cmdOpts.location }),\n ...(cmdOpts.timeHorizon && { timeHorizon: cmdOpts.timeHorizon }),\n ...(filters && { filters }),\n stream: true,\n };\n\n await runStreaming(client, body, globalOpts);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Command option types\n// ---------------------------------------------------------------------------\n\ninterface BriefCmdOpts {\n location?: string;\n timeHorizon?: string;\n tags?: string;\n minVolume?: number;\n maxYesPrice?: number;\n}\n\nfunction buildFilters(opts: BriefCmdOpts): BriefRequestFilters | undefined {\n const tags = opts.tags?.split(\",\").map((t) => t.trim()).filter(Boolean);\n const hasFilters = opts.minVolume != null || opts.maxYesPrice != null || (tags && tags.length > 0);\n if (!hasFilters) return undefined;\n return {\n ...(opts.minVolume != null && { minVolume: opts.minVolume }),\n ...(opts.maxYesPrice != null && { maxYesPrice: opts.maxYesPrice }),\n ...(tags && tags.length > 0 && { tags }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Streaming mode (default)\n// ---------------------------------------------------------------------------\n\nasync function runStreaming(client: ApiClient, body: BriefRequest, globalOpts: GlobalOptions): Promise<void> {\n const startTime = Date.now();\n process.stderr.write(chalk.dim(` Generating brief for \"${out.truncate(body.query, 50)}\"...\\n`));\n\n const stream = await client.streamNdjson(\"/api/brief\", body);\n const result = await parseNdjsonStream(stream, {\n onProgress: (step, message) => {\n process.stderr.write(chalk.dim(` [${step}] `) + message + \"\\n\");\n },\n });\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n if (result.error) {\n out.error(`Brief failed (${result.error.code}): ${result.error.message}`);\n process.exit(1);\n }\n\n if (!result.brief) {\n out.error(\"No Market Brief was produced.\");\n process.exit(1);\n }\n\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n displayBrief(result.brief as unknown as MarketBrief, globalOpts);\n}\n\n// ---------------------------------------------------------------------------\n// Display\n// ---------------------------------------------------------------------------\n\nfunction displayBrief(brief: MarketBrief, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(brief);\n return;\n }\n\n out.heading(\"Market Brief\");\n\n process.stdout.write(\" \" + chalk.bold(brief.title) + \"\\n\\n\");\n process.stdout.write(\" \" + chalk.italic(brief.thesis) + \"\\n\");\n\n if (brief.markets.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Markets\") + \"\\n\\n\");\n const rows = brief.markets.map((m) => {\n const prob = out.percent(m.yesPrice);\n const signals = m.signals.length > 0 ? m.signals.join(\", \") : \"—\";\n const liq = m.liquidity ? out.currency(m.liquidity) : \"—\";\n return [out.truncate(m.question, 40), prob, signals, liq];\n });\n out.table(rows, [\"Market\", \"Prob\", \"Signals\", \"Liq\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of brief.markets) {\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 50) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Causal link: \") + m.causalLink + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + m.polymarketUrl + \"\\n\");\n }\n }\n\n if (brief.gaps.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Coverage Gaps\") + \"\\n\\n\");\n for (const gap of brief.gaps) {\n process.stdout.write(\" \" + chalk.yellow(\"▸\") + \" \" + gap + \"\\n\");\n }\n }\n\n const marketCount = brief.marketCount ?? brief.markets.length;\n process.stdout.write(\"\\n \" + chalk.dim(`${marketCount} markets · ${brief.gaps.length} coverage gaps`) + \"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","/**\n * Parses the Vercel AI SDK UI Message Stream protocol (SSE format).\n *\n * The server sends Server-Sent Events where each `data:` line contains\n * a JSON object with a `type` field:\n * text-delta: { type, id, delta }\n * tool-input-start: { type, toolCallId, toolName }\n * tool-input-delta: { type, toolCallId, inputTextDelta }\n * tool-input-available: { type, toolCallId, toolName, input }\n * tool-output-available:{ type, toolCallId, output }\n * error: { type, errorText }\n * [DONE]: stream termination sentinel\n */\n\nexport interface StreamCallbacks {\n onText?: (text: string) => void;\n onToolCall?: (name: string, args: unknown) => void;\n onToolResult?: (name: string, result: unknown) => void;\n}\n\nexport interface StreamResult {\n assistantText: string;\n toolCalls: Array<{ name: string; args: unknown }>;\n marketBrief: Record<string, unknown> | null;\n feedResult: Record<string, unknown> | null;\n}\n\nexport async function parseStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks = {},\n): Promise<StreamResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let assistantText = \"\";\n const toolCalls: Array<{ name: string; args: unknown }> = [];\n const activeToolCalls = new Map<string, { name: string; argStr: string }>();\n let marketBrief: Record<string, unknown> | null = null;\n let feedResult: Record<string, unknown> | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\":\")) continue;\n\n if (!trimmed.startsWith(\"data:\")) continue;\n const payload = trimmed.slice(5).trim();\n\n if (payload === \"[DONE]\") continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(payload);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"text-delta\": {\n const delta = msg.delta as string;\n if (delta) {\n assistantText += delta;\n callbacks.onText?.(delta);\n }\n break;\n }\n\n case \"tool-input-start\": {\n const id = msg.toolCallId as string;\n const name = msg.toolName as string;\n if (id && name) {\n activeToolCalls.set(id, { name, argStr: \"\" });\n }\n break;\n }\n\n case \"tool-input-delta\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n active.argStr += msg.inputTextDelta as string;\n }\n break;\n }\n\n case \"tool-input-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n const args = msg.input ?? active.argStr;\n toolCalls.push({ name: active.name, args });\n callbacks.onToolCall?.(active.name, args);\n }\n break;\n }\n\n case \"tool-output-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n callbacks.onToolResult?.(active.name, msg.output);\n if (active.name === \"buildMarketBrief\" && isMarketBrief(msg.output)) {\n marketBrief = msg.output as Record<string, unknown>;\n }\n if (active.name === \"getFeed\" && isFeedResult(msg.output)) {\n feedResult = msg.output as Record<string, unknown>;\n }\n activeToolCalls.delete(id);\n }\n break;\n }\n\n case \"error\": {\n throw new Error((msg.errorText as string) ?? \"Unknown stream error\");\n }\n }\n }\n\n if (done) break;\n }\n\n return { assistantText, toolCalls, marketBrief, feedResult };\n}\n\nfunction isMarketBrief(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"title\" in (val as Record<string, unknown>) &&\n \"markets\" in (val as Record<string, unknown>)\n );\n}\n\nfunction isFeedResult(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"markets\" in (val as Record<string, unknown>) &&\n \"sortedBy\" in (val as Record<string, unknown>)\n );\n}\n\n// ---------------------------------------------------------------------------\n// NDJSON stream parser (for POST /api/brief)\n// ---------------------------------------------------------------------------\n\nexport interface NdjsonCallbacks {\n onProgress?: (step: string, message: string) => void;\n}\n\nexport interface NdjsonBriefResult {\n brief: Record<string, unknown> | null;\n error: { code: string; message: string } | null;\n}\n\n/**\n * Parses an NDJSON stream from the /api/brief endpoint.\n *\n * Each line is a JSON object with a `type` field:\n * progress: { type, step, message }\n * brief: { type, data: MarketBrief }\n * error: { type, code, message }\n */\nexport async function parseNdjsonStream(\n body: ReadableStream<Uint8Array>,\n callbacks: NdjsonCallbacks = {},\n): Promise<NdjsonBriefResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let brief: Record<string, unknown> | null = null;\n let error: { code: string; message: string } | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"progress\": {\n callbacks.onProgress?.(msg.step as string, msg.message as string);\n break;\n }\n case \"brief\": {\n brief = msg.data as Record<string, unknown>;\n break;\n }\n case \"error\": {\n error = {\n code: msg.code as string,\n message: msg.message as string,\n };\n break;\n }\n }\n }\n\n if (done) break;\n }\n\n return { brief, error };\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerProfileCommand(program: Command): void {\n program\n .command(\"profile\")\n .description(\"Show your user profile\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const profile = await client.get<UserProfile>(\"/api/profile\");\n\n if (globalOpts.json) {\n out.json(profile);\n return;\n }\n\n out.heading(\"Profile\");\n out.table([\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"Created\", new Date(profile.created_at).toLocaleDateString()],\n ]);\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseStream } from \"../stream.js\";\nimport type { Assessment, MarketBrief, FeedResult, GlobalOptions } from \"../types.js\";\nimport { displayFeedResult } from \"../feed-display.js\";\nimport * as out from \"../output.js\";\n\nexport function registerResearchCommands(program: Command): void {\n const research = program.command(\"research\").description(\"AI-powered market research\");\n\n research\n .command(\"start\", { isDefault: true })\n .description(\"Start an interactive market research session\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const { id } = await client.post<{ id: string }>(\"/api/assessments\");\n\n out.heading(\"Market Research\");\n process.stderr.write(\n chalk.dim(\" Describe a topic or thesis to explore. Type /quit to exit.\\n\\n\"),\n );\n\n let msgCounter = 0;\n const uiMsg = (role: string, content: string) => ({\n id: `msg-${++msgCounter}`,\n role,\n content,\n parts: [{ type: \"text\" as const, text: content }],\n });\n\n const messages: ReturnType<typeof uiMsg>[] = [];\n let firstMessageTs: number | null = null;\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n\n try {\n while (true) {\n const userInput = await rl.question(chalk.cyan(\"You: \"));\n if (!userInput.trim()) continue;\n if (userInput.trim() === \"/quit\") break;\n\n if (firstMessageTs === null) firstMessageTs = Date.now();\n messages.push(uiMsg(\"user\", userInput));\n\n process.stderr.write(chalk.dim(\"\\nAssistant: \"));\n\n try {\n const body = await client.stream(\"/api/chat\", {\n messages,\n assessmentId: id,\n });\n\n const result = await parseStream(body, {\n onText: (text) => process.stderr.write(text),\n onToolCall: (name) => {\n process.stderr.write(chalk.dim(`\\n [tool: ${name}]\\n`));\n },\n onToolResult: (name, toolResult) => {\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` [result: ${name}] ${JSON.stringify(toolResult).slice(0, 200)}\\n`));\n }\n },\n });\n\n process.stderr.write(\"\\n\\n\");\n\n if (result.assistantText) {\n messages.push(uiMsg(\"assistant\", result.assistantText));\n }\n\n try {\n await persistAssessment(client, id, messages, result.marketBrief, firstMessageTs);\n } catch (persistErr) {\n out.warn(\n `Could not save session: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}`,\n );\n }\n\n if (result.feedResult) {\n displayFeedResult(result.feedResult as unknown as FeedResult, globalOpts);\n }\n\n if (result.marketBrief) {\n displayMarketBrief(result.marketBrief as unknown as MarketBrief, globalOpts);\n break;\n }\n } catch (e) {\n process.stderr.write(\"\\n\");\n out.error(`Chat error: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n } finally {\n rl.close();\n }\n });\n\n research\n .command(\"run <query>\")\n .description(\"Run research on a topic and return the final Market Brief as JSON (via /api/brief)\")\n .action(async (query: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n process.stderr.write(chalk.dim(` Researching \"${out.truncate(query, 60)}\"...\\n`));\n const startTime = Date.now();\n\n const { brief, durationMs, stepsCompleted, toolsUsed } = await client.postBriefSync(query);\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n\n const looksLikeBrief =\n brief &&\n typeof brief === \"object\" &&\n Array.isArray((brief as { markets?: unknown }).markets) &&\n typeof (brief as { title?: unknown }).title === \"string\";\n\n if (looksLikeBrief) {\n out.json(brief as unknown as MarketBrief);\n } else {\n process.stderr.write(chalk.yellow(\"No market brief was produced.\\n\"));\n out.json({\n brief: null,\n text: null,\n metadata: {\n model: \"\",\n stepsUsed: stepsCompleted ?? 0,\n toolsUsed,\n durationMs: durationMs ?? Date.now() - startTime,\n },\n raw: brief,\n });\n }\n });\n\n research\n .command(\"list\")\n .description(\"List past research sessions\")\n .option(\"-s, --status <status>\", \"Filter by status\")\n .action(async (cmdOpts: { status?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const params: Record<string, string> = { list: \"true\" };\n if (cmdOpts.status) params.status = cmdOpts.status;\n\n const data = await client.get<{ assessments: Assessment[] }>(\"/api/assessments\", params);\n\n if (globalOpts.json) {\n out.json(data.assessments);\n return;\n }\n\n if (data.assessments.length === 0) {\n out.warn(\"No research sessions found.\");\n return;\n }\n\n out.heading(`Research Sessions (${data.assessments.length})`);\n\n const rows = data.assessments.map((a) => {\n const status = formatStatus(a.status);\n const brief = a.market_brief?.title ?? \"—\";\n const markets = a.market_brief ? String(a.market_brief.marketCount) : \"—\";\n return [a.id.slice(0, 8), status, out.truncate(brief, 30), markets, out.relativeTime(a.created_at)];\n });\n\n out.table(rows, [\"ID\", \"Status\", \"Brief\", \"Markets\", \"Created\"]);\n });\n\n research\n .command(\"show <id>\")\n .description(\"Show research session details\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const assessment = await client.get<Assessment>(`/api/assessments/${id}`);\n\n if (globalOpts.json) {\n out.json(assessment);\n return;\n }\n\n out.heading(\"Research Session \" + out.dim(assessment.id.slice(0, 8)));\n\n out.table([\n [\"Status\", formatStatus(assessment.status)],\n [\"Created\", new Date(assessment.created_at).toLocaleString()],\n [\"Updated\", new Date(assessment.updated_at).toLocaleString()],\n ]);\n\n if (assessment.market_brief) {\n displayMarketBrief(assessment.market_brief, globalOpts);\n }\n });\n\n research\n .command(\"delete <id>\")\n .description(\"Delete a research session\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n await client.delete(`/api/assessments/${id}`);\n out.success(\"Research session deleted.\");\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n\n/** Mirrors web ChatInterface assessment PATCH (simplified metadata without tool-part extraction). */\nfunction buildAssessmentPatch(\n messages: unknown[],\n marketBrief: Record<string, unknown> | null,\n firstMessageTs: number | null,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = { messages };\n const meta: Record<string, unknown> = {\n timeToBriefMs: null,\n searchQueries: [],\n searchResultCounts: [],\n coverageHit: false,\n completedAt: null,\n };\n\n if (\n marketBrief &&\n typeof marketBrief === \"object\" &&\n Array.isArray((marketBrief as { markets?: unknown }).markets)\n ) {\n const markets = (marketBrief as { markets: unknown[] }).markets;\n patch.market_brief = marketBrief;\n patch.status = \"completed\";\n meta.timeToBriefMs = firstMessageTs != null ? Date.now() - firstMessageTs : null;\n meta.coverageHit = markets.length > 0;\n meta.completedAt = new Date().toISOString();\n }\n\n patch.metadata = meta;\n return patch;\n}\n\nasync function persistAssessment(\n client: ApiClient,\n assessmentId: string,\n messages: unknown[],\n marketBrief: Record<string, unknown> | null,\n firstMessageTs: number | null,\n): Promise<void> {\n await client.patch(`/api/assessments/${assessmentId}`, buildAssessmentPatch(messages, marketBrief, firstMessageTs));\n}\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case \"completed\":\n return chalk.green(status);\n case \"in_progress\":\n return chalk.yellow(status);\n case \"abandoned\":\n return chalk.red(status);\n default:\n return status;\n }\n}\n\nfunction displayMarketBrief(brief: MarketBrief, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(brief);\n return;\n }\n\n out.heading(\"Market Brief\");\n\n process.stdout.write(\" \" + chalk.bold(brief.title) + \"\\n\\n\");\n process.stdout.write(\" \" + chalk.italic(brief.thesis) + \"\\n\");\n\n if (brief.markets.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Markets\") + \"\\n\\n\");\n const rows = brief.markets.map((m) => {\n const prob = out.percent(m.yesPrice);\n const signals = m.signals.length > 0 ? m.signals.join(\", \") : \"—\";\n const liq = m.liquidity ? out.currency(m.liquidity) : \"—\";\n return [out.truncate(m.question, 40), prob, signals, liq];\n });\n out.table(rows, [\"Market\", \"Prob\", \"Signals\", \"Liq\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of brief.markets) {\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 50) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Causal link: \") + m.causalLink + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + m.polymarketUrl + \"\\n\");\n }\n }\n\n if (brief.gaps.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Coverage Gaps\") + \"\\n\\n\");\n for (const gap of brief.gaps) {\n process.stdout.write(\" \" + chalk.yellow(\"▸\") + \" \" + gap + \"\\n\");\n }\n }\n\n process.stdout.write(\"\\n \" + chalk.dim(`${brief.marketCount} markets · ${brief.gaps.length} coverage gaps`) + \"\\n\");\n}\n","import chalk from \"chalk\";\nimport type { FeedResult, FeedResultMarket, GlobalOptions } from \"./types.js\";\nimport * as out from \"./output.js\";\n\nconst SORT_LABELS: Record<string, string> = {\n score: \"attention score\",\n volume: \"24h volume\",\n liquidity: \"liquidity\",\n movement: \"price movement\",\n spread: \"spread tightness\",\n recency: \"recency\",\n extremity: \"uncertainty\",\n rewards: \"rewards\",\n rewardYield: \"reward yield (per $ liq)\",\n lpExpectedReturn: \"LP expected return\",\n horizon: \"time to resolution\",\n};\n\nfunction scoreBar(score: number): string {\n const width = 15;\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 70 ? chalk.green : score >= 45 ? chalk.yellow : chalk.dim;\n return color(\"█\".repeat(filled)) + chalk.dim(\"░\".repeat(empty)) + ` ${Math.round(score)}`;\n}\n\nexport function displayFeedResult(feed: FeedResult, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(feed);\n return;\n }\n\n const sortLabel = SORT_LABELS[feed.sortedBy] ?? feed.sortedBy;\n out.heading(`Market Feed — ${feed.marketsReturned} markets by ${sortLabel}`);\n process.stdout.write(\n chalk.dim(\n ` ${feed.totalScanned.toLocaleString()} scanned · ${feed.totalAfterFilter.toLocaleString()} after filters · preset ${feed.preset}\\n\\n`,\n ),\n );\n\n if (feed.markets.length === 0) {\n out.warn(\"No markets matched the criteria.\");\n return;\n }\n\n const rows = feed.markets.map((m: FeedResultMarket) => {\n const prob = out.percent(m.yesPrice);\n const change = m.oneDayPriceChange;\n const changeStr =\n change > 0\n ? chalk.green(`+${(change * 100).toFixed(1)}%`)\n : change < 0\n ? chalk.red(`${(change * 100).toFixed(1)}%`)\n : chalk.dim(\"0.0%\");\n return [\n String(m.rank),\n out.truncate(m.question, 42),\n prob,\n String(Math.round(m.score)),\n out.compactCurrency(m.volume24h),\n out.compactCurrency(m.liquidity),\n changeStr,\n ];\n });\n\n out.table(rows, [\"#\", \"Market\", \"Prob\", \"Score\", \"24h Vol\", \"Liq\", \"Chg\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of feed.markets.slice(0, 5)) {\n const url = m.polymarketUrl;\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 55) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Score: \") + scoreBar(m.score) + \" \");\n process.stdout.write(chalk.dim(\"Spread: \") + m.spread.toFixed(3) + \" \");\n if (m.rewardsDailyRate > 0) {\n process.stdout.write(chalk.dim(\"Rewards: \") + `$${m.rewardsDailyRate.toFixed(2)}/day`);\n }\n process.stdout.write(\"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + url + \"\\n\");\n }\n\n if (feed.markets.length > 5) {\n process.stdout.write(chalk.dim(`\\n … and ${feed.markets.length - 5} more\\n`));\n }\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport { displayFeedResult } from \"../feed-display.js\";\nimport type { FeedResult, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\ninterface FeedCmdOpts {\n profile?: string;\n sortBy?: string;\n preset?: string;\n tag?: string;\n minVolume?: string;\n minLiquidity?: string;\n maxLiquidity?: string;\n minRewardsDailyRate?: string;\n minDaysToEnd?: string;\n maxDaysToEnd?: string;\n maxMarketAgeHours?: string;\n liquidProfile?: string;\n limit?: string;\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not authenticated. Run `hl auth login` first.\");\n process.exit(1);\n }\n}\n\nconst PROFILE_CHOICES = [\"lp-opportunity\", \"liquidity-provider\", \"liquid-new-or-long\"] as const;\n\nfunction isProfile(s: string | undefined): s is (typeof PROFILE_CHOICES)[number] {\n return s !== undefined && (PROFILE_CHOICES as readonly string[]).includes(s);\n}\n\nexport function resolveFeedProfile(\n screening: string | undefined,\n profile: string | undefined,\n warn: (message: string) => void = () => undefined,\n): string | undefined {\n if (profile && !isProfile(profile)) {\n throw new Error(`Unknown feed profile \"${profile}\". Use: ${PROFILE_CHOICES.join(\" or \")}`);\n }\n\n if (!screening) return profile;\n\n if (!isProfile(screening)) {\n throw new Error(`Unknown screening \"${screening}\". Use: ${PROFILE_CHOICES.join(\" or \")}`);\n }\n\n if (profile && profile !== screening) {\n warn(`Both positional and --profile set; using --profile (${profile}).`);\n return profile;\n }\n\n return profile ?? screening;\n}\n\n/**\n * Build query params for GET /api/feed. Omits undefined / empty string.\n */\nfunction feedQueryParams(opts: {\n profile?: string;\n sortBy?: string;\n preset?: string;\n tag?: string;\n minVolume?: string;\n minLiquidity?: string;\n maxLiquidity?: string;\n minRewardsDailyRate?: string;\n minDaysToEnd?: string;\n maxDaysToEnd?: string;\n maxMarketAgeHours?: string;\n liquidProfile?: string;\n limit?: string;\n}): Record<string, string> {\n const entries: [string, string][] = [];\n const add = (k: string, v: string | undefined) => {\n if (v !== undefined && v !== \"\") entries.push([k, v]);\n };\n add(\"profile\", opts.profile);\n add(\"sortBy\", opts.sortBy);\n add(\"preset\", opts.preset);\n add(\"tag\", opts.tag);\n add(\"minVolume\", opts.minVolume);\n add(\"minLiquidity\", opts.minLiquidity);\n add(\"maxLiquidity\", opts.maxLiquidity);\n add(\"minRewardsDailyRate\", opts.minRewardsDailyRate);\n add(\"minDaysToEnd\", opts.minDaysToEnd);\n add(\"maxDaysToEnd\", opts.maxDaysToEnd);\n add(\"maxMarketAgeHours\", opts.maxMarketAgeHours);\n add(\"liquidProfile\", opts.liquidProfile);\n add(\"limit\", opts.limit);\n return Object.fromEntries(entries);\n}\n\nexport function registerFeedCommand(program: Command): void {\n program\n .command(\"feed\")\n .description(\n \"Rank active Polymarket markets (same engine as chat getFeed / GET /api/feed). \" +\n \"Use --profile for curated screens.\",\n )\n .argument(\n \"[screening]\",\n `Optional screening preset: ${PROFILE_CHOICES.join(\" | \")} (same as --profile)`,\n )\n .option(\n \"--profile <name>\",\n `Screening defaults: ${PROFILE_CHOICES.join(\", \")} — explicit flags override`,\n )\n .option(\"--sort-by <key>\", \"score | volume | liquidity | movement | spread | recency | extremity | rewards | rewardYield | lpExpectedReturn | horizon\")\n .option(\"--preset <name>\", \"Attention weight preset (default, volume-hunter, lp-opportunity, …)\")\n .option(\"--tag <slug>\", \"Polymarket category tag, e.g. crypto, politics\")\n .option(\"--min-volume <usd>\", \"Minimum 24h volume (USD)\")\n .option(\"--min-liquidity <usd>\", \"Minimum displayed liquidity (USD)\")\n .option(\"--max-liquidity <usd>\", \"Maximum displayed liquidity (USD)\")\n .option(\"--min-rewards-daily-rate <usd>\", \"Minimum LP rewards USD/day\")\n .option(\"--min-days-to-end <n>\", \"Min calendar days until resolution\")\n .option(\"--max-days-to-end <n>\", \"Max calendar days until resolution\")\n .option(\"--max-market-age-hours <n>\", \"With liquid-new-or-long: max age (hours) for the \\\"new\\\" branch\")\n .option(\"--liquid-profile <mode>\", \"new-or-long (used by liquid-new-or-long screen)\")\n .option(\"--limit <n>\", \"Max markets to return (1–100, default 15)\", \"15\")\n .action(async (screening: string | undefined, o: FeedCmdOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n\n let profile: string | undefined;\n try {\n profile = resolveFeedProfile(screening, o.profile, out.warn);\n } catch (e) {\n out.error(e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const params = feedQueryParams({\n profile,\n sortBy: o.sortBy,\n preset: o.preset,\n tag: o.tag,\n minVolume: o.minVolume,\n minLiquidity: o.minLiquidity,\n maxLiquidity: o.maxLiquidity,\n minRewardsDailyRate: o.minRewardsDailyRate,\n minDaysToEnd: o.minDaysToEnd,\n maxDaysToEnd: o.maxDaysToEnd,\n maxMarketAgeHours: o.maxMarketAgeHours,\n liquidProfile: o.liquidProfile,\n limit: o.limit,\n });\n\n try {\n const result = await client.get<FeedResult>(\"/api/feed\", params);\n if (result.error) {\n out.error(result.error);\n process.exit(1);\n }\n displayFeedResult(result, globalOpts);\n } catch (e) {\n out.error(e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n });\n}\n","import { Command, InvalidArgumentError } from \"commander\";\nimport { readFile } from \"node:fs/promises\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport {\n allocationsFromDecisions,\n displayAllocatorCycleResult,\n feedMarketsToAllocatorMarkets,\n} from \"../allocator-display.js\";\nimport type {\n AllocatorAllocationInput,\n AllocatorCycleApiResponse,\n AllocatorCycleRequest,\n AllocatorStrategyInput,\n FeedResult,\n GlobalOptions,\n} from \"../types.js\";\nimport * as out from \"../output.js\";\n\nconst PROFILE_CHOICES = [\"lp-opportunity\", \"liquidity-provider\", \"liquid-new-or-long\"] as const;\n\ninterface AllocatorCycleOpts {\n profile?: string;\n sortBy?: string;\n tag?: string;\n minVolume?: string;\n minLiquidity?: string;\n maxLiquidity?: string;\n minRewardsDailyRate?: string;\n minDaysToEnd?: string;\n maxDaysToEnd?: string;\n maxMarketAgeHours?: string;\n liquidProfile?: string;\n limit: string;\n totalHoldings?: number;\n capitalLimitPct?: number;\n perMarketLimitPct?: number;\n capitalLimit: number;\n perMarketLimit: number;\n minExpectedReturnDailyPct: number;\n maxInventoryImbalance: number;\n maxOrderNotional: number;\n quoteEdgeBps: number;\n allocatorMinLiquidity: number;\n maxSpread: number;\n allocatorMinDaysToEnd: number;\n maxMarkets: number;\n allocations?: string;\n repeat?: boolean;\n paused?: boolean;\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not authenticated. Run `hl auth login` first.\");\n process.exit(1);\n }\n}\n\nfunction isProfile(s: string | undefined): s is (typeof PROFILE_CHOICES)[number] {\n return s !== undefined && (PROFILE_CHOICES as readonly string[]).includes(s);\n}\n\nfunction parseNonNegative(value: string): number {\n const n = Number(value);\n if (!Number.isFinite(n) || n < 0) {\n throw new InvalidArgumentError(\"Expected a non-negative number\");\n }\n return n;\n}\n\nexport function parsePositiveNumber(value: string): number {\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) {\n throw new InvalidArgumentError(\"Expected a positive number\");\n }\n return n;\n}\n\nfunction parsePositiveInt(value: string): number {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n throw new InvalidArgumentError(\"Expected a positive integer\");\n }\n return n;\n}\n\nfunction maybeAdd(entries: [string, string][], key: string, value: string | undefined): void {\n if (value !== undefined && value !== \"\") entries.push([key, value]);\n}\n\nfunction feedQueryParams(profile: string | undefined, opts: AllocatorCycleOpts): Record<string, string> {\n const entries: [string, string][] = [];\n maybeAdd(entries, \"profile\", profile);\n maybeAdd(entries, \"sortBy\", opts.sortBy);\n maybeAdd(entries, \"tag\", opts.tag);\n maybeAdd(entries, \"minVolume\", opts.minVolume);\n maybeAdd(entries, \"minLiquidity\", opts.minLiquidity);\n maybeAdd(entries, \"maxLiquidity\", opts.maxLiquidity);\n maybeAdd(entries, \"minRewardsDailyRate\", opts.minRewardsDailyRate);\n maybeAdd(entries, \"minDaysToEnd\", opts.minDaysToEnd);\n maybeAdd(entries, \"maxDaysToEnd\", opts.maxDaysToEnd);\n maybeAdd(entries, \"maxMarketAgeHours\", opts.maxMarketAgeHours);\n maybeAdd(entries, \"liquidProfile\", opts.liquidProfile);\n maybeAdd(entries, \"limit\", opts.limit);\n return Object.fromEntries(entries);\n}\n\nfunction strategyFromOptions(opts: AllocatorCycleOpts): AllocatorStrategyInput {\n return {\n id: \"cli-dry-run\",\n name: \"CLI dry-run LP strategy\",\n status: opts.paused ? \"paused\" : \"dry_run\",\n ...(opts.totalHoldings !== undefined && { total_holdings: opts.totalHoldings }),\n ...(opts.capitalLimitPct !== undefined && { capital_limit_pct: opts.capitalLimitPct }),\n ...(opts.perMarketLimitPct !== undefined && { per_market_limit_pct: opts.perMarketLimitPct }),\n capital_limit: opts.capitalLimit,\n per_market_limit: opts.perMarketLimit,\n min_expected_return_daily_pct: opts.minExpectedReturnDailyPct,\n max_inventory_imbalance: opts.maxInventoryImbalance,\n max_order_notional: opts.maxOrderNotional,\n quote_edge_bps: opts.quoteEdgeBps,\n min_liquidity: opts.allocatorMinLiquidity,\n max_spread: opts.maxSpread,\n min_days_to_end: opts.allocatorMinDaysToEnd,\n max_markets: opts.maxMarkets,\n };\n}\n\nfunction validatePercentageSizing(opts: AllocatorCycleOpts): void {\n const usesPercentageSizing =\n opts.capitalLimitPct !== undefined || opts.perMarketLimitPct !== undefined;\n if (usesPercentageSizing && opts.totalHoldings === undefined) {\n out.error(\n \"Percentage sizing requires --total-holdings so the allocator can convert percentages into dollar caps.\",\n );\n process.exit(1);\n }\n}\n\nasync function readAllocations(path: string | undefined): Promise<AllocatorAllocationInput[]> {\n if (!path) return [];\n const raw = path === \"-\" ? await readStdin() : await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) {\n throw new Error(\"Allocations JSON must be an array\");\n }\n return parsed as AllocatorAllocationInput[];\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nasync function runAllocatorCycle(\n client: ApiClient,\n payload: AllocatorCycleRequest,\n): Promise<AllocatorCycleApiResponse> {\n return client.post<AllocatorCycleApiResponse>(\"/api/allocator/cycle\", payload);\n}\n\nexport function registerAllocatorCommands(program: Command): void {\n const allocator = program\n .command(\"allocator\")\n .description(\"Run dry-run liquidity allocation cycles\");\n\n allocator\n .command(\"cycle\")\n .description(\"Find LP candidates from /api/feed and run a dry-run allocator cycle\")\n .argument(\n \"[screening]\",\n `Optional screening preset: ${PROFILE_CHOICES.join(\" | \")} (same as --profile)`,\n \"lp-opportunity\",\n )\n .option(\"--profile <name>\", `Screening defaults: ${PROFILE_CHOICES.join(\", \")}`)\n .option(\"--sort-by <key>\", \"score | volume | liquidity | movement | spread | rewards | rewardYield | lpExpectedReturn | horizon\")\n .option(\"--tag <slug>\", \"Polymarket category tag, e.g. crypto, politics\")\n .option(\"--min-volume <usd>\", \"Minimum 24h volume (USD)\")\n .option(\"--min-liquidity <usd>\", \"Minimum displayed liquidity (USD)\")\n .option(\"--max-liquidity <usd>\", \"Maximum displayed liquidity (USD)\")\n .option(\"--min-rewards-daily-rate <usd>\", \"Minimum LP rewards USD/day\")\n .option(\"--min-days-to-end <n>\", \"Feed filter: minimum days until resolution\")\n .option(\"--max-days-to-end <n>\", \"Feed filter: maximum days until resolution\")\n .option(\"--max-market-age-hours <n>\", \"With liquid-new-or-long: max age for the new branch\")\n .option(\"--liquid-profile <mode>\", \"new-or-long (used by liquid-new-or-long screen)\")\n .option(\"--limit <n>\", \"Max feed markets to fetch (1-100, default 15)\", \"15\")\n .option(\"--total-holdings <usd>\", \"Total user holdings / portfolio value used for percentage sizing\", parsePositiveNumber)\n .option(\"--capital-limit-pct <pct>\", \"Portfolio-level allocation cap as a percent of total holdings\", parsePositiveNumber)\n .option(\"--per-market-limit-pct <pct>\", \"Per-market target cap as a percent of total holdings\", parsePositiveNumber)\n .option(\"--capital-limit <usd>\", \"Portfolio capital limit for this cycle\", parseNonNegative, 500)\n .option(\"--per-market-limit <usd>\", \"Per-market target cap\", parseNonNegative, 100)\n .option(\"--min-expected-return-daily-pct <pct>\", \"Minimum expected daily return percent\", parseNonNegative, 0.02)\n .option(\"--max-inventory-imbalance <ratio>\", \"Maximum inventory imbalance\", parseNonNegative, 0.25)\n .option(\"--max-order-notional <usd>\", \"Maximum notional per planned passive order\", parseNonNegative, 25)\n .option(\"--quote-edge-bps <bps>\", \"Passive quote edge in basis points\", parseNonNegative, 100)\n .option(\"--allocator-min-liquidity <usd>\", \"Allocator safety gate: minimum market liquidity\", parseNonNegative, 500)\n .option(\"--max-spread <ratio>\", \"Allocator safety gate: maximum spread\", parseNonNegative, 0.12)\n .option(\"--allocator-min-days-to-end <n>\", \"Allocator safety gate: minimum days to resolution\", parseNonNegative, 3)\n .option(\"--max-markets <n>\", \"Maximum markets allocator may target\", parsePositiveInt, 5)\n .option(\"--allocations <file>\", \"Existing allocations JSON array; use '-' to read stdin\")\n .option(\"--repeat\", \"Run a second cycle using targets returned by the first cycle\")\n .option(\"--paused\", \"Send strategy status paused instead of dry_run\")\n .action(async (screening: string | undefined, o: AllocatorCycleOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n validatePercentageSizing(o);\n\n let profile = o.profile ?? screening ?? \"lp-opportunity\";\n if (!isProfile(profile)) {\n out.error(`Unknown screening \"${profile}\". Use: ${PROFILE_CHOICES.join(\" or \")}`);\n process.exit(1);\n }\n if (o.profile && screening && screening !== \"lp-opportunity\" && o.profile !== screening) {\n out.warn(`Both positional and --profile set; using --profile (${o.profile}).`);\n profile = o.profile;\n }\n\n const feed = await client.get<FeedResult>(\"/api/feed\", feedQueryParams(profile, o));\n if (feed.error) {\n out.error(feed.error);\n process.exit(1);\n }\n if (feed.markets.length === 0) {\n out.warn(\"No feed markets matched the allocator criteria.\");\n return;\n }\n\n const allocations = await readAllocations(o.allocations);\n const payload: AllocatorCycleRequest = {\n strategy: strategyFromOptions(o),\n markets: feedMarketsToAllocatorMarkets(feed.markets),\n allocations,\n };\n\n if (!globalOpts.json) {\n process.stderr.write(\n chalk.dim(\n ` Running allocator dry-run on ${feed.markets.length} ${profile} candidates...\\n`,\n ),\n );\n }\n\n const first = await runAllocatorCycle(client, payload);\n const firstResult = first.result ?? {};\n\n if (o.repeat) {\n const repeatPayload: AllocatorCycleRequest = {\n ...payload,\n allocations: allocationsFromDecisions(firstResult.decisions ?? []),\n };\n const second = await runAllocatorCycle(client, repeatPayload);\n if (globalOpts.json) {\n out.json({ initial: first, repeat: second });\n } else {\n displayAllocatorCycleResult(firstResult, globalOpts);\n process.stdout.write(\"\\n\" + chalk.bold(\"Repeated with target allocations\") + \"\\n\");\n displayAllocatorCycleResult(second.result ?? {}, globalOpts);\n }\n return;\n }\n\n if (globalOpts.json) {\n out.json(first);\n } else {\n displayAllocatorCycleResult(firstResult, globalOpts);\n }\n });\n}\n","import chalk from \"chalk\";\nimport type {\n AllocatorAllocationInput,\n AllocatorCycleResult,\n AllocatorDecision,\n FeedResultMarket,\n GlobalOptions,\n} from \"./types.js\";\nimport * as out from \"./output.js\";\n\nfunction actionColor(action: string): string {\n switch (action) {\n case \"ALLOCATE\":\n case \"INCREASE\":\n return chalk.green(action);\n case \"REDUCE\":\n case \"EXIT\":\n return chalk.yellow(action);\n case \"SKIP\":\n return chalk.dim(action);\n case \"WATCH\":\n return chalk.cyan(action);\n default:\n return action;\n }\n}\n\nfunction num(value: unknown, fallback = 0): number {\n const n = Number(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nexport function feedMarketsToAllocatorMarkets(markets: FeedResultMarket[]) {\n return markets.slice(0, 25).map((m) => {\n const probability = num(m.probability ?? m.yesPrice, 0.5);\n const daysToEnd =\n m.daysToEnd == null || m.daysToEnd === undefined ? undefined : num(m.daysToEnd);\n return {\n slug: String(m.slug ?? \"\"),\n question: String(m.question ?? \"\"),\n yesTokenId: m.yesTokenId ? String(m.yesTokenId) : undefined,\n noTokenId: m.noTokenId ? String(m.noTokenId) : undefined,\n yesPrice: num(m.yesPrice, probability),\n noPrice: num(m.noPrice, 1 - probability),\n liquidity: num(m.liquidity),\n volume24h: num(m.volume24h),\n spread: num(m.spread),\n rewardsDailyRate: num(m.rewardsDailyRate),\n oneDayPriceChange: num(m.oneDayPriceChange),\n ...(daysToEnd !== undefined && { daysToEnd }),\n active: m.active == null ? true : Boolean(m.active),\n };\n });\n}\n\nexport function allocationsFromDecisions(\n decisions: AllocatorDecision[],\n): AllocatorAllocationInput[] {\n return decisions\n .filter((d) => String(d.market_slug ?? \"\"))\n .map((d) => ({\n market_slug: String(d.market_slug),\n status: String(d.action ?? \"planned\").toLowerCase(),\n allocated_capital: num(d.target_capital),\n locked_capital: 0,\n inventory_yes: 0,\n inventory_no: 0,\n open_order_notional: Array.isArray(d.order_plan)\n ? d.order_plan.reduce((sum, order) => sum + num(order.notional), 0)\n : 0,\n }));\n}\n\nexport function displayAllocatorCycleResult(\n result: AllocatorCycleResult,\n globalOpts: GlobalOptions,\n): void {\n if (globalOpts.json) {\n out.json(result);\n return;\n }\n\n const decisions = Array.isArray(result.decisions) ? result.decisions : [];\n const summary = result.summary ?? {};\n const dryRun = result.dry_run === false ? \"live\" : \"dry run\";\n\n out.heading(`Allocator Cycle — ${dryRun}`);\n process.stdout.write(\n chalk.dim(\n ` ${num(result.total_markets, decisions.length)} markets · ${out.currency(\n num(summary.target_capital),\n )} target capital · ${num(summary.orders_planned)} planned orders\\n\\n`,\n ),\n );\n\n if (decisions.length === 0) {\n out.warn(\"No allocator decisions returned.\");\n return;\n }\n\n const rows = decisions.map((d) => {\n const action = String(d.action ?? \"UNKNOWN\");\n const score = num(d.score?.score);\n const expected = num(d.score?.expected_return_daily_pct);\n const orders = Array.isArray(d.order_plan) ? d.order_plan.length : 0;\n const failedChecks = Array.isArray(d.safety_checks)\n ? d.safety_checks.filter((check) => check.passed === false).length\n : 0;\n return [\n out.truncate(String(d.question ?? d.market_slug ?? \"—\"), 42),\n actionColor(action),\n out.currency(num(d.target_capital)),\n signedCurrency(num(d.capital_delta)),\n `${expected.toFixed(3)}%`,\n String(Math.round(score)),\n String(orders),\n failedChecks === 0 ? chalk.green(\"0\") : chalk.yellow(String(failedChecks)),\n ];\n });\n\n out.table(rows, [\"Market\", \"Action\", \"Target\", \"Delta\", \"Exp/day\", \"Score\", \"Orders\", \"Fails\"]);\n\n process.stdout.write(\"\\n\");\n for (const decision of decisions.slice(0, 5)) {\n const action = String(decision.action ?? \"UNKNOWN\");\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(String(decision.question ?? decision.market_slug ?? \"—\"), 65) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Action: \") + actionColor(action));\n if (decision.rationale) {\n process.stdout.write(\" \" + chalk.dim(\"Rationale: \") + out.truncate(decision.rationale, 120));\n }\n process.stdout.write(\"\\n\");\n\n const orders = Array.isArray(decision.order_plan) ? decision.order_plan : [];\n for (const order of orders.slice(0, 2)) {\n process.stdout.write(\n \" \" +\n chalk.dim(\"Order: \") +\n `${String(order.side ?? \"BUY\")} ${String(order.outcome ?? \"?\")} @ ${num(order.price).toFixed(3)} ` +\n `for ${out.currency(num(order.notional))}` +\n \"\\n\",\n );\n }\n if (orders.length > 2) {\n process.stdout.write(chalk.dim(` … ${orders.length - 2} more orders\\n`));\n }\n }\n\n if (decisions.length > 5) {\n process.stdout.write(chalk.dim(`\\n … and ${decisions.length - 5} more decisions\\n`));\n }\n}\n\nfunction signedCurrency(value: number): string {\n const formatted = out.currency(Math.abs(value));\n if (value > 0) return chalk.green(`+${formatted}`);\n if (value < 0) return chalk.yellow(`-${formatted}`);\n return chalk.dim(\"$0.00\");\n}\n"],"mappings":";;;AAAA,SAAS,WAAAA,gBAAe;;;ACCxB,OAAO,cAAc;;;ACDrB,SAAS,cAAc,eAAe,WAAW,YAAY,kBAAkB;AAC/E,SAAS,YAAY;AACrB,SAAS,eAAe;AAExB,IAAM,aAAa,KAAK,QAAQ,GAAG,aAAa;AAChD,IAAM,cAAc,KAAK,YAAY,aAAa;AAE3C,IAAM,kBAAkB;AAO/B,SAAS,gBAAwB;AAC/B,SAAO,EAAE,SAAS,iBAAiB,OAAO,KAAK;AACjD;AAEO,SAAS,aAAqB;AACnC,MAAI;AACF,QAAI,CAAC,WAAW,WAAW,EAAG,QAAO,cAAc;AACnD,UAAM,MAAM,aAAa,aAAa,OAAO;AAC7C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO;AAAA,MACL,SAAS,OAAO,WAAW;AAAA,MAC3B,OAAO,OAAO,SAAS;AAAA,IACzB;AAAA,EACF,QAAQ;AACN,WAAO,cAAc;AAAA,EACvB;AACF;AAEO,SAAS,WAAW,QAAsB;AAC/C,YAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACzC,gBAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAC5E;AAEO,SAAS,cAAoB;AAClC,MAAI;AACF,QAAI,WAAW,WAAW,EAAG,YAAW,WAAW;AAAA,EACrD,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,aAAqB;AACnC,SAAO;AACT;;;AC5CO,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,OAAsB,CAAC,GAAG;AACpC,UAAM,SAAS,WAAW;AAC1B,SAAK,WAAW,KAAK,UAAU,OAAO,WAAW,iBAAiB,QAAQ,OAAO,EAAE;AACnF,SAAK,QAAQ,KAAK,SAAS,OAAO,SAAS;AAC3C,SAAK,UAAU,KAAK,WAAW;AAAA,EACjC;AAAA,EAEA,IAAI,kBAA2B;AAC7B,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,QAAQ,QAAgC,CAAC,GAA2B;AAC1E,UAAM,IAA4B;AAAA,MAChC,gBAAgB;AAAA,MAChB,GAAG;AAAA,IACL;AACA,QAAI,KAAK,OAAO;AACd,QAAE,eAAe,IAAI,UAAU,KAAK,KAAK;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,IAAI,QAAgB,MAAc,QAAuB;AAC/D,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,YAAY,SAAS,WAAM,MAAM,KAAK;AAC5C,YAAQ,OAAO,MAAM,aAAa,MAAM,IAAI,KAAK,OAAO,GAAG,IAAI,GAAG,SAAS;AAAA,CAAI;AAAA,EACjF;AAAA,EAEA,MAAM,IAAO,MAAc,QAA6C;AACtE,UAAM,MAAM,IAAI,IAAI,MAAM,KAAK,OAAO;AACtC,QAAI,QAAQ;AACV,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,YAAI,MAAM,UAAa,MAAM,GAAI,KAAI,aAAa,IAAI,GAAG,CAAC;AAAA,MAC5D;AAAA,IACF;AAEA,SAAK,IAAI,OAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,EAAE;AAC9C,UAAM,MAAM,MAAM,MAAM,IAAI,SAAS,GAAG,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AACnE,SAAK,IAAI,OAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,IAAI,IAAI,MAAM;AAE1D,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA,EAEA,MAAM,KAAQ,MAAc,MAA4B;AACtD,SAAK,IAAI,QAAQ,IAAI;AACrB,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AACD,SAAK,IAAI,QAAQ,MAAM,IAAI,MAAM;AAEjC,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,OAKjB;AACD,UAAM,OAAO;AACb,SAAK,IAAI,QAAQ,IAAI;AACrB,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,IAC/C,CAAC;AACD,SAAK,IAAI,QAAQ,MAAM,IAAI,MAAM;AAEjC,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AAEA,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN,YAAM,IAAI,SAAS,IAAI,QAAQ,QAAQ,8BAA8B;AAAA,IACvE;AAEA,UAAM,MAAM,IAAI,QAAQ,IAAI,eAAe;AAC3C,UAAM,QAAQ,IAAI,QAAQ,IAAI,mBAAmB;AACjD,UAAM,QAAQ,IAAI,QAAQ,IAAI,cAAc;AAE5C,WAAO;AAAA,MACL;AAAA,MACA,YAAY,OAAO,OAAO,OAAO,GAAG,IAAI;AAAA,MACxC,gBAAgB,SAAS,OAAO,OAAO,KAAK,IAAI;AAAA,MAChD,WAAW,QAAQ,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO,IAAI,CAAC;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,MAAS,MAAc,MAA2B;AACtD,SAAK,IAAI,SAAS,IAAI;AACtB,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,SAAK,IAAI,SAAS,MAAM,IAAI,MAAM;AAElC,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA,EAEA,MAAM,OAAO,MAA6B;AACxC,SAAK,IAAI,UAAU,IAAI;AACvB,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,SAAK,IAAI,UAAU,MAAM,IAAI,MAAM;AAEnC,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,MAAoD;AAC7E,SAAK,IAAI,iBAAiB,IAAI;AAC9B,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ,EAAE,QAAQ,oBAAoB,CAAC;AAAA,MACrD,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,SAAK,IAAI,iBAAiB,MAAM,IAAI,MAAM;AAE1C,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AACA,QAAI,CAAC,IAAI,MAAM;AACb,YAAM,IAAI,SAAS,GAAG,6BAA6B;AAAA,IACrD;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,aAAa,MAAc,MAAoD;AACnF,SAAK,IAAI,iBAAiB,IAAI;AAC9B,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ,EAAE,QAAQ,uBAAuB,CAAC;AAAA,MACxD,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,SAAK,IAAI,iBAAiB,MAAM,IAAI,MAAM;AAE1C,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAM,IAAI,SAAS,IAAI,QAAQ,IAAI;AAAA,IACrC;AACA,QAAI,CAAC,IAAI,MAAM;AACb,YAAM,IAAI,SAAS,GAAG,6BAA6B;AAAA,IACrD;AACA,WAAO,IAAI;AAAA,EACb;AACF;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACS,QACA,MACP;AACA,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,YAAM,OAAO,SAAS,OAAO,WAAW;AAAA,IAC1C,QAAQ;AACN,YAAM;AAAA,IACR;AACA,UAAM,aAAa,MAAM,KAAK,GAAG,EAAE;AAV5B;AACA;AAUP,SAAK,OAAO;AAAA,EACd;AACF;;;AC1MA,OAAO,WAAW;AAEX,SAAS,KAAK,MAAqB;AACxC,UAAQ,OAAO,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AAC3D;AAEO,SAAS,MAAM,MAAkB,SAA0B;AAChE,QAAM,UAAU,UAAU,CAAC,SAAS,GAAG,IAAI,IAAI;AAC/C,QAAM,YAAsB,CAAC;AAC7B,aAAW,OAAO,SAAS;AACzB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,gBAAU,CAAC,IAAI,KAAK,IAAI,UAAU,CAAC,KAAK,GAAG,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM;AAAA,IACrE;AAAA,EACF;AAEA,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,UAAM,SAAS,IAAI,IAAI,CAAC,MAAM,MAAM;AAClC,YAAM,OAAO,UAAU,IAAI;AAC3B,YAAM,MAAM,UAAU,CAAC,IAAI,KAAK;AAChC,aAAO,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,GAAG,CAAC;AAAA,IAC3C,CAAC;AACD,YAAQ,OAAO,MAAM,OAAO,OAAO,KAAK,IAAI,IAAI,IAAI;AAEpD,QAAI,MAAM,KAAK,SAAS;AACtB,YAAM,MAAM,UAAU,IAAI,CAAC,MAAM,SAAI,OAAO,CAAC,CAAC,EAAE,KAAK,cAAI;AACzD,cAAQ,OAAO,MAAM,OAAO,MAAM,IAAI;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,UAAU,KAAqB;AAEtC,SAAO,IAAI,QAAQ,mBAAmB,EAAE;AAC1C;AAEO,SAAS,QAAQ,MAAoB;AAC1C,UAAQ,OAAO,MAAM,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM;AACvD;AAEO,SAAS,QAAQ,MAAoB;AAC1C,UAAQ,OAAO,MAAM,MAAM,MAAM,QAAG,IAAI,MAAM,OAAO,IAAI;AAC3D;AAEO,SAAS,KAAK,MAAoB;AACvC,UAAQ,OAAO,MAAM,MAAM,OAAO,QAAG,IAAI,MAAM,OAAO,IAAI;AAC5D;AAEO,SAAS,MAAM,MAAoB;AACxC,UAAQ,OAAO,MAAM,MAAM,IAAI,QAAG,IAAI,MAAM,OAAO,IAAI;AACzD;AAEO,SAAS,IAAI,MAAsB;AACxC,SAAO,MAAM,IAAI,IAAI;AACvB;AAEO,SAAS,KAAK,MAAsB;AACzC,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,SAAS,GAAmB;AAC1C,SAAO,MAAM,EAAE,eAAe,SAAS,EAAE,uBAAuB,GAAG,uBAAuB,EAAE,CAAC;AAC/F;AAEO,SAAS,gBAAgB,GAAmB;AACjD,MAAI,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AAC3B,MAAI,KAAK,IAAW,QAAO,KAAK,IAAI,KAAW,QAAQ,CAAC,CAAC;AACzD,MAAI,KAAK,IAAO,QAAO,KAAK,IAAI,KAAO,QAAQ,CAAC,CAAC;AACjD,SAAO,IAAI,EAAE,QAAQ,CAAC,CAAC;AACzB;AAEO,SAAS,QAAQ,GAAmB;AACzC,UAAQ,IAAI,KAAK,QAAQ,CAAC,IAAI;AAChC;AAEO,SAAS,SAAS,KAAa,KAAqB;AACzD,MAAI,IAAI,UAAU,IAAK,QAAO;AAC9B,SAAO,IAAI,MAAM,GAAG,MAAM,CAAC,IAAI;AACjC;AAEO,SAAS,aAAa,MAAsB;AACjD,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,QAAQ;AACjD,QAAM,OAAO,KAAK,MAAM,OAAO,GAAM;AACrC,MAAI,OAAO,EAAG,QAAO;AACrB,MAAI,OAAO,GAAI,QAAO,GAAG,IAAI;AAC7B,QAAM,QAAQ,KAAK,MAAM,OAAO,EAAE;AAClC,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,SAAO,GAAG,IAAI;AAChB;;;AHlFO,SAAS,qBAAqBC,UAAwB;AAC3D,QAAM,OAAOA,SAAQ,QAAQ,MAAM,EAAE,YAAY,2BAA2B;AAE5E,OACG,QAAQ,OAAO,EACf,YAAY,2CAA2C,EACvD,OAAO,mBAAmB,gBAAgB,eAAe,EACzD,OAAO,OAAO,YAAiC;AAC9C,UAAM,aAAaA,SAAQ,KAAoB;AAE/C,UAAM,KAAK,SAAS,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AACpF,QAAI;AACF,MAAI,QAAQ,8BAAyB;AACrC,cAAQ,OAAO;AAAA,QACb,0BAA8B,KAAK,wCAAwC,CAAC;AAAA;AAAA;AAAA,MAC9E;AAEA,YAAM,SAAS,MAAM,GAAG,SAAS,wBAAwB,GAAG,KAAK;AAEjE,UAAI,CAAC,MAAM,WAAW,KAAK,KAAK,MAAM,WAAW,IAAI;AACnD,QAAI,MAAM,sEAAsE;AAChF,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,SAAS,WAAW,UAAU,QAAQ,UAAU;AACtD,YAAM,SAAS,IAAI,UAAU,EAAE,OAAO,OAAO,CAAC;AAE9C,cAAQ,OAAO,MAAM,uBAAuB;AAC5C,UAAI;AACJ,UAAI;AACF,kBAAU,MAAM,OAAO,IAAiB,cAAc;AAAA,MACxD,QAAQ;AACN,gBAAQ,OAAO,MAAM,IAAI;AACzB,QAAI,MAAM,0DAA0D;AACpE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,cAAQ,OAAO,MAAM,WAAW;AAEhC,iBAAW,EAAE,SAAS,QAAQ,MAAM,CAAC;AAErC,MAAI,QAAQ,gBAAoB,KAAK,QAAQ,UAAU,QAAQ,OAAO,CAAC,EAAE;AACzE,cAAQ,OAAO,MAAM,qBAAyB,IAAI,WAAW,CAAC,CAAC;AAAA,CAAI;AAAA,IACrE,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,oCAAoC,EAChD,OAAO,YAAY;AAClB,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,WAAW;AAC1B,UAAM,QAAQ,WAAW,SAAS,OAAO;AAEzC,QAAI,CAAC,OAAO;AACV,MAAI,KAAK,wBAA4B,KAAK,eAAe,IAAI,mBAAmB;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,IAAI,UAAU,UAAU;AAEvC,QAAI;AACF,YAAM,UAAU,MAAM,OAAO,IAAiB,cAAc;AAC5D,UAAI,WAAW,MAAM;AACnB,QAAI,KAAK;AAAA,UACP,eAAe;AAAA,UACf,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,MACH,OAAO;AACL,QAAI,QAAQ,aAAa;AACzB,QAAI;AAAA,UACF;AAAA,YACE,CAAC,UAAc,KAAK,QAAQ,UAAU,QAAQ,CAAC;AAAA,YAC/C,CAAC,WAAW,QAAQ,OAAO;AAAA,YAC3B,CAAC,WAAW,OAAO,MAAM;AAAA,YACzB,CAAC,UAAU,WAAW,CAAC;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AACN,MAAI,MAAM,sCAA0C,KAAK,eAAe,IAAI,sBAAsB;AAClG,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,yBAAyB,EACrC,OAAO,MAAM;AACZ,gBAAY;AACZ,IAAI,QAAQ,oCAAwC,IAAI,WAAW,CAAC,CAAC;AAAA,EACvE,CAAC;AACL;;;AIrGA,OAAOC,YAAW;;;AC0BlB,eAAsB,YACpB,MACA,YAA6B,CAAC,GACP;AACvB,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,KAAK,UAAU;AAE9B,MAAI,SAAS;AACb,MAAI,gBAAgB;AACpB,QAAM,YAAoD,CAAC;AAC3D,QAAM,kBAAkB,oBAAI,IAA8C;AAC1E,MAAI,cAA8C;AAClD,MAAI,aAA6C;AAEjD,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,CAAC,MAAM;AACT,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IAClD;AAEA,UAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,aAAS,OAAO,KAAM,MAAM,IAAI,KAAK;AAErC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AAEzC,UAAI,CAAC,QAAQ,WAAW,OAAO,EAAG;AAClC,YAAM,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;AAEtC,UAAI,YAAY,SAAU;AAE1B,UAAI;AACJ,UAAI;AACF,cAAM,KAAK,MAAM,OAAO;AAAA,MAC1B,QAAQ;AACN;AAAA,MACF;AAEA,YAAM,OAAO,IAAI;AAEjB,cAAQ,MAAM;AAAA,QACZ,KAAK,cAAc;AACjB,gBAAM,QAAQ,IAAI;AAClB,cAAI,OAAO;AACT,6BAAiB;AACjB,sBAAU,SAAS,KAAK;AAAA,UAC1B;AACA;AAAA,QACF;AAAA,QAEA,KAAK,oBAAoB;AACvB,gBAAM,KAAK,IAAI;AACf,gBAAM,OAAO,IAAI;AACjB,cAAI,MAAM,MAAM;AACd,4BAAgB,IAAI,IAAI,EAAE,MAAM,QAAQ,GAAG,CAAC;AAAA,UAC9C;AACA;AAAA,QACF;AAAA,QAEA,KAAK,oBAAoB;AACvB,gBAAM,KAAK,IAAI;AACf,gBAAM,SAAS,gBAAgB,IAAI,EAAE;AACrC,cAAI,QAAQ;AACV,mBAAO,UAAU,IAAI;AAAA,UACvB;AACA;AAAA,QACF;AAAA,QAEA,KAAK,wBAAwB;AAC3B,gBAAM,KAAK,IAAI;AACf,gBAAM,SAAS,gBAAgB,IAAI,EAAE;AACrC,cAAI,QAAQ;AACV,kBAAM,OAAO,IAAI,SAAS,OAAO;AACjC,sBAAU,KAAK,EAAE,MAAM,OAAO,MAAM,KAAK,CAAC;AAC1C,sBAAU,aAAa,OAAO,MAAM,IAAI;AAAA,UAC1C;AACA;AAAA,QACF;AAAA,QAEA,KAAK,yBAAyB;AAC5B,gBAAM,KAAK,IAAI;AACf,gBAAM,SAAS,gBAAgB,IAAI,EAAE;AACrC,cAAI,QAAQ;AACV,sBAAU,eAAe,OAAO,MAAM,IAAI,MAAM;AAChD,gBAAI,OAAO,SAAS,sBAAsB,cAAc,IAAI,MAAM,GAAG;AACnE,4BAAc,IAAI;AAAA,YACpB;AACA,gBAAI,OAAO,SAAS,aAAa,aAAa,IAAI,MAAM,GAAG;AACzD,2BAAa,IAAI;AAAA,YACnB;AACA,4BAAgB,OAAO,EAAE;AAAA,UAC3B;AACA;AAAA,QACF;AAAA,QAEA,KAAK,SAAS;AACZ,gBAAM,IAAI,MAAO,IAAI,aAAwB,sBAAsB;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAM;AAAA,EACZ;AAEA,SAAO,EAAE,eAAe,WAAW,aAAa,WAAW;AAC7D;AAEA,SAAS,cAAc,KAAuB;AAC5C,SACE,QAAQ,QACR,OAAO,QAAQ,YACf,WAAY,OACZ,aAAc;AAElB;AAEA,SAAS,aAAa,KAAuB;AAC3C,SACE,QAAQ,QACR,OAAO,QAAQ,YACf,aAAc,OACd,cAAe;AAEnB;AAuBA,eAAsB,kBACpB,MACA,YAA6B,CAAC,GACF;AAC5B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,KAAK,UAAU;AAE9B,MAAI,SAAS;AACb,MAAI,QAAwC;AAC5C,MAAIC,SAAkD;AAEtD,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,CAAC,MAAM;AACT,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IAClD;AAEA,UAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,aAAS,OAAO,KAAM,MAAM,IAAI,KAAK;AAErC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,QAAS;AAEd,UAAI;AACJ,UAAI;AACF,cAAM,KAAK,MAAM,OAAO;AAAA,MAC1B,QAAQ;AACN;AAAA,MACF;AAEA,YAAM,OAAO,IAAI;AAEjB,cAAQ,MAAM;AAAA,QACZ,KAAK,YAAY;AACf,oBAAU,aAAa,IAAI,MAAgB,IAAI,OAAiB;AAChE;AAAA,QACF;AAAA,QACA,KAAK,SAAS;AACZ,kBAAQ,IAAI;AACZ;AAAA,QACF;AAAA,QACA,KAAK,SAAS;AACZ,UAAAA,SAAQ;AAAA,YACN,MAAM,IAAI;AAAA,YACV,SAAS,IAAI;AAAA,UACf;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAM;AAAA,EACZ;AAEA,SAAO,EAAE,OAAO,OAAAA,OAAM;AACxB;;;AD/NO,SAAS,sBAAsBC,UAAwB;AAC5D,EAAAA,SACG,QAAQ,eAAe,EACvB,YAAY,uDAAuD,EACnE,OAAO,6BAA6B,+CAA+C,EACnF,OAAO,gCAAgC,sCAAsC,EAC7E,OAAO,iBAAiB,6DAA6D,EACrF,OAAO,oBAAoB,gCAAgC,UAAU,EACrE,OAAO,uBAAuB,2BAA2B,UAAU,EACnE,OAAO,OAAO,OAAe,YAA0B;AACtD,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,gBAAY,MAAM;AAElB,UAAM,UAAU,aAAa,OAAO;AACpC,UAAM,OAAqB;AAAA,MACzB;AAAA,MACA,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;AAAA,MACrD,GAAI,QAAQ,eAAe,EAAE,aAAa,QAAQ,YAAY;AAAA,MAC9D,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,QAAQ;AAAA,IACV;AAEA,UAAM,aAAa,QAAQ,MAAM,UAAU;AAAA,EAC7C,CAAC;AACL;AAcA,SAAS,aAAa,MAAqD;AACzE,QAAM,OAAO,KAAK,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACtE,QAAM,aAAa,KAAK,aAAa,QAAQ,KAAK,eAAe,QAAS,QAAQ,KAAK,SAAS;AAChG,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO;AAAA,IACL,GAAI,KAAK,aAAa,QAAQ,EAAE,WAAW,KAAK,UAAU;AAAA,IAC1D,GAAI,KAAK,eAAe,QAAQ,EAAE,aAAa,KAAK,YAAY;AAAA,IAChE,GAAI,QAAQ,KAAK,SAAS,KAAK,EAAE,KAAK;AAAA,EACxC;AACF;AAMA,eAAe,aAAa,QAAmB,MAAoB,YAA0C;AAC3G,QAAM,YAAY,KAAK,IAAI;AAC3B,UAAQ,OAAO,MAAMC,OAAM,IAAI,2BAA+B,SAAS,KAAK,OAAO,EAAE,CAAC;AAAA,CAAQ,CAAC;AAE/F,QAAM,SAAS,MAAM,OAAO,aAAa,cAAc,IAAI;AAC3D,QAAM,SAAS,MAAM,kBAAkB,QAAQ;AAAA,IAC7C,YAAY,CAAC,MAAM,YAAY;AAC7B,cAAQ,OAAO,MAAMA,OAAM,IAAI,MAAM,IAAI,IAAI,IAAI,UAAU,IAAI;AAAA,IACjE;AAAA,EACF,CAAC;AAED,QAAM,YAAY,KAAK,IAAI,IAAI,aAAa,KAAM,QAAQ,CAAC;AAE3D,MAAI,OAAO,OAAO;AAChB,IAAI,MAAM,iBAAiB,OAAO,MAAM,IAAI,MAAM,OAAO,MAAM,OAAO,EAAE;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,OAAO,OAAO;AACjB,IAAI,MAAM,+BAA+B;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,OAAO,MAAMA,OAAM,IAAI,WAAW,OAAO;AAAA;AAAA,CAAQ,CAAC;AAC1D,eAAa,OAAO,OAAiC,UAAU;AACjE;AAMA,SAAS,aAAa,OAAoB,YAAiC;AACzE,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,KAAK;AACd;AAAA,EACF;AAEA,EAAI,QAAQ,cAAc;AAE1B,UAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,MAAM,KAAK,IAAI,MAAM;AAC5D,UAAQ,OAAO,MAAM,OAAOA,OAAM,OAAO,MAAM,MAAM,IAAI,IAAI;AAE7D,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,WAAW,IAAI,MAAM;AAC5D,UAAM,OAAO,MAAM,QAAQ,IAAI,CAAC,MAAM;AACpC,YAAM,OAAW,QAAQ,EAAE,QAAQ;AACnC,YAAM,UAAU,EAAE,QAAQ,SAAS,IAAI,EAAE,QAAQ,KAAK,IAAI,IAAI;AAC9D,YAAM,MAAM,EAAE,YAAgB,SAAS,EAAE,SAAS,IAAI;AACtD,aAAO,CAAK,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,SAAS,GAAG;AAAA,IAC1D,CAAC;AACD,IAAI,MAAM,MAAM,CAAC,UAAU,QAAQ,WAAW,KAAK,CAAC;AAEpD,YAAQ,OAAO,MAAM,IAAI;AACzB,eAAW,KAAK,MAAM,SAAS;AAC7B,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,SAAI,IAAQ,SAAS,EAAE,UAAU,EAAE,IAAI,IAAI;AACjF,cAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,eAAe,IAAI,EAAE,aAAa,IAAI;AAC9E,cAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,cAAc,IAAI,EAAE,gBAAgB,IAAI;AAAA,IAClF;AAAA,EACF;AAEA,MAAI,MAAM,KAAK,SAAS,GAAG;AACzB,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,iBAAiB,IAAI,MAAM;AAClE,eAAW,OAAO,MAAM,MAAM;AAC5B,cAAQ,OAAO,MAAM,OAAOA,OAAM,OAAO,QAAG,IAAI,MAAM,MAAM,IAAI;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,eAAe,MAAM,QAAQ;AACvD,UAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,GAAG,WAAW,iBAAc,MAAM,KAAK,MAAM,gBAAgB,IAAI,IAAI;AAC/G;AAMA,SAAS,YAAY,QAAyB;AAC5C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,IAAI,MAAM,wBAA4B,KAAK,eAAe,IAAI,SAAS;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AExIO,SAAS,uBAAuBC,UAAwB;AAC7D,EAAAA,SACG,QAAQ,SAAS,EACjB,YAAY,wBAAwB,EACpC,OAAO,YAAY;AAClB,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,UAAM,UAAU,MAAM,OAAO,IAAiB,cAAc;AAE5D,QAAI,WAAW,MAAM;AACnB,MAAI,KAAK,OAAO;AAChB;AAAA,IACF;AAEA,IAAI,QAAQ,SAAS;AACrB,IAAI,MAAM;AAAA,MACR,CAAC,UAAc,KAAK,QAAQ,UAAU,QAAQ,CAAC;AAAA,MAC/C,CAAC,WAAW,QAAQ,OAAO;AAAA,MAC3B,CAAC,WAAW,IAAI,KAAK,QAAQ,UAAU,EAAE,mBAAmB,CAAC;AAAA,IAC/D,CAAC;AAAA,EACH,CAAC;AACL;AAEA,SAASA,aAAY,QAAyB;AAC5C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,IAAI,MAAM,wBAA4B,KAAK,eAAe,IAAI,SAAS;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AClCA,OAAOC,eAAc;AACrB,OAAOC,YAAW;;;ACFlB,OAAOC,YAAW;AAIlB,IAAM,cAAsC;AAAA,EAC1C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,SAAS;AACX;AAEA,SAAS,SAAS,OAAuB;AACvC,QAAM,QAAQ;AACd,QAAM,SAAS,KAAK,MAAO,QAAQ,MAAO,KAAK;AAC/C,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,SAAS,KAAKC,OAAM,QAAQ,SAAS,KAAKA,OAAM,SAASA,OAAM;AAC7E,SAAO,MAAM,SAAI,OAAO,MAAM,CAAC,IAAIA,OAAM,IAAI,SAAI,OAAO,KAAK,CAAC,IAAI,IAAI,KAAK,MAAM,KAAK,CAAC;AACzF;AAEO,SAAS,kBAAkB,MAAkB,YAAiC;AACnF,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,IAAI;AACb;AAAA,EACF;AAEA,QAAM,YAAY,YAAY,KAAK,QAAQ,KAAK,KAAK;AACrD,EAAI,QAAQ,sBAAiB,KAAK,eAAe,eAAe,SAAS,EAAE;AAC3E,UAAQ,OAAO;AAAA,IACbA,OAAM;AAAA,MACJ,KAAK,KAAK,aAAa,eAAe,CAAC,iBAAc,KAAK,iBAAiB,eAAe,CAAC,8BAA2B,KAAK,MAAM;AAAA;AAAA;AAAA,IACnI;AAAA,EACF;AAEA,MAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,IAAI,KAAK,kCAAkC;AAC3C;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAwB;AACrD,UAAM,OAAW,QAAQ,EAAE,QAAQ;AACnC,UAAM,SAAS,EAAE;AACjB,UAAM,YACJ,SAAS,IACLA,OAAM,MAAM,KAAK,SAAS,KAAK,QAAQ,CAAC,CAAC,GAAG,IAC5C,SAAS,IACPA,OAAM,IAAI,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC,GAAG,IACzCA,OAAM,IAAI,MAAM;AACxB,WAAO;AAAA,MACL,OAAO,EAAE,IAAI;AAAA,MACT,SAAS,EAAE,UAAU,EAAE;AAAA,MAC3B;AAAA,MACA,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AAAA,MACtB,gBAAgB,EAAE,SAAS;AAAA,MAC3B,gBAAgB,EAAE,SAAS;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,CAAC;AAED,EAAI,MAAM,MAAM,CAAC,KAAK,UAAU,QAAQ,SAAS,WAAW,OAAO,KAAK,CAAC;AAEzE,UAAQ,OAAO,MAAM,IAAI;AACzB,aAAW,KAAK,KAAK,QAAQ,MAAM,GAAG,CAAC,GAAG;AACxC,UAAM,MAAM,EAAE;AACd,YAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,SAAI,IAAQ,SAAS,EAAE,UAAU,EAAE,IAAI,IAAI;AACjF,YAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,SAAS,IAAI,SAAS,EAAE,KAAK,IAAI,IAAI;AAC7E,YAAQ,OAAO,MAAMA,OAAM,IAAI,UAAU,IAAI,EAAE,OAAO,QAAQ,CAAC,IAAI,IAAI;AACvE,QAAI,EAAE,mBAAmB,GAAG;AAC1B,cAAQ,OAAO,MAAMA,OAAM,IAAI,WAAW,IAAI,IAAI,EAAE,iBAAiB,QAAQ,CAAC,CAAC,MAAM;AAAA,IACvF;AACA,YAAQ,OAAO,MAAM,IAAI;AACzB,YAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,cAAc,IAAI,MAAM,IAAI;AAAA,EACtE;AAEA,MAAI,KAAK,QAAQ,SAAS,GAAG;AAC3B,YAAQ,OAAO,MAAMA,OAAM,IAAI;AAAA,eAAa,KAAK,QAAQ,SAAS,CAAC;AAAA,CAAS,CAAC;AAAA,EAC/E;AACF;;;AD1EO,SAAS,yBAAyBC,UAAwB;AAC/D,QAAM,WAAWA,SAAQ,QAAQ,UAAU,EAAE,YAAY,4BAA4B;AAErF,WACG,QAAQ,SAAS,EAAE,WAAW,KAAK,CAAC,EACpC,YAAY,8CAA8C,EAC1D,OAAO,YAAY;AAClB,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,UAAM,EAAE,GAAG,IAAI,MAAM,OAAO,KAAqB,kBAAkB;AAEnE,IAAI,QAAQ,iBAAiB;AAC7B,YAAQ,OAAO;AAAA,MACbC,OAAM,IAAI,kEAAkE;AAAA,IAC9E;AAEA,QAAI,aAAa;AACjB,UAAM,QAAQ,CAAC,MAAc,aAAqB;AAAA,MAChD,IAAI,OAAO,EAAE,UAAU;AAAA,MACvB;AAAA,MACA;AAAA,MACA,OAAO,CAAC,EAAE,MAAM,QAAiB,MAAM,QAAQ,CAAC;AAAA,IAClD;AAEA,UAAM,WAAuC,CAAC;AAC9C,QAAI,iBAAgC;AACpC,UAAM,KAAKC,UAAS,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAEpF,QAAI;AACF,aAAO,MAAM;AACX,cAAM,YAAY,MAAM,GAAG,SAASD,OAAM,KAAK,OAAO,CAAC;AACvD,YAAI,CAAC,UAAU,KAAK,EAAG;AACvB,YAAI,UAAU,KAAK,MAAM,QAAS;AAElC,YAAI,mBAAmB,KAAM,kBAAiB,KAAK,IAAI;AACvD,iBAAS,KAAK,MAAM,QAAQ,SAAS,CAAC;AAEtC,gBAAQ,OAAO,MAAMA,OAAM,IAAI,eAAe,CAAC;AAE/C,YAAI;AACF,gBAAM,OAAO,MAAM,OAAO,OAAO,aAAa;AAAA,YAC5C;AAAA,YACA,cAAc;AAAA,UAChB,CAAC;AAED,gBAAM,SAAS,MAAM,YAAY,MAAM;AAAA,YACrC,QAAQ,CAAC,SAAS,QAAQ,OAAO,MAAM,IAAI;AAAA,YAC3C,YAAY,CAAC,SAAS;AACpB,sBAAQ,OAAO,MAAMA,OAAM,IAAI;AAAA,WAAc,IAAI;AAAA,CAAK,CAAC;AAAA,YACzD;AAAA,YACA,cAAc,CAAC,MAAM,eAAe;AAClC,kBAAI,WAAW,SAAS;AACtB,wBAAQ,OAAO,MAAMA,OAAM,IAAI,cAAc,IAAI,KAAK,KAAK,UAAU,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,CAAI,CAAC;AAAA,cACrG;AAAA,YACF;AAAA,UACF,CAAC;AAED,kBAAQ,OAAO,MAAM,MAAM;AAE3B,cAAI,OAAO,eAAe;AACxB,qBAAS,KAAK,MAAM,aAAa,OAAO,aAAa,CAAC;AAAA,UACxD;AAEA,cAAI;AACF,kBAAM,kBAAkB,QAAQ,IAAI,UAAU,OAAO,aAAa,cAAc;AAAA,UAClF,SAAS,YAAY;AACnB,YAAI;AAAA,cACF,2BAA2B,sBAAsB,QAAQ,WAAW,UAAU,OAAO,UAAU,CAAC;AAAA,YAClG;AAAA,UACF;AAEA,cAAI,OAAO,YAAY;AACrB,8BAAkB,OAAO,YAAqC,UAAU;AAAA,UAC1E;AAEA,cAAI,OAAO,aAAa;AACtB,+BAAmB,OAAO,aAAuC,UAAU;AAC3E;AAAA,UACF;AAAA,QACF,SAAS,GAAG;AACV,kBAAQ,OAAO,MAAM,IAAI;AACzB,UAAI,MAAM,eAAe,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,QACvE;AAAA,MACF;AAAA,IACF,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,aAAa,EACrB,YAAY,oFAAoF,EAChG,OAAO,OAAO,UAAkB;AAC/B,UAAM,aAAaF,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,YAAQ,OAAO,MAAMC,OAAM,IAAI,kBAAsB,SAAS,OAAO,EAAE,CAAC;AAAA,CAAQ,CAAC;AACjF,UAAM,YAAY,KAAK,IAAI;AAE3B,UAAM,EAAE,OAAO,YAAY,gBAAgB,UAAU,IAAI,MAAM,OAAO,cAAc,KAAK;AAEzF,UAAM,YAAY,KAAK,IAAI,IAAI,aAAa,KAAM,QAAQ,CAAC;AAC3D,YAAQ,OAAO,MAAMA,OAAM,IAAI,WAAW,OAAO;AAAA;AAAA,CAAQ,CAAC;AAE1D,UAAM,iBACJ,SACA,OAAO,UAAU,YACjB,MAAM,QAAS,MAAgC,OAAO,KACtD,OAAQ,MAA8B,UAAU;AAElD,QAAI,gBAAgB;AAClB,MAAI,KAAK,KAA+B;AAAA,IAC1C,OAAO;AACL,cAAQ,OAAO,MAAMA,OAAM,OAAO,iCAAiC,CAAC;AACpE,MAAI,KAAK;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR,OAAO;AAAA,UACP,WAAW,kBAAkB;AAAA,UAC7B;AAAA,UACA,YAAY,cAAc,KAAK,IAAI,IAAI;AAAA,QACzC;AAAA,QACA,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,OAAO,yBAAyB,kBAAkB,EAClD,OAAO,OAAO,YAAiC;AAC9C,UAAM,aAAaF,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,UAAM,SAAiC,EAAE,MAAM,OAAO;AACtD,QAAI,QAAQ,OAAQ,QAAO,SAAS,QAAQ;AAE5C,UAAM,OAAO,MAAM,OAAO,IAAmC,oBAAoB,MAAM;AAEvF,QAAI,WAAW,MAAM;AACnB,MAAI,KAAK,KAAK,WAAW;AACzB;AAAA,IACF;AAEA,QAAI,KAAK,YAAY,WAAW,GAAG;AACjC,MAAI,KAAK,6BAA6B;AACtC;AAAA,IACF;AAEA,IAAI,QAAQ,sBAAsB,KAAK,YAAY,MAAM,GAAG;AAE5D,UAAM,OAAO,KAAK,YAAY,IAAI,CAAC,MAAM;AACvC,YAAM,SAAS,aAAa,EAAE,MAAM;AACpC,YAAM,QAAQ,EAAE,cAAc,SAAS;AACvC,YAAM,UAAU,EAAE,eAAe,OAAO,EAAE,aAAa,WAAW,IAAI;AACtE,aAAO,CAAC,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,QAAY,SAAS,OAAO,EAAE,GAAG,SAAa,aAAa,EAAE,UAAU,CAAC;AAAA,IACpG,CAAC;AAED,IAAI,MAAM,MAAM,CAAC,MAAM,UAAU,SAAS,WAAW,SAAS,CAAC;AAAA,EACjE,CAAC;AAEH,WACG,QAAQ,WAAW,EACnB,YAAY,+BAA+B,EAC3C,OAAO,OAAO,OAAe;AAC5B,UAAM,aAAaD,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,UAAM,aAAa,MAAM,OAAO,IAAgB,oBAAoB,EAAE,EAAE;AAExE,QAAI,WAAW,MAAM;AACnB,MAAI,KAAK,UAAU;AACnB;AAAA,IACF;AAEA,IAAI,QAAQ,sBAA0B,IAAI,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;AAEpE,IAAI,MAAM;AAAA,MACR,CAAC,UAAU,aAAa,WAAW,MAAM,CAAC;AAAA,MAC1C,CAAC,WAAW,IAAI,KAAK,WAAW,UAAU,EAAE,eAAe,CAAC;AAAA,MAC5D,CAAC,WAAW,IAAI,KAAK,WAAW,UAAU,EAAE,eAAe,CAAC;AAAA,IAC9D,CAAC;AAED,QAAI,WAAW,cAAc;AAC3B,yBAAmB,WAAW,cAAc,UAAU;AAAA,IACxD;AAAA,EACF,CAAC;AAEH,WACG,QAAQ,aAAa,EACrB,YAAY,2BAA2B,EACvC,OAAO,OAAO,OAAe;AAC5B,UAAM,aAAaD,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAC,aAAY,MAAM;AAElB,UAAM,OAAO,OAAO,oBAAoB,EAAE,EAAE;AAC5C,IAAI,QAAQ,2BAA2B;AAAA,EACzC,CAAC;AACL;AAEA,SAASA,aAAY,QAAyB;AAC5C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,IAAI,MAAM,wBAA4B,KAAK,eAAe,IAAI,SAAS;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAGA,SAAS,qBACP,UACA,aACA,gBACyB;AACzB,QAAM,QAAiC,EAAE,SAAS;AAClD,QAAM,OAAgC;AAAA,IACpC,eAAe;AAAA,IACf,eAAe,CAAC;AAAA,IAChB,oBAAoB,CAAC;AAAA,IACrB,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAEA,MACE,eACA,OAAO,gBAAgB,YACvB,MAAM,QAAS,YAAsC,OAAO,GAC5D;AACA,UAAM,UAAW,YAAuC;AACxD,UAAM,eAAe;AACrB,UAAM,SAAS;AACf,SAAK,gBAAgB,kBAAkB,OAAO,KAAK,IAAI,IAAI,iBAAiB;AAC5E,SAAK,cAAc,QAAQ,SAAS;AACpC,SAAK,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,EAC5C;AAEA,QAAM,WAAW;AACjB,SAAO;AACT;AAEA,eAAe,kBACb,QACA,cACA,UACA,aACA,gBACe;AACf,QAAM,OAAO,MAAM,oBAAoB,YAAY,IAAI,qBAAqB,UAAU,aAAa,cAAc,CAAC;AACpH;AAEA,SAAS,aAAa,QAAwB;AAC5C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAOC,OAAM,MAAM,MAAM;AAAA,IAC3B,KAAK;AACH,aAAOA,OAAM,OAAO,MAAM;AAAA,IAC5B,KAAK;AACH,aAAOA,OAAM,IAAI,MAAM;AAAA,IACzB;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,mBAAmB,OAAoB,YAAiC;AAC/E,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,KAAK;AACd;AAAA,EACF;AAEA,EAAI,QAAQ,cAAc;AAE1B,UAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,MAAM,KAAK,IAAI,MAAM;AAC5D,UAAQ,OAAO,MAAM,OAAOA,OAAM,OAAO,MAAM,MAAM,IAAI,IAAI;AAE7D,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,WAAW,IAAI,MAAM;AAC5D,UAAM,OAAO,MAAM,QAAQ,IAAI,CAAC,MAAM;AACpC,YAAM,OAAW,QAAQ,EAAE,QAAQ;AACnC,YAAM,UAAU,EAAE,QAAQ,SAAS,IAAI,EAAE,QAAQ,KAAK,IAAI,IAAI;AAC9D,YAAM,MAAM,EAAE,YAAgB,SAAS,EAAE,SAAS,IAAI;AACtD,aAAO,CAAK,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,SAAS,GAAG;AAAA,IAC1D,CAAC;AACD,IAAI,MAAM,MAAM,CAAC,UAAU,QAAQ,WAAW,KAAK,CAAC;AAEpD,YAAQ,OAAO,MAAM,IAAI;AACzB,eAAW,KAAK,MAAM,SAAS;AAC7B,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,SAAI,IAAQ,SAAS,EAAE,UAAU,EAAE,IAAI,IAAI;AACjF,cAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,eAAe,IAAI,EAAE,aAAa,IAAI;AAC9E,cAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,cAAc,IAAI,EAAE,gBAAgB,IAAI;AAAA,IAClF;AAAA,EACF;AAEA,MAAI,MAAM,KAAK,SAAS,GAAG;AACzB,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,iBAAiB,IAAI,MAAM;AAClE,eAAW,OAAO,MAAM,MAAM;AAC5B,cAAQ,OAAO,MAAM,OAAOA,OAAM,OAAO,QAAG,IAAI,MAAM,MAAM,IAAI;AAAA,IAClE;AAAA,EACF;AAEA,UAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,GAAG,MAAM,WAAW,iBAAc,MAAM,KAAK,MAAM,gBAAgB,IAAI,IAAI;AACrH;;;AEtSA,SAASE,aAAY,QAAyB;AAC5C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,IAAI,MAAM,+CAA+C;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,IAAM,kBAAkB,CAAC,kBAAkB,sBAAsB,oBAAoB;AAErF,SAAS,UAAU,GAA8D;AAC/E,SAAO,MAAM,UAAc,gBAAsC,SAAS,CAAC;AAC7E;AAEO,SAAS,mBACd,WACA,SACAC,QAAkC,MAAM,QACpB;AACpB,MAAI,WAAW,CAAC,UAAU,OAAO,GAAG;AAClC,UAAM,IAAI,MAAM,yBAAyB,OAAO,WAAW,gBAAgB,KAAK,MAAM,CAAC,EAAE;AAAA,EAC3F;AAEA,MAAI,CAAC,UAAW,QAAO;AAEvB,MAAI,CAAC,UAAU,SAAS,GAAG;AACzB,UAAM,IAAI,MAAM,sBAAsB,SAAS,WAAW,gBAAgB,KAAK,MAAM,CAAC,EAAE;AAAA,EAC1F;AAEA,MAAI,WAAW,YAAY,WAAW;AACpC,IAAAA,MAAK,uDAAuD,OAAO,IAAI;AACvE,WAAO;AAAA,EACT;AAEA,SAAO,WAAW;AACpB;AAKA,SAAS,gBAAgB,MAcE;AACzB,QAAM,UAA8B,CAAC;AACrC,QAAM,MAAM,CAAC,GAAW,MAA0B;AAChD,QAAI,MAAM,UAAa,MAAM,GAAI,SAAQ,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,EACtD;AACA,MAAI,WAAW,KAAK,OAAO;AAC3B,MAAI,UAAU,KAAK,MAAM;AACzB,MAAI,UAAU,KAAK,MAAM;AACzB,MAAI,OAAO,KAAK,GAAG;AACnB,MAAI,aAAa,KAAK,SAAS;AAC/B,MAAI,gBAAgB,KAAK,YAAY;AACrC,MAAI,gBAAgB,KAAK,YAAY;AACrC,MAAI,uBAAuB,KAAK,mBAAmB;AACnD,MAAI,gBAAgB,KAAK,YAAY;AACrC,MAAI,gBAAgB,KAAK,YAAY;AACrC,MAAI,qBAAqB,KAAK,iBAAiB;AAC/C,MAAI,iBAAiB,KAAK,aAAa;AACvC,MAAI,SAAS,KAAK,KAAK;AACvB,SAAO,OAAO,YAAY,OAAO;AACnC;AAEO,SAAS,oBAAoBC,UAAwB;AAC1D,EAAAA,SACG,QAAQ,MAAM,EACd;AAAA,IACC;AAAA,EAEF,EACC;AAAA,IACC;AAAA,IACA,8BAA8B,gBAAgB,KAAK,KAAK,CAAC;AAAA,EAC3D,EACC;AAAA,IACC;AAAA,IACA,uBAAuB,gBAAgB,KAAK,IAAI,CAAC;AAAA,EACnD,EACC,OAAO,mBAAmB,2HAA2H,EACrJ,OAAO,mBAAmB,0EAAqE,EAC/F,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,sBAAsB,0BAA0B,EACvD,OAAO,yBAAyB,mCAAmC,EACnE,OAAO,yBAAyB,mCAAmC,EACnE,OAAO,kCAAkC,4BAA4B,EACrE,OAAO,yBAAyB,oCAAoC,EACpE,OAAO,yBAAyB,oCAAoC,EACpE,OAAO,8BAA8B,+DAAiE,EACtG,OAAO,2BAA2B,iDAAiD,EACnF,OAAO,eAAe,kDAA6C,IAAI,EACvE,OAAO,OAAO,WAA+B,MAAmB;AAC/D,UAAM,aAAaA,SAAQ,KAAoB;AAE/C,QAAI;AACJ,QAAI;AACF,gBAAU,mBAAmB,WAAW,EAAE,SAAa,IAAI;AAAA,IAC7D,SAAS,GAAG;AACV,MAAI,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAF,aAAY,MAAM;AAElB,UAAM,SAAS,gBAAgB;AAAA,MAC7B;AAAA,MACA,QAAQ,EAAE;AAAA,MACV,QAAQ,EAAE;AAAA,MACV,KAAK,EAAE;AAAA,MACP,WAAW,EAAE;AAAA,MACb,cAAc,EAAE;AAAA,MAChB,cAAc,EAAE;AAAA,MAChB,qBAAqB,EAAE;AAAA,MACvB,cAAc,EAAE;AAAA,MAChB,cAAc,EAAE;AAAA,MAChB,mBAAmB,EAAE;AAAA,MACrB,eAAe,EAAE;AAAA,MACjB,OAAO,EAAE;AAAA,IACX,CAAC;AAED,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,IAAgB,aAAa,MAAM;AAC/D,UAAI,OAAO,OAAO;AAChB,QAAI,MAAM,OAAO,KAAK;AACtB,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,wBAAkB,QAAQ,UAAU;AAAA,IACtC,SAAS,GAAG;AACV,MAAI,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;ACrKA,SAAkB,4BAA4B;AAC9C,SAAS,gBAAgB;AACzB,OAAOG,YAAW;;;ACFlB,OAAOC,YAAW;AAUlB,SAAS,YAAY,QAAwB;AAC3C,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AACH,aAAOC,OAAM,MAAM,MAAM;AAAA,IAC3B,KAAK;AAAA,IACL,KAAK;AACH,aAAOA,OAAM,OAAO,MAAM;AAAA,IAC5B,KAAK;AACH,aAAOA,OAAM,IAAI,MAAM;AAAA,IACzB,KAAK;AACH,aAAOA,OAAM,KAAK,MAAM;AAAA,IAC1B;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,IAAI,OAAgB,WAAW,GAAW;AACjD,QAAM,IAAI,OAAO,KAAK;AACtB,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAEO,SAAS,8BAA8B,SAA6B;AACzE,SAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,MAAM;AACrC,UAAM,cAAc,IAAI,EAAE,eAAe,EAAE,UAAU,GAAG;AACxD,UAAM,YACJ,EAAE,aAAa,QAAQ,EAAE,cAAc,SAAY,SAAY,IAAI,EAAE,SAAS;AAChF,WAAO;AAAA,MACL,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,MACzB,UAAU,OAAO,EAAE,YAAY,EAAE;AAAA,MACjC,YAAY,EAAE,aAAa,OAAO,EAAE,UAAU,IAAI;AAAA,MAClD,WAAW,EAAE,YAAY,OAAO,EAAE,SAAS,IAAI;AAAA,MAC/C,UAAU,IAAI,EAAE,UAAU,WAAW;AAAA,MACrC,SAAS,IAAI,EAAE,SAAS,IAAI,WAAW;AAAA,MACvC,WAAW,IAAI,EAAE,SAAS;AAAA,MAC1B,WAAW,IAAI,EAAE,SAAS;AAAA,MAC1B,QAAQ,IAAI,EAAE,MAAM;AAAA,MACpB,kBAAkB,IAAI,EAAE,gBAAgB;AAAA,MACxC,mBAAmB,IAAI,EAAE,iBAAiB;AAAA,MAC1C,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,MAC3C,QAAQ,EAAE,UAAU,OAAO,OAAO,QAAQ,EAAE,MAAM;AAAA,IACpD;AAAA,EACF,CAAC;AACH;AAEO,SAAS,yBACd,WAC4B;AAC5B,SAAO,UACJ,OAAO,CAAC,MAAM,OAAO,EAAE,eAAe,EAAE,CAAC,EACzC,IAAI,CAAC,OAAO;AAAA,IACX,aAAa,OAAO,EAAE,WAAW;AAAA,IACjC,QAAQ,OAAO,EAAE,UAAU,SAAS,EAAE,YAAY;AAAA,IAClD,mBAAmB,IAAI,EAAE,cAAc;AAAA,IACvC,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,cAAc;AAAA,IACd,qBAAqB,MAAM,QAAQ,EAAE,UAAU,IAC3C,EAAE,WAAW,OAAO,CAAC,KAAK,UAAU,MAAM,IAAI,MAAM,QAAQ,GAAG,CAAC,IAChE;AAAA,EACN,EAAE;AACN;AAEO,SAAS,4BACd,QACA,YACM;AACN,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,MAAM;AACf;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,YAAY,CAAC;AACxE,QAAM,UAAU,OAAO,WAAW,CAAC;AACnC,QAAM,SAAS,OAAO,YAAY,QAAQ,SAAS;AAEnD,EAAI,QAAQ,0BAAqB,MAAM,EAAE;AACzC,UAAQ,OAAO;AAAA,IACbA,OAAM;AAAA,MACJ,KAAK,IAAI,OAAO,eAAe,UAAU,MAAM,CAAC,iBAAkB;AAAA,QAChE,IAAI,QAAQ,cAAc;AAAA,MAC5B,CAAC,wBAAqB,IAAI,QAAQ,cAAc,CAAC;AAAA;AAAA;AAAA,IACnD;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,IAAI,KAAK,kCAAkC;AAC3C;AAAA,EACF;AAEA,QAAM,OAAO,UAAU,IAAI,CAAC,MAAM;AAChC,UAAM,SAAS,OAAO,EAAE,UAAU,SAAS;AAC3C,UAAM,QAAQ,IAAI,EAAE,OAAO,KAAK;AAChC,UAAM,WAAW,IAAI,EAAE,OAAO,yBAAyB;AACvD,UAAM,SAAS,MAAM,QAAQ,EAAE,UAAU,IAAI,EAAE,WAAW,SAAS;AACnE,UAAM,eAAe,MAAM,QAAQ,EAAE,aAAa,IAC9C,EAAE,cAAc,OAAO,CAAC,UAAU,MAAM,WAAW,KAAK,EAAE,SAC1D;AACJ,WAAO;AAAA,MACD,SAAS,OAAO,EAAE,YAAY,EAAE,eAAe,QAAG,GAAG,EAAE;AAAA,MAC3D,YAAY,MAAM;AAAA,MACd,SAAS,IAAI,EAAE,cAAc,CAAC;AAAA,MAClC,eAAe,IAAI,EAAE,aAAa,CAAC;AAAA,MACnC,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,MACtB,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,MACxB,OAAO,MAAM;AAAA,MACb,iBAAiB,IAAIA,OAAM,MAAM,GAAG,IAAIA,OAAM,OAAO,OAAO,YAAY,CAAC;AAAA,IAC3E;AAAA,EACF,CAAC;AAED,EAAI,MAAM,MAAM,CAAC,UAAU,UAAU,UAAU,SAAS,WAAW,SAAS,UAAU,OAAO,CAAC;AAE9F,UAAQ,OAAO,MAAM,IAAI;AACzB,aAAW,YAAY,UAAU,MAAM,GAAG,CAAC,GAAG;AAC5C,UAAM,SAAS,OAAO,SAAS,UAAU,SAAS;AAClD,YAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,SAAI,IAAQ,SAAS,OAAO,SAAS,YAAY,SAAS,eAAe,QAAG,GAAG,EAAE,IAAI,IAAI;AAC/H,YAAQ,OAAO,MAAM,SAASA,OAAM,IAAI,UAAU,IAAI,YAAY,MAAM,CAAC;AACzE,QAAI,SAAS,WAAW;AACtB,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,aAAa,IAAQ,SAAS,SAAS,WAAW,GAAG,CAAC;AAAA,IAC9F;AACA,YAAQ,OAAO,MAAM,IAAI;AAEzB,UAAM,SAAS,MAAM,QAAQ,SAAS,UAAU,IAAI,SAAS,aAAa,CAAC;AAC3E,eAAW,SAAS,OAAO,MAAM,GAAG,CAAC,GAAG;AACtC,cAAQ,OAAO;AAAA,QACb,SACEA,OAAM,IAAI,SAAS,IACnB,GAAG,OAAO,MAAM,QAAQ,KAAK,CAAC,IAAI,OAAO,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,MAAM,KAAK,EAAE,QAAQ,CAAC,CAAC,QACpF,SAAS,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA;AAAA,MAE5C;AAAA,IACF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,cAAQ,OAAO,MAAMA,OAAM,IAAI,cAAS,OAAO,SAAS,CAAC;AAAA,CAAgB,CAAC;AAAA,IAC5E;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,GAAG;AACxB,YAAQ,OAAO,MAAMA,OAAM,IAAI;AAAA,eAAa,UAAU,SAAS,CAAC;AAAA,CAAmB,CAAC;AAAA,EACtF;AACF;AAEA,SAAS,eAAe,OAAuB;AAC7C,QAAM,YAAgB,SAAS,KAAK,IAAI,KAAK,CAAC;AAC9C,MAAI,QAAQ,EAAG,QAAOA,OAAM,MAAM,IAAI,SAAS,EAAE;AACjD,MAAI,QAAQ,EAAG,QAAOA,OAAM,OAAO,IAAI,SAAS,EAAE;AAClD,SAAOA,OAAM,IAAI,OAAO;AAC1B;;;AD1IA,IAAMC,mBAAkB,CAAC,kBAAkB,sBAAsB,oBAAoB;AAiCrF,SAASC,aAAY,QAAyB;AAC5C,MAAI,CAAC,OAAO,iBAAiB;AAC3B,IAAI,MAAM,+CAA+C;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAASC,WAAU,GAA8D;AAC/E,SAAO,MAAM,UAAcF,iBAAsC,SAAS,CAAC;AAC7E;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,QAAM,IAAI,OAAO,KAAK;AACtB,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAChC,UAAM,IAAI,qBAAqB,gCAAgC;AAAA,EACjE;AACA,SAAO;AACT;AAEO,SAAS,oBAAoB,OAAuB;AACzD,QAAM,IAAI,OAAO,KAAK;AACtB,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,GAAG;AACjC,UAAM,IAAI,qBAAqB,4BAA4B;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,QAAM,IAAI,OAAO,KAAK;AACtB,MAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GAAG;AACjC,UAAM,IAAI,qBAAqB,6BAA6B;AAAA,EAC9D;AACA,SAAO;AACT;AAEA,SAAS,SAAS,SAA6B,KAAa,OAAiC;AAC3F,MAAI,UAAU,UAAa,UAAU,GAAI,SAAQ,KAAK,CAAC,KAAK,KAAK,CAAC;AACpE;AAEA,SAASG,iBAAgB,SAA6B,MAAkD;AACtG,QAAM,UAA8B,CAAC;AACrC,WAAS,SAAS,WAAW,OAAO;AACpC,WAAS,SAAS,UAAU,KAAK,MAAM;AACvC,WAAS,SAAS,OAAO,KAAK,GAAG;AACjC,WAAS,SAAS,aAAa,KAAK,SAAS;AAC7C,WAAS,SAAS,gBAAgB,KAAK,YAAY;AACnD,WAAS,SAAS,gBAAgB,KAAK,YAAY;AACnD,WAAS,SAAS,uBAAuB,KAAK,mBAAmB;AACjE,WAAS,SAAS,gBAAgB,KAAK,YAAY;AACnD,WAAS,SAAS,gBAAgB,KAAK,YAAY;AACnD,WAAS,SAAS,qBAAqB,KAAK,iBAAiB;AAC7D,WAAS,SAAS,iBAAiB,KAAK,aAAa;AACrD,WAAS,SAAS,SAAS,KAAK,KAAK;AACrC,SAAO,OAAO,YAAY,OAAO;AACnC;AAEA,SAAS,oBAAoB,MAAkD;AAC7E,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,KAAK,SAAS,WAAW;AAAA,IACjC,GAAI,KAAK,kBAAkB,UAAa,EAAE,gBAAgB,KAAK,cAAc;AAAA,IAC7E,GAAI,KAAK,oBAAoB,UAAa,EAAE,mBAAmB,KAAK,gBAAgB;AAAA,IACpF,GAAI,KAAK,sBAAsB,UAAa,EAAE,sBAAsB,KAAK,kBAAkB;AAAA,IAC3F,eAAe,KAAK;AAAA,IACpB,kBAAkB,KAAK;AAAA,IACvB,+BAA+B,KAAK;AAAA,IACpC,yBAAyB,KAAK;AAAA,IAC9B,oBAAoB,KAAK;AAAA,IACzB,gBAAgB,KAAK;AAAA,IACrB,eAAe,KAAK;AAAA,IACpB,YAAY,KAAK;AAAA,IACjB,iBAAiB,KAAK;AAAA,IACtB,aAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,yBAAyB,MAAgC;AAChE,QAAM,uBACJ,KAAK,oBAAoB,UAAa,KAAK,sBAAsB;AACnE,MAAI,wBAAwB,KAAK,kBAAkB,QAAW;AAC5D,IAAI;AAAA,MACF;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,eAAe,gBAAgB,MAA+D;AAC5F,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,MAAM,SAAS,MAAM,MAAM,UAAU,IAAI,MAAM,SAAS,MAAM,MAAM;AAC1E,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,eAAe,YAA6B;AAC1C,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ,OAAO;AACvC,WAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,EACjE;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAC9C;AAEA,eAAe,kBACb,QACA,SACoC;AACpC,SAAO,OAAO,KAAgC,wBAAwB,OAAO;AAC/E;AAEO,SAAS,0BAA0BC,UAAwB;AAChE,QAAM,YAAYA,SACf,QAAQ,WAAW,EACnB,YAAY,yCAAyC;AAExD,YACG,QAAQ,OAAO,EACf,YAAY,qEAAqE,EACjF;AAAA,IACC;AAAA,IACA,8BAA8BJ,iBAAgB,KAAK,KAAK,CAAC;AAAA,IACzD;AAAA,EACF,EACC,OAAO,oBAAoB,uBAAuBA,iBAAgB,KAAK,IAAI,CAAC,EAAE,EAC9E,OAAO,mBAAmB,qGAAqG,EAC/H,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,sBAAsB,0BAA0B,EACvD,OAAO,yBAAyB,mCAAmC,EACnE,OAAO,yBAAyB,mCAAmC,EACnE,OAAO,kCAAkC,4BAA4B,EACrE,OAAO,yBAAyB,4CAA4C,EAC5E,OAAO,yBAAyB,4CAA4C,EAC5E,OAAO,8BAA8B,qDAAqD,EAC1F,OAAO,2BAA2B,iDAAiD,EACnF,OAAO,eAAe,iDAAiD,IAAI,EAC3E,OAAO,0BAA0B,oEAAoE,mBAAmB,EACxH,OAAO,6BAA6B,iEAAiE,mBAAmB,EACxH,OAAO,gCAAgC,wDAAwD,mBAAmB,EAClH,OAAO,yBAAyB,0CAA0C,kBAAkB,GAAG,EAC/F,OAAO,4BAA4B,yBAAyB,kBAAkB,GAAG,EACjF,OAAO,yCAAyC,yCAAyC,kBAAkB,IAAI,EAC/G,OAAO,qCAAqC,+BAA+B,kBAAkB,IAAI,EACjG,OAAO,8BAA8B,8CAA8C,kBAAkB,EAAE,EACvG,OAAO,0BAA0B,sCAAsC,kBAAkB,GAAG,EAC5F,OAAO,mCAAmC,mDAAmD,kBAAkB,GAAG,EAClH,OAAO,wBAAwB,yCAAyC,kBAAkB,IAAI,EAC9F,OAAO,mCAAmC,qDAAqD,kBAAkB,CAAC,EAClH,OAAO,qBAAqB,wCAAwC,kBAAkB,CAAC,EACvF,OAAO,wBAAwB,wDAAwD,EACvF,OAAO,YAAY,8DAA8D,EACjF,OAAO,YAAY,gDAAgD,EACnE,OAAO,OAAO,WAA+B,MAA0B;AACtE,UAAM,aAAaI,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AACvC,IAAAH,aAAY,MAAM;AAClB,6BAAyB,CAAC;AAE1B,QAAI,UAAU,EAAE,WAAW,aAAa;AACxC,QAAI,CAACC,WAAU,OAAO,GAAG;AACvB,MAAI,MAAM,sBAAsB,OAAO,WAAWF,iBAAgB,KAAK,MAAM,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,EAAE,WAAW,aAAa,cAAc,oBAAoB,EAAE,YAAY,WAAW;AACvF,MAAI,KAAK,uDAAuD,EAAE,OAAO,IAAI;AAC7E,gBAAU,EAAE;AAAA,IACd;AAEA,UAAM,OAAO,MAAM,OAAO,IAAgB,aAAaG,iBAAgB,SAAS,CAAC,CAAC;AAClF,QAAI,KAAK,OAAO;AACd,MAAI,MAAM,KAAK,KAAK;AACpB,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,MAAI,KAAK,iDAAiD;AAC1D;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,gBAAgB,EAAE,WAAW;AACvD,UAAM,UAAiC;AAAA,MACrC,UAAU,oBAAoB,CAAC;AAAA,MAC/B,SAAS,8BAA8B,KAAK,OAAO;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,CAAC,WAAW,MAAM;AACpB,cAAQ,OAAO;AAAA,QACbE,OAAM;AAAA,UACJ,kCAAkC,KAAK,QAAQ,MAAM,IAAI,OAAO;AAAA;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,kBAAkB,QAAQ,OAAO;AACrD,UAAM,cAAc,MAAM,UAAU,CAAC;AAErC,QAAI,EAAE,QAAQ;AACZ,YAAM,gBAAuC;AAAA,QAC3C,GAAG;AAAA,QACH,aAAa,yBAAyB,YAAY,aAAa,CAAC,CAAC;AAAA,MACnE;AACA,YAAM,SAAS,MAAM,kBAAkB,QAAQ,aAAa;AAC5D,UAAI,WAAW,MAAM;AACnB,QAAI,KAAK,EAAE,SAAS,OAAO,QAAQ,OAAO,CAAC;AAAA,MAC7C,OAAO;AACL,oCAA4B,aAAa,UAAU;AACnD,gBAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,kCAAkC,IAAI,IAAI;AACjF,oCAA4B,OAAO,UAAU,CAAC,GAAG,UAAU;AAAA,MAC7D;AACA;AAAA,IACF;AAEA,QAAI,WAAW,MAAM;AACnB,MAAI,KAAK,KAAK;AAAA,IAChB,OAAO;AACL,kCAA4B,aAAa,UAAU;AAAA,IACrD;AAAA,EACF,CAAC;AACL;;;AXtQA,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,yEAAoE,EAChF,QAAQ,OAAW,EACnB,OAAO,UAAU,mCAAmC,EACpD,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,mBAAmB,2BAA2B,EACrD,OAAO,aAAa,2BAA2B,EAC/C,OAAO,cAAc,wBAAwB;AAEhD,qBAAqB,OAAO;AAC5B,sBAAsB,OAAO;AAE7B,uBAAuB,OAAO;AAC9B,yBAAyB,OAAO;AAChC,oBAAoB,OAAO;AAC3B,0BAA0B,OAAO;AAEjC,QAAQ,KAAK,aAAa,CAAC,cAAc,kBAAkB;AACzD,QAAM,OAAO,QAAQ,KAAK;AAC1B,MAAI,KAAK,UAAU,OAAO;AACxB,YAAQ,IAAI,cAAc;AAAA,EAC5B;AACA,MAAI,KAAK,SAAS;AAChB,UAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,OAAO,MAAU,IAAI,yBAAyB,OAAO;AAAA,CAAI,CAAC;AAAA,EACpE;AACF,CAAC;AAED,eAAe,OAAO;AACpB,MAAI;AACF,UAAM,QAAQ,WAAW,QAAQ,IAAI;AAAA,EACvC,SAAS,GAAG;AACV,QAAI,aAAa,SAAS,EAAE,QAAQ,SAAS,WAAW,GAAG;AACzD,MAAI,MAAM,EAAE,OAAO;AAAA,IACrB,OAAO;AACL,MAAI,MAAM,qBAAqB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAC3E,UAAI,QAAQ,KAAK,EAAE,SAAS;AAC1B,gBAAQ,MAAM,CAAC;AAAA,MACjB;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,KAAK;","names":["Command","program","chalk","error","program","chalk","program","requireAuth","readline","chalk","chalk","chalk","program","requireAuth","chalk","readline","requireAuth","warn","program","chalk","chalk","chalk","PROFILE_CHOICES","requireAuth","isProfile","feedQueryParams","program","chalk","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hedge-layer/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "CLI for Hedge Layer — prediction market intelligence from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"tsup": "^8.4.0",
|
|
48
48
|
"typescript": "^5.7.0",
|
|
49
49
|
"typescript-eslint": "^8.57.0",
|
|
50
|
-
"vitest": "^4.
|
|
50
|
+
"vitest": "^4.1.8"
|
|
51
51
|
}
|
|
52
52
|
}
|