@hedge-layer/cli 0.2.0 → 1.1.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 +51 -35
- package/dist/index.mjs +330 -266
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
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
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -20,8 +20,11 @@ Requires Node.js 22 or later.
|
|
|
20
20
|
# 2. Authenticate the CLI
|
|
21
21
|
hl auth login
|
|
22
22
|
|
|
23
|
-
# 3.
|
|
24
|
-
hl
|
|
23
|
+
# 3. Generate a Market Brief
|
|
24
|
+
hl brief "US China trade war tariffs"
|
|
25
|
+
|
|
26
|
+
# 4. Or start an interactive research session
|
|
27
|
+
hl research
|
|
25
28
|
```
|
|
26
29
|
|
|
27
30
|
## Authentication
|
|
@@ -37,55 +40,68 @@ hl auth logout # Remove stored token
|
|
|
37
40
|
You can also pass a token inline for CI/scripts:
|
|
38
41
|
|
|
39
42
|
```bash
|
|
40
|
-
hl --token hl_abc123...
|
|
43
|
+
hl --token hl_abc123... research list
|
|
41
44
|
```
|
|
42
45
|
|
|
43
46
|
## Commands
|
|
44
47
|
|
|
45
|
-
###
|
|
48
|
+
### Brief
|
|
46
49
|
|
|
47
|
-
|
|
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.
|
|
48
51
|
|
|
49
52
|
```bash
|
|
50
|
-
#
|
|
51
|
-
hl
|
|
52
|
-
hl
|
|
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
|
+
# Disable streaming (block until complete)
|
|
64
|
+
hl brief "AI regulation in Europe" --no-stream
|
|
53
65
|
```
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
| Option | Description |
|
|
68
|
+
|--------|-------------|
|
|
69
|
+
| `-l, --location <loc>` | Geographic context (e.g. `"Middle East"`, `"US"`) |
|
|
70
|
+
| `-t, --time-horizon <h>` | Time frame (e.g. `"3 months"`, `"2026"`) |
|
|
71
|
+
| `--tags <tags>` | Comma-separated focus area tags (e.g. `"geopolitics,energy"`) |
|
|
72
|
+
| `--min-volume <n>` | Minimum market volume in USD |
|
|
73
|
+
| `--max-yes-price <n>` | Maximum YES price (0-1) |
|
|
74
|
+
| `--no-stream` | Disable streaming — block until complete |
|
|
75
|
+
|
|
76
|
+
### Research
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
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.
|
|
58
79
|
|
|
59
80
|
```bash
|
|
60
|
-
# Start an interactive
|
|
61
|
-
hl
|
|
81
|
+
# Start an interactive research session (Q&A)
|
|
82
|
+
hl research
|
|
62
83
|
|
|
63
|
-
# List past
|
|
64
|
-
hl
|
|
65
|
-
hl
|
|
84
|
+
# List past research sessions
|
|
85
|
+
hl research list
|
|
86
|
+
hl research list --status completed
|
|
66
87
|
|
|
67
|
-
# View a specific
|
|
68
|
-
hl
|
|
88
|
+
# View a specific session and its Market Brief
|
|
89
|
+
hl research show <id>
|
|
69
90
|
|
|
70
|
-
# Delete
|
|
71
|
-
hl
|
|
91
|
+
# Delete a session
|
|
92
|
+
hl research delete <id>
|
|
72
93
|
```
|
|
73
94
|
|
|
74
|
-
|
|
95
|
+
For non-interactive, single-shot brief generation, use `hl brief` — it uses a dedicated API endpoint optimized for programmatic use.
|
|
96
|
+
|
|
97
|
+
### Markets
|
|
75
98
|
|
|
76
|
-
|
|
99
|
+
Polymarket orderbook tools.
|
|
77
100
|
|
|
78
101
|
```bash
|
|
79
|
-
#
|
|
80
|
-
hl
|
|
81
|
-
|
|
82
|
-
# From stdin
|
|
83
|
-
echo '{
|
|
84
|
-
"location": "33109",
|
|
85
|
-
"assetType": "residential",
|
|
86
|
-
"riskTypes": ["hurricane", "flood"],
|
|
87
|
-
"assetValue": 500000
|
|
88
|
-
}' | hl hedge -
|
|
102
|
+
# View orderbook for a specific CLOB token
|
|
103
|
+
hl markets orderbook <tokenId>
|
|
104
|
+
hl markets orderbook <tokenId> --size 1000
|
|
89
105
|
```
|
|
90
106
|
|
|
91
107
|
### Profile
|
|
@@ -109,7 +125,7 @@ hl profile
|
|
|
109
125
|
Every command supports `--json` for pipe-friendly output:
|
|
110
126
|
|
|
111
127
|
```bash
|
|
112
|
-
hl --json
|
|
128
|
+
hl --json research list | jq '.[0].id'
|
|
113
129
|
```
|
|
114
130
|
|
|
115
131
|
## Development
|
|
@@ -122,7 +138,7 @@ npm run build # Build with tsup
|
|
|
122
138
|
npm run dev # Watch mode
|
|
123
139
|
|
|
124
140
|
# Test against local dev server
|
|
125
|
-
node dist/index.mjs --api-url http://localhost:3000
|
|
141
|
+
node dist/index.mjs --api-url http://localhost:3000 research list
|
|
126
142
|
```
|
|
127
143
|
|
|
128
144
|
## Publishing
|
|
@@ -134,7 +150,7 @@ npm version patch # or minor / major
|
|
|
134
150
|
git push --tags
|
|
135
151
|
```
|
|
136
152
|
|
|
137
|
-
The workflow builds and publishes to npm when a version tag (`v*`) is pushed.
|
|
153
|
+
The workflow builds and publishes to npm when a version tag (`v*`) is pushed. Authentication uses npm's OIDC trusted publishers — no secrets required.
|
|
138
154
|
|
|
139
155
|
## Changelog
|
|
140
156
|
|
package/dist/index.mjs
CHANGED
|
@@ -149,6 +149,23 @@ var ApiClient = class {
|
|
|
149
149
|
}
|
|
150
150
|
return res.body;
|
|
151
151
|
}
|
|
152
|
+
async streamNdjson(path, body) {
|
|
153
|
+
this.log("POST (ndjson)", path);
|
|
154
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: this.headers({ Accept: "application/x-ndjson" }),
|
|
157
|
+
body: JSON.stringify(body)
|
|
158
|
+
});
|
|
159
|
+
this.log("POST (ndjson)", path, res.status);
|
|
160
|
+
if (!res.ok) {
|
|
161
|
+
const text = await res.text();
|
|
162
|
+
throw new ApiError(res.status, text);
|
|
163
|
+
}
|
|
164
|
+
if (!res.body) {
|
|
165
|
+
throw new ApiError(0, "No response body for stream");
|
|
166
|
+
}
|
|
167
|
+
return res.body;
|
|
168
|
+
}
|
|
152
169
|
};
|
|
153
170
|
var ApiError = class extends Error {
|
|
154
171
|
constructor(status, body) {
|
|
@@ -313,82 +330,8 @@ function registerAuthCommands(program2) {
|
|
|
313
330
|
});
|
|
314
331
|
}
|
|
315
332
|
|
|
316
|
-
// src/commands/
|
|
333
|
+
// src/commands/brief.ts
|
|
317
334
|
import chalk2 from "chalk";
|
|
318
|
-
function registerMarketCommands(program2) {
|
|
319
|
-
const markets = program2.command("markets").description("Polymarket orderbook tools");
|
|
320
|
-
markets.command("orderbook <tokenId>").description("Show orderbook spread and depth for a CLOB token").option("-s, --size <n>", "Size for slippage calculation").action(async (tokenId, cmdOpts) => {
|
|
321
|
-
const globalOpts = program2.opts();
|
|
322
|
-
const client = new ApiClient(globalOpts);
|
|
323
|
-
const params = { tokenId };
|
|
324
|
-
if (cmdOpts.size) params.size = cmdOpts.size;
|
|
325
|
-
const data = await client.get("/api/orderbook", params);
|
|
326
|
-
if (globalOpts.json) {
|
|
327
|
-
json(data);
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
heading("Orderbook");
|
|
331
|
-
if (data.spread) {
|
|
332
|
-
table([
|
|
333
|
-
["Best Bid", data.spread.bid.toFixed(4)],
|
|
334
|
-
["Best Ask", data.spread.ask.toFixed(4)],
|
|
335
|
-
["Spread", percent(data.spread.spread)],
|
|
336
|
-
["Ask Depth", currency(data.askDepth)]
|
|
337
|
-
]);
|
|
338
|
-
} else {
|
|
339
|
-
warn("No spread data available (empty orderbook)");
|
|
340
|
-
}
|
|
341
|
-
if (data.slippage) {
|
|
342
|
-
process.stdout.write("\n");
|
|
343
|
-
table([
|
|
344
|
-
["Avg Fill Price", data.slippage.avgPrice.toFixed(4)],
|
|
345
|
-
["Worst Price", data.slippage.worstPrice.toFixed(4)],
|
|
346
|
-
["Slippage", percent(data.slippage.slippage)],
|
|
347
|
-
["Fillable Size", currency(data.slippage.fillableSize)]
|
|
348
|
-
]);
|
|
349
|
-
}
|
|
350
|
-
if (data.book.asks.length > 0) {
|
|
351
|
-
process.stdout.write("\n" + chalk2.dim(" Top 5 asks:") + "\n");
|
|
352
|
-
const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);
|
|
353
|
-
table(askRows, ["Price", "Size"]);
|
|
354
|
-
}
|
|
355
|
-
if (data.book.bids.length > 0) {
|
|
356
|
-
process.stdout.write("\n" + chalk2.dim(" Top 5 bids:") + "\n");
|
|
357
|
-
const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);
|
|
358
|
-
table(bidRows, ["Price", "Size"]);
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/commands/profile.ts
|
|
364
|
-
function registerProfileCommand(program2) {
|
|
365
|
-
program2.command("profile").description("Show your user profile").action(async () => {
|
|
366
|
-
const globalOpts = program2.opts();
|
|
367
|
-
const client = new ApiClient(globalOpts);
|
|
368
|
-
requireAuth(client);
|
|
369
|
-
const profile = await client.get("/api/profile");
|
|
370
|
-
if (globalOpts.json) {
|
|
371
|
-
json(profile);
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
heading("Profile");
|
|
375
|
-
table([
|
|
376
|
-
["Handle", bold(profile.handle || "(none)")],
|
|
377
|
-
["User ID", profile.user_id],
|
|
378
|
-
["Created", new Date(profile.created_at).toLocaleDateString()]
|
|
379
|
-
]);
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
function requireAuth(client) {
|
|
383
|
-
if (!client.isAuthenticated) {
|
|
384
|
-
error("Not logged in. Run " + bold("hl auth login") + " first.");
|
|
385
|
-
process.exit(1);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// src/commands/assess.ts
|
|
390
|
-
import readline2 from "readline/promises";
|
|
391
|
-
import chalk3 from "chalk";
|
|
392
335
|
|
|
393
336
|
// src/stream.ts
|
|
394
337
|
async function parseStream(body, callbacks = {}) {
|
|
@@ -398,7 +341,7 @@ async function parseStream(body, callbacks = {}) {
|
|
|
398
341
|
let assistantText = "";
|
|
399
342
|
const toolCalls = [];
|
|
400
343
|
const activeToolCalls = /* @__PURE__ */ new Map();
|
|
401
|
-
let
|
|
344
|
+
let marketBrief = null;
|
|
402
345
|
while (true) {
|
|
403
346
|
const { done, value } = await reader.read();
|
|
404
347
|
if (!done) {
|
|
@@ -459,8 +402,8 @@ async function parseStream(body, callbacks = {}) {
|
|
|
459
402
|
const active = activeToolCalls.get(id);
|
|
460
403
|
if (active) {
|
|
461
404
|
callbacks.onToolResult?.(active.name, msg.output);
|
|
462
|
-
if (active.name === "
|
|
463
|
-
|
|
405
|
+
if (active.name === "buildMarketBrief" && isMarketBrief(msg.output)) {
|
|
406
|
+
marketBrief = msg.output;
|
|
464
407
|
}
|
|
465
408
|
activeToolCalls.delete(id);
|
|
466
409
|
}
|
|
@@ -473,23 +416,249 @@ async function parseStream(body, callbacks = {}) {
|
|
|
473
416
|
}
|
|
474
417
|
if (done) break;
|
|
475
418
|
}
|
|
476
|
-
return { assistantText, toolCalls,
|
|
419
|
+
return { assistantText, toolCalls, marketBrief };
|
|
420
|
+
}
|
|
421
|
+
function isMarketBrief(val) {
|
|
422
|
+
return val !== null && typeof val === "object" && "title" in val && "markets" in val;
|
|
423
|
+
}
|
|
424
|
+
async function parseNdjsonStream(body, callbacks = {}) {
|
|
425
|
+
const decoder = new TextDecoder();
|
|
426
|
+
const reader = body.getReader();
|
|
427
|
+
let buffer = "";
|
|
428
|
+
let brief = null;
|
|
429
|
+
let error2 = null;
|
|
430
|
+
while (true) {
|
|
431
|
+
const { done, value } = await reader.read();
|
|
432
|
+
if (!done) {
|
|
433
|
+
buffer += decoder.decode(value, { stream: true });
|
|
434
|
+
}
|
|
435
|
+
const lines = buffer.split("\n");
|
|
436
|
+
buffer = done ? "" : lines.pop() ?? "";
|
|
437
|
+
for (const line of lines) {
|
|
438
|
+
const trimmed = line.trim();
|
|
439
|
+
if (!trimmed) continue;
|
|
440
|
+
let msg;
|
|
441
|
+
try {
|
|
442
|
+
msg = JSON.parse(trimmed);
|
|
443
|
+
} catch {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const type = msg.type;
|
|
447
|
+
switch (type) {
|
|
448
|
+
case "progress": {
|
|
449
|
+
callbacks.onProgress?.(msg.step, msg.message);
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
case "brief": {
|
|
453
|
+
brief = msg.data;
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
case "error": {
|
|
457
|
+
error2 = {
|
|
458
|
+
code: msg.code,
|
|
459
|
+
message: msg.message
|
|
460
|
+
};
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (done) break;
|
|
466
|
+
}
|
|
467
|
+
return { brief, error: error2 };
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/commands/brief.ts
|
|
471
|
+
function registerBriefCommands(program2) {
|
|
472
|
+
program2.command("brief <query>").description("Generate a Market Brief for a topic (non-interactive)").option("-l, --location <location>", "Geographic context (e.g. 'Middle East', 'US')").option("-t, --time-horizon <horizon>", "Time frame (e.g. '3 months', '2026')").option("--tags <tags>", "Comma-separated focus area tags (e.g. 'geopolitics,energy')").option("--min-volume <n>", "Minimum market volume in USD", parseFloat).option("--max-yes-price <n>", "Maximum YES price (0-1)", parseFloat).option("--no-stream", "Disable streaming \u2014 block until complete").action(async (query, cmdOpts) => {
|
|
473
|
+
const globalOpts = program2.opts();
|
|
474
|
+
const client = new ApiClient(globalOpts);
|
|
475
|
+
requireAuth(client);
|
|
476
|
+
const filters = buildFilters(cmdOpts);
|
|
477
|
+
const body = {
|
|
478
|
+
query,
|
|
479
|
+
...cmdOpts.location && { location: cmdOpts.location },
|
|
480
|
+
...cmdOpts.timeHorizon && { timeHorizon: cmdOpts.timeHorizon },
|
|
481
|
+
...filters && { filters },
|
|
482
|
+
stream: cmdOpts.stream !== false
|
|
483
|
+
};
|
|
484
|
+
if (body.stream) {
|
|
485
|
+
await runStreaming(client, body, globalOpts);
|
|
486
|
+
} else {
|
|
487
|
+
await runBlocking(client, body, globalOpts);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
function buildFilters(opts) {
|
|
492
|
+
const tags = opts.tags?.split(",").map((t) => t.trim()).filter(Boolean);
|
|
493
|
+
const hasFilters = opts.minVolume != null || opts.maxYesPrice != null || tags && tags.length > 0;
|
|
494
|
+
if (!hasFilters) return void 0;
|
|
495
|
+
return {
|
|
496
|
+
...opts.minVolume != null && { minVolume: opts.minVolume },
|
|
497
|
+
...opts.maxYesPrice != null && { maxYesPrice: opts.maxYesPrice },
|
|
498
|
+
...tags && tags.length > 0 && { tags }
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
async function runStreaming(client, body, globalOpts) {
|
|
502
|
+
const startTime = Date.now();
|
|
503
|
+
process.stderr.write(chalk2.dim(` Generating brief for "${truncate(body.query, 50)}"...
|
|
504
|
+
`));
|
|
505
|
+
const stream = await client.streamNdjson("/api/brief", body);
|
|
506
|
+
const result = await parseNdjsonStream(stream, {
|
|
507
|
+
onProgress: (step, message) => {
|
|
508
|
+
process.stderr.write(chalk2.dim(` [${step}] `) + message + "\n");
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
512
|
+
if (result.error) {
|
|
513
|
+
error(`Brief failed (${result.error.code}): ${result.error.message}`);
|
|
514
|
+
process.exit(1);
|
|
515
|
+
}
|
|
516
|
+
if (!result.brief) {
|
|
517
|
+
error("No Market Brief was produced.");
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
process.stderr.write(chalk2.dim(` Done (${elapsed}s)
|
|
521
|
+
|
|
522
|
+
`));
|
|
523
|
+
displayBrief(result.brief, globalOpts);
|
|
524
|
+
}
|
|
525
|
+
async function runBlocking(client, body, globalOpts) {
|
|
526
|
+
const startTime = Date.now();
|
|
527
|
+
process.stderr.write(chalk2.dim(` Generating brief for "${truncate(body.query, 50)}"...
|
|
528
|
+
`));
|
|
529
|
+
const brief = await client.post("/api/brief", body);
|
|
530
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
531
|
+
process.stderr.write(chalk2.dim(` Done (${elapsed}s)
|
|
532
|
+
|
|
533
|
+
`));
|
|
534
|
+
displayBrief(brief, globalOpts);
|
|
535
|
+
}
|
|
536
|
+
function displayBrief(brief, globalOpts) {
|
|
537
|
+
if (globalOpts.json) {
|
|
538
|
+
json(brief);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
heading("Market Brief");
|
|
542
|
+
process.stdout.write(" " + chalk2.bold(brief.title) + "\n\n");
|
|
543
|
+
process.stdout.write(" " + chalk2.italic(brief.thesis) + "\n");
|
|
544
|
+
if (brief.markets.length > 0) {
|
|
545
|
+
process.stdout.write("\n" + chalk2.bold(" Markets") + "\n\n");
|
|
546
|
+
const rows = brief.markets.map((m) => {
|
|
547
|
+
const prob = percent(m.yesPrice);
|
|
548
|
+
const signals = m.signals.length > 0 ? m.signals.join(", ") : "\u2014";
|
|
549
|
+
const liq = m.liquidity ? currency(m.liquidity) : "\u2014";
|
|
550
|
+
return [truncate(m.question, 40), prob, signals, liq];
|
|
551
|
+
});
|
|
552
|
+
table(rows, ["Market", "Prob", "Signals", "Liq"]);
|
|
553
|
+
process.stdout.write("\n");
|
|
554
|
+
for (const m of brief.markets) {
|
|
555
|
+
process.stdout.write(" " + chalk2.dim("\u25B8 ") + truncate(m.question, 50) + "\n");
|
|
556
|
+
process.stdout.write(" " + chalk2.dim("Causal link: ") + m.causalLink + "\n");
|
|
557
|
+
process.stdout.write(" " + chalk2.dim("Polymarket: ") + m.polymarketUrl + "\n");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (brief.gaps.length > 0) {
|
|
561
|
+
process.stdout.write("\n" + chalk2.bold(" Coverage Gaps") + "\n\n");
|
|
562
|
+
for (const gap of brief.gaps) {
|
|
563
|
+
process.stdout.write(" " + chalk2.yellow("\u25B8") + " " + gap + "\n");
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
const marketCount = brief.marketCount ?? brief.markets.length;
|
|
567
|
+
process.stdout.write("\n " + chalk2.dim(`${marketCount} markets \xB7 ${brief.gaps.length} coverage gaps`) + "\n");
|
|
477
568
|
}
|
|
478
|
-
function
|
|
479
|
-
|
|
569
|
+
function requireAuth(client) {
|
|
570
|
+
if (!client.isAuthenticated) {
|
|
571
|
+
error("Not logged in. Run " + bold("hl auth login") + " first.");
|
|
572
|
+
process.exit(1);
|
|
573
|
+
}
|
|
480
574
|
}
|
|
481
575
|
|
|
482
|
-
// src/commands/
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
576
|
+
// src/commands/markets.ts
|
|
577
|
+
import chalk3 from "chalk";
|
|
578
|
+
function registerMarketCommands(program2) {
|
|
579
|
+
const markets = program2.command("markets").description("Polymarket orderbook tools");
|
|
580
|
+
markets.command("orderbook <tokenId>").description("Show orderbook spread and depth for a CLOB token").option("-s, --size <n>", "Size for slippage calculation").action(async (tokenId, cmdOpts) => {
|
|
581
|
+
const globalOpts = program2.opts();
|
|
582
|
+
const client = new ApiClient(globalOpts);
|
|
583
|
+
const params = { tokenId };
|
|
584
|
+
if (cmdOpts.size) params.size = cmdOpts.size;
|
|
585
|
+
const data = await client.get("/api/orderbook", params);
|
|
586
|
+
if (globalOpts.json) {
|
|
587
|
+
json(data);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
heading("Orderbook");
|
|
591
|
+
if (data.spread) {
|
|
592
|
+
table([
|
|
593
|
+
["Best Bid", data.spread.bid.toFixed(4)],
|
|
594
|
+
["Best Ask", data.spread.ask.toFixed(4)],
|
|
595
|
+
["Spread", percent(data.spread.spread)],
|
|
596
|
+
["Ask Depth", currency(data.askDepth)]
|
|
597
|
+
]);
|
|
598
|
+
} else {
|
|
599
|
+
warn("No spread data available (empty orderbook)");
|
|
600
|
+
}
|
|
601
|
+
if (data.slippage) {
|
|
602
|
+
process.stdout.write("\n");
|
|
603
|
+
table([
|
|
604
|
+
["Avg Fill Price", data.slippage.avgPrice.toFixed(4)],
|
|
605
|
+
["Worst Price", data.slippage.worstPrice.toFixed(4)],
|
|
606
|
+
["Slippage", percent(data.slippage.slippage)],
|
|
607
|
+
["Fillable Size", currency(data.slippage.fillableSize)]
|
|
608
|
+
]);
|
|
609
|
+
}
|
|
610
|
+
if (data.book.asks.length > 0) {
|
|
611
|
+
process.stdout.write("\n" + chalk3.dim(" Top 5 asks:") + "\n");
|
|
612
|
+
const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);
|
|
613
|
+
table(askRows, ["Price", "Size"]);
|
|
614
|
+
}
|
|
615
|
+
if (data.book.bids.length > 0) {
|
|
616
|
+
process.stdout.write("\n" + chalk3.dim(" Top 5 bids:") + "\n");
|
|
617
|
+
const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);
|
|
618
|
+
table(bidRows, ["Price", "Size"]);
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// src/commands/profile.ts
|
|
624
|
+
function registerProfileCommand(program2) {
|
|
625
|
+
program2.command("profile").description("Show your user profile").action(async () => {
|
|
486
626
|
const globalOpts = program2.opts();
|
|
487
627
|
const client = new ApiClient(globalOpts);
|
|
488
628
|
requireAuth2(client);
|
|
629
|
+
const profile = await client.get("/api/profile");
|
|
630
|
+
if (globalOpts.json) {
|
|
631
|
+
json(profile);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
heading("Profile");
|
|
635
|
+
table([
|
|
636
|
+
["Handle", bold(profile.handle || "(none)")],
|
|
637
|
+
["User ID", profile.user_id],
|
|
638
|
+
["Created", new Date(profile.created_at).toLocaleDateString()]
|
|
639
|
+
]);
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
function requireAuth2(client) {
|
|
643
|
+
if (!client.isAuthenticated) {
|
|
644
|
+
error("Not logged in. Run " + bold("hl auth login") + " first.");
|
|
645
|
+
process.exit(1);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// src/commands/research.ts
|
|
650
|
+
import readline2 from "readline/promises";
|
|
651
|
+
import chalk4 from "chalk";
|
|
652
|
+
function registerResearchCommands(program2) {
|
|
653
|
+
const research = program2.command("research").description("AI-powered market research");
|
|
654
|
+
research.command("start", { isDefault: true }).description("Start an interactive market research session").action(async () => {
|
|
655
|
+
const globalOpts = program2.opts();
|
|
656
|
+
const client = new ApiClient(globalOpts);
|
|
657
|
+
requireAuth3(client);
|
|
489
658
|
const { id } = await client.post("/api/assessments");
|
|
490
|
-
heading("
|
|
659
|
+
heading("Market Research");
|
|
491
660
|
process.stderr.write(
|
|
492
|
-
|
|
661
|
+
chalk4.dim(" Describe a topic or thesis to explore. Type /quit to exit.\n\n")
|
|
493
662
|
);
|
|
494
663
|
let msgCounter = 0;
|
|
495
664
|
const uiMsg = (role, content) => ({
|
|
@@ -502,11 +671,11 @@ function registerAssessCommands(program2) {
|
|
|
502
671
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
503
672
|
try {
|
|
504
673
|
while (true) {
|
|
505
|
-
const userInput = await rl.question(
|
|
674
|
+
const userInput = await rl.question(chalk4.cyan("You: "));
|
|
506
675
|
if (!userInput.trim()) continue;
|
|
507
676
|
if (userInput.trim() === "/quit") break;
|
|
508
677
|
messages.push(uiMsg("user", userInput));
|
|
509
|
-
process.stderr.write(
|
|
678
|
+
process.stderr.write(chalk4.dim("\nAssistant: "));
|
|
510
679
|
try {
|
|
511
680
|
const body = await client.stream("/api/chat", {
|
|
512
681
|
messages,
|
|
@@ -514,18 +683,14 @@ function registerAssessCommands(program2) {
|
|
|
514
683
|
});
|
|
515
684
|
const result = await parseStream(body, {
|
|
516
685
|
onText: (text) => process.stderr.write(text),
|
|
517
|
-
onToolCall: (name
|
|
518
|
-
process.stderr.write(
|
|
686
|
+
onToolCall: (name) => {
|
|
687
|
+
process.stderr.write(chalk4.dim(`
|
|
519
688
|
[tool: ${name}]
|
|
520
689
|
`));
|
|
521
|
-
if (globalOpts.verbose) {
|
|
522
|
-
process.stderr.write(chalk3.dim(` ${JSON.stringify(args)}
|
|
523
|
-
`));
|
|
524
|
-
}
|
|
525
690
|
},
|
|
526
|
-
onToolResult: (name,
|
|
691
|
+
onToolResult: (name, toolResult) => {
|
|
527
692
|
if (globalOpts.verbose) {
|
|
528
|
-
process.stderr.write(
|
|
693
|
+
process.stderr.write(chalk4.dim(` [result: ${name}] ${JSON.stringify(toolResult).slice(0, 200)}
|
|
529
694
|
`));
|
|
530
695
|
}
|
|
531
696
|
}
|
|
@@ -534,8 +699,8 @@ function registerAssessCommands(program2) {
|
|
|
534
699
|
if (result.assistantText) {
|
|
535
700
|
messages.push(uiMsg("assistant", result.assistantText));
|
|
536
701
|
}
|
|
537
|
-
if (result.
|
|
538
|
-
|
|
702
|
+
if (result.marketBrief) {
|
|
703
|
+
displayMarketBrief(result.marketBrief, globalOpts);
|
|
539
704
|
break;
|
|
540
705
|
}
|
|
541
706
|
} catch (e) {
|
|
@@ -547,10 +712,29 @@ function registerAssessCommands(program2) {
|
|
|
547
712
|
rl.close();
|
|
548
713
|
}
|
|
549
714
|
});
|
|
550
|
-
|
|
715
|
+
research.command("run <query>").description("Run research on a topic and return the final brief as JSON").action(async (query) => {
|
|
551
716
|
const globalOpts = program2.opts();
|
|
552
717
|
const client = new ApiClient(globalOpts);
|
|
553
|
-
|
|
718
|
+
requireAuth3(client);
|
|
719
|
+
process.stderr.write(chalk4.dim(` Researching "${truncate(query, 60)}"...
|
|
720
|
+
`));
|
|
721
|
+
const startTime = Date.now();
|
|
722
|
+
const result = await client.post("/api/research", { query });
|
|
723
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
724
|
+
process.stderr.write(chalk4.dim(` Done (${elapsed}s)
|
|
725
|
+
|
|
726
|
+
`));
|
|
727
|
+
if (result.brief) {
|
|
728
|
+
json(result.brief);
|
|
729
|
+
} else {
|
|
730
|
+
process.stderr.write(chalk4.yellow("No market brief was produced.\n"));
|
|
731
|
+
json(result);
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
research.command("list").description("List past research sessions").option("-s, --status <status>", "Filter by status").action(async (cmdOpts) => {
|
|
735
|
+
const globalOpts = program2.opts();
|
|
736
|
+
const client = new ApiClient(globalOpts);
|
|
737
|
+
requireAuth3(client);
|
|
554
738
|
const params = { list: "true" };
|
|
555
739
|
if (cmdOpts.status) params.status = cmdOpts.status;
|
|
556
740
|
const data = await client.get("/api/assessments", params);
|
|
@@ -559,56 +743,46 @@ function registerAssessCommands(program2) {
|
|
|
559
743
|
return;
|
|
560
744
|
}
|
|
561
745
|
if (data.assessments.length === 0) {
|
|
562
|
-
warn("No
|
|
746
|
+
warn("No research sessions found.");
|
|
563
747
|
return;
|
|
564
748
|
}
|
|
565
|
-
heading(`
|
|
749
|
+
heading(`Research Sessions (${data.assessments.length})`);
|
|
566
750
|
const rows = data.assessments.map((a) => {
|
|
567
751
|
const status = formatStatus(a.status);
|
|
568
|
-
const
|
|
569
|
-
const
|
|
570
|
-
return [a.id.slice(0, 8), status,
|
|
752
|
+
const brief = a.market_brief?.title ?? "\u2014";
|
|
753
|
+
const markets = a.market_brief ? String(a.market_brief.marketCount) : "\u2014";
|
|
754
|
+
return [a.id.slice(0, 8), status, truncate(brief, 30), markets, relativeTime(a.created_at)];
|
|
571
755
|
});
|
|
572
|
-
table(rows, ["ID", "Status", "
|
|
756
|
+
table(rows, ["ID", "Status", "Brief", "Markets", "Created"]);
|
|
573
757
|
});
|
|
574
|
-
|
|
758
|
+
research.command("show <id>").description("Show research session details").action(async (id) => {
|
|
575
759
|
const globalOpts = program2.opts();
|
|
576
760
|
const client = new ApiClient(globalOpts);
|
|
577
|
-
|
|
761
|
+
requireAuth3(client);
|
|
578
762
|
const assessment = await client.get(`/api/assessments/${id}`);
|
|
579
763
|
if (globalOpts.json) {
|
|
580
764
|
json(assessment);
|
|
581
765
|
return;
|
|
582
766
|
}
|
|
583
|
-
heading("
|
|
767
|
+
heading("Research Session " + dim(assessment.id.slice(0, 8)));
|
|
584
768
|
table([
|
|
585
769
|
["Status", formatStatus(assessment.status)],
|
|
586
770
|
["Created", new Date(assessment.created_at).toLocaleString()],
|
|
587
771
|
["Updated", new Date(assessment.updated_at).toLocaleString()]
|
|
588
772
|
]);
|
|
589
|
-
if (assessment.
|
|
590
|
-
|
|
591
|
-
process.stdout.write("\n");
|
|
592
|
-
table([
|
|
593
|
-
["Location", rp.location],
|
|
594
|
-
["Asset Type", rp.assetType],
|
|
595
|
-
["Asset Value", currency(rp.assetValue)],
|
|
596
|
-
["Risk Types", rp.riskTypes.join(", ")]
|
|
597
|
-
]);
|
|
598
|
-
}
|
|
599
|
-
if (assessment.hedge_bundle) {
|
|
600
|
-
displayHedgeBundle(assessment.hedge_bundle, globalOpts);
|
|
773
|
+
if (assessment.market_brief) {
|
|
774
|
+
displayMarketBrief(assessment.market_brief, globalOpts);
|
|
601
775
|
}
|
|
602
776
|
});
|
|
603
|
-
|
|
777
|
+
research.command("delete <id>").description("Delete a research session").action(async (id) => {
|
|
604
778
|
const globalOpts = program2.opts();
|
|
605
779
|
const client = new ApiClient(globalOpts);
|
|
606
|
-
|
|
780
|
+
requireAuth3(client);
|
|
607
781
|
await client.delete(`/api/assessments/${id}`);
|
|
608
|
-
success("
|
|
782
|
+
success("Research session deleted.");
|
|
609
783
|
});
|
|
610
784
|
}
|
|
611
|
-
function
|
|
785
|
+
function requireAuth3(client) {
|
|
612
786
|
if (!client.isAuthenticated) {
|
|
613
787
|
error("Not logged in. Run " + bold("hl auth login") + " first.");
|
|
614
788
|
process.exit(1);
|
|
@@ -617,166 +791,56 @@ function requireAuth2(client) {
|
|
|
617
791
|
function formatStatus(status) {
|
|
618
792
|
switch (status) {
|
|
619
793
|
case "completed":
|
|
620
|
-
return
|
|
794
|
+
return chalk4.green(status);
|
|
621
795
|
case "in_progress":
|
|
622
|
-
return
|
|
796
|
+
return chalk4.yellow(status);
|
|
623
797
|
case "abandoned":
|
|
624
|
-
return
|
|
798
|
+
return chalk4.red(status);
|
|
625
799
|
default:
|
|
626
800
|
return status;
|
|
627
801
|
}
|
|
628
802
|
}
|
|
629
|
-
function
|
|
803
|
+
function displayMarketBrief(brief, globalOpts) {
|
|
630
804
|
if (globalOpts.json) {
|
|
631
|
-
json(
|
|
805
|
+
json(brief);
|
|
632
806
|
return;
|
|
633
807
|
}
|
|
634
|
-
heading("
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
const market = p.market?.question ?? "Unknown";
|
|
645
|
-
const cost = currency(Number(p.estimatedCost ?? 0));
|
|
646
|
-
const payout = currency(Number(p.potentialPayout ?? 0));
|
|
647
|
-
const price = Number(p.yesPrice ?? 0).toFixed(2);
|
|
648
|
-
const capped = p.wasCapped ? chalk3.yellow(" (capped)") : "";
|
|
649
|
-
return [truncate(market, 40), price, cost, payout + capped];
|
|
808
|
+
heading("Market Brief");
|
|
809
|
+
process.stdout.write(" " + chalk4.bold(brief.title) + "\n\n");
|
|
810
|
+
process.stdout.write(" " + chalk4.italic(brief.thesis) + "\n");
|
|
811
|
+
if (brief.markets.length > 0) {
|
|
812
|
+
process.stdout.write("\n" + chalk4.bold(" Markets") + "\n\n");
|
|
813
|
+
const rows = brief.markets.map((m) => {
|
|
814
|
+
const prob = percent(m.yesPrice);
|
|
815
|
+
const signals = m.signals.length > 0 ? m.signals.join(", ") : "\u2014";
|
|
816
|
+
const liq = m.liquidity ? currency(m.liquidity) : "\u2014";
|
|
817
|
+
return [truncate(m.question, 40), prob, signals, liq];
|
|
650
818
|
});
|
|
651
|
-
table(rows, ["Market", "
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
import chalk4 from "chalk";
|
|
658
|
-
function registerHedgeCommand(program2) {
|
|
659
|
-
program2.command("hedge [file]").description("Calculate hedge positions from a risk profile JSON").addHelpText(
|
|
660
|
-
"after",
|
|
661
|
-
`
|
|
662
|
-
Example risk profile JSON:
|
|
663
|
-
{
|
|
664
|
-
"location": "33109",
|
|
665
|
-
"assetType": "residential",
|
|
666
|
-
"riskTypes": ["hurricane", "flood"],
|
|
667
|
-
"assetValue": 500000
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
Usage:
|
|
671
|
-
hl hedge profile.json Read from file
|
|
672
|
-
echo '{"location":...}' | hl hedge - Read from stdin`
|
|
673
|
-
).action(async (file) => {
|
|
674
|
-
const globalOpts = program2.opts();
|
|
675
|
-
const client = new ApiClient(globalOpts);
|
|
676
|
-
let raw;
|
|
677
|
-
if (!file || file === "-") {
|
|
678
|
-
raw = await readStdin();
|
|
679
|
-
} else {
|
|
680
|
-
try {
|
|
681
|
-
raw = readFileSync2(file, "utf-8");
|
|
682
|
-
} catch (e) {
|
|
683
|
-
error(`Cannot read file: ${file} \u2014 ${e instanceof Error ? e.message : e}`);
|
|
684
|
-
process.exit(1);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
let profile;
|
|
688
|
-
try {
|
|
689
|
-
profile = JSON.parse(raw);
|
|
690
|
-
} catch {
|
|
691
|
-
error("Invalid JSON input. Expected a RiskProfile object.");
|
|
692
|
-
process.exit(1);
|
|
819
|
+
table(rows, ["Market", "Prob", "Signals", "Liq"]);
|
|
820
|
+
process.stdout.write("\n");
|
|
821
|
+
for (const m of brief.markets) {
|
|
822
|
+
process.stdout.write(" " + chalk4.dim("\u25B8 ") + truncate(m.question, 50) + "\n");
|
|
823
|
+
process.stdout.write(" " + chalk4.dim("Causal link: ") + m.causalLink + "\n");
|
|
824
|
+
process.stdout.write(" " + chalk4.dim("Polymarket: ") + m.polymarketUrl + "\n");
|
|
693
825
|
}
|
|
694
|
-
if (!profile.location || !profile.assetValue || !profile.riskTypes?.length) {
|
|
695
|
-
error("Risk profile must include location, assetValue, and at least one riskType.");
|
|
696
|
-
process.exit(1);
|
|
697
|
-
}
|
|
698
|
-
process.stderr.write(chalk4.dim("Searching markets and calculating hedge...\n"));
|
|
699
|
-
const messages = [
|
|
700
|
-
{
|
|
701
|
-
role: "user",
|
|
702
|
-
content: `I need to hedge a ${profile.assetType ?? "residential"} property worth $${profile.assetValue.toLocaleString()} in ${profile.location} against ${profile.riskTypes.join(", ")} risks. Please search for relevant markets and build a hedge bundle.`
|
|
703
|
-
}
|
|
704
|
-
];
|
|
705
|
-
try {
|
|
706
|
-
const stream = await client.stream("/api/chat", { messages });
|
|
707
|
-
let bundleJson = null;
|
|
708
|
-
const decoder = new TextDecoder();
|
|
709
|
-
const reader = stream.getReader();
|
|
710
|
-
let buffer = "";
|
|
711
|
-
while (true) {
|
|
712
|
-
const { done, value } = await reader.read();
|
|
713
|
-
if (done) break;
|
|
714
|
-
buffer += decoder.decode(value, { stream: true });
|
|
715
|
-
const lines = buffer.split("\n");
|
|
716
|
-
buffer = lines.pop() ?? "";
|
|
717
|
-
for (const line of lines) {
|
|
718
|
-
if (!line.startsWith("d:")) continue;
|
|
719
|
-
try {
|
|
720
|
-
const parsed = JSON.parse(line.slice(2));
|
|
721
|
-
if (parsed && typeof parsed === "object" && "positions" in parsed) {
|
|
722
|
-
bundleJson = parsed;
|
|
723
|
-
}
|
|
724
|
-
} catch {
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
if (bundleJson) {
|
|
729
|
-
displayBundle(bundleJson, globalOpts);
|
|
730
|
-
} else {
|
|
731
|
-
warn("No hedge bundle was produced. Try the interactive assessment: hl assess");
|
|
732
|
-
}
|
|
733
|
-
} catch (e) {
|
|
734
|
-
error(`Hedge calculation failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
735
|
-
process.exit(1);
|
|
736
|
-
}
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
|
-
function displayBundle(bundle, globalOpts) {
|
|
740
|
-
if (globalOpts.json) {
|
|
741
|
-
json(bundle);
|
|
742
|
-
return;
|
|
743
826
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
["Efficiency", percent(bundle.hedgeEfficiency)]
|
|
750
|
-
]);
|
|
751
|
-
if (bundle.positions?.length > 0) {
|
|
752
|
-
process.stdout.write("\n" + chalk4.bold(" Positions") + "\n\n");
|
|
753
|
-
const rows = bundle.positions.map((p) => {
|
|
754
|
-
const market = p.market?.question ?? "Unknown";
|
|
755
|
-
const cost = currency(p.estimatedCost);
|
|
756
|
-
const payout = currency(p.potentialPayout);
|
|
757
|
-
const price = p.yesPrice.toFixed(2);
|
|
758
|
-
const capped = p.wasCapped ? chalk4.yellow(" (capped)") : "";
|
|
759
|
-
return [truncate(market, 40), price, cost, payout + capped];
|
|
760
|
-
});
|
|
761
|
-
table(rows, ["Market", "YES", "Cost", "Payout"]);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
async function readStdin() {
|
|
765
|
-
const chunks = [];
|
|
766
|
-
for await (const chunk of process.stdin) {
|
|
767
|
-
chunks.push(chunk);
|
|
827
|
+
if (brief.gaps.length > 0) {
|
|
828
|
+
process.stdout.write("\n" + chalk4.bold(" Coverage Gaps") + "\n\n");
|
|
829
|
+
for (const gap of brief.gaps) {
|
|
830
|
+
process.stdout.write(" " + chalk4.yellow("\u25B8") + " " + gap + "\n");
|
|
831
|
+
}
|
|
768
832
|
}
|
|
769
|
-
|
|
833
|
+
process.stdout.write("\n " + chalk4.dim(`${brief.marketCount} markets \xB7 ${brief.gaps.length} coverage gaps`) + "\n");
|
|
770
834
|
}
|
|
771
835
|
|
|
772
836
|
// src/index.ts
|
|
773
837
|
var program = new Command();
|
|
774
|
-
program.name("hl").description("Hedge Layer CLI \u2014
|
|
838
|
+
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.1.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");
|
|
775
839
|
registerAuthCommands(program);
|
|
840
|
+
registerBriefCommands(program);
|
|
776
841
|
registerMarketCommands(program);
|
|
777
842
|
registerProfileCommand(program);
|
|
778
|
-
|
|
779
|
-
registerHedgeCommand(program);
|
|
843
|
+
registerResearchCommands(program);
|
|
780
844
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
781
845
|
const opts = program.opts();
|
|
782
846
|
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/markets.ts","../src/commands/profile.ts","../src/commands/assess.ts","../src/stream.ts","../src/commands/hedge.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerMarketCommands } from \"./commands/markets.js\";\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerAssessCommands } from \"./commands/assess.js\";\nimport { registerHedgeCommand } from \"./commands/hedge.js\";\nimport * as out from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"hl\")\n .description(\"Hedge Layer CLI — hedge real-world risks on Polymarket\")\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);\nregisterMarketCommands(program);\nregisterProfileCommand(program);\nregisterAssessCommands(program);\nregisterHedgeCommand(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 // Pass verbose state down for debugging\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 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\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 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 type { Orderbook, SlippageResult, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerMarketCommands(program: Command): void {\n const markets = program.command(\"markets\").description(\"Polymarket orderbook tools\");\n\n markets\n .command(\"orderbook <tokenId>\")\n .description(\"Show orderbook spread and depth for a CLOB token\")\n .option(\"-s, --size <n>\", \"Size for slippage calculation\")\n .action(async (tokenId: string, cmdOpts: { size?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n const params: Record<string, string> = { tokenId };\n if (cmdOpts.size) params.size = cmdOpts.size;\n\n const data = await client.get<{\n book: Orderbook;\n spread: { bid: number; ask: number; spread: number } | null;\n askDepth: number;\n slippage: SlippageResult | null;\n }>(\"/api/orderbook\", params);\n\n if (globalOpts.json) {\n out.json(data);\n return;\n }\n\n out.heading(\"Orderbook\");\n\n if (data.spread) {\n out.table([\n [\"Best Bid\", data.spread.bid.toFixed(4)],\n [\"Best Ask\", data.spread.ask.toFixed(4)],\n [\"Spread\", out.percent(data.spread.spread)],\n [\"Ask Depth\", out.currency(data.askDepth)],\n ]);\n } else {\n out.warn(\"No spread data available (empty orderbook)\");\n }\n\n if (data.slippage) {\n process.stdout.write(\"\\n\");\n out.table([\n [\"Avg Fill Price\", data.slippage.avgPrice.toFixed(4)],\n [\"Worst Price\", data.slippage.worstPrice.toFixed(4)],\n [\"Slippage\", out.percent(data.slippage.slippage)],\n [\"Fillable Size\", out.currency(data.slippage.fillableSize)],\n ]);\n }\n\n if (data.book.asks.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 asks:\") + \"\\n\");\n const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(askRows, [\"Price\", \"Size\"]);\n }\n\n if (data.book.bids.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 bids:\") + \"\\n\");\n const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(bidRows, [\"Price\", \"Size\"]);\n }\n });\n}\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, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerAssessCommands(program: Command): void {\n const assess = program.command(\"assess\").description(\"AI-powered risk assessment\");\n\n assess\n .command(\"start\", { isDefault: true })\n .description(\"Start an interactive risk assessment chat\")\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(\"Risk Assessment\");\n process.stderr.write(\n chalk.dim(\" Describe the risks you want to hedge. 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 const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n\n try {\n // eslint-disable-next-line no-constant-condition\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 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, args) => {\n process.stderr.write(chalk.dim(`\\n [tool: ${name}]\\n`));\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` ${JSON.stringify(args)}\\n`));\n }\n },\n onToolResult: (name, result) => {\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` [result: ${name}] ${JSON.stringify(result).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 if (result.hedgeBundle) {\n displayHedgeBundle(result.hedgeBundle, 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 assess\n .command(\"list\")\n .description(\"List past assessments\")\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 assessments found.\");\n return;\n }\n\n out.heading(`Assessments (${data.assessments.length})`);\n\n const rows = data.assessments.map((a) => {\n const status = formatStatus(a.status);\n const location = a.risk_profile?.location ?? \"—\";\n const cost = a.hedge_bundle ? out.currency(a.hedge_bundle.totalCost) : \"—\";\n return [a.id.slice(0, 8), status, location, cost, out.relativeTime(a.created_at)];\n });\n\n out.table(rows, [\"ID\", \"Status\", \"Location\", \"Cost\", \"Created\"]);\n });\n\n assess\n .command(\"show <id>\")\n .description(\"Show assessment 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(\"Assessment \" + 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.risk_profile) {\n const rp = assessment.risk_profile;\n process.stdout.write(\"\\n\");\n out.table([\n [\"Location\", rp.location],\n [\"Asset Type\", rp.assetType],\n [\"Asset Value\", out.currency(rp.assetValue)],\n [\"Risk Types\", rp.riskTypes.join(\", \")],\n ]);\n }\n\n if (assessment.hedge_bundle) {\n displayHedgeBundle(assessment.hedge_bundle, globalOpts);\n }\n });\n\n assess\n .command(\"delete <id>\")\n .description(\"Delete an assessment\")\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(\"Assessment 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\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 displayHedgeBundle(\n bundle: { positions: Array<Record<string, unknown>>; totalCost: number; totalCoverage: number; hedgeEfficiency: number; assetValue: number },\n globalOpts: GlobalOptions,\n): void {\n if (globalOpts.json) {\n out.json(bundle);\n return;\n }\n\n out.heading(\"Hedge Bundle\");\n\n out.table([\n [\"Asset Value\", out.currency(bundle.assetValue)],\n [\"Total Cost\", out.currency(bundle.totalCost)],\n [\"Total Coverage\", out.currency(bundle.totalCoverage)],\n [\"Efficiency\", out.percent(bundle.hedgeEfficiency)],\n ]);\n\n if (bundle.positions.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Positions\") + \"\\n\\n\");\n const rows = bundle.positions.map((p) => {\n const market = (p.market as Record<string, string>)?.question ?? \"Unknown\";\n const cost = out.currency(Number(p.estimatedCost ?? 0));\n const payout = out.currency(Number(p.potentialPayout ?? 0));\n const price = Number(p.yesPrice ?? 0).toFixed(2);\n const capped = p.wasCapped ? chalk.yellow(\" (capped)\") : \"\";\n return [out.truncate(market, 40), price, cost, payout + capped];\n });\n out.table(rows, [\"Market\", \"YES\", \"Cost\", \"Payout\"]);\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 hedgeBundle: 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 hedgeBundle: 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 === \"buildHedgeBundle\" && isHedgeBundle(msg.output)) {\n hedgeBundle = 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, hedgeBundle };\n}\n\nfunction isHedgeBundle(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"positions\" in (val as Record<string, unknown>) &&\n \"totalCost\" in (val as Record<string, unknown>)\n );\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport type { HedgeBundle, RiskProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerHedgeCommand(program: Command): void {\n program\n .command(\"hedge [file]\")\n .description(\"Calculate hedge positions from a risk profile JSON\")\n .addHelpText(\n \"after\",\n `\nExample risk profile JSON:\n {\n \"location\": \"33109\",\n \"assetType\": \"residential\",\n \"riskTypes\": [\"hurricane\", \"flood\"],\n \"assetValue\": 500000\n }\n\nUsage:\n hl hedge profile.json Read from file\n echo '{\"location\":...}' | hl hedge - Read from stdin`,\n )\n .action(async (file: string | undefined) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n let raw: string;\n if (!file || file === \"-\") {\n raw = await readStdin();\n } else {\n try {\n raw = readFileSync(file, \"utf-8\");\n } catch (e) {\n out.error(`Cannot read file: ${file} — ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n }\n }\n\n let profile: RiskProfile;\n try {\n profile = JSON.parse(raw);\n } catch {\n out.error(\"Invalid JSON input. Expected a RiskProfile object.\");\n process.exit(1);\n }\n\n if (!profile.location || !profile.assetValue || !profile.riskTypes?.length) {\n out.error(\"Risk profile must include location, assetValue, and at least one riskType.\");\n process.exit(1);\n }\n\n process.stderr.write(chalk.dim(\"Searching markets and calculating hedge...\\n\"));\n\n const messages = [\n {\n role: \"user\",\n content: `I need to hedge a ${profile.assetType ?? \"residential\"} property worth $${profile.assetValue.toLocaleString()} in ${profile.location} against ${profile.riskTypes.join(\", \")} risks. Please search for relevant markets and build a hedge bundle.`,\n },\n ];\n\n try {\n const stream = await client.stream(\"/api/chat\", { messages });\n let bundleJson: Record<string, unknown> | null = null;\n\n const decoder = new TextDecoder();\n const reader = stream.getReader();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"d:\")) continue;\n try {\n const parsed = JSON.parse(line.slice(2));\n if (parsed && typeof parsed === \"object\" && \"positions\" in parsed) {\n bundleJson = parsed as Record<string, unknown>;\n }\n } catch {\n // not JSON, skip\n }\n }\n }\n\n if (bundleJson) {\n displayBundle(bundleJson as unknown as HedgeBundle, globalOpts);\n } else {\n out.warn(\"No hedge bundle was produced. Try the interactive assessment: hl assess\");\n }\n } catch (e) {\n out.error(`Hedge calculation failed: ${e instanceof Error ? e.message : String(e)}`);\n process.exit(1);\n }\n });\n}\n\nfunction displayBundle(bundle: HedgeBundle, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(bundle);\n return;\n }\n\n out.heading(\"Hedge Bundle\");\n\n out.table([\n [\"Asset Value\", out.currency(bundle.assetValue)],\n [\"Total Cost\", out.currency(bundle.totalCost)],\n [\"Total Coverage\", out.currency(bundle.totalCoverage)],\n [\"Efficiency\", out.percent(bundle.hedgeEfficiency)],\n ]);\n\n if (bundle.positions?.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Positions\") + \"\\n\\n\");\n const rows = bundle.positions.map((p) => {\n const market = p.market?.question ?? \"Unknown\";\n const cost = out.currency(p.estimatedCost);\n const payout = out.currency(p.potentialPayout);\n const price = p.yesPrice.toFixed(2);\n const capped = p.wasCapped ? chalk.yellow(\" (capped)\") : \"\";\n return [out.truncate(market, 40), price, cost, payout + capped];\n });\n out.table(rows, [\"Market\", \"YES\", \"Cost\", \"Payout\"]);\n }\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;;;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,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;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;;;AC5IA,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,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;;;AH3EO,SAAS,qBAAqBA,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,gCAAgC,CAAC;AAAA;AAAA;AAAA,MACtE;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;AAKX,SAAS,uBAAuBC,UAAwB;AAC7D,QAAM,UAAUA,SAAQ,QAAQ,SAAS,EAAE,YAAY,4BAA4B;AAEnF,UACG,QAAQ,qBAAqB,EAC7B,YAAY,kDAAkD,EAC9D,OAAO,kBAAkB,+BAA+B,EACxD,OAAO,OAAO,SAAiB,YAA+B;AAC7D,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AAEvC,UAAM,SAAiC,EAAE,QAAQ;AACjD,QAAI,QAAQ,KAAM,QAAO,OAAO,QAAQ;AAExC,UAAM,OAAO,MAAM,OAAO,IAKvB,kBAAkB,MAAM;AAE3B,QAAI,WAAW,MAAM;AACnB,MAAI,KAAK,IAAI;AACb;AAAA,IACF;AAEA,IAAI,QAAQ,WAAW;AAEvB,QAAI,KAAK,QAAQ;AACf,MAAI,MAAM;AAAA,QACR,CAAC,YAAY,KAAK,OAAO,IAAI,QAAQ,CAAC,CAAC;AAAA,QACvC,CAAC,YAAY,KAAK,OAAO,IAAI,QAAQ,CAAC,CAAC;AAAA,QACvC,CAAC,UAAc,QAAQ,KAAK,OAAO,MAAM,CAAC;AAAA,QAC1C,CAAC,aAAiB,SAAS,KAAK,QAAQ,CAAC;AAAA,MAC3C,CAAC;AAAA,IACH,OAAO;AACL,MAAI,KAAK,4CAA4C;AAAA,IACvD;AAEA,QAAI,KAAK,UAAU;AACjB,cAAQ,OAAO,MAAM,IAAI;AACzB,MAAI,MAAM;AAAA,QACR,CAAC,kBAAkB,KAAK,SAAS,SAAS,QAAQ,CAAC,CAAC;AAAA,QACpD,CAAC,eAAe,KAAK,SAAS,WAAW,QAAQ,CAAC,CAAC;AAAA,QACnD,CAAC,YAAgB,QAAQ,KAAK,SAAS,QAAQ,CAAC;AAAA,QAChD,CAAC,iBAAqB,SAAS,KAAK,SAAS,YAAY,CAAC;AAAA,MAC5D,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,KAAK,KAAK,SAAS,GAAG;AAC7B,cAAQ,OAAO,MAAM,OAAOC,OAAM,IAAI,eAAe,IAAI,IAAI;AAC7D,YAAM,UAAU,KAAK,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC;AACvE,MAAI,MAAM,SAAS,CAAC,SAAS,MAAM,CAAC;AAAA,IACtC;AAEA,QAAI,KAAK,KAAK,KAAK,SAAS,GAAG;AAC7B,cAAQ,OAAO,MAAM,OAAOA,OAAM,IAAI,eAAe,IAAI,IAAI;AAC7D,YAAM,UAAU,KAAK,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC;AACvE,MAAI,MAAM,SAAS,CAAC,SAAS,MAAM,CAAC;AAAA,IACtC;AAAA,EACF,CAAC;AACL;;;AC9DO,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,gBAAY,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,SAAS,YAAY,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;;;ACwBlB,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;AAElD,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,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,YAAY;AACjD;AAEA,SAAS,cAAc,KAAuB;AAC5C,SACE,QAAQ,QACR,OAAO,QAAQ,YACf,eAAgB,OAChB,eAAgB;AAEpB;;;ADjIO,SAAS,uBAAuBC,UAAwB;AAC7D,QAAM,SAASA,SAAQ,QAAQ,QAAQ,EAAE,YAAY,4BAA4B;AAEjF,SACG,QAAQ,SAAS,EAAE,WAAW,KAAK,CAAC,EACpC,YAAY,2CAA2C,EACvD,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,iEAAiE;AAAA,IAC7E;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,UAAM,KAAKC,UAAS,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAEpF,QAAI;AAEF,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,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,MAAM,SAAS;AAC1B,sBAAQ,OAAO,MAAMA,OAAM,IAAI;AAAA,WAAc,IAAI;AAAA,CAAK,CAAC;AACvD,kBAAI,WAAW,SAAS;AACtB,wBAAQ,OAAO,MAAMA,OAAM,IAAI,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,CAAI,CAAC;AAAA,cAC/D;AAAA,YACF;AAAA,YACA,cAAc,CAAC,MAAME,YAAW;AAC9B,kBAAI,WAAW,SAAS;AACtB,wBAAQ,OAAO,MAAMF,OAAM,IAAI,cAAc,IAAI,KAAK,KAAK,UAAUE,OAAM,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,CAAI,CAAC;AAAA,cACjG;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,OAAO,aAAa;AACtB,+BAAmB,OAAO,aAAa,UAAU;AACjD;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,SACG,QAAQ,MAAM,EACd,YAAY,uBAAuB,EACnC,OAAO,yBAAyB,kBAAkB,EAClD,OAAO,OAAO,YAAiC;AAC9C,UAAM,aAAaJ,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,uBAAuB;AAChC;AAAA,IACF;AAEA,IAAI,QAAQ,gBAAgB,KAAK,YAAY,MAAM,GAAG;AAEtD,UAAM,OAAO,KAAK,YAAY,IAAI,CAAC,MAAM;AACvC,YAAM,SAAS,aAAa,EAAE,MAAM;AACpC,YAAM,WAAW,EAAE,cAAc,YAAY;AAC7C,YAAM,OAAO,EAAE,eAAmB,SAAS,EAAE,aAAa,SAAS,IAAI;AACvE,aAAO,CAAC,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,QAAQ,UAAU,MAAU,aAAa,EAAE,UAAU,CAAC;AAAA,IAClF,CAAC;AAED,IAAI,MAAM,MAAM,CAAC,MAAM,UAAU,YAAY,QAAQ,SAAS,CAAC;AAAA,EACjE,CAAC;AAEH,SACG,QAAQ,WAAW,EACnB,YAAY,yBAAyB,EACrC,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,gBAAoB,IAAI,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;AAE9D,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,YAAM,KAAK,WAAW;AACtB,cAAQ,OAAO,MAAM,IAAI;AACzB,MAAI,MAAM;AAAA,QACR,CAAC,YAAY,GAAG,QAAQ;AAAA,QACxB,CAAC,cAAc,GAAG,SAAS;AAAA,QAC3B,CAAC,eAAmB,SAAS,GAAG,UAAU,CAAC;AAAA,QAC3C,CAAC,cAAc,GAAG,UAAU,KAAK,IAAI,CAAC;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,QAAI,WAAW,cAAc;AAC3B,yBAAmB,WAAW,cAAc,UAAU;AAAA,IACxD;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,aAAa,EACrB,YAAY,sBAAsB,EAClC,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,qBAAqB;AAAA,EACnC,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;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,mBACP,QACA,YACM;AACN,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,MAAM;AACf;AAAA,EACF;AAEA,EAAI,QAAQ,cAAc;AAE1B,EAAI,MAAM;AAAA,IACR,CAAC,eAAmB,SAAS,OAAO,UAAU,CAAC;AAAA,IAC/C,CAAC,cAAkB,SAAS,OAAO,SAAS,CAAC;AAAA,IAC7C,CAAC,kBAAsB,SAAS,OAAO,aAAa,CAAC;AAAA,IACrD,CAAC,cAAkB,QAAQ,OAAO,eAAe,CAAC;AAAA,EACpD,CAAC;AAED,MAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,aAAa,IAAI,MAAM;AAC9D,UAAM,OAAO,OAAO,UAAU,IAAI,CAAC,MAAM;AACvC,YAAM,SAAU,EAAE,QAAmC,YAAY;AACjE,YAAM,OAAW,SAAS,OAAO,EAAE,iBAAiB,CAAC,CAAC;AACtD,YAAM,SAAa,SAAS,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAC1D,YAAM,QAAQ,OAAO,EAAE,YAAY,CAAC,EAAE,QAAQ,CAAC;AAC/C,YAAM,SAAS,EAAE,YAAYA,OAAM,OAAO,WAAW,IAAI;AACzD,aAAO,CAAK,SAAS,QAAQ,EAAE,GAAG,OAAO,MAAM,SAAS,MAAM;AAAA,IAChE,CAAC;AACD,IAAI,MAAM,MAAM,CAAC,UAAU,OAAO,QAAQ,QAAQ,CAAC;AAAA,EACrD;AACF;;;AElOA,SAAS,gBAAAG,qBAAoB;AAC7B,OAAOC,YAAW;AAKX,SAAS,qBAAqBC,UAAwB;AAC3D,EAAAA,SACG,QAAQ,cAAc,EACtB,YAAY,oDAAoD,EAChE;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYF,EACC,OAAO,OAAO,SAA6B;AAC1C,UAAM,aAAaA,SAAQ,KAAoB;AAC/C,UAAM,SAAS,IAAI,UAAU,UAAU;AAEvC,QAAI;AACJ,QAAI,CAAC,QAAQ,SAAS,KAAK;AACzB,YAAM,MAAM,UAAU;AAAA,IACxB,OAAO;AACL,UAAI;AACF,cAAMC,cAAa,MAAM,OAAO;AAAA,MAClC,SAAS,GAAG;AACV,QAAI,MAAM,qBAAqB,IAAI,WAAM,aAAa,QAAQ,EAAE,UAAU,CAAC,EAAE;AAC7E,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,MAAM,GAAG;AAAA,IAC1B,QAAQ;AACN,MAAI,MAAM,oDAAoD;AAC9D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc,CAAC,QAAQ,WAAW,QAAQ;AAC1E,MAAI,MAAM,4EAA4E;AACtF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,OAAO,MAAMC,OAAM,IAAI,8CAA8C,CAAC;AAE9E,UAAM,WAAW;AAAA,MACf;AAAA,QACE,MAAM;AAAA,QACN,SAAS,qBAAqB,QAAQ,aAAa,aAAa,oBAAoB,QAAQ,WAAW,eAAe,CAAC,OAAO,QAAQ,QAAQ,YAAY,QAAQ,UAAU,KAAK,IAAI,CAAC;AAAA,MACxL;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,OAAO,aAAa,EAAE,SAAS,CAAC;AAC5D,UAAI,aAA6C;AAEjD,YAAM,UAAU,IAAI,YAAY;AAChC,YAAM,SAAS,OAAO,UAAU;AAChC,UAAI,SAAS;AAEb,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AACV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAEhD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACxB,cAAI,CAAC,KAAK,WAAW,IAAI,EAAG;AAC5B,cAAI;AACF,kBAAM,SAAS,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AACvC,gBAAI,UAAU,OAAO,WAAW,YAAY,eAAe,QAAQ;AACjE,2BAAa;AAAA,YACf;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAEA,UAAI,YAAY;AACd,sBAAc,YAAsC,UAAU;AAAA,MAChE,OAAO;AACL,QAAI,KAAK,yEAAyE;AAAA,MACpF;AAAA,IACF,SAAS,GAAG;AACV,MAAI,MAAM,6BAA6B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AACnF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;AAEA,SAAS,cAAc,QAAqB,YAAiC;AAC3E,MAAI,WAAW,MAAM;AACnB,IAAI,KAAK,MAAM;AACf;AAAA,EACF;AAEA,EAAI,QAAQ,cAAc;AAE1B,EAAI,MAAM;AAAA,IACR,CAAC,eAAmB,SAAS,OAAO,UAAU,CAAC;AAAA,IAC/C,CAAC,cAAkB,SAAS,OAAO,SAAS,CAAC;AAAA,IAC7C,CAAC,kBAAsB,SAAS,OAAO,aAAa,CAAC;AAAA,IACrD,CAAC,cAAkB,QAAQ,OAAO,eAAe,CAAC;AAAA,EACpD,CAAC;AAED,MAAI,OAAO,WAAW,SAAS,GAAG;AAChC,YAAQ,OAAO,MAAM,OAAOA,OAAM,KAAK,aAAa,IAAI,MAAM;AAC9D,UAAM,OAAO,OAAO,UAAU,IAAI,CAAC,MAAM;AACvC,YAAM,SAAS,EAAE,QAAQ,YAAY;AACrC,YAAM,OAAW,SAAS,EAAE,aAAa;AACzC,YAAM,SAAa,SAAS,EAAE,eAAe;AAC7C,YAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAClC,YAAM,SAAS,EAAE,YAAYA,OAAM,OAAO,WAAW,IAAI;AACzD,aAAO,CAAK,SAAS,QAAQ,EAAE,GAAG,OAAO,MAAM,SAAS,MAAM;AAAA,IAChE,CAAC;AACD,IAAI,MAAM,MAAM,CAAC,UAAU,OAAO,QAAQ,QAAQ,CAAC;AAAA,EACrD;AACF;AAEA,eAAe,YAA6B;AAC1C,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ,OAAO;AACvC,WAAO,KAAK,KAAe;AAAA,EAC7B;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAC/C;;;ATpIA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,6DAAwD,EACpE,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,uBAAuB,OAAO;AAC9B,uBAAuB,OAAO;AAC9B,uBAAuB,OAAO;AAC9B,qBAAqB,OAAO;AAE5B,QAAQ,KAAK,aAAa,CAAC,cAAc,kBAAkB;AACzD,QAAM,OAAO,QAAQ,KAAK;AAC1B,MAAI,KAAK,UAAU,OAAO;AACxB,YAAQ,IAAI,cAAc;AAAA,EAC5B;AAEA,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":["program","chalk","program","chalk","program","readline","chalk","program","requireAuth","chalk","readline","result","readFileSync","chalk","program","readFileSync","chalk"]}
|
|
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/markets.ts","../src/commands/profile.ts","../src/commands/research.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerBriefCommands } from \"./commands/brief.js\";\nimport { registerMarketCommands } from \"./commands/markets.js\";\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerResearchCommands } from \"./commands/research.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);\nregisterMarketCommands(program);\nregisterProfileCommand(program);\nregisterResearchCommands(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 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 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 .option(\"--no-stream\", \"Disable streaming — block until complete\")\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: cmdOpts.stream !== false,\n };\n\n if (body.stream) {\n await runStreaming(client, body, globalOpts);\n } else {\n await runBlocking(client, body, globalOpts);\n }\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 stream?: boolean;\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// Blocking mode (--no-stream)\n// ---------------------------------------------------------------------------\n\nasync function runBlocking(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 brief = await client.post<MarketBrief>(\"/api/brief\", body);\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n\n displayBrief(brief, 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}\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\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 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 };\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\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 chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport type { Orderbook, SlippageResult, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerMarketCommands(program: Command): void {\n const markets = program.command(\"markets\").description(\"Polymarket orderbook tools\");\n\n markets\n .command(\"orderbook <tokenId>\")\n .description(\"Show orderbook spread and depth for a CLOB token\")\n .option(\"-s, --size <n>\", \"Size for slippage calculation\")\n .action(async (tokenId: string, cmdOpts: { size?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n const params: Record<string, string> = { tokenId };\n if (cmdOpts.size) params.size = cmdOpts.size;\n\n const data = await client.get<{\n book: Orderbook;\n spread: { bid: number; ask: number; spread: number } | null;\n askDepth: number;\n slippage: SlippageResult | null;\n }>(\"/api/orderbook\", params);\n\n if (globalOpts.json) {\n out.json(data);\n return;\n }\n\n out.heading(\"Orderbook\");\n\n if (data.spread) {\n out.table([\n [\"Best Bid\", data.spread.bid.toFixed(4)],\n [\"Best Ask\", data.spread.ask.toFixed(4)],\n [\"Spread\", out.percent(data.spread.spread)],\n [\"Ask Depth\", out.currency(data.askDepth)],\n ]);\n } else {\n out.warn(\"No spread data available (empty orderbook)\");\n }\n\n if (data.slippage) {\n process.stdout.write(\"\\n\");\n out.table([\n [\"Avg Fill Price\", data.slippage.avgPrice.toFixed(4)],\n [\"Worst Price\", data.slippage.worstPrice.toFixed(4)],\n [\"Slippage\", out.percent(data.slippage.slippage)],\n [\"Fillable Size\", out.currency(data.slippage.fillableSize)],\n ]);\n }\n\n if (data.book.asks.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 asks:\") + \"\\n\");\n const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(askRows, [\"Price\", \"Size\"]);\n }\n\n if (data.book.bids.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 bids:\") + \"\\n\");\n const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(bidRows, [\"Price\", \"Size\"]);\n }\n });\n}\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, GlobalOptions, ResearchResponse } from \"../types.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 const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n\n try {\n // eslint-disable-next-line no-constant-condition\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 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 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 brief as JSON\")\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 result = await client.post<ResearchResponse>(\"/api/research\", { query });\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n\n if (result.brief) {\n out.json(result.brief);\n } else {\n process.stderr.write(chalk.yellow(\"No market brief was produced.\\n\"));\n out.json(result);\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\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"],"mappings":"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","names":["program","chalk","error","program","chalk","chalk","program","chalk","program","requireAuth","readline","chalk","program","requireAuth","chalk","readline"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hedge-layer/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI for Hedge Layer —
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "CLI for Hedge Layer — prediction market intelligence from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"hl": "dist/index.mjs"
|
|
@@ -21,12 +21,15 @@
|
|
|
21
21
|
"node": ">=22"
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|
|
24
|
-
"hedge",
|
|
25
24
|
"polymarket",
|
|
26
25
|
"prediction-markets",
|
|
27
|
-
"
|
|
26
|
+
"market-intelligence",
|
|
27
|
+
"market-brief",
|
|
28
28
|
"cli"
|
|
29
29
|
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
30
33
|
"license": "MIT",
|
|
31
34
|
"repository": {
|
|
32
35
|
"type": "git",
|
|
@@ -38,8 +41,11 @@
|
|
|
38
41
|
"ora": "^8.2.0"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
44
|
+
"@eslint/js": "^10.0.1",
|
|
45
|
+
"eslint": "^10.0.3",
|
|
41
46
|
"tsup": "^8.4.0",
|
|
42
47
|
"typescript": "^5.7.0",
|
|
48
|
+
"typescript-eslint": "^8.57.0",
|
|
43
49
|
"vitest": "^4.0.0"
|
|
44
50
|
}
|
|
45
51
|
}
|