698 Commits
Author SHA1 Message Date
Andrey Antukh 97fe51e08b Merge remote-tracking branch 'origin/staging' into develop 2026-11-05 22:43:31 +01:00
Francis Santiago 030509c6fd ⬆️ Update DHI base image digests
Refresh the pinned DHI digests used by Penpot's container builds.

Stale Debian bases conflict with current APT package versions.

AI-assisted-by: gpt-6
Signed-off-by: Francis Santiago <francis.santiago@kaleidos.net>
2026-11-04 12:46:37 +01:00
David Barragán Merino 0e9a9a8950 💥 Enable admin console by default (#12475)
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-11-03 23:34:16 +01:00
penpot-renovate[bot] 2bf9f4c78b ⬆️ Update DHI base images (#12767)
- dhi.io/debian-base trixie-debian13-dev@af61a32 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@af61a32 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13@834d20c (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@af61a32 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@af61a32 (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.8-debian13-dev@f69a0ea (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.2-debian13-dev@df819cf (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.2-debian13-dev@df819cf (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@df819cf (docker/images/Dockerfile.exporter)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
Co-authored-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-11-03 16:03:28 +01:00
penpot-renovate[bot] ecd0eb2c26 ⬆️ Update DHI base images (#12762)
- dhi.io/nginx 1.31.8-debian13-dev@f8c15ec (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.2-debian13-dev@3083ddf (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.2-debian13@ce582f8 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@3083ddf (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@3083ddf (docker/images/Dockerfile.exporter)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-11-02 10:57:24 +01:00
penpot-renovate[bot] 31e5fb53d0 ⬆️ Update DHI base images (#12725)
- dhi.io/debian-base trixie-debian13-dev@9e479c6 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@9e479c6 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13@fefc620 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@9e479c6 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@9e479c6 (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.8-alpine3.24@7a4e902 (docker/images/Dockerfile.storybook)
- dhi.io/nginx 1.31.8-debian13-dev@cdfb6c6 (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.2-debian13-dev@3f37250 (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.2-debian13@2b299a5 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@3f37250 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@3f37250 (docker/images/Dockerfile.exporter)
- node >=20.20.2 (mcp/packages/server/package.json)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-11-01 19:27:24 +01:00
Miguel de Benito Delgado 723267cfdd 🐳 Expose GPU in devenv (#12726)
* ✨ Add GPU support to the devenv

AI-assisted-by: gpt-6.1-sol

* 📚 Fix broken link in dev docs
2026-10-30 15:13:29 +01:00
Andrey Antukh 8491cdaf63 Merge branch 'main-2.18.x' 2026-10-29 15:43:06 +01:00
Andrey Antukh 41be5bfb5f ⬆️ Bump docker base images 2026-10-29 15:28:19 +01:00
penpot-renovate[bot]andAndrey Antukh 936371d9a6 ⬆️ Update dependency pnpm to v12.16.1 (#12714)
- pnpm 12.16.1 (docker/images/Dockerfile.media-processor)
- pnpm 12.16.1 (docker/images/Dockerfile.mcp)
- pnpm 12.16.1 (docker/images/Dockerfile.exporter)
- pnpm 12.16.1 (docker/devenv/Dockerfile)
- pnpm 12.16.1 (render-wasm/package.json)
- pnpm 12.16.1 (plugins/package.json)
- pnpm 12.16.1 (plugins/libs/plugins-styles/package.json)
- pnpm 12.16.1 (plugins/libs/plugins-runtime/package.json)
- pnpm 12.16.1 (plugins/libs/plugin-types/package.json)
- pnpm 12.16.1 (plugins/apps/table-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/rename-layers-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/poc-tokens-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/poc-state-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/plugin-api-test-suite/package.json)
- pnpm 12.16.1 (plugins/apps/lorem-ipsum-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/icons-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/example-styles/package.json)
- pnpm 12.16.1 (plugins/apps/e2e/package.json)
- pnpm 12.16.1 (plugins/apps/create-palette-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/contrast-plugin/package.json)
- pnpm 12.16.1 (plugins/apps/composable-test-suite/package.json)
- pnpm 12.16.1 (plugins/apps/colors-to-tokens-plugin/package.json)
- pnpm 12.16.1 (package.json)
- pnpm 12.16.1 (media-processor/package.json)
- pnpm 12.16.1 (mcp/packages/server/package.json)
- pnpm 12.16.1 (mcp/packages/plugin/package.json)
- pnpm 12.16.1 (mcp/packages/common/package.json)
- pnpm 12.16.1 (mcp/package.json)
- pnpm 12.16.1 (library/package.json)
- pnpm 12.16.1 (frontend/text-editor/package.json)
- pnpm 12.16.1 (frontend/packages/ui/package.json)
- pnpm 12.16.1 (frontend/packages/mousetrap/package.json)
- pnpm 12.16.1 (frontend/packages/draft-js/package.json)
- pnpm 12.16.1 (frontend/package.json)
- pnpm 12.16.1 (exporter/package.json)
- pnpm 12.16.1 (docs/package.json)
- pnpm 12.16.1 (common/package.json)
- pnpm 12.16.1 (backend/package.json)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-10-29 15:26:20 +01:00
penpot-renovate[bot] c0af48f873 ⬆️ Update DHI base images (#12713)
- dhi.io/debian-base trixie-debian13-dev@cc4e05f (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@cc4e05f (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13@2664ef2 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@cc4e05f (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@cc4e05f (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.8-alpine3.24@83489ce (docker/images/Dockerfile.storybook)
- dhi.io/nginx 1.31.8-debian13-dev@fbff190 (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.2@ (docker/devenv/Dockerfile)
- dhi.io/node 24.22.2@ (.nvmrc)
- dhi.io/node 24.22.2-debian13-dev@53af56f (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.2-debian13@24fa625 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@53af56f (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.2-debian13-dev@53af56f (docker/images/Dockerfile.exporter)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-10-29 15:24:22 +01:00
Andrey Antukh 857c666022 ⬆️ Update pnpm to 12.16.1 and node to 24.22.2
pnpm 12.5.1 -> 12.16.1: the tarball pin of docker/devenv and of the
media-processor, exporter and mcp images, the packageManager field of
every workspace manifest, and the lockfile metadata of the 11
workspaces. The new pnpm also normalizes one engine range per lockfile
(>=18.* to >=18).

node 24.21.0 -> 24.22.2: devenv NODE_VERSION and both NODE_SHA256,
.nvmrc, and the runtime pin of the two plugins-deploy workflows. The
dhi.io image tags stay as they are until their digests are available.

AI-assisted-by: deepseek-v4.1-flash
2026-10-29 14:09:54 +00:00
Dr. Dominik Jain c0f0b14540 🎉 Add direct MCP feedback channel via dedicated tool (#12551)
* ♻️ Move devenv-only tools to a separate folder

* 🎉 Add an MCP feedback channel

Add a user-approved feedback tool and an MCP-token-authenticated backend
endpoint that queues plain-text email. Enable the tool through the
configured backend URI in both local and multi-user mode.

Validate subject and feedback limits, enforce per-profile rate limits,
and document configuration. Cover authentication, queueing, tool
availability, and failure handling with backend and MCP tests.

Closes #12490

AI-assisted-by: gpt-6

* ♻️ Move MCP feedback submission into RPC

Use the standard RPC wrappers for feedback and remove the dedicated
HTTP endpoint, route wiring, and custom rate limiter.

Restrict MCP tokens to opted-in routes and commands. Add a shared RPC
call helper to the MCP backend client and adapt the existing tests.

AI-assisted-by: gpt-6

* 🐛 Harden MCP feedback auth, validation and messages

Accept MCP tokens when either the mcp or the access-tokens flag is on, so
instances that enable MCP without personal access tokens can send
feedback. Personal tokens still need access-tokens. Keep the issuer in one
constant, decode tokens without raising to reject unknown issuers, and
name the issuer and type checks.

Reject control characters in the subject, and in the feedback all but
tabs and line breaks, in both the command and the tool, so a NUL answers
400 instead of failing when the mail job is stored. Answer 403 with
profile-blocked or profile-not-active for unusable profiles, record only
who sent feedback in the audit event, and add doc metadata.

Replace on OAuth approval an MCP token issued before MCP tokens had their
own issuer, or one this instance cannot decrypt, since the backend rejects
both.

In the MCP server, mention disabled access tokens on 401, drop the unused
503 case, and say that delivery happens in the background. Document the
flags in the README.

AI-assisted-by: claude-opus-5-5

* 📚 Document the MCP feedback tool and MCP token rules

List submit_feedback among the MCP tools and add an MCP feedback section to
the configuration guide covering PENPOT_MCP_BACKEND_URI,
PENPOT_MCP_FEEDBACK_EMAIL, the flags and the email settings. Add commented
examples of both variables to the compose file.

In the agent memories, record when OAuth approval replaces an MCP token,
how the MCP server reaches the backend, and which flags, routes and
commands accept MCP tokens.

AI-assisted-by: claude-opus-5-5
2026-10-29 10:35:46 +01:00
Dr. Dominik Jainandalonso.torres e20a0d748e ✨ Add OAuth support for MCP server (#12480)
* 🎉 Add OAuth support for remote MCP connections

Add MCP-specific discovery, client registration, and approval endpoints.
Exchange single-use authorization codes with PKCE for the fixed MCP user
token, enabling MCP and creating the token on approval when needed.

Use self-contained client IDs without new database tables or stored client
records. Keep temporary authorization state in Redis/Valkey.

Accept bearer credentials while preserving query-parameter connections.
Enable OAuth through PENPOT_MCP_AUTH_URI in multi-user mode. Document the
environment variable in the README and implementation details in Serena.

Explain protocol and concurrency decisions in the Clojure code. Cover token
provisioning, OAuth state, client registration, HTTP flows, and the approval
page with tests.

AI-assisted-by: gpt-6

* 🐛 Wait for devenv initialization before starting builds

Docker reports a container as Running as soon as its main process starts,
while the entrypoint may still be preparing the development environment.
manage.sh used that status to launch tmux jobs, allowing frontend builds
to race with ownership changes to /opt/rustup and Cargo setup.

On a fresh container, rustup could fail with Permission denied before the
frontend watcher started. Nginx would later serve the existing JavaScript,
leaving source changes absent from the running app despite restarting
devenv.

Wait for nginx's local health endpoint before launching the jobs. Nginx
starts after entrypoint setup, so its response confirms that setup has
finished. Allow up to 120 seconds and report a timeout without starting
the jobs if initialization does not complete.

Validation: shell syntax and whitespace checks pass.

AI-assisted-by: gpt-6

* ♻️ Share the login modal with MCP authorization

Extract the viewer login modal and its styles into a shared auth
component, retaining the viewer wrapper and its close behavior.

Use the modal on the MCP approval page and preserve the pending request
through login. Closing it clears the saved return URL and shows a
cancellation message without further actions.

Cover return URL handling and cancellation with frontend tests.

AI-assisted-by: gpt-6

* ✨ Show client icons in MCP authorization

Preserve HTTPS logo URLs from client registration and published metadata
and show the icon beside the application name on the approval page.
Ignore unusable URLs and hide failed images without blocking approval.

Update the access description to refer to MCP connections established
from Penpot. Cover logo metadata and approval responses in backend tests.

AI-assisted-by: gpt-6

* 🐛 Follow the system theme when no preference is configured

Default to the system theme in the shared resolver used by the app and
plugins. Preserve explicit light and dark choices, including the legacy
default value that means dark.

Reuse the reactive theme hook in progress widgets and show the system
preference in settings for accounts without a configured theme.

Verify preference resolution with regression tests and browser checks.
All 1,474 frontend tests pass.

AI-assisted-by: gpt-6

* 🐛 Replace expired MCP tokens during OAuth approval

Settings can give an MCP token an expiry date. OAuth approval reused
the newest MCP token without checking it, so an expired token reached
the client and never matched a plugin connection.

Approval now treats an expired token as missing and creates a new one.
Token exchange rejects a code whose token expired after approval with
invalid_grant.

AI-assisted-by: claude-opus-5-5

* 🐛 Log unexpected errors on MCP OAuth endpoints

The OAuth routes sit outside the shared HTTP middleware, so the shared
error handler never saw them, and their own handler turned unexpected
failures into a 503 without logging anything. Failures in the session
middleware of the approval endpoints had no handler at all.

Unexpected failures now also go through the shared error handler for
its logging, while clients still get an OAuth error body. The OAuth
error handler also wraps the session middleware of the approval
endpoints.

AI-assisted-by: claude-opus-5-5

* 🔧 Add devenv script to run the MCP server with OAuth

start-mcp-devenv-oauth starts the MCP server in multi-user mode with
PENPOT_MCP_AUTH_URI derived from PENPOT_PUBLIC_URI, to test OAuth in
the devenv. Agentic tooling still uses the single-user
start-mcp-devenv.

AI-assisted-by: claude-opus-5-5

* 🐛 Fix failing test case

---------

Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
2026-10-28 18:40:04 +01:00
Dr. Dominik Jainandalonso.torres 9d5dad3de7 ⬆️ Upgrade to Serena v2.1.0 (#12482)
* ⬆️ Upgrade to Serena v2.1.0

Switch to REPL interface (configured in project)

Additional changes:
* Remove additional Serena project in subfolder mcp/

* 🐛 Fix outdated memories

---------

Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
2026-10-27 14:59:22 +01:00
David Barragán Merino 7cf914088a Merge branch 'main' into staging 2026-10-26 10:01:26 +01:00
David Barragán Merino f44566963d ⏪ Revert the subpath support brought by the docker/ backport
The backport of docker/ from develop (2df5f417a) also brought the subpath
support from #12358 and its fix (95bc48a08). It needs the Admin Console
from 2.20, so with the current one every Admin Console URL fails. Restore
the previous nginx configuration and docker-compose.yaml.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-10-26 09:59:00 +01:00
Andrey Antukh c04af5ddc5 Merge remote-tracking branch 'origin/main' into staging 2026-10-23 13:11:52 +02:00
Andrey Antukh 2df5f417a0 ⏪ Backport .github and docker/ changes from develop 2026-10-23 12:40:24 +02:00
Andrey Antukh 76a83387d9 ⬆️ Update JVM, Node, pnpm and devenv dependencies (#12600)
Move the backend JDK to its latest maintenance build within Java 26 and
refresh the dependency versions pinned by hand in the development and
production images.

- Backend: Zulu JDK 26.0.2 to 26.0.2.1. The jlink module list keeps
  jdk.management, so the prometheus process metrics stay exported.
- Node.js 24.22.1 in .nvmrc, the development image tarball and the two
  plugins deploy workflows that pin it.
- pnpm 12.15.0 in the four Dockerfiles, the 34 packageManager fields and
  the eleven lockfiles.
- Development tools: clj-kondo 2026.10.20, Babashka 1.13.226, Pixi
  0.83.0, GitHub CLI 2.103.0, AWS CLI 2.38.5 and uv 0.13.5.
- Infra services: RustFS 1.0.3, Mailpit v1.32.0, and Valkey pinned to
  8.1.10 instead of the floating 8.1 tag.

Fix SERENA_UPDATE_VERSION in the compose file. A value there makes the
start script reinstall that Serena release on every start, overriding
the one baked into the image; it was replacing 1.7.0 with 1.6.1.

The hardened base image updates are left to Renovate.

Closes #12599

AI-assisted-by: deepseek-v4.1-flash

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-10-23 12:36:11 +02:00
penpot-renovate[bot] c3a23174a1 ⬆️ Update DHI base images (#12597)
- dhi.io/debian-base trixie-debian13-dev@9b02576 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@9b02576 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13@de80b46 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@9b02576 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@9b02576 (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.7-debian13-dev@940ee35 (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.1@ (docker/devenv/Dockerfile)
- dhi.io/node 24.22.1@ (.nvmrc)
- dhi.io/node 24.22.1-debian13-dev@20cf36e (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.1-debian13@32a2fa6 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.1-debian13-dev@20cf36e (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.1-debian13-dev@20cf36e (docker/images/Dockerfile.exporter)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
Co-authored-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-10-23 11:50:52 +02:00
David Barragán Merino 95bc48a08a 🐛 Fix Admin Console URLs escaped twice
The Admin Console location built its proxy_pass target from a capture of
$request_uri, which nginx escapes again when the path has escaped
characters: %XX became %25XX and the query string ended up in the path,
so Admin Console links returned 404. Strip the prefix with a rewrite and
let proxy_pass forward the rewritten URI instead.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-10-21 14:22:53 +02:00
David Barragán Merino d6e1cb23e0 🐳 Serve Penpot and the Admin Console from a subpath (#12358)
* 🐳 Serve the frontend under the path of PENPOT_PUBLIC_URI

Requests below the path are rewritten to the root, so a reverse proxy can
forward them unchanged. The Admin Console keeps receiving the original path.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>

* 🐳 Strip the public path before proxying to the Admin Console

The Admin Console is served at the root of its own server and applies the
public path at runtime, so it needs a matching Admin Console image.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>

* 📚 Document subpath deployments in docker-compose.yaml

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>

* 📚 Describe subpath deployments without proxy rewrites

The frontend now serves the subpath itself, so the reverse proxy must
forward it unchanged.

AI-assisted-by: Claude
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>

---------

Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-10-19 15:49:41 +02:00
Andrey Antukh 9336962a77 ⏪ Backport docker changes from develop 2026-10-17 14:54:23 +02:00
Andrey Antukh 8c5113b815 Merge remote-tracking branch 'origin/staging' into develop 2026-10-17 14:44:44 +02:00
penpot-renovate[bot] 1a68928aca ⬆️ Update DHI base images (#12399)
- dhi.io/debian-base trixie-debian13-dev@7b1d652 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@7b1d652 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@7b1d652 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@7b1d652 (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.7-alpine3.24@6d3811f (docker/images/Dockerfile.storybook)
- dhi.io/nginx 1.31.7-debian13-dev@10c0037 (docker/images/Dockerfile.frontend)
- dhi.io/node 24.22.0@ (docker/devenv/Dockerfile)
- dhi.io/node 24.22.0@ (.nvmrc)
- dhi.io/node 24.22.0-debian13-dev@39f5547 (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.22.0-debian13@c6ddacf (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.0-debian13-dev@39f5547 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.22.0-debian13-dev@39f5547 (docker/images/Dockerfile.exporter)
2026-10-17 14:06:09 +02:00
Andrey Antukh 016c3976d0 🔧 Install opencode on demand instead of baking it in
The opencode build stage was already commented out, so the image carried
a dead block and a commented COPY. Drop both: opencode now comes from
scripts/setup-opencode, which installs @opencode/cli as a global pnpm
package in the penpot user's $PNPM_HOME. That dir sits in the user-data
volume, so the install survives a container re-creation and needs no
root.

pnpm 12 keeps the global binaries in $PNPM_HOME/bin, so put that dir on
PATH in the bashrc (and make the guard check the same path) instead of
$PNPM_HOME, which left the commands unreachable.

The entrypoint now also chowns ~/.local, ~/.cache and the dotfiles it
copies from /root. EXTERNAL_UID remaps penpot to the host UID on every
start, so the ownership the image set at build time stops matching; that
broke global pnpm installs and pnpm's own packageManager download.

AI-assisted-by: deepseek-v4.1-flash
2026-10-17 14:00:43 +02:00
Andrey Antukh d1aa36b814 ⬆️ Update pnpm to 12.14.0 and Node to v24.22.0
Bump the pnpm pin to 12.14.0 in the devenv and the production images
and stamp the same version into every package.json, realigning the
drift between the devenv (12.9.1) and the rest (12.6.0).

Bump Node to v24.22.0, the newest patch of the Krypton LTS line, in
.nvmrc, the devenv and image Dockerfiles and the plugins-deploy
workflows.

The pnpm arch checksums are those of the GitHub release tarballs, not
of the npm package. Lockfile changes are metadata only.

AI-assisted-by: deepseek-v4.1-flash
2026-10-17 14:00:43 +02:00
Andrey Antukh d0f82b9979 Merge remote-tracking branch 'origin/staging' into develop 2026-10-14 14:37:58 +02:00
Andrey Antukh 24d3e62c62 ⬆️ Update opencode on devenv dockerfile
Bump opencode to 2.0.29 in the devenv image and refresh
the published checksums for both supported architectures.

AI-assisted-by: muse-spark-1.3-contributor
2026-10-14 12:25:34 +00:00
Andrey Antukh 6f33d8d9d8 Merge remote-tracking branch 'origin/staging' into develop 2026-10-09 19:16:03 +02:00
Andrey Antukh 25e8f349e1 ⬆️ Update opencode to 2.0.26 in the devenv image
Bumps the OpenCode CLI version pinned by the devenv image from 2.0.25
to 2.0.26 and refreshes the per-architecture SHA-256 checksums used
to verify the downloaded tarballs.
AI-assisted-by: step-5-preview-free
2026-10-09 19:14:29 +02:00
Andrey Antukh 473a59b134 Merge remote-tracking branch 'origin/staging' into develop 2026-10-09 09:01:12 +02:00
Andrey Antukh d6f62d8d7d ⬆️ Update opencode on devenv dockerfile 2026-10-08 13:13:10 +02:00
David Barragán Merino edd500302c ⬆️ Update ImageMagick to 7.1.2-32
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-10-07 13:02:27 +02:00
David Barragán Merino 472973533e 🐳 Verify the Node.js tarball checksum in the devenv
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-10-06 17:14:55 +02:00
Andrey Antukh 746184caf9 Merge remote-tracking branch 'origin/staging' into develop 2026-10-06 15:58:01 +02:00
Andrey Antukh 0ccd75487f ⬆️ Update dependencies on devenv 2026-10-06 15:43:38 +02:00
penpot-renovate[bot] a61a4fceb1 ⬆️ Update dependency pnpm to v12.8.1
- pnpm 12.8.1 (docker/images/Dockerfile.media-processor)
- pnpm 12.8.1 (docker/images/Dockerfile.mcp)
- pnpm 12.8.1 (docker/images/Dockerfile.exporter)
- pnpm 12.8.1 (render-wasm/package.json)
- pnpm 12.8.1 (plugins/package.json)
- pnpm 12.8.1 (plugins/libs/plugins-styles/package.json)
- pnpm 12.8.1 (plugins/libs/plugins-runtime/package.json)
- pnpm 12.8.1 (plugins/libs/plugin-types/package.json)
- pnpm 12.8.1 (plugins/apps/table-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/rename-layers-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/poc-tokens-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/poc-state-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/plugin-api-test-suite/package.json)
- pnpm 12.8.1 (plugins/apps/lorem-ipsum-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/icons-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/example-styles/package.json)
- pnpm 12.8.1 (plugins/apps/e2e/package.json)
- pnpm 12.8.1 (plugins/apps/create-palette-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/contrast-plugin/package.json)
- pnpm 12.8.1 (plugins/apps/composable-test-suite/package.json)
- pnpm 12.8.1 (plugins/apps/colors-to-tokens-plugin/package.json)
- pnpm 12.8.1 (package.json)
- pnpm 12.8.1 (media-processor/package.json)
- pnpm 12.8.1 (mcp/packages/server/package.json)
- pnpm 12.8.1 (mcp/packages/plugin/package.json)
- pnpm 12.8.1 (mcp/packages/common/package.json)
- pnpm 12.8.1 (mcp/package.json)
- pnpm 12.8.1 (library/package.json)
- pnpm 12.8.1 (frontend/text-editor/package.json)
- pnpm 12.8.1 (frontend/packages/ui/package.json)
- pnpm 12.8.1 (frontend/packages/tokenscript/package.json)
- pnpm 12.8.1 (frontend/packages/mousetrap/package.json)
- pnpm 12.8.1 (frontend/packages/draft-js/package.json)
- pnpm 12.8.1 (frontend/package.json)
- pnpm 12.8.1 (exporter/package.json)
- pnpm 12.8.1 (docs/package.json)
- pnpm 12.8.1 (common/package.json)
- pnpm 12.8.1 (backend/package.json)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-10-06 15:12:15 +02:00
penpot-renovate[bot] e17c3c0c8f ⬆️ Pin DHI base image digests
- dhi.io/debian-base trixie-debian13-dev@61dc022 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13-dev@61dc022 (docker/images/Dockerfile.backend)
- dhi.io/debian-base trixie-debian13@20079b5 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@61dc022 (docker/imagemagick/Dockerfile)
- dhi.io/debian-base trixie-debian13-dev@61dc022 (docker/devenv/Dockerfile)
- dhi.io/nginx 1.31.6-alpine3.24@9465275 (docker/images/Dockerfile.storybook)
- dhi.io/nginx 1.31.6-debian13-dev@32e4340 (docker/images/Dockerfile.frontend)
- dhi.io/node 24.21.0-debian13-dev@2e51e83 (docker/images/Dockerfile.media-processor)
- dhi.io/node 24.21.0-debian13@f3575cf (docker/images/Dockerfile.mcp)
- dhi.io/node 24.21.0-debian13-dev@2e51e83 (docker/images/Dockerfile.mcp)
- dhi.io/node 24.21.0-debian13-dev@2e51e83 (docker/images/Dockerfile.exporter)

Signed-off-by: penpot-renovate[bot] <338182062+penpot-renovate[bot]@users.noreply.github.com>
2026-10-06 13:58:17 +02:00
Andrey Antukh 3f610ad793 ✨ Isolate backend-test database per devenv instance (#12048)
* ✨ Isolate backend-test database per devenv instance

Each wsN now gets its own backend-test database
(penpot_test_wsN) and Valkey DB (6+N) on the shared
infra, so parallel test runs no longer wipe each
other. The main database stays shared on purpose.

manage.sh creates the test database on bring-up and
passes PENPOT_TEST_* into the main container. Test
helpers already read those vars, so no runtime code
changes. scripts/psql and db-schema gain --ws.

AI-assisted-by: muse-spark-1.3-contributor-free

* 🐛 Fix per-instance test database creation on bring-up

psql -c does not reliably mix SQL with psql-only
commands, so the CREATE DATABASE ... WHERE NOT
EXISTS ... \gexec one-liner never ran. Use two
plain SQL round-trips instead (check pg_database,
then CREATE DATABASE) and print what happens, so a
future failure shows up in the bring-up output.

AI-assisted-by: muse-spark-1.3-contributor-free
2026-10-01 19:22:01 +02:00
Andrey Antukh 8db9cb83f3 📎 Update devenv dockerfile 2026-10-01 12:09:57 +02:00
David Barragán Merino 0049c8b673 🐳 Remove OpenEXR support from ImageMagick and Docker images
Penpot only accepts jpeg, png, webp, gif and svg images, so the
EXR coder was never used. It was enabled only because ImageMagick's
configure auto-detected libopenexr-dev at build time.

OpenEXR accounted for 25 CVEs (15 High) in both the exporter and
media-processor images, and was also bundled into the backend via
/opt/imagick/lib/deps, where dpkg-based scanners cannot see it.

- Build ImageMagick with --without-openexr and drop libopenexr-dev
- Drop libopenexr-3-1-30 from the imagemagick, backend, exporter,
  media-processor and devenv images
- Remove `apt-get upgrade` from the ImageMagick build stage
- Bump penpotapp/imagemagick to 7.1.2-27-1

Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-09-29 19:13:41 +02:00
David Barragán Merino 2d73adc926 🐳 Remove dist-upgrade from DHI-based Docker images
Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
2026-09-29 19:13:41 +02:00
Andrey Antukh f38c7dd639 ⬆️ Update deps (#11960)
* 🐛 Migrate openUIApi schema to Zod v4 function syntax

Zod 4 removed z.function().args(), which broke the
plugins-runtime build with implicit-any errors on every
openUIApi parameter and knock-on possibly-null errors on
the modal in plugin-manager.

Declare the inputs with z.function({ input: [...] }) so the
parameter and return types infer again; behavior is unchanged.

Add a regression spec covering delegation, optional args and
rejection of invalid theme and title values.

AI-assisted-by: muse-spark-1.3-contributor

* 📚 Fix deprecated markdown-it-anchor permalink option in docs

Migrate docs Eleventy config to the markdown-it-anchor v10 API.
Replace the deprecated boolean permalink option with
linkInsideHeader, keeping the same symbol and class.
Bump markdown-it-anchor to v10 and related docs deps.

AI-assisted-by: muse-spark-1.3-contributor

* ⬆️ Update deps

* ⬆️ Update base docker images

* 📎 Fix mcp tests
2026-09-29 09:07:34 +02:00
Andrey Antukh a69f80fe29 ⬆️ Update pnpm to 12.6.0 and opencode pair in devenv
Bump the devenv and image Dockerfiles to pnpm 12.6.0
(latest stable; 12.8.0 is still on the next tag) with
fresh SHA256 pins, and opencode to 1.18.33 plus
opencode2 to 2.0.18 with fresh checksums.

Stamp all 35 package.json files via
scripts/sync-pnpm-version and refresh the 11 lockfiles;
diffs are metadata-only, with no dependency re-resolution.

Drop the last corepack calls from the media-processor
build script and its generated image setup: pnpm now
ships as a system binary and self-heals version drift.

AI-assisted-by: muse-spark-1.3-contributor
2026-09-28 18:19:26 +00:00
Andrey Antukh eda9e670be 🔧 Update OpenCode development tooling
Expose selected agent skills as slash commands and pass invocation
arguments to their entry points.

Update the devenv OpenCode CLI to v2.0.16 with checksums for both
supported architectures.

AI-assisted-by: space-bunny-free
2026-09-24 14:53:08 +02:00
Andrey Antukh 32d6ee195e 🔧 Expand link preview crawler detection
Add the User-Agent values used by Mattermost, OpenGraph.xyz and the
Twitter Card Validator to the production and development
link-preview routing maps.

This lets those crawlers reach the dynamic Open Graph response instead
of receiving the generic Penpot preview.

AI-assisted-by: space-bunny-free
2026-09-24 13:39:47 +02:00
Andrey Antukh f64cc1eb8e ⬆️ Upgrade opencode2 to 2.0.15
Bump the OpenCode V2 binary in the devenv image from 2.0.12 to the
current npm latest tag (2.0.15) and refresh the per-architecture
SHA-256 checksums for both arm64 and amd64 tarballs.

AI-assisted-by: deepseek-v4.1-flash
2026-09-23 19:37:00 +02:00
Andrey Antukh b3c1aab720 Merge remote-tracking branch 'origin/staging' into develop 2026-09-23 19:19:18 +02:00