LibTmux.Query.Json
0.0.0-alpha.7
Prefix Reserved
dotnet add package LibTmux.Query.Json --version 0.0.0-alpha.7
NuGet\Install-Package LibTmux.Query.Json -Version 0.0.0-alpha.7
<PackageReference Include="LibTmux.Query.Json" Version="0.0.0-alpha.7" />
<PackageVersion Include="LibTmux.Query.Json" Version="0.0.0-alpha.7" />
<PackageReference Include="LibTmux.Query.Json" />
paket add LibTmux.Query.Json --version 0.0.0-alpha.7
#r "nuget: LibTmux.Query.Json, 0.0.0-alpha.7"
#:package LibTmux.Query.Json@0.0.0-alpha.7
#addin nuget:?package=LibTmux.Query.Json&version=0.0.0-alpha.7&prerelease
#tool nuget:?package=LibTmux.Query.Json&version=0.0.0-alpha.7&prerelease
LibTmux.Query.Json
JSON for LibTmux query documents. The
core library does not reference System.Text.Json, so a caller who does not
want it does not get it.
Alpha. The public API is not settled and can change between prereleases without notice, so pin an exact version.
$ dotnet add package LibTmux.Query.Json --prerelease
When you want this
A query in LibTmux is a document, not a lambda: an expression is translated into a closed AST that can be checked, stored, logged, or sent somewhere else. This package is how that document crosses a process boundary.
Reach for it when a filter is written in one place and evaluated in another — a CLI that takes a filter argument, a service that accepts one over HTTP, a tool that records what it queried.
Use it
A query is written over the objects the library hands back, and becomes a document that travels:
QueryDocument document = QueryExtensions.Translate<Session>(
session => session.Name.StartsWith("build") && session.Attached);
string wire = QueryJson.Serialize(document);
QueryDocument parsed = QueryJson.Deserialize(wire);
// The document that came back means what the one that left meant.
Console.WriteLine(parsed == document);
wire is the versioned document, and it says what it is:
{
"schema": "libtmux.query",
"version": 1,
"target": "session",
"predicate": {
"kind": "and",
"operands": [
{ "kind": "string", "operator": "startsWith", "field": "session_name", "value": "build" },
{ "kind": "comparison", "operator": "equal", "field": "session_attached", "value": true }
]
}
}
The same document filters what you already hold, wherever it was written:
// However this arrived — an argument, a request body, a stored filter.
string received = QueryJson.Serialize(QueryExtensions.Translate<Session>(
session => session.Name.StartsWith("build")));
IReadOnlyList<Session> sessions = await server.GetSessionsAsync(ct);
IReadOnlyList<Session> matched = sessions.Matching(QueryJson.Deserialize(received));
Console.WriteLine(matched.Count);
What reading a document costs
Deserializing applies the limits in QueryJsonLimits.V1 — depth, node count,
string length — so a document that arrived from somewhere else cannot cost more
than a document is allowed to. The schema those limits describe ships in the
package as libtmux-query-v1.schema.json.
Console.WriteLine($"depth {QueryJsonLimits.V1.MaximumDepth}, nodes {QueryJsonLimits.V1.MaximumNodes}");
The field catalog is closed
session_name, session_attached, session_id, session_windows,
window_name, window_id, window_panes, pane_id, pane_command,
client_id, client_name, client_control.
You write these as the properties they are — Session.Name,
Client.IsControlClient — and the wire carries the tmux spelling.
A field outside it throws UnsupportedQueryExpressionException at translation
rather than falling back to filtering in memory, so a document that exists is
one tmux can answer.
Related packages
| Package | Adds |
|---|---|
| LibTmux | The client. Required. |
| LibTmux.Workspace | Sessions from tmuxp YAML |
| LibTmux.Mcp | A Model Context Protocol server, as a .NET tool |
Source, docs and issues: https://github.com/libtmux/libtmux-dotnet
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.0-alpha.7 | 52 | 8/16/2026 |
| 0.0.0-alpha.6 | 47 | 8/16/2026 |
| 0.0.0-alpha.5 | 41 | 8/16/2026 |
| 0.0.0-alpha.4 | 56 | 8/16/2026 |
| 0.0.0-alpha.3 | 50 | 8/16/2026 |
| 0.0.0-alpha.2 | 51 | 8/15/2026 |
| 0.0.0-alpha.1 | 48 | 8/15/2026 |
Alpha. LibTmux.Mcp is a different server: 42 tools across three safety tiers, six tmux:// resources and four workflow prompts, where it had five tools. Every tool answers a typed record with a JSON output schema rather than prose, and the tool names all changed. Nothing polls — tmux_run reports the shell's real exit status, tmux_wait_for_text sleeps on tmux's control-mode stream, and tmux_start_job carries work that outlives one call. Every capture keeps the newest lines and reports what it dropped. Subscriptions and the Tasks extension are served on the current protocol revision. No change to LibTmux itself. The public API is not settled and may change without notice between prereleases; pin an exact version. Full history: https://github.com/libtmux/libtmux-dotnet/blob/master/CHANGELOG.md