@spfunctions/cli 1.7.6 → 1.7.8

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.
@@ -2,8 +2,7 @@
2
2
  * sf query "iran oil"
3
3
  *
4
4
  * LLM-enhanced prediction market knowledge search. No auth required.
5
- * Searches Kalshi, Polymarket, and SimpleFunctions content.
6
- * Returns structured answer with markets, thesis, content, key factors.
5
+ * Searches Kalshi, Polymarket, X, traditional markets, and SimpleFunctions content.
7
6
  *
8
7
  * Usage:
9
8
  * sf query "iran oil" — Formatted output
@@ -3,8 +3,7 @@
3
3
  * sf query "iran oil"
4
4
  *
5
5
  * LLM-enhanced prediction market knowledge search. No auth required.
6
- * Searches Kalshi, Polymarket, and SimpleFunctions content.
7
- * Returns structured answer with markets, thesis, content, key factors.
6
+ * Searches Kalshi, Polymarket, X, traditional markets, and SimpleFunctions content.
8
7
  *
9
8
  * Usage:
10
9
  * sf query "iran oil" — Formatted output
@@ -49,46 +48,78 @@ async function queryCommand(q, opts) {
49
48
  }
50
49
  console.log();
51
50
  }
52
- // Markets
53
- if (data.markets?.length > 0) {
51
+ // Markets — each venue separately
52
+ const kalshiList = data.kalshi || [];
53
+ const polyList = data.polymarket || [];
54
+ if (kalshiList.length > 0 || polyList.length > 0) {
54
55
  console.log(' \x1b[1mMarkets\x1b[22m');
55
- for (const m of data.markets.slice(0, 8)) {
56
- const venue = m.venue === 'kalshi' ? '\x1b[36mK\x1b[39m' : '\x1b[35mP\x1b[39m';
57
- const vol = m.volume > 1_000_000 ? `${(m.volume / 1_000_000).toFixed(1)}M` :
58
- m.volume > 1_000 ? `${(m.volume / 1_000).toFixed(0)}K` :
59
- String(m.volume);
60
- const ticker = m.ticker ? ` ${m.ticker}` : '';
61
- console.log(` ${venue} ${String(m.price).padStart(3)}¢ vol ${vol.padStart(6)} ${m.title.slice(0, 55)}${ticker}`);
56
+ for (const m of kalshiList.slice(0, 8)) {
57
+ const vol = fmtVol(m.volume);
58
+ console.log(` \x1b[36mK\x1b[39m ${String(m.price).padStart(3)}¢ vol ${vol.padStart(6)} ${m.title.slice(0, 55)}`);
59
+ }
60
+ if (kalshiList.length > 0 && polyList.length > 0)
61
+ console.log();
62
+ for (const m of polyList.slice(0, 8)) {
63
+ const vol = fmtVol(m.volume);
64
+ console.log(` \x1b[35mP\x1b[39m ${String(m.price).padStart(3)}¢ vol ${vol.padStart(6)} ${m.title.slice(0, 55)}`);
65
+ }
66
+ console.log();
67
+ }
68
+ // X posts
69
+ const xList = data.x || [];
70
+ if (xList.length > 0) {
71
+ console.log(' \x1b[1mX signals\x1b[22m');
72
+ for (const p of xList.slice(0, 5)) {
73
+ const engagement = `${fmtNum(p.likes)}♥ ${fmtNum(p.retweets)}⟲`;
74
+ console.log(` @${p.author} ${engagement} ${p.text.slice(0, 80)}`);
75
+ }
76
+ console.log();
77
+ }
78
+ // Traditional markets
79
+ const tradList = data.traditional || [];
80
+ if (tradList.length > 0) {
81
+ console.log(' \x1b[1mTraditional\x1b[22m');
82
+ for (const m of tradList) {
83
+ const sign = m.change1d >= 0 ? '+' : '';
84
+ console.log(` ${m.symbol.padEnd(5)} $${m.price} ${sign}${m.change1d} (${sign}${m.changePct}%) ${m.name}`);
62
85
  }
63
86
  console.log();
64
87
  }
65
88
  // Theses
66
89
  if (data.theses?.length > 0) {
67
- console.log(` \x1b[1mTheses\x1b[22m`);
90
+ console.log(' \x1b[1mTheses\x1b[22m');
68
91
  for (const t of data.theses.slice(0, 3)) {
69
92
  console.log(` ${t.confidence || '?'}% ${String(t.edges || 0).padStart(2)} edges ${t.title.slice(0, 50)}`);
70
93
  }
71
94
  console.log();
72
95
  }
73
- else if (data.thesis) {
74
- // Backward compat
75
- const t = data.thesis;
76
- console.log(` \x1b[1mThesis\x1b[22m`);
77
- console.log(` ${t.confidence}% confidence ${t.edges} edges /thesis/${t.slug}`);
78
- console.log();
79
- }
80
96
  // Content
81
97
  if (data.content?.length > 0) {
82
98
  console.log(' \x1b[1mContent\x1b[22m');
83
99
  for (const c of data.content.slice(0, 5)) {
84
100
  const type = c.type.padEnd(9);
85
- console.log(` \x1b[2m${type}\x1b[22m ${c.title.slice(0, 60)}`);
101
+ console.log(` \x1b[2m${type}\x1b[22m ${c.title.slice(0, 50)} \x1b[2m${c.url}\x1b[22m`);
86
102
  }
87
103
  console.log();
88
104
  }
89
- // Sources
90
- if (data.sources?.length > 0) {
91
- console.log(` \x1b[2mSources: ${data.sources.join(', ')}\x1b[22m`);
92
- console.log();
93
- }
105
+ // Meta
106
+ const meta = data.meta || {};
107
+ const sources = meta.sources || data.sources || [];
108
+ const latency = meta.latencyMs ? `${(meta.latencyMs / 1000).toFixed(1)}s` : '';
109
+ console.log(` \x1b[2mSources: ${sources.join(', ')}${latency ? ` (${latency})` : ''}\x1b[22m`);
110
+ console.log();
111
+ }
112
+ function fmtVol(v) {
113
+ if (v > 1_000_000)
114
+ return `${(v / 1_000_000).toFixed(1)}M`;
115
+ if (v > 1_000)
116
+ return `${(v / 1_000).toFixed(0)}K`;
117
+ return String(Math.round(v));
118
+ }
119
+ function fmtNum(n) {
120
+ if (n > 1_000_000)
121
+ return `${(n / 1_000_000).toFixed(1)}M`;
122
+ if (n > 1_000)
123
+ return `${(n / 1_000).toFixed(1)}K`;
124
+ return String(n);
94
125
  }
package/dist/index.js CHANGED
@@ -141,9 +141,13 @@ program
141
141
  .option('--api-url <url>', 'API base URL (or set SF_API_URL env var)')
142
142
  .configureHelp({
143
143
  formatHelp: (cmd, helper) => {
144
- if (cmd.parent)
145
- return helper.formatHelp(cmd, helper);
146
- return GROUPED_HELP;
144
+ // Root command (sf --help) → show grouped help
145
+ // Subcommands (sf query --help) → default behavior
146
+ if (!cmd.parent)
147
+ return GROUPED_HELP;
148
+ const { Help } = require('commander');
149
+ const defaultHelper = new Help();
150
+ return defaultHelper.formatHelp(cmd, helper);
147
151
  },
148
152
  })
149
153
  .action(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spfunctions/cli",
3
- "version": "1.7.6",
3
+ "version": "1.7.8",
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"