synapse-hub 2.1.1 → 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.
Files changed (58) hide show
  1. package/.agents/agents/orchestrator.md +7 -0
  2. package/.agents/rules/lessons-learned.md +1 -0
  3. package/.agents/skills/agent-orchestration-multi-agent-optimize/SKILL.md +1 -1
  4. package/.agents/skills/antigravity-test-sentinel/SKILL.md +1 -2
  5. package/.agents/skills/api-network-mocking-interception/SKILL.md +1 -1
  6. package/.agents/skills/api-spec-to-e2e-matrix/SKILL.md +11 -4
  7. package/.agents/skills/architecture-decision-records/SKILL.md +1 -1
  8. package/.agents/skills/auth-session-and-cookie-manager/SKILL.md +1 -1
  9. package/.agents/skills/backend-load-and-stress-patterns/SKILL.md +32 -11
  10. package/.agents/skills/bats-testing-patterns/SKILL.md +1 -1
  11. package/.agents/skills/clean-pom-crafter/SKILL.md +1 -4
  12. package/.agents/skills/code-refactoring-refactor-clean/SKILL.md +1 -1
  13. package/.agents/skills/db-state-verifier-and-seeder/SKILL.md +1 -1
  14. package/.agents/skills/e2e-testing-patterns/SKILL.md +1 -1
  15. package/.agents/skills/failure-autopsy-and-healing/SKILL.md +1 -3
  16. package/.agents/skills/file-and-report-validator/SKILL.md +1 -1
  17. package/.agents/skills/flaky-test-sentinel-and-quarantine/SKILL.md +1 -1
  18. package/.agents/skills/github-actions-templates/SKILL.md +1 -1
  19. package/.agents/skills/graphify-impact-analyzer/SKILL.md +1 -3
  20. package/.agents/skills/katalon-cli-runner/SKILL.md +1 -1
  21. package/.agents/skills/lam-script-generator/SKILL.md +1 -2
  22. package/.agents/skills/playwright-live-interaction/SKILL.md +1 -4
  23. package/.agents/skills/security-dast-sentinel/SKILL.md +1 -1
  24. package/.agents/skills/self-healing-locator/SKILL.md +1 -2
  25. package/.agents/skills/skillspector-security-guard/SKILL.md +115 -0
  26. package/.agents/skills/synthetic-test-data-generator/SKILL.md +1 -1
  27. package/.agents/skills/token-and-context-optimizer/SKILL.md +1 -1
  28. package/.agents/skills/visual-regression-sentinel/SKILL.md +1 -1
  29. package/.agents/skills/wcag-audit-patterns/SKILL.md +1 -1
  30. package/.agents/skills/web-vitals-and-performance-profiler/SKILL.md +1 -1
  31. package/AGENTS.md +36 -0
  32. package/README.md +140 -103
  33. package/package.json +1 -1
  34. package/skills_manifest.json +42 -29
  35. package/templates/PROJECT_AI_GUIDE_TEMPLATE.md +15 -1
  36. package/templates/ai_bridges/CLAUDE.md +31 -0
  37. package/templates/ai_bridges/copilot-instructions.md +25 -0
  38. package/templates/ai_bridges/cursor_synapse_qa.mdc +26 -0
  39. package/templates/ai_bridges/windsurfrules +25 -0
  40. package/templates/ci/github-actions-synapse.yml +28 -0
  41. package/templates/ci/gitlab-ci-synapse.yml +16 -0
  42. package/tools/TOOLS_RUNBOOK.md +203 -12
  43. package/tools/browser_helpers.js +2 -2
  44. package/tools/bump_version.py +8 -0
  45. package/tools/cli.py +74 -2
  46. package/tools/export_postman_collection.py +535 -218
  47. package/tools/generate_jmx_plan.py +672 -102
  48. package/tools/git_pre_commit_guard.py +21 -0
  49. package/tools/jtl_analyzer.py +474 -0
  50. package/tools/mcp_excel_server.ps1 +1 -1
  51. package/tools/mcp_server.py +1 -1
  52. package/tools/newman_analyzer.py +385 -0
  53. package/tools/setup_project.py +203 -18
  54. package/tools/skillspector.py +1141 -0
  55. package/tools/telemetry_correlator.py +351 -0
  56. package/tools/templates/jmeter-distributed/README.md +54 -0
  57. package/tools/templates/jmeter-distributed/docker-compose.yml +83 -0
  58. package/tools/update_sentinel.py +313 -0
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Enterprise Synapse-Hub Auto-Update & Version Drift Sentinel
4
+ ------------------------------------------------------------
5
+ Provides non-blocking upstream version checks and 1-click self-updating
6
+ across Local Git Clones, Global Antigravity Plugins, and NPM installations.
7
+
8
+ Features:
9
+ 1. Non-blocking check against NPM Registry & GitHub (cached 24h, zero latency).
10
+ 2. Non-intrusive update banner on CLI invocations.
11
+ 3. 1-Click upgrade engine: `synapse-hub update` / `agent-qa update`.
12
+ """
13
+
14
+ import os
15
+ import sys
16
+ import json
17
+ import time
18
+ import urllib.request
19
+ import subprocess
20
+ from datetime import datetime
21
+
22
+ # Enforce UTF-8 stdout encoding for Windows console compatibility
23
+ if hasattr(sys.stdout, 'reconfigure'):
24
+ try:
25
+ sys.stdout.reconfigure(encoding='utf-8')
26
+ sys.stderr.reconfigure(encoding='utf-8')
27
+ except Exception:
28
+ pass
29
+
30
+ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
31
+ HUB_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
32
+ GLOBAL_DIR = os.path.expanduser("~/.agent_memory")
33
+ CACHE_FILE = os.path.join(GLOBAL_DIR, "update_cache.json")
34
+ GLOBAL_PLUGIN_DIR = os.path.expanduser("~/.gemini/config/plugins/synapse-hub")
35
+
36
+ CHECK_INTERVAL_SECONDS = 86400 # 24 Hours
37
+
38
+ # ANSI Formatting
39
+ CYAN = "\033[96m"
40
+ GREEN = "\033[92m"
41
+ YELLOW = "\033[93m"
42
+ RED = "\033[91m"
43
+ BOLD = "\033[1m"
44
+ RESET = "\033[0m"
45
+
46
+
47
+ def parse_semver(ver_str):
48
+ """Parses a version string into a numeric tuple for comparison."""
49
+ clean = ver_str.strip().lstrip("v")
50
+ parts = []
51
+ for p in clean.split("."):
52
+ try:
53
+ parts.append(int(p))
54
+ except ValueError:
55
+ parts.append(0)
56
+ while len(parts) < 3:
57
+ parts.append(0)
58
+ return tuple(parts[:3])
59
+
60
+
61
+ def get_local_version():
62
+ """Reads the local version from package.json or skills_manifest.json."""
63
+ pkg_file = os.path.join(HUB_ROOT, "package.json")
64
+ if os.path.exists(pkg_file):
65
+ try:
66
+ with open(pkg_file, "r", encoding="utf-8") as f:
67
+ data = json.load(f)
68
+ return data.get("version", "2.1.1")
69
+ except Exception:
70
+ pass
71
+
72
+ manifest_file = os.path.join(HUB_ROOT, "skills_manifest.json")
73
+ if os.path.exists(manifest_file):
74
+ try:
75
+ with open(manifest_file, "r", encoding="utf-8") as f:
76
+ data = json.load(f)
77
+ return data.get("version", "2.1.1")
78
+ except Exception:
79
+ pass
80
+
81
+ return "2.1.1"
82
+
83
+
84
+ def fetch_remote_version():
85
+ """Queries NPM registry or GitHub raw for the latest published version."""
86
+ headers = {"User-Agent": "synapse-hub-update-sentinel"}
87
+
88
+ # 1. Primary: NPM Registry
89
+ try:
90
+ req = urllib.request.Request("https://registry.npmjs.org/synapse-hub/latest", headers=headers)
91
+ with urllib.request.urlopen(req, timeout=1.8) as resp:
92
+ data = json.loads(resp.read().decode("utf-8"))
93
+ if "version" in data:
94
+ return data["version"], "npm"
95
+ except Exception:
96
+ pass
97
+
98
+ # 2. Secondary fallback: GitHub raw package.json
99
+ try:
100
+ raw_url = "https://raw.githubusercontent.com/TeeVee998/Synapse-Hub/main/package.json"
101
+ req = urllib.request.Request(raw_url, headers=headers)
102
+ with urllib.request.urlopen(req, timeout=1.8) as resp:
103
+ data = json.loads(resp.read().decode("utf-8"))
104
+ if "version" in data:
105
+ return data["version"], "github"
106
+ except Exception:
107
+ pass
108
+
109
+ return None, None
110
+
111
+
112
+ def read_update_cache():
113
+ if os.path.exists(CACHE_FILE):
114
+ try:
115
+ with open(CACHE_FILE, "r", encoding="utf-8") as f:
116
+ return json.load(f)
117
+ except Exception:
118
+ pass
119
+ return {}
120
+
121
+
122
+ def write_update_cache(data):
123
+ try:
124
+ os.makedirs(GLOBAL_DIR, exist_ok=True)
125
+ with open(CACHE_FILE, "w", encoding="utf-8") as f:
126
+ json.dump(data, f, indent=2)
127
+ except Exception:
128
+ pass
129
+
130
+
131
+ def check_for_updates(force=False, notify=True):
132
+ """
133
+ Checks if a newer version exists upstream.
134
+ Uses a 24-hour file cache to prevent network overhead during daily workflows.
135
+ """
136
+ cache = read_update_cache()
137
+ now = time.time()
138
+ last_check = cache.get("last_check_timestamp", 0)
139
+
140
+ local_ver = get_local_version()
141
+ remote_ver = cache.get("latest_remote_version")
142
+
143
+ # Only fetch if cache is stale or forced
144
+ if force or (now - last_check > CHECK_INTERVAL_SECONDS) or not remote_ver:
145
+ fetched_ver, source = fetch_remote_version()
146
+ if fetched_ver:
147
+ remote_ver = fetched_ver
148
+ cache["latest_remote_version"] = fetched_ver
149
+ cache["source"] = source
150
+ cache["last_check_timestamp"] = now
151
+ cache["last_check_date"] = datetime.now().isoformat()
152
+ write_update_cache(cache)
153
+ elif not remote_ver:
154
+ return False, local_ver, None
155
+
156
+ if remote_ver:
157
+ is_newer = parse_semver(remote_ver) > parse_semver(local_ver)
158
+ if is_newer and notify:
159
+ print_update_banner(local_ver, remote_ver)
160
+ return is_newer, local_ver, remote_ver
161
+
162
+ return False, local_ver, None
163
+
164
+
165
+ def print_update_banner(local_ver, remote_ver):
166
+ """Prints a clean ASCII alert banner when an update is available."""
167
+ banner = f"""
168
+ {CYAN}┌────────────────────────────────────────────────────────────────────────┐
169
+ │ {BOLD}🚀 Synapse-Hub Update Available: {YELLOW}{local_ver}{RESET}{CYAN} → {GREEN}{BOLD}v{remote_ver}{RESET}{CYAN} │
170
+ │ │
171
+ │ To upgrade your local hub, run: │
172
+ │ 👉 {BOLD}agent-qa update{RESET}{CYAN} or {BOLD}npx synapse-hub update{RESET}{CYAN} │
173
+ │ │
174
+ │ Repository: {BOLD}https://github.com/TeeVee998/Synapse-Hub{RESET}{CYAN} │
175
+ └────────────────────────────────────────────────────────────────────────┘{RESET}
176
+ """
177
+ print(banner)
178
+
179
+
180
+ def perform_update():
181
+ """
182
+ Executes 1-click update:
183
+ 1. If inside a git repository (local clone or global plugin): pulls latest changes.
184
+ 2. Synchronizes SQLite central memory.
185
+ 3. Re-runs DoD Quality Gates to guarantee integrity.
186
+ """
187
+ print(f"\n{BOLD}{CYAN}======================================================================{RESET}")
188
+ print(f"{BOLD}{CYAN} SYNAPSE-HUB: 1-CLICK AUTOMATED UPDATE ENGINE {RESET}")
189
+ print(f"{BOLD}{CYAN}======================================================================{RESET}")
190
+
191
+ local_ver = get_local_version()
192
+ print(f"📦 Current Hub Version: {BOLD}v{local_ver}{RESET}")
193
+ print("🔍 Checking upstream for latest releases...")
194
+
195
+ has_update, local_ver, remote_ver = check_for_updates(force=True, notify=False)
196
+ if remote_ver:
197
+ print(f"🌐 Latest Upstream Version: {BOLD}{GREEN}v{remote_ver}{RESET}")
198
+ else:
199
+ print("⚠️ Could not reach upstream registry (offline or network timeout).")
200
+
201
+ # Detect if repo is a git clone
202
+ git_dir = os.path.join(HUB_ROOT, ".git")
203
+ is_git_repo = os.path.exists(git_dir)
204
+
205
+ updated = False
206
+
207
+ if is_git_repo:
208
+ print(f"\n{BOLD}[1/3] Pulling latest updates via Git...{RESET}")
209
+ try:
210
+ res = subprocess.run(
211
+ ["git", "pull", "--ff-only"],
212
+ cwd=HUB_ROOT,
213
+ stdout=subprocess.PIPE,
214
+ stderr=subprocess.PIPE,
215
+ text=True
216
+ )
217
+ if res.returncode == 0:
218
+ print(f" {GREEN}[OK] Git pull successful:{RESET}")
219
+ for line in res.stdout.strip().splitlines():
220
+ print(f" {line}")
221
+ updated = True
222
+ else:
223
+ print(f" ⚠️ Git pull notice: {res.stderr.strip() or res.stdout.strip()}")
224
+ except Exception as e:
225
+ print(f" ⚠️ Could not execute git pull: {e}")
226
+ else:
227
+ print(f"\n{BOLD}[1/3] Checking NPM package installation...{RESET}")
228
+ try:
229
+ res = subprocess.run(
230
+ ["npm", "install", "-g", "synapse-hub@latest"],
231
+ stdout=subprocess.PIPE,
232
+ stderr=subprocess.PIPE,
233
+ text=True
234
+ )
235
+ if res.returncode == 0:
236
+ print(f" {GREEN}[OK] Global NPM package updated to latest!{RESET}")
237
+ updated = True
238
+ except Exception:
239
+ pass
240
+
241
+ # 2. Check Global Plugin
242
+ if os.path.exists(GLOBAL_PLUGIN_DIR) and GLOBAL_PLUGIN_DIR.lower() != HUB_ROOT.lower():
243
+ print(f"\n{BOLD}[2/3] Synchronizing Global Antigravity Plugin...{RESET}")
244
+ plugin_git = os.path.join(GLOBAL_PLUGIN_DIR, ".git")
245
+ if os.path.exists(plugin_git):
246
+ try:
247
+ subprocess.run(["git", "pull", "--ff-only"], cwd=GLOBAL_PLUGIN_DIR, stdout=subprocess.DEVNULL)
248
+ print(f" {GREEN}[OK] Updated Global Plugin repository: {GLOBAL_PLUGIN_DIR}{RESET}")
249
+ except Exception:
250
+ pass
251
+ else:
252
+ # Refresh plugin.json in global plugin
253
+ try:
254
+ import shutil
255
+ src_pkg = os.path.join(HUB_ROOT, "plugin.json")
256
+ dst_pkg = os.path.join(GLOBAL_PLUGIN_DIR, "plugin.json")
257
+ if os.path.exists(src_pkg):
258
+ shutil.copy2(src_pkg, dst_pkg)
259
+ print(f" {GREEN}[OK] Refreshed plugin.json in: {GLOBAL_PLUGIN_DIR}{RESET}")
260
+ except Exception:
261
+ pass
262
+
263
+ # 3. Re-initialize SQLite Memory Cache
264
+ print(f"\n{BOLD}[3/3] Synchronizing Central Agent Memory Cache...{RESET}")
265
+ try:
266
+ import cache_resolver
267
+ cache_resolver.init_db(seed=True)
268
+ print(f" {GREEN}[OK] Synced episodic solution memory (0-token cache).{RESET}")
269
+ except Exception as e:
270
+ print(f" ⚠️ Cache sync notice: {e}")
271
+
272
+ # Clear update cache so banner dismisses
273
+ new_local_ver = get_local_version()
274
+ cache = {
275
+ "last_check_timestamp": time.time(),
276
+ "latest_remote_version": new_local_ver,
277
+ "last_check_date": datetime.now().isoformat(),
278
+ "source": "self-update"
279
+ }
280
+ write_update_cache(cache)
281
+
282
+ print(f"\n{BOLD}{CYAN}======================================================================{RESET}")
283
+ print(f"{BOLD}{GREEN} 🎉 UPDATE COMPLETE: Synapse-Hub is up to date (v{new_local_ver})! {RESET}")
284
+ print(f"{BOLD}{CYAN}======================================================================{RESET}\n")
285
+ return True
286
+
287
+
288
+ def main():
289
+ import argparse
290
+ parser = argparse.ArgumentParser(description="Synapse-Hub Auto-Update & Drift Sentinel")
291
+ parser.add_argument("--check", action="store_true", help="Check for available updates without applying")
292
+ parser.add_argument("--update", action="store_true", help="Perform 1-click update to latest version")
293
+ parser.add_argument("--force", action="store_true", help="Force refresh update check bypassing cache")
294
+ args = parser.parse_args()
295
+
296
+ if args.check:
297
+ has_update, cur, rem = check_for_updates(force=True, notify=False)
298
+ print(f"Current Hub Version : v{cur}")
299
+ print(f"Latest Upstream : v{rem if rem else 'Unknown'}")
300
+ if has_update:
301
+ print(f"{YELLOW}⚠️ An update is available! Run 'agent-qa update' to upgrade.{RESET}")
302
+ sys.exit(1)
303
+ else:
304
+ print(f"{GREEN}✅ Synapse-Hub is up to date.{RESET}")
305
+ sys.exit(0)
306
+
307
+ if args.update or not (args.check or args.force):
308
+ perform_update()
309
+ sys.exit(0)
310
+
311
+
312
+ if __name__ == "__main__":
313
+ main()