universal-memory 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.
- universal_memory-0.1.0/PKG-INFO +195 -0
- universal_memory-0.1.0/README.md +178 -0
- universal_memory-0.1.0/pyproject.toml +56 -0
- universal_memory-0.1.0/src/universal_memory/__init__.py +8 -0
- universal_memory-0.1.0/src/universal_memory/__main__.py +4 -0
- universal_memory-0.1.0/src/universal_memory/application/__init__.py +1 -0
- universal_memory-0.1.0/src/universal_memory/application/host/__init__.py +25 -0
- universal_memory-0.1.0/src/universal_memory/application/host/drift_detector.py +93 -0
- universal_memory-0.1.0/src/universal_memory/application/host/setup_host_use_case.py +1153 -0
- universal_memory-0.1.0/src/universal_memory/application/host/sync_instructions_use_case.py +456 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/__init__.py +61 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/assemble_context_summary_use_case.py +360 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/context_hygiene_use_case.py +50 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/get_memory_status_use_case.py +217 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/list_facts_use_case.py +24 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/purge_fact_use_case.py +49 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/remember_fact_use_case.py +85 -0
- universal_memory-0.1.0/src/universal_memory/application/memory/search_facts_use_case.py +78 -0
- universal_memory-0.1.0/src/universal_memory/application/onboarding/__init__.py +8 -0
- universal_memory-0.1.0/src/universal_memory/application/onboarding/setup_project.py +302 -0
- universal_memory-0.1.0/src/universal_memory/application/security/__init__.py +43 -0
- universal_memory-0.1.0/src/universal_memory/application/security/list_audit_log_use_case.py +48 -0
- universal_memory-0.1.0/src/universal_memory/application/security/list_snapshots_use_case.py +57 -0
- universal_memory-0.1.0/src/universal_memory/application/security/rollback_use_case.py +195 -0
- universal_memory-0.1.0/src/universal_memory/application/security/safe_write_use_case.py +252 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/__init__.py +65 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/generate_skill.py +369 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/list_skills.py +315 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/native_skill_sync.py +312 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/propose_skill.py +203 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/track_latent_skill.py +148 -0
- universal_memory-0.1.0/src/universal_memory/application/skills/update_skill.py +602 -0
- universal_memory-0.1.0/src/universal_memory/application/update/__init__.py +25 -0
- universal_memory-0.1.0/src/universal_memory/application/update/update_use_cases.py +619 -0
- universal_memory-0.1.0/src/universal_memory/bootstrap/__init__.py +1 -0
- universal_memory-0.1.0/src/universal_memory/bootstrap/cli.py +286 -0
- universal_memory-0.1.0/src/universal_memory/bootstrap/mcp.py +213 -0
- universal_memory-0.1.0/src/universal_memory/domain/__init__.py +75 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/__init__.py +62 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/audit_event.py +37 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/base.py +46 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/context_summary.py +24 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/fact.py +28 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/host.py +48 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/instruction_target.py +89 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/latent_skill.py +26 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/rule.py +24 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/runtime.py +382 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/safe_write_result.py +8 -0
- universal_memory-0.1.0/src/universal_memory/domain/entities/snapshot.py +42 -0
- universal_memory-0.1.0/src/universal_memory/domain/exceptions.py +37 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/__init__.py +21 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/audit_log_repository.py +50 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/config_validation_port.py +11 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/context_summary_repository.py +50 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/fact_repository.py +106 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/latent_skill_repository.py +70 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/project_layout_port.py +16 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/rule_repository.py +60 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/secret_scanner_port.py +14 -0
- universal_memory-0.1.0/src/universal_memory/domain/ports/snapshot_repository.py +68 -0
- universal_memory-0.1.0/src/universal_memory/domain/project_layout.py +8 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/__init__.py +1 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/config/__init__.py +27 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/config/adapters.py +23 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/config/project_layout.py +122 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/config/toml_loader.py +221 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/security/__init__.py +11 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/security/entropy_secret_scanner.py +112 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/security/local_audit_log_repository.py +137 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/security/local_snapshot_repository.py +249 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/storage/__init__.py +15 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/storage/local_context_summary_repository.py +183 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/storage/local_fact_repository.py +433 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/storage/local_latent_skill_repository.py +347 -0
- universal_memory-0.1.0/src/universal_memory/infrastructure/storage/local_rule_repository.py +256 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/__init__.py +1 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/cli/__init__.py +3 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/cli/init_command.py +3617 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/cli/message_catalog.py +55 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/errors.py +208 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/mcp/__init__.py +7 -0
- universal_memory-0.1.0/src/universal_memory/interfaces/mcp/server.py +940 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: universal-memory
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Vendor-agnostic cognitive persistence layer for AI agents.
|
|
5
|
+
Author: Yan L. Amorelli
|
|
6
|
+
Author-email: Yan L. Amorelli <dev@amorelliaoyan.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Requires-Dist: fastmcp>=0.1.0
|
|
9
|
+
Requires-Dist: pydantic>=2.0
|
|
10
|
+
Requires-Dist: rich>=15.0.0
|
|
11
|
+
Requires-Dist: tomli-w>=1.0.0
|
|
12
|
+
Requires-Dist: typer>=0.9.0
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Project-URL: Homepage, https://github.com/YanAmorelli/universal-memory
|
|
15
|
+
Project-URL: Repository, https://github.com/YanAmorelli/universal-memory
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# Universal Memory (umem)
|
|
19
|
+
|
|
20
|
+
[](https://pypi.org/project/universal-memory/)
|
|
21
|
+
[](https://img.shields.io/project/universal-memory/)
|
|
22
|
+
[](https://opensource.org/licenses/MIT)
|
|
23
|
+
|
|
24
|
+
A vendor-agnostic cognitive persistence layer for AI agents. Eliminate the "repetition tax" by transporting your context, preferences, guidelines, and history seamlessly across sessions, IDEs, and LLM models.
|
|
25
|
+
|
|
26
|
+
To see the core idea visually, check out the [Excalidraw design](https://excalidraw.com/#json=j3XjQIWMYEnkIzHpypuBb,rNJaVOECDGZ3WSuEYcCDjQ) or the proposal structure:
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
### Diagram Breakdown (English Translation)
|
|
31
|
+
|
|
32
|
+
* **Short-Term Memory (Ephemeral):** Project-specific (folder-level) memories. A simple summary of recent changes, pending tasks, and project or task-level constraints.
|
|
33
|
+
* **Agents Behaviours:** Comports the user's expected agent behaviors. Instead of requesting the same settings in every session, the agent understands the user by their traits, thoughts, and any context key to enhancing the overall experience. This encompasses:
|
|
34
|
+
* **Long-Term Memory**
|
|
35
|
+
* **Short-Term Memory**
|
|
36
|
+
* **User Preferences**
|
|
37
|
+
* **Skill Creator:** Encapsulates understanding of specific workflows. When a user explains a task pattern multiple times, the system translates it into structured, reusable agent skills.
|
|
38
|
+
* **Unified Instruction File (`AGENT.MD`):** The shared persistence endpoint consumed by all local agent instances (e.g., Agent A, Agent B, Agent C).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## The Problem: The "Repetition Tax"
|
|
43
|
+
|
|
44
|
+
Every time you open a new session in Claude Code, start a new chat in Cursor, spin up a terminal with OpenCode, or invoke a local AI assistant, you pay a steep cognitive tax:
|
|
45
|
+
* Re-explaining your stack (e.g., "We use Python 3.12, Typer, and Ruff").
|
|
46
|
+
* Repeating coding style preferences (e.g., "Prefer functional design, do not write docstrings unless requested").
|
|
47
|
+
* Copy-pasting database connection schemas or module layouts.
|
|
48
|
+
* Explaining workflow methodologies (e.g., "We follow Spec-Driven Development (SDD)").
|
|
49
|
+
|
|
50
|
+
Universal Memory acts as a local "Cognitive USB Drive" that automatically connects to your AI runtimes, aligning them to your exact workflow, context, and rules with zero friction.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Key Architectural Concepts
|
|
55
|
+
|
|
56
|
+
### 1. Dual-Memory Model
|
|
57
|
+
* **Short-Term Memory (Project Scope):** Ephemeral, directory-specific context. Tracks what you did 10 minutes ago, current active tasks, and immediate constraints.
|
|
58
|
+
* **Universal Memory (Global Scope):** Long-lived preferences, style guidelines, tool configurations, and identity.
|
|
59
|
+
|
|
60
|
+
### 2. Auto-Adaptation Engine
|
|
61
|
+
Instead of copy-pasting instructions, `umem` monitors your session context and automatically updates active project instruction manifests (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, etc.), enforcing operational consistency across all agents.
|
|
62
|
+
|
|
63
|
+
### 3. Model Context Protocol (MCP) Integration
|
|
64
|
+
Integrate `umem` natively with any client supporting the standard MCP (such as Claude Desktop or Cursor). AI agents can programmatically retrieve context, learn new facts, and suggest skills on the fly.
|
|
65
|
+
|
|
66
|
+
### 4. Agent Skills Standard
|
|
67
|
+
Encapsulates complex, repetitive procedural instructions into formal Agent Skills (conforming to the [agentskills.io](https://agentskills.io) standard), complete with structured directories containing `SKILL.md` instructions, helper `scripts/`, and documentation `references/`.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Installation & Setup
|
|
72
|
+
|
|
73
|
+
Ensure you have Python 3.12+ installed. You can run or install `umem` using your preferred package manager.
|
|
74
|
+
|
|
75
|
+
### Run instantly with `uv` (Recommended)
|
|
76
|
+
You don't even need to install it permanently:
|
|
77
|
+
```bash
|
|
78
|
+
uvx umem --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Install via PyPI
|
|
82
|
+
```bash
|
|
83
|
+
pip install universal-memory
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Quick Start Guide
|
|
89
|
+
|
|
90
|
+
### 1. Initialize your project
|
|
91
|
+
Initialize `umem` in the current directory and hook it to your preferred runtimes/agents:
|
|
92
|
+
```bash
|
|
93
|
+
umem init --runtime claude-code --runtime opencode --runtime cursor
|
|
94
|
+
```
|
|
95
|
+
This sets up a local repository configuration, hooks up the necessary workspace instructions (`AGENTS.md`, `CLAUDE.md`), and prepares native skill folders.
|
|
96
|
+
|
|
97
|
+
### 2. Save your first preferences and facts
|
|
98
|
+
Tell `umem` what to keep in mind. You can target either the project scope (this folder) or the global scope (across all projects):
|
|
99
|
+
```bash
|
|
100
|
+
# Save a global preference
|
|
101
|
+
umem remember --scope global "Yan is a solutions architect specializing in AI applications"
|
|
102
|
+
|
|
103
|
+
# Save a project-specific constraint
|
|
104
|
+
umem remember --scope project "Always use Tomllib instead of PyYAML for configuration files" --tag config
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 3. Retrieve Context
|
|
108
|
+
Verify the consolidated context summary generated by combining short-term facts, rules, and global preferences:
|
|
109
|
+
```bash
|
|
110
|
+
umem context --scope project
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4. Check status and health
|
|
114
|
+
```bash
|
|
115
|
+
umem status
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Host Integration & Support Matrix
|
|
121
|
+
|
|
122
|
+
`umem` maps cognitive context and agent skills directly into native runtime paths:
|
|
123
|
+
|
|
124
|
+
| Runtime / Host | Support Tier | Config / Instructions Target |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| **Claude Code** | Tier 1 (Full) | `CLAUDE.md`, `.claude/`, `~/.claude/` |
|
|
127
|
+
| **OpenCode** | Tier 1 (Full) | `AGENTS.md`, `.opencode/`, `~/.config/opencode/` |
|
|
128
|
+
| **Codex (OpenAI)** | Tier 1 (Full) | `AGENTS.md`, workspace configuration files |
|
|
129
|
+
| **Cursor** | Tier 2 (Basic) | `.cursor/rules/`, `~/.cursor/` |
|
|
130
|
+
| **Antigravity / Gemini** | Tier 2 (Basic) | `GEMINI.md`, `~/.gemini/` |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Running as an Model Context Protocol (MCP) Server
|
|
135
|
+
|
|
136
|
+
AI agents can interact directly with your memory over the Model Context Protocol.
|
|
137
|
+
|
|
138
|
+
### CLI Launch Command
|
|
139
|
+
```bash
|
|
140
|
+
umem-mcp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Example Config: Claude Desktop (`claude_desktop_config.json`)
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"universal-memory": {
|
|
148
|
+
"command": "uv",
|
|
149
|
+
"args": [
|
|
150
|
+
"run",
|
|
151
|
+
"--package",
|
|
152
|
+
"universal-memory",
|
|
153
|
+
"umem-mcp"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Safety & Guardrails
|
|
163
|
+
|
|
164
|
+
* **API Secret Scanner:** `umem` passes all incoming facts through a passive scanner to block API keys, tokens, or credentials from being stored in your persistent cognitive base.
|
|
165
|
+
* **Snapshots & Rollbacks:** Every automated update to your config files (`AGENTS.md`, `CLAUDE.md`) is preceded by a snapshot backup. You can rollback anytime:
|
|
166
|
+
```bash
|
|
167
|
+
# View audit logs
|
|
168
|
+
umem audit list --scope project
|
|
169
|
+
|
|
170
|
+
# Revert last automated modification
|
|
171
|
+
umem rollback --scope project
|
|
172
|
+
```
|
|
173
|
+
* **Update Conflict Warnings:** When updating canonical skills, if `umem` detects manual edits in local runtime rule directories (e.g. `.cursor/rules/sdd-rules.md`), it prompts you interactivelly to choose whether to keep your local edits or overwrite them, preventing workflow disruption.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Managing Agent Skills
|
|
178
|
+
|
|
179
|
+
You can create, list, and sync specialized behaviors:
|
|
180
|
+
```bash
|
|
181
|
+
# List all active skills
|
|
182
|
+
umem skills list
|
|
183
|
+
|
|
184
|
+
# Synchronize skills into active native runtime folders
|
|
185
|
+
umem update --skills
|
|
186
|
+
|
|
187
|
+
# Generate a new skill template from a latent skill proposal
|
|
188
|
+
umem skills generate --name build-standard
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Universal Memory (umem)
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/universal-memory/)
|
|
4
|
+
[](https://img.shields.io/project/universal-memory/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
A vendor-agnostic cognitive persistence layer for AI agents. Eliminate the "repetition tax" by transporting your context, preferences, guidelines, and history seamlessly across sessions, IDEs, and LLM models.
|
|
8
|
+
|
|
9
|
+
To see the core idea visually, check out the [Excalidraw design](https://excalidraw.com/#json=j3XjQIWMYEnkIzHpypuBb,rNJaVOECDGZ3WSuEYcCDjQ) or the proposal structure:
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
### Diagram Breakdown (English Translation)
|
|
14
|
+
|
|
15
|
+
* **Short-Term Memory (Ephemeral):** Project-specific (folder-level) memories. A simple summary of recent changes, pending tasks, and project or task-level constraints.
|
|
16
|
+
* **Agents Behaviours:** Comports the user's expected agent behaviors. Instead of requesting the same settings in every session, the agent understands the user by their traits, thoughts, and any context key to enhancing the overall experience. This encompasses:
|
|
17
|
+
* **Long-Term Memory**
|
|
18
|
+
* **Short-Term Memory**
|
|
19
|
+
* **User Preferences**
|
|
20
|
+
* **Skill Creator:** Encapsulates understanding of specific workflows. When a user explains a task pattern multiple times, the system translates it into structured, reusable agent skills.
|
|
21
|
+
* **Unified Instruction File (`AGENT.MD`):** The shared persistence endpoint consumed by all local agent instances (e.g., Agent A, Agent B, Agent C).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## The Problem: The "Repetition Tax"
|
|
26
|
+
|
|
27
|
+
Every time you open a new session in Claude Code, start a new chat in Cursor, spin up a terminal with OpenCode, or invoke a local AI assistant, you pay a steep cognitive tax:
|
|
28
|
+
* Re-explaining your stack (e.g., "We use Python 3.12, Typer, and Ruff").
|
|
29
|
+
* Repeating coding style preferences (e.g., "Prefer functional design, do not write docstrings unless requested").
|
|
30
|
+
* Copy-pasting database connection schemas or module layouts.
|
|
31
|
+
* Explaining workflow methodologies (e.g., "We follow Spec-Driven Development (SDD)").
|
|
32
|
+
|
|
33
|
+
Universal Memory acts as a local "Cognitive USB Drive" that automatically connects to your AI runtimes, aligning them to your exact workflow, context, and rules with zero friction.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Key Architectural Concepts
|
|
38
|
+
|
|
39
|
+
### 1. Dual-Memory Model
|
|
40
|
+
* **Short-Term Memory (Project Scope):** Ephemeral, directory-specific context. Tracks what you did 10 minutes ago, current active tasks, and immediate constraints.
|
|
41
|
+
* **Universal Memory (Global Scope):** Long-lived preferences, style guidelines, tool configurations, and identity.
|
|
42
|
+
|
|
43
|
+
### 2. Auto-Adaptation Engine
|
|
44
|
+
Instead of copy-pasting instructions, `umem` monitors your session context and automatically updates active project instruction manifests (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, etc.), enforcing operational consistency across all agents.
|
|
45
|
+
|
|
46
|
+
### 3. Model Context Protocol (MCP) Integration
|
|
47
|
+
Integrate `umem` natively with any client supporting the standard MCP (such as Claude Desktop or Cursor). AI agents can programmatically retrieve context, learn new facts, and suggest skills on the fly.
|
|
48
|
+
|
|
49
|
+
### 4. Agent Skills Standard
|
|
50
|
+
Encapsulates complex, repetitive procedural instructions into formal Agent Skills (conforming to the [agentskills.io](https://agentskills.io) standard), complete with structured directories containing `SKILL.md` instructions, helper `scripts/`, and documentation `references/`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Installation & Setup
|
|
55
|
+
|
|
56
|
+
Ensure you have Python 3.12+ installed. You can run or install `umem` using your preferred package manager.
|
|
57
|
+
|
|
58
|
+
### Run instantly with `uv` (Recommended)
|
|
59
|
+
You don't even need to install it permanently:
|
|
60
|
+
```bash
|
|
61
|
+
uvx umem --help
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Install via PyPI
|
|
65
|
+
```bash
|
|
66
|
+
pip install universal-memory
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quick Start Guide
|
|
72
|
+
|
|
73
|
+
### 1. Initialize your project
|
|
74
|
+
Initialize `umem` in the current directory and hook it to your preferred runtimes/agents:
|
|
75
|
+
```bash
|
|
76
|
+
umem init --runtime claude-code --runtime opencode --runtime cursor
|
|
77
|
+
```
|
|
78
|
+
This sets up a local repository configuration, hooks up the necessary workspace instructions (`AGENTS.md`, `CLAUDE.md`), and prepares native skill folders.
|
|
79
|
+
|
|
80
|
+
### 2. Save your first preferences and facts
|
|
81
|
+
Tell `umem` what to keep in mind. You can target either the project scope (this folder) or the global scope (across all projects):
|
|
82
|
+
```bash
|
|
83
|
+
# Save a global preference
|
|
84
|
+
umem remember --scope global "Yan is a solutions architect specializing in AI applications"
|
|
85
|
+
|
|
86
|
+
# Save a project-specific constraint
|
|
87
|
+
umem remember --scope project "Always use Tomllib instead of PyYAML for configuration files" --tag config
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3. Retrieve Context
|
|
91
|
+
Verify the consolidated context summary generated by combining short-term facts, rules, and global preferences:
|
|
92
|
+
```bash
|
|
93
|
+
umem context --scope project
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Check status and health
|
|
97
|
+
```bash
|
|
98
|
+
umem status
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Host Integration & Support Matrix
|
|
104
|
+
|
|
105
|
+
`umem` maps cognitive context and agent skills directly into native runtime paths:
|
|
106
|
+
|
|
107
|
+
| Runtime / Host | Support Tier | Config / Instructions Target |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| **Claude Code** | Tier 1 (Full) | `CLAUDE.md`, `.claude/`, `~/.claude/` |
|
|
110
|
+
| **OpenCode** | Tier 1 (Full) | `AGENTS.md`, `.opencode/`, `~/.config/opencode/` |
|
|
111
|
+
| **Codex (OpenAI)** | Tier 1 (Full) | `AGENTS.md`, workspace configuration files |
|
|
112
|
+
| **Cursor** | Tier 2 (Basic) | `.cursor/rules/`, `~/.cursor/` |
|
|
113
|
+
| **Antigravity / Gemini** | Tier 2 (Basic) | `GEMINI.md`, `~/.gemini/` |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Running as an Model Context Protocol (MCP) Server
|
|
118
|
+
|
|
119
|
+
AI agents can interact directly with your memory over the Model Context Protocol.
|
|
120
|
+
|
|
121
|
+
### CLI Launch Command
|
|
122
|
+
```bash
|
|
123
|
+
umem-mcp
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Example Config: Claude Desktop (`claude_desktop_config.json`)
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"mcpServers": {
|
|
130
|
+
"universal-memory": {
|
|
131
|
+
"command": "uv",
|
|
132
|
+
"args": [
|
|
133
|
+
"run",
|
|
134
|
+
"--package",
|
|
135
|
+
"universal-memory",
|
|
136
|
+
"umem-mcp"
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Safety & Guardrails
|
|
146
|
+
|
|
147
|
+
* **API Secret Scanner:** `umem` passes all incoming facts through a passive scanner to block API keys, tokens, or credentials from being stored in your persistent cognitive base.
|
|
148
|
+
* **Snapshots & Rollbacks:** Every automated update to your config files (`AGENTS.md`, `CLAUDE.md`) is preceded by a snapshot backup. You can rollback anytime:
|
|
149
|
+
```bash
|
|
150
|
+
# View audit logs
|
|
151
|
+
umem audit list --scope project
|
|
152
|
+
|
|
153
|
+
# Revert last automated modification
|
|
154
|
+
umem rollback --scope project
|
|
155
|
+
```
|
|
156
|
+
* **Update Conflict Warnings:** When updating canonical skills, if `umem` detects manual edits in local runtime rule directories (e.g. `.cursor/rules/sdd-rules.md`), it prompts you interactivelly to choose whether to keep your local edits or overwrite them, preventing workflow disruption.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Managing Agent Skills
|
|
161
|
+
|
|
162
|
+
You can create, list, and sync specialized behaviors:
|
|
163
|
+
```bash
|
|
164
|
+
# List all active skills
|
|
165
|
+
umem skills list
|
|
166
|
+
|
|
167
|
+
# Synchronize skills into active native runtime folders
|
|
168
|
+
umem update --skills
|
|
169
|
+
|
|
170
|
+
# Generate a new skill template from a latent skill proposal
|
|
171
|
+
umem skills generate --name build-standard
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "universal-memory"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Vendor-agnostic cognitive persistence layer for AI agents."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Yan L. Amorelli", email = "dev@amorelliaoyan.com" }
|
|
9
|
+
]
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"fastmcp>=0.1.0",
|
|
13
|
+
"pydantic>=2.0",
|
|
14
|
+
"rich>=15.0.0",
|
|
15
|
+
"tomli-w>=1.0.0",
|
|
16
|
+
"typer>=0.9.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/YanAmorelli/universal-memory"
|
|
21
|
+
Repository = "https://github.com/YanAmorelli/universal-memory"
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
umem = "universal_memory.bootstrap.cli:main"
|
|
25
|
+
universal-memory = "universal_memory.bootstrap.cli:main"
|
|
26
|
+
umem-mcp = "universal_memory.bootstrap.mcp:main"
|
|
27
|
+
|
|
28
|
+
[dependency-groups]
|
|
29
|
+
dev = [
|
|
30
|
+
"pyright>=1.1.350",
|
|
31
|
+
"pytest>=8.0.0",
|
|
32
|
+
"ruff>=0.3.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["uv_build>=0.11.7,<0.12.0"]
|
|
37
|
+
build-backend = "uv_build"
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
target-version = "py312"
|
|
41
|
+
line-length = 100
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = ["E", "F", "I", "N", "UP", "PL", "RUF", "B", "S"]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint.per-file-ignores]
|
|
47
|
+
"tests/**/*.py" = ["S101"]
|
|
48
|
+
"src/universal_memory/interfaces/cli/init_command.py" = ["E501"]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
[tool.pyright]
|
|
52
|
+
include = ["src", "tests", "benchmarks"]
|
|
53
|
+
pythonVersion = "3.12"
|
|
54
|
+
typeCheckingMode = "standard"
|
|
55
|
+
venvPath = "."
|
|
56
|
+
venv = ".venv"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Application layer for universal-memory."""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from universal_memory.application.host.setup_host_use_case import (
|
|
2
|
+
ConfigureHostCommand,
|
|
3
|
+
ConfigureHostResult,
|
|
4
|
+
ConfigureHostUseCase,
|
|
5
|
+
InstructionBlock,
|
|
6
|
+
InstructionPartition,
|
|
7
|
+
partition_instruction_blocks,
|
|
8
|
+
)
|
|
9
|
+
from universal_memory.application.host.sync_instructions_use_case import (
|
|
10
|
+
SyncInstructionsCommand,
|
|
11
|
+
SyncInstructionsResult,
|
|
12
|
+
SyncInstructionsUseCase,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ConfigureHostCommand",
|
|
17
|
+
"ConfigureHostResult",
|
|
18
|
+
"ConfigureHostUseCase",
|
|
19
|
+
"InstructionBlock",
|
|
20
|
+
"InstructionPartition",
|
|
21
|
+
"SyncInstructionsCommand",
|
|
22
|
+
"SyncInstructionsResult",
|
|
23
|
+
"SyncInstructionsUseCase",
|
|
24
|
+
"partition_instruction_blocks",
|
|
25
|
+
]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class InstructionDriftDetector:
|
|
7
|
+
def detect(self, *, agents_content: str, claude_content: str) -> list[str]:
|
|
8
|
+
if not agents_content or not claude_content:
|
|
9
|
+
return []
|
|
10
|
+
agents_lines = _instruction_lines(agents_content)
|
|
11
|
+
claude_lines = _instruction_lines(claude_content)
|
|
12
|
+
warnings: list[str] = []
|
|
13
|
+
|
|
14
|
+
agents_by_normalized = {_normalize_line(line): line for line in agents_lines}
|
|
15
|
+
for claude_line in claude_lines:
|
|
16
|
+
normalized = _normalize_line(claude_line)
|
|
17
|
+
if normalized in agents_by_normalized:
|
|
18
|
+
warnings.append(
|
|
19
|
+
"Instrucao duplicada em AGENTS.md e CLAUDE.md: "
|
|
20
|
+
f"{agents_by_normalized[normalized]}"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
contradiction_warnings = _detect_always_never_contradictions(
|
|
24
|
+
agents_lines,
|
|
25
|
+
claude_lines,
|
|
26
|
+
)
|
|
27
|
+
warnings.extend(contradiction_warnings)
|
|
28
|
+
return warnings
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _instruction_lines(content: str) -> list[str]:
|
|
32
|
+
lines: list[str] = []
|
|
33
|
+
for raw_line in content.splitlines():
|
|
34
|
+
line = raw_line.strip()
|
|
35
|
+
if not line or "<!--" in line or "-->" in line or line.startswith(("#", ">")):
|
|
36
|
+
continue
|
|
37
|
+
line = re.sub(r"^[-*]\s*", "", line)
|
|
38
|
+
line = re.sub(r"^\([a-z_-]+\)\s*", "", line).strip()
|
|
39
|
+
if line:
|
|
40
|
+
lines.append(line)
|
|
41
|
+
return lines
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _normalize_line(line: str) -> str:
|
|
45
|
+
return re.sub(r"\s+", " ", line).strip().rstrip(".").casefold()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _detect_always_never_contradictions(
|
|
49
|
+
agents_lines: list[str],
|
|
50
|
+
claude_lines: list[str],
|
|
51
|
+
) -> list[str]:
|
|
52
|
+
warnings: list[str] = []
|
|
53
|
+
agents_norms = [_normalize_line(line) for line in agents_lines]
|
|
54
|
+
agents_rules = {}
|
|
55
|
+
for line, norm in zip(agents_lines, agents_norms, strict=True):
|
|
56
|
+
if _rule_polarity(norm):
|
|
57
|
+
body = _rule_body(norm)
|
|
58
|
+
if body:
|
|
59
|
+
agents_rules[body] = (line, norm)
|
|
60
|
+
|
|
61
|
+
for claude_line in claude_lines:
|
|
62
|
+
norm = _normalize_line(claude_line)
|
|
63
|
+
claude_polarity = _rule_polarity(norm)
|
|
64
|
+
if claude_polarity is None:
|
|
65
|
+
continue
|
|
66
|
+
body = _rule_body(norm)
|
|
67
|
+
if not body:
|
|
68
|
+
continue
|
|
69
|
+
matched = agents_rules.get(body)
|
|
70
|
+
if matched is None:
|
|
71
|
+
continue
|
|
72
|
+
agents_line, agents_norm = matched
|
|
73
|
+
agents_polarity = _rule_polarity(agents_norm)
|
|
74
|
+
if agents_polarity != claude_polarity:
|
|
75
|
+
warnings.append(
|
|
76
|
+
f"Contradicao explicita entre AGENTS.md e CLAUDE.md: {agents_line} / {claude_line}"
|
|
77
|
+
)
|
|
78
|
+
return warnings
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _rule_polarity(normalized: str) -> str | None:
|
|
82
|
+
if normalized.startswith(("always ", "sempre ")):
|
|
83
|
+
return "positive"
|
|
84
|
+
if normalized.startswith(("never ", "nunca ")):
|
|
85
|
+
return "negative"
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _rule_body(normalized: str) -> str:
|
|
90
|
+
for prefix in ("always ", "never ", "sempre ", "nunca "):
|
|
91
|
+
if normalized.startswith(prefix):
|
|
92
|
+
return normalized.removeprefix(prefix)
|
|
93
|
+
return normalized
|