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.
@@ -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
+ }