@ngocsangairvds/vsaf 3.0.3 → 3.0.4

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/README.md CHANGED
@@ -64,12 +64,12 @@ first 30 days.
64
64
  ```
65
65
  .
66
66
  ├── .claude/
67
- │ ├── settings.json # Security hooks: block secrets, protect config files
67
+ │ ├── settings.json # Local AI settings (optional hook policy)
68
68
  │ └── skills/ # Coding standards for Go, Rust, Python
69
69
  ├── docs/
70
70
  │ ├── architecture/ # Architecture documents (from BMAD Architect)
71
71
  │ └── onboarding/ # Developer onboarding (see table above)
72
- ├── githooks/ # Git hooks (pre-push runs verify + security scan)
72
+ ├── githooks/ # Optional local hooks (disabled by default)
73
73
  ├── graphify-out/ # Graphify output (gitignored, regenerated by `vsaf index`)
74
74
  ├── openspec/ # OpenSpec workspace (proposals, specs, designs, tasks)
75
75
  ├── scripts/
@@ -111,7 +111,7 @@ for a full command-by-command example.
111
111
  | **BMAD Method** | AI agents for planning: Analyst, PM, Architect, Product Owner | Free |
112
112
  | **OpenSpec** | Spec-driven development: proposals, specs, designs, task lists, verification | Free |
113
113
  | **Superpowers** | Methodology engine: brainstorm, plan, TDD execution, code review | Free |
114
- | **Security guardrails** | Security scanner + git hooks (block secrets) + coding standards | Free |
114
+ | **Security guardrails** | Optional hooks/policies + coding standards (team-defined security scanning) | Free |
115
115
  | **GitNexus** | Code knowledge graph via MCP — impact analysis, dependency queries | Free |
116
116
  | **Graphify** | Multimodal knowledge graph — visual dependency maps, path tracing | Free |
117
117
  | **claude-mem** | Auto-pilot memory — captures sessions, re-injects context next time | Free |
@@ -121,4 +121,4 @@ for a full command-by-command example.
121
121
 
122
122
  **Core principles:** Spec before code. Context is king. Git is source of truth.
123
123
  3-layer review before every PR. Re-index after every merge. Mine decisions
124
- weekly.
124
+ weekly. Hooks are optional in the current simplified setup.
package/bin/vsaf.js CHANGED
@@ -12,7 +12,7 @@ USAGE
12
12
  vsaf project Scaffold project files only (assumes global done)
13
13
  vsaf status Show installation status
14
14
  vsaf index Re-index codebase (GitNexus + Graphify)
15
- vsaf verify Check implementation against OpenSpec specs
15
+ vsaf verify Check implementation against OpenSpec specs (manual pre-push gate)
16
16
  vsaf review Run 3-layer review flow
17
17
  vsaf archive Archive specs and re-index
18
18
  vsaf mine Mine conversations into MemPalace
@@ -23,7 +23,7 @@ GLOBAL (once per machine → ~/.claude/)
23
23
  Binaries: gitnexus, openspec, graphify, mempalace, bun, claude-mem
24
24
 
25
25
  PER PROJECT (per repo, run inside the repo root)
26
- .claude/settings.json Hooks: secret detection, protected files
26
+ .claude/settings.json Local AI settings (optional hook policy)
27
27
  .claude/skills + .codex/skills BMAD skills synced for local clients
28
28
  _bmad + _bmad-output BMAD workspace + generated artifacts folders
29
29
  CLAUDE.md 10-step workflow rules
@@ -36,6 +36,13 @@ EXAMPLES
36
36
  `;
37
37
 
38
38
  async function main() {
39
+ const runAndExit = (result, label) => {
40
+ if (result === false) {
41
+ console.error(`\n${label} failed.`);
42
+ process.exit(1);
43
+ }
44
+ };
45
+
39
46
  switch (cmd) {
40
47
  case 'init': {
41
48
  const { installGlobal } = require('../src/global');
@@ -61,32 +68,32 @@ async function main() {
61
68
  }
62
69
  case 'index': {
63
70
  const { runIndex } = require('../src/workflow');
64
- runIndex();
71
+ runAndExit(runIndex(), 'Index');
65
72
  break;
66
73
  }
67
74
  case 'verify': {
68
75
  const { runVerify } = require('../src/workflow');
69
- runVerify();
76
+ runAndExit(runVerify(), 'Verify');
70
77
  break;
71
78
  }
72
79
  case 'review': {
73
80
  const { runReview } = require('../src/workflow');
74
- runReview();
81
+ runAndExit(runReview(), 'Review');
75
82
  break;
76
83
  }
77
84
  case 'archive': {
78
85
  const { runArchive } = require('../src/workflow');
79
- runArchive();
86
+ runAndExit(runArchive(), 'Archive');
80
87
  break;
81
88
  }
82
89
  case 'mine': {
83
90
  const { runMine } = require('../src/workflow');
84
- runMine();
91
+ runAndExit(runMine(), 'Mine');
85
92
  break;
86
93
  }
87
94
  case 'clean': {
88
95
  const { runClean } = require('../src/workflow');
89
- runClean();
96
+ runAndExit(runClean(), 'Clean');
90
97
  break;
91
98
  }
92
99
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngocsangairvds/vsaf",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "VSAF — Agentic AI SDLC Framework. Spec-driven development, 3-layer review, 7 integrated tools.",
5
5
  "keywords": ["claude", "claude-code", "ai", "sdlc", "framework", "bmad", "openspec"],
6
6
  "bin": {
package/src/project.js CHANGED
@@ -20,7 +20,6 @@ async function installProject() {
20
20
  initOpenSpec();
21
21
  initGitNexus();
22
22
  initMemPalace();
23
- configureGitHooks();
24
23
 
25
24
  console.log('\n\x1b[32m\x1b[1m✓ Project ready.\x1b[0m');
26
25
  console.log('\n Next steps:');
@@ -164,12 +163,5 @@ function initMemPalace() {
164
163
  exec(`mempalace init --yes "${CWD}"`, { cwd: CWD }) ? ok('MemPalace initialised') : warn('mempalace init failed — run manually');
165
164
  }
166
165
 
167
- function configureGitHooks() {
168
- step('Git hooks');
169
- if (!fs.existsSync(path.join(CWD, '.git'))) { warn('Not a git repo — skipping'); return; }
170
- fs.mkdirSync(path.join(CWD, 'githooks'), { recursive: true });
171
- exec('git config core.hooksPath githooks/', { cwd: CWD });
172
- ok('Git hooks path → githooks/');
173
- }
174
166
 
175
167
  module.exports = { installProject };
package/src/status.js CHANGED
@@ -17,7 +17,7 @@ async function showStatus() {
17
17
 
18
18
  // ── Project ────────────────────────────────────────────────────────────────
19
19
  console.log('\n\x1b[1mProject (current repo)\x1b[0m');
20
- checkPath('.claude/settings.json', 'Project settings');
20
+ checkPath('.claude/settings.json', 'Project settings (optional hooks)');
21
21
  checkPath('CLAUDE.md', 'Workflow rules');
22
22
  checkPath('_bmad', 'BMAD workspace');
23
23
  checkPath('_bmad-output', 'BMAD output folder');
@@ -26,7 +26,6 @@ async function showStatus() {
26
26
  checkPath('.gitnexus', 'GitNexus index');
27
27
  checkPath('openspec', 'OpenSpec');
28
28
  checkPath('mempalace.yaml', 'MemPalace');
29
- checkPath('githooks', 'Git hooks');
30
29
  console.log('');
31
30
  }
32
31
 
package/src/workflow.js CHANGED
@@ -7,76 +7,95 @@ function runIndex() {
7
7
 
8
8
  if (!hasCommand('gitnexus')) {
9
9
  warn('gitnexus not found — run: vsaf global');
10
- return;
10
+ return false;
11
11
  }
12
12
 
13
13
  info('Running gitnexus analyze...');
14
- exec('gitnexus analyze') ? ok('GitNexus index updated') : warn('gitnexus analyze failed — run manually');
14
+ const gitnexusOk = exec('gitnexus analyze');
15
+ gitnexusOk ? ok('GitNexus index updated') : warn('gitnexus analyze failed — run manually');
15
16
 
16
17
  if (!hasCommand('graphify')) {
17
18
  warn('graphify not found — skipping graphify update');
18
- return;
19
+ return false;
19
20
  }
20
21
 
21
22
  info('Running graphify update...');
22
- exec('graphify . --update') ? ok('Graphify updated') : warn('graphify update failed — run manually');
23
+ const graphifyOk = exec('graphify update .');
24
+ graphifyOk ? ok('Graphify updated') : warn('graphify update failed — run manually');
25
+
26
+ return gitnexusOk && graphifyOk;
23
27
  }
24
28
 
25
29
  function runVerify() {
26
30
  step('Verify');
27
31
  if (!hasCommand('openspec')) {
28
32
  warn('openspec not found — run: vsaf global');
29
- return;
33
+ return false;
30
34
  }
31
35
 
32
36
  info('Running openspec validate --all...');
33
- exec('openspec validate --all') ? ok('OpenSpec verification passed') : warn('OpenSpec verification failed');
37
+ const okVerify = exec('openspec validate --all');
38
+ okVerify ? ok('OpenSpec verification passed') : warn('OpenSpec verification failed');
39
+ return okVerify;
34
40
  }
35
41
 
36
42
  function runReview() {
37
43
  step('Review (3-layer)');
38
44
  info('Layer 1: Methodology review — run in Claude Code: /superpowers:code-review');
39
45
  info('Layer 2: Spec compliance');
40
- runVerify();
46
+ const verifyOk = runVerify();
41
47
  info('Layer 3: Knowledge graph sync');
42
- runIndex();
43
- ok('Review flow completed');
48
+ const indexOk = runIndex();
49
+
50
+ if (verifyOk && indexOk) {
51
+ ok('Review flow completed');
52
+ return true;
53
+ }
54
+
55
+ warn('Review flow completed with failures. Fix warnings and re-run.');
56
+ return false;
44
57
  }
45
58
 
46
59
  function runArchive() {
47
60
  step('Archive');
48
61
  if (!hasCommand('openspec')) {
49
62
  warn('openspec not found — run: vsaf global');
50
- return;
63
+ return false;
51
64
  }
52
65
 
53
66
  info('Running openspec archive...');
54
- exec('openspec archive') ? ok('OpenSpec archived') : warn('openspec archive failed — run manually');
55
- runIndex();
67
+ const archiveOk = exec('openspec archive');
68
+ archiveOk ? ok('OpenSpec archived') : warn('openspec archive failed — run manually');
69
+ const indexOk = runIndex();
70
+ return archiveOk && indexOk;
56
71
  }
57
72
 
58
73
  function runMine() {
59
74
  step('Mine');
60
75
  if (!hasCommand('mempalace')) {
61
76
  warn('mempalace not found — run: vsaf global');
62
- return;
77
+ return false;
63
78
  }
64
79
 
65
80
  info('Running mempalace mine ~/chats/ --mode convos --extract general...');
66
- exec('mempalace mine ~/chats/ --mode convos --extract general')
81
+ const mineOk = exec('mempalace mine ~/chats/ --mode convos --extract general');
82
+ mineOk
67
83
  ? ok('MemPalace mine completed')
68
84
  : warn('mempalace mine failed — run manually');
85
+ return mineOk;
69
86
  }
70
87
 
71
88
  function runClean() {
72
89
  step('Clean');
73
90
  if (!hasCommand('gitnexus')) {
74
91
  warn('gitnexus not found — run: vsaf global');
75
- return;
92
+ return false;
76
93
  }
77
94
 
78
95
  info('Running gitnexus clean...');
79
- exec('gitnexus clean') ? ok('GitNexus index cleaned') : warn('gitnexus clean failed — run manually');
96
+ const cleanOk = exec('gitnexus clean');
97
+ cleanOk ? ok('GitNexus index cleaned') : warn('gitnexus clean failed — run manually');
98
+ return cleanOk;
80
99
  }
81
100
 
82
101
  module.exports = { runIndex, runVerify, runReview, runArchive, runMine, runClean };