git-ai-control 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,41 @@
1
+ # 更新日志
2
+
3
+ 本项目的所有重要变更都会记录在此文件中。
4
+
5
+ ## [0.2.0] - 2026-07-30
6
+
7
+ ### 新增
8
+
9
+ - 新增 npm 命令 `npx git-ai-control start`;
10
+ - 命令会安装或更新本机服务,并自动打开配置页面;
11
+ - README 增加项目简介、真实脱敏截图、快速开始和贡献指南。
12
+
13
+ ### 安全
14
+
15
+ - 移除源码中硬编码的原上报端点,改为安装时备份至权限为 `0600` 的本机配置;
16
+ - 安装升级时可从旧版运行时迁移原上报端点;
17
+ - README 截图中的仓库地址、用户目录和 Skill 规则均使用 `example` 数据;
18
+ - 清理公开源码、发布产物和 Git 元数据中的组织及私人仓库信息。
19
+
20
+ ## [0.1.0] - 2026-07-30
21
+
22
+ ### 新增
23
+
24
+ - 基于 React、Vite 和 shadcn/ui 的 Git AI 本地配置中心;
25
+ - 仓库插件和 Skill 过滤插件的独立配置表单;
26
+ - 可配置的数据类型开关、仓库字段脱敏、Skill 关键词过滤和仓库主机匹配;
27
+ - 配置驱动的本机上传过滤运行时;
28
+ - Web 服务与过滤服务的 LaunchAgent 模板;
29
+ - 可重复执行的安装和卸载脚本;
30
+ - 右上角配置验证 Toast;
31
+ - `custom_metrics` 定制版和官方 `git-ai-project/git-ai` 的自动识别;
32
+ - 官方版 OSS 遥测开关及真实兼容能力提示;
33
+ - 官方版与定制版的兼容性说明。
34
+
35
+ ### 安全
36
+
37
+ - GitHub 新安装默认仅允许脱敏 Token,阻断 Commit、Checkpoint、Agent、提示报告、提示耗时和 Skill 上报;
38
+ - 插件配置损坏时使用默认拒绝策略;
39
+ - Web 服务仅监听本机回环地址;
40
+ - 用户配置采用原子写入,安装过程保留已有配置;
41
+ - 官方版不支持细粒度过滤时不会修改无效的 `custom_metrics.json`。
@@ -0,0 +1,66 @@
1
+ # Git AI 兼容性说明
2
+
3
+ ## 结论
4
+
5
+ 本项目同时支持两类 Git AI,但支持层级不同:
6
+
7
+ | 能力 | `custom_metrics` 定制版 | 官方 `git-ai-project/git-ai` |
8
+ | --- | --- | --- |
9
+ | 管理 `~/.git-ai/config.json` | 支持 | 支持 |
10
+ | 自动更新、版本检查、仓库排除 | 支持 | 支持 |
11
+ | OSS Sentry/PostHog 遥测开关 | 配置会保留,定制版可忽略 | 支持 |
12
+ | 仓库级数据类型开关 | 支持 | 不支持 |
13
+ | 仓库、路径、分支字段脱敏 | 支持 | 不支持 |
14
+ | Skill 名称过滤 | 支持 | 不支持 |
15
+ | GitHub 仅上传脱敏 Token | 支持 | 官方版当前无法通过外部配置实现 |
16
+
17
+ 安装脚本会检查 `git-ai` 二进制是否包含 `custom_metrics.json` 扩展点:
18
+
19
+ - 检测到扩展点时,将自定义指标端点指向 `127.0.0.1:38741`,启用完整过滤;
20
+ - 未检测到扩展点时,不创建或修改无效的 `custom_metrics.json`,只启用原生配置管理;
21
+ - Web 页面会显示当前发行版和细粒度过滤是否真正接管。
22
+
23
+ ## 官方版为什么不能直接使用现有过滤器
24
+
25
+ 审计基线:
26
+
27
+ - 上游仓库:[`git-ai-project/git-ai`](https://github.com/git-ai-project/git-ai)
28
+ - 上游提交:[`a751efd`](https://github.com/git-ai-project/git-ai/commit/a751efd64d129272947239f819822bfee14bef97)
29
+ - 审计日期:2026-07-30
30
+
31
+ 官方版与本机定制版使用不同的上传接口:
32
+
33
+ 1. 本机定制版读取 `~/.git-ai/custom_metrics.json`,每种事件都有独立端点,例如 `token_usage_endpoint_v2`、`skill_usage_endpoint_v2` 和 `agent_usage_endpoint_v2`。
34
+ 2. 官方版没有读取 `custom_metrics.json`,登录或配置 API key 后,将压缩后的指标批量发送到 `/worker/metrics/upload`。
35
+ 3. 官方指标批次使用位置编码的事件结构,提交、Checkpoint、Agent、Session 等事件混在同一个批次中,官方配置没有提供单独的指标代理地址。
36
+
37
+ 相关上游源码:
38
+
39
+ - [`src/config.rs`](https://github.com/git-ai-project/git-ai/blob/main/src/config.rs):原生配置字段和 `~/.git-ai/config.json` 路径;
40
+ - [`src/api/metrics.rs`](https://github.com/git-ai-project/git-ai/blob/main/src/api/metrics.rs):官方 `/worker/metrics/upload` 上传入口;
41
+ - [`src/metrics/types.rs`](https://github.com/git-ai-project/git-ai/blob/main/src/metrics/types.rs):批量指标协议;
42
+ - [`src/metrics/attrs.rs`](https://github.com/git-ai-project/git-ai/blob/main/src/metrics/attrs.rs):仓库与分支等位置编码字段。
43
+
44
+ 因此,把官方版的 `api_base_url` 直接改到当前过滤器并不安全:它还会影响登录、升级、Notes、CAS 和其他 API,并且需要正确代理认证头和全部请求类型。本项目不会用这种方式伪装成“已兼容”。
45
+
46
+ ## 官方版当前可用的隐私能力
47
+
48
+ 本项目可以管理官方版已经公开支持的原生设置:
49
+
50
+ - `exclude_repositories`:匹配后整个仓库停用 Git AI;
51
+ - `exclude_prompts_in_repositories`:提示词和会话内容仅保存在本地;
52
+ - `telemetry_oss=off`:关闭官方 OSS 的 Sentry/PostHog 遥测;
53
+ - `disable_auto_updates`、`disable_version_checks`:更新行为。
54
+
55
+ 注意:`telemetry_oss=off` 不等于禁用登录后的 `/worker/metrics/upload`。官方源码中该上传是否执行由登录状态或 API key 决定。
56
+
57
+ ## 达到完整官方兼容需要什么
58
+
59
+ 要让官方版也支持“GitHub 仅上传脱敏 Token”,优先方案是推动上游提供稳定扩展点:
60
+
61
+ 1. 可配置的 metrics endpoint;
62
+ 2. 上传前本地过滤回调或插件接口;
63
+ 3. 可按仓库和事件类型控制的官方配置;
64
+ 4. 稳定、带版本号的指标批次字段说明。
65
+
66
+ 在上游提供其中一种能力前,本项目对官方版保持“原生配置兼容”,不会宣称细粒度过滤已经生效。
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # Git AI Control Panel
2
+
3
+ 公司统一安装了 Git AI,但不想让私人 GitHub 项目的仓库名、路径、分支或 Skill 使用情况被上报?可以试试 Git AI Control Panel。
4
+
5
+ 它是一个仅运行在 macOS 本机的 Git AI 配置与上传策略管理页面:不用手改 JSON,也不用为每条隐私规则编写脚本,就能按仓库主机控制允许上传的数据类型和字段。前端使用 React、Vite 与 shadcn/ui,Web 服务只监听 `127.0.0.1:38742`,不会向局域网或公网开放。
6
+
7
+ > [!IMPORTANT]
8
+ > 项目可以识别 `custom_metrics` 定制版和官方 [`git-ai-project/git-ai`](https://github.com/git-ai-project/git-ai),但两者支持层级不同。仓库级事件开关、字段脱敏和 Skill 过滤目前需要 `custom_metrics` 扩展点;官方版只能管理 Git AI 已公开的原生配置。安装前请阅读[兼容性说明](COMPATIBILITY.md)。
9
+
10
+ ## 功能
11
+
12
+ - 可视化管理 Git AI 自动更新、版本检查、仓库排除和提示词排除;
13
+ - 通过“匹配仓库主机”统一处理 GitHub、GitLab、Gitee 或其他 Git 服务;
14
+ - 分别控制 Token、Skills、Commit、Checkpoint、Agent、提示耗时和提示报告;
15
+ - 可删除仓库信息、项目路径和分支名称等敏感字段;
16
+ - 可将允许上传的 Skill 项目目录替换为固定目录;
17
+ - 可按关键词或正则拦截指定 Skill;
18
+ - 仓库插件与 Skill 过滤插件使用各自独立的配置表单;
19
+ - 支持配置验证、运行状态检查和本机过滤服务重启。
20
+
21
+ ## 界面截图
22
+
23
+ ### Git AI 原生设置
24
+
25
+ ![Git AI 原生设置页面](docs/images/git-ai-settings.jpg)
26
+
27
+ ### 插件管理
28
+
29
+ ![仓库插件与 Skill 过滤插件管理页面](docs/images/plugin-management.jpg)
30
+
31
+ 仓库插件可以同时配置匹配主机、允许上传的数据类型和允许保留的字段;Skill 过滤插件使用独立表单管理名称规则。每种插件类型只能配置一次,新增其他类型的插件会增加新的配置模块,不会替换已有模块。
32
+
33
+ ## 快速开始
34
+
35
+ ### 1. 一条命令启动
36
+
37
+ 目前支持 macOS,并要求 Git AI 已安装在:
38
+
39
+ ```text
40
+ ~/.git-ai/bin/git-ai
41
+ ```
42
+
43
+ 确认文件存在后运行:
44
+
45
+ ```bash
46
+ npx git-ai-control start
47
+ ```
48
+
49
+ 该命令会自动下载最新版本、安装或更新本机服务,并打开 Git AI 配置中心。安装过程会:
50
+
51
+ 1. 识别当前 Git AI 是否支持 `custom_metrics` 扩展;
52
+ 2. 将原始上报端点备份到仅当前用户可读的本机配置;
53
+ 3. 安装控制页面和上传过滤运行时;
54
+ 4. 保留已有的 `config.json` 与 `filter_plugins.json`;
55
+ 5. 创建并启动两个 macOS LaunchAgent;
56
+ 6. 等待控制页面和过滤服务通过健康检查。
57
+
58
+ 如果浏览器没有自动打开,可以手动访问:
59
+
60
+ ```text
61
+ http://127.0.0.1:38742
62
+ ```
63
+
64
+ 页面顶部会显示当前 Git AI 发行版、过滤接管状态和服务状态。
65
+
66
+ ### 2. 配置仓库插件
67
+
68
+ 以“GitHub 私人仓库只允许上传 Token”为例:
69
+
70
+ 1. 在“仓库插件”中添加或打开现有仓库插件;
71
+ 2. 在“匹配仓库主机”中填写 `github.com`;
72
+ 3. 只打开 `Token`,关闭 `Skills`、`Commit`、`Checkpoint`、`Agent`、提示耗时和提示报告;
73
+ 4. 关闭“仓库信息”“项目路径”和“分支名称”;
74
+ 5. 保存配置。
75
+
76
+ 同一个仓库插件也可以填写多个主机,每行一个。GitLab、Gitee 和自建 Git 服务不需要单独开发插件。
77
+
78
+ ### 3. 配置 Skill 过滤插件
79
+
80
+ 需要按名称拦截 Skill 时:
81
+
82
+ 1. 添加“Skill 过滤插件”;
83
+ 2. 打开插件;
84
+ 3. 每行填写一个关键词或正则;
85
+ 4. 保存配置。
86
+
87
+ Skill 过滤插件只负责名称规则。仓库匹配、上传类型和目录替换仍由仓库插件负责。
88
+
89
+ ### 4. 验证配置
90
+
91
+ 点击页面中的“验证配置”。结果会通过右上角 Toast 显示,不会占用配置表单空间。
92
+
93
+ 也可以在终端检查两个本机服务:
94
+
95
+ ```bash
96
+ curl -fsS http://127.0.0.1:38742/api/status
97
+ curl -fsS http://127.0.0.1:38741/health
98
+ ```
99
+
100
+ ## 工作方式
101
+
102
+ 本项目不会修改 `~/.git-ai/bin/git-ai` 二进制。检测到 `custom_metrics` 扩展点后,安装脚本会将 Git AI 的自定义上报端点指向本机过滤服务:
103
+
104
+ ```text
105
+ Git AI
106
+ -> ~/.git-ai/custom_metrics.json
107
+ -> http://127.0.0.1:38741
108
+ -> 读取 ~/.git-ai/filter_plugins.json
109
+ -> 读取 ~/.git-ai/upstream_metrics.json
110
+ -> 拦截,或脱敏后转发至原上报服务
111
+ ```
112
+
113
+ 控制页面保存时只更新:
114
+
115
+ - `~/.git-ai/config.json`:Git AI 原生设置;
116
+ - `~/.git-ai/filter_plugins.json`:仓库插件和 Skill 过滤插件策略。
117
+
118
+ 过滤逻辑来自仓库中的 `plugins/upload-filter/plugin_filter_runtime.py`。控制页面不会动态生成或改写 Python 脚本,`~/.git-ai` 只保存安装副本和用户配置。
119
+
120
+ ## 文件位置
121
+
122
+ | 内容 | 位置 |
123
+ | --- | --- |
124
+ | 过滤运行时源码 | `plugins/upload-filter/plugin_filter_runtime.py` |
125
+ | LaunchAgent 模板 | `launchagents/*.plist.in` |
126
+ | 安装与卸载脚本 | `scripts/install.sh`、`scripts/uninstall.sh` |
127
+ | Git AI 原生配置 | `~/.git-ai/config.json` |
128
+ | 插件策略 | `~/.git-ai/filter_plugins.json` |
129
+ | 原上报端点本机备份 | `~/.git-ai/upstream_metrics.json` |
130
+ | 过滤运行时安装副本 | `~/.git-ai/filters/plugin_filter_runtime.py` |
131
+ | Web 服务安装副本 | `~/.git-ai/control-panel` |
132
+ | Web 服务 LaunchAgent | `~/Library/LaunchAgents/com.git-ai.control-panel.plist` |
133
+ | 过滤服务 LaunchAgent | `~/Library/LaunchAgents/com.git-ai.skill-usage-filter.plist` |
134
+
135
+ ## 卸载
136
+
137
+ ```bash
138
+ ./scripts/uninstall.sh
139
+ ```
140
+
141
+ 卸载脚本会停止两个服务、删除本项目安装的程序副本,并将上报端点恢复为 Git AI 原地址。`config.json`、`filter_plugins.json` 和日志会保留。
142
+
143
+ ## 参与贡献
144
+
145
+ 欢迎提交 Issue 和 Pull Request,尤其欢迎:
146
+
147
+ - 补充不同 Git AI 版本的兼容性验证;
148
+ - 新增与仓库过滤不同类型的独立插件;
149
+ - 改进过滤规则的测试覆盖;
150
+ - 修正文档、交互和无障碍问题。
151
+
152
+ 开发前请先 Fork 仓库并创建主题分支。前端源码位于 `frontend/git-ai-control-panel`,shadcn/ui 组件位于 `src/components/ui`。
153
+
154
+ ```bash
155
+ cd frontend/git-ai-control-panel
156
+ npm ci
157
+ npm run lint
158
+ npm run build
159
+ cd ../..
160
+ /usr/bin/python3 -m py_compile server.py plugins/upload-filter/plugin_filter_runtime.py
161
+ ```
162
+
163
+ 提交 Pull Request 时请说明:
164
+
165
+ 1. 解决的问题和使用场景;
166
+ 2. 对配置结构或过滤行为的影响;
167
+ 3. 已执行的验证命令;
168
+ 4. 涉及界面变化时附上前后截图。
169
+
170
+ 新增插件类型时,请为它设计独立的数据结构和配置表单;不要复用仓库插件表单来表达无关能力。涉及上报兼容性时,应基于实际 Git AI 版本和请求路径验证,避免把“页面可配置”误写成“运行时已接管”。
171
+
172
+ ## 安全边界
173
+
174
+ - Web 服务只绑定本机回环地址;
175
+ - 不读取或展示 Git AI API key 等敏感字段;
176
+ - 原始上报端点不会写入项目源码,只保存在权限为 `0600` 的本机配置中;
177
+ - 配置保存采用临时文件替换,避免写入中断产生不完整文件;
178
+ - 页面没有跨域权限,拒绝非本页面来源的修改请求;
179
+ - 插件配置缺失或损坏时,GitHub 默认策略保持全部阻断;
180
+ - 官方版缺少细粒度过滤扩展点时,页面会显示“仅原生配置兼容”,不会把空闲代理误报为已接管。
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "node:child_process"
4
+ import { fileURLToPath } from "node:url"
5
+ import path from "node:path"
6
+
7
+ const command = process.argv[2]
8
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
9
+ const controlPanelUrl = "http://127.0.0.1:38742"
10
+
11
+ function printHelp() {
12
+ console.log(`Git AI Control Panel
13
+
14
+ 用法:
15
+ git-ai-control start 安装或更新本机服务,并打开配置页面
16
+ git-ai-control --help 显示帮助`)
17
+ }
18
+
19
+ if (command === "--help" || command === "-h" || !command) {
20
+ printHelp()
21
+ process.exit(0)
22
+ }
23
+
24
+ if (command !== "start") {
25
+ console.error(`未知命令:${command}`)
26
+ printHelp()
27
+ process.exit(1)
28
+ }
29
+
30
+ if (process.platform !== "darwin") {
31
+ console.error("git-ai-control 目前仅支持 macOS")
32
+ process.exit(1)
33
+ }
34
+
35
+ const installResult = spawnSync("/bin/sh", [path.join(packageRoot, "scripts/install.sh")], {
36
+ cwd: packageRoot,
37
+ env: process.env,
38
+ stdio: "inherit",
39
+ })
40
+
41
+ if (installResult.error) {
42
+ console.error(`安装失败:${installResult.error.message}`)
43
+ process.exit(1)
44
+ }
45
+ if (installResult.status !== 0) {
46
+ process.exit(installResult.status ?? 1)
47
+ }
48
+
49
+ const openResult = spawnSync("/usr/bin/open", [controlPanelUrl], {
50
+ stdio: "ignore",
51
+ })
52
+ if (openResult.error || openResult.status !== 0) {
53
+ console.error(`服务已启动,请手动访问 ${controlPanelUrl}`)
54
+ process.exit(1)
55
+ }
56
+
57
+ console.log(`已打开 Git AI 配置中心:${controlPanelUrl}`)
Binary file
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
3
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4
+ <plist version="1.0">
5
+ <dict>
6
+ <key>Label</key>
7
+ <string>com.git-ai.control-panel</string>
8
+ <key>ProgramArguments</key>
9
+ <array>
10
+ <string>/usr/bin/python3</string>
11
+ <string>__GIT_AI_ROOT__/control-panel/server.py</string>
12
+ </array>
13
+ <key>RunAtLoad</key>
14
+ <true/>
15
+ <key>KeepAlive</key>
16
+ <true/>
17
+ <key>ProcessType</key>
18
+ <string>Background</string>
19
+ <key>StandardOutPath</key>
20
+ <string>__GIT_AI_ROOT__/control-panel.out.log</string>
21
+ <key>StandardErrorPath</key>
22
+ <string>__GIT_AI_ROOT__/control-panel.err.log</string>
23
+ </dict>
24
+ </plist>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
3
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4
+ <plist version="1.0">
5
+ <dict>
6
+ <key>Label</key>
7
+ <string>com.git-ai.skill-usage-filter</string>
8
+ <key>ProgramArguments</key>
9
+ <array>
10
+ <string>/usr/bin/python3</string>
11
+ <string>__GIT_AI_ROOT__/filters/plugin_filter_runtime.py</string>
12
+ </array>
13
+ <key>RunAtLoad</key>
14
+ <true/>
15
+ <key>KeepAlive</key>
16
+ <true/>
17
+ <key>StandardOutPath</key>
18
+ <string>__GIT_AI_ROOT__/filters/skill_usage_filter.out.log</string>
19
+ <key>StandardErrorPath</key>
20
+ <string>__GIT_AI_ROOT__/filters/skill_usage_filter.err.log</string>
21
+ </dict>
22
+ </plist>
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "git-ai-control",
3
+ "version": "0.2.0",
4
+ "description": "Git AI 本地配置与上传隐私控制面板",
5
+ "type": "module",
6
+ "bin": {
7
+ "git-ai-control": "bin/git-ai-control.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "docs",
12
+ "launchagents",
13
+ "plugins",
14
+ "scripts",
15
+ "static",
16
+ "CHANGELOG.md",
17
+ "COMPATIBILITY.md",
18
+ "README.md",
19
+ "policy.example.json",
20
+ "server.py"
21
+ ],
22
+ "scripts": {
23
+ "check": "node bin/git-ai-control.js --help && /usr/bin/python3 -m py_compile server.py plugins/upload-filter/plugin_filter_runtime.py && sh -n scripts/install.sh scripts/uninstall.sh"
24
+ },
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "os": [
29
+ "darwin"
30
+ ],
31
+ "keywords": [
32
+ "git-ai",
33
+ "privacy",
34
+ "telemetry",
35
+ "macos"
36
+ ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/yingyanzhitong/git-ai-control.git"
40
+ },
41
+ "homepage": "https://github.com/yingyanzhitong/git-ai-control#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/yingyanzhitong/git-ai-control/issues"
44
+ }
45
+ }