bingo-light 2.1.2 → 2.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/README.en.md +17 -7
- package/README.md +30 -4
- package/bingo-light +321 -11
- package/bingo_core/__init__.py +9 -1
- package/bingo_core/decisions.py +167 -0
- package/bingo_core/dep.py +385 -25
- package/bingo_core/dep_fork.py +268 -0
- package/bingo_core/models.py +1 -0
- package/bingo_core/repo.py +1031 -9
- package/bingo_core/semantic.py +85 -0
- package/bingo_core/state.py +1 -1
- package/bingo_core/team.py +170 -0
- package/completions/bingo-light.bash +14 -4
- package/completions/bingo-light.fish +23 -2
- package/completions/bingo-light.zsh +18 -2
- package/mcp-server.py +245 -7
- package/package.json +1 -1
package/mcp-server.py
CHANGED
|
@@ -231,7 +231,7 @@ TOOLS = [
|
|
|
231
231
|
"name": "bingo_doctor",
|
|
232
232
|
"description": (
|
|
233
233
|
"Diagnose setup issues: checks git version, rerere, upstream remote, branch structure, "
|
|
234
|
-
"and tests whether patches apply cleanly on latest upstream."
|
|
234
|
+
"and tests whether patches apply cleanly on latest upstream. Use report=true for extended checks."
|
|
235
235
|
),
|
|
236
236
|
"inputSchema": {
|
|
237
237
|
"type": "object",
|
|
@@ -239,6 +239,10 @@ TOOLS = [
|
|
|
239
239
|
"cwd": {
|
|
240
240
|
"type": "string",
|
|
241
241
|
"description": "Path to the git repository"
|
|
242
|
+
},
|
|
243
|
+
"report": {
|
|
244
|
+
"type": "boolean",
|
|
245
|
+
"description": "Include extended checks (team locks, expiry, deps)"
|
|
242
246
|
}
|
|
243
247
|
},
|
|
244
248
|
"required": ["cwd"]
|
|
@@ -283,9 +287,14 @@ TOOLS = [
|
|
|
283
287
|
{
|
|
284
288
|
"name": "bingo_conflict_analyze",
|
|
285
289
|
"description": (
|
|
286
|
-
"Analyze current rebase conflicts. Returns structured info about each conflicted file
|
|
287
|
-
"
|
|
288
|
-
"
|
|
290
|
+
"Analyze current rebase conflicts. Returns structured info about each conflicted file "
|
|
291
|
+
"(ours/theirs, conflict count, hints, semantic_class: whitespace/import_reorder/"
|
|
292
|
+
"signature_change/logic) plus: patch_intent (name, subject, full commit message, "
|
|
293
|
+
"original_sha, original_diff, meta, stack_position), verify (test_command + per-file "
|
|
294
|
+
"syntax/parse commands), upstream_context (upstream commits touching conflicts with "
|
|
295
|
+
"author/PR), patch_dependencies (later patches touching same files — cascade risk), "
|
|
296
|
+
"and decision_memory (prior resolutions for this patch from .bingo/decisions/). "
|
|
297
|
+
"Call this when bingo_sync reports a conflict."
|
|
289
298
|
),
|
|
290
299
|
"inputSchema": {
|
|
291
300
|
"type": "object",
|
|
@@ -302,7 +311,9 @@ TOOLS = [
|
|
|
302
311
|
"name": "bingo_conflict_resolve",
|
|
303
312
|
"description": (
|
|
304
313
|
"Resolve a conflict during rebase by writing the resolved content to a file, "
|
|
305
|
-
"staging it, and continuing the rebase. Use after bingo_conflict_analyze."
|
|
314
|
+
"staging it, and continuing the rebase. Use after bingo_conflict_analyze. "
|
|
315
|
+
"Set verify=true to run test.command after the final rebase --continue; "
|
|
316
|
+
"the result is attached as verify_result."
|
|
306
317
|
),
|
|
307
318
|
"inputSchema": {
|
|
308
319
|
"type": "object",
|
|
@@ -318,6 +329,10 @@ TOOLS = [
|
|
|
318
329
|
"content": {
|
|
319
330
|
"type": "string",
|
|
320
331
|
"description": "The fully resolved file content (no conflict markers)"
|
|
332
|
+
},
|
|
333
|
+
"verify": {
|
|
334
|
+
"type": "boolean",
|
|
335
|
+
"description": "If true, run test.command after the final rebase --continue. Default false."
|
|
321
336
|
}
|
|
322
337
|
},
|
|
323
338
|
"required": ["cwd", "file", "content"]
|
|
@@ -549,6 +564,176 @@ TOOLS = [
|
|
|
549
564
|
"required": ["cwd", "package"]
|
|
550
565
|
}
|
|
551
566
|
},
|
|
567
|
+
# ── Team / Locking tools ────────────────────────────────────────────
|
|
568
|
+
{
|
|
569
|
+
"name": "bingo_patch_lock",
|
|
570
|
+
"description": "Lock a patch for exclusive editing. Prevents other team members from editing or dropping it.",
|
|
571
|
+
"inputSchema": {
|
|
572
|
+
"type": "object",
|
|
573
|
+
"properties": {
|
|
574
|
+
"cwd": {"type": "string", "description": "Path to the git repository"},
|
|
575
|
+
"name": {"type": "string", "description": "Patch name to lock"},
|
|
576
|
+
"reason": {"type": "string", "description": "Why you are locking this patch"}
|
|
577
|
+
},
|
|
578
|
+
"required": ["cwd", "name"]
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"name": "bingo_patch_unlock",
|
|
583
|
+
"description": "Unlock a patch, allowing other team members to edit or drop it.",
|
|
584
|
+
"inputSchema": {
|
|
585
|
+
"type": "object",
|
|
586
|
+
"properties": {
|
|
587
|
+
"cwd": {"type": "string", "description": "Path to the git repository"},
|
|
588
|
+
"name": {"type": "string", "description": "Patch name to unlock"},
|
|
589
|
+
"force": {"type": "boolean", "description": "Force unlock even if locked by someone else"}
|
|
590
|
+
},
|
|
591
|
+
"required": ["cwd", "name"]
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
# ── Smart Patch Management tools ────────────────────────────────────
|
|
595
|
+
{
|
|
596
|
+
"name": "bingo_patch_check",
|
|
597
|
+
"description": "Check if patches are still needed. Detects if upstream has merged equivalent changes, making a patch obsolete.",
|
|
598
|
+
"inputSchema": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": {
|
|
601
|
+
"cwd": {"type": "string", "description": "Path to the git repository"},
|
|
602
|
+
"name": {"type": "string", "description": "Patch name to check (omit for all patches)"}
|
|
603
|
+
},
|
|
604
|
+
"required": ["cwd"]
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"name": "bingo_patch_upstream",
|
|
609
|
+
"description": "Export a patch as a clean PR-ready diff suitable for submitting to the upstream repository.",
|
|
610
|
+
"inputSchema": {
|
|
611
|
+
"type": "object",
|
|
612
|
+
"properties": {
|
|
613
|
+
"cwd": {"type": "string", "description": "Path to the git repository"},
|
|
614
|
+
"name": {"type": "string", "description": "Patch name to export"}
|
|
615
|
+
},
|
|
616
|
+
"required": ["cwd", "name"]
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"name": "bingo_patch_expire",
|
|
621
|
+
"description": "List patches that have passed their expiry date or are expiring soon (within 7 days).",
|
|
622
|
+
"inputSchema": {
|
|
623
|
+
"type": "object",
|
|
624
|
+
"properties": {
|
|
625
|
+
"cwd": {"type": "string", "description": "Path to the git repository"}
|
|
626
|
+
},
|
|
627
|
+
"required": ["cwd"]
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"name": "bingo_patch_stats",
|
|
632
|
+
"description": "Get health metrics for all patches: age, size, conflict frequency.",
|
|
633
|
+
"inputSchema": {
|
|
634
|
+
"type": "object",
|
|
635
|
+
"properties": {
|
|
636
|
+
"cwd": {"type": "string", "description": "Path to the git repository"}
|
|
637
|
+
},
|
|
638
|
+
"required": ["cwd"]
|
|
639
|
+
}
|
|
640
|
+
},
|
|
641
|
+
# ── Report tool ─────────────────────────────────────────────────────
|
|
642
|
+
{
|
|
643
|
+
"name": "bingo_report",
|
|
644
|
+
"description": "Generate a comprehensive markdown health report covering patches, sync status, team locks, expiry, and dependencies.",
|
|
645
|
+
"inputSchema": {
|
|
646
|
+
"type": "object",
|
|
647
|
+
"properties": {
|
|
648
|
+
"cwd": {"type": "string", "description": "Path to the git repository"}
|
|
649
|
+
},
|
|
650
|
+
"required": ["cwd"]
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
# ── npm Override Management tools ───────────────────────────────────
|
|
654
|
+
{
|
|
655
|
+
"name": "bingo_dep_override_list",
|
|
656
|
+
"description": "List all npm overrides/yarn resolutions with tracked reasons.",
|
|
657
|
+
"inputSchema": {
|
|
658
|
+
"type": "object",
|
|
659
|
+
"properties": {
|
|
660
|
+
"cwd": {"type": "string", "description": "Project directory"}
|
|
661
|
+
},
|
|
662
|
+
"required": ["cwd"]
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"name": "bingo_dep_override_check",
|
|
667
|
+
"description": "Check if npm overrides are still needed by comparing against package-lock.json resolved versions.",
|
|
668
|
+
"inputSchema": {
|
|
669
|
+
"type": "object",
|
|
670
|
+
"properties": {
|
|
671
|
+
"cwd": {"type": "string", "description": "Project directory"}
|
|
672
|
+
},
|
|
673
|
+
"required": ["cwd"]
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"name": "bingo_dep_override_add",
|
|
678
|
+
"description": "Add an npm override to package.json with reason tracking.",
|
|
679
|
+
"inputSchema": {
|
|
680
|
+
"type": "object",
|
|
681
|
+
"properties": {
|
|
682
|
+
"cwd": {"type": "string", "description": "Project directory"},
|
|
683
|
+
"package": {"type": "string", "description": "Package to override"},
|
|
684
|
+
"version": {"type": "string", "description": "Version to force"},
|
|
685
|
+
"reason": {"type": "string", "description": "Why this override exists"}
|
|
686
|
+
},
|
|
687
|
+
"required": ["cwd", "package", "version"]
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"name": "bingo_dep_override_drop",
|
|
692
|
+
"description": "Remove an npm override from package.json and tracking.",
|
|
693
|
+
"inputSchema": {
|
|
694
|
+
"type": "object",
|
|
695
|
+
"properties": {
|
|
696
|
+
"cwd": {"type": "string", "description": "Project directory"},
|
|
697
|
+
"package": {"type": "string", "description": "Package to remove override for"}
|
|
698
|
+
},
|
|
699
|
+
"required": ["cwd", "package"]
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
# ── Fork-as-Dependency Tracking tools ───────────────────────────────
|
|
703
|
+
{
|
|
704
|
+
"name": "bingo_dep_fork_list",
|
|
705
|
+
"description": "List all git-based dependencies in package.json (github:user/repo, git+https://, etc.).",
|
|
706
|
+
"inputSchema": {
|
|
707
|
+
"type": "object",
|
|
708
|
+
"properties": {
|
|
709
|
+
"cwd": {"type": "string", "description": "Project directory"}
|
|
710
|
+
},
|
|
711
|
+
"required": ["cwd"]
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
"name": "bingo_dep_fork_check",
|
|
716
|
+
"description": "Check fork drift: compare git dependency refs against latest npm releases and GitHub commits.",
|
|
717
|
+
"inputSchema": {
|
|
718
|
+
"type": "object",
|
|
719
|
+
"properties": {
|
|
720
|
+
"cwd": {"type": "string", "description": "Project directory"}
|
|
721
|
+
},
|
|
722
|
+
"required": ["cwd"]
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
"name": "bingo_dep_fork_sync",
|
|
727
|
+
"description": "Update a fork dependency ref in package.json to the latest GitHub commit.",
|
|
728
|
+
"inputSchema": {
|
|
729
|
+
"type": "object",
|
|
730
|
+
"properties": {
|
|
731
|
+
"cwd": {"type": "string", "description": "Project directory"},
|
|
732
|
+
"package": {"type": "string", "description": "Package to update"}
|
|
733
|
+
},
|
|
734
|
+
"required": ["cwd", "package"]
|
|
735
|
+
}
|
|
736
|
+
},
|
|
552
737
|
]
|
|
553
738
|
|
|
554
739
|
# ─── Command Mapping ──────────────────────────────────────────────────────────
|
|
@@ -600,7 +785,7 @@ def handle_tool_call(name: str, arguments: dict) -> dict:
|
|
|
600
785
|
return _result(repo.undo())
|
|
601
786
|
|
|
602
787
|
elif name == "bingo_doctor":
|
|
603
|
-
return _result(repo.doctor())
|
|
788
|
+
return _result(repo.doctor(report=arguments.get("report", False)))
|
|
604
789
|
|
|
605
790
|
elif name == "bingo_diff":
|
|
606
791
|
return _result(repo.diff())
|
|
@@ -615,6 +800,7 @@ def handle_tool_call(name: str, arguments: dict) -> dict:
|
|
|
615
800
|
return _result(repo.conflict_resolve(
|
|
616
801
|
arguments.get("file", ""),
|
|
617
802
|
arguments.get("content", ""),
|
|
803
|
+
verify=bool(arguments.get("verify", False)),
|
|
618
804
|
))
|
|
619
805
|
|
|
620
806
|
elif name == "bingo_log":
|
|
@@ -709,6 +895,36 @@ def handle_tool_call(name: str, arguments: dict) -> dict:
|
|
|
709
895
|
elif name == "bingo_workspace_status":
|
|
710
896
|
return _result(repo.workspace_status())
|
|
711
897
|
|
|
898
|
+
# ── Team / Locking tools ──────────────────────────────────────────
|
|
899
|
+
elif name == "bingo_patch_lock":
|
|
900
|
+
return _result(repo.patch_lock(
|
|
901
|
+
arguments["name"],
|
|
902
|
+
reason=arguments.get("reason", ""),
|
|
903
|
+
))
|
|
904
|
+
|
|
905
|
+
elif name == "bingo_patch_unlock":
|
|
906
|
+
return _result(repo.patch_unlock(
|
|
907
|
+
arguments["name"],
|
|
908
|
+
force=arguments.get("force", False),
|
|
909
|
+
))
|
|
910
|
+
|
|
911
|
+
# ── Smart Patch Management tools ──────────────────────────────────
|
|
912
|
+
elif name == "bingo_patch_check":
|
|
913
|
+
return _result(repo.patch_check(arguments.get("name", "")))
|
|
914
|
+
|
|
915
|
+
elif name == "bingo_patch_upstream":
|
|
916
|
+
return _result(repo.patch_upstream(arguments["name"]))
|
|
917
|
+
|
|
918
|
+
elif name == "bingo_patch_expire":
|
|
919
|
+
return _result(repo.patch_expire())
|
|
920
|
+
|
|
921
|
+
elif name == "bingo_patch_stats":
|
|
922
|
+
return _result(repo.patch_stats())
|
|
923
|
+
|
|
924
|
+
# ── Report tool ───────────────────────────────────────────────────
|
|
925
|
+
elif name == "bingo_report":
|
|
926
|
+
return _result(repo.report())
|
|
927
|
+
|
|
712
928
|
# ── Dependency patching tools ────────────────────────────────────
|
|
713
929
|
elif name.startswith("bingo_dep_"):
|
|
714
930
|
from bingo_core.dep import DepManager
|
|
@@ -733,6 +949,28 @@ def handle_tool_call(name: str, arguments: dict) -> dict:
|
|
|
733
949
|
arguments["package"],
|
|
734
950
|
arguments.get("patch_name", ""),
|
|
735
951
|
))
|
|
952
|
+
# Override management
|
|
953
|
+
elif name == "bingo_dep_override_list":
|
|
954
|
+
return _result(dm.override_list())
|
|
955
|
+
elif name == "bingo_dep_override_check":
|
|
956
|
+
return _result(dm.override_check())
|
|
957
|
+
elif name == "bingo_dep_override_add":
|
|
958
|
+
return _result(dm.override_add(
|
|
959
|
+
arguments["package"], arguments["version"],
|
|
960
|
+
arguments.get("reason", ""),
|
|
961
|
+
))
|
|
962
|
+
elif name == "bingo_dep_override_drop":
|
|
963
|
+
return _result(dm.override_drop(arguments["package"]))
|
|
964
|
+
# Fork tracking
|
|
965
|
+
elif name.startswith("bingo_dep_fork_"):
|
|
966
|
+
from bingo_core.dep_fork import ForkTracker
|
|
967
|
+
ft = ForkTracker(cwd)
|
|
968
|
+
if name == "bingo_dep_fork_list":
|
|
969
|
+
return _result(ft.fork_list())
|
|
970
|
+
elif name == "bingo_dep_fork_check":
|
|
971
|
+
return _result(ft.fork_check())
|
|
972
|
+
elif name == "bingo_dep_fork_sync":
|
|
973
|
+
return _result(ft.fork_sync(arguments["package"]))
|
|
736
974
|
|
|
737
975
|
else:
|
|
738
976
|
return {
|
|
@@ -859,7 +1097,7 @@ def main():
|
|
|
859
1097
|
"capabilities": {"tools": {}},
|
|
860
1098
|
"serverInfo": {
|
|
861
1099
|
"name": "bingo-light",
|
|
862
|
-
"version": "2.
|
|
1100
|
+
"version": "2.2.0",
|
|
863
1101
|
},
|
|
864
1102
|
}))
|
|
865
1103
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bingo-light",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "AI-native fork maintenance — manage customizations as a clean patch stack on top of upstream",
|
|
5
5
|
"keywords": ["git", "fork", "patch", "mcp", "ai", "maintenance", "upstream", "rebase"],
|
|
6
6
|
"homepage": "https://github.com/DanOps-1/bingo-light",
|