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.
Files changed (42) hide show
  1. package/.pi/package.json +2 -2
  2. package/.pi/prompts/deploy.md +53 -28
  3. package/.pi/prompts/develop-tdd.md +5 -80
  4. package/.pi/prompts/migrate-spec.md +273 -197
  5. package/.pi/prompts/publish-package.md +125 -67
  6. package/.pi/prompts/release-branch.md +85 -69
  7. package/.pi/prompts/smoke-test.md +98 -58
  8. package/.pi/prompts/using-bigpowers.md +2 -2
  9. package/.pi/prompts/validate-contracts.md +169 -54
  10. package/.pi/prompts/wire-ci.md +147 -89
  11. package/.pi/skills/deploy/SKILL.md +53 -28
  12. package/.pi/skills/develop-tdd/SKILL.md +5 -80
  13. package/.pi/skills/migrate-spec/SKILL.md +273 -197
  14. package/.pi/skills/publish-package/SKILL.md +125 -67
  15. package/.pi/skills/release-branch/SKILL.md +85 -69
  16. package/.pi/skills/smoke-test/SKILL.md +98 -58
  17. package/.pi/skills/using-bigpowers/SKILL.md +2 -2
  18. package/.pi/skills/validate-contracts/SKILL.md +169 -54
  19. package/.pi/skills/wire-ci/SKILL.md +147 -89
  20. package/CHANGELOG.md +14 -0
  21. package/README.md +4 -4
  22. package/SKILL-INDEX.md +1 -1
  23. package/deploy/REFERENCE.md +82 -0
  24. package/deploy/SKILL.md +3 -63
  25. package/develop-tdd/SKILL.md +5 -80
  26. package/migrate-spec/REFERENCE.md +268 -0
  27. package/migrate-spec/SKILL.md +5 -199
  28. package/package.json +4 -3
  29. package/publish-package/REFERENCE.md +239 -0
  30. package/publish-package/SKILL.md +8 -192
  31. package/release-branch/REFERENCE.md +83 -0
  32. package/release-branch/SKILL.md +2 -69
  33. package/scripts/generate-reference-tables.sh +1 -0
  34. package/scripts/sync-skills.sh +4 -1
  35. package/skills-lock.json +9 -9
  36. package/smoke-test/REFERENCE.md +162 -0
  37. package/smoke-test/SKILL.md +5 -130
  38. package/using-bigpowers/SKILL.md +2 -2
  39. package/validate-contracts/REFERENCE.md +183 -0
  40. package/validate-contracts/SKILL.md +6 -77
  41. package/wire-ci/REFERENCE.md +257 -0
  42. package/wire-ci/SKILL.md +8 -210
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.34.0",
4
- "description": "61 agent skills for spec-driven, test-first software development by solo developers",
3
+ "version": "2.34.2",
4
+ "description": "70 agent skills for spec-driven, test-first software development by solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "compliance": "bash scripts/audit-compliance.sh specs/verifications/features && bash scripts/validate-doctrine.sh",
@@ -44,7 +44,8 @@
44
44
  "url": "https://github.com/danielvm-git/bigpowers.git"
45
45
  },
46
46
  "bin": {
47
- "bigpowers": "./bin/bigpowers.js"
47
+ "bigpowers": "./bin/bigpowers.js",
48
+ "bigpowers-dashboard": "./dashboard/bin/dashboard.js"
48
49
  },
49
50
  "engines": {
50
51
  "node": ">=14.0.0"
@@ -0,0 +1,239 @@
1
+ # Publish Package — Reference
2
+
3
+ ## Options
4
+
5
+ | Flag | Description |
6
+ |------|-------------|
7
+ | `--dry-run` | Verify prerequisites and show publish command without executing |
8
+ | `--registry <type>` | Force registry type (skip auto-detection) |
9
+ | `--otp <code>` | One-time password for npm 2FA |
10
+ | `--no-verify` | Skip prerequisite checks (use with caution) |
11
+
12
+
13
+ ---
14
+
15
+ ## Examples
16
+
17
+ ### Publish an npm package
18
+
19
+ ```bash
20
+ # Verify first
21
+ publish-package --dry-run
22
+
23
+ # Publish
24
+ publish-package
25
+
26
+ # Output:
27
+ # [npm] Publishing my-package v0.4.0...
28
+ # OK: npm publish confirmed (my-package@0.4.0 on registry)
29
+ ```
30
+
31
+ ### Publish a Rust crate
32
+
33
+ ```bash
34
+ export CARGO_REGISTRY_TOKEN=<token>
35
+ publish-package --dry-run
36
+ publish-package
37
+ ```
38
+
39
+ ### Missing token scenario
40
+
41
+ ```bash
42
+ $ publish-package
43
+ FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add to .npmrc
44
+ ```
45
+
46
+
47
+ ---
48
+
49
+ ## Integration with release-branch
50
+
51
+ When wired into `release-branch`, add a step after git push:
52
+
53
+ ```
54
+ 6a. Run publish-package to publish to package registries
55
+ → verify: publish-package --dry-run && publish-package
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Reference block 1
61
+
62
+ ```bash
63
+ # Check auth token exists
64
+ if [ -z "${NPM_TOKEN:-}" ]; then
65
+ if [ ! -f ~/.npmrc ] || ! grep -q "_authToken" ~/.npmrc; then
66
+ echo "FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add //registry.npmjs.org/:_authToken=<token> to .npmrc"
67
+ exit 1
68
+ fi
69
+ fi
70
+
71
+ # Check version not already published
72
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
73
+ CURRENT_VER=$(node -p "require('./package.json').version")
74
+ if npm view "$PACKAGE_NAME@$CURRENT_VER" version 2>/dev/null; then
75
+ echo "FAIL: Version $CURRENT_VER already published for $PACKAGE_NAME. Bump version first."
76
+ exit 1
77
+ fi
78
+
79
+ # Check build artifacts are fresh
80
+ if [ -d dist ] || [ -d lib ]; then
81
+ LATEST_BUILD=$(find dist lib 2>/dev/null -name "*.js" -o -name "*.cjs" -o -name "*.mjs" | xargs ls -t 2>/dev/null | head -1)
82
+ PACKAGE_MODIFIED=$(stat -f %m package.json 2>/dev/null || stat -c %Y package.json 2>/dev/null)
83
+ if [ -n "$LATEST_BUILD" ] && [ -n "$PACKAGE_MODIFIED" ]; then
84
+ BUILD_TIME=$(stat -f %m "$LATEST_BUILD" 2>/dev/null || stat -c %Y "$LATEST_BUILD" 2>/dev/null)
85
+ if [ "$BUILD_TIME" -lt "$PACKAGE_MODIFIED" ]; then
86
+ echo "WARNING: Build artifacts may be stale (package.json modified after last build). Run npm run build first."
87
+ fi
88
+ fi
89
+ fi
90
+
91
+ # Check CHANGELOG is updated
92
+ if [ -f CHANGELOG.md ]; then
93
+ if ! grep -q "$CURRENT_VER" CHANGELOG.md 2>/dev/null; then
94
+ echo "WARNING: Version $CURRENT_VER not found in CHANGELOG.md. Update changelog before publish."
95
+ fi
96
+ fi
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Reference block 2
102
+
103
+ ```bash
104
+ # Check auth token exists
105
+ if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
106
+ if [ ! -f ~/.cargo/config.toml ] || ! grep -q "token" ~/.cargo/config.toml; then
107
+ echo "FAIL: CARGO_REGISTRY_TOKEN not set. Set via: export CARGO_REGISTRY_TOKEN=<token> or add to ~/.cargo/config.toml"
108
+ exit 1
109
+ fi
110
+ fi
111
+
112
+ # Check version not already published
113
+ CRATE_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
114
+ CURRENT_VER=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
115
+ if cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\""; then
116
+ echo "FAIL: Version $CURRENT_VER already published for $CRATE_NAME. Bump version in Cargo.toml first."
117
+ exit 1
118
+ fi
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Reference block 3
124
+
125
+ ```bash
126
+ # Check auth token exists
127
+ if [ -z "${TWINE_PASSWORD:-}" ] && [ -z "${POETRY_PYPI_TOKEN_PYPI:-}" ]; then
128
+ if [ ! -f ~/.pypirc ]; then
129
+ echo "FAIL: PyPI token not configured. Set TWINE_PASSWORD or create ~/.pypirc"
130
+ exit 1
131
+ fi
132
+ fi
133
+
134
+ # Check for build artifacts
135
+ if [ ! -d dist ] || [ -z "$(ls dist/*.whl 2>/dev/null)" ]; then
136
+ echo "WARNING: No .whl files found in dist/. Run: python -m build"
137
+ fi
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Reference block 4
143
+
144
+ ```bash
145
+ # npm
146
+ npm publish --access public
147
+
148
+ # crates.io
149
+ cargo publish
150
+
151
+ # PyPI
152
+ python -m twine upload dist/* # or: poetry publish
153
+
154
+ # Homebrew (opens PR, does not publish directly)
155
+ brew bump-formula-pr --url=<tarball-url> <formula-name>
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Reference block 5
161
+
162
+ ```bash
163
+ # npm
164
+ npm view "$PACKAGE_NAME" versions --json 2>/dev/null | grep -q "\"$CURRENT_VER\"" && echo "OK: npm publish confirmed"
165
+
166
+ # crates.io
167
+ cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\"" && echo "OK: crates.io publish confirmed"
168
+
169
+ # PyPI
170
+ pip index versions "$PACKAGE_NAME" 2>/dev/null | grep -q "$CURRENT_VER" && echo "OK: PyPI publish confirmed"
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Reference block 6
176
+
177
+ ```bash
178
+ # Generic failure handler
179
+ if [ $? -ne 0 ]; then
180
+ case "$REGISTRY" in
181
+ npm)
182
+ echo "FAIL: npm publish failed."
183
+ echo " Common causes:"
184
+ echo " - NPM_TOKEN not set in secrets: add to GitHub repo secrets"
185
+ echo " - Version already published: bump version in package.json"
186
+ echo " - Two-factor auth required: use --otp=<code> flag"
187
+ echo " - Package scoped but not public: add --access public"
188
+ ;;
189
+ crates.io)
190
+ echo "FAIL: cargo publish failed."
191
+ echo " Common causes:"
192
+ echo " - CARGO_REGISTRY_TOKEN not configured: see ~/.cargo/config.toml"
193
+ echo " - Version already published: bump version in Cargo.toml"
194
+ echo " - Local changes not committed: cargo publish requires clean working tree"
195
+ ;;
196
+ pypi)
197
+ echo "FAIL: PyPI publish failed."
198
+ echo " Common causes:"
199
+ echo " - TWINE_PASSWORD not configured: set env var or ~/.pypirc"
200
+ echo " - Build artifacts missing: run python -m build first"
201
+ echo " - Version conflict: version already exists on PyPI"
202
+ ;;
203
+ esac
204
+ exit 1
205
+ fi
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Reference block 7
211
+
212
+ ```bash
213
+ # Example output
214
+ $ publish-package --dry-run
215
+
216
+ [DRY-RUN] Detected package type: npm
217
+ [DRY-RUN] Package: my-package v0.4.0
218
+ [DRY-RUN] Checking NPM_TOKEN... OK
219
+ [DRY-RUN] Checking version 0.4.0 not already published... OK
220
+ [DRY-RUN] Checking build artifacts... WARNING: package.json modified after build
221
+ [DRY-RUN] Checking CHANGELOG... OK
222
+ [DRY-RUN] Would run: npm publish --access public
223
+ [DRY-RUN] Exiting without publishing.
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Reference block 8
229
+
230
+ ```bash
231
+ # npm dry-run
232
+ npm publish --access public --dry-run
233
+
234
+ # crates.io dry-run (cargo does not have a publish dry-run; use --dry-run flag for validation only)
235
+ cargo package --list 2>/dev/null
236
+
237
+ # PyPI dry-run
238
+ python -m twine upload --repository testpypi dist/* # test.pypi.org
239
+ ```
@@ -33,225 +33,41 @@ If no manifest is found, prompt the user to specify the type or pass `--type <np
33
33
  Before attempting any publish, run all applicable checks:
34
34
 
35
35
  **npm (`package.json`):**
36
- ```bash
37
- # Check auth token exists
38
- if [ -z "${NPM_TOKEN:-}" ]; then
39
- if [ ! -f ~/.npmrc ] || ! grep -q "_authToken" ~/.npmrc; then
40
- echo "FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add //registry.npmjs.org/:_authToken=<token> to .npmrc"
41
- exit 1
42
- fi
43
- fi
44
-
45
- # Check version not already published
46
- PACKAGE_NAME=$(node -p "require('./package.json').name")
47
- CURRENT_VER=$(node -p "require('./package.json').version")
48
- if npm view "$PACKAGE_NAME@$CURRENT_VER" version 2>/dev/null; then
49
- echo "FAIL: Version $CURRENT_VER already published for $PACKAGE_NAME. Bump version first."
50
- exit 1
51
- fi
52
-
53
- # Check build artifacts are fresh
54
- if [ -d dist ] || [ -d lib ]; then
55
- LATEST_BUILD=$(find dist lib 2>/dev/null -name "*.js" -o -name "*.cjs" -o -name "*.mjs" | xargs ls -t 2>/dev/null | head -1)
56
- PACKAGE_MODIFIED=$(stat -f %m package.json 2>/dev/null || stat -c %Y package.json 2>/dev/null)
57
- if [ -n "$LATEST_BUILD" ] && [ -n "$PACKAGE_MODIFIED" ]; then
58
- BUILD_TIME=$(stat -f %m "$LATEST_BUILD" 2>/dev/null || stat -c %Y "$LATEST_BUILD" 2>/dev/null)
59
- if [ "$BUILD_TIME" -lt "$PACKAGE_MODIFIED" ]; then
60
- echo "WARNING: Build artifacts may be stale (package.json modified after last build). Run npm run build first."
61
- fi
62
- fi
63
- fi
64
-
65
- # Check CHANGELOG is updated
66
- if [ -f CHANGELOG.md ]; then
67
- if ! grep -q "$CURRENT_VER" CHANGELOG.md 2>/dev/null; then
68
- echo "WARNING: Version $CURRENT_VER not found in CHANGELOG.md. Update changelog before publish."
69
- fi
70
- fi
71
- ```
36
+ See [REFERENCE.md](REFERENCE.md)
72
37
 
73
38
  **crates.io (`Cargo.toml`):**
74
- ```bash
75
- # Check auth token exists
76
- if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
77
- if [ ! -f ~/.cargo/config.toml ] || ! grep -q "token" ~/.cargo/config.toml; then
78
- echo "FAIL: CARGO_REGISTRY_TOKEN not set. Set via: export CARGO_REGISTRY_TOKEN=<token> or add to ~/.cargo/config.toml"
79
- exit 1
80
- fi
81
- fi
82
-
83
- # Check version not already published
84
- CRATE_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
85
- CURRENT_VER=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
86
- if cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\""; then
87
- echo "FAIL: Version $CURRENT_VER already published for $CRATE_NAME. Bump version in Cargo.toml first."
88
- exit 1
89
- fi
90
- ```
39
+ See [REFERENCE.md](REFERENCE.md)
91
40
 
92
41
  **PyPI (`setup.py` / `pyproject.toml`):**
93
- ```bash
94
- # Check auth token exists
95
- if [ -z "${TWINE_PASSWORD:-}" ] && [ -z "${POETRY_PYPI_TOKEN_PYPI:-}" ]; then
96
- if [ ! -f ~/.pypirc ]; then
97
- echo "FAIL: PyPI token not configured. Set TWINE_PASSWORD or create ~/.pypirc"
98
- exit 1
99
- fi
100
- fi
101
-
102
- # Check for build artifacts
103
- if [ ! -d dist ] || [ -z "$(ls dist/*.whl 2>/dev/null)" ]; then
104
- echo "WARNING: No .whl files found in dist/. Run: python -m build"
105
- fi
106
- ```
42
+ See [REFERENCE.md](REFERENCE.md)
107
43
 
108
44
  ### 3. Run publish
109
45
 
110
46
  After all prerequisite checks pass, run the registry-specific command:
111
47
 
112
- ```bash
113
- # npm
114
- npm publish --access public
115
-
116
- # crates.io
117
- cargo publish
118
-
119
- # PyPI
120
- python -m twine upload dist/* # or: poetry publish
121
-
122
- # Homebrew (opens PR, does not publish directly)
123
- brew bump-formula-pr --url=<tarball-url> <formula-name>
124
- ```
48
+ See [REFERENCE.md](REFERENCE.md)
125
49
 
126
50
  ### 4. Verify publish success
127
51
 
128
52
  After publish, confirm the version appears on the registry:
129
53
 
130
- ```bash
131
- # npm
132
- npm view "$PACKAGE_NAME" versions --json 2>/dev/null | grep -q "\"$CURRENT_VER\"" && echo "OK: npm publish confirmed"
133
-
134
- # crates.io
135
- cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\"" && echo "OK: crates.io publish confirmed"
136
-
137
- # PyPI
138
- pip index versions "$PACKAGE_NAME" 2>/dev/null | grep -q "$CURRENT_VER" && echo "OK: PyPI publish confirmed"
139
- ```
54
+ See [REFERENCE.md](REFERENCE.md)
140
55
 
141
56
  ### 5. Error handling
142
57
 
143
58
  On failure, surface actionable hints:
144
59
 
145
- ```bash
146
- # Generic failure handler
147
- if [ $? -ne 0 ]; then
148
- case "$REGISTRY" in
149
- npm)
150
- echo "FAIL: npm publish failed."
151
- echo " Common causes:"
152
- echo " - NPM_TOKEN not set in secrets: add to GitHub repo secrets"
153
- echo " - Version already published: bump version in package.json"
154
- echo " - Two-factor auth required: use --otp=<code> flag"
155
- echo " - Package scoped but not public: add --access public"
156
- ;;
157
- crates.io)
158
- echo "FAIL: cargo publish failed."
159
- echo " Common causes:"
160
- echo " - CARGO_REGISTRY_TOKEN not configured: see ~/.cargo/config.toml"
161
- echo " - Version already published: bump version in Cargo.toml"
162
- echo " - Local changes not committed: cargo publish requires clean working tree"
163
- ;;
164
- pypi)
165
- echo "FAIL: PyPI publish failed."
166
- echo " Common causes:"
167
- echo " - TWINE_PASSWORD not configured: set env var or ~/.pypirc"
168
- echo " - Build artifacts missing: run python -m build first"
169
- echo " - Version conflict: version already exists on PyPI"
170
- ;;
171
- esac
172
- exit 1
173
- fi
174
- ```
60
+ See [REFERENCE.md](REFERENCE.md)
175
61
 
176
62
  ### 6. Dry-run mode (`--dry-run`)
177
63
 
178
64
  Run `--dry-run` to verify all prerequisites without actually publishing:
179
65
 
180
- ```bash
181
- # Example output
182
- $ publish-package --dry-run
183
-
184
- [DRY-RUN] Detected package type: npm
185
- [DRY-RUN] Package: my-package v0.4.0
186
- [DRY-RUN] Checking NPM_TOKEN... OK
187
- [DRY-RUN] Checking version 0.4.0 not already published... OK
188
- [DRY-RUN] Checking build artifacts... WARNING: package.json modified after build
189
- [DRY-RUN] Checking CHANGELOG... OK
190
- [DRY-RUN] Would run: npm publish --access public
191
- [DRY-RUN] Exiting without publishing.
192
- ```
66
+ See [REFERENCE.md](REFERENCE.md)
193
67
 
194
68
  ### 7. Dry-run mode per registry
195
69
 
196
- ```bash
197
- # npm dry-run
198
- npm publish --access public --dry-run
199
-
200
- # crates.io dry-run (cargo does not have a publish dry-run; use --dry-run flag for validation only)
201
- cargo package --list 2>/dev/null
202
-
203
- # PyPI dry-run
204
- python -m twine upload --repository testpypi dist/* # test.pypi.org
205
- ```
206
-
207
- ## Options
208
-
209
- | Flag | Description |
210
- |------|-------------|
211
- | `--dry-run` | Verify prerequisites and show publish command without executing |
212
- | `--registry <type>` | Force registry type (skip auto-detection) |
213
- | `--otp <code>` | One-time password for npm 2FA |
214
- | `--no-verify` | Skip prerequisite checks (use with caution) |
215
-
216
- ## Examples
217
-
218
- ### Publish an npm package
219
-
220
- ```bash
221
- # Verify first
222
- publish-package --dry-run
223
-
224
- # Publish
225
- publish-package
226
-
227
- # Output:
228
- # [npm] Publishing my-package v0.4.0...
229
- # OK: npm publish confirmed (my-package@0.4.0 on registry)
230
- ```
231
-
232
- ### Publish a Rust crate
233
-
234
- ```bash
235
- export CARGO_REGISTRY_TOKEN=<token>
236
- publish-package --dry-run
237
- publish-package
238
- ```
239
-
240
- ### Missing token scenario
241
-
242
- ```bash
243
- $ publish-package
244
- FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add to .npmrc
245
- ```
246
-
247
- ## Integration with release-branch
248
-
249
- When wired into `release-branch`, add a step after git push:
250
-
251
- ```
252
- 6a. Run publish-package to publish to package registries
253
- → verify: publish-package --dry-run && publish-package
254
- ```
70
+ See [REFERENCE.md](REFERENCE.md)
255
71
 
256
72
  ## Verify
257
73
 
@@ -1,5 +1,7 @@
1
1
  # Release Branch — Reference
2
2
 
3
+ # Release Branch — Reference
4
+
3
5
  ## PR body template (team-pr mode)
4
6
 
5
7
  ```bash
@@ -53,3 +55,84 @@ After landing the branch, record delivery metrics for this story:
53
55
  cycle_minutes: 90
54
56
  bcp_per_hour: 2.0
55
57
  ```
58
+
59
+ ---
60
+
61
+ ## Solo-local fallback detail
62
+
63
+ The fallback sequence (Path B above) handles the "remote has moved" case with `git pull --rebase`. Use when `scripts/land-branch.sh` is absent.
64
+
65
+ **Acceptance:** When fallback runs, main is updated, feature branch is deleted locally, and output states `"used fallback merge (land-branch.sh not found)"`.
66
+
67
+ ## Handoff
68
+
69
+ Gate: READY -> next: survey-context
70
+ Writes: state.yaml handoff.next_skill = survey-context
71
+
72
+ ---
73
+
74
+ ## Reference block 1
75
+
76
+ ```bash
77
+ # Fallback: manual squash-merge when land-branch.sh is absent
78
+ FEATURE_BRANCH=<task-slug>
79
+ DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo main)
80
+
81
+ # Ensure we're on the feature branch
82
+ if [ "$(git branch --show-current)" != "$FEATURE_BRANCH" ]; then
83
+ git checkout "$FEATURE_BRANCH"
84
+ fi
85
+
86
+ # Checkout default branch and update
87
+ git checkout "$DEFAULT_BRANCH"
88
+ git pull --rebase origin "$DEFAULT_BRANCH" 2>/dev/null || git pull origin "$DEFAULT_BRANCH"
89
+
90
+ # Squash-merge the feature branch
91
+ git merge --no-ff "$FEATURE_BRANCH" -m "<conventional-commit-message>"
92
+
93
+ # Push
94
+ git push origin "$DEFAULT_BRANCH"
95
+
96
+ # Clean up local feature branch
97
+ git branch -d "$FEATURE_BRANCH"
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Reference block 2
103
+
104
+ ```bash
105
+ echo "==> Polling CI for main branch..."
106
+ TIMEOUT=600 # 10 minutes
107
+ INTERVAL=30 # poll every 30 seconds
108
+ ELAPSED=0
109
+
110
+ while [ $ELAPSED -lt $TIMEOUT ]; do
111
+ CI_JSON=$(gh run list --limit 1 --branch main --workflow CI --json status,conclusion,headSha,databaseId 2>/dev/null)
112
+ CI_STATUS=$(echo "$CI_JSON" | jq -r '.[0].status // "unknown"')
113
+ CI_CONCLUSION=$(echo "$CI_JSON" | jq -r '.[0].conclusion // ""')
114
+ CI_SHA=$(echo "$CI_JSON" | jq -r '.[0].headSha // ""')
115
+ CI_ID=$(echo "$CI_JSON" | jq -r '.[0].databaseId // ""')
116
+
117
+ if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "success" ]; then
118
+ echo "OK: CI passed for $(git rev-parse --short HEAD)"
119
+ bp-yaml-set.sh specs/state.yaml release.ci_verified true 2>/dev/null || \
120
+ echo " (bp-yaml-set not available — manually set release.ci_verified: true in state.yaml)"
121
+ break
122
+ fi
123
+
124
+ if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "failure" ]; then
125
+ echo "FAIL: CI failed for $(git rev-parse --short HEAD)"
126
+ echo " Run URL: https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/actions/runs/$CI_ID"
127
+ echo " Handoff to fix-bug with the failure URL above."
128
+ return 1
129
+ fi
130
+
131
+ sleep $INTERVAL
132
+ ELAPSED=$((ELAPSED + INTERVAL))
133
+ echo " Waiting... (${ELAPSED}s / ${TIMEOUT}s)"
134
+ done
135
+
136
+ echo "FAIL: CI did not complete within ${TIMEOUT}s timeout"
137
+ return 1
138
+ ```
@@ -63,29 +63,7 @@ bash scripts/land-branch.sh <task-slug> "feat(scope): description"
63
63
  ```
64
64
 
65
65
  **Path B — `scripts/land-branch.sh` missing (fallback):**
66
- ```bash
67
- # Fallback: manual squash-merge when land-branch.sh is absent
68
- FEATURE_BRANCH=<task-slug>
69
- DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo main)
70
-
71
- # Ensure we're on the feature branch
72
- if [ "$(git branch --show-current)" != "$FEATURE_BRANCH" ]; then
73
- git checkout "$FEATURE_BRANCH"
74
- fi
75
-
76
- # Checkout default branch and update
77
- git checkout "$DEFAULT_BRANCH"
78
- git pull --rebase origin "$DEFAULT_BRANCH" 2>/dev/null || git pull origin "$DEFAULT_BRANCH"
79
-
80
- # Squash-merge the feature branch
81
- git merge --no-ff "$FEATURE_BRANCH" -m "<conventional-commit-message>"
82
-
83
- # Push
84
- git push origin "$DEFAULT_BRANCH"
85
-
86
- # Clean up local feature branch
87
- git branch -d "$FEATURE_BRANCH"
88
- ```
66
+ See [REFERENCE.md](REFERENCE.md)
89
67
 
90
68
  **Report which path was taken.** Print exactly:
91
69
  - `"used land-branch.sh"` if Path A
@@ -117,41 +95,7 @@ mv specs/epics/eNN-slug specs/epics/archive/
117
95
 
118
96
  After push (solo-local step 5 or team-pr step 7), verify the CI workflow completes successfully:
119
97
 
120
- ```bash
121
- echo "==> Polling CI for main branch..."
122
- TIMEOUT=600 # 10 minutes
123
- INTERVAL=30 # poll every 30 seconds
124
- ELAPSED=0
125
-
126
- while [ $ELAPSED -lt $TIMEOUT ]; do
127
- CI_JSON=$(gh run list --limit 1 --branch main --workflow CI --json status,conclusion,headSha,databaseId 2>/dev/null)
128
- CI_STATUS=$(echo "$CI_JSON" | jq -r '.[0].status // "unknown"')
129
- CI_CONCLUSION=$(echo "$CI_JSON" | jq -r '.[0].conclusion // ""')
130
- CI_SHA=$(echo "$CI_JSON" | jq -r '.[0].headSha // ""')
131
- CI_ID=$(echo "$CI_JSON" | jq -r '.[0].databaseId // ""')
132
-
133
- if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "success" ]; then
134
- echo "OK: CI passed for $(git rev-parse --short HEAD)"
135
- bp-yaml-set.sh specs/state.yaml release.ci_verified true 2>/dev/null || \
136
- echo " (bp-yaml-set not available — manually set release.ci_verified: true in state.yaml)"
137
- break
138
- fi
139
-
140
- if [ "$CI_STATUS" = "completed" ] && [ "$CI_CONCLUSION" = "failure" ]; then
141
- echo "FAIL: CI failed for $(git rev-parse --short HEAD)"
142
- echo " Run URL: https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/actions/runs/$CI_ID"
143
- echo " Handoff to fix-bug with the failure URL above."
144
- return 1
145
- fi
146
-
147
- sleep $INTERVAL
148
- ELAPSED=$((ELAPSED + INTERVAL))
149
- echo " Waiting... (${ELAPSED}s / ${TIMEOUT}s)"
150
- done
151
-
152
- echo "FAIL: CI did not complete within ${TIMEOUT}s timeout"
153
- return 1
154
- ```
98
+ See [REFERENCE.md](REFERENCE.md)
155
99
 
156
100
  - [ ] CI workflow passes after push
157
101
  - [ ] `release.ci_verified: true` documented in state.yaml
@@ -176,14 +120,3 @@ git checkout main && git status && pwd
176
120
  ```
177
121
 
178
122
  Report: "Branch released. Integrate mode: <solo-local|team-pr>. cwd: $(pwd) on $(git branch --show-current)."
179
-
180
- ## Solo-local fallback detail
181
-
182
- The fallback sequence (Path B above) handles the "remote has moved" case with `git pull --rebase`. Use when `scripts/land-branch.sh` is absent.
183
-
184
- **Acceptance:** When fallback runs, main is updated, feature branch is deleted locally, and output states `"used fallback merge (land-branch.sh not found)"`.
185
-
186
- ## Handoff
187
-
188
- Gate: READY -> next: survey-context
189
- Writes: state.yaml handoff.next_skill = survey-context
@@ -6,6 +6,7 @@ set -euo pipefail
6
6
 
7
7
  REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
8
8
  TARGET="$REPO_ROOT/docs/references/model-profiles.md"
9
+ mkdir -p "$(dirname "$TARGET")"
9
10
 
10
11
  cd "$REPO_ROOT"
11
12
 
@@ -231,6 +231,9 @@ if [[ -f "$validate_script" ]] && command -v python3 &>/dev/null; then
231
231
  fi
232
232
 
233
233
  # Regenerate derived reference tables from live SKILL.md frontmatter
234
- bash "$REPO_ROOT/scripts/generate-reference-tables.sh"
234
+ # Only in dev context (with .git) — not during consumer npm install where docs/ is excluded
235
+ if [[ -d "$REPO_ROOT/.git" ]]; then
236
+ bash "$REPO_ROOT/scripts/generate-reference-tables.sh"
237
+ fi
235
238
 
236
239
  exit 0