@@ -215,7 +215,7 @@ describe("canUseTool MCP approval enforcement", () => {
215215 "auto" ,
216216 "bypassPermissions" ,
217217 ] as const ) (
218- "prompts for a configured PostHog exec match in %s mode without remembering " ,
218+ "prompts for a configured PostHog exec match in %s mode with a remembered choice " ,
219219 async ( permissionMode ) => {
220220 setMcpToolApprovalStates ( { mcp__posthog__exec : "approved" } ) ;
221221
@@ -226,6 +226,8 @@ describe("canUseTool MCP approval enforcement", () => {
226226 posthogExecPermissionRegex,
227227 settingsManager : {
228228 getRepoRoot : vi . fn ( ) . mockReturnValue ( "/repo" ) ,
229+ hasPostHogExecApproval : vi . fn ( ) . mockReturnValue ( false ) ,
230+ addPostHogExecApproval : vi . fn ( ) ,
229231 } ,
230232 } ,
231233 } ) ;
@@ -236,6 +238,7 @@ describe("canUseTool MCP approval enforcement", () => {
236238 expect . objectContaining ( {
237239 options : [
238240 expect . objectContaining ( { kind : "allow_once" } ) ,
241+ expect . objectContaining ( { kind : "allow_always" } ) ,
239242 expect . objectContaining ( { kind : "reject_once" } ) ,
240243 ] ,
241244 toolCall : expect . objectContaining ( {
@@ -247,6 +250,54 @@ describe("canUseTool MCP approval enforcement", () => {
247250 } ,
248251 ) ;
249252
253+ it ( "skips the prompt for a remembered PostHog exec sub-tool" , async ( ) => {
254+ setMcpToolApprovalStates ( { mcp__posthog__exec : "approved" } ) ;
255+
256+ const context = createContext ( "mcp__posthog__exec" , {
257+ toolInput : { command : "call experiment-update {}" } ,
258+ session : {
259+ permissionMode : "default" ,
260+ posthogExecPermissionRegex,
261+ settingsManager : {
262+ getRepoRoot : vi . fn ( ) . mockReturnValue ( "/repo" ) ,
263+ hasPostHogExecApproval : vi . fn ( ) . mockReturnValue ( true ) ,
264+ addPostHogExecApproval : vi . fn ( ) ,
265+ } ,
266+ } ,
267+ } ) ;
268+
269+ const result = await canUseTool ( context ) ;
270+
271+ expect ( result . behavior ) . toBe ( "allow" ) ;
272+ expect ( context . client . requestPermission ) . not . toHaveBeenCalled ( ) ;
273+ } ) ;
274+
275+ it ( "persists a PostHog exec sub-tool selected with allow always" , async ( ) => {
276+ setMcpToolApprovalStates ( { mcp__posthog__exec : "approved" } ) ;
277+ const addPostHogExecApproval = vi . fn ( ) . mockResolvedValue ( undefined ) ;
278+
279+ const context = createContext ( "mcp__posthog__exec" , {
280+ toolInput : { command : "call notebooks-destroy {}" } ,
281+ session : {
282+ permissionMode : "default" ,
283+ posthogExecPermissionRegex,
284+ settingsManager : {
285+ getRepoRoot : vi . fn ( ) . mockReturnValue ( "/repo" ) ,
286+ hasPostHogExecApproval : vi . fn ( ) . mockReturnValue ( false ) ,
287+ addPostHogExecApproval,
288+ } ,
289+ } ,
290+ client : createClient ( {
291+ outcome : { outcome : "selected" , optionId : "allow_always" } ,
292+ } ) ,
293+ } ) ;
294+
295+ const result = await canUseTool ( context ) ;
296+
297+ expect ( result . behavior ) . toBe ( "allow" ) ;
298+ expect ( addPostHogExecApproval ) . toHaveBeenCalledWith ( "notebooks-destroy" ) ;
299+ } ) ;
300+
250301 it ( "does not gate a nonmatching PostHog sub-tool" , async ( ) => {
251302 setMcpToolApprovalStates ( { mcp__posthog__exec : "approved" } ) ;
252303
0 commit comments