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/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
- "the 'ours' version (upstream), 'theirs' version (your patch), conflict count, and resolution hints. "
288
- "Call this when bingo_sync reports a conflict to understand what needs fixing."
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.1.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.1.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",