bingo-light 2.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 +21 -0
- package/README.md +522 -0
- package/README.zh-CN.md +534 -0
- package/bin/cli.js +46 -0
- package/bin/mcp.js +45 -0
- package/bingo-light +1094 -0
- package/bingo_core/__init__.py +77 -0
- package/bingo_core/__pycache__/__init__.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/_entry.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/config.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/exceptions.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/git.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/models.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/repo.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/setup.cpython-313.pyc +0 -0
- package/bingo_core/__pycache__/state.cpython-313.pyc +0 -0
- package/bingo_core/config.py +110 -0
- package/bingo_core/exceptions.py +48 -0
- package/bingo_core/git.py +194 -0
- package/bingo_core/models.py +37 -0
- package/bingo_core/repo.py +2376 -0
- package/bingo_core/setup.py +549 -0
- package/bingo_core/state.py +306 -0
- package/completions/bingo-light.bash +118 -0
- package/completions/bingo-light.fish +197 -0
- package/completions/bingo-light.zsh +169 -0
- package/mcp-server.py +788 -0
- package/package.json +34 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<br>
|
|
3
|
+
<img src="docs/logo.svg" alt="bingo-light logo" width="200">
|
|
4
|
+
<br><br>
|
|
5
|
+
<strong>面向人类和 AI 代理的 Fork 维护工具。<br>一条命令同步。零依赖。</strong>
|
|
6
|
+
<br><br>
|
|
7
|
+
<a href="README.md">English</a> | <b>简体中文</b>
|
|
8
|
+
<br><br>
|
|
9
|
+
<a href="https://github.com/DanOps-1/bingo-light/actions"><img src="https://github.com/DanOps-1/bingo-light/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
|
11
|
+
<a href="https://github.com/DanOps-1/bingo-light/releases"><img src="https://img.shields.io/github/v/release/DanOps-1/bingo-light?label=Release&color=orange" alt="Release"></a>
|
|
12
|
+
<a href="#mcp-服务器"><img src="https://img.shields.io/badge/MCP_Server-29_tools-blueviolet.svg" alt="MCP: 27 tools"></a>
|
|
13
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.8+-3776ab.svg" alt="Python 3.8+"></a>
|
|
14
|
+
<img src="https://img.shields.io/badge/Dependencies-Zero-brightgreen.svg" alt="Zero deps">
|
|
15
|
+
<a href="https://github.com/DanOps-1/bingo-light/stargazers"><img src="https://img.shields.io/github/stars/DanOps-1/bingo-light?style=social" alt="Stars"></a>
|
|
16
|
+
<br><br>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
GitHub 的 "Sync fork" 按钮一碰到你的定制化改动就报废。`git rebase` 是个 6 步仪式。而且这些东西没一个能从 AI 代理调用。
|
|
20
|
+
|
|
21
|
+
**bingo-light 三个问题一起解决。**
|
|
22
|
+
|
|
23
|
+
你的补丁作为干净的栈叠在上游之上。同步就是 `bingo-light sync`。冲突自动记忆,解决一次永远不用再解决。出了问题 `bingo-light undo` 一秒复原。
|
|
24
|
+
|
|
25
|
+
每条命令都输出 JSON。内置 MCP 服务器提供 29 个工具,让 AI 代理自主管理你的 Fork — 从初始化到冲突解决,全程无需人工介入。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 目录
|
|
30
|
+
|
|
31
|
+
- [快速开始](#快速开始)
|
|
32
|
+
- [演示](#演示)
|
|
33
|
+
- [安装](#安装)
|
|
34
|
+
- [功能特性](#功能特性)
|
|
35
|
+
- [工作原理](#工作原理)
|
|
36
|
+
- [MCP 服务器](#mcp-服务器)
|
|
37
|
+
- [命令参考](#命令参考)
|
|
38
|
+
- [集成指南](#集成指南)
|
|
39
|
+
- [配置](#配置)
|
|
40
|
+
- [常见问题](#常见问题)
|
|
41
|
+
- [与其他方案对比](#与其他方案对比)
|
|
42
|
+
- [项目生态](#项目生态)
|
|
43
|
+
- [参与贡献](#参与贡献)
|
|
44
|
+
- [许可证](#许可证)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 快速开始
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 安装(任选一种)
|
|
52
|
+
pip install bingo-light # Python
|
|
53
|
+
npm install -g bingo-light # Node.js
|
|
54
|
+
brew install DanOps-1/tap/bingo-light # Homebrew
|
|
55
|
+
|
|
56
|
+
# 初始化 Fork 追踪
|
|
57
|
+
cd my-forked-project
|
|
58
|
+
bingo-light init https://github.com/original/project.git
|
|
59
|
+
|
|
60
|
+
# 改代码,创建命名补丁
|
|
61
|
+
vim src/feature.py
|
|
62
|
+
bingo-light patch new my-feature
|
|
63
|
+
|
|
64
|
+
# 与上游同步(补丁自动变基到最新上游之上)
|
|
65
|
+
bingo-light sync
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
搞定。你的补丁始终是干净的栈,叠在上游最新代码之上。想同步就同步。
|
|
69
|
+
|
|
70
|
+
## 演示
|
|
71
|
+
|
|
72
|
+
### 基本流程:初始化、创建补丁、同步
|
|
73
|
+
|
|
74
|
+
<p align="center">
|
|
75
|
+
<img src="docs/demo.svg" alt="bingo-light 基本演示" width="850">
|
|
76
|
+
</p>
|
|
77
|
+
|
|
78
|
+
### 冲突解决:同步、分析、修复
|
|
79
|
+
|
|
80
|
+
<p align="center">
|
|
81
|
+
<img src="docs/demo-conflict.svg" alt="bingo-light 冲突解决演示" width="850">
|
|
82
|
+
</p>
|
|
83
|
+
|
|
84
|
+
> AI 调用 `conflict-analyze --json`,读取结构化的 ours/theirs 数据,写入合并后的文件,rebase 自动继续。全程不需要人。
|
|
85
|
+
|
|
86
|
+
### AI 获取结构化 JSON
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
$ bingo-light status --json
|
|
90
|
+
```
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"ok": true,
|
|
94
|
+
"upstream_url": "https://github.com/torvalds/linux.git",
|
|
95
|
+
"behind": 47,
|
|
96
|
+
"patch_count": 2,
|
|
97
|
+
"patches": [
|
|
98
|
+
{"name": "custom-scheduler", "hash": "a3f7c21", "subject": "O(1) task scheduling", "files": 3},
|
|
99
|
+
{"name": "perf-monitoring", "hash": "b8e2d4f", "subject": "eBPF tracing hooks", "files": 5}
|
|
100
|
+
],
|
|
101
|
+
"conflict_risk": ["kernel/sched/core.c"]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 冲突解决(AI 工作流)
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
$ bingo-light conflict-analyze --json
|
|
109
|
+
```
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"rebase_in_progress": true,
|
|
113
|
+
"current_patch": "custom-scheduler",
|
|
114
|
+
"conflicts": [
|
|
115
|
+
{
|
|
116
|
+
"file": "kernel/sched/core.c",
|
|
117
|
+
"conflict_count": 2,
|
|
118
|
+
"ours": "... 上游版本 ...",
|
|
119
|
+
"theirs": "... 你的补丁版本 ...",
|
|
120
|
+
"hint": "上游重构了调度器核心;补丁需要适配新结构。"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 安装
|
|
127
|
+
|
|
128
|
+
任选一种安装方式,然后运行 `bingo-light setup` 交互式配置 MCP(支持 Claude Code、Cursor、Windsurf、VS Code/Copilot、Zed、Gemini CLI 等)。
|
|
129
|
+
|
|
130
|
+
### pip / pipx
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pip install bingo-light # 或: pipx install bingo-light
|
|
134
|
+
bingo-light setup # 交互式选择要配置的 AI 工具
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### npm / npx
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm install -g bingo-light # 全局安装
|
|
141
|
+
bingo-light setup
|
|
142
|
+
|
|
143
|
+
# 或用 npx 免安装:
|
|
144
|
+
npx bingo-light setup
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
MCP 客户端可直接使用 npx:
|
|
148
|
+
```json
|
|
149
|
+
{"command": "npx", "args": ["-y", "bingo-light-mcp"]}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Homebrew
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
brew install DanOps-1/tap/bingo-light
|
|
156
|
+
bingo-light setup
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Docker
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# CLI
|
|
163
|
+
docker run --rm -v "$PWD:/repo" -w /repo ghcr.io/danops-1/bingo-light status
|
|
164
|
+
|
|
165
|
+
# MCP 服务器(stdio 传输)
|
|
166
|
+
docker run --rm -i -v "$PWD:/repo" -w /repo ghcr.io/danops-1/bingo-light mcp-server.py
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Shell 安装器
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
curl -fsSL https://raw.githubusercontent.com/DanOps-1/bingo-light/main/install.sh | sh
|
|
173
|
+
|
|
174
|
+
# 非交互模式(CI / Docker)
|
|
175
|
+
curl -fsSL .../install.sh | sh -s -- --yes
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 从源码安装
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
git clone https://github.com/DanOps-1/bingo-light.git
|
|
182
|
+
cd bingo-light
|
|
183
|
+
make install && bingo-light setup
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**依赖:** Python 3.8+, git 2.20+。零 pip 依赖。
|
|
187
|
+
|
|
188
|
+
## 功能特性
|
|
189
|
+
|
|
190
|
+
### 给 AI 代理用
|
|
191
|
+
|
|
192
|
+
| 功能 | 说明 |
|
|
193
|
+
|------|------|
|
|
194
|
+
| **MCP 服务器** | 29 个工具,覆盖从初始化到冲突解决的全流程 |
|
|
195
|
+
| **`--json` 标志** | 所有命令返回结构化 JSON |
|
|
196
|
+
| **`--yes` 标志** | 完全非交互,不需要 TTY |
|
|
197
|
+
| **自动检测非 TTY** | 管道或子进程调用时自动抑制交互提示 |
|
|
198
|
+
| **`BINGO_DESCRIPTION`** | 通过环境变量设置补丁描述 |
|
|
199
|
+
| **`conflict-analyze`** | 结构化冲突数据:文件、ours、theirs、提示 |
|
|
200
|
+
| **`conflict-resolve`** | 通过 MCP 写入解决内容,自动暂存,继续 rebase |
|
|
201
|
+
| **Advisor 代理** | `contrib/agent.py` 监控漂移、分析风险、安全时自动同步 |
|
|
202
|
+
|
|
203
|
+
### 给人类用
|
|
204
|
+
|
|
205
|
+
| 功能 | 说明 |
|
|
206
|
+
|------|------|
|
|
207
|
+
| **零依赖** | Python 3 + git,`pip install bingo-light` 即可 |
|
|
208
|
+
| **命名补丁栈** | 每个改动都是一个独立的、有名字的 commit |
|
|
209
|
+
| **一键同步** | `bingo-light sync` 把你的补丁变基到上游之上 |
|
|
210
|
+
| **预演模式** | `sync --dry-run` 先在临时分支上试跑 |
|
|
211
|
+
| **冲突记忆** | git rerere 自动启用;解决一次,永远不用再解决 |
|
|
212
|
+
| **一键撤销** | `bingo-light undo` 瞬间恢复同步前状态 |
|
|
213
|
+
| **冲突预测** | `status` 提前告诉你哪些文件可能冲突 |
|
|
214
|
+
| **诊断** | `doctor` 全面诊断 + 测试变基 |
|
|
215
|
+
| **导出/导入** | 补丁导出为 `.patch` 文件(兼容 quilt) |
|
|
216
|
+
| **CI 自动同步** | 生成 GitHub Actions 工作流,冲突时自动告警 |
|
|
217
|
+
| **TUI 面板** | 基于 curses 的实时监控面板(`contrib/tui.py`) |
|
|
218
|
+
| **多仓库** | `workspace` 一个地方管理所有 Fork |
|
|
219
|
+
| **Shell 补全** | bash、zsh、fish 全支持 |
|
|
220
|
+
| **通知 Hook** | Discord、Slack、通用 Webhook,同步/冲突/测试事件触发 |
|
|
221
|
+
| **补丁元数据** | 标签、原因、过期日期、上游 PR 追踪 |
|
|
222
|
+
| **测试集成** | 同步后自动跑测试,失败自动回滚 |
|
|
223
|
+
|
|
224
|
+
## 工作原理
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
upstream (github.com/original/project)
|
|
228
|
+
|
|
|
229
|
+
| git fetch
|
|
230
|
+
v
|
|
231
|
+
upstream-tracking ─────── 上游的精确镜像,从不手动碰
|
|
232
|
+
|
|
|
233
|
+
| git rebase
|
|
234
|
+
v
|
|
235
|
+
bingo-patches ─────────── 你的改动叠在这里
|
|
236
|
+
|
|
|
237
|
+
+── [bl] custom-scheduler: O(1) 任务调度
|
|
238
|
+
+── [bl] perf-monitoring: eBPF 追踪钩子
|
|
239
|
+
+── [bl] fix-logging: 结构化 JSON 日志
|
|
240
|
+
|
|
|
241
|
+
v
|
|
242
|
+
HEAD (你的工作 Fork)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**同步流程:** 拉取上游 -> 快进追踪分支 -> 把补丁变基到上游之上。你的补丁始终干净地叠在最新代码上。
|
|
246
|
+
|
|
247
|
+
**冲突记忆:** 初始化时自动启用 git rerere。解决一次冲突,git 就记住了 -- 下次同步碰到同样的冲突,自动应用之前的修复。
|
|
248
|
+
|
|
249
|
+
**AI 冲突流程:** rebase 碰到冲突时,AI 调用 `conflict-analyze` 获取结构化数据(每个文件的 ours/theirs/提示),通过 `conflict-resolve` 写入解决内容,rebase 自动继续。全程不需要人。
|
|
250
|
+
|
|
251
|
+
## MCP 服务器
|
|
252
|
+
|
|
253
|
+
`mcp-server.py` 是零依赖的 Python 3 MCP 服务器,通过 stdio 暴露 29 个工具(JSON-RPC 2.0)。
|
|
254
|
+
|
|
255
|
+
### 配置
|
|
256
|
+
|
|
257
|
+
**Claude Code** -- 添加到 `.mcp.json` 或 `~/.claude/settings.json`:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"mcpServers": {
|
|
262
|
+
"bingo-light": {
|
|
263
|
+
"command": "python3",
|
|
264
|
+
"args": ["/path/to/bingo-light/mcp-server.py"]
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Claude Desktop** -- 添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"mcpServers": {
|
|
275
|
+
"bingo-light": {
|
|
276
|
+
"command": "python3",
|
|
277
|
+
"args": ["/path/to/bingo-light/mcp-server.py"]
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**任意 MCP 客户端**(VS Code Copilot、Cursor、自定义代理):通过 stdio 连接 `python3 mcp-server.py`。
|
|
284
|
+
|
|
285
|
+
### 全部工具
|
|
286
|
+
|
|
287
|
+
| 工具 | 用途 |
|
|
288
|
+
|------|------|
|
|
289
|
+
| `bingo_init` | 初始化 Fork 追踪 |
|
|
290
|
+
| `bingo_status` | 健康检查:漂移、补丁、冲突风险 |
|
|
291
|
+
| `bingo_sync` | 拉取上游并变基补丁 |
|
|
292
|
+
| `bingo_undo` | 恢复到同步前状态 |
|
|
293
|
+
| `bingo_patch_new` | 创建命名补丁 |
|
|
294
|
+
| `bingo_patch_list` | 列出补丁栈 |
|
|
295
|
+
| `bingo_patch_show` | 查看补丁 diff |
|
|
296
|
+
| `bingo_patch_drop` | 移除补丁 |
|
|
297
|
+
| `bingo_patch_export` | 导出为 `.patch` 文件 |
|
|
298
|
+
| `bingo_patch_import` | 导入 `.patch` 文件 |
|
|
299
|
+
| `bingo_patch_meta` | 获取/设置补丁元数据 |
|
|
300
|
+
| `bingo_patch_squash` | 合并两个补丁 |
|
|
301
|
+
| `bingo_patch_reorder` | 非交互式重排补丁 |
|
|
302
|
+
| `bingo_doctor` | 全面诊断 + 测试变基 |
|
|
303
|
+
| `bingo_diff` | 补丁总 diff vs 上游 |
|
|
304
|
+
| `bingo_auto_sync` | 生成 GitHub Actions 工作流 |
|
|
305
|
+
| `bingo_conflict_analyze` | AI 用的结构化冲突数据 |
|
|
306
|
+
| `bingo_conflict_resolve` | 写入解决内容,暂存,继续 rebase |
|
|
307
|
+
| `bingo_config` | 获取/设置配置 |
|
|
308
|
+
| `bingo_history` | 同步历史 + hash 映射 |
|
|
309
|
+
| `bingo_test` | 运行测试套件 |
|
|
310
|
+
| `bingo_workspace_status` | 多仓库工作区概览 |
|
|
311
|
+
| `bingo_patch_edit` | 修改已有补丁 |
|
|
312
|
+
| `bingo_workspace_init` | 初始化多仓库工作区 |
|
|
313
|
+
| `bingo_workspace_add` | 添加仓库到工作区 |
|
|
314
|
+
| `bingo_workspace_sync` | 同步工作区所有仓库 |
|
|
315
|
+
| `bingo_workspace_list` | 列出工作区仓库 |
|
|
316
|
+
|
|
317
|
+
## 命令参考
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
bingo-light init <upstream-url> [branch] 初始化上游追踪
|
|
321
|
+
bingo-light patch new <name> 创建命名补丁
|
|
322
|
+
bingo-light patch list [-v] 列出补丁栈
|
|
323
|
+
bingo-light patch show <name|index> 查看补丁 diff
|
|
324
|
+
bingo-light patch edit <name|index> 修改补丁(先暂存变更)
|
|
325
|
+
bingo-light patch drop <name|index> 移除补丁
|
|
326
|
+
bingo-light patch reorder [--order "3,1,2"] 重排补丁
|
|
327
|
+
bingo-light patch export [dir] 导出为 .patch 文件
|
|
328
|
+
bingo-light patch import <file|dir> 导入 .patch 文件
|
|
329
|
+
bingo-light patch squash <idx1> <idx2> 合并两个补丁
|
|
330
|
+
bingo-light patch meta <name> [key] [value] 获取/设置补丁元数据
|
|
331
|
+
bingo-light sync [--dry-run] [--force] 与上游同步
|
|
332
|
+
bingo-light sync --test 同步后跑测试,失败自动回滚
|
|
333
|
+
bingo-light undo 恢复到同步前状态
|
|
334
|
+
bingo-light status 健康检查 + 冲突预测
|
|
335
|
+
bingo-light doctor 全面诊断
|
|
336
|
+
bingo-light diff 补丁总 diff vs 上游
|
|
337
|
+
bingo-light log 同步历史
|
|
338
|
+
bingo-light conflict-analyze 分析 rebase 冲突
|
|
339
|
+
bingo-light config get|set|list [key] [val] 管理配置
|
|
340
|
+
bingo-light history 详细同步历史 + 映射
|
|
341
|
+
bingo-light test 运行测试套件
|
|
342
|
+
bingo-light workspace init|add|status|sync 多仓库管理
|
|
343
|
+
bingo-light auto-sync 生成 GitHub Actions 工作流
|
|
344
|
+
bingo-light version 打印版本
|
|
345
|
+
bingo-light help 打印帮助
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**全局标志:** `--json`(结构化 JSON 输出) | `--yes`(跳过所有确认提示)
|
|
349
|
+
|
|
350
|
+
## 集成指南
|
|
351
|
+
|
|
352
|
+
### Claude Code (MCP)
|
|
353
|
+
|
|
354
|
+
配置好 MCP 服务器后,Claude Code 端到端管理你的 Fork:
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
你: "把我的 Fork 和上游同步,修复所有冲突。"
|
|
358
|
+
|
|
359
|
+
Claude Code:
|
|
360
|
+
1. bingo_status(cwd) -> 落后 47 个 commit,风险文件: core.c
|
|
361
|
+
2. bingo_sync(cwd, dry_run) -> 预测 1 个冲突
|
|
362
|
+
3. bingo_sync(cwd) -> rebase 在冲突处停下
|
|
363
|
+
4. bingo_conflict_analyze() -> 结构化 ours/theirs/提示
|
|
364
|
+
5. 读取双方版本,生成合并内容
|
|
365
|
+
6. bingo_conflict_resolve(cwd, file, content) -> 搞定
|
|
366
|
+
7. bingo_status(cwd) -> 0 落后,所有补丁干净
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Aider / CLI 代理
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
bingo-light status --json # 解析 Fork 状态
|
|
373
|
+
bingo-light sync --yes # 非交互同步
|
|
374
|
+
bingo-light conflict-analyze --json # 结构化冲突数据
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### 自定义 Python 代理
|
|
378
|
+
|
|
379
|
+
```python
|
|
380
|
+
import subprocess, json
|
|
381
|
+
|
|
382
|
+
def bingo(cmd, cwd="/path/to/repo"):
|
|
383
|
+
result = subprocess.run(
|
|
384
|
+
["bingo-light"] + cmd.split() + ["--json", "--yes"],
|
|
385
|
+
cwd=cwd, capture_output=True, text=True
|
|
386
|
+
)
|
|
387
|
+
return json.loads(result.stdout)
|
|
388
|
+
|
|
389
|
+
status = bingo("status")
|
|
390
|
+
if status["behind"] > 0:
|
|
391
|
+
result = bingo("sync")
|
|
392
|
+
if result.get("conflicts"):
|
|
393
|
+
analysis = bingo("conflict-analyze")
|
|
394
|
+
for c in analysis["conflicts"]:
|
|
395
|
+
resolved = my_llm_resolve(c["ours"], c["theirs"], c["hint"])
|
|
396
|
+
# 通过 CLI 或 MCP 写入解决内容
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 配置
|
|
400
|
+
|
|
401
|
+
配置存储在 `.bingolight`(git-config 格式),通过 `.git/info/exclude` 排除在版本控制之外。
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
bingo-light config set sync.auto-test true # 同步后自动跑测试
|
|
405
|
+
bingo-light config set test.command "make test" # 测试命令
|
|
406
|
+
bingo-light config list # 查看所有配置
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 通知 Hook
|
|
410
|
+
|
|
411
|
+
在 `.bingo/hooks/` 中放置可执行脚本:
|
|
412
|
+
|
|
413
|
+
| Hook | 触发时机 |
|
|
414
|
+
|------|---------|
|
|
415
|
+
| `on-sync-success` | 同步成功后 |
|
|
416
|
+
| `on-conflict` | rebase 碰到冲突时 |
|
|
417
|
+
| `on-test-fail` | 同步后测试失败时 |
|
|
418
|
+
|
|
419
|
+
每个 Hook 通过 stdin 接收 JSON 数据。示例见 [contrib/hooks/](contrib/hooks/)(Slack、Discord、通用 Webhook)。
|
|
420
|
+
|
|
421
|
+
## 常见问题
|
|
422
|
+
|
|
423
|
+
<details>
|
|
424
|
+
<summary><b>为什么不直接 <code>git rebase</code>?</b></summary>
|
|
425
|
+
|
|
426
|
+
可以啊。bingo-light 自动化了 rebase 周边那堆烦人的操作:追踪上游远程、维护专用补丁分支、启用 rerere、同步前预测冲突、给自动化提供结构化输出。一次性 rebase 用不着这工具。但如果你长期维护 3 个以上补丁,它能省下大量时间。
|
|
427
|
+
</details>
|
|
428
|
+
|
|
429
|
+
<details>
|
|
430
|
+
<summary><b>能用在已有的 Fork 上吗?</b></summary>
|
|
431
|
+
|
|
432
|
+
能。在你的 Fork 里跑 `bingo-light init <upstream-url>`,然后用 `bingo-light patch new <name>` 把已有的改动转成命名补丁。任何标准 git 仓库都行。
|
|
433
|
+
</details>
|
|
434
|
+
|
|
435
|
+
<details>
|
|
436
|
+
<summary><b>只给 AI 用吗?人也能用吗?</b></summary>
|
|
437
|
+
|
|
438
|
+
当然都能用。`bingo-light sync` 这条命令,你跑和 AI 跑效果完全一样。AI 原生功能(`--json`、`--yes`、MCP)是纯增量的附加能力。不加这些标志,输出就是正常的人类友好格式。
|
|
439
|
+
</details>
|
|
440
|
+
|
|
441
|
+
<details>
|
|
442
|
+
<summary><b>冲突记忆是怎么回事?</b></summary>
|
|
443
|
+
|
|
444
|
+
bingo-light 在 `init` 时自动启用 git 的 `rerere`(reuse recorded resolution)。你解决一次冲突,git 就记住了。下次同步碰到同样的冲突,自动应用之前的修复。bingo-light 还会检测已自动解决的冲突并继续 rebase,不会傻等你。
|
|
445
|
+
</details>
|
|
446
|
+
|
|
447
|
+
<details>
|
|
448
|
+
<summary><b>同步搞砸了怎么办?</b></summary>
|
|
449
|
+
|
|
450
|
+
跑 `bingo-light undo`。它把补丁分支恢复到同步前的精确状态。基于 git reflog 实现,即使经历了复杂的 rebase 也稳得很。
|
|
451
|
+
</details>
|
|
452
|
+
|
|
453
|
+
<details>
|
|
454
|
+
<summary><b>支持 GitHub/GitLab/Bitbucket 吗?</b></summary>
|
|
455
|
+
|
|
456
|
+
支持。bingo-light 用的是标准 git 操作(fetch、rebase、push),跟任何 git 远程都能配合。`auto-sync` 命令生成 GitHub Actions 工作流,但核心工具跟平台无关。
|
|
457
|
+
</details>
|
|
458
|
+
|
|
459
|
+
<details>
|
|
460
|
+
<summary><b>和 <code>git format-patch</code> / quilt 有什么区别?</b></summary>
|
|
461
|
+
|
|
462
|
+
`format-patch` 能导出补丁,但不管理活的补丁栈。quilt 管理补丁,但在 git 体系之外运作。bingo-light 把补丁保持为真正的 git commit,所以你拥有完整的 git 历史、冲突解决能力、rerere 记忆 -- 同时还能以 quilt 兼容格式导出/导入。
|
|
463
|
+
</details>
|
|
464
|
+
|
|
465
|
+
## 为什么不用...
|
|
466
|
+
|
|
467
|
+
<details>
|
|
468
|
+
<summary><b>...GitHub 的 "Sync fork" 按钮?</b></summary>
|
|
469
|
+
<br>
|
|
470
|
+
|
|
471
|
+
它只能做 fast-forward。只要你有任何定制化改动(fork 上有上游没有的 commit),它要么拒绝,要么创建一个 merge commit 把你的改动埋起来。它没有补丁栈的概念,没有冲突记忆,没有给 AI 代理用的 API。
|
|
472
|
+
</details>
|
|
473
|
+
|
|
474
|
+
<details>
|
|
475
|
+
<summary><b>...手动 <code>git rebase</code>?</b></summary>
|
|
476
|
+
<br>
|
|
477
|
+
|
|
478
|
+
你可以。需要 6 步:fetch、checkout tracking 分支、pull、checkout patches 分支、rebase、push。你得记住哪个分支是哪个,手动启用 rerere,出了问题还得祈祷 reflog 没搞乱。bingo-light 把这些全包进 `bingo-light sync`,带自动撤销、冲突预测和结构化输出。
|
|
479
|
+
</details>
|
|
480
|
+
|
|
481
|
+
<details>
|
|
482
|
+
<summary><b>...StGit / quilt / TopGit?</b></summary>
|
|
483
|
+
<br>
|
|
484
|
+
|
|
485
|
+
StGit(649 stars)管理补丁栈但没有 AI 集成、没有 MCP 服务器、没有 JSON 输出、没有冲突预测。quilt 完全在 git 体系之外运作 — 没有 rerere,没有历史。TopGit 基本已经废弃。它们都不是为 AI 代理时代设计的。
|
|
486
|
+
</details>
|
|
487
|
+
|
|
488
|
+
## 与其他方案对比
|
|
489
|
+
|
|
490
|
+
| | **bingo-light** | GitHub Sync | git rebase | quilt | StGit |
|
|
491
|
+
|---|:---:|:---:|:---:|:---:|:---:|
|
|
492
|
+
| 命名补丁栈 | **有** | 无 | 无 | 有 | 有 |
|
|
493
|
+
| 一键同步 | **有** | 仅按钮 | 无(6 步) | 无 | 无 |
|
|
494
|
+
| 处理定制化改动 | **有** | **不行** | 手动 | 手动 | 手动 |
|
|
495
|
+
| 冲突记忆 (rerere) | **自动** | 无 | 需手动启用 | 无 | 无 |
|
|
496
|
+
| 冲突预测 | **有** | 无 | 无 | 无 | 无 |
|
|
497
|
+
| AI/MCP 集成 | **29 个工具** | 无 | 无 | 无 | 无 |
|
|
498
|
+
| JSON 输出 | **所有命令** | 无 | 无 | 无 | 无 |
|
|
499
|
+
| 非交互模式 | **原生支持** | 无 | 部分 | 部分 | 部分 |
|
|
500
|
+
| 撤销同步 | **一条命令** | 无 | git reflog | 手动 | 手动 |
|
|
501
|
+
| 安装方式 | 一条命令 | 内置 | 内置 | 包管理器 | 包管理器 |
|
|
502
|
+
|
|
503
|
+
## 项目生态
|
|
504
|
+
|
|
505
|
+
```
|
|
506
|
+
bingo-light CLI 入口(Python 3,零依赖)
|
|
507
|
+
bingo_core/ 核心库包(全部业务逻辑)
|
|
508
|
+
mcp-server.py MCP 服务器(零依赖 Python 3,29 个工具)
|
|
509
|
+
contrib/agent.py Advisor 代理(监控 + 分析 + 安全时自动同步)
|
|
510
|
+
contrib/tui.py 终端面板(curses TUI)
|
|
511
|
+
install.sh 安装器(--yes 支持 CI,--help 查看选项)
|
|
512
|
+
completions/ Shell 补全(bash/zsh/fish)
|
|
513
|
+
contrib/hooks/ 通知 Hook 示例(Slack/Discord/Webhook)
|
|
514
|
+
tests/ 测试套件(250 个测试,5 个文件)
|
|
515
|
+
docs/ 文档
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## 参与贡献
|
|
519
|
+
|
|
520
|
+
欢迎贡献。纯 Python,零依赖,不需要构建。
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
git clone https://github.com/DanOps-1/bingo-light.git
|
|
524
|
+
cd bingo-light
|
|
525
|
+
make test # 核心测试
|
|
526
|
+
make test-all # 全部 250 个测试
|
|
527
|
+
make lint # Python 语法 + flake8 + shellcheck
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
详见 [CONTRIBUTING.md](CONTRIBUTING.md)。
|
|
531
|
+
|
|
532
|
+
## 许可证
|
|
533
|
+
|
|
534
|
+
[MIT](LICENSE)
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// bingo-light CLI wrapper for npm distribution.
|
|
3
|
+
// Finds python3 and runs the bundled bingo-light script.
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const { execFileSync } = require("child_process");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
|
|
10
|
+
const script = path.join(__dirname, "..", "bingo-light");
|
|
11
|
+
|
|
12
|
+
// Find python3
|
|
13
|
+
const pythons = ["python3", "python"];
|
|
14
|
+
let python = null;
|
|
15
|
+
|
|
16
|
+
for (const cmd of pythons) {
|
|
17
|
+
try {
|
|
18
|
+
const ver = execFileSync(cmd, ["--version"], {
|
|
19
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
20
|
+
}).toString().trim();
|
|
21
|
+
const match = ver.match(/(\d+)\.(\d+)/);
|
|
22
|
+
if (match && (parseInt(match[1]) > 3 || (parseInt(match[1]) === 3 && parseInt(match[2]) >= 8))) {
|
|
23
|
+
python = cmd;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
} catch (_) {
|
|
27
|
+
// not found, try next
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!python) {
|
|
32
|
+
process.stderr.write(
|
|
33
|
+
"error: Python 3.8+ is required but not found.\n" +
|
|
34
|
+
"Install Python from https://python.org and try again.\n"
|
|
35
|
+
);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const result = execFileSync(python, [script, ...process.argv.slice(2)], {
|
|
41
|
+
stdio: "inherit",
|
|
42
|
+
env: process.env,
|
|
43
|
+
});
|
|
44
|
+
} catch (e) {
|
|
45
|
+
process.exit(e.status || 1);
|
|
46
|
+
}
|
package/bin/mcp.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// bingo-light MCP server wrapper for npm distribution.
|
|
3
|
+
// Used by MCP clients: {"command": "npx", "args": ["-y", "bingo-light", "mcp"]}
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const { execFileSync } = require("child_process");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
|
|
10
|
+
const script = path.join(__dirname, "..", "mcp-server.py");
|
|
11
|
+
|
|
12
|
+
const pythons = ["python3", "python"];
|
|
13
|
+
let python = null;
|
|
14
|
+
|
|
15
|
+
for (const cmd of pythons) {
|
|
16
|
+
try {
|
|
17
|
+
const ver = execFileSync(cmd, ["--version"], {
|
|
18
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
19
|
+
}).toString().trim();
|
|
20
|
+
const match = ver.match(/(\d+)\.(\d+)/);
|
|
21
|
+
if (match && (parseInt(match[1]) > 3 || (parseInt(match[1]) === 3 && parseInt(match[2]) >= 8))) {
|
|
22
|
+
python = cmd;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
} catch (_) {
|
|
26
|
+
// not found, try next
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!python) {
|
|
31
|
+
process.stderr.write(
|
|
32
|
+
"error: Python 3.8+ is required but not found.\n" +
|
|
33
|
+
"Install Python from https://python.org and try again.\n"
|
|
34
|
+
);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
execFileSync(python, [script, ...process.argv.slice(2)], {
|
|
40
|
+
stdio: "inherit",
|
|
41
|
+
env: process.env,
|
|
42
|
+
});
|
|
43
|
+
} catch (e) {
|
|
44
|
+
process.exit(e.status || 1);
|
|
45
|
+
}
|