llar 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. llar-0.1.1/LICENSE +21 -0
  2. llar-0.1.1/PKG-INFO +311 -0
  3. llar-0.1.1/README.md +284 -0
  4. llar-0.1.1/pyproject.toml +69 -0
  5. llar-0.1.1/pyproject.toml.orig +55 -0
  6. llar-0.1.1/src/llar/__init__.py +2 -0
  7. llar-0.1.1/src/llar/__main__.py +7 -0
  8. llar-0.1.1/src/llar/cli.py +646 -0
  9. llar-0.1.1/src/llar/core/__init__.py +2 -0
  10. llar-0.1.1/src/llar/core/activity.py +32 -0
  11. llar-0.1.1/src/llar/core/associations.py +271 -0
  12. llar-0.1.1/src/llar/core/atomic.py +38 -0
  13. llar-0.1.1/src/llar/core/context.py +36 -0
  14. llar-0.1.1/src/llar/core/conversations.py +93 -0
  15. llar-0.1.1/src/llar/core/coverage.py +293 -0
  16. llar-0.1.1/src/llar/core/doctor.py +72 -0
  17. llar-0.1.1/src/llar/core/file_copy.py +431 -0
  18. llar-0.1.1/src/llar/core/inspection.py +40 -0
  19. llar-0.1.1/src/llar/core/inventory.py +41 -0
  20. llar-0.1.1/src/llar/core/scope.py +29 -0
  21. llar-0.1.1/src/llar/core/snapshot.py +94 -0
  22. llar-0.1.1/src/llar/core/ssh.py +335 -0
  23. llar-0.1.1/src/llar/core/ssh_receiver.py +161 -0
  24. llar-0.1.1/src/llar/core/ssh_transfer.py +306 -0
  25. llar-0.1.1/src/llar/core/state.py +185 -0
  26. llar-0.1.1/src/llar/core/transfer_plan.py +725 -0
  27. llar-0.1.1/src/llar/core/transfers.py +206 -0
  28. llar-0.1.1/src/llar/harnesses/__init__.py +8 -0
  29. llar-0.1.1/src/llar/harnesses/base.py +19 -0
  30. llar-0.1.1/src/llar/harnesses/claude/__init__.py +121 -0
  31. llar-0.1.1/src/llar/harnesses/claude/activity.py +80 -0
  32. llar-0.1.1/src/llar/harnesses/claude/copy.py +577 -0
  33. llar-0.1.1/src/llar/harnesses/claude/locking.py +136 -0
  34. llar-0.1.1/src/llar/harnesses/claude/paths.py +18 -0
  35. llar-0.1.1/src/llar/harnesses/claude/records.py +220 -0
  36. llar-0.1.1/src/llar/harnesses/claude/state.py +385 -0
  37. llar-0.1.1/src/llar/harnesses/claude/transfer.py +131 -0
  38. llar-0.1.1/src/llar/harnesses/codex/Apache-2.0.txt +201 -0
  39. llar-0.1.1/src/llar/harnesses/codex/NOTICE +6 -0
  40. llar-0.1.1/src/llar/harnesses/codex/__init__.py +96 -0
  41. llar-0.1.1/src/llar/harnesses/codex/activity.py +75 -0
  42. llar-0.1.1/src/llar/harnesses/codex/copy.py +355 -0
  43. llar-0.1.1/src/llar/harnesses/codex/database.py +155 -0
  44. llar-0.1.1/src/llar/harnesses/codex/import_state.py +481 -0
  45. llar-0.1.1/src/llar/harnesses/codex/native-schema.json +621 -0
  46. llar-0.1.1/src/llar/harnesses/codex/publication.py +108 -0
  47. llar-0.1.1/src/llar/harnesses/codex/schemas.json +501 -0
  48. llar-0.1.1/src/llar/harnesses/codex/schemas.py +38 -0
  49. llar-0.1.1/src/llar/harnesses/codex/state.py +519 -0
  50. llar-0.1.1/src/llar/harnesses/codex/transfer.py +100 -0
  51. llar-0.1.1/src/llar/harnesses/transfers.py +91 -0
llar-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 All Tuner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
llar-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,311 @@
1
+ Metadata-Version: 2.4
2
+ Name: llar
3
+ Version: 0.1.1
4
+ Summary: Look after the local state coding agents keep about your projects.
5
+ Keywords: claude,codex,sessions,developer-tools,cli
6
+ Author: All Tuner
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.15
17
+ Classifier: Topic :: Software Development
18
+ Classifier: Topic :: Utilities
19
+ Requires-Dist: psutil>=7.2.2
20
+ Requires-Dist: typer>=0.27.3
21
+ Requires-Python: >=3.12
22
+ Project-URL: Homepage, https://github.com/alltuner/llar
23
+ Project-URL: Repository, https://github.com/alltuner/llar
24
+ Project-URL: Issues, https://github.com/alltuner/llar/issues
25
+ Project-URL: Documentation, https://github.com/alltuner/llar#readme
26
+ Description-Content-Type: text/markdown
27
+
28
+ # llar
29
+
30
+ Inspect and copy the project state that Claude Code and Codex keep outside your
31
+ checkout.
32
+
33
+ Moving a repository does not move its conversations, memories, or path-based
34
+ settings. llar discovers that state, explains its ownership, and plans transfers.
35
+ Supported copies can then be applied explicitly.
36
+
37
+ *Llar* is Catalan for home or hearth. The project is under active development;
38
+ the table below describes implemented support, not the eventual command surface.
39
+
40
+ ## What works today
41
+
42
+ | Operation | Support |
43
+ |---|---|
44
+ | Inspect projects, explicit trust, sessions, activity, and storage locations | Claude Code and Codex |
45
+ | Diagnose missing directories and unresolved state | Read-only |
46
+ | Copy project files locally | Explicit file selection |
47
+ | Copy project files over SSH | Push or pull, one remote endpoint |
48
+ | Copy Claude project state locally | Recognized settings, history, sessions, memory, and artifacts; select Claude explicitly |
49
+ | Copy Codex project state locally | Selected sessions, supported SQLite memory rows, and artifacts; exclude settings |
50
+ | Apply one copy across both harnesses | Pending |
51
+ | Transfer native state over SSH | Pending |
52
+ | Apply a move | Pending; move plans are available |
53
+
54
+ Every copy is a **dry run by default**. Writes require `--apply`. Destination
55
+ conflicts are refused, including existing native IDs or project-setting keys.
56
+ Unsupported or unattributed selected state blocks the transfer; llar does not
57
+ quietly drop it.
58
+
59
+ [What remains](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) lists the implementation gaps and deferred work.
60
+
61
+ ## Install
62
+
63
+ llar supports Linux and macOS and requires Python 3.12 or later. Install the
64
+ [PyPI package](https://pypi.org/project/llar/) with
65
+ [uv](https://docs.astral.sh/uv/):
66
+
67
+ ```sh
68
+ uv tool install llar
69
+ llar --help
70
+ llar status
71
+ ```
72
+
73
+ For a one-off run without a persistent tool installation:
74
+
75
+ ```sh
76
+ uvx llar --help
77
+ ```
78
+
79
+ Upgrade an installed copy with:
80
+
81
+ ```sh
82
+ uv tool upgrade llar
83
+ ```
84
+
85
+ The examples below use the installed llar command and work outside a source
86
+ checkout. Replace /path/to/... placeholders with your own paths.
87
+
88
+ Copies also require Linux or macOS, git, and rsync 3.2.6 or later with ACL and
89
+ extended-attribute support. Apple's bundled openrsync is insufficient. On macOS,
90
+ the development workflow installs modern rsync through Homebrew:
91
+
92
+ ```sh
93
+ brew install rsync
94
+ ```
95
+
96
+ llar selects the first compatible rsync in absolute PATH entries. SSH copies
97
+ require compatible llar helpers and modern rsync on both machines.
98
+
99
+ ## Inspect a project
100
+
101
+ ```sh
102
+ llar status /path/to/project
103
+ llar projects list
104
+ llar projects list --missing
105
+ llar projects trust show /path/to/project
106
+ llar doctor --dir /path/to/project
107
+ ```
108
+
109
+ A project is one absolute directory. Inspection filters are exact unless you
110
+ request descendants explicitly. A directory is never expanded to its Git root.
111
+
112
+ ```sh
113
+ llar projects list --dir /path/to/project --recursive
114
+ llar sessions list --dir /path/to/project --harness claude
115
+ llar sessions list --dir /path/to/project --recursive
116
+ llar activity list --dir /path/to/project --state live
117
+ ```
118
+
119
+ Options follow the leaf command. `--harness` is repeatable; inspection otherwise
120
+ selects both harnesses.
121
+
122
+ ### Sessions and activity answer different questions
123
+
124
+ A session is a logical conversation, identified by its harness and native ID.
125
+ It can have several transcript files and runtime observations, counted separately.
126
+
127
+ - Session directory filters use **started_in**, the recorded launch directory.
128
+ - Activity directory filters use **observed_in**, the runtime directory when known.
129
+ - Transfer adapters track **current ownership** separately from launch history.
130
+
131
+ A copied session retains its original launch directory. Copying does not make
132
+ it a conversation that started in the destination. Codex writer locks identify
133
+ thread ownership but do not supply an observed runtime directory.
134
+
135
+ ```sh
136
+ llar sessions list
137
+ llar sessions list --live
138
+ llar activity list --state unknown
139
+ llar activity list --unassigned
140
+ ```
141
+
142
+ To inspect a single session, take its reference from the list. In this example,
143
+ replace `codex:UUID` with that reference:
144
+
145
+ ```sh
146
+ llar sessions show codex:UUID
147
+ ```
148
+
149
+ No activity observed is not proof of idleness. Transfer application performs its
150
+ own checks and acquires the required native locks.
151
+
152
+ ### Trust and memory counts
153
+
154
+ Trust output describes a supported **explicit setting**, not the harness's full
155
+ effective policy. `unset` means the setting was inspected and no supported
156
+ explicit decision was found; `unknown` means it could not be established.
157
+
158
+ Status currently reports `memory_inventory=not_inspected` and a null
159
+ `memory_count`. That does not mean there are no memories. Transfer adapters have
160
+ a separate, broader inventory for supported memory storage.
161
+
162
+ ## Copy project files
163
+
164
+ Preview first, then apply the same selection:
165
+
166
+ ```sh
167
+ llar cp /path/to/source /path/to/target --only files
168
+ llar cp /path/to/source /path/to/target --only files --apply
169
+ ```
170
+
171
+ The destination names the **exact resulting project root** and must not exist
172
+ when files are selected. A trailing slash does not change nesting semantics.
173
+ Hidden files and symlinks are included; symlinks are preserved rather than followed.
174
+
175
+ llar stages privately, verifies content and metadata, and publishes without
176
+ replacing the destination. Copies retain the source. Linked Git worktrees,
177
+ submodules, and unverified external Git bindings are refused.
178
+
179
+ ## Copy native project state
180
+
181
+ Omitting `--only` selects files and all attributable native components. Omitting
182
+ `--harness` selects both harnesses. Because combined application is pending,
183
+ native copies currently require an explicit single-harness selection.
184
+
185
+ A new project directory does not create a new native conversation identity.
186
+ Copying sessions into the same native store conflicts with their existing IDs.
187
+ The examples use a separate destination home for native state:
188
+
189
+ ```sh
190
+ llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home
191
+ llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home --apply
192
+ ```
193
+
194
+ Claude shared settings/history updates add only disjoint records and preserve
195
+ unrelated destination data under native locks. Unsupported formats and artifact
196
+ stores remain blockers.
197
+
198
+ For a supported Codex session/artifact selection:
199
+
200
+ ```sh
201
+ llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home
202
+ llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home --apply
203
+ ```
204
+
205
+ That Codex example is state-only: it does not copy project files. Add another
206
+ `--only files` to include them. SQLite memory rows can be selected with
207
+ `--only memory`; Git-backed memory stores and Codex shared settings remain
208
+ unsupported. Dependencies must be selected explicitly.
209
+
210
+ The [transfer guide](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) explains component selection,
211
+ destination profiles, conflicts, native format limits, and partial failures.
212
+
213
+ ## Copy files across machines
214
+
215
+ SSH currently supports explicit **files-only** copies in either direction:
216
+
217
+ ```sh
218
+ llar cp /path/to/source machine:~/repos/target --only files
219
+ llar cp /path/to/source machine:~/repos/target --only files --apply
220
+ llar cp machine:~/repos/source /path/to/target --only files --apply
221
+ ```
222
+
223
+ Use existing OpenSSH aliases, authentication, and trusted host keys. Remote paths
224
+ must be absolute or start with `~/`, expanded remotely. An optional
225
+ `--ssh-config` selects a local OpenSSH configuration file.
226
+
227
+ Initial SSH support requires matching OS platforms, equal user IDs, and
228
+ preservable numeric group ownership. Cross-platform metadata translation is
229
+ pending. Native state over SSH and all move application remain blocked.
230
+
231
+ ## Read results reliably
232
+
233
+ ```sh
234
+ llar status /path/to/project --json
235
+ llar sessions list --json
236
+ llar cp /path/to/source /path/to/target --only files --json
237
+ ```
238
+
239
+ JSON includes `items`, `diagnostics`, and `coverage`. Complete coverage means the
240
+ declared inspection finished; it does not mean every native feature is supported.
241
+ Partial results retain useful records, but their counts are not guaranteed totals.
242
+
243
+ | Exit code | Meaning |
244
+ |---|---|
245
+ | 0 | Inspection or supported preview completed, or apply succeeded. Doctor findings alone do not make inspection fail. |
246
+ | 1 | Inspection is incomplete, a plan is blocked, or apply failed or partially completed. |
247
+ | 2 | Invalid usage, or a missing/ambiguous session reference after a complete scan. |
248
+
249
+ Applied copies record progress under the destination home's private
250
+ `.local/state/llar/operations` directory. Publication can be partial across files
251
+ or databases. SSH disconnection during final publication can leave its outcome
252
+ unknown. Keep the reported receipt and staging; automatic recovery is pending.
253
+
254
+ [Output and troubleshooting](https://github.com/alltuner/llar/blob/main/docs/output.md) explains coverage, trust, blockers,
255
+ receipts, and the JSON fields needed by scripts.
256
+
257
+ ## State locations
258
+
259
+ Without `--home`, llar uses the current user's home and honors `CLAUDE_CONFIG_DIR`,
260
+ `CODEX_HOME`, and the supported `CODEX_SQLITE_HOME` override. An explicit
261
+ `--home` selects an isolated effective home and ignores those native overrides.
262
+
263
+ ```sh
264
+ llar harnesses
265
+ llar harnesses --home /path/to/home --json
266
+ ```
267
+
268
+ `--home` selects state stores; it does not rewrite project paths recorded inside
269
+ them. Alternate homes are storage contexts, not filesystem sandboxes: recorded
270
+ absolute paths and supported native configuration references retain their meaning.
271
+ For transfers, `--home` is the source home and `--target-home` is the
272
+ destination home. Local transfers default the latter to the former; SSH
273
+ transfers do not.
274
+
275
+ ## Documentation and development
276
+
277
+ | Document | Purpose |
278
+ |---|---|
279
+ | [Transfer guide](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) | Supported workflows, selection, SSH, and failure handling |
280
+ | [Output and troubleshooting](https://github.com/alltuner/llar/blob/main/docs/output.md) | Evidence fields, JSON, exit codes, and common blockers |
281
+ | [Roadmap](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) | Pending, deferred, and unspecified work |
282
+ | [Releasing](https://github.com/alltuner/llar/blob/main/docs/releasing.md) | Maintainer workflow and PyPI trusted publishing |
283
+ | [CLI contract](https://github.com/alltuner/llar/blob/main/docs/cli-contract.md) | Accepted target surface; includes commands not implemented yet |
284
+ | [Transfer design](https://github.com/alltuner/llar/blob/main/docs/transfers.md) | Safety protocol, adapter decisions, and implementation constraints |
285
+ | [Architecture](https://github.com/alltuner/llar/blob/main/docs/architecture.md) | Models, boundaries, and coordination |
286
+ | [Native attribution](https://github.com/alltuner/llar/blob/main/docs/state-attribution.md) | Recognized storage layouts and ownership evidence |
287
+
288
+ For development, clone the repository and use uv's project environment.
289
+ [just](https://just.systems/) and the copy/test dependencies must be installed:
290
+
291
+ ```sh
292
+ git clone https://github.com/alltuner/llar.git
293
+ cd llar
294
+ uv sync --locked
295
+ uv run llar --help
296
+ just check
297
+ just smoke
298
+ just build
299
+ ```
300
+
301
+ Pytest uses isolated homes, real files, SQLite databases, processes, native locks,
302
+ and an ephemeral OpenSSH server. Development also requires ssh, ssh-keygen, and
303
+ sshd; Linux CI installs openssh-server and prepares its privilege-separation
304
+ directory. Tests use generated keys and a private server configuration.
305
+ Ruff handles lint/format checks and ty checks types. CI targets Linux and macOS
306
+ with Python 3.12 and 3.15.
307
+
308
+ ## License
309
+
310
+ [MIT](https://github.com/alltuner/llar/blob/main/LICENSE), copyright All Tuner. Packaged Codex schema material retains its
311
+ [upstream license and notices](https://github.com/alltuner/llar/blob/main/src/llar/harnesses/codex/NOTICE).
llar-0.1.1/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # llar
2
+
3
+ Inspect and copy the project state that Claude Code and Codex keep outside your
4
+ checkout.
5
+
6
+ Moving a repository does not move its conversations, memories, or path-based
7
+ settings. llar discovers that state, explains its ownership, and plans transfers.
8
+ Supported copies can then be applied explicitly.
9
+
10
+ *Llar* is Catalan for home or hearth. The project is under active development;
11
+ the table below describes implemented support, not the eventual command surface.
12
+
13
+ ## What works today
14
+
15
+ | Operation | Support |
16
+ |---|---|
17
+ | Inspect projects, explicit trust, sessions, activity, and storage locations | Claude Code and Codex |
18
+ | Diagnose missing directories and unresolved state | Read-only |
19
+ | Copy project files locally | Explicit file selection |
20
+ | Copy project files over SSH | Push or pull, one remote endpoint |
21
+ | Copy Claude project state locally | Recognized settings, history, sessions, memory, and artifacts; select Claude explicitly |
22
+ | Copy Codex project state locally | Selected sessions, supported SQLite memory rows, and artifacts; exclude settings |
23
+ | Apply one copy across both harnesses | Pending |
24
+ | Transfer native state over SSH | Pending |
25
+ | Apply a move | Pending; move plans are available |
26
+
27
+ Every copy is a **dry run by default**. Writes require `--apply`. Destination
28
+ conflicts are refused, including existing native IDs or project-setting keys.
29
+ Unsupported or unattributed selected state blocks the transfer; llar does not
30
+ quietly drop it.
31
+
32
+ [What remains](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) lists the implementation gaps and deferred work.
33
+
34
+ ## Install
35
+
36
+ llar supports Linux and macOS and requires Python 3.12 or later. Install the
37
+ [PyPI package](https://pypi.org/project/llar/) with
38
+ [uv](https://docs.astral.sh/uv/):
39
+
40
+ ```sh
41
+ uv tool install llar
42
+ llar --help
43
+ llar status
44
+ ```
45
+
46
+ For a one-off run without a persistent tool installation:
47
+
48
+ ```sh
49
+ uvx llar --help
50
+ ```
51
+
52
+ Upgrade an installed copy with:
53
+
54
+ ```sh
55
+ uv tool upgrade llar
56
+ ```
57
+
58
+ The examples below use the installed llar command and work outside a source
59
+ checkout. Replace /path/to/... placeholders with your own paths.
60
+
61
+ Copies also require Linux or macOS, git, and rsync 3.2.6 or later with ACL and
62
+ extended-attribute support. Apple's bundled openrsync is insufficient. On macOS,
63
+ the development workflow installs modern rsync through Homebrew:
64
+
65
+ ```sh
66
+ brew install rsync
67
+ ```
68
+
69
+ llar selects the first compatible rsync in absolute PATH entries. SSH copies
70
+ require compatible llar helpers and modern rsync on both machines.
71
+
72
+ ## Inspect a project
73
+
74
+ ```sh
75
+ llar status /path/to/project
76
+ llar projects list
77
+ llar projects list --missing
78
+ llar projects trust show /path/to/project
79
+ llar doctor --dir /path/to/project
80
+ ```
81
+
82
+ A project is one absolute directory. Inspection filters are exact unless you
83
+ request descendants explicitly. A directory is never expanded to its Git root.
84
+
85
+ ```sh
86
+ llar projects list --dir /path/to/project --recursive
87
+ llar sessions list --dir /path/to/project --harness claude
88
+ llar sessions list --dir /path/to/project --recursive
89
+ llar activity list --dir /path/to/project --state live
90
+ ```
91
+
92
+ Options follow the leaf command. `--harness` is repeatable; inspection otherwise
93
+ selects both harnesses.
94
+
95
+ ### Sessions and activity answer different questions
96
+
97
+ A session is a logical conversation, identified by its harness and native ID.
98
+ It can have several transcript files and runtime observations, counted separately.
99
+
100
+ - Session directory filters use **started_in**, the recorded launch directory.
101
+ - Activity directory filters use **observed_in**, the runtime directory when known.
102
+ - Transfer adapters track **current ownership** separately from launch history.
103
+
104
+ A copied session retains its original launch directory. Copying does not make
105
+ it a conversation that started in the destination. Codex writer locks identify
106
+ thread ownership but do not supply an observed runtime directory.
107
+
108
+ ```sh
109
+ llar sessions list
110
+ llar sessions list --live
111
+ llar activity list --state unknown
112
+ llar activity list --unassigned
113
+ ```
114
+
115
+ To inspect a single session, take its reference from the list. In this example,
116
+ replace `codex:UUID` with that reference:
117
+
118
+ ```sh
119
+ llar sessions show codex:UUID
120
+ ```
121
+
122
+ No activity observed is not proof of idleness. Transfer application performs its
123
+ own checks and acquires the required native locks.
124
+
125
+ ### Trust and memory counts
126
+
127
+ Trust output describes a supported **explicit setting**, not the harness's full
128
+ effective policy. `unset` means the setting was inspected and no supported
129
+ explicit decision was found; `unknown` means it could not be established.
130
+
131
+ Status currently reports `memory_inventory=not_inspected` and a null
132
+ `memory_count`. That does not mean there are no memories. Transfer adapters have
133
+ a separate, broader inventory for supported memory storage.
134
+
135
+ ## Copy project files
136
+
137
+ Preview first, then apply the same selection:
138
+
139
+ ```sh
140
+ llar cp /path/to/source /path/to/target --only files
141
+ llar cp /path/to/source /path/to/target --only files --apply
142
+ ```
143
+
144
+ The destination names the **exact resulting project root** and must not exist
145
+ when files are selected. A trailing slash does not change nesting semantics.
146
+ Hidden files and symlinks are included; symlinks are preserved rather than followed.
147
+
148
+ llar stages privately, verifies content and metadata, and publishes without
149
+ replacing the destination. Copies retain the source. Linked Git worktrees,
150
+ submodules, and unverified external Git bindings are refused.
151
+
152
+ ## Copy native project state
153
+
154
+ Omitting `--only` selects files and all attributable native components. Omitting
155
+ `--harness` selects both harnesses. Because combined application is pending,
156
+ native copies currently require an explicit single-harness selection.
157
+
158
+ A new project directory does not create a new native conversation identity.
159
+ Copying sessions into the same native store conflicts with their existing IDs.
160
+ The examples use a separate destination home for native state:
161
+
162
+ ```sh
163
+ llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home
164
+ llar cp /path/to/source /path/to/target --harness claude --target-home /path/to/destination-home --apply
165
+ ```
166
+
167
+ Claude shared settings/history updates add only disjoint records and preserve
168
+ unrelated destination data under native locks. Unsupported formats and artifact
169
+ stores remain blockers.
170
+
171
+ For a supported Codex session/artifact selection:
172
+
173
+ ```sh
174
+ llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home
175
+ llar cp /path/to/source /path/to/target --harness codex --only sessions --only artifacts --target-home /path/to/destination-home --apply
176
+ ```
177
+
178
+ That Codex example is state-only: it does not copy project files. Add another
179
+ `--only files` to include them. SQLite memory rows can be selected with
180
+ `--only memory`; Git-backed memory stores and Codex shared settings remain
181
+ unsupported. Dependencies must be selected explicitly.
182
+
183
+ The [transfer guide](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) explains component selection,
184
+ destination profiles, conflicts, native format limits, and partial failures.
185
+
186
+ ## Copy files across machines
187
+
188
+ SSH currently supports explicit **files-only** copies in either direction:
189
+
190
+ ```sh
191
+ llar cp /path/to/source machine:~/repos/target --only files
192
+ llar cp /path/to/source machine:~/repos/target --only files --apply
193
+ llar cp machine:~/repos/source /path/to/target --only files --apply
194
+ ```
195
+
196
+ Use existing OpenSSH aliases, authentication, and trusted host keys. Remote paths
197
+ must be absolute or start with `~/`, expanded remotely. An optional
198
+ `--ssh-config` selects a local OpenSSH configuration file.
199
+
200
+ Initial SSH support requires matching OS platforms, equal user IDs, and
201
+ preservable numeric group ownership. Cross-platform metadata translation is
202
+ pending. Native state over SSH and all move application remain blocked.
203
+
204
+ ## Read results reliably
205
+
206
+ ```sh
207
+ llar status /path/to/project --json
208
+ llar sessions list --json
209
+ llar cp /path/to/source /path/to/target --only files --json
210
+ ```
211
+
212
+ JSON includes `items`, `diagnostics`, and `coverage`. Complete coverage means the
213
+ declared inspection finished; it does not mean every native feature is supported.
214
+ Partial results retain useful records, but their counts are not guaranteed totals.
215
+
216
+ | Exit code | Meaning |
217
+ |---|---|
218
+ | 0 | Inspection or supported preview completed, or apply succeeded. Doctor findings alone do not make inspection fail. |
219
+ | 1 | Inspection is incomplete, a plan is blocked, or apply failed or partially completed. |
220
+ | 2 | Invalid usage, or a missing/ambiguous session reference after a complete scan. |
221
+
222
+ Applied copies record progress under the destination home's private
223
+ `.local/state/llar/operations` directory. Publication can be partial across files
224
+ or databases. SSH disconnection during final publication can leave its outcome
225
+ unknown. Keep the reported receipt and staging; automatic recovery is pending.
226
+
227
+ [Output and troubleshooting](https://github.com/alltuner/llar/blob/main/docs/output.md) explains coverage, trust, blockers,
228
+ receipts, and the JSON fields needed by scripts.
229
+
230
+ ## State locations
231
+
232
+ Without `--home`, llar uses the current user's home and honors `CLAUDE_CONFIG_DIR`,
233
+ `CODEX_HOME`, and the supported `CODEX_SQLITE_HOME` override. An explicit
234
+ `--home` selects an isolated effective home and ignores those native overrides.
235
+
236
+ ```sh
237
+ llar harnesses
238
+ llar harnesses --home /path/to/home --json
239
+ ```
240
+
241
+ `--home` selects state stores; it does not rewrite project paths recorded inside
242
+ them. Alternate homes are storage contexts, not filesystem sandboxes: recorded
243
+ absolute paths and supported native configuration references retain their meaning.
244
+ For transfers, `--home` is the source home and `--target-home` is the
245
+ destination home. Local transfers default the latter to the former; SSH
246
+ transfers do not.
247
+
248
+ ## Documentation and development
249
+
250
+ | Document | Purpose |
251
+ |---|---|
252
+ | [Transfer guide](https://github.com/alltuner/llar/blob/main/docs/usage-transfers.md) | Supported workflows, selection, SSH, and failure handling |
253
+ | [Output and troubleshooting](https://github.com/alltuner/llar/blob/main/docs/output.md) | Evidence fields, JSON, exit codes, and common blockers |
254
+ | [Roadmap](https://github.com/alltuner/llar/blob/main/docs/roadmap.md) | Pending, deferred, and unspecified work |
255
+ | [Releasing](https://github.com/alltuner/llar/blob/main/docs/releasing.md) | Maintainer workflow and PyPI trusted publishing |
256
+ | [CLI contract](https://github.com/alltuner/llar/blob/main/docs/cli-contract.md) | Accepted target surface; includes commands not implemented yet |
257
+ | [Transfer design](https://github.com/alltuner/llar/blob/main/docs/transfers.md) | Safety protocol, adapter decisions, and implementation constraints |
258
+ | [Architecture](https://github.com/alltuner/llar/blob/main/docs/architecture.md) | Models, boundaries, and coordination |
259
+ | [Native attribution](https://github.com/alltuner/llar/blob/main/docs/state-attribution.md) | Recognized storage layouts and ownership evidence |
260
+
261
+ For development, clone the repository and use uv's project environment.
262
+ [just](https://just.systems/) and the copy/test dependencies must be installed:
263
+
264
+ ```sh
265
+ git clone https://github.com/alltuner/llar.git
266
+ cd llar
267
+ uv sync --locked
268
+ uv run llar --help
269
+ just check
270
+ just smoke
271
+ just build
272
+ ```
273
+
274
+ Pytest uses isolated homes, real files, SQLite databases, processes, native locks,
275
+ and an ephemeral OpenSSH server. Development also requires ssh, ssh-keygen, and
276
+ sshd; Linux CI installs openssh-server and prepares its privilege-separation
277
+ directory. Tests use generated keys and a private server configuration.
278
+ Ruff handles lint/format checks and ty checks types. CI targets Linux and macOS
279
+ with Python 3.12 and 3.15.
280
+
281
+ ## License
282
+
283
+ [MIT](https://github.com/alltuner/llar/blob/main/LICENSE), copyright All Tuner. Packaged Codex schema material retains its
284
+ [upstream license and notices](https://github.com/alltuner/llar/blob/main/src/llar/harnesses/codex/NOTICE).
@@ -0,0 +1,69 @@
1
+ [project]
2
+ name = "llar"
3
+ version = "0.1.1"
4
+ description = "Look after the local state coding agents keep about your projects."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.12"
9
+ keywords = [
10
+ "claude",
11
+ "codex",
12
+ "sessions",
13
+ "developer-tools",
14
+ "cli",
15
+ ]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: MacOS",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.15",
25
+ "Topic :: Software Development",
26
+ "Topic :: Utilities",
27
+ ]
28
+ dependencies = [
29
+ "psutil>=7.2.2",
30
+ "typer>=0.27.3",
31
+ ]
32
+
33
+ [[project.authors]]
34
+ name = "All Tuner"
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/alltuner/llar"
38
+ Repository = "https://github.com/alltuner/llar"
39
+ Issues = "https://github.com/alltuner/llar/issues"
40
+ Documentation = "https://github.com/alltuner/llar#readme"
41
+
42
+ [project.scripts]
43
+ llar = "llar.cli:app"
44
+
45
+ [build-system]
46
+ requires = ["uv_build>=0.13.6,<0.14"]
47
+ build-backend = "uv_build"
48
+
49
+ [tool.ruff]
50
+ target-version = "py312"
51
+
52
+ [tool.ruff.lint]
53
+ select = [
54
+ "E",
55
+ "F",
56
+ "I",
57
+ "UP",
58
+ "B",
59
+ ]
60
+
61
+ [tool.ty.rules]
62
+ all = "error"
63
+
64
+ [dependency-groups]
65
+ dev = [
66
+ "pytest>=9.2.0",
67
+ "ruff>=0.17.3",
68
+ "ty>=0.0.95",
69
+ ]