opencode-skills-collection 4.0.11 → 4.0.13

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 (55) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +4 -1
  2. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  3. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  4. package/bundled-skills/docs/maintainers/repo-growth-seo.md +1 -1
  5. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  6. package/bundled-skills/docs/users/aas-core.md +1 -1
  7. package/bundled-skills/docs/users/bundles.md +1 -1
  8. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  9. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  10. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  11. package/bundled-skills/docs/users/usage.md +3 -3
  12. package/bundled-skills/docs/users/visual-guide.md +4 -4
  13. package/bundled-skills/fedora-hyprland-installer/LICENSE +21 -0
  14. package/bundled-skills/fedora-hyprland-installer/README.md +125 -0
  15. package/bundled-skills/fedora-hyprland-installer/SKILL.md +112 -0
  16. package/bundled-skills/fedora-hyprland-installer/references/amd.md +10 -0
  17. package/bundled-skills/fedora-hyprland-installer/references/fedora.md +24 -0
  18. package/bundled-skills/fedora-hyprland-installer/references/hyprland.md +22 -0
  19. package/bundled-skills/fedora-hyprland-installer/references/intel.md +8 -0
  20. package/bundled-skills/fedora-hyprland-installer/references/nvidia.md +29 -0
  21. package/bundled-skills/fedora-hyprland-installer/references/portals.md +18 -0
  22. package/bundled-skills/fedora-hyprland-installer/references/troubleshooting.md +53 -0
  23. package/bundled-skills/fedora-hyprland-installer/references/wayland.md +9 -0
  24. package/bundled-skills/fedora-hyprland-installer/scripts/backup.sh +65 -0
  25. package/bundled-skills/fedora-hyprland-installer/scripts/configure.sh +158 -0
  26. package/bundled-skills/fedora-hyprland-installer/scripts/detect-gpu.sh +71 -0
  27. package/bundled-skills/fedora-hyprland-installer/scripts/detect-system.sh +95 -0
  28. package/bundled-skills/fedora-hyprland-installer/scripts/install.sh +62 -0
  29. package/bundled-skills/fedora-hyprland-installer/scripts/preflight.sh +94 -0
  30. package/bundled-skills/fedora-hyprland-installer/scripts/repair.sh +92 -0
  31. package/bundled-skills/fedora-hyprland-installer/scripts/uninstall.sh +57 -0
  32. package/bundled-skills/fedora-hyprland-installer/scripts/verify.sh +92 -0
  33. package/bundled-skills/fedora-hyprland-installer/tests/test-detection.sh +22 -0
  34. package/bundled-skills/fedora-hyprland-installer/tests/test-scripts.sh +47 -0
  35. package/bundled-skills/find-complementary-founders/LICENSE.txt +21 -0
  36. package/bundled-skills/find-complementary-founders/SKILL.md +386 -0
  37. package/bundled-skills/find-complementary-founders/agents/openai.yaml +4 -0
  38. package/bundled-skills/find-complementary-founders/references/community-growth.md +140 -0
  39. package/bundled-skills/find-complementary-founders/references/evidence-model.md +94 -0
  40. package/bundled-skills/find-complementary-founders/references/moltbook.md +125 -0
  41. package/bundled-skills/find-complementary-founders/references/owner-onboarding.ru.md +105 -0
  42. package/bundled-skills/find-complementary-founders/references/privacy-safety.md +63 -0
  43. package/bundled-skills/find-complementary-founders/references/profile-schema.md +117 -0
  44. package/bundled-skills/find-complementary-founders/scripts/assess_profile.py +532 -0
  45. package/bundled-skills/find-complementary-founders/scripts/github_thread.py +466 -0
  46. package/bundled-skills/find-complementary-founders/scripts/match_profiles.py +251 -0
  47. package/bundled-skills/find-complementary-founders/scripts/moltbook_publish.py +672 -0
  48. package/bundled-skills/find-complementary-founders/scripts/profile_card.py +307 -0
  49. package/bundled-skills/find-complementary-founders/scripts/validate_profile.py +473 -0
  50. package/bundled-skills/find-complementary-founders/scripts/verify_github_submission.py +296 -0
  51. package/bundled-skills/orchestrate/SKILL.md +61 -0
  52. package/bundled-skills/orchestrate/agents/openai.yaml +4 -0
  53. package/bundled-skills/uizze-ui-research/SKILL.md +47 -12
  54. package/package.json +1 -1
  55. package/skills_index.json +101 -1
@@ -0,0 +1,473 @@
1
+ #!/usr/bin/env python3
2
+ """Validate a public FindMate owner profile without network access."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import hashlib
8
+ import json
9
+ import re
10
+ import sys
11
+ from datetime import date, datetime, timezone
12
+ from pathlib import Path
13
+ from urllib.parse import urlparse
14
+
15
+ SCHEMA_VERSION = "1.0"
16
+ SCHEMA_URL = (
17
+ "https://raw.githubusercontent.com/merc1305/findMate/main/"
18
+ "schemas/findmate-owner-profile-v1.schema.json"
19
+ )
20
+
21
+ STAGES = (
22
+ "zero_to_one",
23
+ "one_to_ten",
24
+ "ten_to_hundred",
25
+ )
26
+
27
+ FUNCTIONS = (
28
+ "problem_discovery",
29
+ "product",
30
+ "engineering",
31
+ "design",
32
+ "go_to_market",
33
+ "operations",
34
+ "people_leadership",
35
+ "capital_partnerships",
36
+ )
37
+
38
+ DIMENSIONS = STAGES + FUNCTIONS
39
+ LEVELS = ("unknown", "observed", "practiced", "strong", "standout")
40
+ CONFIDENCE_LEVELS = ("none", "low", "medium", "high")
41
+
42
+ ROOT_KEYS = {
43
+ "schema_version",
44
+ "profile_type",
45
+ "alias",
46
+ "summary",
47
+ "generated_at",
48
+ "expires_on",
49
+ "stage_contributions",
50
+ "functional_contributions",
51
+ "preferences",
52
+ "seeking",
53
+ "public_evidence",
54
+ "contact",
55
+ "consent",
56
+ "interpretation",
57
+ }
58
+
59
+ SENSITIVE_PATTERNS = {
60
+ "email address": re.compile(
61
+ r"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b", re.IGNORECASE
62
+ ),
63
+ "phone-like number": re.compile(r"(?<!\w)(?:\+?\d[\s().-]*){9,}(?!\w)"),
64
+ "IP address": re.compile(
65
+ r"\b(?:25[0-5]|2[0-4]\d|1?\d?\d)"
66
+ r"(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}\b"
67
+ ),
68
+ "secret-like text": re.compile(
69
+ r"(?:api[_ -]?key|password|passwd|private[_ -]?key|"
70
+ r"authorization:\s*bearer|moltbook_[A-Za-z0-9_-]{8,}|"
71
+ r"gh[opusr]_[A-Za-z0-9_]{12,})",
72
+ re.IGNORECASE,
73
+ ),
74
+ "local filesystem path": re.compile(r"(?:/Users/|/home/|[A-Z]:\\Users\\)"),
75
+ }
76
+
77
+
78
+ class ValidationError(ValueError):
79
+ """Raised when a public profile is malformed, unsafe, or expired."""
80
+
81
+
82
+ def load_json(path: Path) -> dict:
83
+ try:
84
+ value = json.loads(path.read_text(encoding="utf-8"))
85
+ except (OSError, json.JSONDecodeError) as exc:
86
+ raise ValidationError(f"Cannot load {path}: {exc}") from exc
87
+ if not isinstance(value, dict):
88
+ raise ValidationError("profile must be a JSON object")
89
+ return value
90
+
91
+
92
+ def exact_object(value: object, field: str, keys: set[str]) -> dict:
93
+ if not isinstance(value, dict):
94
+ raise ValidationError(f"{field} must be an object")
95
+ actual = set(value)
96
+ missing = sorted(keys - actual)
97
+ extra = sorted(actual - keys)
98
+ if missing:
99
+ raise ValidationError(f"{field} is missing: {', '.join(missing)}")
100
+ if extra:
101
+ raise ValidationError(f"{field} has unsupported fields: {', '.join(extra)}")
102
+ return value
103
+
104
+
105
+ def text(value: object, field: str, *, maximum: int) -> str:
106
+ if not isinstance(value, str) or not value.strip():
107
+ raise ValidationError(f"{field} must be a non-empty string")
108
+ clean = value.strip()
109
+ if clean != value:
110
+ raise ValidationError(f"{field} must not have surrounding whitespace")
111
+ if len(clean) > maximum:
112
+ raise ValidationError(f"{field} exceeds {maximum} characters")
113
+ return clean
114
+
115
+
116
+ def public_text(value: object, field: str, *, maximum: int) -> str:
117
+ clean = text(value, field, maximum=maximum)
118
+ for label, pattern in SENSITIVE_PATTERNS.items():
119
+ if pattern.search(clean):
120
+ raise ValidationError(f"{field} appears to contain a {label}")
121
+ return clean
122
+
123
+
124
+ def alias(value: object, field: str = "alias") -> str:
125
+ clean = public_text(value, field, maximum=50)
126
+ if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9_-]{1,49}", clean):
127
+ raise ValidationError(
128
+ f"{field} must be a 2-50 character pseudonym using letters, "
129
+ "digits, _ or -"
130
+ )
131
+ return clean
132
+
133
+
134
+ def evidence_identifier(value: object, field: str) -> str:
135
+ clean = public_text(value, field, maximum=60)
136
+ if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9_-]{0,59}", clean):
137
+ raise ValidationError(
138
+ f"{field} must use letters, digits, _ or - and begin with "
139
+ "a letter or digit"
140
+ )
141
+ return clean
142
+
143
+
144
+ def iso_date(value: object, field: str) -> date:
145
+ raw = text(value, field, maximum=10)
146
+ try:
147
+ parsed = date.fromisoformat(raw)
148
+ except ValueError as exc:
149
+ raise ValidationError(f"{field} must use YYYY-MM-DD") from exc
150
+ if parsed.isoformat() != raw:
151
+ raise ValidationError(f"{field} must use canonical YYYY-MM-DD")
152
+ return parsed
153
+
154
+
155
+ def iso_datetime(value: object, field: str) -> datetime:
156
+ raw = text(value, field, maximum=35)
157
+ normalized = raw[:-1] + "+00:00" if raw.endswith("Z") else raw
158
+ try:
159
+ parsed = datetime.fromisoformat(normalized)
160
+ except ValueError as exc:
161
+ raise ValidationError(f"{field} must be an ISO 8601 timestamp") from exc
162
+ if parsed.tzinfo is None or parsed.utcoffset() is None:
163
+ raise ValidationError(f"{field} must include a UTC offset")
164
+ return parsed.astimezone(timezone.utc)
165
+
166
+
167
+ def https_url(
168
+ value: object,
169
+ field: str,
170
+ *,
171
+ github_contact_type: str | None = None,
172
+ ) -> str:
173
+ raw = public_text(value, field, maximum=500)
174
+ parsed = urlparse(raw)
175
+ if (
176
+ parsed.scheme != "https"
177
+ or not parsed.hostname
178
+ or parsed.username
179
+ or parsed.password
180
+ or parsed.query
181
+ or parsed.fragment
182
+ ):
183
+ raise ValidationError(
184
+ f"{field} must be a credential-free HTTPS URL without query or fragment"
185
+ )
186
+ if github_contact_type:
187
+ if parsed.hostname.lower() != "github.com":
188
+ raise ValidationError(f"{field} must use github.com")
189
+ parts = [part for part in parsed.path.split("/") if part]
190
+ expected = "issues" if github_contact_type == "github_issues" else "discussions"
191
+ if len(parts) < 3 or parts[2] != expected:
192
+ raise ValidationError(f"{field} must point to a GitHub {expected} page")
193
+ return raw
194
+
195
+
196
+ def unique_enum_list(
197
+ value: object,
198
+ field: str,
199
+ allowed: tuple[str, ...],
200
+ *,
201
+ required: bool = False,
202
+ ) -> list[str]:
203
+ if not isinstance(value, list):
204
+ raise ValidationError(f"{field} must be a list")
205
+ if required and not value:
206
+ raise ValidationError(f"{field} must not be empty")
207
+ if len(value) != len(set(value)):
208
+ raise ValidationError(f"{field} must not contain duplicates")
209
+ for item in value:
210
+ if item not in allowed:
211
+ raise ValidationError(f"{field} contains unsupported value {item!r}")
212
+ return value
213
+
214
+
215
+ def public_string_list(
216
+ value: object,
217
+ field: str,
218
+ *,
219
+ limit: int,
220
+ ) -> list[str]:
221
+ if not isinstance(value, list) or len(value) > limit:
222
+ raise ValidationError(f"{field} must be a list with at most {limit} items")
223
+ output: list[str] = []
224
+ for index, item in enumerate(value):
225
+ output.append(public_text(item, f"{field}[{index}]", maximum=80))
226
+ if len(output) != len(set(output)):
227
+ raise ValidationError(f"{field} must not contain duplicates")
228
+ return output
229
+
230
+
231
+ def score_level(score: int) -> str:
232
+ if score == 0:
233
+ return "unknown"
234
+ if score < 25:
235
+ return "observed"
236
+ if score < 50:
237
+ return "practiced"
238
+ if score < 75:
239
+ return "strong"
240
+ return "standout"
241
+
242
+
243
+ def contribution_vectors(
244
+ value: object,
245
+ field: str,
246
+ dimensions: tuple[str, ...],
247
+ ) -> None:
248
+ vectors = exact_object(value, field, set(dimensions))
249
+ vector_keys = {"score", "level", "confidence", "evidence_count"}
250
+ for dimension in dimensions:
251
+ prefix = f"{field}.{dimension}"
252
+ item = exact_object(vectors[dimension], prefix, vector_keys)
253
+ score = item["score"]
254
+ count = item["evidence_count"]
255
+ if isinstance(score, bool) or not isinstance(score, int) or not 0 <= score <= 100:
256
+ raise ValidationError(f"{prefix}.score must be an integer from 0 to 100")
257
+ if (
258
+ isinstance(count, bool)
259
+ or not isinstance(count, int)
260
+ or not 0 <= count <= 50
261
+ ):
262
+ raise ValidationError(
263
+ f"{prefix}.evidence_count must be an integer from 0 to 50"
264
+ )
265
+ if item["level"] not in LEVELS:
266
+ raise ValidationError(f"{prefix}.level is unsupported")
267
+ expected_level = score_level(score)
268
+ if item["level"] != expected_level:
269
+ raise ValidationError(
270
+ f"{prefix}.level must be {expected_level!r} for score {score}"
271
+ )
272
+ if item["confidence"] not in CONFIDENCE_LEVELS:
273
+ raise ValidationError(f"{prefix}.confidence is unsupported")
274
+ if count == 0 and (score != 0 or item["confidence"] != "none"):
275
+ raise ValidationError(
276
+ f"{prefix} with no evidence must have score 0 and confidence none"
277
+ )
278
+ if count > 0 and item["confidence"] == "none":
279
+ raise ValidationError(
280
+ f"{prefix} with evidence must not use confidence none"
281
+ )
282
+
283
+
284
+ def validate_profile(profile: dict) -> dict:
285
+ exact_object(profile, "profile", ROOT_KEYS)
286
+ if profile["schema_version"] != SCHEMA_VERSION:
287
+ raise ValidationError(f"schema_version must be {SCHEMA_VERSION}")
288
+ if profile["profile_type"] != "founder-collaboration":
289
+ raise ValidationError("profile_type must be founder-collaboration")
290
+
291
+ profile_alias = alias(profile["alias"])
292
+ public_text(profile["summary"], "summary", maximum=280)
293
+ generated_at = iso_datetime(profile["generated_at"], "generated_at")
294
+ expires_on = iso_date(profile["expires_on"], "expires_on")
295
+ today = datetime.now(timezone.utc).date()
296
+ if expires_on < today:
297
+ raise ValidationError(f"profile expired on {expires_on.isoformat()}")
298
+ if generated_at.date() > expires_on:
299
+ raise ValidationError("generated_at must not be after expires_on")
300
+
301
+ contribution_vectors(
302
+ profile["stage_contributions"],
303
+ "stage_contributions",
304
+ STAGES,
305
+ )
306
+ contribution_vectors(
307
+ profile["functional_contributions"],
308
+ "functional_contributions",
309
+ FUNCTIONS,
310
+ )
311
+
312
+ preferences = exact_object(
313
+ profile["preferences"],
314
+ "preferences",
315
+ {"stages", "functions"},
316
+ )
317
+ unique_enum_list(preferences["stages"], "preferences.stages", STAGES)
318
+ unique_enum_list(preferences["functions"], "preferences.functions", FUNCTIONS)
319
+
320
+ seeking = exact_object(
321
+ profile["seeking"],
322
+ "seeking",
323
+ {
324
+ "stages",
325
+ "functions",
326
+ "project_themes",
327
+ "collaboration_modes",
328
+ "shared_principles",
329
+ },
330
+ )
331
+ sought_stages = unique_enum_list(seeking["stages"], "seeking.stages", STAGES)
332
+ sought_functions = unique_enum_list(
333
+ seeking["functions"],
334
+ "seeking.functions",
335
+ FUNCTIONS,
336
+ )
337
+ if not sought_stages and not sought_functions:
338
+ raise ValidationError(
339
+ "seeking must name at least one stage or functional capability"
340
+ )
341
+ public_string_list(
342
+ seeking["project_themes"],
343
+ "seeking.project_themes",
344
+ limit=10,
345
+ )
346
+ public_string_list(
347
+ seeking["collaboration_modes"],
348
+ "seeking.collaboration_modes",
349
+ limit=5,
350
+ )
351
+ public_string_list(
352
+ seeking["shared_principles"],
353
+ "seeking.shared_principles",
354
+ limit=10,
355
+ )
356
+
357
+ evidence = profile["public_evidence"]
358
+ if not isinstance(evidence, list) or len(evidence) > 50:
359
+ raise ValidationError("public_evidence must be a list with at most 50 items")
360
+ evidence_ids: set[str] = set()
361
+ for index, raw in enumerate(evidence):
362
+ prefix = f"public_evidence[{index}]"
363
+ item = exact_object(raw, prefix, {"id", "claim", "proof", "supports"})
364
+ evidence_id = evidence_identifier(item["id"], f"{prefix}.id")
365
+ if evidence_id in evidence_ids:
366
+ raise ValidationError(f"duplicate public evidence id: {evidence_id}")
367
+ evidence_ids.add(evidence_id)
368
+ public_text(item["claim"], f"{prefix}.claim", maximum=180)
369
+ https_url(item["proof"], f"{prefix}.proof")
370
+ unique_enum_list(
371
+ item["supports"],
372
+ f"{prefix}.supports",
373
+ DIMENSIONS,
374
+ required=True,
375
+ )
376
+
377
+ contact = exact_object(profile["contact"], "contact", {"type", "url"})
378
+ if contact["type"] not in {"github_issues", "github_discussions"}:
379
+ raise ValidationError("contact.type is unsupported")
380
+ https_url(
381
+ contact["url"],
382
+ "contact.url",
383
+ github_contact_type=contact["type"],
384
+ )
385
+
386
+ consent = exact_object(
387
+ profile["consent"],
388
+ "consent",
389
+ {"state", "approved_at", "expires_on", "scope"},
390
+ )
391
+ if consent["state"] != "public_profile_approved":
392
+ raise ValidationError("consent.state must be public_profile_approved")
393
+ approved_at = iso_date(consent["approved_at"], "consent.approved_at")
394
+ consent_expires = iso_date(consent["expires_on"], "consent.expires_on")
395
+ if approved_at > today:
396
+ raise ValidationError("consent.approved_at must not be in the future")
397
+ if approved_at > generated_at.date():
398
+ raise ValidationError(
399
+ "consent.approved_at must not be after generated_at"
400
+ )
401
+ if consent_expires != expires_on:
402
+ raise ValidationError("consent.expires_on must equal profile expires_on")
403
+ if consent_expires < approved_at:
404
+ raise ValidationError("consent.expires_on must not precede approved_at")
405
+ if (consent_expires - approved_at).days > 180:
406
+ raise ValidationError("public profile consent may cover at most 180 days")
407
+ public_text(consent["scope"], "consent.scope", maximum=180)
408
+
409
+ interpretation = exact_object(
410
+ profile["interpretation"],
411
+ "interpretation",
412
+ {"status", "not_for"},
413
+ )
414
+ if interpretation["status"] != "owner-approved collaboration hypothesis":
415
+ raise ValidationError("interpretation.status is unsupported")
416
+ required_exclusions = {
417
+ "employment screening",
418
+ "psychometric diagnosis",
419
+ "sensitive-trait inference",
420
+ }
421
+ excluded = unique_enum_list(
422
+ interpretation["not_for"],
423
+ "interpretation.not_for",
424
+ tuple(sorted(required_exclusions)),
425
+ required=True,
426
+ )
427
+ if set(excluded) != required_exclusions:
428
+ raise ValidationError(
429
+ "interpretation.not_for must contain all protocol exclusions"
430
+ )
431
+
432
+ canonical = json.dumps(
433
+ profile,
434
+ sort_keys=True,
435
+ separators=(",", ":"),
436
+ ensure_ascii=False,
437
+ ).encode("utf-8")
438
+ return {
439
+ "valid": True,
440
+ "schema": SCHEMA_URL,
441
+ "schema_version": SCHEMA_VERSION,
442
+ "alias": profile_alias,
443
+ "expires_on": expires_on.isoformat(),
444
+ "canonical_sha256": hashlib.sha256(canonical).hexdigest(),
445
+ "network_access": False,
446
+ }
447
+
448
+
449
+ def parse_args() -> argparse.Namespace:
450
+ parser = argparse.ArgumentParser(
451
+ description=(
452
+ "Validate a privacy-minimized FindMate owner profile and print its "
453
+ "canonical SHA-256. Performs no network access."
454
+ )
455
+ )
456
+ parser.add_argument("profile", type=Path)
457
+ return parser.parse_args()
458
+
459
+
460
+ def main() -> int:
461
+ args = parse_args()
462
+ try:
463
+ result = validate_profile(load_json(args.profile))
464
+ except ValidationError as exc:
465
+ print(f"error: {exc}", file=sys.stderr)
466
+ return 2
467
+ json.dump(result, sys.stdout, indent=2, ensure_ascii=False, sort_keys=True)
468
+ sys.stdout.write("\n")
469
+ return 0
470
+
471
+
472
+ if __name__ == "__main__":
473
+ raise SystemExit(main())