dev-recall 0.2.5__tar.gz → 0.2.6__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 (47) hide show
  1. {dev_recall-0.2.5 → dev_recall-0.2.6}/PKG-INFO +7 -4
  2. {dev_recall-0.2.5 → dev_recall-0.2.6}/README.md +6 -3
  3. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/PKG-INFO +7 -4
  4. {dev_recall-0.2.5 → dev_recall-0.2.6}/pyproject.toml +1 -1
  5. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/_hooks.py +5 -5
  6. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/ai_chat.py +29 -8
  7. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/SOURCES.txt +0 -0
  8. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/dependency_links.txt +0 -0
  9. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/entry_points.txt +0 -0
  10. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/requires.txt +0 -0
  11. {dev_recall-0.2.5 → dev_recall-0.2.6}/dev_recall.egg-info/top_level.txt +0 -0
  12. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/__init__.py +0 -0
  13. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/cli.py +0 -0
  14. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/__init__.py +0 -0
  15. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/containers.py +0 -0
  16. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/git.py +0 -0
  17. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/linux_process.py +0 -0
  18. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/linux_session.py +0 -0
  19. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/linux_window.py +0 -0
  20. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/shell.py +0 -0
  21. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/collectors/vscode.py +0 -0
  22. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/config.py +0 -0
  23. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/daemon.py +0 -0
  24. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/daemon_main.py +0 -0
  25. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/mcp_server.py +0 -0
  26. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/models.py +0 -0
  27. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/processor/__init__.py +0 -0
  28. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/processor/embedder.py +0 -0
  29. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/processor/enricher.py +0 -0
  30. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/processor/session.py +0 -0
  31. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/query/__init__.py +0 -0
  32. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/query/context.py +0 -0
  33. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/query/llm.py +0 -0
  34. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/query/retriever.py +0 -0
  35. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/query/timeparser.py +0 -0
  36. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/storage/__init__.py +0 -0
  37. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/storage/db.py +0 -0
  38. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/storage/vectors.py +0 -0
  39. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/vscode-extension/package.json +0 -0
  40. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/vscode-extension/src/extension.ts +0 -0
  41. {dev_recall-0.2.5 → dev_recall-0.2.6}/recall/vscode-extension/tsconfig.json +0 -0
  42. {dev_recall-0.2.5 → dev_recall-0.2.6}/setup.cfg +0 -0
  43. {dev_recall-0.2.5 → dev_recall-0.2.6}/tests/test_collectors.py +0 -0
  44. {dev_recall-0.2.5 → dev_recall-0.2.6}/tests/test_enricher.py +0 -0
  45. {dev_recall-0.2.5 → dev_recall-0.2.6}/tests/test_query.py +0 -0
  46. {dev_recall-0.2.5 → dev_recall-0.2.6}/tests/test_session.py +0 -0
  47. {dev_recall-0.2.5 → dev_recall-0.2.6}/tests/test_storage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dev-recall
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Local-first developer memory layer
5
5
  License: MIT
6
6
  Keywords: developer-tools,memory,productivity,cli
@@ -29,14 +29,16 @@ Requires-Dist: docker>=7.0; extra == "linux"
29
29
 
30
30
  # Recall
31
31
 
32
- **Local-first developer memory layer.** Captures every developer activity terminal commands, git commits, file edits, repo opens, AI chat sessions into a structured SQLite database with a FAISS vector index. Enables natural language recall:
32
+ **Time-travel for your dev workflow.** Recall is a local-first CLI that automatically records your development activity and lets you search it in plain English.
33
33
 
34
34
  ```
35
- recall ask "what did I work on last Tuesday?"
36
- recall ask "how did I fix the auth bug?"
37
35
  recall today
36
+ ```
37
+ ![recall today](docs/today.png)
38
+ ```
38
39
  recall timeline
39
40
  ```
41
+ ![recall timeline](docs/timeline.png)
40
42
 
41
43
  ---
42
44
 
@@ -82,6 +84,7 @@ source .zshrc # or .bashrc
82
84
 
83
85
  ## Architecture
84
86
 
87
+ **🔒Privacy-first by design** - Everything is stored locally
85
88
  ```
86
89
  Collectors (shell hook, git hooks, VS Code ext, AI log watcher)
87
90
  ↓ events (TSV files + HTTP POST)
@@ -1,13 +1,15 @@
1
1
  # Recall
2
2
 
3
- **Local-first developer memory layer.** Captures every developer activity terminal commands, git commits, file edits, repo opens, AI chat sessions into a structured SQLite database with a FAISS vector index. Enables natural language recall:
3
+ **Time-travel for your dev workflow.** Recall is a local-first CLI that automatically records your development activity and lets you search it in plain English.
4
4
 
5
5
  ```
6
- recall ask "what did I work on last Tuesday?"
7
- recall ask "how did I fix the auth bug?"
8
6
  recall today
7
+ ```
8
+ ![recall today](docs/today.png)
9
+ ```
9
10
  recall timeline
10
11
  ```
12
+ ![recall timeline](docs/timeline.png)
11
13
 
12
14
  ---
13
15
 
@@ -53,6 +55,7 @@ source .zshrc # or .bashrc
53
55
 
54
56
  ## Architecture
55
57
 
58
+ **🔒Privacy-first by design** - Everything is stored locally
56
59
  ```
57
60
  Collectors (shell hook, git hooks, VS Code ext, AI log watcher)
58
61
  ↓ events (TSV files + HTTP POST)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dev-recall
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Local-first developer memory layer
5
5
  License: MIT
6
6
  Keywords: developer-tools,memory,productivity,cli
@@ -29,14 +29,16 @@ Requires-Dist: docker>=7.0; extra == "linux"
29
29
 
30
30
  # Recall
31
31
 
32
- **Local-first developer memory layer.** Captures every developer activity terminal commands, git commits, file edits, repo opens, AI chat sessions into a structured SQLite database with a FAISS vector index. Enables natural language recall:
32
+ **Time-travel for your dev workflow.** Recall is a local-first CLI that automatically records your development activity and lets you search it in plain English.
33
33
 
34
34
  ```
35
- recall ask "what did I work on last Tuesday?"
36
- recall ask "how did I fix the auth bug?"
37
35
  recall today
36
+ ```
37
+ ![recall today](docs/today.png)
38
+ ```
38
39
  recall timeline
39
40
  ```
41
+ ![recall timeline](docs/timeline.png)
40
42
 
41
43
  ---
42
44
 
@@ -82,6 +84,7 @@ source .zshrc # or .bashrc
82
84
 
83
85
  ## Architecture
84
86
 
87
+ **🔒Privacy-first by design** - Everything is stored locally
85
88
  ```
86
89
  Collectors (shell hook, git hooks, VS Code ext, AI log watcher)
87
90
  ↓ events (TSV files + HTTP POST)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dev-recall"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  description = "Local-first developer memory layer"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -93,7 +93,7 @@ GIT_POST_COMMIT = r'''#!/bin/sh
93
93
  # Recall git post-commit hook
94
94
  # Installed globally via: git config --global core.hooksPath ~/.config/dev-recall/git-hooks/
95
95
 
96
- __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/devmem}"
96
+ __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/dev-recall}"
97
97
  REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
98
98
  HASH=$(git rev-parse HEAD 2>/dev/null) || exit 0
99
99
  MSG=$(git log -1 --format="%s" 2>/dev/null)
@@ -116,7 +116,7 @@ GIT_POST_CHECKOUT = r'''#!/bin/sh
116
116
  # Only record branch switches, not file checkouts
117
117
  [ "$3" = "1" ] || exit 0
118
118
 
119
- __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/devmem}"
119
+ __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/dev-recall}"
120
120
  REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
121
121
  NEW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
122
122
  OLD_BRANCH=$(git name-rev --name-only "$1" 2>/dev/null || echo "unknown")
@@ -134,7 +134,7 @@ GIT_PRE_PUSH = r'''#!/bin/sh
134
134
  # Installed globally via: git config --global core.hooksPath ~/.config/dev-recall/git-hooks/
135
135
 
136
136
  REMOTE="$1"
137
- __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/devmem}"
137
+ __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/dev-recall}"
138
138
  REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
139
139
  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
140
140
  TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -162,7 +162,7 @@ GIT_POST_MERGE = r'''#!/bin/sh
162
162
  # $1=1 if squash merge, 0 otherwise
163
163
 
164
164
  IS_SQUASH="${1:-0}"
165
- __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/devmem}"
165
+ __devrecall_dir="${DEV_RECALL_DATA_DIR:-$HOME/.local/share/dev-recall}"
166
166
  REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
167
167
  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
168
168
  TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -180,7 +180,7 @@ exit 0
180
180
  FISH_HOOK = r'''# Recall shell hook — source this in ~/.config/fish/config.fish
181
181
  # Installed by: recall init
182
182
 
183
- set -g __devrecall_dir (set -q DEV_RECALL_DATA_DIR; and echo $DEV_RECALL_DATA_DIR; or echo "$HOME/.local/share/devmem")
183
+ set -g __devrecall_dir (set -q DEV_RECALL_DATA_DIR; and echo $DEV_RECALL_DATA_DIR; or echo "$HOME/.local/share/dev-recall")
184
184
  set -g __devrecall_shell_log "$__devrecall_dir/shell.tsv"
185
185
  set -g __devrecall_cmd ""
186
186
  set -g __devrecall_start_ms 0
@@ -248,12 +248,20 @@ class AIChatCollector:
248
248
  # Copilot debug logs have various shapes — try common structures
249
249
  messages: list[dict] = []
250
250
 
251
- if "messages" in entry and isinstance(entry["messages"], list):
251
+ if entry.get("type") == "message" and "message" in entry and isinstance(entry["message"], dict):
252
+ # New message format: {"type": "message", "message": {"role": ..., "content": ...}}
253
+ messages = [entry["message"]]
254
+ elif "messages" in entry and isinstance(entry["messages"], list):
252
255
  messages = entry["messages"]
253
256
  elif "request" in entry and isinstance(entry.get("request"), dict):
254
257
  req = entry["request"]
255
258
  if "messages" in req:
256
259
  messages = req["messages"]
260
+ elif "response" in entry and isinstance(entry.get("response"), dict):
261
+ # Some logs might have response with messages
262
+ res = entry["response"]
263
+ if "messages" in res:
264
+ messages = res["messages"]
257
265
  elif "role" in entry and "content" in entry:
258
266
  messages = [entry]
259
267
 
@@ -488,7 +496,12 @@ class AIChatCollector:
488
496
  ai_source: str,
489
497
  source: Source,
490
498
  ) -> Optional[Event]:
491
- role = msg.get("role", "")
499
+ # Normalize roles to "user" or "assistant"
500
+ if role == "human":
501
+ role = "user"
502
+ elif role == "model":
503
+ role = "assistant"
504
+
492
505
  if role not in ("user", "assistant"):
493
506
  return None
494
507
 
@@ -600,12 +613,20 @@ def _extract_ts(entry: dict) -> str:
600
613
  """Extract a timestamp from a log entry dict, falling back to now."""
601
614
  for key in ("timestamp", "ts", "time", "created_at", "date"):
602
615
  if key in entry:
603
- val = str(entry[key])
604
- try:
605
- dt = datetime.fromisoformat(val.replace("Z", "+00:00"))
606
- return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
607
- except ValueError:
608
- pass
616
+ val = entry[key]
617
+ if isinstance(val, (int, float)):
618
+ # Assume Unix milliseconds
619
+ try:
620
+ dt = datetime.fromtimestamp(val / 1000, tz=timezone.utc)
621
+ return dt.strftime("%Y-%m-%dT%H:%M:%SZ")
622
+ except (ValueError, OSError):
623
+ pass
624
+ elif isinstance(val, str):
625
+ try:
626
+ dt = datetime.fromisoformat(val.replace("Z", "+00:00"))
627
+ return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
628
+ except ValueError:
629
+ pass
609
630
  return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
610
631
 
611
632
 
File without changes
File without changes
File without changes
File without changes
File without changes