devmemory 0.1.2__tar.gz → 0.1.3__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 (44) hide show
  1. {devmemory-0.1.2 → devmemory-0.1.3}/.github/workflows/ci.yml +4 -4
  2. {devmemory-0.1.2 → devmemory-0.1.3}/CONTRIBUTING.md +9 -3
  3. {devmemory-0.1.2 → devmemory-0.1.3}/Makefile +2 -2
  4. {devmemory-0.1.2 → devmemory-0.1.3}/PKG-INFO +5 -5
  5. {devmemory-0.1.2 → devmemory-0.1.3}/README.md +4 -4
  6. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/__init__.py +1 -1
  7. devmemory-0.1.3/devmemory/__main__.py +3 -0
  8. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/git_ai_parser.py +42 -23
  9. {devmemory-0.1.2 → devmemory-0.1.3}/pyproject.toml +1 -1
  10. {devmemory-0.1.2 → devmemory-0.1.3}/scripts/install.sh +81 -15
  11. {devmemory-0.1.2 → devmemory-0.1.3}/scripts/verify.sh +12 -3
  12. {devmemory-0.1.2 → devmemory-0.1.3}/.cursor/rules/devmemory-context.mdc +0 -0
  13. {devmemory-0.1.2 → devmemory-0.1.3}/.cursor/rules/devmemory.mdc +0 -0
  14. {devmemory-0.1.2 → devmemory-0.1.3}/.env.example +0 -0
  15. {devmemory-0.1.2 → devmemory-0.1.3}/.gitignore +0 -0
  16. {devmemory-0.1.2 → devmemory-0.1.3}/CHANGELOG.md +0 -0
  17. {devmemory-0.1.2 → devmemory-0.1.3}/LICENSE +0 -0
  18. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/cli.py +0 -0
  19. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/__init__.py +0 -0
  20. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/add.py +0 -0
  21. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/config_cmd.py +0 -0
  22. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/context.py +0 -0
  23. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/install.py +0 -0
  24. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/learn.py +0 -0
  25. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/search.py +0 -0
  26. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/status.py +0 -0
  27. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/commands/sync.py +0 -0
  28. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/__init__.py +0 -0
  29. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/ams_client.py +0 -0
  30. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/config.py +0 -0
  31. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/llm_client.py +0 -0
  32. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/memory_formatter.py +0 -0
  33. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/core/sync_state.py +0 -0
  34. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/hooks/__init__.py +0 -0
  35. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/hooks/post_commit.py +0 -0
  36. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/rules/devmemory-context.mdc +0 -0
  37. {devmemory-0.1.2 → devmemory-0.1.3}/devmemory/rules/devmemory.mdc +0 -0
  38. {devmemory-0.1.2 → devmemory-0.1.3}/docker-compose.yml +0 -0
  39. {devmemory-0.1.2 → devmemory-0.1.3}/docs/auto-sync.gif +0 -0
  40. {devmemory-0.1.2 → devmemory-0.1.3}/tests/test_git_ai_parser.py +0 -0
  41. {devmemory-0.1.2 → devmemory-0.1.3}/tests/test_learn.py +0 -0
  42. {devmemory-0.1.2 → devmemory-0.1.3}/tests/test_llm_client.py +0 -0
  43. {devmemory-0.1.2 → devmemory-0.1.3}/tests/test_memory_formatter.py +0 -0
  44. {devmemory-0.1.2 → devmemory-0.1.3}/tests/test_status.py +0 -0
@@ -17,16 +17,16 @@ jobs:
17
17
  - name: Checkout
18
18
  uses: actions/checkout@v4
19
19
 
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
20
23
  - name: Set up Python
21
24
  uses: actions/setup-python@v5
22
25
  with:
23
26
  python-version: ${{ matrix.python-version }}
24
27
 
25
28
  - name: Install dependencies
26
- run: |
27
- python -m pip install --upgrade pip
28
- pip install -e .[dev]
29
+ run: uv pip install --system -e .[dev]
29
30
 
30
31
  - name: Run tests
31
32
  run: pytest
32
-
@@ -2,13 +2,20 @@
2
2
 
3
3
  ### Development setup
4
4
 
5
- - Clone the repository and create a virtualenv.
5
+ - Clone the repository.
6
6
  - Copy `.env.example` to `.env` and set `OPENAI_API_KEY`.
7
7
  - Start the local stack with `make up`.
8
8
  - Install the package in editable mode with dev extras:
9
9
 
10
10
  ```bash
11
- pip install -e .[dev]
11
+ uv tool install --editable .
12
+ ```
13
+
14
+ Or if you prefer a virtual environment for development:
15
+
16
+ ```bash
17
+ uv venv
18
+ uv pip install -e .[dev]
12
19
  ```
13
20
 
14
21
  ### Running tests and linting
@@ -42,4 +49,3 @@ ruff check .
42
49
  - Add or update tests when changing behavior.
43
50
  - Ensure `pytest` passes locally.
44
51
  - Keep commits focused and descriptive.
45
-
@@ -22,7 +22,7 @@ setup:
22
22
  @bash scripts/install.sh
23
23
 
24
24
  build:
25
- .venv/bin/python -m build
25
+ uv build
26
26
 
27
27
  publish:
28
- .venv/bin/twine upload dist/*
28
+ uv publish
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devmemory
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Sync AI coding context from Git AI to Redis Agent Memory Server for semantic search and recall.
5
5
  Project-URL: Homepage, https://github.com/devmemory/devmemory
6
6
  Project-URL: Repository, https://github.com/devmemory/devmemory
@@ -177,10 +177,10 @@ bash scripts/install.sh
177
177
 
178
178
  This script:
179
179
 
180
- - Checks Docker / Python / Git AI
180
+ - Checks Docker / Python / Git AI and verifies the Docker daemon is running
181
+ - Installs [uv](https://docs.astral.sh/uv/) if not present, then installs the `devmemory` CLI via `uv tool install`
181
182
  - Sets up `.env` from `.env.example`
182
183
  - Starts Redis + AMS + MCP via Docker
183
- - Installs the `devmemory` CLI
184
184
  - Configures git hooks + Cursor MCP + agent rules in the current repo
185
185
 
186
186
  ### Manual Setup
@@ -196,8 +196,8 @@ cp .env.example .env
196
196
  # Start the stack
197
197
  make up
198
198
 
199
- # Install the CLI
200
- pip install -e .
199
+ # Install the CLI (requires uv: https://docs.astral.sh/uv/)
200
+ uv tool install --editable .
201
201
 
202
202
  # Set up hooks, MCP config, and Cursor rules in your project
203
203
  cd /path/to/your/project
@@ -145,10 +145,10 @@ bash scripts/install.sh
145
145
 
146
146
  This script:
147
147
 
148
- - Checks Docker / Python / Git AI
148
+ - Checks Docker / Python / Git AI and verifies the Docker daemon is running
149
+ - Installs [uv](https://docs.astral.sh/uv/) if not present, then installs the `devmemory` CLI via `uv tool install`
149
150
  - Sets up `.env` from `.env.example`
150
151
  - Starts Redis + AMS + MCP via Docker
151
- - Installs the `devmemory` CLI
152
152
  - Configures git hooks + Cursor MCP + agent rules in the current repo
153
153
 
154
154
  ### Manual Setup
@@ -164,8 +164,8 @@ cp .env.example .env
164
164
  # Start the stack
165
165
  make up
166
166
 
167
- # Install the CLI
168
- pip install -e .
167
+ # Install the CLI (requires uv: https://docs.astral.sh/uv/)
168
+ uv tool install --editable .
169
169
 
170
170
  # Set up hooks, MCP config, and Cursor rules in your project
171
171
  cd /path/to/your/project
@@ -1,2 +1,2 @@
1
- __version__ = "0.1.2"
1
+ __version__ = "0.1.3"
2
2
  __app_name__ = "devmemory"
@@ -0,0 +1,3 @@
1
+ from devmemory.cli import main
2
+
3
+ main()
@@ -180,7 +180,7 @@ def parse_ai_note(raw_note: str) -> list[FileAttribution]:
180
180
 
181
181
 
182
182
  def get_prompt_data(prompt_id: str, commit_sha: str | None = None) -> PromptData | None:
183
- cmd = ["git-ai", "show-prompt", prompt_id]
183
+ cmd = _git_ai_prefix() + ["show-prompt", prompt_id]
184
184
  if commit_sha:
185
185
  cmd.extend(["--commit", commit_sha])
186
186
 
@@ -215,7 +215,7 @@ def get_prompt_data(prompt_id: str, commit_sha: str | None = None) -> PromptData
215
215
 
216
216
 
217
217
  def get_commit_stats(sha: str) -> CommitStats | None:
218
- cmd = ["git-ai", "stats", sha, "--json"]
218
+ cmd = _git_ai_prefix() + ["stats", sha, "--json"]
219
219
  try:
220
220
  result = subprocess.run(cmd, capture_output=True, text=True, check=True)
221
221
  except (subprocess.CalledProcessError, FileNotFoundError):
@@ -333,30 +333,49 @@ def get_latest_commit_note() -> CommitNote | None:
333
333
  return _build_commit_note(commits[0])
334
334
 
335
335
 
336
- def is_git_ai_installed() -> bool:
337
- try:
338
- result = subprocess.run(
339
- ["git-ai", "version"],
340
- capture_output=True, text=True,
341
- )
342
- return result.returncode == 0
343
- except FileNotFoundError:
344
- try:
345
- result = subprocess.run(
346
- ["git", "ai", "version"],
347
- capture_output=True, text=True,
348
- )
349
- return result.returncode == 0
350
- except FileNotFoundError:
351
- return False
352
-
353
-
354
- def get_git_ai_version() -> str:
355
- for cmd in [["git-ai", "version"], ["git", "ai", "version"]]:
336
+ def _resolve_git_ai() -> list[str] | None:
337
+ """Find a working git-ai command: PATH, well-known install dir, or git subcommand."""
338
+ candidates = [
339
+ ["git-ai", "version"],
340
+ [os.path.expanduser("~/.git-ai/bin/git-ai"), "version"],
341
+ ["git", "ai", "version"],
342
+ ]
343
+ for cmd in candidates:
356
344
  try:
357
345
  result = subprocess.run(cmd, capture_output=True, text=True)
358
346
  if result.returncode == 0:
359
- return result.stdout.strip()
347
+ return cmd[:-1] # return without the "version" arg
360
348
  except FileNotFoundError:
361
349
  continue
350
+ return None
351
+
352
+
353
+ # Cache the result so we don't probe on every call
354
+ _git_ai_cmd_prefix: list[str] | None = None
355
+ _git_ai_resolved = False
356
+
357
+
358
+ def _git_ai_prefix() -> list[str]:
359
+ """Return the command prefix for git-ai (cached after first lookup)."""
360
+ global _git_ai_cmd_prefix, _git_ai_resolved
361
+ if not _git_ai_resolved:
362
+ _git_ai_cmd_prefix = _resolve_git_ai()
363
+ _git_ai_resolved = True
364
+ return _git_ai_cmd_prefix or ["git-ai"]
365
+
366
+
367
+ def is_git_ai_installed() -> bool:
368
+ return _resolve_git_ai() is not None
369
+
370
+
371
+ def get_git_ai_version() -> str:
372
+ prefix = _resolve_git_ai()
373
+ if not prefix:
374
+ return "not installed"
375
+ try:
376
+ result = subprocess.run(prefix + ["version"], capture_output=True, text=True)
377
+ if result.returncode == 0:
378
+ return result.stdout.strip()
379
+ except FileNotFoundError:
380
+ pass
362
381
  return "not installed"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "devmemory"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "Sync AI coding context from Git AI to Redis Agent Memory Server for semantic search and recall."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -19,12 +19,14 @@ step "DevMemory Setup"
19
19
  echo "This script will:"
20
20
  echo " 1. Check prerequisites (git, docker, python3)"
21
21
  echo " 2. Install Git AI (if not present)"
22
- echo " 3. Install devmemory CLI"
22
+ echo " 3. Install devmemory CLI (via uv)"
23
23
  echo " 4. Set up .env file"
24
24
  echo " 5. Start the Docker stack"
25
25
  echo " 6. Configure git hooks, Cursor MCP, and agent coordination rules"
26
26
  echo ""
27
27
 
28
+ # ── Step 1: Prerequisites ──────────────────────────────────────────────────────
29
+
28
30
  step "[1/6] Checking prerequisites..."
29
31
 
30
32
  if ! command -v git &>/dev/null; then
@@ -39,6 +41,34 @@ if ! command -v docker &>/dev/null; then
39
41
  fi
40
42
  info "docker $(docker --version | awk '{print $3}' | tr -d ',')"
41
43
 
44
+ if ! docker info &>/dev/null 2>&1; then
45
+ error "Docker daemon is not running."
46
+ echo ""
47
+ case "$(uname -s)" in
48
+ Darwin)
49
+ echo " Start Docker Desktop:"
50
+ echo " open -a Docker"
51
+ ;;
52
+ Linux)
53
+ if grep -qi microsoft /proc/version 2>/dev/null; then
54
+ echo " You appear to be on WSL. Start Docker Desktop from Windows,"
55
+ echo " or enable the WSL integration in Docker Desktop settings."
56
+ else
57
+ echo " Start the Docker service:"
58
+ echo " sudo systemctl start docker"
59
+ fi
60
+ ;;
61
+ *)
62
+ echo " Please start Docker Desktop or the Docker service."
63
+ ;;
64
+ esac
65
+ echo ""
66
+ echo " Then re-run:"
67
+ echo " $0"
68
+ exit 1
69
+ fi
70
+ info "docker daemon is running"
71
+
42
72
  if ! docker compose version &>/dev/null 2>&1; then
43
73
  error "docker compose is not available"
44
74
  exit 1
@@ -64,9 +94,20 @@ if [ -z "$PYTHON_CMD" ]; then
64
94
  fi
65
95
  info "$PYTHON_CMD $($PYTHON_CMD --version 2>&1 | awk '{print $2}')"
66
96
 
97
+ # ── Step 2: Git AI ─────────────────────────────────────────────────────────────
98
+
67
99
  step "[2/6] Checking Git AI..."
68
100
 
69
- if command -v git-ai &>/dev/null || git ai version &>/dev/null 2>&1; then
101
+ GIT_AI_BIN=""
102
+ if command -v git-ai &>/dev/null; then
103
+ GIT_AI_BIN="git-ai"
104
+ elif [ -x "$HOME/.git-ai/bin/git-ai" ]; then
105
+ GIT_AI_BIN="$HOME/.git-ai/bin/git-ai"
106
+ elif git ai version &>/dev/null 2>&1; then
107
+ GIT_AI_BIN="git ai"
108
+ fi
109
+
110
+ if [ -n "$GIT_AI_BIN" ]; then
70
111
  info "Git AI is already installed"
71
112
  else
72
113
  warn "Git AI is not installed"
@@ -82,24 +123,45 @@ else
82
123
  fi
83
124
  fi
84
125
 
126
+ # ── Step 3: Install devmemory CLI via uv ───────────────────────────────────────
127
+
85
128
  step "[3/6] Installing devmemory CLI..."
86
129
 
87
- if command -v pip &>/dev/null || command -v pip3 &>/dev/null; then
88
- PIP_CMD="pip3"
89
- command -v pip3 &>/dev/null || PIP_CMD="pip"
130
+ cd "$SCRIPT_DIR"
131
+
132
+ # Install uv if not present
133
+ if ! command -v uv &>/dev/null; then
134
+ echo "Installing uv package manager..."
135
+ curl -LsSf https://astral.sh/uv/install.sh | sh
136
+ # Source the env so uv is available immediately
137
+ export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
138
+ if ! command -v uv &>/dev/null; then
139
+ error "Failed to install uv. Install manually: https://docs.astral.sh/uv/getting-started/installation/"
140
+ exit 1
141
+ fi
142
+ info "uv installed"
90
143
  else
91
- PIP_CMD="$PYTHON_CMD -m pip"
144
+ info "uv $(uv --version | awk '{print $2}')"
92
145
  fi
93
146
 
94
- cd "$SCRIPT_DIR"
147
+ uv tool install --editable "$SCRIPT_DIR" --force --quiet
148
+ uv tool update-shell --quiet 2>/dev/null || true
149
+ info "devmemory installed"
95
150
 
96
- if command -v pipx &>/dev/null; then
97
- pipx install -e "$SCRIPT_DIR" --force 2>/dev/null && info "devmemory installed via pipx" || {
98
- $PIP_CMD install -e "$SCRIPT_DIR" && info "devmemory installed via pip"
99
- }
100
- else
101
- $PIP_CMD install -e "$SCRIPT_DIR" && info "devmemory installed via pip"
151
+ # Ensure devmemory is on PATH for the rest of this script
152
+ if ! command -v devmemory &>/dev/null; then
153
+ export PATH="$HOME/.local/bin:$PATH"
154
+ fi
155
+
156
+ if ! command -v devmemory &>/dev/null; then
157
+ error "devmemory not found on PATH after install."
158
+ echo " Try opening a new terminal, or run:"
159
+ echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
160
+ exit 1
102
161
  fi
162
+ info "devmemory is on PATH"
163
+
164
+ # ── Step 4: Environment ────────────────────────────────────────────────────────
103
165
 
104
166
  step "[4/6] Setting up environment..."
105
167
 
@@ -112,20 +174,22 @@ if [ ! -f "$ENV_FILE" ]; then
112
174
  echo ""
113
175
  read -p "Enter your OpenAI API key (or press Enter to skip): " api_key
114
176
  if [ -n "$api_key" ]; then
115
- sed -i "s/your_openai_api_key_here/$api_key/" "$ENV_FILE"
177
+ sed -i.bak "s/your_openai_api_key_here/$api_key/" "$ENV_FILE" && rm -f "$ENV_FILE.bak"
116
178
  info "API key saved to .env"
117
179
  else
118
180
  warn "No API key set. Edit .env before starting the stack."
119
181
  warn "Memories won't be processed without an OpenAI API key."
120
182
  fi
121
183
  else
122
- sed -i "s/your_openai_api_key_here/$OPENAI_API_KEY/" "$ENV_FILE"
184
+ sed -i.bak "s/your_openai_api_key_here/$OPENAI_API_KEY/" "$ENV_FILE" && rm -f "$ENV_FILE.bak"
123
185
  info "API key set from OPENAI_API_KEY environment variable"
124
186
  fi
125
187
  else
126
188
  info ".env file already exists"
127
189
  fi
128
190
 
191
+ # ── Step 5: Docker stack ───────────────────────────────────────────────────────
192
+
129
193
  step "[5/6] Starting Docker stack..."
130
194
 
131
195
  cd "$SCRIPT_DIR"
@@ -149,6 +213,8 @@ if curl -sf http://localhost:6379 >/dev/null 2>&1 || docker compose exec -T redi
149
213
  info "Redis is healthy"
150
214
  fi
151
215
 
216
+ # ── Step 6: Configure hooks, MCP, agent rules ─────────────────────────────────
217
+
152
218
  step "[6/6] Configuring hooks, MCP, and agent rules..."
153
219
 
154
220
  if git rev-parse --show-toplevel &>/dev/null; then
@@ -94,8 +94,17 @@ curl -sf -X DELETE "http://localhost:8000/v1/long-term-memory?memory_ids=$TEST_I
94
94
 
95
95
  echo ""
96
96
  echo "Git AI:"
97
- if command -v git-ai &>/dev/null || git ai version &>/dev/null 2>&1; then
98
- VERSION=$(git-ai version 2>/dev/null || git ai version 2>/dev/null || echo "unknown")
97
+ GIT_AI_BIN=""
98
+ if command -v git-ai &>/dev/null; then
99
+ GIT_AI_BIN="git-ai"
100
+ elif [ -x "$HOME/.git-ai/bin/git-ai" ]; then
101
+ GIT_AI_BIN="$HOME/.git-ai/bin/git-ai"
102
+ elif git ai version &>/dev/null 2>&1; then
103
+ GIT_AI_BIN="git ai"
104
+ fi
105
+
106
+ if [ -n "$GIT_AI_BIN" ]; then
107
+ VERSION=$($GIT_AI_BIN version 2>/dev/null || echo "unknown")
99
108
  pass "Git AI installed: $VERSION"
100
109
  else
101
110
  skip "Git AI is not installed (optional for basic testing)"
@@ -106,7 +115,7 @@ echo "DevMemory CLI:"
106
115
  if command -v devmemory &>/dev/null; then
107
116
  pass "devmemory CLI is installed"
108
117
  else
109
- skip "devmemory CLI not on PATH (install with: pip install -e .)"
118
+ skip "devmemory CLI not on PATH (install with: uv tool install --editable .)"
110
119
  fi
111
120
 
112
121
  echo ""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes