Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add skills/sparq-org/sparq/clinpx skills add sparq-org/sparq --skill cligit clone --depth 1 https://github.com/sparq-org/sparqWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/sparq-org/sparq/cli)<a href="https://agentmods.dev/skills/sparq-org/sparq/cli"><img src="https://agentmods.dev/badge/skills/sparq-org/sparq/cli.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00146 | $0.09631 |
| Opus 5 | $0.00073 | $0.04816 |
| Sonnet 5 | $0.00029 | $0.01926 |
| Haiku 4.5 | $0.00015 | $0.00963 |
Grade A, and why
cli scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 201 lines — stays where its author put it; the contents beside it link to each section on GitHub.
sparq-cli
sparq-cli is the command-line front-end to the sparq RDF triplestore + SPARQL engine. It loads RDF files (with transparent gzip/bzip2/zstd decompression), runs SPARQL, builds and queries out-of-core memory-mapped indexes, and materializes reasoning closures (RDFS / OWL-RL / N3).
Argument style (important): the CLI uses a hand-rolled positional parser — there is no clap, no --help, and no GNU-style flags except --reason/--proof, query's --format/--count, and diff's --exact. The first token is the subcommand; the rest are positional and order matters. An unknown/missing subcommand prints a short usage block and exits with code 2.
Quickstart
Run via cargo (the binary is sparq-cli; build with --release — debug builds are far slower):
# Load a Turtle file and run one query — prints the RESULTS (a readable table by default).
cargo run --release -p sparq-cli -- \
query data.ttl turtle 'SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10'
# stderr: loaded N triples in 0.123s (...)
# stdout: a table of the solution bindings + a "(K row(s))" footer
query emits real results by FORM: SELECT → the solution bindings, ASK → a boolean (true/false), CONSTRUCT/DESCRIBE → the resulting triples as N-Triples. Pick the SELECT/ASK serialisation with --format <table|tsv|csv|xml|json|ntriples> (default table); add --count to restore the old count-only line (<n> solutions/triples in <ms>ms). See the query entry under Key APIs for the full matrix.
format is one of turtle | ntriples | nquads | trig (aliases: n-triples, n-quads, application/trig). nquads/trig are loaded as a dataset so GRAPH {} works. Compressed inputs are auto-detected by extension (.gz, .bz2, .zst/.zstd) and streamed.
Key APIs (subcommands)
All invoked as sparq-cli <subcommand> <args...>:
query <data-file> <format> <sparql> [--format <out>] [--count] [--reason <rdfs|owl|n3|el|datalog:<rules.dlog>>]— load file, run one query, print its results to stdout, dispatched by query form:- SELECT → the solution bindings.
--formatchooses the serialisation:table(default, a readable fixed-width ASCII table with a(K row(s))footer),tsv/csv/xml(W3C SPARQL Results, reusingsparq-server's serialisers), orjson(SPARQL 1.1 Results JSON, the engine's direct serialiser).ntriplesis not meaningful for bindings and falls back totsv. - ASK → a boolean:
true/false.--format json/--format xmlemit the W3C boolean documents ({"head":{},"boolean":…}/<sparql>…<boolean>…</boolean></sparql>); other formats print the bare token. - CONSTRUCT / DESCRIBE → the resulting triples serialised as N-Triples (always;
--formatis a SELECT/ASK selector and is ignored for the graph forms). --countrestores the historical count-only output (<n> solutions in <ms>msfor SELECT/ASK,<n> triples in <ms>msfor the graph forms) — the backward-compatible escape hatch for scripts that scraped the count.- An unknown
--formatvalue is a usage error (exit 2); a query/runtime error exits 1.
- SELECT → the solution bindings.
diff <file-a> <file-b> [--exact](opt-indifffeature; [GPT-5.6] sq-lsp7k.28) — auto-detect each RDF format from.nt,.ttl,.nq,.trig, or.jsonld(before an optional compression extension), compare the documents as triple sets, and emit a deterministic N-Triples patch. Lines prefixed by-form the first lexicographically sorted block; lines prefixed by+form the second. Exit 0 means identical sets and empty stdout; exit 1 means different sets. Named-graph names are discarded, duplicate triples collapse, and blank-node labels compare exactly as loaded.--exactis currently a compatibility alias for that same behavior.reason <data-file> <format> <rdfs|owl|n3|el|datalog:<rules.dlog>> [out.nt]— materialize the entailed closure; print closure triple count; without.nt, write the full closure as N-Triples. Add--proof(N3 only) to print each derivation step.elneeds the opt-inelfeature (seeclassifybelow);datalog:<rules.dlog>needs the opt-indatalogfeature (see the stratified-Datalog example below).classify <data-file> <format> [out.nt](opt-inelfeature; [OPUS-5] sq-2ch27) — run the OWL 2 EL consequence-based classifier (sparq-reason-el) and materialize the class-subsumption lattice asrdfs:subClassOftriples (plus the role-inclusion closure asrdfs:subPropertyOf, since the CLI'selfeature also turns on the crate'srboxrole automaton). Scope: complete for the E1+E2 fragment, not for OWL 2 EL as a whole — the CLI does not enable the crate'scdomainfeature, so concrete-domain axioms (see theskipped_axiomsnote below) are deferred. Prints the classification report asname<TAB>valuelines on stdout —triples,named_classes,emitted_subclassof,emitted_subpropertyof,skipped_axioms,unsatisfiable_classes,thing_unsatisfiable,rbox_non_regular— and without.ntwrites the lattice-augmented graph as N-Triples. Honest incompleteness is reported, never swallowed: a non-zeroskipped_axiomsmeans class axioms used a construct this build does not reason over and were not applied — either outside EL entirely (union / complement / allValuesFrom / cardinality / multi-individualoneOf), or in OWL 2 EL but deferred here because the CLI omitscdomain: every concrete-domain axiom (facetedowl:onDatatype/owl:withRestrictions, literalowl:hasValue/owl:oneOf) is skipped, so a valid EL ontology using datatype restrictions can classify to an incomplete hierarchy;rbox_non_regularmeans the told RBox has a property-chain cycle, so derivations stay sound but the completeness argument does not hold. Both also print an explanatory NOTE on stderr.build <file[.gz|.bz2|.zst]> <format> <dir> [chunk_millions=16]— EXTERNAL-MEMORY build: stream the (compressed) document straight to on-disk memory-mapped indexes via disk-backed sort/merge. For datasets whose indexes exceed RAM.chunk_millionssets the in-memory run size. Writes RAW perms by default; setSPARQ_BUILD_COMPRESSED=1to emit block-compressed (SPQCPRM1) perms directly from the merge tail, skipping a laterrecompress(byte-identical to build-then-recompress).save <data-file> <format> <dir> [compressed] [--format-v2]— load into RAM then persist the six permutation indexes to<dir>. Add the literal wordcompressedfor block-compressed permutations, and--format-v2to write those asSPQCPRM2instead ofSPQCPRM1(see the emit-format note below).query-mmap <dir> <sparql> [--format <out>] [--count]— open a saved/built dir with indexes MEMORY-MAPPED (out-of-core) and run a query, printing its results. Output is at parity withquery: SELECT → bindings (default a readable table;--format <table|tsv|csv|xml|json|ntriples>selects the serialisation), ASK → a boolean (--format json|xml→ the W3C boolean documents), CONSTRUCT/DESCRIBE → the resulting triples as N-Triples;--countrestores the legacy count-only line (<n> solutions/triples in <ms>ms). The only difference fromqueryis the data source — an mmap-backedGraph::openinstead of an in-RAM load (permutations stay in the OS page cache, not the process heap). An unknown--formatis a usage error (exit 2); a query/runtime error exits 1.recompress <src-dir> <dst-dir> [--v2]— re-persist a saved dir with block-compressed permutations without re-parsing (dirs must differ).--v2writesSPQCPRM2(see the emit-format note below).- Compressed-perm emit format (
--format-v2/--v2; opt-inspqcprm2feature; [SONNET-4.6] sq-kmve2). A build emitsSPQCPRM1by DEFAULT and the V2 emitter is opt-in (cargo build -p sparq-cli --features spqcprm2); the V2 reader always ships, so aSPQCPRM2dir opens anywhere. The flag is the per-invocation form ofSPARQ_EMIT_FORMAT=v2— same effect, no env var to leak into child processes — and takes precedence over that variable, which still works unchanged. Fail-closed:--format-v2without thecompressedpositional, an unknown--flag, or the flag on a binary built WITHOUTspqcprm2are all usage errors (exit 2) rather than a silentSPQCPRM1write. Whether V2 is smaller than V1 is corpus-dependent (it frame-of-reference encodes the col2 reset) — measure on your data; see thedata-formatsskill. compact <persist-dir>— WAL compaction / vacuum for erasure-completeness (sq-x32t). OFFLINE operator command: stop a--persistserver, run this on its directory, restart. Opens the dir (replaying its WAL into the live overlay), then physically rewrites the store to only the current live triples with a re-interned (purged) dictionary, and atomically swaps the directory (rollback-safe two-rename + WAL truncate; an interrupted swap is healed on the next open). So a logically-DELETEd /DROPped triple's data — including an orphaned literal value — is gone from disk, not just hidden. The live triple set is preserved exactly (round-trip). The online equivalent isPOST /admin/compacton a running server (see thehttp-serverskill). Honest scope: scrubs the engine's own on-disk segments + dictionary; it cannot reach off-box copies (filesystem snapshots, COW history, external backups) — seecompliance/privacy/retention-erasure-runbook.md§7a/§7b.dump <file[.gz|.bz2|.zst]> <in-format> <out-format>— load an RDF document and re-serialize the whole graph (default + named graphs) to stdout in the RDF writer matrix.out-format∈turtle | turtle-pretty | trig | trig-pretty | nquads | ntriples | jsonld[-expanded|-flattened|-compacted] | jsonld-pretty[-expanded|-flattened|-compacted](Turtle emits the default graph only; trig/nquads/jsonld emit the full dataset; barejsonld==jsonld-expanded, barejsonld-pretty==jsonld-pretty-expanded; theturtle-pretty/trig-prettyforms emit deterministic, idiomatic Turtle/TriG — sorted, blank-line-separated subject blocks, the engine home for the site's pretty-Turtle reshaper; thejsonld-pretty*forms emit indented JSON-LD — a whitespace-only re-indent of the minified document, so same ordering, same RDF). The writer matrix issparq-engine/serialize-rdf(zero new deps — the JSON-LD writer is a native, hand-rolled emitter with no json-ld/serde crate), pulled into the default build by the default-onjsonldfeature (see "Default cargo features" below).dumpalso reads a JSON-LD<in-format>(jsonld/json-ld/application/ld+json) in the default build — JSON-LD is default-on ([OPUS-4.8] sq-oy1f.4). A--no-default-featuresbuild drops both theoxjsonldparser and the writer matrix (dumpthen errors on ajsonldout-format, and ajsonldin-format → exit 2). Unknown out-format → exit 2.ingest <file[.gz|.bz2|.zst]> [parse|intern|full] [max_millions]— streaming-throughput experiment over N-Triples:parse(decompress+parse+count),intern(+dictionary),full(+build indexes). Reports triples/s.bench <data-file> <format> <queries-dir> [iters=5] [count|materialize|json]— load once, run every*.rqin the dir (sorted)iterstimes, print TSV<name>\t<rows>\t<min_micros>. Mode defaultmaterialize.memstat <data-file> <format> [compressed]([FABLE-5] sq-7d3dj.32) — load a document and print a deterministic memory-composition breakdown asname<TAB>valuelines on stdout: triple/term counts, the self-accounted heap total decomposed into dictionary / six-permutation store / numeric+temporal caches (bytes and B-per-triple, plus dict B-per-term), and the kernel'sVmRSS/VmHWM(post-load resident + peak during load; Linux/proc/self/status,0elsewhere). Trailing literalcompressed(orSPARQ_STORE_PROFILE=compressed, OR'd, applied once) re-encodes into the memory-bound in-RAM mode (Graph::into_compressed: block-compressed permutations + blob dictionary) before reporting, so both in-memory framings come from one instrument (themodeline says which). The at-scale extension of the CIstore_bytes_per_triplemetric — driven byscripts/bench/bytes-per-triple.sh(bench idbytes-per-triple) for the in-memory-vs-external bytes/triple envelope. Numbers are host-reported and non-canonical off the dedicated bench box; never commit them into docs.bench-mmap <index-dir> <queries-dir> [iters=5] [count|materialize|json] [decompress]— same asbenchbut opens the dataset out-of-core; trailing literaldecompressdecodes compressed perms to RAM first. Mode defaultcount.scaling <data-file> <format> <queries-dir> [threads=1,2,4,8,…] [iters=3]— parallel-efficiency sweep across rayon pool sizes; TSVsubsystem\tthreads\tbest_ms\tspeedup\tefficiency.probe-compress <perm-file>/compare-compress <data-file> <format> [<sparql>]/bench-remap [n] [dict] [iters]— measurement/instrumentation probes.tabular <csv[.gz|.zst|.bz2]> [<name>=<csv> …] [flags](opt-intabularfeature; [FABLE-5] sq-lsp7k.8) — materializing tabular→RDF import, streaming end-to-end (CSV rows → first-party RFC-4180 reader → per-row N-Triples chunks → the parallel NT ingest; no whole-file buffering; compressed inputs auto-detected by extension). Two modes:- Direct mapping (default): subject =
--templateIRI template with{col}+{_row}(1-based data-row number) placeholders, default<base><table>/row/{_row}; predicate =<base><table>#<column>; object = the cell with datatype inference (xsd:integer/xsd:decimal/xsd:double/xsd:boolean, else plain string;--no-inferdisables); each row typedrdf:type <base><table>(--class <iri|none>overrides).--basedefaults tohttp://example.com/; table = file stem; template-substituted values are IRI-safe percent-encoded. An EMPTY cell is NULL → no triple (a NULL in the subject template skips the row). - R2RML (
--mapping <r2rml.ttl>): the materializing subset over CSV logical tables (rr:tableNamebinds to a CSV by file stem, or explicitly via a<name>=<path>positional). Supportsrr:subjectMap/rr:subject,rr:class,rr:predicateObjectMap,rr:predicateMap/rr:predicate,rr:objectMap/rr:object,rr:template/rr:column/rr:constant,rr:termType(IRI/Literal/BlankNode),rr:datatype,rr:language, plus cross-CSV joins and named graphs ([OPUS-5] sq-u1z86, below). Fail-closed: any otherrr:construct —rr:sqlQuery,rr:sqlVersion,rr:inverseExpression— is a loud exit-1 error, never a silent skip; SQL-connection R2RML stays a non-goal (sparq's counter-story is materializing import, not virtualization). No datatype inference here (CSV's natural datatype is string, per the spec). - Joins (
rr:parentTriplesMap+rr:joinCondition/rr:child/rr:parent; [OPUS-5] sq-u1z86): a referencing object map runs as a keyed hash join — the parent CSV is pre-scanned once into ajoin-key tuple → parent subjectsindex, then the child table streams past it. Honest cost: that index is the one non-constant-memory part of the pipeline (one key tuple + subject per parent row); the child side still streams. SQL NULL semantics: an empty join cell on either side matches nothing. At least onerr:joinConditionis required — R2RML's condition-free (cross-join) form is a loud error, not a guess. - Named graphs (
rr:graphMap/rr:graph; [OPUS-5] sq-u1z86): a graph map on the subject map scopes that triples map's class + predicate-object triples, one on a predicate-object map scopes its own, and the two sets union; an empty set (or therr:defaultGraphconstant) is the default graph. A graph map that generates NULL contributes nothing to that union rather than erasing it — a sibling graph map, or the other side of the subject/predicate-object union, still scopes the statement; only when every declared graph map is NULL is the statement unscoped and dropped (never a silent fallback into the default graph). Using any graph map switches the emitter to N-Quads and the load path toGraph::load_dataset, soGRAPH ?g { … }works. Honest cost: the dataset load is whole-document, so the quad load path buffers the generated N-Quads (--outstill streams); a graph-map-free mapping keeps the unchanged streaming N-Triples fast path. - Row provenance (
--row-provenance, both modes; [OPUS-5] sq-u1z86): every generated subject also gets<subject> prov:wasDerivedFrom <base><table>/row/{_row}>— the same row IRI the direct mapping's default subject template produces, emitted into the row's graph(s). With the default direct-mapping template the subject is the row IRI, so the triple is a self-link; it earns its keep under--template/ R2RML subjects. - Output: default = load the graph and print the summary line; add
--query <sparql>(+--format/--countas inquery) to query it in the same shot; or--out <file.nt|.nq[.gz|.zst]>to stream the triples/quads out without building a graph.--sep <char|tab>sets the separator. Usage errors exit 2; data/mapping errors exit 1. Fixture suite:crates/sparq-cli/tests/fixtures/r2rml/(W3C-R2RML-adapted cases, incl.join/); perf smoke: bench idtabular-import-smoke.
- Direct mapping (default): subject =
terse <terse-query | ->(opt-intersefeature; [OPUS-4.8] sq-vczh2) — transpile a terse query (theK:<name>keyword layer over canonical SPARQL) into the canonical, conformant SPARQL it expands to, printing the verifiable JSON contract{ "canonical_sparql", "keywords": [{ "keyword", "iri", "legendVersion" }], "resolutions": [], "warnings": [], "legendVersion" }(the SAME shape the server'sPOST /terse/transpilereturns). Pass-to read the query from stdin. It does not execute the query — pipecanonical_sparqlintoquery. TheK:<name>legend maps the hot PKG predicates/classes (e.g.K:derivedFrom→<http://www.w3.org/ns/prov#wasDerivedFrom>) so an agent need not emit aPREFIXline. Loud-fail, never a silent guess: an unknownK:<name>, aPREFIX K:collision, or non-conformant input (the silent-rewrite canary) exits 2 with a message on stderr.resolutionsis always empty in this build —V("phrase")concept resolution needs the crate'svectorsfeature (a graph-bound resolver + embedder), a future extension, so aV(...)construct exits 2 rather than guessing (caveatsq-26fdp). Off by default; build with--features terse.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 3d ago First seen · 201 lines · 146 tokens per session scan A 48cf8af0b81f
cli is a skill published in the GitHub repository sparq-org/sparq (10 stars, last pushed today), licensed MIT. It adds 146 tokens to every session and 9,631 once invoked, about $0.0007 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
systematic-debugging
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
auto-perf-optimize
Run agent-driven VS Code performance or memory investigations. Use when asked to launch Code OSS, automate a VS Code scenario, run the Chat memory smoke runner, capture renderer heap snapshots, take workflow screenshots, compare run summaries, or drive a repeatable scenario before heap-snapshot analysis.
chat-perf
Run chat perf benchmarks and memory leak checks against the local dev build or any published VS Code version. Use when investigating chat rendering regressions, validating perf-sensitive changes to chat UI, or checking for memory leaks in the chat response pipeline.
chat-pet-sprite-creation
Use when creating or changing VS Code chat pet sprite art, sprite sheets, state animations, eye treatments, Stable/Insiders variants, or pet transitions under src/vs/workbench/contrib/chat/browser/widget/media/chatPet.
cpu-profile-analysis
Analyze V8/Chrome CPU profiles (.cpuprofile) and DevTools trace files (Trace-.json). Use when: profiling performance, investigating slow functions, comparing code paths, finding bottlenecks, analyzing timeToRequest, understanding call trees from sampling profiler data, analyzing layout/paint/rendering, investigating…