system-diff 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.
- system_diff-0.1.0/.gitattributes +2 -0
- system_diff-0.1.0/.github/workflows/ci.yml +41 -0
- system_diff-0.1.0/.github/workflows/release.yml +41 -0
- system_diff-0.1.0/.github/workflows/system-diff.yml +51 -0
- system_diff-0.1.0/.gitignore +15 -0
- system_diff-0.1.0/LICENSE +21 -0
- system_diff-0.1.0/PKG-INFO +131 -0
- system_diff-0.1.0/README.md +102 -0
- system_diff-0.1.0/docs/diagrams/system.json +236 -0
- system_diff-0.1.0/docs/diagrams/system.svg +97 -0
- system_diff-0.1.0/pyproject.toml +45 -0
- system_diff-0.1.0/src/system_diff/__init__.py +8 -0
- system_diff-0.1.0/src/system_diff/__main__.py +5 -0
- system_diff-0.1.0/src/system_diff/agent.py +197 -0
- system_diff-0.1.0/src/system_diff/cli.py +214 -0
- system_diff-0.1.0/src/system_diff/compare.py +105 -0
- system_diff-0.1.0/src/system_diff/config.py +106 -0
- system_diff-0.1.0/src/system_diff/diff.py +171 -0
- system_diff-0.1.0/src/system_diff/extract.py +279 -0
- system_diff-0.1.0/src/system_diff/graph.py +209 -0
- system_diff-0.1.0/src/system_diff/mcp_server.py +206 -0
- system_diff-0.1.0/src/system_diff/narrate.py +141 -0
- system_diff-0.1.0/src/system_diff/pictures.py +550 -0
- system_diff-0.1.0/src/system_diff/png.py +121 -0
- system_diff-0.1.0/src/system_diff/readme.py +39 -0
- system_diff-0.1.0/src/system_diff/sources.py +76 -0
- system_diff-0.1.0/src/system_diff/watch.py +177 -0
- system_diff-0.1.0/system-diff.toml +105 -0
- system_diff-0.1.0/tests/conftest.py +117 -0
- system_diff-0.1.0/tests/test_checkpoint_watch_mcp.py +188 -0
- system_diff-0.1.0/tests/test_system_diff.py +122 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
# macOS is left out for now: on this repository its runners were never assigned (cancelled after 15
|
|
17
|
+
# minutes in the queue, no step run). Add macos-latest back once they are.
|
|
18
|
+
os: [ubuntu-latest, windows-latest]
|
|
19
|
+
python: ["3.11", "3.12", "3.13"]
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python }}
|
|
26
|
+
- run: python -m pip install -e ".[dev]"
|
|
27
|
+
- run: python -m pytest -q
|
|
28
|
+
|
|
29
|
+
map:
|
|
30
|
+
# The README's system map is drawn from this repository's own code: it must be current.
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.12"
|
|
37
|
+
- run: python -m pip install -e .
|
|
38
|
+
- name: The system map is current (if not, run the two commands below and commit)
|
|
39
|
+
run: |
|
|
40
|
+
system-diff map --dir . --out docs/diagrams --check
|
|
41
|
+
system-diff readme --json docs/diagrams/system.json --check
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# A tag vX.Y.Z publishes that version to PyPI through trusted publishing: no token is stored anywhere. PyPI accepts the
|
|
4
|
+
# upload only from this workflow, in this repository, in the `pypi` environment.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: The tag is the version in pyproject.toml
|
|
21
|
+
run: |
|
|
22
|
+
v=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
|
|
23
|
+
[ "v$v" = "$GITHUB_REF_NAME" ] || { echo "tag $GITHUB_REF_NAME, but pyproject.toml says $v"; exit 1; }
|
|
24
|
+
- run: python -m pip install build && python -m build
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: dist
|
|
28
|
+
path: dist
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
needs: build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: dist
|
|
40
|
+
path: dist
|
|
41
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: system diff
|
|
2
|
+
|
|
3
|
+
# What a pull request does to the system, as a comment on it and in the run's summary; the picture is the run's
|
|
4
|
+
# "system-diff" artifact. Copy this file into another repository to get the same there.
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
diff:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
- run: python -m pip install -e .
|
|
23
|
+
- name: Draw what this pull request does to the system
|
|
24
|
+
run: system-diff diff --base "origin/${{ github.base_ref }}" --head HEAD --out system-diff-out
|
|
25
|
+
- name: Write the summary
|
|
26
|
+
run: |
|
|
27
|
+
{
|
|
28
|
+
echo '<!-- system-diff -->'
|
|
29
|
+
echo '### System diff'
|
|
30
|
+
echo
|
|
31
|
+
cat system-diff-out/headline.txt
|
|
32
|
+
echo
|
|
33
|
+
echo '```'
|
|
34
|
+
cat system-diff-out/plan.txt
|
|
35
|
+
echo '```'
|
|
36
|
+
echo
|
|
37
|
+
echo "The picture: the **system-diff** artifact of [this run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})."
|
|
38
|
+
} > system-diff-out/comment.md
|
|
39
|
+
cat system-diff-out/comment.md >> "$GITHUB_STEP_SUMMARY"
|
|
40
|
+
- uses: actions/upload-artifact@v4
|
|
41
|
+
with:
|
|
42
|
+
name: system-diff
|
|
43
|
+
path: system-diff-out
|
|
44
|
+
- name: Comment on the pull request
|
|
45
|
+
# A pull request from a fork gets a read-only token: it has the summary and the artifact instead.
|
|
46
|
+
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
47
|
+
env:
|
|
48
|
+
GH_TOKEN: ${{ github.token }}
|
|
49
|
+
run: |
|
|
50
|
+
gh pr comment "${{ github.event.pull_request.number }}" --body-file system-diff-out/comment.md --edit-last \
|
|
51
|
+
|| gh pr comment "${{ github.event.pull_request.number }}" --body-file system-diff-out/comment.md
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 simplifiedmachine
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: system-diff
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Draws your system from its code (parts, entry points, data, outside systems) and what each change adds, changes or removes. No dependencies; SVG pictures for PRs and READMEs.
|
|
5
|
+
Project-URL: Homepage, https://github.com/simplifiedmachine/system-diff
|
|
6
|
+
Project-URL: Documentation, https://github.com/simplifiedmachine/system-diff/wiki
|
|
7
|
+
Project-URL: Issues, https://github.com/simplifiedmachine/system-diff/issues
|
|
8
|
+
Author: simplifiedmachine
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: architecture,code-review,code-visualization,developer-tools,diagrams,pull-requests,system-design
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: mcp>=1.10; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
24
|
+
Provides-Extra: mcp
|
|
25
|
+
Requires-Dist: mcp>=1.10; extra == 'mcp'
|
|
26
|
+
Provides-Extra: png
|
|
27
|
+
Requires-Dist: playwright>=1.40; extra == 'png'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# system-diff
|
|
31
|
+
|
|
32
|
+
Draws your system from its code (parts, entry points, data, outside systems) and what each change adds, changes or
|
|
33
|
+
removes. No dependencies; SVG pictures for PRs and READMEs.
|
|
34
|
+
|
|
35
|
+
<!-- system-map:begin -->
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
<details><summary>How this map is made</summary>
|
|
39
|
+
|
|
40
|
+
Regenerated by `system-diff` from the code: the parts and their columns from `system-diff.toml`, the connections from imports, API calls and the settings each part reads, the outside systems from the settings a deploy configuration sets, and the tables from the migrations. Parts used everywhere are drawn without the arrows into them, and each part keeps only its strongest connections; `system-diff map` writes all of them to `system.json`.
|
|
41
|
+
|
|
42
|
+
Read by the code but set by no deploy configuration, so not drawn: Headless Chromium (Docker or Playwright) (png).
|
|
43
|
+
|
|
44
|
+
</details>
|
|
45
|
+
<!-- system-map:end -->
|
|
46
|
+
|
|
47
|
+
## What it does
|
|
48
|
+
|
|
49
|
+
- **`map`**: reads a commit straight from git (no checkout) or a folder, and writes `system.json` (everything it
|
|
50
|
+
found) and `system.svg` (the picture): a column per role, from what people use through entry points, logic and data
|
|
51
|
+
access to stored data and outside systems.
|
|
52
|
+
- **`diff`**: the typed difference between two commits, or a commit and your working tree: parts, endpoints,
|
|
53
|
+
connections, outside systems, tables, settings and deployment files added, changed or removed. One sentence
|
|
54
|
+
(`headline.txt`), the exact list (`plan.txt`, like `terraform plan`), and a picture of only what changed, with the
|
|
55
|
+
parts it touches beside it (`diff.svg`). `--narrate` adds a plain-words summary from your own LLM.
|
|
56
|
+
- **`readme`**: keeps a generated system map in your README, between two markers.
|
|
57
|
+
- **`draw`**: hand-made pictures in the same look, from small JSON specs: maps, stages of a process, sequences.
|
|
58
|
+
|
|
59
|
+
Deterministic: the same code gives the same picture, byte for byte, and a part that did not change keeps its place.
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
pipx install system-diff
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Python 3.11 or newer, nothing else. `pip install "system-diff[png]"` adds PNG output through Playwright; `system-diff
|
|
68
|
+
png` also uses Docker when it is there.
|
|
69
|
+
|
|
70
|
+
## Use
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
system-diff map --dir . --out docs/diagrams # the system as it is now
|
|
74
|
+
system-diff diff --base origin/main --out out # what this branch does to it
|
|
75
|
+
system-diff diff --base HEAD --head . --out out # what your uncommitted work does to it
|
|
76
|
+
system-diff readme --json docs/diagrams/system.json # refresh the map in README.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
With no config, every folder of code is a part named by its path. A `system-diff.toml` at the repository root names the
|
|
80
|
+
parts and says what is what:
|
|
81
|
+
|
|
82
|
+
```toml
|
|
83
|
+
tests = ["tests/**"]
|
|
84
|
+
|
|
85
|
+
[code]
|
|
86
|
+
roots = ["app/", "web/src/"]
|
|
87
|
+
|
|
88
|
+
[[components]]
|
|
89
|
+
id = "api"
|
|
90
|
+
label = "API"
|
|
91
|
+
kind = "interface" # ui | interface | logic | data: the column it is drawn in
|
|
92
|
+
paths = ["app/api/**"]
|
|
93
|
+
|
|
94
|
+
[[externals]]
|
|
95
|
+
id = "postgres"
|
|
96
|
+
label = "PostgreSQL"
|
|
97
|
+
shape = "db"
|
|
98
|
+
env = ["DATABASE_URL"] # the settings that reach it
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Every key, and how the code is read: [the wiki](https://github.com/simplifiedmachine/system-diff/wiki).
|
|
102
|
+
|
|
103
|
+
## In pull requests
|
|
104
|
+
|
|
105
|
+
This repository runs system-diff on itself: the map above is regenerated from its own code, CI fails when it is out of
|
|
106
|
+
date, and every pull request gets its system diff as a comment (`.github/workflows/system-diff.yml`, which you can
|
|
107
|
+
copy).
|
|
108
|
+
|
|
109
|
+
## With AI coding agents
|
|
110
|
+
|
|
111
|
+
When an agent changes the code with you, the question is what it did to the system. system-diff answers it as you go:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
pipx install system-diff
|
|
115
|
+
pipx inject system-diff mcp # the MCP server's one dependency
|
|
116
|
+
system-diff setup claude # the hook, a skill and the MCP server, in one step (--scope project, --undo)
|
|
117
|
+
system-diff watch # http://127.0.0.1:8765/ : the system diff since you last marked it seen
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- **After every Claude Code turn**, one line says what changed in the system since your checkpoint ("Adds 1 endpoint
|
|
121
|
+
(DELETE /api/orders/{id}); changes 1 table (public.orders)."), or nothing when nothing structural did.
|
|
122
|
+
- **The live page** redraws as files change. Press **Mark as seen** once you have understood it: the next diff then
|
|
123
|
+
shows only what is new to you. `system-diff checkpoint` does the same from the terminal.
|
|
124
|
+
- **The MCP server** gives the agent `system_diff` (the exact plan to explain from, and the picture), `system_map`,
|
|
125
|
+
`draw` (pictures of processes and sequences in the same look) and `checkpoint`.
|
|
126
|
+
- The working tree is read as a snapshot (untracked files included) without touching your index, HEAD or branches,
|
|
127
|
+
and the checkpoint lives under `refs/system-diff/`, in your clone only.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# system-diff
|
|
2
|
+
|
|
3
|
+
Draws your system from its code (parts, entry points, data, outside systems) and what each change adds, changes or
|
|
4
|
+
removes. No dependencies; SVG pictures for PRs and READMEs.
|
|
5
|
+
|
|
6
|
+
<!-- system-map:begin -->
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
<details><summary>How this map is made</summary>
|
|
10
|
+
|
|
11
|
+
Regenerated by `system-diff` from the code: the parts and their columns from `system-diff.toml`, the connections from imports, API calls and the settings each part reads, the outside systems from the settings a deploy configuration sets, and the tables from the migrations. Parts used everywhere are drawn without the arrows into them, and each part keeps only its strongest connections; `system-diff map` writes all of them to `system.json`.
|
|
12
|
+
|
|
13
|
+
Read by the code but set by no deploy configuration, so not drawn: Headless Chromium (Docker or Playwright) (png).
|
|
14
|
+
|
|
15
|
+
</details>
|
|
16
|
+
<!-- system-map:end -->
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
- **`map`**: reads a commit straight from git (no checkout) or a folder, and writes `system.json` (everything it
|
|
21
|
+
found) and `system.svg` (the picture): a column per role, from what people use through entry points, logic and data
|
|
22
|
+
access to stored data and outside systems.
|
|
23
|
+
- **`diff`**: the typed difference between two commits, or a commit and your working tree: parts, endpoints,
|
|
24
|
+
connections, outside systems, tables, settings and deployment files added, changed or removed. One sentence
|
|
25
|
+
(`headline.txt`), the exact list (`plan.txt`, like `terraform plan`), and a picture of only what changed, with the
|
|
26
|
+
parts it touches beside it (`diff.svg`). `--narrate` adds a plain-words summary from your own LLM.
|
|
27
|
+
- **`readme`**: keeps a generated system map in your README, between two markers.
|
|
28
|
+
- **`draw`**: hand-made pictures in the same look, from small JSON specs: maps, stages of a process, sequences.
|
|
29
|
+
|
|
30
|
+
Deterministic: the same code gives the same picture, byte for byte, and a part that did not change keeps its place.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pipx install system-diff
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Python 3.11 or newer, nothing else. `pip install "system-diff[png]"` adds PNG output through Playwright; `system-diff
|
|
39
|
+
png` also uses Docker when it is there.
|
|
40
|
+
|
|
41
|
+
## Use
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
system-diff map --dir . --out docs/diagrams # the system as it is now
|
|
45
|
+
system-diff diff --base origin/main --out out # what this branch does to it
|
|
46
|
+
system-diff diff --base HEAD --head . --out out # what your uncommitted work does to it
|
|
47
|
+
system-diff readme --json docs/diagrams/system.json # refresh the map in README.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
With no config, every folder of code is a part named by its path. A `system-diff.toml` at the repository root names the
|
|
51
|
+
parts and says what is what:
|
|
52
|
+
|
|
53
|
+
```toml
|
|
54
|
+
tests = ["tests/**"]
|
|
55
|
+
|
|
56
|
+
[code]
|
|
57
|
+
roots = ["app/", "web/src/"]
|
|
58
|
+
|
|
59
|
+
[[components]]
|
|
60
|
+
id = "api"
|
|
61
|
+
label = "API"
|
|
62
|
+
kind = "interface" # ui | interface | logic | data: the column it is drawn in
|
|
63
|
+
paths = ["app/api/**"]
|
|
64
|
+
|
|
65
|
+
[[externals]]
|
|
66
|
+
id = "postgres"
|
|
67
|
+
label = "PostgreSQL"
|
|
68
|
+
shape = "db"
|
|
69
|
+
env = ["DATABASE_URL"] # the settings that reach it
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Every key, and how the code is read: [the wiki](https://github.com/simplifiedmachine/system-diff/wiki).
|
|
73
|
+
|
|
74
|
+
## In pull requests
|
|
75
|
+
|
|
76
|
+
This repository runs system-diff on itself: the map above is regenerated from its own code, CI fails when it is out of
|
|
77
|
+
date, and every pull request gets its system diff as a comment (`.github/workflows/system-diff.yml`, which you can
|
|
78
|
+
copy).
|
|
79
|
+
|
|
80
|
+
## With AI coding agents
|
|
81
|
+
|
|
82
|
+
When an agent changes the code with you, the question is what it did to the system. system-diff answers it as you go:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
pipx install system-diff
|
|
86
|
+
pipx inject system-diff mcp # the MCP server's one dependency
|
|
87
|
+
system-diff setup claude # the hook, a skill and the MCP server, in one step (--scope project, --undo)
|
|
88
|
+
system-diff watch # http://127.0.0.1:8765/ : the system diff since you last marked it seen
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **After every Claude Code turn**, one line says what changed in the system since your checkpoint ("Adds 1 endpoint
|
|
92
|
+
(DELETE /api/orders/{id}); changes 1 table (public.orders)."), or nothing when nothing structural did.
|
|
93
|
+
- **The live page** redraws as files change. Press **Mark as seen** once you have understood it: the next diff then
|
|
94
|
+
shows only what is new to you. `system-diff checkpoint` does the same from the terminal.
|
|
95
|
+
- **The MCP server** gives the agent `system_diff` (the exact plan to explain from, and the picture), `system_map`,
|
|
96
|
+
`draw` (pictures of processes and sequences in the same look) and `checkpoint`.
|
|
97
|
+
- The working tree is read as a snapshot (untracked files included) without touching your index, HEAD or branches,
|
|
98
|
+
and the checkpoint lives under `refs/system-diff/`, in your clone only.
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ref": "working tree",
|
|
3
|
+
"components": {
|
|
4
|
+
"cli": {
|
|
5
|
+
"label": "Command line",
|
|
6
|
+
"layer": "",
|
|
7
|
+
"kind": "interface",
|
|
8
|
+
"order": 0,
|
|
9
|
+
"container": "",
|
|
10
|
+
"declared": true,
|
|
11
|
+
"files": 3,
|
|
12
|
+
"lines": 227,
|
|
13
|
+
"hub": false,
|
|
14
|
+
"quiet": false
|
|
15
|
+
},
|
|
16
|
+
"agent": {
|
|
17
|
+
"label": "Claude Code hook and setup",
|
|
18
|
+
"layer": "",
|
|
19
|
+
"kind": "interface",
|
|
20
|
+
"order": 2,
|
|
21
|
+
"container": "",
|
|
22
|
+
"declared": true,
|
|
23
|
+
"files": 1,
|
|
24
|
+
"lines": 197,
|
|
25
|
+
"hub": false,
|
|
26
|
+
"quiet": false
|
|
27
|
+
},
|
|
28
|
+
"compare": {
|
|
29
|
+
"label": "Checkpoints and snapshots",
|
|
30
|
+
"layer": "",
|
|
31
|
+
"kind": "logic",
|
|
32
|
+
"order": 4,
|
|
33
|
+
"container": "",
|
|
34
|
+
"declared": true,
|
|
35
|
+
"files": 1,
|
|
36
|
+
"lines": 105,
|
|
37
|
+
"hub": false,
|
|
38
|
+
"quiet": false
|
|
39
|
+
},
|
|
40
|
+
"config": {
|
|
41
|
+
"label": "Config",
|
|
42
|
+
"layer": "",
|
|
43
|
+
"kind": "logic",
|
|
44
|
+
"order": 5,
|
|
45
|
+
"container": "",
|
|
46
|
+
"declared": true,
|
|
47
|
+
"files": 1,
|
|
48
|
+
"lines": 106,
|
|
49
|
+
"hub": false,
|
|
50
|
+
"quiet": false
|
|
51
|
+
},
|
|
52
|
+
"diff": {
|
|
53
|
+
"label": "Typed diff",
|
|
54
|
+
"layer": "",
|
|
55
|
+
"kind": "logic",
|
|
56
|
+
"order": 7,
|
|
57
|
+
"container": "",
|
|
58
|
+
"declared": true,
|
|
59
|
+
"files": 1,
|
|
60
|
+
"lines": 171,
|
|
61
|
+
"hub": false,
|
|
62
|
+
"quiet": false
|
|
63
|
+
},
|
|
64
|
+
"extract": {
|
|
65
|
+
"label": "Extraction",
|
|
66
|
+
"layer": "",
|
|
67
|
+
"kind": "logic",
|
|
68
|
+
"order": 6,
|
|
69
|
+
"container": "",
|
|
70
|
+
"declared": true,
|
|
71
|
+
"files": 1,
|
|
72
|
+
"lines": 279,
|
|
73
|
+
"hub": false,
|
|
74
|
+
"quiet": false
|
|
75
|
+
},
|
|
76
|
+
"graph": {
|
|
77
|
+
"label": "Map layout",
|
|
78
|
+
"layer": "",
|
|
79
|
+
"kind": "logic",
|
|
80
|
+
"order": 8,
|
|
81
|
+
"container": "",
|
|
82
|
+
"declared": true,
|
|
83
|
+
"files": 1,
|
|
84
|
+
"lines": 209,
|
|
85
|
+
"hub": false,
|
|
86
|
+
"quiet": false
|
|
87
|
+
},
|
|
88
|
+
"mcp": {
|
|
89
|
+
"label": "MCP server",
|
|
90
|
+
"layer": "",
|
|
91
|
+
"kind": "interface",
|
|
92
|
+
"order": 1,
|
|
93
|
+
"container": "",
|
|
94
|
+
"declared": true,
|
|
95
|
+
"files": 1,
|
|
96
|
+
"lines": 206,
|
|
97
|
+
"hub": false,
|
|
98
|
+
"quiet": false
|
|
99
|
+
},
|
|
100
|
+
"narrate": {
|
|
101
|
+
"label": "LLM summary",
|
|
102
|
+
"layer": "",
|
|
103
|
+
"kind": "logic",
|
|
104
|
+
"order": 11,
|
|
105
|
+
"container": "",
|
|
106
|
+
"declared": true,
|
|
107
|
+
"files": 1,
|
|
108
|
+
"lines": 141,
|
|
109
|
+
"hub": false,
|
|
110
|
+
"quiet": false
|
|
111
|
+
},
|
|
112
|
+
"pictures": {
|
|
113
|
+
"label": "SVG pictures",
|
|
114
|
+
"layer": "",
|
|
115
|
+
"kind": "logic",
|
|
116
|
+
"order": 9,
|
|
117
|
+
"container": "",
|
|
118
|
+
"declared": true,
|
|
119
|
+
"files": 1,
|
|
120
|
+
"lines": 550,
|
|
121
|
+
"hub": true,
|
|
122
|
+
"quiet": false
|
|
123
|
+
},
|
|
124
|
+
"png": {
|
|
125
|
+
"label": "PNG rendering",
|
|
126
|
+
"layer": "",
|
|
127
|
+
"kind": "logic",
|
|
128
|
+
"order": 12,
|
|
129
|
+
"container": "",
|
|
130
|
+
"declared": true,
|
|
131
|
+
"files": 1,
|
|
132
|
+
"lines": 121,
|
|
133
|
+
"hub": false,
|
|
134
|
+
"quiet": false
|
|
135
|
+
},
|
|
136
|
+
"readme": {
|
|
137
|
+
"label": "README section",
|
|
138
|
+
"layer": "",
|
|
139
|
+
"kind": "logic",
|
|
140
|
+
"order": 10,
|
|
141
|
+
"container": "",
|
|
142
|
+
"declared": true,
|
|
143
|
+
"files": 1,
|
|
144
|
+
"lines": 39,
|
|
145
|
+
"hub": false,
|
|
146
|
+
"quiet": false
|
|
147
|
+
},
|
|
148
|
+
"sources": {
|
|
149
|
+
"label": "Git and folder sources",
|
|
150
|
+
"layer": "",
|
|
151
|
+
"kind": "data",
|
|
152
|
+
"order": 13,
|
|
153
|
+
"container": "",
|
|
154
|
+
"declared": true,
|
|
155
|
+
"files": 1,
|
|
156
|
+
"lines": 76,
|
|
157
|
+
"hub": false,
|
|
158
|
+
"quiet": false
|
|
159
|
+
},
|
|
160
|
+
"watch": {
|
|
161
|
+
"label": "Live page",
|
|
162
|
+
"layer": "",
|
|
163
|
+
"kind": "interface",
|
|
164
|
+
"order": 3,
|
|
165
|
+
"container": "",
|
|
166
|
+
"declared": true,
|
|
167
|
+
"files": 1,
|
|
168
|
+
"lines": 177,
|
|
169
|
+
"hub": false,
|
|
170
|
+
"quiet": false
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"flows": {
|
|
174
|
+
"agent>compare": 1,
|
|
175
|
+
"agent>sources": 1,
|
|
176
|
+
"cli>agent": 2,
|
|
177
|
+
"cli>compare": 1,
|
|
178
|
+
"cli>config": 2,
|
|
179
|
+
"cli>diff": 1,
|
|
180
|
+
"cli>extract": 2,
|
|
181
|
+
"cli>graph": 2,
|
|
182
|
+
"cli>mcp": 1,
|
|
183
|
+
"cli>narrate": 1,
|
|
184
|
+
"cli>pictures": 1,
|
|
185
|
+
"cli>png": 1,
|
|
186
|
+
"cli>readme": 1,
|
|
187
|
+
"cli>sources": 1,
|
|
188
|
+
"cli>watch": 1,
|
|
189
|
+
"compare>config": 1,
|
|
190
|
+
"compare>diff": 1,
|
|
191
|
+
"compare>extract": 1,
|
|
192
|
+
"compare>sources": 1,
|
|
193
|
+
"diff>extract": 1,
|
|
194
|
+
"diff>sources": 1,
|
|
195
|
+
"extract>config": 1,
|
|
196
|
+
"graph>diff": 1,
|
|
197
|
+
"graph>pictures": 1,
|
|
198
|
+
"mcp>compare": 1,
|
|
199
|
+
"mcp>config": 1,
|
|
200
|
+
"mcp>extract": 1,
|
|
201
|
+
"mcp>graph": 1,
|
|
202
|
+
"mcp>pictures": 1,
|
|
203
|
+
"mcp>sources": 1,
|
|
204
|
+
"readme>pictures": 1,
|
|
205
|
+
"watch>compare": 1,
|
|
206
|
+
"watch>graph": 1
|
|
207
|
+
},
|
|
208
|
+
"api": {},
|
|
209
|
+
"routes": {},
|
|
210
|
+
"externals": {},
|
|
211
|
+
"dormant": {
|
|
212
|
+
"chromium": {
|
|
213
|
+
"label": "Headless Chromium (Docker or Playwright)",
|
|
214
|
+
"shape": "",
|
|
215
|
+
"used_by": [
|
|
216
|
+
"png"
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"internal": {},
|
|
221
|
+
"env": {
|
|
222
|
+
"png": [
|
|
223
|
+
"SYSTEM_DIFF_RENDER_IMAGE"
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"containers": {},
|
|
227
|
+
"container_labels": {},
|
|
228
|
+
"tables": {},
|
|
229
|
+
"store": "postgres",
|
|
230
|
+
"migrations": [],
|
|
231
|
+
"tests": {
|
|
232
|
+
"tests/conftest.py": 1,
|
|
233
|
+
"tests/test_checkpoint_watch_mcp.py": 1,
|
|
234
|
+
"tests/test_system_diff.py": 1
|
|
235
|
+
}
|
|
236
|
+
}
|