@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngocsangairvds/vsaf",
3
- "version": "3.2.10",
3
+ "version": "3.2.11",
4
4
  "description": "improve confluence format",
5
5
  "keywords": ["claude", "claude-code", "ai", "sdlc", "framework", "bmad", "gitnexus", "superpowers"],
6
6
  "bin": {
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
- installBinary('uv', () => exec('curl -LsSf https://astral.sh/uv/install.sh | sh'));
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('Cài đặt thành công.');
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
- const cmd = `claude mcp add vds-orchestrator -e VDS_SCRIPTS_ROOT="${destDir}" -- uv run --project "${mcpDir}" vds-mcp-server`;
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 pathCheck = spawnSync('sh', ['-c', `command -v "${cmd}"`], { stdio: 'ignore', shell: false });
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 settings.username and settings.password:
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 VDS_USERNAME+VDS_PASSWORD or an API token.",
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 VDS_USERNAME+VDS_PASSWORD or a CONFLUENCE token.",
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))