bigpowers 2.8.0 → 2.9.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/.pi/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.8.0",
4
- "description": "63 skills — 61 agent skills for spec-driven, test-first software development by solo developers",
3
+ "version": "2.9.0",
4
+ "description": "64 skills — 61 agent skills for spec-driven, test-first software development by solo developers",
5
5
  "keywords": [
6
6
  "pi-package"
7
7
  ],
@@ -0,0 +1,260 @@
1
+ ---
2
+ description: "Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies prerequisites, runs the publish command, confirms success, and surfaces actionable error hints on failure."
3
+ ---
4
+
5
+
6
+ # Publish Package
7
+
8
+ > **HARD GATE** — Do not attempt to publish without verifying prerequisites. Missing auth tokens, stale builds, or duplicate versions cause CI failures that are hard to debug post-push.
9
+ >
10
+ > **HARD GATE** — Always run `--dry-run` first. Package registries are append-only — a bad publish cannot be fully undone on most registries.
11
+
12
+ Publish packages to language-specific registries. Detects package type from manifest files, verifies publish prerequisites, runs the registry-specific publish command, and confirms the version appears on the registry.
13
+
14
+ ## Process
15
+
16
+ ### 1. Detect package type
17
+
18
+ Read the project root for manifest files to determine the package type:
19
+
20
+ | Manifest | Registry | Publish command |
21
+ |----------|----------|----------------|
22
+ | `package.json` | npm | `npm publish --access public` |
23
+ | `Cargo.toml` | crates.io | `cargo publish` |
24
+ | `setup.py` / `pyproject.toml` | PyPI | `twine upload dist/*` or `flit publish` |
25
+ | `Formula/<name>.rb` | Homebrew | `brew bump-formula-pr` |
26
+ | Multiple detected | Polyglot | Error: specify registry with `--registry <npm|crates.io|pypi|brew>` |
27
+
28
+ If no manifest is found, prompt the user to specify the type or pass `--type <npm|crates.io|pypi|brew>`.
29
+
30
+ ### 2. Verify prerequisites
31
+
32
+ Before attempting any publish, run all applicable checks:
33
+
34
+ **npm (`package.json`):**
35
+ ```bash
36
+ # Check auth token exists
37
+ if [ -z "${NPM_TOKEN:-}" ]; then
38
+ if [ ! -f ~/.npmrc ] || ! grep -q "_authToken" ~/.npmrc; then
39
+ echo "FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add //registry.npmjs.org/:_authToken=<token> to .npmrc"
40
+ exit 1
41
+ fi
42
+ fi
43
+
44
+ # Check version not already published
45
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
46
+ CURRENT_VER=$(node -p "require('./package.json').version")
47
+ if npm view "$PACKAGE_NAME@$CURRENT_VER" version 2>/dev/null; then
48
+ echo "FAIL: Version $CURRENT_VER already published for $PACKAGE_NAME. Bump version first."
49
+ exit 1
50
+ fi
51
+
52
+ # Check build artifacts are fresh
53
+ if [ -d dist ] || [ -d lib ]; then
54
+ LATEST_BUILD=$(find dist lib 2>/dev/null -name "*.js" -o -name "*.cjs" -o -name "*.mjs" | xargs ls -t 2>/dev/null | head -1)
55
+ PACKAGE_MODIFIED=$(stat -f %m package.json 2>/dev/null || stat -c %Y package.json 2>/dev/null)
56
+ if [ -n "$LATEST_BUILD" ] && [ -n "$PACKAGE_MODIFIED" ]; then
57
+ BUILD_TIME=$(stat -f %m "$LATEST_BUILD" 2>/dev/null || stat -c %Y "$LATEST_BUILD" 2>/dev/null)
58
+ if [ "$BUILD_TIME" -lt "$PACKAGE_MODIFIED" ]; then
59
+ echo "WARNING: Build artifacts may be stale (package.json modified after last build). Run npm run build first."
60
+ fi
61
+ fi
62
+ fi
63
+
64
+ # Check CHANGELOG is updated
65
+ if [ -f CHANGELOG.md ]; then
66
+ if ! grep -q "$CURRENT_VER" CHANGELOG.md 2>/dev/null; then
67
+ echo "WARNING: Version $CURRENT_VER not found in CHANGELOG.md. Update changelog before publish."
68
+ fi
69
+ fi
70
+ ```
71
+
72
+ **crates.io (`Cargo.toml`):**
73
+ ```bash
74
+ # Check auth token exists
75
+ if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
76
+ if [ ! -f ~/.cargo/config.toml ] || ! grep -q "token" ~/.cargo/config.toml; then
77
+ echo "FAIL: CARGO_REGISTRY_TOKEN not set. Set via: export CARGO_REGISTRY_TOKEN=<token> or add to ~/.cargo/config.toml"
78
+ exit 1
79
+ fi
80
+ fi
81
+
82
+ # Check version not already published
83
+ CRATE_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
84
+ CURRENT_VER=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
85
+ if cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\""; then
86
+ echo "FAIL: Version $CURRENT_VER already published for $CRATE_NAME. Bump version in Cargo.toml first."
87
+ exit 1
88
+ fi
89
+ ```
90
+
91
+ **PyPI (`setup.py` / `pyproject.toml`):**
92
+ ```bash
93
+ # Check auth token exists
94
+ if [ -z "${TWINE_PASSWORD:-}" ] && [ -z "${POETRY_PYPI_TOKEN_PYPI:-}" ]; then
95
+ if [ ! -f ~/.pypirc ]; then
96
+ echo "FAIL: PyPI token not configured. Set TWINE_PASSWORD or create ~/.pypirc"
97
+ exit 1
98
+ fi
99
+ fi
100
+
101
+ # Check for build artifacts
102
+ if [ ! -d dist ] || [ -z "$(ls dist/*.whl 2>/dev/null)" ]; then
103
+ echo "WARNING: No .whl files found in dist/. Run: python -m build"
104
+ fi
105
+ ```
106
+
107
+ ### 3. Run publish
108
+
109
+ After all prerequisite checks pass, run the registry-specific command:
110
+
111
+ ```bash
112
+ # npm
113
+ npm publish --access public
114
+
115
+ # crates.io
116
+ cargo publish
117
+
118
+ # PyPI
119
+ python -m twine upload dist/* # or: poetry publish
120
+
121
+ # Homebrew (opens PR, does not publish directly)
122
+ brew bump-formula-pr --url=<tarball-url> <formula-name>
123
+ ```
124
+
125
+ ### 4. Verify publish success
126
+
127
+ After publish, confirm the version appears on the registry:
128
+
129
+ ```bash
130
+ # npm
131
+ npm view "$PACKAGE_NAME" versions --json 2>/dev/null | grep -q "\"$CURRENT_VER\"" && echo "OK: npm publish confirmed"
132
+
133
+ # crates.io
134
+ cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\"" && echo "OK: crates.io publish confirmed"
135
+
136
+ # PyPI
137
+ pip index versions "$PACKAGE_NAME" 2>/dev/null | grep -q "$CURRENT_VER" && echo "OK: PyPI publish confirmed"
138
+ ```
139
+
140
+ ### 5. Error handling
141
+
142
+ On failure, surface actionable hints:
143
+
144
+ ```bash
145
+ # Generic failure handler
146
+ if [ $? -ne 0 ]; then
147
+ case "$REGISTRY" in
148
+ npm)
149
+ echo "FAIL: npm publish failed."
150
+ echo " Common causes:"
151
+ echo " - NPM_TOKEN not set in secrets: add to GitHub repo secrets"
152
+ echo " - Version already published: bump version in package.json"
153
+ echo " - Two-factor auth required: use --otp=<code> flag"
154
+ echo " - Package scoped but not public: add --access public"
155
+ ;;
156
+ crates.io)
157
+ echo "FAIL: cargo publish failed."
158
+ echo " Common causes:"
159
+ echo " - CARGO_REGISTRY_TOKEN not configured: see ~/.cargo/config.toml"
160
+ echo " - Version already published: bump version in Cargo.toml"
161
+ echo " - Local changes not committed: cargo publish requires clean working tree"
162
+ ;;
163
+ pypi)
164
+ echo "FAIL: PyPI publish failed."
165
+ echo " Common causes:"
166
+ echo " - TWINE_PASSWORD not configured: set env var or ~/.pypirc"
167
+ echo " - Build artifacts missing: run python -m build first"
168
+ echo " - Version conflict: version already exists on PyPI"
169
+ ;;
170
+ esac
171
+ exit 1
172
+ fi
173
+ ```
174
+
175
+ ### 6. Dry-run mode (`--dry-run`)
176
+
177
+ Run `--dry-run` to verify all prerequisites without actually publishing:
178
+
179
+ ```bash
180
+ # Example output
181
+ $ publish-package --dry-run
182
+
183
+ [DRY-RUN] Detected package type: npm
184
+ [DRY-RUN] Package: my-package v0.4.0
185
+ [DRY-RUN] Checking NPM_TOKEN... OK
186
+ [DRY-RUN] Checking version 0.4.0 not already published... OK
187
+ [DRY-RUN] Checking build artifacts... WARNING: package.json modified after build
188
+ [DRY-RUN] Checking CHANGELOG... OK
189
+ [DRY-RUN] Would run: npm publish --access public
190
+ [DRY-RUN] Exiting without publishing.
191
+ ```
192
+
193
+ ### 7. Dry-run mode per registry
194
+
195
+ ```bash
196
+ # npm dry-run
197
+ npm publish --access public --dry-run
198
+
199
+ # crates.io dry-run (cargo does not have a publish dry-run; use --dry-run flag for validation only)
200
+ cargo package --list 2>/dev/null
201
+
202
+ # PyPI dry-run
203
+ python -m twine upload --repository testpypi dist/* # test.pypi.org
204
+ ```
205
+
206
+ ## Options
207
+
208
+ | Flag | Description |
209
+ |------|-------------|
210
+ | `--dry-run` | Verify prerequisites and show publish command without executing |
211
+ | `--registry <type>` | Force registry type (skip auto-detection) |
212
+ | `--otp <code>` | One-time password for npm 2FA |
213
+ | `--no-verify` | Skip prerequisite checks (use with caution) |
214
+
215
+ ## Examples
216
+
217
+ ### Publish an npm package
218
+
219
+ ```bash
220
+ # Verify first
221
+ publish-package --dry-run
222
+
223
+ # Publish
224
+ publish-package
225
+
226
+ # Output:
227
+ # [npm] Publishing my-package v0.4.0...
228
+ # OK: npm publish confirmed (my-package@0.4.0 on registry)
229
+ ```
230
+
231
+ ### Publish a Rust crate
232
+
233
+ ```bash
234
+ export CARGO_REGISTRY_TOKEN=<token>
235
+ publish-package --dry-run
236
+ publish-package
237
+ ```
238
+
239
+ ### Missing token scenario
240
+
241
+ ```bash
242
+ $ publish-package
243
+ FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add to .npmrc
244
+ ```
245
+
246
+ ## Integration with release-branch
247
+
248
+ When wired into `release-branch`, add a step after git push:
249
+
250
+ ```
251
+ 6a. Run publish-package to publish to package registries
252
+ → verify: publish-package --dry-run && publish-package
253
+ ```
254
+
255
+ ## Verify
256
+
257
+ → verify: `test -f publish-package/SKILL.md && echo "OK: skill file exists" || echo "FAIL: no skill file"`
258
+ → verify: `grep -q "name: publish-package" publish-package/SKILL.md && echo "OK: frontmatter" || echo "FAIL: frontmatter"`
259
+ → verify: `grep -ci "npm\|crates.io\|pypi\|publish\|registry" publish-package/SKILL.md | awk '{if($1>=4) print "OK: semantics"; else print "FAIL: missing"}'`
260
+ → verify: `grep -q "publish-package" SKILL-INDEX.md && echo "OK: in SKILL-INDEX" || echo "FAIL: not indexed"`
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: publish-package
3
+ description: "\"Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies prerequisites, runs the publish command, confirms success, and surfaces actionable error hints on failure.\""
4
+ model: sonnet
5
+ ---
6
+
7
+
8
+ # Publish Package
9
+
10
+ > **HARD GATE** — Do not attempt to publish without verifying prerequisites. Missing auth tokens, stale builds, or duplicate versions cause CI failures that are hard to debug post-push.
11
+ >
12
+ > **HARD GATE** — Always run `--dry-run` first. Package registries are append-only — a bad publish cannot be fully undone on most registries.
13
+
14
+ Publish packages to language-specific registries. Detects package type from manifest files, verifies publish prerequisites, runs the registry-specific publish command, and confirms the version appears on the registry.
15
+
16
+ ## Process
17
+
18
+ ### 1. Detect package type
19
+
20
+ Read the project root for manifest files to determine the package type:
21
+
22
+ | Manifest | Registry | Publish command |
23
+ |----------|----------|----------------|
24
+ | `package.json` | npm | `npm publish --access public` |
25
+ | `Cargo.toml` | crates.io | `cargo publish` |
26
+ | `setup.py` / `pyproject.toml` | PyPI | `twine upload dist/*` or `flit publish` |
27
+ | `Formula/<name>.rb` | Homebrew | `brew bump-formula-pr` |
28
+ | Multiple detected | Polyglot | Error: specify registry with `--registry <npm|crates.io|pypi|brew>` |
29
+
30
+ If no manifest is found, prompt the user to specify the type or pass `--type <npm|crates.io|pypi|brew>`.
31
+
32
+ ### 2. Verify prerequisites
33
+
34
+ Before attempting any publish, run all applicable checks:
35
+
36
+ **npm (`package.json`):**
37
+ ```bash
38
+ # Check auth token exists
39
+ if [ -z "${NPM_TOKEN:-}" ]; then
40
+ if [ ! -f ~/.npmrc ] || ! grep -q "_authToken" ~/.npmrc; then
41
+ echo "FAIL: NPM_TOKEN not set. Set via: export NPM_TOKEN=<token> or add //registry.npmjs.org/:_authToken=<token> to .npmrc"
42
+ exit 1
43
+ fi
44
+ fi
45
+
46
+ # Check version not already published
47
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
48
+ CURRENT_VER=$(node -p "require('./package.json').version")
49
+ if npm view "$PACKAGE_NAME@$CURRENT_VER" version 2>/dev/null; then
50
+ echo "FAIL: Version $CURRENT_VER already published for $PACKAGE_NAME. Bump version first."
51
+ exit 1
52
+ fi
53
+
54
+ # Check build artifacts are fresh
55
+ if [ -d dist ] || [ -d lib ]; then
56
+ LATEST_BUILD=$(find dist lib 2>/dev/null -name "*.js" -o -name "*.cjs" -o -name "*.mjs" | xargs ls -t 2>/dev/null | head -1)
57
+ PACKAGE_MODIFIED=$(stat -f %m package.json 2>/dev/null || stat -c %Y package.json 2>/dev/null)
58
+ if [ -n "$LATEST_BUILD" ] && [ -n "$PACKAGE_MODIFIED" ]; then
59
+ BUILD_TIME=$(stat -f %m "$LATEST_BUILD" 2>/dev/null || stat -c %Y "$LATEST_BUILD" 2>/dev/null)
60
+ if [ "$BUILD_TIME" -lt "$PACKAGE_MODIFIED" ]; then
61
+ echo "WARNING: Build artifacts may be stale (package.json modified after last build). Run npm run build first."
62
+ fi
63
+ fi
64
+ fi
65
+
66
+ # Check CHANGELOG is updated
67
+ if [ -f CHANGELOG.md ]; then
68
+ if ! grep -q "$CURRENT_VER" CHANGELOG.md 2>/dev/null; then
69
+ echo "WARNING: Version $CURRENT_VER not found in CHANGELOG.md. Update changelog before publish."
70
+ fi
71
+ fi
72
+ ```
73
+
74
+ **crates.io (`Cargo.toml`):**
75
+ ```bash
76
+ # Check auth token exists
77
+ if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
78
+ if [ ! -f ~/.cargo/config.toml ] || ! grep -q "token" ~/.cargo/config.toml; then
79
+ echo "FAIL: CARGO_REGISTRY_TOKEN not set. Set via: export CARGO_REGISTRY_TOKEN=<token> or add to ~/.cargo/config.toml"
80
+ exit 1
81
+ fi
82
+ fi
83
+
84
+ # Check version not already published
85
+ CRATE_NAME=$(grep '^name' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
86
+ CURRENT_VER=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
87
+ if cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\""; then
88
+ echo "FAIL: Version $CURRENT_VER already published for $CRATE_NAME. Bump version in Cargo.toml first."
89
+ exit 1
90
+ fi
91
+ ```
92
+
93
+ **PyPI (`setup.py` / `pyproject.toml`):**
94
+ ```bash
95
+ # Check auth token exists
96
+ if [ -z "${TWINE_PASSWORD:-}" ] && [ -z "${POETRY_PYPI_TOKEN_PYPI:-}" ]; then
97
+ if [ ! -f ~/.pypirc ]; then
98
+ echo "FAIL: PyPI token not configured. Set TWINE_PASSWORD or create ~/.pypirc"
99
+ exit 1
100
+ fi
101
+ fi
102
+
103
+ # Check for build artifacts
104
+ if [ ! -d dist ] || [ -z "$(ls dist/*.whl 2>/dev/null)" ]; then
105
+ echo "WARNING: No .whl files found in dist/. Run: python -m build"
106
+ fi
107
+ ```
108
+
109
+ ### 3. Run publish
110
+
111
+ After all prerequisite checks pass, run the registry-specific command:
112
+
113
+ ```bash
114
+ # npm
115
+ npm publish --access public
116
+
117
+ # crates.io
118
+ cargo publish
119
+
120
+ # PyPI
121
+ python -m twine upload dist/* # or: poetry publish
122
+
123
+ # Homebrew (opens PR, does not publish directly)
124
+ brew bump-formula-pr --url=<tarball-url> <formula-name>
125
+ ```
126
+
127
+ ### 4. Verify publish success
128
+
129
+ After publish, confirm the version appears on the registry:
130
+
131
+ ```bash
132
+ # npm
133
+ npm view "$PACKAGE_NAME" versions --json 2>/dev/null | grep -q "\"$CURRENT_VER\"" && echo "OK: npm publish confirmed"
134
+
135
+ # crates.io
136
+ cargo search "$CRATE_NAME" 2>/dev/null | grep -q "^${CRATE_NAME}.*\"$CURRENT_VER\"" && echo "OK: crates.io publish confirmed"
137
+
138
+ # PyPI
139
+ pip index versions "$PACKAGE_NAME" 2>/dev/null | grep -q "$CURRENT_VER" && echo "OK: PyPI publish confirmed"
140
+ ```
141
+
142
+ ### 5. Error handling
143
+
144
+ On failure, surface actionable hints:
145
+
146
+ ```bash
147
+ # Generic failure handler
148
+ if [ $? -ne 0 ]; then
149
+ case "$REGISTRY" in
150
+ npm)
151
+ echo "FAIL: npm publish failed."
152
+ echo " Common causes:"
153
+ echo " - NPM_TOKEN not set in secrets: add to GitHub repo secrets"
154
+ echo " - Version already published: bump version in package.json"
155
+ echo " - Two-factor auth required: use --otp=<code> flag"
156
+ echo " - Package scoped but not public: add --access public"
157
+ ;;
158
+ crates.io)
159
+ echo "FAIL: cargo publish failed."
160
+ echo " Common causes:"
161
+ echo " - CARGO_REGISTRY_TOKEN not configured: see ~/.cargo/config.toml"
162
+ echo " - Version already published: bump version in Cargo.toml"
163
+ echo " - Local changes not committed: cargo publish requires clean working tree"
164
+ ;;
165
+ pypi)
166
+ echo "FAIL: PyPI publish failed."
167
+ echo " Common causes:"
168
+ echo " - TWINE_PASSWORD not configured: set env var or ~/.pypirc"
169
+ echo " - Build artifacts missing: run python -m build first"
170
+ echo " - Version conflict: version already exists on PyPI"
171
+ ;;
172
+ esac
173
+ exit 1
174
+ fi
175
+ ```
176
+
177
+ ### 6. Dry-run mode (`--dry-run`)
178
+
179
+ Run `--dry-run` to verify all prerequisites without actually publishing:
180
+
181
+ ```bash
182
+ # Example output
183
+ $ publish-package --dry-run
184
+
185
+ [DRY-RUN] Detected package type: npm
186
+ [DRY-RUN] Package: my-package v0.4.0
187
+ [DRY-RUN] Checking NPM_TOKEN... OK
188
+ [DRY-RUN] Checking version 0.4.0 not already published... OK
189
+ [DRY-RUN] Checking build artifacts... WARNING: package.json modified after build
190
+ [DRY-RUN] Checking CHANGELOG... OK
191
+ [DRY-RUN] Would run: npm publish --access public
192
+ [DRY-RUN] Exiting without publishing.
193
+ ```
194
+
195
+ ### 7. Dry-run mode per registry
196
+
197
+ ```bash
198
+ # npm dry-run
199
+ npm publish --access public --dry-run
200
+
201
+ # crates.io dry-run (cargo does not have a publish dry-run; use --dry-run flag for validation only)
202
+ cargo package --list 2>/dev/null
203
+
204
+ # PyPI dry-run
205
+ python -m twine upload --repository testpypi dist/* # test.pypi.org
206
+ ```
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"`
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [2.9.0](https://github.com/danielvm-git/bigpowers/compare/v2.8.0...v2.9.0) (2026-06-20)
2
+
3
+
4
+ ### Features
5
+
6
+ * **skills:** add publish-package skill for multi-registry publishing ([945a481](https://github.com/danielvm-git/bigpowers/commit/945a481cef07335c59277c82137e4a6bec78655a))
7
+
1
8
  # [2.8.0](https://github.com/danielvm-git/bigpowers/compare/v2.7.5...v2.8.0) (2026-06-20)
2
9
 
3
10
 
package/SKILL-INDEX.md CHANGED
@@ -3,8 +3,8 @@
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:22:23Z
7
- **Skills:** 63
6
+ **Generated:** 2026-06-20T21:29:33Z
7
+ **Skills:** 64
8
8
 
9
9
  ---
10
10
 
@@ -15,11 +15,11 @@
15
15
  | Discover | 6 | `elaborate-spec, map-codebase, research-first, search-skills, survey-context, using-bigpowers` |
16
16
  | Design | 7 | `deepen-architecture, define-language, define-success, design-interface, grill-me, grill-with-docs, model-domain` |
17
17
  | Plan | 9 | `assess-impact, change-request, plan-refactor, plan-release, plan-work, run-planning, scope-work, seed-conventions, slice-tasks` |
18
- | Build | 13 | `align-grid, build-epic, craft-skill, develop-tdd, execute-plan, guard-git, hook-commits, kickoff-branch, orchestrate-project, setup-environment, spike-prototype, wire-ci, wire-observability` |
18
+ | Build | 14 | `align-grid, build-epic, craft-skill, develop-tdd, execute-plan, guard-git, hook-commits, kickoff-branch, orchestrate-project, publish-package, setup-environment, spike-prototype, wire-ci, wire-observability` |
19
19
  | Verify | 12 | `audit-code, diagnose-root, enforce-first, fix-bug, inspect-quality, investigate-bug, request-review, respond-review, run-evals, trace-requirement, validate-fix, verify-work` |
20
20
  | Release | 2 | `commit-message, release-branch` |
21
21
  | Sustain | 13 | `compose-workflow, delegate-task, dispatch-agents, edit-document, evolve-skill, migrate-spec, organize-workspace, reset-baseline, session-state, simulate-agents, stocktake-skills, terse-mode, write-document` |
22
- | **TOTAL** | **62** | |
22
+ | **TOTAL** | **63** | |
23
23
 
24
24
  ---
25
25
 
@@ -58,39 +58,40 @@
58
58
  | 29 | Build | `hook-commits` | Set up pre-commit hooks with lint-staged (Prettier), type checking, and tests in | ✅ Active |
59
59
  | 30 | Build | `kickoff-branch` | Create a git worktree and feature branch, then verify a clean test baseline befo | ✅ Active |
60
60
  | 31 | Build | `orchestrate-project` | Meta-skill that enforces the 6-phase core loop (discover → elaborate → plan | ✅ Active |
61
- | 32 | Build | `setup-environment` | Pre-install dependencies and configure tools before development work begins. Use | ✅ Active |
62
- | 33 | Build | `spike-prototype` | Throw-away prototype for unknown problem spaces. Output is learning notes in spe | ✅ Active |
63
- | 34 | Build | `wire-ci` | "CI pipeline setup with pre-built templates and local validation. Generates GitH | ✅ Active |
64
- | 35 | Build | `wire-observability` | Add structured JSON logging, observability commands, and idempotent setup script | ✅ Active |
65
- | 36 | Verify | `audit-code` | Self-review checklist for the coding agent to run before dispatching a reviewer. | ✅ Active |
66
- | 37 | Verify | `diagnose-root` | Run 4-phase root cause analysis reproduce, isolate, hypothesize, verify. Use | ✅ Active |
67
- | 38 | Verify | `enforce-first` | Apply the F.I.R.S.T test quality rubric (Fast, Independent, Repeatable, Self-Val | ✅ Active |
68
- | 39 | Verify | `fix-bug` | Bug fix orchestrator active_flow fix_bug; reads specs/bugs/BUG-*.md; chains | ✅ Active |
69
- | 40 | Verify | `inspect-quality` | Interactive QA session where user reports bugs or issues conversationally, and t | ✅ Active |
70
- | 41 | Verify | `investigate-bug` | Investigate a bug or issue by exploring the codebase to find root cause, then wr | ✅ Active |
71
- | 42 | Verify | `request-review` | Dispatch a fresh reviewer agent with a clean context to critique the code after | ✅ Active |
72
- | 43 | Verify | `respond-review` | Act on a reviewer agent's feedback systematically categorize findings, apply | ✅ Active |
73
- | 44 | Verify | `run-evals` | Eval-Driven Development define capability and regression evals before buildi | ✅ Active |
74
- | 45 | Verify | `trace-requirement` | Link story IDs from specs/release-plan.yaml + epic capsule directories to the im | ✅ Active |
75
- | 46 | Verify | `validate-fix` | Prove a fix works before declaring done re-run the failing test, run the ful | ✅ Active |
76
- | 47 | Verify | `verify-work` | Multi-phase UAT gatecold-start smoke, build, typecheck, lint, tests, step-b | ✅ Active |
77
- | 48 | Release | `commit-message` | Reviews working-tree changes, then drafts a Conventional Commits title/body and | ✅ Active |
78
- | 49 | Release | `release-branch` | Make the merge/PR/keep/discard decision for a feature branch, verify coverage ga | ✅ Active |
79
- | 50 | Sustain | `compose-workflow` | Chain multiple bigpowers skills into a custom workflow recipe saved in specs/. U | ✅ Active |
80
- | 51 | Sustain | `delegate-task` | Delegate one complex task to a single subagent, review its work in two stages be | ✅ Active |
81
- | 52 | Sustain | `dispatch-agents` | Dispatch multiple subagents in parallel on independent tasks. No waiting between | ✅ Active |
82
- | 53 | Sustain | `edit-document` | Edit and improve documents by restructuring sections, improving clarity, and tig | ✅ Active |
83
- | 54 | Sustain | `evolve-skill` | Benchmark-gated skill evolution consume bigpowers-benchmark report, propose | ✅ Active |
84
- | 55 | Sustain | `migrate-spec` | Detect GSD, spec-kit, or BMAD spec artifacts and transform them into bigpowers Y | ✅ Active |
85
- | 56 | Sustain | `organize-workspace` | Scans the active workspace for disposable artifacts—logs, caches, stale build | ✅ Active |
86
- | 57 | Sustain | `reset-baseline` | Restore the project to a known clean state between agent runs or experiments. Us | ✅ Active |
87
- | 58 | Sustain | `session-state` | Track implementation decisions and progress in specs/state.yaml to prevent conte | ✅ Active |
88
- | 59 | Sustain | `simulate-agents` | Run Mock User and Auditor agents against a feature in fresh contexts before huma | ✅ Active |
89
- | 60 | Sustain | `stocktake-skills` | Sequential subagent batch audit of the bigpowers skill catalog Quick Scan (c | ✅ Active |
90
- | 61 | Sustain | `terse-mode` | Fallback ultra-compressed communication mode. Cuts token usage ~75% by dropping | ✅ Active |
91
- | 62 | Sustain | `write-document` | Write, organize, and sync high-integrity technical documents using the BMAD meth | ✅ Active |
92
-
93
- **Total: 62 active skills.**
61
+ | 32 | Build | `publish-package` | "Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies pr | ✅ Active |
62
+ | 33 | Build | `setup-environment` | Pre-install dependencies and configure tools before development work begins. Use | ✅ Active |
63
+ | 34 | Build | `spike-prototype` | Throw-away prototype for unknown problem spaces. Output is learning notes in spe | ✅ Active |
64
+ | 35 | Build | `wire-ci` | "CI pipeline setup with pre-built templates and local validation. Generates GitH | ✅ Active |
65
+ | 36 | Build | `wire-observability` | Add structured JSON logging, observability commands, and idempotent setup script | ✅ Active |
66
+ | 37 | Verify | `audit-code` | Self-review checklist for the coding agent to run before dispatching a reviewer. | ✅ Active |
67
+ | 38 | Verify | `diagnose-root` | Run 4-phase root cause analysis reproduce, isolate, hypothesize, verify. Use | ✅ Active |
68
+ | 39 | Verify | `enforce-first` | Apply the F.I.R.S.T test quality rubric (Fast, Independent, Repeatable, Self-Val | ✅ Active |
69
+ | 40 | Verify | `fix-bug` | Bug fix orchestrator active_flow fix_bug; reads specs/bugs/BUG-*.md; chains | ✅ Active |
70
+ | 41 | Verify | `inspect-quality` | Interactive QA session where user reports bugs or issues conversationally, and t | ✅ Active |
71
+ | 42 | Verify | `investigate-bug` | Investigate a bug or issue by exploring the codebase to find root cause, then wr | ✅ Active |
72
+ | 43 | Verify | `request-review` | Dispatch a fresh reviewer agent with a clean context to critique the code after | ✅ Active |
73
+ | 44 | Verify | `respond-review` | Act on a reviewer agent's feedback systematically categorize findings, apply | ✅ Active |
74
+ | 45 | Verify | `run-evals` | Eval-Driven Development define capability and regression evals before buildi | ✅ Active |
75
+ | 46 | Verify | `trace-requirement` | Link story IDs from specs/release-plan.yaml + epic capsule directories to the im | ✅ Active |
76
+ | 47 | Verify | `validate-fix` | Prove a fix works before declaring done re-run the failing test, run the ful | ✅ Active |
77
+ | 48 | Verify | `verify-work` | Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-b | ✅ Active |
78
+ | 49 | Release | `commit-message` | Reviews working-tree changes, then drafts a Conventional Commits title/body and | ✅ Active |
79
+ | 50 | Release | `release-branch` | Make the merge/PR/keep/discard decision for a feature branch, verify coverage ga | ✅ Active |
80
+ | 51 | Sustain | `compose-workflow` | Chain multiple bigpowers skills into a custom workflow recipe saved in specs/. U | ✅ Active |
81
+ | 52 | Sustain | `delegate-task` | Delegate one complex task to a single subagent, review its work in two stages be | ✅ Active |
82
+ | 53 | Sustain | `dispatch-agents` | Dispatch multiple subagents in parallel on independent tasks. No waiting between | ✅ Active |
83
+ | 54 | Sustain | `edit-document` | Edit and improve documents by restructuring sections, improving clarity, and tig | ✅ Active |
84
+ | 55 | Sustain | `evolve-skill` | Benchmark-gated skill evolution consume bigpowers-benchmark report, propose | ✅ Active |
85
+ | 56 | Sustain | `migrate-spec` | Detect GSD, spec-kit, or BMAD spec artifacts and transform them into bigpowers Y | ✅ Active |
86
+ | 57 | Sustain | `organize-workspace` | Scans the active workspace for disposable artifacts—logs, caches, stale build | ✅ Active |
87
+ | 58 | Sustain | `reset-baseline` | Restore the project to a known clean state between agent runs or experiments. Us | ✅ Active |
88
+ | 59 | Sustain | `session-state` | Track implementation decisions and progress in specs/state.yaml to prevent conte | ✅ Active |
89
+ | 60 | Sustain | `simulate-agents` | Run Mock User and Auditor agents against a feature in fresh contexts before huma | ✅ Active |
90
+ | 61 | Sustain | `stocktake-skills` | Sequential subagent batch audit of the bigpowers skill catalog — Quick Scan (c | ✅ Active |
91
+ | 62 | Sustain | `terse-mode` | Fallback ultra-compressed communication mode. Cuts token usage ~75% by dropping | ✅ Active |
92
+ | 63 | Sustain | `write-document` | Write, organize, and sync high-integrity technical documents using the BMAD meth | ✅ Active |
93
+
94
+ **Total: 63 active skills.**
94
95
 
95
96
  ---
96
97
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
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,261 @@
1
+ ---
2
+ name: publish-package
3
+ description: "Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies prerequisites, runs the publish command, confirms success, and surfaces actionable error hints on failure."
4
+ model: sonnet
5
+ ---
6
+
7
+ # Publish Package
8
+
9
+ > **HARD GATE** — Do not attempt to publish without verifying prerequisites. Missing auth tokens, stale builds, or duplicate versions cause CI failures that are hard to debug post-push.
10
+ >
11
+ > **HARD GATE** — Always run `--dry-run` first. Package registries are append-only — a bad publish cannot be fully undone on most registries.
12
+
13
+ Publish packages to language-specific registries. Detects package type from manifest files, verifies publish prerequisites, runs the registry-specific publish command, and confirms the version appears on the registry.
14
+
15
+ ## Process
16
+
17
+ ### 1. Detect package type
18
+
19
+ Read the project root for manifest files to determine the package type:
20
+
21
+ | Manifest | Registry | Publish command |
22
+ |----------|----------|----------------|
23
+ | `package.json` | npm | `npm publish --access public` |
24
+ | `Cargo.toml` | crates.io | `cargo publish` |
25
+ | `setup.py` / `pyproject.toml` | PyPI | `twine upload dist/*` or `flit publish` |
26
+ | `Formula/<name>.rb` | Homebrew | `brew bump-formula-pr` |
27
+ | Multiple detected | Polyglot | Error: specify registry with `--registry <npm|crates.io|pypi|brew>` |
28
+
29
+ If no manifest is found, prompt the user to specify the type or pass `--type <npm|crates.io|pypi|brew>`.
30
+
31
+ ### 2. Verify prerequisites
32
+
33
+ Before attempting any publish, run all applicable checks:
34
+
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
+ ```
72
+
73
+ **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
+ ```
91
+
92
+ **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
+ ```
107
+
108
+ ### 3. Run publish
109
+
110
+ After all prerequisite checks pass, run the registry-specific command:
111
+
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
+ ```
125
+
126
+ ### 4. Verify publish success
127
+
128
+ After publish, confirm the version appears on the registry:
129
+
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
+ ```
140
+
141
+ ### 5. Error handling
142
+
143
+ On failure, surface actionable hints:
144
+
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
+ ```
175
+
176
+ ### 6. Dry-run mode (`--dry-run`)
177
+
178
+ Run `--dry-run` to verify all prerequisites without actually publishing:
179
+
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
+ ```
193
+
194
+ ### 7. Dry-run mode per registry
195
+
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
+ ```
255
+
256
+ ## Verify
257
+
258
+ → verify: `test -f publish-package/SKILL.md && echo "OK: skill file exists" || echo "FAIL: no skill file"`
259
+ → verify: `grep -q "name: publish-package" publish-package/SKILL.md && echo "OK: frontmatter" || echo "FAIL: frontmatter"`
260
+ → verify: `grep -ci "npm\|crates.io\|pypi\|publish\|registry" publish-package/SKILL.md | awk '{if($1>=4) print "OK: semantics"; else print "FAIL: missing"}'`
261
+ → verify: `grep -q "publish-package" SKILL-INDEX.md && echo "OK: in SKILL-INDEX" || echo "FAIL: not indexed"`
@@ -51,6 +51,7 @@ PHASE_MAP=(
51
51
  [setup-environment]="Build"
52
52
  [wire-observability]="Build"
53
53
  [wire-ci]="Build"
54
+ [publish-package]="Build"
54
55
  [align-grid]="Build"
55
56
  [orchestrate-project]="Build"
56
57
  [guard-git]="Build"
package/skills-lock.json CHANGED
@@ -186,6 +186,11 @@
186
186
  "sha256": "12d45efb07a36e94",
187
187
  "path": "plan-work/SKILL.md"
188
188
  },
189
+ "publish-package": {
190
+ "description": "\"Package registry publishing for npm, crates.io, PyPI, and Homebrew. Verifies prerequisites, runs the publish command, confirms success, and surfaces actionable error hints on failure.\"",
191
+ "sha256": "25ead1dd4d174d54",
192
+ "path": "publish-package/SKILL.md"
193
+ },
189
194
  "release-branch": {
190
195
  "description": "Make the merge/PR/keep/discard decision for a feature branch, verify coverage gates, create the PR with gh, and clean up the worktree. Use when a feature is done and ready to ship, or when user says \"release\", \"merge\", or \"open a PR\".",
191
196
  "sha256": "70fc37ac4e22143d",