> ## 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.

# Referencia de blueprints

> Referencia completa de los campos de los blueprints: secciones, tipos de pasos, GitHub Actions, variables de entorno, secretos y archivos adjuntos.

<Info>
  Esta es la referencia completa de los campos de los blueprints. Para obtener una introducción a los blueprints y cómo se integran en el entorno de Devin, consulta [Configuración declarativa
  del entorno](/es/onboard-devin/environment/blueprints).
</Info>

Un blueprint define cómo se configura el entorno de Devin: qué herramientas instalar, cómo mantener las dependencias actualizadas y qué comandos debe conocer Devin.

<div id="overview">
  ## Descripción general
</div>

Un blueprint tiene tres secciones principales, además de una sección `post-build` para blueprints de nivel de org y blueprint de nivel Enterprise, y una sección `clone` opcional para blueprints de nivel de repositorio:

```yaml theme={null}
initialize: ...   # Install tools and runtimes
maintenance: ...  # Install project dependencies
knowledge: ...    # Reference info for Devin (never executed)
post-build: ...   # (Solo para org/enterprise) Comandos que se ejecutan después de toda la configuración
clone: ...        # (Repo-level only) Override git-clone defaults
```

| Sección       | Propósito                                                                                                           | ¿Se ejecuta?                                                                                                |
| ------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `initialize`  | Instalar herramientas del sistema, entornos de ejecución y CLIs globales                                            | Durante las compilaciones completas y para los espacios de trabajo recompilados desde cero                  |
| `maintenance` | Instalar y actualizar las dependencias del proyecto                                                                 | Sí, durante las compilaciones. Se muestra al agente al inicio de la sesión (no se ejecuta automáticamente). |
| `knowledge`   | Indicarle a Devin cómo ejecutar lint, pruebas, compilaciones y otra información específica del proyecto             | No, se proporciona como referencia                                                                          |
| `post-build`  | Comandos que se ejecutan después de que todos los repositorios se hayan clonado y configurado (solo org/Enterprise) | Sí, durante las compilaciones — un código de salida distinto de cero hace fallar la compilación             |
| `clone`       | Anular cómo se clona el repositorio en la instantánea (solo a nivel de repositorio)                                 | Se aplica durante el paso de clonado de la compilación                                                      |

Todas las secciones son opcionales. Puedes incluir cualquier combinación.

`initialize` se ejecuta durante las compilaciones completas y para los espacios de trabajo recompilados desde cero. Los resultados se guardan en la instantánea. En una [compilación diferencial](/es/onboard-devin/environment/differential-builds), los espacios de trabajo heredados omiten `initialize`, traen el código más reciente y ejecutan solo `maintenance`. Escribe `maintenance` de modo que sea autocontenido y pueda ejecutarse de forma independiente sobre la instantánea existente sin requerir que `initialize` se ejecute inmediatamente antes ni depender de variables de entorno que `initialize` haya escrito previamente en `$ENVRC`. Al inicio de cada sesión, los comandos de `maintenance` **no se ejecutan automáticamente**; en su lugar, se muestran al agente como contexto para que sepa qué comandos de dependencias ejecutar si es necesario (p. ej., después de traer el código más reciente). Los comandos deben seguir siendo rápidos e incrementales. Las compilaciones se ejecutan automáticamente cuando cambia tu blueprint y de forma periódica (cada \~24 horas).

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

Usa `initialize` para instalar herramientas y entornos de ejecución que no dependan del estado específico de tu código: entornos de ejecución de lenguajes, paquetes del sistema y CLI globales.

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

Para comandos de shell sencillos, usa un escalar de bloque:

```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">
  ### Forma estructurada
</div>

Para los pasos con nombre, las variables de entorno o GitHub Actions, usa una 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"
```

Ambas formas pueden combinarse. La forma simple equivale a un único paso con `run`.

<div id="when-to-use-initialize-vs-maintenance">
  ### Cuándo usar `initialize` vs. `maintenance`
</div>

| Coloca en `initialize`                | Coloca en `maintenance`                              |
| ------------------------------------- | ---------------------------------------------------- |
| Instalación del entorno de ejecución  | `npm install` / `pip install`                        |
| Paquetes del sistema (`apt-get`)      | `bundle install`                                     |
| Herramientas de CLI globales          | `go mod download`                                    |
| Configuración única                   | Actualizaciones de la caché de dependencias          |
| GitHub Actions (`setup-python`, etc.) | Scripts de configuración específicos del repositorio |

Ambas secciones se ejecutan durante las compilaciones completas. En las compilaciones diferenciales, los espacios de trabajo heredados omiten `initialize` y ejecutan solo `maintenance` tras hacer pull del código más reciente. Las herramientas y los entornos de ejecución van en `initialize`; los comandos de dependencias que siguen los archivos de bloqueo de tu código van en `maintenance`.

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

Usa `maintenance` para instalar dependencias y ejecutar otros comandos que deban ejecutarse después de clonar tu código. Estos comandos se ejecutan durante las compilaciones y se muestran al agente al inicio de la sesión para que pueda volver a ejecutarlos si las dependencias han cambiado. Aquí es donde van `npm install`, `pip install`, `uv sync` y comandos similares.

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

O de forma estructurada:

```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 los blueprints a nivel de repositorio, los comandos `maintenance` se ejecutan desde el directorio raíz del repositorio. Para los blueprints a nivel de organización, se ejecutan desde el directorio de inicio (`~`).</Info>

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

La sección `knowledge` **no se ejecuta**. Proporciona información de referencia que Devin utiliza cuando trabaja en tu proyecto. Aquí es donde le indicas a Devin los comandos correctos para linting, pruebas, compilación y cualquier otro flujo de trabajo específico del proyecto.

```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 elemento de conocimiento tiene:

| Campo      | Tipo   | Descripción                                                                      |
| ---------- | ------ | -------------------------------------------------------------------------------- |
| `name`     | string | Identificador de este elemento de conocimiento (p. ej., `lint`, `test`, `build`) |
| `contents` | string | Texto libre con comandos, instrucciones o notas                                  |

El campo `name` es una etiqueta. Por convención, `lint`, `test` y `build` son los nombres estándar. Devin los usa como referencia al verificar su trabajo. Puede agregar cualquier elemento de conocimiento adicional con nombres 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>

La sección `post-build` está disponible **solo en blueprints de nivel de organización y de nivel Enterprise** (no es compatible con blueprints de nivel de repositorio). Sus pasos se ejecutan durante la compilación **después de que se hayan clonado todos los repositorios y se hayan completado sus pasos `initialize` y `maintenance`**, pero antes de la comprobación de estado y de que se cree la imagen de instantánea. Por eso, es el lugar adecuado para validaciones entre repositorios y comprobaciones de estado que requieren el Environment completamente montado.

Como se ejecuta al final de la compilación, con todo el Environment ya listo, un paso de `post-build` puede ver cada repo clonado y cada herramienta instalada por los blueprints de Enterprise, de la organización y del repo.

```yaml theme={null}
post-build: |
  # Verificar que el environment ensamblado esté en buen estado
  node --version
  python --version
  test -d ~/repos/my-service
```

O en forma estructurada:

```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>
  Los pasos `post-build` **fallan la compilación si devuelven un código de salida distinto de cero**. Si un paso `post-build` termina con un código distinto de cero, la compilación se marca como fallida y no se genera ninguna imagen de instantánea. Usa esto para supeditar las instantáneas a comprobaciones de estado, pero asegúrate de que los comandos sean fiables para que una comprobación inestable no bloquee tus compilaciones.
</Warning>

<Info>
  Los pasos `post-build` usan los mismos [tipos de pasos](#step-types) que `initialize` y `maintenance` (comandos de shell `run` y `uses` de GitHub Actions), y se ejecutan desde el directorio de inicio (`~`).
</Info>

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

Para los **blueprints a nivel de repositorio**, la sección opcional `clone` anula los valores predeterminados que Devin usa al clonar el repositorio en la instantánea. Todos los campos son opcionales y, si no se especifican, adoptan un valor predeterminado razonable que mantiene el comportamiento actual.

```yaml theme={null}
clone:
  path: my-project        # destino del clone bajo ~/repos/ (predeterminado: nombre corto del repo)
  ref: develop            # rama o etiqueta a extraer (predeterminado: rama predeterminada del repo)
  depth: 1                # 0 = historial completo, N = --depth N (predeterminado: 0)
  tags: false             # false pasa --no-tags (predeterminado: true)
  submodules: recursive   # true / false / "recursive" (predeterminado: true)
  lfs: false              # false establece GIT_LFS_SKIP_SMUDGE=1 durante el clone (predeterminado: true)
```

| Campo        | Tipo                  | Predeterminado               | Descripción                                                                                                                          |
| ------------ | --------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `path`       | string                | nombre corto del repo        | Anula el directorio de destino de la clonación en `~/repos/`. Debe ser único entre los repos de la misma instantánea.                |
| `ref`        | string                | rama predeterminada del repo | Rama o etiqueta que se extrae después de clonar. Aquí no se admiten SHA de commits.                                                  |
| `depth`      | int                   | `0`                          | Profundidad de clonación. `0` clona el historial completo; cualquier valor positivo pasa `--depth N` para una clonación superficial. |
| `tags`       | bool                  | `true`                       | Cuando es `false`, pasa `--no-tags` para omitir la descarga de etiquetas de Git.                                                     |
| `submodules` | bool or `"recursive"` | `true`                       | `true` o `"recursive"` pasa `--recurse-submodules`. `false` omite por completo los submódulos.                                       |
| `lfs`        | bool                  | `true`                       | Cuando es `false`, establece `GIT_LFS_SKIP_SMUDGE=1` para omitir la descarga de objetos de Git LFS durante la clonación.             |

<Info>
  `clone` solo se aplica a blueprints de **a nivel de repositorio**: controla cómo se clona ese repo concreto en la instantánea. No tiene efecto en blueprints de a nivel de organización ni de enterprise-level.
</Info>

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

Cada paso de `initialize`, `maintenance` o `post-build` utiliza uno de estos dos tipos: comandos de shell (`run`) o GitHub Actions (`uses`).

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

Ejecuta cualquier comando de shell en bash:

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

| Campo  | Tipo              | Descripción                                     |
| ------ | ----------------- | ----------------------------------------------- |
| `name` | string (optional) | Etiqueta descriptiva del paso                   |
| `run`  | string            | Comando(s) de shell que se ejecutarán           |
| `env`  | map (optional)    | Variables de entorno adicionales para este paso |

**Detalles de ejecución:**

* Los comandos se ejecutan en bash. Si algún comando de un script de varias líneas falla, todo el paso se detiene de inmediato.
* Los blueprints a nivel de organización se ejecutan en el directorio de inicio (`~`).
* Los blueprints a nivel de repositorio se ejecutan en la raíz del repositorio clonado.
* Cada paso tiene un tiempo de espera de 1 hora.
* Los secretos están disponibles automáticamente como variables de entorno.

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

Ejecuta GitHub Actions basadas en Node.js directamente en tu blueprint:

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

| Campo  | Tipo              | Descripción                                     |
| ------ | ----------------- | ----------------------------------------------- |
| `name` | string (optional) | Etiqueta legible para el paso                   |
| `uses` | string            | Referencia de GitHub Action                     |
| `with` | map (optional)    | Parámetros de entrada de la acción              |
| `env`  | map (optional)    | Variables de entorno adicionales para este paso |

**Formato de la referencia de la acción:**

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

Tanto el prefijo `github.com/` como el sufijo `@<ref>` son obligatorios. La `ref` suele ser una etiqueta de versión como `v5`.

**Acciones de uso común:**

| Acción                                      | Propósito         | Ejemplo de `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   | (ninguno)                                       |
| `github.com/ruby/setup-ruby@v1`             | Instalar Ruby     | `ruby-version: "3.3"`                           |

<Warning>Solo se admiten GitHub Actions **basadas en Node.js**. No se admiten las acciones compuestas ni las acciones basadas en Docker.</Warning>

**Cómo funcionan los valores de `with`:**

Los valores que se pasan mediante `with` se proporcionan a la acción como entradas, siguiendo las mismas convenciones que los flujos de trabajo de GitHub Actions. Todos los valores se convierten en cadenas.

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

**Cómo las acciones propagan los cambios:**

Las acciones pueden modificar el entorno para los pasos siguientes. Por ejemplo, `setup-python` agrega el binario de Python a `PATH`, que sigue disponible en todos los pasos posteriores y en `maintenance`.

<div id="run-vs-uses-which-to-use">
  ### run vs uses: cuál usar
</div>

| Usa `run` cuando...                       | Usa `uses` cuando...                                              |
| ----------------------------------------- | ----------------------------------------------------------------- |
| Instalas paquetes del sistema (`apt-get`) | Configuras entornos de ejecución (Python, Node, Go, Java, Ruby)   |
| Ejecutas scripts específicos del proyecto | Existe una acción oficial de GitHub para lo que necesitas         |
| Configuras archivos o el entorno          | Quieres gestión automática de versiones y almacenamiento en caché |
| El comando es simple y autosuficiente     | Usarías la misma acción en un workflow de GitHub Actions          |

En la práctica, la mayoría de las configuraciones usan `uses` para los entornos de ejecución y `run` para todo lo demás.

<div id="environment-variables-and-secrets">
  ## Variables de entorno y secretos
</div>

<div id="step-level-environment-variables">
  ### Variables de entorno por paso
</div>

Cualquier paso puede definir variables de entorno adicionales con el 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"
```

Estas se limitan a este paso y no persisten en los pasos posteriores.

<div id="cross-step-environment-variables-envrc">
  ### Variables de entorno compartidas entre pasos (`$ENVRC`)
</div>

Para propagar variables de entorno entre pasos, escríbalas en el archivo `$ENVRC`:

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

Las variables escritas en `$ENVRC` se exportan automáticamente y están disponibles para todos los
pasos siguientes y para la sesión de Devin generada por la compilación actual. Esto funciona
de manera similar a `$GITHUB_ENV` en GitHub Actions.

Esto también se aplica a `PATH`. Si instala una herramienta en un directorio no estándar
(cualquier directorio fuera de `/usr/bin` o `/usr/local/bin`), añádala a `$ENVRC` para que
los pasos siguientes y los blueprint de nivel de repositorio puedan encontrar el binario:

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

Un simple `export PATH=...` dentro de un bloque `run:` solo afecta al shell de ese paso.
Cada paso inicia un nuevo proceso de shell, por lo que los cambios en `PATH` que no se escriben en
`$ENVRC` se pierden.

<Info>
  Las acciones `uses:` (p. ej., `actions/setup-node`) propagan automáticamente sus adiciones a `PATH`
  a `$ENVRC` — solo tiene que hacer esto manualmente en los pasos `run:`.
</Info>

`$ENVRC` se restablece al inicio de cada compilación, incluidas las compilaciones diferenciales.
Los valores escritos durante una compilación no están disponibles en la siguiente. En
particular, un `espacio de trabajo` heredado solo ejecuta `maintenance`, por lo que no puede depender de
`PATH` ni de otras variables que `initialize` escribió en `$ENVRC` en la compilación
anterior. Configure cualquier entorno requerido por `maintenance` dentro de
`maintenance`.

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

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

Los secretos configurados en la interfaz de Devin (a través de la pestaña **Secrets** en cada editor de blueprint) se inyectan automáticamente como variables de entorno. No hace falta declararlos en tu blueprint. Solo refiérelos por su nombre (p. ej., `$MY_SECRET`).

Los secretos se inyectan antes de ejecutar cada paso durante las compilaciones **y** se vuelven a inyectar al inicio de cada sesión. Se eliminan de la propia imagen de instantánea, por lo que las credenciales nunca quedan incorporadas en imágenes guardadas de la máquina.

* **Secretos de la organización**: Están disponibles como variables de entorno en todos los pasos de todos los blueprints de la organización. Configúralos en la pestaña **Secrets** del editor del blueprint de toda la organización.
* **Secretos de Enterprise**: Se combinan con los secretos de la organización (los secretos de la organización tienen prioridad si hay conflictos de nombre). Están disponibles en todas las organizaciones de Enterprise.
* **Secretos del repositorio**: Se escriben en un archivo por repo en `/run/repo_secrets/{owner/repo}/.env.secrets`. Durante las compilaciones, los secretos del repo se cargan automáticamente antes de que se ejecuten los pasos del blueprint de ese repo. Durante la sesión, Devin los carga cuando trabaja en el repo. Configúralos en la pestaña **Secrets** del editor de blueprint del repositorio.

<Info>
  **Secretos solo para compilación**: Los secretos marcados como "solo para compilación" están disponibles durante las compilaciones de instantánea, pero se eliminan antes de que se guarde la instantánea. Úsalos para credenciales necesarias solo en tiempo de compilación (p. ej.,
  para descargar artefactos privados durante `initialize`).
</Info>

<Warning>
  `maintenance` se ejecuta durante las compilaciones. Al inicio de la sesión, los comandos de `maintenance` se muestran al agente (no se ejecutan automáticamente), por lo que el agente puede volver a ejecutarlos si es necesario. Si un paso de
  `maintenance` escribe secretos en archivos de configuración (p. ej., `~/.m2/settings.xml`, `~/.npmrc`), esos archivos quedarán incorporados en la instantánea. Coloca los pasos que escriben credenciales en `maintenance` (no en `initialize`) para que se
  actualicen durante las compilaciones periódicas, pero ten en cuenta que los archivos escritos permanecen en la imagen. Para obtener la máxima seguridad, usa variables de entorno o `$ENVRC` en lugar de escribir credenciales en disco.
</Warning>

<div id="file-attachments">
  ### Archivos adjuntos
</div>

Puedes subir archivos (como `.npmrc`, `settings.xml` y archivos de configuración) desde el editor de blueprints. Los archivos subidos se guardan en `~/.files/` y se configura una variable de entorno que apunta a la ruta de cada archivo:

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

El nombre de la variable se obtiene a partir del nombre del archivo: en mayúsculas, con los caracteres no alfanuméricos reemplazados por guiones bajos y con el prefijo `FILE_`.

Usa archivos adjuntos en los pasos de tu 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 respaldados por Git
</div>

Puedes almacenar blueprints como archivos `.devin/blueprint.yaml` directamente en tu repositorio y luego sincronizarlos mediante la API o la UI. Consulta [blueprints respaldados por Git](/es/onboard-devin/environment/git-backed-blueprints) para obtener instrucciones de configuración y más detalles.

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

<Info>
  Para ver cómo se combinan los blueprints entre niveles (enterprise → org → repo), los estados de compilación, los estados del repositorio y qué activa una recompilación, consulta [Compilaciones y
  sesiones](/es/onboard-devin/environment/blueprints#builds-and-sessions) en la página de configuración declarativa.
</Info>

<div id="org-wide-blueprint">
  ### Blueprint para toda la organización
</div>

Herramientas compartidas que necesita cada repo de la organización. Se ejecuta primero (después de cualquier blueprint de Enterprise), en el directorio de inicio.

```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 a nivel de repositorio
</div>

Configuración específica del proyecto para un monorepo de Node.js y Python. Se ejecuta después del blueprint de toda la organización, en el directorio del repositorio.

```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
```
