Metadata-Version: 2.4
Name: llar
Version: 0.1.1
Summary: Look after the local state coding agents keep about your projects.
Keywords: claude,codex,sessions,developer-tools,cli
Author: All Tuner
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Dist: psutil>=7.2.2
Requires-Dist: typer>=0.27.3
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/alltuner/llar
Project-URL: Repository, https://github.com/alltuner/llar
Project-URL: Issues, https://github.com/alltuner/llar/issues
Project-URL: Documentation, https://github.com/alltuner/llar#readme
Description-Content-Type: text/markdown

# 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](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) lists the implementation gaps and deferred work.

## Install

llar supports Linux and macOS and requires Python 3.12 or later. Install the
[PyPI package](https://pypi.org/project/llar/) with
[uv](https://docs.astral.sh/uv/):

```sh
uv tool install llar
llar --help
llar status
```

For a one-off run without a persistent tool installation:

```sh
uvx llar --help
```

Upgrade an installed copy with:

```sh
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:

```sh
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

```sh
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.

```sh
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.

```sh
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:

```sh
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:

```sh
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:

```sh
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:

```sh
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](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) 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:

```sh
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

```sh
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](https://github.com/alltuner/llar/blob/main/docs/output.md) 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.

```sh
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](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) | Supported workflows, selection, SSH, and failure handling |
| [Output and troubleshooting](https://github.com/alltuner/llar/blob/main/docs/output.md) | Evidence fields, JSON, exit codes, and common blockers |
| [Roadmap](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) | Pending, deferred, and unspecified work |
| [Releasing](https://github.com/alltuner/llar/blob/main/docs/releasing.md) | Maintainer workflow and PyPI trusted publishing |
| [CLI contract](https://github.com/alltuner/llar/blob/main/docs/cli-contract.md) | Accepted target surface; includes commands not implemented yet |
| [Transfer design](https://github.com/alltuner/llar/blob/main/docs/transfers.md) | Safety protocol, adapter decisions, and implementation constraints |
| [Architecture](https://github.com/alltuner/llar/blob/main/docs/architecture.md) | Models, boundaries, and coordination |
| [Native attribution](https://github.com/alltuner/llar/blob/main/docs/state-attribution.md) | Recognized storage layouts and ownership evidence |

For development, clone the repository and use uv's project environment.
[just](https://just.systems/) and the copy/test dependencies must be installed:

```sh
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](https://github.com/alltuner/llar/blob/main/LICENSE), copyright All Tuner. Packaged Codex schema material retains its
[upstream license and notices](https://github.com/alltuner/llar/blob/main/src/llar/harnesses/codex/NOTICE).
