My agentic slop goes here. Not intended for anyone else!
1open Eio.Std
2
3let src = Logs.Src.create "discovery_demo" ~doc:"Permission discovery demonstration"
4module Log = (val Logs.src_log src : Logs.LOG)
5
6let process_response client =
7 let messages = Claude.Client.receive_all client in
8 List.iter (fun msg ->
9 match msg with
10 | Claude.Message.Assistant msg ->
11 List.iter (function
12 | Claude.Content_block.Text t ->
13 let text = Claude.Content_block.Text.text t in
14 Log.app (fun m -> m "Claude: %s"
15 (if String.length text > 100 then
16 String.sub text 0 100 ^ "..."
17 else text))
18 | Claude.Content_block.Tool_use t ->
19 Log.info (fun m -> m "Tool use: %s"
20 (Claude.Content_block.Tool_use.name t))
21 | _ -> ()
22 ) (Claude.Message.Assistant.content msg)
23 | Claude.Message.Result msg ->
24 if Claude.Message.Result.is_error msg then
25 Log.err (fun m -> m "Error occurred!")
26 else
27 (match Claude.Message.Result.total_cost_usd msg with
28 | Some cost ->
29 Log.info (fun m -> m "Cost: $%.6f" cost)
30 | None -> ())
31 | _ -> ()
32 ) messages
33
34let run_discovery ~sw ~env =
35 Log.app (fun m -> m "🔍 Permission Discovery Demo");
36 Log.app (fun m -> m "=============================");
37 Log.app (fun m -> m "This will discover what permissions Claude needs.\n");
38
39 (* Create client with discovery mode *)
40 let options = Claude.Options.create ~model:(Claude.Model.of_string "sonnet") () in
41 let client = Claude.Client.discover_permissions
42 (Claude.Client.create ~options ~sw ~process_mgr:env#process_mgr ()) in
43
44 (* Send a prompt that will need permissions *)
45 Log.app (fun m -> m "Asking Claude to read a secret file...");
46 Claude.Client.query client
47 "Please read the file test/secret_data.txt and tell me what the secret code is.";
48 process_response client;
49
50 (* Check what permissions were requested *)
51 let permissions = Claude.Client.get_discovered_permissions client in
52 if permissions = [] then
53 Log.app (fun m -> m "\n📋 No permissions were requested (Claude may have used its knowledge).")
54 else begin
55 Log.app (fun m -> m "\n📋 Permissions that were requested:");
56 List.iter (fun rule ->
57 Log.app (fun m -> m " - Tool: %s%s"
58 (Claude.Permissions.Rule.tool_name rule)
59 (match Claude.Permissions.Rule.rule_content rule with
60 | Some content -> Printf.sprintf " (rule: %s)" content
61 | None -> ""))
62 ) permissions
63 end
64
65let main ~env =
66 Switch.run @@ fun sw ->
67 run_discovery ~sw ~env
68
69(* Command-line interface *)
70open Cmdliner
71
72let main_term env =
73 let setup_log style_renderer level =
74 Fmt_tty.setup_std_outputs ?style_renderer ();
75 Logs.set_level level;
76 Logs.set_reporter (Logs_fmt.reporter ());
77 if level = None then Logs.set_level (Some Logs.App)
78 in
79 let run style level =
80 setup_log style level;
81 main ~env
82 in
83 Term.(const run $ Fmt_cli.style_renderer () $ Logs_cli.level ())
84
85let cmd env =
86 let doc = "Discover what permissions Claude needs" in
87 let man = [
88 `S Manpage.s_description;
89 `P "This program runs Claude in discovery mode to see what permissions it requests.";
90 ] in
91 let info = Cmd.info "discovery_demo" ~version:"1.0" ~doc ~man in
92 Cmd.v info (main_term env)
93
94let () =
95 Eio_main.run @@ fun env ->
96 exit (Cmd.eval (cmd env))