inquirex-tty 0.4.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 +7 -0
- data/.envrc +3 -0
- data/.relaxed_rubocop.yml +153 -0
- data/.secrets.baseline +127 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +530 -0
- data/Rakefile +36 -0
- data/docs/badges/coverage_badge.svg +21 -0
- data/examples/01_hello_world.rb +32 -0
- data/examples/02_yes_or_no.rb +33 -0
- data/examples/03_food_preferences.png +0 -0
- data/examples/03_food_preferences.rb +65 -0
- data/examples/04_event_registration.rb +86 -0
- data/examples/05_job_application.rb +122 -0
- data/examples/06_health_assessment.rb +173 -0
- data/examples/07_loan_application.rb +217 -0
- data/examples/08_tax_preparer.rb +195 -0
- data/examples/09_tax_preparer_llm.rb +151 -0
- data/examples/10_answers.json +53 -0
- data/examples/10_real_tax_preparer.rb +604 -0
- data/examples/README.md +50 -0
- data/exe/inquirex +24 -0
- data/justfile +56 -0
- data/lefthook.yml +36 -0
- data/lib/inquirex/tty/commands/export.rb +81 -0
- data/lib/inquirex/tty/commands/graph.rb +116 -0
- data/lib/inquirex/tty/commands/run.rb +193 -0
- data/lib/inquirex/tty/commands/validate.rb +108 -0
- data/lib/inquirex/tty/commands/version.rb +19 -0
- data/lib/inquirex/tty/commands.rb +19 -0
- data/lib/inquirex/tty/flow_loader.rb +41 -0
- data/lib/inquirex/tty/output_path.rb +66 -0
- data/lib/inquirex/tty/renderer.rb +245 -0
- data/lib/inquirex/tty/ui_helper.rb +58 -0
- data/lib/inquirex/tty/version.rb +7 -0
- data/lib/inquirex/tty.rb +41 -0
- data/sig/inquirex/tty.rbs +6 -0
- metadata +197 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module TTY
|
|
5
|
+
# Shared output path resolution for commands that accept an `-o/--output` option.
|
|
6
|
+
#
|
|
7
|
+
# Rules:
|
|
8
|
+
# - nil or empty output → nil (caller should write to stdout)
|
|
9
|
+
# - output is an existing dir → <dir>/<flow-basename>.<ext>
|
|
10
|
+
# - output has an extension → <output> with its extension replaced by .<ext>
|
|
11
|
+
# - output has no extension → <output>.<ext>
|
|
12
|
+
#
|
|
13
|
+
# For commands that must always write to a file (e.g. images that cannot go
|
|
14
|
+
# to stdout), use {.resolve_with_default}, which falls back to
|
|
15
|
+
# `<flow-basename>.<ext>` in the current directory.
|
|
16
|
+
module OutputPath
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
# Resolves an output path, returning nil when the caller should use stdout.
|
|
20
|
+
#
|
|
21
|
+
# @param flow_file [String] source .rb flow file (basename used for defaults)
|
|
22
|
+
# @param output [String, nil] value of the --output option
|
|
23
|
+
# @param extension [String] including leading dot, e.g. ".json"
|
|
24
|
+
# @return [String, nil]
|
|
25
|
+
def resolve(flow_file, output, extension)
|
|
26
|
+
return nil if output.nil? || output.to_s.empty?
|
|
27
|
+
return File.join(output, "#{flow_basename(flow_file)}#{extension}") if File.directory?(output)
|
|
28
|
+
|
|
29
|
+
with_default_extension(output, extension)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Resolves an output path, falling back to "<basename>.<ext>" in cwd when
|
|
33
|
+
# no --output was given. For commands where stdout is not an option.
|
|
34
|
+
#
|
|
35
|
+
# @param flow_file [String]
|
|
36
|
+
# @param output [String, nil]
|
|
37
|
+
# @param extension [String]
|
|
38
|
+
# @return [String]
|
|
39
|
+
def resolve_with_default(flow_file, output, extension)
|
|
40
|
+
resolve(flow_file, output, extension) || "#{flow_basename(flow_file)}#{extension}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The flow file's basename without its extension.
|
|
44
|
+
#
|
|
45
|
+
# @param flow_file [String]
|
|
46
|
+
# @return [String]
|
|
47
|
+
def flow_basename(flow_file)
|
|
48
|
+
File.basename(flow_file, File.extname(flow_file))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Ensures `path` ends with the given extension. If the path has no
|
|
52
|
+
# extension, appends it. If it has one, replaces it.
|
|
53
|
+
#
|
|
54
|
+
# @param path [String]
|
|
55
|
+
# @param extension [String] including leading dot
|
|
56
|
+
# @return [String]
|
|
57
|
+
def with_default_extension(path, extension)
|
|
58
|
+
if File.extname(path).empty?
|
|
59
|
+
"#{path}#{extension}"
|
|
60
|
+
else
|
|
61
|
+
path.sub(%r{\.[^/.]+\z}, extension)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module TTY
|
|
5
|
+
# Renders flow nodes as interactive TTY prompts. Dispatches collecting steps
|
|
6
|
+
# via the node's TTY widget hint (from +Inquirex::WidgetRegistry+ or an
|
|
7
|
+
# explicit +widget target: :tty+ declaration in the DSL).
|
|
8
|
+
#
|
|
9
|
+
# Display verbs render text/boxes and return +nil+; the caller is responsible
|
|
10
|
+
# for calling +engine.advance+.
|
|
11
|
+
#
|
|
12
|
+
# Widget type → tty-prompt method:
|
|
13
|
+
# text_input → prompt.ask
|
|
14
|
+
# multiline → line-by-line collector (empty line submits)
|
|
15
|
+
# number_input → prompt.ask(convert: :int / :float)
|
|
16
|
+
# currency_input → prompt.ask(convert: :float)
|
|
17
|
+
# yes_no → prompt.yes?
|
|
18
|
+
# select → prompt.select
|
|
19
|
+
# multi_select → prompt.multi_select
|
|
20
|
+
# enum_select → prompt.enum_select
|
|
21
|
+
# mask → prompt.mask
|
|
22
|
+
# slider → prompt.slider
|
|
23
|
+
# (fallback) → prompt.ask
|
|
24
|
+
#
|
|
25
|
+
# Header display verb uses TTY::Font for large ASCII-art section titles.
|
|
26
|
+
class Renderer
|
|
27
|
+
include UIHelper
|
|
28
|
+
|
|
29
|
+
# @return [TTY::Prompt]
|
|
30
|
+
attr_reader :prompt
|
|
31
|
+
|
|
32
|
+
# @param prompt [TTY::Prompt] injectable for testing
|
|
33
|
+
def initialize(prompt: ::TTY::Prompt.new)
|
|
34
|
+
@prompt = prompt
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Prints a "thinking" line before the LLM adapter is called.
|
|
38
|
+
# Plain colored text — no animation so it plays nicely with piped output.
|
|
39
|
+
#
|
|
40
|
+
# @param message [String]
|
|
41
|
+
# @return [void]
|
|
42
|
+
def thinking(message)
|
|
43
|
+
sep(:magenta, "─")
|
|
44
|
+
puts pastel.bright_magenta.bold(message)
|
|
45
|
+
sep(:magenta, "─")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Prints the structured data extracted by a clarify step, dimming any
|
|
49
|
+
# fields the LLM left blank so the user can see what still needs asking.
|
|
50
|
+
#
|
|
51
|
+
# @param result [Hash] adapter output
|
|
52
|
+
# @return [void]
|
|
53
|
+
def show_extraction(result)
|
|
54
|
+
puts pastel.bold("📋 LLM extracted:")
|
|
55
|
+
result.each do |key, value|
|
|
56
|
+
if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
57
|
+
puts pastel.dim(" ❓ #{key}: (unknown — will ask)")
|
|
58
|
+
else
|
|
59
|
+
puts pastel.green(" ✅ #{key}: #{value.inspect}")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
sep(:magenta, "─")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Renders a node. Returns the collected answer, or +nil+ for display verbs.
|
|
66
|
+
# @param node [Inquirex::Node]
|
|
67
|
+
# @return [Object, nil]
|
|
68
|
+
def render(node)
|
|
69
|
+
if node.display?
|
|
70
|
+
render_display_verb(node)
|
|
71
|
+
nil
|
|
72
|
+
else
|
|
73
|
+
render_collecting(node)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# Dispatches display verbs to their styled renderers.
|
|
80
|
+
# :header uses TTY::Font for a large ASCII-art title.
|
|
81
|
+
# :btw and :warning use TTY::Box info/warn boxes.
|
|
82
|
+
# :say outputs plain text.
|
|
83
|
+
# @param node [Inquirex::Node]
|
|
84
|
+
# @return [void]
|
|
85
|
+
def render_display_verb(node)
|
|
86
|
+
case node.verb
|
|
87
|
+
when :header
|
|
88
|
+
render_header(node)
|
|
89
|
+
when :say
|
|
90
|
+
puts "\n#{node.text}\n"
|
|
91
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
92
|
+
sep(:green, "━")
|
|
93
|
+
when :btw
|
|
94
|
+
info(node.text)
|
|
95
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
96
|
+
when :warning
|
|
97
|
+
warning(node.text)
|
|
98
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
99
|
+
else
|
|
100
|
+
puts "\n#{node.text}\n"
|
|
101
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Renders a header node using TTY::Font for an ASCII-art title.
|
|
106
|
+
# Falls back to a TTY::Box bordered header if font rendering fails
|
|
107
|
+
# (e.g. unsupported characters in the text).
|
|
108
|
+
# @param node [Inquirex::Node]
|
|
109
|
+
# @return [void]
|
|
110
|
+
def render_header(node)
|
|
111
|
+
font = ::TTY::Font.new(:doom)
|
|
112
|
+
title_text = node.text.upcase
|
|
113
|
+
title_text.split.each do |_word|
|
|
114
|
+
title = font.write(node.text.upcase)
|
|
115
|
+
puts pastel.yellow(title)
|
|
116
|
+
end
|
|
117
|
+
sep(:cyan, "━")
|
|
118
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
119
|
+
rescue StandardError
|
|
120
|
+
# Fall back to tty-box if TTY::Font cannot render the text
|
|
121
|
+
puts box(node.text, bg: :blue, fg: :white)
|
|
122
|
+
prompt.keypress(pastel.dim("Press any key to continue..."))
|
|
123
|
+
sep(:cyan, "━")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Gets the effective TTY widget hint and dispatches to the right render method.
|
|
127
|
+
# @param node [Inquirex::Node]
|
|
128
|
+
# @return [Object]
|
|
129
|
+
def render_collecting(node)
|
|
130
|
+
hint = effective_tty_hint(node)
|
|
131
|
+
method_name = :"render_#{hint.type}"
|
|
132
|
+
if respond_to?(method_name, true)
|
|
133
|
+
send(method_name, node)
|
|
134
|
+
else
|
|
135
|
+
render_text_input(node)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Returns the effective TTY widget hint for a node, with a text_input fallback.
|
|
140
|
+
# @param node [Inquirex::Node]
|
|
141
|
+
# @return [Inquirex::WidgetHint]
|
|
142
|
+
def effective_tty_hint(node)
|
|
143
|
+
hint =
|
|
144
|
+
if node.respond_to?(:effective_widget_hint_for)
|
|
145
|
+
node.effective_widget_hint_for(target: :tty)
|
|
146
|
+
else
|
|
147
|
+
Inquirex::WidgetRegistry.default_hint_for(node.type, context: :tty)
|
|
148
|
+
end
|
|
149
|
+
hint || Inquirex::WidgetHint.new(type: :text_input)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Single-line text.
|
|
153
|
+
def render_text_input(node)
|
|
154
|
+
prompt.ask(node.question)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Multi-line text (empty line to submit).
|
|
158
|
+
def render_multiline(node)
|
|
159
|
+
puts pastel.bold(node.question)
|
|
160
|
+
puts pastel.dim("Enter your response. Press Enter on a blank line to submit.")
|
|
161
|
+
sep(:cyan, "─")
|
|
162
|
+
collect_multiline_text
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def collect_multiline_text
|
|
166
|
+
lines = []
|
|
167
|
+
loop do
|
|
168
|
+
line = prompt.ask(">") { |q| q.required(false) }
|
|
169
|
+
break if line.nil? || line.empty?
|
|
170
|
+
|
|
171
|
+
lines << line
|
|
172
|
+
end
|
|
173
|
+
sep(:cyan, "─")
|
|
174
|
+
lines.empty? ? nil : lines.join("\n")
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Integer or float depending on the node's data type.
|
|
178
|
+
def render_number_input(node)
|
|
179
|
+
convert = node.type == :integer ? :int : :float
|
|
180
|
+
prompt.ask(node.question, convert:)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Float for currency types.
|
|
184
|
+
def render_currency_input(node)
|
|
185
|
+
prompt.ask(node.question, convert: :float)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Boolean — tty-prompt yes?.
|
|
189
|
+
def render_yes_no(node)
|
|
190
|
+
prompt.yes?(node.question)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Single-choice scrollable menu.
|
|
194
|
+
def render_select(node)
|
|
195
|
+
prompt.select(node.question, select_options(node))
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Multiple-choice list (space to toggle, min 1 selection).
|
|
199
|
+
def render_multi_select(node)
|
|
200
|
+
prompt.multi_select(node.question, select_options(node), min: 1)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Numbered choice menu.
|
|
204
|
+
def render_enum_select(node)
|
|
205
|
+
prompt.enum_select(node.question, select_options(node))
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Hidden / masked input.
|
|
209
|
+
def render_mask(node)
|
|
210
|
+
prompt.mask(node.question)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Numeric slider. Reads min/max/step from explicit widget hint options.
|
|
214
|
+
def render_slider(node)
|
|
215
|
+
opts = {}
|
|
216
|
+
if node.respond_to?(:effective_widget_hint_for)
|
|
217
|
+
hint_opts = node.effective_widget_hint_for(target: :tty)&.options || {}
|
|
218
|
+
opts[:min] = hint_opts[:min] if hint_opts[:min]
|
|
219
|
+
opts[:max] = hint_opts[:max] if hint_opts[:max]
|
|
220
|
+
opts[:step] = hint_opts[:step] if hint_opts[:step]
|
|
221
|
+
end
|
|
222
|
+
prompt.slider(node.question, **opts)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Aliases: date, email, phone degrade to plain text_input in TTY.
|
|
226
|
+
alias render_date_picker render_text_input
|
|
227
|
+
alias render_email_input render_text_input
|
|
228
|
+
alias render_phone_input render_text_input
|
|
229
|
+
# textarea is multiline in TTY
|
|
230
|
+
alias render_textarea render_multiline
|
|
231
|
+
|
|
232
|
+
# Returns options suitable for TTY::Prompt select/multi_select.
|
|
233
|
+
# Inquirex exposes option values via `node.options` and display labels
|
|
234
|
+
# via `node.option_labels` ({value => label}). TTY::Prompt expects a
|
|
235
|
+
# Hash in the opposite orientation: {label => return_value}.
|
|
236
|
+
def select_options(node)
|
|
237
|
+
values = node.options || []
|
|
238
|
+
labels = node.respond_to?(:option_labels) ? node.option_labels : nil
|
|
239
|
+
return values unless labels && !labels.empty?
|
|
240
|
+
|
|
241
|
+
values.to_h { |v| [labels[v] || v, v] }
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Inquirex
|
|
4
|
+
module TTY
|
|
5
|
+
# Mixin providing TTY::Box, Pastel, and screen helpers to CLI commands
|
|
6
|
+
# and the Renderer. Defines +box+, +sep+, +next_step+, +frame+, +info+,
|
|
7
|
+
# +success+, +error+, +warning+, and +width+ on the including class.
|
|
8
|
+
module UIHelper
|
|
9
|
+
class << self
|
|
10
|
+
# @return [Pastel] shared Pastel instance
|
|
11
|
+
def pastel
|
|
12
|
+
@pastel ||= Pastel.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def included(base)
|
|
16
|
+
base.extend(Forwardable)
|
|
17
|
+
base.define_method(:tty_box) { ::TTY::Box }
|
|
18
|
+
base.define_method(:tty_screen) { ::TTY::Screen }
|
|
19
|
+
base.define_method(:pastel) { ::Inquirex::TTY::UIHelper.pastel }
|
|
20
|
+
|
|
21
|
+
%i[frame info success error].each do |method|
|
|
22
|
+
base.define_method(method) { |*args, **kwargs| puts ::TTY::Box.send(method, *args, **kwargs) }
|
|
23
|
+
end
|
|
24
|
+
base.define_method(:warning) { |*args, **kwargs| puts ::TTY::Box.send(:warn, *args, **kwargs) }
|
|
25
|
+
|
|
26
|
+
base.def_delegators :tty_screen, :width
|
|
27
|
+
|
|
28
|
+
base.class_eval do
|
|
29
|
+
# Draw a bordered box with optional title.
|
|
30
|
+
def box(text, title: nil, bg: :green, fg: :white) # rubocop:disable Naming/MethodParameterName
|
|
31
|
+
w = [width, 80].min
|
|
32
|
+
args = {
|
|
33
|
+
width: w,
|
|
34
|
+
padding: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
35
|
+
align: :center,
|
|
36
|
+
style: { fg: fg, bg: bg,
|
|
37
|
+
border: { type: :thin, fg: fg, bg: bg } }
|
|
38
|
+
}
|
|
39
|
+
args[:title] = { top_left: title } if title
|
|
40
|
+
frame(text, **args)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Print step progress and separator.
|
|
44
|
+
def next_step(step_id, step_number)
|
|
45
|
+
puts pastel.yellow("Step #{step_number}: #{step_id}")
|
|
46
|
+
sep(:yellow, "━")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Print a full-width separator in the given color.
|
|
50
|
+
def sep(color = :yellow, char = "━")
|
|
51
|
+
puts pastel.send(color, char * 80)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/inquirex/tty.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "inquirex"
|
|
4
|
+
require "inquirex/llm"
|
|
5
|
+
require "dry/cli"
|
|
6
|
+
require "tty-prompt"
|
|
7
|
+
require "tty-box"
|
|
8
|
+
require "tty-screen"
|
|
9
|
+
require "tty-font"
|
|
10
|
+
require "pastel"
|
|
11
|
+
require "forwardable"
|
|
12
|
+
require "json"
|
|
13
|
+
require "yaml"
|
|
14
|
+
require "time"
|
|
15
|
+
require "shellwords"
|
|
16
|
+
require "tempfile"
|
|
17
|
+
|
|
18
|
+
module Inquirex
|
|
19
|
+
# Terminal adapter for Inquirex flows. Renders questions as interactive
|
|
20
|
+
# TTY prompts via tty-prompt, mapping each data type to the appropriate
|
|
21
|
+
# widget via Inquirex widget hints.
|
|
22
|
+
#
|
|
23
|
+
# Entry point:
|
|
24
|
+
# Dry::CLI.new(Inquirex::TTY::Commands).call
|
|
25
|
+
module TTY
|
|
26
|
+
# Raised when inquirex-tty encounters a load, validation, or runtime error.
|
|
27
|
+
class Error < StandardError; end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
require_relative "tty/version"
|
|
32
|
+
require_relative "tty/ui_helper"
|
|
33
|
+
require_relative "tty/flow_loader"
|
|
34
|
+
require_relative "tty/output_path"
|
|
35
|
+
require_relative "tty/renderer"
|
|
36
|
+
require_relative "tty/commands/run"
|
|
37
|
+
require_relative "tty/commands/validate"
|
|
38
|
+
require_relative "tty/commands/graph"
|
|
39
|
+
require_relative "tty/commands/export"
|
|
40
|
+
require_relative "tty/commands/version"
|
|
41
|
+
require_relative "tty/commands"
|
metadata
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: inquirex-tty
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Konstantin Gredeskoul
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: dry-cli
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: inquirex
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.3'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.3'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: inquirex-llm
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.1'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: pastel
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.8'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.8'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: tty-box
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.7'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.7'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: tty-font
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.5'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.5'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: tty-prompt
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0.23'
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0.23'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: tty-screen
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.8'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0.8'
|
|
124
|
+
description: 'Renders Inquirex flow definitions as interactive ANSI terminal wizards
|
|
125
|
+
using tty-prompt, tty-box, and tty-font. Provides a dry-cli command suite: run,
|
|
126
|
+
validate, graph, version.'
|
|
127
|
+
email:
|
|
128
|
+
- kigster@gmail.com
|
|
129
|
+
executables:
|
|
130
|
+
- inquirex
|
|
131
|
+
extensions: []
|
|
132
|
+
extra_rdoc_files: []
|
|
133
|
+
files:
|
|
134
|
+
- ".envrc"
|
|
135
|
+
- ".relaxed_rubocop.yml"
|
|
136
|
+
- ".secrets.baseline"
|
|
137
|
+
- CHANGELOG.md
|
|
138
|
+
- LICENSE.txt
|
|
139
|
+
- README.md
|
|
140
|
+
- Rakefile
|
|
141
|
+
- docs/badges/coverage_badge.svg
|
|
142
|
+
- examples/01_hello_world.rb
|
|
143
|
+
- examples/02_yes_or_no.rb
|
|
144
|
+
- examples/03_food_preferences.png
|
|
145
|
+
- examples/03_food_preferences.rb
|
|
146
|
+
- examples/04_event_registration.rb
|
|
147
|
+
- examples/05_job_application.rb
|
|
148
|
+
- examples/06_health_assessment.rb
|
|
149
|
+
- examples/07_loan_application.rb
|
|
150
|
+
- examples/08_tax_preparer.rb
|
|
151
|
+
- examples/09_tax_preparer_llm.rb
|
|
152
|
+
- examples/10_answers.json
|
|
153
|
+
- examples/10_real_tax_preparer.rb
|
|
154
|
+
- examples/README.md
|
|
155
|
+
- exe/inquirex
|
|
156
|
+
- justfile
|
|
157
|
+
- lefthook.yml
|
|
158
|
+
- lib/inquirex/tty.rb
|
|
159
|
+
- lib/inquirex/tty/commands.rb
|
|
160
|
+
- lib/inquirex/tty/commands/export.rb
|
|
161
|
+
- lib/inquirex/tty/commands/graph.rb
|
|
162
|
+
- lib/inquirex/tty/commands/run.rb
|
|
163
|
+
- lib/inquirex/tty/commands/validate.rb
|
|
164
|
+
- lib/inquirex/tty/commands/version.rb
|
|
165
|
+
- lib/inquirex/tty/flow_loader.rb
|
|
166
|
+
- lib/inquirex/tty/output_path.rb
|
|
167
|
+
- lib/inquirex/tty/renderer.rb
|
|
168
|
+
- lib/inquirex/tty/ui_helper.rb
|
|
169
|
+
- lib/inquirex/tty/version.rb
|
|
170
|
+
- sig/inquirex/tty.rbs
|
|
171
|
+
homepage: https://github.com/flowengine-rb/inquirex-tty
|
|
172
|
+
licenses:
|
|
173
|
+
- MIT
|
|
174
|
+
metadata:
|
|
175
|
+
allowed_push_host: https://rubygems.org
|
|
176
|
+
homepage_uri: https://github.com/flowengine-rb/inquirex-tty
|
|
177
|
+
source_code_uri: https://github.com/inquirex/inquirex-tty
|
|
178
|
+
changelog_uri: https://github.com/inquirex/inquirex-tty/blob/main/CHANGELOG.md
|
|
179
|
+
rubygems_mfa_required: 'true'
|
|
180
|
+
rdoc_options: []
|
|
181
|
+
require_paths:
|
|
182
|
+
- lib
|
|
183
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: 4.0.0
|
|
188
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
|
+
requirements:
|
|
190
|
+
- - ">="
|
|
191
|
+
- !ruby/object:Gem::Version
|
|
192
|
+
version: '0'
|
|
193
|
+
requirements: []
|
|
194
|
+
rubygems_version: 4.0.16
|
|
195
|
+
specification_version: 4
|
|
196
|
+
summary: Terminal adapter for Inquirex flows — interactive TTY wizard via tty-prompt
|
|
197
|
+
test_files: []
|