research-git 0.0.3__tar.gz → 0.0.4__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.3/src/research_git.egg-info → research_git-0.0.4}/PKG-INFO +21 -12
- {research_git-0.0.3 → research_git-0.0.4}/README.md +20 -11
- {research_git-0.0.3 → research_git-0.0.4}/pyproject.toml +1 -1
- {research_git-0.0.3 → research_git-0.0.4/src/research_git.egg-info}/PKG-INFO +21 -12
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/skills/rgit-capture/SKILL.md +4 -1
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/agent_guidance.py +14 -6
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/astmap.py +26 -31
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/cli.py +448 -41
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/curation.py +4 -1
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/gitutil.py +203 -1
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/hooks.py +13 -2
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/installer.py +21 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/segmenter.py +47 -8
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/db.py +4 -1
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/models.py +1 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/store.py +5 -3
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_agent_guidance.py +18 -1
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_astmap.py +26 -0
- research_git-0.0.4/tests/test_cli.py +1247 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_curation.py +31 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_e2e.py +41 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_gitutil.py +207 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_hooks.py +28 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_installer.py +21 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_segmenter.py +59 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_store.py +37 -0
- research_git-0.0.3/tests/test_cli.py +0 -551
- {research_git-0.0.3 → research_git-0.0.4}/LICENSE +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/setup.cfg +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/research_git.egg-info/SOURCES.txt +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/research_git.egg-info/dependency_links.txt +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/research_git.egg-info/entry_points.txt +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/research_git.egg-info/requires.txt +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/research_git.egg-info/top_level.txt +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/__init__.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/.claude-plugin/marketplace.json +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/.claude-plugin/plugin.json +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/agents/capsule-regenerator.md +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/agents/capsule-segmenter.md +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/agents/edge-judge.md +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/_plugin/skills/rgit-recall/SKILL.md +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/ablation.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/agent_platforms.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/compare.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/compose.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/edges.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/graphview.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/mcp_server.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/metricdir.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/metrics.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/provenance.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/ranking.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/recall.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/runner.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/__init__.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/ids.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/store/objects.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/tables.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/toggles.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/src/rgit/watch.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_ablation.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_active_edges.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_compare.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_compose.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_db.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_edges.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_graphview.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_guidance_coupling.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_mcp_server.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_metricdir.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_metricdir_store.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_metrics.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_models.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_objects.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_provenance.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_ranking.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_recall.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_review_fixes.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_runner.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_tables.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_toggles.py +0 -0
- {research_git-0.0.3 → research_git-0.0.4}/tests/test_watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: research-git
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A memory system that captures code ideas as semantic capsules you can regenerate onto today's codebase
|
|
5
5
|
Author: Stepzero Lab
|
|
6
6
|
License-Expression: MIT
|
|
@@ -43,15 +43,13 @@ Dynamic: license-file
|
|
|
43
43
|
<strong>Git recovers history. It can't recover an entangled idea onto today's code.</strong>
|
|
44
44
|
</p>
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Git can't do that. Its unit is a *tree snapshot*, not an *idea*. `git checkout` drags back everything from that moment and throws away all the infrastructure you've built since. You can't pull one feature forward without rolling back the rest.
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="assets/hero.png" alt="Capture a code idea as a clean semantic unit — regenerate it onto today's codebase." width="800" />
|
|
48
|
+
</p>
|
|
51
49
|
|
|
52
|
-
research-git
|
|
50
|
+
research-git captures experiments as Feature Capsules, then regenerates the one you need onto your current agent, using your existing Coding Plan subscription, no pay-per-use API.
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
> **Think of it as Git for agentic coding experiments: not just recovering old code, but bringing old ideas back into today’s code.**
|
|
55
53
|
|
|
56
54
|
---
|
|
57
55
|
|
|
@@ -104,9 +102,9 @@ Five steps: install → init → run → capture → recall.
|
|
|
104
102
|
pip install research-git # or, from a clone: pip install -e .
|
|
105
103
|
|
|
106
104
|
# wire the plugin (agents + skills) and the MCP server into your client
|
|
107
|
-
rgit install
|
|
108
|
-
rgit install
|
|
109
|
-
rgit install --list #
|
|
105
|
+
rgit install # auto-detects every agent client on this machine and wires them all
|
|
106
|
+
rgit install claude-code # or pick one explicitly (claude-code / codex / gemini / opencode / generic)
|
|
107
|
+
rgit install --list # list platforms; --uninstall to remove
|
|
110
108
|
```
|
|
111
109
|
|
|
112
110
|
`codex`, `gemini`, and `opencode` share the `~/.agents/skills/` convention — the installer symlinks each skill there and prints the one-line MCP server entry to drop into that client's config. It also writes a managed research-git guidance block into the client's global guidance file when the platform has one (`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, or `~/.gemini/GEMINI.md`). On an interactive terminal you're asked how proactive capture should be — `default`, `manual-only`, or `none`; pass `--guidance <mode>` to choose non-interactively. Start a new agent session after install so the guidance is loaded. Prefer the manual route on Claude Code? `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
|
|
@@ -118,6 +116,14 @@ cd your-project
|
|
|
118
116
|
rgit init # creates .rgit/ (the store) at the git root
|
|
119
117
|
```
|
|
120
118
|
|
|
119
|
+
**Optional — capture on every commit.** `rgit install <platform>` wires the agent side only; it deliberately does **not** touch your git hooks. If you also want every `git commit` to stage its own diff as a pending proposal automatically, opt in with:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Good fit: solo research repos where you want nothing to slip through, even when you forget to capture. Skip it if the repo already has its own post-commit hook (the installer refuses to touch foreign hooks, so nothing breaks — it just won't install), if your team prefers deliberate manual capture, or in CI/shared clones where commit-time side effects are unwelcome. Without hooks you lose nothing: bare `rgit capture` takes the last commit when the tree is clean, `rgit capture A..B` a whole span, and `rgit review` is the gate either way — hooks only stage proposals, they never approve anything. Remove with `rgit install-hooks --uninstall`.
|
|
126
|
+
|
|
121
127
|
### 3. Run a variation and capture the idea
|
|
122
128
|
|
|
123
129
|
Launch your work through `rgit run` — it executes your command, freezes a reproducible artifact, records the run + any metrics, and stages what changed:
|
|
@@ -134,6 +140,8 @@ rgit review # list proposals
|
|
|
134
140
|
rgit review --approve <proposal_id> --name rerank-retrieval
|
|
135
141
|
```
|
|
136
142
|
|
|
143
|
+
Committed before capturing? Just run `rgit capture` — on a clean tree it captures the last commit (and says which one); `rgit capture main..HEAD` takes a whole span. (With the optional post-commit hook installed, every commit stages itself automatically.)
|
|
144
|
+
|
|
137
145
|
### 4. Bring an idea back onto today's code
|
|
138
146
|
|
|
139
147
|
Weeks later, after the agent has moved on:
|
|
@@ -198,7 +206,8 @@ The five-step loop above is the core. These show up as your store grows — run
|
|
|
198
206
|
| Command | What it does |
|
|
199
207
|
|---------|--------------|
|
|
200
208
|
| `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
|
|
201
|
-
| `rgit
|
|
209
|
+
| `rgit capture [REV \| A..B]` | bare: auto-picks the working tree or, when clean, the last commit; pass a commit or an A..B range for precise control |
|
|
210
|
+
| `rgit install-hooks` | opt-in: stage every commit's diff via a post-commit hook (not installed by `rgit install`; won't touch an existing hook) — see step 2 above |
|
|
202
211
|
| `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
|
|
203
212
|
| `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
|
|
204
213
|
| `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
|
|
@@ -17,15 +17,13 @@
|
|
|
17
17
|
<strong>Git recovers history. It can't recover an entangled idea onto today's code.</strong>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Git can't do that. Its unit is a *tree snapshot*, not an *idea*. `git checkout` drags back everything from that moment and throws away all the infrastructure you've built since. You can't pull one feature forward without rolling back the rest.
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="assets/hero.png" alt="Capture a code idea as a clean semantic unit — regenerate it onto today's codebase." width="800" />
|
|
22
|
+
</p>
|
|
25
23
|
|
|
26
|
-
research-git
|
|
24
|
+
research-git captures experiments as Feature Capsules, then regenerates the one you need onto your current agent, using your existing Coding Plan subscription, no pay-per-use API.
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
> **Think of it as Git for agentic coding experiments: not just recovering old code, but bringing old ideas back into today’s code.**
|
|
29
27
|
|
|
30
28
|
---
|
|
31
29
|
|
|
@@ -78,9 +76,9 @@ Five steps: install → init → run → capture → recall.
|
|
|
78
76
|
pip install research-git # or, from a clone: pip install -e .
|
|
79
77
|
|
|
80
78
|
# wire the plugin (agents + skills) and the MCP server into your client
|
|
81
|
-
rgit install
|
|
82
|
-
rgit install
|
|
83
|
-
rgit install --list #
|
|
79
|
+
rgit install # auto-detects every agent client on this machine and wires them all
|
|
80
|
+
rgit install claude-code # or pick one explicitly (claude-code / codex / gemini / opencode / generic)
|
|
81
|
+
rgit install --list # list platforms; --uninstall to remove
|
|
84
82
|
```
|
|
85
83
|
|
|
86
84
|
`codex`, `gemini`, and `opencode` share the `~/.agents/skills/` convention — the installer symlinks each skill there and prints the one-line MCP server entry to drop into that client's config. It also writes a managed research-git guidance block into the client's global guidance file when the platform has one (`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, or `~/.gemini/GEMINI.md`). On an interactive terminal you're asked how proactive capture should be — `default`, `manual-only`, or `none`; pass `--guidance <mode>` to choose non-interactively. Start a new agent session after install so the guidance is loaded. Prefer the manual route on Claude Code? `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
|
|
@@ -92,6 +90,14 @@ cd your-project
|
|
|
92
90
|
rgit init # creates .rgit/ (the store) at the git root
|
|
93
91
|
```
|
|
94
92
|
|
|
93
|
+
**Optional — capture on every commit.** `rgit install <platform>` wires the agent side only; it deliberately does **not** touch your git hooks. If you also want every `git commit` to stage its own diff as a pending proposal automatically, opt in with:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Good fit: solo research repos where you want nothing to slip through, even when you forget to capture. Skip it if the repo already has its own post-commit hook (the installer refuses to touch foreign hooks, so nothing breaks — it just won't install), if your team prefers deliberate manual capture, or in CI/shared clones where commit-time side effects are unwelcome. Without hooks you lose nothing: bare `rgit capture` takes the last commit when the tree is clean, `rgit capture A..B` a whole span, and `rgit review` is the gate either way — hooks only stage proposals, they never approve anything. Remove with `rgit install-hooks --uninstall`.
|
|
100
|
+
|
|
95
101
|
### 3. Run a variation and capture the idea
|
|
96
102
|
|
|
97
103
|
Launch your work through `rgit run` — it executes your command, freezes a reproducible artifact, records the run + any metrics, and stages what changed:
|
|
@@ -108,6 +114,8 @@ rgit review # list proposals
|
|
|
108
114
|
rgit review --approve <proposal_id> --name rerank-retrieval
|
|
109
115
|
```
|
|
110
116
|
|
|
117
|
+
Committed before capturing? Just run `rgit capture` — on a clean tree it captures the last commit (and says which one); `rgit capture main..HEAD` takes a whole span. (With the optional post-commit hook installed, every commit stages itself automatically.)
|
|
118
|
+
|
|
111
119
|
### 4. Bring an idea back onto today's code
|
|
112
120
|
|
|
113
121
|
Weeks later, after the agent has moved on:
|
|
@@ -172,7 +180,8 @@ The five-step loop above is the core. These show up as your store grows — run
|
|
|
172
180
|
| Command | What it does |
|
|
173
181
|
|---------|--------------|
|
|
174
182
|
| `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
|
|
175
|
-
| `rgit
|
|
183
|
+
| `rgit capture [REV \| A..B]` | bare: auto-picks the working tree or, when clean, the last commit; pass a commit or an A..B range for precise control |
|
|
184
|
+
| `rgit install-hooks` | opt-in: stage every commit's diff via a post-commit hook (not installed by `rgit install`; won't touch an existing hook) — see step 2 above |
|
|
176
185
|
| `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
|
|
177
186
|
| `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
|
|
178
187
|
| `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: research-git
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A memory system that captures code ideas as semantic capsules you can regenerate onto today's codebase
|
|
5
5
|
Author: Stepzero Lab
|
|
6
6
|
License-Expression: MIT
|
|
@@ -43,15 +43,13 @@ Dynamic: license-file
|
|
|
43
43
|
<strong>Git recovers history. It can't recover an entangled idea onto today's code.</strong>
|
|
44
44
|
</p>
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Git can't do that. Its unit is a *tree snapshot*, not an *idea*. `git checkout` drags back everything from that moment and throws away all the infrastructure you've built since. You can't pull one feature forward without rolling back the rest.
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="assets/hero.png" alt="Capture a code idea as a clean semantic unit — regenerate it onto today's codebase." width="800" />
|
|
48
|
+
</p>
|
|
51
49
|
|
|
52
|
-
research-git
|
|
50
|
+
research-git captures experiments as Feature Capsules, then regenerates the one you need onto your current agent, using your existing Coding Plan subscription, no pay-per-use API.
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
> **Think of it as Git for agentic coding experiments: not just recovering old code, but bringing old ideas back into today’s code.**
|
|
55
53
|
|
|
56
54
|
---
|
|
57
55
|
|
|
@@ -104,9 +102,9 @@ Five steps: install → init → run → capture → recall.
|
|
|
104
102
|
pip install research-git # or, from a clone: pip install -e .
|
|
105
103
|
|
|
106
104
|
# wire the plugin (agents + skills) and the MCP server into your client
|
|
107
|
-
rgit install
|
|
108
|
-
rgit install
|
|
109
|
-
rgit install --list #
|
|
105
|
+
rgit install # auto-detects every agent client on this machine and wires them all
|
|
106
|
+
rgit install claude-code # or pick one explicitly (claude-code / codex / gemini / opencode / generic)
|
|
107
|
+
rgit install --list # list platforms; --uninstall to remove
|
|
110
108
|
```
|
|
111
109
|
|
|
112
110
|
`codex`, `gemini`, and `opencode` share the `~/.agents/skills/` convention — the installer symlinks each skill there and prints the one-line MCP server entry to drop into that client's config. It also writes a managed research-git guidance block into the client's global guidance file when the platform has one (`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, or `~/.gemini/GEMINI.md`). On an interactive terminal you're asked how proactive capture should be — `default`, `manual-only`, or `none`; pass `--guidance <mode>` to choose non-interactively. Start a new agent session after install so the guidance is loaded. Prefer the manual route on Claude Code? `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
|
|
@@ -118,6 +116,14 @@ cd your-project
|
|
|
118
116
|
rgit init # creates .rgit/ (the store) at the git root
|
|
119
117
|
```
|
|
120
118
|
|
|
119
|
+
**Optional — capture on every commit.** `rgit install <platform>` wires the agent side only; it deliberately does **not** touch your git hooks. If you also want every `git commit` to stage its own diff as a pending proposal automatically, opt in with:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Good fit: solo research repos where you want nothing to slip through, even when you forget to capture. Skip it if the repo already has its own post-commit hook (the installer refuses to touch foreign hooks, so nothing breaks — it just won't install), if your team prefers deliberate manual capture, or in CI/shared clones where commit-time side effects are unwelcome. Without hooks you lose nothing: bare `rgit capture` takes the last commit when the tree is clean, `rgit capture A..B` a whole span, and `rgit review` is the gate either way — hooks only stage proposals, they never approve anything. Remove with `rgit install-hooks --uninstall`.
|
|
126
|
+
|
|
121
127
|
### 3. Run a variation and capture the idea
|
|
122
128
|
|
|
123
129
|
Launch your work through `rgit run` — it executes your command, freezes a reproducible artifact, records the run + any metrics, and stages what changed:
|
|
@@ -134,6 +140,8 @@ rgit review # list proposals
|
|
|
134
140
|
rgit review --approve <proposal_id> --name rerank-retrieval
|
|
135
141
|
```
|
|
136
142
|
|
|
143
|
+
Committed before capturing? Just run `rgit capture` — on a clean tree it captures the last commit (and says which one); `rgit capture main..HEAD` takes a whole span. (With the optional post-commit hook installed, every commit stages itself automatically.)
|
|
144
|
+
|
|
137
145
|
### 4. Bring an idea back onto today's code
|
|
138
146
|
|
|
139
147
|
Weeks later, after the agent has moved on:
|
|
@@ -198,7 +206,8 @@ The five-step loop above is the core. These show up as your store grows — run
|
|
|
198
206
|
| Command | What it does |
|
|
199
207
|
|---------|--------------|
|
|
200
208
|
| `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
|
|
201
|
-
| `rgit
|
|
209
|
+
| `rgit capture [REV \| A..B]` | bare: auto-picks the working tree or, when clean, the last commit; pass a commit or an A..B range for precise control |
|
|
210
|
+
| `rgit install-hooks` | opt-in: stage every commit's diff via a post-commit hook (not installed by `rgit install`; won't touch an existing hook) — see step 2 above |
|
|
202
211
|
| `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
|
|
203
212
|
| `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
|
|
204
213
|
| `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
|
|
@@ -26,9 +26,12 @@ Every `agents/<name>.md` reference below (`agents/capsule-segmenter.md`, `agents
|
|
|
26
26
|
If the user just made changes and there is no open proposal yet, create one:
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
rgit capture
|
|
29
|
+
rgit capture # picks for you: uncommitted work, or the last commit when the tree is clean
|
|
30
|
+
rgit capture main..HEAD # a specific span of commits (any A..B range)
|
|
30
31
|
```
|
|
31
32
|
|
|
33
|
+
The bare form auto-picks its source, so it works the same before or after a `git commit`; repeated captures of the same diff dedup into the existing proposal. If the repo has the post-commit hook installed (`rgit install-hooks`), each commit is captured automatically; don't capture the same commit twice.
|
|
34
|
+
|
|
32
35
|
This runs the libcst symbol mapping + the free heuristic, producing one or more open proposals with a raw diff and a crude candidate. Proposals also appear automatically from `rgit run`, the post-commit hook, and the `rgit watch` daemon.
|
|
33
36
|
|
|
34
37
|
### 2. Read the pending captures
|
|
@@ -45,14 +45,22 @@ def render_global_block(mode: str = "default") -> str:
|
|
|
45
45
|
"- Do not write repo preferences for one-off session instructions.\n"
|
|
46
46
|
"\n"
|
|
47
47
|
"Use:\n"
|
|
48
|
-
"- After meaningful code/research changes,
|
|
49
|
-
"
|
|
48
|
+
"- After meaningful code/research changes, run `rgit capture` — it "
|
|
49
|
+
"captures uncommitted work, or the last commit when the tree is "
|
|
50
|
+
"clean, so committing first is fine. Then use the `rgit-capture` "
|
|
51
|
+
"skill to segment.\n"
|
|
52
|
+
"- For a specific span of commits: `rgit capture main..HEAD` (any "
|
|
53
|
+
"A..B range works).\n"
|
|
54
|
+
"- If a post-commit hook is installed (`rgit install-hooks`), commits "
|
|
55
|
+
"are captured automatically; do not capture the same commit again.\n"
|
|
56
|
+
"- Skip mechanical formatting, dependency churn, generated files, or "
|
|
57
|
+
"changes with no reusable research/code idea.\n"
|
|
50
58
|
"- For recall/resurrection requests, use the `rgit-recall` skill.\n"
|
|
51
59
|
"- If `.rgit/` is missing in a git repo: when operating autonomously "
|
|
52
|
-
"(no human to ask), bootstrap the store with `rgit capture --init "
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
60
|
+
"(no human to ask), bootstrap the store with `rgit capture --init` "
|
|
61
|
+
"(store only — never install hooks unless asked); in an interactive "
|
|
62
|
+
"session, tell the user to run `rgit init` rather than initializing "
|
|
63
|
+
"silently.\n"
|
|
56
64
|
"- In final feedback, mention any capsules created, approved, applied, "
|
|
57
65
|
"or skipped, plus important graph relations.\n"
|
|
58
66
|
f"{END}\n"
|
|
@@ -1,34 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import re
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
4
|
+
from typing import Callable, Optional
|
|
5
5
|
|
|
6
6
|
import libcst as cst
|
|
7
7
|
from libcst.metadata import MetadataWrapper, PositionProvider
|
|
8
8
|
|
|
9
|
-
from .gitutil import
|
|
9
|
+
from .gitutil import parse_git_diff_header, read_worktree_python
|
|
10
10
|
|
|
11
11
|
_HUNK = re.compile(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", re.M)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def _read_python_source(path: Path) -> str:
|
|
15
|
-
"""Read a .py file for parsing. ``utf-8-sig`` strips a UTF-8 BOM (common on
|
|
16
|
-
Windows-authored files) that would otherwise make libcst miss the first
|
|
17
|
-
symbol — and it also reads plain UTF-8 unchanged."""
|
|
18
|
-
return path.read_text(encoding="utf-8-sig")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _python_source_path(repo: Path, file: str) -> Optional[Path]:
|
|
22
|
-
"""Repo-contained regular Python file, without following external symlinks."""
|
|
23
|
-
path = repo / file
|
|
24
|
-
if path.suffix != ".py" or not _within(repo, path):
|
|
25
|
-
return None
|
|
26
|
-
try:
|
|
27
|
-
return path if path.is_file() else None
|
|
28
|
-
except OSError:
|
|
29
|
-
return None
|
|
30
|
-
|
|
31
|
-
|
|
32
14
|
def _changed_line_ranges(diff: str) -> dict[str, list[tuple[int, int]]]:
|
|
33
15
|
"""file -> list of (start, end) ranges of *actually changed* new-side lines.
|
|
34
16
|
|
|
@@ -99,15 +81,28 @@ class _SymbolFinder(cst.CSTVisitor):
|
|
|
99
81
|
self.found.add(node.name.value)
|
|
100
82
|
|
|
101
83
|
|
|
102
|
-
def changed_symbols(diff: str, repo: Path
|
|
103
|
-
|
|
84
|
+
def changed_symbols(diff: str, repo: Path,
|
|
85
|
+
read_source: Optional[Callable[[str], Optional[str]]] = None,
|
|
86
|
+
) -> list[dict]:
|
|
87
|
+
"""[{file, symbol}] for each top-level def/class overlapping a diff hunk.
|
|
88
|
+
|
|
89
|
+
`read_source(file)` supplies the new-side source text (None skips the
|
|
90
|
+
file); the default reads the working tree. Committed-diff capture passes a
|
|
91
|
+
reader pinned to the captured commit, so symbol mapping cannot drift when
|
|
92
|
+
the worktree has moved past — or never matched — the diff being segmented
|
|
93
|
+
(e.g. a partially staged commit).
|
|
94
|
+
"""
|
|
95
|
+
if read_source is None:
|
|
96
|
+
read_source = lambda file: read_worktree_python(repo, file) # noqa: E731
|
|
104
97
|
out: list[dict] = []
|
|
105
98
|
for file, ranges in _changed_line_ranges(diff).items():
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
if not ranges:
|
|
100
|
+
continue
|
|
101
|
+
text = read_source(file)
|
|
102
|
+
if text is None:
|
|
108
103
|
continue
|
|
109
104
|
try:
|
|
110
|
-
wrapper = MetadataWrapper(cst.parse_module(
|
|
105
|
+
wrapper = MetadataWrapper(cst.parse_module(text))
|
|
111
106
|
except (cst.ParserSyntaxError, UnicodeDecodeError):
|
|
112
107
|
continue
|
|
113
108
|
finder = _SymbolFinder(ranges)
|
|
@@ -119,11 +114,11 @@ def changed_symbols(diff: str, repo: Path) -> list[dict]:
|
|
|
119
114
|
|
|
120
115
|
def read_symbol_source(repo: Path, file: str, symbol: str) -> Optional[str]:
|
|
121
116
|
"""Current source text of a top-level def/class, or None if absent."""
|
|
122
|
-
|
|
123
|
-
if
|
|
117
|
+
text = read_worktree_python(repo, file)
|
|
118
|
+
if text is None:
|
|
124
119
|
return None
|
|
125
120
|
try:
|
|
126
|
-
module = cst.parse_module(
|
|
121
|
+
module = cst.parse_module(text)
|
|
127
122
|
except (cst.ParserSyntaxError, UnicodeDecodeError):
|
|
128
123
|
return None
|
|
129
124
|
for stmt in module.body:
|
|
@@ -134,11 +129,11 @@ def read_symbol_source(repo: Path, file: str, symbol: str) -> Optional[str]:
|
|
|
134
129
|
|
|
135
130
|
def symbol_at_line(repo: Path, file: str, line: int) -> Optional[str]:
|
|
136
131
|
"""Name of the top-level def/class enclosing `line` (1-based), or None."""
|
|
137
|
-
|
|
138
|
-
if
|
|
132
|
+
text = read_worktree_python(repo, file)
|
|
133
|
+
if text is None:
|
|
139
134
|
return None
|
|
140
135
|
try:
|
|
141
|
-
wrapper = MetadataWrapper(cst.parse_module(
|
|
136
|
+
wrapper = MetadataWrapper(cst.parse_module(text))
|
|
142
137
|
except (cst.ParserSyntaxError, UnicodeDecodeError):
|
|
143
138
|
return None
|
|
144
139
|
finder = _SymbolFinder([(line, line)])
|