agy-superpowers 5.1.2 → 5.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +198 -175
  3. package/package.json +1 -1
  4. package/template/agent/.shared/mobile-uiux-promax/data/accessibility.csv +25 -0
  5. package/template/agent/.shared/mobile-uiux-promax/data/animation.csv +22 -0
  6. package/template/agent/.shared/mobile-uiux-promax/data/components.csv +21 -0
  7. package/template/agent/.shared/mobile-uiux-promax/data/gestures.csv +26 -0
  8. package/template/agent/.shared/mobile-uiux-promax/data/layout.csv +21 -0
  9. package/template/agent/.shared/mobile-uiux-promax/data/navigation.csv +27 -0
  10. package/template/agent/.shared/mobile-uiux-promax/data/onboarding.csv +17 -0
  11. package/template/agent/.shared/mobile-uiux-promax/data/platform.csv +22 -0
  12. package/template/agent/.shared/mobile-uiux-promax/data/stacks/flutter.csv +19 -0
  13. package/template/agent/.shared/mobile-uiux-promax/data/stacks/jetpack-compose.csv +18 -0
  14. package/template/agent/.shared/mobile-uiux-promax/data/stacks/react-native.csv +20 -0
  15. package/template/agent/.shared/mobile-uiux-promax/data/stacks/swiftui.csv +18 -0
  16. package/template/agent/.shared/mobile-uiux-promax/data/ux-laws.csv +16 -0
  17. package/template/agent/.shared/mobile-uiux-promax/scripts/mobile-search.py +157 -0
  18. package/template/agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  19. package/template/agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  20. package/template/agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  21. package/template/agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  22. package/template/agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  23. package/template/agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  24. package/template/agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  25. package/template/agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  26. package/template/agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  27. package/template/agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  28. package/template/agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  29. package/template/agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  30. package/template/agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  31. package/template/agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  32. package/template/agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  33. package/template/agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  34. package/template/agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  35. package/template/agent/.shared/ui-ux-pro-max/scripts/core.py +236 -0
  36. package/template/agent/.shared/ui-ux-pro-max/scripts/search.py +61 -0
  37. package/template/agent/.tests/TESTS.md +119 -0
  38. package/template/agent/.tests/mobile-uiux-promax/test_search.py +266 -0
  39. package/template/agent/.tests/run_tests.py +86 -0
  40. package/template/agent/patches/skills-patches.md +24 -0
  41. package/template/agent/rules/git-policy.md +25 -0
  42. package/template/agent/skills/brainstorming/SKILL.md +57 -0
  43. package/template/agent/skills/finishing-a-development-branch/SKILL.md +18 -6
  44. package/template/agent/skills/frontend-design/SKILL.md +147 -0
  45. package/template/agent/skills/frontend-design/reference/color-and-contrast.md +117 -0
  46. package/template/agent/skills/frontend-design/reference/interaction-design.md +159 -0
  47. package/template/agent/skills/frontend-design/reference/motion-design.md +150 -0
  48. package/template/agent/skills/frontend-design/reference/responsive-design.md +161 -0
  49. package/template/agent/skills/frontend-design/reference/spatial-design.md +122 -0
  50. package/template/agent/skills/frontend-design/reference/typography.md +124 -0
  51. package/template/agent/skills/frontend-design/reference/ux-writing.md +127 -0
  52. package/template/agent/skills/mobile-uiux-promax/SKILL.md +139 -0
  53. package/template/agent/skills/using-git-worktrees/SKILL.md +3 -1
  54. package/template/agent/skills/verification-before-completion/SKILL.md +11 -0
  55. package/template/agent/workflows/mobile-uiux-promax.md +137 -0
  56. package/template/agent/workflows/ui-ux-pro-max.md +231 -0
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive test suite for mobile-search.py
4
+ Tests all 9 domains, 4 stacks, edge cases, and data integrity.
5
+ """
6
+ import subprocess
7
+ import sys
8
+ import csv
9
+ from pathlib import Path
10
+
11
+ # Project root: 3 levels up (.agent/.tests/<skill>/test_*.py → project root)
12
+ BASE = str(Path(__file__).resolve().parents[3])
13
+ SCRIPT = f"{BASE}/.agent/.shared/mobile-uiux-promax/scripts/mobile-search.py"
14
+ DATA_DIR = f"{BASE}/.agent/.shared/mobile-uiux-promax/data"
15
+
16
+ passed = []
17
+ failed = []
18
+
19
+
20
+ def run(query, flag, target, n=3):
21
+ return subprocess.run(
22
+ ["python3", SCRIPT, query, flag, target, "-n", str(n)],
23
+ capture_output=True, text=True, cwd=BASE
24
+ )
25
+
26
+
27
+ def check(label, output, expected_kw, returncode=0):
28
+ ok_code = (output.returncode == returncode)
29
+ all_output = output.stdout + output.stderr
30
+ ok_kw = expected_kw.lower() in all_output.lower() if expected_kw else True
31
+ ok = ok_code and ok_kw
32
+ if ok:
33
+ passed.append(label)
34
+ print(f" ✅ {label}")
35
+ else:
36
+ failed.append(label)
37
+ reasons = []
38
+ if not ok_code:
39
+ reasons.append(f"returncode={output.returncode} (expected {returncode})")
40
+ if not ok_kw:
41
+ reasons.append(f"keyword '{expected_kw}' not found")
42
+ print(f" ❌ {label}")
43
+ for r in reasons:
44
+ print(f" → {r}")
45
+ print(f" → stdout[:300]: {output.stdout[:300]!r}")
46
+
47
+
48
+ # ═══════════════════════════════════════════════════════════
49
+ # GROUP 1: Navigation domain
50
+ # ═══════════════════════════════════════════════════════════
51
+ print("\n📍 GROUP 1: Navigation domain")
52
+ check("tab bar primary sections", run("bottom tab bar primary sections", "--domain", "navigation"), "Tab Bar")
53
+ check("hamburger discoverability", run("hamburger hidden navigation discoverability", "--domain", "navigation"), "discoverability")
54
+ check("thumb zone ergonomics", run("thumb zone one handed ergonomics bottom", "--domain", "navigation"), "Thumb")
55
+ check("drawer sidebar menu", run("drawer sidebar menu hamburger secondary", "--domain", "navigation"), "Drawer")
56
+ check("modal full screen overlay", run("modal full screen immersive camera auth", "--domain", "navigation"), "Modal")
57
+ check("bottom sheet partial", run("bottom sheet action partial overlay", "--domain", "navigation"), "Bottom Sheet")
58
+ check("deep link universal", run("deep link universal link routing url", "--domain", "navigation"), "Deep Link")
59
+ check("back navigation ios swipe", run("back navigation ios swipe gesture return", "--domain", "navigation"), "Back")
60
+
61
+ # ═══════════════════════════════════════════════════════════
62
+ # GROUP 2: Gestures domain
63
+ # ═══════════════════════════════════════════════════════════
64
+ print("\n📍 GROUP 2: Gestures domain")
65
+ check("swipe back ios edge", run("swipe back dismiss ios edge left", "--domain", "gestures"), "Swipe")
66
+ check("pinch zoom two finger", run("pinch zoom scale two finger gesture", "--domain", "gestures"), "Pinch")
67
+ check("long press context menu", run("long press hold context menu action", "--domain", "gestures"), "Long")
68
+ check("pull to refresh scroll", run("pull to refresh scroll top reload", "--domain", "gestures"), "Pull")
69
+ check("double tap zoom toggle", run("double tap zoom toggle like", "--domain", "gestures"), "Double")
70
+
71
+ # ═══════════════════════════════════════════════════════════
72
+ # GROUP 3: Components domain
73
+ # ═══════════════════════════════════════════════════════════
74
+ print("\n📍 GROUP 3: Components domain")
75
+ check("bottom sheet component", run("bottom sheet modal partial screen", "--domain", "components"), "Bottom Sheet")
76
+ check("FAB floating action button", run("floating action button primary create", "--domain", "components"), "FAB")
77
+ check("skeleton loading shimmer", run("skeleton loading placeholder shimmer", "--domain", "components"), "Skeleton")
78
+ check("snackbar toast feedback", run("snackbar toast feedback notification", "--domain", "components"), "Snackbar")
79
+ check("chip filter tag", run("chip filter tag selection category", "--domain", "components"), "Chip")
80
+
81
+ # ═══════════════════════════════════════════════════════════
82
+ # GROUP 4: Layout domain
83
+ # ═══════════════════════════════════════════════════════════
84
+ print("\n📍 GROUP 4: Layout domain")
85
+ check("safe area notch inset", run("safe area notch inset dynamic island", "--domain", "layout"), "Safe Area")
86
+ check("touch target 44pt 48dp", run("touch target minimum size 44pt 48dp", "--domain", "layout"), "44")
87
+ check("thumb zone bottom reach", run("thumb zone reachability bottom reach", "--domain", "layout"), "Thumb")
88
+ check("keyboard avoidance input", run("keyboard avoidance input scroll TextField", "--domain", "layout"), "Keyboard")
89
+ check("spacing design system 8pt", run("spacing 8pt grid system padding margin", "--domain", "layout"), "8")
90
+
91
+ # ═══════════════════════════════════════════════════════════
92
+ # GROUP 5: Platform domain
93
+ # ═══════════════════════════════════════════════════════════
94
+ print("\n📍 GROUP 5: Platform domain")
95
+ check("dark mode system appearance", run("dark mode night system appearance adaptive", "--domain", "platform"), "Dark Mode")
96
+ check("haptic feedback vibration", run("haptic feedback vibration taptic engine", "--domain", "platform"), "Haptic")
97
+ check("typography font system", run("typography font ios android system native", "--domain", "platform"), "Typography")
98
+ check("navigation ios android diff", run("navigation back button ios android differ", "--domain", "platform"), "Navigation")
99
+ check("status bar appearance", run("status bar color tint appearance", "--domain", "platform"), "Status Bar")
100
+
101
+ # ═══════════════════════════════════════════════════════════
102
+ # GROUP 6: Onboarding domain
103
+ # ═══════════════════════════════════════════════════════════
104
+ print("\n📍 GROUP 6: Onboarding domain")
105
+ check("permission priming camera", run("permission priming rationale camera notification", "--domain", "onboarding"), "Permission")
106
+ check("paywall timing subscription", run("paywall timing subscription trial premium", "--domain", "onboarding"), "Paywall")
107
+ check("sign in apple social", run("sign in with apple social login auth", "--domain", "onboarding"), "Sign in with Apple")
108
+ check("value proposition screen", run("value proposition benefit feature showcase", "--domain", "onboarding"), "Value")
109
+ check("progress step indicator", run("onboarding step indicator progress multi", "--domain", "onboarding"), "Step")
110
+
111
+ # ═══════════════════════════════════════════════════════════
112
+ # GROUP 7: Animation domain
113
+ # ═══════════════════════════════════════════════════════════
114
+ print("\n📍 GROUP 7: Animation domain")
115
+ check("spring animation modal", run("spring animation modal sheet natural", "--domain", "animation"), "Spring")
116
+ check("skeleton shimmer loading", run("skeleton shimmer loading placeholder animation", "--domain", "animation"), "Shimmer")
117
+ check("reduce motion accessibility", run("reduce motion accessibility preference disable", "--domain", "animation"), "Reduce")
118
+ check("page transition navigation", run("page transition navigation push slide", "--domain", "animation"), "Transition")
119
+ check("haptic sync animation", run("haptic feedback sync animation success", "--domain", "animation"), "Haptic")
120
+
121
+ # ═══════════════════════════════════════════════════════════
122
+ # GROUP 8: Accessibility domain
123
+ # ═══════════════════════════════════════════════════════════
124
+ print("\n📍 GROUP 8: Accessibility domain")
125
+ check("touch target 44pt minimum", run("touch target size minimum 44pt", "--domain", "accessibility"), "Touch Target")
126
+ check("screen reader label name", run("screen reader voiceover label accessible name", "--domain", "accessibility"), "Screen Reader")
127
+ check("view-tap asymmetry small", run("view tap asymmetry visible untappable small dot", "--domain", "accessibility"), "Asymmetry")
128
+ check("color contrast ratio 4.5:1", run("color contrast ratio 4.5 text background", "--domain", "accessibility"), "Contrast")
129
+ check("dynamic type font scaling", run("dynamic type font scaling text size large", "--domain", "accessibility"), "Dynamic Type")
130
+ check("NNGroup 1cm physical touch", run("NNGroup physical 1cm touch target research", "--domain", "accessibility"), "NNGroup")
131
+ check("coach mark single tip", run("coach mark single tip one at a time overlay", "--domain", "accessibility"), "Coach Mark")
132
+
133
+ # ═══════════════════════════════════════════════════════════
134
+ # GROUP 9: UX Laws domain
135
+ # ═══════════════════════════════════════════════════════════
136
+ print("\n📍 GROUP 9: UX Laws domain")
137
+ check("Fitts touch target size", run("touch target size placement distance primary", "--domain", "ux-laws"), "Fitts")
138
+ check("Hick choices decision time", run("choices menu options decision time complexity", "--domain", "ux-laws"), "Hick")
139
+ check("Jakob mental model familiar", run("mental model convention familiar platform", "--domain", "ux-laws"), "Jakob")
140
+ check("Goal-Gradient progress bar", run("progress steps completion motivation reward", "--domain", "ux-laws"), "Goal-Gradient")
141
+ check("Peak-End memorable delight", run("memorable experience delight success moment", "--domain", "ux-laws"), "Peak")
142
+ check("Doherty 400ms threshold", run("400ms response time loading feedback threshold", "--domain", "ux-laws"), "Doherty")
143
+ check("Miller 7 items memory", run("7 chunks working memory cognitive load limit", "--domain", "ux-laws"), "Miller")
144
+ check("Zeigarnik streak incomplete", run("streak incomplete task engagement retention", "--domain", "ux-laws"), "Zeigarnik")
145
+ check("Von Restorff standout color", run("standout highlight color accent primary call", "--domain", "ux-laws"), "Von Restorff")
146
+ check("Serial Position first last", run("first last item serial position memory recall", "--domain", "ux-laws"), "Serial Position")
147
+ check("Proximity grouping related", run("proximity grouping related elements spacing", "--domain", "ux-laws"), "Proximity")
148
+ check("Common Region card container",run("card container region visual grouping border", "--domain", "ux-laws"), "Common Region")
149
+ check("Paradox coach mark tutorial", run("tutorial coach mark skip learn by doing", "--domain", "ux-laws"), "Paradox")
150
+
151
+ # ═══════════════════════════════════════════════════════════
152
+ # GROUP 10: Stack — React Native
153
+ # ═══════════════════════════════════════════════════════════
154
+ print("\n📍 GROUP 10: Stack — React Native")
155
+ check("FlatList performance", run("FlatList list performance rendering key", "--stack", "react-native"), "FlatList")
156
+ check("Reanimated animations", run("Reanimated animation gesture performant", "--stack", "react-native"), "Reanimated")
157
+ check("accessibilityLabel VoiceOver",run("accessibilityLabel accessible name VoiceOver", "--stack", "react-native"), "accessibilityLabel")
158
+ check("Metro bundler fast refresh", run("Metro bundler fast refresh hot reload", "--stack", "react-native"), "Metro")
159
+
160
+ # ═══════════════════════════════════════════════════════════
161
+ # GROUP 11: Stack — Flutter
162
+ # ═══════════════════════════════════════════════════════════
163
+ print("\n📍 GROUP 11: Stack — Flutter")
164
+ check("GoRouter navigation", run("GoRouter routing navigation deep link", "--stack", "flutter"), "GoRouter")
165
+ check("ListView.builder lazy", run("ListView builder lazy performance list", "--stack", "flutter"), "ListView")
166
+ check("Riverpod state management", run("Riverpod state management provider", "--stack", "flutter"), "Riverpod")
167
+ check("MediaQuery safe area", run("MediaQuery safe area padding inset", "--stack", "flutter"), "MediaQuery")
168
+
169
+ # ═══════════════════════════════════════════════════════════
170
+ # GROUP 12: Stack — SwiftUI
171
+ # ═══════════════════════════════════════════════════════════
172
+ print("\n📍 GROUP 12: Stack — SwiftUI")
173
+ check("NavigationStack push view", run("NavigationStack navigation push screen iOS", "--stack", "swiftui"), "NavigationStack")
174
+ check("@StateObject ViewModel", run("StateObject ViewModel lifecycle init", "--stack", "swiftui"), "StateObject")
175
+ check("reduce motion isReduceMotion",run("reduce motion isReduceMotionEnabled animation", "--stack", "swiftui"), "reduceMotion")
176
+ check("task modifier async load", run("task async await data loading onAppear", "--stack", "swiftui"), "task")
177
+
178
+ # ═══════════════════════════════════════════════════════════
179
+ # GROUP 13: Stack — Jetpack Compose
180
+ # ═══════════════════════════════════════════════════════════
181
+ print("\n📍 GROUP 13: Stack — Jetpack Compose")
182
+ check("LazyColumn list performance", run("LazyColumn list performance lazy scroll", "--stack", "jetpack-compose"), "LazyColumn")
183
+ check("sealed UiState data class", run("sealed class UiState loading error success", "--stack", "jetpack-compose"), "sealed")
184
+ check("WindowInsets edge-to-edge", run("WindowInsets edge to edge insets system bar", "--stack", "jetpack-compose"), "WindowInsets")
185
+ check("remember derivedStateOf", run("remember derivedStateOf state performance recomposition", "--stack", "jetpack-compose"), "derivedStateOf")
186
+
187
+ # ═══════════════════════════════════════════════════════════
188
+ # GROUP 14: Edge Cases
189
+ # ═══════════════════════════════════════════════════════════
190
+ print("\n📍 GROUP 14: Edge Cases")
191
+
192
+ # -n flag returns correct count
193
+ r = run("navigation tab bottom bar", "--domain", "navigation", n=5)
194
+ count = r.stdout.count("### Result")
195
+ ok = count == 5
196
+ (passed if ok else failed).append("navigation: -n 5 returns 5 results")
197
+ print(f" {'✅' if ok else '❌'} -n 5 flag returns 5 results (got {count})")
198
+
199
+ # invalid domain → non-zero exit
200
+ r_bad = subprocess.run(["python3", SCRIPT, "test", "--domain", "foobar"],
201
+ capture_output=True, text=True, cwd=BASE)
202
+ check("invalid domain → error exit", r_bad, None, returncode=2)
203
+
204
+ # invalid stack → non-zero exit
205
+ r_bad2 = subprocess.run(["python3", SCRIPT, "test", "--stack", "xamarin"],
206
+ capture_output=True, text=True, cwd=BASE)
207
+ check("invalid stack → error exit", r_bad2, None, returncode=2)
208
+
209
+ # no flag → non-zero exit
210
+ r_bad3 = subprocess.run(["python3", SCRIPT, "hello"],
211
+ capture_output=True, text=True, cwd=BASE)
212
+ check("no --domain/--stack → error", r_bad3, None, returncode=2)
213
+
214
+ # zero results for nonsense query → "No results" message
215
+ r_zero = run("xyzxyzxyz_gibberish_asdfqwer", "--domain", "navigation")
216
+ check("gibberish query → no crash", r_zero, "results", returncode=0)
217
+
218
+ # ═══════════════════════════════════════════════════════════
219
+ # GROUP 15: Data Integrity
220
+ # ═══════════════════════════════════════════════════════════
221
+ print("\n📍 GROUP 15: Data Integrity (row counts)")
222
+
223
+ expected_min_rows = {
224
+ "navigation.csv": 20,
225
+ "gestures.csv": 20,
226
+ "components.csv": 15,
227
+ "layout.csv": 15,
228
+ "platform.csv": 15,
229
+ "onboarding.csv": 12,
230
+ "animation.csv": 15,
231
+ "accessibility.csv": 20,
232
+ "ux-laws.csv": 12,
233
+ "stacks/react-native.csv": 15,
234
+ "stacks/flutter.csv": 15,
235
+ "stacks/swiftui.csv": 14,
236
+ "stacks/jetpack-compose.csv": 14,
237
+ }
238
+
239
+ for fname, min_rows in expected_min_rows.items():
240
+ fpath = Path(DATA_DIR) / fname
241
+ if not fpath.exists():
242
+ failed.append(f"file exists: {fname}")
243
+ print(f" ❌ file exists: {fname} → FILE MISSING")
244
+ continue
245
+ with open(fpath, encoding="utf-8") as f:
246
+ rows = list(csv.reader(f))
247
+ data_rows = len(rows) - 1 # minus header
248
+ ok = data_rows >= min_rows
249
+ (passed if ok else failed).append(f"row count: {fname}")
250
+ print(f" {'✅' if ok else '❌'} {fname}: {data_rows} rows (min {min_rows})")
251
+
252
+ # ═══════════════════════════════════════════════════════════
253
+ # FINAL REPORT
254
+ # ═══════════════════════════════════════════════════════════
255
+ total = len(passed) + len(failed)
256
+ pct = int(100 * len(passed) / total) if total else 0
257
+ print(f"\n{'═'*55}")
258
+ print(f" TOTAL TESTS : {total}")
259
+ print(f" PASSED : {len(passed)} ({pct}%)")
260
+ print(f" FAILED : {len(failed)}")
261
+ if failed:
262
+ print(f"\n ❌ FAILED TESTS:")
263
+ for f in failed:
264
+ print(f" - {f}")
265
+ print(f"{'═'*55}")
266
+ sys.exit(0 if not failed else 1)
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ .agent/.tests/run_tests.py
4
+ Auto-discover and run all test_*.py files for a given skill.
5
+
6
+ Usage:
7
+ python3 .agent/.tests/run_tests.py mobile-uiux-promax
8
+ python3 .agent/.tests/run_tests.py --all
9
+ """
10
+ import sys
11
+ import subprocess
12
+ from pathlib import Path
13
+
14
+ ROOT = Path(__file__).resolve().parent # .agent/.tests/
15
+
16
+
17
+ def run_suite(skill_name: str) -> tuple[int, int]:
18
+ """Run all test_*.py in .agent/.tests/<skill_name>/. Returns (passed_files, failed_files)."""
19
+ suite_dir = ROOT / skill_name
20
+ if not suite_dir.exists():
21
+ print(f" ⚠️ No test suite found for '{skill_name}' at {suite_dir}")
22
+ return 0, 0
23
+
24
+ test_files = sorted(suite_dir.glob("test_*.py"))
25
+ if not test_files:
26
+ print(f" ⚠️ No test_*.py files found in {suite_dir}")
27
+ return 0, 0
28
+
29
+ passed_files = 0
30
+ failed_files = 0
31
+
32
+ for tf in test_files:
33
+ print(f" → {tf.name}")
34
+ result = subprocess.run(
35
+ ["python3", str(tf)],
36
+ capture_output=False, # let output stream directly (verbose)
37
+ cwd=str(ROOT.parent.parent), # project root
38
+ )
39
+ if result.returncode == 0:
40
+ passed_files += 1
41
+ else:
42
+ failed_files += 1
43
+
44
+ return passed_files, failed_files
45
+
46
+
47
+ def main():
48
+ args = sys.argv[1:]
49
+
50
+ if not args:
51
+ print("Usage: python3 run_tests.py <skill-name> OR --all")
52
+ sys.exit(1)
53
+
54
+ if args[0] == "--all":
55
+ skills = [d.name for d in ROOT.iterdir() if d.is_dir() and not d.name.startswith(".")]
56
+ if not skills:
57
+ print("No test suites found.")
58
+ sys.exit(0)
59
+ else:
60
+ skills = [args[0]]
61
+
62
+ total_passed = total_failed = 0
63
+
64
+ for skill in skills:
65
+ print(f"\n🧪 Running tests for: {skill}")
66
+ p, f = run_suite(skill)
67
+ total_passed += p
68
+ total_failed += f
69
+
70
+ total = total_passed + total_failed
71
+ if total == 0:
72
+ print("\nNo test files executed.")
73
+ sys.exit(0)
74
+
75
+ print(f"\n{'═' * 55}")
76
+ if total_failed == 0:
77
+ print(f" ✅ ALL SUITES PASSED ({total_passed}/{total} files)")
78
+ else:
79
+ print(f" ❌ {total_failed} SUITE(S) FAILED ({total_passed}/{total} files passed)")
80
+ print(f"{'═' * 55}")
81
+
82
+ sys.exit(0 if total_failed == 0 else 1)
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -92,3 +92,27 @@ Update any diagram labels that mention "commits" to reflect this conditionality
92
92
  **Intent:** Make the "Commit your work" step in the implementer's job list conditional:
93
93
  - Change "4. Commit your work" to "4. Commit your work (if auto_commit is enabled)"
94
94
  - Add sub-steps: read `.agent/config.yml`, if `auto_commit: true` (or not set): `git add` + `git commit`, if `auto_commit: false`: skip commit and staging entirely, print skip message.
95
+
96
+ ---
97
+
98
+ ## Patch: git-policy rule — finishing-a-development-branch
99
+
100
+ **File:** `finishing-a-development-branch/SKILL.md`
101
+ **Intent:** Before each git write operation in Execute Choice (Option 1: merge + branch delete,
102
+ Option 2: push, Option 4: branch delete), add an explicit `auto_commit` check:
103
+ - Read `.agent/config.yml` before the git operation
104
+ - If `auto_commit: false`: skip the operation, print "Skipping git operation (auto_commit: false)."
105
+ - If `auto_commit: true` (or absent): proceed normally.
106
+
107
+ ---
108
+
109
+ ## Patch: git-policy rule — using-git-worktrees
110
+
111
+ **File:** `using-git-worktrees/SKILL.md`
112
+ **Intent:** In the "If NOT ignored" safety verification block, make the git commit step conditional:
113
+ - Step 1 (add to .gitignore): always runs — file edit is not a git write operation
114
+ - Step 2 (commit): check `auto_commit` in `.agent/config.yml`
115
+ - If `false`: skip commit, print "Skipping git operation (auto_commit: false)."
116
+ - If `true` (or absent): `git add .gitignore && git commit -m "chore: ignore worktree directory"`
117
+ - Step 3 (proceed with worktree creation): always runs
118
+
@@ -0,0 +1,25 @@
1
+ # Git Policy
2
+
3
+ <HARD-GATE>
4
+ Before running ANY git write operation — git add, git commit, git push,
5
+ git pull, git merge, git tag, git branch -d, git branch -D, git worktree remove,
6
+ git rebase, git cherry-pick, git reset --hard —
7
+ you MUST read `.agent/config.yml` and check the `auto_commit` setting.
8
+
9
+ If `auto_commit: false`:
10
+ - DO NOT run the operation
11
+ - Print exactly: "Skipping git operation (auto_commit: false)."
12
+ - Continue with the rest of the task (non-git steps still execute)
13
+
14
+ If `auto_commit: true` (or key is absent): proceed normally.
15
+ </HARD-GATE>
16
+
17
+ This applies everywhere — inside skills, workflows, and any ad-hoc actions.
18
+ No exceptions.
19
+
20
+ ## Always Allowed (read-only)
21
+
22
+ These operations are never blocked:
23
+ - `git status`, `git log`, `git diff`, `git show`
24
+ - `git worktree add`, `git worktree list`
25
+ - `git checkout <branch>` (navigation only)
@@ -25,6 +25,7 @@ You MUST create a task for each of these items and complete them in order:
25
25
  2. **Offer visual companion** (if topic will involve visual questions) — this is its own message, not combined with a clarifying question. See the Visual Companion section below.
26
26
  3. **Ask clarifying questions** — one at a time, understand purpose/constraints/success criteria
27
27
  4. **Propose 2-3 approaches** — with trade-offs and your recommendation
28
+ - *UI/visual tasks only:* Before proposing, run `search.py` to gather style, typography, color, and UX data so proposals are grounded in real design patterns. See the [UI/UX Intelligence](#uiux-intelligence) section below.
28
29
  5. **Present design** — in sections scaled to their complexity, get user approval after each section
29
30
  6. **Write design doc** — save to `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md` and commit
30
31
  7. **Spec review loop** — dispatch spec-document-reviewer subagent with precisely crafted review context (never your session history); fix issues and re-dispatch until approved (max 3 iterations, then surface to human)
@@ -86,6 +87,62 @@ digraph brainstorming {
86
87
  - Present options conversationally with your recommendation and reasoning
87
88
  - Lead with your recommended option and explain why
88
89
 
90
+ ## UI/UX Intelligence
91
+
92
+ **When the task involves any visual/UI work** (landing pages, dashboards, components, screens, design systems), run the UI/UX Pro Max search tool **before** presenting the design. This grounds your proposals in a curated knowledge base rather than generic defaults.
93
+
94
+ **How to trigger:**
95
+
96
+ ```bash
97
+ python3 .agent/.shared/ui-ux-pro-max/scripts/search.py "<keyword>" --domain <domain>
98
+ ```
99
+
100
+ **Recommended search sequence** (run in parallel where possible):
101
+
102
+ | # | Domain | What to search | Example |
103
+ |---|--------|----------------|---------|
104
+ | 1 | `product` | Product type + industry | `"SaaS dashboard"`, `"beauty landing page"` |
105
+ | 2 | `style` | Desired visual style | `"glassmorphism dark"`, `"minimal clean"` |
106
+ | 3 | `typography` | Mood/personality | `"elegant modern"`, `"playful friendly"` |
107
+ | 4 | `color` | Industry or product type | `"fintech"`, `"healthcare"`, `"beauty spa"` |
108
+ | 5 | `landing` | Page structure type | `"hero-centric social-proof"` |
109
+ | 6 | `ux` | `"animation"`, `"accessibility"`, `"z-index"` | Always check these three |
110
+ | 7 | `stack` | Target framework | `--stack react-native`, `--stack flutter` |
111
+
112
+ **When to use each domain:**
113
+ - Always run `product` + `style` + `ux` as a baseline for any UI task
114
+ - Add `typography` + `color` when presenting a full design system
115
+ - Add `landing` only for marketing/landing pages
116
+ - Add `chart` only for analytics dashboards
117
+ - Use `--stack` flag to get implementation-specific patterns (e.g., `--stack react-native` for mobile)
118
+
119
+ **Synthesize results before presenting design:** Do not dump raw search output to the user. Summarize what you found and explain how it informs your design choices.
120
+
121
+ > **Skip this step** for purely backend, data-model, or logic-only tasks where no UI is involved.
122
+
123
+ ### Mobile UI/UX Intelligence (Extended Layer)
124
+
125
+ **When the request is for a mobile app** — detect keywords like: `iOS`, `Android`, `React Native`, `Flutter`, `SwiftUI`, `Jetpack Compose`, `mobile`, `app screen`, `native app` — run the **mobile-uiux-promax workflow** IN ADDITION to the web tool above.
126
+
127
+ Read the workflow file first: `.agent/workflows/mobile-uiux-promax.md`
128
+
129
+ The mobile workflow adds 3 more steps after the web style layer:
130
+
131
+ ```bash
132
+ # Step 2: Mobile behavior
133
+ python3 .agent/.shared/mobile-uiux-promax/scripts/mobile-search.py "<nav pattern>" --domain navigation
134
+ python3 .agent/.shared/mobile-uiux-promax/scripts/mobile-search.py "<component>" --domain components
135
+ python3 .agent/.shared/mobile-uiux-promax/scripts/mobile-search.py "<platform topic>" --domain platform
136
+ python3 .agent/.shared/mobile-uiux-promax/scripts/mobile-search.py "<animation>" --domain animation
137
+
138
+ # Step 3: Stack guidelines (react-native / flutter / swiftui / jetpack-compose)
139
+ python3 .agent/.shared/mobile-uiux-promax/scripts/mobile-search.py "<topic>" --stack react-native
140
+
141
+ # Step 4: Synthesize style + mobile behavior + stack patterns → present design
142
+ ```
143
+
144
+ Read and apply the mobile-uiux-promax skill: `.agent/skills/mobile-uiux-promax/SKILL.md`
145
+
89
146
  **Presenting the design:**
90
147
 
91
148
  - Once you believe you understand what you're building, present the design
@@ -67,20 +67,24 @@ Which option?
67
67
 
68
68
  #### Option 1: Merge Locally
69
69
 
70
+ **Before git write steps:** Check `.agent/config.yml` for `auto_commit`.
71
+ - If `auto_commit: false`: skip all git write operations below, print "Skipping git operation (auto_commit: false)."
72
+ - If `auto_commit: true` (or absent): proceed normally.
73
+
70
74
  ```bash
71
75
  # Switch to base branch
72
76
  git checkout <base-branch>
73
77
 
74
- # Pull latest
78
+ # Pull latest (blocked if auto_commit: false)
75
79
  git pull
76
80
 
77
- # Merge feature branch
81
+ # Merge feature branch (blocked if auto_commit: false)
78
82
  git merge <feature-branch>
79
83
 
80
84
  # Verify tests on merged result
81
85
  <test command>
82
86
 
83
- # If tests pass
87
+ # If tests pass (blocked if auto_commit: false)
84
88
  git branch -d <feature-branch>
85
89
  ```
86
90
 
@@ -88,11 +92,15 @@ Then: Cleanup worktree (Step 5)
88
92
 
89
93
  #### Option 2: Push and Create PR
90
94
 
95
+ **Before git write steps:** Check `.agent/config.yml` for `auto_commit`.
96
+ - If `auto_commit: false`: skip all git write operations below, print "Skipping git operation (auto_commit: false)."
97
+ - If `auto_commit: true` (or absent): proceed normally.
98
+
91
99
  ```bash
92
- # Push branch
100
+ # Push branch (blocked if auto_commit: false)
93
101
  git push -u origin <feature-branch>
94
102
 
95
- # Create PR
103
+ # Create PR (blocked if auto_commit: false)
96
104
  gh pr create --title "<title>" --body "$(cat <<'EOF'
97
105
  ## Summary
98
106
  <2-3 bullets of what changed>
@@ -125,10 +133,14 @@ Type 'discard' to confirm.
125
133
 
126
134
  Wait for exact confirmation.
127
135
 
136
+ **Before git write steps:** Check `.agent/config.yml` for `auto_commit`.
137
+ - If `auto_commit: false`: skip all git write operations below, print "Skipping git operation (auto_commit: false)."
138
+ - If `auto_commit: true` (or absent): proceed normally.
139
+
128
140
  If confirmed:
129
141
  ```bash
130
142
  git checkout <base-branch>
131
- git branch -D <feature-branch>
143
+ git branch -D <feature-branch> # blocked if auto_commit: false
132
144
  ```
133
145
 
134
146
  Then: Cleanup worktree (Step 5)