@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.
- package/dist/101.index.js +1 -0
- package/dist/12.index.js +1 -0
- package/dist/160.index.js +1 -0
- package/dist/174.index.js +1 -0
- package/dist/278.index.js +6 -0
- package/dist/582.index.js +1 -0
- package/dist/641.index.js +324 -0
- package/dist/669.index.js +1 -0
- package/dist/722.index.js +1 -0
- package/dist/788.index.js +1 -0
- package/dist/816.index.js +12 -0
- package/dist/830.index.js +1 -0
- package/dist/921.index.js +1 -0
- package/dist/index.js +1 -833
- package/package.json +5 -2
- package/dist/cache.d.ts +0 -6
- package/dist/cache.js +0 -31
- package/dist/cache.test.d.ts +0 -1
- package/dist/cache.test.js +0 -73
- package/dist/client.d.ts +0 -56
- package/dist/client.js +0 -205
- package/dist/client.test.d.ts +0 -1
- package/dist/client.test.js +0 -89
- package/dist/commands/agent.d.ts +0 -20
- package/dist/commands/agent.js +0 -4119
- package/dist/commands/announcements.d.ts +0 -3
- package/dist/commands/announcements.js +0 -28
- package/dist/commands/augment.d.ts +0 -12
- package/dist/commands/augment.js +0 -56
- package/dist/commands/balance.d.ts +0 -3
- package/dist/commands/balance.js +0 -17
- package/dist/commands/book.d.ts +0 -17
- package/dist/commands/book.js +0 -220
- package/dist/commands/cancel.d.ts +0 -5
- package/dist/commands/cancel.js +0 -41
- package/dist/commands/context.d.ts +0 -6
- package/dist/commands/context.js +0 -208
- package/dist/commands/create.d.ts +0 -7
- package/dist/commands/create.js +0 -42
- package/dist/commands/dashboard.d.ts +0 -14
- package/dist/commands/dashboard.js +0 -215
- package/dist/commands/delta.d.ts +0 -16
- package/dist/commands/delta.js +0 -115
- package/dist/commands/edges.d.ts +0 -26
- package/dist/commands/edges.js +0 -246
- package/dist/commands/evaluate.d.ts +0 -4
- package/dist/commands/evaluate.js +0 -30
- package/dist/commands/explore.d.ts +0 -14
- package/dist/commands/explore.js +0 -116
- package/dist/commands/feed.d.ts +0 -13
- package/dist/commands/feed.js +0 -73
- package/dist/commands/fills.d.ts +0 -4
- package/dist/commands/fills.js +0 -29
- package/dist/commands/forecast.d.ts +0 -4
- package/dist/commands/forecast.js +0 -53
- package/dist/commands/get.d.ts +0 -5
- package/dist/commands/get.js +0 -98
- package/dist/commands/heartbeat.d.ts +0 -20
- package/dist/commands/heartbeat.js +0 -73
- package/dist/commands/history.d.ts +0 -3
- package/dist/commands/history.js +0 -38
- package/dist/commands/liquidity.d.ts +0 -14
- package/dist/commands/liquidity.js +0 -378
- package/dist/commands/list.d.ts +0 -5
- package/dist/commands/list.js +0 -38
- package/dist/commands/login.d.ts +0 -10
- package/dist/commands/login.js +0 -98
- package/dist/commands/markets.d.ts +0 -10
- package/dist/commands/markets.js +0 -39
- package/dist/commands/milestones.d.ts +0 -8
- package/dist/commands/milestones.js +0 -56
- package/dist/commands/orders.d.ts +0 -4
- package/dist/commands/orders.js +0 -28
- package/dist/commands/performance.d.ts +0 -11
- package/dist/commands/performance.js +0 -250
- package/dist/commands/positions.d.ts +0 -19
- package/dist/commands/positions.js +0 -294
- package/dist/commands/prompt.d.ts +0 -13
- package/dist/commands/prompt.js +0 -35
- package/dist/commands/publish.d.ts +0 -15
- package/dist/commands/publish.js +0 -39
- package/dist/commands/query.d.ts +0 -15
- package/dist/commands/query.js +0 -132
- package/dist/commands/rfq.d.ts +0 -5
- package/dist/commands/rfq.js +0 -35
- package/dist/commands/scan.d.ts +0 -11
- package/dist/commands/scan.js +0 -230
- package/dist/commands/schedule.d.ts +0 -3
- package/dist/commands/schedule.js +0 -38
- package/dist/commands/settlements.d.ts +0 -6
- package/dist/commands/settlements.js +0 -50
- package/dist/commands/setup.d.ts +0 -24
- package/dist/commands/setup.js +0 -700
- package/dist/commands/signal.d.ts +0 -6
- package/dist/commands/signal.js +0 -32
- package/dist/commands/strategies.d.ts +0 -11
- package/dist/commands/strategies.js +0 -130
- package/dist/commands/telegram.d.ts +0 -15
- package/dist/commands/telegram.js +0 -125
- package/dist/commands/trade.d.ts +0 -12
- package/dist/commands/trade.js +0 -112
- package/dist/commands/watch.d.ts +0 -19
- package/dist/commands/watch.js +0 -157
- package/dist/commands/whatif.d.ts +0 -17
- package/dist/commands/whatif.js +0 -209
- package/dist/commands/x.d.ts +0 -28
- package/dist/commands/x.js +0 -167
- package/dist/config.d.ts +0 -55
- package/dist/config.js +0 -139
- package/dist/config.test.d.ts +0 -1
- package/dist/config.test.js +0 -138
- package/dist/index.d.ts +0 -20
- package/dist/kalshi.d.ts +0 -144
- package/dist/kalshi.js +0 -498
- package/dist/polymarket.d.ts +0 -237
- package/dist/polymarket.js +0 -353
- package/dist/polymarket.test.d.ts +0 -1
- package/dist/polymarket.test.js +0 -424
- package/dist/share.d.ts +0 -4
- package/dist/share.js +0 -27
- package/dist/skills/loader.d.ts +0 -19
- package/dist/skills/loader.js +0 -86
- package/dist/telegram/agent-bridge.d.ts +0 -15
- package/dist/telegram/agent-bridge.js +0 -573
- package/dist/telegram/bot.d.ts +0 -10
- package/dist/telegram/bot.js +0 -297
- package/dist/telegram/commands.d.ts +0 -11
- package/dist/telegram/commands.js +0 -120
- package/dist/telegram/format.d.ts +0 -11
- package/dist/telegram/format.js +0 -51
- package/dist/telegram/format.test.d.ts +0 -1
- package/dist/telegram/format.test.js +0 -73
- package/dist/telegram/poller.d.ts +0 -6
- package/dist/telegram/poller.js +0 -32
- package/dist/topics.d.ts +0 -17
- package/dist/topics.js +0 -102
- package/dist/topics.test.d.ts +0 -1
- package/dist/topics.test.js +0 -131
- package/dist/tui/border.d.ts +0 -33
- package/dist/tui/border.js +0 -87
- package/dist/tui/chart.d.ts +0 -19
- package/dist/tui/chart.js +0 -117
- package/dist/tui/dashboard.d.ts +0 -9
- package/dist/tui/dashboard.js +0 -814
- package/dist/tui/layout.d.ts +0 -16
- package/dist/tui/layout.js +0 -41
- package/dist/tui/screen.d.ts +0 -33
- package/dist/tui/screen.js +0 -102
- package/dist/tui/state.d.ts +0 -40
- package/dist/tui/state.js +0 -36
- package/dist/tui/widgets/commandbar.d.ts +0 -8
- package/dist/tui/widgets/commandbar.js +0 -82
- package/dist/tui/widgets/detail.d.ts +0 -9
- package/dist/tui/widgets/detail.js +0 -151
- package/dist/tui/widgets/edges.d.ts +0 -4
- package/dist/tui/widgets/edges.js +0 -34
- package/dist/tui/widgets/liquidity.d.ts +0 -9
- package/dist/tui/widgets/liquidity.js +0 -142
- package/dist/tui/widgets/orders.d.ts +0 -4
- package/dist/tui/widgets/orders.js +0 -37
- package/dist/tui/widgets/portfolio.d.ts +0 -4
- package/dist/tui/widgets/portfolio.js +0 -59
- package/dist/tui/widgets/signals.d.ts +0 -4
- package/dist/tui/widgets/signals.js +0 -31
- package/dist/tui/widgets/statusbar.d.ts +0 -8
- package/dist/tui/widgets/statusbar.js +0 -72
- package/dist/tui/widgets/thesis.d.ts +0 -4
- package/dist/tui/widgets/thesis.js +0 -66
- package/dist/tui/widgets/trade.d.ts +0 -9
- package/dist/tui/widgets/trade.js +0 -117
- package/dist/tui/widgets/upcoming.d.ts +0 -4
- package/dist/tui/widgets/upcoming.js +0 -41
- package/dist/tui/widgets/whatif.d.ts +0 -7
- package/dist/tui/widgets/whatif.js +0 -113
- package/dist/types/output.d.ts +0 -412
- package/dist/types/output.js +0 -9
- package/dist/utils.d.ts +0 -52
- package/dist/utils.js +0 -146
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -111
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spfunctions/cli",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.22",
|
|
4
4
|
"mcpName": "io.github.spfunctions/simplefunctions",
|
|
5
5
|
"description": "Prediction market intelligence CLI. Causal thesis model, 24/7 Kalshi/Polymarket scan, live orderbook, edge detection. Interactive agent mode with tool calling.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"sf": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "node ./node_modules/typescript/bin/tsc",
|
|
10
|
+
"build": "node ./node_modules/typescript/bin/tsc && node ./node_modules/@vercel/ncc/dist/ncc/cli.js build dist/index.js -o dist-bundle --minify --no-source-map-register -e node:fs -e node:path -e node:os -e node:crypto -e node:child_process -e node:readline -e node:events -e node:process -e node:stream -e node:buffer -e node:net -e node:http -e node:https -e node:tty -e node:util -e node:url -e node:assert && rm -rf dist && mkdir dist && for f in dist-bundle/*.js; do node ./node_modules/terser/bin/terser \"$f\" -o \"dist/$(basename $f)\" --compress --mangle; done && rm -rf dist-bundle",
|
|
11
|
+
"build:dev": "node ./node_modules/typescript/bin/tsc",
|
|
11
12
|
"dev": "tsx src/index.ts",
|
|
12
13
|
"test": "vitest run",
|
|
13
14
|
"test:watch": "vitest",
|
|
@@ -23,6 +24,8 @@
|
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/node": "^20.0.0",
|
|
27
|
+
"@vercel/ncc": "^0.38.4",
|
|
28
|
+
"terser": "^5.46.1",
|
|
26
29
|
"tsx": "^4.0.0",
|
|
27
30
|
"typescript": "^5.0.0",
|
|
28
31
|
"vitest": "^4.1.0"
|
package/dist/cache.d.ts
DELETED
package/dist/cache.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Simple in-memory TTL cache for dashboard data
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.cached = cached;
|
|
7
|
-
exports.invalidate = invalidate;
|
|
8
|
-
exports.invalidateAll = invalidateAll;
|
|
9
|
-
const store = new Map();
|
|
10
|
-
async function cached(key, ttlMs, fn) {
|
|
11
|
-
const hit = store.get(key);
|
|
12
|
-
if (hit && Date.now() < hit.expiry)
|
|
13
|
-
return hit.data;
|
|
14
|
-
try {
|
|
15
|
-
const data = await fn();
|
|
16
|
-
store.set(key, { data, expiry: Date.now() + ttlMs });
|
|
17
|
-
return data;
|
|
18
|
-
}
|
|
19
|
-
catch (err) {
|
|
20
|
-
// On error, return stale data if available
|
|
21
|
-
if (hit)
|
|
22
|
-
return hit.data;
|
|
23
|
-
throw err;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function invalidate(key) {
|
|
27
|
-
store.delete(key);
|
|
28
|
-
}
|
|
29
|
-
function invalidateAll() {
|
|
30
|
-
store.clear();
|
|
31
|
-
}
|
package/dist/cache.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/cache.test.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const cache_js_1 = require("./cache.js");
|
|
5
|
-
(0, vitest_1.beforeEach)(() => {
|
|
6
|
-
(0, cache_js_1.invalidateAll)();
|
|
7
|
-
vitest_1.vi.useRealTimers();
|
|
8
|
-
});
|
|
9
|
-
(0, vitest_1.describe)('cached', () => {
|
|
10
|
-
(0, vitest_1.it)('returns fresh data on cache miss', async () => {
|
|
11
|
-
const fn = vitest_1.vi.fn().mockResolvedValue('data');
|
|
12
|
-
const result = await (0, cache_js_1.cached)('key1', 1000, fn);
|
|
13
|
-
(0, vitest_1.expect)(result).toBe('data');
|
|
14
|
-
(0, vitest_1.expect)(fn).toHaveBeenCalledOnce();
|
|
15
|
-
});
|
|
16
|
-
(0, vitest_1.it)('returns cached data on hit without calling fn', async () => {
|
|
17
|
-
const fn = vitest_1.vi.fn().mockResolvedValue('data');
|
|
18
|
-
await (0, cache_js_1.cached)('key2', 5000, fn);
|
|
19
|
-
const result = await (0, cache_js_1.cached)('key2', 5000, fn);
|
|
20
|
-
(0, vitest_1.expect)(result).toBe('data');
|
|
21
|
-
(0, vitest_1.expect)(fn).toHaveBeenCalledOnce();
|
|
22
|
-
});
|
|
23
|
-
(0, vitest_1.it)('expires after TTL', async () => {
|
|
24
|
-
vitest_1.vi.useFakeTimers();
|
|
25
|
-
const fn = vitest_1.vi.fn()
|
|
26
|
-
.mockResolvedValueOnce('first')
|
|
27
|
-
.mockResolvedValueOnce('second');
|
|
28
|
-
await (0, cache_js_1.cached)('key3', 1000, fn);
|
|
29
|
-
vitest_1.vi.advanceTimersByTime(1500);
|
|
30
|
-
const result = await (0, cache_js_1.cached)('key3', 1000, fn);
|
|
31
|
-
(0, vitest_1.expect)(result).toBe('second');
|
|
32
|
-
(0, vitest_1.expect)(fn).toHaveBeenCalledTimes(2);
|
|
33
|
-
});
|
|
34
|
-
(0, vitest_1.it)('returns stale data on error when cache exists', async () => {
|
|
35
|
-
vitest_1.vi.useFakeTimers();
|
|
36
|
-
const fn = vitest_1.vi.fn()
|
|
37
|
-
.mockResolvedValueOnce('stale')
|
|
38
|
-
.mockRejectedValueOnce(new Error('fail'));
|
|
39
|
-
await (0, cache_js_1.cached)('key4', 1000, fn);
|
|
40
|
-
vitest_1.vi.advanceTimersByTime(1500);
|
|
41
|
-
const result = await (0, cache_js_1.cached)('key4', 1000, fn);
|
|
42
|
-
(0, vitest_1.expect)(result).toBe('stale');
|
|
43
|
-
});
|
|
44
|
-
(0, vitest_1.it)('throws on error when no stale data', async () => {
|
|
45
|
-
const fn = vitest_1.vi.fn().mockRejectedValue(new Error('fail'));
|
|
46
|
-
await (0, vitest_1.expect)((0, cache_js_1.cached)('key5', 1000, fn)).rejects.toThrow('fail');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
(0, vitest_1.describe)('invalidate', () => {
|
|
50
|
-
(0, vitest_1.it)('clears a specific key', async () => {
|
|
51
|
-
const fn = vitest_1.vi.fn()
|
|
52
|
-
.mockResolvedValueOnce('first')
|
|
53
|
-
.mockResolvedValueOnce('second');
|
|
54
|
-
await (0, cache_js_1.cached)('key6', 60000, fn);
|
|
55
|
-
(0, cache_js_1.invalidate)('key6');
|
|
56
|
-
const result = await (0, cache_js_1.cached)('key6', 60000, fn);
|
|
57
|
-
(0, vitest_1.expect)(result).toBe('second');
|
|
58
|
-
(0, vitest_1.expect)(fn).toHaveBeenCalledTimes(2);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
(0, vitest_1.describe)('invalidateAll', () => {
|
|
62
|
-
(0, vitest_1.it)('clears all keys', async () => {
|
|
63
|
-
const fn1 = vitest_1.vi.fn().mockResolvedValue('a');
|
|
64
|
-
const fn2 = vitest_1.vi.fn().mockResolvedValue('b');
|
|
65
|
-
await (0, cache_js_1.cached)('x', 60000, fn1);
|
|
66
|
-
await (0, cache_js_1.cached)('y', 60000, fn2);
|
|
67
|
-
(0, cache_js_1.invalidateAll)();
|
|
68
|
-
await (0, cache_js_1.cached)('x', 60000, fn1);
|
|
69
|
-
await (0, cache_js_1.cached)('y', 60000, fn2);
|
|
70
|
-
(0, vitest_1.expect)(fn1).toHaveBeenCalledTimes(2);
|
|
71
|
-
(0, vitest_1.expect)(fn2).toHaveBeenCalledTimes(2);
|
|
72
|
-
});
|
|
73
|
-
});
|
package/dist/client.d.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SimpleFunctions HTTP Client
|
|
3
|
-
*
|
|
4
|
-
* Pure fetch-based client. Zero project dependencies.
|
|
5
|
-
* Talks to the SF API (authenticated) and Kalshi public API (no auth).
|
|
6
|
-
*/
|
|
7
|
-
export declare class SFClient {
|
|
8
|
-
private apiKey;
|
|
9
|
-
private baseUrl;
|
|
10
|
-
constructor(apiKey?: string, baseUrl?: string);
|
|
11
|
-
private request;
|
|
12
|
-
listTheses(): Promise<{
|
|
13
|
-
theses: any[];
|
|
14
|
-
}>;
|
|
15
|
-
getThesis(id: string): Promise<any>;
|
|
16
|
-
getContext(id: string): Promise<any>;
|
|
17
|
-
createThesis(rawThesis: string, sync?: boolean): Promise<any>;
|
|
18
|
-
injectSignal(id: string, type: string, content: string, source?: string): Promise<any>;
|
|
19
|
-
evaluate(id: string): Promise<any>;
|
|
20
|
-
getHeartbeatConfig(id: string): Promise<any>;
|
|
21
|
-
updateHeartbeatConfig(id: string, config: Record<string, unknown>): Promise<any>;
|
|
22
|
-
getFeed(hours?: number, limit?: number): Promise<any>;
|
|
23
|
-
getChanges(id: string, since: string): Promise<any>;
|
|
24
|
-
updateThesis(id: string, data: Record<string, unknown>): Promise<any>;
|
|
25
|
-
publish(id: string, slug: string, description?: string): Promise<any>;
|
|
26
|
-
unpublish(id: string): Promise<any>;
|
|
27
|
-
augmentTree(id: string, dryRun?: boolean): Promise<any>;
|
|
28
|
-
getStrategies(id: string, status?: string): Promise<any>;
|
|
29
|
-
createStrategyAPI(id: string, data: Record<string, unknown>): Promise<any>;
|
|
30
|
-
updateStrategyAPI(thesisId: string, strategyId: string, data: Record<string, unknown>): Promise<any>;
|
|
31
|
-
deleteStrategyAPI(thesisId: string, strategyId: string): Promise<any>;
|
|
32
|
-
searchX(query: string, opts?: {
|
|
33
|
-
mode?: string;
|
|
34
|
-
hours?: number;
|
|
35
|
-
limit?: number;
|
|
36
|
-
}): Promise<any>;
|
|
37
|
-
getXVolume(query: string, opts?: {
|
|
38
|
-
hours?: number;
|
|
39
|
-
granularity?: string;
|
|
40
|
-
}): Promise<any>;
|
|
41
|
-
searchXNews(query: string, opts?: {
|
|
42
|
-
limit?: number;
|
|
43
|
-
}): Promise<any>;
|
|
44
|
-
getXAccount(username: string, opts?: {
|
|
45
|
-
hours?: number;
|
|
46
|
-
limit?: number;
|
|
47
|
-
}): Promise<any>;
|
|
48
|
-
}
|
|
49
|
-
export declare function kalshiFetchAllSeries(): Promise<any[]>;
|
|
50
|
-
export declare function kalshiFetchEvents(seriesTicker: string): Promise<any[]>;
|
|
51
|
-
export declare function kalshiFetchMarket(ticker: string): Promise<any>;
|
|
52
|
-
export declare function kalshiFetchMarketsBySeries(seriesTicker: string): Promise<any[]>;
|
|
53
|
-
export declare function kalshiFetchMarketsByEvent(eventTicker: string): Promise<any[]>;
|
|
54
|
-
export declare function fetchGlobalContext(): Promise<any>;
|
|
55
|
-
export declare function fetchQuery(q: string): Promise<any>;
|
|
56
|
-
export declare function fetchTraditionalMarkets(): Promise<any>;
|
package/dist/client.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* SimpleFunctions HTTP Client
|
|
4
|
-
*
|
|
5
|
-
* Pure fetch-based client. Zero project dependencies.
|
|
6
|
-
* Talks to the SF API (authenticated) and Kalshi public API (no auth).
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.SFClient = void 0;
|
|
10
|
-
exports.kalshiFetchAllSeries = kalshiFetchAllSeries;
|
|
11
|
-
exports.kalshiFetchEvents = kalshiFetchEvents;
|
|
12
|
-
exports.kalshiFetchMarket = kalshiFetchMarket;
|
|
13
|
-
exports.kalshiFetchMarketsBySeries = kalshiFetchMarketsBySeries;
|
|
14
|
-
exports.kalshiFetchMarketsByEvent = kalshiFetchMarketsByEvent;
|
|
15
|
-
exports.fetchGlobalContext = fetchGlobalContext;
|
|
16
|
-
exports.fetchQuery = fetchQuery;
|
|
17
|
-
exports.fetchTraditionalMarkets = fetchTraditionalMarkets;
|
|
18
|
-
const DEFAULT_API_URL = 'https://simplefunctions.dev';
|
|
19
|
-
const KALSHI_BASE = 'https://api.elections.kalshi.com/trade-api/v2';
|
|
20
|
-
// ===== SF API Client =====
|
|
21
|
-
class SFClient {
|
|
22
|
-
apiKey;
|
|
23
|
-
baseUrl;
|
|
24
|
-
constructor(apiKey, baseUrl) {
|
|
25
|
-
this.apiKey = apiKey || process.env.SF_API_KEY || '';
|
|
26
|
-
this.baseUrl = (baseUrl || process.env.SF_API_URL || DEFAULT_API_URL).replace(/\/$/, '');
|
|
27
|
-
if (!this.apiKey) {
|
|
28
|
-
throw new Error('API key required. Set SF_API_KEY or use --api-key');
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async request(method, path, body) {
|
|
32
|
-
const url = `${this.baseUrl}${path}`;
|
|
33
|
-
const headers = {
|
|
34
|
-
'Authorization': `Bearer ${this.apiKey}`,
|
|
35
|
-
'Content-Type': 'application/json',
|
|
36
|
-
};
|
|
37
|
-
const res = await fetch(url, {
|
|
38
|
-
method,
|
|
39
|
-
headers,
|
|
40
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
41
|
-
});
|
|
42
|
-
if (!res.ok) {
|
|
43
|
-
let errorBody = null;
|
|
44
|
-
try {
|
|
45
|
-
const text = await res.text();
|
|
46
|
-
errorBody = text ? JSON.parse(text) : null;
|
|
47
|
-
}
|
|
48
|
-
catch { /* not JSON */ }
|
|
49
|
-
const err = new Error(errorBody?.error || errorBody?.message || `API error ${res.status}`);
|
|
50
|
-
err.status = res.status;
|
|
51
|
-
err.code = errorBody?.code || `HTTP_${res.status}`;
|
|
52
|
-
err.details = errorBody;
|
|
53
|
-
throw err;
|
|
54
|
-
}
|
|
55
|
-
return res.json();
|
|
56
|
-
}
|
|
57
|
-
// ── Thesis operations ──
|
|
58
|
-
async listTheses() {
|
|
59
|
-
return this.request('GET', '/api/thesis');
|
|
60
|
-
}
|
|
61
|
-
// GET /api/thesis/:id returns { ...thesisRow, positions: [] } — flat, NOT { thesis, positions }
|
|
62
|
-
async getThesis(id) {
|
|
63
|
-
return this.request('GET', `/api/thesis/${id}`);
|
|
64
|
-
}
|
|
65
|
-
async getContext(id) {
|
|
66
|
-
return this.request('GET', `/api/thesis/${id}/context`);
|
|
67
|
-
}
|
|
68
|
-
async createThesis(rawThesis, sync = true) {
|
|
69
|
-
return this.request('POST', `/api/thesis/create?sync=${sync}`, { rawThesis });
|
|
70
|
-
}
|
|
71
|
-
async injectSignal(id, type, content, source = 'cli') {
|
|
72
|
-
return this.request('POST', `/api/thesis/${id}/signal`, { type, content, source });
|
|
73
|
-
}
|
|
74
|
-
async evaluate(id) {
|
|
75
|
-
return this.request('POST', `/api/thesis/${id}/evaluate`);
|
|
76
|
-
}
|
|
77
|
-
async getHeartbeatConfig(id) {
|
|
78
|
-
return this.request('GET', `/api/thesis/${id}/heartbeat`);
|
|
79
|
-
}
|
|
80
|
-
async updateHeartbeatConfig(id, config) {
|
|
81
|
-
return this.request('PATCH', `/api/thesis/${id}/heartbeat`, config);
|
|
82
|
-
}
|
|
83
|
-
async getFeed(hours = 24, limit = 200) {
|
|
84
|
-
return this.request('GET', `/api/feed?hours=${hours}&limit=${limit}`);
|
|
85
|
-
}
|
|
86
|
-
async getChanges(id, since) {
|
|
87
|
-
return this.request('GET', `/api/thesis/${id}/changes?since=${encodeURIComponent(since)}`);
|
|
88
|
-
}
|
|
89
|
-
async updateThesis(id, data) {
|
|
90
|
-
return this.request('PATCH', `/api/thesis/${id}`, data);
|
|
91
|
-
}
|
|
92
|
-
async publish(id, slug, description) {
|
|
93
|
-
return this.request('POST', `/api/thesis/${id}/publish`, { slug, description });
|
|
94
|
-
}
|
|
95
|
-
async unpublish(id) {
|
|
96
|
-
return this.request('DELETE', `/api/thesis/${id}/publish`);
|
|
97
|
-
}
|
|
98
|
-
async augmentTree(id, dryRun = false) {
|
|
99
|
-
const qs = dryRun ? '?dryRun=true' : '';
|
|
100
|
-
return this.request('POST', `/api/thesis/${id}/augment${qs}`);
|
|
101
|
-
}
|
|
102
|
-
// ── Strategy operations ──
|
|
103
|
-
async getStrategies(id, status) {
|
|
104
|
-
const qs = status ? `?status=${status}` : '';
|
|
105
|
-
return this.request('GET', `/api/thesis/${id}/strategies${qs}`);
|
|
106
|
-
}
|
|
107
|
-
async createStrategyAPI(id, data) {
|
|
108
|
-
return this.request('POST', `/api/thesis/${id}/strategies`, data);
|
|
109
|
-
}
|
|
110
|
-
async updateStrategyAPI(thesisId, strategyId, data) {
|
|
111
|
-
return this.request('PATCH', `/api/thesis/${thesisId}/strategies/${strategyId}`, data);
|
|
112
|
-
}
|
|
113
|
-
async deleteStrategyAPI(thesisId, strategyId) {
|
|
114
|
-
return this.request('DELETE', `/api/thesis/${thesisId}/strategies/${strategyId}`);
|
|
115
|
-
}
|
|
116
|
-
// ── X (Twitter) operations ──
|
|
117
|
-
async searchX(query, opts) {
|
|
118
|
-
const mode = opts?.mode || 'summary';
|
|
119
|
-
const hours = opts?.hours || 24;
|
|
120
|
-
const limit = opts?.limit || 20;
|
|
121
|
-
return this.request('GET', `/api/x/search?q=${encodeURIComponent(query)}&mode=${mode}&hours=${hours}&limit=${limit}`);
|
|
122
|
-
}
|
|
123
|
-
async getXVolume(query, opts) {
|
|
124
|
-
const hours = opts?.hours || 72;
|
|
125
|
-
const granularity = opts?.granularity || 'hour';
|
|
126
|
-
return this.request('GET', `/api/x/volume?q=${encodeURIComponent(query)}&hours=${hours}&granularity=${granularity}`);
|
|
127
|
-
}
|
|
128
|
-
async searchXNews(query, opts) {
|
|
129
|
-
const limit = opts?.limit || 10;
|
|
130
|
-
return this.request('GET', `/api/x/news?q=${encodeURIComponent(query)}&limit=${limit}`);
|
|
131
|
-
}
|
|
132
|
-
async getXAccount(username, opts) {
|
|
133
|
-
const user = username.replace(/^@/, '');
|
|
134
|
-
const hours = opts?.hours || 24;
|
|
135
|
-
const limit = opts?.limit || 20;
|
|
136
|
-
return this.request('GET', `/api/x/account?username=${user}&hours=${hours}&limit=${limit}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
exports.SFClient = SFClient;
|
|
140
|
-
// ===== Kalshi Public API (no auth) =====
|
|
141
|
-
async function kalshiGet(path, params) {
|
|
142
|
-
const url = new URL(`${KALSHI_BASE}${path}`);
|
|
143
|
-
if (params) {
|
|
144
|
-
for (const [k, v] of Object.entries(params)) {
|
|
145
|
-
if (v !== undefined && v !== '')
|
|
146
|
-
url.searchParams.set(k, v);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const res = await fetch(url.toString());
|
|
150
|
-
if (!res.ok) {
|
|
151
|
-
throw new Error(`Kalshi API ${res.status}: ${await res.text()}`);
|
|
152
|
-
}
|
|
153
|
-
return res.json();
|
|
154
|
-
}
|
|
155
|
-
async function kalshiFetchAllSeries() {
|
|
156
|
-
const data = await kalshiGet('/series', { include_volume: 'true' });
|
|
157
|
-
return data.series || [];
|
|
158
|
-
}
|
|
159
|
-
async function kalshiFetchEvents(seriesTicker) {
|
|
160
|
-
const data = await kalshiGet('/events', {
|
|
161
|
-
series_ticker: seriesTicker,
|
|
162
|
-
status: 'open',
|
|
163
|
-
with_nested_markets: 'true',
|
|
164
|
-
limit: '200',
|
|
165
|
-
});
|
|
166
|
-
return data.events || [];
|
|
167
|
-
}
|
|
168
|
-
async function kalshiFetchMarket(ticker) {
|
|
169
|
-
const data = await kalshiGet(`/markets/${ticker}`);
|
|
170
|
-
return data.market || data;
|
|
171
|
-
}
|
|
172
|
-
async function kalshiFetchMarketsBySeries(seriesTicker) {
|
|
173
|
-
const data = await kalshiGet('/markets', {
|
|
174
|
-
series_ticker: seriesTicker,
|
|
175
|
-
status: 'open',
|
|
176
|
-
limit: '200',
|
|
177
|
-
});
|
|
178
|
-
return data.markets || [];
|
|
179
|
-
}
|
|
180
|
-
async function kalshiFetchMarketsByEvent(eventTicker) {
|
|
181
|
-
const data = await kalshiGet('/markets', {
|
|
182
|
-
event_ticker: eventTicker,
|
|
183
|
-
status: 'open',
|
|
184
|
-
limit: '1000',
|
|
185
|
-
});
|
|
186
|
-
return data.markets || [];
|
|
187
|
-
}
|
|
188
|
-
// ===== Public Endpoints (no auth) =====
|
|
189
|
-
const SF_PUBLIC_BASE = 'https://simplefunctions.dev';
|
|
190
|
-
async function fetchGlobalContext() {
|
|
191
|
-
const res = await fetch(`${SF_PUBLIC_BASE}/api/public/context`);
|
|
192
|
-
if (!res.ok)
|
|
193
|
-
throw new Error(`Context API error: ${res.status}`);
|
|
194
|
-
return res.json();
|
|
195
|
-
}
|
|
196
|
-
async function fetchQuery(q) {
|
|
197
|
-
const res = await fetch(`${SF_PUBLIC_BASE}/api/public/query?q=${encodeURIComponent(q)}`);
|
|
198
|
-
if (!res.ok)
|
|
199
|
-
throw new Error(`Query API error: ${res.status}`);
|
|
200
|
-
return res.json();
|
|
201
|
-
}
|
|
202
|
-
async function fetchTraditionalMarkets() {
|
|
203
|
-
const ctx = await fetchGlobalContext();
|
|
204
|
-
return ctx.traditionalMarkets || [];
|
|
205
|
-
}
|
package/dist/client.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/client.test.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const client_js_1 = require("./client.js");
|
|
5
|
-
const mockFetch = vitest_1.vi.fn();
|
|
6
|
-
vitest_1.vi.stubGlobal('fetch', mockFetch);
|
|
7
|
-
(0, vitest_1.beforeEach)(() => {
|
|
8
|
-
mockFetch.mockReset();
|
|
9
|
-
delete process.env.SF_API_KEY;
|
|
10
|
-
delete process.env.SF_API_URL;
|
|
11
|
-
});
|
|
12
|
-
(0, vitest_1.describe)('SFClient constructor', () => {
|
|
13
|
-
(0, vitest_1.it)('throws when no API key provided', () => {
|
|
14
|
-
(0, vitest_1.expect)(() => new client_js_1.SFClient()).toThrow('API key required');
|
|
15
|
-
});
|
|
16
|
-
(0, vitest_1.it)('accepts explicit API key', () => {
|
|
17
|
-
(0, vitest_1.expect)(() => new client_js_1.SFClient('sf_live_test')).not.toThrow();
|
|
18
|
-
});
|
|
19
|
-
(0, vitest_1.it)('reads from env', () => {
|
|
20
|
-
process.env.SF_API_KEY = 'sf_live_env';
|
|
21
|
-
(0, vitest_1.expect)(() => new client_js_1.SFClient()).not.toThrow();
|
|
22
|
-
});
|
|
23
|
-
(0, vitest_1.it)('strips trailing slash from base URL', () => {
|
|
24
|
-
const client = new client_js_1.SFClient('key', 'https://example.com/');
|
|
25
|
-
mockFetch.mockResolvedValue({ ok: true, json: () => Promise.resolve({ theses: [] }) });
|
|
26
|
-
client.listTheses();
|
|
27
|
-
(0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://example.com/api/thesis', vitest_1.expect.any(Object));
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
(0, vitest_1.describe)('SFClient requests', () => {
|
|
31
|
-
let client;
|
|
32
|
-
(0, vitest_1.beforeEach)(() => {
|
|
33
|
-
client = new client_js_1.SFClient('sf_live_testkey', 'https://api.test.com');
|
|
34
|
-
});
|
|
35
|
-
(0, vitest_1.it)('sends GET with correct headers', async () => {
|
|
36
|
-
mockFetch.mockResolvedValue({
|
|
37
|
-
ok: true,
|
|
38
|
-
json: () => Promise.resolve({ theses: [] }),
|
|
39
|
-
});
|
|
40
|
-
await client.listTheses();
|
|
41
|
-
(0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://api.test.com/api/thesis', vitest_1.expect.objectContaining({
|
|
42
|
-
method: 'GET',
|
|
43
|
-
headers: vitest_1.expect.objectContaining({
|
|
44
|
-
Authorization: 'Bearer sf_live_testkey',
|
|
45
|
-
'Content-Type': 'application/json',
|
|
46
|
-
}),
|
|
47
|
-
}));
|
|
48
|
-
});
|
|
49
|
-
(0, vitest_1.it)('sends POST with JSON body', async () => {
|
|
50
|
-
mockFetch.mockResolvedValue({
|
|
51
|
-
ok: true,
|
|
52
|
-
json: () => Promise.resolve({ id: '123' }),
|
|
53
|
-
});
|
|
54
|
-
await client.injectSignal('thesis1', 'news', 'breaking news');
|
|
55
|
-
const call = mockFetch.mock.calls[0];
|
|
56
|
-
(0, vitest_1.expect)(call[1].method).toBe('POST');
|
|
57
|
-
(0, vitest_1.expect)(JSON.parse(call[1].body)).toEqual({
|
|
58
|
-
type: 'news',
|
|
59
|
-
content: 'breaking news',
|
|
60
|
-
source: 'cli',
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
(0, vitest_1.it)('throws on non-ok response', async () => {
|
|
64
|
-
mockFetch.mockResolvedValue({
|
|
65
|
-
ok: false,
|
|
66
|
-
status: 404,
|
|
67
|
-
text: () => Promise.resolve('Not found'),
|
|
68
|
-
});
|
|
69
|
-
await (0, vitest_1.expect)(client.getThesis('bad-id')).rejects.toThrow('API error 404');
|
|
70
|
-
});
|
|
71
|
-
(0, vitest_1.it)('getContext calls correct path', async () => {
|
|
72
|
-
mockFetch.mockResolvedValue({
|
|
73
|
-
ok: true,
|
|
74
|
-
json: () => Promise.resolve({}),
|
|
75
|
-
});
|
|
76
|
-
await client.getContext('abc123');
|
|
77
|
-
(0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith('https://api.test.com/api/thesis/abc123/context', vitest_1.expect.any(Object));
|
|
78
|
-
});
|
|
79
|
-
(0, vitest_1.it)('evaluate sends POST', async () => {
|
|
80
|
-
mockFetch.mockResolvedValue({
|
|
81
|
-
ok: true,
|
|
82
|
-
json: () => Promise.resolve({ evaluation: {} }),
|
|
83
|
-
});
|
|
84
|
-
await client.evaluate('thesis1');
|
|
85
|
-
const call = mockFetch.mock.calls[0];
|
|
86
|
-
(0, vitest_1.expect)(call[1].method).toBe('POST');
|
|
87
|
-
(0, vitest_1.expect)(call[0]).toBe('https://api.test.com/api/thesis/thesis1/evaluate');
|
|
88
|
-
});
|
|
89
|
-
});
|
package/dist/commands/agent.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* sf agent — Interactive TUI agent powered by pi-tui + pi-agent-core.
|
|
3
|
-
*
|
|
4
|
-
* Layout:
|
|
5
|
-
* [Header overlay] — thesis id, confidence, model
|
|
6
|
-
* [Spacer] — room for header
|
|
7
|
-
* [Chat container] — messages (user, assistant, tool, system)
|
|
8
|
-
* [Editor] — multi-line input with slash command autocomplete
|
|
9
|
-
* [Spacer] — room for footer
|
|
10
|
-
* [Footer overlay] — tokens, cost, tool count, /help hint
|
|
11
|
-
*
|
|
12
|
-
* Slash commands (bypass LLM):
|
|
13
|
-
* /help /tree /edges /pos /eval /model /clear /exit
|
|
14
|
-
*/
|
|
15
|
-
export declare function agentCommand(thesisId?: string, opts?: {
|
|
16
|
-
model?: string;
|
|
17
|
-
modelKey?: string;
|
|
18
|
-
newSession?: boolean;
|
|
19
|
-
noTui?: boolean;
|
|
20
|
-
}): Promise<void>;
|