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}
| Dossier | Package 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 chaquepackage.json) - Extensions
.jsobligatoires 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 buildSinon 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')
})