@ngocsangairvds/vsaf 3.1.19 → 3.1.21

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.
@@ -22,7 +22,7 @@ VSAF is a meta-framework for AI-driven SDLC — not an application. It has no so
22
22
  | Code Intelligence | GitNexus | Impact analysis, call graph, blast radius |
23
23
  | Implementation | Superpowers, Codex | Brainstorm, TDD execution, code review |
24
24
 
25
- Key directories: `.codex/` (skills + instructions), `.vsaf/_bmad/` (BMAD workspace), `.vsaf/docs/` (artifacts), `.vsaf/_gitnexus/` (knowledge graph index).
25
+ Key directories: `.codex/` (skills + instructions), `.vsaf/_bmad/` (BMAD workspace), `.vsaf/docs/` (artifacts), `.gitnexus/` (knowledge graph index).
26
26
 
27
27
  ---
28
28
 
@@ -22,7 +22,7 @@ VSAF is a meta-framework for AI-driven SDLC — not an application. It has no so
22
22
  | Code Intelligence | GitNexus (MCP) | Impact analysis, call graph, blast radius |
23
23
  | Implementation | Superpowers, Claude Code | Brainstorm, TDD execution, code review |
24
24
 
25
- Key directories: `.claude/` (settings + skills), `.vsaf/_bmad/` (BMAD workspace), `.vsaf/docs/` (artifacts), `.vsaf/_gitnexus/` (knowledge graph index, `.gitnexus/` is a symlink here).
25
+ Key directories: `.claude/` (settings + skills), `.vsaf/_bmad/` (BMAD workspace), `.vsaf/docs/` (artifacts), `.gitnexus/` (knowledge graph index).
26
26
 
27
27
  ---
28
28
 
package/bin/vsaf.js CHANGED
@@ -11,7 +11,8 @@ USAGE
11
11
  vsaf global Install global infra only (skills, binaries)
12
12
  vsaf project Scaffold project files only (assumes global done)
13
13
  vsaf status Show installation status
14
- vsaf index Re-index codebase (GitNexus)
14
+ vsaf index Re-index codebase (discovers git root)
15
+ vsaf index --skip-git Re-index from CWD (skip git root discovery)
15
16
  vsaf serve Start GitNexus web UI server
16
17
  vsaf review Run 2-layer review flow
17
18
  vsaf clean Clean GitNexus index
@@ -66,7 +67,8 @@ async function main() {
66
67
  }
67
68
  case 'index': {
68
69
  const { runIndex } = require('../src/workflow');
69
- runAndExit(runIndex(), 'Index');
70
+ const skipGit = process.argv.includes('--skip-git');
71
+ runAndExit(runIndex({ skipGit }), 'Index');
70
72
  break;
71
73
  }
72
74
  case 'serve': {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ngocsangairvds/vsaf",
3
- "version": "3.1.19",
4
- "description": "add method for codex",
3
+ "version": "3.1.21",
4
+ "description": "fix gitnexus with windows",
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
@@ -64,9 +64,9 @@ function setupGitnexusMcp() {
64
64
  }
65
65
 
66
66
  info('Configuring GitNexus MCP...');
67
- exec('claude mcp add gitnexus -- npx -y gitnexus@latest mcp')
67
+ exec('claude mcp add gitnexus -- npx -y gitnexus@rc mcp')
68
68
  ? ok('GitNexus MCP configured')
69
- : warn('MCP setup failed — run manually: claude mcp add gitnexus -- npx -y gitnexus@latest mcp');
69
+ : warn('MCP setup failed — run manually: claude mcp add gitnexus -- npx -y gitnexus@rc mcp');
70
70
  }
71
71
 
72
72
  module.exports = { installGlobal };
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, ensureGitnexusSymlink } = require('./utils');
4
+ const { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, cleanStaleWal } = require('./utils');
5
5
 
6
6
  const PKG_ROOT = path.join(__dirname, '..');
7
7
  const TEMPLATES = path.join(PKG_ROOT, 'assets', 'templates');
@@ -160,7 +160,7 @@ function syncLocalBmadSkills() {
160
160
  function initGitNexus() {
161
161
  step('GitNexus');
162
162
  if (!hasCommand('gitnexus')) { warn('gitnexus not found — run: vsaf global'); return; }
163
- ensureGitnexusSymlink();
163
+ cleanStaleWal();
164
164
  const analyzeCmd = 'gitnexus analyze --skip-git';
165
165
  info('Indexing repository (gitnexus analyze)...');
166
166
  exec(analyzeCmd, { cwd: CWD }) ? ok('Repository indexed') : warn('gitnexus analyze failed — run manually');
package/src/status.js CHANGED
@@ -22,7 +22,7 @@ async function showStatus() {
22
22
  checkPath('.vsaf/docs', 'Project artifact folder');
23
23
  checkProjectSkillDir('.claude/skills', 'Project BMAD skills (.claude)');
24
24
  checkProjectSkillDir('.codex/skills', 'Project BMAD skills (.codex)');
25
- checkPath('.vsaf/_gitnexus', 'GitNexus index');
25
+ checkPath('.gitnexus', 'GitNexus index');
26
26
  console.log('');
27
27
  }
28
28
 
package/src/utils.js CHANGED
@@ -55,27 +55,20 @@ function hasGitCommits() {
55
55
  }
56
56
 
57
57
  /**
58
- * Ensures .gitnexus is a symlink .vsaf/_gitnexus (actual data dir).
59
- * Gitnexus hardcodes .gitnexus/ so we keep it at the root as a symlink
60
- * while the real data lives inside .vsaf/.
58
+ * Removes stale DuckDB WAL files from the .gitnexus directory.
59
+ * WAL files left behind by interrupted gitnexus analyze runs can become
60
+ * corrupted, causing DuckDB to crash with UNREACHABLE_CODE on next open.
61
61
  */
62
- function ensureGitnexusSymlink() {
63
- const cwd = process.cwd();
64
- const actual = path.join(cwd, '.vsaf', '_gitnexus');
65
- const linkPath = path.join(cwd, '.gitnexus');
62
+ function cleanStaleWal() {
63
+ const dir = path.join(process.cwd(), '.gitnexus');
64
+ if (!fs.existsSync(dir)) return;
66
65
 
67
- fs.mkdirSync(actual, { recursive: true });
68
-
69
- try {
70
- const stat = fs.lstatSync(linkPath);
71
- if (stat.isSymbolicLink()) return; // already a symlink — nothing to do
72
- // Real directory left behind (e.g. gitnexus recreated it after clean)
73
- fs.rmSync(linkPath, { recursive: true, force: true });
74
- } catch {
75
- // linkPath does not exist — will create below
66
+ for (const file of fs.readdirSync(dir)) {
67
+ if (file.endsWith('.wal')) {
68
+ fs.unlinkSync(path.join(dir, file));
69
+ warn(`Removed stale WAL: .gitnexus/${file}`);
70
+ }
76
71
  }
77
-
78
- fs.symlinkSync(actual, linkPath);
79
72
  }
80
73
 
81
74
  function getPlatform() {
@@ -83,4 +76,4 @@ function getPlatform() {
83
76
  return 'linux';
84
77
  }
85
78
 
86
- module.exports = { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, CLAUDE_HOME, CODEX_HOME, getPlatform, hasGitCommits, ensureGitnexusSymlink };
79
+ module.exports = { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, CLAUDE_HOME, CODEX_HOME, getPlatform, hasGitCommits, cleanStaleWal };
package/src/workflow.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const path = require('path');
4
4
  const fs = require('fs');
5
- const { ok, info, warn, step, hasCommand, exec, hasGitCommits, ensureGitnexusSymlink } = require('./utils');
5
+ const { ok, info, warn, step, hasCommand, exec, hasGitCommits, cleanStaleWal } = require('./utils');
6
6
 
7
7
  function preflightCheck() {
8
8
  // Check: is this a git repo?
@@ -25,7 +25,7 @@ function preflightCheck() {
25
25
  return true;
26
26
  }
27
27
 
28
- function runIndex() {
28
+ function runIndex({ skipGit = false } = {}) {
29
29
  step('Index');
30
30
 
31
31
  if (!hasCommand('gitnexus')) {
@@ -37,9 +37,10 @@ function runIndex() {
37
37
  return false;
38
38
  }
39
39
 
40
- ensureGitnexusSymlink();
41
- info('Running gitnexus analyze...');
42
- const gitnexusOk = exec('gitnexus analyze --skip-git');
40
+ cleanStaleWal();
41
+ const cmd = skipGit ? 'gitnexus analyze --skip-git' : 'gitnexus analyze';
42
+ info(`Running ${cmd}...`);
43
+ const gitnexusOk = exec(cmd);
43
44
  if (gitnexusOk) {
44
45
  ok('GitNexus index updated');
45
46
  } else {
@@ -80,11 +81,6 @@ function runClean() {
80
81
 
81
82
  info('Running gitnexus clean...');
82
83
  const cleanOk = exec('gitnexus clean --force');
83
- // gitnexus clean deletes the .gitnexus symlink — clear actual data dir too
84
- const actualDir = path.join(process.cwd(), '.vsaf', '_gitnexus');
85
- if (fs.existsSync(actualDir)) fs.rmSync(actualDir, { recursive: true, force: true });
86
- // Restore symlink pointing at the now-empty dir
87
- ensureGitnexusSymlink();
88
84
  cleanOk ? ok('GitNexus index cleaned') : warn('gitnexus clean failed — run manually');
89
85
  return cleanOk;
90
86
  }