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(