646c82be4e02abaf02d8ad303636239bc3d18ea6
- Author
- TheEdgeOfRage <git@theedgeofrage.com>
- Committer
- TheEdgeOfRage <git@theedgeofrage.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/dot_config/opencode/opencode.json.tmpl b/dot_config/opencode/opencode.json.tmpl
2index 7223d882295f852de3d1b9c81329246d02d39841..3cd9e2a45282844b8353448c9ce3c9af31a1eb19 100644
3--- a/dot_config/opencode/opencode.json.tmpl
4+++ b/dot_config/opencode/opencode.json.tmpl
5@@ -30,7 +30,7 @@
6 "doom_loop": "ask"
7 },
8 "plugin": [
9- "@tarquinen/opencode-dcp@v3.1.13",
10+ "@tarquinen/opencode-dcp@v3.1.15",
11 "/home/pavle/dev/opencode/policy-engine/src/index.ts",
12 "file:///home/pavle/.local/lib/node_modules/@rynfar/meridian/plugin/meridian.ts"
13 ],
14diff --git a/dot_config/opencode/skills/comms-polish/SKILL.md b/dot_config/opencode/skills/comms-polish/SKILL.md
15new file mode 100644
16index 0000000000000000000000000000000000000000..6fc217b039754c41f658fba9fd141656c90f33f6
17--- /dev/null
18+++ b/dot_config/opencode/skills/comms-polish/SKILL.md
19@@ -0,0 +1,91 @@
20+---
21+name: comms-polish
22diff --git a/dot_config/opencode/skills/go-code/SKILL.md b/dot_config/opencode/skills/go-code/SKILL.md
23new file mode 100644
24index 0000000000000000000000000000000000000000..415c1463e65eb9bac543636c65f918e5ae3f8ab4
25--- /dev/null
26+++ b/dot_config/opencode/skills/go-code/SKILL.md
27@@ -0,0 +1,8 @@
28+---
29+name: go-code
30+description: Rules for writing go code
31+---
32+
33+## Go development
34+
35+- Always use `make lint` if available, if not, prefer `go vet` over `go build`
36diff --git a/dot_config/opencode/skills/linear-update/SKILL.md b/dot_config/opencode/skills/linear-update/SKILL.md
37new file mode 100644
38index 0000000000000000000000000000000000000000..9df76bc9292aa469c6cb59003bedf4cf4be86ca5
39--- /dev/null
40+++ b/dot_config/opencode/skills/linear-update/SKILL.md
41@@ -0,0 +1,122 @@
42+---
43+name: linear-update
44+version: 2.0.0
45+description: "Draft and post a weekly status update to Linear for a project OR initiative. Auto-detects which the name refers to, synthesizes Past week / Next week / Asks from Linear + Slack, and posts on approval."
46+metadata:
47+ openclaw:
48+ category: "productivity"
49+ requires:
50+ mcpServers: ["linear", "slack"]
51+---
52+
53+# /linear-update
54+
55+Draft and post a weekly status update to Linear. Takes a **name**, figures out whether it
56+is a Linear **project** or **initiative**, then writes the update in the **Past week /
57+Next week / Asks** format and posts it on your approval.
58+
59+## Parameters
60+
61+| Parameter | Required | Default | Description |
62+|-----------|----------|---------|-------------|
63+| `name` | No | — | Name of the Linear project or initiative to update (passed as the argument). The skill auto-detects which it is. If omitted, ask the user. |
64+| `channels` | No | auto | Optional Slack channel name(s) to pull context from. If omitted, auto-discover and confirm. |
65+
66+## Step 1 — Resolve the name (project vs. initiative)
67+
68+This is the first thing the skill does and it determines everything downstream.
69+
70+1. If no `name` was provided, ask the user which project or initiative to update.
71+2. Search both in parallel:
72+ - `list_initiatives` with `query: <name>`
73+ - `list_projects` with `query: <name>`
74+3. Match case-insensitively against the returned names:
75+ - **Exactly one type matches** → use that type (`project` or `initiative`).
76+ - **Both an initiative and a project match** (or near-match) → ask the user which one they mean before continuing. Do not guess.
77+ - **Nothing matches** → show the closest candidates from both lists and ask the user to pick or rename.
78+4. Hold onto the resolved `type` (`project` | `initiative`) and the canonical name/ID — every later tool call branches on it.
79+
80+## Step 2 — Gather context (parallel where possible)
81+
82diff --git a/dot_config/opencode/skills/share-tables/SKILL.md b/dot_config/opencode/skills/share-tables/SKILL.md
83new file mode 100644
84index 0000000000000000000000000000000000000000..5593174147de2d9bdb2075ed36b85437d0582582
85--- /dev/null
86+++ b/dot_config/opencode/skills/share-tables/SKILL.md
87@@ -0,0 +1,104 @@
88+---
89+name: share-tables
90diff --git a/dot_config/opencode/skills/share-tables/mappings_prod b/dot_config/opencode/skills/share-tables/mappings_prod
91new file mode 100644
92index 0000000000000000000000000000000000000000..327c8d2f9add112b8464aa3f77e6d8e3e6ba8074
93--- /dev/null
94+++ b/dot_config/opencode/skills/share-tables/mappings_prod
95@@ -0,0 +1,3 @@
96+stablecore:29946
97+dune_curated_data:35887
98+dune:12
99diff --git a/dot_config/opencode/skills/share-tables/scripts/executable_get-table.sh b/dot_config/opencode/skills/share-tables/scripts/executable_get-table.sh
100new file mode 100644
101index 0000000000000000000000000000000000000000..2e22403e4f012848ec2614bd146fa3aadca98a83
102--- /dev/null
103+++ b/dot_config/opencode/skills/share-tables/scripts/executable_get-table.sh
104@@ -0,0 +1,53 @@
105+#!/usr/bin/env bash
106+# Look up the type (and view SQL, if applicable) of one or more tables via
107+# the Catalog gRPC service, authenticating as a given source team.
108+#
109+# One request per table. No recursion — view-dependency traversal is the
110+# LLM's responsibility.
111+#
112+# Usage:
113+# get-table.sh <dev|prod> <from_handle:from_id> <catalog.schema.table>...
114+#
115+# Example:
116+# get-table.sh prod stablecore:29946 dune.stablecore.stablecoins_evm_balances_enriched_v2
117+#
118+# Requires: grpcurl, jq, tailscale network access to the catalog service.
119+set -euo pipefail
120+
121+if (( $# < 3 )); then
122+ echo "usage: $0 <dev|prod> <from_handle:from_id> <catalog.schema.table>..." >&2
123+ exit 2
124+fi
125+
126+env=$1 from=$2
127+shift 2
128+
129+case $env in
130+ dev) host=dev-catalog-svc-trino.ayu-decibel.ts.net:4040 ;;
131+ prod) host=prod-catalog-service-trino.ayu-decibel.ts.net:4040 ;;
132+ *) echo "error: env must be dev or prod (got: $env)" >&2; exit 2 ;;
133+esac
134+
135+if [[ $from != *:* ]]; then
136+ echo "error: from must be in the form handle:id (got: $from)" >&2
137+ exit 2
138+fi
139+from_id=${from##*:}
140+[[ $from_id =~ ^[0-9]+$ ]] || { echo "error: from id must be numeric (got: $from_id)" >&2; exit 2; }
141+
142+creds=$(printf '{"customerID": "team_%s"}' "$from_id" | base64 -w0 | tr -d '=')
143+
144+for fqn in "$@"; do
145+ IFS='.' read -ra parts <<<"$fqn"
146+ if (( ${#parts[@]} != 3 )) || [[ -z ${parts[0]} || -z ${parts[1]} || -z ${parts[2]} ]]; then
147+ echo "error: table must be in the form catalog.schema.name (got: $fqn)" >&2
148+ exit 2
149+ fi
150+ catalog=${parts[0]} schema=${parts[1]} name=${parts[2]}
151+ echo "=== $catalog.$schema.$name ==="
152+ grpcurl -plaintext \
153+ -d "{\"sql_id\":{\"catalog\":\"$catalog\",\"schema\":\"$schema\",\"name\":\"$name\"},\"credentials\":\"$creds\"}" \
154+ "$host" \
155+ core.catalog.apis.v1.CatalogService/GetTrinoTable \
156+ | jq -r '"type: " + .table.type, (if .table.viewMetadata then "viewSql:\n" + .table.viewMetadata.viewSql else empty end)'
157+done
158diff --git a/dot_config/opencode/skills/share-tables/scripts/executable_share.sh b/dot_config/opencode/skills/share-tables/scripts/executable_share.sh
159new file mode 100644
160index 0000000000000000000000000000000000000000..57622f96203367085573ab6e7dd50a94dbeacf69
161--- /dev/null
162+++ b/dot_config/opencode/skills/share-tables/scripts/executable_share.sh
163@@ -0,0 +1,66 @@
164+#!/usr/bin/env bash
165+# Grant or revoke a team's access to another team's private catalog tables
166+# via the Catalog gRPC service.
167+#
168+# Usage:
169+# share.sh <dev|prod> <add|remove> <from_handle:from_id> <dest_handle> <catalog.schema.table>...
170+#
171+# Example:
172+# share.sh prod add stablecore:29946 gfdionis_team dune.stablecore.stablecoins_evm_activity_enriched
173+#
174+# Requires: grpcurl, tailscale network access to the catalog service.
175+set -euo pipefail
176+
177+if (( $# < 5 )); then
178+ echo "usage: $0 <dev|prod> <add|remove> <from_handle:from_id> <dest_handle> <catalog.schema.table>..." >&2
179+ exit 2
180+fi
181+
182+env=$1 action=$2 from=$3 dest=$4
183+shift 4
184+
185+case $env in
186+ dev) host=dev-catalog-svc-trino.ayu-decibel.ts.net:4040 ;;
187+ prod) host=prod-catalog-service-trino.ayu-decibel.ts.net:4040 ;;
188+ *) echo "error: env must be dev or prod (got: $env)" >&2; exit 2 ;;
189+esac
190+
191+case $action in
192+ add) method=AddTableTeamAccess ;;
193+ remove) method=RemoveTableTeamAccess ;;
194+ *) echo "error: action must be add or remove (got: $action)" >&2; exit 2 ;;
195+esac
196+
197+if [[ $from != *:* ]]; then
198+ echo "error: from must be in the form handle:id (got: $from)" >&2
199+ exit 2
200+fi
201+from_id=${from##*:}
202+[[ $from_id =~ ^[0-9]+$ ]] || { echo "error: from id must be numeric (got: $from_id)" >&2; exit 2; }
203+
204+creds=$(printf '{"customerID":"team_%s","duneAdminKey":"duneDatashare"}' "$from_id" | base64 -w0 | tr -d '=')
205+
206+for fqn in "$@"; do
207+ IFS='.' read -ra parts <<<"$fqn"
208+ if (( ${#parts[@]} != 3 )) || [[ -z ${parts[0]} || -z ${parts[1]} || -z ${parts[2]} ]]; then
209+ echo "error: table must be in the form catalog.schema.name (got: $fqn)" >&2
210+ exit 2
211+ fi
212+ catalog=${parts[0]} schema=${parts[1]} name=${parts[2]}
213+ echo ">>> $action $catalog.$schema.$name -> $dest"
214+ set +e
215+ out=$(grpcurl -plaintext \
216+ -d "{\"sql_id\":{\"catalog\":\"$catalog\",\"schema\":\"$schema\",\"name\":\"$name\"},\"team_handle\":\"$dest\",\"credentials\":\"$creds\"}" \
217+ "$host" \
218+ "core.catalog.apis.v1.CatalogService/$method" 2>&1)
219+ status=$?
220+ set -e
221+ printf '%s\n' "$out"
222+ if (( status != 0 )); then
223+ if [[ $out == *"can only share private tables"* ]]; then
224+ echo " (already public, skipping)"
225+ continue
226+ fi
227+ exit "$status"
228+ fi
229+done
230diff --git a/dot_config/opencode/skills/websearch/SKILL.md b/dot_config/opencode/skills/websearch/SKILL.md
231deleted file mode 100644
232index 0a3b39ffc7af4b21caf9a0a60d9b27dfd9c0b09c..0000000000000000000000000000000000000000
233--- a/dot_config/opencode/skills/websearch/SKILL.md
234+++ /dev/null
235@@ -1,56 +0,0 @@
236----
237-name: websearch
238-description: >
239- Perform web searches using ddgs (web search service client). Use this skill
240- whenever you are uncertain about a fact, need current information, need to
241- look up a library/API/version, or the user explicitly asks to search the web
242- for something. Trigger proactively when you'd otherwise guess or hallucinate
243- an answer — search instead. Also triggers on: "look this up", "what is the
244- latest", "search for", "I'm not sure about", or any question about package
245- versions, documentation, or third-party tools.
246----
247-
248-## When to use
249-
250-Search the web when:
251-- You're uncertain about a fact and could reasonably be wrong
252-- The user asks for current/recent information (versions, docs)
253-- The user explicitly asks for a web search
254-- You need to verify something before giving a definitive answer
255-
256-Don't search for things you know with high confidence, or for purely
257-implementation tasks where no external lookup is needed.
258-
259-## How to search
260-
261-Run the bundled script from this skill's `scripts/` directory:
262-
263-```bash
264-uv run -w ddgs python <skill_dir>/scripts/search.py "<query>" [max_results]
265-```
266-
267-`max_results` defaults to 5. Increase it (up to ~10) for broader topics.
268-
269-The script prints results in this format:
270-
271-```
272-{i}. {title}"
273- {href}"
274- {body}"
275-```
276-
277-## Crafting good queries
278-
279-- Be specific: `"python requests library timeout default"` beats `"python timeout"`
280-- For versioning: `"ddgs latest version pypi"` or `"package changelog site:github.com"`
281-- For docs: append `site:docs.example.com` or `filetype:html` when helpful
282-- For recent info: the library uses `timelimit` but the script defaults to no
283- limit; if you need recent results, modify the query with a year or "2025"
284-
285-## Presenting results
286-
287-After searching:
288-1. Summarize what you found — don't dump raw results on the user
289-2. Cite the source URL for any specific claim
290-3. If results are thin or irrelevant, try a rephrased query before giving up
291-4. If nothing useful turns up after 2 attempts, say so honestly
292diff --git a/dot_config/opencode/skills/websearch/scripts/search.py b/dot_config/opencode/skills/websearch/scripts/search.py
293deleted file mode 100644
294index 4cc412ec1e600a87e6a20b275c97ebd22f974a0b..0000000000000000000000000000000000000000
295--- a/dot_config/opencode/skills/websearch/scripts/search.py
296+++ /dev/null
297@@ -1,25 +0,0 @@
298-#!/usr/bin/env python3
299-"""Web search using ddgs. Usage: uv run -w ddgs python search.py <query> [max_results]"""
300-
301-import sys
302-from ddgs import DDGS
303-
304-
305-def main():
306- if len(sys.argv) < 2:
307- print("Usage: search.py <query> [max_results]", file=sys.stderr)
308- sys.exit(1)
309-
310- query = sys.argv[1]
311- max_results = int(sys.argv[2]) if len(sys.argv) > 2 else 5
312-
313- results = DDGS().text(query, max_results=max_results)
314- for i, r in enumerate(results, 1):
315- print(f"{i}. {r['title']}")
316- print(f" {r['href']}")
317- print(f" {r['body']}")
318- print()
319-
320-
321-if __name__ == "__main__":
322- main()