pub mod dictionary;
pub mod graph;
pub mod ideation;
pub mod knowledge;
pub mod policy;
pub mod references;
pub mod sdk;
pub mod shaping;
pub mod updates;
pub mod workspace;
pub use ideation::{IdeationArtifactKind, SchemaCommand};
use crate::output::OutputFormat;
use camino::Utf8PathBuf;
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Clone, Copy, Debug, Default, ValueEnum)]
pub enum InvocationChannel {
#[default]
Native,
Typescript,
}
#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum PackageManager {
Npm,
Pnpm,
Yarn,
Bun,
Deno,
Nub,
}
#[derive(Clone, Copy, Debug, Default, ValueEnum)]
pub enum SteOnboardingMode {
Agent,
#[default]
Interactive,
}
#[derive(Parser)]
#[command(name = "provenance", version)]
pub struct Cli {
#[arg(long, global = true)]
pub quiet: bool,
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand)]
pub enum Command {
#[command(name = "__cargo-init", hide = true)]
CargoInit {
#[arg(long)]
package: Option<String>,
#[arg(long, value_enum, default_value_t)]
ste_onboarding: SteOnboardingMode,
#[arg(long)]
ste_pdf: Option<Utf8PathBuf>,
},
Init {
#[arg(long)]
path: Utf8PathBuf,
#[arg(long)]
scope: Option<String>,
#[arg(long, requires = "scope")]
path_prefix: Option<Utf8PathBuf>,
#[arg(long)]
disposition_actor_id: Vec<String>,
#[arg(long, conflicts_with = "disposition_actor_id")]
clear_disposition_actors: bool,
#[arg(long, value_enum, default_value_t)]
ste_onboarding: SteOnboardingMode,
#[arg(long)]
ste_pdf: Option<Utf8PathBuf>,
#[arg(long, value_enum, default_value_t, hide = true)]
invocation_channel: InvocationChannel,
#[arg(long, value_enum, hide = true)]
package_manager: Option<PackageManager>,
},
Check {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long)]
strict: bool,
#[arg(long, requires = "strict")]
base: Option<String>,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Docs {
#[command(subcommand)]
command: workspace::DocsCommand,
},
Dictionary {
#[command(subcommand)]
command: dictionary::DictionaryCommand,
},
Wiki {
#[command(subcommand)]
command: workspace::WikiCommand,
},
Review(crate::review::Options),
Materialize {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Sources {
#[command(subcommand)]
command: knowledge::SourcesCommand,
},
Requirements {
#[command(subcommand)]
command: knowledge::RequirementsCommand,
},
GraphReference {
#[command(subcommand)]
command: graph::GraphReferenceCommand,
},
Domains {
#[command(subcommand)]
command: knowledge::DomainsCommand,
},
Boundaries {
#[command(subcommand)]
command: knowledge::BoundariesCommand,
},
Topics {
#[command(subcommand)]
command: shaping::TopicsCommand,
},
Questions {
#[command(subcommand)]
command: shaping::QuestionsCommand,
},
Graph {
requirement_id: String,
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Resolutions {
#[command(subcommand)]
command: policy::ResolutionsCommand,
},
Rules {
#[command(subcommand)]
command: policy::RulesCommand,
},
Traceability {
rule_id: String,
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Gaps {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Thread {
#[command(subcommand)]
command: shaping::ThreadCommand,
},
Contributions {
#[command(subcommand)]
command: ideation::ContributionsCommand,
},
SynthesisPackets {
#[command(subcommand)]
command: ideation::SynthesisPacketsCommand,
},
Proposals {
#[command(subcommand)]
command: ideation::ProposalsCommand,
},
Dispositions {
#[command(subcommand)]
command: ideation::DispositionsCommand,
},
Prime {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Markdown)]
format: OutputFormat,
#[arg(long)]
include_threads: bool,
},
Impact {
id: String,
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long)]
node_type: String,
#[arg(long, default_value_t = 3)]
max_hops: u32,
#[arg(long)]
follow_indirect: bool,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Stale {
base: Option<String>,
head: Option<String>,
#[arg(long, conflicts_with_all = ["base", "head"])]
since: Option<String>,
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long)]
strict: bool,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Health {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Orphans {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Table)]
format: OutputFormat,
},
Coverage {
#[command(subcommand)]
command: workspace::CoverageCommand,
},
Sdk {
#[command(subcommand)]
command: sdk::SdkCommand,
},
SwarmBacktrace {
#[command(subcommand)]
command: ideation::SwarmBacktraceCommand,
},
Skills {
#[command(subcommand)]
command: workspace::SkillsCommand,
},
Schema {
#[command(subcommand)]
command: ideation::SchemaCommand,
},
Validate {
artifact: ideation::IdeationArtifactKind,
#[arg(long)]
input: Utf8PathBuf,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
Export {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
#[arg(long)]
output: Option<Utf8PathBuf>,
},
Import {
#[arg(long, default_value = ".")]
repo: Utf8PathBuf,
#[arg(long, default_value = "default")]
scope: String,
#[arg(long)]
input: Utf8PathBuf,
#[arg(long)]
dry_run: bool,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
MergeJsonl {
base: Utf8PathBuf,
ours: Utf8PathBuf,
theirs: Utf8PathBuf,
#[arg(long)]
output: Option<Utf8PathBuf>,
#[arg(long)]
path: Option<Utf8PathBuf>,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
#[cfg(feature = "dogfood")]
Dogfood {
#[command(subcommand)]
command: DogfoodCommand,
},
}
#[cfg(feature = "dogfood")]
#[derive(Subcommand)]
pub enum DogfoodCommand {
Note {
#[arg(long)]
surface: String,
#[arg(long, value_enum)]
category: DogfoodCategory,
#[arg(long, value_enum)]
severity: DogfoodSeverity,
#[arg(long)]
detail: Option<String>,
#[arg(long)]
suggestion: Option<String>,
summary: String,
},
List {
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
Report {
#[arg(long)]
enrich: Option<Utf8PathBuf>,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
Triage {
#[command(subcommand)]
command: TriageCommand,
},
}
#[cfg(feature = "dogfood")]
#[derive(Subcommand)]
pub enum TriageCommand {
Handle {
id: String,
#[arg(long)]
reason: Option<String>,
},
Reopen {
id: String,
},
List {
#[arg(long, value_enum, default_value_t = TriageFilter::All)]
status: TriageFilter,
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
},
}
#[cfg(feature = "dogfood")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum TriageFilter {
Unhandled,
Handled,
All,
}
#[cfg(feature = "dogfood")]
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
ValueEnum,
serde::Serialize,
serde::Deserialize,
)]
#[serde(rename_all = "kebab-case")]
pub enum DogfoodCategory {
Friction,
Confusion,
Missing,
Bug,
Idea,
}
#[cfg(feature = "dogfood")]
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
ValueEnum,
serde::Serialize,
serde::Deserialize,
)]
#[serde(rename_all = "kebab-case")]
pub enum DogfoodSeverity {
Blocked,
Workaround,
Annoyance,
}