Acme-Claude-Shell

 view release on metacpan or  search on metacpan

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

dry-run, or cancel each command before execution. Dangerous commands
(rm -rf, sudo, mkfs, etc.) trigger additional warnings.

=item * B<read_file> - Read file contents (safe, no confirmation)

Read file contents directly without shell commands. Supports C<lines>
parameter to read first N lines, and C<tail> parameter to read last N lines.

=item * B<list_directory> - List directory contents (safe, no confirmation)

List directory contents with optional glob C<pattern> filtering,
C<long_format> for detailed output, and C<show_hidden> for dotfiles.

=item * B<search_files> - Search for files by pattern (safe, no confirmation)

Search recursively by filename C<pattern> (glob) or file C<content> (grep).
Supports C<max_depth> limit. Results capped at 100 matches.

=item * B<get_system_info> - Get system information (safe, no confirmation)

Returns OS, disk, memory, and process information. Use C<info_type> to
filter: 'all', 'os', 'disk', 'memory', or 'processes'.

=item * B<get_working_directory> - Get current working directory (safe)

Returns the current working directory path.

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

        unless ($show_hidden) {
            @entries = grep { !/^\./ } @entries;
        }
        else {
            # Remove . and .. but keep other hidden files
            @entries = grep { $_ ne '.' && $_ ne '..' } @entries;
        }

        # Apply pattern filter
        if ($pattern) {
            my $regex = _glob_to_regex($pattern);
            @entries = grep { /$regex/ } @entries;
        }

        # Sort entries
        @entries = sort @entries;

        my @output;
        if ($long_format) {
            for my $entry (@entries) {
                my $entry_path = File::Spec->catfile($full_path, $entry);

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

    if ($path !~ m{^/}) {
        $full_path = File::Spec->catfile($session->working_dir // getcwd(), $path);
    }

    unless (-d $full_path) {
        $future->done(_mcp_result("Error: Not a directory: $path", 1));
        return $future;
    }

    my @results;
    my $regex = $pattern ? _glob_to_regex($pattern) : undef;
    my $content_re = $content ? qr/\Q$content\E/i : undef;

    _search_recursive($full_path, $full_path, $regex, $content_re, $max_depth, 0, \@results);

    if (@results) {
        $future->done(_mcp_result(join("\n", @results)));
    }
    else {
        $future->done(_mcp_result("No matches found"));
    }

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

        push @info, "=== Current Process ===";
        push @info, "PID: $$";
        push @info, "User: " . (getpwuid($<) // $<);
        push @info, "";
    }

    $future->done(_mcp_result(join("\n", @info)));
    return $future;
}

# Helper: convert glob pattern to regex
sub _glob_to_regex {
    my ($glob) = @_;
    $glob =~ s/\./\\./g;
    $glob =~ s/\*/.*/g;
    $glob =~ s/\?/./g;
    return qr/^$glob$/i;
}

# Helper: format file permissions
sub _format_perms {
    my ($mode) = @_;
    my $perms = '';
    $perms .= ($mode & 0400) ? 'r' : '-';
    $perms .= ($mode & 0200) ? 'w' : '-';
    $perms .= ($mode & 0100) ? 'x' : '-';
    $perms .= ($mode & 0040) ? 'r' : '-';



( run in 0.624 second using v1.01-cache-2.11-cpan-4de7c937500 )