exa-ai 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/exe/exa-ai +61 -7
  4. data/exe/exa-ai-answer +9 -8
  5. data/exe/exa-ai-context +6 -5
  6. data/exe/exa-ai-enrichment-cancel +1 -0
  7. data/exe/exa-ai-enrichment-create +1 -0
  8. data/exe/exa-ai-enrichment-delete +1 -0
  9. data/exe/exa-ai-enrichment-get +1 -0
  10. data/exe/exa-ai-enrichment-list +1 -0
  11. data/exe/exa-ai-enrichment-update +1 -0
  12. data/exe/exa-ai-find-similar +1 -0
  13. data/exe/exa-ai-get-contents +9 -8
  14. data/exe/exa-ai-import-create +235 -0
  15. data/exe/exa-ai-import-delete +92 -0
  16. data/exe/exa-ai-import-get +92 -0
  17. data/exe/exa-ai-import-list +72 -0
  18. data/exe/exa-ai-import-update +164 -0
  19. data/exe/exa-ai-monitor-create +223 -0
  20. data/exe/exa-ai-monitor-delete +101 -0
  21. data/exe/exa-ai-monitor-get +92 -0
  22. data/exe/exa-ai-monitor-list +90 -0
  23. data/exe/exa-ai-monitor-runs-get +103 -0
  24. data/exe/exa-ai-monitor-runs-list +110 -0
  25. data/exe/exa-ai-monitor-update +207 -0
  26. data/exe/exa-ai-research-get +7 -7
  27. data/exe/exa-ai-research-list +5 -5
  28. data/exe/exa-ai-research-start +8 -7
  29. data/exe/exa-ai-search +20 -13
  30. data/exe/exa-ai-webset-cancel +1 -0
  31. data/exe/exa-ai-webset-create +44 -6
  32. data/exe/exa-ai-webset-delete +1 -0
  33. data/exe/exa-ai-webset-get +1 -0
  34. data/exe/exa-ai-webset-item-get +1 -0
  35. data/exe/exa-ai-webset-item-list +1 -0
  36. data/exe/exa-ai-webset-list +1 -0
  37. data/exe/exa-ai-webset-search-cancel +1 -0
  38. data/exe/exa-ai-webset-search-create +1 -0
  39. data/exe/exa-ai-webset-search-get +1 -0
  40. data/exe/exa-ai-webset-update +1 -0
  41. data/lib/exa/cli/base.rb +8 -2
  42. data/lib/exa/cli/formatters/answer_formatter.rb +2 -0
  43. data/lib/exa/cli/formatters/contents_formatter.rb +2 -0
  44. data/lib/exa/cli/formatters/context_formatter.rb +2 -0
  45. data/lib/exa/cli/formatters/enrichment_formatter.rb +4 -0
  46. data/lib/exa/cli/formatters/import_formatter.rb +85 -0
  47. data/lib/exa/cli/formatters/monitor_formatter.rb +81 -0
  48. data/lib/exa/cli/formatters/monitor_run_formatter.rb +75 -0
  49. data/lib/exa/cli/formatters/research_formatter.rb +4 -0
  50. data/lib/exa/cli/formatters/search_formatter.rb +2 -0
  51. data/lib/exa/cli/formatters/webset_formatter.rb +4 -0
  52. data/lib/exa/cli/formatters/webset_item_formatter.rb +4 -0
  53. data/lib/exa/client.rb +137 -0
  54. data/lib/exa/constants/websets.rb +19 -0
  55. data/lib/exa/middleware/raise_error.rb +5 -0
  56. data/lib/exa/resources/import.rb +86 -0
  57. data/lib/exa/resources/import_collection.rb +33 -0
  58. data/lib/exa/resources/monitor.rb +48 -0
  59. data/lib/exa/resources/monitor_collection.rb +30 -0
  60. data/lib/exa/resources/monitor_run.rb +52 -0
  61. data/lib/exa/resources/monitor_run_collection.rb +30 -0
  62. data/lib/exa/services/search.rb +21 -1
  63. data/lib/exa/services/websets/create_validator.rb +5 -3
  64. data/lib/exa/services/websets/import_create.rb +40 -0
  65. data/lib/exa/services/websets/import_delete.rb +37 -0
  66. data/lib/exa/services/websets/import_get.rb +37 -0
  67. data/lib/exa/services/websets/import_list.rb +25 -0
  68. data/lib/exa/services/websets/import_update.rb +38 -0
  69. data/lib/exa/services/websets/import_upload.rb +58 -0
  70. data/lib/exa/services/websets/monitors/create.rb +42 -0
  71. data/lib/exa/services/websets/monitors/delete.rb +32 -0
  72. data/lib/exa/services/websets/monitors/get.rb +33 -0
  73. data/lib/exa/services/websets/monitors/list.rb +27 -0
  74. data/lib/exa/services/websets/monitors/runs/get.rb +37 -0
  75. data/lib/exa/services/websets/monitors/runs/list.rb +30 -0
  76. data/lib/exa/services/websets/monitors/update.rb +33 -0
  77. data/lib/exa/version.rb +1 -1
  78. data/lib/exa.rb +23 -0
  79. metadata +50 -1
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ import_id = nil
8
+ api_key = nil
9
+ output_format = "json"
10
+
11
+ args = ARGV.dup
12
+ while args.any?
13
+ arg = args.shift
14
+ case arg
15
+ when "--api-key"
16
+ api_key = args.shift
17
+ when "--output-format"
18
+ output_format = args.shift
19
+ when "--help", "-h"
20
+ puts <<~HELP
21
+ Usage: exa-ai import-get <import_id> [OPTIONS]
22
+
23
+ Get details of a specific import
24
+
25
+ Arguments:
26
+ import_id ID of the import (required)
27
+
28
+ Options:
29
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
30
+ --output-format FMT Output format: json, pretty, or text (default: json)
31
+ --help, -h Show this help message
32
+
33
+ Examples:
34
+ exa-ai import-get imp_123
35
+ exa-ai import-get imp_123 --output-format text
36
+ HELP
37
+ exit 0
38
+ else
39
+ # First positional argument is import_id
40
+ if import_id.nil?
41
+ import_id = arg
42
+ else
43
+ $stderr.puts "Unknown option: #{arg}"
44
+ exit 1
45
+ end
46
+ end
47
+ end
48
+
49
+ # Validate
50
+ if import_id.nil?
51
+ $stderr.puts "Error: import_id argument is required"
52
+ $stderr.puts "Usage: exa-ai import-get <import_id> [OPTIONS]"
53
+ $stderr.puts "Try 'exa-ai import-get --help' for more information"
54
+ exit 1
55
+ end
56
+
57
+ begin
58
+ # Resolve API key and format
59
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
60
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
61
+
62
+ # Build client
63
+ client = Exa::CLI::Base.build_client(api_key)
64
+
65
+ # Get import
66
+ import = client.get_import(import_id)
67
+
68
+ # Format and output
69
+ output = Exa::CLI::Formatters::ImportFormatter.format(import, output_format)
70
+ puts output
71
+
72
+ rescue Exa::NotFound => e
73
+ $stderr.puts "Import not found: #{e.message}"
74
+ exit 1
75
+ rescue Exa::Unauthorized => e
76
+ $stderr.puts "Authentication error: #{e.message}"
77
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
78
+ exit 1
79
+ rescue Exa::ClientError => e
80
+ $stderr.puts "Client error: #{e.message}"
81
+ exit 1
82
+ rescue Exa::ServerError => e
83
+ $stderr.puts "Server error: #{e.message}"
84
+ exit 1
85
+ rescue Exa::Error => e
86
+ $stderr.puts "Error: #{e.message}"
87
+ exit 1
88
+ rescue StandardError => e
89
+ $stderr.puts "Unexpected error: #{e.message}"
90
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
91
+ exit 1
92
+ end
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ api_key = nil
8
+ output_format = "json"
9
+
10
+ args = ARGV.dup
11
+ while args.any?
12
+ arg = args.shift
13
+ case arg
14
+ when "--api-key"
15
+ api_key = args.shift
16
+ when "--output-format"
17
+ output_format = args.shift
18
+ when "--help", "-h"
19
+ puts <<~HELP
20
+ Usage: exa-ai import-list [OPTIONS]
21
+
22
+ List all imports
23
+
24
+ Options:
25
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
26
+ --output-format FMT Output format: json, pretty, or text (default: json)
27
+ --help, -h Show this help message
28
+
29
+ Examples:
30
+ exa-ai import-list
31
+ exa-ai import-list --output-format text
32
+ HELP
33
+ exit 0
34
+ else
35
+ $stderr.puts "Unknown option: #{arg}"
36
+ exit 1
37
+ end
38
+ end
39
+
40
+ begin
41
+ # Resolve API key and format
42
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
43
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
44
+
45
+ # Build client
46
+ client = Exa::CLI::Base.build_client(api_key)
47
+
48
+ # List imports
49
+ collection = client.list_imports
50
+
51
+ # Format and output
52
+ output = Exa::CLI::Formatters::ImportFormatter.format_collection(collection, output_format)
53
+ puts output
54
+
55
+ rescue Exa::Unauthorized => e
56
+ $stderr.puts "Authentication error: #{e.message}"
57
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
58
+ exit 1
59
+ rescue Exa::ClientError => e
60
+ $stderr.puts "Client error: #{e.message}"
61
+ exit 1
62
+ rescue Exa::ServerError => e
63
+ $stderr.puts "Server error: #{e.message}"
64
+ exit 1
65
+ rescue Exa::Error => e
66
+ $stderr.puts "Error: #{e.message}"
67
+ exit 1
68
+ rescue StandardError => e
69
+ $stderr.puts "Unexpected error: #{e.message}"
70
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
71
+ exit 1
72
+ end
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Recursively convert hash keys from strings to symbols
7
+ def deep_symbolize_keys(obj)
8
+ case obj
9
+ when Hash
10
+ obj.each_with_object({}) do |(key, value), result|
11
+ result[key.to_sym] = deep_symbolize_keys(value)
12
+ end
13
+ when Array
14
+ obj.map { |item| deep_symbolize_keys(item) }
15
+ else
16
+ obj
17
+ end
18
+ end
19
+
20
+ # Parse JSON string or load from file (supports @file.json syntax)
21
+ def parse_json_or_file(value)
22
+ json_data = if value.start_with?("@")
23
+ file_path = value[1..]
24
+ JSON.parse(File.read(file_path))
25
+ else
26
+ JSON.parse(value)
27
+ end
28
+ deep_symbolize_keys(json_data)
29
+ rescue JSON::ParserError => e
30
+ $stderr.puts "Error: Invalid JSON: #{e.message}"
31
+ exit 1
32
+ rescue Errno::ENOENT => e
33
+ $stderr.puts "Error: File not found: #{e.message}"
34
+ exit 1
35
+ end
36
+
37
+ # Parse command-line arguments
38
+ def parse_args(argv)
39
+ # Check for help first
40
+ if argv.include?("--help") || argv.include?("-h")
41
+ puts <<~HELP
42
+ Usage: exa-ai import-update <import_id> [OPTIONS]
43
+
44
+ Update an existing import
45
+
46
+ Required:
47
+ <import_id> Import ID
48
+
49
+ Options:
50
+ --title TEXT New display title
51
+ --metadata JSON New metadata (supports @file.json)
52
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
53
+ --output-format FMT Output format: json, pretty, or text (default: json)
54
+ --help, -h Show this help message
55
+
56
+ Examples:
57
+ exa-ai import-update imp_123 --title "Updated Title"
58
+ exa-ai import-update imp_123 --metadata '{"status":"reviewed"}'
59
+ exa-ai import-update imp_123 --title "New Title" --metadata @metadata.json
60
+ HELP
61
+ exit 0
62
+ end
63
+
64
+ args = {
65
+ output_format: "json",
66
+ api_key: nil
67
+ }
68
+
69
+ # First positional argument is import_id
70
+ if argv.empty? || argv[0].start_with?("--")
71
+ return args
72
+ end
73
+
74
+ args[:import_id] = argv[0]
75
+ i = 1
76
+
77
+ while i < argv.length
78
+ arg = argv[i]
79
+ case arg
80
+ when "--title"
81
+ args[:title] = argv[i + 1]
82
+ i += 2
83
+ when "--metadata"
84
+ args[:metadata] = parse_json_or_file(argv[i + 1])
85
+ i += 2
86
+ when "--api-key"
87
+ args[:api_key] = argv[i + 1]
88
+ i += 2
89
+ when "--output-format"
90
+ args[:output_format] = argv[i + 1]
91
+ i += 2
92
+ else
93
+ $stderr.puts "Unknown option: #{arg}"
94
+ exit 1
95
+ end
96
+ end
97
+
98
+ args
99
+ end
100
+
101
+ # Main execution
102
+ begin
103
+ args = parse_args(ARGV)
104
+
105
+ # Validate required parameters
106
+ unless args[:import_id]
107
+ $stderr.puts "Error: <import_id> is required"
108
+ $stderr.puts "Run 'exa-ai import-update --help' for usage information"
109
+ exit 1
110
+ end
111
+
112
+ # Validate at least one update parameter provided
113
+ unless args[:title] || args[:metadata]
114
+ $stderr.puts "Error: At least one of --title or --metadata must be provided"
115
+ $stderr.puts "Run 'exa-ai import-update --help' for usage information"
116
+ exit 1
117
+ end
118
+
119
+ # Resolve API key
120
+ api_key = Exa::CLI::Base.resolve_api_key(args[:api_key])
121
+
122
+ # Resolve output format
123
+ output_format = Exa::CLI::Base.resolve_output_format(args[:output_format])
124
+
125
+ # Build client
126
+ client = Exa::CLI::Base.build_client(api_key)
127
+
128
+ # Prepare update parameters (only include provided values)
129
+ update_params = {}
130
+ update_params[:title] = args[:title] if args[:title]
131
+ update_params[:metadata] = args[:metadata] if args[:metadata]
132
+
133
+ # Update import
134
+ import = client.update_import(args[:import_id], **update_params)
135
+
136
+ # Format and output result
137
+ output = Exa::CLI::Formatters::ImportFormatter.format(import, output_format)
138
+ puts output
139
+
140
+ rescue Exa::NotFound => e
141
+ $stderr.puts "Import not found: #{e.message}"
142
+ exit 1
143
+ rescue Exa::ConfigurationError => e
144
+ $stderr.puts "Configuration error: #{e.message}"
145
+ exit 1
146
+ rescue Exa::Unauthorized => e
147
+ $stderr.puts "Authentication error: #{e.message}"
148
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
149
+ exit 1
150
+ rescue Exa::ClientError => e
151
+ $stderr.puts "Client error: #{e.message}"
152
+ exit 1
153
+ rescue Exa::ServerError => e
154
+ $stderr.puts "Server error: #{e.message}"
155
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
156
+ exit 1
157
+ rescue Exa::Error => e
158
+ $stderr.puts "Error: #{e.message}"
159
+ exit 1
160
+ rescue StandardError => e
161
+ $stderr.puts "Unexpected error: #{e.message}"
162
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
163
+ exit 1
164
+ end
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ VALID_BEHAVIOR_TYPES = %w[search refresh].freeze
7
+
8
+ # Recursively convert hash keys from strings to symbols
9
+ def deep_symbolize_keys(obj)
10
+ case obj
11
+ when Hash
12
+ obj.each_with_object({}) do |(key, value), result|
13
+ result[key.to_sym] = deep_symbolize_keys(value)
14
+ end
15
+ when Array
16
+ obj.map { |item| deep_symbolize_keys(item) }
17
+ else
18
+ obj
19
+ end
20
+ end
21
+
22
+ # Parse JSON string or load from file (supports @file.json syntax)
23
+ def parse_json_or_file(value)
24
+ json_data = if value.start_with?("@")
25
+ file_path = value[1..]
26
+ JSON.parse(File.read(file_path))
27
+ else
28
+ JSON.parse(value)
29
+ end
30
+ deep_symbolize_keys(json_data)
31
+ rescue JSON::ParserError => e
32
+ $stderr.puts "Error: Invalid JSON: #{e.message}"
33
+ exit 1
34
+ rescue Errno::ENOENT => e
35
+ $stderr.puts "Error: File not found: #{e.message}"
36
+ exit 1
37
+ end
38
+
39
+ # Parse command-line arguments
40
+ def parse_args(argv)
41
+ # Check for help first
42
+ if argv.include?("--help") || argv.include?("-h")
43
+ puts <<~HELP
44
+ Usage: exa-ai monitor-create <webset_id> --cron EXPR --timezone TZ --behavior-type TYPE [OPTIONS]
45
+
46
+ Create a new monitor to automate webset updates on a schedule
47
+
48
+ Required:
49
+ <webset_id> Webset ID
50
+ --cron EXPR Cron expression (e.g., "0 0 * * *" for daily at midnight)
51
+ --timezone TZ Timezone (e.g., "America/New_York")
52
+ --behavior-type TYPE One of: #{VALID_BEHAVIOR_TYPES.join(', ')}
53
+
54
+ For search behavior:
55
+ --query TEXT Search query (required for search behavior)
56
+ --count N Number of results (optional)
57
+ --behavior-mode MODE Mode: override or append (optional, default: append)
58
+
59
+ Other options:
60
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
61
+ --output-format FMT Output format: json, pretty, or text (default: json)
62
+ --help, -h Show this help message
63
+
64
+ Examples:
65
+ # Create a search monitor
66
+ exa-ai monitor-create ws_123 --cron "0 0 * * *" --timezone "America/New_York" \\
67
+ --behavior-type search --query "AI startups in San Francisco" --count 50
68
+
69
+ # Create a refresh monitor
70
+ exa-ai monitor-create ws_123 --cron "0 */6 * * *" --timezone "UTC" \\
71
+ --behavior-type refresh
72
+ HELP
73
+ exit 0
74
+ end
75
+
76
+ args = {
77
+ output_format: "json",
78
+ api_key: nil
79
+ }
80
+
81
+ # First, check for positional argument (webset_id)
82
+ if argv.empty? || argv[0].start_with?("--")
83
+ return args
84
+ end
85
+
86
+ args[:webset_id] = argv[0]
87
+ i = 1
88
+
89
+ while i < argv.length
90
+ arg = argv[i]
91
+ case arg
92
+ when "--cron"
93
+ args[:cron] = argv[i + 1]
94
+ i += 2
95
+ when "--timezone"
96
+ args[:timezone] = argv[i + 1]
97
+ i += 2
98
+ when "--behavior-type"
99
+ args[:behavior_type] = argv[i + 1]
100
+ i += 2
101
+ when "--query"
102
+ args[:query] = argv[i + 1]
103
+ i += 2
104
+ when "--count"
105
+ args[:count] = argv[i + 1]&.to_i
106
+ i += 2
107
+ when "--behavior-mode"
108
+ args[:behavior_mode] = argv[i + 1]
109
+ i += 2
110
+ when "--api-key"
111
+ args[:api_key] = argv[i + 1]
112
+ i += 2
113
+ when "--output-format"
114
+ args[:output_format] = argv[i + 1]
115
+ i += 2
116
+ else
117
+ $stderr.puts "Unknown option: #{arg}"
118
+ exit 1
119
+ end
120
+ end
121
+
122
+ args
123
+ end
124
+
125
+ # Validate required arguments
126
+ def validate_args(args)
127
+ unless args[:webset_id]
128
+ $stderr.puts "Error: webset_id argument is required"
129
+ $stderr.puts "Usage: exa-ai monitor-create <webset_id> --cron EXPR --timezone TZ --behavior-type TYPE [OPTIONS]"
130
+ $stderr.puts "Try 'exa-ai monitor-create --help' for more information"
131
+ exit 1
132
+ end
133
+
134
+ unless args[:cron]
135
+ $stderr.puts "Error: --cron is required"
136
+ $stderr.puts "Try 'exa-ai monitor-create --help' for more information"
137
+ exit 1
138
+ end
139
+
140
+ unless args[:timezone]
141
+ $stderr.puts "Error: --timezone is required"
142
+ $stderr.puts "Try 'exa-ai monitor-create --help' for more information"
143
+ exit 1
144
+ end
145
+
146
+ unless args[:behavior_type]
147
+ $stderr.puts "Error: --behavior-type is required"
148
+ $stderr.puts "Try 'exa-ai monitor-create --help' for more information"
149
+ exit 1
150
+ end
151
+
152
+ unless VALID_BEHAVIOR_TYPES.include?(args[:behavior_type])
153
+ $stderr.puts "Error: --behavior-type must be one of: #{VALID_BEHAVIOR_TYPES.join(', ')}"
154
+ exit 1
155
+ end
156
+
157
+ # Validate search behavior requirements
158
+ if args[:behavior_type] == "search" && !args[:query]
159
+ $stderr.puts "Error: --query is required for search behavior"
160
+ $stderr.puts "Try 'exa-ai monitor-create --help' for more information"
161
+ exit 1
162
+ end
163
+ end
164
+
165
+ # Main execution
166
+ args = parse_args(ARGV)
167
+ validate_args(args)
168
+
169
+ begin
170
+ # Resolve API key and format
171
+ api_key = Exa::CLI::Base.resolve_api_key(args[:api_key])
172
+ output_format = Exa::CLI::Base.resolve_output_format(args[:output_format])
173
+
174
+ # Build client
175
+ client = Exa::CLI::Base.build_client(api_key)
176
+
177
+ # Build cadence object
178
+ cadence = {
179
+ cron: args[:cron],
180
+ timezone: args[:timezone]
181
+ }
182
+
183
+ # Build behavior object
184
+ behavior = {type: args[:behavior_type]}
185
+ if args[:behavior_type] == "search"
186
+ behavior[:query] = args[:query]
187
+ behavior[:count] = args[:count] if args[:count]
188
+ behavior[:mode] = args[:behavior_mode] || "append"
189
+ end
190
+
191
+ # Create monitor
192
+ monitor = client.create_monitor(
193
+ webset_id: args[:webset_id],
194
+ cadence: cadence,
195
+ behavior: behavior
196
+ )
197
+
198
+ # Format and output
199
+ output = Exa::CLI::Formatters::MonitorFormatter.format(monitor, output_format)
200
+ puts output
201
+
202
+ rescue Exa::ConfigurationError => e
203
+ $stderr.puts "Configuration error: #{e.message}"
204
+ exit 1
205
+ rescue Exa::Unauthorized => e
206
+ $stderr.puts "Authentication error: #{e.message}"
207
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
208
+ exit 1
209
+ rescue Exa::ClientError => e
210
+ $stderr.puts "Client error: #{e.message}"
211
+ exit 1
212
+ rescue Exa::ServerError => e
213
+ $stderr.puts "Server error: #{e.message}"
214
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
215
+ exit 1
216
+ rescue Exa::Error => e
217
+ $stderr.puts "Error: #{e.message}"
218
+ exit 1
219
+ rescue StandardError => e
220
+ $stderr.puts "Unexpected error: #{e.message}"
221
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
222
+ exit 1
223
+ end
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ # Parse arguments
7
+ monitor_id = nil
8
+ api_key = nil
9
+ output_format = "json"
10
+
11
+ args = ARGV.dup
12
+ while args.any?
13
+ arg = args.shift
14
+ case arg
15
+ when "--api-key"
16
+ api_key = args.shift
17
+ when "--output-format"
18
+ output_format = args.shift
19
+ when "--help", "-h"
20
+ puts <<~HELP
21
+ Usage: exa-ai monitor-delete <monitor_id> [OPTIONS]
22
+
23
+ Delete a monitor
24
+
25
+ Arguments:
26
+ monitor_id ID of the monitor to delete (required)
27
+
28
+ Options:
29
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
30
+ --output-format FMT Output format: json, pretty, or text (default: json)
31
+ --help, -h Show this help message
32
+
33
+ Examples:
34
+ exa-ai monitor-delete mon_abc123
35
+ exa-ai monitor-delete mon_abc123 --output-format pretty
36
+ HELP
37
+ exit 0
38
+ else
39
+ # First positional argument is monitor_id
40
+ if monitor_id.nil?
41
+ monitor_id = arg
42
+ else
43
+ $stderr.puts "Unknown option: #{arg}"
44
+ exit 1
45
+ end
46
+ end
47
+ end
48
+
49
+ # Validate
50
+ if monitor_id.nil?
51
+ $stderr.puts "Error: monitor_id argument is required"
52
+ $stderr.puts "Usage: exa-ai monitor-delete <monitor_id> [OPTIONS]"
53
+ $stderr.puts "Try 'exa-ai monitor-delete --help' for more information"
54
+ exit 1
55
+ end
56
+
57
+ begin
58
+ # Resolve API key and format
59
+ api_key = Exa::CLI::Base.resolve_api_key(api_key)
60
+ output_format = Exa::CLI::Base.resolve_output_format(output_format)
61
+
62
+ # Build client
63
+ client = Exa::CLI::Base.build_client(api_key)
64
+
65
+ # Delete monitor
66
+ result = client.delete_monitor(monitor_id)
67
+
68
+ # Format and output
69
+ output = case output_format
70
+ when "json"
71
+ JSON.generate(result)
72
+ when "pretty"
73
+ JSON.pretty_generate(result)
74
+ when "text"
75
+ "Monitor #{monitor_id} deleted successfully"
76
+ else
77
+ raise ArgumentError, "Unknown output format: #{output_format}"
78
+ end
79
+ puts output
80
+
81
+ rescue Exa::NotFound => e
82
+ $stderr.puts "Monitor not found: #{e.message}"
83
+ exit 1
84
+ rescue Exa::Unauthorized => e
85
+ $stderr.puts "Authentication error: #{e.message}"
86
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
87
+ exit 1
88
+ rescue Exa::ClientError => e
89
+ $stderr.puts "Client error: #{e.message}"
90
+ exit 1
91
+ rescue Exa::ServerError => e
92
+ $stderr.puts "Server error: #{e.message}"
93
+ exit 1
94
+ rescue Exa::Error => e
95
+ $stderr.puts "Error: #{e.message}"
96
+ exit 1
97
+ rescue StandardError => e
98
+ $stderr.puts "Unexpected error: #{e.message}"
99
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
100
+ exit 1
101
+ end