1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//! Clap argument definitions for `tet`.
use std::path::PathBuf;
use clap::{Args, Parser, Subcommand, ValueEnum};
use tetration::query::{HistorySettings, QueryOutputFormat};
#[derive(Parser)]
#[command(
name = "tet",
version,
about = "Tetration CLI: JSON queries and format conversion"
)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Summarize a `.tet` file (default: dataset table; footer attrs under rows when present).
/// Use `--json` for full dump; `--metadata` for coordinate label previews.
Info {
/// Path to `.tet` file.
path: PathBuf,
/// Full pretty JSON (superblock, catalog, chunks, history).
#[arg(long)]
json: bool,
/// One-line summary on stdout.
#[arg(short = 'q', long, conflicts_with = "json")]
quiet: bool,
/// All text sections (layout, execution, datasets, chunks, history).
#[arg(long)]
all: bool,
/// Superblock / layout fields.
#[arg(long)]
layout: bool,
/// Per-file execution defaults from the chunk index header.
#[arg(long)]
execution: bool,
/// Dataset catalog table (default when no section flags).
#[arg(long)]
datasets: bool,
/// Chunk index table (`-n` limits rows; `0` = all).
#[arg(long)]
chunks: bool,
/// Convert / provenance footer events (`tet info --history`; not `tet qhist`).
#[arg(long = "history")]
show_footer_history: bool,
/// Max chunk rows when `--chunks` or `--all` (default 32; `0` = all).
#[arg(short = 'n', long, value_name = "N")]
limit: Option<usize>,
/// Case-insensitive substring on dataset name.
#[arg(long)]
dataset: Option<String>,
/// Case-insensitive substring on dataset name, dtype, or footer metadata.
#[arg(long)]
grep: Option<String>,
/// Verbose footer metadata under dataset rows (coordinate label previews).
#[arg(long)]
metadata: bool,
},
/// Run a JSON query (plan, execute, or both).
///
/// Typical flows:
/// tet query q.json -t data.tet
/// tet query q.json -t data.tet -x -q
/// tet query '{"dataset":"f32","mean":[]}' -t data.tet -x
#[command(
visible_alias = "q",
after_help = "QUERY: path to .json / .toml, inline JSON or TOML, or `-` for stdin; omit QUERY to read stdin. \
Leading `{` selects JSON; otherwise TOML. Extension `.json` / `.toml` overrides. \
-x decodes chunks (requires -t). -q is --format quiet; else default full."
)]
Query {
/// Query document: `.json` / `.toml` path, inline JSON/TOML, or `-` for stdin.
#[arg(value_name = "QUERY")]
query: Option<String>,
/// `.tet` file (catalog + optional execute).
#[arg(short = 't', long, value_name = "PATH")]
tet: Option<PathBuf>,
/// Decode planned chunks and attach `execution` (requires `-t`).
#[arg(short = 'x', long, requires = "tet")]
execute: bool,
/// stdout: full, json, stats, plan (`read_plan` only), quiet. Default: full.
#[arg(long, value_enum, default_value_t = QueryStdoutFormat::Full, conflicts_with = "quiet")]
format: QueryStdoutFormat,
/// Shorthand for `--format quiet` (one-line stdout).
#[arg(short = 'q', long, conflicts_with = "format")]
quiet: bool,
/// Sample values in JSON when executing (all dtypes). Default: 64 (full/json), 0 (quiet/stats).
#[arg(long, visible_alias = "preview-f32", value_name = "N")]
preview: Option<usize>,
/// Extra spill directory roots (repeatable; needs `-x` and `-t`).
#[arg(long, requires = "execute", requires = "tet")]
spill_allow: Vec<PathBuf>,
/// Device for tier-A/B reductions: `cpu`, `auto`, `metal`, `cuda`, `cuda:N` (overrides query `execution.device`).
#[arg(long, value_name = "DEVICE", requires = "execute")]
device: Option<String>,
},
/// Verify a `.tet` file (layout, catalog, chunk index, payloads, footer).
Verify {
/// Path to `.tet` file.
path: PathBuf,
/// Pretty JSON report (automation / CI).
#[arg(long)]
json: bool,
/// One-line summary on stdout.
#[arg(short = 'q', long, conflicts_with = "json")]
quiet: bool,
/// After verify, apply safe in-place repairs (see `tet repair`).
#[arg(long)]
repair: bool,
/// Full verify: decode every chunk payload (`tet verify` alone is a quick scan of the first 128 chunks on large files).
#[arg(long)]
deep: bool,
},
/// Plan or apply in-place repairs (default: plan from verify recommendations).
Repair {
/// Path to `.tet` file.
path: PathBuf,
/// Pretty JSON (plan or repair report).
#[arg(long)]
json: bool,
/// Recommendation codes to apply (repeatable).
#[arg(long = "apply", value_name = "CODE")]
apply: Vec<String>,
/// Show what would change without writing the file (with `--apply`).
#[arg(long)]
dry_run: bool,
},
/// Export a `.tet` file to a Zarr v3 directory store.
Export {
/// Source `.tet` file.
input: PathBuf,
/// Destination Zarr v3 directory (must not exist or must be empty).
output: PathBuf,
},
/// Convert HDF5 / `NetCDF` / Zarr v3 directory store into `.tet` (format from input extension or sniff).
Convert {
/// Source array file (`.h5`/`.hdf5`/`.hdf`/`.he2`/`.he5`, `.nc`/`.netcdf`/`.nc4`/`.nc3`/`.cdf`, Zarr v3 directory with root `zarr.json`, or recognizable signature).
input: PathBuf,
/// Destination `.tet` file.
output: PathBuf,
/// Parallel chunk read workers (`0` = host `available_parallelism`, capped at 64).
#[arg(long = "jobs", default_value_t = 0)]
jobs: usize,
},
/// Recent `tet query` log (platform cache; not in `.tet` footer). Default: `list`.
Qhist(QhistArgs),
}
/// `tet qhist` — platform query history (not `tet info --history` footer).
#[derive(Args)]
#[command(
name = "qhist",
visible_alias = "hist",
about = "Recent tet query log (platform cache; not in .tet footer). Default: list"
)]
pub struct QhistArgs {
#[command(subcommand)]
pub cmd: Option<QhistCmd>,
/// Remove the query history file (`list --clear` or bare `tet qhist --clear`).
#[arg(long, global = true)]
pub clear: bool,
}
#[derive(Subcommand)]
pub enum QhistCmd {
/// List recent queries (default). Use `--all` for every retained row.
List {
/// Max rows to print (ignored when `--all` is set).
#[arg(short = 'n', long, default_value_t = HistorySettings::default().cli_query_max)]
limit: usize,
/// Print all retained rows (up to `TET_QUERY_HISTORY_MAX` on disk).
#[arg(long)]
all: bool,
/// Pretty JSON (full entries); default is a compact table.
#[arg(long)]
json: bool,
/// Case-insensitive substring on dataset name.
#[arg(long)]
dataset: Option<String>,
/// Case-insensitive substring on saved `.tet` path.
#[arg(long)]
tet: Option<String>,
/// `x` / `execute` or `p` / `plan` (matches list `mode` column).
#[arg(long, value_name = "x|p")]
mode: Option<String>,
/// Search dataset, tet path, and operation label.
#[arg(long)]
grep: Option<String>,
},
/// Re-run a saved query (`N`: 1 = newest; indices match filtered `list`).
Run {
/// History index (1 = newest).
#[arg(value_name = "N")]
index: usize,
/// Override `.tet` from the saved row.
#[arg(short = 't', long, value_name = "PATH")]
tet: Option<PathBuf>,
/// Force execute (needs `-t` on the row or this flag).
#[arg(short = 'x', long, conflicts_with = "plan")]
execute: bool,
/// Plan only (ignore saved execute).
#[arg(long, conflicts_with = "execute")]
plan: bool,
#[arg(long, value_enum, default_value_t = QueryStdoutFormat::Full, conflicts_with = "quiet")]
format: QueryStdoutFormat,
#[arg(short = 'q', long, conflicts_with = "format")]
quiet: bool,
#[arg(long, visible_alias = "preview-f32", value_name = "N")]
preview: Option<usize>,
#[arg(long)]
spill_allow: Vec<PathBuf>,
/// Same filters as `qhist list` (with positional `N`).
#[arg(long)]
dataset: Option<String>,
#[arg(long, value_name = "PATH")]
tet_filter: Option<String>,
#[arg(long, value_name = "x|p")]
mode: Option<String>,
#[arg(long)]
grep: Option<String>,
},
}
/// How `tet query` prints success on stdout (errors always go to stderr).
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, ValueEnum)]
pub enum QueryStdoutFormat {
/// Pretty JSON of the full `QueryResponse` (default).
#[default]
Full,
/// Compact one-line JSON (scripts, `jq`).
Json,
/// Slim JSON: plan summary + aggregates, no chunk list or preview arrays.
Stats,
/// Slim JSON: catalog + `read_plan` summary only (no chunks, no execution).
Plan,
/// One human-readable line (`dataset=… op=… mean=…`).
Quiet,
/// ASCII tables (summary, plan, aggregates, optional preview sample).
Table,
}
impl From<QueryStdoutFormat> for QueryOutputFormat {
fn from(f: QueryStdoutFormat) -> Self {
match f {
QueryStdoutFormat::Full => Self::Full,
QueryStdoutFormat::Json => Self::Json,
QueryStdoutFormat::Stats => Self::Stats,
QueryStdoutFormat::Plan => Self::Plan,
QueryStdoutFormat::Quiet => Self::Quiet,
QueryStdoutFormat::Table => Self::Table,
}
}
}