use clap::{Parser,Subcommand,CommandFactory};
use reedline::{Prompt,Reedline,Signal,PromptHistorySearch,PromptEditMode};
use std::borrow::Cow;
use nexgenomics::utils::{get_api_auth_token,set_api_auth_token};
#[derive(Parser,Debug)]
#[command(name="nexgenomics")]
#[command(version)]
#[command(about="This is the NexGenomics CLI\nCopyright(C) 2026 by NexGenomics Inc.\nAll Rights Reserved\n",long_about=None)]
struct Cli {
#[command(subcommand)]
command:Commands,
}
#[derive(Subcommand,Debug)]
enum Commands {
Hello {
#[arg(short,long)]
name:Option<String>
},
Version,
Quit,
Exit,
#[command(alias="?")]
Commands,
#[command(subcommand)]
Create(Creates),
#[command(about=r#"
**set-auth-token** prompts you for an authentication token, which is
required for various tasks in this command-line utility and in the
NexGenomics REST API.
You must enter the auth token via the prompt. There's no command-line
option that takes it. This enhances security.
Go to https://agentstore.nexgenomics.ai to create an auth token.
The token will be stored on your system at $HOME/.nexgenomicsrc.
"#)]
SetAuthToken(SetAuthTokenArgs),
}
#[derive(Subcommand,Debug)]
enum Creates {
DataConnector {
}
}
#[derive(Parser,Debug)]
struct SetAuthTokenArgs {
#[arg(trailing_var_arg=true)]
args:Vec<String>,
}
struct MyPrompt;
impl Prompt for MyPrompt {
fn render_prompt_left(&self) -> Cow<'_,str> {
Cow::Borrowed("NG> ")
}
fn render_prompt_right(&self) -> Cow<'_,str> {
Cow::Borrowed("")
}
fn render_prompt_indicator(&self, _prompt_mode: PromptEditMode) -> Cow<'_,str> {
Cow::Borrowed("")
}
fn render_prompt_multiline_indicator(&self) -> Cow<'_,str> {
Cow::Borrowed("::: ")
}
fn render_prompt_history_search_indicator(
&self,
_history_search: PromptHistorySearch,
) -> Cow<'_,str> {
Cow::Borrowed("⏳ ")
}
}
fn main() {
let mut line_editor = Reedline::create();
let prompt = MyPrompt;
println!("NexGenomics Shell");
loop {
match line_editor.read_line(&prompt) {
Ok(Signal::Success(line)) => {
let input = line.trim();
let args = std::iter::once("").chain(input.split_whitespace());
match Cli::try_parse_from(args) {
Ok(cli) => {
match cli.command {
Commands::Quit => {
break;
}
Commands::Version => {
let v = env!("CARGO_PKG_VERSION");
println!("{}", v);
}
Commands::Exit => {
break;
}
Commands::Commands => {
let mut c = Cli::command();
let _ = c.print_help();
println!();
}
Commands::SetAuthToken(run_args) => set_auth_token(run_args),
_ => {}
}
}
Err(e) => {
eprintln!("{}",e);
}
}
}
Ok(Signal::CtrlC) | Ok(Signal::CtrlD) => {
break;
}
Err(_err) => {
break;
}
}
}
}
fn set_auth_token(run_args: SetAuthTokenArgs) {
if let Some(token) = get_api_auth_token() {
println!("Token already exists {}", token);
return;
}
if let Some(token) = run_args.args.first() {
match set_api_auth_token(token) {
Ok(()) => println!("✅ Ok"),
Err(err) => eprintln!("❌ Didn't work, {}", err),
}
} else {
println!("❌ No token specified!");
}
}