llar
Inspect and copy the project state that Claude Code and Codex keep outside your checkout.
Moving a repository does not move its conversations, memories, or path-based settings. llar discovers that state, explains its ownership, and plans transfers. Supported copies can then be applied explicitly.
Llar is Catalan for home or hearth. The project is under active development; the table below describes implemented support, not the eventual command surface.
What works today
| Operation | Support |
|---|---|
| Inspect projects, explicit trust, sessions, activity, and storage locations | Claude Code and Codex |
| Diagnose missing directories and unresolved state | Read-only |
| Copy project files locally | Explicit file selection |
| Copy project files over SSH | Push or pull, one remote endpoint |
| Copy Claude project state locally | Recognized settings, history, sessions, memory, and artifacts; select Claude explicitly |
| Copy Codex project state locally | Selected sessions, supported SQLite memory rows, and artifacts; exclude settings |
| Apply one copy across both harnesses | Pending |
| Transfer native state over SSH | Pending |
| Apply a move | Pending; move plans are available |
Every copy is a dry run by default. Writes require --apply. Destination
conflicts are refused, including existing native IDs or project-setting keys.
Unsupported or unattributed selected state blocks the transfer; llar does not
quietly drop it.
What remains lists the implementation gaps and deferred work.
Install
llar supports Linux and macOS and requires Python 3.12 or later. Install the PyPI package with uv:
uv tool install llar
llar --help
llar status
For a one-off run without a persistent tool installation:
uvx llar --help
Upgrade an installed copy with:
uv tool upgrade llar
The examples below use the installed llar command and work outside a source checkout. Replace /path/to/... placeholders with your own paths.
Copies also require Linux or macOS, git, and rsync 3.2.6 or later with ACL and extended-attribute support. Apple's bundled openrsync is insufficient. On macOS, the development workflow installs modern rsync through Homebrew:
brew install rsync
llar selects the first compatible rsync in absolute PATH entries. SSH copies require compatible llar helpers and modern rsync on both machines.
Inspect a project
llar status /path/to/project
llar projects list
llar projects list --missing
llar projects trust show /path/to/project
llar doctor --dir /path/to/project
A project is one absolute directory. Inspection filters are exact unless you request descendants explicitly. A directory is never expanded to its Git root.
llar projects list --dir /path/to/project --recursive
llar sessions list --dir /path/to/project --harness claude
llar sessions list --dir /path/to/project --recursive
llar activity list --dir /path/to/project --state live
Options follow the leaf command. --harness is repeatable; inspection otherwise
selects both harnesses.
Sessions and activity answer different questions
A session is a logical conversation, identified by its harness and native ID. It can have several transcript files and runtime observations, counted separately.
- Session directory filters use started_in, the recorded launch directory.
- Activity directory filters use observed_in, the runtime directory when known.
- Transfer adapters track current ownership separately from launch history.
A copied session retains its original launch directory. Copying does not make it a conversation that started in the destination. Codex writer locks identify thread ownership but do not supply an observed runtime directory.
llar sessions list
llar sessions list --live
llar activity list --state unknown
llar activity list --unassigned
To inspect a single session, take its reference from the list. In this example,
replace codex:UUID with that reference:
llar sessions show codex:UUID
No activity observed is not proof of idleness. Transfer application performs its own checks and acquires the required native locks.
Trust and memory counts
Trust output describes a supported explicit setting, not the harness's full
effective policy. unset means the setting was inspected and no supported
explicit decision was found; unknown means it could not be established.
Status currently reports memory_inventory=not_inspected and a null
memory_count. That does not mean there are no memories. Transfer adapters have
a separate, broader inventory for supported memory storage.
Copy project files
Preview first, then apply the same selection:
llar cp /path/to/source /path/to/target --only files
llar cp /path/to/source /path/to/target --only files --apply
The destination names the exact resulting project root and must not exist when files are selected. A trailing slash does not change nesting semantics. Hidden files and symlinks are included; symlinks are preserved rather than followed.
llar stages privately, verifies content and metadata, and publishes without replacing the destination. Copies retain the source. Linked Git worktrees, submodules, and unverified external Git bindings are refused.
Copy native project state
Omitting --only selects files and all attributable native components. Omitting
--harness selects both harnesses. Because combined application is pending,
native copies currently require an explicit single-harness selection.
A new project directory does not create a new native conversation identity. Copying sessions into the same native store conflicts with their existing IDs. The examples use a separate destination home for native state:
llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home
llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home --apply
Claude shared settings/history updates add only disjoint records and preserve unrelated destination data under native locks. Unsupported formats and artifact stores remain blockers.
For a supported Codex session/artifact selection:
llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home
llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home --apply
That Codex example is state-only: it does not copy project files. Add another
--only files to include them. SQLite memory rows can be selected with
--only memory; Git-backed memory stores and Codex shared settings remain
unsupported. Dependencies must be selected explicitly.
The transfer guide explains component selection, destination profiles, conflicts, native format limits, and partial failures.
Copy files across machines
SSH currently supports explicit files-only copies in either direction:
llar cp /path/to/source machine:~/repos/target --only files
llar cp /path/to/source machine:~/repos/target --only files --apply
llar cp machine:~/repos/source /path/to/target --only files --apply
Use existing OpenSSH aliases, authentication, and trusted host keys. Remote paths
must be absolute or start with ~/, expanded remotely. An optional
--ssh-config selects a local OpenSSH configuration file.
Initial SSH support requires matching OS platforms, equal user IDs, and preservable numeric group ownership. Cross-platform metadata translation is pending. Native state over SSH and all move application remain blocked.
Read results reliably
llar status /path/to/project --json
llar sessions list --json
llar cp /path/to/source /path/to/target --only files --json
JSON includes items, diagnostics, and coverage. Complete coverage means the
declared inspection finished; it does not mean every native feature is supported.
Partial results retain useful records, but their counts are not guaranteed totals.
| Exit code | Meaning |
|---|---|
| 0 | Inspection or supported preview completed, or apply succeeded. Doctor findings alone do not make inspection fail. |
| 1 | Inspection is incomplete, a plan is blocked, or apply failed or partially completed. |
| 2 | Invalid usage, or a missing/ambiguous session reference after a complete scan. |
Applied copies record progress under the destination home's private
.local/state/llar/operations directory. Publication can be partial across files
or databases. SSH disconnection during final publication can leave its outcome
unknown. Keep the reported receipt and staging; automatic recovery is pending.
Output and troubleshooting explains coverage, trust, blockers, receipts, and the JSON fields needed by scripts.
State locations
Without --home, llar uses the current user's home and honors CLAUDE_CONFIG_DIR,
CODEX_HOME, and the supported CODEX_SQLITE_HOME override. An explicit
--home selects an isolated effective home and ignores those native overrides.
llar harnesses
llar harnesses --home /path/to/home --json
--home selects state stores; it does not rewrite project paths recorded inside
them. Alternate homes are storage contexts, not filesystem sandboxes: recorded
absolute paths and supported native configuration references retain their meaning.
For transfers, --home is the source home and --target-home is the
destination home. Local transfers default the latter to the former; SSH
transfers do not.
Documentation and development
| Document | Purpose |
|---|---|
| Transfer guide | Supported workflows, selection, SSH, and failure handling |
| Output and troubleshooting | Evidence fields, JSON, exit codes, and common blockers |
| Roadmap | Pending, deferred, and unspecified work |
| Releasing | Maintainer workflow and PyPI trusted publishing |
| CLI contract | Accepted target surface; includes commands not implemented yet |
| Transfer design | Safety protocol, adapter decisions, and implementation constraints |
| Architecture | Models, boundaries, and coordination |
| Native attribution | Recognized storage layouts and ownership evidence |
For development, clone the repository and use uv's project environment. just and the copy/test dependencies must be installed:
git clone https://github.com/alltuner/llar.git
cd llar
uv sync --locked
uv run llar --help
just check
just smoke
just build
Pytest uses isolated homes, real files, SQLite databases, processes, native locks, and an ephemeral OpenSSH server. Development also requires ssh, ssh-keygen, and sshd; Linux CI installs openssh-server and prepares its privilege-separation directory. Tests use generated keys and a private server configuration. Ruff handles lint/format checks and ty checks types. CI targets Linux and macOS with Python 3.12 and 3.15.
License
MIT, copyright All Tuner. Packaged Codex schema material retains its upstream license and notices.
Metadata
Release files for llar 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| llar-0.1.1.tar.gz | 87.2 kB | Without provenance | Details for llar-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| llar-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for llar-0.1.1-py3-none-any.whl |
Total release size: 192.0 kB
Release files / llar-0.1.1.tar.gz
| Download URL | llar-0.1.1.tar.gz |
|---|---|
| Size | 87.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c6516b302c26286ce89e2c0c18d9a399e56eef5247c6632f410790114611bbf
|
|
BLAKE2b-256 checksum How to use checksums |
4239d5075d2a9bda91b24383a16e688fa75d1d722a9a3026a1d5a8c6f7b2643a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / llar-0.1.1-py3-none-any.whl
| Download URL | llar-0.1.1-py3-none-any.whl |
|---|---|
| Size | 104.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7ed3632640085795bf75be401bff9bb38a28576a3fbacd7b36618d966494fd2
|
|
BLAKE2b-256 checksum How to use checksums |
221180f07fe56b96b6cc6c826b4b92567eb897cd037a84cf29e7b2ff9edab00f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for llar 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.