@ngocsangairvds/vsaf 4.0.11 → 4.0.14

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": "4.0.11",
3
+ "version": "4.0.14",
4
4
  "description": "is it ready to use ?",
5
5
  "main": "packages/core/dist/index.js",
6
6
  "types": "packages/core/dist/index.d.ts",
@@ -20,13 +20,14 @@
20
20
  "files": [
21
21
  "packages/core/dist",
22
22
  "packages/cli/dist",
23
+ "scripts",
23
24
  "workflows",
24
25
  "commands",
25
26
  "skills"
26
27
  ],
27
28
  "scripts": {
28
29
  "build": "npm run build --workspaces",
29
- "postinstall": "node -e \"const fs=require('fs'),p=require('path'),r=p.resolve;const d=r(process.cwd(),'node_modules','@vsaf');fs.mkdirSync(d,{recursive:true});const t=r(d,'core');try{fs.rmSync(t,{recursive:true,force:true})}catch{};const s=r(process.cwd(),'packages','core','dist');try{fs.symlinkSync(s,t,process.platform==='win32'?'junction':'dir')}catch{fs.cpSync(s,t,{recursive:true})}\"",
30
+ "postinstall": "node scripts/postinstall.js",
30
31
  "prepack": "cp package.json package.json.bak && node -e \"const f='package.json',j=JSON.parse(require('fs').readFileSync(f));delete j.workspaces;require('fs').writeFileSync(f,JSON.stringify(j,null,2)+'\\n')\"",
31
32
  "postpack": "mv package.json.bak package.json",
32
33
  "test": "vitest run",
@@ -1,6 +1,2 @@
1
- export interface InitOptions {
2
- /** Skill pack to auto-install. Default: 'sdlc'. Pass false to skip. */
3
- pack?: string | false;
4
- }
5
- export declare function execInit(projectPath: string, options?: InitOptions): Promise<void>;
1
+ export declare function execInit(projectPath: string): Promise<void>;
6
2
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDxF"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAiBA,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCjE"}
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.execInit = execInit;
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
- const skill_js_1 = require("./skill.js");
7
- const install_js_1 = require("./install.js");
8
6
  const DEFAULT_CONFIG = `provider: claude
9
7
  model: sonnet
10
8
  isolation:
@@ -18,30 +16,16 @@ isolation:
18
16
  - .vsaf/storage
19
17
  max_workspaces: 5
20
18
  `;
21
- async function execInit(projectPath, options) {
19
+ async function execInit(projectPath) {
22
20
  const vsafDir = (0, path_1.join)(projectPath, '.vsaf');
23
21
  if ((0, fs_1.existsSync)(vsafDir)) {
24
22
  throw new Error(`.vsaf/ already exists at ${projectPath}. Remove it first to reinitialize.`);
25
23
  }
24
+ // Create .vsaf/ directory structure
26
25
  (0, fs_1.mkdirSync)((0, path_1.join)(vsafDir, 'workflows'), { recursive: true });
27
26
  (0, fs_1.mkdirSync)((0, path_1.join)(vsafDir, 'commands'), { recursive: true });
28
27
  (0, fs_1.mkdirSync)((0, path_1.join)(vsafDir, 'storage'), { recursive: true });
29
28
  (0, fs_1.writeFileSync)((0, path_1.join)(vsafDir, 'config.yaml'), DEFAULT_CONFIG, 'utf-8');
30
- // Auto-install skill pack (default: sdlc)
31
- const packName = options?.pack !== false ? (options?.pack ?? 'sdlc') : null;
32
- if (packName) {
33
- const packDir = (0, skill_js_1.resolveSource)(packName);
34
- const packInfo = (0, skill_js_1.resolvePackInfo)(packName, projectPath);
35
- const skillsDir = (0, path_1.join)(projectPath, '.claude', 'skills');
36
- (0, install_js_1.deploySkills)(packDir, packName, packInfo.skillNames, skillsDir, {});
37
- if (packInfo.bundledNames.length > 0) {
38
- (0, install_js_1.deploySkills)(packDir, packName, packInfo.bundledNames, skillsDir, { noPrefix: true });
39
- }
40
- const prefixedNames = packInfo.skillNames
41
- .filter(n => n !== 'setup')
42
- .map(n => `${packName}-${n}`);
43
- (0, skill_js_1.skillInit)(packName, projectPath, prefixedNames, { workflows: packInfo.workflows });
44
- }
45
29
  // Create .mcp.json for MCP server registration
46
30
  const mcpPath = (0, path_1.join)(projectPath, '.mcp.json');
47
31
  const vsafServer = { type: 'stdio', command: 'vsaf', args: ['mcp'] };
@@ -73,5 +57,7 @@ async function execInit(projectPath, options) {
73
57
  (0, fs_1.writeFileSync)(mcpPath, JSON.stringify(existing, null, 2) + '\n', 'utf-8');
74
58
  }
75
59
  }
60
+ console.log(`\n[vsaf] Initialized .vsaf/ at ${projectPath}`);
61
+ console.log('[vsaf] Next: vsaf install sdlc (deploy skills + dependencies)\n');
76
62
  }
77
63
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";;AAiBA,4BAwCC;AAzDD,2BAAwE;AACxE,+BAA4B;AAE5B,MAAM,cAAc,GAAG;;;;;;;;;;;;CAYtB,CAAC;AAEK,KAAK,UAAU,QAAQ,CAAC,WAAmB;IAChD,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE3C,IAAI,IAAA,eAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4BAA4B,WAAW,oCAAoC,CAAC,CAAC;IAC/F,CAAC;IAED,oCAAoC;IACpC,IAAA,cAAS,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,IAAA,cAAS,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAA,cAAS,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,IAAA,kBAAa,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAErE,+CAA+C;IAC/C,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IACrE,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC;IAEjG,IAAI,CAAC,IAAA,eAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG;YAChB,UAAU,EAAE;gBACV,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,cAAc;aACzB;SACF,CAAC;QACF,IAAA,kBAAa,EAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,wDAAwD;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,CAAC,UAAU;YAAE,QAAQ,CAAC,UAAU,GAAG,EAAE,CAAC;QACnD,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,UAAU,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;QAAC,CAAC;QACzF,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,GAAG,cAAc,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;QAAC,CAAC;QACrG,IAAI,OAAO,EAAE,CAAC;YACZ,IAAA,kBAAa,EAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,WAAW,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script — create @vsaf/core workspace link
5
+ *
6
+ * Monorepo workspace links are stripped during `npm pack` (prepack removes
7
+ * "workspaces" from package.json). This script recreates the link so that
8
+ * `require('@vsaf/core')` works after `npm install -g`.
9
+ *
10
+ * Strategy (in order):
11
+ * 1. symlink (macOS/Linux) or junction (Windows — no admin needed)
12
+ * 2. cpSync fallback (copy dist/ contents)
13
+ * 3. Fail with clear instructions
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const cwd = process.cwd();
20
+ const nsDir = path.resolve(cwd, 'node_modules', '@vsaf');
21
+ const target = path.resolve(nsDir, 'core');
22
+ const source = path.resolve(cwd, 'packages', 'core', 'dist');
23
+
24
+ // Skip if source doesn't exist (e.g. fresh clone before build)
25
+ if (!fs.existsSync(source)) {
26
+ process.exit(0);
27
+ }
28
+
29
+ // Ensure @vsaf/ namespace directory
30
+ fs.mkdirSync(nsDir, { recursive: true });
31
+
32
+ // Clean existing link/dir
33
+ try { fs.rmSync(target, { recursive: true, force: true }); } catch {}
34
+
35
+ // Attempt 1: symlink (dir on Unix, junction on Windows)
36
+ try {
37
+ const type = process.platform === 'win32' ? 'junction' : 'dir';
38
+ fs.symlinkSync(source, target, type);
39
+ process.exit(0);
40
+ } catch (e1) {
41
+ // Attempt 2: copy
42
+ try {
43
+ fs.cpSync(source, target, { recursive: true });
44
+ process.exit(0);
45
+ } catch (e2) {
46
+ // Both failed — show clear instructions
47
+ console.error('\n' + '='.repeat(60));
48
+ console.error(' VSAF postinstall failed: cannot link @vsaf/core');
49
+ console.error('='.repeat(60));
50
+ console.error(`\n Symlink error: ${e1.message}`);
51
+ console.error(` Copy error: ${e2.message}`);
52
+
53
+ if (process.platform === 'win32') {
54
+ console.error('\n Windows fix (choose one):');
55
+ console.error(' 1. Enable Developer Mode:');
56
+ console.error(' Settings > Update & Security > For Developers > Developer Mode ON');
57
+ console.error(' Then re-run: npm install -g @ngocsangairvds/vsaf');
58
+ console.error('');
59
+ console.error(' 2. Run as Administrator:');
60
+ console.error(' Right-click terminal > "Run as administrator"');
61
+ console.error(' Then re-run: npm install -g @ngocsangairvds/vsaf');
62
+ console.error('');
63
+ console.error(' 3. Manual copy:');
64
+ console.error(` xcopy /E /I "${source}" "${target}"`);
65
+ } else {
66
+ console.error('\n Fix: check file permissions on node_modules/');
67
+ console.error(` Manual: cp -r "${source}" "${target}"`);
68
+ }
69
+
70
+ console.error('\n' + '='.repeat(60) + '\n');
71
+ process.exit(1);
72
+ }
73
+ }
@@ -10,8 +10,8 @@
10
10
  * node install-deps.mjs [projectPath]
11
11
  */
12
12
 
13
- import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, chmodSync } from 'fs';
14
- import { join, dirname } from 'path';
13
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, chmodSync, unlinkSync } from 'fs';
14
+ import { join, dirname, delimiter } from 'path';
15
15
  import { homedir } from 'os';
16
16
 
17
17
  const projectPath = process.argv[2] || process.cwd();
@@ -227,19 +227,37 @@ if (!vdsCliFound) {
227
227
  if (vdsScriptsDir) {
228
228
  log('📂', `vds-scripts: ${vdsScriptsDir}`);
229
229
  if (existsSync(join(vdsScriptsDir, 'pyproject.toml'))) {
230
- console.log('');
231
- log('🔄', 'Syncing vds-scripts packages (uv sync --all-packages)...');
230
+ // Check uv is available before attempting sync
231
+ let uvAvailable = false;
232
232
  try {
233
- execSync('uv sync --all-packages', {
234
- stdio: 'pipe',
235
- encoding: 'utf-8',
236
- timeout: 120000,
237
- cwd: vdsScriptsDir,
238
- });
239
- log('✅', 'All vds-scripts packages synced');
233
+ execSync('uv --version', { stdio: 'pipe', encoding: 'utf-8', timeout: 10000 });
234
+ uvAvailable = true;
240
235
  } catch {
241
- log('⚠️', 'Failed to sync vds-scripts packagessubcommands like confluence/jira may not work');
242
- log(' ', `Fix: cd ${vdsScriptsDir} && uv sync --all-packages`);
236
+ log('⚠️', 'uv (Python package manager) not found required for vds-scripts');
237
+ if (process.platform === 'win32') {
238
+ log(' ', 'Install: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"');
239
+ log(' ', ' or: winget install astral-sh.uv');
240
+ } else {
241
+ log(' ', 'Install: curl -LsSf https://astral.sh/uv/install.sh | sh');
242
+ log(' ', ' or: brew install uv');
243
+ }
244
+ }
245
+
246
+ if (uvAvailable) {
247
+ console.log('');
248
+ log('🔄', 'Syncing vds-scripts packages (uv sync --all-packages)...');
249
+ try {
250
+ execSync('uv sync --all-packages', {
251
+ stdio: 'pipe',
252
+ encoding: 'utf-8',
253
+ timeout: 120000,
254
+ cwd: vdsScriptsDir,
255
+ });
256
+ log('✅', 'All vds-scripts packages synced');
257
+ } catch {
258
+ log('⚠️', 'Failed to sync vds-scripts packages — subcommands like confluence/jira may not work');
259
+ log(' ', `Fix: cd ${vdsScriptsDir} && uv sync --all-packages`);
260
+ }
243
261
  }
244
262
  }
245
263
  } else {
@@ -252,31 +270,49 @@ console.log('');
252
270
  log('🔍', 'Verifying vds-cli...');
253
271
 
254
272
  let verified = false;
273
+
274
+ // First pass: try vds-cli on PATH
255
275
  try {
256
276
  const ver = execSync('vds-cli --version', { stdio: 'pipe', encoding: 'utf-8', timeout: 15000 }).trim();
257
277
  log('✅', `vds-cli ${ver} — working`);
258
278
  verified = true;
259
279
  } catch {
260
- // Try with project-local wrapper in PATH
280
+ // vds-cli on PATH failed check if a broken shim exists and auto-remove it
281
+ try {
282
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
283
+ const shimPath = execSync(`${whichCmd} vds-cli`, { stdio: 'pipe', encoding: 'utf-8' }).trim().split('\n')[0];
284
+ // Shim exists but doesn't work — remove it automatically
285
+ log('🗑️', `Removing broken shim: ${shimPath}`);
286
+ try {
287
+ unlinkSync(shimPath);
288
+ log('✅', 'Broken shim removed');
289
+ } catch (e) {
290
+ log('⚠️', `Cannot auto-remove shim (${e.code || e.message})`);
291
+ if (process.platform === 'win32') {
292
+ log(' ', 'Fix: open cmd as Administrator, then run:');
293
+ log(' ', ` del "${shimPath}"`);
294
+ log(' ', ' vsaf install vds-skill');
295
+ } else {
296
+ log(' ', `Fix: rm "${shimPath}" then re-run: vsaf install vds-skill`);
297
+ }
298
+ }
299
+ } catch {
300
+ // No shim found — that's fine
301
+ }
302
+ }
303
+
304
+ // Second pass: try project-local wrapper
305
+ if (!verified) {
261
306
  try {
262
307
  const wrapperPath = join(projectPath, '.claude', 'bin');
263
308
  const ver = execSync('vds-cli --version', {
264
309
  stdio: 'pipe', encoding: 'utf-8', timeout: 15000,
265
- env: { ...process.env, PATH: `${wrapperPath}:${process.env.PATH}` },
310
+ env: { ...process.env, PATH: `${wrapperPath}${delimiter}${process.env.PATH}` },
266
311
  }).trim();
267
312
  log('✅', `vds-cli ${ver} — working (via .claude/bin/vds-cli)`);
268
313
  verified = true;
269
314
  } catch {
270
- // Check if a shim exists but is broken
271
- try {
272
- const whichCmd = process.platform === 'win32' ? 'where' : 'which';
273
- const shimPath = execSync(`${whichCmd} vds-cli`, { stdio: 'pipe', encoding: 'utf-8' }).trim().split('\n')[0];
274
- log('❌', `vds-cli BROKEN — ${shimPath} exists but fails to run`);
275
- log(' ', 'The shim likely points to a deleted venv or missing vds-scripts directory.');
276
- log(' ', `Fix: rm ${shimPath} then re-run: vsaf install vds-skill`);
277
- } catch {
278
- log('❌', 'vds-cli not found');
279
- }
315
+ log('❌', 'vds-cli not working skills will be BLOCKED at runtime');
280
316
  }
281
317
  }
282
318