Skip to main content

omgbase_surface/
reference.rs

1//! The `query_syntax` text (`spec/surface/README.md` §4: reference prose,
2//! unpinned). A condensed distillation of `docs/query-language.md`.
3
4/// The agent-facing OQX syntax reference the `query_syntax` tool returns.
5pub const QUERY_SYNTAX: &str = r#"# query — OQX syntax reference
6
7The `query` tool takes ONE plain OQX string (+ optional `limit`/`cursor`).
8
9  [select <items>] from <target> [where <pred>] [follow <dest>, … [{ … }]]
10                   [order by <expr> [asc|desc], …] [limit N] [offset N]
11  $repo.<target> count|exists|none|first|single { <block> }     (scalar/one-row form)
12
13CLAUSE ORDER IS FIXED: select, from, where, follow, order by, limit, offset —
14each at most once. Only `select` may drop its keyword, and only as the first
15clause. A predicate is never implicit: blocks filter with `where`
16(`nodes exists { where kind == "md:task" }`).
17
18Results are LEAN hits — {id, path} + whatever `select` projects (or `values`,
19`count`, `exists`, `none`). Hydrate by id via nodes_get / docs_read.
20
21## Targets & field namespaces
22
23`$`-prefixed names are engine intrinsics; BARE identifiers are your content.
24
25docs:    bare identifier = a document PROPERTY (frontmatter + inline, nested via
26         dots); frontmatter.<k> / inline.<k> force a source; entries(frontmatter)
27         is the whole bag; $title, $tags, format; $id, $path, $updated_at, $body,
28         $content_hash; relations nodes, blocks, doc.out / doc.in,
29         doc.out_edges / doc.in_edges. A bare id/path/updated_at/content_hash/
30         body is rejected ("did you mean $x?").
31blocks:  type, text, attrs keys flattened (`checked`); $id, $doc, $path,
32         $ordinal, $depth, $updated_at, $body, $content_hash; doc.<key>;
33         block.children, block.nodes, block.out_edges, section.
34nodes:   kind, name, value, attrs keys flattened; $id, $doc_id, $block_id,
35         $path; doc.<key>, block.<field>; section.blocks, section.children,
36         section.subsections.
37edges:   predicate, provenance, dst_kind, anchor, src_field; $id, $src, $dst,
38         $dst_path, $dst_uri, $src_block, $via, $from_commit; $path and
39         doc.<key> reach the SOURCE document.
40
41## Functions
42
43text("terms") — FTS prune (docs/blocks/nodes). semantic("phrase") — cosine
44score (docs/blocks; needs a provider). Blocks only: under(id),
45under_heading(s), within(doc id | path glob), under_kind(type[, name]),
46yaml_path(p), json_pointer(p), has_anchor(), child_count(), parent_type().
47has_edge(pred[, dst]) on docs and blocks. Free: list, size, has, entries,
48range, refs. Methods: contains, startsWith, endsWith, matches, size, lower,
49upper.
50
51refs(x) — the live documents a property's document references name: x is a
52string, a list or absent; each "/a/b.md", "a/b.md" or "d_…" element resolves
53to that doc's row (paths match $path after one leading "/" is stripped);
54dangling and non-string elements are dropped. Yields docs rows, so it is a
55source, a receiver or a follow destination: `follow refs(before), refs(after)`
56walks a timeline both ways. A HIT IS A STORE ROW: a top-level row that is not
57a doc/block/node/edge fails (filter_invalid) — `follow before` over a list of
58paths reaches the STRINGS; write `follow refs(before)`.
59
60## Directives
61
62<receiver> exists|none|count|collect|first|single { <block> } — nested,
63correlated to the current row; `^name` reads one scope out; `$repo.<target>`
64is an unbounded root scan from any depth. `distinct` dedups by projection;
65`values` returns bare values; `limit`/`offset` bound a block before its
66consumer. `follow <dest>, … { where … frontier … depth N by … }` recurses
67over type-preserving destinations ($depth, $stop, $leaf, $frontier,
68$ordinal): each <dest> is a relation of the current row or a
69`<recv> collect|first|single [distinct] { … }` block re-evaluated per frontier
70row; one step's successors are unioned by identity. Inside the follow-local
71`where` and inside a destination block `^` is the row being expanded (`^^`
72the walk's enclosing scope): `follow doc.in { where before.contains(^$path) }`,
73`follow doc.out, $repo.docs collect { where after.contains(^$path) }`.
74A custom `order by` disables the keyset cursor.
75"#;