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