@invizi/cli 0.1.12 → 0.1.15

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
@@ -1,4 +1,5 @@
1
1
  import { getApiUrl, loadConfig, saveConfig } from './config.js';
2
+ import { getDefaultHeaders } from './http.js';
2
3
  const DEFAULT_SCOPE = 'openid profile email offline_access';
3
4
  function sleep(ms) {
4
5
  return new Promise(resolve => setTimeout(resolve, ms));
@@ -106,66 +107,8 @@ export async function getAuthorizationHeader() {
106
107
  return null;
107
108
  }
108
109
  async function login() {
109
- const { domain, audience, clientId } = getAuth0Config();
110
- const deviceRes = await fetch(`https://${domain}/oauth/device/code`, {
111
- method: 'POST',
112
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
113
- body: new URLSearchParams({
114
- client_id: clientId,
115
- audience,
116
- scope: DEFAULT_SCOPE,
117
- }),
118
- });
119
- if (!deviceRes.ok) {
120
- const body = await deviceRes.text();
121
- throw new Error(`Auth0 device flow init failed: ${body}`);
122
- }
123
- const device = await deviceRes.json();
124
- console.log('\nAuth0 login required');
125
- console.log(`1) Open: ${device.verification_uri_complete || device.verification_uri}`);
126
- if (!device.verification_uri_complete) {
127
- console.log(`2) Enter code: ${device.user_code}`);
128
- }
129
- const deadline = Date.now() + (device.expires_in * 1000);
130
- let intervalMs = (device.interval || 5) * 1000;
131
- while (Date.now() < deadline) {
132
- await sleep(intervalMs);
133
- const tokenRes = await fetch(`https://${domain}/oauth/token`, {
134
- method: 'POST',
135
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
136
- body: new URLSearchParams({
137
- grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
138
- device_code: device.device_code,
139
- client_id: clientId,
140
- }),
141
- });
142
- const token = await tokenRes.json();
143
- if (tokenRes.ok && token.access_token && token.expires_in) {
144
- setStoredAuth({
145
- accessToken: token.access_token,
146
- refreshToken: token.refresh_token,
147
- expiresAt: Date.now() + (token.expires_in * 1000),
148
- tokenType: token.token_type,
149
- scope: token.scope,
150
- domain,
151
- audience,
152
- clientId,
153
- });
154
- console.log('\nLogin successful.');
155
- return 0;
156
- }
157
- if (token.error === 'authorization_pending')
158
- continue;
159
- if (token.error === 'slow_down') {
160
- intervalMs += 5000;
161
- continue;
162
- }
163
- if (token.error === 'expired_token') {
164
- throw new Error('Device code expired. Run `invizi auth login` again.');
165
- }
166
- throw new Error(`Login failed: ${token.error || 'unknown error'}`);
167
- }
168
- throw new Error('Login timed out before authorization completed.');
110
+ console.log('Login is not available yet. Coming soon!');
111
+ return 1;
169
112
  }
170
113
  async function status() {
171
114
  const header = await getAuthorizationHeader();
@@ -176,7 +119,7 @@ async function status() {
176
119
  // Use v1 protocol (auth.me) instead of /api/me (not exposed via nginx)
177
120
  const res = await fetch(`${getApiUrl()}/cli/v1/execute`, {
178
121
  method: 'POST',
179
- headers: { 'Content-Type': 'application/json', Authorization: header },
122
+ headers: getDefaultHeaders({ 'Content-Type': 'application/json', Authorization: header }),
180
123
  body: JSON.stringify({ commandId: 'auth.me' }),
181
124
  });
182
125
  if (!res.ok) {
package/dist/config.js CHANGED
@@ -3,6 +3,11 @@ import { dirname, join } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  export const DEFAULT_API_URL = 'https://api.invizi.co';
5
5
  export function getConfigDir(home = homedir()) {
6
+ // Respect XDG_CONFIG_HOME if set (used for test isolation + Linux standard)
7
+ const xdgOverride = process.env.XDG_CONFIG_HOME;
8
+ if (xdgOverride) {
9
+ return join(xdgOverride, 'invizi');
10
+ }
6
11
  const xdg = join(home, '.config', 'invizi');
7
12
  const fallback = join(home, '.invizi');
8
13
  if (existsSync(join(home, '.config'))) {
package/dist/http.js ADDED
@@ -0,0 +1,11 @@
1
+ import { readFileSync } from 'node:fs';
2
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
3
+ export const CLI_VERSION = pkg.version || 'unknown';
4
+ export const INVIZI_CLI_USER_AGENT = `invizi-cli/${CLI_VERSION}`;
5
+ export function getDefaultHeaders(headers = {}) {
6
+ const merged = new Headers(headers);
7
+ if (!merged.has('User-Agent')) {
8
+ merged.set('User-Agent', INVIZI_CLI_USER_AGENT);
9
+ }
10
+ return merged;
11
+ }
package/dist/invizi.js CHANGED
@@ -1,7 +1,7 @@
1
- import { readFileSync } from 'node:fs';
2
1
  import { auth, getAuthorizationHeader } from './auth.js';
3
2
  import { track } from './track.js';
4
3
  import { getApiUrl, getConfigPath, loadConfig, redactConfig } from './config.js';
4
+ import { CLI_VERSION, getDefaultHeaders } from './http.js';
5
5
  import { setup } from './setup.js';
6
6
  import { trades } from './commands/index.js';
7
7
  function showLocalHelp() {
@@ -34,10 +34,10 @@ async function executeProtocol(args, authHeader) {
34
34
  const apiUrl = getApiUrl();
35
35
  const res = await fetch(`${apiUrl}/cli/v1/execute`, {
36
36
  method: 'POST',
37
- headers: {
37
+ headers: getDefaultHeaders({
38
38
  'Content-Type': 'application/json',
39
39
  Authorization: authHeader,
40
- },
40
+ }),
41
41
  body: JSON.stringify({ argv: serverArgs }),
42
42
  });
43
43
  if (res.status === 404) {
@@ -71,7 +71,7 @@ async function executeProtocol(args, authHeader) {
71
71
  async function showRemoteHelp(authHeader) {
72
72
  const apiUrl = getApiUrl();
73
73
  const res = await fetch(`${apiUrl}/cli/v1/commands`, {
74
- headers: { Authorization: authHeader },
74
+ headers: getDefaultHeaders({ Authorization: authHeader }),
75
75
  });
76
76
  if (!res.ok) {
77
77
  throw new Error(`Unable to fetch command catalog (${res.status})`);
@@ -140,16 +140,21 @@ export async function main(rawArgs = process.argv.slice(2)) {
140
140
  return track(args.slice(1));
141
141
  if (command === 'trades')
142
142
  return trades(args.slice(1));
143
- if (command === 'setup')
143
+ if (command === 'setup') {
144
+ const header = await getAuthorizationHeader();
145
+ if (!header) {
146
+ console.error('Not authenticated. Run: invizi login');
147
+ return 1;
148
+ }
144
149
  return setup(args.slice(1));
150
+ }
145
151
  if (command === 'config') {
146
152
  console.log(JSON.stringify(redactConfig(loadConfig()), null, 2));
147
153
  console.log(`\nConfig path: ${getConfigPath()}`);
148
154
  return 0;
149
155
  }
150
156
  if (command === 'version' || command === '--version' || command === '-v') {
151
- const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
152
- console.log(`invizi-cli v${pkg.version || 'unknown'}`);
157
+ console.log(`invizi-cli v${CLI_VERSION}`);
153
158
  return 0;
154
159
  }
155
160
  return executeRemote(args);
package/dist/setup.js CHANGED
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  import { loadConfig, saveConfig, getConfigPath } from './config.js';
5
+ import { getDefaultHeaders } from './http.js';
5
6
  const SKILLS_URL = 'https://pub-6e61fc0656544ad3bf01416b1d0a6065.r2.dev';
6
7
  function detectAiTool() {
7
8
  const checks = [
@@ -26,7 +27,7 @@ export async function setup(args) {
26
27
  const customOutput = outputIdx !== -1 ? args[outputIdx + 1] : null;
27
28
  const dryRun = args.includes('--dry-run');
28
29
  const isDev = args.includes('--dev');
29
- const apiUrl = isDev ? 'http://localhost:3000' : 'https://api.invizi.co';
30
+ const apiUrl = process.env.INVIZI_API_URL || (isDev ? 'http://localhost:3000' : 'https://api.invizi.co');
30
31
  // Step 0: Configure API URL + Auth0
31
32
  console.log(`Configuring Invizi CLI (${isDev ? 'dev' : 'prod'})...`);
32
33
  if (!dryRun) {
@@ -82,7 +83,9 @@ export async function setup(args) {
82
83
  console.log('(dry run - no files will be written)');
83
84
  }
84
85
  console.log('Fetching skills...');
85
- const listRes = await fetch(`${SKILLS_URL}/list.json`);
86
+ const listRes = await fetch(`${SKILLS_URL}/list.json`, {
87
+ headers: getDefaultHeaders(),
88
+ });
86
89
  if (!listRes.ok) {
87
90
  console.error('Failed to fetch skill list from Invizi.');
88
91
  return 1;
@@ -99,7 +102,9 @@ export async function setup(args) {
99
102
  continue;
100
103
  }
101
104
  }
102
- const res = await fetch(`${SKILLS_URL}/${name}/SKILL.md`);
105
+ const res = await fetch(`${SKILLS_URL}/${name}/SKILL.md`, {
106
+ headers: getDefaultHeaders(),
107
+ });
103
108
  if (!res.ok) {
104
109
  console.error(` [x] ${name} (download failed)`);
105
110
  continue;
package/dist/track.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { getApiUrl, loadConfig, saveConfig } from './config.js';
2
2
  import { getAuthorizationHeader } from './auth.js';
3
+ import { getDefaultHeaders } from './http.js';
3
4
  const HLP_API = 'https://api.hyperliquid.xyz/info';
4
5
  function detectChain(address) {
5
6
  if (/^0x[0-9a-fA-F]{40}$/.test(address))
@@ -41,10 +42,10 @@ async function registerWithServer(exchange, address, label) {
41
42
  }
42
43
  const res = await fetch(`${apiUrl}/api/connect`, {
43
44
  method: 'POST',
44
- headers: {
45
+ headers: getDefaultHeaders({
45
46
  'Content-Type': 'application/json',
46
47
  Authorization: authHeader,
47
- },
48
+ }),
48
49
  body: JSON.stringify({ exchange, address, label }),
49
50
  });
50
51
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invizi/cli",
3
- "version": "0.1.12",
3
+ "version": "0.1.15",
4
4
  "description": "Invizi CLI",
5
5
  "type": "module",
6
6
  "bin": {