Skip to content

Structure du monorepo

Organisation

runeya/
├── apps/
│   ├── agent/           # Process executor
│   ├── cli/             # Binaire runeya (entry point)
│   ├── docs/            # Ce site de documentation
│   ├── server/          # Serveur local
│   └── web/             # Interface Vue 3
├── packages/
│   ├── shared/          # Schémas Zod, types partagés
│   ├── mcp-server/      # Serveur MCP (Model Context Protocol)
│   ├── runner-native/   # Runner natif — exécution via execa
│   └── runner-docker/   # Runner Docker — exécution via Docker
├── scripts/
│   ├── check-monorepo/      # Lint des conventions monorepo
│   ├── generate-ci/         # Génération GitHub Actions
│   ├── tsup-config/         # Config tsup partagée
│   └── retrigger-all-build/ # Déclenchement du rebuild en cascade
├── docs/                # Documentation markdown source
├── turbo.json           # Pipeline Turborepo
└── package.json         # Root (workspaces)

Convention de nommage

Format obligatoire : @runeya/{folder}-{name}

DossierPackage name
apps/agent@runeya/apps-agent
apps/cli@runeya/apps-cli
apps/server@runeya/apps-server
apps/web@runeya/apps-web
packages/shared@runeya/packages-shared
packages/mcp-server@runeya/packages-mcp-server
packages/runner-native@runeya/packages-runner-native
packages/runner-docker@runeya/packages-runner-docker
scripts/check-monorepo@runeya/scripts-check-monorepo
scripts/generate-ci@runeya/scripts-generate-ci
scripts/tsup-config@runeya/scripts-tsup-config
scripts/retrigger-all-build@runeya/scripts-retrigger-all-build

Validé par yarn check-monorepo — interdit en CI.

Module system

  • Tous les packages sont ESM ("type": "module" dans chaque package.json)
  • Extensions .js obligatoires dans tous les imports relatifs (même les .ts)
  • Node.js 22+ requis
typescript
// ✅ Correct
import { serviceStore } from './service-store.js'

// ❌ Incorrect
import { serviceStore } from './service-store'

Build avec tsup

Chaque package utilise tsup avec la config partagée :

typescript
// apps/server/tsup.config.ts
import { getAppConfig } from '@runeya/scripts-tsup-config'

export default getAppConfig({
  entry: ['src/index.ts'],
  // noExternal bundle @runeya/* (dist, pas src)
})

Rebuild shared après modification

Après toute modification de packages/shared, il faut rebuilder avant de tester :

sh
yarn workspace @runeya/packages-shared build

Sinon le serveur en mode watch tourne avec l'ancienne version de Zod et silently strip les nouveaux champs.

Pipeline Turborepo

json
// turbo.json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],  // build les deps d'abord
      "outputs": ["dist/**"]
    },
    "test": {
      "dependsOn": ["build"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Yarn 4 Berry

  • nodeLinker: node-modules (compatibilité maximale)
  • Workspaces : apps/*, packages/*, scripts/*
  • Dépendances workspace : "@runeya/packages-shared": "workspace:*"

Tests

  • Framework : Vitest
  • Chaque package a son propre vitest.config.ts
  • Aliases workspace configurés pour les imports cross-package
  • Pattern singletons :
typescript
// Toujours réinitialiser les modules pour les singletons
beforeEach(async () => {
  vi.resetModules()
  vi.doMock('./my-dep.js', () => ({ ... }))
  const { myService } = await import('./my-service.js')
})

Publié sous licence MIT.