Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

467 lines
21 KiB
YAML

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0 (frozen)
hooks:
- id: check-yaml
exclude: cookiecutter-docker/.*
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
args: ['--maxkb=1000']
- id: check-case-conflict
- id: forbid-new-submodules
# Secret scanning — gitleaks is the sole pre-commit secret scanner.
# detect-secrets was removed because its line-number-based .secrets.baseline
# caused constant merge conflicts and 173 KB of churn. gitleaks uses
# path/regex-based allowlists (.gitleaks.toml) that are stable across
# line changes. Additional CI coverage: Semgrep (p/secrets), Bearer (secrets).
- repo: https://github.com/adrienverge/yamllint
rev: v1.37.0
hooks:
- id: yamllint
args: ['-c', '.yamllint.yaml']
exclude: cookiecutter-docker/.*
- repo: https://github.com/gitleaks/gitleaks
rev: 2ca41cc1372d1e939a6a879f18cdc19fc1cac1ce # v8.30.0 (frozen)
hooks:
- id: gitleaks
name: Detect secrets with gitleaks
description: "Detect hardcoded secrets like passwords, API keys, and tokens"
args: ["--config", ".gitleaks.toml"]
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: 745eface02aef23e168a8afb6b5737818efbea95 # v0.11.0.1 (frozen)
hooks:
- id: shellcheck
name: Shellcheck - lint shell scripts
description: "Shell script static analysis tool"
# ESLint runs as a local hook so it resolves plugins from the project's
# node_modules (mirrors-eslint installs into its own cache, which flat
# config's `import` cannot reach). Requires `npm install` first.
- repo: local
hooks:
- id: eslint
name: ESLint - lint JavaScript
entry: npx eslint --config eslint.config.js
language: system
files: \.(js|mjs)$
exclude: (node_modules|dist|build|\.min\.js|static/dist)
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: aca6d4c8045a504e2812ea4bedff1d0a09e437bc # v0.15.8 (frozen)
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/rhysd/actionlint
rev: a443f344ff32813837fa49f7aa6cbc478d770e62 # v1.7.9 (frozen)
hooks:
- id: actionlint
name: Lint GitHub Actions workflows
description: "Static checker for GitHub Actions workflow files"
files: ^\.github/workflows/.*\.ya?ml$
- repo: local
hooks:
- id: check-workflow-test-paths
name: Check workflow test paths exist
entry: .pre-commit-hooks/check-workflow-test-paths.py
language: script
files: ^\.github/workflows/.*\.ya?ml$
description: "Ensure pytest paths referenced in GitHub workflows exist
on disk, so a renamed/deleted test file can't silently break a CI
gate with exit code 5 (no tests collected)"
- id: check-release-gate-needs
name: Check release-gate SARIF needs lists are in sync
entry: .pre-commit-hooks/check-release-gate-needs.py
language: script
files: ^\.github/workflows/.*\.ya?ml$
pass_filenames: false
description: "Every scan that uploads SARIF to code scanning must be in
both release-gate.yml needs lists (check-code-scanning-alerts and
release-gate-summary); a missing one can silently bypass the gate (#4817)"
- id: custom-code-checks
name: Custom Code Quality Checks
entry: .pre-commit-hooks/custom-checks.py
language: script
files: \.py$
description: "Check for loguru usage, logger.exception vs logger.error, raw
SQL, redundant {e} in logger.exception, and non-UTC datetime usage"
- id: check-env-vars
name: Environment Variable Access Check
entry: .pre-commit-hooks/check-env-vars.py
language: script
files: \.py$
description: "Ensure environment variables are accessed through SettingsManager"
- id: check-author-identity
name: Author identity consistency
entry: .pre-commit-hooks/check-author-identity.py
language: script
always_run: true
pass_filenames: false
description: "Ensure commits by a declared project author use that author's declared identity"
- id: file-whitelist-check
name: File Whitelist Security Check
entry: .pre-commit-hooks/file-whitelist-check.sh
language: script
types: [file]
description: "Check for allowed file types and file sizes"
- id: check-deprecated-db-connection
name: Check for deprecated get_db_connection usage
entry: .pre-commit-hooks/check-deprecated-db.py
language: script
files: \.py$
description: "Ensure code uses per-user database connections instead of deprecated
shared database"
- id: check-ldr-db-usage
name: Check for ldr.db usage
entry: .pre-commit-hooks/check-ldr-db.py
language: script
files: \.py$
description: "Prevent usage of shared ldr.db database - all data must use
per-user encrypted databases"
- id: check-journal-quality-readonly
name: Check journal_quality.db opens are read-only
entry: .pre-commit-hooks/check-journal-quality-readonly.py
language: script
files: \.py$
description: "The compiled journal-quality DB has exactly one writer
(build_db). All other consumers must open it with SQLite mode=ro."
- id: check-research-id-type
name: Check for incorrect research_id type hints
entry: .pre-commit-hooks/check-research-id-type.py
language: script
files: \.py$
description: "Ensure research_id is always treated as string/UUID, never as
int"
- id: check-deprecated-settings-wrapper
name: Check for deprecated get_setting_from_db_main_thread usage
entry: .pre-commit-hooks/check-deprecated-settings-wrapper.py
language: script
files: \.py$
description: "Prevent usage of redundant get_setting_from_db_main_thread wrapper
- use SettingsManager directly"
- id: check-datetime-timezone
name: Check DateTime columns use UtcDateTime
entry: scripts/pre_commit/check_datetime_timezone.py
language: script
files: \.py$
description: "All DateTime columns (models and migrations) must use UtcDateTime from sqlalchemy_utc"
- id: check-session-context-manager
name: Check for try/finally session patterns
entry: .pre-commit-hooks/check-session-context-manager.py
language: script
files: \.py$
description: "Ensure SQLAlchemy sessions use context managers instead of try/finally
blocks"
- id: check-settings-manager-thread-safety
name: Check get_settings_manager() thread-safety
entry: .pre-commit-hooks/check-settings-manager-thread-safety.py
language: script
files: \.py$
exclude: ^tests/
description: "Ensure get_settings_manager() passes db_session in background-thread
code"
- id: check-settings-key-namespace
name: Check settings key namespace
entry: .pre-commit-hooks/check-settings-key-namespace.py
language: script
files: \.(py|js|mjs)$
exclude: ^(tests/|\.pre-commit-hooks/)
description: "Ensure hardcoded settings keys match allowed prefixes from
settings_routes.py"
- id: check-pathlib-usage
name: Check for os.path usage
entry: .pre-commit-hooks/check-pathlib-usage.py
language: script
files: \.py$
description: "Enforce using pathlib.Path instead of os.path for better cross-platform
compatibility"
- id: check-no-external-resources
name: Check for external CDN/resource references
entry: .pre-commit-hooks/check-external-resources.py
language: script
files: \.(html|js|css|py)$
exclude: ^tests/
description: "Ensure no external CDN URLs or external resources are referenced
in the codebase"
- id: check-target-blank-rel
name: Check external target=_blank links have rel=noopener noreferrer
entry: .pre-commit-hooks/check-target-blank-rel.py
language: script
files: \.(html|js|jsx|ts|tsx|mjs|jinja2|jinja)$
exclude: ^(tests?/|vendor/|.*/vendor/)
description: "Prevent tabnabbing and Referer leakage on external
target=_blank links"
- id: check-css-class-prefix
name: Check CSS class names have ldr- prefix
entry: .pre-commit-hooks/check-css-class-prefix.py
language: script
files: \.(css|html|js|jsx|ts|tsx|mjs)$
exclude: (tests?/|spec\.|test\.|\.test\.|\.spec\.)
description: "Ensure all LDR-specific CSS classes are prefixed with 'ldr-'
to prevent conflicts"
- id: check-sensitive-logging
name: Check for sensitive data in logging
entry: .pre-commit-hooks/check-sensitive-logging.py
language: script
files: \.py$
exclude: ^(tests/|examples/)
description: "Prevent logging of sensitive data"
- id: check-url-security
name: Check for unsafe URL handling in JavaScript
entry: .pre-commit-hooks/check-url-security.py
language: script
files: \.js$
description: "Ensure JavaScript code validates URLs to prevent XSS attacks"
- id: check-double-escaping
name: Check for double HTML escaping in JavaScript
entry: .pre-commit-hooks/check-double-escaping.py
language: script
files: \.js$
exclude: (tests?/|spec\.|test\.|\.test\.|\.spec\.)
description: "Detect escapeHtml() inside functions that already escape internally
(showError, showSuccess, showInfo, showAlert)"
- id: check-raw-console
name: Check for raw console.* calls in JavaScript
entry: .pre-commit-hooks/check-raw-console.py
language: script
files: \.js$
exclude: (tests?/|spec\.|test\.|\.test\.|\.spec\.)
description: "Ensure JS files use SafeLogger instead of raw console.log/error/warn"
- id: check-bearer-disable
name: Check bearer:disable directives are well-formed
entry: .pre-commit-hooks/check-bearer-disable.py
language: script
files: ^src/local_deep_research/.*\.(py|js)$
description: "Bearer ignores a bearer:disable directive unless it is the bare
rule id on its own line above the statement; reject same-line or
trailing-prose directives that would silently suppress nothing"
- id: check-loguru-formatting
name: Check loguru formatting style
entry: .pre-commit-hooks/check-loguru-formatting.py
language: script
files: \.py$
description: "Prevent printf-style %s/%d placeholders in loguru logger calls"
- id: check-open-encoding
name: Check open() calls have explicit encoding
entry: .pre-commit-hooks/check-open-encoding.py
language: script
files: \.py$
exclude: ^tests/
description: "Enforce explicit encoding= on text-mode open() calls (issue #3743)"
- id: check-image-pinning
name: Check Docker Image Pinning
entry: .pre-commit-hooks/check-image-pinning.sh
language: script
files:
(Dockerfile|docker-compose.*\.ya?ml|\.github/workflows/.*\.ya?ml)$
description: "Ensure all Docker images use SHA256 digests for security"
- id: check-safe-requests
name: Check for unsafe requests usage (SSRF protection)
entry: .pre-commit-hooks/check-safe-requests.py
language: script
files: \.py$
description: "Prevent direct requests.get/post/Session - use safe_get/safe_post/SafeSession"
- id: check-silent-cleanup
name: Check for silent exceptions in close() methods
entry: .pre-commit-hooks/check-silent-cleanup.py
language: script
files: \.py$
exclude: ^tests/
description: "Ensure close() methods log cleanup failures instead of silently passing"
- id: check-silent-exceptions
name: Check for silent exception swallowing
entry: .pre-commit-hooks/check-silent-exceptions.py
language: script
files: \.py$
exclude: ^(tests/|examples/)
description: "Flag except Exception: pass without logging — use logger.debug()
or # noqa: silent-exception to suppress"
- id: check-service-context-managers
name: Check services use context managers
entry: .pre-commit-hooks/check-service-context-managers.py
language: script
files: \.py$
description: "Ensure DownloadService, LibraryRAGService, LocalEmbeddingManager use context managers"
- id: check-absolute-module-paths
name: Check for absolute module paths
entry: .pre-commit-hooks/check-absolute-module-paths.py
language: script
files: \.(py|json)$
description: "Ensure module_path values use relative imports, not absolute paths"
- id: check-utcnow-parens
name: Check utcnow() has parentheses in Column defaults
entry: .pre-commit-hooks/check-utcnow-parens.py
language: script
files: \.py$
exclude: ^(\.pre-commit-hooks/|tests/)
description: "Prevent default=utcnow (missing parens) — utcnow is a FunctionElement
class, parens are required to create the SQL expression object"
- id: check-pdm-lock
name: Check pdm.lock sync
entry: .pre-commit-hooks/check-pdm-lock.sh
language: script
files: ^pyproject\.toml$
description: "Ensure pdm.lock is up-to-date with pyproject.toml"
- id: check-version-sync
name: Check Version Sync
entry: .pre-commit-hooks/check-version-sync.py
language: script
files: ^(package\.json|src/local_deep_research/__version__\.py)$
pass_filenames: false
description: "Ensure package.json version matches src/local_deep_research/__version__.py"
- id: check-codeowners-sync
name: Check CODEOWNERS Sync
entry: .pre-commit-hooks/check-codeowners-sync.py
language: script
files: ^\.github/(CODEOWNERS|workflows/pr-triage\.yml)$
pass_filenames: false
description: "Ensure pr-triage.yml CODEOWNERS const matches .github/CODEOWNERS global owners"
- id: check-golden-master-settings
name: Check Golden Master Settings Sync
entry: .pre-commit-hooks/check-golden-master-settings.py
language: script
files: ^src/local_deep_research/defaults/.*\.json$
pass_filenames: false
description: "Ensure golden master settings are updated when defaults change"
- id: check-adr-numbers
name: Check ADR numbering
entry: .pre-commit-hooks/check-adr-numbers.py
language: script
files: ^docs/decisions/.*\.md$
pass_filenames: false
description: "Ensure docs/decisions ADR numbers are unique (no two files share a NNNN prefix)"
- id: check-readme-links
name: Check README/docs links and examples
entry: .pre-commit-hooks/check-readme-links.py
language: script
pass_filenames: false
files: ^(README\.md|SECURITY\.md|CONTRIBUTING\.md|docs/.*\.md|src/local_deep_research/web_search_engines/engine_registry\.py)$
description: "Validate relative links, heading anchors, python -m
examples, and engine=... names in README.md, SECURITY.md,
CONTRIBUTING.md, and docs/**.md against the repo, so renamed
files/headings or removed modules/engines can't silently break
the documentation"
- id: check-layer-imports
name: Check infrastructure packages don't import from web/
entry: .pre-commit-hooks/check-layer-imports.py
language: script
files: \.py$
exclude: ^tests/
description: "Prevent settings/, utilities/, security/, config/ from importing
web/ — breaks CLI/MCP/API usage"
- id: recommend-docs
name: Documentation Reminder
entry: .pre-commit-hooks/recommend-docs.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Gentle reminder to update docs when source files change"
- id: recommend-tests
name: Test Coverage Recommendation
entry: .pre-commit-hooks/recommend-tests.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Direct recommendation to include tests when source files change"
- id: recommend-vitest
name: Vitest Coverage Nudge
entry: .pre-commit-hooks/recommend-vitest.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Nudge to add vitest tests when frontend JS source changes lack them"
- id: recommend-performance-tests
name: Performance Test Reminder
entry: .pre-commit-hooks/recommend-performance-tests.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Remind contributors about subsystem fast tests and opt-in live tests"
- id: check-changelog-fragments
name: Check changelog fragment names
entry: .pre-commit-hooks/check-changelog-fragments.py
language: script
files: ^changelog\.d/
pass_filenames: false
description: "Fail on changelog.d/ fragments with undeclared towncrier categories -
towncrier silently drops them from the rendered release notes"
- id: recommend-release-notes
name: Release Notes Reminder
entry: .pre-commit-hooks/recommend-release-notes.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Remind contributors to add a changelog.d/<id>.<category>.md fragment for substantial changes (rendered by towncrier at release prep)"
- id: recommend-pr-description-update
name: PR Description Freshness Reminder
entry: .pre-commit-hooks/recommend-pr-description-update.py
language: script
pass_filenames: false
always_run: true
verbose: true
description: "Nudge to update PR description and pending changelog fragments on PR branches"
- id: require-tests
name: Require Tests for Substantial Changes
entry: .pre-commit-hooks/require-tests.py
language: script
pass_filenames: false
always_run: true
description: "Block commits with substantial new code but no tests"
- id: require-strategy-deletion-docs
name: Require docs/strategies/deleted/ note on strategy deletion
entry: .pre-commit-hooks/require-strategy-deletion-docs.py
language: script
pass_filenames: false
always_run: true
description: "Block commits that delete a search strategy file without adding/updating a notes file in docs/strategies/deleted/"
- id: check-unmarked-sleep
name: Check time.sleep() in tests has @pytest.mark.slow
entry: .pre-commit-hooks/check-unmarked-sleep.py
language: script
files: ^tests/.*\.py$
description: "Ensure test functions with time.sleep(>0.1s) are marked
@pytest.mark.slow so CI can skip them with -m 'not slow'"
- id: check-fixture-duplication
name: Check for duplicated test fixtures
entry: .pre-commit-hooks/check-fixture-duplication.py
language: script
files: ^tests/.*\.py$
description: "Warn when test files redefine app/client/authenticated_client
fixtures from root conftest.py"
- id: check-shadow-tests
name: Check for shadow tests (no SUT import)
entry: .pre-commit-hooks/check-shadow-tests.py
language: script
files: ^tests/.*\.py$
# Black-box (HTTP-client) and meta (hook/guardian) test trees
# legitimately never import local_deep_research; scattered
# survivors use a '# allow: no-sut-import' marker instead.
exclude: ^tests/(api_tests|api_tests_with_login|ui_tests|hooks|ci|health_check|accessibility_tests|performance/api_auth)/|_hook\.py$
description: "Block test modules that import nothing from local_deep_research
(shadow tests). Opt out a legitimate no-import test with
'# allow: no-sut-import — <reason>'. See CONTRIBUTING.md."
- id: check-weak-tests
name: Check for tautological / no-op tests
entry: .pre-commit-hooks/check-weak-tests.py
language: script
files: ^tests/.*\.py$
description: "Block tests that pass regardless of the SUT: assert-True-only,
import-existence tautologies, `... or True`, and
`x is None or x is not None`. Opt out per-test with `# allow: weak-test`."
# Hooks intentionally NOT added
# See docs/decisions/0002-pre-commit-hook-reviews.md for full rationale.
#
# codespell (PR #3222): CamelCase false positives on code identifiers
# mypy (PR #3231): ignore_errors covers most modules; already in CI
# vulture (PR #3230): Advisory-only in CI; use workflow instead
# innerHTML regex (PR #3227): Nested-brace regex fails on real JS files
# utcnow callable (PR #3218): Conflicts with existing check-utcnow-parens hook