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}