inquirex 0.6.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +3 -11
- data/README.md +14 -51
- data/lib/.DS_Store +0 -0
- data/lib/inquirex/engine/state_serializer.rb +1 -0
- data/lib/inquirex/engine.rb +39 -1
- data/lib/inquirex/version.rb +1 -1
- metadata +2 -16
- data/.relaxed_rubocop.yml +0 -153
- data/.rub +0 -0
- data/.ruby-version +0 -1
- data/.secrets.baseline +0 -127
- data/Brewfile +0 -7
- data/Rakefile +0 -36
- data/docs/badges/coverage_badge.svg +0 -21
- data/examples/01_readme_example.rb +0 -55
- data/examples/02_readme_mermaid.png +0 -0
- data/examples/02_readme_mermaid.rb +0 -36
- data/examples/03_send_email_actions.rb +0 -97
- data/examples/README.md +0 -33
- data/justfile +0 -70
- data/lefthook.yml +0 -35
- data/sig/inquirex.rbs +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3422d46566a55c973dc712fb60918cde34029d3dc739e36bb1eb2c40110f1f25
|
|
4
|
+
data.tar.gz: eb6e54e12a407b21547ac97ca7153b93af516713c0dbcaa83a2323f909f8f816
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42b3c45e598ebadec67d48e251605e74022cfe1ba0923c21b5998b0c0c2ef8005f2895e43c501dfd9a8613d05821a95653330c5395ff7755fa1892a74761873c
|
|
7
|
+
data.tar.gz: c85a9f013fb304ddfc7cbb9742a24167c7da7cefe18fa83425cfc83f1ac5184eeb7960a9ee3592d95ebd82890f7b9568aaea2b1eb488d8840a17106cbe091f3f
|
data/CHANGELOG.md
CHANGED
|
@@ -3,20 +3,12 @@
|
|
|
3
3
|
## [0.6.0] - 2026-07-19
|
|
4
4
|
|
|
5
5
|
- Post-completion `action` DSL verb with an extensible effect registry
|
|
6
|
-
- `send_email` effect: builds `Mail::Message` objects (multipart text/HTML)
|
|
7
|
-
from `{{field}}` templates into `Answers#outbox`; delivery is the host
|
|
8
|
-
application's responsibility. The `mail` gem is a soft dependency.
|
|
6
|
+
- `send_email` effect: builds `Mail::Message` objects (multipart text/HTML) from `{{field}}` templates into `Answers#outbox`; delivery is the host application's responsibility. The `mail` gem is a soft dependency.
|
|
9
7
|
- `run { |answers, outbox| ... }` escape-hatch effect (stripped from JSON)
|
|
10
|
-
- `webhook` effect: POSTs the answers envelope to a static https URL whose
|
|
11
|
-
host must be covered by the new top-level `allowed_domains` declaration;
|
|
12
|
-
enforcement runs in `Definition#validate!`, so tampered JSON definitions
|
|
13
|
-
fail at rehydration
|
|
8
|
+
- `webhook` effect: POSTs the answers envelope to a static https URL whose host must be covered by the new top-level `allowed_domains` declaration; enforcement runs in `Definition#validate!`, so tampered JSON definitions fail at rehydration
|
|
14
9
|
- `Inquirex::Actions::Runner` and `Inquirex::Actions.run(definition, answers)`
|
|
15
10
|
- Actions serialize to/from JSON with their rule gates
|
|
16
|
-
- `CompletionMetadata` (OpenStruct; `engine` and `engine_version` required)
|
|
17
|
-
stamped by the engine at flow completion, enrichable by front-ends via the
|
|
18
|
-
new `Engine#after_completion` hook, persisted in engine state, and merged
|
|
19
|
-
into answers by `Engine#answers_with_metadata`
|
|
11
|
+
- `CompletionMetadata` (OpenStruct; `engine` and `engine_version` required) stamped by the engine at flow completion, enrichable by front-ends via the new `Engine#after_completion` hook, persisted in engine state, and merged into answers by `Engine#answers_with_metadata`
|
|
20
12
|
|
|
21
13
|
## [0.1.0] - 2026-04-13
|
|
22
14
|
|
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@ It provides a rich DSL for creating dynamic user intake forms, with complexity r
|
|
|
31
31
|
>
|
|
32
32
|
> For technically inclined, Inquirex turns user forms into a directed graph, where nodes are either questions or statements (or UI transitions), while edges are AST-based logical conditions that can be stacked and joined in arbitrarily complex ways, allowing you to move from one question to any other based on the previous answer. See the details below.
|
|
33
33
|
|
|
34
|
-
***Don't want to deal with figuring it out? Head to [Qualified.At](https://qualified.at
|
|
34
|
+
***Don't want to deal with figuring it out? Head to [Qualified.At](https://qualified.at) and walk through the demo onboarding form, that exists specifically to show you how quickly you can have the same conceptually on your site, tailored to YOUR users.***
|
|
35
35
|
|
|
36
36
|
## Summary
|
|
37
37
|
|
|
@@ -435,11 +435,7 @@ Behavior:
|
|
|
435
435
|
- Use `finished?` to detect completion
|
|
436
436
|
- Use `total(:price)` / `totals` to read running totals
|
|
437
437
|
- Use `to_state` / `.from_state` for persistence/resume (totals included)
|
|
438
|
-
- Use `prefill!(hash)` to merge externally-supplied answers into the state,
|
|
439
|
-
e.g. fields extracted by an LLM from a free-text answer (see
|
|
440
|
-
[inquirex-llm](#extension-gems)). Existing answers are preserved; `nil`
|
|
441
|
-
and empty values are ignored so they don't spuriously satisfy
|
|
442
|
-
`not_empty` rules. The engine auto-advances past any newly-skippable step.
|
|
438
|
+
- Use `prefill!(hash)` to merge externally-supplied answers into the state, e.g. fields extracted by an LLM from a free-text answer (see [inquirex-llm](#extension-gems)). Existing answers are preserved; `nil` and empty values are ignored so they don't spuriously satisfy `not_empty` rules. The engine auto-advances past any newly-skippable step.
|
|
443
439
|
|
|
444
440
|
```ruby
|
|
445
441
|
engine = Inquirex::Engine.new(definition)
|
|
@@ -468,10 +464,7 @@ engine = Inquirex::Engine.new(definition, validator: my_validator)
|
|
|
468
464
|
|
|
469
465
|
## Completion Metadata
|
|
470
466
|
|
|
471
|
-
When a flow finishes, the engine guarantees a `CompletionMetadata` — an
|
|
472
|
-
OpenStruct describing how the answers were collected. Only `engine` and
|
|
473
|
-
`engine_version` are required members; rendering front-ends attach richer
|
|
474
|
-
environment details from an `after_completion` hook:
|
|
467
|
+
When a flow finishes, the engine guarantees a `CompletionMetadata` — an OpenStruct describing how the answers were collected. Only `engine` and `engine_version` are required members; rendering front-ends attach richer environment details from an `after_completion` hook:
|
|
475
468
|
|
|
476
469
|
```ruby
|
|
477
470
|
engine.after_completion do |eng|
|
|
@@ -485,21 +478,11 @@ engine.after_completion do |eng|
|
|
|
485
478
|
end
|
|
486
479
|
```
|
|
487
480
|
|
|
488
|
-
If no hook supplies one, the engine stamps the minimal core version
|
|
489
|
-
(`engine: "inquirex"`, `engine_version: Inquirex::VERSION`). The metadata
|
|
490
|
-
persists through `Engine#to_state` / `Engine.from_state`, and
|
|
491
|
-
`engine.answers_with_metadata` merges it into the answers hash under
|
|
492
|
-
`:completion_metadata` — which also makes it available to post-completion
|
|
493
|
-
actions: webhook payloads carry it, and email templates can interpolate
|
|
494
|
-
`{{completion_metadata.engine}}`.
|
|
481
|
+
If no hook supplies one, the engine stamps the minimal core version (`engine: "inquirex"`, `engine_version: Inquirex::VERSION`). The metadata persists through `Engine#to_state` / `Engine.from_state`, and `engine.answers_with_metadata` merges it into the answers hash under `:completion_metadata` — which also makes it available to post-completion actions: webhook payloads carry it, and email templates can interpolate `{{completion_metadata.engine}}`.
|
|
495
482
|
|
|
496
483
|
## Post-Completion Actions
|
|
497
484
|
|
|
498
|
-
After all questions are answered, `action` declarations run server-side with
|
|
499
|
-
the collected answers. The flagship effect is `send_email`, which **builds**
|
|
500
|
-
`Mail::Message` objects (the same object ActionMailer wraps) and attaches them
|
|
501
|
-
to `answers.outbox` — **nothing is delivered**; the host application decides
|
|
502
|
-
how and when to send.
|
|
485
|
+
After all questions are answered, `action` declarations run server-side with the collected answers. The flagship effect is `send_email`, which **builds** `Mail::Message` objects (the same object ActionMailer wraps) and attaches them to `answers.outbox` — **nothing is delivered**; the host application decides how and when to send.
|
|
503
486
|
|
|
504
487
|
```ruby
|
|
505
488
|
Inquirex.define id: "tax-intake-2025" do
|
|
@@ -554,31 +537,14 @@ end
|
|
|
554
537
|
|
|
555
538
|
Key semantics:
|
|
556
539
|
|
|
557
|
-
- **Templating is `{{field}}` interpolation only** — dot-notation keys resolved
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
The built-in `{{answers_summary}}` expands to all collected answers.
|
|
562
|
-
- **`if:` gates** reuse the serializable rule AST (`not_empty(:email)`, ...).
|
|
563
|
-
A false rule records `:skipped` — declare no actions (or gate them) when a
|
|
564
|
-
flow should only save answers.
|
|
565
|
-
- **`run { |answers, outbox| ... }`** is the full-Ruby escape hatch; like all
|
|
566
|
-
lambdas it is stripped from JSON.
|
|
567
|
-
- **Failures are isolated**: a raising effect records `:failed` in
|
|
568
|
-
`outbox.results` and never blocks other actions.
|
|
540
|
+
- **Templating is `{{field}}` interpolation only** — dot-notation keys resolved against `Answers#to_flat_h`, deliberately inert (no code execution), so definitions stored in a database render safely. Values interpolated into `html:` bodies are HTML-escaped automatically; `text:` bodies stay verbatim. The built-in `{{answers_summary}}` expands to all collected answers.
|
|
541
|
+
- **`if:` gates** reuse the serializable rule AST (`not_empty(:email)`, ...). A false rule records `:skipped` — declare no actions (or gate them) when a flow should only save answers.
|
|
542
|
+
- **`run { |answers, outbox| ... }`** is the full-Ruby escape hatch; like all lambdas it is stripped from JSON.
|
|
543
|
+
- **Failures are isolated**: a raising effect records `:failed` in `outbox.results` and never blocks other actions.
|
|
569
544
|
- **Images** in HTML bodies must be external URLs; attachments are unsupported.
|
|
570
|
-
- The `mail` gem is a soft dependency, needed only when a message is built
|
|
571
|
-
|
|
572
|
-
-
|
|
573
|
-
URL's host must be covered by `allowed_domains`, declared at the top of the
|
|
574
|
-
definition so the flow's egress surface is auditable at a glance. The check
|
|
575
|
-
runs inside `Definition.new` — a JSON definition whose webhook URL was
|
|
576
|
-
tampered with fails at *rehydration*, before anything executes. Also
|
|
577
|
-
enforced: https only (plain http just for localhost), no userinfo, no
|
|
578
|
-
`{{field}}` templates in URLs (the destination must be static), redirects
|
|
579
|
-
are not followed, and non-2xx responses record `:failed`.
|
|
580
|
-
- Effects are extensible: `Inquirex::Actions.register(:save_record, MyEffect)`
|
|
581
|
-
gives a new verb both DSL and JSON wire support.
|
|
545
|
+
- The `mail` gem is a soft dependency, needed only when a message is built (Rails hosts already have it via ActionMailer).
|
|
546
|
+
- **`webhook url:`** POSTs `{"answers": {...}}` as JSON to a static URL. The URL's host must be covered by `allowed_domains`, declared at the top of the definition so the flow's egress surface is auditable at a glance. The check runs inside `Definition.new` — a JSON definition whose webhook URL was tampered with fails at *rehydration*, before anything executes. Also enforced: https only (plain http just for localhost), no userinfo, no `{{field}}` templates in URLs (the destination must be static), redirects are not followed, and non-2xx responses record `:failed`.
|
|
547
|
+
- Effects are extensible: `Inquirex::Actions.register(:save_record, MyEffect)` gives a new verb both DSL and JSON wire support.
|
|
582
548
|
|
|
583
549
|
## Serialization
|
|
584
550
|
|
|
@@ -597,11 +563,8 @@ Serialized structure includes:
|
|
|
597
563
|
- Steps and transitions
|
|
598
564
|
- Rule AST payloads
|
|
599
565
|
- Widget hints
|
|
600
|
-
- Post-completion actions (`actions`) with their rules and effects; `run`
|
|
601
|
-
|
|
602
|
-
omitted entirely
|
|
603
|
-
- The `allowed_domains` egress allowlist, re-enforced against webhook URLs
|
|
604
|
-
every time a definition is rehydrated
|
|
566
|
+
- Post-completion actions (`actions`) with their rules and effects; `run` blocks are stripped, and an action left with no serializable effects is omitted entirely
|
|
567
|
+
- The `allowed_domains` egress allowlist, re-enforced against webhook URLs every time a definition is rehydrated
|
|
605
568
|
|
|
606
569
|
Important serialization details:
|
|
607
570
|
|
data/lib/.DS_Store
ADDED
|
Binary file
|
|
@@ -11,6 +11,7 @@ module Inquirex
|
|
|
11
11
|
history: ->(v) { Array(v).map { |e| e&.to_sym } },
|
|
12
12
|
answers: ->(v) { symbolize_answers(v) },
|
|
13
13
|
totals: ->(v) { symbolize_answers(v) },
|
|
14
|
+
suggestions: ->(v) { symbolize_answers(v) },
|
|
14
15
|
completion_metadata: ->(v) { symbolize_answers(v) }
|
|
15
16
|
}.freeze
|
|
16
17
|
|
data/lib/inquirex/engine.rb
CHANGED
|
@@ -21,6 +21,15 @@ module Inquirex
|
|
|
21
21
|
# @return [CompletionMetadata, nil] nil until the flow finishes
|
|
22
22
|
attr_accessor :completion_metadata
|
|
23
23
|
|
|
24
|
+
# Answer suggestions produced by prefill! for multi-select steps, keyed by
|
|
25
|
+
# step id. A suggestion pre-populates the step's choices in a renderer but
|
|
26
|
+
# — unlike an answer — never satisfies skip_if rules: multi-select
|
|
27
|
+
# extraction is treated as a hint the user confirms and may extend, not a
|
|
28
|
+
# deterministic fact. Cleared per step once the user answers it.
|
|
29
|
+
#
|
|
30
|
+
# @return [Hash{Symbol => Array}]
|
|
31
|
+
attr_reader :suggestions
|
|
32
|
+
|
|
24
33
|
# Exceptions raised by after_completion hooks, in the order they were
|
|
25
34
|
# raised. Hooks are isolated from one another, so a raising hook is
|
|
26
35
|
# recorded here rather than propagated — callers that care can inspect
|
|
@@ -41,6 +50,7 @@ module Inquirex
|
|
|
41
50
|
@completion_metadata = nil
|
|
42
51
|
@after_completion_hooks = []
|
|
43
52
|
@completion_hook_errors = []
|
|
53
|
+
@suggestions = {}
|
|
44
54
|
@history << @current_step_id
|
|
45
55
|
skip_display_steps_if_needed
|
|
46
56
|
end
|
|
@@ -81,6 +91,7 @@ module Inquirex
|
|
|
81
91
|
raise Errors::ValidationError, "Validation failed: #{result.errors.join(", ")}" unless result.valid?
|
|
82
92
|
|
|
83
93
|
@answers[@current_step_id] = value
|
|
94
|
+
@suggestions.delete(@current_step_id)
|
|
84
95
|
apply_accumulations(current_step, value)
|
|
85
96
|
advance_step
|
|
86
97
|
end
|
|
@@ -115,12 +126,28 @@ module Inquirex
|
|
|
115
126
|
next if value.respond_to?(:empty?) && value.empty?
|
|
116
127
|
|
|
117
128
|
sym = key.to_sym
|
|
118
|
-
|
|
129
|
+
if multi_select_step?(sym)
|
|
130
|
+
# Multi-select extraction is a hint, not a fact: the user may have
|
|
131
|
+
# more selections in mind than the text revealed. Record it as a
|
|
132
|
+
# suggestion so renderers pre-check the choices while the question
|
|
133
|
+
# is still asked; skip_if rules see no answer and do not fire.
|
|
134
|
+
@suggestions[sym] = Array(value) unless @answers.key?(sym)
|
|
135
|
+
else
|
|
136
|
+
@answers[sym] = value unless @answers.key?(sym)
|
|
137
|
+
end
|
|
119
138
|
end
|
|
120
139
|
skip_if_needed unless finished?
|
|
121
140
|
@answers
|
|
122
141
|
end
|
|
123
142
|
|
|
143
|
+
# The prefill suggestion for a step, or nil when none was recorded.
|
|
144
|
+
#
|
|
145
|
+
# @param step_id [Symbol, String] step id
|
|
146
|
+
# @return [Array, nil] suggested selections for a multi-select step
|
|
147
|
+
def suggestion_for(step_id)
|
|
148
|
+
@suggestions[step_id.to_sym]
|
|
149
|
+
end
|
|
150
|
+
|
|
124
151
|
# Registers a hook to run when the flow finishes. The block receives the
|
|
125
152
|
# engine; front-ends typically use it to attach a rich
|
|
126
153
|
# completion_metadata (host, user, ips, terminal, ...). Optional — after
|
|
@@ -163,6 +190,7 @@ module Inquirex
|
|
|
163
190
|
answers: @answers,
|
|
164
191
|
history: @history,
|
|
165
192
|
totals: @totals,
|
|
193
|
+
suggestions: @suggestions,
|
|
166
194
|
completion_metadata: @completion_metadata&.to_h
|
|
167
195
|
}
|
|
168
196
|
end
|
|
@@ -202,6 +230,16 @@ module Inquirex
|
|
|
202
230
|
@completion_metadata = CompletionMetadata.from_h(state[:completion_metadata])
|
|
203
231
|
@after_completion_hooks = []
|
|
204
232
|
@completion_hook_errors = []
|
|
233
|
+
@suggestions = state[:suggestions] || {}
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Whether +step_id+ names a multi-select step in the definition. Unknown
|
|
237
|
+
# ids (e.g. an extract schema field that matches no step) are not.
|
|
238
|
+
#
|
|
239
|
+
# @param step_id [Symbol]
|
|
240
|
+
# @return [Boolean]
|
|
241
|
+
def multi_select_step?(step_id)
|
|
242
|
+
@definition.step_ids.include?(step_id) && @definition.step(step_id).type == :multi_enum
|
|
205
243
|
end
|
|
206
244
|
|
|
207
245
|
def init_totals
|
data/lib/inquirex/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inquirex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
@@ -36,23 +36,10 @@ executables: []
|
|
|
36
36
|
extensions: []
|
|
37
37
|
extra_rdoc_files: []
|
|
38
38
|
files:
|
|
39
|
-
- ".relaxed_rubocop.yml"
|
|
40
|
-
- ".rub"
|
|
41
|
-
- ".ruby-version"
|
|
42
|
-
- ".secrets.baseline"
|
|
43
|
-
- Brewfile
|
|
44
39
|
- CHANGELOG.md
|
|
45
40
|
- LICENSE.txt
|
|
46
41
|
- README.md
|
|
47
|
-
-
|
|
48
|
-
- docs/badges/coverage_badge.svg
|
|
49
|
-
- examples/01_readme_example.rb
|
|
50
|
-
- examples/02_readme_mermaid.png
|
|
51
|
-
- examples/02_readme_mermaid.rb
|
|
52
|
-
- examples/03_send_email_actions.rb
|
|
53
|
-
- examples/README.md
|
|
54
|
-
- justfile
|
|
55
|
-
- lefthook.yml
|
|
42
|
+
- lib/.DS_Store
|
|
56
43
|
- lib/inquirex.rb
|
|
57
44
|
- lib/inquirex/accumulator.rb
|
|
58
45
|
- lib/inquirex/actions.rb
|
|
@@ -92,7 +79,6 @@ files:
|
|
|
92
79
|
- lib/inquirex/version.rb
|
|
93
80
|
- lib/inquirex/widget_hint.rb
|
|
94
81
|
- lib/inquirex/widget_registry.rb
|
|
95
|
-
- sig/inquirex.rbs
|
|
96
82
|
homepage: https://github.com/inquirex/inquirex
|
|
97
83
|
licenses:
|
|
98
84
|
- MIT
|
data/.relaxed_rubocop.yml
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
# Relaxed.Ruby.Style
|
|
2
|
-
## Version 2.5
|
|
3
|
-
|
|
4
|
-
Style/Alias:
|
|
5
|
-
Enabled: false
|
|
6
|
-
StyleGuide: https://relaxed.ruby.style/#stylealias
|
|
7
|
-
|
|
8
|
-
Style/AsciiComments:
|
|
9
|
-
Enabled: false
|
|
10
|
-
StyleGuide: https://relaxed.ruby.style/#styleasciicomments
|
|
11
|
-
|
|
12
|
-
Style/BeginBlock:
|
|
13
|
-
Enabled: false
|
|
14
|
-
StyleGuide: https://relaxed.ruby.style/#stylebeginblock
|
|
15
|
-
|
|
16
|
-
Style/BlockDelimiters:
|
|
17
|
-
Enabled: false
|
|
18
|
-
StyleGuide: https://relaxed.ruby.style/#styleblockdelimiters
|
|
19
|
-
|
|
20
|
-
Style/CommentAnnotation:
|
|
21
|
-
Enabled: false
|
|
22
|
-
StyleGuide: https://relaxed.ruby.style/#stylecommentannotation
|
|
23
|
-
|
|
24
|
-
Style/Documentation:
|
|
25
|
-
Enabled: false
|
|
26
|
-
StyleGuide: https://relaxed.ruby.style/#styledocumentation
|
|
27
|
-
|
|
28
|
-
Layout/DotPosition:
|
|
29
|
-
Enabled: false
|
|
30
|
-
StyleGuide: https://relaxed.ruby.style/#layoutdotposition
|
|
31
|
-
|
|
32
|
-
Style/DoubleNegation:
|
|
33
|
-
Enabled: false
|
|
34
|
-
StyleGuide: https://relaxed.ruby.style/#styledoublenegation
|
|
35
|
-
|
|
36
|
-
Style/EndBlock:
|
|
37
|
-
Enabled: false
|
|
38
|
-
StyleGuide: https://relaxed.ruby.style/#styleendblock
|
|
39
|
-
|
|
40
|
-
Style/FormatString:
|
|
41
|
-
Enabled: false
|
|
42
|
-
StyleGuide: https://relaxed.ruby.style/#styleformatstring
|
|
43
|
-
|
|
44
|
-
Style/IfUnlessModifier:
|
|
45
|
-
Enabled: false
|
|
46
|
-
StyleGuide: https://relaxed.ruby.style/#styleifunlessmodifier
|
|
47
|
-
|
|
48
|
-
Style/Lambda:
|
|
49
|
-
Enabled: false
|
|
50
|
-
StyleGuide: https://relaxed.ruby.style/#stylelambda
|
|
51
|
-
|
|
52
|
-
Style/ModuleFunction:
|
|
53
|
-
Enabled: false
|
|
54
|
-
StyleGuide: https://relaxed.ruby.style/#stylemodulefunction
|
|
55
|
-
|
|
56
|
-
Style/MultilineBlockChain:
|
|
57
|
-
Enabled: false
|
|
58
|
-
StyleGuide: https://relaxed.ruby.style/#stylemultilineblockchain
|
|
59
|
-
|
|
60
|
-
Style/NegatedIf:
|
|
61
|
-
Enabled: false
|
|
62
|
-
StyleGuide: https://relaxed.ruby.style/#stylenegatedif
|
|
63
|
-
|
|
64
|
-
Style/NegatedWhile:
|
|
65
|
-
Enabled: false
|
|
66
|
-
StyleGuide: https://relaxed.ruby.style/#stylenegatedwhile
|
|
67
|
-
|
|
68
|
-
Style/NumericPredicate:
|
|
69
|
-
Enabled: false
|
|
70
|
-
StyleGuide: https://relaxed.ruby.style/#stylenumericpredicate
|
|
71
|
-
|
|
72
|
-
Style/ParallelAssignment:
|
|
73
|
-
Enabled: false
|
|
74
|
-
StyleGuide: https://relaxed.ruby.style/#styleparallelassignment
|
|
75
|
-
|
|
76
|
-
Style/PercentLiteralDelimiters:
|
|
77
|
-
Enabled: false
|
|
78
|
-
StyleGuide: https://relaxed.ruby.style/#stylepercentliteraldelimiters
|
|
79
|
-
|
|
80
|
-
Style/PerlBackrefs:
|
|
81
|
-
Enabled: false
|
|
82
|
-
StyleGuide: https://relaxed.ruby.style/#styleperlbackrefs
|
|
83
|
-
|
|
84
|
-
Style/Semicolon:
|
|
85
|
-
Enabled: false
|
|
86
|
-
StyleGuide: https://relaxed.ruby.style/#stylesemicolon
|
|
87
|
-
|
|
88
|
-
Style/SignalException:
|
|
89
|
-
Enabled: false
|
|
90
|
-
StyleGuide: https://relaxed.ruby.style/#stylesignalexception
|
|
91
|
-
|
|
92
|
-
Style/SingleLineBlockParams:
|
|
93
|
-
Enabled: false
|
|
94
|
-
StyleGuide: https://relaxed.ruby.style/#stylesinglelineblockparams
|
|
95
|
-
|
|
96
|
-
Style/SingleLineMethods:
|
|
97
|
-
Enabled: false
|
|
98
|
-
StyleGuide: https://relaxed.ruby.style/#stylesinglelinemethods
|
|
99
|
-
|
|
100
|
-
Layout/SpaceBeforeBlockBraces:
|
|
101
|
-
Enabled: false
|
|
102
|
-
StyleGuide: https://relaxed.ruby.style/#layoutspacebeforeblockbraces
|
|
103
|
-
|
|
104
|
-
Layout/SpaceInsideParens:
|
|
105
|
-
Enabled: false
|
|
106
|
-
StyleGuide: https://relaxed.ruby.style/#layoutspaceinsideparens
|
|
107
|
-
|
|
108
|
-
Style/SpecialGlobalVars:
|
|
109
|
-
Enabled: false
|
|
110
|
-
StyleGuide: https://relaxed.ruby.style/#stylespecialglobalvars
|
|
111
|
-
|
|
112
|
-
Style/StringLiterals:
|
|
113
|
-
Enabled: false
|
|
114
|
-
StyleGuide: https://relaxed.ruby.style/#stylestringliterals
|
|
115
|
-
|
|
116
|
-
Style/TrailingCommaInArguments:
|
|
117
|
-
Enabled: false
|
|
118
|
-
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarguments
|
|
119
|
-
|
|
120
|
-
Style/TrailingCommaInArrayLiteral:
|
|
121
|
-
Enabled: false
|
|
122
|
-
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarrayliteral
|
|
123
|
-
|
|
124
|
-
Style/TrailingCommaInHashLiteral:
|
|
125
|
-
Enabled: false
|
|
126
|
-
StyleGuide: https://relaxed.ruby.style/#styletrailingcommainhashliteral
|
|
127
|
-
|
|
128
|
-
Style/SymbolArray:
|
|
129
|
-
Enabled: false
|
|
130
|
-
StyleGuide: http://relaxed.ruby.style/#stylesymbolarray
|
|
131
|
-
|
|
132
|
-
Style/WhileUntilModifier:
|
|
133
|
-
Enabled: false
|
|
134
|
-
StyleGuide: https://relaxed.ruby.style/#stylewhileuntilmodifier
|
|
135
|
-
|
|
136
|
-
Style/WordArray:
|
|
137
|
-
Enabled: false
|
|
138
|
-
StyleGuide: https://relaxed.ruby.style/#stylewordarray
|
|
139
|
-
|
|
140
|
-
Lint/AmbiguousRegexpLiteral:
|
|
141
|
-
Enabled: false
|
|
142
|
-
StyleGuide: https://relaxed.ruby.style/#lintambiguousregexpliteral
|
|
143
|
-
|
|
144
|
-
Lint/AssignmentInCondition:
|
|
145
|
-
Enabled: false
|
|
146
|
-
StyleGuide: https://relaxed.ruby.style/#lintassignmentincondition
|
|
147
|
-
|
|
148
|
-
Layout/LineLength:
|
|
149
|
-
Enabled: false
|
|
150
|
-
|
|
151
|
-
Metrics:
|
|
152
|
-
Enabled: false
|
|
153
|
-
|
data/.rub
DELETED
|
File without changes
|
data/.ruby-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4.0.5
|
data/.secrets.baseline
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "1.5.0",
|
|
3
|
-
"plugins_used": [
|
|
4
|
-
{
|
|
5
|
-
"name": "ArtifactoryDetector"
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
"name": "AWSKeyDetector"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"name": "AzureStorageKeyDetector"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "Base64HighEntropyString",
|
|
15
|
-
"limit": 4.5
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"name": "BasicAuthDetector"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"name": "CloudantDetector"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"name": "DiscordBotTokenDetector"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"name": "GitHubTokenDetector"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"name": "GitLabTokenDetector"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"name": "HexHighEntropyString",
|
|
34
|
-
"limit": 3.0
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"name": "IbmCloudIamDetector"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"name": "IbmCosHmacDetector"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"name": "IPPublicDetector"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"name": "JwtTokenDetector"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"name": "KeywordDetector",
|
|
50
|
-
"keyword_exclude": ""
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"name": "MailchimpDetector"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"name": "NpmDetector"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"name": "OpenAIDetector"
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"name": "PrivateKeyDetector"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"name": "PypiTokenDetector"
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"name": "SendGridDetector"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"name": "SlackDetector"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"name": "SoftlayerDetector"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"name": "SquareOAuthDetector"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"name": "StripeDetector"
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"name": "TelegramBotTokenDetector"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"name": "TwilioKeyDetector"
|
|
87
|
-
}
|
|
88
|
-
],
|
|
89
|
-
"filters_used": [
|
|
90
|
-
{
|
|
91
|
-
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
|
|
95
|
-
"min_level": 2
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"path": "detect_secrets.filters.heuristic.is_lock_file"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"path": "detect_secrets.filters.heuristic.is_sequential_string"
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
"path": "detect_secrets.filters.heuristic.is_swagger_file"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
"path": "detect_secrets.filters.heuristic.is_templated_secret"
|
|
123
|
-
}
|
|
124
|
-
],
|
|
125
|
-
"results": {},
|
|
126
|
-
"generated_at": "2026-04-13T21:29:03Z"
|
|
127
|
-
}
|
data/Brewfile
DELETED
data/Rakefile
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "rspec/core/rake_task"
|
|
5
|
-
require "timeout"
|
|
6
|
-
require "yard"
|
|
7
|
-
|
|
8
|
-
def shell(*args)
|
|
9
|
-
puts "running: #{args.join(" ")}"
|
|
10
|
-
system(args.join(" "))
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
task :clean do
|
|
14
|
-
shell("rm -rf pkg/ tmp/ coverage/ doc/ ")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
task gem: [:build] do
|
|
18
|
-
shell("gem install pkg/*")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
task permissions: [:clean] do
|
|
22
|
-
shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
|
|
23
|
-
shell("find . -type d -exec chmod o+x,g+x {} \\;")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
task build: :permissions
|
|
27
|
-
|
|
28
|
-
YARD::Rake::YardocTask.new(:doc) do |t|
|
|
29
|
-
t.files = %w[lib/**/*.rb exe/*.rb - README.md LICENSE.txt CHANGELOG.md]
|
|
30
|
-
t.options.unshift("--title", '"FlowEngine — DSL + AST for buildiong complex flows in Ruby."')
|
|
31
|
-
t.after = -> { exec("open doc/index.html") } if RUBY_PLATFORM =~ /darwin/
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
RSpec::Core::RakeTask.new(:spec)
|
|
35
|
-
|
|
36
|
-
task default: :spec
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
|
|
3
|
-
<linearGradient id="b" x2="0" y2="100%">
|
|
4
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
5
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<mask id="a">
|
|
8
|
-
<rect width="99" height="20" rx="3" fill="#fff"/>
|
|
9
|
-
</mask>
|
|
10
|
-
<g mask="url(#a)">
|
|
11
|
-
<path fill="#555" d="M0 0h63v20H0z"/>
|
|
12
|
-
<path fill="#4c1" d="M63 0h36v20H63z"/>
|
|
13
|
-
<path fill="url(#b)" d="M0 0h99v20H0z"/>
|
|
14
|
-
</g>
|
|
15
|
-
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
|
16
|
-
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
|
17
|
-
<text x="31.5" y="14">coverage</text>
|
|
18
|
-
<text x="80" y="15" fill="#010101" fill-opacity=".3">96%</text>
|
|
19
|
-
<text x="80" y="14">96%</text>
|
|
20
|
-
</g>
|
|
21
|
-
</svg>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "inquirex"
|
|
6
|
-
|
|
7
|
-
DEFINITION = Inquirex.define id: "tax-intake-2025", version: "1.0.0" do
|
|
8
|
-
meta title: "Tax Preparation Intake", subtitle: "Let's understand your situation"
|
|
9
|
-
start :filing_status
|
|
10
|
-
|
|
11
|
-
ask :filing_status do
|
|
12
|
-
type :enum
|
|
13
|
-
question "What is your filing status?"
|
|
14
|
-
options single: "Single", married_jointly: "Married Filing Jointly"
|
|
15
|
-
widget target: :desktop, type: :radio_group, columns: 2
|
|
16
|
-
widget target: :mobile, type: :dropdown
|
|
17
|
-
transition to: :dependents
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
ask :dependents do
|
|
21
|
-
type :integer
|
|
22
|
-
question "How many dependents?"
|
|
23
|
-
default 0
|
|
24
|
-
transition to: :business_income
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
confirm :business_income do
|
|
28
|
-
question "Do you have business income?"
|
|
29
|
-
transition to: :business_count, if_rule: equals(:business_income, true)
|
|
30
|
-
transition to: :done
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
ask :business_count do
|
|
34
|
-
type :integer
|
|
35
|
-
question "How many businesses?"
|
|
36
|
-
transition to: :done
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
say :done do
|
|
40
|
-
text "Thanks for completing the intake."
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
engine = Inquirex::Engine.new(DEFINITION)
|
|
45
|
-
|
|
46
|
-
engine.answer("single") # filing_status
|
|
47
|
-
engine.answer(2) # dependents
|
|
48
|
-
engine.answer(false) # business_income
|
|
49
|
-
engine.advance # done (display step)
|
|
50
|
-
engine.finished? # => true
|
|
51
|
-
|
|
52
|
-
if __FILE__ == $0
|
|
53
|
-
require 'json'
|
|
54
|
-
puts JSON.pretty_generate(DEFINITION.to_h)
|
|
55
|
-
end
|
|
Binary file
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require_relative '01_readme_example'
|
|
4
|
-
require 'inquirex'
|
|
5
|
-
require 'stringio'
|
|
6
|
-
|
|
7
|
-
output = StringIO.new
|
|
8
|
-
exporter = Inquirex::Graph::MermaidExporter.new(DEFINITION)
|
|
9
|
-
output << exporter.export
|
|
10
|
-
|
|
11
|
-
source = <<~HTML
|
|
12
|
-
<html>
|
|
13
|
-
<head>
|
|
14
|
-
<meta charset="utf-8">
|
|
15
|
-
</head>
|
|
16
|
-
<body>
|
|
17
|
-
<meta charset="utf-8">
|
|
18
|
-
<div class="mermaid">
|
|
19
|
-
#{output.string}
|
|
20
|
-
</div>
|
|
21
|
-
<script type="module">
|
|
22
|
-
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
23
|
-
mermaid.initialize({ startOnLoad: true });
|
|
24
|
-
</script>
|
|
25
|
-
</html>
|
|
26
|
-
HTML
|
|
27
|
-
|
|
28
|
-
if __FILE__ == $0
|
|
29
|
-
File.write('mermaid.html', source)
|
|
30
|
-
system("open mermaid.html")
|
|
31
|
-
sleep 10
|
|
32
|
-
|
|
33
|
-
at_exit do
|
|
34
|
-
File.delete('mermaid.html')
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# Example 03: Post-completion actions building emails into the outbox.
|
|
5
|
-
#
|
|
6
|
-
# The `action` verb runs server-side after the flow finishes. send_email
|
|
7
|
-
# builds Mail::Message objects — nothing is delivered here; a host Rails app
|
|
8
|
-
# would iterate answers.outbox and deliver via its own ActionMailer config.
|
|
9
|
-
#
|
|
10
|
-
# Run:
|
|
11
|
-
# bundle exec ruby examples/03_send_email_actions.rb
|
|
12
|
-
|
|
13
|
-
require "bundler/setup"
|
|
14
|
-
require "inquirex"
|
|
15
|
-
|
|
16
|
-
DEFINITION = Inquirex.define id: "lead-intake", version: "1.0.0" do
|
|
17
|
-
# Egress allowlist: webhook effects may only POST to these hosts.
|
|
18
|
-
allowed_domains "*.agentica.group"
|
|
19
|
-
|
|
20
|
-
meta title: "Lead Intake", subtitle: "Tell us about your project"
|
|
21
|
-
start :name
|
|
22
|
-
|
|
23
|
-
ask :name do
|
|
24
|
-
type :string
|
|
25
|
-
question "What is your name?"
|
|
26
|
-
transition to: :email
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
ask :email do
|
|
30
|
-
type :email
|
|
31
|
-
question "Where can we reach you? (leave blank to skip the receipt)"
|
|
32
|
-
transition to: :budget
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
ask :budget do
|
|
36
|
-
type :currency
|
|
37
|
-
question "What is your approximate budget?"
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Sent only when the visitor left an email address.
|
|
41
|
-
action :client_receipt, if: not_empty(:email) do
|
|
42
|
-
send_email to: "{{email}}",
|
|
43
|
-
from: "forms@agentica.group",
|
|
44
|
-
subject: "Thanks {{name}} — we got your inquiry",
|
|
45
|
-
text: <<~TEXT,
|
|
46
|
-
Hi {{name}},
|
|
47
|
-
|
|
48
|
-
We received your answers and will reply within one business day.
|
|
49
|
-
|
|
50
|
-
{{answers_summary}}
|
|
51
|
-
TEXT
|
|
52
|
-
html: <<~HTML
|
|
53
|
-
<p>Hi {{name}},</p>
|
|
54
|
-
<p>We received your answers and will reply within one business day.</p>
|
|
55
|
-
{{answers_summary}}
|
|
56
|
-
HTML
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Always notify the site owner, and demonstrate the Ruby escape hatch.
|
|
60
|
-
action :admin_alert do
|
|
61
|
-
send_email to: "owner@agentica.group",
|
|
62
|
-
from: "forms@agentica.group",
|
|
63
|
-
subject: "New lead: {{name}} (budget {{budget}})",
|
|
64
|
-
html: "{{answers_summary}}"
|
|
65
|
-
run { |answers, _outbox| puts ">> run{} saw budget: #{answers.budget}" }
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Webhook to an allowed_domains host. Gated by an always-false rule so this
|
|
69
|
-
# example runs offline — it records :skipped instead of POSTing. Drop the
|
|
70
|
-
# if: to exercise it for real.
|
|
71
|
-
action :crm_push, if: equals(:name, "__network_demo__") do
|
|
72
|
-
webhook url: "https://hooks.agentica.group/inquirex",
|
|
73
|
-
headers: { "X-Api-Key" => "demo" }
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
answers = Inquirex::Actions.run(
|
|
78
|
-
DEFINITION,
|
|
79
|
-
name: "Ada Lovelace",
|
|
80
|
-
email: "ada@lovelace.io",
|
|
81
|
-
budget: 12_500.00
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
puts "Built #{answers.outbox.size} message(s):"
|
|
85
|
-
answers.outbox.each do |mail|
|
|
86
|
-
puts "-" * 60
|
|
87
|
-
puts "To: #{mail.to.join(", ")}"
|
|
88
|
-
puts "Subject: #{mail.subject}"
|
|
89
|
-
puts "Parts: #{mail.multipart? ? "text + html" : mail.content_type}"
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
puts "-" * 60
|
|
93
|
-
puts "Results: #{answers.outbox.results.map { |r| "#{r.action_id}=#{r.status}" }.join(", ")}"
|
|
94
|
-
|
|
95
|
-
# The definition (rules and all) round-trips through JSON — run{} is stripped:
|
|
96
|
-
restored = Inquirex::Definition.from_json(DEFINITION.to_json)
|
|
97
|
-
puts "Actions after JSON round-trip: #{restored.actions.map(&:id).inspect}"
|
data/examples/README.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Examples
|
|
2
|
-
|
|
3
|
-
This folder contains just a couple examples to demonstrate the API and the functionality.
|
|
4
|
-
|
|
5
|
-
For a fuller list of more comprehensive examples, please see the [examples in the `inquirex-tty` gem](https://github.com/inquirex/inquirex-tty/tree/main/examples).
|
|
6
|
-
|
|
7
|
-
## Running Examples
|
|
8
|
-
|
|
9
|
-
These examples are meant to be run as executables from the root level of the gem folder.
|
|
10
|
-
|
|
11
|
-
### First Example
|
|
12
|
-
|
|
13
|
-
This example should print to stdout the DSL definition in JSON:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
# First example — creates a DSL definition and prints it to stdout in JSON format
|
|
17
|
-
./examples/01_readme_example.rb | jq
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
### Second Example
|
|
21
|
-
|
|
22
|
-
This is a more interesting example. It builds on the first, takes that definition and uses the mermaid converter to write a tiny HTML file with a mermaid diagram inside, which represents the definition defined in the first file.
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# creates a mermaid.html file at the root of the project
|
|
26
|
-
# opens the browser with the file and waits 10 seconds
|
|
27
|
-
# deletes the HTML file and exits
|
|
28
|
-
./examples/02_readme_mermaid.rb
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The mermaid file generated should look like this:
|
|
32
|
-
|
|
33
|
-
<img src="02_readme_mermaid.png" width="300px" text-align="left"></img>
|
data/justfile
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Tell 'just' to run bash, source our setup script, then execute the recipe
|
|
2
|
-
set shell := ["bash", "-c"]
|
|
3
|
-
|
|
4
|
-
version := `grep VERSION lib/inquirex/version.rb | awk '{print $3}' | tr -d '"' | tr -d '\n'`
|
|
5
|
-
rbenv := 'eval "$(rbenv init bash)"; bundle exec '
|
|
6
|
-
repo := 'git@github.com:inquirex/inquirex.git'
|
|
7
|
-
|
|
8
|
-
[no-exit-message]
|
|
9
|
-
recipes:
|
|
10
|
-
just --choose
|
|
11
|
-
|
|
12
|
-
# Sync all dependencies
|
|
13
|
-
install:
|
|
14
|
-
bin/setup
|
|
15
|
-
|
|
16
|
-
build: install
|
|
17
|
-
|
|
18
|
-
# Lint and reformat files
|
|
19
|
-
lint:
|
|
20
|
-
{{ rbenv }} rubocop
|
|
21
|
-
|
|
22
|
-
# Lint and reformat files (-a) — pass -A as an argument
|
|
23
|
-
format *args:
|
|
24
|
-
{{ rbenv }} rubocop -a {{ args }}
|
|
25
|
-
|
|
26
|
-
# Run all the tests
|
|
27
|
-
test *args:
|
|
28
|
-
export ENVIRONMENT=test; {{ rbenv }} rspec {{args}}
|
|
29
|
-
|
|
30
|
-
# Run tests with coverage
|
|
31
|
-
test-coverage *args:
|
|
32
|
-
export ENVIRONMENT=test; export COVERAGE=true; {{ rbenv }} rspec {{ args }}
|
|
33
|
-
|
|
34
|
-
ci: lint test-coverage
|
|
35
|
-
|
|
36
|
-
alias check-all := ci
|
|
37
|
-
|
|
38
|
-
clean:
|
|
39
|
-
#!/usr/bin/env bash
|
|
40
|
-
@find . -name .DS_Store -delete -print || true
|
|
41
|
-
@rm -rf tmp/*
|
|
42
|
-
|
|
43
|
-
# Run all lefthook pre-commit hooks
|
|
44
|
-
lefthook:
|
|
45
|
-
{{ rbenv }} lefthook run pre-commit --all-files
|
|
46
|
-
|
|
47
|
-
# Print current gem version
|
|
48
|
-
version:
|
|
49
|
-
@echo "{{ version }}"
|
|
50
|
-
|
|
51
|
-
# Clobber
|
|
52
|
-
clobber:
|
|
53
|
-
{{ rbenv }} rake clobber
|
|
54
|
-
|
|
55
|
-
# Generate documentation
|
|
56
|
-
doc:
|
|
57
|
-
#!/usr/bin/env bash
|
|
58
|
-
{{ rbenv }} rake doc
|
|
59
|
-
|
|
60
|
-
# Create
|
|
61
|
-
publish: build
|
|
62
|
-
{{ rbenv }} rake release[remote]
|
|
63
|
-
|
|
64
|
-
# Tag v{{ version }}, publish the GH release, & refresh the Homebrew tap.
|
|
65
|
-
release:
|
|
66
|
-
git fetch --tags
|
|
67
|
-
git tag -f "v{{ version }}"
|
|
68
|
-
git push -f --tags
|
|
69
|
-
gh release delete -y "v{{ version }}" --repo {{ repo }} 2>/dev/null || true
|
|
70
|
-
gh release create "v{{ version }}" --generate-notes --repo {{ repo }}
|
data/lefthook.yml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
output:
|
|
2
|
-
- summary
|
|
3
|
-
- failure
|
|
4
|
-
|
|
5
|
-
pre-commit:
|
|
6
|
-
parallel: true
|
|
7
|
-
jobs:
|
|
8
|
-
- name: lint
|
|
9
|
-
run: bundle exec rubocop -c .rubocop.yml {staged_files}
|
|
10
|
-
glob: "*.{rb,Gemfile}"
|
|
11
|
-
stage_fixed: true
|
|
12
|
-
|
|
13
|
-
- name: check for conflict markers and whitespace issues
|
|
14
|
-
run: git --no-pager diff --check
|
|
15
|
-
|
|
16
|
-
# If tests take >1 second, move this (or just the long-running tests) to pre-push.
|
|
17
|
-
- name: run tests
|
|
18
|
-
run: just test
|
|
19
|
-
|
|
20
|
-
- name: fix rubocop formatting issues
|
|
21
|
-
run: bundle exec rubocop -a {staged_files}
|
|
22
|
-
glob: "*.{rb,Gemfile,gemspec}"
|
|
23
|
-
stage_fixed: true
|
|
24
|
-
|
|
25
|
-
- name: spell check
|
|
26
|
-
run: codespell {staged_files}
|
|
27
|
-
glob: "*.{rb,md,gemspec}"
|
|
28
|
-
|
|
29
|
-
- name: format markdown
|
|
30
|
-
run: mdformat {staged_files}
|
|
31
|
-
glob: "*.md"
|
|
32
|
-
stage_fixed: true
|
|
33
|
-
|
|
34
|
-
- name: scan for secrets
|
|
35
|
-
run: detect-secrets-hook --baseline .secrets.baseline
|
data/sig/inquirex.rbs
DELETED