musubix 3.6.1 โ 3.7.3
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/.github/skills/build-fix/SKILL.md +124 -0
- package/.github/skills/checkpoint/SKILL.md +131 -0
- package/.github/skills/codemap/SKILL.md +120 -0
- package/.github/skills/codemap/templates/codemap-index.md +142 -0
- package/.github/skills/codemap/templates/package-codemap.md +160 -0
- package/.github/skills/context-optimizer/SKILL.md +109 -0
- package/.github/skills/context-optimizer/contexts/dev.md +40 -0
- package/.github/skills/context-optimizer/contexts/research.md +55 -0
- package/.github/skills/context-optimizer/contexts/review.md +49 -0
- package/.github/skills/e2e-runner/SKILL.md +145 -0
- package/.github/skills/eval-harness/SKILL.md +111 -0
- package/.github/skills/eval-harness/examples/capability-eval.md +158 -0
- package/.github/skills/eval-harness/examples/human-grader-template.md +326 -0
- package/.github/skills/eval-harness/examples/regression-eval.md +228 -0
- package/.github/skills/learning-hooks/SKILL.md +101 -0
- package/.github/skills/learning-hooks/templates/learned-skill-template.md +79 -0
- package/.github/skills/musubix-adr-generation/SKILL.md +33 -168
- package/.github/skills/musubix-best-practices/SKILL.md +46 -276
- package/.github/skills/musubix-c4-design/SKILL.md +48 -124
- package/.github/skills/musubix-code-generation/SKILL.md +46 -193
- package/.github/skills/musubix-domain-inference/SKILL.md +54 -168
- package/.github/skills/musubix-ears-validation/SKILL.md +49 -136
- package/.github/skills/musubix-sdd-workflow/SKILL.md +56 -178
- package/.github/skills/musubix-technical-writing/SKILL.md +45 -381
- package/.github/skills/musubix-test-generation/SKILL.md +52 -176
- package/.github/skills/musubix-traceability/SKILL.md +52 -99
- package/.github/skills/refactor-cleaner/SKILL.md +105 -0
- package/.github/skills/session-manager/SKILL.md +119 -0
- package/.github/skills/session-manager/scripts/session-end.sh +175 -0
- package/.github/skills/session-manager/scripts/session-start.sh +87 -0
- package/.github/skills/verification-loop/SKILL.md +111 -0
- package/.github/skills/verification-loop/scripts/verify.sh +305 -0
- package/AGENTS.md +231 -1034
- package/docs/CODEMAPS/CODEMAP.md +1 -0
- package/docs/adr/ADR-v3.7.0-001-everything-claude-code-integration.md +102 -0
- package/package.json +2 -2
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# MUSUBIX Session End Hook
|
|
3
|
+
# REQ-SM-002: SessionEnd Hook
|
|
4
|
+
#
|
|
5
|
+
# Usage: ./session-end.sh [--project PROJECT_NAME]
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
# Configuration
|
|
10
|
+
SESSIONS_DIR="${HOME}/.musubix/sessions"
|
|
11
|
+
MAX_FILE_SIZE=1048576 # 1MB
|
|
12
|
+
RETENTION_DAYS=30
|
|
13
|
+
MAX_FILES=100
|
|
14
|
+
|
|
15
|
+
# Colors
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
BLUE='\033[0;34m'
|
|
19
|
+
RED='\033[0;31m'
|
|
20
|
+
NC='\033[0m'
|
|
21
|
+
|
|
22
|
+
# Parse arguments
|
|
23
|
+
PROJECT_NAME=""
|
|
24
|
+
while [[ "$#" -gt 0 ]]; do
|
|
25
|
+
case $1 in
|
|
26
|
+
--project) PROJECT_NAME="$2"; shift ;;
|
|
27
|
+
*) echo "Unknown parameter: $1"; exit 1 ;;
|
|
28
|
+
esac
|
|
29
|
+
shift
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
# Create sessions directory if it doesn't exist
|
|
33
|
+
mkdir -p "$SESSIONS_DIR"
|
|
34
|
+
|
|
35
|
+
# Generate filename
|
|
36
|
+
TIMESTAMP=$(date +"%Y-%m-%d-%H-%M")
|
|
37
|
+
SESSION_FILE="${SESSIONS_DIR}/${TIMESTAMP}.md"
|
|
38
|
+
|
|
39
|
+
echo -e "${BLUE}๐ MUSUBIX Session Manager - Session End${NC}"
|
|
40
|
+
echo "================================================"
|
|
41
|
+
echo ""
|
|
42
|
+
|
|
43
|
+
# Detect project name if not provided
|
|
44
|
+
if [ -z "$PROJECT_NAME" ]; then
|
|
45
|
+
if [ -f "package.json" ]; then
|
|
46
|
+
PROJECT_NAME=$(grep -o '"name": *"[^"]*"' package.json | head -1 | cut -d'"' -f4)
|
|
47
|
+
elif [ -d ".git" ]; then
|
|
48
|
+
PROJECT_NAME=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null)
|
|
49
|
+
fi
|
|
50
|
+
PROJECT_NAME="${PROJECT_NAME:-Unknown Project}"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Get start time (approximate based on shell history or use current)
|
|
54
|
+
START_TIME=$(date -d "2 hours ago" +"%H:%M" 2>/dev/null || date +"%H:%M")
|
|
55
|
+
CURRENT_TIME=$(date +"%H:%M")
|
|
56
|
+
CURRENT_DATE=$(date +"%Y-%m-%d")
|
|
57
|
+
|
|
58
|
+
# Interactive prompts for session data
|
|
59
|
+
echo -e "${YELLOW}ใปใใทใงใณๆ
ๅ ฑใๅ
ฅๅใใฆใใ ใใ:${NC}"
|
|
60
|
+
echo ""
|
|
61
|
+
|
|
62
|
+
# Completed tasks
|
|
63
|
+
echo "โ
ๅฎไบใใใฟในใฏ (็ฉบ่กใง็ตไบ):"
|
|
64
|
+
COMPLETED_TASKS=""
|
|
65
|
+
while IFS= read -r line; do
|
|
66
|
+
[ -z "$line" ] && break
|
|
67
|
+
COMPLETED_TASKS="${COMPLETED_TASKS}\n- [x] ${line}"
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
# In progress tasks
|
|
71
|
+
echo ""
|
|
72
|
+
echo "โณ ้ฒ่กไธญใฎใฟในใฏ (็ฉบ่กใง็ตไบ):"
|
|
73
|
+
IN_PROGRESS_TASKS=""
|
|
74
|
+
while IFS= read -r line; do
|
|
75
|
+
[ -z "$line" ] && break
|
|
76
|
+
IN_PROGRESS_TASKS="${IN_PROGRESS_TASKS}\n- [ ] ${line}"
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
# Notes for next session
|
|
80
|
+
echo ""
|
|
81
|
+
echo "๐ ๆฌกๅๅใใกใข (็ฉบ่กใง็ตไบ):"
|
|
82
|
+
NOTES=""
|
|
83
|
+
while IFS= read -r line; do
|
|
84
|
+
[ -z "$line" ] && break
|
|
85
|
+
NOTES="${NOTES}\n- ${line}"
|
|
86
|
+
done
|
|
87
|
+
|
|
88
|
+
# Context files to load
|
|
89
|
+
echo ""
|
|
90
|
+
echo "๐ ๆฌกๅ่ชญใฟ่พผใในใใใกใคใซ (็ฉบ่กใง็ตไบ):"
|
|
91
|
+
CONTEXT_FILES=""
|
|
92
|
+
while IFS= read -r line; do
|
|
93
|
+
[ -z "$line" ] && break
|
|
94
|
+
CONTEXT_FILES="${CONTEXT_FILES}\n${line}"
|
|
95
|
+
done
|
|
96
|
+
|
|
97
|
+
# Count completed tasks
|
|
98
|
+
COMPLETED_COUNT=$(echo -e "$COMPLETED_TASKS" | grep -c "\[x\]" 2>/dev/null || echo 0)
|
|
99
|
+
IN_PROGRESS_COUNT=$(echo -e "$IN_PROGRESS_TASKS" | grep -c "\[ \]" 2>/dev/null || echo 0)
|
|
100
|
+
NOTES_COUNT=$(echo -e "$NOTES" | grep -c "^-" 2>/dev/null || echo 0)
|
|
101
|
+
|
|
102
|
+
# Generate session file
|
|
103
|
+
cat > "$SESSION_FILE" << EOF
|
|
104
|
+
# Session: ${CURRENT_DATE}
|
|
105
|
+
|
|
106
|
+
**Date:** ${CURRENT_DATE}
|
|
107
|
+
**Started:** ${START_TIME}
|
|
108
|
+
**Last Updated:** ${CURRENT_TIME}
|
|
109
|
+
**Project:** ${PROJECT_NAME}
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Current State
|
|
114
|
+
|
|
115
|
+
### Completed
|
|
116
|
+
$(echo -e "$COMPLETED_TASKS" | sed '/^$/d')
|
|
117
|
+
|
|
118
|
+
### In Progress
|
|
119
|
+
$(echo -e "$IN_PROGRESS_TASKS" | sed '/^$/d')
|
|
120
|
+
|
|
121
|
+
### Blocked
|
|
122
|
+
- [ ] (ใชใ)
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Notes for Next Session
|
|
127
|
+
$(echo -e "$NOTES" | sed '/^$/d')
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Context to Load
|
|
132
|
+
|
|
133
|
+
\`\`\`
|
|
134
|
+
$(echo -e "$CONTEXT_FILES" | sed '/^$/d')
|
|
135
|
+
\`\`\`
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Session Summary
|
|
140
|
+
|
|
141
|
+
- **ใฟในใฏๅฎไบๆฐ**: ${COMPLETED_COUNT}
|
|
142
|
+
- **ๆชๅฎไบใฟในใฏ**: ${IN_PROGRESS_COUNT}
|
|
143
|
+
- **ๆฌกๅๅใใกใข**: ${NOTES_COUNT}้
็ฎ
|
|
144
|
+
- **ใปใใทใงใณๆ้**: ${START_TIME} - ${CURRENT_TIME}
|
|
145
|
+
|
|
146
|
+
EOF
|
|
147
|
+
|
|
148
|
+
# Check file size
|
|
149
|
+
FILE_SIZE=$(stat -f%z "$SESSION_FILE" 2>/dev/null || stat -c%s "$SESSION_FILE" 2>/dev/null)
|
|
150
|
+
if [ "$FILE_SIZE" -gt "$MAX_FILE_SIZE" ]; then
|
|
151
|
+
echo -e "${RED}โ ๏ธ ่ญฆๅ: ใปใใทใงใณใใกใคใซใ1MBใ่ถ
ใใฆใใพใ${NC}"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Cleanup old sessions
|
|
155
|
+
echo ""
|
|
156
|
+
echo -e "${YELLOW}๐งน ๅคใใปใใทใงใณใฎใฏใชใผใณใขใใ...${NC}"
|
|
157
|
+
find "$SESSIONS_DIR" -name "*.md" -mtime +"$RETENTION_DAYS" -delete 2>/dev/null || true
|
|
158
|
+
|
|
159
|
+
# Check file count
|
|
160
|
+
FILE_COUNT=$(find "$SESSIONS_DIR" -name "*.md" -type f | wc -l)
|
|
161
|
+
if [ "$FILE_COUNT" -gt "$MAX_FILES" ]; then
|
|
162
|
+
echo -e "${YELLOW}โน๏ธ ใใกใคใซๆฐใ${MAX_FILES}ใ่ถ
ใใฆใใพใใๅคใใใกใคใซใๅ้คใใพใใ${NC}"
|
|
163
|
+
find "$SESSIONS_DIR" -name "*.md" -type f -printf '%T+ %p\n' | sort | head -n "$((FILE_COUNT - MAX_FILES))" | cut -d' ' -f2- | xargs rm -f 2>/dev/null || true
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
echo ""
|
|
167
|
+
echo "================================================"
|
|
168
|
+
echo -e "${GREEN}โ
ใปใใทใงใณใไฟๅญใใพใใ: ${SESSION_FILE}${NC}"
|
|
169
|
+
echo ""
|
|
170
|
+
echo -e "${BLUE}ใตใใชใผ:${NC}"
|
|
171
|
+
echo " - ๅฎไบใฟในใฏ: ${COMPLETED_COUNT}ไปถ"
|
|
172
|
+
echo " - ๆชๅฎไบใฟในใฏ: ${IN_PROGRESS_COUNT}ไปถ"
|
|
173
|
+
echo " - ๆฌกๅๅใใกใข: ${NOTES_COUNT}้
็ฎ"
|
|
174
|
+
echo ""
|
|
175
|
+
echo -e "${GREEN}ใปใใทใงใณใๆญฃๅธธใซ็ตไบใใพใใใใ็ฒใๆงใงใใ๏ผ${NC}"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# MUSUBIX Session Start Hook
|
|
3
|
+
# REQ-SM-001: SessionStart Hook
|
|
4
|
+
#
|
|
5
|
+
# Usage: source session-start.sh
|
|
6
|
+
# Or run directly: ./session-start.sh
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
# Configuration
|
|
11
|
+
SESSIONS_DIR="${HOME}/.musubix/sessions"
|
|
12
|
+
RETENTION_DAYS=7
|
|
13
|
+
MAX_SESSIONS_TO_SHOW=5
|
|
14
|
+
|
|
15
|
+
# Colors
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
BLUE='\033[0;34m'
|
|
19
|
+
NC='\033[0m' # No Color
|
|
20
|
+
|
|
21
|
+
# Create sessions directory if it doesn't exist
|
|
22
|
+
mkdir -p "$SESSIONS_DIR"
|
|
23
|
+
|
|
24
|
+
echo -e "${BLUE}๐ MUSUBIX Session Manager - Session Start${NC}"
|
|
25
|
+
echo "================================================"
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# Find recent sessions (within RETENTION_DAYS days)
|
|
29
|
+
recent_sessions=$(find "$SESSIONS_DIR" -name "*.md" -mtime -"$RETENTION_DAYS" -type f 2>/dev/null | sort -r | head -"$MAX_SESSIONS_TO_SHOW")
|
|
30
|
+
|
|
31
|
+
if [ -z "$recent_sessions" ]; then
|
|
32
|
+
echo -e "${YELLOW}โน๏ธ ้ๅป${RETENTION_DAYS}ๆฅ้ใฎใปใใทใงใณใฏ่ฆใคใใใพใใใงใใใ${NC}"
|
|
33
|
+
echo ""
|
|
34
|
+
echo "ๆฐใใใปใใทใงใณใ้ๅงใใพใใ"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo -e "${GREEN}โ
้ๅป${RETENTION_DAYS}ๆฅ้ใฎใปใใทใงใณใ่ฆใคใใใพใใ:${NC}"
|
|
39
|
+
echo ""
|
|
40
|
+
|
|
41
|
+
# Process each session
|
|
42
|
+
for session_file in $recent_sessions; do
|
|
43
|
+
filename=$(basename "$session_file")
|
|
44
|
+
date_part="${filename%.md}"
|
|
45
|
+
|
|
46
|
+
# Extract info from session file
|
|
47
|
+
echo -e "${BLUE}๐ $filename${NC}"
|
|
48
|
+
|
|
49
|
+
# Extract Notes for Next Session
|
|
50
|
+
notes=$(sed -n '/^## Notes for Next Session/,/^##/p' "$session_file" 2>/dev/null | grep -v "^##" | head -5)
|
|
51
|
+
if [ -n "$notes" ]; then
|
|
52
|
+
echo " ๐ ๆฌกๅๅใใกใข:"
|
|
53
|
+
echo "$notes" | sed 's/^/ /'
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Extract In Progress tasks
|
|
57
|
+
in_progress=$(sed -n '/^### In Progress/,/^###/p' "$session_file" 2>/dev/null | grep "^\- \[ \]" | head -5)
|
|
58
|
+
if [ -n "$in_progress" ]; then
|
|
59
|
+
echo " โณ ๆชๅฎไบใฟในใฏ:"
|
|
60
|
+
echo "$in_progress" | sed 's/^/ /'
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo ""
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
# Get the most recent session
|
|
67
|
+
most_recent=$(echo "$recent_sessions" | head -1)
|
|
68
|
+
|
|
69
|
+
if [ -n "$most_recent" ]; then
|
|
70
|
+
echo "================================================"
|
|
71
|
+
echo -e "${YELLOW}๐ก ๆๆฐใปใใทใงใณ: $(basename "$most_recent")${NC}"
|
|
72
|
+
echo ""
|
|
73
|
+
echo "ๅๅใฎใปใใทใงใณใใ็ถใใพใใ๏ผ"
|
|
74
|
+
echo " - 'yes' ใพใใฏ 'y' ใงๅๅใฎใณใณใใญในใใ่ชญใฟ่พผใฟ"
|
|
75
|
+
echo " - 'no' ใพใใฏ 'n' ใงๆฐ่ฆใปใใทใงใณ้ๅง"
|
|
76
|
+
echo ""
|
|
77
|
+
|
|
78
|
+
# Extract Context to Load
|
|
79
|
+
context_files=$(sed -n '/^## Context to Load/,/^##/p' "$most_recent" 2>/dev/null | grep -v "^##" | grep -v "^\`\`\`" | grep -v "^$")
|
|
80
|
+
if [ -n "$context_files" ]; then
|
|
81
|
+
echo "๐ ่ชญใฟ่พผใฟๆจๅฅจใใกใคใซ:"
|
|
82
|
+
echo "$context_files" | sed 's/^/ /'
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
echo ""
|
|
87
|
+
echo -e "${GREEN}ใปใใทใงใณ้ๅงใฎๆบๅใๅฎไบใใพใใใ${NC}"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verification-loop
|
|
3
|
+
description: 6ใใงใผใบๆค่จผใซใผใ๏ผBuildโTypeโLintโTestโSecurityโDiff๏ผใงPRใฌใใฃใในใๅคๅฎใ
|
|
4
|
+
license: MIT
|
|
5
|
+
version: 1.1.0
|
|
6
|
+
triggers:
|
|
7
|
+
- /verify
|
|
8
|
+
- /verify quick
|
|
9
|
+
- PRใฌใใฅใผๅ
|
|
10
|
+
- ใปใใทใงใณ็ตไบ
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Verification Loop
|
|
14
|
+
|
|
15
|
+
> **่ฆ็ด**: 6ใใงใผใบใฎ็ทๅๆค่จผใงPRใฌใใฃใในใๅคๅฎใquick/fullใขใผใใจStop Hook็ฃๆปใใตใใผใใ
|
|
16
|
+
|
|
17
|
+
## ๐ /verify ใณใใณใ
|
|
18
|
+
|
|
19
|
+
### Fullๆค่จผ (REQ-VL-001)
|
|
20
|
+
|
|
21
|
+
**WHEN** `/verify` ๅฎ่ก
|
|
22
|
+
**DO** 6ใใงใผใบใ้ ๆฌกๅฎ่ก
|
|
23
|
+
|
|
24
|
+
| # | ใใงใผใบ | ใณใใณใ | ๅคฑๆๆ |
|
|
25
|
+
|---|---------|---------|--------|
|
|
26
|
+
| 1 | **Build** | `npm run build` | ๅณๅๆญขใปไฟฎๆญฃ |
|
|
27
|
+
| 2 | **Type** | `npx tsc --noEmit` | ้ๅคงใจใฉใผไฟฎๆญฃ |
|
|
28
|
+
| 3 | **Lint** | `npm run lint` | ๅ ฑๅ๏ผ--fixๅฏ๏ผ |
|
|
29
|
+
| 4 | **Test** | `npm test` | ๅ ฑๅ |
|
|
30
|
+
| 5 | **Security** | `npm audit` | ๅ ฑๅ |
|
|
31
|
+
| 6 | **Diff** | `git diff --stat` | ใฌใใฅใผ |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### Quickๆค่จผ (REQ-VL-004)
|
|
36
|
+
|
|
37
|
+
**WHEN** `/verify quick` ๅฎ่ก
|
|
38
|
+
**DO** ๆๅฐใปใใใๅฎ่ก
|
|
39
|
+
|
|
40
|
+
- Type Check๏ผๅฏ่ฝใชใ๏ผ
|
|
41
|
+
- Tests๏ผๅทฎๅ้ข้ฃ or `test:unit`๏ผ
|
|
42
|
+
- Diff Review๏ผใตใใชใผใฎใฟ๏ผ
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ๐ Verification Report (REQ-VL-002)
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
50
|
+
โ VERIFICATION REPORT โ
|
|
51
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
|
|
52
|
+
โ Build: [PASS] โ
โ
|
|
53
|
+
โ Types: [PASS] โ
(0 errors) โ
|
|
54
|
+
โ Lint: [PASS] โ ๏ธ (3 warnings) โ
|
|
55
|
+
โ Tests: [PASS] โ
(42/42, 85%) โ
|
|
56
|
+
โ Security: [PASS] โ
(0 critical) โ
|
|
57
|
+
โ Diff: [INFO] ๐ (5 files, +120 -45) โ
|
|
58
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
|
|
59
|
+
โ Overall: [READY] โ
for PR โ
|
|
60
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**NOT READYๆ**:
|
|
64
|
+
```
|
|
65
|
+
Issues to Fix:
|
|
66
|
+
1. src/user.ts:45 - Type error TS2322
|
|
67
|
+
2. tests/api.test.ts - 2 failed tests
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## โฑ๏ธ Continuous Verification (REQ-VL-003)
|
|
73
|
+
|
|
74
|
+
**WHEN** ้ทๆ้ใปใใทใงใณ๏ผ15ๅไปฅไธ๏ผใพใใฏๅคงใใชๅคๆดๅพ
|
|
75
|
+
**DO** ่ชๅๆค่จผใๆๆก
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
๐ก ๆค่จผใๅฎ่กใใพใใ๏ผ
|
|
79
|
+
ๆๅพใฎๆค่จผใใ15ๅ็ต้ใใพใใใ
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## ๐ Stop Hook็ฃๆป (REQ-VL-005)
|
|
85
|
+
|
|
86
|
+
**WHEN** ใปใใทใงใณ็ตไบ
|
|
87
|
+
**DO** ็ทจ้ใใกใคใซใซๅฏพใใฆ็ฃๆป
|
|
88
|
+
|
|
89
|
+
| ใใงใใฏ | ๅฏพ่ฑก | ใขใฏใทใงใณ |
|
|
90
|
+
|---------|------|----------|
|
|
91
|
+
| `console.log` | `.ts`, `.tsx`, `.js` | ่ญฆๅ |
|
|
92
|
+
| `debugger` | `.ts`, `.tsx`, `.js` | ่ญฆๅ |
|
|
93
|
+
| TODO/FIXME | ๅ
จใใกใคใซ | ใชในใๅ |
|
|
94
|
+
| ๆชใณใใใ | Git็ฎก็ | ใณใใใๆๆก |
|
|
95
|
+
|
|
96
|
+
**ๆคๅบใณใใณใ**:
|
|
97
|
+
```bash
|
|
98
|
+
grep -rn "console.log\|debugger" --include="*.ts" --include="*.tsx" src/
|
|
99
|
+
grep -rn "TODO\|FIXME" --include="*.ts" src/
|
|
100
|
+
git status --short
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## ใใฌใผใตใใชใใฃ
|
|
106
|
+
|
|
107
|
+
- REQ-VL-001: Multi-Phase Verification
|
|
108
|
+
- REQ-VL-002: Verification Report
|
|
109
|
+
- REQ-VL-003: Continuous Verification
|
|
110
|
+
- REQ-VL-004: Verification Modes
|
|
111
|
+
- REQ-VL-005: Stop Hook็ฃๆป
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# verify.sh - 6ใใงใผใบๆค่จผในใฏใชใใ
|
|
3
|
+
# Usage: ./verify.sh [quick|full]
|
|
4
|
+
#
|
|
5
|
+
# ใใฌใผใตใใชใใฃ: REQ-VL-001, DES-VL-001
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
MODE="${1:-full}"
|
|
10
|
+
REPORT_FILE=".reports/verification-$(date +%Y%m%d-%H%M%S).md"
|
|
11
|
+
|
|
12
|
+
# ใซใฉใผๅฎ็พฉ
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
BLUE='\033[0;34m'
|
|
17
|
+
NC='\033[0m' # No Color
|
|
18
|
+
|
|
19
|
+
# ็ตๆใๆ ผ็ดใใ้
ๅ
|
|
20
|
+
declare -A RESULTS
|
|
21
|
+
declare -A DETAILS
|
|
22
|
+
|
|
23
|
+
# ใใซใใผ้ขๆฐ
|
|
24
|
+
log_phase() {
|
|
25
|
+
echo -e "\n${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
26
|
+
echo -e "${BLUE}Phase: $1${NC}"
|
|
27
|
+
echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log_pass() {
|
|
31
|
+
echo -e "${GREEN}โ
PASS${NC}: $1"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
log_fail() {
|
|
35
|
+
echo -e "${RED}โ FAIL${NC}: $1"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
log_warn() {
|
|
39
|
+
echo -e "${YELLOW}โ ๏ธ WARN${NC}: $1"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
log_skip() {
|
|
43
|
+
echo -e "${YELLOW}โญ๏ธ SKIP${NC}: $1"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# Phase 1: Build
|
|
47
|
+
phase_build() {
|
|
48
|
+
log_phase "1. Build"
|
|
49
|
+
|
|
50
|
+
if [ "$MODE" = "quick" ]; then
|
|
51
|
+
log_skip "Quick mode - skipping build"
|
|
52
|
+
RESULTS[build]="SKIP"
|
|
53
|
+
return 0
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if npm run build 2>&1; then
|
|
57
|
+
log_pass "Build succeeded"
|
|
58
|
+
RESULTS[build]="PASS"
|
|
59
|
+
return 0
|
|
60
|
+
else
|
|
61
|
+
log_fail "Build failed"
|
|
62
|
+
RESULTS[build]="FAIL"
|
|
63
|
+
return 1
|
|
64
|
+
fi
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Phase 2: Type Check
|
|
68
|
+
phase_types() {
|
|
69
|
+
log_phase "2. Type Check"
|
|
70
|
+
|
|
71
|
+
local output
|
|
72
|
+
output=$(npx tsc --noEmit 2>&1) || true
|
|
73
|
+
local error_count
|
|
74
|
+
error_count=$(echo "$output" | grep -c "error TS" || echo "0")
|
|
75
|
+
|
|
76
|
+
if [ "$error_count" -eq 0 ]; then
|
|
77
|
+
log_pass "No type errors"
|
|
78
|
+
RESULTS[types]="PASS"
|
|
79
|
+
DETAILS[types]="0 errors"
|
|
80
|
+
return 0
|
|
81
|
+
else
|
|
82
|
+
log_fail "$error_count type error(s)"
|
|
83
|
+
RESULTS[types]="FAIL"
|
|
84
|
+
DETAILS[types]="$error_count errors"
|
|
85
|
+
echo "$output" | head -20
|
|
86
|
+
return 1
|
|
87
|
+
fi
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Phase 3: Lint
|
|
91
|
+
phase_lint() {
|
|
92
|
+
log_phase "3. Lint"
|
|
93
|
+
|
|
94
|
+
if [ "$MODE" = "quick" ]; then
|
|
95
|
+
log_skip "Quick mode - skipping lint"
|
|
96
|
+
RESULTS[lint]="SKIP"
|
|
97
|
+
return 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
local output
|
|
101
|
+
output=$(npm run lint 2>&1) || true
|
|
102
|
+
local error_count
|
|
103
|
+
error_count=$(echo "$output" | grep -c "error" || echo "0")
|
|
104
|
+
local warn_count
|
|
105
|
+
warn_count=$(echo "$output" | grep -c "warning" || echo "0")
|
|
106
|
+
|
|
107
|
+
if [ "$error_count" -eq 0 ]; then
|
|
108
|
+
if [ "$warn_count" -gt 0 ]; then
|
|
109
|
+
log_warn "$warn_count warning(s)"
|
|
110
|
+
RESULTS[lint]="PASS"
|
|
111
|
+
DETAILS[lint]="$warn_count warnings"
|
|
112
|
+
else
|
|
113
|
+
log_pass "No lint errors or warnings"
|
|
114
|
+
RESULTS[lint]="PASS"
|
|
115
|
+
DETAILS[lint]="clean"
|
|
116
|
+
fi
|
|
117
|
+
return 0
|
|
118
|
+
else
|
|
119
|
+
log_fail "$error_count error(s), $warn_count warning(s)"
|
|
120
|
+
RESULTS[lint]="FAIL"
|
|
121
|
+
DETAILS[lint]="$error_count errors, $warn_count warnings"
|
|
122
|
+
echo "$output" | head -20
|
|
123
|
+
return 1
|
|
124
|
+
fi
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Phase 4: Tests
|
|
128
|
+
phase_tests() {
|
|
129
|
+
log_phase "4. Tests"
|
|
130
|
+
|
|
131
|
+
local test_cmd="npm run test"
|
|
132
|
+
|
|
133
|
+
if [ "$MODE" = "quick" ]; then
|
|
134
|
+
# Quick mode: ๅคๆดใซ้ข้ฃใใใในใใฎใฟ
|
|
135
|
+
test_cmd="npm run test:unit -- --changed"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
local output
|
|
139
|
+
if output=$($test_cmd 2>&1); then
|
|
140
|
+
local passed
|
|
141
|
+
passed=$(echo "$output" | grep -oP '\d+ passed' | head -1 || echo "? passed")
|
|
142
|
+
log_pass "Tests $passed"
|
|
143
|
+
RESULTS[tests]="PASS"
|
|
144
|
+
DETAILS[tests]="$passed"
|
|
145
|
+
return 0
|
|
146
|
+
else
|
|
147
|
+
log_fail "Some tests failed"
|
|
148
|
+
RESULTS[tests]="FAIL"
|
|
149
|
+
DETAILS[tests]="failed"
|
|
150
|
+
echo "$output" | tail -30
|
|
151
|
+
return 1
|
|
152
|
+
fi
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Phase 5: Security
|
|
156
|
+
phase_security() {
|
|
157
|
+
log_phase "5. Security"
|
|
158
|
+
|
|
159
|
+
if [ "$MODE" = "quick" ]; then
|
|
160
|
+
log_skip "Quick mode - skipping security scan"
|
|
161
|
+
RESULTS[security]="SKIP"
|
|
162
|
+
return 0
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
local output
|
|
166
|
+
output=$(npm audit --json 2>&1) || true
|
|
167
|
+
|
|
168
|
+
local critical
|
|
169
|
+
critical=$(echo "$output" | jq '.metadata.vulnerabilities.critical // 0' 2>/dev/null || echo "0")
|
|
170
|
+
local high
|
|
171
|
+
high=$(echo "$output" | jq '.metadata.vulnerabilities.high // 0' 2>/dev/null || echo "0")
|
|
172
|
+
|
|
173
|
+
if [ "$critical" -eq 0 ] && [ "$high" -eq 0 ]; then
|
|
174
|
+
log_pass "No critical or high vulnerabilities"
|
|
175
|
+
RESULTS[security]="PASS"
|
|
176
|
+
DETAILS[security]="0 critical, 0 high"
|
|
177
|
+
return 0
|
|
178
|
+
else
|
|
179
|
+
log_fail "$critical critical, $high high vulnerabilities"
|
|
180
|
+
RESULTS[security]="FAIL"
|
|
181
|
+
DETAILS[security]="$critical critical, $high high"
|
|
182
|
+
return 1
|
|
183
|
+
fi
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# Phase 6: Diff
|
|
187
|
+
phase_diff() {
|
|
188
|
+
log_phase "6. Diff Review"
|
|
189
|
+
|
|
190
|
+
local stats
|
|
191
|
+
stats=$(git diff --stat HEAD~1..HEAD 2>/dev/null || git diff --stat)
|
|
192
|
+
|
|
193
|
+
local files_changed
|
|
194
|
+
files_changed=$(echo "$stats" | tail -1 | grep -oP '\d+ file' | grep -oP '\d+' || echo "0")
|
|
195
|
+
local insertions
|
|
196
|
+
insertions=$(echo "$stats" | tail -1 | grep -oP '\d+ insertion' | grep -oP '\d+' || echo "0")
|
|
197
|
+
local deletions
|
|
198
|
+
deletions=$(echo "$stats" | tail -1 | grep -oP '\d+ deletion' | grep -oP '\d+' || echo "0")
|
|
199
|
+
|
|
200
|
+
echo "$stats"
|
|
201
|
+
|
|
202
|
+
RESULTS[diff]="INFO"
|
|
203
|
+
DETAILS[diff]="$files_changed files, +$insertions -$deletions"
|
|
204
|
+
|
|
205
|
+
return 0
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# ใฌใใผใ็ๆ
|
|
209
|
+
generate_report() {
|
|
210
|
+
mkdir -p .reports
|
|
211
|
+
|
|
212
|
+
local overall="READY"
|
|
213
|
+
for phase in build types lint tests security; do
|
|
214
|
+
if [ "${RESULTS[$phase]}" = "FAIL" ]; then
|
|
215
|
+
overall="NOT READY"
|
|
216
|
+
break
|
|
217
|
+
fi
|
|
218
|
+
done
|
|
219
|
+
|
|
220
|
+
cat << EOF > "$REPORT_FILE"
|
|
221
|
+
# Verification Report
|
|
222
|
+
|
|
223
|
+
**Date**: $(date +%Y-%m-%d\ %H:%M:%S)
|
|
224
|
+
**Mode**: $MODE
|
|
225
|
+
|
|
226
|
+
## Results
|
|
227
|
+
|
|
228
|
+
| Phase | Status | Details |
|
|
229
|
+
|-------|--------|---------|
|
|
230
|
+
| Build | ${RESULTS[build]:-N/A} | ${DETAILS[build]:-} |
|
|
231
|
+
| Types | ${RESULTS[types]:-N/A} | ${DETAILS[types]:-} |
|
|
232
|
+
| Lint | ${RESULTS[lint]:-N/A} | ${DETAILS[lint]:-} |
|
|
233
|
+
| Tests | ${RESULTS[tests]:-N/A} | ${DETAILS[tests]:-} |
|
|
234
|
+
| Security | ${RESULTS[security]:-N/A} | ${DETAILS[security]:-} |
|
|
235
|
+
| Diff | ${RESULTS[diff]:-N/A} | ${DETAILS[diff]:-} |
|
|
236
|
+
|
|
237
|
+
## Overall
|
|
238
|
+
|
|
239
|
+
**Status**: $overall
|
|
240
|
+
|
|
241
|
+
EOF
|
|
242
|
+
|
|
243
|
+
echo ""
|
|
244
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
245
|
+
echo "โ VERIFICATION REPORT โ"
|
|
246
|
+
echo "โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ"
|
|
247
|
+
echo "โ โ"
|
|
248
|
+
printf "โ Build: [%-4s] %-40s โ\n" "${RESULTS[build]}" ""
|
|
249
|
+
printf "โ Types: [%-4s] %-40s โ\n" "${RESULTS[types]}" "(${DETAILS[types]:-})"
|
|
250
|
+
printf "โ Lint: [%-4s] %-40s โ\n" "${RESULTS[lint]}" "(${DETAILS[lint]:-})"
|
|
251
|
+
printf "โ Tests: [%-4s] %-40s โ\n" "${RESULTS[tests]}" "(${DETAILS[tests]:-})"
|
|
252
|
+
printf "โ Security: [%-4s] %-40s โ\n" "${RESULTS[security]}" "(${DETAILS[security]:-})"
|
|
253
|
+
printf "โ Diff: [%-4s] %-40s โ\n" "${RESULTS[diff]}" "(${DETAILS[diff]:-})"
|
|
254
|
+
echo "โ โ"
|
|
255
|
+
echo "โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ"
|
|
256
|
+
printf "โ Overall: [%-9s] for PR โ\n" "$overall"
|
|
257
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
258
|
+
echo ""
|
|
259
|
+
echo "Report saved to: $REPORT_FILE"
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
# ใกใคใณๅฆ็
|
|
263
|
+
main() {
|
|
264
|
+
echo "Starting verification ($MODE mode)..."
|
|
265
|
+
echo ""
|
|
266
|
+
|
|
267
|
+
local failed=0
|
|
268
|
+
|
|
269
|
+
# Phase 1: Build
|
|
270
|
+
phase_build || failed=1
|
|
271
|
+
|
|
272
|
+
# ใใซใๅคฑๆๆใฏๅพ็ถใใงใผใบใในใญใใ
|
|
273
|
+
if [ "${RESULTS[build]}" = "FAIL" ]; then
|
|
274
|
+
RESULTS[types]="SKIP"
|
|
275
|
+
RESULTS[lint]="SKIP"
|
|
276
|
+
RESULTS[tests]="SKIP"
|
|
277
|
+
RESULTS[security]="SKIP"
|
|
278
|
+
RESULTS[diff]="SKIP"
|
|
279
|
+
else
|
|
280
|
+
# Phase 2: Type Check
|
|
281
|
+
phase_types || failed=1
|
|
282
|
+
|
|
283
|
+
# ๅใจใฉใผๆใฏๅพ็ถใในใญใใ
|
|
284
|
+
if [ "${RESULTS[types]}" = "FAIL" ]; then
|
|
285
|
+
RESULTS[lint]="SKIP"
|
|
286
|
+
RESULTS[tests]="SKIP"
|
|
287
|
+
RESULTS[security]="SKIP"
|
|
288
|
+
else
|
|
289
|
+
# Phase 3-5
|
|
290
|
+
phase_lint || failed=1
|
|
291
|
+
phase_tests || failed=1
|
|
292
|
+
phase_security || failed=1
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# Phase 6: Diff (ๅธธใซๅฎ่ก)
|
|
296
|
+
phase_diff
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
# ใฌใใผใ็ๆ
|
|
300
|
+
generate_report
|
|
301
|
+
|
|
302
|
+
exit $failed
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
main "$@"
|