synapse-hub 2.7.0 → 3.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.
Files changed (108) hide show
  1. package/.agents/agents/live-explorer.md +2 -0
  2. package/.agents/agents/pom-crafter.md +2 -0
  3. package/.agents/agents/test-runner.md +3 -0
  4. package/.agents/skills/lean-impact-scoreboard/SKILL.md +1 -1
  5. package/.agents/skills/repo-quality-audit/SKILL.md +1 -1
  6. package/.agents/skills/review-spec/SKILL.md +1 -1
  7. package/.agents/skills/senior-code-review/SKILL.md +1 -1
  8. package/.agents/skills/technical-debt-harvester/SKILL.md +1 -1
  9. package/CLAUDE.md +1 -1
  10. package/README.en.md +70 -291
  11. package/README.md +68 -303
  12. package/docs/ARCHITECTURE.md +48 -2
  13. package/docs/CONTRIBUTING.md +1 -1
  14. package/docs/QUALITY_GATES.md +113 -0
  15. package/package.json +1 -1
  16. package/scripts/package_dist.py +2 -1
  17. package/skills_manifest.json +6 -6
  18. package/synapse.config.json +1 -1
  19. package/templates/ai_bridges/CLAUDE.md +1 -1
  20. package/templates/ai_bridges/copilot-instructions.md +2 -2
  21. package/tools/__init__.py +18 -1
  22. package/tools/_openapi_parser.py +1 -1
  23. package/tools/agent_canary.py +42 -30
  24. package/tools/agentless_patcher.py +2 -2
  25. package/tools/analyze_project.py +3 -5
  26. package/tools/api_drift_sentinel.py +4 -4
  27. package/tools/api_fuzzer.py +8 -8
  28. package/tools/auto_heal.py +4 -5
  29. package/tools/auto_heal_reflexion.py +2 -2
  30. package/tools/autogen_qa_broker.py +2 -2
  31. package/tools/browser_helpers.js +2 -2
  32. package/tools/browsergym_eval.py +2 -3
  33. package/tools/bug_reporter.py +11 -13
  34. package/tools/bump_version.py +75 -5
  35. package/tools/cache_resolver.py +78 -83
  36. package/tools/check_env.py +9 -1
  37. package/tools/check_version_sync.py +40 -3
  38. package/tools/ci_healing_hook.py +4 -6
  39. package/tools/cli.py +5 -7
  40. package/tools/config_decoupler.py +2 -3
  41. package/tools/core/__init__.py +52 -0
  42. package/tools/count_tokens.py +22 -20
  43. package/tools/dashboard_generator.py +627 -998
  44. package/tools/db_sandbox.py +65 -53
  45. package/tools/debt_harvester.py +3 -3
  46. package/tools/distill_log.py +3 -3
  47. package/tools/dspy_qa_signatures.py +3 -4
  48. package/tools/export_postman_collection.py +8 -8
  49. package/tools/flaky_detector.py +2 -2
  50. package/tools/fuzz_payloads.py +5 -5
  51. package/tools/generate_allure_report.py +1 -1
  52. package/tools/generate_jmx_plan.py +4 -4
  53. package/tools/gherkin_suite.py +1 -1
  54. package/tools/git_pre_commit_guard.py +2 -2
  55. package/tools/goldfish_review.py +2 -2
  56. package/tools/heal/__init__.py +28 -0
  57. package/tools/heal_pr_automator.py +6 -6
  58. package/tools/heuristic_locator_matcher.py +2 -2
  59. package/tools/infer_linter.py +8 -8
  60. package/tools/interview_story.py +0 -1
  61. package/tools/jtl_analyzer.py +11 -11
  62. package/tools/lint/__init__.py +30 -0
  63. package/tools/lint_ai_docs.py +42 -0
  64. package/tools/lookup_tc.py +1 -1
  65. package/tools/matrix_sharder.py +15 -13
  66. package/tools/mcp/__init__.py +16 -0
  67. package/tools/mcp_excel_server.py +2 -2
  68. package/tools/mcp_server.py +3 -4
  69. package/tools/md_to_xlsx.py +26 -26
  70. package/tools/micro_mutator.py +11 -12
  71. package/tools/network_mock_shield.py +27 -27
  72. package/tools/newman_analyzer.py +2 -3
  73. package/tools/omni_emitter.py +5 -8
  74. package/tools/omni_parser.py +5 -5
  75. package/tools/omni_transpiler.py +5 -5
  76. package/tools/output_formatter.py +19 -0
  77. package/tools/perf/__init__.py +24 -0
  78. package/tools/pinpoint_failure.py +1 -1
  79. package/tools/project_state.py +0 -2
  80. package/tools/qa_event_stream.py +1 -1
  81. package/tools/repo_map.py +8 -8
  82. package/tools/report/__init__.py +32 -0
  83. package/tools/reversible_sandbox.py +1 -2
  84. package/tools/safety_firewall.py +2 -2
  85. package/tools/senior_code_review.py +2 -2
  86. package/tools/setup_project.py +10 -12
  87. package/tools/skill_collision_guard.py +3 -3
  88. package/tools/skill_vault.py +12 -3
  89. package/tools/skillspector.py +5 -7
  90. package/tools/smart_visual_masker.py +4 -6
  91. package/tools/spec_drift_sentinel.py +1 -2
  92. package/tools/swe_qa_aci.py +2 -2
  93. package/tools/synapse_qa_bench.py +3 -3
  94. package/tools/sync_agent_rules.py +17 -3
  95. package/tools/telemetry_correlator.py +3 -2
  96. package/tools/test_memory_os.py +15 -5
  97. package/tools/textgrad_mutation_optimizer.py +3 -3
  98. package/tools/tms_sync_bridge.py +5 -5
  99. package/tools/tot_exploratory_tester.py +5 -6
  100. package/tools/traffic_session_converter.py +9 -9
  101. package/tools/universal_ir.py +2 -3
  102. package/tools/update_sentinel.py +6 -9
  103. package/tools/verify_all.py +10 -0
  104. package/tools/visual_diff_canvas.py +1 -2
  105. package/tools/visual_som_helper.py +15 -13
  106. package/tools/watch_mode.py +1 -1
  107. package/tools/wcag_audit.py +22 -1
  108. package/tools/welcome_page.py +5 -6
@@ -10,10 +10,8 @@ When a test fails due to a broken locator:
10
10
  """
11
11
 
12
12
  import os
13
- import sys
14
- import json
15
13
  import argparse
16
- from typing import Dict, Any, Optional
14
+ from typing import Dict, Any
17
15
  from datetime import datetime
18
16
 
19
17
 
@@ -35,11 +33,11 @@ class CIHealingHook:
35
33
  """
36
34
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
37
35
  branch_name = f"auto-heal/{test_id.lower()}_{timestamp}"
38
-
36
+
39
37
  pr_description = f"""## 🤖 Autonomous CI/CD Self-Healing Report
40
38
 
41
- > **Target File:** `{file_path}`
42
- > **Confidence Score:** `{confidence * 100:.1f}%`
39
+ > **Target File:** `{file_path}`
40
+ > **Confidence Score:** `{confidence * 100:.1f}%`
43
41
  > **Timestamp:** `{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}`
44
42
 
45
43
  ### 📝 Summary of Changes
package/tools/cli.py CHANGED
@@ -41,7 +41,7 @@ RESET = "\033[0m"
41
41
  def cmd_version(args):
42
42
  """Displays the current hub version, skill catalog count, and license information."""
43
43
  manifest_path = os.path.join(REPO_ROOT, "skills_manifest.json")
44
- version = "2.7.0"
44
+ version = "3.0.0"
45
45
  if os.path.exists(manifest_path):
46
46
  try:
47
47
  import json
@@ -145,7 +145,7 @@ def cmd_clean(args):
145
145
  os.remove(os.path.join(root, f))
146
146
  removed_count += 1
147
147
  except OSError as err:
148
- failed_files = getattr(args, "verbose", False) and print(f"Notice: Could not remove {f}: {err}")
148
+ getattr(args, "verbose", False) and print(f"Notice: Could not remove {f}: {err}")
149
149
  print(f"✅ Cleanup finished: {removed_count} build artifacts and caches removed.")
150
150
 
151
151
 
@@ -255,7 +255,6 @@ def cmd_transpile(args):
255
255
  def cmd_omni_scan(args):
256
256
  from omni_transpiler import scan_repository
257
257
  inv = scan_repository(args.path)
258
- import json
259
258
  if getattr(args, "json", False):
260
259
  print(json.dumps(inv, indent=2))
261
260
  else:
@@ -542,21 +541,20 @@ def cmd_release(args):
542
541
 
543
542
  def _hub_version():
544
543
  manifest_path = os.path.join(REPO_ROOT, "skills_manifest.json")
545
- version = "2.7.0"
544
+ version = "3.0.0"
546
545
  if os.path.exists(manifest_path):
547
546
  try:
548
547
  import json
549
548
  with open(manifest_path, "r", encoding="utf-8") as f:
550
549
  version = json.load(f).get("version", version)
551
550
  except (OSError, json.JSONDecodeError):
552
- version = "2.7.0"
551
+ version = "3.0.0"
553
552
  return version
554
553
 
555
554
 
556
555
  class SynapseArgumentParser(argparse.ArgumentParser):
557
556
  """Enhanced ArgumentParser providing fuzzy Did-You-Mean suggestions on command typos."""
558
557
  def error(self, message):
559
- import difflib
560
558
  m = re.search(r"invalid choice: '([^']+)'", message)
561
559
  if m:
562
560
  bad_choice = m.group(1)
@@ -1008,7 +1006,7 @@ def main():
1008
1006
  import update_sentinel
1009
1007
  update_sentinel.check_for_updates(force=False, notify=True)
1010
1008
  except (ImportError, OSError, TimeoutError):
1011
- update_status = None
1009
+ _ = False
1012
1010
 
1013
1011
  # Dispatch subcommand
1014
1012
  args.func(args)
@@ -15,8 +15,7 @@ import re
15
15
  import sys
16
16
  import json
17
17
  import argparse
18
- from pathlib import Path
19
- from typing import Dict, List, Any, Tuple
18
+ from typing import Dict, List, Any, Tuple, Optional
20
19
 
21
20
  # Enforce UTF-8 stdout encoding for Windows console compatibility
22
21
  if hasattr(sys.stdout, 'reconfigure'):
@@ -129,7 +128,7 @@ class ConfigDecoupler:
129
128
  "replacement": f"process.env.{key}"
130
129
  })
131
130
 
132
- def export_configs(self, output_dir: str = None) -> Tuple[str, str]:
131
+ def export_configs(self, output_dir: Optional[str] = None) -> Tuple[str, str]:
133
132
  """Generates env.default.json and .env.example configuration files."""
134
133
  out_base = output_dir or os.path.join(self.target_dir, "config", "profiles")
135
134
  os.makedirs(out_base, exist_ok=True)
@@ -0,0 +1,52 @@
1
+ """
2
+ Synapse Hub — Core Execution Engines & Verification Sentinels (tools.core)
3
+ --------------------------------------------------------------------------
4
+ Domain package grouping all CLI routers, Definition-of-Done Quality Gate
5
+ orchestrators, AST scanners, and autonomous subagent execution bridges.
6
+ """
7
+
8
+ from tools import (
9
+ analyze_project,
10
+ bump_version,
11
+ check_env,
12
+ cli,
13
+ count_tokens,
14
+ debt_harvester,
15
+ distill_log,
16
+ micro_mutator,
17
+ project_state,
18
+ repo_map,
19
+ safety_firewall,
20
+ senior_code_review,
21
+ setup_project,
22
+ skill_vault,
23
+ sync_agent_rules,
24
+ test_impact,
25
+ test_memory_os,
26
+ universal_ir,
27
+ update_sentinel,
28
+ verify_all,
29
+ )
30
+
31
+ __all__ = [
32
+ "analyze_project",
33
+ "bump_version",
34
+ "check_env",
35
+ "cli",
36
+ "count_tokens",
37
+ "debt_harvester",
38
+ "distill_log",
39
+ "micro_mutator",
40
+ "project_state",
41
+ "repo_map",
42
+ "safety_firewall",
43
+ "senior_code_review",
44
+ "setup_project",
45
+ "skill_vault",
46
+ "sync_agent_rules",
47
+ "test_impact",
48
+ "test_memory_os",
49
+ "universal_ir",
50
+ "update_sentinel",
51
+ "verify_all",
52
+ ]
@@ -39,9 +39,9 @@ import hashlib
39
39
  import sqlite3
40
40
  import argparse
41
41
  from datetime import datetime, timezone, timedelta
42
- from typing import Dict, List, Any, Optional, Tuple
42
+ from typing import Dict, List, Any, Optional
43
43
 
44
- PRICING_TABLE = {
44
+ PRICING_TABLE: Dict[str, Dict[str, Any]] = {
45
45
  "gemini-flash": {
46
46
  "name": "Google Gemini 2.5/3.x Flash",
47
47
  "input_per_m": 0.075,
@@ -140,7 +140,7 @@ def get_budget_config() -> Dict[str, int]:
140
140
  "budget_7d": data.get("budget_7d", DEFAULT_7D_BUDGET),
141
141
  }
142
142
  except (OSError, json.JSONDecodeError):
143
- custom_budgets = None
143
+ _ = False
144
144
  return {
145
145
  "budget_5h": DEFAULT_5H_BUDGET,
146
146
  "budget_7d": DEFAULT_7D_BUDGET,
@@ -198,17 +198,19 @@ class AntigravityAdapter:
198
198
  if db_path:
199
199
  try:
200
200
  conn = sqlite3.connect(db_path)
201
- cursor = conn.cursor()
202
- cursor.execute("SELECT conversation_id, title, step_count, last_modified_time FROM conversation_summaries")
203
- for row in cursor.fetchall():
204
- title_map[row[0]] = {
205
- "title": row[1],
206
- "step_count": row[2],
207
- "last_modified": row[3],
208
- }
209
- conn.close()
201
+ try:
202
+ cursor = conn.cursor()
203
+ cursor.execute("SELECT conversation_id, title, step_count, last_modified_time FROM conversation_summaries")
204
+ for row in cursor.fetchall():
205
+ title_map[row[0]] = {
206
+ "title": row[1],
207
+ "step_count": row[2],
208
+ "last_modified": row[3],
209
+ }
210
+ finally:
211
+ conn.close()
210
212
  except (sqlite3.Error, OSError):
211
- conn_closed = True
213
+ _ = False
212
214
 
213
215
  conversations = []
214
216
  for entry in os.listdir(brain_dir):
@@ -240,7 +242,7 @@ class AntigravityAdapter:
240
242
  return {"error": f"Transcript not found at {transcript_path}"}
241
243
 
242
244
  turns = []
243
- current_turn = None
245
+ current_turn: Optional[Dict[str, Any]] = None
244
246
  total_input = 0
245
247
  total_cache = 0
246
248
  total_output = 0
@@ -388,7 +390,7 @@ class AntigravityAdapter:
388
390
  usage_hours["cache"] += cache_tok
389
391
  usage_hours["output"] += out_tok
390
392
  except (OSError, UnicodeDecodeError):
391
- transcript_read = False
393
+ _ = False
392
394
 
393
395
  budgets = get_budget_config()
394
396
  b_5h = budgets["budget_5h"]
@@ -452,7 +454,7 @@ class CursorAdapter:
452
454
  return []
453
455
 
454
456
  pattern = os.path.join(projects_dir, "*", "agent-transcripts", "*", "*.jsonl")
455
- sessions = []
457
+ sessions: List[Dict[str, Any]] = []
456
458
  for fpath in glob.glob(pattern):
457
459
  try:
458
460
  mtime = os.path.getmtime(fpath)
@@ -493,7 +495,7 @@ class CursorAdapter:
493
495
  return {"error": f"Transcript not found at {transcript_path}"}
494
496
 
495
497
  turns = []
496
- current_turn = None
498
+ current_turn: Optional[Dict[str, Any]] = None
497
499
  total_input = 0
498
500
  total_output = 0
499
501
  total_cache = 0
@@ -608,7 +610,7 @@ class ClaudeCodeAdapter:
608
610
 
609
611
  @classmethod
610
612
  def get_sessions(cls) -> List[Dict[str, Any]]:
611
- sessions = []
613
+ sessions: List[Dict[str, Any]] = []
612
614
  home = os.path.expanduser("~")
613
615
  # Search candidate directories
614
616
  patterns = [
@@ -665,7 +667,7 @@ def detect_platform_from_file(file_path: str) -> str:
665
667
  if "claude" in line.lower():
666
668
  return "claude"
667
669
  except (OSError, UnicodeDecodeError):
668
- model_detected = None
670
+ _ = False
669
671
  return "antigravity"
670
672
 
671
673
 
@@ -997,7 +999,7 @@ def export_opentelemetry_genai_spans(parsed: Dict[str, Any], session_id: str = "
997
999
  }
998
1000
  gen_ai_system = system_map.get(platform, "google")
999
1001
 
1000
- spans = []
1002
+ spans: List[Dict[str, Any]] = []
1001
1003
  turns = parsed.get("turns", [])
1002
1004
  for idx, turn in enumerate(turns, 1):
1003
1005
  turn_span_id = hashlib.md5(f"{session_id}_turn_{idx}".encode('utf-8'), usedforsecurity=False).hexdigest()[:16]