research-git 0.0.4__tar.gz → 0.0.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 (90) hide show
  1. {research_git-0.0.4/src/research_git.egg-info → research_git-0.0.6}/PKG-INFO +31 -38
  2. {research_git-0.0.4 → research_git-0.0.6}/README.md +30 -37
  3. {research_git-0.0.4 → research_git-0.0.6}/pyproject.toml +1 -1
  4. {research_git-0.0.4 → research_git-0.0.6/src/research_git.egg-info}/PKG-INFO +31 -38
  5. {research_git-0.0.4 → research_git-0.0.6}/src/research_git.egg-info/SOURCES.txt +8 -0
  6. research_git-0.0.6/src/rgit/__init__.py +6 -0
  7. research_git-0.0.6/src/rgit/__main__.py +5 -0
  8. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/.claude-plugin/plugin.json +1 -1
  9. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/skills/rgit-capture/SKILL.md +1 -2
  10. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/skills/rgit-recall/SKILL.md +1 -2
  11. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/agent_guidance.py +86 -7
  12. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/cli.py +65 -2
  13. research_git-0.0.6/src/rgit/doctor.py +362 -0
  14. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/installer.py +31 -9
  15. research_git-0.0.6/src/rgit/selfupdate.py +103 -0
  16. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/db.py +22 -3
  17. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/models.py +21 -0
  18. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/objects.py +9 -3
  19. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/store.py +15 -6
  20. research_git-0.0.6/src/rgit/updatecheck.py +150 -0
  21. {research_git-0.0.4 → research_git-0.0.6}/tests/test_agent_guidance.py +124 -6
  22. {research_git-0.0.4 → research_git-0.0.6}/tests/test_cli.py +6 -6
  23. research_git-0.0.6/tests/test_cli_update.py +75 -0
  24. {research_git-0.0.4 → research_git-0.0.6}/tests/test_db.py +24 -0
  25. research_git-0.0.6/tests/test_doctor.py +313 -0
  26. {research_git-0.0.4 → research_git-0.0.6}/tests/test_installer.py +21 -6
  27. research_git-0.0.6/tests/test_selfupdate.py +128 -0
  28. {research_git-0.0.4 → research_git-0.0.6}/tests/test_store.py +28 -0
  29. research_git-0.0.6/tests/test_updatecheck.py +183 -0
  30. research_git-0.0.4/src/rgit/__init__.py +0 -1
  31. {research_git-0.0.4 → research_git-0.0.6}/LICENSE +0 -0
  32. {research_git-0.0.4 → research_git-0.0.6}/setup.cfg +0 -0
  33. {research_git-0.0.4 → research_git-0.0.6}/src/research_git.egg-info/dependency_links.txt +0 -0
  34. {research_git-0.0.4 → research_git-0.0.6}/src/research_git.egg-info/entry_points.txt +0 -0
  35. {research_git-0.0.4 → research_git-0.0.6}/src/research_git.egg-info/requires.txt +0 -0
  36. {research_git-0.0.4 → research_git-0.0.6}/src/research_git.egg-info/top_level.txt +0 -0
  37. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/.claude-plugin/marketplace.json +0 -0
  38. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/agents/capsule-regenerator.md +0 -0
  39. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/agents/capsule-segmenter.md +0 -0
  40. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/_plugin/agents/edge-judge.md +0 -0
  41. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/ablation.py +0 -0
  42. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/agent_platforms.py +0 -0
  43. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/astmap.py +0 -0
  44. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/compare.py +0 -0
  45. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/compose.py +0 -0
  46. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/curation.py +0 -0
  47. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/edges.py +0 -0
  48. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/gitutil.py +0 -0
  49. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/graphview.py +0 -0
  50. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/hooks.py +0 -0
  51. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/mcp_server.py +0 -0
  52. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/metricdir.py +0 -0
  53. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/metrics.py +0 -0
  54. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/provenance.py +0 -0
  55. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/ranking.py +0 -0
  56. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/recall.py +0 -0
  57. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/runner.py +0 -0
  58. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/segmenter.py +0 -0
  59. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/__init__.py +0 -0
  60. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/store/ids.py +0 -0
  61. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/tables.py +0 -0
  62. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/toggles.py +0 -0
  63. {research_git-0.0.4 → research_git-0.0.6}/src/rgit/watch.py +0 -0
  64. {research_git-0.0.4 → research_git-0.0.6}/tests/test_ablation.py +0 -0
  65. {research_git-0.0.4 → research_git-0.0.6}/tests/test_active_edges.py +0 -0
  66. {research_git-0.0.4 → research_git-0.0.6}/tests/test_astmap.py +0 -0
  67. {research_git-0.0.4 → research_git-0.0.6}/tests/test_compare.py +0 -0
  68. {research_git-0.0.4 → research_git-0.0.6}/tests/test_compose.py +0 -0
  69. {research_git-0.0.4 → research_git-0.0.6}/tests/test_curation.py +0 -0
  70. {research_git-0.0.4 → research_git-0.0.6}/tests/test_e2e.py +0 -0
  71. {research_git-0.0.4 → research_git-0.0.6}/tests/test_edges.py +0 -0
  72. {research_git-0.0.4 → research_git-0.0.6}/tests/test_gitutil.py +0 -0
  73. {research_git-0.0.4 → research_git-0.0.6}/tests/test_graphview.py +0 -0
  74. {research_git-0.0.4 → research_git-0.0.6}/tests/test_guidance_coupling.py +0 -0
  75. {research_git-0.0.4 → research_git-0.0.6}/tests/test_hooks.py +0 -0
  76. {research_git-0.0.4 → research_git-0.0.6}/tests/test_mcp_server.py +0 -0
  77. {research_git-0.0.4 → research_git-0.0.6}/tests/test_metricdir.py +0 -0
  78. {research_git-0.0.4 → research_git-0.0.6}/tests/test_metricdir_store.py +0 -0
  79. {research_git-0.0.4 → research_git-0.0.6}/tests/test_metrics.py +0 -0
  80. {research_git-0.0.4 → research_git-0.0.6}/tests/test_models.py +0 -0
  81. {research_git-0.0.4 → research_git-0.0.6}/tests/test_objects.py +0 -0
  82. {research_git-0.0.4 → research_git-0.0.6}/tests/test_provenance.py +0 -0
  83. {research_git-0.0.4 → research_git-0.0.6}/tests/test_ranking.py +0 -0
  84. {research_git-0.0.4 → research_git-0.0.6}/tests/test_recall.py +0 -0
  85. {research_git-0.0.4 → research_git-0.0.6}/tests/test_review_fixes.py +0 -0
  86. {research_git-0.0.4 → research_git-0.0.6}/tests/test_runner.py +0 -0
  87. {research_git-0.0.4 → research_git-0.0.6}/tests/test_segmenter.py +0 -0
  88. {research_git-0.0.4 → research_git-0.0.6}/tests/test_tables.py +0 -0
  89. {research_git-0.0.4 → research_git-0.0.6}/tests/test_toggles.py +0 -0
  90. {research_git-0.0.4 → research_git-0.0.6}/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.4
3
+ Version: 0.0.6
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
@@ -94,65 +94,58 @@ Capsules live in a small graph beside your repo (`.rgit/`), on top of normal git
94
94
 
95
95
  ## 🚀 Quick Start
96
96
 
97
- Five steps: install → init → run → capture → recall.
98
-
99
97
  ### 1. Install
100
98
 
101
99
  ```bash
102
- pip install research-git # or, from a clone: pip install -e .
103
-
104
- # wire the plugin (agents + skills) and the MCP server into your client
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
100
+ pip install research-git
101
+ rgit install # wires research-git into every agent client on this machine
102
+ cd your-project
103
+ rgit init # creates the .rgit/ store in your repo
108
104
  ```
109
105
 
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`.
106
+ That's the whole setup. Start a new agent session afterwards so it picks everything up.
111
107
 
112
- ### 2. Initialize in your repo
108
+ <details>
109
+ <summary>Install details: choosing platforms, guidance modes, capture-on-commit</summary>
113
110
 
114
- ```bash
115
- cd your-project
116
- rgit init # creates .rgit/ (the store) at the git root
117
- ```
111
+ - `rgit install claude-code` (or `codex` / `gemini` / `opencode` / `generic`) targets one client; `--list` shows all; `--uninstall` removes.
112
+ - The installer also writes a short guidance block into your client's global file (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, …) so the agent knows when to save ideas. On an interactive terminal you pick how proactive that should be (`default` / `manual-only` / `none`); pass `--guidance <mode>` to choose non-interactively.
113
+ - **Optional:** `rgit install-hooks` (per repo) makes every `git commit` stage its own snapshot automatically, so nothing slips through even when you forget. It never touches an existing hook, hooks never approve anything, and `rgit install-hooks --uninstall` removes it. Skip it in CI or shared clones.
114
+ - Manual route on Claude Code: `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
118
115
 
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:
116
+ </details>
120
117
 
121
- ```bash
122
- rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
123
- ```
118
+ ### 2. Working with an agent? Just talk to it
124
119
 
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`.
120
+ After install your agent does the remembering. Work as usual — it saves each meaningful idea as a Feature Capsule (asking you before anything is kept). Weeks later, when the code has moved on, just ask:
126
121
 
127
- ### 3. Run a variation and capture the idea
122
+ > *"bring back the re-ranking retrieval step"*
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:
124
+ The agent finds the capsule and **re-implements the idea onto today's code**, leaving you a reviewable diff. No commands to memorize but if you like being explicit, `/rgit-capture` saves recent work and `/rgit-recall <what you want back>` brings an idea home.
125
+
126
+ ### 3. Working in the terminal? Three commands
130
127
 
131
128
  ```bash
132
- rgit run -- python eval_agent.py --retrieval rerank
129
+ rgit run -- python eval_agent.py --retrieval rerank # run an experiment; freezes a byte-exact snapshot + metrics
130
+ rgit review # see what's been captured, approve what's worth keeping
131
+ rgit compare rerank # which variant won?
133
132
  ```
134
133
 
135
- Then turn that raw material into a clean capsule (in a Claude Code session):
136
-
137
- ```
138
- /rgit-capture # segments the diff into Feature Capsules, then wires up graph edges
139
- rgit review # list proposals
140
- rgit review --approve <proposal_id> --name rerank-retrieval
141
- ```
134
+ `rgit capture` saves the current changes (or the last commit) when you're not using `rgit run`. Bringing an idea *back* needs an agent session — that's where the intelligence lives; from the terminal you can always browse the memory with `rgit features` and `rgit graph`.
142
135
 
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.)
136
+ More commands as your store grows: [More commands](#more-commands).
144
137
 
145
- ### 4. Bring an idea back onto today's code
138
+ ---
146
139
 
147
- Weeks later, after the agent has moved on:
140
+ ## Updating
148
141
 
149
- ```
150
- /rgit-recall bring back the re-ranking retrieval step
142
+ ```bash
143
+ rgit update
151
144
  ```
152
145
 
153
- Recall scores capsules against your query, surfaces each hit with its related neighbors, then dispatches a subagent that *re-implements* the idea onto today's structure adapting to refactors and leaving you a reviewable diff.
146
+ Upgrades the package (via whichever of uv/pipx/pip installed it) and refreshes every installed platform surface: the Claude Code plugin copy, MCP config, and the managed guidance blocks. Guidance blocks you have customized or removed are left alone — the command tells you how to restore them instead.
154
147
 
155
- That's the whole loop. The rest of the commands you'll meet as you need themsee [More commands](#more-commands).
148
+ rgit checks PyPI for a newer release at most once a day (in the background, terminal sessions only). Once one is found, it prints a one-line upgrade notice after every qualifying command until you upgrade or turn the notice off the check is throttled, the reminder is not. Silence it for good with `rgit update --off`, or per-environment with `RGIT_UPDATE_CHECK=0`.
156
149
 
157
150
  ---
158
151
 
@@ -207,7 +200,7 @@ The five-step loop above is the core. These show up as your store grows — run
207
200
  |---------|--------------|
208
201
  | `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
209
202
  | `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 |
203
+ | `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 install details above |
211
204
  | `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
212
205
  | `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
213
206
  | `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
@@ -68,65 +68,58 @@ Capsules live in a small graph beside your repo (`.rgit/`), on top of normal git
68
68
 
69
69
  ## 🚀 Quick Start
70
70
 
71
- Five steps: install → init → run → capture → recall.
72
-
73
71
  ### 1. Install
74
72
 
75
73
  ```bash
76
- pip install research-git # or, from a clone: pip install -e .
77
-
78
- # wire the plugin (agents + skills) and the MCP server into your client
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
74
+ pip install research-git
75
+ rgit install # wires research-git into every agent client on this machine
76
+ cd your-project
77
+ rgit init # creates the .rgit/ store in your repo
82
78
  ```
83
79
 
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`.
80
+ That's the whole setup. Start a new agent session afterwards so it picks everything up.
85
81
 
86
- ### 2. Initialize in your repo
82
+ <details>
83
+ <summary>Install details: choosing platforms, guidance modes, capture-on-commit</summary>
87
84
 
88
- ```bash
89
- cd your-project
90
- rgit init # creates .rgit/ (the store) at the git root
91
- ```
85
+ - `rgit install claude-code` (or `codex` / `gemini` / `opencode` / `generic`) targets one client; `--list` shows all; `--uninstall` removes.
86
+ - The installer also writes a short guidance block into your client's global file (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, …) so the agent knows when to save ideas. On an interactive terminal you pick how proactive that should be (`default` / `manual-only` / `none`); pass `--guidance <mode>` to choose non-interactively.
87
+ - **Optional:** `rgit install-hooks` (per repo) makes every `git commit` stage its own snapshot automatically, so nothing slips through even when you forget. It never touches an existing hook, hooks never approve anything, and `rgit install-hooks --uninstall` removes it. Skip it in CI or shared clones.
88
+ - Manual route on Claude Code: `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
92
89
 
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:
90
+ </details>
94
91
 
95
- ```bash
96
- rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
97
- ```
92
+ ### 2. Working with an agent? Just talk to it
98
93
 
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`.
94
+ After install your agent does the remembering. Work as usual — it saves each meaningful idea as a Feature Capsule (asking you before anything is kept). Weeks later, when the code has moved on, just ask:
100
95
 
101
- ### 3. Run a variation and capture the idea
96
+ > *"bring back the re-ranking retrieval step"*
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:
98
+ The agent finds the capsule and **re-implements the idea onto today's code**, leaving you a reviewable diff. No commands to memorize but if you like being explicit, `/rgit-capture` saves recent work and `/rgit-recall <what you want back>` brings an idea home.
99
+
100
+ ### 3. Working in the terminal? Three commands
104
101
 
105
102
  ```bash
106
- rgit run -- python eval_agent.py --retrieval rerank
103
+ rgit run -- python eval_agent.py --retrieval rerank # run an experiment; freezes a byte-exact snapshot + metrics
104
+ rgit review # see what's been captured, approve what's worth keeping
105
+ rgit compare rerank # which variant won?
107
106
  ```
108
107
 
109
- Then turn that raw material into a clean capsule (in a Claude Code session):
110
-
111
- ```
112
- /rgit-capture # segments the diff into Feature Capsules, then wires up graph edges
113
- rgit review # list proposals
114
- rgit review --approve <proposal_id> --name rerank-retrieval
115
- ```
108
+ `rgit capture` saves the current changes (or the last commit) when you're not using `rgit run`. Bringing an idea *back* needs an agent session — that's where the intelligence lives; from the terminal you can always browse the memory with `rgit features` and `rgit graph`.
116
109
 
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.)
110
+ More commands as your store grows: [More commands](#more-commands).
118
111
 
119
- ### 4. Bring an idea back onto today's code
112
+ ---
120
113
 
121
- Weeks later, after the agent has moved on:
114
+ ## Updating
122
115
 
123
- ```
124
- /rgit-recall bring back the re-ranking retrieval step
116
+ ```bash
117
+ rgit update
125
118
  ```
126
119
 
127
- Recall scores capsules against your query, surfaces each hit with its related neighbors, then dispatches a subagent that *re-implements* the idea onto today's structure adapting to refactors and leaving you a reviewable diff.
120
+ Upgrades the package (via whichever of uv/pipx/pip installed it) and refreshes every installed platform surface: the Claude Code plugin copy, MCP config, and the managed guidance blocks. Guidance blocks you have customized or removed are left alone — the command tells you how to restore them instead.
128
121
 
129
- That's the whole loop. The rest of the commands you'll meet as you need themsee [More commands](#more-commands).
122
+ rgit checks PyPI for a newer release at most once a day (in the background, terminal sessions only). Once one is found, it prints a one-line upgrade notice after every qualifying command until you upgrade or turn the notice off the check is throttled, the reminder is not. Silence it for good with `rgit update --off`, or per-environment with `RGIT_UPDATE_CHECK=0`.
130
123
 
131
124
  ---
132
125
 
@@ -181,7 +174,7 @@ The five-step loop above is the core. These show up as your store grows — run
181
174
  |---------|--------------|
182
175
  | `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
183
176
  | `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 |
177
+ | `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 install details above |
185
178
  | `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
186
179
  | `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
187
180
  | `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "research-git"
3
- version = "0.0.4"
3
+ version = "0.0.6"
4
4
  description = "A memory system that captures code ideas as semantic capsules you can regenerate onto today's codebase"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: research-git
3
- Version: 0.0.4
3
+ Version: 0.0.6
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
@@ -94,65 +94,58 @@ Capsules live in a small graph beside your repo (`.rgit/`), on top of normal git
94
94
 
95
95
  ## 🚀 Quick Start
96
96
 
97
- Five steps: install → init → run → capture → recall.
98
-
99
97
  ### 1. Install
100
98
 
101
99
  ```bash
102
- pip install research-git # or, from a clone: pip install -e .
103
-
104
- # wire the plugin (agents + skills) and the MCP server into your client
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
100
+ pip install research-git
101
+ rgit install # wires research-git into every agent client on this machine
102
+ cd your-project
103
+ rgit init # creates the .rgit/ store in your repo
108
104
  ```
109
105
 
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`.
106
+ That's the whole setup. Start a new agent session afterwards so it picks everything up.
111
107
 
112
- ### 2. Initialize in your repo
108
+ <details>
109
+ <summary>Install details: choosing platforms, guidance modes, capture-on-commit</summary>
113
110
 
114
- ```bash
115
- cd your-project
116
- rgit init # creates .rgit/ (the store) at the git root
117
- ```
111
+ - `rgit install claude-code` (or `codex` / `gemini` / `opencode` / `generic`) targets one client; `--list` shows all; `--uninstall` removes.
112
+ - The installer also writes a short guidance block into your client's global file (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, …) so the agent knows when to save ideas. On an interactive terminal you pick how proactive that should be (`default` / `manual-only` / `none`); pass `--guidance <mode>` to choose non-interactively.
113
+ - **Optional:** `rgit install-hooks` (per repo) makes every `git commit` stage its own snapshot automatically, so nothing slips through even when you forget. It never touches an existing hook, hooks never approve anything, and `rgit install-hooks --uninstall` removes it. Skip it in CI or shared clones.
114
+ - Manual route on Claude Code: `/plugin marketplace add StepzeroLab/research-git` then `/plugin install research-git@research-git`.
118
115
 
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:
116
+ </details>
120
117
 
121
- ```bash
122
- rgit install-hooks # adds a post-commit hook (never clobbers an existing one)
123
- ```
118
+ ### 2. Working with an agent? Just talk to it
124
119
 
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`.
120
+ After install your agent does the remembering. Work as usual — it saves each meaningful idea as a Feature Capsule (asking you before anything is kept). Weeks later, when the code has moved on, just ask:
126
121
 
127
- ### 3. Run a variation and capture the idea
122
+ > *"bring back the re-ranking retrieval step"*
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:
124
+ The agent finds the capsule and **re-implements the idea onto today's code**, leaving you a reviewable diff. No commands to memorize but if you like being explicit, `/rgit-capture` saves recent work and `/rgit-recall <what you want back>` brings an idea home.
125
+
126
+ ### 3. Working in the terminal? Three commands
130
127
 
131
128
  ```bash
132
- rgit run -- python eval_agent.py --retrieval rerank
129
+ rgit run -- python eval_agent.py --retrieval rerank # run an experiment; freezes a byte-exact snapshot + metrics
130
+ rgit review # see what's been captured, approve what's worth keeping
131
+ rgit compare rerank # which variant won?
133
132
  ```
134
133
 
135
- Then turn that raw material into a clean capsule (in a Claude Code session):
136
-
137
- ```
138
- /rgit-capture # segments the diff into Feature Capsules, then wires up graph edges
139
- rgit review # list proposals
140
- rgit review --approve <proposal_id> --name rerank-retrieval
141
- ```
134
+ `rgit capture` saves the current changes (or the last commit) when you're not using `rgit run`. Bringing an idea *back* needs an agent session — that's where the intelligence lives; from the terminal you can always browse the memory with `rgit features` and `rgit graph`.
142
135
 
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.)
136
+ More commands as your store grows: [More commands](#more-commands).
144
137
 
145
- ### 4. Bring an idea back onto today's code
138
+ ---
146
139
 
147
- Weeks later, after the agent has moved on:
140
+ ## Updating
148
141
 
149
- ```
150
- /rgit-recall bring back the re-ranking retrieval step
142
+ ```bash
143
+ rgit update
151
144
  ```
152
145
 
153
- Recall scores capsules against your query, surfaces each hit with its related neighbors, then dispatches a subagent that *re-implements* the idea onto today's structure adapting to refactors and leaving you a reviewable diff.
146
+ Upgrades the package (via whichever of uv/pipx/pip installed it) and refreshes every installed platform surface: the Claude Code plugin copy, MCP config, and the managed guidance blocks. Guidance blocks you have customized or removed are left alone — the command tells you how to restore them instead.
154
147
 
155
- That's the whole loop. The rest of the commands you'll meet as you need themsee [More commands](#more-commands).
148
+ rgit checks PyPI for a newer release at most once a day (in the background, terminal sessions only). Once one is found, it prints a one-line upgrade notice after every qualifying command until you upgrade or turn the notice off the check is throttled, the reminder is not. Silence it for good with `rgit update --off`, or per-environment with `RGIT_UPDATE_CHECK=0`.
156
149
 
157
150
  ---
158
151
 
@@ -207,7 +200,7 @@ The five-step loop above is the core. These show up as your store grows — run
207
200
  |---------|--------------|
208
201
  | `rgit watch` | free, deterministic background capture — stages raw material as you edit, so fleeting in-between states aren't lost |
209
202
  | `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 |
203
+ | `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 install details above |
211
204
  | `rgit run --from <capsule>` | run a recalled variant and link the new run as a `variant_of` the original |
212
205
  | `rgit compare <query>` | which variant won: ranked table, Δ vs baseline, ★ winner |
213
206
  | `rgit provenance <run_id>` | per-feature clean (capsule) vs agent-adapted (frozen) diff for a run |
@@ -8,6 +8,7 @@ src/research_git.egg-info/entry_points.txt
8
8
  src/research_git.egg-info/requires.txt
9
9
  src/research_git.egg-info/top_level.txt
10
10
  src/rgit/__init__.py
11
+ src/rgit/__main__.py
11
12
  src/rgit/ablation.py
12
13
  src/rgit/agent_guidance.py
13
14
  src/rgit/agent_platforms.py
@@ -16,6 +17,7 @@ src/rgit/cli.py
16
17
  src/rgit/compare.py
17
18
  src/rgit/compose.py
18
19
  src/rgit/curation.py
20
+ src/rgit/doctor.py
19
21
  src/rgit/edges.py
20
22
  src/rgit/gitutil.py
21
23
  src/rgit/graphview.py
@@ -29,8 +31,10 @@ src/rgit/ranking.py
29
31
  src/rgit/recall.py
30
32
  src/rgit/runner.py
31
33
  src/rgit/segmenter.py
34
+ src/rgit/selfupdate.py
32
35
  src/rgit/tables.py
33
36
  src/rgit/toggles.py
37
+ src/rgit/updatecheck.py
34
38
  src/rgit/watch.py
35
39
  src/rgit/_plugin/.claude-plugin/marketplace.json
36
40
  src/rgit/_plugin/.claude-plugin/plugin.json
@@ -50,10 +54,12 @@ tests/test_active_edges.py
50
54
  tests/test_agent_guidance.py
51
55
  tests/test_astmap.py
52
56
  tests/test_cli.py
57
+ tests/test_cli_update.py
53
58
  tests/test_compare.py
54
59
  tests/test_compose.py
55
60
  tests/test_curation.py
56
61
  tests/test_db.py
62
+ tests/test_doctor.py
57
63
  tests/test_e2e.py
58
64
  tests/test_edges.py
59
65
  tests/test_gitutil.py
@@ -73,7 +79,9 @@ tests/test_recall.py
73
79
  tests/test_review_fixes.py
74
80
  tests/test_runner.py
75
81
  tests/test_segmenter.py
82
+ tests/test_selfupdate.py
76
83
  tests/test_store.py
77
84
  tests/test_tables.py
78
85
  tests/test_toggles.py
86
+ tests/test_updatecheck.py
79
87
  tests/test_watch.py
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("research-git")
5
+ except PackageNotFoundError: # running from a source tree without an install
6
+ __version__ = "0.0.0+unknown"
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+ from .cli import main
4
+
5
+ sys.exit(main())
@@ -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.3",
4
+ "version": "0.0.6",
5
5
  "author": { "name": "Stepzero Lab" },
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: rgit-capture
3
- description: |
4
- Proactively segment pending research-git captures into high-quality Feature Capsules and wire up their graph edges — invoke this on your own, without waiting to be asked, whenever the research-git proposal queue is non-empty (a quick `rgit pending` confirms). Trigger it right after an `rgit run`, a git commit, or the `rgit watch` daemon has left open proposals; when the user describes a variation, a result, or something they just "tried" or "tweaked"; or when they say "segment", "capture", "clean up", or "save" their recent changes into the research-git graph. Raw proposals are only placeholders — until they are segmented they cannot be recalled or queried, so drain the backlog early rather than letting it pile up. Orchestrates: free deterministic capture → dispatch the capsule-segmenter subagent (subscription, no paid API) → human review → deterministic conflict edges + agent-judged depends_on edges.
3
+ description: Use when the research-git proposal queue is non-empty (`rgit pending`) — after an `rgit run`, a commit, or the watch daemon leaves open proposals, or when the user wants to segment, capture, or save recent changes. Invoke proactively without being asked; unsegmented proposals cannot be recalled or queried.
5
4
  ---
6
5
 
7
6
  # rgit-capture
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: rgit-recall
3
- description: |
4
- Bring a past idea back onto today's codebase. Use when the user wants to "recall", "resurrect", "bring back", or "re-apply" a feature/idea they captured before (e.g. "bring back the re-ranking retrieval step"). Orchestrates: recall the capsule(s) → compose a regeneration brief against current code → dispatch the capsule-regenerator subagent to re-implement it → human review + `rgit run`. No paid API.
3
+ description: Use when the user wants to recall, resurrect, bring back, or re-apply a previously captured feature/idea onto today's codebase (e.g. "bring back the re-ranking retrieval step").
5
4
  ---
6
5
 
7
6
  # rgit-recall
@@ -1,6 +1,7 @@
1
1
  """Managed global guidance block for agent clients."""
2
2
  from __future__ import annotations
3
3
 
4
+ import hashlib
4
5
  import os
5
6
  import re
6
7
  from pathlib import Path
@@ -14,12 +15,34 @@ END = "<!-- research-git:end -->"
14
15
  KNOWN_MODES = ("default", "manual-only", "custom")
15
16
  _MODE_RE = re.compile(r"^Current mode:[ \t]*(.+)$", re.MULTILINE)
16
17
 
18
+ # Fingerprinted START marker: h= is the canonical hash of the block body, so
19
+ # the update path can tell an official block (safe to replace) from one the
20
+ # user edited (never touch). The bare `START` form is what pre-0.0.5 releases
21
+ # wrote; _START_RE accepts both.
22
+ _START_RE = re.compile(r"<!-- research-git:start(?: h=([0-9a-f]{12}))? -->")
23
+
24
+ # canonical_hash of every official block body ever shipped without a
25
+ # fingerprint (see docs/superpowers/specs/2026-07-04-runtime-update-check-design.md).
26
+ HISTORICAL_HASHES = frozenset({
27
+ "9e20fa27047f", # v0.0.1 - v0.0.3
28
+ "c7d73fc2ba60", # v0.0.4
29
+ })
30
+
31
+
32
+ def canonical_hash(block: str) -> str:
33
+ """12-hex digest of a block's body: markers and mode line excluded, so the
34
+ hash survives mode pinning and marker-format changes."""
35
+ lines = block.strip().splitlines()
36
+ body = [l.rstrip() for l in lines[1:-1]
37
+ if not l.startswith("Current mode:")]
38
+ text = "\n".join(body).strip() + "\n"
39
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()[:12]
40
+
17
41
 
18
42
  def render_global_block(mode: str = "default") -> str:
19
43
  if mode not in KNOWN_MODES:
20
44
  mode = "default"
21
- return (
22
- f"{START}\n"
45
+ body = (
23
46
  "## research-git\n"
24
47
  "\n"
25
48
  "research-git is installed as a default agent capability.\n"
@@ -63,8 +86,10 @@ def render_global_block(mode: str = "default") -> str:
63
86
  "silently.\n"
64
87
  "- In final feedback, mention any capsules created, approved, applied, "
65
88
  "or skipped, plus important graph relations.\n"
66
- f"{END}\n"
67
89
  )
90
+ provisional = f"{START}\n{body}{END}\n"
91
+ h = canonical_hash(provisional)
92
+ return f"<!-- research-git:start h={h} -->\n{body}{END}\n"
68
93
 
69
94
 
70
95
  def manual_status(mode: str = "default") -> dict:
@@ -149,16 +174,70 @@ def _carry_mode(old_block: str, new_block: str) -> str:
149
174
 
150
175
 
151
176
  def _managed_span(text: str) -> tuple[int, int] | None:
152
- start = text.find(START)
153
- if start < 0:
177
+ m = _START_RE.search(text)
178
+ if m is None:
154
179
  return None
155
- end = text.find(END, start)
180
+ end = text.find(END, m.start())
156
181
  if end < 0:
157
182
  return None
158
183
  after_end = end + len(END)
159
184
  if text[after_end:after_end + 1] == "\n":
160
185
  after_end += 1
161
- return start, after_end
186
+ return m.start(), after_end
187
+
188
+
189
+ def classify_block(text: str) -> str:
190
+ """absent | broken | pristine | customized (update-path policy input)."""
191
+ span = _managed_span(text)
192
+ if span is None:
193
+ if _START_RE.search(text) or END in text:
194
+ return "broken"
195
+ return "absent"
196
+ block = text[span[0]:span[1]]
197
+ h = canonical_hash(block)
198
+ stamped = _START_RE.match(block).group(1)
199
+ if h == stamped or h in HISTORICAL_HASHES \
200
+ or h == canonical_hash(render_global_block()):
201
+ return "pristine"
202
+ return "customized"
203
+
204
+
205
+ def refresh_managed_block(path: Path, *, dry_run: bool = False) -> dict:
206
+ """Update-path guidance refresh: replace only pristine official blocks.
207
+
208
+ Unlike upsert_managed_block (explicit-install semantics), this never
209
+ appends a missing block and never overwrites user edits - it skips and
210
+ explains instead. `dry_run` short-circuits the only writing path (a
211
+ pending update to a pristine block) and reports `would_update` instead;
212
+ the skip/absent branches are already read-only.
213
+ """
214
+ if not path.exists():
215
+ return {"action": "absent_file", "path": str(path)}
216
+ text = path.read_text(encoding="utf-8")
217
+ kind = classify_block(text)
218
+ if kind == "absent":
219
+ return {"action": "skipped_removed", "path": str(path),
220
+ "hint": (f"no research-git block in {path} (removed on "
221
+ f"purpose?) — run `rgit install` to restore it")}
222
+ if kind == "broken":
223
+ return {"action": "skipped_broken", "path": str(path),
224
+ "hint": (f"research-git markers in {path} look damaged (one "
225
+ f"of the start/end pair is missing) — fix or remove "
226
+ f"them manually, then run `rgit install`")}
227
+ if kind == "customized":
228
+ return {"action": "skipped_customized", "path": str(path),
229
+ "hint": (f"customized research-git block in {path} left "
230
+ f"untouched — run `rgit install` to overwrite it "
231
+ f"with the new official version")}
232
+ start, end = _managed_span(text)
233
+ block = _carry_mode(text[start:end], render_global_block("default"))
234
+ new_text = text[:start] + block + text[end:]
235
+ if new_text == text:
236
+ return {"action": "unchanged", "path": str(path)}
237
+ if dry_run:
238
+ return {"action": "would_update", "path": str(path)}
239
+ _atomic_write(path, new_text)
240
+ return {"action": "updated", "path": str(path)}
162
241
 
163
242
 
164
243
  def _dry_action(action: str) -> str: