chat-memory-sync 0.1.3__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.
- chat_memory_sync-0.1.3/.gitignore +8 -0
- chat_memory_sync-0.1.3/CODE_OF_CONDUCT.md +36 -0
- chat_memory_sync-0.1.3/CONTRIBUTING.md +123 -0
- chat_memory_sync-0.1.3/LICENSE +21 -0
- chat_memory_sync-0.1.3/PKG-INFO +204 -0
- chat_memory_sync-0.1.3/README.md +183 -0
- chat_memory_sync-0.1.3/ROADMAP.md +48 -0
- chat_memory_sync-0.1.3/docs/agent-integration.md +68 -0
- chat_memory_sync-0.1.3/pyproject.toml +42 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/__init__.py +2 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/__main__.py +5 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/cli.py +62 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/cmlib.py +76 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/install.py +221 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/recall.py +231 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/run.py +92 -0
- chat_memory_sync-0.1.3/src/chat_memory_sync/sync.py +938 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and maintainers pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body size,
|
|
7
|
+
visible or invisible disability, ethnicity, sex characteristics, gender identity and
|
|
8
|
+
expression, level of experience, education, socio-economic status, nationality, personal
|
|
9
|
+
appearance, race, religion, or sexual identity and orientation.
|
|
10
|
+
|
|
11
|
+
## Our standards
|
|
12
|
+
|
|
13
|
+
Examples of behavior that contributes to a positive environment:
|
|
14
|
+
|
|
15
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
16
|
+
- Giving and gracefully accepting constructive feedback
|
|
17
|
+
- Focusing on what is best for the community
|
|
18
|
+
- Showing empathy toward other community members
|
|
19
|
+
|
|
20
|
+
Unacceptable behavior includes:
|
|
21
|
+
|
|
22
|
+
- Harassment, insulting/derogatory comments, and personal or political attacks
|
|
23
|
+
- Public or private harassment
|
|
24
|
+
- Publishing others' private information without explicit permission
|
|
25
|
+
- Other conduct which could reasonably be considered inappropriate
|
|
26
|
+
|
|
27
|
+
## Enforcement
|
|
28
|
+
|
|
29
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to
|
|
30
|
+
the maintainers via a GitHub issue or direct contact. All complaints will be reviewed
|
|
31
|
+
and investigated promptly and fairly. Maintainers are obligated to respect the privacy
|
|
32
|
+
and security of the reporter of any incident.
|
|
33
|
+
|
|
34
|
+
This Code of Conduct is adapted from the [Contributor Covenant][cc], version 2.1.
|
|
35
|
+
|
|
36
|
+
[cc]: https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Contributing to chat-memory-sync
|
|
2
|
+
|
|
3
|
+
Thanks for helping! The whole point of this project is that **no one person can keep up
|
|
4
|
+
with every AI coding harness** β so adapters are community-driven. Most contributions
|
|
5
|
+
are a single new adapter function.
|
|
6
|
+
|
|
7
|
+
- π **Found a bug?** Open an issue.
|
|
8
|
+
- π **Want a harness supported?** Open a *Harness request* issue (even if you can't code
|
|
9
|
+
it β the storage-location details are the hard part, and you can help gather them).
|
|
10
|
+
- π **Adding/βfixing an adapter?** Read ["Adding a harness"](#adding-a-harness) below.
|
|
11
|
+
|
|
12
|
+
By contributing you agree your work is licensed under the repo's [MIT License](LICENSE)
|
|
13
|
+
and that you follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
14
|
+
|
|
15
|
+
## Project shape
|
|
16
|
+
|
|
17
|
+
| File | Role |
|
|
18
|
+
| ---- | ---- |
|
|
19
|
+
| `cmlib.py` | config + paths (data dir, state dir, client) |
|
|
20
|
+
| `sync.py` | **harness adapters** + Markdown writer + index builder |
|
|
21
|
+
| `run.py` | runner: git pull β sync β commit β push |
|
|
22
|
+
| `recall.py` | full-text search |
|
|
23
|
+
| `install.py` | installer + schedulers |
|
|
24
|
+
|
|
25
|
+
No dependencies beyond the Python standard library (`sqlite3`, `json`, `glob`, β¦). Please
|
|
26
|
+
keep it that way β this has to run anywhere with just `python3` + `git`.
|
|
27
|
+
|
|
28
|
+
## Adding a harness
|
|
29
|
+
|
|
30
|
+
A harness adapter is a generator in `sync.py` that reads that tool's native chat store
|
|
31
|
+
and `yield`s normalized chat dicts. Everything else (writing Markdown, project grouping,
|
|
32
|
+
client tagging, indexing, syncing) is handled for you.
|
|
33
|
+
|
|
34
|
+
### 1. Find where the harness stores chats
|
|
35
|
+
|
|
36
|
+
This is usually the biggest part. Look under:
|
|
37
|
+
|
|
38
|
+
- `~/.<tool>/`, `~/.config/<tool>/`, `~/.local/share/<tool>/`
|
|
39
|
+
- macOS: `~/Library/Application Support/<Tool>/`
|
|
40
|
+
- VS Code forks: `β¦/<Tool>/User/globalStorage/state.vscdb` + `workspaceStorage/`
|
|
41
|
+
|
|
42
|
+
Chats are usually **JSONL** (one event/message per line), a **SQLite DB**, or per-session
|
|
43
|
+
**JSON** files. Record the exact path and format in your PR/issue so others can verify.
|
|
44
|
+
|
|
45
|
+
### 2. Write the adapter
|
|
46
|
+
|
|
47
|
+
Yield one dict per conversation:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
{
|
|
51
|
+
"harness": "myharness", # short, kebab-case; becomes a folder name
|
|
52
|
+
"id": "<stable session id>", # unique per chat (used in the filename)
|
|
53
|
+
"project": canonical_project(cwd), # use the helper; maps cwd β repo name
|
|
54
|
+
"source_path": cwd, # absolute path the chat ran in (may be "")
|
|
55
|
+
"title": "<short title>", # first user line is fine if none stored
|
|
56
|
+
"created": <epoch_ms>, # use toms(...) to normalize ISO/sec/ms
|
|
57
|
+
"updated": <epoch_ms>,
|
|
58
|
+
"models": {"model-name"}, # set(); may be empty
|
|
59
|
+
"messages": [
|
|
60
|
+
{
|
|
61
|
+
"role": "user" | "assistant",
|
|
62
|
+
"model": "", # optional, per-message
|
|
63
|
+
"thinking": "", # reasoning text, optional
|
|
64
|
+
"text": "...", # main content
|
|
65
|
+
"tools": [ # tool calls, optional
|
|
66
|
+
{"name": "Shell", "args": {...} | "raw", "result": "..." | None},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Then register it:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
ADAPTERS = [cursor_chats, ..., myharness_chats]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Guidelines:
|
|
80
|
+
|
|
81
|
+
- **Skip empties** β don't yield chats with no renderable messages.
|
|
82
|
+
- **OS-aware paths** β branch on `platform.system()` or probe candidate paths with
|
|
83
|
+
`_first_existing(...)`; degrade gracefully (just `return` if the store isn't present).
|
|
84
|
+
- **Don't crash the run** β wrap risky parsing in `try/except`; a bad file should skip,
|
|
85
|
+
not abort. (Adapters are already isolated, but be defensive.)
|
|
86
|
+
- **Timestamps** via `toms(...)`; **project** via `canonical_project(...)`.
|
|
87
|
+
- **Truncate** giant tool args/results if needed (the writer already caps them).
|
|
88
|
+
|
|
89
|
+
### 3. Test it
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# point at a throwaway data dir so you don't touch your real one
|
|
93
|
+
export CHAT_MEMORY_DATA_DIR=/tmp/cm-test CHAT_MEMORY_HOME=/tmp/cm-home
|
|
94
|
+
python3 sync.py
|
|
95
|
+
ls -R /tmp/cm-test/projects # inspect the generated Markdown
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Check: titles are sensible, messages are ordered, projects resolve, no tracebacks.
|
|
99
|
+
Run twice β the second run should report everything `unchanged` (idempotent).
|
|
100
|
+
|
|
101
|
+
### 4. Open a PR
|
|
102
|
+
|
|
103
|
+
Include:
|
|
104
|
+
|
|
105
|
+
- [ ] the adapter + `ADAPTERS` entry
|
|
106
|
+
- [ ] the harness's storage path/format in the PR description
|
|
107
|
+
- [ ] a row added to the **Harness support** table in `README.md`
|
|
108
|
+
- [ ] (if the format is non-obvious) a short note in the PR on how you decoded it
|
|
109
|
+
|
|
110
|
+
## Style
|
|
111
|
+
|
|
112
|
+
- Standard library only, Python 3.8+.
|
|
113
|
+
- Match the surrounding style (no formatter enforced; keep it clean and readable).
|
|
114
|
+
- Keep adapters self-contained and defensive.
|
|
115
|
+
|
|
116
|
+
## Not a coder? Still useful.
|
|
117
|
+
|
|
118
|
+
Open a **Harness request** issue with:
|
|
119
|
+
- the tool name + link
|
|
120
|
+
- where it stores chats on your OS (paths)
|
|
121
|
+
- one small (redacted) example file
|
|
122
|
+
|
|
123
|
+
That alone makes it easy for someone else to write the adapter.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aayush Gautam
|
|
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.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: chat-memory-sync
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Unified, searchable memory bank of your AI coding chats across Cursor, Claude Code, OpenCode, Codex, Gemini CLI, Pi and more β synced across machines.
|
|
5
|
+
Project-URL: Homepage, https://github.com/insideaayush/chat-memory-sync
|
|
6
|
+
Project-URL: Repository, https://github.com/insideaayush/chat-memory-sync
|
|
7
|
+
Project-URL: Issues, https://github.com/insideaayush/chat-memory-sync/issues
|
|
8
|
+
Author: Aayush Gautam
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,chat-history,claude-code,cli,codex,cursor,developer-tools,gemini,memory,opencode
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# chat-memory-sync
|
|
23
|
+
|
|
24
|
+
Turn your AI coding assistants' chat history into a unified, searchable **memory bank**.
|
|
25
|
+
|
|
26
|
+
`chat-memory-sync` exports conversations from every AI coding harness you use into one
|
|
27
|
+
project-organized Markdown repo, syncs it across all your machines via git, and gives
|
|
28
|
+
agents a `recall` command to look up relevant past chats β so an assistant working on a
|
|
29
|
+
feature can learn from what you discussed about it in a *different* tool weeks ago.
|
|
30
|
+
|
|
31
|
+
- **Many harnesses** β one place: Cursor, Cursor Agent CLI, Claude Code, OpenCode, Pi,
|
|
32
|
+
Codex, Gemini CLI. (Antigravity is stubbed β opaque local store.)
|
|
33
|
+
- **Project-organized** so memory is scoped to the repo you're in (worktrees/sub-apps
|
|
34
|
+
merged into the parent repo).
|
|
35
|
+
- **Multi-machine** via a *client* dimension (mac / pc / cloud) β each machine syncs
|
|
36
|
+
independently; no machine ever clobbers another's chats.
|
|
37
|
+
- **Private by design**: the tooling is open source; your chats live in a **separate
|
|
38
|
+
private data repo** you own.
|
|
39
|
+
- **Incremental & idempotent**: only changed chats are rewritten; updates to old chats
|
|
40
|
+
are picked up; deleted chats are pruned.
|
|
41
|
+
|
|
42
|
+
## How it's split
|
|
43
|
+
|
|
44
|
+
| Repo | Visibility | Contents |
|
|
45
|
+
| ---- | ---------- | -------- |
|
|
46
|
+
| **chat-memory-sync** (this) | public | the scripts + installer + background job |
|
|
47
|
+
| **your data repo** (e.g. `chat-memory`) | **private** | `projects/` + `INDEX.md` (your chats) |
|
|
48
|
+
|
|
49
|
+
The tool reads `~/.config/chat-memory/config.json` for your data repo's location.
|
|
50
|
+
Machine-local state (search index, client name, logs) also lives under
|
|
51
|
+
`~/.config/chat-memory/` β never inside the data repo.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
Get the `chat-memory` CLI (pure Python, no dependencies):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Homebrew
|
|
59
|
+
brew install insideaayush/tap/chat-memory-sync
|
|
60
|
+
|
|
61
|
+
# pipx (recommended for pip users)
|
|
62
|
+
pipx install chat-memory-sync
|
|
63
|
+
|
|
64
|
+
# pip
|
|
65
|
+
pip install --user chat-memory-sync
|
|
66
|
+
|
|
67
|
+
# from source
|
|
68
|
+
git clone https://github.com/insideaayush/chat-memory-sync.git
|
|
69
|
+
pip install ./chat-memory-sync
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then set it up on this machine:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
chat-memory install \
|
|
76
|
+
--data-remote git@github.com:<you>/chat-memory.git \
|
|
77
|
+
--client "macbook-air" \
|
|
78
|
+
--time 21:00
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
That one command: writes config, clones (or inits) your private data repo, runs the
|
|
82
|
+
first sync, registers a **daily background job** for your OS, and ensures the `recall`
|
|
83
|
+
command is available.
|
|
84
|
+
|
|
85
|
+
### Commands
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
chat-memory install # config + data repo + daily job + recall
|
|
89
|
+
chat-memory sync # pull -> export -> commit -> push (what the job runs)
|
|
90
|
+
chat-memory export # export only (no git)
|
|
91
|
+
chat-memory recall β¦ # search past chats (also the standalone `recall` command)
|
|
92
|
+
chat-memory doctor # config, detected harnesses, chat counts
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| OS | Background job |
|
|
96
|
+
| -- | -------------- |
|
|
97
|
+
| macOS | launchd LaunchAgent `com.user.chat-memory-sync` |
|
|
98
|
+
| Windows | Task Scheduler task `ChatMemorySync` |
|
|
99
|
+
| Linux | systemd **user** timer (falls back to cron) |
|
|
100
|
+
|
|
101
|
+
Only needs `git` + `python3`. Re-running `chat-memory install` is safe.
|
|
102
|
+
|
|
103
|
+
> No private data repo yet? Create an empty **private** repo on your git host first,
|
|
104
|
+
> then pass its URL as `--data-remote`. Or omit `--data-remote` to keep it local-only.
|
|
105
|
+
|
|
106
|
+
Releases are automated (PyPI + Homebrew) β see [RELEASING.md](RELEASING.md).
|
|
107
|
+
|
|
108
|
+
## Finding relevant chats β `recall`
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
cd ~/code/my-project
|
|
112
|
+
recall "auth token refresh" # ranked (BM25) hits for THIS repo, with snippets
|
|
113
|
+
recall "rate limiting" --all # every project
|
|
114
|
+
recall "payout bug" --harness cursor --since 2026-09 -k 10
|
|
115
|
+
recall "..." --full # just file paths (pipe-friendly)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Auto-scopes to the project you're in (via CWD), builds a local SQLite full-text index
|
|
119
|
+
that rebuilds when chats change. The index is machine-local (`~/.config/chat-memory/
|
|
120
|
+
index.db`), never synced.
|
|
121
|
+
|
|
122
|
+
**For agents:** run `recall "<topic>"` from the repo you're working in, read the top
|
|
123
|
+
hits, then open those `.md` files for full context. Add a line to your project's
|
|
124
|
+
`AGENTS.md`/`CLAUDE.md` so assistants do this automatically.
|
|
125
|
+
|
|
126
|
+
## Multi-machine
|
|
127
|
+
|
|
128
|
+
Every machine runs the same job independently. Each run:
|
|
129
|
+
|
|
130
|
+
1. `git pull --rebase` the data repo (other machines' chats)
|
|
131
|
+
2. export **this** machine's chats (tagged with its `client` id)
|
|
132
|
+
3. prune only **this client's** deleted chats
|
|
133
|
+
4. rebuild indexes from the union, `git commit`, `git push`
|
|
134
|
+
|
|
135
|
+
Set a machine's name with `--client` (default: hostname), or
|
|
136
|
+
`CHAT_MEMORY_CLIENT=cloud-vm`.
|
|
137
|
+
|
|
138
|
+
## Harness support
|
|
139
|
+
|
|
140
|
+
Legend: β
supported Β· π§ͺ partial Β· π stub/planned Β· β wanted (help us!)
|
|
141
|
+
|
|
142
|
+
| Harness | Status | Source | Notes |
|
|
143
|
+
| ------- | :----: | ------ | ----- |
|
|
144
|
+
| Cursor | β
| `β¦/Cursor/User/globalStorage/state.vscdb` (OS-aware) | IDE chats / composers |
|
|
145
|
+
| Cursor Agent CLI | β
| `~/.cursor/acp-sessions/<uuid>/store.db` + `meta.json` | blob store |
|
|
146
|
+
| Claude Code | β
| `~/.claude/projects/<enc>/<uuid>.jsonl` | |
|
|
147
|
+
| OpenCode | β
| `~/.local/share/opencode/opencode.db` | |
|
|
148
|
+
| Pi | β
| `~/.pi/agent/sessions/<enc>/<ts>_<id>.jsonl` | |
|
|
149
|
+
| Codex | β
| `~/.codex/sessions/**/rollout-*.jsonl` (+ `archived_sessions/`) | |
|
|
150
|
+
| Gemini CLI | π§ͺ | `~/.gemini/tmp/<key>/checkpoint-*.json` (+ `logs.json`) | full via checkpoints; else prompts only |
|
|
151
|
+
| Antigravity | π | opaque protobuf LevelDB (`shared_proto_db`) | needs a decoder |
|
|
152
|
+
| Windsurf, Aider, Cline, Continue, Zed, Copilot Chat, β¦ | β | β | [request](../../issues/new?template=harness_request.md) or PR |
|
|
153
|
+
|
|
154
|
+
Can't track every tool in the world β **adapters are community-driven**. Adding one is
|
|
155
|
+
usually a single function; see **[CONTRIBUTING.md](CONTRIBUTING.md)** and the
|
|
156
|
+
**[ROADMAP](ROADMAP.md)**.
|
|
157
|
+
|
|
158
|
+
## How it works
|
|
159
|
+
|
|
160
|
+
| File | Role |
|
|
161
|
+
| ---- | ---- |
|
|
162
|
+
| `cmlib.py` | config + paths (data dir, state dir, client) |
|
|
163
|
+
| `sync.py` | export every harness's native store β Markdown; rebuild indexes |
|
|
164
|
+
| `run.py` | runner: `git pull β sync β commit β push` (+ warms recall index) |
|
|
165
|
+
| `recall.py` | full-text (BM25) search, auto-scoped to the current project |
|
|
166
|
+
| `install.py` | one-command setup + scheduler + `recall` command |
|
|
167
|
+
|
|
168
|
+
### Adding a harness
|
|
169
|
+
|
|
170
|
+
Adapters are community-driven β adding one is usually a single generator function in
|
|
171
|
+
`sync.py`. See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the full contract and the
|
|
172
|
+
support table above.
|
|
173
|
+
|
|
174
|
+
## Config reference
|
|
175
|
+
|
|
176
|
+
`~/.config/chat-memory/config.json`:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{ "data_dir": "/Users/you/chat-memory", "client": "macbook-air" }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Env overrides: `CHAT_MEMORY_DATA_DIR`, `CHAT_MEMORY_CLIENT`, `CHAT_MEMORY_HOME`.
|
|
183
|
+
|
|
184
|
+
## Give your agents memory
|
|
185
|
+
|
|
186
|
+
Any assistant with shell access can query all your past chats via `recall`. Add a short
|
|
187
|
+
snippet to your project's `AGENTS.md` / `CLAUDE.md` / `GEMINI.md` so assistants do it
|
|
188
|
+
automatically β copy-paste blocks per harness are in
|
|
189
|
+
**[docs/agent-integration.md](docs/agent-integration.md)**.
|
|
190
|
+
|
|
191
|
+
## Contributing & community
|
|
192
|
+
|
|
193
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** β add a harness adapter (the main ask) or fix a bug.
|
|
194
|
+
- **[ROADMAP.md](ROADMAP.md)** β planned work; pick anything up.
|
|
195
|
+
- **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)**.
|
|
196
|
+
- Not a coder? A [harness request](../../issues/new?template=harness_request.md) with
|
|
197
|
+
storage paths + a redacted sample is hugely useful.
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT β see [LICENSE](LICENSE). Contributions accepted under the same license.
|
|
202
|
+
|
|
203
|
+
> The tooling is open source; **your chats stay in your own private data repo.**
|
|
204
|
+
> This project reads local chat stores and writes Markdown β review the code before running it.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# chat-memory-sync
|
|
2
|
+
|
|
3
|
+
Turn your AI coding assistants' chat history into a unified, searchable **memory bank**.
|
|
4
|
+
|
|
5
|
+
`chat-memory-sync` exports conversations from every AI coding harness you use into one
|
|
6
|
+
project-organized Markdown repo, syncs it across all your machines via git, and gives
|
|
7
|
+
agents a `recall` command to look up relevant past chats β so an assistant working on a
|
|
8
|
+
feature can learn from what you discussed about it in a *different* tool weeks ago.
|
|
9
|
+
|
|
10
|
+
- **Many harnesses** β one place: Cursor, Cursor Agent CLI, Claude Code, OpenCode, Pi,
|
|
11
|
+
Codex, Gemini CLI. (Antigravity is stubbed β opaque local store.)
|
|
12
|
+
- **Project-organized** so memory is scoped to the repo you're in (worktrees/sub-apps
|
|
13
|
+
merged into the parent repo).
|
|
14
|
+
- **Multi-machine** via a *client* dimension (mac / pc / cloud) β each machine syncs
|
|
15
|
+
independently; no machine ever clobbers another's chats.
|
|
16
|
+
- **Private by design**: the tooling is open source; your chats live in a **separate
|
|
17
|
+
private data repo** you own.
|
|
18
|
+
- **Incremental & idempotent**: only changed chats are rewritten; updates to old chats
|
|
19
|
+
are picked up; deleted chats are pruned.
|
|
20
|
+
|
|
21
|
+
## How it's split
|
|
22
|
+
|
|
23
|
+
| Repo | Visibility | Contents |
|
|
24
|
+
| ---- | ---------- | -------- |
|
|
25
|
+
| **chat-memory-sync** (this) | public | the scripts + installer + background job |
|
|
26
|
+
| **your data repo** (e.g. `chat-memory`) | **private** | `projects/` + `INDEX.md` (your chats) |
|
|
27
|
+
|
|
28
|
+
The tool reads `~/.config/chat-memory/config.json` for your data repo's location.
|
|
29
|
+
Machine-local state (search index, client name, logs) also lives under
|
|
30
|
+
`~/.config/chat-memory/` β never inside the data repo.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
Get the `chat-memory` CLI (pure Python, no dependencies):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Homebrew
|
|
38
|
+
brew install insideaayush/tap/chat-memory-sync
|
|
39
|
+
|
|
40
|
+
# pipx (recommended for pip users)
|
|
41
|
+
pipx install chat-memory-sync
|
|
42
|
+
|
|
43
|
+
# pip
|
|
44
|
+
pip install --user chat-memory-sync
|
|
45
|
+
|
|
46
|
+
# from source
|
|
47
|
+
git clone https://github.com/insideaayush/chat-memory-sync.git
|
|
48
|
+
pip install ./chat-memory-sync
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then set it up on this machine:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
chat-memory install \
|
|
55
|
+
--data-remote git@github.com:<you>/chat-memory.git \
|
|
56
|
+
--client "macbook-air" \
|
|
57
|
+
--time 21:00
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
That one command: writes config, clones (or inits) your private data repo, runs the
|
|
61
|
+
first sync, registers a **daily background job** for your OS, and ensures the `recall`
|
|
62
|
+
command is available.
|
|
63
|
+
|
|
64
|
+
### Commands
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
chat-memory install # config + data repo + daily job + recall
|
|
68
|
+
chat-memory sync # pull -> export -> commit -> push (what the job runs)
|
|
69
|
+
chat-memory export # export only (no git)
|
|
70
|
+
chat-memory recall β¦ # search past chats (also the standalone `recall` command)
|
|
71
|
+
chat-memory doctor # config, detected harnesses, chat counts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
| OS | Background job |
|
|
75
|
+
| -- | -------------- |
|
|
76
|
+
| macOS | launchd LaunchAgent `com.user.chat-memory-sync` |
|
|
77
|
+
| Windows | Task Scheduler task `ChatMemorySync` |
|
|
78
|
+
| Linux | systemd **user** timer (falls back to cron) |
|
|
79
|
+
|
|
80
|
+
Only needs `git` + `python3`. Re-running `chat-memory install` is safe.
|
|
81
|
+
|
|
82
|
+
> No private data repo yet? Create an empty **private** repo on your git host first,
|
|
83
|
+
> then pass its URL as `--data-remote`. Or omit `--data-remote` to keep it local-only.
|
|
84
|
+
|
|
85
|
+
Releases are automated (PyPI + Homebrew) β see [RELEASING.md](RELEASING.md).
|
|
86
|
+
|
|
87
|
+
## Finding relevant chats β `recall`
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
cd ~/code/my-project
|
|
91
|
+
recall "auth token refresh" # ranked (BM25) hits for THIS repo, with snippets
|
|
92
|
+
recall "rate limiting" --all # every project
|
|
93
|
+
recall "payout bug" --harness cursor --since 2026-09 -k 10
|
|
94
|
+
recall "..." --full # just file paths (pipe-friendly)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Auto-scopes to the project you're in (via CWD), builds a local SQLite full-text index
|
|
98
|
+
that rebuilds when chats change. The index is machine-local (`~/.config/chat-memory/
|
|
99
|
+
index.db`), never synced.
|
|
100
|
+
|
|
101
|
+
**For agents:** run `recall "<topic>"` from the repo you're working in, read the top
|
|
102
|
+
hits, then open those `.md` files for full context. Add a line to your project's
|
|
103
|
+
`AGENTS.md`/`CLAUDE.md` so assistants do this automatically.
|
|
104
|
+
|
|
105
|
+
## Multi-machine
|
|
106
|
+
|
|
107
|
+
Every machine runs the same job independently. Each run:
|
|
108
|
+
|
|
109
|
+
1. `git pull --rebase` the data repo (other machines' chats)
|
|
110
|
+
2. export **this** machine's chats (tagged with its `client` id)
|
|
111
|
+
3. prune only **this client's** deleted chats
|
|
112
|
+
4. rebuild indexes from the union, `git commit`, `git push`
|
|
113
|
+
|
|
114
|
+
Set a machine's name with `--client` (default: hostname), or
|
|
115
|
+
`CHAT_MEMORY_CLIENT=cloud-vm`.
|
|
116
|
+
|
|
117
|
+
## Harness support
|
|
118
|
+
|
|
119
|
+
Legend: β
supported Β· π§ͺ partial Β· π stub/planned Β· β wanted (help us!)
|
|
120
|
+
|
|
121
|
+
| Harness | Status | Source | Notes |
|
|
122
|
+
| ------- | :----: | ------ | ----- |
|
|
123
|
+
| Cursor | β
| `β¦/Cursor/User/globalStorage/state.vscdb` (OS-aware) | IDE chats / composers |
|
|
124
|
+
| Cursor Agent CLI | β
| `~/.cursor/acp-sessions/<uuid>/store.db` + `meta.json` | blob store |
|
|
125
|
+
| Claude Code | β
| `~/.claude/projects/<enc>/<uuid>.jsonl` | |
|
|
126
|
+
| OpenCode | β
| `~/.local/share/opencode/opencode.db` | |
|
|
127
|
+
| Pi | β
| `~/.pi/agent/sessions/<enc>/<ts>_<id>.jsonl` | |
|
|
128
|
+
| Codex | β
| `~/.codex/sessions/**/rollout-*.jsonl` (+ `archived_sessions/`) | |
|
|
129
|
+
| Gemini CLI | π§ͺ | `~/.gemini/tmp/<key>/checkpoint-*.json` (+ `logs.json`) | full via checkpoints; else prompts only |
|
|
130
|
+
| Antigravity | π | opaque protobuf LevelDB (`shared_proto_db`) | needs a decoder |
|
|
131
|
+
| Windsurf, Aider, Cline, Continue, Zed, Copilot Chat, β¦ | β | β | [request](../../issues/new?template=harness_request.md) or PR |
|
|
132
|
+
|
|
133
|
+
Can't track every tool in the world β **adapters are community-driven**. Adding one is
|
|
134
|
+
usually a single function; see **[CONTRIBUTING.md](CONTRIBUTING.md)** and the
|
|
135
|
+
**[ROADMAP](ROADMAP.md)**.
|
|
136
|
+
|
|
137
|
+
## How it works
|
|
138
|
+
|
|
139
|
+
| File | Role |
|
|
140
|
+
| ---- | ---- |
|
|
141
|
+
| `cmlib.py` | config + paths (data dir, state dir, client) |
|
|
142
|
+
| `sync.py` | export every harness's native store β Markdown; rebuild indexes |
|
|
143
|
+
| `run.py` | runner: `git pull β sync β commit β push` (+ warms recall index) |
|
|
144
|
+
| `recall.py` | full-text (BM25) search, auto-scoped to the current project |
|
|
145
|
+
| `install.py` | one-command setup + scheduler + `recall` command |
|
|
146
|
+
|
|
147
|
+
### Adding a harness
|
|
148
|
+
|
|
149
|
+
Adapters are community-driven β adding one is usually a single generator function in
|
|
150
|
+
`sync.py`. See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the full contract and the
|
|
151
|
+
support table above.
|
|
152
|
+
|
|
153
|
+
## Config reference
|
|
154
|
+
|
|
155
|
+
`~/.config/chat-memory/config.json`:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{ "data_dir": "/Users/you/chat-memory", "client": "macbook-air" }
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Env overrides: `CHAT_MEMORY_DATA_DIR`, `CHAT_MEMORY_CLIENT`, `CHAT_MEMORY_HOME`.
|
|
162
|
+
|
|
163
|
+
## Give your agents memory
|
|
164
|
+
|
|
165
|
+
Any assistant with shell access can query all your past chats via `recall`. Add a short
|
|
166
|
+
snippet to your project's `AGENTS.md` / `CLAUDE.md` / `GEMINI.md` so assistants do it
|
|
167
|
+
automatically β copy-paste blocks per harness are in
|
|
168
|
+
**[docs/agent-integration.md](docs/agent-integration.md)**.
|
|
169
|
+
|
|
170
|
+
## Contributing & community
|
|
171
|
+
|
|
172
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** β add a harness adapter (the main ask) or fix a bug.
|
|
173
|
+
- **[ROADMAP.md](ROADMAP.md)** β planned work; pick anything up.
|
|
174
|
+
- **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)**.
|
|
175
|
+
- Not a coder? A [harness request](../../issues/new?template=harness_request.md) with
|
|
176
|
+
storage paths + a redacted sample is hugely useful.
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT β see [LICENSE](LICENSE). Contributions accepted under the same license.
|
|
181
|
+
|
|
182
|
+
> The tooling is open source; **your chats stay in your own private data repo.**
|
|
183
|
+
> This project reads local chat stores and writes Markdown β review the code before running it.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
Ideas and planned work. Contributions welcome β pick anything, or open an issue to
|
|
4
|
+
propose something. Ordering is rough priority, not a commitment.
|
|
5
|
+
|
|
6
|
+
## Harness coverage
|
|
7
|
+
|
|
8
|
+
- [ ] **Antigravity** β decode the Cascade protobuf LevelDB (`shared_proto_db`).
|
|
9
|
+
- [ ] **Windsurf** (Cascade) β same family; likely similar store.
|
|
10
|
+
- [ ] **Aider** β `.aider.chat.history.md` / input history.
|
|
11
|
+
- [ ] **Cline / Roo Code** (VS Code) β task history in global/workspace storage.
|
|
12
|
+
- [ ] **Continue.dev** β `~/.continue/sessions/`.
|
|
13
|
+
- [ ] **Zed** β assistant/agent threads.
|
|
14
|
+
- [ ] **GitHub Copilot Chat** β VS Code chat session JSON.
|
|
15
|
+
- [ ] **Amp**, **Goose**, **Cody**, **Windmill**, β¦ β PRs welcome.
|
|
16
|
+
|
|
17
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md#adding-a-harness) for the adapter contract.
|
|
18
|
+
|
|
19
|
+
## Retrieval & memory quality
|
|
20
|
+
|
|
21
|
+
- [ ] **MCP server** exposing `recall` as a tool, so MCP-capable harnesses can query
|
|
22
|
+
memory natively (no shell needed).
|
|
23
|
+
- [ ] **Semantic search** option (local embeddings + vector index) alongside BM25.
|
|
24
|
+
- [ ] **Cross-harness dedup** β collapse the same conversation captured by two tools.
|
|
25
|
+
- [ ] **Per-chat summaries** / auto-tags in frontmatter for better ranking & scanning.
|
|
26
|
+
- [ ] **Incremental indexing** (only re-index changed files) for very large histories.
|
|
27
|
+
|
|
28
|
+
## Sync & scale
|
|
29
|
+
|
|
30
|
+
- [ ] **Conflict-free multi-machine** hardening (large concurrent pushes).
|
|
31
|
+
- [ ] **History/size management** β optional squash, or Git LFS for the data repo.
|
|
32
|
+
- [ ] **Selective sync** β include/exclude projects or harnesses via config.
|
|
33
|
+
- [ ] **Redaction/secret-scrubbing** pass before commit (configurable patterns).
|
|
34
|
+
- [ ] **Encryption at rest** option for the data repo.
|
|
35
|
+
|
|
36
|
+
## Tooling & DX
|
|
37
|
+
|
|
38
|
+
- [ ] **`doctor` command** β verify config, detect installed harnesses, report counts.
|
|
39
|
+
- [ ] **One-line installers** (curl | sh) per OS.
|
|
40
|
+
- [ ] **CI** β lint + a smoke test that runs adapters against fixture data.
|
|
41
|
+
- [ ] **Fixture corpus** β tiny redacted sample stores per harness for tests.
|
|
42
|
+
- [ ] **Web/TUI browser** for the data repo.
|
|
43
|
+
|
|
44
|
+
## Docs
|
|
45
|
+
|
|
46
|
+
- [ ] Per-harness "where are my chats" reference with screenshots.
|
|
47
|
+
- [ ] Example `AGENTS.md`/`CLAUDE.md` snippets per tool (started in
|
|
48
|
+
[docs/agent-integration.md](docs/agent-integration.md)).
|