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
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Markdown to Excel (.xlsx) Enterprise Converter
4
+ ------------------------------------------------
5
+ Parses Markdown Test Case tables and converts them into professional,
6
+ styled Excel workbooks with:
7
+ - Corporate header styling (Navy Blue, bold, centered)
8
+ - Color-coded Risk Level (High=Red, Med=Yellow, Low=Green)
9
+ - Color-coded Priority (Critical/High/Med/Low) and Automatable badges
10
+ - Frozen top header row (A2 freeze pane)
11
+ - AutoFilter enabled across all columns
12
+ - Smart column widths and multi-line text wrapping (replaces <br> with newlines)
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ import re
18
+ import argparse
19
+ from typing import List, Dict, Any, Tuple
20
+
21
+ # UTF-8 terminal encoding
22
+ if hasattr(sys.stdout, 'reconfigure'):
23
+ try:
24
+ sys.stdout.reconfigure(encoding='utf-8')
25
+ sys.stderr.reconfigure(encoding='utf-8')
26
+ except Exception:
27
+ pass
28
+
29
+ try:
30
+ import openpyxl
31
+ from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
32
+ from openpyxl.utils import get_column_letter
33
+ OPENPYXL_AVAILABLE = True
34
+ except ImportError:
35
+ OPENPYXL_AVAILABLE = False
36
+
37
+
38
+ def clean_cell_content(cell: str) -> str:
39
+ """Cleans Markdown cell formatting: replaces <br> with newlines, strips backticks."""
40
+ text = cell.strip()
41
+ text = re.sub(r'<br\s*/?>', '\n', text, flags=re.IGNORECASE)
42
+ text = re.sub(r'`([^`]*)`', r'\1', text)
43
+ # Strip leading/trailing pipes if present in split artifact
44
+ text = text.strip()
45
+ return text
46
+
47
+
48
+ def parse_markdown_tables(content: str) -> List[Tuple[List[str], List[List[str]]]]:
49
+ """
50
+ Parses all Markdown tables in a string.
51
+ Returns a list of tuples: (headers, rows).
52
+ """
53
+ lines = content.splitlines()
54
+ tables = []
55
+
56
+ current_header = None
57
+ current_rows = []
58
+ in_table = False
59
+
60
+ for line in lines:
61
+ stripped = line.strip()
62
+ if not stripped.startswith('|') or not stripped.endswith('|'):
63
+ if in_table and current_header and current_rows:
64
+ tables.append((current_header, current_rows))
65
+ current_header = None
66
+ current_rows = []
67
+ in_table = False
68
+ continue
69
+
70
+ # Split cells
71
+ raw_cells = [c.strip() for c in stripped[1:-1].split('|')]
72
+
73
+ # Check if separator row (|---|---|)
74
+ if all(re.match(r'^\s*:?-+:?\s*$', c) for c in raw_cells if c):
75
+ in_table = True
76
+ continue
77
+
78
+ if not in_table:
79
+ # First line with pipes is potential header
80
+ current_header = [clean_cell_content(c) for c in raw_cells]
81
+ else:
82
+ # Data row
83
+ cleaned_row = [clean_cell_content(c) for c in raw_cells]
84
+ # Ensure row length matches header
85
+ if current_header:
86
+ if len(cleaned_row) < len(current_header):
87
+ cleaned_row.extend([''] * (len(current_header) - len(cleaned_row)))
88
+ elif len(cleaned_row) > len(current_header):
89
+ cleaned_row = cleaned_row[:len(current_header)]
90
+ current_rows.append(cleaned_row)
91
+
92
+ if in_table and current_header and current_rows:
93
+ tables.append((current_header, current_rows))
94
+
95
+ return tables
96
+
97
+
98
+ def create_styled_excel(tables: List[Tuple[List[str], List[List[str]]]], output_path: str, sheet_title: str = "Test Cases") -> int:
99
+ """Builds and styles the Excel workbook using openpyxl."""
100
+ if not OPENPYXL_AVAILABLE:
101
+ raise RuntimeError("openpyxl is not installed. Run: pip install openpyxl")
102
+
103
+ wb = openpyxl.Workbook()
104
+ ws = wb.active
105
+ ws.title = sheet_title[:31] # Excel limits sheet names to 31 chars
106
+
107
+ # Palette
108
+ NAVY_BLUE = "1F4E78"
109
+ WHITE = "FFFFFF"
110
+ BORDER_COLOR = "D9D9D9"
111
+
112
+ # Styles
113
+ header_fill = PatternFill(start_color=NAVY_BLUE, end_color=NAVY_BLUE, fill_type="solid")
114
+ header_font = Font(name="Calibri", size=11, bold=True, color=WHITE)
115
+ header_align = Alignment(horizontal="center", vertical="center", wrap_text=True)
116
+
117
+ cell_border = Border(
118
+ left=Side(style='thin', color=BORDER_COLOR),
119
+ right=Side(style='thin', color=BORDER_COLOR),
120
+ top=Side(style='thin', color=BORDER_COLOR),
121
+ bottom=Side(style='thin', color=BORDER_COLOR)
122
+ )
123
+
124
+ # Status badges
125
+ fill_high = PatternFill(start_color="FCE4D6", fill_type="solid") # Soft Red
126
+ font_high = Font(name="Calibri", size=10, bold=True, color="C00000")
127
+
128
+ fill_med = PatternFill(start_color="FFF2CC", fill_type="solid") # Soft Yellow
129
+ font_med = Font(name="Calibri", size=10, bold=True, color="B25900")
130
+
131
+ fill_low = PatternFill(start_color="E2EFDA", fill_type="solid") # Soft Green
132
+ font_low = Font(name="Calibri", size=10, bold=True, color="375623")
133
+
134
+ fill_yes = PatternFill(start_color="E2EFDA", fill_type="solid")
135
+ font_yes = Font(name="Calibri", size=10, color="276A3C", bold=True)
136
+
137
+ fill_no = PatternFill(start_color="F2F2F2", fill_type="solid")
138
+ font_no = Font(name="Calibri", size=10, color="595959")
139
+
140
+ # Combine tables if multiple or take the primary table
141
+ primary_headers = tables[0][0]
142
+ all_rows = []
143
+ for h, rows in tables:
144
+ # If headers match, stack rows; otherwise keep all
145
+ all_rows.extend(rows)
146
+
147
+ # 1. Write Header
148
+ ws.append(primary_headers)
149
+ ws.row_dimensions[1].height = 28
150
+
151
+ for col_idx in range(1, len(primary_headers) + 1):
152
+ cell = ws.cell(row=1, column=col_idx)
153
+ cell.fill = header_fill
154
+ cell.font = header_font
155
+ cell.alignment = header_align
156
+ cell.border = cell_border
157
+
158
+ # Standard Column Width Presets
159
+ width_map = {
160
+ "tc id": 16,
161
+ "id": 14,
162
+ "module": 18,
163
+ "requirement": 24,
164
+ "feature": 24,
165
+ "risk": 12,
166
+ "risk level": 12,
167
+ "test title": 36,
168
+ "title": 36,
169
+ "scenario": 36,
170
+ "pre-condition": 28,
171
+ "test steps": 45,
172
+ "steps": 45,
173
+ "expected result": 45,
174
+ "expected": 45,
175
+ "priority": 12,
176
+ "test data": 28,
177
+ "data": 28,
178
+ "automatable": 14,
179
+ "auto type": 12,
180
+ "tags": 22
181
+ }
182
+
183
+ # Identify column types by header name
184
+ col_types = {}
185
+ for idx, header in enumerate(primary_headers, 1):
186
+ h_lower = header.lower().strip()
187
+ col_types[idx] = h_lower
188
+
189
+ # 2. Write Data Rows
190
+ current_row_idx = 2
191
+ for row_data in all_rows:
192
+ ws.append(row_data)
193
+ ws.row_dimensions[current_row_idx].height = None # Auto height for wrapped text
194
+
195
+ for col_idx, val in enumerate(row_data, 1):
196
+ cell = ws.cell(row=current_row_idx, column=col_idx)
197
+ cell.border = cell_border
198
+ cell.font = Font(name="Calibri", size=10)
199
+
200
+ h_name = col_types.get(col_idx, "")
201
+ val_str = str(val).strip()
202
+ val_lower = val_str.lower()
203
+
204
+ # Alignments & Styling based on column semantic
205
+ if any(k in h_name for k in ["steps", "expected", "title", "scenario", "pre-condition"]):
206
+ cell.alignment = Alignment(horizontal="left", vertical="top", wrap_text=True)
207
+ elif any(k in h_name for k in ["risk", "priority", "automatable", "auto type", "id"]):
208
+ cell.alignment = Alignment(horizontal="center", vertical="top")
209
+ else:
210
+ cell.alignment = Alignment(horizontal="left", vertical="top")
211
+
212
+ # Badges
213
+ if "risk" in h_name or "priority" in h_name:
214
+ if "high" in val_lower or "critical" in val_lower:
215
+ cell.fill = fill_high
216
+ cell.font = font_high
217
+ elif "med" in val_lower:
218
+ cell.fill = fill_med
219
+ cell.font = font_med
220
+ elif "low" in val_lower:
221
+ cell.fill = fill_low
222
+ cell.font = font_low
223
+ elif "automatable" in h_name:
224
+ if val_lower in ["yes", "true"]:
225
+ cell.fill = fill_yes
226
+ cell.font = font_yes
227
+ elif val_lower in ["no", "false"]:
228
+ cell.fill = fill_no
229
+ cell.font = font_no
230
+ elif "partial" in val_lower:
231
+ cell.fill = fill_med
232
+ cell.font = font_med
233
+
234
+ current_row_idx += 1
235
+
236
+ total_rows = len(all_rows)
237
+
238
+ # 3. Freeze Header Row
239
+ ws.freeze_panes = "A2"
240
+
241
+ # 4. Enable AutoFilter
242
+ last_col_letter = get_column_letter(len(primary_headers))
243
+ ws.auto_filter.ref = f"A1:{last_col_letter}{total_rows + 1}"
244
+
245
+ # 5. Set Optimal Column Widths
246
+ for col_idx, header in enumerate(primary_headers, 1):
247
+ h_lower = header.lower().strip()
248
+ col_letter = get_column_letter(col_idx)
249
+
250
+ # Check presets
251
+ target_width = None
252
+ for key, width in width_map.items():
253
+ if key in h_lower:
254
+ target_width = width
255
+ break
256
+
257
+ if not target_width:
258
+ # Dynamic max calculation
259
+ max_len = len(header)
260
+ for r in all_rows:
261
+ if col_idx - 1 < len(r):
262
+ lines = str(r[col_idx - 1]).split('\n')
263
+ for l in lines:
264
+ if len(l) > max_len:
265
+ max_len = len(l)
266
+ target_width = min(max(max_len + 3, 12), 45)
267
+
268
+ ws.column_dimensions[col_letter].width = target_width
269
+
270
+ # Ensure parent dir exists
271
+ os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
272
+ wb.save(output_path)
273
+ return total_rows
274
+
275
+
276
+ def main():
277
+ parser = argparse.ArgumentParser(description="Convert Markdown Test Cases into Styled Excel (.xlsx)")
278
+ parser.add_argument("input", help="Path to input Markdown file (.md)")
279
+ parser.add_argument("-o", "--output", help="Path to output Excel file (.xlsx). Defaults to same name as input.")
280
+ parser.add_argument("--sheet-name", default="Test Cases", help="Worksheet title (default: Test Cases)")
281
+
282
+ args = parser.parse_args()
283
+
284
+ if not os.path.exists(args.input):
285
+ print(f"❌ Error: Input file not found: {args.input}", file=sys.stderr)
286
+ sys.exit(1)
287
+
288
+ output_path = args.output
289
+ if not output_path:
290
+ base, _ = os.path.splitext(args.input)
291
+ output_path = base + ".xlsx"
292
+
293
+ with open(args.input, "r", encoding="utf-8") as f:
294
+ content = f.read()
295
+
296
+ tables = parse_markdown_tables(content)
297
+ if not tables:
298
+ print(f"❌ Error: No valid Markdown tables found in {args.input}", file=sys.stderr)
299
+ sys.exit(1)
300
+
301
+ print(f"📖 Found {len(tables)} table(s) in: {args.input}")
302
+ total = create_styled_excel(tables, output_path, args.sheet_name)
303
+ print(f"✅ Successfully converted {total} test case(s) to styled Excel: {output_path}")
304
+
305
+
306
+ if __name__ == "__main__":
307
+ main()