@hedge-layer/cli 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -48
- package/dist/index.mjs +114 -293
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -6
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,11 +20,8 @@ Requires Node.js 22 or later.
|
|
|
20
20
|
# 2. Authenticate the CLI
|
|
21
21
|
hl auth login
|
|
22
22
|
|
|
23
|
-
# 3.
|
|
24
|
-
hl
|
|
25
|
-
|
|
26
|
-
# 4. Start an interactive risk assessment
|
|
27
|
-
hl assess
|
|
23
|
+
# 3. Start an interactive research session
|
|
24
|
+
hl research
|
|
28
25
|
```
|
|
29
26
|
|
|
30
27
|
## Authentication
|
|
@@ -40,59 +37,38 @@ hl auth logout # Remove stored token
|
|
|
40
37
|
You can also pass a token inline for CI/scripts:
|
|
41
38
|
|
|
42
39
|
```bash
|
|
43
|
-
hl --token hl_abc123...
|
|
40
|
+
hl --token hl_abc123... research list
|
|
44
41
|
```
|
|
45
42
|
|
|
46
43
|
## Commands
|
|
47
44
|
|
|
48
|
-
###
|
|
45
|
+
### Research
|
|
49
46
|
|
|
50
|
-
|
|
47
|
+
AI-powered market research sessions. Describe a topic or thesis, and the AI researches current events, discovers relevant prediction markets, and synthesizes a structured Market Brief.
|
|
51
48
|
|
|
52
49
|
```bash
|
|
53
|
-
#
|
|
54
|
-
hl
|
|
55
|
-
hl markets search "hurricane" --limit 20
|
|
56
|
-
|
|
57
|
-
# View orderbook for a specific CLOB token
|
|
58
|
-
hl markets orderbook <tokenId>
|
|
59
|
-
hl markets orderbook <tokenId> --size 1000
|
|
60
|
-
```
|
|
50
|
+
# Start an interactive research session
|
|
51
|
+
hl research
|
|
61
52
|
|
|
62
|
-
|
|
53
|
+
# List past research sessions
|
|
54
|
+
hl research list
|
|
55
|
+
hl research list --status completed
|
|
63
56
|
|
|
64
|
-
|
|
57
|
+
# View a specific session and its Market Brief
|
|
58
|
+
hl research show <id>
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
hl assess
|
|
69
|
-
|
|
70
|
-
# List past assessments
|
|
71
|
-
hl assess list
|
|
72
|
-
hl assess list --status completed
|
|
73
|
-
|
|
74
|
-
# View a specific assessment
|
|
75
|
-
hl assess show <id>
|
|
76
|
-
|
|
77
|
-
# Delete an assessment
|
|
78
|
-
hl assess delete <id>
|
|
60
|
+
# Delete a session
|
|
61
|
+
hl research delete <id>
|
|
79
62
|
```
|
|
80
63
|
|
|
81
|
-
###
|
|
64
|
+
### Markets
|
|
82
65
|
|
|
83
|
-
|
|
66
|
+
Polymarket orderbook tools.
|
|
84
67
|
|
|
85
68
|
```bash
|
|
86
|
-
#
|
|
87
|
-
hl
|
|
88
|
-
|
|
89
|
-
# From stdin
|
|
90
|
-
echo '{
|
|
91
|
-
"location": "33109",
|
|
92
|
-
"assetType": "residential",
|
|
93
|
-
"riskTypes": ["hurricane", "flood"],
|
|
94
|
-
"assetValue": 500000
|
|
95
|
-
}' | hl hedge -
|
|
69
|
+
# View orderbook for a specific CLOB token
|
|
70
|
+
hl markets orderbook <tokenId>
|
|
71
|
+
hl markets orderbook <tokenId> --size 1000
|
|
96
72
|
```
|
|
97
73
|
|
|
98
74
|
### Profile
|
|
@@ -116,8 +92,7 @@ hl profile
|
|
|
116
92
|
Every command supports `--json` for pipe-friendly output:
|
|
117
93
|
|
|
118
94
|
```bash
|
|
119
|
-
hl --json
|
|
120
|
-
hl --json assess list | jq '.[0].id'
|
|
95
|
+
hl --json research list | jq '.[0].id'
|
|
121
96
|
```
|
|
122
97
|
|
|
123
98
|
## Development
|
|
@@ -130,7 +105,7 @@ npm run build # Build with tsup
|
|
|
130
105
|
npm run dev # Watch mode
|
|
131
106
|
|
|
132
107
|
# Test against local dev server
|
|
133
|
-
node dist/index.mjs --api-url http://localhost:3000
|
|
108
|
+
node dist/index.mjs --api-url http://localhost:3000 research list
|
|
134
109
|
```
|
|
135
110
|
|
|
136
111
|
## Publishing
|
|
@@ -142,7 +117,7 @@ npm version patch # or minor / major
|
|
|
142
117
|
git push --tags
|
|
143
118
|
```
|
|
144
119
|
|
|
145
|
-
The workflow builds and publishes to npm when a version tag (`v*`) is pushed.
|
|
120
|
+
The workflow builds and publishes to npm when a version tag (`v*`) is pushed. Authentication uses npm's OIDC trusted publishers — no secrets required.
|
|
146
121
|
|
|
147
122
|
## Changelog
|
|
148
123
|
|
package/dist/index.mjs
CHANGED
|
@@ -316,33 +316,7 @@ function registerAuthCommands(program2) {
|
|
|
316
316
|
// src/commands/markets.ts
|
|
317
317
|
import chalk2 from "chalk";
|
|
318
318
|
function registerMarketCommands(program2) {
|
|
319
|
-
const markets = program2.command("markets").description("
|
|
320
|
-
markets.command("search <query>").description("Search for markets by keyword").option("-l, --limit <n>", "Max results", "10").action(async (query, cmdOpts) => {
|
|
321
|
-
const globalOpts = program2.opts();
|
|
322
|
-
const client = new ApiClient(globalOpts);
|
|
323
|
-
const data = await client.get("/api/markets", {
|
|
324
|
-
q: query,
|
|
325
|
-
limit: cmdOpts.limit
|
|
326
|
-
});
|
|
327
|
-
if (globalOpts.json) {
|
|
328
|
-
json(data);
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
if (data.markets.length === 0) {
|
|
332
|
-
warn(`No markets found for "${query}"`);
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
heading(`Markets matching "${query}" (${data.total} total)`);
|
|
336
|
-
const rows = data.markets.map((m) => {
|
|
337
|
-
const prices = parseOutcomePrices(m.outcomePrices);
|
|
338
|
-
const yesPrice = prices ? percent(prices[0]) : "\u2014";
|
|
339
|
-
const vol = formatVolume(m.volume);
|
|
340
|
-
const end = m.endDate ? formatDate(m.endDate) : "\u2014";
|
|
341
|
-
const status = m.closed ? chalk2.red("closed") : chalk2.green("active");
|
|
342
|
-
return [truncate(m.question, 50), yesPrice, vol, end, status];
|
|
343
|
-
});
|
|
344
|
-
table(rows, ["Market", "YES", "Volume", "Ends", "Status"]);
|
|
345
|
-
});
|
|
319
|
+
const markets = program2.command("markets").description("Polymarket orderbook tools");
|
|
346
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) => {
|
|
347
321
|
const globalOpts = program2.opts();
|
|
348
322
|
const client = new ApiClient(globalOpts);
|
|
@@ -385,27 +359,6 @@ function registerMarketCommands(program2) {
|
|
|
385
359
|
}
|
|
386
360
|
});
|
|
387
361
|
}
|
|
388
|
-
function parseOutcomePrices(raw) {
|
|
389
|
-
try {
|
|
390
|
-
const parsed = JSON.parse(raw);
|
|
391
|
-
if (Array.isArray(parsed) && parsed.length === 2) {
|
|
392
|
-
return [Number(parsed[0]), Number(parsed[1])];
|
|
393
|
-
}
|
|
394
|
-
} catch {
|
|
395
|
-
}
|
|
396
|
-
return null;
|
|
397
|
-
}
|
|
398
|
-
function formatVolume(vol) {
|
|
399
|
-
const n = Number(vol);
|
|
400
|
-
if (isNaN(n)) return vol;
|
|
401
|
-
if (n >= 1e6) return `$${(n / 1e6).toFixed(1)}M`;
|
|
402
|
-
if (n >= 1e3) return `$${(n / 1e3).toFixed(1)}K`;
|
|
403
|
-
return `$${n.toFixed(0)}`;
|
|
404
|
-
}
|
|
405
|
-
function formatDate(iso) {
|
|
406
|
-
const d = new Date(iso);
|
|
407
|
-
return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
408
|
-
}
|
|
409
362
|
|
|
410
363
|
// src/commands/profile.ts
|
|
411
364
|
function registerProfileCommand(program2) {
|
|
@@ -433,7 +386,7 @@ function requireAuth(client) {
|
|
|
433
386
|
}
|
|
434
387
|
}
|
|
435
388
|
|
|
436
|
-
// src/commands/
|
|
389
|
+
// src/commands/research.ts
|
|
437
390
|
import readline2 from "readline/promises";
|
|
438
391
|
import chalk3 from "chalk";
|
|
439
392
|
|
|
@@ -445,113 +398,106 @@ async function parseStream(body, callbacks = {}) {
|
|
|
445
398
|
let assistantText = "";
|
|
446
399
|
const toolCalls = [];
|
|
447
400
|
const activeToolCalls = /* @__PURE__ */ new Map();
|
|
448
|
-
let
|
|
401
|
+
let marketBrief = null;
|
|
449
402
|
while (true) {
|
|
450
403
|
const { done, value } = await reader.read();
|
|
451
|
-
if (done)
|
|
452
|
-
|
|
404
|
+
if (!done) {
|
|
405
|
+
buffer += decoder.decode(value, { stream: true });
|
|
406
|
+
}
|
|
453
407
|
const lines = buffer.split("\n");
|
|
454
|
-
buffer = lines.pop() ?? "";
|
|
408
|
+
buffer = done ? "" : lines.pop() ?? "";
|
|
455
409
|
for (const line of lines) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
410
|
+
const trimmed = line.trim();
|
|
411
|
+
if (!trimmed || trimmed.startsWith(":")) continue;
|
|
412
|
+
if (!trimmed.startsWith("data:")) continue;
|
|
413
|
+
const payload = trimmed.slice(5).trim();
|
|
414
|
+
if (payload === "[DONE]") continue;
|
|
415
|
+
let msg;
|
|
416
|
+
try {
|
|
417
|
+
msg = JSON.parse(payload);
|
|
418
|
+
} catch {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
const type = msg.type;
|
|
459
422
|
switch (type) {
|
|
460
|
-
case "
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
assistantText +=
|
|
464
|
-
callbacks.onText?.(
|
|
465
|
-
} catch {
|
|
423
|
+
case "text-delta": {
|
|
424
|
+
const delta = msg.delta;
|
|
425
|
+
if (delta) {
|
|
426
|
+
assistantText += delta;
|
|
427
|
+
callbacks.onText?.(delta);
|
|
466
428
|
}
|
|
467
429
|
break;
|
|
468
430
|
}
|
|
469
|
-
case "
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
431
|
+
case "tool-input-start": {
|
|
432
|
+
const id = msg.toolCallId;
|
|
433
|
+
const name = msg.toolName;
|
|
434
|
+
if (id && name) {
|
|
435
|
+
activeToolCalls.set(id, { name, argStr: "" });
|
|
474
436
|
}
|
|
475
437
|
break;
|
|
476
438
|
}
|
|
477
|
-
case "
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
} catch {
|
|
439
|
+
case "tool-input-delta": {
|
|
440
|
+
const id = msg.toolCallId;
|
|
441
|
+
const active = activeToolCalls.get(id);
|
|
442
|
+
if (active) {
|
|
443
|
+
active.argStr += msg.inputTextDelta;
|
|
483
444
|
}
|
|
484
445
|
break;
|
|
485
446
|
}
|
|
486
|
-
case "
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
args = JSON.parse(active.argStr);
|
|
494
|
-
} catch {
|
|
495
|
-
args = active.argStr;
|
|
496
|
-
}
|
|
497
|
-
toolCalls.push({ name: active.name, args });
|
|
498
|
-
callbacks.onToolCall?.(active.name, args);
|
|
499
|
-
callbacks.onToolResult?.(active.name, data.result);
|
|
500
|
-
if (active.name === "buildHedgeBundle" && isHedgeBundle(data.result)) {
|
|
501
|
-
hedgeBundle = data.result;
|
|
502
|
-
}
|
|
503
|
-
activeToolCalls.delete(data.toolCallId);
|
|
504
|
-
}
|
|
505
|
-
} catch {
|
|
447
|
+
case "tool-input-available": {
|
|
448
|
+
const id = msg.toolCallId;
|
|
449
|
+
const active = activeToolCalls.get(id);
|
|
450
|
+
if (active) {
|
|
451
|
+
const args = msg.input ?? active.argStr;
|
|
452
|
+
toolCalls.push({ name: active.name, args });
|
|
453
|
+
callbacks.onToolCall?.(active.name, args);
|
|
506
454
|
}
|
|
507
455
|
break;
|
|
508
456
|
}
|
|
509
|
-
case "
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
}
|
|
457
|
+
case "tool-output-available": {
|
|
458
|
+
const id = msg.toolCallId;
|
|
459
|
+
const active = activeToolCalls.get(id);
|
|
460
|
+
if (active) {
|
|
461
|
+
callbacks.onToolResult?.(active.name, msg.output);
|
|
462
|
+
if (active.name === "buildMarketBrief" && isMarketBrief(msg.output)) {
|
|
463
|
+
marketBrief = msg.output;
|
|
518
464
|
}
|
|
519
|
-
|
|
465
|
+
activeToolCalls.delete(id);
|
|
520
466
|
}
|
|
521
467
|
break;
|
|
522
468
|
}
|
|
523
|
-
case "
|
|
524
|
-
|
|
525
|
-
const errData = JSON.parse(payload);
|
|
526
|
-
throw new Error(
|
|
527
|
-
typeof errData === "string" ? errData : JSON.stringify(errData)
|
|
528
|
-
);
|
|
529
|
-
} catch (e) {
|
|
530
|
-
if (e instanceof Error && e.message !== payload) throw e;
|
|
531
|
-
}
|
|
532
|
-
break;
|
|
469
|
+
case "error": {
|
|
470
|
+
throw new Error(msg.errorText ?? "Unknown stream error");
|
|
533
471
|
}
|
|
534
472
|
}
|
|
535
473
|
}
|
|
474
|
+
if (done) break;
|
|
536
475
|
}
|
|
537
|
-
return { assistantText, toolCalls,
|
|
476
|
+
return { assistantText, toolCalls, marketBrief };
|
|
538
477
|
}
|
|
539
|
-
function
|
|
540
|
-
return val !== null && typeof val === "object" && "
|
|
478
|
+
function isMarketBrief(val) {
|
|
479
|
+
return val !== null && typeof val === "object" && "title" in val && "markets" in val;
|
|
541
480
|
}
|
|
542
481
|
|
|
543
|
-
// src/commands/
|
|
544
|
-
function
|
|
545
|
-
const
|
|
546
|
-
|
|
482
|
+
// src/commands/research.ts
|
|
483
|
+
function registerResearchCommands(program2) {
|
|
484
|
+
const research = program2.command("research").description("AI-powered market research");
|
|
485
|
+
research.command("start", { isDefault: true }).description("Start an interactive market research session").action(async () => {
|
|
547
486
|
const globalOpts = program2.opts();
|
|
548
487
|
const client = new ApiClient(globalOpts);
|
|
549
488
|
requireAuth2(client);
|
|
550
489
|
const { id } = await client.post("/api/assessments");
|
|
551
|
-
heading("
|
|
490
|
+
heading("Market Research");
|
|
552
491
|
process.stderr.write(
|
|
553
|
-
chalk3.dim(" Describe
|
|
492
|
+
chalk3.dim(" Describe a topic or thesis to explore. Type /quit to exit.\n\n")
|
|
554
493
|
);
|
|
494
|
+
let msgCounter = 0;
|
|
495
|
+
const uiMsg = (role, content) => ({
|
|
496
|
+
id: `msg-${++msgCounter}`,
|
|
497
|
+
role,
|
|
498
|
+
content,
|
|
499
|
+
parts: [{ type: "text", text: content }]
|
|
500
|
+
});
|
|
555
501
|
const messages = [];
|
|
556
502
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
557
503
|
try {
|
|
@@ -559,7 +505,7 @@ function registerAssessCommands(program2) {
|
|
|
559
505
|
const userInput = await rl.question(chalk3.cyan("You: "));
|
|
560
506
|
if (!userInput.trim()) continue;
|
|
561
507
|
if (userInput.trim() === "/quit") break;
|
|
562
|
-
messages.push(
|
|
508
|
+
messages.push(uiMsg("user", userInput));
|
|
563
509
|
process.stderr.write(chalk3.dim("\nAssistant: "));
|
|
564
510
|
try {
|
|
565
511
|
const body = await client.stream("/api/chat", {
|
|
@@ -568,28 +514,24 @@ function registerAssessCommands(program2) {
|
|
|
568
514
|
});
|
|
569
515
|
const result = await parseStream(body, {
|
|
570
516
|
onText: (text) => process.stderr.write(text),
|
|
571
|
-
onToolCall: (name
|
|
517
|
+
onToolCall: (name) => {
|
|
572
518
|
process.stderr.write(chalk3.dim(`
|
|
573
519
|
[tool: ${name}]
|
|
574
520
|
`));
|
|
575
|
-
if (globalOpts.verbose) {
|
|
576
|
-
process.stderr.write(chalk3.dim(` ${JSON.stringify(args)}
|
|
577
|
-
`));
|
|
578
|
-
}
|
|
579
521
|
},
|
|
580
|
-
onToolResult: (name,
|
|
522
|
+
onToolResult: (name, toolResult) => {
|
|
581
523
|
if (globalOpts.verbose) {
|
|
582
|
-
process.stderr.write(chalk3.dim(` [result: ${name}] ${JSON.stringify(
|
|
524
|
+
process.stderr.write(chalk3.dim(` [result: ${name}] ${JSON.stringify(toolResult).slice(0, 200)}
|
|
583
525
|
`));
|
|
584
526
|
}
|
|
585
527
|
}
|
|
586
528
|
});
|
|
587
529
|
process.stderr.write("\n\n");
|
|
588
530
|
if (result.assistantText) {
|
|
589
|
-
messages.push(
|
|
531
|
+
messages.push(uiMsg("assistant", result.assistantText));
|
|
590
532
|
}
|
|
591
|
-
if (result.
|
|
592
|
-
|
|
533
|
+
if (result.marketBrief) {
|
|
534
|
+
displayMarketBrief(result.marketBrief, globalOpts);
|
|
593
535
|
break;
|
|
594
536
|
}
|
|
595
537
|
} catch (e) {
|
|
@@ -601,7 +543,7 @@ function registerAssessCommands(program2) {
|
|
|
601
543
|
rl.close();
|
|
602
544
|
}
|
|
603
545
|
});
|
|
604
|
-
|
|
546
|
+
research.command("list").description("List past research sessions").option("-s, --status <status>", "Filter by status").action(async (cmdOpts) => {
|
|
605
547
|
const globalOpts = program2.opts();
|
|
606
548
|
const client = new ApiClient(globalOpts);
|
|
607
549
|
requireAuth2(client);
|
|
@@ -613,19 +555,19 @@ function registerAssessCommands(program2) {
|
|
|
613
555
|
return;
|
|
614
556
|
}
|
|
615
557
|
if (data.assessments.length === 0) {
|
|
616
|
-
warn("No
|
|
558
|
+
warn("No research sessions found.");
|
|
617
559
|
return;
|
|
618
560
|
}
|
|
619
|
-
heading(`
|
|
561
|
+
heading(`Research Sessions (${data.assessments.length})`);
|
|
620
562
|
const rows = data.assessments.map((a) => {
|
|
621
563
|
const status = formatStatus(a.status);
|
|
622
|
-
const
|
|
623
|
-
const
|
|
624
|
-
return [a.id.slice(0, 8), status,
|
|
564
|
+
const brief = a.market_brief?.title ?? "\u2014";
|
|
565
|
+
const markets = a.market_brief ? String(a.market_brief.marketCount) : "\u2014";
|
|
566
|
+
return [a.id.slice(0, 8), status, truncate(brief, 30), markets, relativeTime(a.created_at)];
|
|
625
567
|
});
|
|
626
|
-
table(rows, ["ID", "Status", "
|
|
568
|
+
table(rows, ["ID", "Status", "Brief", "Markets", "Created"]);
|
|
627
569
|
});
|
|
628
|
-
|
|
570
|
+
research.command("show <id>").description("Show research session details").action(async (id) => {
|
|
629
571
|
const globalOpts = program2.opts();
|
|
630
572
|
const client = new ApiClient(globalOpts);
|
|
631
573
|
requireAuth2(client);
|
|
@@ -634,32 +576,22 @@ function registerAssessCommands(program2) {
|
|
|
634
576
|
json(assessment);
|
|
635
577
|
return;
|
|
636
578
|
}
|
|
637
|
-
heading("
|
|
579
|
+
heading("Research Session " + dim(assessment.id.slice(0, 8)));
|
|
638
580
|
table([
|
|
639
581
|
["Status", formatStatus(assessment.status)],
|
|
640
582
|
["Created", new Date(assessment.created_at).toLocaleString()],
|
|
641
583
|
["Updated", new Date(assessment.updated_at).toLocaleString()]
|
|
642
584
|
]);
|
|
643
|
-
if (assessment.
|
|
644
|
-
|
|
645
|
-
process.stdout.write("\n");
|
|
646
|
-
table([
|
|
647
|
-
["Location", rp.location],
|
|
648
|
-
["Asset Type", rp.assetType],
|
|
649
|
-
["Asset Value", currency(rp.assetValue)],
|
|
650
|
-
["Risk Types", rp.riskTypes.join(", ")]
|
|
651
|
-
]);
|
|
652
|
-
}
|
|
653
|
-
if (assessment.hedge_bundle) {
|
|
654
|
-
displayHedgeBundle(assessment.hedge_bundle, globalOpts);
|
|
585
|
+
if (assessment.market_brief) {
|
|
586
|
+
displayMarketBrief(assessment.market_brief, globalOpts);
|
|
655
587
|
}
|
|
656
588
|
});
|
|
657
|
-
|
|
589
|
+
research.command("delete <id>").description("Delete a research session").action(async (id) => {
|
|
658
590
|
const globalOpts = program2.opts();
|
|
659
591
|
const client = new ApiClient(globalOpts);
|
|
660
592
|
requireAuth2(client);
|
|
661
593
|
await client.delete(`/api/assessments/${id}`);
|
|
662
|
-
success("
|
|
594
|
+
success("Research session deleted.");
|
|
663
595
|
});
|
|
664
596
|
}
|
|
665
597
|
function requireAuth2(client) {
|
|
@@ -680,157 +612,46 @@ function formatStatus(status) {
|
|
|
680
612
|
return status;
|
|
681
613
|
}
|
|
682
614
|
}
|
|
683
|
-
function
|
|
615
|
+
function displayMarketBrief(brief, globalOpts) {
|
|
684
616
|
if (globalOpts.json) {
|
|
685
|
-
json(
|
|
617
|
+
json(brief);
|
|
686
618
|
return;
|
|
687
619
|
}
|
|
688
|
-
heading("
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
const market = p.market?.question ?? "Unknown";
|
|
699
|
-
const cost = currency(Number(p.estimatedCost ?? 0));
|
|
700
|
-
const payout = currency(Number(p.potentialPayout ?? 0));
|
|
701
|
-
const price = Number(p.yesPrice ?? 0).toFixed(2);
|
|
702
|
-
const capped = p.wasCapped ? chalk3.yellow(" (capped)") : "";
|
|
703
|
-
return [truncate(market, 40), price, cost, payout + capped];
|
|
620
|
+
heading("Market Brief");
|
|
621
|
+
process.stdout.write(" " + chalk3.bold(brief.title) + "\n\n");
|
|
622
|
+
process.stdout.write(" " + chalk3.italic(brief.thesis) + "\n");
|
|
623
|
+
if (brief.markets.length > 0) {
|
|
624
|
+
process.stdout.write("\n" + chalk3.bold(" Markets") + "\n\n");
|
|
625
|
+
const rows = brief.markets.map((m) => {
|
|
626
|
+
const prob = percent(m.yesPrice);
|
|
627
|
+
const signals = m.signals.length > 0 ? m.signals.join(", ") : "\u2014";
|
|
628
|
+
const liq = m.liquidity ? currency(m.liquidity) : "\u2014";
|
|
629
|
+
return [truncate(m.question, 40), prob, signals, liq];
|
|
704
630
|
});
|
|
705
|
-
table(rows, ["Market", "
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
import chalk4 from "chalk";
|
|
712
|
-
function registerHedgeCommand(program2) {
|
|
713
|
-
program2.command("hedge [file]").description("Calculate hedge positions from a risk profile JSON").addHelpText(
|
|
714
|
-
"after",
|
|
715
|
-
`
|
|
716
|
-
Example risk profile JSON:
|
|
717
|
-
{
|
|
718
|
-
"location": "33109",
|
|
719
|
-
"assetType": "residential",
|
|
720
|
-
"riskTypes": ["hurricane", "flood"],
|
|
721
|
-
"assetValue": 500000
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
Usage:
|
|
725
|
-
hl hedge profile.json Read from file
|
|
726
|
-
echo '{"location":...}' | hl hedge - Read from stdin`
|
|
727
|
-
).action(async (file) => {
|
|
728
|
-
const globalOpts = program2.opts();
|
|
729
|
-
const client = new ApiClient(globalOpts);
|
|
730
|
-
let raw;
|
|
731
|
-
if (!file || file === "-") {
|
|
732
|
-
raw = await readStdin();
|
|
733
|
-
} else {
|
|
734
|
-
try {
|
|
735
|
-
raw = readFileSync2(file, "utf-8");
|
|
736
|
-
} catch (e) {
|
|
737
|
-
error(`Cannot read file: ${file} \u2014 ${e instanceof Error ? e.message : e}`);
|
|
738
|
-
process.exit(1);
|
|
739
|
-
}
|
|
631
|
+
table(rows, ["Market", "Prob", "Signals", "Liq"]);
|
|
632
|
+
process.stdout.write("\n");
|
|
633
|
+
for (const m of brief.markets) {
|
|
634
|
+
process.stdout.write(" " + chalk3.dim("\u25B8 ") + truncate(m.question, 50) + "\n");
|
|
635
|
+
process.stdout.write(" " + chalk3.dim("Causal link: ") + m.causalLink + "\n");
|
|
636
|
+
process.stdout.write(" " + chalk3.dim("Polymarket: ") + m.polymarketUrl + "\n");
|
|
740
637
|
}
|
|
741
|
-
let profile;
|
|
742
|
-
try {
|
|
743
|
-
profile = JSON.parse(raw);
|
|
744
|
-
} catch {
|
|
745
|
-
error("Invalid JSON input. Expected a RiskProfile object.");
|
|
746
|
-
process.exit(1);
|
|
747
|
-
}
|
|
748
|
-
if (!profile.location || !profile.assetValue || !profile.riskTypes?.length) {
|
|
749
|
-
error("Risk profile must include location, assetValue, and at least one riskType.");
|
|
750
|
-
process.exit(1);
|
|
751
|
-
}
|
|
752
|
-
process.stderr.write(chalk4.dim("Searching markets and calculating hedge...\n"));
|
|
753
|
-
const messages = [
|
|
754
|
-
{
|
|
755
|
-
role: "user",
|
|
756
|
-
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.`
|
|
757
|
-
}
|
|
758
|
-
];
|
|
759
|
-
try {
|
|
760
|
-
const stream = await client.stream("/api/chat", { messages });
|
|
761
|
-
let bundleJson = null;
|
|
762
|
-
const decoder = new TextDecoder();
|
|
763
|
-
const reader = stream.getReader();
|
|
764
|
-
let buffer = "";
|
|
765
|
-
while (true) {
|
|
766
|
-
const { done, value } = await reader.read();
|
|
767
|
-
if (done) break;
|
|
768
|
-
buffer += decoder.decode(value, { stream: true });
|
|
769
|
-
const lines = buffer.split("\n");
|
|
770
|
-
buffer = lines.pop() ?? "";
|
|
771
|
-
for (const line of lines) {
|
|
772
|
-
if (!line.startsWith("d:")) continue;
|
|
773
|
-
try {
|
|
774
|
-
const parsed = JSON.parse(line.slice(2));
|
|
775
|
-
if (parsed && typeof parsed === "object" && "positions" in parsed) {
|
|
776
|
-
bundleJson = parsed;
|
|
777
|
-
}
|
|
778
|
-
} catch {
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
if (bundleJson) {
|
|
783
|
-
displayBundle(bundleJson, globalOpts);
|
|
784
|
-
} else {
|
|
785
|
-
warn("No hedge bundle was produced. Try the interactive assessment: hl assess");
|
|
786
|
-
}
|
|
787
|
-
} catch (e) {
|
|
788
|
-
error(`Hedge calculation failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
789
|
-
process.exit(1);
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
function displayBundle(bundle, globalOpts) {
|
|
794
|
-
if (globalOpts.json) {
|
|
795
|
-
json(bundle);
|
|
796
|
-
return;
|
|
797
638
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
["Efficiency", percent(bundle.hedgeEfficiency)]
|
|
804
|
-
]);
|
|
805
|
-
if (bundle.positions?.length > 0) {
|
|
806
|
-
process.stdout.write("\n" + chalk4.bold(" Positions") + "\n\n");
|
|
807
|
-
const rows = bundle.positions.map((p) => {
|
|
808
|
-
const market = p.market?.question ?? "Unknown";
|
|
809
|
-
const cost = currency(p.estimatedCost);
|
|
810
|
-
const payout = currency(p.potentialPayout);
|
|
811
|
-
const price = p.yesPrice.toFixed(2);
|
|
812
|
-
const capped = p.wasCapped ? chalk4.yellow(" (capped)") : "";
|
|
813
|
-
return [truncate(market, 40), price, cost, payout + capped];
|
|
814
|
-
});
|
|
815
|
-
table(rows, ["Market", "YES", "Cost", "Payout"]);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
async function readStdin() {
|
|
819
|
-
const chunks = [];
|
|
820
|
-
for await (const chunk of process.stdin) {
|
|
821
|
-
chunks.push(chunk);
|
|
639
|
+
if (brief.gaps.length > 0) {
|
|
640
|
+
process.stdout.write("\n" + chalk3.bold(" Coverage Gaps") + "\n\n");
|
|
641
|
+
for (const gap of brief.gaps) {
|
|
642
|
+
process.stdout.write(" " + chalk3.yellow("\u25B8") + " " + gap + "\n");
|
|
643
|
+
}
|
|
822
644
|
}
|
|
823
|
-
|
|
645
|
+
process.stdout.write("\n " + chalk3.dim(`${brief.marketCount} markets \xB7 ${brief.gaps.length} coverage gaps`) + "\n");
|
|
824
646
|
}
|
|
825
647
|
|
|
826
648
|
// src/index.ts
|
|
827
649
|
var program = new Command();
|
|
828
|
-
program.name("hl").description("Hedge Layer CLI \u2014
|
|
650
|
+
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.0.0").option("--json", "Output as JSON (machine-readable)").option("--api-url <url>", "Override API base URL").option("--token <token>", "Override stored API token").option("--verbose", "Show HTTP request details").option("--no-color", "Disable colored output");
|
|
829
651
|
registerAuthCommands(program);
|
|
830
652
|
registerMarketCommands(program);
|
|
831
653
|
registerProfileCommand(program);
|
|
832
|
-
|
|
833
|
-
registerHedgeCommand(program);
|
|
654
|
+
registerResearchCommands(program);
|
|
834
655
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
835
656
|
const opts = program.opts();
|
|
836
657
|
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(\"0.1.0\")\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 { Market, 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(\"Browse Polymarket prediction markets\");\n\n markets\n .command(\"search <query>\")\n .description(\"Search for markets by keyword\")\n .option(\"-l, --limit <n>\", \"Max results\", \"10\")\n .action(async (query: string, cmdOpts: { limit: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n const data = await client.get<{ markets: Market[]; total: number }>(\"/api/markets\", {\n q: query,\n limit: cmdOpts.limit,\n });\n\n if (globalOpts.json) {\n out.json(data);\n return;\n }\n\n if (data.markets.length === 0) {\n out.warn(`No markets found for \"${query}\"`);\n return;\n }\n\n out.heading(`Markets matching \"${query}\" (${data.total} total)`);\n\n const rows = data.markets.map((m) => {\n const prices = parseOutcomePrices(m.outcomePrices);\n const yesPrice = prices ? out.percent(prices[0]) : \"—\";\n const vol = formatVolume(m.volume);\n const end = m.endDate ? formatDate(m.endDate) : \"—\";\n const status = m.closed ? chalk.red(\"closed\") : chalk.green(\"active\");\n return [out.truncate(m.question, 50), yesPrice, vol, end, status];\n });\n\n out.table(rows, [\"Market\", \"YES\", \"Volume\", \"Ends\", \"Status\"]);\n });\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\nfunction parseOutcomePrices(raw: string): [number, number] | null {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed) && parsed.length === 2) {\n return [Number(parsed[0]), Number(parsed[1])];\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nfunction formatVolume(vol: string): string {\n const n = Number(vol);\n if (isNaN(n)) return vol;\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nfunction formatDate(iso: string): string {\n const d = new Date(iso);\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\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 const messages: { role: string; content: string }[] = [];\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({ role: \"user\", content: 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({ role: \"assistant\", content: 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 streaming response format.\n *\n * The AI SDK uses a line-based protocol where each line is prefixed with\n * a type code and colon. Key types:\n * 0: text delta (JSON-encoded string)\n * 9: tool call begin { toolCallId, toolName }\n * a: tool call delta (partial JSON args)\n * b: tool result { toolCallId, result }\n * d: finish message data (array)\n * e: error\n * f: message annotations\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) 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.length < 2 || line[1] !== \":\") continue;\n\n const type = line[0];\n const payload = line.slice(2);\n\n switch (type) {\n case \"0\": {\n try {\n const text = JSON.parse(payload) as string;\n assistantText += text;\n callbacks.onText?.(text);\n } catch {\n // skip malformed text delta\n }\n break;\n }\n\n case \"9\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; toolName: string };\n activeToolCalls.set(data.toolCallId, { name: data.toolName, argStr: \"\" });\n } catch {\n // skip\n }\n break;\n }\n\n case \"a\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; argsTextDelta: string };\n const active = activeToolCalls.get(data.toolCallId);\n if (active) active.argStr += data.argsTextDelta;\n } catch {\n // skip\n }\n break;\n }\n\n case \"b\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; result: unknown };\n const active = activeToolCalls.get(data.toolCallId);\n if (active) {\n let args: unknown = undefined;\n try {\n args = JSON.parse(active.argStr);\n } catch {\n args = active.argStr;\n }\n toolCalls.push({ name: active.name, args });\n callbacks.onToolCall?.(active.name, args);\n callbacks.onToolResult?.(active.name, data.result);\n\n if (active.name === \"buildHedgeBundle\" && isHedgeBundle(data.result)) {\n hedgeBundle = data.result as Record<string, unknown>;\n }\n activeToolCalls.delete(data.toolCallId);\n }\n } catch {\n // skip\n }\n break;\n }\n\n case \"d\": {\n try {\n const finishData = JSON.parse(payload);\n if (Array.isArray(finishData)) {\n for (const item of finishData) {\n if (item && typeof item === \"object\" && \"positions\" in item) {\n hedgeBundle = item as Record<string, unknown>;\n }\n }\n }\n } catch {\n // skip\n }\n break;\n }\n\n case \"e\": {\n try {\n const errData = JSON.parse(payload);\n throw new Error(\n typeof errData === \"string\" ? errData : JSON.stringify(errData),\n );\n } catch (e) {\n if (e instanceof Error && e.message !== payload) throw e;\n }\n break;\n }\n }\n }\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":"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","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/markets.ts","../src/commands/profile.ts","../src/commands/research.ts","../src/stream.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 { 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);\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\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, MarketBrief, GlobalOptions } 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(\"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","/**\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"],"mappings":"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","names":["program","chalk","program","chalk","program","readline","chalk","program","requireAuth","chalk","readline"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hedge-layer/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI for Hedge Layer —
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for Hedge Layer — prediction market intelligence from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"hl": "
|
|
7
|
+
"hl": "dist/index.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
@@ -21,16 +21,19 @@
|
|
|
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",
|
|
33
|
-
"url": "https://github.com/hedge-layer/hedge-layer-cli.git"
|
|
36
|
+
"url": "git+https://github.com/hedge-layer/hedge-layer-cli.git"
|
|
34
37
|
},
|
|
35
38
|
"dependencies": {
|
|
36
39
|
"chalk": "^5.4.1",
|
|
@@ -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
|
}
|