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

# Espaces de travail et monorepos

> Configurez l'environnement de Devin pour les monorepos, les espaces de travail multi-packages et les projets avec des sous-répertoires indépendants.

Les monorepos et les espaces de travail multi-packages nécessitent une attention particulière dans les blueprints, car différents sous-répertoires peuvent utiliser différents langages, gestionnaires de paquets ou ensembles de dépendances. Devin prend en charge deux approches :

<CardGroup cols={2}>
  <Card title="Espaces de travail natifs (recommandés)" icon="cubes" href="#native-workspaces">
    Créez un blueprint distinct pour chaque sous-répertoire. Chaque espace de travail dispose de ses propres sections initialize, maintenance et Knowledge, le répertoire de travail étant automatiquement défini sur ce sous-répertoire.
  </Card>

  <Card title="Subshells" icon="terminal" href="#subshells">
    Exécutez des commandes dans des sous-répertoires au sein d'un seul blueprint à l'aide de `(cd dir && command)`. Solution plus simple pour les petits monorepos avec seulement quelques packages.
  </Card>
</CardGroup>

***

<div id="native-workspaces">
  ## Espaces de travail natifs
</div>

<Info>
  **Recommandé pour la plupart des monorepos.** Les espaces de travail natifs attribuent à chaque sous-répertoire son propre blueprint, avec une configuration initiale, un Knowledge et un répertoire de travail isolés. Cette approche est plus propre et plus facile à maintenir que les subshells à mesure que le nombre de packages augmente.
</Info>

Avec les espaces de travail natifs, chaque sous-répertoire dispose d’un blueprint dédié. Les commandes de ce blueprint s’exécutent avec le répertoire de travail déjà défini sur le sous-répertoire — inutile d’utiliser `cd` ou des subshells.

<div id="the-root-blueprint">
  ### Le blueprint racine
</div>

Chaque dépôt utilisant des espaces de travail natifs doit disposer d’un **blueprint racine**. Le blueprint racine s’exécute à la racine du dépôt, **avant** tout blueprint associé à un espace de travail. Utilisez-le pour la configuration partagée applicable à l’ensemble du dépôt — installation des environnements d’exécution, des outils globaux ou des dépendances à la racine.

```yaml theme={null}
# Blueprint racine — s'exécute en premier, depuis la racine du repo
initialize: |
  npm install -g pnpm

maintenance: |
  pnpm install
```

Les blueprints d’espace de travail gèrent ensuite la configuration propre aux packages et s’exécutent après le blueprint racine.

<div id="creating-a-workspace">
  ### Créer un espace de travail
</div>

1. Accédez à **Settings > Environment > Blueprints**
2. Cliquez sur le dépôt
3. Cliquez sur **Ajouter un espace de travail**
4. Saisissez le chemin du sous-répertoire (par ex. `packages/frontend`)
5. Rédigez le blueprint pour cet espace de travail

<Warning>
  Le chemin de l’espace de travail doit correspondre à un répertoire réel du dépôt. Si ce chemin n’existe pas au moment de l’exécution du build, le build échouera. Vérifiez bien que le chemin correspond exactement à la structure de votre repo (par ex. `packages/frontend`, et non `pkg/frontend`).
</Warning>

<div id="example">
  ### Exemple
</div>

Un monorepo avec un frontend React et un backend Python. Le blueprint racine installe les outils partagés, puis chaque espace de travail gère ses propres dépendances :

<Tabs>
  <Tab title="Racine">
    ```yaml theme={null}
    # Blueprint racine — configuration partagée pour l'ensemble du repo
    initialize: |
      npm install -g pnpm
      curl -LsSf https://astral.sh/uv/install.sh | sh

    knowledge:
      - name: structure
        contents: |
          Monorepo avec deux packages :
          - packages/frontend — application React (TypeScript, pnpm)
          - packages/backend — API Python (FastAPI, uv)
    ```
  </Tab>

  <Tab title="packages/frontend">
    ```yaml theme={null}
    # Espace de travail limité à packages/frontend
    maintenance: |
      pnpm install

    knowledge:
      - name: lint
        contents: pnpm lint
      - name: test
        contents: pnpm test
      - name: dev
        contents: pnpm dev
    ```
  </Tab>

  <Tab title="packages/backend">
    ```yaml theme={null}
    # Espace de travail limité à packages/backend
    maintenance: |
      uv sync

    knowledge:
      - name: lint
        contents: uv run ruff check .
      - name: test
        contents: uv run pytest
      - name: dev
        contents: uv run uvicorn app.main:app --reload
    ```
  </Tab>
</Tabs>

Les entrées `knowledge` de chaque espace de travail sont propres à ce sous-répertoire. Quand Devin travaille dans `packages/frontend`, il voit les commandes lint/test/dev du frontend, et non celles du backend.

<div id="when-to-use-native-workspaces">
  ### Quand utiliser des espaces de travail natifs
</div>

* Les sous-répertoires utilisent **des langages ou des gestionnaires de paquets différents**
* Chaque package a besoin de ses propres **entrées Knowledge** (commandes de lint, test, build)
* Vous voulez une **configuration isolée** — un blueprint défaillant pour un espace de travail ne bloque pas les autres
* Le nombre de packages augmente et un blueprint unique devient difficile à gérer

***

<div id="subshells">
  ## Subshells
</div>

Pour les monorepos les plus simples, vous pouvez tout gérer dans un seul blueprint à l’aide de subshells. Encadrez les commandes par des parenthèses pour les exécuter dans un sous-répertoire sans que cela n’affecte les étapes suivantes :

```yaml theme={null}
maintenance:
  - name: Frontend deps
    run: (cd packages/frontend && pnpm install)
  - name: Backend deps
    run: (cd packages/backend && uv sync)
```

Les parenthèses `(cd ... && ...)` créent un subshell. Lorsque le subshell se termine, le répertoire de travail revient à la racine du dépôt pour l’étape suivante.

<Warning>
  Sans parenthèses, `cd` change le répertoire de travail pour toutes les étapes suivantes. Utilisez toujours des subshells lorsque vous changez de répertoire dans les étapes d’un blueprint.
</Warning>

<div id="why-subshells-matter">
  ### Pourquoi les subshells sont utiles
</div>

Comparez ces deux approches :

<Tabs>
  <Tab title="Correct (subshells)">
    ```yaml theme={null}
    maintenance:
      - name: Frontend deps
        run: (cd packages/frontend && pnpm install)
      - name: Backend deps
        run: (cd packages/backend && uv sync)
    ```

    Chaque étape s’exécute à partir de la racine du repo. Les deux commandes trouvent le bon sous-répertoire `packages/`.
  </Tab>

  <Tab title="Incorrect (sans subshells)">
    ```yaml theme={null}
    maintenance:
      - name: Frontend deps
        run: cd packages/frontend && pnpm install
      - name: Backend deps
        run: cd packages/backend && uv sync
    ```

    La première étape modifie le répertoire de travail pour `packages/frontend`. La deuxième étape tente alors d’exécuter `cd packages/backend` par rapport à `packages/frontend`, ce qui échoue.
  </Tab>
</Tabs>

<div id="when-to-use-subshells">
  ### Quand utiliser des subshells
</div>

* Le monorepo comporte **quelques packages** avec une configuration simple
* Tous les packages utilisent **le même langage et le même gestionnaire de paquet**
* Vous n'avez pas besoin d'entrées Knowledge propres à chaque package

***

<div id="knowledge-entries-for-monorepos">
  ## Entrées de Knowledge pour les monorepos
</div>

Que vous utilisiez des espaces de travail natifs ou des subshell, des entrées de Knowledge bien structurées aident Devin à s’orienter dans la base de code :

```yaml theme={null}
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
```

<Tip>
  Une entrée Knowledge `structure` qui associe chaque répertoire à son langage et à sa chaîne d’outils aide Devin à se repérer rapidement dans le dépôt. Avec les espaces de travail natifs, chaque espace de travail dispose de ses propres entrées Knowledge ; l’entrée `structure` est donc surtout utile dans le blueprint racine ou pour les configurations basées sur des subshells.
</Tip>

<div id="examples">
  ## Exemples
</div>

<div id="turborepo-nx-workspace">
  ### Espace de travail Turborepo / Nx
</div>

Pour les espaces de travail gérés par un outil de build pour monorepo comme Turborepo ou Nx, installez les dépendances à la racine et laissez l’outil gérer l’orchestration package par package :

```yaml theme={null}
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
```

<div id="multiple-jdk-versions">
  ### Plusieurs versions du JDK
</div>

Un monorepo Java où différents services nécessitent des versions du JDK différentes :

```yaml theme={null}
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)
```

<div id="org-blueprint-for-shared-tools">
  ### Blueprint d’organisation pour les outils partagés
</div>

Si plusieurs packages d’un monorepo utilisent les mêmes outils, installez-les une seule fois dans le blueprint à l’échelle de l’organisation :

```yaml theme={null}
# Blueprint à l'échelle de l'organisation (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
```

Chaque blueprint de repo n’a alors besoin que de commandes propres au projet :

```yaml theme={null}
# Repo blueprint (utilise pnpm et uv du org blueprint)
maintenance:
  - name: Install all workspace deps
    run: pnpm install
  - name: Install Python service deps
    run: (cd services/ml-pipeline && uv sync)
```

<div id="best-practices">
  ## Bonnes pratiques
</div>

<AccordionGroup>
  <Accordion title="Privilégiez les espaces de travail natifs pour les monorepos complexes">
    Lorsque chaque sous-répertoire a son propre langage, son propre gestionnaire de paquets ou son propre processus de build, les espaces de travail natifs permettent à chaque blueprint de rester ciblé et indépendant. Réservez les subshells aux cas simples comportant seulement quelques packages.
  </Accordion>

  <Accordion title="Utilisez toujours des subshells pour les changements de répertoire">
    Lorsque vous utilisez l’approche par subshell, placez les commandes `cd` entre parenthèses : `(cd dir && command)`. Cela évite qu’un changement de répertoire dans une étape n’affecte l’étape suivante.
  </Accordion>

  <Accordion title="Placez les outils partagés dans le blueprint d’organisation">
    Les environnements d’exécution et les gestionnaires de paquets utilisés dans plusieurs repos doivent se trouver dans le blueprint à l’échelle de l’organisation. Cela évite les doublons et permet aux blueprints de repo de rester centrés sur la configuration spécifique au projet.
  </Accordion>

  <Accordion title="Ordonnez les étapes de maintenance selon les dépendances">
    Si le package A dépend du build préalable du package B, placez l’étape de build de B avant l’étape d’installation de A dans `maintenance`. Les étapes d’un blueprint s’exécutent séquentiellement dans l’ordre indiqué.
  </Accordion>

  <Accordion title="Ajoutez une entrée Knowledge de structure">
    Une entrée Knowledge nommée `structure`, qui associe les répertoires à leurs langages et à leurs outils, aide Devin à se repérer dans la base de code. Indiquez quel gestionnaire de paquets utilise chaque sous-répertoire ainsi que les dépendances entre packages.
  </Accordion>

  <Accordion title="Utilisez des entrées Knowledge par package">
    Au lieu d’une seule grande entrée Knowledge, créez des entrées distinctes pour chaque package (p. ex. : `frontend`, `backend`, `ml-pipeline`). Avec les espaces de travail natifs, chaque espace de travail intègre déjà sa propre section Knowledge.
  </Accordion>

  <Accordion title="Privilégiez une maintenance incrémentale">
    Utilisez `pnpm install` (et non `pnpm install --force`) et `uv sync` (et non `rm -rf .venv && uv sync`). Les commandes incrémentales sont plus rapides lors des rebuilds périodiques.
  </Accordion>
</AccordionGroup>

<div id="related-pages">
  ## Pages associées
</div>

* [Configuration déclarative de l'environnement](/fr/onboard-devin/environment/blueprints)
* [Référence Blueprint](/fr/onboard-devin/environment/blueprint-reference)
* [Bibliothèque de modèle](/fr/onboard-devin/environment/templates) — comprend des modèles monorepo prêts à l'emploi
