ragtime-cli 0.2.11__py3-none-any.whl → 0.2.12__py3-none-any.whl
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.
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/METADATA +1 -1
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/RECORD +9 -9
- src/cli.py +45 -0
- src/mcp_server.py +1 -1
- src/memory.py +13 -1
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/WHEEL +0 -0
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/entry_points.txt +0 -0
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/licenses/LICENSE +0 -0
- {ragtime_cli-0.2.11.dist-info → ragtime_cli-0.2.12.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ragtime-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.12
|
|
4
4
|
Summary: Local-first memory and RAG system for Claude Code - semantic search over code, docs, and team knowledge
|
|
5
5
|
Author-email: Bret Martineau <bretwardjames@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
ragtime_cli-0.2.
|
|
1
|
+
ragtime_cli-0.2.12.dist-info/licenses/LICENSE,sha256=9A0wJs2PRDciGRH4F8JUJ-aMKYQyq_gVu2ixrXs-l5A,1070
|
|
2
2
|
src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
src/cli.py,sha256=
|
|
3
|
+
src/cli.py,sha256=Do9R2ItJAGQ3tkTXpTs-4zJhIwDo97clmIuWzM5TVAA,75989
|
|
4
4
|
src/config.py,sha256=tQ6gPLr4ksn2bJPIUjtELFr-k01Eg4g-LDo3GNE6P0Q,4600
|
|
5
5
|
src/db.py,sha256=ueSThFXkhI5MFwXICkNW3zqCawGDi3kqFQnbm4st_Ew,8186
|
|
6
|
-
src/mcp_server.py,sha256=
|
|
7
|
-
src/memory.py,sha256=
|
|
6
|
+
src/mcp_server.py,sha256=BFu6LcaGkKgFhQf52t9hUyrBL2nX1LT3YuACg6OwD2M,21559
|
|
7
|
+
src/memory.py,sha256=VHbKGaBRLQEkUhlzryM0HIZZANipZGLd4Jw_LbY0gwY,16131
|
|
8
8
|
src/commands/audit.md,sha256=Xkucm-gfBIMalK9wf7NBbyejpsqBTUAGGlb7GxMtMPY,5137
|
|
9
9
|
src/commands/create-pr.md,sha256=u6-jVkDP_6bJQp6ImK039eY9F6B9E2KlAVlvLY-WV6Q,9483
|
|
10
10
|
src/commands/generate-docs.md,sha256=9W2Yy-PDyC3p5k39uEb31z5YAHkSKsQLg6gV3tLgSnQ,7015
|
|
@@ -18,8 +18,8 @@ src/commands/start.md,sha256=qoqhkMgET74DBx8YPIT1-wqCiVBUDxlmevigsCinHSY,6506
|
|
|
18
18
|
src/indexers/__init__.py,sha256=MYoCPZUpHakMX1s2vWnc9shjWfx_X1_0JzUhpKhnKUQ,454
|
|
19
19
|
src/indexers/code.py,sha256=G2TbiKbWj0e7DV5KsU8-Ggw6ziDb4zTuZ4Bu3ryV4g8,18059
|
|
20
20
|
src/indexers/docs.py,sha256=nyewQ4Ug4SCuhne4TuLDlUDzz9GH2STInddj81ocz50,3555
|
|
21
|
-
ragtime_cli-0.2.
|
|
22
|
-
ragtime_cli-0.2.
|
|
23
|
-
ragtime_cli-0.2.
|
|
24
|
-
ragtime_cli-0.2.
|
|
25
|
-
ragtime_cli-0.2.
|
|
21
|
+
ragtime_cli-0.2.12.dist-info/METADATA,sha256=s8nahuddN_C6gMGMt0TFp62HU8gD1Agz_da8lnQMMoU,11269
|
|
22
|
+
ragtime_cli-0.2.12.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
23
|
+
ragtime_cli-0.2.12.dist-info/entry_points.txt,sha256=cWLbeyMxZNbew-THS3bHXTpCRXt1EaUy5QUOXGXLjl4,75
|
|
24
|
+
ragtime_cli-0.2.12.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
|
|
25
|
+
ragtime_cli-0.2.12.dist-info/RECORD,,
|
src/cli.py
CHANGED
|
@@ -734,6 +734,51 @@ def reindex(path: Path):
|
|
|
734
734
|
click.echo(f"✓ Reindexed {count} memory files")
|
|
735
735
|
|
|
736
736
|
|
|
737
|
+
@main.command()
|
|
738
|
+
@click.option("--path", type=click.Path(exists=True, path_type=Path), default=".")
|
|
739
|
+
@click.option("--dry-run", is_flag=True, help="Show duplicates without removing them")
|
|
740
|
+
def dedupe(path: Path, dry_run: bool):
|
|
741
|
+
"""Remove duplicate entries from the index.
|
|
742
|
+
|
|
743
|
+
Keeps one entry per unique file path, removing duplicates created
|
|
744
|
+
by older versions of reindex that generated random IDs.
|
|
745
|
+
"""
|
|
746
|
+
path = Path(path).resolve()
|
|
747
|
+
db = get_db(path)
|
|
748
|
+
|
|
749
|
+
# Get all entries with their file paths
|
|
750
|
+
results = db.collection.get(include=["metadatas"])
|
|
751
|
+
|
|
752
|
+
# Group by file path
|
|
753
|
+
by_file: dict[str, list[str]] = {}
|
|
754
|
+
for i, mem_id in enumerate(results["ids"]):
|
|
755
|
+
file_path = results["metadatas"][i].get("file", "")
|
|
756
|
+
if file_path:
|
|
757
|
+
if file_path not in by_file:
|
|
758
|
+
by_file[file_path] = []
|
|
759
|
+
by_file[file_path].append(mem_id)
|
|
760
|
+
|
|
761
|
+
# Find duplicates
|
|
762
|
+
duplicates_to_remove = []
|
|
763
|
+
for file_path, ids in by_file.items():
|
|
764
|
+
if len(ids) > 1:
|
|
765
|
+
# Keep the first one, remove the rest
|
|
766
|
+
duplicates_to_remove.extend(ids[1:])
|
|
767
|
+
if dry_run:
|
|
768
|
+
click.echo(f" {file_path}: {len(ids)} copies (would remove {len(ids) - 1})")
|
|
769
|
+
|
|
770
|
+
if not duplicates_to_remove:
|
|
771
|
+
click.echo("✓ No duplicates found")
|
|
772
|
+
return
|
|
773
|
+
|
|
774
|
+
if dry_run:
|
|
775
|
+
click.echo(f"\nWould remove {len(duplicates_to_remove)} duplicate entries")
|
|
776
|
+
click.echo("Run without --dry-run to remove them")
|
|
777
|
+
else:
|
|
778
|
+
db.delete(duplicates_to_remove)
|
|
779
|
+
click.echo(f"✓ Removed {len(duplicates_to_remove)} duplicate entries")
|
|
780
|
+
|
|
781
|
+
|
|
737
782
|
@main.command("new-branch")
|
|
738
783
|
@click.argument("issue", type=int)
|
|
739
784
|
@click.option("--path", type=click.Path(exists=True, path_type=Path), default=".")
|
src/mcp_server.py
CHANGED
src/memory.py
CHANGED
|
@@ -10,6 +10,7 @@ from dataclasses import dataclass, field
|
|
|
10
10
|
from datetime import date
|
|
11
11
|
from typing import Optional
|
|
12
12
|
import uuid
|
|
13
|
+
import hashlib
|
|
13
14
|
import re
|
|
14
15
|
import yaml
|
|
15
16
|
|
|
@@ -139,8 +140,19 @@ class Memory:
|
|
|
139
140
|
except ValueError:
|
|
140
141
|
pass # path not relative to base, will regenerate
|
|
141
142
|
|
|
143
|
+
# Use frontmatter ID if present, otherwise derive stable ID from file path
|
|
144
|
+
# This ensures reindex is idempotent - same file always gets same ID
|
|
145
|
+
if "id" in frontmatter:
|
|
146
|
+
memory_id = frontmatter["id"]
|
|
147
|
+
elif file_path:
|
|
148
|
+
# Stable hash of relative path
|
|
149
|
+
memory_id = hashlib.sha256(file_path.encode()).hexdigest()[:8]
|
|
150
|
+
else:
|
|
151
|
+
# Fallback: hash of absolute path
|
|
152
|
+
memory_id = hashlib.sha256(str(path).encode()).hexdigest()[:8]
|
|
153
|
+
|
|
142
154
|
return cls(
|
|
143
|
-
id=
|
|
155
|
+
id=memory_id,
|
|
144
156
|
content=content,
|
|
145
157
|
namespace=frontmatter.get("namespace", "app"),
|
|
146
158
|
type=frontmatter.get("type", "unknown"),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|