@ngocsangairvds/vsaf 3.1.3 → 3.1.5

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/vsaf.js CHANGED
@@ -95,24 +95,50 @@ async function main() {
95
95
 
96
96
  function printInstallHint() {
97
97
  const pkg = '@ngocsangairvds/vsaf';
98
+ const { getPlatform } = require('../src/utils');
99
+ const platform = getPlatform();
100
+
98
101
  console.log('\n\x1b[1m╔══════════════════════════════════════════════════════════╗\x1b[0m');
99
- console.log( '\x1b[1m║ 🚀 Cài lệnh vsaf để dùng mọi lúc ║\x1b[0m');
102
+ console.log( '\x1b[1m║ Install vsaf globally for easy access ║\x1b[0m');
100
103
  console.log( '\x1b[1m╚══════════════════════════════════════════════════════════╝\x1b[0m');
101
- console.log(`
102
- Lệnh \x1b[36mvsaf\x1b[0m chưa được cài vào PATH vì bạn vừa chạy qua \x1b[33mnpx\x1b[0m.
103
- Để dùng \x1b[36mvsaf\x1b[0m trực tiếp từ terminal, hãy cài global một lần:
104
-
105
- \x1b[1m\x1b[32m npm install -g ${pkg}\x1b[0m
106
104
 
107
- Sau đó bạn có thể dùng:
105
+ console.log(`\n Detected OS: \x1b[36m${platform}\x1b[0m\n`);
108
106
 
109
- \x1b[36mvsaf status\x1b[0m # kiểm tra cài đặt
110
- \x1b[36mvsaf index\x1b[0m # index codebase (GitNexus)
111
- \x1b[36mvsaf review\x1b[0m # chạy 2-layer review
107
+ if (platform === 'windows') {
108
+ console.log(` \x1b[1m\x1b[33m[Windows]\x1b[0m Recommended installation methods:\n`);
109
+ console.log(` \x1b[1mOption 1: PowerShell (Admin)\x1b[0m`);
110
+ console.log(` \x1b[32mnpm install -g ${pkg}\x1b[0m\n`);
111
+ console.log(` \x1b[1mOption 2: PowerShell setup script\x1b[0m`);
112
+ console.log(` \x1b[32mSet-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass\x1b[0m`);
113
+ console.log(` \x1b[32m.\\scripts\\setup-vsaf.ps1\x1b[0m\n`);
114
+ console.log(` \x1b[1mOption 3: WSL (Windows Subsystem for Linux)\x1b[0m`);
115
+ console.log(` \x1b[90mRun inside WSL terminal for full Linux compatibility:\x1b[0m`);
116
+ console.log(` \x1b[32mnpm install -g ${pkg}\x1b[0m`);
117
+ console.log(` \x1b[32mbash scripts/setup-vsaf.sh\x1b[0m\n`);
118
+ console.log(` \x1b[1mOption 4: Git Bash\x1b[0m`);
119
+ console.log(` \x1b[90mIf you have Git for Windows installed:\x1b[0m`);
120
+ console.log(` \x1b[32mnpm install -g ${pkg}\x1b[0m`);
121
+ console.log(` \x1b[32mbash scripts/setup-vsaf.sh\x1b[0m\n`);
122
+ } else if (platform === 'macos') {
123
+ console.log(` \x1b[1m\x1b[33m[macOS]\x1b[0m Recommended installation methods:\n`);
124
+ console.log(` \x1b[1mOption 1: npm global install\x1b[0m`);
125
+ console.log(` \x1b[32mnpm install -g ${pkg}\x1b[0m\n`);
126
+ console.log(` \x1b[1mOption 2: Setup script\x1b[0m`);
127
+ console.log(` \x1b[32mbash scripts/setup-vsaf.sh\x1b[0m\n`);
128
+ } else {
129
+ console.log(` \x1b[1m\x1b[33m[Linux]\x1b[0m Recommended installation methods:\n`);
130
+ console.log(` \x1b[1mOption 1: npm global install\x1b[0m`);
131
+ console.log(` \x1b[32mnpm install -g ${pkg}\x1b[0m\n`);
132
+ console.log(` \x1b[1mOption 2: Setup script\x1b[0m`);
133
+ console.log(` \x1b[32mbash scripts/setup-vsaf.sh\x1b[0m\n`);
134
+ }
112
135
 
113
- \x1b[90mHoặc tiếp tục dùng npx nếu không muốn cài global:\x1b[0m
114
- \x1b[90m npx ${pkg} <command>\x1b[0m
115
- `);
136
+ console.log(` After installation, you can use:\n`);
137
+ console.log(` \x1b[36mvsaf status\x1b[0m # check installation`);
138
+ console.log(` \x1b[36mvsaf index\x1b[0m # index codebase (GitNexus)`);
139
+ console.log(` \x1b[36mvsaf review\x1b[0m # run 2-layer review\n`);
140
+ console.log(` \x1b[90mOr continue using npx without global install:\x1b[0m`);
141
+ console.log(` \x1b[90m npx ${pkg} <command>\x1b[0m\n`);
116
142
  }
117
143
 
118
144
  main().catch(err => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngocsangairvds/vsaf",
3
- "version": "3.1.3",
3
+ "version": "3.1.5",
4
4
  "description": "VSAF — Agentic AI SDLC Framework. 3 integrated tools: BMAD, GitNexus, Superpowers. 2-layer review.",
5
5
  "keywords": ["claude", "claude-code", "ai", "sdlc", "framework", "bmad", "gitnexus", "superpowers"],
6
6
  "bin": {
package/src/project.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
- const { ok, info, warn, step, hasCommand, exec, copyDir, copyFile } = require('./utils');
4
+ const { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, isWindows } = require('./utils');
5
5
 
6
6
  const PKG_ROOT = path.join(__dirname, '..');
7
7
  const TEMPLATES = path.join(PKG_ROOT, 'assets', 'templates');
@@ -49,7 +49,7 @@ function scaffoldFiles() {
49
49
  ok(`${dst} — already exists, skipped`);
50
50
  } else {
51
51
  copyFile(src, dstAbs);
52
- if (chmod) fs.chmodSync(dstAbs, chmod);
52
+ if (chmod && !isWindows) fs.chmodSync(dstAbs, chmod);
53
53
  ok(`${dst} — created`);
54
54
  }
55
55
  }
package/src/utils.js CHANGED
@@ -11,13 +11,22 @@ const info = (msg) => console.log(` \x1b[36m→\x1b[0m ${msg}`);
11
11
  const warn = (msg) => console.log(` \x1b[33m!\x1b[0m ${msg}`);
12
12
  const step = (msg) => console.log(`\n\x1b[1m${msg}\x1b[0m`);
13
13
 
14
+ const isWindows = process.platform === 'win32';
15
+
14
16
  function hasCommand(cmd) {
15
- const versionCheck = spawnSync(cmd, ['--version'], { stdio: 'ignore', shell: false });
17
+ // Try --version first (works on most CLIs across all platforms)
18
+ const versionCheck = spawnSync(cmd, ['--version'], { stdio: 'ignore', shell: isWindows });
16
19
  if (versionCheck.status === 0) return true;
17
20
 
18
- // Some CLIs don't support --version but are still available on PATH.
19
- const pathCheck = spawnSync('sh', ['-c', `command -v "${cmd}"`], { stdio: 'ignore', shell: false });
20
- return pathCheck.status === 0;
21
+ // Fallback: check if command exists on PATH
22
+ if (isWindows) {
23
+ // 'where' is a native Windows command; run as a single string via shell
24
+ const whereCheck = spawnSync(`where "${cmd}"`, { stdio: 'ignore', shell: true });
25
+ return whereCheck.status === 0;
26
+ } else {
27
+ const pathCheck = spawnSync('sh', ['-c', `command -v "${cmd}"`], { stdio: 'ignore', shell: false });
28
+ return pathCheck.status === 0;
29
+ }
21
30
  }
22
31
 
23
32
  function exec(cmd, opts = {}) {
@@ -43,4 +52,10 @@ function copyFile(src, dst) {
43
52
  fs.copyFileSync(src, dst);
44
53
  }
45
54
 
46
- module.exports = { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, CLAUDE_HOME };
55
+ function getPlatform() {
56
+ if (process.platform === 'win32') return 'windows';
57
+ if (process.platform === 'darwin') return 'macos';
58
+ return 'linux';
59
+ }
60
+
61
+ module.exports = { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, CLAUDE_HOME, isWindows, getPlatform };