[general]
name=TerraPulse
qgisMinimumVersion=3.34
qgisMaximumVersion=3.99
description=AI-powered ground deformation and subsidence intelligence using Sentinel-1 InSAR
version=0.2.14
author=OSMAN IBRAHIM
email=osmangeomatics93@gmail.com
about=TerraPulse lets planners, engineers, and NGO workers draw an Area of Interest in QGIS,
    select a time window, and receive an interpreted deformation map with risk attribution —
    no SAR or InSAR expertise required. Powered by Sentinel-1 SBAS-InSAR, scikit-learn
    classification, and optional LLM-generated plain-language reports.

    Features:
    - Draw or import AOI, select time window and processing mode
    - Queries Sentinel-1 SLC stacks from Copernicus Data Space STAC API
    - Runs InSAR processing locally via Docker/PyGMTSAR
    - ML pixel classification: stable / linear / seasonal / accelerating / anomalous
    - OSM infrastructure overlay with risk ranking (buildings, roads, pipelines)
    - PDF/HTML report with optional AI-written narrative (Anthropic Claude)
    - YAML provenance recipe + STAC 1.0 item for full reproducibility
    - Persistent settings (CDSE credentials, API keys, output directory)
    - Non-blocking background processing via QGIS task manager

    Requirements:
    - QGIS 3.34 or later
    - Python 3.11 or later
    - Docker Desktop (for local InSAR processing)
    - Free Copernicus Data Space Ecosystem account (dataspace.copernicus.eu)

tracker=https://github.com/Osman-Geomatics93/TerraPulse-Plugin/issues
repository=https://github.com/Osman-Geomatics93/TerraPulse-Plugin
homepage=https://github.com/Osman-Geomatics93/TerraPulse-Plugin#readme

tags=InSAR,SAR,Sentinel-1,subsidence,deformation,risk,AI,machine learning,geohazard,Copernicus

icon=resources/icons/terrapulse_32.png

experimental=True
deprecated=False
server=False

hasProcessingProvider=False

changelog=
    0.2.14 (2026-05-29)
    - Remove the last plugins.qgis.org security-scan blocker: detect-secrets
      was flagging `cdse_password="secret"` in two docstring usage examples
      (engine_ipc.py and downloader.py) as a "Secret Keyword". Replaced the
      placeholder with `os.environ["CDSE_PW"]` so the docstring stays valid
      Python and detect-secrets has nothing to flag. Local scan: 0 findings.

    0.2.13 (2026-05-29)
    - Fix Discover Scenes crash on QGIS 3.44: the bundled pydantic and
      pydantic_core are version-mismatched ("ImportError: cannot import
      name 'validate_core_schema'"), so importing terrapulse_core.stac.models
      blew up. Refactored models.py to use standard-library @dataclass instead
      of pydantic.BaseModel — same public API, no third-party dependencies,
      verified working in QGIS 3.44.6 Python 3.12.

    0.2.12 (2026-05-29)
    - Fix "Discover Scenes" button which failed with ModuleNotFoundError
      for users who installed from plugins.qgis.org. The button calls
      STACClient in the QGIS process, but QGIS Python doesn't have
      pystac_client installed. Refactored STACClient to use plain `requests`
      against CDSE's HTTP STAC API — same behaviour, no extra Python deps.

    0.2.11 (2026-05-29)
    - Suppress 4 additional Bandit B105/B107 false positives that blocked
      0.2.10 from the plugins.qgis.org security scan:
      * settings_manager.py: KEY_CDSE_PASSWORD/KEY_ANTHROPIC_KEY constants
        (the strings are QgsSettings KEY NAMES, not credentials)
      * insar_task.py / engine_ipc.py: cdse_password parameter default ""
        (it's an unset-by-default placeholder, not a real password)
      * downloader.py: _TOKEN_URL is the public CDSE OAuth endpoint URL,
        flagged because it contains the word "token"

    0.2.10 (2026-05-29)
    - Pass plugins.qgis.org security scan. Fix the two Bandit medium-severity
      issues that blocked 0.2.9 from being approved:
      * engine_ipc.py: use tempfile.gettempdir() instead of hardcoded "/tmp"
        for the harmless ping-mount target (B108).
      * ml/classifier.py: add `# nosec B301` to the pickle.load call that
        loads the trusted plugin-shipped ML model (B301).

    0.2.9 (2026-05-29)
    - CRITICAL: fix CDSE 401 "invalid_grant" caused by a QgsSettings key
      mismatch in main_dialog.py. The Settings dialog saves the CDSE password
      to "terrapulse/cdse_credential" (via SettingsManager) but main_dialog
      was reading it from "terrapulse/cdse_password" (raw QgsSettings) — a
      different key that's never written. Result: every InSAR run sent an
      empty password to CDSE and got rejected. Now uses SettingsManager
      consistently.

    0.2.8 (2026-05-28)
    - STAC client now retries transient CDSE failures (HTTP 502/503/504,
      connection drops) with exponential backoff (5s, 20s, 60s).
    - Strip CDSE's nginx HTML error pages from user-facing error messages:
      instead of dumping <html><head><title>502 Bad Gateway... the dialog
      now shows "Copernicus Data Space is temporarily unavailable (HTTP 502)".

    0.2.7 (2026-05-28)
    - engine_ipc: explicitly close subprocess stdin/stdout/stderr after the
      Docker engine exits, instead of leaving them for the Python garbage
      collector. Silences ResourceWarning: unclosed file <_io.TextIOWrapper>
      that appeared in QGIS logs after every failed/early-exit InSAR run.

    0.2.6 (2026-05-28)
    - Strip __pycache__ from vendored terrapulse_core before qgis-plugin-ci
      packaging. The earlier "Validate __version__.py" workflow step imports
      terrapulse_core and creates .pyc files; cp -r copied them into the
      vendored directory; plugins.qgis.org rejected the upload with
      "For security reasons, zip file cannot contain .pyc file".

    0.2.5 (2026-05-28)
    - Fix release workflow: qgis-plugin-ci uses git ls-files for packaging, so
      the gitignored vendored terrapulse_core copy was excluded from the zip
      uploaded to plugins.qgis.org (the GitHub release zip was already correct).
      release.yml now runs `git add -f` on the vendored directory so it appears
      in git ls-files during CI builds.

    0.2.4 (2026-05-28)
    - Fix critical packaging bug: terrapulse_core was missing from the released
      QGIS plugin zip, causing ModuleNotFoundError on every InSAR run
    - release.yml now vendors terrapulse_core into the plugin zip
    - plugin/__init__.py finds bundled terrapulse_core (production) or repo
      source tree (dev) and adds it to sys.path
    - Default Docker image hardcoded to osmanos93/terrapulse-pygmtsar:latest
      in insar_task.py and settings_dialog.py (was bare local name)
    - main_dialog now reads docker_image and max_scenes from SettingsManager
    - Better error message when image not pulled: suggests docker pull from
      Docker Hub instead of only the docker build instruction
    - Distinguish ModuleNotFoundError from real Docker errors in pre-check

    0.2.3 (2026-05-26)
    - Fix security scan: suppress detect-secrets false positives in settings_manager.py

    0.2.2 (2026-05-26)
    - Default Docker image updated to osmanos93/terrapulse-pygmtsar:latest (Docker Hub)

    0.2.1 (2026-05-26)
    - Author name updated to OSMAN IBRAHIM

    0.2.0 (2026-05-25)
    - Fixed download crash at ~16 pct progress (pipe deadlock + double disk usage)
    - Parallel HTTP Range download for 4x faster Sentinel-1 SLC acquisition
    - Full IPC pipeline (Docker subprocess JSON protocol)
    - PyGMTSAR engine server, CDSE OAuth2 downloader, COG writer
    - STACDiscoveryTask and InSARTask background workers
    - AOI rubber-band map tool, velocity/coherence layer loaders
    - RandomForest deformation classifier (5 classes: stable/linear/seasonal/accelerating/anomalous)
    - OSM infrastructure overlay with composite risk score
    - PDF/HTML report renderer with optional AI narrative
    - YAML provenance recipe + STAC 1.0 item
    - Settings dialog (CDSE credentials, API keys, output directory)
    - 241 automated tests, Python 3.11 and 3.12, Ubuntu and Windows CI