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