@hedge-layer/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hedge Layer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # @hedge-layer/cli
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@hedge-layer/cli)](https://www.npmjs.com/package/@hedge-layer/cli)
4
+ [![license](https://img.shields.io/github/license/hedge-layer/hedge-layer-cli)](LICENSE)
5
+
6
+ Command-line interface for [Hedge Layer](https://hedgelayer.ai) — hedge real-world risks on Polymarket prediction markets.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install -g @hedge-layer/cli
12
+ ```
13
+
14
+ Requires Node.js 22 or later.
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ # 1. Create an API token at https://hedgelayer.ai/settings → API Tokens
20
+ # 2. Authenticate the CLI
21
+ hl auth login
22
+
23
+ # 3. Search prediction markets
24
+ hl markets search "hurricane"
25
+
26
+ # 4. Start an interactive risk assessment
27
+ hl assess
28
+ ```
29
+
30
+ ## Authentication
31
+
32
+ The CLI uses API tokens created in the Hedge Layer web app. Tokens are stored locally in `~/.hedgelayer/config.json`.
33
+
34
+ ```bash
35
+ hl auth login # Paste your API token (interactive)
36
+ hl auth status # Check current authentication
37
+ hl auth logout # Remove stored token
38
+ ```
39
+
40
+ You can also pass a token inline for CI/scripts:
41
+
42
+ ```bash
43
+ hl --token hl_abc123... markets search "earthquake"
44
+ ```
45
+
46
+ ## Commands
47
+
48
+ ### Markets
49
+
50
+ Browse Polymarket prediction markets (no authentication required).
51
+
52
+ ```bash
53
+ # Search markets by keyword
54
+ hl markets search "wildfire"
55
+ hl markets search "hurricane" --limit 20
56
+
57
+ # View orderbook for a specific CLOB token
58
+ hl markets orderbook <tokenId>
59
+ hl markets orderbook <tokenId> --size 1000
60
+ ```
61
+
62
+ ### Assess
63
+
64
+ Run AI-powered risk assessments interactively.
65
+
66
+ ```bash
67
+ # Start an interactive chat assessment
68
+ hl assess
69
+
70
+ # List past assessments
71
+ hl assess list
72
+ hl assess list --status completed
73
+
74
+ # View a specific assessment
75
+ hl assess show <id>
76
+
77
+ # Delete an assessment
78
+ hl assess delete <id>
79
+ ```
80
+
81
+ ### Hedge
82
+
83
+ Calculate hedge positions from a risk profile JSON file.
84
+
85
+ ```bash
86
+ # From a file
87
+ hl hedge profile.json
88
+
89
+ # From stdin
90
+ echo '{
91
+ "location": "33109",
92
+ "assetType": "residential",
93
+ "riskTypes": ["hurricane", "flood"],
94
+ "assetValue": 500000
95
+ }' | hl hedge -
96
+ ```
97
+
98
+ ### Profile
99
+
100
+ ```bash
101
+ hl profile
102
+ ```
103
+
104
+ ## Global Options
105
+
106
+ | Flag | Description |
107
+ |------|-------------|
108
+ | `--json` | Machine-readable JSON output |
109
+ | `--api-url <url>` | Override API base URL (default: `https://hedgelayer.ai`) |
110
+ | `--token <token>` | Override stored API token |
111
+ | `--verbose` | Show HTTP request/response details |
112
+ | `--no-color` | Disable colored output |
113
+
114
+ ### JSON output
115
+
116
+ Every command supports `--json` for pipe-friendly output:
117
+
118
+ ```bash
119
+ hl --json markets search "flood" | jq '.markets[].question'
120
+ hl --json assess list | jq '.[0].id'
121
+ ```
122
+
123
+ ## Development
124
+
125
+ ```bash
126
+ git clone https://github.com/hedge-layer/hedge-layer-cli.git
127
+ cd hedge-layer-cli
128
+ npm install
129
+ npm run build # Build with tsup
130
+ npm run dev # Watch mode
131
+
132
+ # Test against local dev server
133
+ node dist/index.mjs --api-url http://localhost:3000 markets search "test"
134
+ ```
135
+
136
+ ## Publishing
137
+
138
+ Releases are automated via GitHub Actions. To publish a new version:
139
+
140
+ ```bash
141
+ npm version patch # or minor / major
142
+ git push --tags
143
+ ```
144
+
145
+ The workflow builds and publishes to npm when a version tag (`v*`) is pushed. Requires an `NPM_TOKEN` secret in the repo settings.
146
+
147
+ ## Changelog
148
+
149
+ See [CHANGELOG.md](CHANGELOG.md) for release history.
150
+
151
+ ## License
152
+
153
+ MIT
package/dist/index.mjs ADDED
@@ -0,0 +1,861 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/auth.ts
7
+ import readline from "readline/promises";
8
+
9
+ // src/config.ts
10
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from "fs";
11
+ import { join } from "path";
12
+ import { homedir } from "os";
13
+ var CONFIG_DIR = join(homedir(), ".hedgelayer");
14
+ var CONFIG_FILE = join(CONFIG_DIR, "config.json");
15
+ var DEFAULT_API_URL = "https://hedgelayer.ai";
16
+ function defaultConfig() {
17
+ return { api_url: DEFAULT_API_URL, token: null };
18
+ }
19
+ function loadConfig() {
20
+ try {
21
+ if (!existsSync(CONFIG_FILE)) return defaultConfig();
22
+ const raw = readFileSync(CONFIG_FILE, "utf-8");
23
+ const parsed = JSON.parse(raw);
24
+ return {
25
+ api_url: parsed.api_url ?? DEFAULT_API_URL,
26
+ token: parsed.token ?? null
27
+ };
28
+ } catch {
29
+ return defaultConfig();
30
+ }
31
+ }
32
+ function saveConfig(config) {
33
+ mkdirSync(CONFIG_DIR, { recursive: true });
34
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
35
+ }
36
+ function clearConfig() {
37
+ try {
38
+ if (existsSync(CONFIG_FILE)) unlinkSync(CONFIG_FILE);
39
+ } catch {
40
+ }
41
+ }
42
+ function configPath() {
43
+ return CONFIG_FILE;
44
+ }
45
+
46
+ // src/client.ts
47
+ var ApiClient = class {
48
+ baseUrl;
49
+ token;
50
+ verbose;
51
+ constructor(opts = {}) {
52
+ const config = loadConfig();
53
+ this.baseUrl = (opts.apiUrl ?? config.api_url ?? DEFAULT_API_URL).replace(/\/$/, "");
54
+ this.token = opts.token ?? config.token ?? null;
55
+ this.verbose = opts.verbose ?? false;
56
+ }
57
+ get isAuthenticated() {
58
+ return this.token !== null;
59
+ }
60
+ get apiUrl() {
61
+ return this.baseUrl;
62
+ }
63
+ headers(extra = {}) {
64
+ const h = {
65
+ "Content-Type": "application/json",
66
+ ...extra
67
+ };
68
+ if (this.token) {
69
+ h["Authorization"] = `Bearer ${this.token}`;
70
+ }
71
+ return h;
72
+ }
73
+ log(method, path, status) {
74
+ if (!this.verbose) return;
75
+ const statusStr = status ? ` \u2192 ${status}` : "";
76
+ process.stderr.write(`[verbose] ${method} ${this.baseUrl}${path}${statusStr}
77
+ `);
78
+ }
79
+ async get(path, params) {
80
+ const url = new URL(path, this.baseUrl);
81
+ if (params) {
82
+ for (const [k, v] of Object.entries(params)) {
83
+ if (v !== void 0 && v !== "") url.searchParams.set(k, v);
84
+ }
85
+ }
86
+ this.log("GET", `${url.pathname}${url.search}`);
87
+ const res = await fetch(url.toString(), { headers: this.headers() });
88
+ this.log("GET", `${url.pathname}${url.search}`, res.status);
89
+ if (!res.ok) {
90
+ const body = await res.text();
91
+ throw new ApiError(res.status, body);
92
+ }
93
+ return res.json();
94
+ }
95
+ async post(path, body) {
96
+ this.log("POST", path);
97
+ const res = await fetch(`${this.baseUrl}${path}`, {
98
+ method: "POST",
99
+ headers: this.headers(),
100
+ body: body !== void 0 ? JSON.stringify(body) : void 0
101
+ });
102
+ this.log("POST", path, res.status);
103
+ if (!res.ok) {
104
+ const text = await res.text();
105
+ throw new ApiError(res.status, text);
106
+ }
107
+ return res.json();
108
+ }
109
+ async patch(path, body) {
110
+ this.log("PATCH", path);
111
+ const res = await fetch(`${this.baseUrl}${path}`, {
112
+ method: "PATCH",
113
+ headers: this.headers(),
114
+ body: JSON.stringify(body)
115
+ });
116
+ this.log("PATCH", path, res.status);
117
+ if (!res.ok) {
118
+ const text = await res.text();
119
+ throw new ApiError(res.status, text);
120
+ }
121
+ return res.json();
122
+ }
123
+ async delete(path) {
124
+ this.log("DELETE", path);
125
+ const res = await fetch(`${this.baseUrl}${path}`, {
126
+ method: "DELETE",
127
+ headers: this.headers()
128
+ });
129
+ this.log("DELETE", path, res.status);
130
+ if (!res.ok) {
131
+ const text = await res.text();
132
+ throw new ApiError(res.status, text);
133
+ }
134
+ }
135
+ async stream(path, body) {
136
+ this.log("POST (stream)", path);
137
+ const res = await fetch(`${this.baseUrl}${path}`, {
138
+ method: "POST",
139
+ headers: this.headers({ Accept: "text/event-stream" }),
140
+ body: JSON.stringify(body)
141
+ });
142
+ this.log("POST (stream)", path, res.status);
143
+ if (!res.ok) {
144
+ const text = await res.text();
145
+ throw new ApiError(res.status, text);
146
+ }
147
+ if (!res.body) {
148
+ throw new ApiError(0, "No response body for stream");
149
+ }
150
+ return res.body;
151
+ }
152
+ };
153
+ var ApiError = class extends Error {
154
+ constructor(status, body) {
155
+ let msg;
156
+ try {
157
+ const parsed = JSON.parse(body);
158
+ msg = parsed.error ?? parsed.message ?? body;
159
+ } catch {
160
+ msg = body;
161
+ }
162
+ super(`API error ${status}: ${msg}`);
163
+ this.status = status;
164
+ this.body = body;
165
+ this.name = "ApiError";
166
+ }
167
+ };
168
+
169
+ // src/output.ts
170
+ import chalk from "chalk";
171
+ function json(data) {
172
+ process.stdout.write(JSON.stringify(data, null, 2) + "\n");
173
+ }
174
+ function table(rows, headers) {
175
+ const allRows = headers ? [headers, ...rows] : rows;
176
+ const colWidths = [];
177
+ for (const row of allRows) {
178
+ for (let i = 0; i < row.length; i++) {
179
+ colWidths[i] = Math.max(colWidths[i] ?? 0, stripAnsi(row[i]).length);
180
+ }
181
+ }
182
+ for (let r = 0; r < allRows.length; r++) {
183
+ const row = allRows[r];
184
+ const padded = row.map((cell, i) => {
185
+ const bare = stripAnsi(cell);
186
+ const pad = colWidths[i] - bare.length;
187
+ return cell + " ".repeat(Math.max(0, pad));
188
+ });
189
+ process.stdout.write(" " + padded.join(" ") + "\n");
190
+ if (r === 0 && headers) {
191
+ const sep = colWidths.map((w) => "\u2500".repeat(w)).join("\u2500\u2500");
192
+ process.stdout.write(" " + sep + "\n");
193
+ }
194
+ }
195
+ }
196
+ function stripAnsi(str) {
197
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
198
+ }
199
+ function heading(text) {
200
+ process.stdout.write("\n" + chalk.bold(text) + "\n\n");
201
+ }
202
+ function success(text) {
203
+ process.stdout.write(chalk.green("\u2713") + " " + text + "\n");
204
+ }
205
+ function warn(text) {
206
+ process.stdout.write(chalk.yellow("\u26A0") + " " + text + "\n");
207
+ }
208
+ function error(text) {
209
+ process.stderr.write(chalk.red("\u2717") + " " + text + "\n");
210
+ }
211
+ function dim(text) {
212
+ return chalk.dim(text);
213
+ }
214
+ function bold(text) {
215
+ return chalk.bold(text);
216
+ }
217
+ function currency(n) {
218
+ return "$" + n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
219
+ }
220
+ function percent(n) {
221
+ return (n * 100).toFixed(1) + "%";
222
+ }
223
+ function truncate(str, max) {
224
+ if (str.length <= max) return str;
225
+ return str.slice(0, max - 1) + "\u2026";
226
+ }
227
+ function relativeTime(date) {
228
+ const diff = Date.now() - new Date(date).getTime();
229
+ const mins = Math.floor(diff / 6e4);
230
+ if (mins < 1) return "just now";
231
+ if (mins < 60) return `${mins}m ago`;
232
+ const hours = Math.floor(mins / 60);
233
+ if (hours < 24) return `${hours}h ago`;
234
+ const days = Math.floor(hours / 24);
235
+ return `${days}d ago`;
236
+ }
237
+
238
+ // src/commands/auth.ts
239
+ function registerAuthCommands(program2) {
240
+ const auth = program2.command("auth").description("Manage API authentication");
241
+ auth.command("login").description("Authenticate with a Hedge Layer API token").option("--api-url <url>", "API base URL", DEFAULT_API_URL).action(async (cmdOpts) => {
242
+ const globalOpts = program2.opts();
243
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
244
+ try {
245
+ heading("Hedge Layer CLI \u2014 Login");
246
+ process.stderr.write(
247
+ `Create an API token at ${bold("https://hedgelayer.ai/settings")} \u2192 API Tokens
248
+
249
+ `
250
+ );
251
+ const token = (await rl.question("Paste your API token: ")).trim();
252
+ if (!token.startsWith("hl_") || token.length !== 43) {
253
+ error('Invalid token format. Tokens start with "hl_" and are 43 characters.');
254
+ process.exit(1);
255
+ }
256
+ const apiUrl = globalOpts.apiUrl ?? cmdOpts.apiUrl ?? DEFAULT_API_URL;
257
+ const client = new ApiClient({ token, apiUrl });
258
+ process.stderr.write("\nValidating token...");
259
+ let profile;
260
+ try {
261
+ profile = await client.get("/api/profile");
262
+ } catch {
263
+ process.stderr.write("\n");
264
+ error("Token validation failed. Check your token and try again.");
265
+ process.exit(1);
266
+ }
267
+ process.stderr.write(" done\n\n");
268
+ saveConfig({ api_url: apiUrl, token });
269
+ success(`Logged in as ${bold(profile.handle || profile.user_id)}`);
270
+ process.stderr.write(` Config saved to ${dim(configPath())}
271
+ `);
272
+ } finally {
273
+ rl.close();
274
+ }
275
+ });
276
+ auth.command("status").description("Show current authentication status").action(async () => {
277
+ const globalOpts = program2.opts();
278
+ const config = loadConfig();
279
+ const token = globalOpts.token ?? config.token;
280
+ if (!token) {
281
+ warn("Not logged in. Run " + bold("hl auth login") + " to authenticate.");
282
+ process.exit(1);
283
+ }
284
+ const client = new ApiClient(globalOpts);
285
+ try {
286
+ const profile = await client.get("/api/profile");
287
+ if (globalOpts.json) {
288
+ json({
289
+ authenticated: true,
290
+ handle: profile.handle,
291
+ user_id: profile.user_id,
292
+ api_url: client.apiUrl
293
+ });
294
+ } else {
295
+ heading("Auth Status");
296
+ table(
297
+ [
298
+ ["Handle", bold(profile.handle || "(none)")],
299
+ ["User ID", profile.user_id],
300
+ ["API URL", client.apiUrl],
301
+ ["Config", configPath()]
302
+ ]
303
+ );
304
+ }
305
+ } catch {
306
+ error("Token is invalid or expired. Run " + bold("hl auth login") + " to re-authenticate.");
307
+ process.exit(1);
308
+ }
309
+ });
310
+ auth.command("logout").description("Remove stored API token").action(() => {
311
+ clearConfig();
312
+ success("Logged out. Token removed from " + dim(configPath()));
313
+ });
314
+ }
315
+
316
+ // src/commands/markets.ts
317
+ import chalk2 from "chalk";
318
+ function registerMarketCommands(program2) {
319
+ const markets = program2.command("markets").description("Browse Polymarket prediction markets");
320
+ markets.command("search <query>").description("Search for markets by keyword").option("-l, --limit <n>", "Max results", "10").action(async (query, cmdOpts) => {
321
+ const globalOpts = program2.opts();
322
+ const client = new ApiClient(globalOpts);
323
+ const data = await client.get("/api/markets", {
324
+ q: query,
325
+ limit: cmdOpts.limit
326
+ });
327
+ if (globalOpts.json) {
328
+ json(data);
329
+ return;
330
+ }
331
+ if (data.markets.length === 0) {
332
+ warn(`No markets found for "${query}"`);
333
+ return;
334
+ }
335
+ heading(`Markets matching "${query}" (${data.total} total)`);
336
+ const rows = data.markets.map((m) => {
337
+ const prices = parseOutcomePrices(m.outcomePrices);
338
+ const yesPrice = prices ? percent(prices[0]) : "\u2014";
339
+ const vol = formatVolume(m.volume);
340
+ const end = m.endDate ? formatDate(m.endDate) : "\u2014";
341
+ const status = m.closed ? chalk2.red("closed") : chalk2.green("active");
342
+ return [truncate(m.question, 50), yesPrice, vol, end, status];
343
+ });
344
+ table(rows, ["Market", "YES", "Volume", "Ends", "Status"]);
345
+ });
346
+ markets.command("orderbook <tokenId>").description("Show orderbook spread and depth for a CLOB token").option("-s, --size <n>", "Size for slippage calculation").action(async (tokenId, cmdOpts) => {
347
+ const globalOpts = program2.opts();
348
+ const client = new ApiClient(globalOpts);
349
+ const params = { tokenId };
350
+ if (cmdOpts.size) params.size = cmdOpts.size;
351
+ const data = await client.get("/api/orderbook", params);
352
+ if (globalOpts.json) {
353
+ json(data);
354
+ return;
355
+ }
356
+ heading("Orderbook");
357
+ if (data.spread) {
358
+ table([
359
+ ["Best Bid", data.spread.bid.toFixed(4)],
360
+ ["Best Ask", data.spread.ask.toFixed(4)],
361
+ ["Spread", percent(data.spread.spread)],
362
+ ["Ask Depth", currency(data.askDepth)]
363
+ ]);
364
+ } else {
365
+ warn("No spread data available (empty orderbook)");
366
+ }
367
+ if (data.slippage) {
368
+ process.stdout.write("\n");
369
+ table([
370
+ ["Avg Fill Price", data.slippage.avgPrice.toFixed(4)],
371
+ ["Worst Price", data.slippage.worstPrice.toFixed(4)],
372
+ ["Slippage", percent(data.slippage.slippage)],
373
+ ["Fillable Size", currency(data.slippage.fillableSize)]
374
+ ]);
375
+ }
376
+ if (data.book.asks.length > 0) {
377
+ process.stdout.write("\n" + chalk2.dim(" Top 5 asks:") + "\n");
378
+ const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);
379
+ table(askRows, ["Price", "Size"]);
380
+ }
381
+ if (data.book.bids.length > 0) {
382
+ process.stdout.write("\n" + chalk2.dim(" Top 5 bids:") + "\n");
383
+ const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);
384
+ table(bidRows, ["Price", "Size"]);
385
+ }
386
+ });
387
+ }
388
+ function parseOutcomePrices(raw) {
389
+ try {
390
+ const parsed = JSON.parse(raw);
391
+ if (Array.isArray(parsed) && parsed.length === 2) {
392
+ return [Number(parsed[0]), Number(parsed[1])];
393
+ }
394
+ } catch {
395
+ }
396
+ return null;
397
+ }
398
+ function formatVolume(vol) {
399
+ const n = Number(vol);
400
+ if (isNaN(n)) return vol;
401
+ if (n >= 1e6) return `$${(n / 1e6).toFixed(1)}M`;
402
+ if (n >= 1e3) return `$${(n / 1e3).toFixed(1)}K`;
403
+ return `$${n.toFixed(0)}`;
404
+ }
405
+ function formatDate(iso) {
406
+ const d = new Date(iso);
407
+ return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
408
+ }
409
+
410
+ // src/commands/profile.ts
411
+ function registerProfileCommand(program2) {
412
+ program2.command("profile").description("Show your user profile").action(async () => {
413
+ const globalOpts = program2.opts();
414
+ const client = new ApiClient(globalOpts);
415
+ requireAuth(client);
416
+ const profile = await client.get("/api/profile");
417
+ if (globalOpts.json) {
418
+ json(profile);
419
+ return;
420
+ }
421
+ heading("Profile");
422
+ table([
423
+ ["Handle", bold(profile.handle || "(none)")],
424
+ ["User ID", profile.user_id],
425
+ ["Created", new Date(profile.created_at).toLocaleDateString()]
426
+ ]);
427
+ });
428
+ }
429
+ function requireAuth(client) {
430
+ if (!client.isAuthenticated) {
431
+ error("Not logged in. Run " + bold("hl auth login") + " first.");
432
+ process.exit(1);
433
+ }
434
+ }
435
+
436
+ // src/commands/assess.ts
437
+ import readline2 from "readline/promises";
438
+ import chalk3 from "chalk";
439
+
440
+ // src/stream.ts
441
+ async function parseStream(body, callbacks = {}) {
442
+ const decoder = new TextDecoder();
443
+ const reader = body.getReader();
444
+ let buffer = "";
445
+ let assistantText = "";
446
+ const toolCalls = [];
447
+ const activeToolCalls = /* @__PURE__ */ new Map();
448
+ let hedgeBundle = null;
449
+ while (true) {
450
+ const { done, value } = await reader.read();
451
+ if (done) break;
452
+ buffer += decoder.decode(value, { stream: true });
453
+ const lines = buffer.split("\n");
454
+ buffer = lines.pop() ?? "";
455
+ for (const line of lines) {
456
+ if (line.length < 2 || line[1] !== ":") continue;
457
+ const type = line[0];
458
+ const payload = line.slice(2);
459
+ switch (type) {
460
+ case "0": {
461
+ try {
462
+ const text = JSON.parse(payload);
463
+ assistantText += text;
464
+ callbacks.onText?.(text);
465
+ } catch {
466
+ }
467
+ break;
468
+ }
469
+ case "9": {
470
+ try {
471
+ const data = JSON.parse(payload);
472
+ activeToolCalls.set(data.toolCallId, { name: data.toolName, argStr: "" });
473
+ } catch {
474
+ }
475
+ break;
476
+ }
477
+ case "a": {
478
+ try {
479
+ const data = JSON.parse(payload);
480
+ const active = activeToolCalls.get(data.toolCallId);
481
+ if (active) active.argStr += data.argsTextDelta;
482
+ } catch {
483
+ }
484
+ break;
485
+ }
486
+ case "b": {
487
+ try {
488
+ const data = JSON.parse(payload);
489
+ const active = activeToolCalls.get(data.toolCallId);
490
+ if (active) {
491
+ let args = void 0;
492
+ try {
493
+ args = JSON.parse(active.argStr);
494
+ } catch {
495
+ args = active.argStr;
496
+ }
497
+ toolCalls.push({ name: active.name, args });
498
+ callbacks.onToolCall?.(active.name, args);
499
+ callbacks.onToolResult?.(active.name, data.result);
500
+ if (active.name === "buildHedgeBundle" && isHedgeBundle(data.result)) {
501
+ hedgeBundle = data.result;
502
+ }
503
+ activeToolCalls.delete(data.toolCallId);
504
+ }
505
+ } catch {
506
+ }
507
+ break;
508
+ }
509
+ case "d": {
510
+ try {
511
+ const finishData = JSON.parse(payload);
512
+ if (Array.isArray(finishData)) {
513
+ for (const item of finishData) {
514
+ if (item && typeof item === "object" && "positions" in item) {
515
+ hedgeBundle = item;
516
+ }
517
+ }
518
+ }
519
+ } catch {
520
+ }
521
+ break;
522
+ }
523
+ case "e": {
524
+ try {
525
+ const errData = JSON.parse(payload);
526
+ throw new Error(
527
+ typeof errData === "string" ? errData : JSON.stringify(errData)
528
+ );
529
+ } catch (e) {
530
+ if (e instanceof Error && e.message !== payload) throw e;
531
+ }
532
+ break;
533
+ }
534
+ }
535
+ }
536
+ }
537
+ return { assistantText, toolCalls, hedgeBundle };
538
+ }
539
+ function isHedgeBundle(val) {
540
+ return val !== null && typeof val === "object" && "positions" in val && "totalCost" in val;
541
+ }
542
+
543
+ // src/commands/assess.ts
544
+ function registerAssessCommands(program2) {
545
+ const assess = program2.command("assess").description("AI-powered risk assessment");
546
+ assess.command("start", { isDefault: true }).description("Start an interactive risk assessment chat").action(async () => {
547
+ const globalOpts = program2.opts();
548
+ const client = new ApiClient(globalOpts);
549
+ requireAuth2(client);
550
+ const { id } = await client.post("/api/assessments");
551
+ heading("Risk Assessment");
552
+ process.stderr.write(
553
+ chalk3.dim(" Describe the risks you want to hedge. Type /quit to exit.\n\n")
554
+ );
555
+ const messages = [];
556
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
557
+ try {
558
+ while (true) {
559
+ const userInput = await rl.question(chalk3.cyan("You: "));
560
+ if (!userInput.trim()) continue;
561
+ if (userInput.trim() === "/quit") break;
562
+ messages.push({ role: "user", content: userInput });
563
+ process.stderr.write(chalk3.dim("\nAssistant: "));
564
+ try {
565
+ const body = await client.stream("/api/chat", {
566
+ messages,
567
+ assessmentId: id
568
+ });
569
+ const result = await parseStream(body, {
570
+ onText: (text) => process.stderr.write(text),
571
+ onToolCall: (name, args) => {
572
+ process.stderr.write(chalk3.dim(`
573
+ [tool: ${name}]
574
+ `));
575
+ if (globalOpts.verbose) {
576
+ process.stderr.write(chalk3.dim(` ${JSON.stringify(args)}
577
+ `));
578
+ }
579
+ },
580
+ onToolResult: (name, result2) => {
581
+ if (globalOpts.verbose) {
582
+ process.stderr.write(chalk3.dim(` [result: ${name}] ${JSON.stringify(result2).slice(0, 200)}
583
+ `));
584
+ }
585
+ }
586
+ });
587
+ process.stderr.write("\n\n");
588
+ if (result.assistantText) {
589
+ messages.push({ role: "assistant", content: result.assistantText });
590
+ }
591
+ if (result.hedgeBundle) {
592
+ displayHedgeBundle(result.hedgeBundle, globalOpts);
593
+ break;
594
+ }
595
+ } catch (e) {
596
+ process.stderr.write("\n");
597
+ error(`Chat error: ${e instanceof Error ? e.message : String(e)}`);
598
+ }
599
+ }
600
+ } finally {
601
+ rl.close();
602
+ }
603
+ });
604
+ assess.command("list").description("List past assessments").option("-s, --status <status>", "Filter by status").action(async (cmdOpts) => {
605
+ const globalOpts = program2.opts();
606
+ const client = new ApiClient(globalOpts);
607
+ requireAuth2(client);
608
+ const params = { list: "true" };
609
+ if (cmdOpts.status) params.status = cmdOpts.status;
610
+ const data = await client.get("/api/assessments", params);
611
+ if (globalOpts.json) {
612
+ json(data.assessments);
613
+ return;
614
+ }
615
+ if (data.assessments.length === 0) {
616
+ warn("No assessments found.");
617
+ return;
618
+ }
619
+ heading(`Assessments (${data.assessments.length})`);
620
+ const rows = data.assessments.map((a) => {
621
+ const status = formatStatus(a.status);
622
+ const location = a.risk_profile?.location ?? "\u2014";
623
+ const cost = a.hedge_bundle ? currency(a.hedge_bundle.totalCost) : "\u2014";
624
+ return [a.id.slice(0, 8), status, location, cost, relativeTime(a.created_at)];
625
+ });
626
+ table(rows, ["ID", "Status", "Location", "Cost", "Created"]);
627
+ });
628
+ assess.command("show <id>").description("Show assessment details").action(async (id) => {
629
+ const globalOpts = program2.opts();
630
+ const client = new ApiClient(globalOpts);
631
+ requireAuth2(client);
632
+ const assessment = await client.get(`/api/assessments/${id}`);
633
+ if (globalOpts.json) {
634
+ json(assessment);
635
+ return;
636
+ }
637
+ heading("Assessment " + dim(assessment.id.slice(0, 8)));
638
+ table([
639
+ ["Status", formatStatus(assessment.status)],
640
+ ["Created", new Date(assessment.created_at).toLocaleString()],
641
+ ["Updated", new Date(assessment.updated_at).toLocaleString()]
642
+ ]);
643
+ if (assessment.risk_profile) {
644
+ const rp = assessment.risk_profile;
645
+ process.stdout.write("\n");
646
+ table([
647
+ ["Location", rp.location],
648
+ ["Asset Type", rp.assetType],
649
+ ["Asset Value", currency(rp.assetValue)],
650
+ ["Risk Types", rp.riskTypes.join(", ")]
651
+ ]);
652
+ }
653
+ if (assessment.hedge_bundle) {
654
+ displayHedgeBundle(assessment.hedge_bundle, globalOpts);
655
+ }
656
+ });
657
+ assess.command("delete <id>").description("Delete an assessment").action(async (id) => {
658
+ const globalOpts = program2.opts();
659
+ const client = new ApiClient(globalOpts);
660
+ requireAuth2(client);
661
+ await client.delete(`/api/assessments/${id}`);
662
+ success("Assessment deleted.");
663
+ });
664
+ }
665
+ function requireAuth2(client) {
666
+ if (!client.isAuthenticated) {
667
+ error("Not logged in. Run " + bold("hl auth login") + " first.");
668
+ process.exit(1);
669
+ }
670
+ }
671
+ function formatStatus(status) {
672
+ switch (status) {
673
+ case "completed":
674
+ return chalk3.green(status);
675
+ case "in_progress":
676
+ return chalk3.yellow(status);
677
+ case "abandoned":
678
+ return chalk3.red(status);
679
+ default:
680
+ return status;
681
+ }
682
+ }
683
+ function displayHedgeBundle(bundle, globalOpts) {
684
+ if (globalOpts.json) {
685
+ json(bundle);
686
+ return;
687
+ }
688
+ heading("Hedge Bundle");
689
+ table([
690
+ ["Asset Value", currency(bundle.assetValue)],
691
+ ["Total Cost", currency(bundle.totalCost)],
692
+ ["Total Coverage", currency(bundle.totalCoverage)],
693
+ ["Efficiency", percent(bundle.hedgeEfficiency)]
694
+ ]);
695
+ if (bundle.positions.length > 0) {
696
+ process.stdout.write("\n" + chalk3.bold(" Positions") + "\n\n");
697
+ const rows = bundle.positions.map((p) => {
698
+ const market = p.market?.question ?? "Unknown";
699
+ const cost = currency(Number(p.estimatedCost ?? 0));
700
+ const payout = currency(Number(p.potentialPayout ?? 0));
701
+ const price = Number(p.yesPrice ?? 0).toFixed(2);
702
+ const capped = p.wasCapped ? chalk3.yellow(" (capped)") : "";
703
+ return [truncate(market, 40), price, cost, payout + capped];
704
+ });
705
+ table(rows, ["Market", "YES", "Cost", "Payout"]);
706
+ }
707
+ }
708
+
709
+ // src/commands/hedge.ts
710
+ import { readFileSync as readFileSync2 } from "fs";
711
+ import chalk4 from "chalk";
712
+ function registerHedgeCommand(program2) {
713
+ program2.command("hedge [file]").description("Calculate hedge positions from a risk profile JSON").addHelpText(
714
+ "after",
715
+ `
716
+ Example risk profile JSON:
717
+ {
718
+ "location": "33109",
719
+ "assetType": "residential",
720
+ "riskTypes": ["hurricane", "flood"],
721
+ "assetValue": 500000
722
+ }
723
+
724
+ Usage:
725
+ hl hedge profile.json Read from file
726
+ echo '{"location":...}' | hl hedge - Read from stdin`
727
+ ).action(async (file) => {
728
+ const globalOpts = program2.opts();
729
+ const client = new ApiClient(globalOpts);
730
+ let raw;
731
+ if (!file || file === "-") {
732
+ raw = await readStdin();
733
+ } else {
734
+ try {
735
+ raw = readFileSync2(file, "utf-8");
736
+ } catch (e) {
737
+ error(`Cannot read file: ${file} \u2014 ${e instanceof Error ? e.message : e}`);
738
+ process.exit(1);
739
+ }
740
+ }
741
+ let profile;
742
+ try {
743
+ profile = JSON.parse(raw);
744
+ } catch {
745
+ error("Invalid JSON input. Expected a RiskProfile object.");
746
+ process.exit(1);
747
+ }
748
+ if (!profile.location || !profile.assetValue || !profile.riskTypes?.length) {
749
+ error("Risk profile must include location, assetValue, and at least one riskType.");
750
+ process.exit(1);
751
+ }
752
+ process.stderr.write(chalk4.dim("Searching markets and calculating hedge...\n"));
753
+ const messages = [
754
+ {
755
+ role: "user",
756
+ content: `I need to hedge a ${profile.assetType ?? "residential"} property worth $${profile.assetValue.toLocaleString()} in ${profile.location} against ${profile.riskTypes.join(", ")} risks. Please search for relevant markets and build a hedge bundle.`
757
+ }
758
+ ];
759
+ try {
760
+ const stream = await client.stream("/api/chat", { messages });
761
+ let bundleJson = null;
762
+ const decoder = new TextDecoder();
763
+ const reader = stream.getReader();
764
+ let buffer = "";
765
+ while (true) {
766
+ const { done, value } = await reader.read();
767
+ if (done) break;
768
+ buffer += decoder.decode(value, { stream: true });
769
+ const lines = buffer.split("\n");
770
+ buffer = lines.pop() ?? "";
771
+ for (const line of lines) {
772
+ if (!line.startsWith("d:")) continue;
773
+ try {
774
+ const parsed = JSON.parse(line.slice(2));
775
+ if (parsed && typeof parsed === "object" && "positions" in parsed) {
776
+ bundleJson = parsed;
777
+ }
778
+ } catch {
779
+ }
780
+ }
781
+ }
782
+ if (bundleJson) {
783
+ displayBundle(bundleJson, globalOpts);
784
+ } else {
785
+ warn("No hedge bundle was produced. Try the interactive assessment: hl assess");
786
+ }
787
+ } catch (e) {
788
+ error(`Hedge calculation failed: ${e instanceof Error ? e.message : String(e)}`);
789
+ process.exit(1);
790
+ }
791
+ });
792
+ }
793
+ function displayBundle(bundle, globalOpts) {
794
+ if (globalOpts.json) {
795
+ json(bundle);
796
+ return;
797
+ }
798
+ heading("Hedge Bundle");
799
+ table([
800
+ ["Asset Value", currency(bundle.assetValue)],
801
+ ["Total Cost", currency(bundle.totalCost)],
802
+ ["Total Coverage", currency(bundle.totalCoverage)],
803
+ ["Efficiency", percent(bundle.hedgeEfficiency)]
804
+ ]);
805
+ if (bundle.positions?.length > 0) {
806
+ process.stdout.write("\n" + chalk4.bold(" Positions") + "\n\n");
807
+ const rows = bundle.positions.map((p) => {
808
+ const market = p.market?.question ?? "Unknown";
809
+ const cost = currency(p.estimatedCost);
810
+ const payout = currency(p.potentialPayout);
811
+ const price = p.yesPrice.toFixed(2);
812
+ const capped = p.wasCapped ? chalk4.yellow(" (capped)") : "";
813
+ return [truncate(market, 40), price, cost, payout + capped];
814
+ });
815
+ table(rows, ["Market", "YES", "Cost", "Payout"]);
816
+ }
817
+ }
818
+ async function readStdin() {
819
+ const chunks = [];
820
+ for await (const chunk of process.stdin) {
821
+ chunks.push(chunk);
822
+ }
823
+ return Buffer.concat(chunks).toString("utf-8");
824
+ }
825
+
826
+ // src/index.ts
827
+ var program = new Command();
828
+ program.name("hl").description("Hedge Layer CLI \u2014 hedge real-world risks on Polymarket").version("0.1.0").option("--json", "Output as JSON (machine-readable)").option("--api-url <url>", "Override API base URL").option("--token <token>", "Override stored API token").option("--verbose", "Show HTTP request details").option("--no-color", "Disable colored output");
829
+ registerAuthCommands(program);
830
+ registerMarketCommands(program);
831
+ registerProfileCommand(program);
832
+ registerAssessCommands(program);
833
+ registerHedgeCommand(program);
834
+ program.hook("preAction", (_thisCommand, actionCommand) => {
835
+ const opts = program.opts();
836
+ if (opts.color === false) {
837
+ process.env.FORCE_COLOR = "0";
838
+ }
839
+ if (opts.verbose) {
840
+ const cmdName = actionCommand.name();
841
+ process.stderr.write(dim(`[verbose] Running: hl ${cmdName}
842
+ `));
843
+ }
844
+ });
845
+ async function main() {
846
+ try {
847
+ await program.parseAsync(process.argv);
848
+ } catch (e) {
849
+ if (e instanceof Error && e.message.includes("API error")) {
850
+ error(e.message);
851
+ } else {
852
+ error(`Unexpected error: ${e instanceof Error ? e.message : String(e)}`);
853
+ if (program.opts().verbose) {
854
+ console.error(e);
855
+ }
856
+ }
857
+ process.exit(1);
858
+ }
859
+ }
860
+ main();
861
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/client.ts","../src/output.ts","../src/commands/markets.ts","../src/commands/profile.ts","../src/commands/assess.ts","../src/stream.ts","../src/commands/hedge.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerMarketCommands } from \"./commands/markets.js\";\nimport { registerProfileCommand } from \"./commands/profile.js\";\nimport { registerAssessCommands } from \"./commands/assess.js\";\nimport { registerHedgeCommand } from \"./commands/hedge.js\";\nimport * as out from \"./output.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"hl\")\n .description(\"Hedge Layer CLI — hedge real-world risks on Polymarket\")\n .version(\"0.1.0\")\n .option(\"--json\", \"Output as JSON (machine-readable)\")\n .option(\"--api-url <url>\", \"Override API base URL\")\n .option(\"--token <token>\", \"Override stored API token\")\n .option(\"--verbose\", \"Show HTTP request details\")\n .option(\"--no-color\", \"Disable colored output\");\n\nregisterAuthCommands(program);\nregisterMarketCommands(program);\nregisterProfileCommand(program);\nregisterAssessCommands(program);\nregisterHedgeCommand(program);\n\nprogram.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const opts = program.opts();\n if (opts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n // Pass verbose state down for debugging\n if (opts.verbose) {\n const cmdName = actionCommand.name();\n process.stderr.write(out.dim(`[verbose] Running: hl ${cmdName}\\n`));\n }\n});\n\nasync function main() {\n try {\n await program.parseAsync(process.argv);\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"API error\")) {\n out.error(e.message);\n } else {\n out.error(`Unexpected error: ${e instanceof Error ? e.message : String(e)}`);\n if (program.opts().verbose) {\n console.error(e);\n }\n }\n process.exit(1);\n }\n}\n\nmain();\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport { loadConfig, saveConfig, clearConfig, configPath, DEFAULT_API_URL } from \"../config.js\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage API authentication\");\n\n auth\n .command(\"login\")\n .description(\"Authenticate with a Hedge Layer API token\")\n .option(\"--api-url <url>\", \"API base URL\", DEFAULT_API_URL)\n .action(async (cmdOpts: { apiUrl?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n try {\n out.heading(\"Hedge Layer CLI — Login\");\n process.stderr.write(\n `Create an API token at ${out.bold(\"https://hedgelayer.ai/settings\")} → API Tokens\\n\\n`,\n );\n\n const token = (await rl.question(\"Paste your API token: \")).trim();\n\n if (!token.startsWith(\"hl_\") || token.length !== 43) {\n out.error('Invalid token format. Tokens start with \"hl_\" and are 43 characters.');\n process.exit(1);\n }\n\n const apiUrl = globalOpts.apiUrl ?? cmdOpts.apiUrl ?? DEFAULT_API_URL;\n const client = new ApiClient({ token, apiUrl });\n\n process.stderr.write(\"\\nValidating token...\");\n let profile: UserProfile;\n try {\n profile = await client.get<UserProfile>(\"/api/profile\");\n } catch {\n process.stderr.write(\"\\n\");\n out.error(\"Token validation failed. Check your token and try again.\");\n process.exit(1);\n }\n process.stderr.write(\" done\\n\\n\");\n\n saveConfig({ api_url: apiUrl, token });\n\n out.success(`Logged in as ${out.bold(profile.handle || profile.user_id)}`);\n process.stderr.write(` Config saved to ${out.dim(configPath())}\\n`);\n } finally {\n rl.close();\n }\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const config = loadConfig();\n const token = globalOpts.token ?? config.token;\n\n if (!token) {\n out.warn(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" to authenticate.\");\n process.exit(1);\n }\n\n const client = new ApiClient(globalOpts);\n\n try {\n const profile = await client.get<UserProfile>(\"/api/profile\");\n if (globalOpts.json) {\n out.json({\n authenticated: true,\n handle: profile.handle,\n user_id: profile.user_id,\n api_url: client.apiUrl,\n });\n } else {\n out.heading(\"Auth Status\");\n out.table(\n [\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"API URL\", client.apiUrl],\n [\"Config\", configPath()],\n ],\n );\n }\n } catch {\n out.error(\"Token is invalid or expired. Run \" + out.bold(\"hl auth login\") + \" to re-authenticate.\");\n process.exit(1);\n }\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored API token\")\n .action(() => {\n clearConfig();\n out.success(\"Logged out. Token removed from \" + out.dim(configPath()));\n });\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst CONFIG_DIR = join(homedir(), \".hedgelayer\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport const DEFAULT_API_URL = \"https://hedgelayer.ai\";\n\nexport interface Config {\n api_url: string;\n token: string | null;\n}\n\nfunction defaultConfig(): Config {\n return { api_url: DEFAULT_API_URL, token: null };\n}\n\nexport function loadConfig(): Config {\n try {\n if (!existsSync(CONFIG_FILE)) return defaultConfig();\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n return {\n api_url: parsed.api_url ?? DEFAULT_API_URL,\n token: parsed.token ?? null,\n };\n } catch {\n return defaultConfig();\n }\n}\n\nexport function saveConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\nexport function clearConfig(): void {\n try {\n if (existsSync(CONFIG_FILE)) unlinkSync(CONFIG_FILE);\n } catch {\n // ignore\n }\n}\n\nexport function configPath(): string {\n return CONFIG_FILE;\n}\n","import type { GlobalOptions } from \"./types.js\";\nimport { loadConfig, DEFAULT_API_URL } from \"./config.js\";\n\nexport class ApiClient {\n private baseUrl: string;\n private token: string | null;\n private verbose: boolean;\n\n constructor(opts: GlobalOptions = {}) {\n const config = loadConfig();\n this.baseUrl = (opts.apiUrl ?? config.api_url ?? DEFAULT_API_URL).replace(/\\/$/, \"\");\n this.token = opts.token ?? config.token ?? null;\n this.verbose = opts.verbose ?? false;\n }\n\n get isAuthenticated(): boolean {\n return this.token !== null;\n }\n\n get apiUrl(): string {\n return this.baseUrl;\n }\n\n private headers(extra: Record<string, string> = {}): Record<string, string> {\n const h: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n if (this.token) {\n h[\"Authorization\"] = `Bearer ${this.token}`;\n }\n return h;\n }\n\n private log(method: string, path: string, status?: number): void {\n if (!this.verbose) return;\n const statusStr = status ? ` → ${status}` : \"\";\n process.stderr.write(`[verbose] ${method} ${this.baseUrl}${path}${statusStr}\\n`);\n }\n\n async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(path, this.baseUrl);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== \"\") url.searchParams.set(k, v);\n }\n }\n\n this.log(\"GET\", `${url.pathname}${url.search}`);\n const res = await fetch(url.toString(), { headers: this.headers() });\n this.log(\"GET\", `${url.pathname}${url.search}`, res.status);\n\n if (!res.ok) {\n const body = await res.text();\n throw new ApiError(res.status, body);\n }\n return res.json() as Promise<T>;\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n this.log(\"POST\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n this.log(\"POST\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n this.log(\"PATCH\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"PATCH\",\n headers: this.headers(),\n body: JSON.stringify(body),\n });\n this.log(\"PATCH\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n return res.json() as Promise<T>;\n }\n\n async delete(path: string): Promise<void> {\n this.log(\"DELETE\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"DELETE\",\n headers: this.headers(),\n });\n this.log(\"DELETE\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n }\n\n async stream(path: string, body: unknown): Promise<ReadableStream<Uint8Array>> {\n this.log(\"POST (stream)\", path);\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: this.headers({ Accept: \"text/event-stream\" }),\n body: JSON.stringify(body),\n });\n this.log(\"POST (stream)\", path, res.status);\n\n if (!res.ok) {\n const text = await res.text();\n throw new ApiError(res.status, text);\n }\n if (!res.body) {\n throw new ApiError(0, \"No response body for stream\");\n }\n return res.body;\n }\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public body: string,\n ) {\n let msg: string;\n try {\n const parsed = JSON.parse(body);\n msg = parsed.error ?? parsed.message ?? body;\n } catch {\n msg = body;\n }\n super(`API error ${status}: ${msg}`);\n this.name = \"ApiError\";\n }\n}\n","import chalk from \"chalk\";\n\nexport function json(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nexport function table(rows: string[][], headers?: string[]): void {\n const allRows = headers ? [headers, ...rows] : rows;\n const colWidths: number[] = [];\n for (const row of allRows) {\n for (let i = 0; i < row.length; i++) {\n colWidths[i] = Math.max(colWidths[i] ?? 0, stripAnsi(row[i]).length);\n }\n }\n\n for (let r = 0; r < allRows.length; r++) {\n const row = allRows[r];\n const padded = row.map((cell, i) => {\n const bare = stripAnsi(cell);\n const pad = colWidths[i] - bare.length;\n return cell + \" \".repeat(Math.max(0, pad));\n });\n process.stdout.write(\" \" + padded.join(\" \") + \"\\n\");\n\n if (r === 0 && headers) {\n const sep = colWidths.map((w) => \"─\".repeat(w)).join(\"──\");\n process.stdout.write(\" \" + sep + \"\\n\");\n }\n }\n}\n\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function heading(text: string): void {\n process.stdout.write(\"\\n\" + chalk.bold(text) + \"\\n\\n\");\n}\n\nexport function success(text: string): void {\n process.stdout.write(chalk.green(\"✓\") + \" \" + text + \"\\n\");\n}\n\nexport function warn(text: string): void {\n process.stdout.write(chalk.yellow(\"⚠\") + \" \" + text + \"\\n\");\n}\n\nexport function error(text: string): void {\n process.stderr.write(chalk.red(\"✗\") + \" \" + text + \"\\n\");\n}\n\nexport function dim(text: string): string {\n return chalk.dim(text);\n}\n\nexport function bold(text: string): string {\n return chalk.bold(text);\n}\n\nexport function currency(n: number): string {\n return \"$\" + n.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n}\n\nexport function percent(n: number): string {\n return (n * 100).toFixed(1) + \"%\";\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function relativeTime(date: string): string {\n const diff = Date.now() - new Date(date).getTime();\n const mins = Math.floor(diff / 60_000);\n if (mins < 1) return \"just now\";\n if (mins < 60) return `${mins}m ago`;\n const hours = Math.floor(mins / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport type { Market, Orderbook, SlippageResult, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerMarketCommands(program: Command): void {\n const markets = program.command(\"markets\").description(\"Browse Polymarket prediction markets\");\n\n markets\n .command(\"search <query>\")\n .description(\"Search for markets by keyword\")\n .option(\"-l, --limit <n>\", \"Max results\", \"10\")\n .action(async (query: string, cmdOpts: { limit: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n const data = await client.get<{ markets: Market[]; total: number }>(\"/api/markets\", {\n q: query,\n limit: cmdOpts.limit,\n });\n\n if (globalOpts.json) {\n out.json(data);\n return;\n }\n\n if (data.markets.length === 0) {\n out.warn(`No markets found for \"${query}\"`);\n return;\n }\n\n out.heading(`Markets matching \"${query}\" (${data.total} total)`);\n\n const rows = data.markets.map((m) => {\n const prices = parseOutcomePrices(m.outcomePrices);\n const yesPrice = prices ? out.percent(prices[0]) : \"—\";\n const vol = formatVolume(m.volume);\n const end = m.endDate ? formatDate(m.endDate) : \"—\";\n const status = m.closed ? chalk.red(\"closed\") : chalk.green(\"active\");\n return [out.truncate(m.question, 50), yesPrice, vol, end, status];\n });\n\n out.table(rows, [\"Market\", \"YES\", \"Volume\", \"Ends\", \"Status\"]);\n });\n\n markets\n .command(\"orderbook <tokenId>\")\n .description(\"Show orderbook spread and depth for a CLOB token\")\n .option(\"-s, --size <n>\", \"Size for slippage calculation\")\n .action(async (tokenId: string, cmdOpts: { size?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n const params: Record<string, string> = { tokenId };\n if (cmdOpts.size) params.size = cmdOpts.size;\n\n const data = await client.get<{\n book: Orderbook;\n spread: { bid: number; ask: number; spread: number } | null;\n askDepth: number;\n slippage: SlippageResult | null;\n }>(\"/api/orderbook\", params);\n\n if (globalOpts.json) {\n out.json(data);\n return;\n }\n\n out.heading(\"Orderbook\");\n\n if (data.spread) {\n out.table([\n [\"Best Bid\", data.spread.bid.toFixed(4)],\n [\"Best Ask\", data.spread.ask.toFixed(4)],\n [\"Spread\", out.percent(data.spread.spread)],\n [\"Ask Depth\", out.currency(data.askDepth)],\n ]);\n } else {\n out.warn(\"No spread data available (empty orderbook)\");\n }\n\n if (data.slippage) {\n process.stdout.write(\"\\n\");\n out.table([\n [\"Avg Fill Price\", data.slippage.avgPrice.toFixed(4)],\n [\"Worst Price\", data.slippage.worstPrice.toFixed(4)],\n [\"Slippage\", out.percent(data.slippage.slippage)],\n [\"Fillable Size\", out.currency(data.slippage.fillableSize)],\n ]);\n }\n\n if (data.book.asks.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 asks:\") + \"\\n\");\n const askRows = data.book.asks.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(askRows, [\"Price\", \"Size\"]);\n }\n\n if (data.book.bids.length > 0) {\n process.stdout.write(\"\\n\" + chalk.dim(\" Top 5 bids:\") + \"\\n\");\n const bidRows = data.book.bids.slice(0, 5).map((l) => [l.price, l.size]);\n out.table(bidRows, [\"Price\", \"Size\"]);\n }\n });\n}\n\nfunction parseOutcomePrices(raw: string): [number, number] | null {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed) && parsed.length === 2) {\n return [Number(parsed[0]), Number(parsed[1])];\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nfunction formatVolume(vol: string): string {\n const n = Number(vol);\n if (isNaN(n)) return vol;\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nfunction formatDate(iso: string): string {\n const d = new Date(iso);\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n}\n","import { Command } from \"commander\";\nimport { ApiClient } from \"../client.js\";\nimport type { UserProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerProfileCommand(program: Command): void {\n program\n .command(\"profile\")\n .description(\"Show your user profile\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const profile = await client.get<UserProfile>(\"/api/profile\");\n\n if (globalOpts.json) {\n out.json(profile);\n return;\n }\n\n out.heading(\"Profile\");\n out.table([\n [\"Handle\", out.bold(profile.handle || \"(none)\")],\n [\"User ID\", profile.user_id],\n [\"Created\", new Date(profile.created_at).toLocaleDateString()],\n ]);\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport readline from \"node:readline/promises\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport { parseStream } from \"../stream.js\";\nimport type { Assessment, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerAssessCommands(program: Command): void {\n const assess = program.command(\"assess\").description(\"AI-powered risk assessment\");\n\n assess\n .command(\"start\", { isDefault: true })\n .description(\"Start an interactive risk assessment chat\")\n .action(async () => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const { id } = await client.post<{ id: string }>(\"/api/assessments\");\n\n out.heading(\"Risk Assessment\");\n process.stderr.write(\n chalk.dim(\" Describe the risks you want to hedge. Type /quit to exit.\\n\\n\"),\n );\n\n const messages: { role: string; content: string }[] = [];\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr });\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const userInput = await rl.question(chalk.cyan(\"You: \"));\n if (!userInput.trim()) continue;\n if (userInput.trim() === \"/quit\") break;\n\n messages.push({ role: \"user\", content: userInput });\n\n process.stderr.write(chalk.dim(\"\\nAssistant: \"));\n\n try {\n const body = await client.stream(\"/api/chat\", {\n messages,\n assessmentId: id,\n });\n\n const result = await parseStream(body, {\n onText: (text) => process.stderr.write(text),\n onToolCall: (name, args) => {\n process.stderr.write(chalk.dim(`\\n [tool: ${name}]\\n`));\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` ${JSON.stringify(args)}\\n`));\n }\n },\n onToolResult: (name, result) => {\n if (globalOpts.verbose) {\n process.stderr.write(chalk.dim(` [result: ${name}] ${JSON.stringify(result).slice(0, 200)}\\n`));\n }\n },\n });\n\n process.stderr.write(\"\\n\\n\");\n\n if (result.assistantText) {\n messages.push({ role: \"assistant\", content: result.assistantText });\n }\n\n if (result.hedgeBundle) {\n displayHedgeBundle(result.hedgeBundle, globalOpts);\n break;\n }\n } catch (e) {\n process.stderr.write(\"\\n\");\n out.error(`Chat error: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n } finally {\n rl.close();\n }\n });\n\n assess\n .command(\"list\")\n .description(\"List past assessments\")\n .option(\"-s, --status <status>\", \"Filter by status\")\n .action(async (cmdOpts: { status?: string }) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const params: Record<string, string> = { list: \"true\" };\n if (cmdOpts.status) params.status = cmdOpts.status;\n\n const data = await client.get<{ assessments: Assessment[] }>(\"/api/assessments\", params);\n\n if (globalOpts.json) {\n out.json(data.assessments);\n return;\n }\n\n if (data.assessments.length === 0) {\n out.warn(\"No assessments found.\");\n return;\n }\n\n out.heading(`Assessments (${data.assessments.length})`);\n\n const rows = data.assessments.map((a) => {\n const status = formatStatus(a.status);\n const location = a.risk_profile?.location ?? \"—\";\n const cost = a.hedge_bundle ? out.currency(a.hedge_bundle.totalCost) : \"—\";\n return [a.id.slice(0, 8), status, location, cost, out.relativeTime(a.created_at)];\n });\n\n out.table(rows, [\"ID\", \"Status\", \"Location\", \"Cost\", \"Created\"]);\n });\n\n assess\n .command(\"show <id>\")\n .description(\"Show assessment details\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n const assessment = await client.get<Assessment>(`/api/assessments/${id}`);\n\n if (globalOpts.json) {\n out.json(assessment);\n return;\n }\n\n out.heading(\"Assessment \" + out.dim(assessment.id.slice(0, 8)));\n\n out.table([\n [\"Status\", formatStatus(assessment.status)],\n [\"Created\", new Date(assessment.created_at).toLocaleString()],\n [\"Updated\", new Date(assessment.updated_at).toLocaleString()],\n ]);\n\n if (assessment.risk_profile) {\n const rp = assessment.risk_profile;\n process.stdout.write(\"\\n\");\n out.table([\n [\"Location\", rp.location],\n [\"Asset Type\", rp.assetType],\n [\"Asset Value\", out.currency(rp.assetValue)],\n [\"Risk Types\", rp.riskTypes.join(\", \")],\n ]);\n }\n\n if (assessment.hedge_bundle) {\n displayHedgeBundle(assessment.hedge_bundle, globalOpts);\n }\n });\n\n assess\n .command(\"delete <id>\")\n .description(\"Delete an assessment\")\n .action(async (id: string) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n requireAuth(client);\n\n await client.delete(`/api/assessments/${id}`);\n out.success(\"Assessment deleted.\");\n });\n}\n\nfunction requireAuth(client: ApiClient): void {\n if (!client.isAuthenticated) {\n out.error(\"Not logged in. Run \" + out.bold(\"hl auth login\") + \" first.\");\n process.exit(1);\n }\n}\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case \"completed\":\n return chalk.green(status);\n case \"in_progress\":\n return chalk.yellow(status);\n case \"abandoned\":\n return chalk.red(status);\n default:\n return status;\n }\n}\n\nfunction displayHedgeBundle(\n bundle: { positions: Array<Record<string, unknown>>; totalCost: number; totalCoverage: number; hedgeEfficiency: number; assetValue: number },\n globalOpts: GlobalOptions,\n): void {\n if (globalOpts.json) {\n out.json(bundle);\n return;\n }\n\n out.heading(\"Hedge Bundle\");\n\n out.table([\n [\"Asset Value\", out.currency(bundle.assetValue)],\n [\"Total Cost\", out.currency(bundle.totalCost)],\n [\"Total Coverage\", out.currency(bundle.totalCoverage)],\n [\"Efficiency\", out.percent(bundle.hedgeEfficiency)],\n ]);\n\n if (bundle.positions.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Positions\") + \"\\n\\n\");\n const rows = bundle.positions.map((p) => {\n const market = (p.market as Record<string, string>)?.question ?? \"Unknown\";\n const cost = out.currency(Number(p.estimatedCost ?? 0));\n const payout = out.currency(Number(p.potentialPayout ?? 0));\n const price = Number(p.yesPrice ?? 0).toFixed(2);\n const capped = p.wasCapped ? chalk.yellow(\" (capped)\") : \"\";\n return [out.truncate(market, 40), price, cost, payout + capped];\n });\n out.table(rows, [\"Market\", \"YES\", \"Cost\", \"Payout\"]);\n }\n}\n","/**\n * Parses the Vercel AI SDK streaming response format.\n *\n * The AI SDK uses a line-based protocol where each line is prefixed with\n * a type code and colon. Key types:\n * 0: text delta (JSON-encoded string)\n * 9: tool call begin { toolCallId, toolName }\n * a: tool call delta (partial JSON args)\n * b: tool result { toolCallId, result }\n * d: finish message data (array)\n * e: error\n * f: message annotations\n */\n\nexport interface StreamCallbacks {\n onText?: (text: string) => void;\n onToolCall?: (name: string, args: unknown) => void;\n onToolResult?: (name: string, result: unknown) => void;\n}\n\nexport interface StreamResult {\n assistantText: string;\n toolCalls: Array<{ name: string; args: unknown }>;\n hedgeBundle: Record<string, unknown> | null;\n}\n\nexport async function parseStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks = {},\n): Promise<StreamResult> {\n const decoder = new TextDecoder();\n const reader = body.getReader();\n\n let buffer = \"\";\n let assistantText = \"\";\n const toolCalls: Array<{ name: string; args: unknown }> = [];\n const activeToolCalls = new Map<string, { name: string; argStr: string }>();\n let hedgeBundle: Record<string, unknown> | null = null;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.length < 2 || line[1] !== \":\") continue;\n\n const type = line[0];\n const payload = line.slice(2);\n\n switch (type) {\n case \"0\": {\n try {\n const text = JSON.parse(payload) as string;\n assistantText += text;\n callbacks.onText?.(text);\n } catch {\n // skip malformed text delta\n }\n break;\n }\n\n case \"9\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; toolName: string };\n activeToolCalls.set(data.toolCallId, { name: data.toolName, argStr: \"\" });\n } catch {\n // skip\n }\n break;\n }\n\n case \"a\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; argsTextDelta: string };\n const active = activeToolCalls.get(data.toolCallId);\n if (active) active.argStr += data.argsTextDelta;\n } catch {\n // skip\n }\n break;\n }\n\n case \"b\": {\n try {\n const data = JSON.parse(payload) as { toolCallId: string; result: unknown };\n const active = activeToolCalls.get(data.toolCallId);\n if (active) {\n let args: unknown = undefined;\n try {\n args = JSON.parse(active.argStr);\n } catch {\n args = active.argStr;\n }\n toolCalls.push({ name: active.name, args });\n callbacks.onToolCall?.(active.name, args);\n callbacks.onToolResult?.(active.name, data.result);\n\n if (active.name === \"buildHedgeBundle\" && isHedgeBundle(data.result)) {\n hedgeBundle = data.result as Record<string, unknown>;\n }\n activeToolCalls.delete(data.toolCallId);\n }\n } catch {\n // skip\n }\n break;\n }\n\n case \"d\": {\n try {\n const finishData = JSON.parse(payload);\n if (Array.isArray(finishData)) {\n for (const item of finishData) {\n if (item && typeof item === \"object\" && \"positions\" in item) {\n hedgeBundle = item as Record<string, unknown>;\n }\n }\n }\n } catch {\n // skip\n }\n break;\n }\n\n case \"e\": {\n try {\n const errData = JSON.parse(payload);\n throw new Error(\n typeof errData === \"string\" ? errData : JSON.stringify(errData),\n );\n } catch (e) {\n if (e instanceof Error && e.message !== payload) throw e;\n }\n break;\n }\n }\n }\n }\n\n return { assistantText, toolCalls, hedgeBundle };\n}\n\nfunction isHedgeBundle(val: unknown): boolean {\n return (\n val !== null &&\n typeof val === \"object\" &&\n \"positions\" in (val as Record<string, unknown>) &&\n \"totalCost\" in (val as Record<string, unknown>)\n );\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport chalk from \"chalk\";\nimport { ApiClient } from \"../client.js\";\nimport type { HedgeBundle, RiskProfile, GlobalOptions } from \"../types.js\";\nimport * as out from \"../output.js\";\n\nexport function registerHedgeCommand(program: Command): void {\n program\n .command(\"hedge [file]\")\n .description(\"Calculate hedge positions from a risk profile JSON\")\n .addHelpText(\n \"after\",\n `\nExample risk profile JSON:\n {\n \"location\": \"33109\",\n \"assetType\": \"residential\",\n \"riskTypes\": [\"hurricane\", \"flood\"],\n \"assetValue\": 500000\n }\n\nUsage:\n hl hedge profile.json Read from file\n echo '{\"location\":...}' | hl hedge - Read from stdin`,\n )\n .action(async (file: string | undefined) => {\n const globalOpts = program.opts<GlobalOptions>();\n const client = new ApiClient(globalOpts);\n\n let raw: string;\n if (!file || file === \"-\") {\n raw = await readStdin();\n } else {\n try {\n raw = readFileSync(file, \"utf-8\");\n } catch (e) {\n out.error(`Cannot read file: ${file} — ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n }\n }\n\n let profile: RiskProfile;\n try {\n profile = JSON.parse(raw);\n } catch {\n out.error(\"Invalid JSON input. Expected a RiskProfile object.\");\n process.exit(1);\n }\n\n if (!profile.location || !profile.assetValue || !profile.riskTypes?.length) {\n out.error(\"Risk profile must include location, assetValue, and at least one riskType.\");\n process.exit(1);\n }\n\n process.stderr.write(chalk.dim(\"Searching markets and calculating hedge...\\n\"));\n\n const messages = [\n {\n role: \"user\",\n content: `I need to hedge a ${profile.assetType ?? \"residential\"} property worth $${profile.assetValue.toLocaleString()} in ${profile.location} against ${profile.riskTypes.join(\", \")} risks. Please search for relevant markets and build a hedge bundle.`,\n },\n ];\n\n try {\n const stream = await client.stream(\"/api/chat\", { messages });\n let bundleJson: Record<string, unknown> | null = null;\n\n const decoder = new TextDecoder();\n const reader = stream.getReader();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"d:\")) continue;\n try {\n const parsed = JSON.parse(line.slice(2));\n if (parsed && typeof parsed === \"object\" && \"positions\" in parsed) {\n bundleJson = parsed as Record<string, unknown>;\n }\n } catch {\n // not JSON, skip\n }\n }\n }\n\n if (bundleJson) {\n displayBundle(bundleJson as unknown as HedgeBundle, globalOpts);\n } else {\n out.warn(\"No hedge bundle was produced. Try the interactive assessment: hl assess\");\n }\n } catch (e) {\n out.error(`Hedge calculation failed: ${e instanceof Error ? e.message : String(e)}`);\n process.exit(1);\n }\n });\n}\n\nfunction displayBundle(bundle: HedgeBundle, globalOpts: GlobalOptions): void {\n if (globalOpts.json) {\n out.json(bundle);\n return;\n }\n\n out.heading(\"Hedge Bundle\");\n\n out.table([\n [\"Asset Value\", out.currency(bundle.assetValue)],\n [\"Total Cost\", out.currency(bundle.totalCost)],\n [\"Total Coverage\", out.currency(bundle.totalCoverage)],\n [\"Efficiency\", out.percent(bundle.hedgeEfficiency)],\n ]);\n\n if (bundle.positions?.length > 0) {\n process.stdout.write(\"\\n\" + chalk.bold(\" Positions\") + \"\\n\\n\");\n const rows = bundle.positions.map((p) => {\n const market = p.market?.question ?? \"Unknown\";\n const cost = out.currency(p.estimatedCost);\n const payout = out.currency(p.potentialPayout);\n const price = p.yesPrice.toFixed(2);\n const capped = p.wasCapped ? chalk.yellow(\" (capped)\") : \"\";\n return [out.truncate(market, 40), price, cost, payout + capped];\n });\n out.table(rows, [\"Market\", \"YES\", \"Cost\", \"Payout\"]);\n }\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n return Buffer.concat(chunks).toString(\"utf-8\");\n}\n"],"mappings":"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","names":["program","chalk","program","chalk","program","readline","chalk","program","requireAuth","chalk","readline","result","readFileSync","chalk","program","readFileSync","chalk"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@hedge-layer/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Hedge Layer — hedge real-world risks on Polymarket",
5
+ "type": "module",
6
+ "bin": {
7
+ "hl": "./dist/index.mjs"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsup --watch",
15
+ "lint": "eslint src/",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "engines": {
21
+ "node": ">=22"
22
+ },
23
+ "keywords": [
24
+ "hedge",
25
+ "polymarket",
26
+ "prediction-markets",
27
+ "risk",
28
+ "cli"
29
+ ],
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/hedge-layer/hedge-layer-cli.git"
34
+ },
35
+ "dependencies": {
36
+ "chalk": "^5.4.1",
37
+ "commander": "^13.1.0",
38
+ "ora": "^8.2.0"
39
+ },
40
+ "devDependencies": {
41
+ "tsup": "^8.4.0",
42
+ "typescript": "^5.7.0",
43
+ "vitest": "^4.0.0"
44
+ }
45
+ }