@slamb2k/mad-skills 2.0.51 → 2.0.54
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/.claude-plugin/plugin.json +1 -1
- package/package.json +5 -2
- package/references/azdo-cli-reference.md +342 -0
- package/references/azdo-platform.md +88 -0
- package/references/superpowers-deferral.md +51 -0
- package/scripts/lib/frontmatter.js +33 -0
- package/scripts/lib/superpowers.js +61 -0
- package/scripts/lib/superpowers.test.js +76 -0
- package/skills/brace/SKILL.md +6 -0
- package/skills/brace/references/claude-md-template.md +10 -0
- package/skills/build/SKILL.md +12 -0
- package/skills/build/tests/evals.json +16 -0
- package/skills/manifest.json +6 -6
- package/skills/prime/SKILL.md +17 -0
- package/skills/prime/tests/evals.json +9 -0
- package/skills/ship/SKILL.md +4 -0
- package/skills/ship/tests/evals.json +16 -0
- package/skills/speccy/SKILL.md +15 -0
- package/skills/speccy/tests/evals.json +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slamb2k/mad-skills",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.54",
|
|
4
4
|
"description": "Claude Code skills collection — full lifecycle development tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
"skills/",
|
|
12
12
|
"agents/",
|
|
13
13
|
"hooks/",
|
|
14
|
+
"scripts/lib/",
|
|
15
|
+
"references/",
|
|
14
16
|
".claude-plugin/"
|
|
15
17
|
],
|
|
16
18
|
"scripts": {
|
|
@@ -22,7 +24,8 @@
|
|
|
22
24
|
"build:skills": "node scripts/package-skills.js",
|
|
23
25
|
"build": "npm run build:manifests && npm run build:skills",
|
|
24
26
|
"prepublishOnly": "npm run validate && npm run build:manifests",
|
|
25
|
-
"test": "
|
|
27
|
+
"test:unit": "node --test scripts/lib/superpowers.test.js",
|
|
28
|
+
"test": "npm run validate && npm run lint && npm run test:unit && npm run eval"
|
|
26
29
|
},
|
|
27
30
|
"keywords": [
|
|
28
31
|
"claude",
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# Azure DevOps CLI Reference for Claude Code
|
|
2
|
+
|
|
3
|
+
This document provides guidance for LLM agents constructing Azure DevOps CLI
|
|
4
|
+
commands. It addresses common pitfalls, inconsistent flag support across
|
|
5
|
+
subcommands, and REST API authentication patterns.
|
|
6
|
+
|
|
7
|
+
## Critical: `--project` Flag Is NOT Universal
|
|
8
|
+
|
|
9
|
+
The `--project` flag is **only supported by some `az devops` subcommands**.
|
|
10
|
+
Using it where it is not supported produces `ERROR: unrecognized arguments`.
|
|
11
|
+
|
|
12
|
+
### Commands that accept `--project`
|
|
13
|
+
|
|
14
|
+
| Command | `--project` | Notes |
|
|
15
|
+
|---------|------------|-------|
|
|
16
|
+
| `az repos pr create` | YES | Required if not configured via defaults |
|
|
17
|
+
| `az repos pr list` | YES | Filters by project |
|
|
18
|
+
| `az pipelines list` | YES | |
|
|
19
|
+
| `az pipelines runs list` | YES | |
|
|
20
|
+
| `az pipelines run` | YES | Queue a new run |
|
|
21
|
+
| `az repos policy list` | YES | |
|
|
22
|
+
|
|
23
|
+
### Commands that DO NOT accept `--project`
|
|
24
|
+
|
|
25
|
+
| Command | `--project` | Use instead |
|
|
26
|
+
|---------|------------|------------|
|
|
27
|
+
| `az repos pr update` | NO | `--org` only, or configure defaults |
|
|
28
|
+
| `az repos pr show` | NO | `--org` only, or configure defaults |
|
|
29
|
+
| `az devops invoke` | NO | Pass project in `--route-parameters` |
|
|
30
|
+
|
|
31
|
+
### Safe pattern
|
|
32
|
+
|
|
33
|
+
Always configure defaults at the start of a session, then omit `--project`
|
|
34
|
+
from commands that don't support it:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
az devops configure --defaults \
|
|
38
|
+
organization="$AZDO_ORG_URL" \
|
|
39
|
+
project="$AZDO_PROJECT"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After this, commands that support `--project` will use the default, and
|
|
43
|
+
commands that don't (like `pr update` and `pr show`) will detect the project
|
|
44
|
+
from the `--org` URL or the PR ID.
|
|
45
|
+
|
|
46
|
+
For `az devops invoke`, pass the project via route parameters:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
az devops invoke \
|
|
50
|
+
--area build --resource timeline \
|
|
51
|
+
--route-parameters buildId=12345 project="$AZDO_PROJECT" \
|
|
52
|
+
--org "$AZDO_ORG_URL" -o json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## PR Merge Pattern
|
|
58
|
+
|
|
59
|
+
The correct command to squash-merge a PR:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
az repos pr update \
|
|
63
|
+
--id "$PR_NUMBER" \
|
|
64
|
+
--status completed \
|
|
65
|
+
--squash true \
|
|
66
|
+
--delete-source-branch true \
|
|
67
|
+
--merge-commit-message "commit message here" \
|
|
68
|
+
--org "$AZDO_ORG_URL"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If the PR has branch policies that haven't been satisfied (e.g., no CI checks
|
|
72
|
+
registered, no required reviewers), add:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
--bypass-policy true \
|
|
76
|
+
--bypass-policy-reason "Reason for bypass"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Important:** After calling `pr update --status completed`, the merge may be
|
|
80
|
+
asynchronous. Poll with:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
az repos pr show --id "$PR_NUMBER" --query status -o tsv --org "$AZDO_ORG_URL"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Expected result: `completed`. If still `active`, wait 5-10 seconds and retry.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## CI Pipeline Monitoring
|
|
91
|
+
|
|
92
|
+
### Branch name mismatch
|
|
93
|
+
|
|
94
|
+
Azure DevOps PR builds have `sourceBranch` set to `refs/pull/<N>/merge`, NOT
|
|
95
|
+
the feature branch name. When listing runs for a PR:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# WRONG — will return no results
|
|
99
|
+
az pipelines runs list --branch "feat/my-feature" ...
|
|
100
|
+
|
|
101
|
+
# CORRECT — match the PR merge ref
|
|
102
|
+
az pipelines runs list --branch "refs/pull/$PR_NUMBER/merge" \
|
|
103
|
+
--org "$AZDO_ORG_URL" --project "$AZDO_PROJECT" \
|
|
104
|
+
--top 1 -o json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Alternatively, list without branch filter and filter in `jq`:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
az pipelines runs list --top 10 \
|
|
111
|
+
--org "$AZDO_ORG_URL" --project "$AZDO_PROJECT" -o json \
|
|
112
|
+
| jq "[.[] | select(.sourceBranch == \"refs/pull/$PR_NUMBER/merge\")]"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Polling for completion
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
RESULT=$(az pipelines runs show --id "$RUN_ID" \
|
|
119
|
+
--org "$AZDO_ORG_URL" --project "$AZDO_PROJECT" \
|
|
120
|
+
--query result -o tsv)
|
|
121
|
+
|
|
122
|
+
# RESULT is one of: succeeded, failed, canceled, (empty if still running)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Getting failed job details
|
|
126
|
+
|
|
127
|
+
Use the timeline API to find which jobs/steps failed:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
az devops invoke \
|
|
131
|
+
--area build --resource timeline \
|
|
132
|
+
--route-parameters buildId="$RUN_ID" project="$AZDO_PROJECT" \
|
|
133
|
+
--org "$AZDO_ORG_URL" -o json \
|
|
134
|
+
| jq '[.records[] | select(.result=="failed") | {name, type}]'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
To get log output from a failed step, extract the log URL from the timeline
|
|
138
|
+
record and fetch it with `curl` using PAT auth (see REST API section below).
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## URL Formats and Org Detection
|
|
143
|
+
|
|
144
|
+
Azure DevOps has two URL formats. Both are valid, but REST API calls via
|
|
145
|
+
`curl` may only work with one depending on org configuration.
|
|
146
|
+
|
|
147
|
+
| Format | Example |
|
|
148
|
+
|--------|---------|
|
|
149
|
+
| Modern | `https://dev.azure.com/{ORG}/{PROJECT}/_git/{REPO}` |
|
|
150
|
+
| Legacy | `https://{ORG}.visualstudio.com/{PROJECT}/_git/{REPO}` |
|
|
151
|
+
| SSH | `{ORG}@vs-ssh.visualstudio.com:v3/{ORG}/{PROJECT}/{REPO}` |
|
|
152
|
+
|
|
153
|
+
### Preserve the original URL format
|
|
154
|
+
|
|
155
|
+
When the remote uses `visualstudio.com`, keep that format for REST API calls.
|
|
156
|
+
Do NOT normalize to `dev.azure.com` — some legacy organizations only respond
|
|
157
|
+
to the original domain.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
|
|
161
|
+
|
|
162
|
+
if echo "$REMOTE_URL" | grep -q 'dev\.azure\.com'; then
|
|
163
|
+
AZDO_ORG=$(echo "$REMOTE_URL" | sed -n 's|.*dev\.azure\.com/\([^/]*\)/.*|\1|p')
|
|
164
|
+
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
165
|
+
elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
166
|
+
AZDO_ORG=$(echo "$REMOTE_URL" | sed -n 's|.*//\([^.]*\)\.visualstudio\.com.*|\1|p')
|
|
167
|
+
# Keep the original domain for REST API compatibility
|
|
168
|
+
AZDO_ORG_URL="https://${AZDO_ORG}.visualstudio.com"
|
|
169
|
+
fi
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### URL-decoding project names
|
|
173
|
+
|
|
174
|
+
Project names with spaces are URL-encoded in remote URLs (e.g.,
|
|
175
|
+
`Velrada%20AI%20Agents`). The common `printf '%b'` approach fails when
|
|
176
|
+
`%20` is followed by hex characters (A-F, 0-9):
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# BROKEN — fails on "Velrada%20AI%20Agents" (interprets %20A as \x20A)
|
|
180
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
181
|
+
|
|
182
|
+
# CORRECT — use Python for reliable URL decoding
|
|
183
|
+
AZDO_PROJECT=$(python3 -c "import urllib.parse; print(urllib.parse.unquote('$AZDO_PROJECT_URL_SAFE'))")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Keep both the URL-safe and decoded versions:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
AZDO_PROJECT_URL_SAFE="Velrada%20AI%20Agents" # for REST API URL paths
|
|
190
|
+
AZDO_PROJECT="Velrada AI Agents" # for CLI --project flags
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## REST API via `curl`
|
|
196
|
+
|
|
197
|
+
### Authentication
|
|
198
|
+
|
|
199
|
+
Use the `AZURE_DEVOPS_EXT_PAT` environment variable (this is the standard env
|
|
200
|
+
var that `az devops login` also reads):
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
TOKEN=$(printf ":%s" "$AZURE_DEVOPS_EXT_PAT" | base64 -w0)
|
|
204
|
+
AUTH="Authorization: Basic $TOKEN"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### DO NOT use `az rest` for Azure DevOps
|
|
208
|
+
|
|
209
|
+
`az rest` is designed for Azure Resource Manager (ARM) APIs. It cannot
|
|
210
|
+
automatically derive the correct Azure AD resource for Azure DevOps endpoints.
|
|
211
|
+
Even with `--resource "499b84ac-1321-427f-aa17-267ca6975798"` (the Azure DevOps
|
|
212
|
+
resource ID), it often fails for legacy organizations.
|
|
213
|
+
|
|
214
|
+
**Always use `curl` with PAT-based Basic auth for Azure DevOps REST APIs.**
|
|
215
|
+
|
|
216
|
+
### Common REST API patterns
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Build timeline (get failed steps)
|
|
220
|
+
curl -s -H "$AUTH" \
|
|
221
|
+
"${AZDO_ORG_URL}/${AZDO_PROJECT_URL_SAFE}/_apis/build/builds/${BUILD_ID}/timeline?api-version=7.1"
|
|
222
|
+
|
|
223
|
+
# Build logs (get log content for a specific log ID)
|
|
224
|
+
curl -s -H "$AUTH" \
|
|
225
|
+
"${AZDO_ORG_URL}/${AZDO_PROJECT_URL_SAFE}/_apis/build/builds/${BUILD_ID}/logs/${LOG_ID}?api-version=7.1"
|
|
226
|
+
|
|
227
|
+
# PR details
|
|
228
|
+
curl -s -H "$AUTH" \
|
|
229
|
+
"${AZDO_ORG_URL}/${AZDO_PROJECT_URL_SAFE}/_apis/git/repositories/${REPO_NAME}/pullRequests/${PR_NUMBER}?api-version=7.1"
|
|
230
|
+
|
|
231
|
+
# Complete a PR (REST fallback)
|
|
232
|
+
curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
|
|
233
|
+
"${AZDO_ORG_URL}/${AZDO_PROJECT_URL_SAFE}/_apis/git/repositories/${REPO_NAME}/pullRequests/${PR_NUMBER}?api-version=7.1" \
|
|
234
|
+
-d '{
|
|
235
|
+
"status": "completed",
|
|
236
|
+
"completionOptions": {
|
|
237
|
+
"squashMerge": true,
|
|
238
|
+
"deleteSourceBranch": true,
|
|
239
|
+
"mergeCommitMessage": "commit message"
|
|
240
|
+
}
|
|
241
|
+
}'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## JSON Safety: Validate Before Piping to `jq`
|
|
247
|
+
|
|
248
|
+
Azure CLI commands can output warnings, error messages, or HTML instead of
|
|
249
|
+
JSON. Always validate before piping:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Pattern 1: Capture output, validate, then parse
|
|
253
|
+
OUTPUT=$(az pipelines runs show --id "$RUN_ID" --org "$AZDO_ORG_URL" -o json 2>&1)
|
|
254
|
+
if echo "$OUTPUT" | jq empty 2>/dev/null; then
|
|
255
|
+
echo "$OUTPUT" | jq '.result'
|
|
256
|
+
else
|
|
257
|
+
echo "ERROR: Non-JSON response: $OUTPUT" >&2
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# Pattern 2: Use --output json and redirect stderr
|
|
261
|
+
RESULT=$(az repos pr show --id "$PR_NUMBER" --query status -o tsv 2>/dev/null)
|
|
262
|
+
|
|
263
|
+
# Pattern 3: For curl, check HTTP status
|
|
264
|
+
HTTP_CODE=$(curl -s -o /tmp/response.json -w "%{http_code}" -H "$AUTH" "$URL")
|
|
265
|
+
if [ "$HTTP_CODE" = "200" ]; then
|
|
266
|
+
jq '.' /tmp/response.json
|
|
267
|
+
else
|
|
268
|
+
echo "ERROR: HTTP $HTTP_CODE" >&2
|
|
269
|
+
fi
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Never swallow stderr with `2>/dev/null` on commands that might fail.**
|
|
273
|
+
Capture stderr to a variable instead:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
OUTPUT=$(az repos pr update --id "$PR_NUMBER" --status completed 2>&1)
|
|
277
|
+
EXIT_CODE=$?
|
|
278
|
+
if [ $EXIT_CODE -ne 0 ]; then
|
|
279
|
+
echo "MERGE FAILED: $OUTPUT" >&2
|
|
280
|
+
fi
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Quick Reference: Common Operations
|
|
286
|
+
|
|
287
|
+
### Create PR
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
az repos pr create \
|
|
291
|
+
--title "feat: description" \
|
|
292
|
+
--description "## Summary ..." \
|
|
293
|
+
--source-branch "$BRANCH" \
|
|
294
|
+
--target-branch main \
|
|
295
|
+
--org "$AZDO_ORG_URL" \
|
|
296
|
+
--project "$AZDO_PROJECT" \
|
|
297
|
+
--output json
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### List runs for a PR
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
az pipelines runs list \
|
|
304
|
+
--branch "refs/pull/$PR_NUMBER/merge" \
|
|
305
|
+
--top 1 \
|
|
306
|
+
--org "$AZDO_ORG_URL" \
|
|
307
|
+
--project "$AZDO_PROJECT" \
|
|
308
|
+
-o json
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Queue a pipeline run
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
az pipelines run \
|
|
315
|
+
--id "$PIPELINE_ID" \
|
|
316
|
+
--branch "$BRANCH" \
|
|
317
|
+
--org "$AZDO_ORG_URL" \
|
|
318
|
+
--project "$AZDO_PROJECT" \
|
|
319
|
+
-o json
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Complete (merge) a PR
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
az repos pr update \
|
|
326
|
+
--id "$PR_NUMBER" \
|
|
327
|
+
--status completed \
|
|
328
|
+
--squash true \
|
|
329
|
+
--delete-source-branch true \
|
|
330
|
+
--merge-commit-message "message" \
|
|
331
|
+
--org "$AZDO_ORG_URL"
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Check PR status
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
az repos pr show \
|
|
338
|
+
--id "$PR_NUMBER" \
|
|
339
|
+
--query status \
|
|
340
|
+
-o tsv \
|
|
341
|
+
--org "$AZDO_ORG_URL"
|
|
342
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Azure DevOps Platform Support
|
|
2
|
+
|
|
3
|
+
Shared procedures for AzDO tooling detection and configuration validation.
|
|
4
|
+
Referenced by SKILL.md during pre-flight when `PLATFORM == azdo`.
|
|
5
|
+
|
|
6
|
+
## AzDO Tooling Detection
|
|
7
|
+
|
|
8
|
+
When `PLATFORM == azdo`, determine which tooling is available. Set `AZDO_MODE`
|
|
9
|
+
for use in all subsequent phases:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
if az devops -h &>/dev/null; then
|
|
13
|
+
AZDO_MODE="cli"
|
|
14
|
+
else
|
|
15
|
+
AZDO_MODE="rest"
|
|
16
|
+
fi
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **`cli`**: Use `az repos` / `az pipelines` commands (preferred)
|
|
20
|
+
- **`rest`**: Use Azure DevOps REST API via `curl`. Requires a PAT (personal
|
|
21
|
+
access token) in `AZURE_DEVOPS_EXT_PAT` or `AZDO_PAT` env var. If no PAT
|
|
22
|
+
is found, prompt the user to either install the CLI or set the env var.
|
|
23
|
+
|
|
24
|
+
Report in pre-flight:
|
|
25
|
+
- ✅ `az devops cli` — version found
|
|
26
|
+
- ⚠️ `az devops cli` — not found → using REST API fallback
|
|
27
|
+
- ❌ `az devops cli` — not found, no PAT configured → halt with setup instructions
|
|
28
|
+
|
|
29
|
+
## AzDO Configuration Validation
|
|
30
|
+
|
|
31
|
+
When `PLATFORM == azdo`, extract organization and project from the remote URL
|
|
32
|
+
and validate they are usable. These values are needed by every `az repos` /
|
|
33
|
+
`az pipelines` command and every REST API call.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Extract org and project from remote URL patterns:
|
|
37
|
+
# https://dev.azure.com/{ORG}/{PROJECT}/_git/{REPO}
|
|
38
|
+
# https://{ORG}@dev.azure.com/{ORG}/{PROJECT}/_git/{REPO}
|
|
39
|
+
# {ORG}@vs-ssh.visualstudio.com:v3/{ORG}/{PROJECT}/{REPO}
|
|
40
|
+
|
|
41
|
+
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
|
|
42
|
+
|
|
43
|
+
if echo "$REMOTE_URL" | grep -q 'dev\.azure\.com'; then
|
|
44
|
+
AZDO_ORG=$(echo "$REMOTE_URL" | sed -n 's|.*dev\.azure\.com/\([^/]*\)/.*|\1|p')
|
|
45
|
+
AZDO_PROJECT=$(echo "$REMOTE_URL" | sed -n 's|.*dev\.azure\.com/[^/]*/\([^/]*\)/.*|\1|p')
|
|
46
|
+
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
47
|
+
elif echo "$REMOTE_URL" | grep -q 'vs-ssh\.visualstudio\.com'; then
|
|
48
|
+
AZDO_ORG=$(echo "$REMOTE_URL" | sed -n 's|.*vs-ssh\.visualstudio\.com:v3/\([^/]*\)/.*|\1|p')
|
|
49
|
+
AZDO_PROJECT=$(echo "$REMOTE_URL" | sed -n 's|.*vs-ssh\.visualstudio\.com:v3/[^/]*/\([^/]*\)/.*|\1|p')
|
|
50
|
+
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
51
|
+
elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
52
|
+
AZDO_ORG=$(echo "$REMOTE_URL" | sed -n 's|.*//\([^.]*\)\.visualstudio\.com.*|\1|p')
|
|
53
|
+
AZDO_PROJECT=$(echo "$REMOTE_URL" | sed -n 's|.*/\([^/]*\)/_git/.*|\1|p')
|
|
54
|
+
# Preserve the original domain for REST API compatibility
|
|
55
|
+
AZDO_ORG_URL="https://${AZDO_ORG}.visualstudio.com"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
59
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
60
|
+
AZDO_PROJECT=$(python3 -c "import urllib.parse; print(urllib.parse.unquote('$AZDO_PROJECT'))")
|
|
61
|
+
|
|
62
|
+
if [ -z "$AZDO_ORG" ] || [ -z "$AZDO_PROJECT" ]; then
|
|
63
|
+
echo "❌ Could not extract organization/project from remote URL"
|
|
64
|
+
echo " Remote: $REMOTE_URL"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Ensure the remote URL follows one of these formats:"
|
|
67
|
+
echo " https://dev.azure.com/{ORG}/{PROJECT}/_git/{REPO}"
|
|
68
|
+
echo " https://{ORG}.visualstudio.com/{PROJECT}/_git/{REPO}"
|
|
69
|
+
echo " {ORG}@vs-ssh.visualstudio.com:v3/{ORG}/{PROJECT}/{REPO}"
|
|
70
|
+
# HALT — cannot proceed without org/project context
|
|
71
|
+
fi
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
When `AZDO_MODE == cli`, also configure the defaults so commands work correctly:
|
|
75
|
+
```bash
|
|
76
|
+
az devops configure --defaults organization="$AZDO_ORG_URL" project="$AZDO_PROJECT"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When `AZDO_MODE == rest`, store these for API calls:
|
|
80
|
+
- Base URL: `$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis`
|
|
81
|
+
- Auth header: `Authorization: Basic $(printf ":%s" "$PAT" | base64 | tr -d '\n')`
|
|
82
|
+
|
|
83
|
+
Report in pre-flight:
|
|
84
|
+
- ✅ `azdo context` — org: `{AZDO_ORG}`, project: `{AZDO_PROJECT}`
|
|
85
|
+
- ❌ `azdo context` — could not parse from remote URL → halt with instructions
|
|
86
|
+
|
|
87
|
+
Pass `{AZDO_MODE}`, `{AZDO_ORG}`, `{AZDO_PROJECT}`, `{AZDO_ORG_URL}` into
|
|
88
|
+
all phase prompts alongside `{PLATFORM}`.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Superpowers Deferral Contract
|
|
2
|
+
|
|
3
|
+
Shared deferral behavior for `speccy`, `build`, and `ship`. Superpowers is a
|
|
4
|
+
soft/recommended dependency (runtime-detected, like claude-mem) — never required.
|
|
5
|
+
When it is absent, every skill runs its standalone pipeline unchanged.
|
|
6
|
+
|
|
7
|
+
## Detection
|
|
8
|
+
|
|
9
|
+
Detection is a bounded on-disk anchor check via `scripts/lib/superpowers.js`
|
|
10
|
+
(anchor file: `using-superpowers/SKILL.md`). Run it from a SKILL.md pre-flight
|
|
11
|
+
step with an ESM-safe dynamic import. `LIB` resolves to the plugin's
|
|
12
|
+
`scripts/lib` directory using the same `CLAUDE_PLUGIN_ROOT` fallback the other
|
|
13
|
+
skills use, so it works for plugin installs and degrades gracefully otherwise:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
LIB="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/slamb2k}/scripts/lib"
|
|
17
|
+
SP=$(node -e "import('$LIB/superpowers.js').then(m=>process.stdout.write(m.detectSuperpowers().installed?'1':'0')).catch(()=>process.stdout.write('0'))")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`SP` is `1` when Superpowers is detected, `0` otherwise. If the helper is not
|
|
21
|
+
present at runtime (e.g. a single-skill install), the `.catch` yields `0` so the
|
|
22
|
+
skill safely runs its standalone pipeline. Passing `--no-superpowers`
|
|
23
|
+
short-circuits `SP` to `0` before this check runs.
|
|
24
|
+
|
|
25
|
+
## Announcement format
|
|
26
|
+
|
|
27
|
+
When deferring, print exactly one line (GUD-002):
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
⚡ Superpowers detected — deferring {stage} to superpowers:{skill}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## `--no-superpowers` flag
|
|
34
|
+
|
|
35
|
+
Parsed alongside each skill's existing flags. Forces the standalone pipeline even
|
|
36
|
+
when Superpowers is installed. Treat it as setting `SP=0` for the whole run.
|
|
37
|
+
|
|
38
|
+
## Absent-fallback rule (REQ-007)
|
|
39
|
+
|
|
40
|
+
When Superpowers is not installed (or `--no-superpowers` is set), the skill runs
|
|
41
|
+
its current standalone pipeline with byte-for-byte identical user-facing output.
|
|
42
|
+
No announcement is printed — the deferral logic is purely additive.
|
|
43
|
+
|
|
44
|
+
## Per-skill deferral map
|
|
45
|
+
|
|
46
|
+
| Skill / stage | Defers to (when present) | Retained by mad-skills |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `speccy` requirements interview | `superpowers:brainstorming` | writes `specs/*.md` + pending-build marker |
|
|
49
|
+
| `build` plan/implement core | `superpowers:executing-plans` / `superpowers:subagent-driven-development` | explore, 3× code-review, verify, ship gate |
|
|
50
|
+
| `ship` final integration | `superpowers:finishing-a-development-branch` | sync, branch, commit, PR, CI-poll, auto-fix |
|
|
51
|
+
| `prime` graphify awareness | — (hint only) | context summary |
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared YAML frontmatter parser for SKILL.md files.
|
|
3
|
+
* Used by validate-skills.js and build-manifests.js.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function parseFrontmatter(content) {
|
|
7
|
+
// Normalise line endings (CRLF → LF) for cross-platform support
|
|
8
|
+
const normalised = content.replace(/\r\n/g, "\n");
|
|
9
|
+
const match = normalised.match(/^---\n([\s\S]*?)\n---/);
|
|
10
|
+
if (!match) return null;
|
|
11
|
+
|
|
12
|
+
const result = {};
|
|
13
|
+
let currentKey = null;
|
|
14
|
+
let currentValue = "";
|
|
15
|
+
|
|
16
|
+
for (const line of match[1].split("\n")) {
|
|
17
|
+
// Continuation line (indented)
|
|
18
|
+
if (currentKey && (line.startsWith(" ") || line.startsWith("\t"))) {
|
|
19
|
+
currentValue += " " + line.trim();
|
|
20
|
+
result[currentKey] = currentValue;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const colonIdx = line.indexOf(":");
|
|
25
|
+
if (colonIdx === -1) continue;
|
|
26
|
+
|
|
27
|
+
currentKey = line.slice(0, colonIdx).trim();
|
|
28
|
+
currentValue = line.slice(colonIdx + 1).trim();
|
|
29
|
+
result[currentKey] = currentValue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Superpowers detection helper.
|
|
3
|
+
* Soft-dependency, on-disk anchor check — used by speccy/build/ship pre-flight.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
|
|
10
|
+
const ANCHOR = "using-superpowers/SKILL.md";
|
|
11
|
+
const MAX_DEPTH = 7;
|
|
12
|
+
|
|
13
|
+
function anchorExists(dir) {
|
|
14
|
+
try {
|
|
15
|
+
return fs.existsSync(path.join(dir, ANCHOR));
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function findAnchorDir(root, depth = 0) {
|
|
22
|
+
if (depth > MAX_DEPTH) return null;
|
|
23
|
+
|
|
24
|
+
if (anchorExists(root)) return root;
|
|
25
|
+
|
|
26
|
+
let entries;
|
|
27
|
+
try {
|
|
28
|
+
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (!entry.isDirectory()) continue;
|
|
35
|
+
const child = path.join(root, entry.name);
|
|
36
|
+
const hit = findAnchorDir(child, depth + 1);
|
|
37
|
+
if (hit) return hit;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function detectSuperpowers({
|
|
44
|
+
homedir = os.homedir(),
|
|
45
|
+
cwd = process.cwd(),
|
|
46
|
+
} = {}) {
|
|
47
|
+
const roots = [
|
|
48
|
+
path.join(homedir, ".claude", "plugins"),
|
|
49
|
+
path.join(homedir, ".claude", "skills", "superpowers"),
|
|
50
|
+
path.join(cwd, ".claude", "skills"),
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const root of roots) {
|
|
54
|
+
const hit = findAnchorDir(root);
|
|
55
|
+
if (hit) {
|
|
56
|
+
return { installed: true, basePath: hit };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { installed: false, basePath: null };
|
|
61
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
import { detectSuperpowers } from "./superpowers.js";
|
|
8
|
+
|
|
9
|
+
function mkTmp() {
|
|
10
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "sp-"));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function writeAnchor(dir, rel) {
|
|
14
|
+
const file = path.join(dir, rel);
|
|
15
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
16
|
+
fs.writeFileSync(file, "# anchor\n");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test("installed: anchor under plugins cache", () => {
|
|
20
|
+
const tmp = mkTmp();
|
|
21
|
+
try {
|
|
22
|
+
writeAnchor(
|
|
23
|
+
tmp,
|
|
24
|
+
".claude/plugins/somepkg/superpowers/skills/using-superpowers/SKILL.md",
|
|
25
|
+
);
|
|
26
|
+
const result = detectSuperpowers({ homedir: tmp, cwd: tmp });
|
|
27
|
+
assert.equal(result.installed, true);
|
|
28
|
+
assert.ok(result.basePath);
|
|
29
|
+
} finally {
|
|
30
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("not installed: empty tree", () => {
|
|
35
|
+
const tmp = mkTmp();
|
|
36
|
+
try {
|
|
37
|
+
const result = detectSuperpowers({ homedir: tmp, cwd: tmp });
|
|
38
|
+
assert.equal(result.installed, false);
|
|
39
|
+
assert.equal(result.basePath, null);
|
|
40
|
+
} finally {
|
|
41
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("partial install: anchor missing → not installed", () => {
|
|
46
|
+
const tmp = mkTmp();
|
|
47
|
+
try {
|
|
48
|
+
writeAnchor(
|
|
49
|
+
tmp,
|
|
50
|
+
".claude/plugins/somepkg/superpowers/skills/writing-plans/SKILL.md",
|
|
51
|
+
);
|
|
52
|
+
const result = detectSuperpowers({ homedir: tmp, cwd: tmp });
|
|
53
|
+
assert.equal(result.installed, false);
|
|
54
|
+
assert.equal(result.basePath, null);
|
|
55
|
+
} finally {
|
|
56
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("project-local: anchor under cwd .claude/skills", () => {
|
|
61
|
+
const tmp = mkTmp();
|
|
62
|
+
try {
|
|
63
|
+
writeAnchor(
|
|
64
|
+
tmp,
|
|
65
|
+
".claude/skills/superpowers-foo/using-superpowers/SKILL.md",
|
|
66
|
+
);
|
|
67
|
+
const result = detectSuperpowers({
|
|
68
|
+
homedir: path.join(tmp, "nohome"),
|
|
69
|
+
cwd: tmp,
|
|
70
|
+
});
|
|
71
|
+
assert.equal(result.installed, true);
|
|
72
|
+
assert.ok(result.basePath);
|
|
73
|
+
} finally {
|
|
74
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
75
|
+
}
|
|
76
|
+
});
|
package/skills/brace/SKILL.md
CHANGED
|
@@ -87,6 +87,7 @@ Before starting, check all dependencies in this table:
|
|
|
87
87
|
|-----------|------|-------|----------|------------|--------|
|
|
88
88
|
| claude-mem | plugin | — | no | ask | `claude plugin install claude-mem` |
|
|
89
89
|
| oh-my-claudecode | plugin | — | no | ask | `claude plugin install oh-my-claudecode` |
|
|
90
|
+
| superpowers | plugin | on-disk glob via scripts/lib/superpowers.js | no | ask | `claude plugin install superpowers` |
|
|
90
91
|
|
|
91
92
|
For each row, in order:
|
|
92
93
|
1. Run the Check command (for cli/npm) or test file existence (for agent/skill)
|
|
@@ -104,6 +105,11 @@ For each row, in order:
|
|
|
104
105
|
name set to `true`. Store results as `PLUGIN_STATE` (`claude_mem_installed`,
|
|
105
106
|
`omc_installed`) for use in Phase 4 and Phase 7.
|
|
106
107
|
|
|
108
|
+
**Superpowers detection differs:** Superpowers is a soft dependency detected via
|
|
109
|
+
the on-disk glob helper `scripts/lib/superpowers.js` (anchor file
|
|
110
|
+
`using-superpowers/SKILL.md`), **not** the `enabledPlugins` settings.json check
|
|
111
|
+
used for claude-mem and OMC — see `references/superpowers-deferral.md`.
|
|
112
|
+
|
|
107
113
|
1. Capture **FLAGS** from the user's request
|
|
108
114
|
|
|
109
115
|
---
|
|
@@ -53,6 +53,16 @@ MCP tools for search, timeline, and observation management. Claude Code's
|
|
|
53
53
|
built-in auto memory (`~/.claude/projects/<project>/memory/MEMORY.md`)
|
|
54
54
|
handles curated facts.
|
|
55
55
|
|
|
56
|
+
For the methodology layer (plan → build → finish), install the **superpowers**
|
|
57
|
+
plugin:
|
|
58
|
+
```
|
|
59
|
+
claude plugin install superpowers
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
mad-skills defers its overlapping `/speccy`, `/build`, and `/ship` stages to
|
|
63
|
+
superpowers when it is present, and falls back to its own standalone pipeline
|
|
64
|
+
when it is absent.
|
|
65
|
+
|
|
56
66
|
{PLUGIN_ROLE_SEPARATION}
|
|
57
67
|
|
|
58
68
|
{UNIVERSAL_PRINCIPLES}
|
package/skills/build/SKILL.md
CHANGED
|
@@ -75,6 +75,7 @@ Parse optional flags from the request:
|
|
|
75
75
|
- `--skip-review`: Skip Stage 5 (code review)
|
|
76
76
|
- `--no-ship`: Stop after Stage 8 docs update
|
|
77
77
|
- `--parallel-impl`: Split implementation into parallel agents when independent
|
|
78
|
+
- `--no-superpowers`: Force the standalone pipeline even when Superpowers is installed
|
|
78
79
|
|
|
79
80
|
---
|
|
80
81
|
|
|
@@ -89,6 +90,7 @@ Before starting, check all dependencies in this table:
|
|
|
89
90
|
| feature-dev:code-explorer | agent | — | no | fallback | Uses general-purpose agent |
|
|
90
91
|
| feature-dev:code-architect | agent | — | no | fallback | Uses general-purpose agent |
|
|
91
92
|
| feature-dev:code-reviewer | agent | — | no | fallback | Uses general-purpose agent |
|
|
93
|
+
| superpowers | plugin | on-disk glob via scripts/lib/superpowers.js | no | fallback | Routes Stage 4 impl core to superpowers:executing-plans / subagent-driven-development when present; see references/superpowers-deferral.md |
|
|
92
94
|
|
|
93
95
|
For each row, in order:
|
|
94
96
|
1. Run the Check command (for cli/npm) or test file existence (for agent/skill)
|
|
@@ -241,6 +243,16 @@ If rejected, incorporate feedback and re-run.
|
|
|
241
243
|
|
|
242
244
|
## Stage 4: Implementation
|
|
243
245
|
|
|
246
|
+
**Superpowers deferral (soft dependency):** When Superpowers is detected (per the
|
|
247
|
+
pre-flight check) and `--no-superpowers` is not set, announce
|
|
248
|
+
`⚡ Superpowers detected — deferring plan/implement core to superpowers:executing-plans`
|
|
249
|
+
and route the plan-execution/implementation core through
|
|
250
|
+
`superpowers:executing-plans` / `superpowers:subagent-driven-development` instead
|
|
251
|
+
of the general-purpose subagents below. Stage 1 (explore), Stage 5 (3× review),
|
|
252
|
+
and Stage 7 (verify) remain unchanged either way. When Superpowers is absent or
|
|
253
|
+
`--no-superpowers` is set, run the standalone implementation below unchanged.
|
|
254
|
+
See `references/superpowers-deferral.md`.
|
|
255
|
+
|
|
244
256
|
If ARCH_REPORT identifies independent `parallel_groups`, launch **multiple
|
|
245
257
|
general-purpose subagents in parallel** — one per group. Do NOT wait for
|
|
246
258
|
`--parallel-impl` flag; parallel execution is the **default** when the
|
|
@@ -32,5 +32,21 @@
|
|
|
32
32
|
{ "type": "contains", "value": "██" },
|
|
33
33
|
{ "type": "semantic", "value": "Acknowledges the --skip-questions flag (skipping clarifying questions) and the --no-ship flag (stopping before committing/pushing/creating PR)" }
|
|
34
34
|
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "build-superpowers-present",
|
|
38
|
+
"prompt": "The superpowers plugin is installed. Run build on specs/rate-limiter.md. Which superpowers skill does build route its implementation core through?",
|
|
39
|
+
"assertions": [
|
|
40
|
+
{ "type": "regex", "value": "(executing-plans|subagent-driven-development)", "flags": "i" },
|
|
41
|
+
{ "type": "contains", "value": "Superpowers detected" }
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "build-superpowers-absent",
|
|
46
|
+
"prompt": "Superpowers is NOT installed. How does build implement a plan?",
|
|
47
|
+
"assertions": [
|
|
48
|
+
{ "type": "regex", "value": "(explore|architect|implement|review)", "flags": "i" },
|
|
49
|
+
{ "type": "semantic", "value": "Runs the standalone feature-dev pipeline (explore, architect, implement, review, verify) using its own subagents, with no deferral to superpowers" }
|
|
50
|
+
]
|
|
35
51
|
}
|
|
36
52
|
]
|
package/skills/manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generated": "2026-
|
|
2
|
+
"generated": "2026-07-02T03:59:12.977Z",
|
|
3
3
|
"count": 11,
|
|
4
4
|
"skills": [
|
|
5
5
|
{
|
|
6
6
|
"name": "brace",
|
|
7
7
|
"directory": "brace",
|
|
8
8
|
"description": "'Initialize any project directory with a standard scaffold for AI-assisted development. Creates specs/ and context/ directories, a project CLAUDE.md with development workflow and guardrails, .gitignore, and branch protection. Recommends claude-mem for persistent memory. Idempotent — safe to run on existing projects. Triggers: \"init project\", \"setup brace\", \"brace\", \"initialize\", \"bootstrap\", \"scaffold\".'",
|
|
9
|
-
"lines":
|
|
9
|
+
"lines": 436,
|
|
10
10
|
"hasScripts": false,
|
|
11
11
|
"hasReferences": true,
|
|
12
12
|
"hasAssets": true,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"name": "build",
|
|
17
17
|
"directory": "build",
|
|
18
18
|
"description": "Context-isolated feature development pipeline. Takes a detailed design/plan as argument and executes the full feature-dev lifecycle (explore, question, architect, implement, review, ship) inside subagents so the primary conversation stays compact. Use when you have a well-defined plan and want autonomous execution with minimal context window consumption.",
|
|
19
|
-
"lines":
|
|
19
|
+
"lines": 468,
|
|
20
20
|
"hasScripts": false,
|
|
21
21
|
"hasReferences": true,
|
|
22
22
|
"hasAssets": false,
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"name": "prime",
|
|
67
67
|
"directory": "prime",
|
|
68
68
|
"description": "\"Load project context before implementing features or making architectural decisions. Invoke proactively at the start of significant work on any project. Scans CLAUDE.md, README, specs/, docs/, and source structure to build a context summary. Supports optional domain hints to focus on specific areas of the codebase. Use when you need project conventions, architecture understanding, or domain context before coding.\"",
|
|
69
|
-
"lines":
|
|
69
|
+
"lines": 165,
|
|
70
70
|
"hasScripts": false,
|
|
71
71
|
"hasReferences": true,
|
|
72
72
|
"hasAssets": false,
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"name": "ship",
|
|
87
87
|
"directory": "ship",
|
|
88
88
|
"description": "\"Ship changes through the full PR lifecycle. Use after completing feature work to commit, push, create PR, wait for checks, and merge. Handles the entire workflow: syncs with main, creates feature branch if needed, groups commits logically with semantic messages, creates detailed PR, monitors CI, fixes issues, squash merges, and cleans up. Invoke when work is ready to ship.\"",
|
|
89
|
-
"lines":
|
|
89
|
+
"lines": 499,
|
|
90
90
|
"hasScripts": true,
|
|
91
91
|
"hasReferences": true,
|
|
92
92
|
"hasAssets": false,
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"name": "speccy",
|
|
97
97
|
"directory": "speccy",
|
|
98
98
|
"description": "Deep-dive interview skill for creating comprehensive specifications. Reviews existing code and docs, then interviews the user through multiple rounds of targeted questions covering technical implementation, UI/UX, concerns, and tradeoffs. Produces a structured spec in specs/. Use when starting a new feature, system, or major change that needs a spec.",
|
|
99
|
-
"lines":
|
|
99
|
+
"lines": 275,
|
|
100
100
|
"hasScripts": false,
|
|
101
101
|
"hasReferences": true,
|
|
102
102
|
"hasAssets": false,
|
package/skills/prime/SKILL.md
CHANGED
|
@@ -108,6 +108,13 @@ For each file:
|
|
|
108
108
|
- If it exists: read and summarise (2-3 lines max per domain)
|
|
109
109
|
- If it doesn't exist: record as NOT FOUND and continue
|
|
110
110
|
|
|
111
|
+
## Graphify Awareness (existence check only)
|
|
112
|
+
|
|
113
|
+
Check whether a `graphify-out/` directory exists at the project root
|
|
114
|
+
(existence only — do NOT run any graphify query, read its contents, or treat
|
|
115
|
+
it as a dependency). Record the boolean in the report. This is purely additive:
|
|
116
|
+
when absent, the report is unchanged.
|
|
117
|
+
|
|
111
118
|
## Output Format
|
|
112
119
|
|
|
113
120
|
PRIME_REPORT:
|
|
@@ -117,6 +124,7 @@ PRIME_REPORT:
|
|
|
117
124
|
- per_domain_summary:
|
|
118
125
|
- {domain}: {2-3 line summary}
|
|
119
126
|
- branch: {current branch from git branch --show-current}
|
|
127
|
+
- graphify_out_present: {true|false}
|
|
120
128
|
- ready_for: {inferred from loaded context}
|
|
121
129
|
```
|
|
122
130
|
|
|
@@ -143,5 +151,14 @@ Parse PRIME_REPORT and present a clean summary to the user:
|
|
|
143
151
|
└─────────────────────────────────────────────────
|
|
144
152
|
```
|
|
145
153
|
|
|
154
|
+
If `graphify_out_present` is true, add a single passive line after the report
|
|
155
|
+
box (omit entirely when false):
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
graphify-out/ detected — codebase questions can be answered via /graphify
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This is a hint only — never execute a graphify query on the user's behalf.
|
|
162
|
+
|
|
146
163
|
If CLAUDE.md was missing, warn the user and note that only domain context
|
|
147
164
|
was loaded.
|
|
@@ -24,5 +24,14 @@
|
|
|
24
24
|
{ "type": "contains", "value": "██" },
|
|
25
25
|
{ "type": "semantic", "value": "Recognizes 'dashboard' and 'routing' as valid domain-specific contexts and describes loading files relevant to those domains" }
|
|
26
26
|
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "prime-graphify-hint",
|
|
30
|
+
"prompt": "Prime me for this project. The repository root contains a graphify-out/ directory alongside CLAUDE.md and specs/.",
|
|
31
|
+
"assertions": [
|
|
32
|
+
{ "type": "contains", "value": "██" },
|
|
33
|
+
{ "type": "contains", "value": "/graphify" },
|
|
34
|
+
{ "type": "semantic", "value": "Detects the graphify-out/ directory by existence only and surfaces a passive hint that codebase questions can be answered via /graphify, without running any graphify query" }
|
|
35
|
+
]
|
|
27
36
|
}
|
|
28
37
|
]
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -70,6 +70,7 @@ Parse optional flags from the request:
|
|
|
70
70
|
- `--pr-only`: Stop after creating the PR
|
|
71
71
|
- `--no-squash`: Use regular merge instead of squash
|
|
72
72
|
- `--keep-branch`: Don't delete the source branch after merge
|
|
73
|
+
- `--no-superpowers`: Force standalone merge even when Superpowers is installed
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
@@ -113,6 +114,7 @@ Before starting, check all dependencies in this table. The table contains
|
|
|
113
114
|
| git | cli | `git --version` | yes | stop | Install from https://git-scm.com |
|
|
114
115
|
| gh | cli | `gh --version` | yes | url | https://cli.github.com |
|
|
115
116
|
| az devops | cli | `az devops -h 2>/dev/null` | no | fallback | Falls back to REST API with PAT; see AzDO tooling below |
|
|
117
|
+
| superpowers | plugin | on-disk glob via scripts/lib/superpowers.js | no | fallback | Replaces final merge with superpowers:finishing-a-development-branch when present; see references/superpowers-deferral.md |
|
|
116
118
|
|
|
117
119
|
**Platform-conditional rules:**
|
|
118
120
|
- **`gh`**: Only required when `PLATFORM == github`. Skip for AzDO repos.
|
|
@@ -374,6 +376,8 @@ defaults (override via `--no-squash` and `--keep-branch` flags only).
|
|
|
374
376
|
|
|
375
377
|
### 5a. Merge the PR
|
|
376
378
|
|
|
379
|
+
**Superpowers deferral:** When Superpowers is detected and `--no-superpowers` is not set, after CI is green and auto-fix, announce `⚡ Superpowers detected — deferring final integration to superpowers:finishing-a-development-branch` and invoke that skill to present merge/PR/cleanup options instead of calling merge.sh directly (CI-poll + auto-fix and the no-manual-CI-trigger rule still apply); otherwise run merge.sh below.
|
|
380
|
+
|
|
377
381
|
Run the merge script directly (no LLM needed):
|
|
378
382
|
|
|
379
383
|
```bash
|
|
@@ -26,5 +26,21 @@
|
|
|
26
26
|
{ "type": "regex", "value": "(script|sync\\.sh|ci-watch\\.sh|merge\\.sh|general.purpose)", "flags": "i" },
|
|
27
27
|
{ "type": "semantic", "value": "Uses deterministic scripts for sync, CI monitoring, and merge stages, with LLM subagents only for commit/PR authoring and CI fix analysis" }
|
|
28
28
|
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "ship-superpowers-present",
|
|
32
|
+
"prompt": "The superpowers plugin is installed. Run ship. Once CI is green, which superpowers skill handles the final integration instead of an auto squash-merge?",
|
|
33
|
+
"assertions": [
|
|
34
|
+
{ "type": "contains", "value": "finishing-a-development-branch" },
|
|
35
|
+
{ "type": "contains", "value": "Superpowers detected" }
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "ship-superpowers-absent",
|
|
40
|
+
"prompt": "Superpowers is NOT installed. How does ship merge the PR after CI passes?",
|
|
41
|
+
"assertions": [
|
|
42
|
+
{ "type": "regex", "value": "(squash|merge)", "flags": "i" },
|
|
43
|
+
{ "type": "semantic", "value": "Runs the standalone merge (squash merge and delete branch by default) via merge.sh, with no deferral to superpowers" }
|
|
44
|
+
]
|
|
29
45
|
}
|
|
30
46
|
]
|
package/skills/speccy/SKILL.md
CHANGED
|
@@ -66,6 +66,11 @@ in `references/spec-template.md`.
|
|
|
66
66
|
Interview prompts and question guidelines: `references/interview-guide.md`
|
|
67
67
|
Spec template and writing guidelines: `references/spec-template.md`
|
|
68
68
|
|
|
69
|
+
## Flags
|
|
70
|
+
|
|
71
|
+
Parse optional flags from the request:
|
|
72
|
+
- `--no-superpowers`: Force the standalone interview even when Superpowers is installed
|
|
73
|
+
|
|
69
74
|
## Pre-flight
|
|
70
75
|
|
|
71
76
|
Before starting, check all dependencies in this table:
|
|
@@ -73,6 +78,7 @@ Before starting, check all dependencies in this table:
|
|
|
73
78
|
| Dependency | Type | Check | Required | Resolution | Detail |
|
|
74
79
|
|-----------|------|-------|----------|------------|--------|
|
|
75
80
|
| prime | skill | `ls .claude/skills/prime/SKILL.md ~/.claude/skills/prime/SKILL.md ~/.claude/plugins/marketplaces/slamb2k/skills/prime/SKILL.md 2>/dev/null` | no | fallback | Context loading; falls back to manual project scan |
|
|
81
|
+
| superpowers | plugin | on-disk glob via scripts/lib/superpowers.js | no | fallback | Defers Stage 2 interview to superpowers:brainstorming when present; see references/superpowers-deferral.md |
|
|
76
82
|
|
|
77
83
|
For each row, in order:
|
|
78
84
|
1. Test file existence (check both paths for symlinked skills)
|
|
@@ -135,6 +141,15 @@ Group gaps into interview categories:
|
|
|
135
141
|
Conduct multiple rounds of questions using `AskUserQuestion`. Continue until
|
|
136
142
|
all knowledge gaps are resolved.
|
|
137
143
|
|
|
144
|
+
**Superpowers deferral (soft dependency):** When Superpowers is detected (per the
|
|
145
|
+
pre-flight check) and the `--no-superpowers` flag is not set, announce
|
|
146
|
+
`⚡ Superpowers detected — deferring requirements interview to superpowers:brainstorming`
|
|
147
|
+
and use `superpowers:brainstorming` for requirements/gap exploration in place of
|
|
148
|
+
(or ahead of) the multi-round interview below. In ALL cases — deferred or
|
|
149
|
+
standalone — speccy still writes `specs/{slug}.md` and the pending-build marker
|
|
150
|
+
(see `references/superpowers-deferral.md`). When Superpowers is absent or
|
|
151
|
+
`--no-superpowers` is set, run the standalone interview unchanged.
|
|
152
|
+
|
|
138
153
|
### Question Rules
|
|
139
154
|
|
|
140
155
|
1. **4 questions per round maximum** (AskUserQuestion limit)
|
|
@@ -30,5 +30,29 @@
|
|
|
30
30
|
"value": "Security"
|
|
31
31
|
}
|
|
32
32
|
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "speccy-superpowers-present",
|
|
36
|
+
"prompt": "The superpowers plugin is installed. Run speccy to spec out a rate limiter. Which stage does speccy defer, and to which superpowers skill?",
|
|
37
|
+
"assertions": [
|
|
38
|
+
{
|
|
39
|
+
"type": "contains",
|
|
40
|
+
"value": "⚡ Superpowers detected"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "contains",
|
|
44
|
+
"value": "brainstorming"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "speccy-superpowers-absent",
|
|
50
|
+
"prompt": "Superpowers is NOT installed. How does speccy gather requirements to build a spec?",
|
|
51
|
+
"assertions": [
|
|
52
|
+
{
|
|
53
|
+
"type": "contains",
|
|
54
|
+
"value": "interview"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
33
57
|
}
|
|
34
58
|
]
|