You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bcd740a
Browse filesBrowse the repository at this point in the historyBrowse files
Fold the remaining docs into the README and CONTRIBUTING
docs/mcp.md and docs/embed.md become the README's AI agents and Embed a
graph in a web page sections, with the reference tables in collapsed
blocks, and pre-flight's checks and text graph move under Pre-flight.
docs/testing.md and the build and publishing notes from docs/vscode.md
move into CONTRIBUTING.md. docs/ now holds only the README's images.
Signed-off-by: Jacob Stopak <jacob@initialcommit.io>
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+32-7Lines changed: 32 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,23 +55,48 @@ $ git-sim merge dev
55
55
-`src/git_sim/live.py`, `preflight.py`, `mcp_server.py`, `claude_hook.py`: live mode, pre-flight, the MCP server, and the agent hook
56
56
-`vscode/`: the VS Code extension
57
57
-`integrations/`: the GitHub CLI extension (`gh sim`) and the GitHub Action
58
-
-`docs/`: guides for live mode, pre-flight and agents, embedding, integrations, and testing
58
+
-`docs/img/`: the README's images
59
59
-`scripts/`: the scripts that draw the README's graphs
60
60
61
61
## Running the tests
62
62
63
-
Three suites, each answering a different question. [docs/testing.md](docs/testing.md) explains them in detail.
64
-
65
63
```console
66
64
$ pytest tests/unit_tests # the pieces, in isolation
67
-
$ pytest tests/validation # every command and option, checked against what git does
65
+
$ pytest tests/validation # every command and option, checked against what Git does
68
66
$ pytest tests/e2e_tests # the raster images, pixel by pixel
69
67
```
70
68
69
+
GitHub Actions runs the unit tests on Linux, macOS, and Windows with every supported Python version on each push.
70
+
71
71
-**Clear your own settings first.** Any `git_sim_*` environment variables you've set (a dark theme, an image format) change what git-sim draws, so unset them before running the suites.
72
-
-**The e2e suite** needs `VIRTUAL_ENV` set to your virtual environment's absolute path.
73
-
-**The validation suite** compares what git-sim draws with golden models in `tests/validation/golden/`. When you change what a command draws on purpose, review the diff, then accept it with `pytest tests/validation --update-golden`.
74
-
-**New options need a case.** A new command or option needs a case in `tests/validation/cases.py`, and `test_coverage.py` fails until it has one.
72
+
-**The e2e suite** needs `VIRTUAL_ENV` set to your virtual environment's absolute path. Its reference images use a bundled font so they match across systems.
73
+
-**The validation suite** builds repo shapes with git-dummy, runs git-sim as a real subprocess, reads the SVG back into a model of what was drawn, and checks it against Git (`oracle.py`), against a golden model in `tests/validation/golden/`, and for clean failures. When you change what a command draws on purpose, review the diff, then accept it with `pytest tests/validation --update-golden`. It's almost 400 renders, so `pip install pytest-xdist` and `pytest -n auto` help, and `-m "not slow"` skips the large repo shape.
74
+
-**New options need a case.** A new command or option needs a one-line case in `tests/validation/cases.py`, and `test_coverage.py` fails until it has one.
75
+
-**The MCP server** can be checked against one of your repos with `python scripts/mcp_smoke_test.py /path/to/repo`.
76
+
77
+
### The sanity run
78
+
79
+
Before each release, `tests/sanity/sanity.py` runs git-sim the way a user would on six open-source repos, up to git/git, and compares every simulation with what Git actually does. It isn't collected by pytest and takes about half an hour:
80
+
81
+
```console
82
+
$ python tests/sanity/sanity.py clone # once: about 400 MB, most of it git/git
83
+
$ python tests/sanity/sanity.py run # all six repos, three at a time
84
+
$ python tests/sanity/sanity.py run flask --scenario "merge: conflict"
85
+
$ python tests/sanity/sanity.py list # the repos and scenario names
86
+
```
87
+
88
+
`run` ends with a report of the scenarios that matched Git and every problem with the command that showed it, also saved to `tests/sanity/.work/report.md`. A problem is either in git-sim or in the scenario, so check the scenario's `check=` and `refuse=` in `sanity.py` first. A real git-sim bug usually deserves a validation case too, so it stays fixed.
89
+
90
+
## The VS Code extension
91
+
92
+
The extension in `vscode/` is plain JavaScript that runs the `git-sim` command line tool, so there's nothing to compile. Open `vscode/` in VS Code and press F5 to try changes. To package it without Node:
The same `.vsix` is published to the Visual Studio Marketplace (`initialcommit` publisher, at marketplace.visualstudio.com/manage or with `vsce publish`) and to Open VSX for Cursor, Windsurf, and VSCodium (`npx ovsx publish -p <token>`). Both show `vscode/README.md` as the extension's page, so images in it need absolute links.
Copy file name to clipboardExpand all lines: README.md
+162-4Lines changed: 162 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -125,7 +125,7 @@ It names, animates, and tracks every change to your Git repo, so you can step ba
125
125
126
126
By default, the page opens in the git-sim viewer on initialcommit.com which connects to a lightweight web server `git-sim live` runs on your machine, reachable only from `127.0.0.1` and with a session key. All Git data is compressed and stored in the URL #fragment, so nothing about your repo leaves your machine, and `--open-in local` serves the page from git-sim itself instead if you prefer not to invoke initialcommit.com's git-sim viewer and run purely local.
127
127
128
-
**Runs inside VS Code:** the VS code extension shows the same live graph in its **Live graph** tab and sidebar view (see [docs/vscode.md](https://github.com/initialcommit-com/git-sim/blob/main/docs/vscode.md)).
128
+
**Runs inside VS Code:** the VS code extension shows the same live graph in its **Live graph** tab and sidebar view (see the [extension's page](https://github.com/initialcommit-com/git-sim/tree/main/vscode)).
129
129
130
130
**How it watches your repo:** live mode reads what Git reports between checks, rather than watching `.git`, and waits for the repo to settle, so a rebase or a pull shows as one change. It names each change from the reflog when it can (`git commit`, `git reset <commit>`, `git switch -c <branch>`), and otherwise from what changed (a branch created, a file staged, a stash popped). Chrome and Edge ask once for permission to reach the local server. If a browser refuses, the page offers the local version.
131
131
@@ -148,13 +148,171 @@ Set `GIT_SIM_LIVE_DEBUG=1` to log each detected change.
148
148
$ git-sim preflight reset --hard HEAD~2
149
149
```
150
150
151
-
[](https://github.com/initialcommit-com/git-sim/blob/main/docs/mcp.md)
151
+
[](https://github.com/initialcommit-com/git-sim#ai-agents)
152
152
153
153
git-sim's pre-flight mode shows a deterministic evaluation of whether any Git command is safe or potentially destructive to your repo, including how risky it is, which commits might become unreachable, which changes would be lost for good, and the command that undoes it, all without impacting your repo.
154
154
155
155
This can be wired into AI agents to bring yourself (the human) into the loop to approve/deny Git commands that could be destructive. Run `git-sim wire-agents` to set up the automatic git-sim pre-flight for AI agents.
156
156
157
-
The `--markdown` flag formats the report for a pull request comment, and the VS Code extension shows it in an editor tab.
157
+
Git's own options pass straight through, and quoting the whole command works too (`git-sim preflight "git stash drop"`). `-C <path>` checks another repo, `--json` prints the report as JSON, and `--markdown` formats it for a pull request comment. The VS Code extension shows it in an editor tab.
158
+
159
+
<details>
160
+
<summary>What pre-flight checks</summary>
161
+
162
+
-`reset`: the commits left behind and the uncommitted changes thrown away
163
+
-`clean`: the exact files it would delete (from `git clean -n`)
164
+
-`rebase`: the commits it replays, and whether any were already pushed
165
+
-`merge`: whether it fast-forwards, and whether it would conflict (from `git merge-tree`)
166
+
-`push`: whether a force-push would overwrite commits on the remote, and branches `push --delete` would remove
167
+
-`branch -d` and `-D`: commits not merged anywhere else
168
+
-`restore`, `checkout`, and `switch`: local changes they would throw away
169
+
-`stash drop` and `stash clear`: the stashed changes lost, including stashes from branches checked out in other worktrees
170
+
-`commit --amend`: whether the commit was already pushed
171
+
-`worktree remove` and `prune`: uncommitted changes deleted with the worktree, and stale records
172
+
-`rm`: uncommitted changes deleted with the file
173
+
-`reflog expire` and `delete`, `gc --prune`, and `filter-branch`
174
+
-`submodule deinit` and `update --force`: local changes inside the submodule
175
+
-`--abort`, `--continue`, `--skip`, and `--quit` for merges, rebases, cherry-picks, and reverts in progress
176
+
177
+
Commands that only read, or only add (`add`, `mv`, `init`, `clone`, `cherry-pick`, `revert`), are `safe`. `pull` is `safe` unless it's `pull --rebase` with local commits, which is `caution`. Commands pre-flight doesn't know are `caution`.
178
+
179
+
When a repo has more than one worktree, as with agents running in parallel, every report says which worktree the command runs in and checks what it could reach in the others: shared stashes, branches checked out elsewhere, and branches built on commits a rebase replays.
180
+
181
+
</details>
182
+
183
+
<details>
184
+
<summary>The text graph</summary>
185
+
186
+
Every report has a plain-text graph for places an image can't go, like a permission prompt, an SSH session, or CI logs. It's Git's own `log --graph` layout with a marker beside each commit the command affects, then the affected files:
187
+
188
+
```text
189
+
* c362a60 (HEAD -> mcp-server) Add Claude Code PreToolUse hook for autom... <- ABANDONED
190
+
* d31d48b Add MCP server with deterministic git pre-flight engine <- ABANDONED
191
+
* ccd3d99 (tag: v0.3.5, main) Bump version to 0.3.5 <- NEW HEAD
192
+
* 4f7c57e Update logo entry in manifest
193
+
... 212 earlier commit(s) not shown
194
+
195
+
Working tree:
196
+
modified README.md <- DISCARDED (not recoverable)
197
+
```
198
+
199
+
The markers are `ABANDONED` and `NEW HEAD` (reset), `REPLAYED (new hash)` and `NEW BASE` (rebase), `INCOMING` (merge), `PUSHED` and `OVERWRITTEN (remote only)` (push), `ABANDONED (branch deleted)` (`branch -D`), `REPLACED (new hash)` (`commit --amend`), and `SWITCH TARGET` (checkout and switch).
200
+
201
+
</details>
202
+
203
+
## AI agents
204
+
205
+
AI coding agents run Git commands for you. git-sim shows you what a risky one will do before it runs, worked out from your actual repo rather than guessed by the model, in two ways:
206
+
207
+
-**The pre-flight hook** stops the agent before a risky Git command and asks you to approve it, with the facts in front of you and the simulation open. The agent can't skip it.
208
+
-**The MCP server** gives the agent two tools it can call itself: `git_preflight(command, repo_path)` to check a command, and `git_simulate(command, repo_path)` to draw one (`interactive=true` for the interactive page). Neither ever changes your repo.
209
+
210
+
To set up both in every agent on your machine, run:
211
+
212
+
```console
213
+
$ git-sim wire-agents
214
+
```
215
+
216
+
Then restart any agents that are running. It sets up the hook and the MCP server in Claude Code, Codex CLI, Cursor, GitHub Copilot CLI, Gemini CLI, and VS Code (Copilot), and the MCP server only in Windsurf, Cline, Roo Code, Amazon Q Developer CLI, and Claude Desktop, which have no hooks.
217
+
218
+
`--agent claude --agent cursor` sets up only those agents, `--scope project` writes to the current repo instead of your home folder, `--no-hook` or `--no-mcp` skips one, and `--dry-run` shows what would change. Running it again updates git-sim's entries, and `git-sim unwire-agents` removes exactly what it added.
Loses: 2 commits removed from branch main; unstaged changes in README.md (NOT recoverable)
226
+
Undo: Commits stay in the reflog ~90 days: git reset --hard e35b0b7
227
+
```
228
+
229
+
Claude Code, Cursor, and Copilot ask you directly. Codex and Gemini hooks can only allow or deny, so the hook denies the command and tells the agent to show you the facts and, if you approve, rerun it starting with `GIT_SIM_APPROVE=1`. Safe commands and anything that isn't Git go straight through, and if the hook hits an error of its own, it lets the command through rather than blocking your agent.
230
+
231
+
<details>
232
+
<summary>Hook settings</summary>
233
+
234
+
Set these as environment variables:
235
+
236
+
| Variable | Default | What it does |
237
+
|---|---|---|
238
+
|`GIT_SIM_HOOK_ASK_ON`|`caution`| The lowest risk that stops the agent: `caution` or `destructive`|
239
+
|`GIT_SIM_HOOK_MODE`|`ask`|`ask` prompts you, `deny` denies risky commands outright (for unattended runs), `warn` lets them run with the facts attached |
240
+
|`GIT_SIM_HOOK_RENDER`|`1`|`0` skips drawing the simulation, for just the facts |
241
+
|`GIT_SIM_HOOK_OPEN`|`always`|`always` opens the simulation, `never` doesn't, `ask` asks first in a small system dialog |
242
+
|`GIT_SIM_HOOK_OPEN_IN`|`hosted`|`local` opens the saved `.html` file instead of the git-sim viewer |
243
+
|`GIT_SIM_HOOK_TEXT`|`0`|`1` adds the text commit graph to the prompt |
244
+
|`GIT_SIM_HOOK_REPORT_SAFE`|`1` in VS Code, `0` elsewhere |`1` adds a one-line SAFE or CAUTION note to Git commands that don't stop the agent |
245
+
|`GIT_SIM_HOOK_AGENT`| detected | Which agent's hook format to answer in (`claude`, `codex`, `cursor`, `copilot`, `gemini`) |
246
+
|`GIT_SIM_APPROVE`|| Set on a single command to let it through after you've approved it (Codex and Gemini) |
247
+
248
+
</details>
249
+
250
+
<details>
251
+
<summary>Setting up by hand</summary>
252
+
253
+
The hook in Claude Code, in `.claude/settings.json` or `~/.claude/settings.json`:
Put a git-sim graph in any blog post, tutorial, or docs page, with the full interactive viewer. Save the graph as an SVG (or use **Download SVG** in any git-sim page's Share menu):
285
+
286
+
```console
287
+
$ git-sim --img-format svg rebase main
288
+
```
289
+
290
+
Copy it next to your page, then add:
291
+
292
+
```html
293
+
<divclass="git-sim"data-src="/img/rebase-main.svg"data-title="git rebase main">
294
+
<ahref="https://initialcommit.com/tools/git-sim">git rebase main, created with git-sim</a>
The script turns every element with the `git-sim` class into the viewer, each in its own frame so they never clash with your page or each other. The link becomes a credit under the graph, and is what readers see if the script can't run.
300
+
301
+
<details>
302
+
<summary>Embed attributes</summary>
303
+
304
+
| Attribute | What it does |
305
+
| --- | --- |
306
+
|`data-src`| The SVG (or saved git-sim page) to show, on the same site as your page or a host that allows cross-origin requests |
307
+
|`data-title`| The command, used in the share text and the frame's title |
308
+
|`data-state`|`before`, `after`, or `step=N` holds the graph at that point. Without it, the graph plays on a loop |
309
+
|`data-theme`|`dark` or `light`. By default it follows the reader's setting |
310
+
|`data-controls`|`full` (the default) or `compact`, which keeps just the slider and Share |
311
+
|`data-height`| A fixed height, like `480px`. By default the embed fits the graph |
312
+
313
+
Style `.git-sim-credit` to change the credit's look. If your page adds content after it loads, call `GitSimEmbed.scan(element)` to set up new graphs inside it.
314
+
315
+
</details>
158
316
159
317
## Supported Git commands
160
318
@@ -686,7 +844,7 @@ Every option can also be set with an environment variable named `git_sim_` plus
686
844
687
845
The `[global options]` apply to the overarching `git-sim` simulation itself, including:
688
846
689
-
`--img-format`: Output format, i.e. `html` (default: the interactive page), `jpg`, `png`, or `svg` (the graph alone, for [embedding in a page](https://github.com/initialcommit-com/git-sim/blob/main/docs/embed.md)). Set `git_sim_img_format=jpg` in your environment to make an image the default.
847
+
`--img-format`: Output format, i.e. `html` (default: the interactive page), `jpg`, `png`, or `svg` (the graph alone, for [embedding in a page](https://github.com/initialcommit-com/git-sim#embed-a-graph-in-a-web-page)). Set `git_sim_img_format=jpg` in your environment to make an image the default.
690
848
`--open-in`: Where the interactive page opens: `hosted` (default) shows it in the git-sim viewer at initialcommit.com, `local` opens the saved `.html` file. The page is saved locally either way, and the hosted page says where. Set `git_sim_open_in=local` to make local the default.
691
849
`--reverse, -r` / `--no-reverse`: By default the newest commit is on the left and arrows point right toward parents, so history reads left to right. `--no-reverse` puts the newest commit on the right with arrows pointing left, the original layout.
692
850
`-n <number>`: Number of commits to display from each branch head.
0 commit comments