use std::io::IsTerminal;
use std::sync::OnceLock;
pub mod cli_args;
pub mod commands;
pub mod help;
pub mod render;
pub mod style;
pub mod tips;
pub mod transaction_sentinel;
#[cfg(feature = "weft-client")]
pub use cli_args::PresenceCommands;
#[cfg(feature = "git-overlay")]
pub use cli_args::{BridgeCommands, GitCommands};
#[cfg(feature = "weft-client")]
pub use cli_args::{AuthCommands, SupportCommands};
pub use cli_args::{
ActorCommands, AgentCommands, AttemptArgs, BisectCommands,
CheckpointArgs, Cli, CloneArgs, CollapseArgs, Commands, ContextCommands, DaemonCommands,
DiagnoseArgs, DiffArgs, DoctorArgs, DoctorCommands, DoctorDocsArgs, HookCommands,
HookInstallSource, InitArgs, IntegrationCommands, IntegrationInstallArgs, IntegrationRelayArgs,
IntegrationTargetArgs, LogArgs, MaintenanceCommands, MarkerCommands, MergeArgs, OutputMode,
PullArgs, PurgeApplyArgs, PurgeCommands, PurgeListArgs, PushArgs, ReadyArgs, RedactApplyArgs,
RedactCommands, RedactListArgs, RedactShowArgs, RemoteCommands, ResolveArgs, RetroArgs,
RevertArgs, RunArgs, SessionCommands, SessionEndArgs, SessionListArgs, SessionSegmentArgs,
SessionShowArgs, SessionStartArgs, SnapshotArgs, StashCommands, StoreCommands,
ThreadAbsorbArgs, ThreadCleanupArgs, ThreadCommands, ThreadDropArgs, ThreadListArgs,
ThreadMoveArgs, ThreadNameArgs, ThreadPromoteArgs, ThreadRenameArgs, ThreadResolveArgs,
ThreadShowArgs, ThreadStartArgs, TryArgs, UndoArgs, WatchArgs, WorkspaceCommands,
WorkspaceModeArg, WorkspaceShowArgs,
};
#[cfg(feature = "semantic")]
pub use cli_args::{HotEventKindArg, HotSpotKeyArg, SemanticCommands};
use repo::{Config, OutputFormat};
use crate::config::UserConfig;
pub fn is_tty() -> bool {
std::io::stdout().is_terminal()
}
pub fn load_user_config_or_exit() -> UserConfig {
UserConfig::load_default().unwrap_or_else(|err| {
eprintln!("failed to load Heddle user config: {err}");
std::process::exit(2);
})
}
pub fn should_output_json(cli: &Cli, config: Option<&Config>) -> bool {
let user_config = Some(load_user_config_or_exit());
let mut format = user_config
.as_ref()
.map(|cfg| cfg.output.format)
.or_else(|| config.map(|cfg| cfg.output.format))
.unwrap_or(OutputFormat::Auto);
if let Some(output) = cli.output {
format = match output {
OutputMode::Auto => OutputFormat::Auto,
OutputMode::Json => OutputFormat::Json,
OutputMode::Text => OutputFormat::Text,
};
}
if cli.json {
warn_json_deprecated_once();
format = OutputFormat::Json;
}
match format {
OutputFormat::Json => true,
OutputFormat::Text => false,
OutputFormat::Auto => !is_tty(),
}
}
impl weft_client_shim::CliContext for Cli {
fn repo_path(&self) -> Option<&std::path::Path> {
self.repo.as_deref()
}
fn operation_id_wire(&self) -> String {
crate::operation_id::wire(self)
}
fn should_output_json(&self, repo_config: Option<&Config>) -> bool {
should_output_json(self, repo_config)
}
}
fn warn_json_deprecated_once() {
static WARNED: OnceLock<()> = OnceLock::new();
if WARNED.set(()).is_ok() {
eprintln!("warning: --json is deprecated; use --output json");
}
}
pub fn worktree_status_options(config: Option<&Config>) -> repo::WorktreeStatusOptions {
load_user_config_or_exit().worktree_status_options(config)
}