Acme-Claude-Shell
view release on metacpan or search on metacpan
lib/Acme/Claude/Shell.pm view on Meta::CPAN
our $VERSION = '0.03';
=head1 NAME
Acme::Claude::Shell - AI-powered interactive shell using Claude Agent SDK
=head1 VERSION
Version 0.03
=head1 SYNOPSIS
use Acme::Claude::Shell qw(shell run);
# 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
=item * C<session()> for multi-turn conversations with context
=item * SDK MCP tools for shell operations
=item * Hooks for safety (confirm destructive commands)
=item * Dry-run mode to preview
=item * Async with IO::Async
=item * CLI utilities (spinners, colored output, menus)
=back
Describe what you want in natural language, and Claude figures out the
shell commands, explains them, and executes them (with your approval).
=head1 EXPORTS
=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
use Acme::Claude::Shell::Session;
use Acme::Claude::Shell::Query;
use IO::Async::Loop;
sub shell {
my (%args) = @_;
my $loop = $args{loop} // IO::Async::Loop->new;
my $session = Acme::Claude::Shell::Session->new(
loop => $loop,
dry_run => $args{dry_run} // 0,
safe_mode => $args{safe_mode} // 1,
working_dir => $args{working_dir} // '.',
colorful => $args{colorful} // _detect_color(),
($args{model} ? (model => $args{model}) : ()),
);
return $session->run->get;
}
sub run {
my ($prompt, %args) = @_;
my $loop = $args{loop} // IO::Async::Loop->new;
my $query = Acme::Claude::Shell::Query->new(
loop => $loop,
dry_run => $args{dry_run} // 0,
safe_mode => $args{safe_mode} // 1,
working_dir => $args{working_dir} // '.',
colorful => $args{colorful} // _detect_color(),
($args{model} ? (model => $args{model}) : ()),
);
return $query->run($prompt)->get;
}
sub _detect_color {
return -t STDOUT ? 1 : 0;
}
=head1 EXAMPLE SESSION
( run in 0.687 second using v1.01-cache-2.11-cpan-b85c58fdc1d )