lairen 0.1.0__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.
lairen-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 igamenovoer
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.
lairen-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.4
2
+ Name: lairen
3
+ Version: 0.1.0
4
+ Summary: Store CLI-agent credentials and deploy them into target homes.
5
+ Author: igamenovoer
6
+ License: MIT
7
+ Keywords: cli,credentials,codex,kimi,oauth
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Utilities
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: click>=8.1
17
+ Dynamic: license-file
18
+
19
+ # lairen 来人
20
+
21
+ **Bring the right CLI-agent identity to the right place.**
22
+
23
+ `lairen` is a Python credential registry and deployer for CLI coding agents.
24
+ It stores a provider login once, then materializes it into any target home on
25
+ demand — project-local, holder directories, or throwaway worktrees.
26
+
27
+ Status: `0.1.0`, Pixi-managed, Click-based. Codex and Kimi are the tested
28
+ adapters; the other provider adapters are implemented but remain experimental
29
+ because this project has no live credentials for them yet. Remote quota
30
+ queries and OAuth refresh are the next milestones.
31
+
32
+ ## Why
33
+
34
+ - Keep credentials out of project repos and out of a single global home.
35
+ - Deploy a saved login into an arbitrary provider home.
36
+ - Preserve session-level Kimi identity: `(user_id, device_id)`, not just
37
+ `user_id`, so independent logins of one account stay addressable.
38
+ - Inspect expiry and usage from one command, including machine-readable JSON.
39
+ - Use explicit CLI arguments first; common provider environment variables are
40
+ respected only as fallbacks.
41
+
42
+ ## Requirements
43
+
44
+ - Python `>=3.11` (the Pixi environment pins the 3.11 line)
45
+ - Pixi for the managed development environment
46
+ - Click for the CLI
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pixi install
52
+ pixi run lairen --help
53
+ ```
54
+
55
+ A plain editable install works too:
56
+
57
+ ```bash
58
+ python -m pip install -e .
59
+ lairen --help
60
+ ```
61
+
62
+ ## Quick start
63
+
64
+ Codex and Kimi are the tested paths:
65
+
66
+ ```bash
67
+ # Register a Codex home (reads auth.json, never prints tokens)
68
+ pixi run lairen register codex --home ~/codex-holder/.codex
69
+
70
+ # Register a Kimi home (reads credentials/kimi-code.json)
71
+ pixi run lairen register kimi --home ~/kimi-homes/kimi-2064-1
72
+
73
+ # List saved identities
74
+ pixi run lairen list
75
+
76
+ # Deploy a saved login into a project-local home
77
+ pixi run lairen deploy codex/alice@example.com --home ./my-project/.codex
78
+
79
+ # Usage / expiry report (alias: stats)
80
+ pixi run lairen usage
81
+ pixi run lairen usage kimi/alice--device-id --json
82
+ ```
83
+
84
+ ## Provider surface
85
+
86
+ `lairen` exposes every provider surface that `subswap` supports. Adapters
87
+ marked `tested=no` are implemented against the upstream storage layouts but
88
+ have not been exercised with live credentials here.
89
+
90
+ | Provider | Tested | Env fallback | Default home | Credential | Notes |
91
+ |---|---:|---|---|---|---|
92
+ | `claude` | no | `CLAUDE_CONFIG_DIR` | `~/.claude` | `.credentials.json` | Merges `oauthAccount` metadata on deploy |
93
+ | `codex` | yes | `CODEX_HOME` | `~/.codex` | `auth.json` | ChatGPT OAuth |
94
+ | `commandcode` | no | `COMMANDCODE_HOME` | `~/.commandcode` | `auth.json` | API-key auth |
95
+ | `cursor` | no | `CURSOR_HOME` | `~/.config/Cursor/User/globalStorage` | `state.vscdb` | Desktop SQLite; close Cursor before deploying |
96
+ | `kimi` | yes | `KIMI_CODE_HOME` | `~/.kimi-code` | `credentials/kimi-code.json` | Session identity `user_id--device_id` |
97
+ | `opencode` | no | `OPENCODE_HOME` | `~/.local/share/opencode` | `auth.json` | Go API-key slot; Console accounts use the official CLI |
98
+
99
+ Provider home resolution order:
100
+
101
+ 1. `--home <path>`
102
+ 2. the provider environment variable (`CODEX_HOME`, `KIMI_CODE_HOME`, ...)
103
+ 3. the provider default
104
+
105
+ Deployment always requires an explicit `--home`; `lairen` does not infer a
106
+ target from an environment variable.
107
+
108
+ ## Commands
109
+
110
+ | Command | Purpose |
111
+ |---|---|
112
+ | `lairen register <provider> [--home PATH] [--label NAME]` | Save the live login from a provider home |
113
+ | `lairen list [--json]` | List saved accounts |
114
+ | `lairen show <ref>` | Show one account and its local usage metadata |
115
+ | `lairen deploy <ref> --home PATH` | Write a saved credential into a target home |
116
+ | `lairen usage [ref ...] [--json]` | Expiry/usage statistics (alias: `stats`) |
117
+ | `lairen remove <ref> --yes` | Remove an account from the registry and store |
118
+ | `lairen providers` | Show provider defaults, tested status, and notes |
119
+ | `lairen doctor` | Show resolved paths, account counts, and provider homes |
120
+
121
+ `<ref>` is `provider/id` (for example `codex/alice@example.com` or
122
+ `kimi/alice--<device-id>`). A bare id or label is accepted when it is unique.
123
+
124
+ ## Storage
125
+
126
+ ```
127
+ ~/.config/lairen/
128
+ registry.json # account metadata: provider, id, label, source
129
+ ~/.local/share/lairen/
130
+ credentials.json # credential blobs, mode 0600
131
+ state/snapshots/ # pre-deploy copies of overwritten target files
132
+ ```
133
+
134
+ Set `LAIREN_HOME=/absolute/path` to keep config, data, and state under one
135
+ root. This is a development and testing override, not an input mechanism for
136
+ provider selection.
137
+
138
+ ## Design
139
+
140
+ - **Registry and credentials stay separate.** Metadata is readable; secrets
141
+ live in one `0600` JSON file.
142
+ - **Deployment is atomic.** Target files are written through a temporary file
143
+ and `os.replace`, with a pre-deploy snapshot when the target already exists.
144
+ Provider-specific adapters merge rather than replace where upstream expects
145
+ it (OpenCode Go slot, Cursor `ItemTable`, Claude `oauthAccount`).
146
+ - **Kimi identity is a session.** `user_id` plus `device_id`, joined as
147
+ `user_id--device_id`, so multiple logins of one account remain distinct.
148
+ - **Usage is local-first.** `lairen usage` reports token expiry and refresh
149
+ timestamps from stored blobs. Remote quota endpoints plug in behind
150
+ `Provider.local_usage()` later.
151
+
152
+ ## Development
153
+
154
+ ```bash
155
+ pixi run test # core + aux unit/integration suites
156
+ pixi run test-core # tests for src/lairen
157
+ pixi run test-aux # tests for repository support files
158
+ pixi run lint
159
+ pixi run typecheck
160
+ ```
161
+
162
+ Codex and Kimi are the only adapters with live-credential tests. Other
163
+ adapters use fake payloads or remain untested until credentials are available.
164
+
165
+ ## Project layout
166
+
167
+ - `src/lairen/`: importable package and Click CLI
168
+ - `tests/core/`: tests for distributed code (`unit`, `integration`, `manual`)
169
+ - `tests/aux/`: tests for repository support content
170
+ - `extern/`: tracked, orphan, and linked-worktree external material
171
+ - `context/`: plans, features, design, summaries, and archived context
172
+ - `docs/`: user-facing documentation source
173
+ - `scripts/`: repository automation outside the installed package
174
+ - `skillset/`: project-specific agent skills
175
+
176
+ ## Security
177
+
178
+ Credential files are stored in plaintext with `0600` permissions, matching the
179
+ native clients. Do not commit `credentials.json`, `registry.json`, or any
180
+ provider home. Rotating OAuth refresh tokens cannot be safely shared by two
181
+ active homes at once; prefer one active home per saved session.
182
+
183
+ ## Limitations
184
+
185
+ - Remote quota queries and OAuth refresh/write-back are not implemented.
186
+ - `cursor` requires Cursor to be closed while the SQLite database is updated.
187
+ - `opencode` covers the Go API-key slot; Console account switching stays with
188
+ the official CLI.
189
+ - `claude`, `commandcode`, `cursor`, and `opencode` are experimental until
190
+ live-credential tests are added.
191
+
192
+ ## License
193
+
194
+ MIT
lairen-0.1.0/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # lairen 来人
2
+
3
+ **Bring the right CLI-agent identity to the right place.**
4
+
5
+ `lairen` is a Python credential registry and deployer for CLI coding agents.
6
+ It stores a provider login once, then materializes it into any target home on
7
+ demand — project-local, holder directories, or throwaway worktrees.
8
+
9
+ Status: `0.1.0`, Pixi-managed, Click-based. Codex and Kimi are the tested
10
+ adapters; the other provider adapters are implemented but remain experimental
11
+ because this project has no live credentials for them yet. Remote quota
12
+ queries and OAuth refresh are the next milestones.
13
+
14
+ ## Why
15
+
16
+ - Keep credentials out of project repos and out of a single global home.
17
+ - Deploy a saved login into an arbitrary provider home.
18
+ - Preserve session-level Kimi identity: `(user_id, device_id)`, not just
19
+ `user_id`, so independent logins of one account stay addressable.
20
+ - Inspect expiry and usage from one command, including machine-readable JSON.
21
+ - Use explicit CLI arguments first; common provider environment variables are
22
+ respected only as fallbacks.
23
+
24
+ ## Requirements
25
+
26
+ - Python `>=3.11` (the Pixi environment pins the 3.11 line)
27
+ - Pixi for the managed development environment
28
+ - Click for the CLI
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pixi install
34
+ pixi run lairen --help
35
+ ```
36
+
37
+ A plain editable install works too:
38
+
39
+ ```bash
40
+ python -m pip install -e .
41
+ lairen --help
42
+ ```
43
+
44
+ ## Quick start
45
+
46
+ Codex and Kimi are the tested paths:
47
+
48
+ ```bash
49
+ # Register a Codex home (reads auth.json, never prints tokens)
50
+ pixi run lairen register codex --home ~/codex-holder/.codex
51
+
52
+ # Register a Kimi home (reads credentials/kimi-code.json)
53
+ pixi run lairen register kimi --home ~/kimi-homes/kimi-2064-1
54
+
55
+ # List saved identities
56
+ pixi run lairen list
57
+
58
+ # Deploy a saved login into a project-local home
59
+ pixi run lairen deploy codex/alice@example.com --home ./my-project/.codex
60
+
61
+ # Usage / expiry report (alias: stats)
62
+ pixi run lairen usage
63
+ pixi run lairen usage kimi/alice--device-id --json
64
+ ```
65
+
66
+ ## Provider surface
67
+
68
+ `lairen` exposes every provider surface that `subswap` supports. Adapters
69
+ marked `tested=no` are implemented against the upstream storage layouts but
70
+ have not been exercised with live credentials here.
71
+
72
+ | Provider | Tested | Env fallback | Default home | Credential | Notes |
73
+ |---|---:|---|---|---|---|
74
+ | `claude` | no | `CLAUDE_CONFIG_DIR` | `~/.claude` | `.credentials.json` | Merges `oauthAccount` metadata on deploy |
75
+ | `codex` | yes | `CODEX_HOME` | `~/.codex` | `auth.json` | ChatGPT OAuth |
76
+ | `commandcode` | no | `COMMANDCODE_HOME` | `~/.commandcode` | `auth.json` | API-key auth |
77
+ | `cursor` | no | `CURSOR_HOME` | `~/.config/Cursor/User/globalStorage` | `state.vscdb` | Desktop SQLite; close Cursor before deploying |
78
+ | `kimi` | yes | `KIMI_CODE_HOME` | `~/.kimi-code` | `credentials/kimi-code.json` | Session identity `user_id--device_id` |
79
+ | `opencode` | no | `OPENCODE_HOME` | `~/.local/share/opencode` | `auth.json` | Go API-key slot; Console accounts use the official CLI |
80
+
81
+ Provider home resolution order:
82
+
83
+ 1. `--home <path>`
84
+ 2. the provider environment variable (`CODEX_HOME`, `KIMI_CODE_HOME`, ...)
85
+ 3. the provider default
86
+
87
+ Deployment always requires an explicit `--home`; `lairen` does not infer a
88
+ target from an environment variable.
89
+
90
+ ## Commands
91
+
92
+ | Command | Purpose |
93
+ |---|---|
94
+ | `lairen register <provider> [--home PATH] [--label NAME]` | Save the live login from a provider home |
95
+ | `lairen list [--json]` | List saved accounts |
96
+ | `lairen show <ref>` | Show one account and its local usage metadata |
97
+ | `lairen deploy <ref> --home PATH` | Write a saved credential into a target home |
98
+ | `lairen usage [ref ...] [--json]` | Expiry/usage statistics (alias: `stats`) |
99
+ | `lairen remove <ref> --yes` | Remove an account from the registry and store |
100
+ | `lairen providers` | Show provider defaults, tested status, and notes |
101
+ | `lairen doctor` | Show resolved paths, account counts, and provider homes |
102
+
103
+ `<ref>` is `provider/id` (for example `codex/alice@example.com` or
104
+ `kimi/alice--<device-id>`). A bare id or label is accepted when it is unique.
105
+
106
+ ## Storage
107
+
108
+ ```
109
+ ~/.config/lairen/
110
+ registry.json # account metadata: provider, id, label, source
111
+ ~/.local/share/lairen/
112
+ credentials.json # credential blobs, mode 0600
113
+ state/snapshots/ # pre-deploy copies of overwritten target files
114
+ ```
115
+
116
+ Set `LAIREN_HOME=/absolute/path` to keep config, data, and state under one
117
+ root. This is a development and testing override, not an input mechanism for
118
+ provider selection.
119
+
120
+ ## Design
121
+
122
+ - **Registry and credentials stay separate.** Metadata is readable; secrets
123
+ live in one `0600` JSON file.
124
+ - **Deployment is atomic.** Target files are written through a temporary file
125
+ and `os.replace`, with a pre-deploy snapshot when the target already exists.
126
+ Provider-specific adapters merge rather than replace where upstream expects
127
+ it (OpenCode Go slot, Cursor `ItemTable`, Claude `oauthAccount`).
128
+ - **Kimi identity is a session.** `user_id` plus `device_id`, joined as
129
+ `user_id--device_id`, so multiple logins of one account remain distinct.
130
+ - **Usage is local-first.** `lairen usage` reports token expiry and refresh
131
+ timestamps from stored blobs. Remote quota endpoints plug in behind
132
+ `Provider.local_usage()` later.
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ pixi run test # core + aux unit/integration suites
138
+ pixi run test-core # tests for src/lairen
139
+ pixi run test-aux # tests for repository support files
140
+ pixi run lint
141
+ pixi run typecheck
142
+ ```
143
+
144
+ Codex and Kimi are the only adapters with live-credential tests. Other
145
+ adapters use fake payloads or remain untested until credentials are available.
146
+
147
+ ## Project layout
148
+
149
+ - `src/lairen/`: importable package and Click CLI
150
+ - `tests/core/`: tests for distributed code (`unit`, `integration`, `manual`)
151
+ - `tests/aux/`: tests for repository support content
152
+ - `extern/`: tracked, orphan, and linked-worktree external material
153
+ - `context/`: plans, features, design, summaries, and archived context
154
+ - `docs/`: user-facing documentation source
155
+ - `scripts/`: repository automation outside the installed package
156
+ - `skillset/`: project-specific agent skills
157
+
158
+ ## Security
159
+
160
+ Credential files are stored in plaintext with `0600` permissions, matching the
161
+ native clients. Do not commit `credentials.json`, `registry.json`, or any
162
+ provider home. Rotating OAuth refresh tokens cannot be safely shared by two
163
+ active homes at once; prefer one active home per saved session.
164
+
165
+ ## Limitations
166
+
167
+ - Remote quota queries and OAuth refresh/write-back are not implemented.
168
+ - `cursor` requires Cursor to be closed while the SQLite database is updated.
169
+ - `opencode` covers the Go API-key slot; Console account switching stays with
170
+ the official CLI.
171
+ - `claude`, `commandcode`, `cursor`, and `opencode` are experimental until
172
+ live-credential tests are added.
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,72 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lairen"
7
+ version = "0.1.0"
8
+ description = "Store CLI-agent credentials and deploy them into target homes."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "igamenovoer" }]
13
+ keywords = ["cli", "credentials", "codex", "kimi", "oauth"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Utilities",
20
+ ]
21
+ dependencies = ["click>=8.1"]
22
+
23
+ [project.scripts]
24
+ lairen = "lairen.cli:main"
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["src"]
28
+
29
+ [tool.pixi.workspace]
30
+ channels = ["conda-forge"]
31
+ platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
32
+
33
+ [tool.pixi.dependencies]
34
+ python = ">=3.11,<3.12"
35
+ click = ">=8.1"
36
+ pytest = ">=8"
37
+ pytest-xdist = ">=3"
38
+ ruff = ">=0.6"
39
+ mypy = ">=1.10"
40
+ python-build = ">=1.2"
41
+
42
+ [tool.pixi.pypi-dependencies]
43
+ lairen = { path = ".", editable = true }
44
+
45
+ [tool.pixi.tasks]
46
+ test-core = "python -m pytest tests/core/unit tests/core/integration"
47
+ test-aux = "python -m pytest tests/aux/unit tests/aux/integration"
48
+ test = { depends-on = ["test-core", "test-aux"] }
49
+ build = "python -m build"
50
+ lint = "ruff check src tests"
51
+ fmt = "ruff format src tests"
52
+ typecheck = "mypy src"
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = [
56
+ "tests/core/unit",
57
+ "tests/core/integration",
58
+ "tests/aux/unit",
59
+ "tests/aux/integration",
60
+ ]
61
+ addopts = "-ra"
62
+
63
+ [tool.ruff]
64
+ line-length = 100
65
+ target-version = "py311"
66
+
67
+ [tool.ruff.lint]
68
+ select = ["E", "F", "I", "UP", "B"]
69
+
70
+ [tool.mypy]
71
+ python_version = "3.11"
72
+ files = ["src"]
lairen-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """lairen 来人 — CLI-agent credential registry and deployer."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from lairen.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()