lairen 来人
Bring the right CLI-agent identity to the right place.
lairen is a Python credential registry and deployer for CLI coding agents.
It stores a provider login once, then materializes it into any target home on
demand — project-local, holder directories, or throwaway worktrees.
Status: 0.1.0, Pixi-managed, Click-based. Codex and Kimi are the tested
adapters; the other provider adapters are implemented but remain experimental
because this project has no live credentials for them yet. Remote quota
queries and OAuth refresh are the next milestones.
Why
- Keep credentials out of project repos and out of a single global home.
- Deploy a saved login into an arbitrary provider home.
- Preserve session-level Kimi identity:
(user_id, device_id), not justuser_id, so independent logins of one account stay addressable. - Inspect expiry and usage from one command, including machine-readable JSON.
- Use explicit CLI arguments first; common provider environment variables are respected only as fallbacks.
Requirements
- Python
>=3.11(the Pixi environment pins the 3.11 line) - Pixi for the managed development environment
- Click for the CLI
Install
pixi install
pixi run lairen --help
A plain editable install works too:
python -m pip install -e .
lairen --help
Quick start
Codex and Kimi are the tested paths:
# Register a Codex home (reads auth.json, never prints tokens)
pixi run lairen register codex --home ~/codex-holder/.codex
# Register a Kimi home (reads credentials/kimi-code.json)
pixi run lairen register kimi --home ~/kimi-homes/kimi-2064-1
# List saved identities
pixi run lairen list
# Deploy a saved login into a project-local home
pixi run lairen deploy codex/alice@example.com --home ./my-project/.codex
# Usage / expiry report (alias: stats)
pixi run lairen usage
pixi run lairen usage kimi/alice--device-id --json
Provider surface
lairen exposes every provider surface that subswap supports. Adapters
marked tested=no are implemented against the upstream storage layouts but
have not been exercised with live credentials here.
| Provider | Tested | Env fallback | Default home | Credential | Notes |
|---|---|---|---|---|---|
claude |
no | CLAUDE_CONFIG_DIR |
~/.claude |
.credentials.json |
Merges oauthAccount metadata on deploy |
codex |
yes | CODEX_HOME |
~/.codex |
auth.json |
ChatGPT OAuth |
commandcode |
no | COMMANDCODE_HOME |
~/.commandcode |
auth.json |
API-key auth |
cursor |
no | CURSOR_HOME |
~/.config/Cursor/User/globalStorage |
state.vscdb |
Desktop SQLite; close Cursor before deploying |
kimi |
yes | KIMI_CODE_HOME |
~/.kimi-code |
credentials/kimi-code.json |
Session identity user_id--device_id |
opencode |
no | OPENCODE_HOME |
~/.local/share/opencode |
auth.json |
Go API-key slot; Console accounts use the official CLI |
Provider home resolution order:
--home <path>- the provider environment variable (
CODEX_HOME,KIMI_CODE_HOME, ...) - the provider default
Deployment always requires an explicit --home; lairen does not infer a
target from an environment variable.
Commands
| Command | Purpose |
|---|---|
lairen register <provider> [--home PATH] [--label NAME] |
Save the live login from a provider home |
lairen list [--json] |
List saved accounts |
lairen show <ref> |
Show one account and its local usage metadata |
lairen deploy <ref> --home PATH |
Write a saved credential into a target home |
lairen usage [ref ...] [--json] |
Expiry/usage statistics (alias: stats) |
lairen remove <ref> --yes |
Remove an account from the registry and store |
lairen providers |
Show provider defaults, tested status, and notes |
lairen doctor |
Show resolved paths, account counts, and provider homes |
<ref> is provider/id (for example codex/alice@example.com or
kimi/alice--<device-id>). A bare id or label is accepted when it is unique.
Storage
~/.config/lairen/
registry.json # account metadata: provider, id, label, source
~/.local/share/lairen/
credentials.json # credential blobs, mode 0600
state/snapshots/ # pre-deploy copies of overwritten target files
Set LAIREN_HOME=/absolute/path to keep config, data, and state under one
root. This is a development and testing override, not an input mechanism for
provider selection.
Design
- Registry and credentials stay separate. Metadata is readable; secrets
live in one
0600JSON file. - Deployment is atomic. Target files are written through a temporary file
and
os.replace, with a pre-deploy snapshot when the target already exists. Provider-specific adapters merge rather than replace where upstream expects it (OpenCode Go slot, CursorItemTable, ClaudeoauthAccount). - Kimi identity is a session.
user_idplusdevice_id, joined asuser_id--device_id, so multiple logins of one account remain distinct. - Usage is local-first.
lairen usagereports token expiry and refresh timestamps from stored blobs. Remote quota endpoints plug in behindProvider.local_usage()later.
Development
pixi run test # core + aux unit/integration suites
pixi run test-core # tests for src/lairen
pixi run test-aux # tests for repository support files
pixi run lint
pixi run typecheck
Codex and Kimi are the only adapters with live-credential tests. Other adapters use fake payloads or remain untested until credentials are available.
Project layout
src/lairen/: importable package and Click CLItests/core/: tests for distributed code (unit,integration,manual)tests/aux/: tests for repository support contentextern/: tracked, orphan, and linked-worktree external materialcontext/: plans, features, design, summaries, and archived contextdocs/: user-facing documentation sourcescripts/: repository automation outside the installed packageskillset/: project-specific agent skills
Security
Credential files are stored in plaintext with 0600 permissions, matching the
native clients. Do not commit credentials.json, registry.json, or any
provider home. Rotating OAuth refresh tokens cannot be safely shared by two
active homes at once; prefer one active home per saved session.
Limitations
- Remote quota queries and OAuth refresh/write-back are not implemented.
cursorrequires Cursor to be closed while the SQLite database is updated.opencodecovers the Go API-key slot; Console account switching stays with the official CLI.claude,commandcode,cursor, andopencodeare experimental until live-credential tests are added.
License
MIT
Metadata
Release files for lairen 0.1.0
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 |
|---|---|---|---|---|
| lairen-0.1.0.tar.gz | 19.2 kB | With provenance | Details for lairen-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lairen-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for lairen-0.1.0-py3-none-any.whl |
Total release size: 41.8 kB
Release files / lairen-0.1.0.tar.gz
| Download URL | lairen-0.1.0.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4dbc429ce8cb11a562afae3352656c49bcddfa1566eeb9dc77e140abdb1aa5e6
|
|
BLAKE2b-256 checksum How to use checksums |
9de27d4758e6df6575b437931aed3d08fee87b9bbecb73589491d48acae8f321
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logRelease files / lairen-0.1.0-py3-none-any.whl
| Download URL | lairen-0.1.0-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
16de60d1a56de90273673bf25cf7c80caf61a5c38854063209ab7597f9681b1b
|
|
BLAKE2b-256 checksum How to use checksums |
74c43b8a86106356e9f3de484a45b62eff695f9a8fb58145b944b0832b638669
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logSecurity for lairen 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for lairen-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logA 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.