inquirex-tty 0.5.0 → 0.9.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d2a11293b1ac438c2ccd3b25cf1b18782e9b49e9b3e1d4d344e84216403cca9
4
- data.tar.gz: d4001771880c748982dbaa765a390f910d4d0e71772259981bb317af0c2696c7
3
+ metadata.gz: 6c91d8b125db72e34420575e33b12dd5fed05353e9df289ea4665f53e5d64a7b
4
+ data.tar.gz: c2b8f0bc334e8c47809cd38e4697fa165a75118032ee41aefc2ddb27f7e9f042
5
5
  SHA512:
6
- metadata.gz: '085bb14fd6cd73b341108763e61989b882ad4936f7b70ffd2a45089bd5bc930887ab7e7d85b8e2c15e682c77bdb8ba7384971a102199ae74038f2696c0af71dd'
7
- data.tar.gz: c6c92ee9cd25e7b23b1a0d6a839f7df0f92bc6a6a36c385a33ee2be4bd01004261c476bb4cf2a5689a2eca10afca1cfd23334546c4c12da7c4e89e42602ebc8f
6
+ metadata.gz: '0288a89785bbcb89b4437c48f4f96695fcbace9713ceb6eca2181d8cd2d9131b6c97ee26766300f9a95ac83dc72596d4e82e8287842b32d10a40f3ef6160e9b4'
7
+ data.tar.gz: a42da62f0f194c99bed2ad417ad35a2e16dfe6d50b9d91fc9262c5d2854229819c1da687858ab757cfd7e929fa4a4efd2f48253da751739a771fbc95d221965f
@@ -0,0 +1,5 @@
1
+ user=inquirex
2
+ project=inquirex-tty
3
+ exclude-labels=duplicate,question,invalid,wontfix
4
+ issues=false
5
+ add-sections={"security":{"prefix":"### Security","labels":["security"]}}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
- ## [Unreleased]
1
+ # Changelog
2
2
 
3
- ## [0.1.0] - 2026-04-13
3
+ ## [Unreleased](https://github.com/inquirex/inquirex-tty/tree/HEAD)
4
4
 
5
- - Initial release
5
+ [Full Changelog](https://github.com/inquirex/inquirex-tty/compare/v0.6.0...HEAD)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Fix CI: broken Gemfile path override, RuboCop scanning vendor/ [\#9](https://github.com/inquirex/inquirex-tty/pull/9) ([kigster](https://github.com/kigster))
10
+
11
+ ## [v0.6.0](https://github.com/inquirex/inquirex-tty/tree/v0.6.0) (2026-07-20)
12
+
13
+ [Full Changelog](https://github.com/inquirex/inquirex-tty/compare/v0.5.0...v0.6.0)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Document lib in YARD style to 100% coverage [\#8](https://github.com/inquirex/inquirex-tty/pull/8) ([kigster](https://github.com/kigster))
18
+ - Use $stderr.puts for CLI messages, not warn [\#7](https://github.com/inquirex/inquirex-tty/pull/7) ([kigster](https://github.com/kigster))
19
+
20
+ ## [v0.5.0](https://github.com/inquirex/inquirex-tty/tree/v0.5.0) (2026-07-16)
21
+
22
+ [Full Changelog](https://github.com/inquirex/inquirex-tty/compare/v0.4.0...v0.5.0)
23
+
24
+ ## [v0.4.0](https://github.com/inquirex/inquirex-tty/tree/v0.4.0) (2026-07-14)
25
+
26
+ [Full Changelog](https://github.com/inquirex/inquirex-tty/compare/971751bdfcbde3f1fd694cfb38d00bc3205b3e12...v0.4.0)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - Raise inquirex-tty test coverage from 79% to 99% [\#5](https://github.com/inquirex/inquirex-tty/pull/5) ([kigster](https://github.com/kigster))
31
+ - Update bundled dependencies [\#4](https://github.com/inquirex/inquirex-tty/pull/4) ([kigster](https://github.com/kigster))
32
+ - Integrate inquirex-llm, drop inquirex-ui dep, add LLM-assisted tax example [\#3](https://github.com/inquirex/inquirex-tty/pull/3) ([kigster](https://github.com/kigster))
33
+ - Add inquirex export command and shared OutputPath helper [\#2](https://github.com/inquirex/inquirex-tty/pull/2) ([kigster](https://github.com/kigster))
34
+ - Simplify graph command: merge open-graph, add "both" format [\#1](https://github.com/inquirex/inquirex-tty/pull/1) ([kigster](https://github.com/kigster))
35
+
36
+
37
+
38
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/README.md CHANGED
@@ -4,7 +4,11 @@
4
4
 
5
5
  Terminal adapter for the [Inquirex](https://github.com/inquirex/inquirex) questionnaire engine. Renders flow definitions as interactive ANSI terminal wizards using [tty-prompt](https://github.com/piotrmurach/tty-prompt), with ASCII-art headers, styled boxes, and automatic widget selection based on data types.
6
6
 
7
- Ships as a CLI (`inquirex`) with commands to run flows interactively, validate definitions, and export Mermaid diagrams.
7
+ Ships as a CLI (`inquirex-tty`) with commands to run flows interactively, validate definitions, and export Mermaid diagrams.
8
+
9
+ ## Inquirex CLI Shorthand Alias
10
+
11
+ This gem also installs a shorter command `inqt` which you can run in place of `inquirex-tty`.
8
12
 
9
13
  ## Installation
10
14
 
@@ -12,7 +16,7 @@ Ships as a CLI (`inquirex`) with commands to run flows interactively, validate d
12
16
  gem "inquirex-tty"
13
17
  ```
14
18
 
15
- The gem installs an `inquirex` executable.
19
+ The gem installs an `inquirex-tty` executable.
16
20
 
17
21
  ## Quick Start
18
22
 
@@ -47,30 +51,30 @@ end
47
51
  Run it:
48
52
 
49
53
  ```bash
50
- inquirex run my_flow.rb
54
+ inqt run my_flow.rb
51
55
  ```
52
56
 
53
57
  The CLI walks the user through each step, selecting the appropriate TTY widget for each data type, and prints collected answers as JSON when the flow completes.
54
58
 
55
59
  ## CLI Commands
56
60
 
57
- ### `inquirex run <flow_file>`
61
+ ### `inquirex-tty run <flow_file>`
58
62
 
59
63
  Execute a flow interactively. Each step is rendered with the appropriate tty-prompt widget based on the node's data type and widget hints.
60
64
 
61
65
  ```bash
62
66
  # run it and then dump answers as json to stdout
63
- inquirex run examples/08_tax_preparer.rb
67
+ inqt run examples/08_tax_preparer.rb
64
68
 
65
69
  # run it and save the anawers to a json file
66
- inquirex run examples/08_tax_preparer.rb \
70
+ inqt run examples/08_tax_preparer.rb \
67
71
  --output answers.json
68
72
  ```
69
73
 
70
74
  Options:
71
75
 
72
- | Flag | Description |
73
- |------|-------------|
76
+ | Flag | Description |
77
+ | ---------------- | ---------------------------------------------- |
74
78
  | `--output`, `-o` | Write JSON results to a file instead of stderr |
75
79
 
76
80
  On completion, outputs a JSON summary:
@@ -98,7 +102,7 @@ On completion, outputs a JSON summary:
98
102
  }
99
103
  ```
100
104
 
101
- ### `inquirex validate <flow_file>`
105
+ ### `inquirex-tty validate <flow_file>`
102
106
 
103
107
  Check that a flow definition is well-formed without running it. Validates:
104
108
 
@@ -107,49 +111,49 @@ Check that a flow definition is well-formed without running it. Validates:
107
111
  - All steps are reachable from the start step (detects orphans)
108
112
 
109
113
  ```bash
110
- inquirex validate examples/08_tax_preparer.rb
114
+ inqt validate examples/08_tax_preparer.rb
111
115
  ```
112
116
 
113
- ### `inquirex graph <flow_file>`
117
+ ### `inquirex-tty graph <flow_file>`
114
118
 
115
119
  Export the flow as a [Mermaid](https://mermaid.js.org/) diagram source, an image, or both.
116
120
 
117
121
  ```bash
118
- inquirex graph examples/08_tax_preparer.rb # Mermaid source to stdout
119
- inquirex graph examples/08_tax_preparer.rb --output flow.mmd # write source to a file
120
- inquirex graph examples/08_tax_preparer.rb --format image -o flow.svg # SVG via mmdc
121
- inquirex graph examples/08_tax_preparer.rb --format both --output ~/Desktop # source + image into a directory
122
- inquirex graph examples/08_tax_preparer.rb --format image --open # SVG + open in viewer
122
+ inqt graph examples/08_tax_preparer.rb # Mermaid source to stdout
123
+ inqt graph examples/08_tax_preparer.rb --output flow.mmd # write source to a file
124
+ inqt graph examples/08_tax_preparer.rb --format image -o flow.svg # SVG via mmdc
125
+ inqt graph examples/08_tax_preparer.rb --format both --output ~/Desktop # source + image into a directory
126
+ inqt graph examples/08_tax_preparer.rb --format image --open # SVG + open in viewer
123
127
  ```
124
128
 
125
129
  Options:
126
130
 
127
- | Flag | Description |
128
- |------|-------------|
129
- | `--output`, `-o` | Output file or directory (default: stdout) |
130
- | `--format`, `-f` | `source` (default), `image` (SVG via `mmdc`), or `both` |
131
- | `--open`, `-p` | Open the generated image in the system viewer (default: false) |
131
+ | Flag | Description |
132
+ | ---------------- | -------------------------------------------------------------- |
133
+ | `--output`, `-o` | Output file or directory (default: stdout) |
134
+ | `--format`, `-f` | `source` (default), `image` (SVG via `mmdc`), or `both` |
135
+ | `--open`, `-p` | Open the generated image in the system viewer (default: false) |
132
136
 
133
137
  Image generation requires [mermaid-cli](https://github.com/mermaid-js/mermaid-cli) (`npm install -g @mermaid-js/mermaid-cli`). The command attempts to install it automatically if `mmdc` is not on your `PATH`.
134
138
 
135
- ### `inquirex export <flow_file>`
139
+ ### `inquirex-tty export <flow_file>`
136
140
 
137
141
  Export the flow definition as JSON or YAML. Useful for serving flows to frontend adapters (the JS widget, Rails API, etc.) or for inspecting the wire format.
138
142
 
139
143
  ```bash
140
- inquirex export examples/08_tax_preparer.rb # pretty JSON to stdout
141
- inquirex export examples/08_tax_preparer.rb -f yml # YAML to stdout
142
- inquirex export examples/08_tax_preparer.rb -o . # write 08_tax_preparer.json to cwd
143
- inquirex export examples/08_tax_preparer.rb -f yml -o ~/flows # write 08_tax_preparer.yml to ~/flows
144
- inquirex export examples/08_tax_preparer.rb -o out.json # write to named file
145
- inquirex export examples/08_tax_preparer.rb -f yml -o out # appends .yml → out.yml
144
+ inqt export examples/08_tax_preparer.rb # pretty JSON to stdout
145
+ inqt export examples/08_tax_preparer.rb -f yml # YAML to stdout
146
+ inqt export examples/08_tax_preparer.rb -o . # write 08_tax_preparer.json to cwd
147
+ inqt export examples/08_tax_preparer.rb -f yml -o ~/flows # write 08_tax_preparer.yml to ~/flows
148
+ inqt export examples/08_tax_preparer.rb -o out.json # write to named file
149
+ inqt export examples/08_tax_preparer.rb -f yml -o out # appends .yml → out.yml
146
150
  ```
147
151
 
148
152
  Options:
149
153
 
150
- | Flag | Description |
151
- |------|-------------|
152
- | `--format`, `-f` | `json` (default), `yaml`, or `yml` |
154
+ | Flag | Description |
155
+ | ---------------- | ------------------------------------------ |
156
+ | `--format`, `-f` | `json` (default), `yaml`, or `yml` |
153
157
  | `--output`, `-o` | Output file or directory (default: stdout) |
154
158
 
155
159
  Output path rules:
@@ -158,12 +162,12 @@ Output path rules:
158
162
  - `--output <dir>` (existing directory) → write `<flow-basename>.<ext>` inside it
159
163
  - `--output <file>` → use that filename; if the extension is missing or mismatched, the appropriate one (`.json`/`.yml`) is substituted
160
164
 
161
- ### `inquirex version`
165
+ ### `inquirex-tty version`
162
166
 
163
167
  Print version information for the TTY adapter and its dependencies.
164
168
 
165
169
  ```bash
166
- inquirex version
170
+ inqt version
167
171
  ```
168
172
 
169
173
  ## Example Session
@@ -171,7 +175,7 @@ inquirex version
171
175
  Running the tax preparation intake example:
172
176
 
173
177
  ```
174
- $ inquirex run examples/08_tax_preparer.rb
178
+ $ inquirex-tty run examples/08_tax_preparer.rb
175
179
 
176
180
  _____ _ __ __ ____ ____ _____ ____ _ ____ _ _____ ___ ___ _ _ ___ _ _ _____ _ _ __ _____
177
181
  |_ _| / \ \ \/ / | _ \ | _ \ | ____| | _ \ / \ | _ \ / \ |_ _| |_ _| / _ \ | \ | | |_ _| | \ | | |_ _| / \ | |/ / | ____|
@@ -226,17 +230,17 @@ Press any key to continue...
226
230
 
227
231
  The renderer selects a tty-prompt method for each node based on the `:tty` widget hint from `WidgetRegistry`:
228
232
 
229
- | Widget Hint | tty-prompt Method | Used For |
230
- |-------------|-------------------|----------|
231
- | `text_input` | `prompt.ask` | `:string`, `:date`, `:email`, `:phone` |
232
- | `multiline` | `prompt.multiline` | `:text` |
233
- | `number_input` | `prompt.ask` (with `convert:`) | `:integer`, `:decimal`, `:currency` |
234
- | `yes_no` | `prompt.yes?` | `:boolean` / `confirm` |
235
- | `select` | `prompt.select` | `:enum` |
236
- | `multi_select` | `prompt.multi_select` | `:multi_enum` |
237
- | `enum_select` | `prompt.enum_select` | Numbered menu variant |
238
- | `mask` | `prompt.mask` | Password/hidden input |
239
- | `slider` | `prompt.slider` | Numeric range |
233
+ | Widget Hint | tty-prompt Method | Used For |
234
+ | -------------- | ------------------------------ | -------------------------------------- |
235
+ | `text_input` | `prompt.ask` | `:string`, `:date`, `:email`, `:phone` |
236
+ | `multiline` | `prompt.multiline` | `:text` |
237
+ | `number_input` | `prompt.ask` (with `convert:`) | `:integer`, `:decimal`, `:currency` |
238
+ | `yes_no` | `prompt.yes?` | `:boolean` / `confirm` |
239
+ | `select` | `prompt.select` | `:enum` |
240
+ | `multi_select` | `prompt.multi_select` | `:multi_enum` |
241
+ | `enum_select` | `prompt.enum_select` | Numbered menu variant |
242
+ | `mask` | `prompt.mask` | Password/hidden input |
243
+ | `slider` | `prompt.slider` | Numeric range |
240
244
 
241
245
  You can override the default by setting an explicit `:tty` widget hint in the DSL:
242
246
 
@@ -252,49 +256,37 @@ end
252
256
 
253
257
  ## Display Verbs
254
258
 
255
- | Verb | Rendering |
256
- |------|-----------|
257
- | `header` | Large ASCII-art text via TTY::Font (falls back to TTY::Box) |
258
- | `say` | Plain text with "Press any key to continue..." |
259
- | `btw` | Info-styled box (blue border) |
260
- | `warning` | Warning-styled box (yellow/red) |
259
+ | Verb | Rendering |
260
+ | --------- | ----------------------------------------------------------- |
261
+ | `header` | Large ASCII-art text via TTY::Font (falls back to TTY::Box) |
262
+ | `say` | Plain text with "Press any key to continue..." |
263
+ | `btw` | Info-styled box (blue border) |
264
+ | `warning` | Warning-styled box (yellow/red) |
261
265
 
262
266
  ## LLM Integration
263
267
 
264
- When a flow contains [inquirex-llm](../inquirex-llm) verbs (`clarify`,
265
- `describe`, `summarize`, `detour`), the `inquirex run` command automatically:
266
-
267
- 1. Loads `.env` files, walking up from the current directory and the flow
268
- file's directory. Shell-set values take precedence; empty-string keys are
269
- treated as unset.
270
- 1. Picks an adapter based on available credentials (see "Adapter selection"
271
- below).
272
- 1. Shows a `🧠 Thinking — asking <provider> to extract structured data…`
273
- banner while the LLM call is in flight.
274
- 1. For `clarify` steps, splats the extracted fields into the engine's
275
- top-level answers via `Engine#prefill!`, so any downstream step with
276
- `skip_if not_empty(:field)` is auto-skipped.
277
- 1. Prints a `✅` / `❓` extraction table showing which fields the LLM filled
278
- in vs. which ones will still be asked.
268
+ When a flow contains [inquirex-llm](../inquirex-llm) verbs (`clarify`, `describe`, `summarize`, `detour`), the `inquirex-tty run` command automatically:
269
+
270
+ 1. Loads `.env` files, walking up from the current directory and the flow file's directory. Shell-set values take precedence; empty-string keys are treated as unset.
271
+ 1. Picks an adapter based on available credentials (see "Adapter selection" below).
272
+ 1. Shows a `🧠 Thinking asking <provider> to extract structured data…` banner while the LLM call is in flight.
273
+ 1. For `clarify` steps, splats the extracted fields into the engine's top-level answers via `Engine#prefill!`, so any downstream step with `skip_if not_empty(:field)` is auto-skipped.
274
+ 1. Prints a `✅` / `❓` extraction table showing which fields the LLM filled in vs. which ones will still be asked.
279
275
 
280
276
  ### Adapter selection (first match wins)
281
277
 
282
- | Condition | Adapter used |
283
- |---------------------------------------------|--------------------------------------|
284
- | `INQUIREX_LLM_ADAPTER=null` | `Inquirex::LLM::NullAdapter` |
285
- | `INQUIREX_LLM_ADAPTER=anthropic` | `Inquirex::LLM::AnthropicAdapter` |
286
- | `INQUIREX_LLM_ADAPTER=openai` | `Inquirex::LLM::OpenAIAdapter` |
287
- | `ANTHROPIC_API_KEY` is set | `Inquirex::LLM::AnthropicAdapter` |
288
- | `OPENAI_API_KEY` is set | `Inquirex::LLM::OpenAIAdapter` |
289
- | nothing set | `Inquirex::LLM::NullAdapter` (demo) |
278
+ | Condition | Adapter used |
279
+ | -------------------------------- | ----------------------------------- |
280
+ | `INQUIREX_LLM_ADAPTER=null` | `Inquirex::LLM::NullAdapter` |
281
+ | `INQUIREX_LLM_ADAPTER=anthropic` | `Inquirex::LLM::AnthropicAdapter` |
282
+ | `INQUIREX_LLM_ADAPTER=openai` | `Inquirex::LLM::OpenAIAdapter` |
283
+ | `ANTHROPIC_API_KEY` is set | `Inquirex::LLM::AnthropicAdapter` |
284
+ | `OPENAI_API_KEY` is set | `Inquirex::LLM::OpenAIAdapter` |
285
+ | nothing set | `Inquirex::LLM::NullAdapter` (demo) |
290
286
 
291
287
  ### End-to-end example
292
288
 
293
- `examples/09_tax_preparer_llm.rb` is a complete LLM-assisted tax intake. The
294
- user types one free-text description of their tax situation; the LLM extracts
295
- `filing_status`, `dependents`, `income_types`, `state_filing`; the wizard only
296
- asks for whatever the LLM couldn't determine, then runs a final `summarize`
297
- for a complexity / fee-estimate write-up.
289
+ `examples/09_tax_preparer_llm.rb` is a complete LLM-assisted tax intake. The user types one free-text description of their tax situation; the LLM extracts `filing_status`, `dependents`, `income_types`, `state_filing`; the wizard only asks for whatever the LLM couldn't determine, then runs a final `summarize` for a complexity / fee-estimate write-up.
298
290
 
299
291
  ```ruby
300
292
  # examples/09_tax_preparer_llm.rb (excerpt)
@@ -363,7 +355,7 @@ Run it:
363
355
  # Put your key in any .env up the tree — OPENAI_API_KEY or ANTHROPIC_API_KEY
364
356
  echo 'OPENAI_API_KEY=sk-…' >> ../.env
365
357
 
366
- inquirex run examples/09_tax_preparer_llm.rb
358
+ inqt run examples/09_tax_preparer_llm.rb
367
359
  ```
368
360
 
369
361
  A typical session (input shortened):
@@ -384,52 +376,45 @@ A typical session (input shortened):
384
376
 
385
377
  ### Troubleshooting
386
378
 
387
- - **"the null adapter"** shown in the thinking banner → no API key was found.
388
- Check `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` in your shell or in a `.env`
389
- up the directory tree.
390
- - **`NoMethodError: undefined method 'prefill!'`** → you're running the
391
- `inquirex` binary against an older rubygems-installed copy of the core gem.
392
- `exe/inquirex` now bootstraps Bundler against the repo's Gemfile
393
- automatically, but a global `rake install`'d copy will still be
394
- stale — run `rake install` in `../inquirex` to update, or run from a
395
- checkout so the shim's Bundler bootstrap takes over.
379
+ - **"the null adapter"** shown in the thinking banner → no API key was found. Check `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` in your shell or in a `.env` up the directory tree.
380
+ - **`NoMethodError: undefined method 'prefill!'`** → you're running the `inquirex-tty` binary against an older rubygems-installed copy of the core gem. `exe/inquirex-tty` now bootstraps Bundler against the repo's Gemfile automatically, but a global `rake install`'d copy will still be stale — run `rake install` in `../inquirex` to update, or run from a checkout so the shim's Bundler bootstrap takes over.
396
381
 
397
382
  ## Examples
398
383
 
399
384
  The gem ships with 10 examples of increasing complexity:
400
385
 
401
- | Example | Description | Steps | Features |
402
- |---------|-------------|-------|----------|
403
- | `01_hello_world.rb` | Minimal flow | 3 | String and integer input |
404
- | `02_yes_or_no.rb` | Boolean branching | 3 | `confirm`, `equals` rule |
405
- | `03_food_preferences.rb` | Multi-select branching | 6 | `multi_enum`, `contains` rule |
406
- | `04_event_registration.rb` | Two-level branching | 9 | Nested conditionals |
407
- | `05_job_application.rb` | Composed rules | 13 | `all()`, `any()`, `greater_than` |
408
- | `06_health_assessment.rb` | Three-level branching | 18 | Complex composed rules |
409
- | `07_loan_application.rb` | Real-world loan intake | 20+ | Currency, 3-level branching |
410
- | `08_tax_preparer.rb` | Full tax preparation wizard | 18+ | All data types, deep branching |
411
- | `09_tax_preparer_llm.rb` | **LLM-assisted tax intake** | 9 | `clarify` + `summarize`, `skip_if not_empty`, auto-prefill |
412
- | `10_real_tax_preparer.rb` | Realistic tax preparer flow | 20+ | Full intake variant |
386
+ | Example | Description | Steps | Features |
387
+ | -------------------------- | --------------------------- | ----- | ---------------------------------------------------------- |
388
+ | `01_hello_world.rb` | Minimal flow | 3 | String and integer input |
389
+ | `02_yes_or_no.rb` | Boolean branching | 3 | `confirm`, `equals` rule |
390
+ | `03_food_preferences.rb` | Multi-select branching | 6 | `multi_enum`, `contains` rule |
391
+ | `04_event_registration.rb` | Two-level branching | 9 | Nested conditionals |
392
+ | `05_job_application.rb` | Composed rules | 13 | `all()`, `any()`, `greater_than` |
393
+ | `06_health_assessment.rb` | Three-level branching | 18 | Complex composed rules |
394
+ | `07_loan_application.rb` | Real-world loan intake | 20+ | Currency, 3-level branching |
395
+ | `08_tax_preparer.rb` | Full tax preparation wizard | 18+ | All data types, deep branching |
396
+ | `09_tax_preparer_llm.rb` | **LLM-assisted tax intake** | 9 | `clarify` + `summarize`, `skip_if not_empty`, auto-prefill |
397
+ | `10_real_tax_preparer.rb` | Realistic tax preparer flow | 20+ | Full intake variant |
413
398
 
414
399
  Run any example:
415
400
 
416
401
  ```bash
417
- inquirex run examples/01_hello_world.rb
418
- inquirex run examples/08_tax_preparer.rb
419
- inquirex run examples/09_tax_preparer_llm.rb
402
+ inqt run examples/01_hello_world.rb
403
+ inqt run examples/08_tax_preparer.rb
404
+ inqt run examples/09_tax_preparer_llm.rb
420
405
  ```
421
406
 
422
407
  Validate all examples:
423
408
 
424
409
  ```bash
425
- for f in examples/*.rb; do inquirex validate "$f"; done
410
+ for f in examples/*.rb; do inquirex-tty validate "$f"; done
426
411
  ```
427
412
 
428
413
  ## Architecture
429
414
 
430
415
  ```
431
416
  inquirex-tty/
432
- ├── exe/inquirex # CLI entry point (dry-cli)
417
+ ├── exe/inquirex-tty # CLI entry point (dry-cli)
433
418
  └── lib/inquirex/tty/
434
419
  ├── commands/
435
420
  │ ├── run.rb # Interactive flow execution
data/Rakefile CHANGED
@@ -19,8 +19,11 @@ task gem: [:build] do
19
19
  end
20
20
 
21
21
  task permissions: [:clean] do
22
- shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
23
- shell("find . -type d -exec chmod o+x,g+x {} \\;")
22
+ # One traversal replaces a six-level glob chain that printed "No such file
23
+ # or directory" for every level this project does not have, skipped dotfiles
24
+ # entirely, and silently stopped at depth six. .git is pruned — its objects
25
+ # have no business being group-readable.
26
+ shell("find . -path ./.git -prune -o -type d -exec chmod o+rx,g+rx {} + -o -type f -exec chmod o+r,g+r {} +")
24
27
  end
25
28
 
26
29
  task build: :permissions
@@ -15,7 +15,7 @@
15
15
  <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
16
16
  <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
17
17
  <text x="31.5" y="14">coverage</text>
18
- <text x="80" y="15" fill="#010101" fill-opacity=".3">99%</text>
19
- <text x="80" y="14">99%</text>
18
+ <text x="80" y="15" fill="#010101" fill-opacity=".3">96%</text>
19
+ <text x="80" y="14">96%</text>
20
20
  </g>
21
21
  </svg>
@@ -49,6 +49,37 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
49
49
  "Please do NOT enter any personal information: no names,\n" \
50
50
  "SSN, ITIN, addresses, or account numbers. We only need\n" \
51
51
  "enough to quote a fee."
52
+ transition to: :describe
53
+ end
54
+
55
+ # -----------------------------------------------------------------------
56
+ # Opening
57
+ # -----------------------------------------------------------------------
58
+
59
+ ask :describe do
60
+ type :text
61
+ question "Describe your last year's tax situation, your residency/citizenship status, your filing status, any dependents, various income types, which state(s) you are filing in,and whether you have your prior year returns available. If you also participate in businesses, please describe their tax status (S-Corp, LLC, etc), and if you have any foreign investments or property."
62
+ transition to: :summary
63
+ end
64
+
65
+ extract :summary do
66
+ from :describe
67
+ prompt "Extract the filer's tax intake details for scoping: filing status, " \
68
+ "dependents, income types, states filed in, residency status, prior " \
69
+ "return availability, and any business entities owned."
70
+
71
+ # Schema derived from the referenced questions: each symbol resolves to
72
+ # that ask step's type, and enum/multi_enum option values are folded in
73
+ # automatically — no duplication of the option lists here.
74
+ schema :filing_status,
75
+ :dependents,
76
+ :income_types,
77
+ :state_filing,
78
+ :residency_status,
79
+ :prior_return_available,
80
+ :business_entities
81
+
82
+ model :claude_sonnet
52
83
  transition to: :residency_status
53
84
  end
54
85
 
@@ -59,6 +90,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
59
90
  ask :residency_status do
60
91
  type :enum
61
92
  question "Which best describes your US tax residency for 2025?"
93
+ skip_if not_empty(:residency_status)
62
94
  options({
63
95
  "us_person" => "US citizen or permanent resident",
64
96
  "resident" => "Resident alien (substantial presence)",
@@ -74,6 +106,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
74
106
  ask :prior_return_available do
75
107
  type :enum
76
108
  question "Do you have a copy of your most recent tax return?"
109
+ skip_if not_empty(:prior_return_available)
77
110
  options({
78
111
  "yes_last_year" => "Yes, last year's return",
79
112
  "yes_older" => "Yes, but older than last year",
@@ -88,6 +121,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
88
121
  ask :filing_status do
89
122
  type :enum
90
123
  question "What is your filing status for 2025?"
124
+ skip_if not_empty(:filing_status)
91
125
  options({
92
126
  "single" => "Single",
93
127
  "married_filing_jointly" => "Married Filing Jointly",
@@ -98,12 +132,13 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
98
132
  widget target: :tty, type: :select
99
133
  widget target: :desktop, type: :radio_group, columns: 1
100
134
  widget target: :mobile, type: :dropdown
101
- transition to: :dependents_band
135
+ transition to: :dependents
102
136
  end
103
137
 
104
- ask :dependents_band do
138
+ ask :dependents do
105
139
  type :enum
106
140
  question "How many dependents will you claim?"
141
+ skip_if not_empty(:dependents)
107
142
  options %w[0 1 2 3 4+]
108
143
  widget target: :tty, type: :select
109
144
  widget target: :desktop, type: :radio_group, columns: 5
@@ -118,6 +153,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
118
153
  ask :income_types do
119
154
  type :multi_enum
120
155
  question "Select every type of income you had in 2025."
156
+ skip_if not_empty(:income_types)
121
157
  options({
122
158
  "W2" => "W-2 wages",
123
159
  "1099_nec" => "1099-NEC (contractor)",
@@ -166,6 +202,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
166
202
  ask :business_entities do
167
203
  type :multi_enum
168
204
  question "Which business entity types do you own or partner in?"
205
+ skip_if not_empty(:business_entities)
169
206
  options({
170
207
  "sole_prop" => "Sole Proprietor / Schedule C",
171
208
  "single_llc" => "Single-member LLC",
@@ -435,6 +472,7 @@ Inquirex.define id: "tax-preparer-2025", version: "2.0.0" do
435
472
  ask :state_filing do
436
473
  type :multi_enum
437
474
  question "Select every state (and DC) you need to file a return in."
475
+ skip_if not_empty(:state_filing)
438
476
  options US_STATES
439
477
  widget target: :tty, type: :multi_select
440
478
  widget target: :desktop, type: :checkbox_group, columns: 10, layout: :grid
@@ -0,0 +1,52 @@
1
+ Inquirex.define do
2
+ meta title: "Coolness Questionnaire",
3
+ subtitle: "Let's figure out how cool you are :)"
4
+
5
+ start :welcome
6
+
7
+ say :welcome do
8
+ text "Hello there! This is a demo of the Qualified.At DSL."
9
+ transition to: :loves_to_dance
10
+ end
11
+
12
+ ask :loves_to_dance do
13
+ type :boolean
14
+ question "Might we ask, do you like to dance to electronic music?"
15
+ transition to: :no_problem, if_rule: equals(:loves_to_dance, false)
16
+ transition to: :burning_man
17
+ end
18
+
19
+ say :no_problem do
20
+ text "Not everyone loves to dance. It's quite personal, we get it."
21
+ transition to: :burning_man
22
+ end
23
+
24
+ ask :burning_man do
25
+ type :enum
26
+ question "How many times have you been to Burning Man?"
27
+ options ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"]
28
+ transition to: :awesome, if_rule: greater_than(:burning_man, 20)
29
+ transition to: :good, if_rule: greater_than(:burning_man, 10)
30
+ transition to: :decent, if_rule: greater_than(:burning_man, 1)
31
+ transition to: :lame, if_rule: less_than(:burning_man, 1)
32
+ widget target: :tty, type: :select
33
+ widget target: :desktop, type: :radio_group, columns: 5
34
+ widget target: :mobile, type: :dropdown
35
+ end
36
+
37
+ say :awesome do
38
+ text "You are awesome! That must be a record!"
39
+ end
40
+
41
+ say :good do
42
+ text "Not bad at all! This is a very respectable number."
43
+ end
44
+
45
+ say :decent do
46
+ text "It's decent, but not amazing, pardon our judgment :)"
47
+ end
48
+
49
+ say :lame do
50
+ text "You've never been? Pardon the judgment, but you MUST go. It's beyond compare."
51
+ end
52
+ end