1use crate::activity::ActivityStateValue;
2
3use clap::{Args, Command, CommandFactory, Parser, Subcommand};
4
5#[derive(Debug, Parser)]
6#[command(
7 name = "agent-id",
8 version,
9 about = "Portable identity registry for coding-agent sessions",
10 long_about = "agent-id assigns permanent human-readable names to stable agent-harness session IDs."
11)]
12pub struct Cli {
13 #[command(subcommand)]
14 pub command: Commands,
15}
16
17#[derive(Debug, Subcommand)]
18pub enum Commands {
19 Register(RegisterArgs),
21 Lookup(LookupArgs),
23 Current(CurrentArgs),
25 Annotate(AnnotateArgs),
27 Discover(DiscoverArgs),
29 Prune(PruneArgs),
31 Prime(PrimeArgs),
33}
34
35#[derive(Debug, Args)]
36pub struct CurrentArgs {
37 #[arg(long)]
39 pub json: bool,
40}
41
42#[derive(Debug, Args)]
43pub struct RegisterArgs {
44 #[arg(value_name = "SESSION_ID", conflicts_with = "session_id")]
46 pub session: Option<String>,
47
48 #[arg(long = "session-id", value_name = "ID")]
50 pub session_id: Option<String>,
51
52 #[arg(long, value_name = "NAME")]
54 pub family: Option<String>,
55
56 #[arg(long, value_name = "NAME")]
58 pub realm: Option<String>,
59
60 #[arg(long)]
62 pub json: bool,
63}
64
65impl RegisterArgs {
66 pub fn explicit_session(&self) -> Option<&str> {
67 self.session.as_deref().or(self.session_id.as_deref())
68 }
69}
70
71#[derive(Debug, Args)]
72pub struct LookupArgs {
73 #[arg(value_name = "IDENTIFIER", conflicts_with = "session_id")]
75 pub input: Option<String>,
76
77 #[arg(long = "session-id", value_name = "ID")]
79 pub session_id: Option<String>,
80
81 #[arg(long)]
83 pub json: bool,
84}
85
86impl LookupArgs {
87 pub fn explicit_input(&self) -> Option<&str> {
88 self.input.as_deref().or(self.session_id.as_deref())
89 }
90}
91
92#[derive(Debug, Args)]
93pub struct AnnotateArgs {
94 #[arg(value_name = "SESSION_ID", conflicts_with = "session_id")]
96 pub session: Option<String>,
97
98 #[arg(long = "session-id", value_name = "ID")]
100 pub session_id: Option<String>,
101
102 #[arg(long, value_name = "TEXT", conflicts_with = "clear_summary")]
104 pub summary: Option<String>,
105
106 #[arg(long, conflicts_with = "summary")]
108 pub clear_summary: bool,
109
110 #[arg(long, value_name = "VALUE", conflicts_with = "clear_state")]
112 pub state: Option<ActivityStateValue>,
113
114 #[arg(long, conflicts_with = "state")]
116 pub clear_state: bool,
117
118 #[arg(long, value_name = "PATH", conflicts_with = "clear_cwd")]
120 pub cwd: Option<String>,
121
122 #[arg(long, conflicts_with = "cwd")]
124 pub clear_cwd: bool,
125
126 #[arg(long = "extension", value_name = "OWNER=JSON")]
128 pub extensions: Vec<String>,
129
130 #[arg(long = "clear-extension", value_name = "OWNER")]
132 pub clear_extensions: Vec<String>,
133
134 #[arg(long)]
136 pub json: bool,
137}
138
139impl AnnotateArgs {
140 pub fn explicit_session(&self) -> Option<&str> {
141 self.session.as_deref().or(self.session_id.as_deref())
142 }
143}
144
145#[derive(Debug, Args)]
146#[command(
147 about = "Find identity assignments for related work",
148 after_help = "Neighbor selection: prefer an agent whose current work is related to the request. Do not contact arbitrary agents merely because they are idle or discoverable. If no suitable neighbor is apparent, do not broadcast; ask the user or report that no suitable neighbor was found. An explicit recipient chosen by the user takes precedence."
149)]
150pub struct DiscoverArgs {
151 #[arg(long, default_value_t = 20)]
153 pub limit: usize,
154
155 #[arg(long, value_name = "HOURS")]
157 pub recent: Option<i64>,
158
159 #[arg(long, value_name = "NAME")]
161 pub realm: Option<String>,
162
163 #[arg(long)]
165 pub all: bool,
166
167 #[arg(long)]
169 pub json: bool,
170}
171
172#[derive(Debug, Args)]
173pub struct PruneArgs {
174 #[arg(long, value_name = "TIMESTAMP", required = true)]
176 pub before: String,
177
178 #[arg(long)]
180 pub dry_run: bool,
181
182 #[arg(long)]
184 pub json: bool,
185}
186
187#[derive(Debug, Args)]
188#[command(about = "Output the agent-facing identity workflow manual")]
189pub struct PrimeArgs {
190 #[arg(long)]
192 pub prelude: bool,
193
194 #[arg(long)]
196 pub json: bool,
197}
198
199pub fn build_cli() -> Command {
200 Cli::command()
201}