Arya CLI
Universal Project Memory Layer for AI Coding Agents
Arya gives AI coding agents (Claude Code, Cursor, Copilot, Cline, Windsurf, Aider, and others) persistent, structured memory about your project — across sessions, across tools, and across crashes — without dumping your entire repo into their context window every time.
Status: Private alpha. APIs, file formats, and command behavior may still change.
Why
AI coding agents are stateless between sessions. Every new conversation starts from zero: no memory of what you decided last week, what's half-finished, or why you rejected an approach. Two common workarounds are both bad:
- Re-scanning the whole repo on every session — slow, expensive, and it can't recover decisions or intent, only current file contents.
- One giant hand-maintained
NOTES.md— drifts out of date the moment nobody remembers to update it.
Arya instead keeps an event-sourced log of what happened in your project (file changes, commands, prompts, decisions), and periodically compiles that log into a compact, structured state.json plus a human-readable memory.md. Any agent — or any human — can read those two files and immediately know: what this project is, what's currently being worked on, what was decided and why, and what to do next.
How it works
- Event-sourced, append-only — every significant action is recorded as an
Eventin~/.arya/projects/<project-id>/events/, never mutated in place. - Global, not local — Arya's data for a project lives under
~/.arya/projects/<hash-of-path>/, not inside the project directory. This is deliberate: an earlier version used a local.arya/symlink into that directory, but a symlink to an absolute path on your machine breaks the moment the repo is cloned somewhere else (a teammate's machine, CI, a Vercel build). Usearya pathto resolve the real location from any context. - Watermark-based dedup — the LLM-backed extractor tracks how much of each transcript/event stream it has already processed, so re-running extraction never reprocesses (or re-bills) the same content.
- Structured state + narrative memory —
state.json(machine-readable: goal, current/next task, tech stack, decisions, completed/in-progress features, file history) andmemory.md(human-readable narrative, generated fromstate.json) are kept in sync. - Agent instructions via
AGENTS.md— onarya init/arya sync, Arya writes (or merges into) anAGENTS.mdin your project root telling any agent how to find and use its memory. GitHub Copilot is additionally supported via.github/copilot-instructions.md.
Architecture at a glance
your-project/
├── AGENTS.md ← agent instructions (how to use Arya)
├── .github/
│ └── copilot-instructions.md
└── (your code, untouched)
~/.arya/projects/<project-id>/ ← the actual memory (NOT in your repo)
├── state.json ← structured project state
├── memory.md ← human-readable narrative, generated from state.json
├── events/ ← append-only event log (source of truth)
├── sessions/ ← per-session records
├── snapshots/ ← point-in-time state snapshots
└── decisions/ ← structured decisions with reasoning/alternatives
<project-id> is a deterministic hash derived from your project's path, so the same project always resolves to the same memory directory on a given machine.
Install
pip install arya-cli
arya --version
Requires Python 3.10 or newer. The command is arya.
Quickstart
cd your-project
arya init # sets up memory + writes AGENTS.md
arya sync # pick up file/git changes since last sync
arya status # see current goal / task / git state
arya summary # compile events into a fresh state.json + memory.md
arya continue # print a handoff prompt for the next agent session
That's it — from here, any agent working in this repo that reads AGENTS.md will know to run arya path to find its memory, and to update it as work progresses.
Gemini API key (optional)
Arya works without any key. Git-based memory, hooks and the daemon do not need one. A Gemini key only turns on LLM decision extraction, which records why things were decided. There is no Arya account and no Arya login to pay for.
arya login # add or replace your key (hidden input, test-run before saving)
arya login --status # show where the key comes from; never prints the key
arya logout # remove the saved key
You bring your own key. Google offers a free Gemini tier, and any usage beyond it is billed by Google to you directly. Check Google's current limits and pricing.
Which key Arya uses, in order:
ARYA_GEMINI_API_KEYenvironment variable (Arya-only override, handy for CI)- The key saved by
arya login(OS keychain, with a0600file fallback) GEMINI_API_KEY, thenGOOGLE_API_KEYenvironment variables
Generic variables rank last so they never override a key you gave Arya on purpose. arya doctor and arya login tell you when one is set but ignored.
.env files are not read. A project's .env belongs to your app, so Arya never picks up keys from it.
Command reference
arya init
Initialize a new Arya project memory layer in the current directory.
--name, -n <str> Name of the project. Defaults to the current directory name.
--desc, -d <str> Short description of the project.
arya sync
Detect the project root, initialize Arya if this project hasn't been seen before, and trigger a summary update silently. This is the command most agents/hooks should call routinely — it's idempotent and safe to run often.
arya summary
Compile recorded event logs into a consolidated ProjectState and print the summary. This is what turns the raw event log into the structured/narrative memory files.
arya status
Display Arya's initialization state, the current project state (goal, current task, next task, tech stack), and Git status (branch, latest commit, changed files) for the current project.
arya path
Print the absolute path to this project's Arya memory directory (~/.arya/projects/<id>/).
--state Print only the path to state.json.
--memory Print only the path to memory.md.
There is no local .arya/ directory or symlink in your project root — use this command (or the equivalent get_project_mem_dir() call from Python) to resolve the real location, from a script, a hook, or an agent's instructions.
arya continue
Output a "continuation prompt" — a compact handoff summarizing project state — for pasting into (or programmatically feeding) the next agent session.
arya task done
Complete the current task and promote the next one.
--next <str> Description of the next task to pick up.
arya sync-rules (via arya init / arya sync internally)
Agent rule files (AGENTS.md, .github/copilot-instructions.md) are synced automatically as part of init/sync — merging any existing home-directory template and project-local content with Arya's current default instructions, without duplicating or losing user-authored content.
arya shell install / arya shell uninstall
Install or uninstall Arya's shell hooks into your shell profile (.zshrc/.bashrc/etc.), so arya sync can be triggered automatically around your normal workflow. Writes are atomic (temp file + rename) to avoid corrupting your shell config if the write is interrupted.
arya daemon run / arya daemon stop
Manage the background filesystem-watcher daemon that can record events as you work, without needing every action to go through the CLI explicitly.
arya daemon stop --all Stop every known daemon, not just the one for the current directory.
arya doctor
Run diagnostic checks on the Arya setup (dependencies, config, permissions) and report problems.
arya version
Print Arya's version details.
arya update
Update Arya to the latest version automatically.
Design principles
- Memory lives outside your repo. Nothing Arya generates for its own bookkeeping needs to be committed, and the one thing that is written into your repo (
AGENTS.md) is plain, readable Markdown — not opaque state. - Append-only, never destructive. The event log is never rewritten in place;
state.json/memory.mdare derived views, always safely regenerable from events. - Cross-machine safe. Nothing in the repo should ever hardcode a path that only exists on one machine (this is actively enforced — see
arya pathabove). - Minimal repo footprint. Arya writes to exactly one rule file (
AGENTS.md) plus a Copilot-specific file, not a dozen tool-specific variants.
Development
git clone https://github.com/CheerathAniketh/arya-cli
cd arya-cli
pip install -e ".[dev]"
python -m pytest tests/ -v
Fresh-init smoke test
rm -rf /tmp/test-arya && mkdir /tmp/test-arya && cd /tmp/test-arya
git init
arya init
ls -la # should show only .git, .gitignore, AGENTS.md, .github
arya path # should resolve to ~/.arya/projects/<id>/
Contributing
This project is in private alpha and not yet accepting external contributions in a structured way. If you have access to the repo, open a PR against main; please include or update tests for any behavioral change, and run the full test suite before submitting.
License
Proprietary — all rights reserved, see LICENSE. This project incorporates MIT-licensed third-party code; see THRID_PARTY_NOTICES.md for details.
Contact
Founder: Aniketh Cheerath Company: Arya Labs GitHub: github.com/CheerathAniketh/arya-cli
Metadata
Release files for arya-cli 2.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 | |
|---|---|---|---|
| arya_cli-2.1.0.tar.gz | 92.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arya_cli-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 174.4 kB
Release files / arya_cli-2.1.0.tar.gz
| Download URL | arya_cli-2.1.0.tar.gz |
|---|---|
| Size | 92.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
236decf863d6ea22ade67900ef0bef3e0d84113a4430cb85a54ae88cf5303b6b
|
|
BLAKE2b-256 checksum How to use checksums |
6ca8f4ff8431585e1e6cd60f6dd60ae9b5047e2dfc62c641ebf0876a7c46805b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / arya_cli-2.1.0-py3-none-any.whl
| Download URL | arya_cli-2.1.0-py3-none-any.whl |
|---|---|
| Size | 82.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b905f6224742118e309cba9e68219721b69ef959ca36fab8a99dd638eeb5718
|
|
BLAKE2b-256 checksum How to use checksums |
c1cebfc7e212c0335b6f6a9d3b0af15c17a22cd76e4fb8b3d0564255e36ef80c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|