use std::path::PathBuf;
use clap::{Args, Subcommand};
use serde::Serialize;
use crate::commands::record::RecordProfile;
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingArgs {
#[command(subcommand)]
pub command: TrackingCommand,
}
#[derive(Debug, Clone, Subcommand, Serialize)]
pub enum TrackingCommand {
#[command(
after_help = "State payload replacement policy: this command targets the active payload contract only. Old state payload formats require one-off migration/repair outside the main CLI; no long-term v2 reader or mixed old/new stream reconciliation is provided."
)]
Status(Box<TrackingStatusArgs>),
Run(Box<TrackingRunArgs>),
Checkpoint(Box<TrackingCheckpointArgs>),
#[command(name = "close-ready")]
#[command(
after_help = "State payload replacement policy: this command targets the active payload contract only. Old state payload formats require one-off migration/repair outside the main CLI; no long-term v2 reader or mixed old/new stream reconciliation is provided."
)]
CloseReady(Box<TrackingCloseReadyArgs>),
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingRunArgs {
#[command(subcommand)]
pub command: TrackingRunCommand,
}
#[derive(Debug, Clone, Subcommand, Serialize)]
pub enum TrackingRunCommand {
Init(Box<TrackingRunInitArgs>),
Update(Box<TrackingRunUpdateArgs>),
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingRunInitArgs {
#[arg(long = "provider-repo", value_name = "owner/repo")]
pub provider_repo: String,
#[arg(long, value_name = "number")]
pub issue: u64,
#[arg(long, value_enum, default_value_t = RecordProfile::Tracking)]
pub profile: RecordProfile,
#[arg(long, value_name = "dir")]
pub bundle: Option<PathBuf>,
#[arg(long = "execution-state-file", value_name = "path")]
pub execution_state_file: Option<PathBuf>,
#[arg(long, value_name = "id")]
pub task: Option<String>,
#[arg(long, value_name = "number")]
pub sprint: Option<i32>,
#[arg(long, value_name = "name")]
pub branch: Option<String>,
#[arg(long, value_name = "path")]
pub worktree: Option<PathBuf>,
#[arg(long = "linked-pr", value_name = "ref")]
pub linked_pr: Option<String>,
#[arg(long = "run-id", value_name = "id")]
pub run_id: Option<String>,
#[arg(long = "now", value_name = "rfc3339")]
pub now: Option<String>,
#[arg(long = "out", value_name = "path")]
pub out: Option<PathBuf>,
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingRunUpdateArgs {
#[arg(long = "run-state", value_name = "path")]
pub run_state: PathBuf,
#[arg(long, value_enum)]
pub phase: Option<RunPhaseArg>,
#[arg(long = "selected-task", value_name = "id")]
pub selected_task: Option<String>,
#[arg(long, value_name = "name")]
pub branch: Option<String>,
#[arg(long = "linked-pr", value_name = "ref")]
pub linked_pr: Option<String>,
#[arg(long = "validation-overall", value_name = "status")]
pub validation_overall: Option<String>,
#[arg(long = "validation-command", value_name = "command")]
pub validation_command: Option<String>,
#[arg(long = "validation-status", value_name = "status")]
pub validation_status: Option<String>,
#[arg(long = "validation-evidence", value_name = "path")]
pub validation_evidence: Option<String>,
#[arg(long = "review-decision", value_name = "decision")]
pub review_decision: Option<String>,
#[arg(long, value_name = "text")]
pub note: Option<String>,
#[arg(long = "now", value_name = "rfc3339")]
pub now: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, clap::ValueEnum)]
pub enum RunPhaseArg {
Initial,
Implementing,
Validating,
Reviewing,
Blocked,
ReadyForClose,
Closed,
}
impl RunPhaseArg {
pub fn as_str(self) -> &'static str {
match self {
Self::Initial => "initial",
Self::Implementing => "implementing",
Self::Validating => "validating",
Self::Reviewing => "reviewing",
Self::Blocked => "blocked",
Self::ReadyForClose => "ready_for_close",
Self::Closed => "closed",
}
}
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingCheckpointArgs {
#[arg(long = "provider-repo", value_name = "owner/repo")]
pub provider_repo: Option<String>,
#[arg(long, value_name = "number")]
pub issue: Option<u64>,
#[arg(long, value_enum, default_value_t = RecordProfile::Tracking)]
pub profile: RecordProfile,
#[arg(long = "run-state", value_name = "path")]
pub run_state: PathBuf,
#[arg(long, value_name = "roles", default_value = "state")]
pub post: String,
#[arg(long = "repair-dashboard", default_value_t = false)]
pub repair_dashboard: bool,
#[arg(long, value_name = "dir")]
pub fixture: Option<PathBuf>,
#[arg(long = "body-file", value_name = "path")]
pub body_file: Option<PathBuf>,
#[arg(long = "comments-json", value_name = "path")]
pub comments_json: Option<PathBuf>,
#[arg(long = "live", default_value_t = false)]
pub live: bool,
#[arg(long = "expect-visible", default_value_t = true)]
pub expect_visible: bool,
#[arg(long = "rendered-out", value_name = "dir")]
pub rendered_out: Option<PathBuf>,
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingCloseReadyArgs {
#[arg(long = "provider-repo", value_name = "owner/repo")]
pub provider_repo: Option<String>,
#[arg(long, value_name = "number")]
pub issue: Option<u64>,
#[arg(long, value_enum, default_value_t = RecordProfile::Tracking)]
pub profile: RecordProfile,
#[arg(long = "run-state", value_name = "path")]
pub run_state: Option<PathBuf>,
#[arg(long = "linked-pr", value_name = "ref")]
pub linked_pr: Vec<String>,
#[arg(long, value_name = "text")]
pub approval: Option<String>,
#[arg(long, value_name = "dir")]
pub fixture: Option<PathBuf>,
#[arg(long = "body-file", value_name = "path")]
pub body_file: Option<PathBuf>,
#[arg(long = "comments-json", value_name = "path")]
pub comments_json: Option<PathBuf>,
#[arg(long = "expect-visible", default_value_t = true)]
pub expect_visible: bool,
}
#[derive(Debug, Clone, Args, Serialize)]
pub struct TrackingStatusArgs {
#[arg(long, value_name = "owner/repo")]
pub provider_repo: Option<String>,
#[arg(long, value_name = "number")]
pub issue: Option<u64>,
#[arg(long, value_enum, default_value_t = RecordProfile::Tracking)]
pub profile: RecordProfile,
#[arg(long = "body-file", value_name = "path")]
pub body_file: Option<PathBuf>,
#[arg(long = "comments-json", value_name = "path")]
pub comments_json: Option<PathBuf>,
#[arg(long, value_name = "dir")]
pub fixture: Option<PathBuf>,
#[arg(long = "run-state", value_name = "path")]
pub run_state: Option<PathBuf>,
#[arg(long, value_name = "dir")]
pub bundle: Option<PathBuf>,
#[arg(long = "expect-visible", default_value_t = false)]
pub expect_visible: bool,
}
#[cfg(test)]
mod tests {
use super::RunPhaseArg;
use pretty_assertions::assert_eq;
#[test]
fn run_phase_arg_as_str_matches_wire_contract() {
assert_eq!(RunPhaseArg::Initial.as_str(), "initial");
assert_eq!(RunPhaseArg::Implementing.as_str(), "implementing");
assert_eq!(RunPhaseArg::Validating.as_str(), "validating");
assert_eq!(RunPhaseArg::Reviewing.as_str(), "reviewing");
assert_eq!(RunPhaseArg::Blocked.as_str(), "blocked");
assert_eq!(RunPhaseArg::ReadyForClose.as_str(), "ready_for_close");
assert_eq!(RunPhaseArg::Closed.as_str(), "closed");
}
}