exa-ai 0.5.0 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/exe/exa-ai +55 -1
  4. data/exe/exa-ai-import-create +235 -0
  5. data/exe/exa-ai-import-delete +92 -0
  6. data/exe/exa-ai-import-get +92 -0
  7. data/exe/exa-ai-import-list +72 -0
  8. data/exe/exa-ai-import-update +164 -0
  9. data/exe/exa-ai-monitor-create +223 -0
  10. data/exe/exa-ai-monitor-delete +101 -0
  11. data/exe/exa-ai-monitor-get +92 -0
  12. data/exe/exa-ai-monitor-list +90 -0
  13. data/exe/exa-ai-monitor-runs-get +103 -0
  14. data/exe/exa-ai-monitor-runs-list +110 -0
  15. data/exe/exa-ai-monitor-update +207 -0
  16. data/exe/exa-ai-webset-create +43 -6
  17. data/lib/exa/cli/base.rb +8 -2
  18. data/lib/exa/cli/formatters/answer_formatter.rb +2 -0
  19. data/lib/exa/cli/formatters/contents_formatter.rb +2 -0
  20. data/lib/exa/cli/formatters/context_formatter.rb +2 -0
  21. data/lib/exa/cli/formatters/enrichment_formatter.rb +4 -0
  22. data/lib/exa/cli/formatters/import_formatter.rb +85 -0
  23. data/lib/exa/cli/formatters/monitor_formatter.rb +81 -0
  24. data/lib/exa/cli/formatters/monitor_run_formatter.rb +75 -0
  25. data/lib/exa/cli/formatters/research_formatter.rb +4 -0
  26. data/lib/exa/cli/formatters/search_formatter.rb +2 -0
  27. data/lib/exa/cli/formatters/webset_formatter.rb +4 -0
  28. data/lib/exa/cli/formatters/webset_item_formatter.rb +4 -0
  29. data/lib/exa/client.rb +137 -0
  30. data/lib/exa/constants/websets.rb +19 -0
  31. data/lib/exa/resources/import.rb +86 -0
  32. data/lib/exa/resources/import_collection.rb +33 -0
  33. data/lib/exa/resources/monitor.rb +48 -0
  34. data/lib/exa/resources/monitor_collection.rb +30 -0
  35. data/lib/exa/resources/monitor_run.rb +52 -0
  36. data/lib/exa/resources/monitor_run_collection.rb +30 -0
  37. data/lib/exa/services/websets/create_validator.rb +5 -3
  38. data/lib/exa/services/websets/import_create.rb +40 -0
  39. data/lib/exa/services/websets/import_delete.rb +37 -0
  40. data/lib/exa/services/websets/import_get.rb +37 -0
  41. data/lib/exa/services/websets/import_list.rb +25 -0
  42. data/lib/exa/services/websets/import_update.rb +38 -0
  43. data/lib/exa/services/websets/import_upload.rb +58 -0
  44. data/lib/exa/services/websets/monitors/create.rb +42 -0
  45. data/lib/exa/services/websets/monitors/delete.rb +32 -0
  46. data/lib/exa/services/websets/monitors/get.rb +33 -0
  47. data/lib/exa/services/websets/monitors/list.rb +27 -0
  48. data/lib/exa/services/websets/monitors/runs/get.rb +37 -0
  49. data/lib/exa/services/websets/monitors/runs/list.rb +30 -0
  50. data/lib/exa/services/websets/monitors/update.rb +33 -0
  51. data/lib/exa/version.rb +1 -1
  52. data/lib/exa.rb +23 -0
  53. metadata +50 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f9d0670c6b642073a66e32d8ecdd46702931e4b17f66bd6970b976a51ec5c56
4
- data.tar.gz: 2f9126068c6e0672cf7ac67b2d18e188396dbd3785285c4683b2deb99b97d14d
3
+ metadata.gz: 4458cc74fb6924d5e7e57300ba28ae1db399d0d89bf68495b1203f5fe29d73d2
4
+ data.tar.gz: 00b7f59be62aad198438660acdec2e1a2e3c86539bd1a462c4ea03f45c08a87b
5
5
  SHA512:
6
- metadata.gz: 70e7be7fd10d14c69dd1b3125e453c9aa5a7233fb5f618233b8e3af0b42c7546a02b7cb34b9a20f9bb25b0f235f5b6fcbecefbaa5c33393720a47200b1443d93
7
- data.tar.gz: 3ef41b82e7126b4f875a3acddeaf046293a75e2d6cae3a03ea1c3ab46dc5ba9d8ade004add9e5f588876b7cdc4bf7a6c4f27d6be08a42b31e29a7ec3a987dd4f
6
+ metadata.gz: b45e4d6a35d33910e9ce4b154b1b432efba13732b9c237ab94da5962944fae65bf3562a426dc9fa9c18af8c820e8db5d1a4ae3417605d171a136de2d01f149db
7
+ data.tar.gz: 98f082e62eeef3cf7851abcda1cdd61ee5edd548c2cd0d5a65b7645510248ebd0a2274b743e83b7ff354e1ebb4016a92ab83e8a4f93300c255d298fdb9a2683b
data/README.md CHANGED
@@ -128,6 +128,15 @@ exa-ai enrichment-get WEBSET_ID ENRICHMENT_ID
128
128
  exa-ai enrichment-update WEBSET_ID ENRICHMENT_ID --description "Updated description"
129
129
  exa-ai enrichment-delete WEBSET_ID ENRICHMENT_ID --force
130
130
  exa-ai enrichment-cancel WEBSET_ID ENRICHMENT_ID
131
+
132
+ # Webset Imports
133
+ exa-ai webset-import-create companies.csv --count 100 --title "My Companies" --format csv --entity-type company
134
+ exa-ai webset-import-create data.csv --count 50 --title "Tech Startups" --format csv --entity-type company --csv-identifier 0
135
+ exa-ai webset-import-create import.csv --count 100 --title "Import" --format csv --entity-type company --metadata '{"source":"crm"}' --quiet
136
+ exa-ai webset-import-list
137
+ exa-ai webset-import-get IMPORT_ID
138
+ exa-ai webset-import-update IMPORT_ID --title "Updated Title"
139
+ exa-ai webset-import-delete IMPORT_ID
131
140
  ```
132
141
 
133
142
  ## Features
@@ -150,6 +159,7 @@ The gem provides complete access to Exa's API endpoints:
150
159
  - **Webset Searches** — Run searches within websets and manage search tasks
151
160
  - **Webset Items** — List, retrieve, and manage individual items in websets
152
161
  - **Enrichments** — Create and manage AI-powered data enrichment tasks on websets
162
+ - **Imports** — Upload CSV files to import external data into websets
153
163
 
154
164
  ## Error Handling
155
165
 
data/exe/exa-ai CHANGED
@@ -32,7 +32,19 @@ module ExaCLI
32
32
  "enrichment-list" => "List enrichments",
33
33
  "enrichment-update" => "Update an enrichment",
34
34
  "enrichment-delete" => "Delete an enrichment",
35
- "enrichment-cancel" => "Cancel an enrichment"
35
+ "enrichment-cancel" => "Cancel an enrichment",
36
+ "import-create" => "Create a new import",
37
+ "import-list" => "List imports",
38
+ "import-get" => "Get import details",
39
+ "import-update" => "Update an import",
40
+ "import-delete" => "Delete an import",
41
+ "monitor-create" => "Create a webset monitor",
42
+ "monitor-get" => "Get monitor details",
43
+ "monitor-list" => "List monitors",
44
+ "monitor-update" => "Update a monitor",
45
+ "monitor-delete" => "Delete a monitor",
46
+ "monitor-runs-list" => "List monitor runs",
47
+ "monitor-runs-get" => "Get monitor run details"
36
48
  }.freeze
37
49
 
38
50
  def self.run
@@ -98,6 +110,30 @@ module ExaCLI
98
110
  exec File.expand_path("../exa-ai-enrichment-delete", __FILE__), *ARGV[1..]
99
111
  when "enrichment-cancel"
100
112
  exec File.expand_path("../exa-ai-enrichment-cancel", __FILE__), *ARGV[1..]
113
+ when "import-create"
114
+ exec File.expand_path("../exa-ai-import-create", __FILE__), *ARGV[1..]
115
+ when "import-list"
116
+ exec File.expand_path("../exa-ai-import-list", __FILE__), *ARGV[1..]
117
+ when "import-get"
118
+ exec File.expand_path("../exa-ai-import-get", __FILE__), *ARGV[1..]
119
+ when "import-update"
120
+ exec File.expand_path("../exa-ai-import-update", __FILE__), *ARGV[1..]
121
+ when "import-delete"
122
+ exec File.expand_path("../exa-ai-import-delete", __FILE__), *ARGV[1..]
123
+ when "monitor-create"
124
+ exec File.expand_path("../exa-ai-monitor-create", __FILE__), *ARGV[1..]
125
+ when "monitor-get"
126
+ exec File.expand_path("../exa-ai-monitor-get", __FILE__), *ARGV[1..]
127
+ when "monitor-list"
128
+ exec File.expand_path("../exa-ai-monitor-list", __FILE__), *ARGV[1..]
129
+ when "monitor-update"
130
+ exec File.expand_path("../exa-ai-monitor-update", __FILE__), *ARGV[1..]
131
+ when "monitor-delete"
132
+ exec File.expand_path("../exa-ai-monitor-delete", __FILE__), *ARGV[1..]
133
+ when "monitor-runs-list"
134
+ exec File.expand_path("../exa-ai-monitor-runs-list", __FILE__), *ARGV[1..]
135
+ when "monitor-runs-get"
136
+ exec File.expand_path("../exa-ai-monitor-runs-get", __FILE__), *ARGV[1..]
101
137
  else
102
138
  print_error_for_command(ARGV[0])
103
139
  exit 1
@@ -154,6 +190,24 @@ module ExaCLI
154
190
  ["enrichment-cancel", "Cancel an enrichment"]
155
191
  ])
156
192
 
193
+ print_command_section("Imports", [
194
+ ["import-create", "Create a new import"],
195
+ ["import-list", "List imports"],
196
+ ["import-get", "Get import details"],
197
+ ["import-update", "Update an import"],
198
+ ["import-delete", "Delete an import"]
199
+ ])
200
+
201
+ print_command_section("Webset Monitors", [
202
+ ["monitor-create", "Create a webset monitor"],
203
+ ["monitor-get", "Get monitor details"],
204
+ ["monitor-list", "List monitors"],
205
+ ["monitor-update", "Update a monitor"],
206
+ ["monitor-delete", "Delete a monitor"],
207
+ ["monitor-runs-list", "List monitor runs"],
208
+ ["monitor-runs-get", "Get monitor run details"]
209
+ ])
210
+
157
211
  puts "Global Options:"
158
212
  puts " --help, -h Show this help message"
159
213
  puts " --version Show version number"
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "exa-ai"
5
+
6
+ VALID_FORMATS = Exa::Constants::Websets::IMPORT_FORMATS
7
+ VALID_ENTITY_TYPES = Exa::Constants::Websets::ENTITY_TYPES
8
+
9
+ # Recursively convert hash keys from strings to symbols
10
+ def deep_symbolize_keys(obj)
11
+ case obj
12
+ when Hash
13
+ obj.each_with_object({}) do |(key, value), result|
14
+ result[key.to_sym] = deep_symbolize_keys(value)
15
+ end
16
+ when Array
17
+ obj.map { |item| deep_symbolize_keys(item) }
18
+ else
19
+ obj
20
+ end
21
+ end
22
+
23
+ # Parse JSON string or load from file (supports @file.json syntax)
24
+ def parse_json_or_file(value)
25
+ json_data = if value.start_with?("@")
26
+ file_path = value[1..]
27
+ JSON.parse(File.read(file_path))
28
+ else
29
+ JSON.parse(value)
30
+ end
31
+ deep_symbolize_keys(json_data)
32
+ rescue JSON::ParserError => e
33
+ $stderr.puts "Error: Invalid JSON: #{e.message}"
34
+ exit 1
35
+ rescue Errno::ENOENT => e
36
+ $stderr.puts "Error: File not found: #{e.message}"
37
+ exit 1
38
+ end
39
+
40
+ # Parse command-line arguments
41
+ def parse_args(argv)
42
+ # Check for help first
43
+ if argv.include?("--help") || argv.include?("-h")
44
+ puts <<~HELP
45
+ Usage: exa-ai import-create FILE [OPTIONS]
46
+
47
+ Create a new import and upload external data file
48
+
49
+ Arguments:
50
+ FILE Path to the CSV file to upload
51
+
52
+ Required:
53
+ --count N Number of entities in the import
54
+ --title TEXT Display title
55
+ --format TYPE Format type (default: csv, options: #{VALID_FORMATS.join(', ')})
56
+ --entity-type TYPE Entity type (options: #{VALID_ENTITY_TYPES.join(', ')})
57
+
58
+ Options:
59
+ --csv-identifier N CSV column identifier (0-indexed)
60
+ --metadata JSON Custom metadata (supports @file.json)
61
+ --quiet Suppress normal output (only show errors)
62
+ --api-key KEY Exa API key (or set EXA_API_KEY env var)
63
+ --output-format FMT Output format: json, pretty, or text (default: json)
64
+ --help, -h Show this help message
65
+
66
+ Examples:
67
+ exa-ai import-create data.csv --count 100 --title "My Companies" --format csv --entity-type company
68
+ exa-ai import-create companies.csv --count 50 --title "Tech Startups" --format csv --entity-type company --csv-identifier 0
69
+ exa-ai import-create import.csv --count 100 --title "Import" --format csv --entity-type company --metadata '{"source":"crm"}' --quiet
70
+ HELP
71
+ exit 0
72
+ end
73
+
74
+ # First argument should be the file path
75
+ if argv.empty? || argv[0].start_with?("--")
76
+ $stderr.puts "Error: FILE argument is required"
77
+ $stderr.puts "Run 'exa-ai import-create --help' for usage information"
78
+ exit 1
79
+ end
80
+
81
+ args = {
82
+ file_path: argv[0],
83
+ output_format: "json",
84
+ api_key: nil,
85
+ format: "csv",
86
+ quiet: false
87
+ }
88
+
89
+ i = 1 # Start after the file path
90
+ while i < argv.length
91
+ arg = argv[i]
92
+ case arg
93
+ when "--count"
94
+ args[:count] = argv[i + 1].to_i
95
+ i += 2
96
+ when "--title"
97
+ args[:title] = argv[i + 1]
98
+ i += 2
99
+ when "--format"
100
+ args[:format] = argv[i + 1]
101
+ i += 2
102
+ when "--entity-type"
103
+ args[:entity_type] = argv[i + 1]
104
+ i += 2
105
+ when "--csv-identifier"
106
+ args[:csv_identifier] = argv[i + 1].to_i
107
+ i += 2
108
+ when "--metadata"
109
+ args[:metadata] = parse_json_or_file(argv[i + 1])
110
+ i += 2
111
+ when "--quiet"
112
+ args[:quiet] = true
113
+ i += 1
114
+ when "--api-key"
115
+ args[:api_key] = argv[i + 1]
116
+ i += 2
117
+ when "--output-format"
118
+ args[:output_format] = argv[i + 1]
119
+ i += 2
120
+ else
121
+ $stderr.puts "Unknown option: #{arg}"
122
+ exit 1
123
+ end
124
+ end
125
+
126
+ args
127
+ end
128
+
129
+ # Main execution
130
+ begin
131
+ args = parse_args(ARGV)
132
+
133
+ # Validate required parameters
134
+ unless args[:count]
135
+ $stderr.puts "Error: --count is required"
136
+ $stderr.puts "Run 'exa-ai import-create --help' for usage information"
137
+ exit 1
138
+ end
139
+
140
+ unless args[:title]
141
+ $stderr.puts "Error: --title is required"
142
+ $stderr.puts "Run 'exa-ai import-create --help' for usage information"
143
+ exit 1
144
+ end
145
+
146
+ unless args[:entity_type]
147
+ $stderr.puts "Error: --entity-type is required"
148
+ $stderr.puts "Run 'exa-ai import-create --help' for usage information"
149
+ exit 1
150
+ end
151
+
152
+ # Validate format
153
+ unless VALID_FORMATS.include?(args[:format])
154
+ $stderr.puts "Error: format must be one of: #{VALID_FORMATS.join(', ')}"
155
+ exit 1
156
+ end
157
+
158
+ # Validate entity type
159
+ unless VALID_ENTITY_TYPES.include?(args[:entity_type])
160
+ $stderr.puts "Error: entity-type must be one of: #{VALID_ENTITY_TYPES.join(', ')}"
161
+ exit 1
162
+ end
163
+
164
+ # Validate file exists
165
+ unless File.exist?(args[:file_path])
166
+ $stderr.puts "Error: File not found: #{args[:file_path]}"
167
+ exit 1
168
+ end
169
+
170
+ # Resolve API key
171
+ api_key = Exa::CLI::Base.resolve_api_key(args[:api_key])
172
+
173
+ # Resolve output format
174
+ output_format = Exa::CLI::Base.resolve_output_format(args[:output_format])
175
+
176
+ # Build client
177
+ client = Exa::CLI::Base.build_client(api_key)
178
+
179
+ # Prepare import parameters
180
+ import_params = {
181
+ file_path: args[:file_path],
182
+ count: args[:count],
183
+ title: args[:title],
184
+ format: args[:format],
185
+ entity: { type: args[:entity_type] }
186
+ }
187
+ import_params[:metadata] = args[:metadata] if args[:metadata]
188
+
189
+ # Add CSV config if csv_identifier provided
190
+ if args[:csv_identifier]
191
+ import_params[:csv] = { identifier: args[:csv_identifier] }
192
+ end
193
+
194
+ # Show upload message unless quiet
195
+ unless args[:quiet]
196
+ file_size = File.size(args[:file_path])
197
+ $stderr.puts "Uploading #{args[:file_path]} (#{file_size} bytes)..."
198
+ end
199
+
200
+ # Upload import
201
+ import = client.upload_import(**import_params)
202
+
203
+ # Show success message unless quiet
204
+ unless args[:quiet]
205
+ $stderr.puts "Upload complete. Import ID: #{import.id}"
206
+ end
207
+
208
+ # Format and output result (unless quiet)
209
+ unless args[:quiet]
210
+ output = Exa::CLI::Formatters::ImportFormatter.format(import, output_format)
211
+ puts output
212
+ end
213
+
214
+ rescue Exa::ConfigurationError => e
215
+ $stderr.puts "Configuration error: #{e.message}"
216
+ exit 1
217
+ rescue Exa::Unauthorized => e
218
+ $stderr.puts "Authentication error: #{e.message}"
219
+ $stderr.puts "Check your API key (set EXA_API_KEY or use --api-key)"
220
+ exit 1
221
+ rescue Exa::ClientError => e
222
+ $stderr.puts "Client error: #{e.message}"
223
+ exit 1
224
+ rescue Exa::ServerError => e
225
+ $stderr.puts "Server error: #{e.message}"
226
+ $stderr.puts "The Exa API may be experiencing issues. Please try again later."
227
+ exit 1
228
+ rescue Exa::Error => e
229
+ $stderr.puts "Error: #{e.message}"
230
+ exit 1
231
+ rescue StandardError => e
232
+ $stderr.puts "Unexpected error: #{e.message}"
233
+ $stderr.puts e.backtrace.first(5) if ENV["DEBUG"]
234
+ exit 1
235
+ end
@@ -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-delete <import_id> [OPTIONS]
22
+
23
+ Delete an import
24
+
25
+ Arguments:
26
+ import_id ID of the import 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 import-delete imp_123
35
+ exa-ai import-delete 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-delete <import_id> [OPTIONS]"
53
+ $stderr.puts "Try 'exa-ai import-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 import
66
+ import = client.delete_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,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