@yokira404/dsh-git-guard 0.0.0-stage → 1.0.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yokira
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.
package/README.md CHANGED
@@ -1,3 +1,106 @@
1
- # Temporary Holding Version
1
+ # Git Repository Guard · dsh-git-guard
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Two switches at the right of the Session header that stop an agent from writing your
4
+ local git repository or uploading it to a remote.
5
+
6
+ | Switch | Position | What it blocks |
7
+ | --- | --- | --- |
8
+ | Local repository | left | Writes to the local repository: `git add`, `git commit`, `git reset`, `git merge`, `git tag` and friends |
9
+ | Remote repository | right | Anything that reaches a remote: `git push`, `git pull`, `git clone`, `git remote`, `gh` and friends |
10
+
11
+ Both start on. The block happens **before** a command runs: the call is not executed,
12
+ and the agent gets a clear refusal instead.
13
+
14
+ ![Where the two switches sit](docs/position.svg)
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ dsh plugin --profile <profile> add https://github.com/Yokira404/dsh-git-guard
20
+ ```
21
+
22
+ Reload the page and the two switches appear at the right of the Session header.
23
+
24
+ > By hand: add `@yokira404/dsh-git-guard` to `dsh.profile.bundles` in
25
+ > `~/.dsh/profiles/<profile>/package.json`, and point `dependencies` at this package.
26
+
27
+ ## How the two switches interact
28
+
29
+ Two rules, both the **consequence of a click** — never a condition that has to hold:
30
+
31
+ | Click | Local | Remote |
32
+ | --- | --- | --- |
33
+ | left (local) | toggles | turns **on** with the local switch when that lands on; left alone when it lands off |
34
+ | right (remote) | turns **off** with the remote switch when that lands off; left alone when it lands on | toggles |
35
+
36
+ - **Switching a guard on never releases the other one.** Asking for one protection must not dismantle the other.
37
+ - **Releasing the upload guard releases the local one with it** — the local writes are exactly what an upload would carry.
38
+ - One deliberate opening: **with both off, the right switch arms the upload guard alone**, leaving local writes open.
39
+
40
+ All four states are reachable:
41
+
42
+ | State | Local writes | Uploads |
43
+ | --- | --- | --- |
44
+ | on · on (default) | blocked | blocked |
45
+ | off · on | allowed | blocked |
46
+ | on · off | blocked | allowed |
47
+ | off · off | allowed | allowed |
48
+
49
+ ## What is blocked
50
+
51
+ **Left switch** — writes to the local repository:
52
+
53
+ ```
54
+ git add · git commit · git am · git apply · git checkout-index · git config
55
+ git merge · git mv · git notes · git rebase · git reset · git restore
56
+ git revert · git rm · git stash · git switch · git tag
57
+ git update-index · git update-ref
58
+ ```
59
+
60
+ **Right switch** — anything that reaches a remote:
61
+
62
+ ```
63
+ git push · git pull · git fetch · git clone · git ls-remote · git remote
64
+ git submodule · git send-pack · git archive · git request-pull · git svn
65
+ gh repo / pr / release / issue / run / workflow / api / gist / secret / …
66
+ a repository URL on the command line (github.com, gitlab.com, gitee.com, …)
67
+ ```
68
+
69
+ **Never blocked**: `git status`, `git log`, `git diff`, `git show`, `git branch`,
70
+ `git blame`, `git init`, `git rev-parse`, `git check-ignore`, `git ls-files`,
71
+ `git worktree`, `git help`, `gh auth`, `gh config`, `gh api /user`, and anything that is
72
+ not about git at all. `git init` is allowed on purpose: creating a repository neither
73
+ commits nor uploads anything.
74
+
75
+ Matching is **quote-aware**: `git commit -m "do not push this"` is a local commit, not
76
+ an upload, and `echo "git push" > notes.txt` is nothing. It is not fooled by prefixes
77
+ either — `sudo git push`, `env FOO=1 git commit` and
78
+ `C:\Program Files\Git\cmd\git.exe push` are all recognised.
79
+
80
+ ## What the agent sees when it is blocked
81
+
82
+ ```
83
+ 已阻止:DSH 的「Git 仓库保护」插件当前开着左侧的本地仓库开关,
84
+ 写入本地仓库的操作(git add / git commit 等)被拒绝。
85
+ 被拦截的命令:`git commit -m x`
86
+ 这是用户有意设置的开关,不是故障:不要改用其他命令、其他工具或直接调用 API 绕过它,
87
+ 也不要尝试关闭该开关。请把这一步作为「未执行」如实报告给用户,
88
+ 并说明用户可以点击会话标题栏的两个方形按钮自行放行。
89
+ ```
90
+
91
+ ## Limits
92
+
93
+ - **It never changes your repository**: no `.git/hooks`, no `git config`, blocking only.
94
+ - **It also catches text that merely names a command**: matching reads the whole of a
95
+ tool call's command-like field (`command`, `script`, `code`, …), so writing a document
96
+ whose text contains `git push` can have that write blocked. That is the deliberate
97
+ bias — one extra blocked write beats one upload that got through.
98
+ - **It cannot stop paths that avoid the shell**; it targets the real one, an agent
99
+ uploading a repository through a command.
100
+ - **No undo**: the block is up front, so there is no window in which something was
101
+ already uploaded.
102
+ - **State is not persisted**: a DSH restart returns both switches to on.
103
+
104
+ ## License
105
+
106
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,91 @@
1
+ # Git 仓库保护 · dsh-git-guard
2
+
3
+ 会话标题栏右侧的一对开关,拦住 agent 写入本地 git 仓库或把它上传到远端。
4
+
5
+ | 开关 | 位置 | 拦住什么 |
6
+ | --- | --- | --- |
7
+ | 本地仓库 | 左 | 写入本地仓库的操作:`git add`、`git commit`、`git reset`、`git merge`、`git tag` 等 |
8
+ | 远端仓库 | 右 | 触达远端的操作:`git push`、`git pull`、`git clone`、`git remote`、`gh` 等 |
9
+
10
+ 两个都默认开启。拦截发生在命令真正执行**之前**,被拒绝的操作不会执行,agent 会收到明确的拒绝理由。
11
+
12
+ ![两个开关的位置](docs/position.svg)
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ dsh plugin --profile <profile> add https://github.com/Yokira404/dsh-git-guard
18
+ ```
19
+
20
+ 装好后重新加载页面,即可在会话标题栏右侧看到这两个开关。
21
+
22
+ > 手动登记 profile 也可以:在 `~/.dsh/profiles/<profile>/package.json` 的 `dsh.profile.bundles` 里加上 `@yokira404/dsh-git-guard`,并在 `dependencies` 里指向本包。
23
+
24
+ ## 开关怎么联动
25
+
26
+ 两者的关系只有两条,都是**一次点击的后果**,没有「必须一直成立」的约束:
27
+
28
+ | 点击 | 本地 | 远端 |
29
+ | --- | --- | --- |
30
+ | 左(本地) | 取反 | 本地变成**开**时,远端跟着**开**;本地变成关时,远端不动 |
31
+ | 右(远端) | 远端变成**关**时,本地跟着**关**;远端变成开时,本地不动 | 取反 |
32
+
33
+ - **打开一侧永远不会关掉另一侧**:打开一个保护,不该顺手拆掉另一个保护。
34
+ - **关闭远端会连带关闭本地**:本地写入正是上传要带走的东西,只放开远端等于留着一半。
35
+ - 特例:**两个都关时点右侧**,只打开远端、本地保持关闭。这是有意留的口子 —— 只拦上传、不拦本地写入。
36
+
37
+ 四种状态都可达:
38
+
39
+ | 状态 | 本地写入 | 上传远端 |
40
+ | --- | --- | --- |
41
+ | 开 · 开(默认) | 拦 | 拦 |
42
+ | 关 · 开 | 放行 | 拦 |
43
+ | 开 · 关 | 拦 | 放行 |
44
+ | 关 · 关 | 放行 | 放行 |
45
+
46
+ ## 判定范围
47
+
48
+ **会被拦 · 左开关** —— 写入本地仓库:
49
+
50
+ ```
51
+ git add · git commit · git am · git apply · git checkout-index · git config
52
+ git merge · git mv · git notes · git rebase · git reset · git restore
53
+ git revert · git rm · git stash · git switch · git tag
54
+ git update-index · git update-ref
55
+ ```
56
+
57
+ **会被拦 · 右开关** —— 触达远端:
58
+
59
+ ```
60
+ git push · git pull · git fetch · git clone · git ls-remote · git remote
61
+ git submodule · git send-pack · git archive · git request-pull · git svn
62
+ gh repo / pr / release / issue / run / workflow / api / gist / secret / …
63
+ 命令行上直接出现 github.com、gitlab.com、gitee.com 等仓库地址
64
+ ```
65
+
66
+ **不会被拦**:`git status`、`git log`、`git diff`、`git show`、`git branch`、`git blame`、`git init`、`git rev-parse`、`git check-ignore`、`git ls-files`、`git worktree`、`git help`、`gh auth`、`gh config`、`gh api /user`,以及任何与 git 无关的命令。`git init` 是有意放行的:建仓库既不上传也不提交。
67
+
68
+ 判定是**引用感知**的:`git commit -m "do not push this"` 是本地提交,不是上传;`echo "git push" > notes.txt` 什么都不是。判定也不吃前缀:`sudo git push`、`env FOO=1 git commit`、`C:\Program Files\Git\cmd\git.exe push` 都能识别出来。
69
+
70
+ ## 被拦时 agent 看到什么
71
+
72
+ ```
73
+ 已阻止:DSH 的「Git 仓库保护」插件当前开着左侧的本地仓库开关,
74
+ 写入本地仓库的操作(git add / git commit 等)被拒绝。
75
+ 被拦截的命令:`git commit -m x`
76
+ 这是用户有意设置的开关,不是故障:不要改用其他命令、其他工具或直接调用 API 绕过它,
77
+ 也不要尝试关闭该开关。请把这一步作为「未执行」如实报告给用户,
78
+ 并说明用户可以点击会话标题栏的两个方形按钮自行放行。
79
+ ```
80
+
81
+ ## 已知限制
82
+
83
+ - **不改动你的仓库**:不写 `.git/hooks`,不碰 `git config`,只做拦截。
84
+ - **会误伤「正文里写着命令名」的调用**:判定看的是工具调用里命令类字段(`command` / `script` / `code` 等)的整串文本,所以用 `write` 写一份含 `git push` 字样的文档时,那次写入本身可能被拦。这是有意的偏向 —— 宁可多拦一次写入,也不放过一次上传;换个写法即可正常写入。
85
+ - **拦不住不走 shell 的路径**:它针对的是 agent 通过命令上传仓库这条真实路径。
86
+ - **不做事后撤销**:拦在事前,不存在已经推上去再回滚的窗口。
87
+ - **状态不持久化**:DSH 重启后回到「两个都开启」。
88
+
89
+ ## 许可
90
+
91
+ MIT