viepilot 1.0.1 → 1.2.0
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/CHANGELOG.md +5 -1
- package/README.md +10 -2
- package/bin/vp-tools.cjs +29 -2
- package/dev-install.sh +15 -0
- package/docs/skills-reference.md +7 -6
- package/docs/troubleshooting.md +16 -0
- package/docs/user/features/autonomous-mode.md +7 -5
- package/docs/user/quick-start.md +6 -0
- package/install.sh +47 -0
- package/lib/cli-shared.cjs +38 -0
- package/package.json +2 -1
- package/skills/vp-auto/SKILL.md +4 -3
- package/templates/phase/SUMMARY.md +2 -2
- package/templates/phase/TASK.md +3 -2
- package/workflows/audit.md +5 -4
- package/workflows/autonomous.md +15 -7
- package/workflows/rollback.md +8 -7
package/CHANGELOG.md
CHANGED
|
@@ -9,16 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Enhanced
|
|
11
11
|
|
|
12
|
-
- **M1.
|
|
12
|
+
- **M1.17 / Phase 21 (ENH-013) completed** — realigned README metrics (`npm run readme:sync` with `cloc`) and moved `.viepilot` to local-only (`.gitignore` + untracked index).
|
|
13
|
+
- **M1.15 / Phase 18 (FEAT-004) completed** — npm distribution flow is now fully closed: publish pipeline passes and package released to npm as `viepilot@1.0.1`.
|
|
13
14
|
- **M1.15 / Phase 19 (FEAT-005) completed** — installer now supports keyboard selector UX (arrow/space/enter), added `viepilot uninstall` command (`--target`, `--yes`, `--dry-run`), and switched dev installer to copy-first flow to avoid symlink-based skill discovery failures.
|
|
15
|
+
- **M1.16 / Phase 20 (FEAT-006) completed** — added README LOC auto-sync command (`npm run readme:sync`) driven by `cloc` with non-blocking fallback, installer `cloc` dependency checks/guidance, and a donate section in README with PayPal/MOMO links.
|
|
14
16
|
|
|
15
17
|
### Fixed
|
|
16
18
|
|
|
19
|
+
- **M1.18 / Phase 22 (BUG-002) completed** — introduced project-scoped checkpoint tags (`{project}-vp-p...`) and kept backward compatibility with legacy `vp-p...` tags for list/rollback flows.
|
|
17
20
|
- **CI coverage** — Jest chỉ instrument process hiện tại; test CLI qua `spawnSync` khiến `bin/vp-tools.cjs` báo **0%**. Đã tách `lib/cli-shared.cjs` (validators, `findProjectRoot`, Levenshtein) và đặt `collectCoverageFrom` trên file đó; bổ sung test in-process + `require.main === module` gate cho CLI; `install.sh` / `dev-install.sh` cài kèm `lib/`.
|
|
18
21
|
|
|
19
22
|
### Documentation
|
|
20
23
|
|
|
21
24
|
- `README.md`, `docs/user/quick-start.md` — updated install wizard controls and uninstall command examples.
|
|
25
|
+
- `README.md`, `docs/troubleshooting.md`, `docs/user/quick-start.md` — documented README metric sync flow, `cloc` fallback/install guidance, and maintainer usage.
|
|
22
26
|
- `docs/troubleshooting.md` — added selector TTY fallback guidance and uninstall/reinstall recovery flow for legacy symlink installs.
|
|
23
27
|
- `README.md` — Project Scale LOC + M1.11 completion banner; Documentation row includes `api/`
|
|
24
28
|
- `.viepilot/audit-report.md` — PASS after README metric sync (`/vp-audit`)
|
package/README.md
CHANGED
|
@@ -16,13 +16,19 @@ ViePilot là bộ skill framework cho phép AI assistant (Claude, GPT, etc.) ph
|
|
|
16
16
|
|
|
17
17
|
ViePilot is a skill framework that enables AI assistants to develop projects **autonomously**, with **control points**, and **recovery capability**. Built with professional standards: Semantic Versioning, Conventional Commits, Keep a Changelog.
|
|
18
18
|
|
|
19
|
+
### Support ViePilot
|
|
20
|
+
|
|
21
|
+
Nếu ViePilot giúp ích cho bạn, bạn có thể ủng hộ một ly cafe:
|
|
22
|
+
- PayPal: [https://paypal.me/SATCODING](https://paypal.me/SATCODING)
|
|
23
|
+
- MOMO: [https://me.momo.vn/aMINujUPTbIRtbTli6Fd](https://me.momo.vn/aMINujUPTbIRtbTli6Fd)
|
|
24
|
+
|
|
19
25
|
---
|
|
20
26
|
|
|
21
27
|
## Quy mô dự án / Project Scale
|
|
22
28
|
|
|
23
29
|
| Chỉ số / Metric | Giá trị / Value |
|
|
24
30
|
|-----------------|-----------------|
|
|
25
|
-
| Total LOC | **~
|
|
31
|
+
| Total LOC | **~22,384+** (`.md`, `.js`, `.cjs`, `.yml`, `.json`, `.sh`; không gồm `node_modules`) |
|
|
26
32
|
| Skills | **14** |
|
|
27
33
|
| Workflows | **12** |
|
|
28
34
|
| Templates | **16** (Project: 11, Phase: 5) |
|
|
@@ -31,6 +37,8 @@ ViePilot is a skill framework that enables AI assistants to develop projects **a
|
|
|
31
37
|
| ViePilot phases (repo) | **15** hoàn thành (xem `.viepilot/TRACKER.md`) |
|
|
32
38
|
| Standards | 5 (SemVer, Commits, Changelog, Comments, Contributors) |
|
|
33
39
|
|
|
40
|
+
> Metric `Total LOC` có thể được refresh tự động bằng `npm run readme:sync` (dùng `cloc`; nếu thiếu `cloc` script sẽ fallback an toàn).
|
|
41
|
+
|
|
34
42
|
### Phân bổ / Breakdown
|
|
35
43
|
|
|
36
44
|
| Thành phần / Component | Số lượng / Count | Mô tả / Description |
|
|
@@ -176,7 +184,7 @@ Tổng thể / Overall: ██████████████████
|
|
|
176
184
|
| **Workflows** | Step-by-step XML-like process definitions |
|
|
177
185
|
| **CLI** | Node.js (vp-tools.cjs, viepilot.cjs) |
|
|
178
186
|
| **State** | JSON (HANDOFF.json) + Markdown (TRACKER.md) |
|
|
179
|
-
| **Version Control** | Git tags for checkpoints (vp-p{N}-t{M}) |
|
|
187
|
+
| **Version Control** | Git tags for checkpoints (`{project}-vp-p{N}-t{M}`, legacy `vp-p{N}-t{M}` supported) |
|
|
180
188
|
|
|
181
189
|
---
|
|
182
190
|
|
package/bin/vp-tools.cjs
CHANGED
|
@@ -19,6 +19,8 @@ const {
|
|
|
19
19
|
levenshteinDistance,
|
|
20
20
|
findProjectRoot,
|
|
21
21
|
VIEPILOT_DIR,
|
|
22
|
+
getCheckpointTagPrefix,
|
|
23
|
+
isCheckpointTag,
|
|
22
24
|
} = require(path.join(__dirname, '../lib/cli-shared.cjs'));
|
|
23
25
|
|
|
24
26
|
// ============================================================================
|
|
@@ -570,10 +572,10 @@ const commands = {
|
|
|
570
572
|
const { execSync } = require('child_process');
|
|
571
573
|
|
|
572
574
|
try {
|
|
573
|
-
const tags = execSync('git tag
|
|
575
|
+
const tags = execSync('git tag --sort=-creatordate', {
|
|
574
576
|
cwd: projectRoot,
|
|
575
577
|
encoding: 'utf8'
|
|
576
|
-
}).trim().split('\n').filter(t => t);
|
|
578
|
+
}).trim().split('\n').filter(t => t).filter(isCheckpointTag);
|
|
577
579
|
|
|
578
580
|
if (tags.length === 0) {
|
|
579
581
|
console.log(formatWarning('No checkpoints found'));
|
|
@@ -616,6 +618,22 @@ const commands = {
|
|
|
616
618
|
}
|
|
617
619
|
},
|
|
618
620
|
|
|
621
|
+
/**
|
|
622
|
+
* Output deterministic project-scoped checkpoint tag prefix
|
|
623
|
+
*/
|
|
624
|
+
'tag-prefix': (args) => {
|
|
625
|
+
const projectCheck = validators.requireProjectRoot();
|
|
626
|
+
validateArgs([projectCheck]);
|
|
627
|
+
const raw = args.includes('--raw');
|
|
628
|
+
const prefix = getCheckpointTagPrefix(projectCheck.value);
|
|
629
|
+
if (raw) {
|
|
630
|
+
console.log(prefix);
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
console.log(formatInfo(`Checkpoint tag prefix: ${colors.bold}${prefix}${colors.reset}`));
|
|
634
|
+
console.log(JSON.stringify({ prefix }));
|
|
635
|
+
},
|
|
636
|
+
|
|
619
637
|
/**
|
|
620
638
|
* Check for potential conflicts
|
|
621
639
|
*/
|
|
@@ -803,6 +821,14 @@ const commands = {
|
|
|
803
821
|
'vp-tools version bump minor',
|
|
804
822
|
],
|
|
805
823
|
},
|
|
824
|
+
'tag-prefix': {
|
|
825
|
+
usage: 'vp-tools tag-prefix [--raw]',
|
|
826
|
+
description: 'Return deterministic project-scoped checkpoint tag prefix',
|
|
827
|
+
examples: [
|
|
828
|
+
'vp-tools tag-prefix',
|
|
829
|
+
'vp-tools tag-prefix --raw',
|
|
830
|
+
],
|
|
831
|
+
},
|
|
806
832
|
};
|
|
807
833
|
|
|
808
834
|
if (command && commandHelp[command]) {
|
|
@@ -839,6 +865,7 @@ ${colors.cyan}Commands:${colors.reset}
|
|
|
839
865
|
${colors.bold}reset${colors.reset} <target> [-f] Reset task/phase/all state (interactive)
|
|
840
866
|
${colors.bold}clean${colors.reset} [-f] [--dry-run] Clean generated files (interactive)
|
|
841
867
|
${colors.bold}checkpoints${colors.reset} List all ViePilot checkpoints (git tags)
|
|
868
|
+
${colors.bold}tag-prefix${colors.reset} [--raw] Show project-scoped checkpoint prefix
|
|
842
869
|
${colors.bold}conflicts${colors.reset} Check for potential conflicts
|
|
843
870
|
${colors.bold}save-state${colors.reset} Save current state for precise resume
|
|
844
871
|
${colors.bold}help${colors.reset} [command] Show help (optionally for specific command)
|
package/dev-install.sh
CHANGED
|
@@ -31,6 +31,20 @@ echo " Target: $CURSOR_SKILLS_DIR, $VIEPILOT_DIR"
|
|
|
31
31
|
echo " Profile: $INSTALL_PROFILE"
|
|
32
32
|
echo ""
|
|
33
33
|
|
|
34
|
+
check_cloc_dependency() {
|
|
35
|
+
if command -v cloc >/dev/null 2>&1; then
|
|
36
|
+
echo -e " ${GREEN}✓${NC} cloc detected"
|
|
37
|
+
return 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
echo -e "${YELLOW} cloc not found.${NC}"
|
|
41
|
+
echo " README LOC auto-sync will fallback safely, but metrics won't refresh automatically."
|
|
42
|
+
echo " Install suggestion:"
|
|
43
|
+
echo " - macOS: brew install cloc"
|
|
44
|
+
echo " - Ubuntu/Debian: sudo apt-get install -y cloc"
|
|
45
|
+
echo " - Windows: choco install cloc"
|
|
46
|
+
}
|
|
47
|
+
|
|
34
48
|
# Confirm
|
|
35
49
|
if [ "$AUTO_YES" != "1" ]; then
|
|
36
50
|
read -p "This will replace existing installation with dev files. Continue? (y/n) " -n 1 -r
|
|
@@ -95,6 +109,7 @@ echo -e " ${GREEN}✓${NC} templates"
|
|
|
95
109
|
echo -e " ${GREEN}✓${NC} bin"
|
|
96
110
|
echo -e " ${GREEN}✓${NC} lib"
|
|
97
111
|
echo -e " ${GREEN}✓${NC} ui-components"
|
|
112
|
+
check_cloc_dependency
|
|
98
113
|
|
|
99
114
|
# Count installed
|
|
100
115
|
SKILL_COUNT=$(ls -d "$CURSOR_SKILLS_DIR"/vp-*/ 2>/dev/null | wc -l | tr -d ' ')
|
package/docs/skills-reference.md
CHANGED
|
@@ -109,9 +109,10 @@ AI pauses for user input when:
|
|
|
109
109
|
- Blocker encountered
|
|
110
110
|
|
|
111
111
|
### Git Tags
|
|
112
|
-
- `vp-p{phase}-t{task}` - Task started
|
|
113
|
-
- `vp-p{phase}-t{task}-done` - Task completed
|
|
114
|
-
- `vp-p{phase}-complete` - Phase completed
|
|
112
|
+
- `{project}-vp-p{phase}-t{task}` - Task started
|
|
113
|
+
- `{project}-vp-p{phase}-t{task}-done` - Task completed
|
|
114
|
+
- `{project}-vp-p{phase}-complete` - Phase completed
|
|
115
|
+
- Legacy `vp-p...` tags are still accepted for compatibility
|
|
115
116
|
|
|
116
117
|
---
|
|
117
118
|
|
|
@@ -337,9 +338,9 @@ CHANGELOG.md (updated)
|
|
|
337
338
|
### Checkpoint Types
|
|
338
339
|
| Tag Pattern | Created By | Meaning |
|
|
339
340
|
|-------------|------------|---------|
|
|
340
|
-
| `vp-p{N}-t{M}` | vp-auto | Task started |
|
|
341
|
-
| `vp-p{N}-t{M}-done` | vp-auto | Task completed |
|
|
342
|
-
| `vp-p{N}-complete` | vp-auto | Phase completed |
|
|
341
|
+
| `{project}-vp-p{N}-t{M}` | vp-auto | Task started |
|
|
342
|
+
| `{project}-vp-p{N}-t{M}-done` | vp-auto | Task completed |
|
|
343
|
+
| `{project}-vp-p{N}-complete` | vp-auto | Phase completed |
|
|
343
344
|
| `v{semver}` | vp-auto | Version release |
|
|
344
345
|
|
|
345
346
|
### Safety Guarantees
|
package/docs/troubleshooting.md
CHANGED
|
@@ -41,6 +41,22 @@ npx viepilot install --target cursor-agent --yes
|
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
+
### README LOC metric is not updating
|
|
45
|
+
|
|
46
|
+
**Cause**: `cloc` is not installed, so `readme:sync` skips update by design.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Install cloc (macOS)
|
|
50
|
+
brew install cloc
|
|
51
|
+
|
|
52
|
+
# Then rerun metric sync
|
|
53
|
+
npm run readme:sync
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
On Linux/Windows, use your package manager (`apt`, `dnf`, `choco`) to install `cloc`.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
44
60
|
### `./install.sh: Permission denied`
|
|
45
61
|
|
|
46
62
|
**Cause**: Script not executable.
|
|
@@ -13,11 +13,11 @@ Autonomous mode điều phối **toàn bộ** phase và task theo `workflows/aut
|
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Mỗi task:
|
|
16
|
-
1. Tạo git checkpoint tag (`vp-p{N}-t{T}`)
|
|
16
|
+
1. Tạo git checkpoint tag (`{project}-vp-p{N}-t{T}`)
|
|
17
17
|
2. Implement theo acceptance criteria
|
|
18
18
|
3. Verify (automated + manual nếu cần)
|
|
19
19
|
4. Commit với conventional commit message
|
|
20
|
-
5. Tạo done tag (`vp-p{N}-t{T}-done`)
|
|
20
|
+
5. Tạo done tag (`{project}-vp-p{N}-t{T}-done`)
|
|
21
21
|
|
|
22
22
|
## Flags
|
|
23
23
|
|
|
@@ -87,15 +87,17 @@ Nếu bất kỳ gate nào fail → control point.
|
|
|
87
87
|
Mỗi task tạo 2 git tags:
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
vp-p2-t3 # Bắt đầu task 3 của phase 2
|
|
91
|
-
vp-p2-t3-done # Hoàn thành task 3 của phase 2
|
|
90
|
+
viepilot-vp-p2-t3 # Bắt đầu task 3 của phase 2
|
|
91
|
+
viepilot-vp-p2-t3-done # Hoàn thành task 3 của phase 2
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
Khi phase complete:
|
|
95
95
|
```bash
|
|
96
|
-
vp-p2-complete # Phase 2 hoàn thành
|
|
96
|
+
viepilot-vp-p2-complete # Phase 2 hoàn thành
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
+
Legacy tags `vp-p...` vẫn được hỗ trợ khi list/rollback để tương thích dự án cũ.
|
|
100
|
+
|
|
99
101
|
Xem tất cả checkpoints:
|
|
100
102
|
```bash
|
|
101
103
|
vp-tools checkpoints
|
package/docs/user/quick-start.md
CHANGED
package/install.sh
CHANGED
|
@@ -40,6 +40,50 @@ echo " ViePilot: $VIEPILOT_DIR"
|
|
|
40
40
|
echo " Profile: $INSTALL_PROFILE"
|
|
41
41
|
echo ""
|
|
42
42
|
|
|
43
|
+
install_cloc_best_effort() {
|
|
44
|
+
if command -v cloc >/dev/null 2>&1; then
|
|
45
|
+
echo " ✓ cloc detected"
|
|
46
|
+
return 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo -e "${YELLOW} cloc not found.${NC}"
|
|
50
|
+
echo " README metric auto-sync can still run with fallback, but LOC refresh will be skipped."
|
|
51
|
+
echo " Suggested install:"
|
|
52
|
+
echo " - macOS: brew install cloc"
|
|
53
|
+
echo " - Ubuntu/Debian: sudo apt-get install -y cloc"
|
|
54
|
+
echo " - Windows: choco install cloc"
|
|
55
|
+
|
|
56
|
+
if [ "$AUTO_YES" = "1" ]; then
|
|
57
|
+
return 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
read -p " Attempt automatic cloc install now (best effort)? (y/n) " -n 1 -r
|
|
61
|
+
echo
|
|
62
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
63
|
+
return 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
if command -v brew >/dev/null 2>&1; then
|
|
67
|
+
brew install cloc || true
|
|
68
|
+
elif command -v apt-get >/dev/null 2>&1; then
|
|
69
|
+
sudo apt-get update && sudo apt-get install -y cloc || true
|
|
70
|
+
elif command -v dnf >/dev/null 2>&1; then
|
|
71
|
+
sudo dnf install -y cloc || true
|
|
72
|
+
elif command -v yum >/dev/null 2>&1; then
|
|
73
|
+
sudo yum install -y cloc || true
|
|
74
|
+
elif command -v pacman >/dev/null 2>&1; then
|
|
75
|
+
sudo pacman -Sy --noconfirm cloc || true
|
|
76
|
+
else
|
|
77
|
+
echo -e "${YELLOW} Could not detect supported package manager. Install cloc manually.${NC}"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if command -v cloc >/dev/null 2>&1; then
|
|
81
|
+
echo " ✓ cloc installed"
|
|
82
|
+
else
|
|
83
|
+
echo -e "${YELLOW} cloc is still unavailable; continuing without blocking installation.${NC}"
|
|
84
|
+
fi
|
|
85
|
+
}
|
|
86
|
+
|
|
43
87
|
# Confirm installation
|
|
44
88
|
if [ "$AUTO_YES" != "1" ]; then
|
|
45
89
|
read -p "Continue with installation? (y/n) " -n 1 -r
|
|
@@ -102,6 +146,9 @@ chmod +x "$VIEPILOT_DIR/bin/vp-tools.cjs"
|
|
|
102
146
|
chmod +x "$VIEPILOT_DIR/bin/viepilot.cjs"
|
|
103
147
|
echo " ✓ vp-tools.cjs + viepilot.cjs + lib/cli-shared.cjs"
|
|
104
148
|
|
|
149
|
+
echo " Checking optional dependency for README metric sync..."
|
|
150
|
+
install_cloc_best_effort
|
|
151
|
+
|
|
105
152
|
# Create symlink in PATH (optional)
|
|
106
153
|
echo ""
|
|
107
154
|
if [ "$AUTO_YES" != "1" ]; then
|
package/lib/cli-shared.cjs
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
8
9
|
|
|
9
10
|
const VIEPILOT_DIR = '.viepilot';
|
|
10
11
|
|
|
@@ -19,6 +20,39 @@ function findProjectRoot() {
|
|
|
19
20
|
return null;
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
function normalizeTagPart(value) {
|
|
24
|
+
return String(value || '')
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
27
|
+
.replace(/^-+|-+$/g, '')
|
|
28
|
+
.replace(/-{2,}/g, '-');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getProjectSlug(root = findProjectRoot()) {
|
|
32
|
+
if (!root) return 'project';
|
|
33
|
+
try {
|
|
34
|
+
const gitTop = execSync('git rev-parse --show-toplevel', { cwd: root, encoding: 'utf8' }).trim();
|
|
35
|
+
const repoName = path.basename(gitTop);
|
|
36
|
+
const normalizedRepo = normalizeTagPart(repoName);
|
|
37
|
+
if (normalizedRepo) return normalizedRepo;
|
|
38
|
+
} catch (_e) {
|
|
39
|
+
// fallback to directory name below
|
|
40
|
+
}
|
|
41
|
+
return normalizeTagPart(path.basename(root)) || 'project';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getCheckpointTagPrefix(root = findProjectRoot()) {
|
|
45
|
+
return `${getProjectSlug(root)}-vp`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isCheckpointTag(tag) {
|
|
49
|
+
const value = String(tag || '');
|
|
50
|
+
return /^vp-p\d+-(?:t\d+(?:-done)?|complete)$/.test(value)
|
|
51
|
+
|| /^[a-z0-9][a-z0-9-]*-vp-p\d+-(?:t\d+(?:-done)?|complete)$/.test(value)
|
|
52
|
+
|| /^vp-backup-\d{8}-\d{6}$/.test(value)
|
|
53
|
+
|| /^[a-z0-9][a-z0-9-]*-vp-backup-\d{8}-\d{6}$/.test(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
22
56
|
const validators = {
|
|
23
57
|
isPositiveInteger(value, name = 'value') {
|
|
24
58
|
const num = parseInt(value, 10);
|
|
@@ -103,6 +137,10 @@ function levenshteinDistance(a, b) {
|
|
|
103
137
|
module.exports = {
|
|
104
138
|
VIEPILOT_DIR,
|
|
105
139
|
findProjectRoot,
|
|
140
|
+
normalizeTagPart,
|
|
141
|
+
getProjectSlug,
|
|
142
|
+
getCheckpointTagPrefix,
|
|
143
|
+
isCheckpointTag,
|
|
106
144
|
validators,
|
|
107
145
|
levenshteinDistance,
|
|
108
146
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viepilot",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "**Autonomous Vibe Coding Framework / Bộ khung phát triển tự động có kiểm soát**",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"test": "jest",
|
|
15
15
|
"test:coverage": "jest --coverage",
|
|
16
16
|
"test:watch": "jest --watch",
|
|
17
|
+
"readme:sync": "node scripts/sync-readme-metrics.cjs",
|
|
17
18
|
"lint:cli": "node --check bin/vp-tools.cjs && node --check bin/viepilot.cjs",
|
|
18
19
|
"verify:release": "npm run lint:cli && npm test && npm pack --dry-run",
|
|
19
20
|
"prepublishOnly": "npm run verify:release",
|
package/skills/vp-auto/SKILL.md
CHANGED
|
@@ -47,7 +47,7 @@ If required task details are missing, do not implement until task contract is re
|
|
|
47
47
|
**Doc-first gate before implementation (BUG-001):**
|
|
48
48
|
- After contract validation and **before** any deliverable code/doc edits: the task `.md` MUST hold a real written plan (`Paths` + `File-Level Plan` or bullet **Implementation Notes**—no bare `{{PLACEHOLDER}}` rows).
|
|
49
49
|
- `PHASE-STATE.md` MUST show the task `in_progress` **before** the first implementation commit for that task.
|
|
50
|
-
- **Do not** create `vp-p{phase}-t{task}` or edit shipping files until both are satisfied (read-only exploration and editing the task file to record the plan are allowed).
|
|
50
|
+
- **Do not** create `{projectPrefix}-vp-p{phase}-t{task}` or edit shipping files until both are satisfied (read-only exploration and editing the task file to record the plan are allowed).
|
|
51
51
|
|
|
52
52
|
**Preflight before each task implementation:**
|
|
53
53
|
- Read `.viepilot/STACKS.md` (if exists)
|
|
@@ -63,6 +63,7 @@ If required task details are missing, do not implement until task contract is re
|
|
|
63
63
|
|
|
64
64
|
**Updates on milestone complete:**
|
|
65
65
|
- `README.md` — version badge, skills/workflows counts, Skills Reference table, Workflows table, Project Structure, Completion Status
|
|
66
|
+
- `README.md` metrics — run `npm run readme:sync` when script exists; if `cloc` missing, continue with logged guidance (non-blocking)
|
|
66
67
|
|
|
67
68
|
**After:** Project built, or paused for user intervention.
|
|
68
69
|
</objective>
|
|
@@ -131,7 +132,7 @@ Stack preflight:
|
|
|
131
132
|
1. Validate task contract (`workflows/autonomous.md`).
|
|
132
133
|
2. Record plan in task file; set task `in_progress` in `PHASE-STATE.md`.
|
|
133
134
|
3. Stack preflight.
|
|
134
|
-
4. Create git tag `vp-p{phase}-t{task}` **only after** steps 1–3 pass.
|
|
135
|
+
4. Create git tag `{projectPrefix}-vp-p{phase}-t{task}` **only after** steps 1–3 pass.
|
|
135
136
|
|
|
136
137
|
#### 3b. Execute Task
|
|
137
138
|
- Implement according to objective
|
|
@@ -176,7 +177,7 @@ When all tasks done:
|
|
|
176
177
|
- Run phase verification
|
|
177
178
|
- Check phase quality gate
|
|
178
179
|
- Write SUMMARY.md
|
|
179
|
-
- Create git tag: `vp-p{phase}-complete`
|
|
180
|
+
- Create git tag: `{projectPrefix}-vp-p{phase}-complete`
|
|
180
181
|
- Increment version if needed
|
|
181
182
|
|
|
182
183
|
### 6. Iterate
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
## Files Changed
|
|
28
28
|
|
|
29
|
-
> Populate by running: `git diff
|
|
29
|
+
> Populate by running: `TAG_PREFIX=$(vp-tools tag-prefix --raw) && git diff "${TAG_PREFIX}-p{{PHASE_NUMBER}}-t1"..HEAD --name-status | sort`
|
|
30
30
|
> List every file individually. Do NOT use glob patterns or summarize groups.
|
|
31
31
|
|
|
32
32
|
### Created
|
|
@@ -64,4 +64,4 @@
|
|
|
64
64
|
{{NOTES}}
|
|
65
65
|
|
|
66
66
|
---
|
|
67
|
-
Git Tag: `vp-p{{PHASE_NUMBER}}-complete`
|
|
67
|
+
Git Tag: `{projectPrefix}-vp-p{{PHASE_NUMBER}}-complete`
|
package/templates/phase/TASK.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- **Status**: not_started | in_progress | blocked | done | skipped
|
|
6
6
|
- **Complexity**: {{COMPLEXITY}}
|
|
7
7
|
- **Dependencies**: {{DEPENDENCIES}}
|
|
8
|
-
- **Git Tag**: vp-p{{PHASE_NUMBER}}-t{{TASK_NUMBER}}
|
|
8
|
+
- **Git Tag**: {projectPrefix}-vp-p{{PHASE_NUMBER}}-t{{TASK_NUMBER}}
|
|
9
9
|
|
|
10
10
|
## Objective
|
|
11
11
|
|
|
@@ -97,5 +97,6 @@ manual:
|
|
|
97
97
|
## Rollback
|
|
98
98
|
```bash
|
|
99
99
|
# If need to undo this task:
|
|
100
|
-
|
|
100
|
+
TAG_PREFIX=$(vp-tools tag-prefix --raw)
|
|
101
|
+
git revert --no-commit $(git rev-list "${TAG_PREFIX}-p{{PHASE_NUMBER}}-t{{TASK_NUMBER}}".."${TAG_PREFIX}-p{{PHASE_NUMBER}}-t{{TASK_NUMBER}}-done")
|
|
101
102
|
```
|
package/workflows/audit.md
CHANGED
|
@@ -92,8 +92,8 @@ fi
|
|
|
92
92
|
### 1d. Git tags vs completed phases
|
|
93
93
|
```bash
|
|
94
94
|
# List completed phases (PHASE-STATE.md with status: complete)
|
|
95
|
-
# List git tags matching
|
|
96
|
-
COMPLETE_TAGS=$(git tag 2>/dev/null | grep -E '^vp-p[0-9]+-complete$' | sort)
|
|
95
|
+
# List git tags matching legacy + project-scoped complete format
|
|
96
|
+
COMPLETE_TAGS=$(git tag 2>/dev/null | grep -E '(^vp-p[0-9]+-complete$)|(^[a-z0-9-]+-vp-p[0-9]+-complete$)' | sort)
|
|
97
97
|
# Report any phase marked complete in PHASE-STATE.md without a git tag
|
|
98
98
|
```
|
|
99
99
|
|
|
@@ -206,8 +206,9 @@ for phase_state in $RECENT_PHASES; do
|
|
|
206
206
|
PHASE_DIR=$(dirname "$phase_state")
|
|
207
207
|
# Check if docs/ was updated in commits for this phase
|
|
208
208
|
PHASE_NUM=$(basename "$PHASE_DIR" | grep -o '^[0-9]*' | sed 's/^0*//')
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
TAG_PREFIX=$(vp-tools tag-prefix --raw 2>/dev/null || echo "vp")
|
|
210
|
+
PHASE_TAG="${TAG_PREFIX}-p${PHASE_NUM}-complete"
|
|
211
|
+
PREV_TAG=$(git tag --sort=-version:refname 2>/dev/null | grep -E "(vp-p.*-complete|[a-z0-9-]+-vp-p.*-complete)" | grep -A1 "^$PHASE_TAG$" | tail -1)
|
|
211
212
|
if [ -n "$PREV_TAG" ]; then
|
|
212
213
|
DOCS_CHANGED=$(git diff "$PREV_TAG"..HEAD --name-only 2>/dev/null | grep "^docs/" | wc -l | tr -d ' ')
|
|
213
214
|
if [ "$DOCS_CHANGED" -eq 0 ]; then
|
package/workflows/autonomous.md
CHANGED
|
@@ -119,7 +119,7 @@ Canonical order for every task: **Validate contract → Doc-first gate → Stack
|
|
|
119
119
|
|
|
120
120
|
If any check fails:
|
|
121
121
|
- Mark task `blocked` in `PHASE-STATE.md` and list what is missing under **Notes**
|
|
122
|
-
- **Do not** create `vp-p{phase}-t{task}`
|
|
122
|
+
- **Do not** create `{projectPrefix}-vp-p{phase}-t{task}`
|
|
123
123
|
- **Do not** proceed to **Execute Task**
|
|
124
124
|
|
|
125
125
|
#### Stack Preflight (token-efficient lookup)
|
|
@@ -137,7 +137,7 @@ If stack cache is missing:
|
|
|
137
137
|
|
|
138
138
|
Only after **Validate Task Contract**, **Pre-execution documentation gate**, and **Stack Preflight** (or explicit waiver logged in the task file with reason):
|
|
139
139
|
|
|
140
|
-
Create git tag: `vp-p{phase}-t{task}`
|
|
140
|
+
Create git tag: `{projectPrefix}-vp-p{phase}-t{task}`
|
|
141
141
|
Ensure `PHASE-STATE.md` already shows current task `in_progress` (set during the gate if not already).
|
|
142
142
|
|
|
143
143
|
#### Execute Task
|
|
@@ -178,7 +178,7 @@ quality_gate:
|
|
|
178
178
|
#### Handle Result
|
|
179
179
|
|
|
180
180
|
**PASS:**
|
|
181
|
-
- Create git tag: `vp-p{phase}-t{task}-done`
|
|
181
|
+
- Create git tag: `{projectPrefix}-vp-p{phase}-t{task}-done`
|
|
182
182
|
- Update PHASE-STATE.md immediately: task → done, append files changed by this task to Files Changed table (individual files, no glob patterns)
|
|
183
183
|
- Update TRACKER.md immediately
|
|
184
184
|
- Update HANDOFF.json immediately
|
|
@@ -224,7 +224,8 @@ When all tasks in phase are done/skipped:
|
|
|
224
224
|
Populate `{{CREATED_FILES}}`, `{{MODIFIED_FILES}}`, `{{DELETED_FILES}}` from git:
|
|
225
225
|
```bash
|
|
226
226
|
# Get ALL individual files changed since phase start tag
|
|
227
|
-
|
|
227
|
+
TAG_PREFIX=$(node bin/vp-tools.cjs tag-prefix --raw)
|
|
228
|
+
git diff "${TAG_PREFIX}-p{phase}-t1"..HEAD --name-status | sort
|
|
228
229
|
```
|
|
229
230
|
List **every file individually** — do NOT use glob patterns or summarize.
|
|
230
231
|
Correct example:
|
|
@@ -243,7 +244,7 @@ When all tasks in phase are done/skipped:
|
|
|
243
244
|
| smarttrack-*/pom.xml (8 files) | 1.1 | ← WRONG: glob pattern
|
|
244
245
|
| smarttrack-*/src/** (7 files) | 1.1 | ← WRONG: summarized
|
|
245
246
|
```
|
|
246
|
-
4. Create git tag: `vp-p{phase}-complete`
|
|
247
|
+
4. Create git tag: `{projectPrefix}-vp-p{phase}-complete`
|
|
247
248
|
5. Check version bump needed:
|
|
248
249
|
- Features added → MINOR
|
|
249
250
|
- Fixes only → PATCH
|
|
@@ -280,7 +281,8 @@ Commit: `chore: update ROADMAP.md — phase {N} complete`
|
|
|
280
281
|
if [ ! -d "skills" ]; then
|
|
281
282
|
echo "→ Skipping skills-reference update (not a viepilot framework repo)"
|
|
282
283
|
else
|
|
283
|
-
|
|
284
|
+
TAG_PREFIX=$(node bin/vp-tools.cjs tag-prefix --raw)
|
|
285
|
+
NEW_SKILLS=$(git diff "${TAG_PREFIX}-p{phase}-t1"..HEAD --name-only | grep 'skills/.*/SKILL\.md' | sed 's|skills/||; s|/SKILL\.md||')
|
|
284
286
|
if [ -n "$NEW_SKILLS" ]; then
|
|
285
287
|
# Append new sections to docs/skills-reference.md
|
|
286
288
|
# (same incremental logic as workflows/documentation.md step 3B)
|
|
@@ -323,6 +325,11 @@ fi
|
|
|
323
325
|
Update README.md — **generic updates (all projects)**:
|
|
324
326
|
1. Any version number mentions: update to `$ACTUAL_VERSION`
|
|
325
327
|
2. Any "last updated" or "as of" date references
|
|
328
|
+
3. If project contains `README` metrics table and `scripts/sync-readme-metrics.cjs`, run:
|
|
329
|
+
```bash
|
|
330
|
+
npm run readme:sync || true
|
|
331
|
+
```
|
|
332
|
+
- If `cloc` is unavailable, script must log guidance and continue (non-blocking).
|
|
326
333
|
|
|
327
334
|
**viepilot framework only** (skip if `skills/` directory does not exist):
|
|
328
335
|
```bash
|
|
@@ -387,7 +394,8 @@ Options:
|
|
|
387
394
|
|
|
388
395
|
**Rollback:**
|
|
389
396
|
```bash
|
|
390
|
-
|
|
397
|
+
TAG_PREFIX=$(node bin/vp-tools.cjs tag-prefix --raw)
|
|
398
|
+
git revert --no-commit $(git rev-list "${TAG_PREFIX}-p{phase}-t{task}"..HEAD)
|
|
391
399
|
```
|
|
392
400
|
- Reset task → not_started
|
|
393
401
|
- Continue or stop
|
package/workflows/rollback.md
CHANGED
|
@@ -8,7 +8,7 @@ Safe rollback to any ViePilot checkpoint với backup và state preservation.
|
|
|
8
8
|
## 1. List Available Checkpoints
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
git tag
|
|
11
|
+
git tag --sort=-creatordate | rg "(^vp-p|^-*vp-backup|^[a-z0-9-]+-vp-p|^[a-z0-9-]+-vp-backup)" | head -20
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
For each tag, get info:
|
|
@@ -41,7 +41,7 @@ If `--list` flag, stop here.
|
|
|
41
41
|
Validate tag exists.
|
|
42
42
|
|
|
43
43
|
**If --latest:**
|
|
44
|
-
Select most recent
|
|
44
|
+
Select most recent checkpoint tag (project-scoped or legacy).
|
|
45
45
|
|
|
46
46
|
**Otherwise:**
|
|
47
47
|
Ask user to select from list or enter tag name.
|
|
@@ -98,7 +98,8 @@ Wait for confirmation.
|
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
100
|
# Create backup tag
|
|
101
|
-
|
|
101
|
+
TAG_PREFIX="$(vp-tools tag-prefix --raw)"
|
|
102
|
+
BACKUP_TAG="${TAG_PREFIX}-backup-$(date +%Y%m%d-%H%M%S)"
|
|
102
103
|
git tag $BACKUP_TAG
|
|
103
104
|
|
|
104
105
|
# Backup state files
|
|
@@ -126,10 +127,10 @@ git log -1 --oneline
|
|
|
126
127
|
<step name="update_state">
|
|
127
128
|
## 7. Update State Files
|
|
128
129
|
|
|
129
|
-
Parse tag to determine phase/task:
|
|
130
|
-
- `vp-p{N}-t{M}` → Phase N, Task M, status: in_progress
|
|
131
|
-
- `vp-p{N}-t{M}-done` → Phase N, Task M+1, status: not_started
|
|
132
|
-
- `vp-p{N}-complete` → Phase N+1, Task 1, status: not_started
|
|
130
|
+
Parse tag to determine phase/task (support both legacy and project-scoped):
|
|
131
|
+
- `vp-p{N}-t{M}` or `{project}-vp-p{N}-t{M}` → Phase N, Task M, status: in_progress
|
|
132
|
+
- `vp-p{N}-t{M}-done` or `{project}-vp-p{N}-t{M}-done` → Phase N, Task M+1, status: not_started
|
|
133
|
+
- `vp-p{N}-complete` or `{project}-vp-p{N}-complete` → Phase N+1, Task 1, status: not_started
|
|
133
134
|
|
|
134
135
|
Update HANDOFF.json accordingly.
|
|
135
136
|
Update TRACKER.md progress.
|