bigpowers 2.34.0 → 2.34.2
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 +2 -2
- package/.pi/prompts/deploy.md +53 -28
- package/.pi/prompts/develop-tdd.md +5 -80
- package/.pi/prompts/migrate-spec.md +273 -197
- package/.pi/prompts/publish-package.md +125 -67
- package/.pi/prompts/release-branch.md +85 -69
- package/.pi/prompts/smoke-test.md +98 -58
- package/.pi/prompts/using-bigpowers.md +2 -2
- package/.pi/prompts/validate-contracts.md +169 -54
- package/.pi/prompts/wire-ci.md +147 -89
- package/.pi/skills/deploy/SKILL.md +53 -28
- package/.pi/skills/develop-tdd/SKILL.md +5 -80
- package/.pi/skills/migrate-spec/SKILL.md +273 -197
- package/.pi/skills/publish-package/SKILL.md +125 -67
- package/.pi/skills/release-branch/SKILL.md +85 -69
- package/.pi/skills/smoke-test/SKILL.md +98 -58
- package/.pi/skills/using-bigpowers/SKILL.md +2 -2
- package/.pi/skills/validate-contracts/SKILL.md +169 -54
- package/.pi/skills/wire-ci/SKILL.md +147 -89
- package/CHANGELOG.md +14 -0
- package/README.md +4 -4
- package/SKILL-INDEX.md +1 -1
- package/deploy/REFERENCE.md +82 -0
- package/deploy/SKILL.md +3 -63
- package/develop-tdd/SKILL.md +5 -80
- package/migrate-spec/REFERENCE.md +268 -0
- package/migrate-spec/SKILL.md +5 -199
- package/package.json +4 -3
- package/publish-package/REFERENCE.md +239 -0
- package/publish-package/SKILL.md +8 -192
- package/release-branch/REFERENCE.md +83 -0
- package/release-branch/SKILL.md +2 -69
- package/scripts/generate-reference-tables.sh +1 -0
- package/scripts/sync-skills.sh +4 -1
- package/skills-lock.json +9 -9
- package/smoke-test/REFERENCE.md +162 -0
- package/smoke-test/SKILL.md +5 -130
- package/using-bigpowers/SKILL.md +2 -2
- package/validate-contracts/REFERENCE.md +183 -0
- package/validate-contracts/SKILL.md +6 -77
- package/wire-ci/REFERENCE.md +257 -0
- package/wire-ci/SKILL.md +8 -210
|
@@ -34,6 +34,112 @@ If no manifest is found, prompt the user to specify the type or pass `--type <np
|
|
|
34
34
|
Before attempting any publish, run all applicable checks:
|
|
35
35
|
|
|
36
36
|
**npm (`package.json`):**
|
|
37
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
38
|
+
|
|
39
|
+
**crates.io (`Cargo.toml`):**
|
|
40
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
41
|
+
|
|
42
|
+
**PyPI (`setup.py` / `pyproject.toml`):**
|
|
43
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
44
|
+
|
|
45
|
+
### 3. Run publish
|
|
46
|
+
|
|
47
|
+
After all prerequisite checks pass, run the registry-specific command:
|
|
48
|
+
|
|
49
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
50
|
+
|
|
51
|
+
### 4. Verify publish success
|
|
52
|
+
|
|
53
|
+
After publish, confirm the version appears on the registry:
|
|
54
|
+
|
|
55
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
56
|
+
|
|
57
|
+
### 5. Error handling
|
|
58
|
+
|
|
59
|
+
On failure, surface actionable hints:
|
|
60
|
+
|
|
61
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
62
|
+
|
|
63
|
+
### 6. Dry-run mode (`--dry-run`)
|
|
64
|
+
|
|
65
|
+
Run `--dry-run` to verify all prerequisites without actually publishing:
|
|
66
|
+
|
|
67
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
68
|
+
|
|
69
|
+
### 7. Dry-run mode per registry
|
|
70
|
+
|
|
71
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
72
|
+
|
|
73
|
+
## Verify
|
|
74
|
+
|
|
75
|
+
→ verify: `test -f publish-package/SKILL.md && echo "OK: skill file exists" || echo "FAIL: no skill file"`
|
|
76
|
+
→ verify: `grep -q "name: publish-package" publish-package/SKILL.md && echo "OK: frontmatter" || echo "FAIL: frontmatter"`
|
|
77
|
+
→ verify: `grep -ci "npm\|crates.io\|pypi\|publish\|registry" publish-package/SKILL.md | awk '{if($1>=4) print "OK: semantics"; else print "FAIL: missing"}'`
|
|
78
|
+
→ verify: `grep -q "publish-package" SKILL-INDEX.md && echo "OK: in SKILL-INDEX" || echo "FAIL: not indexed"`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
# Publish Package — Reference
|
|
83
|
+
|
|
84
|
+
## Options
|
|
85
|
+
|
|
86
|
+
| Flag | Description |
|
|
87
|
+
|------|-------------|
|
|
88
|
+
| `--dry-run` | Verify prerequisites and show publish command without executing |
|
|
89
|
+
| `--registry <type>` | Force registry type (skip auto-detection) |
|
|
90
|
+
| `--otp <code>` | One-time password for npm 2FA |
|
|
91
|
+
| `--no-verify` | Skip prerequisite checks (use with caution) |
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Examples
|
|
97
|
+
|
|
98
|
+
### Publish an npm package
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Verify first
|
|
102
|
+
publish-package --dry-run
|
|
103
|
+
|
|
104
|
+
# Publish
|
|
105
|
+
publish-package
|
|
106
|
+
|
|
107
|
+
# Output:
|
|
108
|
+
# [npm] Publishing my-package v0.4.0...
|
|
109
|
+
# OK: npm publish confirmed (my-package@0.4.0 on registry)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Publish a Rust crate
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
export CARGO_REGISTRY_TOKEN=<token>
|
|
116
|
+
publish-package --dry-run
|
|
117
|
+
publish-package
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Missing token scenario
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
$ publish-package
|
|
124
|
+
FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add to .npmrc
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Integration with release-branch
|
|
131
|
+
|
|
132
|
+
When wired into `release-branch`, add a step after git push:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
6a. Run publish-package to publish to package registries
|
|
136
|
+
→ verify: publish-package --dry-run && publish-package
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Reference block 1
|
|
142
|
+
|
|
37
143
|
```bash
|
|
38
144
|
# Check auth token exists
|
|
39
145
|
if [ -z "${NPM_TOKEN:-}" ]; then
|
|
@@ -71,7 +177,10 @@ if [ -f CHANGELOG.md ]; then
|
|
|
71
177
|
fi
|
|
72
178
|
```
|
|
73
179
|
|
|
74
|
-
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Reference block 2
|
|
183
|
+
|
|
75
184
|
```bash
|
|
76
185
|
# Check auth token exists
|
|
77
186
|
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
|
|
@@ -90,7 +199,10 @@ if cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_
|
|
|
90
199
|
fi
|
|
91
200
|
```
|
|
92
201
|
|
|
93
|
-
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Reference block 3
|
|
205
|
+
|
|
94
206
|
```bash
|
|
95
207
|
# Check auth token exists
|
|
96
208
|
if [ -z "${TWINE_PASSWORD:-}" ] && [ -z "${POETRY_PYPI_TOKEN_PYPI:-}" ]; then
|
|
@@ -106,9 +218,9 @@ if [ ! -d dist ] || [ -z "$(ls dist/*.whl 2>/dev/null)" ]; then
|
|
|
106
218
|
fi
|
|
107
219
|
```
|
|
108
220
|
|
|
109
|
-
|
|
221
|
+
---
|
|
110
222
|
|
|
111
|
-
|
|
223
|
+
## Reference block 4
|
|
112
224
|
|
|
113
225
|
```bash
|
|
114
226
|
# npm
|
|
@@ -124,9 +236,9 @@ python -m twine upload dist/* # or: poetry publish
|
|
|
124
236
|
brew bump-formula-pr --url=<tarball-url> <formula-name>
|
|
125
237
|
```
|
|
126
238
|
|
|
127
|
-
|
|
239
|
+
---
|
|
128
240
|
|
|
129
|
-
|
|
241
|
+
## Reference block 5
|
|
130
242
|
|
|
131
243
|
```bash
|
|
132
244
|
# npm
|
|
@@ -139,9 +251,9 @@ cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER
|
|
|
139
251
|
pip index versions "$PACKAGE_NAME" 2>/dev/null | grep -q "$CURRENT_VER" && echo "OK: PyPI publish confirmed"
|
|
140
252
|
```
|
|
141
253
|
|
|
142
|
-
|
|
254
|
+
---
|
|
143
255
|
|
|
144
|
-
|
|
256
|
+
## Reference block 6
|
|
145
257
|
|
|
146
258
|
```bash
|
|
147
259
|
# Generic failure handler
|
|
@@ -174,9 +286,9 @@ if [ $? -ne 0 ]; then
|
|
|
174
286
|
fi
|
|
175
287
|
```
|
|
176
288
|
|
|
177
|
-
|
|
289
|
+
---
|
|
178
290
|
|
|
179
|
-
|
|
291
|
+
## Reference block 7
|
|
180
292
|
|
|
181
293
|
```bash
|
|
182
294
|
# Example output
|
|
@@ -192,7 +304,9 @@ $ publish-package --dry-run
|
|
|
192
304
|
[DRY-RUN] Exiting without publishing.
|
|
193
305
|
```
|
|
194
306
|
|
|
195
|
-
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Reference block 8
|
|
196
310
|
|
|
197
311
|
```bash
|
|
198
312
|
# npm dry-run
|
|
@@ -204,59 +318,3 @@ cargo package --list 2>/dev/null
|
|
|
204
318
|
# PyPI dry-run
|
|
205
319
|
python -m twine upload --repository testpypi dist/* # test.pypi.org
|
|
206
320
|
```
|
|
207
|
-
|
|
208
|
-
## Options
|
|
209
|
-
|
|
210
|
-
| Flag | Description |
|
|
211
|
-
|------|-------------|
|
|
212
|
-
| `--dry-run` | Verify prerequisites and show publish command without executing |
|
|
213
|
-
| `--registry <type>` | Force registry type (skip auto-detection) |
|
|
214
|
-
| `--otp <code>` | One-time password for npm 2FA |
|
|
215
|
-
| `--no-verify` | Skip prerequisite checks (use with caution) |
|
|
216
|
-
|
|
217
|
-
## Examples
|
|
218
|
-
|
|
219
|
-
### Publish an npm package
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
# Verify first
|
|
223
|
-
publish-package --dry-run
|
|
224
|
-
|
|
225
|
-
# Publish
|
|
226
|
-
publish-package
|
|
227
|
-
|
|
228
|
-
# Output:
|
|
229
|
-
# [npm] Publishing my-package v0.4.0...
|
|
230
|
-
# OK: npm publish confirmed (my-package@0.4.0 on registry)
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Publish a Rust crate
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
export CARGO_REGISTRY_TOKEN=<token>
|
|
237
|
-
publish-package --dry-run
|
|
238
|
-
publish-package
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Missing token scenario
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
$ publish-package
|
|
245
|
-
FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add to .npmrc
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Integration with release-branch
|
|
249
|
-
|
|
250
|
-
When wired into `release-branch`, add a step after git push:
|
|
251
|
-
|
|
252
|
-
```
|
|
253
|
-
6a. Run publish-package to publish to package registries
|
|
254
|
-
→ verify: publish-package --dry-run && publish-package
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## Verify
|
|
258
|
-
|
|
259
|
-
→ verify: `test -f publish-package/SKILL.md && echo "OK: skill file exists" || echo "FAIL: no skill file"`
|
|
260
|
-
→ verify: `grep -q "name: publish-package" publish-package/SKILL.md && echo "OK: frontmatter" || echo "FAIL: frontmatter"`
|
|
261
|
-
→ verify: `grep -ci "npm\|crates.io\|pypi\|publish\|registry" publish-package/SKILL.md | awk '{if($1>=4) print "OK: semantics"; else print "FAIL: missing"}'`
|
|
262
|
-
→ verify: `grep -q "publish-package" SKILL-INDEX.md && echo "OK: in SKILL-INDEX" || echo "FAIL: not indexed"`
|
|
@@ -64,29 +64,7 @@ bash scripts/land-branch.sh <task-slug> "feat(scope): description"
|
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
**Path B — `scripts/land-branch.sh` missing (fallback):**
|
|
67
|
-
|
|
68
|
-
# Fallback: manual squash-merge when land-branch.sh is absent
|
|
69
|
-
FEATURE_BRANCH=<task-slug>
|
|
70
|
-
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo main)
|
|
71
|
-
|
|
72
|
-
# Ensure we're on the feature branch
|
|
73
|
-
if [ "$(git branch --show-current)" != "$FEATURE_BRANCH" ]; then
|
|
74
|
-
git checkout "$FEATURE_BRANCH"
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# Checkout default branch and update
|
|
78
|
-
git checkout "$DEFAULT_BRANCH"
|
|
79
|
-
git pull --rebase origin "$DEFAULT_BRANCH" 2>/dev/null || git pull origin "$DEFAULT_BRANCH"
|
|
80
|
-
|
|
81
|
-
# Squash-merge the feature branch
|
|
82
|
-
git merge --no-ff "$FEATURE_BRANCH" -m "<conventional-commit-message>"
|
|
83
|
-
|
|
84
|
-
# Push
|
|
85
|
-
git push origin "$DEFAULT_BRANCH"
|
|
86
|
-
|
|
87
|
-
# Clean up local feature branch
|
|
88
|
-
git branch -d "$FEATURE_BRANCH"
|
|
89
|
-
```
|
|
67
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
90
68
|
|
|
91
69
|
**Report which path was taken.** Print exactly:
|
|
92
70
|
- `"used land-branch.sh"` if Path A
|
|
@@ -118,41 +96,7 @@ mv specs/epics/eNN-slug specs/epics/archive/
|
|
|
118
96
|
|
|
119
97
|
After push (solo-local step 5 or team-pr step 7), verify the CI workflow completes successfully:
|
|
120
98
|
|
|
121
|
-
|
|
122
|
-
echo "==> Polling CI for main branch..."
|
|
123
|
-
TIMEOUT=600 # 10 minutes
|
|
124
|
-
INTERVAL=30 # poll every 30 seconds
|
|
125
|
-
ELAPSED=0
|
|
126
|
-
|
|
127
|
-
while [ $ELAPSED -lt $TIMEOUT ]; do
|
|
128
|
-
CI_JSON=$(gh run list --limit 1 --branch main --workflow CI --json status,conclusion,headSha,databaseId 2>/dev/null)
|
|
129
|
-
CI_STATUS=$(echo "$CI_JSON" | jq -r '.[0].status // "unknown"')
|
|
130
|
-
CI_CONCLUSION=$(echo "$CI_JSON" | jq -r '.[0].conclusion // ""')
|
|
131
|
-
CI_SHA=$(echo "$CI_JSON" | jq -r '.[0].headSha // ""')
|
|
132
|
-
CI_ID=$(echo "$CI_JSON" | jq -r '.[0].databaseId // ""')
|
|
133
|
-
|
|
134
|
-
if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "success" ]; then
|
|
135
|
-
echo "OK: CI passed for $(git rev-parse --short HEAD)"
|
|
136
|
-
bp-yaml-set.sh specs/state.yaml release.ci_verified true 2>/dev/null || \
|
|
137
|
-
echo " (bp-yaml-set not available — manually set release.ci_verified: true in state.yaml)"
|
|
138
|
-
break
|
|
139
|
-
fi
|
|
140
|
-
|
|
141
|
-
if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "failure" ]; then
|
|
142
|
-
echo "FAIL: CI failed for $(git rev-parse --short HEAD)"
|
|
143
|
-
echo " Run URL: https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/actions/runs/$CI_ID"
|
|
144
|
-
echo " Handoff to fix-bug with the failure URL above."
|
|
145
|
-
return 1
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
sleep $INTERVAL
|
|
149
|
-
ELAPSED=$((ELAPSED + INTERVAL))
|
|
150
|
-
echo " Waiting... (${ELAPSED}s / ${TIMEOUT}s)"
|
|
151
|
-
done
|
|
152
|
-
|
|
153
|
-
echo "FAIL: CI did not complete within ${TIMEOUT}s timeout"
|
|
154
|
-
return 1
|
|
155
|
-
```
|
|
99
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
156
100
|
|
|
157
101
|
- [ ] CI workflow passes after push
|
|
158
102
|
- [ ] `release.ci_verified: true` documented in state.yaml
|
|
@@ -178,21 +122,12 @@ git checkout main && git status && pwd
|
|
|
178
122
|
|
|
179
123
|
Report: "Branch released. Integrate mode: <solo-local|team-pr>. cwd: $(pwd) on $(git branch --show-current)."
|
|
180
124
|
|
|
181
|
-
## Solo-local fallback detail
|
|
182
|
-
|
|
183
|
-
The fallback sequence (Path B above) handles the "remote has moved" case with `git pull --rebase`. Use when `scripts/land-branch.sh` is absent.
|
|
184
|
-
|
|
185
|
-
**Acceptance:** When fallback runs, main is updated, feature branch is deleted locally, and output states `"used fallback merge (land-branch.sh not found)"`.
|
|
186
|
-
|
|
187
|
-
## Handoff
|
|
188
|
-
|
|
189
|
-
Gate: READY -> next: survey-context
|
|
190
|
-
Writes: state.yaml handoff.next_skill = survey-context
|
|
191
|
-
|
|
192
125
|
---
|
|
193
126
|
|
|
194
127
|
# Release Branch — Reference
|
|
195
128
|
|
|
129
|
+
# Release Branch — Reference
|
|
130
|
+
|
|
196
131
|
## PR body template (team-pr mode)
|
|
197
132
|
|
|
198
133
|
```bash
|
|
@@ -246,3 +181,84 @@ After landing the branch, record delivery metrics for this story:
|
|
|
246
181
|
cycle_minutes: 90
|
|
247
182
|
bcp_per_hour: 2.0
|
|
248
183
|
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Solo-local fallback detail
|
|
188
|
+
|
|
189
|
+
The fallback sequence (Path B above) handles the "remote has moved" case with `git pull --rebase`. Use when `scripts/land-branch.sh` is absent.
|
|
190
|
+
|
|
191
|
+
**Acceptance:** When fallback runs, main is updated, feature branch is deleted locally, and output states `"used fallback merge (land-branch.sh not found)"`.
|
|
192
|
+
|
|
193
|
+
## Handoff
|
|
194
|
+
|
|
195
|
+
Gate: READY -> next: survey-context
|
|
196
|
+
Writes: state.yaml handoff.next_skill = survey-context
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Reference block 1
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Fallback: manual squash-merge when land-branch.sh is absent
|
|
204
|
+
FEATURE_BRANCH=<task-slug>
|
|
205
|
+
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo main)
|
|
206
|
+
|
|
207
|
+
# Ensure we're on the feature branch
|
|
208
|
+
if [ "$(git branch --show-current)" != "$FEATURE_BRANCH" ]; then
|
|
209
|
+
git checkout "$FEATURE_BRANCH"
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
# Checkout default branch and update
|
|
213
|
+
git checkout "$DEFAULT_BRANCH"
|
|
214
|
+
git pull --rebase origin "$DEFAULT_BRANCH" 2>/dev/null || git pull origin "$DEFAULT_BRANCH"
|
|
215
|
+
|
|
216
|
+
# Squash-merge the feature branch
|
|
217
|
+
git merge --no-ff "$FEATURE_BRANCH" -m "<conventional-commit-message>"
|
|
218
|
+
|
|
219
|
+
# Push
|
|
220
|
+
git push origin "$DEFAULT_BRANCH"
|
|
221
|
+
|
|
222
|
+
# Clean up local feature branch
|
|
223
|
+
git branch -d "$FEATURE_BRANCH"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Reference block 2
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
echo "==> Polling CI for main branch..."
|
|
232
|
+
TIMEOUT=600 # 10 minutes
|
|
233
|
+
INTERVAL=30 # poll every 30 seconds
|
|
234
|
+
ELAPSED=0
|
|
235
|
+
|
|
236
|
+
while [ $ELAPSED -lt $TIMEOUT ]; do
|
|
237
|
+
CI_JSON=$(gh run list --limit 1 --branch main --workflow CI --json status,conclusion,headSha,databaseId 2>/dev/null)
|
|
238
|
+
CI_STATUS=$(echo "$CI_JSON" | jq -r '.[0].status // "unknown"')
|
|
239
|
+
CI_CONCLUSION=$(echo "$CI_JSON" | jq -r '.[0].conclusion // ""')
|
|
240
|
+
CI_SHA=$(echo "$CI_JSON" | jq -r '.[0].headSha // ""')
|
|
241
|
+
CI_ID=$(echo "$CI_JSON" | jq -r '.[0].databaseId // ""')
|
|
242
|
+
|
|
243
|
+
if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "success" ]; then
|
|
244
|
+
echo "OK: CI passed for $(git rev-parse --short HEAD)"
|
|
245
|
+
bp-yaml-set.sh specs/state.yaml release.ci_verified true 2>/dev/null || \
|
|
246
|
+
echo " (bp-yaml-set not available — manually set release.ci_verified: true in state.yaml)"
|
|
247
|
+
break
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "failure" ]; then
|
|
251
|
+
echo "FAIL: CI failed for $(git rev-parse --short HEAD)"
|
|
252
|
+
echo " Run URL: https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/actions/runs/$CI_ID"
|
|
253
|
+
echo " Handoff to fix-bug with the failure URL above."
|
|
254
|
+
return 1
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
sleep $INTERVAL
|
|
258
|
+
ELAPSED=$((ELAPSED + INTERVAL))
|
|
259
|
+
echo " Waiting... (${ELAPSED}s / ${TIMEOUT}s)"
|
|
260
|
+
done
|
|
261
|
+
|
|
262
|
+
echo "FAIL: CI did not complete within ${TIMEOUT}s timeout"
|
|
263
|
+
return 1
|
|
264
|
+
```
|
|
@@ -22,6 +22,94 @@ Can be run standalone for quick health checks or chained as the final step of th
|
|
|
22
22
|
|
|
23
23
|
Smoke checks are defined in `smoke-checks.yaml` at the project root:
|
|
24
24
|
|
|
25
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
26
|
+
|
|
27
|
+
Checks can also be specified inline via environment variables or CLI arguments for ad-hoc use.
|
|
28
|
+
|
|
29
|
+
### Check Schema
|
|
30
|
+
|
|
31
|
+
| Field | Required | Default | Description |
|
|
32
|
+
|-------|----------|---------|-------------|
|
|
33
|
+
| `name` | Yes | — | Human-readable check name (used in report) |
|
|
34
|
+
| `path` | Yes | `/` | URL path relative to base_url |
|
|
35
|
+
| `method` | No | `GET` | HTTP method |
|
|
36
|
+
| `expected_status` | No | `200` | Expected HTTP status code |
|
|
37
|
+
| `content_signal` | No | — | Regex or string to find in response body |
|
|
38
|
+
| `max_response_time_ms` | No | — | Fail if response slower than this threshold (ms) |
|
|
39
|
+
|
|
40
|
+
## Process
|
|
41
|
+
|
|
42
|
+
### 1. Load smoke checks
|
|
43
|
+
|
|
44
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
45
|
+
|
|
46
|
+
### 2. Run each check
|
|
47
|
+
|
|
48
|
+
For each check in the configuration, perform an HTTP request:
|
|
49
|
+
|
|
50
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
51
|
+
|
|
52
|
+
### 3. Assert results
|
|
53
|
+
|
|
54
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
55
|
+
|
|
56
|
+
### 4. Generate report
|
|
57
|
+
|
|
58
|
+
See [REFERENCE.md](REFERENCE.md)
|
|
59
|
+
|
|
60
|
+
## Integration with deploy skill
|
|
61
|
+
|
|
62
|
+
The `deploy` skill references `smoke-test` as its final verification step:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# In deploy workflow — after successful deploy
|
|
66
|
+
DEPLOY_URL="$DEPLOY_URL" bash scripts/run-smoke.sh
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
# Smoke Test — Reference
|
|
72
|
+
|
|
73
|
+
## Runner script
|
|
74
|
+
|
|
75
|
+
A ready-to-use runner is provided for standalone operation:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
bash scripts/run-smoke.sh [url] [smoke-checks-file]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The runner:
|
|
82
|
+
1. Uses `$DEPLOY_URL`, `$SMOKE_CHECKS_FILE`, or CLI arguments
|
|
83
|
+
2. Runs all defined checks
|
|
84
|
+
3. Prints a pass/fail summary
|
|
85
|
+
4. Exits 0 on all pass, non-zero on any failure
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Configuration reference
|
|
91
|
+
|
|
92
|
+
| Variable | Default | Description |
|
|
93
|
+
|----------|---------|-------------|
|
|
94
|
+
| `SMOKE_CHECKS_FILE` | `smoke-checks.yaml` | Path to smoke checks YAML |
|
|
95
|
+
| `DEPLOY_URL` / `BASE_URL` | *(required)* | Base URL for all checks |
|
|
96
|
+
| `SMOKE_TIMEOUT` | `30` | Per-check timeout (seconds) |
|
|
97
|
+
| `SMOKE_RETRIES` | `0` | Number of retries on failure |
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Verification
|
|
103
|
+
|
|
104
|
+
→ verify: `test -f smoke-test/SKILL.md && grep -q 'name: smoke-test' smoke-test/SKILL.md && echo OK`
|
|
105
|
+
→ verify: `grep -qi 'smoke.checks.yaml\|checklist\|expected_status\|content_signal' smoke-test/SKILL.md && echo OK`
|
|
106
|
+
→ verify: `grep -ci 'pass\|fail\|summary\|report' smoke-test/SKILL.md | awk '{if($1>=2) print "OK"; else print "FAIL"}'`
|
|
107
|
+
→ verify: `grep -q 'smoke-test' SKILL-INDEX.md && echo OK`
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Reference block 1
|
|
112
|
+
|
|
25
113
|
```yaml
|
|
26
114
|
# smoke-checks.yaml — auto-loaded if present at project root
|
|
27
115
|
base_url: "https://example.com"
|
|
@@ -52,22 +140,9 @@ checks:
|
|
|
52
140
|
content_signal: "not found|404"
|
|
53
141
|
```
|
|
54
142
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
### Check Schema
|
|
58
|
-
|
|
59
|
-
| Field | Required | Default | Description |
|
|
60
|
-
|-------|----------|---------|-------------|
|
|
61
|
-
| `name` | Yes | — | Human-readable check name (used in report) |
|
|
62
|
-
| `path` | Yes | `/` | URL path relative to base_url |
|
|
63
|
-
| `method` | No | `GET` | HTTP method |
|
|
64
|
-
| `expected_status` | No | `200` | Expected HTTP status code |
|
|
65
|
-
| `content_signal` | No | — | Regex or string to find in response body |
|
|
66
|
-
| `max_response_time_ms` | No | — | Fail if response slower than this threshold (ms) |
|
|
67
|
-
|
|
68
|
-
## Process
|
|
143
|
+
---
|
|
69
144
|
|
|
70
|
-
|
|
145
|
+
## Reference block 2
|
|
71
146
|
|
|
72
147
|
```bash
|
|
73
148
|
SMOKE_CHECKS_FILE="${SMOKE_CHECKS_FILE:-smoke-checks.yaml}"
|
|
@@ -83,9 +158,9 @@ else
|
|
|
83
158
|
fi
|
|
84
159
|
```
|
|
85
160
|
|
|
86
|
-
|
|
161
|
+
---
|
|
87
162
|
|
|
88
|
-
|
|
163
|
+
## Reference block 3
|
|
89
164
|
|
|
90
165
|
```bash
|
|
91
166
|
url="${BASE_URL}${path}"
|
|
@@ -98,7 +173,9 @@ status=$response
|
|
|
98
173
|
body=$(cat /tmp/smoke_body.txt)
|
|
99
174
|
```
|
|
100
175
|
|
|
101
|
-
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Reference block 4
|
|
102
179
|
|
|
103
180
|
```bash
|
|
104
181
|
checks_passed=0
|
|
@@ -133,7 +210,9 @@ if [ -n "$max_response_time_ms" ] && [ "$response_time" -gt "$max_response_time_
|
|
|
133
210
|
fi
|
|
134
211
|
```
|
|
135
212
|
|
|
136
|
-
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Reference block 5
|
|
137
216
|
|
|
138
217
|
```bash
|
|
139
218
|
total=$((checks_passed + checks_failed))
|
|
@@ -151,42 +230,3 @@ else
|
|
|
151
230
|
exit 0
|
|
152
231
|
fi
|
|
153
232
|
```
|
|
154
|
-
|
|
155
|
-
## Runner script
|
|
156
|
-
|
|
157
|
-
A ready-to-use runner is provided for standalone operation:
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
bash scripts/run-smoke.sh [url] [smoke-checks-file]
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
The runner:
|
|
164
|
-
1. Uses `$DEPLOY_URL`, `$SMOKE_CHECKS_FILE`, or CLI arguments
|
|
165
|
-
2. Runs all defined checks
|
|
166
|
-
3. Prints a pass/fail summary
|
|
167
|
-
4. Exits 0 on all pass, non-zero on any failure
|
|
168
|
-
|
|
169
|
-
## Integration with deploy skill
|
|
170
|
-
|
|
171
|
-
The `deploy` skill references `smoke-test` as its final verification step:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
# In deploy workflow — after successful deploy
|
|
175
|
-
DEPLOY_URL="$DEPLOY_URL" bash scripts/run-smoke.sh
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Configuration reference
|
|
179
|
-
|
|
180
|
-
| Variable | Default | Description |
|
|
181
|
-
|----------|---------|-------------|
|
|
182
|
-
| `SMOKE_CHECKS_FILE` | `smoke-checks.yaml` | Path to smoke checks YAML |
|
|
183
|
-
| `DEPLOY_URL` / `BASE_URL` | *(required)* | Base URL for all checks |
|
|
184
|
-
| `SMOKE_TIMEOUT` | `30` | Per-check timeout (seconds) |
|
|
185
|
-
| `SMOKE_RETRIES` | `0` | Number of retries on failure |
|
|
186
|
-
|
|
187
|
-
## Verification
|
|
188
|
-
|
|
189
|
-
→ verify: `test -f smoke-test/SKILL.md && grep -q 'name: smoke-test' smoke-test/SKILL.md && echo OK`
|
|
190
|
-
→ verify: `grep -qi 'smoke.checks.yaml\|checklist\|expected_status\|content_signal' smoke-test/SKILL.md && echo OK`
|
|
191
|
-
→ verify: `grep -ci 'pass\|fail\|summary\|report' smoke-test/SKILL.md | awk '{if($1>=2) print "OK"; else print "FAIL"}'`
|
|
192
|
-
→ verify: `grep -q 'smoke-test' SKILL-INDEX.md && echo OK`
|
|
@@ -9,7 +9,7 @@ model: sonnet
|
|
|
9
9
|
> **HARD GATE** — **HARD GATE** — This skill is the entry point. Do NOT skip it when onboarding new users or starting a new session. It establishes the bigpowers methodology, lifecycle phases, and conventions.
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
Welcome to **bigpowers** — a lifecycle of **
|
|
12
|
+
Welcome to **bigpowers** — a lifecycle of **70** agent skills for production-ready, TDD-driven software by solo developers.
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -100,7 +100,7 @@ Start the HTTP dashboard with `visual-dashboard` → `GET /api/status?projectDir
|
|
|
100
100
|
- **Integrate:** team default is `gh pr` (team-pr); solo profile uses `land-branch.sh`. Never create GitHub issues from skills — use local Markdown files instead.
|
|
101
101
|
- **One skill, one thing.** If you're unsure which skill to call, call `survey-context` — it reads your current state and recommends the next step.
|
|
102
102
|
- **verify: every step.** Every epic task must have `verify: <runnable command>`. Evidence over claims.
|
|
103
|
-
- **
|
|
103
|
+
- **70 skills.** See `SKILL-INDEX.md`; find skills with `search-skills`.
|
|
104
104
|
|
|
105
105
|
## After this
|
|
106
106
|
|