File Coverage

blib/lib/Sim/Agent/Journal.pm
Criterion Covered Total %
statement 6 39 15.3
branch 0 14 0.0
condition n/a
subroutine 2 8 25.0
pod 0 4 0.0
total 8 65 12.3


line stmt bran cond sub pod time code
1             package Sim::Agent::Journal;
2              
3 1     1   8 use strict;
  1         2  
  1         44  
4 1     1   5 use warnings;
  1         2  
  1         807  
5              
6             sub new
7             {
8 0     0 0   my ($class, %opts) = @_;
9              
10 0           my $self = {};
11 0           bless $self, $class;
12              
13 0           my $run_dir = $self->_create_run_dir;
14              
15 0 0         open my $fh, '>', "$run_dir/journal.log"
16             or die "Cannot open journal.log";
17              
18 0           $self->{run_dir} = $run_dir;
19 0           $self->{fh} = $fh;
20              
21 0           return $self;
22             }
23              
24             # ------------------------------------------------------------
25             # Public Methods
26             # ------------------------------------------------------------
27              
28             sub log
29             {
30 0     0 0   my ($self, $message) = @_;
31              
32 0           my $ts = $self->_timestamp;
33              
34 0           print { $self->{fh} } "[$ts] $message\n";
  0            
35             }
36              
37             sub archive_plan
38             {
39 0     0 0   my ($self, $plan_file) = @_;
40              
41 0 0         open my $in, '<', $plan_file
42             or die "Cannot read plan file: $plan_file";
43              
44 0 0         open my $out, '>', "$self->{run_dir}/plan.sexpr"
45             or die "Cannot write archived plan";
46              
47 0           while (<$in>)
48             {
49 0           print {$out} $_;
  0            
50             }
51              
52 0           close $in;
53 0           close $out;
54             }
55              
56             sub agent_dir
57             {
58 0     0 0   my ($self, $agent) = @_;
59              
60 0           my $dir = "$self->{run_dir}/agents/$agent";
61              
62 0 0         unless (-d $dir)
63             {
64 0 0         mkdir $dir
65             or die "Cannot create agent directory: $dir";
66             }
67              
68 0           return $dir;
69             }
70              
71             # ------------------------------------------------------------
72             # Private Helpers
73             # ------------------------------------------------------------
74              
75             sub _create_run_dir
76             {
77 0     0     my ($self) = @_;
78              
79 0           my $base = "run_" . $self->_timestamp;
80              
81 0 0         mkdir $base
82             or die "Cannot create run dir $base";
83              
84 0 0         mkdir "$base/agents"
85             or die "Cannot create agents dir";
86              
87 0           return $base;
88             }
89              
90             sub _timestamp
91             {
92 0     0     my ($self) = @_;
93              
94 0           my @t = localtime();
95              
96 0           return sprintf(
97             "%04d%02d%02d_%02d%02d%02d",
98             $t[5] + 1900,
99             $t[4] + 1,
100             $t[3],
101             $t[2],
102             $t[1],
103             $t[0],
104             );
105             }
106              
107             1;
108              
109             =pod
110              
111             =head1 NAME
112              
113             Sim::Agent::Journal - File-backed journaling and run directory management
114              
115             =head1 DESCRIPTION
116              
117             Creates the per-run directory, writes journal.log entries, archives the plan, and provides per-agent directories used by LLM adapters.
118              
119             See L.
120              
121             =head1 AUTHOR
122              
123             Gian Luca Brunetti (2026), gianluca.brunetti@gmail.com
124              
125             =head1 LICENSE
126              
127             The GNU General Public License v3.0
128              
129             =cut
130