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
@@ -20,6 +20,7 @@ Automated actions:
20
20
 
21
21
  import os
22
22
  import sys
23
+ import json
23
24
  import shutil
24
25
  import argparse
25
26
  from pathlib import Path
@@ -95,7 +96,7 @@ def detect_tech_stack(target_dir):
95
96
  "language": "Groovy",
96
97
  "page_dir": "Keywords/pages",
97
98
  "test_dir": "Scripts",
98
- "run_cmd": "./tools/run_headless_kre.sh (or katalonc CLI)"
99
+ "run_cmd": "katalonc -noSplash -runMode=console"
99
100
  }
100
101
 
101
102
  # 2. Playwright check
@@ -121,7 +122,21 @@ def detect_tech_stack(target_dir):
121
122
  "run_cmd": "npx cypress run --headless"
122
123
  }
123
124
 
124
- # 4. Pytest check
125
+ # 4. Selenium WebDriver check
126
+ req_txt = target_path / "requirements.txt"
127
+ has_selenium_req = req_txt.exists() and "selenium" in req_txt.read_text(encoding="utf-8", errors="ignore").lower()
128
+ has_selenium_code = any("selenium" in f.read_text(encoding="utf-8", errors="ignore") for f in list(target_path.glob("**/*.py"))[:10]) if list(target_path.glob("**/*.py")) else False
129
+ if has_selenium_req or has_selenium_code:
130
+ return {
131
+ "name": target_path.name,
132
+ "framework": "Selenium WebDriver",
133
+ "language": "Python",
134
+ "page_dir": "pages",
135
+ "test_dir": "tests",
136
+ "run_cmd": "pytest tests/ -v"
137
+ }
138
+
139
+ # 5. Pytest check
125
140
  if (target_path / "pytest.ini").exists() or list(target_path.glob("test_*.py")):
126
141
  return {
127
142
  "name": target_path.name,
@@ -143,7 +158,7 @@ def detect_tech_stack(target_dir):
143
158
  }
144
159
 
145
160
 
146
- def ensure_project_ai_guide(target_dir, stack_info):
161
+ def ensure_project_ai_guide(target_dir, stack_info, profile="full"):
147
162
  """Generates PROJECT_AI_GUIDE.md tailored to the target project if missing."""
148
163
  guide_path = os.path.join(target_dir, "PROJECT_AI_GUIDE.md")
149
164
  if os.path.exists(guide_path):
@@ -167,6 +182,14 @@ def ensure_project_ai_guide(target_dir, stack_info):
167
182
  content = content.replace("tests/e2e/... or Scripts/...", stack_info["test_dir"])
168
183
  content = content.replace("[e.g., npx playwright test --project=chromium --reporter=html,junit:results.xml]", stack_info["run_cmd"])
169
184
 
185
+ profile_line = f"- **Active Skills Profile:** `{profile.upper()}`"
186
+ if profile_line not in content:
187
+ lang_target = f"- **Script Language:** `{stack_info['language']}`"
188
+ if lang_target in content:
189
+ content = content.replace(lang_target, f"{lang_target}\n{profile_line}")
190
+ else:
191
+ content = content.replace("## 1. General System Under Test", f"## 1. General System Under Test\n{profile_line}")
192
+
170
193
  with open(guide_path, "w", encoding="utf-8") as f:
171
194
  f.write(content)
172
195
 
@@ -195,7 +218,7 @@ def install_git_pre_push_hook(target_dir):
195
218
  try:
196
219
  with open(manifest_file, "r", encoding="utf-8") as f:
197
220
  pkg_ver = json.load(f).get("version", pkg_ver)
198
- except Exception:
221
+ except (IOError, json.JSONDecodeError, KeyError):
199
222
  pass
200
223
 
201
224
  verify_all_script = os.path.join(SCRIPT_DIR, "verify_all.py").replace("\\", "/")
@@ -204,22 +227,31 @@ def install_git_pre_push_hook(target_dir):
204
227
  hook_snippet = f"""
205
228
  # --- Synapse-Hub Pre-Push Quality Gate (v{pkg_ver}) ---
206
229
  echo "\\n[AI-GUARD] Running Pre-Push Verification (Quality Gates DoD)..."
207
- if command -v npx >/dev/null 2>&1; then
208
- npx synapse-hub@{pkg_ver} verify || npx synapse-hub verify
209
- elif [ -f "{verify_all_script}" ]; then
230
+ # Prioritize local tool execution to run offline without network latency or registry dependency
231
+ if [ -f "{verify_all_script}" ]; then
210
232
  python3 "{verify_all_script}" || python "{verify_all_script}"
233
+ elif command -v synapse-hub >/dev/null 2>&1; then
234
+ synapse-hub verify
235
+ elif command -v agent-qa >/dev/null 2>&1; then
236
+ agent-qa verify
237
+ elif command -v npx >/dev/null 2>&1; then
238
+ npx --no-install synapse-hub verify 2>/dev/null || npx synapse-hub@{pkg_ver} verify
211
239
  fi
212
240
  if [ $? -ne 0 ]; then
213
241
  echo "\\n[AI-GUARD - REJECTED] Git Push aborted: Quality Gates verification failed!"
214
- echo "Please fix defects or run 'npx synapse-hub@{pkg_ver} verify' locally before pushing.\\n"
242
+ echo "Please fix defects or run 'python tools/verify_all.py' locally before pushing.\\n"
215
243
  exit 1
216
244
  fi
217
245
 
218
246
  echo "[AI-GUARD - PASSED] Quality Gates satisfied. Syncing project health report..."
219
- if command -v npx >/dev/null 2>&1; then
220
- npx synapse-hub@{pkg_ver} analyze || npx synapse-hub analyze
221
- elif [ -f "{analyze_script}" ]; then
247
+ if [ -f "{analyze_script}" ]; then
222
248
  python3 "{analyze_script}" || python "{analyze_script}"
249
+ elif command -v synapse-hub >/dev/null 2>&1; then
250
+ synapse-hub analyze
251
+ elif command -v agent-qa >/dev/null 2>&1; then
252
+ agent-qa analyze
253
+ elif command -v npx >/dev/null 2>&1; then
254
+ npx --no-install synapse-hub analyze 2>/dev/null || npx synapse-hub@{pkg_ver} analyze
223
255
  fi
224
256
  echo "[AI-GUARD - READY] Pushing to remote...\\n"
225
257
  # --- End Synapse-Hub Quality Gate ---
@@ -250,7 +282,7 @@ echo "[AI-GUARD - READY] Pushing to remote...\\n"
250
282
  # Attempt to make executable on Unix-like environments
251
283
  try:
252
284
  os.chmod(hook_file, 0o755)
253
- except Exception:
285
+ except OSError:
254
286
  pass
255
287
 
256
288
  print(f" {GREEN}[OK] Configured automated Pre-Push Git Hook:{RESET} {hook_file} (pinned to v{pkg_ver})")
@@ -260,11 +292,87 @@ echo "[AI-GUARD - READY] Pushing to remote...\\n"
260
292
  return False
261
293
 
262
294
 
295
+ def ensure_gitignore_protection(target_dir):
296
+ """Ensures local cache and generated AST intelligence artifacts are ignored in target repo."""
297
+ gitignore_path = os.path.join(target_dir, ".gitignore")
298
+ entries = [".synapse/", "repo_map.txt", "repo_map.json"]
299
+ try:
300
+ existing = ""
301
+ if os.path.exists(gitignore_path):
302
+ with open(gitignore_path, "r", encoding="utf-8", errors="ignore") as f:
303
+ existing = f.read()
304
+ missing = [e for e in entries if e not in existing]
305
+ if missing:
306
+ with open(gitignore_path, "a", encoding="utf-8") as f:
307
+ if existing and not existing.endswith("\n"):
308
+ f.write("\n")
309
+ f.write("\n# Synapse-Hub Local Cache & AST Intelligence\n")
310
+ for e in missing:
311
+ f.write(f"{e}\n")
312
+ print(f" {GREEN}[OK] Protected local cache in .gitignore:{RESET} {gitignore_path}")
313
+ return True
314
+ except OSError:
315
+ pass
316
+ return False
317
+
318
+
319
+ def install_git_post_merge_hook(target_dir):
320
+ """
321
+ Installs or appends an automated post-merge hook into target project's .git repository.
322
+ When a developer pulls code for the first time via 'git pull', this triggers the
323
+ welcome landing page once, then silently records it as completed.
324
+ """
325
+ git_dir = os.path.join(target_dir, ".git")
326
+ if not os.path.isdir(git_dir):
327
+ return False
328
+
329
+ hooks_dir = os.path.join(git_dir, "hooks")
330
+ os.makedirs(hooks_dir, exist_ok=True)
331
+ hook_file = os.path.join(hooks_dir, "post-merge")
332
+
333
+ welcome_script = os.path.join(SCRIPT_DIR, "welcome_page.py").replace("\\", "/")
334
+
335
+ hook_snippet = f"""# --- Synapse-Hub Post-Merge First-Pull Sentinel ---
336
+ # Security invariant: Never execute relative scripts from target repository
337
+ if [ -f "{welcome_script}" ]; then
338
+ python3 "{welcome_script}" --first-run 2>/dev/null || python "{welcome_script}" --first-run 2>/dev/null || true
339
+ elif command -v synapse-hub >/dev/null 2>&1; then
340
+ synapse-hub welcome --first-run 2>/dev/null || true
341
+ elif command -v agent-qa >/dev/null 2>&1; then
342
+ agent-qa welcome --first-run 2>/dev/null || true
343
+ fi
344
+ """
345
+ try:
346
+ if os.path.exists(hook_file):
347
+ with open(hook_file, "r", encoding="utf-8", errors="ignore") as f:
348
+ existing_content = f.read()
349
+
350
+ if "Synapse-Hub Post-Merge" in existing_content:
351
+ return True
352
+
353
+ final_content = existing_content.rstrip() + "\n" + hook_snippet
354
+ else:
355
+ final_content = "#!/bin/sh\n" + hook_snippet
356
+
357
+ with open(hook_file, "w", encoding="utf-8", newline="\n") as f:
358
+ f.write(final_content)
359
+
360
+ try:
361
+ os.chmod(hook_file, 0o755)
362
+ except OSError:
363
+ pass
364
+
365
+ print(f" {GREEN}[OK] Configured Post-Merge First-Pull Git Hook:{RESET} {hook_file}")
366
+ return True
367
+ except (OSError, UnicodeDecodeError):
368
+ return False
369
+
370
+
263
371
  def inject_antigravity_global_plugin():
264
372
  """
265
373
  Automatically injects Synapse-Hub into Antigravity's Global Plugin Directory
266
374
  (~/.gemini/config/plugins/synapse-hub).
267
- Ensures that running `npx synapse-hub setup` activates the 27 skills and 6 subagents
375
+ Ensures that running `npx synapse-hub setup` activates the 38 skills and 6 subagents
268
376
  globally across ALL projects in Google Antigravity.
269
377
  """
270
378
  try:
@@ -295,7 +403,7 @@ def inject_antigravity_global_plugin():
295
403
  if os.path.islink(dst):
296
404
  try:
297
405
  os.unlink(dst)
298
- except Exception:
406
+ except OSError:
299
407
  pass
300
408
  if sys.platform == "win32":
301
409
  try:
@@ -303,7 +411,7 @@ def inject_antigravity_global_plugin():
303
411
  if not os.path.exists(dst):
304
412
  _winapi.CreateJunction(src, dst)
305
413
  return
306
- except Exception:
414
+ except (OSError, ImportError, AttributeError):
307
415
  pass
308
416
  shutil.copytree(src, dst, dirs_exist_ok=True, ignore=shutil.ignore_patterns("__pycache__", "*.pyc", "*.tmp"))
309
417
 
@@ -405,7 +513,65 @@ def install_universal_ai_bridges(target_dir):
405
513
  return True
406
514
 
407
515
 
408
- def run_setup(target_repo):
516
+ def uninstall_setup(target_repo: str) -> int:
517
+ """Safely reverts and removes files installed by setup_project in the target repo."""
518
+ print(f"\n{BOLD}{YELLOW}======================================================================{RESET}")
519
+ print(f"{BOLD}{YELLOW} SYNAPSE HUB — REVERT & UNINSTALL SETUP {RESET}")
520
+ print(f"{BOLD}{YELLOW}======================================================================{RESET}")
521
+ print(f"Target Repository: {target_repo}")
522
+
523
+ reverted_items = 0
524
+
525
+ # 1. Remove PROJECT_AI_GUIDE.md
526
+ guide_file = os.path.join(target_repo, "PROJECT_AI_GUIDE.md")
527
+ if os.path.exists(guide_file):
528
+ os.remove(guide_file)
529
+ print(f" {GREEN}[REMOVED]{RESET} {guide_file}")
530
+ reverted_items += 1
531
+
532
+ # 2. Restore/Remove Git Pre-Push Hook
533
+ hook_file = os.path.join(target_repo, ".git", "hooks", "pre-push")
534
+ backup_file = os.path.join(target_repo, ".git", "hooks", "pre-push.bak")
535
+ if os.path.exists(backup_file):
536
+ if os.path.exists(hook_file):
537
+ os.remove(hook_file)
538
+ shutil.move(backup_file, hook_file)
539
+ print(f" {GREEN}[RESTORED]{RESET} Restored original pre-push hook from backup")
540
+ reverted_items += 1
541
+ elif os.path.exists(hook_file):
542
+ with open(hook_file, "r", encoding="utf-8", errors="ignore") as f:
543
+ content = f.read()
544
+ if "Synapse-Hub" in content or "synapse-hub" in content:
545
+ os.remove(hook_file)
546
+ print(f" {GREEN}[REMOVED]{RESET} Cleaned Synapse-Hub pre-push hook")
547
+ reverted_items += 1
548
+
549
+ # 3. Remove Cursor rule
550
+ cursor_rule = os.path.join(target_repo, ".cursor", "rules", "synapse-qa.mdc")
551
+ if os.path.exists(cursor_rule):
552
+ os.remove(cursor_rule)
553
+ print(f" {GREEN}[REMOVED]{RESET} {cursor_rule}")
554
+ reverted_items += 1
555
+
556
+ # 4. Remove Copilot instruction
557
+ copilot_file = os.path.join(target_repo, ".github", "copilot-instructions.md")
558
+ if os.path.exists(copilot_file):
559
+ os.remove(copilot_file)
560
+ print(f" {GREEN}[REMOVED]{RESET} {copilot_file}")
561
+ reverted_items += 1
562
+
563
+ # 5. Remove Windsurf rules
564
+ windsurf_file = os.path.join(target_repo, ".windsurfrules")
565
+ if os.path.exists(windsurf_file):
566
+ os.remove(windsurf_file)
567
+ print(f" {GREEN}[REMOVED]{RESET} {windsurf_file}")
568
+ reverted_items += 1
569
+
570
+ print(f"\n{GREEN}✅ Uninstall complete! Cleaned {reverted_items} configuration files/hooks.{RESET}\n")
571
+ return 0
572
+
573
+
574
+ def run_setup(target_repo, dry_run=False, profile="auto", no_global=True, no_git_hook=False, no_browser=True, open_browser=False):
409
575
  """Main execution entrypoint for automated project setup."""
410
576
  print(f"\n{BOLD}{CYAN}======================================================================{RESET}")
411
577
  print(f"{BOLD}{CYAN} AUTONOMOUS ZERO-COMMAND PROJECT BOOTSTRAP (AI-READY SETUP) {RESET}")
@@ -417,9 +583,42 @@ def run_setup(target_repo):
417
583
  print(f"🔍 Detected Stack : {BOLD}{stack_info['framework']}{RESET} ({stack_info['language']})")
418
584
  print(f"📂 Structure Scope : Pages: `{stack_info['page_dir']}` | Tests: `{stack_info['test_dir']}`\n")
419
585
 
586
+ # Resolve active profile
587
+ if profile == "auto":
588
+ fw = stack_info.get("framework", "").lower()
589
+ lang = stack_info.get("language", "").lower()
590
+ if "playwright" in fw:
591
+ profile = "playwright"
592
+ elif "selenium" in fw:
593
+ profile = "selenium"
594
+ elif "cypress" in fw:
595
+ profile = "cypress"
596
+ elif "katalon" in fw:
597
+ profile = "katalon"
598
+ elif "pytest" in fw or "python" in lang:
599
+ profile = "pytest"
600
+ else:
601
+ profile = "full"
602
+
603
+ print(f"🎯 Selected Profile: {BOLD}{profile.upper()}{RESET}")
604
+ if dry_run:
605
+ print(f"Operational Mode : {YELLOW}DRY-RUN (Simulating without modifying files on disk){RESET}\n")
606
+ else:
607
+ print(f"Operational Mode : APPLY CHANGES\n")
608
+
609
+ if dry_run:
610
+ print(f"{YELLOW}[DRY-RUN PREVIEW]{RESET}")
611
+ print(f" • Profile: {profile.upper()}")
612
+ print(f" • Would generate: {os.path.join(target_repo, 'PROJECT_AI_GUIDE.md')}")
613
+ print(f" • Would deploy AI bridges: .cursor/rules/synapse-qa.mdc, .github/copilot-instructions.md, .windsurfrules")
614
+ print(f" • Would install pre-push hook: {os.path.join(target_repo, '.git', 'hooks', 'pre-push')}")
615
+ print(f" • Would initialize: Central Agent Memory (~/.agent_memory/global_cache.db)")
616
+ print(f"\n{GREEN}✅ Dry-run completed successfully. Zero changes written to disk.{RESET}\n")
617
+ return 0
618
+
420
619
  # 2. Ensure PROJECT_AI_GUIDE.md & PROJECT_STATE.md
421
620
  print(f"{BOLD}[1/5] Checking Project AI Guide & State Anchor...{RESET}")
422
- guide_created = ensure_project_ai_guide(target_repo, stack_info)
621
+ guide_created = ensure_project_ai_guide(target_repo, stack_info, profile=profile)
423
622
  project_state.init_state(target_repo)
424
623
 
425
624
  # 3. Deploy Universal AI Bridges (Cursor, Claude Code, GitHub Copilot, Windsurf)
@@ -427,35 +626,66 @@ def run_setup(target_repo):
427
626
  bridges_deployed = install_universal_ai_bridges(target_repo)
428
627
 
429
628
  # 4. Inject Antigravity Global Plugin
430
- print(f"\n{BOLD}[3/5] Injecting Antigravity Global Plugin (~/.gemini/config/plugins)...{RESET}")
431
- plugin_injected = inject_antigravity_global_plugin()
432
-
433
- # 4.1 Initialize Central Agent Memory (SQLite Cache)
434
- try:
435
- import cache_resolver
436
- cache_resolver.init_db(seed=True)
437
- print(f" {GREEN}[OK] Initialized Central Agent Memory (SQLite):{RESET} ~/.agent_memory/global_cache.db")
438
- except Exception as e:
439
- print(f" ⚠️ Could not initialize memory cache: {e}")
629
+ plugin_injected = False
630
+ if no_global:
631
+ print(f"\n{BOLD}[3/5] Checking Antigravity Global Plugin (~/.gemini/config/plugins)...{RESET}")
632
+ print(f" {YELLOW}[SKIP] Local-only mode (default). Skipped global plugin injection (pass --global to install globally).{RESET}")
633
+ else:
634
+ print(f"\n{BOLD}[3/5] Injecting Antigravity Global Plugin (~/.gemini/config/plugins)...{RESET}")
635
+ plugin_injected = inject_antigravity_global_plugin()
440
636
 
441
- # 5. Install Pre-Push Git Hook
442
- print(f"\n{BOLD}[4/5] Installing Zero-Leakage Git Pre-Push Hook...{RESET}")
443
- hook_installed = install_git_pre_push_hook(target_repo)
637
+ # 4.1 Initialize Central Agent Memory (SQLite Cache)
638
+ try:
639
+ import cache_resolver
640
+ cache_resolver.init_db(seed=True)
641
+ print(f" {GREEN}[OK] Initialized Central Agent Memory (SQLite):{RESET} ~/.agent_memory/global_cache.db")
642
+ except Exception as e:
643
+ print(f" ⚠️ Could not initialize memory cache: {e}")
644
+
645
+ # 4.2 Protect local cache in .gitignore
646
+ ensure_gitignore_protection(target_repo)
647
+
648
+ # 5. Install Pre-Push & Post-Merge Git Hooks
649
+ hook_installed = False
650
+ if no_git_hook:
651
+ print(f"\n{BOLD}[4/5] Installing Zero-Leakage Git Hooks...{RESET}")
652
+ print(f" {YELLOW}[SKIP] Skipped Git hook installation (--no-git-hook).{RESET}")
653
+ else:
654
+ print(f"\n{BOLD}[4/5] Installing Zero-Leakage Git Hooks...{RESET}")
655
+ hook_installed = install_git_pre_push_hook(target_repo)
656
+ install_git_post_merge_hook(target_repo)
444
657
 
445
658
  # 6. Run 5-in-1 Comprehensive Health & AST Analysis
446
659
  print(f"\n{BOLD}[5/5] Executing Initial Health Audit & AST Mapping...{RESET}")
447
660
  analysis_code = analyze_project.run_full_analysis(target_repo)
448
661
 
662
+ # 7. Generate & Launch Interactive Visual Landing Page (Silent by default unless --open)
663
+ welcome_url = None
664
+ try:
665
+ from welcome_page import generate_welcome_page
666
+ should_open = (not no_browser) and open_browser and (not os.environ.get("CI")) and (not os.environ.get("HEADLESS")) and ("unittest" not in sys.modules) and ("pytest" not in sys.modules)
667
+ welcome_file = generate_welcome_page(
668
+ target_repo=target_repo,
669
+ stack_info=stack_info,
670
+ open_browser=should_open
671
+ )
672
+ welcome_url = f"file://{welcome_file}"
673
+ except (ImportError, OSError, ValueError):
674
+ pass
675
+
449
676
  print(f"\n{BOLD}{CYAN}======================================================================{RESET}")
450
677
  print(f"{BOLD}{CYAN} 🎉 PROJECT IS NOW 100% AI-READY (LEVEL 5 SETUP) {RESET}")
451
678
  print(f"{BOLD}{CYAN}======================================================================{RESET}")
452
679
  print(f" Target Framework : {stack_info['framework']}")
680
+ print(f" Active Profile : {profile.upper()}")
453
681
  print(f" AI Project Guide : {os.path.join(target_repo, 'PROJECT_AI_GUIDE.md')}")
454
682
  print(f" Universal Bridges : Cursor (.cursor/rules), Claude Code, Copilot, Windsurf")
455
683
  print(f" Antigravity Plugin : {'ACTIVE (~/.gemini/config/plugins/synapse-hub)' if plugin_injected else 'STANDALONE'}")
456
684
  print(f" AST Method Map : {os.path.join(target_repo, 'repo_map.txt')}")
457
685
  print(f" Health Report : {os.path.join(target_repo, 'PROJECT_HEALTH_REPORT.md')}")
458
686
  print(f" Pre-Push Sentinel : {'ACTIVE (.git/hooks/pre-push)' if hook_installed else 'MANUAL (No .git folder)'}")
687
+ if welcome_url:
688
+ print(f" Visual Landing Page : {welcome_url}")
459
689
  print(f"{BOLD}{CYAN}======================================================================{RESET}\n")
460
690
 
461
691
  return analysis_code
@@ -465,6 +695,24 @@ def main():
465
695
  parser = argparse.ArgumentParser(description="Autonomous Enterprise QA Project Setup")
466
696
  parser.add_argument("target", nargs="?", default=None, help="Target repository path to setup")
467
697
  parser.add_argument("--repo", "--path", dest="repo_path", default=None, help="Target repository path")
698
+ parser.add_argument(
699
+ "--profile",
700
+ default="auto",
701
+ choices=["auto", "core", "web-e2e", "api-perf", "full", "playwright", "pytest", "cypress", "katalon"],
702
+ help="Skills profile to install (auto, core, web-e2e, api-perf, full, playwright, pytest, cypress, katalon)"
703
+ )
704
+ parser.add_argument("--dry-run", action="store_true", help="Simulate setup actions without modifying disk")
705
+ parser.add_argument("--uninstall", action="store_true", help="Revert and remove files installed by setup_project")
706
+ parser.add_argument("--global", action="store_true", dest="enable_global", default=False,
707
+ help="Inject Synapse-Hub into Antigravity global plugins (~/.gemini/config/plugins) and central memory")
708
+ parser.add_argument("--local-only", "--no-global", action="store_true", dest="no_global", default=True,
709
+ help="Only configure project-local assets (PROJECT_AI_GUIDE.md, bridges), do not touch ~/.gemini (default: True)")
710
+ parser.add_argument("--no-git-hook", action="store_true",
711
+ help="Skip installing automated .git/hooks/pre-push")
712
+ parser.add_argument("--open", action="store_true", dest="open_browser",
713
+ help="Launch landing page in web browser")
714
+ parser.add_argument("--no-browser", "--no-open", action="store_true", dest="no_browser", default=True,
715
+ help="Do not automatically launch landing page in web browser (default: True)")
468
716
  args = parser.parse_args()
469
717
 
470
718
  try:
@@ -473,7 +721,23 @@ def main():
473
721
  print(f"❌ Error: {e}")
474
722
  return 1
475
723
 
476
- return run_setup(target_repo)
724
+ if args.uninstall:
725
+ return uninstall_setup(target_repo)
726
+
727
+ # When --open is explicitly requested, honor it
728
+ no_browser = False if getattr(args, "open_browser", False) else True
729
+ open_browser = bool(getattr(args, "open_browser", False))
730
+ use_no_global = False if getattr(args, "enable_global", False) else True
731
+
732
+ return run_setup(
733
+ target_repo,
734
+ dry_run=args.dry_run,
735
+ profile=args.profile,
736
+ no_global=use_no_global,
737
+ no_git_hook=args.no_git_hook,
738
+ no_browser=no_browser,
739
+ open_browser=open_browser
740
+ )
477
741
 
478
742
 
479
743
  if __name__ == "__main__":
@@ -247,6 +247,34 @@ def is_in_prohibition_context(content: str, start: int, end: int) -> bool:
247
247
  if any(m in full_line.lower() for m in ("e.g.", "such as", "example", "checks", "pattern", "trigger", "only active", "prohibited", "rule")):
248
248
  return True
249
249
 
250
+ # 7. Code Comment / Explanatory Header Guard
251
+ # If the match occurs on a comment line (#, //, *) with defensive/explanatory words
252
+ clean_line = full_line.strip()
253
+ if clean_line.startswith(("#", "//", "*")):
254
+ if any(w in clean_line.lower() for w in ("disallow", "block", "deny", "filter", "check", "prevent", "reject", "exclude", "ignore", "not", "defense", "forbidden", "prohibit")):
255
+ return True
256
+
257
+ # 8. Defensive Filter / Validation Guard in Source Code
258
+ # Recognizes checks that explicitly reject, raise, or block sensitive targets
259
+ if any(k in clean_line for k in ("raise PermissionError", "raise ValueError", "raise SecurityException", "is_link_local")):
260
+ return True
261
+ if re.search(r'\b(?:if|elif)\b.*(?:in|==|!=)\s*[\{\[\(]', clean_line) and any(k in clean_line for k in ("raise", "deny", "return False", "reject", "block", "error", "warning")):
262
+ return True
263
+
264
+ # 9. CLI Argument / Help String Guard
265
+ if "parser.add_argument" in full_line or "help=" in clean_line:
266
+ return True
267
+
268
+ # 10. Multi-line Defensive Filter (Lookahead for raise/return False)
269
+ subsequent_text = content[line_end:min(len(content), line_end + 300)]
270
+ if any(k in subsequent_text for k in ("raise PermissionError", "raise ValueError", "raise SecurityException", "return False")):
271
+ if re.search(r'\b(?:if|elif)\b', clean_line):
272
+ return True
273
+
274
+ # 11. Legitimate Plugin Manager Guard (e.g. ~/.gemini/config/plugins)
275
+ if "plugins" in full_line.lower() and any(k in full_line.lower() for k in ("plugin", "target", "dir", "install", "inject")):
276
+ return True
277
+
250
278
  return False
251
279
 
252
280
 
@@ -931,6 +959,7 @@ def scan_target(target_path: str) -> ScanReport:
931
959
  scanned_count = 0
932
960
 
933
961
  SKIP_DIRS = {".git", ".venv", "venv", "node_modules", "__pycache__", ".pytest_cache", "dist", "build"}
962
+ SKIP_FILES = {"skillspector.py"}
934
963
  SCANNABLE_EXTS = {".md", ".py", ".json", ".yaml", ".yml", ".sh", ".ps1", ".txt", ".ts", ".js"}
935
964
 
936
965
  if path_obj.is_file():
@@ -940,6 +969,8 @@ def scan_target(target_path: str) -> ScanReport:
940
969
  for root, dirs, files in os.walk(path_obj):
941
970
  dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
942
971
  for file in files:
972
+ if file in SKIP_FILES:
973
+ continue
943
974
  ext = os.path.splitext(file)[1].lower()
944
975
  if ext in SCANNABLE_EXTS:
945
976
  full_p = os.path.join(root, file)