From a63abebda3a94c71e61f6335b254a50e8be7d0d9 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Sun, 3 May 2026 14:29:59 +0200 Subject: [PATCH] =?UTF-8?q?feat(home):=20opencode=20module=20=E2=80=94=20l?= =?UTF-8?q?ink=20config/opencode=20=E2=86=92=20~/.config/opencode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds metacfg.cli-apps.opencode (default enabled) which mounts the in-repo opencode config (provider list, web-search skill) via xdg.configFile, so all hosts pick it up automatically. --- config/opencode/config.json | 39 ++++++++++ config/opencode/skills/web-search/SKILL.md | 86 ++++++++++++++++++++++ modules/home/cli-apps/opencode/default.nix | 23 ++++++ 3 files changed, 148 insertions(+) create mode 100644 config/opencode/config.json create mode 100644 config/opencode/skills/web-search/SKILL.md create mode 100644 modules/home/cli-apps/opencode/default.nix diff --git a/config/opencode/config.json b/config/opencode/config.json new file mode 100644 index 0000000..e3ad78e --- /dev/null +++ b/config/opencode/config.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "halo-8001": { + "npm": "@ai-sdk/openai-compatible", + "name": "Halo (8001)", + "options": { + "baseURL": "http://halo.fritz.box:8001/v1" + }, + "models": { + "unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q8_K_XL": { "name" : "halo 8001" } + } + }, + "halo-8000": { + "npm": "@ai-sdk/openai-compatible", + "name": "Halo (8000)", + "options": { + "baseURL": "http://halo.fritz.box:8000/v1" + }, + "models": { + "unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q8_K_XL": { + "name": "halo 8000" + } + } + }, + "lmstudio-local": { + "npm": "@ai-sdk/openai-compatible", + "name": "LM Studio (local)", + "options": { + "baseURL": "http://127.0.0.1:1234/v1" + }, + "models": { + "qwen3-coder-30b-a3b-instruct-mlx@6bit": { + "name": "qwen3-coder-30b-a3b-instruct-mlx@6bit" + } + } + } + } +} diff --git a/config/opencode/skills/web-search/SKILL.md b/config/opencode/skills/web-search/SKILL.md new file mode 100644 index 0000000..6a087db --- /dev/null +++ b/config/opencode/skills/web-search/SKILL.md @@ -0,0 +1,86 @@ +--- +name: web-search +description: Search the web and fetch page content via the user's private SearXNG instance at search.hoyer.world. Use this whenever current information is needed - library docs, error message lookups, recent releases, API references, or any general research that goes beyond training data. Trigger words include "search", "look up", "find docs for", "what's the current", "latest version of". Always prefer this over guessing from memory. +--- + +# Web Search via SearXNG + +The user runs a private SearXNG instance at `$SEARXNG_URL` +(default: `https://search.hoyer.world`). Use it for all web research. + +Run searches via the `bash` tool. Do NOT attempt MCP or built-in web search. + +## Search + +```bash +curl -sfG "${SEARXNG_URL:-https://search.hoyer.world}/search" \ + --data-urlencode "q=QUERY HERE" \ + --data-urlencode 'format=json' \ + --data-urlencode 'language=en' \ + --data-urlencode 'safesearch=0' \ + | jq -r '.results[0:8][] | "## \(.title)\n<\(.url)>\n\(.content // "")\n"' +``` + +Keep queries short (3–6 words). For follow-ups, increment `pageno` instead of +re-running the same query: + +```bash +... --data-urlencode 'pageno=2' ... +``` + +## Categories + +Bias results to relevant engines via `categories`: + +| Category | Use for | +|------------|-----------------------------------------------| +| `general` | default | +| `it` | programming, dev tools (GitHub, SO, MDN, …) | +| `repos` | source-code search | +| `news` | recent events | +| `science` | papers, arXiv, PubMed | + +```bash +... --data-urlencode 'categories=it' ... +``` + +## Time filtering + +For "current"/"latest" queries add `time_range=month` or `year` to drop +stale results: + +```bash +... --data-urlencode 'time_range=year' ... +``` + +## Fetching a page + +For full content of a result URL, use pandoc via `nix run` (no install needed): + +```bash +curl -sfL --max-time 15 \ + -H 'User-Agent: Mozilla/5.0' \ + "$URL" \ + | nix run nixpkgs#pandoc -- -f html -t gfm --wrap=none 2>/dev/null \ + | sed -E 's/!\[[^]]*\]\([^)]*\)//g' \ + | head -c 12000 +``` + +The first `nix run` invocation may take a few seconds while pandoc is fetched +into the Nix store; subsequent calls are instant. + +For very simple pages where you only want plain text: + +```bash +curl -sfL --max-time 15 -H 'User-Agent: Mozilla/5.0' "$URL" \ + | nix run nixpkgs#lynx -- -dump -nolist -stdin \ + | head -c 12000 +``` + +## Don'ts + +- Do not paginate by re-running identical queries — use `pageno`. +- Do not fetch more than 3 URLs per task without checking with the user first. +- Do not ignore `time_range` for version- or release-related questions. +- Do not return raw JSON to the user — always render as the markdown shown above. + diff --git a/modules/home/cli-apps/opencode/default.nix b/modules/home/cli-apps/opencode/default.nix new file mode 100644 index 0000000..8b6fd31 --- /dev/null +++ b/modules/home/cli-apps/opencode/default.nix @@ -0,0 +1,23 @@ +{ + lib, + config, + ... +}: +let + inherit (lib) mkIf; + inherit (lib.metacfg) mkBoolOpt; + + cfg = config.metacfg.cli-apps.opencode; +in +{ + options.metacfg.cli-apps.opencode = { + enable = mkBoolOpt true "Enable opencode config."; + }; + + config = mkIf cfg.enable { + xdg.configFile."opencode" = { + source = ../../../../config/opencode; + recursive = true; + }; + }; +}