opencode-skills-collection 3.0.34 → 3.0.35

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 (45) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +2 -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 +3 -3
  5. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  6. package/bundled-skills/docs/users/bundles.md +1 -1
  7. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  8. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  9. package/bundled-skills/docs/users/getting-started.md +3 -3
  10. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  11. package/bundled-skills/docs/users/usage.md +4 -4
  12. package/bundled-skills/docs/users/visual-guide.md +4 -4
  13. package/bundled-skills/mmx-cli/SKILL.md +5 -2
  14. package/bundled-skills/nextjs-seo-indexing/SKILL.md +3 -3
  15. package/bundled-skills/schema-markup-generator/SKILL.md +1 -1
  16. package/bundled-skills/social-metadata-hardening/SKILL.md +4 -3
  17. package/bundled-skills/social-post-writer-seo/SKILL.md +19 -0
  18. package/bundled-skills/user-thoughts/SKILL.md +236 -0
  19. package/bundled-skills/user-thoughts/assets/Runtime-Template/README.ai.md +13 -0
  20. package/bundled-skills/user-thoughts/assets/Runtime-Template/define.ini +3 -0
  21. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/README.ai.md +25 -0
  22. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/backlog.md +19 -0
  23. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/dev-stack.md +7 -0
  24. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/general.md +7 -0
  25. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/plans.md +7 -0
  26. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/rules.md +7 -0
  27. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/ui/details.md +7 -0
  28. package/bundled-skills/user-thoughts/assets/Runtime-Template/mdbase/details/ui/outline.md +7 -0
  29. package/bundled-skills/user-thoughts/references/commands.md +54 -0
  30. package/bundled-skills/user-thoughts/references/edge-cases.md +84 -0
  31. package/bundled-skills/user-thoughts/references/safety.md +65 -0
  32. package/bundled-skills/user-thoughts/references/sortin.md +76 -0
  33. package/bundled-skills/user-thoughts/scripts/common.py +62 -0
  34. package/bundled-skills/user-thoughts/scripts/ignore_ops.py +125 -0
  35. package/bundled-skills/user-thoughts/scripts/init.py +63 -0
  36. package/bundled-skills/user-thoughts/scripts/show_mdbase.py +93 -0
  37. package/bundled-skills/user-thoughts/scripts/show_raw.py +42 -0
  38. package/bundled-skills/user-thoughts/scripts/sortin.py +211 -0
  39. package/bundled-skills/user-thoughts/scripts/status.py +56 -0
  40. package/bundled-skills/user-thoughts/scripts/toggle.py +68 -0
  41. package/bundled-skills/user-thoughts/scripts/write_raw.py +106 -0
  42. package/bundled-skills/vibe-code-cleanup/SKILL.md +4 -4
  43. package/bundled-skills/vibecode-production-qa-validator/SKILL.md +3 -2
  44. package/package.json +1 -1
  45. package/skills_index.json +26 -4
@@ -0,0 +1,42 @@
1
+ """Show unprocessed raw files."""
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ from common import find_ustht, is_processed
6
+
7
+ HELP = """Usage: python show_raw.py [--help]
8
+
9
+ Show unprocessed #raw/ files, including filenames, entry counts, and content.
10
+ """
11
+
12
+
13
+ def main():
14
+ if "--help" in sys.argv or "-h" in sys.argv:
15
+ print(HELP)
16
+ sys.exit(0)
17
+
18
+ ustht = find_ustht()
19
+ if ustht is None:
20
+ print("Error: .ustht/ was not found. Run /ustht init first.")
21
+ sys.exit(1)
22
+
23
+ raw_dir = ustht / "raw"
24
+ if not raw_dir.exists():
25
+ print("No unprocessed records.")
26
+ return
27
+
28
+ files = [f for f in sorted(raw_dir.glob("*.md"), reverse=True) if not is_processed(f)]
29
+ if not files:
30
+ print("No unprocessed records. All raw files are marked processed.")
31
+ return
32
+
33
+ for f in files:
34
+ content = f.read_text(encoding="utf-8").strip()
35
+ entry_count = sum(1 for line in content.splitlines() if line.strip().startswith("- ["))
36
+ print(f"#{f.name} ({entry_count} unprocessed entries):")
37
+ print(content)
38
+ print()
39
+
40
+
41
+ if __name__ == "__main__":
42
+ main()
@@ -0,0 +1,211 @@
1
+ """Soft-maintain raw user-thought entries into mdbase."""
2
+ import re
3
+ import sys
4
+ from collections import defaultdict
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+
8
+ from common import find_ustht, read_define_ini, write_define_ini, is_processed, validate_dim_name
9
+
10
+ HELP = """Usage: python sortin.py [--dry] [--help]
11
+
12
+ Soft maintenance: parse unprocessed #raw/*.md files, append entries to matching
13
+ mdbase dimensions, mark raw files as processed, and update LAST_SORTIN.
14
+
15
+ Options:
16
+ --dry Preview changes without writing
17
+ --help Show this help text
18
+ """
19
+
20
+
21
+ def parse_raw_file(filepath: Path):
22
+ """Parse raw entries from one file."""
23
+ entries = []
24
+ date = filepath.stem.split("-", 3)
25
+ if len(date) >= 3:
26
+ date = "-".join(date[:3])
27
+ else:
28
+ date = datetime.now().strftime("%Y-%m-%d")
29
+
30
+ for line in filepath.read_text(encoding="utf-8").splitlines():
31
+ line = line.strip()
32
+ match = re.match(r"^- \[(\d{2}:\d{2})\] (.*)$", line)
33
+ if not match:
34
+ continue
35
+ time, content = match.groups()
36
+ dim = "general"
37
+ text = content
38
+ if " | suggested-dim:" in content:
39
+ text, dim = content.rsplit(" | suggested-dim:", 1)
40
+ dim = dim.strip()
41
+ if not validate_dim_name(dim):
42
+ dim = "general"
43
+ entries.append({"time": time, "text": text.strip(), "dimension": dim, "date": date})
44
+ return entries
45
+
46
+
47
+ def dim_path(mdbase: Path, dim: str) -> Path:
48
+ """Return the target file path for a dimension."""
49
+ if dim == "backlog":
50
+ return mdbase / "backlog.md"
51
+ return mdbase / "details" / f"{dim}.md"
52
+
53
+
54
+ def count_entries(path: Path) -> int:
55
+ if not path.exists():
56
+ return 0
57
+ return sum(1 for line in path.read_text(encoding="utf-8").splitlines() if line.strip().startswith("- "))
58
+
59
+
60
+ def append_entries(path: Path, entries):
61
+ """Append entries grouped by date to one dimension file."""
62
+ by_date = defaultdict(list)
63
+ for entry in entries:
64
+ by_date[entry["date"]].append(entry)
65
+
66
+ path.parent.mkdir(parents=True, exist_ok=True)
67
+ if not path.exists():
68
+ title = path.stem.replace("-", " ").title()
69
+ path.write_text(f"# {title}\n\n> Project memory for `{path.stem}`.\n\n", encoding="utf-8")
70
+
71
+ content = path.read_text(encoding="utf-8").rstrip()
72
+ for date, date_entries in sorted(by_date.items()):
73
+ lines = [f"- {entry['text']}" for entry in date_entries]
74
+ block = "\n".join(lines)
75
+ heading = f"## {date}"
76
+ if heading in content:
77
+ content_lines = content.splitlines()
78
+ heading_idx = next(i for i, line in enumerate(content_lines) if line.strip() == heading)
79
+ insert_idx = len(content_lines)
80
+ for i in range(heading_idx + 1, len(content_lines)):
81
+ if content_lines[i].startswith("## "):
82
+ insert_idx = i
83
+ break
84
+ before = content_lines[:insert_idx]
85
+ after = content_lines[insert_idx:]
86
+ if before and before[-1].strip():
87
+ before.append("")
88
+ before.extend(lines)
89
+ if after:
90
+ before.append("")
91
+ before.extend(after)
92
+ content = "\n".join(before).rstrip()
93
+ else:
94
+ content = f"{content}\n\n{heading}\n\n{block}".rstrip()
95
+ path.write_text(content + "\n", encoding="utf-8")
96
+
97
+
98
+ def mark_processed(filepath: Path):
99
+ """Insert the processed marker at the top of a raw file."""
100
+ content = filepath.read_text(encoding="utf-8")
101
+ if content.split("\n", 1)[0].strip() != "<!-- processed -->":
102
+ filepath.write_text("<!-- processed -->\n" + content, encoding="utf-8")
103
+
104
+
105
+ def update_index(mdbase: Path):
106
+ """Rebuild mdbase/README.ai.md with dimension counts."""
107
+ now = datetime.now().strftime("%Y-%m-%d %H:%M")
108
+ details = mdbase / "details"
109
+ dims = []
110
+ if details.exists():
111
+ dims = sorted(p.relative_to(details).with_suffix("").as_posix() for p in details.rglob("*.md"))
112
+
113
+ rows = ["| File | Dimension | Entries |", "|------|-----------|---------|"]
114
+ backlog = mdbase / "backlog.md"
115
+ if backlog.exists():
116
+ rows.append(f"| [backlog.md](backlog.md) | backlog | {count_entries(backlog)} |")
117
+ for dim in dims:
118
+ path = details / f"{dim}.md"
119
+ rows.append(f"| [details/{dim}.md](details/{dim}.md) | {dim} | {count_entries(path)} |")
120
+
121
+ content = "\n".join([
122
+ "# user-thoughts mdbase Index",
123
+ "",
124
+ "This directory stores user-provided project decisions, constraints, preferences, and plans.",
125
+ "",
126
+ f"Last updated: {now}",
127
+ "",
128
+ "## Maintenance Rules",
129
+ "",
130
+ "- Preserve user wording and constraints.",
131
+ "- Append entries by date under `## yyyy-mm-dd` headings.",
132
+ "- Prefer existing dimensions before creating new ones.",
133
+ "- Mark deprecated content instead of silently deleting history.",
134
+ "",
135
+ "## Document Index",
136
+ "",
137
+ *rows,
138
+ "",
139
+ ])
140
+ (mdbase / "README.ai.md").write_text(content, encoding="utf-8")
141
+
142
+
143
+ def main():
144
+ if "--help" in sys.argv or "-h" in sys.argv:
145
+ print(HELP)
146
+ sys.exit(0)
147
+
148
+ dry = "--dry" in sys.argv
149
+ ustht = find_ustht()
150
+ if ustht is None:
151
+ print("Error: .ustht/ was not found. Run /ustht init first.")
152
+ sys.exit(1)
153
+
154
+ cfg = read_define_ini(ustht)
155
+ if cfg.get("SKILL_STATUS") == "off":
156
+ print("SKILL is off; write ignored. Run /ustht skill on to enable it.")
157
+ sys.exit(0)
158
+
159
+ raw_dir = ustht / "raw"
160
+ if not raw_dir.exists():
161
+ print("No unprocessed records.")
162
+ return
163
+
164
+ raw_files = [f for f in sorted(raw_dir.glob("*.md")) if not is_processed(f)]
165
+ if not raw_files:
166
+ print("No unprocessed records. All raw files are marked processed.")
167
+ return
168
+
169
+ all_entries = []
170
+ entries_by_file = {}
171
+ for f in raw_files:
172
+ entries = parse_raw_file(f)
173
+ entries_by_file[f] = entries
174
+ all_entries.extend(entries)
175
+
176
+ if not all_entries:
177
+ print("No valid entries found in raw files.")
178
+ return
179
+
180
+ grouped = defaultdict(list)
181
+ for entry in all_entries:
182
+ grouped[entry["dimension"]].append(entry)
183
+
184
+ print("Preview mode:" if dry else f"Soft maintenance complete. Processed {len(all_entries)} thoughts:")
185
+ mdbase = ustht / "mdbase"
186
+ for dim, entries in sorted(grouped.items()):
187
+ target = dim_path(mdbase, dim)
188
+ label = f"{dim}.md" if target.exists() else f"{dim}.md [new dimension]"
189
+ sample = entries[0]["text"][:60]
190
+ print(f" -> {label}: +{len(entries)} ({sample})")
191
+
192
+ if dry:
193
+ print(f" {len(all_entries)} total entries; no files were changed.")
194
+ return
195
+
196
+ for dim, entries in grouped.items():
197
+ append_entries(dim_path(mdbase, dim), entries)
198
+
199
+ for f in raw_files:
200
+ if entries_by_file.get(f):
201
+ mark_processed(f)
202
+
203
+ now = datetime.now().strftime("%Y-%m-%d %H:%M")
204
+ cfg["LAST_SORTIN"] = now
205
+ write_define_ini(ustht, cfg)
206
+ update_index(mdbase)
207
+ print(f" LAST_SORTIN updated to {now}")
208
+
209
+
210
+ if __name__ == "__main__":
211
+ main()
@@ -0,0 +1,56 @@
1
+ """Show current user-thoughts runtime status."""
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ from common import find_ustht, read_define_ini, is_processed
6
+
7
+ HELP = """Usage: python status.py [--help]
8
+
9
+ Show SKILL_STATUS, INSTANT_STATUS, LAST_SORTIN, raw file counts, and mdbase
10
+ dimension counts.
11
+ """
12
+
13
+
14
+ def count_raw(raw_dir: Path):
15
+ """Return total and unprocessed raw file counts."""
16
+ if not raw_dir.exists():
17
+ return 0, 0
18
+ files = list(raw_dir.glob("*.md"))
19
+ unprocessed = sum(1 for f in files if not is_processed(f))
20
+ return len(files), unprocessed
21
+
22
+
23
+ def count_dims(mdbase: Path):
24
+ """Count dimension files under mdbase/details/."""
25
+ details = mdbase / "details"
26
+ if not details.exists():
27
+ return 0
28
+ return len(list(details.rglob("*.md")))
29
+
30
+
31
+ def main():
32
+ if "--help" in sys.argv or "-h" in sys.argv:
33
+ print(HELP)
34
+ sys.exit(0)
35
+
36
+ ustht = find_ustht()
37
+ if ustht is None:
38
+ print("Error: .ustht/ was not found. Run /ustht init first.")
39
+ sys.exit(1)
40
+
41
+ cfg = read_define_ini(ustht)
42
+ skill_status = cfg.get("SKILL_STATUS", "unknown")
43
+ instant_status = cfg.get("INSTANT_STATUS", "unknown")
44
+ last_sortin = cfg.get("LAST_SORTIN", "never") or "never"
45
+ total_raw, unprocessed_raw = count_raw(ustht / "raw")
46
+ dims = count_dims(ustht / "mdbase")
47
+
48
+ print(f"SKILL_STATUS={skill_status}")
49
+ print(f"INSTANT_STATUS={instant_status}")
50
+ print(f"LAST_SORTIN={last_sortin}")
51
+ print(f"raw={unprocessed_raw} unprocessed / {total_raw} total")
52
+ print(f"dims={dims}")
53
+
54
+
55
+ if __name__ == "__main__":
56
+ main()
@@ -0,0 +1,68 @@
1
+ """Toggle SKILL_STATUS and INSTANT_STATUS."""
2
+ import sys
3
+
4
+ from common import find_ustht, read_define_ini, write_define_ini
5
+
6
+ HELP = """Usage: python toggle.py skill|instant [on|off] [--help]
7
+
8
+ Subcommands:
9
+ skill Show SKILL_STATUS
10
+ skill on|off Set SKILL_STATUS
11
+ instant Show INSTANT_STATUS
12
+ instant on|off Set INSTANT_STATUS
13
+
14
+ Note: instant on requires SKILL_STATUS=on.
15
+ """
16
+
17
+
18
+ def main():
19
+ if "--help" in sys.argv or "-h" in sys.argv:
20
+ print(HELP)
21
+ sys.exit(0)
22
+
23
+ ustht = find_ustht()
24
+ if ustht is None:
25
+ print("Error: .ustht/ was not found. Run /ustht init first.")
26
+ sys.exit(1)
27
+
28
+ if len(sys.argv) < 2:
29
+ print(f"Usage: {sys.argv[0]} skill|instant [on|off]")
30
+ sys.exit(1)
31
+
32
+ cmd = sys.argv[1]
33
+ if cmd not in {"skill", "instant"}:
34
+ print(f"Unknown command: {cmd}. Available: skill, instant")
35
+ sys.exit(1)
36
+
37
+ cfg = read_define_ini(ustht)
38
+ ini_key = "SKILL_STATUS" if cmd == "skill" else "INSTANT_STATUS"
39
+
40
+ if len(sys.argv) == 2:
41
+ print(f"{ini_key}={cfg.get(ini_key, 'unknown')}")
42
+ return
43
+
44
+ val = sys.argv[2]
45
+ if val not in {"on", "off"}:
46
+ print(f"Invalid value: {val}. Available values: on | off")
47
+ sys.exit(1)
48
+
49
+ if cmd == "instant" and val == "on" and cfg.get("SKILL_STATUS") == "off":
50
+ print("SKILL is off; instant capture cannot be enabled. Run /ustht skill on first.")
51
+ sys.exit(1)
52
+
53
+ cfg[ini_key] = val
54
+ if cmd == "skill" and val == "off":
55
+ cfg["INSTANT_STATUS"] = "off"
56
+ write_define_ini(ustht, cfg)
57
+
58
+ if cmd == "skill":
59
+ if val == "off":
60
+ print("SKILL is off. Instant capture has been paused.")
61
+ else:
62
+ print("SKILL is on.")
63
+ else:
64
+ print("Instant capture is on." if val == "on" else "Instant capture is off.")
65
+
66
+
67
+ if __name__ == "__main__":
68
+ main()
@@ -0,0 +1,106 @@
1
+ """Append one thought to today's raw file."""
2
+ import sys
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+
6
+ from common import find_ustht, read_define_ini, validate_dim_name
7
+
8
+ HELP = """Usage: python write_raw.py "thought text" [--dim dimension] [--help]
9
+
10
+ Append one thought to today's #raw/ markdown file.
11
+
12
+ Arguments:
13
+ "thought text" Thought text to record (required)
14
+ --dim dimension Suggested dimension, such as rules or ui/outline
15
+ --help Show this help text
16
+
17
+ Behavior:
18
+ - If today's raw file is already processed, creates a numbered file such as 2026-06-01-2.md.
19
+ - If the day has more than five raw entries, suggests /ustht sortin.
20
+ - If SKILL_STATUS=off, exits without writing.
21
+ """
22
+
23
+
24
+ def count_today_raw(raw_dir: Path) -> int:
25
+ """Count unprocessed entries across today's raw files."""
26
+ today = datetime.now().strftime("%Y-%m-%d")
27
+ count = 0
28
+ for f in sorted(raw_dir.glob(f"{today}*.md")):
29
+ content = f.read_text(encoding="utf-8")
30
+ first_line = content.split("\n", 1)[0].strip()
31
+ if first_line == "<!-- processed -->":
32
+ continue
33
+ count += sum(1 for line in content.splitlines() if line.strip().startswith("- ["))
34
+ return count
35
+
36
+
37
+ def main():
38
+ if "--help" in sys.argv or "-h" in sys.argv:
39
+ print(HELP)
40
+ sys.exit(0)
41
+
42
+ ustht = find_ustht()
43
+ if ustht is None:
44
+ print("Error: .ustht/ was not found. Run /ustht init first.")
45
+ sys.exit(1)
46
+
47
+ cfg = read_define_ini(ustht)
48
+ if cfg.get("SKILL_STATUS") == "off":
49
+ print("SKILL is off; write ignored.")
50
+ sys.exit(0)
51
+
52
+ thought = None
53
+ dim = None
54
+ args = sys.argv[1:]
55
+ i = 0
56
+ while i < len(args):
57
+ if args[i] == "--dim" and i + 1 < len(args):
58
+ dim = args[i + 1]
59
+ i += 2
60
+ elif thought is None:
61
+ thought = args[i]
62
+ i += 1
63
+ else:
64
+ i += 1
65
+
66
+ if not thought:
67
+ print("Error: missing thought text.")
68
+ print(f"Usage: {sys.argv[0]} \"thought text\" [--dim dimension]")
69
+ sys.exit(1)
70
+
71
+ if dim and not validate_dim_name(dim):
72
+ print(f"Invalid dimension name: {dim}. Use lowercase letters, digits, hyphens, and optional / subdirectories.")
73
+ sys.exit(1)
74
+
75
+ raw_dir = ustht / "raw"
76
+ raw_dir.mkdir(exist_ok=True)
77
+
78
+ today = datetime.now().strftime("%Y-%m-%d")
79
+ now = datetime.now().strftime("%H:%M")
80
+ raw_file = raw_dir / f"{today}.md"
81
+
82
+ if raw_file.exists():
83
+ first_line = raw_file.read_text(encoding="utf-8").split("\n", 1)[0].strip()
84
+ if first_line == "<!-- processed -->":
85
+ seq = 2
86
+ while (raw_dir / f"{today}-{seq}.md").exists():
87
+ seq += 1
88
+ raw_file = raw_dir / f"{today}-{seq}.md"
89
+
90
+ thought_clean = thought.replace("\n", " ").replace("\r", "")
91
+ suffix = f" | suggested-dim:{dim}" if dim else ""
92
+ entry = f"- [{now}] {thought_clean}{suffix}"
93
+
94
+ if raw_file.exists():
95
+ content = raw_file.read_text(encoding="utf-8").rstrip()
96
+ raw_file.write_text(f"{content}\n{entry}\n", encoding="utf-8")
97
+ else:
98
+ raw_file.write_text(f"{entry}\n", encoding="utf-8")
99
+
100
+ count = count_today_raw(raw_dir)
101
+ if count > 5:
102
+ print(f"Today has {count} recorded thoughts. Consider running /ustht sortin.")
103
+
104
+
105
+ if __name__ == "__main__":
106
+ main()
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: vibe-code-cleanup
3
- description: "Safe production cleanup and hardening for vibe-coded fullstack apps (Next.js, React, Node.js, etc.). Removes dead imports, unused files, broken references, and standardizes helpers without breaking routes or APIs."
3
+ description: "Safe production cleanup and hardening for vibe-coded fullstack apps (Next.js, React, Node.js, etc.). Removes dead imports, unused files, and broken references without breaking routes or APIs."
4
4
  category: fullstack
5
5
  risk: safe
6
6
  source: self
@@ -48,8 +48,8 @@ Before changing anything, map the codebase:
48
48
 
49
49
  ```bash
50
50
  # List all pages/routes
51
- find . -path "*/app/**/page.{js,jsx,ts,tsx}" | sort
52
- find . -path "*/pages/**/*.{js,jsx,ts,tsx}" | grep -v "_" | sort
51
+ find . -type f \( -name 'page.js' -o -name 'page.jsx' -o -name 'page.ts' -o -name 'page.tsx' \)
52
+ find pages -type f \( -name '*.js' -o -name '*.jsx' -o -name '*.ts' -o -name '*.tsx' \) | rg -v '/_' | sort
53
53
 
54
54
  # Find broken imports (TS projects)
55
55
  npx tsc --noEmit 2>&1 | head -80
@@ -185,7 +185,7 @@ If build or typecheck breaks → **revert the last batch** before continuing.
185
185
 
186
186
  Each commit should be a single logical unit:
187
187
 
188
- ```
188
+ ```text
189
189
  fix: remove broken import in app/blog/page.js
190
190
  refactor: consolidate social metadata into lib/socialMetadata.js
191
191
  chore: remove verified-unused utils/oldHelper.js
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: vibecode-production-qa-validator
3
- description: "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps before going live or shipping a major update. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation."
3
+ description: "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation."
4
4
  category: devops
5
5
  risk: safe
6
6
  source: self
@@ -69,6 +69,7 @@ grep "Static pages\|○\|●" build.log | tail -5
69
69
  ```
70
70
 
71
71
  ### Route symbols explained
72
+
72
73
  | Symbol | Meaning | Expected? |
73
74
  |--------|---------|-----------|
74
75
  | `○` | Static (rendered at build time) | ✓ Good for most pages |
@@ -179,7 +180,7 @@ git status | grep -E "\.next|node_modules"
179
180
  ```
180
181
 
181
182
  Good commit message format:
182
- ```
183
+ ```text
183
184
  type(scope): brief description
184
185
 
185
186
  fix(seo): add canonical tags to all blog pages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-skills-collection",
3
- "version": "3.0.34",
3
+ "version": "3.0.35",
4
4
  "description": "OpenCode CLI plugin that automatically downloads and keeps skills up to date.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/skills_index.json CHANGED
@@ -25211,7 +25211,7 @@
25211
25211
  "path": "skills/schema-markup-generator",
25212
25212
  "category": "seo",
25213
25213
  "name": "schema-markup-generator",
25214
- "description": "Generate and implement JSON-LD structured data for web apps, tool pages, blogs, FAQs, and SaaS sites. Supports WebSite, SoftwareApplication, BlogPosting, FAQPage, HowTo, BreadcrumbList, and Organization schemas.",
25214
+ "description": "Generate and implement JSON-LD structured data for web apps, blogs, FAQs, and SaaS sites. Supports WebSite, SoftwareApplication, BlogPosting, FAQPage, HowTo, and more.",
25215
25215
  "risk": "safe",
25216
25216
  "source": "self",
25217
25217
  "date_added": "2026-05-31",
@@ -27561,7 +27561,7 @@
27561
27561
  "path": "skills/social-metadata-hardening",
27562
27562
  "category": "seo",
27563
27563
  "name": "social-metadata-hardening",
27564
- "description": "Fix social sharing previews so URLs render as rich cards on Facebook, LinkedIn, X/Twitter, WhatsApp, Telegram, Slack, and Discord. Covers OG tags, Twitter cards, absolute image URLs, and metadata debugging.",
27564
+ "description": "Fix social sharing previews so URLs render as rich cards on Facebook, LinkedIn, X/Twitter, WhatsApp, Telegram, and more. Covers OG tags, Twitter cards, absolute image URLs, and debugging.",
27565
27565
  "risk": "safe",
27566
27566
  "source": "self",
27567
27567
  "date_added": "2026-05-31",
@@ -30732,6 +30732,28 @@
30732
30732
  "reasons": []
30733
30733
  }
30734
30734
  },
30735
+ {
30736
+ "id": "user-thoughts",
30737
+ "path": "skills/user-thoughts",
30738
+ "category": "web-development",
30739
+ "name": "user-thoughts",
30740
+ "description": "Persist user decisions and project constraints to mdbase across sessions. Trigger on /user-thoughts or /ustht, or when the user discusses architecture, tech stack, rules, UI/UX, or project memory.",
30741
+ "risk": "safe",
30742
+ "source": "https://github.com/JularDepick/user-thoughts.SKILL",
30743
+ "date_added": "2026-05-31",
30744
+ "plugin": {
30745
+ "targets": {
30746
+ "codex": "supported",
30747
+ "claude": "supported"
30748
+ },
30749
+ "setup": {
30750
+ "type": "none",
30751
+ "summary": "",
30752
+ "docs": null
30753
+ },
30754
+ "reasons": []
30755
+ }
30756
+ },
30735
30757
  {
30736
30758
  "id": "using-git-worktrees",
30737
30759
  "path": "skills/using-git-worktrees",
@@ -31225,7 +31247,7 @@
31225
31247
  "path": "skills/vibe-code-cleanup",
31226
31248
  "category": "fullstack",
31227
31249
  "name": "vibe-code-cleanup",
31228
- "description": "Safe production cleanup and hardening for vibe-coded fullstack apps (Next.js, React, Node.js, etc.). Removes dead imports, unused files, broken references, and standardizes helpers without breaking routes or APIs.",
31250
+ "description": "Safe production cleanup and hardening for vibe-coded fullstack apps (Next.js, React, Node.js, etc.). Removes dead imports, unused files, and broken references without breaking routes or APIs.",
31229
31251
  "risk": "safe",
31230
31252
  "source": "self",
31231
31253
  "date_added": "2026-05-31",
@@ -31247,7 +31269,7 @@
31247
31269
  "path": "skills/vibecode-production-qa-validator",
31248
31270
  "category": "devops",
31249
31271
  "name": "vibecode-production-qa-validator",
31250
- "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps before going live or shipping a major update. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.",
31272
+ "description": "End-to-end production QA, build verification, and launch-readiness checklist for fullstack Next.js apps. Covers TypeScript, linting, tests, build, SEO tags, route regression, and sitemap validation.",
31251
31273
  "risk": "safe",
31252
31274
  "source": "self",
31253
31275
  "date_added": "2026-05-31",