Data Model
Documentation of JSON structures persisted in ./.runeya/ (the DATA_DIR, relative to the current repository).
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 — Scenarios
Scenarios are stored in settings.json under the scenarios: Scenario[] key.
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 // inject all predecessor outputs into context
contextNodeIds: string[] // explicit node IDs to inject (max 50)
groupId?: string // parent group UUID (max 128)
aiCli: 'claude-code' | 'codex'
model: string // model alias, e.g. 'sonnet' (max 128)
effort: 'low' | 'normal' | 'high'
}
interface ScenarioEdge {
id: string // UUID, max 128
source: string // source node ID (max 128)
target: string // target node ID (max 128)
description: string // branch label, max 500 (used for AI routing)
}
interface ScenarioGroup {
id: string // UUID, max 128
label: string // max 200
position: { x: number; y: number }
width: number // 100–5000, default 300
height: number // 80–5000, default 200
borderColor?: string // max 50
bgColor?: string // max 50
textColor?: string // max 50
}Conditional branching (AI-driven)
When a prompt node has multiple outgoing edges, the runner automatically injects numbered choices into the AI prompt:
Reply PASS1 for "<edge 1 description>" or PASS2 for "<edge 2 description>"The AI must end its response with PASS1 or PASS2 on its own line. The runner extracts this token from the last line of the response and follows the corresponding edge.
- Node with 1 edge: unchanged behavior (
PASS/FAIL). - Node with 0 edges: terminal node, scenario ends.
- Invalid token: the run stops with an error.
settings.json — Enterprises
Enterprises are stored in settings.json under the enterprises: Enterprise[] key.
interface Enterprise {
id: string // UUID, max 128
name: string // max 200
description?: string // max 2000
leaderId: string // must reference an existing person
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 // direct manager (optional)
teamId: string | null // team (optional)
firstName: string // max 120
lastName: string // max 120
age: number | null // 16..90
prompt: string // max 50 000
autoGenerated: boolean
}Business constraints:
leaderIdmust reference an existing person.parentIdmust reference an existing person (when set).- Hierarchy cycles are rejected.
conversations.private.json
AI conversation history. Messages are encrypted at rest (AES-256-GCM) in encryptedMessages.
interface ConversationOnDisk {
id: string
title: string // max 200
encryptedMessages: string // encrypted JSON payload of messages
isCli?: boolean
contextUsage?: {
inputTokens: number
contextWindow: number
}
scenarioId?: string // set when the conversation is a scenario run
enterpriseId?: string // set when the conversation is an enterprise run
archived?: boolean
createdAt: number // epoch ms
updatedAt: number // epoch ms
}Note: scenario run conversation titles can be edited by users and can also be AI-generated via scenario.generateName.
enterprise-runs/<conversationId>/
Workspace automatically created when an enterprise conversation is created.
README.md: enterprise overview, leader, members, and rules.USER_REQUEST.md: initial user brief (enterpriseInput).<slug>_<personId>.md: one file per person (prompt + work log).
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.
Entity Relationships
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)