NAME

Langertha::Raider::SessionStore - Internal store of the session journals of one scope

VERSION

version 0.503

SYNOPSIS

# Internal to Langertha-Raider -- no API promise.
my $store = Langertha::Raider::SessionStore->new(scope => 'project', root => $dir);

my $session = $store->create;                 # new journal, locked for writing
my $run = $session->next_run;                 # 'r1'
$session->append('run.started', run => $run, engine => 'openai', model => 'gpt-4o');

my @ids     = $store->ids;                    # newest first
my $journal = $store->read($ids[0]);          # no lock needed
my $again   = $store->open($ids[0]);          # croaks "... is in use" while $session lives

DESCRIPTION

Internal module. Its interface may change without notice.

The session journals of one scope (ADR 0003, ADR 0015): the directory sessions/ under <project>/.raider (scope project) or ~/.raider (scope home), one <id>.jsonl per session. "create" and "open" hand out a Langertha::Raider::Session, the one writer of a journal, which holds its lock; "read" gives a Langertha::Raider::Session::Journal without taking a lock.

scope

project (the default) or home.

root

The project directory. Required for the project scope.

home

The home directory of the home scope. Defaults to $ENV{HOME}, then the user's home from the password database.

principal

The local user name written into session.created. Defaults to the name of the real user id, then $ENV{USER}.

clock

Code reference returning the current time as epoch seconds; the time of every event and the time in a new id. Defaults to "time" in Time::HiRes.

base

The scope directory: <root>/.raider or <home>/.raider, as a Path::Tiny.

dir

The sessions directory under "base".

is_id

$store->is_id('20260925-081500-3f2a');   # true

Whether the string has the form of a session id, YYYYMMDD-HHMMSS-xxxx.

path_of

my $file = $store->path_of($id);

The journal file of a session id. Croaks on a string that is no id, so no path outside "dir" can be built from user input.

exists

True when the session has a journal in this scope.

ids

The ids of the sessions in this scope, newest first. Empty when there is no sessions directory.

latest

The id of the newest session, or undef.

is_ref

$store->is_ref('3f2a');            # true
$store->is_ref('20260925-0815');   # true

Whether the string can name a session on the command line: a whole id, the start of one (at least four characters), or the four hex digits at its end. Also works as a class method. "resolve" finds the session it names.

resolve

my $id = $store->resolve('3f2a');

The id of the one session a reference ("is_ref") names: the session with that id, else the one whose id starts with it or ends in -REF. Croaks unknown session REF when there is none, and session REF is ambiguous: ID, ID (newest first) when there is more than one.

prepare_base

Creates "base". In the project scope it also writes .raider/.gitignore excluding sessions/ and lib/ when there is none, so journals and the local::lib of the Perl tools are never committed by default. Whatever creates .raider/ goes through here.

prepare

"prepare_base", then creates "dir".

new_id

A fresh id for the current time: YYYYMMDD-HHMMSS in UTC and four random hex digits.

create

my $session = $store->create;
my $fork    = $store->create(forked_from => $id);

Starts a new session: "prepare", claims a fresh id (a file that already exists is never reused), locks it and writes session.created as line 1 -- id, scope, root (the project, or the home directory), principal and raider (the version), plus the given fields (which never replace those).

open

my $session = $store->open($id);

Opens an existing session for writing. Croaks unknown session ID when it has no journal here, and session ID is in use when another writer holds its lock -- at once, without waiting.

read

my $journal = $store->read($id);

The Langertha::Raider::Session::Journal of a session, read without a lock. Croaks unknown session ID when there is none.

remove

$store->remove($id);

Deletes a session: its journal and its lock file. It takes the lock first, so it croaks session ID is in use -- at once -- while another writer has the session open, and unknown session ID when there is none. Nothing in Raider removes a session on its own.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha-raider/issues.

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.