@ngocsangairvds/vsaf 3.2.10 → 3.2.11
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
CHANGED
package/src/global.js
CHANGED
|
@@ -17,7 +17,10 @@ async function installGlobal() {
|
|
|
17
17
|
installSkills();
|
|
18
18
|
installBinary('gitnexus', () => exec('npm install -g gitnexus@1.6.4-rc.79'));
|
|
19
19
|
setupGitnexusMcp();
|
|
20
|
-
|
|
20
|
+
const isWin = process.platform === 'win32';
|
|
21
|
+
installBinary('uv', () => isWin
|
|
22
|
+
? exec('powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"')
|
|
23
|
+
: exec('curl -LsSf https://astral.sh/uv/install.sh | sh'));
|
|
21
24
|
await setupVdsScriptsMcp();
|
|
22
25
|
|
|
23
26
|
console.log('\n\x1b[32m\x1b[1m✓ Global infra ready.\x1b[0m\n');
|
|
@@ -74,6 +77,47 @@ function setupGitnexusMcp() {
|
|
|
74
77
|
|
|
75
78
|
|
|
76
79
|
|
|
80
|
+
function installVdsCliwrapper(vdsRoot) {
|
|
81
|
+
const os = require('os');
|
|
82
|
+
const isWin = process.platform === 'win32';
|
|
83
|
+
|
|
84
|
+
if (isWin) {
|
|
85
|
+
const wrapperDir = path.join(os.homedir(), '.local', 'bin');
|
|
86
|
+
const wrapperPath = path.join(wrapperDir, 'vds-cli.cmd');
|
|
87
|
+
fs.mkdirSync(wrapperDir, { recursive: true });
|
|
88
|
+
fs.writeFileSync(wrapperPath, [
|
|
89
|
+
'@echo off',
|
|
90
|
+
`set "ROOT=${vdsRoot}"`,
|
|
91
|
+
`set "VENV=%ROOT%\\.venv"`,
|
|
92
|
+
`if exist "%USERPROFILE%\\.vds\\.env" (`,
|
|
93
|
+
` for /f "usebackq tokens=*" %%a in ("%USERPROFILE%\\.vds\\.env") do set "%%a"`,
|
|
94
|
+
`)`,
|
|
95
|
+
`"%VENV%\\Scripts\\vds-cli.exe" %*`,
|
|
96
|
+
].join('\r\n'));
|
|
97
|
+
ok(`vds-cli wrapper → ${wrapperPath}`);
|
|
98
|
+
const inPath = (process.env.PATH || '').split(';').some(p => p.toLowerCase() === wrapperDir.toLowerCase());
|
|
99
|
+
if (!inPath) warn(`Thêm vào PATH: ${wrapperDir}`);
|
|
100
|
+
} else {
|
|
101
|
+
const wrapperDir = path.join(os.homedir(), '.local', 'bin');
|
|
102
|
+
const wrapperPath = path.join(wrapperDir, 'vds-cli');
|
|
103
|
+
fs.mkdirSync(wrapperDir, { recursive: true });
|
|
104
|
+
fs.writeFileSync(wrapperPath, [
|
|
105
|
+
'#!/usr/bin/env bash',
|
|
106
|
+
'set -euo pipefail',
|
|
107
|
+
`ROOT="${vdsRoot}"`,
|
|
108
|
+
'VENV="$ROOT/.venv"',
|
|
109
|
+
'if [[ -n "${VIRTUAL_ENV:-}" && "${VIRTUAL_ENV}" != "$VENV" ]]; then unset VIRTUAL_ENV; fi',
|
|
110
|
+
'unset UV_PROJECT_ENVIRONMENT CONDA_PREFIX 2>/dev/null || true',
|
|
111
|
+
'if [[ -f "$HOME/.vds/.env" ]]; then set -a; source "$HOME/.vds/.env"; set +a; fi',
|
|
112
|
+
'exec "$VENV/bin/vds-cli" "$@"',
|
|
113
|
+
].join('\n') + '\n');
|
|
114
|
+
fs.chmodSync(wrapperPath, 0o755);
|
|
115
|
+
ok(`vds-cli wrapper → ${wrapperPath}`);
|
|
116
|
+
const inPath = (process.env.PATH || '').split(':').includes(wrapperDir);
|
|
117
|
+
if (!inPath) warn(`Thêm vào ~/.bashrc hoặc ~/.zshrc: export PATH="$HOME/.local/bin:$PATH"`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
77
121
|
async function setupVdsScriptsMcp() {
|
|
78
122
|
step('VDS Scripts MCP');
|
|
79
123
|
|
|
@@ -93,7 +137,15 @@ async function setupVdsScriptsMcp() {
|
|
|
93
137
|
|
|
94
138
|
fs.mkdirSync(path.dirname(destDir), { recursive: true });
|
|
95
139
|
copyDir(srcDir, destDir);
|
|
96
|
-
ok('
|
|
140
|
+
ok('Đã sao chép vds-scripts.');
|
|
141
|
+
|
|
142
|
+
info('Đang khởi tạo môi trường Python (uv sync)...');
|
|
143
|
+
if (!exec(`uv sync --frozen --project "${destDir}"`, { silent: true })) {
|
|
144
|
+
exec(`uv sync --project "${destDir}"`, { silent: true });
|
|
145
|
+
}
|
|
146
|
+
ok('Môi trường Python đã sẵn sàng.');
|
|
147
|
+
|
|
148
|
+
installVdsCliwrapper(destDir);
|
|
97
149
|
|
|
98
150
|
step('Cấu hình VDS CLI và Credentials');
|
|
99
151
|
const envDir = path.join(require('os').homedir(), '.vds');
|
|
@@ -131,7 +183,8 @@ async function setupVdsScriptsMcp() {
|
|
|
131
183
|
ok('Đã tìm thấy file cấu hình ~/.vds/.env');
|
|
132
184
|
}
|
|
133
185
|
|
|
134
|
-
|
|
186
|
+
exec('claude mcp remove vds-orchestrator', { silent: true });
|
|
187
|
+
const cmd = `claude mcp add vds-orchestrator --scope user -e VDS_SCRIPTS_ROOT="${destDir}" -- uv run --project "${mcpDir}" vds-mcp-server`;
|
|
135
188
|
|
|
136
189
|
if (exec(cmd)) {
|
|
137
190
|
ok('VDS Scripts MCP đã được cấu hình thành công');
|
package/src/utils.js
CHANGED
|
@@ -18,7 +18,10 @@ function hasCommand(cmd) {
|
|
|
18
18
|
if (versionCheck.status === 0) return true;
|
|
19
19
|
|
|
20
20
|
// Fallback: check if command exists on PATH
|
|
21
|
-
const
|
|
21
|
+
const isWin = process.platform === 'win32';
|
|
22
|
+
const pathCheck = isWin
|
|
23
|
+
? spawnSync('where', [cmd], { stdio: 'ignore', shell: false })
|
|
24
|
+
: spawnSync('sh', ['-c', `command -v "${cmd}"`], { stdio: 'ignore', shell: false });
|
|
22
25
|
return pathCheck.status === 0;
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -73,6 +76,7 @@ function cleanStaleWal() {
|
|
|
73
76
|
|
|
74
77
|
function getPlatform() {
|
|
75
78
|
if (process.platform === 'darwin') return 'macos';
|
|
79
|
+
if (process.platform === 'win32') return 'windows';
|
|
76
80
|
return 'linux';
|
|
77
81
|
}
|
|
78
82
|
|
|
@@ -222,29 +222,31 @@ class ConfluenceClient:
|
|
|
222
222
|
client_cls = AtlassianConfluenceCloud if self._is_cloud else AtlassianConfluenceServer
|
|
223
223
|
|
|
224
224
|
# Configure authentication based on available credentials
|
|
225
|
+
# Token (Bearer/PAT) takes priority over username+password to avoid 401s
|
|
226
|
+
# when Basic auth is disabled on the server.
|
|
225
227
|
auth_kwargs: dict[str, Any] = {"url": base_url, "timeout": self._timeout}
|
|
226
228
|
if self._is_cloud:
|
|
227
|
-
if
|
|
229
|
+
if token:
|
|
230
|
+
auth_kwargs["token"] = token
|
|
231
|
+
elif settings.username and settings.password:
|
|
228
232
|
auth_kwargs["username"] = settings.username
|
|
229
233
|
auth_kwargs["password"] = resolve_secret(settings.password)
|
|
230
|
-
elif token:
|
|
231
|
-
auth_kwargs["token"] = token
|
|
232
234
|
else:
|
|
233
235
|
raise AuthError(
|
|
234
236
|
f"No credentials available for cloud server '{self._server}'. "
|
|
235
|
-
"Provide
|
|
237
|
+
"Provide an API token or VDS_USERNAME+VDS_PASSWORD.",
|
|
236
238
|
context={"server": self._server},
|
|
237
239
|
)
|
|
240
|
+
elif token:
|
|
241
|
+
# PATs supported on Confluence Server/Data Center
|
|
242
|
+
auth_kwargs["token"] = token
|
|
238
243
|
elif settings.username and settings.password:
|
|
239
244
|
auth_kwargs["username"] = settings.username
|
|
240
245
|
auth_kwargs["password"] = resolve_secret(settings.password)
|
|
241
|
-
elif token:
|
|
242
|
-
# Recent ConfluenceServer class also supports PATs
|
|
243
|
-
auth_kwargs["token"] = token
|
|
244
246
|
else:
|
|
245
247
|
raise AuthError(
|
|
246
248
|
f"No credentials available for server '{self._server}'. "
|
|
247
|
-
"Provide
|
|
249
|
+
"Provide a CONFLUENCE token or VDS_USERNAME+VDS_PASSWORD.",
|
|
248
250
|
context={"server": self._server},
|
|
249
251
|
)
|
|
250
252
|
client_params = set(self._safe_signature_params(client_cls))
|