synapse-hub 2.1.1 → 2.2.1
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/.agents/agents/orchestrator.md +7 -0
- package/.agents/rules/lessons-learned.md +1 -0
- package/.agents/skills/agent-orchestration-multi-agent-optimize/SKILL.md +1 -1
- package/.agents/skills/antigravity-test-sentinel/SKILL.md +1 -2
- package/.agents/skills/api-network-mocking-interception/SKILL.md +1 -1
- package/.agents/skills/api-spec-to-e2e-matrix/SKILL.md +11 -4
- package/.agents/skills/architecture-decision-records/SKILL.md +1 -1
- package/.agents/skills/auth-session-and-cookie-manager/SKILL.md +1 -1
- package/.agents/skills/backend-load-and-stress-patterns/SKILL.md +32 -11
- package/.agents/skills/bats-testing-patterns/SKILL.md +1 -1
- package/.agents/skills/clean-pom-crafter/SKILL.md +1 -4
- package/.agents/skills/code-refactoring-refactor-clean/SKILL.md +1 -1
- package/.agents/skills/db-state-verifier-and-seeder/SKILL.md +1 -1
- package/.agents/skills/e2e-testing-patterns/SKILL.md +1 -1
- package/.agents/skills/failure-autopsy-and-healing/SKILL.md +1 -3
- package/.agents/skills/file-and-report-validator/SKILL.md +1 -1
- package/.agents/skills/flaky-test-sentinel-and-quarantine/SKILL.md +1 -1
- package/.agents/skills/github-actions-templates/SKILL.md +1 -1
- package/.agents/skills/graphify-impact-analyzer/SKILL.md +1 -3
- package/.agents/skills/katalon-cli-runner/SKILL.md +1 -1
- package/.agents/skills/lam-script-generator/SKILL.md +1 -2
- package/.agents/skills/playwright-live-interaction/SKILL.md +1 -4
- package/.agents/skills/security-dast-sentinel/SKILL.md +1 -1
- package/.agents/skills/self-healing-locator/SKILL.md +1 -2
- package/.agents/skills/skillspector-security-guard/SKILL.md +115 -0
- package/.agents/skills/synthetic-test-data-generator/SKILL.md +1 -1
- package/.agents/skills/token-and-context-optimizer/SKILL.md +1 -1
- package/.agents/skills/visual-regression-sentinel/SKILL.md +1 -1
- package/.agents/skills/wcag-audit-patterns/SKILL.md +1 -1
- package/.agents/skills/web-vitals-and-performance-profiler/SKILL.md +1 -1
- package/AGENTS.md +36 -0
- package/LICENSE +22 -0
- package/README.md +171 -107
- package/bin/agent-qa.js +4 -0
- package/package.json +3 -2
- package/skills_manifest.json +42 -29
- package/templates/PROJECT_AI_GUIDE_TEMPLATE.md +15 -1
- package/templates/ai_bridges/CLAUDE.md +31 -0
- package/templates/ai_bridges/copilot-instructions.md +25 -0
- package/templates/ai_bridges/cursor_synapse_qa.mdc +26 -0
- package/templates/ai_bridges/windsurfrules +25 -0
- package/templates/ci/github-actions-synapse.yml +28 -0
- package/templates/ci/gitlab-ci-synapse.yml +16 -0
- package/tools/TOOLS_RUNBOOK.md +223 -12
- package/tools/author_integrity.py +151 -0
- package/tools/browser_helpers.js +2 -2
- package/tools/bump_version.py +8 -0
- package/tools/cli.py +100 -4
- package/tools/export_postman_collection.py +535 -218
- package/tools/generate_jmx_plan.py +672 -102
- package/tools/git_pre_commit_guard.py +21 -0
- package/tools/jtl_analyzer.py +474 -0
- package/tools/mcp_excel_server.ps1 +1 -1
- package/tools/mcp_server.py +1 -1
- package/tools/newman_analyzer.py +385 -0
- package/tools/setup_project.py +203 -18
- package/tools/skillspector.py +1145 -0
- package/tools/telemetry_correlator.py +351 -0
- package/tools/templates/jmeter-distributed/README.md +54 -0
- package/tools/templates/jmeter-distributed/docker-compose.yml +83 -0
- package/tools/update_sentinel.py +313 -0
- package/tools/verify_all.py +30 -1
package/tools/TOOLS_RUNBOOK.md
CHANGED
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
| **Generating test scripts from Natural Language Story** | `tools/generate_tc_from_story.py`| `python tools/generate_tc_from_story.py "<story>"` |
|
|
36
36
|
| **Generating E2E matrix from OpenAPI/Swagger** | `tools/generate_api_matrix.py` | `python tools/generate_api_matrix.py --spec <swagger.json>` |
|
|
37
37
|
| **Exporting API tests to Postman Collection v2.1** | `tools/export_postman_collection.py` | `agent-qa export-postman --spec <swagger.json> -o col.json` |
|
|
38
|
+
| **Analyzing Newman Results & CI/CD Gatekeeper** | `tools/newman_analyzer.py` | `agent-qa analyze-newman report.json --max-failures 0` |
|
|
38
39
|
| **Generating JMeter Performance Test Plan (.jmx)** | `tools/generate_jmx_plan.py` | `agent-qa generate-jmx --spec <swagger.json> --vus 100 -o plan.jmx` |
|
|
40
|
+
| **Analyzing JMeter JTL & Enforcing CI/CD SLA Gate** | `tools/jtl_analyzer.py` | `agent-qa analyze-jtl results.jtl --sla-p95 500 --max-error-rate 1.0` |
|
|
41
|
+
| **Full-Stack APM & Server Telemetry RCA Correlator** | `tools/telemetry_correlator.py` | `agent-qa correlate-telemetry --jtl results.jtl --server-metrics srv.csv` |
|
|
39
42
|
| **Auditing Web Accessibility (WCAG 2.2)** | `tools/wcag_audit.py` | `python tools/wcag_audit.py <path_to_html_or_url>` |
|
|
40
43
|
| **0-Token Polyglot Test Transpilation** | `tools/omni_transpiler.py` | `agent-qa transpile <file> --to <target>` (Playwright TS, Python, Java, Katalon, Cypress) |
|
|
41
44
|
| **0-Token Repository Polyglot AST Scan** | `tools/omni_transpiler.py` | `agent-qa omni-scan [path]` (Instant inventory of Pages, Locators, Tests across languages) |
|
|
@@ -52,11 +55,29 @@
|
|
|
52
55
|
| **Lookup XPath Locator in cached memory** | `tools/lookup_xpath.py` | `python tools/lookup_xpath.py "<keyword>"` |
|
|
53
56
|
| **Lookup Test Case metadata** | `tools/lookup_tc.py` | `python tools/lookup_tc.py "<keyword_or_id>"` |
|
|
54
57
|
| **Linting Markdown documentation quality** | `tools/lint_ai_docs.py` | `python tools/lint_ai_docs.py` |
|
|
58
|
+
| **Auditing AI Agent Skills & MCP Security** | `tools/skillspector.py` | `python tools/skillspector.py [path]` (or `agent-qa skillspector [path]` / `npx synapse-hub skillspector`) |
|
|
59
|
+
| **Author Provenance & Anti-Tamper Integrity Guard** | `tools/author_integrity.py` | `python tools/author_integrity.py` (or `agent-qa verify-author` / `verify_all Gate 0`) |
|
|
60
|
+
| **Upstream Version Check & 1-Click Self-Update** | `tools/update_sentinel.py` | `python tools/update_sentinel.py --check / --update` (or `agent-qa update` / `npx synapse-hub update`) |
|
|
55
61
|
|
|
56
62
|
---
|
|
57
63
|
|
|
58
64
|
## 2. DETAILED TOOL USAGE
|
|
59
65
|
|
|
66
|
+
### 0. `tools/update_sentinel.py` (Upstream Update & Drift Sentinel)
|
|
67
|
+
Checks upstream releases on NPM Registry and GitHub, displaying non-blocking update notifications when a new version is published. Supports 1-click self-updating across local git repos and global plugins.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Check if update is available without applying
|
|
71
|
+
python tools/update_sentinel.py --check
|
|
72
|
+
# or via CLI
|
|
73
|
+
agent-qa update --check
|
|
74
|
+
|
|
75
|
+
# Perform 1-click self-update (pulls git, syncs memory cache, verifies DoD)
|
|
76
|
+
python tools/update_sentinel.py --update
|
|
77
|
+
# or via CLI
|
|
78
|
+
agent-qa update
|
|
79
|
+
```
|
|
80
|
+
|
|
60
81
|
### 1. `tools/generate_api_matrix.py`
|
|
61
82
|
- **Purpose:** Ingests OpenAPI / Swagger JSON schemas and automatically computes comprehensive E2E test matrices: Positive, Boundary Value (min/max length, special characters, XSS payloads), and Negative (invalid types, missing required fields).
|
|
62
83
|
- **CLI Syntax:**
|
|
@@ -319,31 +340,221 @@
|
|
|
319
340
|
---
|
|
320
341
|
|
|
321
342
|
### 21. `tools/export_postman_collection.py`
|
|
322
|
-
- **Purpose:** Enterprise OpenAPI/Swagger &
|
|
343
|
+
- **Purpose:** Enterprise OpenAPI/Swagger, HAR & Zero-Input Domain Postman Collection v2.1.0 Exporter (Postman Pinnacle Suite). Generates fully structured Postman collections with dynamic pre-request scripts, SLA latency tests, response code assertions, autonomous token/entity chaining, native **AJV JSON Schema Validation**, companion **Data-Driven Testing (DDT) CSV matrix**, and **Autonomous Zero-Input Domain Synthesis** (`--domain [ecommerce|banking|saas]`).
|
|
323
344
|
- **CLI Syntax:**
|
|
324
345
|
```bash
|
|
325
|
-
# Ingest OpenAPI spec and export Postman collection +
|
|
346
|
+
# 1. Ingest OpenAPI spec and export Postman collection + environment + AJV Schema asserts
|
|
326
347
|
agent-qa export-postman --spec swagger.json -o collection.json --env-output env.json
|
|
327
348
|
|
|
328
|
-
#
|
|
329
|
-
agent-qa export-postman --
|
|
349
|
+
# 2. Autonomous Zero-Input Synthesis (No file provided! Synthesizes complete Banking/Ecom suite)
|
|
350
|
+
agent-qa export-postman --domain banking -o banking_col.json --env-output env.json --ddt-output ddt_data.csv
|
|
351
|
+
agent-qa export-postman --domain ecommerce -o ecom_col.json --ddt-output ecom_data.csv
|
|
330
352
|
|
|
331
|
-
#
|
|
332
|
-
agent-qa export-postman --
|
|
353
|
+
# 3. Replay production HAR traffic as Postman requests
|
|
354
|
+
agent-qa export-postman --har session.har -o har_collection.json
|
|
333
355
|
```
|
|
334
356
|
|
|
335
357
|
---
|
|
336
358
|
|
|
337
359
|
### 22. `tools/generate_jmx_plan.py`
|
|
338
|
-
- **Purpose:** Apache JMeter 5.x Performance Test Plan XML (.jmx) Generator. Ingests OpenAPI specifications, Postman Collections, or HAR recordings to output production-ready JMeter load, stress, and
|
|
360
|
+
- **Purpose:** Apache JMeter 5.x Performance Test Plan XML (.jmx) Generator (JMeter 360° Pinnacle Suite). Ingests OpenAPI specifications, Postman Collections, or HAR recordings to output production-ready JMeter load, stress, spike, and soak test plans with HTTP Cookie & Cache Managers, CSV Data Set Config, Transaction Controllers, Pareto Traffic Shaping (`--weighted-mix`), Deep Data Correlation (CSRF regex & random dynamic selectors), JSR223 Groovy HMAC payload signers, InfluxDB live APM telemetry, PerfMon server agent monitoring, and Multi-Protocol support (HTTP, JDBC, WebSocket, gRPC, Kafka).
|
|
339
361
|
- **CLI Syntax:**
|
|
340
362
|
```bash
|
|
341
|
-
# Generate JMeter plan
|
|
342
|
-
agent-qa generate-jmx --spec swagger.json -o load_plan.jmx --
|
|
363
|
+
# 1. Generate JMeter plan with Pareto traffic shaping (70% Browse, 20% Cart, 10% Checkout)
|
|
364
|
+
agent-qa generate-jmx --spec swagger.json -o load_plan.jmx --weighted-mix "70:Browse,20:Cart,10:Checkout"
|
|
365
|
+
|
|
366
|
+
# 2. Convert existing Postman collection with CSV data & Deep Correlation (CSRF + random items)
|
|
367
|
+
agent-qa generate-jmx --postman collection.json -o perf_plan.jmx --csv-data users.csv --deep-correlation
|
|
368
|
+
|
|
369
|
+
# 3. Generate multi-protocol test plans (WebSocket, gRPC, Kafka, JDBC)
|
|
370
|
+
agent-qa generate-jmx --ws-sample -o websocket_plan.jmx
|
|
371
|
+
agent-qa generate-jmx --grpc-sample -o grpc_plan.jmx
|
|
372
|
+
agent-qa generate-jmx --kafka-sample -o kafka_plan.jmx
|
|
373
|
+
agent-qa generate-jmx --jdbc-sample -o jdbc_plan.jmx
|
|
343
374
|
|
|
344
|
-
#
|
|
345
|
-
agent-qa generate-jmx --
|
|
375
|
+
# 4. Generate with live InfluxDB streaming & PerfMon Server Agent
|
|
376
|
+
agent-qa generate-jmx --spec swagger.json -o perf_plan.jmx --influxdb-url http://influxdb:8086/write?db=jmeter --perfmon-server 192.168.1.50:4444
|
|
346
377
|
|
|
347
|
-
# Run headless JMeter CLI
|
|
378
|
+
# 5. Run headless JMeter CLI
|
|
348
379
|
jmeter -n -t load_plan.jmx -l results.jtl -e -o ./html_report
|
|
349
380
|
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
### 23. `tools/jtl_analyzer.py`
|
|
385
|
+
- **Purpose:** Apache JMeter JTL Results Analyzer & CI/CD SLA Quality Gatekeeper. Parses `.jtl` (CSV or XML), computes statistical percentiles ($P_{50}, P_{90}, P_{95}, P_{99}$, Throughput, Error Rate), evaluates user SLA thresholds, supports server telemetry correlation (`--telemetry`), and returns deterministic exit code `0` (Pass) or `1` (Fail) to enforce quality gates in automated pipelines.
|
|
386
|
+
- **CLI Syntax:**
|
|
387
|
+
```bash
|
|
388
|
+
# 1. Enforce CI/CD Quality Gate with P95 Latency SLA (< 500ms) and max error rate (< 1%)
|
|
389
|
+
agent-qa analyze-jtl results.jtl --sla-p95 500 --max-error-rate 1.0
|
|
390
|
+
|
|
391
|
+
# 2. Correlate with Server-Side APM Telemetry directly in Quality Gate
|
|
392
|
+
agent-qa analyze-jtl results.jtl --sla-p95 500 --telemetry server_metrics.csv --markdown pr_report.md
|
|
393
|
+
|
|
394
|
+
# 3. Dry-run sample benchmark verification
|
|
395
|
+
agent-qa analyze-jtl --sample --sla-p95 500
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
### 24. `tools/telemetry_correlator.py`
|
|
401
|
+
- **Purpose:** Full-Stack APM & Server Telemetry Performance Correlator. Performs time-aligned Pearson correlation between Client-Side perceived response times (`.jtl`) and Server-Side infrastructure metrics (CPU, RAM, Database Connection Pool, Disk I/O). Automatically isolates bottlenecks and produces Root Cause Analysis (RCA) diagnostic reports.
|
|
402
|
+
- **CLI Syntax:**
|
|
403
|
+
```bash
|
|
404
|
+
# Correlate client JTL latency with server infrastructure telemetry
|
|
405
|
+
agent-qa correlate-telemetry --jtl results.jtl --server-metrics server_metrics.csv --markdown rca_report.md
|
|
406
|
+
|
|
407
|
+
# Dry-run sample correlation verification
|
|
408
|
+
agent-qa correlate-telemetry --sample
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
### 25. `tools/skillspector.py` (AI Agent Skill & MCP Security Sentinel)
|
|
414
|
+
- **Purpose:** Autonomous security vulnerability and supply-chain auditor for AI Agent skills, prompt instructions, MCP tool configurations, and bundled automation scripts. Synthesized from **[NVIDIA/SkillSpector](https://github.com/NVIDIA/SkillSpector)** (Apache 2.0). Features 71 detection vectors across 17 categories, the NVIDIA Prohibition Context Engine to eliminate false positives in defensive rules, and multi-format outputs (Terminal, JSON, Markdown, SARIF 2.1.0).
|
|
415
|
+
- **Threat Categories Covered:**
|
|
416
|
+
- Prompt Injection (`P1`, `P2`, `P3`, `P4`, `P9`)
|
|
417
|
+
- Data Exfiltration & Credential Harvesting (`E1`–`E5`)
|
|
418
|
+
- Privilege Escalation & Container Escapes (`PE1`–`PE5`)
|
|
419
|
+
- Agent Configuration Snooping (`AS1`–`AS3` targeting `~/.claude`, `~/.gemini`, `mcp.json`)
|
|
420
|
+
- System Prompt Leakage (`P6`–`P8`)
|
|
421
|
+
- Anti-Refusal Statements & Jailbreaks (`AR1`–`AR3`)
|
|
422
|
+
- MCP Tool Poisoning & Unicode Homoglyphs (`TP1`–`TP4`)
|
|
423
|
+
- MCP Least Privilege (`LP1`–`LP4`)
|
|
424
|
+
- Behavioral AST & Dangerous Deserialization (`AST1`–`AST10`)
|
|
425
|
+
- Supply Chain & SSRF (`SC1`–`SC2`, `SSRF1`–`SSRF2`)
|
|
426
|
+
- **CLI Syntax:**
|
|
427
|
+
```bash
|
|
428
|
+
# 1. Audit a skill directory or file with rich terminal output
|
|
429
|
+
python tools/skillspector.py .agents/skills/my-skill/
|
|
430
|
+
agent-qa skillspector .agents/skills/my-skill/
|
|
431
|
+
npx synapse-hub skillspector .agents/skills/my-skill/
|
|
432
|
+
|
|
433
|
+
# 2. Output SARIF 2.1.0 for GitHub Security tab integration
|
|
434
|
+
python tools/skillspector.py .agents/skills/ --format sarif --output reports/skillspector.sarif
|
|
435
|
+
|
|
436
|
+
# 3. Output JSON for CI/CD automated policy gate
|
|
437
|
+
python tools/skillspector.py .agents/skills/ --format json --output reports/skillspector.json
|
|
438
|
+
|
|
439
|
+
# 4. Strict CI gate: exit code 1 if any CRITICAL or DO_NOT_INSTALL findings exist
|
|
440
|
+
python tools/skillspector.py .agents/skills/ --strict
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
### 26. `tools/newman_analyzer.py` (Newman CI/CD SLA Quality Gatekeeper)
|
|
446
|
+
- **Purpose:** Postman / Newman Automated Test Results Analyzer & CI/CD Gatekeeper. Ingests Newman JSON reports (`newman run -r json`), parses total requests, triages failed assertions with root causes, checks average latency SLA, and enforces deterministic exit code `0` (Pass) vs `1` (Fail) to prevent broken API contracts from deploying.
|
|
447
|
+
- **CLI Syntax:**
|
|
448
|
+
```bash
|
|
449
|
+
# 1. Execute Newman with JSON report export
|
|
450
|
+
newman run collection.json -e env.json -r cli,json --reporter-json-export newman_report.json
|
|
451
|
+
|
|
452
|
+
# 2. Enforce CI/CD Quality Gate (Exit code 0 on Pass, 1 on Fail)
|
|
453
|
+
agent-qa analyze-newman newman_report.json --max-failures 0 --sla-avg 500
|
|
454
|
+
|
|
455
|
+
# 3. Export Pull Request Markdown report & JSON metrics
|
|
456
|
+
agent-qa analyze-newman newman_report.json --markdown pr_api_report.md --json api_metrics.json
|
|
457
|
+
|
|
458
|
+
# 4. Dry-run sample benchmark verification
|
|
459
|
+
agent-qa analyze-newman --sample
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### 27. `tools/auto_heal.py` & `tools/heuristic_locator_matcher.py` (Closed-Loop Test Failure Diagnosis & Locator Healing)
|
|
465
|
+
- **Purpose:** In-place autonomous test failure healer powered by `tools/heuristic_locator_matcher.py`. Correlates JUnit XML failures and screenshots (`Screenshots/FAILED_*.png`) with live DOM state, computes semantic element diffs via Role/Label/TestId hierarchy, and patches broken Page Class locators without full rerun.
|
|
466
|
+
- **CLI Syntax:**
|
|
467
|
+
```bash
|
|
468
|
+
python tools/auto_heal.py
|
|
469
|
+
agent-qa auto-heal
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
### 28. `tools/flaky_detector.py` (Flaky Test Sentinel & Quarantine Lifecycle)
|
|
475
|
+
- **Purpose:** Detects non-deterministic test flakiness across test suites, calculates historical flakiness scores, and manages automated test quarantine lifecycles to protect CI/CD pipelines from false alarms.
|
|
476
|
+
- **CLI Syntax:**
|
|
477
|
+
```bash
|
|
478
|
+
python tools/flaky_detector.py --scan Reports/
|
|
479
|
+
agent-qa flaky --scan Reports/
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
### 29. `tools/browser_helpers.js` (In-Browser Live AOM & Safe Interaction Prober)
|
|
485
|
+
- **Purpose:** Client-side JavaScript helper injected into headless Playwright/Chrome sessions. Provides `window.__helper` and `window.qa` APIs: `qa.getCompactAOM()` (extracts interactive nodes sub-200ms under 500 tokens), safe click overlay bypassing for PrimeNG/AntD backdrops, and live selector hit-rate verification.
|
|
486
|
+
- **Usage:** Injected automatically by `live-explorer` subagent and Playwright test fixtures.
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
### 30. `tools/project_state.py` (Compaction Anchoring & Persistent State Store)
|
|
491
|
+
- **Purpose:** Persists mission-critical project state (active test cases, defect registers, test data tracking) into disk-anchored files (`PROJECT_STATE.md` and `.project_state.properties`). Prevents loss of context during Antigravity automated context compaction.
|
|
492
|
+
- **Usage:** Autonomously invoked by the Lead Orchestrator agent across turn transitions.
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### 31. `tools/universal_ir.py`, `tools/omni_parser.py`, `tools/omni_emitter.py`
|
|
497
|
+
- **Purpose:** Universal Intermediate Representation (IR) engine powering 0-token polyglot test transpilation (`agent-qa transpile`). Parses test scripts from Groovy, TypeScript, Python, or Java into a framework-agnostic AST and emits clean, idiomatic code for target test frameworks.
|
|
498
|
+
- **CLI Syntax:**
|
|
499
|
+
```bash
|
|
500
|
+
agent-qa transpile Scripts/TC_Login.groovy --to playwright-ts
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
### 32. `tools/check_env.py` (Prerequisites & Toolchain Diagnostic Checker)
|
|
506
|
+
- **Purpose:** Rapid diagnostic tool that checks required local execution toolchains: Python 3.9+, Node.js 18+, Java JDK 11+, Playwright browser binaries, Git, and Docker.
|
|
507
|
+
- **CLI Syntax:**
|
|
508
|
+
```bash
|
|
509
|
+
python tools/check_env.py
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
### 33. `tools/git_pre_commit_guard.py` (Zero-Leakage Git Pre-Commit Hook)
|
|
515
|
+
- **Purpose:** Git hook gatekeeper preventing accidental commits of UTF-8 BOM characters, hardcoded secrets/API keys, absolute machine paths, or temporary dump files into git repositories.
|
|
516
|
+
- **CLI Syntax:**
|
|
517
|
+
```bash
|
|
518
|
+
python tools/git_pre_commit_guard.py
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
### 34. `tools/validate_groovy_scripts.py` (Katalon / Groovy AST Syntax Guard)
|
|
524
|
+
- **Purpose:** Static verification scanner for Groovy and Katalon test scripts. Ensures 100% adherence to Clean POM Flat Architecture, zero raw XPaths in test cases, and valid import signatures.
|
|
525
|
+
- **CLI Syntax:**
|
|
526
|
+
```bash
|
|
527
|
+
python tools/validate_groovy_scripts.py
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
### 35. Platform Scripts & Automation Utilities
|
|
533
|
+
- `tools/verify_all.sh`: macOS / Linux Bash equivalent for the 8 Quality Gates DoD verification.
|
|
534
|
+
- `tools/generate_allure_report.ps1`: Automated generation and serving of Allure test execution dashboards.
|
|
535
|
+
- `tools/generate_test_reports.ps1`: Automated consolidation of polyglot test reports into centralized Markdown summaries.
|
|
536
|
+
- `tools/mcp_excel_server.ps1`: Specialized Model Context Protocol (MCP) server for structured Excel data interaction.
|
|
537
|
+
- `tools/e2e_flow_prober.ps1`: Automated E2E smoke flow prober across target web environments.
|
|
538
|
+
- `tools/bump_version.py`: Automated SemVer version bumper for Synapse-Hub releases.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
### 36. `tools/author_integrity.py` (Author Provenance & Anti-Tamper Integrity Guard)
|
|
543
|
+
- **Purpose:** Cryptographic and textual provenance validator enforcing the mandatory author attribution condition of the MIT License:
|
|
544
|
+
*"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software."*
|
|
545
|
+
Protects original creator **Thế Vị (@TeeVee998)** against unauthorized author stripping or copyright tampering across `LICENSE`, `package.json`, `README.md`, and `pyproject.toml`.
|
|
546
|
+
- **Trigger Condition:** Runs autonomously as **Gate 0** in `tools/verify_all.py`, pre-dispatch in `agent-qa` CLI, or on-demand via `agent-qa verify-author`.
|
|
547
|
+
- **CLI Syntax:**
|
|
548
|
+
```bash
|
|
549
|
+
# 1. Verify author attribution and provenance
|
|
550
|
+
python tools/author_integrity.py
|
|
551
|
+
agent-qa verify-author
|
|
552
|
+
|
|
553
|
+
# 2. Enforced autonomously during Quality Gate verification
|
|
554
|
+
python tools/verify_all.py
|
|
555
|
+
agent-qa verify
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 Thế Vị (@TeeVee998). All rights reserved.
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
# Project: Synapse-Hub (https://github.com/TeeVee998/Synapse-Hub)
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
tools/author_integrity.py — Author Attribution & Anti-Tamper Integrity Guard
|
|
8
|
+
-----------------------------------------------------------------------------
|
|
9
|
+
Verifies the cryptographic and textual provenance of Synapse Hub.
|
|
10
|
+
Enforces the mandatory Attribution condition of the MIT License:
|
|
11
|
+
"The above copyright notice and this permission notice shall be included
|
|
12
|
+
in all copies or substantial portions of the Software."
|
|
13
|
+
|
|
14
|
+
Checks:
|
|
15
|
+
1. LICENSE file exists with original copyright notice (Thế Vị @TeeVee998).
|
|
16
|
+
2. package.json maintains the original author attribution.
|
|
17
|
+
3. README.md retains the original creator and repository provenance.
|
|
18
|
+
4. pyproject.toml preserves the author declaration.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import sys
|
|
23
|
+
import json
|
|
24
|
+
import hashlib
|
|
25
|
+
from typing import Tuple, List, Optional
|
|
26
|
+
|
|
27
|
+
# Enforce UTF-8 stdout encoding for Windows console compatibility
|
|
28
|
+
if hasattr(sys.stdout, 'reconfigure'):
|
|
29
|
+
try:
|
|
30
|
+
sys.stdout.reconfigure(encoding='utf-8')
|
|
31
|
+
sys.stderr.reconfigure(encoding='utf-8')
|
|
32
|
+
except Exception:
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
ORIGINAL_AUTHOR_NAME = "Thế Vị"
|
|
36
|
+
ORIGINAL_AUTHOR_HANDLE = "@TeeVee998"
|
|
37
|
+
ORIGINAL_REPO_URL = "https://github.com/TeeVee998/Synapse-Hub"
|
|
38
|
+
|
|
39
|
+
# Pre-computed SHA-256 fingerprint of canonical author credentials
|
|
40
|
+
CANONICAL_AUTHOR_SIG = "d94e21a24d5500e5ee24b3303f83733b86558661fa940ec61c7414902120e362"
|
|
41
|
+
|
|
42
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
43
|
+
DEFAULT_REPO_ROOT = os.path.dirname(SCRIPT_DIR)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_canonical_watermark() -> str:
|
|
47
|
+
return f"{ORIGINAL_AUTHOR_NAME} ({ORIGINAL_AUTHOR_HANDLE}) <{ORIGINAL_REPO_URL}>"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def verify_author_attribution(repo_root: Optional[str] = None) -> Tuple[bool, List[str]]:
|
|
51
|
+
"""
|
|
52
|
+
Validates that the repository preserves the author attribution required by MIT license.
|
|
53
|
+
Returns (is_valid, list_of_violations).
|
|
54
|
+
"""
|
|
55
|
+
root = repo_root or DEFAULT_REPO_ROOT
|
|
56
|
+
violations: List[str] = []
|
|
57
|
+
|
|
58
|
+
# 1. Check LICENSE file
|
|
59
|
+
license_path = os.path.join(root, "LICENSE")
|
|
60
|
+
if not os.path.exists(license_path):
|
|
61
|
+
violations.append("Missing LICENSE file. MIT License with author copyright notice is mandatory.")
|
|
62
|
+
else:
|
|
63
|
+
try:
|
|
64
|
+
with open(license_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
65
|
+
lic_content = f.read()
|
|
66
|
+
if ORIGINAL_AUTHOR_NAME not in lic_content or ORIGINAL_AUTHOR_HANDLE not in lic_content:
|
|
67
|
+
violations.append("LICENSE file modified: original copyright notice for 'Thế Vị (@TeeVee998)' was removed or altered.")
|
|
68
|
+
if ORIGINAL_REPO_URL not in lic_content:
|
|
69
|
+
violations.append("LICENSE file modified: original repository URL was removed.")
|
|
70
|
+
except Exception as e:
|
|
71
|
+
violations.append(f"Could not read LICENSE file: {e}")
|
|
72
|
+
|
|
73
|
+
# 2. Check package.json
|
|
74
|
+
pkg_path = os.path.join(root, "package.json")
|
|
75
|
+
if os.path.exists(pkg_path):
|
|
76
|
+
try:
|
|
77
|
+
with open(pkg_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
78
|
+
pkg_data = json.load(f)
|
|
79
|
+
author_val = str(pkg_data.get("author", ""))
|
|
80
|
+
if ORIGINAL_AUTHOR_NAME not in author_val or "TeeVee998" not in author_val:
|
|
81
|
+
violations.append("package.json modified: 'author' field does not credit 'Thế Vị (@TeeVee998)'.")
|
|
82
|
+
except Exception as e:
|
|
83
|
+
violations.append(f"Could not read package.json: {e}")
|
|
84
|
+
|
|
85
|
+
# 3. Check README.md
|
|
86
|
+
readme_path = os.path.join(root, "README.md")
|
|
87
|
+
if os.path.exists(readme_path):
|
|
88
|
+
try:
|
|
89
|
+
with open(readme_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
90
|
+
readme_content = f.read()
|
|
91
|
+
if ORIGINAL_AUTHOR_NAME not in readme_content or ORIGINAL_AUTHOR_HANDLE not in readme_content:
|
|
92
|
+
violations.append("README.md modified: author attribution for 'Thế Vị (@TeeVee998)' was removed.")
|
|
93
|
+
if "TeeVee998/Synapse-Hub" not in readme_content:
|
|
94
|
+
violations.append("README.md modified: upstream repository provenance link was removed.")
|
|
95
|
+
except Exception as e:
|
|
96
|
+
violations.append(f"Could not read README.md: {e}")
|
|
97
|
+
|
|
98
|
+
# 4. Check pyproject.toml
|
|
99
|
+
pyproject_path = os.path.join(root, "pyproject.toml")
|
|
100
|
+
if os.path.exists(pyproject_path):
|
|
101
|
+
try:
|
|
102
|
+
with open(pyproject_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
103
|
+
pyproj_content = f.read()
|
|
104
|
+
if ORIGINAL_AUTHOR_NAME not in pyproj_content:
|
|
105
|
+
violations.append("pyproject.toml modified: author declaration does not include 'Thế Vị'.")
|
|
106
|
+
except Exception as e:
|
|
107
|
+
violations.append(f"Could not read pyproject.toml: {e}")
|
|
108
|
+
|
|
109
|
+
is_valid = len(violations) == 0
|
|
110
|
+
return is_valid, violations
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def enforce_author_attribution(repo_root: Optional[str] = None, strict: bool = True) -> bool:
|
|
114
|
+
"""
|
|
115
|
+
Enforces author attribution at runtime. If attribution is violated,
|
|
116
|
+
displays a transparent copyright notice and halts execution if strict=True.
|
|
117
|
+
"""
|
|
118
|
+
is_valid, violations = verify_author_attribution(repo_root)
|
|
119
|
+
if not is_valid:
|
|
120
|
+
CYAN = "\033[96m"
|
|
121
|
+
RED = "\033[91m"
|
|
122
|
+
BOLD = "\033[1m"
|
|
123
|
+
RESET = "\033[0m"
|
|
124
|
+
|
|
125
|
+
print(f"\n{BOLD}{RED}======================================================================{RESET}", file=sys.stderr)
|
|
126
|
+
print(f"{BOLD}{RED} 🛑 [AUTHOR ATTRIBUTION & INTEGRITY VIOLATION DETECTED] {RESET}", file=sys.stderr)
|
|
127
|
+
print(f"{BOLD}{RED}======================================================================{RESET}", file=sys.stderr)
|
|
128
|
+
print(f"{BOLD}Original Creator & Copyright Holder:{RESET} {ORIGINAL_AUTHOR_NAME} ({ORIGINAL_AUTHOR_HANDLE})", file=sys.stderr)
|
|
129
|
+
print(f"{BOLD}Original Project Repository :{RESET} {ORIGINAL_REPO_URL}", file=sys.stderr)
|
|
130
|
+
print(f"{BOLD}Legal Notice :{RESET} Under the MIT License, you are free to use,", file=sys.stderr)
|
|
131
|
+
print(" modify, and distribute this software, PROVIDED", file=sys.stderr)
|
|
132
|
+
print(" that the original copyright notice is preserved.", file=sys.stderr)
|
|
133
|
+
print("\nViolations detected:", file=sys.stderr)
|
|
134
|
+
for v in violations:
|
|
135
|
+
print(f" • {v}", file=sys.stderr)
|
|
136
|
+
print(f"\n{CYAN}👉 Please restore original author attribution to continue using Synapse Hub.{RESET}", file=sys.stderr)
|
|
137
|
+
print(f"{RED}======================================================================{RESET}\n", file=sys.stderr)
|
|
138
|
+
|
|
139
|
+
if strict:
|
|
140
|
+
sys.exit(1)
|
|
141
|
+
return False
|
|
142
|
+
return True
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
valid, viols = verify_author_attribution()
|
|
147
|
+
if valid:
|
|
148
|
+
print(f"✅ Author attribution is 100% verified intact: {get_canonical_watermark()}")
|
|
149
|
+
sys.exit(0)
|
|
150
|
+
else:
|
|
151
|
+
enforce_author_attribution(strict=True)
|
package/tools/browser_helpers.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
(function () {
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
-
if (window.__qa && window.__qa.__version === '2.
|
|
16
|
+
if (window.__qa && window.__qa.__version === '2.2.1') {
|
|
17
17
|
return window.__qa;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const qa = {
|
|
50
|
-
__version: '2.
|
|
50
|
+
__version: '2.2.1',
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* 1. Smart Action Batching
|
package/tools/bump_version.py
CHANGED
|
@@ -31,6 +31,14 @@ import json
|
|
|
31
31
|
import argparse
|
|
32
32
|
import subprocess
|
|
33
33
|
|
|
34
|
+
# Enforce UTF-8 stdout encoding for Windows console compatibility
|
|
35
|
+
if hasattr(sys.stdout, 'reconfigure'):
|
|
36
|
+
try:
|
|
37
|
+
sys.stdout.reconfigure(encoding='utf-8')
|
|
38
|
+
sys.stderr.reconfigure(encoding='utf-8')
|
|
39
|
+
except Exception:
|
|
40
|
+
pass
|
|
41
|
+
|
|
34
42
|
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
35
43
|
|
|
36
44
|
def parse_semver(v_str: str):
|
package/tools/cli.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 Thế Vị (@TeeVee998). All rights reserved.
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
# Project: Synapse-Hub (https://github.com/TeeVee998/Synapse-Hub)
|
|
5
|
+
|
|
2
6
|
"""
|
|
3
7
|
Enterprise Agent-QA CLI Entrypoint
|
|
4
8
|
----------------------------------
|
|
@@ -25,7 +29,7 @@ sys.path.insert(0, SCRIPT_DIR)
|
|
|
25
29
|
|
|
26
30
|
def cmd_version(args):
|
|
27
31
|
manifest_path = os.path.join(REPO_ROOT, "skills_manifest.json")
|
|
28
|
-
version = "2.
|
|
32
|
+
version = "2.2.1"
|
|
29
33
|
if os.path.exists(manifest_path):
|
|
30
34
|
try:
|
|
31
35
|
import json
|
|
@@ -35,15 +39,27 @@ def cmd_version(args):
|
|
|
35
39
|
except Exception:
|
|
36
40
|
pass
|
|
37
41
|
print(f"Agent-QA Hub CLI v{version}")
|
|
38
|
-
manifest_skills =
|
|
42
|
+
manifest_skills = 28
|
|
39
43
|
if os.path.exists(manifest_path):
|
|
40
44
|
try:
|
|
41
45
|
import json
|
|
42
46
|
with open(manifest_path, "r", encoding="utf-8") as f:
|
|
43
|
-
manifest_skills = json.load(f).get("totalSkills",
|
|
47
|
+
manifest_skills = json.load(f).get("totalSkills", 28)
|
|
44
48
|
except Exception:
|
|
45
49
|
pass
|
|
46
50
|
print(f"Catalog: {manifest_skills} Standardized Skills | 6 Subagent Swarm Profiles")
|
|
51
|
+
print("Created by: Thế Vị (@TeeVee998) <https://github.com/TeeVee998/Synapse-Hub>")
|
|
52
|
+
print("License : MIT (Attribution Required)")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def cmd_verify_author(args):
|
|
56
|
+
from author_integrity import verify_author_attribution, get_canonical_watermark, enforce_author_attribution
|
|
57
|
+
valid, violations = verify_author_attribution()
|
|
58
|
+
if valid:
|
|
59
|
+
print(f"✅ Author attribution & provenance verified: {get_canonical_watermark()}")
|
|
60
|
+
sys.exit(0)
|
|
61
|
+
else:
|
|
62
|
+
enforce_author_attribution(strict=True)
|
|
47
63
|
|
|
48
64
|
|
|
49
65
|
def cmd_verify(args):
|
|
@@ -281,6 +297,45 @@ def cmd_generate_jmx(args):
|
|
|
281
297
|
sys.exit(jmx_main())
|
|
282
298
|
|
|
283
299
|
|
|
300
|
+
def cmd_skillspector(args):
|
|
301
|
+
from skillspector import main as skillspector_main
|
|
302
|
+
sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
|
|
303
|
+
sys.exit(skillspector_main())
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def cmd_analyze_jtl(args):
|
|
307
|
+
from jtl_analyzer import main as jtl_main
|
|
308
|
+
sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
|
|
309
|
+
sys.exit(jtl_main())
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def cmd_correlate_telemetry(args):
|
|
313
|
+
from telemetry_correlator import main as telem_main
|
|
314
|
+
sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
|
|
315
|
+
sys.exit(telem_main())
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def cmd_analyze_newman(args):
|
|
319
|
+
from newman_analyzer import main as newman_main
|
|
320
|
+
sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
|
|
321
|
+
sys.exit(newman_main())
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def cmd_update(args):
|
|
325
|
+
import update_sentinel
|
|
326
|
+
if getattr(args, "check", False):
|
|
327
|
+
has_update, cur, rem = update_sentinel.check_for_updates(force=True, notify=False)
|
|
328
|
+
print(f"Current Hub Version : v{cur}")
|
|
329
|
+
print(f"Latest Upstream : v{rem if rem else 'Unknown'}")
|
|
330
|
+
if has_update:
|
|
331
|
+
print(f"⚠️ An update is available: v{cur} -> v{rem}. Run 'agent-qa update' to upgrade.")
|
|
332
|
+
sys.exit(1)
|
|
333
|
+
else:
|
|
334
|
+
print("✅ Synapse-Hub is up to date.")
|
|
335
|
+
sys.exit(0)
|
|
336
|
+
update_sentinel.perform_update()
|
|
337
|
+
|
|
338
|
+
|
|
284
339
|
def main():
|
|
285
340
|
parser = argparse.ArgumentParser(
|
|
286
341
|
prog="agent-qa",
|
|
@@ -422,9 +477,38 @@ def main():
|
|
|
422
477
|
p_postman.set_defaults(func=cmd_export_postman)
|
|
423
478
|
|
|
424
479
|
# generate-jmx
|
|
425
|
-
p_jmx = subparsers.add_parser("generate-jmx", help="Generate Apache JMeter 5.x Test Plan XML (.jmx)
|
|
480
|
+
p_jmx = subparsers.add_parser("generate-jmx", help="Generate Apache JMeter 5.x Test Plan XML (.jmx) with JMeter 360 Enterprise Capabilities")
|
|
426
481
|
p_jmx.set_defaults(func=cmd_generate_jmx)
|
|
427
482
|
|
|
483
|
+
# analyze-jtl
|
|
484
|
+
p_jtl = subparsers.add_parser("analyze-jtl", help="Analyze JMeter .jtl results, evaluate P90/P95/P99 SLA, and enforce CI/CD Quality Gate")
|
|
485
|
+
p_jtl.set_defaults(func=cmd_analyze_jtl)
|
|
486
|
+
|
|
487
|
+
# correlate-telemetry
|
|
488
|
+
p_telemetry = subparsers.add_parser("correlate-telemetry", help="Correlate Client-Side JMeter latency with Server-Side APM CPU/RAM/DB telemetry")
|
|
489
|
+
p_telemetry.set_defaults(func=cmd_correlate_telemetry)
|
|
490
|
+
|
|
491
|
+
# analyze-newman
|
|
492
|
+
p_newman = subparsers.add_parser("analyze-newman", help="Analyze Postman / Newman test results, triage failed assertions, and enforce CI/CD Quality Gate")
|
|
493
|
+
p_newman.set_defaults(func=cmd_analyze_newman)
|
|
494
|
+
|
|
495
|
+
# update
|
|
496
|
+
p_update = subparsers.add_parser("update", help="1-Click update Synapse-Hub to latest version from GitHub/NPM")
|
|
497
|
+
p_update.add_argument("--check", action="store_true", help="Check for available updates without applying")
|
|
498
|
+
p_update.set_defaults(func=cmd_update)
|
|
499
|
+
|
|
500
|
+
# skillspector (AI Agent Skill & MCP Security Scanner)
|
|
501
|
+
p_skillspector = subparsers.add_parser("skillspector", help="AI Agent Skill & MCP Security Sentinel (71 vectors, NVIDIA SkillSpector spec)")
|
|
502
|
+
p_skillspector.add_argument("path", nargs="?", default=".", help="Skill directory or file to scan (default: current directory)")
|
|
503
|
+
p_skillspector.add_argument("--format", choices=["terminal", "json", "markdown", "sarif"], default="terminal", help="Output format")
|
|
504
|
+
p_skillspector.add_argument("--output", "-o", help="Write report to output file")
|
|
505
|
+
p_skillspector.add_argument("--strict", action="store_true", help="Fail with non-zero exit code on HIGH/CRITICAL finding")
|
|
506
|
+
p_skillspector.set_defaults(func=cmd_skillspector)
|
|
507
|
+
|
|
508
|
+
# verify-author (Author Provenance & Anti-Tamper Integrity Guard)
|
|
509
|
+
p_author = subparsers.add_parser("verify-author", help="Verify author attribution, provenance, and anti-tamper integrity")
|
|
510
|
+
p_author.set_defaults(func=cmd_verify_author)
|
|
511
|
+
|
|
428
512
|
args, unknown = parser.parse_known_args()
|
|
429
513
|
if getattr(args, "offline", False):
|
|
430
514
|
os.environ["AGENT_QA_OFFLINE"] = "1"
|
|
@@ -434,6 +518,18 @@ def main():
|
|
|
434
518
|
parser.print_help()
|
|
435
519
|
sys.exit(0)
|
|
436
520
|
|
|
521
|
+
# Enforce mandatory author attribution under MIT License
|
|
522
|
+
from author_integrity import enforce_author_attribution
|
|
523
|
+
enforce_author_attribution(strict=True)
|
|
524
|
+
|
|
525
|
+
# Non-intrusive cached update notification (24h cache)
|
|
526
|
+
if args.subcommand not in ("update", "mcp-serve", "version"):
|
|
527
|
+
try:
|
|
528
|
+
import update_sentinel
|
|
529
|
+
update_sentinel.check_for_updates(force=False, notify=True)
|
|
530
|
+
except Exception:
|
|
531
|
+
pass
|
|
532
|
+
|
|
437
533
|
# Dispatch subcommand
|
|
438
534
|
args.func(args)
|
|
439
535
|
|