sesame/
main.rs

1//! Open Sesame CLI — platform orchestration for multi-agent desktop control.
2//!
3//! All subcommands connect to the IPC bus, send a request, wait for a
4//! correlated response, format the output, and exit.
5//!
6//! Exit codes:
7//!   0 — success (or child process exit code for `sesame env`)
8//!   1 — error (daemon unreachable, request failed, etc.)
9//!   2 — timeout waiting for response
10
11mod audit;
12mod cli;
13mod clipboard;
14mod env;
15mod helpers;
16mod init;
17mod input;
18mod ipc;
19mod launch;
20mod profile;
21mod secrets;
22mod snippets;
23mod ssh;
24mod status;
25mod unlock;
26mod wm;
27mod workspace;
28
29use clap::Parser;
30use owo_colors::OwoColorize;
31
32use cli::*;
33
34#[tokio::main(flavor = "current_thread")]
35async fn main() {
36    let cli = Cli::parse();
37
38    if let Err(e) = run(cli).await {
39        eprintln!("{}: {e:#}", "error".red().bold());
40        std::process::exit(1);
41    }
42}
43
44async fn run(cli: Cli) -> anyhow::Result<()> {
45    match cli.command {
46        Command::Init {
47            no_keybinding,
48            wipe_reset_destroy_all_data,
49            org,
50            ssh_key,
51            password,
52            auth_policy,
53        } => {
54            if wipe_reset_destroy_all_data {
55                init::cmd_wipe()
56            } else {
57                init::cmd_init(no_keybinding, org, ssh_key, password, auth_policy).await
58            }
59        }
60        Command::Status => status::cmd_status().await,
61        Command::Unlock { profile } => unlock::cmd_unlock(profile).await,
62        Command::Lock { profile } => unlock::cmd_lock(profile).await,
63        Command::Profile(sub) => match sub {
64            ProfileCmd::List => profile::cmd_profile_list().await,
65            ProfileCmd::Activate { name } => profile::cmd_profile_activate(&name).await,
66            ProfileCmd::Deactivate { name } => profile::cmd_profile_deactivate(&name).await,
67            ProfileCmd::Default { name } => profile::cmd_profile_default(&name).await,
68            ProfileCmd::Show { name } => profile::cmd_profile_show(&name),
69        },
70        Command::Ssh(sub) => match sub {
71            SshCmd::Enroll { profile, ssh_key } => ssh::cmd_ssh_enroll(profile, ssh_key).await,
72            SshCmd::List { profile } => ssh::cmd_ssh_list(profile).await,
73            SshCmd::Revoke { profile } => ssh::cmd_ssh_revoke(profile).await,
74        },
75        Command::Secret(sub) => match sub {
76            SecretCmd::Set { profile, key } => secrets::cmd_secret_set(&profile, &key).await,
77            SecretCmd::Get { profile, key } => secrets::cmd_secret_get(&profile, &key).await,
78            SecretCmd::Delete { profile, key, yes } => {
79                secrets::cmd_secret_delete(&profile, &key, yes).await
80            }
81            SecretCmd::List { profile } => secrets::cmd_secret_list(&profile).await,
82        },
83        Command::Audit(sub) => match sub {
84            AuditCmd::Verify => audit::cmd_audit_verify(),
85            AuditCmd::Tail { count, follow } => audit::cmd_audit_tail(count, follow).await,
86        },
87        Command::Wm(sub) => match sub {
88            WmCmd::List => wm::cmd_wm_list().await,
89            WmCmd::Switch { backward } => wm::cmd_wm_switch(backward).await,
90            WmCmd::Focus { window_id } => wm::cmd_wm_focus(&window_id).await,
91            WmCmd::Overlay { launcher, backward } => wm::cmd_wm_overlay(launcher, backward).await,
92            WmCmd::OverlayResident => wm::cmd_wm_overlay_resident().await,
93        },
94        Command::Launch(sub) => match sub {
95            LaunchCmd::Search {
96                query,
97                max_results,
98                profile,
99            } => launch::cmd_launch_search(&query, max_results, profile.as_deref()).await,
100            LaunchCmd::Run { entry_id, profile } => {
101                launch::cmd_launch_run(&entry_id, profile.as_deref()).await
102            }
103        },
104        Command::Clipboard(sub) => match sub {
105            ClipboardCmd::History { profile, limit } => {
106                clipboard::cmd_clipboard_history(&profile, limit).await
107            }
108            ClipboardCmd::Clear { profile } => clipboard::cmd_clipboard_clear(&profile).await,
109            ClipboardCmd::Get { entry_id } => clipboard::cmd_clipboard_get(&entry_id).await,
110        },
111        Command::Input(sub) => match sub {
112            InputCmd::Layers => input::cmd_input_layers().await,
113            InputCmd::Status => input::cmd_input_status().await,
114        },
115        Command::Snippet(sub) => match sub {
116            SnippetCmd::List { profile } => snippets::cmd_snippet_list(&profile).await,
117            SnippetCmd::Expand { profile, trigger } => {
118                snippets::cmd_snippet_expand(&profile, &trigger).await
119            }
120            SnippetCmd::Add {
121                profile,
122                trigger,
123                template,
124            } => snippets::cmd_snippet_add(&profile, &trigger, &template).await,
125        },
126        #[cfg(all(target_os = "linux", feature = "desktop"))]
127        Command::SetupKeybinding { launcher_key } => {
128            platform_linux::cosmic_keys::setup_keybinding(&launcher_key)
129                .map_err(|e| anyhow::anyhow!("{e}"))
130        }
131        #[cfg(all(target_os = "linux", feature = "desktop"))]
132        Command::RemoveKeybinding => {
133            platform_linux::cosmic_keys::remove_keybinding().map_err(|e| anyhow::anyhow!("{e}"))
134        }
135        #[cfg(all(target_os = "linux", feature = "desktop"))]
136        Command::KeybindingStatus => {
137            platform_linux::cosmic_keys::keybinding_status().map_err(|e| anyhow::anyhow!("{e}"))
138        }
139        Command::Env {
140            profile,
141            prefix,
142            command,
143        } => env::cmd_env(profile.as_deref(), prefix.as_deref(), &command).await,
144        Command::Export {
145            profile,
146            format,
147            prefix,
148        } => env::cmd_export(profile.as_deref(), &format, prefix.as_deref()).await,
149        Command::Workspace(sub) => workspace::cmd_workspace(sub).await,
150    }
151}