mit einem Klick
writing-hashql-jexpr
// HashQL J-Expr syntax for writing queries. Use when writing J-Expr code, using #literal/#struct/#list constructs, understanding function call syntax, or working with HashQL query files (.jsonc).
// HashQL J-Expr syntax for writing queries. Use when writing J-Expr code, using #literal/#struct/#list constructs, understanding function call syntax, or working with HashQL query files (.jsonc).
Use when creating, moving, splitting, or organizing TypeScript files and folders. Applies fractal tree file-structuring rules which reduce the cognitive overhead of choosing where to put files and ultimately navigating a codebase (once the structure is established and understood).
HashQL testing strategies including compiletest (UI tests), unit tests, and snapshot tests. Use when writing tests for HashQL code, using //~ annotations, running --bless, debugging test failures, or choosing the right testing approach.
Rust documentation practices for HASH codebase. Use when writing doc comments, documenting functions/types/traits/modules, creating error sections, using intra-doc links, or following rustdoc conventions.
HASH error handling patterns using error-stack crate. Use when working with Result types, Report types, defining custom errors, propagating errors with change_context, adding context with attach, implementing Error trait, or documenting error conditions in Rust code.
Guide for creating effective Agent Skills. Use when users want to create a new skill (or update an existing skill) that extends an AI agent's capabilities with specialized knowledge, workflows, or tool integrations. Covers skill structure, YAML frontmatter, trigger configuration, and the 500-line rule.
HashQL diagnostic writing patterns using hashql-diagnostics crate. Use when creating error messages, warnings, Labels, Messages, Severity levels, Patches, Suggestions, or improving diagnostic quality in HashQL code.
| name | writing-hashql-jexpr |
| description | HashQL J-Expr syntax for writing queries. Use when writing J-Expr code, using #literal/#struct/#list constructs, understanding function call syntax, or working with HashQL query files (.jsonc). |
| license | AGPL-3.0 |
| metadata | {"triggers":{"type":"domain","enforcement":"suggest","priority":"high","keywords":["J-Expr","jexpr","hashql query","hashql syntax","#literal","#struct","#list","#tuple"],"intent-patterns":["\\b(write|read|create|parse)\\b.*?\\b(j-?expr|hashql)\\b","\\b(hashql|jexpr)\\b.*?\\b(query|syntax|expression)\\b"]}} |
J-Expr is a JSON-based expression syntax for HashQL. It represents typed expressions using JSON primitives.
J-Expr has three expression types:
| JSON Type | J-Expr Meaning |
|---|---|
| String | Path/identifier/symbol |
| Array | Function call |
| Object | Data constructor (with # keys) |
Strings are parsed as paths or identifiers:
"x" // Simple variable
"vertex.id.entity_id" // Dotted path access
"::core::types::String" // Namespaced/rooted path
"::graph::head::entities" // Graph function path
Arrays represent function calls: [function, arg1, arg2, ...]
// Basic function call
["add", {"#literal": 1}, {"#literal": 2}]
// Namespaced function
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
// Labeled argument with :prefix in object
["greet", {":name": {"#literal": "Alice"}}]
// Shorthand labeled argument (string with :prefix)
["func", ":name"]
Objects with special # keys construct data:
| Key | Purpose | Example |
|---|---|---|
#literal | Primitive values | {"#literal": 42} |
#struct | Named fields | {"#struct": {"x": ...}} |
#list | Variable-size ordered | {"#list": [...]} |
#tuple | Fixed-size ordered | {"#tuple": [...]} |
#dict | Key-value map | {"#dict": {"k": ...}} |
#type | Type annotation | Used with other keys |
{"#literal": 42}
{"#literal": "hello"}
{"#literal": true}
{"#literal": null}
{"#literal": 3.14, "#type": "Float"}
{"#struct": {"name": {"#literal": "Alice"}, "age": {"#literal": 30}}}
{"#struct": {"x": {"#literal": 1}}, "#type": "Point"}
{"#list": [{"#literal": 1}, {"#literal": 2}]}
{"#tuple": [{"#literal": 1}, {"#literal": "text"}]}
{ "#dict": { "key": { "#literal": "value" } } }
["let", "varName", { "#literal": 10 }, ["add", "varName", { "#literal": 5 }]]
["fn", {"#tuple": []}, {"#struct": {"vertex": "_"}}, "_", body_expr]
["if", condition_expr, then_expr, else_expr]
["==", "left", "right"]
[">", {"#literal": 5}, {"#literal": 3}]
#literal for all primitive values (numbers, strings, booleans, null):: prefix for namespaced paths: prefix for labeled arguments#type with other constructors for type annotations{"#literal": ...}#list (variable-size) with #tuple (fixed-size)# prefix for labeled arguments (use :)# keys incorrectly - each object should have one primary # keyEntity query:
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
Filtering with comparison:
[
"filter",
"entities",
[
"fn",
{ "#tuple": [] },
{ "#struct": { "entity": "_" } },
"_",
["==", "entity.draft_id", { "#literal": null }],
],
]
Struct with type:
{ "#struct": { "value": { "#literal": 100 } }, "#type": "Amount" }
if, let, fn, type, use, etc.)#literal, #struct, #tuple, #list, #dict, #type)libs/@local/hashql/syntax-jexpr/src/parser/libs/@local/hashql/syntax-jexpr/src/parser/object/libs/@local/hashql/syntax-jexpr/src/parser/string/type.rs