@slamb2k/mad-skills 2.0.35 → 2.0.36
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 +1 -1
- package/skills/brace/SKILL.md +7 -3
- package/skills/dock/references/azdo-platform.md +6 -1
- package/skills/keel/references/azdo-platform.md +6 -1
- package/skills/manifest.json +4 -4
- package/skills/rig/SKILL.md +6 -1
- package/skills/ship/SKILL.md +8 -2
- package/skills/ship/references/stage-prompts.md +30 -17
package/package.json
CHANGED
package/skills/brace/SKILL.md
CHANGED
|
@@ -329,6 +329,10 @@ elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
|
329
329
|
AZDO_PROJECT=$(echo "$REMOTE_URL" | sed -n 's|.*/\([^/]*\)/_git/.*|\1|p')
|
|
330
330
|
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
331
331
|
fi
|
|
332
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
333
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
334
|
+
AZDO_ORG=$(printf '%b' "${AZDO_ORG//%/\\x}")
|
|
335
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
332
336
|
REPO_NAME=$(basename -s .git "$REMOTE_URL")
|
|
333
337
|
```
|
|
334
338
|
|
|
@@ -350,11 +354,11 @@ If org/project extraction fails, report ⚠️ and skip branch policies.
|
|
|
350
354
|
AUTH="Authorization: Basic $(echo -n ":$PAT" | base64)"
|
|
351
355
|
# Get repository ID first
|
|
352
356
|
REPO_ID=$(curl -s -H "$AUTH" \
|
|
353
|
-
"$AZDO_ORG_URL/$
|
|
357
|
+
"$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis/git/repositories/$REPO_NAME?api-version=7.0" \
|
|
354
358
|
| jq -r '.id')
|
|
355
359
|
# List branch policies
|
|
356
360
|
curl -s -H "$AUTH" \
|
|
357
|
-
"$AZDO_ORG_URL/$
|
|
361
|
+
"$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis/policy/configurations?api-version=7.0" \
|
|
358
362
|
| jq "[.value[] | select(.settings.scope[]?.refName == \"refs/heads/$default_branch\" and .settings.scope[]?.repositoryId == \"$REPO_ID\")]"
|
|
359
363
|
```
|
|
360
364
|
|
|
@@ -386,7 +390,7 @@ If org/project extraction fails, report ⚠️ and skip branch policies.
|
|
|
386
390
|
**REST fallback:**
|
|
387
391
|
```bash
|
|
388
392
|
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
389
|
-
"$AZDO_ORG_URL/$
|
|
393
|
+
"$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis/policy/configurations?api-version=7.0" \
|
|
390
394
|
-d "{
|
|
391
395
|
\"isEnabled\": true,
|
|
392
396
|
\"isBlocking\": true,
|
|
@@ -54,6 +54,11 @@ elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
|
54
54
|
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
55
55
|
fi
|
|
56
56
|
|
|
57
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
58
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
59
|
+
AZDO_ORG=$(printf '%b' "${AZDO_ORG//%/\\x}")
|
|
60
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
61
|
+
|
|
57
62
|
if [ -z "$AZDO_ORG" ] || [ -z "$AZDO_PROJECT" ]; then
|
|
58
63
|
echo "❌ Could not extract organization/project from remote URL"
|
|
59
64
|
echo " Remote: $REMOTE_URL"
|
|
@@ -72,7 +77,7 @@ az devops configure --defaults organization="$AZDO_ORG_URL" project="$AZDO_PROJE
|
|
|
72
77
|
```
|
|
73
78
|
|
|
74
79
|
When `AZDO_MODE == rest`, store these for API calls:
|
|
75
|
-
- Base URL: `$AZDO_ORG_URL/$
|
|
80
|
+
- Base URL: `$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis`
|
|
76
81
|
- Auth header: `Authorization: Basic $(echo -n ":$PAT" | base64)`
|
|
77
82
|
|
|
78
83
|
Report in pre-flight:
|
|
@@ -54,6 +54,11 @@ elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
|
54
54
|
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
55
55
|
fi
|
|
56
56
|
|
|
57
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
58
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
59
|
+
AZDO_ORG=$(printf '%b' "${AZDO_ORG//%/\\x}")
|
|
60
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
61
|
+
|
|
57
62
|
if [ -z "$AZDO_ORG" ] || [ -z "$AZDO_PROJECT" ]; then
|
|
58
63
|
echo "❌ Could not extract organization/project from remote URL"
|
|
59
64
|
echo " Remote: $REMOTE_URL"
|
|
@@ -72,7 +77,7 @@ az devops configure --defaults organization="$AZDO_ORG_URL" project="$AZDO_PROJE
|
|
|
72
77
|
```
|
|
73
78
|
|
|
74
79
|
When `AZDO_MODE == rest`, store these for API calls:
|
|
75
|
-
- Base URL: `$AZDO_ORG_URL/$
|
|
80
|
+
- Base URL: `$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis`
|
|
76
81
|
- Auth header: `Authorization: Basic $(echo -n ":$PAT" | base64)`
|
|
77
82
|
|
|
78
83
|
Report in pre-flight:
|
package/skills/manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generated": "2026-03-
|
|
2
|
+
"generated": "2026-03-17T01:20:17.972Z",
|
|
3
3
|
"count": 10,
|
|
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": 445,
|
|
10
10
|
"hasScripts": false,
|
|
11
11
|
"hasReferences": true,
|
|
12
12
|
"hasAssets": true,
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"name": "rig",
|
|
67
67
|
"directory": "rig",
|
|
68
68
|
"description": "'Idempotently bootstrap any repository with standard development tools, hooks, and workflows. Use when starting work on a new repo, onboarding to an existing project, or ensuring a repo has proper CI/CD setup. Configures: git hooks (lefthook), commit message templates, PR templates, and GitHub Actions for lint/format/type-check/build. Prompts for user confirmation before changes. Triggers: \"bootstrap repo\", \"setup hooks\", \"configure CI\", \"rig\", \"standardize repo\".'",
|
|
69
|
-
"lines":
|
|
69
|
+
"lines": 343,
|
|
70
70
|
"hasScripts": false,
|
|
71
71
|
"hasReferences": true,
|
|
72
72
|
"hasAssets": true,
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"name": "ship",
|
|
77
77
|
"directory": "ship",
|
|
78
78
|
"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.\"",
|
|
79
|
-
"lines":
|
|
79
|
+
"lines": 428,
|
|
80
80
|
"hasScripts": false,
|
|
81
81
|
"hasReferences": true,
|
|
82
82
|
"hasAssets": false,
|
package/skills/rig/SKILL.md
CHANGED
|
@@ -169,6 +169,11 @@ elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
|
169
169
|
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
170
170
|
fi
|
|
171
171
|
|
|
172
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
173
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
174
|
+
AZDO_ORG=$(printf '%b' "${AZDO_ORG//%/\\x}")
|
|
175
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
176
|
+
|
|
172
177
|
if [ -z "$AZDO_ORG" ] || [ -z "$AZDO_PROJECT" ]; then
|
|
173
178
|
echo "❌ Could not extract organization/project from remote URL"
|
|
174
179
|
echo " Remote: $REMOTE_URL"
|
|
@@ -187,7 +192,7 @@ az devops configure --defaults organization="$AZDO_ORG_URL" project="$AZDO_PROJE
|
|
|
187
192
|
```
|
|
188
193
|
|
|
189
194
|
When `AZDO_MODE == rest`, store these for API calls:
|
|
190
|
-
- Base URL: `$AZDO_ORG_URL/$
|
|
195
|
+
- Base URL: `$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis`
|
|
191
196
|
- Auth header: `Authorization: Basic $(echo -n ":$PAT" | base64)`
|
|
192
197
|
|
|
193
198
|
Report in pre-flight:
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -185,6 +185,11 @@ elif echo "$REMOTE_URL" | grep -q 'visualstudio\.com'; then
|
|
|
185
185
|
AZDO_ORG_URL="https://dev.azure.com/$AZDO_ORG"
|
|
186
186
|
fi
|
|
187
187
|
|
|
188
|
+
# URL-decode for CLI/display; keep URL-safe versions for REST API paths
|
|
189
|
+
AZDO_PROJECT_URL_SAFE="$AZDO_PROJECT"
|
|
190
|
+
AZDO_ORG=$(printf '%b' "${AZDO_ORG//%/\\x}")
|
|
191
|
+
AZDO_PROJECT=$(printf '%b' "${AZDO_PROJECT//%/\\x}")
|
|
192
|
+
|
|
188
193
|
if [ -z "$AZDO_ORG" ] || [ -z "$AZDO_PROJECT" ]; then
|
|
189
194
|
echo "❌ Could not extract organization/project from remote URL"
|
|
190
195
|
echo " Remote: $REMOTE_URL"
|
|
@@ -203,14 +208,15 @@ az devops configure --defaults organization="$AZDO_ORG_URL" project="$AZDO_PROJE
|
|
|
203
208
|
```
|
|
204
209
|
|
|
205
210
|
When `AZDO_MODE == rest`, store these for API calls:
|
|
206
|
-
- Base URL: `$AZDO_ORG_URL/$
|
|
211
|
+
- Base URL: `$AZDO_ORG_URL/$AZDO_PROJECT_URL_SAFE/_apis`
|
|
207
212
|
- Auth header: `Authorization: Basic $(echo -n ":$PAT" | base64)`
|
|
208
213
|
|
|
209
214
|
Report in pre-flight:
|
|
210
215
|
- ✅ `azdo context` — org: `{AZDO_ORG}`, project: `{AZDO_PROJECT}`
|
|
211
216
|
- ❌ `azdo context` — could not parse from remote URL → halt with instructions
|
|
212
217
|
|
|
213
|
-
Pass `{AZDO_MODE}`, `{AZDO_ORG}`, `{AZDO_PROJECT}`, `{
|
|
218
|
+
Pass `{AZDO_MODE}`, `{AZDO_ORG}`, `{AZDO_PROJECT}`, `{AZDO_PROJECT_URL_SAFE}`,
|
|
219
|
+
`{AZDO_ORG_URL}` into
|
|
214
220
|
all stage prompts alongside `{PLATFORM}`.
|
|
215
221
|
|
|
216
222
|
Read `default_branch` and `remote` from Stage 1's SYNC_REPORT. These are
|
|
@@ -5,7 +5,8 @@ substitutes template variables before launching each subagent.
|
|
|
5
5
|
|
|
6
6
|
`{PLATFORM}` is either `github` or `azdo` (detected from remote URL).
|
|
7
7
|
`{AZDO_MODE}` is `cli` or `rest` (only relevant when PLATFORM == azdo).
|
|
8
|
-
`{AZDO_ORG}`, `{AZDO_PROJECT}`, `{AZDO_ORG_URL}` provide AzDO context.
|
|
8
|
+
`{AZDO_ORG}`, `{AZDO_PROJECT}`, `{AZDO_PROJECT_URL_SAFE}`, `{AZDO_ORG_URL}` provide AzDO context.
|
|
9
|
+
Use `{AZDO_PROJECT}` for CLI `--project` flags and display. Use `{AZDO_PROJECT_URL_SAFE}` in REST API URL paths.
|
|
9
10
|
|
|
10
11
|
---
|
|
11
12
|
|
|
@@ -100,7 +101,7 @@ FILES TO EXCLUDE: {FILES_TO_EXCLUDE}
|
|
|
100
101
|
PR_JSON=$(curl -s -X POST \
|
|
101
102
|
-H "$AUTH" \
|
|
102
103
|
-H "Content-Type: application/json" \
|
|
103
|
-
"{AZDO_ORG_URL}/{
|
|
104
|
+
"{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/git/repositories/$REPO_NAME/pullrequests?api-version=7.0" \
|
|
104
105
|
-d "{\"sourceRefName\": \"refs/heads/$BRANCH\", \"targetRefName\": \"refs/heads/{DEFAULT_BRANCH}\", \"title\": \"<type>: <concise title>\", \"description\": \"## Summary\\n<1-3 sentences>\\n\\n## Changes\\n<bullets>\\n\\n## Testing\\n- [ ] <steps>\"}")
|
|
105
106
|
|
|
106
107
|
6. **Gather info**
|
|
@@ -116,13 +117,13 @@ FILES TO EXCLUDE: {FILES_TO_EXCLUDE}
|
|
|
116
117
|
PR_NUMBER=$(az repos pr list --source-branch "$BRANCH" --status active \
|
|
117
118
|
--org "{AZDO_ORG_URL}" --project "{AZDO_PROJECT}" \
|
|
118
119
|
--query '[0].pullRequestId' -o tsv)
|
|
119
|
-
PR_URL="{AZDO_ORG_URL}/{
|
|
120
|
+
PR_URL="{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_git/$(basename -s .git "$(git remote get-url origin)")/pullrequest/$PR_NUMBER"
|
|
120
121
|
|
|
121
122
|
**If PLATFORM == azdo AND AZDO_MODE == rest:**
|
|
122
123
|
# Parse from the create response JSON:
|
|
123
124
|
PR_NUMBER=$(echo "$PR_JSON" | jq -r '.pullRequestId')
|
|
124
125
|
REPO_NAME=$(basename -s .git "$(git remote get-url origin)")
|
|
125
|
-
PR_URL="{AZDO_ORG_URL}/{
|
|
126
|
+
PR_URL="{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_git/$REPO_NAME/pullrequest/$PR_NUMBER"
|
|
126
127
|
|
|
127
128
|
COMMITS=$(git log {REMOTE}/{DEFAULT_BRANCH}..HEAD --oneline)
|
|
128
129
|
DIFF_STAT=$(git diff {REMOTE}/{DEFAULT_BRANCH} --shortstat)
|
|
@@ -244,7 +245,7 @@ BRANCH: {BRANCH}
|
|
|
244
245
|
```
|
|
245
246
|
REPO_NAME=$(basename -s .git "$(git remote get-url origin)")
|
|
246
247
|
AUTH="Authorization: Basic $(echo -n ":{PAT}" | base64)"
|
|
247
|
-
BUILDS_URL="{AZDO_ORG_URL}/{
|
|
248
|
+
BUILDS_URL="{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/build/builds?branchName=refs/heads/$BRANCH&\$top=5&api-version=7.0"
|
|
248
249
|
|
|
249
250
|
RUNS_FOUND=false
|
|
250
251
|
for i in $(seq 1 8); do
|
|
@@ -259,7 +260,7 @@ BRANCH: {BRANCH}
|
|
|
259
260
|
If no runs appear, check PR policy evaluations via REST:
|
|
260
261
|
```
|
|
261
262
|
EVALS=$(curl -s -H "$AUTH" \
|
|
262
|
-
"{AZDO_ORG_URL}/{
|
|
263
|
+
"{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/policy/evaluations?artifactId=vstfs:///CodeReview/CodeReviewId/{AZDO_PROJECT_URL_SAFE}/{PR_NUMBER}&api-version=7.0")
|
|
263
264
|
EVAL_COUNT=$(echo "$EVALS" | jq '.value | length')
|
|
264
265
|
```
|
|
265
266
|
If no evaluations exist either, report `no_checks`.
|
|
@@ -323,22 +324,34 @@ FAILING CHECKS: {FAILING_CHECKS}
|
|
|
323
324
|
--query "[?result=='failed'].id | [0]" -o tsv)
|
|
324
325
|
az pipelines runs show --id $RUN_ID \
|
|
325
326
|
--org "{AZDO_ORG_URL}" --project "{AZDO_PROJECT}" --output json
|
|
326
|
-
#
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
--org "{AZDO_ORG_URL}"
|
|
330
|
-
|
|
327
|
+
# Download logs locally — more reliable than timeline API on legacy domains
|
|
328
|
+
LOGDIR=$(mktemp -d)
|
|
329
|
+
az pipelines logs download --run-id $RUN_ID --path "$LOGDIR" \
|
|
330
|
+
--org "{AZDO_ORG_URL}" --project "{AZDO_PROJECT}" 2>/dev/null
|
|
331
|
+
if [ -d "$LOGDIR" ] && [ "$(ls "$LOGDIR")" ]; then
|
|
332
|
+
grep -ril "error\|fail\|##vso\[task.logissue" "$LOGDIR" | head -5 | while read f; do
|
|
333
|
+
echo "=== $(basename "$f") ==="
|
|
334
|
+
grep -i "error\|fail\|##vso\[task.logissue" "$f" | tail -30
|
|
335
|
+
done
|
|
336
|
+
fi
|
|
337
|
+
rm -rf "$LOGDIR"
|
|
331
338
|
|
|
332
339
|
**If PLATFORM == azdo AND AZDO_MODE == rest:**
|
|
333
340
|
AUTH="Authorization: Basic $(echo -n ":{PAT}" | base64)"
|
|
334
341
|
# Get failed build ID
|
|
335
342
|
RUN_ID=$(curl -s -H "$AUTH" \
|
|
336
|
-
"{AZDO_ORG_URL}/{
|
|
343
|
+
"{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/build/builds?branchName=refs/heads/{BRANCH}&resultFilter=failed&\$top=1&api-version=7.0" \
|
|
337
344
|
| jq -r '.value[0].id')
|
|
338
345
|
# Get timeline for step-level failures
|
|
339
|
-
curl -s -H "$AUTH" \
|
|
340
|
-
"{AZDO_ORG_URL}/{
|
|
341
|
-
|
|
346
|
+
TIMELINE=$(curl -s -H "$AUTH" \
|
|
347
|
+
"{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/build/builds/$RUN_ID/timeline?api-version=7.0")
|
|
348
|
+
# Extract failed task names and log URLs
|
|
349
|
+
echo "$TIMELINE" | jq -r '.records[] | select(.result=="failed") | "\(.name): \(.log.url // "no log URL")"'
|
|
350
|
+
# Fetch actual log content from each failed task's log URL
|
|
351
|
+
for LOG_URL in $(echo "$TIMELINE" | jq -r '.records[] | select(.result=="failed") | .log.url // empty'); do
|
|
352
|
+
echo "=== Log: $LOG_URL ==="
|
|
353
|
+
curl -s -H "$AUTH" "$LOG_URL" | tail -50
|
|
354
|
+
done
|
|
342
355
|
|
|
343
356
|
2. **Analyze and fix**
|
|
344
357
|
Read the relevant source files, understand the failures, fix the code.
|
|
@@ -430,11 +443,11 @@ BRANCH_FLAGS: {--delete-branch (default) | omit if --keep-branch}
|
|
|
430
443
|
**If PLATFORM == azdo AND AZDO_MODE == rest:**
|
|
431
444
|
AUTH="Authorization: Basic $(echo -n ":{PAT}" | base64)"
|
|
432
445
|
REPO_NAME=$(basename -s .git "$(git remote get-url origin)")
|
|
433
|
-
PR_API="{AZDO_ORG_URL}/{
|
|
446
|
+
PR_API="{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/git/repositories/$REPO_NAME/pullrequests/{PR_NUMBER}"
|
|
434
447
|
|
|
435
448
|
# 1. Check for rejected policy evaluations
|
|
436
449
|
EVALS=$(curl -s -H "$AUTH" \
|
|
437
|
-
"{AZDO_ORG_URL}/{
|
|
450
|
+
"{AZDO_ORG_URL}/{AZDO_PROJECT_URL_SAFE}/_apis/policy/evaluations?artifactId=vstfs:///CodeReview/CodeReviewId/{AZDO_PROJECT_URL_SAFE}/{PR_NUMBER}&api-version=7.0")
|
|
438
451
|
REJECTED=$(echo "$EVALS" | jq '[.value[] | select(.status=="rejected")] | length')
|
|
439
452
|
if [ "$REJECTED" != "0" ]; then
|
|
440
453
|
echo "ERROR: PR has rejected policy evaluations — cannot merge"
|