@spfunctions/cli 1.7.16 → 1.7.19

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.
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Stable JSON output schemas for all SF CLI commands.
3
+ *
4
+ * IMPORTANT: These types define the contract that --share and sf watch depend on.
5
+ * Breaking changes here cascade to the share renderer and watch differ.
6
+ * Add fields freely; removing or renaming fields is a breaking change.
7
+ */
8
+ export type Venue = 'kalshi' | 'polymarket';
9
+ export interface MarketItem {
10
+ venue: Venue;
11
+ ticker: string;
12
+ title: string;
13
+ yesAsk: number;
14
+ lastPrice: number;
15
+ volume24h: number;
16
+ liquidity: number;
17
+ seriesTicker?: string;
18
+ }
19
+ export interface TraditionalMarket {
20
+ symbol: string;
21
+ name: string;
22
+ price: number;
23
+ changePct: number;
24
+ change1d?: number;
25
+ }
26
+ export interface EdgeItem {
27
+ marketId: string;
28
+ market: string;
29
+ venue: Venue;
30
+ direction: string;
31
+ marketPrice: number;
32
+ thesisPrice: number;
33
+ edge: number;
34
+ executableEdge: number | null;
35
+ spread: number | null;
36
+ liquidityScore: string | null;
37
+ thesisId: string;
38
+ position: {
39
+ side: string;
40
+ quantity: number;
41
+ avgPrice: number;
42
+ currentValue: number;
43
+ pnl: number;
44
+ totalCost: number;
45
+ } | null;
46
+ }
47
+ export interface ThesisSummary {
48
+ id: string;
49
+ status: string;
50
+ confidence: number | null;
51
+ updatedAt: string;
52
+ title: string;
53
+ rawThesis?: string;
54
+ slug?: string;
55
+ edgeCount?: number;
56
+ }
57
+ export interface CausalNode {
58
+ id: string;
59
+ label: string;
60
+ probability: number;
61
+ depth?: number;
62
+ children?: CausalNode[];
63
+ }
64
+ export interface EvaluationSummary {
65
+ evaluatedAt: string;
66
+ summary: string;
67
+ confidence: number;
68
+ confidenceDelta: number;
69
+ model?: string;
70
+ thesisTitle?: string;
71
+ thesisSlug?: string;
72
+ }
73
+ /** sf scan "keywords" --json */
74
+ export type ScanOutput = MarketItem[];
75
+ /** sf query "question" --json */
76
+ export interface QueryOutput {
77
+ query: string;
78
+ answer: string;
79
+ keyFactors?: string[];
80
+ kalshi?: Array<{
81
+ title: string;
82
+ ticker: string;
83
+ price: number;
84
+ volume: number;
85
+ }>;
86
+ polymarket?: Array<{
87
+ title: string;
88
+ slug: string;
89
+ price: number;
90
+ volume: number;
91
+ }>;
92
+ x?: Array<{
93
+ author: string;
94
+ text: string;
95
+ url: string;
96
+ likes: number;
97
+ retweets?: number;
98
+ }>;
99
+ traditional?: TraditionalMarket[];
100
+ theses?: Array<{
101
+ title: string;
102
+ slug: string;
103
+ confidence: number;
104
+ edges: number;
105
+ }>;
106
+ content?: Array<{
107
+ type: string;
108
+ title: string;
109
+ url: string;
110
+ snippet?: string;
111
+ }>;
112
+ meta?: {
113
+ sources?: string[];
114
+ latencyMs?: number;
115
+ };
116
+ }
117
+ /** sf context --json (no thesis ID — global context) */
118
+ export interface GlobalContextOutput {
119
+ scannedAt?: string;
120
+ meta?: {
121
+ totalMarkets: number;
122
+ kalshiMarkets: number;
123
+ polymarketMarkets: number;
124
+ };
125
+ traditional?: TraditionalMarket[];
126
+ highlights?: Array<{
127
+ title: string;
128
+ detail: string;
129
+ relatedTickers?: string[];
130
+ suggestedAction?: string;
131
+ }>;
132
+ categories?: Array<{
133
+ name: string;
134
+ description: string;
135
+ marketCount: number;
136
+ totalVolume24h: number;
137
+ topMovers?: Array<{
138
+ venue: string;
139
+ price: number;
140
+ change24h: number;
141
+ title: string;
142
+ ticker: string;
143
+ whyInteresting?: string;
144
+ }>;
145
+ mostLiquid?: Array<{
146
+ venue: string;
147
+ price: number;
148
+ spread: number;
149
+ volume24h: number;
150
+ title: string;
151
+ }>;
152
+ }>;
153
+ edges?: Array<{
154
+ price: number;
155
+ edge: number;
156
+ title: string;
157
+ thesisSlug: string;
158
+ venue: string;
159
+ }>;
160
+ signals?: EvaluationSummary[];
161
+ }
162
+ /** sf context <id> --json (thesis-specific context) */
163
+ export interface ThesisContextOutput {
164
+ thesis: string;
165
+ rawThesis?: string;
166
+ confidence: number | null;
167
+ status: string;
168
+ updatedAt?: string;
169
+ causalTree?: {
170
+ nodes: CausalNode[];
171
+ };
172
+ edges?: Array<{
173
+ marketId: string;
174
+ market: string;
175
+ marketTitle?: string;
176
+ marketPrice: number;
177
+ thesisPrice: number;
178
+ edge: number;
179
+ edgeSize?: number;
180
+ direction: string;
181
+ venue: string;
182
+ orderbook?: {
183
+ spread: number;
184
+ liquidityScore: string;
185
+ };
186
+ }>;
187
+ lastEvaluation?: {
188
+ evaluatedAt: string;
189
+ summary: string;
190
+ model: string;
191
+ positionRecommendations?: Array<{
192
+ positionId: string;
193
+ recommendation: string;
194
+ reason: string;
195
+ }>;
196
+ };
197
+ edgeMeta?: {
198
+ lastRescanAt: string;
199
+ };
200
+ }
201
+ /** sf edges --json */
202
+ export interface EdgesOutput {
203
+ totalEdges: number;
204
+ displayed: number;
205
+ thesesScanned: number;
206
+ edges: EdgeItem[];
207
+ }
208
+ /** sf list --json */
209
+ export type ListOutput = ThesisSummary[];
210
+ /** sf markets --json */
211
+ export interface MarketsOutput {
212
+ snapshotAt: string;
213
+ markets: TraditionalMarket[];
214
+ }
215
+ /** sf positions --json */
216
+ export interface PositionsOutput {
217
+ kalshiConfigured: boolean;
218
+ polymarketConfigured: boolean;
219
+ positions: Array<{
220
+ ticker: string;
221
+ side: string;
222
+ quantity: number;
223
+ average_price_paid: number;
224
+ current_value?: number;
225
+ unrealized_pnl?: number;
226
+ total_cost?: number;
227
+ }>;
228
+ polymarketPositions: Array<{
229
+ title?: string;
230
+ slug?: string;
231
+ outcome?: string;
232
+ size?: number;
233
+ avgPrice?: number;
234
+ curPrice?: number;
235
+ cashPnl?: number;
236
+ }>;
237
+ edges: Array<EdgeItem & {
238
+ thesisId: string;
239
+ }>;
240
+ }
241
+ /** sf explore --json (list mode, no slug) */
242
+ export interface ExploreListOutput {
243
+ theses: Array<{
244
+ slug: string;
245
+ confidence: number | null;
246
+ impliedReturn?: number;
247
+ status: string;
248
+ title: string;
249
+ }>;
250
+ }
251
+ /** sf explore <slug> --json (detail mode) */
252
+ export interface ExploreDetailOutput {
253
+ thesis: {
254
+ title: string;
255
+ slug: string;
256
+ confidence: number | null;
257
+ status: string;
258
+ publishedAt?: string;
259
+ description?: string;
260
+ };
261
+ causalTree?: {
262
+ nodes: CausalNode[];
263
+ };
264
+ impliedReturns?: {
265
+ avgReturnPct: number;
266
+ winRate: number;
267
+ winners: number;
268
+ losers: number;
269
+ trackedSince?: string;
270
+ edges: Array<{
271
+ market: string;
272
+ entryPrice: number;
273
+ currentPrice: number;
274
+ returnPct: number;
275
+ }>;
276
+ };
277
+ confidenceHistory?: EvaluationSummary[];
278
+ edges?: Array<{
279
+ market: string;
280
+ marketPrice: number;
281
+ thesisPrice: number;
282
+ edge: number;
283
+ orderbook?: {
284
+ liquidityScore: string;
285
+ };
286
+ }>;
287
+ }
288
+ /** sf balance --json */
289
+ export interface BalanceOutput {
290
+ available: number;
291
+ total: number;
292
+ currency: string;
293
+ }
294
+ /** sf orders --json */
295
+ export type OrdersOutput = Array<{
296
+ orderId: string;
297
+ ticker: string;
298
+ side: string;
299
+ type: string;
300
+ price: number;
301
+ quantity: number;
302
+ remainingQuantity: number;
303
+ status: string;
304
+ createdAt: string;
305
+ }>;
306
+ /** sf fills --json */
307
+ export type FillsOutput = Array<{
308
+ tradeId: string;
309
+ ticker: string;
310
+ side: string;
311
+ price: number;
312
+ count: number;
313
+ createdAt: string;
314
+ }>;
315
+ /** sf performance --json */
316
+ export interface PerformanceOutput {
317
+ totalPnl: number;
318
+ realizedPnl: number;
319
+ unrealizedPnl: number;
320
+ winRate: number;
321
+ trades: number;
322
+ positions: Array<{
323
+ ticker: string;
324
+ side: string;
325
+ entryPrice: number;
326
+ currentPrice: number;
327
+ pnl: number;
328
+ returnPct: number;
329
+ }>;
330
+ }
331
+ /** sf feed --json */
332
+ export type FeedOutput = EvaluationSummary[];
333
+ /** sf milestones --json */
334
+ export type MilestonesOutput = Array<{
335
+ date: string;
336
+ ticker: string;
337
+ title: string;
338
+ category?: string;
339
+ }>;
340
+ /** sf history <ticker> --json */
341
+ export type HistoryOutput = Array<{
342
+ ts: string;
343
+ price: number;
344
+ volume?: number;
345
+ }>;
346
+ /** sf forecast <event> --json */
347
+ export interface ForecastOutput {
348
+ event: string;
349
+ markets: Array<{
350
+ ticker: string;
351
+ title: string;
352
+ price: number;
353
+ impliedProb: number;
354
+ }>;
355
+ distribution?: {
356
+ p10: number;
357
+ p25: number;
358
+ p50: number;
359
+ p75: number;
360
+ p90: number;
361
+ };
362
+ }
363
+ /** sf liquidity --json */
364
+ export interface LiquidityOutput {
365
+ markets: Array<{
366
+ ticker: string;
367
+ title: string;
368
+ venue: Venue;
369
+ spread: number;
370
+ bidDepth: number;
371
+ askDepth: number;
372
+ score: string;
373
+ }>;
374
+ }
375
+ /** sf book <ticker> --json */
376
+ export interface BookOutput {
377
+ ticker: string;
378
+ bids: Array<{
379
+ price: number;
380
+ quantity: number;
381
+ }>;
382
+ asks: Array<{
383
+ price: number;
384
+ quantity: number;
385
+ }>;
386
+ spread: number;
387
+ midPrice: number;
388
+ }
389
+ /** Wrapper used by --share to store snapshots */
390
+ export interface ShareSnapshot {
391
+ command: string;
392
+ args: string[];
393
+ timestamp: string;
394
+ data: unknown;
395
+ version: string;
396
+ }
397
+ /** Change event emitted by sf watch */
398
+ export interface WatchChangeEvent {
399
+ type: 'edge_change' | 'new_contract' | 'removed_contract' | 'price_move';
400
+ timestamp: string;
401
+ market: string;
402
+ venue: Venue;
403
+ before?: {
404
+ price: number;
405
+ edge?: number;
406
+ };
407
+ after: {
408
+ price: number;
409
+ edge?: number;
410
+ };
411
+ delta: number;
412
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Stable JSON output schemas for all SF CLI commands.
4
+ *
5
+ * IMPORTANT: These types define the contract that --share and sf watch depend on.
6
+ * Breaking changes here cascade to the share renderer and watch differ.
7
+ * Add fields freely; removing or renaming fields is a breaking change.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/utils.d.ts CHANGED
@@ -34,6 +34,16 @@ export declare function rpad(s: string, width: number): string;
34
34
  export declare function hr(width?: number): void;
35
35
  /** Print an error and exit */
36
36
  export declare function die(msg: string): never;
37
+ /**
38
+ * Print an error with an actionable suggestion.
39
+ * Use instead of bare console.error for user-facing errors.
40
+ */
41
+ export declare function errorWithHint(message: string, hint?: string): void;
42
+ /**
43
+ * Print an empty state message with a next-action CTA.
44
+ * Use when a command returns zero results.
45
+ */
46
+ export declare function emptyState(thing: string, nextAction?: string): void;
37
47
  /** Print a section header */
38
48
  export declare function header(title: string): void;
39
49
  /** Truncate a string with ellipsis */
package/dist/utils.js CHANGED
@@ -15,6 +15,8 @@ exports.pad = pad;
15
15
  exports.rpad = rpad;
16
16
  exports.hr = hr;
17
17
  exports.die = die;
18
+ exports.errorWithHint = errorWithHint;
19
+ exports.emptyState = emptyState;
18
20
  exports.header = header;
19
21
  exports.trunc = trunc;
20
22
  exports.shortId = shortId;
@@ -108,6 +110,26 @@ function die(msg) {
108
110
  console.error(`${exports.c.red}Error:${exports.c.reset} ${msg}`);
109
111
  process.exit(1);
110
112
  }
113
+ /**
114
+ * Print an error with an actionable suggestion.
115
+ * Use instead of bare console.error for user-facing errors.
116
+ */
117
+ function errorWithHint(message, hint) {
118
+ console.error(`\n ${exports.c.red}Error:${exports.c.reset} ${message}`);
119
+ if (hint)
120
+ console.error(` ${exports.c.dim}${hint}${exports.c.reset}`);
121
+ console.error();
122
+ }
123
+ /**
124
+ * Print an empty state message with a next-action CTA.
125
+ * Use when a command returns zero results.
126
+ */
127
+ function emptyState(thing, nextAction) {
128
+ console.log(`\n ${exports.c.dim}No ${thing} found.${exports.c.reset}`);
129
+ if (nextAction)
130
+ console.log(` ${exports.c.dim}${nextAction}${exports.c.reset}`);
131
+ console.log();
132
+ }
111
133
  /** Print a section header */
112
134
  function header(title) {
113
135
  console.log(`\n${exports.c.bold}${exports.c.cyan}${title}${exports.c.reset}`);
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@spfunctions/cli",
3
- "version": "1.7.16",
3
+ "version": "1.7.19",
4
+ "mcpName": "io.github.spfunctions/simplefunctions",
4
5
  "description": "Prediction market intelligence CLI. Causal thesis model, 24/7 Kalshi/Polymarket scan, live orderbook, edge detection. Interactive agent mode with tool calling.",
5
6
  "bin": {
6
7
  "sf": "./dist/index.js"