cli

cli is a skill for Claude Code, Codex from sparq-org/sparq. It costs 146 tokens per session (9,631 once invoked), scanned A, original, MIT.

A command-line program for loading RDF files, running SPARQL queries, comparing RDF triple sets, building disk-backed indexes, and materializing reasoning results. RDF is a format for representing linked facts; SPARQL is its query language.

In plain words
What is it for?
Use it to query Turtle, N-Triples, N-Quads, TriG, or HDT files, decompress input, compare datasets, build or query memory-mapped indexes, and generate reasoning closures or proofs.
Why use it?
It provides one terminal interface for common graph tasks, including datasets too large to fit in memory and queries that need RDFS, OWL-RL, or N3 reasoning.

Skill for Claude CodeCodex

Part of the sparq plugin — 35 skills, 20 agents, 2 hooks shipped together

Install

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.

agentmods
npx agentmods add skills/sparq-org/sparq/cli
Any agent
npx skills add sparq-org/sparq --skill cli
Clone the repo
git clone --depth 1 https://github.com/sparq-org/sparq

Made for: Claude Code, Codex.

Or install sparq, the plugin that ships this one along with the rest of its 35 skills, 20 agents, 2 hooks.

Wrote 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.

agentmods badge for cli

README.md
[![agentmods](https://agentmods.dev/badge/skills/sparq-org/sparq/cli.svg)](https://agentmods.dev/skills/sparq-org/sparq/cli)
Your own site
<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>
Per session 146 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 9,631 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

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.

ModelPer sessionOnce 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

Measured 3d ago against content hash 48cf8af0b81f, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

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.

skills/cli/SKILL.md · 201 lines

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. --format chooses the serialisation: table (default, a readable fixed-width ASCII table with a (K row(s)) footer), tsv / csv / xml (W3C SPARQL Results, reusing sparq-server's serialisers), or json (SPARQL 1.1 Results JSON, the engine's direct serialiser). ntriples is not meaningful for bindings and falls back to tsv.
    • ASK → a boolean: true / false. --format json / --format xml emit 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; --format is a SELECT/ASK selector and is ignored for the graph forms).
    • --count restores the historical count-only output (<n> solutions in <ms>ms for SELECT/ASK, <n> triples in <ms>ms for the graph forms) — the backward-compatible escape hatch for scripts that scraped the count.
    • An unknown --format value is a usage error (exit 2); a query/runtime error exits 1.
  • diff <file-a> <file-b> [--exact] (opt-in diff feature; [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. --exact is 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; with out.nt, write the full closure as N-Triples. Add --proof (N3 only) to print each derivation step. el needs the opt-in el feature (see classify below); datalog:<rules.dlog> needs the opt-in datalog feature (see the stratified-Datalog example below).
  • classify <data-file> <format> [out.nt] (opt-in el feature; [OPUS-5] sq-2ch27) — run the OWL 2 EL consequence-based classifier (sparq-reason-el) and materialize the class-subsumption lattice as rdfs:subClassOf triples (plus the role-inclusion closure as rdfs:subPropertyOf, since the CLI's el feature also turns on the crate's rbox role automaton). Scope: complete for the E1+E2 fragment, not for OWL 2 EL as a whole — the CLI does not enable the crate's cdomain feature, so concrete-domain axioms (see the skipped_axioms note below) are deferred. Prints the classification report as name<TAB>value lines on stdout — triples, named_classes, emitted_subclassof, emitted_subpropertyof, skipped_axioms, unsatisfiable_classes, thing_unsatisfiable, rbox_non_regular — and with out.nt writes the lattice-augmented graph as N-Triples. Honest incompleteness is reported, never swallowed: a non-zero skipped_axioms means class axioms used a construct this build does not reason over and were not applied — either outside EL entirely (union / complement / allValuesFrom / cardinality / multi-individual oneOf), or in OWL 2 EL but deferred here because the CLI omits cdomain: every concrete-domain axiom (faceted owl:onDatatype/owl:withRestrictions, literal owl:hasValue/owl:oneOf) is skipped, so a valid EL ontology using datatype restrictions can classify to an incomplete hierarchy; rbox_non_regular means 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_millions sets the in-memory run size. Writes RAW perms by default; set SPARQ_BUILD_COMPRESSED=1 to emit block-compressed (SPQCPRM1) perms directly from the merge tail, skipping a later recompress (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 word compressed for block-compressed permutations, and --format-v2 to write those as SPQCPRM2 instead of SPQCPRM1 (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 with query: 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; --count restores the legacy count-only line (<n> solutions/triples in <ms>ms). The only difference from query is the data source — an mmap-backed Graph::open instead of an in-RAM load (permutations stay in the OS page cache, not the process heap). An unknown --format is 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). --v2 writes SPQCPRM2 (see the emit-format note below).
  • Compressed-perm emit format (--format-v2 / --v2; opt-in spqcprm2 feature; [SONNET-4.6] sq-kmve2). A build emits SPQCPRM1 by DEFAULT and the V2 emitter is opt-in (cargo build -p sparq-cli --features spqcprm2); the V2 reader always ships, so a SPQCPRM2 dir opens anywhere. The flag is the per-invocation form of SPARQ_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-v2 without the compressed positional, an unknown --flag, or the flag on a binary built WITHOUT spqcprm2 are all usage errors (exit 2) rather than a silent SPQCPRM1 write. Whether V2 is smaller than V1 is corpus-dependent (it frame-of-reference encodes the col2 reset) — measure on your data; see the data-formats skill.
  • compact <persist-dir>WAL compaction / vacuum for erasure-completeness (sq-x32t). OFFLINE operator command: stop a --persist server, 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 is POST /admin/compact on a running server (see the http-server skill). Honest scope: scrubs the engine's own on-disk segments + dictionary; it cannot reach off-box copies (filesystem snapshots, COW history, external backups) — see compliance/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-formatturtle | 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; bare jsonld == jsonld-expanded, bare jsonld-pretty == jsonld-pretty-expanded; the turtle-pretty/trig-pretty forms emit deterministic, idiomatic Turtle/TriG — sorted, blank-line-separated subject blocks, the engine home for the site's pretty-Turtle reshaper; the jsonld-pretty* forms emit indented JSON-LD — a whitespace-only re-indent of the minified document, so same ordering, same RDF). The writer matrix is sparq-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-on jsonld feature (see "Default cargo features" below). dump also 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-features build drops both the oxjsonld parser and the writer matrix (dump then errors on a jsonld out-format, and a jsonld in-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 *.rq in the dir (sorted) iters times, print TSV <name>\t<rows>\t<min_micros>. Mode default materialize.
  • memstat <data-file> <format> [compressed] ([FABLE-5] sq-7d3dj.32) — load a document and print a deterministic memory-composition breakdown as name<TAB>value lines 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's VmRSS/VmHWM (post-load resident + peak during load; Linux /proc/self/status, 0 elsewhere). Trailing literal compressed (or SPARQ_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 (the mode line says which). The at-scale extension of the CI store_bytes_per_triple metric — driven by scripts/bench/bytes-per-triple.sh (bench id bytes-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 as bench but opens the dataset out-of-core; trailing literal decompress decodes compressed perms to RAM first. Mode default count.
  • scaling <data-file> <format> <queries-dir> [threads=1,2,4,8,…] [iters=3] — parallel-efficiency sweep across rayon pool sizes; TSV subsystem\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-in tabular feature; [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 = --template IRI 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-infer disables); each row typed rdf:type <base><table> (--class <iri|none> overrides). --base defaults to http://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:tableName binds to a CSV by file stem, or explicitly via a <name>=<path> positional). Supports rr: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 other rr: 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 a join-key tuple → parent subjects index, 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 one rr:joinCondition is 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 the rr:defaultGraph constant) 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 to Graph::load_dataset, so GRAPH ?g { … } works. Honest cost: the dataset load is whole-document, so the quad load path buffers the generated N-Quads (--out still 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/--count as in query) 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 id tabular-import-smoke.
  • terse <terse-query | -> (opt-in terse feature; [OPUS-4.8] sq-vczh2) — transpile a terse query (the K:<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's POST /terse/transpile returns). Pass - to read the query from stdin. It does not execute the query — pipe canonical_sparql into query. The K:<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 a PREFIX line. Loud-fail, never a silent guess: an unknown K:<name>, a PREFIX K: collision, or non-conformant input (the silent-rewrite canary) exits 2 with a message on stderr. resolutions is always empty in this build — V("phrase") concept resolution needs the crate's vectors feature (a graph-bound resolver + embedder), a future extension, so a V(...) construct exits 2 rather than guessing (caveat sq-26fdp). Off by default; build with --features terse.

Read the full file on GitHub · 201 lines

Changes

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.

  1. 3d ago First seen · 201 lines · 146 tokens per session scan A 48cf8af0b81f

Subscribe to this mod's changes

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.

Related

Other skills, from other repositories

systematic-debugging

Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes.

obra/superpowers · 21 tokens

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.

obra/superpowers · 37 tokens

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.

microsoft/vscode · 62 tokens

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.

microsoft/vscode · 51 tokens

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.

microsoft/vscode · 53 tokens

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…

microsoft/vscode · 71 tokens