1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser, Debug)]
#[command(
name = "babysit",
version,
about = "Wrap a shell command in a PTY and expose it to external agents via subcommands",
long_about = None,
arg_required_else_help = true,
)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
/// Session selector flag, shared across read/operate subcommands.
///
/// Resolution: --session arg → $BABYSIT_SESSION_ID env → most recently active.
#[derive(clap::Args, Debug, Clone)]
pub struct SessionSel {
/// Session id (defaults to $BABYSIT_SESSION_ID or `latest`)
#[arg(short = 's', long, value_name = "ID")]
pub session: Option<String>,
}
#[derive(Subcommand, Debug)]
pub enum Command {
/// Wrap a shell command in a PTY and expose it via the other subcommands
Run {
/// Session id to assign (default: auto-generated). Must be unique;
/// allowed characters: ASCII letters, digits, `-`, `_`, `.`.
#[arg(long, value_name = "ID")]
id: Option<String>,
/// Run detached: start the command in the background and return
/// immediately. babysit keeps supervising it; query later with
/// `babysit log`/`status`.
#[arg(short = 'd', long)]
detach: bool,
/// Internal: session id handed down by the parent when it re-execs
/// itself to run detached. Not for direct use.
#[arg(long = "detached-id", value_name = "ID", hide = true)]
detached_id: Option<String>,
/// Run with plain pipes instead of a PTY. Programs that detect a
/// non-tty then emit clean, line-oriented output — nicer for log
/// scraping (e.g. by an agent). Disables interactive/TUI rendering.
#[arg(long = "no-tty")]
no_tty: bool,
/// Auto-terminate the command after this long (e.g. 30s, 10m, 2h).
/// A safety valve for unattended runs that may hang.
#[arg(long, value_name = "DUR")]
timeout: Option<String>,
/// The command to wrap, plus its arguments
#[arg(trailing_var_arg = true, allow_hyphen_values = true, num_args = 1..)]
cmd: Vec<String>,
},
/// List all babysit sessions
#[command(alias = "ls")]
List {
#[arg(long)]
json: bool,
},
/// Show status of a session
#[command(aliases = ["st", "info"])]
Status {
#[command(flatten)]
sel: SessionSel,
#[arg(long)]
json: bool,
},
/// Show recent output from the wrapped command
#[command(alias = "logs")]
Log {
#[command(flatten)]
sel: SessionSel,
/// Last N lines (default: full)
#[arg(long)]
tail: Option<usize>,
/// Include raw ANSI escapes (default: stripped)
#[arg(long)]
raw: bool,
},
/// Block until the wrapped command exits, then return its exit code
Wait {
#[command(flatten)]
sel: SessionSel,
/// Give up waiting after this long (e.g. 30s, 10m); exits 124.
#[arg(long, value_name = "DUR")]
timeout: Option<String>,
},
/// Restart the wrapped command
#[command(alias = "r")]
Restart {
#[command(flatten)]
sel: SessionSel,
},
/// Terminate the wrapped command
#[command(alias = "stop")]
Kill {
#[command(flatten)]
sel: SessionSel,
},
/// Send text to the wrapped command's stdin (newline appended)
#[command(alias = "type")]
Send {
#[command(flatten)]
sel: SessionSel,
/// Text to send
text: String,
},
/// Attach your terminal to a session (detach with Ctrl-\ Ctrl-\)
#[command(alias = "a")]
Attach {
#[command(flatten)]
sel: SessionSel,
},
/// Detach any terminal currently attached to a session
Detach {
#[command(flatten)]
sel: SessionSel,
},
/// Delete sessions whose wrapped command has finished or whose owner died
Prune {
/// Print what would be deleted, but don't delete
#[arg(long)]
dry_run: bool,
},
/// Self-update to the latest version
Upgrade,
/// Print shell integration (completions) to eval from your shell rc,
/// e.g. `eval "$(babysit config zsh)"`.
Config {
/// Shell to emit integration for
#[arg(value_enum)]
shell: Shell,
},
}
#[derive(ValueEnum, Debug, Clone, Copy)]
pub enum Shell {
Zsh,
Bash,
}