@ngocsangairvds/vsaf 3.1.23 → 3.1.25
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/assets/templates/CLAUDE.md +8 -4
- package/bin/vsaf.js +1 -1
- package/package.json +2 -2
- package/src/global.js +96 -3
- package/src/workflow.js +1 -1
- package/tools/bmad/bmm/config.yaml +4 -0
- package/tools/skills/vsaf-doc-prd/SKILL.md +2 -1
- package/tools/skills/vsaf-doc-srs/SKILL.md +2 -1
- package/tools/skills/vsaf-push-prd/SKILL.md +79 -0
- package/tools/skills/vsaf-push-srs/SKILL.md +85 -0
- package/assets/templates/Makefile +0 -29
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
4
|
|
|
5
|
-
> VSAF v3 — Agentic AI SDLC Framework.
|
|
5
|
+
> VSAF v3 — Agentic AI SDLC Framework. 3 integrated tools. 2-layer review.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## Prerequisites
|
|
10
10
|
|
|
11
|
-
Node.js ≥18,
|
|
11
|
+
Node.js ≥18, Git, Claude Code subscription. Run `npx vsaf init` (idempotent) to install all tools.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
17
|
-
VSAF is a meta-framework for AI-driven SDLC — not an application. It has no source code to compile. The
|
|
17
|
+
VSAF is a meta-framework for AI-driven SDLC — not an application. It has no source code to compile. The 3-tool stack:
|
|
18
18
|
|
|
19
19
|
| Layer | Tools | Purpose |
|
|
20
20
|
|-------|-------|---------|
|
|
@@ -66,11 +66,13 @@ npx vsaf init
|
|
|
66
66
|
- Use `/vsaf-onboard` for the structured onboarding sequence.
|
|
67
67
|
- Do not modify code on day one.
|
|
68
68
|
|
|
69
|
-
### Step 2: Planning + Requirement -> PRD -> SRS
|
|
69
|
+
### Step 2: Planning + Requirement -> PRD -> SRS -> Confluence
|
|
70
70
|
```
|
|
71
71
|
/vsaf-plan <requirement> # scope + impact + approach
|
|
72
72
|
/vsaf-doc-prd # write PRD from approved scope
|
|
73
|
+
/vsaf-push-prd <comment> # publish PRD to Confluence
|
|
73
74
|
/vsaf-doc-srs # write SRS from PRD
|
|
75
|
+
/vsaf-push-srs <comment> # publish SRS to Confluence
|
|
74
76
|
```
|
|
75
77
|
Quick Flow (bug fix) may use a mini-SRS, but impact analysis is still mandatory.
|
|
76
78
|
|
|
@@ -118,7 +120,9 @@ PR description must include: impact summary (from GitNexus), test results.
|
|
|
118
120
|
| VSAF onboard | `/vsaf-onboard` |
|
|
119
121
|
| VSAF plan | `/vsaf-plan <requirement>` |
|
|
120
122
|
| VSAF doc PRD | `/vsaf-doc-prd` |
|
|
123
|
+
| VSAF push PRD → Confluence | `/vsaf-push-prd <comment>` |
|
|
121
124
|
| VSAF doc SRS | `/vsaf-doc-srs` |
|
|
125
|
+
| VSAF push SRS → Confluence | `/vsaf-push-srs <comment>` |
|
|
122
126
|
| VSAF testcase | `/vsaf-test <path/to/srs>` |
|
|
123
127
|
| VSAF implement | `/vsaf-build <srs> <testcases>` |
|
|
124
128
|
| VSAF ship | `/vsaf-ship` |
|
package/bin/vsaf.js
CHANGED
|
@@ -24,7 +24,7 @@ GLOBAL (once per machine → ~/.claude/)
|
|
|
24
24
|
PER PROJECT (per repo, run inside the repo root)
|
|
25
25
|
.claude/settings.json Local AI settings
|
|
26
26
|
.claude/skills + .codex/skills BMAD skills synced for local clients
|
|
27
|
-
_bmad
|
|
27
|
+
.vsaf/_bmad BMAD workspace (planning configs + templates)
|
|
28
28
|
CLAUDE.md 8-step workflow rules
|
|
29
29
|
|
|
30
30
|
EXAMPLES
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngocsangairvds/vsaf",
|
|
3
|
-
"version": "3.1.
|
|
4
|
-
"description": "fix gitnexus
|
|
3
|
+
"version": "3.1.25",
|
|
4
|
+
"description": "fix gitnexus skip git",
|
|
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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const readline = require('readline');
|
|
4
5
|
const { ok, info, warn, step, hasCommand, exec, copyDir, copyFile, CLAUDE_HOME, CODEX_HOME } = require('./utils');
|
|
5
6
|
|
|
6
7
|
const PKG_ROOT = path.join(__dirname, '..');
|
|
@@ -14,8 +15,9 @@ async function installGlobal() {
|
|
|
14
15
|
console.log( '\x1b[1m╚══════════════════════════════════════════╝\x1b[0m');
|
|
15
16
|
|
|
16
17
|
installSkills();
|
|
17
|
-
installBinary('gitnexus', () => exec('npm install -g gitnexus@1.6.4-rc.
|
|
18
|
+
installBinary('gitnexus', () => exec('npm install -g gitnexus@1.6.4-rc.79'));
|
|
18
19
|
setupGitnexusMcp();
|
|
20
|
+
await setupConfluenceMcp();
|
|
19
21
|
|
|
20
22
|
console.log('\n\x1b[32m\x1b[1m✓ Global infra ready.\x1b[0m\n');
|
|
21
23
|
}
|
|
@@ -64,9 +66,100 @@ function setupGitnexusMcp() {
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
info('Configuring GitNexus MCP...');
|
|
67
|
-
exec('claude mcp add gitnexus -- npx -y gitnexus@1.6.4-rc.
|
|
69
|
+
exec('claude mcp add gitnexus -- npx -y gitnexus@1.6.4-rc.79 mcp')
|
|
68
70
|
? ok('GitNexus MCP configured')
|
|
69
|
-
: warn('MCP setup failed — run manually: claude mcp add gitnexus -- npx -y gitnexus@1.6.4-rc.
|
|
71
|
+
: warn('MCP setup failed — run manually: claude mcp add gitnexus -- npx -y gitnexus@1.6.4-rc.79 mcp');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function setupConfluenceMcp() {
|
|
75
|
+
step('Confluence MCP');
|
|
76
|
+
|
|
77
|
+
if (!hasCommand('claude')) {
|
|
78
|
+
info('Claude Code CLI not found — skip Confluence MCP setup');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const url = await promptInput(
|
|
83
|
+
' Confluence URL (blank to skip, e.g. http://confluence.company.com): '
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
if (!url) {
|
|
87
|
+
warn('Confluence MCP skipped — run manually later:\n' +
|
|
88
|
+
' claude mcp add confluence -e CONF_MODE=server \\\n' +
|
|
89
|
+
' -e CONF_BASE_URL=<your-url> \\\n' +
|
|
90
|
+
' -e CONF_AUTH_MODE=bearer \\\n' +
|
|
91
|
+
' -e CONF_TOKEN=<your-token> \\\n' +
|
|
92
|
+
' -- npx -y confluence-mcp-server');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const token = await promptSecret(
|
|
97
|
+
' Confluence Personal Access Token: '
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (!token) {
|
|
101
|
+
warn('Confluence MCP skipped — token is required');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const cmd = [
|
|
106
|
+
'claude mcp add confluence',
|
|
107
|
+
'-e CONF_MODE=server',
|
|
108
|
+
`-e CONF_BASE_URL=${url}`,
|
|
109
|
+
'-e CONF_AUTH_MODE=bearer',
|
|
110
|
+
`-e CONF_TOKEN=${token}`,
|
|
111
|
+
'-- npx -y confluence-mcp-server',
|
|
112
|
+
].join(' ');
|
|
113
|
+
|
|
114
|
+
exec(cmd)
|
|
115
|
+
? ok('Confluence MCP configured')
|
|
116
|
+
: warn('Confluence MCP setup failed — run manually (see above)');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function promptInput(question) {
|
|
120
|
+
return new Promise((resolve) => {
|
|
121
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
122
|
+
rl.question(question, (answer) => { rl.close(); resolve(answer.trim()); });
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function promptSecret(question) {
|
|
127
|
+
return new Promise((resolve) => {
|
|
128
|
+
// Non-TTY (CI, pipe): fall back to plain readline without hiding
|
|
129
|
+
if (!process.stdin.isTTY) {
|
|
130
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
131
|
+
rl.question(question, (answer) => { rl.close(); resolve(answer.trim()); });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
process.stdout.write(question);
|
|
136
|
+
process.stdin.setRawMode(true);
|
|
137
|
+
process.stdin.resume();
|
|
138
|
+
|
|
139
|
+
let input = '';
|
|
140
|
+
const onData = (buf) => {
|
|
141
|
+
const ch = buf.toString('utf8');
|
|
142
|
+
if (ch === '\r' || ch === '\n' || ch === '\x00') {
|
|
143
|
+
// Enter — done
|
|
144
|
+
process.stdin.setRawMode(false);
|
|
145
|
+
process.stdin.pause();
|
|
146
|
+
process.stdout.write('\n');
|
|
147
|
+
process.stdin.removeListener('data', onData);
|
|
148
|
+
resolve(input.trim());
|
|
149
|
+
} else if (ch === '\x03') {
|
|
150
|
+
// Ctrl+C
|
|
151
|
+
process.stdout.write('\n');
|
|
152
|
+
process.exit(0);
|
|
153
|
+
} else if (ch === '\x7f' || ch === '\b') {
|
|
154
|
+
// Backspace
|
|
155
|
+
input = input.slice(0, -1);
|
|
156
|
+
} else {
|
|
157
|
+
input += ch;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
process.stdin.on('data', onData);
|
|
162
|
+
});
|
|
70
163
|
}
|
|
71
164
|
|
|
72
165
|
module.exports = { installGlobal };
|
package/src/workflow.js
CHANGED
|
@@ -14,3 +14,7 @@ user_name: DuongOT
|
|
|
14
14
|
communication_language: English
|
|
15
15
|
document_output_language: English
|
|
16
16
|
output_folder: "{project-root}/_bmad-output"
|
|
17
|
+
|
|
18
|
+
# Confluence Integration (set by /vsaf-push-prd or /vsaf-push-srs on first use)
|
|
19
|
+
confluence_space_key: ""
|
|
20
|
+
confluence_parent_page: ""
|
|
@@ -48,7 +48,8 @@ Must have run `/vsaf-plan` and have its output before running this skill.
|
|
|
48
48
|
- Validation: [PASS / FAIL — details if fail]
|
|
49
49
|
|
|
50
50
|
## Next step
|
|
51
|
-
Run /vsaf-
|
|
51
|
+
- Run /vsaf-push-prd <comment> to publish this PRD to Confluence
|
|
52
|
+
- Or run /vsaf-doc-srs to write SRS from this PRD
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
## Notes
|
|
@@ -159,7 +159,8 @@ Save the SRS document to: `.vsaf/docs/srs/SRS-[project-name]-[FR-ID]-[feature-na
|
|
|
159
159
|
- [SRS sections still containing {{...}} that need additional input]
|
|
160
160
|
|
|
161
161
|
## Next step
|
|
162
|
-
Run /vsaf-
|
|
162
|
+
- Run /vsaf-push-srs <comment> to publish this SRS to Confluence
|
|
163
|
+
- Or run /vsaf-test .vsaf/docs/srs/SRS-[...].md to generate testcases
|
|
163
164
|
```
|
|
164
165
|
|
|
165
166
|
## Notes
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vsaf-push-prd
|
|
3
|
+
description: Push PRD document to Confluence. Use after /vsaf-doc-prd or /vsaf-doc-prd (edit) to publish or update the PRD page on Confluence. Accepts an optional comment as version note.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# VSAF Push PRD
|
|
7
|
+
|
|
8
|
+
## Objective
|
|
9
|
+
Publish the current PRD to Confluence — create a new page if it doesn't exist, or update the existing one. The comment becomes the Confluence version note.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
- `[comment]` — optional version note (e.g. "Initial draft", "Updated scope after stakeholder review")
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
- Confluence MCP must be configured (`vsaf init` sets this up)
|
|
16
|
+
- A PRD file must exist in `.vsaf/docs/planning-artifacts/`
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### Step 1 — Find PRD file
|
|
21
|
+
- List files in `.vsaf/docs/planning-artifacts/` matching `prd-*.md`
|
|
22
|
+
- If multiple found: ask user which one to push
|
|
23
|
+
- If none found: STOP — tell user to run `/vsaf-doc-prd` first
|
|
24
|
+
- Read full PRD content
|
|
25
|
+
|
|
26
|
+
### Step 2 — Load Confluence config
|
|
27
|
+
Read `.vsaf/_bmad/bmm/config.yaml` and extract:
|
|
28
|
+
- `confluence_space_key` — Confluence space (e.g. `PROJ`)
|
|
29
|
+
- `confluence_parent_page` — parent page title (e.g. `Project Documentation`)
|
|
30
|
+
|
|
31
|
+
If either field is missing or empty:
|
|
32
|
+
- Ask user: "Enter Confluence space key (e.g. PROJ):"
|
|
33
|
+
- Ask user: "Enter parent page title in Confluence (blank = root of space):"
|
|
34
|
+
- Save answers back to config so the user is not asked again
|
|
35
|
+
|
|
36
|
+
### Step 3 — Determine page title
|
|
37
|
+
Page title format: `[PRD] {feature-name}` — derive feature name from the filename (e.g. `prd-user-management.md` → `[PRD] User Management`)
|
|
38
|
+
|
|
39
|
+
### Step 4 — Check if page exists
|
|
40
|
+
Use the `confluence` MCP to search for a page with that exact title in the configured space:
|
|
41
|
+
```
|
|
42
|
+
CQL: title = "[PRD] {feature-name}" AND space = "{space_key}"
|
|
43
|
+
```
|
|
44
|
+
- **Found** → proceed to Step 5 (update)
|
|
45
|
+
- **Not found** → proceed to Step 6 (create)
|
|
46
|
+
|
|
47
|
+
### Step 5 — Update existing page
|
|
48
|
+
- Use the `confluence` MCP update tool with:
|
|
49
|
+
- Page ID from search result
|
|
50
|
+
- New content: full PRD markdown converted to Confluence format
|
|
51
|
+
- Version comment: the `[comment]` argument (or "Updated via vsaf-push-prd" if blank)
|
|
52
|
+
- Confirm the two-stage update if the MCP requires it
|
|
53
|
+
|
|
54
|
+
### Step 6 — Create new page
|
|
55
|
+
- Use the `confluence` MCP create tool with:
|
|
56
|
+
- Space key from config
|
|
57
|
+
- Parent page title from config (find its ID first if needed)
|
|
58
|
+
- Title: `[PRD] {feature-name}`
|
|
59
|
+
- Content: full PRD markdown
|
|
60
|
+
- Version comment: the `[comment]` argument (or "Created via vsaf-push-prd" if blank)
|
|
61
|
+
|
|
62
|
+
### Step 7 — Output to user
|
|
63
|
+
```
|
|
64
|
+
## PRD pushed to Confluence
|
|
65
|
+
|
|
66
|
+
- Page: [PRD] {feature-name}
|
|
67
|
+
- Action: [Created / Updated]
|
|
68
|
+
- Space: {space_key}
|
|
69
|
+
- Comment: {comment}
|
|
70
|
+
- URL: {confluence_page_url}
|
|
71
|
+
|
|
72
|
+
## Next step
|
|
73
|
+
Run /vsaf-push-srs to also publish the SRS, or continue with /vsaf-build
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Notes
|
|
77
|
+
- Never push a PRD that has failed `/vsaf-validate-prd` validation
|
|
78
|
+
- If the Confluence MCP is not configured, tell the user to run `vsaf init` and enter their token
|
|
79
|
+
- Do not modify the local PRD file during this step
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vsaf-push-srs
|
|
3
|
+
description: Push SRS document to Confluence. Use after /vsaf-doc-srs or SRS edits to publish or update the SRS page on Confluence. Accepts an optional comment as version note.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# VSAF Push SRS
|
|
7
|
+
|
|
8
|
+
## Objective
|
|
9
|
+
Publish the current SRS to Confluence — create a new page if it doesn't exist, or update the existing one. The comment becomes the Confluence version note.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
- `[comment]` — optional version note (e.g. "Initial draft", "Revised after tech review")
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
- Confluence MCP must be configured (`vsaf init` sets this up)
|
|
16
|
+
- An SRS file must exist in `.vsaf/docs/srs/`
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### Step 1 — Find SRS file
|
|
21
|
+
- List files in `.vsaf/docs/srs/` matching `*.md` (exclude `*-results.md`)
|
|
22
|
+
- If multiple found: ask user which one to push
|
|
23
|
+
- If none found: STOP — tell user to run `/vsaf-doc-srs` first
|
|
24
|
+
- Read full SRS content
|
|
25
|
+
|
|
26
|
+
### Step 2 — Load Confluence config
|
|
27
|
+
Read `.vsaf/_bmad/bmm/config.yaml` and extract:
|
|
28
|
+
- `confluence_space_key` — Confluence space (e.g. `PROJ`)
|
|
29
|
+
- `confluence_parent_page` — parent page title (e.g. `Project Documentation`)
|
|
30
|
+
|
|
31
|
+
If either field is missing or empty:
|
|
32
|
+
- Ask user: "Enter Confluence space key (e.g. PROJ):"
|
|
33
|
+
- Ask user: "Enter parent page title in Confluence (blank = root of space):"
|
|
34
|
+
- Save answers back to config so the user is not asked again
|
|
35
|
+
|
|
36
|
+
### Step 3 — Determine page title
|
|
37
|
+
Page title format: `[SRS] {feature-name}` — derive feature name from the filename (e.g. `user-management.md` → `[SRS] User Management`)
|
|
38
|
+
|
|
39
|
+
### Step 4 — Check if page exists
|
|
40
|
+
Use the `confluence` MCP to search for a page with that exact title in the configured space:
|
|
41
|
+
```
|
|
42
|
+
CQL: title = "[SRS] {feature-name}" AND space = "{space_key}"
|
|
43
|
+
```
|
|
44
|
+
- **Found** → proceed to Step 5 (update)
|
|
45
|
+
- **Not found** → proceed to Step 6 (create)
|
|
46
|
+
|
|
47
|
+
### Step 5 — Update existing page
|
|
48
|
+
- Use the `confluence` MCP update tool with:
|
|
49
|
+
- Page ID from search result
|
|
50
|
+
- New content: full SRS markdown converted to Confluence format
|
|
51
|
+
- Version comment: the `[comment]` argument (or "Updated via vsaf-push-srs" if blank)
|
|
52
|
+
- Confirm the two-stage update if the MCP requires it
|
|
53
|
+
|
|
54
|
+
### Step 6 — Create new page
|
|
55
|
+
- Use the `confluence` MCP create tool with:
|
|
56
|
+
- Space key from config
|
|
57
|
+
- Parent page title from config (find its ID first if needed)
|
|
58
|
+
- Title: `[SRS] {feature-name}`
|
|
59
|
+
- Content: full SRS markdown
|
|
60
|
+
- Version comment: the `[comment]` argument (or "Created via vsaf-push-srs" if blank)
|
|
61
|
+
|
|
62
|
+
### Step 7 — Link SRS page to PRD page (if PRD page exists)
|
|
63
|
+
- Search Confluence for the corresponding `[PRD] {feature-name}` page
|
|
64
|
+
- If found: add a "Related Documents" section or comment on the SRS page linking back to the PRD
|
|
65
|
+
- This creates traceability in Confluence
|
|
66
|
+
|
|
67
|
+
### Step 8 — Output to user
|
|
68
|
+
```
|
|
69
|
+
## SRS pushed to Confluence
|
|
70
|
+
|
|
71
|
+
- Page: [SRS] {feature-name}
|
|
72
|
+
- Action: [Created / Updated]
|
|
73
|
+
- Space: {space_key}
|
|
74
|
+
- Comment: {comment}
|
|
75
|
+
- URL: {confluence_page_url}
|
|
76
|
+
- PRD link: [linked / not found]
|
|
77
|
+
|
|
78
|
+
## Next step
|
|
79
|
+
Run /vsaf-test to generate testcases from this SRS, or /vsaf-build to implement
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Notes
|
|
83
|
+
- If the Confluence MCP is not configured, tell the user to run `vsaf init` and enter their token
|
|
84
|
+
- Do not modify the local SRS file during this step
|
|
85
|
+
- SRS result files (`*-results.md`) are test outputs — push those separately if needed
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Optional compatibility wrapper for teams that still type `make`.
|
|
2
|
-
# Preferred usage: run `vsaf <command>` directly.
|
|
3
|
-
|
|
4
|
-
.PHONY: help index verify review archive status mine clean
|
|
5
|
-
|
|
6
|
-
help: ## Show this help
|
|
7
|
-
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
|
8
|
-
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}'
|
|
9
|
-
|
|
10
|
-
index: ## Run `vsaf index`
|
|
11
|
-
@vsaf index
|
|
12
|
-
|
|
13
|
-
verify: ## Run `vsaf verify`
|
|
14
|
-
@vsaf verify
|
|
15
|
-
|
|
16
|
-
review: ## Run `vsaf review`
|
|
17
|
-
@vsaf review
|
|
18
|
-
|
|
19
|
-
archive: ## Run `vsaf archive`
|
|
20
|
-
@vsaf archive
|
|
21
|
-
|
|
22
|
-
mine: ## Run `vsaf mine`
|
|
23
|
-
@vsaf mine
|
|
24
|
-
|
|
25
|
-
status: ## Run `vsaf status`
|
|
26
|
-
@vsaf status
|
|
27
|
-
|
|
28
|
-
clean: ## Run `vsaf clean`
|
|
29
|
-
@vsaf clean
|