Skip to main content

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