v12.3.0
stackblitz-labs/bolt.diyv12.3.0Aug 18, 2026by github-actions[bot]
AI Summary
This release introduces a new client-side CLI for schema syncing, search-first AI tool discovery, and updates to image transformation limits, while fixing critical storage connection leaks and changing Docker image behavior.
Key Highlights
- Introduced a new client-side CLI for syncing schema between Directus instances
- Added search-first AI tool discovery for chat and MCP tools
- Fixed storage connections leaking when asset requests were cancelled or transformations failed
- Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (6000px)
- Fixed 'Update Items' and 'Delete Items' operations affecting every item when keys or queries are empty
Breaking Changes
- `exists()` now throws an error on failure instead of returning `false`
- "Update Items" and "Delete Items" operations now return `null` instead of affecting all items when empty
- "Update Items" and "Delete Items" operations throw an error when both `key` and `query` are defined
- Docker image entrypoint changed to use bundled `pm2` via `docker-entrypoint.cjs` instead of `pm2-runtime` on PATH
New Features
- Added search-first AI tool discovery for chat and MCP tools
- Added a caption field to the WYSIWYG image drawer
- Added collection name appended to display template in item and drawer headers
- Introduced `@directus/cli` (client-side CLI) for syncing schema and configuration
Full Release Notes
### ⚠️ Potential Breaking Changes
**Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076))**
`exists()` now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of also reporting `false`. Callers that relied on a `false` result for any failure need to handle the error. Note that S3 answers 403 rather than 404 for a missing object when the credentials cannot list the bucket, so granting `s3:ListBucket` is needed to keep getting a clean "missing" answer.
**Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759))**
**Nothing to target is a no-op**
"Update Items" and "Delete Items" operations now return `null` instead of falling back to every item whenever the configuration doesn't target anything — that is, when `key` is empty or missing (e.g. `[]`, `""`) and `query` is empty or missing (e.g. `{}`). "Update Items" additionally returns `null` when there is nothing to write, i.e. an empty or missing `payload` (e.g. `{}`, or `[]` for a batch payload). Flows that relied on the previous fallback to every item can use `{"limit": -1}`.
**Contradictory options error**
"Update Items" and "Delete Items" operations now throw an error when both `key` and `query` are defined. "Update Items" also throws when `key` or `query` is combined with a batch payload.
**Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111))**
The default maximum output dimension is now `6000` px. Users who rely on the previous limit of `3000` px can explicitly configure `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION`.
**Used the `pm2` bundled with `@directus/api` in the Docker images instead of installing a separate copy, so its dependencies follow the versions pinned by the workspace ([#28120](https://github.com/directus/directus/pull/28120))**
If you extend the Docker image: it now boots via `CMD ["node", "docker-entrypoint.cjs"]`, which runs the same `bootstrap` then `pm2-runtime` sequence as before. `pm2-runtime` is no longer on the `PATH`, so a custom `CMD` that called it directly should hand off to `docker-entrypoint.cjs` instead. `pm2` itself remains on the `PATH` for `docker exec` diagnostics.
- **@directus/api**
- Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759) by @ComfortablyCoding)
- **@directus/storage-driver-cloudinary**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/storage-driver-s3**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/storage-driver-local**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/storage-driver-supabase**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/sdk**
- Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner)
### ✨ New Features & Improvements
- **@directus/app**
- Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. ([#27797](https://github.com/directus/directus/pull/27797) by @bryantgillespie)
- Added a caption field to the WYSIWYG image drawer, which wraps the image in a `figure` with a `figcaption` ([#28026](https://github.com/directus/directus/pull/28026) by @alvarosabu)
- Added the collection name appended to display template in item and drawer headers ([#28078](https://github.com/directus/directus/pull/28078) by @AlexGaillard)
- **@directus/api**
- Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. ([#27797](https://github.com/directus/directus/pull/27797) by @bryantgillespie)
- **@directus/cli**
- Introduced `@directus/cli` (`d6s` / `directus-cli`) — a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files, with `sync pull`, `sync diff`, `sync push`, and an interactive wizard ([#27861](https://github.com/directus/directus/pull/27861) by @bryantgillespie)
- **@directus/types**
- Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner)
### 🐛 Bug Fixes & Optimizations
- **@directus/app**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- Removed dead “Save and Quit” dropdown row outside the content item view ([#28051](https://github.com/directus/directus/pull/28051) by @robluton)
- Fixed relational items with unsaved nested values, such as newly added translated items in a content version, rendering as `--` instead of their display template ([#28010](https://github.com/directus/directus/pull/28010) by @alvarosabu)
- Fixed the repeater interface options showing empty sub-fields, and dropping their key and type on save, when the sub-fields were created through the API without repeating the key and type inside their meta ([#28041](https://github.com/directus/directus/pull/28041) by @lazerg)
- Fixed relational fields showing stale values after a manual flow updated them ([#28056](https://github.com/directus/directus/pull/28056) by @AlexGaillard)
- Fixed the Markdown interface's Edit and Preview buttons not indicating which view is currently active ([#28023](https://github.com/directus/directus/pull/28023) by @Aniket-a14)
- Fixed silent failure of dragging & dropping files with an unrecognized extension into the file library ([#28093](https://github.com/directus/directus/pull/28093) by @alvarosabu)
- Fixed a request for a non-existent item when opening an item whose Many-to-One field references an unsaved parent ([#27975](https://github.com/directus/directus/pull/27975) by @sourav-18)
- Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner)
- Fixed field configuration appearing to close when selecting related collection that switches interface ([#28118](https://github.com/directus/directus/pull/28118) by @robluton)
- Fixed the translations interface AI translation button only showing for admins ([#28089](https://github.com/directus/directus/pull/28089) by @AlexGaillard)
- Fixed SSO login redirecting to the last visited page instead of the originally requested page ([#28080](https://github.com/directus/directus/pull/28080) by @AlexGaillard)
- Stopped the policy creation modal from writing app access permission rows to the database, matching the policy detail page where app access permissions are applied at runtime instead of stored ([#28101](https://github.com/directus/directus/pull/28101) by @alvarosabu)
- Added block-level custom formats to the WYSIWYG interface, so `block`, `selector` and `items` entries in the Custom Formats option apply classes and attributes to paragraphs, headings and other block nodes from the Formats dropdown ([#28044](https://github.com/directus/directus/pull/28044) by @alvarosabu)
- Fixed WYSIWYG content the editor can't represent being hidden and unrestorable in the comparison modal ([#28067](https://github.com/directus/directus/pull/28067) by @alvarosabu)
- **@directus/api**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- Added a batch-import regression test pinning that a negative temporary key maps like any other non-existent auto-increment key in merge mode ([#27861](https://github.com/directus/directus/pull/27861) by @bryantgillespie)
- Updated MCP tool descriptions and safety annotations for connector clients. ([#28090](https://github.com/directus/directus/pull/28090) by @bryantgillespie)
- Updated or replaced various dependencies to address GHSA-rgw5-rvv9-x895 ([#28050](https://github.com/directus/directus/pull/28050) by @br41nslug)
- Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required ([#27699](https://github.com/directus/directus/pull/27699) by @br41nslug)
- Updated various dependencies to address CVEs ([#28110](https://github.com/directus/directus/pull/28110) by @br41nslug)
- Fixed slow extension sync from remote storage during startup. Added `EXTENSIONS_STORAGE_MAX_CONCURRENCY` to configure the maximum number of concurrent requests to the extensions storage location ([#27989](https://github.com/directus/directus/pull/27989) by @dstockton)
- Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111) by @ComfortablyCoding)
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- Fixed `TranslationsService.updateMany` incorrectly rejecting single-row updates containing both `key` and `language` ([#28001](https://github.com/directus/directus/pull/28001) by @suhailopensource)
- Fixed collection names with surrounding whitespace being accepted on creation ([#28038](https://github.com/directus/directus/pull/28038) by @lazerg)
- Fixed WebSocket rate limiting breaking on shared Redis setups where keys must start with a per-project prefix. The WebSocket limiter now accepts `RATE_LIMITER_WEBSOCKETS_*` values as overrides, including `RATE_LIMITER_WEBSOCKETS_KEY_PREFIX` to override the Redis key prefix. ([#28107](https://github.com/directus/directus/pull/28107) by @AlexGaillard)
- **@directus/storage-driver-azure**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/storage-driver-gcs**
- Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton)
- **@directus/release-notes-generator**
- Updated or replaced various dependencies to address GHSA-rgw5-rvv9-x895 ([#28050](https://github.com/directus/directus/pull/28050) by @br41nslug)
- **@directus/schema**
- Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required ([#27699](https://github.com/directus/directus/pull/27699) by @br41nslug)
- **@directus/env**
- Fixed slow extension sync from remote storage during startup. Added `EXTENSIONS_STORAGE_MAX_CONCURRENCY` to configure the maximum number of concurrent requests to the extensions storage location ([#27989](https://github.com/directus/directus/pull/27989) by @dstockton)
- Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111) by @ComfortablyCoding)
- **@directus/extensions-registry**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- **@directus/composables**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- **@directus/extensions**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- Fixed extensions that set `sandbox` without an `enabled` flag being rejected as invalid ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton)
- **@directus/errors**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- **@directus/stores**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- **@directus/utils**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- Updated ESLint dependencies `eslint`, `@eslint/js`, `eslint-plugin-vue`, and `typescript-eslint`. Replaced `eslint-plugin-import` with `eslint-plugin-import-x` ([#28047](https://github.com/directus/directus/pull/28047) by @br41nslug)
- **@directus/sdk**
- Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding)
- Fixed an unhandled rejection in the sdk realtime client when the socket errored or closed during the auth handshake ([#28009](https://github.com/directus/directus/pull/28009) by @Deluvio)
- **@directus/specs**
- Fixed OpenAPI spec drift, added missing query parameters, and ensured consistent parameter ordering across list endpoints ([#27938](https://github.com/directus/directus/pull/27938) by @kheiner)
- **@directus/types**
- Fixed extensions that set `sandbox` without an `enabled` flag being rejected as invalid ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton)
- **@directus/extensions-sdk**
- Fixed `extension validate` crashing on extensions with a disabled sandbox due to an invalid `findIndex` call ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton)
### 📦 Published Versions
- `@directus/app@17.1.0`
- `@directus/api@39.0.0`
- `@directus/cli@12.2.0`
- `@directus/composables@11.6.1`
- `create-directus-extension@12.1.3`
- `@directus/env@6.2.1`
- `@directus/errors@2.5.1`
- `@directus/extensions@4.0.3`
- `@directus/extensions-registry@4.0.3`
- `@directus/extensions-sdk@18.0.3`
- `@directus/memory@4.0.3`
- `@directus/pressure@4.0.3`
- `@directus/release-notes-generator@3.0.1`
- `@directus/schema@14.0.2`
- `@directus/schema-builder@1.0.2`
- `@directus/specs@15.1.1`
- `@directus/storage-driver-azure@13.0.3`
- `@directus/storage-driver-cloudinary@14.0.0`
- `@directus/storage-driver-gcs@13.0.3`
- `@directus/storage-driver-local@14.0.0`
- `@directus/storage-driver-s3@14.0.0`
- `@directus/storage-driver-supabase@5.0.0`
- `@directus/stores@3.0.1`
- `@directus/themes@2.0.3`
- `@directus/types@16.2.0`
- `@directus/utils@13.5.3`
- `@directus/validation@3.0.3`
- `@directus/sdk@25.0.0`