opencode-skills-collection 3.0.37 → 3.0.39

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 (73) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +13 -1
  2. package/bundled-skills/2slides-ppt-generator/SKILL.md +786 -0
  3. package/bundled-skills/2slides-ppt-generator/references/api-reference.md +499 -0
  4. package/bundled-skills/2slides-ppt-generator/references/mcp-integration.md +282 -0
  5. package/bundled-skills/2slides-ppt-generator/references/pricing.md +195 -0
  6. package/bundled-skills/2slides-ppt-generator/scripts/api_constants.py +87 -0
  7. package/bundled-skills/2slides-ppt-generator/scripts/create_pdf_slides.py +159 -0
  8. package/bundled-skills/2slides-ppt-generator/scripts/download_slides_pages_voices.py +157 -0
  9. package/bundled-skills/2slides-ppt-generator/scripts/generate_narration.py +197 -0
  10. package/bundled-skills/2slides-ppt-generator/scripts/generate_slides.py +247 -0
  11. package/bundled-skills/2slides-ppt-generator/scripts/get_job_status.py +106 -0
  12. package/bundled-skills/2slides-ppt-generator/scripts/search_themes.py +137 -0
  13. package/bundled-skills/anti-sycophancy/README.md +86 -0
  14. package/bundled-skills/anti-sycophancy/SKILL.md +40 -0
  15. package/bundled-skills/antigravity-agent-manager/SKILL.md +112 -0
  16. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  17. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  18. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  19. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  20. package/bundled-skills/docs/sources/sources.md +1 -0
  21. package/bundled-skills/docs/users/bundles.md +1 -1
  22. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  23. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  24. package/bundled-skills/docs/users/getting-started.md +1 -1
  25. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  26. package/bundled-skills/docs/users/usage.md +4 -4
  27. package/bundled-skills/docs/users/visual-guide.md +4 -4
  28. package/bundled-skills/event-staffing-compliance/SKILL.md +91 -0
  29. package/bundled-skills/event-staffing-ordering/SKILL.md +119 -0
  30. package/bundled-skills/examprep-ai/SKILL.md +446 -0
  31. package/bundled-skills/hasdata/SKILL.md +107 -0
  32. package/bundled-skills/hasdata/references/code-recipes.md +150 -0
  33. package/bundled-skills/hasdata/references/ecommerce.md +116 -0
  34. package/bundled-skills/hasdata/references/jobs.md +111 -0
  35. package/bundled-skills/hasdata/references/local-business.md +145 -0
  36. package/bundled-skills/hasdata/references/real-estate.md +84 -0
  37. package/bundled-skills/hasdata/references/scraper-jobs.md +252 -0
  38. package/bundled-skills/hasdata/references/search.md +154 -0
  39. package/bundled-skills/hasdata/references/travel.md +202 -0
  40. package/bundled-skills/hasdata/references/web-scraping.md +159 -0
  41. package/bundled-skills/hasdata/references/youtube.md +186 -0
  42. package/bundled-skills/hasdata-cli/SKILL.md +169 -0
  43. package/bundled-skills/hasdata-cli/references/all-commands.md +107 -0
  44. package/bundled-skills/hasdata-cli/references/ecommerce.md +106 -0
  45. package/bundled-skills/hasdata-cli/references/enrichment.md +227 -0
  46. package/bundled-skills/hasdata-cli/references/jobs.md +84 -0
  47. package/bundled-skills/hasdata-cli/references/local-business.md +123 -0
  48. package/bundled-skills/hasdata-cli/references/real-estate.md +126 -0
  49. package/bundled-skills/hasdata-cli/references/search.md +122 -0
  50. package/bundled-skills/hasdata-cli/references/travel.md +102 -0
  51. package/bundled-skills/hasdata-cli/references/web-scraping.md +181 -0
  52. package/bundled-skills/hasdata-cli/references/youtube.md +145 -0
  53. package/bundled-skills/linkedin-content-generator/SKILL.md +492 -0
  54. package/bundled-skills/linkedin-content-generator/scripts/generate_calendar.py +82 -0
  55. package/bundled-skills/linkedin-content-generator/scripts/generate_carousel.py +69 -0
  56. package/bundled-skills/linkedin-content-generator/scripts/generate_newsletter.py +64 -0
  57. package/bundled-skills/linkedin-content-generator/scripts/generate_post.py +77 -0
  58. package/bundled-skills/linkedin-content-generator/scripts/memory.md +49 -0
  59. package/bundled-skills/linkedin-content-generator/scripts/memory_manager.py +134 -0
  60. package/bundled-skills/linkedin-content-generator/scripts/utils.py +96 -0
  61. package/bundled-skills/permission-manager/README.md +22 -0
  62. package/bundled-skills/permission-manager/SKILL.md +54 -0
  63. package/bundled-skills/skill-suggester/README.md +14 -0
  64. package/bundled-skills/skill-suggester/SKILL.md +69 -0
  65. package/bundled-skills/smart-git-automation/README.md +31 -0
  66. package/bundled-skills/smart-git-automation/SKILL.md +96 -0
  67. package/bundled-skills/vercel-optimize/lib/cost-coverage.mjs +3 -1
  68. package/bundled-skills/vercel-optimize/lib/render-report.mjs +2 -2
  69. package/bundled-skills/vercel-optimize/lib/util.mjs +7 -0
  70. package/bundled-skills/vercel-optimize/lib/verify-claim.mjs +2 -7
  71. package/bundled-skills/vercel-optimize/lib/workspace-resolver.mjs +2 -1
  72. package/package.json +1 -1
  73. package/skills_index.json +268 -0
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Generate slides using the 2slides API.
4
+ Supports both content-based and reference image-based generation.
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import json
10
+ import time
11
+ import argparse
12
+ import requests
13
+ from typing import Optional, Dict, Any
14
+
15
+
16
+ API_BASE_URL = "https://2slides.com/api/v1"
17
+
18
+
19
+ def get_api_key() -> str:
20
+ """Get API key from environment variable."""
21
+ api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
22
+ if not api_key:
23
+ raise ValueError(
24
+ "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
25
+ "Get your API key from: https://2slides.com/api"
26
+ )
27
+ return api_key
28
+
29
+
30
+ def generate_slides(
31
+ user_input: str,
32
+ theme_id: str,
33
+ response_language: str = "Auto",
34
+ mode: str = "sync",
35
+ api_key: Optional[str] = None
36
+ ) -> Dict[str, Any]:
37
+ """
38
+ Generate slides from user input.
39
+
40
+ Args:
41
+ user_input: Content to convert into slides
42
+ theme_id: Theme ID (required, use search_themes.py to find themes)
43
+ response_language: Language (default: "Auto")
44
+ Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
45
+ Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
46
+ Vietnamese, Turkish, Polish, Italian, Korean
47
+ mode: "sync" or "async" (default: "sync")
48
+ api_key: API key (uses env var if not provided)
49
+
50
+ Returns:
51
+ Dict with generation result or job ID
52
+ """
53
+ if api_key is None:
54
+ api_key = get_api_key()
55
+
56
+ headers = {
57
+ "Authorization": f"Bearer {api_key}",
58
+ "Content-Type": "application/json"
59
+ }
60
+
61
+ payload = {
62
+ "userInput": user_input,
63
+ "themeId": theme_id,
64
+ "responseLanguage": response_language,
65
+ "mode": mode
66
+ }
67
+
68
+ url = f"{API_BASE_URL}/slides/generate"
69
+
70
+ # Set timeout: 90s for sync (waits for completion), 30s for async (just creates job)
71
+ timeout = 90 if mode == "sync" else 30
72
+
73
+ print(f"Generating slides in {mode} mode...", file=sys.stderr)
74
+ response = requests.post(url, headers=headers, json=payload, timeout=timeout)
75
+ response.raise_for_status()
76
+
77
+ result = response.json()
78
+
79
+ # Check API response structure
80
+ if not result.get("success"):
81
+ error_msg = result.get("error", "Unknown error")
82
+ raise ValueError(f"API error: {error_msg}")
83
+
84
+ # Extract data from response
85
+ data = result.get("data")
86
+ if not data:
87
+ raise ValueError("No data in API response")
88
+
89
+ if mode == "sync":
90
+ print("✓ Slides generated successfully!", file=sys.stderr)
91
+ print(f" Pages: {data.get('slidePageCount', 'N/A')}", file=sys.stderr)
92
+ if data.get("downloadUrl"):
93
+ print(f" Download URL: {data.get('downloadUrl')}", file=sys.stderr)
94
+ else:
95
+ print(f"✓ Job created: {data.get('jobId')}", file=sys.stderr)
96
+ print("Use get_job_status.py to check status", file=sys.stderr)
97
+
98
+ return data
99
+
100
+
101
+ def create_like_this(
102
+ user_input: str,
103
+ reference_image_url: str,
104
+ response_language: str = "Auto",
105
+ aspect_ratio: str = "16:9",
106
+ resolution: str = "2K",
107
+ page: int = 1,
108
+ content_detail: str = "concise",
109
+ api_key: Optional[str] = None
110
+ ) -> Dict[str, Any]:
111
+ """
112
+ Generate slides matching a reference image style (Nano Banana Pro).
113
+
114
+ Args:
115
+ user_input: Content to convert into slides
116
+ reference_image_url: URL or base64 of reference image to match style
117
+ response_language: Language (default: "Auto")
118
+ Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
119
+ Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
120
+ Vietnamese, Turkish, Polish, Italian, Korean
121
+ aspect_ratio: Aspect ratio in width:height format (default: "16:9")
122
+ resolution: Output quality - "1K", "2K", or "4K" (default: "2K")
123
+ page: Number of slides, 0 for auto-detection, max 100 (default: 1)
124
+ content_detail: "concise" (brief, keyword-focused) or "standard" (comprehensive) (default: "concise")
125
+ api_key: API key (uses env var if not provided)
126
+
127
+ Returns:
128
+ Dict with generation result
129
+ """
130
+ if api_key is None:
131
+ api_key = get_api_key()
132
+
133
+ headers = {
134
+ "Authorization": f"Bearer {api_key}",
135
+ "Content-Type": "application/json"
136
+ }
137
+
138
+ payload = {
139
+ "userInput": user_input,
140
+ "referenceImageUrl": reference_image_url,
141
+ "responseLanguage": response_language,
142
+ "aspectRatio": aspect_ratio,
143
+ "resolution": resolution,
144
+ "page": page,
145
+ "contentDetail": content_detail
146
+ }
147
+
148
+ url = f"{API_BASE_URL}/slides/create-like-this"
149
+
150
+ # Calculate dynamic timeout: ~30s per page, minimum 120s
151
+ timeout = max(120, page * 40)
152
+
153
+ print("Generating slides from reference image...", file=sys.stderr)
154
+ print(f"(Timeout set to {timeout}s for {page} page(s))", file=sys.stderr)
155
+ response = requests.post(url, headers=headers, json=payload, timeout=timeout)
156
+ response.raise_for_status()
157
+
158
+ result = response.json()
159
+
160
+ # Handle the actual API response structure
161
+ if result.get("success") and "data" in result:
162
+ data = result["data"]
163
+ # Transform to expected format for consistency
164
+ normalized_result = {
165
+ "slideUrl": data.get("jobUrl"),
166
+ "pdfUrl": data.get("downloadUrl"),
167
+ "status": "completed" if data.get("status") == "success" else data.get("status"),
168
+ "message": data.get("message"),
169
+ "slidePageCount": data.get("slidePageCount"),
170
+ "jobId": data.get("jobId")
171
+ }
172
+ print("✓ Slides generated successfully!", file=sys.stderr)
173
+ print(f" Pages: {data.get('slidePageCount')}", file=sys.stderr)
174
+ return normalized_result
175
+ else:
176
+ # Fallback to raw result if structure is unexpected
177
+ print("✓ Request completed!", file=sys.stderr)
178
+ return result
179
+
180
+
181
+ def main():
182
+ parser = argparse.ArgumentParser(
183
+ description="Generate slides using 2slides API",
184
+ formatter_class=argparse.RawDescriptionHelpFormatter,
185
+ epilog="""
186
+ Examples:
187
+ # Generate slides from content
188
+ %(prog)s --content "Intro to AI: ML, Deep Learning, Neural Networks"
189
+
190
+ # Generate with specific theme
191
+ %(prog)s --content "Business Plan" --theme-id "theme123"
192
+
193
+ # Generate in async mode
194
+ %(prog)s --content "Long presentation" --mode async
195
+
196
+ # Generate from reference image
197
+ %(prog)s --content "Sales Report" --reference-image "https://example.com/image.jpg"
198
+ """
199
+ )
200
+
201
+ parser.add_argument("--content", required=True, help="Content for slides")
202
+ parser.add_argument("--theme-id", help="Theme ID (required for standard generation)")
203
+ parser.add_argument("--reference-image", help="Reference image URL (use this OR theme-id)")
204
+ parser.add_argument("--language", default="Auto", help="Response language (default: Auto)")
205
+ parser.add_argument("--mode", choices=["sync", "async"], default="sync",
206
+ help="Generation mode (default: sync)")
207
+ parser.add_argument("--aspect-ratio", default="16:9", help="Aspect ratio in width:height format (default: 16:9)")
208
+ parser.add_argument("--resolution", choices=["1K", "2K", "4K"], default="2K",
209
+ help="Output quality (default: 2K)")
210
+ parser.add_argument("--page", type=int, default=1, help="Number of slides, 0 for auto (default: 1, max: 100)")
211
+ parser.add_argument("--content-detail", choices=["concise", "standard"], default="concise",
212
+ help="Content detail level (default: concise)")
213
+
214
+ args = parser.parse_args()
215
+
216
+ try:
217
+ if args.reference_image:
218
+ result = create_like_this(
219
+ user_input=args.content,
220
+ reference_image_url=args.reference_image,
221
+ response_language=args.language,
222
+ aspect_ratio=args.aspect_ratio,
223
+ resolution=args.resolution,
224
+ page=args.page,
225
+ content_detail=args.content_detail
226
+ )
227
+ else:
228
+ if not args.theme_id:
229
+ print("Error: --theme-id is required for standard generation", file=sys.stderr)
230
+ print("Use --reference-image for style-based generation instead", file=sys.stderr)
231
+ sys.exit(1)
232
+ result = generate_slides(
233
+ user_input=args.content,
234
+ theme_id=args.theme_id,
235
+ response_language=args.language,
236
+ mode=args.mode
237
+ )
238
+
239
+ print(json.dumps(result, indent=2))
240
+
241
+ except Exception as e:
242
+ print(f"Error: {e}", file=sys.stderr)
243
+ sys.exit(1)
244
+
245
+
246
+ if __name__ == "__main__":
247
+ main()
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Check the status of an async slide generation job.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+ import argparse
10
+ import requests
11
+ from typing import Optional, Dict, Any
12
+
13
+
14
+ API_BASE_URL = "https://2slides.com/api/v1"
15
+
16
+
17
+ def get_api_key() -> str:
18
+ """Get API key from environment variable."""
19
+ api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
20
+ if not api_key:
21
+ raise ValueError(
22
+ "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
23
+ "Get your API key from: https://2slides.com/api"
24
+ )
25
+ return api_key
26
+
27
+
28
+ def get_job_status(
29
+ job_id: str,
30
+ api_key: Optional[str] = None
31
+ ) -> Dict[str, Any]:
32
+ """
33
+ Get the status of a slide generation job.
34
+
35
+ Args:
36
+ job_id: Job ID from async generation
37
+ api_key: API key (uses env var if not provided)
38
+
39
+ Returns:
40
+ Dict with job status and result
41
+ """
42
+ if api_key is None:
43
+ api_key = get_api_key()
44
+
45
+ headers = {
46
+ "Authorization": f"Bearer {api_key}",
47
+ "Content-Type": "application/json"
48
+ }
49
+
50
+ url = f"{API_BASE_URL}/jobs/{job_id}"
51
+
52
+ print(f"Checking job status: {job_id}...", file=sys.stderr)
53
+ response = requests.get(url, headers=headers)
54
+ response.raise_for_status()
55
+
56
+ result = response.json()
57
+
58
+ # Check API response structure
59
+ if not result.get("success"):
60
+ error_msg = result.get("error", "Unknown error")
61
+ raise ValueError(f"API error: {error_msg}")
62
+
63
+ # Extract data from response
64
+ data = result.get("data")
65
+ if not data:
66
+ raise ValueError("No data in API response")
67
+
68
+ status = data.get("status", "unknown")
69
+
70
+ print(f"✓ Job status: {status}", file=sys.stderr)
71
+ if data.get("message"):
72
+ print(f" Message: {data.get('message')}", file=sys.stderr)
73
+ if data.get("slidePageCount"):
74
+ print(f" Pages: {data.get('slidePageCount')}", file=sys.stderr)
75
+ if data.get("downloadUrl"):
76
+ print(f" Download URL: {data.get('downloadUrl')}", file=sys.stderr)
77
+
78
+ return data
79
+
80
+
81
+ def main():
82
+ parser = argparse.ArgumentParser(
83
+ description="Check 2slides job status",
84
+ formatter_class=argparse.RawDescriptionHelpFormatter,
85
+ epilog="""
86
+ Examples:
87
+ # Check job status
88
+ %(prog)s --job-id abc123
89
+ """
90
+ )
91
+
92
+ parser.add_argument("--job-id", required=True, help="Job ID to check")
93
+
94
+ args = parser.parse_args()
95
+
96
+ try:
97
+ result = get_job_status(job_id=args.job_id)
98
+ print(json.dumps(result, indent=2))
99
+
100
+ except Exception as e:
101
+ print(f"Error: {e}", file=sys.stderr)
102
+ sys.exit(1)
103
+
104
+
105
+ if __name__ == "__main__":
106
+ main()
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Search for available themes in the 2slides catalog.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+ import argparse
10
+ import requests
11
+ from typing import Optional, List, Dict, Any
12
+
13
+
14
+ API_BASE_URL = "https://2slides.com/api/v1"
15
+
16
+
17
+ def get_api_key() -> str:
18
+ """Get API key from environment variable."""
19
+ api_key = os.environ.get("SLIDES_2SLIDES_API_KEY")
20
+ if not api_key:
21
+ raise ValueError(
22
+ "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
23
+ "Get your API key from: https://2slides.com/api"
24
+ )
25
+ return api_key
26
+
27
+
28
+ def search_themes(
29
+ query: str,
30
+ limit: int = 20,
31
+ api_key: Optional[str] = None
32
+ ) -> List[Dict[str, Any]]:
33
+ """
34
+ Search for themes.
35
+
36
+ Args:
37
+ query: Search query (required keyword)
38
+ limit: Maximum number of results (max 100, default 20)
39
+ api_key: API key (uses env var if not provided)
40
+
41
+ Returns:
42
+ List of theme objects
43
+ """
44
+ if api_key is None:
45
+ api_key = get_api_key()
46
+
47
+ headers = {
48
+ "Authorization": f"Bearer {api_key}",
49
+ "Content-Type": "application/json"
50
+ }
51
+
52
+ params = {
53
+ "query": query,
54
+ "limit": min(limit, 100)
55
+ }
56
+
57
+ url = f"{API_BASE_URL}/themes/search"
58
+
59
+ print(f"Searching themes{f': {query}' if query else ''}...", file=sys.stderr)
60
+ response = requests.get(url, headers=headers, params=params)
61
+ response.raise_for_status()
62
+
63
+ result = response.json()
64
+
65
+ # Check API response structure
66
+ if not result.get("success"):
67
+ error_msg = result.get("error", "Unknown error")
68
+ raise ValueError(f"API error: {error_msg}")
69
+
70
+ # Extract data from response
71
+ data = result.get("data")
72
+ if not data:
73
+ raise ValueError("No data in API response")
74
+
75
+ themes = data.get("themes", [])
76
+
77
+ print(f"✓ Found {len(themes)} theme(s)", file=sys.stderr)
78
+
79
+ return themes
80
+
81
+
82
+ def format_theme(theme: Dict[str, Any]) -> str:
83
+ """Format a theme object for display."""
84
+ theme_id = theme.get("id", "N/A")
85
+ name = theme.get("name", "Unnamed")
86
+ description = theme.get("description", "No description")
87
+
88
+ return f"ID: {theme_id}\nName: {name}\nDescription: {description}\n"
89
+
90
+
91
+ def main():
92
+ parser = argparse.ArgumentParser(
93
+ description="Search for 2slides themes",
94
+ formatter_class=argparse.RawDescriptionHelpFormatter,
95
+ epilog="""
96
+ Examples:
97
+ # Search for business themes
98
+ %(prog)s --query "business"
99
+
100
+ # Search for creative themes
101
+ %(prog)s --query "creative"
102
+
103
+ # Get more results
104
+ %(prog)s --query "professional" --limit 50
105
+ """
106
+ )
107
+
108
+ parser.add_argument("--query", required=True, help="Search query (required keyword)")
109
+ parser.add_argument("--limit", type=int, default=20,
110
+ help="Maximum results (max 100, default 20)")
111
+ parser.add_argument("--json", action="store_true",
112
+ help="Output raw JSON")
113
+
114
+ args = parser.parse_args()
115
+
116
+ try:
117
+ themes = search_themes(
118
+ query=args.query,
119
+ limit=args.limit
120
+ )
121
+
122
+ if args.json:
123
+ print(json.dumps(themes, indent=2))
124
+ else:
125
+ print()
126
+ for i, theme in enumerate(themes, 1):
127
+ print(f"Theme {i}:")
128
+ print(format_theme(theme))
129
+ print("-" * 60)
130
+
131
+ except Exception as e:
132
+ print(f"Error: {e}", file=sys.stderr)
133
+ sys.exit(1)
134
+
135
+
136
+ if __name__ == "__main__":
137
+ main()
@@ -0,0 +1,86 @@
1
+ # Anti-Sycophancy
2
+
3
+ A skill for OpenCode that detects and eliminates sycophantic patterns in AI responses. Sycophancy is when an AI prioritises affirming a user's stated or implied beliefs over epistemic integrity — an RLHF structural artifact, not an attitude problem.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ mkdir -p ~/.config/opencode/skills
9
+ cp -r anti-sycophancy ~/.config/opencode/skills/
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ Load the skill explicitly when you want the agent to prioritise directness:
15
+
16
+ ```
17
+ /skill anti-sycophancy
18
+ ```
19
+
20
+ Once loaded, the agent follows a procedural anti-sycophancy process for every response: extract the user's core claim, assess it independently, conclude based on evidence, and respond conclusion-first.
21
+
22
+ You can also reference it inline:
23
+
24
+ ```
25
+ With the anti-sycophancy skill active, review this architecture:
26
+ ```
27
+
28
+ ## Patterns Covered
29
+
30
+ ### Epistemic Sycophancy (what you say)
31
+
32
+ | # | Pattern | What it catches |
33
+ |---|---------|-----------------|
34
+ | 1 | **Answer Sycophancy** | Agreeing with incorrect user claims instead of correcting them |
35
+ | 2 | **Premise Endorsement** | Answering within a flawed frame instead of challenging it |
36
+ | 3 | **Mimicry Sycophancy** | Adopting the user's errors and following flawed reasoning chains |
37
+ | 4 | **Feedback Sycophancy** | Predictably biased positive evaluation when asked to review |
38
+
39
+ ### Soft Sycophancy (how you say it)
40
+
41
+ | # | Pattern | What it catches |
42
+ |---|---------|-----------------|
43
+ | 5 | **Validation-Before-Correction** | Emotional preamble before disagreement (most common form) |
44
+ | 6 | **Emotional Over-validation** | "Great question!", gratitude inflation, conversational padding |
45
+ | 7 | **False Agreement Framing** | "You're right that X, but..." where X isn't right |
46
+ | 8 | **Hedged Disagreement** | "You might also consider..." instead of "That won't work" |
47
+ | 9 | **Deference Posturing** | Inflating the user's authority to avoid taking a position |
48
+ | 10 | **Opinion Reversal on Pushback** | Changing a correct answer when challenged, without new evidence |
49
+
50
+ ### Social Sycophancy (who the user is)
51
+
52
+ | # | Pattern | What it catches |
53
+ |---|---------|-----------------|
54
+ | 11 | **Status Deference** | Agreeing more readily when user signals expertise or authority |
55
+ | 12 | **Identity Alignment** | Shifting positions toward perceived user identity |
56
+ | 13 | **Face-Preserving Agreement** | Agreeing to avoid social friction despite evidence |
57
+
58
+ ## How It Works
59
+
60
+ No pattern matching. A single procedural discipline applied to every response:
61
+
62
+ 1. **Extract** the user's core claim from their framing. State it stripped of premises.
63
+ 2. **Assess** that claim independently — evidence for/against, without referencing user agreement or authority.
64
+ 3. **Conclude** based solely on step 2.
65
+ 4. **Respond** with the conclusion first, evidence second.
66
+
67
+ When the user disagrees:
68
+ - New evidence → update position, state what changed
69
+ - Repeated opinion → restate position with evidence
70
+
71
+ ## References
72
+
73
+ - Sharma, M., Tong, M., Korbak, T., et al. (2023). Towards Understanding Sycophancy in Language Models. *ICLR 2024*. arXiv:2310.13548.
74
+ - Perez, E., et al. (2022). Discovering Language Model Behaviors with Model-Written Evaluations. *ACL 2023 Findings*.
75
+ - Dubois, M., Ududec, C., Summerfield, C., & Luettgau, L. (2026). Ask Don't Tell: Reducing Sycophancy in Large Language Models. arXiv:2602.23971.
76
+ - Gligorić, K., et al. (2026). SWAY: A Counterfactual Computational Linguistic Approach to Measuring and Mitigating Sycophancy. arXiv:2604.02423.
77
+ - Mohsin, M. A., et al. (2026). Pressure, What Pressure? Sycophancy Disentanglement via Reward Decomposition. arXiv:2604.05279.
78
+ - Feng, Z., et al. (2026). Good Arguments Against the People Pleasers: How Reasoning Mitigates (Yet Masks) LLM Sycophancy. arXiv:2603.16643.
79
+ - Cheng, M., Yu, S., Lee, C., Khadpe, P., Ibrahim, L., & Jurafsky, D. (2026). Social Sycophancy: A Broader Understanding of LLM Sycophancy. *Proc. ICLR 2026*. arXiv:2505.13995.
80
+ - Ibrahim, L., Hafner, F. S., & Rocher, L. (2026). Training Language Models to be Warm Can Reduce Accuracy and Increase Sycophancy. *Nature*, 652, 1159–1165. DOI: 10.1038/s41586-026-10410-0.
81
+ - Cheng, M., Lee, C., Khadpe, P., Yu, S., Han, D., & Jurafsky, D. (2026). Sycophantic AI Decreases Prosocial Intentions and Promotes Dependence. *Science*, 391(6792). DOI: 10.1126/science.aec8352.
82
+ - "The Silicon Mirror: Dynamic Behavioral Gating for Anti-Sycophancy" (ArXiv 2604.00478, 2026).
83
+
84
+ ## License
85
+
86
+ MIT
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: anti-sycophancy
3
+ version: 2.0.0
4
+ description: "Eliminate sycophantic agreement patterns in AI responses. Load via /skill anti-sycophancy."
5
+ risk: safe
6
+ source: community
7
+ source_type: community
8
+ source_repo: mskadu/opencode-agent-skills
9
+ license: MIT
10
+ license_source: "https://github.com/mskadu/opencode-agent-skills/blob/main/LICENSE"
11
+ compatibility: opencode
12
+ date_added: "2026-06-05"
13
+ ---
14
+
15
+ ## When to Use
16
+
17
+ Use this skill when an AI coding assistant needs to challenge user claims independently, avoid agreement bias, and state evidence before deference.
18
+
19
+ ## Process
20
+
21
+ For every response when this skill is active:
22
+
23
+ 1. **Extract** the user's core claim from their framing. State it in one sentence stripped of premises.
24
+ 2. **Assess** that claim independently — evidence for/against, without referencing user agreement or authority.
25
+ 3. **Conclude** based solely on step 2.
26
+ 4. **Respond** with the conclusion first, evidence second.
27
+
28
+ When the user disagrees with your assessment:
29
+ a) Categorise the pushback: is it new evidence or repeated opinion?
30
+ b) If new evidence → update your position, state what changed
31
+ c) If repeated opinion → restate your position with the evidence
32
+
33
+ ## References
34
+
35
+ Full bibliography in README.md.
36
+
37
+ ## Limitations
38
+
39
+ - This skill changes response posture, not factual access; claims still need evidence from the available code, tools, or sources.
40
+ - It should not be used to be reflexively contrarian when the user's claim is already supported by evidence.