Acme-Claude-Shell

 view release on metacpan or  search on metacpan

bin/acme_claude_shell  view on Meta::CPAN

    }

    print_section("Usage", $c);
    print "    acme_claude_shell [options]\n";
    print "    acme_claude_shell -c \"find all large log files\"\n\n";

    print_section("Options", $c);
    print_opt("-n, --dry-run", "Preview mode - show commands without executing", $c);
    print_opt("-u, --unsafe", "Disable safety confirmations for dangerous commands", $c);
    print_opt("--no-color", "Disable colored output", $c);
    print_opt("-d, --directory DIR", "Set working directory (default: current)", $c);
    print_opt("-c, --command CMD", "Run single command and exit (use '-' for stdin)", $c);
    print_opt("-m, --model MODEL", "Claude model to use (e.g., claude-opus-4-5)", $c);
    print_opt("-h, --help", "Show this help", $c);
    print_opt("-v, --version", "Show version", $c);
    print "\n";

    print_section("Examples", $c);
    print "    acme_claude_shell                         # Start interactive shell\n";
    print "    acme_claude_shell --dry-run               # Preview mode\n";
    print "    acme_claude_shell -d /var/log             # Start in specific directory\n";

bin/acme_claude_shell  view on Meta::CPAN

=item B<-u, --unsafe>

Disable safety confirmations for dangerous commands.

=item B<--no-color>

Disable colored output.

=item B<-d, --directory> DIR

Set working directory (default: current directory).

=item B<-c, --command> CMD

Run a single command and exit instead of starting interactive mode.
Use '-' to read the command from stdin for piping.

=item B<-m, --model> MODEL

Specify the Claude model to use (e.g., claude-opus-4-5, claude-sonnet-4-5).

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

    # Interactive session mode (uses session() for multi-turn context)
    shell();

    # Single-shot query mode (uses query())
    my $result = run("find all large log files");

    # With options
    shell(
        dry_run   => 1,      # Preview mode - show commands without executing
        safe_mode => 0,      # Disable dangerous command warnings
        colorful  => 1,      # Force colors (default: auto-detect)
    );

=head1 DESCRIPTION

Acme::Claude::Shell is an AI-enhanced interactive shell that showcases
all Claude::Agent SDK features:

=over 4

=item * C<query()> for single-shot commands

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

=head2 shell

    shell(%options);

Start an interactive REPL session. Claude remembers context from previous
commands, so you can say things like "now compress those files".

Options:

    dry_run     - Preview mode, don't execute commands
    safe_mode   - Confirm dangerous commands (default: 1)
    working_dir - Starting directory (default: current)
    colorful    - Force colors on/off (default: auto-detect)

=head2 run

    my $result = run($prompt, %options);

Execute a single command and return the result. Does not maintain
session context between calls.

=cut

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

=head2 Session Options

The following session attributes affect hook behavior:

=over 4

=item * C<verbose> - Enable verbose logging of tool calls and notifications

=item * C<audit_log> - Enable detailed audit logging to C<< $session->{_audit_log} >>

=item * C<colorful> - Use colored output (default: auto-detect TTY)

=back

=cut

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

    # Tool name pattern - matches mcp__shell-tools__execute_command
    my $execute_cmd_pattern = 'execute_command$';

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

=item * CLI utilities - Spinners and colored output

=back

=head2 Attributes

=over 4

=item * C<loop> (required) - IO::Async::Loop instance

=item * C<dry_run> - Preview mode, don't execute commands (default: 0)

=item * C<safe_mode> - Confirm dangerous commands (default: 1)

=item * C<working_dir> - Starting directory (default: '.')

=item * C<colorful> - Use colored output (default: 1)

=item * C<model> - Claude model to use (optional)

=back

=head2 Methods

=over 4

=item * C<run($prompt)> - Execute a single prompt and return a Future

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

=item * CLI utilities - Spinners, menus, colored output

=back

=head2 Attributes

=over 4

=item * C<loop> (required) - IO::Async::Loop instance

=item * C<dry_run> - Preview mode, don't execute commands (default: 0)

=item * C<safe_mode> - Confirm dangerous commands (default: 1)

=item * C<working_dir> - Starting directory (default: '.')

=item * C<colorful> - Use colored output (default: 1)

=item * C<model> - Claude model to use (optional)

=back

=head2 Built-in Commands

=over 4

=item * C<help> - Show help message

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

            '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);
            },
        ),

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


        # 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 => {

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

                    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',
                    },
                },
            },
            sub {
                my ($params, $loop) = @_;
                return _search_files_safe($session, $params, $loop);

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


        # get_system_info tool - safe system information, no confirmation needed
        tool(
            'get_system_info',
            'Get system information including OS, disk space, and memory. Safe operation - does not require user confirmation.',
            {
                type       => 'object',
                properties => {
                    info_type => {
                        type        => 'string',
                        description => 'Type of info: "all", "os", "disk", "memory", "processes" (defaults to "all")',
                        enum        => ['all', 'os', 'disk', 'memory', 'processes'],
                    },
                },
            },
            sub {
                my ($params, $loop) = @_;
                return _get_system_info($session, $params, $loop);
            },
        ),
    ];

t/04-session.t  view on Meta::CPAN


    my $session = Acme::Claude::Shell::Session->new(
        loop  => $loop,
        model => 'claude-sonnet-4-5',
    );

    ok($session->has_model, 'has_model returns true');
    is($session->model, 'claude-sonnet-4-5', 'model attribute');
};

# Test default values
subtest 'Session defaults' => sub {
    plan tests => 4;

    require IO::Async::Loop;
    my $loop = IO::Async::Loop->new;

    my $session = Acme::Claude::Shell::Session->new(
        loop => $loop,
    );

    is($session->dry_run, 0, 'dry_run defaults to 0');
    is($session->safe_mode, 1, 'safe_mode defaults to 1');
    is($session->working_dir, '.', 'working_dir defaults to .');
    is($session->colorful, 1, 'colorful defaults to 1');
};

# Test _history management
subtest 'Session history' => sub {
    plan tests => 3;

    require IO::Async::Loop;
    my $loop = IO::Async::Loop->new;

    my $session = Acme::Claude::Shell::Session->new(

t/05-query.t  view on Meta::CPAN


    my $query = Acme::Claude::Shell::Query->new(
        loop  => $loop,
        model => 'claude-opus-4-5',
    );

    ok($query->has_model, 'has_model returns true');
    is($query->model, 'claude-opus-4-5', 'model attribute');
};

# Test default values
subtest 'Query defaults' => sub {
    plan tests => 4;

    require IO::Async::Loop;
    my $loop = IO::Async::Loop->new;

    my $query = Acme::Claude::Shell::Query->new(
        loop => $loop,
    );

    is($query->dry_run, 0, 'dry_run defaults to 0');
    is($query->safe_mode, 1, 'safe_mode defaults to 1');
    is($query->working_dir, '.', 'working_dir defaults to .');
    is($query->colorful, 1, 'colorful defaults to 1');
};

# Test _spinner attribute
subtest 'Query spinner' => sub {
    plan tests => 3;

    require IO::Async::Loop;
    my $loop = IO::Async::Loop->new;

    my $query = Acme::Claude::Shell::Query->new(



( run in 0.706 second using v1.01-cache-2.11-cpan-140bd7fdf52 )