agent-memory-git 0.1.4__tar.gz → 0.1.5__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 (30) hide show
  1. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/PKG-INFO +1 -1
  2. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/pyproject.toml +1 -1
  3. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/pyproject.toml.orig +1 -1
  4. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/config.py +13 -1
  5. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/update.py +68 -13
  6. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/LICENSE +0 -0
  7. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/README.md +0 -0
  8. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/PROTOCOL.md +0 -0
  9. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/__init__.py +0 -0
  10. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/__main__.py +0 -0
  11. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/capture.py +0 -0
  12. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/cli.py +0 -0
  13. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/context.py +0 -0
  14. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/embed_worker.py +0 -0
  15. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/frontmatter.py +0 -0
  16. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/gitsync.py +0 -0
  17. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/hooks.py +0 -0
  18. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/importers.py +0 -0
  19. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/install.py +0 -0
  20. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/lint.py +0 -0
  21. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/select.py +0 -0
  22. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/sessions.py +0 -0
  23. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/store.py +0 -0
  24. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/ui.py +0 -0
  25. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/ui_server.py +0 -0
  26. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/util.py +0 -0
  27. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/webui/assets/index-MdftBYNd.js +0 -0
  28. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/webui/assets/index-h-rsgD7i.css +0 -0
  29. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/webui/index.html +0 -0
  30. {agent_memory_git-0.1.4 → agent_memory_git-0.1.5}/src/agent_memory/workdir.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-memory-git
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Shared, git-backed memory for Claude Code and Codex.
5
5
  Keywords: claude-code,codex,memory,agents,git
6
6
  Author: Shichao Song
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agent-memory-git"
3
- version = "0.1.4"
3
+ version = "0.1.5"
4
4
  description = "Shared, git-backed memory for Claude Code and Codex."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agent-memory-git"
3
- version = "0.1.4"
3
+ version = "0.1.5"
4
4
  description = "Shared, git-backed memory for Claude Code and Codex."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -14,9 +14,21 @@ CONFIG_FILE = CONFIG_DIR / "config.json"
14
14
  PROTOCOL_COPY = CONFIG_DIR / "PROTOCOL.md" # what Claude Code imports; `mem install` refreshes it
15
15
 
16
16
 
17
+ def _python():
18
+ """This interpreter, as the `python` beside it when that is the same file. Whether `mem` was
19
+ started as python3 or python3.11 (uv has changed its entry scripts) then leaves the hook
20
+ commands alone, so `mem install` does not rewrite them and Codex does not ask to trust them again."""
21
+ exe = Path(sys.executable)
22
+ try:
23
+ plain = exe.with_name("python")
24
+ return str(plain) if plain != exe and plain.samefile(exe) else sys.executable
25
+ except (OSError, ValueError): # no `python` beside it, or no sys.executable at all
26
+ return sys.executable
27
+
28
+
17
29
  def mem_command():
18
30
  """The argv that runs `mem` with this interpreter, for hooks and background sync."""
19
- return [sys.executable, "-m", "agent_memory"]
31
+ return [_python(), "-m", "agent_memory"]
20
32
 
21
33
 
22
34
  def _mem_path():
@@ -8,10 +8,12 @@ import datetime as _dt
8
8
  import importlib.metadata
9
9
  import json
10
10
  import re
11
+ import shlex
11
12
  import shutil
12
13
  import subprocess
13
14
  import sys
14
15
  import time
16
+ import tomllib
15
17
  import urllib.request
16
18
  from pathlib import Path
17
19
 
@@ -21,9 +23,8 @@ PACKAGE = "agent-memory-git"
21
23
  INDEX = f"https://pypi.org/pypi/{PACKAGE}/json"
22
24
  CHECK_EVERY = 24 * 3600
23
25
  CACHE_NAME = "update-check.json"
24
- # how to update, by how this copy was installed
26
+ # how to update, by how this copy was installed; for `uv tool` it depends on the install, see upgrade_args
25
27
  COMMANDS = {
26
- "uv-tool": f"uv tool upgrade {PACKAGE} && mem install",
27
28
  "uvx": f'uvx --refresh --from "{PACKAGE}[ui]" mem ui',
28
29
  "dev": "git pull && (cd web && npm ci && npm run build) && mem install", # run in the checkout
29
30
  "other": f'pip install -U "{PACKAGE}[ui]" && mem install',
@@ -34,6 +35,13 @@ def _cache():
34
35
  return config.CONFIG_DIR / CACHE_NAME
35
36
 
36
37
 
38
+ def _cached():
39
+ try:
40
+ return json.loads(_cache().read_text("utf-8"))
41
+ except (OSError, ValueError):
42
+ return {}
43
+
44
+
37
45
  def current():
38
46
  try:
39
47
  return importlib.metadata.version(PACKAGE)
@@ -81,7 +89,7 @@ def _inside(path, root):
81
89
 
82
90
 
83
91
  def how_installed():
84
- """'uv-tool' when `uv tool upgrade` can update this copy; else 'dev', 'uvx' or 'other'."""
92
+ """'uv-tool' when uv can update this copy in place; else 'dev', 'uvx' or 'other'."""
85
93
  try:
86
94
  direct = importlib.metadata.distribution(PACKAGE).read_text("direct_url.json")
87
95
  except importlib.metadata.PackageNotFoundError:
@@ -97,13 +105,48 @@ def how_installed():
97
105
  return "other"
98
106
 
99
107
 
108
+ def _receipt():
109
+ """What `uv tool install` was given for this copy, from the receipt uv keeps in its environment."""
110
+ try:
111
+ return tomllib.loads((Path(sys.prefix) / "uv-receipt.toml").read_text("utf-8")).get("tool", {})
112
+ except (OSError, ValueError):
113
+ return {}
114
+
115
+
116
+ def _requirement(req, specifier=True):
117
+ extras = f"[{','.join(req['extras'])}]" if req.get("extras") else ""
118
+ return req["name"] + extras + (req.get("specifier", "") if specifier else "")
119
+
120
+
121
+ def upgrade_args():
122
+ """The uv arguments that update this `uv tool` install. `uv tool upgrade` keeps a version given at
123
+ install time (`agent-memory-git==0.1.3`), so such an install is installed again without it,
124
+ keeping its extras, its Python and the packages added with `--with`."""
125
+ tool = _receipt()
126
+ reqs = tool.get("requirements", [])
127
+ ours = next((r for r in reqs if r.get("name") == PACKAGE), {})
128
+ simple = set(tool) <= {"requirements", "python", "entrypoints"} and all(
129
+ set(r) <= {"name", "extras", "specifier"} for r in reqs
130
+ ) # nothing a plain `uv tool install` would lose, such as a custom index or a git source
131
+ if not (ours.get("specifier") and simple):
132
+ return ["tool", "upgrade", PACKAGE]
133
+ args = ["tool", "install", "--upgrade", _requirement(ours, specifier=False)]
134
+ if tool.get("python"):
135
+ args += ["--python", tool["python"]]
136
+ for r in reqs:
137
+ if r is not ours:
138
+ args += ["--with", _requirement(r)]
139
+ return args
140
+
141
+
142
+ def _uv_command(args):
143
+ return f"{shlex.join(['uv', *args])} && mem install"
144
+
145
+
100
146
  def status(force=False):
101
147
  """What the page shows: this version, the latest one known, and how to update."""
102
148
  auto = config.load().get("check_updates", True)
103
- try:
104
- cached = json.loads(_cache().read_text("utf-8"))
105
- except (OSError, ValueError):
106
- cached = {}
149
+ cached = _cached()
107
150
  if force or (auto and time.time() - cached.get("checked", 0) > CHECK_EVERY):
108
151
  latest = fetch_latest()
109
152
  if latest:
@@ -119,7 +162,7 @@ def status(force=False):
119
162
  "checked": _dt.datetime.fromtimestamp(checked).astimezone().isoformat() if checked else None,
120
163
  "auto": auto,
121
164
  "method": method,
122
- "command": COMMANDS[method],
165
+ "command": _uv_command(upgrade_args()) if method == "uv-tool" else COMMANDS[method],
123
166
  "oneClick": method == "uv-tool",
124
167
  }
125
168
 
@@ -130,27 +173,39 @@ def _tail(*outputs, lines=12):
130
173
 
131
174
 
132
175
  def upgrade():
133
- """`uv tool upgrade`, then `mem install` from the upgraded code. Returns what happened."""
176
+ """The uv update (see upgrade_args), then `mem install` from the upgraded code. Returns what happened."""
134
177
  if how_installed() != "uv-tool":
135
178
  return {"ok": False, "error": "This copy was not installed with `uv tool`; update it with the command shown."}
136
179
  before = current()
137
- up = subprocess.run([shutil.which("uv"), "tool", "upgrade", PACKAGE], capture_output=True, text=True, timeout=600)
180
+ args = upgrade_args()
181
+ up = subprocess.run([shutil.which("uv"), *args], capture_output=True, text=True, timeout=600)
138
182
  if up.returncode != 0:
139
- return {"ok": False, "error": "uv tool upgrade failed.", "log": _tail(up.stdout, up.stderr)}
183
+ return {"ok": False, "error": f"`{shlex.join(['uv', *args])}` failed.", "log": _tail(up.stdout, up.stderr)}
140
184
  # a new process, so both run the upgraded code
141
185
  after = subprocess.run(
142
186
  [sys.executable, "-c", f"import importlib.metadata as m; print(m.version({PACKAGE!r}))"],
143
187
  capture_output=True,
144
188
  text=True,
145
189
  ).stdout.strip()
190
+ if after in ("", before): # nothing new installed, so nothing for mem install to refresh
191
+ known = _cached().get("latest")
192
+ missed = newer(known, before) # e.g. a version bound uv kept; its output says why
193
+ return {
194
+ "ok": not missed,
195
+ "from": before,
196
+ "to": before,
197
+ "changed": False,
198
+ "error": f"uv did not install {known}; its output is below." if missed else None,
199
+ "log": _tail(up.stdout, up.stderr),
200
+ }
146
201
  inst = subprocess.run(
147
202
  [sys.executable, "-m", "agent_memory", "install"], capture_output=True, text=True, timeout=120
148
203
  )
149
204
  return {
150
205
  "ok": inst.returncode == 0,
151
206
  "from": before,
152
- "to": after or before,
153
- "changed": bool(after) and after != before,
207
+ "to": after,
208
+ "changed": True,
154
209
  "error": None if inst.returncode == 0 else "mem install failed after the upgrade.",
155
210
  "log": _tail(up.stdout, up.stderr, inst.stdout, inst.stderr),
156
211
  }