@boshu2/vibe-check 1.0.2 → 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/.agents/bundles/ml-learning-loop-complete-plan-2025-11-28.md +908 -0
- package/.agents/bundles/unified-vibe-system-plan-phase1-2025-11-28.md +962 -0
- package/.agents/bundles/unified-vibe-system-research-2025-11-28.md +1003 -0
- package/.agents/bundles/vibe-check-ecosystem-plan-2025-11-29.md +635 -0
- package/.agents/bundles/vibe-check-gamification-complete-2025-11-29.md +132 -0
- package/.agents/bundles/vibe-score-scientific-framework-2025-11-28.md +602 -0
- package/.vibe-check/calibration.json +38 -0
- package/.vibe-check/latest.json +114 -0
- package/CHANGELOG.md +47 -0
- package/CLAUDE.md +178 -0
- package/README.md +222 -7
- package/action.yml +270 -0
- package/dashboard/app.js +494 -0
- package/dashboard/index.html +235 -0
- package/dashboard/styles.css +647 -0
- package/dist/calibration/ece.d.ts +26 -0
- package/dist/calibration/ece.d.ts.map +1 -0
- package/dist/calibration/ece.js +93 -0
- package/dist/calibration/ece.js.map +1 -0
- package/dist/calibration/index.d.ts +3 -0
- package/dist/calibration/index.d.ts.map +1 -0
- package/dist/calibration/index.js +15 -0
- package/dist/calibration/index.js.map +1 -0
- package/dist/calibration/storage.d.ts +34 -0
- package/dist/calibration/storage.d.ts.map +1 -0
- package/dist/calibration/storage.js +188 -0
- package/dist/calibration/storage.js.map +1 -0
- package/dist/cli.js +31 -76
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +16 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +256 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init-hook.d.ts +3 -0
- package/dist/commands/init-hook.d.ts.map +1 -0
- package/dist/commands/init-hook.js +161 -0
- package/dist/commands/init-hook.js.map +1 -0
- package/dist/commands/level.d.ts +3 -0
- package/dist/commands/level.d.ts.map +1 -0
- package/dist/commands/level.js +277 -0
- package/dist/commands/level.js.map +1 -0
- package/dist/commands/profile.d.ts +4 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +143 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/gamification/achievements.d.ts +15 -0
- package/dist/gamification/achievements.d.ts.map +1 -0
- package/dist/gamification/achievements.js +273 -0
- package/dist/gamification/achievements.js.map +1 -0
- package/dist/gamification/index.d.ts +8 -0
- package/dist/gamification/index.d.ts.map +1 -0
- package/dist/gamification/index.js +30 -0
- package/dist/gamification/index.js.map +1 -0
- package/dist/gamification/profile.d.ts +46 -0
- package/dist/gamification/profile.d.ts.map +1 -0
- package/dist/gamification/profile.js +272 -0
- package/dist/gamification/profile.js.map +1 -0
- package/dist/gamification/streaks.d.ts +26 -0
- package/dist/gamification/streaks.d.ts.map +1 -0
- package/dist/gamification/streaks.js +132 -0
- package/dist/gamification/streaks.js.map +1 -0
- package/dist/gamification/types.d.ts +111 -0
- package/dist/gamification/types.d.ts.map +1 -0
- package/dist/gamification/types.js +26 -0
- package/dist/gamification/types.js.map +1 -0
- package/dist/gamification/xp.d.ts +37 -0
- package/dist/gamification/xp.d.ts.map +1 -0
- package/dist/gamification/xp.js +115 -0
- package/dist/gamification/xp.js.map +1 -0
- package/dist/git.d.ts +11 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +52 -0
- package/dist/git.js.map +1 -1
- package/dist/metrics/code-stability.d.ts +13 -0
- package/dist/metrics/code-stability.d.ts.map +1 -0
- package/dist/metrics/code-stability.js +74 -0
- package/dist/metrics/code-stability.js.map +1 -0
- package/dist/metrics/file-churn.d.ts +8 -0
- package/dist/metrics/file-churn.d.ts.map +1 -0
- package/dist/metrics/file-churn.js +75 -0
- package/dist/metrics/file-churn.js.map +1 -0
- package/dist/metrics/time-spiral.d.ts +8 -0
- package/dist/metrics/time-spiral.d.ts.map +1 -0
- package/dist/metrics/time-spiral.js +69 -0
- package/dist/metrics/time-spiral.js.map +1 -0
- package/dist/metrics/velocity-anomaly.d.ts +13 -0
- package/dist/metrics/velocity-anomaly.d.ts.map +1 -0
- package/dist/metrics/velocity-anomaly.js +67 -0
- package/dist/metrics/velocity-anomaly.js.map +1 -0
- package/dist/output/index.d.ts +6 -3
- package/dist/output/index.d.ts.map +1 -1
- package/dist/output/index.js +4 -3
- package/dist/output/index.js.map +1 -1
- package/dist/output/json.d.ts +2 -2
- package/dist/output/json.d.ts.map +1 -1
- package/dist/output/json.js +54 -0
- package/dist/output/json.js.map +1 -1
- package/dist/output/markdown.d.ts +2 -2
- package/dist/output/markdown.d.ts.map +1 -1
- package/dist/output/markdown.js +34 -1
- package/dist/output/markdown.js.map +1 -1
- package/dist/output/terminal.d.ts +6 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +131 -3
- package/dist/output/terminal.js.map +1 -1
- package/dist/recommend/index.d.ts +3 -0
- package/dist/recommend/index.d.ts.map +1 -0
- package/dist/recommend/index.js +14 -0
- package/dist/recommend/index.js.map +1 -0
- package/dist/recommend/ordered-logistic.d.ts +49 -0
- package/dist/recommend/ordered-logistic.d.ts.map +1 -0
- package/dist/recommend/ordered-logistic.js +153 -0
- package/dist/recommend/ordered-logistic.js.map +1 -0
- package/dist/recommend/questions.d.ts +19 -0
- package/dist/recommend/questions.d.ts.map +1 -0
- package/dist/recommend/questions.js +73 -0
- package/dist/recommend/questions.js.map +1 -0
- package/dist/score/index.d.ts +21 -0
- package/dist/score/index.d.ts.map +1 -0
- package/dist/score/index.js +48 -0
- package/dist/score/index.js.map +1 -0
- package/dist/score/weights.d.ts +16 -0
- package/dist/score/weights.d.ts.map +1 -0
- package/dist/score/weights.js +28 -0
- package/dist/score/weights.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -1
- package/hooks/pre-push +103 -0
- package/package.json +10 -9
package/action.yml
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
name: 'Vibe Check'
|
|
2
|
+
description: 'Analyze git commit patterns and post vibe coding metrics to PR comments'
|
|
3
|
+
author: 'boshu2'
|
|
4
|
+
branding:
|
|
5
|
+
icon: 'activity'
|
|
6
|
+
color: 'purple'
|
|
7
|
+
|
|
8
|
+
inputs:
|
|
9
|
+
github-token:
|
|
10
|
+
description: 'GitHub token for posting PR comments'
|
|
11
|
+
required: true
|
|
12
|
+
default: ${{ github.token }}
|
|
13
|
+
since:
|
|
14
|
+
description: 'Start date for analysis (e.g., "1 week ago", or leave empty for PR commits only)'
|
|
15
|
+
required: false
|
|
16
|
+
default: ''
|
|
17
|
+
threshold:
|
|
18
|
+
description: 'Minimum overall rating to pass (elite, solid, needs-work, struggling)'
|
|
19
|
+
required: false
|
|
20
|
+
default: ''
|
|
21
|
+
include-score:
|
|
22
|
+
description: 'Include VibeScore in output'
|
|
23
|
+
required: false
|
|
24
|
+
default: 'true'
|
|
25
|
+
include-recommendation:
|
|
26
|
+
description: 'Include level recommendation in output'
|
|
27
|
+
required: false
|
|
28
|
+
default: 'true'
|
|
29
|
+
output-file:
|
|
30
|
+
description: 'Path to write JSON results (optional)'
|
|
31
|
+
required: false
|
|
32
|
+
default: ''
|
|
33
|
+
comment-on-pr:
|
|
34
|
+
description: 'Post results as PR comment'
|
|
35
|
+
required: false
|
|
36
|
+
default: 'true'
|
|
37
|
+
|
|
38
|
+
outputs:
|
|
39
|
+
overall:
|
|
40
|
+
description: 'Overall rating (elite, solid, needs-work, struggling)'
|
|
41
|
+
value: ${{ steps.vibe-check.outputs.overall }}
|
|
42
|
+
vibe-score:
|
|
43
|
+
description: 'Numeric vibe score (0-100)'
|
|
44
|
+
value: ${{ steps.vibe-check.outputs.vibe-score }}
|
|
45
|
+
json:
|
|
46
|
+
description: 'Full JSON results'
|
|
47
|
+
value: ${{ steps.vibe-check.outputs.json }}
|
|
48
|
+
|
|
49
|
+
runs:
|
|
50
|
+
using: 'composite'
|
|
51
|
+
steps:
|
|
52
|
+
- name: Setup Node.js
|
|
53
|
+
uses: actions/setup-node@v4
|
|
54
|
+
with:
|
|
55
|
+
node-version: '20'
|
|
56
|
+
|
|
57
|
+
- name: Install vibe-check
|
|
58
|
+
shell: bash
|
|
59
|
+
run: npm install -g @boshu2/vibe-check
|
|
60
|
+
|
|
61
|
+
- name: Fetch full git history
|
|
62
|
+
shell: bash
|
|
63
|
+
run: |
|
|
64
|
+
git fetch --unshallow 2>/dev/null || true
|
|
65
|
+
git fetch origin ${{ github.base_ref }} 2>/dev/null || true
|
|
66
|
+
|
|
67
|
+
- name: Run vibe-check
|
|
68
|
+
id: vibe-check
|
|
69
|
+
shell: bash
|
|
70
|
+
env:
|
|
71
|
+
GITHUB_TOKEN: ${{ inputs.github-token }}
|
|
72
|
+
run: |
|
|
73
|
+
# Determine the date range
|
|
74
|
+
if [ -n "${{ inputs.since }}" ]; then
|
|
75
|
+
SINCE_ARG="--since \"${{ inputs.since }}\""
|
|
76
|
+
elif [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
77
|
+
# For PRs, analyze commits since the base branch
|
|
78
|
+
BASE_SHA=$(git merge-base origin/${{ github.base_ref }} HEAD 2>/dev/null || echo "")
|
|
79
|
+
if [ -n "$BASE_SHA" ]; then
|
|
80
|
+
BASE_DATE=$(git show -s --format=%ci $BASE_SHA)
|
|
81
|
+
SINCE_ARG="--since \"$BASE_DATE\""
|
|
82
|
+
else
|
|
83
|
+
SINCE_ARG="--since \"1 week ago\""
|
|
84
|
+
fi
|
|
85
|
+
else
|
|
86
|
+
SINCE_ARG="--since \"1 week ago\""
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Build command
|
|
90
|
+
CMD="vibe-check"
|
|
91
|
+
[ "${{ inputs.include-score }}" = "true" ] && CMD="$CMD --score"
|
|
92
|
+
[ "${{ inputs.include-recommendation }}" = "true" ] && CMD="$CMD --recommend"
|
|
93
|
+
|
|
94
|
+
# Run with JSON output
|
|
95
|
+
echo "Running: $CMD $SINCE_ARG --format json"
|
|
96
|
+
RESULT=$(eval "$CMD $SINCE_ARG --format json" 2>&1) || true
|
|
97
|
+
|
|
98
|
+
# Parse results
|
|
99
|
+
if echo "$RESULT" | jq . > /dev/null 2>&1; then
|
|
100
|
+
OVERALL=$(echo "$RESULT" | jq -r '.overall')
|
|
101
|
+
VIBE_SCORE=$(echo "$RESULT" | jq -r '.vibeScore // "N/A"')
|
|
102
|
+
|
|
103
|
+
echo "overall=$OVERALL" >> $GITHUB_OUTPUT
|
|
104
|
+
echo "vibe-score=$VIBE_SCORE" >> $GITHUB_OUTPUT
|
|
105
|
+
|
|
106
|
+
# Save JSON (escape for multiline)
|
|
107
|
+
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
|
108
|
+
echo "json<<$EOF" >> $GITHUB_OUTPUT
|
|
109
|
+
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
110
|
+
echo "$EOF" >> $GITHUB_OUTPUT
|
|
111
|
+
|
|
112
|
+
# Write to file if requested
|
|
113
|
+
if [ -n "${{ inputs.output-file }}" ]; then
|
|
114
|
+
echo "$RESULT" > "${{ inputs.output-file }}"
|
|
115
|
+
echo "Results written to ${{ inputs.output-file }}"
|
|
116
|
+
fi
|
|
117
|
+
else
|
|
118
|
+
echo "overall=error" >> $GITHUB_OUTPUT
|
|
119
|
+
echo "vibe-score=0" >> $GITHUB_OUTPUT
|
|
120
|
+
echo "json={\"error\": \"Failed to parse vibe-check output\"}" >> $GITHUB_OUTPUT
|
|
121
|
+
echo "::warning::vibe-check output was not valid JSON: $RESULT"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
- name: Generate markdown comment
|
|
125
|
+
id: markdown
|
|
126
|
+
if: inputs.comment-on-pr == 'true' && github.event_name == 'pull_request'
|
|
127
|
+
shell: bash
|
|
128
|
+
run: |
|
|
129
|
+
JSON='${{ steps.vibe-check.outputs.json }}'
|
|
130
|
+
|
|
131
|
+
# Parse metrics
|
|
132
|
+
OVERALL=$(echo "$JSON" | jq -r '.overall')
|
|
133
|
+
COMMITS=$(echo "$JSON" | jq -r '.commits')
|
|
134
|
+
VIBE_SCORE=$(echo "$JSON" | jq -r '.vibeScore // "N/A"')
|
|
135
|
+
|
|
136
|
+
# Get individual metrics
|
|
137
|
+
VELOCITY=$(echo "$JSON" | jq -r '.metrics.iterationVelocity.value')
|
|
138
|
+
VELOCITY_RATING=$(echo "$JSON" | jq -r '.metrics.iterationVelocity.rating')
|
|
139
|
+
REWORK=$(echo "$JSON" | jq -r '.metrics.reworkRatio.value')
|
|
140
|
+
REWORK_RATING=$(echo "$JSON" | jq -r '.metrics.reworkRatio.rating')
|
|
141
|
+
TRUST=$(echo "$JSON" | jq -r '.metrics.trustPassRate.value')
|
|
142
|
+
TRUST_RATING=$(echo "$JSON" | jq -r '.metrics.trustPassRate.rating')
|
|
143
|
+
SPIRAL=$(echo "$JSON" | jq -r '.metrics.debugSpiralDuration.value')
|
|
144
|
+
SPIRAL_RATING=$(echo "$JSON" | jq -r '.metrics.debugSpiralDuration.rating')
|
|
145
|
+
FLOW=$(echo "$JSON" | jq -r '.metrics.flowEfficiency.value')
|
|
146
|
+
FLOW_RATING=$(echo "$JSON" | jq -r '.metrics.flowEfficiency.rating')
|
|
147
|
+
|
|
148
|
+
# Map ratings to emoji
|
|
149
|
+
rating_emoji() {
|
|
150
|
+
case "$1" in
|
|
151
|
+
elite) echo "🟢" ;;
|
|
152
|
+
solid) echo "🔵" ;;
|
|
153
|
+
needs-work) echo "🟡" ;;
|
|
154
|
+
struggling) echo "🔴" ;;
|
|
155
|
+
*) echo "⚪" ;;
|
|
156
|
+
esac
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Overall emoji
|
|
160
|
+
case "$OVERALL" in
|
|
161
|
+
elite) OVERALL_EMOJI="🚀" ;;
|
|
162
|
+
solid) OVERALL_EMOJI="✅" ;;
|
|
163
|
+
needs-work) OVERALL_EMOJI="⚠️" ;;
|
|
164
|
+
struggling) OVERALL_EMOJI="🔴" ;;
|
|
165
|
+
*) OVERALL_EMOJI="❓" ;;
|
|
166
|
+
esac
|
|
167
|
+
|
|
168
|
+
# Build comment
|
|
169
|
+
COMMENT="## $OVERALL_EMOJI Vibe Check: **${OVERALL^^}**
|
|
170
|
+
|
|
171
|
+
**Commits analyzed:** $COMMITS"
|
|
172
|
+
|
|
173
|
+
[ "$VIBE_SCORE" != "N/A" ] && [ "$VIBE_SCORE" != "null" ] && COMMENT="$COMMENT | **VibeScore:** $VIBE_SCORE/100"
|
|
174
|
+
|
|
175
|
+
COMMENT="$COMMENT
|
|
176
|
+
|
|
177
|
+
| Metric | Value | Rating |
|
|
178
|
+
|--------|-------|--------|
|
|
179
|
+
| Iteration Velocity | ${VELOCITY}/hr | $(rating_emoji $VELOCITY_RATING) $VELOCITY_RATING |
|
|
180
|
+
| Rework Ratio | ${REWORK}% | $(rating_emoji $REWORK_RATING) $REWORK_RATING |
|
|
181
|
+
| Trust Pass Rate | ${TRUST}% | $(rating_emoji $TRUST_RATING) $TRUST_RATING |
|
|
182
|
+
| Debug Spiral Duration | ${SPIRAL}m | $(rating_emoji $SPIRAL_RATING) $SPIRAL_RATING |
|
|
183
|
+
| Flow Efficiency | ${FLOW}% | $(rating_emoji $FLOW_RATING) $FLOW_RATING |
|
|
184
|
+
|
|
185
|
+
<details>
|
|
186
|
+
<summary>What do these metrics mean?</summary>
|
|
187
|
+
|
|
188
|
+
- **Iteration Velocity**: Commits per active hour (higher = faster iteration)
|
|
189
|
+
- **Rework Ratio**: Percentage of commits that are fixes (lower = cleaner first attempts)
|
|
190
|
+
- **Trust Pass Rate**: Commits without immediate follow-up fixes (higher = more reliable)
|
|
191
|
+
- **Debug Spiral Duration**: Average time stuck in fix chains (lower = faster recovery)
|
|
192
|
+
- **Flow Efficiency**: Time building vs debugging (higher = more productive)
|
|
193
|
+
|
|
194
|
+
</details>
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
*Generated by [vibe-check](https://github.com/boshu2/vibe-check)*"
|
|
198
|
+
|
|
199
|
+
# Save comment for next step
|
|
200
|
+
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
|
201
|
+
echo "comment<<$EOF" >> $GITHUB_OUTPUT
|
|
202
|
+
echo "$COMMENT" >> $GITHUB_OUTPUT
|
|
203
|
+
echo "$EOF" >> $GITHUB_OUTPUT
|
|
204
|
+
|
|
205
|
+
- name: Post PR comment
|
|
206
|
+
if: inputs.comment-on-pr == 'true' && github.event_name == 'pull_request'
|
|
207
|
+
uses: actions/github-script@v7
|
|
208
|
+
with:
|
|
209
|
+
github-token: ${{ inputs.github-token }}
|
|
210
|
+
script: |
|
|
211
|
+
const comment = `${{ steps.markdown.outputs.comment }}`;
|
|
212
|
+
|
|
213
|
+
// Find existing vibe-check comment
|
|
214
|
+
const { data: comments } = await github.rest.issues.listComments({
|
|
215
|
+
owner: context.repo.owner,
|
|
216
|
+
repo: context.repo.repo,
|
|
217
|
+
issue_number: context.issue.number,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const existingComment = comments.find(c =>
|
|
221
|
+
c.body.includes('Generated by [vibe-check]')
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
if (existingComment) {
|
|
225
|
+
// Update existing comment
|
|
226
|
+
await github.rest.issues.updateComment({
|
|
227
|
+
owner: context.repo.owner,
|
|
228
|
+
repo: context.repo.repo,
|
|
229
|
+
comment_id: existingComment.id,
|
|
230
|
+
body: comment
|
|
231
|
+
});
|
|
232
|
+
console.log('Updated existing vibe-check comment');
|
|
233
|
+
} else {
|
|
234
|
+
// Create new comment
|
|
235
|
+
await github.rest.issues.createComment({
|
|
236
|
+
owner: context.repo.owner,
|
|
237
|
+
repo: context.repo.repo,
|
|
238
|
+
issue_number: context.issue.number,
|
|
239
|
+
body: comment
|
|
240
|
+
});
|
|
241
|
+
console.log('Created new vibe-check comment');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
- name: Check threshold
|
|
245
|
+
if: inputs.threshold != ''
|
|
246
|
+
shell: bash
|
|
247
|
+
run: |
|
|
248
|
+
OVERALL="${{ steps.vibe-check.outputs.overall }}"
|
|
249
|
+
THRESHOLD="${{ inputs.threshold }}"
|
|
250
|
+
|
|
251
|
+
# Rating order (higher = better)
|
|
252
|
+
rating_to_num() {
|
|
253
|
+
case "$1" in
|
|
254
|
+
elite) echo 4 ;;
|
|
255
|
+
solid) echo 3 ;;
|
|
256
|
+
needs-work) echo 2 ;;
|
|
257
|
+
struggling) echo 1 ;;
|
|
258
|
+
*) echo 0 ;;
|
|
259
|
+
esac
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
ACTUAL=$(rating_to_num "$OVERALL")
|
|
263
|
+
REQUIRED=$(rating_to_num "$THRESHOLD")
|
|
264
|
+
|
|
265
|
+
if [ "$ACTUAL" -lt "$REQUIRED" ]; then
|
|
266
|
+
echo "::error::Vibe check failed: $OVERALL is below threshold $THRESHOLD"
|
|
267
|
+
exit 1
|
|
268
|
+
else
|
|
269
|
+
echo "Vibe check passed: $OVERALL meets threshold $THRESHOLD"
|
|
270
|
+
fi
|