@ayurak/aribot-cli 1.0.2 → 1.0.3
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/cli.js +23 -12
- package/package.json +1 -1
- package/src/cli.ts +23 -12
package/dist/cli.js
CHANGED
|
@@ -37,7 +37,7 @@ function getHeaders() {
|
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
|
-
'
|
|
40
|
+
'X-API-Key': apiKey,
|
|
41
41
|
'Content-Type': 'application/json'
|
|
42
42
|
};
|
|
43
43
|
}
|
|
@@ -64,19 +64,28 @@ program
|
|
|
64
64
|
message: 'Enter your Aribot API key:',
|
|
65
65
|
mask: '*'
|
|
66
66
|
}]);
|
|
67
|
-
const spinner = (0, ora_1.default)('
|
|
67
|
+
const spinner = (0, ora_1.default)('Exchanging API key for token...').start();
|
|
68
68
|
try {
|
|
69
69
|
const fetch = (await import('node-fetch')).default;
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
// Exchange API key for JWT token
|
|
71
|
+
const response = await fetch(`${API_BASE}/v1/developer/token/`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: { 'Content-Type': 'application/json' },
|
|
74
|
+
body: JSON.stringify({ api_key: apiKey })
|
|
72
75
|
});
|
|
73
76
|
if (response.ok) {
|
|
77
|
+
const data = await response.json();
|
|
78
|
+
config.set('accessToken', data.access);
|
|
79
|
+
config.set('refreshToken', data.refresh);
|
|
74
80
|
config.set('apiKey', apiKey);
|
|
81
|
+
config.set('userEmail', data.user?.email);
|
|
82
|
+
config.set('company', data.user?.company);
|
|
75
83
|
spinner.succeed(chalk_1.default.green('Authenticated successfully!'));
|
|
76
|
-
console.log(chalk_1.default.dim(
|
|
84
|
+
console.log(chalk_1.default.dim(`Logged in as ${data.user?.email}`));
|
|
77
85
|
}
|
|
78
86
|
else {
|
|
79
|
-
|
|
87
|
+
const error = await response.json();
|
|
88
|
+
spinner.fail(chalk_1.default.red(error.message || 'Invalid API key'));
|
|
80
89
|
}
|
|
81
90
|
}
|
|
82
91
|
catch (error) {
|
|
@@ -108,8 +117,9 @@ program
|
|
|
108
117
|
return;
|
|
109
118
|
}
|
|
110
119
|
data.results.forEach((d) => {
|
|
111
|
-
const status = d.
|
|
112
|
-
|
|
120
|
+
const status = d.stage === 'completed' ? chalk_1.default.green('✓') : chalk_1.default.yellow('⋯');
|
|
121
|
+
const name = d.name || d.filename || 'Unnamed';
|
|
122
|
+
console.log(`${status} ${chalk_1.default.cyan(d.id.slice(0, 8))} ${name} ${chalk_1.default.dim(d.threats_count + ' threats')}`);
|
|
113
123
|
});
|
|
114
124
|
console.log(chalk_1.default.dim(`\nShowing ${data.results.length} of ${data.count} diagrams`));
|
|
115
125
|
}
|
|
@@ -193,13 +203,14 @@ program
|
|
|
193
203
|
medium: chalk_1.default.blue,
|
|
194
204
|
low: chalk_1.default.dim
|
|
195
205
|
};
|
|
196
|
-
data.results
|
|
206
|
+
const threats = data.threats || data.results || [];
|
|
207
|
+
threats.forEach((t) => {
|
|
197
208
|
const color = severityColors[t.severity] || chalk_1.default.white;
|
|
198
|
-
console.log(`${color(`[${t.severity
|
|
199
|
-
console.log(chalk_1.default.dim(`
|
|
209
|
+
console.log(`${color(`[${t.severity?.toUpperCase() || 'UNKNOWN'}]`)} ${t.title || t.name}`);
|
|
210
|
+
console.log(chalk_1.default.dim(` Category: ${t.category || t.stride_category || 'N/A'} | ID: ${String(t.id).slice(0, 8)}`));
|
|
200
211
|
console.log();
|
|
201
212
|
});
|
|
202
|
-
console.log(chalk_1.default.dim(`Total: ${
|
|
213
|
+
console.log(chalk_1.default.dim(`Total: ${threats.length} threats`));
|
|
203
214
|
}
|
|
204
215
|
catch (error) {
|
|
205
216
|
spinner.fail('Failed to fetch threats');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ayurak/aribot-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "AI-powered threat modeling CLI by Ayurak. Automatically analyze diagrams, generate STRIDE threats, and get security recommendations.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
package/src/cli.ts
CHANGED
|
@@ -37,7 +37,7 @@ function getHeaders(): Record<string, string> {
|
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
|
-
'
|
|
40
|
+
'X-API-Key': apiKey,
|
|
41
41
|
'Content-Type': 'application/json'
|
|
42
42
|
};
|
|
43
43
|
}
|
|
@@ -69,20 +69,29 @@ program
|
|
|
69
69
|
mask: '*'
|
|
70
70
|
}]);
|
|
71
71
|
|
|
72
|
-
const spinner = ora('
|
|
72
|
+
const spinner = ora('Exchanging API key for token...').start();
|
|
73
73
|
|
|
74
74
|
try {
|
|
75
75
|
const fetch = (await import('node-fetch')).default;
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
// Exchange API key for JWT token
|
|
77
|
+
const response = await fetch(`${API_BASE}/v1/developer/token/`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: { 'Content-Type': 'application/json' },
|
|
80
|
+
body: JSON.stringify({ api_key: apiKey })
|
|
78
81
|
});
|
|
79
82
|
|
|
80
83
|
if (response.ok) {
|
|
84
|
+
const data = await response.json() as any;
|
|
85
|
+
config.set('accessToken', data.access);
|
|
86
|
+
config.set('refreshToken', data.refresh);
|
|
81
87
|
config.set('apiKey', apiKey);
|
|
88
|
+
config.set('userEmail', data.user?.email);
|
|
89
|
+
config.set('company', data.user?.company);
|
|
82
90
|
spinner.succeed(chalk.green('Authenticated successfully!'));
|
|
83
|
-
console.log(chalk.dim(
|
|
91
|
+
console.log(chalk.dim(`Logged in as ${data.user?.email}`));
|
|
84
92
|
} else {
|
|
85
|
-
|
|
93
|
+
const error = await response.json() as any;
|
|
94
|
+
spinner.fail(chalk.red(error.message || 'Invalid API key'));
|
|
86
95
|
}
|
|
87
96
|
} catch (error) {
|
|
88
97
|
spinner.fail(chalk.red('Authentication failed'));
|
|
@@ -119,8 +128,9 @@ program
|
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
data.results.forEach((d: any) => {
|
|
122
|
-
const status = d.
|
|
123
|
-
|
|
131
|
+
const status = d.stage === 'completed' ? chalk.green('✓') : chalk.yellow('⋯');
|
|
132
|
+
const name = d.name || d.filename || 'Unnamed';
|
|
133
|
+
console.log(`${status} ${chalk.cyan(d.id.slice(0, 8))} ${name} ${chalk.dim(d.threats_count + ' threats')}`);
|
|
124
134
|
});
|
|
125
135
|
|
|
126
136
|
console.log(chalk.dim(`\nShowing ${data.results.length} of ${data.count} diagrams`));
|
|
@@ -220,14 +230,15 @@ program
|
|
|
220
230
|
low: chalk.dim
|
|
221
231
|
};
|
|
222
232
|
|
|
223
|
-
data.results
|
|
233
|
+
const threats = data.threats || data.results || [];
|
|
234
|
+
threats.forEach((t: any) => {
|
|
224
235
|
const color = severityColors[t.severity] || chalk.white;
|
|
225
|
-
console.log(`${color(`[${t.severity
|
|
226
|
-
console.log(chalk.dim(`
|
|
236
|
+
console.log(`${color(`[${t.severity?.toUpperCase() || 'UNKNOWN'}]`)} ${t.title || t.name}`);
|
|
237
|
+
console.log(chalk.dim(` Category: ${t.category || t.stride_category || 'N/A'} | ID: ${String(t.id).slice(0, 8)}`));
|
|
227
238
|
console.log();
|
|
228
239
|
});
|
|
229
240
|
|
|
230
|
-
console.log(chalk.dim(`Total: ${
|
|
241
|
+
console.log(chalk.dim(`Total: ${threats.length} threats`));
|
|
231
242
|
} catch (error) {
|
|
232
243
|
spinner.fail('Failed to fetch threats');
|
|
233
244
|
console.error(error);
|