···28282929(* Interactive permission callback *)
3030let interactive_permission_callback ~tool_name ~input ~context:_ =
3131+ Log.info (fun m -> m "๐ Permission callback invoked for tool: %s" tool_name);
3132 Log.app (fun m -> m "\n๐ PERMISSION REQUEST ๐");
3233 Log.app (fun m -> m "Tool: %s" tool_name);
3434+3535+ (* Log the full input for debugging *)
3636+ Log.info (fun m -> m "Full input JSON: %s" (Ezjsonm.value_to_string input));
33373438 (* Show input details *)
3539 (* Try to extract key information from the input *)
···4448 | "Write" | "Edit" ->
4549 let file_path = Ezjsonm.find input ["file_path"] |> Ezjsonm.get_string in
4650 Log.app (fun m -> m "File: %s" file_path)
5151+ | "Glob" ->
5252+ let pattern = Ezjsonm.find input ["pattern"] |> Ezjsonm.get_string in
5353+ Log.app (fun m -> m "Pattern: %s" pattern);
5454+ (try
5555+ let path = Ezjsonm.find input ["path"] |> Ezjsonm.get_string in
5656+ Log.app (fun m -> m "Path: %s" path)
5757+ with _ -> Log.app (fun m -> m "Path: (current directory)"))
5858+ | "Grep" ->
5959+ let pattern = Ezjsonm.find input ["pattern"] |> Ezjsonm.get_string in
6060+ Log.app (fun m -> m "Pattern: %s" pattern);
6161+ (try
6262+ let path = Ezjsonm.find input ["path"] |> Ezjsonm.get_string in
6363+ Log.app (fun m -> m "Path: %s" path)
6464+ with _ -> Log.app (fun m -> m "Path: (current directory)"))
4765 | _ ->
4866 Log.app (fun m -> m "Input: %s" (Ezjsonm.value_to_string input))
4949- with _ -> ());
6767+ with exn ->
6868+ Log.info (fun m -> m "Failed to parse input details: %s" (Printexc.to_string exn)));
50695170 (* Check if already granted *)
5271 if Granted.is_granted tool_name then begin
5372 Log.app (fun m -> m "โ Auto-approved (previously granted)");
7373+ Log.info (fun m -> m "Returning allow result for %s" tool_name);
5474 Claude.Permissions.Result.allow ()
5575 end else begin
5676 (* Ask user *)
···5878 match read_line () |> String.lowercase_ascii with
5979 | "y" | "yes" ->
6080 Log.app (fun m -> m "โ Allowed (this time only)");
8181+ Log.info (fun m -> m "User approved %s for this request only" tool_name);
6182 Claude.Permissions.Result.allow ()
6283 | "a" | "always" ->
6384 Granted.grant tool_name;
8585+ Log.info (fun m -> m "User granted permanent permission for %s" tool_name);
6486 Claude.Permissions.Result.allow ()
6587 | _ ->
6688 Granted.deny tool_name;
8989+ Log.info (fun m -> m "User denied permission for %s" tool_name);
6790 Claude.Permissions.Result.deny ~message:(Printf.sprintf "User denied access to %s" tool_name) ~interrupt:false
6891 end
6992···102125 Log.app (fun m -> m "Claude will request permissions as needed.\n");
103126104127 (* Create options with custom permission callback *)
105105- (* Don't use disallowed_tools - rely on permission callback for all access control *)
128128+ (* DON'T specify allowed_tools - let the permission callback handle everything.
129129+ The Default permission mode with a callback should send requests for all tools. *)
106130 let options = Claude.Options.create
107131 ~model:"sonnet"
132132+ ~permission_mode:Claude.Permissions.Mode.Default
108133 ~permission_callback:interactive_permission_callback
109134 () in
110135···112137 ~process_mgr:env#process_mgr
113138 () in
114139115115- (* First prompt - Claude will need to request Read permission *)
116116- Log.app (fun m -> m "\n๐ค Sending first prompt...");
140140+ (* First prompt - Claude will need to request Read permission for ../lib *)
141141+ Log.app (fun m -> m "\n๐ค Sending first prompt (reading from ../lib)...");
117142 Claude.Client.query client
118118- "Please read the file 'permission_demo.ml' in the current directory and tell me what it does.";
143143+ "Please read and analyze the source files in the ../lib directory. Focus on the main OCaml modules and their purpose. What is the overall architecture of this Claude library?";
119144 process_response client;
120145121146 (* Show current permissions *)
122147 Log.app (fun m -> m "\n๐ Current permission status:");
123148 Granted.list ();
124149125125- (* Second prompt - might need different permissions *)
126126- Log.app (fun m -> m "\n๐ค Sending second prompt...");
150150+ (* Second prompt - will need Write permission *)
151151+ Log.app (fun m -> m "\n๐ค Sending second prompt (writing TEST.md)...");
127152 Claude.Client.query client
128128- "Now check if there's a README.md file in the test directory and tell me what tests exist.";
153153+ "Now write a summary of what you learned about the Claude library architecture to a file called TEST.md in the current directory. Include the main modules, their purposes, and how they work together.";
129154 process_response client;
130155131156 (* Show final permissions *)