Skip to content

feat(interactive): add reflection-driven interactive prompt engine#249

Open
ben-kalmus wants to merge 1 commit into
mainfrom
feat/interactive-package
Open

feat(interactive): add reflection-driven interactive prompt engine#249
ben-kalmus wants to merge 1 commit into
mainfrom
feat/interactive-package

Conversation

@ben-kalmus

@ben-kalmus ben-kalmus commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds pkg/interactive, a generic package that builds a request body by walking any Go struct with reflection and prompting for each field. It is the foundation for --interactive modes across the CLI.

  • This PR introduces the engine only. No command is wired to it yet (see the follow-up PR adding --interactive to compositions upsert).

Demo

compositions-upsert

Stacked PRs

How it works

  • Builder.Build(&v) walks the struct and prompts for inputs: optional pointer fields can be skipped, large optional-only parameter objects let you multi-select which fields to fill.

  • Enums (named string types the SDK generates with an IsValid() bool method) are validated against the SDK's own check via reflection.

  • Bad input does not abort the build. It re-prompts in place (non-numeric integer, malformed JSON, empty required field) using validators.

  • A depth/cycle guard degrades self-referential structures to a raw-JSON prompt instead of looping forever.

Design notes

  • SDK-agnostic: the package imports only pkg/iostreams and pkg/prompt, no SDK or command packages, so any command can reuse it.

  • Input is gathered through a small Prompter interface (Input/Confirm/Select/MultiSelect). Production uses SurveyPrompter; tests use ScriptedPrompter, a label-keyed fake whose answers match by field label rather than call order, so tests do not break when SDK changes.

Changes

  • pkg/interactive/prompter.go: Prompter interface and SurveyPrompter (survey/v2 via pkg/prompt).
  • pkg/interactive/scripted_prompter.go: ScriptedPrompter, the reusable label-keyed test fake.
  • pkg/interactive/builder.go: the reflection walk (scalars, optional pointers, unions, parameter bags, slices, maps, enum and input validation).
  • pkg/interactive/classify.go: reflection helpers (union, parameter-bag, required-field detection).
  • pkg/interactive/validators.go: input validator builders (required string, integer, number, boolean, JSON).

Tests

Unit tests under pkg/interactive covering:

  • Scalars, optional pointers (set and skipped), and enums (valid and rejected)
  • oneOf unions, parameter bags, slices, and map[string]string
  • Pre-populated fields preserved, and the depth/cycle guards falling back to raw JSON
  • Validator behavior and both the scripted and survey prompters

@codacy-production

codacy-production Bot commented Jun 17, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 228 complexity · 9 duplication

Metric Results
Complexity 228
Duplication 9

View in Codacy

TIP This summary will be updated as you push new changes.

A generic package that builds a request body by walking any struct via
reflection and prompting for each field through a small Prompter interface
(survey-backed in production, a scripted fake for tests). Handles scalars,
optional pointers, enums (validated through the SDK's own IsValid method),
oneOf unions, parameter bags, slices and maps, with per-field input
validation and re-prompt on invalid entries. No SDK or command coupling.
@ben-kalmus ben-kalmus force-pushed the feat/interactive-package branch from b28c05b to c17e3a6 Compare June 18, 2026 10:09
@ben-kalmus ben-kalmus marked this pull request as ready for review June 18, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant