feat(tui-go): workflow-propose choice panel

Render a workflow.proposed frame as a single-select picker with a manual-answer
slot: ↑↓/jk to choose, enter to launch, e for custom, esc to peek away. Picking
a candidate sends StartSession (and focuses the launched session); the custom
slot continues the conversation via ChatInput. Reuses the modal helpers from the
clarification view.
This commit is contained in:
2026-06-14 13:29:34 +04:00
parent b62b6e09a1
commit b563d9841d
9 changed files with 420 additions and 0 deletions
+15
View File
@@ -35,6 +35,7 @@ const (
TypeApprovalRequired = "approval.required"
TypeApprovalResolved = "approval.resolved"
TypeClarification = "clarification.required"
TypeWorkflowProposed = "workflow.proposed"
TypeWorkspaceBound = "session.workspace_bound"
TypeStageManifest = "stage.tool_manifest"
TypeProviderStatus = "provider.status_changed"
@@ -139,6 +140,19 @@ type ServerMessage struct {
// clarification.required — open questions a stage raised for the operator
Questions []ClarificationQuestionDto `json:"questions"`
// workflow.proposed — the router's triage suggestion of candidate workflows
ProposalID string `json:"proposalId"`
Prompt string `json:"prompt"`
OriginalRequest string `json:"originalRequest"`
Candidates []ProposedWorkflowDto `json:"candidates"`
}
// ProposedWorkflowDto is one candidate workflow the router suggests, with a short
// reason. Mirrors the Kotlin ProposedWorkflow (core:events), the wire shape.
type ProposedWorkflowDto struct {
WorkflowID string `json:"workflowId"`
Reason string `json:"reason"`
}
// ClarificationQuestionDto is one open question from a stage. Empty Options ->
@@ -313,6 +327,7 @@ func (m ServerMessage) IsEventBearing() bool {
TypeToolStarted, TypeToolCompleted, TypeToolFailed, TypeToolRejected,
TypeToolAssessed,
TypeApprovalRequired, TypeApprovalResolved, TypeClarification,
TypeWorkflowProposed,
TypeWorkspaceBound, TypeArtifactCreated,
TypeArtifactValid, TypePlanLocked,
TypeRouterNarration: