gpterm 0.6.5 → 0.7.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.
- checksums.yaml +4 -4
- data/config/prompts.yml +2 -0
- data/lib/app_config.rb +69 -0
- data/lib/{client.rb → command_generator.rb} +16 -4
- data/lib/gpterm.rb +62 -160
- data/lib/input.rb +31 -0
- data/lib/parse_options.rb +65 -0
- metadata +5 -3
- data/lib/config.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5d7e207cd381258fa26f30cad19add40fef4c0b3931971e9d7c131ec16734fd
|
4
|
+
data.tar.gz: d3c472cf2ac8f979616f2863310aa9fd8ea083384c85ac6a78eaba5397a15899
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 984be150518b40b63ba73a873d0389801c5ab45069be710c2373baa5fe324c538694a5a040c57218388ea0200a3ec38a6d5c2e04d2db803a9e9d91f543781d0e
|
7
|
+
data.tar.gz: 461c55256fc8f71ac54422c95022d921a172f79ec4ef4e59dd31df2d5a123c3d61fcd3013fb5d597701a37285202596342c8b47d768756fb51c8ef485639a868
|
data/config/prompts.yml
CHANGED
@@ -116,3 +116,5 @@ goal_commands: |
|
|
116
116
|
- $$cannot_compute$$ - You cannot create a VALID response to this prompt. The user will be asked to provide a new prompt.
|
117
117
|
|
118
118
|
COMMANDS:
|
119
|
+
refine_commands: |
|
120
|
+
The last response needs some changes. Please take into account this prompt from the user, then refine the commands you provided in the last response.
|
data/lib/app_config.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
require_relative 'input'
|
5
|
+
|
6
|
+
module AppConfig
|
7
|
+
CONFIG_FILE = File.join(Dir.home, '.gpterm', 'config.yml').freeze
|
8
|
+
|
9
|
+
def self.load
|
10
|
+
# Check if the directory exists, if not, create it
|
11
|
+
unless File.directory?(File.dirname(CONFIG_FILE))
|
12
|
+
Dir.mkdir(File.dirname(CONFIG_FILE))
|
13
|
+
end
|
14
|
+
|
15
|
+
unless File.exist?(self::CONFIG_FILE)
|
16
|
+
puts 'Welcome to gpterm! It looks like this is your first time using this application.'.colorize(:magenta)
|
17
|
+
|
18
|
+
new_config = {}
|
19
|
+
puts "Before we get started, we need to configure the application. All the info you provide will be saved in #{self::CONFIG_FILE}.".colorize(:magenta)
|
20
|
+
|
21
|
+
puts "Enter your OpenAI API key's \"SECRET KEY\" value then hit return: ".colorize(:yellow)
|
22
|
+
new_config['openapi_key'] = Input.non_empty
|
23
|
+
|
24
|
+
puts "Your PATH environment variable is: #{ENV['PATH']}".colorize(:magenta)
|
25
|
+
puts 'Are you happy for your PATH to be sent to OpenAI to help with command generation? (Y/n then hit return) '.colorize(:yellow)
|
26
|
+
|
27
|
+
input = Input.yes_or_no
|
28
|
+
|
29
|
+
if input == 'y'
|
30
|
+
new_config['send_path'] = true
|
31
|
+
else
|
32
|
+
new_config['send_path'] = false
|
33
|
+
end
|
34
|
+
|
35
|
+
default_model = 'gpt-4-turbo-preview'
|
36
|
+
|
37
|
+
puts "The default model is #{default_model}. If you would like to change it please enter the name of your preferred model:".colorize(:yellow)
|
38
|
+
new_config['model'] = STDIN.gets.chomp.strip || default_model
|
39
|
+
|
40
|
+
self.save_config(new_config)
|
41
|
+
|
42
|
+
puts "Configuration saved to #{self::CONFIG_FILE}".colorize(:green)
|
43
|
+
|
44
|
+
new_config
|
45
|
+
else
|
46
|
+
self.load_config_from_file
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.load_config_from_file
|
51
|
+
YAML.load_file(CONFIG_FILE)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.save_config(config)
|
55
|
+
File.write(CONFIG_FILE, config.to_yaml)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.add_openapi_key(config, openapi_key)
|
59
|
+
config['openapi_key'] = openapi_key
|
60
|
+
save_config(config)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.add_preset(config, preset_name, preset_prompt)
|
64
|
+
# This is a YAML file so we need to make sure the presets key exists
|
65
|
+
config['presets'] ||= {}
|
66
|
+
config['presets'][preset_name] = preset_prompt
|
67
|
+
save_config(config)
|
68
|
+
end
|
69
|
+
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
require "openai"
|
2
1
|
require 'yaml'
|
3
2
|
|
4
|
-
class
|
3
|
+
class CommandGenerator
|
5
4
|
attr_reader :openai_client
|
6
5
|
attr_reader :config
|
7
6
|
|
8
|
-
def initialize(config)
|
7
|
+
def initialize(config, openai_client)
|
9
8
|
@config = config
|
10
|
-
@openai_client =
|
9
|
+
@openai_client = openai_client
|
11
10
|
@prompts = YAML.load_file(File.join(__dir__, '..', 'config', 'prompts.yml'))
|
12
11
|
end
|
13
12
|
|
@@ -74,6 +73,19 @@ class Client
|
|
74
73
|
continue_conversation(goal_commands_prompt)
|
75
74
|
end
|
76
75
|
|
76
|
+
def refine_last_response(prompt)
|
77
|
+
refinement_prompt = @prompts["refine_commands"]
|
78
|
+
|
79
|
+
refinement_prompt += <<~PROMPT
|
80
|
+
|
81
|
+
#{prompt}
|
82
|
+
|
83
|
+
COMMANDS:
|
84
|
+
PROMPT
|
85
|
+
|
86
|
+
continue_conversation(refinement_prompt)
|
87
|
+
end
|
88
|
+
|
77
89
|
private
|
78
90
|
|
79
91
|
def continue_conversation(prompt)
|
data/lib/gpterm.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
require 'optparse'
|
2
1
|
require 'colorize'
|
3
2
|
require 'open3'
|
3
|
+
require "openai"
|
4
4
|
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
5
|
+
require_relative 'app_config'
|
6
|
+
require_relative 'command_generator'
|
7
|
+
require_relative 'parse_options'
|
8
|
+
require_relative 'input'
|
7
9
|
|
8
10
|
# The colours work like this:
|
9
11
|
# - Output from STDOUT or STDERR is default
|
@@ -14,9 +16,10 @@ require_relative 'client'
|
|
14
16
|
|
15
17
|
class GPTerm
|
16
18
|
def initialize
|
17
|
-
@config =
|
18
|
-
@options =
|
19
|
-
@
|
19
|
+
@config = AppConfig.load
|
20
|
+
@options = ParseOptions.call(@config)
|
21
|
+
@openai_client = OpenAI::Client.new(access_token: @config["openapi_key"])
|
22
|
+
@command_generator = CommandGenerator.new(@config, @openai_client)
|
20
23
|
end
|
21
24
|
|
22
25
|
def run
|
@@ -47,93 +50,35 @@ class GPTerm
|
|
47
50
|
exit
|
48
51
|
end
|
49
52
|
|
50
|
-
# Ensures the user enters "y" or "n"
|
51
|
-
def get_yes_or_no
|
52
|
-
input = STDIN.gets.chomp.downcase
|
53
|
-
while ['y', 'n'].include?(input) == false
|
54
|
-
puts 'Please enter "y/Y" or "n/N":'.colorize(:yellow)
|
55
|
-
input = STDIN.gets.chomp.downcase
|
56
|
-
end
|
57
|
-
input
|
58
|
-
end
|
59
|
-
|
60
|
-
# Ensures the user enters a non-empty value
|
61
|
-
def get_non_empty_input
|
62
|
-
input = STDIN.gets.chomp.strip
|
63
|
-
while input.length == 0
|
64
|
-
puts 'Please enter a non-empty value:'.colorize(:yellow)
|
65
|
-
input = STDIN.gets.chomp.strip
|
66
|
-
end
|
67
|
-
input
|
68
|
-
end
|
69
|
-
|
70
53
|
def start_conversation(prompt)
|
71
|
-
|
54
|
+
shell_output = gather_information_from_shell(prompt)
|
72
55
|
|
73
|
-
|
74
|
-
exit_with_message('Sorry, a command could not be generated for that prompt. Try another.', :red)
|
75
|
-
end
|
76
|
-
|
77
|
-
if message.downcase == '$$no_gathering_needed$$'
|
78
|
-
puts 'No information gathering needed'.colorize(:magenta)
|
79
|
-
output = "No information gathering was needed."
|
80
|
-
elsif message.downcase == '$$cannot_compute$$'
|
81
|
-
exit_with_message('Sorry, a command could not be generated for that prompt. Try another.', :red)
|
82
|
-
else
|
83
|
-
puts 'Information gathering command:'.colorize(:magenta)
|
84
|
-
puts message.gsub(/^/, "#{" $".colorize(:blue)} ")
|
85
|
-
puts 'Do you want to execute this command? (Y/n then hit return)'.colorize(:yellow)
|
86
|
-
continue = get_yes_or_no
|
56
|
+
offer_prompt_response = @command_generator.offer_information_prompt(shell_output, :shell_output_response)
|
87
57
|
|
88
|
-
|
89
|
-
exit
|
90
|
-
end
|
91
|
-
|
92
|
-
puts 'Running command...'
|
93
|
-
output = `#{message}`
|
94
|
-
|
95
|
-
if @config[:verbose]
|
96
|
-
puts 'Output:'
|
97
|
-
puts output
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
output = @client.offer_information_prompt(output, :shell_output_response)
|
102
|
-
|
103
|
-
while output.downcase != '$$no_more_information_needed$$'
|
58
|
+
while offer_prompt_response.downcase != '$$no_more_information_needed$$'
|
104
59
|
puts "You have been asked to provide more information with this command:".colorize(:magenta)
|
105
|
-
puts
|
60
|
+
puts offer_prompt_response.gsub(/^/, "#{" >".colorize(:blue)} ")
|
106
61
|
puts "What is your response? (Type 'skip' to skip this step and force the final command to be generated)".colorize(:yellow)
|
107
62
|
|
108
|
-
|
63
|
+
user_question_response = Input.non_empty
|
109
64
|
|
110
|
-
if
|
111
|
-
|
65
|
+
if user_question_response.downcase == 'skip'
|
66
|
+
offer_prompt_response = '$$no_more_information_needed$$'
|
67
|
+
puts 'Thanks, one moment please...'.colorize(:magenta)
|
112
68
|
else
|
113
|
-
|
69
|
+
offer_prompt_response = @command_generator.offer_information_prompt(user_question_response, :question_response)
|
114
70
|
end
|
115
71
|
end
|
116
72
|
|
117
|
-
puts 'Requesting the next command...'.colorize(:magenta)
|
118
|
-
|
119
|
-
message = @client.final_prompt(output)
|
120
|
-
|
121
|
-
if message.downcase == '$$cannot_compute$$'
|
122
|
-
exit_with_message('Sorry, a command could not be generated for that prompt. Try another.', :red)
|
123
|
-
end
|
124
|
-
|
125
|
-
puts 'Generated command to accomplish your goal:'.colorize(:magenta)
|
126
|
-
puts message.gsub(/^/, "#{" $".colorize(:green)} ")
|
127
|
-
|
128
|
-
puts 'Do you want to execute this command? (Y/n then hit return)'.colorize(:yellow)
|
73
|
+
puts 'Requesting the next command...'.colorize(:magenta) if @config[:verbose]
|
129
74
|
|
130
|
-
|
75
|
+
# TODO: Some redundant info being passed here in the case of
|
76
|
+
# the user answering a question
|
77
|
+
goal_prompt_response = @command_generator.final_prompt(offer_prompt_response)
|
131
78
|
|
132
|
-
|
133
|
-
exit
|
134
|
-
end
|
79
|
+
goal_prompt_response = run_refinement_loop(goal_prompt_response)
|
135
80
|
|
136
|
-
commands =
|
81
|
+
commands = goal_prompt_response.split("\n")
|
137
82
|
|
138
83
|
commands.each do |command|
|
139
84
|
stdout, stderr, exit_status = execute_shell_command(command)
|
@@ -149,101 +94,58 @@ class GPTerm
|
|
149
94
|
end
|
150
95
|
end
|
151
96
|
|
152
|
-
def
|
153
|
-
|
154
|
-
puts 'Welcome to gpterm! It looks like this is your first time using this application.'.colorize(:magenta)
|
155
|
-
|
156
|
-
new_config = {}
|
157
|
-
puts "Before we get started, we need to configure the application. All the info you provide will be saved in #{AppConfig::CONFIG_FILE}.".colorize(:magenta)
|
97
|
+
def gather_information_from_shell(prompt)
|
98
|
+
info_prompt_response = @command_generator.first_prompt(prompt)
|
158
99
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
100
|
+
if info_prompt_response.downcase == '$$no_gathering_needed$$'
|
101
|
+
puts 'No information gathering needed'.colorize(:magenta) if @config[:verbose]
|
102
|
+
shell_output = nil
|
103
|
+
else
|
104
|
+
info_prompt_response = run_refinement_loop(info_prompt_response, 'gather more information for your request')
|
164
105
|
|
165
|
-
|
106
|
+
puts 'Running command...' if @config[:verbose]
|
107
|
+
shell_output = `#{info_prompt_response}`
|
166
108
|
|
167
|
-
if
|
168
|
-
|
169
|
-
|
170
|
-
new_config['send_path'] = false
|
109
|
+
if @config[:verbose]
|
110
|
+
puts 'Shell output:'
|
111
|
+
puts shell_output
|
171
112
|
end
|
172
113
|
|
173
|
-
|
114
|
+
end
|
115
|
+
shell_output
|
116
|
+
end
|
174
117
|
|
175
|
-
|
176
|
-
|
118
|
+
def run_refinement_loop(original_response, purpose = 'accomplish your goal')
|
119
|
+
if original_response.downcase == '$$cannot_compute$$'
|
120
|
+
exit_with_message('Sorry, a command could not be generated for that prompt. Try another.', :red)
|
121
|
+
end
|
177
122
|
|
178
|
-
|
123
|
+
refined_response = original_response.dup
|
179
124
|
|
180
|
-
|
125
|
+
puts "The following command(s) were generated to #{purpose}:".colorize(:magenta)
|
126
|
+
puts refined_response.gsub(/^/, "#{" $".colorize(:green)} ")
|
127
|
+
puts 'Do you want to execute this/these command(s), or refine them with another prompt? (Y/n/r then hit return)'.colorize(:yellow)
|
128
|
+
continue = Input.yes_no_or_refine
|
181
129
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
130
|
+
while continue.downcase == 'r'
|
131
|
+
puts 'Please enter a new prompt:'.colorize(:yellow)
|
132
|
+
new_prompt = Input.non_empty
|
133
|
+
refined_response = @command_generator.refine_last_response(new_prompt)
|
187
134
|
|
188
|
-
|
189
|
-
|
190
|
-
subcommands = {
|
191
|
-
'preset' => {
|
192
|
-
option_parser: OptionParser.new do |opts|
|
193
|
-
opts.banner = "gpterm preset <name> <prompt>"
|
194
|
-
end,
|
195
|
-
argument_parser: ->(args) {
|
196
|
-
if args.length < 2
|
197
|
-
options[:prompt] = @config['presets'][args[0]]
|
198
|
-
else
|
199
|
-
options[:preset_prompt] = [args[0], args[1]]
|
200
|
-
end
|
201
|
-
}
|
202
|
-
},
|
203
|
-
'config' => {
|
204
|
-
option_parser: OptionParser.new do |opts|
|
205
|
-
opts.banner = "gpterm config [--openapi_key <value>|--send_path <true|false>]"
|
206
|
-
opts.on("--openapi_key VALUE", "Set the OpenAI API key") do |v|
|
207
|
-
AppConfig.add_openapi_key(@config, v)
|
208
|
-
exit_with_message("OpenAI API key saved")
|
209
|
-
end
|
210
|
-
opts.on("--send_path", "Send the PATH environment variable to OpenAI") do
|
211
|
-
@config['send_path'] = true
|
212
|
-
AppConfig.save_config(@config)
|
213
|
-
exit_with_message("Your PATH environment variable will be sent to OpenAI to help with command generation")
|
214
|
-
end
|
215
|
-
end
|
216
|
-
}
|
217
|
-
}
|
218
|
-
|
219
|
-
main = OptionParser.new do |opts|
|
220
|
-
opts.banner = "Usage:"
|
221
|
-
opts.banner += "\n\ngpterm <prompt> [options] [subcommand [options]]"
|
222
|
-
opts.banner += "\n\nSubcommands:"
|
223
|
-
subcommands.each do |name, subcommand|
|
224
|
-
opts.banner += "\n #{name} - #{subcommand[:option_parser].banner}"
|
225
|
-
end
|
226
|
-
opts.banner += "\n\nOptions:"
|
227
|
-
opts.on("-v", "--verbose", "Run verbosely") do |v|
|
228
|
-
options[:verbose] = true
|
135
|
+
if refined_response.downcase == '$$cannot_compute$$'
|
136
|
+
exit_with_message('Sorry, a command could not be generated for that prompt. Try another.', :red)
|
229
137
|
end
|
230
|
-
end
|
231
138
|
|
232
|
-
|
139
|
+
puts "The following command(s) were generated to #{purpose}:".colorize(:magenta)
|
140
|
+
puts refined_response.gsub(/^/, "#{" $".colorize(:blue)} ")
|
141
|
+
puts 'Do you want to execute this/these command(s), or refine them with another prompt? (Y/n/r then hit return)'.colorize(:yellow)
|
142
|
+
continue = Input.yes_no_or_refine
|
143
|
+
end
|
233
144
|
|
234
|
-
|
235
|
-
|
236
|
-
subcommands[command][:option_parser].parse!
|
237
|
-
subcommands[command][:argument_parser].call(ARGV) if subcommands[command][:argument_parser]
|
238
|
-
elsif command == 'help'
|
239
|
-
exit_with_message(main)
|
240
|
-
elsif command
|
241
|
-
options[:prompt] = command
|
242
|
-
else
|
243
|
-
puts 'Enter a prompt to generate text from:'.colorize(:yellow)
|
244
|
-
options[:prompt] = get_non_empty_input
|
145
|
+
unless continue.downcase == 'y'
|
146
|
+
exit
|
245
147
|
end
|
246
148
|
|
247
|
-
|
149
|
+
refined_response
|
248
150
|
end
|
249
151
|
end
|
data/lib/input.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Input
|
2
|
+
# Ensures the user enters a non-empty value
|
3
|
+
def self.non_empty
|
4
|
+
input = STDIN.gets.chomp.strip
|
5
|
+
while input.length == 0
|
6
|
+
puts 'Please enter a non-empty value:'.colorize(:yellow)
|
7
|
+
input = STDIN.gets.chomp.strip
|
8
|
+
end
|
9
|
+
input
|
10
|
+
end
|
11
|
+
|
12
|
+
# Ensures the user enters "y" or "n"
|
13
|
+
def self.yes_or_no
|
14
|
+
input = STDIN.gets.chomp.downcase
|
15
|
+
while ['y', 'n'].include?(input) == false
|
16
|
+
puts 'Please enter "y/Y" or "n/N":'.colorize(:yellow)
|
17
|
+
input = STDIN.gets.chomp.downcase
|
18
|
+
end
|
19
|
+
input
|
20
|
+
end
|
21
|
+
|
22
|
+
# Ensures the user enters "y" or "n"
|
23
|
+
def self.yes_no_or_refine
|
24
|
+
input = STDIN.gets.chomp.downcase
|
25
|
+
while ['y', 'n', 'r'].include?(input) == false
|
26
|
+
puts 'Please enter "y/Y", "n/N" or "r/R":'.colorize(:yellow)
|
27
|
+
input = STDIN.gets.chomp.downcase
|
28
|
+
end
|
29
|
+
input
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
class ParseOptions
|
4
|
+
def self.call(config)
|
5
|
+
options = {}
|
6
|
+
subcommands = {
|
7
|
+
'preset' => {
|
8
|
+
option_parser: OptionParser.new do |opts|
|
9
|
+
opts.banner = "gpterm preset <name> <prompt>"
|
10
|
+
end,
|
11
|
+
argument_parser: ->(args) {
|
12
|
+
if args.length < 2
|
13
|
+
options[:prompt] = config['presets'][args[0]]
|
14
|
+
else
|
15
|
+
options[:preset_prompt] = [args[0], args[1]]
|
16
|
+
end
|
17
|
+
}
|
18
|
+
},
|
19
|
+
'config' => {
|
20
|
+
option_parser: OptionParser.new do |opts|
|
21
|
+
opts.banner = "gpterm config [--openapi_key <value>|--send_path <true|false>]"
|
22
|
+
opts.on("--openapi_key VALUE", "Set the OpenAI API key") do |v|
|
23
|
+
AppConfig.add_openapi_key(config, v)
|
24
|
+
exit_with_message("OpenAI API key saved")
|
25
|
+
end
|
26
|
+
opts.on("--send_path", "Send the PATH environment variable to OpenAI") do
|
27
|
+
config['send_path'] = true
|
28
|
+
AppConfig.save_config(config)
|
29
|
+
exit_with_message("Your PATH environment variable will be sent to OpenAI to help with command generation")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
main = OptionParser.new do |opts|
|
36
|
+
opts.banner = "Usage:"
|
37
|
+
opts.banner += "\n\ngpterm <prompt> [options] [subcommand [options]]"
|
38
|
+
opts.banner += "\n\nSubcommands:"
|
39
|
+
subcommands.each do |name, subcommand|
|
40
|
+
opts.banner += "\n #{name} - #{subcommand[:option_parser].banner}"
|
41
|
+
end
|
42
|
+
opts.banner += "\n\nOptions:"
|
43
|
+
opts.on("-v", "--verbose", "Run verbosely") do |v|
|
44
|
+
options[:verbose] = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
command = ARGV.shift
|
49
|
+
|
50
|
+
main.order!
|
51
|
+
if subcommands.key?(command)
|
52
|
+
subcommands[command][:option_parser].parse!
|
53
|
+
subcommands[command][:argument_parser].call(ARGV) if subcommands[command][:argument_parser]
|
54
|
+
elsif command == 'help'
|
55
|
+
exit_with_message(main)
|
56
|
+
elsif command
|
57
|
+
options[:prompt] = command
|
58
|
+
else
|
59
|
+
puts 'Enter a prompt to generate text from:'.colorize(:yellow)
|
60
|
+
options[:prompt] = Input.non_empty
|
61
|
+
end
|
62
|
+
|
63
|
+
options
|
64
|
+
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gpterm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Hough
|
@@ -51,9 +51,11 @@ files:
|
|
51
51
|
- README.md
|
52
52
|
- bin/gpterm
|
53
53
|
- config/prompts.yml
|
54
|
-
- lib/
|
55
|
-
- lib/
|
54
|
+
- lib/app_config.rb
|
55
|
+
- lib/command_generator.rb
|
56
56
|
- lib/gpterm.rb
|
57
|
+
- lib/input.rb
|
58
|
+
- lib/parse_options.rb
|
57
59
|
homepage: https://github.com/basicallydan/gpterm
|
58
60
|
licenses:
|
59
61
|
- MIT
|
data/lib/config.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module AppConfig
|
4
|
-
CONFIG_FILE = File.join(Dir.home, '.gpterm', 'config.yml').freeze
|
5
|
-
|
6
|
-
# Check if the directory exists, if not, create it
|
7
|
-
unless File.directory?(File.dirname(CONFIG_FILE))
|
8
|
-
Dir.mkdir(File.dirname(CONFIG_FILE))
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.load_config
|
12
|
-
YAML.load_file(CONFIG_FILE)
|
13
|
-
rescue Errno::ENOENT
|
14
|
-
default_config
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.save_config(config)
|
18
|
-
File.write(CONFIG_FILE, config.to_yaml)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.add_openapi_key(config, openapi_key)
|
22
|
-
config['openapi_key'] = openapi_key
|
23
|
-
save_config(config)
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.add_preset(config, preset_name, preset_prompt)
|
27
|
-
# This is a YAML file so we need to make sure the presets key exists
|
28
|
-
config['presets'] ||= {}
|
29
|
-
config['presets'][preset_name] = preset_prompt
|
30
|
-
save_config(config)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.default_config
|
34
|
-
{
|
35
|
-
'openapi_key' => ''
|
36
|
-
}
|
37
|
-
end
|
38
|
-
end
|