> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Referência de campos de blueprints

> Referência completa dos campos de blueprints: seções, tipos de etapa, GitHub Actions, variáveis de ambiente, segredos e anexos de arquivos.

<Info>
  Esta é a referência completa dos campos de blueprints. Para uma introdução aos blueprints e a como eles se encaixam no ambiente do Devin, veja [Configuração declarativa do
  ambiente](/pt-BR/onboard-devin/environment/blueprints).
</Info>

Um blueprint define como o ambiente do Devin é configurado: quais ferramentas instalar, como manter as dependências atualizadas e quais comandos o Devin deve conhecer.

<div id="overview">
  ## Visão geral
</div>

Um blueprint tem três seções principais de nível superior, mais uma seção `post-build` para blueprints em nível de org e Enterprise e uma seção `clone` opcional para blueprints em nível de repositório:

```yaml theme={null}
initialize: ...   # Install tools and runtimes
maintenance: ...  # Install project dependencies
knowledge: ...    # Reference info for Devin (never executed)
post-build: ...   # (Somente org/enterprise) Comandos executados após toda a configuração
clone: ...        # (Repo-level only) Override git-clone defaults
```

| Seção         | Objetivo                                                                                                | Executado?                                                                                      |
| ------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `initialize`  | Instalar ferramentas do sistema, runtimes de linguagem e CLIs globais                                   | Durante builds completos e para workspaces reconstruídos                                        |
| `maintenance` | Instalar e atualizar as dependências do projeto                                                         | Sim, durante builds. Apresentado ao agente no início da sessão (não executado automaticamente). |
| `knowledge`   | Informar ao Devin como executar lint, testes e build, além de outras informações específicas do projeto | Não, usado apenas como referência                                                               |
| `post-build`  | Comandos executados após todos os repositórios serem clonados e configurados (somente org/Enterprise)   | Sim, durante builds — um código de saída diferente de zero faz o build falhar                   |
| `clone`       | Override de como o repositório é clonado no snapshot (apenas no nível de repositório)                   | Aplicado durante a etapa de clone do build                                                      |

Todas as seções são opcionais. Você pode incluir qualquer combinação delas.

`initialize` é executado durante builds completos e para workspaces reconstruídos do zero. Os resultados são salvos no snapshot. Em um [build diferencial](/pt-BR/onboard-devin/environment/differential-builds), os workspaces herdados pulam `initialize`, fazem pull do código mais recente e executam apenas `maintenance`. Escreva `maintenance` de forma que seja autossuficiente e possa ser executado de forma independente sobre o snapshot existente, sem exigir que `initialize` seja executado imediatamente antes nem depender de variáveis de ambiente que `initialize` tenha gravado anteriormente em `$ENVRC`. No início de cada sessão, os comandos de `maintenance` **não são executados automaticamente** — em vez disso, são apresentados ao agente como contexto para que ele saiba quais comandos de dependência executar, se necessário (por exemplo, após fazer pull do código mais recente). Os comandos ainda devem ser rápidos e incrementais. Os builds são executados automaticamente quando seu blueprint muda e periodicamente (a cada \~24 horas).

<div id="initialize">
  ## initialize
</div>

Use `initialize` para instalar ferramentas e runtimes que não dependem do estado específico do seu código: runtimes de linguagens, pacotes do sistema e CLIs globais.

<div id="simple-form">
  ### Forma simples
</div>

Para comandos de shell simples, use um escalar em bloco:

```yaml theme={null}
initialize: |
  curl -LsSf https://astral.sh/uv/install.sh | sh
  apt-get update && apt-get install -y build-essential
  npm install -g pnpm
```

<div id="structured-form">
  ### Formato estruturado
</div>

Para etapas nomeadas, variáveis de ambiente ou GitHub Actions, use uma lista:

```yaml theme={null}
initialize:
  - name: "Install Python 3.12"
    uses: github.com/actions/setup-python@v5
    with:
      python-version: "3.12"

  - name: "Install system packages"
    run: |
      apt-get update
      apt-get install -y libpq-dev

  - name: "Install global tools"
    run: pip install uv
    env:
      PIP_BREAK_SYSTEM_PACKAGES: "1"
```

As duas formas podem ser combinadas. A forma simples equivale a uma única etapa com `run`.

<div id="when-to-use-initialize-vs-maintenance">
  ### Quando usar `initialize` vs `maintenance`
</div>

| Coloque em `initialize`               | Coloque em `maintenance`                           |
| ------------------------------------- | -------------------------------------------------- |
| Instalação do runtime de linguagem    | `npm install` / `pip install`                      |
| Pacotes do sistema (`apt-get`)        | `bundle install`                                   |
| Ferramentas de CLI globais            | `go mod download`                                  |
| Configuração única                    | Atualizações do cache de dependências              |
| GitHub Actions (`setup-python`, etc.) | Scripts de configuração específicos do repositório |

Ambas as seções são executadas durante builds completos. Em builds diferenciais, workspaces herdados pulam `initialize` e executam apenas `maintenance` após obter o código mais recente. Ferramentas e runtimes de linguagem ficam em `initialize`; comandos de dependência vinculados aos arquivos de lock do seu código ficam em `maintenance`.

<div id="maintenance">
  ## maintenance
</div>

Use `maintenance` para instalar dependências e executar outros comandos que devem ser executados depois que seu código for clonado. Esses comandos são executados durante os builds e são apresentados ao agente no início da sessão para que ele possa executá-los novamente se as dependências tiverem mudado. É aqui que entram `npm install`, `pip install`, `uv sync` e comandos semelhantes.

```yaml theme={null}
maintenance: |
  npm install
  pip install -r requirements.txt
```

Ou em formato estruturado:

```yaml theme={null}
maintenance:
  - name: "Install npm dependencies"
    run: npm install

  - name: "Install Python dependencies"
    run: uv sync
    env:
      UV_CACHE_DIR: /tmp/uv-cache
```

<Info>Para blueprints no nível do repositório, os comandos `maintenance` são executados a partir do diretório raiz do repositório. Para blueprints no nível da organização, eles são executados a partir do diretório inicial (`~`).</Info>

<div id="knowledge">
  ## knowledge
</div>

A seção `knowledge` **não é executada**. Ela fornece informações de referência que Devin usa ao trabalhar no seu projeto. É aqui que você informa ao Devin os comandos corretos para linting, testing, build e quaisquer outros workflows específicos do projeto.

```yaml theme={null}
knowledge:
  - name: lint
    contents: |
      Run linting with:
      npm run lint

      For auto-fix:
      npm run lint -- --fix

  - name: test
    contents: |
      Run the full test suite:
      npm test

      Run a single test file:
      npm test -- path/to/test.ts

  - name: build
    contents: |
      npm run build

      Build output goes to dist/
```

Cada item de conhecimento tem:

| Campo      | Tipo   | Descrição                                                                       |
| ---------- | ------ | ------------------------------------------------------------------------------- |
| `name`     | string | Identificador deste item de conhecimento (por exemplo, `lint`, `test`, `build`) |
| `contents` | string | Texto livre com comandos, instruções ou observações                             |

O campo `name` é um rótulo. Por convenção, `lint`, `test` e `build` são os nomes padrão. O Devin usa esses nomes ao verificar o próprio trabalho. Você pode adicionar outros itens de conhecimento com nomes personalizados:

```yaml theme={null}
knowledge:
  - name: lint
    contents: ...
  - name: test
    contents: ...
  - name: build
    contents: ...
  - name: deploy
    contents: |
      Deploy to staging:
      npm run deploy:staging
  - name: database
    contents: |
      Run migrations:
      npm run db:migrate

      Seed test data:
      npm run db:seed
```

<div id="post-build">
  ## post-build
</div>

A seção `post-build` está disponível **apenas em blueprints de nível organizacional e de nível Enterprise** (não há suporte para ela em blueprints de nível de repositório). Suas etapas são executadas durante o build **depois que todos os repositórios forem clonados e que as etapas `initialize` e `maintenance` de cada um forem concluídas**, mas antes da verificação de integridade e da criação da imagem de snapshot. Isso faz dela o lugar certo para validações entre repositórios e verificações de integridade que exigem o ambiente totalmente montado.

Como ela é executada no fim do build, com todo o ambiente já configurado, uma etapa `post-build` pode ver todos os repositórios clonados e todas as ferramentas instaladas pelos blueprints Enterprise, organizacionais e de repositório.

```yaml theme={null}
post-build: |
  # Verifica se o ambiente está funcionando corretamente
  node --version
  python --version
  test -d ~/repos/my-service
```

Ou de forma estruturada:

```yaml theme={null}
post-build:
  - name: "Verify toolchain"
    run: |
      node --version
      uv --version

  - name: "Smoke-test the workspace"
    run: ~/repos/my-service/scripts/healthcheck.sh
```

<Warning>
  Etapas `post-build` **fazem o build falhar quando retornam um código de saída diferente de zero**. Se uma etapa `post-build` retornar um valor diferente de zero, o build será marcado como falho e nenhuma imagem de snapshot será gerada. Use isso para condicionar snapshots a verificações de integridade — mas garanta que os comandos sejam confiáveis, para que uma verificação instável não bloqueie seus builds.
</Warning>

<Info>
  As etapas `post-build` usam os mesmos [tipos de etapa](#step-types) de `initialize` e `maintenance` (comandos de shell `run` e `uses` do GitHub Actions) e são executadas a partir do diretório inicial (`~`).
</Info>

<div id="clone">
  ## clone
</div>

Para **blueprints em nível de repositório**, a seção opcional `clone` substitui os padrões usados quando o Devin clona o repositório para o snapshot. Todos os campos são opcionais e, se não forem definidos, usam um padrão sensato que preserva o comportamento atual.

```yaml theme={null}
clone:
  path: my-project        # destino do clone em ~/repos/ (padrão: nome curto do repo)
  ref: develop            # branch ou tag para checkout (padrão: branch padrão do repo)
  depth: 1                # 0 = histórico completo, N = --depth N (padrão: 0)
  tags: false             # false passa --no-tags (padrão: true)
  submodules: recursive   # true / false / "recursive" (padrão: true)
  lfs: false              # false define GIT_LFS_SKIP_SMUDGE=1 durante o clone (padrão: true)
```

| Campo        | Tipo                  | Padrão                       | Descrição                                                                                                                      |
| ------------ | --------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `path`       | string                | nome curto do repositório    | Substitui o diretório de destino da clonagem em `~/repos/`. Deve ser único entre os repositórios no mesmo snapshot.            |
| `ref`        | string                | branch padrão do repositório | Branch ou tag para fazer checkout após a clonagem. SHAs de commit não têm suporte aqui.                                        |
| `depth`      | int                   | `0`                          | Profundidade da clonagem. `0` clona o histórico completo; qualquer valor positivo passa `--depth N` para um clone superficial. |
| `tags`       | bool                  | `true`                       | Quando `false`, passa `--no-tags` para não buscar tags do Git.                                                                 |
| `submodules` | bool ou `"recursive"` | `true`                       | `true` ou `"recursive"` passa `--recurse-submodules`. `false` ignora completamente os submódulos.                              |
| `lfs`        | bool                  | `true`                       | Quando `false`, define `GIT_LFS_SKIP_SMUDGE=1` para não baixar objetos do Git LFS durante a clonagem.                          |

<Info>
  `clone` se aplica apenas a blueprints **no nível do repositório** — ele controla como esse repositório específico é clonado no snapshot. Não tem efeito em blueprints no nível da organização ou no nível Enterprise.
</Info>

<div id="step-types">
  ## Tipos de etapa
</div>

Cada etapa em `initialize`, `maintenance` ou `post-build` usa um de dois tipos: comandos de shell (`run`) ou GitHub Actions (`uses`).

<div id="shell-commands-run">
  ### Comandos de shell (`run`)
</div>

Execute comandos arbitrários de shell no bash:

```yaml theme={null}
- name: "Install dependencies"
  run: |
    npm install
    pip install -r requirements.txt
```

| Campo  | Tipo              | Descrição                                        |
| ------ | ----------------- | ------------------------------------------------ |
| `name` | string (optional) | Rótulo legível para humanos da etapa             |
| `run`  | string            | Comando(s) de shell a ser executado(s)           |
| `env`  | map (optional)    | Variáveis de ambiente adicionais para esta etapa |

**Detalhes de execução:**

* Os comandos são executados em bash. Se qualquer comando em um script com várias linhas falhar, a etapa inteira é interrompida imediatamente.
* Blueprints no nível da organização são executados no diretório inicial (`~`).
* Blueprints no nível do repositório são executados na raiz do repositório clonado.
* Cada etapa tem um tempo limite de 1 hora.
* Os segredos ficam automaticamente disponíveis como variáveis de ambiente.

<div id="github-actions-uses">
  ### GitHub Actions (`uses`)
</div>

Execute GitHub Actions baseadas em Node.js diretamente no seu blueprint:

```yaml theme={null}
- name: "Install Python"
  uses: github.com/actions/setup-python@v5
  with:
    python-version: "3.12"
```

| Campo  | Tipo              | Descrição                                    |
| ------ | ----------------- | -------------------------------------------- |
| `name` | string (optional) | Nome legível da etapa                        |
| `uses` | string            | Referência da ação do GitHub                 |
| `with` | map (optional)    | Parâmetros de entrada da ação                |
| `env`  | map (optional)    | Variáveis de ambiente extras para esta etapa |

**Formato da referência da ação:**

```
github.com/<owner>/<repo>@<ref>
github.com/<owner>/<repo>/<subpath>@<ref>
```

O prefixo `github.com/` e o sufixo `@<ref>` são obrigatórios. O ref normalmente é uma tag de versão, como `v5`.

**Ações mais usadas:**

| Action                                      | Purpose           | Example `with`                                  |
| ------------------------------------------- | ----------------- | ----------------------------------------------- |
| `github.com/actions/setup-python@v5`        | Instalar Python   | `python-version: "3.12"`                        |
| `github.com/actions/setup-node@v4`          | Instalar Node.js  | `node-version: "20"`                            |
| `github.com/actions/setup-go@v5`            | Instalar Go       | `go-version: "1.22"`                            |
| `github.com/actions/setup-java@v4`          | Instalar Java/JDK | `java-version: "21"`, `distribution: "temurin"` |
| `github.com/gradle/actions/setup-gradle@v4` | Instalar Gradle   | (nenhum)                                        |
| `github.com/ruby/setup-ruby@v1`             | Instalar Ruby     | `ruby-version: "3.3"`                           |

<Warning>Somente GitHub Actions **baseadas em Node.js** são compatíveis. Ações compostas e ações baseadas em Docker não são compatíveis.</Warning>

**Como os valores de `with` funcionam:**

Os valores passados em `with` são fornecidos à ação como entradas, seguindo as mesmas convenções dos workflows do GitHub Actions. Todos os valores são convertidos em strings.

```yaml theme={null}
with:
  python-version: "3.12"
  check-latest: true
  cache: "pip"
```

**Como as ações propagam alterações:**

As ações podem modificar o ambiente para as etapas seguintes. Por exemplo, `setup-python` adiciona o binário do Python ao `PATH`, que permanece disponível para todas as etapas posteriores e no `maintenance`.

<div id="run-vs-uses-which-to-use">
  ### `run` vs `uses`: qual usar
</div>

| Use `run` quando...                     | Use `uses` quando...                                            |
| --------------------------------------- | --------------------------------------------------------------- |
| Instalar pacotes do sistema (`apt-get`) | Configurar runtimes de linguagem (Python, Node, Go, Java, Ruby) |
| Executar scripts específicos do projeto | Houver uma GitHub Action oficial para o que você precisa        |
| Configurar arquivos ou o ambiente       | Você quiser gerenciamento automático de versões e cache         |
| O comando for simples e autocontido     | Você usaria a mesma Action em um workflow do GitHub Actions     |

Na prática, a maioria das configurações usa `uses` para runtimes de linguagem e `run` para todo o resto.

<div id="environment-variables-and-secrets">
  ## Variáveis de ambiente e segredos
</div>

<div id="step-level-environment-variables">
  ### Variáveis de ambiente por etapa
</div>

Cada etapa pode definir variáveis de ambiente adicionais usando o campo `env`:

```yaml theme={null}
- run: pip install -r requirements.txt
  env:
    PIP_INDEX_URL: "https://pypi.example.com/simple/"
    PIP_BREAK_SYSTEM_PACKAGES: "1"
```

Eles ficam restritos à etapa e não persistem nas etapas subsequentes.

<div id="cross-step-environment-variables-envrc">
  ### Variáveis de ambiente compartilhadas entre etapas (`$ENVRC`)
</div>

Para propagar variáveis de ambiente entre etapas, grave-as no arquivo `$ENVRC`:

```yaml theme={null}
- name: "Set shared variables"
  run: |
    echo "DATABASE_URL=postgresql://localhost:5432/myapp" >> $ENVRC
    echo "APP_ENV=development" >> $ENVRC
```

As variáveis gravadas em `$ENVRC` são exportadas automaticamente e ficam disponíveis para todas as etapas seguintes e para a sessão do Devin produzida pela build atual. Isso funciona de forma semelhante ao `$GITHUB_ENV` no GitHub Actions.

Isso também se aplica ao `PATH`. Se você instalar uma ferramenta em um diretório não padrão
(qualquer coisa fora de `/usr/bin` ou `/usr/local/bin`), adicione-o ao `$ENVRC` para que
as etapas seguintes e os blueprints em nível de repositório possam localizar o binário:

```yaml theme={null}
- name: "Install latest direnv"
  run: |
    curl -sfL https://direnv.net/install.sh | bash
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> $ENVRC
```

Um `export PATH=...` simples dentro de um bloco `run:` afeta apenas o shell daquela etapa.
Cada etapa inicia um novo processo de shell, portanto as alterações em `PATH` que não forem gravadas em
`$ENVRC` serão perdidas.

<Info>
  As GitHub Actions `uses:` (por exemplo, `actions/setup-node`) propagam automaticamente suas adições ao `PATH`
  para `$ENVRC` — você só precisa fazer isso manualmente para etapas `run:`.
</Info>

`$ENVRC` é redefinido no início de cada build, incluindo builds diferenciais.
Os valores gravados durante uma build não ficam disponíveis para a build seguinte. Em
particular, um workspace herdado executa apenas `maintenance`, portanto não pode depender de
`PATH` ou de outras variáveis que `initialize` gravou em `$ENVRC` na build
pai. Configure qualquer ambiente exigido por `maintenance` no próprio
`maintenance`.

<script src="/anchor-scroll-fix.js" />

<div id="secrets">
  ### Segredos
</div>

Os segredos configurados na interface do Devin (pela aba **Segredos** em cada editor de blueprint) são injetados automaticamente como variáveis de ambiente. Você não precisa declará-los no blueprint. Basta referenciá-los pelo nome (por exemplo, `$MY_SECRET`).

Os segredos são injetados antes da execução de cada etapa durante os builds **e** reinjetados no início de cada sessão. Eles são removidos da própria imagem do snapshot, para que as credenciais nunca fiquem embutidas em imagens de máquina salvas.

* **Segredos da organização**: Disponíveis como variáveis de ambiente em todas as etapas de todos os blueprints da organização. Configure-os na aba **Segredos** do editor do blueprint de nível da organização.
* **Segredos do Enterprise**: Mesclados com os segredos da organização (os segredos da organização têm precedência em caso de conflito de nomes). Disponíveis em todas as organização do enterprise.
* **Segredos do repositório**: Gravados em um arquivo por repositório em `/run/repo_secrets/{owner/repo}/.env.secrets`. Durante os builds, os segredos do repositório são carregados automaticamente antes da execução das etapas do blueprint desse repositório. Durante a sessão, o Devin os carrega ao trabalhar no repositório. Configure-os na aba **Segredos** do editor de blueprint do repositório.

<Info>
  **Segredos apenas para build**: Segredos marcados como "somente para build" ficam disponíveis durante os builds do snapshot, mas são removidos antes de o snapshot ser salvo. Use-os para credenciais necessárias apenas no momento do build (por exemplo, baixar artefatos privados durante `initialize`).
</Info>

<Warning>
  `maintenance` é executado durante os builds. No início da sessão, os comandos de `maintenance` são apresentados ao agente (não executados automaticamente), então o agente pode executá-los novamente, se necessário. Se uma etapa `maintenance` gravar segredos em arquivos de configuração (por exemplo, `~/.m2/settings.xml`, `~/.npmrc`), esses arquivos serão incorporados ao snapshot. Coloque as etapas que gravam credenciais em `maintenance` (não em `initialize`) para que sejam atualizadas durante os builds periódicos, mas lembre-se de que os arquivos gravados persistem na imagem. Para máxima segurança, use variáveis de ambiente ou `$ENVRC` em vez de gravar credenciais em disco.
</Warning>

<div id="file-attachments">
  ### Anexos de arquivos
</div>

Você pode importar arquivos (como `.npmrc`, `settings.xml` e arquivos de configuração) no editor de blueprint. Os arquivos importados são gravados em `~/.files/`, e uma variável de ambiente é definida apontando para o caminho de cada arquivo:

```
$FILE_SETTINGS_XML    -> /home/ubuntu/.files/settings.xml
$FILE_NPMRC           -> /home/ubuntu/.files/.npmrc
```

O nome da variável é obtido a partir do nome do arquivo: em maiúsculas, com caracteres não alfanuméricos substituídos por underscores, com o prefixo `FILE_`.

Use anexos de arquivo nas etapas do seu blueprint:

```yaml theme={null}
maintenance:
  - name: "Configure Maven"
    run: |
      mkdir -p ~/.m2
      cp "$FILE_SETTINGS_XML" ~/.m2/settings.xml
```

<div id="git-backed-blueprints">
  ## Blueprints baseados em Git
</div>

Você pode armazenar blueprints como arquivos `.devin/blueprint.yaml` diretamente no seu repositório e depois sincronizá-los pela API ou pela UI. Consulte [Blueprints baseados em Git](/pt-BR/onboard-devin/environment/git-backed-blueprints) para obter instruções de configuração e mais detalhes.

<div id="complete-example">
  ## Exemplo completo
</div>

<Info>
  Para entender como os blueprints se compõem entre os níveis (enterprise → org → repo), os status das builds, os estados do repositório e o que aciona um rebuild, consulte [Builds e sessões](/pt-BR/onboard-devin/environment/blueprints#builds-and-sessions) na página de configuração declarativa.
</Info>

<div id="org-wide-blueprint">
  ### Blueprint de nível da organização
</div>

Ferramentas compartilhadas de que todos os repositórios da organização precisam. É executado primeiro (após qualquer blueprint Enterprise), no diretório inicial.

```yaml theme={null}
initialize:
  - name: "Install Node.js 20"
    uses: github.com/actions/setup-node@v4
    with:
      node-version: "20"

  - name: "Install Python 3.12 and uv"
    run: |
      curl -LsSf https://astral.sh/uv/install.sh | sh

  - name: "Install shared tools"
    run: |
      npm install -g pnpm turbo
      apt-get update && apt-get install -y jq ripgrep

  - name: "Configure private registry"
    run: |
      echo "//npm.corp.example.com/:_authToken=$NPM_REGISTRY_TOKEN" >> ~/.npmrc
```

<div id="repo-level-blueprint">
  ### Blueprint em nível de repositório
</div>

Configuração específica do projeto para um monorepo em Node.js + Python. É executado após o blueprint em nível da organização, no diretório do repositório.

```yaml theme={null}
initialize:
  - name: "Install Playwright browsers"
    run: npx playwright install --with-deps chromium

  - name: "Set up project environment variables"
    run: |
      echo "DATABASE_URL=postgresql://localhost:5432/myapp_dev" >> $ENVRC
      echo "REDIS_URL=redis://localhost:6379" >> $ENVRC
      echo "APP_ENV=development" >> $ENVRC

maintenance:
  - name: "Install frontend dependencies"
    run: |
      cd frontend
      pnpm install

  - name: "Install backend dependencies"
    run: |
      cd backend
      uv sync

  - name: "Run database migrations"
    run: |
      cd backend
      uv run alembic upgrade head
    env:
      DATABASE_URL: "postgresql://localhost:5432/myapp_dev"

knowledge:
  - name: lint
    contents: |
      Frontend:
      cd frontend && pnpm lint

      Backend:
      cd backend && uv run ruff check .

      Auto-fix:
      cd frontend && pnpm lint --fix
      cd backend && uv run ruff check --fix .

  - name: test
    contents: |
      Frontend unit tests:
      cd frontend && pnpm test

      Backend unit tests:
      cd backend && uv run pytest

      E2E tests (requires dev server running):
      cd frontend && pnpm test:e2e

  - name: build
    contents: |
      Frontend:
      cd frontend && pnpm build

      Backend:
      cd backend && uv run python -m build

  - name: dev-server
    contents: |
      Start the full development stack:
      cd backend && uv run uvicorn main:app --reload &
      cd frontend && pnpm dev

      Frontend: http://localhost:3000
      Backend API: http://localhost:8000
      API docs: http://localhost:8000/docs

  - name: database
    contents: |
      Run migrations:
      cd backend && uv run alembic upgrade head

      Create a new migration:
      cd backend && uv run alembic revision --autogenerate -m "description"

      Reset the database:
      cd backend && uv run alembic downgrade base && uv run alembic upgrade head
```
