muscle-memory 0.2.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.
- muscle_memory-0.2.0/.gitignore +80 -0
- muscle_memory-0.2.0/LICENSE +21 -0
- muscle_memory-0.2.0/PKG-INFO +174 -0
- muscle_memory-0.2.0/README.md +136 -0
- muscle_memory-0.2.0/pyproject.toml +116 -0
- muscle_memory-0.2.0/src/muscle_memory/__init__.py +24 -0
- muscle_memory-0.2.0/src/muscle_memory/__main__.py +6 -0
- muscle_memory-0.2.0/src/muscle_memory/bootstrap.py +171 -0
- muscle_memory-0.2.0/src/muscle_memory/cli.py +717 -0
- muscle_memory-0.2.0/src/muscle_memory/config.py +165 -0
- muscle_memory-0.2.0/src/muscle_memory/db.py +544 -0
- muscle_memory-0.2.0/src/muscle_memory/dedup.py +153 -0
- muscle_memory-0.2.0/src/muscle_memory/embeddings.py +136 -0
- muscle_memory-0.2.0/src/muscle_memory/extractor.py +211 -0
- muscle_memory-0.2.0/src/muscle_memory/hooks/__init__.py +5 -0
- muscle_memory-0.2.0/src/muscle_memory/hooks/install.py +182 -0
- muscle_memory-0.2.0/src/muscle_memory/hooks/stop.py +258 -0
- muscle_memory-0.2.0/src/muscle_memory/hooks/user_prompt.py +238 -0
- muscle_memory-0.2.0/src/muscle_memory/llm.py +278 -0
- muscle_memory-0.2.0/src/muscle_memory/models.py +189 -0
- muscle_memory-0.2.0/src/muscle_memory/outcomes.py +214 -0
- muscle_memory-0.2.0/src/muscle_memory/prompts/__init__.py +1 -0
- muscle_memory-0.2.0/src/muscle_memory/prompts/extract.md +113 -0
- muscle_memory-0.2.0/src/muscle_memory/prompts/refine_gradient.md +87 -0
- muscle_memory-0.2.0/src/muscle_memory/prompts/refine_judge.md +70 -0
- muscle_memory-0.2.0/src/muscle_memory/prompts/refine_rewrite.md +53 -0
- muscle_memory-0.2.0/src/muscle_memory/refine.py +535 -0
- muscle_memory-0.2.0/src/muscle_memory/retriever.py +106 -0
- muscle_memory-0.2.0/src/muscle_memory/scorer.py +94 -0
- muscle_memory-0.2.0/tests/conftest.py +76 -0
- muscle_memory-0.2.0/tests/test_behavioral.py +502 -0
- muscle_memory-0.2.0/tests/test_db.py +107 -0
- muscle_memory-0.2.0/tests/test_dedup.py +189 -0
- muscle_memory-0.2.0/tests/test_edge_cases.py +478 -0
- muscle_memory-0.2.0/tests/test_extractor.py +229 -0
- muscle_memory-0.2.0/tests/test_integration.py +674 -0
- muscle_memory-0.2.0/tests/test_models.py +99 -0
- muscle_memory-0.2.0/tests/test_outcomes.py +138 -0
- muscle_memory-0.2.0/tests/test_refine.py +567 -0
- muscle_memory-0.2.0/tests/test_retriever.py +107 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
MANIFEST
|
|
23
|
+
|
|
24
|
+
# Virtual environments
|
|
25
|
+
.venv/
|
|
26
|
+
venv/
|
|
27
|
+
env/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# uv
|
|
31
|
+
.uv/
|
|
32
|
+
|
|
33
|
+
# Testing
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
htmlcov/
|
|
38
|
+
.tox/
|
|
39
|
+
.nox/
|
|
40
|
+
coverage.xml
|
|
41
|
+
*.cover
|
|
42
|
+
.hypothesis/
|
|
43
|
+
|
|
44
|
+
# Type checking
|
|
45
|
+
.mypy_cache/
|
|
46
|
+
.dmypy.json
|
|
47
|
+
dmypy.json
|
|
48
|
+
.pyright/
|
|
49
|
+
.pytype/
|
|
50
|
+
|
|
51
|
+
# Linting
|
|
52
|
+
.ruff_cache/
|
|
53
|
+
|
|
54
|
+
# IDEs
|
|
55
|
+
.vscode/
|
|
56
|
+
.idea/
|
|
57
|
+
*.swp
|
|
58
|
+
*.swo
|
|
59
|
+
*~
|
|
60
|
+
.DS_Store
|
|
61
|
+
|
|
62
|
+
# muscle-memory runtime artifacts
|
|
63
|
+
.claude/mm.db
|
|
64
|
+
.claude/mm.db-*
|
|
65
|
+
.claude/mm.activations/
|
|
66
|
+
.claude/mm.extract_queue.txt
|
|
67
|
+
.claude/settings.json
|
|
68
|
+
*.mm.db
|
|
69
|
+
*.mm.db-*
|
|
70
|
+
|
|
71
|
+
# Local env
|
|
72
|
+
.env
|
|
73
|
+
.env.*
|
|
74
|
+
!.env.example
|
|
75
|
+
|
|
76
|
+
# Logs
|
|
77
|
+
*.log
|
|
78
|
+
|
|
79
|
+
# Claude Code session state (don't commit personal sessions)
|
|
80
|
+
.claude/projects/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Azhar Anwar
|
|
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,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: muscle-memory
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Procedural memory for coding agents. Your past sessions, compiled.
|
|
5
|
+
Project-URL: Homepage, https://github.com/iamazhar/muscle-memory
|
|
6
|
+
Project-URL: Repository, https://github.com/iamazhar/muscle-memory
|
|
7
|
+
Project-URL: Issues, https://github.com/iamazhar/muscle-memory/issues
|
|
8
|
+
Author-email: Azhar Anwar <azharcodes@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,anthropic,claude-code,llm,memory,procedural-memory,procmem,skills
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: anthropic>=0.40
|
|
22
|
+
Requires-Dist: fastembed>=0.4
|
|
23
|
+
Requires-Dist: platformdirs>=4.2
|
|
24
|
+
Requires-Dist: pydantic>=2.6
|
|
25
|
+
Requires-Dist: rich>=13.7
|
|
26
|
+
Requires-Dist: sqlite-vec>=0.1.6
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
33
|
+
Provides-Extra: openai
|
|
34
|
+
Requires-Dist: openai>=1.40; extra == 'openai'
|
|
35
|
+
Provides-Extra: voyage
|
|
36
|
+
Requires-Dist: voyageai>=0.2; extra == 'voyage'
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="docs/assets/hero.png" alt="Pixel art of a vintage CRT monitor with a tiny brain character flexing a bicep on its amber phosphor screen" width="720">
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<h1 align="center">muscle-memory</h1>
|
|
44
|
+
|
|
45
|
+
<p align="center">
|
|
46
|
+
<em>Procedural memory for coding agents. Your past sessions, compiled.</em>
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
`muscle-memory` gives Claude Code a memory that actually compounds. Instead of dumping prose into `CLAUDE.md` files that bloat every context, it watches your sessions, extracts reusable **Skills** — executable playbooks with activation conditions, steps, and termination criteria — and retrieves the right ones on demand when you start a new task.
|
|
51
|
+
|
|
52
|
+
Inspired by [ProcMEM (arxiv:2602.01869)](https://arxiv.org/abs/2602.01869), but purpose-built for coding agents.
|
|
53
|
+
|
|
54
|
+
## The problem
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Session 1: Figure out the monorepo's weird test runner (15 min)
|
|
58
|
+
Session 2: Figure it out again (15 min)
|
|
59
|
+
Session 3: Add a note to CLAUDE.md (2 min, bloats future context)
|
|
60
|
+
Session 50: CLAUDE.md is 4000 lines, half stale, nobody reads it
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What muscle-memory does instead
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Session 1: Figure out the test runner (15 min) → extractor creates a Skill
|
|
67
|
+
Session 2: "run the tests" → Skill activates automatically, zero rediscovery
|
|
68
|
+
Session 5: Skill gets refined from more examples
|
|
69
|
+
Session 20: Skill has been invoked 18x, 17 successes → promoted to "proven"
|
|
70
|
+
Session 50: Unused skills auto-pruned, active ones keep improving
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Skills are **on-demand** (not always in context), **execution-scored** (good ones survive, bad ones die), and **user-editable** (plain text, no opaque embeddings).
|
|
74
|
+
|
|
75
|
+
## Quickstart
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# install (Anthropic default)
|
|
79
|
+
uv tool install muscle-memory
|
|
80
|
+
|
|
81
|
+
# or with OpenAI support baked in
|
|
82
|
+
uv tool install 'muscle-memory[openai]'
|
|
83
|
+
|
|
84
|
+
# in your project
|
|
85
|
+
cd ~/code/my-project
|
|
86
|
+
mm init # creates .claude/mm.db, registers Claude Code hooks
|
|
87
|
+
|
|
88
|
+
# optional: bootstrap from recent history
|
|
89
|
+
mm bootstrap --days 30
|
|
90
|
+
|
|
91
|
+
# now just use Claude Code normally.
|
|
92
|
+
# skills accumulate automatically.
|
|
93
|
+
|
|
94
|
+
# inspect what you've learned
|
|
95
|
+
mm list
|
|
96
|
+
mm show <skill-id>
|
|
97
|
+
mm stats
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Authentication
|
|
101
|
+
|
|
102
|
+
`muscle-memory` needs an LLM for skill extraction (runs after each session,
|
|
103
|
+
not on every prompt). **It cannot reuse your Claude Code subscription auth**
|
|
104
|
+
— that's a known limitation; Anthropic does not currently expose a
|
|
105
|
+
subscription-capable SDK for third-party tools.
|
|
106
|
+
|
|
107
|
+
Your options:
|
|
108
|
+
|
|
109
|
+
| Provider | Setup | Cost |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| **Anthropic** (default) | `export ANTHROPIC_API_KEY=sk-ant-...` — **needs API credits, not a Max/Pro subscription** | ~$0.001 / session with Haiku 4.5 |
|
|
112
|
+
| **OpenAI** | `export OPENAI_API_KEY=sk-...` and `export MM_LLM_PROVIDER=openai` | ~$0.0005 / session with gpt-4o-mini |
|
|
113
|
+
| **Local / Ollama** | *(planned, not yet implemented)* | free |
|
|
114
|
+
|
|
115
|
+
If you already use Claude Code via a Max/Pro subscription, you'll still
|
|
116
|
+
need a separate Anthropic API key with billing credits, or use OpenAI.
|
|
117
|
+
See [docs/authentication.md](docs/authentication.md) for details.
|
|
118
|
+
|
|
119
|
+
## How it works
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
┌──────────────────────────────────────────────────────┐
|
|
123
|
+
│ Claude Code Session │
|
|
124
|
+
│ │
|
|
125
|
+
│ user prompt ─┐ │
|
|
126
|
+
│ ▼ │
|
|
127
|
+
│ ┌───────────────┐ top skills │
|
|
128
|
+
│ │ Retriever │────────────► inject context │
|
|
129
|
+
│ │ (embedding) │ │
|
|
130
|
+
│ └───────────────┘ │
|
|
131
|
+
│ │ │
|
|
132
|
+
│ ▼ │
|
|
133
|
+
│ [ LLM executes with Skill hints ] │
|
|
134
|
+
│ │ │
|
|
135
|
+
│ ▼ │
|
|
136
|
+
│ ┌───────────────┐ │
|
|
137
|
+
│ │ Extractor │ proposes new Skills │
|
|
138
|
+
│ │ (async) │ │
|
|
139
|
+
│ └───────┬───────┘ │
|
|
140
|
+
│ │ │
|
|
141
|
+
│ ▼ │
|
|
142
|
+
│ ┌────────────────────┐ │
|
|
143
|
+
│ │ Scorer │ updates / prunes │
|
|
144
|
+
│ └────────────────────┘ │
|
|
145
|
+
│ │ │
|
|
146
|
+
│ ▼ │
|
|
147
|
+
│ ┌────────────────────┐ │
|
|
148
|
+
│ │ SQLite + vec │ │
|
|
149
|
+
│ └────────────────────┘ │
|
|
150
|
+
└──────────────────────────────────────────────────────┘
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Skill anatomy
|
|
154
|
+
|
|
155
|
+
Each Skill is three editable text fields:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"activation": "When pytest fails with ModuleNotFoundError in this monorepo",
|
|
160
|
+
"execution": "1. Check if tools/test-runner.sh exists.\n2. If yes, use it instead of invoking pytest directly.\n3. Set PYTEST_ADDOPTS=--no-cov for speed.",
|
|
161
|
+
"termination": "Tests pass, or runner is confirmed missing",
|
|
162
|
+
"tool_hints": ["Bash: tools/test-runner.sh"]
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
No DSL. No code templates. Plain English that the agent reads and executes with judgment.
|
|
167
|
+
|
|
168
|
+
## Status
|
|
169
|
+
|
|
170
|
+
**Alpha.** Core extraction + retrieval + scoring are working. The Non-Parametric PPO refinement loop from the paper is planned for v2.
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/hero.png" alt="Pixel art of a vintage CRT monitor with a tiny brain character flexing a bicep on its amber phosphor screen" width="720">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">muscle-memory</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<em>Procedural memory for coding agents. Your past sessions, compiled.</em>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
`muscle-memory` gives Claude Code a memory that actually compounds. Instead of dumping prose into `CLAUDE.md` files that bloat every context, it watches your sessions, extracts reusable **Skills** — executable playbooks with activation conditions, steps, and termination criteria — and retrieves the right ones on demand when you start a new task.
|
|
13
|
+
|
|
14
|
+
Inspired by [ProcMEM (arxiv:2602.01869)](https://arxiv.org/abs/2602.01869), but purpose-built for coding agents.
|
|
15
|
+
|
|
16
|
+
## The problem
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Session 1: Figure out the monorepo's weird test runner (15 min)
|
|
20
|
+
Session 2: Figure it out again (15 min)
|
|
21
|
+
Session 3: Add a note to CLAUDE.md (2 min, bloats future context)
|
|
22
|
+
Session 50: CLAUDE.md is 4000 lines, half stale, nobody reads it
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What muscle-memory does instead
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Session 1: Figure out the test runner (15 min) → extractor creates a Skill
|
|
29
|
+
Session 2: "run the tests" → Skill activates automatically, zero rediscovery
|
|
30
|
+
Session 5: Skill gets refined from more examples
|
|
31
|
+
Session 20: Skill has been invoked 18x, 17 successes → promoted to "proven"
|
|
32
|
+
Session 50: Unused skills auto-pruned, active ones keep improving
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Skills are **on-demand** (not always in context), **execution-scored** (good ones survive, bad ones die), and **user-editable** (plain text, no opaque embeddings).
|
|
36
|
+
|
|
37
|
+
## Quickstart
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# install (Anthropic default)
|
|
41
|
+
uv tool install muscle-memory
|
|
42
|
+
|
|
43
|
+
# or with OpenAI support baked in
|
|
44
|
+
uv tool install 'muscle-memory[openai]'
|
|
45
|
+
|
|
46
|
+
# in your project
|
|
47
|
+
cd ~/code/my-project
|
|
48
|
+
mm init # creates .claude/mm.db, registers Claude Code hooks
|
|
49
|
+
|
|
50
|
+
# optional: bootstrap from recent history
|
|
51
|
+
mm bootstrap --days 30
|
|
52
|
+
|
|
53
|
+
# now just use Claude Code normally.
|
|
54
|
+
# skills accumulate automatically.
|
|
55
|
+
|
|
56
|
+
# inspect what you've learned
|
|
57
|
+
mm list
|
|
58
|
+
mm show <skill-id>
|
|
59
|
+
mm stats
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Authentication
|
|
63
|
+
|
|
64
|
+
`muscle-memory` needs an LLM for skill extraction (runs after each session,
|
|
65
|
+
not on every prompt). **It cannot reuse your Claude Code subscription auth**
|
|
66
|
+
— that's a known limitation; Anthropic does not currently expose a
|
|
67
|
+
subscription-capable SDK for third-party tools.
|
|
68
|
+
|
|
69
|
+
Your options:
|
|
70
|
+
|
|
71
|
+
| Provider | Setup | Cost |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| **Anthropic** (default) | `export ANTHROPIC_API_KEY=sk-ant-...` — **needs API credits, not a Max/Pro subscription** | ~$0.001 / session with Haiku 4.5 |
|
|
74
|
+
| **OpenAI** | `export OPENAI_API_KEY=sk-...` and `export MM_LLM_PROVIDER=openai` | ~$0.0005 / session with gpt-4o-mini |
|
|
75
|
+
| **Local / Ollama** | *(planned, not yet implemented)* | free |
|
|
76
|
+
|
|
77
|
+
If you already use Claude Code via a Max/Pro subscription, you'll still
|
|
78
|
+
need a separate Anthropic API key with billing credits, or use OpenAI.
|
|
79
|
+
See [docs/authentication.md](docs/authentication.md) for details.
|
|
80
|
+
|
|
81
|
+
## How it works
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
┌──────────────────────────────────────────────────────┐
|
|
85
|
+
│ Claude Code Session │
|
|
86
|
+
│ │
|
|
87
|
+
│ user prompt ─┐ │
|
|
88
|
+
│ ▼ │
|
|
89
|
+
│ ┌───────────────┐ top skills │
|
|
90
|
+
│ │ Retriever │────────────► inject context │
|
|
91
|
+
│ │ (embedding) │ │
|
|
92
|
+
│ └───────────────┘ │
|
|
93
|
+
│ │ │
|
|
94
|
+
│ ▼ │
|
|
95
|
+
│ [ LLM executes with Skill hints ] │
|
|
96
|
+
│ │ │
|
|
97
|
+
│ ▼ │
|
|
98
|
+
│ ┌───────────────┐ │
|
|
99
|
+
│ │ Extractor │ proposes new Skills │
|
|
100
|
+
│ │ (async) │ │
|
|
101
|
+
│ └───────┬───────┘ │
|
|
102
|
+
│ │ │
|
|
103
|
+
│ ▼ │
|
|
104
|
+
│ ┌────────────────────┐ │
|
|
105
|
+
│ │ Scorer │ updates / prunes │
|
|
106
|
+
│ └────────────────────┘ │
|
|
107
|
+
│ │ │
|
|
108
|
+
│ ▼ │
|
|
109
|
+
│ ┌────────────────────┐ │
|
|
110
|
+
│ │ SQLite + vec │ │
|
|
111
|
+
│ └────────────────────┘ │
|
|
112
|
+
└──────────────────────────────────────────────────────┘
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Skill anatomy
|
|
116
|
+
|
|
117
|
+
Each Skill is three editable text fields:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"activation": "When pytest fails with ModuleNotFoundError in this monorepo",
|
|
122
|
+
"execution": "1. Check if tools/test-runner.sh exists.\n2. If yes, use it instead of invoking pytest directly.\n3. Set PYTEST_ADDOPTS=--no-cov for speed.",
|
|
123
|
+
"termination": "Tests pass, or runner is confirmed missing",
|
|
124
|
+
"tool_hints": ["Bash: tools/test-runner.sh"]
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
No DSL. No code templates. Plain English that the agent reads and executes with judgment.
|
|
129
|
+
|
|
130
|
+
## Status
|
|
131
|
+
|
|
132
|
+
**Alpha.** Core extraction + retrieval + scoring are working. The Non-Parametric PPO refinement loop from the paper is planned for v2.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "muscle-memory"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "Procedural memory for coding agents. Your past sessions, compiled."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Azhar Anwar", email = "azharcodes@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
keywords = [
|
|
12
|
+
"llm",
|
|
13
|
+
"claude-code",
|
|
14
|
+
"agent",
|
|
15
|
+
"memory",
|
|
16
|
+
"procedural-memory",
|
|
17
|
+
"procmem",
|
|
18
|
+
"skills",
|
|
19
|
+
"anthropic",
|
|
20
|
+
]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 3 - Alpha",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"License :: OSI Approved :: MIT License",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Programming Language :: Python :: 3.13",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"typer>=0.12",
|
|
33
|
+
"rich>=13.7",
|
|
34
|
+
"pydantic>=2.6",
|
|
35
|
+
"sqlite-vec>=0.1.6",
|
|
36
|
+
"anthropic>=0.40",
|
|
37
|
+
"fastembed>=0.4",
|
|
38
|
+
"platformdirs>=4.2",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
dev = [
|
|
43
|
+
"pytest>=8.0",
|
|
44
|
+
"pytest-asyncio>=0.23",
|
|
45
|
+
"ruff>=0.6",
|
|
46
|
+
"mypy>=1.10",
|
|
47
|
+
]
|
|
48
|
+
openai = ["openai>=1.40"]
|
|
49
|
+
voyage = ["voyageai>=0.2"]
|
|
50
|
+
|
|
51
|
+
[project.scripts]
|
|
52
|
+
mm = "muscle_memory.cli:app"
|
|
53
|
+
muscle-memory = "muscle_memory.cli:app"
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/iamazhar/muscle-memory"
|
|
57
|
+
Repository = "https://github.com/iamazhar/muscle-memory"
|
|
58
|
+
Issues = "https://github.com/iamazhar/muscle-memory/issues"
|
|
59
|
+
|
|
60
|
+
[build-system]
|
|
61
|
+
requires = ["hatchling"]
|
|
62
|
+
build-backend = "hatchling.build"
|
|
63
|
+
|
|
64
|
+
[tool.hatch.build.targets.wheel]
|
|
65
|
+
packages = ["src/muscle_memory"]
|
|
66
|
+
include = [
|
|
67
|
+
"src/muscle_memory/**/*.py",
|
|
68
|
+
"src/muscle_memory/**/*.md",
|
|
69
|
+
"src/muscle_memory/prompts/*.md",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.hatch.build.targets.sdist]
|
|
73
|
+
include = [
|
|
74
|
+
"src/muscle_memory",
|
|
75
|
+
"tests",
|
|
76
|
+
"README.md",
|
|
77
|
+
"LICENSE",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
[tool.ruff]
|
|
81
|
+
line-length = 100
|
|
82
|
+
target-version = "py311"
|
|
83
|
+
src = ["src", "tests"]
|
|
84
|
+
|
|
85
|
+
[tool.ruff.lint]
|
|
86
|
+
select = [
|
|
87
|
+
"E", # pycodestyle errors
|
|
88
|
+
"W", # pycodestyle warnings
|
|
89
|
+
"F", # pyflakes
|
|
90
|
+
"I", # isort
|
|
91
|
+
"B", # flake8-bugbear
|
|
92
|
+
"UP", # pyupgrade
|
|
93
|
+
"N", # pep8-naming
|
|
94
|
+
"SIM", # flake8-simplify
|
|
95
|
+
]
|
|
96
|
+
ignore = [
|
|
97
|
+
"E501", # line too long (let formatter handle)
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
[tool.ruff.lint.per-file-ignores]
|
|
101
|
+
"tests/**/*.py" = ["B011"]
|
|
102
|
+
|
|
103
|
+
[tool.pytest.ini_options]
|
|
104
|
+
testpaths = ["tests"]
|
|
105
|
+
asyncio_mode = "auto"
|
|
106
|
+
filterwarnings = [
|
|
107
|
+
"ignore::DeprecationWarning",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[tool.mypy]
|
|
111
|
+
python_version = "3.11"
|
|
112
|
+
strict = true
|
|
113
|
+
warn_return_any = true
|
|
114
|
+
warn_unused_configs = true
|
|
115
|
+
disallow_untyped_defs = true
|
|
116
|
+
no_implicit_optional = true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""muscle-memory: procedural memory for coding agents."""
|
|
2
|
+
|
|
3
|
+
from muscle_memory.models import (
|
|
4
|
+
Episode,
|
|
5
|
+
Maturity,
|
|
6
|
+
Outcome,
|
|
7
|
+
Scope,
|
|
8
|
+
Skill,
|
|
9
|
+
ToolCall,
|
|
10
|
+
Trajectory,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__version__ = "0.2.0"
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"Episode",
|
|
17
|
+
"Maturity",
|
|
18
|
+
"Outcome",
|
|
19
|
+
"Scope",
|
|
20
|
+
"Skill",
|
|
21
|
+
"ToolCall",
|
|
22
|
+
"Trajectory",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|