myask 0.0.1
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 +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +70 -0
- data/README.rdoc +6 -0
- data/Rakefile +21 -0
- data/bin/myask +101 -0
- data/lib/myask/api/api_helper.rb +45 -0
- data/lib/myask/api/invitation.rb +49 -0
- data/lib/myask/api/project.rb +193 -0
- data/lib/myask/api/project_helper.rb +46 -0
- data/lib/myask/api/question.rb +99 -0
- data/lib/myask/config.rb +37 -0
- data/lib/myask/config_helper.rb +28 -0
- data/lib/myask/prompt.rb +63 -0
- data/lib/myask/prompt_helper.rb +80 -0
- data/lib/myask/version.rb +3 -0
- data/lib/myask.rb +28 -0
- data/myask.gemspec +22 -0
- data/myask.rdoc +138 -0
- data/test/default_test.rb +14 -0
- data/test/test_helper.rb +4 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 006a91a281c01fdcecea19680a9d7af0b289f1e4f2caedeefd8b7f2619bf7cfc
|
4
|
+
data.tar.gz: b626f02eda6131712e88acc76c0fa21a600e2e3c0657a6d7461506c461017f38
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b16d43f1e3877f7e925cbcdac03002863ad444d41f6d99edc4d4517a319138daaf76801c73a0aad94c8269ae256ff6bcde3d0db26a42717f10b65469e04a81c5
|
7
|
+
data.tar.gz: 361cb8182fca17368f3d60f2fa06e4b5449994fac7b695d9f52c4f2218295d899832fd03d060bcf23451b1ece43aa21103b12e2cc2b6c34e14161be425a19071
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
myask (0.0.1)
|
5
|
+
gli (~> 2.22.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
byebug (12.0.0)
|
11
|
+
coderay (1.1.3)
|
12
|
+
date (3.4.1)
|
13
|
+
gli (2.22.2)
|
14
|
+
ostruct
|
15
|
+
json (2.10.2)
|
16
|
+
method_source (1.1.0)
|
17
|
+
minitest (5.25.5)
|
18
|
+
open-uri (0.5.0)
|
19
|
+
stringio
|
20
|
+
time
|
21
|
+
uri
|
22
|
+
ostruct (0.6.1)
|
23
|
+
pastel (0.8.0)
|
24
|
+
tty-color (~> 0.5)
|
25
|
+
pry (0.15.2)
|
26
|
+
coderay (~> 1.1)
|
27
|
+
method_source (~> 1.0)
|
28
|
+
pry-byebug (3.11.0)
|
29
|
+
byebug (~> 12.0)
|
30
|
+
pry (>= 0.13, < 0.16)
|
31
|
+
psych (5.2.3)
|
32
|
+
date
|
33
|
+
stringio
|
34
|
+
rake (13.2.1)
|
35
|
+
rdoc (6.13.0)
|
36
|
+
psych (>= 4.0.0)
|
37
|
+
stringio (3.1.6)
|
38
|
+
time (0.4.1)
|
39
|
+
date
|
40
|
+
tty-color (0.6.0)
|
41
|
+
tty-cursor (0.7.1)
|
42
|
+
tty-prompt (0.23.1)
|
43
|
+
pastel (~> 0.8)
|
44
|
+
tty-reader (~> 0.8)
|
45
|
+
tty-reader (0.9.0)
|
46
|
+
tty-cursor (~> 0.7)
|
47
|
+
tty-screen (~> 0.8)
|
48
|
+
wisper (~> 2.0)
|
49
|
+
tty-screen (0.8.2)
|
50
|
+
tty-spinner (0.9.3)
|
51
|
+
tty-cursor (~> 0.7)
|
52
|
+
uri (1.0.3)
|
53
|
+
wisper (2.0.1)
|
54
|
+
|
55
|
+
PLATFORMS
|
56
|
+
arm64-darwin-22
|
57
|
+
|
58
|
+
DEPENDENCIES
|
59
|
+
json (~> 2.10)
|
60
|
+
minitest
|
61
|
+
myask!
|
62
|
+
open-uri (~> 0.5.0)
|
63
|
+
pry-byebug (~> 3.11)
|
64
|
+
rake
|
65
|
+
rdoc
|
66
|
+
tty-prompt (~> 0.23.1)
|
67
|
+
tty-spinner (~> 0.9.3)
|
68
|
+
|
69
|
+
BUNDLED WITH
|
70
|
+
2.4.22
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
Rake::RDocTask.new do |rd|
|
6
|
+
rd.main = "README.rdoc"
|
7
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
8
|
+
rd.title = 'Your application title'
|
9
|
+
end
|
10
|
+
|
11
|
+
spec = Gem::Specification.load("myask.gemspec")
|
12
|
+
|
13
|
+
Gem::PackageTask.new(spec) do |pkg|
|
14
|
+
end
|
15
|
+
require 'rake/testtask'
|
16
|
+
Rake::TestTask.new do |t|
|
17
|
+
t.libs << "test"
|
18
|
+
t.test_files = FileList['test/*_test.rb']
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => :test
|
data/bin/myask
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "gli"
|
3
|
+
require "myask"
|
4
|
+
|
5
|
+
class App
|
6
|
+
extend GLI::App
|
7
|
+
|
8
|
+
config_file ".myask.rc"
|
9
|
+
|
10
|
+
program_desc "Describe your application here"
|
11
|
+
|
12
|
+
version Myask::VERSION
|
13
|
+
|
14
|
+
subcommand_option_handling :normal
|
15
|
+
arguments :strict
|
16
|
+
|
17
|
+
desc "Silent Progress Spinner"
|
18
|
+
default_value false
|
19
|
+
switch [:silent]
|
20
|
+
|
21
|
+
desc "Format Output as JSON"
|
22
|
+
default_value false
|
23
|
+
switch [:json]
|
24
|
+
|
25
|
+
desc "Host for MyAsk API"
|
26
|
+
default_value "https://myask.io"
|
27
|
+
flag [:api_host], type: String
|
28
|
+
|
29
|
+
desc "API Key for MyAsk API"
|
30
|
+
flag [:api_key], type: String
|
31
|
+
|
32
|
+
desc "Current MyAsk Project"
|
33
|
+
flag [:project], type: String
|
34
|
+
|
35
|
+
desc "View current or set new MyAsk configuration values"
|
36
|
+
command :config do |c|
|
37
|
+
MyAsk::Config.new(c)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Send a prompt to MyAsk API"
|
41
|
+
command :prompt do |c|
|
42
|
+
MyAsk::Prompt.new(c)
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Create/show/list/delete MyAsk Project"
|
46
|
+
command :project do |c|
|
47
|
+
MyAsk::Api::Project.new(c)
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Show/delete MyAsk Question"
|
51
|
+
command :question do |c|
|
52
|
+
MyAsk::Api::Question.new(c)
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Create/list MyAsk Invitations"
|
56
|
+
command :invitation do |c|
|
57
|
+
MyAsk::Api::Invitation.new(c)
|
58
|
+
end
|
59
|
+
|
60
|
+
pre do |global,command,options,args|
|
61
|
+
unless command&.parent&.name == :config
|
62
|
+
config = global
|
63
|
+
auth_token = config[:api_key]
|
64
|
+
project = options[:project] || config[:project]
|
65
|
+
|
66
|
+
if auth_token.nil?
|
67
|
+
puts "Missing MyAsk API token. Set it using \"myask config -k YOUR_AUTH_TOKEN\"."
|
68
|
+
exit
|
69
|
+
end
|
70
|
+
|
71
|
+
if project.nil?
|
72
|
+
puts "MyAsk Project Not Set. Set it using \"myask api:project:set\"."
|
73
|
+
exit
|
74
|
+
end
|
75
|
+
end
|
76
|
+
true # false to break command
|
77
|
+
end
|
78
|
+
|
79
|
+
post do |global,command,options,args|
|
80
|
+
# Post logic here
|
81
|
+
# Use skips_post before a command to skip this
|
82
|
+
# block on that command only
|
83
|
+
end
|
84
|
+
|
85
|
+
on_error do |exception|
|
86
|
+
case exception
|
87
|
+
when TTY::Reader::InputInterrupt
|
88
|
+
abort "\n\n--- User Exit ---\n"
|
89
|
+
when SystemExit
|
90
|
+
# abort "Exited"
|
91
|
+
when Errno::ECONNREFUSED
|
92
|
+
abort "API Error: #{exception}"
|
93
|
+
else # RuntimeError
|
94
|
+
puts exception.backtrace
|
95
|
+
binding.pry
|
96
|
+
end
|
97
|
+
false # false to skip default error handling
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
exit App.run(ARGV)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module MyAsk
|
2
|
+
module Api
|
3
|
+
class Helper
|
4
|
+
|
5
|
+
def self.make_request(method, uri, api_key, payload = nil)
|
6
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
7
|
+
http.use_ssl = true if uri.scheme == 'https'
|
8
|
+
|
9
|
+
if method == "Get"
|
10
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
11
|
+
request['Authorization'] = "Bearer #{api_key}"
|
12
|
+
request["Content-Type"] = "application/json"
|
13
|
+
response = http.request(request)
|
14
|
+
elsif method == "Delete"
|
15
|
+
request = Net::HTTP::Delete.new(uri.request_uri)
|
16
|
+
request['Authorization'] = "Bearer #{api_key}"
|
17
|
+
request["Content-Type"] = "application/json"
|
18
|
+
request.body = payload.to_json
|
19
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
20
|
+
http.request(request)
|
21
|
+
end
|
22
|
+
elsif method == "Patch"
|
23
|
+
request = Net::HTTP::Patch.new(uri.request_uri)
|
24
|
+
request['Authorization'] = "Bearer #{api_key}"
|
25
|
+
request["Content-Type"] = "application/json"
|
26
|
+
request.body = payload.to_json
|
27
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
28
|
+
http.request(request)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
32
|
+
request['Authorization'] = "Bearer #{api_key}"
|
33
|
+
request["Content-Type"] = "application/json"
|
34
|
+
request.body = payload.to_json
|
35
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
36
|
+
http.request(request)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
response
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module MyAsk
|
2
|
+
module Api
|
3
|
+
class Invitation
|
4
|
+
|
5
|
+
def initialize(c)
|
6
|
+
c.desc 'List MyAsk invitations.'
|
7
|
+
c.command :list do |c|
|
8
|
+
c.action do |global_options, _options, _args|
|
9
|
+
uri = URI("#{global_options[:api_host]}/api/invitations")
|
10
|
+
response = MyAsk::Api::Helper.make_request("Get", uri, global_options[:api_key])
|
11
|
+
|
12
|
+
puts "Invitation sent successfully:" unless global_options[:json]
|
13
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
c.desc "Send MyAsk invitation to a new user"
|
18
|
+
c.command :send do |c|
|
19
|
+
c.desc "Send MyAsk invitation to a new user"
|
20
|
+
c.flag [:email], desc: "Email of the user to invite to MyAsk"
|
21
|
+
|
22
|
+
c.action do |global_options, options, args|
|
23
|
+
email = options[:email]
|
24
|
+
|
25
|
+
if !email
|
26
|
+
prompt = TTY::Prompt.new
|
27
|
+
email = prompt.ask('Enter invitee email:')
|
28
|
+
end
|
29
|
+
|
30
|
+
payload = {
|
31
|
+
invitation: {
|
32
|
+
email: email
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
uri = URI("#{global_options[:api_host]}/api/invitations")
|
37
|
+
response = MyAsk::Api::Helper.make_request("Post", uri, global_options[:api_key], payload)
|
38
|
+
|
39
|
+
puts "Invitation sent successfully:" unless global_options[:json]
|
40
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
c.default_command :list
|
45
|
+
c
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
module MyAsk
|
2
|
+
module Api
|
3
|
+
class Project
|
4
|
+
|
5
|
+
def initialize(c)
|
6
|
+
c.desc "Show MyAsk Project Details"
|
7
|
+
c.arg_name "project"
|
8
|
+
c.command :show do |c|
|
9
|
+
c.desc "List projects and select to view"
|
10
|
+
c.switch [:l, :list]
|
11
|
+
|
12
|
+
c.flag [:project], desc: "ID of project to display"
|
13
|
+
|
14
|
+
c.action do |global_options, options, args|
|
15
|
+
config = global_options
|
16
|
+
project = options[:project] || config[:project]
|
17
|
+
|
18
|
+
helper = MyAsk::Api::ProjectHelper.new(global_options, options, args)
|
19
|
+
|
20
|
+
project = if options[:list]
|
21
|
+
helper.project_id_from_selection
|
22
|
+
else
|
23
|
+
args[0] || project
|
24
|
+
end
|
25
|
+
|
26
|
+
helper.show_project_info(project)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
c.desc "Set MyAsk Project"
|
31
|
+
c.arg_name "project"
|
32
|
+
c.command :set do |c|
|
33
|
+
c.desc "Set current MyAsk project"
|
34
|
+
c.switch [:l, :list]
|
35
|
+
|
36
|
+
c.flag [:project], desc: "ID of MyAsk Project to display"
|
37
|
+
|
38
|
+
c.action do |global_options, options, args|
|
39
|
+
config = global_options
|
40
|
+
project = options[:project] || config[:project]
|
41
|
+
|
42
|
+
helper = MyAsk::Api::ProjectHelper.new(global_options, options, args)
|
43
|
+
|
44
|
+
project = if options[:list]
|
45
|
+
helper.project_id_from_selection
|
46
|
+
else
|
47
|
+
args[0] || project
|
48
|
+
end
|
49
|
+
|
50
|
+
helper = MyAsk::ConfigHelper.new(global_options, options.merge(project: project), args)
|
51
|
+
response = helper.save_config
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
c.desc "Edit MyAsk Project"
|
56
|
+
c.arg_name "project"
|
57
|
+
c.command :edit do |c|
|
58
|
+
c.desc "Edit MyAsk project"
|
59
|
+
c.switch [:l, :list]
|
60
|
+
|
61
|
+
c.flag [:project], desc: "ID of MyAsk Project to Edit"
|
62
|
+
|
63
|
+
c.action do |global_options, options, args|
|
64
|
+
config = global_options
|
65
|
+
project = options[:project] || config[:project]
|
66
|
+
|
67
|
+
helper = MyAsk::Api::ProjectHelper.new(global_options, options, args)
|
68
|
+
|
69
|
+
project = if options[:list]
|
70
|
+
helper.project_id_from_selection
|
71
|
+
else
|
72
|
+
args[0] || project
|
73
|
+
end
|
74
|
+
|
75
|
+
payload = helper.show_project_info(project)
|
76
|
+
|
77
|
+
ai_models = ["gpt-4o-mini", "o3-mini", "o1-mini", "gpt-3.5-turbo", "gpt-4o", "chatgpt-4o-latest"]
|
78
|
+
|
79
|
+
prompt = TTY::Prompt.new
|
80
|
+
|
81
|
+
payload["project"]["name"] = prompt.read_line("Enter project name:", value: payload["project"]["name"]).strip
|
82
|
+
payload["project"]["description"] = prompt.read_line("Enter project description:", value: payload["project"]["description"]).strip
|
83
|
+
|
84
|
+
payload["project"]["ai_model"] = prompt.enum_select(
|
85
|
+
"Select an AI model for this project:",
|
86
|
+
ai_models,
|
87
|
+
default: payload["project"]["ai_model"]
|
88
|
+
)
|
89
|
+
|
90
|
+
payload["project"]["system_message"] = prompt.read_line(
|
91
|
+
"Enter project system_message (optional):",
|
92
|
+
value: payload["project"]["metadata"]["system_message"]["content"]
|
93
|
+
).strip
|
94
|
+
|
95
|
+
puts payload
|
96
|
+
|
97
|
+
uri = URI("#{global_options[:api_host]}/api/projects/#{payload["project"]["id"]}")
|
98
|
+
response = MyAsk::Api::Helper.make_request("Patch", uri, global_options[:api_key], payload)
|
99
|
+
|
100
|
+
if response.is_a?(Net::HTTPSuccess)
|
101
|
+
puts "Project successfully edited:" unless global_options[:json]
|
102
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
103
|
+
else
|
104
|
+
raise "Failed to edit project. Response code: #{response.code}, Body: #{response.body}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
c.desc "Create MyAsk Project"
|
110
|
+
c.command :create do |c|
|
111
|
+
c.flag [:name], desc: "Project Name"
|
112
|
+
c.flag [:description], desc: "Project Description"
|
113
|
+
c.flag [:ai_model], desc: "Project AI Model"
|
114
|
+
c.flag [:system_message], desc: "Project System Message"
|
115
|
+
|
116
|
+
c.action do |global_options, options, _args|
|
117
|
+
ai_models = ["gpt-4o-mini", "o3-mini", "o1-mini", "gpt-3.5-turbo", "gpt-4o", "chatgpt-4o-latest"]
|
118
|
+
|
119
|
+
prompt = TTY::Prompt.new
|
120
|
+
|
121
|
+
project_name = options[:name] || prompt.read_line("Enter project name:")
|
122
|
+
project_description = options[:description] || prompt.read_line("Enter project description:")
|
123
|
+
|
124
|
+
project_ai_model = options[:ai_model] || prompt.enum_select(
|
125
|
+
"Select an AI model for this project:",
|
126
|
+
ai_models
|
127
|
+
)
|
128
|
+
|
129
|
+
project_system_message = options[:system_message] || prompt.read_line(
|
130
|
+
"Enter project system_message (optional):"
|
131
|
+
)
|
132
|
+
|
133
|
+
payload = {
|
134
|
+
project: {
|
135
|
+
name: project_name.strip,
|
136
|
+
description: project_description.strip,
|
137
|
+
ai_model: project_ai_model,
|
138
|
+
system_message: { role: "developer", content: project_system_message.strip }
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
uri = URI("#{global_options[:api_host]}/api/projects")
|
143
|
+
response = MyAsk::Api::Helper.make_request("Post", uri, global_options[:api_key], payload)
|
144
|
+
|
145
|
+
if response.is_a?(Net::HTTPSuccess)
|
146
|
+
puts "Project created successfully:" unless global_options[:json]
|
147
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
148
|
+
else
|
149
|
+
raise "Failed to create project. Response code: #{response.code}, Body: #{response.body}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
c.desc "Delete MyAsk Project"
|
155
|
+
c.command :delete do |c|
|
156
|
+
c.desc "List projects and select to view"
|
157
|
+
c.switch [:l, :list]
|
158
|
+
|
159
|
+
c.flag [:project], desc: "Project ID"
|
160
|
+
|
161
|
+
c.action do |global_options, options, args|
|
162
|
+
helper = MyAsk::Api::ProjectHelper.new(global_options, options, args)
|
163
|
+
|
164
|
+
project = if options[:list]
|
165
|
+
helper.project_id_from_selection
|
166
|
+
else
|
167
|
+
args[0] || project
|
168
|
+
end
|
169
|
+
|
170
|
+
payload = {
|
171
|
+
project: {
|
172
|
+
id: project
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
uri = URI("#{global_options[:api_host]}/api/projects/#{project}")
|
177
|
+
response = MyAsk::Api::Helper.make_request("Delete", uri, global_options[:api_key], payload)
|
178
|
+
|
179
|
+
if response.is_a?(Net::HTTPSuccess)
|
180
|
+
puts "Project deleted successfully:" unless global_options[:json]
|
181
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
182
|
+
else
|
183
|
+
raise "Failed to delete project. Response code: #{response.code}, Body: #{response.body}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
c
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MyAsk
|
2
|
+
module Api
|
3
|
+
class ProjectHelper
|
4
|
+
|
5
|
+
def initialize(global_options, options, args)
|
6
|
+
@global_options = global_options
|
7
|
+
@options = options
|
8
|
+
@args = args
|
9
|
+
|
10
|
+
@api_host = global_options[:api_host]
|
11
|
+
@api_key = global_options[:api_key]
|
12
|
+
end
|
13
|
+
|
14
|
+
def project_id_from_selection
|
15
|
+
uri = URI("#{@api_host}/api/projects")
|
16
|
+
response = MyAsk::Api::Helper.make_request('Get', uri, @api_key)
|
17
|
+
|
18
|
+
projects = JSON.parse(response.body)
|
19
|
+
if projects.empty?
|
20
|
+
puts 'No projects found.'
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
select_project(projects)
|
25
|
+
end
|
26
|
+
|
27
|
+
def select_project(projects)
|
28
|
+
prompt = TTY::Prompt.new
|
29
|
+
selected_project = prompt.select(
|
30
|
+
"Select MyAsk Project:",
|
31
|
+
projects.map { |project| {"#{project["name"]}": project["id"]} }
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def show_project_info(project_id)
|
36
|
+
uri = URI("#{@api_host}/api/projects/#{project_id}")
|
37
|
+
response = MyAsk::Api::Helper.make_request('Get', uri, @api_key)
|
38
|
+
|
39
|
+
project_info = JSON.parse(response.body)
|
40
|
+
puts JSON.pretty_generate(project_info.except("question_ids"))
|
41
|
+
project_info.except("question_ids")
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module MyAsk
|
2
|
+
module Api
|
3
|
+
class Question
|
4
|
+
|
5
|
+
def initialize(c)
|
6
|
+
c.desc "Show details for MyAsk question"
|
7
|
+
c.arg_name "question_id"
|
8
|
+
|
9
|
+
c.command :show do |c|
|
10
|
+
c.desc "List questions and select to view"
|
11
|
+
c.switch [:l, :list]
|
12
|
+
|
13
|
+
c.flag [:q, :question_id], desc: "ID of question to display"
|
14
|
+
c.switch [:skip_response], desc: "Do not include question response in output"
|
15
|
+
|
16
|
+
c.action do |global_options, options, args|
|
17
|
+
api_host = global_options[:api_host]
|
18
|
+
api_key = global_options[:api_key]
|
19
|
+
|
20
|
+
if options[:list]
|
21
|
+
response = MyAsk::Api::Helper.make_request("Get", URI("#{api_host}/api/questions"), api_key)
|
22
|
+
questions = JSON.parse(response.body).reverse
|
23
|
+
|
24
|
+
if questions.empty?
|
25
|
+
puts "No questions found."
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
selected_question_id = TTY::Prompt.new.select("Select a question:", per_page: 10) do |menu|
|
30
|
+
questions.each do |q|
|
31
|
+
menu.choice "[#{q["id"]}] #{q["content"][0, 80]}", q["id"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
selected_question = selected_question_id
|
36
|
+
end
|
37
|
+
|
38
|
+
response = MyAsk::Api::Helper.make_request("Get", URI("#{api_host}/api/questions/#{selected_question || options[:question_id]}"), api_key)
|
39
|
+
response = JSON.parse(response.body)
|
40
|
+
response = response.except("response") if options[:skip_response]
|
41
|
+
|
42
|
+
puts "\n#{"\\" * 30} BEGIN Question (#{response["question"]["id"]}) #{"/" * 30}\n\n" unless global_options[:json]
|
43
|
+
puts global_options[:json] ? response.to_json : response["question"]["content"]
|
44
|
+
puts "\n#{"\\" * 35} END Question #{"/" * 35}\n" unless global_options[:json]
|
45
|
+
|
46
|
+
unless options[:skip_response] || global_options[:json] || response["response"].nil?
|
47
|
+
puts "\n\n#{"\\" * 30} BEGIN Response (#{response["response"]["id"]}) #{"/" * 30}\n\n" unless global_options[:json]
|
48
|
+
puts response["response"]["content"]
|
49
|
+
puts "\n#{"\\" * 35} END Response #{"/" * 35}\n" unless global_options[:json]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
c.desc "Delete MyAsk question"
|
55
|
+
c.arg_name "question_id"
|
56
|
+
|
57
|
+
c.command :delete do |c|
|
58
|
+
c.desc "List questions and select to delete"
|
59
|
+
c.switch [:l, :list]
|
60
|
+
|
61
|
+
c.flag [:question_id], desc: "ID of question to delete"
|
62
|
+
|
63
|
+
c.action do |global_options, options, args|
|
64
|
+
api_host = global_options[:api_host]
|
65
|
+
api_key = global_options[:api_key]
|
66
|
+
|
67
|
+
if options[:list]
|
68
|
+
response = MyAsk::Api::Helper.make_request("Get", URI("#{api_host}/api/questions"), api_key)
|
69
|
+
questions = JSON.parse(response.body).reverse
|
70
|
+
|
71
|
+
if questions.empty?
|
72
|
+
puts "No questions found."
|
73
|
+
exit
|
74
|
+
end
|
75
|
+
|
76
|
+
selected_question_id = TTY::Prompt.new.select("Select a question:", per_page: 10) do |menu|
|
77
|
+
questions.each do |q|
|
78
|
+
menu.choice "[#{q["id"]}] #{q["content"][0, 80]}", q["id"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
selected_question = selected_question_id
|
83
|
+
end
|
84
|
+
|
85
|
+
response = MyAsk::Api::Helper.make_request("Delete", URI("#{api_host}/api/questions/#{selected_question || options[:question_id]}"), api_key)
|
86
|
+
response = JSON.parse(response.body)
|
87
|
+
|
88
|
+
puts JSON.pretty_generate(response["question"])
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
c.default_command :show
|
94
|
+
c
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/myask/config.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module MyAsk
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def initialize(c)
|
5
|
+
c.command :save do |c|
|
6
|
+
c.desc "Set MyAsk API URL"
|
7
|
+
c.flag [:api_host], type: String
|
8
|
+
|
9
|
+
c.desc "Set MyAsk API Key"
|
10
|
+
c.flag [:api_key], type: String
|
11
|
+
|
12
|
+
c.desc "Set MyAsk Project"
|
13
|
+
c.flag [:project], type: String
|
14
|
+
|
15
|
+
c.action do |global_options, options, args|
|
16
|
+
helper = MyAsk::ConfigHelper.new(global_options, options, args)
|
17
|
+
response = helper.save_config
|
18
|
+
puts response
|
19
|
+
response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
c.command :show do |c|
|
24
|
+
c.action do |global_options, options, args|
|
25
|
+
helper = MyAsk::ConfigHelper.new(global_options, options, args)
|
26
|
+
response = helper.get_config
|
27
|
+
puts response
|
28
|
+
response
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
c.default_command :show
|
33
|
+
c
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MyAsk
|
2
|
+
class ConfigHelper
|
3
|
+
|
4
|
+
def initialize(global_options, options, args)
|
5
|
+
@global_options = global_options
|
6
|
+
@options = options
|
7
|
+
@args = args
|
8
|
+
@rc_file_path = File.expand_path("~/.myask.rc")
|
9
|
+
@config_data = YAML.load_file(@rc_file_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_config
|
13
|
+
@config_data.reject { |key, _| ["commands", "version", "s", "help"].include?(key.to_s) }.to_json
|
14
|
+
end
|
15
|
+
|
16
|
+
def save_config
|
17
|
+
@config_data[:api_key] = @options[:api_key] if @options[:api_key]
|
18
|
+
@config_data[:api_host] = @options[:api_host] if @options[:api_host]
|
19
|
+
@config_data[:project] = @options[:project] if @options[:project]
|
20
|
+
|
21
|
+
File.open(@rc_file_path, "w") do |file|
|
22
|
+
file.write(@config_data.to_yaml)
|
23
|
+
end
|
24
|
+
@config_data.reject { |key, _| ["commands", "version", "s", "help"].include?(key.to_s) }.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/myask/prompt.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module MyAsk
|
2
|
+
class Prompt
|
3
|
+
|
4
|
+
def initialize(c)
|
5
|
+
c.desc "Skip Follow-Up Question"
|
6
|
+
c.switch [:no_followup]
|
7
|
+
|
8
|
+
c.desc "Project ID"
|
9
|
+
c.flag [:project]
|
10
|
+
|
11
|
+
c.desc "Prompt to send"
|
12
|
+
c.flag [:p, :prompt]
|
13
|
+
|
14
|
+
c.desc "Question IDs to include in prompt context"
|
15
|
+
c.flag [:c, :context_ids], multiple: true
|
16
|
+
|
17
|
+
c.desc "Path to source file(s)"
|
18
|
+
c.flag [:F, :input_file], multiple: true
|
19
|
+
|
20
|
+
c.action do |global_options, options, args|
|
21
|
+
helper = MyAsk::PromptHelper.new(global_options, options, args)
|
22
|
+
|
23
|
+
config = global_options
|
24
|
+
auth_token = config[:api_key]
|
25
|
+
project = options[:project] || config[:project]
|
26
|
+
|
27
|
+
content = helper.get_initial_question
|
28
|
+
context_ids = options[:"context_ids"]
|
29
|
+
|
30
|
+
loop do
|
31
|
+
begin
|
32
|
+
question_id = helper.submit_question(config[:api_host], auth_token, project, content, context_ids)
|
33
|
+
abort if question_id.nil?
|
34
|
+
|
35
|
+
context_ids << question_id
|
36
|
+
|
37
|
+
response = helper.poll_for_response(config[:api_host], auth_token, question_id)
|
38
|
+
|
39
|
+
if global_options[:json]
|
40
|
+
puts "\n\n#{JSON.dump({response: response})}\n\n"
|
41
|
+
else
|
42
|
+
puts "\n\n#{response}\n\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
break if options[:no_followup]
|
46
|
+
|
47
|
+
prompt = TTY::Prompt.new
|
48
|
+
is_follow_up = prompt.yes?("Would you like to ask a follow-up question?", default: false)
|
49
|
+
|
50
|
+
break unless is_follow_up
|
51
|
+
|
52
|
+
follow_up_question = prompt.ask("Enter your follow-up question:").strip
|
53
|
+
content = follow_up_question
|
54
|
+
rescue => e
|
55
|
+
abort "Error: #{e}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
c
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module MyAsk
|
2
|
+
class PromptHelper
|
3
|
+
def initialize(global_options, options, args)
|
4
|
+
@global_options = global_options
|
5
|
+
@options = options
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def submit_question(api_host, auth_token, project_id, content, context_ids)
|
10
|
+
uri = URI("#{api_host}/api/questions")
|
11
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
12
|
+
http.use_ssl = (uri.scheme == "https")
|
13
|
+
|
14
|
+
request = Net::HTTP::Post.new(uri.path)
|
15
|
+
request["Authorization"] = "Bearer #{auth_token}"
|
16
|
+
request["Content-Type"] = "application/json"
|
17
|
+
|
18
|
+
request.body = {
|
19
|
+
question: {
|
20
|
+
project_id: project_id,
|
21
|
+
content: content,
|
22
|
+
context_ids: context_ids
|
23
|
+
}
|
24
|
+
}.to_json
|
25
|
+
|
26
|
+
response = http.request(request)
|
27
|
+
parsed_response = JSON.parse(response.body)
|
28
|
+
|
29
|
+
parsed_response['id'] || nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def poll_for_response(api_host, auth_token, question_id)
|
33
|
+
unless @global_options[:silent]
|
34
|
+
spinner = TTY::Spinner.new('🔄 Waiting for response from MyAsk API... [:spinner]', format: :dots)
|
35
|
+
spinner.auto_spin
|
36
|
+
end
|
37
|
+
|
38
|
+
max_retries = 50
|
39
|
+
attempt = 0
|
40
|
+
|
41
|
+
while attempt < max_retries
|
42
|
+
sleep 3
|
43
|
+
uri = URI("#{api_host}/api/responses/#{question_id}")
|
44
|
+
response = Net::HTTP.get(uri, { 'Authorization' => "Bearer #{auth_token}" })
|
45
|
+
parsed_response = JSON.parse(response)
|
46
|
+
|
47
|
+
if parsed_response.key?('content')
|
48
|
+
spinner.success('✅ Response received!') unless @global_options[:silent]
|
49
|
+
return parsed_response['content']
|
50
|
+
end
|
51
|
+
|
52
|
+
attempt += 1
|
53
|
+
end
|
54
|
+
|
55
|
+
spinner.error('❌ Timed out waiting for MyAsk API response.') unless @global_options[:silent]
|
56
|
+
raise 'No response received from MyAsk API after multiple attempts.'
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_initial_question
|
60
|
+
file_contents = []
|
61
|
+
|
62
|
+
if @options[:input_file]&.any?
|
63
|
+
@options[:input_file].each do |file_path|
|
64
|
+
begin
|
65
|
+
content = File.read(file_path).strip
|
66
|
+
file_contents << "**File**: #{file_path}**\n#{content}"
|
67
|
+
rescue => e
|
68
|
+
raise "❌ Failed to read input file: #{file_path}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
combined_question = "#{@options[:prompt]}\n\n---\n#{file_contents.join("\n\n---\n")}" unless file_contents.empty?
|
74
|
+
combined_question ||= @options[:prompt] || TTY::Prompt.new.ask('Please enter a prompt:').strip
|
75
|
+
|
76
|
+
combined_question.empty? ? nil : combined_question
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
data/lib/myask.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'myask/version.rb'
|
2
|
+
|
3
|
+
require 'myask/config.rb'
|
4
|
+
require 'myask/config_helper.rb'
|
5
|
+
|
6
|
+
require 'myask/api/api_helper.rb'
|
7
|
+
|
8
|
+
require 'myask/api/question.rb'
|
9
|
+
require 'myask/api/invitation.rb'
|
10
|
+
|
11
|
+
require 'myask/api/project.rb'
|
12
|
+
require 'myask/api/project_helper.rb'
|
13
|
+
|
14
|
+
require 'myask/prompt.rb'
|
15
|
+
require 'myask/prompt_helper.rb'
|
16
|
+
|
17
|
+
# Add requires for other files you add to your project here, so
|
18
|
+
# you just need to require this one file in your bin file
|
19
|
+
|
20
|
+
require 'net/http'
|
21
|
+
require 'json'
|
22
|
+
|
23
|
+
require 'io/console'
|
24
|
+
require 'tty-spinner'
|
25
|
+
require 'tty-prompt'
|
26
|
+
require 'yaml'
|
27
|
+
|
28
|
+
require 'pry-byebug'
|
data/myask.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','myask','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'myask'
|
5
|
+
s.version = Myask::VERSION
|
6
|
+
s.author = 'Andrew Chaney (netuoso)'
|
7
|
+
s.email = 'netuoso@myask.io'
|
8
|
+
s.homepage = 'https://myask.io'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'MyAsk Command Line Tool Integrates with MyAsk AI API (https://myask.io).'
|
11
|
+
s.files = `git ls-files`.split("
|
12
|
+
")
|
13
|
+
s.require_paths << 'lib'
|
14
|
+
s.extra_rdoc_files = ['README.rdoc','myask.rdoc']
|
15
|
+
s.rdoc_options << '--title' << 'myask' << '--main' << 'README.rdoc' << '-ri'
|
16
|
+
s.bindir = 'bin'
|
17
|
+
s.executables << 'myask'
|
18
|
+
s.add_development_dependency('rake')
|
19
|
+
s.add_development_dependency('rdoc')
|
20
|
+
s.add_development_dependency('minitest')
|
21
|
+
s.add_runtime_dependency('gli','~> 2.22.2')
|
22
|
+
end
|
data/myask.rdoc
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
== myask - Describe your application here
|
2
|
+
|
3
|
+
v0.0.1
|
4
|
+
|
5
|
+
=== Global Options
|
6
|
+
=== --api_host arg
|
7
|
+
|
8
|
+
Host for MyAsk API
|
9
|
+
|
10
|
+
[Default Value] http://localhost:3000
|
11
|
+
|
12
|
+
|
13
|
+
=== --api_key arg
|
14
|
+
|
15
|
+
API Key for MyAsk API
|
16
|
+
|
17
|
+
[Default Value] A9qVFSgXFH8Ubclq4jVYn0PBsEGMSfQf
|
18
|
+
|
19
|
+
|
20
|
+
=== --project arg
|
21
|
+
|
22
|
+
Current MyAsk Project
|
23
|
+
|
24
|
+
[Default Value] 156891416
|
25
|
+
|
26
|
+
|
27
|
+
=== --help
|
28
|
+
Show this message
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
=== --[no-]json
|
33
|
+
Format Output as JSON
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
=== --[no-]silent
|
38
|
+
Silent Progress Spinner
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
=== --version
|
43
|
+
Display the program version
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
=== Commands
|
48
|
+
==== Command: <tt>config </tt>
|
49
|
+
View current or set new MyAsk configuration values
|
50
|
+
|
51
|
+
|
52
|
+
===== Commands
|
53
|
+
====== Command: <tt>save </tt>
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
====== Command: <tt>show </tt>
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
[Default Command] show
|
62
|
+
==== Command: <tt>help command</tt>
|
63
|
+
Shows a list of commands or help for one command
|
64
|
+
|
65
|
+
Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function
|
66
|
+
===== Options
|
67
|
+
===== -c
|
68
|
+
List commands one per line, to assist with shell completion
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
==== Command: <tt>initconfig </tt>
|
73
|
+
Initialize the config file using current global options
|
74
|
+
|
75
|
+
Initializes a configuration file where you can set default options for command line flags, both globally and on a per-command basis. These defaults override the built-in defaults and allow you to omit commonly-used command line flags when invoking this program
|
76
|
+
===== Options
|
77
|
+
===== --[no-]force
|
78
|
+
force overwrite of existing config file
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
==== Command: <tt>invitation </tt>
|
83
|
+
Create/list MyAsk Invitations
|
84
|
+
|
85
|
+
|
86
|
+
===== Commands
|
87
|
+
====== Command: <tt>list </tt>
|
88
|
+
List MyAsk invitations.
|
89
|
+
|
90
|
+
|
91
|
+
====== Command: <tt>send </tt>
|
92
|
+
Send MyAsk invitation to a new user
|
93
|
+
|
94
|
+
|
95
|
+
[Default Command] list
|
96
|
+
==== Command: <tt>project </tt>
|
97
|
+
Create/show/list/delete MyAsk Project
|
98
|
+
|
99
|
+
|
100
|
+
===== Commands
|
101
|
+
====== Command: <tt>create </tt>
|
102
|
+
Create MyAsk Project
|
103
|
+
|
104
|
+
|
105
|
+
====== Command: <tt>delete </tt>
|
106
|
+
Delete MyAsk Project
|
107
|
+
|
108
|
+
|
109
|
+
====== Command: <tt>edit project</tt>
|
110
|
+
Edit MyAsk Project
|
111
|
+
|
112
|
+
|
113
|
+
====== Command: <tt>set project</tt>
|
114
|
+
Set MyAsk Project
|
115
|
+
|
116
|
+
|
117
|
+
====== Command: <tt>show project</tt>
|
118
|
+
Show MyAsk Project Details
|
119
|
+
|
120
|
+
|
121
|
+
==== Command: <tt>prompt </tt>
|
122
|
+
Send a prompt to MyAsk API
|
123
|
+
|
124
|
+
|
125
|
+
==== Command: <tt>question </tt>
|
126
|
+
Show/delete MyAsk Question
|
127
|
+
|
128
|
+
|
129
|
+
===== Commands
|
130
|
+
====== Command: <tt>delete question_id</tt>
|
131
|
+
Delete MyAsk question
|
132
|
+
|
133
|
+
|
134
|
+
====== Command: <tt>show question_id</tt>
|
135
|
+
Show details for MyAsk question
|
136
|
+
|
137
|
+
|
138
|
+
[Default Command] show
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: myask
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Chaney (netuoso)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-03-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: gli
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.22.2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.22.2
|
69
|
+
description:
|
70
|
+
email: netuoso@myask.io
|
71
|
+
executables:
|
72
|
+
- myask
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files:
|
75
|
+
- README.rdoc
|
76
|
+
- myask.rdoc
|
77
|
+
files:
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- README.rdoc
|
81
|
+
- Rakefile
|
82
|
+
- bin/myask
|
83
|
+
- lib/myask.rb
|
84
|
+
- lib/myask/api/api_helper.rb
|
85
|
+
- lib/myask/api/invitation.rb
|
86
|
+
- lib/myask/api/project.rb
|
87
|
+
- lib/myask/api/project_helper.rb
|
88
|
+
- lib/myask/api/question.rb
|
89
|
+
- lib/myask/config.rb
|
90
|
+
- lib/myask/config_helper.rb
|
91
|
+
- lib/myask/prompt.rb
|
92
|
+
- lib/myask/prompt_helper.rb
|
93
|
+
- lib/myask/version.rb
|
94
|
+
- myask.gemspec
|
95
|
+
- myask.rdoc
|
96
|
+
- test/default_test.rb
|
97
|
+
- test/test_helper.rb
|
98
|
+
homepage: https://myask.io
|
99
|
+
licenses: []
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options:
|
103
|
+
- "--title"
|
104
|
+
- myask
|
105
|
+
- "--main"
|
106
|
+
- README.rdoc
|
107
|
+
- "-ri"
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubygems_version: 3.4.10
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: MyAsk Command Line Tool Integrates with MyAsk AI API (https://myask.io).
|
126
|
+
test_files: []
|