@invizi/cli 0.1.9 → 0.1.11

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/auth.js CHANGED
@@ -199,9 +199,6 @@ async function status() {
199
199
  if (email) {
200
200
  console.log(`Email: ${email}`);
201
201
  }
202
- if (Array.isArray(me.permissions) && me.permissions.length > 0) {
203
- console.log(`Permissions: ${me.permissions.join(', ')}`);
204
- }
205
202
  return 0;
206
203
  }
207
204
  function logout() {
@@ -239,7 +239,7 @@ export async function trades(args) {
239
239
  const config = loadConfig();
240
240
  const address = positionals.find(a => /^0x[0-9a-fA-F]{40}$/.test(a)) || config.address;
241
241
  if (!address) {
242
- console.error('No address found. Run: invizi connect <address>');
242
+ console.error('No address found. Run: invizi track <address>');
243
243
  console.error('Or pass directly: invizi trades 0x...');
244
244
  return 1;
245
245
  }
package/dist/invizi.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { auth, getAuthorizationHeader } from './auth.js';
3
- import { connect } from './connect.js';
3
+ import { track } from './track.js';
4
4
  import { getApiUrl, getConfigPath, loadConfig, redactConfig } from './config.js';
5
5
  import { setup } from './setup.js';
6
6
  import { trades } from './commands/index.js';
@@ -9,16 +9,17 @@ function showLocalHelp() {
9
9
  Invizi CLI
10
10
 
11
11
  Data:
12
- invizi context Market overview, macro, yields, options, HLP
13
- invizi context -c SOL + coin data, flow, positions, trade history
12
+ invizi market Market overview — prices, macro, yields, funding
13
+ invizi market -c SOL + coin deep dive (RSI, taker flow, whale imb)
14
+ invizi market list All tradeable assets with prices
14
15
  invizi scout <COIN> Quick coin scan (price, funding, RSI, OBI)
15
- invizi market BTC/ETH/SOL prices, fear/greed, funding extremes
16
16
  invizi trades Analyze past trades — P&L by coin (local)
17
17
 
18
18
  Account:
19
- invizi auth login Login
19
+ invizi login Login
20
+ invizi logout Logout
20
21
  invizi auth status Show current identity
21
- invizi connect <address> Connect a wallet address
22
+ invizi track <address> Track a wallet address
22
23
 
23
24
  Setup:
24
25
  invizi setup Configure API + install AI skills
@@ -131,8 +132,12 @@ export async function main(rawArgs = process.argv.slice(2)) {
131
132
  }
132
133
  if (command === 'auth')
133
134
  return auth(args.slice(1));
134
- if (command === 'connect')
135
- return connect(args.slice(1));
135
+ if (command === 'login')
136
+ return auth(['login']);
137
+ if (command === 'logout')
138
+ return auth(['logout']);
139
+ if (command === 'track')
140
+ return track(args.slice(1));
136
141
  if (command === 'trades')
137
142
  return trades(args.slice(1));
138
143
  if (command === 'setup')
package/dist/track.js ADDED
@@ -0,0 +1,131 @@
1
+ import { getApiUrl, loadConfig, saveConfig } from './config.js';
2
+ import { getAuthorizationHeader } from './auth.js';
3
+ const HLP_API = 'https://api.hyperliquid.xyz/info';
4
+ function detectChain(address) {
5
+ if (/^0x[0-9a-fA-F]{40}$/.test(address))
6
+ return 'evm';
7
+ return null;
8
+ }
9
+ const EXCHANGE_CHECKERS = {
10
+ evm: [{ name: 'hyperliquid', check: validateHlpAddress }],
11
+ };
12
+ async function validateHlpAddress(address) {
13
+ const [stateRes, fillsRes] = await Promise.all([
14
+ fetch(HLP_API, {
15
+ method: 'POST',
16
+ headers: { 'Content-Type': 'application/json' },
17
+ body: JSON.stringify({ type: 'clearinghouseState', user: address }),
18
+ }),
19
+ fetch(HLP_API, {
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ body: JSON.stringify({ type: 'userFills', user: address }),
23
+ }),
24
+ ]);
25
+ if (!stateRes.ok || !fillsRes.ok) {
26
+ return null;
27
+ }
28
+ const state = (await stateRes.json());
29
+ const fills = (await fillsRes.json());
30
+ return {
31
+ positions: state.assetPositions?.length || 0,
32
+ accountValue: Number.parseFloat(state.marginSummary?.accountValue || '0'),
33
+ trades: fills.length || 0,
34
+ };
35
+ }
36
+ async function registerWithServer(exchange, address, label) {
37
+ const apiUrl = getApiUrl();
38
+ const authHeader = await getAuthorizationHeader();
39
+ if (!authHeader) {
40
+ throw new Error('Not authenticated. Run: invizi auth login');
41
+ }
42
+ const res = await fetch(`${apiUrl}/api/connect`, {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ Authorization: authHeader,
47
+ },
48
+ body: JSON.stringify({ exchange, address, label }),
49
+ });
50
+ if (!res.ok) {
51
+ const bodyText = await res.text();
52
+ let parsed = null;
53
+ try {
54
+ parsed = JSON.parse(bodyText);
55
+ }
56
+ catch {
57
+ parsed = null;
58
+ }
59
+ if (res.status === 403 && parsed?.error?.includes('Tracking limit reached')) {
60
+ const tracked = parsed.trackedAddress;
61
+ const details = tracked
62
+ ? `existing ${tracked.exchange}:${tracked.address}${tracked.label ? ` (${tracked.label})` : ''}`
63
+ : 'already at limit';
64
+ throw new Error(`Tracking limit reached (${details}).`);
65
+ }
66
+ throw new Error(`Server error: ${res.status} ${parsed?.error || bodyText}`);
67
+ }
68
+ return (await res.json());
69
+ }
70
+ export async function track(args) {
71
+ const address = args[0];
72
+ const labelIdx = args.indexOf('--label');
73
+ const label = labelIdx !== -1 ? args[labelIdx + 1] || null : null;
74
+ if (!address) {
75
+ console.error('Usage: invizi track <wallet-address> [--label name]');
76
+ return 1;
77
+ }
78
+ const chain = detectChain(address);
79
+ if (!chain) {
80
+ console.error(`Unrecognized address format: ${address}`);
81
+ console.error('Supported: EVM addresses (0x...)');
82
+ return 1;
83
+ }
84
+ const checkers = EXCHANGE_CHECKERS[chain];
85
+ if (!checkers || checkers.length === 0) {
86
+ console.error(`No supported exchanges for chain: ${chain}`);
87
+ return 1;
88
+ }
89
+ console.log(`Scanning exchanges for ${address}...`);
90
+ const found = [];
91
+ for (const { name, check } of checkers) {
92
+ const info = await check(address);
93
+ if (info && (info.positions > 0 || info.trades > 0 || info.accountValue > 0)) {
94
+ found.push({ exchange: name, info });
95
+ console.log(` [ok] ${name}: ${info.positions} positions, ${info.trades} trades, $${info.accountValue.toFixed(2)}`);
96
+ }
97
+ else {
98
+ console.log(` [x] ${name}: no activity`);
99
+ }
100
+ }
101
+ if (found.length === 0) {
102
+ console.error('No activity found on any supported exchange for this address.');
103
+ return 1;
104
+ }
105
+ const selected = found[0];
106
+ try {
107
+ const result = await registerWithServer(selected.exchange, address, label);
108
+ const config = loadConfig();
109
+ config.userId = result.userId;
110
+ config.trackedAddressId = result.trackedAddressId;
111
+ delete config.accountId;
112
+ config.address = address;
113
+ config.exchange = selected.exchange;
114
+ if (label)
115
+ config.label = label;
116
+ saveConfig(config);
117
+ console.log(`Connected watch-only tracking: ${selected.exchange}`);
118
+ if (result.alreadyTracked) {
119
+ console.log(' Already tracked previously.');
120
+ }
121
+ console.log(` Positions: ${selected.info.positions}`);
122
+ console.log(` Trades: ${selected.info.trades}`);
123
+ console.log(` Account value: $${selected.info.accountValue.toFixed(2)}`);
124
+ return 0;
125
+ }
126
+ catch (error) {
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ console.error(`Failed to register: ${message}`);
129
+ return 1;
130
+ }
131
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invizi/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Invizi CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,8 @@
14
14
  "build": "tsc -p tsconfig.json",
15
15
  "typecheck": "tsc --noEmit -p tsconfig.json",
16
16
  "test": "jest",
17
- "prepack": "npm run build"
17
+ "prepack": "npm run build",
18
+ "postinstall": "node -e \"console.log('\\n\\x1b[1m✨ Invizi CLI installed!\\x1b[0m\\n\\nGet started:\\n invizi login Authenticate\\n invizi connect <address> Connect your wallet\\n invizi setup Install AI skills\\n invizi market Check the markets\\n invizi --help See all commands\\n')\""
18
19
  },
19
20
  "devDependencies": {
20
21
  "@types/jest": "^30.0.0",