diff --git a/.devenv/README.md b/.devenv/README.md index d56e327dd0..f56b1e09d1 100644 --- a/.devenv/README.md +++ b/.devenv/README.md @@ -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 diff --git a/.serena/memories/devenv/core.md b/.serena/memories/devenv/core.md index e612a5f923..82e4e704f3 100644 --- a/.serena/memories/devenv/core.md +++ b/.serena/memories/devenv/core.md @@ -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 `/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. diff --git a/docs/technical-guide/developer/agentic-devenv.md b/docs/technical-guide/developer/agentic-devenv.md index ed362ce385..8d943dcd93 100644 --- a/docs/technical-guide/developer/agentic-devenv.md +++ b/docs/technical-guide/developer/agentic-devenv.md @@ -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): diff --git a/docs/technical-guide/developer/devenv.md b/docs/technical-guide/developer/devenv.md index 88ae8db6ca..5aaab86e7f 100644 --- a/docs/technical-guide/developer/devenv.md +++ b/docs/technical-guide/developer/devenv.md @@ -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@` @@ -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,