zenith_cli/cli/workspace.rs
1//! Argument types for `zenith workspace` and its subcommands.
2
3use clap::{Args, Subcommand};
4use std::path::PathBuf;
5
6/// Arguments for `zenith workspace`.
7#[derive(Debug, Args)]
8pub struct WorkspaceArgs {
9 #[command(subcommand)]
10 pub command: WorkspaceSub,
11}
12
13/// Subcommands of `zenith workspace`.
14#[derive(Debug, Subcommand)]
15pub enum WorkspaceSub {
16 /// Record, list, and inspect scratch design candidates for a document.
17 ///
18 /// Scratch candidates are content-addressed `.zen` snapshots stored in the
19 /// session data directory alongside the durable version history. Use `new`
20 /// to record a candidate, `list` to enumerate them, and `show` to inspect
21 /// a specific one.
22 Scratch(ScratchArgs),
23
24 /// Transition a scratch candidate's lifecycle status (draft → selected | rejected).
25 Candidate(CandidateArgs),
26
27 /// Promote a selected candidate into a target page of the deliverable document.
28 ///
29 /// Fetches the candidate's stored `.zen` snapshot, deep-copies the source page's
30 /// content into the named target page (suffixing all ids), validates the result,
31 /// and writes the mutated document back in place. The promote is recorded in
32 /// version history. The candidate must have status `selected`; use
33 /// `zenith workspace candidate` to transition it first.
34 Promote(PromoteArgs),
35
36 /// Clean up rejected scratch candidates according to their cleanup policy.
37 ///
38 /// Candidates with `status = rejected` and `cleanup_policy = delete` are
39 /// removed from the scratch index. Their snapshot objects are left in the
40 /// object store for a future GC pass. All other candidates are preserved.
41 Finalize(FinalizeArgs),
42
43 /// Pack a document's entire session store into a portable `.zenithbundle` file.
44 ///
45 /// The bundle is a deterministic, C-free DEFLATE archive containing every
46 /// object, version record, run log, scratch candidate, and metadata file
47 /// for the document. Same store bytes in → same bundle bytes out.
48 Bundle(BundleArgs),
49
50 /// Restore a document's session store from a `.zenithbundle` file.
51 ///
52 /// Extracts the bundle into the default store directory and prints the
53 /// restored doc-id.
54 Unbundle(UnbundleArgs),
55}
56
57/// Arguments for `zenith workspace bundle`.
58#[derive(Debug, Args)]
59#[command(after_help = "EXAMPLE:\n zenith workspace bundle poster.zen --out poster.zenithbundle")]
60pub struct BundleArgs {
61 /// Path to the `.zen` document whose store to bundle.
62 pub doc: PathBuf,
63
64 /// Output path for the `.zenithbundle` file.
65 #[arg(long)]
66 pub out: PathBuf,
67}
68
69/// Arguments for `zenith workspace unbundle`.
70#[derive(Debug, Args)]
71#[command(after_help = "EXAMPLE:\n zenith workspace unbundle poster.zenithbundle")]
72pub struct UnbundleArgs {
73 /// Path to the `.zenithbundle` file to restore.
74 pub bundle: PathBuf,
75}
76
77/// Arguments for `zenith workspace scratch`.
78#[derive(Debug, Args)]
79pub struct ScratchArgs {
80 #[command(subcommand)]
81 pub command: ScratchSub,
82}
83
84/// Subcommands of `zenith workspace scratch`.
85#[derive(Debug, Subcommand)]
86pub enum ScratchSub {
87 /// Record the current `.zen` file as a scratch candidate.
88 New(ScratchNewArgs),
89 /// List all scratch candidates for a document.
90 List(ScratchListArgs),
91 /// Show detail for one scratch candidate.
92 Show(ScratchShowArgs),
93}
94
95/// Arguments for `zenith workspace scratch new`.
96#[derive(Debug, Args)]
97#[command(after_help = "EXAMPLE:\n \
98zenith workspace scratch new poster.zen --page main --status draft --notes \"first pass\"")]
99pub struct ScratchNewArgs {
100 /// Path to the `.zen` document to snapshot.
101 pub doc: PathBuf,
102
103 /// Page id this candidate captures (default: `*` for the whole document).
104 #[arg(long, value_name = "ID")]
105 pub page: Option<String>,
106
107 /// Initial lifecycle status: `draft`, `selected`, or `rejected` (default: `draft`).
108 #[arg(long, default_value = "draft", value_name = "STATUS")]
109 pub status: String,
110
111 /// Free-text notes about this candidate.
112 #[arg(long, value_name = "TEXT")]
113 pub notes: Option<String>,
114
115 /// Target slot or branch to promote this candidate into.
116 #[arg(long, value_name = "TARGET")]
117 pub promotion_target: Option<String>,
118
119 /// Policy tag controlling when this candidate may be cleaned up.
120 #[arg(long, value_name = "POLICY")]
121 pub cleanup_policy: Option<String>,
122
123 /// Workflow role label for this candidate (e.g. `hero`, `fallback`).
124 #[arg(long, value_name = "ROLE")]
125 pub workspace_role: Option<String>,
126}
127
128/// Arguments for `zenith workspace scratch list`.
129#[derive(Debug, Args)]
130pub struct ScratchListArgs {
131 /// Path to the `.zen` document.
132 pub doc: PathBuf,
133
134 /// Emit machine-readable JSON instead of a human-readable listing.
135 #[arg(long)]
136 pub json: bool,
137}
138
139/// Arguments for `zenith workspace scratch show`.
140#[derive(Debug, Args)]
141pub struct ScratchShowArgs {
142 /// Path to the `.zen` document.
143 pub doc: PathBuf,
144
145 /// The candidate id to show (e.g. `cand0`).
146 pub candidate: String,
147
148 /// Emit machine-readable JSON instead of a human-readable summary.
149 #[arg(long)]
150 pub json: bool,
151}
152
153/// Arguments for `zenith workspace promote`.
154#[derive(Debug, Args)]
155#[command(after_help = "EXAMPLE:\n \
156zenith workspace promote poster.zen cand0 --into page.export\n \
157zenith workspace promote poster.zen cand0 --into page.export --id-suffix .v2")]
158pub struct PromoteArgs {
159 /// Path to the deliverable `.zen` document (written in-place).
160 pub doc: PathBuf,
161
162 /// The candidate id to promote (must have status `selected`).
163 pub candidate: String,
164
165 /// Id of the target page in the deliverable document to merge content into.
166 #[arg(long, value_name = "PAGE_ID")]
167 pub into: String,
168
169 /// Suffix appended to every cloned node id to keep them unique (default: `.promoted`).
170 #[arg(long, default_value = ".promoted", value_name = "SUFFIX")]
171 pub id_suffix: String,
172}
173
174/// Arguments for `zenith workspace finalize`.
175#[derive(Debug, Args)]
176#[command(
177 after_help = "EXAMPLE:\n zenith workspace finalize poster.zen\n zenith workspace finalize poster.zen --json"
178)]
179pub struct FinalizeArgs {
180 /// Path to the `.zen` document whose scratch store to finalize.
181 pub doc: PathBuf,
182
183 /// Emit machine-readable JSON instead of a human-readable report.
184 #[arg(long)]
185 pub json: bool,
186}
187
188/// Arguments for `zenith workspace candidate`.
189#[derive(Debug, Args)]
190#[command(after_help = "EXAMPLE:\n zenith workspace candidate poster.zen cand0 selected")]
191pub struct CandidateArgs {
192 /// Path to the `.zen` document.
193 pub doc: PathBuf,
194
195 /// The candidate id to transition (e.g. `cand0`).
196 pub candidate: String,
197
198 /// New lifecycle status: `draft`, `selected`, or `rejected`.
199 pub status: String,
200}