Skip to main content

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}