@vibe-assurance/cli 1.1.0 → 1.2.0
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/bin/vibe.js +6 -0
- package/package.json +1 -1
- package/src/commands/login.js +11 -4
- package/src/commands/whoami.js +65 -0
- package/src/config/credentials.js +35 -1
package/bin/vibe.js
CHANGED
|
@@ -10,6 +10,7 @@ const pkg = require('../package.json');
|
|
|
10
10
|
// Commands
|
|
11
11
|
const login = require('../src/commands/login');
|
|
12
12
|
const logout = require('../src/commands/logout');
|
|
13
|
+
const whoami = require('../src/commands/whoami');
|
|
13
14
|
const mcpServer = require('../src/commands/mcp-server');
|
|
14
15
|
const setupClaude = require('../src/commands/setup-claude');
|
|
15
16
|
const { registerProjectCommands } = require('../src/commands/projects');
|
|
@@ -29,6 +30,11 @@ program
|
|
|
29
30
|
.description('Clear stored credentials')
|
|
30
31
|
.action(logout);
|
|
31
32
|
|
|
33
|
+
program
|
|
34
|
+
.command('whoami')
|
|
35
|
+
.description('Show current authenticated user')
|
|
36
|
+
.action(whoami);
|
|
37
|
+
|
|
32
38
|
program
|
|
33
39
|
.command('mcp-server')
|
|
34
40
|
.description('Start the MCP server for Claude Code')
|
package/package.json
CHANGED
package/src/commands/login.js
CHANGED
|
@@ -5,7 +5,7 @@ const chalk = require('chalk');
|
|
|
5
5
|
const ora = require('ora');
|
|
6
6
|
const inquirer = require('inquirer');
|
|
7
7
|
const axios = require('axios');
|
|
8
|
-
const { storeCredentials, hasValidCredentials, setProjectId } = require('../config/credentials');
|
|
8
|
+
const { storeCredentials, hasValidCredentials, setProjectId, setUserInfo } = require('../config/credentials');
|
|
9
9
|
const { API_BASE_URL } = require('../api/client');
|
|
10
10
|
|
|
11
11
|
// Local callback server port (chosen to be unlikely to conflict)
|
|
@@ -162,9 +162,10 @@ async function login() {
|
|
|
162
162
|
/**
|
|
163
163
|
* CR-2026-043: Select project after successful authentication
|
|
164
164
|
* Fetches user's projects and prompts for selection if multiple exist
|
|
165
|
+
* Also stores and displays user info
|
|
165
166
|
*/
|
|
166
167
|
async function selectProject() {
|
|
167
|
-
const spinner = ora('Fetching your
|
|
168
|
+
const spinner = ora('Fetching your profile...').start();
|
|
168
169
|
|
|
169
170
|
try {
|
|
170
171
|
// Get credentials to make authenticated request
|
|
@@ -179,9 +180,15 @@ async function selectProject() {
|
|
|
179
180
|
}
|
|
180
181
|
});
|
|
181
182
|
|
|
182
|
-
const { projects, defaultProjectId } = response.data;
|
|
183
|
+
const { username, email, projects, defaultProjectId } = response.data;
|
|
183
184
|
spinner.stop();
|
|
184
185
|
|
|
186
|
+
// Store and display user info
|
|
187
|
+
if (username && email) {
|
|
188
|
+
await setUserInfo(username, email);
|
|
189
|
+
console.log(chalk.cyan(`\nSigned in as ${chalk.bold(username)} (${email})`));
|
|
190
|
+
}
|
|
191
|
+
|
|
185
192
|
if (!projects || projects.length === 0) {
|
|
186
193
|
console.log(chalk.yellow('\nNo projects found. A default project will be created when you first use the API.'));
|
|
187
194
|
return;
|
|
@@ -190,7 +197,7 @@ async function selectProject() {
|
|
|
190
197
|
if (projects.length === 1) {
|
|
191
198
|
// Auto-select single project
|
|
192
199
|
await setProjectId(projects[0]._id, projects[0].name);
|
|
193
|
-
console.log(chalk.green(
|
|
200
|
+
console.log(chalk.green(`✓ Selected project: ${projects[0].name}`));
|
|
194
201
|
return;
|
|
195
202
|
}
|
|
196
203
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whoami command - shows current authenticated user
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const ora = require('ora');
|
|
7
|
+
const axios = require('axios');
|
|
8
|
+
const { hasValidCredentials, getUserInfo, getCredentials, getProjectName } = require('../config/credentials');
|
|
9
|
+
const { API_BASE_URL } = require('../api/client');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Show current user info
|
|
13
|
+
* Command: vibe whoami
|
|
14
|
+
*/
|
|
15
|
+
async function whoami() {
|
|
16
|
+
// Check if logged in
|
|
17
|
+
if (!await hasValidCredentials()) {
|
|
18
|
+
console.log(chalk.red('Not logged in.'));
|
|
19
|
+
console.log(chalk.dim('Run `vibe login` to authenticate.'));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Try to get cached user info first
|
|
24
|
+
const cachedUser = await getUserInfo();
|
|
25
|
+
const projectName = await getProjectName();
|
|
26
|
+
|
|
27
|
+
if (cachedUser) {
|
|
28
|
+
console.log(chalk.cyan(`\nSigned in as ${chalk.bold(cachedUser.username)} (${cachedUser.email})`));
|
|
29
|
+
if (projectName) {
|
|
30
|
+
console.log(chalk.dim(`Current project: ${projectName}`));
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// If no cached info, fetch from API
|
|
36
|
+
const spinner = ora('Fetching user info...').start();
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const creds = await getCredentials();
|
|
40
|
+
const response = await axios.get(`${API_BASE_URL}/api/auth/me`, {
|
|
41
|
+
headers: {
|
|
42
|
+
'Authorization': `Bearer ${creds.accessToken}`,
|
|
43
|
+
'Content-Type': 'application/json'
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const { username, email } = response.data;
|
|
48
|
+
spinner.stop();
|
|
49
|
+
|
|
50
|
+
if (username && email) {
|
|
51
|
+
console.log(chalk.cyan(`\nSigned in as ${chalk.bold(username)} (${email})`));
|
|
52
|
+
if (projectName) {
|
|
53
|
+
console.log(chalk.dim(`Current project: ${projectName}`));
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
console.log(chalk.yellow('Could not retrieve user info.'));
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
spinner.stop();
|
|
60
|
+
console.error(chalk.red('Failed to fetch user info:'), err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = whoami;
|
|
@@ -156,6 +156,38 @@ async function setProjectId(projectId, projectName) {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Get stored user info
|
|
161
|
+
* @returns {Promise<{username: string, email: string}|null>} User info or null
|
|
162
|
+
*/
|
|
163
|
+
async function getUserInfo() {
|
|
164
|
+
const creds = await getCredentials();
|
|
165
|
+
if (creds?.username && creds?.email) {
|
|
166
|
+
return {
|
|
167
|
+
username: creds.username,
|
|
168
|
+
email: creds.email
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Set user info (updates existing credentials)
|
|
176
|
+
* @param {string} username - Username to store
|
|
177
|
+
* @param {string} email - Email to store
|
|
178
|
+
* @returns {Promise<void>}
|
|
179
|
+
*/
|
|
180
|
+
async function setUserInfo(username, email) {
|
|
181
|
+
const creds = await getCredentials();
|
|
182
|
+
if (creds) {
|
|
183
|
+
await storeCredentials({
|
|
184
|
+
...creds,
|
|
185
|
+
username,
|
|
186
|
+
email
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
159
191
|
module.exports = {
|
|
160
192
|
storeCredentials,
|
|
161
193
|
getCredentials,
|
|
@@ -163,5 +195,7 @@ module.exports = {
|
|
|
163
195
|
hasValidCredentials,
|
|
164
196
|
getProjectId,
|
|
165
197
|
getProjectName,
|
|
166
|
-
setProjectId
|
|
198
|
+
setProjectId,
|
|
199
|
+
getUserInfo,
|
|
200
|
+
setUserInfo
|
|
167
201
|
};
|