@ngocsangairvds/vsaf 3.2.1 → 3.2.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/package.json +2 -2
- package/src/global.js +24 -59
- package/src/project.js +4 -2
- package/src/status.js +15 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngocsangairvds/vsaf",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"description": "add vds script",
|
|
3
|
+
"version": "3.2.3",
|
|
4
|
+
"description": "add vds script env",
|
|
5
5
|
"keywords": ["claude", "claude-code", "ai", "sdlc", "framework", "bmad", "gitnexus", "superpowers"],
|
|
6
6
|
"bin": {
|
|
7
7
|
"vsaf": "./bin/vsaf.js"
|
package/src/global.js
CHANGED
|
@@ -11,13 +11,13 @@ const CODEX_SKILLS_DST = path.join(CODEX_HOME, 'skills');
|
|
|
11
11
|
|
|
12
12
|
async function installGlobal() {
|
|
13
13
|
console.log('\n\x1b[1m╔══════════════════════════════════════════╗\x1b[0m');
|
|
14
|
-
console.log('\x1b[1m║ VSAF — Global Infra ║\x1b[0m');
|
|
15
|
-
console.log('\x1b[1m╚══════════════════════════════════════════╝\x1b[0m');
|
|
14
|
+
console.log('\x1b [1m║ VSAF — Global Infra ║\x1b[0m');
|
|
15
|
+
console.log('\x1b[ 1m╚══════════════════════════════════════════╝\x1b[0m');
|
|
16
16
|
|
|
17
17
|
installSkills();
|
|
18
18
|
installBinary('gitnexus', () => exec('npm install -g gitnexus@1.6.4-rc.79'));
|
|
19
19
|
setupGitnexusMcp();
|
|
20
|
-
|
|
20
|
+
installBinary('uv', () => exec('curl -LsSf https://astral.sh/uv/install.sh | sh'));
|
|
21
21
|
await setupVdsScriptsMcp();
|
|
22
22
|
|
|
23
23
|
console.log('\n\x1b[32m\x1b[1m✓ Global infra ready.\x1b[0m\n');
|
|
@@ -72,50 +72,7 @@ function setupGitnexusMcp() {
|
|
|
72
72
|
: warn('MCP setup failed — run manually: claude mcp add gitnexus -- npx -y gitnexus@1.6.4-rc.79 mcp');
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
async function setupConfluenceMcp() {
|
|
76
|
-
step('Confluence MCP');
|
|
77
75
|
|
|
78
|
-
if (!hasCommand('claude')) {
|
|
79
|
-
info('Claude Code CLI not found — skip Confluence MCP setup');
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const url = await promptInput(
|
|
84
|
-
' Confluence URL (blank to skip, e.g. http://confluence.company.com): '
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
if (!url) {
|
|
88
|
-
warn('Confluence MCP skipped — run manually later:\n' +
|
|
89
|
-
' claude mcp add confluence -e CONF_MODE=server \\\n' +
|
|
90
|
-
' -e CONF_BASE_URL=<your-url> \\\n' +
|
|
91
|
-
' -e CONF_AUTH_MODE=bearer \\\n' +
|
|
92
|
-
' -e CONF_TOKEN=<your-token> \\\n' +
|
|
93
|
-
' -- npx -y confluence-mcp-server');
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const token = await promptSecret(
|
|
98
|
-
' Confluence Personal Access Token: '
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (!token) {
|
|
102
|
-
warn('Confluence MCP skipped — token is required');
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const cmd = [
|
|
107
|
-
'claude mcp add confluence',
|
|
108
|
-
'-e CONF_MODE=server',
|
|
109
|
-
`-e CONF_BASE_URL=${url}`,
|
|
110
|
-
'-e CONF_AUTH_MODE=bearer',
|
|
111
|
-
`-e CONF_TOKEN=${token}`,
|
|
112
|
-
'-- npx -y confluence-mcp-server',
|
|
113
|
-
].join(' ');
|
|
114
|
-
|
|
115
|
-
exec(cmd)
|
|
116
|
-
? ok('Confluence MCP configured')
|
|
117
|
-
: warn('Confluence MCP setup failed — run manually (see above)');
|
|
118
|
-
}
|
|
119
76
|
|
|
120
77
|
async function setupVdsScriptsMcp() {
|
|
121
78
|
step('VDS Scripts MCP');
|
|
@@ -126,37 +83,46 @@ async function setupVdsScriptsMcp() {
|
|
|
126
83
|
}
|
|
127
84
|
|
|
128
85
|
const srcDir = path.join(PKG_ROOT, 'tools', 'vds-scripts');
|
|
86
|
+
const destDir = path.join(CLAUDE_HOME, 'vds-scripts');
|
|
87
|
+
const mcpDir = path.join(destDir, 'mcp_server');
|
|
88
|
+
|
|
89
|
+
info(`Source: ${srcDir}`);
|
|
129
90
|
if (!fs.existsSync(srcDir)) {
|
|
130
91
|
warn('Không tìm thấy source vds-scripts trong package — bỏ qua cài đặt.');
|
|
131
92
|
return;
|
|
132
93
|
}
|
|
133
94
|
|
|
134
|
-
const destDir = path.join(CLAUDE_HOME, 'vds-scripts');
|
|
135
|
-
const mcpDir = path.join(destDir, 'mcp_server');
|
|
136
|
-
|
|
137
|
-
info(`Đang copy mã nguồn vds-scripts vào ${destDir}...`);
|
|
138
95
|
fs.mkdirSync(path.dirname(destDir), { recursive: true });
|
|
139
96
|
copyDir(srcDir, destDir);
|
|
140
|
-
ok('
|
|
97
|
+
ok('Cài đặt thành công.');
|
|
141
98
|
|
|
142
99
|
step('Cấu hình VDS CLI và Credentials');
|
|
143
100
|
const envDir = path.join(require('os').homedir(), '.vds');
|
|
144
101
|
const envFile = path.join(envDir, '.env');
|
|
145
102
|
if (!fs.existsSync(envFile)) {
|
|
146
|
-
info('Đang khởi tạo file cấu hình ~/.vds/.env...');
|
|
147
103
|
fs.mkdirSync(envDir, { recursive: true });
|
|
148
104
|
|
|
149
|
-
info('Vui lòng cung cấp các thông tin xác thực sau (để
|
|
105
|
+
info('Vui lòng cung cấp các thông tin xác thực sau (Enter để bỏ qua nếu đã có sẵn):');
|
|
150
106
|
const vdsUsername = await promptInput(' Nhập VDS_USERNAME: ');
|
|
151
107
|
const vdsPassword = await promptSecret(' Nhập VDS_PASSWORD: ');
|
|
152
|
-
const bitbucketToken = await promptSecret(' Nhập
|
|
108
|
+
const bitbucketToken = await promptSecret(' Nhập BITBUCKET_TOKEN: ');
|
|
109
|
+
const jiraToken = await promptSecret(' Nhập JIRA_TOKEN: ');
|
|
110
|
+
const confluenceToken = await promptSecret(' Nhập INTERNAL_CONFLUENCE_TOKEN: ');
|
|
111
|
+
const extConfluenceToken = await promptSecret(' Nhập EXTERNAL_CONFLUENCE_TOKEN: ');
|
|
112
|
+
|
|
113
|
+
const confluenceInternalUrl = (await promptInput(' Nhập CONFLUENCE_INTERNAL_URL (ex: http://10.254.136.35:8090): ')) || 'http://10.254.136.35:8090';
|
|
114
|
+
const confluenceExternalUrl = (await promptInput(' Nhập CONFLUENCE_EXTERNAL_URL (ex: https://atlassian.digital.vn): ')) || 'https://atlassian.digital.vn';
|
|
153
115
|
|
|
154
116
|
const envContent = [
|
|
155
117
|
`VDS_USERNAME=${vdsUsername}`,
|
|
156
118
|
`VDS_PASSWORD=${vdsPassword}`,
|
|
157
|
-
`
|
|
158
|
-
|
|
159
|
-
|
|
119
|
+
`BITBUCKET_TOKEN=${bitbucketToken}`,
|
|
120
|
+
`JIRA_TOKEN=${jiraToken}`,
|
|
121
|
+
`INTERNAL_CONFLUENCE_TOKEN=${confluenceToken}`,
|
|
122
|
+
`EXTERNAL_CONFLUENCE_TOKEN=${extConfluenceToken}`,
|
|
123
|
+
'JIRA_BASE_URL=https://jira.viettelmoney.vn/',
|
|
124
|
+
`CONFLUENCE_INTERNAL_URL=${confluenceInternalUrl}`,
|
|
125
|
+
`CONFLUENCE_EXTERNAL_URL=${confluenceExternalUrl}`,
|
|
160
126
|
'BITBUCKET_BASE_URL=http://bitbucket.digital.vn'
|
|
161
127
|
].join('\n') + '\n';
|
|
162
128
|
|
|
@@ -166,7 +132,6 @@ async function setupVdsScriptsMcp() {
|
|
|
166
132
|
ok('Đã tìm thấy file cấu hình ~/.vds/.env');
|
|
167
133
|
}
|
|
168
134
|
|
|
169
|
-
info('Đang cấu hình VDS Scripts MCP vào Claude...');
|
|
170
135
|
const cmd = `claude mcp add vds-orchestrator -- uv run --project "${mcpDir}" vds-mcp-server`;
|
|
171
136
|
|
|
172
137
|
if (exec(cmd)) {
|
|
@@ -222,4 +187,4 @@ function promptSecret(question) {
|
|
|
222
187
|
});
|
|
223
188
|
}
|
|
224
189
|
|
|
225
|
-
module.exports = { installGlobal };
|
|
190
|
+
module.exports = { installGlobal, setupVdsScriptsMcp };
|
package/src/project.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, cleanStaleWal } = require('./utils');
|
|
5
|
+
const { setupVdsScriptsMcp } = require('./global');
|
|
5
6
|
|
|
6
7
|
const PKG_ROOT = path.join(__dirname, '..');
|
|
7
8
|
const TEMPLATES = path.join(PKG_ROOT, 'assets', 'templates');
|
|
@@ -16,8 +17,9 @@ async function installProject() {
|
|
|
16
17
|
|
|
17
18
|
scaffoldFiles();
|
|
18
19
|
scaffoldBmadWorkspace();
|
|
19
|
-
|
|
20
|
+
syncLocalSkills();
|
|
20
21
|
initGitNexus();
|
|
22
|
+
await setupVdsScriptsMcp();
|
|
21
23
|
|
|
22
24
|
console.log('\n\x1b[32m\x1b[1m✓ Project ready.\x1b[0m');
|
|
23
25
|
console.log('\n Next steps:');
|
|
@@ -128,7 +130,7 @@ function syncLocalBmadSkills() {
|
|
|
128
130
|
|
|
129
131
|
const entries = fs
|
|
130
132
|
.readdirSync(SKILLS_SRC, { withFileTypes: true })
|
|
131
|
-
.filter((entry) => entry.name.startsWith('bmad-'));
|
|
133
|
+
.filter((entry) => entry.name.startsWith('bmad-') || entry.name.startsWith('vsaf-') || entry.name.startsWith('vds-'));
|
|
132
134
|
|
|
133
135
|
if (entries.length === 0) {
|
|
134
136
|
warn('No BMAD skills found in package — skipping');
|
package/src/status.js
CHANGED
|
@@ -11,7 +11,9 @@ async function showStatus() {
|
|
|
11
11
|
checkSkills();
|
|
12
12
|
checkCodexSkills();
|
|
13
13
|
checkCmd('gitnexus', 'GitNexus');
|
|
14
|
-
|
|
14
|
+
checkCmd('uv', 'UV Package Manager');
|
|
15
|
+
checkVdsScripts();
|
|
16
|
+
checkVdsEnv();
|
|
15
17
|
// ── Project ────────────────────────────────────────────────────────────────
|
|
16
18
|
console.log('\n\x1b[1mProject (current repo)\x1b[0m');
|
|
17
19
|
checkPath('.claude/settings.json', 'Claude settings');
|
|
@@ -71,4 +73,16 @@ function checkProjectSkillDir(rel, label) {
|
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
function checkVdsScripts() {
|
|
77
|
+
const dir = path.join(CLAUDE_HOME, 'vds-scripts');
|
|
78
|
+
const exists = fs.existsSync(dir);
|
|
79
|
+
console.log(` ${exists ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m'} VDS Scripts (~/.claude/vds-scripts)`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function checkVdsEnv() {
|
|
83
|
+
const file = path.join(require('os').homedir(), '.vds', '.env');
|
|
84
|
+
const exists = fs.existsSync(file);
|
|
85
|
+
console.log(` ${exists ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m'} VDS Config (~/.vds/.env)`);
|
|
86
|
+
}
|
|
87
|
+
|
|
74
88
|
module.exports = { showStatus };
|