synapse-hub 2.2.4 → 2.4.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.
Files changed (312) hide show
  1. package/.agents/agents/failure-analyst.md +11 -0
  2. package/.agents/agents/live-explorer.md +28 -0
  3. package/.agents/agents/orchestrator.md +23 -4
  4. package/.agents/agents/pom-crafter.md +15 -0
  5. package/.agents/agents/quality-gatekeeper.md +20 -4
  6. package/.agents/agents/test-runner.md +12 -0
  7. package/.agents/rules/communication-style.md +40 -0
  8. package/.agents/rules/context-engineering.md +23 -0
  9. package/.agents/rules/git-push-protocol.md +10 -16
  10. package/.agents/rules/graphify.md +14 -14
  11. package/.agents/rules/mandatory-playwright-live.md +29 -29
  12. package/.agents/rules/mobile_appium_rules.md +132 -0
  13. package/.agents/rules/performance_testing_rules.md +74 -0
  14. package/.agents/rules/systematic-debugging.md +6 -6
  15. package/.agents/skills/agent-orchestration-multi-agent-optimize/SKILL.md +64 -215
  16. package/.agents/skills/agent-orchestration-multi-agent-optimize/examples/swarm_workload_config.json +12 -0
  17. package/.agents/skills/antigravity-test-sentinel/SKILL.md +3 -3
  18. package/.agents/skills/antigravity-test-sentinel/examples/dod_gate_policy.json +11 -0
  19. package/.agents/skills/api-network-mocking-interception/SKILL.md +1 -1
  20. package/.agents/skills/api-network-mocking-interception/examples/network_route_stub.json +9 -0
  21. package/.agents/skills/api-spec-to-e2e-matrix/SKILL.md +9 -9
  22. package/.agents/skills/api-spec-to-e2e-matrix/examples/sample_openapi.json +19 -0
  23. package/.agents/skills/architecture-decision-records/SKILL.md +35 -412
  24. package/.agents/skills/architecture-decision-records/examples/0001-record-architecture-decisions.md +12 -0
  25. package/.agents/skills/auth-session-and-cookie-manager/SKILL.md +1 -1
  26. package/.agents/skills/auth-session-and-cookie-manager/examples/storage_state_sample.json +11 -0
  27. package/.agents/skills/backend-load-and-stress-patterns/SKILL.md +80 -186
  28. package/.agents/skills/backend-load-and-stress-patterns/examples/k6_load_test_sample.js +13 -0
  29. package/.agents/skills/bats-testing-patterns/SKILL.md +1 -1
  30. package/.agents/skills/bats-testing-patterns/examples/cli_runner_test.bats +6 -0
  31. package/.agents/skills/bats-testing-patterns/resources/implementation-playbook.md +614 -614
  32. package/.agents/skills/clean-pom-crafter/SKILL.md +21 -3
  33. package/.agents/skills/clean-pom-crafter/examples/standard_test_case.groovy +28 -28
  34. package/.agents/skills/clean-pom-crafter/references/pom_patterns.groovy +138 -138
  35. package/.agents/skills/code-refactoring-refactor-clean/SKILL.md +2 -2
  36. package/.agents/skills/code-refactoring-refactor-clean/examples/refactored_page_sample.groovy +9 -0
  37. package/.agents/skills/db-state-verifier-and-seeder/SKILL.md +5 -5
  38. package/.agents/skills/db-state-verifier-and-seeder/examples/db_fixture_seed.json +12 -0
  39. package/.agents/skills/e2e-testing-patterns/SKILL.md +1 -1
  40. package/.agents/skills/e2e-testing-patterns/examples/playwright_sharded_config.ts +12 -0
  41. package/.agents/skills/e2e-testing-patterns/resources/implementation-playbook.md +522 -522
  42. package/.agents/skills/failure-autopsy-and-healing/SKILL.md +17 -3
  43. package/.agents/skills/failure-autopsy-and-healing/examples/sample_junit_failure.xml +8 -0
  44. package/.agents/skills/failure-autopsy-and-healing/references/healing_matrix.md +64 -64
  45. package/.agents/skills/failure-autopsy-and-healing/references/qa_investigation_protocol.md +56 -56
  46. package/.agents/skills/failure-autopsy-and-healing/scripts/triage_failures.sh +98 -98
  47. package/.agents/skills/file-and-report-validator/SKILL.md +1 -1
  48. package/.agents/skills/file-and-report-validator/examples/sample_export_schema.json +14 -0
  49. package/.agents/skills/flaky-test-sentinel-and-quarantine/SKILL.md +3 -3
  50. package/.agents/skills/flaky-test-sentinel-and-quarantine/examples/quarantine_registry.json +11 -0
  51. package/.agents/skills/gherkin-to-suite/SKILL.md +103 -0
  52. package/.agents/skills/gherkin-to-suite/examples/checkout.feature +39 -0
  53. package/.agents/skills/gherkin-to-suite/examples/suite_report_sample.json +334 -0
  54. package/.agents/skills/github-actions-templates/SKILL.md +47 -304
  55. package/.agents/skills/github-actions-templates/examples/matrix_test_pipeline.yml +8 -0
  56. package/.agents/skills/graphify-impact-analyzer/SKILL.md +6 -6
  57. package/.agents/skills/graphify-impact-analyzer/examples/dependency_blast_radius.json +8 -0
  58. package/.agents/skills/katalon-cli-runner/SKILL.md +2 -2
  59. package/.agents/skills/katalon-cli-runner/examples/headless_kre_exec.sh +3 -0
  60. package/.agents/skills/katalon-cli-runner/references/groovy-patterns.md +209 -209
  61. package/.agents/skills/katalon-cli-runner/references/katalon-api.md +155 -155
  62. package/.agents/skills/katalon-cli-runner/references/runner_commands.md +67 -67
  63. package/.agents/skills/lam-script-generator/SKILL.md +42 -1
  64. package/.agents/skills/lam-script-generator/examples/user_story_sample.md +8 -0
  65. package/.agents/skills/lean-code-ladder/SKILL.md +83 -0
  66. package/.agents/skills/lean-code-ladder/examples/ladder_walkthrough.md +37 -0
  67. package/.agents/skills/meta-prompt-crafter/SKILL.md +107 -0
  68. package/.agents/skills/meta-prompt-crafter/examples/qa_prompt_template.md +35 -0
  69. package/.agents/skills/persistent-planning-files/SKILL.md +108 -0
  70. package/.agents/skills/persistent-planning-files/examples/task_plan_example.md +56 -0
  71. package/.agents/skills/playwright-live-interaction/SKILL.md +49 -1
  72. package/.agents/skills/playwright-live-interaction/examples/live_probe_script.js +5 -0
  73. package/.agents/skills/playwright-live-interaction/references/advanced_superpowers.md +160 -160
  74. package/.agents/skills/playwright-live-interaction/references/compact_accessibility_snapshots.md +75 -75
  75. package/.agents/skills/playwright-live-interaction/references/recipes.md +388 -388
  76. package/.agents/skills/playwright-live-interaction/references/swarm_orchestration.md +134 -134
  77. package/.agents/skills/playwright-webapp-testing/SKILL.md +93 -0
  78. package/.agents/skills/playwright-webapp-testing/examples/server_lifecycle_playwright.py +63 -0
  79. package/.agents/skills/rbt-manual-testing/SKILL.md +150 -0
  80. package/.agents/skills/rbt-manual-testing/examples/checkout_rbt_manual_suite.md +25 -0
  81. package/.agents/skills/security-dast-sentinel/SKILL.md +54 -135
  82. package/.agents/skills/security-dast-sentinel/examples/dast_scan_config.json +10 -0
  83. package/.agents/skills/self-healing-locator/SKILL.md +24 -10
  84. package/.agents/skills/self-healing-locator/examples/aom_diff_sample.json +16 -0
  85. package/.agents/skills/skillspector-security-guard/SKILL.md +32 -90
  86. package/.agents/skills/skillspector-security-guard/examples/safe_mcp_config.json +12 -0
  87. package/.agents/skills/surgical-coding-principles/SKILL.md +89 -0
  88. package/.agents/skills/surgical-coding-principles/examples/surgical_vs_scope_creep.md +46 -0
  89. package/.agents/skills/synthetic-test-data-generator/SKILL.md +3 -3
  90. package/.agents/skills/synthetic-test-data-generator/examples/idempotent_data_recipe.json +9 -0
  91. package/.agents/skills/systematic-debugging/SKILL.md +100 -0
  92. package/.agents/skills/systematic-debugging/examples/four_phase_case.md +44 -0
  93. package/.agents/skills/test-driven-development/SKILL.md +114 -0
  94. package/.agents/skills/test-driven-development/examples/red_green_refactor_qa.md +78 -0
  95. package/.agents/skills/token-and-context-optimizer/SKILL.md +1 -1
  96. package/.agents/skills/token-and-context-optimizer/examples/distilled_log_sample.txt +3 -0
  97. package/.agents/skills/verification-before-completion/SKILL.md +100 -0
  98. package/.agents/skills/verification-before-completion/examples/evidence_log_example.md +46 -0
  99. package/.agents/skills/visual-regression-sentinel/SKILL.md +21 -1
  100. package/.agents/skills/visual-regression-sentinel/examples/visual_mask_rules.json +9 -0
  101. package/.agents/skills/wcag-audit-patterns/SKILL.md +3 -3
  102. package/.agents/skills/wcag-audit-patterns/examples/wcag_compliance_checklist.json +10 -0
  103. package/.agents/skills/wcag-audit-patterns/resources/implementation-playbook.md +541 -541
  104. package/.agents/skills/web-vitals-and-performance-profiler/SKILL.md +1 -1
  105. package/.agents/skills/web-vitals-and-performance-profiler/examples/cwv_budget_policy.json +6 -0
  106. package/.agents/templates/completion_report.md +57 -57
  107. package/.agents/workflows/analyze_requirement_document.md +18 -0
  108. package/.agents/workflows/export_testcases_excel.md +32 -0
  109. package/.agents/workflows/generate_combinatorial_test_data.md +28 -0
  110. package/.agents/workflows/generate_cross_module_test_plan.md +37 -0
  111. package/.agents/workflows/generate_manual_testcases_rbt.md +56 -0
  112. package/.agents/workflows/generate_requirements_from_website.md +25 -0
  113. package/.agents/workflows/generate_testcases_from_requirements.md +21 -0
  114. package/.agents/workflows/graphify.md +10 -10
  115. package/.agents/workflows/verify.md +2 -2
  116. package/.cursor/rules/language.mdc +7 -7
  117. package/.cursor/rules/synapse-qa.mdc +23 -0
  118. package/.cursorrules +7 -0
  119. package/.pre-commit-hooks.yaml +14 -0
  120. package/.windsurfrules +7 -0
  121. package/AGENTS.md +54 -15
  122. package/CLAUDE.md +35 -12
  123. package/LICENSE +30 -0
  124. package/NOTICE +180 -0
  125. package/README.en.md +331 -0
  126. package/README.md +252 -515
  127. package/action.yml +51 -0
  128. package/benchmarks/qa_eval/README.md +71 -0
  129. package/benchmarks/qa_eval/build_dataset.py +677 -0
  130. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-06_api_contract_drift.json +22 -0
  131. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-07_api_contract_drift.json +22 -0
  132. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-08_api_contract_drift.json +22 -0
  133. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-09_api_contract_drift.json +22 -0
  134. package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-10_api_contract_drift.json +22 -0
  135. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-21_fake_pass_tautology.json +21 -0
  136. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-22_fake_pass_tautology.json +21 -0
  137. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-23_fake_pass_tautology.json +21 -0
  138. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-24_fake_pass_tautology.json +21 -0
  139. package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-25_fake_pass_tautology.json +21 -0
  140. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-01_locator_drift.json +23 -0
  141. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-02_locator_drift.json +23 -0
  142. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-03_locator_drift.json +23 -0
  143. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-04_locator_drift.json +23 -0
  144. package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-05_locator_drift.json +23 -0
  145. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-16_stale_and_mutation.json +22 -0
  146. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-17_stale_and_mutation.json +22 -0
  147. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-18_stale_and_mutation.json +22 -0
  148. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-19_stale_and_mutation.json +22 -0
  149. package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-20_stale_and_mutation.json +23 -0
  150. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-11_timing_and_race.json +22 -0
  151. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-12_timing_and_race.json +22 -0
  152. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-13_timing_and_race.json +22 -0
  153. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-14_timing_and_race.json +22 -0
  154. package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-15_timing_and_race.json +22 -0
  155. package/benchmarks/qa_eval/eval_runner.py +418 -0
  156. package/benchmarks/qa_eval/reports/AB_METHODOLOGY_REPORT.md +83 -0
  157. package/benchmarks/qa_eval/reports/BENCHMARK_REPORT.md +69 -0
  158. package/benchmarks/qa_eval/reports/eval_results.json +105 -0
  159. package/bin/agent-qa.js +16 -4
  160. package/docs/ARCHITECTURE.md +107 -0
  161. package/docs/CI_CD_INTEGRATION.md +94 -0
  162. package/docs/CLI_REFERENCE.md +157 -0
  163. package/docs/CONTRIBUTING.md +91 -0
  164. package/docs/PLUGIN_DEVELOPMENT_GUIDE.md +126 -0
  165. package/docs/TOKEN_QUOTA_PLAYBOOK.md +41 -0
  166. package/docs/adopted-ecosystem-tools.md +87 -0
  167. package/docs/schemas/synapse.config.schema.json +64 -0
  168. package/examples/cypress-ecommerce-suite/README.md +45 -0
  169. package/examples/cypress-ecommerce-suite/cypress/e2e/checkout.cy.js +17 -0
  170. package/examples/cypress-ecommerce-suite/cypress/pages/BasePage.js +29 -0
  171. package/examples/cypress-ecommerce-suite/cypress/pages/CartPage.js +51 -0
  172. package/examples/cypress-ecommerce-suite/cypress.config.js +13 -0
  173. package/examples/cypress-ecommerce-suite/package.json +13 -0
  174. package/examples/katalon-suite/Keywords/pages/BasePage.groovy +19 -0
  175. package/examples/katalon-suite/Keywords/pages/DashboardPage.groovy +29 -0
  176. package/examples/katalon-suite/Keywords/pages/LoginPage.groovy +45 -0
  177. package/examples/katalon-suite/Profiles/default.glbl +12 -0
  178. package/examples/katalon-suite/README.md +18 -0
  179. package/examples/katalon-suite/Scripts/Auth/TC_LoginSuccess/Script1234567890.groovy +12 -0
  180. package/examples/katalon-suite/Scripts/Dashboard/TC_ViewSummary/Script1234567891.groovy +15 -0
  181. package/examples/katalon-suite/katalon_suite.prj +21 -0
  182. package/examples/playwright-crm-suite/README.md +40 -0
  183. package/examples/playwright-crm-suite/package.json +14 -0
  184. package/examples/playwright-crm-suite/pages/BasePage.ts +37 -0
  185. package/examples/playwright-crm-suite/pages/CustomerPage.ts +57 -0
  186. package/examples/playwright-crm-suite/pages/LoginPage.ts +32 -0
  187. package/examples/playwright-crm-suite/playwright.config.ts +27 -0
  188. package/examples/playwright-crm-suite/tests/auth.spec.ts +22 -0
  189. package/examples/playwright-crm-suite/tests/customers.spec.ts +33 -0
  190. package/examples/plugins/sample-custom-plugin/README.md +14 -0
  191. package/examples/plugins/sample-custom-plugin/plugin.json +16 -0
  192. package/examples/plugins/sample-custom-plugin/skills/custom-security-headers-audit/SKILL.md +29 -0
  193. package/examples/plugins/sample-custom-plugin/skills/custom-security-headers-audit/examples/audit_fixture.json +8 -0
  194. package/examples/plugins/sample-custom-plugin/tools/custom_security_headers.py +125 -0
  195. package/examples/practices/README.md +22 -0
  196. package/examples/practices/requirements/crm/requirements_contracts.md +292 -0
  197. package/examples/practices/requirements/crm/requirements_customers.md +462 -0
  198. package/examples/practices/requirements/crm/requirements_login.md +202 -0
  199. package/examples/practices/requirements/crm/requirements_projects.md +396 -0
  200. package/examples/practices/requirements/crm/requirements_tasks.md +343 -0
  201. package/examples/practices/requirements/ecommerce/requirements_category_brand.txt +402 -0
  202. package/examples/practices/requirements/jira/KAN-5/KAN-1/2026-04-03_04-28-27.png +0 -0
  203. package/examples/practices/requirements/jira/KAN-5/KAN-1/KAN-1_requirement.md +52 -0
  204. package/examples/practices/requirements/jira/KAN-5/KAN-4/2026-04-03_04-28-19.png +0 -0
  205. package/examples/practices/requirements/jira/KAN-5/KAN-4/2026-04-03_04-28-57.png +0 -0
  206. package/examples/practices/requirements/jira/KAN-5/KAN-4/KAN-4_requirement.md +119 -0
  207. package/examples/practices/requirements/jira/KAN-5/KAN-5_overview.md +9 -0
  208. package/examples/practices/requirements/jira/KAN-5/KAN-6/2026-04-03_05-58-08.png +0 -0
  209. package/examples/practices/requirements/jira/KAN-5/KAN-6/2026-04-03_05-58-23.png +0 -0
  210. package/examples/practices/requirements/jira/KAN-5/KAN-6/KAN-6_requirement.md +32 -0
  211. package/examples/practices/testcases/api/book_management_api_test_cases.md +144 -0
  212. package/examples/practices/testcases/api/user_management_api_test_cases.md +139 -0
  213. package/examples/practices/testcases/crm/test_cases_crm_login.md +148 -0
  214. package/examples/practices/testcases/crm/test_cases_customers.md +156 -0
  215. package/examples/pytest-api-suite/README.md +45 -0
  216. package/examples/pytest-api-suite/conftest.py +31 -0
  217. package/examples/pytest-api-suite/pages/user_api_client.py +36 -0
  218. package/examples/pytest-api-suite/requirements.txt +2 -0
  219. package/examples/pytest-api-suite/tests/test_user_api.py +44 -0
  220. package/examples/selenium-suite/README.md +18 -0
  221. package/examples/selenium-suite/pages/base_page.py +27 -0
  222. package/examples/selenium-suite/pages/login_page.py +29 -0
  223. package/examples/selenium-suite/pages/order_page.py +25 -0
  224. package/examples/selenium-suite/pytest.ini +6 -0
  225. package/examples/selenium-suite/requirements.txt +2 -0
  226. package/examples/selenium-suite/tests/test_login.py +10 -0
  227. package/examples/selenium-suite/tests/test_order.py +10 -0
  228. package/package.json +27 -12
  229. package/scripts/generate_skill_examples.py +244 -0
  230. package/scripts/install.ps1 +112 -0
  231. package/scripts/install_global_plugin.ps1 +94 -0
  232. package/scripts/install_global_plugin.sh +49 -0
  233. package/scripts/lint_skills.ps1 +57 -0
  234. package/scripts/package_dist.py +323 -0
  235. package/scripts/setup.sh +59 -0
  236. package/scripts/update_hub.ps1 +19 -0
  237. package/scripts/update_hub.sh +15 -0
  238. package/skills_manifest.json +209 -6
  239. package/synapse.config.json +30 -0
  240. package/templates/PROJECT_AI_GUIDE_TEMPLATE.md +7 -7
  241. package/templates/PROJECT_STATE_TEMPLATE.md +1 -1
  242. package/templates/ai_bridges/CLAUDE.md +33 -16
  243. package/templates/ai_bridges/copilot-instructions.md +14 -21
  244. package/templates/ai_bridges/cursor_synapse_qa.mdc +17 -20
  245. package/templates/ai_bridges/windsurfrules +21 -21
  246. package/templates/ci/github-actions-synapse.yml +71 -4
  247. package/templates/welcome.html.tmpl +1674 -0
  248. package/tools/.infer_baseline.json +1102 -0
  249. package/tools/TOOLS_RUNBOOK.md +98 -131
  250. package/tools/__init__.py +26 -0
  251. package/tools/agent_canary.py +501 -501
  252. package/tools/analyze_project.py +31 -17
  253. package/tools/api_fuzzer.py +278 -6
  254. package/tools/author_integrity.py +6 -6
  255. package/tools/auto_heal.py +1 -1
  256. package/tools/browser_helpers.js +105 -7
  257. package/tools/bug_reporter.py +31 -1
  258. package/tools/bump_version.py +30 -3
  259. package/tools/cache_resolver.py +248 -14
  260. package/tools/check_env.py +55 -14
  261. package/tools/check_version_sync.py +171 -0
  262. package/tools/ci_healing_hook.py +1 -1
  263. package/tools/cli.py +454 -42
  264. package/tools/count_tokens.py +1257 -0
  265. package/tools/dashboard_generator.py +2638 -0
  266. package/tools/db_sandbox.py +198 -20
  267. package/tools/e2e_flow_prober.ps1 +12 -64
  268. package/tools/e2e_flow_prober.py +99 -0
  269. package/tools/e2e_flow_prober.sh +4 -0
  270. package/tools/flaky_detector.py +4 -3
  271. package/tools/generate_allure_report.ps1 +12 -29
  272. package/tools/generate_allure_report.py +77 -0
  273. package/tools/generate_allure_report.sh +4 -0
  274. package/tools/generate_jmx_plan.py +257 -58
  275. package/tools/generate_test_reports.ps1 +12 -134
  276. package/tools/generate_test_reports.py +133 -0
  277. package/tools/generate_test_reports.sh +4 -0
  278. package/tools/gherkin_suite.py +758 -0
  279. package/tools/git_pre_commit_guard.py +12 -6
  280. package/tools/goldfish_review.py +366 -0
  281. package/tools/heal_pr_automator.py +1 -1
  282. package/tools/heuristic_locator_matcher.py +170 -21
  283. package/tools/infer_linter.py +612 -70
  284. package/tools/lint_ai_docs.py +64 -0
  285. package/tools/matrix_sharder.py +1 -1
  286. package/tools/mcp_excel_server.ps1 +12 -250
  287. package/tools/mcp_excel_server.py +249 -0
  288. package/tools/mcp_excel_server.sh +4 -0
  289. package/tools/mcp_server.py +368 -144
  290. package/tools/md_to_xlsx.py +307 -0
  291. package/tools/micro_mutator.py +302 -69
  292. package/tools/omni_transpiler.py +2 -2
  293. package/tools/output_formatter.py +128 -0
  294. package/tools/pinpoint_failure.py +88 -88
  295. package/tools/project_state.py +2 -2
  296. package/tools/repo_map.py +1 -1
  297. package/tools/safety_firewall.py +196 -45
  298. package/tools/setup_project.py +295 -31
  299. package/tools/skillspector.py +31 -0
  300. package/tools/spec_drift_sentinel.py +439 -0
  301. package/tools/sync_agent_rules.py +248 -0
  302. package/tools/telemetry_correlator.py +45 -0
  303. package/tools/test_impact.py +51 -12
  304. package/tools/tms_sync_bridge.py +21 -5
  305. package/tools/universal_ir.py +3 -0
  306. package/tools/update_sentinel.py +87 -15
  307. package/tools/verify_all.ps1 +13 -0
  308. package/tools/verify_all.py +479 -85
  309. package/tools/visual_diff_canvas.py +1 -0
  310. package/tools/visual_som_helper.py +1 -1
  311. package/tools/watch_mode.py +305 -0
  312. package/tools/welcome_page.py +291 -0
package/tools/cli.py CHANGED
@@ -12,6 +12,9 @@ Dispatches commands to underlying specialized tools in tools/.
12
12
 
13
13
  import os
14
14
  import sys
15
+ import json
16
+ import re
17
+ import difflib
15
18
  import argparse
16
19
 
17
20
  # Enforce UTF-8 stdout encoding for Windows console compatibility
@@ -26,26 +29,35 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
26
29
  REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
27
30
  sys.path.insert(0, SCRIPT_DIR)
28
31
 
32
+ # ANSI Color formatting
33
+ CYAN = "\033[96m"
34
+ GREEN = "\033[92m"
35
+ YELLOW = "\033[93m"
36
+ RED = "\033[91m"
37
+ BOLD = "\033[1m"
38
+ RESET = "\033[0m"
39
+
29
40
 
30
41
  def cmd_version(args):
42
+ """Displays the current hub version, skill catalog count, and license information."""
31
43
  manifest_path = os.path.join(REPO_ROOT, "skills_manifest.json")
32
- version = "2.2.4"
44
+ version = "2.4.1"
33
45
  if os.path.exists(manifest_path):
34
46
  try:
35
47
  import json
36
48
  with open(manifest_path, "r", encoding="utf-8") as f:
37
49
  data = json.load(f)
38
50
  version = data.get("version", version)
39
- except Exception:
51
+ except (OSError, json.JSONDecodeError):
40
52
  pass
41
53
  print(f"Agent-QA Hub CLI v{version}")
42
- manifest_skills = 28
54
+ manifest_skills = 38
43
55
  if os.path.exists(manifest_path):
44
56
  try:
45
57
  import json
46
58
  with open(manifest_path, "r", encoding="utf-8") as f:
47
- manifest_skills = json.load(f).get("totalSkills", 28)
48
- except Exception:
59
+ manifest_skills = json.load(f).get("totalSkills", 38)
60
+ except (OSError, json.JSONDecodeError):
49
61
  pass
50
62
  print(f"Catalog: {manifest_skills} Standardized Skills | 6 Subagent Swarm Profiles")
51
63
  print("Created by: Thế Vị (@TeeVee998) <https://github.com/TeeVee998/Synapse-Hub>")
@@ -53,6 +65,7 @@ def cmd_version(args):
53
65
 
54
66
 
55
67
  def cmd_verify_author(args):
68
+ """Validates author attribution and MIT provenance integrity across the repository."""
56
69
  from author_integrity import verify_author_attribution, get_canonical_watermark, enforce_author_attribution
57
70
  valid, violations = verify_author_attribution()
58
71
  if valid:
@@ -62,33 +75,52 @@ def cmd_verify_author(args):
62
75
  enforce_author_attribution(strict=True)
63
76
 
64
77
 
78
+ def _forward_subcommand_args(args_or_name=None) -> list:
79
+ """Safely extracts and forwards arguments intended for the underlying subcommand tool."""
80
+ subcmd = None
81
+ if isinstance(args_or_name, str):
82
+ subcmd = args_or_name
83
+ elif hasattr(args_or_name, "subcommand"):
84
+ subcmd = args_or_name.subcommand
85
+
86
+ if subcmd and subcmd in sys.argv:
87
+ idx = sys.argv.index(subcmd)
88
+ return [sys.argv[0]] + sys.argv[idx + 1:]
89
+ return [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
90
+
91
+
65
92
  def cmd_verify(args):
93
+ """Executes the 9 Quality Gates Definition of Done (DoD) verification suite."""
66
94
  from verify_all import main as verify_main
67
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
95
+ sys.argv = _forward_subcommand_args(args)
68
96
  sys.exit(verify_main())
69
97
 
70
98
 
71
99
  def cmd_lint(args):
100
+ """Runs the Meta Infer-style AST Fake-Pass, zero-assertion, and hard sleep scanner."""
72
101
  from infer_linter import main as lint_main
73
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
102
+ sys.argv = _forward_subcommand_args(args)
74
103
  sys.exit(lint_main())
75
104
 
76
105
 
77
106
  def cmd_heal(args):
107
+ """Interacts with the central episodic self-healing solution memory cache."""
78
108
  from cache_resolver import main as heal_main
79
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
109
+ sys.argv = _forward_subcommand_args(args)
80
110
  sys.exit(heal_main())
81
111
 
82
112
 
83
113
  def cmd_distill(args):
114
+ """Distills and filters high-volume CI/CD test execution logs by ~95%."""
84
115
  from distill_log import main as distill_main
85
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
116
+ sys.argv = _forward_subcommand_args(args)
86
117
  sys.exit(distill_main())
87
118
 
88
119
 
89
120
  def cmd_impact(args):
121
+ """Analyzes code change impact and scopes affected tests using AST graph mapping."""
90
122
  from test_impact import main as impact_main
91
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
123
+ sys.argv = _forward_subcommand_args(args)
92
124
  sys.exit(impact_main())
93
125
 
94
126
 
@@ -112,73 +144,99 @@ def cmd_clean(args):
112
144
  try:
113
145
  os.remove(os.path.join(root, f))
114
146
  removed_count += 1
115
- except Exception:
147
+ except OSError:
116
148
  pass
117
149
  print(f"✅ Cleanup finished: {removed_count} build artifacts and caches removed.")
118
150
 
119
151
 
120
152
  def cmd_flaky(args):
153
+ """Detects non-deterministic flaky tests and manages quarantine governance."""
121
154
  from flaky_detector import main as flaky_main
122
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
155
+ sys.argv = _forward_subcommand_args(args)
123
156
  sys.exit(flaky_main())
124
157
 
125
158
 
126
159
  def cmd_canary(args):
160
+ """Executes the autonomous canary self-healing benchmark across 8 failure vectors."""
127
161
  from agent_canary import main as canary_main
128
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
162
+ sys.argv = _forward_subcommand_args(args)
129
163
  sys.exit(canary_main())
130
164
 
131
165
 
132
166
  def cmd_analyze(args):
167
+ """Runs comprehensive 5-in-1 project health and AST architecture analysis."""
133
168
  from analyze_project import main as analyze_main
134
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
169
+ sys.argv = _forward_subcommand_args(args)
135
170
  sys.exit(analyze_main())
136
171
 
137
172
 
138
173
  def cmd_setup(args):
174
+ """Bootstraps a target test repository with AI guide, Git hook, and AST map."""
139
175
  from setup_project import main as setup_main
140
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
176
+ sys.argv = _forward_subcommand_args(args)
141
177
  sys.exit(setup_main())
142
178
 
143
179
 
180
+ def cmd_doctor(args):
181
+ """Runs a 1-click diagnostic check of system environment, tools, and dependencies."""
182
+ from check_env import main as check_env_main
183
+ sys.argv = _forward_subcommand_args(args)
184
+ sys.exit(check_env_main())
185
+
186
+
187
+ def cmd_uninstall(args):
188
+ """Reverts and cleans configuration files and Git hooks installed by setup in target project."""
189
+ from setup_project import uninstall_setup, resolve_target_repo
190
+ target = getattr(args, "target", None)
191
+ target_repo = resolve_target_repo(cli_target=target)
192
+ sys.exit(uninstall_setup(target_repo))
193
+
194
+
144
195
  def cmd_auto_heal(args):
196
+ """Executes closed-loop test failure diagnosis and creates a locator healing plan."""
145
197
  from auto_heal import main as auto_heal_main
146
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
198
+ sys.argv = _forward_subcommand_args(args)
147
199
  sys.exit(auto_heal_main())
148
200
 
149
201
 
150
202
  def cmd_safety_check(args):
203
+ """Validates actions against the Action Safety Firewall to prevent destructive operations."""
151
204
  from safety_firewall import main as safety_main
152
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
205
+ sys.argv = _forward_subcommand_args(args)
153
206
  sys.exit(safety_main())
154
207
 
155
208
 
156
209
  def cmd_contract_drift(args):
210
+ """Detects breaking API changes across OpenAPI / Swagger contract specifications."""
157
211
  from api_drift_sentinel import main as drift_main
158
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
212
+ sys.argv = _forward_subcommand_args(args)
159
213
  sys.exit(drift_main())
160
214
 
161
215
 
162
216
  def cmd_mcp_serve(args):
217
+ """Starts the JSON-RPC 2.0 stdio Model Context Protocol (MCP) server."""
163
218
  from mcp_server import run_stdio_server
164
219
  run_stdio_server()
165
220
 
166
221
 
167
222
  def cmd_mutate(args):
223
+ """Injects syntactic micro-mutations to measure test assertion sensitivity."""
168
224
  from micro_mutator import main as mut_main
169
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
225
+ sys.argv = _forward_subcommand_args(args)
170
226
  sys.exit(mut_main())
171
227
 
172
228
 
173
229
  def cmd_heal_pr(args):
230
+ """Calculates self-healing confidence and generates an automated Git pull request draft."""
174
231
  from heal_pr_automator import main as pr_main
175
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
232
+ sys.argv = _forward_subcommand_args(args)
176
233
  sys.exit(pr_main())
177
234
 
178
235
 
179
236
  def cmd_shard(args):
237
+ """Balances parallel CI/CD test execution using duration-balanced bin-packing."""
180
238
  from matrix_sharder import main as shard_main
181
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
239
+ sys.argv = _forward_subcommand_args(args)
182
240
  sys.exit(shard_main())
183
241
 
184
242
 
@@ -217,25 +275,37 @@ def cmd_omni_scan(args):
217
275
 
218
276
  def cmd_report_bug(args):
219
277
  from bug_reporter import main as bug_main
220
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
278
+ sys.argv = _forward_subcommand_args(args)
221
279
  sys.exit(bug_main())
222
280
 
223
281
 
224
282
  def cmd_mock_shield(args):
225
283
  from network_mock_shield import main as mock_main
226
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
284
+ sys.argv = _forward_subcommand_args(args)
227
285
  sys.exit(mock_main())
228
286
 
229
287
 
230
288
  def cmd_visual_mask(args):
231
289
  from smart_visual_masker import main as mask_main
232
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
290
+ sys.argv = _forward_subcommand_args(args)
233
291
  sys.exit(mask_main())
234
292
 
235
293
 
294
+ def cmd_review_spec(args):
295
+ from goldfish_review import main as review_main
296
+ sys.argv = _forward_subcommand_args(args)
297
+ sys.exit(review_main())
298
+
299
+
300
+ def cmd_drift_check(args):
301
+ from spec_drift_sentinel import main as drift_main
302
+ sys.argv = _forward_subcommand_args(args)
303
+ sys.exit(drift_main())
304
+
305
+
236
306
  def cmd_ci_hook(args):
237
307
  from ci_healing_hook import main as hook_main
238
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
308
+ sys.argv = _forward_subcommand_args(args)
239
309
  sys.exit(hook_main())
240
310
 
241
311
 
@@ -259,8 +329,8 @@ def cmd_migrate(args):
259
329
  try:
260
330
  transpile_file(file_path, target, output_dir=dest, hermetic=True)
261
331
  migrated_count += 1
262
- except Exception:
263
- pass
332
+ except (OSError, ValueError, SyntaxError) as e:
333
+ print(f" ⚠️ Skipping {f}: {e}")
264
334
  print(f"✅ [MIGRATION COMPLETE] {migrated_count} test files converted to {target} in '{dest}'.")
265
335
  else:
266
336
  transpile_file(src, target, output_dir=dest, hermetic=True)
@@ -269,55 +339,67 @@ def cmd_migrate(args):
269
339
 
270
340
  def cmd_decouple_config(args):
271
341
  from config_decoupler import main as decouple_main
272
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
342
+ sys.argv = _forward_subcommand_args(args)
273
343
  sys.exit(decouple_main())
274
344
 
275
345
 
276
346
  def cmd_fuzz_api(args):
277
347
  from api_fuzzer import main as fuzz_main
278
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
348
+ sys.argv = _forward_subcommand_args(args)
279
349
  sys.exit(fuzz_main())
280
350
 
281
351
 
282
352
  def cmd_som(args):
283
353
  from visual_som_helper import main as som_main
284
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
354
+ sys.argv = _forward_subcommand_args(args)
285
355
  sys.exit(som_main())
286
356
 
287
357
 
358
+ def cmd_gherkin(args):
359
+ from gherkin_suite import main as gherkin_main
360
+ sys.argv = _forward_subcommand_args(args)
361
+ sys.exit(gherkin_main())
362
+
363
+
288
364
  def cmd_export_postman(args):
289
365
  from export_postman_collection import main as postman_main
290
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
366
+ sys.argv = _forward_subcommand_args(args)
291
367
  sys.exit(postman_main())
292
368
 
293
369
 
294
370
  def cmd_generate_jmx(args):
295
371
  from generate_jmx_plan import main as jmx_main
296
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
372
+ sys.argv = _forward_subcommand_args(args)
297
373
  sys.exit(jmx_main())
298
374
 
299
375
 
300
376
  def cmd_skillspector(args):
301
377
  from skillspector import main as skillspector_main
302
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
378
+ sys.argv = _forward_subcommand_args(args)
303
379
  sys.exit(skillspector_main())
304
380
 
305
381
 
306
382
  def cmd_analyze_jtl(args):
307
383
  from jtl_analyzer import main as jtl_main
308
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
384
+ sys.argv = _forward_subcommand_args(args)
309
385
  sys.exit(jtl_main())
310
386
 
311
387
 
388
+ def cmd_export_excel(args):
389
+ from md_to_xlsx import main as excel_main
390
+ sys.argv = _forward_subcommand_args(args)
391
+ sys.exit(excel_main())
392
+
393
+
312
394
  def cmd_correlate_telemetry(args):
313
395
  from telemetry_correlator import main as telem_main
314
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
396
+ sys.argv = _forward_subcommand_args(args)
315
397
  sys.exit(telem_main())
316
398
 
317
399
 
318
400
  def cmd_analyze_newman(args):
319
401
  from newman_analyzer import main as newman_main
320
- sys.argv = [sys.argv[0]] + (sys.argv[2:] if len(sys.argv) > 2 else [])
402
+ sys.argv = _forward_subcommand_args(args)
321
403
  sys.exit(newman_main())
322
404
 
323
405
 
@@ -336,17 +418,161 @@ def cmd_update(args):
336
418
  update_sentinel.perform_update()
337
419
 
338
420
 
421
+ def cmd_tokens(args):
422
+ import count_tokens
423
+ sys.argv = _forward_subcommand_args(args)
424
+ count_tokens.main()
425
+
426
+
427
+ def cmd_dashboard(args):
428
+ import dashboard_generator
429
+ sys.argv = _forward_subcommand_args(args)
430
+ dashboard_generator.main()
431
+
432
+
433
+ def cmd_watch(args):
434
+ import watch_mode
435
+ sys.argv = _forward_subcommand_args(args)
436
+ watch_mode.main()
437
+
438
+
439
+ def cmd_welcome(args):
440
+ import welcome_page
441
+ sys.argv = _forward_subcommand_args(args)
442
+ welcome_page.main()
443
+
444
+
445
+ def cmd_wcag_audit(args):
446
+ from wcag_audit import main as wcag_main
447
+ sys.argv = _forward_subcommand_args(args)
448
+ sys.exit(wcag_main())
449
+
450
+
451
+ def cmd_lookup_tc(args):
452
+ from lookup_tc import main as tc_main
453
+ sys.argv = _forward_subcommand_args(args)
454
+ sys.exit(tc_main())
455
+
456
+
457
+ def cmd_lookup_xpath(args):
458
+ from lookup_xpath import main as xpath_main
459
+ sys.argv = _forward_subcommand_args(args)
460
+ sys.exit(xpath_main())
461
+
462
+
463
+ def cmd_trace_data_flow(args):
464
+ from trace_data_flow import main as tdf_main
465
+ sys.argv = _forward_subcommand_args(args)
466
+ sys.exit(tdf_main())
467
+
468
+
469
+ def cmd_generate_tc(args):
470
+ from generate_tc_from_story import main as gen_tc_main
471
+ sys.argv = _forward_subcommand_args(args)
472
+ sys.exit(gen_tc_main())
473
+
474
+
475
+ def cmd_pinpoint_failure(args):
476
+ from pinpoint_failure import main as pp_main
477
+ sys.argv = _forward_subcommand_args(args)
478
+ sys.exit(pp_main())
479
+
480
+
481
+ def cmd_sync_rules(args):
482
+ from sync_agent_rules import main as sync_rules_main
483
+ sys.argv = _forward_subcommand_args(args)
484
+ sys.exit(sync_rules_main())
485
+
486
+
487
+ def cmd_api_matrix(args):
488
+ from generate_api_matrix import main as api_matrix_main
489
+ sys.argv = _forward_subcommand_args(args)
490
+ sys.exit(api_matrix_main())
491
+
492
+
493
+ def cmd_canvas_diff(args):
494
+ from visual_diff_canvas import main as canvas_diff_main
495
+ sys.argv = _forward_subcommand_args(args)
496
+ sys.exit(canvas_diff_main())
497
+
498
+
499
+ def cmd_validate_groovy(args):
500
+ from validate_groovy_scripts import main as groovy_main
501
+ sys.argv = _forward_subcommand_args(args)
502
+ sys.exit(groovy_main())
503
+
504
+
505
+ def cmd_check_version(args):
506
+ from check_version_sync import main as ver_sync_main
507
+ sys.argv = _forward_subcommand_args(args)
508
+ sys.exit(ver_sync_main())
509
+
510
+
511
+ def cmd_mcp_excel(args):
512
+ from mcp_excel_server import main as mcp_excel_main
513
+ sys.argv = _forward_subcommand_args(args)
514
+ sys.exit(mcp_excel_main())
515
+
516
+
517
+ def _hub_version():
518
+ manifest_path = os.path.join(REPO_ROOT, "skills_manifest.json")
519
+ version = "2.4.1"
520
+ if os.path.exists(manifest_path):
521
+ try:
522
+ import json
523
+ with open(manifest_path, "r", encoding="utf-8") as f:
524
+ version = json.load(f).get("version", version)
525
+ except (OSError, json.JSONDecodeError):
526
+ pass
527
+ return version
528
+
529
+
530
+ class SynapseArgumentParser(argparse.ArgumentParser):
531
+ """Enhanced ArgumentParser providing fuzzy Did-You-Mean suggestions on command typos."""
532
+ def error(self, message):
533
+ import difflib
534
+ m = re.search(r"invalid choice: '([^']+)'", message)
535
+ if m:
536
+ bad_choice = m.group(1)
537
+ choices = []
538
+ for action in self._actions:
539
+ if isinstance(action, argparse._SubParsersAction):
540
+ choices = list(action.choices.keys())
541
+ break
542
+ matches = difflib.get_close_matches(bad_choice, choices, n=3, cutoff=0.4)
543
+ sys.stderr.write(f"\n{BOLD}{RED}❌ Error: Lệnh '{bad_choice}' không tồn tại trong Synapse-Hub.{RESET}\n")
544
+ if matches:
545
+ suggestions = ", ".join(f"{BOLD}{GREEN}{c}{RESET}" for c in matches)
546
+ sys.stderr.write(f"💡 Có phải ý bạn là: {suggestions} ?\n\n")
547
+ sys.stderr.write(f"👉 Thử chạy: {BOLD}agent-qa {matches[0]} --help{RESET}\n\n")
548
+ else:
549
+ sys.stderr.write(f"👉 Gõ {BOLD}agent-qa --help{RESET} để xem danh sách tất cả các lệnh khả dụng.\n\n")
550
+ sys.exit(2)
551
+ super().error(message)
552
+
553
+
339
554
  def main():
340
- parser = argparse.ArgumentParser(
555
+ parser = SynapseArgumentParser(
341
556
  prog="agent-qa",
342
557
  description="Enterprise AI Agent Quality Engineering & Test Automation Hub CLI"
343
558
  )
559
+ parser.add_argument(
560
+ "--version",
561
+ action="version",
562
+ version=f"Agent-QA Hub CLI v{_hub_version()}"
563
+ )
344
564
  parser.add_argument(
345
565
  "--offline", "--offline-deterministic",
346
566
  action="store_true",
347
567
  dest="offline",
348
568
  help="Force 100%% offline air-gapped deterministic mode (zero external network / LLM API calls)"
349
569
  )
570
+ parser.add_argument(
571
+ "-q", "--quiet",
572
+ action="store_true",
573
+ dest="quiet",
574
+ help="Suppress informational banners and output only critical verdicts"
575
+ )
350
576
  subparsers = parser.add_subparsers(dest="subcommand", help="Available subcommands")
351
577
 
352
578
  # version
@@ -357,6 +583,18 @@ def main():
357
583
  p_setup = subparsers.add_parser("setup", help="Autonomous 1-click bootstrap of target project (AI guide, Git hook, AST map)")
358
584
  p_setup.set_defaults(func=cmd_setup)
359
585
 
586
+ # doctor
587
+ p_doctor = subparsers.add_parser("doctor", description="Enterprise Environment Diagnostic Tool", help="Run 1-click diagnostic check of system environment, tools, and dependencies")
588
+ p_doctor.add_argument("target", nargs="?", default=None, help="Target repository path to diagnose")
589
+ p_doctor.add_argument("--repo", "--path", dest="repo_path", default=None, help="Target repository path")
590
+ p_doctor.add_argument("--insecure", action="store_true", help="Allow unverified SSL certificates during connectivity checks")
591
+ p_doctor.set_defaults(func=cmd_doctor)
592
+
593
+ # uninstall
594
+ p_uninstall = subparsers.add_parser("uninstall", help="Revert and remove files installed by setup in target project")
595
+ p_uninstall.add_argument("target", nargs="?", default=None, help="Target repository path to revert")
596
+ p_uninstall.set_defaults(func=cmd_uninstall)
597
+
360
598
  # auto-heal
361
599
  p_auto_heal = subparsers.add_parser("auto-heal", help="Autonomous closed-loop test failure diagnosis and healing plan")
362
600
  p_auto_heal.set_defaults(func=cmd_auto_heal)
@@ -366,7 +604,7 @@ def main():
366
604
  p_heal_pr.set_defaults(func=cmd_heal_pr)
367
605
 
368
606
  # mutate
369
- p_mut = subparsers.add_parser("mutate", help="Inject AST micro-mutants to verify test assertion strength")
607
+ p_mut = subparsers.add_parser("mutate", help="Inject syntactic micro-mutants to verify test assertion strength")
370
608
  p_mut.set_defaults(func=cmd_mutate)
371
609
 
372
610
  # shard
@@ -390,7 +628,7 @@ def main():
390
628
  p_analyze.set_defaults(func=cmd_analyze)
391
629
 
392
630
  # verify
393
- p_verify = subparsers.add_parser("verify", help="Execute 7 Quality Gates DoD Verification")
631
+ p_verify = subparsers.add_parser("verify", help="Execute 9 Quality Gates DoD Verification")
394
632
  p_verify.set_defaults(func=cmd_verify)
395
633
 
396
634
  # lint
@@ -409,6 +647,10 @@ def main():
409
647
  p_impact = subparsers.add_parser("impact", help="Analyze code change impact using AST Knowledge Graph")
410
648
  p_impact.set_defaults(func=cmd_impact)
411
649
 
650
+ # gherkin
651
+ p_gherkin = subparsers.add_parser("gherkin", help="Compile Gherkin .feature files into test matrix, Universal IR and coverage-gap report (0-token)")
652
+ p_gherkin.set_defaults(func=cmd_gherkin)
653
+
412
654
  # canary
413
655
  p_canary = subparsers.add_parser("canary", help="Run autonomous canary resilience benchmark")
414
656
  p_canary.set_defaults(func=cmd_canary)
@@ -484,6 +726,13 @@ def main():
484
726
  p_jtl = subparsers.add_parser("analyze-jtl", help="Analyze JMeter .jtl results, evaluate P90/P95/P99 SLA, and enforce CI/CD Quality Gate")
485
727
  p_jtl.set_defaults(func=cmd_analyze_jtl)
486
728
 
729
+ # export-excel
730
+ p_excel = subparsers.add_parser("export-excel", help="Convert Markdown Test Cases into Styled Enterprise Excel (.xlsx)")
731
+ p_excel.add_argument("input", nargs="?", help="Path to input Markdown file (.md)")
732
+ p_excel.add_argument("-o", "--output", help="Path to output Excel file (.xlsx)")
733
+ p_excel.add_argument("--sheet-name", default="Test Cases", help="Worksheet title (default: Test Cases)")
734
+ p_excel.set_defaults(func=cmd_export_excel)
735
+
487
736
  # correlate-telemetry
488
737
  p_telemetry = subparsers.add_parser("correlate-telemetry", help="Correlate Client-Side JMeter latency with Server-Side APM CPU/RAM/DB telemetry")
489
738
  p_telemetry.set_defaults(func=cmd_correlate_telemetry)
@@ -509,25 +758,188 @@ def main():
509
758
  p_author = subparsers.add_parser("verify-author", help="Verify author attribution, provenance, and anti-tamper integrity")
510
759
  p_author.set_defaults(func=cmd_verify_author)
511
760
 
761
+ # tokens (Cross-Platform Token & Cost Auditor)
762
+ p_tokens = subparsers.add_parser("tokens", help="Audit token usage and estimated API cost across Antigravity, Cursor, and Claude Code")
763
+ p_tokens.add_argument("--platform", "-p", choices=["auto", "antigravity", "cursor", "claude", "all"], default="auto", help="AI platform to audit (default: auto)")
764
+ p_tokens.add_argument("--session", type=str, help="Specific session ID or index to audit")
765
+ p_tokens.add_argument("--current", action="store_true", help="Audit current active conversation")
766
+ p_tokens.add_argument("--last", action="store_true", help="Audit previous completed session (default)")
767
+ p_tokens.add_argument("--last-task", action="store_true", help="Audit specifically the last turn of target session")
768
+ p_tokens.add_argument("--turns", action="store_true", help="Show full turn-by-turn breakdown table")
769
+ p_tokens.add_argument("--rolling", "--budget", action="store_true", dest="rolling", help="Show 5-hour and 7-day rolling window quota & remaining tokens")
770
+ p_tokens.add_argument("--savings", action="store_true", help="Show Hub vs. Non-Hub token and cost savings comparison")
771
+ p_tokens.add_argument("--header", action="store_true", help="Print Pre-Flight confirmation block lines")
772
+ p_tokens.add_argument("--list", action="store_true", help="List recent conversations")
773
+ p_tokens.add_argument("--pricing", choices=["gemini-flash", "gemini-pro", "claude-sonnet", "claude-opus", "gpt-4o", "gpt-4o-mini"], default=None, help="Model pricing basis (default: auto-detected)")
774
+ p_tokens.add_argument("--json", action="store_true", help="Output machine-readable JSON format")
775
+ p_tokens.add_argument("--file", type=str, help="Direct path to a transcript.jsonl file")
776
+ p_tokens.set_defaults(func=cmd_tokens)
777
+
778
+ # dashboard (Standalone One-Page HTML Executive Dashboard)
779
+ p_dashboard = subparsers.add_parser("dashboard", help="Generate standalone one-page executive HTML dashboard (zero CDN deps)")
780
+ p_dashboard.add_argument("target", nargs="?", default=None, help="Target repository directory (default: current or Hub)")
781
+ p_dashboard.add_argument("--output", "-o", help="Output HTML file path (default: <target>/reports/PROJECT_DASHBOARD.html)")
782
+ p_dashboard.add_argument("--open", action="store_true", help="Automatically open generated dashboard in default browser")
783
+ p_dashboard.add_argument("--json", action="store_true", help="Print summary JSON to stdout")
784
+ p_dashboard.add_argument("--lang", choices=["vi", "en"], default="vi", help="Default display language (vi: Tiếng Việt, en: English, default: vi)")
785
+ p_dashboard.set_defaults(func=cmd_dashboard)
786
+
787
+ # watch (Real-Time Incremental Watch Mode Sentinel)
788
+ p_watch = subparsers.add_parser("watch", help="Real-Time incremental watch mode & test engineering HUD (< 100ms feedback)")
789
+ p_watch.add_argument("target", nargs="?", default=".", help="Directory to monitor (default: current directory)")
790
+ p_watch.add_argument("--debounce", type=float, default=0.8, help="Debounce interval in seconds (default: 0.8)")
791
+ p_watch.add_argument("--inactivity-timeout", type=float, default=0.0, help="Inactivity timeout in seconds to trigger stuck warning (default: 0 = disabled)")
792
+ p_watch.add_argument("--once", action="store_true", help="Run incremental scan once on all files and exit")
793
+ p_watch.set_defaults(func=cmd_watch)
794
+
795
+ # welcome (Interactive Visual Landing Page)
796
+ p_welcome = subparsers.add_parser("welcome", description="Interactive Visual Landing Page", help="Launch interactive visual landing page introducing Synapse Hub")
797
+ p_welcome.add_argument("target", nargs="?", default=None, help="Target repository directory (default: current directory)")
798
+ p_welcome.add_argument("--output", "-o", default=None, help="Output HTML file path (default: reports/WELCOME.html)")
799
+ p_welcome.add_argument("--lang", choices=["vi", "en"], default="vi", help="Default initial language (default: vi = Vietnamese)")
800
+ p_welcome.add_argument("--no-browser", action="store_true", help="Do not open the browser after generating the page")
801
+ p_welcome.add_argument("--open", action="store_true", help="Explicitly open the browser")
802
+ p_welcome.add_argument("--first-run", action="store_true", help="Only open if running for the first time (e.g. npm install or first pull)")
803
+ p_welcome.set_defaults(func=cmd_welcome)
804
+
805
+ # wcag-audit (WCAG 2.2 Accessibility Sentinel)
806
+ p_wcag = subparsers.add_parser("wcag-audit", help="Audit WCAG 2.2 accessibility conformance and contrast ratios")
807
+ p_wcag.add_argument("target", nargs="?", default=".", help="Target HTML file or directory to audit")
808
+ p_wcag.set_defaults(func=cmd_wcag_audit)
809
+
810
+ # lookup-tc (Deterministic Test Case Identifier Index)
811
+ p_lookup_tc = subparsers.add_parser("lookup-tc", help="Search test cases by ID, tag, priority, or flow")
812
+ p_lookup_tc.add_argument("query", nargs="?", default="", help="Query keyword or TC ID")
813
+ p_lookup_tc.set_defaults(func=cmd_lookup_tc)
814
+
815
+ # lookup-xpath (AOM & DOM Selector Lookup Cache)
816
+ p_lookup_xpath = subparsers.add_parser("lookup-xpath", help="Query cached resilient XPath & AOM locators")
817
+ p_lookup_xpath.add_argument("query", nargs="?", default="", help="Element text, test-id, or locator label")
818
+ p_lookup_xpath.set_defaults(func=cmd_lookup_xpath)
819
+
820
+ # trace-data-flow (Idempotent Data Flow & Taint Analysis)
821
+ p_trace = subparsers.add_parser("trace-data-flow", help="Trace test data lifecycles to detect DB leaks and missing teardowns")
822
+ p_trace.add_argument("target", nargs="?", default=".", help="Target test directory to inspect")
823
+ p_trace.set_defaults(func=cmd_trace_data_flow)
824
+
825
+ # generate-tc (User Story & Acceptance Criteria Compiler)
826
+ p_gen_tc = subparsers.add_parser("generate-tc", help="Compile natural language user stories into Clean POM test cases")
827
+ p_gen_tc.add_argument("story_file", nargs="?", default="", help="Path to markdown/text user story specification")
828
+ p_gen_tc.set_defaults(func=cmd_generate_tc)
829
+
830
+ # pinpoint-failure (Instant JUnit XML Root Cause Autopsy)
831
+ p_pinpoint = subparsers.add_parser("pinpoint-failure", help="Parse JUnit XML and locate exact failing line in 0.1s")
832
+ p_pinpoint.add_argument("report_file", nargs="?", default="", help="Path to JUnit XML test report")
833
+ p_pinpoint.set_defaults(func=cmd_pinpoint_failure)
834
+
835
+ # sync-rules (Single-Source Agent Rules Synchronizer)
836
+ p_sync_rules = subparsers.add_parser("sync-rules", help="Synchronize AGENTS.md single source of truth across all AI IDE bridges")
837
+ p_sync_rules.add_argument("--check", action="store_true", help="Verify all AI bridges are in sync without writing")
838
+ p_sync_rules.set_defaults(func=cmd_sync_rules)
839
+
840
+ # review-spec (Zero-Context Test Spec Auditor - Elephant-Goldfish Model)
841
+ p_review = subparsers.add_parser("review-spec", help="Zero-context stress-test for specifications and user stories (Elephant-Goldfish Model)")
842
+ p_review.add_argument("spec_file", nargs="?", default="", help="Path to specification file (Markdown or Gherkin .feature, use '-' for stdin)")
843
+ p_review.add_argument("--stdin", action="store_true", help="Read specification from standard input (stdin)")
844
+ p_review.add_argument("--json", action="store_true", help="Output machine-readable JSON format")
845
+ p_review.add_argument("--min-score", type=int, default=80, help="Minimum readiness score threshold (default: 80)")
846
+ p_review.set_defaults(func=cmd_review_spec)
847
+
848
+ # drift-check (Spec-to-Code Drift Sentinel)
849
+ p_drift = subparsers.add_parser("drift-check", help="Spec-to-Code Drift Sentinel checking Deficit & Scope Drift")
850
+ p_drift.add_argument("--spec", required=True, help="Path to specification file (Markdown or Gherkin .feature)")
851
+ p_drift.add_argument("--code", required=True, help="Path to test script or directory of test scripts")
852
+ p_drift.add_argument("--markdown", "-m", help="Path to export Markdown drift report (e.g. SPEC_DRIFT_REPORT.md)")
853
+ p_drift.add_argument("--json", action="store_true", help="Output machine-readable JSON format")
854
+ p_drift.set_defaults(func=cmd_drift_check)
855
+
856
+ # api-matrix
857
+ p_api_mat = subparsers.add_parser("api-matrix", help="Generate Positive, Boundary, and Negative test matrix from OpenAPI/Swagger")
858
+ p_api_mat.add_argument("--spec", "-s", help="Path to OpenAPI / Swagger JSON/YAML file")
859
+ p_api_mat.add_argument("--format", "-f", choices=["markdown", "json"], default="markdown", help="Output format (markdown, json)")
860
+ p_api_mat.add_argument("--output", "-o", help="Output file path")
861
+ p_api_mat.add_argument("--sample", action="store_true", help="Generate a sample matrix using built-in demonstration schema")
862
+ p_api_mat.set_defaults(func=cmd_api_matrix)
863
+
864
+ # canvas-diff
865
+ p_canvas = subparsers.add_parser("canvas-diff", help="HTML5 Canvas visual regression diffing & blank check")
866
+ p_canvas.add_argument("canvas_args", nargs="*", help="Subcommand (compare/check-blank) and image paths")
867
+ p_canvas.set_defaults(func=cmd_canvas_diff)
868
+
869
+ # validate-groovy
870
+ p_groovy = subparsers.add_parser("validate-groovy", help="Pre-check Groovy scripts & keywords syntax balance")
871
+ p_groovy.add_argument("target", nargs="?", default=None, help="Target repository or file to validate")
872
+ p_groovy.add_argument("--dir", "-d", help="Explicit directory to scan")
873
+ p_groovy.set_defaults(func=cmd_validate_groovy)
874
+
875
+ # check-version
876
+ p_ver_sync = subparsers.add_parser("check-version", help="Verify universal version synchronization across all files")
877
+ p_ver_sync.add_argument("--expected-version", "-e", help="Expected version string (e.g. from git tag)", default=None)
878
+ p_ver_sync.set_defaults(func=cmd_check_version)
879
+
880
+ # mcp-excel
881
+ p_mcp_excel = subparsers.add_parser("mcp-excel", help="Start the JSON-RPC 2.0 stdio MCP Excel server")
882
+ p_mcp_excel.set_defaults(func=cmd_mcp_excel)
883
+
512
884
  args, unknown = parser.parse_known_args()
513
885
  if getattr(args, "offline", False):
514
886
  os.environ["AGENT_QA_OFFLINE"] = "1"
515
887
  print("🔒 [OFFLINE MODE] Air-Gapped Deterministic Mode Active. 100% Local AST & Heuristics (Zero External API calls).")
516
888
 
517
889
  if not args.subcommand:
890
+ # If running in an interactive terminal, offer a friendly quick-start menu
891
+ is_interactive = hasattr(sys.stdin, "isatty") and sys.stdin.isatty() and not os.environ.get("CI") and not os.environ.get("SYNAPSE_NON_INTERACTIVE")
892
+ if is_interactive:
893
+ print(f"\n{BOLD}{CYAN}======================================================================{RESET}")
894
+ print(f"{BOLD}{CYAN} 🧠 SYNAPSE HUB — INTERACTIVE TERMINAL WIZARD {RESET}")
895
+ print(f"{BOLD}{CYAN}======================================================================{RESET}")
896
+ print("Chào bạn! Hãy chọn nhanh một tác vụ để bắt đầu (hoặc nhấn Enter để xem Trợ Giúp):")
897
+ print(f" {BOLD}1.{RESET} 🩺 {BOLD}Doctor{RESET} - Kiểm tra chẩn đoán môi trường (Node, Python, Chrome, Git)")
898
+ print(f" {BOLD}2.{RESET} 🚀 {BOLD}Setup{RESET} - Thiết lập bảo vệ 1-click cho dự án kiểm thử mục tiêu")
899
+ print(f" {BOLD}3.{RESET} 🔍 {BOLD}Lint{RESET} - Quét phát hiện test pass ảo, 0 assert, sleep cứng")
900
+ print(f" {BOLD}4.{RESET} 🛡️ {BOLD}Verify{RESET} - Chạy kiểm tra 9 Cổng Chất Lượng DoD")
901
+ print(f" {BOLD}5.{RESET} 🌐 {BOLD}Welcome{RESET} - Mở trang Landing Page trực quan")
902
+ print(f" {BOLD}6.{RESET} ❓ {BOLD}Help{RESET} - Xem danh sách đầy đủ tất cả các lệnh CLI")
903
+ print(f"{BOLD}{CYAN}======================================================================{RESET}")
904
+ try:
905
+ choice = input(f"Nhập lựa chọn {BOLD}[1-6]{RESET} (mặc định: 6): ").strip()
906
+ except (EOFError, KeyboardInterrupt):
907
+ print()
908
+ sys.exit(0)
909
+
910
+ if choice == "1":
911
+ args.subcommand = "doctor"
912
+ return cmd_doctor(args)
913
+ elif choice == "2":
914
+ args.subcommand = "setup"
915
+ return cmd_setup(args)
916
+ elif choice == "3":
917
+ args.subcommand = "lint"
918
+ return cmd_lint(args)
919
+ elif choice == "4":
920
+ args.subcommand = "verify"
921
+ return cmd_verify(args)
922
+ elif choice == "5":
923
+ args.subcommand = "welcome"
924
+ return cmd_welcome(args)
925
+
518
926
  parser.print_help()
927
+ print("\n💡 Tip: Run 'npx synapse-hub welcome' (or 'npm start') to launch the visual landing page.")
519
928
  sys.exit(0)
520
929
 
521
- # Enforce cryptographic author attribution and anti-tamper provenance
930
+ # Enforce canonical author attribution and anti-tamper provenance
522
931
  from author_integrity import assert_integrity_or_raise
523
932
  assert_integrity_or_raise()
524
933
 
934
+ if getattr(args, "quiet", False):
935
+ os.environ["SYNAPSE_QUIET"] = "1"
936
+
525
937
  # Non-intrusive cached update notification (24h cache)
526
- if args.subcommand not in ("update", "mcp-serve", "version"):
938
+ if args.subcommand not in ("update", "mcp-serve", "version") and not getattr(args, "quiet", False):
527
939
  try:
528
940
  import update_sentinel
529
941
  update_sentinel.check_for_updates(force=False, notify=True)
530
- except Exception:
942
+ except (ImportError, OSError, TimeoutError):
531
943
  pass
532
944
 
533
945
  # Dispatch subcommand