pocket_cli/cli/
mod.rs

1use clap::{Parser, Subcommand, Args, ArgAction};
2use std::path::PathBuf;
3
4pub mod handler;
5
6#[derive(Parser)]
7#[command(
8    name = "pocket",
9    about = "A CLI tool for saving, organizing, and retrieving code snippets with integrated version control",
10    version = env!("CARGO_PKG_VERSION"),
11    author
12)]
13pub struct Cli {
14    /// Enable verbose output
15    #[arg(short, long, action = ArgAction::Count, global = true)]
16    pub verbose: u8,
17
18    /// Command to execute
19    #[command(subcommand)]
20    pub command: Commands,
21}
22
23#[derive(Subcommand)]
24pub enum Commands {
25    #[command(about = "Snippet Management Commands")]
26    #[command(visible_alias = "snippet")]
27    /// Add content to your pocket storage
28    Add {
29        /// Path to the file to add
30        #[arg(value_name = "FILE")]
31        file: Option<String>,
32
33        /// Specify text directly
34        #[arg(short, long, value_name = "TEXT")]
35        message: Option<String>,
36
37        /// Open editor to compose the snippet
38        #[arg(short, long)]
39        editor: bool,
40
41        /// Store in a specific backpack
42        #[arg(short, long, value_name = "NAME")]
43        backpack: Option<String>,
44
45        /// Get content from clipboard
46        #[arg(long)]
47        clipboard: bool,
48
49        /// Generate a summary using LLM
50        #[arg(short, long, value_name = "MODEL")]
51        summarize: Option<String>,
52    },
53
54    #[command(about = "Display all pocket entries")]
55    /// List all snippets in your pocket storage
56    List {
57        /// Display entries from all backpacks
58        #[arg(short = 'a', long)]
59        all: bool,
60
61        /// Specific backpack to list from
62        #[arg(short, long, value_name = "NAME")]
63        backpack: Option<String>,
64
65        /// Output as JSON
66        #[arg(long)]
67        json: bool,
68
69        /// Limit number of entries to display
70        #[arg(short, long, value_name = "N", default_value = "10")]
71        limit: usize,
72    },
73
74    #[command(about = "Remove an entry from storage")]
75    /// Remove a snippet from your pocket storage
76    Remove {
77        /// ID of the entry to remove
78        id: String,
79
80        /// Don't ask for confirmation
81        #[arg(short, long)]
82        force: bool,
83
84        /// Backpack the entry is in
85        #[arg(short, long, value_name = "NAME")]
86        backpack: Option<String>,
87    },
88
89    #[command(about = "Create a new backpack for organizing entries")]
90    /// Create a new backpack for organizing entries
91    Create {
92        /// Name of the backpack
93        name: String,
94
95        /// Description of the backpack
96        #[arg(short, long, value_name = "TEXT")]
97        description: Option<String>,
98    },
99
100    #[command(about = "Find entries across all backpacks with powerful search algorithms")]
101    /// Search for entries in your pocket storage
102    Search {
103        /// Search query
104        query: String,
105
106        /// Maximum results to return
107        #[arg(short, long, value_name = "N", default_value = "10")]
108        limit: usize,
109
110        /// Search in a specific backpack
111        #[arg(short, long, value_name = "NAME")]
112        backpack: Option<String>,
113
114        /// Use exact matching instead of semantic search
115        #[arg(long)]
116        exact: bool,
117
118        /// Search for packages instead of entries
119        #[arg(short, long)]
120        package: bool,
121    },
122
123    #[command(about = "Insert an entry into a file")]
124    /// Insert a snippet into a file
125    Insert {
126        /// ID of the entry to insert
127        id: Option<String>,
128
129        /// Path to the file to insert into
130        file: Option<String>,
131
132        /// Use the most recent entry
133        #[arg(short, long)]
134        top: bool,
135
136        /// Don't ask for confirmation
137        #[arg(short = 'f', long)]
138        no_confirm: bool,
139
140        /// Custom delimiter to use when inserting
141        #[arg(short, long, value_name = "TEXT")]
142        delimiter: Option<String>,
143    },
144
145    #[command(about = "Reload all extensions")]
146    /// Reload all extensions and cards
147    Reload,
148
149    #[command(about = "Display help information")]
150    /// Show help information for commands and extensions
151    ShowHelp {
152        /// Command to show help for
153        command: Option<String>,
154
155        /// List all available extensions
156        #[arg(short, long)]
157        extensions: bool,
158    },
159
160    #[command(about = "Create and execute command chains")]
161    /// Lint code before adding to pocket storage
162    Lint {
163        /// Optional workflow to run
164        workflow: Option<String>,
165    },
166
167    #[command(about = "Remove a saved workflow")]
168    /// Delete a saved workflow
169    DeleteWorkflow {
170        /// Name of the workflow to delete
171        name: String,
172    },
173
174    #[command(about = "Display version information")]
175    /// Show version information
176    Version,
177
178    #[command(about = "Edit an existing entry")]
179    /// Edit a snippet in your pocket storage
180    Edit {
181        /// ID of the entry to edit
182        id: String,
183
184        /// Don't ask for confirmation before saving
185        #[arg(short, long)]
186        force: bool,
187
188        /// Backpack the entry is in
189        #[arg(short, long, value_name = "NAME")]
190        backpack: Option<String>,
191    },
192
193    #[command(about = "Execute a script")]
194    /// Execute a saved script
195    Execute {
196        /// Name of the script to execute
197        name: String,
198
199        /// Arguments to pass to the script
200        args: Vec<String>,
201    },
202
203    #[command(about = "๐Ÿ”Œ Manage cards")]
204    /// Manage cards (extensions)
205    Cards {
206        #[command(subcommand)]
207        operation: Option<CardOperation>,
208    },
209
210    #[command(about = "๐Ÿงช Blend shell scripts into your shell configuration")]
211    /// Blend shell scripts into your shell environment
212    Blend {
213        /// Path to shell script file to blend into shell configuration
214        script_file: Option<String>,
215
216        /// Create as an executable hook command (accessible with @name)
217        #[arg(short, long)]
218        executable: bool,
219
220        #[command(subcommand)]
221        command: Option<BlendCommands>,
222    },
223}
224
225#[derive(Subcommand)]
226pub enum CardOperation {
227    /// List all available cards
228    List {
229        /// Show detailed information
230        #[arg(short, long)]
231        detail: bool,
232    },
233
234    /// Enable a card
235    Enable {
236        /// Name of the card to enable
237        name: String,
238    },
239
240    /// Disable a card
241    Disable {
242        /// Name of the card to disable
243        name: String,
244    },
245
246    /// Add a new card
247    Add {
248        /// Name of the card
249        name: String,
250
251        /// URL of the card repository
252        url: String,
253    },
254
255    /// Remove a card
256    Remove {
257        /// Name of the card to remove
258        name: String,
259
260        /// Don't ask for confirmation
261        #[arg(short, long)]
262        force: bool,
263    },
264
265    /// Build a card
266    Build {
267        /// Name of the card to build
268        name: String,
269
270        /// Create a release build
271        #[arg(short, long)]
272        release: bool,
273    },
274    
275    /// Create a new card template
276    Create {
277        /// Name of the card to create
278        name: String,
279        
280        /// Description of the card
281        #[arg(short, long)]
282        description: String,
283    },
284}
285
286#[derive(Subcommand)]
287pub enum BlendCommands {
288    /// Edit an existing hook
289    Edit {
290        /// Name of the hook to edit (with or without @ prefix)
291        hook_name: String,
292    },
293
294    /// List all installed hooks
295    List,
296
297    /// Run a hook command directly
298    Run {
299        /// Name of the hook to run (with or without @ prefix)
300        hook_name: String,
301
302        /// Arguments to pass to the hook
303        args: Vec<String>,
304    },
305}