@spfunctions/cli 1.4.5 → 1.5.1
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 +2 -0
- package/dist/client.js +11 -2
- package/dist/client.test.js +1 -1
- package/dist/commands/agent.js +370 -48
- package/dist/commands/book.d.ts +17 -0
- package/dist/commands/book.js +220 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.js +18 -7
- package/dist/commands/dashboard.js +30 -1
- package/dist/commands/liquidity.d.ts +2 -0
- package/dist/commands/liquidity.js +128 -43
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +4 -0
- package/dist/commands/positions.js +50 -0
- package/dist/commands/scan.d.ts +1 -0
- package/dist/commands/scan.js +66 -15
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +71 -6
- package/dist/config.d.ts +2 -0
- package/dist/config.js +8 -0
- package/dist/index.js +97 -11
- package/dist/polymarket.d.ts +237 -0
- package/dist/polymarket.js +353 -0
- package/dist/polymarket.test.d.ts +1 -0
- package/dist/polymarket.test.js +424 -0
- package/dist/telegram/agent-bridge.js +81 -8
- package/dist/topics.d.ts +3 -0
- package/dist/topics.js +65 -7
- package/dist/topics.test.js +83 -6
- package/dist/tui/dashboard.js +65 -30
- package/dist/tui/widgets/edges.js +5 -4
- package/dist/tui/widgets/portfolio.js +3 -2
- package/package.json +1 -1
package/dist/topics.test.js
CHANGED
|
@@ -7,21 +7,85 @@ const topics_js_1 = require("./topics.js");
|
|
|
7
7
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXWTIMAX-26DEC31-T135')).toBe('OIL');
|
|
8
8
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXWTID-something')).toBe('OIL');
|
|
9
9
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXWTIW-2026')).toBe('OIL');
|
|
10
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXWTI-26MAR24-T100')).toBe('OIL');
|
|
10
11
|
});
|
|
11
12
|
(0, vitest_1.it)('matches recession', () => {
|
|
12
13
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXRECSSNBER-26')).toBe('RECESSION');
|
|
13
14
|
});
|
|
14
15
|
(0, vitest_1.it)('matches fed', () => {
|
|
15
16
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXFEDDECISION-2026')).toBe('FED');
|
|
17
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXFED-something')).toBe('FED');
|
|
18
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXRATECUT-2026')).toBe('FED');
|
|
19
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXRATECUTCOUNT-2026')).toBe('FED');
|
|
16
20
|
});
|
|
17
21
|
(0, vitest_1.it)('matches cpi', () => {
|
|
18
22
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXCPI-26MAY-T0.4')).toBe('CPI');
|
|
23
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXCPIYOY-2026')).toBe('CPI');
|
|
19
24
|
});
|
|
20
25
|
(0, vitest_1.it)('matches gas', () => {
|
|
21
26
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXAAAGASM-26MAR31-4.40')).toBe('GAS');
|
|
27
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXAAAGASW-2026')).toBe('GAS');
|
|
22
28
|
});
|
|
23
29
|
(0, vitest_1.it)('matches sp500', () => {
|
|
24
30
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXINXY-26DEC31H1600-T4000')).toBe('SP500');
|
|
31
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXINXU-2026')).toBe('SP500');
|
|
32
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXINX-2026')).toBe('SP500');
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)('matches nasdaq', () => {
|
|
35
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXNASDAQ100-2026')).toBe('NASDAQ');
|
|
36
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXNASDAQ100U-2026')).toBe('NASDAQ');
|
|
37
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXNASDAQ100Y-2026')).toBe('NASDAQ');
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.it)('matches crypto', () => {
|
|
40
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXBTCD-2026')).toBe('CRYPTO');
|
|
41
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXBTC15M-2026')).toBe('CRYPTO');
|
|
42
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXBTCMAXY-2026')).toBe('CRYPTO');
|
|
43
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXETHD-2026')).toBe('CRYPTO');
|
|
44
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXETH15M-2026')).toBe('CRYPTO');
|
|
45
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXSOL15M-2026')).toBe('CRYPTO');
|
|
46
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXXRP15M-2026')).toBe('CRYPTO');
|
|
47
|
+
});
|
|
48
|
+
(0, vitest_1.it)('matches unemployment & jobs', () => {
|
|
49
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXU3-2026')).toBe('UNEMPLOYMENT');
|
|
50
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXPAYROLLS-2026')).toBe('UNEMPLOYMENT');
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.it)('matches gdp', () => {
|
|
53
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXGDP-Q1-2026')).toBe('GDP');
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.it)('matches geopolitics', () => {
|
|
56
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXCLOSEHORMUZ-2026')).toBe('GEOPOLITICS');
|
|
57
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXHORMUZTRAFFICW-26MAR')).toBe('GEOPOLITICS');
|
|
58
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXKHAMENEIOUT-2026')).toBe('GEOPOLITICS');
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.it)('matches elections', () => {
|
|
61
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('PRES-2028')).toBe('ELECTIONS');
|
|
62
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXFEDCHAIRNOM-2026')).toBe('ELECTIONS');
|
|
63
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTRUMPOUT-2026')).toBe('ELECTIONS');
|
|
64
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXNEXTPOPE-2026')).toBe('ELECTIONS');
|
|
65
|
+
});
|
|
66
|
+
(0, vitest_1.it)('matches politics', () => {
|
|
67
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXGOVSHUT-2026')).toBe('POLITICS');
|
|
68
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXGOVTSHUTDOWN-2026')).toBe('POLITICS');
|
|
69
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXGREENLAND-2026')).toBe('POLITICS');
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)('matches central banks', () => {
|
|
72
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXCBDECISIONJAPAN-2026')).toBe('CENTRALBANKS');
|
|
73
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXCBDECISIONEU-2026')).toBe('CENTRALBANKS');
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.it)('matches tariffs', () => {
|
|
76
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTARIFFRATEPRC-2026')).toBe('TARIFFS');
|
|
77
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTARIFFRATECA-2026')).toBe('TARIFFS');
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.it)('matches treasury', () => {
|
|
80
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTNOTEW-2026')).toBe('TREASURY');
|
|
81
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTNOTED-2026')).toBe('TREASURY');
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.it)('matches forex', () => {
|
|
84
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXUSDJPY-2026')).toBe('FOREX');
|
|
85
|
+
});
|
|
86
|
+
(0, vitest_1.it)('matches tech', () => {
|
|
87
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXLLM1-2026')).toBe('TECH');
|
|
88
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('KXTOPMODEL-2026')).toBe('TECH');
|
|
25
89
|
});
|
|
26
90
|
(0, vitest_1.it)('returns OTHER for unknown tickers', () => {
|
|
27
91
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('UNKNOWN-TICKER')).toBe('OTHER');
|
|
@@ -29,11 +93,20 @@ const topics_js_1 = require("./topics.js");
|
|
|
29
93
|
});
|
|
30
94
|
(0, vitest_1.it)('is case-insensitive', () => {
|
|
31
95
|
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('kxwtimax-lower')).toBe('OIL');
|
|
96
|
+
(0, vitest_1.expect)((0, topics_js_1.tickerToTopic)('kxbtcd-lower')).toBe('CRYPTO');
|
|
32
97
|
});
|
|
33
98
|
});
|
|
34
99
|
(0, vitest_1.describe)('TOPIC_SERIES', () => {
|
|
35
|
-
(0, vitest_1.it)('has expected topics', () => {
|
|
36
|
-
|
|
100
|
+
(0, vitest_1.it)('has all expected topics', () => {
|
|
101
|
+
const topics = Object.keys(topics_js_1.TOPIC_SERIES);
|
|
102
|
+
(0, vitest_1.expect)(topics).toEqual(vitest_1.expect.arrayContaining([
|
|
103
|
+
'oil', 'gas', 'fed', 'cpi', 'recession', 'sp500', 'nasdaq',
|
|
104
|
+
'crypto', 'unemployment', 'gdp', 'treasury', 'geopolitics',
|
|
105
|
+
'elections', 'politics', 'centralbanks', 'forex', 'tariffs', 'tech',
|
|
106
|
+
]));
|
|
107
|
+
});
|
|
108
|
+
(0, vitest_1.it)('has at least 18 topics', () => {
|
|
109
|
+
(0, vitest_1.expect)(Object.keys(topics_js_1.TOPIC_SERIES).length).toBeGreaterThanOrEqual(18);
|
|
37
110
|
});
|
|
38
111
|
(0, vitest_1.it)('each topic has at least one series', () => {
|
|
39
112
|
for (const [, series] of Object.entries(topics_js_1.TOPIC_SERIES)) {
|
|
@@ -42,13 +115,17 @@ const topics_js_1 = require("./topics.js");
|
|
|
42
115
|
});
|
|
43
116
|
});
|
|
44
117
|
(0, vitest_1.describe)('RISK_CATEGORIES', () => {
|
|
45
|
-
(0, vitest_1.it)('maps
|
|
118
|
+
(0, vitest_1.it)('maps oil series to Oil', () => {
|
|
46
119
|
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXWTIMAX']).toBe('Oil');
|
|
120
|
+
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXWTI']).toBe('Oil');
|
|
47
121
|
});
|
|
48
|
-
(0, vitest_1.it)('maps
|
|
49
|
-
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['
|
|
122
|
+
(0, vitest_1.it)('maps crypto series', () => {
|
|
123
|
+
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXBTCD']).toBe('Bitcoin');
|
|
124
|
+
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXETHD']).toBe('Ethereum');
|
|
50
125
|
});
|
|
51
|
-
(0, vitest_1.it)('maps
|
|
126
|
+
(0, vitest_1.it)('maps financial series', () => {
|
|
127
|
+
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXINXY']).toBe('S&P 500');
|
|
128
|
+
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXNASDAQ100']).toBe('Nasdaq');
|
|
52
129
|
(0, vitest_1.expect)(topics_js_1.RISK_CATEGORIES['KXFEDDECISION']).toBe('Fed Rate');
|
|
53
130
|
});
|
|
54
131
|
});
|
package/dist/tui/dashboard.js
CHANGED
|
@@ -17,6 +17,7 @@ const config_js_1 = require("../config.js");
|
|
|
17
17
|
const client_js_1 = require("../client.js");
|
|
18
18
|
const kalshi_js_1 = require("../kalshi.js");
|
|
19
19
|
const topics_js_1 = require("../topics.js");
|
|
20
|
+
const polymarket_js_1 = require("../polymarket.js");
|
|
20
21
|
// Widget renderers
|
|
21
22
|
const portfolio_js_1 = require("./widgets/portfolio.js");
|
|
22
23
|
const thesis_js_1 = require("./widgets/thesis.js");
|
|
@@ -78,6 +79,29 @@ async function loadAllData(state) {
|
|
|
78
79
|
}
|
|
79
80
|
state.positions = positions;
|
|
80
81
|
}
|
|
82
|
+
// Polymarket positions (merge into state.positions with venue tag)
|
|
83
|
+
const config = (0, config_js_1.loadConfig)();
|
|
84
|
+
if (config.polymarketWalletAddress) {
|
|
85
|
+
try {
|
|
86
|
+
const polyPos = await (0, cache_js_1.cached)('poly-positions', REFRESH_POSITIONS, () => (0, polymarket_js_1.polymarketGetPositions)(config.polymarketWalletAddress));
|
|
87
|
+
if (polyPos && Array.isArray(polyPos) && polyPos.length > 0) {
|
|
88
|
+
for (const p of polyPos) {
|
|
89
|
+
state.positions.push({
|
|
90
|
+
ticker: (p.title || p.slug || p.asset || '').slice(0, 25),
|
|
91
|
+
quantity: p.size || 0,
|
|
92
|
+
average_price_paid: Math.round((p.avgPrice || 0) * 100),
|
|
93
|
+
current_value: Math.round((p.curPrice || p.currentPrice || 0) * 100),
|
|
94
|
+
unrealized_pnl: Math.round((p.cashPnl || 0) * 100),
|
|
95
|
+
side: (p.outcome || 'yes').toLowerCase(),
|
|
96
|
+
venue: 'polymarket',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// skip
|
|
103
|
+
}
|
|
104
|
+
}
|
|
81
105
|
// Theses
|
|
82
106
|
if (thesesResult.status === 'fulfilled' && thesesResult.value) {
|
|
83
107
|
const raw = thesesResult.value;
|
|
@@ -585,39 +609,50 @@ async function loadLiquidityData(state) {
|
|
|
585
609
|
if (!seriesList)
|
|
586
610
|
return;
|
|
587
611
|
try {
|
|
588
|
-
//
|
|
612
|
+
// Phase 1: Fetch market lists in parallel (fast — just metadata)
|
|
613
|
+
const seriesResults = await Promise.allSettled(seriesList.map(series => (0, cache_js_1.cached)(`liq:${series}`, 30_000, async () => {
|
|
614
|
+
const url = `https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=${series}&status=open&limit=200`;
|
|
615
|
+
const res = await fetch(url, { headers: { Accept: 'application/json' } });
|
|
616
|
+
if (!res.ok)
|
|
617
|
+
return [];
|
|
618
|
+
const data = await res.json();
|
|
619
|
+
return data.markets || [];
|
|
620
|
+
})));
|
|
589
621
|
const allMarkets = [];
|
|
590
|
-
for (const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
622
|
+
for (const r of seriesResults) {
|
|
623
|
+
if (r.status === 'fulfilled' && Array.isArray(r.value)) {
|
|
624
|
+
allMarkets.push(...r.value);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
// Show markets immediately (before orderbooks load)
|
|
628
|
+
state.liquidityData.set(topic, [...allMarkets]);
|
|
629
|
+
// Phase 2: Fetch orderbooks in parallel batches of 8
|
|
630
|
+
const BATCH = 8;
|
|
631
|
+
for (let i = 0; i < allMarkets.length; i += BATCH) {
|
|
632
|
+
const batch = allMarkets.slice(i, i + BATCH);
|
|
633
|
+
const obResults = await Promise.allSettled(batch.map(mkt => (0, cache_js_1.cached)(`ob:${mkt.ticker}`, 30_000, () => (0, kalshi_js_1.getPublicOrderbook)(mkt.ticker))
|
|
634
|
+
.then(ob => ({ mkt, ob }))));
|
|
635
|
+
for (const r of obResults) {
|
|
636
|
+
if (r.status !== 'fulfilled' || !r.value.ob)
|
|
637
|
+
continue;
|
|
638
|
+
const { mkt, ob } = r.value;
|
|
639
|
+
const yes = (ob.yes_dollars || []).map((l) => ({
|
|
640
|
+
price: Math.round(parseFloat(l[0]) * 100),
|
|
641
|
+
qty: parseFloat(l[1]),
|
|
642
|
+
})).filter((l) => l.price > 0).sort((a, b) => b.price - a.price);
|
|
643
|
+
const no = (ob.no_dollars || []).map((l) => ({
|
|
644
|
+
price: Math.round(parseFloat(l[0]) * 100),
|
|
645
|
+
qty: parseFloat(l[1]),
|
|
646
|
+
})).filter((l) => l.price > 0).sort((a, b) => b.price - a.price);
|
|
647
|
+
mkt.bestBid = yes.length > 0 ? yes[0].price : 0;
|
|
648
|
+
mkt.bestAsk = no.length > 0 ? (100 - no[0].price) : 100;
|
|
649
|
+
mkt.spread = mkt.bestAsk - mkt.bestBid;
|
|
650
|
+
mkt.totalDepth = yes.slice(0, 3).reduce((s, l) => s + l.qty, 0)
|
|
651
|
+
+ no.slice(0, 3).reduce((s, l) => s + l.qty, 0);
|
|
618
652
|
}
|
|
653
|
+
// Progressive update: refresh display after each batch
|
|
654
|
+
state.liquidityData.set(topic, [...allMarkets]);
|
|
619
655
|
}
|
|
620
|
-
state.liquidityData.set(topic, allMarkets);
|
|
621
656
|
}
|
|
622
657
|
catch (err) {
|
|
623
658
|
state.error = 'Failed to load liquidity data';
|
|
@@ -25,9 +25,10 @@ function renderEdges(screen, region, state) {
|
|
|
25
25
|
const edgeStr = `+${edgeVal.toFixed(1)}¢`;
|
|
26
26
|
const liq = e.orderbook?.liquidityScore || '?';
|
|
27
27
|
const liqColor = liq === 'high' ? border_js_1.CLR.green : liq === 'low' ? border_js_1.CLR.yellow : border_js_1.CLR.dim;
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
screen.write(y, x
|
|
31
|
-
screen.write(y, x + nameWidth +
|
|
28
|
+
const venueTag = e.venue === 'polymarket' ? 'P ' : 'K ';
|
|
29
|
+
const nameWidth = Math.max(w - 20, 10);
|
|
30
|
+
screen.write(y, x, `${marker}${venueTag}${(0, border_js_1.fit)(name, nameWidth)}`, selected ? border_js_1.CLR.white : border_js_1.CLR.text);
|
|
31
|
+
screen.write(y, x + nameWidth + 3, (0, border_js_1.fit)(edgeStr, 8, 'right'), border_js_1.CLR.emerald);
|
|
32
|
+
screen.write(y, x + nameWidth + 12, (0, border_js_1.fit)(liq, 5, 'right'), liqColor);
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -26,8 +26,9 @@ function renderPortfolio(screen, region, state) {
|
|
|
26
26
|
const selected = state.focusArea === 'positions' && state.selectedIndex === idx;
|
|
27
27
|
const marker = selected ? '▸' : ' ';
|
|
28
28
|
const ticker = pos.ticker || '???';
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const venueTag = pos.venue === 'polymarket' ? 'P ' : 'K ';
|
|
30
|
+
// Line 1: marker + venue + ticker
|
|
31
|
+
screen.write(y, x, (0, border_js_1.fit)(`${marker}${venueTag}${ticker}`, w), selected ? border_js_1.CLR.white : border_js_1.CLR.text);
|
|
31
32
|
// Line 2: qty @ entry → current P&L sparkline
|
|
32
33
|
if (line + 1 < maxRows) {
|
|
33
34
|
const qty = pos.quantity ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spfunctions/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Prediction market intelligence CLI. Causal thesis model, 24/7 Kalshi/Polymarket scan, live orderbook, edge detection. Interactive agent mode with tool calling.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sf": "./dist/index.js"
|