Acme-Claude-Shell

 view release on metacpan or  search on metacpan

lib/Acme/Claude/Shell/Tools.pm  view on Meta::CPAN

=head2 Command Approval

The C<execute_command> tool handles user approval directly (not via hooks)
to ensure synchronous confirmation before execution. Users can:

=over 4

=item * B<[a]> Approve and run the command

=item * B<[d]> Dry-run (preview only, don't execute)

=item * B<[e]> Edit the command before running

=item * B<[x]> Cancel

=back

=head2 Dangerous Command Detection

The following patterns trigger additional safety warnings:

=over 4

=item * C<rm -rf>, C<rm --recursive>, C<rm --force>

=item * C<sudo> commands

=item * C<mkfs>, C<dd of=>, device writes

=item * C<chmod 777>, C<chown -R>

=item * C<kill -9>, C<reboot>, C<shutdown>, C<halt>, C<poweroff>

=item * Fork bombs, remote script piping (curl/wget | sh)

=back

=cut

sub shell_tools {
    my ($session) = @_;

    return [
        # execute_command tool - ALL shell operations go through this
        # so the PreToolUse hook can confirm each command
        tool(
            'execute_command',
            'Execute a shell command and return its output. Use this for ALL shell operations including listing files, reading files, etc. The user will be prompted to approve each command.',
            {
                type       => 'object',
                properties => {
                    command => {
                        type        => 'string',
                        description => 'The shell command to execute (e.g., "ls -la", "cat file.txt", "find . -name *.pl")',
                    },
                    working_dir => {
                        type        => 'string',
                        description => 'Directory to run command in (optional, defaults to current directory)',
                    },
                },
                required => ['command'],
            },
            sub {
                my ($params, $loop) = @_;
                return _execute_command($session, $params, $loop);
            },
        ),

        # get_working_directory tool - safe, no confirmation needed
        tool(
            'get_working_directory',
            'Get the current working directory. This is safe and does not require user confirmation.',
            {
                type       => 'object',
                properties => {},
            },
            sub {
                my ($params, $loop) = @_;
                my $future = $loop->new_future;
                $future->done(_mcp_result(getcwd()));
                return $future;
            },
        ),

        # read_file tool - safe read operation, no confirmation needed
        tool(
            'read_file',
            'Read the contents of a file. Safe operation - does not require user confirmation. Use this instead of execute_command for reading files.',
            {
                type       => 'object',
                properties => {
                    path => {
                        type        => 'string',
                        description => 'Path to the file to read',
                    },
                    lines => {
                        type        => 'integer',
                        description => 'Number of lines to read from the beginning (optional)',
                    },
                    tail => {
                        type        => 'integer',
                        description => 'Number of lines to read from the end (optional)',
                    },
                },
                required => ['path'],
            },
            sub {
                my ($params, $loop) = @_;
                return _read_file_safe($session, $params, $loop);
            },
        ),

        # list_directory tool - safe read operation, no confirmation needed
        tool(
            'list_directory',
            'List the contents of a directory. Safe operation - does not require user confirmation. Use this instead of execute_command for listing files.',
            {
                type       => 'object',
                properties => {
                    path => {
                        type        => 'string',
                        description => 'Path to the directory to list (defaults to current directory)',
                    },
                    pattern => {
                        type        => 'string',
                        description => 'Glob pattern to filter files (e.g., "*.pl", "*.txt")',
                    },
                    long_format => {
                        type        => 'boolean',
                        description => 'Show detailed file information (size, date, permissions)',
                    },
                    show_hidden => {
                        type        => 'boolean',
                        description => 'Include hidden files (starting with .)',
                    },
                },
            },
            sub {
                my ($params, $loop) = @_;
                return _list_directory_safe($session, $params, $loop);
            },
        ),

        # search_files tool - safe search operation, no confirmation needed
        tool(
            'search_files',
            'Search for files by name pattern or content. Safe operation - does not require user confirmation.',
            {
                type       => 'object',
                properties => {
                    pattern => {
                        type        => 'string',
                        description => 'File name pattern to search for (e.g., "*.pm", "config*")',
                    },
                    content => {
                        type        => 'string',
                        description => 'Text pattern to search for within files (grep)',
                    },
                    path => {
                        type        => 'string',
                        description => 'Directory to search in (defaults to current directory)',
                    },
                    max_depth => {
                        type        => 'integer',
                        description => 'Maximum directory depth to search',



( run in 1.648 second using v1.01-cache-2.11-cpan-13bb782fe5a )