rewindex 0.1.0__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.
- rewindex-0.1.0/LICENSE +20 -0
- rewindex-0.1.0/PKG-INFO +12 -0
- rewindex-0.1.0/README.md +433 -0
- rewindex-0.1.0/pyproject.toml +28 -0
- rewindex-0.1.0/rewindex/__init__.py +4 -0
- rewindex-0.1.0/rewindex/agent/__init__.py +2 -0
- rewindex-0.1.0/rewindex/agent/detector.py +40 -0
- rewindex-0.1.0/rewindex/agent/plugins/__init__.py +24 -0
- rewindex-0.1.0/rewindex/agent/plugins/aider.py +9 -0
- rewindex-0.1.0/rewindex/agent/plugins/base.py +18 -0
- rewindex-0.1.0/rewindex/agent/plugins/claude_code.py +9 -0
- rewindex-0.1.0/rewindex/agent/plugins/cursor.py +9 -0
- rewindex-0.1.0/rewindex/agent/plugins/nanobot.py +9 -0
- rewindex-0.1.0/rewindex/agent/registry.py +85 -0
- rewindex-0.1.0/rewindex/autostart/__init__.py +2 -0
- rewindex-0.1.0/rewindex/autostart/linux.py +61 -0
- rewindex-0.1.0/rewindex/autostart/macos.py +73 -0
- rewindex-0.1.0/rewindex/cli.py +67 -0
- rewindex-0.1.0/rewindex/commands/__init__.py +2 -0
- rewindex-0.1.0/rewindex/commands/cleanup.py +195 -0
- rewindex-0.1.0/rewindex/commands/diff.py +101 -0
- rewindex-0.1.0/rewindex/commands/init.py +146 -0
- rewindex-0.1.0/rewindex/commands/log.py +138 -0
- rewindex-0.1.0/rewindex/commands/note.py +58 -0
- rewindex-0.1.0/rewindex/commands/project.py +225 -0
- rewindex-0.1.0/rewindex/commands/rewind.py +254 -0
- rewindex-0.1.0/rewindex/commands/snap.py +57 -0
- rewindex-0.1.0/rewindex/commands/start.py +14 -0
- rewindex-0.1.0/rewindex/commands/status.py +100 -0
- rewindex-0.1.0/rewindex/commands/stop.py +12 -0
- rewindex-0.1.0/rewindex/commands/update.py +95 -0
- rewindex-0.1.0/rewindex/config/__init__.py +2 -0
- rewindex-0.1.0/rewindex/config/defaults.py +88 -0
- rewindex-0.1.0/rewindex/config/loader.py +69 -0
- rewindex-0.1.0/rewindex/config/validator.py +57 -0
- rewindex-0.1.0/rewindex/daemon/__init__.py +2 -0
- rewindex-0.1.0/rewindex/daemon/reconcile.py +97 -0
- rewindex-0.1.0/rewindex/daemon/runner.py +172 -0
- rewindex-0.1.0/rewindex/daemon/watcher.py +225 -0
- rewindex-0.1.0/rewindex/db/__init__.py +2 -0
- rewindex-0.1.0/rewindex/db/connection.py +53 -0
- rewindex-0.1.0/rewindex/db/queries.py +248 -0
- rewindex-0.1.0/rewindex/db/schema.py +41 -0
- rewindex-0.1.0/rewindex/session.py +80 -0
- rewindex-0.1.0/rewindex/snapshot/__init__.py +2 -0
- rewindex-0.1.0/rewindex/snapshot/engine.py +264 -0
- rewindex-0.1.0/rewindex/snapshot/opcodes.py +46 -0
- rewindex-0.1.0/rewindex/snapshot/reconstruct.py +66 -0
- rewindex-0.1.0/rewindex/snapshot/storage.py +56 -0
- rewindex-0.1.0/rewindex/ui/__init__.py +2 -0
- rewindex-0.1.0/rewindex/ui/diff_viewer.py +70 -0
- rewindex-0.1.0/rewindex/ui/rewind_prompt.py +56 -0
- rewindex-0.1.0/rewindex/ui/welcome.py +25 -0
- rewindex-0.1.0/rewindex/utils/__init__.py +0 -0
- rewindex-0.1.0/rewindex/utils/validation.py +60 -0
- rewindex-0.1.0/rewindex/version.py +60 -0
- rewindex-0.1.0/rewindex.egg-info/PKG-INFO +12 -0
- rewindex-0.1.0/rewindex.egg-info/SOURCES.txt +78 -0
- rewindex-0.1.0/rewindex.egg-info/dependency_links.txt +1 -0
- rewindex-0.1.0/rewindex.egg-info/entry_points.txt +2 -0
- rewindex-0.1.0/rewindex.egg-info/requires.txt +6 -0
- rewindex-0.1.0/rewindex.egg-info/top_level.txt +1 -0
- rewindex-0.1.0/setup.cfg +4 -0
- rewindex-0.1.0/tests/test_advanced_roundtrip.py +304 -0
- rewindex-0.1.0/tests/test_agent_aliases.py +134 -0
- rewindex-0.1.0/tests/test_agent_detection.py +59 -0
- rewindex-0.1.0/tests/test_config.py +62 -0
- rewindex-0.1.0/tests/test_daemon_log.py +124 -0
- rewindex-0.1.0/tests/test_db.py +84 -0
- rewindex-0.1.0/tests/test_missing_coverage.py +522 -0
- rewindex-0.1.0/tests/test_multiproject.py +253 -0
- rewindex-0.1.0/tests/test_new_fixes.py +224 -0
- rewindex-0.1.0/tests/test_opcodes.py +70 -0
- rewindex-0.1.0/tests/test_orphan_detection.py +183 -0
- rewindex-0.1.0/tests/test_rewind.py +60 -0
- rewindex-0.1.0/tests/test_rewind_navigation.py +196 -0
- rewindex-0.1.0/tests/test_same_folder.py +128 -0
- rewindex-0.1.0/tests/test_security_fixes.py +240 -0
- rewindex-0.1.0/tests/test_session.py +111 -0
- rewindex-0.1.0/tests/test_snapshot_roundtrip.py +120 -0
rewindex-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2026 Rewindex. All rights reserved.
|
|
2
|
+
|
|
3
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
4
|
+
|
|
5
|
+
This software and its source code are the exclusive property of Rewindex.
|
|
6
|
+
All rights reserved. No part of this software may be reproduced, distributed,
|
|
7
|
+
modified, sublicensed, or used in any form without the prior written permission
|
|
8
|
+
of Rewindex.
|
|
9
|
+
|
|
10
|
+
UNAUTHORIZED USE PROHIBITED
|
|
11
|
+
|
|
12
|
+
This software is provided solely for use by authorized licensees under the
|
|
13
|
+
terms of a separate written agreement with Rewindex. Any use, copying,
|
|
14
|
+
modification, distribution, or disclosure of this software or its contents
|
|
15
|
+
without the express written consent of Rewindex is strictly prohibited and
|
|
16
|
+
may subject the violator to civil and criminal penalties.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED. REWINDEX SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING FROM USE OF
|
|
20
|
+
THIS SOFTWARE.
|
rewindex-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rewindex
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Automatic file snapshots for AI-assisted development
|
|
5
|
+
License: Proprietary
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: watchdog<7,>=4.0
|
|
8
|
+
Requires-Dist: questionary<3,>=2.0
|
|
9
|
+
Requires-Dist: click<9,>=8.0
|
|
10
|
+
Requires-Dist: pyyaml<7,>=6.0
|
|
11
|
+
Requires-Dist: psutil<6,>=5.9
|
|
12
|
+
Requires-Dist: rich<15,>=13.0
|
rewindex-0.1.0/README.md
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# Rewindex
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**Automatic file snapshots for AI-assisted development.**
|
|
8
|
+
|
|
9
|
+
Rewindex watches your project files and creates snapshots every time an AI agent (or you) makes a change. Rewind any file to any point in time — no commits needed, no manual saves, no data loss.
|
|
10
|
+
|
|
11
|
+
Think of it as an **undo history that never forgets**, built specifically for the workflow where AI agents write code on your behalf.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Table of Contents
|
|
16
|
+
|
|
17
|
+
- [Why Rewindex](#why-rewindex)
|
|
18
|
+
- [How It Works](#how-it-works)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Quick Start](#quick-start)
|
|
21
|
+
- [Commands](#commands)
|
|
22
|
+
- [Snapshot & History](#snapshot--history)
|
|
23
|
+
- [Rewind & Restore](#rewind--restore)
|
|
24
|
+
- [Project Management](#project-management)
|
|
25
|
+
- [Maintenance](#maintenance)
|
|
26
|
+
- [Configuration](#configuration)
|
|
27
|
+
- [Supported AI Agents](#supported-ai-agents)
|
|
28
|
+
- [Session Grouping](#session-grouping)
|
|
29
|
+
- [Snapshot Notes](#snapshot-notes)
|
|
30
|
+
- [Security](#security)
|
|
31
|
+
- [How Snapshots Work](#how-snapshots-work)
|
|
32
|
+
- [FAQ](#faq)
|
|
33
|
+
- [License](#license)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Why Rewindex
|
|
38
|
+
|
|
39
|
+
When AI agents edit your code, changes happen fast. A single prompt can modify 10 files in seconds. If something goes wrong:
|
|
40
|
+
|
|
41
|
+
- **Git won't help** — you haven't committed yet
|
|
42
|
+
- **Ctrl+Z won't help** — the AI edited files outside your editor
|
|
43
|
+
- **File backups won't help** — they're too coarse-grained
|
|
44
|
+
|
|
45
|
+
Rewindex captures every change the moment it happens. You can see exactly what each agent changed, when, and rewind any file to any previous state.
|
|
46
|
+
|
|
47
|
+
## How It Works
|
|
48
|
+
|
|
49
|
+
1. A background daemon watches your project folder(s)
|
|
50
|
+
2. When a file changes, Rewindex hashes it and creates a compressed snapshot
|
|
51
|
+
3. Only the delta (diff) is stored — not the entire file
|
|
52
|
+
4. An agent detector identifies which AI tool made the change
|
|
53
|
+
5. You browse history, view diffs, and rewind files through the CLI
|
|
54
|
+
|
|
55
|
+
Everything stays on your machine. No cloud, no account, no telemetry.
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
> **Supported platforms: macOS and Linux only.** Windows is not yet supported.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# pip
|
|
63
|
+
pip install rewindex
|
|
64
|
+
|
|
65
|
+
# pipx (recommended for CLI tools — keeps dependencies isolated)
|
|
66
|
+
pipx install rewindex
|
|
67
|
+
|
|
68
|
+
# uv
|
|
69
|
+
uv tool install rewindex
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Requires Python 3.10+.
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 1. Set up your first project
|
|
78
|
+
rewindex init
|
|
79
|
+
|
|
80
|
+
# 2. Start the background daemon
|
|
81
|
+
rewindex start
|
|
82
|
+
|
|
83
|
+
# 3. Make changes (or let your AI agent work)
|
|
84
|
+
# Rewindex snapshots automatically in the background
|
|
85
|
+
|
|
86
|
+
# 4. View what happened
|
|
87
|
+
rewindex log
|
|
88
|
+
|
|
89
|
+
# 5. See what changed in a specific snapshot
|
|
90
|
+
rewindex diff 42
|
|
91
|
+
|
|
92
|
+
# 6. Rewind a file to a previous state
|
|
93
|
+
rewindex rewind 42
|
|
94
|
+
|
|
95
|
+
# 7. Check daemon status
|
|
96
|
+
rewindex status
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Non-interactive setup (for AI agents):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
rewindex init --project my-app --folder ~/projects/my-app
|
|
103
|
+
rewindex start
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Commands
|
|
107
|
+
|
|
108
|
+
### Snapshot & History
|
|
109
|
+
|
|
110
|
+
#### `rewindex log`
|
|
111
|
+
|
|
112
|
+
View snapshot history grouped into sessions.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
rewindex log # session view (default)
|
|
116
|
+
rewindex log --detail # individual snapshots
|
|
117
|
+
rewindex log --agent claude # filter by agent
|
|
118
|
+
rewindex log --since "14:00" # since a specific time
|
|
119
|
+
rewindex log --from 39 --to 44 # index range
|
|
120
|
+
rewindex log --limit 100 # max entries (default: 50)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### `rewindex diff [INDEX]`
|
|
124
|
+
|
|
125
|
+
View file changes for a snapshot.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
rewindex diff # interactive — pick from list
|
|
129
|
+
rewindex diff 44 # show diff for snapshot #44
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### `rewindex snap [LABEL]`
|
|
133
|
+
|
|
134
|
+
Manually trigger a snapshot of all watched files.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
rewindex snap # snapshot all changed files
|
|
138
|
+
rewindex snap "before refactor" # with a label
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### `rewindex status`
|
|
142
|
+
|
|
143
|
+
Show daemon state, project info, snapshot counts, and disk usage.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
rewindex status
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Output:
|
|
150
|
+
```
|
|
151
|
+
Rewindex is running (PID 12345)
|
|
152
|
+
|
|
153
|
+
my-app
|
|
154
|
+
→ ~/projects/my-app
|
|
155
|
+
142 snapshots · 28 files · latest #0142
|
|
156
|
+
Last activity: 2026-04-15 14:32:05
|
|
157
|
+
Disk usage: 3.2 MB
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Rewind & Restore
|
|
161
|
+
|
|
162
|
+
#### `rewindex rewind [INDEX] [FILES...]`
|
|
163
|
+
|
|
164
|
+
Restore files to a previous snapshot state.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Interactive — pick snapshot and files
|
|
168
|
+
rewindex rewind
|
|
169
|
+
|
|
170
|
+
# Rewind all files in snapshot #44
|
|
171
|
+
rewindex rewind 44
|
|
172
|
+
|
|
173
|
+
# Rewind specific file only
|
|
174
|
+
rewindex rewind 44 src/auth.py
|
|
175
|
+
|
|
176
|
+
# Preview diff without writing (read-only)
|
|
177
|
+
rewindex rewind --preview 44
|
|
178
|
+
|
|
179
|
+
# Rewind without confirmation (for AI agents)
|
|
180
|
+
rewindex rewind 44 --yes
|
|
181
|
+
|
|
182
|
+
# Rewind all files changed since snapshot #41
|
|
183
|
+
rewindex rewind --since 41 --yes
|
|
184
|
+
|
|
185
|
+
# Rewind last change by a specific agent
|
|
186
|
+
rewindex rewind --agent claude --last --yes
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### `rewindex note INDEX TEXT`
|
|
190
|
+
|
|
191
|
+
Add a note to a snapshot.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
rewindex note 44 "refactored auth to JWT"
|
|
195
|
+
rewindex note latest "WIP — do not rewind"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Project Management
|
|
199
|
+
|
|
200
|
+
#### `rewindex project add NAME FOLDER`
|
|
201
|
+
|
|
202
|
+
Add a new project to watch.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
rewindex project add backend ~/api
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### `rewindex project list`
|
|
209
|
+
|
|
210
|
+
Show all configured projects and their folders.
|
|
211
|
+
|
|
212
|
+
#### `rewindex project remove NAME`
|
|
213
|
+
|
|
214
|
+
Stop watching a project. Snapshots are kept on disk.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
rewindex project remove backend
|
|
218
|
+
rewindex project remove backend --yes # skip confirmation
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
To delete snapshot data, run `rewindex cleanup --orphans --apply` after removing.
|
|
222
|
+
|
|
223
|
+
#### `rewindex project add-folder NAME FOLDER`
|
|
224
|
+
|
|
225
|
+
Add an additional folder to an existing project.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
rewindex project add-folder my-app ~/shared-lib
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### `rewindex project remove-folder NAME FOLDER`
|
|
232
|
+
|
|
233
|
+
Remove a folder from a project.
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
rewindex project remove-folder my-app ~/shared-lib
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### `rewindex project rename OLD NEW`
|
|
240
|
+
|
|
241
|
+
Rename a project. Updates the config, renames the snapshots directory, and updates all snapshot records in the database.
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
rewindex project rename my-app my-app-v2
|
|
245
|
+
rewindex project rename my-app my-app-v2 --yes # skip confirmation
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Maintenance
|
|
249
|
+
|
|
250
|
+
#### `rewindex cleanup`
|
|
251
|
+
|
|
252
|
+
Identify snapshots that are safe to delete (already committed to git).
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
rewindex cleanup # dry run — report only
|
|
256
|
+
rewindex cleanup --apply # actually delete
|
|
257
|
+
rewindex cleanup --orphans # show orphaned snapshot dirs
|
|
258
|
+
rewindex cleanup --orphans --apply # delete orphaned dirs
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
#### `rewindex update`
|
|
262
|
+
|
|
263
|
+
Check for updates and sync config.
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
rewindex update # check current version
|
|
267
|
+
rewindex update --latest # upgrade from PyPI
|
|
268
|
+
rewindex update --sync # add missing config defaults
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### `rewindex start` / `rewindex stop`
|
|
272
|
+
|
|
273
|
+
Start or stop the background daemon.
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
rewindex start
|
|
277
|
+
rewindex stop
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Configuration
|
|
281
|
+
|
|
282
|
+
Config file: `~/.rewindex/.rewindex.config.yaml`
|
|
283
|
+
|
|
284
|
+
```yaml
|
|
285
|
+
projects:
|
|
286
|
+
- name: my-app
|
|
287
|
+
folders:
|
|
288
|
+
- ~/projects/my-app
|
|
289
|
+
- ~/projects/shared-lib
|
|
290
|
+
|
|
291
|
+
exclude:
|
|
292
|
+
- "node_modules/"
|
|
293
|
+
- ".git/"
|
|
294
|
+
- "__pycache__/"
|
|
295
|
+
- "venv/"
|
|
296
|
+
- ".venv/"
|
|
297
|
+
- "*.log"
|
|
298
|
+
- "*.tmp"
|
|
299
|
+
|
|
300
|
+
debounce_seconds: 5.0 # wait before snapshotting (group rapid saves)
|
|
301
|
+
session_gap_seconds: 20 # gap threshold for session grouping
|
|
302
|
+
|
|
303
|
+
history:
|
|
304
|
+
max_diffs: 600 # auto-trim after this many diffs per file
|
|
305
|
+
trim_count: 100 # number of oldest diffs removed per trim
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Security Exclusions (hardcoded, not configurable)
|
|
309
|
+
|
|
310
|
+
These files are **never** snapshotted:
|
|
311
|
+
|
|
312
|
+
- `.env`, `.env.*`, `*.secret`
|
|
313
|
+
- `id_rsa`, `id_ed25519`, `authorized_keys`
|
|
314
|
+
- `*.pem`, `*.key`, `*.p12`, `*.pfx`
|
|
315
|
+
- `.npmrc`, `.pypirc`, `.netrc`
|
|
316
|
+
- `*.kubeconfig`
|
|
317
|
+
|
|
318
|
+
## Supported AI Agents
|
|
319
|
+
|
|
320
|
+
Rewindex auto-detects which AI agent is modifying your files:
|
|
321
|
+
|
|
322
|
+
| Agent | Detection |
|
|
323
|
+
|-------|-----------|
|
|
324
|
+
| Claude Code | Process name `claude` or node args |
|
|
325
|
+
| Cursor | Process name `cursor` |
|
|
326
|
+
| Windsurf | Process name `windsurf` |
|
|
327
|
+
| Aider | Process name `aider` or python args |
|
|
328
|
+
| Codex (OpenAI) | Process name `codex` or node args |
|
|
329
|
+
| Zed | Process name `zed` |
|
|
330
|
+
| OpenClaw | Process name `openclaw` or node args |
|
|
331
|
+
| OpenCode | Process name `opencode` |
|
|
332
|
+
| Augment Code | Process name `auggie` |
|
|
333
|
+
| Hermes | Process name `hermes` |
|
|
334
|
+
| Goose | Process name `goose` |
|
|
335
|
+
| Plandex | Process name `plandex` or `pdx` |
|
|
336
|
+
| ZeroClaw | Process name `zeroclaw` |
|
|
337
|
+
| Kilo | Process name `kilo` or node args |
|
|
338
|
+
| Pi | Process name `pi` or node args |
|
|
339
|
+
| nanobot | Process name `nanobot` |
|
|
340
|
+
|
|
341
|
+
If no agent is detected, changes are labeled as `manual`.
|
|
342
|
+
|
|
343
|
+
## Session Grouping
|
|
344
|
+
|
|
345
|
+
`rewindex log` groups snapshots into sessions automatically:
|
|
346
|
+
|
|
347
|
+
- **Same agent + gap ≤ 20 seconds** = same session
|
|
348
|
+
- **Different agent** = always a new session
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
#0042–#0044 14:30–14:32 Claude Code 3 files
|
|
352
|
+
src/auth.py
|
|
353
|
+
src/middleware.py
|
|
354
|
+
models/user.py
|
|
355
|
+
|
|
356
|
+
#0041 14:15 manual 1 file
|
|
357
|
+
config.py
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Use `rewindex log --detail` to see individual snapshots.
|
|
361
|
+
|
|
362
|
+
The threshold is configurable via `session_gap_seconds` in your config file.
|
|
363
|
+
|
|
364
|
+
## Snapshot Notes
|
|
365
|
+
|
|
366
|
+
Add context to snapshots for future reference:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
rewindex note latest "refactored auth to use JWT"
|
|
370
|
+
rewindex note 42 "before breaking change"
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Notes appear in log output. Designed for both human and AI agent use — agents can annotate their changes automatically.
|
|
374
|
+
|
|
375
|
+
## Security
|
|
376
|
+
|
|
377
|
+
- `~/.rewindex/` directory: `chmod 700` (owner only)
|
|
378
|
+
- `daemon.log`: `chmod 600` (owner only)
|
|
379
|
+
- Path traversal protection on all file operations
|
|
380
|
+
- Symlinks that point outside the project folder are ignored
|
|
381
|
+
- SQL injection prevented via parameterized queries throughout
|
|
382
|
+
- LIKE wildcards (`%`, `_`) escaped in agent filters
|
|
383
|
+
- Binary files detected and skipped (null byte check, same method as git)
|
|
384
|
+
- Text files larger than 10 MB are skipped
|
|
385
|
+
- Gzip bomb protection (50 MB decompressed limit)
|
|
386
|
+
- Config file bomb protection (1 MB limit)
|
|
387
|
+
- Log rotation via RotatingFileHandler (5 MB × 3 backups)
|
|
388
|
+
- PID verification before sending stop signal
|
|
389
|
+
- Autostart binary path validated (absolute path, owner check)
|
|
390
|
+
|
|
391
|
+
## How Snapshots Work
|
|
392
|
+
|
|
393
|
+
1. **Hash** — SHA-256 hash of the file content
|
|
394
|
+
2. **Compare** — If hash matches the last snapshot, skip (no change)
|
|
395
|
+
3. **Store** — First snapshot is a full copy (`.full.gz`), subsequent ones are diffs (`.diff.gz`)
|
|
396
|
+
4. **Compress** — All snapshots are gzip compressed
|
|
397
|
+
5. **Reconstruct** — To view or rewind, chain: load base → apply diffs in order
|
|
398
|
+
|
|
399
|
+
Storage is efficient: only deltas are stored, compressed. A typical project uses 1-5 MB for hundreds of snapshots.
|
|
400
|
+
|
|
401
|
+
### Auto-Trim
|
|
402
|
+
|
|
403
|
+
When a file accumulates more than `max_diffs` (default: 600) diff snapshots, Rewindex automatically:
|
|
404
|
+
|
|
405
|
+
1. Promotes the 100th oldest diff to a new full base
|
|
406
|
+
2. Deletes everything before it
|
|
407
|
+
3. History continues seamlessly — no user action needed
|
|
408
|
+
|
|
409
|
+
Hard safety cap: 1,000 diffs maximum per file in the reconstruction chain.
|
|
410
|
+
|
|
411
|
+
## FAQ
|
|
412
|
+
|
|
413
|
+
**Q: Does Rewindex modify my files?**
|
|
414
|
+
A: Never. It only reads files to create snapshots. The only time it writes to your project folder is when you explicitly run `rewindex rewind`.
|
|
415
|
+
|
|
416
|
+
**Q: Does it send data anywhere?**
|
|
417
|
+
A: No. Everything is stored locally in `~/.rewindex/`. Cloud backup is planned for a future release but is opt-in.
|
|
418
|
+
|
|
419
|
+
**Q: How much disk space does it use?**
|
|
420
|
+
A: Very little. Diffs are compressed and typically 50-500 bytes each. Run `rewindex status` to check, or `rewindex cleanup` to free space.
|
|
421
|
+
|
|
422
|
+
**Q: Can I use it without AI agents?**
|
|
423
|
+
A: Yes. Rewindex snapshots any file change, whether made by an AI agent, your editor, or a script. Manual changes are labeled as `manual`.
|
|
424
|
+
|
|
425
|
+
**Q: What happens if I delete the database?**
|
|
426
|
+
A: The daemon creates a new one on restart and catches up by snapshotting all current files. Previous history is lost, but snapshot files remain on disk.
|
|
427
|
+
|
|
428
|
+
**Q: Does it work on Windows?**
|
|
429
|
+
A: Not yet. Currently supports Linux and macOS.
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
Proprietary. See LICENSE for details.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "rewindex"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Automatic file snapshots for AI-assisted development"
|
|
5
|
+
requires-python = ">=3.10"
|
|
6
|
+
license = { text = "Proprietary" }
|
|
7
|
+
dependencies = [
|
|
8
|
+
"watchdog>=4.0,<7",
|
|
9
|
+
"questionary>=2.0,<3",
|
|
10
|
+
"click>=8.0,<9",
|
|
11
|
+
"pyyaml>=6.0,<7",
|
|
12
|
+
"psutil>=5.9,<6",
|
|
13
|
+
"rich>=13.0,<15",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.scripts]
|
|
17
|
+
rewindex = "rewindex.cli:main"
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["setuptools>=61", "wheel"]
|
|
21
|
+
build-backend = "setuptools.build_meta"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools]
|
|
24
|
+
license-files = []
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["."]
|
|
28
|
+
include = ["rewindex*"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Copyright (c) 2026 Rewindex. All rights reserved.
|
|
2
|
+
# Proprietary and confidential. Unauthorized use prohibited.
|
|
3
|
+
|
|
4
|
+
import psutil
|
|
5
|
+
|
|
6
|
+
from .registry import KNOWN_AGENTS
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def detect_agent() -> str:
|
|
10
|
+
"""
|
|
11
|
+
Scan running processes and return the display name of the first
|
|
12
|
+
recognized AI agent found. Returns "manual" if none found.
|
|
13
|
+
Called once per file-change event — not a continuous poll.
|
|
14
|
+
"""
|
|
15
|
+
try:
|
|
16
|
+
for proc in psutil.process_iter(["name", "cmdline"]):
|
|
17
|
+
name = (proc.info.get("name") or "").lower()
|
|
18
|
+
cmdline = proc.info.get("cmdline") or []
|
|
19
|
+
cmdline_str = " ".join(cmdline).lower()
|
|
20
|
+
|
|
21
|
+
rule = KNOWN_AGENTS.get(name)
|
|
22
|
+
if rule is None:
|
|
23
|
+
continue
|
|
24
|
+
|
|
25
|
+
if isinstance(rule, str):
|
|
26
|
+
return rule
|
|
27
|
+
|
|
28
|
+
# dict rule: check args_contains
|
|
29
|
+
if isinstance(rule, dict):
|
|
30
|
+
for entry in rule.get("args_contains", []):
|
|
31
|
+
if isinstance(entry, str):
|
|
32
|
+
if entry in cmdline_str:
|
|
33
|
+
return rule["name"]
|
|
34
|
+
elif isinstance(entry, dict):
|
|
35
|
+
if entry["fragment"] in cmdline_str:
|
|
36
|
+
return entry["name"]
|
|
37
|
+
except (psutil.Error, OSError, AttributeError, TypeError):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
return "manual"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright (c) 2026 Rewindex. All rights reserved.
|
|
2
|
+
# Proprietary and confidential. Unauthorized use prohibited.
|
|
3
|
+
|
|
4
|
+
from .aider import AiderPlugin
|
|
5
|
+
from .claude_code import ClaudeCodePlugin
|
|
6
|
+
from .cursor import CursorPlugin
|
|
7
|
+
from .nanobot import NanobotPlugin
|
|
8
|
+
|
|
9
|
+
_PLUGINS = [
|
|
10
|
+
AiderPlugin(),
|
|
11
|
+
ClaudeCodePlugin(),
|
|
12
|
+
CursorPlugin(),
|
|
13
|
+
NanobotPlugin(),
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
# Map agent display name → plugin instance (case-insensitive prefix match)
|
|
17
|
+
_PLUGIN_MAP: dict[str, object] = {p.get_agent_name().lower(): p for p in _PLUGINS}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_plugin_for_agent(agent: str):
|
|
21
|
+
"""Return plugin instance for the given agent name string, or None."""
|
|
22
|
+
# agent strings can be "Claude Code", "manual", "manual:label", etc.
|
|
23
|
+
agent_lower = agent.lower().split(":")[0].strip()
|
|
24
|
+
return _PLUGIN_MAP.get(agent_lower)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) 2026 Rewindex. All rights reserved.
|
|
2
|
+
# Proprietary and confidential. Unauthorized use prohibited.
|
|
3
|
+
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AgentPlugin(ABC):
|
|
8
|
+
@abstractmethod
|
|
9
|
+
def get_agent_name(self) -> str:
|
|
10
|
+
"""Return the display name of this agent."""
|
|
11
|
+
...
|
|
12
|
+
|
|
13
|
+
def on_file_change(self, filepath: str, diff: list) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Optional hook called after a snapshot is taken.
|
|
16
|
+
filepath: relative path of the changed file.
|
|
17
|
+
diff: list of opcodes from snapshot/opcodes.py generate().
|
|
18
|
+
"""
|