chasm_cli/
cli.rs

1// Copyright (c) 2024-2026 Nervosys LLC
2// SPDX-License-Identifier: Apache-2.0
3//! CLI argument definitions using clap derive macros
4
5use clap::{Parser, Subcommand};
6
7/// Chat System Manager (csm) - Manage and merge chat sessions across workspaces
8#[derive(Parser)]
9#[command(name = "csm")]
10#[command(author = "Nervosys")]
11#[command(version)]
12#[command(about = "Manage and merge chat sessions across workspaces", long_about = None)]
13pub struct Cli {
14    #[command(subcommand)]
15    pub command: Commands,
16}
17
18#[derive(Subcommand)]
19pub enum Commands {
20    // ============================================================================
21    // List Commands
22    // ============================================================================
23    /// List workspaces, sessions, or paths
24    #[command(visible_alias = "ls")]
25    List {
26        #[command(subcommand)]
27        command: Option<ListCommands>,
28    },
29
30    // ============================================================================
31    // Find Commands
32    // ============================================================================
33    /// Search workspaces or sessions by text pattern (title, content, ID)
34    Find {
35        #[command(subcommand)]
36        command: Option<FindCommands>,
37    },
38
39    // ============================================================================
40    // Show Commands
41    // ============================================================================
42    /// Show workspaces, sessions, or paths
43    #[command(visible_alias = "info")]
44    Show {
45        #[command(subcommand)]
46        command: Option<ShowCommands>,
47    },
48
49    // ============================================================================
50    // Fetch Commands
51    // ============================================================================
52    /// Fetch chat sessions from workspaces, sessions, or paths
53    Fetch {
54        #[command(subcommand)]
55        command: Option<FetchCommands>,
56    },
57
58    // ============================================================================
59    // Merge Commands
60    // ============================================================================
61    /// Merge chat sessions from workspaces, sessions, or paths
62    Merge {
63        #[command(subcommand)]
64        command: Option<MergeCommands>,
65    },
66
67    // ============================================================================
68    // Export Commands
69    // ============================================================================
70    /// Export chat sessions from workspaces, sessions, or paths
71    Export {
72        #[command(subcommand)]
73        command: Option<ExportCommands>,
74    },
75
76    // ============================================================================
77    // Import Commands
78    // ============================================================================
79    /// Import session files from external directories into a workspace
80    Import {
81        #[command(subcommand)]
82        command: Option<ImportCommands>,
83    },
84
85    // ============================================================================
86    // Move Commands
87    // ============================================================================
88    /// Move chat sessions between workspaces
89    #[command(visible_alias = "mv")]
90    Move {
91        #[command(subcommand)]
92        command: Option<MoveCommands>,
93    },
94
95    // ============================================================================
96    // Git Integration Commands
97    // ============================================================================
98    /// Git integration for chat session versioning
99    Git {
100        #[command(subcommand)]
101        command: GitCommands,
102    },
103
104    // ============================================================================
105    // Migration Commands
106    // ============================================================================
107    /// Migration commands for moving chat sessions between machines
108    Migration {
109        #[command(subcommand)]
110        command: MigrationCommands,
111    },
112
113    // ============================================================================
114    // Run Commands (TUI)
115    // ============================================================================
116    /// Run interactive tools
117    Run {
118        #[command(subcommand)]
119        command: RunCommands,
120    },
121
122    // ============================================================================
123    // Provider Commands
124    // ============================================================================
125    /// Manage LLM providers (Ollama, vLLM, Foundry, Cursor, etc.)
126    Provider {
127        #[command(subcommand)]
128        command: ProviderCommands,
129    },
130
131    // ============================================================================
132    // Detect Commands
133    // ============================================================================
134    /// Auto-detect workspace and provider information
135    Detect {
136        #[command(subcommand)]
137        command: Option<DetectCommands>,
138    },
139
140    // ============================================================================
141    // Register Commands
142    // ============================================================================
143    /// Add on-disk sessions to VS Code's database index (makes orphaned sessions visible)
144    #[command(visible_alias = "sync")]
145    Register {
146        #[command(subcommand)]
147        command: RegisterCommands,
148    },
149
150    // ============================================================================
151    // Harvest Commands
152    // ============================================================================
153    /// Harvest chat sessions from all providers into a unified database
154    Harvest {
155        #[command(subcommand)]
156        command: HarvestCommands,
157    },
158
159    // ============================================================================
160    // API Server Commands
161    // ============================================================================
162    /// Start the HTTP API server for the web frontend
163    #[command(visible_alias = "serve")]
164    Api {
165        #[command(subcommand)]
166        command: ApiCommands,
167    },
168
169    // ============================================================================
170    // Agency Commands
171    // ============================================================================
172    /// Agent Development Kit - manage agents and orchestration
173    Agency {
174        #[command(subcommand)]
175        command: AgencyCommands,
176    },
177
178    // ============================================================================
179    // Easter Egg
180    // ============================================================================
181    /// Show banner
182    #[command(hide = true)]
183    Banner,
184}
185
186// ============================================================================
187// List Subcommands
188// ============================================================================
189
190#[derive(Subcommand)]
191pub enum ListCommands {
192    /// List all VS Code workspaces
193    #[command(visible_alias = "ws")]
194    Workspaces,
195
196    /// List all chat sessions
197    #[command(visible_alias = "s")]
198    Sessions {
199        /// Filter by project path
200        #[arg(long)]
201        project_path: Option<String>,
202    },
203
204    /// List sessions for a specific project path
205    Path {
206        /// Project path (default: current directory)
207        project_path: Option<String>,
208    },
209
210    /// List unregistered sessions (exist on disk but invisible to VS Code)
211    Orphaned {
212        /// Project path (default: current directory)
213        #[arg(long)]
214        path: Option<String>,
215    },
216}
217
218// ============================================================================
219// Find Subcommands
220// ============================================================================
221
222#[derive(Subcommand)]
223pub enum FindCommands {
224    /// Search workspaces by name pattern (defaults to current directory name)
225    #[command(visible_alias = "ws")]
226    Workspace {
227        /// Text pattern to match (case-insensitive, defaults to current directory name)
228        pattern: Option<String>,
229    },
230
231    /// Search sessions by title, content, or ID pattern
232    #[command(visible_alias = "s")]
233    Session {
234        /// Text pattern to match (case-insensitive, defaults to current directory name)
235        pattern: Option<String>,
236
237        /// Filter by project path or workspace name
238        #[arg(long, short = 'w')]
239        workspace: Option<String>,
240
241        /// Only search in session titles (faster, skip content search)
242        #[arg(long, short = 't')]
243        title_only: bool,
244
245        /// Include message content in search (slower)
246        #[arg(long, short = 'c')]
247        content: bool,
248
249        /// Filter sessions modified after this date (YYYY-MM-DD)
250        #[arg(long)]
251        after: Option<String>,
252
253        /// Filter sessions modified before this date (YYYY-MM-DD)
254        #[arg(long)]
255        before: Option<String>,
256
257        /// Limit number of results
258        #[arg(long, short = 'n', default_value = "50")]
259        limit: usize,
260    },
261
262    /// Search sessions within a specific project path
263    Path {
264        /// Search pattern (case-insensitive, defaults to current directory name)
265        pattern: Option<String>,
266
267        /// Project path (default: current directory)
268        #[arg(long)]
269        project_path: Option<String>,
270    },
271}
272
273// ============================================================================
274// Show Subcommands
275// ============================================================================
276
277#[derive(Subcommand)]
278pub enum ShowCommands {
279    /// Show workspace details
280    #[command(visible_alias = "ws")]
281    Workspace {
282        /// Workspace name or hash
283        workspace: String,
284    },
285
286    /// Show session details
287    #[command(visible_alias = "s")]
288    Session {
289        /// Session ID or filename
290        session_id: String,
291
292        /// Project path to search in
293        #[arg(long)]
294        project_path: Option<String>,
295    },
296
297    /// Show chat history timeline for a project path
298    Path {
299        /// Path to the project (default: current directory)
300        project_path: Option<String>,
301    },
302}
303
304// ============================================================================
305// Fetch Subcommands
306// ============================================================================
307
308#[derive(Subcommand)]
309pub enum FetchCommands {
310    /// Fetch sessions from workspaces matching a pattern
311    #[command(visible_alias = "ws")]
312    Workspace {
313        /// Workspace name pattern (case-insensitive)
314        workspace_name: String,
315
316        /// Target project path (default: current directory)
317        #[arg(long)]
318        target_path: Option<String>,
319
320        /// Overwrite existing sessions
321        #[arg(long)]
322        force: bool,
323
324        /// Don't register sessions in VS Code index
325        #[arg(long)]
326        no_register: bool,
327    },
328
329    /// Fetch specific sessions by ID
330    #[command(visible_alias = "s")]
331    Session {
332        /// Session IDs to fetch (space-separated)
333        #[arg(required = true, num_args = 1..)]
334        session_ids: Vec<String>,
335
336        /// Target project path (default: current directory)
337        #[arg(long)]
338        target_path: Option<String>,
339
340        /// Overwrite existing sessions
341        #[arg(long)]
342        force: bool,
343
344        /// Don't register sessions in VS Code index
345        #[arg(long)]
346        no_register: bool,
347    },
348
349    /// Fetch chat sessions from other workspaces by project path
350    Path {
351        /// Path to the project (default: current directory)
352        project_path: Option<String>,
353
354        /// Overwrite existing sessions and skip VS Code running check
355        #[arg(long)]
356        force: bool,
357
358        /// Don't register sessions in VS Code index
359        #[arg(long)]
360        no_register: bool,
361    },
362}
363
364// ============================================================================
365// Merge Subcommands
366// ============================================================================
367
368#[derive(Subcommand)]
369pub enum MergeCommands {
370    /// Merge sessions from workspaces matching a name pattern
371    #[command(visible_alias = "ws")]
372    Workspace {
373        /// Workspace name pattern to search for (case-insensitive)
374        workspace_name: String,
375
376        /// Title for the merged session
377        #[arg(short, long)]
378        title: Option<String>,
379
380        /// Target project path to save the merged session (default: current directory)
381        #[arg(long)]
382        target_path: Option<String>,
383
384        /// Skip VS Code running check
385        #[arg(long)]
386        force: bool,
387
388        /// Don't create backup of current sessions
389        #[arg(long)]
390        no_backup: bool,
391    },
392
393    /// Merge sessions from multiple workspace name patterns
394    #[command(visible_alias = "wss")]
395    Workspaces {
396        /// Workspace name patterns to search for (space-separated, case-insensitive)
397        #[arg(required = true, num_args = 1..)]
398        workspace_names: Vec<String>,
399
400        /// Title for the merged session
401        #[arg(short, long)]
402        title: Option<String>,
403
404        /// Target project path to save the merged session (default: current directory)
405        #[arg(long)]
406        target_path: Option<String>,
407
408        /// Skip VS Code running check
409        #[arg(long)]
410        force: bool,
411
412        /// Don't create backup of current sessions
413        #[arg(long)]
414        no_backup: bool,
415    },
416
417    /// Merge specific sessions by their IDs or filenames
418    #[command(visible_alias = "s")]
419    Sessions {
420        /// Session IDs or filenames (comma-separated or space-separated)
421        #[arg(required = true, num_args = 1..)]
422        sessions: Vec<String>,
423
424        /// Title for the merged session
425        #[arg(short, long)]
426        title: Option<String>,
427
428        /// Target project path to save the merged session (default: current directory)
429        #[arg(long)]
430        target_path: Option<String>,
431
432        /// Skip VS Code running check
433        #[arg(long)]
434        force: bool,
435
436        /// Don't create backup of current sessions
437        #[arg(long)]
438        no_backup: bool,
439    },
440
441    /// Merge all sessions for a project path into one unified chat
442    Path {
443        /// Path to the project (default: current directory)
444        project_path: Option<String>,
445
446        /// Title for the merged session
447        #[arg(short, long)]
448        title: Option<String>,
449
450        /// Skip VS Code running check
451        #[arg(long)]
452        force: bool,
453
454        /// Don't create backup of current sessions
455        #[arg(long)]
456        no_backup: bool,
457    },
458
459    /// Merge sessions from an LLM provider (Ollama, Cursor, etc.)
460    Provider {
461        /// Provider name (copilot, cursor, ollama, vllm, foundry, etc.)
462        provider_name: String,
463
464        /// Title for the merged session
465        #[arg(short, long)]
466        title: Option<String>,
467
468        /// Target project path to save the merged session (default: current directory)
469        #[arg(long)]
470        target_path: Option<String>,
471
472        /// Session IDs from the provider to include (omit for all)
473        #[arg(long)]
474        sessions: Option<Vec<String>>,
475
476        /// Skip VS Code running check
477        #[arg(long)]
478        force: bool,
479
480        /// Don't create backup of current sessions
481        #[arg(long)]
482        no_backup: bool,
483    },
484
485    /// Merge sessions from multiple providers
486    #[command(name = "providers")]
487    Providers {
488        /// Provider names (space-separated: copilot cursor ollama)
489        #[arg(required = true, num_args = 1..)]
490        providers: Vec<String>,
491
492        /// Title for the merged session
493        #[arg(short, long)]
494        title: Option<String>,
495
496        /// Target project path to save the merged session (default: current directory)
497        #[arg(long)]
498        target_path: Option<String>,
499
500        /// Filter by workspace name pattern (applies to providers that support workspaces)
501        #[arg(long)]
502        workspace: Option<String>,
503
504        /// Skip VS Code running check
505        #[arg(long)]
506        force: bool,
507
508        /// Don't create backup of current sessions
509        #[arg(long)]
510        no_backup: bool,
511    },
512
513    /// Merge all sessions across all available providers
514    All {
515        /// Title for the merged session
516        #[arg(short, long)]
517        title: Option<String>,
518
519        /// Target project path to save the merged session (default: current directory)
520        #[arg(long)]
521        target_path: Option<String>,
522
523        /// Filter by workspace name pattern (applies to providers that support workspaces)
524        #[arg(long)]
525        workspace: Option<String>,
526
527        /// Skip VS Code running check
528        #[arg(long)]
529        force: bool,
530
531        /// Don't create backup of current sessions
532        #[arg(long)]
533        no_backup: bool,
534    },
535}
536
537// ============================================================================
538// Export Subcommands
539// ============================================================================
540
541#[derive(Subcommand)]
542pub enum ExportCommands {
543    /// Export sessions from a workspace by hash
544    #[command(visible_alias = "ws")]
545    Workspace {
546        /// Destination directory for exported sessions
547        destination: String,
548
549        /// Source workspace hash
550        hash: String,
551    },
552
553    /// Export specific sessions by ID
554    #[command(visible_alias = "s")]
555    Sessions {
556        /// Destination directory for exported sessions
557        destination: String,
558
559        /// Session IDs to export (space-separated)
560        #[arg(required = true, num_args = 1..)]
561        session_ids: Vec<String>,
562
563        /// Source project path
564        #[arg(long)]
565        project_path: Option<String>,
566    },
567
568    /// Export chat sessions from a project path
569    Path {
570        /// Destination directory for exported sessions
571        destination: String,
572
573        /// Source project path (default: current directory)
574        project_path: Option<String>,
575    },
576}
577
578// ============================================================================
579// Import Subcommands
580// ============================================================================
581
582#[derive(Subcommand)]
583pub enum ImportCommands {
584    /// Copy session files from external directory into a workspace
585    #[command(visible_alias = "ws")]
586    Workspace {
587        /// Source directory containing session JSON files to import
588        source: String,
589
590        /// Target workspace hash
591        hash: String,
592
593        /// Overwrite existing sessions
594        #[arg(long)]
595        force: bool,
596    },
597
598    /// Copy specific session files into a workspace
599    #[command(visible_alias = "s")]
600    Sessions {
601        /// Session files to import (space-separated paths)
602        #[arg(required = true, num_args = 1..)]
603        session_files: Vec<String>,
604
605        /// Target project path (default: current directory)
606        #[arg(long)]
607        target_path: Option<String>,
608
609        /// Overwrite existing sessions
610        #[arg(long)]
611        force: bool,
612    },
613
614    /// Copy session files from external directory into a project workspace
615    Path {
616        /// Source directory containing session JSON files to import
617        source: String,
618
619        /// Target project path (default: current directory)
620        target_path: Option<String>,
621
622        /// Overwrite existing sessions
623        #[arg(long)]
624        force: bool,
625    },
626}
627
628// ============================================================================
629// Move Subcommands
630// ============================================================================
631
632#[derive(Subcommand)]
633pub enum MoveCommands {
634    /// Move all sessions from one workspace to another
635    #[command(visible_alias = "ws")]
636    Workspace {
637        /// Source workspace hash
638        source_hash: String,
639
640        /// Target workspace hash or project path
641        target: String,
642    },
643
644    /// Move specific sessions by ID
645    #[command(visible_alias = "s")]
646    Sessions {
647        /// Session IDs to move (space-separated)
648        #[arg(required = true, num_args = 1..)]
649        session_ids: Vec<String>,
650
651        /// Target project path
652        target_path: String,
653    },
654
655    /// Move sessions from a source path to target path
656    Path {
657        /// Source project path
658        source_path: String,
659
660        /// Target project path
661        target_path: String,
662    },
663}
664
665// ============================================================================
666// Git Subcommands
667// ============================================================================
668
669#[derive(Subcommand)]
670pub enum GitCommands {
671    /// Configure git settings for chat sessions
672    Config {
673        /// Git user name
674        #[arg(long)]
675        name: Option<String>,
676
677        /// Git user email
678        #[arg(long)]
679        email: Option<String>,
680
681        /// Project path
682        #[arg(long)]
683        path: Option<String>,
684    },
685
686    /// Initialize git versioning for chat sessions
687    Init {
688        /// Project path
689        path: String,
690    },
691
692    /// Add chat sessions to git (stage and optionally commit)
693    Add {
694        /// Project path
695        path: String,
696
697        /// Also commit the changes
698        #[arg(long)]
699        commit: bool,
700
701        /// Commit message (requires --commit)
702        #[arg(short, long)]
703        message: Option<String>,
704    },
705
706    /// Show git status of chat sessions
707    Status {
708        /// Project path
709        path: String,
710    },
711
712    /// Create a git tag snapshot of chat sessions
713    Snapshot {
714        /// Project path
715        path: String,
716
717        /// Tag name (auto-generated if not provided)
718        #[arg(long)]
719        tag: Option<String>,
720
721        /// Snapshot message
722        #[arg(short, long)]
723        message: Option<String>,
724    },
725
726    /// Track chat sessions together with associated file changes
727    Track {
728        /// Project path
729        path: String,
730
731        /// Commit message describing the changes
732        #[arg(short, long)]
733        message: Option<String>,
734
735        /// Include all staged and unstaged file changes
736        #[arg(long)]
737        all: bool,
738
739        /// Include specific files in addition to chat sessions
740        #[arg(long)]
741        files: Option<Vec<String>>,
742
743        /// Create a tag for this tracked state
744        #[arg(long)]
745        tag: Option<String>,
746    },
747
748    /// Show history of chat session commits with associated file changes
749    Log {
750        /// Project path
751        path: String,
752
753        /// Number of commits to show
754        #[arg(short = 'n', long, default_value = "10")]
755        count: usize,
756
757        /// Show only commits that include chat session changes
758        #[arg(long)]
759        sessions_only: bool,
760    },
761
762    /// Diff chat sessions between commits or current state
763    Diff {
764        /// Project path
765        path: String,
766
767        /// First commit (default: HEAD)
768        #[arg(long)]
769        from: Option<String>,
770
771        /// Second commit (default: working directory)
772        #[arg(long)]
773        to: Option<String>,
774
775        /// Show associated file changes alongside chat diffs
776        #[arg(long)]
777        with_files: bool,
778    },
779
780    /// Restore chat sessions from a specific commit
781    Restore {
782        /// Project path
783        path: String,
784
785        /// Commit hash, tag, or reference to restore from
786        commit: String,
787
788        /// Also restore associated files from the same commit
789        #[arg(long)]
790        with_files: bool,
791
792        /// Create a backup before restoring
793        #[arg(long)]
794        backup: bool,
795    },
796}
797
798// ============================================================================
799// Migration Subcommands
800// ============================================================================
801
802#[derive(Subcommand)]
803pub enum MigrationCommands {
804    /// Create a migration package for moving to a new machine
805    Create {
806        /// Output directory for migration package
807        output: String,
808
809        /// Comma-separated list of project paths to include
810        #[arg(long)]
811        projects: Option<String>,
812
813        /// Include all workspaces with chat sessions
814        #[arg(long)]
815        all: bool,
816    },
817
818    /// Restore a migration package on a new machine
819    Restore {
820        /// Path to migration package directory
821        package: String,
822
823        /// Project path mapping: 'old1:new1;old2:new2'
824        #[arg(long)]
825        mapping: Option<String>,
826
827        /// Show what would be done without doing it
828        #[arg(long)]
829        dry_run: bool,
830    },
831}
832
833// ============================================================================
834// Run Subcommands
835// ============================================================================
836
837#[derive(Subcommand)]
838pub enum RunCommands {
839    /// Launch interactive TUI (Text User Interface)
840    Tui,
841}
842
843// ============================================================================
844// Provider Subcommands
845// ============================================================================
846
847#[derive(Subcommand)]
848pub enum ProviderCommands {
849    /// List all discovered LLM providers
850    List,
851
852    /// Show detailed info about a specific provider
853    Info {
854        /// Provider name (copilot, cursor, ollama, vllm, foundry, lm-studio, etc.)
855        provider: String,
856    },
857
858    /// Configure a provider
859    Config {
860        /// Provider name
861        provider: String,
862
863        /// API endpoint URL
864        #[arg(long)]
865        endpoint: Option<String>,
866
867        /// API key
868        #[arg(long)]
869        api_key: Option<String>,
870
871        /// Default model
872        #[arg(long)]
873        model: Option<String>,
874
875        /// Enable or disable the provider
876        #[arg(long)]
877        enabled: Option<bool>,
878    },
879
880    /// Import sessions from another provider
881    Import {
882        /// Source provider name
883        #[arg(long)]
884        from: String,
885
886        /// Target project path (or current directory)
887        #[arg(long)]
888        path: Option<String>,
889
890        /// Session ID to import (omit for all)
891        #[arg(long)]
892        session: Option<String>,
893    },
894
895    /// Test connection to a provider
896    Test {
897        /// Provider name
898        provider: String,
899    },
900}
901
902// ============================================================================
903// Detect Subcommands
904// ============================================================================
905
906#[derive(Subcommand)]
907pub enum DetectCommands {
908    /// Detect workspace for a path
909    Workspace {
910        /// Project path (default: current directory)
911        path: Option<String>,
912    },
913
914    /// Detect available providers
915    Providers {
916        /// Only show providers with sessions
917        #[arg(long)]
918        with_sessions: bool,
919    },
920
921    /// Detect which provider a session belongs to
922    Session {
923        /// Session ID or filename
924        session_id: String,
925
926        /// Project path to search in
927        #[arg(long)]
928        path: Option<String>,
929    },
930
931    /// Detect everything (workspace, providers, sessions) for a path
932    All {
933        /// Project path (default: current directory)
934        path: Option<String>,
935
936        /// Show detailed information
937        #[arg(long)]
938        verbose: bool,
939    },
940}
941
942// ============================================================================
943// Register Subcommands
944// ============================================================================
945
946#[derive(Subcommand)]
947pub enum RegisterCommands {
948    /// Register all on-disk sessions into VS Code's index (fixes orphaned sessions)
949    All {
950        /// Project path (default: current directory)
951        #[arg(long)]
952        path: Option<String>,
953
954        /// Merge all sessions into one before registering
955        #[arg(long, short)]
956        merge: bool,
957
958        /// Force registration even if VS Code is running
959        #[arg(long, short)]
960        force: bool,
961    },
962
963    /// Register specific sessions by ID or title into VS Code's index
964    #[command(visible_alias = "s")]
965    Session {
966        /// Session IDs or filenames (without .json extension)
967        #[arg(required_unless_present = "title")]
968        ids: Vec<String>,
969
970        /// Match sessions by title instead of ID
971        #[arg(long, short, num_args = 1.., value_delimiter = ' ')]
972        title: Option<Vec<String>>,
973
974        /// Project path (default: current directory)
975        #[arg(long)]
976        path: Option<String>,
977
978        /// Force registration even if VS Code is running
979        #[arg(long, short)]
980        force: bool,
981    },
982}
983
984// ============================================================================
985// Harvest Subcommands
986// ============================================================================
987
988#[derive(Subcommand)]
989pub enum HarvestCommands {
990    /// Initialize a harvest database
991    Init {
992        /// Path to the database file (default: ./chat_sessions.db)
993        #[arg(long)]
994        path: Option<String>,
995
996        /// Initialize git tracking for the database
997        #[arg(long)]
998        git: bool,
999    },
1000
1001    /// Scan for available providers and sessions
1002    Scan {
1003        /// Show individual sessions
1004        #[arg(long)]
1005        sessions: bool,
1006
1007        /// Scan for web-based LLM providers (ChatGPT, Claude, etc.)
1008        #[arg(long)]
1009        web: bool,
1010
1011        /// Timeout in seconds for web provider checks (default: 5)
1012        #[arg(long, default_value = "5")]
1013        timeout: u64,
1014
1015        /// Show verbose debug output for browser scanning
1016        #[arg(long, short)]
1017        verbose: bool,
1018    },
1019
1020    /// Run the harvest to collect sessions from all providers
1021    Run {
1022        /// Path to the harvest database
1023        #[arg(long)]
1024        path: Option<String>,
1025
1026        /// Only include specific providers (comma-separated: copilot,cursor,ollama)
1027        #[arg(long, value_delimiter = ',')]
1028        providers: Option<Vec<String>>,
1029
1030        /// Exclude specific providers (comma-separated)
1031        #[arg(long, value_delimiter = ',')]
1032        exclude: Option<Vec<String>>,
1033
1034        /// Only harvest sessions changed since last run
1035        #[arg(long)]
1036        incremental: bool,
1037
1038        /// Auto-commit changes to git after harvest
1039        #[arg(long)]
1040        commit: bool,
1041
1042        /// Commit message (requires --commit)
1043        #[arg(short, long)]
1044        message: Option<String>,
1045    },
1046
1047    /// Show harvest database status
1048    Status {
1049        /// Path to the harvest database
1050        #[arg(long)]
1051        path: Option<String>,
1052    },
1053
1054    /// List sessions in the harvest database
1055    List {
1056        /// Path to the harvest database
1057        #[arg(long)]
1058        path: Option<String>,
1059
1060        /// Filter by provider name
1061        #[arg(long)]
1062        provider: Option<String>,
1063
1064        /// Maximum number of sessions to show
1065        #[arg(long, default_value = "20")]
1066        limit: usize,
1067
1068        /// Search sessions by title or ID
1069        #[arg(long)]
1070        search: Option<String>,
1071    },
1072
1073    /// Export sessions from the harvest database
1074    Export {
1075        /// Output file path
1076        output: String,
1077
1078        /// Path to the harvest database
1079        #[arg(long)]
1080        path: Option<String>,
1081
1082        /// Export format: json, jsonl, md (markdown)
1083        #[arg(long, default_value = "json")]
1084        format: String,
1085
1086        /// Filter by provider name
1087        #[arg(long)]
1088        provider: Option<String>,
1089
1090        /// Export specific sessions by ID (comma-separated)
1091        #[arg(long, value_delimiter = ',')]
1092        sessions: Option<Vec<String>>,
1093    },
1094
1095    /// Import a shared chat session from a URL
1096    Share {
1097        /// Share link URL (ChatGPT, Claude, etc.)
1098        url: String,
1099
1100        /// Path to the harvest database
1101        #[arg(long)]
1102        path: Option<String>,
1103
1104        /// Custom name for the imported session
1105        #[arg(long)]
1106        name: Option<String>,
1107
1108        /// Associate with a workspace path
1109        #[arg(long)]
1110        workspace: Option<String>,
1111    },
1112
1113    /// List pending or imported share links
1114    Shares {
1115        /// Path to the harvest database
1116        #[arg(long)]
1117        path: Option<String>,
1118
1119        /// Filter by status: pending, imported, failed, expired
1120        #[arg(long)]
1121        status: Option<String>,
1122
1123        /// Maximum number of links to show
1124        #[arg(long, default_value = "20")]
1125        limit: usize,
1126    },
1127
1128    /// Create a checkpoint (version snapshot) of a session
1129    Checkpoint {
1130        /// Session ID to checkpoint
1131        session: String,
1132
1133        /// Path to the harvest database
1134        #[arg(long)]
1135        path: Option<String>,
1136
1137        /// Checkpoint description message
1138        #[arg(short, long)]
1139        message: Option<String>,
1140    },
1141
1142    /// List checkpoints for a session
1143    Checkpoints {
1144        /// Session ID to list checkpoints for
1145        session: String,
1146
1147        /// Path to the harvest database
1148        #[arg(long)]
1149        path: Option<String>,
1150    },
1151
1152    /// Restore a session to a previous checkpoint
1153    Restore {
1154        /// Session ID to restore
1155        session: String,
1156
1157        /// Checkpoint number to restore to
1158        checkpoint: i64,
1159
1160        /// Path to the harvest database
1161        #[arg(long)]
1162        path: Option<String>,
1163    },
1164
1165    /// Rebuild the full-text search index
1166    Rebuild {
1167        /// Path to the harvest database
1168        #[arg(long)]
1169        path: Option<String>,
1170    },
1171
1172    /// Search messages across all sessions (full-text search)
1173    Search {
1174        /// Search query
1175        query: String,
1176
1177        /// Path to the harvest database
1178        #[arg(long)]
1179        path: Option<String>,
1180
1181        /// Filter by provider
1182        #[arg(long)]
1183        provider: Option<String>,
1184
1185        /// Maximum results to show
1186        #[arg(long, default_value = "20")]
1187        limit: usize,
1188    },
1189
1190    /// Git operations for the harvest database
1191    Git {
1192        #[command(subcommand)]
1193        command: HarvestGitCommands,
1194    },
1195}
1196
1197#[derive(Subcommand)]
1198pub enum HarvestGitCommands {
1199    /// Initialize git tracking for the harvest database
1200    Init {
1201        /// Path to the harvest database
1202        #[arg(long)]
1203        path: Option<String>,
1204    },
1205
1206    /// Commit changes to the harvest database
1207    Commit {
1208        /// Path to the harvest database
1209        #[arg(long)]
1210        path: Option<String>,
1211
1212        /// Commit message
1213        #[arg(short, long)]
1214        message: Option<String>,
1215    },
1216
1217    /// Show git log for the harvest database
1218    Log {
1219        /// Path to the harvest database
1220        #[arg(long)]
1221        path: Option<String>,
1222
1223        /// Number of commits to show
1224        #[arg(short = 'n', long, default_value = "10")]
1225        count: usize,
1226    },
1227
1228    /// Show changes to the harvest database
1229    Diff {
1230        /// Path to the harvest database
1231        #[arg(long)]
1232        path: Option<String>,
1233
1234        /// Compare against specific commit
1235        #[arg(long)]
1236        commit: Option<String>,
1237    },
1238
1239    /// Restore harvest database from a commit
1240    Restore {
1241        /// Commit hash to restore from
1242        commit: String,
1243
1244        /// Path to the harvest database
1245        #[arg(long)]
1246        path: Option<String>,
1247    },
1248}
1249
1250// ============================================================================
1251// API Server Subcommands
1252// ============================================================================
1253
1254#[derive(Subcommand)]
1255pub enum ApiCommands {
1256    /// Start the API server
1257    Serve {
1258        /// Host to bind to (default: 0.0.0.0 for all interfaces)
1259        #[arg(long, default_value = "0.0.0.0")]
1260        host: String,
1261
1262        /// Port to listen on (default: 8787)
1263        #[arg(short, long, default_value = "8787")]
1264        port: u16,
1265
1266        /// Path to the database file
1267        #[arg(long)]
1268        database: Option<String>,
1269    },
1270}
1271
1272// ============================================================================
1273// Agency (Agent Development Kit) Subcommands
1274// ============================================================================
1275
1276#[derive(Subcommand)]
1277pub enum AgencyCommands {
1278    /// List available agents and their roles
1279    List {
1280        /// Show detailed information
1281        #[arg(short, long)]
1282        verbose: bool,
1283    },
1284
1285    /// Show agent information
1286    Info {
1287        /// Agent name or ID
1288        name: String,
1289    },
1290
1291    /// List supported orchestration modes
1292    Modes,
1293
1294    /// Run an agent with a prompt
1295    Run {
1296        /// Agent name to run
1297        #[arg(short, long, default_value = "assistant")]
1298        agent: String,
1299
1300        /// Prompt or task for the agent
1301        prompt: String,
1302
1303        /// Model to use (e.g., gemini-2.0-flash, gpt-4o)
1304        #[arg(short, long)]
1305        model: Option<String>,
1306
1307        /// Orchestration mode (single, sequential, parallel, swarm)
1308        #[arg(long, default_value = "single")]
1309        orchestration: String,
1310
1311        /// Enable verbose output
1312        #[arg(short, long)]
1313        verbose: bool,
1314    },
1315
1316    /// Create a new agent configuration
1317    Create {
1318        /// Agent name
1319        name: String,
1320
1321        /// Agent role (coordinator, researcher, coder, reviewer, executor, writer, tester, custom)
1322        #[arg(short, long, default_value = "custom")]
1323        role: String,
1324
1325        /// System instruction for the agent
1326        #[arg(short, long)]
1327        instruction: Option<String>,
1328
1329        /// Model to use
1330        #[arg(short, long)]
1331        model: Option<String>,
1332    },
1333
1334    /// List available tools
1335    Tools,
1336
1337    /// Show swarm templates
1338    Templates,
1339}