@vibe-assurance/cli 1.1.0 → 1.3.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/README.md +33 -1
- 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/src/mcp/tools.js +3 -3
package/README.md
CHANGED
|
@@ -34,6 +34,9 @@ npm install -g @vibe-assurance/cli
|
|
|
34
34
|
| `vibe logout` | Clear stored credentials |
|
|
35
35
|
| `vibe mcp-server` | Start the MCP server (used by AI coding agents) |
|
|
36
36
|
| `vibe setup-claude` | Configure MCP client to use Vibe Assurance |
|
|
37
|
+
| `vibe projects` | List your accessible projects |
|
|
38
|
+
| `vibe project current` | Show current project |
|
|
39
|
+
| `vibe project select` | Switch to a different project |
|
|
37
40
|
| `vibe --version` | Show CLI version |
|
|
38
41
|
|
|
39
42
|
### MCP Tools
|
|
@@ -61,12 +64,28 @@ Once configured, your AI coding agent has access to these tools:
|
|
|
61
64
|
|
|
62
65
|
| Tool | Description |
|
|
63
66
|
|------|-------------|
|
|
64
|
-
| `vibe_store_artifact` | Store a created document (CR, risk, vulnerability, etc.) |
|
|
67
|
+
| `vibe_store_artifact` | Store a created document (CR, risk, vulnerability, plan, etc.) |
|
|
65
68
|
| `vibe_update_artifact` | Update an existing artifact |
|
|
69
|
+
| `vibe_append_file` | Safely add a file to an artifact without replacing others |
|
|
66
70
|
| `vibe_list_artifacts` | List your stored artifacts |
|
|
67
71
|
| `vibe_get_artifact` | Get a specific artifact by ID |
|
|
68
72
|
| `vibe_delete_artifact` | Delete an artifact |
|
|
69
73
|
|
|
74
|
+
#### Artifact Types
|
|
75
|
+
|
|
76
|
+
The following artifact types are supported:
|
|
77
|
+
|
|
78
|
+
| Type | Description | Example ID |
|
|
79
|
+
|------|-------------|------------|
|
|
80
|
+
| `CR` | Change Requests | CR-2026-051 |
|
|
81
|
+
| `RISK` | Risk Register Entries | RISK-001 |
|
|
82
|
+
| `VULNERABILITY` | Security Vulnerabilities | VUL-059 |
|
|
83
|
+
| `REPORT` | Security/Audit Reports | RPT-2026-001 |
|
|
84
|
+
| `POLICY` | Governance Policies | POL-001 |
|
|
85
|
+
| `PLAN` | Strategic & Technical Plans | PLAN-2026-002 |
|
|
86
|
+
| `ARCHITECTURE` | Architecture Decision Records | ADR-001 |
|
|
87
|
+
| `CONFIG` | Configuration Documentation | CFG-001 |
|
|
88
|
+
|
|
70
89
|
### Example Session
|
|
71
90
|
|
|
72
91
|
```
|
|
@@ -174,6 +193,19 @@ Then remove the MCP configuration from your AI agent's config file.
|
|
|
174
193
|
- All API communication uses HTTPS
|
|
175
194
|
- Tokens auto-refresh when expired
|
|
176
195
|
|
|
196
|
+
## Changelog
|
|
197
|
+
|
|
198
|
+
### v1.3.0 (2026-01-06)
|
|
199
|
+
- Added `PLAN`, `ARCHITECTURE`, `CONFIG` artifact types
|
|
200
|
+
- Enables Technical Strategist to store plans as PLAN artifacts
|
|
201
|
+
- Supports architecture decision records (ADRs)
|
|
202
|
+
- Supports configuration documentation
|
|
203
|
+
|
|
204
|
+
### v1.2.0
|
|
205
|
+
- Added `vibe_append_file` for safe file additions to artifacts
|
|
206
|
+
- Added project management commands (`vibe projects`, `vibe project select`)
|
|
207
|
+
- Improved token refresh handling
|
|
208
|
+
|
|
177
209
|
## License
|
|
178
210
|
|
|
179
211
|
MIT
|
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
|
};
|
package/src/mcp/tools.js
CHANGED
|
@@ -173,13 +173,13 @@ const tools = [
|
|
|
173
173
|
|
|
174
174
|
{
|
|
175
175
|
name: 'vibe_store_artifact',
|
|
176
|
-
description: 'Store a created document (CR, report, risk, vulnerability, etc.) in Vibe Assurance. The artifact will be saved to your account and visible in the web portal.',
|
|
176
|
+
description: 'Store a created document (CR, report, risk, vulnerability, plan, architecture, config, etc.) in Vibe Assurance. The artifact will be saved to your account and visible in the web portal.',
|
|
177
177
|
inputSchema: {
|
|
178
178
|
type: 'object',
|
|
179
179
|
properties: {
|
|
180
180
|
type: {
|
|
181
181
|
type: 'string',
|
|
182
|
-
enum: ['CR', 'RISK', 'VULNERABILITY', 'REPORT', 'POLICY'],
|
|
182
|
+
enum: ['CR', 'RISK', 'VULNERABILITY', 'REPORT', 'POLICY', 'PLAN', 'ARCHITECTURE', 'CONFIG'],
|
|
183
183
|
description: 'Type of artifact'
|
|
184
184
|
},
|
|
185
185
|
artifactId: {
|
|
@@ -304,7 +304,7 @@ const tools = [
|
|
|
304
304
|
properties: {
|
|
305
305
|
type: {
|
|
306
306
|
type: 'string',
|
|
307
|
-
enum: ['CR', 'RISK', 'VULNERABILITY', 'REPORT', 'POLICY'],
|
|
307
|
+
enum: ['CR', 'RISK', 'VULNERABILITY', 'REPORT', 'POLICY', 'PLAN', 'ARCHITECTURE', 'CONFIG'],
|
|
308
308
|
description: 'Filter by artifact type'
|
|
309
309
|
},
|
|
310
310
|
status: {
|