Acme-Claude-Shell
view release on metacpan or search on metacpan
lib/Acme/Claude/Shell.pm view on Meta::CPAN
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
============================================================
Acme::Claude::Shell
============================================================
i AI-powered shell - describe what you want in plain English
i Type 'exit' or 'quit' to leave, 'history' for command log
------------------------------------------------------------
acme_claude_shell> find all perl files larger than 100k
Thinking...
I'll find all .pl files over 100KB and display their sizes:
i Command: find . -name "*.pl" -size +100k -exec ls -lh {} \;
Action:
[a] Approve and run
[d] Dry-run (show only)
[e] Edit command
[x] Cancel
> a
-rw-r--r-- 1 user staff 142K Jan 10 14:23 ./big_script.pl
Done
acme_claude_shell> now compress that file
Thinking...
Based on our previous results, I'll compress:
i Command: gzip ./big_script.pl
Action:
[a] Approve and run
> a
Files compressed successfully
=head1 SDK FEATURES DEMONSTRATED
This module demonstrates every major feature of the Claude::Agent SDK:
=over 4
=item B<query()> - Single-shot mode via C<run()>
=item B<session()> - Multi-turn context via C<shell()>
=item B<SDK MCP Tools> - 6 tools: execute_command, read_file, list_directory, search_files, get_system_info, get_working_directory
=item B<Hooks (PreToolUse)> - Audit logging of tool calls
( run in 0.785 second using v1.01-cache-2.11-cpan-6aa56a78535 )