@spfunctions/cli 1.7.19 → 1.7.22

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.
Files changed (180) hide show
  1. package/dist/101.index.js +1 -0
  2. package/dist/12.index.js +1 -0
  3. package/dist/160.index.js +1 -0
  4. package/dist/174.index.js +1 -0
  5. package/dist/278.index.js +6 -0
  6. package/dist/582.index.js +1 -0
  7. package/dist/641.index.js +324 -0
  8. package/dist/669.index.js +1 -0
  9. package/dist/722.index.js +1 -0
  10. package/dist/788.index.js +1 -0
  11. package/dist/816.index.js +12 -0
  12. package/dist/830.index.js +1 -0
  13. package/dist/921.index.js +1 -0
  14. package/dist/index.js +1 -833
  15. package/package.json +5 -2
  16. package/dist/cache.d.ts +0 -6
  17. package/dist/cache.js +0 -31
  18. package/dist/cache.test.d.ts +0 -1
  19. package/dist/cache.test.js +0 -73
  20. package/dist/client.d.ts +0 -56
  21. package/dist/client.js +0 -205
  22. package/dist/client.test.d.ts +0 -1
  23. package/dist/client.test.js +0 -89
  24. package/dist/commands/agent.d.ts +0 -20
  25. package/dist/commands/agent.js +0 -4119
  26. package/dist/commands/announcements.d.ts +0 -3
  27. package/dist/commands/announcements.js +0 -28
  28. package/dist/commands/augment.d.ts +0 -12
  29. package/dist/commands/augment.js +0 -56
  30. package/dist/commands/balance.d.ts +0 -3
  31. package/dist/commands/balance.js +0 -17
  32. package/dist/commands/book.d.ts +0 -17
  33. package/dist/commands/book.js +0 -220
  34. package/dist/commands/cancel.d.ts +0 -5
  35. package/dist/commands/cancel.js +0 -41
  36. package/dist/commands/context.d.ts +0 -6
  37. package/dist/commands/context.js +0 -208
  38. package/dist/commands/create.d.ts +0 -7
  39. package/dist/commands/create.js +0 -42
  40. package/dist/commands/dashboard.d.ts +0 -14
  41. package/dist/commands/dashboard.js +0 -215
  42. package/dist/commands/delta.d.ts +0 -16
  43. package/dist/commands/delta.js +0 -115
  44. package/dist/commands/edges.d.ts +0 -26
  45. package/dist/commands/edges.js +0 -246
  46. package/dist/commands/evaluate.d.ts +0 -4
  47. package/dist/commands/evaluate.js +0 -30
  48. package/dist/commands/explore.d.ts +0 -14
  49. package/dist/commands/explore.js +0 -116
  50. package/dist/commands/feed.d.ts +0 -13
  51. package/dist/commands/feed.js +0 -73
  52. package/dist/commands/fills.d.ts +0 -4
  53. package/dist/commands/fills.js +0 -29
  54. package/dist/commands/forecast.d.ts +0 -4
  55. package/dist/commands/forecast.js +0 -53
  56. package/dist/commands/get.d.ts +0 -5
  57. package/dist/commands/get.js +0 -98
  58. package/dist/commands/heartbeat.d.ts +0 -20
  59. package/dist/commands/heartbeat.js +0 -73
  60. package/dist/commands/history.d.ts +0 -3
  61. package/dist/commands/history.js +0 -38
  62. package/dist/commands/liquidity.d.ts +0 -14
  63. package/dist/commands/liquidity.js +0 -378
  64. package/dist/commands/list.d.ts +0 -5
  65. package/dist/commands/list.js +0 -38
  66. package/dist/commands/login.d.ts +0 -10
  67. package/dist/commands/login.js +0 -98
  68. package/dist/commands/markets.d.ts +0 -10
  69. package/dist/commands/markets.js +0 -39
  70. package/dist/commands/milestones.d.ts +0 -8
  71. package/dist/commands/milestones.js +0 -56
  72. package/dist/commands/orders.d.ts +0 -4
  73. package/dist/commands/orders.js +0 -28
  74. package/dist/commands/performance.d.ts +0 -11
  75. package/dist/commands/performance.js +0 -250
  76. package/dist/commands/positions.d.ts +0 -19
  77. package/dist/commands/positions.js +0 -294
  78. package/dist/commands/prompt.d.ts +0 -13
  79. package/dist/commands/prompt.js +0 -35
  80. package/dist/commands/publish.d.ts +0 -15
  81. package/dist/commands/publish.js +0 -39
  82. package/dist/commands/query.d.ts +0 -15
  83. package/dist/commands/query.js +0 -132
  84. package/dist/commands/rfq.d.ts +0 -5
  85. package/dist/commands/rfq.js +0 -35
  86. package/dist/commands/scan.d.ts +0 -11
  87. package/dist/commands/scan.js +0 -230
  88. package/dist/commands/schedule.d.ts +0 -3
  89. package/dist/commands/schedule.js +0 -38
  90. package/dist/commands/settlements.d.ts +0 -6
  91. package/dist/commands/settlements.js +0 -50
  92. package/dist/commands/setup.d.ts +0 -24
  93. package/dist/commands/setup.js +0 -700
  94. package/dist/commands/signal.d.ts +0 -6
  95. package/dist/commands/signal.js +0 -32
  96. package/dist/commands/strategies.d.ts +0 -11
  97. package/dist/commands/strategies.js +0 -130
  98. package/dist/commands/telegram.d.ts +0 -15
  99. package/dist/commands/telegram.js +0 -125
  100. package/dist/commands/trade.d.ts +0 -12
  101. package/dist/commands/trade.js +0 -112
  102. package/dist/commands/watch.d.ts +0 -19
  103. package/dist/commands/watch.js +0 -157
  104. package/dist/commands/whatif.d.ts +0 -17
  105. package/dist/commands/whatif.js +0 -209
  106. package/dist/commands/x.d.ts +0 -28
  107. package/dist/commands/x.js +0 -167
  108. package/dist/config.d.ts +0 -55
  109. package/dist/config.js +0 -139
  110. package/dist/config.test.d.ts +0 -1
  111. package/dist/config.test.js +0 -138
  112. package/dist/index.d.ts +0 -20
  113. package/dist/kalshi.d.ts +0 -144
  114. package/dist/kalshi.js +0 -498
  115. package/dist/polymarket.d.ts +0 -237
  116. package/dist/polymarket.js +0 -353
  117. package/dist/polymarket.test.d.ts +0 -1
  118. package/dist/polymarket.test.js +0 -424
  119. package/dist/share.d.ts +0 -4
  120. package/dist/share.js +0 -27
  121. package/dist/skills/loader.d.ts +0 -19
  122. package/dist/skills/loader.js +0 -86
  123. package/dist/telegram/agent-bridge.d.ts +0 -15
  124. package/dist/telegram/agent-bridge.js +0 -573
  125. package/dist/telegram/bot.d.ts +0 -10
  126. package/dist/telegram/bot.js +0 -297
  127. package/dist/telegram/commands.d.ts +0 -11
  128. package/dist/telegram/commands.js +0 -120
  129. package/dist/telegram/format.d.ts +0 -11
  130. package/dist/telegram/format.js +0 -51
  131. package/dist/telegram/format.test.d.ts +0 -1
  132. package/dist/telegram/format.test.js +0 -73
  133. package/dist/telegram/poller.d.ts +0 -6
  134. package/dist/telegram/poller.js +0 -32
  135. package/dist/topics.d.ts +0 -17
  136. package/dist/topics.js +0 -102
  137. package/dist/topics.test.d.ts +0 -1
  138. package/dist/topics.test.js +0 -131
  139. package/dist/tui/border.d.ts +0 -33
  140. package/dist/tui/border.js +0 -87
  141. package/dist/tui/chart.d.ts +0 -19
  142. package/dist/tui/chart.js +0 -117
  143. package/dist/tui/dashboard.d.ts +0 -9
  144. package/dist/tui/dashboard.js +0 -814
  145. package/dist/tui/layout.d.ts +0 -16
  146. package/dist/tui/layout.js +0 -41
  147. package/dist/tui/screen.d.ts +0 -33
  148. package/dist/tui/screen.js +0 -102
  149. package/dist/tui/state.d.ts +0 -40
  150. package/dist/tui/state.js +0 -36
  151. package/dist/tui/widgets/commandbar.d.ts +0 -8
  152. package/dist/tui/widgets/commandbar.js +0 -82
  153. package/dist/tui/widgets/detail.d.ts +0 -9
  154. package/dist/tui/widgets/detail.js +0 -151
  155. package/dist/tui/widgets/edges.d.ts +0 -4
  156. package/dist/tui/widgets/edges.js +0 -34
  157. package/dist/tui/widgets/liquidity.d.ts +0 -9
  158. package/dist/tui/widgets/liquidity.js +0 -142
  159. package/dist/tui/widgets/orders.d.ts +0 -4
  160. package/dist/tui/widgets/orders.js +0 -37
  161. package/dist/tui/widgets/portfolio.d.ts +0 -4
  162. package/dist/tui/widgets/portfolio.js +0 -59
  163. package/dist/tui/widgets/signals.d.ts +0 -4
  164. package/dist/tui/widgets/signals.js +0 -31
  165. package/dist/tui/widgets/statusbar.d.ts +0 -8
  166. package/dist/tui/widgets/statusbar.js +0 -72
  167. package/dist/tui/widgets/thesis.d.ts +0 -4
  168. package/dist/tui/widgets/thesis.js +0 -66
  169. package/dist/tui/widgets/trade.d.ts +0 -9
  170. package/dist/tui/widgets/trade.js +0 -117
  171. package/dist/tui/widgets/upcoming.d.ts +0 -4
  172. package/dist/tui/widgets/upcoming.js +0 -41
  173. package/dist/tui/widgets/whatif.d.ts +0 -7
  174. package/dist/tui/widgets/whatif.js +0 -113
  175. package/dist/types/output.d.ts +0 -412
  176. package/dist/types/output.js +0 -9
  177. package/dist/utils.d.ts +0 -52
  178. package/dist/utils.js +0 -146
  179. package/dist/utils.test.d.ts +0 -1
  180. package/dist/utils.test.js +0 -111
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ordersCommand = ordersCommand;
4
- const kalshi_js_1 = require("../kalshi.js");
5
- const utils_js_1 = require("../utils.js");
6
- async function ordersCommand(opts) {
7
- const status = opts.status || 'resting';
8
- const result = await (0, kalshi_js_1.getOrders)({ status, limit: 100 });
9
- if (!result)
10
- throw new Error('Kalshi not configured. Set KALSHI_API_KEY_ID + KALSHI_PRIVATE_KEY_PATH.');
11
- if (opts.json) {
12
- console.log(JSON.stringify(result.orders, null, 2));
13
- return;
14
- }
15
- if (result.orders.length === 0) {
16
- console.log(`${utils_js_1.c.dim}No ${status} orders.${utils_js_1.c.reset}`);
17
- return;
18
- }
19
- console.log(`${utils_js_1.c.bold}${utils_js_1.c.cyan}Orders (${status})${utils_js_1.c.reset}`);
20
- console.log(`${utils_js_1.c.dim}${'─'.repeat(80)}${utils_js_1.c.reset}`);
21
- for (const o of result.orders) {
22
- const price = o.yes_price_dollars ? `${parseFloat(o.yes_price_dollars) * 100}¢` : `${o.yes_price || '?'}¢`;
23
- const side = o.side === 'yes' ? `${utils_js_1.c.green}YES${utils_js_1.c.reset}` : `${utils_js_1.c.red}NO${utils_js_1.c.reset}`;
24
- const remaining = o.remaining_count_fp || o.remaining_count || '?';
25
- console.log(` ${(o.ticker || '').padEnd(35)} ${side} ${price.padEnd(8)} qty ${remaining}`);
26
- }
27
- console.log(`\n${utils_js_1.c.dim}${result.orders.length} order(s)${utils_js_1.c.reset}`);
28
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * sf performance — Portfolio P&L over time with thesis event annotations
3
- *
4
- * Layout: each row is a position, with inline sparkline and current P&L.
5
- * Scales from 7 days to months — sparkline adapts to available data.
6
- */
7
- export declare function performanceCommand(opts: {
8
- ticker?: string;
9
- since?: string;
10
- json?: boolean;
11
- }): Promise<void>;
@@ -1,250 +0,0 @@
1
- "use strict";
2
- /**
3
- * sf performance — Portfolio P&L over time with thesis event annotations
4
- *
5
- * Layout: each row is a position, with inline sparkline and current P&L.
6
- * Scales from 7 days to months — sparkline adapts to available data.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.performanceCommand = performanceCommand;
10
- const client_js_1 = require("../client.js");
11
- const kalshi_js_1 = require("../kalshi.js");
12
- const config_js_1 = require("../config.js");
13
- const utils_js_1 = require("../utils.js");
14
- function fmtDate(d) {
15
- const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
16
- return `${months[d.getMonth()]} ${String(d.getDate()).padStart(2, '0')}`;
17
- }
18
- function fmtDollar(cents) {
19
- const abs = Math.abs(cents / 100);
20
- const str = abs >= 1000 ? `${(abs / 1000).toFixed(1)}k` : abs >= 100 ? abs.toFixed(0) : abs.toFixed(2);
21
- return cents >= 0 ? `+$${str}` : `-$${str}`;
22
- }
23
- function dateKey(d) {
24
- return d.toISOString().slice(0, 10);
25
- }
26
- /** Build a sparkline string from an array of values */
27
- function sparkline(values, colorFn) {
28
- if (values.length === 0)
29
- return '';
30
- const min = Math.min(...values);
31
- const max = Math.max(...values);
32
- const range = max - min || 1;
33
- const blocks = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
34
- return values.map(v => {
35
- const idx = Math.round(((v - min) / range) * (blocks.length - 1));
36
- const ch = blocks[idx];
37
- if (colorFn)
38
- return colorFn(v) + ch + utils_js_1.c.reset;
39
- return ch;
40
- }).join('');
41
- }
42
- async function performanceCommand(opts) {
43
- if (!(0, kalshi_js_1.isKalshiConfigured)()) {
44
- console.log(`${utils_js_1.c.yellow}Kalshi not configured.${utils_js_1.c.reset} Run ${utils_js_1.c.cyan}sf setup --kalshi${utils_js_1.c.reset} first.`);
45
- return;
46
- }
47
- // 1. Fetch fills
48
- const fillsResult = await (0, kalshi_js_1.getFills)({ limit: 500 });
49
- if (!fillsResult || fillsResult.fills.length === 0) {
50
- console.log(`${utils_js_1.c.dim}No fills found.${utils_js_1.c.reset}`);
51
- return;
52
- }
53
- const tickerMap = new Map();
54
- for (const fill of fillsResult.fills) {
55
- const ticker = fill.ticker || fill.market_ticker || '';
56
- if (!ticker)
57
- continue;
58
- const action = fill.action || 'buy';
59
- const side = fill.side || 'yes';
60
- const count = Math.round(parseFloat(fill.count_fp || fill.count || '0'));
61
- const yesPrice = Math.round(parseFloat(fill.yes_price_dollars || '0') * 100);
62
- // buy yes = +count, sell yes = -count
63
- // buy no = -count (short yes), sell no = +count (close short)
64
- let delta = count;
65
- if (action === 'sell')
66
- delta = -delta;
67
- if (side === 'no')
68
- delta = -delta;
69
- const info = tickerMap.get(ticker) || { ticker, netQty: 0, totalCostCents: 0, totalContracts: 0, earliestFillTs: Infinity };
70
- info.netQty += delta;
71
- if (delta > 0) {
72
- // Entering a position — accumulate cost
73
- const costPerContract = side === 'no' ? (100 - yesPrice) : yesPrice;
74
- info.totalCostCents += costPerContract * count;
75
- info.totalContracts += count;
76
- }
77
- const fillTime = fill.created_time || fill.ts || fill.created_at;
78
- if (fillTime) {
79
- const ts = Math.floor(new Date(fillTime).getTime() / 1000);
80
- if (ts < info.earliestFillTs)
81
- info.earliestFillTs = ts;
82
- }
83
- tickerMap.set(ticker, info);
84
- }
85
- let tickers = [...tickerMap.values()].filter(t => t.netQty !== 0);
86
- if (opts.ticker) {
87
- const needle = opts.ticker.toLowerCase();
88
- tickers = tickers.filter(t => t.ticker.toLowerCase().includes(needle));
89
- }
90
- if (tickers.length === 0) {
91
- console.log(`${utils_js_1.c.dim}No open positions found${opts.ticker ? ` matching "${opts.ticker}"` : ''}.${utils_js_1.c.reset}`);
92
- return;
93
- }
94
- // 3. Fetch candlesticks
95
- const sinceTs = opts.since
96
- ? Math.floor(new Date(opts.since).getTime() / 1000)
97
- : Math.min(...tickers.map(t => t.earliestFillTs === Infinity ? Math.floor(Date.now() / 1000) - 30 * 86400 : t.earliestFillTs));
98
- const nowTs = Math.floor(Date.now() / 1000);
99
- const candleData = await (0, kalshi_js_1.getBatchCandlesticks)({
100
- tickers: tickers.map(t => t.ticker),
101
- startTs: sinceTs,
102
- endTs: nowTs,
103
- periodInterval: 1440,
104
- });
105
- // Build candlestick lookup: ticker -> sorted [{ date, closeCents }]
106
- const candleMap = new Map();
107
- for (const mc of candleData) {
108
- const entries = [];
109
- for (const candle of (mc.candlesticks || [])) {
110
- const bidClose = parseFloat(candle.yes_bid?.close_dollars || '0');
111
- const askClose = parseFloat(candle.yes_ask?.close_dollars || '0');
112
- const mid = bidClose > 0 && askClose > 0 ? (bidClose + askClose) / 2 : bidClose || askClose;
113
- const closeDollars = parseFloat(candle.price?.close_dollars || '0') || mid;
114
- const closeCents = Math.round(closeDollars * 100);
115
- const ts = candle.end_period_ts || candle.period_end_ts || candle.ts;
116
- if (ts)
117
- entries.push({ date: dateKey(new Date(ts * 1000)), close: closeCents });
118
- }
119
- entries.sort((a, b) => a.date.localeCompare(b.date));
120
- candleMap.set(mc.market_ticker, entries);
121
- }
122
- // Collect all dates for total P&L
123
- const allDates = new Set();
124
- for (const [, entries] of candleMap)
125
- for (const e of entries)
126
- allDates.add(e.date);
127
- const sortedDates = [...allDates].sort();
128
- // Entry prices
129
- const entryPrices = new Map();
130
- for (const t of tickers) {
131
- entryPrices.set(t.ticker, t.totalContracts > 0 ? Math.round(t.totalCostCents / t.totalContracts) : 0);
132
- }
133
- const events = [];
134
- try {
135
- const config = (0, config_js_1.loadConfig)();
136
- const client = new client_js_1.SFClient(config.apiKey, config.apiUrl);
137
- const feedData = await client.getFeed(720);
138
- const feedItems = feedData?.feed || feedData?.items || feedData || [];
139
- if (Array.isArray(feedItems)) {
140
- for (const item of feedItems) {
141
- const confDelta = item.delta ?? item.confidenceDelta ?? 0;
142
- if (Math.abs(confDelta) >= 0.02) {
143
- const itemDate = item.evaluatedAt || item.createdAt || item.timestamp || '';
144
- if (itemDate) {
145
- events.push({
146
- date: dateKey(new Date(itemDate)),
147
- direction: confDelta > 0 ? 'up' : 'down',
148
- deltaPct: Math.round(confDelta * 100),
149
- summary: item.summary || '',
150
- });
151
- }
152
- }
153
- }
154
- }
155
- }
156
- catch { /* feed unavailable */ }
157
- const perfs = [];
158
- for (const t of tickers) {
159
- const entry = entryPrices.get(t.ticker) || 0;
160
- const entries = candleMap.get(t.ticker) || [];
161
- const current = entries.length > 0 ? entries[entries.length - 1].close : entry;
162
- const pnlCents = (current - entry) * t.netQty;
163
- const costBasis = entry * t.netQty;
164
- const pnlPct = costBasis !== 0 ? (pnlCents / Math.abs(costBasis)) * 100 : 0;
165
- const dailyPnl = entries.map(e => (e.close - entry) * t.netQty);
166
- perfs.push({ ticker: t.ticker, qty: t.netQty, entry, current, pnlCents, pnlPct, dailyPnl });
167
- }
168
- // Sort by absolute P&L descending
169
- perfs.sort((a, b) => Math.abs(b.pnlCents) - Math.abs(a.pnlCents));
170
- // Total daily P&L
171
- const totalDailyPnl = sortedDates.map(dk => {
172
- let total = 0;
173
- for (const t of tickers) {
174
- const entries = candleMap.get(t.ticker) || [];
175
- const entry = entryPrices.get(t.ticker) || 0;
176
- const dayEntry = entries.find(e => e.date === dk);
177
- if (dayEntry)
178
- total += (dayEntry.close - entry) * t.netQty;
179
- }
180
- return total;
181
- });
182
- // Summary
183
- const totalCostCents = tickers.reduce((sum, t) => sum + t.totalCostCents, 0);
184
- const totalPnlCents = perfs.reduce((sum, p) => sum + p.pnlCents, 0);
185
- const totalPnlPct = totalCostCents > 0 ? (totalPnlCents / totalCostCents) * 100 : 0;
186
- // 6. JSON output
187
- if (opts.json) {
188
- console.log(JSON.stringify({
189
- positions: perfs.map(p => ({
190
- ticker: p.ticker, qty: p.qty, entry: p.entry, current: p.current,
191
- pnl: p.pnlCents, pnlPct: Math.round(p.pnlPct * 10) / 10,
192
- })),
193
- totalDailyPnl: sortedDates.map((d, i) => ({ date: d, pnl: totalDailyPnl[i] })),
194
- events,
195
- summary: { cost: totalCostCents, pnl: totalPnlCents, pnlPct: Math.round(totalPnlPct * 10) / 10 },
196
- }, null, 2));
197
- return;
198
- }
199
- // 7. Formatted output — rows are positions
200
- const startDate = sortedDates.length > 0 ? fmtDate(new Date(sortedDates[0])) : '?';
201
- const endDate = fmtDate(new Date());
202
- console.log();
203
- console.log(` ${utils_js_1.c.bold}Portfolio Performance${utils_js_1.c.reset} ${utils_js_1.c.dim}(${startDate} → ${endDate})${utils_js_1.c.reset}`);
204
- console.log(` ${utils_js_1.c.dim}${'─'.repeat(76)}${utils_js_1.c.reset}`);
205
- console.log();
206
- // Header
207
- const maxTickerLen = Math.max(...perfs.map(p => p.ticker.length), 5) + 2;
208
- const w = maxTickerLen + 50;
209
- const pad2 = (s, n) => s.padEnd(n);
210
- console.log(` ${utils_js_1.c.dim}${pad2('Ticker', maxTickerLen)} Qty Entry Now P&L Trend${utils_js_1.c.reset}`);
211
- for (const p of perfs) {
212
- const pnlStr = fmtDollar(p.pnlCents);
213
- const pnlColor = p.pnlCents > 0 ? utils_js_1.c.green : p.pnlCents < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
214
- const spark = sparkline(p.dailyPnl, v => v >= 0 ? utils_js_1.c.green : utils_js_1.c.red);
215
- console.log(` ${pad2(p.ticker, maxTickerLen)} ` +
216
- `${(0, utils_js_1.rpad)(String(p.qty), 8)}` +
217
- `${(0, utils_js_1.rpad)(p.entry + '¢', 7)}` +
218
- `${(0, utils_js_1.rpad)(p.current + '¢', 7)}` +
219
- `${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 13)}${utils_js_1.c.reset}` +
220
- spark);
221
- }
222
- // Total row
223
- console.log(` ${utils_js_1.c.dim}${'─'.repeat(w)}${utils_js_1.c.reset}`);
224
- const totalPnlStr = fmtDollar(totalPnlCents);
225
- const totalPctStr = `${totalPnlPct >= 0 ? '+' : ''}${totalPnlPct.toFixed(1)}%`;
226
- const totalColor = totalPnlCents >= 0 ? utils_js_1.c.green : utils_js_1.c.red;
227
- const totalSpark = sparkline(totalDailyPnl, v => v >= 0 ? utils_js_1.c.green : utils_js_1.c.red);
228
- console.log(` ${utils_js_1.c.bold}${pad2('TOTAL', maxTickerLen)}${utils_js_1.c.reset} ` +
229
- `${(0, utils_js_1.rpad)('', 22)}` +
230
- `${totalColor}${utils_js_1.c.bold}${(0, utils_js_1.rpad)(`${totalPnlStr} (${totalPctStr})`, 13)}${utils_js_1.c.reset}` +
231
- totalSpark);
232
- // Events
233
- if (events.length > 0) {
234
- const dateSet = new Set(sortedDates);
235
- const relevant = events.filter(e => dateSet.has(e.date));
236
- if (relevant.length > 0) {
237
- console.log();
238
- for (const ev of relevant.slice(0, 8)) {
239
- const arrow = ev.direction === 'up' ? `${utils_js_1.c.green}▲${utils_js_1.c.reset}` : `${utils_js_1.c.red}▼${utils_js_1.c.reset}`;
240
- const summary = ev.summary.length > 55 ? ev.summary.slice(0, 54) + '…' : ev.summary;
241
- console.log(` ${arrow} ${utils_js_1.c.dim}${fmtDate(new Date(ev.date))}${utils_js_1.c.reset} ${ev.deltaPct > 0 ? '+' : ''}${ev.deltaPct}% → ${summary}`);
242
- }
243
- }
244
- }
245
- // Summary
246
- console.log();
247
- const costStr = `$${(totalCostCents / 100).toFixed(0)}`;
248
- console.log(` ${utils_js_1.c.dim}Cost basis:${utils_js_1.c.reset} ${costStr} ${utils_js_1.c.dim}|${utils_js_1.c.reset} ${totalColor}${utils_js_1.c.bold}${totalPnlStr} (${totalPctStr})${utils_js_1.c.reset}`);
249
- console.log();
250
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * sf positions — Show Kalshi positions with thesis edge overlay
3
- *
4
- * Flow:
5
- * 1. Call local kalshi.getPositions() (Kalshi SDK + local private key) → real positions
6
- * 2. Call SF API /api/thesis (via SF_API_KEY) → all theses' edge_analysis
7
- * 3. Local merge: match position ticker to edge marketId
8
- * 4. Output
9
- *
10
- * No server involvement for positions. Kalshi credentials never leave the machine.
11
- */
12
- interface PositionsOpts {
13
- json?: boolean;
14
- thesis?: string;
15
- apiKey?: string;
16
- apiUrl?: string;
17
- }
18
- export declare function positionsCommand(opts: PositionsOpts): Promise<void>;
19
- export {};
@@ -1,294 +0,0 @@
1
- "use strict";
2
- /**
3
- * sf positions — Show Kalshi positions with thesis edge overlay
4
- *
5
- * Flow:
6
- * 1. Call local kalshi.getPositions() (Kalshi SDK + local private key) → real positions
7
- * 2. Call SF API /api/thesis (via SF_API_KEY) → all theses' edge_analysis
8
- * 3. Local merge: match position ticker to edge marketId
9
- * 4. Output
10
- *
11
- * No server involvement for positions. Kalshi credentials never leave the machine.
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.positionsCommand = positionsCommand;
15
- const client_js_1 = require("../client.js");
16
- const kalshi_js_1 = require("../kalshi.js");
17
- const polymarket_js_1 = require("../polymarket.js");
18
- const config_js_1 = require("../config.js");
19
- const utils_js_1 = require("../utils.js");
20
- async function positionsCommand(opts) {
21
- const client = new client_js_1.SFClient(opts.apiKey, opts.apiUrl);
22
- // ── Step 1: Fetch Kalshi positions (local) ──
23
- let positions = null;
24
- if ((0, kalshi_js_1.isKalshiConfigured)()) {
25
- console.log(`${utils_js_1.c.dim}Fetching Kalshi positions...${utils_js_1.c.reset}`);
26
- positions = await (0, kalshi_js_1.getPositions)();
27
- }
28
- // ── Step 1b: Fetch Polymarket positions (if wallet configured) ──
29
- const config = (0, config_js_1.loadConfig)();
30
- let polyPositions = [];
31
- if (config.polymarketWalletAddress) {
32
- console.log(`${utils_js_1.c.dim}Fetching Polymarket positions...${utils_js_1.c.reset}`);
33
- try {
34
- polyPositions = await (0, polymarket_js_1.polymarketGetPositions)(config.polymarketWalletAddress);
35
- }
36
- catch {
37
- // skip
38
- }
39
- }
40
- // ── Step 2: Fetch all theses and their edges (via SF API) ──
41
- console.log(`${utils_js_1.c.dim}Fetching thesis edges...${utils_js_1.c.reset}`);
42
- let theses = [];
43
- try {
44
- const data = await client.listTheses();
45
- theses = data.theses || [];
46
- }
47
- catch (err) {
48
- console.warn(`${utils_js_1.c.yellow}Warning: Could not fetch theses: ${err}${utils_js_1.c.reset}`);
49
- }
50
- // If filtering by thesis, only fetch that one's context
51
- let allEdges = [];
52
- if (opts.thesis) {
53
- try {
54
- const ctx = await client.getContext(opts.thesis);
55
- for (const edge of (ctx.edges || [])) {
56
- allEdges.push({
57
- thesisId: ctx.thesisId,
58
- thesisTitle: ctx.thesis || ctx.title || '',
59
- edge,
60
- });
61
- }
62
- }
63
- catch (err) {
64
- console.warn(`${utils_js_1.c.yellow}Warning: Could not fetch context for ${opts.thesis}: ${err}${utils_js_1.c.reset}`);
65
- }
66
- }
67
- else {
68
- // Fetch context for all monitoring theses
69
- const monitoringTheses = theses.filter(t => t.status === 'monitoring' || t.status === 'active');
70
- for (const thesis of monitoringTheses.slice(0, 5)) { // limit to 5 to avoid rate limits
71
- try {
72
- const ctx = await client.getContext(thesis.id);
73
- for (const edge of (ctx.edges || [])) {
74
- allEdges.push({
75
- thesisId: thesis.id,
76
- thesisTitle: ctx.thesis || ctx.title || thesis.title || '',
77
- edge,
78
- });
79
- }
80
- }
81
- catch {
82
- // skip failed
83
- }
84
- }
85
- }
86
- // ── Step 2.5: Enrich positions with live prices ──
87
- if (positions && positions.length > 0) {
88
- console.log(`${utils_js_1.c.dim}Fetching live prices for ${positions.length} positions...${utils_js_1.c.reset}`);
89
- for (const pos of positions) {
90
- try {
91
- const livePrice = await (0, kalshi_js_1.getMarketPrice)(pos.ticker);
92
- if (livePrice !== null) {
93
- pos.current_value = livePrice;
94
- // P&L in cents: (currentPrice - avgEntry) * quantity
95
- pos.unrealized_pnl = (livePrice - pos.average_price_paid) * pos.quantity;
96
- }
97
- // Small delay to avoid rate limits
98
- await new Promise(r => setTimeout(r, 100));
99
- }
100
- catch {
101
- // skip — live price optional
102
- }
103
- }
104
- }
105
- // ── Step 3: Merge ──
106
- // Build a lookup from ticker → edge
107
- const edgeByTicker = new Map();
108
- for (const item of allEdges) {
109
- const ticker = item.edge.marketId;
110
- if (!edgeByTicker.has(ticker))
111
- edgeByTicker.set(ticker, []);
112
- edgeByTicker.get(ticker).push(item);
113
- }
114
- if (opts.json) {
115
- console.log(JSON.stringify({
116
- kalshiConfigured: (0, kalshi_js_1.isKalshiConfigured)(),
117
- polymarketConfigured: !!config.polymarketWalletAddress,
118
- positions: positions || [],
119
- polymarketPositions: polyPositions,
120
- edges: allEdges.map(e => ({ ...e.edge, thesisId: e.thesisId })),
121
- }, null, 2));
122
- return;
123
- }
124
- // ── Step 4: Display ──
125
- // A) Positioned edges (positions that match thesis edges)
126
- if (positions && positions.length > 0) {
127
- (0, utils_js_1.header)('Your Positions (via Kalshi)');
128
- console.log(' ' + utils_js_1.c.bold +
129
- (0, utils_js_1.pad)('Ticker', 25) +
130
- (0, utils_js_1.rpad)('Side', 5) +
131
- (0, utils_js_1.rpad)('Qty', 7) +
132
- (0, utils_js_1.rpad)('Avg', 6) +
133
- (0, utils_js_1.rpad)('Now', 6) +
134
- (0, utils_js_1.rpad)('P&L', 9) +
135
- (0, utils_js_1.rpad)('Edge', 7) +
136
- ' Signal' +
137
- utils_js_1.c.reset);
138
- console.log(' ' + utils_js_1.c.dim + '─'.repeat(85) + utils_js_1.c.reset);
139
- for (const pos of positions) {
140
- // Try to get current price
141
- const nowPrice = pos.current_value || null;
142
- const avgPrice = pos.average_price_paid || 0;
143
- const pnl = pos.unrealized_pnl || 0;
144
- const pnlColor = pnl > 0 ? utils_js_1.c.green : pnl < 0 ? utils_js_1.c.red : utils_js_1.c.dim;
145
- const pnlStr = pnl >= 0 ? `+$${(pnl / 100).toFixed(2)}` : `-$${(Math.abs(pnl) / 100).toFixed(2)}`;
146
- // Find matching edge
147
- const matchingEdges = edgeByTicker.get(pos.ticker) || [];
148
- const topEdge = matchingEdges[0];
149
- const edgeSize = topEdge?.edge?.edge ?? topEdge?.edge?.edgeSize ?? 0;
150
- const edgeColor = Math.abs(edgeSize) > 10 ? utils_js_1.c.green : Math.abs(edgeSize) > 5 ? utils_js_1.c.yellow : utils_js_1.c.dim;
151
- // Signal: HOLD if edge still positive in same direction, WATCH otherwise
152
- let signal = 'HOLD';
153
- if (topEdge) {
154
- const posDirection = pos.side;
155
- const edgeDirection = topEdge.edge.direction;
156
- if (posDirection === edgeDirection && edgeSize > 3) {
157
- signal = 'HOLD';
158
- }
159
- else if (edgeSize < -3) {
160
- signal = 'CLOSE';
161
- }
162
- else {
163
- signal = 'HOLD';
164
- }
165
- }
166
- else {
167
- signal = '—';
168
- }
169
- const signalColor = signal === 'HOLD' ? utils_js_1.c.dim : signal === 'CLOSE' ? utils_js_1.c.red : utils_js_1.c.yellow;
170
- console.log(' ' +
171
- (0, utils_js_1.pad)(pos.ticker, 25) +
172
- (0, utils_js_1.rpad)(pos.side.toUpperCase(), 5) +
173
- (0, utils_js_1.rpad)(String(pos.quantity), 7) +
174
- (0, utils_js_1.rpad)(`${avgPrice}¢`, 6) +
175
- (0, utils_js_1.rpad)(nowPrice ? `${nowPrice}¢` : '-', 6) +
176
- `${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 9)}${utils_js_1.c.reset}` +
177
- `${edgeColor}${(0, utils_js_1.rpad)(edgeSize ? `${edgeSize > 0 ? '+' : ''}${edgeSize.toFixed(0)}` : '-', 7)}${utils_js_1.c.reset}` +
178
- ` ${signalColor}${signal}${utils_js_1.c.reset}`);
179
- }
180
- console.log('');
181
- }
182
- else if ((0, kalshi_js_1.isKalshiConfigured)()) {
183
- console.log(`\n ${utils_js_1.c.dim}No open Kalshi positions.${utils_js_1.c.reset}\n`);
184
- }
185
- else {
186
- console.log(`\n ${utils_js_1.c.dim}Kalshi not configured. Run: ${utils_js_1.c.cyan}sf setup --kalshi${utils_js_1.c.reset}\n`);
187
- }
188
- // C) Polymarket positions
189
- if (polyPositions.length > 0) {
190
- (0, utils_js_1.header)('Polymarket Positions');
191
- console.log(' ' + utils_js_1.c.bold +
192
- (0, utils_js_1.pad)('Market', 35) +
193
- (0, utils_js_1.rpad)('Side', 5) +
194
- (0, utils_js_1.rpad)('Size', 8) +
195
- (0, utils_js_1.rpad)('Avg', 6) +
196
- (0, utils_js_1.rpad)('Now', 6) +
197
- (0, utils_js_1.rpad)('P&L', 9) +
198
- utils_js_1.c.reset);
199
- console.log(' ' + utils_js_1.c.dim + '─'.repeat(75) + utils_js_1.c.reset);
200
- for (const pos of polyPositions) {
201
- const title = (pos.title || pos.slug || pos.asset || '').slice(0, 34);
202
- const side = pos.outcome || 'YES';
203
- const size = pos.size || 0;
204
- const avgPrice = Math.round((pos.avgPrice || 0) * 100);
205
- const curPrice = Math.round((pos.curPrice || pos.currentPrice || 0) * 100);
206
- const pnl = pos.cashPnl || ((curPrice - avgPrice) * size / 100);
207
- const pnlColor = pnl >= 0 ? utils_js_1.c.green : utils_js_1.c.red;
208
- const pnlStr = pnl >= 0 ? `+$${pnl.toFixed(2)}` : `-$${Math.abs(pnl).toFixed(2)}`;
209
- console.log(' ' +
210
- (0, utils_js_1.pad)(title, 35) +
211
- (0, utils_js_1.rpad)(side.toUpperCase(), 5) +
212
- (0, utils_js_1.rpad)(String(Math.round(size)), 8) +
213
- (0, utils_js_1.rpad)(`${avgPrice}¢`, 6) +
214
- (0, utils_js_1.rpad)(`${curPrice}¢`, 6) +
215
- `${pnlColor}${(0, utils_js_1.rpad)(pnlStr, 9)}${utils_js_1.c.reset}`);
216
- }
217
- console.log('');
218
- }
219
- else if (config.polymarketWalletAddress) {
220
- console.log(`${utils_js_1.c.dim}No open positions on Polymarket.${utils_js_1.c.reset}\n`);
221
- }
222
- // B) Unpositioned edges (edges without matching positions)
223
- const positionedTickers = new Set((positions || []).map(p => p.ticker));
224
- const unpositionedEdges = allEdges.filter(e => !positionedTickers.has(e.edge.marketId));
225
- if (unpositionedEdges.length > 0) {
226
- // Sort by absolute edge size descending
227
- unpositionedEdges.sort((a, b) => Math.abs(b.edge.edge ?? b.edge.edgeSize ?? 0) - Math.abs(a.edge.edge ?? a.edge.edgeSize ?? 0));
228
- // Pre-fetch orderbooks locally for top Kalshi edges that don't already have server OB data
229
- const topEdgesForOB = unpositionedEdges.slice(0, 10).filter(item => item.edge.venue === 'kalshi' && !item.edge.orderbook && Math.abs(item.edge.edge ?? item.edge.edgeSize ?? 0) > 5);
230
- const localObMap = new Map();
231
- if (topEdgesForOB.length > 0 && (0, kalshi_js_1.isKalshiConfigured)()) {
232
- console.log(`${utils_js_1.c.dim}Fetching orderbooks for ${topEdgesForOB.length} edges...${utils_js_1.c.reset}`);
233
- for (const item of topEdgesForOB) {
234
- try {
235
- const ob = await (0, kalshi_js_1.getOrderbook)(item.edge.marketId);
236
- if (ob)
237
- localObMap.set(item.edge.marketId, ob);
238
- await new Promise(r => setTimeout(r, 150));
239
- }
240
- catch {
241
- // skip
242
- }
243
- }
244
- }
245
- const thesisLabel = opts.thesis ? ` (thesis ${(0, utils_js_1.shortId)(opts.thesis)})` : '';
246
- (0, utils_js_1.header)(`Unpositioned Edges${thesisLabel}`);
247
- console.log(' ' + utils_js_1.c.bold +
248
- (0, utils_js_1.pad)('Market', 30) +
249
- (0, utils_js_1.rpad)('Mkt', 6) +
250
- (0, utils_js_1.rpad)('Thesis', 8) +
251
- (0, utils_js_1.rpad)('Edge', 7) +
252
- (0, utils_js_1.rpad)('Spread', 8) +
253
- (0, utils_js_1.rpad)('Liq', 8) +
254
- ' Signal' +
255
- utils_js_1.c.reset);
256
- console.log(' ' + utils_js_1.c.dim + '─'.repeat(85) + utils_js_1.c.reset);
257
- for (const item of unpositionedEdges.slice(0, 20)) {
258
- const e = item.edge;
259
- const edgeSize = e.edge ?? e.edgeSize ?? 0;
260
- const edgeColor = edgeSize > 10 ? utils_js_1.c.green : edgeSize > 5 ? utils_js_1.c.yellow : edgeSize > 0 ? utils_js_1.c.dim : utils_js_1.c.red;
261
- const mktPrice = e.marketPrice ?? 0;
262
- const thesisPrice = e.thesisPrice ?? e.thesisImpliedPrice ?? 0;
263
- const title = (e.market || e.marketTitle || e.marketId || '?').slice(0, 29);
264
- // Orderbook: prefer server data, fallback to local fetch
265
- const serverOb = e.orderbook;
266
- const localOb = localObMap.get(e.marketId);
267
- const ob = serverOb || localOb;
268
- const spreadStr = ob ? `${ob.spread}¢` : '-';
269
- const liqStr = ob ? ob.liquidityScore : '-';
270
- const liqColor = ob?.liquidityScore === 'high' ? utils_js_1.c.green : ob?.liquidityScore === 'medium' ? utils_js_1.c.yellow : utils_js_1.c.dim;
271
- // Signal
272
- let signal = 'WATCH';
273
- if (edgeSize > 10 && ob?.liquidityScore !== 'low') {
274
- signal = 'CONSIDER';
275
- }
276
- else if (edgeSize > 5 && ob?.liquidityScore === 'high') {
277
- signal = 'CONSIDER';
278
- }
279
- const signalColor = signal === 'CONSIDER' ? utils_js_1.c.green : utils_js_1.c.dim;
280
- console.log(' ' +
281
- (0, utils_js_1.pad)(title, 30) +
282
- (0, utils_js_1.rpad)(`${mktPrice.toFixed(0)}¢`, 6) +
283
- (0, utils_js_1.rpad)(`${thesisPrice.toFixed(0)}¢`, 8) +
284
- `${edgeColor}${(0, utils_js_1.rpad)(`${edgeSize > 0 ? '+' : ''}${edgeSize.toFixed(0)}`, 7)}${utils_js_1.c.reset}` +
285
- (0, utils_js_1.rpad)(spreadStr, 8) +
286
- `${liqColor}${(0, utils_js_1.rpad)(liqStr, 8)}${utils_js_1.c.reset}` +
287
- ` ${signalColor}${signal}${utils_js_1.c.reset}`);
288
- }
289
- console.log('');
290
- }
291
- else if (allEdges.length === 0) {
292
- console.log(`\n${utils_js_1.c.dim}No thesis edges found.${utils_js_1.c.reset}\n`);
293
- }
294
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * sf prompt [thesisId] — Get dynamic system prompt for an agent
3
- *
4
- * Outputs a ready-to-use system prompt with live thesis state.
5
- * Pipe-friendly: sf prompt f582bf76 >> agent_context.txt
6
- */
7
- export declare function promptCommand(thesisId: string | undefined, opts: {
8
- sections?: string;
9
- maxLength?: string;
10
- json?: boolean;
11
- apiKey?: string;
12
- apiUrl?: string;
13
- }): Promise<void>;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- /**
3
- * sf prompt [thesisId] — Get dynamic system prompt for an agent
4
- *
5
- * Outputs a ready-to-use system prompt with live thesis state.
6
- * Pipe-friendly: sf prompt f582bf76 >> agent_context.txt
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.promptCommand = promptCommand;
10
- async function promptCommand(thesisId, opts) {
11
- const baseUrl = (opts.apiUrl || process.env.SF_API_URL || 'https://simplefunctions.dev').replace(/\/$/, '');
12
- const apiKey = opts.apiKey || process.env.SF_API_KEY || '';
13
- const params = new URLSearchParams();
14
- if (opts.sections)
15
- params.set('sections', opts.sections);
16
- if (opts.maxLength)
17
- params.set('maxLength', opts.maxLength);
18
- if (opts.json)
19
- params.set('format', 'json');
20
- const path = thesisId
21
- ? `/api/thesis/${thesisId}/prompt`
22
- : '/api/prompt';
23
- const qs = params.toString() ? `?${params.toString()}` : '';
24
- const res = await fetch(`${baseUrl}${path}${qs}`, {
25
- headers: { 'Authorization': `Bearer ${apiKey}` },
26
- });
27
- if (!res.ok) {
28
- const text = await res.text();
29
- throw new Error(`API error ${res.status}: ${text}`);
30
- }
31
- const body = await res.text();
32
- process.stdout.write(body);
33
- if (!body.endsWith('\n'))
34
- process.stdout.write('\n');
35
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * sf publish / sf unpublish
3
- *
4
- * Publish a thesis for public viewing or remove it from public.
5
- */
6
- export declare function publishCommand(thesisId: string, opts: {
7
- slug: string;
8
- description?: string;
9
- apiKey?: string;
10
- apiUrl?: string;
11
- }): Promise<void>;
12
- export declare function unpublishCommand(thesisId: string, opts: {
13
- apiKey?: string;
14
- apiUrl?: string;
15
- }): Promise<void>;