From qfs
Use when a task needs to read or modify any external service the user has connected — mail, files, databases, GitHub, Slack, git, cloud storage — via the `qfs` CLI and its pipe-SQL query language. Covers the query syntax and semantics, the describe→preview→commit loop, one-shot execution, and the safety model.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qfs:qfsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
`qfs` exposes every external service as a **filesystem of paths** queried with **one small pipe-SQL
qfs exposes every external service as a filesystem of paths queried with one small pipe-SQL
language. Mail is /mail/inbox, a database table is /sql/pg/orders, a repo's pull requests are
/github/acme/web/pulls, a Drive folder is /drive/Reports, a bucket object is /s3/bucket/key.
The same grammar reads, joins, transforms, and writes across all of them.
Prefer one-shot commands (qfs run '<statement>', qfs describe <path>) — each runs once and
exits, which is what you want as an agent. The interactive shell (qfs with no args) exists but you
generally won't use it.
The repo's docs/ (and qfs skill / qfs skill --examples, printed from the binary) are
authoritative; this skill is the quick operating guide.
qfs, or build it: cd packages/qfs && cargo build --release
→ packages/qfs/target/release/qfs. qfs --version confirms it runs.describe and preview work
offline with no credentials at all. To apply real changes, the user adds an account once:
qfs account add <service> <name> (e.g. qfs account add mail work). Names are safe to print;
the secret is never echoed. qfs account list shows configured accounts.qfs describe <path> — learn the node's archetype, columns, supported verbs, CALL
procedures, and which filters push down. Pure: no creds, no network. Always read this first.qfs run '<statement>' — previews by default: prints the effect-plan (paths, affected
counts, and an irreversible flag) without touching anything.--commit to apply, once the preview looks right.qfs describe /mail/drafts --json # 1: the contract
qfs run "INSERT INTO /mail/drafts VALUES ('[email protected]','Hi','Body')" # 2+3: PREVIEW
qfs run "INSERT INTO /mail/drafts VALUES ('[email protected]','Hi','Body')" --commit # 4: apply
/); there is no working directory in one-shot mode.qfs describe shows them):
SELECT, UPSERT, REMOVESELECT, JOIN, INSERT, UPDATE, UPSERTSELECT (read tail), INSERT (append)SELECT, INSERT, UPDATE, REMOVE, CALL/git/[email protected]/src/main.rs reads as of a ref.SELECT/INSERT/UPSERT/UPDATE/REMOVE are the only verbs. ls/cp/mv/rm are just shell
aliases for them (ls=SELECT listing, cp=UPSERT, rm=REMOVE) — interactive shell only.A statement is a source followed by stages joined by |> (a pipe). Write multi-stage
statements one stage per line:
FROM /sql/pg/orders
|> WHERE total > 100 AND status IN ('open', 'pending')
|> SELECT id, total, status
|> ORDER BY total DESC
|> LIMIT 5
Read/transform stages: WHERE <cond> (=, <>, <, >, <=, >=, LIKE, IN, BETWEEN,
AND/OR), SELECT <cols> (rename with AS), EXTEND <col> = <expr>,
JOIN <path> ON <cond> (works across services), AGGREGATE <fn>(<col>) AS <name> (+ GROUP BY),
ORDER BY <col> [DESC], LIMIT <n>, DISTINCT, and UNION/EXCEPT/INTERSECT FROM <path>.
Effect (write) stages and statements:
INSERT INTO /slack/acme/general/messages VALUES ('Deploy done')
UPSERT INTO /s3/backups/db.sql VALUES ('…bytes…') -- retry-safe write
UPDATE /sql/pg/orders SET status = 'shipped' WHERE id = 7
REMOVE /mail/inbox WHERE subject LIKE '%spam%' -- REMOVE takes a path + WHERE
FROM /github/acme/web/pulls/42 |> CALL github.merge(method => 'squash')
Codecs convert formats — DECODE/ENCODE with json, jsonl, yaml, toml, csv, md:
FROM /local/config.json
|> DECODE json
|> ENCODE yaml
Cross-service join (qfs pushes each side's filters down, then joins locally):
FROM /sql/pg/orders
|> JOIN /github/acme/web/issues ON id = issue_id
|> SELECT id, title
See docs/cookbook/ in the repo for many more recipes.
qfs prints a human table on a TTY and JSON when piped; force it with --json (or
--format json). Parse the JSON rather than scraping the table:
qfs describe /mail/drafts --json | jq '.verbs, .procedures'
qfs run "FROM /sql/pg/orders |> WHERE total > 100 |> SELECT id" --json
A preview's JSON includes preview.rows (each with verb, target, affected, irreversible),
total_affected, and committed: false. After --commit, committed: true.
qfs run previews by default; nothing changes until you pass --commit.CALL mail.send), merging a PR (CALL github.merge),
deleting/trashing (REMOVE) — are flagged irreversible: true in the preview. In a one-shot,
applying them needs both --commit and --commit-irreversible; without the extra flag qfs
refuses (fails closed). Treat these as gates: preview, confirm intent, then commit.UPSERT is the retry-safe default for writes (create-or-replace; re-running converges).# Reversible: --commit is enough
qfs run "INSERT INTO /mail/drafts VALUES ('[email protected]','Hi','Body')" --commit
# Irreversible: needs the explicit ack
qfs run "FROM /mail/drafts |> CALL mail.send" --commit --commit-irreversible
0 = success. Non-zero = failure; the error body goes to stderr as JSON with a kind:
parse (bad syntax), usage (e.g. a relative path), capability (unknown/unsupported
source or verb), auth, internal.capability error on a read often just means no account/backend is connected for that
service yet — the statement's syntax is fine.describe, not in logs, not in errors).cd, no relative paths.REMOVE is REMOVE <path> WHERE …, not a pipe stage.UPDATE on an append log) — it's rejected.CREATE JOB nightly EVERY '1h' DO ….CREATE ENDPOINT|TRIGGER|JOB|VIEW|POLICY) are statements too — preview them to
see the exact plan they'd install before qfs serve runs them.Guides reception of code review feedback: verify before implementing, avoid performative agreement, push back with technical reasoning when needed.
Design banners for social media, ads, website heroes, and print with multiple art direction options and AI-generated visuals.
npx claudepluginhub qmu/qfs --plugin qfs