Skip to main content

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.

I monorepo e i workspace multi-package richiedono particolare attenzione nei blueprint, perché sottodirectory diverse possono usare linguaggi, gestori di pacchetti o set di dipendenze differenti. Devin supporta due approcci:

Workspace nativi (consigliato)

Crea un blueprint separato per ogni sottodirectory. Ogni workspace ha le proprie sezioni initialize, maintenance e Knowledge, con la directory di lavoro impostata automaticamente sulla sottodirectory corrispondente.

Subshells

Esegui i comandi nelle sottodirectory all’interno di un singolo blueprint usando (cd dir && command). È più semplice per monorepo di piccole dimensioni con pochi package.

Workspace nativi

Consigliati per la maggior parte dei monorepo. I workspace nativi forniscono a ogni sottodirectory il proprio blueprint, con setup, Knowledge e directory di lavoro isolati. Questa soluzione è più ordinata e più facile da mantenere rispetto ai subshells, man mano che aumenta il numero di package.
Con i workspace nativi, ogni sottodirectory ha un blueprint dedicato. I comandi in quel blueprint vengono eseguiti con la directory di lavoro già impostata sulla sottodirectory, senza bisogno di cd o di subshells.

Il blueprint radice

Ogni repo che usa workspace native deve avere un blueprint radice. Il blueprint radice viene eseguito dalla radice del repository prima di qualsiasi blueprint con ambito workspace. Usalo per la configurazione condivisa valida per l’intero repo — ad esempio per installare runtime, strumenti globali o le dipendenze a livello della radice.
# blueprint radice — viene eseguito per primo, dalla root del repo
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install
I blueprint del workspace gestiscono quindi la configurazione specifica del package e vengono eseguiti una volta completato il blueprint radice.

Creare un workspace

  1. Vai a Settings > Environment > Blueprints
  2. Fai clic sul repository
  3. Fai clic su Add workspace
  4. Inserisci il percorso della sottodirectory (ad es. packages/frontend)
  5. Scrivi il blueprint per quel workspace
Il percorso del workspace deve corrispondere a una directory reale all’interno del repository. Se il percorso non esiste quando viene eseguita la build, la build fallirà. Verifica attentamente che il percorso corrisponda esattamente alla struttura del tuo repo (ad es. packages/frontend, non pkg/frontend).

Esempio

Un monorepo con un frontend React e un backend Python. Il blueprint radice installa gli strumenti condivisi, poi ogni workspace gestisce le proprie dipendenze:
# blueprint radice — configurazione condivisa per l'intera repo
initialize: |
  npm install -g pnpm
  curl -LsSf https://astral.sh/uv/install.sh | sh

knowledge:
  - name: structure
    contents: |
      Monorepo con due package:
      - packages/frontend — app React (TypeScript, pnpm)
      - packages/backend — API Python (FastAPI, uv)
Le voci knowledge di ciascun workspace sono limitate a quella sottodirectory. Quando Devin lavora in packages/frontend, vede i comandi lint/test/dev del frontend, non quelli del backend.

Quando usare i workspace nativi

  • Le sottodirectory usano linguaggi o gestori di pacchetti diversi
  • Ogni package ha bisogno di proprie voci di Knowledge (comandi di lint, test, build)
  • Vuoi una configurazione isolata — un blueprint non funzionante in un workspace non blocca gli altri
  • Il numero di package è in crescita e un singolo blueprint sta diventando difficile da gestire

Subshells

Per i monorepo più semplici, puoi gestire tutto all’interno di un unico blueprint tramite subshell. Racchiudi i comandi tra parentesi per eseguirli in una sottodirectory senza influire sui passaggi successivi:
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
Le parentesi (cd ... && ...) creano una subshell. Quando la subshell termina, la directory di lavoro torna alla radice della repo per il passaggio successivo.
Senza parentesi, cd cambia la directory di lavoro per tutti i passaggi successivi. Usa sempre le subshell quando cambi directory nei passaggi di Blueprint.

Perché le subshell sono importanti

Confronta questi due approcci:
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
Ogni passaggio viene eseguito dalla radice della repo. Entrambi i comandi trovano la sottodirectory packages/ corretta.

Quando usare le subshell

  • Il monorepo ha pochi pacchetti con una configurazione semplice
  • Tutti i pacchetti condividono lo stesso linguaggio di programmazione e lo stesso gestore di pacchetti
  • Non sono necessarie voci di Knowledge per singolo pacchetto

Voci di Knowledge per i monorepo

Che tu usi workspace nativi o subshell, delle voci di Knowledge ben strutturate aiutano Devin a orientarsi nel codebase:
knowledge:
  - name: structure
    contents: |
      This is a monorepo with three packages:
      - `packages/frontend` — React app (TypeScript, pnpm)
      - `packages/backend` — Python API (FastAPI, uv)
      - `packages/shared` — Shared TypeScript utilities
  - name: frontend
    contents: |
      cd packages/frontend
      Dev server: pnpm dev
      Lint: pnpm lint
      Test: pnpm test
  - name: backend
    contents: |
      cd packages/backend
      Dev server: uv run uvicorn app.main:app --reload
      Lint: uv run ruff check .
      Test: uv run pytest
Una voce di Knowledge structure che associa ogni directory al relativo linguaggio e alla relativa toolchain aiuta Devin a orientarsi rapidamente nel repo. Con i workspace nativi, ogni workspace ha le proprie voci di Knowledge, quindi la voce structure è particolarmente utile nel blueprint di root o per configurazioni basate su subshell.

Esempi

Workspace Turborepo / Nx

Per i workspace gestiti da uno strumento di build monorepo come Turborepo o Nx, installa le dipendenze alla radice e lascia che lo strumento gestisca l’orchestrazione dei singoli pacchetti:
initialize: |
  npm install -g pnpm turbo

maintenance: |
  pnpm install

knowledge:
  - name: structure
    contents: |
      Turborepo monorepo. Use `turbo` for building and testing:
      - `apps/web` — Next.js app
      - `apps/api` — Express API
      - `packages/ui` — Shared component library
      - `packages/config` — Shared configuration
  - name: build
    contents: turbo run build
  - name: test
    contents: turbo run test
  - name: lint
    contents: turbo run lint
  - name: dev
    contents: turbo run dev

Più versioni del JDK

Un monorepo Java in cui servizi diversi richiedono versioni diverse del JDK:
initialize:
  - name: Install JDK 17 (primary)
    run: |
      sudo apt-get update -qq
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-17-jdk-headless
      echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' \
        | sudo tee /etc/profile.d/java.sh > /dev/null

  - name: Install JDK 11 (legacy service)
    run: |
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq openjdk-11-jdk-headless

maintenance:
  - name: Warm dependency caches
    run: |
      export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
      (cd services/api && ./gradlew dependencies --refresh-dependencies)

      export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
      (cd services/legacy && ./gradlew dependencies --refresh-dependencies)

knowledge:
  - name: build_api
    contents: |
      Build the API service (JDK 17):
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        cd services/api && ./gradlew clean build
  - name: build_legacy
    contents: |
      Build the legacy service (JDK 11):
        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        cd services/legacy && ./gradlew clean build
  - name: test_all
    contents: |
      Run tests for all services:
        JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
        (cd services/api && ./gradlew test)

        JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
        (cd services/legacy && ./gradlew test)

Blueprint dell’org per gli strumenti condivisi

Quando più package di un monorepo condividono gli stessi strumenti, installali una sola volta nel blueprint per tutta l’org:
# Blueprint per tutta l'org (Settings > Environment > Blueprints > Org-wide setup)
initialize:
  - name: Install pnpm
    run: npm install -g pnpm
  - name: Install uv
    run: curl -LsSf https://astral.sh/uv/install.sh | sh
  - name: Install shared build tools
    run: npm install -g turbo typescript
In questo modo, ogni blueprint del repo deve includere solo i comandi specifici del progetto:
# Repo blueprint (usa pnpm e uv dall'org blueprint)
maintenance:
  - name: Install all workspace deps
    run: pnpm install
  - name: Install Python service deps
    run: (cd services/ml-pipeline && uv sync)

Buone pratiche

Quando ogni sottodirectory ha il proprio linguaggio, gestore di pacchetti o processo di build, i workspace nativi mantengono ogni blueprint focalizzato e indipendente. Riserva le subshell ai casi semplici con pochi pacchetti.
Quando usi l’approccio basato su subshell, racchiudi i comandi cd tra parentesi: (cd dir && command). Questo impedisce che il cambio di directory di un passaggio influisca su quello successivo.
I runtime dei linguaggi e i gestori di pacchetti usati in più repo appartengono al blueprint per tutta l’org. Questo evita duplicazioni e mantiene i blueprint delle repo focalizzati sulla configurazione specifica del progetto.
Se il pacchetto A dipende dal fatto che il pacchetto B venga compilato per primo, elenca il passaggio di build di B prima del passaggio di installazione di A in maintenance. I passaggi del blueprint vengono eseguiti in sequenza nell’ordine indicato.
Una voce di Knowledge chiamata structure, che associa le directory ai rispettivi linguaggi e strumenti, aiuta Devin a orientarsi nella codebase. Includi quale gestore di pacchetti usa ogni sottodirectory ed eventuali dipendenze tra pacchetti.
Invece di un’unica grande voce di Knowledge, crea voci separate per ogni pacchetto (ad es. frontend, backend, ml-pipeline). Con i workspace nativi, ogni workspace include già la propria sezione Knowledge.
Usa pnpm install (non pnpm install --force) e uv sync (non rm -rf .venv && uv sync). I comandi incrementali sono più veloci durante le ricostruzioni periodiche.