Modèle de données
Documentation des structures JSON persistées dans ./.runeya/ (répertoire DATA_DIR, relatif au dépôt courant).
projects.json
interface Project {
id: string // UUID
name: string // max 128
description?: string
createdAt: string // ISO 8601
updatedAt: string
}services.json
interface ServiceConfig {
id: string // UUID (= processId côté agent)
name: string // max 128
description?: string // max 512
command: string // max 2048
cwd: string // répertoire de travail, max 2048
shell: boolean // false par défaut
projectId: string // UUID du projet parent
agentId: string // UUID de l'agent assigné
parserIds: string[] // UUIDs des parsers JS, dans l'ordre
// Variables secrètes (chiffrées AES-256-GCM)
envSecrets: Array<{
key: string
value: string // format: iv:authTag:ciphertext (hex)
}>
// Environnements service-scoped
environments?: Array<{
reference: string // nom de l'env global
activateOn: string // nom de l'env actif déclencheur
overrides: Record<string, Variable> // variableId → Variable
}>
createdAt: string
updatedAt: string
}environments.json
interface Environment {
id: string
name: string // max 128
immutable?: boolean // protégé contre suppression
variables: Record<string, Variable> // variableId → Variable
createdAt: string
updatedAt: string
}
interface Variable {
key: string // Nom de la variable d'env
value: string // Valeur (ciphertext si secret)
secret: boolean
}agents.json
interface Agent {
id: string
name: string
url: string // http://127.0.0.1:9546
passphrase: string // chiffré AES-256-GCM
registeredAt: string
lastSeenAt?: string
}settings.json
interface Settings {
mode: 'local-simple'
notifications: NotificationPreferences
logParsers: JSLogParser[]
scenarios: Scenario[]
enterprises: Enterprise[]
}
interface NotificationPreferences {
scenario_waiting_input: boolean
ai_conversation_complete: boolean
ai_conversation_error: boolean
service_error_log: boolean
service_status_changed: boolean
service_health_changed: boolean
}
interface JSLogParser {
id: string // UUID
name: string // max 128
code: string // code JS sandbox, max 16KB
version: 1 | 2 // 1 = (raw, stream) => result, 2 = (line) => line
}settings.json — Scénarios
Les scénarios sont stockés dans settings.json sous la clé scenarios: Scenario[].
interface Scenario {
id: string // UUID, max 128
name: string // max 200
description?: string // max 2000
nodes: ScenarioNode[] // max 50
edges: ScenarioEdge[] // max 100
groups: ScenarioGroup[] // max 20
createdAt: number // epoch ms
updatedAt: number // epoch ms
}
interface ScenarioNode {
id: string // UUID, max 128
type: 'prompt' | 'ask_user'
label: string // max 200
prompt: string // max 50 000 chars
position: { x: number; y: number }
allPredecessors: boolean // injecter tous les prédécesseurs dans le contexte
contextNodeIds: string[] // IDs des nœuds à injecter explicitement (max 50)
groupId?: string // UUID du groupe parent (max 128)
aiCli: 'claude-code' | 'codex'
model: string // alias du modèle, ex : 'sonnet' (max 128)
effort: 'low' | 'normal' | 'high'
}
interface ScenarioEdge {
id: string // UUID, max 128
source: string // ID du nœud source (max 128)
target: string // ID du nœud cible (max 128)
description: string // Label de branche, max 500 (utilisé pour le routage IA)
}
interface ScenarioGroup {
id: string // UUID, max 128
label: string // max 200
position: { x: number; y: number }
width: number // 100–5000, défaut 300
height: number // 80–5000, défaut 200
borderColor?: string // max 50
bgColor?: string // max 50
textColor?: string // max 50
}Branchement conditionnel (AI-driven)
Quand un nœud prompt a plusieurs edges sortantes, le runner injecte automatiquement dans le prompt de l'IA des choix numérotés :
Réponds PASS1 pour "<description edge 1>" ou PASS2 pour "<description edge 2>"L'IA doit terminer sa réponse par PASS1 ou PASS2 (sur sa propre ligne). Le runner extrait ce token depuis la dernière ligne de la réponse et suit l'edge correspondante.
- Nœud avec 1 edge : comportement inchangé (
PASS/FAIL). - Nœud avec 0 edge : nœud terminal, fin du scénario.
- Token invalide : le run s'arrête avec une erreur.
settings.json — Enterprises
Les enterprises sont stockées dans settings.json sous la clé enterprises: Enterprise[].
interface Enterprise {
id: string // UUID, max 128
name: string // max 200
description?: string // max 2000
leaderId: string // ID d'une personne existante
teams: EnterpriseTeam[] // max 100
people: EnterprisePerson[] // max 500
createdAt: number // epoch ms
updatedAt: number // epoch ms
}
interface EnterpriseTeam {
id: string // UUID, max 128
name: string // max 200
description?: string // max 1000
}
interface EnterprisePerson {
id: string // UUID, max 128
parentId: string | null // manager direct (optionnel)
teamId: string | null // équipe (optionnel)
firstName: string // max 120
lastName: string // max 120
age: number | null // 16..90
prompt: string // max 50 000
autoGenerated: boolean
}Contraintes métier:
leaderIddoit référencer une personne existante.parentIddoit référencer une personne existante (si défini).- Les cycles hiérarchiques sont refusés.
conversations.private.json
Historique des conversations IA. Les messages sont chiffrés au repos (AES-256-GCM) dans encryptedMessages.
interface ConversationOnDisk {
id: string
title: string // max 200
encryptedMessages: string // JSON chiffré des messages
isCli?: boolean
contextUsage?: {
inputTokens: number
contextWindow: number
}
scenarioId?: string // présent pour un run de scénario
enterpriseId?: string // présent pour une conversation enterprise
archived?: boolean
createdAt: number // epoch ms
updatedAt: number // epoch ms
}Note : le nom d'une conversation de scénario est modifiable par l'utilisateur et peut aussi être généré par IA via scenario.generateName.
enterprise-runs/<conversationId>/
Workspace créé automatiquement à la création d'une conversation enterprise.
README.md: aperçu de l'enterprise, leader, membres et règles.USER_REQUEST.md: brief initial utilisateur (enterpriseInput).<slug>_<personId>.md: un fichier par personne (prompt + log de travail).
schema-version.json
{ "version": 3 }Utilisé par le système de migration pour détecter les anciennes versions de données.
.encryption.key
Fichier binaire contenant 32 bytes (256 bits) de données aléatoires. Permissions : 0o600 (lecture seule pour l'owner). Jamais commitée, jamais loggée.
Relations entre entités
Project (1) ──────────────── (N) Service
│
├── (1) Agent
│
├── (N) JSLogParser (via parserIds)
│
└── (N) Environment (service-scoped)
│
└── référence → Environment global (1)
Settings
├── (N) JSLogParser
├── (N) Scenario
│ ├── (N) ScenarioNode
│ ├── (N) ScenarioEdge (source → target, description)
│ └── (N) ScenarioGroup
└── (N) Enterprise
├── (N) EnterpriseTeam
└── (N) EnterprisePerson (parentId → EnterprisePerson)