Diff
1diff --git a/dot_config/opencode/skills/qmd/SKILL.md b/dot_config/opencode/skills/qmd/SKILL.md
2index 328d079f6c64d2a7ff7d1609e1077d2aa709c864..de910987c35e99fc0024863f7fbbe5040974387b 100644
3--- a/dot_config/opencode/skills/qmd/SKILL.md
4+++ b/dot_config/opencode/skills/qmd/SKILL.md
5@@ -1,6 +1,6 @@
6 ---
7 name: qmd
8-description: Search markdown knowledge bases, notes, and documentation using QMD. Use when users ask to search notes, find documents, or look up information.
9+description: Search markdown knowledge bases, notes, and documentation using QMD. Use when users ask to search notes, find documents, or look up information in local files.
10 license: MIT
11 compatibility: Requires qmd CLI
12 metadata:
13diff --git a/dot_config/opencode/skills/websearch/SKILL.md b/dot_config/opencode/skills/websearch/SKILL.md
14new file mode 100644
15index 0000000000000000000000000000000000000000..fa8e287d00a00d20e90665c9e035b086275a53a0
16--- /dev/null
17+++ b/dot_config/opencode/skills/websearch/SKILL.md
18@@ -0,0 +1,50 @@
19+---
20+name: websearch
21+description: >
22+ Perform web searches using ddgs (web search service client). Use this skill
23+ whenever you are uncertain about a fact, need current information, need to
24+ look up a library/API/version, or the user explicitly asks to search the web
25+ for something. Trigger proactively when you'd otherwise guess or hallucinate
26+ an answer — search instead. Also triggers on: "look this up", "what is the
27+ latest", "search for", "I'm not sure about", or any question about package
28+ versions, documentation, or third-party tools.
29+---
30+
31+## When to use
32+
33+Search the web when:
34+- You're uncertain about a fact and could reasonably be wrong
35+- The user asks for current/recent information (versions, docs)
36+- The user explicitly asks for a web search
37+- You need to verify something before giving a definitive answer
38+
39+Don't search for things you know with high confidence, or for purely
40+implementation tasks where no external lookup is needed.
41+
42+## How to search
43+
44+Run the bundled script from this skill's `scripts/` directory:
45+
46+```bash
47+python <skill_dir>/scripts/search.py "<query>" [max_results]
48+```
49+
50+`max_results` defaults to 5. Increase it (up to ~10) for broader topics.
51+
52+The script prints results as: title, URL, and a snippet per result.
53+
54+## Crafting good queries
55+
56+- Be specific: `"python requests library timeout default"` beats `"python timeout"`
57+- For versioning: `"ddgs latest version pypi"` or `"package changelog site:github.com"`
58+- For docs: append `site:docs.example.com` or `filetype:html` when helpful
59+- For recent info: the library uses `timelimit` but the script defaults to no
60+ limit; if you need recent results, modify the query with a year or "2025"
61+
62+## Presenting results
63+
64+After searching:
65+1. Summarize what you found — don't dump raw results on the user
66+2. Cite the source URL for any specific claim
67+3. If results are thin or irrelevant, try a rephrased query before giving up
68+4. If nothing useful turns up after 2 attempts, say so honestly
69diff --git a/dot_config/opencode/skills/websearch/scripts/search.py b/dot_config/opencode/skills/websearch/scripts/search.py
70new file mode 100644
71index 0000000000000000000000000000000000000000..bbda2f158a6f5088524a7339a96a1505015755bb
72--- /dev/null
73+++ b/dot_config/opencode/skills/websearch/scripts/search.py
74@@ -0,0 +1,26 @@
75+#!/usr/bin/env python3
76+"""Web search using ddgs. Usage: python search.py <query> [max_results]"""
77+
78+import sys
79+import json
80+from ddgs import DDGS
81+
82+
83+def main():
84+ if len(sys.argv) < 2:
85+ print("Usage: search.py <query> [max_results]", file=sys.stderr)
86+ sys.exit(1)
87+
88+ query = sys.argv[1]
89+ max_results = int(sys.argv[2]) if len(sys.argv) > 2 else 5
90+
91+ results = DDGS().text(query, max_results=max_results)
92+ for i, r in enumerate(results, 1):
93+ print(f"{i}. {r['title']}")
94+ print(f" {r['href']}")
95+ print(f" {r['body']}")
96+ print()
97+
98+
99+if __name__ == "__main__":
100+ main()