research-git 0.0.1__tar.gz → 0.0.2__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.
- {research_git-0.0.1/src/research_git.egg-info → research_git-0.0.2}/PKG-INFO +1 -1
- {research_git-0.0.1 → research_git-0.0.2}/pyproject.toml +1 -1
- {research_git-0.0.1 → research_git-0.0.2/src/research_git.egg-info}/PKG-INFO +1 -1
- research_git-0.0.2/src/rgit/__init__.py +1 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/.claude-plugin/plugin.json +1 -1
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/agent_guidance.py +4 -1
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_agent_guidance.py +11 -9
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_installer.py +7 -7
- research_git-0.0.1/src/rgit/__init__.py +0 -1
- {research_git-0.0.1 → research_git-0.0.2}/LICENSE +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/README.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/setup.cfg +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/research_git.egg-info/SOURCES.txt +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/research_git.egg-info/dependency_links.txt +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/research_git.egg-info/entry_points.txt +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/research_git.egg-info/requires.txt +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/research_git.egg-info/top_level.txt +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/.claude-plugin/marketplace.json +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/agents/capsule-regenerator.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/agents/capsule-segmenter.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/agents/edge-judge.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/skills/rgit-capture/SKILL.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/_plugin/skills/rgit-recall/SKILL.md +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/ablation.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/agent_platforms.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/astmap.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/cli.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/compare.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/compose.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/curation.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/edges.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/gitutil.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/graphview.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/hooks.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/installer.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/mcp_server.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/metricdir.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/metrics.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/provenance.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/ranking.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/recall.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/runner.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/segmenter.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/__init__.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/db.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/ids.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/models.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/objects.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/store/store.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/tables.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/toggles.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/src/rgit/watch.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_ablation.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_active_edges.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_astmap.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_cli.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_compare.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_compose.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_curation.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_db.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_e2e.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_edges.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_gitutil.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_graphview.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_guidance_coupling.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_hooks.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_mcp_server.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_metricdir.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_metricdir_store.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_metrics.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_models.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_objects.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_provenance.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_ranking.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_recall.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_review_fixes.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_runner.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_segmenter.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_store.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_tables.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_toggles.py +0 -0
- {research_git-0.0.1 → research_git-0.0.2}/tests/test_watch.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.2"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "research-git",
|
|
3
3
|
"description": "A memory system for the code you're exploring: capture each idea as a semantic Feature Capsule, recall it, and regenerate it onto today's codebase. Segmentation/regeneration run on natively-dispatched subagents (your subscription) — no pay-per-use API. MCP serves the graph read-only for sharing.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"author": { "name": "Stepzero Lab" },
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -163,7 +163,10 @@ def _dry_action(action: str) -> str:
|
|
|
163
163
|
|
|
164
164
|
def _atomic_write(path: Path, text: str) -> None:
|
|
165
165
|
tmp = path.with_name(f".{path.name}.research-git.tmp")
|
|
166
|
-
|
|
166
|
+
# newline="" disables newline translation so the user's exact text (LF) is
|
|
167
|
+
# preserved byte-for-byte — on Windows write_text would otherwise rewrite
|
|
168
|
+
# every "\n" to "\r\n" and corrupt the surrounding user content.
|
|
169
|
+
tmp.write_text(text, encoding="utf-8", newline="")
|
|
167
170
|
if path.exists():
|
|
168
171
|
os.chmod(tmp, path.stat().st_mode)
|
|
169
172
|
tmp.replace(path)
|
|
@@ -20,7 +20,7 @@ def test_upsert_creates_parent_and_file(tmp_path):
|
|
|
20
20
|
|
|
21
21
|
assert res["action"] == "created"
|
|
22
22
|
assert res["path"] == str(path)
|
|
23
|
-
text = path.read_text()
|
|
23
|
+
text = path.read_text(encoding="utf-8")
|
|
24
24
|
assert text.count(agent_guidance.START) == 1
|
|
25
25
|
assert text.count(agent_guidance.END) == 1
|
|
26
26
|
|
|
@@ -28,12 +28,12 @@ def test_upsert_creates_parent_and_file(tmp_path):
|
|
|
28
28
|
def test_upsert_appends_without_changing_existing_text(tmp_path):
|
|
29
29
|
path = tmp_path / "AGENTS.md"
|
|
30
30
|
original = "# Project notes\n\nKeep tests focused.\n"
|
|
31
|
-
path.write_text(original)
|
|
31
|
+
path.write_text(original, encoding="utf-8")
|
|
32
32
|
|
|
33
33
|
res = agent_guidance.upsert_managed_block(path)
|
|
34
34
|
|
|
35
35
|
assert res["action"] == "appended"
|
|
36
|
-
text = path.read_text()
|
|
36
|
+
text = path.read_text(encoding="utf-8")
|
|
37
37
|
assert text.startswith(original)
|
|
38
38
|
assert text.count(agent_guidance.START) == 1
|
|
39
39
|
assert "Current mode: default" in text
|
|
@@ -44,13 +44,14 @@ def test_upsert_replaces_existing_managed_block_without_duplication(tmp_path):
|
|
|
44
44
|
path.write_text(
|
|
45
45
|
"before\n"
|
|
46
46
|
f"{agent_guidance.START}\nold unique phrase\n{agent_guidance.END}\n"
|
|
47
|
-
"after\n"
|
|
47
|
+
"after\n",
|
|
48
|
+
encoding="utf-8",
|
|
48
49
|
)
|
|
49
50
|
|
|
50
51
|
res = agent_guidance.upsert_managed_block(path)
|
|
51
52
|
|
|
52
53
|
assert res["action"] == "updated"
|
|
53
|
-
text = path.read_text()
|
|
54
|
+
text = path.read_text(encoding="utf-8")
|
|
54
55
|
assert "before\n" in text
|
|
55
56
|
assert "after\n" in text
|
|
56
57
|
assert "old unique phrase" not in text
|
|
@@ -92,13 +93,14 @@ def test_remove_managed_block_preserves_user_text(tmp_path):
|
|
|
92
93
|
path.write_text(
|
|
93
94
|
"before\n"
|
|
94
95
|
f"{agent_guidance.START}\nmanaged\n{agent_guidance.END}\n"
|
|
95
|
-
"after\n"
|
|
96
|
+
"after\n",
|
|
97
|
+
encoding="utf-8",
|
|
96
98
|
)
|
|
97
99
|
|
|
98
100
|
res = agent_guidance.remove_managed_block(path)
|
|
99
101
|
|
|
100
102
|
assert res["action"] == "removed"
|
|
101
|
-
text = path.read_text()
|
|
103
|
+
text = path.read_text(encoding="utf-8")
|
|
102
104
|
assert "before\n" in text
|
|
103
105
|
assert "after\n" in text
|
|
104
106
|
assert agent_guidance.START not in text
|
|
@@ -110,9 +112,9 @@ def test_remove_reports_absent_for_missing_file_or_no_block(tmp_path):
|
|
|
110
112
|
assert agent_guidance.remove_managed_block(missing)["action"] == "absent"
|
|
111
113
|
|
|
112
114
|
plain = tmp_path / "plain.md"
|
|
113
|
-
plain.write_text("user text\n")
|
|
115
|
+
plain.write_text("user text\n", encoding="utf-8")
|
|
114
116
|
assert agent_guidance.remove_managed_block(plain)["action"] == "absent"
|
|
115
|
-
assert plain.read_text() == "user text\n"
|
|
117
|
+
assert plain.read_text(encoding="utf-8") == "user text\n"
|
|
116
118
|
|
|
117
119
|
|
|
118
120
|
def test_manual_uninstall_status_does_not_tell_user_to_add_block():
|
|
@@ -213,7 +213,7 @@ def test_uninstall_claude_code_keeps_guidance_when_cli_command_fails(
|
|
|
213
213
|
fake_home, monkeypatch):
|
|
214
214
|
guidance = fake_home / ".claude" / "CLAUDE.md"
|
|
215
215
|
guidance.parent.mkdir(parents=True)
|
|
216
|
-
guidance.write_text(agent_guidance.render_global_block())
|
|
216
|
+
guidance.write_text(agent_guidance.render_global_block(), encoding="utf-8")
|
|
217
217
|
|
|
218
218
|
def fail(plan):
|
|
219
219
|
return [{"cmd": plan[0], "rc": 1, "out": "remove failed"}]
|
|
@@ -224,7 +224,7 @@ def test_uninstall_claude_code_keeps_guidance_when_cli_command_fails(
|
|
|
224
224
|
|
|
225
225
|
assert res["guidance"]["action"] == "skipped_error"
|
|
226
226
|
assert "uninstall commands failed" in res["guidance"]["error"]
|
|
227
|
-
assert agent_guidance.START in guidance.read_text()
|
|
227
|
+
assert agent_guidance.START in guidance.read_text(encoding="utf-8")
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
def test_install_codex_writes_guidance_and_symlinks_under_fake_home(fake_home):
|
|
@@ -234,7 +234,7 @@ def test_install_codex_writes_guidance_and_symlinks_under_fake_home(fake_home):
|
|
|
234
234
|
assert (fake_home / ".agents" / "skills" / "rgit-capture").is_symlink()
|
|
235
235
|
guidance = fake_home / ".codex" / "AGENTS.md"
|
|
236
236
|
assert guidance.exists()
|
|
237
|
-
assert guidance.read_text().count(agent_guidance.START) == 1
|
|
237
|
+
assert guidance.read_text(encoding="utf-8").count(agent_guidance.START) == 1
|
|
238
238
|
assert res["guidance"]["action"] == "created"
|
|
239
239
|
|
|
240
240
|
|
|
@@ -243,7 +243,7 @@ def test_install_codex_is_idempotent_for_guidance(fake_home):
|
|
|
243
243
|
res = installer.install("codex")
|
|
244
244
|
|
|
245
245
|
guidance = fake_home / ".codex" / "AGENTS.md"
|
|
246
|
-
assert guidance.read_text().count(agent_guidance.START) == 1
|
|
246
|
+
assert guidance.read_text(encoding="utf-8").count(agent_guidance.START) == 1
|
|
247
247
|
assert res["guidance"]["action"] == "unchanged"
|
|
248
248
|
|
|
249
249
|
|
|
@@ -251,12 +251,12 @@ def test_uninstall_codex_removes_only_managed_guidance(fake_home):
|
|
|
251
251
|
guidance = fake_home / ".codex" / "AGENTS.md"
|
|
252
252
|
block = agent_guidance.render_global_block()
|
|
253
253
|
guidance.parent.mkdir(parents=True)
|
|
254
|
-
guidance.write_text("before\n" + block + "\nafter\n")
|
|
254
|
+
guidance.write_text("before\n" + block + "\nafter\n", encoding="utf-8")
|
|
255
255
|
|
|
256
256
|
res = installer.uninstall("codex")
|
|
257
257
|
|
|
258
258
|
assert res["guidance"]["action"] == "removed"
|
|
259
|
-
text = guidance.read_text()
|
|
259
|
+
text = guidance.read_text(encoding="utf-8")
|
|
260
260
|
assert "before\n" in text
|
|
261
261
|
assert "after\n" in text
|
|
262
262
|
assert agent_guidance.START not in text
|
|
@@ -308,7 +308,7 @@ def test_edge_judge_agent_is_packaged():
|
|
|
308
308
|
|
|
309
309
|
def test_capture_skill_uses_cli_not_mcp_write_tools():
|
|
310
310
|
from rgit import installer
|
|
311
|
-
skill = (installer.plugin_dir() / "skills" / "rgit-capture" / "SKILL.md").read_text()
|
|
311
|
+
skill = (installer.plugin_dir() / "skills" / "rgit-capture" / "SKILL.md").read_text(encoding="utf-8")
|
|
312
312
|
assert "rgit pending" in skill
|
|
313
313
|
assert "rgit resegment" in skill
|
|
314
314
|
assert "pending_captures" not in skill # MCP write tools are gone
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|