mirror of
https://github.com/penpot/penpot.git
synced 2026-07-20 21:17:44 +00:00
📚 Update and improve devenv documentation
* Fix stale references to `run-devenv-agentic` and `start-devenv` * Improve clarity in description of workspaces * Improve section on agentic devenv Co-authored-by: Michael Panchenko <michael.panchenko@oraios-ai.de>
This commit is contained in:
parent
93b5baa9fc
commit
b9e0421f79
@ -52,7 +52,7 @@ built fresh from `shared/codex.toml` + `templates/codex.toml` at launch.
|
||||
`manage.sh`.
|
||||
* **`mcp/`** (Claude Code, opencode) is the result of merging `shared/` with
|
||||
the port-substituted `templates/`. `manage.sh` writes these on every
|
||||
`run-devenv-agentic` pass. Gitignored, dedicated paths with no developer
|
||||
`run-devenv --agentic` pass. Gitignored, dedicated paths with no developer
|
||||
content — never edit by hand, your edits will be overwritten on the next
|
||||
reconcile.
|
||||
* **`.vscode/mcp.json`** is the same merge, but written to the path VS Code
|
||||
|
||||
@ -25,7 +25,7 @@ Compose-based dev environment under `docker/devenv/`, driven by `manage.sh`. Par
|
||||
|
||||
## Worker policy
|
||||
|
||||
Backend workers run only on ws0. `_env` gates `enable-backend-worker` on `PENPOT_BACKEND_WORKER`; ws1+ inject it as false. ws0 must be running whenever any ws1+ is running, and is the last instance to stop — `run-devenv-agentic --ws N` (N≥1) auto-starts ws0 first; `stop-devenv` refuses to stop ws0 while any ws1+ is up. Workers are pure fire-and-forget: `wrk/submit!` inserts a row into the shared Postgres `task` table and returns; RPC handlers never wait on completion and workers never publish to msgbus. The reason for "ws0 only" is avoiding multi-instance worker races (cron dedup is best-effort across instances, `wrk/submit!` `dedupe` is racy across submitters); details in `mem:prod-infra/core`.
|
||||
Backend workers run only on ws0. `_env` gates `enable-backend-worker` on `PENPOT_BACKEND_WORKER`; ws1+ inject it as false. ws0 must be running whenever any ws1+ is running, and is the last instance to stop — `run-devenv --agentic --ws N` (N≥1) auto-starts ws0 first; `stop-devenv` refuses to stop ws0 while any ws1+ is up. Workers are pure fire-and-forget: `wrk/submit!` inserts a row into the shared Postgres `task` table and returns; RPC handlers never wait on completion and workers never publish to msgbus. The reason for "ws0 only" is avoiding multi-instance worker races (cron dedup is best-effort across instances, `wrk/submit!` `dedupe` is racy across submitters); details in `mem:prod-infra/core`.
|
||||
|
||||
## Port layout
|
||||
|
||||
@ -44,13 +44,13 @@ Everything else (frontend dev, backend API, exporter, storybook, REPLs, plugin d
|
||||
|
||||
## Tmux + MCP routing
|
||||
|
||||
`docker/devenv/files/start-tmux.sh` is session-level idempotent. Reads `PENPOT_TMUX_ATTACH`. If the session exists it attaches or exits; otherwise creates 4 base windows (frontend watch / storybook / exporter / backend) plus `mcp` (when `enable-mcp` in `PENPOT_FLAGS`) and `serena` (when `SERENA_ENABLED=true`). `run-devenv-agentic` always sets both env vars. The legacy `run-devenv` alias doesn't, hence its 4-window-only session. To switch from a legacy session to agentic, `stop-devenv` then `run-devenv-agentic` — the conditional windows are only added at session create time.
|
||||
`docker/devenv/files/start-tmux.sh` is session-level idempotent. Reads `PENPOT_TMUX_ATTACH`. If the session exists it attaches or exits; otherwise creates 4 base windows (frontend watch / storybook / exporter / backend) plus `mcp` (when `enable-mcp` in `PENPOT_FLAGS`) and `serena` (when `SERENA_ENABLED=true`). `run-devenv --agentic` always sets both env vars. The legacy `run-devenv` alias doesn't, hence its 4-window-only session. To switch from a legacy session to agentic, `stop-devenv` then `run-devenv --agentic` — the conditional windows are only added at session create time.
|
||||
|
||||
MCP plugin routing is same-origin: frontend uses `<public-uri>/mcp/ws`, per-instance nginx proxies to MCP port 4401 in-container. For the plugin↔MCP server wiring (how the browser plugin discovers the URL, the in-memory connection registry, why DB-mediated routing isn't needed), see `mem:mcp/core`.
|
||||
|
||||
## Workspace orchestration (ws1+)
|
||||
|
||||
Workspace directories are user-maintained at `${PENPOT_WORKSPACES_DIR}/wsN`. `run-devenv-agentic --ws i` syncs only when `--sync` is passed, with one exception: if the workspace directory is missing on first use, sync runs implicitly to seed it.
|
||||
Workspace directories are user-maintained at `${PENPOT_WORKSPACES_DIR}/wsN`. `run-devenv --agentic --ws i` syncs only when `--sync` is passed, with one exception: if the workspace directory is missing on first use, sync runs implicitly to seed it.
|
||||
|
||||
`sync-workspace wsN`:
|
||||
1. `assert-clean-git-state` — refuses on `.git/{rebase-apply,rebase-merge,MERGE_HEAD,CHERRY_PICK_HEAD,index.lock}`. No `--sync-force` escape.
|
||||
@ -63,7 +63,7 @@ No `--delete` on the working-tree pass: gitignored caches in the workspace survi
|
||||
|
||||
## CLI surface
|
||||
|
||||
- `run-devenv-agentic [--ws main|0|wsN|N] [--sync] [--serena-context CTX]`: bring one instance up. Agentic only — MCP and Serena windows are always created. Default target main. Errors out if the target is already running. `--sync` is rejected on main; on ws1+ it's optional (forced only when the workspace dir does not exist yet). Auto-starts ws0 first when the target is ws1+ and ws0 is not yet up.
|
||||
- `run-devenv --agentic [--ws main|0|wsN|N] [--sync] [--serena-context CTX]`: bring one instance up. Agentic only — MCP and Serena windows are always created. Default target main. Errors out if the target is already running. `--sync` is rejected on main; on ws1+ it's optional (forced only when the workspace dir does not exist yet). Auto-starts ws0 first when the target is ws1+ and ws0 is not yet up.
|
||||
- `stop-devenv [--ws main|0|wsN|N] [--all]`: stop instances. Flags mutually exclusive. `--ws N` (N≥1) stops just that workspace. `--ws 0` or no flag stops ws0 + shared infra, refused while any ws1+ is running. `--all` stops every ws highest-first then ws0, then infra.
|
||||
- `run-devenv`: legacy alias, ws0 non-agentic attached.
|
||||
- `attach-devenv [--ws main|0|wsN|N]`: pure attach. Fails fast if instance/session missing.
|
||||
|
||||
@ -1,30 +1,22 @@
|
||||
---
|
||||
title: 3.11. Agentic Development Environment
|
||||
title: 3.11. Agentic Dev Environment
|
||||
desc: Dive into agentic Penpot development.
|
||||
---
|
||||
|
||||
# Agentic Development Environment
|
||||
# Agentic Dev Environment
|
||||
|
||||
The agentic DevEnv is an extension of the standard DevEnv (the
|
||||
[general DevEnv instructions](/technical-guide/developer/devenv/) apply),
|
||||
optimised for AI agent-based development. It adds MCP servers (Penpot,
|
||||
Serena, Playwright) and supports a launcher that wires them into your AI client.
|
||||
|
||||
Two things to know up front:
|
||||
|
||||
- **Parallel workspaces are first-class.** Run several devenv instances side
|
||||
by side - one per AI agent if you like - each with its own source-tree
|
||||
clone, ports, and tmux session. Pass `--ws N` to target one.
|
||||
- **Your existing AI-client config is preserved.** The launcher loads a
|
||||
per-workspace MCP config on top of your global one.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Bring up one or more workspaces**[^cfg]:
|
||||
|
||||
```bash
|
||||
./manage.sh run-devenv-agentic # ws0 (the live repo)
|
||||
./manage.sh run-devenv-agentic --ws 1 # ws1 (sibling clone)
|
||||
./manage.sh run-devenv --agentic --attach # ws0 (the live repo)
|
||||
./manage.sh run-devenv --agentic --ws 1 # ws1 (sibling clone)
|
||||
```
|
||||
|
||||
Add `--ws 2`, `--ws 3`, … for more parallel workspaces.
|
||||
@ -47,20 +39,20 @@ Two things to know up front:
|
||||
"MCP Server" on. The agentic DevEnv runs the MCP server in single-user
|
||||
mode - the key and proxied URL shown in the UI are not needed.
|
||||
|
||||
4. **Launch your AI client** against the workspace you want it to drive:
|
||||
4. **Launch your AI client**. Either use your manually configured client
|
||||
(as described below) or conveniently launch an explicitly supported client
|
||||
against the workspace you want it to drive:
|
||||
|
||||
```bash
|
||||
./manage.sh start-coding-agent claude # ws0
|
||||
./manage.sh start-coding-agent claude # ws0 (main)
|
||||
./manage.sh start-coding-agent claude --ws 1 # ws1
|
||||
```
|
||||
|
||||
Supported clients: `claude` | `opencode` | `vscode` | `codex`.
|
||||
5. **Attach to the tmux session** for the workspace (optional):
|
||||
Note: The launcher loads a per-workspace MCP config on top of your global one (if any).
|
||||
|
||||
```bash
|
||||
./manage.sh attach-devenv # ws0
|
||||
./manage.sh attach-devenv --ws 1 # ws1
|
||||
```
|
||||
5. **Work within your client**, which is now equipped with extended capabilities
|
||||
for Penpot development (see below for details).
|
||||
|
||||
6. **Shut down workspaces** with `./manage.sh stop-devenv`, either one by one or all at once.
|
||||
You cannot shut down `ws0` if any other workspace is still running, since it's the worker-bearer.
|
||||
@ -113,10 +105,10 @@ var penpotFlags = "enable-mcp";
|
||||
```
|
||||
|
||||
The file is gitignored and lives in the live repo only. On every
|
||||
`run-devenv-agentic` call it is read directly for ws0; for wsN (N ≥ 1) it is
|
||||
`run-devenv --agentic` call it is read directly for ws0; for wsN (N ≥ 1) it is
|
||||
copied into the workspace clone on the **initial** sync only - subsequent
|
||||
`--sync` passes leave the workspace's copy alone so per-workspace
|
||||
customisations survive. `run-devenv-agentic` refuses to start if the file is
|
||||
customisations survive. `run-devenv --agentic` refuses to start if the file is
|
||||
missing.
|
||||
|
||||
**Browser remote debugging.** The Playwright MCP server drives a real
|
||||
@ -148,13 +140,13 @@ devenv image itself (add a tool, change a base layer):
|
||||
./manage.sh build-devenv --local
|
||||
```
|
||||
|
||||
The default `run-devenv-agentic` flow pulls the published image
|
||||
The default `run-devenv --agentic` flow pulls the published image
|
||||
automatically, so regular users never run this.
|
||||
|
||||
### Bringing up workspaces
|
||||
|
||||
```bash
|
||||
./manage.sh run-devenv-agentic \
|
||||
./manage.sh run-devenv --agentic \
|
||||
[--ws N] [--sync] [--serena-context CTX] \
|
||||
[--git-user-name NAME] [--git-user-email EMAIL]
|
||||
```
|
||||
@ -171,7 +163,7 @@ every bring-up so you don't compute offsets by hand. See the
|
||||
semantics, and stop ordering.
|
||||
|
||||
**Git identity for agent commits.** Coding agents typically need to commit
|
||||
inside the devenv, so `run-devenv-agentic` wires a Git identity into the
|
||||
inside the devenv, so `run-devenv --agentic` wires a Git identity into the
|
||||
container's global config on every bring-up. By default it propagates the
|
||||
host's effective `git config user.{name,email}` (local repo override wins
|
||||
over `~/.gitconfig`, matching what `git commit` on the host would record).
|
||||
@ -189,7 +181,7 @@ the full mechanics.
|
||||
>
|
||||
> ```bash
|
||||
> ./manage.sh stop-devenv
|
||||
> ./manage.sh run-devenv-agentic
|
||||
> ./manage.sh run-devenv --agentic
|
||||
> ```
|
||||
|
||||
### Launching an AI client
|
||||
@ -198,7 +190,7 @@ The agentic environment supports any AI client, one just needs to set the right
|
||||
see [manual configuration](#manual-ai-client-configuration) below. For some popular clients, the `manage.sh`
|
||||
CLI offers direct support through the following mechanism:
|
||||
|
||||
Every `run-devenv-agentic` regenerates three MCP-client config files with
|
||||
Every `run-devenv --agentic` regenerates three MCP-client config files with
|
||||
the workspace's ports baked in; Codex is wired up at launch instead (see
|
||||
below):
|
||||
|
||||
|
||||
@ -45,31 +45,38 @@ This is an incomplete list of devenv related subcommands found on
|
||||
manage.sh script:
|
||||
|
||||
```bash
|
||||
./manage.sh build-devenv --local # builds the local devenv docker image
|
||||
./manage.sh start-devenv # brings up the shared infra + ws0 in background
|
||||
./manage.sh run-devenv # ws0 with non-agentic tmux, attached (legacy alias)
|
||||
./manage.sh run-devenv-agentic # one agentic instance; --ws to target ws1+; see below
|
||||
./manage.sh attach-devenv # re-attaches to the tmux session of a running instance
|
||||
./manage.sh stop-devenv # stops one instance (or --all); infra stops with the last
|
||||
./manage.sh drop-devenv # removes containers (data volumes preserved)
|
||||
./manage.sh build-devenv --local # builds the local devenv docker image
|
||||
./manage.sh start-devenv # brings up the shared infra + ws0 in background
|
||||
./manage.sh run-devenv --attach # bring up main devenv instance and attach to its tmux session
|
||||
./manage.sh run-devenv --agentic --attach # bring up main devenv instance in agentic mode and attach tmux
|
||||
./manage.sh attach-devenv # re-attaches to the tmux session of a running instance
|
||||
./manage.sh stop-devenv # stops one instance (or --all); infra stops with the last
|
||||
./manage.sh drop-devenv # removes containers (data volumes preserved)
|
||||
```
|
||||
|
||||
### Agentic Mode
|
||||
|
||||
The `--agentic` flag enables additional features for AI-assisted development.
|
||||
See the dedicated section [Agentic Dev Environment](../agentic-devenv/) for details.
|
||||
|
||||
### Parallel workspaces
|
||||
|
||||
The devenv runs as separate compose projects: shared infra (`penpotdev-infra`:
|
||||
Postgres, MinIO, mailer, LDAP) plus one `penpotdev-wsN` project per runtime
|
||||
instance. `ws0` (a.k.a. `main`) binds the live repo; `ws1+` bind clones the
|
||||
developer maintains explicitly under `${PENPOT_WORKSPACES_DIR}/wsN/`
|
||||
(default `~/.penpot/penpot_workspaces/`).
|
||||
The devenv runs as separate compose projects:
|
||||
* shared infra (`penpotdev-infra`: Postgres, MinIO, mailer, LDAP)
|
||||
* `penpotdev-wsN` project per runtime instance.
|
||||
- `ws0` (a.k.a. `main`) is the current state of your repo;
|
||||
- `ws1` and up are clones that you maintain explicitly under `${PENPOT_WORKSPACES_DIR}/wsN/`
|
||||
(default `~/.penpot/penpot_workspaces/`). You can explicitly sync them
|
||||
with the `--sync` flag (automatic on first start).
|
||||
|
||||
Each call to `run-devenv-agentic` brings up one instance, and ws0 is always
|
||||
Each call to `run-devenv` brings up one instance, and ws0 is always
|
||||
running whenever any ws1+ is — `--ws N` (N≥1) auto-starts ws0 first if it
|
||||
isn't already up:
|
||||
|
||||
```bash
|
||||
./manage.sh run-devenv-agentic # main (ws0)
|
||||
./manage.sh run-devenv-agentic --ws 1 # ws0 if needed, then ws1
|
||||
./manage.sh run-devenv-agentic --ws 2 --sync # ws2, re-seeding from the live repo
|
||||
./manage.sh run-devenv # main (ws0)
|
||||
./manage.sh run-devenv --ws 1 # ws0 if needed, then ws1
|
||||
./manage.sh run-devenv --ws 2 --sync # ws2, re-seeding from the live repo
|
||||
```
|
||||
|
||||
Starting an instance that is already running is an error. `--sync` is only
|
||||
@ -102,12 +109,12 @@ Host ports are offset by `10000 × N`:
|
||||
| Serena MCP | `http://localhost:14181` | `http://localhost:24181` | `http://localhost:34181` |
|
||||
|
||||
Container-internal ports stay fixed. Target a specific instance with
|
||||
`--ws N` on `attach-devenv`, `run-devenv-agentic`, `stop-devenv`,
|
||||
`--ws N` on `attach-devenv`, `run-devenv`, `stop-devenv`,
|
||||
`start-coding-agent`, `run-devenv-shell`, and `isolated-shell`. `--ws`
|
||||
accepts a **non-negative integer only** — `--ws main` or `--ws ws1` is
|
||||
rejected, keeping the flag shape uniform across commands. `run-devenv` is
|
||||
ws0-only and takes no workspace flag. `run-devenv-agentic` also accepts
|
||||
`--serena-context CTX` and `--git-user-name NAME` / `--git-user-email
|
||||
ws0-only and takes no workspace flag. `run-devenv` also accepts
|
||||
`--serena-context CTX` (used together with `--agentic`) and `--git-user-name NAME` / `--git-user-email
|
||||
EMAIL` (see below).
|
||||
|
||||
Configuration lives in one tracked file, `docker/devenv/defaults.env` (the
|
||||
@ -116,7 +123,7 @@ derived and injected automatically, so there is no per-instance file to edit.
|
||||
|
||||
### Git identity inside the container
|
||||
|
||||
`run-devenv-agentic` wires a Git author identity into the container's
|
||||
`run-devenv` wires a Git author identity into the container's
|
||||
**global** git config (`git config --global user.{name,email}`) so commits
|
||||
made from inside the devenv carry a real author/committer. Without this,
|
||||
the container would commit as the unconfigured `penpot@<container>`
|
||||
@ -130,7 +137,7 @@ returns at the working directory `manage.sh` is invoked from — local
|
||||
`git commit` on the host would record. If neither is available the script
|
||||
prints a warning and continues — commits will fail inside the container
|
||||
until you set an identity. The values are applied every time
|
||||
`run-devenv-agentic` brings an instance up (idempotent), so re-running
|
||||
`run-devenv` brings an instance up (idempotent), so re-running
|
||||
with different flags is the way to change the in-container identity.
|
||||
|
||||
### Shared state and workers
|
||||
@ -185,11 +192,10 @@ docker rm penpotdev-postgres-1 penpotdev-minio-1 penpotdev-minio-setup-1 \
|
||||
docker network rm penpotdev_default 2>/dev/null
|
||||
|
||||
# Bring up infra + ws0 under the new project layout.
|
||||
./manage.sh run-devenv-agentic
|
||||
./manage.sh run-devenv
|
||||
```
|
||||
|
||||
After the cleanup, normal `./manage.sh start-devenv` / `run-devenv` /
|
||||
`run-devenv-agentic` commands work against the new layout. The legacy
|
||||
After the cleanup, normal `./manage.sh start-devenv` / `run-devenv` work against the new layout. The legacy
|
||||
`penpotdev` compose project is no longer used.
|
||||
|
||||
Having the container running and tmux opened inside the container,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user