aether-cache 0.1.5__tar.gz → 0.1.7__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.
Files changed (25) hide show
  1. {aether_cache-0.1.5 → aether_cache-0.1.7}/PKG-INFO +44 -7
  2. {aether_cache-0.1.5 → aether_cache-0.1.7}/README.md +43 -6
  3. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/__init__.py +1 -1
  4. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/engine.py +26 -1
  5. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/server.py +9 -5
  6. {aether_cache-0.1.5 → aether_cache-0.1.7}/pyproject.toml +1 -1
  7. {aether_cache-0.1.5 → aether_cache-0.1.7}/.gitignore +0 -0
  8. {aether_cache-0.1.5 → aether_cache-0.1.7}/LICENSE +0 -0
  9. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/__main__.py +0 -0
  10. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/cli.py +0 -0
  11. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/config.py +0 -0
  12. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/connect.py +0 -0
  13. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/engine/aether-engine.jar +0 -0
  14. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/javart.py +0 -0
  15. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/portability.py +0 -0
  16. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/repos.py +0 -0
  17. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/OFL.txt +0 -0
  18. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  19. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  20. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  21. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  22. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  23. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui/index.html +0 -0
  24. {aether_cache-0.1.5 → aether_cache-0.1.7}/aether_cache/ui.py +0 -0
  25. {aether_cache-0.1.5 → aether_cache-0.1.7}/docs/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: aether-cache
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: Shared memory for AI coding tools that stays true to your code.
5
5
  Project-URL: Homepage, https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/
6
6
  Project-URL: Repository, https://github.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store
@@ -13,12 +13,14 @@ Requires-Dist: mcp>=1.2
13
13
  Requires-Dist: redis>=5.0
14
14
  Description-Content-Type: text/markdown
15
15
 
16
- [![progress-banner](https://backend.codecrafters.io/progress/redis/f43a7cd3-11e6-45dc-a8ba-9d6690c73ac0)](https://app.codecrafters.io/users/anishchugh05?r=2qF)
16
+ [![Aether Cache: memory that stays true to your code](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/og-image.png)](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)
17
17
 
18
18
  # Aether Cache
19
19
 
20
20
  **Shared memory for AI coding tools that stays true to your code.**
21
21
 
22
+ <!-- mcp-name: io.github.anishchugh05/aether-cache -->
23
+
22
24
  **[Website](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)** · **[PyPI](https://pypi.org/project/aether-cache/)**
23
25
 
24
26
  Claude Code, Cursor, and other AI tools each forget your project between sessions, and when they do remember things,
@@ -63,7 +65,14 @@ other tools ─┘ (Python: embeddings,│ memories, HNSW vector inde
63
65
 
64
66
  ## What it looks like
65
67
 
66
- A memory linked to a file, the file changes, and the next lookup catches it:
68
+ The dashboard (`aether-cache ui`): memories whose files changed wait for a decision, with the file versions side by side.
69
+
70
+ <picture>
71
+ <source media="(prefers-color-scheme: dark)" srcset="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-dark.png">
72
+ <img alt="The Aether Cache dashboard showing stale memories and a possible conflict" src="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-light.png">
73
+ </picture>
74
+
75
+ And from your AI tool's side, a memory linked to a file, the file changes, and the next lookup catches it:
67
76
 
68
77
  ```
69
78
  > remember("The database runs Postgres via docker compose", files=["docker-compose.yml"])
@@ -106,12 +115,26 @@ m1 retired; m3 replaces it.
106
115
 
107
116
  ## Quick start
108
117
 
109
- You need [**uv**](https://docs.astral.sh/uv/) (`curl -LsSf https://astral.sh/uv/install.sh | sh`), which also takes
110
- care of Python for you. Then:
118
+ One line installs everything and runs setup. On macOS or Linux:
119
+
120
+ ```sh
121
+ curl -fsSL https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/install.sh | sh
122
+ ```
123
+
124
+ On Windows (PowerShell):
125
+
126
+ ```powershell
127
+ powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store/main/docs/install.ps1 | iex"
128
+ ```
129
+
130
+ The installer ([install.sh](docs/install.sh), [install.ps1](docs/install.ps1)) gets [uv](https://docs.astral.sh/uv/) if you
131
+ don't have it (uv brings Python), installs Aether Cache, and runs `aether-cache setup`. Prefer your own tools? Any of
132
+ these works, followed by `aether-cache setup`:
111
133
 
112
134
  ```sh
113
135
  uv tool install aether-cache
114
- aether-cache setup
136
+ pipx install aether-cache
137
+ pip install aether-cache # Python 3.10+
115
138
  ```
116
139
 
117
140
  `setup` starts the engine in the background, downloads the embedding model once (about 90 MB), and connects every
@@ -122,7 +145,7 @@ repo and try:
122
145
 
123
146
  Then start a new session and ask how to run the tests.
124
147
 
125
- The engine runs on Java 11+. If you have it, it's used. If you don't, `setup` downloads a private copy (about
148
+ The engine runs on Java 11+. If you have it, it's used. If you don't, Aether Cache downloads a private copy (about
126
149
  50 MB) into `~/.aether-cache/java`, checks it against its published checksum, and uses it only for Aether Cache;
127
150
  nothing is installed system-wide, and `aether-cache uninstall` removes it.
128
151
 
@@ -203,6 +226,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
203
226
  [CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
204
227
  persistence hardening, and the memory layer are my own additions.
205
228
 
229
+ [![progress-banner](https://backend.codecrafters.io/progress/redis/f43a7cd3-11e6-45dc-a8ba-9d6690c73ac0)](https://app.codecrafters.io/users/anishchugh05?r=2qF)
230
+
206
231
  ### Throughput vs. official Redis
207
232
 
208
233
  `redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
@@ -369,6 +394,18 @@ memory_mcp/calibrate.py similarity calibration for duplicate/contradiction
369
394
  vector_bench.py HNSW benchmark (writes results.json)
370
395
  crash_test.py kill -9 crash-safety test
371
396
  ```
397
+
398
+ ## Releasing
399
+
400
+ Bump the version in `pyproject.toml`, `aether_cache/__init__.py`, and `server.json`, commit, then:
401
+
402
+ ```sh
403
+ git tag v0.1.7 && git push --tags
404
+ ```
405
+
406
+ The [release workflow](.github/workflows/release.yml) checks the versions match, builds and smoke-tests the package,
407
+ publishes it to PyPI and the MCP Registry, and creates the GitHub Release.
408
+
372
409
  ## License
373
410
 
374
411
  MIT. See [LICENSE](LICENSE).
@@ -1,9 +1,11 @@
1
- [![progress-banner](https://backend.codecrafters.io/progress/redis/f43a7cd3-11e6-45dc-a8ba-9d6690c73ac0)](https://app.codecrafters.io/users/anishchugh05?r=2qF)
1
+ [![Aether Cache: memory that stays true to your code](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/og-image.png)](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)
2
2
 
3
3
  # Aether Cache
4
4
 
5
5
  **Shared memory for AI coding tools that stays true to your code.**
6
6
 
7
+ <!-- mcp-name: io.github.anishchugh05/aether-cache -->
8
+
7
9
  **[Website](https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/)** · **[PyPI](https://pypi.org/project/aether-cache/)**
8
10
 
9
11
  Claude Code, Cursor, and other AI tools each forget your project between sessions, and when they do remember things,
@@ -48,7 +50,14 @@ other tools ─┘ (Python: embeddings,│ memories, HNSW vector inde
48
50
 
49
51
  ## What it looks like
50
52
 
51
- A memory linked to a file, the file changes, and the next lookup catches it:
53
+ The dashboard (`aether-cache ui`): memories whose files changed wait for a decision, with the file versions side by side.
54
+
55
+ <picture>
56
+ <source media="(prefers-color-scheme: dark)" srcset="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-dark.png">
57
+ <img alt="The Aether Cache dashboard showing stale memories and a possible conflict" src="https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/assets/dashboard-light.png">
58
+ </picture>
59
+
60
+ And from your AI tool's side, a memory linked to a file, the file changes, and the next lookup catches it:
52
61
 
53
62
  ```
54
63
  > remember("The database runs Postgres via docker compose", files=["docker-compose.yml"])
@@ -91,12 +100,26 @@ m1 retired; m3 replaces it.
91
100
 
92
101
  ## Quick start
93
102
 
94
- You need [**uv**](https://docs.astral.sh/uv/) (`curl -LsSf https://astral.sh/uv/install.sh | sh`), which also takes
95
- care of Python for you. Then:
103
+ One line installs everything and runs setup. On macOS or Linux:
104
+
105
+ ```sh
106
+ curl -fsSL https://anishchugh05.github.io/Aether-Cache-Redis-Compatible-Vector-Store/install.sh | sh
107
+ ```
108
+
109
+ On Windows (PowerShell):
110
+
111
+ ```powershell
112
+ powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/anishchugh05/Aether-Cache-Redis-Compatible-Vector-Store/main/docs/install.ps1 | iex"
113
+ ```
114
+
115
+ The installer ([install.sh](docs/install.sh), [install.ps1](docs/install.ps1)) gets [uv](https://docs.astral.sh/uv/) if you
116
+ don't have it (uv brings Python), installs Aether Cache, and runs `aether-cache setup`. Prefer your own tools? Any of
117
+ these works, followed by `aether-cache setup`:
96
118
 
97
119
  ```sh
98
120
  uv tool install aether-cache
99
- aether-cache setup
121
+ pipx install aether-cache
122
+ pip install aether-cache # Python 3.10+
100
123
  ```
101
124
 
102
125
  `setup` starts the engine in the background, downloads the embedding model once (about 90 MB), and connects every
@@ -107,7 +130,7 @@ repo and try:
107
130
 
108
131
  Then start a new session and ask how to run the tests.
109
132
 
110
- The engine runs on Java 11+. If you have it, it's used. If you don't, `setup` downloads a private copy (about
133
+ The engine runs on Java 11+. If you have it, it's used. If you don't, Aether Cache downloads a private copy (about
111
134
  50 MB) into `~/.aether-cache/java`, checks it against its published checksum, and uses it only for Aether Cache;
112
135
  nothing is installed system-wide, and `aether-cache uninstall` removes it.
113
136
 
@@ -188,6 +211,8 @@ A Redis-compatible server written from scratch in Java. It speaks RESP, so `redi
188
211
  [CodeCrafters "Build Your Own Redis"](https://codecrafters.io/challenges/redis) challenge; the vector index,
189
212
  persistence hardening, and the memory layer are my own additions.
190
213
 
214
+ [![progress-banner](https://backend.codecrafters.io/progress/redis/f43a7cd3-11e6-45dc-a8ba-9d6690c73ac0)](https://app.codecrafters.io/users/anishchugh05?r=2qF)
215
+
191
216
  ### Throughput vs. official Redis
192
217
 
193
218
  `redis-benchmark -t set,get`, 100K requests, 50 parallel clients, 3-byte values, same machine:
@@ -354,6 +379,18 @@ memory_mcp/calibrate.py similarity calibration for duplicate/contradiction
354
379
  vector_bench.py HNSW benchmark (writes results.json)
355
380
  crash_test.py kill -9 crash-safety test
356
381
  ```
382
+
383
+ ## Releasing
384
+
385
+ Bump the version in `pyproject.toml`, `aether_cache/__init__.py`, and `server.json`, commit, then:
386
+
387
+ ```sh
388
+ git tag v0.1.7 && git push --tags
389
+ ```
390
+
391
+ The [release workflow](.github/workflows/release.yml) checks the versions match, builds and smoke-tests the package,
392
+ publishes it to PyPI and the MCP Registry, and creates the GitHub Release.
393
+
357
394
  ## License
358
395
 
359
396
  MIT. See [LICENSE](LICENSE).
@@ -1,3 +1,3 @@
1
1
  """Aether Cache: shared memory for AI coding tools that stays true to your code."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.7"
@@ -224,7 +224,7 @@ def start(wait: float = 60) -> str:
224
224
  upgraded = True
225
225
  if state == "other":
226
226
  raise EngineError(port_taken_message())
227
- java, _ = find_java()
227
+ java = _java_or_download()
228
228
  note = _migrate_old_data()
229
229
  config.DATA_DIR.mkdir(parents=True, exist_ok=True)
230
230
  command = [java, "-Xmx1g", "-jar", str(JAR),
@@ -264,6 +264,31 @@ def start(wait: float = 60) -> str:
264
264
  raise EngineError(f"The engine didn't answer within {int(wait)} seconds. See {config.LOG_FILE}.")
265
265
 
266
266
 
267
+ def _java_or_download() -> str:
268
+ """Java for starting the engine. If there isn't any, downloads Aether Cache's private copy, so the engine
269
+ also starts for people whose AI tool runs the server without `aether-cache setup` having run first.
270
+ Called while holding the start lock, so several sessions starting at once download it only once."""
271
+ try:
272
+ return find_java()[0]
273
+ except EngineError as missing:
274
+ if os.environ.get("AETHER_NO_JAVA_DOWNLOAD"):
275
+ raise
276
+ from . import javart
277
+ notice = (f"{str(missing).splitlines()[0]} Downloading a private copy of Java {javart.FEATURE_VERSION} "
278
+ f"for Aether Cache into {javart.JAVA_DIR} (about 50 MB, only the first time).")
279
+ print(notice, file=sys.stderr, flush=True) # stderr: stdout carries the MCP protocol
280
+ try:
281
+ with open(config.LOG_FILE, "a") as log:
282
+ log.write(f"\n{time.strftime('%Y-%m-%d %H:%M:%S')} {notice}\n")
283
+ except OSError:
284
+ pass
285
+ try:
286
+ javart.download(progress=lambda done, total: None)
287
+ except javart.JavaDownloadError as e:
288
+ raise EngineError(f"{str(missing).splitlines()[0]}\n{e}")
289
+ return find_java()[0]
290
+
291
+
267
292
  def ensure_running() -> None:
268
293
  if probe() != "aether" or needs_upgrade():
269
294
  start()
@@ -16,7 +16,7 @@ from typing import List, Optional
16
16
 
17
17
  import redis
18
18
 
19
- from . import config, engine
19
+ from . import __version__, config, engine
20
20
 
21
21
  try:
22
22
  from mcp.server.mcpserver import MCPServer # mcp 2.x
@@ -39,10 +39,14 @@ INSTRUCTIONS = (
39
39
  "replace_memory."
40
40
  )
41
41
 
42
- mcp = MCPServer(
43
- "aether-cache",
44
- instructions=INSTRUCTIONS,
45
- )
42
+ try:
43
+ mcp = MCPServer("aether-cache", instructions=INSTRUCTIONS, version=__version__)
44
+ except Exception: # mcp 1.x has no version argument; set it on the underlying server instead
45
+ mcp = MCPServer("aether-cache", instructions=INSTRUCTIONS)
46
+ try:
47
+ mcp._mcp_server.version = __version__
48
+ except AttributeError:
49
+ pass
46
50
 
47
51
  def quiet_libraries() -> None:
48
52
  """Hides the download libraries' request logs, warnings and progress bars, which otherwise flood the
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "aether-cache"
7
- version = "0.1.5"
7
+ version = "0.1.7"
8
8
  description = "Shared memory for AI coding tools that stays true to your code."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes