Acme-Claude-Shell
view release on metacpan or search on metacpan
lib/Acme/Claude/Shell/Session.pm view on Meta::CPAN
# Fun spinner styles with matching colors
my @SPINNERS = (
{ spinner => 'moon', spinner_color => 'yellow' },
{ spinner => 'earth', spinner_color => 'cyan' },
{ spinner => 'clock', spinner_color => 'blue' },
{ spinner => 'dots', spinner_color => 'magenta' },
{ spinner => 'material', spinner_color => 'green' },
{ spinner => 'circle_half', spinner_color => 'cyan' },
{ spinner => 'color_circles', spinner_color => 'white' },
);
sub _random_spinner {
return %{ $SPINNERS[rand @SPINNERS] };
}
=head1 NAME
Acme::Claude::Shell::Session - Multi-turn session for Acme::Claude::Shell
=head1 SYNOPSIS
use Acme::Claude::Shell::Session;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
my $session = Acme::Claude::Shell::Session->new(
loop => $loop,
dry_run => 0,
safe_mode => 1,
);
$session->run->get;
=head1 DESCRIPTION
Runs an interactive REPL using Claude's session() function for multi-turn
conversations. Claude remembers context from previous commands, so you can
say things like "now compress those files" after a find command.
Uses Claude::Agent SDK features:
=over 4
=item * C<session()> - Multi-turn conversation with context
=item * SDK MCP tools - execute_command, read_file, list_directory, search_files, get_system_info, get_working_directory
=item * Hooks - PreToolUse (audit), PostToolUse (stats), PostToolUseFailure (errors), Stop (statistics), Notification (logging)
=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
=item * C<history> - Select and re-run previous commands
=item * C<clear> - Clear the screen
=item * C<exit> / C<quit> - Exit the shell
=back
=head2 History
Command history is persisted to C<~/.acme_claude_shell_history> and loaded
on startup. Maximum 1000 lines are kept.
=cut
# Query cursor row position via /dev/tty (works even after Term::ReadLine)
# This avoids Term::ProgressSpinner's STDIN-based query which fails after readline
sub _get_cursor_row {
my $row;
eval {
require Term::ReadKey;
open(my $tty, '+<', '/dev/tty') or return undef;
# Set raw mode on the tty
Term::ReadKey::ReadMode(4, $tty);
# Send cursor position query to STDOUT (terminal sees it)
print STDOUT "\e[6n";
STDOUT->flush();
# Read response from the tty
my $response = '';
while (1) {
my $c = Term::ReadKey::ReadKey(0.1, $tty);
last unless defined $c;
$response .= $c;
last if $c eq 'R';
}
# Restore normal mode
Term::ReadKey::ReadMode(0, $tty);
close($tty);
if ($response =~ /\[(\d+);(\d+)R/) {
$row = $1;
}
};
return $row;
}
# Track session prompts for saving
my @_session_prompts;
sub _load_history {
( run in 1.033 second using v1.01-cache-2.11-cpan-140bd7fdf52 )