{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://veld.oss.life.li/schema/v1/veld.schema.json", "title": "Veld Project Configuration", "description": "Configuration file for a Veld local development environment. Place this as veld.json in your project root.", "type": "object", "required": ["schemaVersion", "name", "nodes"], "additionalProperties": false, "properties": { "$schema": { "type": "string", "description": "Optional JSON Schema reference for editor autocompletion." }, "schemaVersion": { "const": "1", "description": "Schema version. Must be \"1\" for this version of Veld." }, "name": { "type": "string", "description": "Human-readable project name. Used in URLs and registry entries.", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$" }, "url_template": { "type": "string", "description": "URL template for services. Supports placeholders: {service}, {variant}, {run}, {project}, {branch}, {worktree}, {username}, {hostname}. Supports fallback operator: {branch ?? run}.", "default": "{service}.{run}.{project}.localhost", "examples": [ "{service}.{run}.{project}.localhost", "{service}.localhost:{port}" ] }, "presets": { "type": "object", "description": "Named shortcuts for node:variant selections. Each preset maps to an array of \"node:variant\" strings.", "additionalProperties": { "type": "array", "items": { "type": "string", "description": "A node:variant selector, e.g. \"backend:local\" or \"frontend:docker\".", "pattern": "^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+$" }, "minItems": 1 } }, "client_log_levels": { "$ref": "#/$defs/ClientLogLevels", "description": "Client-side log levels to capture (project-level default). Overridable at node and variant level." }, "nodes": { "type": "object", "description": "The dependency graph nodes. Each key is a node name, and the value defines its variants.", "additionalProperties": { "$ref": "#/$defs/NodeConfig" }, "minProperties": 1 } }, "$defs": { "NodeConfig": { "type": "object", "description": "Configuration for a single node in the dependency graph.", "required": ["variants"], "additionalProperties": false, "properties": { "default_variant": { "type": "string", "description": "The variant to use when none is specified. If omitted and the node has exactly one variant, that variant is used automatically." }, "url_template": { "type": "string", "description": "URL template override for all variants of this node. Overrides the project-level url_template." }, "hidden": { "type": "boolean", "description": "When true, this node is hidden from `veld nodes` output. Hidden nodes still participate in the dependency graph and run normally.", "default": false }, "client_log_levels": { "$ref": "#/$defs/ClientLogLevels", "description": "Client-side log levels override for all variants of this node." }, "variants": { "type": "object", "description": "Available variants for this node. Each key is a variant name.", "additionalProperties": { "$ref": "#/$defs/VariantConfig" }, "minProperties": 1 } } }, "VariantConfig": { "type": "object", "description": "Configuration for a single variant of a node.", "required": ["type"], "additionalProperties": false, "properties": { "type": { "type": "string", "enum": ["command", "start_server"], "description": "Step type. \"command\" runs a command/script to completion. \"start_server\" starts a long-running process and waits for it to become healthy." }, "command": { "type": "string", "description": "Inline shell command to execute. Supports Veld variable substitution (e.g. ${veld.port}, ${node.output})." }, "script": { "type": "string", "description": "Path to a script file, relative to veld.json. Mutually exclusive with command." }, "health_check": { "$ref": "#/$defs/HealthCheck", "description": "Health check configuration. Required for start_server variants." }, "depends_on": { "type": "object", "description": "Dependencies: maps node names to the variant that must be running before this variant starts.", "additionalProperties": { "type": "string" } }, "env": { "type": "object", "description": "Extra environment variables injected into the process.", "additionalProperties": { "type": "string" } }, "outputs": { "description": "Output declarations. For command steps: an array of output names captured from VELD_OUTPUT. For start_server steps: an object mapping output names to template strings.", "oneOf": [ { "type": "array", "items": { "type": "string" }, "description": "Declared output names for command steps." }, { "type": "object", "additionalProperties": { "type": "string" }, "description": "Synthetic output templates for start_server steps." } ] }, "sensitive_outputs": { "type": "array", "items": { "type": "string" }, "description": "Output keys whose values are sensitive. These are masked in logs and encrypted at rest." }, "strict_outputs": { "type": "boolean", "default": true, "description": "When true (default), fail if the command produces VELD_OUTPUT keys not declared in \"outputs\". Set to false to silently ignore undeclared outputs." }, "verify": { "type": "string", "description": "Idempotency verification command. Only applies to \"command\" type variants. If this command exits 0, the step is considered already complete and is skipped." }, "url_template": { "type": "string", "description": "URL template override for this specific variant. Overrides both node-level and project-level url_template." }, "on_stop": { "type": "string", "description": "Teardown command to run when the environment is stopped. Executed in reverse dependency order. Supports Veld variable substitution." }, "client_log_levels": { "$ref": "#/$defs/ClientLogLevels", "description": "Client-side log levels override for this specific variant." } }, "allOf": [ { "if": { "properties": { "type": { "const": "start_server" } }, "required": ["type"] }, "then": { "required": ["command"] } }, { "if": { "properties": { "type": { "const": "command" } }, "required": ["type"] }, "then": { "anyOf": [ { "required": ["command"] }, { "required": ["script"] } ] } } ] }, "ClientLogLevels": { "type": "array", "description": "Client-side console log levels to capture. Supported values: \"log\", \"warn\", \"error\", \"info\", \"debug\". Unhandled exceptions (\"exception\") are always captured regardless of this setting.", "items": { "type": "string", "enum": ["log", "warn", "error", "info", "debug"] }, "default": ["log", "warn", "error"], "uniqueItems": true }, "HealthCheck": { "type": "object", "description": "Health check configuration for a start_server variant.", "required": ["type"], "additionalProperties": false, "properties": { "type": { "type": "string", "enum": ["http", "port", "command"], "description": "Health check strategy. \"http\" polls an HTTP endpoint. \"port\" checks if the port is accepting connections. \"command\" runs a command and checks the exit code." }, "path": { "type": "string", "description": "HTTP path to poll (type \"http\" only).", "examples": ["/health", "/ready", "/"] }, "expect_status": { "type": "integer", "description": "Expected HTTP status code (type \"http\" only). Defaults to 200.", "minimum": 100, "maximum": 599, "default": 200 }, "command": { "type": "string", "description": "Shell command to run (type \"command\" only). Exit code 0 means healthy." }, "timeout_seconds": { "type": "integer", "description": "Maximum seconds to wait for the service to become healthy.", "default": 60, "minimum": 1 }, "interval_ms": { "type": "integer", "description": "Milliseconds between health check attempts.", "default": 1000, "minimum": 100 } } } } }