create skill: silverbullet-query — SLIQ query/filter widgets for SilverBullet notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a26678119b
commit
d7dfb6c0e2
2 changed files with 184 additions and 0 deletions
|
|
@ -42,6 +42,8 @@ description: Master index of all skills in your robot assistant system. Your ass
|
|||
| "support punt," "forward to support," "send to support," "punt this to support," "hand off to support" | **send-to-support** |
|
||||
| "add a contact," "look up a contact," "find someone's number," "update a contact," "delete a contact," "list my contacts," "contacts" | **contacts** |
|
||||
| "transcribe this video," "get the subtitles," "what does this video say," "summarize this YouTube video," "YouTube transcript" | **youtube-transcript** |
|
||||
| "upload to s2," "s2," "s2 storage," "upload a file," "store this file" | **s2-storage** |
|
||||
| "make a query," "show all pages tagged," "build a filter," "list tasks in," "show recent notes," "create a silverbullet view," "make a live widget" | **silverbullet-query** |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -221,6 +223,18 @@ description: Master index of all skills in your robot assistant system. Your ass
|
|||
**File:** `skills/youtube-transcript/SKILL.md`
|
||||
**Dependencies:** `yt-dlp` CLI, Python 3
|
||||
|
||||
### S2 Storage
|
||||
**Purpose:** Upload and manage files on S2, a self-hosted file storage service at s2.connorrhodes.com. Provides upload endpoint and auth details for persistent file storage.
|
||||
**Triggers:** "upload to s2," "s2," "s2 storage," "upload a file," "store this file"
|
||||
**File:** `skills/s2-storage/SKILL.md`
|
||||
**Dependencies:** `curl` CLI
|
||||
|
||||
### SilverBullet Query
|
||||
**Purpose:** Write Space Lua (SLIQ) queries and live filter widgets for SilverBullet notes. Covers filtering pages by folder or tag, listing tasks, showing recently modified notes, building dashboards, and embedding dynamic query expressions in any note.
|
||||
**Triggers:** "make a query," "show all pages tagged," "build a filter," "list tasks in," "show recent notes," "create a silverbullet view," "make a live widget"
|
||||
**File:** `skills/silverbullet-query/SKILL.md`
|
||||
**Dependencies:** SilverBullet running with Space Lua enabled
|
||||
|
||||
---
|
||||
|
||||
## Adding New Skills
|
||||
|
|
|
|||
170
silverbullet-query/SKILL.md
Normal file
170
silverbullet-query/SKILL.md
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
name: silverbullet-query
|
||||
description: Write Space Lua queries (SLIQ) for SilverBullet notes. Use this skill whenever the user wants to build a query, filter, or live view in their SilverBullet space — including filtering pages by folder or tag, listing tasks, showing recently modified notes, building dashboards, or embedding any kind of dynamic query widget in a note. Triggers on phrases like "make a query," "show all pages tagged," "build a filter," "list tasks in," "show recent notes," "create a silverbullet view," or "make a live widget."
|
||||
---
|
||||
|
||||
# SilverBullet Query Skill
|
||||
|
||||
SilverBullet uses **SLIQ** (Space Lua Integrated Query) — an SQL-inspired query language embedded in Lua. Queries live inside `${...}` expressions that render as live widgets in any note.
|
||||
|
||||
## Quick reference
|
||||
|
||||
### Embedding a query in a note
|
||||
|
||||
Queries render inline using the `${...}` expression syntax:
|
||||
|
||||
```
|
||||
${template.each(query[[
|
||||
from p = index.tag "page"
|
||||
where p.name:startsWith("proj/")
|
||||
order by p.lastModified desc
|
||||
]], templates.pageItem)}
|
||||
```
|
||||
|
||||
Use `template.each(collection, template)` to render a list. Use `query[[...]]` alone when you just need the raw data or a single computed value.
|
||||
|
||||
### Data sources
|
||||
|
||||
| What you want | `from` clause |
|
||||
|---|---|
|
||||
| All pages | `from p = index.tag "page"` |
|
||||
| All tasks | `from t = index.tag "task"` |
|
||||
| All bullet items | `from i = index.tag "item"` |
|
||||
| All paragraphs | `from p = index.tag "paragraph"` |
|
||||
| All tags | `from t = index.tag "tag"` |
|
||||
| A Lua list | `from n = {1, 2, 3}` |
|
||||
|
||||
Always use the explicit variable binding form (`p =`) — it's more reliable and future-proof.
|
||||
|
||||
### Filtering (`where`)
|
||||
|
||||
```
|
||||
-- Pages in a folder
|
||||
where p.name:startsWith("proj/")
|
||||
|
||||
-- Pages with a specific tag
|
||||
where table.includes(p.tags, "account")
|
||||
|
||||
-- Pages matching name
|
||||
where p.name:startsWith("Person")
|
||||
|
||||
-- Tasks on the current page only
|
||||
where t.page == _CTX.currentPage.name
|
||||
|
||||
-- Combine conditions
|
||||
where p.name:startsWith("proj/") and table.includes(p.tags, "active")
|
||||
```
|
||||
|
||||
### Sorting (`order by`)
|
||||
|
||||
```
|
||||
order by p.lastModified desc -- newest first
|
||||
order by p.lastModified asc -- oldest first
|
||||
order by p.name -- alphabetical
|
||||
order by p.lastModified desc, p.name -- multi-key
|
||||
```
|
||||
|
||||
Nulls default to last (asc) or first (desc). Override with `nulls first` / `nulls last`.
|
||||
|
||||
### Limits and offsets
|
||||
|
||||
```
|
||||
limit 10
|
||||
limit 10, 2 -- limit 10, skip first 2 (inline offset)
|
||||
offset 5
|
||||
```
|
||||
|
||||
### Selecting / transforming results
|
||||
|
||||
```
|
||||
select p.name -- just the name
|
||||
select { name = p.name, mod = p.lastModified } -- custom object
|
||||
select p -- full object (default)
|
||||
```
|
||||
|
||||
### Render templates
|
||||
|
||||
| Template | Renders as |
|
||||
|---|---|
|
||||
| `templates.pageItem` | `* [[page name]]` |
|
||||
| `templates.fullPageItem` | `* [[page name\|page name]]` |
|
||||
| `templates.taskItem` | `* [state] [[ref]] task text` |
|
||||
| `templates.itemItem` | `* [[ref]] item text` |
|
||||
| `templates.paragraphItem` | `* [[ref]] paragraph text` |
|
||||
| `templates.tagItem` | `* [[tag:name\|#name]]` |
|
||||
|
||||
## Common patterns
|
||||
|
||||
### Pages in a folder, newest first
|
||||
|
||||
```
|
||||
${template.each(query[[
|
||||
from p = index.tag "page"
|
||||
where p.name:startsWith("FOLDER/")
|
||||
order by p.lastModified desc
|
||||
]], templates.pageItem)}
|
||||
```
|
||||
|
||||
### Pages with a given tag
|
||||
|
||||
```
|
||||
${template.each(query[[
|
||||
from p = index.tag "page"
|
||||
where table.includes(p.tags, "TAGNAME")
|
||||
order by p.lastModified desc
|
||||
]], templates.pageItem)}
|
||||
```
|
||||
|
||||
### Open tasks on the current page
|
||||
|
||||
```
|
||||
${template.each(query[[
|
||||
from t = index.tag "task"
|
||||
where t.page == _CTX.currentPage.name and t.state == " "
|
||||
]], templates.taskItem)}
|
||||
```
|
||||
|
||||
### 5 most recently modified pages
|
||||
|
||||
```
|
||||
${template.each(query[[
|
||||
from p = index.tag "page"
|
||||
order by p.lastModified desc
|
||||
limit 5
|
||||
]], templates.pageItem)}
|
||||
```
|
||||
|
||||
### Inline count (no template)
|
||||
|
||||
```
|
||||
${#query[[from p = index.tag "page" where p.name:startsWith("proj/")]]} projects
|
||||
```
|
||||
|
||||
## How to write a query for the user
|
||||
|
||||
1. Ask what objects they want (pages, tasks, items, tags, etc.)
|
||||
2. Ask what filter applies (folder prefix, tag, current page, a condition)
|
||||
3. Ask how to sort (newest first is `lastModified desc`, alphabetical is `p.name`)
|
||||
4. Ask if they want a limit
|
||||
5. Pick the right `templates.*` for the object type
|
||||
6. Wrap in `${template.each(...)}` and drop it into the note
|
||||
|
||||
If the user already described the intent (e.g., "show all proj pages newest first"), skip the questions and just write it.
|
||||
|
||||
## Placing the query
|
||||
|
||||
Queries go directly in the note as Markdown text — no fenced code block needed. The `${...}` syntax renders on Alt-click (or view mode). Drop the expression on its own line for clean rendering.
|
||||
|
||||
If the user wants the query to live in a `space-lua` block as a reusable function rather than an inline expression, wrap it:
|
||||
|
||||
```space-lua
|
||||
function myView()
|
||||
return template.each(query[[
|
||||
from p = index.tag "page"
|
||||
where p.name:startsWith("proj/")
|
||||
order by p.lastModified desc
|
||||
]], templates.pageItem)
|
||||
end
|
||||
```
|
||||
|
||||
Then call it anywhere: `${myView()}`
|
||||
Loading…
Add table
Add a link
Reference in a new issue