rememb 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.
- rememb-0.1.0/MANIFEST.in +4 -0
- rememb-0.1.0/PKG-INFO +196 -0
- rememb-0.1.0/README.md +165 -0
- rememb-0.1.0/demo/demo.gif +0 -0
- rememb-0.1.0/pyproject.toml +52 -0
- rememb-0.1.0/rules/claude.md +21 -0
- rememb-0.1.0/rules/continue.md +22 -0
- rememb-0.1.0/rules/cursor.md +22 -0
- rememb-0.1.0/rules/vscode.md +21 -0
- rememb-0.1.0/rules/windsurf.md +22 -0
- rememb-0.1.0/setup.cfg +4 -0
- rememb-0.1.0/src/rememb/__init__.py +3 -0
- rememb-0.1.0/src/rememb/cli.py +290 -0
- rememb-0.1.0/src/rememb/store.py +175 -0
- rememb-0.1.0/src/rememb.egg-info/PKG-INFO +196 -0
- rememb-0.1.0/src/rememb.egg-info/SOURCES.txt +18 -0
- rememb-0.1.0/src/rememb.egg-info/dependency_links.txt +1 -0
- rememb-0.1.0/src/rememb.egg-info/entry_points.txt +2 -0
- rememb-0.1.0/src/rememb.egg-info/requires.txt +8 -0
- rememb-0.1.0/src/rememb.egg-info/top_level.txt +1 -0
rememb-0.1.0/MANIFEST.in
ADDED
rememb-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rememb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Persistent memory standard for AI agents — local, portable, zero config
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/LuizEduPP/rememb
|
|
7
|
+
Project-URL: Repository, https://github.com/LuizEduPP/rememb
|
|
8
|
+
Project-URL: Issues, https://github.com/LuizEduPP/rememb/issues
|
|
9
|
+
Keywords: ai,agents,memory,llm,mcp,windsurf,cursor,claude,copilot,continue,vscode,persistent-memory,ai-tools
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Environment :: Console
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: typer>=0.12.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: sentence-transformers>=3.0.0
|
|
27
|
+
Requires-Dist: numpy>=1.24.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: twine; extra == "dev"
|
|
31
|
+
|
|
32
|
+
# rememb
|
|
33
|
+
|
|
34
|
+
> **Persistent memory for AI agents — local, portable, zero config.**
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
AI agents (Windsurf, Cursor, Claude, Continue) forget everything between sessions.
|
|
39
|
+
`rememb` gives them a structured memory that lives in your project, belongs to you, and works with any agent.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The problem
|
|
44
|
+
|
|
45
|
+
Every developer using AI agents hits this wall:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Session 1: "We're using PostgreSQL, the auth module is at src/auth/, prefer async patterns."
|
|
49
|
+
Session 2: Agent starts from zero. You explain everything again.
|
|
50
|
+
Session 3: Same thing.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Existing solutions (Mem0, Zep, Letta) require servers, API keys, cloud accounts, and framework lock-in.
|
|
54
|
+
You just want the agent to **remember your project**.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## The solution
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
.rememb/
|
|
62
|
+
entries.json ← structured memory (project, actions, systems, user, context)
|
|
63
|
+
meta.json ← project metadata
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
That's it. A JSON file in your project. Your agent reads it at the start of every session.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/LuizEduPP/rememb.git
|
|
74
|
+
cd rememb
|
|
75
|
+
pip install -e .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Quickstart
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Initialize in your project
|
|
84
|
+
rememb init
|
|
85
|
+
|
|
86
|
+
# Write memories
|
|
87
|
+
rememb write "Project uses FastAPI + PostgreSQL + async patterns" --section project
|
|
88
|
+
rememb write "User prefers direct answers, no filler text" --section user
|
|
89
|
+
rememb write "Auth module lives at src/auth/, JWT-based" --section systems
|
|
90
|
+
|
|
91
|
+
# Read everything (for the agent)
|
|
92
|
+
rememb read --agent
|
|
93
|
+
|
|
94
|
+
# Search semantically
|
|
95
|
+
rememb search "authentication"
|
|
96
|
+
|
|
97
|
+
# Get ready-to-use rules for your editor
|
|
98
|
+
rememb rules windsurf
|
|
99
|
+
rememb rules cursor
|
|
100
|
+
rememb rules claude
|
|
101
|
+
rememb rules continue
|
|
102
|
+
rememb rules vscode
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Agent integration
|
|
108
|
+
|
|
109
|
+
**Configure once. Works forever.**
|
|
110
|
+
|
|
111
|
+
Run `rememb rules <editor>` to get the instructions for your editor, then paste them once. From that point on, your agent automatically reads and writes memory on every session.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
rememb rules windsurf # Windsurf / Cascade
|
|
115
|
+
rememb rules cursor # Cursor
|
|
116
|
+
rememb rules claude # Claude Code
|
|
117
|
+
rememb rules continue # Continue.dev
|
|
118
|
+
rememb rules vscode # VS Code + Copilot
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Editor | Where to paste |
|
|
122
|
+
|--------|---------------|
|
|
123
|
+
| **Windsurf / Cascade** | `.windsurfrules` at project root — or Settings → Cascade → Custom Instructions |
|
|
124
|
+
| **Cursor** | `.cursorrules` at project root — or Settings → Rules for AI |
|
|
125
|
+
| **Claude Code** | `CLAUDE.md` at project root (auto-read every session) |
|
|
126
|
+
| **Continue.dev** | `config.json` → `models[].systemMessage` |
|
|
127
|
+
| **VS Code + Copilot** | `.github/copilot-instructions.md` at project root (auto-read by Copilot) |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Memory sections
|
|
132
|
+
|
|
133
|
+
| Section | What to store |
|
|
134
|
+
|---------|---------------|
|
|
135
|
+
| `project` | Tech stack, architecture, goals |
|
|
136
|
+
| `actions` | What was done, decisions made |
|
|
137
|
+
| `systems` | Services, modules, integrations |
|
|
138
|
+
| `requests` | User preferences, recurring asks |
|
|
139
|
+
| `user` | Name, style, expertise, preferences |
|
|
140
|
+
| `context` | Anything else relevant |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Commands
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
rememb init Initialize .rememb/ in current project
|
|
148
|
+
rememb write <text> Write a memory entry (--section, --tags)
|
|
149
|
+
rememb read Read all entries (--section, --agent, --raw)
|
|
150
|
+
rememb search <query> Semantic search (falls back to keyword)
|
|
151
|
+
rememb rules [editor] Print agent rules for windsurf/cursor/claude/continue
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## How search works
|
|
157
|
+
|
|
158
|
+
`rememb search` uses `sentence-transformers` for semantic similarity search locally.
|
|
159
|
+
No API calls. No embeddings sent to the cloud. Falls back to keyword search if the model isn't available.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Design principles
|
|
164
|
+
|
|
165
|
+
- **Local first** — everything is a JSON file in your project
|
|
166
|
+
- **Portable** — copy `.rememb/` and it works anywhere
|
|
167
|
+
- **Agnostic** — works with any agent that can run CLI commands
|
|
168
|
+
- **Zero config** — `pip install rememb && rememb init` and you're done
|
|
169
|
+
- **No lock-in** — plain JSON, read it with anything
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Roadmap
|
|
174
|
+
|
|
175
|
+
- [ ] MCP server (`rememb mcp`) for native IDE integration
|
|
176
|
+
- [ ] `rememb sync` — optional encrypted remote backup
|
|
177
|
+
- [ ] `rememb export` — export to Markdown, Obsidian, Notion
|
|
178
|
+
- [ ] VS Code / Windsurf extension
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Contributing
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
git clone https://github.com/LuizEduPP/rememb
|
|
186
|
+
cd rememb
|
|
187
|
+
pip install -e ".[dev]"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
PRs welcome. Issues welcome. Stars welcome. 🌟
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
rememb-0.1.0/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
> **Persistent memory for AI agents — local, portable, zero config.**
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
AI agents (Windsurf, Cursor, Claude, Continue) forget everything between sessions.
|
|
8
|
+
`rememb` gives them a structured memory that lives in your project, belongs to you, and works with any agent.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## The problem
|
|
13
|
+
|
|
14
|
+
Every developer using AI agents hits this wall:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Session 1: "We're using PostgreSQL, the auth module is at src/auth/, prefer async patterns."
|
|
18
|
+
Session 2: Agent starts from zero. You explain everything again.
|
|
19
|
+
Session 3: Same thing.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Existing solutions (Mem0, Zep, Letta) require servers, API keys, cloud accounts, and framework lock-in.
|
|
23
|
+
You just want the agent to **remember your project**.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## The solution
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
.rememb/
|
|
31
|
+
entries.json ← structured memory (project, actions, systems, user, context)
|
|
32
|
+
meta.json ← project metadata
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
That's it. A JSON file in your project. Your agent reads it at the start of every session.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/LuizEduPP/rememb.git
|
|
43
|
+
cd rememb
|
|
44
|
+
pip install -e .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Initialize in your project
|
|
53
|
+
rememb init
|
|
54
|
+
|
|
55
|
+
# Write memories
|
|
56
|
+
rememb write "Project uses FastAPI + PostgreSQL + async patterns" --section project
|
|
57
|
+
rememb write "User prefers direct answers, no filler text" --section user
|
|
58
|
+
rememb write "Auth module lives at src/auth/, JWT-based" --section systems
|
|
59
|
+
|
|
60
|
+
# Read everything (for the agent)
|
|
61
|
+
rememb read --agent
|
|
62
|
+
|
|
63
|
+
# Search semantically
|
|
64
|
+
rememb search "authentication"
|
|
65
|
+
|
|
66
|
+
# Get ready-to-use rules for your editor
|
|
67
|
+
rememb rules windsurf
|
|
68
|
+
rememb rules cursor
|
|
69
|
+
rememb rules claude
|
|
70
|
+
rememb rules continue
|
|
71
|
+
rememb rules vscode
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Agent integration
|
|
77
|
+
|
|
78
|
+
**Configure once. Works forever.**
|
|
79
|
+
|
|
80
|
+
Run `rememb rules <editor>` to get the instructions for your editor, then paste them once. From that point on, your agent automatically reads and writes memory on every session.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
rememb rules windsurf # Windsurf / Cascade
|
|
84
|
+
rememb rules cursor # Cursor
|
|
85
|
+
rememb rules claude # Claude Code
|
|
86
|
+
rememb rules continue # Continue.dev
|
|
87
|
+
rememb rules vscode # VS Code + Copilot
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Editor | Where to paste |
|
|
91
|
+
|--------|---------------|
|
|
92
|
+
| **Windsurf / Cascade** | `.windsurfrules` at project root — or Settings → Cascade → Custom Instructions |
|
|
93
|
+
| **Cursor** | `.cursorrules` at project root — or Settings → Rules for AI |
|
|
94
|
+
| **Claude Code** | `CLAUDE.md` at project root (auto-read every session) |
|
|
95
|
+
| **Continue.dev** | `config.json` → `models[].systemMessage` |
|
|
96
|
+
| **VS Code + Copilot** | `.github/copilot-instructions.md` at project root (auto-read by Copilot) |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Memory sections
|
|
101
|
+
|
|
102
|
+
| Section | What to store |
|
|
103
|
+
|---------|---------------|
|
|
104
|
+
| `project` | Tech stack, architecture, goals |
|
|
105
|
+
| `actions` | What was done, decisions made |
|
|
106
|
+
| `systems` | Services, modules, integrations |
|
|
107
|
+
| `requests` | User preferences, recurring asks |
|
|
108
|
+
| `user` | Name, style, expertise, preferences |
|
|
109
|
+
| `context` | Anything else relevant |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Commands
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
rememb init Initialize .rememb/ in current project
|
|
117
|
+
rememb write <text> Write a memory entry (--section, --tags)
|
|
118
|
+
rememb read Read all entries (--section, --agent, --raw)
|
|
119
|
+
rememb search <query> Semantic search (falls back to keyword)
|
|
120
|
+
rememb rules [editor] Print agent rules for windsurf/cursor/claude/continue
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## How search works
|
|
126
|
+
|
|
127
|
+
`rememb search` uses `sentence-transformers` for semantic similarity search locally.
|
|
128
|
+
No API calls. No embeddings sent to the cloud. Falls back to keyword search if the model isn't available.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Design principles
|
|
133
|
+
|
|
134
|
+
- **Local first** — everything is a JSON file in your project
|
|
135
|
+
- **Portable** — copy `.rememb/` and it works anywhere
|
|
136
|
+
- **Agnostic** — works with any agent that can run CLI commands
|
|
137
|
+
- **Zero config** — `pip install rememb && rememb init` and you're done
|
|
138
|
+
- **No lock-in** — plain JSON, read it with anything
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Roadmap
|
|
143
|
+
|
|
144
|
+
- [ ] MCP server (`rememb mcp`) for native IDE integration
|
|
145
|
+
- [ ] `rememb sync` — optional encrypted remote backup
|
|
146
|
+
- [ ] `rememb export` — export to Markdown, Obsidian, Notion
|
|
147
|
+
- [ ] VS Code / Windsurf extension
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Contributing
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
git clone https://github.com/LuizEduPP/rememb
|
|
155
|
+
cd rememb
|
|
156
|
+
pip install -e ".[dev]"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
PRs welcome. Issues welcome. Stars welcome. 🌟
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rememb"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Persistent memory standard for AI agents — local, portable, zero config"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
keywords = ["ai", "agents", "memory", "llm", "mcp", "windsurf", "cursor", "claude", "copilot", "continue", "vscode", "persistent-memory", "ai-tools"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Topic :: Software Development :: Libraries",
|
|
17
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Environment :: Console",
|
|
25
|
+
"Operating System :: OS Independent",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"typer>=0.12.0",
|
|
29
|
+
"rich>=13.0.0",
|
|
30
|
+
"sentence-transformers>=3.0.0",
|
|
31
|
+
"numpy>=1.24.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
rememb = "rememb.cli:app"
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = ["build", "twine"]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/LuizEduPP/rememb"
|
|
42
|
+
Repository = "https://github.com/LuizEduPP/rememb"
|
|
43
|
+
Issues = "https://github.com/LuizEduPP/rememb/issues"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
where = ["src"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-data]
|
|
49
|
+
"*" = ["*.md", "*.json", "*.gif"]
|
|
50
|
+
|
|
51
|
+
[tool.setuptools]
|
|
52
|
+
include-package-data = true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
You have access to `rememb`, a CLI tool for persistent memory across sessions.
|
|
4
|
+
Use it to remember and retrieve context about this project and user.
|
|
5
|
+
|
|
6
|
+
## Reading memory
|
|
7
|
+
Run `rememb read --agent` to load all stored context before responding.
|
|
8
|
+
Run `rememb search "<topic>" --agent` to find specific information.
|
|
9
|
+
|
|
10
|
+
## Writing memory
|
|
11
|
+
Run `rememb write "<summary>" --section <section>` when you learn something worth remembering.
|
|
12
|
+
Available sections: project | actions | systems | requests | user | context
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
- Always read memory at the start of a new session
|
|
16
|
+
- Save important context after learning it — do not wait
|
|
17
|
+
- Keep entries short (1-3 sentences)
|
|
18
|
+
- Use --tags to categorize: `rememb write "..." --section project --tags tag1,tag2`
|
|
19
|
+
|
|
20
|
+
# Where to place (Claude Code)
|
|
21
|
+
- CLAUDE.md at project root (auto-read every session)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
You have access to `rememb`, a CLI tool for persistent memory across sessions.
|
|
4
|
+
Use it to remember and retrieve context about this project and user.
|
|
5
|
+
|
|
6
|
+
## Reading memory
|
|
7
|
+
Run `rememb read --agent` to load all stored context before responding.
|
|
8
|
+
Run `rememb search "<topic>" --agent` to find specific information.
|
|
9
|
+
|
|
10
|
+
## Writing memory
|
|
11
|
+
Run `rememb write "<summary>" --section <section>` when you learn something worth remembering.
|
|
12
|
+
Available sections: project | actions | systems | requests | user | context
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
- Always read memory at the start of a new session
|
|
16
|
+
- Save important context after learning it — do not wait
|
|
17
|
+
- Keep entries short (1-3 sentences)
|
|
18
|
+
- Use --tags to categorize: `rememb write "..." --section project --tags tag1,tag2`
|
|
19
|
+
|
|
20
|
+
# Where to place (Continue.dev)
|
|
21
|
+
- config.json → models[].systemMessage
|
|
22
|
+
- Or: .continuerc.json → systemMessage
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
You have access to `rememb`, a CLI tool for persistent memory across sessions.
|
|
4
|
+
Use it to remember and retrieve context about this project and user.
|
|
5
|
+
|
|
6
|
+
## Reading memory
|
|
7
|
+
Run `rememb read --agent` to load all stored context before responding.
|
|
8
|
+
Run `rememb search "<topic>" --agent` to find specific information.
|
|
9
|
+
|
|
10
|
+
## Writing memory
|
|
11
|
+
Run `rememb write "<summary>" --section <section>` when you learn something worth remembering.
|
|
12
|
+
Available sections: project | actions | systems | requests | user | context
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
- Always read memory at the start of a new session
|
|
16
|
+
- Save important context after learning it — do not wait
|
|
17
|
+
- Keep entries short (1-3 sentences)
|
|
18
|
+
- Use --tags to categorize: `rememb write "..." --section project --tags tag1,tag2`
|
|
19
|
+
|
|
20
|
+
# Where to place (Cursor)
|
|
21
|
+
- .cursorrules at project root
|
|
22
|
+
- Or: Settings → Rules for AI
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
You have access to `rememb`, a CLI tool for persistent memory across sessions.
|
|
4
|
+
Use it to remember and retrieve context about this project and user.
|
|
5
|
+
|
|
6
|
+
## Reading memory
|
|
7
|
+
Run `rememb read --agent` to load all stored context before responding.
|
|
8
|
+
Run `rememb search "<topic>" --agent` to find specific information.
|
|
9
|
+
|
|
10
|
+
## Writing memory
|
|
11
|
+
Run `rememb write "<summary>" --section <section>` when you learn something worth remembering.
|
|
12
|
+
Available sections: project | actions | systems | requests | user | context
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
- Always read memory at the start of a new session
|
|
16
|
+
- Save important context after learning it — do not wait
|
|
17
|
+
- Keep entries short (1-3 sentences)
|
|
18
|
+
- Use --tags to categorize: `rememb write "..." --section project --tags tag1,tag2`
|
|
19
|
+
|
|
20
|
+
# Where to place (VS Code + Copilot)
|
|
21
|
+
- .github/copilot-instructions.md at project root (auto-read by Copilot)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# rememb
|
|
2
|
+
|
|
3
|
+
You have access to `rememb`, a CLI tool for persistent memory across sessions.
|
|
4
|
+
Use it to remember and retrieve context about this project and user.
|
|
5
|
+
|
|
6
|
+
## Reading memory
|
|
7
|
+
Run `rememb read --agent` to load all stored context before responding.
|
|
8
|
+
Run `rememb search "<topic>" --agent` to find specific information.
|
|
9
|
+
|
|
10
|
+
## Writing memory
|
|
11
|
+
Run `rememb write "<summary>" --section <section>` when you learn something worth remembering.
|
|
12
|
+
Available sections: project | actions | systems | requests | user | context
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
- Always read memory at the start of a new session
|
|
16
|
+
- Save important context after learning it — do not wait
|
|
17
|
+
- Keep entries short (1-3 sentences)
|
|
18
|
+
- Use --tags to categorize: `rememb write "..." --section project --tags tag1,tag2`
|
|
19
|
+
|
|
20
|
+
# Where to place (Windsurf / Cascade)
|
|
21
|
+
- Settings → Cascade → Custom Instructions
|
|
22
|
+
- Or: .windsurfrules at project root
|
rememb-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"""rememb CLI — persistent memory for AI agents."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.markdown import Markdown
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
from rich.table import Table
|
|
13
|
+
from rich import box
|
|
14
|
+
|
|
15
|
+
from rememb import __version__
|
|
16
|
+
from rememb.store import (
|
|
17
|
+
SECTIONS,
|
|
18
|
+
find_root,
|
|
19
|
+
global_root,
|
|
20
|
+
init,
|
|
21
|
+
is_initialized,
|
|
22
|
+
read_entries,
|
|
23
|
+
search_entries,
|
|
24
|
+
write_entry,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
app = typer.Typer(
|
|
28
|
+
name="rememb",
|
|
29
|
+
help="Persistent memory for AI agents — local, portable, zero config.",
|
|
30
|
+
no_args_is_help=True,
|
|
31
|
+
rich_markup_mode="rich",
|
|
32
|
+
)
|
|
33
|
+
console = Console()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _root() -> Path:
|
|
37
|
+
"""Returns memory root. Auto-initializes global ~/.rememb/ if nothing found."""
|
|
38
|
+
root = find_root()
|
|
39
|
+
if not is_initialized(root):
|
|
40
|
+
root = global_root()
|
|
41
|
+
init(root, project_name="global", global_mode=True)
|
|
42
|
+
return root
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@app.command()
|
|
46
|
+
def version():
|
|
47
|
+
"""Show rememb version."""
|
|
48
|
+
console.print(f"rememb v{__version__}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def init_cmd(
|
|
52
|
+
path: Optional[Path] = typer.Argument(None, help="Project root (default: current dir)"),
|
|
53
|
+
name: str = typer.Option("", "--name", "-n", help="Project name"),
|
|
54
|
+
):
|
|
55
|
+
"""Initialize .rememb/ in the current project (or globally with --global)."""
|
|
56
|
+
root = (path or Path.cwd()).resolve()
|
|
57
|
+
|
|
58
|
+
if is_initialized(root):
|
|
59
|
+
console.print(f"[yellow]Already initialized at {root / '.rememb'}[/yellow]")
|
|
60
|
+
raise typer.Exit()
|
|
61
|
+
|
|
62
|
+
global_mode = root == global_root()
|
|
63
|
+
rememb = init(root, project_name=name, global_mode=global_mode)
|
|
64
|
+
console.print(Panel(
|
|
65
|
+
f"[green]✓[/green] Initialized [bold].rememb/[/bold] at [dim]{rememb}[/dim]\n\n"
|
|
66
|
+
f"[dim]Sections:[/dim] {', '.join(SECTIONS)}\n\n"
|
|
67
|
+
f"Next steps:\n"
|
|
68
|
+
f" [bold]rememb write[/bold] --section project \"My project does X\"\n"
|
|
69
|
+
f" [bold]rememb read[/bold]\n"
|
|
70
|
+
f" [bold]rememb rules[/bold] ← copy rules for your AI editor",
|
|
71
|
+
title="rememb",
|
|
72
|
+
border_style="green",
|
|
73
|
+
))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
app.command("init")(init_cmd)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@app.command()
|
|
81
|
+
def write(
|
|
82
|
+
content: str = typer.Argument(..., help="Memory content to store"),
|
|
83
|
+
section: str = typer.Option("context", "--section", "-s", help=f"Section: {', '.join(SECTIONS)}"),
|
|
84
|
+
tags: Optional[str] = typer.Option(None, "--tags", "-t", help="Comma-separated tags"),
|
|
85
|
+
):
|
|
86
|
+
"""Write a new memory entry."""
|
|
87
|
+
root = _root()
|
|
88
|
+
tag_list = [t.strip() for t in tags.split(",")] if tags else []
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
entry = write_entry(root, section, content, tag_list)
|
|
92
|
+
except (RuntimeError, ValueError) as e:
|
|
93
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
94
|
+
raise typer.Exit(1)
|
|
95
|
+
|
|
96
|
+
console.print(
|
|
97
|
+
f"[green]✓[/green] Saved [bold][{entry['section']}][/bold] "
|
|
98
|
+
f"[dim]id={entry['id']} at {entry['created_at']}[/dim]"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@app.command()
|
|
103
|
+
def read(
|
|
104
|
+
section: Optional[str] = typer.Option(None, "--section", "-s", help="Filter by section"),
|
|
105
|
+
raw: bool = typer.Option(False, "--raw", help="Output raw JSON"),
|
|
106
|
+
agent: bool = typer.Option(False, "--agent", help="Output optimized for agent consumption"),
|
|
107
|
+
):
|
|
108
|
+
"""Read memory entries."""
|
|
109
|
+
root = _root()
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
entries = read_entries(root, section)
|
|
113
|
+
except RuntimeError as e:
|
|
114
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
115
|
+
raise typer.Exit(1)
|
|
116
|
+
|
|
117
|
+
if not entries:
|
|
118
|
+
console.print("[dim]No entries found.[/dim]")
|
|
119
|
+
raise typer.Exit()
|
|
120
|
+
|
|
121
|
+
if raw:
|
|
122
|
+
import json
|
|
123
|
+
print(json.dumps(entries, indent=2))
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
if agent:
|
|
127
|
+
_print_agent_format(entries)
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
_print_table(entries)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@app.command()
|
|
134
|
+
def search(
|
|
135
|
+
query: str = typer.Argument(..., help="Search query"),
|
|
136
|
+
top_k: int = typer.Option(5, "--top", "-k", help="Number of results"),
|
|
137
|
+
agent: bool = typer.Option(False, "--agent", help="Output optimized for agent consumption"),
|
|
138
|
+
):
|
|
139
|
+
"""Search memory entries semantically (falls back to keyword)."""
|
|
140
|
+
root = _root()
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
results = search_entries(root, query, top_k)
|
|
144
|
+
except RuntimeError as e:
|
|
145
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
146
|
+
raise typer.Exit(1)
|
|
147
|
+
|
|
148
|
+
if not results:
|
|
149
|
+
console.print("[dim]No results found.[/dim]")
|
|
150
|
+
raise typer.Exit()
|
|
151
|
+
|
|
152
|
+
if agent:
|
|
153
|
+
_print_agent_format(results)
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
console.print(f"\n[bold]Top {len(results)} results for:[/bold] [italic]{query}[/italic]\n")
|
|
157
|
+
_print_table(results)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@app.command()
|
|
161
|
+
def rules(
|
|
162
|
+
editor: Optional[str] = typer.Argument(None, help="Editor: windsurf, cursor, claude, continue, vscode, all"),
|
|
163
|
+
):
|
|
164
|
+
"""Print ready-to-use agent rules/instructions for your editor."""
|
|
165
|
+
_rules = _build_rules()
|
|
166
|
+
|
|
167
|
+
editors = {
|
|
168
|
+
"windsurf": ("Windsurf / Cascade", "windsurf_rules"),
|
|
169
|
+
"cursor": ("Cursor", "cursor_rules"),
|
|
170
|
+
"claude": ("Claude / Claude.md", "claude_rules"),
|
|
171
|
+
"continue": ("Continue.dev", "continue_rules"),
|
|
172
|
+
"vscode": ("VS Code + Copilot", "vscode_rules"),
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if not editor:
|
|
176
|
+
console.print("\n[bold]Available editors:[/bold]\n")
|
|
177
|
+
for key, (label, _) in editors.items():
|
|
178
|
+
console.print(f" [cyan]rememb rules {key}[/cyan] [dim]→ {label}[/dim]")
|
|
179
|
+
console.print()
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
if editor.lower() == "all":
|
|
183
|
+
for key, (label, rule_key) in editors.items():
|
|
184
|
+
print(_rules[rule_key])
|
|
185
|
+
print()
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
if editor.lower() not in editors:
|
|
189
|
+
console.print(f"[red]Unknown editor:[/red] {editor}. Choose from: {', '.join(editors)}")
|
|
190
|
+
raise typer.Exit(1)
|
|
191
|
+
|
|
192
|
+
label, key = editors[editor.lower()]
|
|
193
|
+
print(_rules[key])
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _build_rules() -> dict:
|
|
197
|
+
base = (
|
|
198
|
+
"# rememb\n\n"
|
|
199
|
+
"You have access to `rememb`, a CLI tool for persistent memory across sessions.\n"
|
|
200
|
+
"Use it to remember and retrieve context about this project and user.\n\n"
|
|
201
|
+
"## Reading memory\n"
|
|
202
|
+
"Run `rememb read --agent` to load all stored context before responding.\n"
|
|
203
|
+
"Run `rememb search \"<topic>\" --agent` to find specific information.\n\n"
|
|
204
|
+
"## Writing memory\n"
|
|
205
|
+
"Run `rememb write \"<summary>\" --section <section>` when you learn something worth remembering.\n"
|
|
206
|
+
"Available sections: project | actions | systems | requests | user | context\n\n"
|
|
207
|
+
"## Rules\n"
|
|
208
|
+
"- Always read memory at the start of a new session\n"
|
|
209
|
+
"- Save important context after learning it — don't wait\n"
|
|
210
|
+
"- Keep entries short (1-3 sentences)\n"
|
|
211
|
+
"- Use --tags to categorize: `rememb write \"...\" --section project --tags tag1,tag2`\n"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
windsurf = (
|
|
215
|
+
base +
|
|
216
|
+
"\n# Where to place (Windsurf / Cascade)\n"
|
|
217
|
+
"- Settings → Cascade → Custom Instructions\n"
|
|
218
|
+
"- Or: .windsurfrules at project root\n"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
cursor = (
|
|
222
|
+
base +
|
|
223
|
+
"\n# Where to place (Cursor)\n"
|
|
224
|
+
"- .cursorrules at project root\n"
|
|
225
|
+
"- Or: Settings → Rules for AI\n"
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
claude = (
|
|
229
|
+
base +
|
|
230
|
+
"\n# Where to place (Claude Code)\n"
|
|
231
|
+
"- CLAUDE.md at project root (auto-read every session)\n"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
continue_dev = (
|
|
235
|
+
base +
|
|
236
|
+
"\n# Where to place (Continue.dev)\n"
|
|
237
|
+
"- config.json → models[].systemMessage\n"
|
|
238
|
+
"- Or: .continuerc.json → systemMessage\n"
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
vscode = (
|
|
242
|
+
base +
|
|
243
|
+
"\n# Where to place (VS Code + Copilot)\n"
|
|
244
|
+
"- .github/copilot-instructions.md at project root (auto-read by Copilot)\n"
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
"windsurf_rules": windsurf,
|
|
249
|
+
"cursor_rules": cursor,
|
|
250
|
+
"claude_rules": claude,
|
|
251
|
+
"continue_rules": continue_dev,
|
|
252
|
+
"vscode_rules": vscode,
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _print_table(entries: list[dict]) -> None:
|
|
257
|
+
table = Table(box=box.ROUNDED, show_header=True, header_style="bold cyan")
|
|
258
|
+
table.add_column("ID", style="dim", width=10)
|
|
259
|
+
table.add_column("Section", style="bold", width=12)
|
|
260
|
+
table.add_column("Content")
|
|
261
|
+
table.add_column("Tags", style="dim", width=20)
|
|
262
|
+
table.add_column("Date", style="dim", width=22)
|
|
263
|
+
|
|
264
|
+
for e in entries:
|
|
265
|
+
table.add_row(
|
|
266
|
+
e["id"],
|
|
267
|
+
e["section"],
|
|
268
|
+
e["content"],
|
|
269
|
+
", ".join(e.get("tags", [])) or "-",
|
|
270
|
+
e["created_at"],
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
console.print(table)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def _print_agent_format(entries: list[dict]) -> None:
|
|
277
|
+
"""Compact format optimized for LLM context consumption."""
|
|
278
|
+
by_section: dict[str, list] = {}
|
|
279
|
+
for e in entries:
|
|
280
|
+
by_section.setdefault(e["section"], []).append(e)
|
|
281
|
+
|
|
282
|
+
output = ["# Memory Context (rememb)\n"]
|
|
283
|
+
for section, items in by_section.items():
|
|
284
|
+
output.append(f"## {section.capitalize()}")
|
|
285
|
+
for item in items:
|
|
286
|
+
tags = f" [{', '.join(item['tags'])}]" if item.get("tags") else ""
|
|
287
|
+
output.append(f"- {item['content']}{tags}")
|
|
288
|
+
output.append("")
|
|
289
|
+
|
|
290
|
+
print("\n".join(output))
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""Core storage engine for .rememb/"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import uuid
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
REMEMB_DIR = ".rememb"
|
|
12
|
+
GLOBAL_REMEMB_DIR = Path.home() / ".rememb"
|
|
13
|
+
ENTRIES_FILE = "entries.json"
|
|
14
|
+
META_FILE = "meta.json"
|
|
15
|
+
|
|
16
|
+
SECTIONS = ["project", "actions", "systems", "requests", "user", "context"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def global_root() -> Path:
|
|
20
|
+
"""Returns the global memory root: ~/.rememb/"""
|
|
21
|
+
return Path.home()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _rememb_path(root: Path) -> Path:
|
|
25
|
+
return root / REMEMB_DIR
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _entries_path(root: Path) -> Path:
|
|
29
|
+
return _rememb_path(root) / ENTRIES_FILE
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _meta_path(root: Path) -> Path:
|
|
33
|
+
return _rememb_path(root) / META_FILE
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def find_root(start: Optional[Path] = None, local: bool = False) -> Path:
|
|
37
|
+
"""Find .rememb/ root.
|
|
38
|
+
|
|
39
|
+
Priority:
|
|
40
|
+
1. Walk up from start looking for a local .rememb/ (if --local or found naturally)
|
|
41
|
+
2. Fall back to global ~/.rememb/
|
|
42
|
+
"""
|
|
43
|
+
current = (start or Path.cwd()).resolve()
|
|
44
|
+
for parent in [current, *current.parents]:
|
|
45
|
+
if (parent / REMEMB_DIR).is_dir():
|
|
46
|
+
return parent
|
|
47
|
+
|
|
48
|
+
if local:
|
|
49
|
+
return current
|
|
50
|
+
|
|
51
|
+
return global_root()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def is_initialized(root: Path) -> bool:
|
|
55
|
+
return _entries_path(root).exists()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def init(root: Path, project_name: str = "", global_mode: bool = False) -> Path:
|
|
59
|
+
rememb = _rememb_path(root)
|
|
60
|
+
rememb.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
|
|
62
|
+
entries_file = _entries_path(root)
|
|
63
|
+
if not entries_file.exists():
|
|
64
|
+
entries_file.write_text(json.dumps([], indent=2), encoding="utf-8")
|
|
65
|
+
|
|
66
|
+
meta_file = _meta_path(root)
|
|
67
|
+
if not meta_file.exists():
|
|
68
|
+
meta = {
|
|
69
|
+
"version": "1",
|
|
70
|
+
"project": project_name or ("global" if global_mode else root.name),
|
|
71
|
+
"created_at": _now(),
|
|
72
|
+
"sections": SECTIONS,
|
|
73
|
+
}
|
|
74
|
+
meta_file.write_text(json.dumps(meta, indent=2), encoding="utf-8")
|
|
75
|
+
|
|
76
|
+
if not global_mode:
|
|
77
|
+
gitignore = root / ".gitignore"
|
|
78
|
+
gitignore_line = ".rememb/embeddings.npy\n"
|
|
79
|
+
if gitignore.exists():
|
|
80
|
+
content = gitignore.read_text(encoding="utf-8")
|
|
81
|
+
if gitignore_line.strip() not in content:
|
|
82
|
+
gitignore.write_text(content.rstrip() + "\n" + gitignore_line, encoding="utf-8")
|
|
83
|
+
|
|
84
|
+
return rememb
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def write_entry(root: Path, section: str, content: str, tags: list[str] | None = None) -> dict:
|
|
88
|
+
if not is_initialized(root):
|
|
89
|
+
raise RuntimeError("rememb not initialized. Run `rememb init` first.")
|
|
90
|
+
|
|
91
|
+
section = section.lower()
|
|
92
|
+
if section not in SECTIONS:
|
|
93
|
+
raise ValueError(f"Invalid section '{section}'. Choose from: {', '.join(SECTIONS)}")
|
|
94
|
+
|
|
95
|
+
entries = _load_entries(root)
|
|
96
|
+
entry = {
|
|
97
|
+
"id": str(uuid.uuid4())[:8],
|
|
98
|
+
"section": section,
|
|
99
|
+
"content": content,
|
|
100
|
+
"tags": tags or [],
|
|
101
|
+
"created_at": _now(),
|
|
102
|
+
}
|
|
103
|
+
entries.append(entry)
|
|
104
|
+
_save_entries(root, entries)
|
|
105
|
+
return entry
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def read_entries(root: Path, section: Optional[str] = None) -> list[dict]:
|
|
109
|
+
if not is_initialized(root):
|
|
110
|
+
raise RuntimeError("rememb not initialized. Run `rememb init` first.")
|
|
111
|
+
entries = _load_entries(root)
|
|
112
|
+
if section:
|
|
113
|
+
entries = [e for e in entries if e["section"] == section.lower()]
|
|
114
|
+
return entries
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def search_entries(root: Path, query: str, top_k: int = 5) -> list[dict]:
|
|
118
|
+
"""Semantic search using sentence-transformers. Falls back to keyword search."""
|
|
119
|
+
entries = _load_entries(root)
|
|
120
|
+
if not entries:
|
|
121
|
+
return []
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
return _semantic_search(root, entries, query, top_k)
|
|
125
|
+
except Exception:
|
|
126
|
+
return _keyword_search(entries, query, top_k)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _semantic_search(root: Path, entries: list[dict], query: str, top_k: int) -> list[dict]:
|
|
130
|
+
import numpy as np
|
|
131
|
+
from sentence_transformers import SentenceTransformer
|
|
132
|
+
|
|
133
|
+
model = SentenceTransformer("all-MiniLM-L6-v2")
|
|
134
|
+
texts = [e["content"] for e in entries]
|
|
135
|
+
|
|
136
|
+
embeddings_path = _rememb_path(root) / "embeddings.npy"
|
|
137
|
+
if embeddings_path.exists():
|
|
138
|
+
embeddings = np.load(str(embeddings_path))
|
|
139
|
+
if len(embeddings) != len(texts):
|
|
140
|
+
embeddings = model.encode(texts)
|
|
141
|
+
np.save(str(embeddings_path), embeddings)
|
|
142
|
+
else:
|
|
143
|
+
embeddings = model.encode(texts)
|
|
144
|
+
np.save(str(embeddings_path), embeddings)
|
|
145
|
+
|
|
146
|
+
query_vec = model.encode([query])[0]
|
|
147
|
+
scores = np.dot(embeddings, query_vec) / (
|
|
148
|
+
np.linalg.norm(embeddings, axis=1) * np.linalg.norm(query_vec) + 1e-9
|
|
149
|
+
)
|
|
150
|
+
top_indices = np.argsort(scores)[::-1][:top_k]
|
|
151
|
+
return [entries[i] for i in top_indices]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _keyword_search(entries: list[dict], query: str, top_k: int) -> list[dict]:
|
|
155
|
+
q = query.lower()
|
|
156
|
+
scored = []
|
|
157
|
+
for entry in entries:
|
|
158
|
+
score = entry["content"].lower().count(q)
|
|
159
|
+
if score > 0:
|
|
160
|
+
scored.append((score, entry))
|
|
161
|
+
scored.sort(key=lambda x: x[0], reverse=True)
|
|
162
|
+
return [e for _, e in scored[:top_k]]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _load_entries(root: Path) -> list[dict]:
|
|
166
|
+
raw = _entries_path(root).read_text(encoding="utf-8")
|
|
167
|
+
return json.loads(raw)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _save_entries(root: Path, entries: list[dict]) -> None:
|
|
171
|
+
_entries_path(root).write_text(json.dumps(entries, indent=2), encoding="utf-8")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _now() -> str:
|
|
175
|
+
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rememb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Persistent memory standard for AI agents — local, portable, zero config
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/LuizEduPP/rememb
|
|
7
|
+
Project-URL: Repository, https://github.com/LuizEduPP/rememb
|
|
8
|
+
Project-URL: Issues, https://github.com/LuizEduPP/rememb/issues
|
|
9
|
+
Keywords: ai,agents,memory,llm,mcp,windsurf,cursor,claude,copilot,continue,vscode,persistent-memory,ai-tools
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Environment :: Console
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: typer>=0.12.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: sentence-transformers>=3.0.0
|
|
27
|
+
Requires-Dist: numpy>=1.24.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: twine; extra == "dev"
|
|
31
|
+
|
|
32
|
+
# rememb
|
|
33
|
+
|
|
34
|
+
> **Persistent memory for AI agents — local, portable, zero config.**
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
AI agents (Windsurf, Cursor, Claude, Continue) forget everything between sessions.
|
|
39
|
+
`rememb` gives them a structured memory that lives in your project, belongs to you, and works with any agent.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The problem
|
|
44
|
+
|
|
45
|
+
Every developer using AI agents hits this wall:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Session 1: "We're using PostgreSQL, the auth module is at src/auth/, prefer async patterns."
|
|
49
|
+
Session 2: Agent starts from zero. You explain everything again.
|
|
50
|
+
Session 3: Same thing.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Existing solutions (Mem0, Zep, Letta) require servers, API keys, cloud accounts, and framework lock-in.
|
|
54
|
+
You just want the agent to **remember your project**.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## The solution
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
.rememb/
|
|
62
|
+
entries.json ← structured memory (project, actions, systems, user, context)
|
|
63
|
+
meta.json ← project metadata
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
That's it. A JSON file in your project. Your agent reads it at the start of every session.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/LuizEduPP/rememb.git
|
|
74
|
+
cd rememb
|
|
75
|
+
pip install -e .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Quickstart
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Initialize in your project
|
|
84
|
+
rememb init
|
|
85
|
+
|
|
86
|
+
# Write memories
|
|
87
|
+
rememb write "Project uses FastAPI + PostgreSQL + async patterns" --section project
|
|
88
|
+
rememb write "User prefers direct answers, no filler text" --section user
|
|
89
|
+
rememb write "Auth module lives at src/auth/, JWT-based" --section systems
|
|
90
|
+
|
|
91
|
+
# Read everything (for the agent)
|
|
92
|
+
rememb read --agent
|
|
93
|
+
|
|
94
|
+
# Search semantically
|
|
95
|
+
rememb search "authentication"
|
|
96
|
+
|
|
97
|
+
# Get ready-to-use rules for your editor
|
|
98
|
+
rememb rules windsurf
|
|
99
|
+
rememb rules cursor
|
|
100
|
+
rememb rules claude
|
|
101
|
+
rememb rules continue
|
|
102
|
+
rememb rules vscode
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Agent integration
|
|
108
|
+
|
|
109
|
+
**Configure once. Works forever.**
|
|
110
|
+
|
|
111
|
+
Run `rememb rules <editor>` to get the instructions for your editor, then paste them once. From that point on, your agent automatically reads and writes memory on every session.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
rememb rules windsurf # Windsurf / Cascade
|
|
115
|
+
rememb rules cursor # Cursor
|
|
116
|
+
rememb rules claude # Claude Code
|
|
117
|
+
rememb rules continue # Continue.dev
|
|
118
|
+
rememb rules vscode # VS Code + Copilot
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Editor | Where to paste |
|
|
122
|
+
|--------|---------------|
|
|
123
|
+
| **Windsurf / Cascade** | `.windsurfrules` at project root — or Settings → Cascade → Custom Instructions |
|
|
124
|
+
| **Cursor** | `.cursorrules` at project root — or Settings → Rules for AI |
|
|
125
|
+
| **Claude Code** | `CLAUDE.md` at project root (auto-read every session) |
|
|
126
|
+
| **Continue.dev** | `config.json` → `models[].systemMessage` |
|
|
127
|
+
| **VS Code + Copilot** | `.github/copilot-instructions.md` at project root (auto-read by Copilot) |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Memory sections
|
|
132
|
+
|
|
133
|
+
| Section | What to store |
|
|
134
|
+
|---------|---------------|
|
|
135
|
+
| `project` | Tech stack, architecture, goals |
|
|
136
|
+
| `actions` | What was done, decisions made |
|
|
137
|
+
| `systems` | Services, modules, integrations |
|
|
138
|
+
| `requests` | User preferences, recurring asks |
|
|
139
|
+
| `user` | Name, style, expertise, preferences |
|
|
140
|
+
| `context` | Anything else relevant |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Commands
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
rememb init Initialize .rememb/ in current project
|
|
148
|
+
rememb write <text> Write a memory entry (--section, --tags)
|
|
149
|
+
rememb read Read all entries (--section, --agent, --raw)
|
|
150
|
+
rememb search <query> Semantic search (falls back to keyword)
|
|
151
|
+
rememb rules [editor] Print agent rules for windsurf/cursor/claude/continue
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## How search works
|
|
157
|
+
|
|
158
|
+
`rememb search` uses `sentence-transformers` for semantic similarity search locally.
|
|
159
|
+
No API calls. No embeddings sent to the cloud. Falls back to keyword search if the model isn't available.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Design principles
|
|
164
|
+
|
|
165
|
+
- **Local first** — everything is a JSON file in your project
|
|
166
|
+
- **Portable** — copy `.rememb/` and it works anywhere
|
|
167
|
+
- **Agnostic** — works with any agent that can run CLI commands
|
|
168
|
+
- **Zero config** — `pip install rememb && rememb init` and you're done
|
|
169
|
+
- **No lock-in** — plain JSON, read it with anything
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Roadmap
|
|
174
|
+
|
|
175
|
+
- [ ] MCP server (`rememb mcp`) for native IDE integration
|
|
176
|
+
- [ ] `rememb sync` — optional encrypted remote backup
|
|
177
|
+
- [ ] `rememb export` — export to Markdown, Obsidian, Notion
|
|
178
|
+
- [ ] VS Code / Windsurf extension
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Contributing
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
git clone https://github.com/LuizEduPP/rememb
|
|
186
|
+
cd rememb
|
|
187
|
+
pip install -e ".[dev]"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
PRs welcome. Issues welcome. Stars welcome. 🌟
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
demo/demo.gif
|
|
5
|
+
rules/claude.md
|
|
6
|
+
rules/continue.md
|
|
7
|
+
rules/cursor.md
|
|
8
|
+
rules/vscode.md
|
|
9
|
+
rules/windsurf.md
|
|
10
|
+
src/rememb/__init__.py
|
|
11
|
+
src/rememb/cli.py
|
|
12
|
+
src/rememb/store.py
|
|
13
|
+
src/rememb.egg-info/PKG-INFO
|
|
14
|
+
src/rememb.egg-info/SOURCES.txt
|
|
15
|
+
src/rememb.egg-info/dependency_links.txt
|
|
16
|
+
src/rememb.egg-info/entry_points.txt
|
|
17
|
+
src/rememb.egg-info/requires.txt
|
|
18
|
+
src/rememb.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rememb
|