@hedge-layer/cli 1.1.0 → 1.2.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 +0 -34
- package/dist/index.mjs +108 -89
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -94,16 +94,6 @@ hl research delete <id>
|
|
|
94
94
|
|
|
95
95
|
For non-interactive, single-shot brief generation, use `hl brief` — it uses a dedicated API endpoint optimized for programmatic use.
|
|
96
96
|
|
|
97
|
-
### Markets
|
|
98
|
-
|
|
99
|
-
Polymarket orderbook tools.
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
# View orderbook for a specific CLOB token
|
|
103
|
-
hl markets orderbook <tokenId>
|
|
104
|
-
hl markets orderbook <tokenId> --size 1000
|
|
105
|
-
```
|
|
106
|
-
|
|
107
97
|
### Profile
|
|
108
98
|
|
|
109
99
|
```bash
|
|
@@ -128,30 +118,6 @@ Every command supports `--json` for pipe-friendly output:
|
|
|
128
118
|
hl --json research list | jq '.[0].id'
|
|
129
119
|
```
|
|
130
120
|
|
|
131
|
-
## Development
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
git clone https://github.com/hedge-layer/hedge-layer-cli.git
|
|
135
|
-
cd hedge-layer-cli
|
|
136
|
-
npm install
|
|
137
|
-
npm run build # Build with tsup
|
|
138
|
-
npm run dev # Watch mode
|
|
139
|
-
|
|
140
|
-
# Test against local dev server
|
|
141
|
-
node dist/index.mjs --api-url http://localhost:3000 research list
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Publishing
|
|
145
|
-
|
|
146
|
-
Releases are automated via GitHub Actions. To publish a new version:
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
npm version patch # or minor / major
|
|
150
|
-
git push --tags
|
|
151
|
-
```
|
|
152
|
-
|
|
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.
|
|
154
|
-
|
|
155
121
|
## Changelog
|
|
156
122
|
|
|
157
123
|
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
package/dist/index.mjs
CHANGED
|
@@ -234,6 +234,12 @@ function bold(text) {
|
|
|
234
234
|
function currency(n) {
|
|
235
235
|
return "$" + n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
236
236
|
}
|
|
237
|
+
function compactCurrency(n) {
|
|
238
|
+
if (!n || isNaN(n)) return "$0";
|
|
239
|
+
if (n >= 1e6) return `$${(n / 1e6).toFixed(1)}M`;
|
|
240
|
+
if (n >= 1e3) return `$${(n / 1e3).toFixed(1)}K`;
|
|
241
|
+
return `$${n.toFixed(0)}`;
|
|
242
|
+
}
|
|
237
243
|
function percent(n) {
|
|
238
244
|
return (n * 100).toFixed(1) + "%";
|
|
239
245
|
}
|
|
@@ -342,6 +348,7 @@ async function parseStream(body, callbacks = {}) {
|
|
|
342
348
|
const toolCalls = [];
|
|
343
349
|
const activeToolCalls = /* @__PURE__ */ new Map();
|
|
344
350
|
let marketBrief = null;
|
|
351
|
+
let feedResult = null;
|
|
345
352
|
while (true) {
|
|
346
353
|
const { done, value } = await reader.read();
|
|
347
354
|
if (!done) {
|
|
@@ -405,6 +412,9 @@ async function parseStream(body, callbacks = {}) {
|
|
|
405
412
|
if (active.name === "buildMarketBrief" && isMarketBrief(msg.output)) {
|
|
406
413
|
marketBrief = msg.output;
|
|
407
414
|
}
|
|
415
|
+
if (active.name === "getFeed" && isFeedResult(msg.output)) {
|
|
416
|
+
feedResult = msg.output;
|
|
417
|
+
}
|
|
408
418
|
activeToolCalls.delete(id);
|
|
409
419
|
}
|
|
410
420
|
break;
|
|
@@ -416,11 +426,14 @@ async function parseStream(body, callbacks = {}) {
|
|
|
416
426
|
}
|
|
417
427
|
if (done) break;
|
|
418
428
|
}
|
|
419
|
-
return { assistantText, toolCalls, marketBrief };
|
|
429
|
+
return { assistantText, toolCalls, marketBrief, feedResult };
|
|
420
430
|
}
|
|
421
431
|
function isMarketBrief(val) {
|
|
422
432
|
return val !== null && typeof val === "object" && "title" in val && "markets" in val;
|
|
423
433
|
}
|
|
434
|
+
function isFeedResult(val) {
|
|
435
|
+
return val !== null && typeof val === "object" && "markets" in val && "sortedBy" in val;
|
|
436
|
+
}
|
|
424
437
|
async function parseNdjsonStream(body, callbacks = {}) {
|
|
425
438
|
const decoder = new TextDecoder();
|
|
426
439
|
const reader = body.getReader();
|
|
@@ -469,7 +482,7 @@ async function parseNdjsonStream(body, callbacks = {}) {
|
|
|
469
482
|
|
|
470
483
|
// src/commands/brief.ts
|
|
471
484
|
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).
|
|
485
|
+
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).action(async (query, cmdOpts) => {
|
|
473
486
|
const globalOpts = program2.opts();
|
|
474
487
|
const client = new ApiClient(globalOpts);
|
|
475
488
|
requireAuth(client);
|
|
@@ -479,13 +492,9 @@ function registerBriefCommands(program2) {
|
|
|
479
492
|
...cmdOpts.location && { location: cmdOpts.location },
|
|
480
493
|
...cmdOpts.timeHorizon && { timeHorizon: cmdOpts.timeHorizon },
|
|
481
494
|
...filters && { filters },
|
|
482
|
-
stream:
|
|
495
|
+
stream: true
|
|
483
496
|
};
|
|
484
|
-
|
|
485
|
-
await runStreaming(client, body, globalOpts);
|
|
486
|
-
} else {
|
|
487
|
-
await runBlocking(client, body, globalOpts);
|
|
488
|
-
}
|
|
497
|
+
await runStreaming(client, body, globalOpts);
|
|
489
498
|
});
|
|
490
499
|
}
|
|
491
500
|
function buildFilters(opts) {
|
|
@@ -522,17 +531,6 @@ async function runStreaming(client, body, globalOpts) {
|
|
|
522
531
|
`));
|
|
523
532
|
displayBrief(result.brief, globalOpts);
|
|
524
533
|
}
|
|
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
534
|
function displayBrief(brief, globalOpts) {
|
|
537
535
|
if (globalOpts.json) {
|
|
538
536
|
json(brief);
|
|
@@ -573,53 +571,6 @@ function requireAuth(client) {
|
|
|
573
571
|
}
|
|
574
572
|
}
|
|
575
573
|
|
|
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
574
|
// src/commands/profile.ts
|
|
624
575
|
function registerProfileCommand(program2) {
|
|
625
576
|
program2.command("profile").description("Show your user profile").action(async () => {
|
|
@@ -648,7 +599,7 @@ function requireAuth2(client) {
|
|
|
648
599
|
|
|
649
600
|
// src/commands/research.ts
|
|
650
601
|
import readline2 from "readline/promises";
|
|
651
|
-
import
|
|
602
|
+
import chalk3 from "chalk";
|
|
652
603
|
function registerResearchCommands(program2) {
|
|
653
604
|
const research = program2.command("research").description("AI-powered market research");
|
|
654
605
|
research.command("start", { isDefault: true }).description("Start an interactive market research session").action(async () => {
|
|
@@ -658,7 +609,7 @@ function registerResearchCommands(program2) {
|
|
|
658
609
|
const { id } = await client.post("/api/assessments");
|
|
659
610
|
heading("Market Research");
|
|
660
611
|
process.stderr.write(
|
|
661
|
-
|
|
612
|
+
chalk3.dim(" Describe a topic or thesis to explore. Type /quit to exit.\n\n")
|
|
662
613
|
);
|
|
663
614
|
let msgCounter = 0;
|
|
664
615
|
const uiMsg = (role, content) => ({
|
|
@@ -671,11 +622,11 @@ function registerResearchCommands(program2) {
|
|
|
671
622
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
672
623
|
try {
|
|
673
624
|
while (true) {
|
|
674
|
-
const userInput = await rl.question(
|
|
625
|
+
const userInput = await rl.question(chalk3.cyan("You: "));
|
|
675
626
|
if (!userInput.trim()) continue;
|
|
676
627
|
if (userInput.trim() === "/quit") break;
|
|
677
628
|
messages.push(uiMsg("user", userInput));
|
|
678
|
-
process.stderr.write(
|
|
629
|
+
process.stderr.write(chalk3.dim("\nAssistant: "));
|
|
679
630
|
try {
|
|
680
631
|
const body = await client.stream("/api/chat", {
|
|
681
632
|
messages,
|
|
@@ -684,13 +635,13 @@ function registerResearchCommands(program2) {
|
|
|
684
635
|
const result = await parseStream(body, {
|
|
685
636
|
onText: (text) => process.stderr.write(text),
|
|
686
637
|
onToolCall: (name) => {
|
|
687
|
-
process.stderr.write(
|
|
638
|
+
process.stderr.write(chalk3.dim(`
|
|
688
639
|
[tool: ${name}]
|
|
689
640
|
`));
|
|
690
641
|
},
|
|
691
642
|
onToolResult: (name, toolResult) => {
|
|
692
643
|
if (globalOpts.verbose) {
|
|
693
|
-
process.stderr.write(
|
|
644
|
+
process.stderr.write(chalk3.dim(` [result: ${name}] ${JSON.stringify(toolResult).slice(0, 200)}
|
|
694
645
|
`));
|
|
695
646
|
}
|
|
696
647
|
}
|
|
@@ -699,6 +650,9 @@ function registerResearchCommands(program2) {
|
|
|
699
650
|
if (result.assistantText) {
|
|
700
651
|
messages.push(uiMsg("assistant", result.assistantText));
|
|
701
652
|
}
|
|
653
|
+
if (result.feedResult) {
|
|
654
|
+
displayFeedResult(result.feedResult, globalOpts);
|
|
655
|
+
}
|
|
702
656
|
if (result.marketBrief) {
|
|
703
657
|
displayMarketBrief(result.marketBrief, globalOpts);
|
|
704
658
|
break;
|
|
@@ -716,18 +670,18 @@ function registerResearchCommands(program2) {
|
|
|
716
670
|
const globalOpts = program2.opts();
|
|
717
671
|
const client = new ApiClient(globalOpts);
|
|
718
672
|
requireAuth3(client);
|
|
719
|
-
process.stderr.write(
|
|
673
|
+
process.stderr.write(chalk3.dim(` Researching "${truncate(query, 60)}"...
|
|
720
674
|
`));
|
|
721
675
|
const startTime = Date.now();
|
|
722
676
|
const result = await client.post("/api/research", { query });
|
|
723
677
|
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
724
|
-
process.stderr.write(
|
|
678
|
+
process.stderr.write(chalk3.dim(` Done (${elapsed}s)
|
|
725
679
|
|
|
726
680
|
`));
|
|
727
681
|
if (result.brief) {
|
|
728
682
|
json(result.brief);
|
|
729
683
|
} else {
|
|
730
|
-
process.stderr.write(
|
|
684
|
+
process.stderr.write(chalk3.yellow("No market brief was produced.\n"));
|
|
731
685
|
json(result);
|
|
732
686
|
}
|
|
733
687
|
});
|
|
@@ -791,25 +745,91 @@ function requireAuth3(client) {
|
|
|
791
745
|
function formatStatus(status) {
|
|
792
746
|
switch (status) {
|
|
793
747
|
case "completed":
|
|
794
|
-
return
|
|
748
|
+
return chalk3.green(status);
|
|
795
749
|
case "in_progress":
|
|
796
|
-
return
|
|
750
|
+
return chalk3.yellow(status);
|
|
797
751
|
case "abandoned":
|
|
798
|
-
return
|
|
752
|
+
return chalk3.red(status);
|
|
799
753
|
default:
|
|
800
754
|
return status;
|
|
801
755
|
}
|
|
802
756
|
}
|
|
757
|
+
var SORT_LABELS = {
|
|
758
|
+
score: "attention score",
|
|
759
|
+
volume: "24h volume",
|
|
760
|
+
liquidity: "liquidity",
|
|
761
|
+
movement: "price movement",
|
|
762
|
+
spread: "spread tightness",
|
|
763
|
+
recency: "recency",
|
|
764
|
+
extremity: "uncertainty",
|
|
765
|
+
rewards: "rewards"
|
|
766
|
+
};
|
|
767
|
+
function displayFeedResult(feed, globalOpts) {
|
|
768
|
+
if (globalOpts.json) {
|
|
769
|
+
json(feed);
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const sortLabel = SORT_LABELS[feed.sortedBy] ?? feed.sortedBy;
|
|
773
|
+
heading(`Market Feed \u2014 ${feed.marketsReturned} markets by ${sortLabel}`);
|
|
774
|
+
process.stdout.write(
|
|
775
|
+
chalk3.dim(` ${feed.totalScanned.toLocaleString()} scanned \xB7 ${feed.totalAfterFilter.toLocaleString()} after filters
|
|
776
|
+
|
|
777
|
+
`)
|
|
778
|
+
);
|
|
779
|
+
if (feed.markets.length === 0) {
|
|
780
|
+
warn("No markets matched the criteria.");
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
const rows = feed.markets.map((m) => {
|
|
784
|
+
const prob = percent(m.yesPrice);
|
|
785
|
+
const change = m.oneDayPriceChange;
|
|
786
|
+
const changeStr = change > 0 ? chalk3.green(`+${(change * 100).toFixed(1)}%`) : change < 0 ? chalk3.red(`${(change * 100).toFixed(1)}%`) : chalk3.dim("0.0%");
|
|
787
|
+
return [
|
|
788
|
+
String(m.rank),
|
|
789
|
+
truncate(m.question, 42),
|
|
790
|
+
prob,
|
|
791
|
+
String(Math.round(m.score)),
|
|
792
|
+
compactCurrency(m.volume24h),
|
|
793
|
+
compactCurrency(m.liquidity),
|
|
794
|
+
changeStr
|
|
795
|
+
];
|
|
796
|
+
});
|
|
797
|
+
table(rows, ["#", "Market", "Prob", "Score", "24h Vol", "Liq", "Chg"]);
|
|
798
|
+
process.stdout.write("\n");
|
|
799
|
+
for (const m of feed.markets.slice(0, 5)) {
|
|
800
|
+
const url = m.polymarketUrl;
|
|
801
|
+
process.stdout.write(" " + chalk3.dim("\u25B8 ") + truncate(m.question, 55) + "\n");
|
|
802
|
+
process.stdout.write(" " + chalk3.dim("Score: ") + scoreBar(m.score) + " ");
|
|
803
|
+
process.stdout.write(chalk3.dim("Spread: ") + m.spread.toFixed(3) + " ");
|
|
804
|
+
if (m.rewardsDailyRate > 0) {
|
|
805
|
+
process.stdout.write(chalk3.dim("Rewards: ") + `$${m.rewardsDailyRate.toFixed(2)}/day`);
|
|
806
|
+
}
|
|
807
|
+
process.stdout.write("\n");
|
|
808
|
+
process.stdout.write(" " + chalk3.dim("Polymarket: ") + url + "\n");
|
|
809
|
+
}
|
|
810
|
+
if (feed.markets.length > 5) {
|
|
811
|
+
process.stdout.write(chalk3.dim(`
|
|
812
|
+
\u2026 and ${feed.markets.length - 5} more
|
|
813
|
+
`));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
function scoreBar(score) {
|
|
817
|
+
const width = 15;
|
|
818
|
+
const filled = Math.round(score / 100 * width);
|
|
819
|
+
const empty = width - filled;
|
|
820
|
+
const color = score >= 70 ? chalk3.green : score >= 45 ? chalk3.yellow : chalk3.dim;
|
|
821
|
+
return color("\u2588".repeat(filled)) + chalk3.dim("\u2591".repeat(empty)) + ` ${Math.round(score)}`;
|
|
822
|
+
}
|
|
803
823
|
function displayMarketBrief(brief, globalOpts) {
|
|
804
824
|
if (globalOpts.json) {
|
|
805
825
|
json(brief);
|
|
806
826
|
return;
|
|
807
827
|
}
|
|
808
828
|
heading("Market Brief");
|
|
809
|
-
process.stdout.write(" " +
|
|
810
|
-
process.stdout.write(" " +
|
|
829
|
+
process.stdout.write(" " + chalk3.bold(brief.title) + "\n\n");
|
|
830
|
+
process.stdout.write(" " + chalk3.italic(brief.thesis) + "\n");
|
|
811
831
|
if (brief.markets.length > 0) {
|
|
812
|
-
process.stdout.write("\n" +
|
|
832
|
+
process.stdout.write("\n" + chalk3.bold(" Markets") + "\n\n");
|
|
813
833
|
const rows = brief.markets.map((m) => {
|
|
814
834
|
const prob = percent(m.yesPrice);
|
|
815
835
|
const signals = m.signals.length > 0 ? m.signals.join(", ") : "\u2014";
|
|
@@ -819,26 +839,25 @@ function displayMarketBrief(brief, globalOpts) {
|
|
|
819
839
|
table(rows, ["Market", "Prob", "Signals", "Liq"]);
|
|
820
840
|
process.stdout.write("\n");
|
|
821
841
|
for (const m of brief.markets) {
|
|
822
|
-
process.stdout.write(" " +
|
|
823
|
-
process.stdout.write(" " +
|
|
824
|
-
process.stdout.write(" " +
|
|
842
|
+
process.stdout.write(" " + chalk3.dim("\u25B8 ") + truncate(m.question, 50) + "\n");
|
|
843
|
+
process.stdout.write(" " + chalk3.dim("Causal link: ") + m.causalLink + "\n");
|
|
844
|
+
process.stdout.write(" " + chalk3.dim("Polymarket: ") + m.polymarketUrl + "\n");
|
|
825
845
|
}
|
|
826
846
|
}
|
|
827
847
|
if (brief.gaps.length > 0) {
|
|
828
|
-
process.stdout.write("\n" +
|
|
848
|
+
process.stdout.write("\n" + chalk3.bold(" Coverage Gaps") + "\n\n");
|
|
829
849
|
for (const gap of brief.gaps) {
|
|
830
|
-
process.stdout.write(" " +
|
|
850
|
+
process.stdout.write(" " + chalk3.yellow("\u25B8") + " " + gap + "\n");
|
|
831
851
|
}
|
|
832
852
|
}
|
|
833
|
-
process.stdout.write("\n " +
|
|
853
|
+
process.stdout.write("\n " + chalk3.dim(`${brief.marketCount} markets \xB7 ${brief.gaps.length} coverage gaps`) + "\n");
|
|
834
854
|
}
|
|
835
855
|
|
|
836
856
|
// src/index.ts
|
|
837
857
|
var program = new Command();
|
|
838
|
-
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.
|
|
858
|
+
program.name("hl").description("Hedge Layer CLI \u2014 prediction market intelligence from the terminal").version("1.2.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");
|
|
839
859
|
registerAuthCommands(program);
|
|
840
860
|
registerBriefCommands(program);
|
|
841
|
-
registerMarketCommands(program);
|
|
842
861
|
registerProfileCommand(program);
|
|
843
862
|
registerResearchCommands(program);
|
|
844
863
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/client.ts","../src/output.ts","../src/commands/brief.ts","../src/stream.ts","../src/commands/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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/client.ts","../src/output.ts","../src/commands/brief.ts","../src/stream.ts","../src/commands/profile.ts","../src/commands/research.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerBriefCommands } from \"./commands/brief.js\";\n\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerResearchCommands } from \"./commands/research.js\";\nimport * as out from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"hl\")\n .description(\"Hedge Layer CLI — prediction market intelligence from the terminal\")\n .version(__VERSION__)\n .option(\"--json\", \"Output as JSON (machine-readable)\")\n .option(\"--api-url <url>\", \"Override API base URL\")\n .option(\"--token <token>\", \"Override stored API token\")\n .option(\"--verbose\", \"Show HTTP request details\")\n .option(\"--no-color\", \"Disable colored output\");\n\nregisterAuthCommands(program);\nregisterBriefCommands(program);\n\nregisterProfileCommand(program);\nregisterResearchCommands(program);\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 compactCurrency(n: number): string {\n if (!n || isNaN(n)) return \"$0\";\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nexport function percent(n: number): string {\n return (n * 100).toFixed(1) + \"%\";\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function relativeTime(date: string): string {\n const diff = Date.now() - new Date(date).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseNdjsonStream } from \"../stream.js\";\nimport type { MarketBrief, BriefRequest, BriefRequestFilters, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerBriefCommands(program: Command): void {\n program\n .command(\"brief <query>\")\n .description(\"Generate a Market Brief for a topic (non-interactive)\")\n .option(\"-l, --location <location>\", \"Geographic context (e.g. 'Middle East', 'US')\")\n .option(\"-t, --time-horizon <horizon>\", \"Time frame (e.g. '3 months', '2026')\")\n .option(\"--tags <tags>\", \"Comma-separated focus area tags (e.g. 'geopolitics,energy')\")\n .option(\"--min-volume <n>\", \"Minimum market volume in USD\", parseFloat)\n .option(\"--max-yes-price <n>\", \"Maximum YES price (0-1)\", parseFloat)\n .action(async (query: string, cmdOpts: BriefCmdOpts) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const filters = buildFilters(cmdOpts);\n const body: BriefRequest = {\n query,\n ...(cmdOpts.location && { location: cmdOpts.location }),\n ...(cmdOpts.timeHorizon && { timeHorizon: cmdOpts.timeHorizon }),\n ...(filters && { filters }),\n stream: true,\n };\n\n await runStreaming(client, body, globalOpts);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Command option types\n// ---------------------------------------------------------------------------\n\ninterface BriefCmdOpts {\n location?: string;\n timeHorizon?: string;\n tags?: string;\n minVolume?: number;\n maxYesPrice?: number;\n}\n\nfunction buildFilters(opts: BriefCmdOpts): BriefRequestFilters | undefined {\n const tags = opts.tags?.split(\",\").map((t) => t.trim()).filter(Boolean);\n const hasFilters = opts.minVolume != null || opts.maxYesPrice != null || (tags && tags.length > 0);\n if (!hasFilters) return undefined;\n return {\n ...(opts.minVolume != null && { minVolume: opts.minVolume }),\n ...(opts.maxYesPrice != null && { maxYesPrice: opts.maxYesPrice }),\n ...(tags && tags.length > 0 && { tags }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Streaming mode (default)\n// ---------------------------------------------------------------------------\n\nasync function runStreaming(client: ApiClient, body: BriefRequest, globalOpts: GlobalOptions): Promise<void> {\n const startTime = Date.now();\n process.stderr.write(chalk.dim(` Generating brief for \"${out.truncate(body.query, 50)}\"...\\n`));\n\n const stream = await client.streamNdjson(\"/api/brief\", body);\n const result = await parseNdjsonStream(stream, {\n onProgress: (step, message) => {\n process.stderr.write(chalk.dim(` [${step}] `) + message + \"\\n\");\n },\n });\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n if (result.error) {\n out.error(`Brief failed (${result.error.code}): ${result.error.message}`);\n process.exit(1);\n }\n\n if (!result.brief) {\n out.error(\"No Market Brief was produced.\");\n process.exit(1);\n }\n\n process.stderr.write(chalk.dim(` Done (${elapsed}s)\\n\\n`));\n displayBrief(result.brief as unknown as MarketBrief, globalOpts);\n}\n\n// ---------------------------------------------------------------------------\n// Display\n// ---------------------------------------------------------------------------\n\nfunction displayBrief(brief: MarketBrief, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(brief);\n return;\n }\n\n out.heading(\"Market Brief\");\n\n process.stdout.write(\" \" + chalk.bold(brief.title) + \"\\n\\n\");\n process.stdout.write(\" \" + chalk.italic(brief.thesis) + \"\\n\");\n\n if (brief.markets.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Markets\") + \"\\n\\n\");\n const rows = brief.markets.map((m) => {\n const prob = out.percent(m.yesPrice);\n const signals = m.signals.length > 0 ? m.signals.join(\", \") : \"—\";\n const liq = m.liquidity ? out.currency(m.liquidity) : \"—\";\n return [out.truncate(m.question, 40), prob, signals, liq];\n });\n out.table(rows, [\"Market\", \"Prob\", \"Signals\", \"Liq\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of brief.markets) {\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 50) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Causal link: \") + m.causalLink + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + m.polymarketUrl + \"\\n\");\n }\n }\n\n if (brief.gaps.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Coverage Gaps\") + \"\\n\\n\");\n for (const gap of brief.gaps) {\n process.stdout.write(\" \" + chalk.yellow(\"▸\") + \" \" + gap + \"\\n\");\n }\n }\n\n const marketCount = brief.marketCount ?? brief.markets.length;\n process.stdout.write(\"\\n \" + chalk.dim(`${marketCount} markets · ${brief.gaps.length} coverage gaps`) + \"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","/**\n * Parses the Vercel AI SDK UI Message Stream protocol (SSE format).\n *\n * The server sends Server-Sent Events where each `data:` line contains\n * a JSON object with a `type` field:\n * text-delta: { type, id, delta }\n * tool-input-start: { type, toolCallId, toolName }\n * tool-input-delta: { type, toolCallId, inputTextDelta }\n * tool-input-available: { type, toolCallId, toolName, input }\n * tool-output-available:{ type, toolCallId, output }\n * error: { type, errorText }\n * [DONE]: stream termination sentinel\n */\n\nexport interface StreamCallbacks {\n onText?: (text: string) => void;\n onToolCall?: (name: string, args: unknown) => void;\n onToolResult?: (name: string, result: unknown) => void;\n}\n\nexport interface StreamResult {\n assistantText: string;\n toolCalls: Array<{ name: string; args: unknown }>;\n marketBrief: Record<string, unknown> | null;\n feedResult: Record<string, unknown> | null;\n}\n\nexport async function parseStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks = {},\n): Promise<StreamResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let assistantText = \"\";\n const toolCalls: Array<{ name: string; args: unknown }> = [];\n const activeToolCalls = new Map<string, { name: string; argStr: string }>();\n let marketBrief: Record<string, unknown> | null = null;\n let feedResult: Record<string, unknown> | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\":\")) continue;\n\n if (!trimmed.startsWith(\"data:\")) continue;\n const payload = trimmed.slice(5).trim();\n\n if (payload === \"[DONE]\") continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(payload);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"text-delta\": {\n const delta = msg.delta as string;\n if (delta) {\n assistantText += delta;\n callbacks.onText?.(delta);\n }\n break;\n }\n\n case \"tool-input-start\": {\n const id = msg.toolCallId as string;\n const name = msg.toolName as string;\n if (id && name) {\n activeToolCalls.set(id, { name, argStr: \"\" });\n }\n break;\n }\n\n case \"tool-input-delta\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n active.argStr += msg.inputTextDelta as string;\n }\n break;\n }\n\n case \"tool-input-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n const args = msg.input ?? active.argStr;\n toolCalls.push({ name: active.name, args });\n callbacks.onToolCall?.(active.name, args);\n }\n break;\n }\n\n case \"tool-output-available\": {\n const id = msg.toolCallId as string;\n const active = activeToolCalls.get(id);\n if (active) {\n callbacks.onToolResult?.(active.name, msg.output);\n if (active.name === \"buildMarketBrief\" && isMarketBrief(msg.output)) {\n marketBrief = msg.output as Record<string, unknown>;\n }\n if (active.name === \"getFeed\" && isFeedResult(msg.output)) {\n feedResult = msg.output as Record<string, unknown>;\n }\n activeToolCalls.delete(id);\n }\n break;\n }\n\n case \"error\": {\n throw new Error((msg.errorText as string) ?? \"Unknown stream error\");\n }\n }\n }\n\n if (done) break;\n }\n\n return { assistantText, toolCalls, marketBrief, feedResult };\n}\n\nfunction isMarketBrief(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"title\" in (val as Record<string, unknown>) &&\n \"markets\" in (val as Record<string, unknown>)\n );\n}\n\nfunction isFeedResult(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"markets\" in (val as Record<string, unknown>) &&\n \"sortedBy\" in (val as Record<string, unknown>)\n );\n}\n\n// ---------------------------------------------------------------------------\n// NDJSON stream parser (for POST /api/brief)\n// ---------------------------------------------------------------------------\n\nexport interface NdjsonCallbacks {\n onProgress?: (step: string, message: string) => void;\n}\n\nexport interface NdjsonBriefResult {\n brief: Record<string, unknown> | null;\n error: { code: string; message: string } | null;\n}\n\n/**\n * Parses an NDJSON stream from the /api/brief endpoint.\n *\n * Each line is a JSON object with a `type` field:\n * progress: { type, step, message }\n * brief: { type, data: MarketBrief }\n * error: { type, code, message }\n */\nexport async function parseNdjsonStream(\n body: ReadableStream<Uint8Array>,\n callbacks: NdjsonCallbacks = {},\n): Promise<NdjsonBriefResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let brief: Record<string, unknown> | null = null;\n let error: { code: string; message: string } | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (!done) {\n buffer += decoder.decode(value, { stream: true });\n }\n\n const lines = buffer.split(\"\\n\");\n buffer = done ? \"\" : (lines.pop() ?? \"\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n const type = msg.type as string;\n\n switch (type) {\n case \"progress\": {\n callbacks.onProgress?.(msg.step as string, msg.message as string);\n break;\n }\n case \"brief\": {\n brief = msg.data as Record<string, unknown>;\n break;\n }\n case \"error\": {\n error = {\n code: msg.code as string,\n message: msg.message as string,\n };\n break;\n }\n }\n }\n\n if (done) break;\n }\n\n return { brief, error };\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerProfileCommand(program: Command): void {\n program\n .command(\"profile\")\n .description(\"Show your user profile\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const profile = await client.get<UserProfile>(\"/api/profile\");\n\n if (globalOpts.json) {\n out.json(profile);\n return;\n }\n\n out.heading(\"Profile\");\n out.table([\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"Created\", new Date(profile.created_at).toLocaleDateString()],\n ]);\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseStream } from \"../stream.js\";\nimport type { Assessment, MarketBrief, FeedResult, FeedResultMarket, 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 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.feedResult) {\n displayFeedResult(result.feedResult as unknown as FeedResult, globalOpts);\n }\n\n if (result.marketBrief) {\n displayMarketBrief(result.marketBrief as unknown as MarketBrief, globalOpts);\n break;\n }\n } catch (e) {\n process.stderr.write(\"\\n\");\n out.error(`Chat error: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n } finally {\n rl.close();\n }\n });\n\n research\n .command(\"run <query>\")\n .description(\"Run research on a topic and return the final 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\nconst SORT_LABELS: Record<string, string> = {\n score: \"attention score\",\n volume: \"24h volume\",\n liquidity: \"liquidity\",\n movement: \"price movement\",\n spread: \"spread tightness\",\n recency: \"recency\",\n extremity: \"uncertainty\",\n rewards: \"rewards\",\n};\n\nfunction displayFeedResult(feed: FeedResult, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(feed);\n return;\n }\n\n const sortLabel = SORT_LABELS[feed.sortedBy] ?? feed.sortedBy;\n out.heading(`Market Feed — ${feed.marketsReturned} markets by ${sortLabel}`);\n process.stdout.write(\n chalk.dim(` ${feed.totalScanned.toLocaleString()} scanned · ${feed.totalAfterFilter.toLocaleString()} after filters\\n\\n`),\n );\n\n if (feed.markets.length === 0) {\n out.warn(\"No markets matched the criteria.\");\n return;\n }\n\n const rows = feed.markets.map((m: FeedResultMarket) => {\n const prob = out.percent(m.yesPrice);\n const change = m.oneDayPriceChange;\n const changeStr = change > 0\n ? chalk.green(`+${(change * 100).toFixed(1)}%`)\n : change < 0\n ? chalk.red(`${(change * 100).toFixed(1)}%`)\n : chalk.dim(\"0.0%\");\n return [\n String(m.rank),\n out.truncate(m.question, 42),\n prob,\n String(Math.round(m.score)),\n out.compactCurrency(m.volume24h),\n out.compactCurrency(m.liquidity),\n changeStr,\n ];\n });\n\n out.table(rows, [\"#\", \"Market\", \"Prob\", \"Score\", \"24h Vol\", \"Liq\", \"Chg\"]);\n\n process.stdout.write(\"\\n\");\n for (const m of feed.markets.slice(0, 5)) {\n const url = m.polymarketUrl;\n process.stdout.write(\" \" + chalk.dim(\"▸ \") + out.truncate(m.question, 55) + \"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Score: \") + scoreBar(m.score) + \" \");\n process.stdout.write(chalk.dim(\"Spread: \") + m.spread.toFixed(3) + \" \");\n if (m.rewardsDailyRate > 0) {\n process.stdout.write(chalk.dim(\"Rewards: \") + `$${m.rewardsDailyRate.toFixed(2)}/day`);\n }\n process.stdout.write(\"\\n\");\n process.stdout.write(\" \" + chalk.dim(\"Polymarket: \") + url + \"\\n\");\n }\n\n if (feed.markets.length > 5) {\n process.stdout.write(chalk.dim(`\\n … and ${feed.markets.length - 5} more\\n`));\n }\n}\n\nfunction scoreBar(score: number): string {\n const width = 15;\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 70 ? chalk.green : score >= 45 ? chalk.yellow : chalk.dim;\n return color(\"█\".repeat(filled)) + chalk.dim(\"░\".repeat(empty)) + ` ${Math.round(score)}`;\n}\n\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","program","requireAuth","readline","chalk","program","requireAuth","chalk","readline"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hedge-layer/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "CLI for Hedge Layer — prediction market intelligence from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@eslint/js": "^10.0.1",
|
|
45
|
+
"@types/node": "^25.5.2",
|
|
45
46
|
"eslint": "^10.0.3",
|
|
46
47
|
"tsup": "^8.4.0",
|
|
47
48
|
"typescript": "^5.7.0",
|