MCPcopy Create free account
hub / github.com/diillson/chatcli / CheckAndPrompt

Method CheckAndPrompt

cli/policy_adapter.go:96–183  ·  view source on GitHub ↗

CheckAndPrompt checks the policy for a tool call. If the policy is "ask", it acquires a mutex, pauses the spinner, and prompts the user interactively with full context about which agent is requesting the action and why.

(ctx context.Context, toolName, args string)

Source from the content-addressed store, hash-verified

94// it acquires a mutex, pauses the spinner, and prompts the user interactively
95// with full context about which agent is requesting the action and why.
96func (a *workerPolicyAdapter) CheckAndPrompt(ctx context.Context, toolName, args string) (bool, string) {
97 action := a.pm.Check(toolName, args)
98
99 switch action {
100 case coder.ActionAllow:
101 return true, ""
102
103 case coder.ActionDeny:
104 a.logger.Info("Worker tool call blocked by policy (deny)",
105 zap.String("tool", toolName),
106 )
107 return false, "AÇÃO BLOQUEADA (Regra de Segurança). NÃO TENTE NOVAMENTE."
108
109 case coder.ActionAsk:
110 if a.unattended {
111 // Gateway: no human to answer; blocking on stdin would hang the
112 // worker silently. Auto-approve (see field doc).
113 a.logger.Info("Worker tool call auto-approved (unattended gateway)",
114 zap.String("tool", toolName))
115 return true, ""
116 }
117
118 // Serialize prompts: only one worker prompts the user at a time.
119 a.mu.Lock()
120 defer a.mu.Unlock()
121
122 // Re-check after acquiring the lock — another worker's prompt may
123 // have created an "allow always" or "deny forever" rule for this
124 // same pattern while we were waiting.
125 newPM, pmErr := coder.NewPolicyManager(a.logger) // reload rules
126 if pmErr != nil {
127 a.logger.Error("failed to reload policy manager", zap.Error(pmErr))
128 return false, "AÇÃO BLOQUEADA (erro ao recarregar políticas de segurança)."
129 }
130 a.pm = newPM
131 recheck := a.pm.Check(toolName, args)
132 if recheck == coder.ActionAllow {
133 return true, ""
134 }
135 if recheck == coder.ActionDeny {
136 return false, "AÇÃO BLOQUEADA (Regra de Segurança). NÃO TENTE NOVAMENTE."
137 }
138
139 // Pause spinner so the prompt renders cleanly
140 a.pauseSpinner()
141
142 // Build context for the enhanced prompt
143 secCtx := buildSecurityContext(ctx)
144
145 // Prompt the user with full context
146 decision := coder.PromptSecurityCheckWithContextGuarded(ctx, toolName, args, secCtx, a.stdinCh)
147 pattern := coder.GetSuggestedPattern(toolName, args)
148
149 // Clear the prompt area and resume spinner
150 fmt.Print(metrics.ClearLine())
151 a.resumeSpinner()
152
153 switch decision {

Callers

nothing calls this directly

Calls 15

pauseSpinnerMethod · 0.95
resumeSpinnerMethod · 0.95
NewPolicyManagerFunction · 0.92
GetSuggestedPatternFunction · 0.92
ClearLineFunction · 0.92
buildSecurityContextFunction · 0.85
LockMethod · 0.80
UnlockMethod · 0.80
AddRuleMethod · 0.80
WarnMethod · 0.80
CheckMethod · 0.65

Tested by

no test coverage detected