securegate-cli-tool 2.1.2 → 2.1.4
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/index.js +351 -351
- package/package.json +35 -35
- package/scripts/postinstall.js +37 -37
- package/src/api.js +213 -213
- package/src/commands/connect.js +102 -102
- package/src/commands/keys.js +280 -280
- package/src/commands/login.js +189 -191
- package/src/commands/providers.js +51 -51
- package/src/commands/status.js +78 -78
- package/src/config.js +85 -85
- package/src/index.js +165 -165
- package/templates/SKILL.md +59 -59
package/src/commands/status.js
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* securegate status — Show current authentication & connection state
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const chalk = require('chalk');
|
|
6
|
-
const ora = require('ora');
|
|
7
|
-
const { getAuth, getConnections, CONFIG_FILE } = require('../config');
|
|
8
|
-
const api = require('../api');
|
|
9
|
-
|
|
10
|
-
async function statusCommand() {
|
|
11
|
-
console.log();
|
|
12
|
-
console.log(chalk.cyan.bold('📊 SecureGate Status'));
|
|
13
|
-
console.log(chalk.dim('━'.repeat(50)));
|
|
14
|
-
console.log();
|
|
15
|
-
|
|
16
|
-
// Auth status
|
|
17
|
-
const auth = getAuth();
|
|
18
|
-
if (!auth) {
|
|
19
|
-
console.log(chalk.dim(' Auth: ') + chalk.red('Not logged in'));
|
|
20
|
-
console.log(chalk.dim(` Run: ${chalk.cyan('securegate login')}`));
|
|
21
|
-
console.log();
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
console.log(chalk.dim(' Auth: ') + chalk.green('● Logged in'));
|
|
26
|
-
console.log(chalk.dim(' Email: ') + chalk.white(auth.user?.email || 'unknown'));
|
|
27
|
-
console.log(chalk.dim(' ID: ') + chalk.dim(auth.user?.id?.substring(0, 8) + '...'));
|
|
28
|
-
|
|
29
|
-
if (auth.expires_at) {
|
|
30
|
-
const remaining = auth.expires_at - Date.now();
|
|
31
|
-
if (remaining > 0) {
|
|
32
|
-
const mins = Math.round(remaining / 60000);
|
|
33
|
-
console.log(chalk.dim(' Token: ') + chalk.green(`Valid (${mins}m remaining)`));
|
|
34
|
-
} else {
|
|
35
|
-
console.log(chalk.dim(' Token: ') + chalk.yellow('Expired (will auto-refresh)'));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
console.log();
|
|
39
|
-
|
|
40
|
-
// Local connections
|
|
41
|
-
const localConns = getConnections();
|
|
42
|
-
const localCount = Object.keys(localConns).length;
|
|
43
|
-
console.log(chalk.dim(` Local keys: ${localCount} saved in ${CONFIG_FILE}`));
|
|
44
|
-
|
|
45
|
-
// Remote connections
|
|
46
|
-
const spinner = ora({ text: 'Fetching remote status...', indent: 2 }).start();
|
|
47
|
-
try {
|
|
48
|
-
const res = await api.listConnections();
|
|
49
|
-
if (res.status === 200) {
|
|
50
|
-
const conns = res.data?.connections || res.data || [];
|
|
51
|
-
spinner.succeed(`${conns.length} connection(s) on server`);
|
|
52
|
-
|
|
53
|
-
for (const c of conns) {
|
|
54
|
-
const keyCount = c.security_keys?.length || 0;
|
|
55
|
-
console.log(chalk.dim(` ${chalk.cyan(c.connection_id)} — ${c.provider} — ${keyCount} key(s)`));
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
spinner.warn('Could not fetch remote status');
|
|
59
|
-
}
|
|
60
|
-
} catch (err) {
|
|
61
|
-
spinner.warn(`Could not reach server: ${err.message}`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
console.log();
|
|
65
|
-
// Plan info
|
|
66
|
-
try {
|
|
67
|
-
const profile = await api.getProfile();
|
|
68
|
-
if (profile.status === 200) {
|
|
69
|
-
const plan = profile.data?.plan || 'free';
|
|
70
|
-
const planColor = plan === 'free' ? chalk.dim : chalk.green;
|
|
71
|
-
console.log(chalk.dim(' Plan: ') + planColor(plan.charAt(0).toUpperCase() + plan.slice(1)));
|
|
72
|
-
}
|
|
73
|
-
} catch { }
|
|
74
|
-
|
|
75
|
-
console.log();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
module.exports = statusCommand;
|
|
1
|
+
/**
|
|
2
|
+
* securegate status — Show current authentication & connection state
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const ora = require('ora');
|
|
7
|
+
const { getAuth, getConnections, CONFIG_FILE } = require('../config');
|
|
8
|
+
const api = require('../api');
|
|
9
|
+
|
|
10
|
+
async function statusCommand() {
|
|
11
|
+
console.log();
|
|
12
|
+
console.log(chalk.cyan.bold('📊 SecureGate Status'));
|
|
13
|
+
console.log(chalk.dim('━'.repeat(50)));
|
|
14
|
+
console.log();
|
|
15
|
+
|
|
16
|
+
// Auth status
|
|
17
|
+
const auth = getAuth();
|
|
18
|
+
if (!auth) {
|
|
19
|
+
console.log(chalk.dim(' Auth: ') + chalk.red('Not logged in'));
|
|
20
|
+
console.log(chalk.dim(` Run: ${chalk.cyan('securegate login')}`));
|
|
21
|
+
console.log();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(chalk.dim(' Auth: ') + chalk.green('● Logged in'));
|
|
26
|
+
console.log(chalk.dim(' Email: ') + chalk.white(auth.user?.email || 'unknown'));
|
|
27
|
+
console.log(chalk.dim(' ID: ') + chalk.dim(auth.user?.id?.substring(0, 8) + '...'));
|
|
28
|
+
|
|
29
|
+
if (auth.expires_at) {
|
|
30
|
+
const remaining = auth.expires_at - Date.now();
|
|
31
|
+
if (remaining > 0) {
|
|
32
|
+
const mins = Math.round(remaining / 60000);
|
|
33
|
+
console.log(chalk.dim(' Token: ') + chalk.green(`Valid (${mins}m remaining)`));
|
|
34
|
+
} else {
|
|
35
|
+
console.log(chalk.dim(' Token: ') + chalk.yellow('Expired (will auto-refresh)'));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
console.log();
|
|
39
|
+
|
|
40
|
+
// Local connections
|
|
41
|
+
const localConns = getConnections();
|
|
42
|
+
const localCount = Object.keys(localConns).length;
|
|
43
|
+
console.log(chalk.dim(` Local keys: ${localCount} saved in ${CONFIG_FILE}`));
|
|
44
|
+
|
|
45
|
+
// Remote connections
|
|
46
|
+
const spinner = ora({ text: 'Fetching remote status...', indent: 2 }).start();
|
|
47
|
+
try {
|
|
48
|
+
const res = await api.listConnections();
|
|
49
|
+
if (res.status === 200) {
|
|
50
|
+
const conns = res.data?.connections || res.data || [];
|
|
51
|
+
spinner.succeed(`${conns.length} connection(s) on server`);
|
|
52
|
+
|
|
53
|
+
for (const c of conns) {
|
|
54
|
+
const keyCount = c.security_keys?.length || 0;
|
|
55
|
+
console.log(chalk.dim(` ${chalk.cyan(c.connection_id)} — ${c.provider} — ${keyCount} key(s)`));
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
spinner.warn('Could not fetch remote status');
|
|
59
|
+
}
|
|
60
|
+
} catch (err) {
|
|
61
|
+
spinner.warn(`Could not reach server: ${err.message}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log();
|
|
65
|
+
// Plan info
|
|
66
|
+
try {
|
|
67
|
+
const profile = await api.getProfile();
|
|
68
|
+
if (profile.status === 200) {
|
|
69
|
+
const plan = profile.data?.plan || 'free';
|
|
70
|
+
const planColor = plan === 'free' ? chalk.dim : chalk.green;
|
|
71
|
+
console.log(chalk.dim(' Plan: ') + planColor(plan.charAt(0).toUpperCase() + plan.slice(1)));
|
|
72
|
+
}
|
|
73
|
+
} catch { }
|
|
74
|
+
|
|
75
|
+
console.log();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = statusCommand;
|
package/src/config.js
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SecureGate CLI — Configuration & Storage
|
|
3
|
-
* Manages ~/.securegate/config.json
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const os = require('os');
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
const CONFIG_DIR = path.join(os.homedir(), '.securegate');
|
|
11
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
12
|
-
|
|
13
|
-
// Supabase project
|
|
14
|
-
// SECURITY NOTE: The Anon Key is designed to be public and is safe to include in the CLI.
|
|
15
|
-
// SecureGate uses strict Row Level Security (RLS) with no policies, meaning this key
|
|
16
|
-
// CANNOT read or write any database data. It is strictly used for the login flow.
|
|
17
|
-
const SUPABASE_URL = 'https://pbrmsfoowrjqsikgkijb.supabase.co';
|
|
18
|
-
const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBicm1zZm9vd3JqcXNpa2draWpiIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzAzNjU0NjIsImV4cCI6MjA4NTk0MTQ2Mn0.XfZyEv3atJp7BMH7oQKx1T-rrP_8PLTKeyoIfvUgLks';
|
|
19
|
-
|
|
20
|
-
// Public-facing proxy URL
|
|
21
|
-
const PROXY_BASE_URL = 'https://usesecuregate.xyz/v1';
|
|
22
|
-
|
|
23
|
-
function ensureConfigDir() {
|
|
24
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
25
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function loadConfig() {
|
|
30
|
-
try {
|
|
31
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
32
|
-
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
33
|
-
}
|
|
34
|
-
} catch { }
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function saveConfig(config) {
|
|
39
|
-
ensureConfigDir();
|
|
40
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getAuth() {
|
|
44
|
-
const config = loadConfig();
|
|
45
|
-
return config.auth || null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function setAuth(auth) {
|
|
49
|
-
const config = loadConfig();
|
|
50
|
-
config.auth = auth;
|
|
51
|
-
saveConfig(config);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function clearAuth() {
|
|
55
|
-
const config = loadConfig();
|
|
56
|
-
delete config.auth;
|
|
57
|
-
saveConfig(config);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function getConnections() {
|
|
61
|
-
const config = loadConfig();
|
|
62
|
-
return config.connections || {};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function setConnection(connectionId, data) {
|
|
66
|
-
const config = loadConfig();
|
|
67
|
-
if (!config.connections) config.connections = {};
|
|
68
|
-
config.connections[connectionId] = data;
|
|
69
|
-
saveConfig(config);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
module.exports = {
|
|
73
|
-
CONFIG_DIR,
|
|
74
|
-
CONFIG_FILE,
|
|
75
|
-
SUPABASE_URL,
|
|
76
|
-
SUPABASE_ANON_KEY,
|
|
77
|
-
PROXY_BASE_URL,
|
|
78
|
-
loadConfig,
|
|
79
|
-
saveConfig,
|
|
80
|
-
getAuth,
|
|
81
|
-
setAuth,
|
|
82
|
-
clearAuth,
|
|
83
|
-
getConnections,
|
|
84
|
-
setConnection,
|
|
85
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* SecureGate CLI — Configuration & Storage
|
|
3
|
+
* Manages ~/.securegate/config.json
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const CONFIG_DIR = path.join(os.homedir(), '.securegate');
|
|
11
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
12
|
+
|
|
13
|
+
// Supabase project
|
|
14
|
+
// SECURITY NOTE: The Anon Key is designed to be public and is safe to include in the CLI.
|
|
15
|
+
// SecureGate uses strict Row Level Security (RLS) with no policies, meaning this key
|
|
16
|
+
// CANNOT read or write any database data. It is strictly used for the login flow.
|
|
17
|
+
const SUPABASE_URL = 'https://pbrmsfoowrjqsikgkijb.supabase.co';
|
|
18
|
+
const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBicm1zZm9vd3JqcXNpa2draWpiIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzAzNjU0NjIsImV4cCI6MjA4NTk0MTQ2Mn0.XfZyEv3atJp7BMH7oQKx1T-rrP_8PLTKeyoIfvUgLks';
|
|
19
|
+
|
|
20
|
+
// Public-facing proxy URL
|
|
21
|
+
const PROXY_BASE_URL = 'https://usesecuregate.xyz/v1';
|
|
22
|
+
|
|
23
|
+
function ensureConfigDir() {
|
|
24
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
25
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function loadConfig() {
|
|
30
|
+
try {
|
|
31
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
32
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
33
|
+
}
|
|
34
|
+
} catch { }
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function saveConfig(config) {
|
|
39
|
+
ensureConfigDir();
|
|
40
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getAuth() {
|
|
44
|
+
const config = loadConfig();
|
|
45
|
+
return config.auth || null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function setAuth(auth) {
|
|
49
|
+
const config = loadConfig();
|
|
50
|
+
config.auth = auth;
|
|
51
|
+
saveConfig(config);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function clearAuth() {
|
|
55
|
+
const config = loadConfig();
|
|
56
|
+
delete config.auth;
|
|
57
|
+
saveConfig(config);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getConnections() {
|
|
61
|
+
const config = loadConfig();
|
|
62
|
+
return config.connections || {};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function setConnection(connectionId, data) {
|
|
66
|
+
const config = loadConfig();
|
|
67
|
+
if (!config.connections) config.connections = {};
|
|
68
|
+
config.connections[connectionId] = data;
|
|
69
|
+
saveConfig(config);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
CONFIG_DIR,
|
|
74
|
+
CONFIG_FILE,
|
|
75
|
+
SUPABASE_URL,
|
|
76
|
+
SUPABASE_ANON_KEY,
|
|
77
|
+
PROXY_BASE_URL,
|
|
78
|
+
loadConfig,
|
|
79
|
+
saveConfig,
|
|
80
|
+
getAuth,
|
|
81
|
+
setAuth,
|
|
82
|
+
clearAuth,
|
|
83
|
+
getConnections,
|
|
84
|
+
setConnection,
|
|
85
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,165 +1,165 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SecureGate CLI v2.0
|
|
5
|
-
* Secure your AI agent API keys from the terminal.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* securegate login Authenticate with SecureGate
|
|
9
|
-
* securegate connect Connect a new AI provider
|
|
10
|
-
* securegate keys [list|create|update|revoke] Manage security keys
|
|
11
|
-
* securegate providers List supported providers
|
|
12
|
-
|
|
13
|
-
* securegate status Show account status
|
|
14
|
-
* securegate logout Clear stored credentials
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const { Command } = require('commander');
|
|
18
|
-
const chalk = require('chalk');
|
|
19
|
-
const { clearAuth, getAuth } = require('./config');
|
|
20
|
-
|
|
21
|
-
const program = new Command();
|
|
22
|
-
|
|
23
|
-
program
|
|
24
|
-
.name('securegate')
|
|
25
|
-
.description(chalk.cyan('🔐 SecureGate CLI') + ' — Secure your AI agent API keys')
|
|
26
|
-
.version('2.0.0');
|
|
27
|
-
|
|
28
|
-
// ── login ────────────────────────────────────────────────────────────────────
|
|
29
|
-
|
|
30
|
-
program
|
|
31
|
-
.command('login')
|
|
32
|
-
.description('Authenticate with your SecureGate account')
|
|
33
|
-
.action(async () => {
|
|
34
|
-
const loginCmd = require('./commands/login');
|
|
35
|
-
await loginCmd();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// ── connect ──────────────────────────────────────────────────────────────────
|
|
39
|
-
|
|
40
|
-
program
|
|
41
|
-
.command('connect')
|
|
42
|
-
.description('Connect a new AI provider (OpenAI, Anthropic, etc.)')
|
|
43
|
-
.action(async () => {
|
|
44
|
-
const connectCmd = require('./commands/connect');
|
|
45
|
-
await connectCmd();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// ── keys ─────────────────────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
const keysCmd = program
|
|
51
|
-
.command('keys')
|
|
52
|
-
.description('Manage security keys');
|
|
53
|
-
|
|
54
|
-
keysCmd
|
|
55
|
-
.command('list')
|
|
56
|
-
.description('List all connections and their security keys')
|
|
57
|
-
.action(async () => {
|
|
58
|
-
const { keysListCommand } = require('./commands/keys');
|
|
59
|
-
await keysListCommand();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
keysCmd
|
|
63
|
-
.command('create')
|
|
64
|
-
.description('Generate a new security key for a connection')
|
|
65
|
-
.action(async () => {
|
|
66
|
-
const { keysCreateCommand } = require('./commands/keys');
|
|
67
|
-
await keysCreateCommand();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
keysCmd
|
|
71
|
-
.command('update <key-id>')
|
|
72
|
-
.description('Update an existing security key')
|
|
73
|
-
.option('--city <city>', 'Restrict key to a specific city')
|
|
74
|
-
.option('--models <model1,model2>', 'Comma separated list of allowed models')
|
|
75
|
-
.action(async (keyId, options) => {
|
|
76
|
-
const { keysUpdateCommand } = require('./commands/keys');
|
|
77
|
-
await keysUpdateCommand(keyId, options);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
keysCmd
|
|
81
|
-
.command('lock <key-id>')
|
|
82
|
-
.description('Lock a security key to an IP')
|
|
83
|
-
.option('--ip <ip-address>', 'Specific IP address to lock to')
|
|
84
|
-
.action(async (keyId, options) => {
|
|
85
|
-
const { keysLockCommand } = require('./commands/keys');
|
|
86
|
-
await keysLockCommand(keyId, options);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
keysCmd
|
|
90
|
-
.command('revoke <key-id>')
|
|
91
|
-
.description('Revoke a security key')
|
|
92
|
-
.action(async (keyId) => {
|
|
93
|
-
const { keysRevokeCommand } = require('./commands/keys');
|
|
94
|
-
await keysRevokeCommand(keyId);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Default: list keys
|
|
98
|
-
keysCmd
|
|
99
|
-
.action(async () => {
|
|
100
|
-
const { keysListCommand } = require('./commands/keys');
|
|
101
|
-
await keysListCommand();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// ── providers ────────────────────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
program
|
|
107
|
-
.command('providers')
|
|
108
|
-
.description('List all supported AI providers')
|
|
109
|
-
.action(() => {
|
|
110
|
-
const providersCmd = require('./commands/providers');
|
|
111
|
-
providersCmd();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// ── status ───────────────────────────────────────────────────────────────────
|
|
117
|
-
|
|
118
|
-
program
|
|
119
|
-
.command('status')
|
|
120
|
-
.description('Show current account and connection status')
|
|
121
|
-
.action(async () => {
|
|
122
|
-
const statusCmd = require('./commands/status');
|
|
123
|
-
await statusCmd();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// ── logout ───────────────────────────────────────────────────────────────────
|
|
127
|
-
|
|
128
|
-
program
|
|
129
|
-
.command('logout')
|
|
130
|
-
.description('Clear stored credentials')
|
|
131
|
-
.action(() => {
|
|
132
|
-
const auth = getAuth();
|
|
133
|
-
if (!auth) {
|
|
134
|
-
console.log(chalk.dim('\n Already logged out.\n'));
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
clearAuth();
|
|
138
|
-
console.log(chalk.green('\n ✓ Logged out. Credentials cleared.\n'));
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// ── Banner ───────────────────────────────────────────────────────────────────
|
|
142
|
-
|
|
143
|
-
program.addHelpText('beforeAll', `
|
|
144
|
-
${chalk.cyan.bold('🔐 SecureGate CLI v2.0')}
|
|
145
|
-
${chalk.dim('━'.repeat(50))}
|
|
146
|
-
${chalk.dim('Protect your AI agent API keys with hardware-grade security.')}
|
|
147
|
-
${chalk.dim('https://securegate.xyz')}
|
|
148
|
-
`);
|
|
149
|
-
|
|
150
|
-
program.addHelpText('afterAll', `
|
|
151
|
-
${chalk.dim('━'.repeat(50))}
|
|
152
|
-
${chalk.dim('Quick start:')}
|
|
153
|
-
${chalk.cyan('securegate login')} ${chalk.dim('Sign in to your account')}
|
|
154
|
-
${chalk.cyan('securegate connect')} ${chalk.dim('Add an AI provider')}
|
|
155
|
-
|
|
156
|
-
`);
|
|
157
|
-
|
|
158
|
-
// ── Parse ────────────────────────────────────────────────────────────────────
|
|
159
|
-
|
|
160
|
-
program.parse(process.argv);
|
|
161
|
-
|
|
162
|
-
// Show help if no command
|
|
163
|
-
if (!process.argv.slice(2).length) {
|
|
164
|
-
program.help();
|
|
165
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SecureGate CLI v2.0
|
|
5
|
+
* Secure your AI agent API keys from the terminal.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* securegate login Authenticate with SecureGate
|
|
9
|
+
* securegate connect Connect a new AI provider
|
|
10
|
+
* securegate keys [list|create|update|revoke] Manage security keys
|
|
11
|
+
* securegate providers List supported providers
|
|
12
|
+
|
|
13
|
+
* securegate status Show account status
|
|
14
|
+
* securegate logout Clear stored credentials
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { Command } = require('commander');
|
|
18
|
+
const chalk = require('chalk');
|
|
19
|
+
const { clearAuth, getAuth } = require('./config');
|
|
20
|
+
|
|
21
|
+
const program = new Command();
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.name('securegate')
|
|
25
|
+
.description(chalk.cyan('🔐 SecureGate CLI') + ' — Secure your AI agent API keys')
|
|
26
|
+
.version('2.0.0');
|
|
27
|
+
|
|
28
|
+
// ── login ────────────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command('login')
|
|
32
|
+
.description('Authenticate with your SecureGate account')
|
|
33
|
+
.action(async () => {
|
|
34
|
+
const loginCmd = require('./commands/login');
|
|
35
|
+
await loginCmd();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// ── connect ──────────────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
program
|
|
41
|
+
.command('connect')
|
|
42
|
+
.description('Connect a new AI provider (OpenAI, Anthropic, etc.)')
|
|
43
|
+
.action(async () => {
|
|
44
|
+
const connectCmd = require('./commands/connect');
|
|
45
|
+
await connectCmd();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// ── keys ─────────────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
const keysCmd = program
|
|
51
|
+
.command('keys')
|
|
52
|
+
.description('Manage security keys');
|
|
53
|
+
|
|
54
|
+
keysCmd
|
|
55
|
+
.command('list')
|
|
56
|
+
.description('List all connections and their security keys')
|
|
57
|
+
.action(async () => {
|
|
58
|
+
const { keysListCommand } = require('./commands/keys');
|
|
59
|
+
await keysListCommand();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
keysCmd
|
|
63
|
+
.command('create')
|
|
64
|
+
.description('Generate a new security key for a connection')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
const { keysCreateCommand } = require('./commands/keys');
|
|
67
|
+
await keysCreateCommand();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
keysCmd
|
|
71
|
+
.command('update <key-id>')
|
|
72
|
+
.description('Update an existing security key')
|
|
73
|
+
.option('--city <city>', 'Restrict key to a specific city')
|
|
74
|
+
.option('--models <model1,model2>', 'Comma separated list of allowed models')
|
|
75
|
+
.action(async (keyId, options) => {
|
|
76
|
+
const { keysUpdateCommand } = require('./commands/keys');
|
|
77
|
+
await keysUpdateCommand(keyId, options);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
keysCmd
|
|
81
|
+
.command('lock <key-id>')
|
|
82
|
+
.description('Lock a security key to an IP')
|
|
83
|
+
.option('--ip <ip-address>', 'Specific IP address to lock to')
|
|
84
|
+
.action(async (keyId, options) => {
|
|
85
|
+
const { keysLockCommand } = require('./commands/keys');
|
|
86
|
+
await keysLockCommand(keyId, options);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
keysCmd
|
|
90
|
+
.command('revoke <key-id>')
|
|
91
|
+
.description('Revoke a security key')
|
|
92
|
+
.action(async (keyId) => {
|
|
93
|
+
const { keysRevokeCommand } = require('./commands/keys');
|
|
94
|
+
await keysRevokeCommand(keyId);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Default: list keys
|
|
98
|
+
keysCmd
|
|
99
|
+
.action(async () => {
|
|
100
|
+
const { keysListCommand } = require('./commands/keys');
|
|
101
|
+
await keysListCommand();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// ── providers ────────────────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
program
|
|
107
|
+
.command('providers')
|
|
108
|
+
.description('List all supported AI providers')
|
|
109
|
+
.action(() => {
|
|
110
|
+
const providersCmd = require('./commands/providers');
|
|
111
|
+
providersCmd();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
// ── status ───────────────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
program
|
|
119
|
+
.command('status')
|
|
120
|
+
.description('Show current account and connection status')
|
|
121
|
+
.action(async () => {
|
|
122
|
+
const statusCmd = require('./commands/status');
|
|
123
|
+
await statusCmd();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// ── logout ───────────────────────────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
program
|
|
129
|
+
.command('logout')
|
|
130
|
+
.description('Clear stored credentials')
|
|
131
|
+
.action(() => {
|
|
132
|
+
const auth = getAuth();
|
|
133
|
+
if (!auth) {
|
|
134
|
+
console.log(chalk.dim('\n Already logged out.\n'));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
clearAuth();
|
|
138
|
+
console.log(chalk.green('\n ✓ Logged out. Credentials cleared.\n'));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// ── Banner ───────────────────────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
program.addHelpText('beforeAll', `
|
|
144
|
+
${chalk.cyan.bold('🔐 SecureGate CLI v2.0')}
|
|
145
|
+
${chalk.dim('━'.repeat(50))}
|
|
146
|
+
${chalk.dim('Protect your AI agent API keys with hardware-grade security.')}
|
|
147
|
+
${chalk.dim('https://securegate.xyz')}
|
|
148
|
+
`);
|
|
149
|
+
|
|
150
|
+
program.addHelpText('afterAll', `
|
|
151
|
+
${chalk.dim('━'.repeat(50))}
|
|
152
|
+
${chalk.dim('Quick start:')}
|
|
153
|
+
${chalk.cyan('securegate login')} ${chalk.dim('Sign in to your account')}
|
|
154
|
+
${chalk.cyan('securegate connect')} ${chalk.dim('Add an AI provider')}
|
|
155
|
+
|
|
156
|
+
`);
|
|
157
|
+
|
|
158
|
+
// ── Parse ────────────────────────────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
program.parse(process.argv);
|
|
161
|
+
|
|
162
|
+
// Show help if no command
|
|
163
|
+
if (!process.argv.slice(2).length) {
|
|
164
|
+
program.help();
|
|
165
|
+
}
|