bigpowers 2.12.0 → 2.12.1

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/.pi/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.12.0",
3
+ "version": "2.12.1",
4
4
  "description": "66 skills — 61 agent skills for spec-driven, test-first software development by solo developers",
5
5
  "keywords": [
6
6
  "pi-package"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [2.12.1](https://github.com/danielvm-git/bigpowers/compare/v2.12.0...v2.12.1) (2026-06-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **skills:** add run-smoke.sh referenced by deploy, smoke-test ([5108891](https://github.com/danielvm-git/bigpowers/commit/51088912084979df38d6bb529297b03a34a6bb66))
7
+
1
8
  # [2.12.0](https://github.com/danielvm-git/bigpowers/compare/v2.11.0...v2.12.0) (2026-06-20)
2
9
 
3
10
 
package/SKILL-INDEX.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > **DO NOT EDIT** — This file is auto-generated by `scripts/generate-skill-index.sh`.
4
4
  > Edit `SKILL.md` source files or `skills-lock.json` instead. Run `bash scripts/sync-skills.sh` to regenerate.
5
5
 
6
- **Generated:** 2026-06-20T21:50:12Z
6
+ **Generated:** 2026-06-20T21:59:15Z
7
7
  **Skills:** 66
8
8
 
9
9
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.12.0",
3
+ "version": "2.12.1",
4
4
  "description": "61 agent skills for spec-driven, test-first software development by solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env bash
2
+ # run-smoke.sh — Post-deploy health-check runner for smoke-test skill
3
+ # Usage: bash scripts/run-smoke.sh [url] [smoke-checks-file]
4
+ #
5
+ # Reads from smoke-checks.yaml by default. Falls back to single-URL check.
6
+ # Env vars: DEPLOY_URL, SMOKE_CHECKS_FILE, SMOKE_TIMEOUT, SMOKE_RETRIES
7
+ set -euo pipefail
8
+
9
+ SMOKE_CHECKS_FILE="${2:-${SMOKE_CHECKS_FILE:-smoke-checks.yaml}}"
10
+ BASE_URL="${1:-${DEPLOY_URL:-}}"
11
+ SMOKE_TIMEOUT="${SMOKE_TIMEOUT:-30}"
12
+ SMOKE_RETRIES="${SMOKE_RETRIES:-0}"
13
+
14
+ TMPDIR=$(mktemp -d)
15
+ trap 'rm -rf "$TMPDIR"' EXIT
16
+
17
+ checks_passed=0
18
+ checks_failed=0
19
+ failures=""
20
+
21
+ # ── 1. Load checks ──────────────────────────────────────────────────────────
22
+
23
+ run_single_url_check() {
24
+ local url="$1"
25
+ local name="${2:-URL check}"
26
+ local expected_status="${3:-200}"
27
+ local content_signal="${4:-}"
28
+
29
+ echo "[$name]"
30
+ start_time=$(python3 -c 'import time; print(int(time.time() * 1000))')
31
+ response=$(curl -s -o "$TMPDIR/body.txt" -w "%{http_code}" --max-time "$SMOKE_TIMEOUT" "$url")
32
+ response_time=$(( $(python3 -c 'import time; print(int(time.time() * 1000))') - start_time ))
33
+ status="$response"
34
+ body=$(cat "$TMPDIR/body.txt" 2>/dev/null || echo "")
35
+
36
+ # Assert status
37
+ if [ "$status" -ne "$expected_status" ]; then
38
+ echo " FAIL: HTTP $status (expected $expected_status)"
39
+ checks_failed=$((checks_failed + 1))
40
+ failures="${failures} - $name: HTTP $status (expected $expected_status)\n"
41
+ else
42
+ echo " PASS: HTTP $status"
43
+ checks_passed=$((checks_passed + 1))
44
+ fi
45
+
46
+ # Assert content signal
47
+ if [ -n "$content_signal" ]; then
48
+ if echo "$body" | grep -qiE "$content_signal"; then
49
+ echo " PASS: body matches \"$content_signal\""
50
+ else
51
+ echo " FAIL: body does not match \"$content_signal\""
52
+ checks_failed=$((checks_failed + 1))
53
+ failures="${failures} - $name: missing content signal \"$content_signal\"\n"
54
+ fi
55
+ fi
56
+
57
+ # Assert response time
58
+ if [ "$response_time" -gt 0 ]; then
59
+ echo " Time: ${response_time}ms"
60
+ fi
61
+ echo ""
62
+ }
63
+
64
+ parse_and_run_checks() {
65
+ local file="$1"
66
+ local base_url=""
67
+ local in_checks=false
68
+ local check_name="" check_path="" check_method="" check_status="" check_signal="" check_time=""
69
+
70
+ while IFS= read -r line; do
71
+ # Strip inline comments
72
+ line="${line%%#*}"
73
+ # Trim whitespace
74
+ line="${line#"${line%%[![:space:]]*}"}"
75
+ line="${line%"${line##*[![:space:]]}"}"
76
+ [ -z "$line" ] && continue
77
+
78
+ if [[ "$line" =~ ^base_url: ]]; then
79
+ base_url="${line#base_url:}"
80
+ base_url="${base_url#"${base_url%%[![:space:]]*}"}"
81
+ base_url="${base_url%"${base_url##*[![:space:]]}"}"
82
+ base_url="${base_url%\"}"
83
+ base_url="${base_url#\"}"
84
+ base_url="${base_url%\'}"
85
+ base_url="${base_url#\'}"
86
+ continue
87
+ fi
88
+
89
+ if [[ "$line" == "checks:" ]]; then
90
+ in_checks=true
91
+ check_name=""; check_path=""; check_method="GET"; check_status="200"
92
+ check_signal=""; check_time=""
93
+ continue
94
+ fi
95
+
96
+ if $in_checks; then
97
+ # Detect new check entry (dash at start of list item)
98
+ if [[ "$line" == "- name:"* ]]; then
99
+ # Run previous check if accumulated
100
+ if [ -n "$check_name" ] && [ -n "$base_url" ]; then
101
+ run_parsed_check "$base_url" "$check_name" "$check_path" "$check_status" "$check_signal"
102
+ fi
103
+ check_name="${line#- name:}"
104
+ check_name="${check_name#"${check_name%%[![:space:]]*}"}"
105
+ check_name="${check_name%\"}"; check_name="${check_name#\"}"
106
+ check_name="${check_name%\'}"; check_name="${check_name#\'}"
107
+ check_path=""; check_method="GET"; check_status="200"; check_signal=""; check_time=""
108
+ elif [[ "$line" == "name:"* ]]; then
109
+ check_name="${line#name:}"
110
+ check_name="${check_name#"${check_name%%[![:space:]]*}"}"
111
+ check_name="${check_name%\"}"; check_name="${check_name#\"}"
112
+ check_name="${check_name%\'}"; check_name="${check_name#\'}"
113
+ elif [[ "$line" == "path:"* ]]; then
114
+ check_path="${line#path:}"
115
+ check_path="${check_path#"${check_path%%[![:space:]]*}"}"
116
+ check_path="${check_path%\"}"; check_path="${check_path#\"}"
117
+ check_path="${check_path%\'}"; check_path="${check_path#\'}"
118
+ elif [[ "$line" == "method:"* ]]; then
119
+ check_method="${line#method:}"
120
+ check_method="${check_method#"${check_method%%[![:space:]]*}"}"
121
+ check_method="${check_method%\"}"; check_method="${check_method#\"}"
122
+ check_method="${check_method%\'}"; check_method="${check_method#\'}"
123
+ elif [[ "$line" == "expected_status:"* ]]; then
124
+ check_status="${line#expected_status:}"
125
+ check_status="${check_status#"${check_status%%[![:space:]]*}"}"
126
+ elif [[ "$line" == "content_signal:"* ]]; then
127
+ check_signal="${line#content_signal:}"
128
+ check_signal="${check_signal#"${check_signal%%[![:space:]]*}"}"
129
+ check_signal="${check_signal%\"}"; check_signal="${check_signal#\"}"
130
+ check_signal="${check_signal%\'}"; check_signal="${check_signal#\'}"
131
+ elif [[ "$line" == "max_response_time_ms:"* ]]; then
132
+ check_time="${line#max_response_time_ms:}"
133
+ check_time="${check_time#"${check_time%%[![:space:]]*}"}"
134
+ fi
135
+ fi
136
+ done < "$file"
137
+
138
+ # Run last check
139
+ if [ -n "$check_name" ] && [ -n "$base_url" ]; then
140
+ run_parsed_check "$base_url" "$check_name" "$check_path" "$check_status" "$check_signal"
141
+ fi
142
+ }
143
+
144
+ run_parsed_check() {
145
+ local base_url="$1" name="$2" path="$3" expected_status="$4" content_signal="$5"
146
+ local url="${base_url}${path}"
147
+
148
+ echo "[$name]"
149
+ echo " URL: $url"
150
+ start_time=$(python3 -c 'import time; print(int(time.time() * 1000))')
151
+ response=$(curl -s -o "$TMPDIR/body.txt" -w "%{http_code}" --max-time "$SMOKE_TIMEOUT" "$url" 2>/dev/null || echo "000")
152
+ response_time=$(( $(python3 -c 'import time; print(int(time.time() * 1000))') - start_time ))
153
+ status="$response"
154
+ body=$(cat "$TMPDIR/body.txt" 2>/dev/null || echo "")
155
+
156
+ # Assert status code
157
+ if [ "$status" -ne "$expected_status" ]; then
158
+ echo " FAIL: HTTP $status (expected $expected_status)"
159
+ checks_failed=$((checks_failed + 1))
160
+ failures="${failures} - $name: HTTP $status (expected $expected_status)\n"
161
+ else
162
+ echo " PASS: HTTP $status"
163
+ fi
164
+
165
+ # Assert content signal
166
+ if [ -n "$content_signal" ]; then
167
+ if echo "$body" | grep -qiE "$content_signal"; then
168
+ echo " PASS: body matches \"$content_signal\""
169
+ checks_passed=$((checks_passed + 1))
170
+ else
171
+ echo " FAIL: body does not match \"$content_signal\""
172
+ checks_failed=$((checks_failed + 1))
173
+ failures="${failures} - $name: missing content signal \"$content_signal\"\n"
174
+ fi
175
+ fi
176
+
177
+ # Assert response time
178
+ if [ -n "${check_time:-}" ] && [ "$check_time" -gt 0 ] 2>/dev/null; then
179
+ if [ "$response_time" -gt "$check_time" ]; then
180
+ echo " FAIL: ${response_time}ms exceeds ${check_time}ms max"
181
+ checks_failed=$((checks_failed + 1))
182
+ failures="${failures} - $name: response time ${response_time}ms (max ${check_time}ms)\n"
183
+ else
184
+ echo " PASS: ${response_time}ms within ${check_time}ms limit"
185
+ fi
186
+ fi
187
+
188
+ if [ "$response_time" -gt 0 ]; then
189
+ echo " Time: ${response_time}ms"
190
+ fi
191
+ echo ""
192
+ }
193
+
194
+ # ── Main dispatch ───────────────────────────────────────────────────────────
195
+
196
+ echo "=== Smoke Test Runner ==="
197
+ echo "Started at: $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
198
+ echo ""
199
+
200
+ if [ -f "$SMOKE_CHECKS_FILE" ]; then
201
+ echo "Checks file: $SMOKE_CHECKS_FILE"
202
+ parse_and_run_checks "$SMOKE_CHECKS_FILE"
203
+ elif [ -n "$BASE_URL" ]; then
204
+ echo "Single URL mode: $BASE_URL"
205
+ run_single_url_check "$BASE_URL" "Baseline"
206
+ else
207
+ echo "ERROR: No smoke-checks.yaml found and no URL provided."
208
+ echo "Usage: bash scripts/run-smoke.sh [url] [smoke-checks-file]"
209
+ echo " DEPLOY_URL=http://example.com bash scripts/run-smoke.sh"
210
+ exit 2
211
+ fi
212
+
213
+ # ── Summary ──────────────────────────────────────────────────────────────────
214
+
215
+ total=$((checks_passed + checks_failed))
216
+ echo "=== Smoke Test Summary ==="
217
+ echo "Total: $total | Passed: $checks_passed | Failed: $checks_failed"
218
+ echo ""
219
+
220
+ if [ "$checks_failed" -gt 0 ]; then
221
+ echo "Failures:"
222
+ echo -e "$failures"
223
+ echo "Smoke test FAILED."
224
+ exit 1
225
+ fi
226
+
227
+ if [ "$total" -eq 0 ]; then
228
+ echo "No checks were executed."
229
+ exit 1
230
+ fi
231
+
232
+ echo "All checks passed."
233
+ exit 0