@@ -37,6 +37,7 @@ type wsApprover struct {
3737 pending map [string ]chan string // request ID → response channel
3838 mu sync.Mutex
3939 approveAll map [danger.RiskClass ]bool // trust-cached risk classes
40+ cancel chan struct {} // closed by Cancel() to interrupt waiting PromptCommand
4041}
4142
4243// newWSApprover creates a wsApprover that sends requests via sendFn.
@@ -45,6 +46,7 @@ func newWSApprover(sendFn func(v any) error) *wsApprover {
4546 sendFn : sendFn ,
4647 pending : make (map [string ]chan string ),
4748 approveAll : make (map [danger.RiskClass ]bool ),
49+ cancel : make (chan struct {}),
4850 }
4951}
5052
@@ -79,9 +81,15 @@ func (a *wsApprover) PromptCommand(cls danger.RiskClass, cmd, description string
7981 return fmt .Errorf ("approval: send failed: %w" , err )
8082 }
8183
82- // Wait for response (60s timeout prevents agent deadlock)
84+ // Wait for response, cancellation, or timeout (60s).
8385 select {
8486 case action := <- resp :
87+ // Ack the user's choice back to the browser for UI feedback.
88+ a .sendFn (map [string ]any {
89+ "type" : "approval_ack" ,
90+ "id" : id ,
91+ "action" : action ,
92+ })
8593 switch action {
8694 case "approve" :
8795 return nil
@@ -91,6 +99,8 @@ func (a *wsApprover) PromptCommand(cls danger.RiskClass, cmd, description string
9199 default :
92100 return fmt .Errorf ("operation denied by user: %s" , cmd )
93101 }
102+ case <- a .cancel :
103+ return fmt .Errorf ("approval cancelled: %s" , cmd )
94104 case <- time .After (60 * time .Second ):
95105 return fmt .Errorf ("approval timeout: %s" , cmd )
96106 }
@@ -118,3 +128,14 @@ func (a *wsApprover) newID() string {
118128 rand .Read (b )
119129 return "apr-" + hex .EncodeToString (b )
120130}
131+
132+ // Cancel interrupts any pending PromptCommand by closing the cancel channel.
133+ // Safe to call multiple times — subsequent calls are no-ops.
134+ func (a * wsApprover ) Cancel () {
135+ select {
136+ case <- a .cancel :
137+ // Already closed.
138+ default :
139+ close (a .cancel )
140+ }
141+ }
0 commit comments