Skip to content

Migrate mini question UI to V2 forms #36083

Description

@opencode-agent

Summary

opencode mini should handle V2 forms directly instead of relying on the older question blocker flow.

Mini currently has interactive support for question.v2.asked through its footer question UI, while non-interactive opencode run already observes form.created and auto-cancels forms. The TUI has the fuller form semantics under packages/tui/src/routes/session/form.tsx; mini should migrate to the same V2 form model.

Current state

Relevant mini files on v2:

  • packages/cli/src/mini/stream-v2.transport.ts subscribes to events, hydrates session state, maps events to footer/scrollback updates, and sends session.prompt, session.command, session.skill, and session.shell.
  • packages/cli/src/mini/types.ts currently models blocker UI as FooterView.permission | FooterView.question.
  • packages/cli/src/mini/footer.question.tsx and packages/cli/src/mini/question.shared.ts implement the existing question UI/state machine.
  • packages/cli/src/mini/noninteractive.ts already sees form.created, but only to cancel forms for headless runs.

TUI reference implementation:

  • packages/tui/src/context/data.tsx handles form.created, form.replied, and form.cancelled, plus form list hydration.
  • packages/tui/src/routes/session/form.tsx renders URL forms and field-based forms, validates answers, submits replies, and cancels.

Desired behavior

  • Interactive mini should display pending V2 forms in the footer blocker area.
  • Users should be able to submit or cancel forms from mini.
  • URL forms and field forms should both have a reasonable mini rendering.
  • Existing question.v2 support can remain as a compatibility fallback until server-side question callers are fully gone.
  • Non-interactive opencode run should continue to auto-cancel forms instead of blocking for input.

Implementation notes

Likely changes:

  • Add form request state and hydration to packages/cli/src/mini/stream-v2.transport.ts:
    • handle form.created
    • remove on form.replied / form.cancelled
    • hydrate with sdk.form.list(...)
    • consider the existing global-form sentinel behavior from the TUI/noninteractive path.
  • Extend FooterView in packages/cli/src/mini/types.ts with a form variant.
  • Add footer callbacks for form submit/cancel through footer.ts, footer.view.tsx, and runtime.ts.
  • Add a mini-specific form component/state helper, likely footer.form.tsx and form.shared.ts, borrowing behavior from the TUI rather than trying to reuse the TUI component directly.
  • Keep the existing question UI as fallback or bridge question requests into the form UI if that stays simpler.

Acceptance criteria

  • A form.created event for the active session appears in interactive mini as a footer blocker.
  • Submitting a valid form calls the V2 form reply API with the selected values.
  • Cancelling calls the V2 form cancel API and returns the footer to the prompt view.
  • Form completion/cancellation events remove the blocker from mini state.
  • Existing question.v2 behavior does not regress while compatibility remains.
  • Add focused tests for event handling/state transitions where practical.

Source

Requested from internal Slack #core discussion on 2026-07-09 while reviewing the current opencode mini state on the v2 branch.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions