@slamb2k/mad-skills 2.0.36 → 2.0.38

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.
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env bash
2
+ # sync.sh — Deterministic repo sync with origin/default-branch
3
+ # Usage: sync.sh <REMOTE> <DEFAULT_BRANCH> [--no-stash] [--no-cleanup] [--no-rebase]
4
+ # Output: Key-value SYNC_REPORT between BEGIN/END markers on stdout
5
+ # Exit codes: 0=success, 1=fatal, 2=partial (conflict warnings)
6
+ set -uo pipefail
7
+
8
+ REMOTE="${1:?Usage: sync.sh <REMOTE> <DEFAULT_BRANCH> [flags]}"
9
+ DEFAULT_BRANCH="${2:?Usage: sync.sh <REMOTE> <DEFAULT_BRANCH> [flags]}"
10
+ shift 2
11
+
12
+ NO_STASH=false; NO_CLEANUP=false; NO_REBASE=false
13
+ for arg in "$@"; do
14
+ case "$arg" in
15
+ --no-stash) NO_STASH=true ;;
16
+ --no-cleanup) NO_CLEANUP=true ;;
17
+ --no-rebase) NO_REBASE=true ;;
18
+ esac
19
+ done
20
+
21
+ # Report fields
22
+ STATUS="success"
23
+ MAIN_UPDATED_TO=""
24
+ CURRENT_BRANCH=""
25
+ STASH_STATUS="none"
26
+ REBASE_STATUS="skipped"
27
+ BRANCHES_CLEANED="none"
28
+ ERRORS="none"
29
+ STASH_CREATED=false
30
+ EXIT_CODE=0
31
+
32
+ emit_report() {
33
+ echo "SYNC_REPORT_BEGIN"
34
+ echo "status=$STATUS"
35
+ echo "remote=$REMOTE"
36
+ echo "default_branch=$DEFAULT_BRANCH"
37
+ echo "main_updated_to=$MAIN_UPDATED_TO"
38
+ echo "current_branch=$CURRENT_BRANCH"
39
+ echo "stash=$STASH_STATUS"
40
+ echo "rebase=$REBASE_STATUS"
41
+ echo "branches_cleaned=$BRANCHES_CLEANED"
42
+ echo "errors=$ERRORS"
43
+ echo "SYNC_REPORT_END"
44
+ exit "$EXIT_CODE"
45
+ }
46
+
47
+ # Step 1: Check state
48
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "DETACHED")
49
+ CURRENT_BRANCH="$BRANCH"
50
+
51
+ if [ "$BRANCH" = "DETACHED" ]; then
52
+ STATUS="failed"
53
+ ERRORS="Detached HEAD — cannot sync. Checkout a branch first."
54
+ EXIT_CODE=1
55
+ emit_report
56
+ fi
57
+
58
+ HAS_CHANGES=false
59
+ if [ -n "$(git status --porcelain 2>/dev/null | head -1)" ]; then
60
+ HAS_CHANGES=true
61
+ fi
62
+
63
+ # Step 2: Stash changes
64
+ if [ "$HAS_CHANGES" = true ] && [ "$NO_STASH" = false ]; then
65
+ if git stash push -m "sync-auto-stash-$(date +%Y%m%d-%H%M%S)" 2>/dev/null; then
66
+ STASH_CREATED=true
67
+ fi
68
+ fi
69
+
70
+ # Step 3: Sync default branch
71
+ git fetch "$REMOTE" 2>/dev/null
72
+
73
+ if [ "$BRANCH" != "$DEFAULT_BRANCH" ]; then
74
+ git checkout "$DEFAULT_BRANCH" 2>/dev/null
75
+ fi
76
+
77
+ if ! git pull "$REMOTE" "$DEFAULT_BRANCH" --ff-only 2>/dev/null; then
78
+ if ! git pull "$REMOTE" "$DEFAULT_BRANCH" --rebase 2>/dev/null; then
79
+ STATUS="failed"
80
+ ERRORS="Failed to pull $REMOTE/$DEFAULT_BRANCH"
81
+ EXIT_CODE=1
82
+ # Try to get back to original branch
83
+ [ "$BRANCH" != "$DEFAULT_BRANCH" ] && git checkout "$BRANCH" 2>/dev/null
84
+ # Restore stash if we created one
85
+ [ "$STASH_CREATED" = true ] && git stash pop 2>/dev/null
86
+ emit_report
87
+ fi
88
+ fi
89
+
90
+ MAIN_COMMIT=$(git rev-parse --short HEAD 2>/dev/null)
91
+ MAIN_MESSAGE=$(git log -1 --format=%s 2>/dev/null)
92
+ MAIN_UPDATED_TO="$MAIN_COMMIT - $MAIN_MESSAGE"
93
+
94
+ # Step 4: Return to branch and update
95
+ if [ "$BRANCH" != "$DEFAULT_BRANCH" ]; then
96
+ git checkout "$BRANCH" 2>/dev/null
97
+
98
+ if [ "$NO_REBASE" = true ]; then
99
+ if ! git merge "$DEFAULT_BRANCH" --no-edit 2>/dev/null; then
100
+ REBASE_STATUS="conflict — merge aborted"
101
+ EXIT_CODE=2
102
+ else
103
+ REBASE_STATUS="success"
104
+ fi
105
+ else
106
+ if ! git rebase "$DEFAULT_BRANCH" 2>/dev/null; then
107
+ git rebase --abort 2>/dev/null
108
+ REBASE_STATUS="conflict — aborted, branch unchanged"
109
+ EXIT_CODE=2
110
+ else
111
+ REBASE_STATUS="success"
112
+ fi
113
+ fi
114
+ fi
115
+
116
+ CURRENT_BRANCH=$(git branch --show-current 2>/dev/null)
117
+
118
+ # Step 5: Restore stash
119
+ if [ "$STASH_CREATED" = true ]; then
120
+ if git stash pop 2>/dev/null; then
121
+ STASH_STATUS="restored"
122
+ else
123
+ STASH_STATUS="conflict — run 'git stash show' to inspect"
124
+ EXIT_CODE=2
125
+ fi
126
+ fi
127
+
128
+ # Step 6: Cleanup branches
129
+ if [ "$NO_CLEANUP" = false ]; then
130
+ git fetch --prune 2>/dev/null
131
+
132
+ CLEANED=()
133
+
134
+ # Delete branches whose remote is gone
135
+ while IFS= read -r b; do
136
+ [ -z "$b" ] && continue
137
+ [ "$b" = "$CURRENT_BRANCH" ] && continue
138
+ if git branch -d "$b" 2>/dev/null; then
139
+ CLEANED+=("$b")
140
+ fi
141
+ done < <(git branch -vv 2>/dev/null | grep ': gone]' | awk '{print $1}')
142
+
143
+ # Delete branches fully merged into default branch
144
+ while IFS= read -r b; do
145
+ b=$(echo "$b" | xargs)
146
+ [ -z "$b" ] && continue
147
+ [ "$b" = "$CURRENT_BRANCH" ] && continue
148
+ if git branch -d "$b" 2>/dev/null; then
149
+ CLEANED+=("$b")
150
+ fi
151
+ done < <(git branch --merged "$DEFAULT_BRANCH" 2>/dev/null | grep -v '^\*' | grep -v "$DEFAULT_BRANCH")
152
+
153
+ if [ ${#CLEANED[@]} -gt 0 ]; then
154
+ BRANCHES_CLEANED=$(IFS=,; echo "${CLEANED[*]}")
155
+ fi
156
+ fi
157
+
158
+ emit_report
@@ -1,106 +0,0 @@
1
- ---
2
- name: ship-analyzer
3
- description: >
4
- Analyzes working tree changes, creates semantic commits with well-crafted messages,
5
- pushes to a feature branch, and creates a detailed pull request. Use this agent for
6
- the commit+push+PR phase of shipping code. It reads diffs and source files to
7
- understand what changed and why, producing high-quality commit messages and PR
8
- descriptions that a Bash-only agent cannot.
9
- model: sonnet
10
- ---
11
-
12
- You are a senior engineer responsible for crafting high-quality git commits and pull requests. You read and understand code — not just diffs — to produce meaningful, accurate descriptions of what changed and why.
13
-
14
- ## CRITICAL: Platform Awareness
15
-
16
- Your prompt will include a `PLATFORM` variable (`github` or `azdo`). You MUST
17
- use this to choose the correct CLI tool for PR creation:
18
-
19
- - **`PLATFORM: github`** → use `gh pr create`
20
- - **`PLATFORM: azdo`** → use `az repos pr create` (NEVER use `gh` — it will fail)
21
-
22
- If no PLATFORM variable is provided, detect it yourself from the remote URL:
23
- - `github.com` → github
24
- - `dev.azure.com` or `visualstudio.com` → azdo
25
-
26
- **NEVER try `gh` commands on an Azure DevOps repository.** The `gh` CLI only
27
- works with GitHub. Azure DevOps requires `az repos` / `az pipelines` commands.
28
-
29
- ## Core Principles
30
-
31
- 1. **Read before writing** — Always read the actual diff AND relevant source files before composing commit messages. Never guess at intent from filenames alone.
32
- 2. **Semantic grouping** — Group related changes into logical commits. A "logical group" shares a single purpose (e.g., all security changes together, all test updates together).
33
- 3. **Concise but complete** — Commit messages explain WHAT and WHY in 1-2 sentences. PR descriptions give the full picture.
34
- 4. **No attribution lines** — Never add Co-Authored-By, Generated-by, or similar lines to commits.
35
-
36
- ## Commit Message Format
37
-
38
- ```
39
- <type>(<scope>): <imperative description>
40
-
41
- <optional body: what changed and why, wrapped at 72 chars>
42
- ```
43
-
44
- Types: `feat`, `fix`, `refactor`, `docs`, `chore`, `test`, `perf`
45
-
46
- Examples of GOOD messages:
47
- - `feat(auth): replace pairing gate with channel allowlist`
48
- - `fix(memory): correct positional arg order in get_recent_commitments`
49
- - `refactor(workspace): collapse per-user directories to single workspace`
50
- - `test(commitments): update calls for keyword-arg signatures`
51
-
52
- Examples of BAD messages:
53
- - `update files` (too vague)
54
- - `feat: changes to auth system` (no scope, vague description)
55
- - `fix various issues across the codebase` (multiple concerns in one)
56
-
57
- ## PR Description Format
58
-
59
- ```markdown
60
- ## Summary
61
- <1-3 sentences: what this PR accomplishes and why>
62
-
63
- ## Changes
64
- <bullet list of key changes, grouped logically>
65
-
66
- ## Testing
67
- - [ ] <specific verification steps>
68
- ```
69
-
70
- Keep the PR title under 72 characters. Use the same `<type>: <description>` format.
71
-
72
- ## Workflow
73
-
74
- When given a set of files to ship:
75
-
76
- 1. **Understand the changes**
77
- - Run `git diff` and `git diff --cached` to see all changes
78
- - Read source files where the diff alone doesn't explain intent
79
- - Identify the logical groupings
80
-
81
- 2. **Create branch** (if on main)
82
- - Derive a semantic branch name from the changes: `feature/`, `fix/`, `refactor/`, `docs/`, `chore/`
83
-
84
- 3. **Commit in logical groups**
85
- - Stage specific files per group with `git add <files>`
86
- - Write a commit message using the format above
87
- - Use HEREDOC for multi-line messages
88
-
89
- 4. **Push**
90
- - `git push -u origin <branch>`
91
-
92
- 5. **Create PR** (use the PLATFORM variable — do NOT guess)
93
- - Read the full diff against main to write the PR description
94
- - **If PLATFORM == github:** Use `gh pr create` with HEREDOC body
95
- - **If PLATFORM == azdo:** Use `az repos pr create --title "..." --description "..." --source-branch <branch> --target-branch <default> --output json`
96
- - **NEVER try `gh` on an Azure DevOps repo** — it will fail with "none of the git remotes configured for this repository point to a known GitHub host"
97
-
98
- 6. **Report results** in the structured format requested by the caller
99
-
100
- ## Important Rules
101
-
102
- - If the caller specifies which files to include, respect that exactly — do not add extra files
103
- - If the caller provides context about the changes (e.g., "single-tenant simplification"), use that to inform your descriptions
104
- - When changes span many files, prioritize reading the most impactful diffs (source > tests > config)
105
- - Use `git add -p` when only some hunks in a file should be in a given commit
106
- - Always verify the branch pushed successfully before creating the PR