Update SilverBullet skill CLI guidance

Amolith created

Refresh the using-silverbullet skill to prefer current sb CLI patterns
such as get, describe, and query. Keep Lua guidance for page bodies and
edits where the CLI still needs Space Lua, and avoid documenting upgrade
commands.

Change summary

SKILL.md | 188 +++++++++++++++++++++++++--------------------------------
1 file changed, 82 insertions(+), 106 deletions(-)

Detailed changes

SKILL.md πŸ”—

@@ -8,145 +8,121 @@ metadata:
 
 SilverBullet is a self-hosted Markdown note-taking app with a Lua scripting layer. Do not write top-level `# Titles`; SilverBullet puts the page title at the top of the page and `Title\n\n# Title` is redundant.
 
-# CLI
+# Prefer the high-level CLI
 
-`sb` executes Lua _on_ the remote SilverBullet instance. Use `sb --help` to explore available commands.
+`sb` talks to a running SilverBullet instance through the Runtime API. Prefer `get`, `describe`, and `query` before dropping into Lua. Use `sb <command> -h` for full flags and edge cases.
 
-- `sb eval '<expr>'` β€” single expression, prints its return value
-- `sb script` β€” multi-statement script from file (`-f`), inline argument, or stdin; use `return` for output (`print` is swallowed)
-- `sb query '<sliq-expression>'` β€” runs Space Lua Integrated Query directly (wraps in `query[[...]]` for you)
+Most useful commands:
 
-```bash
-# expression
-sb eval 'space.readPage("index")'
-
-# multi-statement via stdin
-echo '
-local text = space.readPage("index")
-text = string.gsub(text, "old", "new")
-space.writePage("index", text)
-return "done"
-' | sb script
-```
-
-# Editing pages with plainReplace
+- `sb space ls`, `sb space add`, `sb space rm <name>` β€” manage saved space connections. Use `-s <name>` to select a space when more than one is configured.
+- `sb get` β€” list indexed tag names in the space.
+- `sb describe [tag]` β€” show query syntax and live schemas, e.g. `sb describe page` or `sb describe task`.
+- `sb get <tag> [ref]` β€” list indexed objects or fetch one object by ref. For pages, the ref is the page name.
+- `sb query '<sliq-expression>'` β€” run Space Lua Integrated Query; this wraps the argument in `query[[...]]`.
+- `sb eval '<expression>'` β€” evaluate one Space Lua expression and print its return value.
+- `sb script [code]`, `sb script -f file.lua`, or stdin β€” run multi-statement Space Lua. The positional argument is inline code, not a filename.
+- `sb logs`, `sb logs -n 20`, `sb logs -f` β€” inspect or follow headless client logs.
 
-`string.gsub` treats the search string as a **Lua pattern**, not plain text. Characters like `-`, `.`, `%`, and so on are magic and silently break replacements. **Always use the `plainReplace` helper** instead of raw `string.gsub` for find/replace on page content:
-
-```lua
-function plainReplace(str, old, new, n)
-  old = old:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")
-  new = new:gsub("%%", "%%%%")
-  if n == nil then
-    return str:gsub(old, new)
-  else
-    return str:gsub(old, new, n)
-  end
-end
-```
+Use `--json` for parseable output, `-o jsonl` for line-oriented pipelines, and `--text` for human-readable output. `--text` is an output format, not β€œpage text”.
 
-Usage: `plainReplace(text, "arm64-v8a", "x86_64", 1)`
+# Common operations
 
-# Space Lua tripwires
+```bash
+# List recent page metadata
+sb get page --sort-by lastModified:desc --limit 10 --select name,lastModified
 
-- Space Lua APIs are camelCase: `space.readPage`, not `space.read_page`.
-- Use `return`; `print()` output is swallowed.
-- Don't chain `:gsub()` calls. `gsub` returns `(string, count)`, so reassign each step.
-- Don't use `query` as a variable or parameter name; it can parse as LIQ syntax.
-- The standard Lua `utf8` library is unavailable.
-- In LIQ, use explicit binding: `from p = ...`.
+# Find pages by name/prefix metadata
+sb get page --where name:contains=meeting --select name,lastModified
+sb get page --where name:startsWith=Journal/ --select name,lastModified
 
-# Operations
+# Fetch one page metadata object. This does NOT return the Markdown body.
+sb get page "Journal/2026-06-07" --json
 
-```bash
-# search (full-text, returns JSON with excerpts/scores/offsets)
-sb eval 'silversearch.search("query", {silent=true})'
+# Read the Markdown body of a page
+sb eval 'space.readPage("Journal/2026-06-07")'
 
-# read
-sb eval 'space.readPage("PageName")'
-sb eval 'space.getPageMeta("PageName")'
+# Full-text search; returns matches with excerpts, scores, and offsets
+sb eval 'silversearch.search("search terms", {silent=true})'
 
-# query the object index (Space Lua Integrated Query)
-sb query 'from p = index.tag "page" order by p.lastModified desc limit 10 select p.name'
+# Tasks: prefer get filters for routine list/filter/sort work
+sb get task --where done=false --sort-by priority:desc --limit 20
+sb get task --where due:lte=2026-06-30 --where done=false
 
-# find pages that link to a specific page
+# Query when get cannot express the relationship
 sb query 'from l = index.tag "link" where l.toPage == "TargetPage" select l.fromPage'
-# also available through eval, but the query wrapper is more convenient when sufficient
-sb eval 'query[[from l = index.tag "link" where l.toPage == "TargetPage" select l.fromPage]]'
+sb query 'from p = index.tag "page" order by p.lastModified desc limit 10 select p.name'
 
-# write / create
-sb eval 'space.writePage("PageName", "# Title\nContent")'
+# Write/create only when asked to change the space
+sb eval 'space.writePage("PageName", "Content without a duplicate top heading")'
 
-# delete
+# Delete only when explicitly asked
 sb eval 'space.deletePage("PageName")'
+```
+
+`sb get` supports `--where`, `-l/--selector`, `--sort-by`, `--limit`, `--offset`, and `--select`; run `sb get -h` rather than memorising every filter operator.
+
+# Editing pages safely
 
-# edit one-liner
-sb eval 'space.writePage("Page", plainReplace(space.readPage("Page"), "typo", "fixed"))'
+`string.gsub` treats the search string as a Lua pattern, not plain text. Characters like `-`, `.`, and `%` are magic and can silently break replacements. Use a helper that returns only the replacement string:
 
-# multiple replacements
-echo '
+```lua
 local function plainReplace(str, old, new, n)
   old = old:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")
   new = new:gsub("%%", "%%%%")
+
+  local replaced
   if n == nil then
-    return str:gsub(old, new)
+    replaced = str:gsub(old, new)
   else
-    return str:gsub(old, new, n)
+    replaced = str:gsub(old, new, n)
   end
+  return replaced
 end
-local text = space.readPage("Title")
-text = plainReplace(text, "mistake one", "correction one", 1) -- specify the replacement limit; you usually want 1
-text = plainReplace(text, "mistake two", "correction two", 1)
-space.writePage("Title", text)
-return "done"
-' | sb script
-
-# writing multi-line Markdown with sb script
-# Use [==[...]==] instead of [[...]] when Markdown contains wiki links
-# or templates. If the content contains ]==], use a regular quoted string
-# with \n escapes or edit existing content with plainReplace instead.
-echo '
-local text = [==[
-Some content with [[wiki links]] and ${template directives}.
-]==]
-space.writePage("PageName", text)
-return "done"
-' | sb script
-
-# If multi-line content ends with ]] immediately before the closing ]==],
-# add a newline before the close and trim it off.
-echo '
-local text = [==[
-Ends with [[Page]]
-]==]:sub(1, -2)
-space.writePage("PageName", text)
-return "done"
-' | sb script
 ```
 
-# Fetching SilverBullet docs
-
-The official SilverBullet instance at `silverbullet.md` serves raw Markdown pages. When you need details on any Space Lua feature, API, or concept, fetch the docs directly:
+Use `sb script` for multi-step edits:
 
 ```bash
-# Fetch a specific docs page (URL-encode spaces and slashes)
-sb eval 'net.readURI("https://silverbullet.md/.fs/Space%20Lua.md")'
-
-# List all docs pages to find what you need
 sb script <<'EOF'
-local result = http.request("https://silverbullet.md/.fs", {
-  headers = { ["X-Sync-Mode"] = "true" }
-})
-local names = {}
-for _, p in ipairs(result.body) do
-  table.insert(names, p.name)
+local function plainReplace(str, old, new, n)
+  old = old:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")
+  new = new:gsub("%%", "%%%%")
+
+  local replaced
+  if n == nil then
+    replaced = str:gsub(old, new)
+  else
+    replaced = str:gsub(old, new, n)
+  end
+  return replaced
 end
-return table.concat(names, "\n")
+
+local text = space.readPage("PageName")
+text = plainReplace(text, "old literal text", "new literal text", 1)
+space.writePage("PageName", text)
+return "done"
 EOF
 ```
 
-URL-encode page names (`%20` for spaces, `%2F` for `/`). The page listing is always current, so no hardcoded index is needed.
+For multi-line Markdown literals, prefer `[==[...]==]` over `[[...]]` so wiki links and templates do not terminate the string accidentally. If the content itself contains `]==]`, use a normal quoted string with `\n` escapes or edit existing content with `plainReplace`.
 
----
+# Space Lua tripwires
+
+- Space Lua APIs are camelCase: `space.readPage`, not `space.read_page`.
+- Use `return`; `print()` output is swallowed.
+- Do not chain `:gsub()` calls. `gsub` returns `(string, count)`, so reassign each step.
+- Do not use `query` as a variable or parameter name; it can parse as SLIQ syntax.
+- The standard Lua `utf8` library is unavailable.
+- In SLIQ, use explicit binding: `from p = ...`.
+- Use current command names: `eval` and `script`. Old `lua`/`lua-script` aliases are hidden compatibility shims.
+
+# SilverBullet docs
+
+The official docs space serves raw Markdown pages. Fetch docs directly when you need detail on Space Lua, SLIQ, or the CLI:
+
+```bash
+curl -fsSL 'https://silverbullet.md/.fs/CLI.md'
+curl -fsSL 'https://silverbullet.md/.fs/Space%20Lua.md'
+```
 
-If `sb` is unavailable when you run it, fetch the contents of https://silverbullet.md/.fs/CLI.md to read the installation instructions yourself and link the user to https://silverbullet.md/CLI so they can read it too. If they use mise.jdx.dev, the line to add to their global config is `"github:silverbulletmd/silverbullet" = "latest"` and the binary they want is `sb`.
+URL-encode page names (`%20` for spaces, `%2F` for `/`). If `sb` is unavailable, read `https://silverbullet.md/.fs/CLI.md` yourself and link the user to `https://silverbullet.md/CLI`.