@vike-io/cli 0.14.0 → 0.16.0
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/CHANGELOG.md +30 -0
- package/README.md +32 -14
- package/package.json +4 -4
- package/skills/vike/SKILL.md +75 -37
- package/skills/vike-alerts-setup/SKILL.md +42 -10
- package/skills/vike-alerts-webhook/SKILL.md +18 -10
- package/skills/vike-candles/SKILL.md +10 -2
- package/skills/vike-core/SKILL.md +6 -3
- package/skills/vike-daily-brief/SKILL.md +68 -0
- package/skills/vike-follow-the-money/SKILL.md +60 -0
- package/skills/vike-hl-asset-briefing/SKILL.md +48 -0
- package/skills/vike-hl-builder-intel/SKILL.md +39 -0
- package/skills/vike-hl-cohort-backtest/SKILL.md +61 -0
- package/skills/vike-hl-cohort-positioning/SKILL.md +58 -0
- package/skills/vike-hl-liquidation-radar/SKILL.md +49 -0
- package/skills/vike-hl-position-match/SKILL.md +4 -3
- package/skills/vike-hl-top-traders/SKILL.md +22 -9
- package/skills/vike-hl-trader-profile/SKILL.md +65 -0
- package/skills/vike-perp-crowding/SKILL.md +49 -0
- package/skills/vike-perp-funding/SKILL.md +4 -1
- package/skills/vike-perp-overview/SKILL.md +23 -3
- package/skills/vike-pm-l2-archive/SKILL.md +50 -0
- package/skills/vike-pm-market-diligence/SKILL.md +60 -0
- package/skills/vike-polymarket-market-detail/SKILL.md +20 -15
- package/skills/vike-polymarket-markets/SKILL.md +2 -1
- package/skills/vike-polymarket-smart-money/SKILL.md +1 -0
- package/skills/vike-polymarket-trader/SKILL.md +2 -1
- package/skills/vike-smart-money-discovery/SKILL.md +4 -3
- package/skills/vike-stream/SKILL.md +99 -0
- package/skills/vike-token-holder-diligence/SKILL.md +58 -0
- package/skills/vike-token-holders/SKILL.md +6 -4
- package/skills/vike-token-research/SKILL.md +6 -6
- package/skills/vike-token-screener/SKILL.md +3 -3
- package/skills/vike-token-search/SKILL.md +2 -1
- package/skills/vike-token-smart-money-trend/SKILL.md +57 -0
- package/skills/vike-token-transfers/SKILL.md +8 -6
- package/skills/vike-wallet-balances/SKILL.md +9 -7
- package/skills/vike-wallet-batch/SKILL.md +3 -3
- package/skills/vike-wallet-compare/SKILL.md +2 -2
- package/skills/vike-wallet-counterparties/SKILL.md +2 -2
- package/skills/vike-wallet-discover/SKILL.md +3 -1
- package/skills/vike-wallet-ens/SKILL.md +2 -2
- package/skills/vike-wallet-label-provenance/SKILL.md +5 -4
- package/skills/vike-wallet-pnl-history/SKILL.md +2 -2
- package/skills/vike-wallet-portfolio/SKILL.md +10 -8
- package/skills/vike-wallet-summary/SKILL.md +6 -6
- package/skills/vike-wallet-trace/SKILL.md +4 -3
- package/skills/vike-wallet-transactions/SKILL.md +2 -2
- package/skills/vike-wallet-who-is/SKILL.md +50 -0
- package/skills/vike-wallets-related/SKILL.md +52 -0
- package/skills.sh.json +34 -12
- package/src/commands/alerts.js +85 -15
- package/src/commands/call.js +32 -0
- package/src/commands/candles.js +11 -15
- package/src/commands/doctor.js +4 -4
- package/src/commands/hl.js +274 -0
- package/src/commands/perp.js +5 -5
- package/src/commands/polymarket.js +105 -5
- package/src/commands/search.js +10 -0
- package/src/commands/stream.js +308 -0
- package/src/commands/token.js +2 -0
- package/src/commands/tool-command.js +27 -0
- package/src/commands/wallet.js +21 -0
- package/src/index.js +10 -1
- package/src/mcp-client.js +37 -16
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vike-wallets-related
|
|
3
|
+
description: Gather evidence on whether two wallets, or a wallet and its possible siblings, belong to the same entity - labels, first funders, shared counterparties and tokens with exchanges and routers removed, direct links, a depth-2 trace - with confidence tiers. Use when the user asks "are these wallets the same person" / "find wallets related to 0x..." / "is this a sybil cluster" / "does B belong to A".
|
|
4
|
+
allowed-tools: Bash(vike-data:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vike-wallets-related
|
|
8
|
+
|
|
9
|
+
Evidence, never proof: no tool exposes a deposit-address owner or a cluster id. Cap the cluster at 10 wallets and ask before widening. About 20-30 credits.
|
|
10
|
+
|
|
11
|
+
## Chain
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
vike-data labels $A --json # 1 A and B: same entity already?
|
|
15
|
+
vike-data labels $B --json
|
|
16
|
+
vike-data wallet first-funder $A --json # 2 earliest inbound coin and token, sender labelled
|
|
17
|
+
vike-data wallet first-funder $B --json
|
|
18
|
+
vike-data wallet compare $A $B --window 90d --limit 50 --json # 3, up to ~20 s on busy wallets
|
|
19
|
+
vike-data wallet batch <shared counterparties> --json # 2 label them, drop exchanges and routers
|
|
20
|
+
vike-data wallet trace $A --depth 2 --width 10 --window 90d --min-usd 1000 --json # 4 is B in A's neighbourhood?
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Add `--chain bsc|base|hyperevm` to every wallet command when the wallets live there (default ethereum); `labels` reads the Ethereum label table, so on other chains use `wallet batch --chain`.
|
|
24
|
+
|
|
25
|
+
## Siblings mode (only A is known)
|
|
26
|
+
|
|
27
|
+
`wallet counterparties $A --window 90d --limit 50`, label them with `wallet batch`, drop `cex`, `dex`, `market_maker` and contract rows, keep the highest-volume unlabelled or `user` wallets, then `wallet compare $A <candidate>` for the top 3-5, `wallet first-funder` on each, and `wallet trace` once. Stop at 10 wallets.
|
|
28
|
+
|
|
29
|
+
## Reading
|
|
30
|
+
|
|
31
|
+
- `compare` returns `shared_counterparties` (`wallet`, `a_volume_usd`, `b_volume_usd`, `entity`, `wallet_type`) and `shared_tokens`. The big shared rows are almost always an exchange, a router or USDT/USDC/the native coin: in a live market-maker pair the top shared counterparties were Binance, another wallet of the same firm and Coinbase, the shared tokens ETH, USDT and USDC. **Remove CEX, router and stablecoin overlap before counting anything.**
|
|
32
|
+
- **Direct links**: B appearing as a node of A's trace (an edge with `out_usd` or `in_usd` > 0 between them) is stronger than any overlap.
|
|
33
|
+
- **First funders**: the same non-exchange sender in `first_native_in` or `first_token_in` of both is a link; the same exchange hot wallet is not (everyone withdrawing from it shares it). Native rows hold top-level sends only and history starts per chain (`coverage.history_from`): no match is not evidence against.
|
|
34
|
+
|
|
35
|
+
| Tier | Evidence |
|
|
36
|
+
|---|---|
|
|
37
|
+
| High | the same entity in `labels` / `batch` for both; or a direct transfer between them AND a shared non-CEX counterparty |
|
|
38
|
+
| Medium | several shared non-exchange counterparties AND shared niche tokens (not stablecoins/ETH); one direct link of size; or the same non-exchange first funder |
|
|
39
|
+
| Low / none | overlap only through exchanges, routers, stablecoins; matching ENS style; funding from the same CEX |
|
|
40
|
+
|
|
41
|
+
State the tier and the list of what was removed.
|
|
42
|
+
|
|
43
|
+
## Anti-patterns
|
|
44
|
+
|
|
45
|
+
- Don't claim "same person" from a shared CEX hot wallet: everyone who uses that exchange shares it.
|
|
46
|
+
- Don't trace through exchanges or past 10 wallets; don't trace at `--min-usd 0`.
|
|
47
|
+
- Don't call two wallets unrelated from one chain: run the commands on the chain where both are active (`wallet balances` shows where the value is).
|
|
48
|
+
|
|
49
|
+
## Pairs well with
|
|
50
|
+
|
|
51
|
+
- `vike-wallet-who-is`, `vike-wallet-compare`, `vike-wallet-counterparties`, `vike-wallet-trace`, `vike-wallet-batch`
|
|
52
|
+
- `vike-polymarket-trader`: for Polymarket wallets, `polymarket wallet` returns `correlated`, the wallets trading the same markets
|
package/skills.sh.json
CHANGED
|
@@ -4,35 +4,41 @@
|
|
|
4
4
|
"groupings": [
|
|
5
5
|
{
|
|
6
6
|
"title": "Quick start",
|
|
7
|
-
"description": "Start here. The umbrella skill routes user questions to the right specialized skill below; vike-core covers install and auth.",
|
|
7
|
+
"description": "Start here. The umbrella skill routes user questions to the right specialized skill below; vike-core covers install and auth; vike-daily-brief is a cheap cross-market rundown.",
|
|
8
8
|
"skills": [
|
|
9
9
|
"vike",
|
|
10
|
-
"vike-core"
|
|
10
|
+
"vike-core",
|
|
11
|
+
"vike-daily-brief"
|
|
11
12
|
]
|
|
12
13
|
},
|
|
13
14
|
{
|
|
14
15
|
"title": "Tokens",
|
|
15
|
-
"description": "Resolve, screen, and research tokens on Ethereum, BSC and
|
|
16
|
+
"description": "Resolve, screen, and research tokens on Ethereum, BSC, Base and HyperEVM. Smart-money inflow and its trend over time (Ethereum), holders and holder due diligence, top buyers and sellers.",
|
|
16
17
|
"skills": [
|
|
17
18
|
"vike-token-search",
|
|
18
19
|
"vike-token-research",
|
|
19
20
|
"vike-token-transfers",
|
|
20
21
|
"vike-token-holders",
|
|
22
|
+
"vike-token-holder-diligence",
|
|
21
23
|
"vike-token-screener",
|
|
22
|
-
"vike-smart-money-discovery"
|
|
24
|
+
"vike-smart-money-discovery",
|
|
25
|
+
"vike-token-smart-money-trend"
|
|
23
26
|
]
|
|
24
27
|
},
|
|
25
28
|
{
|
|
26
29
|
"title": "Wallets",
|
|
27
|
-
"description": "
|
|
30
|
+
"description": "Who a wallet is, per-wallet profile, flows, counterparty graphs, incident tracing, relatedness evidence, ENS, batch labelling, label provenance, on Ethereum, BSC, Base and HyperEVM.",
|
|
28
31
|
"skills": [
|
|
32
|
+
"vike-wallet-who-is",
|
|
29
33
|
"vike-wallet-summary",
|
|
30
34
|
"vike-wallet-portfolio",
|
|
31
35
|
"vike-wallet-discover",
|
|
32
36
|
"vike-wallet-transactions",
|
|
33
37
|
"vike-wallet-counterparties",
|
|
34
38
|
"vike-wallet-trace",
|
|
39
|
+
"vike-follow-the-money",
|
|
35
40
|
"vike-wallet-compare",
|
|
41
|
+
"vike-wallets-related",
|
|
36
42
|
"vike-wallet-batch",
|
|
37
43
|
"vike-wallet-pnl-history",
|
|
38
44
|
"vike-wallet-balances",
|
|
@@ -42,18 +48,25 @@
|
|
|
42
48
|
},
|
|
43
49
|
{
|
|
44
50
|
"title": "CEX perps",
|
|
45
|
-
"description": "Funding-rate arb and per-symbol venue comparison,
|
|
51
|
+
"description": "Funding-rate arb and per-symbol venue comparison, cross-venue perp price gaps, open interest and long/short lean per venue, and a crowding read that nets open interest against price.",
|
|
46
52
|
"skills": [
|
|
47
53
|
"vike-perp-funding",
|
|
48
|
-
"vike-perp-overview"
|
|
54
|
+
"vike-perp-overview",
|
|
55
|
+
"vike-perp-crowding"
|
|
49
56
|
]
|
|
50
57
|
},
|
|
51
58
|
{
|
|
52
59
|
"title": "Hyperliquid perps",
|
|
53
|
-
"description": "Top traders
|
|
60
|
+
"description": "Top traders and leaderboards, one-wallet profiles, wallet-cohort positioning and its backtest method, single-symbol briefings, liquidation risk, builder codes, and share-card reverse-lookup.",
|
|
54
61
|
"skills": [
|
|
55
62
|
"vike-hl-top-traders",
|
|
56
|
-
"vike-hl-
|
|
63
|
+
"vike-hl-trader-profile",
|
|
64
|
+
"vike-hl-position-match",
|
|
65
|
+
"vike-hl-cohort-positioning",
|
|
66
|
+
"vike-hl-cohort-backtest",
|
|
67
|
+
"vike-hl-asset-briefing",
|
|
68
|
+
"vike-hl-liquidation-radar",
|
|
69
|
+
"vike-hl-builder-intel"
|
|
57
70
|
]
|
|
58
71
|
},
|
|
59
72
|
{
|
|
@@ -65,21 +78,30 @@
|
|
|
65
78
|
},
|
|
66
79
|
{
|
|
67
80
|
"title": "Polymarket",
|
|
68
|
-
"description": "Prediction-market discovery, single-market deep-dives, trader profiles,
|
|
81
|
+
"description": "Prediction-market discovery, single-market deep-dives and due diligence (order book, tape, trades with wallets, holders, on-chain settlement), trader profiles, smart-money signals, and the free L2 Parquet archive.",
|
|
69
82
|
"skills": [
|
|
70
83
|
"vike-polymarket-markets",
|
|
71
84
|
"vike-polymarket-market-detail",
|
|
85
|
+
"vike-pm-market-diligence",
|
|
72
86
|
"vike-polymarket-trader",
|
|
73
|
-
"vike-polymarket-smart-money"
|
|
87
|
+
"vike-polymarket-smart-money",
|
|
88
|
+
"vike-pm-l2-archive"
|
|
74
89
|
]
|
|
75
90
|
},
|
|
76
91
|
{
|
|
77
92
|
"title": "Alerts",
|
|
78
|
-
"description": "Create, list, edit, delete
|
|
93
|
+
"description": "Create, list, edit, delete transfer alerts (a token or one wallet, USD thresholds) and Hyperliquid alerts; read what fired; HTTPS webhooks with HMAC delivery.",
|
|
79
94
|
"skills": [
|
|
80
95
|
"vike-alerts-setup",
|
|
81
96
|
"vike-alerts-webhook"
|
|
82
97
|
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"title": "Live streams",
|
|
101
|
+
"description": "Hyperliquid, HL cohort, on-chain and Polymarket events as they happen over WebSocket, as NDJSON, resumed by cursor.",
|
|
102
|
+
"skills": [
|
|
103
|
+
"vike-stream"
|
|
104
|
+
]
|
|
83
105
|
}
|
|
84
106
|
]
|
|
85
107
|
}
|
package/src/commands/alerts.js
CHANGED
|
@@ -1,11 +1,45 @@
|
|
|
1
1
|
import { callTool } from '../mcp-client.js';
|
|
2
2
|
import { emit, emitError } from '../format.js';
|
|
3
3
|
import { parseBool, parseInt10 } from '../util.js';
|
|
4
|
+
import { addTool } from './tool-command.js';
|
|
5
|
+
|
|
6
|
+
// What a rule watches beyond token and USD bounds: a transfer alert's address, and the Hyperliquid
|
|
7
|
+
// parameters. Which alert type takes which is the server's to check; it names the fix.
|
|
8
|
+
const TARGET_OPTIONS = [
|
|
9
|
+
['--address <a>', 'transfer: one wallet to watch (0x + 40 hex), sent or received'],
|
|
10
|
+
['--address-role <r>', 'transfer: any | from | to (default any; needs --address)'],
|
|
11
|
+
['--wallet <a>', 'Hyperliquid account (0x + 40 hex): required by hl_wallet and hl_liq_proximity, optional for hl_liquidation'],
|
|
12
|
+
['--actions <a...>', 'hl_wallet: open close flip increase reduce (default all but reduce)'],
|
|
13
|
+
['--pnl-cohorts <c...>', 'hl_cohort_fill, hl_liquidation: PnL cohorts, e.g. "3x smart" "2x smart"'],
|
|
14
|
+
['--size-cohorts <c...>', 'hl_cohort_fill, hl_liquidation: size cohorts, e.g. "4x whale" whale'],
|
|
15
|
+
['--index <i>', 'hl_cohort_bias (required): smi | wsi | smart_bias | whale_bias | smi_wsi_gap'],
|
|
16
|
+
['--threshold <n>', 'hl_cohort_bias: level to cross (default 0); hl_liq_proximity: share of the way to liquidation, 0-1 (default 0.8)'],
|
|
17
|
+
['--band <n>', 'hl_cohort_bias, hl_liq_proximity: hysteresis, > 0 (default 0.1)'],
|
|
18
|
+
['--direction <d>', 'hl_cohort_bias: up | down | both (default both)'],
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
// `--pnl-cohorts ''` clears the list: send [] (the server refuses ['']).
|
|
22
|
+
const list = (v) => (Array.isArray(v) && v.every((x) => x === '') ? [] : v);
|
|
23
|
+
|
|
24
|
+
function targetArgs(opts) {
|
|
25
|
+
return {
|
|
26
|
+
address: opts.address,
|
|
27
|
+
address_role: opts.addressRole,
|
|
28
|
+
wallet: opts.wallet,
|
|
29
|
+
actions: list(opts.actions),
|
|
30
|
+
pnl_cohorts: list(opts.pnlCohorts),
|
|
31
|
+
size_cohorts: list(opts.sizeCohorts),
|
|
32
|
+
index: opts.index,
|
|
33
|
+
threshold: opts.threshold,
|
|
34
|
+
band: opts.band,
|
|
35
|
+
direction: opts.direction,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
4
38
|
|
|
5
39
|
export function registerAlerts(program) {
|
|
6
40
|
const cmd = program
|
|
7
41
|
.command('alerts')
|
|
8
|
-
.description('Manage on-chain
|
|
42
|
+
.description('Manage alerts: on-chain transfers and Hyperliquid fills, liquidations, cohort bias and liquidation proximity');
|
|
9
43
|
|
|
10
44
|
cmd
|
|
11
45
|
.command('list')
|
|
@@ -38,7 +72,7 @@ export function registerAlerts(program) {
|
|
|
38
72
|
|
|
39
73
|
cmd
|
|
40
74
|
.command('channels')
|
|
41
|
-
.description('List your enabled notification channels (email/
|
|
75
|
+
.description('List your enabled notification channels (email/webhook)')
|
|
42
76
|
.option('--json', 'Emit JSON')
|
|
43
77
|
.action(async (opts) => {
|
|
44
78
|
try {
|
|
@@ -47,25 +81,31 @@ export function registerAlerts(program) {
|
|
|
47
81
|
} catch (err) { emitError(err, opts); }
|
|
48
82
|
});
|
|
49
83
|
|
|
50
|
-
cmd
|
|
84
|
+
const create = cmd
|
|
51
85
|
.command('create')
|
|
52
|
-
.description('Create
|
|
86
|
+
.description('Create an alert: an on-chain transfer alert (default) or a Hyperliquid alert (--type)')
|
|
53
87
|
.requiredOption('--label <l>', 'Alert label (user-visible name)')
|
|
54
|
-
.option('--
|
|
55
|
-
.option('--
|
|
56
|
-
|
|
57
|
-
.option('--
|
|
58
|
-
.option('--
|
|
59
|
-
.option('--
|
|
88
|
+
.option('--type <t>', 'transfer | hl_wallet | hl_cohort_fill | hl_liquidation | hl_cohort_bias | hl_liq_proximity (default transfer)')
|
|
89
|
+
.option('--token <sym>', 'transfer: token ticker, UPPERCASE (e.g. USDC); Hyperliquid: the coin (BTC, kPEPE), required by hl_cohort_bias')
|
|
90
|
+
// No default chain: a Hyperliquid alert refuses one.
|
|
91
|
+
.option('--chain <c>', 'transfer only: eth | bsc | base | hyperevm (default eth)')
|
|
92
|
+
.option('--min-usd <n>', 'transfer: minimum USD value; Hyperliquid: fill or liquidation floor (hl_cohort_fill: required, >= 10000)')
|
|
93
|
+
.option('--max-usd <n>', 'transfer only: maximum USD value');
|
|
94
|
+
for (const [flags, text] of TARGET_OPTIONS) create.option(flags, text);
|
|
95
|
+
create
|
|
96
|
+
.option('--channel <c...>', 'Notification channel(s): email, webhook (Hyperliquid: webhook, or none and read them with `alerts events`)')
|
|
97
|
+
.option('--cooldown <min>', 'Token-wide transfer alerts: minimum gap between notifications (minutes)', '60')
|
|
60
98
|
.option('--json', 'Emit JSON')
|
|
61
99
|
.action(async (opts) => {
|
|
62
100
|
try {
|
|
63
101
|
const r = await callTool('alerts_create', {
|
|
64
102
|
label: opts.label,
|
|
103
|
+
alert_type: opts.type,
|
|
65
104
|
token_symbol: opts.token,
|
|
66
105
|
chain: opts.chain,
|
|
67
106
|
min_value_usd: opts.minUsd,
|
|
68
107
|
max_value_usd: opts.maxUsd,
|
|
108
|
+
...targetArgs(opts),
|
|
69
109
|
channels: opts.channel,
|
|
70
110
|
cooldown_minutes: parseInt10(opts.cooldown, 60),
|
|
71
111
|
});
|
|
@@ -73,27 +113,29 @@ export function registerAlerts(program) {
|
|
|
73
113
|
} catch (err) { emitError(err, opts); }
|
|
74
114
|
});
|
|
75
115
|
|
|
76
|
-
cmd
|
|
116
|
+
const edit = cmd
|
|
77
117
|
.command('edit <alert_id>')
|
|
78
|
-
.description('Update an alert (only fields you pass are modified)')
|
|
118
|
+
.description('Update an alert (only fields you pass are modified; \'\' clears an optional one)')
|
|
79
119
|
.option('--label <l>')
|
|
80
120
|
.option('--token <sym>')
|
|
81
121
|
.option('--chain <c>')
|
|
82
122
|
.option('--min-usd <n>')
|
|
83
|
-
.option('--max-usd <n>')
|
|
123
|
+
.option('--max-usd <n>');
|
|
124
|
+
for (const [flags, text] of TARGET_OPTIONS) edit.option(flags, text);
|
|
125
|
+
edit
|
|
84
126
|
.option('--channel <c...>')
|
|
85
127
|
.option('--cooldown <min>')
|
|
86
128
|
.option('--active <bool>', 'Pause/resume (true|false)')
|
|
87
129
|
.option('--json', 'Emit JSON')
|
|
88
130
|
.action(async (alertId, opts) => {
|
|
89
131
|
try {
|
|
90
|
-
const payload = { alert_id: alertId };
|
|
132
|
+
const payload = { alert_id: alertId, ...targetArgs(opts) };
|
|
91
133
|
if (opts.label !== undefined) payload.label = opts.label;
|
|
92
134
|
if (opts.token !== undefined) payload.token_symbol = opts.token;
|
|
93
135
|
if (opts.chain !== undefined) payload.chain = opts.chain;
|
|
94
136
|
if (opts.minUsd !== undefined) payload.min_value_usd = opts.minUsd;
|
|
95
137
|
if (opts.maxUsd !== undefined) payload.max_value_usd = opts.maxUsd;
|
|
96
|
-
if (opts.channel !== undefined) payload.channels = opts.channel;
|
|
138
|
+
if (opts.channel !== undefined) payload.channels = list(opts.channel);
|
|
97
139
|
if (opts.cooldown !== undefined) payload.cooldown_minutes = opts.cooldown;
|
|
98
140
|
if (opts.active !== undefined) payload.is_active = parseBool(opts.active, true);
|
|
99
141
|
const r = await callTool('alerts_edit', payload);
|
|
@@ -115,4 +157,32 @@ export function registerAlerts(program) {
|
|
|
115
157
|
emit(r, opts);
|
|
116
158
|
} catch (err) { emitError(err, opts); }
|
|
117
159
|
});
|
|
160
|
+
|
|
161
|
+
addTool(cmd, 'events', {
|
|
162
|
+
tool: 'alerts_events',
|
|
163
|
+
desc: 'Events your alerts produced, oldest first, with each delivery\'s status (kept 15 days)',
|
|
164
|
+
options: [
|
|
165
|
+
['--cursor <c>', 'next_cursor from the previous page (an empty page returns the same one)'],
|
|
166
|
+
['--limit <n>', 'Events per page, 1-500 (default 100)'],
|
|
167
|
+
['--rule-id <id>', 'Only the events of this alert'],
|
|
168
|
+
],
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
addTool(cmd, 'resend <delivery_id>', {
|
|
172
|
+
tool: 'alerts_resend_delivery',
|
|
173
|
+
args: ['delivery_id'],
|
|
174
|
+
desc: 'Send one delivery again (its id from an event\'s delivery list in `alerts events`)',
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
addTool(cmd, 'rotate-secret <channel_id>', {
|
|
178
|
+
tool: 'alerts_rotate_webhook_secret',
|
|
179
|
+
args: ['channel_id'],
|
|
180
|
+
desc: 'New signing secret for a webhook channel; the old one keeps signing for 24 hours',
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
addTool(cmd, 'test-webhook <channel_id>', {
|
|
184
|
+
tool: 'alerts_test_webhook',
|
|
185
|
+
args: ['channel_id'],
|
|
186
|
+
desc: 'Send the signed test event to a webhook channel again',
|
|
187
|
+
});
|
|
118
188
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { callTool } from '../mcp-client.js';
|
|
3
|
+
import { emitError } from '../format.js';
|
|
4
|
+
|
|
5
|
+
export function registerCall(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('call <tool>')
|
|
8
|
+
.description('Call any MCP tool by name and print its raw result (see `vike-data schema --pretty` for the tools and their arguments)')
|
|
9
|
+
.option('--args <json>', 'Tool arguments as a JSON object, e.g. \'{"symbol":"BTC"}\'')
|
|
10
|
+
.option('--args-file <path>', 'Read the arguments JSON from a file (- for stdin)')
|
|
11
|
+
.option('--timeout <s>', 'Seconds to wait for the answer', '60')
|
|
12
|
+
.option('--json', 'Errors as JSON on stdout (the result is JSON either way)')
|
|
13
|
+
.action(async (tool, opts) => {
|
|
14
|
+
try {
|
|
15
|
+
const text = (opts.argsFile !== undefined
|
|
16
|
+
? readFileSync(opts.argsFile === '-' ? 0 : opts.argsFile, 'utf8')
|
|
17
|
+
: (opts.args ?? '{}')).replace(/^/, '').trim(); // a file saved with a UTF-8 BOM
|
|
18
|
+
let args;
|
|
19
|
+
try { args = JSON.parse(text); } catch (err) {
|
|
20
|
+
throw new Error(`arguments are not valid JSON: ${err.message}`);
|
|
21
|
+
}
|
|
22
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
23
|
+
throw new Error('arguments must be a JSON object, e.g. {"address":"0x..."}');
|
|
24
|
+
}
|
|
25
|
+
const seconds = Number(opts.timeout);
|
|
26
|
+
if (!(seconds > 0)) throw new Error(`--timeout must be a positive number of seconds, got ${opts.timeout}`);
|
|
27
|
+
// Parsed only to check it; the text itself is sent, so numbers above 2^53 are not rounded.
|
|
28
|
+
const r = await callTool(tool, args, { raw: true, argsText: text, timeoutMs: seconds * 1000 });
|
|
29
|
+
process.stdout.write((typeof r === 'string' ? r : JSON.stringify(r)) + '\n');
|
|
30
|
+
} catch (err) { emitError(err, opts); }
|
|
31
|
+
});
|
|
32
|
+
}
|
package/src/commands/candles.js
CHANGED
|
@@ -8,26 +8,22 @@ export function registerCandles(program) {
|
|
|
8
8
|
.description('Historical OHLCV candles — Hyperliquid markets and Polymarket outcome tokens');
|
|
9
9
|
|
|
10
10
|
cmd
|
|
11
|
-
.command('hl
|
|
12
|
-
.description('Hyperliquid candles (perp or spot), aggregated from HL executed fills')
|
|
13
|
-
.option('--
|
|
14
|
-
.option('--
|
|
15
|
-
.option('--
|
|
11
|
+
.command('hl [symbol]')
|
|
12
|
+
.description('Hyperliquid candles (perp or spot), aggregated from HL executed fills; --view latest = the newest 1m bar of every symbol')
|
|
13
|
+
.option('--view <v>', 'candles (default; needs <symbol>) | export (the same, limit defaults to 5000) | latest (every symbol, no <symbol>)')
|
|
14
|
+
.option('--interval <i>', '1m | 5m | 15m | 30m | 1h | 4h | 1d (default 1h; latest: 1m only)')
|
|
15
|
+
.option('--market <m>', 'perp | spot (default perp)')
|
|
16
|
+
.option('--dex <d>', 'Perp DEX (default HL, the core venue; others are HIP-3 builder DEXs; latest: omit for every DEX)')
|
|
16
17
|
.option('--start <t>', 'ISO-8601 UTC or epoch ms (inclusive)')
|
|
17
18
|
.option('--end <t>', 'ISO-8601 UTC or epoch ms (exclusive)')
|
|
18
|
-
.option('--limit <n>', 'Max candles (default 500, max 5000)'
|
|
19
|
+
.option('--limit <n>', 'Max candles (default 500, export 5000; max 5000)')
|
|
19
20
|
.option('--json', 'Emit JSON')
|
|
20
21
|
.action(async (symbol, opts) => {
|
|
21
22
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
limit: parseInt10(opts.limit, 500),
|
|
27
|
-
};
|
|
28
|
-
if (opts.dex !== undefined) args.dex = opts.dex;
|
|
29
|
-
if (opts.start !== undefined) args.start = opts.start;
|
|
30
|
-
if (opts.end !== undefined) args.end = opts.end;
|
|
23
|
+
// Only what was given: the server's defaults stay the defaults. `latest` takes only market, dex and
|
|
24
|
+
// interval, so a symbol, window or limit is not sent with it.
|
|
25
|
+
const args = { view: opts.view, interval: opts.interval, market: opts.market, dex: opts.dex };
|
|
26
|
+
if (opts.view !== 'latest') Object.assign(args, { symbol, start: opts.start, end: opts.end, limit: opts.limit });
|
|
31
27
|
const r = await callTool('hl_ohlcv', args);
|
|
32
28
|
emit(r, opts);
|
|
33
29
|
} catch (err) { emitError(err, opts); }
|
package/src/commands/doctor.js
CHANGED
|
@@ -8,13 +8,13 @@ export function registerDoctor(program) {
|
|
|
8
8
|
.action(async () => {
|
|
9
9
|
const checks = [];
|
|
10
10
|
|
|
11
|
-
// 1. Node version
|
|
11
|
+
// 1. Node version: package.json engines is >=22.12.0
|
|
12
12
|
const nodeVer = process.version;
|
|
13
|
-
const major =
|
|
13
|
+
const [major, minor] = process.versions.node.split('.').map(Number);
|
|
14
14
|
checks.push({
|
|
15
15
|
name: 'Node runtime',
|
|
16
|
-
ok: major >=
|
|
17
|
-
detail: `${nodeVer} (need >=
|
|
16
|
+
ok: major > 22 || (major === 22 && minor >= 12),
|
|
17
|
+
detail: `${nodeVer} (need >= 22.12.0)`,
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
// 2. API key
|