Moved the djls-check pre-commit hook to the dedicated djls-pre-commit repository, where each hook revision installs the matching django-language-server release.
Changed Django settings analysis to keep mutually exclusive configuration branches separate instead of combining their values into one partial result.
Changed Django settings analysis to treat closed unsupported Python literals as malformed rather than unresolved.
Changed template semantics and IDE features to use each file's feasible backends and the Template Library definitions active at each source position.
Changed template-library completion and installed-app guidance to retain known results through unrelated discovery problems, while unknown-library and unknown-symbol diagnostics now require an exhaustive miss.
Changed template navigation to avoid reporting templates as missing when configuration or filesystem search is incomplete, while retaining known possible destinations.
Changed unreadable files to be skipped instead of analyzed as empty source.
Changed Python model and template-spec extraction to retain known facts after recoverable syntax errors.
Changed template goto definition to return origin ranges for clients that support definition links.
Changed template tag library discovery to derive libraries from project source and Django settings instead of the runtime inspector.
Changed static Django discovery to preserve inactive-app evidence for S118, S119, and S121 diagnostics without runtime introspection.
Changed Django discovery to run after LSP initialization, refresh in the background, and warm IDE caches without blocking read requests.
Changed startup refreshes to run discovery phases in parallel and report counted progress.
Changed template validation and completion scoping to use localized inventory completeness, suppressing absence diagnostics only where discovery evidence is incomplete.
Changed template formatting to honor LSP/editor formatting options for indentation and final/trailing whitespace.
Bumped Rust toolchain from 1.95 to 1.97.1 and moved workspace crates to Rust 2024.
Internal: Added multi-file scenario support and a pluggable snapshot renderer to the djls-testing mdtest harness.
Internal: Reshaped template tag library storage around loadable and builtin mounts.
Internal: Moved the project model and static source recognizers into djls-project.
Internal: Moved Python spec extraction and template-origin resolution into djls-project, leaving djls-semantic as the project-meaning layer.
Internal: Refactored template semantics around TemplateTree for validation, references, outlines, folding, and opaque-region handling.
Internal: Reworked template analysis around per-library semantic products, sparse per-Template projections, and generation-gated production priming.
Internal: Updated realistic template benchmarks to use project-backed source extraction, canonical builtin roles, and snapshot-backed workload contracts.
Internal: Moved corpus tooling and shared test fixtures into djls-testing.
Internal: Reworked Python settings evaluation around module identities, typed import outcomes, invariant-preserving collections, and correlated list alternatives.
Internal: Reworked Django model inheritance around typed base outcomes, C3 ordering, and declaration-owned relation bindings.
Internal: Reduced development and test debug information to line tables to limit Rust build artifact size.
Internal: Expanded contributor guidance for setup, testing environments, corpus data, snapshots, linting, and pinned tool updates.
Removed the runtime inspector subprocess, embedded Python zipapp, and ~/.cache/djls/inspector/ disk cache. The server no longer needs a working Django setup to derive project facts.
Removed the template library snapshot disk cache and startup cache-loading phase.
Internal: Removed djls-workspace; workspace/filesystem logic now lives in djls-source and djls-server.
Internal: Removed the deprecated extract_rules extraction path.
Fixed false unknown tag and filter diagnostics when a template library imports or dynamically mutates its Django registration object.
Fixed static path evaluation to follow imported helper aliases without mistaking shadowed Path, str, or os bindings for standard-library helpers.
Fixed static Django settings evaluation through ordinary and from imports, including dotted module chains, module attributes, named package children, and __all__-controlled star exports.
Fixed Python settings evaluation to distinguish list and tuple concatenation while preserving known collection facts through supported iterable extensions.
Fixed relative imports in Django settings modules, including package aliases and overlapping Python search roots.
Fixed project reloads so an analysis task panic no longer prevents later reloads.
Fixed Django relative template paths (./, ../) in {% extends %} and {% include %} resolution, including inheritance chains, document links, goto definition, and find references.
Fixed false tag argument errors for manually parsed tags that strip trailing assignment clauses, such as {% now ... as var %} and {% url ... as var %}.
Fixed static Django settings analysis hanging on projects with many conditional module effects.
Fixed static Python evaluation to honor short-circuiting and and or operands.
Fixed static settings analysis to exclude impossible combinations from repeated and derived configuration predicates.
Fixed static settings analysis to preserve known template backend fields after nested dictionary assignments.
Internal: Fixed CLI summary tests to run without a discoverable Django installation.
Added document symbols for Django template structure outlines.
Added hover documentation for Django template tags, filters, libraries, and template references.
Added folding ranges for Django template block, comment, and import regions.
Added pre-commit hook for running djls check on Django template files.
Added rg-style file filtering flags to djls check: -g/--glob for glob patterns, --no-ignore to skip ignore files, -L/--follow for symlinks, -d/--max-depth for recursion depth, --color always|auto|never, and -q/--quiet.
Added env_file configuration option for loading environment variables from a .env file into the inspector process.
Filesystem cache for template library snapshots (~/.cache/djls/inspector/). On subsequent startups, cached data is loaded in ~2ms instead of waiting 200-700ms for the Python subprocess. The cache is validated in the background on every startup.
Internal: Added venv model scanning, workspace model discovery, and Salsa wiring for compute_model_graph — the model graph is now populated from both site-packages and workspace models.py files with automatic invalidation on edit.
Internal: Added just dev profile recipe for local flamegraph profiling of benchmarks.
Internal: Added [profile.bench] with debug = 2 to Cargo.toml for symbolized bench profiles.
Internal: Replaced the database inspector handle with a backend-neutral project introspector.
Internal: Added a semantic validate_template_file convenience query for file-level template validation.
Internal: Unified djls-corpus to repo-only format, removing the PyPI package path. All corpus entries are now [[repo]] in manifest.toml, fetched as git archives. Removed sha2, toml_edit dependencies and the add CLI command.
Internal: Added license file fetching to djls-corpus lock. License text is saved to crates/djls-corpus/licenses/ for attribution.
Internal: Replaced manual AvailableSymbols cache in TemplateValidator with SymbolIndex. Symbol availability is now precomputed per {% load %} boundary and memoized across revisions, eliminating per-walk rebuilds and hand-rolled invalidation logic.
Internal: Moved check_file orchestration and diagnostic rendering into djls-db. Removed djls-ide, djls-templates, and djls-project dependencies from the CLI binary.
Internal: Moved extraction orchestration from djls-project to djls-db. Removed unused djls-workspace dependency from djls-project.
Widened templatetag extraction to catch any uncaught exception in compilation functions, not just TemplateSyntaxError. Tags that raise ValueError, TypeError, or other exceptions in guards now produce validation constraints.
Parallelized inspector subprocess query and filesystem library discovery during startup, hiding discovery latency behind the slower inspector call.
Internal: LoadState now borrows &str from LoadedLibraries instead of cloning strings, and compute_loaded_libraries returns a reference via returns(ref). Eliminated all string allocations in available_at.
Internal: Consolidated TagIndex from three separate tracked fields into a single roles map, reducing classify from 3 Salsa field accesses to 1. TagClass now borrows from Salsa storage instead of cloning.
Internal: Replaced template BlockTree/SemanticForest structure analysis with TemplateTree, a structural semantic projection used by opaque-region computation and future outline features.
Fixed template parser diagnostics to preserve structured parser errors and source spans while retaining the existing T100 diagnostic code. Malformed filter expressions now produce parser errors instead of being silently ignored.
Suppressed failed to send notification ERROR log spam during server shutdown by disabling the LSP log forwarding layer on shutdown.
Fixed djls check silently ignoring file arguments when - (stdin) was also passed. This command now returns an error for mixed stdin/path input.
Fixed djls serve --connection-type tcp silently using stdio. The command now errors with an unsupported-mode message.
Fixed djls check with no arguments silently reading stdin instead of discovering template files. Stdin is now triggered explicitly by passing - as a path.
Fixed structural validation (unclosed tags, unbalanced blocks) being silently skipped when no Python inspector data was available. builtin_tag_specs() now provides Django's standard tag definitions as a fallback.
Deprecated lazy.lua Neovim plugin spec. It now only shows a migration warning and will be removed in the next release. See Neovim client docs for the new Neovim 0.11+ configuration approach.
Added support for loading server settings from user files (~/.config/djls/djls.toml) and project files (djls.toml, .djls.toml, and pyproject.toml via [tool.djls] table`)
Implemented dynamic settings reloading via workspace/didChangeConfiguration
Added venv_path setting to allow explicit configuration of Python virtual environment
Added unified file and LSP logging using tracing to server
Added virtual FileSystem for workspace file management
Implemented textDocument/didSave LSP method
Added typed argspecs for LSP snippets to tagspecs configuration