from flask import Blueprint, render_template, flash, jsonify from jinja2 import TemplateNotFound from markupsafe import escape from html.parser import HTMLParser import json import logging import os import os.path import re from pathlib import Path # Strict allowlists for URL-derived values used in path and script operations. _SAFE_PLUGIN_ID_RE = re.compile(r'^[a-zA-Z0-9_-]{1,64}$') _SAFE_WEB_UI_FILE_RE = re.compile(r'^[a-zA-Z0-9_-]{1,64}\.html$') from src.web_interface.secret_helpers import mask_secret_fields logger = logging.getLogger(__name__) # Will be initialized when blueprint is registered config_manager = None plugin_manager = None plugin_store_manager = None pages_v3 = Blueprint('pages_v3', __name__) class _SettingsIndexParser(HTMLParser): """Extract searchable settings fields from a rendered partial's HTML. Captures one entry per ``